summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/new_game.c4
-rw-r--r--src/pokemon_size_record.c221
2 files changed, 223 insertions, 2 deletions
diff --git a/src/new_game.c b/src/new_game.c
index 4c1dc2dbf..4b5432a95 100644
--- a/src/new_game.c
+++ b/src/new_game.c
@@ -130,8 +130,8 @@ void NewGameInitData(void)
SetMoney(&gSaveBlock1Ptr->money, 3000);
ResetGameStats();
ClearPlayerLinkBattleRecords();
- sub_80A0904();
- sub_80A0958();
+ InitHeracrossSizeRecord();
+ InitMagikarpSizeRecord();
sub_806E190();
gPlayerPartyCount = 0;
ZeroPlayerPartyMons();
diff --git a/src/pokemon_size_record.c b/src/pokemon_size_record.c
new file mode 100644
index 000000000..c5223c153
--- /dev/null
+++ b/src/pokemon_size_record.c
@@ -0,0 +1,221 @@
+#include "global.h"
+#include "data.h"
+#include "event_data.h"
+#include "pokedex.h"
+#include "pokemon.h"
+#include "pokemon_size_record.h"
+#include "string_util.h"
+#include "text.h"
+#include "constants/species.h"
+
+#define DEFAULT_MAX_SIZE 0 // was 0x8100 in Ruby/Sapphire, 0x8000 in Emerald
+
+struct UnknownStruct
+{
+ u16 unk0;
+ u8 unk2;
+ u16 unk4;
+};
+
+static const struct UnknownStruct sBigMonSizeTable[] =
+{
+ { 290, 1, 0 },
+ { 300, 1, 10 },
+ { 400, 2, 110 },
+ { 500, 4, 310 },
+ { 600, 20, 710 },
+ { 700, 50, 2710 },
+ { 800, 100, 7710 },
+ { 900, 150, 17710 },
+ { 1000, 150, 32710 },
+ { 1100, 100, -17826 },
+ { 1200, 50, -7826 },
+ { 1300, 20, -2826 },
+ { 1400, 5, -826 },
+ { 1500, 2, -326 },
+ { 1600, 1, -126 },
+ { 1700, 1, -26 },
+};
+
+static const u8 sGiftRibbonsMonDataIds[] =
+{
+ MON_DATA_GIFT_RIBBON_1, MON_DATA_GIFT_RIBBON_2, MON_DATA_GIFT_RIBBON_3,
+ MON_DATA_GIFT_RIBBON_4, MON_DATA_GIFT_RIBBON_5, MON_DATA_GIFT_RIBBON_6,
+ MON_DATA_GIFT_RIBBON_7
+};
+
+extern const u8 gText_DecimalPoint[];
+
+#define CM_PER_INCH 2.54
+
+static u32 GetMonSizeHash(struct Pokemon * pkmn)
+{
+ u16 personality = GetMonData(pkmn, MON_DATA_PERSONALITY);
+ u16 hpIV = GetMonData(pkmn, MON_DATA_HP_IV) & 0xF;
+ u16 attackIV = GetMonData(pkmn, MON_DATA_ATK_IV) & 0xF;
+ u16 defenseIV = GetMonData(pkmn, MON_DATA_DEF_IV) & 0xF;
+ u16 speedIV = GetMonData(pkmn, MON_DATA_SPEED_IV) & 0xF;
+ u16 spAtkIV = GetMonData(pkmn, MON_DATA_SPATK_IV) & 0xF;
+ u16 spDefIV = GetMonData(pkmn, MON_DATA_SPDEF_IV) & 0xF;
+ u32 hibyte = ((attackIV ^ defenseIV) * hpIV) ^ (personality & 0xFF);
+ u32 lobyte = ((spAtkIV ^ spDefIV) * speedIV) ^ (personality >> 8);
+
+ return (hibyte << 8) + lobyte;
+}
+
+static u8 TranslateBigMonSizeTableIndex(u16 a)
+{
+ u8 i;
+
+ for (i = 1; i < 15; i++)
+ {
+ if (a < sBigMonSizeTable[i].unk4)
+ return i - 1;
+ }
+ return i;
+}
+
+static u32 GetMonSize(u16 species, u16 b)
+{
+ u64 unk2;
+ u64 unk4;
+ u64 unk0;
+ u32 height;
+ u32 var;
+
+ height = GetPokedexHeightWeight(SpeciesToNationalPokedexNum(species), 0);
+ var = TranslateBigMonSizeTableIndex(b);
+ unk0 = sBigMonSizeTable[var].unk0;
+ unk2 = sBigMonSizeTable[var].unk2;
+ unk4 = sBigMonSizeTable[var].unk4;
+ unk0 += (b - unk4) / unk2;
+ return height * unk0 / 10;
+}
+
+static void FormatMonSizeRecord(u8 *string, u32 size)
+{
+#ifdef UNITS_IMPERIAL
+ //Convert size from centimeters to inches
+ //In the Hoenn games, this conversion was performed using floating point values
+ size = size * 100 / 254;
+#endif
+
+ string = ConvertIntToDecimalStringN(string, size / 10, STR_CONV_MODE_LEFT_ALIGN, 8);
+ string = StringAppend(string, gText_DecimalPoint);
+ ConvertIntToDecimalStringN(string, size % 10, STR_CONV_MODE_LEFT_ALIGN, 1);
+}
+
+static u8 CompareMonSize(u16 species, u16 *sizeRecord)
+{
+ if (gSpecialVar_Result >= PARTY_SIZE)
+ {
+ return 0;
+ }
+ else
+ {
+ struct Pokemon * pkmn = &gPlayerParty[gSpecialVar_Result];
+
+ if (GetMonData(pkmn, MON_DATA_IS_EGG) == TRUE || GetMonData(pkmn, MON_DATA_SPECIES) != species)
+ {
+ return 1;
+ }
+ else
+ {
+ u32 oldSize;
+ u32 newSize;
+ u16 sizeParams;
+
+ *(&sizeParams) = GetMonSizeHash(pkmn);
+ newSize = GetMonSize(species, sizeParams);
+ oldSize = GetMonSize(species, *sizeRecord);
+ FormatMonSizeRecord(gStringVar3, oldSize);
+ FormatMonSizeRecord(gStringVar2, newSize);
+ if (newSize == oldSize)
+ {
+ return 4;
+ }
+ else if (newSize < oldSize)
+ {
+ return 2;
+ }
+ else
+ {
+ *sizeRecord = sizeParams;
+ return 3;
+ }
+ }
+ }
+}
+
+// Stores species name in gStringVar1, trainer's name in gStringVar2, and size in gStringVar3
+static void GetMonSizeRecordInfo(u16 species, u16 *sizeRecord)
+{
+ u32 size = GetMonSize(species, *sizeRecord);
+
+ FormatMonSizeRecord(gStringVar3, size);
+ StringCopy(gStringVar1, gSpeciesNames[species]);
+}
+
+void InitHeracrossSizeRecord(void)
+{
+ VarSet(VAR_HERACROSS_SIZE_RECORD, DEFAULT_MAX_SIZE);
+}
+
+void GetHeracrossSizeRecordInfo(void)
+{
+ u16 *sizeRecord = GetVarPointer(VAR_HERACROSS_SIZE_RECORD);
+
+ GetMonSizeRecordInfo(SPECIES_HERACROSS, sizeRecord);
+}
+
+void CompareHeracrossSize(void)
+{
+ u16 *sizeRecord = GetVarPointer(VAR_HERACROSS_SIZE_RECORD);
+
+ gSpecialVar_Result = CompareMonSize(SPECIES_HERACROSS, sizeRecord);
+}
+
+void InitMagikarpSizeRecord(void)
+{
+ VarSet(VAR_MAGIKARP_SIZE_RECORD, DEFAULT_MAX_SIZE);
+}
+
+void GetMagikarpSizeRecordInfo(void)
+{
+ u16 *sizeRecord = GetVarPointer(VAR_MAGIKARP_SIZE_RECORD);
+
+ GetMonSizeRecordInfo(SPECIES_MAGIKARP, sizeRecord);
+}
+
+void CompareMagikarpSize(void)
+{
+ u16 *sizeRecord = GetVarPointer(VAR_MAGIKARP_SIZE_RECORD);
+
+ gSpecialVar_Result = CompareMonSize(SPECIES_MAGIKARP, sizeRecord);
+}
+
+void GiveGiftRibbonToParty(u8 index, u8 ribbonId)
+{
+ s32 i;
+ bool32 gotRibbon = FALSE;
+ u8 data = 1;
+ u8 array[8];
+ memcpy(array, sGiftRibbonsMonDataIds, sizeof(sGiftRibbonsMonDataIds));
+
+ if (index < 11 && ribbonId < 65)
+ {
+ gSaveBlock1Ptr->giftRibbons[index] = ribbonId;
+ for (i = 0; i < PARTY_SIZE; i++)
+ {
+ struct Pokemon * mon = &gPlayerParty[i];
+
+ if (GetMonData(mon, MON_DATA_SPECIES) != 0 && GetMonData(mon, MON_DATA_SANITY_IS_EGG) == 0)
+ {
+ SetMonData(mon, array[index], &data);
+ gotRibbon = TRUE;
+ }
+ }
+ if (gotRibbon)
+ FlagSet(FLAG_SYS_RIBBON_GET);
+ }
+}