SHARE
TWEET

Multiple Protagonists

NettoHikari1131 Feb 8th, 2019 (edited) 708 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ################################################################################
  2. # Multiple Protagonists v1.4
  3. # by NettoHikari
  4. #
  5. # May 20, 2019
  6. #
  7. # This script allows the player to have up to 8 main characters, each with their
  8. # own Pokemon parties, PC and Item storages, Trainer data, etc. It is intended
  9. # for use in games where at least 2 playable characters are introduced
  10. # throughout the story, no matter how significant each protagonist is.
  11. #
  12. # Credits MUST BE GIVEN to NettoHikari
  13. # You should also credit the authors of Pokemon Essentials itself.
  14. #
  15. #-------------------------------------------------------------------------------
  16. # INSTALLATION
  17. #-------------------------------------------------------------------------------
  18. # Copy this script, place it somewhere between "Compiler" and "Main" in the
  19. # script sections, and name it "MultipleProtagonists". In addition, make sure to
  20. # define all of your playable characters in the Global Metadata (found under
  21. # "PBS/metadata.txt" in your game folder), starting with PlayerA (PlayerH is
  22. # the max).
  23. #
  24. # Before using this script, make sure to start a new save file when testing.
  25. # Since it adds new stored data, the script will probably throw errors when used
  26. # with saves where the script wasn't present before. In addition, if you decide
  27. # to release your game in segments, it is important to have this script
  28. # installed in the very first version itself, so as not to cause any problems to
  29. # the player.
  30. #
  31. # To install the "Switch" character command in the pause menu, follow the
  32. # instructions below.
  33. #
  34. # You will need to paste the following code into the section "PScreen_PauseMenu"
  35. # at the appropriate lines (all of which are under "def pbStartPokemonMenu").
  36. # Ignore the suggested line numbers below and just find each line with
  37. # CTRL + Shift + F if you already made your own edits to the script before.
  38. #
  39. # 1. You'll need to start by defining a variable for the command. Place the
  40. #    following line AFTER the line "cmdEndGame   = -1" (around line 106):
  41. #
  42. #    cmdEndGame   = -1 # Find this
  43. #    cmdSwitch   = -1 # Add this below
  44. #
  45. # 2. Now you need to add it to the list of pause menu commands. Place these 4
  46. #    lines AFTER the line "commands[cmdTrainer = commands.length]  = $Trainer.name"
  47. #    (around line 119):
  48. #
  49. #    commands[cmdTrainer = commands.length]  = $Trainer.name # Find this
  50. #    # Add following lines below
  51. #    if $PokemonGlobal.commandCharacterSwitchOn && !pbInSafari? &&
  52. #          !pbInBugContest? && !pbBattleChallenge.pbInProgress?
  53. #      commands[cmdSwitch = commands.length] = _INTL("Switch")
  54. #    end
  55. #
  56. # 3. Finally, you need to add the code for what actually happens when the player
  57. #    selects the command. Add the following code BEFORE the line
  58. #    "elsif cmdOption>=0 && command==cmdOption" (around line 247):
  59. #
  60. #    elsif cmdSwitch>=0 && command==cmdSwitch
  61. #      characters = []
  62. #      characterIDs = []
  63. #      for i in 0...8
  64. #        if $PokemonGlobal.allowedCharacters[i] && i != $PokemonGlobal.playerID
  65. #          characters.push($PokemonGlobal.mainCharacters[i][0][0].name)
  66. #          characterIDs.push(i)
  67. #        end
  68. #      end
  69. #      if characters.length <= 0
  70. #        Kernel.pbMessage(_INTL("You're the only character!"))
  71. #        next
  72. #      end
  73. #      characters.push("Cancel")
  74. #      command = Kernel.pbShowCommands(nil, characters, characters.length)
  75. #      if command >= 0 && command < characters.length - 1
  76. #        @scene.pbHideMenu
  77. #        pbSwitchCharacter(characterIDs[command])
  78. #        break
  79. #      end
  80. #    # Add lines above this line
  81. #    elsif cmdOption>=0 && command==cmdOption # Find this
  82. #
  83. # 4. That's it! When you enable character switching through the menu, this
  84. #    should now show up and let the player switch between characters.
  85. #
  86. # In addition, you'll need to allow the use of \PN0 - \PN7 for map names,
  87. # exactly like how \PN works. To do this, follow the instructions below.
  88. #
  89. # 1. Under the Game_Map section, around line 95:
  90. #
  91. #    gsubPN(ret) # Add this above
  92. #    ret.gsub!(/\\PN/,$Trainer.name) if $Trainer # Find this
  93. #
  94. # 2. Under the Messages section, around line 867:
  95. #
  96. #    gsubPN(map) # Add this above
  97. #    map.gsub!(/\\PN/,$Trainer.name) if $Trainer # Find this
  98. #
  99. #-------------------------------------------------------------------------------
  100. # SCRIPT USAGE
  101. #-------------------------------------------------------------------------------
  102. # To switch to another character at any point in the story, simply call
  103. # "pbSwitchCharacter(id)", where the id corresponds to the definition in the
  104. # Global Metadata (PlayerA is 0, B is 1, etc). If you're switching to a
  105. # character for the first time, you can pass in the same parameters as you would
  106. # for "pbTrainerName", though it's not necessary.
  107. #
  108. # At the start of the game, the character id is initially 0 (PlayerA). Use
  109. # pbTrainerName to set the character up instead of pbSwitchCharacter, unless
  110. # you want the starting character to be someone else.
  111. #
  112. # You can enable and disable the "Switch" command with
  113. # "pbEnableCharacterCommandSwitching" and "pbDisableCharacterCommandSwitching".
  114. #
  115. # You can also enable and disable certain characters from the Switch command
  116. # with "pbEnableCharacter(id)" and "pbDisableCharacter(id)", where "id" is the
  117. # character id.
  118. #
  119. # The "pbSetLastMap(id, map_id, x, y, dir)" function lets you set the spawn
  120. # point of the character id to the specified location, though this doesn't apply
  121. # when pbSwitchCharacter is called from an event.
  122. #
  123. # You can use \PN0 - \PN7 to refer to each of the protagonists' names (\PN0 is
  124. # PlayerA, \PN1 is Player B, and so on) in map names exactly like the way you
  125. # use \PN to refer to the .
  126. #
  127. # You can register or battle against other characters (even yourself!) by
  128. # setting the trainer id as the character id and the trainer name as
  129. # "PROTAG". The general format is pbRegisterPartner(character_id, "PROTAG")
  130. # and pbTrainerBattle(character_id, "PROTAG", _I("END SPEECH"))
  131. # (and similar for one or more characters in pbDoubleTrainerBattle)
  132. #
  133. # For example, if you wanted to fight against Player B, you can use
  134. # this line: pbTrainerBattle(1, "PROTAG", _I("..."))
  135. # More examples can be found below.
  136. #
  137. # The instructions above are a fairly abridged version of each function's
  138. # capabilities. While this should be enough to be able to sufficiently use the
  139. # script, I highly suggest you to read the "List of Functions" below to gain a
  140. # better understanding of how the script works.
  141. #
  142. #-------------------------------------------------------------------------------
  143. # LIST OF FUNCTIONS
  144. #-------------------------------------------------------------------------------
  145. # def pbSwitchCharacter(id, name = nil, outfit = 0)
  146. # - The main command for switching to another character. It requires the "id"
  147. #   of the character, which is the id from the Global Metadata (PlayerA has
  148. #   id = 0, PlayerB's id = 1, etc). It also corresponds to the $Trainer.metaID.
  149. # - Additionally, the function has two optional parameters, "name" and "outfit".
  150. #   If you are switching to a character for the first time, the function will
  151. #   automatically call "pbTrainerName" on it, and if you set name and outfit at
  152. #   that time, they will be sent to pbTrainerName.
  153. #   Example: pbSwitchCharacter(1, "Leaf", 1) will first create the character,
  154. #   give them the name "Leaf", and set their outfit to 1.
  155. # - This function will fade out/fade in when called from the pause menu by the
  156. #   player, but NOT when called through an event, so you will need to call
  157. #   the "Transfer Player" command after switching in an event.
  158. # - It's generally a good idea to transfer the player AFTER calling this
  159. #   function (it won't be noticeable to the player when done after a blackout)
  160. #   rather than before, because if you transfer the player BEFORE calling this
  161. #   function, the map data stored for the old character will be that of the new
  162. #   map, where the new character is supposed to be. It usually won't cause any
  163. #   problems either way, though.
  164. # - Any global switches/variables and event self-switches DO NOT get saved in
  165. #   the character's data, so if you have an event that you want to work on each
  166. #   individual character instead of only one, make sure to handle that by having
  167. #   the event keep track of which characters have already used it.
  168. #
  169. # def pbEnableCharacterCommandSwitching
  170. # - Adds the "Switch" command to the pause menu.
  171. # - Starts as disabled by default.
  172. #
  173. # def pbDisableCharacterCommandSwitching
  174. # - Removes the "Switch" command from the pause menu.
  175. #
  176. # def pbEnableCharacter(id)
  177. # - Adds a character to the list of characters that can be switched to from the
  178. #   pause menu.
  179. # - All characters that have been switched to at least once are enabled by
  180. #   default (including PlayerA at the start).
  181. #
  182. # def pbDisableCharacter(id)
  183. # - Removes a character from the list of characters that can be switched to from
  184. #   the pause menu.
  185. #
  186. # def pbSetLastMap(id, map_id, x, y, dir)
  187. # - Sets the location of a character from the "id" to the specified location.
  188. #   This only takes effect when the character is switched to by the player, not
  189. #   by an event.
  190. # - Erases the "last Pokecenter" location for the character you set it on, so
  191. #   unless that character visits a new Pokecenter after being switched to, that
  192. #   character's blackout location will be the global metadata "home" variable
  193. #   instead. If you do force a new "last map", make sure to put a Pokecenter
  194. #   (or anything else that calls Kernel.pbSetPokemonCenter) around that area.
  195. #
  196. # def pbCharacterInfoArray
  197. # - Returns an array of arrays of the current character's data. The first array
  198. #   is general trainer data, and the second is map data specific to the map the
  199. #   character was last seen on. See actual function below for full list.
  200. # - Used internally by other functions of this script.
  201. #
  202. # def pbGetForeignCharacterID
  203. # - Returns a unique trainer ID compared to all previously defined trainers (not
  204. #   to be confused with character ID).
  205. # - Used internally by other functions of this script.
  206. #
  207. # def gsubPN(name)
  208. # - Modifies the input string to replace \PN0 - \PN7 with the 8 protagonists'
  209. #   names
  210. # - Used internally in other script sections
  211. #
  212. # def pbLoadTrainer(trainerid,trainername,partyid=0)
  213. # - Modified to allow registering/battling other characters
  214. # - If trainername is set to "PROTAG" in pbRegisterPartner, pbTrainerBattle,
  215. #   or pbDoubleTrainerBattle, then the protagonist with their character ID
  216. #   equal to trainerid will be cloned and returned (the original character won't
  217. #   be affected after battle)
  218. # - Used internally in pbRegisterPartner, pbTrainerBattle, and
  219. #   pbDoubleTrainerBattle
  220. # - Ex. If Player A wants to fight alongside Player B against Player C and a
  221. #   camper, the following two lines can be used:
  222. #
  223. #   pbRegisterPartner(1, "PROTAG")
  224. #   pbDoubleTrainerBattle(2, "PROTAG", 0, _I(""), :CAMPER, "Liam", 0, _I(""))
  225. #
  226. # - Ex. If Player A wants to fight against themselves, use this line:
  227. #   pbTrainerBattle(0, "PROTAG", _I(""))
  228. #
  229. #-------------------------------------------------------------------------------
  230. # POTENTIAL BUGS
  231. #-------------------------------------------------------------------------------
  232. # Any maps that have \PN in the name (a placeholder for the player's name) have
  233. # a minor bug of not updating the map's name correctly. For example, if a player
  234. # named Red steps into a house named "\PN's House", the name would show as
  235. # "Red's House", and if later another character named Blue comes in, the name
  236. # would still show "Red's House", UNTIL you save, close and open the game again,
  237. # in which case it will then turn into "Blue's House". If you have any maps with
  238. # \PN in it, this can be fixed by replacing the following:
  239. #
  240. # ret.gsub!(/\\PN/,$Trainer.name)# Find this
  241. #
  242. # with:
  243. #
  244. # ret=ret.gsub(/\\PN/,$Trainer.name) # Replace it with this
  245. #
  246. # Solution added by Tustin2121
  247. #
  248. #-------------------------------------------------------------------------------
  249. # I would like to acknowledge Tustin2121 for making a tutorial for Multiple
  250. # Protagonists on the old wiki, before the wiki was shut down. His tutorial
  251. # essentially laid the basis for how I would design my script.
  252. #
  253. # I hope you enjoy this script!
  254. # - NettoHikari
  255. ################################################################################
  256.  
  257. class PokemonGlobalMetadata
  258.   attr_accessor :mainCharacters           # Stores all protagonists' data
  259.   attr_accessor :commandCharacterSwitchOn # Enables character switching from menu
  260.   attr_accessor :allowedCharacters        # Characters allowed for command switching
  261.  
  262.   alias new_initialize initialize
  263.   def initialize
  264.     new_initialize
  265.     @mainCharacters = Array.new(8)
  266.     @commandCharacterSwitchOn = false
  267.     @allowedCharacters = Array.new(8, false)
  268.     @allowedCharacters[0] = true
  269.   end
  270. end
  271.  
  272. # Enables character switching through pause menu
  273. def pbEnableCharacterCommandSwitching
  274.   $PokemonGlobal.commandCharacterSwitchOn = true
  275. end
  276.  
  277. # Disables character switching through pause menu
  278. def pbDisableCharacterCommandSwitching
  279.   $PokemonGlobal.commandCharacterSwitchOn = false
  280. end
  281.  
  282. # Enables specific character in command switching
  283. def pbEnableCharacter(id)
  284.   return if id < 0 || id >= 8 || !$PokemonGlobal.mainCharacters[id]
  285.   $PokemonGlobal.allowedCharacters[id] = true
  286. end
  287.  
  288. # Disables specific character in command switching
  289. def pbDisableCharacter(id)
  290.   return if id < 0 || id >= 8 || !$PokemonGlobal.mainCharacters[id]
  291.   $PokemonGlobal.allowedCharacters[id] = false
  292. end
  293.  
  294. # Main function to switch between characters
  295. def pbSwitchCharacter(id, name = nil, outfit = 0)
  296.   return if id<0 || id>=8 || id == $Trainer.metaID
  297.   meta = $PokemonGlobal.mainCharacters[id]
  298.   oldid = $Trainer.metaID
  299.   $PokemonGlobal.mainCharacters[oldid] = pbCharacterInfoArray
  300.   if !meta
  301.     $Trainer = nil
  302.     $PokemonGlobal.playerID = id
  303.     pbTrainerName(name, outfit)
  304.     $Trainer.metaID = id
  305.     $Trainer.id = pbGetForeignCharacterID
  306.     $PokemonTemp.begunNewGame = false
  307.     numRegions = 0
  308.     pbRgssOpen("Data/regionals.dat","rb"){|f| numRegions = f.fgetw }
  309.     newplayermeta = [$Trainer, $PokemonBag, PokemonStorage.new, false, false,
  310.                       false, 0, 0, nil, nil, 0, nil, [[nil,0],[nil,0]], false, 0,
  311.                       [], [], (numRegions==0) ? -1 : 0, [], 0, [], nil, [], 0,
  312.                       nil, 0, nil, false, nil, nil]
  313.     for i in 0...numRegions+1     # National Dex isn't a region, but is included
  314.       newplayermeta[18][i]    = 0
  315.       newplayermeta[15][i] = (i==0)
  316.     end
  317.     newmapmeta = [-1, -1, -1, -1, false, false, false, 0, false, 0, nil, [],
  318.                   -1, -1, -1, -1]
  319.     $PokemonGlobal.mainCharacters[id] = [newplayermeta, newmapmeta]
  320.     meta = $PokemonGlobal.mainCharacters[id]
  321.     pbEnableCharacter(id)
  322.   end
  323.   pm = meta[0] # Player Meta
  324.   mm = meta[1] # Map Meta
  325.   if pbMapInterpreterRunning? # Must have been called through event command
  326.     mm = [-1, -1, -1, -1, false, false, false, 0, false, 0, meta[1][10], [],
  327.           meta[1][12], meta[1][13], meta[1][14], meta[1][15]]
  328.   end
  329.   # Player Meta
  330.   $Trainer = pm[0]
  331.   $PokemonBag = pm[1]
  332.   $PokemonStorage = pm[2]
  333.   $PokemonGlobal.runningShoes = pm[3]
  334.   $PokemonGlobal.snagMachine = pm[4]
  335.   $PokemonGlobal.seenStorageCreator = pm[5]
  336.   $PokemonGlobal.coins = pm[6]
  337.   $PokemonGlobal.sootsack = pm[7]
  338.   $PokemonGlobal.mailbox = pm[8]
  339.   $PokemonGlobal.pcItemStorage = pm[9]
  340.   $PokemonGlobal.happinessSteps = pm[10]
  341.   $PokemonGlobal.pokerusTime = pm[11]
  342.   $PokemonGlobal.daycare = pm[12]
  343.   $PokemonGlobal.daycareEgg = pm[13]
  344.   $PokemonGlobal.daycareEggSteps = pm[14]
  345.   $PokemonGlobal.pokedexUnlocked = pm[15]
  346.   $PokemonGlobal.pokedexViable = pm[16]
  347.   $PokemonGlobal.pokedexDex = pm[17]
  348.   $PokemonGlobal.pokedexIndex = pm[18]
  349.   $PokemonGlobal.pokedexMode = pm[19]
  350.   $PokemonGlobal.visitedMaps = pm[20]
  351.   $PokemonGlobal.partner = pm[21]
  352.   $PokemonGlobal.phoneNumbers = pm[22]
  353.   $PokemonGlobal.phoneTime = pm[23]
  354.   $PokemonGlobal.dependentEvents = []
  355.   pbRemoveDependencies()
  356.   $PokemonGlobal.pokeradarBattery = pm[25]
  357.   $PokemonGlobal.purifyChamber = pm[26]
  358.   $PokemonGlobal.seenPurifyChamber = pm[27]
  359.   $PokemonGlobal.triads = pm[28]
  360.   $PokemonGlobal.trainerRecording = pm[29]
  361.   # Map Meta
  362.   # Assumes that if called through event, mm[0] was set to -1 earlier
  363.   if mm[0] >= 0 && $PokemonGlobal.commandCharacterSwitchOn
  364.     $game_temp.player_new_map_id = mm[0]
  365.     $game_temp.player_new_x = mm[1]
  366.     $game_temp.player_new_y = mm[2]
  367.     $game_temp.player_new_direction = mm[3]
  368.     $game_screen.start_tone_change(Tone.new(-255, -255, -255, 0), 12)
  369.     pbWait(16)
  370.     $scene.transfer_player
  371.     $game_screen.start_tone_change(Tone.new(0, 0, 0, 0), 12)
  372.   end
  373.   $PokemonGlobal.bicycle = mm[4]
  374.   $PokemonGlobal.surfing = mm[5]
  375.   $PokemonGlobal.diving = mm[6]
  376.   $PokemonGlobal.repel = mm[7]
  377.   $PokemonGlobal.flashUsed = mm[8]
  378.   $PokemonGlobal.bridge = mm[9]
  379.   $PokemonGlobal.healingSpot = mm[10]
  380.   $PokemonGlobal.escapePoint = mm[11]
  381.   $PokemonGlobal.pokecenterMapId = mm[12]
  382.   $PokemonGlobal.pokecenterX = mm[13]
  383.   $PokemonGlobal.pokecenterY = mm[14]
  384.   $PokemonGlobal.pokecenterDirection = mm[15]
  385.   $PokemonGlobal.dependentEvents = pm[24]
  386.   $PokemonTemp.dependentEvents = DependentEvents.new
  387.   $PokemonTemp.dependentEvents.updateDependentEvents
  388.   $PokemonGlobal.playerID = $Trainer.metaID
  389.   Kernel.pbUpdateVehicle
  390. end
  391.  
  392. # Sets the "last map" variables of character
  393. def pbSetLastMap(id, map_id, x, y, dir)
  394.   return if id < 0 || id >= 8 || map_id < 0 || !$PokemonGlobal.mainCharacters[id]
  395.   mm = [map_id, x, y, dir, false, false, false, 0, false, 0, nil, [], -1, -1, -1, -1]
  396.   $PokemonGlobal.mainCharacters[id][1] = mm
  397. end
  398.  
  399. # List of objects stored for each character
  400. # Player Meta:
  401. # 1. Trainer Object
  402. # 2. Item Bag
  403. # 3. Pokemon Storage
  404. # 4. Running Shoes
  405. # 5. Snag Machine
  406. # 6. Seen Storage Creator
  407. # 7. Coins
  408. # 8. Sootsack
  409. # 9. Mailbox
  410. # 10. Item Storage
  411. # 11. Happiness Steps
  412. # 12. Pokerus Time
  413. # 13. Daycare Pokemon
  414. # 14. Daycare Egg
  415. # 15. Daycare Egg Steps
  416. # 16. Unlocked Pokedexes
  417. # 17. Viable Pokedexes
  418. # 18. Current Pokedex
  419. # 19. Last Viewed Pokemon in each Dex
  420. # 20. Pokedex Search Mode
  421. # 21. Visited Maps
  422. # 22. Partner Trainer
  423. # 23. Phone Numbers
  424. # 24. Phone Time
  425. # 25. Dependent Events
  426. # 26. Pokeradar Battery
  427. # 27. Purify Chamber
  428. # 28. Seen Purify Chamber
  429. # 29. Triad Collection
  430. # 30. Trainer Recording
  431. # Map Meta:
  432. # 1. Last Map
  433. # 2. Last X
  434. # 3. Last Y
  435. # 4. Last Direction
  436. # 5. Bicycle Active
  437. # 6. Surfing Active
  438. # 7. Diving Active
  439. # 8. Repel Steps Remaining
  440. # 9. Flash Active
  441. # 10. Bridge Tile Passage
  442. # 11. Last Healing Spot
  443. # 12. Cave Escape Point
  444. # 13. Last Pokecenter Map ID
  445. # 14. Last Pokecenter X
  446. # 15. Last Pokecenter Y
  447. # 16. Last Pokecenter Direction
  448. def pbCharacterInfoArray
  449.   arr = [$Trainer, $PokemonBag, $PokemonStorage, $PokemonGlobal.runningShoes,
  450.           $PokemonGlobal.snagMachine, $PokemonGlobal.seenStorageCreator,
  451.           $PokemonGlobal.coins, $PokemonGlobal.sootsack, $PokemonGlobal.mailbox,
  452.           $PokemonGlobal.pcItemStorage, $PokemonGlobal.happinessSteps,
  453.           $PokemonGlobal.pokerusTime, $PokemonGlobal.daycare,
  454.           $PokemonGlobal.daycareEgg, $PokemonGlobal.daycareEggSteps,
  455.           $PokemonGlobal.pokedexUnlocked, $PokemonGlobal.pokedexViable,
  456.           $PokemonGlobal.pokedexDex, $PokemonGlobal.pokedexIndex,
  457.           $PokemonGlobal.pokedexMode, $PokemonGlobal.visitedMaps,
  458.           $PokemonGlobal.partner, $PokemonGlobal.phoneNumbers,
  459.           $PokemonGlobal.phoneTime, $PokemonGlobal.dependentEvents,
  460.           $PokemonGlobal.pokeradarBattery, $PokemonGlobal.purifyChamber,
  461.           $PokemonGlobal.seenPurifyChamber, $PokemonGlobal.triads,
  462.           $PokemonGlobal.trainerRecording]
  463.   arr2 = [$game_player.map.map_id, $game_player.x, $game_player.y,
  464.             $game_player.direction, $PokemonGlobal.bicycle,
  465.             $PokemonGlobal.surfing, $PokemonGlobal.diving, $PokemonGlobal.repel,
  466.             $PokemonGlobal.flashUsed, $PokemonGlobal.bridge,
  467.             $PokemonGlobal.healingSpot, $PokemonGlobal.escapePoint,
  468.             $PokemonGlobal.pokecenterMapId, $PokemonGlobal.pokecenterX,
  469.             $PokemonGlobal.pokecenterY, $PokemonGlobal.pokecenterDirection]
  470.   return [arr, arr2]
  471. end
  472.  
  473. # Returns a player ID different from all other character IDs
  474. def pbGetForeignCharacterID
  475.   characterIDs = Array.new
  476.   for i in 0...$PokemonGlobal.mainCharacters.length
  477.     if $PokemonGlobal.mainCharacters[i] != nil
  478.       characterIDs.push($PokemonGlobal.mainCharacters[i][0].id)
  479.     end
  480.   end
  481.   id = $Trainer.getForeignID
  482.   while characterIDs.include?(id)
  483.     id = $Trainer.getForeignID
  484.   end
  485.   return id
  486. end
  487.  
  488. # Substitutes \PN0-7 with the appropriate trainer name
  489. def gsubPN(name)
  490.   if $PokemonGlobal
  491.     for i in 0..7
  492.       if $PokemonGlobal.mainCharacters[i]
  493.         name.gsub!(/\\PN#{i}/, $PokemonGlobal.mainCharacters[i][0][0].name)
  494.       end
  495.     end
  496.   else
  497.     savefile = RTP.getSaveFileName("Game.rxdata")
  498.     global=nil
  499.     File.open(savefile){|f|
  500.           Marshal.load(f) # Trainer already loaded
  501.           Marshal.load(f) # Graphics.frame_count
  502.           Marshal.load(f) # $game_system
  503.           Marshal.load(f) # PokemonSystem already loaded
  504.           Marshal.load(f) # Current map id no longer needed
  505.           Marshal.load(f) # $game_switches
  506.           Marshal.load(f) # $game_variables
  507.           Marshal.load(f) # $game_self_switches
  508.           Marshal.load(f) # $game_screen
  509.           Marshal.load(f) # $MapFactory
  510.           Marshal.load(f) # $game_player
  511.           global=Marshal.load(f) # $PokemonGlobal
  512.     }
  513.     for i in 0..7
  514.       if global.mainCharacters[i]
  515.         name.gsub!(/\\PN#{i}/, global.mainCharacters[i][0][0].name)
  516.       end
  517.     end
  518.   end
  519. end
  520.  
  521. # Clones and returns character trainer and party if given character id and
  522. # "PROTAG" as trainer name, otherwise loads trainer data normally
  523. alias reg_pbLoadTrainer pbLoadTrainer
  524. def pbLoadTrainer(trainerid,trainername,partyid=0)
  525.   if trainername=="PROTAG" && trainerid >= 0 && trainerid < 8 &&
  526.         $PokemonGlobal.mainCharacters[trainerid]
  527.     pm=$PokemonGlobal.mainCharacters[trainerid][0] # Player meta
  528.     opponent = pm[0].clone
  529.     oldparty = pm[0].party
  530.     party = oldparty.clone
  531.     for i in 0...party.length
  532.       party[i] = oldparty[i].clone
  533.       party[i].ev = oldparty[i].ev.clone
  534.       party[i].iv = oldparty[i].iv.clone
  535.       party[i].heal
  536.     end
  537.     opponent.party = party
  538.     return [opponent, [], party]
  539.   else
  540.     return reg_pbLoadTrainer(trainerid,trainername,partyid)
  541.   end
  542. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top