summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mystery_event_menu.c2
-rw-r--r--src/mystery_event_script.c421
-rw-r--r--src/record_mixing.c2
-rw-r--r--src/scrcmd.c2
-rw-r--r--src/script.c6
5 files changed, 396 insertions, 37 deletions
diff --git a/src/mystery_event_menu.c b/src/mystery_event_menu.c
index 89978f635..46b76fd88 100644
--- a/src/mystery_event_menu.c
+++ b/src/mystery_event_menu.c
@@ -287,7 +287,7 @@ static void CB2_MysteryEventMenu(void)
case 11:
if (gReceivedRemoteLinkPlayers)
break;
- unkVal = sub_812613C(unk_2000000);
+ unkVal = RunMysteryEventScript(unk_2000000);
CpuFill32(0, unk_2000000, 0x7D4);
if (!GetEventLoadMessage(gStringVar4, unkVal))
TrySavingData(NORMAL_SAVE);
diff --git a/src/mystery_event_script.c b/src/mystery_event_script.c
index f7a1b633d..f507942a7 100644
--- a/src/mystery_event_script.c
+++ b/src/mystery_event_script.c
@@ -1,103 +1,462 @@
#include "global.h"
+#include "berry.h"
+#include "easy_chat.h"
+#include "event_data.h"
+#include "mail_data.h"
#include "mystery_event_script.h"
+#include "pokedex.h"
+#include "pokemon.h"
+#include "pokemon_size_record.h"
#include "script.h"
+#include "species.h"
+#include "strings.h"
#include "string_util.h"
#include "text.h"
+#include "util.h"
#if ENGLISH
-#define UNK_MASK_1 0x2
+#define LANGUAGE_MASK 0x2
#elif GERMAN
-#define UNK_MASK_1 0x4
+#define LANGUAGE_MASK 0x4
#endif
#ifdef SAPPHIRE
-#define UNK_MASK_2 0x100
+#define VERSION_MASK 0x100
#else
-#define UNK_MASK_2 0x80
+#define VERSION_MASK 0x80
#endif
-extern ScrCmdFunc gScriptFuncs[];
-extern ScrCmdFunc gScriptFuncs_End[];
+extern void party_compaction(void);
+extern void sub_813601C(void);
-extern u8 gOtherText_DataCannotUseVersion[];
+extern ScrCmdFunc gMysteryEventScriptCmdTable[];
+extern ScrCmdFunc gMysteryEventScriptCmdTableEnd[];
-static EWRAM_DATA struct ScriptContext gUnknown_02039288 = {0};
+extern const u8 gOtherText_BerryObtainedDadHasIt[];
+extern const u8 gOtherText_BerryTransformed[];
+extern const u8 gOtherText_BerryAlreadyObtained[];
+extern const u8 gOtherText_SpecialRibbonReceived[];
+extern const u8 gOtherText_DexUpgraded[];
+extern const u8 gOtherText_RareWordAdded[];
+extern const u8 gOtherText_PokeWasSentOver[];
+extern const u8 gOtherText_PartyIsFull[];
+extern const u8 gOtherText_NewTrainerInHoenn[];
+extern const u8 gOtherText_DataCannotUseVersion[];
-bool32 sub_8126098(u16 a1, u32 a2, u16 a3, u32 a4)
+static EWRAM_DATA struct ScriptContext sMysteryEventScriptContext = {0};
+
+static bool32 CheckCompatibility(u16 a1, u32 a2, u16 a3, u32 a4)
{
- if (!(a1 & UNK_MASK_1))
+ if (!(a1 & LANGUAGE_MASK))
return FALSE;
- if (!(a2 & UNK_MASK_1))
+ if (!(a2 & LANGUAGE_MASK))
return FALSE;
if (!(a3 & 0x4))
return FALSE;
- if (!(a4 & UNK_MASK_2))
+ if (!(a4 & VERSION_MASK))
return FALSE;
return TRUE;
}
-void sub_81260D0(void)
+static void SetIncompatible(void)
{
StringExpandPlaceholders(gStringVar4, gOtherText_DataCannotUseVersion);
- sub_8126160(3);
+ SetMysteryEventScriptStatus(3);
}
-void sub_81260EC(struct ScriptContext *ctx, u8 *ptr)
+static void InitMysteryEventScript(struct ScriptContext *ctx, u8 *script)
{
- InitScriptContext(ctx, gScriptFuncs, gScriptFuncs_End);
- SetupBytecodeScript(ctx, ptr);
- ctx->data[0] = (u32)ptr;
+ InitScriptContext(ctx, gMysteryEventScriptCmdTable, gMysteryEventScriptCmdTableEnd);
+ SetupBytecodeScript(ctx, script);
+ ctx->data[0] = (u32)script;
ctx->data[1] = 0;
ctx->data[2] = 0;
ctx->data[3] = 0;
}
-bool32 sub_812611C(struct ScriptContext *ctx)
+static bool32 RunMysteryEventScriptCommand(struct ScriptContext *ctx)
{
- if (RunScript(ctx) && ctx->data[3])
+ if (RunScriptCommand(ctx) && ctx->data[3])
return TRUE;
else
return FALSE;
}
-u32 sub_812613C(u8 *ptr)
+u32 RunMysteryEventScript(u8 *script)
{
- struct ScriptContext *ctx = &gUnknown_02039288;
- sub_81260EC(ctx, ptr);
- while (sub_812611C(ctx))
+ struct ScriptContext *ctx = &sMysteryEventScriptContext;
+ InitMysteryEventScript(ctx, script);
+ while (RunMysteryEventScriptCommand(ctx))
;
return ctx->data[2];
}
-void sub_8126160(u32 val)
+void SetMysteryEventScriptStatus(u32 val)
{
- gUnknown_02039288.data[2] = val;
+ sMysteryEventScriptContext.data[2] = val;
}
-int sub_812616C(u8 *a1, int a2)
+static int CalcChecksum(u8 *data, int size)
{
unsigned int i;
int sum = 0;
- for (i = 0; i < a2; i++)
- sum += a1[i];
+ for (i = 0; i < size; i++)
+ sum += data[i];
return sum;
}
-u32 sub_812618C(u8 *ptr)
+static u32 GetWord(u8 *ptr)
{
return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
}
-void sub_81261A4(u8 *ptr, u32 val)
+static void SetWord(u8 *ptr, u32 val)
{
ptr[0] = val;
ptr[1] = val >> 8;
ptr[2] = val >> 16;
ptr[3] = val >> 24;
}
+
+bool8 unref_sub_81261B4(u8 *a1, int a2)
+{
+ if (a1[0x0] == 1 && a1[0x11] == 15 && !GetWord(a1 + 0x12))
+ {
+ int v4 = GetWord(a1 + 0x16) - a2 + (int)a1;
+ int v5 = GetWord(a1 + 0x1A);
+ int v6 = CalcChecksum((u8*)v4, v5 - a2 + (int)a1 - v4);
+ SetWord(a1 + 0x12, v6);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+bool8 unref_sub_812620C(u8 *a1, int a2)
+{
+ if (a1[0x0] == 1 && a1[0x11] == 16 && !GetWord(a1 + 0x12))
+ {
+ int v4 = GetWord(a1 + 0x16) - a2 + (int)a1;
+ int v5 = GetWord(a1 + 0x1A);
+ int v6 = CalcCRC16((u8*)v4, v5 - a2 + (int)a1 - v4);
+ SetWord(a1 + 0x12, v6);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static u32 CalcRecordMixingGiftChecksum(void)
+{
+ u32 sum = 0;
+ int i;
+ char *data = (char *)&gSaveBlock1.recordMixingGift.data;
+
+ for (i = 0; i < sizeof(gSaveBlock1.recordMixingGift.data); i++)
+ {
+ sum += data[i];
+ }
+
+ return sum;
+}
+
+static bool32 IsRecordMixingGiftValid(void)
+{
+ struct RecordMixingGiftData *data = &gSaveBlock1.recordMixingGift.data;
+
+ u32 checksum = CalcRecordMixingGiftChecksum();
+
+ if (!data->unk0)
+ return FALSE;
+
+ if (!data->quantity)
+ return FALSE;
+
+ if (!data->itemId)
+ return FALSE;
+
+ if (checksum == 0)
+ return FALSE;
+
+ if (checksum == gSaveBlock1.recordMixingGift.checksum)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void ClearRecordMixingGift(void)
+{
+ CpuFill16(0, &gSaveBlock1.recordMixingGift, sizeof(gSaveBlock1.recordMixingGift));
+}
+
+static void SetRecordMixingGift(u8 unk, u8 quantity, u16 itemId)
+{
+ if (!unk || !quantity || !itemId)
+ {
+ ClearRecordMixingGift();
+ }
+ else
+ {
+ gSaveBlock1.recordMixingGift.data.unk0 = unk;
+ gSaveBlock1.recordMixingGift.data.quantity = quantity;
+ gSaveBlock1.recordMixingGift.data.itemId = itemId;
+ gSaveBlock1.recordMixingGift.checksum = CalcRecordMixingGiftChecksum();
+ }
+}
+
+u16 GetRecordMixingGift(void)
+{
+ struct RecordMixingGiftData *data = &gSaveBlock1.recordMixingGift.data;
+
+ if (!IsRecordMixingGiftValid())
+ {
+ ClearRecordMixingGift();
+ return 0;
+ }
+ else
+ {
+ u16 itemId = data->itemId;
+ data->quantity--;
+ if (data->quantity == 0)
+ ClearRecordMixingGift();
+ else
+ gSaveBlock1.recordMixingGift.checksum = CalcRecordMixingGiftChecksum();
+ return itemId;
+ }
+}
+
+bool8 MEScrCmd_end(struct ScriptContext *ctx)
+{
+ StopScript(ctx);
+ return TRUE;
+}
+
+bool8 MEScrCmd_checkcompat(struct ScriptContext *ctx)
+{
+ u16 v1;
+ u32 v2;
+ u16 v3;
+ u32 v4;
+
+ ctx->data[1] = ScriptReadWord(ctx);
+ v1 = ScriptReadHalfword(ctx);
+ v2 = ScriptReadWord(ctx);
+ v3 = ScriptReadHalfword(ctx);
+ v4 = ScriptReadWord(ctx);
+
+ if (CheckCompatibility(v1, v2, v3, v4) == TRUE)
+ ctx->data[3] = 1;
+ else
+ SetIncompatible();
+
+ return TRUE;
+}
+
+bool8 MEScrCmd_nop(struct ScriptContext *ctx)
+{
+ return FALSE;
+}
+
+bool8 MEScrCmd_setstatus(struct ScriptContext *ctx)
+{
+ u8 value = ScriptReadByte(ctx);
+ ctx->data[2] = value;
+ return FALSE;
+}
+
+bool8 MEScrCmd_setmsg(struct ScriptContext *ctx)
+{
+ u8 value = ScriptReadByte(ctx);
+ u8 *str = (u8 *)(ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0]);
+ if (value == 255 || value == ctx->data[2])
+ StringExpandPlaceholders(gStringVar4, str);
+ return FALSE;
+}
+
+bool8 MEScrCmd_runscript(struct ScriptContext *ctx)
+{
+ u8 *script = (u8 *)(ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0]);
+ ScriptContext2_RunNewScript(script);
+ return FALSE;
+}
+
+bool8 MEScrCmd_setenigmaberry(struct ScriptContext *ctx)
+{
+ u8 *str;
+ const u8 *message;
+ bool32 haveBerry = IsEnigmaBerryValid();
+ u8 *berry = (u8 *)(ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0]);
+ StringCopyN(gStringVar1, gSaveBlock1.enigmaBerry.berry.name, 7);
+ SetEnigmaBerry(berry);
+ StringCopyN(gStringVar2, gSaveBlock1.enigmaBerry.berry.name, 7);
+
+ if (!haveBerry)
+ {
+ str = gStringVar4;
+ message = gOtherText_BerryObtainedDadHasIt;
+ }
+ else if (StringCompare(gStringVar1, gStringVar2))
+ {
+ str = gStringVar4;
+ message = gOtherText_BerryTransformed;
+ }
+ else
+ {
+ str = gStringVar4;
+ message = gOtherText_BerryAlreadyObtained;
+ }
+
+ StringExpandPlaceholders(str, message);
+
+ ctx->data[2] = 2;
+
+ if (IsEnigmaBerryValid() == TRUE)
+ VarSet(0x402D, 1);
+ else
+ ctx->data[2] = 1;
+
+ return FALSE;
+}
+
+bool8 MEScrCmd_giveribbon(struct ScriptContext *ctx)
+{
+ u8 index = ScriptReadByte(ctx);
+ u8 ribbonId = ScriptReadByte(ctx);
+ GiveGiftRibbonToParty(index, ribbonId);
+ StringExpandPlaceholders(gStringVar4, gOtherText_SpecialRibbonReceived);
+ ctx->data[2] = 2;
+ return FALSE;
+}
+
+bool8 MEScrCmd_initramscript(struct ScriptContext *ctx)
+{
+ u8 mapGroup = ScriptReadByte(ctx);
+ u8 mapNum = ScriptReadByte(ctx);
+ u8 objectId = ScriptReadByte(ctx);
+ u8 *script = (u8 *)(ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0]);
+ u8 *scriptEnd = (u8 *)(ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0]);
+ InitRamScript(script, scriptEnd - script, mapGroup, mapNum, objectId);
+ return FALSE;
+}
+
+bool8 MEScrCmd_givenationaldex(struct ScriptContext *ctx)
+{
+ EnableNationalPokedex();
+ StringExpandPlaceholders(gStringVar4, gOtherText_DexUpgraded);
+ ctx->data[2] = 2;
+ return FALSE;
+}
+
+bool8 MEScrCmd_addrareword(struct ScriptContext *ctx)
+{
+ sub_80EB890(ScriptReadByte(ctx));
+ StringExpandPlaceholders(gStringVar4, gOtherText_RareWordAdded);
+ ctx->data[2] = 2;
+ return FALSE;
+}
+
+bool8 MEScrCmd_setrecordmixinggift(struct ScriptContext *ctx)
+{
+ u8 unk = ScriptReadByte(ctx);
+ u8 quantity = ScriptReadByte(ctx);
+ u16 itemId = ScriptReadHalfword(ctx);
+ SetRecordMixingGift(unk, quantity, itemId);
+ return FALSE;
+}
+
+bool8 MEScrCmd_givepokemon(struct ScriptContext *ctx)
+{
+ struct MailStruct mail;
+ struct Pokemon pokemon;
+ u16 species;
+ u16 heldItem;
+ u32 data = ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0];
+ void *pokemonPtr = (void *)data;
+ void *mailPtr = (void *)(data + sizeof(struct Pokemon));
+
+ pokemon = *(struct Pokemon *)pokemonPtr;
+ species = GetMonData(&pokemon, MON_DATA_SPECIES2);
+
+ if (species == SPECIES_EGG)
+ StringCopyN(gStringVar1, gSystemText_Egg, 11);
+ else
+ StringCopyN(gStringVar1, gSystemText_Pokemon2, 11);
+
+ if (gPlayerPartyCount == 6)
+ {
+ StringExpandPlaceholders(gStringVar4, gOtherText_PartyIsFull);
+ ctx->data[2] = 3;
+ }
+ else
+ {
+ memcpy(&gPlayerParty[5], pokemonPtr, sizeof(struct Pokemon));
+ memcpy(&mail, mailPtr, sizeof(struct MailStruct));
+
+ if (species != SPECIES_EGG)
+ {
+ u16 pokedexNum = SpeciesToNationalPokedexNum(species);
+ GetNationalPokedexFlag(pokedexNum, 2);
+ GetNationalPokedexFlag(pokedexNum, 3);
+ }
+
+ heldItem = GetMonData(&gPlayerParty[5], MON_DATA_HELD_ITEM);
+ if (ItemIsMail(heldItem))
+ GiveMailToMon2(&gPlayerParty[5], &mail);
+ party_compaction();
+ CalculatePlayerPartyCount();
+ StringExpandPlaceholders(gStringVar4, gOtherText_PokeWasSentOver);
+ ctx->data[2] = 2;
+ }
+
+ return FALSE;
+}
+
+bool8 MEScrCmd_addtrainer(struct ScriptContext *ctx)
+{
+ u32 data = ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0];
+ memcpy(gSaveBlock2.filler_A8.ereaderTrainer, (void *)data, sizeof(gSaveBlock2.filler_A8.ereaderTrainer));
+ sub_813601C();
+ StringExpandPlaceholders(gStringVar4, gOtherText_NewTrainerInHoenn);
+ ctx->data[2] = 2;
+ return FALSE;
+}
+
+bool8 MEScrCmd_enableresetrtc(struct ScriptContext *ctx)
+{
+ EnableResetRTC();
+ StringExpandPlaceholders(gStringVar4, gSystemText_ClockAdjustmentUsable);
+ ctx->data[2] = 2;
+ return FALSE;
+}
+
+bool8 MEScrCmd_checksum(struct ScriptContext *ctx)
+{
+ int checksum = ScriptReadWord(ctx);
+ u8 *data = (u8 *)(ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0]);
+ u8 *dataEnd = (u8 *)(ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0]);
+ if (checksum != CalcChecksum(data, dataEnd - data))
+ {
+ ctx->data[3] = 0;
+ ctx->data[2] = 1;
+ }
+ return TRUE;
+}
+
+bool8 MEScrCmd_crc(struct ScriptContext *ctx)
+{
+ int crc = ScriptReadWord(ctx);
+ u8 *data = (u8 *)(ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0]);
+ u8 *dataEnd = (u8 *)(ScriptReadWord(ctx) - ctx->data[1] + ctx->data[0]);
+ if (crc != CalcCRC16(data, dataEnd - data))
+ {
+ ctx->data[3] = 0;
+ ctx->data[2] = 1;
+ }
+ return TRUE;
+}
diff --git a/src/record_mixing.c b/src/record_mixing.c
index 9cbcce49c..d1083910c 100644
--- a/src/record_mixing.c
+++ b/src/record_mixing.c
@@ -81,7 +81,7 @@ void RecordMixing_PrepareExchangePacket(void)
memcpy(unk_2018000.filler1124, gUnknown_083D0284, sizeof(unk_2018000.filler1124));
if (GetMultiplayerId() == 0)
- unk_2018000.filler11C8[0] = sub_8126338();
+ unk_2018000.filler11C8[0] = GetRecordMixingGift();
}
void RecordMixing_ReceiveExchangePacket(u32 a)
diff --git a/src/scrcmd.c b/src/scrcmd.c
index 7d719371e..66578f350 100644
--- a/src/scrcmd.c
+++ b/src/scrcmd.c
@@ -280,7 +280,7 @@ bool8 ScrCmd_die(struct ScriptContext *ctx)
bool8 ScrCmd_setbyte(struct ScriptContext *ctx)
{
u8 value = ScriptReadByte(ctx);
- sub_8126160(value);
+ SetMysteryEventScriptStatus(value);
return FALSE;
}
diff --git a/src/script.c b/src/script.c
index e5be913c6..8f12da437 100644
--- a/src/script.c
+++ b/src/script.c
@@ -52,7 +52,7 @@ void StopScript(struct ScriptContext *ctx)
ctx->scriptPtr = 0;
}
-u8 RunScript(struct ScriptContext *ctx)
+u8 RunScriptCommand(struct ScriptContext *ctx)
{
if (ctx->mode == 0)
return 0;
@@ -191,7 +191,7 @@ bool8 ScriptContext2_RunScript(void)
ScriptContext2_Enable();
- if (!RunScript(&sScriptContext1))
+ if (!RunScriptCommand(&sScriptContext1))
{
sScriptContext1Status = 2;
ScriptContext2_Disable();
@@ -224,7 +224,7 @@ void ScriptContext2_RunNewScript(const u8 *ptr)
{
InitScriptContext(&sScriptContext2, &gScriptCmdTable, &gScriptCmdTableEnd);
SetupBytecodeScript(&sScriptContext2, ptr);
- while (RunScript(&sScriptContext2) == 1)
+ while (RunScriptCommand(&sScriptContext2) == 1)
;
}