• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Our friends from the Johto Times are hosting a favorite Pokémon poll - and we'd love for you to participate! Click here for information on how to vote for your favorites!
  • Scottie, Todd, Serena, Kris - which Pokémon protagonist is your favorite? Let us know by voting in our poll!
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Complete FireRed Upgrade: Editing and Adding Trainers

  • 14
    Posts
    4
    Years
    It came to my mind that a lot of people were struggling to get trainer editing working, provided they're using the CFRU. "Which trainer editor do I use?", "How and when do I add or edit trainers?". Well, to answer those questions, here is a full tutorial on how to DYNAMICALLY edit and add/remove trainers using the CFRU. No need to worry about repointing data. Ah, and the only 'Trainer Editor' we'll be needing is preferably VS Code (or whichever IDE you're comfortable with). And also while we're at it, I'll be covering Custom EV/IV/Nature/Pokeball spreads, as many people are still clueless to this wonderful utility CFRU has blessed us with.

    This tutorial might seem overwhelming at first, but trust me, it's not. You'll get used to it quickly as you write new trainer data.

    Prerequisites

    • I've provided a .zip file that contains 4 key files: trainer_defines.h, trainer_parties.h, new_text.h and lastly trainer_data.c
      Download it, extract the files and place them in src/Tables

    • Crack open include/battle.hand search for:
      C:
      /*
      extern const struct Trainer gTrainers[];
      */
      Uncomment that line:
      C:
      extern const struct Trainer gTrainers[];
      This is not required, but better to do anyway, in case you want to access the struct from some other file.

    • Go to repoints file in the root folder and add this somewhere:
      Code:
      ## Trainer Data
      gTrainers 0800FC00

    Adding Trainers

    Step 1: Defining Your Trainers
    • Go to trainer_defines.h. Here, you will find a list of all Vanilla FireRed trainers. Add your own entry below like this:
      C:
      ......
      #define TRAINER_CHAMPION_REMATCH_CHARMANDER      741
      #define TRAINER_CUE_BALL_PAXTON                  742
      
      // New Entries
      #define TRAINER_PROFESSOR_OAK_VENUSAUR           743

    • You could also use enum to make the process easier:
      C:
      enum GymLeaders
      {
          TRAINER_GYM_LEADER_1 = 744,
          TRAINER_GYM_LEADER_2,
          TRAINER_GYM_LEADER_3,
          TRAINER_GYM_LEADER_4,
          TRAINER_GYM_LEADER_5,
          TRAINER_GYM_LEADER_6,
          TRAINER_GYM_LEADER_7,
          TRAINER_GYM_LEADER_8,
      };

    • Note: You could also add these trainer defines to asm_defines.s in the root folder in case you plan to script using the CFRU
    Step 2: Editing The Trainer Data
    • Go to trainer_data.c. This file contains the usual Trainer Info such as Name, Trainer Class, AI, Party Data, Items, etc.

    • Add your own struct below the last one:
      C:
              [TRAINER_CUE_BALL_PAXTON] = {
              .partyFlags = 0,
              .trainerClass = CLASS_CUE_BALL,
              .encounterMusic = TRAINER_ENCOUNTER_MUSIC_MALE,
              .gender = 0,
              .trainerPic = TRAINER_PIC_CUE_BALL,
              #ifdef DECAP_TRAINER_NAMES
              .trainerName = { _P, _a, _x, _t, _o, _n, _END },
              #else
              .trainerName = { _P, _A, _X, _T, _O, _N, _END },
              #endif
              .items = {ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE},
              .doubleBattle = FALSE,
              .partySize = 2,
              .aiFlags = AI_SCRIPT_CHECK_BAD_MOVE,
              .party =  { .NoItemDefaultMoves = sParty_CueBallPaxton },
          },
          // New Entries
              [TRAINER_PROFESSOR_OAK_VENUSAUR] = {
              .partyFlags = PARTY_FLAG_CUSTOM_MOVES | PARTY_FLAG_HAS_ITEM,
              .trainerClass = CLASS_PKMN_PROF,
              .encounterMusic = TRAINER_ENCOUNTER_MUSIC_MALE,
              .gender = 0,
              .trainerPic = TRAINER_PIC_PROF_OAK,
              .trainerName = { _O, _a, _k, _END },
              .items = {ITEM_FULL_RESTORE, ITEM_FULL_RESTORE, ITEM_MEGA_RING, ITEM_NONE},
              .doubleBattle = TRUE,
              .partySize = 6,
              .aiFlags = AI_SCRIPT_CHECK_GOOD_MOVE,
              .party =  { .ItemCustomMoves = sParty_ProfessorOakVenusaur },
          },

    • .partyFlags is self-explanatory. You can also leave it as 0 if you don't want either of those.
    • .trainerClass indicates the well... trainer's class. All of them are listed in:
      include/constants/trainer_classes.h
    • .encounterMusic specifies the music you hear when you talk to this trainer. They are listed in:
      include/constants/trainers.h
    • Leave the .gender field as 0 if Male, else set to 1 if Female
    • .trainerPic is again, self-explanatory. You can find them in the same file that contains the defines of .encounterMusic
    • .trainerName is where you'll write the trainer's name, and hence why we needed that new_text.h file. Note that you HAVE to terminate the array with _END
    • Add the items you want the trainer to have in the .items field
    • Set .doubleBattle to TRUE if you want the battle to be fought in a doubles format
    • .partySize defines the size of your trainer's party.
    • .aiFlagsindicates the difficulty of the trainer you'll face. Currently, only three flags are required, and they're quite simple to understand:
      • AI_CHECK_BAD_MOVE
      • AI_CHECK_SEMI_SMART
      • AI_CHECK_GOOD_MOVE
    • In the .partyfield, you shall assign your Party Data and use either of these four fields:
      • .NoItemDefaultMoves
      • .NoItemCustomMoves
      • .ItemDefaultMoves
      • .ItemCustomMoves

    Step 3: Adding Trainer Party Data
    • Crack open trainer_parties.h and add your trainer's party like so:
    • C:
      struct XXXXXXX sParty_ProfessorOakVenusaur[] = {
          {
              .iv = 0,
              .lvl = 72,
              .species = SPECIES_HERACROSS,
              .heldItem = ITEM_CHOICE_SCARF,
              .moves = {MOVE_MEGAHORN, MOVE_EARTHQUAKE, MOVE_CLOSECOMBAT, MOVE_STONEEDGE},
          },
          {
              .iv = 0,
              .lvl = 73,
              .species = SPECIES_ALAKAZAM,
              .heldItem = ITEM_LIFE_ORB,
              .moves = {MOVE_PSYCHIC, MOVE_SHADOWBALL, MOVE_DAZZLINGGLEAM, MOVE_CALMMIND},
          },
          {
              .iv = 0,
              .lvl = 72,
              .species = SPECIES_TYRANITAR,
              .heldItem = ITEM_SMOOTH_ROCK,
              .moves = {MOVE_ROCKSLIDE, MOVE_EARTHQUAKE, MOVE_DRAGONDANCE, MOVE_ICEPUNCH},
          },
          {
              .iv = 0,
              .lvl = 73,
              .species = SPECIES_GYARADOS,
              .heldItem = ITEM_LEFTOVERS,
              .moves = {MOVE_DRAGONDANCE, MOVE_WATERFALL, MOVE_EARTHQUAKE, MOVE_ICEFANG},
          },
          {
              .iv = 0,
              .lvl = 73,
              .species = SPECIES_ARCANINE,
              .heldItem = ITEM_LIFE_ORB,
              .moves = {MOVE_EXTREMESPEED, MOVE_CLOSECOMBAT, MOVE_FLAREBLITZ, MOVE_WILDCHARGE},
          },
          {
              .iv = 0,
              .lvl = 75,
              .species = SPECIES_VENUSAUR,
              .heldItem = ITEM_VENUSAURITE,
              .moves = {MOVE_GIGADRAIN, MOVE_SLUDGEBOMB, MOVE_SLEEPPOWDER, MOVE_SYNTHESIS},
          },
      };
      Where XXXXXXX is either of the four (self-explanatory). In our case, it'll be the fourth one:
      • TrainerMonNoItemDefaultMoves
      • TrainerMonNoItemCustomMoves
      • TrainerMonItemDefaultMoves
      • TrainerMonItemCustomMoves
    • And... you're done! run python scripts//clean.py buildand then python scripts//make.py and your new trainer should appear in the table.
    • Now, you can use trainerbattle 0x0 744 0x0 @before @after to access the Prof Oak Battle. You can add similar entries after that.


    Editing Trainers

    If you've read this far, you should have no trouble editing existing trainers by your own. I have gone through the trouble of importing and converting these trainers from pokefirered to the CFRU format, so you can rest assured have an easy time editing trainers.

    NOTE:- In the start of trainer_data.c, you'll see
    C:
    #define DECAP_TRAINER_NAMES
    Add a // before the line if you want the trainer names to be capitalised.


    Custom Pokemon Spreads

    As I've mentioned before, even though this section is explained by the CFRU Documentation, due to the arising confusion of many people, I'll cover this as well. REMEMBER TO UNCOMMENT #define TRAINERS_WITH_EVS in src/config.h
    • Go to src/Tables/trainers_with_evs_table.h. This file contains a multitude of custom spreads in-built by the CFRU for your use. Though, if you want to use your own spread. Simply edit an existing table, or add a new one under [120]. The abilities can be seen in DPE/src/base_stats.c:
      C:
          [120] =
          { //Fast Wall: Sp. Defense Based, Less Sp. Attack - Ability_Hidden
              .nature = NATURE_JOLLY,
              .ivs = 31,
              .hpEv = 4,
              .spdEv = 252,
              .spDefEv = 252,
              .ball = TRAINER_EV_CLASS_BALL,
              .ability = Ability_Hidden,
          },
          // Custom Spreads
          [121] =
          { // Professor Oak's Gyarados
              .nature = NATURE_JOLLY,
              .ivs = 31,
              .hpEv = 6,
              .atkEv = 252,
              .spdEv = 252,
              .ball = BALL_TYPE_DIVE_BALL,
              .ability = Ability_Hidden, // Moxie
          },
          ...
          ...

    • Now, go back to trainer_parties.h and assign that spread number to the .iv section of the Pokemon. Here, for Oak's Gyarados, it'll be 121:
      C:
      {
              .iv = 121,
              .lvl = 73,
              .species = SPECIES_GYARADOS,
              .heldItem = ITEM_LEFTOVERS,
              .moves = {MOVE_DRAGONDANCE, MOVE_WATERFALL, MOVE_EARTHQUAKE, MOVE_ICEFANG},
      },

    Result

    If you've followed all the steps correctly, then congratulations! You've succeeded in inserting your own trainers / editing existing ones using the CFRU. No need for repoints, tools, or anything else! Just your IDE is enough!

    [PokeCommunity.com] Complete FireRed Upgrade: Editing and Adding Trainers


    [PokeCommunity.com] Complete FireRed Upgrade: Editing and Adding Trainers
     

    Attachments

    • Prerequisites.zip
      48.1 KB · Views: 5
    Last edited:
    Something i can call 'El Besto!' is here :)
    Nice tutorial for this dead community.
     
    Back
    Top