• Do not use Discord to host any images you post, these links expire quickly! You can learn how to add images to your posts here.
Following Pokemon EX

Resource Following Pokemon EX 2.2.3

Gardenette

Cooltrainer
Member
Joined
May 30, 2022
Posts
156
First of all, whether it works or not does not embarrass you in any way. There is nothing more valuable than trying to deliver solutions that can serve the rest of the community. Thank you for that.

I installed the new version, compiled the whole project and the problem persists.

My initial position:

View attachment 17243

If I remove the Pokemon and take it out of the Pokeball staying in that position it works fine (obviously).

If instead I make the character look in another direction and do the same thing... This happens...

View attachment 17244

And if after that I look in the direction of the Pokemon and try again, the following happens...

View attachment 17245

PD: If I surround myself with 3 impassable tiles and for example, an event, the Pokemon still appears on any of them.

I'm baffled. I just can't replicate the issue even with butterfree. What other plugins do you have installed? I doubt you would have anything that messes with followers but still curious.
 

Attachments

  • screen-capture.webm
    1.5 MB

REALMUGEN

Trainer
Member
Joined
Jan 23, 2020
Posts
72
I'm baffled. I just can't replicate the issue even with butterfree. What other plugins do you have installed? I doubt you would have anything that messes with followers but still curious.
You are absolutely right, in a pure Essentials game it works perfectly.

It is difficult to know if any script is causing conflicts. I am going to investigate some that I use that manipulate the use of characters quite a bit. I will try to look scripts that have to do with class Game_Follower... Something must be generating the conflict.

I will report any news here.

EDIT: I just checked and the scripts I use that have to do with class Game_Follower are Mach and Acro Bike and Enhanced Staircases, I deactivated both but I don't notice any changes, I will keep looking.
 
Last edited:

SunriseStudios

Novice
Member
Joined
Aug 10, 2022
Posts
21
Is there a non-plugin version of the latest fix with only the code changed by you? I'd like to give it a try in my game, maybe I can find some dependencies with other scripts.
 

Gardenette

Cooltrainer
Member
Joined
May 30, 2022
Posts
156
Is there a non-plugin version of the latest fix with only the code changed by you? I'd like to give it a try in my game, maybe I can find some dependencies with other scripts.
The snippits I posted above where it's just the fix to the script and not the whole thing - don't use that because it's old. I will get you a snippet of the latest
 

Gardenette

Cooltrainer
Member
Joined
May 30, 2022
Posts
156
Is there a non-plugin version of the latest fix with only the code changed by you? I'd like to give it a try in my game, maybe I can find some dependencies with other scripts.
Here you go. If your Following Pokemon EX script is in the plugins folder, I don't know what will be compiled first - the original Following Pokemon EX plugin or this patch. But it should work fine if you put this in your in-game scripts below the original Following Pokemon EX.

Following Pokemon EX Patch v2.2.4 Snippit:
Expand Collapse Copy
#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
 

Golisopod User

Elite Trainer
Member
Joined
May 11, 2020
Posts
319
Golisopod User updated Following Pokemon EX with a new update entry:

Many Bugfixes

  • Fixed player sprite appearing on top of Following Pokemon sprite.
  • Fixed possibility of crash with one of the default "Music" emote dialogues.
  • Fixed "Heart" emote dialogues never playing.
  • Fixed "HideFollowingPkmn" map flag not doing anything.
  • Fixed crash in "Height-based" disappearing when loading onto an indoor map with encounters.
  • Fixed being able to talk to your Following Pokemon when in a move route, or while using an HM.
  • Fixed Animation issue with surfing and...

Read the rest of this update entry...
 

MR.Tectass

Rookie
Member
Joined
Jun 1, 2023
Posts
5
Hi i have a bug with Pokemon Follow i cant let pokemon like Gyarados from the Demoparty and Pokemon like Steelix follow me Overworld, also if i walk over some bridges that use the pbBridge.ON script it dosnt work as it should and dont turn on the Bridge, this dosnt change if i stop Pokemon to follow me. but if i dont use the Pokemon Follow script at all the pbBridge.ON file work like it should, also on some bridges it works like it should.
Also if i Use the Pokemon follow script on a map like the testmap route 2 that comes with Pokemon Essentials then Pokemon like Gyarados follow on world but all Pokemon that follows dosnt walk behind the player instead they move wildly arround the player while walking.
 

LinKazamine

Champion
Member
Joined
May 24, 2023
Posts
674
It sounds like an incompatibility with another plugin because I have Following Pokemon EX v2.2.3 installed and it works fine. The pokémon, including gyarados, all follow me around right behind the trainer and I can walk over and under the bridges without trouble.
 
Hi i have a bug with Pokemon Follow i cant let pokemon like Gyarados from the Demoparty and Pokemon like Steelix follow me Overworld,
This is normal behaviour. In the official games, Pokemon taller than 10ft in height don't follow the player in interior maps. This is done to prevent a 70ft tall Groudon from absolutely obliterating some poor dudes home, when you enter it. This script recreates that effect from those games. If these "larger Pokemon" aren't appearing in your outdoor maps as well, then that means that your map metadata is poorly set up and you need to correct it to add the "Outdoor" property to it. Here's the wiki link for how to set up your map metadata, please read it.
Also if i Use the Pokemon follow script on a map like the testmap route 2 that comes with Pokemon Essentials then Pokemon like Gyarados follow on world but all Pokemon that follows dosnt walk behind the player instead they move wildly arround the player while walking.
Do you actually mean move wildly around, or do you just mean that they follow slowly like this?

The comments include the solution.
 

MR.Tectass

Rookie
Member
Joined
Jun 1, 2023
Posts
5
Do you actually mean move wildly around, or do you just mean that they follow slowly like this?

The comments include the solution.

Hi idk how but the problem is solved, i also had a problem with 2 connected maps where an Bridge event i created dosnt worked with follow pokemon but the problem was it had the same ID (in my case 001) as the follow Pokemon event on the other map and so i just made a new event with a different ID wich solved this issue ^^
 

MR.Tectass

Rookie
Member
Joined
Jun 1, 2023
Posts
5
This is normal behaviour. In the official games, Pokemon taller than 10ft in height don't follow the player in interior maps. This is done to prevent a 70ft tall Groudon from absolutely obliterating some poor dudes home, when you enter it. This script recreates that effect from those games. If these "larger Pokemon" aren't appearing in your outdoor maps as well, then that means that your map metadata is poorly set up and you need to correct it to add the "Outdoor" property to it. Here's the wiki link for how to set up your map metadata, please read it.
Thank u <3 that helped a lot
 

REALMUGEN

Trainer
Member
Joined
Jan 23, 2020
Posts
72
I'm trying to update this to V.21. I managed to basically update some commands and durations since it's now FPS Agnostic, but there are still some things that don't quite work very well, for example, the follower position, and while most of the time it follows you, sometimes it locates itself in strange positions and doesn't quite respond well. I'm not well versed in scripting. So... Does anyone know what other elements might have changed from 20.1 to 21 that are worth experimenting with? :___)
 

Juno and Ice

Rookie
Member
Joined
Jun 14, 2018
Posts
9
I'm trying to update this to V.21. I managed to basically update some commands and durations since it's now FPS Agnostic, but there are still some things that don't quite work very well, for example, the follower position, and while most of the time it follows you, sometimes it locates itself in strange positions and doesn't quite respond well. I'm not well versed in scripting. So... Does anyone know what other elements might have changed from 20.1 to 21 that are worth experimenting with? :___)
How did you get to animating the follower? I'm also attempting to port this to v21.1 and I can get the follower to render, but the sprite is static and not animating as it should.
 

REALMUGEN

Trainer
Member
Joined
Jan 23, 2020
Posts
72
How did you get to animating the follower? I'm also attempting to port this to v21.1 and I can get the follower to render, but the sprite is static and not animating as it should.

In the script Following Event, on class Game_FollowingPkmn < Game_Follower, replace
Ruby:
Expand Collapse Copy
frames_per_pattern = Game_Map::REAL_RES_X / (512.0 / Graphics.frame_rate * 1.5)
with
Ruby:
Expand Collapse Copy
frames_per_pattern = Game_Map::REAL_RES_X / (512.0 / 0.5)
 

MrRetro

Veteran Gamer
Member
Joined
Feb 13, 2022
Posts
27
I still can't get it to work properly. It seems that we have to do a lot more to do it... : /
Yeah I had that issue even using your little snippets of code changes. I thought maybe you figured it out
 
Back
Top