summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pokemon.c440
1 files changed, 434 insertions, 6 deletions
diff --git a/src/pokemon.c b/src/pokemon.c
index 1467d8b6f..66b7824ff 100644
--- a/src/pokemon.c
+++ b/src/pokemon.c
@@ -13,6 +13,7 @@
#include "battle_gfx_sfx_util.h"
#include "battle_controllers.h"
#include "evolution_scene.h"
+#include "battle_message.h"
#include "constants/items.h"
#include "constants/species.h"
#include "constants/pokemon.h"
@@ -36,6 +37,8 @@ struct UnkStruct20244F4
u8 filler1[0xF];
struct SpriteTemplate *unk10;
};
+
+// External symbols
extern struct UnkStruct20244F4 *gUnknown_20244F4;
extern struct SpriteTemplate gUnknown_825DEF0[];
extern struct SpriteTemplate gUnknown_825DF50[];
@@ -43,11 +46,27 @@ 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 gText_EggNickname[];
-extern const u8 gText_BadEgg[];
extern const u8 gUnknown_825DEA1[];
extern const u8 gPPUpWriteMasks[];
+extern u8 *gUnknown_83FD5D0[];
+extern const u8 gUnknown_825DFF0[];
+extern u8 gBattleTextBuff1[];
+extern u8 gBattleTextBuff2[];
+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 sHoldEffectToType[][2];
+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[];
+// External functions
extern u8 sav1_map_get_name(void); // overworld
extern const struct BattleMove gBattleMoves[];
extern u8 sBattler_AI; // battle_ai
@@ -60,10 +79,6 @@ extern void sub_80174B8(u8 battlerId);
union PokemonSubstruct *GetSubstruct(struct BoxPokemon *boxMon, u32 personality, u8 substructType);
s32 GetDeoxysStat(struct Pokemon *mon, s32 statId);
-extern const u8 sHoldEffectToType[][2];
-extern u8 sLearningMoveTableID;
-extern const u8 sSecretBaseFacilityClasses[2][5];
-
// code
void ZeroBoxMonData(struct BoxPokemon *boxMon)
{
@@ -4368,3 +4383,416 @@ _08042BD8:\n\
.syntax divided\n");
}
#endif
+
+bool8 sub_8042BE8(struct Pokemon *mon, u32 unused, u32 healMask, u8 battleId)
+{
+ if((GetMonData(mon, MON_DATA_STATUS, NULL) & healMask) != 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+u8 GetItemEffectParamOffset(u16 itemId, u8 effectByte, u8 effectBit)
+{
+ const u8 *temp;
+ const u8 *itemEffect;
+ u8 offset;
+ int i;
+ u8 j;
+ u8 val;
+
+ offset = 6;
+
+ temp = gItemEffectTable[itemId - 13];
+
+ if (!temp && itemId != ITEM_ENIGMA_BERRY)
+ return 0;
+
+ if (itemId == ITEM_ENIGMA_BERRY)
+ {
+ temp = gEnigmaBerries[gActiveBattler].itemEffect;
+ }
+
+ itemEffect = temp;
+
+ for (i = 0; i < 6; i++)
+ {
+ switch (i)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ if (i == effectByte)
+ return 0;
+ break;
+ case 4:
+ val = itemEffect[4];
+ if (val & 0x20)
+ val &= 0xDF;
+ j = 0;
+ while (val)
+ {
+ if (val & 1)
+ {
+ switch (j)
+ {
+ case 2:
+ if (val & 0x10)
+ val &= 0xEF;
+ case 0:
+ if (i == effectByte && (val & effectBit))
+ return offset;
+ offset++;
+ break;
+ case 1:
+ if (i == effectByte && (val & effectBit))
+ return offset;
+ offset++;
+ break;
+ case 3:
+ if (i == effectByte && (val & effectBit))
+ return offset;
+ offset++;
+ break;
+ case 7:
+ if (i == effectByte)
+ return 0;
+ break;
+ }
+ }
+ j++;
+ val >>= 1;
+ if (i == effectByte)
+ effectBit >>= 1;
+ }
+ break;
+ case 5:
+ val = itemEffect[5];
+ j = 0;
+ while (val)
+ {
+ if (val & 1)
+ {
+ switch (j)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ if (i == effectByte && (val & effectBit))
+ return offset;
+ offset++;
+ break;
+ case 7:
+ if (i == effectByte)
+ return 0;
+ break;
+ }
+ }
+ j++;
+ val >>= 1;
+ if (i == effectByte)
+ effectBit >>= 1;
+ }
+ break;
+ }
+ }
+
+ return offset;
+}
+
+void sub_8042D50(int stat)
+{
+ gBattlerTarget = gBattlerInMenuId;
+ StringCopy(gBattleTextBuff1, gUnknown_83FD5D0[gUnknown_825DFF0[stat]]);
+ StringCopy(gBattleTextBuff2, BattleText_Rose);
+ BattleStringExpandPlaceholdersToDisplayedString(BattleText_UnknownString3);
+}
+
+u8 *sub_8042DA4(u16 itemId)
+{
+ int i;
+ const u8 *itemEffect;
+
+ if (itemId == ITEM_ENIGMA_BERRY)
+ {
+ if (gMain.inBattle)
+ {
+ itemEffect = gEnigmaBerries[gBattlerInMenuId].itemEffect;
+ }
+ else
+ {
+ itemEffect = gSaveBlock1Ptr->enigmaBerry.itemEffect;
+ }
+ }
+ else
+ {
+ itemEffect = gItemEffectTable[itemId - 13];
+ }
+
+ gPotentialItemEffectBattler = gBattlerInMenuId;
+
+ for (i = 0; i < 3; i++)
+ {
+ if (itemEffect[i] & 0xF)
+ sub_8042D50(i * 2);
+ if (itemEffect[i] & 0xF0)
+ {
+ if (i)
+ {
+ sub_8042D50(i * 2 + 1);
+ }
+ else
+ {
+ sBattler_AI = gBattlerInMenuId;
+ BattleStringExpandPlaceholdersToDisplayedString(BattleText_GetPumped);
+ }
+ }
+ }
+
+ if (itemEffect[3] & 0x80)
+ {
+ sBattler_AI = gBattlerInMenuId;
+ BattleStringExpandPlaceholdersToDisplayedString(BattleText_MistShroud);
+ }
+
+ return gDisplayedStringBattle;
+}
+
+u8 GetNature(struct Pokemon *mon)
+{
+ return GetMonData(mon, MON_DATA_PERSONALITY, 0) % 25;
+}
+
+u8 GetNatureFromPersonality(u32 personality)
+{
+ return personality % 25;
+}
+
+extern bool32 sub_806E25C(u16 targetSpecies);
+
+u16 GetEvolutionTargetSpecies(struct Pokemon *mon, u8 type, u16 evolutionItem)
+{
+ int i;
+ u16 targetSpecies = 0;
+ u16 species = GetMonData(mon, MON_DATA_SPECIES, 0);
+ u16 heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
+ u32 personality = GetMonData(mon, MON_DATA_PERSONALITY, 0);
+ u8 level;
+ u16 friendship;
+ u8 beauty = GetMonData(mon, MON_DATA_BEAUTY, 0);
+ u16 upperPersonality = personality >> 16;
+ u8 holdEffect;
+
+ if (heldItem == ITEM_ENIGMA_BERRY)
+ holdEffect = gSaveBlock1Ptr->enigmaBerry.holdEffect;
+ else
+ holdEffect = ItemId_GetHoldEffect(heldItem);
+
+ if (holdEffect == HOLD_EFFECT_PREVENT_EVOLVE && type != 3)
+ return 0;
+
+ switch (type)
+ {
+ case 0:
+ level = GetMonData(mon, MON_DATA_LEVEL, 0);
+ friendship = GetMonData(mon, MON_DATA_FRIENDSHIP, 0);
+
+ for (i = 0; i < 5; i++)
+ {
+ switch (gEvolutionTable[species][i].method)
+ {
+ case EVO_FRIENDSHIP:
+ if (friendship >= 220)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ // FR/LG removed the time of day evolutions due to having no RTC.
+ case EVO_FRIENDSHIP_DAY:
+ /*
+ RtcCalcLocalTime();
+ if (gLocalTime.hours >= 12 && gLocalTime.hours < 24 && friendship >= 220)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ */
+ break;
+ case EVO_FRIENDSHIP_NIGHT:
+ /*
+ RtcCalcLocalTime();
+ if (gLocalTime.hours >= 0 && gLocalTime.hours < 12 && friendship >= 220)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ */
+ break;
+ case EVO_LEVEL:
+ if (gEvolutionTable[species][i].param <= level)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_ATK_GT_DEF:
+ if (gEvolutionTable[species][i].param <= level)
+ if (GetMonData(mon, MON_DATA_ATK, 0) > GetMonData(mon, MON_DATA_DEF, 0))
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_ATK_EQ_DEF:
+ if (gEvolutionTable[species][i].param <= level)
+ if (GetMonData(mon, MON_DATA_ATK, 0) == GetMonData(mon, MON_DATA_DEF, 0))
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_ATK_LT_DEF:
+ if (gEvolutionTable[species][i].param <= level)
+ if (GetMonData(mon, MON_DATA_ATK, 0) < GetMonData(mon, MON_DATA_DEF, 0))
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_SILCOON:
+ if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) <= 4)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_CASCOON:
+ if (gEvolutionTable[species][i].param <= level && (upperPersonality % 10) > 4)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_LEVEL_NINJASK:
+ if (gEvolutionTable[species][i].param <= level)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_BEAUTY:
+ if (gEvolutionTable[species][i].param <= beauty)
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ }
+ }
+ break;
+ case 1:
+ for (i = 0; i < 5; i++)
+ {
+ switch (gEvolutionTable[species][i].method)
+ {
+ case EVO_TRADE:
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ case EVO_TRADE_ITEM:
+ if (gEvolutionTable[species][i].param == heldItem)
+ {
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ if (sub_806E25C(targetSpecies) || targetSpecies <= 151)
+ {
+ heldItem = 0;
+ SetMonData(mon, MON_DATA_HELD_ITEM, &heldItem);
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ }
+ }
+ break;
+ }
+ }
+ break;
+ case 2:
+ case 3:
+ for (i = 0; i < 5; i++)
+ {
+ if (gEvolutionTable[species][i].method == EVO_ITEM
+ && gEvolutionTable[species][i].param == evolutionItem)
+ {
+ targetSpecies = gEvolutionTable[species][i].targetSpecies;
+ break;
+ }
+ }
+ break;
+ }
+
+ return targetSpecies;
+}
+
+// HoennPokedexNumToSpecies, but is it really Hoenn or Kanto its checking
+// TODO: Figure this out
+u16 sub_80431B4(u16 var)
+{
+ u16 species;
+
+ if(!var)
+ return 0;
+
+ species = 0;
+
+ while(species < POKEMON_SLOTS_NUMBER - 1 && gUnknown_8251CB8[species] != var)
+ species++;
+
+ if(species == POKEMON_SLOTS_NUMBER - 1)
+ return 0;
+
+ return species + 1;
+}
+
+u16 NationalPokedexNumToSpecies(u16 nationalNum)
+{
+ u16 species;
+
+ if (!nationalNum)
+ return 0;
+
+ species = 0;
+
+ while (species < POKEMON_SLOTS_NUMBER - 1 && gUnknown_8251FEE[species] != nationalNum)
+ species++;
+
+ if (species == POKEMON_SLOTS_NUMBER - 1)
+ return 0;
+
+ return species + 1;
+}
+
+// NationalToKantoOrder?
+u16 sub_804324C(u16 nationalNum)
+{
+ u16 hoennNum;
+
+ if (!nationalNum)
+ return 0;
+
+ hoennNum = 0;
+
+ while (hoennNum < POKEMON_SLOTS_NUMBER - 1 && gUnknown_8252324[hoennNum] != nationalNum)
+ hoennNum++;
+
+ if (hoennNum == POKEMON_SLOTS_NUMBER - 1)
+ return 0;
+
+ return hoennNum + 1;
+}
+
+u16 SpeciesToNationalPokedexNum(u16 species)
+{
+ if (!species)
+ return 0;
+
+ return gUnknown_8251FEE[species - 1];
+}
+
+// these 2 functions are probably kanto and not hoenn
+// TODO: figure this out
+u16 SpeciesToHoennPokedexNum(u16 species)
+{
+ if (!species)
+ return 0;
+
+ return gUnknown_8251CB8[species - 1];
+}
+
+u16 HoennToNationalOrder(u16 hoennNum)
+{
+ if (!hoennNum)
+ return 0;
+
+ return gUnknown_8252324[hoennNum - 1];
+}
+
+u16 SpeciesToCryId(u16 species)
+{
+ if (species < SPECIES_OLD_UNOWN_B - 1)
+ return species;
+
+ if (species <= SPECIES_OLD_UNOWN_Z - 1)
+ return SPECIES_UNOWN - 1;
+
+ return gUnknown_82539D4[species - ((SPECIES_OLD_UNOWN_Z + 1) - 1)];
+}