#==============================================================================
#
# HERETIC'S MODULAR PASSABLE [XP]
# Version 1.0
# Friday, October 31st, 2014
#
#==============================================================================
#
# ----- Installation ------
#
# Place below the SDK if you use it, or below Scene Debug. It should be above
# all other custom scripts.
#
#
# --- Version History ---
#
# Version 1.0 - Tuesday, October 21st, 2014
# - Initial Release
#
# ----- Overview ------
#
# This is a Compatability Tool! Use only when required!
#
# Some other scripts may be dependant on this one. If this script is required
# by another Script, just place this below the SDK if it is installed, or
# below Scene_Debug, and above all other scipts.
#
# This script is NOT intended as an SDK.
#
# It is only intended to allow specific scripts that are not compatible due
# to conflicting definitions of passable to be made compatible. I expect
# that it will cause compatability issues, just like the SDK and MACL, hence
# why I suggest using it sparingly. If you really like it, or it helps you
# solve compatability issues, be my guest and use it as a foundation.
#
# Dont just install this script by itself as it does nothing for you without
# dependant scripts.
#
#
# ------ Modularization ------
#
# The intent of this script is to Modularize all of the internal calls made
# within Passable methods for Game_Map and Game_Character.
#
# Checks that are made and local variables created are now done by separate
# methods. This allows Aliases of these methods to alter the functionality
# without the need to either rewrite the main Passable method itself, or to
# do additional iterations elsewhere, which is bad for performance.
#
# - This Script is NOT intended for Maximum Performance
# - This Script IS intended for Maximum Compatability
#
# The benefits will only be apparent when two or more scripts are used that are
# dependant on this framework.
#
#
# ----- Additional Arguments -----
#
# I tried to pass along relevant arguments to each of the methods, even if
# those arguments are not initially needed. Other scripts may have need of
# the arguments passed, even if the initial functionality does not use the
# arguments. Local Variables have also been passed because they can be very
# expensive to recalculate, such as event hash iteration.
#
# In order to maximize compatability between other scripts without creating
# the need to have a specific order for those scripts, every method that is
# called by the main Passable methods allows previously determined results
# to be passed along to other Aliases, or to be completely overridden by
# returning the value as determined by those Aliases.
#
# If you have a script that needs to alter the results of make_new_xy or
# make_new_xy_8dir, please pass the result value in an Array of [x, y]
# to receive the values properly. This script does not provide for
# actual eight directional movement, but can handle the checks needed
# in eight directional movement without replacing the passable methods.
#
#
#
# ----- Additional Functionality: Tile Events ------
#
# Since this script isnt intended to make every script compatible with every
# other script, I took the liberty of making some enhancements.
#
# The first significant change that I made was to create a hash to hold only
# Events that have Tile Graphics. Game_Map Passable originally checked all
# of the events on a map, then checked if each event had a Tile Graphic each
# and every time an Event tried to move. The @event_tiles hash is updated
# in Refresh for Game Event, which is far less frequent than iterating every
# single Event multiple times for each frame of gameplay.
#
# It is much faster to have fewer events to iterate. So Game_Map Passable now
# only iterates the Events in the smaller array. Trust me, the performance
# gain made here is significant enough to offset the extra checks made by
# additional arguments passed as methods.
#
# ----- Additional Functionality: Event Refresh Options -----
#
# Event Refresh has two new purposes. The first is to update the @event_tiles
# hash. The second allows iterating the first several Comments on an Event
# Page for other scripts that use Comments to configure Events.
#
# Event Refresh allows you to easily put in Comment Configurations for your
# script. When an Event is Refreshed, the Comments are passed to a method
# that you can Alias easily and scan for your conditions. This helps to
# prevent conditions that Comments need to be on the first line of
# an Event Page, so additional scripts can add lots of functionality and
# retain compatability.
#
# ----- Comment Limit -----
#
# The COMMENT_LIMIT is used so that only Comments made within the LIMIT
# number of lines are checked. So if you have \option = "foo" on the 3rd line
# it will be checked, but putting \other_option = true on line 17, that wont
# be checked because it will exceed the LIMIT. The COMMENT_LIMIT feature is
# purely for performance.
#
# The Default COMMENT_LIMIT is 10. I strongly recommend that you keep this
# value for performance. If you need to change this value, you can do so
# per Event by adding a \comment_limit[N] Comment on that Event page. This
# will allow only that Page of that Event to check more than the Default.
# This allows performance gains made by keeping the constant at a pretty
# low number intact while still allowing you to do what you need to do
# without comprimising performance. The code is also intended as an Example
# for Scripters to take a look at to see how to use Comments to add additional
# properties in their scripts more easily.
#
# \comment_limit[N] - Overrides the Constant value set in Configuration
#
# Note: Each line of a Comment or Script counts as a Line.
#
# Note: Only the first line of a Comment is passed to the checking method.
# Additional lines can be checked with proper Scripting since the
# counter is also passed as an argument.
#
#
#
# ----- Compatability -----
#
# This script will NOT be compatible with any other script that replaces
# either Game_Map Passable or Game_Character Passable. If a script replaces
# Game_Event Refresh, that can be fixed by putting the entire Game_Event class
# below the conflicting script, but leave Game_Map and Game_Character classes
# in this script above other user created scripts, except the SDK.
#
# If the nature of other scripts is extremely different, expect problems. So
# other scripts like Pixel Movement Scripts most likely will be too foreign
# for this script to offer any compatability. Bananas and Screwdrivers.
#
# This is intended for making the Default Movements more Modular only.
#
#
# ----- Framework Script -----
#
# *** DO NOT USE SUPER FOR ALIASES IN IHERITING CLASSES ***
#
# The result of using Super will cause OTHER SCRIPTS BELOW YOURS TO BREAK.
#
# If you use this Script as a Framework for a Script you create, in order
# to maintain a high degree of compatability with other scripts, Class
# Structure needs to be maintained. This is important when altering
# the outcome of any of the Game_Character definitions. Inheriting
# Classes in Ruby works great, however, aliasing in Subclasses and the use
# of SUPER will break Inheritance Chains of additional scripts. Your script
# will work just fine, but your Script will also BREAK any following Scripts
# because methods called in following scripts will not be called at all!
#
# Each Method defined here also contains a "- Class_Name" so that you can
# maintain proper Class Structure. Alias these methods within their
# appropriate classes when applicable.
#
# When you use Game_Event < Game_Character, and create an Alias of a method
# defined in other scripts under Game_Character, any additional scripts that
# use Game_Event passage checks will NOT be called!
#
# To maintain your Class Structure for dependant Scripst, please ONLY make
# aliases of the Game_Character class and DO NOT create aliases or use
# the Super command in your scripts. To allow you to make your necessary
# checks for proper conditions, the argument of self_event has been passed
# to relevant methods. Use "not self_event.nil? and self != self_event", or
# "self == $game_player" for Player, or "self != self_event" for Events.
#
# Staying within Game_Character and using self checks for methods defined
# in the Modular Passable script will allow both your script and other
# dependant scripts to be 100% compatible and retain Script Order Free
# functionality. Definitions for Game_Event that pertain to resetting
# any @instance_variables and define them can be aliased within the
# Event_Class. Methods that are unique to your script can be used in
# whatever Class you want. Methods that are defined in this script
# should maintain the Class Structure of this Script.
#
# If any methods in a script you create are not being called as expected, then
# start looking at any dependant scripts that I have not written for proper
# Class Sturctures. Game_Character should stay in Game_Character and
# Game_Event should stay in Game_Event. This could very well be the reason
# the methods defined in your script are not being called, and it would have
# nothing to do with your script.
#
# If you add additional arguments to any method, please pass two arguments
# in your *args calls, one for a :type, and additional *args for what ever
# values you need to check. This will allow your script to maintain 100%
# compatability with other scripts that also need to use *args, then just
# write your checks like "if args[0] == :my_type and ...". That will make
# sure your script only checks for your conditions, and other scrips will
# check for their conditions. This is untested and isnt very efficient,
# but will maintain a higher degree of compatability.
#
# --- Return vs Result ---
#
# You can return true or false if you believe your conditions should
# override all other scripts. For example, Super_Through or something like
# that. Otherwise I would recommend using "result = true / false" as
# this script will return a true / false value before making the normal
# checks defined in this script.
#
#
# ----- Configuration: COMMENT_LIMIT -----
#
# COMMENT_LIMIT puts a cap on the number of Lines that will be read in
# the List of Event Commands for Comment Configurations. It prevents
# every single line of an Event from being read, which will cause Lag
# when you have lots of Events with lots of commands. Each Line of
# a Comment or Script will count as a Line. Increasing this number
# will have an impact on performance so don't go nuts and set this
# number beyond anything reasonable.
#
# You can override the COMMENT_LIMIT constant by adding a \comment_limit[N]
# Comment to an Event within the first 10 lines. This is useful if you
# only have very few events that need to exceed this limit. However, if
# your Events are all full of Configuration Comments, then it is an
# appropriate time to bump up the value of the constant.
#
#==============================================================================
COMMENT_LIMIT = 10 # Number of Event Commands to scan for Comment Options
#==============================================================================
# ** Game_Map
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
# * Object Initialization - Game_Map
#--------------------------------------------------------------------------
alias modular_passable_initialize initialize unless $@
def initialize
# Call Original or other Aliases
modular_passable_initialize
# New Property to hold Hash of all Events with Tile Graphics
@event_tiles = {}
end
#--------------------------------------------------------------------------
# * Event Tiles - Game_Map
# - A smaller hash than all events to iterate through for performance
# - Updates on Event Refresh for performance. Any change in Pages with
# Switches or other Conditions requires Events to be Refreshed, which
# is where the hash is updated.
#--------------------------------------------------------------------------
def event_tiles
# Returns existing hash or creates new for save games
return @event_tiles ||= {}
end
#--------------------------------------------------------------------------
# * Setup - Game_Map
# - Creates or Clears the Hash
# map_id : map ID
#--------------------------------------------------------------------------
alias modular_passable_setup setup unless $@
def setup(map_id)
# Clear Event Tiles (Each Event with a Tile will add itself on Refresh)
@event_tiles = {}
# Call Original or other Aliases
modular_passable_setup(map_id)
end
#--------------------------------------------------------------------------
# * Determine Valid Coordinates - Game_Map
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# self_event : Character calling $game_map.passable
# result : true or false passed as an arg by Aliases
# - Added all available arguments for other Aliases to alter result
#--------------------------------------------------------------------------
def valid?(x, y, d = nil, self_event = nil, result = nil)
# If an Alias has declared a Result, use the Alias result instead
return result if not result.nil?
# Standard Map Valid Determination
return (x >= 0 and x < width and y >= 0 and y < height)
end
#--------------------------------------------------------------------------
# * Make Bit - Game_Map
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# self_event : Character calling $game_map.passable
# result : true or false passed as an arg by Aliases
# - Converts Direction in Obstacle Bit (00001011)
#--------------------------------------------------------------------------
def make_bit(x, y, d, self_event = nil, result = nil)
# If an Alias has declared a result, use the Alias result instead
return result if not result.nil?
# Change direction (0,2,4,6,8,10) to Obstacle Bit (0,1,2,4,8,0)
bit = (1 << (d / 2 - 1)) & 0x0f
# Return the Obstacle Bit
return bit
end
#--------------------------------------------------------------------------
# * Make Map Passable List - Game_Map
# - Returns an Array or Hash of Events for Iteration
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# bit : Direction converted to Obstacle Bit
# self_event : Character calling $game_map.passable
# results : MUST be an Array or Hash of Events
# NOTE: results is Plural, not singular
# NOTE: MUST return an Array of Events
#--------------------------------------------------------------------------
def make_map_passable_list(x, y, d, bit, self_event = nil, results = nil)
# If an Alias has declared an Hash of Events, use the Alias result instead
return results if not results.nil?
# Return the Hash of Map using event_tiles Method
return event_tiles.values
end
#--------------------------------------------------------------------------
# * Map Passable Conditions? - Game_Map
# - Return truth value if conditions met: true / false
# - Conditions for running Passability Checks on an Event
# - Typically an Event isnt checking itself, Through, and Coordinates match
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# bit : Direction converted to Obstacle Bit
# event : Iterated Event made by make_map_passable_list
# self_event : Character calling $game_map.passable
# result : true or false passed as an arg by Aliases
#--------------------------------------------------------------------------
def map_passable_conditions?(x,y,d,bit,event,self_event = nil, result = nil)
# If an Alias has declared a result, use the Alias result instead
return result if not result.nil?
# Standard Conditions for checking Event Tiles
if event.x == x and event.y == y and
not event.through and event != self_event and
# Check this Event Tile
return true
end
# Default
return false
end
#--------------------------------------------------------------------------
# * Event Tile Not Passable? - Game_Map
# - If an Event has a Tile and isnt Through, passage determined by bits
# - Inverse Logic: -1 * -1 = 1
# - Returns TRUE if a Tile is Not Passable
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# 10 is used for Jumping
# bit : obstacle bit for specific direction passage
# event : iteration of each event in all events to be checked
# self_event : Self (If event is determined passable)
# result : true or false passed as an arg by Aliases
#--------------------------------------------------------------------------
def event_tile_not_passable?(x,y,d,bit,event,self_event = nil, result = nil)
# If an Alias has another result, use it
return result if not result.nil?
# If obstacle bit is set for that direction
if @passages[event.tile_id] & bit != 0
# Impassable - True is used to say this is NOT Passable
return true
# If obstacle bit is set in all directions
elsif @passages[event.tile_id] & 0x0f == 0x0f
# Impassable - True is used to say this is NOT Passable
return true
end
end
#--------------------------------------------------------------------------
# * Event Tile Passable? - Game_Map
# - Non Through Events with Passable Non Priority Tiles are Passable
# - Returns TRUE if a Tile is Passable
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# 10 is used for Jumping
# bit : obstacle bit for specific direction passage
# event : iteration of each event in all events to be checked
# self_event : Character calling $game_map.passable
# result : true or false passed as an arg by Aliases
#--------------------------------------------------------------------------
def event_tile_passable?(x, y, d, bit, event, self_event = nil, result = nil)
# If an Alias has another result, use it
return result if not result.nil?
# If Event has a Tile with no Priority
if @priorities[event.tile_id] == 0
# Passable
return true
end
end
#--------------------------------------------------------------------------
# * Tile Not Passable? - Game_Map
# - Returns TRUE if a Map Tile is Not Passable due to bits
# - Inverse Logic: -1 * -1 = 1
# - Returns true when Not Passable
# - Must return False or Nil to allow for Movement, other checks made
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# 10 is used for Jumping
# bit : obstacle bit for specific direction passage
# tile_id : ID of each Tile that is being checked for Passage
# self_event : Character calling $game_map.passable
# result : true or false passed as an arg by Aliases
#--------------------------------------------------------------------------
def tile_not_passable?(x, y, d, bit, tile_id, self_event = nil, result = nil)
# If an Alias has another result, use it
return result if not result.nil?
# Tile ID acquistion failure
if tile_id == nil
# Impassable
return true
# If obstacle bit is set
elsif @passages[tile_id] & bit != 0
# Impassable - True is used to say Tile is NOT Passable
return true
# If obstacle bit is set in all directions
elsif @passages[tile_id] & 0x0f == 0x0f
# Impassable - True is used to say Tile is NOT Passable
return true
end
end
#--------------------------------------------------------------------------
# * Tile Passable? - Game_Map
# - Returns TRUE if a Map Tile is Passable and skips next conditions
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# 10 is used for Jumping
# bit : obstacle bit for specific direction passage
# tile_id : ID of each Tile that is being checked for Passage
# self_event : Character calling $game_map.passable
# result : true or false passed as an arg by Aliases
#--------------------------------------------------------------------------
def tile_passable?(x, y, d, bit, tile_id, self_event=nil, result=nil)
# If an Alias has another result, use it
return result if not result.nil?
# If priorities other than not passable that are 0
if @priorities[tile_id] == 0
# Passable
return true
end
end
#--------------------------------------------------------------------------
# * Passable? - Game_Map
#
# *** DO NOT OVERWRITE THIS METHOD ***
# (aliases are fine however)
#
# - Determines if New Location is passable based on Tiles and Event Tiles.
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8,10)
# * 0,10 = determine if all directions are impassable
# self_event : Self (If event is determined passable)
# - This only checks for Tiles and Events with Tiles to determine if
# a location is passable. Character Collisions are determined in
# another method, Game_Character Passable, not here.
# - The List of Events to check can be altered with Aliases instead
# of any need to replace this method, usually
#--------------------------------------------------------------------------
def passable?(x, y, d, self_event = nil)
# If coordinates given are outside of the map
unless valid?(x, y, d, self_event)
# impassable
return false
end
# Change direction (0,2,4,6,8,10) to obstacle bit (0,1,2,4,8,0) with Method
bit = make_bit(x, y, d, self_event)
# Create a List of Events to check on Map for Passable
event_list = make_map_passable_list(x, y, d, bit, self_event)
# Iterate each Event in the Event List
for event in event_list
# If Conditions indicate Event needs to be Checked (Location Match)
if map_passable_conditions?(x, y, d, bit, event, self_event)
# If Event Tile Not Passable returns True, then Event is Not Passable
if event_tile_not_passable?(x, y, d, bit, event, self_event)
# Impassable
return false
# If Event Tile Passable returns True, then Event is Passable
elsif event_tile_passable?(x, y, d, bit, event, self_event)
# Passable
return true
end
end
end
# Loop searches in order from top of layer
for i in [2, 1, 0]
# Get tile ID
tile_id = data[x, y, i]
# If Tile Not Passable returns True, then Tile is Not Passable
if tile_not_passable?(x, y, d, bit, tile_id, self_event)
# Impassable
return false
# If Tile Passable returns True, then Tile is Passable
elsif tile_passable?(x, y, d, bit, tile_id, self_event)
# Passable
return true
end
end
# passable
return true
end
end
#==============================================================================
# ** Game_Character
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Make New XY - Game_Character
# - Makes New Coordinates for X and Y (4 Directional Movement)
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8)
# result : Array passed as an arg by Aliases
#
# NOTE: Must return an Array of New Map Coordinates [new_x, new_y]
# new_x, new_y = make_new_xy(x, y, d)
# - This can be Aliased to alter New Coordinates based on other conditions
#--------------------------------------------------------------------------
def make_new_xy(x, y, d, result = nil)
# If an Alias has another result, use it (Should return 2 values in Array)
return result if not result.nil?
# Get new coordinates for four directional movement
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
# return array of New Coordinates
return [new_x, new_y]
end
#--------------------------------------------------------------------------
# * Make New XY 8D - Game_Character
# - Make New Coordinates for X and Y (8 Directional Movement)
# x : x-coordinate
# y : y-coordinate
# d : direction (0,1,2,3,4,6,7,8,9 no 5)
# result : Array passed as an arg by Aliases
# - This method is not called, but is available if needed
#
# Note: Bit Flipping with 10 - d works, 10 - 9 (up right) = 1 (down left)
# Note: Must return an Array of New Map Coordinates [new_x, new_y]
# new_x, new_y = make_new_xy_8d(x, y, d)
#--------------------------------------------------------------------------
def make_new_xy_8d(x, y, d, result = nil)
# If an Alias has another result, use it (Should return 2 values in Array)
return result if not result.nil?
# Get new coordinates for Eight Directional movement
new_x = x + ([9, 6, 3].include?(d) ? 1 : [7, 4, 1].include?(d) ? -1 : 0)
new_y = y + ([1, 2, 3].include?(d) ? 1 : [7, 8, 9].include?(d) ? -1 : 0)
return [new_x, new_y]
end
#--------------------------------------------------------------------------
# * Event Not Passable? - Game_Character
# - Events can NOT move through another Event unless one is flagged Through
# - Player is allowed to move through Events, other checks performed later
# - Inverse Logic: -1 * -1 = 1
# - Returns true when Not Passable
# - Must return False or Nil to allow for Movement
# 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 : true or false passed as an arg by Aliases
#--------------------------------------------------------------------------
def event_not_passable?(x, y, d, new_x, new_y, event, result = nil)
# If an Alias has another result, use it
return result if not result.nil?
# If Character doing the Passable check is an Event, not a Player
if self != $game_player
# Impassable - TRUE that Events are Not Passable through another Event
return true
end
end
#--------------------------------------------------------------------------
# * Event Character Not Passable? - Game_Character
# - No Character (Events or Player) can move through any Event that has
# a Character Graphic, unless one of them is flagged Through
# - Inverse Logic: -1 * -1 = 1
# - Returns true when Not Passable
# - Must return False or Nil to allow for Movement
# 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 : true or false passed as an arg by Aliases
#--------------------------------------------------------------------------
def event_character_not_passable?(x, y, d, new_x, new_y, event, result = nil)
# If an Alias has another result, use it
return result if not result.nil?
# If this Event has a Character Graphic
if event.character_name != ""
# Impassable - TRUE that Event checked has a Character Graphic
return true
end
end
#--------------------------------------------------------------------------
# * Other Passable? - Game_Character
# - This check is performed prior to Event Iteration for Performance
# - MUST return True to allow for Movement
# 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
# result : true or false passed as an arg by Aliases
#--------------------------------------------------------------------------
def other_passable?(x, y, d, new_x, new_y, result = nil)
# If an Alias has another result, use it
return result if not result.nil?
# Passable - Default
return true
end
#--------------------------------------------------------------------------
# * Make Passable List - Game_Character
# - Returns an Array or Hash of Events for Iteration
# 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
# results : MUST be an Array of Events if used
# NOTE: results is Plural, not singular
# NOTE: MUST return an Array of Events
#--------------------------------------------------------------------------
def make_passable_list(x, y, d, new_x, new_y, results = nil)
# If an Alias has declared an Hash of Events, use the Alias result instead
return results if not results.nil?
# Return All Event Values in Game Map Hash
return $game_map.events.values
end
#--------------------------------------------------------------------------
# * Make Events List - Game_Character
# - Similar to Make Passable List
# - Intended for use in Non Passable determining methods in other Scripts
# - Intended to be aliased where X and Y values can be adjusted as needed
# - Excludes other Arguments needed by Make Passable List
# - Used by other Scripts with Triggers when X or Y have no arguments to fix
# x : x-coordinate
# y : y-coordinate
# results :
#--------------------------------------------------------------------------
def make_events_list(x, y, results = nil)
# If an Alias has declared an Hash of Events, use the Alias result instead
return results if not results.nil?
# Return All Event Values in Game Map Hash
return $game_map.events.values
end
#--------------------------------------------------------------------------
# * Passable Conditions? - Game_Character
# - Return true / false if conditions met
# - Conditions for running Passability Checks on an Event
# - Typically an Event isnt checking itself, Through, and Coordinates match
# 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
# event : Iterated Event made by make_passable_list
# result : values other than nil by Aliases override checks here
#--------------------------------------------------------------------------
def passable_conditions?(x, y, d, new_x, new_y, event, result = nil)
# If an Alias has declared a result, use the Alias result instead
return result if not result.nil?
# Standard Conditions for checking Event Tiles
if event.x == new_x and event.y == new_y and
not event.through and event != self
# Check this Event
return true
end
end
#--------------------------------------------------------------------------
# * Match Coordinates? - Game_Character
# - Modular Passable mp_
# - Can be Aliased to alter Argument Values prior to comparison
# - Used by Heretic's Loop Maps to correct Values
#--------------------------------------------------------------------------
def mp_match_coordinates?(x, y, tx, ty)
# If Argument Coordinates Match
return true if x == tx and y == ty
end
#--------------------------------------------------------------------------
# * Player Conditions? - Game_Character
# - Return true / false if conditions met
# - If New Location matches Player Position and Player not Through
# 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
# result : values other than nil by Aliases override checks here
#--------------------------------------------------------------------------
def player_conditions?(x, y, d, new_x, new_y, result = nil)
# If an Alias has declared a result, use the Alias result instead
return result if not result.nil?
# If Coordinates match Player Location and Player Through is Off
if $game_player.x == new_x and $game_player.y == new_y and
not $game_player.through
# Conditions are met
return true
end
end
#--------------------------------------------------------------------------
# * Event Player Not Passable? - Game_Character
# - Checks for Events with Character Graphics trying to move to the
# current Location of the Game Player
# - Inverse Logic: -1 * -1 = 1
# - Returns true when Not Passable
# - Must return False or Nil to allow for Movement
# 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
# result : true or false passed as an arg by Aliases
#--------------------------------------------------------------------------
def event_player_not_passable?(x, y, d, new_x, new_y, result = nil)
# If an Alias has another result, use it
return result if not result.nil?
# If this Event has a Character Graphic
if @character_name != ""
# Impassable - This Event with Graphic trying to move to Players Location
return true
end
end
#--------------------------------------------------------------------------
# * Passable? - Game_Character
#
# *** DO NOT OVERWRITE THIS METHOD ***
# (aliases are fine however)
#
# - Checks for Character Collisions to determine if Passable
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8)
# * 0 = Determines if all directions are impassable (for jumping)
#--------------------------------------------------------------------------
def passable?(x, y, d)
# Generate new X and Y coordinates
new_x, new_y = make_new_xy(x, y, d)
# If coordinates are outside of map
unless $game_map.valid?(new_x, new_y, d, self)
# Impassable
return false
end
# If through is ON
if @through
# Passable
return true
end
# If unable to leave first move tile in designated direction
unless $game_map.passable?(x, y, d, self)
# Impassable
return false
end
# If unable to enter move tile in designated direction
unless $game_map.passable?(new_x, new_y, 10 - d, self)
# Impassable
return false
end
# If unable to move for any other reason (alias this method)
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 conditions are met to check the event for passable
if passable_conditions?(x, y, d, new_x, new_y, event)
# If Event has Conditions that prohibit passage
if event_not_passable?(x, y, d, new_x, new_y, event)
# Impassable
return false
# If Character has Conditions that prohibit passage
elsif event_character_not_passable?(x, y, d, new_x, new_y, event)
# Impassable
return false
end
end
end
# If Player is at or moving to Location this Event trying to move to
if player_conditions?(x, y, d, new_x, new_y)
# If Event not allowed to move to Players Location
if event_player_not_passable?(x, y, d, new_x, new_y)
# Impassable - Typically Event has a Character Graphic
return false
end
end
# Passable
return true
end
end
#==============================================================================
# ** Game_Player
#==============================================================================
class Game_Player < Game_Character
#--------------------------------------------------------------------------
# * Passable Determinants - Game_Player
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8)
# * 0 = Determines if all directions are impassable (for jumping)
#--------------------------------------------------------------------------
def passable?(x, y, d)
# Generate new X and Y coordinates
new_x, new_y = make_new_xy(x, y, d)
# If coordinates are outside of map
unless $game_map.valid?(new_x, new_y)
# Impassable
return false
end
# If debug mode is ON and ctrl key was pressed
if $DEBUG and Input.press?(Input::CTRL)
# Passable
return true
end
super
end
end
#==============================================================================
# ** Game_Event
#==============================================================================
class Game_Event < Game_Character
#--------------------------------------------------------------------------
# * 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
#
# - This is intended to be Aliased to prevent Iterations of each Comment
# - Each Comment can be scanned for specific strings of characters
# - Counter can be adjusted if you have a need to use more than one line
# - Comment Limit (Constant) is used to prevent scanning after Limit Reached
# - Count allows access to all Event Commands @page.list[count]
#
# Example 1: Set a TRUE Option if the string \option is the comment
# comment.gsub(/\\option/i){@option = true; return count}
# Example 2: Set a Numeric Value to the Option \option[123]
# comment.gsub(/^\\option\[([0-9]+)/z\]/i) {@option = $1.to_i;
# return count}
#
# Note: Proper Aliasing will still allow Non Comment Commands to be checked
# by checking the count argument passed. Code 108 is the First Line
# of a Comment. Code 408 is any Next Line of a Comment. Next Lines
# do count against COMMENT_LIMIT.
#
# if @page.list[count + 1].parameters.code == 408
# # Advance count for other Aliases
# count += 1
# # How to access a Comment on the Next Line
# your_command = @page.list[count].parameters[0]
# # Do your Script Checks here
# end
# # Return count of Original or other Aliases and pass Args
# return alias_of_check_page_comment_config(comment, count)
#
# Note: When aliasing, please return the value of aliased methods for
# the local variable count to be altered as needed.
#--------------------------------------------------------------------------
def check_page_comment_config(comment, count)
# Looks for "\comment_limit[N]" Comments to Override Comment Limit Constant
comment.gsub(/^\\comment_limit\[([-0-9]+)\]\z/i){@comment_limit = $1.to_i;
return count;}
# Return adjusted or unadjusted counter
return count
end
#--------------------------------------------------------------------------
# * Reset Page Comment Config - Game_Event
# - Use this to Reset Varaibles that are set by Comment Configuration
# - If you have an Option that you want to be different on each Page, then
# clear those values here so they can be checked again instead of
# sticking around on different pages when you dont want them.
# - @option = nil or your Default Value
#--------------------------------------------------------------------------
def reset_page_comment_config
# Reset Comment Limit Overrides
@comment_limit = nil
# Reset any Page Comment Configuration Variables here
return true
end
#--------------------------------------------------------------------------
# * Comment Limit? - Game_Event
# - Returns true / false if comment limit reached
# - Override Constant per Event Page with a \comment_limit[20] Comment
#--------------------------------------------------------------------------
def comment_limit?(count)
return (count > @comment_limit) if not @comment_limit.nil?
return (count > COMMENT_LIMIT)
end
#--------------------------------------------------------------------------
# * Refresh - Game_Event
# - Checks for Tile IDs and updates smaller $game_map.event_tiles hash
# - Aliasable Methods used to Reset and Scan for Comment Configs
# Note: Config Comments are ONLY checked on a Page Change
#--------------------------------------------------------------------------
alias tile_event_and_comment_refresh refresh unless $@
def refresh
# Initial State of current @page before Refresh
page = @page
# Call Original or Other Aliases of Refresh
tile_event_and_comment_refresh
# If Valid Tile ID and Not Erased (Call after Refresh method)
if @tile_id > 0 and not @erased
# Store Event with Tile ID
$game_map.event_tiles[@id] = self
else
# Remove Events without Tile ID from small Hash
$game_map.event_tiles.delete(@id)
end
# If Event Not Erased
unless @erased
# If Page is not Nil (Page Conditions) and Page Change is occuring
if not @page.nil? and @page != page
# Reset to set again by Comment Conditions (@option = nil)
reset_page_comment_config
# For Performance on checking each Command in Page List when Refreshed
count = 0
# For each Event Command as 'command' in Page List of Event Commands
@page.list.each {|command|
# If Command Code is a Comment (Code 108, 408 is Next Line Code)
if command.code == 108
# Check Comment for Configuration Values and adjust Counter
count = check_page_comment_config(command.parameters[0], count)
end
# Increment Counter
count += 1
# Stop Iterating after Limit reached
break if comment_limit?(count)
} # End |command| loop (Event Command List)
end
end
end
end
# Version of Modular Passable for dependant scripts to check. DO NOT EDIT
$Modular_Passable = 1.0