diff options
Diffstat (limited to 'src/manager/miscManager.c')
| -rw-r--r-- | src/manager/miscManager.c | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/src/manager/miscManager.c b/src/manager/miscManager.c new file mode 100644 index 00000000..147dfb06 --- /dev/null +++ b/src/manager/miscManager.c @@ -0,0 +1,440 @@ +/** + * @file miscManager.c + * @ingroup Managers + * + * @brief Various different functionalities selected with paramA/unk_0a. + */ +#include "manager/miscManager.h" +#include "area.h" +#include "common.h" +#include "flags.h" +#include "functions.h" +#include "item.h" +#include "message.h" +#include "object.h" +#include "player.h" +#include "room.h" +#include "sound.h" +#include "tiles.h" + +void MiscManager_Type0(MiscManager*); +void MiscManager_Type1(MiscManager*); +void MiscManager_Type3(MiscManager*); +void MiscManager_Type4(MiscManager*); +void MiscManager_Type5(MiscManager*); +void MiscManager_Type6(MiscManager*); +void MiscManager_Type7(MiscManager*); +void MiscManager_Type8(MiscManager*); +void MiscManager_Type9(MiscManager*); +void MiscManager_TypeA(MiscManager*); +void MiscManager_TypeB(MiscManager*); +void MiscManager_TypeC(MiscManager*); +void MiscManager_TypeD(MiscManager*); +#ifndef EU +void MiscManager_TypeE(MiscManager*); +#endif +#if defined(USA) || defined(DEMO_USA) || defined(DEMO_JP) +void MiscManager_TypeF(MiscManager*); +#endif + +// clang-format off +void (*const MiscManager_Types[])(MiscManager*) = { + MiscManager_Type0, + MiscManager_Type1, + MiscManager_Type1, // dup + MiscManager_Type3, + MiscManager_Type4, + MiscManager_Type5, + MiscManager_Type6, + MiscManager_Type7, + MiscManager_Type8, + MiscManager_Type9, + MiscManager_TypeA, + MiscManager_TypeB, + MiscManager_TypeC, + MiscManager_TypeD, +#ifndef EU + MiscManager_TypeE, +#endif +#if defined(USA) || defined(DEMO_USA) || defined(DEMO_JP) + MiscManager_TypeF, +#endif +}; +// clang-format on + +typedef struct { + u16 x; + u16 y; + u16 width; + u16 height; + u16 unk_08; +} PACKED __attribute__((aligned(2))) MiscManager_HelperStruct; + +const MiscManager_HelperStruct gUnk_08108354[] = { + { 0xF0, 0xB0, 0xF0, 0xB0, 0x100 }, + { 0x188, 0x190, 0x28, 0x30, 0x100 }, + { 0xF0, 0x340, 0xF0, 0xB0, 0x80 }, + { 0x180, 0x278, 0x60, 0x38, 0x80 }, +}; + +const u32 gUnk_08108354_terminator = 0xFFFF; // terminator for the previous array + +extern u16 script_PlayerAtDarkNut1[]; +extern u16 script_PlayerAtDarkNut2[]; +extern u16 script_PlayerAtDarkNut3[]; +extern u16 script_PlayerAtMadderpillar[]; + +u16* const gUnk_08108380[] = { + script_PlayerAtDarkNut1, + script_PlayerAtDarkNut2, + script_PlayerAtDarkNut3, + script_PlayerAtMadderpillar, +}; + +void sub_08058F44(u32, u32, u32); +void sub_08058F84(u32, u32); +void sub_08059064(MiscManager*); +void sub_080592EC(MiscManager*); +void sub_0805930C(MiscManager*); +u32 sub_080593CC(MiscManager*); + +// to be moved to headers +extern EntityData gUnk_080F4B88[]; + +void MiscManager_Main(MiscManager* this) { + MiscManager_Types[super->type](this); +} + +void MiscManager_Type0(MiscManager* this) { + if (super->action == 0) + super->action = 1; + if (!CheckRoomFlag(super->type2)) + return; + sub_08058F44(0x128, 0x68, super->type2 + 1); + sub_08058F44(0x158, 0x68, super->type2 + 2); + sub_08058F44(0x128, 0x98, super->type2 + 3); + sub_08058F44(0x158, 0x98, super->type2 + 4); + SoundReq(SFX_124); + DeleteThisEntity(); +} + +void sub_08058F44(u32 unk0, u32 unk1, u32 unk2) { + if (CheckRoomFlag(unk2)) + return; + if (sub_080B1A48(unk0, unk1, 1) != 0x61) + return; + SetTileType(0x26, ((unk0 >> 4) & 0x3F) | (((unk1 >> 4) & 0x3F) << 6), 1); + sub_08058F84(unk0, unk1); +} + +void sub_08058F84(u32 unk0, u32 unk1) { + Entity* tmp; + tmp = CreateObject(OBJECT_21, 0, 0); + if (!tmp) + return; + tmp->x.HALF.HI = gRoomControls.origin_x + unk0; + tmp->y.HALF.HI = gRoomControls.origin_y + unk1; +} + +void MiscManager_Type1(MiscManager* this) { + switch (super->action) { + case 0: + super->action = 1; + if (super->type == 1) { + super->subAction = 7; + super->subtimer = 6; + } else { + super->subAction = 8; + super->subtimer = 2; + } + if (CheckFlags(this->unk_3e)) { + DeleteManager(super); + } + break; + case 1: + if (CheckFlags(this->unk_3e)) { + super->action = 2; + super->timer = 120; + RequestPriorityDuration((Entity*)this, 0xF0); + sub_08059064(this); + } + break; + case 2: + if (super->timer == 90) { + SetPlayerControl(2); + PutAwayItems(); + } + if (super->timer == 60) { + gPlayerEntity.animationState = super->subtimer; + } + if (!--super->timer) { + super->action = 3; + MenuFadeIn(5, super->subAction); + } + break; + default: + SetFlag(this->unk_3e); + SetPlayerControl(1); + DeleteThisEntity(); + } +} + +void sub_08059064(MiscManager* this) { + Entity* tmp; + tmp = CreateObject(GROUND_ITEM, ITEM_SMALL_KEY, 0); + if (!tmp) + return; + tmp->timer = 2; + tmp->x.HALF.HI = this->unk_38 + gRoomControls.origin_x; + tmp->y.HALF.HI = this->unk_3a + gRoomControls.origin_y; +} + +void MiscManager_Type3(MiscManager* this) { + u32 tmp = 0; + if (super->action == 0) { + super->action = 1; + if (CheckLocalFlag(0x60)) { + tmp = 1; + } else { + SetLocalFlag(0x5F); + } + } else { + if (CheckLocalFlag(0x60)) { + ClearLocalFlag(0x5F); + tmp = 1; + } + } + if (tmp) { + LoadRoomEntityList(gUnk_080F4B88); + DeleteManager(super); + } +} + +void MiscManager_Type4(MiscManager* this) { + if (super->action == 0) { + super->action = 1; + SetDefaultPriority((Entity*)this, PRIO_PLAYER_EVENT); + } + if (CheckLocalFlag(0x6c)) { + if (CheckLocalFlag(0x4b)) { + SetLocalFlag(0x4a); + } else { + ClearLocalFlag(0x4a); + } + } else { + ClearLocalFlag(0x4a); + } +} + +void MiscManager_Type5(MiscManager* this) { + switch (super->action) { + default: + if (!--super->timer) { + CreateDustAt(this->unk_38, this->unk_3a, super->type2); + RestorePrevTileEntity(((this->unk_38 >> 4) & 0x3f) | ((this->unk_3a >> 4) & 0x3f) << 6, super->type2); + SoundReq(SFX_TASK_COMPLETE); + DeleteThisEntity(); + } + break; + case 0: + if (CheckFlags(this->unk_3e)) { + DeleteThisEntity(); + } + super->action = 1; + SetTileType(0x365, ((this->unk_38 >> 4) & 0x3f) | ((this->unk_3a >> 4) & 0x3f) << 6, super->type2); + break; + case 1: + if (CheckFlags(this->unk_3e)) { + RequestPriorityDuration((Entity*)this, 0x4b); + super->timer = 0x2d; + super->action++; + } + } +} + +void MiscManager_Type6(MiscManager* this) { + if (super->action == 0) { + super->action = 1; + super->type2 = CheckFlags(this->unk_3e); + if (super->type2) { + gRoomVars.lightLevel = this->unk_3a; + } else { + gRoomVars.lightLevel = this->unk_38; + } + } else { + u32 tmp = CheckFlags(this->unk_3e); + if (super->type2 != tmp) { + super->type2 = tmp; + if (tmp) { + gRoomVars.lightLevel = this->unk_3a; + } else { + gRoomVars.lightLevel = this->unk_38; + } + } + } +} + +void MiscManager_Type7(MiscManager* this) { + const MiscManager_HelperStruct* data; + gRoomVars.lightLevel = 0; + + for (data = gUnk_08108354; data->x != 0xFFFF; data++) { + if (CheckPlayerInRegion(data->x, data->y, data->width, data->height)) { + gRoomVars.lightLevel = data->unk_08; + } + } + if (super->action == 0) { + super->action = 1; + gArea.lightLevel = gRoomVars.lightLevel; + } +} + +void sub_08059278(void) { + MiscManager* tmp; + tmp = (MiscManager*)FindEntityByID(MANAGER, MISC_MANAGER, 0x6); + if (tmp) { + MiscManager_Main(tmp); + } +} + +void MiscManager_Type8(MiscManager* this) { + super->action = 1; + gRoomControls.camera_target = &gPlayerEntity; +} + +void MiscManager_Type9(MiscManager* this) { + if (super->action == 0) { + super->action = 1; + if (CheckFlags(this->unk_3e)) { + sub_080592EC(this); + DeleteThisEntity(); + } + } else { + if (CheckFlags(this->unk_3e)) { + sub_080592EC(this); + sub_0805930C(this); +#ifndef EU + SoundReq(SFX_16E); +#endif + DeleteThisEntity(); + } + } +} + +void sub_080592EC(MiscManager* this) { + SetDirtTile(((this->unk_38 >> 4) & 0x3F) | (((this->unk_3a >> 4) & 0x3F) << 6)); +} + +void sub_0805930C(MiscManager* this) { + Entity* tmp; +#ifdef EU + tmp = CreateObject(SPECIAL_FX, FX_BIG_EXPLOSION2, 0x0); +#else + tmp = CreateObject(SPECIAL_FX, FX_BIG_EXPLOSION2, 0x40); +#endif + if (!tmp) + return; + tmp->x.HALF.HI = this->unk_38 + gRoomControls.origin_x; + tmp->y.HALF.HI = this->unk_3a + gRoomControls.origin_y; + tmp->collisionLayer = 1; +} + +void SetDirtTile(u32 tile) { + SetTileType(CUT_GRASS, tile, 1); + SetTileType(0, tile, 2); + SetTileType(0, tile - 0x40, 2); +} + +void MiscManager_TypeA(MiscManager* this) { + super->action = 1; + if (this->unk_3c == gTextRender.curToken.textIndex) { + SetFlag(this->unk_3e); + DeleteThisEntity(); + } +} + +void MiscManager_TypeB(MiscManager* this) { + if (sub_080593CC(this)) { + if (++super->timer >= 8) { + sub_080806BC(this->unk_38 - gRoomControls.origin_x, this->unk_3a - gRoomControls.origin_y, 0xFF, 0xA); + } + } else { + super->timer = 0; + } +} + +u32 sub_080593CC(MiscManager* this) { + if (!(gPlayerState.flags & PL_MINISH) && gPlayerState.swim_state != 0 && gPlayerEntity.animationState == 0 && + (gPlayerState.field_0x90 & 0xF00) == 0x400) { + return EntityWithinDistance(&gPlayerEntity, this->unk_38, this->unk_3a + 0xC, 6); + } + return 0; +} + +void MiscManager_TypeC(MiscManager* this) { + Entity* tmp; + if (CheckFlags(this->unk_3e)) { + DeleteThisEntity(); + } + if (!CheckFlags(this->unk_3c)) + return; + tmp = CreateObject(SPECIAL_FX, FX_BIG_EXPLOSION, 0); + if (!tmp) + return; + tmp->collisionLayer = 2; + tmp->x.HALF.HI = this->unk_38 + gRoomControls.origin_x; + tmp->y.HALF.HI = this->unk_3a + gRoomControls.origin_y; + EnqueueSFX(SFX_1B0); + DeleteThisEntity(); +} + +void MiscManager_TypeD(MiscManager* this) { + if (!CheckFlags(this->unk_3e)) { + SetPlayerControl(3); + if (gRoomControls.reload_flags) + return; + if (gRoomVars.field_0x0) { + StartPlayerScript(gUnk_08108380[gRoomControls.scroll_direction]); + } else { + StartPlayerScript(gUnk_08108380[gPlayerEntity.animationState >> 1]); + } + } + DeleteThisEntity(); +} + +#ifndef EU +void MiscManager_TypeE(MiscManager* this) { + switch (super->action) { + case 0: + super->action = 1; + // fall through + case 1: + if (!GetInventoryValue(ITEM_FOURSWORD)) + return; + if (CheckLocalFlagByBank(FLAG_BANK_10, 0x85)) + return; + super->action = 2; + sub_080186C0(0xB0F); + break; + case 2: + default: + if (gArea.unk28.inventoryGfxIdx != 0xFF) { + DeleteThisEntity(); + } + if (CheckLocalFlagByBank(FLAG_BANK_10, 0x85)) { + sub_0801855C(); + DeleteThisEntity(); + } + } +} +#endif + +#if defined(USA) || defined(DEMO_USA) || defined(DEMO_JP) +void MiscManager_TypeF(MiscManager* this) { + SetDefaultPriority((Entity*)this, PRIO_PLAYER_EVENT); + if (gPlayerEntity.action == PLAYER_TALKEZLO) { + DeleteThisEntity(); + } + gInput.heldKeys |= 0x4; +} +#endif |
