Submit Your Article


 
RPG Maker

Welcome Guest ( Log In | Register )


  Games Resources RPG Maker VX RPG Maker XP Scripts Tutorials Downloads

 
Reply to this topicStart new topic
> Switch on when pressed, off when left
Tsukihime
post Sep 10 2011, 04:58 PM
Post #1


Level 25
Group Icon

Group: Revolutionary
Posts: 560
Type: None
RM Skill: Undisclosed
Rev Points: 25




I'd probably be able to find a solution if I knew how to phrase the question, but basically I want a switch to be ON when I step onto an event square, but the switch to be OFF when I leave the square.

I thought maybe a two-page event where

Pg1: parallel, set switch to OFF
Pg2: player touch, set switch to ON

My idea was so that if the player touched it, then it would turn itself on, and when the player left it would go back to page 1, but then I'm thinking maybe when I touch it, the engine will always run page 2 regardless whether I leave or not.

A simple application of this type of trigger would be a button that opens a door when you step on it, but then the button releases itself when you step off it.

For me, when I step on the event square, executing a particular skill from the menu would trigger an event, whereas executing the skill from anywhere else would do nothing.

I'm looking for solutions to the switch problem, but if you have any suggestions for how I might want to implement my idea rather than using the switch, that would also be nice.

EDIT: I've decided to check the player's current location, where each parallel event will run the following script:

a scripted solution


CODE
if $game_player.x != $game_map.events[@event_id].x or $game_player.y != $game_map.events[@event_id].y
   $game_switches[17] = false



EDIT: Here is another solution, using self-switches and checking player's coordinates. I think it is more elegant than having a global parallel event running on the map at all times.

Self-contained scripted solution

The problem addressed here is that if multiple events can trigger the same switch, you don't want ALL events to be executing at the same time, otherwise they conflict (they are executed sequentially so all you'll have are the results from the last event).

The basic logic behind is an event that will activate when you step on it, and then stop running after you leave.
Two pages are used:

The first page is simply a touch event that will flip self-switch A, set some switches, and do whatever.

The second page runs when self-switch A is set, and executes the following code in parallel, for as long as you remain on that square:

CODE
if $game_player.x != $game_map.events[@event_id].x or $game_player.y != $game_map.events[@event_id].y
   $game_self_switches[[$game_map.map_id, @event_id, "A"]] = false
   $game_map.refresh
end


Note that the script passes in the current map's iD as well as the current event ID so nothing is hardcoded except the self-switch
Once you step away, it will disable self-switch A, refresh the map, and then wait until you step on it again.

Since the amount of space is limited, you probably can't do too much. For me I just disable a global switch and then move on.
This allows me to copy and paste the event to any map I want and will get the expected results.


Another solution will need to be found so if different events are supposed to activate depending on which tile you're standing on, the correct event will activate without requiring too many additional switches. I can use scripts to flip a self-switch for a specific event, but I'm sort of out of scripting space for a single command.

Maybe run a second event page that will flip the appropriate switch?

This post has been edited by Tsukihime: Sep 11 2011, 05:48 PM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
Donotfeedthemax
post Sep 10 2011, 06:47 PM
Post #2


Level 3
Group Icon

Group: Member
Posts: 31
Type: None
RM Skill: Intermediate




Have a touch event when you step on the square,which turns the switch on.

Then have four identical events on the squares around the former square that turn the switch off when you touch them.

I don't think you'll need to do any complicated scripting...


__________________________
Go to the top of the page
 
+Quote Post
   
Tsukihime
post Sep 10 2011, 06:50 PM
Post #3


Level 25
Group Icon

Group: Revolutionary
Posts: 560
Type: None
RM Skill: Undisclosed
Rev Points: 25




That works, but if I wanted to duplicate this event across multiple maps, it would become quite difficult to maintain.
Also, not sure how this may work, but if I wanted another event to trigger on one of the tiles that holds the switch-disable event, that might become difficult to do.

It would be most convenient if a single event could just say "is the player on my tile?"

This post has been edited by Tsukihime: Sep 11 2011, 05:33 AM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
Donotfeedthemax
post Sep 11 2011, 04:13 PM
Post #4


Level 3
Group Icon

Group: Member
Posts: 31
Type: None
RM Skill: Intermediate




Well, I've been doing essentially the same thing in order to change characters' graphics when they're climbing ladders, because I haven't been able to figure out terrain IDs. I don't think this method is difficult, it just requires a bit of work and some problem solving if you want other events nearby, then you have to strategically place them or something.
But perhaps you could make the special tiles a special terrain type, then have a parallel process event that checks to see if you're on that type, if so, switch on, if not, switch off. But I don't know if terrain types are still a thing in RMXP, or if they stopped with 2K3...

Or you could have a parallel process event on the map that checks, are hero's coordinates (x) and (y)? And if so, turn on switch, if not, then turn off.

This post has been edited by Donotfeedthemax: Sep 11 2011, 04:15 PM


__________________________
Go to the top of the page
 
+Quote Post
   
Tsukihime
post Sep 11 2011, 04:52 PM
Post #5


Level 25
Group Icon

Group: Revolutionary
Posts: 560
Type: None
RM Skill: Undisclosed
Rev Points: 25




There doesn't seem to be a very clean way to do it, because for example if multiple events can activate the "same" switch, then having each event running parallel checks on the player's coordinates and then flipping a global switch would just be wrong.

Though checking the player's coordinates is a good idea, and I need to be able to activate local switches in this case.
How can I activate self-switches using the script command?

The event will consist of two pages:

Page 1 is simply a player touch event that will activate switch 17 and also activate self-switch A.

Page 2 runs when self-switch A is set. It will continuously check that the player's location is equal to this event's location. When the player moves away, it will deactivate switch 17 and then disable self-switch A, so in theory when the player steps on the event again it will repeat the process, allowing me to effectively force these parallel events to run only when I'm standing on it.

CODE
if $game_player.x != $game_map.events[@event_id].x or $game_player.y != $game_map.events[@event_id].y
   $game_self_switches[[$game_map.map_id, @event_id, "A"]] = false
   $game_map.refresh
end


I don't understand how to set self switches from script though; the index is rather confusing. I tried this on a test event, which simply activates self-switch A, but it doesn't seem to work (nothing happens)

CODE
$game_self_switches[[$game_map.map_id, @event_id, "A"]] = true


EDIT: ah, I had to refresh the map. Now the self-switching works through script and is self-contained.

~

Ok, I am getting closer to the solution I like.

Here is a simple example:

There are two NPC's on the map.
When I talk to them, they will say something generic.
When I use a skill called "hypnosis", they will say something more useful.

First problem is that I should be adjacent to the NPC when using the skill.
At the moment, I simply create events around the NPC. Each event has the following:

page 1: activate global switch, activate self-switch A
page 2: if self-switch A is ON, check if the player leaves the tile or not. If leave, turn off self-switch A

Now that's ok, I can use hypnotize on the designated tiles and the NPC will respond appropriately. Each event also deals with its own on/off, so I don't need another event just to turn it off.

But then when I have two NPC's, the above condition is not enough to determine which NPC should talk.

So then a third page is added:

page 3: if self-switch A is ON and hypnosis is used (just a global switch activated from a common event), then
-disable hypnosis switch
-activate self-switch A for target event (hardcode event ID)

The target event will auto-run another event when their self-switch is set. They will then disable the self-switch when it is complete, allowing them to say the normal stuff again.

This allows me to properly handle multiple events where I am using the hypnosis skill, but then there are too many event tiles on the map now. There seems to be a trade-off here

1: if I decide to allow each event to check whether the player is adjacent to it, then I'm going to be running parallel events forever. But at least I don't need to have those extra event tiles around the target.

2: use those extra event tiles, effectively cluttering up my map and making things hard to maintain if I wanted to move things around. But at least I don't have parallel events running all the time when I'm on the map.

Hard to choose. Does having a lot of parallel events on a map bog down performance significantly?

Another idea is to simply write a huge script that will handle this hypnosis, but I am not sure how easy it will be to maintain.

Please don't double post within 48 hours. ~ Redd

This post has been edited by Redd: Sep 26 2011, 04:55 AM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
supercow
post Sep 23 2011, 03:41 AM
Post #6


Level 15
Group Icon

Group: Revolutionary
Posts: 280
Type: Artist
RM Skill: Undisclosed




or you can use variable for it
im going to think that you want the tile/floor switch for it.

first make player variable X & Y ( you can do this for event too)
then conditional branch if variable player X = x map
conditional Y = y map
*activate switch
then another conditional if var player x != x map
conditional Y != y map
* diactivate switch

you can also make event or even floor that move
save variable X and Y of the event that run on paralel
conditional branch if variable player X = X event
conditional player Y = Y event
* activate switch
then another conditional if var player x != X event
conditional player Y != Y event
* diactivate switch

or if you want multiple switch that activate the same
on the event/floor touch activate switch
variable operation- sprite this event X
variable operation- sprite this event Y
and then on another event make it run on paralel
make multiple conditional that when player X and Y is not(!=) X and Y event/floor that you saved earlier, then switch disable

Go to the top of the page
 
+Quote Post
   
Tsukihime
post Sep 28 2011, 01:51 PM
Post #7


Level 25
Group Icon

Group: Revolutionary
Posts: 560
Type: None
RM Skill: Undisclosed
Rev Points: 25




Using that idea, I went to look for a script that can do this for me rather than explicitly storing variables and found ForeverZer0's "Event Range Condition" script that mainly deals with distance and position between events and players in if conditional branches.

Then the set up is simply:

page 1: if player is in some range, then turn on self switch A and desired switch. This desired switch would turn on an additional switch if I used a skill.
page 2: if player is not in some range, then turn off self-switch A and desired switch.
page 3: defines what should happen when self-switch A is on AND the additional switch is on. Then turns off additional switch.

Although with this scheme it only seems to be able to do simple things, for if I wanted to have two options to talk to an NPC (normal, using a skill that only happens if I'm within range), since the parallel events are constantly checking whether I'm around the NPC or not I can't talk to him normally.

This post has been edited by Tsukihime: Sep 28 2011, 02:16 PM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
supercow
post Sep 28 2011, 08:08 PM
Post #8


Level 15
Group Icon

Group: Revolutionary
Posts: 280
Type: Artist
RM Skill: Undisclosed




hey thx its very usefull, glad you could share it happy.gif
i didnt tried this ( its a long way btw) , maybe use range 1, conditional sprite facing event player opposite , conditional press key
Go to the top of the page
 
+Quote Post
   
Tsukihime
post Sep 29 2011, 05:14 PM
Post #9


Level 25
Group Icon

Group: Revolutionary
Posts: 560
Type: None
RM Skill: Undisclosed
Rev Points: 25




Interesting idea.

In my scheme, the second page runs when I'm standing near the event, so I placed the C button press condition in the else branch.
This sort of assumes the keypad does not change (not sure if the user can do that themselves), but it now functions correctly.

Except, since the condition is "while button is being pressed", which means unless you quicky tap the key the condition will be satisfied immediately after the text box goes away (well, in this case it is a textbox).

So I put a wait 3 frames after the textbox to account for this. Actually any amount of frames such that the user won't notice that an explicit wait has been written there would work (so if they want to talk to the event again they won't be forced to wait)

Of course, this is a hackish solution and undesirable because having to put a bunch of waits everywhere is unnecessary effort, and an ideal solution would be to talk to the NPC normally.

This post has been edited by Tsukihime: Sep 29 2011, 05:52 PM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
maximusmaxy
post Sep 30 2011, 05:26 PM
Post #10


PZE whore
Group Icon

Group: Revolutionary
Posts: 131
Type: Scripter
RM Skill: Skilled




I came up with an idea the other day, it may or may not be relevant and it may or may not be beneficial but hey who cares. Its called a map switch or map variable. Basically you implement the following script somewhere above the main.
CODE
class Game_Map
  attr_accessor :switch
  attr_accessor :variable
  alias max_initialize_later initialize
  def initialize
    max_initialize_later
    @switch = []
    @variable = []
  end
end

Then in call scripts you use something like the following.
CODE
$game_map.switch[(insert random number here)] = true

Then in whatever you want to activate put in the conditional branch script.
CODE
$game_map[(insert random number here)].switch == true

and then whatever you want to happen.

You can copy paste the exact same thing on a different map without having to change the coding as the switch or variable is relevant to the map, not the global switches. It's pretty stupid I know but it kinda answers your original question.

This post has been edited by maximusmaxy: Sep 30 2011, 05:27 PM


__________________________
Check out the new PZE Forums! http://zeldaengine.net/index.php
Go to the top of the page
 
+Quote Post
   
Tsukihime
post Sep 30 2011, 05:51 PM
Post #11


Level 25
Group Icon

Group: Revolutionary
Posts: 560
Type: None
RM Skill: Undisclosed
Rev Points: 25




So it's basically a set of switches and variables whose scope is limited to an instance of a map, and so if I wanted to make a block puzzle game, I could move blocks around, exit the map, and then re-enter the map and I could somehow retrieve the positions of those blocks (as opposed to the default behavior where all objects on the map are placed in their initial locations)

Presumably the save function just dumps all maps into the save file so all of the data is preserved.

It can do a lot of things =P

This post has been edited by Tsukihime: Sep 30 2011, 05:55 PM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
maximusmaxy
post Sep 30 2011, 06:19 PM
Post #12


PZE whore
Group Icon

Group: Revolutionary
Posts: 131
Type: Scripter
RM Skill: Skilled




Yeah it all should be saved since it's aliased into the map objects. I haven't tested it at all, but it SHOULD work in theory.


__________________________
Check out the new PZE Forums! http://zeldaengine.net/index.php
Go to the top of the page
 
+Quote Post
   
Tsukihime
post Sep 30 2011, 06:30 PM
Post #13


Level 25
Group Icon

Group: Revolutionary
Posts: 560
Type: None
RM Skill: Undisclosed
Rev Points: 25




It's a nice idea.

Having switches and variables for each map allows for fine-tuning of each map without having to reserve a global switch, which logically doesn't make sense cause other maps probably don't care at all whether you pushed a button at the beginning of the game or not, unless that button triggered the end of the world or something.

This post has been edited by Tsukihime: Sep 30 2011, 06:34 PM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
ForeverZer0
post Sep 30 2011, 06:50 PM
Post #14


Level 2
Group Icon

Group: Member
Posts: 26
Type: Scripter
RM Skill: Masterful




Its not going to work. Game_Map is initialized only once, and that is at the start of a new game. You would need to add it to the setup method instead if you wanted it to be unique to the map.
Go to the top of the page
 
+Quote Post
   
Tsukihime
post Sep 30 2011, 06:59 PM
Post #15


Level 25
Group Icon

Group: Revolutionary
Posts: 560
Type: None
RM Skill: Undisclosed
Rev Points: 25




Would I have to add more parameters to the setup method, as well as modify what kind of data the map passes to the setup? (actually I'm not sure when setup is called)

This post has been edited by Tsukihime: Sep 30 2011, 07:10 PM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   
maximusmaxy
post Sep 30 2011, 07:14 PM
Post #16


PZE whore
Group Icon

Group: Revolutionary
Posts: 131
Type: Scripter
RM Skill: Skilled




No i would just need to edit the code slightly.
CODE
class Game_Map
  attr_accessor :switch
  attr_accessor :variable
  alias max_setup_later setup
  def setup(*args)
    max_initialize_later(*args)
    @switch = []
    @variable = []
  end
end

Something like that


__________________________
Check out the new PZE Forums! http://zeldaengine.net/index.php
Go to the top of the page
 
+Quote Post
   
ForeverZer0
post Sep 30 2011, 07:18 PM
Post #17


Level 2
Group Icon

Group: Member
Posts: 26
Type: Scripter
RM Skill: Masterful




Something like this would work.

CODE
class Game_Map
  
  alias zer0_map_variables_init initialize
  def initialize
    @map_variables = {}
    zer0_map_variables_init
  end
  
  alias zer0_map_variables_setup setup
  def setup(map_id)
    unless @map_variables.has_key?(map_id)
      @map_variables[map_id] = []
    end
    zer0_map_variables_setup(map_id)
  end
  
  def variable
    return @map_variables[@map_id]
  end

  def variable=(value)
    @map_variables[@map_id] = value
  end
end


Each map has its own set of variables, which will be automatically saved with the game, and will be stored so that you do not lose them when the map is changed. Use like this:

CODE
$game_map.variable[INDEX] = VALUE


There really is no need for switches. The variables can be whatever you want, so if you need a boolean, just make them true or false.
Go to the top of the page
 
+Quote Post
   
Tsukihime
post Sep 30 2011, 08:32 PM
Post #18


Level 25
Group Icon

Group: Revolutionary
Posts: 560
Type: None
RM Skill: Undisclosed
Rev Points: 25




That simple addition makes my small projects a lot easier to manage and more flexible smile.gif

Rather than reserving global variables for minor things like pulling a lever to open a door, I can just use the map variable. All of the data is contained in a single map, and unless I really need it to span multiple maps, I'd be minimizing the amount of global switches and variables used.

Unless I was using a specialized system like those really large script sets, that would probably deal with these minor things internally, I can just use a local variable.

This post has been edited by Tsukihime: Sep 30 2011, 08:34 PM


__________________________
My Scripts
Go to the top of the page
 
+Quote Post
   

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 22nd May 2013 - 10:21 AM
RPG RPG Revolution is an Privacy Policy and Legal
eXTReMe Tracker