By default, on RPG maker XP there are two types of cliffs, tall and short ones.
Their passability and priority is different:
- On tall cliffs you CAN'T reach the edge, but you CAN walk below it.
- On short cliffs you CAN reach the edge, but you CAN'T walk below it.
This script allows to get the best of both cases on a single cliff type, so you CAN reach the edge and CAN walk below it; it basically acts one way or another based on where you got from.
Spoiler: Screen
[/quote]
I must say it's not the most intuitive script, but maybe in a future I will also release a configuration helper. For now the instructions are on the script, and if anyone has doubts about it, don't hesitate to ask them here. Sadly it also isn't the most compatible script ever, it overwrites some methods of both Game_Character and Game_Event, so have that in mind.
This script is also compatible with Extended Map Sprite Tiles & Autotiles (EMSTA). The script doesn't require it, but I recommend using both because it helps on the most complex cases.
Author: Wecoc
First Release: October 2018
Last Version: November 2018
Terms of use
- Giving credits (Wecoc) for using this script is optional, but appreciated.
- You can repost this code.
- You can edit this code freely, and distribute the edits as well.
- This code can be used on commercial games.
Instructions
On the database you must define those tiles as if they were tall cliffs. Each tileset supports as many cliffs as you want.
Then you must include those tile IDs on TOP_TILES and CORNER_TILES (see instructions on the script for more details).
Spoiler: How to get the tile ID[quote]By default, the tile on the top-left has ID = 0. The script has an option to include autotiles (non-recommended), therefore tha tile would have ID = 384 instead. Then it increases by one and there are 8 in each row, so a tile with coordinates X=7, Y=3 on the tileset will be 0 + 8*3 + 7 = 31. If you're using WecTools or MENTOR they have options to easily get the tile ID as well.
Each tile type uses a distinct letter on the configuration:
There are also some constants con the configuration (see instructions on the script).
Script calls
In case you define an event on a map coordinate that has a cliff tile, it may be ambiguous to where should it appear, on top or below the cliff. By default it will appear below, but you can change that with this script call: $game_map.events[ID].top_mode = true
You can't interact with an event that isn't on the same altitude as the player by default, even if it's in front of it by coordinate. To fix that (for example a flying event) use both the script call to send it on top and this one: $game_map.events[ID].passable_touch = true
Code
Ruby:
#==============================================================================# ** [XP] Cliff Bugfix v1.1#------------------------------------------------------------------------------# Author: Wecoc (credits are optional but appreciated)#==============================================================================# By default RPG maker XP has a little problem, the top of the cliffs can be# either over or under the player, but not both. This script solves that issue.# Also it goes further and fixes it for events so you can't interact with them# from above or from below, you must be on the same altitude.# This script is a bit complicated in some cases so it's not for newbies.#------------------------------------------------------------------------------# I recommend using it with Extended Map Sprite Tiles & Autotiles (EMSTA)# The script doesn't require it but it helps solving some more complex cases# between cliffs of distint altitude.#==============================================================================# ** Configuration#==============================================================================# On the database the cliff tiles must be defined as a default tall cliff, the# script will read it like a short cliff when you're on top.# You must configurate the CliffTop module, on the very start of the code.#------------------------------------------------------------------------------# TOP_TILES defines the tiles than can be either above or below the player.# You define them using Tileset ID => [tiles]# Each object on that list is an array with [Tile ID, Position]# * Tileset ID - The number of the tileset on the database list# * Tile ID - Tile index inside the tileset. You can count it manually or# using tools to get it, for example WecTools or MENTOR.# * Position: 'L': Left, 'C': Center, 'R': Right#------------------------------------------------------------------------------# CORNER_TILES defines the tiles that correspond to the superior corners# of the cliff. It's defined the same way as in TOP_TILES, except# * Position: 'CL': (Corner)Left, 'CR': (Corner)Right#------------------------------------------------------------------------------# INCLUDE_AUTOTILES defines if on Tile IDs defined previously you should# include autotiles. In that case you will have to add 384 to their value.#------------------------------------------------------------------------------# PASSABLE_TRIGGER_FIX doesn't allow interaction with events that aren't on# the same altitude as the player.#------------------------------------------------------------------------------# MULTICOUNTER_FIX is a little bugfix on the Counter option in the Database.# It allows to interact with events even if more that one counter tile# separates them.#==============================================================================# ** Script calls#==============================================================================# If you create an event on a map coordinate that contains a cliff tile, it# will be created below the cliff by default. You can send it on top using# this from another event on Parallel Process:# $game_map.events[ID].top_mode = true## Change 'ID' to the Event ID you want to move. If there's more than one, you# can change them all from the same event.#==============================================================================#==============================================================================# ** CliffTop#==============================================================================module CliffTop #---------------------------------------------------------------------------- # Configuration #---------------------------------------------------------------------------- TOP_TILES = {} CORNER_TILES = {} INCLUDE_AUTOTILES = false #---------------------------------------------------------------------------- # 004: Mountain TOP_TILES[4] = [[40,'L'], [41,'C'], [42,'R'], [29,'L'], [30,'C'], [31,'R']] CORNER_TILES[4] = [[43,'CL'], [44,'CR'], [67,'CL'], [68,'CR']] # 005: Beach TOP_TILES[5] = [[24,'L'], [25,'C'], [26,'R'], [29,'L'], [30,'C'], [31,'R']] CORNER_TILES[5] = [[27,'CL'], [28,'CR'], [51,'CL'], [52,'CR']] # 006: Desert TOP_TILES[6] = [[40,'L'], [41,'C'], [42,'R'], [45,'L'], [46,'C'], [47,'R']] CORNER_TILES[6] = [[43,'CL'], [44,'CR'], [67,'CL'], [68,'CR']] # 008: Showfield TOP_TILES[8] = [[48,'L'], [49,'C'], [50,'R'], [37,'L'], [38,'C'], [39,'R']] CORNER_TILES[8] = [[51,'CL'], [52,'CR'], [75,'CL'], [76,'CR']] # 017: MineTown TOP_TILES[17] = [[49,'L'], [50,'C'], [51,'R']] CORNER_TILES[17] = [[52,'CL'], [53,'CR']] # 019: DesertTown TOP_TILES[19] = [[40,'L'], [41,'C'], [42,'R']] CORNER_TILES[19] = [[43,'CL'], [44,'CR']] # 023: FarmVillage TOP_TILES[23] = [[64,'L'], [65,'C'], [66,'R'], [69,'L'], [70,'C'], [71,'R']] CORNER_TILES[23] = [[67,'CL'], [68,'CR'], [91,'CL'], [92,'CR']] # 032: Heaven TOP_TILES[32] = [[16,'L'], [17,'C'], [18,'R'], [21,'L'], [22,'C'], [23,'R']] CORNER_TILES[32] = [[35,'CL'], [36,'CR'], [19,'CL'], [20,'CR']] # 034: Bridge TOP_TILES[34] = [[16,'L'], [17,'C'], [18,'R']] CORNER_TILES[34] = [[19,'CL'], [20,'CR']] # 037: Fort TOP_TILES[37] = [[24,'L'], [25,'C'], [26,'R']] CORNER_TILES[37] = [[27,'CL'], [28,'CR']] # 039: Tower TOP_TILES[39] = [[16,'L'], [17,'C'], [18,'R']] CORNER_TILES[39] = [[19,'CL'], [20,'CR']] # 041: EvilCastle TOP_TILES[41] = [[32,'L'], [33,'C'], [34,'R'], [37,'L'], [38,'C'], [39,'R']] CORNER_TILES[41] = [[35,'CL'], [36,'CR'], [59,'CL'], [60,'CR']] # 042: EvilCastle (interior) TOP_TILES[42] = [[21,'L'], [22,'C'], [23,'R']] CORNER_TILES[42] = [[35,'CL'], [36,'CR']] # 043: Cave TOP_TILES[43] = [[37,'L'], [38,'C'], [39,'R']] CORNER_TILES[43] = [[59,'CL'], [60,'CR'], [67,'CL'], [68,'CR']] # 044: Cave 2 TOP_TILES[44] = [[37,'L'], [38,'C'], [39,'R']] CORNER_TILES[44] = [[59,'CL'], [60,'CR'], [67,'CL'], [68,'CR']] # 045: Cave 3 TOP_TILES[45] = [[37,'L'], [38,'C'], [39,'R']] CORNER_TILES[45] = [[59,'CL'], [60,'CR'], [67,'CL'], [68,'CR']] # 046: Cave 4 TOP_TILES[46] = [[37,'L'], [38,'C'], [39,'R']] CORNER_TILES[46] = [[59,'CL'], [60,'CR'], [67,'CL'], [68,'CR']] # 047: Mine TOP_TILES[47] = [[21,'L'], [22,'C'], [23,'R']] CORNER_TILES[47] = [[35,'CL'], [36,'CR']] # 049: InnerBody TOP_TILES[49] = [[45,'L'], [46,'C'], [47,'R']] CORNER_TILES[49] = [[67,'CL'], [68,'CR']] # 050: DarkSpace TOP_TILES[50] = [[53,'L'], [54,'C'], [55,'R'], [48,'L'], [49,'C'], [50,'R']] CORNER_TILES[50] = [[28,'CL'], [29,'CR'], [51,'CL'], [52,'CR']] #---------------------------------------------------------------------------- PASSABLE_TRIGGER_FIX = true MULTICOUNTER_FIX = true #---------------------------------------------------------------------------- TOP_TILES.default = [] # Don't chage CORNER_TILES.default = [] # Don't chageend#==============================================================================# ** Tile_Passage [Scripter's Tool]#==============================================================================class Tile_Passage attr_accessor :bit def initialize(bit) @bit = bit @square = bit & 0x10 @ladder = bit & 0x20 # Unused @bush = bit & 0x40 @counter = bit & 0x80 @passage = bit - @square - @ladder - @bush - @counter end def passage=(passage) @passage = passage @bit = @passage + @square + @ladder + @bush + @counter endend#==============================================================================# ** Game_Map#==============================================================================class Game_Map #---------------------------------------------------------------------------- # * Get the current tileset ID #---------------------------------------------------------------------------- def tileset_id return @map.tileset_id end #---------------------------------------------------------------------------- # * Get the tiles on a given a coordinate #---------------------------------------------------------------------------- def get_tiles(x, y) return [data[x, y, 0], data[x, y, 1], data[x, y, 2]] end #---------------------------------------------------------------------------- # * Get the passages on a given coordinate #---------------------------------------------------------------------------- def map_flag_passages(x, y) t = get_tiles(x, y) return [@passages[t[0]], @passages[t[1]], @passages[t[2]]] end #---------------------------------------------------------------------------- # * Get the priorities on a given coordinate #---------------------------------------------------------------------------- def map_flag_priorities(x, y) t = get_tiles(x, y) return [@priorities[t[0]], @priorities[t[1]], @priorities[t[2]]] end #---------------------------------------------------------------------------- # * Check passability given passable and priority data #---------------------------------------------------------------------------- def flag_passable?(passable_array, priority_array, d) bit = (1 << (d / 2 - 1)) & 0x0f for i in [2, 1, 0] passage = passable_array priority = priority_array if passage & bit != 0 return false elsif passage & 0x0f == 0x0f return false elsif priority == 0 return true end end return true endend#==============================================================================# ** Game_Character#==============================================================================class Game_Character #---------------------------------------------------------------------------- attr_accessor :top_mode, :top_mode_temp_move, :top_mode_temp_stop attr_accessor :top_emsta_tiles attr_accessor :passable_touch attr_reader :move_count #---------------------------------------------------------------------------- unless $@ alias top_mode_ini initialize alias top_mode_screen_z screen_z alias top_mode_stop update_stop alias top_mode_move update_move end #---------------------------------------------------------------------------- # * Start #---------------------------------------------------------------------------- def initialize(*args) top_mode_ini(*args) @top_mode = false @top_mode_temp_move = false @top_mode_temp_stop = false @top_emsta_tiles = [] @move_count = 0 @passable_touch = false end #---------------------------------------------------------------------------- # * Get character width #---------------------------------------------------------------------------- def character_width return 32 if @tile_id > 0 return 0 if @character_name == "" return RPG::Cache.character(@character_name, 0).width / 4 end #---------------------------------------------------------------------------- # * Get character height #---------------------------------------------------------------------------- def character_height return 32 if @tile_id > 0 return 0 if @character_name == "" return RPG::Cache.character(@character_name, 0).height / 4 end #---------------------------------------------------------------------------- # * Get event Z #---------------------------------------------------------------------------- def screen_z(*args) result = top_mode_screen_z(*args) if @top_mode || @top_mode_temp_move || @top_mode_temp_stop if self.character_height <= 32 result += 32 else result += 1 end end return result end #---------------------------------------------------------------------------- # * Update event (stop) #---------------------------------------------------------------------------- def update_stop top_mode_stop @move_count = 0 @top_mode_temp_stop = false end #---------------------------------------------------------------------------- # * Update event (move) #---------------------------------------------------------------------------- def update_move top_mode_move if @move_count > 0 @top_mode_temp_move = false if (@real_x / 4) % 32 == 0 && (@real_y / 4) % 32 == 0 if @top_emsta_tiles.size > 0 for tile in @top_emsta_tiles $game_map.sprite_tiles.delete($game_map.sprite_tiles.key(tile)) end end @top_mode_temp_stop = false end end @move_count += 1 end #---------------------------------------------------------------------------- # * Move down #---------------------------------------------------------------------------- def move_down(turn_enabled = true) turn_down if turn_enabled if passable?(@x, @y, 2) if @top_mode == true && @always_on_top == false current_tiles = $game_map.get_tiles(@x, @y) target_tiles = $game_map.get_tiles(@x, @y + 1) move_v_set_top_(current_tiles, target_tiles) if @top_mode == false @top_mode_temp_move = true end end turn_down @y += 1 increase_steps else check_event_trigger_touch(@x, @y+1) end end #---------------------------------------------------------------------------- # * Move left #---------------------------------------------------------------------------- def move_left(turn_enabled = true) turn_left if turn_enabled if passable?(@x, @y, 4) if @always_on_top == false current_tiles = $game_map.get_tiles(@x, @y) target_tiles = $game_map.get_tiles(@x - 1, @y) move_h_set_top_(current_tiles, target_tiles) end turn_left @x -= 1 increase_steps else check_event_trigger_touch(@x-1, @y) end end #---------------------------------------------------------------------------- # * Move right #---------------------------------------------------------------------------- def move_right(turn_enabled = true) turn_right if turn_enabled if passable?(@x, @y, 6) if @always_on_top == false current_tiles = $game_map.get_tiles(@x, @y) target_tiles = $game_map.get_tiles(@x + 1, @y) move_h_set_top_(current_tiles, target_tiles) end turn_right @x += 1 increase_steps else check_event_trigger_touch(@x+1, @y) end end #---------------------------------------------------------------------------- # * Move up #---------------------------------------------------------------------------- def move_up(turn_enabled = true) turn_up if turn_enabled if passable?(@x, @y, 8) if @top_mode == false && @always_on_top == false current_tiles = $game_map.get_tiles(@x, @y) target_tiles = $game_map.get_tiles(@x, @y - 1) move_v_set_top_(current_tiles, target_tiles) end turn_up @y -= 1 increase_steps else check_event_trigger_touch(@x, @y-1) end end #---------------------------------------------------------------------------- # * Check passability #---------------------------------------------------------------------------- def passable?(x, y, d) new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0) new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0) # Check if the new coordinate is still on the map return false unless $game_map.valid?(new_x, new_y) # Check if the event has the through flag activated return true if @through # Check if it can move from the current tile passages, priorities = *passable_get_current_tile_(x, y, new_x, new_y, d) return false unless $game_map.flag_passable?(passages, priorities, d) # Check if it can move to the new tile passages, priorities = *passable_get_target_tile_(x, y, new_x, new_y, d) return false unless $game_map.flag_passable?(passages, priorities, 10 - d) # Check if there's any event on the new tile return false if passable_events_(x, y, new_x, new_y, d) == false return true end #---------------------------------------------------------------------------- # * Check if the event is over bush #---------------------------------------------------------------------------- def bush_mode return false if @tile_id > 0 or @always_on_top return false if @jump_count > 0 # Tile bush for i in [2, 1, 0] next if @top_mode and i == 0 tile_id = $game_map.data[@x, @y, i] return true if $game_map.passages[tile_id] & 0x40 == 0x40 end # Event bush for event in $game_map.events.values next if event == self if event.x == @x && event.y == @y if event.tile_id > 0 next if @top_mode != event.top_mode return true if $game_map.passages[event.tile_id] & 0x40 == 0x40 end end end return false end #---------------------------------------------------------------------------- # * Get the bush height #---------------------------------------------------------------------------- def bush_depth if bush_mode return 12 else return 0 end end #---------------------------------------------------------------------------- # * [Private] Get if the player is moving on top/below the cliff (vertical) #---------------------------------------------------------------------------- def move_v_set_top_(current_tiles, target_tiles) top_tiles = CliffTop::TOP_TILES[$game_map.tileset_id].clone top_tiles.collect! {|t| t[0] } if CliffTop::INCLUDE_AUTOTILES == false top_tiles.map! {|t| t + 384 } end @top_mode = false if @direction == 2 for tile in current_tiles return if top_tiles.include?(tile) end end for tile in target_tiles @top_mode = true if top_tiles.include?(tile) end end #---------------------------------------------------------------------------- # * [Private] Get if the player is moving on top/below the cliff (horizontal) #---------------------------------------------------------------------------- def move_h_set_top_(current_tiles, target_tiles) top_tiles = CliffTop::TOP_TILES[$game_map.tileset_id].clone corner_tiles = CliffTop::CORNER_TILES[$game_map.tileset_id].clone top_tiles.collect! {|t| t[0] } corner_tiles_cr = corner_tiles.select{|t| t[1] == 'CR'} corner_tiles_cl = corner_tiles.select{|t| t[1] == 'CL'} corner_tiles_cr.collect! {|t| t[0] } corner_tiles_cl.collect! {|t| t[0] } if CliffTop::INCLUDE_AUTOTILES == false top_tiles.map! {|t| t + 384 } corner_tiles_cr.map! {|t| t + 384 } corner_tiles_cl.map! {|t| t + 384 } end if @top_mode == false from_top = false if @direction == 4 for tile in current_tiles if corner_tiles_cl.include?(tile) from_top = true end end end if @direction == 6 for tile in current_tiles if corner_tiles_cr.include?(tile) from_top = true end end end if from_top == true for tile in target_tiles if top_tiles.include?(tile) @top_mode = true end end end if @top_mode == true if $game_map.respond_to?(:set_sprite_tile) for tile in current_tiles if top_tiles.include?(tile) move_top_emsta_exit_(tile) end end end end else stay_in_top = false for tile in target_tiles if top_tiles.include?(tile) stay_in_top = true end end if stay_in_top if @direction == 4 for tile in target_tiles if corner_tiles_cr.include?(tile) stay_in_top = false end end end if @direction == 6 for tile in target_tiles if corner_tiles_cl.include?(tile) stay_in_top = false end end end if stay_in_top == false if $game_map.respond_to?(:set_sprite_tile) for tile in target_tiles if top_tiles.include?(tile) move_top_emsta_enter_(tile) end end end end end if stay_in_top == false @top_mode = false @top_mode_temp_stop = true end end end #---------------------------------------------------------------------------- # * [Private] Draw EMSTA when entering on a conflitive event Corner + Cliff #---------------------------------------------------------------------------- def move_top_emsta_enter_(tile) d = @direction new_x = @x + (d == 6 ? 1 : d == 4 ? -1 : 0) new_y = @y + (d == 2 ? 1 : d == 8 ? -1 : 0) $game_map.set_sprite_tile(new_x, new_y, tile) sprite = $game_map.sprite_tiles.values.select do |t| t[0] == new_x && t[1] == new_y && t[3] == tile end[0] sprite[4] = 1 @top_emsta_tiles.push(sprite) end #---------------------------------------------------------------------------- # * [Private] Draw EMSTA when exiting a conflictive event Corner + Cliff #---------------------------------------------------------------------------- def move_top_emsta_exit_(tile) $game_map.set_sprite_tile(@x, @y, tile) sprite = $game_map.sprite_tiles.values.select do |t| t[0] == @x && t[1] == @y && t[3] == tile end[0] sprite[4] = 1 @top_emsta_tiles.push(sprite) end #---------------------------------------------------------------------------- # * [Private] Get passage and priority flags of the current tile #---------------------------------------------------------------------------- def passable_get_current_tile_(x, y, new_x, new_y, d) passages = $game_map.map_flag_passages(x, y) priorities = $game_map.map_flag_priorities(x, y) current_tiles = $game_map.get_tiles(x, y) top_tiles = CliffTop::TOP_TILES[$game_map.tileset_id].clone corner_tiles = CliffTop::CORNER_TILES[$game_map.tileset_id].clone if CliffTop::INCLUDE_AUTOTILES == false current_tiles.map! {|t| t - 384 } end if @top_mode == true for i in 0...current_tiles.size tile = current_tiles check_top = top_tiles.select{|t| t[0] == tile}[0] if !check_top.nil? priorities = 0 bit_data = Tile_Passage.new(passages) case check_top[1] when 'L' bit_data.passage = 0x0A when 'C' bit_data.passage = 0x08 when 'R' bit_data.passage = 0x0C end passages = bit_data.bit end end else for i in 0...current_tiles.size tile = current_tiles check_top = corner_tiles.select{|t| t[0] == tile}[0] if !check_top.nil? bit_data = Tile_Passage.new(passages) case check_top[1] when 'CL', 'CR' bit_data.passage = 0x00 end passages = bit_data.bit end end end return [passages, priorities] end #---------------------------------------------------------------------------- # * [Private] Get passage and priority flags of the new tile #---------------------------------------------------------------------------- def passable_get_target_tile_(x, y, new_x, new_y, d) passages = $game_map.map_flag_passages(new_x, new_y) priorities = $game_map.map_flag_priorities(new_x, new_y) from_top = false current_tiles = $game_map.get_tiles(x, y) corner_tiles = CliffTop::CORNER_TILES[$game_map.tileset_id].clone corner_tiles_cr = corner_tiles.select{|t| t[1] == 'CR'} corner_tiles_cl = corner_tiles.select{|t| t[1] == 'CL'} corner_tiles_cr.collect! {|t| t[0] } corner_tiles_cl.collect! {|t| t[0] } if CliffTop::INCLUDE_AUTOTILES == false corner_tiles_cr.map! {|t| t + 384 } corner_tiles_cl.map! {|t| t + 384 } end if d == 2 || d == 8 for tile in current_tiles from_top = true if corner_tiles_cr.include?(tile) from_top = true if corner_tiles_cl.include?(tile) end end if d == 4 for tile in current_tiles from_top = true if corner_tiles_cl.include?(tile) end end if d == 6 for tile in current_tiles from_top = true if corner_tiles_cr.include?(tile) end end target_tiles = $game_map.get_tiles(new_x, new_y) top_tiles = CliffTop::TOP_TILES[$game_map.tileset_id].clone corner_tiles = CliffTop::CORNER_TILES[$game_map.tileset_id].clone if CliffTop::INCLUDE_AUTOTILES == false target_tiles.map! {|t| t - 384 } end if @top_mode == false if (d == 8 || from_top == true) for i in 0...target_tiles.size tile = target_tiles check_top = top_tiles.select{|t| t[0] == tile}[0] if !check_top.nil? priorities = 0 bit_data = Tile_Passage.new(passages) case check_top[1] when 'L' bit_data.passage = 0x0A when 'C' bit_data.passage = 0x08 when 'R' bit_data.passage = 0x0C end passages = bit_data.bit end end end else for i in 0...target_tiles.size tile = target_tiles check_top = corner_tiles.select{|t| t[0] == tile}[0] if !check_top.nil? bit_data = Tile_Passage.new(passages) case check_top[1] when 'CL', 'CR' bit_data.passage = 0x00 end passages = bit_data.bit end end end return [passages, priorities] end #---------------------------------------------------------------------------- # * [Private] Get passable flag by event #---------------------------------------------------------------------------- def passable_events_(x, y, new_x, new_y, d) current_from_top = false target_from_top = false current_tiles = $game_map.get_tiles(x, y) target_tiles = $game_map.get_tiles(new_x, new_y) top_tiles = CliffTop::TOP_TILES[$game_map.tileset_id].clone corner_tiles = CliffTop::CORNER_TILES[$game_map.tileset_id].clone top_tiles.collect! {|t| t[0] } corner_tiles.collect! {|t| t[0] } if CliffTop::INCLUDE_AUTOTILES == false top_tiles.map! {|t| t + 384 } corner_tiles.map! {|t| t + 384 } end for tile in current_tiles current_from_top = true if corner_tiles.include?(tile) end for tile in target_tiles target_from_top = true if corner_tiles.include?(tile) end for event in $game_map.events.values if event.x == new_x and event.y == new_y next if self == event next if event.through next if event.character_name == "" && event.tile_id == 0 self_from_top = current_from_top event_from_top = target_from_top self_from_top = true if self.top_mode event_from_top = true if event.top_mode same_height = (self_from_top == event_from_top) same_height = true if d == 8 && (!self_from_top && event_from_top) same_height = true if d == 2 && (self_from_top && !event_from_top) if d == 8 && (!self_from_top && !event_from_top) for tile in target_tiles self_from_top = true if top_tiles.include?(tile) end same_height = false if self_from_top end if same_height return false if event.tile_id == 0 bit = (1 << (d / 2 - 1)) & 0x0f return false if $game_map.passages[event.tile_id] & bit != 0 return false if $game_map.passages[event.tile_id] & 0x0f == 0x0f end end end if $game_player.x == new_x and $game_player.y == new_y next if self == $game_player next if $game_player.through or self.character_name == "" self_from_top = current_from_top player_from_top = target_from_top self_from_top = true if self.top_mode player_from_top = true if $game_player.top_mode same_height = (self_from_top == player_from_top) same_height = true if d == 8 && (!self_from_top && player_from_top) same_height = true if d == 2 && (self_from_top && !player_from_top) if d == 8 && (!self_from_top && !player_from_top) for tile in target_tiles self_from_top = true if top_tiles.include?(tile) end same_height = false if self_from_top end return false if same_height end return true endend#==============================================================================# ** Game_Event#==============================================================================class Game_Event < Game_Character #---------------------------------------------------------------------------- # * Check if the player if over the event #---------------------------------------------------------------------------- alias top_mode_over_trigger? over_trigger? unless $@ def over_trigger? return false if top_mode_over_trigger? == false return false if $game_player.top_mode != self.top_mode return true endend#==============================================================================# ** Game_Player#==============================================================================class Game_Player < Game_Character #-------------------------------------------------------------------------- # * Activate event when key trigger #-------------------------------------------------------------------------- def check_event_trigger_there(triggers) result = false return result if $game_system.map_interpreter.running? new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) d = @direction current_from_top = false target_from_top = false current_tiles = $game_map.get_tiles(@x, @y) target_tiles = $game_map.get_tiles(new_x, new_y) top_tiles = CliffTop::TOP_TILES[$game_map.tileset_id].clone corner_tiles = CliffTop::CORNER_TILES[$game_map.tileset_id].clone top_tiles.collect! {|t| t[0] } corner_tiles.collect! {|t| t[0] } if CliffTop::INCLUDE_AUTOTILES == false top_tiles.map! {|t| t + 384 } corner_tiles.map! {|t| t + 384 } end for tile in current_tiles current_from_top = true if corner_tiles.include?(tile) end for tile in target_tiles target_from_top = true if corner_tiles.include?(tile) end # Press C in front of the event for event in $game_map.events.values if event.x == new_x and event.y == new_y and triggers.include?(event.trigger) if not event.jumping? and not event.top_mode_over_trigger? if CliffTop::PASSABLE_TRIGGER_FIX && event.passable_touch == false passages, priorities = *passable_get_current_tile_(@x, @y, new_x, new_y, d) next if !$game_map.flag_passable?(passages, priorities, d) end self_from_top = current_from_top event_from_top = target_from_top self_from_top = true if self.top_mode event_from_top = true if event.top_mode same_height = (self_from_top == event_from_top) same_height = true if d == 8 && (!self_from_top && event_from_top) same_height = true if d == 2 && (self_from_top && !event_from_top) if d == 8 && (!self_from_top && !event_from_top) for tile in target_tiles self_from_top = true if top_tiles.include?(tile) end same_height = false if self_from_top end if same_height event.start result = true end end end end if result == false # Press C in front of the event (counter mode) if $game_map.counter?(new_x, new_y) if CliffTop::MULTICOUNTER_FIX loop do new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) break if !$game_map.counter?(new_x, new_y) end else new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0) new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0) end for event in $game_map.events.values if event.x == new_x and event.y == new_y and triggers.include?(event.trigger) if not event.jumping? and not event.over_trigger? event.start result = true end end end end end return result end #-------------------------------------------------------------------------- # * Activate event on touch #-------------------------------------------------------------------------- def check_event_trigger_touch(x, y) result = false d = @direction return result if $game_system.map_interpreter.running? for event in $game_map.events.values if event.x == x and event.y == y and [1,2].include?(event.trigger) if not event.jumping? and not event.over_trigger? if CliffTop::PASSABLE_TRIGGER_FIX && event.passable_touch == false passages, priorities = *passable_get_current_tile_(@x, @y, x, y, d) next if !$game_map.flag_passable?(passages, priorities, d) end event.start result = true end end end return result endend
Spoiler: Agreements
This code was made possible thanks to Silvanash, Ledai, Teivko, Eron, Orochii, AsFzKakarotto and schM0ggi.