Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Interpreter command_355 fix

Zeriab

Sponsor

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

[rgss]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
[/rgss]

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)
[rgss]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
[/rgss]

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:
[rgss]$game_player.wait_for_movement
[/rgss]
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)

[rgss]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
[/rgss]

Now the methods you can use in scripts are:
[rgss]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
 
[/rgss]

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.
[rgss]  SCRIPT_WAIT_RESULTS = [:wait, FalseClass] #from this
  SCRIPT_WAIT_RESULTS = [:wait, FalseClass, false] # to this
[/rgss]
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

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
 

regi

Sponsor

I know this is a necro but Zeriab this is an amazing tool for developers, especially the wait for movements part, and I had to comment :biggrin:

A simple question, would the methods "wait_for_movement" work inside the "Move Route: Call Script" function (mainly for Custom Move Routes)? It'd be useful if an event, for example, is programmed to stay still until another event has finished a programmed path.
 

Zeriab

Sponsor

I am glad you like it ^^
Unfortunately the script calls in move route is treated differently and thus the method will not function.

*hugs*
 

regi

Sponsor

I wrote another tiny scriptlet that could help eventers out there :3
This is obviously meant to be used with the command fix in this thread.

Add this chunk above Main:
Code:
class Interpreter

  def wait_for_scrolling

    if $game_map.scrolling?

      return :wait

    end

  end

end

What this does is waits for any screen/map scrolling to finish before executing the next event command. Simply done by entering "wait_for_scrolling" into a "Call Script" command. Hope it's useful for someone out there!
 

Star

Sponsor

Dude! This stuff is completely useful! As a veteran eventor, I wish these scripts were out so that I could of used them a long time ago. I always wondered why the wait for moves completion never worked, I had to time my events in frames instead.

Same goes for wait for scrolling. it's a pain having to keep guessing the proper amount of frames.

This is for XP right? Or both?

*misses Zeriab :sad:
 

regi

Sponsor

Yup. I too used to have so much trouble synching up movements and scrolling in cutscenes, but after dabbling in RGSS Zeri and I figured it out :)

This is for XP, but it could probably be altered to work with VX (I'm not too familiar with it, though).

*misses Zeri too :(
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top