diff --git a/include/macros.h b/include/macros.h index fd6f0e62ad..5d1829c4c5 100644 --- a/include/macros.h +++ b/include/macros.h @@ -29,13 +29,6 @@ #define GET_FIRST_ENEMY(play) ((Actor*)(play)->actorCtx.actorLists[ACTORCAT_ENEMY].first) -// linkAge still exists in MM, but is always set to 0 (always adult) -// There are remnants of these macros from OOT, but they are essentially useless -#define LINK_IS_CHILD (gSaveContext.save.linkAge == 1) -#define LINK_IS_ADULT (gSaveContext.save.linkAge == 0) - -#define CURRENT_DAY (((void)0, gSaveContext.save.day) % 5) - #define CLOCK_TIME(hr, min) (s32)(((hr) * 60 + (min)) * 0x10000 / (24 * 60)) #define CLOCK_TIME_MINUTE (CLOCK_TIME(0, 1)) #define DAY_LENGTH (CLOCK_TIME(24, 0)) @@ -46,66 +39,6 @@ #define TIME_TO_MINUTES_ALT_F(time) ((time) / (0x10000 / (24.0f * 60.0f))) #define CLOCK_TIME_ALT_F(hr, min) (((hr) * 60.0f + (min)) / (24.0f * 60.0f / 0x10000)) -#define SLOT(item) gItemSlots[item] -#define AMMO(item) gSaveContext.save.inventory.ammo[SLOT(item)] -#define INV_CONTENT(item) gSaveContext.save.inventory.items[SLOT(item)] -#define GET_INV_CONTENT(item) ((void)0, gSaveContext.save.inventory.items)[SLOT(item)] - -#define CUR_FORM ((gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) ? 0 : gSaveContext.save.playerForm) - -#define GET_SAVE_EQUIPS_EQUIPMENT ((void)0, gSaveContext.save.equips.equipment) -#define GET_SAVE_INVENTORY_UPGRADES ((void)0, gSaveContext.save.inventory.upgrades) -#define GET_SAVE_INVENTORY_QUEST_ITEMS ((void)0, gSaveContext.save.inventory.questItems) - -#define GET_CUR_EQUIP_VALUE(equip) ((GET_SAVE_EQUIPS_EQUIPMENT & gEquipMasks[equip]) >> gEquipShifts[equip]) - -#define CUR_UPG_VALUE(upg) ((gSaveContext.save.inventory.upgrades & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) -#define GET_CUR_UPG_VALUE(upg) ((GET_SAVE_INVENTORY_UPGRADES & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) - -#define SET_EQUIP_VALUE(equip, value) (gSaveContext.save.equips.equipment = ((GET_SAVE_EQUIPS_EQUIPMENT & gEquipNegMasks[equip]) | (u16)((u16)(value) << gEquipShifts[equip]))) - -#define BUTTON_ITEM_EQUIP(form, button) (gSaveContext.save.equips.buttonItems[form][button]) -#define CUR_FORM_EQUIP(button) BUTTON_ITEM_EQUIP(CUR_FORM, button) - -#define C_SLOT_EQUIP(form, button) (gSaveContext.save.equips.cButtonSlots[form][button]) -#define CHECK_QUEST_ITEM(item) (GET_SAVE_INVENTORY_QUEST_ITEMS & gBitFlags[item]) -#define SET_QUEST_ITEM(item) (gSaveContext.save.inventory.questItems = (GET_SAVE_INVENTORY_QUEST_ITEMS | gBitFlags[item])) -#define REMOVE_QUEST_ITEM(item) (gSaveContext.save.inventory.questItems = (GET_SAVE_INVENTORY_QUEST_ITEMS & (-1 - gBitFlags[item]))) - -#define CHECK_DUNGEON_ITEM(item, dungeonIndex) (gSaveContext.save.inventory.dungeonItems[(void)0, dungeonIndex] & gBitFlags[item]) -#define SET_DUNGEON_ITEM(item, dungeonIndex) (gSaveContext.save.inventory.dungeonItems[(void)0, dungeonIndex] |= (u8)gBitFlags[item]) -#define DUNGEON_KEY_COUNT(dungeonIndex) (gSaveContext.save.inventory.dungeonKeys[(void)0, dungeonIndex]) - -#define GET_CUR_FORM_BTN_ITEM(btn) ((u8)((btn) == EQUIP_SLOT_B ? BUTTON_ITEM_EQUIP(CUR_FORM, btn) : BUTTON_ITEM_EQUIP(0, btn))) -#define GET_CUR_FORM_BTN_SLOT(btn) ((u8)((btn) == EQUIP_SLOT_B ? C_SLOT_EQUIP(CUR_FORM, btn) : C_SLOT_EQUIP(0, btn))) - - -#define SET_CUR_FORM_BTN_ITEM(btn, item) \ - if ((btn) == EQUIP_SLOT_B) { \ - BUTTON_ITEM_EQUIP(CUR_FORM, (btn)) = (item); \ - } else { \ - BUTTON_ITEM_EQUIP(0, (btn)) = (item); \ - } \ - (void)0 - -#define SET_CUR_FORM_BTN_SLOT(btn, item) \ - if ((btn) == EQUIP_SLOT_B) { \ - C_SLOT_EQUIP(CUR_FORM, (btn)) = (item); \ - } else { \ - C_SLOT_EQUIP(0, (btn)) = (item); \ - } \ - (void)0 - -#define STOLEN_ITEM_NONE (0) - -#define STOLEN_ITEM_1 ((gSaveContext.save.stolenItems & 0xFF000000) >> 0x18) -#define STOLEN_ITEM_2 ((gSaveContext.save.stolenItems & 0x00FF0000) >> 0x10) - -#define SET_STOLEN_ITEM_1(itemId) \ - (gSaveContext.save.stolenItems = (gSaveContext.save.stolenItems & ~0xFF000000) | ((itemId & 0xFF) << 0x18)) -#define SET_STOLEN_ITEM_2(itemId) \ - (gSaveContext.save.stolenItems = (gSaveContext.save.stolenItems & ~0x00FF0000) | ((itemId & 0xFF) << 0x10)) - #define CAPACITY(upg, value) gUpgradeCapacities[upg][value] #define CUR_CAPACITY(upg) CAPACITY(upg, CUR_UPG_VALUE(upg)) diff --git a/include/z64save.h b/include/z64save.h index d0b5d7fd2c..d24b5a7c8d 100644 --- a/include/z64save.h +++ b/include/z64save.h @@ -160,7 +160,7 @@ typedef struct Save { /* 0x0EE8 */ u32 unk_EE8; /* 0x0EEC */ u32 horseBackBalloonHighScore; /* 0x0EF0 */ u32 lotteryCodeGuess; // Lottery code chosen by player (only uses lower three hex digits) - /* 0x0EF4 */ u32 unk_EF4; // Shooting Gallery Man Flags + /* 0x0EF4 */ u32 shootingGalleryHighScores; // High scores for both shooting galleries. Town uses lower 16 bits, Swamp uses higher 16 bits. /* 0x0EF8 */ u8 weekEventReg[100]; // "week_event_reg" /* 0x0F5C */ u32 mapsVisited; // "area_arrival" /* 0x0F60 */ u32 mapsVisible; // "cloud_clear" @@ -273,6 +273,78 @@ typedef enum SunsSongState { /* 3 */ SUNSSONG_SPECIAL // time does not advance, but signals the song was played. used for freezing redeads } SunsSongState; +// linkAge still exists in MM, but is always set to 0 (always adult) +// There are remnants of these macros from OOT, but they are essentially useless +#define LINK_IS_CHILD (gSaveContext.save.linkAge == 1) +#define LINK_IS_ADULT (gSaveContext.save.linkAge == 0) + +#define CURRENT_DAY (((void)0, gSaveContext.save.day) % 5) + +#define SLOT(item) gItemSlots[item] +#define AMMO(item) gSaveContext.save.inventory.ammo[SLOT(item)] +#define INV_CONTENT(item) gSaveContext.save.inventory.items[SLOT(item)] +#define GET_INV_CONTENT(item) ((void)0, gSaveContext.save.inventory.items)[SLOT(item)] + +#define CUR_FORM ((gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) ? 0 : gSaveContext.save.playerForm) + +#define GET_SAVE_EQUIPS_EQUIPMENT ((void)0, gSaveContext.save.equips.equipment) +#define GET_SAVE_INVENTORY_UPGRADES ((void)0, gSaveContext.save.inventory.upgrades) +#define GET_SAVE_INVENTORY_QUEST_ITEMS ((void)0, gSaveContext.save.inventory.questItems) + +#define GET_CUR_EQUIP_VALUE(equip) ((GET_SAVE_EQUIPS_EQUIPMENT & gEquipMasks[equip]) >> gEquipShifts[equip]) + +#define CUR_UPG_VALUE(upg) ((gSaveContext.save.inventory.upgrades & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) +#define GET_CUR_UPG_VALUE(upg) ((GET_SAVE_INVENTORY_UPGRADES & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) + +#define SET_EQUIP_VALUE(equip, value) (gSaveContext.save.equips.equipment = ((GET_SAVE_EQUIPS_EQUIPMENT & gEquipNegMasks[equip]) | (u16)((u16)(value) << gEquipShifts[equip]))) + +#define BUTTON_ITEM_EQUIP(form, button) (gSaveContext.save.equips.buttonItems[form][button]) +#define CUR_FORM_EQUIP(button) BUTTON_ITEM_EQUIP(CUR_FORM, button) + +#define C_SLOT_EQUIP(form, button) (gSaveContext.save.equips.cButtonSlots[form][button]) +#define CHECK_QUEST_ITEM(item) (GET_SAVE_INVENTORY_QUEST_ITEMS & gBitFlags[item]) +#define SET_QUEST_ITEM(item) (gSaveContext.save.inventory.questItems = (GET_SAVE_INVENTORY_QUEST_ITEMS | gBitFlags[item])) +#define REMOVE_QUEST_ITEM(item) (gSaveContext.save.inventory.questItems = (GET_SAVE_INVENTORY_QUEST_ITEMS & (-1 - gBitFlags[item]))) + +#define CHECK_DUNGEON_ITEM(item, dungeonIndex) (gSaveContext.save.inventory.dungeonItems[(void)0, dungeonIndex] & gBitFlags[item]) +#define SET_DUNGEON_ITEM(item, dungeonIndex) (gSaveContext.save.inventory.dungeonItems[(void)0, dungeonIndex] |= (u8)gBitFlags[item]) +#define DUNGEON_KEY_COUNT(dungeonIndex) (gSaveContext.save.inventory.dungeonKeys[(void)0, dungeonIndex]) + +#define GET_CUR_FORM_BTN_ITEM(btn) ((u8)((btn) == EQUIP_SLOT_B ? BUTTON_ITEM_EQUIP(CUR_FORM, btn) : BUTTON_ITEM_EQUIP(0, btn))) +#define GET_CUR_FORM_BTN_SLOT(btn) ((u8)((btn) == EQUIP_SLOT_B ? C_SLOT_EQUIP(CUR_FORM, btn) : C_SLOT_EQUIP(0, btn))) + + +#define SET_CUR_FORM_BTN_ITEM(btn, item) \ + if ((btn) == EQUIP_SLOT_B) { \ + BUTTON_ITEM_EQUIP(CUR_FORM, (btn)) = (item); \ + } else { \ + BUTTON_ITEM_EQUIP(0, (btn)) = (item); \ + } \ + (void)0 + +#define SET_CUR_FORM_BTN_SLOT(btn, item) \ + if ((btn) == EQUIP_SLOT_B) { \ + C_SLOT_EQUIP(CUR_FORM, (btn)) = (item); \ + } else { \ + C_SLOT_EQUIP(0, (btn)) = (item); \ + } \ + (void)0 + +#define STOLEN_ITEM_NONE (0) + +#define STOLEN_ITEM_1 ((gSaveContext.save.stolenItems & 0xFF000000) >> 0x18) +#define STOLEN_ITEM_2 ((gSaveContext.save.stolenItems & 0x00FF0000) >> 0x10) + +#define SET_STOLEN_ITEM_1(itemId) \ + (gSaveContext.save.stolenItems = (gSaveContext.save.stolenItems & ~0xFF000000) | ((itemId & 0xFF) << 0x18)) +#define SET_STOLEN_ITEM_2(itemId) \ + (gSaveContext.save.stolenItems = (gSaveContext.save.stolenItems & ~0x00FF0000) | ((itemId & 0xFF) << 0x10)) + +#define GET_TOWN_SHOOTING_GALLERY_HIGH_SCORE() ((s32)(gSaveContext.save.shootingGalleryHighScores & 0xFFFF)) +#define GET_SWAMP_SHOOTING_GALLERY_HIGH_SCORE() ((s32)((gSaveContext.save.shootingGalleryHighScores & 0xFFFF0000) >> 0x10)) +#define SET_TOWN_SHOOTING_GALLERY_HIGH_SCORE(score) (gSaveContext.save.shootingGalleryHighScores = (gSaveContext.save.shootingGalleryHighScores & 0xFFFF0000) | ((u16)(score))) +#define SET_SWAMP_SHOOTING_GALLERY_HIGH_SCORE(score) (gSaveContext.save.shootingGalleryHighScores = ((gSaveContext.save.shootingGalleryHighScores) & 0xFFFF) | ((u16)(score) << 0x10)) + typedef enum { /* 0 */ DUNGEON_INDEX_WOODFALL_TEMPLE, /* 1 */ DUNGEON_INDEX_SNOWHEAD_TEMPLE, diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c index 69a0a4491b..8139846e68 100644 --- a/src/code/z_sram_NES.c +++ b/src/code/z_sram_NES.c @@ -199,8 +199,8 @@ void Sram_ClearHighscores(void) { gSaveContext.save.unk_EE8 = (gSaveContext.save.unk_EE8 & 0xFFFF) | 0x130000; gSaveContext.save.unk_EE8 = (gSaveContext.save.unk_EE8 & 0xFFFF0000) | 0xA; gSaveContext.save.horseBackBalloonHighScore = 6000; // 60 seconds - gSaveContext.save.unk_EF4 = (gSaveContext.save.unk_EF4 & 0xFFFF0000) | 0x27; - gSaveContext.save.unk_EF4 = (gSaveContext.save.unk_EF4 & 0xFFFF) | 0xA0000; + SET_TOWN_SHOOTING_GALLERY_HIGH_SCORE(39); + SET_SWAMP_SHOOTING_GALLERY_HIGH_SCORE(10); gSaveContext.save.dekuPlaygroundHighScores[0] = 7500; // 75 seconds gSaveContext.save.dekuPlaygroundHighScores[1] = 7500; // 75 seconds diff --git a/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c index 65b11055cb..a8d76a7a8e 100644 --- a/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c +++ b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c @@ -90,7 +90,7 @@ void EnSyatekiCrow_Init(Actor* thisx, PlayState* play2) { path = &play->setupPathList[path->unk1]; } - for (i = 0; i < EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor); i++) { + for (i = 0; i < EN_SYATEKI_CROW_GET_NUMBER(&this->actor); i++) { path = &play->setupPathList[path->unk1]; } @@ -102,7 +102,7 @@ void EnSyatekiCrow_Init(Actor* thisx, PlayState* play2) { this->unk_23C.elements->dim.worldSphere.radius = sJntSphInit.elements[0].dim.modelSphere.radius; ActorShape_Init(&this->actor.shape, 2000.0f, ActorShadow_DrawCircle, 20.0f); - if ((path == NULL) || (EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor) >= 0x80)) { + if ((path == NULL) || (EN_SYATEKI_CROW_GET_NUMBER(&this->actor) >= 0x80)) { Actor_MarkForDeath(&this->actor); return; } @@ -136,14 +136,14 @@ void func_809CA5D4(EnSyatekiCrow* this) { void func_809CA67C(EnSyatekiCrow* this, PlayState* play) { EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - if ((syatekiMan->unk_26A == 1) && (this->unk_1C2 == 1) && - (syatekiMan->unk_274 & (1 << EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor)))) { + if ((syatekiMan->shootingGameState == SG_GAME_STATE_RUNNING) && (this->unk_1C2 == 1) && + (syatekiMan->guayFlags & (1 << EN_SYATEKI_CROW_GET_NUMBER(&this->actor)))) { func_809CA71C(this); - } else if (syatekiMan->unk_26A != 1) { + } else if (syatekiMan->shootingGameState != SG_GAME_STATE_RUNNING) { this->unk_1C2 = 1; } - if ((syatekiMan->unk_274 == 0) && (syatekiMan->unk_274 == 0)) { + if ((syatekiMan->guayFlags == 0) && (syatekiMan->guayFlags == 0)) { this->unk_1C2 = 1; } } @@ -185,7 +185,7 @@ void func_809CA8E4(EnSyatekiCrow* this, PlayState* play) { f32 sp30; EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - if (syatekiMan->unk_26A != 1) { + if (syatekiMan->shootingGameState != SG_GAME_STATE_RUNNING) { func_809CA5D4(this); return; } @@ -207,13 +207,13 @@ void func_809CA8E4(EnSyatekiCrow* this, PlayState* play) { this->unk_1CC++; } else { this->unk_1C2 = 0; - syatekiMan->unk_274 &= ~(1 << EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor)); + syatekiMan->guayFlags &= ~(1 << EN_SYATEKI_CROW_GET_NUMBER(&this->actor)); func_809CA5D4(this); } SkelAnime_Update(&this->skelAnime); this->actor.shape.yOffset = (fabsf(this->skelAnime.curFrame - 3.0f) * 150.0f) + 1700.0f; - if ((syatekiMan->unk_26C % 90) == 0) { + if ((syatekiMan->perGameVar1.guaySpawnTimer % 90) == 0) { Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_CRY); } } @@ -221,7 +221,7 @@ void func_809CA8E4(EnSyatekiCrow* this, PlayState* play) { void func_809CAAF8(EnSyatekiCrow* this) { EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - syatekiMan->unk_280 += 60; + syatekiMan->score += 60; this->unk_1C2 = 0; this->actor.speedXZ *= Math_CosS(this->actor.world.rot.x); this->actor.velocity.y = 0.0f; @@ -245,8 +245,8 @@ void func_809CABC0(EnSyatekiCrow* this, PlayState* play) { if (this->unk_1C4 > 20) { func_800B3030(play, &this->actor.world.pos, &D_809CB050, &D_809CB050, this->actor.scale.x * 10000.0f, 0, 0); - syatekiMan->unk_27A++; - syatekiMan->unk_274 &= ~(1 << EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor)); + syatekiMan->guayHitCounter++; + syatekiMan->guayFlags &= ~(1 << EN_SYATEKI_CROW_GET_NUMBER(&this->actor)); func_809CA5D4(this); } diff --git a/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.h b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.h index d0b626218d..05eec4ad0c 100644 --- a/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.h +++ b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.h @@ -5,7 +5,8 @@ #define EN_SYATEKI_CROW_GET_PARAM_F(thisx) ((thisx)->params & 0xF) #define EN_SYATEKI_CROW_GET_PARAM_F0(thisx) (((thisx)->params & 0xF0) >> 4) -#define EN_SYATEKI_CROW_GET_PARAM_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) +#define EN_SYATEKI_CROW_GET_NUMBER(thisx) (((thisx)->params & 0xFF00) >> 8) +#define EN_SYATEKI_CROW_PARAMS(number, unkF0, unkF) (((number << 8) & 0xFF00) | ((unkF0 << 4) & 0xF0) | (unkF & 0xF)) struct EnSyatekiCrow; diff --git a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c index f0f0a225bd..887e626570 100644 --- a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c +++ b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c @@ -131,7 +131,7 @@ void EnSyatekiDekunuts_Init(Actor* thisx, PlayState* play2) { } this->unk_1E4 = Lib_SegmentedToVirtual(path->points); - this->unk_1E8 = EN_SYATEKI_DEKUNUTS_GET_PARAM_F0(&this->actor); + this->unk_1E8 = EN_SYATEKI_DEKUNUTS_GET_NUMBER(&this->actor); this->unk_1EA = path->count; this->unk_1D8 = 0; this->unk_1DC = 0; @@ -166,13 +166,14 @@ void func_80A2BE54(EnSyatekiDekunuts* this) { void func_80A2BF18(EnSyatekiDekunuts* this, PlayState* play) { EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - if ((syatekiMan->unk_26A == 1) && (this->unk_1E2 == 1) && ((syatekiMan->unk_272 & (1 << this->unk_1E8)) != 0)) { + if ((syatekiMan->shootingGameState == SG_GAME_STATE_RUNNING) && (this->unk_1E2 == 1) && + ((syatekiMan->dekuScrubFlags & (1 << this->unk_1E8)) != 0)) { func_80A2BFC4(this); - } else if (syatekiMan->unk_26A != 1) { + } else if (syatekiMan->shootingGameState != SG_GAME_STATE_RUNNING) { this->unk_1E2 = 1; } - if ((syatekiMan->unk_272 == 0) && (syatekiMan->unk_274 == 0) && + if ((syatekiMan->dekuScrubFlags == 0) && (syatekiMan->guayFlags == 0) && (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) != 1)) { this->unk_1E2 = 1; } @@ -189,9 +190,9 @@ void func_80A2BFC4(EnSyatekiDekunuts* this) { this->actor.world.pos = this->actor.prevPos = sp14; this->actor.world.rot.y = this->actor.yawTowardsPlayer; this->actor.shape.rot.y = this->actor.yawTowardsPlayer; - this->unk_1EE = 140 - (syatekiMan->unk_27C * 20); + this->unk_1EE = 140 - (syatekiMan->currentWave * 20); - if ((syatekiMan->unk_27C & 1) != 0) { + if ((syatekiMan->currentWave & 1) != 0) { this->unk_1F0 = 1; this->unk_1F2 = 0; } else { @@ -260,7 +261,7 @@ void func_80A2C27C(EnSyatekiDekunuts* this) { void func_80A2C2E0(EnSyatekiDekunuts* this, PlayState* play) { EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - if ((this->unk_1EE < this->unk_1D8) || (syatekiMan->unk_26A != 1)) { + if ((this->unk_1EE < this->unk_1D8) || (syatekiMan->shootingGameState != SG_GAME_STATE_RUNNING)) { func_80A2C3AC(this); } @@ -270,7 +271,7 @@ void func_80A2C2E0(EnSyatekiDekunuts* this, PlayState* play) { void func_80A2C33C(EnSyatekiDekunuts* this, PlayState* play) { EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - if ((gSaveContext.unk_3DE0[1] <= 0) || (syatekiMan->unk_26A != 1)) { + if ((gSaveContext.unk_3DE0[1] <= 0) || (syatekiMan->shootingGameState != SG_GAME_STATE_RUNNING)) { func_80A2C3AC(this); } @@ -287,7 +288,7 @@ void func_80A2C3AC(EnSyatekiDekunuts* this) { void func_80A2C3F0(EnSyatekiDekunuts* this, PlayState* play) { EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - if (syatekiMan->unk_26A == 1) { + if (syatekiMan->shootingGameState == SG_GAME_STATE_RUNNING) { if (this->unk_1D8 > 160 && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->unk_1D8 = 0; func_80A2C150(this); @@ -319,12 +320,12 @@ void func_80A2C4D0(EnSyatekiDekunuts* this, PlayState* play) { if (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) == 1) { EffectSsExtra_Spawn(play, &this->actor.world.pos, &D_80A2CBA0, &D_80A2CBAC, 5, 2); - syatekiMan->unk_280 += 100; - syatekiMan->unk_26E++; + syatekiMan->score += 100; + syatekiMan->perGameVar2.bonusDekuScrubHitCounter++; } else { EffectSsExtra_Spawn(play, &this->actor.world.pos, &D_80A2CBA0, &D_80A2CBAC, 5, 0); - syatekiMan->unk_280 += 30; - syatekiMan->unk_278++; + syatekiMan->score += 30; + syatekiMan->dekuScrubHitCounter++; } Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DAMAGE); @@ -356,7 +357,7 @@ void func_80A2C5DC(EnSyatekiDekunuts* this, PlayState* play) { EffectSsHahen_SpawnBurst(play, &sp40, 3.0f, 0, 12, 3, 15, HAHEN_OBJECT_DEFAULT, 10, NULL); if (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) != 1) { - syatekiMan->unk_272 &= ~(1 << this->unk_1E8); + syatekiMan->dekuScrubFlags &= ~(1 << this->unk_1E8); } func_80A2BE54(this); diff --git a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.h b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.h index 5acf4d4932..447dcaee70 100644 --- a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.h +++ b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.h @@ -5,8 +5,9 @@ #include "objects/object_dekunuts/object_dekunuts.h" #define EN_SYATEKI_DEKUNUTS_GET_PARAM_F(thisx) ((thisx)->params & 0xF) -#define EN_SYATEKI_DEKUNUTS_GET_PARAM_F0(thisx) (((thisx)->params & 0xF0) >> 4) +#define EN_SYATEKI_DEKUNUTS_GET_NUMBER(thisx) (((thisx)->params & 0xF0) >> 4) #define EN_SYATEKI_DEKUNUTS_GET_PARAM_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) +#define EN_SYATEKI_DEKUNUTS_PARAMS(unkFF00, number, unkF) (((unkFF00 << 8) & 0xFF00) | ((number << 4) & 0xF0) | (unkF & 0xF)) struct EnSyatekiDekunuts; diff --git a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index 3a1409e100..975d1dabf7 100644 --- a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -2,9 +2,15 @@ * File: z_en_syateki_man.c * Overlay: ovl_En_Syateki_Man * Description: Shooting Gallery Man + * + * In addition to handling the normal NPC behavior with the Town/Swamp Shooting Gallery Man, this actor is also + * responsible for running their respective shooting games as well. */ #include "z_en_syateki_man.h" +#include "overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.h" +#include "overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.h" +#include "overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_8000000) @@ -15,24 +21,43 @@ void EnSyatekiMan_Destroy(Actor* thisx, PlayState* play); void EnSyatekiMan_Update(Actor* thisx, PlayState* play); void EnSyatekiMan_Draw(Actor* thisx, PlayState* play); -void func_809C6810(EnSyatekiMan* this, PlayState* play); -void func_809C6848(EnSyatekiMan* this, PlayState* play); -void func_809C6E30(EnSyatekiMan* this, PlayState* play); -void func_809C72D8(EnSyatekiMan* this, PlayState* play); -void func_809C7990(EnSyatekiMan* this, PlayState* play); -void func_809C7A90(EnSyatekiMan* this, PlayState* play); -void func_809C7C14(EnSyatekiMan* this, PlayState* play); -void func_809C7D14(EnSyatekiMan* this, PlayState* play); -void func_809C7EB4(EnSyatekiMan* this, PlayState* play); -void func_809C7FFC(EnSyatekiMan* this, PlayState* play); -void func_809C80C0(EnSyatekiMan* this, PlayState* play); -void func_809C81D0(EnSyatekiMan* this, PlayState* play); -void func_809C8488(EnSyatekiMan* this, PlayState* play); -void func_809C8610(EnSyatekiMan* this, PlayState* play); -void func_809C8710(EnSyatekiMan* this, PlayState* play); -void func_809C8808(EnSyatekiMan* this, PlayState* play); -void func_809C898C(EnSyatekiMan* this, PlayState* play); -void func_809C8BF0(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_SetupIdle(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Swamp_Idle(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Swamp_Talk(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Town_Idle(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Town_Talk(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Swamp_SetupGiveReward(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Swamp_GiveReward(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Town_SetupGiveReward(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Town_GiveReward(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Swamp_MovePlayerAndExplainRules(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Swamp_StartGame(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Swamp_RunGame(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Swamp_EndGame(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Swamp_AddBonusPoints(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Town_MovePlayerAndSayHighScore(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Town_StartGame(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Town_RunGame(EnSyatekiMan* this, PlayState* play); +void EnSyatekiMan_Town_EndGame(EnSyatekiMan* this, PlayState* play); + +#define TALK_FLAG_NONE 0 +#define TALK_FLAG_TOWN_HAS_SPOKEN_WITH_HUMAN (1 << 0) +#define TALK_FLAG_TOWN_HAS_SPOKEN_WITH_DEKU (1 << 1) +#define TALK_FLAG_TOWN_HAS_SPOKEN_WITH_GORON (1 << 2) +#define TALK_FLAG_TOWN_HAS_SPOKEN_WITH_ZORA (1 << 3) +#define TALK_FLAG_TOWN_HAS_EXPLAINED_THE_RULES (1 << 4) +#define TALK_FLAG_SWAMP_HAS_SPOKEN_WITH_HUMAN (1 << 0) +#define TALK_FLAG_SWAMP_HAS_EXPLAINED_THE_RULES (1 << 1) + +#define OCTOROK_FLAG(color, row, column) (1 << ((row * 6) + (column * 2) + color)) +#define COLOR_RED 0 +#define COLOR_BLUE 1 +#define ROW_BACK 0 +#define ROW_CENTER 1 +#define ROW_FRONT 2 +#define COLUMN_LEFT 0 +#define COLUMN_CENTER 1 +#define COLUMN_RIGHT 2 const ActorInit En_Syateki_Man_InitVars = { ACTOR_EN_SYATEKI_MAN, @@ -46,87 +71,111 @@ const ActorInit En_Syateki_Man_InitVars = { (ActorFunc)EnSyatekiMan_Draw, }; +typedef enum { + /* 0 */ EN_SYATEKI_MAN_ANIMATION_HANDS_ON_TABLE, + /* 1 */ EN_SYATEKI_MAN_ANIMATION_SWAMP_HEAD_SCRATCH_LOOP, + /* 2 */ EN_SYATEKI_MAN_ANIMATION_SWAMP_HEAD_SCRATCH_END, +} EnSyatekiManAnimationIndex; + static AnimationInfo sAnimations[] = { { &gBurlyGuyHandsOnTableAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, { &gSwampShootingGalleryManHeadScratchLoopAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, { &gSwampShootingGalleryManHeadScratchEndAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, }; -static s16 D_809C91C8[] = { - 0x00C1, - 0x0302, - 0x0019, - 0x0026, +/** + * In the Swamp Shooting Gallery, there are four waves of Guays. + * For each wave, these flags are used to control which Guays appear. + */ +static s16 sGuayFlagsPerWave[] = { + (1 << 7) | (1 << 6) | (1 << 0), + (1 << 9) | (1 << 8) | (1 << 1), + (1 << 4) | (1 << 3) | (1 << 0), + (1 << 5) | (1 << 2) | (1 << 1), }; -static EnSyatekiManUnkStruct D_809C91D0[] = { - { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, 0x130 }, - { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, 0x20 }, - { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x0 }, - { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x10 }, - { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x20 }, - { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x30 }, - { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x40 }, - { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x1 }, - { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x11 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x0 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x100 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x200 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x300 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x420 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x520 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x601 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x702 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x801 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x902 }, +typedef struct { + /* 0x00 */ s16 actorId; + /* 0x04 */ Vec3f pos; + /* 0x10 */ s32 params; +} SwampTargetActorEntry; // size = 0x14 + +static SwampTargetActorEntry sNormalSwampTargetActorList[] = { + { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_WF_PARAMS(1, 3, 0) }, + { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_WF_PARAMS(0, 2, 0) }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_DEKUNUTS_PARAMS(0, 0, 0) }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_DEKUNUTS_PARAMS(0, 1, 0) }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_DEKUNUTS_PARAMS(0, 2, 0) }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_DEKUNUTS_PARAMS(0, 3, 0) }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_DEKUNUTS_PARAMS(0, 4, 0) }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_DEKUNUTS_PARAMS(0, 0, 1) }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_DEKUNUTS_PARAMS(0, 1, 1) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(0, 0, 0) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(1, 0, 0) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(2, 0, 0) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(3, 0, 0) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(4, 2, 0) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(5, 2, 0) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(6, 0, 1) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(7, 0, 2) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(8, 0, 1) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(9, 0, 2) }, }; -static EnSyatekiManUnkStruct D_809C934C[] = { - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x0 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x100 }, - { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x1 }, - { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, 0x11 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x202 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x302 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x3 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x103 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x423 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x204 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x304 }, - { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, 0x424 }, - { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, 0x25 }, - { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, 0x136 }, +/** + * This actor list is never used in-game and doesn't work properly if modded in. + * Without any "normal" Deku Scrubs, the game will not progress beyond the first wave. + */ +static SwampTargetActorEntry sUnusedSwampTargetActorList[] = { + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(0, 0, 0) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(1, 0, 0) }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_DEKUNUTS_PARAMS(0, 0, 1) }, + { ACTOR_EN_SYATEKI_DEKUNUTS, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_DEKUNUTS_PARAMS(0, 1, 1) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(2, 0, 2) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(3, 0, 2) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(0, 0, 3) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(1, 0, 3) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(4, 2, 3) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(2, 0, 4) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(3, 0, 4) }, + { ACTOR_EN_SYATEKI_CROW, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_CROW_PARAMS(4, 2, 4) }, + { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_WF_PARAMS(0, 2, 5) }, + { ACTOR_EN_SYATEKI_WF, -1000.0f, 200.0f, -700.0f, EN_SYATEKI_WF_PARAMS(1, 3, 6) }, }; -static EnSyatekiManUnkStruct* D_809C9464[] = { - D_809C91D0, - D_809C934C, +static SwampTargetActorEntry* sSwampTargetActorLists[] = { + sNormalSwampTargetActorList, + sUnusedSwampTargetActorList, }; -static s32 D_809C946C[] = { - ARRAY_COUNT(D_809C91D0), - ARRAY_COUNT(D_809C934C), +static s32 sSwampTargetActorListLengths[] = { + ARRAY_COUNT(sNormalSwampTargetActorList), + ARRAY_COUNT(sUnusedSwampTargetActorList), }; -static Vec3f D_809C9474 = { 0.0f, 10.0f, 140.0f }; -static Vec3f D_809C9480 = { -20.0f, 20.0f, 198.0f }; -static Vec3f D_809C948C = { -20.0f, 40.0f, 175.0f }; +static Vec3f sSwampPlayerPos = { 0.0f, 10.0f, 140.0f }; +static Vec3f sTownFierceDietyPlayerPos = { -20.0f, 20.0f, 198.0f }; +static Vec3f sTownPlayerPos = { -20.0f, 40.0f, 175.0f }; -void func_809C64C0(EnSyatekiMan* this, PlayState* play2, EnSyatekiManUnkStruct arg2[], s32 arg3) { +/** + * Spawns all the actors used as targets in the Swamp Shooting Gallery. + */ +void EnSyatekiMan_Swamp_SpawnTargetActors(EnSyatekiMan* this, PlayState* play2, SwampTargetActorEntry actorList[], + s32 actorListLength) { PlayState* play = play2; s32 i; - for (i = 0; i < arg3; i++) { - Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, arg2[i].index, arg2[i].x, arg2[i].y, arg2[i].z, 0, 0, 0, - arg2[i].variable); + for (i = 0; i < actorListLength; i++) { + Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, actorList[i].actorId, actorList[i].pos.x, + actorList[i].pos.y, actorList[i].pos.z, 0, 0, 0, actorList[i].params); } } void EnSyatekiMan_Init(Actor* thisx, PlayState* play) { EnSyatekiMan* this = THIS; s32 pad; - Path* sp34 = &play->setupPathList[ENSYATEKIMAN_GET_FF00(&this->actor)]; - s32 sp30 = D_809C946C[this->unk_194]; + Path* path = &play->setupPathList[EN_SYATEKI_MAN_GET_PATH(&this->actor)]; + s32 actorListLength = sSwampTargetActorListLengths[this->swampTargetActorListIndex]; this->actor.targetMode = 1; Actor_SetScale(&this->actor, 0.01f); @@ -139,26 +188,27 @@ void EnSyatekiMan_Init(Actor* thisx, PlayState* play) { } this->actor.colChkInfo.cylRadius = 100; - this->actionFunc = func_809C6810; - this->unk_26A = 0; - this->unk_270 = 15; - this->unk_27E = 0; - this->unk_26E = 0; - this->unk_190 = 0; - this->unk_272 = 0; - this->unk_274 = 0; - this->unk_280 = 0; - this->unk_278 = 0; - this->unk_27A = 0; - this->unk_284 = 0; - this->unk_194 = 0; - this->unk_282 = 0; + this->actionFunc = EnSyatekiMan_SetupIdle; + this->shootingGameState = SG_GAME_STATE_NONE; + this->talkWaitTimer = 15; + this->flagsIndex = 0; + this->perGameVar2.octorokHitType = SG_OCTO_HIT_TYPE_NONE; + this->octorokFlags = 0; + this->dekuScrubFlags = 0; + this->guayFlags = 0; + this->score = 0; + this->dekuScrubHitCounter = 0; + this->guayHitCounter = 0; + this->prevTextId = 0; + this->swampTargetActorListIndex = 0; + this->talkFlags = TALK_FLAG_NONE; this->eyeIndex = 0; this->blinkTimer = 0; if (play->sceneNum == SCENE_SYATEKI_MORI) { - this->path = sp34; - func_809C64C0(this, play, D_809C9464[this->unk_194], sp30); + this->path = path; + EnSyatekiMan_Swamp_SpawnTargetActors(this, play, sSwampTargetActorLists[this->swampTargetActorListIndex], + actorListLength); } } @@ -166,79 +216,88 @@ void EnSyatekiMan_Destroy(Actor* thisx, PlayState* play) { gSaveContext.save.weekEventReg[63] &= (u8)~1; } -s32 func_809C6720(PlayState* play, Vec3f arg1) { +/** + * Moves the player to the destination through automated control stick movements. + * This is used to move the player to the right place to play the shooting game. + */ +s32 EnSyatekiMan_MovePlayerToPos(PlayState* play, Vec3f pos) { Player* player = GET_PLAYER(play); - f32 sp28; - f32 phi_f0; - s16 sp22 = Math_Vec3f_Yaw(&player->actor.world.pos, &arg1); + f32 distXZ; + f32 magnitude; + s16 yaw = Math_Vec3f_Yaw(&player->actor.world.pos, &pos); - sp28 = Math_Vec3f_DistXZ(&player->actor.world.pos, &arg1); + distXZ = Math_Vec3f_DistXZ(&player->actor.world.pos, &pos); - if (sp28 < 5.0f) { - phi_f0 = 10.0f; - } else if (sp28 < 30.0f) { - phi_f0 = 40.0f; + if (distXZ < 5.0f) { + magnitude = 10.0f; + } else if (distXZ < 30.0f) { + magnitude = 40.0f; } else { - phi_f0 = 80.0f; + magnitude = 80.0f; } play->actorCtx.unk268 = 1; - func_800B6F20(play, &play->actorCtx.unk_26C, phi_f0, sp22); + func_800B6F20(play, &play->actorCtx.unk_26C, magnitude, yaw); - if (sp28 < 5.0f) { + if (distXZ < 5.0f) { return true; } return false; } -void func_809C6810(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_SetupIdle(EnSyatekiMan* this, PlayState* play) { if (play->sceneNum == SCENE_SYATEKI_MORI) { - this->actionFunc = func_809C6848; + this->actionFunc = EnSyatekiMan_Swamp_Idle; } else if (play->sceneNum == SCENE_SYATEKI_MIZU) { - this->actionFunc = func_809C72D8; + this->actionFunc = EnSyatekiMan_Town_Idle; } } -void func_809C6848(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Swamp_Idle(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { - u16 sp22; + u16 faceReactionTextId; - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); - sp22 = Text_GetFaceReaction(play, 0x31); - if (sp22 != 0) { - Message_StartTextbox(play, sp22, &this->actor); - this->unk_284 = sp22; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_SYATEKI_MAN_ANIMATION_SWAMP_HEAD_SCRATCH_END); + faceReactionTextId = Text_GetFaceReaction(play, 0x31); + if (faceReactionTextId != 0) { + Message_StartTextbox(play, faceReactionTextId, &this->actor); + this->prevTextId = faceReactionTextId; } else if (player->transformation == PLAYER_FORM_HUMAN) { - if (this->unk_282 == 0) { - this->unk_282 = 1; + if (this->talkFlags == TALK_FLAG_NONE) { + this->talkFlags = TALK_FLAG_SWAMP_HAS_SPOKEN_WITH_HUMAN; + // How are you? Wanna play? Message_StartTextbox(play, 0xA28, &this->actor); - this->unk_284 = 0xA28; + this->prevTextId = 0xA28; } else { + // Won't you play? Message_StartTextbox(play, 0xA29, &this->actor); - this->unk_284 = 0xA29; + this->prevTextId = 0xA29; } } else { switch (CURRENT_DAY) { case 1: + // You can't play if you don't have a bow! (Day 1) Message_StartTextbox(play, 0xA38, &this->actor); - this->unk_284 = 0xA38; + this->prevTextId = 0xA38; break; case 2: + // You can't play if you don't have a bow! (Day 2) Message_StartTextbox(play, 0xA39, &this->actor); - this->unk_284 = 0xA39; + this->prevTextId = 0xA39; break; case 3: + // You can't play if you don't have a bow! (Day 3) Message_StartTextbox(play, 0xA3A, &this->actor); - this->unk_284 = 0xA3A; + this->prevTextId = 0xA3A; break; } } - this->actionFunc = func_809C6E30; + this->actionFunc = EnSyatekiMan_Swamp_Talk; } else { func_800B8614(&this->actor, play, 120.0f); } @@ -248,23 +307,28 @@ void func_809C6848(EnSyatekiMan* this, PlayState* play) { } } -void func_809C6A04(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Swamp_HandleChoice(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Message_ShouldAdvance(play)) { if (play->msgCtx.choiceIndex == 0) { - if (!CUR_UPG_VALUE(UPG_QUIVER)) { + if (CUR_UPG_VALUE(UPG_QUIVER) == 0) { play_sound(NA_SE_SY_ERROR); + + // You don't have a bow! Message_StartTextbox(play, 0xA30, &this->actor); - this->unk_284 = 0xA30; + this->prevTextId = 0xA30; } else if (gSaveContext.save.playerData.rupees < 20) { play_sound(NA_SE_SY_ERROR); + + // You don't have enough rupees! Message_StartTextbox(play, 0xA31, &this->actor); - this->unk_284 = 0xA31; - if (this->unk_26A == 4) { + this->prevTextId = 0xA31; + if (this->shootingGameState == SG_GAME_STATE_ONE_MORE_GAME) { gSaveContext.minigameState = 3; } - this->unk_26A = 3; + + this->shootingGameState = SG_GAME_STATE_NOT_PLAYING; } else { func_8019F208(); Rupees_ChangeBy(-20); @@ -272,99 +336,105 @@ void func_809C6A04(EnSyatekiMan* this, PlayState* play) { gSaveContext.save.weekEventReg[63] &= (u8)~2; play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; - this->unk_26A = 7; + this->shootingGameState = SG_GAME_STATE_MOVING_PLAYER; player->stateFlags1 |= 0x20; - this->actionFunc = func_809C7FFC; + this->actionFunc = EnSyatekiMan_Swamp_MovePlayerAndExplainRules; } } else { func_8019F230(); switch (CURRENT_DAY) { case 1: + // You're not playing? Please come again. Message_StartTextbox(play, 0xA2D, &this->actor); - this->unk_284 = 0xA2D; + this->prevTextId = 0xA2D; break; case 2: + // You're not playing? Day after tomorrow is the carnival. Message_StartTextbox(play, 0xA2E, &this->actor); - this->unk_284 = 0xA2E; + this->prevTextId = 0xA2E; break; case 3: + // You're not playing? Is something happening outside? Message_StartTextbox(play, 0xA2F, &this->actor); - this->unk_284 = 0xA2F; + this->prevTextId = 0xA2F; break; } - if (this->unk_26A == 4) { + if (this->shootingGameState == SG_GAME_STATE_ONE_MORE_GAME) { gSaveContext.minigameState = 3; } - this->unk_26A = 3; + this->shootingGameState = SG_GAME_STATE_NOT_PLAYING; } } } -void func_809C6C2C(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Swamp_HandleNormalMessage(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Message_ShouldAdvance(play)) { - switch (this->unk_284) { - case 0xA28: - case 0xA29: + switch (this->prevTextId) { + case 0xA28: // How are you? Wanna play? + case 0xA29: // Won't you play? + // It costs 20 rupees to play. Message_StartTextbox(play, 0xA2A, &this->actor); - this->unk_284 = 0xA2A; + this->prevTextId = 0xA2A; break; - case 0xA2B: - case 0xA2C: - case 0xA35: + case 0xA2B: // The rules of the game are a piece of cake! + case 0xA2C: // I keep saying - you have to aim with [Control Stick]! + case 0xA35: // You almost had it! Well...just this once...here you go! play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; player->actor.freezeTimer = 0; func_80112AFC(play); play->interfaceCtx.hbaAmmo = 80; func_80123F2C(play, 80); - this->unk_26A = 1; - this->actionFunc = func_809C80C0; + this->shootingGameState = SG_GAME_STATE_RUNNING; + this->actionFunc = EnSyatekiMan_Swamp_StartGame; func_801A2BB8(NA_BGM_MINI_GAME_2); break; - case 0xA32: + case 0xA32: // You have to try harder! if (gSaveContext.save.weekEventReg[63] & 2) { func_801477B4(play); player->stateFlags1 &= ~0x20; gSaveContext.save.weekEventReg[63] &= (u8)~1; gSaveContext.save.weekEventReg[63] &= (u8)~2; - this->actionFunc = func_809C6848; + this->actionFunc = EnSyatekiMan_Swamp_Idle; gSaveContext.minigameState = 3; - this->unk_26A = 0; + this->shootingGameState = SG_GAME_STATE_NONE; } else { + // Wanna play again? Message_StartTextbox(play, 0xA33, &this->actor); - this->unk_284 = 0xA33; + this->prevTextId = 0xA33; } break; - case 0xA33: + case 0xA33: // Wanna play again? + // It costs 20 rupees to play. Message_StartTextbox(play, 0xA2A, &this->actor); - this->unk_284 = 0xA2A; - this->unk_26A = 4; + this->prevTextId = 0xA2A; + this->shootingGameState = SG_GAME_STATE_ONE_MORE_GAME; break; - case 0xA34: + case 0xA34: // Perfect! Take this! play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; player->actor.freezeTimer = 0; gSaveContext.minigameState = 3; player->stateFlags1 |= 0x20; - this->actionFunc = func_809C7A90; - func_809C7A90(this, play); + this->actionFunc = EnSyatekiMan_Swamp_SetupGiveReward; + EnSyatekiMan_Swamp_SetupGiveReward(this, play); break; } } } -void func_809C6E30(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Swamp_Talk(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (player->stateFlags1 & 0x20) { @@ -373,16 +443,16 @@ void func_809C6E30(EnSyatekiMan* this, PlayState* play) { switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_CLOSING: - this->actionFunc = func_809C6848; - this->unk_26A = 0; + this->actionFunc = EnSyatekiMan_Swamp_Idle; + this->shootingGameState = SG_GAME_STATE_NONE; break; case TEXT_STATE_CHOICE: - func_809C6A04(this, play); + EnSyatekiMan_Swamp_HandleChoice(this, play); break; case TEXT_STATE_5: - func_809C6C2C(this, play); + EnSyatekiMan_Swamp_HandleNormalMessage(this, play); break; case TEXT_STATE_DONE: @@ -392,8 +462,8 @@ void func_809C6E30(EnSyatekiMan* this, PlayState* play) { player->stateFlags1 &= ~0x20; gSaveContext.save.weekEventReg[63] &= (u8)~1; gSaveContext.save.weekEventReg[63] &= (u8)~2; - this->actionFunc = func_809C6848; - this->unk_26A = 0; + this->actionFunc = EnSyatekiMan_Swamp_Idle; + this->shootingGameState = SG_GAME_STATE_NONE; } break; @@ -409,296 +479,335 @@ void func_809C6E30(EnSyatekiMan* this, PlayState* play) { if (this->skelAnime.animation == &gSwampShootingGalleryManHeadScratchEndAnim) { if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_SYATEKI_MAN_ANIMATION_HANDS_ON_TABLE); } } } -void func_809C6F98(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Town_StartIntroTextbox(EnSyatekiMan* this, PlayState* play) { switch (gSaveContext.save.playerForm) { case PLAYER_FORM_HUMAN: Flags_SetAllTreasure(play, Flags_GetAllTreasure(play) + 1); if (CURRENT_DAY != 3) { - if (!(this->unk_282 & 1)) { - this->unk_282 |= 1; + if (!(this->talkFlags & TALK_FLAG_TOWN_HAS_SPOKEN_WITH_HUMAN)) { + this->talkFlags |= TALK_FLAG_TOWN_HAS_SPOKEN_WITH_HUMAN; + // Why don't you give it a try? Message_StartTextbox(play, 0x3E8, &this->actor); - this->unk_284 = 0x3E8; + this->prevTextId = 0x3E8; } else { + // Wanna try? Message_StartTextbox(play, 0x3E9, &this->actor); - this->unk_284 = 0x3E9; + this->prevTextId = 0x3E9; } - } else if (!(this->unk_282 & 1)) { - this->unk_282 |= 1; + } else if (!(this->talkFlags & TALK_FLAG_TOWN_HAS_SPOKEN_WITH_HUMAN)) { + this->talkFlags |= TALK_FLAG_TOWN_HAS_SPOKEN_WITH_HUMAN; + // If you still have time, why don't you try it? Message_StartTextbox(play, 0x3EA, &this->actor); - this->unk_284 = 0x3EA; + this->prevTextId = 0x3EA; } else { + // How about it? Wanna try? Message_StartTextbox(play, 0x3EB, &this->actor); - this->unk_284 = 0x3EB; + this->prevTextId = 0x3EB; } break; case PLAYER_FORM_DEKU: if (CURRENT_DAY != 3) { - if (!(this->unk_282 & 2)) { - this->unk_282 |= 2; + if (!(this->talkFlags & TALK_FLAG_TOWN_HAS_SPOKEN_WITH_DEKU)) { + this->talkFlags |= TALK_FLAG_TOWN_HAS_SPOKEN_WITH_DEKU; + // When I saw your fairy, I thought you were that masked troublemaker. Message_StartTextbox(play, 0x3EC, &this->actor); - this->unk_284 = 0x3EC; + this->prevTextId = 0x3EC; } else { + // You can't play because you don't have a bow. Message_StartTextbox(play, 0x3ED, &this->actor); - this->unk_284 = 0x3ED; + this->prevTextId = 0x3ED; } - } else if (!(this->unk_282 & 2)) { - this->unk_282 |= 2; + } else if (!(this->talkFlags & TALK_FLAG_TOWN_HAS_SPOKEN_WITH_DEKU)) { + this->talkFlags |= TALK_FLAG_TOWN_HAS_SPOKEN_WITH_DEKU; + // I thought you were a customer, but I guess I can't expect any... Message_StartTextbox(play, 0x3EE, &this->actor); - this->unk_284 = 0x3EE; + this->prevTextId = 0x3EE; } else { + // Stop hanging around and go home! Message_StartTextbox(play, 0x3EF, &this->actor); - this->unk_284 = 0x3EF; + this->prevTextId = 0x3EF; } break; case PLAYER_FORM_ZORA: if (CURRENT_DAY != 3) { - if (!(this->unk_282 & 8)) { - this->unk_282 |= 8; + if (!(this->talkFlags & TALK_FLAG_TOWN_HAS_SPOKEN_WITH_ZORA)) { + this->talkFlags |= TALK_FLAG_TOWN_HAS_SPOKEN_WITH_ZORA; + // I swear I've seen you before... Message_StartTextbox(play, 0x3F0, &this->actor); - this->unk_284 = 0x3F0; + this->prevTextId = 0x3F0; } else { + // If you don't have a bow, you can't play. Message_StartTextbox(play, 0x3F1, &this->actor); - this->unk_284 = 0x3F1; + this->prevTextId = 0x3F1; } - } else if (!(this->unk_282 & 8)) { - this->unk_282 |= 8; + } else if (!(this->talkFlags & TALK_FLAG_TOWN_HAS_SPOKEN_WITH_ZORA)) { + this->talkFlags |= TALK_FLAG_TOWN_HAS_SPOKEN_WITH_ZORA; + // Huh? You're still here? Message_StartTextbox(play, 0x3F4, &this->actor); - this->unk_284 = 0x3F4; + this->prevTextId = 0x3F4; } else { + // Haven't you heard the news? Message_StartTextbox(play, 0x3F5, &this->actor); - this->unk_284 = 0x3F5; + this->prevTextId = 0x3F5; } break; case PLAYER_FORM_GORON: if (CURRENT_DAY != 3) { - if (!(this->unk_282 & 4)) { - this->unk_282 |= 4; + if (!(this->talkFlags & TALK_FLAG_TOWN_HAS_SPOKEN_WITH_GORON)) { + this->talkFlags |= TALK_FLAG_TOWN_HAS_SPOKEN_WITH_GORON; + // You have quite the build! Message_StartTextbox(play, 0x3F2, &this->actor); - this->unk_284 = 0x3F2; + this->prevTextId = 0x3F2; } else { + // Sorry...you don't have a bow. Message_StartTextbox(play, 0x3F3, &this->actor); - this->unk_284 = 0x3F3; + this->prevTextId = 0x3F3; } - } else if (!(this->unk_282 & 4)) { - this->unk_282 |= 4; + } else if (!(this->talkFlags & TALK_FLAG_TOWN_HAS_SPOKEN_WITH_GORON)) { + this->talkFlags |= TALK_FLAG_TOWN_HAS_SPOKEN_WITH_GORON; + // Huh? You're still here? Message_StartTextbox(play, 0x3F4, &this->actor); - this->unk_284 = 0x3F4; + this->prevTextId = 0x3F4; } else { + // Haven't you heard the news? Message_StartTextbox(play, 0x3F5, &this->actor); - this->unk_284 = 0x3F5; + this->prevTextId = 0x3F5; } break; } } -void func_809C72D8(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Town_Idle(EnSyatekiMan* this, PlayState* play) { if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { - u16 sp26 = Text_GetFaceReaction(play, 0x30); + u16 faceReactionTextId = Text_GetFaceReaction(play, 0x30); - if (sp26 != 0) { - Message_StartTextbox(play, sp26, &this->actor); - this->unk_284 = sp26; + if (faceReactionTextId != 0) { + Message_StartTextbox(play, faceReactionTextId, &this->actor); + this->prevTextId = faceReactionTextId; } else { - func_809C6F98(this, play); + EnSyatekiMan_Town_StartIntroTextbox(this, play); } - this->actionFunc = func_809C7990; + + this->actionFunc = EnSyatekiMan_Town_Talk; } else { func_800B8614(&this->actor, play, 120.0f); } } -void func_809C7380(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Town_HandleChoice(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Message_ShouldAdvance(play)) { if (play->msgCtx.choiceIndex == 0) { - if (!CUR_UPG_VALUE(UPG_QUIVER)) { + if (CUR_UPG_VALUE(UPG_QUIVER) == 0) { play_sound(NA_SE_SY_ERROR); if (CURRENT_DAY != 3) { + // You don't have a bow? Then you can't play. Message_StartTextbox(play, 0x3F9, &this->actor); - this->unk_284 = 0x3F9; + this->prevTextId = 0x3F9; } else { + // You don't have a bow? That's too bad. Message_StartTextbox(play, 0x3FA, &this->actor); - this->unk_284 = 0x3FA; + this->prevTextId = 0x3FA; } } else if (gSaveContext.save.playerData.rupees < 20) { play_sound(NA_SE_SY_ERROR); if (CURRENT_DAY != 3) { + // You don't have a enough rupees! Message_StartTextbox(play, 0x3FB, &this->actor); - this->unk_284 = 0x3FB; + this->prevTextId = 0x3FB; } else { + // You don't have enough rupees? That's too bad. Message_StartTextbox(play, 0x3FC, &this->actor); - this->unk_284 = 0x3FC; + this->prevTextId = 0x3FC; } - if (this->unk_26A == 4) { + if (this->shootingGameState == SG_GAME_STATE_ONE_MORE_GAME) { player->stateFlags3 &= ~0x400; gSaveContext.minigameState = 3; } - this->unk_26A = 3; + + this->shootingGameState = SG_GAME_STATE_NOT_PLAYING; } else { func_8019F208(); Rupees_ChangeBy(-20); - this->unk_26A = 2; - if (!(this->unk_282 & 0x10)) { - this->unk_282 |= 0x10; + this->shootingGameState = SG_GAME_STATE_EXPLAINING_RULES; + if (!(this->talkFlags & TALK_FLAG_TOWN_HAS_EXPLAINED_THE_RULES)) { + this->talkFlags |= TALK_FLAG_TOWN_HAS_EXPLAINED_THE_RULES; + // The rules are simple. Message_StartTextbox(play, 0x3FD, &this->actor); - this->unk_284 = 0x3FD; + this->prevTextId = 0x3FD; } else { + // Aim for the red ones. Message_StartTextbox(play, 0x3FF, &this->actor); - this->unk_284 = 0x3FF; + this->prevTextId = 0x3FF; } + gSaveContext.save.weekEventReg[63] |= 1; gSaveContext.save.weekEventReg[63] &= (u8)~2; } } else { func_8019F230(); if (CURRENT_DAY != 3) { + // Well, be that way! Message_StartTextbox(play, 0x3F7, &this->actor); - this->unk_284 = 0x3F7; + this->prevTextId = 0x3F7; } else { + // Usually this place is packed... Message_StartTextbox(play, 0x3F8, &this->actor); - this->unk_284 = 0x3F8; + this->prevTextId = 0x3F8; } - if (this->unk_26A == 4) { + if (this->shootingGameState == SG_GAME_STATE_ONE_MORE_GAME) { player->stateFlags3 &= ~0x400; gSaveContext.minigameState = 3; } - this->unk_26A = 3; + + this->shootingGameState = SG_GAME_STATE_NOT_PLAYING; } } } -void func_809C7620(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Town_HandleNormalMessage(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Message_ShouldAdvance(play)) { - switch (this->unk_284) { - case 0x3E8: - case 0x3E9: - case 0x3EA: - case 0x3EB: + switch (this->prevTextId) { + case 0x3E8: // Why don't you give it a try? + case 0x3E9: // Wanna try? + case 0x3EA: // If you still have time, why don't you try it? + case 0x3EB: // How about it? Wanna try? + // One game is 20 rupees. Message_StartTextbox(play, 0x3F6, &this->actor); - this->unk_284 = 0x3F6; + this->prevTextId = 0x3F6; break; - case 0x3EC: + case 0x3EC: // When I saw your fairy, I thought you were that masked troublemaker. + // You can't play because you don't have a bow. Message_StartTextbox(play, 0x3ED, &this->actor); - this->unk_284 = 0x3ED; + this->prevTextId = 0x3ED; break; - case 0x3EE: + case 0x3EE: // I thought you were a customer, but I guess I can't expect any... + // Stop hanging around and go home! Message_StartTextbox(play, 0x3EF, &this->actor); - this->unk_284 = 0x3EF; + this->prevTextId = 0x3EF; break; - case 0x3F0: + case 0x3F0: // I swear I've seen you before... + // If you don't have a bow, you can't play. Message_StartTextbox(play, 0x3F1, &this->actor); - this->unk_284 = 0x3F1; + this->prevTextId = 0x3F1; break; - case 0x3F2: + case 0x3F2: // You have quite the build! + // Sorry...you don't have a bow. Message_StartTextbox(play, 0x3F3, &this->actor); - this->unk_284 = 0x3F3; + this->prevTextId = 0x3F3; break; - case 0x3F4: + case 0x3F4: // Huh? You're still here? + // Haven't you heard the news? Message_StartTextbox(play, 0x3F5, &this->actor); - this->unk_284 = 0x3F5; + this->prevTextId = 0x3F5; break; - case 0x3FD: - case 0x3FF: - if (this->unk_26A == 4) { - if (this->unk_284 == 0x3FD) { + case 0x3FD: // The rules are simple. + case 0x3FF: // Aim for the red ones. + if (this->shootingGameState == SG_GAME_STATE_ONE_MORE_GAME) { + if (this->prevTextId == 0x3FD) { + // Our highest score is [score]. If you break the record, you'll win a prize! Message_StartTextbox(play, 0x3FE, &this->actor); - this->unk_284 = 0x3FE; + this->prevTextId = 0x3FE; } else { + // Our highest score is [score]. Good luck! Message_StartTextbox(play, 0x400, &this->actor); - this->unk_284 = 0x400; + this->prevTextId = 0x400; } } else { play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; player->actor.freezeTimer = 0; - this->unk_26A = 7; + this->shootingGameState = SG_GAME_STATE_MOVING_PLAYER; player->stateFlags1 |= 0x20; gSaveContext.save.weekEventReg[63] |= 1; gSaveContext.save.weekEventReg[63] &= (u8)~2; - this->actionFunc = func_809C8710; + this->actionFunc = EnSyatekiMan_Town_MovePlayerAndSayHighScore; } break; - case 0x3FE: - case 0x400: + case 0x3FE: // Our highest score is [score]. If you break the record, you'll win a prize! + case 0x400: // Our highest score is [score]. Good luck! play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; player->actor.freezeTimer = 0; - this->unk_27E = 0; + this->flagsIndex = 0; func_80112AFC(play); func_80123F2C(play, 0x63); - this->unk_26A = 1; + this->shootingGameState = SG_GAME_STATE_RUNNING; func_801A2BB8(NA_BGM_MINI_GAME_2); - this->actionFunc = func_809C8808; + this->actionFunc = EnSyatekiMan_Town_StartGame; break; - case 0x401: + case 0x401: // You got [score]? Oh, that's too bad... if (gSaveContext.save.weekEventReg[63] & 2) { func_801477B4(play); gSaveContext.save.weekEventReg[63] &= (u8)~1; gSaveContext.save.weekEventReg[63] &= (u8)~2; - this->unk_26A = 0; - this->actionFunc = func_809C72D8; + this->shootingGameState = SG_GAME_STATE_NONE; + this->actionFunc = EnSyatekiMan_Town_Idle; } else { + // You can't stop, can you? You can play as long as you have rupees. Message_StartTextbox(play, 0x402, &this->actor); - this->unk_284 = 0x402; + this->prevTextId = 0x402; } break; - case 0x403: + case 0x403: // You got [score]? Too bad... if (gSaveContext.save.weekEventReg[63] & 2) { func_801477B4(play); gSaveContext.save.weekEventReg[63] &= (u8)~1; gSaveContext.save.weekEventReg[63] &= (u8)~2; - this->unk_26A = 0; - this->actionFunc = func_809C72D8; + this->shootingGameState = SG_GAME_STATE_NONE; + this->actionFunc = EnSyatekiMan_Town_Idle; } else { + // Frustrating, right? Wanna try again? Message_StartTextbox(play, 0x404, &this->actor); - this->unk_284 = 0x404; + this->prevTextId = 0x404; } break; - case 0x402: - case 0x404: + case 0x402: // You can't stop, can you? You can play as long as you have rupees. + case 0x404: // Frustrating, right? Wanna try again? + // One game is 20 rupees. Message_StartTextbox(play, 0x3F6, &this->actor); - this->unk_284 = 0x3F6; - this->unk_26A = 4; + this->prevTextId = 0x3F6; + this->shootingGameState = SG_GAME_STATE_ONE_MORE_GAME; break; - case 0x405: - case 0x406: - case 0x407: + case 0x405: // No way! That was perfect! + case 0x406: // That was perfect! + case 0x407: // You got a new record! play->msgCtx.msgMode = 0x43; play->msgCtx.stateTimer = 4; player->actor.freezeTimer = 0; gSaveContext.minigameState = 3; - this->actionFunc = func_809C7D14; - func_809C7D14(this, play); + this->actionFunc = EnSyatekiMan_Town_SetupGiveReward; + EnSyatekiMan_Town_SetupGiveReward(this, play); break; } } } -void func_809C7990(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Town_Talk(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (player->stateFlags1 & 0x20) { @@ -707,16 +816,16 @@ void func_809C7990(EnSyatekiMan* this, PlayState* play) { switch (Message_GetState(&play->msgCtx)) { case TEXT_STATE_CLOSING: - this->actionFunc = func_809C72D8; - this->unk_26A = 0; + this->actionFunc = EnSyatekiMan_Town_Idle; + this->shootingGameState = SG_GAME_STATE_NONE; break; case TEXT_STATE_CHOICE: - func_809C7380(this, play); + EnSyatekiMan_Town_HandleChoice(this, play); break; case TEXT_STATE_5: - func_809C7620(this, play); + EnSyatekiMan_Town_HandleNormalMessage(this, play); break; case TEXT_STATE_DONE: @@ -724,8 +833,8 @@ void func_809C7990(EnSyatekiMan* this, PlayState* play) { gSaveContext.save.weekEventReg[63] &= (u8)~1; gSaveContext.save.weekEventReg[63] &= (u8)~2; player->stateFlags1 &= ~0x20; - this->actionFunc = func_809C72D8; - this->unk_26A = 0; + this->actionFunc = EnSyatekiMan_Town_Idle; + this->shootingGameState = SG_GAME_STATE_NONE; } break; @@ -740,21 +849,22 @@ void func_809C7990(EnSyatekiMan* this, PlayState* play) { } } -void func_809C7A90(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Swamp_SetupGiveReward(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Actor_HasParent(&this->actor, play)) { if (!(gSaveContext.save.weekEventReg[59] & 0x10)) { gSaveContext.save.weekEventReg[59] |= 0x10; - } else if (!(gSaveContext.save.weekEventReg[32] & 2) && (this->unk_280 >= 0x884)) { + } else if (!(gSaveContext.save.weekEventReg[32] & 2) && (this->score >= 2180)) { gSaveContext.save.weekEventReg[32] |= 2; } + this->actor.parent = NULL; - this->actionFunc = func_809C7C14; + this->actionFunc = EnSyatekiMan_Swamp_GiveReward; } else { if ((CUR_UPG_VALUE(UPG_QUIVER) < 3) && !(gSaveContext.save.weekEventReg[59] & 0x10)) { Actor_PickUp(&this->actor, play, GI_QUIVER_30 + CUR_UPG_VALUE(UPG_QUIVER), 500.0f, 100.0f); - } else if (this->unk_280 < 0x884) { + } else if (this->score < 2180) { Actor_PickUp(&this->actor, play, GI_RUPEE_RED, 500.0f, 100.0f); } else if (!(gSaveContext.save.weekEventReg[32] & 2)) { Actor_PickUp(&this->actor, play, GI_HEART_PIECE, 500.0f, 100.0f); @@ -769,46 +879,50 @@ void func_809C7A90(EnSyatekiMan* this, PlayState* play) { } } -void func_809C7C14(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Swamp_GiveReward(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { if ((CURRENT_DAY == 3) && (gSaveContext.save.time > CLOCK_TIME(12, 0))) { + // We've been having a lot of earthquakes lately. Message_StartTextbox(play, 0xA36, &this->actor); - this->unk_284 = 0xA36; + this->prevTextId = 0xA36; } else { + // Tell your friends about us. Message_StartTextbox(play, 0xA37, &this->actor); - this->unk_284 = 0xA37; + this->prevTextId = 0xA37; } + player->stateFlags1 &= ~0x20; this->actor.flags &= ~ACTOR_FLAG_10000; - this->unk_280 = 0; - this->unk_26A = 0; - this->actionFunc = func_809C6E30; + this->score = 0; + this->shootingGameState = SG_GAME_STATE_NONE; + this->actionFunc = EnSyatekiMan_Swamp_Talk; } else { func_800B85E0(&this->actor, play, 500.0f, EXCH_ITEM_MINUS1); } } -void func_809C7D14(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Town_SetupGiveReward(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (Actor_HasParent(&this->actor, play)) { - if (this->unk_284 == 0x407) { + if (this->prevTextId == 0x407) { if (!(gSaveContext.save.weekEventReg[59] & 0x20)) { gSaveContext.save.weekEventReg[59] |= 0x20; } } - if ((this->unk_284 == 0x405) || (this->unk_284 == 0x406)) { + if ((this->prevTextId == 0x405) || (this->prevTextId == 0x406)) { if (!(gSaveContext.save.weekEventReg[32] & 4)) { gSaveContext.save.weekEventReg[32] |= 4; } } + this->actor.parent = NULL; - this->actionFunc = func_809C7EB4; + this->actionFunc = EnSyatekiMan_Town_GiveReward; } else { - if (this->unk_284 == 0x407) { + if (this->prevTextId == 0x407) { if ((CUR_UPG_VALUE(UPG_QUIVER) < 3) && !(gSaveContext.save.weekEventReg[59] & 0x20)) { Actor_PickUp(&this->actor, play, GI_QUIVER_30 + CUR_UPG_VALUE(UPG_QUIVER), 500.0f, 100.0f); } else { @@ -827,191 +941,209 @@ void func_809C7D14(EnSyatekiMan* this, PlayState* play) { } } -void func_809C7EB4(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Town_GiveReward(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); if (CURRENT_DAY != 3) { if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) { player->stateFlags1 &= ~0x20; - this->unk_280 = 0; - this->unk_26A = 0; + this->score = 0; + this->shootingGameState = SG_GAME_STATE_NONE; gSaveContext.save.weekEventReg[63] &= (u8)~1; gSaveContext.save.weekEventReg[63] &= (u8)~2; - this->actionFunc = func_809C6810; + this->actionFunc = EnSyatekiMan_SetupIdle; } } else if (Actor_ProcessTalkRequest(&this->actor, &play->state)) { + // This may be our last day in business... Message_StartTextbox(play, 0x408, &this->actor); - this->unk_284 = 0x408; + this->prevTextId = 0x408; player->stateFlags1 &= ~0x20; this->actor.flags &= ~ACTOR_FLAG_10000; - this->unk_280 = 0; - this->unk_26A = 0; - this->actionFunc = func_809C7990; + this->score = 0; + this->shootingGameState = SG_GAME_STATE_NONE; + this->actionFunc = EnSyatekiMan_Town_Talk; } else { func_800B85E0(&this->actor, play, 500.0f, EXCH_ITEM_MINUS1); } } -void func_809C7FFC(EnSyatekiMan* this, PlayState* play) { +void EnSyatekiMan_Swamp_MovePlayerAndExplainRules(EnSyatekiMan* this, PlayState* play) { Player* player = GET_PLAYER(play); - if (func_809C6720(play, D_809C9474)) { + if (EnSyatekiMan_MovePlayerToPos(play, sSwampPlayerPos)) { player->stateFlags1 |= 0x20; - this->unk_26A = 2; - if (this->unk_282 != 2) { - this->unk_282 = 2; + this->shootingGameState = SG_GAME_STATE_EXPLAINING_RULES; + if (this->talkFlags != TALK_FLAG_SWAMP_HAS_EXPLAINED_THE_RULES) { + this->talkFlags = TALK_FLAG_SWAMP_HAS_EXPLAINED_THE_RULES; + // The rules of the game are a piece of cake! Message_StartTextbox(play, 0xA2B, &this->actor); - this->unk_284 = 0xA2B; + this->prevTextId = 0xA2B; } else { + // I keep saying - you have to aim with [Control Stick]! Message_StartTextbox(play, 0xA2C, &this->actor); - this->unk_284 = 0xA2C; + this->prevTextId = 0xA2C; } - this->actionFunc = func_809C6E30; + + this->actionFunc = EnSyatekiMan_Swamp_Talk; } } -void func_809C80C0(EnSyatekiMan* this, PlayState* play) { - static s16 D_809C9498 = 30; +void EnSyatekiMan_Swamp_StartGame(EnSyatekiMan* this, PlayState* play) { + static s16 sGameStartTimer = 30; Player* player = GET_PLAYER(play); - if (D_809C9498 > 0) { - player->actor.world.pos = D_809C9474; + if (sGameStartTimer > 0) { + player->actor.world.pos = sSwampPlayerPos; player->actor.shape.rot.y = -0x8000; player->actor.world.rot.y = player->actor.shape.rot.y; play->unk_18790(play, -0x8000, &this->actor); - D_809C9498--; + sGameStartTimer--; } else { - D_809C9498 = 30; - this->unk_27E = 0; - this->unk_280 = 0; + sGameStartTimer = 30; + this->flagsIndex = 0; + this->score = 0; player->stateFlags1 &= ~0x20; Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_FOUND); - this->unk_272 = 0x1F; - this->unk_274 = 0; - this->unk_276 = 0; - this->unk_26C = 0; - this->unk_278 = 0; - this->unk_27A = 0; - this->unk_27C = 0; - this->unk_26E = 0; + this->dekuScrubFlags = (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0); + this->guayFlags = 0; + this->wolfosFlags = 0; + this->perGameVar1.guaySpawnTimer = 0; + this->dekuScrubHitCounter = 0; + this->guayHitCounter = 0; + this->currentWave = 0; + this->perGameVar2.bonusDekuScrubHitCounter = 0; func_8010E9F0(1, 100); this->actor.draw = NULL; - this->actionFunc = func_809C81D0; + this->actionFunc = EnSyatekiMan_Swamp_RunGame; } } -void func_809C81D0(EnSyatekiMan* this, PlayState* play) { - static s16 D_809C949C = 0; +void EnSyatekiMan_Swamp_RunGame(EnSyatekiMan* this, PlayState* play) { + static s16 sHasSpawnedGuaysForThisWave = false; Player* player = GET_PLAYER(play); - if (((this->unk_272 == 0) || (this->unk_26C > 140)) && (D_809C949C == 0) && (this->unk_27C < 4)) { - D_809C949C = 1; - this->unk_26C = 0; + if (((this->dekuScrubFlags == 0) || (this->perGameVar1.guaySpawnTimer > 140)) && !sHasSpawnedGuaysForThisWave && + (this->currentWave < 4)) { + // Spawn three guays after the player has killed all Deku Scrubs, or after 140 frames. + sHasSpawnedGuaysForThisWave = true; + this->perGameVar1.guaySpawnTimer = 0; Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_FOUND); - this->unk_274 = D_809C91C8[this->unk_27E]; - if (this->unk_27E == 3) { - this->unk_27E = 0; + this->guayFlags = sGuayFlagsPerWave[this->flagsIndex]; + if (this->flagsIndex == 3) { + this->flagsIndex = 0; } else { - this->unk_27E++; + this->flagsIndex++; } - } else if ((this->unk_274 == 0) && (this->unk_272 == 0) && (D_809C949C == 1) && (this->unk_27C < 4)) { - if (this->unk_27A < 3) { - this->unk_27A = 0; + } else if ((this->guayFlags == 0) && (this->dekuScrubFlags == 0) && (sHasSpawnedGuaysForThisWave == true) && + (this->currentWave < 4)) { + // Once all Deku Scrubs and Guays in this wave have either disappeared or died, move on to the next wave. + if (this->guayHitCounter < 3) { + this->guayHitCounter = 0; } - this->unk_26C = 0; - D_809C949C = 0; - this->unk_27C++; - if (this->unk_27C < 4) { - this->unk_272 = 31; + + this->perGameVar1.guaySpawnTimer = 0; + sHasSpawnedGuaysForThisWave = false; + this->currentWave++; + if (this->currentWave < 4) { + this->dekuScrubFlags = (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0); } } - if (this->unk_27A == 3) { - this->unk_27A = 0; - this->unk_276 |= 1; + if (this->guayHitCounter == 3) { + this->guayHitCounter = 0; + this->wolfosFlags |= 1; } - if (this->unk_278 == 10) { - this->unk_278 = 0; - this->unk_276 |= 2; + if (this->dekuScrubHitCounter == 10) { + this->dekuScrubHitCounter = 0; + this->wolfosFlags |= 2; } - this->unk_26C++; + this->perGameVar1.guaySpawnTimer++; + if (gSaveContext.unk_3DE0[1] == 0) { gSaveContext.unk_3DE0[1] = 0; gSaveContext.unk_3DD0[1] = 5; this->actor.draw = EnSyatekiMan_Draw; - this->unk_27E = 0; - this->unk_27C = 0; + this->flagsIndex = 0; + this->currentWave = 0; player->stateFlags1 |= 0x20; - D_809C949C = 0; + sHasSpawnedGuaysForThisWave = false; func_801A2C20(); - this->actionFunc = func_809C8488; - } else if ((this->unk_27C == 4) && (this->unk_276 == 0) && (this->unk_26E == 2)) { + this->actionFunc = EnSyatekiMan_Swamp_EndGame; + } else if ((this->currentWave == 4) && (this->wolfosFlags == 0) && + (this->perGameVar2.bonusDekuScrubHitCounter == 2)) { this->actor.draw = EnSyatekiMan_Draw; - this->unk_27E = 0; - this->unk_27C = 0; + this->flagsIndex = 0; + this->currentWave = 0; player->stateFlags1 |= 0x20; - D_809C949C = 0; + sHasSpawnedGuaysForThisWave = false; func_801A2C20(); - this->unk_26A = 5; - if (this->unk_280 == 0x848) { + this->shootingGameState = SG_GAME_STATE_GIVING_BONUS; + if (this->score == 2120) { func_8011B4E0(play, 2); gSaveContext.unk_3DD0[1] = 6; - this->actionFunc = func_809C8610; + this->actionFunc = EnSyatekiMan_Swamp_AddBonusPoints; } else { gSaveContext.unk_3DD0[1] = 5; - this->actionFunc = func_809C8488; + this->actionFunc = EnSyatekiMan_Swamp_EndGame; } } } -void func_809C8488(EnSyatekiMan* this, PlayState* play) { - if ((this->unk_26A == 1) || (this->unk_26A == 5)) { - this->unk_190 = 0; - this->unk_272 = 0; - this->unk_274 = 0; - this->unk_276 = 0; - if (this->unk_270 <= 0) { - if ((s32)((gSaveContext.save.unk_EF4 & 0xFFFF0000) >> 0x10) < this->unk_280) { - gSaveContext.save.unk_EF4 = ((gSaveContext.save.unk_EF4) & 0xFFFF) | ((u16)this->unk_280 << 0x10); +void EnSyatekiMan_Swamp_EndGame(EnSyatekiMan* this, PlayState* play) { + if ((this->shootingGameState == SG_GAME_STATE_RUNNING) || (this->shootingGameState == SG_GAME_STATE_GIVING_BONUS)) { + this->octorokFlags = 0; + this->dekuScrubFlags = 0; + this->guayFlags = 0; + this->wolfosFlags = 0; + if (this->talkWaitTimer <= 0) { + if (GET_SWAMP_SHOOTING_GALLERY_HIGH_SCORE() < this->score) { + SET_SWAMP_SHOOTING_GALLERY_HIGH_SCORE(this->score); } - this->unk_270 = 15; - if (this->unk_280 >= 0x848) { + + this->talkWaitTimer = 15; + if (this->score >= 2120) { + // Perfect! Take this! Message_StartTextbox(play, 0xA34, &this->actor); - this->unk_284 = 0xA34; - this->unk_26A = 6; - } else if (this->unk_280 >= 0x7D0) { + this->prevTextId = 0xA34; + this->shootingGameState = SG_GAME_STATE_ENDED; + } else if (this->score >= 2000) { if (gSaveContext.save.weekEventReg[63] & 2) { gSaveContext.save.weekEventReg[63] &= (u8)~1; gSaveContext.save.weekEventReg[63] &= (u8)~2; - this->unk_26A = 0; + this->shootingGameState = SG_GAME_STATE_NONE; gSaveContext.minigameState = 3; - this->actionFunc = func_809C6848; + this->actionFunc = EnSyatekiMan_Swamp_Idle; return; } + + // You almost had it! Well...just this once...here you go! + // Setting prevTextId to this is what triggers a free replay in EnSyatekiMan_Swamp_HandleNormalMessage. Message_StartTextbox(play, 0xA35, &this->actor); - this->unk_284 = 0xA35; - this->unk_26A = 4; - this->unk_280 = 0; + this->prevTextId = 0xA35; + this->shootingGameState = SG_GAME_STATE_ONE_MORE_GAME; + this->score = 0; } else { + // You have to try harder! Message_StartTextbox(play, 0xA32, &this->actor); - this->unk_284 = 0xA32; - this->unk_26A = 6; + this->prevTextId = 0xA32; + this->shootingGameState = SG_GAME_STATE_ENDED; } - this->actionFunc = func_809C6E30; + + this->actionFunc = EnSyatekiMan_Swamp_Talk; } else { - this->unk_270--; + this->talkWaitTimer--; } } - if (this->unk_270 < 5) { + if (this->talkWaitTimer < 5) { play->unk_1887C = -10; } } -void func_809C8610(EnSyatekiMan* this, PlayState* play) { - static s32 D_809C94A0 = 0; +void EnSyatekiMan_Swamp_AddBonusPoints(EnSyatekiMan* this, PlayState* play) { + static s32 sBonusTimer = 0; Player* player = GET_PLAYER(play); player->stateFlags1 |= 0x20; @@ -1019,130 +1151,202 @@ void func_809C8610(EnSyatekiMan* this, PlayState* play) { if (gSaveContext.unk_3DE0[1] == 0) { gSaveContext.unk_3DE0[1] = 0; gSaveContext.unk_3DD0[1] = 5; - this->unk_27E = 0; - this->unk_27C = 0; - this->actionFunc = func_809C8488; - D_809C94A0 = 0; - } else if (D_809C94A0 > 10) { + this->flagsIndex = 0; + this->currentWave = 0; + this->actionFunc = EnSyatekiMan_Swamp_EndGame; + sBonusTimer = 0; + } else if (sBonusTimer > 10) { gSaveContext.unk_3E88[1] += 100; play->interfaceCtx.unk_25C += 10; - this->unk_280 += 10; + this->score += 10; Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); - D_809C94A0 = 0; + sBonusTimer = 0; } else { - D_809C94A0++; + sBonusTimer++; } } } -void func_809C8710(EnSyatekiMan* this, PlayState* play) { - Vec3f sp24; +void EnSyatekiMan_Town_MovePlayerAndSayHighScore(EnSyatekiMan* this, PlayState* play) { + Vec3f targetPlayerPos; if (gSaveContext.save.playerForm == PLAYER_FORM_FIERCE_DEITY) { - sp24 = D_809C9480; + targetPlayerPos = sTownFierceDietyPlayerPos; } else { - sp24 = D_809C948C; + targetPlayerPos = sTownPlayerPos; } - if (func_809C6720(play, sp24)) { - if (this->unk_284 == 0x3FD) { + if (EnSyatekiMan_MovePlayerToPos(play, targetPlayerPos)) { + if (this->prevTextId == 0x3FD) { + // Our highest score is [score]. If you break the record, you'll win a prize! Message_StartTextbox(play, 0x3FE, &this->actor); - this->unk_284 = 0x3FE; + this->prevTextId = 0x3FE; } else { + // Our highest score is [score]. Good luck! Message_StartTextbox(play, 0x400, &this->actor); - this->unk_284 = 0x400; + this->prevTextId = 0x400; } - this->unk_26A = 2; - this->actionFunc = func_809C7990; + + this->shootingGameState = SG_GAME_STATE_EXPLAINING_RULES; + this->actionFunc = EnSyatekiMan_Town_Talk; } } -void func_809C8808(EnSyatekiMan* this, PlayState* play) { - static s16 D_809C94A4 = 30; +void EnSyatekiMan_Town_StartGame(EnSyatekiMan* this, PlayState* play) { + static s16 sGameStartTimer = 30; Player* player = GET_PLAYER(play); - if (D_809C94A4 == 30) { + if (sGameStartTimer == 30) { if (player->transformation == PLAYER_FORM_FIERCE_DEITY) { - player->actor.world.pos = D_809C9480; + player->actor.world.pos = sTownFierceDietyPlayerPos; } else { - player->actor.world.pos = D_809C948C; + player->actor.world.pos = sTownPlayerPos; } + player->actor.prevPos = player->actor.world.pos; player->actor.shape.rot.y = -0x8000; player->actor.world.rot.y = player->actor.shape.rot.y; play->unk_18790(play, -0x8000, &this->actor); player->stateFlags1 |= 0x20; - D_809C94A4--; - } else if (D_809C94A4 > 0) { + sGameStartTimer--; + } else if (sGameStartTimer > 0) { player->actor.shape.rot.y = -0x8000; player->actor.world.rot.y = player->actor.shape.rot.y; - D_809C94A4--; - } else if (D_809C94A4 == 0) { + sGameStartTimer--; + } else if (sGameStartTimer == 0) { player->stateFlags1 &= ~0x20; - this->unk_280 = 0; - this->unk_27E = 0; - this->unk_26C = 70; - this->unk_26E = 0; - D_809C94A4 = 30; + this->score = 0; + this->flagsIndex = 0; + this->perGameVar1.octorokState = SG_OCTO_STATE_INITIAL; + this->perGameVar2.octorokHitType = SG_OCTO_HIT_TYPE_NONE; + sGameStartTimer = 30; func_8010E9F0(1, 75); this->actor.draw = NULL; - this->actionFunc = func_809C898C; + this->actionFunc = EnSyatekiMan_Town_RunGame; } } -void func_809C898C(EnSyatekiMan* this, PlayState* play) { - static const s32 D_809C94D0[] = { - 0x00000111, 0x00000650, 0x00010025, 0x00011011, 0x00000984, 0x00004050, 0x00010211, 0x00022015, - 0x00026984, 0x00012852, 0x00011999, 0x00022895, 0x0000056A, 0x0002A451, 0x00004115, - }; - static s32 D_809C94A8 = 0; +/** + * In the Town Shooting Gallery, there are fifteen waves of Octoroks. + * For each wave, these flags are used to control which Octoroks appear. + */ +static const s32 sOctorokFlagsPerWave[] = { + OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_CENTER) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_LEFT) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT), + + OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_BLUE, ROW_BACK, COLUMN_RIGHT) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_CENTER) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_LEFT) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_LEFT) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_CENTER), + + OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_CENTER) | OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_LEFT) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT), + + OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_LEFT) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_LEFT) | OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_RIGHT) | + OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_CENTER) | OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_LEFT) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_CENTER), + + OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_LEFT) | + OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_LEFT) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_BLUE, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_LEFT) | + OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_LEFT) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT) | + OCTOROK_FLAG(COLOR_BLUE, ROW_BACK, COLUMN_CENTER) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_LEFT) | + OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_BLUE, ROW_CENTER, COLUMN_LEFT) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_LEFT) | OCTOROK_FLAG(COLOR_BLUE, ROW_BACK, COLUMN_RIGHT) | + OCTOROK_FLAG(COLOR_BLUE, ROW_BACK, COLUMN_CENTER) | OCTOROK_FLAG(COLOR_BLUE, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_BLUE, ROW_FRONT, COLUMN_LEFT) | OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_RIGHT) | + OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_LEFT) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_LEFT), + + OCTOROK_FLAG(COLOR_RED, ROW_FRONT, COLUMN_CENTER) | OCTOROK_FLAG(COLOR_RED, ROW_CENTER, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_RIGHT) | OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_CENTER) | + OCTOROK_FLAG(COLOR_RED, ROW_BACK, COLUMN_LEFT), +}; + +void EnSyatekiMan_Town_RunGame(EnSyatekiMan* this, PlayState* play) { + static s32 sModFromLosingTime = 0; Player* player = GET_PLAYER(play); - s32 sp30 = (((void)0, gSaveContext.unk_3DE0[1]) * 0.1f) + 1.0f; + s32 timer = (((void)0, gSaveContext.unk_3DE0[1]) * 0.1f) + 1.0f; // unit is tenths of a second - if (sp30 < 0x2EF) { - s32 temp; + if (timer <= 750) { + s32 waveTimer; // unit is hundredths of a second - if (D_809C94A8 == 0) { - temp = ((void)0, gSaveContext.unk_3DE0[1]) % 500; + // If you hit a Blue Octorok, you lose 2.5 seconds. If we pretend that the code below was not present, + // then waveTimer would drop by 250, dramatically reducing how much time you have before the Octoroks + // begin hiding. This code will ultimately correct waveTimer such that its value is not affected by + // hitting Blue Octoroks. + if (sModFromLosingTime == 0) { + waveTimer = ((void)0, gSaveContext.unk_3DE0[1]) % 500; } else { - temp = (((void)0, gSaveContext.unk_3DE0[1]) + 250) % 500; + waveTimer = (((void)0, gSaveContext.unk_3DE0[1]) + 250) % 500; } - if (temp < 100) { - this->unk_26C = 80; + // Octoroks begin hiding four seconds after a wave begins. + if (waveTimer < 100) { + this->perGameVar1.octorokState = SG_OCTO_STATE_HIDING; } - if (this->unk_26E != 0) { - if (this->unk_26E == 2) { + if (this->perGameVar2.octorokHitType != SG_OCTO_HIT_TYPE_NONE) { + if (this->perGameVar2.octorokHitType == SG_OCTO_HIT_TYPE_BLUE) { gSaveContext.unk_3E18[1] -= 250; - D_809C94A8 = (D_809C94A8 + 25) % 50; + sModFromLosingTime = (sModFromLosingTime + 25) % 50; } - this->unk_26E = 0; + + this->perGameVar2.octorokHitType = SG_OCTO_HIT_TYPE_NONE; } - if (this->unk_26C == 0) { - this->unk_26C++; + if (this->perGameVar1.octorokState == SG_OCTO_STATE_SPAWNING) { + this->perGameVar1.octorokState++; } - if ((D_809C94A8 == (sp30 % 50)) && (this->unk_26C >= 70)) { - if (this->unk_27E < 15) { - this->unk_190 = D_809C94D0[this->unk_27E++]; + // A new wave of Octoroks should appear every five seconds. However, we need to take into account + // that the player might have lost time from hitting Blue Octoroks, so we do something similar to + // what was done with waveTimer above. + if ((sModFromLosingTime == (timer % 50)) && (this->perGameVar1.octorokState >= SG_OCTO_STATE_INITIAL)) { + if (this->flagsIndex < 15) { + this->octorokFlags = sOctorokFlagsPerWave[this->flagsIndex++]; Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_FOUND); - this->unk_26C = 0; + this->perGameVar1.octorokState = SG_OCTO_STATE_SPAWNING; } } if (gSaveContext.unk_3DE0[1] == 0) { - this->unk_27E = 0; - this->unk_26C = 80; + this->flagsIndex = 0; + this->perGameVar1.octorokState = SG_OCTO_STATE_HIDING; gSaveContext.unk_3DE0[1] = 0; gSaveContext.unk_3DD0[1] = 5; player->stateFlags1 |= 0x20; - D_809C94A8 = 0; + sModFromLosingTime = 0; this->actor.draw = EnSyatekiMan_Draw; func_801A2C20(); - this->actionFunc = func_809C8BF0; - if (this->unk_280 == 50) { + this->actionFunc = EnSyatekiMan_Town_EndGame; + if (this->score == 50) { func_801A3098(NA_BGM_GET_ITEM | 0x900); func_8011B4E0(play, 1); } @@ -1150,47 +1354,56 @@ void func_809C898C(EnSyatekiMan* this, PlayState* play) { } } -void func_809C8BF0(EnSyatekiMan* this, PlayState* play) { - if (this->unk_26A == 1) { - this->unk_190 = 0; - if ((this->unk_270 <= 0) && (play->interfaceCtx.unk_286 == 0)) { - Flags_SetAllTreasure(play, this->unk_280); - this->unk_270 = 15; - if (((s32)(gSaveContext.save.unk_EF4 & 0xFFFF) < this->unk_280) || (this->unk_280 == 50)) { - if ((s32)(gSaveContext.save.unk_EF4 & 0xFFFF) < this->unk_280) { +void EnSyatekiMan_Town_EndGame(EnSyatekiMan* this, PlayState* play) { + if (this->shootingGameState == SG_GAME_STATE_RUNNING) { + this->octorokFlags = 0; + if ((this->talkWaitTimer <= 0) && (play->interfaceCtx.unk_286 == 0)) { + Flags_SetAllTreasure(play, this->score); + this->talkWaitTimer = 15; + if ((GET_TOWN_SHOOTING_GALLERY_HIGH_SCORE() < this->score) || (this->score == 50)) { + if (GET_TOWN_SHOOTING_GALLERY_HIGH_SCORE() < this->score) { if (!(gSaveContext.save.weekEventReg[59] & 0x20)) { + // You got a new record! Message_StartTextbox(play, 0x407, &this->actor); - this->unk_284 = 0x407; - } else if (this->unk_280 == 50) { + this->prevTextId = 0x407; + } else if (this->score == 50) { + // No way! That was perfect! Message_StartTextbox(play, 0x405, &this->actor); - this->unk_284 = 0x405; + this->prevTextId = 0x405; } else { + // You got a new record! Message_StartTextbox(play, 0x407, &this->actor); - this->unk_284 = 0x407; + this->prevTextId = 0x407; } - } else if (this->unk_280 == 50) { + } else if (this->score == 50) { + // That was perfect! Message_StartTextbox(play, 0x406, &this->actor); - this->unk_284 = 0x406; + this->prevTextId = 0x406; } - gSaveContext.save.unk_EF4 = (gSaveContext.save.unk_EF4 & 0xFFFF0000) | (this->unk_280 & 0xFFFF); - this->unk_26A = 6; + + SET_TOWN_SHOOTING_GALLERY_HIGH_SCORE(this->score); + this->shootingGameState = SG_GAME_STATE_ENDED; } else { if (CURRENT_DAY != 3) { + // You got [score]? Oh, that's too bad... Message_StartTextbox(play, 0x401, &this->actor); - this->unk_284 = 0x401; + this->prevTextId = 0x401; } else { + // You got [score]? Too bad... Message_StartTextbox(play, 0x403, &this->actor); - this->unk_284 = 0x403; + this->prevTextId = 0x403; } - this->unk_26A = 4; + + this->shootingGameState = SG_GAME_STATE_ONE_MORE_GAME; } - this->actionFunc = func_809C7990; + + this->actionFunc = EnSyatekiMan_Town_Talk; } else { - this->unk_270--; + this->talkWaitTimer--; } } - if (this->unk_270 < 5) { + if (this->talkWaitTimer < 5) { play->unk_1887C = -10; } } @@ -1223,9 +1436,9 @@ void EnSyatekiMan_Update(Actor* thisx, PlayState* play) { EnSyatekiMan_Blink(this); this->actor.focus.pos.y = 70.0f; Actor_SetFocus(&this->actor, 70.0f); - if (this->unk_26A != 1) { + if (this->shootingGameState != SG_GAME_STATE_RUNNING) { SkelAnime_Update(&this->skelAnime); - Actor_TrackPlayer(play, &this->actor, &this->unk_258, &this->unk_25E, this->actor.focus.pos); + Actor_TrackPlayer(play, &this->actor, &this->headRot, &this->torsoRot, this->actor.focus.pos); } } @@ -1238,11 +1451,11 @@ s32 EnSyatekiMan_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, V if (limbIndex == BURLY_GUY_LIMB_HEAD) { Matrix_Translate(3000.0f, 0.0f, 0.0f, MTXMODE_APPLY); - Matrix_RotateZS(this->unk_258.x, MTXMODE_APPLY); - Matrix_RotateXS(this->unk_258.y, MTXMODE_APPLY); + Matrix_RotateZS(this->headRot.x, MTXMODE_APPLY); + Matrix_RotateXS(this->headRot.y, MTXMODE_APPLY); Matrix_Translate(-3000.0f, 0.0f, 0.0f, MTXMODE_APPLY); } else if (limbIndex == BURLY_GUY_LIMB_TORSO) { - Matrix_RotateXS(-this->unk_25E.y, MTXMODE_APPLY); + Matrix_RotateXS(-this->torsoRot.y, MTXMODE_APPLY); } return false; @@ -1250,10 +1463,10 @@ s32 EnSyatekiMan_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, V void EnSyatekiMan_PostLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnSyatekiMan* this = THIS; - Vec3f sp18 = { 1600.0f, 0.0f, 0.0f }; + Vec3f sFocusOffset = { 1600.0f, 0.0f, 0.0f }; if (limbIndex == BURLY_GUY_LIMB_HEAD) { - Matrix_MultVec3f(&sp18, &this->actor.focus.pos); + Matrix_MultVec3f(&sFocusOffset, &this->actor.focus.pos); } } diff --git a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h index 1719f81612..30bc1b1ad0 100644 --- a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h +++ b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h @@ -4,49 +4,70 @@ #include "global.h" #include "objects/object_shn/object_shn.h" - struct EnSyatekiMan; typedef void (*EnSyatekiManActionFunc)(struct EnSyatekiMan*, PlayState*); -#define ENSYATEKIMAN_GET_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) +#define EN_SYATEKI_MAN_GET_PATH(thisx) (((thisx)->params & 0xFF00) >> 8) -typedef struct { - /* 0x00 */ s16 index; - /* 0x04 */ f32 x; - /* 0x08 */ f32 y; - /* 0x0C */ f32 z; - /* 0x10 */ s32 variable; -} EnSyatekiManUnkStruct; // size = 0x14 +typedef enum { + /* 0 */ SG_GAME_STATE_NONE, // None of the states below apply. + /* 1 */ SG_GAME_STATE_RUNNING, // The shooting game is in-progress. + /* 2 */ SG_GAME_STATE_EXPLAINING_RULES, // For the Town Shooting Gallery, this state is also used for explaining the current high score. + /* 3 */ SG_GAME_STATE_NOT_PLAYING, // Either the player said "No" to playing, or they said "Yes" but don't have enough rupees. + /* 4 */ SG_GAME_STATE_ONE_MORE_GAME, // The player failed to get a new high score (Town) and/or perfect score (Swamp and Town). + /* 5 */ SG_GAME_STATE_GIVING_BONUS, // The player gets bonus points at the end of the Swamp game if they get a perfect score. + /* 6 */ SG_GAME_STATE_ENDED, // The player got a new high score and/or perfect score (Town), or the game is over (Swamp). + /* 7 */ SG_GAME_STATE_MOVING_PLAYER, // The player is automatically moving towards the spot to play the game. +} ShootingGalleryGameState; + +typedef enum { + /* 0 */ SG_OCTO_STATE_SPAWNING, + /* 1 */ SG_OCTO_STATE_SPAWNED, + /* 70 */ SG_OCTO_STATE_INITIAL = 70, + /* 80 */ SG_OCTO_STATE_HIDING = 80, +} ShootingGalleryOctorokState; + +typedef enum { + /* 0 */ SG_OCTO_HIT_TYPE_NONE, + /* 1 */ SG_OCTO_HIT_TYPE_RED, + /* 2 */ SG_OCTO_HIT_TYPE_BLUE, +} ShootingGalleryoctorokHitType; typedef struct EnSyatekiMan { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; /* 0x188 */ EnSyatekiManActionFunc actionFunc; /* 0x18C */ Path* path; - /* 0x190 */ s32 unk_190; - /* 0x194 */ s32 unk_194; + /* 0x190 */ s32 octorokFlags; + /* 0x194 */ s32 swampTargetActorListIndex; // used but never initialized, so the value is implicitly always 0 /* 0x198 */ Vec3s jointTable[BURLY_GUY_LIMB_MAX]; /* 0x1F8 */ Vec3s morphTable[BURLY_GUY_LIMB_MAX]; - /* 0x258 */ Vec3s unk_258; - /* 0x25E */ Vec3s unk_25E; + /* 0x258 */ Vec3s headRot; + /* 0x25E */ Vec3s torsoRot; /* 0x264 */ s16 eyeIndex; /* 0x266 */ s16 blinkTimer; /* 0x268 */ UNK_TYPE1 unk268[0x2]; - /* 0x26A */ s16 unk_26A; - /* 0x26C */ s16 unk_26C; - /* 0x26E */ s16 unk_26E; - /* 0x270 */ s16 unk_270; - /* 0x272 */ s16 unk_272; - /* 0x274 */ s16 unk_274; - /* 0x276 */ s16 unk_276; - /* 0x278 */ s16 unk_278; - /* 0x27A */ s16 unk_27A; - /* 0x27C */ s16 unk_27C; - /* 0x27E */ s16 unk_27E; - /* 0x280 */ s16 unk_280; - /* 0x282 */ s16 unk_282; - /* 0x284 */ s16 unk_284; + /* 0x26A */ s16 shootingGameState; + /* 0x26C */ union { + s16 guaySpawnTimer; + s16 octorokState; + } perGameVar1; + /* 0x26E */ union { + s16 bonusDekuScrubHitCounter; + s16 octorokHitType; + } perGameVar2; + /* 0x270 */ s16 talkWaitTimer; + /* 0x272 */ s16 dekuScrubFlags; + /* 0x274 */ s16 guayFlags; + /* 0x276 */ s16 wolfosFlags; + /* 0x278 */ s16 dekuScrubHitCounter; + /* 0x27A */ s16 guayHitCounter; + /* 0x27C */ s16 currentWave; + /* 0x27E */ s16 flagsIndex; // Used for Octoroks in Town and Guays in Swamp + /* 0x280 */ s16 score; + /* 0x282 */ s16 talkFlags; + /* 0x284 */ s16 prevTextId; } EnSyatekiMan; // size = 0x288 extern const ActorInit En_Syateki_Man_InitVars; diff --git a/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.c b/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.c index 26cdf34150..eda6337a0c 100644 --- a/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.c +++ b/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.c @@ -137,7 +137,7 @@ s32 func_80A361F4(EnSyatekiOkuta* this) { temp_v1 = EN_SYATEKI_OKUTA_GET_F(&this->actor); if ((temp_v1 == 1) || (temp_v1 == 4)) { - temp_a0 = syatekiMan->unk_190; + temp_a0 = syatekiMan->octorokFlags; temp_a1 = (temp_v1 * 2) + 6; if ((temp_a0 >> temp_a1) & 3) { @@ -212,7 +212,7 @@ void func_80A36444(EnSyatekiOkuta* this) { void func_80A36488(EnSyatekiOkuta* this, PlayState* play) { EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - if (syatekiMan->unk_26C >= 0x46) { + if (syatekiMan->perGameVar1.octorokState >= SG_OCTO_STATE_INITIAL) { func_80A364C0(this); } } @@ -341,9 +341,10 @@ void func_80A36AF8(EnSyatekiOkuta* this, PlayState* play) { EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; s16 temp_v1_2; - if ((this->actionFunc != func_80A36488) && (this->actionFunc != func_80A363B4) && (syatekiMan->unk_26A == 1) && - (syatekiMan->unk_26C == 0)) { - temp_v1_2 = (syatekiMan->unk_190 >> (EN_SYATEKI_OKUTA_GET_F(&this->actor) * 2)) & 3; + if ((this->actionFunc != func_80A36488) && (this->actionFunc != func_80A363B4) && + (syatekiMan->shootingGameState == SG_GAME_STATE_RUNNING) && + (syatekiMan->perGameVar1.octorokState == SG_OCTO_STATE_SPAWNING)) { + temp_v1_2 = (syatekiMan->octorokFlags >> (EN_SYATEKI_OKUTA_GET_F(&this->actor) * 2)) & 3; if (temp_v1_2 > 0) { Actor_SetScale(&this->actor, 0.01f); this->unk_2A6 = temp_v1_2; @@ -370,11 +371,11 @@ void EnSyatekiOkuta_Update(Actor* thisx, PlayState* play) { if (this->unk_2A6 == 1) { Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); play->interfaceCtx.unk_25C++; - syatekiMan->unk_280++; - syatekiMan->unk_26E = 1; + syatekiMan->score++; + syatekiMan->perGameVar2.octorokHitType = SG_OCTO_HIT_TYPE_RED; } else { Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_ERROR); - syatekiMan->unk_26E = 2; + syatekiMan->perGameVar2.octorokHitType = SG_OCTO_HIT_TYPE_BLUE; } func_80A3657C(this); diff --git a/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.c b/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.c index e40cc9570f..7c6073bb29 100644 --- a/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.c +++ b/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.c @@ -151,7 +151,7 @@ void EnSyatekiWf_Init(Actor* thisx, PlayState* play) { path = &play->setupPathList[path->unk1]; } - for (i = 0; i < EN_SYATEKI_WF_GET_PARAM_FF00(&this->actor); i++) { + for (i = 0; i < EN_SYATEKI_WF_GET_NUMBER(&this->actor); i++) { path = &play->setupPathList[path->unk1]; } @@ -224,7 +224,7 @@ void func_80A201CC(EnSyatekiWf* this) { this->actor.draw = NULL; this->unk_2A4 = 1; this->unk_298 = 0; - syatekiMan->unk_276 &= ~(1 << EN_SYATEKI_WF_GET_PARAM_FF00(&this->actor)); + syatekiMan->wolfosFlags &= ~(1 << EN_SYATEKI_WF_GET_NUMBER(&this->actor)); this->actionFunc = func_80A20284; } @@ -233,10 +233,10 @@ void func_80A20284(EnSyatekiWf* this, PlayState* play) { if (this->actor.parent != NULL) { syatekiMan = (EnSyatekiMan*)this->actor.parent; - if ((syatekiMan->unk_26A == 1) && (this->unk_298 == 1)) { + if ((syatekiMan->shootingGameState == SG_GAME_STATE_RUNNING) && (this->unk_298 == 1)) { func_80A200E0(this); func_80A2030C(this); - } else if (syatekiMan->unk_276 & (1 << EN_SYATEKI_WF_GET_PARAM_FF00(&this->actor))) { + } else if (syatekiMan->wolfosFlags & (1 << EN_SYATEKI_WF_GET_NUMBER(&this->actor))) { this->unk_298 = 1; } } @@ -270,7 +270,7 @@ void func_80A203DC(EnSyatekiWf* this, PlayState* play) { s16 temp_v0; EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; - if (syatekiMan->unk_26A != 1) { + if (syatekiMan->shootingGameState != SG_GAME_STATE_RUNNING) { func_80A201CC(this); } @@ -375,7 +375,7 @@ void func_80A20858(EnSyatekiWf* this, PlayState* play) { EffectSsExtra_Spawn(play, &this->actor.world.pos, &D_80A20EDC, &D_80A20EE8, 5, 2); Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_DEAD); Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 6); - syatekiMan->unk_280 += 100; + syatekiMan->score += 100; this->actionFunc = func_80A208F8; } diff --git a/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.h b/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.h index 1af2d0b962..4de182a106 100644 --- a/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.h +++ b/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.h @@ -5,7 +5,8 @@ #include "objects/object_wf/object_wf.h" #define EN_SYATEKI_WF_GET_PARAM_F0(thisx) (((thisx)->params & 0xF0) >> 4) -#define EN_SYATEKI_WF_GET_PARAM_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) +#define EN_SYATEKI_WF_GET_NUMBER(thisx) (((thisx)->params & 0xFF00) >> 8) +#define EN_SYATEKI_WF_PARAMS(number, unkF0, unused) (((number << 8) & 0xFF00) | ((unkF0 << 4) & 0xF0) | (unused & 0xF)) struct EnSyatekiWf; diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 3f26ba062b..7ca90a3336 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -9080,33 +9080,33 @@ 0x809C5E14:("EnBomBowlMan_Update",), 0x809C5F44:("EnBomBowlMan_OverrideLimbDraw",), 0x809C5FC4:("EnBomBowlMan_Draw",), - 0x809C64C0:("func_809C64C0",), + 0x809C64C0:("EnSyatekiMan_Swamp_SpawnTargetActors",), 0x809C6578:("EnSyatekiMan_Init",), 0x809C66FC:("EnSyatekiMan_Destroy",), - 0x809C6720:("func_809C6720",), - 0x809C6810:("func_809C6810",), - 0x809C6848:("func_809C6848",), - 0x809C6A04:("func_809C6A04",), - 0x809C6C2C:("func_809C6C2C",), - 0x809C6E30:("func_809C6E30",), - 0x809C6F98:("func_809C6F98",), - 0x809C72D8:("func_809C72D8",), - 0x809C7380:("func_809C7380",), - 0x809C7620:("func_809C7620",), - 0x809C7990:("func_809C7990",), - 0x809C7A90:("func_809C7A90",), - 0x809C7C14:("func_809C7C14",), - 0x809C7D14:("func_809C7D14",), - 0x809C7EB4:("func_809C7EB4",), - 0x809C7FFC:("func_809C7FFC",), - 0x809C80C0:("func_809C80C0",), - 0x809C81D0:("func_809C81D0",), - 0x809C8488:("func_809C8488",), - 0x809C8610:("func_809C8610",), - 0x809C8710:("func_809C8710",), - 0x809C8808:("func_809C8808",), - 0x809C898C:("func_809C898C",), - 0x809C8BF0:("func_809C8BF0",), + 0x809C6720:("EnSyatekiMan_MovePlayerToPos",), + 0x809C6810:("EnSyatekiMan_SetupIdle",), + 0x809C6848:("EnSyatekiMan_Swamp_Idle",), + 0x809C6A04:("EnSyatekiMan_Swamp_HandleChoice",), + 0x809C6C2C:("EnSyatekiMan_Swamp_HandleNormalMessage",), + 0x809C6E30:("EnSyatekiMan_Swamp_Talk",), + 0x809C6F98:("EnSyatekiMan_Town_StartIntroTextbox",), + 0x809C72D8:("EnSyatekiMan_Town_Idle",), + 0x809C7380:("EnSyatekiMan_Town_HandleChoice",), + 0x809C7620:("EnSyatekiMan_Town_HandleNormalMessage",), + 0x809C7990:("EnSyatekiMan_Town_Talk",), + 0x809C7A90:("EnSyatekiMan_Swamp_SetupGiveReward",), + 0x809C7C14:("EnSyatekiMan_Swamp_GiveReward",), + 0x809C7D14:("EnSyatekiMan_Town_SetupGiveReward",), + 0x809C7EB4:("EnSyatekiMan_Town_GiveReward",), + 0x809C7FFC:("EnSyatekiMan_Swamp_MovePlayerAndExplainRules",), + 0x809C80C0:("EnSyatekiMan_Swamp_StartGame",), + 0x809C81D0:("EnSyatekiMan_Swamp_RunGame",), + 0x809C8488:("EnSyatekiMan_Swamp_EndGame",), + 0x809C8610:("EnSyatekiMan_Swamp_AddBonusPoints",), + 0x809C8710:("EnSyatekiMan_Town_MovePlayerAndSayHighScore",), + 0x809C8808:("EnSyatekiMan_Town_StartGame",), + 0x809C898C:("EnSyatekiMan_Town_RunGame",), + 0x809C8BF0:("EnSyatekiMan_Town_EndGame",), 0x809C8DE8:("EnSyatekiMan_Blink",), 0x809C8E44:("EnSyatekiMan_Update",), 0x809C8EE4:("EnSyatekiMan_OverrideLimbDraw",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index 77f840dbe7..0af6d62d09 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -9922,23 +9922,23 @@ 0x809C6264:("D_809C6264","f32","",0x4), 0x809C6268:("D_809C6268","f32","",0x4), 0x809C9160:("En_Syateki_Man_InitVars","UNK_TYPE1","",0x1), - 0x809C9180:("D_809C9180","UNK_TYPE1","",0x1), - 0x809C91C8:("D_809C91C8","UNK_TYPE1","",0x1), - 0x809C91D0:("D_809C91D0","UNK_TYPE1","",0x1), - 0x809C934C:("D_809C934C","UNK_TYPE1","",0x1), - 0x809C9464:("D_809C9464","UNK_PTR","",0x4), - 0x809C946C:("D_809C946C","UNK_TYPE1","",0x1), - 0x809C9474:("D_809C9474","UNK_TYPE4","",0x4), - 0x809C9480:("D_809C9480","UNK_TYPE4","",0x4), - 0x809C948C:("D_809C948C","UNK_TYPE4","",0x4), - 0x809C9498:("D_809C9498","UNK_TYPE2","",0x2), - 0x809C949C:("D_809C949C","UNK_TYPE2","",0x2), - 0x809C94A0:("D_809C94A0","UNK_TYPE4","",0x4), - 0x809C94A4:("D_809C94A4","UNK_TYPE2","",0x2), - 0x809C94A8:("D_809C94A8","UNK_TYPE4","",0x4), - 0x809C94AC:("D_809C94AC","UNK_TYPE4","",0x4), - 0x809C94B8:("D_809C94B8","UNK_PTR","",0x4), - 0x809C94D0:("D_809C94D0","UNK_TYPE1","",0x1), + 0x809C9180:("sAnimations","UNK_TYPE1","",0x1), + 0x809C91C8:("sGuayFlagsPerWave","UNK_TYPE1","",0x1), + 0x809C91D0:("sNormalSwampTargetActorList","UNK_TYPE1","",0x1), + 0x809C934C:("sUnusedSwampTargetActorList","UNK_TYPE1","",0x1), + 0x809C9464:("sSwampTargetActorLists","UNK_PTR","",0x4), + 0x809C946C:("sSwampTargetActorListLengths","UNK_TYPE1","",0x1), + 0x809C9474:("sSwampPlayerPos","UNK_TYPE4","",0x4), + 0x809C9480:("sTownFierceDietyPlayerPos","UNK_TYPE4","",0x4), + 0x809C948C:("sTownPlayerPos","UNK_TYPE4","",0x4), + 0x809C9498:("sGameStartTimer","s16","",0x2), + 0x809C949C:("sHasSpawnedGuaysForThisWave","UNK_TYPE2","",0x2), + 0x809C94A0:("sBonusTimer","s32","",0x4), + 0x809C94A4:("sGameStartTimer","s16","",0x2), + 0x809C94A8:("sModFromLosingTime","s32","",0x4), + 0x809C94AC:("sFocusOffset","UNK_TYPE4","",0x4), + 0x809C94B8:("sEyeTextures","UNK_PTR","",0x4), + 0x809C94D0:("sOctorokFlagsPerWave","UNK_TYPE1","",0x1), 0x809C950C:("jtbl_809C950C","UNK_PTR","",0x4), 0x809C9544:("jtbl_809C9544","UNK_PTR","",0x4), 0x809C9570:("jtbl_809C9570","UNK_PTR","",0x4),