To use this code, grab the demo in the first link, then just replace ALL the code in Platforms with this version.
# Version 2
# Notes to self
#
# LOOP MAP TAKEOFF BUG FIXED - FULLY FIXED
#
# DIAGONAL MOVEMENT BUG - FULLY FIXED
# (Dont use Script Calls for Random 8D, replacement of def move_random works, or
# by putting a 1 frame wait after script random 8d Movement)
#
# Why waste time processing Real Distance for Platform if I only use
# its Move Speed anyway? Clamping to Platform Real Values causes takeoff
# issues in movement - Pull the Code and clean up.
#
#
# Player Transfer Stuff
#
# Event Transfer Stuff
#
# Event and Player Transfers, add an argument to allow "dropping" an
# character onto a Platform without Boarding? Hmm, set a character
# flag and add another optional argument to platform_boardable?(c, option = nil)
#
#
# Thnk about how the Caterpillar Anti Lag works and how it relates
# to Platform and Platform Master concept to prevent Animation Desyncrhonization
#
#
#
# Interpreter Stuff (Msg Boxes, etc) like starting? or lock?
# - Able to move while Dialog is on screen HACK? Nope. Bug, and part of
# the default engine! Player Move Random (repeat) and Touch Event
# will trigger Touch Events! Ha Ha! How to fix that. Leave as Option?
#
#
# Think about Page Changes for Platform Events - Unboard Riders? Reboard?
#
# Think about STAIRS, shouldnt be too hard, I can just alias my own stuff
# and make a requirement to place Platform Script below Stairs. Is there
# another way to do that?
#
# Interpreter - Freeze Platform movement if Interpreter Running as Option?
#
# Condiser adding in Touch Triggers ** Ok, done, but they have to be THROUGH
# on Impassable surfaces.
#
# Look at the Triggers, they seem to be Triggerable from too far away?
#
# Test to see if Random Movement - Move Route Repeat can trigger Touch Events
# and continue to move with default scripts
#
# SDK Stuff, movement is ok, but check other Interpreter and Lock stuff
#
# Caterpillar Stuff
#
# Test stepping on to other surfaces, Ice, Stairs - Ice most likely wont
# work as a Platform unless stepping off, but stairs should work just fine.
#
# SCROLLING CLOUDS GLITCH on edges of Looping Maps
#
# DONT FORGET TO UPDATE MAP HASHES IN COLLISION OPTIMIZER ON TRANSFER
# DONT FORGET TO UPDATE MAP HASHES IN COLLISION OPTIMIZER ON TRANSFER
# DONT FORGET TO UPDATE MAP HASHES IN COLLISION OPTIMIZER ON TRANSFER
#
# ----
#
# Comment the Waiting and Non Waiting "Hack" to make Platforms be used
# for things Unexpected
#
# Look at Restrict Tile passage, did I ever put anything in for No Terrain Tags?
#
# Is the Collision Problem because the Hash is not Updated when Character
# position is Updated? - I think so, I think that if fixed? DONE, but check
#
# Take a look heavily at Collision Optimizer, when Events are moved about
# the Hash Map may need to be updated because the Old Location isnt properly
# stored in the Hash Map of Events. Normal Event Updating allows Hash Map
# to self correct, but when using Event Commands to move an Event from
# one spot to another, those Events may have an Out of Date Hash Map, at
# least for one frame
# Check for Modular Passable Script - REQUIRED - DO NOT EDIT
unless $Modular_Passable
print "Fatal Error: Heretic's Moving Platforms\n",
"requires Heretics Modular Passable Script!\n\n",
"Modular Passable is Not Available or is below this script.\n",
"Modular Passable MUST be above this script.\n\n",
"The Game must now Exit"
exit
end
# Check for Heretic's Collision Optimizer Script - REQUIRED - DO NOT EDIT
unless Game_Map::method_defined?('events_hash_xy')
print "Fatal Error: Heretic's Moving Platforms\n",
"requires Heretics Collision Optimizer Script!\n\n",
"Collision Optimizer is Not Available or is below this script.\n",
"Collision Optimizer MUST be above this script.\n\n",
"The Game must now Exit"
exit
end
# If Loop Maps is being used, but is an old bugged version
if Game_Map::method_defined?('map_loop_passable?') and
(not Game_Map::const_defined?('Loop_Map_Version') or
Game_Map::Loop_Map_Version < 1.01)
print "Fatal Error: Heretic's Moving Platforms\n\n",
"The version of Looping Maps needs to\n be Version 1.01 or above.\n\n",
"This version of Looping Maps is out of date.\n\n",
"The Game must now Exit"
exit
end
#==============================================================================
# ** Game_System
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
# * Public Instance Variables - Game_System
#--------------------------------------------------------------------------
attr_accessor :platform_enabled # Enable or Disable Platforms
#--------------------------------------------------------------------------
# * Object Initialization
# - Adds Option for stepping on and off Platforms
#--------------------------------------------------------------------------
alias platform_system_initialize initialize unless $@
def initialize
# Call Original or other Aliases
platform_system_initialize
# New Option for allowing Platforms
@platform_enabled = true
end
end
#==============================================================================
# ** Game_Map
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Public Instance Variables - Game_Map
#--------------------------------------------------------------------------
attr_accessor :platform_groups # Groups of Platforms
attr_reader :platform_allow_update # Updates Platforms out of order
#--------------------------------------------------------------------------
# * Object Initialization - Game Map
#--------------------------------------------------------------------------
alias platform_map_initialize initialize unless $@
def initialize
# Call Original or other Aliases
platform_map_initialize
# New Array to contain each Platform Group
@platform_groups = {}
end
#--------------------------------------------------------------------------
# * Setup - Game_Map
#--------------------------------------------------------------------------
alias platform_map_setup setup unless $@
def setup(map_id)
# Current Map
current_map_id = @map_id
# If Changing to a New Valid Map
if map_id > 0 and map_id != @map_id
# New Hash to contain each Platform Group
@platform_groups = {}
# Reset the Player Platform properties
$game_player.on_platform = nil
end
# Call Original or other Aliases to Initialize and create Events
platform_map_setup(map_id)
end
#--------------------------------------------------------------------------
# * Update - Game_Map
#--------------------------------------------------------------------------
alias platform_map_main_update update unless $@
def update
# Call Original or other Aliases of Main Update Method
platform_map_main_update
# Update the Platforms Boarding and Unboarding
platforms_update_boarding
# Update the Platform Events out of order
platforms_update_groups
end
#--------------------------------------------------------------------------
# * Platforms Update Boarding - Game_Map
# - Checks and Clears any Boarding Flags
#--------------------------------------------------------------------------
def platforms_update_boarding
# Do not Update Out of Order if System Optin is not Enabled
return unless $game_system.platform_enabled
# Iterate the Groups (.values is needed for Hashes since its not an array)
for group in platform_groups.values
# Temporary Boarding Flags
group_boarding = false
clear_boarding = false
# Iterate each Platform
for platform in group
# Check each Platform for a Boarding Flag
if platform.platform_boarding and not group_boarding
# Select each Platform Rider and check for Movement and On Platform
for rider in platform.platform_riders
# If Rider is not Moving or Jumping
if rider.jumping? or rider.x * 128 != rider.real_x or
rider.y * 128 != rider.real_y
# Platform is still being Boarded / Unboarded
group_boarding = true
# Unable to Clear Boarding because Boarding is occuring
clear_boarding = false
# End Rider and Platform Iteration
break(2)
end
end
# Set the Clear Boarding Flag if we got here
clear_boarding = true
end
end
# Check the Group Boarding and Clear Boarding Flags
if clear_boarding and not group_boarding
# Iterate the Platform Events again and Clear any Boarding Flags
for platform in group
# Clear Boarding Flags
platform.platform_boarding = false
end
end
end
end
#--------------------------------------------------------------------------
# * Platforms Update Groups - Game_Map
# - Standard Event Updates so Platforms are Updated out of order
# - When platform_enabled is not turned on, Platforms update in order
#--------------------------------------------------------------------------
def platforms_update_groups
# Do not Update Out of Order if System Optin is not Enabled
return unless $game_system.platform_enabled
# Disable Updating Platform Events
@platform_allow_update = true
# Iterate the Groups (.values is needed for Hashes since its not an array)
for group in platform_groups.values
# Iterate each Platform
for platform in group
# Update each Platform as an Event
platform.platform_alternate_update
end
end
# Disable Updating Platform Events
@platform_allow_update = false
end
#--------------------------------------------------------------------------
# * Add Platform To Groups - Game_Map
# - Adds Platforms to each Group
#--------------------------------------------------------------------------
def add_platform_to_group(event)
# Get the Platform Group ID
id = event.platform
# Check that Array exists
@platform_groups[id] = [] unless @platform_groups[id].is_a?(Array)
# Add this Event to this Platform Group if it is not already there
@platform_groups[id].push(event) unless @platform_groups[id].include?(event)
end
#--------------------------------------------------------------------------
# * Event Tile Not Passable? - Game_Map
# - Prevents Boarding and Unboarding of Platforms if it is not Waiting
# - Prevents Characters with a \no_platforms Comment from any Movement
# - Allows Platforms to move thru ALL Characters unless the Event
# is a Platform of a different Platform Group (\platform[1] \platform[5])
# - Although there is some Event Iteration, it is very fast due to the
# number of Events selected is usually only 1 or 2 at top. This is also
# why Collision Optimizer is required.
# - See Modular Passable for Argument Details
#--------------------------------------------------------------------------
alias platform_event_tile_not_passable? event_tile_not_passable? unless $@
def event_tile_not_passable?(x,y,d,bit,event,self_event = nil, result = nil)
# If Self is a Platform and Event is not a Platform, or Matching Group
if self_event.platform and
(not event.platform or event.platform == self_event.platform)
# Passable - Platforms can not move thru other Platform Groups ONLY
return false
end
# If Platform
if event.platform and self_event
# Impassable - \no_platforms comment or @no_platforms property
return true if self_event.no_platforms
# Use these Checks if System Option is Enabled
if $game_system.platform_enabled
# Shorthand
platform = $game_map.events[self_event.on_platform]
# Check against the Platform Group
if not platform or platform.platform != event.platform
# Impassable if Platform can not be Boarded
return true if not event.platform_boardable?(self_event)
end
end
end
# If Character is on a Platform and checking Self Location
if self_event and self_event.on_platform and $game_system.platform_enabled
# Platform Shorthand
plat = $game_map.events[self_event.on_platform]
# Check if Platform is Moving
if plat.x * 128 != plat.real_x or plat.y * 128 != plat.real_y
# Determine next Location of Movement
new_x, new_y = self_event.make_new_xy_8d(x, y, d)
# If New Location is not Current Location since checked Here and There
if self_event.x != new_x or self_event.y != new_y
# Get Events at the New Location
events = get_events_at_xy(new_x, new_y)
# Default
found = false
# Iterate through the Events
for e in events
# If Event is not this Platform and is a Boardable Platform
if e.platform_boardable?(self_event)
# Another Platform has been found
found = true
# Quit Iterating for Performance
break
end
end
# Impassable - Unable to transfer to another Platform
return true if not found
end
end
end
# Call Original or other Aliases with new Results
platform_event_tile_not_passable?(x, y, d, bit, event, self_event, result)
end
end
#==============================================================================
# ** Game_Character
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Public Instance Variables - Game_Character
#--------------------------------------------------------------------------
attr_accessor :on_platform # Event ID of Platform
attr_accessor :no_platforms # Prevents NPC's riding Platforms
attr_reader :platform # Event acts as a Platform (Group ID)
#--------------------------------------------------------------------------
# * Increase Steps - Game_Character
# - Used to check for Platforms and Platform Boarding
#--------------------------------------------------------------------------
alias platform_increase_steps increase_steps unless $@
def increase_steps
# Call Original or other Aliases
platform_increase_steps
# Check for Platforms to Board
board_platforms
# Set a Flag that Passage was possible, thus increasing steps
@platform_increased_steps = true
end
#--------------------------------------------------------------------------
# * Board Platforms - Game_Character
# - Used to check for Platforms and Platform Boarding
# - Sets Flags for Unboarding or Transfer
#--------------------------------------------------------------------------
def board_platforms
# Check for Self Properties and System Enabled
if not @platform and not @no_platforms and not @through and
$game_system.platform_enabled and not player_platform_debug?
# Temporary Flag
platform_found = false
# Get Location (with Round on Looping Maps if enabled)
x, y = platform_xy
# Create a List of Events at the Location this Character just moved to
events = $game_map.get_events_at_xy(x, y)
# Current Platform Shorthand (may be nil)
platform = $game_map.events[@on_platform]
# Iterate through the Events to see if there is a Platform
for event in events
# If Event is a Platform and Platform is Boardable?
if event.platform_boardable?(self)
# If Platform has been Boarded
if event.platform_board_character(self)
# Set the Temporary Flag
platform_found = true
# Assign Event ID of Platform to Character
@on_platform = event.id
# If currently on a Platform
if platform
# If New Platform is in the same Platform Group
if platform.platform == event.platform
# Remove Self from old Platforms Riders
platform.platform_riders.delete(self)
else
# Store the Event ID of the Old Platform to remove later
@old_platform_id = platform.id
# Set Boarding Flags on both Platforms
platform.platform_boarding = true
event.platform_boarding = true
end
# Board the Platform
else
# Set Flag that Platform Boarding
event.platform_boarding = true
# Assign Event ID of Platform to Character
@on_platform = event.id
end
# Quit iterating the List of Events for Performance
break
end
end
end
# If on a Platform and suitable New Platforms were Boarded or Unboarded
if @on_platform and not platform_found
# Set the Boarding Flag on the current Platform
platform.platform_boarding = true
# Sets a Flag to remove character from Platforms Riders
@unboard_platform = true
end
end
end
#--------------------------------------------------------------------------
# * Player Platform Debug? - Game_Player
# - When CTRL Key is Pressed, Player can not board Platforms
#--------------------------------------------------------------------------
def player_platform_debug?
# Check Conditions for Player Debug Movement
return ($DEBUG and Input.press?(Input::CTRL) and @id == 0)
end
#--------------------------------------------------------------------------
# * Lock - Game_Character
# - Prevents Locking Platforms because it causes Animation Errors
#--------------------------------------------------------------------------
alias platform_lock lock unless $@
def lock
# Prevent Locking Platforms by pressing Enter
return if @platform
# Call Original or other Aliases
platform_lock
end
#--------------------------------------------------------------------------
# * Update - Game_Character
# - Removes Characters from Platforms when they step off or transfer
#--------------------------------------------------------------------------
alias platform_main_update update unless $@
def update
# Used for Debugging Player Movement
platform_player_debug_update if @id == 0
# Use Math to determine Moving due to Platforms changing the result
last_moving = (@x * 128 != @real_x or @y * 128 != @real_y)
# Call Main Update Method for Character
platform_main_update
# Clear the Flag that Passage was possible with Increase Steps
@platform_increased_steps = nil
# If no longer moving (using Platform Method of checking)
if last_moving and not moving? and not jumping?
# Clear Property
@dir_last_moved = nil
# If Transfer between Two Platform Groups
if @old_platform_id
# Remove Self from the Old Platforms Riders
$game_map.events[@old_platform_id].platform_riders.delete(self)
end
end
# If Flag has been set to Unboard from a Platform and no longer moving
if @unboard_platform and @on_platform and last_moving and
@x * 128 == @real_x and @y * 128 == @real_y
# Remove Self from Platform Riders
$game_map.events[@on_platform].platform_riders.delete(self)
# Clear the On Platform Event ID and Unboard Flag
@on_platform = nil
@unboard_platform = nil
end
end
#--------------------------------------------------------------------------
# * Passable? - Game_Character
# - This preserves a variable needed for motion set in diagonal aliases
#--------------------------------------------------------------------------
alias platform_main_passable? passable? unless $@
def passable?(x, y, d)
# Call Original or other Aliases to determine result
result = platform_main_passable?(x, y, d)
# If Direction is not a Diagonal
if not [1,3,7,9].include?(@dir_last_moved)
# Store Movement Direction if able to move
@dir_last_moved = (result) ? d : nil
end
# Return initial result
return result
end
#--------------------------------------------------------------------------
# * Move Lower Left - Game_Character
#--------------------------------------------------------------------------
alias platform_move_lower_left move_lower_left unless $@
def move_lower_left
# Call Original or other Aliases
platform_move_lower_left
# Save Diagonal Move Direction (1 is Lower Left, like on a Keypad)
@dir_last_moved = (@platform_increased_steps) ? 1 : nil
end
#--------------------------------------------------------------------------
# * Move Lower Right - Game_Character
#--------------------------------------------------------------------------
alias platform_move_lower_right move_lower_right unless $@
def move_lower_right
# Call Original or other Aliases
platform_move_lower_right
# Save Diagonal Move Direction (3 is Lower Right, like on a Keypad)
@dir_last_moved = (@platform_increased_steps) ? 3 : nil
end
#--------------------------------------------------------------------------
# * Move Upper Left - Game_Character
#--------------------------------------------------------------------------
alias platform_move_upper_left move_upper_left unless $@
def move_upper_left
# Call Original or other Aliases
platform_move_upper_left
# Save Diagonal Move Direction (7 is Upper Left, like on a Keypad)
@dir_last_moved = (@platform_increased_steps) ? 7 : nil
end
#--------------------------------------------------------------------------
# * Move Upper Right - Game_Character
#--------------------------------------------------------------------------
alias platform_move_upper_right move_upper_right unless $@
def move_upper_right
# Call Original or other Aliases
platform_move_upper_right
# Save Diagonal Move Direction (9 is Upper Right, like on a Keypad)
@dir_last_moved = (@platform_increased_steps) ? 9 : nil
end
#------------------------------------------------------------------------
# * Platform Align Character - Game_Character
# - Fixes Riders of a Platform with the Platform Position
#------------------------------------------------------------------------
def platform_align_character(x_adj, y_adj, dist_rx, dist_ry)
# Adjust the X and Y with the Distance the Platform moved in Logical Values
@x += x_adj
@y += y_adj
# Adjust Real X and Y with the Distance the Platform moved in Real Values
@real_x += dist_rx
@real_y += dist_ry
# If Game Player (Player has an ID of 0)
if @id == 0
# Scroll the Screen adjusting for Platform Corrections
platform_scroll_map_update(@real_x - dist_rx, @real_y - dist_ry)
# If X or Y changed
if x_adj != 0 or y_adj != 0 and not
$game_system.map_interpreter.running?
# Check if Movement has caused any Event Touch Triggers
check_event_trigger_here([1,2])
end
end
end
#------------------------------------------------------------------------
# * Platform Dist - Game_Character
# - Distance in Logical Coordinates (no Loop Map Round)
#------------------------------------------------------------------------
def platform_distance(x, y)
return [@x - x, @y - y]
end
#------------------------------------------------------------------------
# * Platform Real Distance - Game_Character
# - Distance in Real Coordinates (no Loop Map Round)
#------------------------------------------------------------------------
def platform_real_distance(rx, ry)
return [@real_x - rx, @real_y - ry]
end
#------------------------------------------------------------------------
# * Platform XY - Game_Character
# - Returns X and Y values of Character allowing for alias adjustment
#------------------------------------------------------------------------
def platform_xy
# Return the X and Y values of this Character as an array
return [@x, @y]
end
#------------------------------------------------------------------------
# * Platform X No Match? - Game_Character
# real_x : Real X coordinate of Character
# platform_real_x : Real X coordinate of Platform Event
#------------------------------------------------------------------------
def platform_x_no_match?(real_x, platform_real_x)
# Return whether or not the Real X and Platform Real X values match
return (real_x != platform_real_x)
end
#------------------------------------------------------------------------
# * Platform Y No Match? - Game_Character
# real_y : Real Y coordinate of Character
# platform_real_y : Real Y coordinate of Platform Event
#------------------------------------------------------------------------
def platform_y_no_match?(real_y, platform_real_y)
# Return whether or not the Real Y and Platform Real Y values match
return (real_y != platform_real_y)
end
#------------------------------------------------------------------------
# * Moving X? - Game_Character
#------------------------------------------------------------------------
def platform_moving_x?
# Get the Platform Event
platform = $game_map.events[@on_platform]
# If Self is not the Platform Event and Plaform is moving on X
if platform.x * 128 != platform.real_x
# Movement is occuring on X if coordinates do not match the Platform
return platform_x_no_match?(@real_x, platform.real_x)
end
# Movement X determined by comparison of logical and real coordinates
return @real_x != @x * 128
end
#------------------------------------------------------------------------
# * Moving Y? - Game_Character
#------------------------------------------------------------------------
def platform_moving_y?
# Get the Platform Event
platform = $game_map.events[@on_platform]
# If Self is not the Platform Event and Plaform is moving on Y
if platform.y * 128 != platform.real_y
# Movement is occuring on Y if coordinates do not match the Platform
return platform_y_no_match?(@real_y, platform.real_y)
end
# Movement Y determined by comparison of logical and real coordinates
return @real_y != @y * 128
end
#--------------------------------------------------------------------------
# * Moving? - Game_Character
# - Modifies return value of moving? to allow character movement while on
# a platform and checks for unboarding from a Platform
# - While on a Platform, a Character is not considered moving unless
# the real coordinates of the platform and character do not match
#--------------------------------------------------------------------------
alias platform_moving? moving? unless $@
def moving?
# If Character is on a Platform and Option is Enabled
if @on_platform and $game_system.platform_enabled
# Use these methods to check for Platform compared to Character
return (platform_moving_x? or platform_moving_y?)
end
# Call Original or other Aliases
return platform_moving?
end
#--------------------------------------------------------------------------
# * Platform Clamp Real X - Game_Character
# - Returns values to use with movement in [@real_x + dist, clamp_x].min
#--------------------------------------------------------------------------
def platform_clamp_real_x(x)
return (@platform) ? 2 ** @move_speed : x * 128
end
#--------------------------------------------------------------------------
# * Platform Clamp Real Y - Game_Character
# - Returns values to use with movement in [@real_y + dist, clamp_y].min
#--------------------------------------------------------------------------
def platform_clamp_real_y(y)
return (@platform) ? 2 ** @move_speed : y * 128
end
#--------------------------------------------------------------------------
# * Platform Update Movement - Game_Character
# - Altered to allow indepenedent movement on X and Y for Platforms
#--------------------------------------------------------------------------
def platform_update_movement
# Split Distance into X and Y Distance
x_dist = y_dist = 2 ** @move_speed
# Set X and Y distance to 0 if direction is not relevant
case @dir_last_moved
when 4, 6 # Left and Right
y_dist = 0
when 2, 8 # Up and Down
x_dist = 0
end
# Platform shorthand
platform = $game_map.events[@on_platform]
# Determine Clamping Values for Real X and Real Y
clamp_x = platform.platform_clamp_real_x(@x)
clamp_y = platform.platform_clamp_real_y(@y)
# If command was to move character down, down left, or down right
if [2,1,3].include?(@dir_last_moved)
# Move down
@real_y = [@real_y + y_dist, @real_y - clamp_y].max
# If command was to move character up, up left, or up right
elsif [8,7,9].include?(@dir_last_moved)
# Move up
@real_y = [@real_y - y_dist, @real_y + clamp_y].min
end
# If command was to move character left, down left, or up left
if [4,1,7].include?(@dir_last_moved)
# Move left
@real_x = [@real_x - x_dist, @real_x + clamp_x].min
# If command was to move character right, down right, or up right
elsif [6,3,9].include?(@dir_last_moved)
# Move right
@real_x = [@real_x + x_dist, @real_x - clamp_x].max
end
# If move animation is ON
if @walk_anime
# Increase animation count by 1.5
@anime_count += 1.5
# If move animation is OFF, and stop animation is ON
elsif @step_anime
# Increase animation count by 1
@anime_count += 1
end
end
#--------------------------------------------------------------------------
# If Heretic's Loop Maps is installed
#--------------------------------------------------------------------------
if Game_Map.method_defined?(:map_loop_passable?)
#----------------------------------------------------------------------
# * Platform XY - Game_Character - Loop Map Redefinition
# - Returns X and Y values of Character allowing for alias adjustment
#----------------------------------------------------------------------
def platform_xy
# Get the Values of X and Y adjusted for Looping Maps
x = ($game_map.loop_horizontal?) ? @x % $game_map.width : @x
y = ($game_map.loop_vertical?) ? @y % $game_map.height : @y
# Return the X and Y values of this Character as an array
return [x, y]
end
#------------------------------------------------------------------------
# * Platform X No Match? - Game_Character - Loop Map Redefinition
# real_x : Real X coordinate of Character
# platform_real_x : Real X coordinate of Platform Event
#------------------------------------------------------------------------
def platform_x_no_match?(real_x, platform_real_x)
# If values in Argument need to be adjusted for Looping Maps
if $game_map.loop_horizontal?
real_x %= $game_map.width * 128
platform_real_x %= $game_map.width * 128
end
# Return whether or not the Real X and Platform Real X values match
return (real_x != platform_real_x)
end
#------------------------------------------------------------------------
# * Platform Y No Match? - Game_Character - Loop Map Redefinition
# - This fixes Loop Map Adjustments and returns true / false on match
# real_y : Real Y coordinate of Character
# platform_real_y : Real Y coordinate of Platform Event
#------------------------------------------------------------------------
def platform_y_no_match?(real_y, platform_real_y)
# If values in Argument need to be adjusted for Looping Maps
if $game_map.loop_vertical?
real_y %= $game_map.height * 128
platform_real_y %= $game_map.height * 128
end
# Return whether or not the Real Y and Platform Real Y values match
return (real_y != platform_real_y)
end
#----------------------------------------------------------------------
# * Platform Distance - Game_Character - Loop Map Redefinition
# - Distance in Logical Coordinates
#----------------------------------------------------------------------
def platform_distance(x, y)
# Shorthand for Width and Height
w = $game_map.width
h = $game_map.height
# Round Positions for Looping Maps
x = ($game_map.loop_horizontal?) ? x % w : x
y = ($game_map.loop_vertical?) ? y % h : y
# Round Self Positions for Looping Maps
sx = ($game_map.loop_horizontal?) ? @x % w : @x
sy = ($game_map.loop_vertical?) ? @y % h : @y
# Determine Initial Distance
x_dist = sx - x
y_dist = sy - y
# If Looping and Distance is more than half Width of Map
if $game_map.loop_horizontal? and x_dist.abs > w / 2
x_dist += (x_dist < 0) ? w : w * -1
end
# If Looping and Distance is more than half Height of Map
if $game_map.loop_vertical? and y_dist.abs > h / 2
y_dist += (y_dist < 0) ? h : h * -1
end
# Return Distance XY as an Array - x, y = method(x, y)
return [x_dist, y_dist]
end
#----------------------------------------------------------------------
# * Platform Real Distance - Game_Character - Loop Map Redefinition
# - Distance in Real Coordinates
#----------------------------------------------------------------------
def platform_real_distance(rx, ry)
# Shorthand for Width and Height in Real Values
w = $game_map.width * 128
h = $game_map.height * 128
# Round Positions for Looping Maps
rx = ($game_map.loop_horizontal?) ? rx % w : rx
ry = ($game_map.loop_vertical?) ? ry % h : ry
# Round Self Positions for Looping Maps
srx = ($game_map.loop_horizontal?) ? @real_x % w : @real_x
sry = ($game_map.loop_vertical?) ? @real_y % h : @real_y
# Determine Initial Distance
rx_dist = srx - rx
ry_dist = sry - ry
# If Looping and Distance is more than half Width of Map
if $game_map.loop_horizontal? and rx_dist.abs > w / 2
rx_dist += (rx_dist < 0) ? w : w * -1
end
# If Looping and Distance is more than half Height of Map / 2
if $game_map.loop_vertical? and ry_dist.abs > h / 2
ry_dist += (ry_dist < 0) ? h : h * -1
end
# Return Distance XY as an Array - x, y = method(x, y)
return [rx_dist, ry_dist]
end
#----------------------------------------------------------------------
# * Platform Align Character - Game_Character - Loop Map Alias
# - Alias corrects Player Position on Looping Maps
#----------------------------------------------------------------------
alias loop_platform_align_character platform_align_character unless $@
def platform_align_character(dist_x, dist_y, dist_rx, dist_ry)
# Call Original or other Aliases
loop_platform_align_character(dist_x, dist_y, dist_rx, dist_ry)
# If Not the Player
if @id != 0
# If Map Loops Horizontally
if $game_map.loop_horizontal? and (@x < 0 or @x > $game_map.width)
# Round for Horizontal Loop
@x %= $game_map.width
@real_x %= $game_map.width * 128
end
# If Map Loops Vertically
if $game_map.loop_vertical? and (@y < 0 or @y > $game_map.height)
# Round for Vertical Loop
@y %= $game_map.height
@real_y %= $game_map.height * 128
end
end
end
end # End Loop Map Redefinitions
#--------------------------------------------------------------------------
# * Update Move - Game_Character
# - Allows movement to be handled differently while on a Platform
#--------------------------------------------------------------------------
alias platform_update_move update_move unless $@
def update_move
# If on a Platform and not Unboarding
if @on_platform and not @unboard_platform and @dir_last_moved
# Movement Update for Characters on Platforms
platform_update_movement
else
# Call Original or other Aliases
platform_update_move
end
end
#--------------------------------------------------------------------------
# * Event Not Passable? - Game_Character
# - Allows Platforms to pass thru all Characters if the other
# character is not a Platform of a different Platform Group
#--------------------------------------------------------------------------
alias platform_event_not_passable? event_not_passable? unless $@
def event_not_passable?(x, y, d, new_x, new_y, event, result = nil)
# Check for two Platforms of the same Group
if @platform and @tile_id > 0 and $game_system.platform_enabled and
not (event.platform and @platform != event.platform)
# Passable to Platforms of the same Platform Group
return false
end
# Call Original or other Aliases
platform_event_not_passable?(x, y, d, new_x, new_y, event, result)
end
#--------------------------------------------------------------------------
# * Event Character Not Passable? - Game_Character
# - Allows Platforms to pass thru all other Characters
# - Comparison to other Platform groups is done in other Passable methods
#--------------------------------------------------------------------------
alias p_event_character_not_passable? event_character_not_passable? unless $@
def event_character_not_passable?(x, y, d, new_x, new_y, event, result = nil)
# Platforms are allowed to pass through ALL other Events and Characters
return false if @platform and $game_system.platform_enabled
# Call Original or other Aliases
p_event_character_not_passable?(x, y, d, new_x, new_y, event, result)
end
#--------------------------------------------------------------------------
# * Jump - Game_Character
# x_plus : x-coordinate plus value
# y_plus : y-coordinate plus value
#--------------------------------------------------------------------------
alias platform_jump jump unless $@
def jump(x_plus, y_plus)
# Store Old Coordinates
last_x, last_y = @x, @y
# Call Original or other Aliases
platform_jump(x_plus, y_plus)
# If New Coordinates are different
if last_x != @x or last_y != @y
# If plus value is not (0,0)
if x_plus != 0 or y_plus != 0
# If horizontal distnace is longer
if x_plus.abs > y_plus.abs
# Use the Direction that Passable was used to check
@dir_last_moved = (x_plus < 0) ? 4 : 6
# If vertical distance is longer, or equal
else
# Use the Direction that Passable was used to check
@dir_last_moved = (y_plus < 0) ? 8 : 2
end
end
# Check if Jumping to a Platform
board_platforms
end
end
end
#==============================================================================
# ** Game_Event
#==============================================================================
class Game_Event < Game_Character
#--------------------------------------------------------------------------
# * Public Instance Variables - Game_Event
#--------------------------------------------------------------------------
attr_accessor :platform_boarding # If Platform is being Boarded
attr_reader :platform_sync # Sync other Platform Groups (Array)
#--------------------------------------------------------------------------
# * Check Comment Page Config - Game_Event
#--------------------------------------------------------------------------
alias platform_check_page_comment_config check_page_comment_config unless $@
def check_page_comment_config(comment, count)
# Looks for "\platform[N]" Comments to create Platform Groups
comment.gsub(/^\\platform\[([-0-9]+)\]\z/i) {
# Only Tiles can be Platforms at this time
if @tile_id > 0
# Assign Platform Group ID to Event as a Property
@platform = $1.to_i
platform_riders = []
# Add this Event to the Game Map Platform Groups
$game_map.add_platform_to_group(self)
else
if $DEBUG
print "Error for Event ",@id,", Platforms MUST have a Tile ID\n",
"(You can set the Opacity to 0 to make it Invisible\n",
"or use Event Pages)"
@platform = nil
end
end
# Allow other Alises that use Page Comments to be parsed
return count;
}
# Looks for "\platform[N]" Comments to create Platform Groups
comment.gsub(/^\\no_platforms\z/i) {
# Set Flag to prohibit this Event riding on Platforms
@no_platforms = true
# Allow other Alises that use Page Comments to be parsed
return count;
}
# Looks for "\platform_sync[2, 3]" in the Comment on List of Event Commands
comment.gsub(/^\\platform_sync\[([0-9, ]+)\]\z/i){ @platform_sync = $1;
@platform_sync = @platform_sync.split(",").map { |s| s.to_i };
return count;
}
# Call Original or other Aliases since Comment contained no Platform Data
return platform_check_page_comment_config(comment, count)
end
#--------------------------------------------------------------------------
# * Reset Page Comment Config - Game_Event
# - Resets Platforms on Refresh or Page Change
#--------------------------------------------------------------------------
alias platform_reset_page_comment_config reset_page_comment_config unless $@
def reset_page_comment_config
# Reset Platform Properties
@platform = nil
@platform_riders = []
@no_platforms = nil
@platform_sync = nil
@platform_starting = nil
# Call Original or other Aliases
platform_reset_page_comment_config
end
#--------------------------------------------------------------------------
# * Platform Riders - Game_Event
# - Contains Characters (Player and Events) currently Riding Platform
#--------------------------------------------------------------------------
def platform_riders
return @platform_riders ||= []
end
#--------------------------------------------------------------------------
# * Update - Game_Event
# - Main Update Method for Game_Event
# - Allows Updates for Platforms to occur out of order
#--------------------------------------------------------------------------
alias platform_event_main_update update unless $@
def update
# If Platform and System Option is Enabled
if @platform and $game_system.platform_enabled
# Updates for Platforms performed out of order so must be Enabled
return unless $game_map.platform_allow_update
end
# Call Original or other Aliases
platform_event_main_update
end
#--------------------------------------------------------------------------
# * Start Event - Game_Event
# - Pressing the Enter Key while on a Platform causes all Platforms to
# have the Starting flag set because they require Comments to be able
# to function as expected. When Enter is pressed, Comments count in
# the List of Event Commands, thus, pressing Enter causes the Event
# to become desyncrhonized. if @list.size > 1 registers Comments
#--------------------------------------------------------------------------
alias platform_event_start start unless $@
def start
# If trying to Start a Platform
if @platform
# Use a different flag to check @starting
@platform_starting = true
# Cant use the @starting flag if a Platform due to Animation
return
end
# Call Original or other Aliases
platform_event_start
end
#--------------------------------------------------------------------------
# * Start Event - Game_Event
# - Typically just sets @starting to false by Interpreter
# - This definition clears an additional property by Alias
#--------------------------------------------------------------------------
alias platform_event_clear_starting clear_starting unless $@
def clear_starting
# Clear Platform Starting
@platform_starting = false
# Call Original or other Aliases
platform_event_clear_starting
end
#--------------------------------------------------------------------------
# * Starting - Game_Event
# - This replaces an attr_reader :starting to check for two values
# for Platforms due to Animation being halted while the Starting
# flag is set on Events
#--------------------------------------------------------------------------
def starting
return (@starting or (@platform and @platform_starting) )
end
#--------------------------------------------------------------------------
# * Move Type : Custom - Game_Event
# - Prevents Custom Movement for Platform Groups if being Boarded
#--------------------------------------------------------------------------
alias platform_move_type_custom move_type_custom unless $@
def move_type_custom
# If Player or Event is not completely on the Platform
if @platform and platform_boarding?
# Prevent Custom Movement Until until Platform has been fully Boarded
return
end
# Call Original or other Aliases
platform_move_type_custom
end
#--------------------------------------------------------------------------
# * Platform Boardable? - Game_Event
# - Checks if this Event can be Boarded
# - This does not place restrictions on moving between Platforms of
# the same Platform Group
# - Checking @wait_count > 1 instead of 0 prevents intermittent behavior
# because Platfomrs are updated out of order
#--------------------------------------------------------------------------
def platform_boardable?(character)
# False if Self is not a Platform
return false unless @platform
# Cannot Board unless System Enabled
return false unless $game_system.platform_enabled
# Cannot Board if Character has a No Platform Flag
return false if character.no_platforms
# Platforms can not board other Platforms
return false if character.platform
# Platforms can not be Through
return false if @through
# Get the Platform Event
platform = $game_map.events[character.on_platform]
# Look for a Group Match (@platform holds the Platform Group ID)
if (platform and @platform == platform.platform) or @wait_count > 1
# Boardable
return true
end
# Not Boardable if not Waiting
return false
end
#--------------------------------------------------------------------------
# * Platform Boarding? - Game_Event
# - Checks if Player or other Events are boarding this Platform
#--------------------------------------------------------------------------
def platform_boarding?
# Array of Groups to Check
sync_groups = [@platform]
# Check other Platform Events in same Group
platforms = $game_map.platform_groups[@platform]
# Iterate each Platform
for platform in platforms
# See if there are any other Groups to Sync with
if platform.platform_sync.is_a?(Array)
# Merge the Temporary Array with the one from the Platform Comment
sync_groups = sync_groups + platform.platform_sync
end
end
# Remove Duplicates for Performance
sync_groups = sync_groups.uniq
# Iterate the Groups
for group_id in sync_groups
# Get the Group from Game Map as Platforms
platforms = $game_map.platform_groups[group_id]
# If a Group is found
if platforms
# Iterate each Platform
for platform in platforms
# Group is being Boarded if ANY Platforms checked have Boarding Flags
return true if platform.platform_boarding
end
end
end
# Default State - Not Being Boarded
return false
end
#--------------------------------------------------------------------------
# * Board Platform - Game_Event
# - Checks conditions and adds Character as a Platform Rider
#--------------------------------------------------------------------------
def platform_board_character(character)
# Check for Properties
if character.no_platforms or character.platform or character.through or
not $game_system.platform_enabled
# Unable to Board
return false
end
# Check if Character is already in the Array
if not platform_riders.include?(character)
# Add this Character to the list of Riders
platform_riders.push(character)
# Boarding was successful
return true
end
end
#--------------------------------------------------------------------------
# * Platform Alternate Update - Game_Event
# - Allows Out of Order Updating by Game_Map calls
# - This is NOT an Alias of the Main Update Method
#--------------------------------------------------------------------------
def platform_alternate_update
# Save Coordinates in Temporary Variables (Last X lx, Last Y ly)
lx, ly = @x, @y
# Save Real Coordinates
last_real_x, last_real_y = @real_x, @real_y
# Update the Event using the Main Update Method Call
update
# Use Saved Positions to Update Platform Riders Positions
platform_update_rider_positions(lx, ly, last_real_x, last_real_y)
end
#--------------------------------------------------------------------------
# * Platform Update Rider Positions - Game_Event
# - Updates the Positions of all of the Platform Riders
#--------------------------------------------------------------------------
def platform_update_rider_positions(x, y, last_real_x, last_real_y)
# Determine Distance of Movement on X and Y
x_dist, y_dist = platform_distance(x, y)
# Change Distance into -1, 0, or 1
x_adj = (x_dist < 0) ? -1 : (x_dist > 0) ? 1 : 0
y_adj = (y_dist < 0) ? -1 : (y_dist > 0) ? 1 : 0
# Determine Real Distance of Movement with Last Real X and Last Real Y
rx_dist, ry_dist = platform_real_distance(last_real_x, last_real_y)
# Iterate through each Rider
for rider in platform_riders
# Align the Characters Position with the Platforms Movements
rider.platform_align_character(x_adj, y_adj, rx_dist, ry_dist)
# If X or Y values for this Character have been changed and not Player
if (x_adj != 0 or y_adj != 0) and not rider.id == 0
# Correct the Map Hash Keys for Events for Proper Collisions
rider.store_map_hash_keys
end
end
end
end
#==============================================================================
# ** Game_Player
#==============================================================================
class Game_Player
#--------------------------------------------------------------------------
# * Platform Scroll Map Update - Game_Player
# - Scroll is usually called when movement is updated, but movement is
# considered as not moving while on a platform. This is called in
# a special case while riding a platform
# last_real_x : Player Real X value prior to platform movement
# last_real_y : Player Real Y value prior to platform movement
#--------------------------------------------------------------------------
def platform_scroll_map_update(last_real_x, last_real_y)
# If character moves down and is positioned lower than the center
# of the screen
if @real_y > last_real_y and @real_y - $game_map.display_y > CENTER_Y
# Scroll map down
$game_map.scroll_down(@real_y - last_real_y)
end
# If character moves left and is positioned more let on-screen than
# center
if @real_x < last_real_x and @real_x - $game_map.display_x < CENTER_X
# Scroll map left
$game_map.scroll_left(last_real_x - @real_x)
end
# If character moves right and is positioned more right on-screen than
# center
if @real_x > last_real_x and @real_x - $game_map.display_x > CENTER_X
# Scroll map right
$game_map.scroll_right(@real_x - last_real_x)
end
# If character moves up and is positioned higher than the center
# of the screen
if @real_y < last_real_y and @real_y - $game_map.display_y < CENTER_Y
# Scroll map up
$game_map.scroll_up(last_real_y - @real_y)
end
end
#--------------------------------------------------------------------------
# * Platform Debug Update - Game_Player
# - When CTRL Key is Pressed, Player is Removed from Platforms
# - When CTRL Key is Released and Player is over a Platform, the Player
# is forced onto the Platform whether it is Boardable or not
#--------------------------------------------------------------------------
def platform_player_debug_update
# If Player was just Debugging
if @platform_last_debug and not Input.press?(Input::CTRL)
# Get Events at Location that the Player was "Dropped"
events = $game_map.get_events_at_xy(@x, @y)
# Iterate thru the Events
for event in events
# If Event is a Platform
if event.platform and not event.through
# Bypass Boarding Checks and put the Player on this Platform
event.platform_board_character(self)
# Align Self with the Platform on Real X and Y
@real_x, @real_y = event.real_x, event.real_y
# Store the Event ID of the Platform just Boarded
@on_platform = event.id
# Exit the For Loop
break
end
end
# Clear the Debug Property
@platform_last_debug = nil
end
# If holding down the CTRL Key and run from the Editor
if player_platform_debug?
# Check for Platforms
if @on_platform
# Get the Event
platform = $game_map.events[@on_platform]
# Remove Self from list of Riders
platform.platform_riders.delete(self)
# If Platform has no other Riders and is Boarding
if platform.platform_boarding and platform.platform_riders.size == 0
# Clear the Boarding Flag
platform.platform_boarding = nil
end
# Clear the Property
@on_platform = nil
end
# Check for Old Platforms
if @old_platform_id
# Get the Event
platform = $game_map.events[@old_platform_id]
# Remove Self from list of Riders
platform.platform_riders.delete(self)
# If Platform has no other Riders and is Boarding
if platform.platform_boarding and platform.platform_riders.size == 0
# Clear the Boarding Flag
platform.platform_boarding = nil
end
# Clear the Property
@old_platform_id = nil
end
# Set Flag that Platform Debug is occuring
@platform_last_debug = true
end
end
#--------------------------------------------------------------------------
# If Heretic's Loop Maps is installed
#--------------------------------------------------------------------------
if Game_Map.method_defined?(:map_loop_passable?)
#------------------------------------------------------------------------
# * Map Loop Position - Game_Player
# - Calls for Corrections when Player triggers a Map Loop
#------------------------------------------------------------------------
alias platform_map_loop_position map_loop_position unless $@
def map_loop_position
# If on a Platform
if @on_platform
# Get the Platform Event
p = $game_map.events[@on_platform]
# Determine Distance between Logical and Real (if Rounding is needed)
x_dist = (@x * 128) - @real_x
y_dist = (@y * 128) - @real_y
# We have a Deviation if Distance is greater than 1 / 2 Map
x_dev = (x_dist.abs > $game_map.width * 64) ? true : false
y_dev = (y_dist.abs > $game_map.height * 64) ? true : false
# If Platform is moving, Player is moving, or Jumping
if @real_x != @x * 128 or @real_y != @y * 128 or
p.real_x != p.x * 128 or p.real_y != p.y * 128 or
jumping? or x_dev or y_dev
# Set Looped Property for Scripts to check Value for ONE FRAME
$game_map.looped = nil
# If Horizontal Map Loop
if $game_map.loop_horizontal?
# If a Horizontal Loop is Occuring
if @real_x < 0 or @real_x > $game_map.width * 128
# Correct Positions if outside Map Boundaries
correct_loop_left if @real_x < 0
correct_loop_right if @real_x > $game_map.width * 128
# Else if we have a Deviation in Logical and Real Coordinates
elsif x_dev
# Round the New Coordinates to correct Deviation
@x %= $game_map.width
@real_x %= $game_map.width * 128
# Recenter Display Horizontally
$game_map.display_x = @real_x - CENTER_X
end
end
# If Horizontal Map Loop
if $game_map.loop_vertical?
# If a Vertical Loop is Occuring
if @real_y < 0 or @real_y > $game_map.height * 128
# Correct Positions if outside Map Boundaries
correct_loop_up if @real_y < 0
correct_loop_down if @real_y > $game_map.height * 128
# Else if we have a Deviation in Logical and Real Coordinates
elsif y_dev
# Round the New Coordinates to correct Deviation
@y %= $game_map.height
@real_y %= $game_map.height * 128
# Recenter Display Vertically
$game_map.display_y = @real_y - CENTER_Y
end
end
# Prevent Original from running
return
end
end
# Call Original or other Aliases
platform_map_loop_position
end
end # End Loop Map Redefinitions
end
Later versions of this code that I post will NOT be subject to the same legal restrictions.
In its current state, it will break your game, but can be used during development for your game.