Rayd12smitty
Shadow Maker
- 645
- Posts
- 13
- Years
- Seen Feb 21, 2016
Current Version: Version 1.3
If you use this script give credit to Help-14, zingzags, Rayd12smitty, and venom12
If you are updating from a previous version, replace the Following Pokemon script, and if you are updating from before Version 1.2, look down a bit there is a new part of code to replace in PokemonParty. Also you no longer need to manually turn on the switches for Activated_Following_Switch and Toggle_Following_Switch. They are now automatically included in "pbPokemonFollow(x)" This was updated in Version 1.2.
Intro
Adding Following Pokemon has been a real pain for anyone who doesn't have a decent amount of scripting experience. I want to change that :D I have spent the last few days reorganizing the Following Pokemon script that was previously updated by zingzags so it is easier to read, and works cleaner. I added quite a few nice features, and fixed some that were broken. venom12 is going to working with me to continue improving this feature. Here is my complete guide to installing Following Pokemon.
Quick Overview
Following Pokemon was a feature in HGSS in which the first Pokemon in your party would walk around with you in the Overworld. Quite a few years ago, Help-14 wrote a script to implement Following Pokemon in Pokemon Essentials. Then, more recently, zingzags posted an updated version of the script, along with basic instructions on how to implement it in your game. Now, I have once again updated the script adding more features and fixes. venom12 and I will most likely continue improving this script until it is as good as we can get it.
Features, from Help-14, zingzags, Rayd12smitty, venom12
Version 1.3
* Fixed bug with surf where the Follower could block the player from being able to surf, possibly stranding the player
* Added script to animate all events named "Poke"
* Increased time to find an item. I realize now that 5000 frames is less than 5 min. Way too short. Now it will take 12 and 1/2 min to find an item.
Older Versions
The Script
First add this in Settings. You can change the variables and switches used here. Make sure none of these switches/variables are being used in your game.
Next add this as a new Script Section called Following Pokemon. Put it above Main.
Next replace DependentEvents with this. Please note that having Pokemon Followers makes other followers not a good option. You can still have Trainers following and trainer partners, but they look weird. Adding more support for this in the future maybe.
In PokemonParty, add
directly after
Also in PokemonParty, replace pbPokemonGiveScreen(item) with this
In Game_Player_, add
directly after
In PokeBattle_ActualScene, replace pbEndBattle with
In PokemonField, add this above kernel.pbReceiveItem
In Scene_Map, after
add this. You can change (Input::X) and (Input::Z) to keys of your liking. These rotate the party/follower. If you don't want the player to be able to rotate their party/follower, skip this step.
In PokemonSystem, replace module input with this. You can change (CTRL) to a key of your liking. This will be the key that toggles following pokemon on and off. If you don't want the player to be able to toggle their Pokemon on and off, skip this step.
In Interpreter, replace def command_end with
Other Installations
In the Database click on the "Common Events" tab and go to the Common Event you have listed in settings from earlier. Name this common event "TalkToPokemon", with no Trigger, and in the event have the script
Make sure to use the ExtendText program in your game folder to make sure it fits on one line. I haven't tested if it needs to be on one line or not, but to be safe. To use ExtendText, have the text box to enter the script open, and then without closing anything, open up your game folder in "My Computer" and double click the program called ExtendText.
Next you need to download the following animations and put them in Graphics/Animations.
Then download the animations data and put it in your Data Folder. This will not mess up any attack animations added through the animation editor as attack animations don't use the Database anymore.
You will also need to find sprites for the Pokemon Followers. These can be found on google pretty easily. If anyone has a link and can post it here I will add it to this post. These sprites should be called 001,001s,002,002s,etc, etc, etc. They go in the Graphics/Characters folder. The "s" means shiny. We are still working on adding multiple forms support.
How to use the Script
Alright. So this is a lot of information to take in at once, especially if you have zero scripting knowledge. As long as you followed these instructions perfectly, and I haven't forgotten anything, your game should load without any errors. Now, to call the script use:
where "x" is the EVENT ID of the event that will become the follower. I cannot stress this enough. Many people see this and think "x" is the number of pokemon that will follow the player. This script supports a SINGLE follower. The "x" is the EVENT ID.
Note that the event that becomes the follower will no longer function as it should. You should use a blank event called "Dependent" for the follower, and have the script activated through a different event.
Whenever there is a Pokemon healing event, put
to remove the follower, and
to put the sprite back. The first script should be called when Nurse Joy/Healer takes your Pokemon, and the second one should be called when the Pokemon are given back. Make sure to put these in conditional branches in the event so they only run when $game_switches[Toggle_Following_Switch]==true. Otherwise the animations will play and the script will get confused and the toggle will be reversed until it is pressed a few times.
When you have a healing event that runs when "Starting Over" is running, you need to do something different. You need to put a new blank event called "Dependent" right next to where the player will spawn after losing the battle, and in the auto running "Starting Over" event, after healing the Pokemon, you need to use
again, with the "X" being the ID of the new event you just made.
Other Features
The script is set up so it is user friendly and easy to edit. If you have scripting knowledge, you should be able to figure out how to add new messages for the Pokemon to say for different situations, and how to make the follower sprite move around through scripting. If you don't have any scripting knowledges, feel free to post here asking for help :)
Also, as of Version 1.3, you can now animate other Events in the game so they are constantly moving like your follower. Just call
and all events on the map named "Poke" will animate.
Bug Fixing
If you follow all these steps and get an error that looks like this
you need to delete your saved data, and then replace the Animations data file again with the download I have above. (Just the part that goes in the Data Folder) Start a new game and the issue should be resolved.
If you use this script give credit to Help-14, zingzags, Rayd12smitty, and venom12
If you are updating from a previous version, replace the Following Pokemon script, and if you are updating from before Version 1.2, look down a bit there is a new part of code to replace in PokemonParty. Also you no longer need to manually turn on the switches for Activated_Following_Switch and Toggle_Following_Switch. They are now automatically included in "pbPokemonFollow(x)" This was updated in Version 1.2.
Intro
Adding Following Pokemon has been a real pain for anyone who doesn't have a decent amount of scripting experience. I want to change that :D I have spent the last few days reorganizing the Following Pokemon script that was previously updated by zingzags so it is easier to read, and works cleaner. I added quite a few nice features, and fixed some that were broken. venom12 is going to working with me to continue improving this feature. Here is my complete guide to installing Following Pokemon.
Quick Overview
Following Pokemon was a feature in HGSS in which the first Pokemon in your party would walk around with you in the Overworld. Quite a few years ago, Help-14 wrote a script to implement Following Pokemon in Pokemon Essentials. Then, more recently, zingzags posted an updated version of the script, along with basic instructions on how to implement it in your game. Now, I have once again updated the script adding more features and fixes. venom12 and I will most likely continue improving this script until it is as good as we can get it.
Features, from Help-14, zingzags, Rayd12smitty, venom12
Version 1.3
* Fixed bug with surf where the Follower could block the player from being able to surf, possibly stranding the player
* Added script to animate all events named "Poke"
* Increased time to find an item. I realize now that 5000 frames is less than 5 min. Way too short. Now it will take 12 and 1/2 min to find an item.
Older Versions
Spoiler:
Version 1.2
* Fixed Walk step count so it doesn't add on when Pokemon is toggled off
* No longer have to manually set Toggle_Following_Switch and Following_Activated_Switch whenever "pbPokemonFollow(x)" is called
* Now supports Pokemon with multiple forms
* Items found on specific maps support
* Support for messages when on a map including a word/phrase in its name rather than a single map
* Added stepping animation for follower
* Fixed dismount bike so Pokemon reappears
* Fixed bike so if it couldn't be used it now can
* Few other small bike fixes
Version 1.1
* Fixed surfing dismount so if follower is toggled off it doesn't reappear
* Changed toggle for followers location for easier installation
Version 1.0
* Pokemon follow behind the Player
* Followers disappear when using surf
* Shiny Pokemon support
* Talk to your Pokemon - Hundreds of easy to add custom messages
* Check to make sure the Pokemon is not an egg
* PokeCenter support
* Animations for popping out of a Pokeball, Going back inside, and different Emojis
* Pokemon get happier when following the player
* Pokemon may be holding items that can be taken
* Better map transfers
* Party/Follower rotation
* Toggle Following Pokemon on and off
* Pokemon no longer jump around on ledges
* Fixed Walk step count so it doesn't add on when Pokemon is toggled off
* No longer have to manually set Toggle_Following_Switch and Following_Activated_Switch whenever "pbPokemonFollow(x)" is called
* Now supports Pokemon with multiple forms
* Items found on specific maps support
* Support for messages when on a map including a word/phrase in its name rather than a single map
* Added stepping animation for follower
* Fixed dismount bike so Pokemon reappears
* Fixed bike so if it couldn't be used it now can
* Few other small bike fixes
Version 1.1
* Fixed surfing dismount so if follower is toggled off it doesn't reappear
* Changed toggle for followers location for easier installation
Version 1.0
* Pokemon follow behind the Player
* Followers disappear when using surf
* Shiny Pokemon support
* Talk to your Pokemon - Hundreds of easy to add custom messages
* Check to make sure the Pokemon is not an egg
* PokeCenter support
* Animations for popping out of a Pokeball, Going back inside, and different Emojis
* Pokemon get happier when following the player
* Pokemon may be holding items that can be taken
* Better map transfers
* Party/Follower rotation
* Toggle Following Pokemon on and off
* Pokemon no longer jump around on ledges
The Script
First add this in Settings. You can change the variables and switches used here. Make sure none of these switches/variables are being used in your game.
Code:
#===============================================================================
# * Config Script For Your Game Here. Change the emo_ to what ever number is
# the cell holding the animation.
#===============================================================================
Following_Activated_Switch = 126 # Switch should be reserved
Toggle_Following_Switch = 103 # Switch should be reserved
Current_Following_Variable = 36 # Variable should be reserved
CommonEvent = 4 # Common Event space needed
ItemWalk=26 # Variable should be reserved
Walking_Time_Variable = 27 # Variable should be reserved
Walking_Item_Variable = 28 # Variable should be reserved
Animation_Come_Out = 93
Animation_Come_In = 94
Emo_Happy = 95
Emo_Normal = 96
Emo_Hate = 97
Emo_Poison= 98
Emo_sing= 99
Emo_love= 100
Next add this as a new Script Section called Following Pokemon. Put it above Main.
Code:
#===============================================================================
# * Credit to Help-14 for both the original scripts and sprites
# * Change Log:
#===============================================================================
#===============================================================================
# * Edited by zingzags
#===============================================================================
# * Fixed bugs
# * Clean ups
# * Fixed Surf Bug (After Surf is done)
# * Fixed def talk_to_pokemon while in surf
# * Fixed Surf Check
# * Fixed Type Check
# * Added Door Support
# * Fixed Hp Bug
# * Added Pokemon Center Support
# * Animation problems
# * Fixed Walk_time_variable problem
# * Added random item loot
# * Added egg check
#===============================================================================
#===============================================================================
# * Edited by Rayd12smitty
# * Version 1.0
#===============================================================================
# * Fixed Walk_Time_Variable
# * Fixed crash when talking to Pokemon on a different map than the original
# they appeared on
# * Receiving Items from Pokemon now works
# * Improved Talk_to_Pokemon wiht more messages and special messages
# * Added messages for all Status Conditions
# * Added Party Rotation to switch follower
# * Made Following Pokemon Toggleable
# * Added Animation for Pokemon coming out of Pokeball in sprite_refresh
# * Tidied up script layout and made more user friendly
# * Fixed Issues with Pokemon jumping around on ledges
# * Fixed Badge for Surf Typo in the script
#===============================================================================
# * Version 1.1
#===============================================================================
# * Fixed Surfing so Pokemon doesn't reappear on water when toggled off
# * Changed Layout and location of Toggle Script
#===============================================================================
#===============================================================================
# * Edited by Rayd12smitty and venom12
# * Version 1.2
#===============================================================================
# * Fixed Walk step count so it doesn't add on when Pokemon is toggled off
# * No longer have to manually set Toggle_Following_Switch and
# Following_Activated_Switch whenever "pbPokemonFollow(x)" is called
# * Now supports Pokemon with multiple forms
# * Items found on specific maps support
# * Support for messages when on a map including a word/phrase in its name
# rather than a single map
# * Added stepping animation for follower
# * Fixed dismount bike so Pokemon reappears
# * Fixed bike so if it couldn't be used it now can
# * Few other small bike fixes
#===============================================================================
#===============================================================================
# * Version 1.3
#===============================================================================
# * Fixed bug with surf where the Follower could block the player from being
# able to surf, possibly stranding the player
# * Added script to animate all events named "Poke"
# * Increased time to find an item. I realize now that 5000 frames is less than
# 5 min. Way too short.
#===============================================================================
#===============================================================================
# * To Do
#===============================================================================
# * When Follower is toggled off remove grass/field animations
# * Fix up map transfers a bit more
# * Make NPCs not able to walk over the Follower
#===============================================================================
#===============================================================================
# * Control the following Pokemon
# * Example:
# FollowingMoveRoute([
# PBMoveRoute::TurnRight,
# PBMoveRoute::Wait,4,
# PBMoveRoute::Jump,0,0
# ])
# * The Pokemon turns Right, waits 4 frames, and then jumps
# * Call pbPokeStep to animate all events on the map named "Poke"
#===============================================================================
def FollowingMoveRoute(commands,waitComplete=false)
$PokemonTemp.dependentEvents.SetMoveRoute(commands,waitComplete)
end
def pbPokeStep
for event in $game_map.events.values
if event.name=="Poke"
pbMoveRoute(event,[PBMoveRoute::StepAnimeOn])
end
end
end
#===============================================================================
# * Toggle for Following Pokemon
#===============================================================================
def pbToggleFollowingPokemon
if $game_switches[Following_Activated_Switch]==true
if $game_switches[Toggle_Following_Switch]==true
$PokemonTemp.dependentEvents.remove_sprite(true)
pbWait(1)
$game_switches[Toggle_Following_Switch]=false
else
$FollowingFinishedSurfing = false
$PokemonTemp.dependentEvents.refresh_sprite
pbWait(1)
$game_switches[Toggle_Following_Switch]=true
end
end
end
class DependentEvents
#===============================================================================
# Raises The Current Pokemon's Happiness level +1 per each time the
# Walk_time_Variable reachs 5000 then resets to 0
# ItemWalk, is when the variable reaches a certain amount, that you are able
# to talk to your pokemon to recieve an item
#===============================================================================
def add_following_time
$PokemonTemp.dependentEvents.update_stepping
if $game_switches[Toggle_Following_Switch]==true && $Trainer.party.length>=1
$game_variables[Walking_Time_Variable]+=1 if $game_variables[Current_Following_Variable]!=$Trainer.party.length
$game_variables[Walking_Item_Variable]+=1 if $game_variables[Current_Following_Variable]!=$Trainer.party.length
if $game_variables[Walking_Time_Variable]==5000
$Trainer.party[0].happiness+=1
$game_variables[Walking_Time_Variable]=0
end
if $game_variables[Walking_Item_Variable]==1000
if $game_variables[ItemWalk]==15
else
$game_variables[ItemWalk]+=1
end
$game_variables[Walking_Item_Variable]=0
end
end
end
#===============================================================================
# * refresh_sprite
# * Updates the sprite sprite with an animation
#===============================================================================
def refresh_sprite
if $Trainer.party.length!=$game_variables[Current_Following_Variable]
if $Trainer.party[0].isShiny?
shiny=true
else
shiny=false
end
if $Trainer.party[0].form>0
form=$Trainer.party[0].form
else
form=nil
end
if $Trainer.party[0].hp>0 && !$Trainer.party[0].egg?
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
$scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
pbWait(10)
end
change_sprite($Trainer.party[0].species, shiny, false, form)
elsif $Trainer.party[0].hp<=0
remove_sprite
end
end
end
#===============================================================================
# * change_sprite(id, shiny, animation)
# * Example, to change sprite to shiny lugia with animation:
# change_sprite(249, true, true)
# * If just change sprite:
# change_sprite(249)
#===============================================================================
def change_sprite(id, shiny=nil, animation=nil, form=nil)
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][8]=="Dependent"
if shiny==true
events[i][6]=sprintf("%03ds",id)
if FileTest.image_exist?("Graphics/Characters/"+events[i][6])
@realEvents[i].character_name=sprintf("%03ds",id)
else
events[i][6]=sprintf("%03d",id)
@realEvents[i].character_name=sprintf("%03d",id)
end
else
if $Trainer.party[0].form>0
events[i][6]=sprintf("%03d",id)
@realEvents[i].character_name=sprintf("%03d_%d",id,$Trainer.party[0].form)
else
events[i][6]=sprintf("%03d",id)
@realEvents[i].character_name=sprintf("%03d",id)
end
end
if animation==true
$scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
end
$game_variables[Walking_Time_Variable]=0
end
end
end
#===============================================================================
# * update_stepping
# * Adds step animation for followers
#===============================================================================
def update_stepping
FollowingMoveRoute([PBMoveRoute::StepAnimeOn])
end
#===============================================================================
# * remove_sprite(animation)
# * Example, to remove sprite with animation:
# remove_sprite(true)
# * If just remove sprite:
# remove_sprite
#===============================================================================
def remove_sprite(animation=nil)
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][8]=="Dependent"
events[i][6]=sprintf("nil")
@realEvents[i].character_name=sprintf("nil")
if animation==true
$scene.spriteset.addUserAnimation(Animation_Come_In,@realEvents[i].x,@realEvents[i].y)
pbWait(10)
end
$game_variables[Current_Following_Variable]=$Trainer.party[0]
$game_variables[Walking_Time_Variable]=0
end
end
end
#===============================================================================
# * check_surf(animation)
# * If current Pokemon is a water Pokemon, it is still following.
# * If current Pokemon is not a water Pokemon, remove sprite.
# * Require Water_Pokemon_Can_Surf = true to enable
#===============================================================================
def check_surf(animation=nil)
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][8]=="Dependent"
events[i][6]=sprintf("nil")
@realEvents[i].character_name=sprintf("nil")
else
if $Trainer.party[0].hp>0 && !$Trainer.party[0].egg?
if $Trainer.party[0].hasType?(:WATER)
else
remove_sprite
pbWait(20)
end
elsif $Trainer.party[0].hp<=0
end
end
end
end
#===============================================================================
# * talk_to_pokemon
# * It will run when you talk to Pokemon following
#===============================================================================
def talk_to_pokemon
e=$Trainer.party[0]
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][8]=="Dependent"
pos_x=@realEvents[i].x
pos_y=@realEvents[i].y
end
end
if e==0
else
if e.hp>0 && !$Trainer.party[0].egg?
if $PokemonGlobal.surfing==true || $PokemonGlobal.bicycle==true
else
#===============================================================================
# * Checks to make sure the Pokemon isn't blocking a surfable water surface
# * If the water is blocked by the sprite (even though it is invisible) and
# the player should be able to surf, calls surf
#===============================================================================
terrain=Kernel.pbFacingTerrainTag
notCliff=$game_map.passable?($game_player.x,$game_player.y,$game_player.direction)
if pbIsWaterTag?(terrain) || !notCliff
if !pbGetMetadata($game_map.map_id,MetadataBicycleAlways) && !$PokemonGlobal.surfing
if $DEBUG
$FollowingFinishedSurfing = false
Kernel.pbSurf
elsif (HIDDENMOVESCOUNTBADGES ? $Trainer.numbadges>=BADGEFORSURF : $Trainer.badges[BADGEFORSURF])
$FollowingFinishedSurfing = false
Kernel.pbSurf
end
end
#===============================================================================
# * talk_to_pokemon when possible begins here
#===============================================================================
elsif e!=6 && $game_switches[Toggle_Following_Switch]==true
pbPlayCry(e.species)
random1=rand(7) # random message if no special conditions apply
mapname=$game_map.name # Get's current map name
#===============================================================================
# * Pokemon Messages when Status Condition
#===============================================================================
if e.status==PBStatuses::POISON && e.hp>0 && !e.egg? # Pokemon Poisoned
$scene.spriteset.addUserAnimation(Emo_Poison, pos_x, pos_y-2)
pbWait(120)
Kernel.pbMessage(_INTL("{1} is shivering with the effects of being poisoned.",e.name))
elsif e.status==PBStatuses::BURN && e.hp>0 && !e.egg? # Pokemon Burned
$scene.spriteset.addUserAnimation(Emo_Hate, pos_x, pos_y-2)
pbWait(70)
Kernel.pbMessage(_INTL("{1}'s burn looks painful.",e.name))
elsif e.status==PBStatuses::FROZEN && e.hp>0 && !e.egg? # Pokemon Frozen
$scene.spriteset.addUserAnimation(Emo_Normal, pos_x, pos_y-2)
pbWait(100)
Kernel.pbMessage(_INTL("{1} seems very cold. It's frozen solid!",e.name))
elsif e.status==PBStatuses::SLEEP && e.hp>0 && !e.egg? # Pokemon Asleep
$scene.spriteset.addUserAnimation(Emo_Normal, pos_x, pos_y-2)
pbWait(100)
Kernel.pbMessage(_INTL("{1} seems really tired.",e.name))
elsif e.status==PBStatuses::PARALYSIS && e.hp>0 && !e.egg? # Pokemon Paralyzed
$scene.spriteset.addUserAnimation(Emo_Normal, pos_x, pos_y-2)
pbWait(100)
Kernel.pbMessage(_INTL("{1} is standing still and twitching.",e.name))
#===============================================================================
# * Pokemon is holding an item on a Specific Map
#===============================================================================
elsif $game_variables[ItemWalk]==15 and mapname=="Item Map" # Pokemon has item and is on map "Item Map"
items=[:MASTERBALL,:MASTERBALL] # This array can be edited and extended. Look at the one below for a guide
random2=0
loop do
random2=rand(items.length)
break if hasConst?(PBItems,items[random2])
end
Kernel.pbMessage(_INTL("{1} seems to be holding something.",e.name))
Kernel.pbPokemonFound(getConst(PBItems,items[random2]))
$game_variables[ItemWalk]=0
#===============================================================================
# * Pokemon is holding an item on any other map
#===============================================================================
elsif $game_variables[ItemWalk]==15 # Pokemon has Item
items=[:POTION,:SUPERPOTION,:FULLRESTORE,:REVIVE,:PPUP,
:PPMAX,:RARECANDY,:REPEL,:MAXREPEL,:ESCAPEROPE,
:HONEY,:TINYMUSHROOM,:PEARL,:NUGGET,:GREATBALL,
:ULTRABALL,:THUNDERSTONE,:MOONSTONE,:SUNSTONE,:DUSKSTONE,
:REDAPRICORN,:BLUAPRICORN,:YLWAPRICORN,:GRNAPRICORN,:PNKAPRICORN,
:BLKAPRICORN,:WHTAPRICORN
]
random2=0
loop do
random2=rand(items.length)
break if hasConst?(PBItems,items[random2])
end
Kernel.pbMessage(_INTL("{1} seems to be holding something.",e.name))
Kernel.pbPokemonFound(getConst(PBItems,items[random2]))
$game_variables[ItemWalk]=0
#===============================================================================
# * Examples of Map Specific Messages
#===============================================================================
elsif mapname=="Dusk Forest" && e.hasType?(:BUG) # Bug Type in Dusk Forest
$scene.spriteset.addUserAnimation(Emo_sing, pos_x, pos_y-2)
pbWait(50)
random3=rand(3)
if random3==0
Kernel.pbMessage(_INTL("{1} seems highly interested in the trees.",e.name,$Trainer.name))
elsif random3==1
Kernel.pbMessage(_INTL("{1} seems to enjoy the buzzing of the bug Pokémon.",e.name,$Trainer.name))
elsif random3==2
Kernel.pbMessage(_INTL("{1} is jumping around restlessly in the forest.",e.name,$Trainer.name))
end
elsif mapname=="Old Lab" # In the Old Lab
$scene.spriteset.addUserAnimation(Emo_Normal, pos_x, pos_y-2)
pbWait(100)
random3=rand(3)
if random3==0
Kernel.pbMessage(_INTL("{1} is touching some kind of switch.",e.name,$Trainer.name))
elsif random3==1
Kernel.pbMessage(_INTL("{1} has a cord in its mouth!",e.name,$Trainer.name))
elsif random3==2
Kernel.pbMessage(_INTL("{1} seems to want to touch the machinery.",e.name,$Trainer.name))
end
elsif mapname=="Home" # In the Player's Home
$scene.spriteset.addUserAnimation(Emo_Happy, pos_x, pos_y-2)
pbWait(70)
random3=rand(3)
if random3==0
Kernel.pbMessage(_INTL("{1} is sniffing around the room.",e.name,$Trainer.name))
elsif random3==1
Kernel.pbMessage(_INTL("{1} noticed {2}'s mom is nearby.",e.name,$Trainer.name))
elsif random3==2
Kernel.pbMessage(_INTL("{1} seems to want to settle down at home.",e.name,$Trainer.name))
end
elsif mapname.include?("Route") # On any map that includes "Route" in the name
# Animation goes here
# Appropriate wait time for animation goes here
# random3=rand(x)
# different random messages
#===============================================================================
# * Random Messages if none of the above apply
#===============================================================================
elsif random1==0 # Music Note
$scene.spriteset.addUserAnimation(Emo_sing, pos_x, pos_y-2)
pbWait(50)
random3=rand(5)
if random3==0
Kernel.pbMessage(_INTL("{1} seems to want to play with {2}.",e.name,$Trainer.name))
elsif random3==1
Kernel.pbMessage(_INTL("{1} is singing and humming.",e.name,$Trainer.name))
elsif random3==2
Kernel.pbMessage(_INTL("{1} is looking up at the sky.",e.name,$Trainer.name))
elsif random3==3
Kernel.pbMessage(_INTL("{1} swayed and danced around as it pleased.",e.name,$Trainer.name))
elsif random3==4
Kernel.pbMessage(_INTL("{1} is pulling out the grass.",e.name,$Trainer.name))
end
elsif random1==1 # Hate/Angry Face
$scene.spriteset.addUserAnimation(Emo_Hate, pos_x, pos_y-2)
pbWait(70)
random3=rand(5)
if random3==0
Kernel.pbMessage(_INTL("{1} let out a roar!",e.name,$Trainer.name))
elsif random3==1
Kernel.pbMessage(_INTL("{1} is making a face like it's angry!",e.name,$Trainer.name))
elsif random3==2
Kernel.pbMessage(_INTL("{1} seems to be angry for some reason.",e.name,$Trainer.name))
elsif random3==3
Kernel.pbMessage(_INTL("{1} chewed on your feet.",e.name,$Trainer.name))
elsif random3==4
Kernel.pbMessage(_INTL("{1} is trying to be intimidating.",e.name,$Trainer.name))
end
elsif random1==2 # ... Emoji
$scene.spriteset.addUserAnimation(Emo_Normal, pos_x, pos_y-2)
pbWait(100)
random3=rand(5)
if random3==0
Kernel.pbMessage(_INTL("{1} is looking down steadily.",e.name,$Trainer.name))
elsif random3==1
Kernel.pbMessage(_INTL("{1} is sniffing at the floor.",e.name,$Trainer.name))
elsif random3==2
Kernel.pbMessage(_INTL("{1} is concentrating deeply.",e.name,$Trainer.name))
elsif random3==3
Kernel.pbMessage(_INTL("{1} faced this way and nodded.",e.name,$Trainer.name))
elsif random3==4
Kernel.pbMessage(_INTL("{1} is glaring straight into {2}'s eyes.",e.name,$Trainer.name))
end
elsif random1==3 # Happy Face
$scene.spriteset.addUserAnimation(Emo_Happy, pos_x, pos_y-2)
pbWait(70)
random3=rand(5)
if random3==0
Kernel.pbMessage(_INTL("{1} began poking you in the stomach.",e.name,$Trainer.name))
elsif random3==1
Kernel.pbMessage(_INTL("{1} looks very happy.",e.name,$Trainer.name))
elsif random3==2
Kernel.pbMessage(_INTL("{1} happily cuddled up to you.",e.name,$Trainer.name))
elsif random3==3
Kernel.pbMessage(_INTL("{1} is so happy that it can't stand still.",e.name,$Trainer.name))
elsif random3==4
Kernel.pbMessage(_INTL("{1} looks like it wants to lead!",e.name,$Trainer.name))
end
elsif random1==4 # Heart Emoji
$scene.spriteset.addUserAnimation(Emo_love, pos_x, pos_y-2)
pbWait(70)
random3=rand(5)
if random3==0
Kernel.pbMessage(_INTL("{1} suddenly started walking closer.",e.name,$Trainer.name))
elsif random3==1
Kernel.pbMessage(_INTL("Woah! {1} suddenly hugged {2}.",e.name,$Trainer.name))
elsif random3==2
Kernel.pbMessage(_INTL("{1} is rubbing up against you.",e.name,$Trainer.name))
elsif random3==3
Kernel.pbMessage(_INTL("{1} is keeping close to {2}.",e.name,$Trainer.name))
elsif random3==4
Kernel.pbMessage(_INTL("{1} blushed.",e.name,$Trainer.name))
end
elsif random1==5 # No Emoji
random3=rand(5)
if random3==0
Kernel.pbMessage(_INTL("{1} spun around in a circle!",e.name,$Trainer.name))
elsif random3==1
Kernel.pbMessage(_INTL("{1} let our a battle cry.",e.name,$Trainer.name))
elsif random3==2
Kernel.pbMessage(_INTL("{1} is on the lookout!",e.name,$Trainer.name))
elsif random3==3
Kernel.pbMessage(_INTL("{1} is standing patiently.",e.name,$Trainer.name))
elsif random3==4
Kernel.pbMessage(_INTL("{1} is looking around restlessly.",e.name,$Trainer.name))
end
#===============================================================================
# * This random message shows the Pokemon's Happiness Level
#===============================================================================
elsif random1==6 # Check Happiness Level
if e.happiness>0 && e.happiness<=50
$scene.spriteset.addUserAnimation(Emo_Hate, pos_x, pos_y-2)
pbWait(70)
Kernel.pbMessage(_INTL("{1} hates to travel with {2}.",e.name,$Trainer.name))
elsif e.happiness>50 && e.happiness<=100
$scene.spriteset.addUserAnimation(Emo_Normal, pos_x, pos_y-2)
pbWait(100)
Kernel.pbMessage(_INTL("{1} is still unsure about traveling with {2} is a good thing or not.",e.name,$Trainer.name))
elsif e.happiness>100 && e.happiness<150
$scene.spriteset.addUserAnimation(Emo_Happy, pos_x, pos_y-2)
Kernel.pbMessage(_INTL("{1} is happy traveling with {2}.",e.name,$Trainer.name))
elsif e.happiness>=150
$scene.spriteset.addUserAnimation(Emo_love, pos_x, pos_y-2)
pbWait(70)
Kernel.pbMessage(_INTL("{1} loves traveling with {2}.",e.name,$Trainer.name))
end
end
else
end
end
end
end
end
#===============================================================================
# * Pokemon reapear after using surf
#===============================================================================
def Come_back(shiny=nil, animation=nil)
events=$PokemonGlobal.dependentEvents
if $game_variables[Current_Following_Variable]==$Trainer.party.length
remove_sprite(false)
for i in 0...events.length
$scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
end
else
if $Trainer.party[0].isShiny?
shiny=true
else
shiny=false
end
change_sprite($Trainer.party[0].species, shiny, false)
end
for i in 0..$Trainer.party.length-1
if $Trainer.party[i].hp>0 && !$Trainer.party[0].egg?
$game_variables[Current_Following_Variable]=i
refresh_sprite
break
end
end
for i in 0...events.length
for i in 0..$Trainer.party.length-1
if $Trainer.party[i].hp<=0
id = $Trainer.party[i].species
else
id = $Trainer.party[i].species
end
end
if events[i] && events[i][8]=="Dependent"
if shiny==true
events[i][6]=sprintf("%03ds",id)
if FileTest.image_exist?("Graphics/Characters/"+events[i][6])
@realEvents[i].character_name=sprintf("%03ds",id)
else
events[i][6]=sprintf("%03d",id)
@realEvents[i].character_name=sprintf("%03d",id)
end
else
events[i][6]=sprintf("%03d",id)
@realEvents[i].character_name=sprintf("%03d",id)
end
if animation==true
else
end
end
end
end
#===============================================================================
# * check_faint
# * If current Pokemon is fainted, removes the sprite
#===============================================================================
def check_faint
if $PokemonGlobal.surfing==true || $PokemonGlobal.bicycle==true
else
if $Trainer.party[0].hp<=0
$game_variables[Current_Following_Variable]=0
remove_sprite
elsif $Trainer.party[0].hp>0 && !$Trainer.party[0].egg?
end
end
end
#===============================================================================
# * SetMoveRoute
# * Used in the "Control Following Pokemon" Script listed farther above
#===============================================================================
def SetMoveRoute(commands,waitComplete=false)
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][8]=="Dependent"
pbMoveRoute(@realEvents[i],commands,waitComplete)
end
end
end
end
#===============================================================================
# * Auto add Script to Kernel.pbSurf, It'll check curent Pokemon when surf
#===============================================================================
def Kernel.pbSurf
# if $game_player.pbHasDependentEvents?
# return false
# end
if $DEBUG ||
(HIDDENMOVESCOUNTBADGES ? $Trainer.numbadges>=BADGEFORSURF : $Trainer.badges[BADGEFORSURF])
movefinder=Kernel.pbCheckMove(:SURF)
if $DEBUG || movefinder
if Kernel.pbConfirmMessage(_INTL("The water is dyed a deep blue... Would you like to surf?"))
speciesname=!movefinder ? $Trainer.name : movefinder.name
Kernel.pbMessage(_INTL("{1} used Surf!",speciesname))
pbHiddenMoveAnimation(movefinder)
# $PokemonTemp.dependentEvents.check_surf
surfbgm=pbGetMetadata(0,MetadataSurfBGM)
$PokemonTemp.dependentEvents.check_surf
if surfbgm
pbCueBGM(surfbgm,0.5)
end
pbStartSurfing()
return true
end
end
end
return false
end
def pbStartSurfing()
Kernel.pbCancelVehicles
$PokemonEncounters.clearStepCount
$PokemonGlobal.surfing=true
Kernel.pbUpdateVehicle
Kernel.pbJumpToward
Kernel.pbUpdateVehicle
$game_player.check_event_trigger_here([1,2])
end
#===============================================================================
# * Auto add Script to pbEndSurf, It'll show sprite after surf
#===============================================================================
def pbEndSurf(xOffset,yOffset)
return false if !$PokemonGlobal.surfing
x=$game_player.x
y=$game_player.y
currentTag=$game_map.terrain_tag(x,y)
facingTag=Kernel.pbFacingTerrainTag
if pbIsSurfableTag?(currentTag)&&!pbIsSurfableTag?(facingTag)
if Kernel.pbJumpToward
Kernel.pbCancelVehicles
$game_map.autoplayAsCue
$game_player.increase_steps
result=$game_player.check_event_trigger_here([1,2])
Kernel.pbOnStepTaken(result)
$FollowingFinishedSurfing = true
end
return true
end
return false
end
#===============================================================================
# * Auto add Script to Kernel.pbCanUseHiddenMove, fix HM bug
#===============================================================================
def Kernel.pbCanUseHiddenMove?(pkmn,move)
case move
when PBMoves::FLY
if !$DEBUG && !$Trainer.badges[BADGEFORFLY]
Kernel.pbMessage(_INTL("Sorry, a new Badge is required."))
return false
end
# if $game_player.pbHasDependentEvents?
# Kernel.pbMessage(_INTL("You can't use that if you have someone with you."))
# return false
# end
if !pbGetMetadata($game_map.map_id,MetadataOutdoor)
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
return true
when PBMoves::CUT
if !$DEBUG && !$Trainer.badges[BADGEFORCUT]
Kernel.pbMessage(_INTL("Sorry, a new Badge is required."))
return false
end
facingEvent=$game_player.pbFacingEvent
if !facingEvent || facingEvent.name!="Tree"
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
return true
when PBMoves::HEADBUTT
facingEvent=$game_player.pbFacingEvent
if !facingEvent || facingEvent.name!="HeadbuttTree"
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
return true
when PBMoves::SURF
terrain=Kernel.pbFacingTerrainTag
if !$DEBUG && !$Trainer.badges[BADGEFORSURF]
Kernel.pbMessage(_INTL("Sorry, a new Badge is required."))
return false
end
if $PokemonGlobal.surfing
Kernel.pbMessage(_INTL("You're already surfing."))
return false
end
# if $game_player.pbHasDependentEvents?
# Kernel.pbMessage(_INTL("You can't use that if you have someone with you."))
# return false
# end
terrain=Kernel.pbFacingTerrainTag
if pbGetMetadata($game_map.map_id,MetadataBicycleAlways)
Kernel.pbMessage(_INTL("Let's enjoy cycling!"))
return false
end
if !pbIsWaterTag?(terrain)
Kernel.pbMessage(_INTL("No surfing here!"))
return false
end
return true
when PBMoves::STRENGTH
if !$DEBUG && !$Trainer.badges[BADGEFORSTRENGTH]
Kernel.pbMessage(_INTL("Sorry, a new Badge is required."))
return false
end
facingEvent=$game_player.pbFacingEvent
if !facingEvent || facingEvent.name!="Boulder"
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
return true
when PBMoves::ROCKSMASH
terrain=Kernel.pbFacingTerrainTag
if !$DEBUG && !$Trainer.badges[BADGEFORROCKSMASH]
Kernel.pbMessage(_INTL("Sorry, a new Badge is required."))
return false
end
facingEvent=$game_player.pbFacingEvent
if !facingEvent || facingEvent.name!="Rock"
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
return true
when PBMoves::FLASH
if !$DEBUG && !$Trainer.badges[BADGEFORFLASH]
Kernel.pbMessage(_INTL("Sorry, a new Badge is required."))
return false
end
if !pbGetMetadata($game_map.map_id,MetadataDarkMap)
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
if $PokemonGlobal.flashUsed
Kernel.pbMessage(_INTL("This is in use already."))
return false
end
return true
when PBMoves::WATERFALL
if !$DEBUG && !$Trainer.badges[BADGEFORWATERFALL]
Kernel.pbMessage(_INTL("Sorry, a new Badge is required."))
return false
end
terrain=Kernel.pbFacingTerrainTag
if terrain!=PBTerrain::Waterfall
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
return true
when PBMoves::DIVE
if !$DEBUG && !$Trainer.badges[BADGEFORDIVE]
Kernel.pbMessage(_INTL("Sorry, a new Badge is required."))
return false
end
if $PokemonGlobal.diving
return true
end
if $game_player.terrain_tag!=PBTerrain::DeepWater
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
if !pbGetMetadata($game_map.map_id,MetadataDiveMap)
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
return true
when PBMoves::TELEPORT
if !pbGetMetadata($game_map.map_id,MetadataOutdoor)
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
# if $game_player.pbHasDependentEvents?
# Kernel.pbMessage(_INTL("You can't use that if you have someone with you."))
# return false
# end
healing=$PokemonGlobal.healingSpot
if !healing
healing=pbGetMetadata(0,MetadataHome) # Home
end
if healing
mapname=pbGetMapNameFromId(healing[0])
if Kernel.pbConfirmMessage(_INTL("Want to return to the healing spot used last in {1}?",mapname))
return true
end
return false
else
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
when PBMoves::DIG
escape=pbGetMetadata($game_map.map_id,MetadataEscapePoint)
if !escape
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
if $game_player.pbHasDependentEvents?
Kernel.pbMessage(_INTL("You can't use that if you have someone with you."))
return false
end
mapname=pbGetMapNameFromId(escape[0])
if Kernel.pbConfirmMessage(_INTL("Want to escape from here and return to {1}?",mapname))
return true
end
return false
when PBMoves::SWEETSCENT
return true
else
return HiddenMoveHandlers.triggerCanUseMove(move,pkmn)
end
return false
end
#===============================================================================
# * Auto add Script to Kernel.pbMountBike
#===============================================================================
def Kernel.pbMountBike
return if $PokemonGlobal.bicycle
$PokemonGlobal.bicycle=true
if $game_switches[Toggle_Following_Switch]==true
$PokemonTemp.dependentEvents.remove_sprite(true)
end
Kernel.pbUpdateVehicle
bikebgm=pbGetMetadata(0,MetadataBicycleBGM)
if bikebgm
pbCueBGM(bikebgm,0.5)
end
end
#===============================================================================
# * Auto add Script to Kernel.pbDismountBike
#===============================================================================
def Kernel.pbDismountBike
return if !$PokemonGlobal.bicycle
$PokemonGlobal.bicycle=false
$FollowingFinishedSurfing = true
Kernel.pbUpdateVehicle
$game_map.autoplayAsCue
end
#===============================================================================
# * Auto add Script to pbBikeCheck
#===============================================================================
def pbBikeCheck
if $PokemonGlobal.surfing ||
(!$PokemonGlobal.bicycle && pbGetTerrainTag==PBTerrain::TallGrass)
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
# if $game_player.pbHasDependentEvents?
# Kernel.pbMessage(_INTL("It can't be used when you have someone with you."))
# return false
# end
if $PokemonGlobal.bicycle
if pbGetMetadata($game_map.map_id,MetadataBicycleAlways)
Kernel.pbMessage(_INTL("You can't dismount your Bike here."))
return false
end
return true
else
val=pbGetMetadata($game_map.map_id,MetadataBicycle)
val=pbGetMetadata($game_map.map_id,MetadataOutdoor) if val==nil
if !val
Kernel.pbMessage(_INTL("Can't use that here."))
return false
end
return true
end
end
#===============================================================================
# * Auto add Script to pbTrainerPC
#===============================================================================
def pbTrainerPC
Kernel.pbMessage(_INTL("\\se[computeropen]{1} booted up the PC.",$Trainer.name))
pbTrainerPCMenu
pbSEPlay("computerclose")
$PokemonTemp.dependentEvents.refresh_sprite
end
#===============================================================================
# * Auto add Script to class TrainerPC
#===============================================================================
class TrainerPC
def shouldShow?
return true
end
def name
return _INTL("{1}'s PC",$Trainer.name)
end
def access
Kernel.pbMessage(_INTL("\\se[accesspc]Accessed {1}'s PC.",$Trainer.name))
pbTrainerPCMenu
$PokemonTemp.dependentEvents.refresh_sprite
end
end
#===============================================================================
# * Auto add Script to pbPokeCenterPC
#===============================================================================
def pbPokeCenterPC
Kernel.pbMessage(_INTL("\\se[computeropen]{1} booted up the PC.",$Trainer.name))
loop do
commands=PokemonPCList.getCommandList()
command=Kernel.pbMessage(_INTL("Which PC should be accessed?"),
commands,commands.length)
if !PokemonPCList.callCommand(command)
break
end
end
pbSEPlay("computerclose")
$PokemonTemp.dependentEvents.refresh_sprite
end
#===============================================================================
# * Auto add Script to Events.onStepTakenFieldMovement
# * Fixed End Surf for Toggle
# * NEED TO FIX GRASS ANIMATION PROBLEM
#===============================================================================
Events.onStepTakenFieldMovement+=proc{|sender,e|
event=e[0] # Get the event affected by field movement
currentTag=pbGetTerrainTag(event)
if pbGetTerrainTag(event,true)==PBTerrain::Grass # Won't show if under bridge
$scene.spriteset.addUserAnimation(GRASS_ANIMATION_ID,event.x,event.y)
elsif event==$game_player && currentTag==PBTerrain::WaterfallCrest
# Descend waterfall, but only if this event is the player
Kernel.pbDescendWaterfall(event)
elsif event==$game_player && currentTag==PBTerrain::Ice && !$PokemonGlobal.sliding
Kernel.pbSlideOnIce(event)
end
if $FollowingFinishedSurfing==true && $game_switches[Toggle_Following_Switch]==true
$PokemonTemp.dependentEvents.Come_back(true)
$FollowingFinishedSurfing = false
end
}
#===============================================================================
# * Start Pokemon Following
# * x is the Event ID that will become the follower
#===============================================================================
def pbPokemonFollow(x)
Kernel.pbAddDependency2(x, "Dependent", CommonEvent)
$PokemonTemp.dependentEvents.refresh_sprite
$game_switches[Following_Activated_Switch]=true
$game_switches[Toggle_Following_Switch]=true
end
Next replace DependentEvents with this. Please note that having Pokemon Followers makes other followers not a good option. You can still have Trainers following and trainer partners, but they look weird. Adding more support for this in the future maybe.
Code:
class PokemonTemp
attr_accessor :dependentEvents
def dependentEvents
@dependentEvents=DependentEvents.new if !@dependentEvents
return @dependentEvents
end
end
def pbRemoveDependencies()
$PokemonTemp.dependentEvents.removeAllEvents()
pbDeregisterPartner() rescue nil
end
def pbAddDependency(event)
$PokemonTemp.dependentEvents.addEvent(event)
end
def pbRemoveDependency(event)
$PokemonTemp.dependentEvents.removeEvent(event)
end
def pbAddDependency2(eventID, eventName, commonEvent)
$PokemonTemp.dependentEvents.addEvent($game_map.events[eventID],eventName,commonEvent)
end
# Gets the Game_Character object associated with a dependent event.
def pbGetDependency(eventName)
return $PokemonTemp.dependentEvents.getEventByName(eventName)
end
def pbRemoveDependency2(eventName)
$PokemonTemp.dependentEvents.removeEventByName(eventName)
end
class PokemonGlobalMetadata
attr_accessor :dependentEvents
def dependentEvents
@dependentEvents=[] if !@dependentEvents
return @dependentEvents
end
end
class Game_Event
def set_starting
@starting=true
end
end
def pbTestPass(follower,x,y,direction=nil)
return $MapFactory.isPassable?(follower.map.map_id,x,y,follower)
end
# Same map only
def moveThrough(follower,direction)
oldThrough=follower.through
follower.through=true
case direction
when 2 # down
follower.move_down
when 4 # left
follower.move_left
when 6 # right
follower.move_right
when 8 # up
follower.move_up
end
follower.through=oldThrough
end
# Same map only
def moveFancy(follower,direction)
deltaX=(direction == 6 ? 1 : (direction == 4 ? -1 : 0))
deltaY=(direction == 2 ? 1 : (direction == 8 ? -1 : 0))
newX = follower.x + deltaX
newY = follower.y + deltaY
# Move if new position is the player's, or the new position is passable,
# or the current position is not passable
if ($game_player.x==newX && $game_player.y==newY) ||
pbTestPass(follower,newX,newY,0) ||
!pbTestPass(follower,follower.x,follower.y,0)
oldThrough=follower.through
follower.through=true
case direction
when 2 # down
follower.move_down
when 4 # left
follower.move_left
when 6 # right
follower.move_right
when 8 # up
follower.move_up
end
follower.through=oldThrough
end
end
# Same map only
def jumpFancy(follower,direction)
deltaX=(direction == 6 ? 2 : (direction == 4 ? -2 : 0))
deltaY=(direction == 2 ? 2 : (direction == 8 ? -2 : 0))
halfDeltaX=(direction == 6 ? 1 : (direction == 4 ? -1 : 0))
halfDeltaY=(direction == 2 ? 1 : (direction == 8 ? -1 : 0))
middle=pbTestPass(follower,follower.x+halfDeltaX,follower.y+halfDeltaY,0)
ending=pbTestPass(follower,follower.x+deltaX, follower.y+deltaY, 0)
if middle
moveFancy(follower,direction)
moveFancy(follower,direction)
elsif ending
if pbTestPass(follower,follower.x,follower.y,0)
follower.jump(deltaX,deltaY)
else
moveThrough(follower,direction)
moveThrough(follower,direction)
end
end
end
def pbFancyMoveTo(follower,newX,newY)
if follower.x-newX==-1 && follower.y==newY
moveFancy(follower,6)
elsif follower.x-newX==1 && follower.y==newY
moveFancy(follower,4)
elsif follower.y-newY==-1 && follower.x==newX
moveFancy(follower,2)
elsif follower.y-newY==1 && follower.x==newX
moveFancy(follower,8)
elsif follower.x-newX==-2 && follower.y==newY
jumpFancy(follower,6)
elsif follower.x-newX==2 && follower.y==newY
jumpFancy(follower,4)
elsif follower.y-newY==-2 && follower.x==newX
jumpFancy(follower,2)
elsif follower.y-newY==2 && follower.x==newX
jumpFancy(follower,8)
elsif follower.x!=newX || follower.y!=newY
follower.moveto(newX,newY)
end
end
class DependentEvents
def createEvent(eventData)
rpgEvent=RPG::Event.new(eventData[3],eventData[4])
rpgEvent.id=eventData[1]
if eventData[9]
# Must setup common event list here and now
commonEvent=Game_CommonEvent.new(eventData[9])
rpgEvent.pages[0].list=commonEvent.list
end
newEvent=Game_Event.new(eventData[0],rpgEvent,
$MapFactory.getMap(eventData[2]))
newEvent.character_name=eventData[6]
newEvent.character_hue=eventData[7]
case eventData[5] # direction
when 2 # down
newEvent.turn_down
when 4 # left
newEvent.turn_left
when 6 # right
newEvent.turn_right
when 8 # up
newEvent.turn_up
end
return newEvent
end
attr_reader :lastUpdate
def initialize
# Original map, Event ID, Current map, X, Y, Direction
events=$PokemonGlobal.dependentEvents
@realEvents=[]
@lastUpdate=-1
for event in events
@realEvents.push(createEvent(event))
end
end
def pbEnsureEvent(event, newMapID)
events=$PokemonGlobal.dependentEvents
found=-1
for i in 0...events.length
# Check original map ID and original event ID
if events[i][0]==event.map_id && events[i][1]==event.id
# Change current map ID
events[i][2]=newMapID
newEvent=createEvent(events[i])
# Replace event
@realEvents[i]=newEvent
@lastUpdate+=1
return i
end
end
return -1
end
def pbFollowEventAcrossMaps(leader,follower,instant=false,leaderIsTrueLeader=true)
d=leader.direction
areConnected=$MapFactory.areConnected?(leader.map.map_id,follower.map.map_id)
# Get the rear facing tile of leader
facingDirection=[0,0,8,0,6,0,4,0,2][d]
if !leaderIsTrueLeader && areConnected
relativePos=$MapFactory.getThisAndOtherEventRelativePos(leader,follower)
if (relativePos[1]==0 && relativePos[0]==2) # 2 spaces to the right of leader
facingDirection=6
elsif (relativePos[1]==0 && relativePos[0]==-2) # 2 spaces to the left of leader
facingDirection=4
elsif relativePos[1]==-2 && relativePos[0]==0 # 2 spaces above leader
facingDirection=8
elsif relativePos[1]==2 && relativePos[0]==0 # 2 spaces below leader
facingDirection=2
end
end
facings=[facingDirection] # Get facing from behind
facings.push([0,0,4,0,8,0,2,0,6][d]) # Get right facing
facings.push([0,0,6,0,2,0,8,0,4][d]) # Get left facing
if !leaderIsTrueLeader
facings.push([0,0,2,0,4,0,6,0,8][d]) # Get forward facing
end
mapTile=nil
if areConnected
bestRelativePos=-1
oldthrough=follower.through
follower.through=false
for i in 0...facings.length
facing=facings[i]
tile=$MapFactory.getFacingTile(facing,leader)
passable=tile && $MapFactory.isPassable?(tile[0],tile[1],tile[2],follower)
if i==0 && !passable && tile &&
$MapFactory.getTerrainTag(tile[0],tile[1],tile[2])==PBTerrain::Ledge
# If the tile isn't passable and the tile is a ledge,
# get tile from further behind
tile=$MapFactory.getFacingTileFromPos(tile[0],tile[1],tile[2],facing)
passable=tile && $MapFactory.isPassable?(tile[0],tile[1],tile[2],follower)
end
if passable
relativePos=$MapFactory.getThisAndOtherPosRelativePos(
follower,tile[0],tile[1],tile[2])
distance=Math.sqrt(relativePos[0]*relativePos[0]+relativePos[1]*relativePos[1])
if bestRelativePos==-1 || bestRelativePos>distance
bestRelativePos=distance
mapTile=tile
end
if i==0 && distance<=1 # Prefer behind if tile can move up to 1 space
break
end
end
end
follower.through=oldthrough
else
tile=$MapFactory.getFacingTile(facings[0],leader)
passable=tile && $MapFactory.isPassable?(
tile[0],tile[1],tile[2],follower)
mapTile=passable ? mapTile : nil
end
if mapTile && follower.map.map_id==mapTile[0]
# Follower is on same map
newX=mapTile[1]
newY=mapTile[2]
deltaX=(d == 6 ? -1 : d == 4 ? 1 : 0)
deltaY=(d == 2 ? -1 : d == 8 ? 1 : 0)
posX = newX + deltaX
posY = newY + deltaY
follower.move_speed=leader.move_speed # sync movespeed
if (follower.x-newX==-1 && follower.y==newY) ||
(follower.x-newX==1 && follower.y==newY) ||
(follower.y-newY==-1 && follower.x==newX) ||
(follower.y-newY==1 && follower.x==newX)
if instant
follower.moveto(newX,newY)
else
pbFancyMoveTo(follower,newX,newY)
end
elsif (follower.x-newX==-2 && follower.y==newY) ||
(follower.x-newX==2 && follower.y==newY) ||
(follower.y-newY==-2 && follower.x==newX) ||
(follower.y-newY==2 && follower.x==newX)
if instant
follower.moveto(newX,newY)
else
pbFancyMoveTo(follower,newX,newY)
end
elsif follower.x!=posX || follower.y!=posY
if instant
follower.moveto(newX,newY)
else
pbFancyMoveTo(follower,posX,posY)
pbFancyMoveTo(follower,newX,newY)
end
end
pbTurnTowardEvent(follower,leader)
else
if !mapTile
# Make current position into leader's position
mapTile=[leader.map.map_id,leader.x,leader.y]
end
if follower.map.map_id==mapTile[0]
# Follower is on same map as leader
follower.moveto(leader.x,leader.y)
pbTurnTowardEvent(follower,leader)
else
# Follower will move to different map
events=$PokemonGlobal.dependentEvents
eventIndex=pbEnsureEvent(follower,mapTile[0])
if eventIndex>=0
newFollower=@realEvents[eventIndex]
newEventData=events[eventIndex]
newFollower.moveto(mapTile[1],mapTile[2])
newEventData[3]=mapTile[1]
newEventData[4]=mapTile[2]
if mapTile[0]==leader.map.map_id
pbTurnTowardEvent(follower,leader)
end
end
end
end
end
def debugEcho
self.eachEvent {|e,d|
echoln d
echoln [e.map_id,e.map.map_id,e.id]
}
end
def pbMapChangeMoveDependentEvents
events=$PokemonGlobal.dependentEvents
updateDependentEvents
leader=$game_player
for i in 0...events.length
event=@realEvents[i]
pbFollowEventAcrossMaps(leader,event,true,i==0)
# Update X and Y for this event
events[i][3]=event.x
events[i][4]=event.y
events[i][5]=event.direction
# Set leader to this event
leader=event
end
end
def pbMoveDependentEvents
events=$PokemonGlobal.dependentEvents
updateDependentEvents
leader=$game_player
for i in 0...events.length
event=@realEvents[i]
pbFollowEventAcrossMaps(leader,event,false,i==0)
# Update X and Y for this event
events[i][3]=event.x
events[i][4]=event.y
events[i][5]=event.direction
# Set leader to this event
leader=event
end
end
def pbTurnDependentEvents
events=$PokemonGlobal.dependentEvents
updateDependentEvents
leader=$game_player
for i in 0...events.length
event=@realEvents[i]
pbTurnTowardEvent(event,leader)
# Update direction for this event
events[i][5]=event.direction
# Set leader to this event
leader=event
end
end
def eachEvent
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
yield @realEvents[i],events[i]
end
end
def updateDependentEvents
events=$PokemonGlobal.dependentEvents
return if events.length==0
for i in 0...events.length
event=@realEvents[i]
next if !@realEvents[i]
event.transparent=$game_player.transparent
if (event.jumping? || event.moving?) || !($game_player.jumping? || $game_player.moving?) then
event.update
elsif !event.starting
event.set_starting
event.update
event.clear_starting
end
events[i][3]=event.x
events[i][4]=event.y
events[i][5]=event.direction
end
# Check event triggers
if Input.trigger?(Input::C) && !pbMapInterpreterRunning?
# Get position of tile facing the player
facingTile=$MapFactory.getFacingTile()
self.eachEvent {|e,d|
next if !d[9]
if e.x==$game_player.x && e.y==$game_player.y
# On same position
if not e.jumping? && (!e.respond_to?("over_trigger") || e.over_trigger?)
if e.list.size>1
# Start event
$game_map.refresh if $game_map.need_refresh
e.lock
pbMapInterpreter.setup(e.list,e.id,e.map.map_id)
end
end
elsif facingTile && e.map.map_id==facingTile[0] &&
e.x==facingTile[1] && e.y==facingTile[2]
# On facing tile
if not e.jumping? && (!e.respond_to?("over_trigger") || !e.over_trigger?)
if e.list.size>1
# Start event
$game_map.refresh if $game_map.need_refresh
e.lock
pbMapInterpreter.setup(e.list,e.id,e.map.map_id)
end
end
end
}
end
end
def removeEvent(event)
events=$PokemonGlobal.dependentEvents
mapid=$game_map.map_id
for i in 0...events.length
if events[i][2]==mapid && # Refer to current map
events[i][0]==event.map_id && # Event's map ID is original ID
events[i][1]==event.id
events[i]=nil
@realEvents[i]=nil
@lastUpdate+=1
end
events.compact!
@realEvents.compact!
end
end
def getEventByName(name)
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][8]==name # Arbitrary name given to dependent event
return @realEvents[i]
end
end
return nil
end
def removeAllEvents
events=$PokemonGlobal.dependentEvents
events.clear
@realEvents.clear
@lastUpdate+=1
end
def removeEventByName(name)
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][8]==name # Arbitrary name given to dependent event
events[i]=nil
@realEvents[i]=nil
@lastUpdate+=1
end
events.compact!
@realEvents.compact!
end
end
def addEvent(event,eventName=nil,commonEvent=nil)
return if !event
events=$PokemonGlobal.dependentEvents
for i in 0...events.length
if events[i] && events[i][0]==$game_map.map_id && events[i][1]==event.id
# Already exists
return
end
end
# Original map ID, original event ID, current map ID,
# event X, event Y, event direction,
# event's filename,
# event's hue, event's name, common event ID
eventData=[
$game_map.map_id,event.id,$game_map.map_id,
event.x,event.y,event.direction,
event.character_name.clone,
event.character_hue,eventName,commonEvent
]
newEvent=createEvent(eventData)
events.push(eventData)
@realEvents.push(newEvent)
@lastUpdate+=1
event.erase
end
end
class DependentEventSprites
def refresh
for sprite in @sprites
sprite.dispose
end
@sprites.clear
$PokemonTemp.dependentEvents.eachEvent {|event,data|
if data[0][email protected]_id # Check original map
#@map.events[data[1]].erase
end
if data[2][email protected]_id # Check current map
@sprites.push(Sprite_Character.new(@viewport,event))
end
}
end
def initialize(viewport,map)
@disposed=false
@sprites=[]
@map=map
@viewport=viewport
refresh
@lastUpdate=nil
end
def update
if $PokemonTemp.dependentEvents.lastUpdate!=@lastUpdate
refresh
@lastUpdate=$PokemonTemp.dependentEvents.lastUpdate
end
for sprite in @sprites
sprite.update
end
end
def dispose
return if @disposed
for sprite in @sprites
sprite.dispose
end
@sprites.clear
@disposed=true
end
def disposed?
@disposed
end
end
Events.onSpritesetCreate+=proc{|sender,e|
spriteset=e[0] # Spriteset being created
viewport=e[1] # Viewport used for tilemap and characters
map=spriteset.map # Map associated with the spriteset (not necessarily the current map).
spriteset.addUserSprite(DependentEventSprites.new(viewport,map))
}
Events.onMapSceneChange+=proc{|sender,e|
scene=e[0]
mapChanged=e[1]
if mapChanged
$PokemonTemp.dependentEvents.pbMapChangeMoveDependentEvents
end
}
In PokemonParty, add
Code:
$PokemonTemp.dependentEvents.refresh_sprite
Code:
next if havecommand
if cmdSummary>=0 && command==cmdSummary
@scene.pbSummary(pkmnid)
elsif cmdSwitch>=0 && command==cmdSwitch
@scene.pbSetHelpText(_INTL("Move to where?"))
oldpkmnid=pkmnid
[email protected](true)
if pkmnid>=0 && pkmnid!=oldpkmnid
pbSwitch(oldpkmnid,pkmnid)
Also in PokemonParty, replace pbPokemonGiveScreen(item) with this
Code:
def pbPokemonGiveScreen(item)
@scene.pbStartScene(@party,_INTL("Give to which Pokémon?"))
[email protected]
ret=false
if pkmnid>=0
ret=pbGiveMail(item,@party[pkmnid],pkmnid)
end
pbRefreshSingle(pkmnid)
$PokemonTemp.dependentEvents.refresh_sprite
@scene.pbEndScene
return ret
end
In Game_Player_, add
Code:
$PokemonTemp.dependentEvents.add_following_time
Code:
$PokemonTemp.dependentEvents.updateDependentEvents
In PokeBattle_ActualScene, replace pbEndBattle with
Code:
def pbEndBattle(result)
@abortable=false
pbShowWindow(BLANK)
# Fade out all sprites
$PokemonTemp.dependentEvents.check_faint
pbBGMFade(1.0)
pbFadeOutAndHide(@sprites)
pbDisposeSprites
end
In PokemonField, add this above kernel.pbReceiveItem
Code:
def Kernel.pbPokemonFound(item,quantity=1,plural=nil)
itemname=PBItems.getName(item)
pocket=pbGetPocket(item)
e=$Trainer.party[0].name
if $PokemonBag.pbStoreItem(item,quantity)
pbWait(5)
if $ItemData[item][ITEMUSE]==3 || $ItemData[item][ITEMUSE]==4
Kernel.pbMessage(_INTL("\\se[]{1} found {2}!\\se[itemlevel]\\nIt contained {3}.\\wtnp[30]",e,itemname,PBMoves.getName($ItemData[item][ITEMMACHINE])))
Kernel.pbMessage(_INTL("{1} put the {2}\r\nin the {3} Pocket.",$Trainer.name,itemname,PokemonBag.pocketNames()[pocket]))
elsif isConst?(item,PBItems,:LEFTOVERS)
Kernel.pbMessage(_INTL("\\se[]{1} found some {2}!\\se[itemlevel]\\wtnp[30]",e,itemname))
Kernel.pbMessage(_INTL("{1} put the {2}\r\nin the {3} Pocket.",$Trainer.name,itemname,PokemonBag.pocketNames()[pocket]))
else
if quantity>1
if plural
Kernel.pbMessage(_INTL("\\se[]{1} found {2} {3}!\\se[itemlevel]\\wtnp[30]",e,quantity,plural))
Kernel.pbMessage(_INTL("{1} put the {2}\r\nin the {3} Pocket.",$Trainer.name,plural,PokemonBag.pocketNames()[pocket]))
else
Kernel.pbMessage(_INTL("\\se[]{1} found {2} {3}s!\\se[itemlevel]\\wtnp[30]",e,quantity,itemname))
Kernel.pbMessage(_INTL("{1} put the {2}s\r\nin the {3} Pocket.",$Trainer.name,itemname,PokemonBag.pocketNames()[pocket]))
end
else
Kernel.pbMessage(_INTL("\\se[]{1} found one {2}!\\se[itemlevel]\\wtnp[30]",e,itemname))
Kernel.pbMessage(_INTL("{1} put the {2}\r\nin the {3} Pocket.",$Trainer.name,itemname,PokemonBag.pocketNames()[pocket]))
end
end
return true
else # Can't add the item
if $ItemData[item][ITEMUSE]==3 || $ItemData[item][ITEMUSE]==4
Kernel.pbMessage(_INTL("{1} found {2}!\\wtnp[20]",e,itemname))
elsif isConst?(item,PBItems,:LEFTOVERS)
Kernel.pbMessage(_INTL("{1} found some {2}!\\wtnp[20]",$Trainer.name,itemname))
else
if quantity>1
if plural
Kernel.pbMessage(_INTL("{1} found {2} {3}!\\wtnp[20]",e,quantity,plural))
else
Kernel.pbMessage(_INTL("{1} found {2} {3}s!\\wtnp[20]",$Trainer.name,quantity,itemname))
end
else
Kernel.pbMessage(_INTL("{1} found one {2}!\\wtnp[20]",e,itemname))
end
end
Kernel.pbMessage(_INTL("Too bad... The Bag is full..."))
return false
end
end
In Scene_Map, after
Code:
if Input.trigger?(Input::B)
unless pbMapInterpreterRunning? or $game_system.menu_disabled or $game_player.moving?
$game_temp.menu_calling = true
$game_temp.menu_beep = true
end
end
Code:
if Input.trigger?(Input::X) && $Trainer.party.size > 1
$Trainer.party.push($Trainer.party.delete_at(0))
$PokemonTemp.dependentEvents.refresh_sprite if $game_switches[Toggle_Following_Switch]==true
end
if Input.trigger?(Input::Z) && $Trainer.party.size > 1
$Trainer.party.insert(0,$Trainer.party.pop)
$PokemonTemp.dependentEvents.refresh_sprite if $game_switches[Toggle_Following_Switch]==true
end
In PokemonSystem, replace module input with this. You can change (CTRL) to a key of your liking. This will be the key that toggles following pokemon on and off. If you don't want the player to be able to toggle their Pokemon on and off, skip this step.
Code:
module Input
unless defined?(update_KGC_ScreenCapture)
class << Input
alias update_KGC_ScreenCapture update
end
end
def self.update
update_KGC_ScreenCapture
if trigger?(Input::F8)
pbScreenCapture
end
if trigger?(Input::F7)
pbDebugF7
end
if trigger?(Input::CTRL) # Added Toggle Following Pokemon
pbToggleFollowingPokemon
end
end
end
In Interpreter, replace def command_end with
Code:
def command_end
# Clear list of event commands
@list = nil
# If main map event and event ID are valid
if @main && @event_id > 0 && !($game_map.events[@event_id] && $game_map.events[@event_id].name=="Dependent")
# Unlock event
$game_map.events[@event_id].unlock if $game_map.events[@event_id]
end
end
Other Installations
In the Database click on the "Common Events" tab and go to the Common Event you have listed in settings from earlier. Name this common event "TalkToPokemon", with no Trigger, and in the event have the script
Code:
$PokemonTemp.dependentEvents.talk_to_pokemon
Next you need to download the following animations and put them in Graphics/Animations.
Then download the animations data and put it in your Data Folder. This will not mess up any attack animations added through the animation editor as attack animations don't use the Database anymore.
You will also need to find sprites for the Pokemon Followers. These can be found on google pretty easily. If anyone has a link and can post it here I will add it to this post. These sprites should be called 001,001s,002,002s,etc, etc, etc. They go in the Graphics/Characters folder. The "s" means shiny. We are still working on adding multiple forms support.
How to use the Script
Alright. So this is a lot of information to take in at once, especially if you have zero scripting knowledge. As long as you followed these instructions perfectly, and I haven't forgotten anything, your game should load without any errors. Now, to call the script use:
Code:
pbPokemonFollow(x)
Note that the event that becomes the follower will no longer function as it should. You should use a blank event called "Dependent" for the follower, and have the script activated through a different event.
Whenever there is a Pokemon healing event, put
Code:
$PokemonTemp.dependentEvents.remove_sprite(true)
Code:
$PokemonTemp.dependentEvents.refresh_sprite
When you have a healing event that runs when "Starting Over" is running, you need to do something different. You need to put a new blank event called "Dependent" right next to where the player will spawn after losing the battle, and in the auto running "Starting Over" event, after healing the Pokemon, you need to use
Code:
pbPokemonFollow(x)
Other Features
The script is set up so it is user friendly and easy to edit. If you have scripting knowledge, you should be able to figure out how to add new messages for the Pokemon to say for different situations, and how to make the follower sprite move around through scripting. If you don't have any scripting knowledges, feel free to post here asking for help :)
Also, as of Version 1.3, you can now animate other Events in the game so they are constantly moving like your follower. Just call
Code:
pbPokeStep
Bug Fixing
If you follow all these steps and get an error that looks like this
Spoiler:
Exception: RuntimeError
Message: Script error within event 36, map 7 (Pokémon Lab):
Exception: NoMethodError
Message: Section002:123:in `effect?'undefined method `>' for nil:NilClass
***Full script:
pbPokemonFollow(36)
Interpreter:243:in `pbExecuteScript'
RPG__Sprite:433:in `effect?'
RPG__Sprite:432:in `each'
RPG__Sprite:432:in `effect?'
AnimationSprite:29:in `update'
AnimationSprite:86:in `update'
AnimationSprite:85:in `each'
AnimationSprite:85:in `update'
Scene_Map:51:in `updateSpritesets'
Scene_Map:45:in `each'
Interpreter:276:in `pbExecuteScript'
Interpreter:1600:in `command_355'
Interpreter:494:in `execute_command'
Interpreter:193:in `update'
Interpreter:106:in `loop'
Interpreter:198:in `update'
Scene_Map:103:in `update'
Scene_Map:101:in `loop'
Scene_Map:114:in `update'
Scene_Map:68:in `main'
This exception was logged in
C:\Users\Seth\Saved Games/Pokémon Litharreon/errorlog.txt.
Press Ctrl+C to copy this message to the clipboard.
---------------------------
OK
---------------------------
Message: Script error within event 36, map 7 (Pokémon Lab):
Exception: NoMethodError
Message: Section002:123:in `effect?'undefined method `>' for nil:NilClass
***Full script:
pbPokemonFollow(36)
Interpreter:243:in `pbExecuteScript'
RPG__Sprite:433:in `effect?'
RPG__Sprite:432:in `each'
RPG__Sprite:432:in `effect?'
AnimationSprite:29:in `update'
AnimationSprite:86:in `update'
AnimationSprite:85:in `each'
AnimationSprite:85:in `update'
Scene_Map:51:in `updateSpritesets'
Scene_Map:45:in `each'
Interpreter:276:in `pbExecuteScript'
Interpreter:1600:in `command_355'
Interpreter:494:in `execute_command'
Interpreter:193:in `update'
Interpreter:106:in `loop'
Interpreter:198:in `update'
Scene_Map:103:in `update'
Scene_Map:101:in `loop'
Scene_Map:114:in `update'
Scene_Map:68:in `main'
This exception was logged in
C:\Users\Seth\Saved Games/Pokémon Litharreon/errorlog.txt.
Press Ctrl+C to copy this message to the clipboard.
---------------------------
OK
---------------------------
you need to delete your saved data, and then replace the Animations data file again with the download I have above. (Just the part that goes in the Data Folder) Start a new game and the issue should be resolved.
Last edited: