[XP] Zeriab's Caterpillar Script

Started by Zeriab, August 25, 2008, 01:49:19 pm

Previous topic - Next topic

Zeriab

August 25, 2008, 01:49:19 pm Last Edit: September 04, 2013, 07:35:24 am by ForeverZer0
Zeriab's Caterpillar Script
Authors: Zeriab
Version: 1.0
Type: Party Movement System
Key Term: Custom Movement System



Introduction

This script creates a caterpillar of the party members by using events present on the map. (You need to actually make the events in the editor)
When the caterpillar is deactivated they act just like any other event. Most event commands still works on the events when the caterpillar is activated, but the results be strange.


Screenshot




Demo

Currently I can only present a demo which includes Wachunga's Multiple Message Windows which requires SDK 1.5: MediaFire
This is because Wumpi and Despain requested it to work with that message system. (Only the caterpillar script is my work. I had nothing to do with the rest)


Script

Spoiler: ShowHide
#==============================================================================
# ** Zeriab's Caterpillar Script
#------------------------------------------------------------------------------
# Zeriab
# 1.0
# 2008-08-25
#------------------------------------------------------------------------------
# This script creates a caterpillar of the party members by using events.
#------------------------------------------------------------------------------
# Paste this script just above main.
#
# Put \cat_actor[3] in the name of an event and it will be considered the event
# for the actor with id 3. The name could for example be "Cyrus\cat_actor[3]"
#
# The switch number specified with CATERPILLAR_ACTIVE_SWITCH (default is 23) is
# used to determine whether the events should be positioned in the caterpillar
# or not. Then the switch is off they are just like any other event.
# You can do CATERPILLAR_ACTIVE_SWITCH = true for always having the caterpillar
# enabled
#
# The REMOVE_VISIBLE_ACTORS (default is true) is used to determine whether
# actor event not in the party should be erased or not.
# If it is set to an integer rather than true or false the switch with the
# corresponding id is used. For example REMOVE_VISIBLE_ACTORS = 21 will allow
# you to determine whether the events should be erased or not depending whether
# switch 21 is OFF or ON.
#
# The MAX_ACTORS (default is 4) is used to determine how many player moves
# should be remembered. Only change this if you can have a party with more than
# 4 actors.
#==============================================================================
class Game_Caterpillar
 CATERPILLAR_ACTIVE_SWITCH = 23
 REMOVE_VISIBLE_ACTORS = true
 MAX_ACTORS = 4
 #--------------------------------------------------------------------------
 # * Initialize the caterpillar
 #--------------------------------------------------------------------------
 def initialize
   @actors = []
   @actor_id_to_event = {}
   @move_list = []
 end
 #--------------------------------------------------------------------------
 # * Clear the caterpillar data
 #--------------------------------------------------------------------------
 def clear
   @actors.clear
   @actor_id_to_event.clear
   @move_list.clear
 end
 #--------------------------------------------------------------------------
 # * Check if the caterpillar script is active
 #--------------------------------------------------------------------------
 def active?
   if CATERPILLAR_ACTIVE_SWITCH.is_a?(Integer)
     return $game_switches[CATERPILLAR_ACTIVE_SWITCH]
   else
     return CATERPILLAR_ACTIVE_SWITCH
   end
 end
 #--------------------------------------------------------------------------
 # * Add an actor event to the caterpillar
 #--------------------------------------------------------------------------
 def add_actor(event, actor_id)
   @actor_id_to_event[actor_id] = event
   event.move_list.clear
   added = false
   for actor in $game_party.actors
     if actor.id == actor_id
       @actors << event
       event.moveto($game_player.x, $game_player.y)
       added = true
     end
   end
   if remove_visible_actors? && !added && active?
     event.erase
   end
 end
 #--------------------------------------------------------------------------
 # * Check if visible actors should be removed
 #--------------------------------------------------------------------------
 def remove_visible_actors?
   if REMOVE_VISIBLE_ACTORS.is_a?(Integer)
     return $game_switches[REMOVE_VISIBLE_ACTORS]
   else
     return REMOVE_VISIBLE_ACTORS
   end
 end
 #--------------------------------------------------------------------------
 # * If the game player has been centered. I.e. teleported somewhere.
 #--------------------------------------------------------------------------
 def center
   # Check if the caterpillar is active
   return unless active?
   # Clear the move_llist
   @move_list.clear
   # Refresh the caterpillar
   update
   # Move the actors to the new place
   for event in @actors
     event.moveto($game_player.x, $game_player.y)
     event.move_list.clear
   end
 end
 #--------------------------------------------------------------------------
 # * Refresh the caterpillar. (Use sparingly)
 #--------------------------------------------------------------------------
 def refresh
   # Check if the caterpillar is active
   return unless active?
   # Clear the data
   clear
   # Check each event
   for event in $game_map.events.values
     if event.is_a?(Game_Event)
       event.check_caterpillar
     end
   end
   # Center the events around the player
   center
   # Update the caterpillar
   update
 end
 #--------------------------------------------------------------------------
 # * Register a player move
 #--------------------------------------------------------------------------
 def register_player_move(move_speed, *args)
   # Check if the caterpillar is active
   return unless active?
   # Add the new command
   @move_list.unshift([move_speed, args])
   # Append the new moves to the caterpillar events
   update_actor_movement
   # Check if the last command should be removed
   if @move_list.size > MAX_ACTORS + 1
     # Remove the last move command
     @move_list.pop
   end
 end
 #--------------------------------------------------------------------------
 # * Updates the actors movement.
 #--------------------------------------------------------------------------
 def update_actor_movement
   for i in 0...@actors.size
     if i + 1 < @move_list.size
       command = @move_list[i + 1]
       actor = @actors[i]
       actor.move_list.unshift(command[1])
       actor.move_speed = command[0]
     end
   end
 end
 #--------------------------------------------------------------------------
 # * Update the caterpillar.
 #--------------------------------------------------------------------------
 def update
   # Check if the caterpillar is active
   return unless active?
   old_actors = @actors
   @actors = []
   # Create a copy of the party actors
   caterpillar = $game_party.actors.dup
   # Remove the first element
   caterpillar.shift
   # Go through each actor that's possible present in the caterpillar
   for actor in caterpillar
     event = @actor_id_to_event[actor.id]
     unless event.nil?
       @actors << event
       event.unerase if remove_visible_actors?
       event.character_name = actor.character_name
     end
   end
   if remove_visible_actors?
     # Go through the old actors to see if any should be erased
     for actor in old_actors
       unless @actors.include?(actor)
         actor.erase
       end
     end
   else
     # Erase the event for the current player should there be one
     event = @actor_id_to_event[$game_party.actors[0].id]
     event.erase unless event.nil?
   end
 end
 #--------------------------------------------------------------------------
 # * Unerase all erased actor events
 #--------------------------------------------------------------------------
 def unerase_all
   for event in @actor_id_to_event.values
     event.unerase
   end
 end
 #--------------------------------------------------------------------------
 # * Erase actor events not in the party
 #--------------------------------------------------------------------------
 def erase_non_party_events
   for event in @actor_id_to_event.values
     event.erase unless @actors.include?(event)
   end
 end
end

#==============================================================================
# ** Game_Player - Registration of movement
#==============================================================================
class Game_Player < Game_Character
 unless self.method_defined?('zeriab_caterpillar_game_player_center')
   alias_method(:zeriab_caterpillar_game_player_center, :center)
 end
 #--------------------------------------------------------------------------
 # * When the player is centered (i.e. teleported somewhere)
 #--------------------------------------------------------------------------
 def center(*args)
   zeriab_caterpillar_game_player_center(*args)
   $game_system.caterpillar.center
 end
 
 #--------------------------------------------------------------------------
 # * Generate registration of player moves to the caterpillar code
 #--------------------------------------------------------------------------
 MOVE_METHODS = ['move_down', 'move_left', 'move_right', 'move_up',
                 'move_lower_left', 'move_lower_right', 'move_upper_left',
                 'move_upper_right', 'jump']
 
 # Go through each method
 for method in MOVE_METHODS
   # Create the script for the specific method
   PROG = <<_END_
 def #{method}(*args)
   x,y = self.x, self.y
   super(*args)
   unless self.x == x && self.y == y
     $game_system.caterpillar.register_player_move(@move_speed, '#{method}', args, [self.x, self.y])
   end
 end
_END_
   # Run the script
   eval(PROG)
 end
end

#==============================================================================
# ** The simply version of my little module add-on. Will only be added if it
#    has not been added already. (Will not overwrite the extended if it is used)
#==============================================================================
class Module
 # Prevent adding the method again should it already be present.
 unless self.method_defined?('attr_sec_accessor')
   def attr_sec_accessor(sym, default = 0)
     attr_writer sym
     attr_sec_reader sym, default
   end
   
   def attr_sec_reader(sym, default = 0)
     sym = sym.id2name
     string = "def #{sym};" +
              "  @#{sym} = #{default}  if @#{sym}.nil?;" +
              "  @#{sym};" +
              "end;"
     module_eval(string)
   end
 end
end

#==============================================================================
# ** Game_System - The caterpillar class added
#==============================================================================
class Game_System
 attr_sec_accessor :caterpillar, 'Game_Caterpillar.new'
end

#==============================================================================
# ** Game_Event - Checking of name and implementation of movement for actors
#==============================================================================
class Game_Event < Game_Character
 ##
 # Attributes
 #
 attr_sec_accessor :move_list, '[]'
 attr_accessor     :move_speed
 attr_writer       :character_name
 ##
 # Aliases
 #
 unless self.method_defined?('zeriab_caterpillar_game_event_passable?')
   alias zeriab_caterpillar_game_event_initialize :initialize
   alias zeriab_caterpillar_game_event_passable?  :passable?
   if Module.constants.include?('SDK')
     alias zeriab_caterpillar_game_event_update_movement  :update_movement
   else
     alias zeriab_caterpillar_game_event_update  :update
   end
 end
 #--------------------------------------------------------------------------
 # * Object Initialization
 #--------------------------------------------------------------------------
 def initialize(map_id, event, *args)
   # Default update
   zeriab_caterpillar_game_event_initialize(map_id, event, *args)
   # Check if the caterpillar is active
   return unless $game_system.caterpillar.active?
   # Check for caterpillar actor denomination
   check_caterpillar
 end
 #--------------------------------------------------------------------------
 # * Check for caterpillar actor denomination
 #--------------------------------------------------------------------------
 def check_caterpillar
   # Check for caterpillar actor denomination (Last is used if more present)
   @event.name.gsub(/\\cat_actor\[([0-9]+)\]/i) {@caterpillar_actor = $1 }
   # Check if an valid denomination is found.
   if @caterpillar_actor.is_a?(String)
     @caterpillar_actor = @caterpillar_actor.to_i
     if $data_actors[@caterpillar_actor].nil?
       @caterpillar_actor = nil
     else
       $game_system.caterpillar.add_actor(self, @caterpillar_actor)
     end
   end
 end
 #--------------------------------------------------------------------------
 # * Check passability
 #--------------------------------------------------------------------------
 def passable?(*args)
   if @caterpillar_actor.nil? || move_list.empty? ||
      !$game_system.caterpillar.active?
     return zeriab_caterpillar_game_event_passable?(*args)
   else
     return true
   end
 end
 ##
 # SDK and Non-SDK stuff
 #
 if Module.constants.include?('SDK')
   #------------------------------------------------------------------------
   # * Update Movement
   #------------------------------------------------------------------------
   def update_movement
     if @caterpillar_actor.nil? || move_list.empty? ||
        !$game_system.caterpillar.active?
       return zeriab_caterpillar_game_event_update_movement
     end
     # Interrupt if not stopping
     if jumping? or moving?
       return
     end
     # Retrive the command
     command = move_list[0]
     # Call the command
     method(command[0]).call(*command[1])
     # Make sure the x and y are right in the end
     @x, @y = *command[2]
     # Remove the command
     move_list.pop
   end
 else # Non-SDK version
   #------------------------------------------------------------------------
   # * Update Movement
   #------------------------------------------------------------------------
   def update
     # Interrupt if not stopping
     no_move = jumping? or moving?
     # Update
     zeriab_caterpillar_game_event_update
     # Check if it should return
     if $game_system.caterpillar.active? && @caterpillar_actor != nil &&
        !move_list.empty? && !no_move
       # Retrive the command
       command = move_list[0]
       # Call the command
       method(command[0]).call(*command[1])
       # Make sure the x and y are right in the end
       @x, @y = *command[2]
       # Remove the command
       move_list.pop
     end
   end
 end
 #--------------------------------------------------------------------------
 # * Bring back an erased event
 #--------------------------------------------------------------------------
 def unerase
   @erased = false
   refresh
 end
end

#==============================================================================
# ** Game_Map - Clear the caterpillar when changing to a new map
#==============================================================================
class Game_Map
 ##
 # Aliases
 #
 unless self.method_defined?('zeriab_caterpillar_game_map_setup')
   alias zeriab_caterpillar_game_map_setup :setup
 end
 #--------------------------------------------------------------------------
 # * Transfer Player
 #--------------------------------------------------------------------------
 def setup(*args)
   $game_system.caterpillar.clear
   zeriab_caterpillar_game_map_setup(*args)
 end
end

#==============================================================================
# ** Game_Switches - Listening to special switch changes
#==============================================================================
class Game_Switches
 ##
 # Aliases
 #
 unless self.method_defined?('zeriab_caterpillar_game_switches_setter')
   alias zeriab_caterpillar_game_switches_setter :[]=
 end
 #--------------------------------------------------------------------------
 # * Setter
 #--------------------------------------------------------------------------
 def []=(switch_id, value, *args)
   zeriab_caterpillar_game_switches_setter(switch_id, value, *args)
   if switch_id == Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH
     $game_system.caterpillar.refresh
   elsif switch_id == Game_Caterpillar::REMOVE_VISIBLE_ACTORS
     if value
       $game_system.caterpillar.erase_non_party_events
     else
       $game_system.caterpillar.unerase_all
     end
   end
 end
end

#==============================================================================
# ** Interpreter - Check for use of certain commands
#==============================================================================
class Interpreter
 ##
 # Aliases
 #
 unless self.method_defined?('zeriab_caterpillar_interpreter_command_129')
   alias zeriab_caterpillar_interpreter_command_129 :command_129
   alias zeriab_caterpillar_interpreter_command_322 :command_322
 end
 #--------------------------------------------------------------------------
 # * Change Party Member
 #--------------------------------------------------------------------------
 def command_129
   result = zeriab_caterpillar_interpreter_command_129
   $game_system.caterpillar.refresh
   return result
 end
 #--------------------------------------------------------------------------
 # * Change Actor Graphic
 #--------------------------------------------------------------------------
 def command_322
   result = zeriab_caterpillar_interpreter_command_322
   $game_system.caterpillar.update
   return result
 end
end



Instructions

There are instructions in the header, but they might be hard to understand.
I have tried to break down the instructions so they hopefully are easier to understand.

Big and evil instructions: ShowHide

The script uses map events with special tags in their name.
The map events are tied to specific actors.
If you want an event to represent the actor with id 1 in the database then somewhere in the name of the event put this: \cat_actor[1]
If you want an event to represent the actor with id 19 then use this instead: \cat_actor[19]
Basically you put in \cat_actor[id of actor] in the name of the event in question.
Note that you need to do this for every map. Yes, a lot of work.

You copy the script and paste it just above main. (I.e. you open the script editor, scroll to the bottom of the left form, click on main, press insert and paste the script into the right form)

In the script pay attention to the area just below the script header:
#==============================================================================
class Game_Caterpillar
 CATERPILLAR_ACTIVE_SWITCH = 23
 REMOVE_VISIBLE_ACTORS = true
 MAX_ACTORS = 4
 #--------------------------------------------------------------------------


This is the area of script where you can customize the script. I will go through each of the lines and explain what they do:

CATERPILLAR_ACTIVE_SWITCH = 23
This line will allow you to control whether the caterpillar is active or not by specifying a switch.
By default you can see that we have CATERPILLAR_ACTIVE_SWITCH = 23 which means you can turn the caterpillar ON and OFF by turning switch 23 ON and OFF.
Notice that switch 23 by default start on OFF and you must turn the switch ON before the caterpillar 'works'.
Feel free to change the number 23 to any number you want, i.e. which switch you want.
If you for example want to use switch 0169 instead it should be CATERPILLAR_ACTIVE_SWITCH = 169.

REMOVE_VISIBLE_ACTORS = true
This determines whether events for actors not currently in the party should be erased or not.
You can set this to a number like REMOVE_VISIBLE_ACTORS = 21 if you want to specify it with a switch. In this example you can turn it ON and OFF by turning switch 21 ON and OFF.

MAX_ACTORS = 4
I believe this is self-explonatory. Only change this if you can have more than 4 actors. No harm is done if you have a lower max.

A little word of caution: Do not put leading 0's in front of numbers in ruby. The reason is that Ruby considers numbers with leading 0's as octadecimal. I.e. 0, 1, 2, ... , 6, 7, 10, 11, ...   No 8 nor 9. So for example 15 oct = 13 and 8 oct and 9 oct gives an error.


Here are two call scripts you can use if you feel the caterpillar isn't updated properly like problems with the graphic. Also highly useful should you have custom scripts and need to tell the caterpillar script has changed: (The call script is the event command on the bottom-right of page 3)

This will update the caterpillar to make sure the right events and right graphics are used.
$game_system.caterpillar.update


This will refresh the caterpillar which pretty much 'starts on a fresh'. All the events will be placed the same place as the player. As if you were teleported. Only use this if the update don't work.
$game_system.caterpillar.refresh




FAQ

Why did you make a caterpillar script when so many are around?
Despain requested a script that worked with a particular message script and Wumpi requested a script which used map events.
It didn't seem like there was such a caterpillar script out there although I admittedly didn't search hard.
So I made this believing it would work differently from other caterpillars scripts.

How do you get the events to act differently when they walk in the caterpillar and when they don't?
Create a page which has the caterpillar activation switch as precondition. If that is the top page (the one with the highest number) then that will be the event's functionality when in the caterpillar.
If you have problems with the graphic of some events not being what they are supposed to be then add a 1 frame wait and a script call:
$game_system.caterpillar.update

This should solve the problem. The 1 frame wait is necessary or the page change will not have been registered before the update and the result is the same.

The caterpillar made me stuck
Set the events of the caterpillar to Through. (Options area to the lower right)


Compatibility

This script will most likely not work with any other caterpillar system.
Saves made with this caterpillar script cannot be used should you remove it again. (Saves without it will work with it)
It should work both without and with the SDK and I believe it should with both SDK 1.x and SDK 2.x although I have only tested SDK 1.5.


Credits and Thanks

Credits goes to Zeriab for creating the system

I would like to thank Despain and Wumpi for requesting the script.
I would like to thank everyone using their time to try and use my system.
I would like to thank everyone reading this topic.

Thanks.


Author's Notes

I would be delighted if you report any bug, errors or issues you find.
In fact I would be delighted if you took the time and replied even if you have nothing to report.
Suggestions are more than welcome

And finally: ENJOY!

- Zeriab

Fantasist

I wanted to event this for my game actually, you amaze me as always Zeriab m(_)m
*powers up*
Do you like ambient/electronic music? Then you should promote a talented artist! Help out here. (I'm serious. Just listen to his work at least!)


The best of freeware reviews: Gizmo's Freeware Reviews




Valcos

Holy crap! Surprise much? Nice, didnt even know you can do something like this :huh:
"We are all in the gutter, but some of us are looking at the stars."
-Oscar De La Hoya

Starrodkirby86

Question. How well does this work with Tons, as in...is it better? There are a lot of Caterpillar scripts out and I want to know how this one is awesome. I know it is of course because of the Zeriab brand, that's something in itself for acclaim, but I want to know anything else pretty spiffy about the whole system. I didn't understand the answer you wrote here except for the Despain and Wumpi thing with compatibility with a Message System...
QuoteDespain requested a script that worked with a particular message script and Wumpi requested a script which used map events.
It didn't seem like there was such a caterpillar script out there although I admittedly didn't search hard.
So I made this believing it would work differently from other caterpillars scripts.

One thing, there wasn't a Key Term and a Type so I edited your post so that it is there. If you do not feel that it is the right Key Term/Type, considering I'm a total mundane with it comes to this, feel free to edit it. :)

What's osu!? It's a rhythm game. Thought I should have a signature with a working rank. ;P It's now clickable!
Still Aqua's biggest fan (Or am I?).




Zeriab

August 26, 2008, 05:11:34 am #4 Last Edit: August 26, 2008, 01:31:24 pm by Zeriab
Thanks for adding the Key Term and Type. I forgot :'(

It is different from other caterpillars in that you have to create an event on the map in the editor for each actor. No map event = no caterpillar.
You can treat this event just like any other event.  You can interact with it. You can use normal event commands to get its location and etc.

It is neither better nor worse in general. It's more that in some situations its preferable and in other it's not.
This script requires more work than other caterpillars to work.
While the script is a plug'n'play script it requires a fair amount of work with creating events and etc. for getting it to work.
If you disable the caterpillar the events following you will stop and act like any other event. This should in theory be great for cutscenes.

The idea is more control for more work. Since it is events then there is also a higher chance for compatibility.

Edit: The moved topic is lovely. Such a cute picture <3

Blizzard

*cough* ... new template with HR (horizontal rule)... *cough* <_<; *points at Zeriab or SRK or shdw to fix it* <_<;
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Zeriab

That's what I get for copying the template of an old script topic  :shy:

Killerclaws

So, so sorry for necroposting but....
I really want to use this script, but the link to the script doesn't work and I can't download the demo. :/ Is there any other way for me to get the script? Thanks!

LiTTleDRAgo

Spoiler: ShowHide
#==============================================================================
# ** Zeriab's Caterpillar Script
#------------------------------------------------------------------------------
# Zeriab
# 1.0
# 2008-08-25
#------------------------------------------------------------------------------
# This script creates a caterpillar of the party members by using events.
#------------------------------------------------------------------------------
# Paste this script just above main.
#
# Put \cat_actor[3] in the name of an event and it will be considered the event
# for the actor with id 3. The name could for example be "Cyrus\cat_actor[3]"
#
# The switch number specified with CATERPILLAR_ACTIVE_SWITCH (default is 23) is
# used to determine whether the events should be positioned in the caterpillar
# or not. Then the switch is off they are just like any other event.
# You can do CATERPILLAR_ACTIVE_SWITCH = true for always having the caterpillar
# enabled
#
# The REMOVE_VISIBLE_ACTORS (default is true) is used to determine whether
# actor event not in the party should be erased or not.
# If it is set to an integer rather than true or false the switch with the
# corresponding id is used. For example REMOVE_VISIBLE_ACTORS = 21 will allow
# you to determine whether the events should be erased or not depending whether
# switch 21 is OFF or ON.
#
# The MAX_ACTORS (default is 4) is used to determine how many player moves
# should be remembered. Only change this if you can have a party with more than
# 4 actors.
#==============================================================================
class Game_Caterpillar
  CATERPILLAR_ACTIVE_SWITCH = 23
  REMOVE_VISIBLE_ACTORS = true
  MAX_ACTORS = 4
  #--------------------------------------------------------------------------
  # * Initialize the caterpillar
  #--------------------------------------------------------------------------
  def initialize
    @actors = []
    @actor_id_to_event = {}
    @move_list = []
  end
  #--------------------------------------------------------------------------
  # * Clear the caterpillar data
  #--------------------------------------------------------------------------
  def clear
    @actors.clear
    @actor_id_to_event.clear
    @move_list.clear
  end
  #--------------------------------------------------------------------------
  # * Check if the caterpillar script is active
  #--------------------------------------------------------------------------
  def active?
    if CATERPILLAR_ACTIVE_SWITCH.is_a?(Integer)
      return $game_switches[CATERPILLAR_ACTIVE_SWITCH]
    else
      return CATERPILLAR_ACTIVE_SWITCH
    end
  end
  #--------------------------------------------------------------------------
  # * Add an actor event to the caterpillar
  #--------------------------------------------------------------------------
  def add_actor(event, actor_id)
    @actor_id_to_event[actor_id] = event
    event.move_list.clear
    added = false
    for actor in $game_party.actors
      if actor.id == actor_id
        @actors << event
        event.moveto($game_player.x, $game_player.y)
        added = true
      end
    end
    if remove_visible_actors? && !added && active?
      event.erase
    end
  end
  #--------------------------------------------------------------------------
  # * Check if visible actors should be removed
  #--------------------------------------------------------------------------
  def remove_visible_actors?
    if REMOVE_VISIBLE_ACTORS.is_a?(Integer)
      return $game_switches[REMOVE_VISIBLE_ACTORS]
    else
      return REMOVE_VISIBLE_ACTORS
    end
  end
  #--------------------------------------------------------------------------
  # * If the game player has been centered. I.e. teleported somewhere.
  #--------------------------------------------------------------------------
  def center
    # Check if the caterpillar is active
    return unless active?
    # Clear the move_llist
    @move_list.clear
    # Refresh the caterpillar
    update
    # Move the actors to the new place
    for event in @actors
      event.moveto($game_player.x, $game_player.y)
      event.move_list.clear
    end
  end
  #--------------------------------------------------------------------------
  # * Refresh the caterpillar. (Use sparingly)
  #--------------------------------------------------------------------------
  def refresh
    # Check if the caterpillar is active
    return unless active?
    # Clear the data
    clear
    # Check each event
    for event in $game_map.events.values
      if event.is_a?(Game_Event)
        event.check_caterpillar
      end
    end
    # Center the events around the player
    center
    # Update the caterpillar
    update
  end
  #--------------------------------------------------------------------------
  # * Register a player move
  #--------------------------------------------------------------------------
  def register_player_move(move_speed, *args)
    # Check if the caterpillar is active
    return unless active?
    # Add the new command
    @move_list.unshift([move_speed, args])
    # Append the new moves to the caterpillar events
    update_actor_movement
    # Check if the last command should be removed
    if @move_list.size > MAX_ACTORS + 1
      # Remove the last move command
      @move_list.pop
    end
  end
  #--------------------------------------------------------------------------
  # * Updates the actors movement.
  #--------------------------------------------------------------------------
  def update_actor_movement
    for i in 0...@actors.size
      if i + 1 < @move_list.size
        command = @move_list[i + 1]
        actor = @actors[i]
        actor.move_list.unshift(command[1])
        actor.move_speed = command[0]
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Update the caterpillar.
  #--------------------------------------------------------------------------
  def update
    # Check if the caterpillar is active
    return unless active?
    old_actors = @actors
    @actors = []
    # Create a copy of the party actors
    caterpillar = $game_party.actors.dup
    # Remove the first element
    caterpillar.shift
    # Go through each actor that's possible present in the caterpillar
    for actor in caterpillar
      event = @actor_id_to_event[actor.id]
      unless event.nil?
        @actors << event
        event.unerase if remove_visible_actors?
        event.character_name = actor.character_name
      end
    end
    if remove_visible_actors?
      # Go through the old actors to see if any should be erased
      for actor in old_actors
        unless @actors.include?(actor)
          actor.erase
        end
      end
    else
      # Erase the event for the current player should there be one
      event = @actor_id_to_event[$game_party.actors[0].id]
      event.erase unless event.nil?
    end
  end
  #--------------------------------------------------------------------------
  # * Unerase all erased actor events
  #--------------------------------------------------------------------------
  def unerase_all
    for event in @actor_id_to_event.values
      event.unerase
    end
  end
  #--------------------------------------------------------------------------
  # * Erase actor events not in the party
  #--------------------------------------------------------------------------
  def erase_non_party_events
    for event in @actor_id_to_event.values
      event.erase unless @actors.include?(event)
    end
  end
end

#==============================================================================
# ** Game_Player - Registration of movement
#==============================================================================
class Game_Player < Game_Character
  unless self.method_defined?('zeriab_caterpillar_game_player_center')
    alias_method(:zeriab_caterpillar_game_player_center, :center)
  end
  #--------------------------------------------------------------------------
  # * When the player is centered (i.e. teleported somewhere)
  #--------------------------------------------------------------------------
  def center(*args)
    zeriab_caterpillar_game_player_center(*args)
    $game_system.caterpillar.center
  end
 
  #--------------------------------------------------------------------------
  # * Generate registration of player moves to the caterpillar code
  #--------------------------------------------------------------------------
  MOVE_METHODS = ['move_down', 'move_left', 'move_right', 'move_up',
                  'move_lower_left', 'move_lower_right', 'move_upper_left',
                  'move_upper_right', 'jump']
 
  # Go through each method
  for method in MOVE_METHODS
    # Create the script for the specific method
    PROG = <<_END_
  def #{method}(*args)
    x,y = self.x, self.y
    super(*args)
    unless self.x == x && self.y == y
      $game_system.caterpillar.register_player_move(@move_speed, '#{method}', args, [self.x, self.y])
    end
  end
_END_
    # Run the script
    eval(PROG)
  end
end

#==============================================================================
# ** The simply version of my little module add-on. Will only be added if it
#    has not been added already. (Will not overwrite the extended if it is used)
#==============================================================================
class Module
  # Prevent adding the method again should it already be present.
  unless self.method_defined?('attr_sec_accessor')
    def attr_sec_accessor(sym, default = 0)
      attr_writer sym
      attr_sec_reader sym, default
    end
   
    def attr_sec_reader(sym, default = 0)
      sym = sym.id2name
      string = "def #{sym};" +
               "  @#{sym} = #{default}  if @#{sym}.nil?;" +
               "  @#{sym};" +
               "end;"
      module_eval(string)
    end
  end
end

#==============================================================================
# ** Game_System - The caterpillar class added
#==============================================================================
class Game_System
  attr_sec_accessor :caterpillar, 'Game_Caterpillar.new'
end

#==============================================================================
# ** Game_Event - Checking of name and implementation of movement for actors
#==============================================================================
class Game_Event < Game_Character
  ##
  # Attributes
  #
  attr_sec_accessor :move_list, '[]'
  attr_accessor     :move_speed
  attr_writer       :character_name
  ##
  # Aliases
  #
  unless self.method_defined?('zeriab_caterpillar_game_event_passable?')
    alias zeriab_caterpillar_game_event_initialize :initialize
    alias zeriab_caterpillar_game_event_passable?  :passable?
    if Module.constants.include?('SDK')
      alias zeriab_caterpillar_game_event_update_movement  :update_movement
    else
      alias zeriab_caterpillar_game_event_update  :update
    end
  end
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(map_id, event, *args)
    # Default update
    zeriab_caterpillar_game_event_initialize(map_id, event, *args)
    # Check if the caterpillar is active
    return unless $game_system.caterpillar.active?
    # Check for caterpillar actor denomination
    check_caterpillar
  end
  #--------------------------------------------------------------------------
  # * Check for caterpillar actor denomination
  #--------------------------------------------------------------------------
  def check_caterpillar
    # Check for caterpillar actor denomination (Last is used if more present)
    @event.name.gsub(/\\cat_actor\[([0-9]+)\]/i) {@caterpillar_actor = $1 }
    # Check if an valid denomination is found.
    if @caterpillar_actor.is_a?(String)
      @caterpillar_actor = @caterpillar_actor.to_i
      if $data_actors[@caterpillar_actor].nil?
        @caterpillar_actor = nil
      else
        $game_system.caterpillar.add_actor(self, @caterpillar_actor)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Check passability
  #--------------------------------------------------------------------------
  def passable?(*args)
    if @caterpillar_actor.nil? || move_list.empty? ||
       !$game_system.caterpillar.active?
      return zeriab_caterpillar_game_event_passable?(*args)
    else
      return true
    end
  end
  ##
  # SDK and Non-SDK stuff
  #
  if Module.constants.include?('SDK')
    #------------------------------------------------------------------------
    # * Update Movement
    #------------------------------------------------------------------------
    def update_movement
      if @caterpillar_actor.nil? || move_list.empty? ||
         !$game_system.caterpillar.active?
        return zeriab_caterpillar_game_event_update_movement
      end
      # Interrupt if not stopping
      if jumping? or moving?
        return
      end
      # Retrive the command
      command = move_list[0]
      # Call the command
      method(command[0]).call(*command[1])
      # Make sure the x and y are right in the end
      @x, @y = *command[2]
      # Remove the command
      move_list.pop
    end
  else # Non-SDK version
    #------------------------------------------------------------------------
    # * Update Movement
    #------------------------------------------------------------------------
    def update
      # Interrupt if not stopping
      no_move = jumping? or moving?
      # Update
      zeriab_caterpillar_game_event_update
      # Check if it should return
      if $game_system.caterpillar.active? && @caterpillar_actor != nil &&
         !move_list.empty? && !no_move
        # Retrive the command
        command = move_list[0]
        # Call the command
        method(command[0]).call(*command[1])
        # Make sure the x and y are right in the end
        @x, @y = *command[2]
        # Remove the command
        move_list.pop
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Bring back an erased event
  #--------------------------------------------------------------------------
  def unerase
    @erased = false
    refresh
  end
end

#==============================================================================
# ** Game_Map - Clear the caterpillar when changing to a new map
#==============================================================================
class Game_Map
  ##
  # Aliases
  #
  unless self.method_defined?('zeriab_caterpillar_game_map_setup')
    alias zeriab_caterpillar_game_map_setup :setup
  end
  #--------------------------------------------------------------------------
  # * Transfer Player
  #--------------------------------------------------------------------------
  def setup(*args)
    $game_system.caterpillar.clear
    zeriab_caterpillar_game_map_setup(*args)
  end
end

#==============================================================================
# ** Game_Switches - Listening to special switch changes
#==============================================================================
class Game_Switches
  ##
  # Aliases
  #
  unless self.method_defined?('zeriab_caterpillar_game_switches_setter')
    alias zeriab_caterpillar_game_switches_setter :[]=
  end
  #--------------------------------------------------------------------------
  # * Setter
  #--------------------------------------------------------------------------
  def []=(switch_id, value, *args)
    zeriab_caterpillar_game_switches_setter(switch_id, value, *args)
    if switch_id == Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH
      $game_system.caterpillar.refresh
    elsif switch_id == Game_Caterpillar::REMOVE_VISIBLE_ACTORS
      if value
        $game_system.caterpillar.erase_non_party_events
      else
        $game_system.caterpillar.unerase_all
      end
    end
  end
end

#==============================================================================
# ** Interpreter - Check for use of certain commands
#==============================================================================
class Interpreter
  ##
  # Aliases
  #
  unless self.method_defined?('zeriab_caterpillar_interpreter_command_129')
    alias zeriab_caterpillar_interpreter_command_129 :command_129
    alias zeriab_caterpillar_interpreter_command_322 :command_322
  end
  #--------------------------------------------------------------------------
  # * Change Party Member
  #--------------------------------------------------------------------------
  def command_129
    result = zeriab_caterpillar_interpreter_command_129
    $game_system.caterpillar.refresh
    return result
  end
  #--------------------------------------------------------------------------
  # * Change Actor Graphic
  #--------------------------------------------------------------------------
  def command_322
    result = zeriab_caterpillar_interpreter_command_322
    $game_system.caterpillar.update
    return result
  end
end


Retrieved at December 14, 2008

ForeverZer0

Thanks, LiTTleDRAgo. ++

I added the script to the OP. Anyone have a copy of the demo?
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Heretic86

Quote from: ForeverZer0 on September 02, 2013, 11:29:03 am
Thanks, LiTTleDRAgo. ++

I added the script to the OP. Anyone have a copy of the demo?


I have a Copy.  You can use it as a Mirror too.
http://www.775.net/~heretic/downloads/CaterpillarDemo.rar

He uploaded it to Sendspace and Mediafire.  Sendspace Link is dead.
http://www.mediafire.com/download/nztdyjmr2vd/CaterpillarDemo.rar

https://sites.google.com/site/zeriabsjunk/scripts-/caterpillar
Quote...

Demo

Currently I can only present a demo which includes Wachunga's Multiple Message Windows which requires SDK 1.5: http://www.sendspace.com/file/s5hkl7 (mediafire)
This is because Wumpi and Despain requested it to work with that message system. (Only the caterpillar script is my work. I had nothing to do with the rest)

...


This version is all his and I did not modify it at all.  I did use this as the source base for my caterpillar, so the scripts are similar.  This script does have limited features and functionality compared to my alterations as I've worked on extensively, but for a simpler caterpillar script, it does the job and is probably more compatible.  I havent seen Zeriab around for a long time so its probably worth noting that he will probably not be providing any sort of support for this script.
Current Scripts:
Heretic's Moving Platforms

Current Demos:
Collection of Art and 100% Compatible Scripts

(Script Demos are all still available in the Collection link above.  I lost some individual demos due to a server crash.)

ForeverZer0

Thank you, much, links in the OP should all be fixed now.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.