Interpreter command_355 fix
#1
Interpreter command_355 fix Version: 1.0
By: Zeriab

Introduction

You may have seen other Interpreter command_355 fixes. This is different from those I could locate by the fact that it repairs the nice feature rather than remove it.

The script here fixes the multi-line issue with the call script command and improves the execution of the wait idea.
For those who don't know. If the call script evaluates to false then the event waits a frame before running the script call again. (Consider it like Repeat next frame)
If the script call was on multiple lines there was a single frame wait before it continued with the next event commands. This script fixes this issue so it wait whether single-line or multi-line.

The script now waits on :wait. (And FalseClass for compatibility reasons)
It is easy to change what call script should wait on. :wait conveys it's purpose much better than simply false and scripts accidentally evaluating to :wait is much less likely to happen than for false.

Script

Code:
class Interpreter
  SCRIPT_WAIT_RESULTS = [:wait, FalseClass]
  #--------------------------------------------------------------------------
  # * Script
  #--------------------------------------------------------------------------
  def command_355
    # Set first line to script
    script = @list[@index].parameters[0] + "\n"
    # Store index in case we need to wait.
    current_index = @index
    # Loop
    loop do
      # If next event command is second line of script or after
      if @list[@index+1].code == 655
        # Add second line or after to script
        script += @list[@index+1].parameters[0] + "\n"
      # If event command is not second line or after
      else
        # Abort loop
        break
      end
      # Advance index
      @index += 1
    end
    # Evaluation
    result = eval(script)
    # If return value is false
    if SCRIPT_WAIT_RESULTS.include?(result)
      # Set index back (If multi-line script call)
      @index = current_index
      # End and wait
      return false
    end
    # Continue
    return true
  end
end

Instructions

Copy and paste the script in a new section anywhere above main and below Interpreter 7. You can now use the new functionality in the script calls. (Event commands)

Let the script call evaluate to :wait as long as you want the script call to repeat and anything else (except FalseClass) when you want it to continue. Could for example be :continue or nil.
Naturally if the script call keeps evaluating to :wait then it will wait for ever. In practice it'll feel as if the event freezes.
If it does not evaluate to :wait (or FalseClass) then it will continue interpreting the next event commands without any waiting.
To show why this can be useful I have included a usage example.

Usage example - Waiting for movements completion

Most who have played around with the Wait for Move's Completion event commands knows that the command waits for the movement of all events to be completed. To precise it waits for all the movement set by Set Move Route..., not Autonomous Movement.
This is can be problematic. If you one event which you have given a move route and checked Repeat Action then using Wait for Move's Completion will practically wait forever (unless that event is erased somehow). It is a typical cause for errors. There is no good method for waiting until itself, specific events and the player finishes the forced movement present in the eventing.
By utilizing the waiting feature in the call script you'll see how we can solve this problem in an easy and elegant way.

Let's start by making a method in Game_Character. (Add in its own section anywhere above main)
Code:
class Game_Character
  ##
  # Returns :wait while the character is moving and
  # returns nil otherwise
  #
  def wait_for_movement
    if @move_route_forcing
      return :wait
    end
  end
end

This method returns :wait whenever that character (the player or an event) is moving accordingly to a Set Move Route... and otherwise nil. (It won't wait on autonomous movement, just like Wait for Move's Completion)
Now, how do you use it? Well assuming you have installed the script and you want to wait for the player to finish moving then it's just to put the following in a script call:
Code:
$game_player.wait_for_movement
Simply right? For events you have to specify the id, but to both protect non-scripters and to provide syntactic sugar here is another script you can use: (Add in its own section anywhere above main)

Code:
class Interpreter
  ##
  # Wait for movement where: (Nothing will happen in combat)
  # id < 0: Current event (if there is one)
  # id = 0: Player
  # id > 0: Event with that id (if there is one)
  #
  def wait_for_movement(id = -1)
    # If in battle
    return if $game_temp.in_battle
    # Get actor
    actor = nil
    if id < 0 && @event_id > 0
      actor = $game_map.events[@event_id]
    elsif id == 0
      actor = $game_player
    else
      actor = $game_map.events[id]
    end
    # Wait for actor's movement
    unless actor.nil?
      actor.wait_for_movement
    end
  end
  ##
  # Wait for player's movement
  #
  def wait_for_players_movement
    wait_for_movement(0)
  end
end

Now the methods you can use in scripts are:
Code:
wait_for_players_movement # Wait for the player to finish movement
wait_for_movement # Wait for this event to finish movement
wait_for_movement(0) # Wait for player to finish movement
wait_for_movement(12) # Wait for event 12 to finish movement

Notice that nothing will happen the script call is used when in combat and wait_for_movement will only do something if called from a map event. It can be used in common events in which case it works if the bottom event of the call stack is a map event, but not if its anything else. (See my Common Events Tutorial for more information on how the call stack works)

Note that if Repeat Action is checked or it gets stuck and Ignore If Can't Move is not checked, then freezes can happen. So be aware of these issues. At least you don't have to be aware of all the events. Only of the events you want to wait for. (And possible the player as well)

Compatibility

If you have scripts which relies on false => wait then you have to change SCRIPT_WAIT_RESULTS.
Code:
SCRIPT_WAIT_RESULTS = [:wait, FalseClass] #from this
  SCRIPT_WAIT_RESULTS = [:wait, FalseClass, false] # to this
It has not been included due to the apparently many accidental evaluations to false.

It waits on FalseClass to keep compatibility with my command_355 present in SDK 2.4 (It doesn't fix the multi-line issue, so I don't consider it an earlier version of this script)

Terms and Conditions

License Wrote:Copyright 2009 Zeriab

The scripts presented in this topics are free to use. (Commercial and non-commercial projects alike)
The scripts can be freely changed and distributed.
Copies of this topic can be freely distributed verbatim and changed alike.

This script is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Author's Notes

Use :wait rather than FalseClass. If you use :wait then it will not only be easier to understand, but it is also likely that non-scripters will understand what it does. You could for example use :continue when the event should continue.
It doesn't matter what it is as long as it is not one of those which cause the event to wait functionally, but it will document the behavior better. Self-documenting code is awesome :3

Be sure that it doesn't always evalute to :wait.

*hugs*
- Zeriab
Reply }
#2
This is pretty cool. I often use "wait for movement" completion when eventing cutscenes and I have occasionally encountered the loop annoyance.

I've saved a copy and will look into it in depth very soon.

Thank you for sharing! *hugs*
Reply }




Users browsing this thread: 5 Guest(s)