diff --git a/assets/xml/objects/object_takaraya_objects.xml b/assets/xml/objects/object_takaraya_objects.xml index 4ce448c86a..ef17355755 100644 --- a/assets/xml/objects/object_takaraya_objects.xml +++ b/assets/xml/objects/object_takaraya_objects.xml @@ -1,9 +1,10 @@  + - - - - - + + + + + diff --git a/spec b/spec index 60dfc733df..f39198bd9b 100644 --- a/spec +++ b/spec @@ -3289,9 +3289,7 @@ beginseg name "ovl_Obj_Takaraya_Wall" compress include "build/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.o" - include "build/data/ovl_Obj_Takaraya_Wall/ovl_Obj_Takaraya_Wall.data.o" - include "build/data/ovl_Obj_Takaraya_Wall/ovl_Obj_Takaraya_Wall.bss.o" - include "build/data/ovl_Obj_Takaraya_Wall/ovl_Obj_Takaraya_Wall.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Takaraya_Wall/ovl_Obj_Takaraya_Wall_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Takaraya/z_en_takaraya.c b/src/overlays/actors/ovl_En_Takaraya/z_en_takaraya.c index 0c3b2e7cbf..24cd5779cb 100644 --- a/src/overlays/actors/ovl_En_Takaraya/z_en_takaraya.c +++ b/src/overlays/actors/ovl_En_Takaraya/z_en_takaraya.c @@ -5,6 +5,7 @@ */ #include "z_en_takaraya.h" +#include "overlays/actors/ovl_En_Box/z_en_box.h" #define FLAGS (ACTOR_FLAG_TARGETABLE | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_10 | ACTOR_FLAG_20) @@ -76,11 +77,11 @@ u16 D_80ADFB2C[PLAYER_FORM_MAX] = { }; u8 D_80ADFB38[PLAYER_FORM_MAX][2] = { - { 5, 5 }, // PLAYER_FORM_FIERCE_DEITY - { 12, 5 }, // PLAYER_FORM_GORON - { 4, 4 }, // PLAYER_FORM_ZORA - { 42, 41 }, // PLAYER_FORM_DEKU - { 5, 5 }, // PLAYER_FORM_HUMAN + { GI_RUPEE_PURPLE, GI_RUPEE_PURPLE }, // PLAYER_FORM_FIERCE_DEITY + { GI_HEART_PIECE, GI_RUPEE_PURPLE }, // PLAYER_FORM_GORON + { GI_RUPEE_RED, GI_RUPEE_RED }, // PLAYER_FORM_ZORA + { GI_DEKU_NUTS_10, GI_DEKU_NUTS_5 }, // PLAYER_FORM_DEKU + { GI_RUPEE_PURPLE, GI_RUPEE_PURPLE }, // PLAYER_FORM_HUMAN }; u16 D_80ADFB44[PLAYER_FORM_MAX] = { @@ -190,16 +191,16 @@ void EnTakaraya_Wait(EnTakaraya* this, PlayState* play) { } void EnTakaraya_SpawnWalls(EnTakaraya* this, PlayState* play) { - u8 var_v1; + u8 getItemId; if (Flags_GetSwitch(play, this->formSwitchFlag)) { - var_v1 = D_80ADFB38[GET_PLAYER_FORM][1]; + getItemId = D_80ADFB38[GET_PLAYER_FORM][1]; } else { - var_v1 = D_80ADFB38[GET_PLAYER_FORM][0]; + getItemId = D_80ADFB38[GET_PLAYER_FORM][0]; } Actor_SpawnAsChildAndCutscene(&play->actorCtx, play, ACTOR_OBJ_TAKARAYA_WALL, 0.0f, 0.0f, 0.0f, 0, 0, 5, - ((var_v1 << 5) + this->actor.params) + 0xB000, this->actor.csId, HALFDAYBIT_ALL, - NULL); + (ENBOX_TYPE_BIG_SWITCH_FLAG << 12) + (getItemId << 5) + this->actor.params, + this->actor.csId, HALFDAYBIT_ALL, NULL); } void EnTakaraya_SetupTalk(EnTakaraya* this) { diff --git a/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c index 4d9b488310..3218c3050d 100644 --- a/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c +++ b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c @@ -1,10 +1,31 @@ /* * File: z_obj_takaraya_wall.c * Overlay: ovl_Obj_Takaraya_Wall - * Description: Treasure Chest Shop rising wall + * Description: Treasure Chest Shop board manager + */ + +/** + * The board is laid out as follows: + * + * Back + * 7 6 5 4 3 2 1 0 + * 0 x x x x x x x x <-- Chest spawns in this row + * 1 x x x x x x x x + * 2 x x x x x x x x + * 3 x x x x x x x x + * 4 x x x x x x x x + * Left 5 x x x x x x x x Right + * 6 x x x x x x x x + * 7 x x x x x x x x + * 8 x x x x x x x x + * 9 x x x x x x x x + * 10 x x x x x x x x + * Front + * */ #include "z_obj_takaraya_wall.h" +#include "objects/object_takaraya_objects/object_takaraya_objects.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) @@ -12,12 +33,11 @@ void ObjTakarayaWall_Init(Actor* thisx, PlayState* play); void ObjTakarayaWall_Destroy(Actor* thisx, PlayState* play); -void ObjTakarayaWall_Update(Actor* thisx, PlayState* play); +void ObjTakarayaWall_Update(Actor* thisx, PlayState* play2); void ObjTakarayaWall_Draw(Actor* thisx, PlayState* play); -void func_80AD9B04(ObjTakarayaWall* this, PlayState* play); +void ObjTakarayaWall_Manage(ObjTakarayaWall* this, PlayState* play); -#if 0 ActorInit Obj_Takaraya_Wall_InitVars = { /**/ ACTOR_OBJ_TAKARAYA_WALL, /**/ ACTORCAT_BG, @@ -30,39 +50,455 @@ ActorInit Obj_Takaraya_Wall_InitVars = { /**/ ObjTakarayaWall_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80ADA2A0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 40, 120, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80ADA2CC[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +#define TAKARAYA_WALL_ROWS 11 +#define TAKARAYA_WALL_COLUMNS 8 -extern ColliderCylinderInit D_80ADA2A0; -extern InitChainEntry D_80ADA2CC[]; +typedef struct ObjTakarayaWallCell { + /* 0x0 */ u8 row; + /* 0x1 */ u8 column; +} ObjTakarayaWallCell; // size = 0x2 -extern UNK_TYPE D_06000D60; +typedef enum ObjTakarayaWallCellState { + /* 0 */ TAKARAYA_WALL_INACTIVE, + /* 1 */ TAKARAYA_WALL_RISING, + /* 2 */ TAKARAYA_WALL_FALLING +} ObjTakarayaWallCellState; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Takaraya_Wall/func_80AD9240.s") +s32 sTakarayaWallPathStackDepth; +ObjTakarayaWallCell sTakarayaWallPathStack[TAKARAYA_WALL_ROWS * TAKARAYA_WALL_COLUMNS]; +s32 sTakarayaWallSuccessfulPathStackDepth; // Set but never used +s32 sTakarayaWallPathReachedFront; +Vec3f sTakarayaWallAudioPositions[TAKARAYA_WALL_ROWS][TAKARAYA_WALL_COLUMNS]; +u8 sTakarayaWallStates[TAKARAYA_WALL_ROWS][TAKARAYA_WALL_COLUMNS]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Takaraya_Wall/func_80AD92FC.s") +// -10.0f height means the wall does not raise (the cell is open) +f32 sTakarayaWallHeights[TAKARAYA_WALL_ROWS][TAKARAYA_WALL_COLUMNS]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Takaraya_Wall/func_80AD9358.s") +// Note: returns true if the cell is valid +s32 ObjTakarayaWall_PosToCell(Vec3f* pos, s32* row, s32* column) { + *row = ((s32)pos->x - -1680) / 120; + *column = ((s32)pos->z - 0) / 120; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Takaraya_Wall/func_80AD9488.s") + if ((*row < 0) || (*row >= TAKARAYA_WALL_ROWS) || (*column < 0) || (*column >= TAKARAYA_WALL_COLUMNS)) { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Takaraya_Wall/ObjTakarayaWall_Init.s") +/** + * Checks if the given row and column is valid and is open, i.e does not raise up. + */ +s32 ObjTakarayaWall_IsCellOpen(s32 row, s32 column) { + if ((row < 0) || (row >= TAKARAYA_WALL_ROWS) || (column < 0) || (column >= TAKARAYA_WALL_COLUMNS) || + (sTakarayaWallHeights[row][column] == 0.0f)) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Takaraya_Wall/ObjTakarayaWall_Destroy.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Takaraya_Wall/func_80AD9B04.s") +typedef enum TakarayaWallDirection { + /* 0 */ TAKARAYA_WALL_DIRECTION_BACK, + /* 1 */ TAKARAYA_WALL_DIRECTION_RIGHT, + /* 2 */ TAKARAYA_WALL_DIRECTION_FRONT, + /* 3 */ TAKARAYA_WALL_DIRECTION_LEFT +} TakarayaWallDirection; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Takaraya_Wall/ObjTakarayaWall_Update.s") +/** + * Checks nearby spaces if the adjacent space or any of the three adjacent spaces to that + * space are closed (i.e the wall rises up). + */ +s32 ObjTakarayaWall_CanCarvePath(s32 row, s32 column, TakarayaWallDirection direction) { + s32 adjacentSpaceRow; + s32 adjacentSpaceColumn; + s32 row1; + s32 column1; + s32 row2; + s32 column2; + s32 row3; + s32 column3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Takaraya_Wall/ObjTakarayaWall_Draw.s") + if ((direction == TAKARAYA_WALL_DIRECTION_FRONT) || (direction == TAKARAYA_WALL_DIRECTION_BACK)) { + if (direction == TAKARAYA_WALL_DIRECTION_BACK) { + adjacentSpaceRow = row - 1; + row3 = row - 2; + } else { // TAKARAYA_WALL_DIRECTION_FRONT + adjacentSpaceRow = row + 1; + row3 = row + 2; + } + adjacentSpaceColumn = column; + column3 = column; + row1 = adjacentSpaceRow; + column1 = column + 1; + row2 = adjacentSpaceRow; + column2 = column - 1; + } else { + if (direction == TAKARAYA_WALL_DIRECTION_RIGHT) { + adjacentSpaceColumn = column - 1; + column3 = column - 2; + } else { // TAKARAYA_WALL_DIRECTION_LEFT + adjacentSpaceColumn = column + 1; + column3 = column + 2; + } + adjacentSpaceRow = row; + row3 = row; + row1 = row + 1; + column1 = adjacentSpaceColumn; + row2 = row - 1; + column2 = adjacentSpaceColumn; + } + + if ((adjacentSpaceRow < 0) || (adjacentSpaceRow >= TAKARAYA_WALL_ROWS) || (adjacentSpaceColumn < 0) || + (adjacentSpaceColumn >= TAKARAYA_WALL_COLUMNS) || + (sTakarayaWallHeights[adjacentSpaceRow][adjacentSpaceColumn] == -10.0f) || + ObjTakarayaWall_IsCellOpen(row1, column1) || ObjTakarayaWall_IsCellOpen(row2, column2) || + ObjTakarayaWall_IsCellOpen(row3, column3)) { + return false; + } + + return true; +} + +void ObjTakarayaWall_CarvePath(s32 row, s32 column) { + s32 carveDirectionFlags = 0; + s32 carveDirectionNum = 0; + s32 randMode; + s32 direction; + + if (ObjTakarayaWall_CanCarvePath(row, column, TAKARAYA_WALL_DIRECTION_BACK)) { + carveDirectionNum++; + carveDirectionFlags |= (1 << TAKARAYA_WALL_DIRECTION_BACK); + } + + if (ObjTakarayaWall_CanCarvePath(row, column, TAKARAYA_WALL_DIRECTION_RIGHT)) { + carveDirectionNum++; + carveDirectionFlags |= (1 << TAKARAYA_WALL_DIRECTION_RIGHT); + } + + if (ObjTakarayaWall_CanCarvePath(row, column, TAKARAYA_WALL_DIRECTION_FRONT)) { + carveDirectionNum++; + carveDirectionFlags |= (1 << TAKARAYA_WALL_DIRECTION_FRONT); + } + + if (ObjTakarayaWall_CanCarvePath(row, column, TAKARAYA_WALL_DIRECTION_LEFT)) { + carveDirectionNum++; + carveDirectionFlags |= (1 << TAKARAYA_WALL_DIRECTION_LEFT); + } + + if (carveDirectionNum == 0) { + sTakarayaWallPathStackDepth--; + if (!sTakarayaWallPathReachedFront) { + sTakarayaWallSuccessfulPathStackDepth--; + } + + return; + } + + // Randomly select direction to carve, each possible direction has an equal probability of getting carved out + randMode = (s32)Rand_ZeroFloat(carveDirectionNum) % carveDirectionNum; + + if (randMode == 0) { + direction = TAKARAYA_WALL_DIRECTION_BACK; + while (!((1 << direction) & carveDirectionFlags)) { + direction++; + } + } else if (randMode == 1) { + direction = TAKARAYA_WALL_DIRECTION_LEFT; + while (!((1 << direction) & carveDirectionFlags)) { + direction--; + } + } else if (randMode == 2) { + direction = TAKARAYA_WALL_DIRECTION_BACK; + while (!((1 << direction) & carveDirectionFlags)) { + direction++; + } + direction++; + while (!((1 << direction) & carveDirectionFlags)) { + direction++; + } + } else { + direction = TAKARAYA_WALL_DIRECTION_LEFT; + while (!((1 << direction) & carveDirectionFlags)) { + direction--; + } + direction--; + while (!((1 << direction) & carveDirectionFlags)) { + direction--; + } + } + + if (direction == TAKARAYA_WALL_DIRECTION_BACK) { + row--; + } else if (direction == TAKARAYA_WALL_DIRECTION_FRONT) { + row++; + } else if (direction == TAKARAYA_WALL_DIRECTION_RIGHT) { + column--; + } else { // TAKARAYA_WALL_DIRECTION_LEFT + column++; + } + + sTakarayaWallHeights[row][column] = -10.0f; + sTakarayaWallPathStack[sTakarayaWallPathStackDepth].row = row; + sTakarayaWallPathStack[sTakarayaWallPathStackDepth].column = column; + sTakarayaWallPathStackDepth++; + + if (!sTakarayaWallPathReachedFront) { + sTakarayaWallSuccessfulPathStackDepth++; + if (row == (TAKARAYA_WALL_ROWS - 1)) { + sTakarayaWallPathReachedFront = true; + } + } +} + +void ObjTakarayaWall_Init(Actor* thisx, PlayState* play) { + ObjTakarayaWall* this = THIS; + Actor* chest; + s32 column; + s32 i; + s32 j; + + Actor_ProcessInitChain(&this->actor, sInitChain); + + for (i = 0; i < TAKARAYA_WALL_ROWS; i++) { + for (j = 0; j < TAKARAYA_WALL_COLUMNS; j++) { + sTakarayaWallHeights[i][j] = 0.0f; + } + } + + Collider_InitAndSetCylinder(play, &this->columnCollider, &this->actor, &sCylinderInit); + Collider_InitAndSetCylinder(play, &this->rowCollider, &this->actor, &sCylinderInit); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + + column = (s32)Rand_ZeroFloat(TAKARAYA_WALL_COLUMNS) % TAKARAYA_WALL_COLUMNS; + chest = Actor_SpawnAsChildAndCutscene(&play->actorCtx, play, ACTOR_EN_BOX, -1635.0f, 0.0f, (column * 120) + 60, 0, + 0x4000, this->actor.shape.rot.z, this->actor.params, this->actor.csId, + HALFDAYBIT_ALL, NULL); + Flags_SetSwitch(play, TAKARAYA_WALL_GET_SWTICH_FLAG(&this->actor)); + this->actor.shape.rot.z = 0; + + if (chest != NULL) { + chest->uncullZoneForward = 2000.0f; + } + + sTakarayaWallHeights[0][column] = -10.0f; + sTakarayaWallPathStack[sTakarayaWallPathStackDepth].row = 0; + sTakarayaWallPathStack[sTakarayaWallPathStackDepth].column = column; + sTakarayaWallPathStackDepth++; + sTakarayaWallSuccessfulPathStackDepth++; + + do { + ObjTakarayaWall_CarvePath(sTakarayaWallPathStack[sTakarayaWallPathStackDepth - 1].row, + sTakarayaWallPathStack[sTakarayaWallPathStackDepth - 1].column); + } while (sTakarayaWallPathStackDepth > 1); + + for (j = 1; j < TAKARAYA_WALL_COLUMNS - 1; j++) { + if (sTakarayaWallHeights[TAKARAYA_WALL_ROWS - 1][j] == -10.0f) { + break; + } + } + + // If either corner in the front is part of the success path, and there is no other opening in the front, + // open up the space next to the open corner since the Treasure Chest Shop scene blocks direct access to the + // front corners. + if (j == (TAKARAYA_WALL_COLUMNS - 1)) { + if (sTakarayaWallHeights[TAKARAYA_WALL_ROWS - 1][0] == -10.0f) { + sTakarayaWallHeights[TAKARAYA_WALL_ROWS - 1][1] = -10.0f; + } else { + sTakarayaWallHeights[TAKARAYA_WALL_ROWS - 1][TAKARAYA_WALL_COLUMNS - 2] = -10.0f; + } + } + + this->actionFunc = ObjTakarayaWall_Manage; +} + +void ObjTakarayaWall_Destroy(Actor* thisx, PlayState* play) { + ObjTakarayaWall* this = THIS; + s32 i; + s32 j; + + Collider_DestroyCylinder(play, &this->columnCollider); + Collider_DestroyCylinder(play, &this->rowCollider); + + for (i = 0; i < TAKARAYA_WALL_ROWS; i++) { + for (j = 0; j < TAKARAYA_WALL_COLUMNS; j++) { + AudioSfx_StopByPos(&sTakarayaWallAudioPositions[i][j]); + } + } +} + +void ObjTakarayaWall_Manage(ObjTakarayaWall* this, PlayState* play) { + Player* player = GET_PLAYER(play); + ColliderCylinder* collider; + s32 playerRowBehind; + s32 playerRow; + s32 playerColumn; + s32 columnColliderActive; + s32 rowColliderActive; + s32 playerCellXPos; + s32 playerCellZPos; + s32 i; + s32 j; + s32 playerColumnRight; + s32 playerColumnLeft; + s32 playerRowInFront; + + rowColliderActive = false; + columnColliderActive = false; + playerRowBehind = playerRowInFront = -1; + playerColumnLeft = playerColumnRight = -1; + + ObjTakarayaWall_PosToCell(&player->actor.world.pos, &playerRow, &playerColumn); + playerCellXPos = (((s32)player->actor.world.pos.x - -1800) % 120) - 60; + playerCellZPos = (((s32)player->actor.world.pos.z - -120) % 120) - 60; + + if (playerCellXPos > 20) { + playerRowBehind = playerRow + 1; + } else if (playerCellXPos < -20) { + playerRowInFront = playerRow - 1; + } + + if (playerCellZPos > 20) { + playerColumnLeft = playerColumn + 1; + } else if (playerCellZPos < -20) { + playerColumnRight = playerColumn - 1; + } + + for (i = 0; i < TAKARAYA_WALL_ROWS; i++) { + for (j = 0; j < TAKARAYA_WALL_COLUMNS; j++) { + if (sTakarayaWallHeights[i][j] >= 0.0f) { + if (((j == playerColumn) && ((i == playerRowInFront) || (i == playerRowBehind))) || + ((i == playerRow) && ((j == playerColumnRight) || (j == playerColumnLeft)))) { + if (Math_StepToF(&sTakarayaWallHeights[i][j], 120.0f, 15.0f)) { + sTakarayaWallStates[i][j] = TAKARAYA_WALL_INACTIVE; + } else { + sTakarayaWallStates[i][j] = TAKARAYA_WALL_RISING; + } + if (j == playerColumn) { + columnColliderActive = true; + } else if (i == playerRow) { + rowColliderActive = true; + } + } else if ((i != playerRow) || (j != playerColumn)) { + Math_SmoothStepToF(&sTakarayaWallHeights[i][j], 0.0f, 0.2f, 5.0f, 1.0f); + sTakarayaWallStates[i][j] = TAKARAYA_WALL_FALLING; + } + } + } + } + + collider = &this->columnCollider; + collider->dim.radius = 200; + if (!columnColliderActive) { + collider->dim.pos.y = (s32)this->actor.world.pos.y - 240; + } else { + collider->dim.pos.y = (s32)this->actor.world.pos.y; + collider->dim.pos.z = (s32)player->actor.world.pos.z; + if (playerCellXPos > 0) { + collider->dim.pos.x = ((((s32)player->actor.world.pos.x - -1680) / 120) * 120) - 1380; + } else { + collider->dim.pos.x = ((((s32)player->actor.world.pos.x - -1680) / 120) * 120) - 1860; + } + } + + collider = &this->rowCollider; + collider->dim.radius = 200; + if (!rowColliderActive) { + collider->dim.pos.y = (s32)this->actor.world.pos.y - 240; + } else { + collider->dim.pos.y = (s32)this->actor.world.pos.y; + collider->dim.pos.x = (s32)player->actor.world.pos.x; + if (playerCellZPos > 0) { + collider->dim.pos.z = (((s32)player->actor.world.pos.z / 120) * 120) + 300; + } else { + collider->dim.pos.z = (((s32)player->actor.world.pos.z / 120) * 120) - 180; + } + } +} + +void ObjTakarayaWall_Update(Actor* thisx, PlayState* play2) { + PlayState* play = play2; + ObjTakarayaWall* this = THIS; + + this->actionFunc(this, play); + + CollisionCheck_SetOC(play, &play->colChkCtx, &this->columnCollider.base); + CollisionCheck_SetOC(play, &play->colChkCtx, &this->rowCollider.base); +} + +void ObjTakarayaWall_Draw(Actor* thisx, PlayState* play) { + Vec3f audioPos; + ObjTakarayaWall* this = THIS; + MtxF* mtx; + Gfx* gfx; + s32 i; + s32 j; + + OPEN_DISPS(play->state.gfxCtx); + + mtx = Matrix_GetCurrent(); + + gfx = POLY_OPA_DISP; + gSPDisplayList(gfx++, gSetupDLs[SETUPDL_25]); + gDPSetPrimColor(gfx++, 0, 0, 255, 255, 255, 255); + + for (i = 0; i < TAKARAYA_WALL_ROWS; i++) { + for (j = 0; j < TAKARAYA_WALL_COLUMNS; j++) { + if (sTakarayaWallHeights[i][j] > 0.0f) { + mtx->xw = (i * 120) - 1620; + mtx->yw = sTakarayaWallHeights[i][j] + (this->actor.world.pos.y - 120.0f); + mtx->zw = (j * 120) + 60; + + gSPMatrix(gfx++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (((i + j) % 2) != 0) { + gSPDisplayList(gfx++, gTreasureChestShopWallWhiteDL); + } else { + gSPDisplayList(gfx++, gTreasureChestShopWallBlackDL); + } + + if (sTakarayaWallStates[i][j] != TAKARAYA_WALL_INACTIVE) { + audioPos.x = mtx->xw; + audioPos.y = mtx->yw; + audioPos.z = mtx->zw; + + SkinMatrix_Vec3fMtxFMultXYZ(&play->viewProjectionMtxF, &audioPos, + &sTakarayaWallAudioPositions[i][j]); + + if (sTakarayaWallStates[i][j] == TAKARAYA_WALL_RISING) { + Audio_PlaySfx_AtPos(&sTakarayaWallAudioPositions[i][j], NA_SE_EV_ROCK_CUBE_RISING - SFX_FLAG); + } else { // TAKARAYA_WALL_FALLING + Audio_PlaySfx_AtPos(&sTakarayaWallAudioPositions[i][j], NA_SE_EV_ROCK_CUBE_FALL - SFX_FLAG); + } + } + } + } + } + + POLY_OPA_DISP = gfx; + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h index 225e265122..b9897d655a 100644 --- a/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h +++ b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h @@ -5,12 +5,15 @@ struct ObjTakarayaWall; +#define TAKARAYA_WALL_GET_SWTICH_FLAG(thisx) ((thisx)->shape.rot.z) + typedef void (*ObjTakarayaWallActionFunc)(struct ObjTakarayaWall*, PlayState*); typedef struct ObjTakarayaWall { /* 0x000 */ Actor actor; /* 0x144 */ ObjTakarayaWallActionFunc actionFunc; - /* 0x148 */ char unk_148[0x98]; + /* 0x148 */ ColliderCylinder columnCollider; + /* 0x194 */ ColliderCylinder rowCollider; } ObjTakarayaWall; // size = 0x1E0 #endif // Z_OBJ_TAKARAYA_WALL_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index 78775d9e2a..78cb49b61c 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -12278,13 +12278,13 @@ 0x80AD8BC0:("EnKame_Draw",), 0x80AD8CEC:("EnKame_SpikedSnapperOverrideLimbDraw",), 0x80AD8D64:("EnKame_DrawSpikedSnapper",), - 0x80AD9240:("func_80AD9240",), - 0x80AD92FC:("func_80AD92FC",), - 0x80AD9358:("func_80AD9358",), - 0x80AD9488:("func_80AD9488",), + 0x80AD9240:("ObjTakarayaWall_PosToCell",), + 0x80AD92FC:("ObjTakarayaWall_IsCellOpen",), + 0x80AD9358:("ObjTakarayaWall_CanCarvePath",), + 0x80AD9488:("ObjTakarayaWall_CarvePath",), 0x80AD97DC:("ObjTakarayaWall_Init",), 0x80AD9A6C:("ObjTakarayaWall_Destroy",), - 0x80AD9B04:("func_80AD9B04",), + 0x80AD9B04:("ObjTakarayaWall_Manage",), 0x80AD9F90:("ObjTakarayaWall_Update",), 0x80AD9FF8:("ObjTakarayaWall_Draw",), 0x80ADAAF0:("BgFuMizu_Init",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index b1e1a8b2ea..05ae147913 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -12970,18 +12970,13 @@ 0x80ADA2A0:("D_80ADA2A0","UNK_TYPE1","",0x1), 0x80ADA2CC:("D_80ADA2CC","UNK_TYPE1","",0x1), 0x80ADA2D0:("D_80ADA2D0","f32","",0x4), - 0x80ADA450:("D_80ADA450","UNK_TYPE4","",0x4), - 0x80ADA458:("D_80ADA458","UNK_TYPE1","",0x1), - 0x80ADA508:("D_80ADA508","UNK_TYPE4","",0x4), - 0x80ADA50C:("D_80ADA50C","UNK_TYPE4","",0x4), - 0x80ADA510:("D_80ADA510","UNK_TYPE1","",0x1), - 0x80ADA930:("D_80ADA930","UNK_TYPE1","",0x1), - 0x80ADA988:("D_80ADA988","f32","",0x4), - 0x80ADA98C:("D_80ADA98C","UNK_TYPE4","",0x4), - 0x80ADA9A4:("D_80ADA9A4","UNK_TYPE4","",0x4), - 0x80ADAAC8:("D_80ADAAC8","f32","",0x4), - 0x80ADAACC:("D_80ADAACC","f32","",0x4), - 0x80ADAAE0:("D_80ADAAE0","f32","",0x4), + 0x80ADA450:("sTakarayaWallPathStackDepth","UNK_TYPE4","",0x4), + 0x80ADA458:("sTakarayaWallPathStack","UNK_TYPE1","",0x1), + 0x80ADA508:("sTakarayaWallSuccessfulPathStackDepth","UNK_TYPE4","",0x4), + 0x80ADA50C:("sTakarayaWallPathReachedFront","UNK_TYPE4","",0x4), + 0x80ADA510:("sTakarayaWallAudioPositions","UNK_TYPE1","",0x1), + 0x80ADA930:("sTakarayaWallStates","UNK_TYPE1","",0x1), + 0x80ADA988:("sTakarayaWallHeights","f32","",0x160), 0x80ADAAE8:("D_80ADAAE8","UNK_TYPE1","",0x1), 0x80ADAD80:("Bg_Fu_Mizu_InitVars","UNK_TYPE1","",0x1), 0x80ADD910:("D_80ADD910","UNK_TYPE1","",0x1), diff --git a/undefined_syms.txt b/undefined_syms.txt index cc6a29ebf6..c3b6862a00 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -503,15 +503,6 @@ D_06006F38 = 0x06006F38; D_06006FD8 = 0x06006FD8; D_06009930 = 0x06009930; -// ovl_En_Takaraya - -D_06000968 = 0x06000968; -D_06001384 = 0x06001384; -D_06008FC8 = 0x06008FC8; -D_06009890 = 0x06009890; -D_0600A280 = 0x0600A280; -D_0600AD98 = 0x0600AD98; - // ovl_En_Wdhand D_060000F4 = 0x060000F4; @@ -537,11 +528,6 @@ D_06000030 = 0x06000030; D_06002068 = 0x06002068; D_06002188 = 0x06002188; -// ovl_Obj_Takaraya_Wall - -D_06000B70 = 0x06000B70; -D_06000D60 = 0x06000D60; - // segment 0x07 // segment 0x08