#===============================================================================
#
# HERETIC'S DIAGONAL STAIRS DELUXE [XP]
# Version 1.0
# Tuesday, October 21st, 2014
#
#===============================================================================
#
# --- Requirements and Installation ---
#
# *** REQUIRES HERETICS MODULAR PASSABLE SCRIPT ***
#
# This script should be placed below Heretics Modular Passable.
# Heretics Modular Passable should be placed just below the real SDK
# It should work fine as long as it is between Modular Passable and Main.
#
# Note: There are two versions of this script. DELUXE and LITE. Deluxe
# is dependant on Modular Passable, may be slightly less compatible
# but has more features. The Lite version is NOT Dependant on the
# Modular Passable script and has no interactive options, but is
# probably more compatible.
#
# --- Version History ---
#
# Version 1.0 - Tuesday, October 21st, 2014 - Initial Release
#
#
# --- Summary ---
#
# Definition: NPC - Non Player Character, an Event with a Character Graphic.
#
# This script allows you to use Terrain Tags to easily make Characters move
# diagonally on Stairs. It is useful with some styles of Tilesets where
# the stairs require Diagonal movement. It also allows NPC Events to
# interact with any and all Stairs as well, which is why this is
# far superior to any other solutions.
#
# Oh yeah, and I wrote it, thats why!
#
#
# ----- Features -----
#
# - Diagonal Movement based on Terrain Tags
# - NPCs can interact as expected on Stairs
# - Event Collisions and Triggers work as expected (Customizable)
# - Narrow Stairs work properly
# - NPCs can also interact with Stairs made from Events!(Customizable)
#
#
# --- Instructions ---
#
# Just edit your Tileset and flag any Diagonal Stairs with a Terrain Tag.
#
# There are two directions you can go on stairs, up and down. So there
# are two Terrain Tags for you to use.
#
# Use Terrain Tag 5 (default) for Stairs that go from Lower Right to Upper Left
# Use Terrain Tag 6 (default) for Stairs that go from Lower Left to Upper Right
#
# Note: You MUST use TWO or more Tiles with the same Terrain Tag for the
# effect to work!
#
# Note: ONLY Left and Right Movement Commands are affected by Stairs!
#
#
# --- Configurations ---
#
# You can FORCE any Character to have a specified behavior by using Comments!
#
# The Comment needs to be in the first 10 Lines on EACH PAGE you want to
# force a behavior on. The 10 Line Limit is controlled in the required
# Modular Passable Script under COMMENT_LIMIT, not in this script.
#
# @>Comment: \some_option
#
# Comment Configurations must use the FIRST LINE of a Comment. Additional
# lines are not checked. Each Comment Line and Script Line will count against
# the COMMENT_LIMIT of 10 (by Default).
#
# The PER PAGE feature allows you to specify different behaviors on each
# page of an Event. It is the same as Page 1 having X graphic and Through, but
# Page 2 has a different graphic and different Through settings. Trust me, it
# saves you a LOT of work by not requiring everything to be made with scripts.
#
# By default, Events with "Always On Top" or "Through" will not be affected by
# movement on Stair Tiles. These NPCs can still be "Forced".
#
# \use_stairs - This NPC will ALWAYS use Stairs, regardless of other settings.
# \no_stairs - This NPC will NEVER use Stairs, regardless of other settings.
# \no_event_tiles - This NPC will NEVER try to move on Events with Tiles.
# \no_event_stairs - This NPC will NEVER try to move on Event Stairs
#
# NOTE: You'll see me use \no_event_tiles in several other scripts.
#
#
# --- Script Calls ---
#
# You can FORCE any NPC to have the Behavior you want by using Script Calls
#
# @>Script: $game_map.events[51].use_stairs
# @>Script: $game_player.no_stairs
#
# These can also be called in a Script from Set Move Route
#
# no_event_tiles needs a value to be set: true/false (Events ONLY, no PLAYER)
#
# $game_map.events[5].no_event_tiles = true/false
#
#
# ----- Database Tile Passages -----
#
# In the Database (F9) under Tilesets, you have a Passage (4 Dir) to allow
# specific movement on a Tile. In order to allow the Diagonal Movement that
# occurs on Stairs, I check TWO directions, not just one. For a Stair to
# be considered as Passable for Up Left movement, either Left or Up needs
# to be allowed on your current tile, and either Down or Right needs to
# be allowed on the tile you are trying to move to. I do not check
# the adjacent tiles because that prohibited any form of Narrow Stairs.
# Adjacent Tile checking means that for normal unmodified Diagonal Movement
# to Up Left, either the whole tile directly to the left or directly up
# from the characters position would have to be passable. I only check
# for your current and target tiles and ignore adjacents. Keep this in
# mind when setting up your Passage Settings for your tilesets.
#
#
# ----- Compatability -----
#
# This script will not be compatible with other scripts that overwrite
# either Game_Map Passable? or Game_Character Passable? You can try
# to place this script below any that rewrite those methods but compatability
# is not guaranteed for more exotic scripts like Pixel Movement.
#
# Heretic's Caterpillar has been updated to Version 1.99.6 for compatability.
# Heretic's Caterpillar Versions 1.99.5 and below wont be compatible due
# to conflicting definitions. This is also why the Modular Passable script
# is required.
#
# This script probably wont be compatible with any Pixel Movement Scripts.
#
# Pathfinding over Stair Tiles will most likely be problematic at best.
#
# This script probably wont be needed by any 8 directional movement scripts.
# I have tested 8 dir movement and it does work fine by the way, it is
# just completely superfluous however.
#
#
# ----- Legal -----
#
# You are hereby granted permission to use and redistribute this script with
# two restrictions:
#
# 1) - You give me credit
# 2) - If distributed in a Demo specific to a Tileset, the Tileset MUST be
# configured in the Databse.
#
# I feel very strongly about Tilesets that do not have Database Configurations.
#
# You may post this script on any website.
# You may use this script in commercial projects without my explicit permission
# as long as I am credited somewhere in the project.
# You may package this script.
#
# You may NOT sell this script.
# You may NOT claim this script to be your own property.
#
#
# ----- Configuration Options -----
#
# Terrain Tags - You'll need TWO different Terrain Tags for your Stairs
# Adjust as needed for compatability
#
# Stair Trigger - This Option allows you to define what happens when the
# Player presses Enter. A setting of 0 will only check
# for Trigger Events in front of them. A setting of 1
# will only check Diagonals, dependant on which Stair
# Tile the Player is standing on. And lastly, a setting
# of 2 will check for both directly in front and diagonally
# from the Players position while they stand on Stairs.
# If the player is not standing on a Stair Tile, then
# only Front Triggering occurs, which is default.
#
#
#===============================================================================
# --- TERRAIN TAGS OPTIONS ---
STAIRS_UPLEFT_TAG = 5 # Use for Down Right to Upper Left Stairs
STAIRS_UPRIGHT_TAG = 6 # Use for Down Left to Upper Right Stairs
# --- TRIGGER BEHAVIOR OPTIONS ---
STAIR_TRIGGER = 2 # 0 = Normal, 1 = Diagonal Only, 2 = Diag + Normal
# Check for Modular Passable Script
unless $Modular_Passable
print "Fatal Error: Heretics Diagonal Stairs script\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 will now Exit"
exit
end
#==============================================================================
# ** Game_System
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
# * Public Instance Variables - Game_System
#--------------------------------------------------------------------------
attr_accessor :event_stairs # NPCs on Stairs and Events with Stair Tiles
#--------------------------------------------------------------------------
# * Object Initialization
# - Adds a System Option for using Events with Stair Tiles as Stairs for
# both Player and NPC Characters
# - With this Option set to TRUE, NPCs can move around on Events with
# Terrain Tiles that have Stair Terrain Tags.
#--------------------------------------------------------------------------
alias stair_events_initialize initialize unless $@
def initialize
# Call Original or other Aliases
stair_events_initialize
# New Option for checking Events for Stair Tiles
@event_stairs = true
end
end
#==============================================================================
# ** Game_Character
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Object Initialization - Game_Character
#--------------------------------------------------------------------------
alias stairs_char_initialize initialize unless $@
def initialize
# Call Original or other Aliases
stairs_char_initialize
# Add New Properties
@stairs = nil
@no_stairs = nil
end
#--------------------------------------------------------------------------
# * Change Stairs Property - Game_Character
#--------------------------------------------------------------------------
def use_stairs
# Just changes to True and False for both properties
@stairs = true
@no_stairs = nil
end
#--------------------------------------------------------------------------
# * Change No Stairs Property - Game_Character
# NOTE: You may need to call self.no_stairs as running a Script no_stairs=
# will create a local variable instance of a method call
# if run from Set Move Route -> Script
#--------------------------------------------------------------------------
def no_stairs
# Just changes to True and False for both properties
@stairs = nil
@no_stairs = true
end
#--------------------------------------------------------------------------
# * Clear Stairs - Game_Character
# - Clears both properties due to setter methods
#--------------------------------------------------------------------------
def clear_stairs
# Clears both properties to nil
@stairs = nil
@no_stairs = nil
end
#--------------------------------------------------------------------------
# * Stairs? - Game_Character
# - Returns Value of Stairs Property
# - Useful for scripters to tell if an event is being forced to use stairs
#--------------------------------------------------------------------------
def use_stairs?
return @stairs
end
#--------------------------------------------------------------------------
# * No Stairs? - Game_Character
# - Returns Value of No Stairs
# - Useful for scripters to tell if an event is prohibited from using stairs
#--------------------------------------------------------------------------
def no_stairs?
return @no_stairs
end
#--------------------------------------------------------------------------
# * Stair Tag Valid? - Game_Character
# - Returns true or nil if Terrain Tag matches Config Stair Tags
# tag : Terrain Tag
#--------------------------------------------------------------------------
def stair_tag_valid?(tag)
# Valid if one of the two Constants defined in Config
return true if tag == STAIRS_UPRIGHT_TAG or tag == STAIRS_UPLEFT_TAG
end
#--------------------------------------------------------------------------
# * Stairs Debug - Game_Character
# - Returns true if Player in Debug Mode for Passing through everything
# - If Player Stairs is Forced, Stair Movement will still occur
#--------------------------------------------------------------------------
def stairs_debug?
# If Player and Debug and CTRL Key and not Stairs Forced
if self == $game_player and not @stairs and $DEBUG and
Input.press?(Input::CTRL)
# Debug Movement for Player is Active
return true
end
end
#--------------------------------------------------------------------------
# * Make New XY for Stairs - Game_Character
# - Determines new Y Position while on Stairs
# d : direction
# tag : current Stair Tag
#--------------------------------------------------------------------------
def make_new_xy_for_stairs(d, tag)
# Abbreviate Constants
l = STAIRS_UPLEFT_TAG
r = STAIRS_UPRIGHT_TAG
# Determine New Location based on Current Tags
new_x = @x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = @y + (((d == 6 and tag == l) or (d == 4 and tag == r)) ? 1 :
((d == 4 and tag == l) or (d == 6 and tag == r)) ? -1 : 0)
# Return New Coordinates as Array
return [new_x, new_y]
end
#--------------------------------------------------------------------------
# * Stair Tags Here - Game_Character
# skip_events : true to prevent iterating through events for performance
# - Returns any Terrain Tags from current location
# - The skip_events argument is used when Events have been checked before
# calling this command which would cause reduncancy in interation
# Note: All Event Tiles are checked. Be sure to use Through on Events
# with Tile Graphics if you have any need to Stack Events
#--------------------------------------------------------------------------
def stair_tags_here(skip_events = false)
# If current coordinates given are outside of the map
unless $game_map.valid?(@x, @y)
# No Stair Tags on the Outside of a Map
return 0
end
# Get the Terrain Tag from the Map Tiles
tag = $game_map.terrain_tag(@x, @y)
# If System Option is Enabled for checking Events with Tile Graphics
if $game_system.event_stairs and not skip_events and
not @no_event_tiles and not @no_event_stairs
# Get List of Events at Map XY
event_list = make_events_list(@x, @y)
# Check Events with Tile Graphics to get Terrain Tags
for event in event_list
# If event coordinates are consistent with move destination
if mp_match_coordinates?(@x, @y, event.x, event.y)
# Events with Stair Tiles and Through are ignored
unless event.tile_id == 0 or event.through
# Get Terrain Tag from Event Tile
tag = $game_map.terrain_tags[event.tile_id]
end
end
end
end
# Return any Stair Terrain Tags
return tag
end
#--------------------------------------------------------------------------
# * Stair Tags There - Game_Character
# d : 4 for left and 6 for right ONLY
# tag : when Stair Tag Here has already been calculated
# - Returns Terrain Tag at New Location if Two Stair Tiles are found
# - Returns numeric 0 as a Terrain Tag if not a Stair
#--------------------------------------------------------------------------
def stair_tags_there(d, tag = nil)
# If Direction is not Left or Right
return 0 unless (d == 4 or d == 6)
# If current coordinates given are outside of the map
unless $game_map.valid?(@x, @y)
# No Stair Tags on the Outside of a Map
return 0
end
# Get any Terrain Tags from current location, including Events with Option
tag = (tag != nil) ? tag : stair_tags_here
# Return if no Terrain Tags in either Map or Events
return 0 unless tag > 0
# Determine New Location based on Current Tags
new_x, new_y = make_new_xy_for_stairs(d, tag)
# If new coordinates given are outside of the map
unless $game_map.valid?(new_x, new_y)
# Not a Valid Stair Tag
return 0
end
# Get the Terrain Tag from the Map Tiles
new_tag = $game_map.terrain_tag(new_x, new_y)
# If System Option is Enabled for checking Events with Tile Graphics
# and Character is allowed to move on Events with Tiles / Stairs
if $game_system.event_stairs and
not @no_event_tiles and not @no_event_stairs
# Check Events with Tile Graphics to get Terrain Tags
for event in make_events_list(new_x, new_y)
# If event coordinates are consistent with move destination
if mp_match_coordinates?(new_x, new_y, event.x, event.y)
# Events with Stair Tiles and Through are ignored
unless event.tile_id == 0 or event.through
# Get Terrain Tag from Event Tile
new_tag = $game_map.terrain_tags[event.tile_id]
end
end
end
end
# If Matching Stair Terrain Tags
if tag == new_tag and stair_tag_valid?(tag) and stair_tag_valid?(new_tag)
# Return the Terrain Tag found for the New Tag at Next Location
return new_tag
# When two Matching Terrain Tags not found
else
# Return the Default Terrain Tag
return 0
end
end
#--------------------------------------------------------------------------
# * Move Left on Stairs - Game_Character
# turn_enabled : a flag permits direction change on that spot
# - Modifies normal Move Left behavior so that if a character is on
# a Stair, it will move up or down those stairs according to the
# Terrain Tag of that stair where Default 5 is Up Left, 6 is Down Left
#--------------------------------------------------------------------------
alias stairs_move_left move_left unless $@
def move_left(turn_enabled = true)
# If Player is pressing CTRL from Editor Game and not Forced Stairs
debug = stairs_debug?
# If Stair Movement expected for Character
if !debug and !@no_stairs and (@stairs or (!@through and !@always_on_top))
# Get Stair Tag Value
stair_tag = stair_tags_here()
# If Stair Tag Valid
if stair_tag_valid?(stair_tag)
# Get next Stair Tag Value (4 is Left)
next_stair_tag = stair_tags_there(4, stair_tag)
# If Next Stair Tag Valid
if stair_tag_valid?(next_stair_tag)
# If Stairs go Up and to the Left
if stair_tag == STAIRS_UPLEFT_TAG
# If no direction fix - turn_enabled is ignored
unless @direction_fix
# Turn Left
@direction = 4
end
# Check for passability for Up Left (Event Tiles, not All Events)
return unless ($game_map.passable?(@x, @y, 4) or
$game_map.passable?(@x, @y, 8) ) and
($game_map.passable?(@x - 1, @y - 1, 6) or
$game_map.passable?(@x - 1, @y - 1, 2) )
# When stairs tiles are passable up left
if stair_events_passable?(@x, @y, 6, @x - 1, @y - 1)
# Update coordinates
@x -= 1
@y -= 1
# Increase steps
increase_steps
else
# Determine if touch event is triggered diagonally
check_event_trigger_touch(@x - 1, @y - 1)
end
# Prevent Moving Twice
return
# If Stairs go Down and to the Left
elsif stair_tag == STAIRS_UPRIGHT_TAG
# If no direction fix - turn_enabled is ignored
unless @direction_fix
# Turn Left
@direction = 4
end
# Check for passability for Down Left (Event Tiles, not All Events)
return unless ($game_map.passable?(@x, @y, 4) or
$game_map.passable?(@x, @y, 2) )and
($game_map.passable?(@x - 1, @y + 1, 6) or
$game_map.passable?(@x - 1, @y + 1, 8) )
# When stairs tiles are passable down left
if stair_events_passable?(@x, @y, 6, @x - 1, @y + 1)
# Update coordinates
@x -= 1
@y += 1
# Increase steps
increase_steps
else
# Determine if touch event is triggered diagonally
check_event_trigger_touch(@x - 1, @y + 1)
end
# Prevent Moving Twice
return
end
end
end
end
# Call Original or other Aliases
stairs_move_left(turn_enabled)
end
#--------------------------------------------------------------------------
# * Move Right on Stairs - Game_Character
# turn_enabled : a flag permits direction change on that spot
# - Modifies normal Move Right behavior so that if a character is on
# a Stair, it will move up or down those stairs according to the
# Terrain Tag of that stair where Default 5 is Down Right, 6 is Up Right
#--------------------------------------------------------------------------
alias stairs_move_right move_right unless $@
def move_right(turn_enabled = true)
# If Player is pressing CTRL from Editor Game and not Forced Stairs
debug = stairs_debug?
# If Stair Movement expected for Character
if !debug and !@no_stairs and (@stairs or (!@through and !@always_on_top))
# Get Stair Tag Value
stair_tag = stair_tags_here()
# If Stair Tag Valid
if stair_tag_valid?(stair_tag)
# Get next Stair Tag Value (6 is Right)
next_stair_tag = stair_tags_there(6, stair_tag)
# If Next Stair Tag Valid
if stair_tag_valid?(next_stair_tag)
# If Stairs go Up and to the Right
if stair_tag == STAIRS_UPRIGHT_TAG
# If no direction fix - turn_enabled is ignored
unless @direction_fix
# Turn Right
@direction = 6
end
# Check for passability for Up Right (Event Tiles, not All Events)
return unless ($game_map.passable?(@x, @y, 6) or
$game_map.passable?(@x, @y, 8) ) and
($game_map.passable?(@x + 1, @y - 1, 4) or
$game_map.passable?(@x + 1, @y - 1, 2) )
# When stairs tiles are passable up right (right used for passage)
if stair_events_passable?(@x, @y, 4, @x + 1, @y - 1)
# Update coordinates
@x += 1
@y -= 1
# Increase steps
increase_steps
else
# Determine if touch event is triggered diagonally
check_event_trigger_touch(@x + 1, @y - 1)
end
# Prevent Moving Twice
return
# If Stairs go Down and to the Right
elsif stair_tag == STAIRS_UPLEFT_TAG
# If no direction fix - turn_enabled is ignored
unless @direction_fix
# Turn Right
@direction = 6
end
# Check for passability if Down Right (Event Tiles, not All Events)
return unless ($game_map.passable?(@x, @y, 6) or
$game_map.passable?(@x, @y, 2) ) and
($game_map.passable?(@x + 1, @y + 1, 4) or
$game_map.passable?(@x + 1, @y + 1, 8) )
# When stairs tiles are passable down right
if stair_events_passable?(@x, @y, 4, @x + 1, @y + 1)
# Update coordinates
@x += 1
@y += 1
# Increase steps
increase_steps
else
# Determine if touch event is triggered diagonally
check_event_trigger_touch(@x + 1, @y + 1)
end
# Prevent Moving Twice
return
end
end
end
end
# Call Original or other Aliases
stairs_move_right(turn_enabled)
end
#--------------------------------------------------------------------------
# * Stair Events Passable? - Game_Character
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# new_x : target x-coordinate
# new_y : target y-coordinate
# - Tiles have already been checked so only check for Event Collisions
#--------------------------------------------------------------------------
def stair_events_passable?(x, y, d, new_x, new_y)
# If through is ON
if @through
# passable
return true
end
# Check for any other possible reasons to not allow passage
unless other_passable?(x, y, d, new_x, new_y)
# Impassable
return false
end
# Generate a List of Map Events to loop through
event_list = make_passable_list(x, y, d, new_x, new_y)
# Loop Events in List (typically ALL Game Map Event Values)
for event in event_list
# If event coordinates are consistent with move destination
if mp_match_coordinates?(new_x, new_y, event.x, event.y)
# If through is OFF for Event being checked
unless event.through
# Impassable - Characters can not move through Events with Characters
return false if event_character_not_passable?(x,y,d,new_x,new_y,event)
end
end
end
# If Player is at Location this Event trying to move to
if mp_match_coordinates?(new_x, new_y, $game_player.x, $game_player.y)
# If Player is not flagged as Through
unless $game_player.through
# Impassable - Event has a Graphic so can NOT move to Players Location
return false if event_player_not_passable?(x, y, d, new_x, new_y)
end
end
# passable
return true
end
# If Heretic's Loop Maps is installed
if Game_Map.method_defined?(:map_loop_passable?)
#--------------------------------------------------------------------------
# * Stair Events Passable? - Game_Character
# - Alias Patch corrects Looping Map Arguments for this method
#--------------------------------------------------------------------------
alias loop_map_stair_events_passable? stair_events_passable? unless $@
def stair_events_passable?(x, y, d, new_x, new_y)
# If Map Loops Horizontal
if $game_map.loop_horizontal?
# Adjust X Arguments to Map Width
x %= $game_map.width
new_x %= $game_map.width
end
# if Map Loops Vertical
if $game_map.loop_vertical?
# Adjust y Arguments to Map Height
y %= $game_map.height
new_y %= $game_map.height
end
# Call Original with Adjusted Arguments for Looping Maps
loop_map_stair_events_passable?(x, y, d, new_x, new_y)
end
end # End Loop Map Optional Methods
#--------------------------------------------------------------------------
# * Stair Event Not Passable? - Game_Character
# - This allows NPCs to move across Events with Stair Terrain Tag Tiles
# which is normally not allowed for any Event unless that Event has
# a Through flag
# - Inverse Logic: -1 * -1 = 1
# - Tile Obstale Bits of the Tile now determines passage
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8)
# * 0 = Determines if all directions are impassable (for jumping)
# new_x : Target X Coordinate
# new_y : Target Y Coordinate
# event : Event being checked against in iteration loop
# result : results of other Aliases passed as an argument
#--------------------------------------------------------------------------
alias stair_event_not_passable? event_not_passable? unless $@
def event_not_passable?(x, y, d, new_x, new_y, event, result = nil)
# If this is an Event and is not the Player
if self != $game_player
# Impassable - There is a Flag that prohibits movement on Event Tile
return true if @no_event_tiles
end
# If target Event has a Tile with a Stair Terain Tag
if result.nil? and $game_system.event_stairs and event.tile_id > 0 and
stair_tag_valid?($game_map.terrain_tags[event.tile_id]) and
@character_name != "" and not @no_event_stairs
# Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0)
bit = (1 << (d / 2 - 1)) & 0x0f
# If obstacle bit is not set
unless $game_map.passages[tile_id] & bit != 0 or
$game_map.passages[tile_id] & 0x0f == 0x0f
# Passable - Conditions Met to allow Passage so false Impassable
result = false
end
end
# Call Original or other Aliases
stair_event_not_passable?(x, y, d, new_x, new_y, event, result)
end
# If Heretic's Loop Maps is NOT installed
unless Game_Map.method_defined?(:map_loop_passable?)
#--------------------------------------------------------------------------
# * Character Distance - Game_Character
# - Returns the X and Y Distance between self and another Character
# - This version does NOT check for Looping Maps because the
# script that allows for those features is unavailable here so
# this version is only used as a fallback for nonexistent methods
# target : Character (Player or Event)
#--------------------------------------------------------------------------
def character_distance(target)
# Return Difference X and Y values as Array
return [@x - target.x, @y - target.y]
end
end
#--------------------------------------------------------------------------
# * Turn Towards Player on Stairs - Game_Character
# - Favors Left and Right while on Stairs on Tiles
#--------------------------------------------------------------------------
alias stairs_turn_toward_player turn_toward_player unless $@
def turn_toward_player
# If Event is on a Stair Tag
if stair_tag_valid?(stair_tags_here(skip_events = false))
# Get difference in player coordinates
sx, sy = character_distance($game_player)
# If coordinates are equal
if sx == 0 and sy == 0
# Dont turn
return
end
# If vertical distance is longer
if sy.abs > sx.abs
# Turn up or down towards player
sy > 0 ? turn_up : turn_down
# If horizontal distance is longer
else
# Turn to the right or left towards player
sx > 0 ? turn_left : turn_right
end
# Prevent turning again
return
end
# Call Original or other Aliases
stairs_turn_toward_player
end
#--------------------------------------------------------------------------
# * Turn Away From Player on Stairs - Game_Character
# - Favors Left and Right while on Stairs on Tiles
#--------------------------------------------------------------------------
alias stairs_turn_away_from_player turn_away_from_player unless $@
def turn_away_from_player
# If Event is on a Stair Tag
if stair_tag_valid?(stair_tags_here(skip_events = false))
# Get difference in player coordinates
sx, sy = character_distance($game_player)
# If coordinates are equal
if sx == 0 and sy == 0
# Dont turn
return
end
# If vertical distance is longer
if sy.abs > sx.abs
# Turn up or down away from player
sy > 0 ? turn_down : turn_up
# If horizontal distance is longer
else
# Turn to the right or left towards player
sx > 0 ? turn_right : turn_left
end
# Prevent turning again
return
end
# Call Original or other Aliases
stairs_turn_away_from_player
end
#--------------------------------------------------------------------------
# * Move toward Player - Game_Character
# - Favors Left and Right while on Stairs on Tiles
#--------------------------------------------------------------------------
alias stairs_move_toward_player move_toward_player unless $@
def move_toward_player
# If Event is on a Stair Tag
if stair_tag_valid?(stair_tags_here(skip_events = false))
# Determine Correct Distance to Target for Looping Maps
sx, sy = character_distance($game_player)
# If coordinates are equal
if sx == 0 and sy == 0
return
end
# Get absolute value of difference
abs_sx = sx.abs
abs_sy = sy.abs
# Favor Horizontal if horizontal and vertical distances are equal
abs_sx += 1 if abs_sx == abs_sy
# If horizontal distance is longer
if abs_sx > abs_sy
# Move towards player, prioritize left and right directions
sx > 0 ? move_left : move_right
if not moving? and sy != 0
sy > 0 ? move_up : move_down
end
# If vertical distance is longer
else
# Move towards player, prioritize up and down directions
sy > 0 ? move_up : move_down
if not moving? and sx != 0
sx > 0 ? move_left : move_right
end
end
# Prevent moving again
return
end
# Call Original or other Aliases
stairs_move_toward_player
end
#--------------------------------------------------------------------------
# * Move away from Player
# - Favors Left and Right while on Stairs on Tiles
#--------------------------------------------------------------------------
alias stairs_move_away_from_player move_away_from_player unless $@
def move_away_from_player
# If Event is on a Stair Tag
if stair_tag_valid?(stair_tags_here(skip_events = false))
# Determine Correct Distance to Target for Looping Maps
sx, sy = character_distance($game_player)
# If coordinates are equal
if sx == 0 and sy == 0
return
end
# Get absolute value of difference
abs_sx = sx.abs
abs_sy = sy.abs
# Favor Horizontal if horizontal and vertical distances are equal
abs_sx += 1 if abs_sx == abs_sy
# If horizontal distance is longer
if abs_sx > abs_sy
# Move away from player, prioritize left and right directions
sx > 0 ? move_right : move_left
if not moving? and sy != 0
sy > 0 ? move_down : move_up
end
# If vertical distance is longer
else
# Move away from player, prioritize up and down directions
sy > 0 ? move_down : move_up
if not moving? and sx != 0
sx > 0 ? move_right : move_left
end
end
# Prevent moving again
return
end
# Call Original or other Aliases
stairs_move_away_from_player
end
# If Turn Toward Event is defined
if self.method_defined?(:turn_toward_event)
#------------------------------------------------------------------------
# * Turn Towards Event on Stairs - Game_Character
# id : character ID (0 can be used for Player)
# - Favors Left and Right while on Stairs on Tiles
# - Method provided by Caterpillar or other Scripts
#------------------------------------------------------------------------
alias stairs_turn_toward_event turn_toward_event unless $@
def turn_toward_event(id)
# If Character is on a Stair Tag
if stair_tag_valid?(stair_tags_here(skip_events = false))
# Get the Target
target = (id == 0) ? $game_player : $game_map.events[id]
# Prevent Crash if Target doesnt exist
if target.nil?
# This lets the Error Handler in the Aliased Method to work
stairs_turn_toward_event(id)
# Prevent other Processing since the game would normally crash here
return
end
# Get difference in target character coordinates
sx, sy = character_distance(target)
# If coordinates are equal
if sx == 0 and sy == 0
# Dont turn
return
end
# If vertical distance is longer
if sy.abs > sx.abs
# Turn up or down towards the target character
sy > 0 ? turn_up : turn_down
# If horizontal distance is longer
else
# Turn to the right or left towards target character
sx > 0 ? turn_left : turn_right
end
# Prevent turning again
return
end
# Call Original or other Aliases
stairs_turn_toward_event(id)
end
#------------------------------------------------------------------------
# * Turn Away From Event on Stairs - Game_Character
# id : character ID (0 can be used for Player)
# - Favors Left and Right while on Stairs on Tiles
# - Method provided by Caterpillar or other Scripts
#------------------------------------------------------------------------
alias stairs_turn_away_from_event turn_away_from_event unless $@
def turn_away_from_event(id)
# If Character is on a Stair Tag
if stair_tag_valid?(stair_tags_here(skip_events = false))
# Get the Target
target = (id == 0) ? $game_player : $game_map.events[id]
# Prevent Crash if Target doesnt exist
if target.nil?
# This lets the Error Handler in the Aliased Method to work
stairs_turn_toward_event(id)
# Prevent other Processing since the game would normally crash here
return
end
# Get difference in target character coordinates
sx, sy = character_distance(target)
# If coordinates are equal
if sx == 0 and sy == 0
# Dont turn
return
end
# If vertical distance is longer
if sy.abs > sx.abs
# Turn up or down away from the target character
sy > 0 ? turn_down : turn_up
# If horizontal distance is longer
else
# Turn to the right or left away from target character
sx > 0 ? turn_right : turn_left
end
# Prevent turning again
return
end
# Call Original or other Aliases
stairs_turn_toward_event(id)
end
end
end
#==============================================================================
# ** Game_Player
#==============================================================================
class Game_Player < Game_Character
#--------------------------------------------------------------------------
# * Stair Events Passable? - Game_Player
# - Allows for Debug Mode to pass through anything
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# new_x : target x-coordinate
# new_y : target y-coordinate
#--------------------------------------------------------------------------
def stair_events_passable?(x, y, d, new_x, new_y)
# If DEBUG (running game from Editor) and pressing CTRL Key
return true if $DEBUG and Input.press?(Input::CTRL)
# Passable / Impassable determined by Parent Method of same name
return super
end
#--------------------------------------------------------------------------
# * Check Event Trigger There - Game_Player
# - Triggers Events while on Stairs so Events can trigger Diagonally
# - Front Event Starting Determinant (Default)
# triggers : event triggers - Action Button, Event Touch, Player Touch
#--------------------------------------------------------------------------
alias stairs_check_event_trigger_there check_event_trigger_there unless $@
def check_event_trigger_there(triggers)
result = false
# If event is running
if $game_system.map_interpreter.running?
return result
end
# Look for Stair Tags at current location
tag = stair_tags_here
# If Left / Right, on Stairs and Options to trigger Diagonal Events
if tag > 0 and [4, 6].include?(@direction) and STAIR_TRIGGER > 0
# Shorthand S for Stair Trigger Constant in Config
s = STAIR_TRIGGER
# Calculate front event coordinates
new_x, new_y = make_new_xy(@x, @y, @direction)
# Get Stair Tags at New Location
next_tag = stair_tags_there(@direction, tag)
# Determine Diagonal Coordinates
new_xd, new_yd = make_new_xy_for_stairs(@direction, tag)
# Get List of Events at Map XY
event_list = make_events_list(new_x, new_y)
# Collision Optimizer causes event_list to already match coordinates
if s == 2 and $game_map.respond_to?(:get_events_at_xy)
# Add to very small List of Events if checking Two Locations on Map
event_list += make_events_list(new_x, new_yd)
end
# Loop Events in List
for e in event_list
# Default
next_trigger_check = false
# If Option Conditions and Coordinates are consistent
if s == 0 and mp_match_coordinates?(new_x, new_y, e.x, e.y) or
s == 1 and mp_match_coordinates?(new_x, new_yd, e.x, e.y) or
s == 2 and (mp_match_coordinates?(new_x, new_y, e.x, e.y) or
mp_match_coordinates?(new_x, new_yd, e.x, e.y) )
# Set Flag to run other checks and start event when Triggerable
next_trigger_check = true if triggers.include?(e.trigger)
end
# If event coordinates and triggers were consistent above
if next_trigger_check == true
# If starting determinant is front event (other than jumping)
if not e.jumping? and not e.over_trigger? and not e.starting
# Start the Event
e.start
# Prevents Counter Triggers
result = true
end
end
end
# If fitting event is not found
if result == false
# If front tile is a counter and consistent with Diagonal Options
if s == 0 and $game_map.counter?(new_x, new_y) or
s == 1 and $game_map.counter?(new_x, new_yd) or
s == 2 and ($game_map.counter?(new_x, new_y) or
$game_map.counter?(new_x, new_yd) )
# Calculate 1 tile inside coordinates
new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
# Get List of Events at Map XY
event_list = make_events_list(new_x, new_y)
# Add to List of Events if checking Two Locations on Map
event_list += make_events_list(new_x, new_yd) if s == 2
# Loop Events in List
for e in event_list
# If Option Conditions, Coordinates and Triggers are consistent
if s == 0 and mp_match_coordinates?(new_x, new_y, e.x, e.y) or
s == 1 and mp_match_coordinates?(new_x, new_yd, e.x, e.y) or
s == 2 and (mp_match_coordinates?(new_x, new_y, e.x, e.y) or
mp_match_coordinates?(new_x, new_yd, e.x, e.y) )
# If starting determinant is front event (other than jumping)
if triggers.include?(e.trigger) and
not e.jumping? and not e.over_trigger? and not e.starting
# Start Event and set the Result
e.start
result = true
end
end
end
end
end
# Prevent Original or other Alias from reprocessing the same work
return result
end
# Call Original or other Aliases
stairs_check_event_trigger_there(triggers)
end
end
#==============================================================================
# ** Game_Event
#==============================================================================
class Game_Event < Game_Character
#--------------------------------------------------------------------------
# * Public Instance Variables - Game_Event
#--------------------------------------------------------------------------
attr_accessor :no_event_tiles # Prevents NPCs on Event Tiles
attr_accessor :no_event_stairs # Prevents NPCs on Event Stairs
#--------------------------------------------------------------------------
# * Reset Page Comment Config - Game_Event
# - Resets Instance Variables
# - @stairs and @no_stairs already have accessor Methods
#--------------------------------------------------------------------------
alias stairs_reset_page_comment_config reset_page_comment_config unless $@
def reset_page_comment_config
# Reset to set again by Comment Conditions
@stairs = nil
@no_stairs = nil
@no_event_stairs = nil
@no_event_tiles = nil
# Runs Original or Other Aliases of this method
stairs_reset_page_comment_config
end
#--------------------------------------------------------------------------
# * Stairs Check Comment Page Config - Game_Event
# comment : the Comment to be checked to adjust Page Properties
# count : integer of which List of Event Commands is checked
# - Checks for \use_stairs, \no_stairs, and \no_event_tiles Comments
# - Returns count when a Comment is found to prevent checks by other Aliases
# Note: When aliasing, please return the value of count, especially
# if your script adjusted this value.
#--------------------------------------------------------------------------
alias stairs_check_page_comment_config check_page_comment_config unless $@
def check_page_comment_config(comment, count)
# Looks for "\use_stairs" in the Comments with Regular Expressions or REGEX
comment.gsub(/^\\use_stairs\z/i){@stairs = true; @no_stairs = nil;
return count}
# Looks for "\no_stairs" in the Comments
comment.gsub(/^\\no_stairs\z/i){@stairs = nil; @no_stairs = true;
return count}
# Looks for "\no_event_tiles" in the Comments (Use on Character Events)
comment.gsub(/^\\no_event_tiles\z/i){@no_event_tiles = true;
return count}
# Looks for "\no_event_tiles" in the Comments (Use on Character Events)
comment.gsub(/^\\no_event_stairs\z/i){@no_event_stairs = true;
return count}
# Return counter for other Aliases when no Comments are found
return stairs_check_page_comment_config(comment, count)
end
end