#==============================================================================
# ** Zeriab's Caterpillar Script
#------------------------------------------------------------------------------
# Zeriab
# 1.0
# 2008-08-16
#------------------------------------------------------------------------------
# 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.
#
# 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 = false
MAX_ACTORS = 2
##
# 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
##
# 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 && $game_switches[CATERPILLAR_ACTIVE_SWITCH]
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 center. I.e. teleported somewhere.
#
def center
# Check if the caterpillar is active
return unless $game_switches[CATERPILLAR_ACTIVE_SWITCH]
# 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 $game_switches[CATERPILLAR_ACTIVE_SWITCH]
# 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 $game_switches[CATERPILLAR_ACTIVE_SWITCH]
# 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 $game_switches[CATERPILLAR_ACTIVE_SWITCH]
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
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
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
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
class Game_System
attr_sec_accessor :caterpillar, 'Game_Caterpillar.new'
end
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_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH]
# 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_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH]
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_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH]
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_switches[Game_Caterpillar::CATERPILLAR_ACTIVE_SWITCH] &&
@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
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
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
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