• 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.
  • The Eevee Expo Game Jam has concluded! 🎉 Head on over to the game jam forum to play through the games.
    Don't forget to come back September 21st to vote for your favorites!
  • Reminder: AI-generated content is not allowed on the forums per the Rules and Regulations. Please contact us if you have any questions!
Character switch mechanism

v21.1 Character switch mechanism 1.0

This resource pertains to version 21.1 of Pokémon Essentials.
Pokémon Essentials Version
v21.1 ✅
This system basically allows you to play the game as two trainers, both with their separate teams and the ability to switch which one you control. This can be useful for example to create scenarios, where you'd play as someone else; either solo, or in a team along with the original trainer.
I will provide the entire script and setup here, but on this google drive it's much more organized: Drive
If set up correctly, it should work like this: Video on Reddit

Current features:
  1. Switch player and partner trainer freely, anywhere (except while surfing) in the game
  2. Own set of parties, each gain exp and EVs during battle
  3. Can send them away and tell them to follow you
  4. Shared inventory
  5. Shared PC
To-do list:
  1. Enable the use of Surf
  2. Create a “Wait here” function
  3. Check bike functionality
PBS Edits:
trainer_types
#-------------------------------
[POKEMONTRAINER_Red]
Name = Pokémon Trainer
Gender = Male
BaseMoney = 60
#-------------------------------
[POKEMONTRAINER_Leaf]
Name = Pokémon Trainer
Gender = Female
BaseMoney = 60
#-------------------------------
[POKEMONTRAINER_Brendan]
Name = Pokémon Trainer
Gender = Male
BaseMoney = 60
#-------------------------------
[POKEMONTRAINER_May]
Name = Pokémon Trainer
Gender = Female
BaseMoney = 60
#-------------------------------

trainers
#-------------------------------
[POKEMONTRAINER_May,May]
LoseText = ...
Pokemon = COMBUSKEN,19
#-------------------------------
[POKEMONTRAINER_Leaf,Leaf]
LoseText = ...
Pokemon = COMBUSKEN,19
#-------------------------------
[POKEMONTRAINER_Red,Red]
LoseText = ...
Pokemon = COMBUSKEN,19
#-------------------------------
[POKEMONTRAINER_Brendan,Brendan]
LoseText = ...
Pokemon = COMBUSKEN,19
#-------------------------------

metadata
#-------------------------------
[1]
TrainerType = POKEMONTRAINER_Red
WalkCharset = trainer_POKEMONTRAINER_Red
RunCharset = boy_run
CycleCharset = boy_bike
SurfCharset = boy_surf
DiveCharset = boy_surf
FishCharset = boy_fish_offset
SurfFishCharset = boy_fish_offset
#-------------------------------
[2]
TrainerType = POKEMONTRAINER_Leaf
WalkCharset = trainer_POKEMONTRAINER_Leaf
RunCharset = girl_run
CycleCharset = girl_bike
SurfCharset = girl_surf
DiveCharset = girl_surf
FishCharset = girl_fish_offset
SurfFishCharset = girl_fish_offset
#-------------------------------
[3]
TrainerType = POKEMONTRAINER_Brendan
WalkCharset = trainer_POKEMONTRAINER_Brendan
RunCharset = boy_run
CycleCharset = boy_bike
SurfCharset = boy_surf
DiveCharset = boy_surf
FishCharset = boy_fish_offset
SurfFishCharset = boy_fish_offset
#-------------------------------
[4]
TrainerType = POKEMONTRAINER_May
WalkCharset = trainer_POKEMONTRAINER_May
RunCharset = girl_run
CycleCharset = girl_bike
SurfCharset = girl_surf
DiveCharset = girl_surf
FishCharset = girl_fish_offset
SurfFishCharset = girl_fish_offset

NOTE: Brendan and May don’t have their special charsets in the default pokemon essentials sprite list, so when they’re the player characters and start running, their sprites will switch to Red or Leaf while running. (if you have the sprites, rename the charset names to match your sprite names)
When they’re only the follower, their walking animation speeds up into a goofy powerwalk

SETUP:

1: Intro
Branches right as you choose player gender:
  1. When boy: Control Switch [switch id: BOY] = ON
  2. pbChangePlayer(1)
  3. Insert the “enter name” sequence
  4. Select Partner gender:
    1. Show Choices: Boy, Girl
    2. When: Boy
    3. pbChangePlayer(3)
    4. pbSet(22,pbEnterPlayerName(_INTL("Your partner's name?"),0,7))
    5. pbChangePlayer(1)
    6. Control Switch [switch id: BROTHER] = ON
    7. When: Girl
    8. pbChangePlayer(4)
    9. pbSet(22,pbEnterPlayerName(_INTL("Your partner's name?"),0,7))
    10. pbChangePlayer(1)
    11. Control Switch [switch id: SISTER] = ON
  5. When girl: Control Switch [switch id: GIRL] = ON
  6. pbChangePlayer(2)
  7. Insert the “enter name” sequence
  8. Select Partner gender:
    1. Show Choices: Boy, Girl
    2. When: Boy
    3. pbChangePlayer(3)
    4. pbSet(22,pbEnterPlayerName(_INTL("Your partner's name?"),0,7))
    5. pbChangePlayer(1)
    6. Control Switch [switch id: BROTHER] = ON
    7. When: Girl
    8. pbChangePlayer(4)
    9. pbSet(22,pbEnterPlayerName(_INTL("Your partner's name?"),0,7))
    10. pbChangePlayer(2)
    11. Control Switch [switch id: SISTER] = ON
  9. The rest of the intro plays out as you want
  10. Control Switch [switch id: NEW GAME DONE] = ON

After the Intro create an event that triggers when [switch id: NEW GAME DONE] = ON
Event Page1:
  1. pbSet(21, $player.name)
  2. Control Self Switch [A] = ON
Event Page 2: Triggers when Self Switch [A] = ON
  1. Blank page
(This is necessary to set the player name into variable 21, as you cannot do it until the player is initialized.)
(Feel free to change the variables’ numbers as you’d like)

2: First Character Change
Create your event for getting your starter Pokemon (I used the gen1 starters)
Then set up 4 events:
  1. for the male partner,
  2. for the female partner.
  3. and 4.: The other 2 will be invisible dummy events using the player sprites (place these to an edge of the map, choose the sprite, set opacity to 0, and leave the event page blank).
  • Choose the sprites you wish them to use (and change the sprite name in your script sheet accordingly. I used the default trchar000-003 files (Originals: Red, Leaf; Partners: Brendan, May)
  • The events will have the exact same basic setup structure
You’ll need to create 4 common events too, details about that on the next page
Female partner: activates when: [switch id: SISTER] = ON (optionally triggers after you get your starter)
Male partner: activates when: [switch id: BROTHER] = ON (optionally triggers after you get your starter)
Rest of their setup is the same:
You will need 3 event pages:
  1. is active when Switch [switch id: BOY] = ON
  2. is active when Switch [switch id: GIRL] = ON
  3. is active when Switch [switch id: FirstChangeClear] = ON
Male partner:
  1. pbBecomeBrendanFirst
    toggleLeaderName
    pbREGISTERERRedBrendan
    Control Switch [switch id: First Clear] = ON
  2. pbBecomeBrendanFirst
    toggleLeaderName
    pbREGISTERERLeafBrendan
    Control Switch [switch id: First Clear] = ON
  3. blank
Female partner:
  1. pbBecomeMayFirst
    toggleLeaderName
    pbREGISTERERRedMay
    Control Switch [switch id: First Clear] = ON
  2. pbBecomeMayFirst
    toggleLeaderName
    pbREGISTERERLeafMay
    Control Switch [switch id: First Clear] = ON
  3. blank

This is necessary to initialize the partner’s team. From this on, you’ll be able to switch freely between the 2 characters (you need to set up the common events too first!!)

3: Common Events
2 for the players: Boy - Girl
2 for the partners: Boy - Girl

Both player events have the exact same setup, except for the different pbSWAPPER and switches when discarding them.
And both partner events have the exact same setup, except for the different pbSWAPPER and switches when discarding them

Player Dependent Events:
Show Choices: Change Leader, Follower, Nothing
  1. When: [Change Leader]
    Conditional Branch: Switch [switch id: BROTHER] = ON
    1. pbSWAPPERRedBrendan (Or pbSWAPPERLeafBrendan when girl player)
      else
    2. pbSWAPPERRedMay (Or pbSWAPPERLeafMay when girl player)
      Branch End
  2. When: [Follower]
    1. pbDEREGISTERER
    2. Control Switch [switch id: Red Party] = Off
      Control Switch [switch id: Leaf Party] = Off (when girl player)
    3. Control Switch [switch id: Red Event On ] = ON
      Control Switch [switch id: Leaf Event On ] = ON (when girl player)
  3. When: [Nothing]
    1. blank


Partner Dependent Events:
Show Choices: Change Leader, Follower, Nothing
  1. When: [Change Leader]
    Conditional Branch: Switch [switch id: BOY] = ON
    1. pbSWAPPERRedBrendan (Or pbSWAPPERRedMay when girl partner)
      else
    2. pbSWAPPERLeafBrendan (Or pbSWAPPERLeafMay when girl player)
      Branch End
  2. When: [Follower]
    1. pbDEREGISTERER
    2. Control Switch [switch id: Partner Party] = Off
  3. When: [Nothing]
    1. blank

Change the common event IDs in the script to the correct numbers you got in all Followers.add_sprite instances
(Followers.add_sprite(“sprite file name”, pbGet(name variable), common event ID)

After setting these common events up, you’ll really be able to switch between characters freely now. But you won’t be able to discard them just yet!

4: Inactive Follower Events
2 for the players: Boy - Girl
2 for the partners: Boy - Girl

Player events:
3 Pages each:
  1. Active when:
    Switch [switch id: Red Event On ] = ON
    Switch [switch id: Leaf Event On ] = ON (when girl player)
    Switch [switch id: BROTHER] = ON
  2. Active when:
    Switch [switch id: Red Event On ] = ON
    Switch [switch id: Leaf Event On ] = ON (when girl player)
    Switch [switch id: SISTER] = ON
  3. Active when:
    Switch [switch id: Red Party] = ON
    Switch [switch id: Leaf Party] = ON (when girl player)
Event setup: (use respective player sprites)
Page 1:
  1. pbREGISTERERRedBrendan
    pbREGISTERERLeafBrendan (when girl player)
  2. Control Switch [switch id: Red Party] = ON
    Control Switch [switch id: Leaf Party] = ON (when girl player)
Page 2:
  1. pbREGISTERERRedMay
    pbREGISTERERLeafMay (when girl player)
  2. Control Switch [switch id: Red Party] = ON
    Control Switch [switch id: Leaf Party] = ON (when girl player)
Page 3: blank
Partner events:
3 Pages each:
  1. Active when:
    Switch [switch id: FirstChangeClear] = ON
    Switch [switch id: BOY] = ON
  2. Active when:
    Switch [switch id: FirstChangeClear] = ON
    Switch [switch id: GIRL] = ON
  3. Active when:
    Switch [switch id: Partner Party] = ON
Event setup: (use respective partner sprites)
Page 1:
  1. pbREGISTERERRedBrendan (pbREGISTERERRedMay when female partner)
  2. Control Switch [switch id: Partner Party] = ON
Page 2:
  1. pbREGISTERERLeafBrendan (pbREGISTERERLeafMay when female partner)
  2. Control Switch [switch id: Partner Party] = ON
With these events also done, your setup is complete.

SCRIPTS:
Follower module (Copy content into new script page):
module Followers
def self.add_sprite(sprite_name, name, common_event_id = nil)
event_id = 99 # Reserve this ID for dynamic followers
return if $game_map.events[event_id] # Prevent duplicates

# Create a new RPG::Event and configure it
new_event = RPG::Event.new(0, 0)
new_event.id = event_id
page = RPG::Event::Page.new
page.graphic.character_name = sprite_name
page.graphic.character_hue = 0
page.graphic.direction = 2
page.graphic.pattern = 1
page.move_type = 0
page.trigger = 4 # Parallel Process or Action Button
new_event.pages << page

# Add the event to the current map
game_event = Game_Event.new($game_map.map_id, new_event)
$game_map.events[event_id] = game_event

# Register it as a follower like usual
self.add(event_id, name, common_event_id)
end
end

Modification of Original Script:
It is coded into the original Pokemon Essentials script, that when you battle along a partner trainer, your pokemon are fully restored after each battle.
This is not what we want, so we need to modify the original script a bit.
In the script section: Overworld_BattleStarting
Find this part:
if $PokemonGlobal.partner
$player.heal_party
$PokemonGlobal.partner[3].each do |pkmn|
pkmn.heal
pkmn.makeUnmega
pkmn.makeUnprimal
end
end
And change it to this:
# if $PokemonGlobal.partner
# $player.heal_party
# $PokemonGlobal.partner[3].each do |pkmn|
# pkmn.heal
# pkmn.makeUnmega
# pkmn.makeUnprimal
# end
# end

This makes this script part just comments, so in case you want to revert to its original functionality, you can just remove the # and it will work again.

And now, for the mechanism itself:

Player Switch (Copy content into new script page):
$PokemonTemp ||= {}
$PokemonTemp[:original_party] ||= nil
$PokemonTemp[:partner_party] ||= nil

def pbBecomeMayFirst
[imath]PokemonTemp[:original_party] =[/imath]player.party.map(&:clone)
pbChangePlayer(4)
starter = $player.party[0].species
new_species =
case starter
when :BULBASAUR then :CHARMANDER
when :CHARMANDER then :SQUIRTLE
when :SQUIRTLE then :BULBASAUR
else starter
end
$player.party.clear
$player.party.push(Pokemon.new(new_species, 5))
end

def pbBecomeBrendanFirst
[imath]PokemonTemp[:original_party] =[/imath]player.party.map(&:clone)
pbChangePlayer(3)
starter = $player.party[0].species
new_species =
case starter
when :BULBASAUR then :CHARMANDER
when :CHARMANDER then :SQUIRTLE
when :SQUIRTLE then :BULBASAUR
else starter
end
$player.party.clear
$player.party.push(Pokemon.new(new_species, 5))
end

def pbBecomeMay
[imath]PokemonTemp[:original_party] =[/imath]player.party.map(&:clone)
if [imath]PokemonGlobal.partner &&[/imath]PokemonGlobal.partner[3]
[imath]PokemonTemp[:partner_party] =[/imath]PokemonGlobal.partner[3].map(&:clone)
end
pbChangePlayer(4)
if [imath]PokemonGlobal.partner &&[/imath]PokemonGlobal.partner[3]
[imath]player.party =[/imath]PokemonGlobal.partner[3].map(&:clone)
end
$player.party.each do |pkmn|
next unless pkmn
pkmn.owner = Pokemon::Owner.new_from_trainer($player)
end
end

def pbBecomeBrendan
[imath]PokemonTemp[:original_party] =[/imath]player.party.map(&:clone)
if [imath]PokemonGlobal.partner &&[/imath]PokemonGlobal.partner[3]
[imath]PokemonTemp[:partner_party] =[/imath]PokemonGlobal.partner[3].map(&:clone)
end
pbChangePlayer(3)
if [imath]PokemonGlobal.partner &&[/imath]PokemonGlobal.partner[3]
[imath]player.party =[/imath]PokemonGlobal.partner[3].map(&:clone)
end
$player.party.each do |pkmn|
next unless pkmn
pkmn.owner = Pokemon::Owner.new_from_trainer($player)
end
end

def pbTurnBackToRed
[imath]PokemonTemp[:partner_party] =[/imath]player.party.map(&:clone)
if [imath]PokemonGlobal.partner &&[/imath]PokemonGlobal.partner[3]
[imath]PokemonTemp[:original_party] =[/imath]PokemonGlobal.partner[3].map(&:clone)
end
pbChangePlayer(1)
[imath]player.party =[/imath]PokemonTemp[:original_party].map(&:clone)
$player.party.each do |pkmn|
next unless pkmn
pkmn.owner = Pokemon::Owner.new_from_trainer($player)
end
[imath]PokemonGlobal.partner[3] =[/imath]PokemonTemp[:partner_party].map(&:clone)
end

def pbTurnBackToLeaf
[imath]PokemonTemp[:partner_party] =[/imath]player.party.map(&:clone)
if [imath]PokemonGlobal.partner &&[/imath]PokemonGlobal.partner[3]
[imath]PokemonTemp[:original_party] =[/imath]PokemonGlobal.partner[3].map(&:clone)
end
pbChangePlayer(2)
[imath]player.party =[/imath]PokemonTemp[:original_party].map(&:clone)
$player.party.each do |pkmn|
next unless pkmn
pkmn.owner = Pokemon::Owner.new_from_trainer($player)
end
[imath]PokemonGlobal.partner[3] =[/imath]PokemonTemp[:partner_party].map(&:clone)
end

def toggleLeaderName
if $player.name == pbGet(21)
$player.name = pbGet(22)
else
$player.name = pbGet(21)
end
end

def pbDEREGISTERER
if $player.name == pbGet(21)
Followers.remove(pbGet(22))
pbDeregisterPartner
$game_map.events.delete(99)
elsif $player.name == pbGet(22)
Followers.remove(pbGet(21))
pbDeregisterPartner
$game_map.events.delete(99)
else
pbMessage ("Nobody to send away")
end
end

def pbREGISTERERLeafMay
if $player.name == pbGet(21)
Followers.add_sprite("trchar003", pbGet(22), 5)
pbRegisterMayFromClone (pbGet(22))
elsif $player.name == pbGet(22)
Followers.add_sprite("trchar001", pbGet(21), 4)
pbRegisterLeafFromClone (pbGet(21))
else
pbMessage ("Nobody to swap with")
end
end

def pbREGISTERERLeafBrendan
if $player.name == pbGet(21)
Followers.add_sprite("trchar002", pbGet(22), 9)
pbRegisterBrendanFromClone (pbGet(22))
elsif $player.name == pbGet(22)
Followers.add_sprite("trchar001", pbGet(21), 4)
pbRegisterLeafFromClone (pbGet(21))
else
pbMessage ("Nobody to swap with")
end
end

def pbREGISTERERRedMay
if $player.name == pbGet(21)
Followers.add_sprite("trchar003", pbGet(22), 5)
pbRegisterMayFromClone (pbGet(22))
elsif $player.name == pbGet(22)
Followers.add_sprite("trchar000", pbGet(21), 8)
pbRegisterRedFromClone (pbGet(21))
else
pbMessage ("Nobody to swap with")
end
end

def pbREGISTERERRedBrendan
if $player.name == pbGet(21)
Followers.add_sprite("trchar002", pbGet(22), 9)
pbRegisterBrendanFromClone (pbGet(22))
elsif $player.name == pbGet(22)
Followers.add_sprite("trchar000", pbGet(21), 8)
pbRegisterRedFromClone (pbGet(21))
else
pbMessage ("Nobody to swap with")
end
end

def pbSWAPPERLeafMay
if $player.name == pbGet(21)
pbBecomeMay
pbDEREGISTERER
toggleLeaderName
pbREGISTERERLeafMay
else
pbTurnBackToLeaf
pbDEREGISTERER
toggleLeaderName
pbREGISTERERLeafMay
end
end

def pbSWAPPERLeafBrendan
if $player.name == pbGet(21)
pbBecomeBrendan
pbDEREGISTERER
toggleLeaderName
pbREGISTERERLeafBrendan
else
pbTurnBackToLeaf
pbDEREGISTERER
toggleLeaderName
pbREGISTERERLeafBrendan
end
end

def pbSWAPPERRedMay
if $player.name == pbGet(21)
pbBecomeMay
pbDEREGISTERER
toggleLeaderName
pbREGISTERERRedMay
else
pbTurnBackToRed
pbDEREGISTERER
toggleLeaderName
pbREGISTERERRedMay
end
end

def pbSWAPPERRedBrendan
if $player.name == pbGet(21)
pbBecomeBrendan
pbDEREGISTERER
toggleLeaderName
pbREGISTERERRedBrendan
else
pbTurnBackToRed
pbDEREGISTERER
toggleLeaderName
pbREGISTERERRedBrendan
end
end

def pbRegisterPartnerFromClone(tr_name, trainer_type_symbol)
return unless [imath]PokemonTemp[:partner_party] && ![/imath]PokemonTemp[:partner_party].empty?
trainer = NPCTrainer.new(tr_name, trainer_type_symbol)
trainer.id = $player.make_foreign_ID
trainer.items = []
trainer.lose_text = "I'll try better next time!"
$PokemonTemp[:partner_party].each do |pkmn|
next if !pkmn
new_pokemon = Marshal.load(Marshal.dump(pkmn))
new_pokemon.owner = Pokemon::Owner.new_from_trainer(trainer)
new_pokemon.calc_stats
trainer.party << new_pokemon
end
EventHandlers.trigger(:on_trainer_load, trainer)
trainer.party.each { |p| p.owner = Pokemon::Owner.new_from_trainer(trainer) }
$PokemonGlobal.partner = [trainer_type_symbol, tr_name, trainer.id, trainer.party]
end

def pbRegisterOriginalFromClone(tr_name, trainer_type_symbol)
return unless [imath]PokemonTemp[:original_party] && ![/imath]PokemonTemp[:original_party].empty?
trainer = NPCTrainer.new(tr_name, trainer_type_symbol)
trainer.id = $player.make_foreign_ID
trainer.items = []
trainer.lose_text = "I'll try better next time!"
$PokemonTemp[:original_party].each do |pkmn|
next if !pkmn
new_pokemon = Marshal.load(Marshal.dump(pkmn))
new_pokemon.owner = Pokemon::Owner.new_from_trainer(trainer)
new_pokemon.calc_stats
trainer.party << new_pokemon
end
EventHandlers.trigger(:on_trainer_load, trainer)
trainer.party.each { |p| p.owner = Pokemon::Owner.new_from_trainer(trainer) }
$PokemonGlobal.partner = [trainer_type_symbol, tr_name, trainer.id, trainer.party]
end

def pbRegisterMayFromClone(tr_name)
pbRegisterPartnerFromClone(tr_name, :POKEMONTRAINER_May)
end

def pbRegisterBrendanFromClone(tr_name)
pbRegisterPartnerFromClone(tr_name, :POKEMONTRAINER_Brendan)
end

def pbRegisterLeafFromClone(tr_name)
pbRegisterOriginalFromClone(tr_name, :POKEMONTRAINER_Leaf)
end

def pbRegisterRedFromClone(tr_name)
pbRegisterOriginalFromClone(tr_name, :POKEMONTRAINER_Red)
end
Credits
Credit is not necessary
  • Like
Reactions: drawntoast
Author
bSeb13
Views
141
First release
Last update

Ratings

0.00 star(s) 0 ratings
Back
Top