Just a reminder:
Events with Autonomous Movements will stop moving when the Player directly interacts with them, and will move again from where they left off afterwards (if bug fix in previous post is implemented).
Events with Autonomous Movements will keep moving during Autorun or Parallel Process events, and if you change their movement via a Set Move Route call, they will go back to their Autonomous route immediately after Set Move Route is over.
To prevent this, leave Autonomous Movement on Fixed. Or if you require them to move autonomously outside the Autorun event, have two event pages - one with the custom Autonomous route, and one with the Fixed route - and ensure the page with the Fixed route is active during Autorun.
Showing posts with label Movement. Show all posts
Showing posts with label Movement. Show all posts
Saturday, 6 May 2017
Restore Move Route Bug Fix
I found a bug in RPG Maker VX Ace that I am really surprised I haven't come across a fix for already on the internet.
It's something I noticed before, but didn't really look into until now.
If you have an event with a repeating Custom Autonomous Movement, and some logic when you interact with them that makes a Set Move Route call, once the interaction is over one of two things may happen:
It's something I noticed before, but didn't really look into until now.
If you have an event with a repeating Custom Autonomous Movement, and some logic when you interact with them that makes a Set Move Route call, once the interaction is over one of two things may happen:
- they return to their autonomous movement, but not where they left off when they were interrupted (meaning their original route gets totally screwed up), or
- they stop moving completely.
It turns out, which one happens depends on where they were in their move route when you interacted with them. If you interact with them at the end of their Custom Autonomous Move Route cycle, the second one happens. Any other time, the first one happens.
The Way Movement Works
Events move around via an update_routine_move method that is called continuously (until you interact with them). The move route is the list of move commands, and it keeps track of the current movement via an index that is manually incremented.
In other words, the code retrieves the current move command from the route via the index, processes the command, then advances the index. Pretty standard stuff. This method is also called for Set Move Route commands within the event logic, which actually overwrites the original move route.
But once Player interaction ends, the event is supposed to go back to its original move route. So the code stores (or "memorises") the Custom Autonomous Move Route prior to any Set Move Route call. It also stores the index so it can "remember" where it was up to when interrupted.
Then, when Set Move Route is done, it simply restores the original move route and the original index from memory.
The bug is: it doesn't restore this index correctly.
The problem code is in one of two places, depending how you look at it.
Either:
class Game_Character
#--------------------------------------------------------------
# * Restore Move Route
#--------------------------------------------------------------
def restore_move_route
@move_route = @original_move_route
@move_route_index = @original_move_route_index
@original_move_route = nil
end
end
OR
class Game_Character
#--------------------------------------------------------------
# * Process Move Route End
#--------------------------------------------------------------
def process_route_end
if @move_route.repeat
@move_route_index = -1
elsif @move_route_forcing
@move_route_forcing = false
restore_move_route
end
end
end
It all looks correct and innocent enough, but the giveaway is that the index is set back to -1 and not 0 if the move route is set to repeat.
The reason for this is, the code processes the end of the move route as another command in the list. And as we discovered earlier, after a command is processed, it then advances the index. So when it goes back to the start, the index has been advanced back to 0 and we're good to go.
When it restores the move route, however, it doesn't take this into account. Therefore, the index is out by 1 when the original route is restored.
What this means is if the event was in the middle of the move route when interrupted, it skips the command it was up to and goes to the next one, which is why the original route gets messed up. If the event was at the end of its route when interrupted, the index is then increased to be greater than the number of commands in the list, so when the code goes to process the next command, it simply doesn't find one and the event stops moving.
The Fix
For all that, the fix is very simple. The move route index simply needs to be decreased by 1 when restoring it back to the original route. This can be done in either of the two methods above. It makes more sense to me to do it in process_route_end but it's easier with aliasing to do it in restore_move_route.
IMPORTANT: Choose one or the other, not both.
Either:
class Game_Character
#--------------------------------------------------------------
# * Alias method - Restore Move Route
# Only needed if the overwritten method below isn't used
#--------------------------------------------------------------
alias rtp_bug_fix_restore_move_route restore_move_route
def restore_move_route
rtp_bug_fix_restore_move_route
@move_route_index -= 1
end
end
OR
class Game_Character
#----------------------------------------------------------------
# * Overwrite Method - Process Move Route End
# Only needed if the alias method above isn't used
#--------------------------------------------------------------
def process_route_end
if @move_route.repeat
@move_route_index = -1
elsif @move_route_forcing
@move_route_forcing = false
restore_move_route
@move_route_index -= 1
end
end
end
Saturday, 3 September 2016
Secret Passages
Everyone wants to put secret passages in their RPGs, but if your secret passage has to go through an impassable wall, it can get a little complicated.
People have different ways of doing it:
The problem with this is that it fills up your available tilesets with redundant tiles, and if your impassable wall tile is an Auto Tile then it is a bit more difficult to duplicate them correctly and you'll likely run into other drawing problems as well. (Do note, however, that holding Shift down when you right click a map tile will copy that tile exactly onto another tile when you left click.)
I personally don't like this method, as it seems to defeat the purpose of having a secret passage in the first place (and I think Player movement should only be controlled during cut scenes).
Using this script, you could use events at the start and end of your secret passage to turn Through ON or OFF on the Player (so they can pass through the impassable tiles freely) and mark an impassable region around your secret passage to prevent the Player from being able to pass through the surrounding walls.
Alternatively, with a few adjustments, you can use similar logic to specify regions on your map where a Player or NPC can always go (even if the tile is impassable!) and this way you no longer need events to toggle Player Through ON or OFF.
This would be the perfect, most efficient, simple, preferred solution, but...
The problem is, the now passable impassable tiles of your secret passage are not drawn on top of the Player. You could create events to turn the Player's transparency on and off, but it's pretty clunky to do so and the animation just isn't smooth.
So if you want to utilise this method, you'd still need additional passable * tiles for your secret passage, which ultimately makes it unnecessary to use this method at all...
If you don't mind having a load of Events that don't do anything on your map, and you don't mind the tediousness of it (especially if you want your Player to also move over the top of these tiles at some point), then this is a pretty simple method that works pretty well once you've set up the character sheets (if your tiles are Auto Tiles, then this can take a bit of work).
Keep in mind that you need to save your character sheet with a ! at the start of its filename for RPG Maker VX Ace to draw them at their proper size.
The Player would then freely be able to pass through your secret passage, hidden underneath the overlaid wall tiles, and no tricky event logic would be needed on your part. What's more, you can still use the overlay map as a normal map if you want your character to be able to jump across rooftops or something.
The downside is that you end up with extra maps in your map list, you can't see the overlay in the editor, and as such it can be a little tedious lining the two maps up.
Also, Hime's scripts are not free for commercial use.
People have different ways of doing it:
Duplicate Tiles
One of the simplest methods is to just duplicate your impassable wall tile onto another tileset and set it up so that it's passable (with * so the Player is actually hidden beneath it). Then just use those tiles on top of passable ground tiles where you want your secret passage.The problem with this is that it fills up your available tilesets with redundant tiles, and if your impassable wall tile is an Auto Tile then it is a bit more difficult to duplicate them correctly and you'll likely run into other drawing problems as well. (Do note, however, that holding Shift down when you right click a map tile will copy that tile exactly onto another tile when you left click.)
Forced Movement
Another method I've seen is for the game to take control of the Player's movement while they're in the secret passage, and return control to the Player once they're on the other side.I personally don't like this method, as it seems to defeat the purpose of having a secret passage in the first place (and I think Player movement should only be controlled during cut scenes).
Yanfly's Move Restrict Region (not a solution)
Yanfly's Move Restrict Region script allows you to specify regions on your map where a Player or NPC cannot go. Of most interest is the option to block passage even if the Player has Through ON.| Region 61 = impassable tiles; 60 = passable tiles. |
Alternatively, with a few adjustments, you can use similar logic to specify regions on your map where a Player or NPC can always go (even if the tile is impassable!) and this way you no longer need events to toggle Player Through ON or OFF.
This would be the perfect, most efficient, simple, preferred solution, but...
The problem is, the now passable impassable tiles of your secret passage are not drawn on top of the Player. You could create events to turn the Player's transparency on and off, but it's pretty clunky to do so and the animation just isn't smooth.
So if you want to utilise this method, you'd still need additional passable * tiles for your secret passage, which ultimately makes it unnecessary to use this method at all...
Tile Character Sheets
Similar to the Duplicate Tiles option, you could create special character sheets with your impassable wall tiles and then use Events (with those tiles as their graphic, and Priority set to Above Characters) to mark out your secret passage.If you don't mind having a load of Events that don't do anything on your map, and you don't mind the tediousness of it (especially if you want your Player to also move over the top of these tiles at some point), then this is a pretty simple method that works pretty well once you've set up the character sheets (if your tiles are Auto Tiles, then this can take a bit of work).
Keep in mind that you need to save your character sheet with a ! at the start of its filename for RPG Maker VX Ace to draw them at their proper size.
Hime's Map Overlay
Hime's Map Overlay script allows you to have another map drawn over the top of an existing map. Using this script, you could put passable ground tiles down on your map where you want your secret passage to be, then create another map of the same size with your Auto Wall Tiles in the same place, and have Hime's script overlay it on top.The Player would then freely be able to pass through your secret passage, hidden underneath the overlaid wall tiles, and no tricky event logic would be needed on your part. What's more, you can still use the overlay map as a normal map if you want your character to be able to jump across rooftops or something.
The downside is that you end up with extra maps in your map list, you can't see the overlay in the editor, and as such it can be a little tedious lining the two maps up.
Also, Hime's scripts are not free for commercial use.
Subscribe to:
Posts (Atom)