diff --git a/asm/macros/scrcmd.inc b/asm/macros/scrcmd.inc
index 0183499bb1..2f58d6b0e3 100644
--- a/asm/macros/scrcmd.inc
+++ b/asm/macros/scrcmd.inc
@@ -2493,29 +2493,29 @@
.short \species
.endm
- .macro ScrCmd_1C1 arg0, arg1
+ .macro CalcSizeContestResult destVar, partySlot
.short 449
- .short \arg0
- .short \arg1
+ .short \destVar
+ .short \partySlot
.endm
- .macro ScrCmd_1C2 arg0
+ .macro UpdateSizeContestRecord partySlot
.short 450
- .short \arg0
+ .short \partySlot
.endm
- .macro ScrCmd_1C3 arg0, arg1, arg2
+ .macro BufferPartyPokemonSize intPartIdx, fracPartIdx, partySlot
.short 451
- .short \arg0
- .short \arg1
- .short \arg2
+ .short \intPartIdx
+ .short \fracPartIdx
+ .short \partySlot
.endm
- .macro ScrCmd_1C4 arg0, arg1, arg2
+ .macro BufferSizeContestRecord intPartIdx, fracPartIdx, species
.short 452
- .short \arg0
- .short \arg1
- .short \arg2
+ .short \intPartIdx
+ .short \fracPartIdx
+ .short \species
.endm
.macro InitSizeContestRecord
diff --git a/generated/meson.build b/generated/meson.build
index 530c882f90..6e610d16a6 100644
--- a/generated/meson.build
+++ b/generated/meson.build
@@ -85,6 +85,7 @@ metang_generators = {
'sdat': { 'type': 'enum', 'tag': 'SDATID' },
'signpost_commands': { 'type': 'enum', 'tag': 'SignpostCommand' },
'signpost_types': { 'type': 'enum', 'tag': 'SignpostType' },
+ 'size_contest_results': { 'type': 'enum', 'tag': 'SizeContestResult' },
'shadow_sizes': { 'type': 'enum', 'tag': 'ShadowSize' },
'species': { 'type': 'enum', 'tag': 'Species' },
'species_data_params': { 'type': 'enum', 'tag': 'SpeciesDataParam' },
diff --git a/generated/size_contest_results.txt b/generated/size_contest_results.txt
new file mode 100644
index 0000000000..05a8d47388
--- /dev/null
+++ b/generated/size_contest_results.txt
@@ -0,0 +1,3 @@
+SIZE_CONTEST_SMALLER
+SIZE_CONTEST_SAME_SIZE
+SIZE_CONTEST_LARGER
diff --git a/include/overlay005/ov5_021EE7D4.h b/include/overlay005/ov5_021EE7D4.h
deleted file mode 100644
index d76c8cc2e1..0000000000
--- a/include/overlay005/ov5_021EE7D4.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef POKEPLATINUM_OV5_021EE7D4_H
-#define POKEPLATINUM_OV5_021EE7D4_H
-
-#include "field/field_system_decl.h"
-
-u8 ov5_021EE920(FieldSystem *fieldSystem, u16 param1);
-void ov5_021EE9BC(FieldSystem *fieldSystem, u16 param1);
-void ov5_021EEA54(FieldSystem *fieldSystem, u8 param1, u8 param2, u16 param3);
-void ov5_021EEA84(FieldSystem *fieldSystem, u8 param1, u8 param2, u16 param3);
-
-#endif // POKEPLATINUM_OV5_021EE7D4_H
diff --git a/include/overlay005/size_contest.h b/include/overlay005/size_contest.h
new file mode 100644
index 0000000000..6422426c76
--- /dev/null
+++ b/include/overlay005/size_contest.h
@@ -0,0 +1,11 @@
+#ifndef POKEPLATINUM_OV5_SIZE_CONTEST_H
+#define POKEPLATINUM_OV5_SIZE_CONTEST_H
+
+#include "field/field_system_decl.h"
+
+u8 SizeContest_CalcResultForPartyMon(FieldSystem *fieldSystem, u16 partySlot);
+void SizeContest_UpdateRecordFromPartyMon(FieldSystem *fieldSystem, u16 partySlot);
+void SizeContest_SetRecordSizeStrParams(FieldSystem *fieldSystem, u8 intPartIdx, u8 fracPartIdx, u16 species);
+void SizeContest_SetPartyMonSizeStrParams(FieldSystem *fieldSystem, u8 intPartIdx, u8 fracPartIdx, u16 partySlot);
+
+#endif // POKEPLATINUM_OV5_SIZE_CONTEST_H
diff --git a/platinum.us/main.lsf b/platinum.us/main.lsf
index 871d98033b..9a8a497391 100644
--- a/platinum.us/main.lsf
+++ b/platinum.us/main.lsf
@@ -505,7 +505,7 @@ Overlay overlay5
Object main.nef.p/src_overlay005_ov5_021ECC20.c.o
Object main.nef.p/src_overlay005_ov5_021ECE40.c.o
Object main.nef.p/src_overlay005_ov5_021EE75C.c.o
- Object main.nef.p/src_overlay005_ov5_021EE7D4.c.o
+ Object main.nef.p/src_overlay005_size_contest.c.o
Object main.nef.p/src_overlay005_loaded_map_buffers.c.o
Object main.nef.p/src_overlay005_bdhc.c.o
Object main.nef.p/src_overlay005_dynamic_terrain_height.c.o
diff --git a/res/field/scripts/scripts_route_222_east_house.s b/res/field/scripts/scripts_route_222_east_house.s
index 82576bc420..da209c298f 100644
--- a/res/field/scripts/scripts_route_222_east_house.s
+++ b/res/field/scripts/scripts_route_222_east_house.s
@@ -1,23 +1,24 @@
#include "macros/scrcmd.inc"
#include "res/text/bank/route_222_east_house.h"
+#include "generated/size_contest_results.h"
.data
- ScriptEntry _000A
- ScriptEntry _0010
+ ScriptEntry Route222EastHouse_OnLoad
+ ScriptEntry Route222EastHouse_Fisherman
ScriptEntryEnd
-_000A:
+Route222EastHouse_OnLoad:
SetFlag FLAG_UNK_0x09F0
End
-_0010:
+Route222EastHouse_Fisherman:
PlayFanfare SEQ_SE_CONFIRM
LockAll
FacePlayer
CheckPartyHasSpecies VAR_RESULT, SPECIES_REMORAID
- GoToIfEq VAR_RESULT, 0, _00CF
- Message 1
+ GoToIfEq VAR_RESULT, 0, Route222EastHouse_NoRemoraid
+ Message Route222EastHouse_Text_DreamtLargeRemoraidWasNoDream
CloseMessage
FadeScreen 6, 1, 0, 0
WaitFadeScreen
@@ -26,65 +27,65 @@ _0010:
ReturnToField
FadeScreen 6, 1, 1, 0
WaitFadeScreen
- GoToIfEq VAR_0x8002, 0xFF, _011E
+ GoToIfEq VAR_0x8002, 0xFF, Route222EastHouse_ShowNoPokemon
GetPartyMonSpecies VAR_0x8002, VAR_0x8001
- GoToIfNe VAR_0x8001, 223, _0108
- ScrCmd_1C1 VAR_RESULT, VAR_0x8002
- GoToIfEq VAR_RESULT, 0, _00ED
- GoToIfEq VAR_RESULT, 1, _00DA
- ScrCmd_1C3 0, 1, VAR_0x8002
- Message 2
+ GoToIfNe VAR_0x8001, SPECIES_REMORAID, Route222EastHouse_ShowedOtherSpecies
+ CalcSizeContestResult VAR_RESULT, VAR_0x8002
+ GoToIfEq VAR_RESULT, SIZE_CONTEST_SMALLER, Route222EastHouse_SmallerThanRecord
+ GoToIfEq VAR_RESULT, SIZE_CONTEST_SAME_SIZE, Route222EastHouse_TiedRecord
+ BufferPartyPokemonSize 0, 1, VAR_0x8002
+ Message Route222EastHouse_Text_BetterThanInMyDream
SetVar VAR_0x8004, ITEM_NET_BALL
SetVar VAR_0x8005, 1
- GoToIfCannotFitItem VAR_0x8004, VAR_0x8005, VAR_RESULT, _0113
+ GoToIfCannotFitItem VAR_0x8004, VAR_0x8005, VAR_RESULT, Route222EastHouse_BagFull
CallCommonScript 0x7FC
- ScrCmd_1C2 VAR_0x8002
- Message 3
+ UpdateSizeContestRecord VAR_0x8002
+ Message Route222EastHouse_Text_WillDreamOfBiggerRemoraid
WaitABXPadPress
CloseMessage
ReleaseAll
End
-_00CF:
- Message 0
+Route222EastHouse_NoRemoraid:
+ Message Route222EastHouse_Text_DreamtLargeRemoraid
WaitABXPadPress
CloseMessage
ReleaseAll
End
-_00DA:
- ScrCmd_1C4 0, 1, 223
- Message 4
+Route222EastHouse_TiedRecord:
+ BufferSizeContestRecord 0, 1, SPECIES_REMORAID
+ Message Route222EastHouse_Text_RememberThisSize
WaitABXPadPress
CloseMessage
ReleaseAll
End
-_00ED:
- ScrCmd_1C3 0, 1, VAR_0x8002
- ScrCmd_1C4 2, 3, 223
- Message 5
+Route222EastHouse_SmallerThanRecord:
+ BufferPartyPokemonSize 0, 1, VAR_0x8002
+ BufferSizeContestRecord 2, 3, SPECIES_REMORAID
+ Message Route222EastHouse_Text_KnowAGenius
WaitABXPadPress
CloseMessage
ReleaseAll
End
-_0108:
- Message 6
+Route222EastHouse_ShowedOtherSpecies:
+ Message Route222EastHouse_Text_DidYouListen
WaitABXPadPress
CloseMessage
ReleaseAll
End
-_0113:
- Message 7
+Route222EastHouse_BagFull:
+ Message Route222EastHouse_Text_BagJammedFull
WaitABXPadPress
CloseMessage
ReleaseAll
End
-_011E:
- Message 8
+Route222EastHouse_ShowNoPokemon:
+ Message Route222EastHouse_Text_DenyMeasureRemoraid
WaitABXPadPress
CloseMessage
ReleaseAll
diff --git a/res/text/route_222_east_house.gmm b/res/text/route_222_east_house.gmm
index 8babad058f..9d8709f7de 100644
--- a/res/text/route_222_east_house.gmm
+++ b/res/text/route_222_east_house.gmm
@@ -1,39 +1,39 @@
-
+
used
I had a dream!\nIt was a wonderful dream!\rI dreamt that a Trainer would bring\nme a giant REMORAID!
-
+
used
I had a dream!\nIt was a wonderful dream!\rI dreamt that a Trainer would bring\nme a giant REMORAID!\rOh, my gosh!\nThat dream was no dream!\rH-how big of a REMORAID did you\nbring me?!\r
-
+
used
{STRVAR_1 52, 0, 0}.{STRVAR_1 50, 1, 0} inches...\nThis REMORAID is {STRVAR_1 52, 0, 0}.{STRVAR_1 50, 1, 0} inches...\r...I think you did better than in\nmy dream!\rI’d like you to have this.\r
-
+
used
Thank you!\nI really enjoyed this.\rI think I’ll dream of an even bigger\nREMORAID tonight.
-
+
used
{STRVAR_1 52, 0, 0}.{STRVAR_1 50, 1, 0} inches...\nAm I experiencing deja vu?\fI distinctly remember this size...
-
+
used
This REMORAID was {STRVAR_1 52, 0, 0}.{STRVAR_1 50, 1, 0} inches.\rI know a genius who brought me\na REMORAID that was {STRVAR_1 52, 2, 0}.{STRVAR_1 50, 3, 0} inches...
-
+
used
Wha...\nWhat do you think you’re showing me?\rDid you even listen to what I had\nto say?
-
+
used
Your Bag’s jammed full...\nI can’t give you this...
-
+
used
Oh, what? Why would you deny me\nthe chance to measure your REMORAID?
diff --git a/src/meson.build b/src/meson.build
index 4419177408..c733907f93 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -398,7 +398,7 @@ pokeplatinum_c = files(
'overlay005/ov5_021ECC20.c',
'overlay005/ov5_021ECE40.c',
'overlay005/ov5_021EE75C.c',
- 'overlay005/ov5_021EE7D4.c',
+ 'overlay005/size_contest.c',
'overlay005/loaded_map_buffers.c',
'overlay005/bdhc.c',
'overlay005/dynamic_terrain_height.c',
diff --git a/src/overlay005/ov5_021EE7D4.c b/src/overlay005/ov5_021EE7D4.c
deleted file mode 100644
index cd65dcdc06..0000000000
--- a/src/overlay005/ov5_021EE7D4.c
+++ /dev/null
@@ -1,178 +0,0 @@
-#include "overlay005/ov5_021EE7D4.h"
-
-#include
-#include
-
-#include "struct_decls/struct_02098700_decl.h"
-
-#include "field/field_system.h"
-
-#include "party.h"
-#include "pokedex_heightweight.h"
-#include "pokemon.h"
-#include "script_manager.h"
-#include "string_template.h"
-#include "system_vars.h"
-#include "unk_0206CCB0.h"
-#include "vars_flags.h"
-
-typedef struct {
- u16 unk_00;
- u16 unk_02;
- u16 unk_04;
- u16 unk_06;
-} UnkStruct_ov5_021FF508;
-
-static const UnkStruct_ov5_021FF508 Unk_ov5_021FF508[] = {
- { 0x122, 0x1, 0x0, 0x0 },
- { 0x12C, 0x1, 0xA, 0x0 },
- { 0x190, 0x2, 0x6E, 0x0 },
- { 0x1F4, 0x4, 0x136, 0x0 },
- { 0x258, 0x14, 0x2C6, 0x0 },
- { 0x2BC, 0x32, 0xA96, 0x0 },
- { 0x320, 0x64, 0x1E1E, 0x0 },
- { 0x384, 0x96, 0x452E, 0x0 },
- { 0x3E8, 0x96, 0x7FC6, 0x0 },
- { 0x44C, 0x64, 0xBA5E, 0x0 },
- { 0x4B0, 0x32, 0xE16E, 0x0 },
- { 0x514, 0x14, 0xF4F6, 0x0 },
- { 0x578, 0x5, 0xFCC6, 0x0 },
- { 0x5DC, 0x2, 0xFEBA, 0x0 },
- { 0x640, 0x1, 0xFF82, 0x0 },
- { 0x6A4, 0x1, 0xFFE6, 0x0 }
-};
-
-static int ov5_021EE7D4(Pokemon *param0)
-{
- u16 v0;
- u16 v1, v2, v3;
- u16 v4, v5, v6;
- u16 v7, v8;
-
- v0 = Pokemon_GetValue(param0, MON_DATA_PERSONALITY, NULL) & 0xffff;
- v1 = Pokemon_GetValue(param0, MON_DATA_HP_IV, NULL) & 0xf;
- v2 = Pokemon_GetValue(param0, MON_DATA_ATK_IV, NULL) & 0xf;
- v3 = Pokemon_GetValue(param0, MON_DATA_DEF_IV, NULL) & 0xf;
- v4 = Pokemon_GetValue(param0, MON_DATA_SPEED_IV, NULL) & 0xf;
- v5 = Pokemon_GetValue(param0, MON_DATA_SPATK_IV, NULL) & 0xf;
- v6 = Pokemon_GetValue(param0, MON_DATA_SPDEF_IV, NULL) & 0xf;
- v7 = ((v2 ^ v3) * v1) ^ (v0 & 0xff);
- v8 = ((v5 ^ v6) * v4) ^ (v0 >> 8);
-
- return v7 * 256 + v8;
-}
-
-static u8 ov5_021EE880(u16 param0)
-{
- u8 v0;
-
- for (v0 = 1; v0 < NELEMS(Unk_ov5_021FF508) - 1; v0++) {
- if (param0 < Unk_ov5_021FF508[v0].unk_04) {
- return v0 - 1;
- }
- }
-
- return v0;
-}
-
-static u32 ov5_021EE8A8(u16 param0, u16 param1)
-{
- u64 v0, v1, v2;
- u32 v3;
- u64 v4;
- u8 v5;
- HeightWeightData *v6 = Pokedex_HeightWeightData(HEAP_ID_FIELD);
- Pokedex_HeightWeightData_Load(v6, 0, HEAP_ID_FIELD);
-
- v3 = Pokedex_HeightWeightData_Height((const HeightWeightData *)v6, param0);
- Pokedex_HeightWeightData_Release(v6);
- Pokedex_HeightWeightData_Free(v6);
-
- v5 = ov5_021EE880(param1);
- v0 = Unk_ov5_021FF508[v5].unk_00;
- v1 = Unk_ov5_021FF508[v5].unk_02;
- v2 = Unk_ov5_021FF508[v5].unk_04;
- v4 = v0 + (param1 - v2) / v1;
-
- return v3 * v4 / 10;
-}
-
-u8 ov5_021EE920(FieldSystem *fieldSystem, u16 param1)
-{
- Pokemon *v0;
- vu16 v1, v2;
- u16 v3;
- u32 v4;
- u32 v5;
-
- v0 = Party_GetPokemonBySlotIndex(SaveData_GetParty(fieldSystem->saveData), param1);
- v3 = Pokemon_GetValue(v0, MON_DATA_SPECIES, NULL);
- v1 = ov5_021EE7D4(v0);
- v4 = ov5_021EE8A8(v3, v1);
- v2 = SystemVars_GetSizeContestRecord(SaveData_GetVarsFlags(fieldSystem->saveData));
- v5 = ov5_021EE8A8(v3, v2);
-
- {
- u32 v6 = (((v4 * 1000) / 254 + 5) / 10);
- u32 v7 = (((v5 * 1000) / 254 + 5) / 10);
-
- if (v6 == v7) {
- return 1;
- } else {
- if (v6 > v7) {
- sub_0206DC6C(fieldSystem, v4, v0);
- return 2;
- } else {
- return 0;
- }
- }
- }
-}
-
-void ov5_021EE9BC(FieldSystem *fieldSystem, u16 param1)
-{
- Pokemon *v0;
- vu16 v1;
-
- v0 = Party_GetPokemonBySlotIndex(SaveData_GetParty(fieldSystem->saveData), param1);
- v1 = ov5_021EE7D4(v0);
-
- SystemVars_SetSizeContestRecord(SaveData_GetVarsFlags(fieldSystem->saveData), v1);
-}
-
-static void ov5_021EE9E8(FieldSystem *fieldSystem, u8 param1, u8 param2, u16 param3, vu16 param4)
-{
- u32 v0;
- StringTemplate **v1 = FieldSystem_GetScriptMemberPtr(fieldSystem, SCRIPT_MANAGER_STR_TEMPLATE);
-
- v0 = ov5_021EE8A8(param3, param4);
-
- {
- u32 v2 = v0;
- v0 = (((v0 * 1000) / 254 + 5) / 10);
- }
-
- StringTemplate_SetNumber(*v1, param1, v0 / 10, 3, 0, 1);
- StringTemplate_SetNumber(*v1, param2, v0 % 10, 1, 0, 1);
-}
-
-void ov5_021EEA54(FieldSystem *fieldSystem, u8 param1, u8 param2, u16 param3)
-{
- vu16 v0;
-
- v0 = SystemVars_GetSizeContestRecord(SaveData_GetVarsFlags(fieldSystem->saveData));
- ov5_021EE9E8(fieldSystem, param1, param2, param3, v0);
-}
-
-void ov5_021EEA84(FieldSystem *fieldSystem, u8 param1, u8 param2, u16 param3)
-{
- Pokemon *v0;
- u16 v1;
- vu16 v2;
-
- v0 = Party_GetPokemonBySlotIndex(SaveData_GetParty(fieldSystem->saveData), param3);
- v1 = Pokemon_GetValue(v0, MON_DATA_SPECIES, NULL);
- v2 = ov5_021EE7D4(v0);
-
- ov5_021EE9E8(fieldSystem, param1, param2, v1, v2);
-}
diff --git a/src/overlay005/size_contest.c b/src/overlay005/size_contest.c
new file mode 100644
index 0000000000..460c1aa612
--- /dev/null
+++ b/src/overlay005/size_contest.c
@@ -0,0 +1,169 @@
+#include "overlay005/size_contest.h"
+
+#include
+#include
+
+#include "generated/size_contest_results.h"
+#include "generated/string_padding_mode.h"
+
+#include "struct_decls/struct_02098700_decl.h"
+
+#include "field/field_system.h"
+
+#include "party.h"
+#include "pokedex_heightweight.h"
+#include "pokemon.h"
+#include "script_manager.h"
+#include "strbuf.h"
+#include "string_template.h"
+#include "system_vars.h"
+#include "unk_0206CCB0.h"
+#include "vars_flags.h"
+
+#define MM_TO_TENTH_OF_INCH(length) (((length * 1000) / 254 + 5) / 10)
+
+static u8 GetApproxIntervalIdx(u16 sizeFactor);
+
+/*
+ * Used to approximate a normal distribution from an uniformly distributed u16
+ * variable through a piecewise approximation of the inverse error function (erf^-1)
+ * from 0..65535 into 290...1725
+ */
+typedef struct NormalApproxIntervalParams {
+ u16 base;
+ u16 divisor;
+ u16 intervalStart;
+ u16 unused_06;
+} NormalApproxIntervalParams;
+
+// clang-format off
+static const NormalApproxIntervalParams sUniformToNormalIntervals[] = {
+ { .base = 290, .divisor = 1, .intervalStart = 0, .unused_06 = 0x0 },
+ { .base = 300, .divisor = 1, .intervalStart = 10, .unused_06 = 0x0 },
+ { .base = 400, .divisor = 2, .intervalStart = 110, .unused_06 = 0x0 },
+ { .base = 500, .divisor = 4, .intervalStart = 310, .unused_06 = 0x0 },
+ { .base = 600, .divisor = 20, .intervalStart = 710, .unused_06 = 0x0 },
+ { .base = 700, .divisor = 50, .intervalStart = 2710, .unused_06 = 0x0 },
+ { .base = 800, .divisor = 100, .intervalStart = 7710, .unused_06 = 0x0 },
+ { .base = 900, .divisor = 150, .intervalStart = 17710, .unused_06 = 0x0 },
+ { .base = 1000, .divisor = 150, .intervalStart = 32710, .unused_06 = 0x0 },
+ { .base = 1100, .divisor = 100, .intervalStart = 47710, .unused_06 = 0x0 },
+ { .base = 1200, .divisor = 50, .intervalStart = 57710, .unused_06 = 0x0 },
+ { .base = 1300, .divisor = 20, .intervalStart = 62710, .unused_06 = 0x0 },
+ { .base = 1400, .divisor = 5, .intervalStart = 64710, .unused_06 = 0x0 },
+ { .base = 1500, .divisor = 2, .intervalStart = 65210, .unused_06 = 0x0 },
+ { .base = 1600, .divisor = 1, .intervalStart = 65410, .unused_06 = 0x0 },
+ { .base = 1700, .divisor = 1, .intervalStart = 65510, .unused_06 = 0x0 },
+};
+// clang-format on
+
+// Calculates the erf^-1 approximation.
+// Using u64 is required for matching.
+static inline u64 CalcMultFromSizeFactor(u16 sizeFactor)
+{
+ u8 approxPieceIdx = GetApproxIntervalIdx(sizeFactor);
+ u64 base = sUniformToNormalIntervals[approxPieceIdx].base;
+ u64 div = sUniformToNormalIntervals[approxPieceIdx].divisor;
+ u64 start = sUniformToNormalIntervals[approxPieceIdx].intervalStart;
+ return base + (sizeFactor - start) / div;
+}
+
+static int CalcSizeFactor(Pokemon *mon)
+{
+ u16 personnalityLow = Pokemon_GetValue(mon, MON_DATA_PERSONALITY, NULL) & 0xffff;
+ u16 hpIV = Pokemon_GetValue(mon, MON_DATA_HP_IV, NULL) & 0xf;
+ u16 atkIV = Pokemon_GetValue(mon, MON_DATA_ATK_IV, NULL) & 0xf;
+ u16 defIV = Pokemon_GetValue(mon, MON_DATA_DEF_IV, NULL) & 0xf;
+ u16 speedIV = Pokemon_GetValue(mon, MON_DATA_SPEED_IV, NULL) & 0xf;
+ u16 spAtkIV = Pokemon_GetValue(mon, MON_DATA_SPATK_IV, NULL) & 0xf;
+ u16 spDefIV = Pokemon_GetValue(mon, MON_DATA_SPDEF_IV, NULL) & 0xf;
+ u16 high = ((atkIV ^ defIV) * hpIV) ^ (personnalityLow & 0xff);
+ u16 low = ((spAtkIV ^ spDefIV) * speedIV) ^ (personnalityLow >> 8);
+
+ return high * 256 + low;
+}
+
+static u8 GetApproxIntervalIdx(u16 sizeFactor)
+{
+ u8 i;
+
+ for (i = 1; i < NELEMS(sUniformToNormalIntervals) - 1; i++) {
+ if (sizeFactor < sUniformToNormalIntervals[i].intervalStart) {
+ return i - 1;
+ }
+ }
+
+ return i;
+}
+
+static u32 CalcMillimeterSize(u16 species, u16 sizeFactor)
+{
+ HeightWeightData *heightWeightData = Pokedex_HeightWeightData(HEAP_ID_FIELD);
+ Pokedex_HeightWeightData_Load(heightWeightData, FALSE, HEAP_ID_FIELD);
+
+ u32 height = Pokedex_HeightWeightData_Height(heightWeightData, species);
+ Pokedex_HeightWeightData_Release(heightWeightData);
+ Pokedex_HeightWeightData_Free(heightWeightData);
+
+ u64 sizeMult = CalcMultFromSizeFactor(sizeFactor);
+
+ return height * sizeMult / 10;
+}
+
+u8 SizeContest_CalcResultForPartyMon(FieldSystem *fieldSystem, u16 partySlot)
+{
+ Pokemon *mon = Party_GetPokemonBySlotIndex(SaveData_GetParty(fieldSystem->saveData), partySlot);
+ u16 species = Pokemon_GetValue(mon, MON_DATA_SPECIES, NULL);
+ vu16 sizeFactor = CalcSizeFactor(mon);
+ u32 newSize = CalcMillimeterSize(species, sizeFactor);
+ vu16 recordSizeFactor = SystemVars_GetSizeContestRecord(SaveData_GetVarsFlags(fieldSystem->saveData));
+ u32 recordSize = CalcMillimeterSize(species, recordSizeFactor);
+
+ u32 newSizeInches = MM_TO_TENTH_OF_INCH(newSize);
+ u32 recordSizeInches = MM_TO_TENTH_OF_INCH(recordSize);
+
+ if (newSizeInches == recordSizeInches) {
+ return SIZE_CONTEST_SAME_SIZE;
+ } else {
+ if (newSizeInches > recordSizeInches) {
+ sub_0206DC6C(fieldSystem, newSize, mon);
+ return SIZE_CONTEST_LARGER;
+ } else {
+ return SIZE_CONTEST_SMALLER;
+ }
+ }
+}
+
+void SizeContest_UpdateRecordFromPartyMon(FieldSystem *fieldSystem, u16 partySlot)
+{
+ Pokemon *mon = Party_GetPokemonBySlotIndex(SaveData_GetParty(fieldSystem->saveData), partySlot);
+ vu16 sizeFactor = CalcSizeFactor(mon);
+
+ SystemVars_SetSizeContestRecord(SaveData_GetVarsFlags(fieldSystem->saveData), sizeFactor);
+}
+
+static void SetStrTemplateMonSizeParams(FieldSystem *fieldSystem, u8 intPartIdx, u8 fracPartIdx, u16 species, vu16 sizeFactor)
+{
+ StringTemplate **strTemplate = FieldSystem_GetScriptMemberPtr(fieldSystem, SCRIPT_MANAGER_STR_TEMPLATE);
+
+ u32 size = CalcMillimeterSize(species, sizeFactor);
+ size = MM_TO_TENTH_OF_INCH(size);
+
+ StringTemplate_SetNumber(*strTemplate, intPartIdx, size / 10, 3, PADDING_MODE_NONE, CHARSET_MODE_EN);
+ StringTemplate_SetNumber(*strTemplate, fracPartIdx, size % 10, 1, PADDING_MODE_NONE, CHARSET_MODE_EN);
+}
+
+void SizeContest_SetRecordSizeStrParams(FieldSystem *fieldSystem, u8 intPartIdx, u8 fracPartIdx, u16 species)
+{
+ vu16 recordSizeFactor = SystemVars_GetSizeContestRecord(SaveData_GetVarsFlags(fieldSystem->saveData));
+ SetStrTemplateMonSizeParams(fieldSystem, intPartIdx, fracPartIdx, species, recordSizeFactor);
+}
+
+void SizeContest_SetPartyMonSizeStrParams(FieldSystem *fieldSystem, u8 intPartIdx, u8 fracPartIdx, u16 partySlot)
+{
+ Pokemon *mon = Party_GetPokemonBySlotIndex(SaveData_GetParty(fieldSystem->saveData), partySlot);
+ u16 species = Pokemon_GetValue(mon, MON_DATA_SPECIES, NULL);
+ vu16 sizeFactor = CalcSizeFactor(mon);
+
+ SetStrTemplateMonSizeParams(fieldSystem, intPartIdx, fracPartIdx, species, sizeFactor);
+}
diff --git a/src/scrcmd.c b/src/scrcmd.c
index 33ed095f5f..1434db4457 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -63,11 +63,11 @@
#include "overlay005/ov5_021DFB54.h"
#include "overlay005/ov5_021EA874.h"
#include "overlay005/ov5_021ECC20.h"
-#include "overlay005/ov5_021EE7D4.h"
#include "overlay005/ov5_021F6454.h"
#include "overlay005/save_info_window.h"
#include "overlay005/scrcmd_move_tutor.h"
#include "overlay005/signpost.h"
+#include "overlay005/size_contest.h"
#include "overlay005/struct_ov5_021DD42C.h"
#include "overlay005/vs_seeker.h"
#include "overlay006/npc_trade.h"
@@ -557,10 +557,10 @@ static BOOL ScrCmd_1B5(ScriptContext *ctx);
static BOOL ScrCmd_GetTimeOfDay(ScriptContext *ctx);
static BOOL ScrCmd_GetRandom(ScriptContext *ctx);
static BOOL ScrCmd_GetRandom2(ScriptContext *ctx);
-static BOOL ScrCmd_1C1(ScriptContext *ctx);
-static BOOL ScrCmd_1C2(ScriptContext *ctx);
-static BOOL ScrCmd_1C3(ScriptContext *ctx);
-static BOOL ScrCmd_1C4(ScriptContext *ctx);
+static BOOL ScrCmd_CalcSizeContestResult(ScriptContext *ctx);
+static BOOL ScrCmd_UpdateSizeContestRecord(ScriptContext *ctx);
+static BOOL ScrCmd_BufferPartyPokemonSize(ScriptContext *ctx);
+static BOOL ScrCmd_BufferSizeContestRecord(ScriptContext *ctx);
static BOOL ScrCmd_InitSizeContestRecord(ScriptContext *ctx);
static BOOL ScrCmd_GiveJournal(ScriptContext *ctx);
static BOOL ScrCmd_CreateJournalEvent(ScriptContext *ctx);
@@ -1218,10 +1218,10 @@ const ScrCmdFunc Unk_020EAC58[] = {
ScrCmd_GetDaycareCompatibilityLevel,
ScrCmd_CheckDaycareHasEgg,
ScrCmd_CheckPartyHasSpecies,
- ScrCmd_1C1,
- ScrCmd_1C2,
- ScrCmd_1C3,
- ScrCmd_1C4,
+ ScrCmd_CalcSizeContestResult,
+ ScrCmd_UpdateSizeContestRecord,
+ ScrCmd_BufferPartyPokemonSize,
+ ScrCmd_BufferSizeContestRecord,
ScrCmd_InitSizeContestRecord,
ScrCmd_SelectPartyMonMove,
ScrCmd_GetSelectedPartyMonMove,
@@ -5814,46 +5814,46 @@ static BOOL ScrCmd_GetRandom2(ScriptContext *ctx)
return TRUE;
}
-static BOOL ScrCmd_1C1(ScriptContext *ctx)
+static BOOL ScrCmd_CalcSizeContestResult(ScriptContext *ctx)
{
FieldSystem *fieldSystem = ctx->fieldSystem;
- u16 *v1 = ScriptContext_GetVarPointer(ctx);
- u16 v2 = ScriptContext_GetVar(ctx);
+ u16 *destVar = ScriptContext_GetVarPointer(ctx);
+ u16 partySlot = ScriptContext_GetVar(ctx);
- *v1 = ov5_021EE920(fieldSystem, v2);
+ *destVar = SizeContest_CalcResultForPartyMon(fieldSystem, partySlot);
return FALSE;
}
-static BOOL ScrCmd_1C2(ScriptContext *ctx)
+static BOOL ScrCmd_UpdateSizeContestRecord(ScriptContext *ctx)
{
FieldSystem *fieldSystem = ctx->fieldSystem;
- u16 v2 = ScriptContext_GetVar(ctx);
+ u16 partySlot = ScriptContext_GetVar(ctx);
- ov5_021EE9BC(fieldSystem, v2);
+ SizeContest_UpdateRecordFromPartyMon(fieldSystem, partySlot);
return FALSE;
}
-static BOOL ScrCmd_1C3(ScriptContext *ctx)
+static BOOL ScrCmd_BufferPartyPokemonSize(ScriptContext *ctx)
{
FieldSystem *fieldSystem = ctx->fieldSystem;
- u16 v1 = ScriptContext_GetVar(ctx);
- u16 v2 = ScriptContext_GetVar(ctx);
- u16 v3 = ScriptContext_GetVar(ctx);
+ u16 intPartIdx = ScriptContext_GetVar(ctx);
+ u16 fracPartIdx = ScriptContext_GetVar(ctx);
+ u16 partySlot = ScriptContext_GetVar(ctx);
- ov5_021EEA84(fieldSystem, v1, v2, v3);
+ SizeContest_SetPartyMonSizeStrParams(fieldSystem, intPartIdx, fracPartIdx, partySlot);
return FALSE;
}
-static BOOL ScrCmd_1C4(ScriptContext *ctx)
+static BOOL ScrCmd_BufferSizeContestRecord(ScriptContext *ctx)
{
FieldSystem *fieldSystem = ctx->fieldSystem;
- u16 v1 = ScriptContext_GetVar(ctx);
- u16 v2 = ScriptContext_GetVar(ctx);
- u16 v3 = ScriptContext_GetVar(ctx);
+ u16 intPartIdx = ScriptContext_GetVar(ctx);
+ u16 fracPartIdx = ScriptContext_GetVar(ctx);
+ u16 species = ScriptContext_GetVar(ctx);
- ov5_021EEA54(fieldSystem, v1, v2, v3);
+ SizeContest_SetRecordSizeStrParams(fieldSystem, intPartIdx, fracPartIdx, species);
return FALSE;
}