summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pokemon_size_record.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/pokemon_size_record.c b/src/pokemon_size_record.c
new file mode 100644
index 000000000..1c54352a8
--- /dev/null
+++ b/src/pokemon_size_record.c
@@ -0,0 +1,196 @@
+#include "gba/gba.h"
+#include "global.h"
+#include "pokemon.h"
+#include "species.h"
+
+extern u16 SpeciesToNationalPokedexNum(u16);
+extern u16 sub_8090D54(u16, u8);
+extern bool8 VarSet(u16, u16);
+extern u16 *GetVarPointer(u16);
+extern u8 FlagSet(u16);
+
+struct UnknownStruct
+{
+ u16 unk0;
+ u8 unk2;
+ u16 unk4;
+};
+
+extern struct UnknownStruct gUnknown_083D180C[];
+extern u8 gOtherText_DecimalPoint[];
+extern u8 gOtherText_Marco[];
+extern u16 gScriptResult;
+extern u8 gSpeciesNames[][11];
+extern u8 gUnknown_083D188E[];
+
+#define VAR_SHROOMISH_SIZE_RECORD 0x4047
+#define VAR_BARBOACH_SIZE_RECORD 0x404F
+#define CM_PER_INCH 2.54
+
+static u32 GetMonSizeHash(struct Pokemon *pkmn)
+{
+ // UB: Too few arguments for function 'GetMonData'
+ 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_SPD_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 < gUnknown_083D180C[i].unk4)
+ return i - 1;
+ }
+ return i;
+}
+
+static u32 GetMonSize(u16 species, u16 b)
+{
+ u64 unk2;
+ u64 unk4;
+ u64 unk0;
+ u32 r7;
+ u32 var;
+ struct UnknownStruct *s;
+
+ r7 = sub_8090D54(SpeciesToNationalPokedexNum(species), 0);
+ var = TranslateBigMonSizeTableIndex(b);
+ unk0 = gUnknown_083D180C[var].unk0;
+ unk2 = gUnknown_083D180C[var].unk2;
+ unk4 = gUnknown_083D180C[var].unk4;
+ unk0 += (b - unk4) / unk2;
+ return r7 * unk0 / 10;
+}
+
+static void FormatMonSizeRecord(u8 *string, u32 size)
+{
+ u8 decimalPoint[2];
+
+ memcpy(decimalPoint, gOtherText_DecimalPoint, 2);
+ //Convert size from centimeters to inches
+ size = (double)(size * 10) / (CM_PER_INCH * 10);
+ string = ConvertIntToDecimalStringN(string, size / 10, 0, 8);
+ string = StringAppend(string, decimalPoint);
+ ConvertIntToDecimalStringN(string, size % 10, 0, 1);
+}
+
+static u8 CompareMonSize(u16 species, u16 *sizeRecord)
+{
+ if(gScriptResult == 0xFF)
+ return 0;
+ else
+ {
+ struct Pokemon *pkmn = &gPlayerParty[gScriptResult];
+
+ // UB: Too few arguments for function 'GetMonData'
+ if(GetMonData(pkmn, MON_DATA_IS_EGG) == TRUE || GetMonData(pkmn, MON_DATA_SPECIES) != species)
+ return 1;
+ else
+ {
+ u32 oldSize;
+ u32 newSize;
+ u16 sizeParams;
+ u16 *ptr = &sizeParams; //Why the pointer?
+
+ *ptr = GetMonSizeHash(pkmn);
+ newSize = GetMonSize(species, sizeParams);
+ oldSize = GetMonSize(species, *sizeRecord);
+ FormatMonSizeRecord(gStringVar2, newSize);
+ 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]);
+ if(*sizeRecord == 0x8100)
+ StringCopy(gStringVar2, gOtherText_Marco);
+ else
+ StringCopy(gStringVar2, gSaveBlock2.playerName);
+}
+
+void InitShroomishSizeRecord(void)
+{
+ VarSet(VAR_SHROOMISH_SIZE_RECORD, 0x8100);
+}
+
+void GetShroomishSizeRecordInfo(void)
+{
+ u16 *sizeRecord = GetVarPointer(VAR_SHROOMISH_SIZE_RECORD);
+
+ GetMonSizeRecordInfo(SPECIES_SHROOMISH, sizeRecord);
+}
+
+void CompareShroomishSize(void)
+{
+ u16 *sizeRecord = GetVarPointer(VAR_SHROOMISH_SIZE_RECORD);
+
+ gScriptResult = CompareMonSize(SPECIES_SHROOMISH, sizeRecord);
+}
+
+void InitBarboachSizeRecord(void)
+{
+ VarSet(VAR_BARBOACH_SIZE_RECORD, 0x8100);
+}
+
+void GetBarboachSizeRecordInfo(void)
+{
+ u16 *sizeRecord = GetVarPointer(VAR_BARBOACH_SIZE_RECORD);
+
+ GetMonSizeRecordInfo(SPECIES_BARBOACH, sizeRecord);
+}
+
+void CompareBarboachSize(void)
+{
+ u16 *sizeRecord = GetVarPointer(VAR_BARBOACH_SIZE_RECORD);
+
+ gScriptResult = CompareMonSize(SPECIES_BARBOACH, sizeRecord);
+}
+
+void GiveGiftRibbonToParty(u8 index, u8 ribbonId)
+{
+ s32 i;
+ u8 arr[7];
+ bool32 gotRibbon = FALSE;
+ u8 data = 1;
+
+ memcpy(arr, gUnknown_083D188E, 7);
+ if(index < 11 && ribbonId < 65)
+ {
+ gSaveBlock1.giftRibbons[index] = ribbonId;
+ for(i = 0; i < 6; i++)
+ {
+ struct Pokemon *pkmn = &gPlayerParty[i];
+
+ if(GetMonData(pkmn, MON_DATA_SPECIES) != 0 && GetMonData(pkmn, MON_DATA_SANITY_BIT3) == 0)
+ {
+ SetMonData(pkmn, arr[index], &data);
+ gotRibbon = TRUE;
+ }
+ }
+ if(gotRibbon)
+ FlagSet(0x83B);
+ }
+}