#Patch snippit of Following Pokemon EX v2.2.4 by Gardenette
module FollowingPkmn
def self.can_talk?(interact = false)
return false if !FollowingPkmn.can_check?
return false if !$game_temp || $game_temp.in_battle || $game_temp.in_menu
return false if $PokemonGlobal.using_field_move == true
facing = pbFacingTile
if !FollowingPkmn.active? || !$game_map.passable?(facing[1], facing[2], $game_player.direction, $game_player)
if interact
$game_player.straighten
EventHandlers.trigger(:on_player_interact)
end
return false
end
return true
end
#edited by Gardenette to prevent followers from popping out on impassible tiles
def self.toggle(forced = nil, anim = nil)
return if !FollowingPkmn.can_check? || !FollowingPkmn.get
return if !FollowingPkmn.get_pokemon
anim_1 = FollowingPkmn.active?
if !forced.nil?
# This may seem redundant but it keeps follower_toggled a boolean always
$PokemonGlobal.follower_toggled = !(!forced)
else
$PokemonGlobal.follower_toggled = !($PokemonGlobal.follower_toggled)
end
#added by Gardenette
Game_FollowingPkmn.justCameOut if $PokemonGlobal.follower_toggled == true
anim_2 = FollowingPkmn.active?
anim = anim_1 != anim_2 if anim.nil?
FollowingPkmn.refresh(anim)
$game_temp.followers.move_followers
$game_temp.followers.turn_followers
end
end
class Game_FollowingPkmn < Game_Follower
#added by Gardenette
def self.justCameOut
@@justCameOut = true
end
#added by Gardenette
def tileWaterOrWaterfall?(x, y)
@map = $game_map
tileset = $data_tilesets[@map.tileset_id]
@terrain_tags = tileset.terrain_tags
#if the target tile is water and the pokemon cannot come out on water
[2, 1, 0].each do |i|
tile_id = $game_map.data[x, y, i]
next if tile_id == 0
terrain = GameData::TerrainTag.try_get(@terrain_tags[tile_id])
if terrain
if terrain.can_surf || terrain.waterfall
return true
else
return false
end #if terrain.can_surf || terrain.waterfall
end #if terrain
end #[2, 1, 0].each do |i|
end #def tileWaterOrWaterfall?(x, y)
def followerCanStepOnWater?
#if the pokemon is water or a flying follower
pkmn = FollowingPkmn.get_pokemon
return false if FollowingPkmn::SURFING_FOLLOWERS_EXCEPTIONS.any? do |s|
s == pkmn.species || s.to_s == "#{pkmn.species}_#{pkmn.form}"
end
return true if FollowingPkmn.airborne_follower?
return true if pkmn.hasType?(:WATER)
end
#edited by Gardenette to prevent followers from popping up on impassible objects
def follow_leader(leader, instant = false, leaderIsTrueLeader = true)
maps_connected = $map_factory.areConnected?(leader.map.map_id, self.map.map_id)
target = nil
if !defined?(@@justCameOut)
@@justCameOut = false
end
# Get the target tile that self wants to move to
if maps_connected
behind_direction = 10 - leader.direction
target = $map_factory.getFacingTile(behind_direction, leader)
if target && $map_factory.getTerrainTag(target[0], target[1], target[2]).ledge
# Get the tile above the ledge (where the leader jumped from)
target = $map_factory.getFacingTileFromPos(target[0], target[1], target[2], behind_direction)
end
target = [leader.map.map_id, leader.x, leader.y] if !target
if GameData::TerrainTag.exists?(:StairLeft)
currentTag = $map_factory.getTerrainTag(self.map.map_id, self.x, self.y)
if currentTag == :StairLeft
target[2] += (target[1] > $game_player.x ? -1 : 1)
elsif currentTag == :StairRight
target[2] += (target[1] < $game_player.x ? -1 : 1)
end
end
# Added
if defined?(on_stair?) && on_stair?
if leader.on_stair?
if leader.stair_start_x != self.stair_start_x
# Leader stepped on other side so start/end swapped, but not for follower yet
target[2] = self.y
elsif leader.stair_start_x < leader.stair_end_x
# Left to Right
if leader.x < leader.stair_start_x && self.x != self.stair_start_x
# Leader stepped off
target[2] = self.y
end
elsif leader.stair_end_x < leader.stair_start_x
# Right to Left
if leader.x > leader.stair_start_x && self.x != self.stair_start_x
# Leader stepped off
target[2] = self.y
end
end
elsif self.on_middle_of_stair?
# Leader is no longer on stair but follower is, so player moved up or down at the start or end of the stair
if leader.y < self.stair_end_y - self.stair_y_height + 1 || leader.y > self.stair_end_y
target[2] = self.y
end
end
end
else
# Map transfer to an unconnected map
target = [leader.map.map_id, leader.x, leader.y]
end
if @@justCameOut == true
if !location_passable?(target[1],target[2], behind_direction) || tileWaterOrWaterfall?(target[1],target[2])
i = 1
4.times do
#2=down, 4=left, 6=right, 8=up
#behind_direction = 10 - leader.direction
target = $map_factory.getFacingTile(i*2, leader)
#def location_passable?(x, y, direction)
if location_passable?(target[1],target[2], behind_direction) && !tileWaterOrWaterfall?(target[1],target[2])
#if the direction is passable, don't bother checking other directions
break
end
i += 1
end #4.times do
if !location_passable?(target[1],target[2], behind_direction) || tileWaterOrWaterfall?(target[1],target[2])
#if the pokemon is water or a flying follower
if followerCanStepOnWater?
#can pop out on the water
else
@@justCameOut = false
FollowingPkmn.toggle
end
end
end #if !passable?
@@justCameOut = false
end #if @@justCameOut == true
# Move self to the target
if self.map.map_id != target[0]
vector = $map_factory.getRelativePos(target[0], 0, 0, self.map.map_id, @x, @y)
@map = $map_factory.getMap(target[0])
# NOTE: Can't use moveto because vector is outside the boundaries of the
# map, and moveto doesn't allow setting invalid coordinates.
@x = vector[0]
@y = vector[1]
@real_x = @x * Game_Map::REAL_RES_X
@real_y = @y * Game_Map::REAL_RES_Y
end
if instant || !maps_connected
moveto(target[1], target[2])
else
fancy_moveto(target[1], target[2], leader)
end
end
#-----------------------------------------------------------------------------
end
class PokemonGlobalMetadata
# Added to see if a pokemon is using a field move
attr_accessor :using_field_move
end
#added here by Gardenette from Game_Map
def playerPassable?(x, y, d, self_event = nil)
map = $game_map
tileset = $data_tilesets[map.tileset_id]
terrain_tags = tileset.terrain_tags
passages = tileset.passages
priorities = tileset.priorities
bit = (1 << ((d / 2) - 1)) & 0x0f
[2, 1, 0].each do |i|
tile_id = $game_map.data[x, y, i]
next if tile_id == 0
terrain = GameData::TerrainTag.try_get(terrain_tags[tile_id])
passage = passages[tile_id]
if terrain
# Ignore bridge tiles if not on a bridge
next if terrain.bridge && $PokemonGlobal.bridge == 0
# Make water tiles passable if player is surfing
return true if $PokemonGlobal.surfing && terrain.can_surf && !terrain.waterfall
# Prevent cycling in really tall grass/on ice
return false if $PokemonGlobal.bicycle && terrain.must_walk
# Depend on passability of bridge tile if on bridge
if terrain.bridge && $PokemonGlobal.bridge > 0
return (passage & bit == 0 && passage & 0x0f != 0x0f)
end
end
next if terrain&.ignore_passability
# Regular passability checks
return false if passage & bit != 0 || passage & 0x0f == 0x0f
return true if priorities[tile_id] == 0
end
return true
end
def pbHiddenMoveAnimation(pokemon, no_field_move = false)
no_field_move = no_field_move || $game_temp.no_follower_field_move
ret = __followingpkmn__pbHiddenMoveAnimation(pokemon)
return ret if !ret || no_field_move || !FollowingPkmn.active? || pokemon != FollowingPkmn.get_pokemon
#added by Gardenette
$PokemonGlobal.using_field_move = true
pbTurnTowardEvent(FollowingPkmn.get_event, $game_player)
pbWait(Graphics.frame_rate / 5)
FollowingPkmn.move_route([PBMoveRoute::Forward])
initialDir = $game_player.direction
movedDir = 0
case $game_player.direction
when 2
#player is facing down
#try going up
if playerPassable?($game_player.x, $game_player.y-1, 8) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Up], true)
movedDir = 8
pbMoveRoute($game_player, [PBMoveRoute::TurnDown], true)
end
#try going left
if playerPassable?($game_player.x-1, $game_player.y, 4) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Left], true)
movedDir = 4
pbMoveRoute($game_player, [PBMoveRoute::TurnRight], true)
end
#try going right
if playerPassable?($game_player.x+1, $game_player.y, 6) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Right], true)
movedDir = 6
pbMoveRoute($game_player, [PBMoveRoute::TurnLeft], true)
end
when 4
#player is facing left
#try going right
if playerPassable?($game_player.x+1, $game_player.y, 6) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Right], true)
movedDir = 6
pbMoveRoute($game_player, [PBMoveRoute::TurnLeft], true)
end
#try going down
if playerPassable?($game_player.x, $game_player.y+1, 2) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Down], true)
movedDir = 2
pbMoveRoute($game_player, [PBMoveRoute::TurnUp], true)
end
#try going up
if playerPassable?($game_player.x, $game_player.y-1, 8) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Up], true)
movedDir = 8
pbMoveRoute($game_player, [PBMoveRoute::TurnDown], true)
end
when 6
#player is facing right
#try going left
if playerPassable?($game_player.x-1, $game_player.y, 4) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Left], true)
movedDir = 4
pbMoveRoute($game_player, [PBMoveRoute::TurnRight], true)
end
#try going down
if playerPassable?($game_player.x, $game_player.y+1, 2) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Down], true)
movedDir = 2
pbMoveRoute($game_player, [PBMoveRoute::TurnUp], true)
end
#try going right
if playerPassable?($game_player.x+1, $game_player.y, 6) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Right], true)
movedDir = 6
pbMoveRoute($game_player, [PBMoveRoute::TurnLeft], true)
end
#try going up
if playerPassable?($game_player.x, $game_player.y-1, 8) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Up], true)
movedDir = 8
pbMoveRoute($game_player, [PBMoveRoute::TurnDown], true)
end
when 8
#player is facing up
#try going down
if playerPassable?($game_player.x, $game_player.y+1, 2) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Down], true)
movedDir = 2
pbMoveRoute($game_player, [PBMoveRoute::TurnUp], true)
end
#try going left
if playerPassable?($game_player.x-1, $game_player.y, 4) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Left], true)
movedDir = 4
pbMoveRoute($game_player, [PBMoveRoute::TurnRight], true)
end
#try going right
if playerPassable?($game_player.x+1, $game_player.y, 6) && movedDir <= 0
pbMoveRoute($game_player, [PBMoveRoute::Right], true)
movedDir = 6
pbMoveRoute($game_player, [PBMoveRoute::TurnLeft], true)
end
end #case $game_player.direction
pbWait(Graphics.frame_rate / 5)
pbTurnTowardEvent($game_player, FollowingPkmn.get_event)
pbWait(Graphics.frame_rate / 5)
case initialDir
when 2
#player's initial direction was down
FollowingPkmn.move_route([PBMoveRoute::TurnDown])
when 4
#player's initial direction was left
FollowingPkmn.move_route([PBMoveRoute::TurnLeft])
when 6
#player's initial direction was right
FollowingPkmn.move_route([PBMoveRoute::TurnRight])
when 8
#player's initial direction was up
FollowingPkmn.move_route([PBMoveRoute::TurnUp])
end
pbWait(Graphics.frame_rate / 5)
case movedDir
when 2
#player moved down
pbMoveRoute($game_player, [PBMoveRoute::TurnUp], true)
when 4
#player moved left
pbMoveRoute($game_player, [PBMoveRoute::TurnRight], true)
when 6
#player moved right
pbMoveRoute($game_player, [PBMoveRoute::TurnLeft], true)
when 8
#player moved up
pbMoveRoute($game_player, [PBMoveRoute::TurnDown], true)
end
pbSEPlay("Player jump")
FollowingPkmn.move_route([PBMoveRoute::Jump, 0, 0])
pbWait(Graphics.frame_rate / 5)
#added by Gardenette
$PokemonGlobal.using_field_move = false
return ret
end