Partner Following

From PMDOWiki

Want your partner to follow you around in the overworld? It'll take some scripting work as well as map editor work to achieve this. Let's start with the map editor.

You'll need to place down a spawner that the script will use to spawn in your partner. You can do this in the Entities tab, and choosing an object type of spawner. Let's work with the assumption that your partner will be whoever is in slot 2 of your party. In such a case, we'll call the spawner TEAMMATE_1 and the entity it spawns Teammate1, as seen below.


Place the spawner wherever in the map you want the partner to spawn in. You can also set the default direction they spawn in as by changing the direction of the spawner. Once this is done, save your map changes. It's now time to make changes to the init script for the ground so the game knows what to do with that spawner.

Open up your init script and look at the Init callback function. Here, you'll need to add several functions related to spawning in and setting up your partner.

You'll need to start with calling COMMON.RespawnAllies(). This will call the spawner you made earlier. From here, you'll need to set up your partner's data and AI. You can do this with the following commands:

local partner = CH('Teammate1')
AI:SetcharacterAI(partner, 'ai.ground_partner', CH('PLAYER'), partner.Position)
partner.CollisionDisabled = true

This will initialize the ground character you spawned in (known internally as 'Teammate1') with the partner following AI, targeted at following the player character. Then, it'll disable their collision, as otherwise you'll get stuck on them constantly.

Assuming your init script was fresh before starting, it'll look something like this afterwards:

function YourGroundName.Init(map)
  MapStrings = COMMON.AutoLoadLocalizedStrings()
  COMMON.RespawnAllies()
  local partner = CH('Teammate1')
  AI:SetcharacterAI(partner, 'ai.ground_partner', CH('PLAYER'), partner.Position)
  partner.CollisionDisabled = true
end

Now, whenever the map loads, the character in slot 2 of the party will follow you around that map! You'll need to set this up for every map you want the partner to follow you around in.


What if the player/partner isn't in the party, but I want them to be the overworld Pokemon?

To do this, you'll have to set things up a bit differently. You'll want to call your spawner PARTNER_SPAWN and have the spawned entity called "Partner", as seen below.


Next, you'll need to adjust the values in Scriptvars's test_grounds data to be the player/partner you want. You'll see in the screenshot below variables that correspond to the player/partner's appearance.

-Species = lower case string of the species of Pokemon. -Form = The number for the form of the mon. This should be 0, unless you want to use a non default form of a pokemon (for example, Hisuian Zorua). Then, you need to change that to the number that corresponds to that form, which you can figure out with the dropdown in dev menu's Player tab. Just make sure you have the correct species selected first. -skin = should be "normal" or "shiny", but can be other things if your mod includes additional skin types -Gender = Set to 0 for Genderless, 1 for male, and 2 for female.

You'll do the rest of this the same as before, but you'll replace the COMMON.RespawnAllies call with COMMON.RespawnStarterPartner(). Additionally, you'll need to refer to the partner as "Partner" rather than "Teammate1". So you'll end up with:


function YourGroundName.Init(map)
  MapStrings = COMMON.AutoLoadLocalizedStrings()
  COMMON.RespawnStarterPartner()
  local partner = CH('Partner')
  AI:SetcharacterAI(partner, 'ai.ground_partner', CH('PLAYER'), partner.Position)
  partner.CollisionDisabled = true
end

And presto, even though my party consists of the Kanto starters, in the overworld I am a Pikachu and an Eevee.

Of course, you're free to reimplement these functions to better suit your needs (or to have variables with better names), but the quick and dirty way is to reuse the functions provided by base PMDO's COMMON functionality as described above. Just be sure to read the code for the functions you're using above to get a grasp of how they work first.



What if my map has multiple entrances?

The partner can only spawn in one place, and that's where the spawner is placed on the map. If you want them to appear next to you when you enter a hub world map from one of its many entrances, you'll need to add logic that gets triggered in the Enter callback for that map that teleports them to the player's side while the game is still faded out. You can do this in a number of ways, but one such way would be to have a variable get updated when leaving one map and going to the map with multiple entrances that lets the multiple entrance map's script know where to teleport the partner to.

For example, Halcyon has a system for this where a variable keeps track of the marker to teleport the partner to on the next map when a different map is exited. The partner gets teleported to this marker when the new map loads but before it fades in. The object responsible for map transitions on the different maps is what needs to update this variable, mind you, so if you want to see an example of this, be sure to check those map transition objects.

My partner doesn't spawn behind me when I save and reload! Why?

The ground map by default doesn't discriminate between loading in via a map transition or loading in via loading a saved game. You'll need to introduce your own logic to handle this. One such way is adding a function to the GameSave callback that saves to Scriptvars the position and direction of the partner. Then, add another function to the GameLoad callback that teleports the partner to the position and direction that was saved earlier. Halcyon has an example of this you can look at or reuse if you'd like.