summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/oak_speech.c8
-rw-r--r--src/pokemon.c1213
-rw-r--r--src/trainer_tower.c8
3 files changed, 1096 insertions, 133 deletions
diff --git a/src/oak_speech.c b/src/oak_speech.c
index 26736604e..c00335136 100644
--- a/src/oak_speech.c
+++ b/src/oak_speech.c
@@ -14,7 +14,7 @@
#include "menu.h"
#include "help_system.h"
#include "new_menu_helpers.h"
-#include "pokemon_3.h"
+#include "pokemon.h"
#include "sound.h"
#include "event_scripts.h"
#include "scanline_effect.h"
@@ -500,7 +500,7 @@ static void Task_OaksSpeech1(u8 taskId)
break;
case 1:
sOakSpeechResources = AllocZeroed(sizeof(*sOakSpeechResources));
- SetUpMonSpriteManagerMaybe(1, 1);
+ OakSpeechNidoranFSetup(1, 1);
break;
case 2:
SetGpuReg(REG_OFFSET_WIN0H, 0);
@@ -1513,7 +1513,7 @@ static void Task_OakSpeech41(u8 taskId)
static void Task_OakSpeech42(u8 taskId)
{
FreeAllWindowBuffers();
- sub_8044D80();
+ OakSpeechNidoranFFreeResources();
Free(sOakSpeechResources);
sOakSpeechResources = NULL;
gTextFlags.canABSpeedUpPrint = FALSE;
@@ -1612,7 +1612,7 @@ static void CreateNidoranFSprite(u8 taskId)
{
u8 spriteId;
- DecompressPicFromTable(gUnknown_8235194, sub_8044E00(0), SPECIES_NIDORAN_F);
+ DecompressPicFromTable(gUnknown_8235194, OakSpeechNidoranFGetBuffer(0), SPECIES_NIDORAN_F);
LoadCompressedSpritePaletteUsingHeap(&gUnknown_82373F4);
SetMultiuseSpriteTemplateToPokemon(SPECIES_NIDORAN_F, 0);
spriteId = CreateSprite(&gMultiuseSpriteTemplate, 0x60, 0x60, 1);
diff --git a/src/pokemon.c b/src/pokemon.c
index b9b5e6d76..f4150d5b6 100644
--- a/src/pokemon.c
+++ b/src/pokemon.c
@@ -5,8 +5,10 @@
#include "random.h"
#include "main.h"
#include "text.h"
+#include "data2.h"
#include "string_util.h"
#include "battle.h"
+#include "battle_2.h"
#include "item.h"
#include "event_data.h"
#include "util.h"
@@ -16,9 +18,17 @@
#include "battle_controllers.h"
#include "evolution_scene.h"
#include "battle_message.h"
+#include "battle_util.h"
+#include "battle_ai_script_commands.h"
#include "link.h"
#include "m4a.h"
#include "sound.h"
+#include "pokedex.h"
+#include "strings.h"
+#include "malloc.h"
+#include "overworld.h"
+#include "party_menu.h"
+#include "field_specials.h"
#include "constants/items.h"
#include "constants/species.h"
#include "constants/pokemon.h"
@@ -34,63 +44,304 @@
// Extracts the lower 16 bits of a 32-bit number
#define LOHALF(n) ((n) & 0xFFFF)
-// TODO: what is this
-struct UnkStruct20244F4
+struct OakSpeechNidoranFStruct
{
- u8 unk0:4;
- u8 unk0_2:4;
- u8 filler1[0xF];
- struct SpriteTemplate *unk10;
+ u8 spriteCount:4;
+ u8 battlePosition:4;
+ u8 frameCount;
+ u8 enable;
+ bool8 enable2;
+ u32 sizePerSprite;
+ u8 *dataBuffer;
+ u8 **bufferPtrs;
+ struct SpriteTemplate *templates;
+ struct SpriteFrameImage *frameImages;
};
-// External symbols
-extern struct UnkStruct20244F4 *gUnknown_20244F4;
-extern struct SpriteTemplate gUnknown_825DEF0[];
-extern struct SpriteTemplate gUnknown_825DF50[];
-extern const union AnimCmd *const *const gTrainerBackAnimsPtrTable[];
-extern struct SpriteTemplate gUnknown_825DEF0[];
-extern const union AnimCmd *const *const gTrainerFrontAnimsPtrTable[];
-extern const union AnimCmd *const gUnknown_82349BC[];
-extern const u8 gUnknown_825DEA1[];
-extern const u8 gPPUpWriteMasks[];
-extern u8 *gUnknown_83FD5D0[];
-extern const u8 gUnknown_825DFF0[];
-extern const u8 gText_EggNickname[];
-extern const u8 gText_BadEgg[];
-extern const u8 BattleText_Rose[];
-extern const u8 BattleText_UnknownString3[];
-extern const u8 BattleText_GetPumped[];
-extern const u8 BattleText_MistShroud[];
-extern const u8 gText_PkmnsXPreventsSwitching[];
-extern const u8 sHoldEffectToType[][2];
+// TODO: move sLearningMoveTableID, gPlayerPartyCount, gEnemyPartyCount,
+// gEnemyParty, gPlayerParty here after resolving symbol ref in between.
extern u8 sLearningMoveTableID;
-extern const u8 sSecretBaseFacilityClasses[2][5];
-extern u16 gUnknown_8251CB8[];
-extern u16 gUnknown_8251FEE[];
-extern u16 gUnknown_8252324[];
-extern u16 gUnknown_82539D4[];
-extern struct SpindaSpot gSpindaSpotGraphics[];
-extern s8 gNatureStatTable[][5];
-extern const s8 sFriendshipEventDeltas[][3];
-extern u32 gTMHMLearnsets[][2];
-extern u8 gBattleMonForms[4];
-extern const struct CompressedSpritePalette gMonPaletteTable[];
-extern const struct CompressedSpritePalette gMonShinyPaletteTable[];
-extern const u16 sHMMoves[];
-extern s8 gPokeblockFlavorCompatibilityTable[];
-
-// External functions
-extern u8 GetCurrentRegionMapSectionId(void); // overworld
-extern const struct BattleMove gBattleMoves[];
-extern u8 sBattler_AI; // battle_ai
-extern void set_unknown_box_id(u8); // field_specials
-extern u8 pokemon_order_func(u8);
-extern u16 get_unknown_box_id(void); // field_specials
-extern u8 StorageGetCurrentBox(void); // pokemon_storage_system
-extern void sub_80174B8(u8 battlerId);
-
-union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType);
-s32 GetDeoxysStat(struct Pokemon *mon, s32 statId);
+
+EWRAM_DATA struct SpriteTemplate gMultiuseSpriteTemplate = {0};
+static EWRAM_DATA struct OakSpeechNidoranFStruct *sOakSpeechNidoranResources = NULL;
+
+static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType);
+static u16 GetDeoxysStat(struct Pokemon *mon, s32 statId);
+static bool8 IsShinyOtIdPersonality(u32 otId, u32 personality);
+static u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex);
+static u8 GetNatureFromPersonality(u32 personality);
+static bool8 sub_8042BE8(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId);
+static bool8 HealStatusConditions(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId);
+static bool8 IsPokemonStorageFull(void);
+static u8 SendMonToPC(struct Pokemon* mon);
+static void EncryptBoxMon(struct BoxPokemon *boxMon);
+static void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
+static void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon);
+static u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move);
+static u8 GetLevelFromMonExp(struct Pokemon *mon);
+static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon);
+
+const s8 gPokeblockFlavorCompatibilityTable[] =
+{
+ // Cool, Beauty, Cute, Smart, Tough
+ 0, 0, 0, 0, 0, // Hardy
+ 1, 0, 0, 0, -1, // Lonely
+ 1, 0, -1, 0, 0, // Brave
+ 1, -1, 0, 0, 0, // Adamant
+ 1, 0, 0, -1, 0, // Naughty
+ -1, 0, 0, 0, 1, // Bold
+ 0, 0, 0, 0, 0, // Docile
+ 0, 0, -1, 0, 1, // Relaxed
+ 0, -1, 0, 0, 1, // Impish
+ 0, 0, 0, -1, 1, // Lax
+ -1, 0, 1, 0, 0, // Timid
+ 0, 0, 1, 0, -1, // Hasty
+ 0, 0, 0, 0, 0, // Serious
+ 0, -1, 1, 0, 0, // Jolly
+ 0, 0, 1, -1, 0, // Naive
+ -1, 1, 0, 0, 0, // Modest
+ 0, 1, 0, 0, -1, // Mild
+ 0, 1, -1, 0, 0, // Quiet
+ 0, 0, 0, 0, 0, // Bashful
+ 0, 1, 0, -1, 0, // Rash
+ -1, 0, 0, 1, 0, // Calm
+ 0, 0, 0, 1, -1, // Gentle
+ 0, 0, -1, 1, 0, // Sassy
+ 0, -1, 0, 1, 0, // Careful
+ 0, 0, 0, 0, 0 // Quirky
+};
+
+const u8 gPPUpGetMask[] = { 0x03, 0x0c, 0x30, 0xc0 }; // Masks for getting PP Up count, also PP Max values
+
+const u8 gPPUpSetMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; // Masks for setting PP Up count
+
+const u8 gPPUpAddMask[] = { 0x01, 0x04, 0x10, 0x40 }; // Values added to PP Up count
+
+const u8 gStatStageRatios[][2] =
+{
+ { 10, 40 },
+ { 10, 35 },
+ { 10, 30 },
+ { 10, 25 },
+ { 10, 20 },
+ { 10, 15 },
+ { 10, 10 },
+ { 15, 10 },
+ { 20, 10 },
+ { 25, 10 },
+ { 30, 10 },
+ { 35, 10 },
+ { 40, 10 },
+ { 138, 174 },
+ { 108, 120 },
+};
+
+static const u8 sFiller = _("");
+
+static const u8 sHoldEffectToType[][2] =
+{
+ {HOLD_EFFECT_BUG_POWER, TYPE_BUG},
+ {HOLD_EFFECT_STEEL_POWER, TYPE_STEEL},
+ {HOLD_EFFECT_GROUND_POWER, TYPE_GROUND},
+ {HOLD_EFFECT_ROCK_POWER, TYPE_ROCK},
+ {HOLD_EFFECT_GRASS_POWER, TYPE_GRASS},
+ {HOLD_EFFECT_DARK_POWER, TYPE_DARK},
+ {HOLD_EFFECT_FIGHTING_POWER, TYPE_FIGHTING},
+ {HOLD_EFFECT_ELECTRIC_POWER, TYPE_ELECTRIC},
+ {HOLD_EFFECT_WATER_POWER, TYPE_WATER},
+ {HOLD_EFFECT_FLYING_POWER, TYPE_FLYING},
+ {HOLD_EFFECT_POISON_POWER, TYPE_POISON},
+ {HOLD_EFFECT_ICE_POWER, TYPE_ICE},
+ {HOLD_EFFECT_GHOST_POWER, TYPE_GHOST},
+ {HOLD_EFFECT_PSYCHIC_POWER, TYPE_PSYCHIC},
+ {HOLD_EFFECT_FIRE_POWER, TYPE_FIRE},
+ {HOLD_EFFECT_DRAGON_POWER, TYPE_DRAGON},
+ {HOLD_EFFECT_NORMAL_POWER, TYPE_NORMAL},
+};
+
+const struct SpriteTemplate gUnknown_825DEF0[] =
+{
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F018,
+ .anims = NULL,
+ .images = gUnknown_8234698,
+ .affineAnims = gUnknown_82348C8,
+ .callback = sub_80120C4,
+ },
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F010,
+ .anims = NULL,
+ .images = gUnknown_82346B8,
+ .affineAnims = gUnknown_8234944,
+ .callback = oac_poke_opponent,
+ },
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F018,
+ .anims = NULL,
+ .images = gUnknown_82346D8,
+ .affineAnims = gUnknown_82348C8,
+ .callback = sub_80120C4,
+ },
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F010,
+ .anims = NULL,
+ .images = gUnknown_82346F8,
+ .affineAnims = gUnknown_8234944,
+ .callback = oac_poke_opponent,
+ },
+};
+
+const struct SpriteTemplate gUnknown_825DF50[] =
+{
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F018,
+ .anims = NULL,
+ .images = gUnknown_8234718,
+ .affineAnims = gUnknown_82348C8,
+ .callback = sub_80120C4,
+ },
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F018,
+ .anims = NULL,
+ .images = gUnknown_8234740,
+ .affineAnims = gUnknown_82348C8,
+ .callback = sub_80120C4,
+ },
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F018,
+ .anims = NULL,
+ .images = gUnknown_82347A8,
+ .affineAnims = gUnknown_82348C8,
+ .callback = sub_80120C4,
+ },
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F018,
+ .anims = NULL,
+ .images = gUnknown_82347C8,
+ .affineAnims = gUnknown_82348C8,
+ .callback = sub_80120C4,
+ },
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F018,
+ .anims = NULL,
+ .images = gUnknown_8234768,
+ .affineAnims = gUnknown_82348C8,
+ .callback = sub_80120C4,
+ },
+ {
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = 0,
+ .oam = &gUnknown_824F018,
+ .anims = NULL,
+ .images = gUnknown_8234788,
+ .affineAnims = gUnknown_82348C8,
+ .callback = sub_80120C4,
+ },
+};
+
+static const u8 sSecretBaseFacilityClasses[][5] =
+{
+ { 0x58, 0x58, 0x58, 0x58, 0x58 },
+ { 0x58, 0x58, 0x58, 0x58, 0x58 },
+};
+
+static const u8 sGetMonDataEVConstants[] =
+{
+ MON_DATA_HP_EV,
+ MON_DATA_ATK_EV,
+ MON_DATA_DEF_EV,
+ MON_DATA_SPEED_EV,
+ MON_DATA_SPDEF_EV,
+ MON_DATA_SPATK_EV
+};
+
+static const u8 gUnknown_825DFF0[] =
+{
+ STAT_ATK, STAT_ATK, STAT_SPEED, STAT_DEF, STAT_SPATK, STAT_ACC
+};
+
+static const s8 sFriendshipEventDeltas[][3] =
+{
+ { 5, 3, 2 },
+ { 5, 3, 2 },
+ { 1, 1, 0 },
+ { 3, 2, 1 },
+ { 1, 1, 0 },
+ { 1, 1, 1 },
+ { 3, 3, 3 },
+ {-1, -1, -1 },
+ {-5, -5, -10 },
+ {-5, -5, -10 },
+};
+
+static const u16 sHMMoves[] =
+{
+ MOVE_CUT, MOVE_FLY, MOVE_SURF, MOVE_STRENGTH, MOVE_FLASH,
+ MOVE_ROCK_SMASH, MOVE_WATERFALL, MOVE_DIVE, 0xFFFF
+};
+
+static const u16 sDeoxysBaseStats[] =
+{
+ 50, // Hp
+ 180, // Attack
+ 20, // Defense
+ 150, // Speed
+ 180, // Sp.Attack
+ 20, // Sp.Defense
+};
+
+const u16 gLinkPlayerFacilityClasses[] =
+{
+ 0x74, 0x6F, 0x5C, 0x58, 0x6A,
+ 0x59, 0x6D, 0x6C, 0x75, 0x7D,
+ 0x5D, 0x5A, 0x89, 0x8A, 0x8C,
+ 0x68, 0x0,
+};
+
+const static struct OamData sOakSpeechNidoranFDummyOamData =
+{
+ .y = 0,
+ .affineMode = 0,
+ .objMode = 0,
+ .mosaic = 0,
+ .bpp = 0,
+ .shape = 0,
+ .x = 0,
+ .matrixNum = 0,
+ .size = 3,
+ .tileNum = 0,
+ .priority = 0,
+ .paletteNum = 0,
+};
+
+const struct SpriteTemplate sOakSpeechNidoranFDummyTemplate =
+{
+ .tileTag = SPRITE_INVALID_TAG,
+ .paletteTag = SPRITE_INVALID_TAG,
+ .oam = &sOakSpeechNidoranFDummyOamData,
+ .anims = gDummySpriteAnimTable,
+ .images = NULL,
+ .affineAnims = gDummySpriteAffineAnimTable,
+ .callback = SpriteCallbackDummy,
+};
// code
void ZeroBoxMonData(struct BoxPokemon *boxMon)
@@ -307,7 +558,7 @@ void CreateMonWithIVsPersonality(struct Pokemon *mon, u16 species, u8 level, u32
CalculateMonStats(mon);
}
-void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u32 otId)
+static void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u32 otId)
{
CreateMon(mon, species, level, 0, 0, 0, OT_ID_PRESET, otId);
SetMonData(mon, MON_DATA_HP_IV, &ivs[0]);
@@ -351,7 +602,7 @@ void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedI
CalculateMonStats(mon);
}
-void sub_803E0A4(struct Pokemon *mon, struct BattleTowerPokemon *src)
+void CreateBattleTowerMon(struct Pokemon *mon, struct BattleTowerPokemon *src)
{
s32 i;
u8 value;
@@ -402,7 +653,7 @@ void sub_803E0A4(struct Pokemon *mon, struct BattleTowerPokemon *src)
CalculateMonStats(mon);
}
-void CreateObedientMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
+static void CreateObedientMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
{
bool32 obedient = TRUE;
@@ -447,7 +698,7 @@ void sub_803E23C(struct Pokemon *mon, struct BattleTowerPokemon *dest)
GetMonData(mon, MON_DATA_NICKNAME, dest->nickname);
}
-u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon)
+static u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon)
{
u16 checksum = 0;
union PokemonSubstruct *substruct0 = GetSubstruct(boxMon, boxMon->personality, 0);
@@ -476,7 +727,7 @@ u16 CalculateBoxMonChecksum(struct BoxPokemon *boxMon)
u8 baseStat = gBaseStats[species].base; \
s32 n = (((2 * baseStat + iv + ev / 4) * level) / 100) + 5; \
u8 nature = GetNature(mon); \
- n = nature_stat_mod(nature, n, statIndex); \
+ n = ModifyStatByNature(nature, n, statIndex); \
SetMonData(mon, field, &n); \
}
@@ -556,7 +807,7 @@ void BoxMonToMon(struct BoxPokemon *src, struct Pokemon *dest)
CalculateMonStats(dest);
}
-u8 GetLevelFromMonExp(struct Pokemon *mon)
+static u8 GetLevelFromMonExp(struct Pokemon *mon)
{
u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL);
u32 exp = GetMonData(mon, MON_DATA_EXP, NULL);
@@ -585,7 +836,7 @@ u16 GiveMoveToMon(struct Pokemon *mon, u16 move)
return GiveMoveToBoxMon(&mon->box, move);
}
-u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
+static u16 GiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
{
s32 i;
for (i = 0; i < 4; i++)
@@ -632,7 +883,7 @@ void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot)
mon->pp[slot] = gBattleMoves[move].pp;
}
-void GiveMonInitialMoveset(struct Pokemon *mon)
+static void GiveMonInitialMoveset(struct Pokemon *mon)
{
GiveBoxMonInitialMoveset(&mon->box);
}
@@ -640,7 +891,7 @@ void GiveMonInitialMoveset(struct Pokemon *mon)
// TODO: make level_up_learnsets.h in src/data and move this to there.
#define LEVEL_UP_END 0xffff
-void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon)
+static void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon)
{
u16 species = GetBoxMonData(boxMon, MON_DATA_SPECIES, NULL);
s32 level = GetLevelFromBoxMonExp(boxMon);
@@ -722,7 +973,7 @@ void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move)
SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
}
-void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
+static void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move)
{
s32 i;
u16 moves[4];
@@ -1122,7 +1373,7 @@ u8 GetGenderFromSpeciesAndPersonality(u16 species, u32 personality)
return MON_MALE;
}
-void SetMultiuseSpriteTemplateToPokemon(u16 trainerSpriteId, u8 battlerPosition)
+void SetMultiuseSpriteTemplateToPokemon(u16 speciesTag, u8 battlerPosition)
{
if(gMonSpritesGfxPtr != NULL)
{
@@ -1133,12 +1384,12 @@ void SetMultiuseSpriteTemplateToPokemon(u16 trainerSpriteId, u8 battlerPosition)
}
else
{
- if(gUnknown_20244F4)
+ if(sOakSpeechNidoranResources)
{
- if(battlerPosition >= (s8)gUnknown_20244F4->unk0_2) // why a cast?!? changing the unk0_2 type to s8 causes extra shifts, but a cast is the correct fix. why, compiler?
+ if(battlerPosition >= (s8)sOakSpeechNidoranResources->battlePosition) // why a cast?!? changing the unk0_2 type to s8 causes extra shifts, but a cast is the correct fix. why, compiler?
battlerPosition = 0;
- gMultiuseSpriteTemplate = gUnknown_20244F4->unk10[battlerPosition];
+ gMultiuseSpriteTemplate = sOakSpeechNidoranResources->templates[battlerPosition];
}
else
{
@@ -1148,7 +1399,7 @@ void SetMultiuseSpriteTemplateToPokemon(u16 trainerSpriteId, u8 battlerPosition)
gMultiuseSpriteTemplate = gUnknown_825DEF0[battlerPosition];
}
}
- gMultiuseSpriteTemplate.paletteTag = trainerSpriteId;
+ gMultiuseSpriteTemplate.paletteTag = speciesTag;
gMultiuseSpriteTemplate.anims = gUnknown_82349BC;
}
@@ -1170,7 +1421,7 @@ void SetMultiuseSpriteTemplateToTrainerBack(u16 trainerSpriteId, u8 battlerPosit
}
}
-void EncryptBoxMon(struct BoxPokemon *boxMon)
+static void EncryptBoxMon(struct BoxPokemon *boxMon)
{
u32 i;
for (i = 0; i < 12; i++)
@@ -1180,7 +1431,7 @@ void EncryptBoxMon(struct BoxPokemon *boxMon)
}
}
-void DecryptBoxMon(struct BoxPokemon *boxMon)
+static void DecryptBoxMon(struct BoxPokemon *boxMon)
{
u32 i;
for (i = 0; i < 12; i++)
@@ -1236,7 +1487,7 @@ case n: \
break; \
} \
-union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType)
+static union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType)
{
union PokemonSubstruct *substruct = NULL;
@@ -1290,27 +1541,27 @@ u32 GetMonData(struct Pokemon *mon, s32 field, u8* data)
ret = mon->maxHP;
break;
case MON_DATA_ATK:
- ret = (u16)GetDeoxysStat(mon, STAT_ATK);
+ ret = GetDeoxysStat(mon, STAT_ATK);
if (!ret)
ret = mon->attack;
break;
case MON_DATA_DEF:
- ret = (u16)GetDeoxysStat(mon, STAT_DEF);
+ ret = GetDeoxysStat(mon, STAT_DEF);
if (!ret)
ret = mon->defense;
break;
case MON_DATA_SPEED:
- ret = (u16)GetDeoxysStat(mon, STAT_SPEED);
+ ret = GetDeoxysStat(mon, STAT_SPEED);
if (!ret)
ret = mon->speed;
break;
case MON_DATA_SPATK:
- ret = (u16)GetDeoxysStat(mon, STAT_SPATK);
+ ret = GetDeoxysStat(mon, STAT_SPATK);
if (!ret)
ret = mon->spAttack;
break;
case MON_DATA_SPDEF:
- ret = (u16)GetDeoxysStat(mon, STAT_SPDEF);
+ ret = GetDeoxysStat(mon, STAT_SPDEF);
if (!ret)
ret = mon->spDefense;
break;
@@ -2065,7 +2316,7 @@ u8 GiveMonToPlayer(struct Pokemon *mon)
return MON_GIVEN_TO_PARTY;
}
-u8 SendMonToPC(struct Pokemon* mon)
+static u8 SendMonToPC(struct Pokemon* mon)
{
s32 boxNo, boxPos;
@@ -2165,7 +2416,7 @@ u8 GetMonAbility(struct Pokemon *mon)
return GetAbilityBySpecies(species, altAbility);
}
-void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord)
+static void CreateSecretBaseEnemyParty(struct SecretBaseRecord *secretBaseRecord)
{
s32 i, j;
@@ -2224,7 +2475,7 @@ bool8 IsPlayerPartyAndPokemonStorageFull(void)
return IsPokemonStorageFull();
}
-bool8 IsPokemonStorageFull(void)
+static bool8 IsPokemonStorageFull(void)
{
s32 i, j;
@@ -2258,22 +2509,22 @@ void GetSpeciesName(u8 *name, u16 species)
u8 CalculatePPWithBonus(u16 move, u8 ppBonuses, u8 moveIndex)
{
u8 basePP = gBattleMoves[move].pp;
- return basePP + ((basePP * 20 * ((gUnknown_825DEA1[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100);
+ return basePP + ((basePP * 20 * ((gPPUpGetMask[moveIndex] & ppBonuses) >> (2 * moveIndex))) / 100);
}
void RemoveMonPPBonus(struct Pokemon *mon, u8 moveIndex)
{
u8 ppBonuses = GetMonData(mon, MON_DATA_PP_BONUSES, NULL);
- ppBonuses &= gPPUpWriteMasks[moveIndex];
+ ppBonuses &= gPPUpSetMask[moveIndex];
SetMonData(mon, MON_DATA_PP_BONUSES, &ppBonuses);
}
void RemoveBattleMonPPBonus(struct BattlePokemon *mon, u8 moveIndex)
{
- mon->ppBonuses &= gPPUpWriteMasks[moveIndex];
+ mon->ppBonuses &= gPPUpSetMask[moveIndex];
}
-void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex)
+static void CopyPlayerPartyMonToBattleData(u8 battlerId, u8 partyIndex)
{
u16* hpSwitchout;
s32 i;
@@ -2333,10 +2584,6 @@ bool8 ExecuteTableBasedItemEffect(struct Pokemon *mon, u16 item, u8 partyIndex,
return PokemonUseItemEffects(mon, item, partyIndex, moveIndex, 0);
}
-extern const u8 gUnknown_825DEA1[];
-extern const u8 gUnknown_825DEA9[];
-extern const u8 sGetMonDataEVConstants[];
-
bool8 PokemonUseItemEffects(struct Pokemon *pkmn, u16 item, u8 partyIndex, u8 moveIndex, u8 e)
{
u32 data;
@@ -2512,11 +2759,11 @@ bool8 PokemonUseItemEffects(struct Pokemon *pkmn, u16 item, u8 partyIndex, u8 mo
if (r10 & 0x20)
{
r10 &= ~0x20;
- data = (GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) & gUnknown_825DEA1[moveIndex]) >> (moveIndex * 2);
+ data = (GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) & gPPUpGetMask[moveIndex]) >> (moveIndex * 2);
sp28 = CalculatePPWithBonus(GetMonData(pkmn, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL), moveIndex);
if (data < 3 && sp28 > 4)
{
- data = GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) + gUnknown_825DEA9[moveIndex];
+ data = GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) + gPPUpAddMask[moveIndex];
SetMonData(pkmn, MON_DATA_PP_BONUSES, &data);
data = CalculatePPWithBonus(GetMonData(pkmn, MON_DATA_MOVE1 + moveIndex, NULL), data, moveIndex) - sp28;
@@ -2741,13 +2988,13 @@ bool8 PokemonUseItemEffects(struct Pokemon *pkmn, u16 item, u8 partyIndex, u8 mo
}
break;
case 4:
- data = (GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) & gUnknown_825DEA1[moveIndex]) >> (moveIndex * 2);
+ data = (GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) & gPPUpGetMask[moveIndex]) >> (moveIndex * 2);
if (data < 3)
{
r4 = CalculatePPWithBonus(GetMonData(pkmn, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL), moveIndex);
data = GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL);
- data &= gPPUpWriteMasks[moveIndex];
- data += gUnknown_825DEA9[moveIndex] * 3;
+ data &= gPPUpSetMask[moveIndex];
+ data += gPPUpAddMask[moveIndex] * 3;
SetMonData(pkmn, MON_DATA_PP_BONUSES, &data);
data = CalculatePPWithBonus(GetMonData(pkmn, MON_DATA_MOVE1 + moveIndex, NULL), data, moveIndex) - r4;
@@ -2840,7 +3087,7 @@ bool8 PokemonUseItemEffects(struct Pokemon *pkmn, u16 item, u8 partyIndex, u8 mo
return retVal;
}
-bool8 HealStatusConditions(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId)
+static bool8 HealStatusConditions(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId)
{
u32 status = GetMonData(mon, MON_DATA_STATUS, 0);
@@ -2858,8 +3105,6 @@ bool8 HealStatusConditions(struct Pokemon *mon, u32 unused, u32 healMask, u8 bat
}
}
-extern bool8 sub_8042BE8(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId);
-
#ifdef NONMATCHING
/*
* This is nonmatching due to the compiler's insistence on avoiding the u8 cast
@@ -3047,11 +3292,11 @@ bool8 PokemonUseItemEffects2(struct Pokemon *pkmn, u16 item, u8 partyIndex, u8 m
if (r10 & 0x20)
{
r10 &= ~0x20;
- data = (GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) & gUnknown_825DEA1[moveIndex]) >> (moveIndex * 2);
+ data = (GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) & gPPUpGetMask[moveIndex]) >> (moveIndex * 2);
sp28 = CalculatePPWithBonus(GetMonData(pkmn, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL), moveIndex);
if (data < 3 && sp28 > 4)
{
- //data = GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) + gUnknown_825DEA9[moveIndex];
+ //data = GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) + gPPUpAddMask[moveIndex];
//SetMonData(pkmn, MON_DATA_PP_BONUSES, &data);
//
//data = CalculatePPWithBonus(GetMonData(pkmn, MON_DATA_MOVE1 + moveIndex, NULL), data, moveIndex) - sp28;
@@ -3286,7 +3531,7 @@ bool8 PokemonUseItemEffects2(struct Pokemon *pkmn, u16 item, u8 partyIndex, u8 m
}
break;
case 4:
- data = (GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) & gUnknown_825DEA1[moveIndex]) >> (moveIndex * 2);
+ data = (GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL) & gPPUpGetMask[moveIndex]) >> (moveIndex * 2);
r4 = CalculatePPWithBonus(GetMonData(pkmn, MON_DATA_MOVE1 + moveIndex, NULL), GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL), moveIndex);
if (data < 3)
{
@@ -3295,8 +3540,8 @@ bool8 PokemonUseItemEffects2(struct Pokemon *pkmn, u16 item, u8 partyIndex, u8 m
/*
data = GetMonData(pkmn, MON_DATA_PP_BONUSES, NULL);
- data &= gPPUpWriteMasks[moveIndex];
- data += gUnknown_825DEA9[moveIndex] * 3;
+ data &= gPPUpSetMask[moveIndex];
+ data += gPPUpAddMask[moveIndex] * 3;
SetMonData(pkmn, MON_DATA_PP_BONUSES, &data);
data = CalculatePPWithBonus(GetMonData(pkmn, MON_DATA_MOVE1 + moveIndex, NULL), data, moveIndex) - r4;
@@ -3957,7 +4202,7 @@ _08042850:\n\
movs r2, 0\n\
bl GetMonData\n\
adds r5, r0, 0\n\
- ldr r0, _080428DC @ =gUnknown_825DEA1\n\
+ ldr r0, _080428DC @ =gPPUpGetMask\n\
ldr r1, [sp, 0x8]\n\
adds r0, r1, r0\n\
ldrb r0, [r0]\n\
@@ -4013,7 +4258,7 @@ _080428D2:\n\
ldr r0, [r0]\n\
mov pc, r0\n\
.align 2, 0\n\
-_080428DC: .4byte gUnknown_825DEA1\n\
+_080428DC: .4byte gPPUpGetMask\n\
_080428E0: .4byte _080428E4\n\
.align 2, 0\n\
_080428E4:\n\
@@ -4275,7 +4520,7 @@ _08042AF4:\n\
movs r2, 0\n\
bl GetMonData\n\
adds r5, r0, 0\n\
- ldr r0, _08042B48 @ =gUnknown_825DEA1\n\
+ ldr r0, _08042B48 @ =gPPUpGetMask\n\
ldr r1, [sp, 0x8]\n\
adds r0, r1, r0\n\
ldrb r0, [r0]\n\
@@ -4309,7 +4554,7 @@ _08042AF4:\n\
str r2, [sp, 0x10]\n\
b _08042BBE\n\
.align 2, 0\n\
-_08042B48: .4byte gUnknown_825DEA1\n\
+_08042B48: .4byte gPPUpGetMask\n\
_08042B4C:\n\
mov r0, r8\n\
movs r1, 0x20\n\
@@ -4397,7 +4642,7 @@ _08042BD8:\n\
}
#endif
-bool8 sub_8042BE8(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId)
+static bool8 sub_8042BE8(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId)
{
if((GetMonData(mon, MON_DATA_STATUS, NULL) & healMask) != 0)
return TRUE;
@@ -4518,7 +4763,7 @@ u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
return offset;
}
-void sub_8042D50(int stat)
+static void sub_8042D50(int stat)
{
gBattlerTarget = gBattlerInMenuId;
StringCopy(gBattleTextBuff1, gUnknown_83FD5D0[gUnknown_825DFF0[stat]]);
@@ -4581,13 +4826,11 @@ u8 GetNature(struct Pokemon *mon)
return GetMonData(mon, MON_DATA_PERSONALITY, 0) % 25;
}
-u8 GetNatureFromPersonality(u32 personality)
+static u8 GetNatureFromPersonality(u32 personality)
{
return personality % 25;
}
-extern bool32 sub_806E25C(void);
-
u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem)
{
int i;
@@ -4718,7 +4961,7 @@ u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem)
// HoennPokedexNumToSpecies, but is it really Hoenn or Kanto its checking
// TODO: Figure this out
-u16 sub_80431B4(u16 var)
+static u16 sub_80431B4(u16 var)
{
u16 species;
@@ -4755,7 +4998,7 @@ u16 NationalPokedexNumToSpecies(u16 nationalNum)
}
// NationalToKantoOrder?
-u16 sub_804324C(u16 nationalNum)
+static u16 sub_804324C(u16 nationalNum)
{
u16 hoennNum;
@@ -4783,7 +5026,7 @@ u16 SpeciesToNationalPokedexNum(u16 species)
// these 2 functions are probably kanto and not hoenn
// TODO: figure this out
-u16 SpeciesToHoennPokedexNum(u16 species)
+static u16 SpeciesToHoennPokedexNum(u16 species)
{
if (!species)
return 0;
@@ -4810,7 +5053,7 @@ u16 SpeciesToCryId(u16 species)
return gUnknown_82539D4[species - ((SPECIES_OLD_UNOWN_Z + 1) - 1)];
}
-void sub_8043338(u16 species, u32 personality, u8 *dest)
+static void sub_8043338(u16 species, u32 personality, u8 *dest)
{
if (species == SPECIES_SPINDA
&& dest != gMonSpritesGfxPtr->sprites[0]
@@ -4928,10 +5171,10 @@ bool8 sub_80435E0(void)
return retVal;
}
-bool8 sub_8043620(u8 id)
+bool8 GetLinkTrainerFlankId(u8 linkPlayerId)
{
bool8 retVal = FALSE;
- switch (gLinkPlayers[id].id)
+ switch (gLinkPlayers[linkPlayerId].id)
{
case 0:
case 3:
@@ -4954,12 +5197,12 @@ s32 GetBankMultiplayerId(u16 a1)
return id;
}
-u8 sub_804367C(u16 trainer)
+u8 GetTrainerEncounterMusicId(u16 trainer)
{
return gTrainers[trainer].encounterMusic_gender & 0x7F;
}
-u16 nature_stat_mod(u8 nature, u16 n, u8 statIndex)
+static u16 ModifyStatByNature(u8 nature, u16 n, u8 statIndex)
{
if (statIndex < 1 || statIndex > 5)
{
@@ -5204,7 +5447,7 @@ u8 CheckPartyHasHadPokerus(struct Pokemon *party, u8 selection)
return retVal;
}
-void sub_8043B38(void)
+static void sub_8043B38(void)
{
u8 foo[4]; // huh?
}
@@ -5214,7 +5457,7 @@ void sub_8043B40(void)
u8 foo[4]; // huh?
}
-void sub_8043B48(struct Pokemon *mon, int species, u8 unused, u32 data)
+static void SetMonExpWithMaxLevelCheck(struct Pokemon *mon, int species, u8 unused, u32 data)
{
if (data > gExperienceTables[gBaseStats[species].growthRate][100])
{
@@ -5235,7 +5478,7 @@ bool8 TryIncrementMonLevel(struct Pokemon *mon)
if(exp > gExperienceTables[gBaseStats[species].growthRate][newLevel])
{
SetMonData(mon, MON_DATA_LEVEL, &newLevel);
- sub_8043B48(mon, species, newLevel, exp);
+ SetMonExpWithMaxLevelCheck(mon, species, newLevel, exp);
return TRUE;
}
else
@@ -5243,7 +5486,7 @@ bool8 TryIncrementMonLevel(struct Pokemon *mon)
}
else
{
- sub_8043B48(mon, species, level, exp);
+ SetMonExpWithMaxLevelCheck(mon, species, level, exp);
return FALSE;
}
}
@@ -5377,7 +5620,7 @@ void ClearBattleMonForms(void)
gBattleMonForms[i] = 0;
}
-u16 GetMUS_ForBattle(void)
+static u16 GetMUS_ForBattle(void)
{
if(gBattleTypeFlags & 0x1000)
return 0x12A;
@@ -5480,7 +5723,7 @@ bool8 IsPokeSpriteNotFlipped(u16 species)
return gBaseStats[species].noFlip;
}
-s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor)
+static s8 GetMonFlavorRelation(struct Pokemon *mon, u8 flavor)
{
u8 nature = GetNature(mon);
return gPokeblockFlavorCompatibilityTable[nature * 5 + flavor];
@@ -5595,7 +5838,7 @@ bool8 IsMonShiny(struct Pokemon *mon)
return IsShinyOtIdPersonality(otId, personality);
}
-bool8 IsShinyOtIdPersonality(u32 otId, u32 personality)
+static bool8 IsShinyOtIdPersonality(u32 otId, u32 personality)
{
bool8 retVal = FALSE;
u32 shinyValue = HIHALF(otId) ^ LOHALF(otId) ^ HIHALF(personality) ^ LOHALF(personality);
@@ -5604,8 +5847,728 @@ bool8 IsShinyOtIdPersonality(u32 otId, u32 personality)
return retVal;
}
-u8 *sub_80444C4(void)
+u8 *GetTrainerPartnerName(void)
{
u8 id = GetMultiplayerId();
return gLinkPlayers[GetBankMultiplayerId(gLinkPlayers[id].id ^ 2)].name;
}
+
+u8 GetPlayerPartyHighestLevel(void)
+{
+ s32 slot;
+ u8 level, monLevel;
+
+ level = 1;
+ for(slot = 0; slot < PARTY_SIZE; ++slot)
+ {
+ if (GetMonData(&gPlayerParty[slot], MON_DATA_SANITY_HAS_SPECIES, NULL) == 1 && !GetMonData(&gPlayerParty[slot], MON_DATA_SANITY_IS_EGG, NULL))
+ {
+ monLevel = GetMonData(&gPlayerParty[slot], MON_DATA_LEVEL, NULL);
+ if (monLevel > level)
+ level = monLevel;
+ }
+ }
+ return level;
+}
+
+u16 FacilityClassToPicIndex(u16 facilityClass)
+{
+ return gFacilityClassToPicIndex[facilityClass];
+}
+
+bool8 sub_804455C(u8 caseId, u8 battlerId)
+{
+ switch (caseId)
+ {
+ case 0:
+ default:
+ return FALSE;
+ case 1:
+ if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
+ return FALSE;
+ if (!gMain.inBattle)
+ return FALSE;
+ if (gLinkPlayers[GetMultiplayerId()].id == battlerId)
+ return FALSE;
+ break;
+ case 2:
+ break;
+ case 3:
+ if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI))
+ return FALSE;
+ if (!gMain.inBattle)
+ return FALSE;
+ if (battlerId == 1 || battlerId == 4 || battlerId == 5)
+ return TRUE;
+ return FALSE;
+ case 4:
+ break;
+ case 5:
+ if (gBattleTypeFlags & BATTLE_TYPE_LINK)
+ {
+ if (!gMain.inBattle)
+ return FALSE;
+ if (gBattleTypeFlags & BATTLE_TYPE_MULTI)
+ {
+ if (gLinkPlayers[GetMultiplayerId()].id == battlerId)
+ return FALSE;
+ }
+ else
+ {
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!gMain.inBattle)
+ return FALSE;
+ if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
+ return FALSE;
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+static u16 GetDeoxysStat(struct Pokemon *mon, s32 statId)
+{
+ s32 ivVal, evVal;
+ u16 statValue;
+ u8 nature;
+
+ if (gBattleTypeFlags & BATTLE_TYPE_20 || GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS)
+ {
+ return statValue = 0;
+ }
+ else
+ {
+ ivVal = GetMonData(mon, MON_DATA_HP_IV + statId, NULL);
+ evVal = GetMonData(mon, MON_DATA_HP_EV + statId, NULL);
+ statValue = ((sDeoxysBaseStats[statId] * 2 + ivVal + evVal / 4) * mon->level) / 100 + 5;
+ nature = GetNature(mon);
+ statValue = ModifyStatByNature(nature, statValue, (u8)statId);
+ }
+ return statValue;
+}
+
+void SetDeoxysStats(void)
+{
+ s32 i, value;
+
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ struct Pokemon *mon = &gPlayerParty[i];
+
+ if (GetMonData(mon, MON_DATA_SPECIES, NULL) != SPECIES_DEOXYS)
+ continue;
+ value = GetMonData(mon, MON_DATA_ATK, NULL);
+ SetMonData(mon, MON_DATA_ATK, &value);
+ value = GetMonData(mon, MON_DATA_DEF, NULL);
+ SetMonData(mon, MON_DATA_DEF, &value);
+ value = GetMonData(mon, MON_DATA_SPEED, NULL);
+ SetMonData(mon, MON_DATA_SPEED, &value);
+ value = GetMonData(mon, MON_DATA_SPATK, NULL);
+ SetMonData(mon, MON_DATA_SPATK, &value);
+ value = GetMonData(mon, MON_DATA_SPDEF, NULL);
+ SetMonData(mon, MON_DATA_SPDEF, &value);
+ }
+}
+
+u16 sub_80447AC(void)
+{
+ u8 linkId = GetMultiplayerId() ^ 1;
+ u32 arrId = gLinkPlayers[linkId].trainerId & 7;
+
+ arrId |= gLinkPlayers[linkId].gender << 3;
+ return FacilityClassToPicIndex(gLinkPlayerFacilityClasses[arrId]);
+}
+
+u16 sub_80447F0(void)
+{
+ u8 linkId = GetMultiplayerId() ^ 1;
+ u32 arrId = gLinkPlayers[linkId].trainerId & 7;
+
+ arrId |= gLinkPlayers[linkId].gender << 3;
+ return gFacilityClassToTrainerClass[gLinkPlayerFacilityClasses[arrId]];
+}
+
+void CreateObedientEnemyMon(void)
+{
+ s32 species = gSpecialVar_0x8004;
+ s32 level = gSpecialVar_0x8005;
+ s32 itemId = gSpecialVar_0x8006;
+
+ ZeroEnemyPartyMons();
+ CreateObedientMon(&gEnemyParty[0], species, level, 32, 0, 0, 0, 0);
+ if (itemId)
+ {
+ u8 heldItem[2];
+
+ heldItem[0] = itemId;
+ heldItem[1] = itemId >> 8;
+ SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem);
+ }
+}
+
+void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality)
+{
+ u8 getFlagCaseId = (caseId == FLAG_SET_SEEN) ? FLAG_GET_SEEN : FLAG_GET_CAUGHT;
+
+ if (!GetSetPokedexFlag(nationalNum, getFlagCaseId))
+ {
+ GetSetPokedexFlag(nationalNum, caseId);
+ if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_UNOWN)
+ gSaveBlock2Ptr->pokedex.unownPersonality = personality;
+ if (NationalPokedexNumToSpecies(nationalNum) == SPECIES_SPINDA)
+ gSaveBlock2Ptr->pokedex.spindaPersonality = personality;
+ }
+}
+
+bool8 CheckBattleTypeGhost(struct Pokemon *mon, u8 bank)
+{
+ u8 buffer[12];
+
+ if (gBattleTypeFlags & BATTLE_TYPE_GHOST && GetBattlerSide(bank))
+ {
+ GetMonData(mon, MON_DATA_NICKNAME, buffer);
+ StringGetEnd10(buffer);
+ if (!StringCompare(buffer, gUnknown_841D148))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void OakSpeechNidoranFSetupTemplate(struct OakSpeechNidoranFStruct *structPtr, u8 battlePosition)
+{
+ u16 i = 0, j = 0;
+
+ if (battlePosition > 3)
+ {
+ for (i = 0; i < (s8)structPtr->spriteCount; ++i)
+ {
+ structPtr->templates[i] = gUnknown_825DEF0[i];
+ for (j = 0; j < structPtr->frameCount; ++j)
+ structPtr->frameImages[i * structPtr->frameCount + j].data = &structPtr->bufferPtrs[i][j * 0x800];
+ structPtr->templates[i].images = &structPtr->frameImages[i * structPtr->frameCount];
+ }
+ }
+ else
+ {
+ const struct SpriteTemplate *template = &gUnknown_825DEF0[battlePosition];
+
+ structPtr->templates[0] = *template;
+ for (j = 0; j < structPtr->frameCount; ++j)
+ structPtr->frameImages[j].data = &structPtr->bufferPtrs[0][j * 0x800];
+ structPtr->templates[0].images = structPtr->frameImages;
+ }
+}
+
+// not used
+static void OakSpeechNidoranFSetupTemplateDummy(struct OakSpeechNidoranFStruct *structPtr)
+{
+ u16 i, j;
+
+ for (i = 0; i < (s8)structPtr->spriteCount; ++i)
+ {
+ structPtr->templates[i] = sOakSpeechNidoranFDummyTemplate;
+ for (j = 0; j < structPtr->frameCount; ++j)
+ structPtr->frameImages[i * structPtr->spriteCount + j].data = &structPtr->bufferPtrs[i][j * 0x800];
+ structPtr->templates[i].images = &structPtr->frameImages[i * structPtr->spriteCount]; // should be frameCount logically
+ structPtr->templates[i].anims = gUnknown_82349BC;
+ structPtr->templates[i].paletteTag = i;
+ }
+}
+
+#ifdef NONMATCHING
+struct OakSpeechNidoranFStruct *OakSpeechNidoranFSetup(u8 battlePosition, bool8 enable)
+{
+ s32 size;
+ u8 i, flags = 0;
+
+ if (sOakSpeechNidoranResources != NULL)
+ {
+ if (sOakSpeechNidoranResources->enable == 0xA3)
+ return NULL;
+ memset(sOakSpeechNidoranResources, 0, sizeof(struct OakSpeechNidoranFStruct));
+ sOakSpeechNidoranResources = NULL;
+ }
+ sOakSpeechNidoranResources = AllocZeroed(0x18);
+ if (sOakSpeechNidoranResources == NULL)
+ return NULL;
+ switch (enable)
+ {
+ case TRUE:
+ if (battlePosition == 4)
+ {
+ sOakSpeechNidoranResources->spriteCount = 4;
+ sOakSpeechNidoranResources->battlePosition = 4;
+ }
+ else
+ {
+ if (battlePosition > 4)
+ battlePosition = 0;
+ sOakSpeechNidoranResources->spriteCount = 1;
+ sOakSpeechNidoranResources->battlePosition = 1;
+ }
+ sOakSpeechNidoranResources->frameCount = 4;
+ sOakSpeechNidoranResources->enable2 = TRUE;
+ break;
+ case FALSE:
+ default:
+ if (!battlePosition)
+ battlePosition = 1;
+ if (battlePosition > 8)
+ battlePosition = 8;
+ // The following two statements refused to cooperate.
+ sOakSpeechNidoranResources->spriteCount = battlePosition;
+ sOakSpeechNidoranResources->battlePosition = battlePosition;
+ sOakSpeechNidoranResources->frameCount = 4;
+ sOakSpeechNidoranResources->enable2 = FALSE;
+ break;
+ }
+ size = sOakSpeechNidoranResources->frameCount * 0x800;
+ sOakSpeechNidoranResources->sizePerSprite = size;
+ sOakSpeechNidoranResources->dataBuffer = AllocZeroed(sOakSpeechNidoranResources->spriteCount * size);
+ sOakSpeechNidoranResources->bufferPtrs = AllocZeroed(sOakSpeechNidoranResources->spriteCount * 0x20);
+ if (sOakSpeechNidoranResources->dataBuffer == NULL || sOakSpeechNidoranResources->bufferPtrs == NULL)
+ {
+ flags |= 1;
+ }
+ else
+ {
+ for (i = 0; i < (s8)sOakSpeechNidoranResources->spriteCount; ++i)
+ sOakSpeechNidoranResources->bufferPtrs[i] = &sOakSpeechNidoranResources->dataBuffer[sOakSpeechNidoranResources->sizePerSprite * i];
+ }
+ sOakSpeechNidoranResources->templates = AllocZeroed(sizeof(struct SpriteTemplate) * sOakSpeechNidoranResources->spriteCount);
+ sOakSpeechNidoranResources->frameImages = AllocZeroed(sOakSpeechNidoranResources->spriteCount * sizeof(struct SpriteFrameImage) * sOakSpeechNidoranResources->frameCount);
+ if (sOakSpeechNidoranResources->templates == NULL || sOakSpeechNidoranResources->frameImages == NULL)
+ {
+ flags |= 2;
+ }
+ else
+ {
+ for (i = 0; i < sOakSpeechNidoranResources->frameCount * sOakSpeechNidoranResources->spriteCount; ++i)
+ sOakSpeechNidoranResources->frameImages[i].size = 0x800;
+ switch (sOakSpeechNidoranResources->enable2)
+ {
+ case TRUE:
+ OakSpeechNidoranFSetupTemplate(sOakSpeechNidoranResources, battlePosition);
+ break;
+ case FALSE:
+ default:
+ OakSpeechNidoranFSetupTemplateDummy(sOakSpeechNidoranResources);
+ break;
+ }
+ }
+ if (flags & 2)
+ {
+ if (sOakSpeechNidoranResources->frameImages != NULL)
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources->frameImages);
+ if (sOakSpeechNidoranResources->templates != NULL)
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources->templates);
+ }
+ if (flags & 1)
+ {
+ if (sOakSpeechNidoranResources->bufferPtrs != NULL)
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources->bufferPtrs);
+ if (sOakSpeechNidoranResources->dataBuffer != NULL)
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources->dataBuffer);
+ }
+ if (flags)
+ {
+ memset(sOakSpeechNidoranResources, 0, sizeof(struct OakSpeechNidoranFStruct));
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources);
+ }
+ else
+ {
+ sOakSpeechNidoranResources->enable = 0xA3;
+ }
+ return sOakSpeechNidoranResources;
+}
+#else
+NAKED
+struct OakSpeechNidoranFStruct *OakSpeechNidoranFSetup(u8 battlePosition, bool8 enable)
+{
+ asm_unified("\n\
+ push {r4-r7,lr}\n\
+ mov r7, r8\n\
+ push {r7}\n\
+ lsls r0, 24\n\
+ lsrs r6, r0, 24\n\
+ lsls r1, 24\n\
+ lsrs r5, r1, 24\n\
+ movs r0, 0\n\
+ mov r8, r0\n\
+ ldr r4, _08044B34 @ =sOakSpeechNidoranResources\n\
+ ldr r1, [r4]\n\
+ cmp r1, 0\n\
+ beq _08044B1E\n\
+ ldrb r0, [r1, 0x2]\n\
+ cmp r0, 0xA3\n\
+ beq _08044B2E\n\
+ adds r0, r1, 0\n\
+ movs r1, 0\n\
+ movs r2, 0x18\n\
+ bl memset\n\
+ mov r1, r8\n\
+ str r1, [r4]\n\
+ _08044B1E:\n\
+ ldr r4, _08044B34 @ =sOakSpeechNidoranResources\n\
+ movs r0, 0x18\n\
+ bl AllocZeroed\n\
+ adds r2, r0, 0\n\
+ str r2, [r4]\n\
+ cmp r2, 0\n\
+ bne _08044B38\n\
+ _08044B2E:\n\
+ movs r0, 0\n\
+ b _08044D70\n\
+ .align 2, 0\n\
+ _08044B34: .4byte sOakSpeechNidoranResources\n\
+ _08044B38:\n\
+ cmp r5, 0\n\
+ beq _08044B94\n\
+ cmp r5, 0x1\n\
+ bne _08044B94\n\
+ cmp r6, 0x4\n\
+ bne _08044B5E\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0x10\n\
+ negs r0, r0\n\
+ ands r0, r1\n\
+ movs r1, 0x4\n\
+ orrs r0, r1\n\
+ strb r0, [r2]\n\
+ ldr r2, [r4]\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF\n\
+ ands r0, r1\n\
+ movs r1, 0x40\n\
+ b _08044B7C\n\
+ _08044B5E:\n\
+ cmp r6, 0x4\n\
+ bls _08044B64\n\
+ movs r6, 0\n\
+ _08044B64:\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0x10\n\
+ negs r0, r0\n\
+ ands r0, r1\n\
+ movs r1, 0x1\n\
+ orrs r0, r1\n\
+ strb r0, [r2]\n\
+ ldr r2, [r4]\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF\n\
+ ands r0, r1\n\
+ movs r1, 0x10\n\
+ _08044B7C:\n\
+ orrs r0, r1\n\
+ strb r0, [r2]\n\
+ ldr r2, _08044B90 @ =sOakSpeechNidoranResources\n\
+ ldr r1, [r2]\n\
+ movs r0, 0x4\n\
+ strb r0, [r1, 0x1]\n\
+ ldr r1, [r2]\n\
+ movs r0, 0x1\n\
+ strb r0, [r1, 0x3]\n\
+ b _08044BD0\n\
+ .align 2, 0\n\
+ _08044B90: .4byte sOakSpeechNidoranResources\n\
+ _08044B94:\n\
+ cmp r6, 0\n\
+ bne _08044B9A\n\
+ movs r6, 0x1\n\
+ _08044B9A:\n\
+ cmp r6, 0x8\n\
+ bls _08044BA0\n\
+ movs r6, 0x8\n\
+ _08044BA0:\n\
+ ldr r4, _08044C10 @ =sOakSpeechNidoranResources\n\
+ ldr r3, [r4]\n\
+ movs r0, 0xF\n\
+ adds r1, r6, 0\n\
+ ands r1, r0\n\
+ ldrb r2, [r3]\n\
+ movs r0, 0x10\n\
+ negs r0, r0\n\
+ ands r0, r2\n\
+ orrs r0, r1\n\
+ strb r0, [r3]\n\
+ ldr r2, [r4]\n\
+ lsls r3, r6, 4\n\
+ ldrb r1, [r2]\n\
+ movs r0, 0xF\n\
+ ands r0, r1\n\
+ orrs r0, r3\n\
+ strb r0, [r2]\n\
+ ldr r1, [r4]\n\
+ movs r2, 0\n\
+ movs r0, 0x4\n\
+ strb r0, [r1, 0x1]\n\
+ ldr r0, [r4]\n\
+ strb r2, [r0, 0x3]\n\
+ _08044BD0:\n\
+ ldr r5, _08044C10 @ =sOakSpeechNidoranResources\n\
+ ldr r0, [r5]\n\
+ ldrb r1, [r0, 0x1]\n\
+ lsls r1, 11\n\
+ str r1, [r0, 0x4]\n\
+ ldrb r0, [r0]\n\
+ lsls r0, 28\n\
+ lsrs r0, 28\n\
+ muls r0, r1\n\
+ bl AllocZeroed\n\
+ ldr r1, [r5]\n\
+ str r0, [r1, 0x8]\n\
+ ldrb r0, [r1]\n\
+ lsls r0, 28\n\
+ lsrs r0, 23\n\
+ bl AllocZeroed\n\
+ adds r2, r0, 0\n\
+ ldr r1, [r5]\n\
+ str r2, [r1, 0xC]\n\
+ ldr r0, [r1, 0x8]\n\
+ cmp r0, 0\n\
+ beq _08044C04\n\
+ cmp r2, 0\n\
+ bne _08044C14\n\
+ _08044C04:\n\
+ movs r0, 0x1\n\
+ mov r1, r8\n\
+ orrs r1, r0\n\
+ mov r8, r1\n\
+ b _08044C44\n\
+ .align 2, 0\n\
+ _08044C10: .4byte sOakSpeechNidoranResources\n\
+ _08044C14:\n\
+ ldrb r0, [r1]\n\
+ lsls r0, 28\n\
+ movs r4, 0\n\
+ adds r3, r5, 0\n\
+ cmp r0, 0\n\
+ beq _08044C44\n\
+ _08044C20:\n\
+ ldr r3, [r5]\n\
+ ldr r0, [r3, 0xC]\n\
+ lsls r1, r4, 2\n\
+ adds r1, r0\n\
+ ldr r0, [r3, 0x4]\n\
+ adds r2, r0, 0\n\
+ muls r2, r4\n\
+ ldr r0, [r3, 0x8]\n\
+ adds r0, r2\n\
+ str r0, [r1]\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ ldrb r0, [r3]\n\
+ lsls r0, 28\n\
+ lsrs r0, 28\n\
+ cmp r4, r0\n\
+ blt _08044C20\n\
+ _08044C44:\n\
+ ldr r5, _08044C8C @ =sOakSpeechNidoranResources\n\
+ ldr r0, [r5]\n\
+ ldrb r1, [r0]\n\
+ lsls r1, 28\n\
+ lsrs r1, 28\n\
+ lsls r0, r1, 1\n\
+ adds r0, r1\n\
+ lsls r0, 3\n\
+ bl AllocZeroed\n\
+ ldr r2, [r5]\n\
+ str r0, [r2, 0x10]\n\
+ ldrb r1, [r2]\n\
+ lsls r1, 28\n\
+ lsrs r1, 28\n\
+ ldrb r0, [r2, 0x1]\n\
+ lsls r0, 3\n\
+ muls r0, r1\n\
+ bl AllocZeroed\n\
+ adds r2, r0, 0\n\
+ ldr r1, [r5]\n\
+ str r2, [r1, 0x14]\n\
+ ldr r0, [r1, 0x10]\n\
+ cmp r0, 0\n\
+ beq _08044C7C\n\
+ cmp r2, 0\n\
+ bne _08044C90\n\
+ _08044C7C:\n\
+ movs r0, 0x2\n\
+ mov r1, r8\n\
+ orrs r1, r0\n\
+ lsls r0, r1, 24\n\
+ lsrs r0, 24\n\
+ mov r8, r0\n\
+ b _08044CE2\n\
+ .align 2, 0\n\
+ _08044C8C: .4byte sOakSpeechNidoranResources\n\
+ _08044C90:\n\
+ movs r4, 0\n\
+ ldrb r0, [r1, 0x1]\n\
+ ldrb r1, [r1]\n\
+ lsls r1, 28\n\
+ lsrs r1, 28\n\
+ muls r0, r1\n\
+ adds r3, r5, 0\n\
+ cmp r4, r0\n\
+ bge _08044CC6\n\
+ adds r7, r3, 0\n\
+ movs r5, 0x80\n\
+ lsls r5, 4\n\
+ _08044CA8:\n\
+ ldr r2, [r7]\n\
+ ldr r1, [r2, 0x14]\n\
+ lsls r0, r4, 3\n\
+ adds r0, r1\n\
+ strh r5, [r0, 0x4]\n\
+ adds r0, r4, 0x1\n\
+ lsls r0, 24\n\
+ lsrs r4, r0, 24\n\
+ ldrb r1, [r2, 0x1]\n\
+ ldrb r0, [r2]\n\
+ lsls r0, 28\n\
+ lsrs r0, 28\n\
+ muls r0, r1\n\
+ cmp r4, r0\n\
+ blt _08044CA8\n\
+ _08044CC6:\n\
+ ldr r0, [r3]\n\
+ ldrb r4, [r0, 0x3]\n\
+ cmp r4, 0\n\
+ beq _08044CDA\n\
+ cmp r4, 0x1\n\
+ bne _08044CDA\n\
+ adds r1, r6, 0\n\
+ bl OakSpeechNidoranFSetupTemplate\n\
+ b _08044CE2\n\
+ _08044CDA:\n\
+ ldr r0, _08044D60 @ =sOakSpeechNidoranResources\n\
+ ldr r0, [r0]\n\
+ bl OakSpeechNidoranFSetupTemplateDummy\n\
+ _08044CE2:\n\
+ movs r0, 0x2\n\
+ mov r1, r8\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _08044D12\n\
+ ldr r4, _08044D60 @ =sOakSpeechNidoranResources\n\
+ ldr r0, [r4]\n\
+ ldr r0, [r0, 0x14]\n\
+ cmp r0, 0\n\
+ beq _08044D00\n\
+ bl Free\n\
+ ldr r1, [r4]\n\
+ movs r0, 0\n\
+ str r0, [r1, 0x14]\n\
+ _08044D00:\n\
+ ldr r0, [r4]\n\
+ ldr r0, [r0, 0x10]\n\
+ cmp r0, 0\n\
+ beq _08044D12\n\
+ bl Free\n\
+ ldr r1, [r4]\n\
+ movs r0, 0\n\
+ str r0, [r1, 0x10]\n\
+ _08044D12:\n\
+ movs r0, 0x1\n\
+ mov r1, r8\n\
+ ands r0, r1\n\
+ cmp r0, 0\n\
+ beq _08044D42\n\
+ ldr r4, _08044D60 @ =sOakSpeechNidoranResources\n\
+ ldr r0, [r4]\n\
+ ldr r0, [r0, 0xC]\n\
+ cmp r0, 0\n\
+ beq _08044D30\n\
+ bl Free\n\
+ ldr r1, [r4]\n\
+ movs r0, 0\n\
+ str r0, [r1, 0xC]\n\
+ _08044D30:\n\
+ ldr r0, [r4]\n\
+ ldr r0, [r0, 0x8]\n\
+ cmp r0, 0\n\
+ beq _08044D42\n\
+ bl Free\n\
+ ldr r1, [r4]\n\
+ movs r0, 0\n\
+ str r0, [r1, 0x8]\n\
+ _08044D42:\n\
+ mov r0, r8\n\
+ cmp r0, 0\n\
+ beq _08044D64\n\
+ ldr r4, _08044D60 @ =sOakSpeechNidoranResources\n\
+ ldr r0, [r4]\n\
+ movs r1, 0\n\
+ movs r2, 0x18\n\
+ bl memset\n\
+ ldr r0, [r4]\n\
+ bl Free\n\
+ movs r0, 0\n\
+ str r0, [r4]\n\
+ b _08044D6C\n\
+ .align 2, 0\n\
+ _08044D60: .4byte sOakSpeechNidoranResources\n\
+ _08044D64:\n\
+ ldr r0, _08044D7C @ =sOakSpeechNidoranResources\n\
+ ldr r1, [r0]\n\
+ movs r0, 0xA3\n\
+ strb r0, [r1, 0x2]\n\
+ _08044D6C:\n\
+ ldr r0, _08044D7C @ =sOakSpeechNidoranResources\n\
+ ldr r0, [r0]\n\
+ _08044D70:\n\
+ pop {r3}\n\
+ mov r8, r3\n\
+ pop {r4-r7}\n\
+ pop {r1}\n\
+ bx r1\n\
+ .align 2, 0\n\
+ _08044D7C: .4byte sOakSpeechNidoranResources\n\
+ ");
+}
+#endif
+
+void OakSpeechNidoranFFreeResources(void)
+{
+ if (sOakSpeechNidoranResources != NULL)
+ {
+ if (sOakSpeechNidoranResources->enable != 0xA3)
+ {
+ memset(sOakSpeechNidoranResources, 0, sizeof(struct OakSpeechNidoranFStruct));
+ sOakSpeechNidoranResources = NULL;
+ }
+ else
+ {
+ if (sOakSpeechNidoranResources->frameImages != NULL)
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources->frameImages);
+ if (sOakSpeechNidoranResources->templates != NULL)
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources->templates);
+ if (sOakSpeechNidoranResources->bufferPtrs != NULL)
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources->bufferPtrs);
+ if (sOakSpeechNidoranResources->dataBuffer != NULL)
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources->dataBuffer);
+ memset(sOakSpeechNidoranResources, 0, sizeof(struct OakSpeechNidoranFStruct));
+ FREE_AND_SET_NULL(sOakSpeechNidoranResources);
+ }
+
+ }
+}
+
+void *OakSpeechNidoranFGetBuffer(u8 bufferId)
+{
+ if (sOakSpeechNidoranResources->enable != 0xA3)
+ {
+ return NULL;
+ }
+ else
+ {
+ if (bufferId >= (s8)sOakSpeechNidoranResources->spriteCount)
+ bufferId = 0;
+ return sOakSpeechNidoranResources->bufferPtrs[bufferId];
+ }
+}
diff --git a/src/trainer_tower.c b/src/trainer_tower.c
index b7b9c096d..cdb42ca96 100644
--- a/src/trainer_tower.c
+++ b/src/trainer_tower.c
@@ -1378,21 +1378,21 @@ void sub_815E9FC(void)
{
r2 = gUnknown_847A2EE[r5][r6];
gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[r4].unk_040[r2].level = r9;
- sub_803E0A4(&gEnemyParty[r6], &gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[r4].unk_040[r2]);
+ CreateBattleTowerMon(&gEnemyParty[r6], &gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[r4].unk_040[r2]);
}
break;
case 1:
r2 = gUnknown_847A2FE[r5][0];
gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[0].unk_040[r2].level = r9;
- sub_803E0A4(&gEnemyParty[0], &gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[0].unk_040[r2]);
+ CreateBattleTowerMon(&gEnemyParty[0], &gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[0].unk_040[r2]);
r2 = gUnknown_847A2FE[r5][1];
gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[1].unk_040[r2].level = r9;
- sub_803E0A4(&gEnemyParty[1], &gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[1].unk_040[r2]);
+ CreateBattleTowerMon(&gEnemyParty[1], &gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[1].unk_040[r2]);
break;
case 2:
r2 = gUnknown_847A30E[r5][r4];
gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[r4].unk_040[r2].level = r9;
- sub_803E0A4(&gEnemyParty[0], &gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[r4].unk_040[r2]);
+ CreateBattleTowerMon(&gEnemyParty[0], &gUnknown_203F458->unk_0004.trainers[gUnknown_203F458->unk_0000].unk_004[r4].unk_040[r2]);
break;
}
}