summaryrefslogtreecommitdiff
path: root/arm9/src
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/src')
-rw-r--r--arm9/src/pokemon.c415
-rw-r--r--arm9/src/string_util.c3
2 files changed, 410 insertions, 8 deletions
diff --git a/arm9/src/pokemon.c b/arm9/src/pokemon.c
index 591bf401..43404100 100644
--- a/arm9/src/pokemon.c
+++ b/arm9/src/pokemon.c
@@ -1,9 +1,14 @@
#include "global.h"
#define IN_POKEMON_C
+#include "proto.h"
#include "pokemon.h"
#include "heap.h"
#include "MI_memory.h"
#include "math_util.h"
+#include "move_data.h"
+#include "string_util.h"
+#include "text.h"
+#include "constants/abilities.h"
#pragma thumb on
@@ -12,8 +17,9 @@ void MonDecryptSegment(void * datap, u32 size, u32 key);
u16 MonEncryptionLCRNG(u32 * seed);
u16 CalcMonChecksum(void * datap, u32 size);
void InitBoxMonMoveset(struct BoxPokemon * boxmon);
-u32 GetMonDataInternal(struct Pokemon * pokemon, u32 attr, void * ptr);
-u32 GetBoxMonDataInternal(struct BoxPokemon * pokemon, u32 attr, void * ptr);
+u32 GetMonDataInternal(struct Pokemon * pokemon, int attr, void * ptr);
+PokemonDataBlock * GetSubstruct(struct BoxPokemon * boxmon, u32 personality, u32 which_struct);
+u32 GetBoxMonDataInternal(struct BoxPokemon * pokemon, int attr, void * ptr);
void LoadMonBaseStats_HandleAlternateForme(u32 species, u32 forme, struct BaseStats * baseStats);
int ApplyNatureModToStat(u8 nature, u16 statval, u32 statno);
@@ -466,7 +472,7 @@ void CalcMonStats(struct Pokemon * pokemon)
TryEncryptMon(pokemon, decry);
}
-u32 GetMonData(struct Pokemon * pokemon, u32 attr, void * dest)
+u32 GetMonData(struct Pokemon * pokemon, int attr, void * dest)
{
u32 ret;
u32 checksum;
@@ -490,7 +496,7 @@ u32 GetMonData(struct Pokemon * pokemon, u32 attr, void * dest)
return ret;
}
-u32 GetMonDataInternal(struct Pokemon * pokemon, u32 attr, void * dest)
+u32 GetMonDataInternal(struct Pokemon * pokemon, int attr, void * dest)
{
switch (attr)
{
@@ -525,7 +531,7 @@ u32 GetMonDataInternal(struct Pokemon * pokemon, u32 attr, void * dest)
}
}
-u32 GetBoxMonData(struct BoxPokemon * boxmon, u32 attr, void * dest)
+u32 GetBoxMonData(struct BoxPokemon * boxmon, int attr, void * dest)
{
u32 ret;
u32 checksum;
@@ -546,3 +552,402 @@ u32 GetBoxMonData(struct BoxPokemon * boxmon, u32 attr, void * dest)
}
return ret;
}
+
+u32 GetBoxMonDataInternal(struct BoxPokemon * boxmon, int attr, void * dest)
+{
+ u32 ret = 0;
+ PokemonDataBlockA * blockA = &GetSubstruct(boxmon, boxmon->pid, 0)->blockA;
+ PokemonDataBlockB * blockB = &GetSubstruct(boxmon, boxmon->pid, 1)->blockB;
+ PokemonDataBlockC * blockC = &GetSubstruct(boxmon, boxmon->pid, 2)->blockC;
+ PokemonDataBlockD * blockD = &GetSubstruct(boxmon, boxmon->pid, 3)->blockD;
+
+ switch (attr)
+ {
+ default:
+ ret = 0;
+ break;
+ case MON_DATA_PERSONALITY:
+ ret = boxmon->pid;
+ break;
+ case MON_DATA_PARTY_LOCK:
+ ret = boxmon->party_lock;
+ break;
+ case MON_DATA_BOX_LOCK:
+ ret = boxmon->box_lock;
+ break;
+ case MON_DATA_CHECKSUM_FAILED:
+ ret = boxmon->checksum_fail;
+ break;
+ case MON_DATA_CHECKSUM:
+ ret = boxmon->checksum;
+ break;
+ case MON_DATA_SPECIES_EXISTS:
+ if (blockA->species != SPECIES_NONE)
+ ret = TRUE;
+ else
+ ret = FALSE;
+ break;
+ case MON_DATA_SANITY_IS_EGG:
+ ret = boxmon->checksum_fail;
+ if (!ret)
+ ret = blockB->isEgg;
+ break;
+ case MON_DATA_SPECIES2:
+ ret = blockA->species;
+ if (ret != SPECIES_NONE && (blockB->isEgg || boxmon->checksum_fail))
+ ret = SPECIES_EGG;
+ break;
+ case MON_DATA_LEVEL:
+ ret = CalcLevelBySpeciesAndExp(blockA->species, blockA->exp);
+ break;
+ case MON_DATA_SPECIES:
+ if (boxmon->checksum_fail)
+ ret = SPECIES_EGG;
+ else
+ ret = blockA->species;
+ break;
+ case MON_DATA_HELD_ITEM:
+ ret = blockA->heldItem;
+ break;
+ case MON_DATA_OTID:
+ ret = blockA->otID;
+ break;
+ case MON_DATA_EXPERIENCE:
+ ret = blockA->exp;
+ break;
+ case MON_DATA_FRIENDSHIP:
+ ret = blockA->friendship;
+ break;
+ case MON_DATA_ABILITY:
+ ret = blockA->ability;
+ break;
+ case MON_DATA_MARKINGS:
+ ret = blockA->markings;
+ break;
+ case MON_DATA_GAME_LANGUAGE:
+ ret = blockA->originLanguage;
+ break;
+ case MON_DATA_HP_EV:
+ ret = blockA->hpEV;
+ break;
+ case MON_DATA_ATK_EV:
+ ret = blockA->atkEV;
+ break;
+ case MON_DATA_DEF_EV:
+ ret = blockA->defEV;
+ break;
+ case MON_DATA_SPEED_EV:
+ ret = blockA->spdEV;
+ break;
+ case MON_DATA_SPATK_EV:
+ ret = blockA->spatkEV;
+ break;
+ case MON_DATA_SPDEF_EV:
+ ret = blockA->spdefEV;
+ break;
+ case MON_DATA_COOL:
+ ret = blockA->coolStat;
+ break;
+ case MON_DATA_BEAUTY:
+ ret = blockA->beautyStat;
+ break;
+ case MON_DATA_CUTE:
+ ret = blockA->cuteStat;
+ break;
+ case MON_DATA_SMART:
+ ret = blockA->smartStat;
+ break;
+ case MON_DATA_TOUGH:
+ ret = blockA->toughStat;
+ break;
+ case MON_DATA_SHEEN:
+ ret = blockA->sheen;
+ break;
+ case MON_DATA_SINNOH_CHAMP_RIBBON:
+ case MON_DATA_SINNOH_RIBBON_26:
+ case MON_DATA_SINNOH_RIBBON_27:
+ case MON_DATA_SINNOH_RIBBON_28:
+ case MON_DATA_SINNOH_RIBBON_29:
+ case MON_DATA_SINNOH_RIBBON_30:
+ case MON_DATA_SINNOH_RIBBON_31:
+ case MON_DATA_SINNOH_RIBBON_32:
+ case MON_DATA_SINNOH_RIBBON_33:
+ case MON_DATA_SINNOH_RIBBON_34:
+ case MON_DATA_SINNOH_RIBBON_35:
+ case MON_DATA_SINNOH_RIBBON_36:
+ case MON_DATA_SINNOH_RIBBON_37:
+ case MON_DATA_SINNOH_RIBBON_38:
+ case MON_DATA_SINNOH_RIBBON_39:
+ case MON_DATA_SINNOH_RIBBON_40:
+ case MON_DATA_SINNOH_RIBBON_41:
+ case MON_DATA_SINNOH_RIBBON_42:
+ case MON_DATA_SINNOH_RIBBON_43:
+ case MON_DATA_SINNOH_RIBBON_44:
+ case MON_DATA_SINNOH_RIBBON_45:
+ case MON_DATA_SINNOH_RIBBON_46:
+ case MON_DATA_SINNOH_RIBBON_47:
+ case MON_DATA_SINNOH_RIBBON_48:
+ case MON_DATA_SINNOH_RIBBON_49:
+ case MON_DATA_SINNOH_RIBBON_50:
+ case MON_DATA_SINNOH_RIBBON_51:
+ case MON_DATA_SINNOH_RIBBON_52:
+ case MON_DATA_SINNOH_RIBBON_53:
+ {
+ if (blockA->sinnohRibbons & (1ll << (attr - MON_DATA_SINNOH_CHAMP_RIBBON)))
+ {
+ ret = TRUE;
+ }
+ else
+ {
+ ret = FALSE;
+ }
+ }
+ break;
+ case MON_DATA_MOVE1:
+ case MON_DATA_MOVE2:
+ case MON_DATA_MOVE3:
+ case MON_DATA_MOVE4:
+ attr -= MON_DATA_MOVE1;
+ ret = blockB->moves[attr];
+ break;
+ case MON_DATA_MOVE1PP:
+ case MON_DATA_MOVE2PP:
+ case MON_DATA_MOVE3PP:
+ case MON_DATA_MOVE4PP:
+ attr -= MON_DATA_MOVE1PP;
+ ret = blockB->movePP[attr];
+ break;
+ case MON_DATA_MOVE1PPUP:
+ case MON_DATA_MOVE2PPUP:
+ case MON_DATA_MOVE3PPUP:
+ case MON_DATA_MOVE4PPUP:
+ attr -= MON_DATA_MOVE1PPUP;
+ ret = blockB->movePpUps[attr];
+ break;
+ case MON_DATA_MOVE1MAXPP:
+ case MON_DATA_MOVE2MAXPP:
+ case MON_DATA_MOVE3MAXPP:
+ case MON_DATA_MOVE4MAXPP:
+ attr -= MON_DATA_MOVE1MAXPP;
+ ret = FUN_0206AB30(blockB->moves[attr], blockB->movePpUps[attr]);
+ break;
+ case MON_DATA_HP_IV:
+ ret = blockB->hpIV;
+ break;
+ case MON_DATA_ATK_IV:
+ ret = blockB->atkIV;
+ break;
+ case MON_DATA_DEF_IV:
+ ret = blockB->defIV;
+ break;
+ case MON_DATA_SPEED_IV:
+ ret = blockB->spdIV;
+ break;
+ case MON_DATA_SPATK_IV:
+ ret = blockB->spatkIV;
+ break;
+ case MON_DATA_SPDEF_IV:
+ ret = blockB->spdefIV;
+ break;
+ case MON_DATA_IS_EGG:
+ ret = boxmon->checksum_fail;
+ if (!ret)
+ ret = blockB->isEgg;
+ break;
+ case MON_DATA_HAS_NICKNAME:
+ ret = blockB->isNicknamed;
+ break;
+ case MON_DATA_COOL_RIBBON:
+ case MON_DATA_HOENN_RIBBON_79:
+ case MON_DATA_HOENN_RIBBON_80:
+ case MON_DATA_HOENN_RIBBON_81:
+ case MON_DATA_HOENN_RIBBON_82:
+ case MON_DATA_HOENN_RIBBON_83:
+ case MON_DATA_HOENN_RIBBON_84:
+ case MON_DATA_HOENN_RIBBON_85:
+ case MON_DATA_HOENN_RIBBON_86:
+ case MON_DATA_HOENN_RIBBON_87:
+ case MON_DATA_HOENN_RIBBON_88:
+ case MON_DATA_HOENN_RIBBON_89:
+ case MON_DATA_HOENN_RIBBON_90:
+ case MON_DATA_HOENN_RIBBON_91:
+ case MON_DATA_HOENN_RIBBON_92:
+ case MON_DATA_HOENN_RIBBON_93:
+ case MON_DATA_HOENN_RIBBON_94:
+ case MON_DATA_HOENN_RIBBON_95:
+ case MON_DATA_HOENN_RIBBON_96:
+ case MON_DATA_HOENN_RIBBON_97:
+ case MON_DATA_HOENN_RIBBON_98:
+ case MON_DATA_HOENN_RIBBON_99:
+ case MON_DATA_HOENN_RIBBON_100:
+ case MON_DATA_HOENN_RIBBON_101:
+ case MON_DATA_HOENN_RIBBON_102:
+ case MON_DATA_HOENN_RIBBON_103:
+ case MON_DATA_HOENN_RIBBON_104:
+ case MON_DATA_HOENN_RIBBON_105:
+ case MON_DATA_HOENN_RIBBON_106:
+ case MON_DATA_HOENN_RIBBON_107:
+ case MON_DATA_HOENN_RIBBON_108:
+ case MON_DATA_HOENN_RIBBON_109:
+ if (blockB->ribbonFlags & (1ll << (attr - MON_DATA_COOL_RIBBON)))
+ ret = TRUE;
+ else
+ ret = FALSE;
+ break;
+ case MON_DATA_FATEFUL_ENCOUNTER:
+ ret = blockB->fatefulEncounter;
+ break;
+ case MON_DATA_GENDER:
+ ret = blockB->gender;
+ break;
+ case MON_DATA_FORME:
+ ret = blockB->alternateForm;
+ break;
+ case MON_DATA_RESERVED_113:
+ ret = blockB->HGSS_shinyLeaves;
+ break;
+ case MON_DATA_RESERVED_114:
+ ret = blockB->Unused;
+ break;
+ case MON_DATA_NICKNAME:
+ if (boxmon->checksum_fail)
+ GetSpeciesName(SPECIES_MANAPHY_EGG, 0, dest);
+ else
+ {
+ u16 * dest16 = (u16 *)dest;
+ for (ret = 0; ret < POKEMON_NAME_LENGTH; ret++)
+ {
+ dest16[ret] = blockC->nickname[ret];
+ }
+ dest16[ret] = EOS;
+ }
+ break;
+ case MON_DATA_NICKNAME_3:
+ ret = blockB->isNicknamed;
+ // fallthrough
+ case MON_DATA_NICKNAME_2:
+ if (boxmon->checksum_fail)
+ {
+ u16 * buffer = FUN_0200AA50(SPECIES_MANAPHY_EGG, 0);
+ FUN_02021A74(dest, buffer);
+ FUN_02021A20(buffer);
+ }
+ else
+ {
+ FUN_02021E28(dest, blockC->nickname);
+ }
+ break;
+ case MON_DATA_UNK_120:
+ ret = blockC->Unused;
+ break;
+ case MON_DATA_GAME_VERSION:
+ ret = blockC->originGame;
+ break;
+ case MON_DATA_SINNOH_RIBBON_122:
+ case MON_DATA_SINNOH_RIBBON_123:
+ case MON_DATA_SINNOH_RIBBON_124:
+ case MON_DATA_SINNOH_RIBBON_125:
+ case MON_DATA_SINNOH_RIBBON_126:
+ case MON_DATA_SINNOH_RIBBON_127:
+ case MON_DATA_SINNOH_RIBBON_128:
+ case MON_DATA_SINNOH_RIBBON_129:
+ case MON_DATA_SINNOH_RIBBON_130:
+ case MON_DATA_SINNOH_RIBBON_131:
+ case MON_DATA_SINNOH_RIBBON_132:
+ case MON_DATA_SINNOH_RIBBON_133:
+ case MON_DATA_SINNOH_RIBBON_134:
+ case MON_DATA_SINNOH_RIBBON_135:
+ case MON_DATA_SINNOH_RIBBON_136:
+ case MON_DATA_SINNOH_RIBBON_137:
+ case MON_DATA_SINNOH_RIBBON_138:
+ case MON_DATA_SINNOH_RIBBON_139:
+ case MON_DATA_SINNOH_RIBBON_140:
+ case MON_DATA_SINNOH_RIBBON_141:
+ case MON_DATA_SINNOH_RIBBON_142:
+ if (blockC->sinnohRibbons2 & (1ll << (attr - MON_DATA_SINNOH_RIBBON_122)))
+ ret = TRUE;
+ else
+ ret = FALSE;
+ break;
+ case MON_DATA_OT_NAME:
+ {
+ u16 * dest16 = (u16 *)dest;
+ for (ret = 0; ret < OT_NAME_LENGTH; ret++)
+ dest16[ret] = blockD->otTrainerName[ret];
+ dest16[ret] = EOS;
+ }
+ break;
+ case MON_DATA_OT_NAME_2:
+ FUN_02021E28(dest, blockD->otTrainerName);
+ break;
+ case MON_DATA_EGG_MET_YEAR:
+ ret = blockD->dateEggReceived[0];
+ break;
+ case MON_DATA_EGG_MET_MONTH:
+ ret = blockD->dateEggReceived[1];
+ break;
+ case MON_DATA_EGG_MET_DAY:
+ ret = blockD->dateEggReceived[2];
+ break;
+ case MON_DATA_MET_YEAR:
+ ret = blockD->dateMet[0];
+ break;
+ case MON_DATA_MET_MONTH:
+ ret = blockD->dateMet[1];
+ break;
+ case MON_DATA_MET_DAY:
+ ret = blockD->dateMet[2];
+ break;
+ case MON_DATA_EGG_MET_LOCATION:
+ ret = blockD->DP_EggLocation;
+ break;
+ case MON_DATA_MET_LOCATION:
+ ret = blockD->DP_MetLocation;
+ break;
+ case MON_DATA_POKERUS:
+ ret = blockD->pokerus;
+ break;
+ case MON_DATA_POKEBALL:
+ ret = blockD->pokeball;
+ break;
+ case MON_DATA_MET_LEVEL:
+ ret = blockD->metLevel;
+ break;
+ case MON_DATA_MET_GENDER:
+ ret = blockD->metGender;
+ break;
+ case MON_DATA_ENCOUNTER_TYPE:
+ ret = blockD->encounterType;
+ break;
+ case MON_DATA_RESERVED_158:
+ ret = blockD->HGSS_Pokeball;
+ break;
+ case MON_DATA_IVS_WORD:
+ ret = (blockB->hpIV) | \
+ (blockB->atkIV << 5) | \
+ (blockB->defIV << 10) | \
+ (blockB->spdIV << 15) | \
+ (blockB->spatkIV << 20) | \
+ (blockB->spdefIV << 25);
+ break;
+ case MON_DATA_UNK_175:
+ if ((blockA->species == SPECIES_NIDORAN_F || blockA->species == SPECIES_NIDORAN_M) && !blockB->isNicknamed)
+ ret = FALSE;
+ else
+ ret = TRUE;
+ break;
+ case MON_DATA_TYPE_1:
+ case MON_DATA_TYPE_2:
+ if (blockA->species == SPECIES_ARCEUS && blockA->ability == ABILITY_MULTITYPE)
+ ret = GetArceusTypeByPlate(FUN_0206E7B8(blockA->heldItem, 1, 0));
+ else
+ {
+ ret = GetMonBaseStat_HandleFormeConversion(blockA->species, blockB->alternateForm, attr - MON_DATA_TYPE_1 + BASE_TYPE1);
+ }
+ break;
+ case MON_DATA_SPECIES_NAME:
+ GetSpeciesName(blockA->species, 0, dest);
+ break;
+ }
+ return ret;
+}
diff --git a/arm9/src/string_util.c b/arm9/src/string_util.c
index e36f1a30..54ad61fc 100644
--- a/arm9/src/string_util.c
+++ b/arm9/src/string_util.c
@@ -1,8 +1,5 @@
#include "string_util.h"
-#define EOS 0xFFFF
-#define NON_DIGIT 0xE2
-
const u16 gDigitTable[] = {
0xA2,
0xA3,