summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com>2020-12-06 18:48:51 +0000
committerGitHub <noreply@github.com>2020-12-06 13:48:51 -0500
commitdadee87f9423fd7b06ec088bf4bde5f768598d3c (patch)
treeb2fc154fc398997ec558ef4917ae4536b7aa2114 /src
parentb097c58cafd8e2644a0589144c061b0afa6ab573 (diff)
Bombchu bowling OK (#496)
* All functions decompiled, most named * asm deleted, spec and undefined_syms included * missed a static * Some cleanup on comments and osSyncPrintfs * asm Co-authored-by: fig02 <fig02srl@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/code/z_vr_box_draw.c6
-rw-r--r--src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.c2
-rw-r--r--src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.c206
-rw-r--r--src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.h7
-rw-r--r--src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c2
-rw-r--r--src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c500
-rw-r--r--src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h32
-rw-r--r--src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c205
-rw-r--r--src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h26
-rw-r--r--src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h6
-rw-r--r--src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h4
-rw-r--r--src/overlays/actors/ovl_En_Rd/z_en_rd.c2
-rw-r--r--src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c134
-rw-r--r--src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.h9
-rw-r--r--src/overlays/actors/ovl_En_Zl1/z_en_zl1.c2
-rw-r--r--src/overlays/actors/ovl_En_Zl3/z_en_zl3.c8
16 files changed, 1072 insertions, 79 deletions
diff --git a/src/code/z_vr_box_draw.c b/src/code/z_vr_box_draw.c
index 90b7b2d9b..a7677c15f 100644
--- a/src/code/z_vr_box_draw.c
+++ b/src/code/z_vr_box_draw.c
@@ -16,9 +16,9 @@ void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyb
func_800945A0(gfxCtx);
- gSPSegment(POLY_OPA_DISP++, 7, skyboxCtx->staticSegments[0]);
- gSPSegment(POLY_OPA_DISP++, 8, skyboxCtx->staticSegments[1]);
- gSPSegment(POLY_OPA_DISP++, 9, skyboxCtx->staticSegments[2]);
+ gSPSegment(POLY_OPA_DISP++, 0x7, skyboxCtx->staticSegments[0]);
+ gSPSegment(POLY_OPA_DISP++, 0x8, skyboxCtx->staticSegments[1]);
+ gSPSegment(POLY_OPA_DISP++, 0x9, skyboxCtx->staticSegments[2]);
gDPSetPrimColor(POLY_OPA_DISP++, 0x00, 0x00, 0, 0, 0, alpha);
gSPTexture(POLY_OPA_DISP++, 0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON);
diff --git a/src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.c b/src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.c
index 573f6b152..902ca6dad 100644
--- a/src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.c
+++ b/src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.c
@@ -69,7 +69,7 @@ void func_8086E638(BgBomGuard* this, GlobalContext* globalCtx) {
while (it != 0) {
if (it->id == ACTOR_EN_BOM_BOWL_MAN) {
- if ((((EnBomBowlMan*)it)->unk_258 != 0) && (fabsf(globalCtx->view.eye.x) > -20.0f) &&
+ if ((((EnBomBowlMan*)it)->minigamePlayStatus != 0) && (fabsf(globalCtx->view.eye.x) > -20.0f) &&
(fabsf(globalCtx->view.eye.y) > 110.0f)) {
this->unk_168 = 1;
}
diff --git a/src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.c b/src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.c
index d6570d91a..84bf54f07 100644
--- a/src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.c
+++ b/src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.c
@@ -5,6 +5,9 @@
*/
#include "z_bg_bowl_wall.h"
+#include "vt.h"
+#include "overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.h"
+#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#define FLAGS 0x00000030
@@ -15,13 +18,17 @@ void BgBowlWall_Destroy(Actor* thisx, GlobalContext* globalCtx);
void BgBowlWall_Update(Actor* thisx, GlobalContext* globalCtx);
void BgBowlWall_Draw(Actor* thisx, GlobalContext* globalCtx);
-void func_8086F260(BgBowlWall* this, GlobalContext* globalCtx);
-void func_8086F440(BgBowlWall* this, GlobalContext* globalCtx);
-void func_8086F464(BgBowlWall* this, GlobalContext* globalCtx);
-void func_8086F718(BgBowlWall* this, GlobalContext* globalCtx);
-void func_8086F7F8(BgBowlWall* this, GlobalContext* globalCtx);
+void BgBowlWall_SpawnBullseyes(BgBowlWall* this, GlobalContext* globalCtx);
+void BgBowlWall_WaitForHit(BgBowlWall* this, GlobalContext* globalCtx);
+void BgBowlWall_FallDoEffects(BgBowlWall* this, GlobalContext* globalCtx);
+void BgBowlWall_FinishFall(BgBowlWall* this, GlobalContext* globalCtx);
+void BgBowlWall_Reset(BgBowlWall* this, GlobalContext* globalCtx);
+
+extern ColHeader D_06000CB8;
+extern ColHeader D_06001B00;
+extern Gfx D_06000610[];
+extern Gfx D_06001390[];
-/*
const ActorInit Bg_Bowl_Wall_InitVars = {
ACTOR_BG_BOWL_WALL,
ACTORTYPE_PROP,
@@ -33,21 +40,188 @@ const ActorInit Bg_Bowl_Wall_InitVars = {
(ActorFunc)BgBowlWall_Update,
(ActorFunc)BgBowlWall_Draw,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/BgBowlWall_Init.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/BgBowlWall_Destroy.s")
+static Vec3f sBullseyeOffset[] = {
+ { 0.0f, 210.0f, -20.0f },
+ { 0.0f, 170.0f, -20.0f },
+ { -170.0f, 0.0f, -20.0f },
+ { 170.0f, 0.0f, -20.0f },
+};
+
+static s16 sTargetRot[] = { 0x0000, 0x0000, 0x3FFF, -0x3FFF };
+
+void BgBowlWall_Init(Actor* thisx, GlobalContext* globalCtx) {
+ BgBowlWall* this = THIS;
+ s32 pad1;
+ s32 pad2;
+ ColHeader* colHeader = NULL;
+
+ DynaPolyInfo_SetActorMove(&this->dyna, 0);
+
+ if (this->dyna.actor.params == 0) {
+ DynaPolyInfo_Alloc(&D_06000CB8, &colHeader);
+ } else {
+ DynaPolyInfo_Alloc(&D_06001B00, &colHeader);
+ }
+
+ this->dyna.dynaPolyId =
+ DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
+ this->initPos = this->dyna.actor.posRot.pos;
+ osSyncPrintf("\n\n");
+ osSyncPrintf(VT_FGCOL(GREEN) " ☆☆☆☆☆ ボーリングおじゃま壁発生 ☆☆☆☆☆ %d\n" VT_RST, this->dyna.actor.params);
+ this->actionFunc = BgBowlWall_SpawnBullseyes;
+ this->dyna.actor.scale.x = this->dyna.actor.scale.y = this->dyna.actor.scale.z = 1.0f;
+}
+
+void BgBowlWall_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ BgBowlWall* this = THIS;
+
+ DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
+}
+
+void BgBowlWall_SpawnBullseyes(BgBowlWall* this, GlobalContext* globalCtx) {
+ s32 pad;
+ EnWallTubo* bullseye;
+ Actor* lookForGirl;
+ s16 type;
+
+ type = this->dyna.actor.params;
+ if (type != 0) {
+ type += (s16)Math_Rand_ZeroFloat(2.99f);
+ this->dyna.actor.shape.rot.z = this->dyna.actor.posRot.rot.z = sTargetRot[type];
+ osSyncPrintf("\n\n");
+ }
+ this->bullseyeCenter.x = sBullseyeOffset[type].x + this->dyna.actor.posRot.pos.x;
+ this->bullseyeCenter.y = sBullseyeOffset[type].y + this->dyna.actor.posRot.pos.y;
+ this->bullseyeCenter.z = sBullseyeOffset[type].z + this->dyna.actor.posRot.pos.z;
+ if (1) {}
+ bullseye = (EnWallTubo*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_EN_WALL_TUBO,
+ this->bullseyeCenter.x, this->bullseyeCenter.y, this->bullseyeCenter.z,
+ 0, 0, 0, this->dyna.actor.params);
+ if (bullseye != NULL) {
+ bullseye->explosionCenter = this->bullseyeCenter;
+ if (type != 0) {
+ bullseye->explosionCenter = this->bullseyeCenter = this->dyna.actor.posRot.pos;
+ }
+ if (this->chuGirl == NULL) {
+ lookForGirl = globalCtx->actorCtx.actorList[ACTORTYPE_NPC].first;
+ while (lookForGirl != NULL) {
+ if (lookForGirl->id != ACTOR_EN_BOM_BOWL_MAN) {
+ lookForGirl = lookForGirl->next;
+ } else {
+ this->chuGirl = (EnBomBowlMan*)lookForGirl;
+ break;
+ }
+ }
+ }
+ this->actionFunc = BgBowlWall_WaitForHit;
+ }
+}
+
+void BgBowlWall_WaitForHit(BgBowlWall* this, GlobalContext* globalCtx) {
+ if (this->isHit) {
+ this->actionFunc = BgBowlWall_FallDoEffects;
+ }
+}
+
+void BgBowlWall_FallDoEffects(BgBowlWall* this, GlobalContext* globalCtx) {
+ s16 pad;
+ Vec3f effectAccel = { 0.0f, 0.1f, 0.0f };
+ Vec3f effectVelocity = { 0.0f, 0.0f, 0.0f };
+ Vec3f effectPos;
+ s16 quakeIndex;
+ s32 wallFallen;
+ s32 i;
+
+ wallFallen = false;
+
+ if (this->dyna.actor.params == 0) { // wall collapses backwards
+ Math_SmoothScaleMaxMinS(&this->dyna.actor.shape.rot.x, -0x3E80, 3, 500, 0);
+ this->dyna.actor.posRot.rot.x = this->dyna.actor.shape.rot.x;
+ if (this->dyna.actor.shape.rot.x < -0x3C1E) {
+ wallFallen = true;
+ }
+ } else { // wall slides downwards
+ Math_SmoothScaleMaxF(&this->dyna.actor.posRot.pos.y, this->initPos.y - 450.0f, 0.3f, 10.0f);
+ if (this->dyna.actor.posRot.pos.y < (this->initPos.y - 400.0f)) {
+ wallFallen = true;
+ }
+ }
+
+ if (wallFallen) {
+ for (i = 0; i < 15; i++) {
+ effectPos.x = Math_Rand_CenteredFloat(300.0f) + this->bullseyeCenter.x;
+ effectPos.y = -100.0f;
+ effectPos.z = Math_Rand_CenteredFloat(400.0f) + this->bullseyeCenter.z;
+ EffectSsBomb2_SpawnLayered(globalCtx, &effectPos, &effectVelocity, &effectAccel, 100, 30);
+ effectPos.y = -50.0f;
+ EffectSsHahen_SpawnBurst(globalCtx, &effectPos, 10.0f, 0, 50, 15, 3, HAHEN_OBJECT_DEFAULT, 10, NULL);
+ Audio_PlayActorSound2(&this->dyna.actor, NA_SE_IT_BOMB_EXPLOSION);
+ }
+ quakeIndex = Quake_Add(ACTIVE_CAM, 1);
+ Quake_SetSpeed(quakeIndex, 0x7FFF);
+ Quake_SetQuakeValues(quakeIndex, 300, 0, 0, 0);
+ Quake_SetCountdown(quakeIndex, 30);
+ this->timer = 20;
+ this->actionFunc = BgBowlWall_FinishFall;
+ }
+}
+
+void BgBowlWall_FinishFall(BgBowlWall* this, GlobalContext* globalCtx) {
+ if (this->timer >= 2) {
+ if (this->dyna.actor.params == 0) {
+ Math_SmoothScaleMaxMinS(&this->dyna.actor.shape.rot.x, -0x3E80, 1, 200, 0);
+ } else {
+ Math_SmoothScaleMaxF(&this->dyna.actor.posRot.pos.y, this->initPos.y - 450.0f, 0.3f, 10.0f);
+ }
+ } else if (this->timer == 1) {
+ this->dyna.actor.posRot.rot.x = this->dyna.actor.shape.rot.x = 0;
+ this->dyna.actor.posRot.pos.y = this->initPos.y - 450.0f;
+ this->chuGirl->wallStatus[this->dyna.actor.params] = 2;
+ this->actionFunc = BgBowlWall_Reset;
+ }
+}
+
+void BgBowlWall_Reset(BgBowlWall* this, GlobalContext* globalCtx) {
+ if (this->chuGirl->wallStatus[this->dyna.actor.params] != 2) {
+ Math_SmoothScaleMaxF(&this->dyna.actor.posRot.pos.y, this->initPos.y, 0.3f, 50.0f);
+ if (fabsf(this->dyna.actor.posRot.pos.y - this->initPos.y) <= 10.0f) {
+ this->dyna.actor.posRot.pos.y = this->initPos.y;
+ this->isHit = false;
+ this->actionFunc = BgBowlWall_SpawnBullseyes;
+ }
+ }
+}
+
+void BgBowlWall_Update(Actor* thisx, GlobalContext* globalCtx) {
+ BgBowlWall* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F260.s")
+ if (this->timer != 0) {
+ this->timer--;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F440.s")
+ this->actionFunc(this, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F464.s")
+void BgBowlWall_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ GlobalContext* globalCtx2 = globalCtx;
+ BgBowlWall* this = THIS;
+ u32 frames;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F718.s")
+ OPEN_DISPS(globalCtx2->state.gfxCtx, "../z_bg_bowl_wall.c", 441);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F7F8.s")
+ func_80093D84(globalCtx2->state.gfxCtx);
+ gSPSegment(POLY_OPA_DISP++, 0x8,
+ Gfx_TexScroll(globalCtx2->state.gfxCtx, 0, -2 * (frames = globalCtx2->state.frames), 16, 16));
+ gDPPipeSync(POLY_OPA_DISP++);
+ gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx2->state.gfxCtx, "../z_bg_bowl_wall.c", 453),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/BgBowlWall_Update.s")
+ if (this->dyna.actor.params == 0) {
+ gSPDisplayList(POLY_OPA_DISP++, D_06000610);
+ } else {
+ gSPDisplayList(POLY_OPA_DISP++, D_06001390);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/BgBowlWall_Draw.s")
+ CLOSE_DISPS(globalCtx2->state.gfxCtx, "../z_bg_bowl_wall.c", 464);
+}
diff --git a/src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.h b/src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.h
index d2cd7197a..913687778 100644
--- a/src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.h
+++ b/src/overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.h
@@ -3,6 +3,7 @@
#include "ultra64.h"
#include "global.h"
+#include "overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h"
struct BgBowlWall;
@@ -11,7 +12,11 @@ typedef void (*BgBowlWallActionFunc)(struct BgBowlWall*, GlobalContext*);
typedef struct BgBowlWall {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ BgBowlWallActionFunc actionFunc;
- /* 0x0168 */ char unk_168[0x20];
+ /* 0x0168 */ Vec3f initPos;
+ /* 0x0174 */ Vec3f bullseyeCenter;
+ /* 0x0180 */ s16 isHit;
+ /* 0x0182 */ s16 timer;
+ /* 0x0184 */ EnBomBowlMan* chuGirl;
} BgBowlWall; // size = 0x0188
extern const ActorInit Bg_Bowl_Wall_InitVars;
diff --git a/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c b/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c
index b381b8c38..4ad7d474e 100644
--- a/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c
+++ b/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c
@@ -103,7 +103,7 @@ void DemoShd_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
u32 unk_14E = this->unk_14E;
- if (1) {}; // Necessary to match, can be anywhere in the function
+ if (1) {} // Necessary to match, can be anywhere in the function
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_demo_shd.c", 726);
diff --git a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c
index 5828f505e..39032cacc 100644
--- a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c
+++ b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c
@@ -1,15 +1,44 @@
#include "z_en_bom_bowl_man.h"
+#include "vt.h"
+#include "overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.h"
#define FLAGS 0x08000039
#define THIS ((EnBomBowlMan*)thisx)
+typedef enum {
+ /* 0 */ CHU_GIRL_EYES_ASLEEP,
+ /* 1 */ CHU_GIRL_EYES_OPEN_SLOWLY,
+ /* 2 */ CHU_GIRL_EYES_BLINK_RAPIDLY,
+ /* 3 */ CHU_GIRL_EYES_AWAKE
+} BombchuGirlEyeMode;
+
void EnBomBowlMan_Init(Actor* thisx, GlobalContext* globalCtx);
void EnBomBowlMan_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnBomBowlMan_Update(Actor* thisx, GlobalContext* globalCtx);
void EnBomBowlMan_Draw(Actor* thisx, GlobalContext* globalCtx);
-/*
+void EnBomBowMan_SetupWaitAsleep(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_WaitAsleep(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_TalkAsleep(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_WakeUp(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_BlinkAwake(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_CheckBeatenDC(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_WaitNotBeatenDC(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_TalkNotBeatenDC(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_SetupRunGame(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_RunGame(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowlMan_HandlePlayChoice(EnBomBowlMan* this, GlobalContext* globalCtx);
+void func_809C41FC(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_SetupChooseShowPrize(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowMan_ChooseShowPrize(EnBomBowlMan* this, GlobalContext* globalCtx);
+void EnBomBowlMan_BeginPlayGame(EnBomBowlMan* this, GlobalContext* globalCtx);
+
+extern FlexSkeletonHeader D_06006EB0;
+extern AnimationHeader D_06000710;
+extern AnimationHeader D_06000080;
+extern AnimationHeader D_060072AC;
+
const ActorInit En_Bom_Bowl_Man_InitVars = {
ACTOR_EN_BOM_BOWL_MAN,
ACTORTYPE_NPC,
@@ -21,43 +50,470 @@ const ActorInit En_Bom_Bowl_Man_InitVars = {
(ActorFunc)EnBomBowlMan_Update,
(ActorFunc)EnBomBowlMan_Draw,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Init.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Destroy.s")
+void EnBomBowlMan_Init(Actor* thisx, GlobalContext* globalCtx) {
+ static f32 cuccoColliderDims[][3] = { { 16.0f, 46.0f, 0.0f }, { 36.0f, 56.0f, 0.0f } };
+ static Vec3f cuccoSpawnPos[] = { { 60, -60, -430 }, { 0, -120, -620 } };
+ static f32 cuccoScales[] = { 0.01f, 0.03f };
+ EnBomBowlMan* this = THIS;
+ EnSyatekiNiw* cucco;
+ s32 i;
+ GlobalContext* globalCtx2 = globalCtx;
+
+ ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFunc_Circle, 30.0f);
+ SkelAnime_InitFlex(globalCtx2, &this->skelAnime, &D_06006EB0, &D_06000710, this->limbDrawTable,
+ this->transitionDrawTable, 11);
+ // ☆ Man, my shoulders hurt~ ☆
+ osSyncPrintf(VT_FGCOL(GREEN) "☆ もー 肩こっちゃうよねぇ〜 \t\t ☆ \n" VT_RST);
+ // ☆ Isn't there some sort of job that will pay better and be more relaxing? ☆ %d
+ osSyncPrintf(VT_FGCOL(GREEN) "☆ もっとラクしてもうかるバイトないかしら? ☆ %d\n" VT_RST,
+ globalCtx2->bombchuBowlingAmmo);
+ this->posCopy = this->actor.posRot.pos;
+ this->actor.shape.unk_08 = -60.0f;
+ Actor_SetScale(&this->actor, 0.013f);
+
+ for (i = 0; i < 2; i++) {
+ cucco = (EnSyatekiNiw*)Actor_Spawn(&globalCtx2->actorCtx, globalCtx2, ACTOR_EN_SYATEKI_NIW, cuccoSpawnPos[i].x,
+ cuccoSpawnPos[i].y, cuccoSpawnPos[i].z, 0, 0, 0, 1);
+ if (cucco != NULL) {
+ cucco->unk_2F4 = cuccoScales[i];
+ cucco->collider.dim.radius = (s16)cuccoColliderDims[i][0];
+ cucco->collider.dim.height = (s16)cuccoColliderDims[i][1];
+ }
+ }
+
+ this->prizeSelect = (s16)Math_Rand_ZeroFloat(4.99f);
+ this->actor.unk_1F = 1;
+ this->actionFunc = EnBomBowMan_SetupWaitAsleep;
+}
+
+void EnBomBowlMan_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+}
+
+void EnBomBowMan_SetupWaitAsleep(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ this->frameCount = (f32)SkelAnime_GetFrameCount(&D_06000710);
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_06000710, 1.0f, 0.0f, this->frameCount, 0, -10.0f);
+ this->actor.textId = 0xC0;
+ this->dialogState = 5;
+ this->actionFunc = EnBomBowMan_WaitAsleep;
+}
+
+void EnBomBowMan_WaitAsleep(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ s16 yawDiff;
+
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+
+ if (func_8002F194(&this->actor, globalCtx)) {
+ this->actionFunc = EnBomBowMan_TalkAsleep;
+ } else {
+ yawDiff = ABS((s16)(this->actor.yawTowardsLink - this->actor.shape.rot.y));
+
+ if (!(this->actor.xzDistFromLink > 120.0f) && (yawDiff < 0x4300)) {
+ func_8002F2CC(&this->actor, globalCtx, 120.0f);
+ }
+ }
+}
+
+void EnBomBowMan_TalkAsleep(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+
+ if ((func_8010BDBC(&globalCtx->msgCtx) == this->dialogState) && (func_80106BC8(globalCtx) != 0)) {
+ globalCtx->msgCtx.msgMode = 0x37;
+ this->actionFunc = EnBomBowMan_WakeUp;
+ }
+}
+
+void EnBomBowMan_WakeUp(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ this->frameCount = (f32)SkelAnime_GetFrameCount(&D_06000080);
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_06000080, 1.0f, 0.0f, this->frameCount, 2, -10.0f);
+ this->eyeMode = CHU_GIRL_EYES_OPEN_SLOWLY;
+ this->actionFunc = EnBomBowMan_BlinkAwake;
+}
+
+void EnBomBowMan_BlinkAwake(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ f32 frameCount = this->skelAnime.animCurrentFrame;
+
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if (frameCount == 30.0f) {
+ this->dialogState = 5;
+ // Check for beaten Dodongo's Cavern
+ if ((gSaveContext.eventChkInf[2] & 0x20) || BREG(2)) {
+ this->actor.textId = 0xBF;
+ } else {
+ this->actor.textId = 0x7058;
+ }
+ }
+ func_8010B720(globalCtx, this->actor.textId);
+
+ if ((this->eyeTextureIndex == 0) && (this->eyeMode == CHU_GIRL_EYES_BLINK_RAPIDLY) && (this->blinkTimer == 0)) {
+ // Blink twice, then move on
+ this->eyeTextureIndex = 2;
+ this->blinkCount++;
+ if (this->blinkCount >= 3) {
+ this->actionFunc = EnBomBowMan_CheckBeatenDC;
+ }
+ }
+}
+
+void EnBomBowMan_CheckBeatenDC(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+
+ if ((func_8010BDBC(&globalCtx->msgCtx) == this->dialogState) && (func_80106BC8(globalCtx) != 0)) {
+ func_80106CCC(globalCtx);
+ this->frameCount = (f32)SkelAnime_GetFrameCount(&D_060072AC);
+ SkelAnime_ChangeAnim(&this->skelAnime, &D_060072AC, 1.0f, 0.0f, this->frameCount, 0, -10.0f);
+ this->eyeMode = CHU_GIRL_EYES_AWAKE;
+ this->blinkTimer = (s16)Math_Rand_ZeroFloat(60.0f) + 20;
+ // Check for beaten Dodongo's Cavern
+ if (!((gSaveContext.eventChkInf[2] & 0x20) || BREG(2))) {
+ this->actionFunc = EnBomBowMan_WaitNotBeatenDC;
+ } else {
+ this->actor.textId = 0x18;
+ this->dialogState = 4;
+ func_8010B720(globalCtx, this->actor.textId);
+ this->actionFunc = EnBomBowlMan_HandlePlayChoice;
+ }
+ }
+}
+
+void EnBomBowMan_WaitNotBeatenDC(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+
+ if (func_8002F194(&this->actor, globalCtx)) {
+ this->actionFunc = EnBomBowMan_TalkNotBeatenDC;
+ } else {
+ func_8002F2CC(&this->actor, globalCtx, 120.0f);
+ }
+}
+
+void EnBomBowMan_TalkNotBeatenDC(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+
+ if ((func_8010BDBC(&globalCtx->msgCtx) == this->dialogState) && (func_80106BC8(globalCtx) != 0)) {
+ func_80106CCC(globalCtx);
+ this->actionFunc = EnBomBowMan_WaitNotBeatenDC;
+ }
+}
+
+void EnBomBowMan_SetupRunGame(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+
+ if (this->minigamePlayStatus == 0) {
+ if (!this->startedPlaying) {
+ this->actor.textId = 0x18;
+ } else {
+ this->actor.textId = 0x1A;
+ }
+ this->dialogState = 4;
+ } else {
+ this->actor.textId = 0x19;
+ this->dialogState = 5;
+ }
+ this->actionFunc = EnBomBowMan_RunGame;
+}
+
+void EnBomBowMan_RunGame(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ s16 yawDiff;
+
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+
+ if (BREG(3)) {
+ osSyncPrintf(VT_FGCOL(RED) "☆ game_play->bomchu_game_flag ☆ %d\n" VT_RST, globalCtx->bombchuBowlingAmmo);
+ // HOW'S THE FIRST WALL DOING?
+ osSyncPrintf(VT_FGCOL(RED) "☆ 壁1の状態どう? ☆ %d\n" VT_RST, this->wallStatus[0]);
+ // HOW'S THE SECOND WALL DOING?
+ osSyncPrintf(VT_FGCOL(RED) "☆ 壁2の状態どう? ☆ %d\n" VT_RST, this->wallStatus[1]);
+ // HOLE INFORMATION
+ osSyncPrintf(VT_FGCOL(RED) "☆ 穴情報\t ☆ %d\n" VT_RST, this->bowlPit->status);
+ osSyncPrintf("\n\n");
+ }
+
+ this->gameResult = 0;
+
+ if (this->bowlPit != 0) {
+ if ((this->wallStatus[0] != 1) && (this->wallStatus[1] != 1) && (this->bowlPit->status == 2)) {
+ this->gameResult = 1; // Won
+ this->bowlPit->status = 0;
+ // Center HIT!
+ osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ 中央HIT!!!! ☆☆☆☆☆ \n" VT_RST);
+ }
+ if ((globalCtx->bombchuBowlingAmmo == -1) &&
+ (globalCtx->actorCtx.actorList[ACTORTYPE_EXPLOSIVES].length == 0) && (this->bowlPit->status == 0) &&
+ (this->wallStatus[0] != 1) && (this->wallStatus[1] != 1)) {
+ this->gameResult = 2; // Lost
+ // Bombchu lost
+ osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆☆ ボムチュウ消化 ☆☆☆☆☆ \n" VT_RST);
+ }
+ }
+
+ if (this->gameResult != 0) { // won or lost
+ this->actor.textId = 0x1A;
+ this->dialogState = 4;
+ this->minigamePlayStatus = 0;
+ if ((this->exItem != NULL) && (this->exItem->actor.update != 0)) {
+ this->exItem->unk_160 = 1;
+ this->exItem = NULL;
+ }
+ globalCtx->bombchuBowlingAmmo = 0;
+ this->playingAgain = true;
+ func_8010B680(globalCtx, this->actor.textId, NULL);
+ if (this->gameResult == 2) {
+ func_8002DF54(globalCtx, NULL, 8);
+ }
+ this->actionFunc = EnBomBowlMan_HandlePlayChoice;
+ } else {
+ if (func_8002F194(&this->actor, globalCtx)) {
+ if (this->minigamePlayStatus == 0) {
+ this->actionFunc = EnBomBowlMan_HandlePlayChoice;
+ } else {
+ this->actionFunc = func_809C41FC;
+ }
+ } else {
+ yawDiff = ABS((s16)(this->actor.yawTowardsLink - this->actor.shape.rot.y));
+ if (!(this->actor.xzDistFromLink > 120.0f) && (yawDiff < 0x4300)) {
+ func_8002F2CC(&this->actor, globalCtx, 120.0f);
+ }
+ }
+ }
+}
+
+void EnBomBowlMan_HandlePlayChoice(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+
+ if ((func_8010BDBC(&globalCtx->msgCtx) == this->dialogState) && (func_80106BC8(globalCtx) != 0)) {
+ func_80106CCC(globalCtx);
+
+ switch (globalCtx->msgCtx.choiceIndex) {
+ case 0: // Yes
+ if (gSaveContext.rupees >= 30) {
+ Rupees_ChangeBy(-30);
+ this->minigamePlayStatus = 1;
+ this->wallStatus[0] = this->wallStatus[1] = 0;
+ globalCtx->bombchuBowlingAmmo = 10;
+ Flags_SetSwitch(globalCtx, 0x38);
+ if (!this->startedPlaying && !this->playingAgain) {
+ this->actor.textId = 0x19;
+ func_8010B720(globalCtx, this->actor.textId);
+ this->dialogState = 5;
+ this->actionFunc = func_809C41FC;
+ } else {
+ this->actor.textId = 0x1B;
+ func_8010B720(globalCtx, this->actor.textId);
+ this->dialogState = 5;
+ func_800800F8(globalCtx, 0x1F4A, -0x63, NULL, 0);
+ func_8002DF54(globalCtx, NULL, 8);
+ this->actionFunc = EnBomBowMan_SetupChooseShowPrize;
+ }
+ } else {
+ this->playingAgain = false;
+ this->actor.textId = 0x85;
+ func_8010B720(globalCtx, this->actor.textId);
+ this->dialogState = 5;
+ this->actionFunc = func_809C41FC;
+ }
+ break;
+ case 1: // No
+ this->playingAgain = false;
+ this->actor.textId = 0x2D;
+ func_8010B720(globalCtx, this->actor.textId);
+ this->dialogState = 5;
+ this->actionFunc = func_809C41FC;
+ }
+ }
+}
+
+void func_809C41FC(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+ if ((func_8010BDBC(&globalCtx->msgCtx) == this->dialogState) && (func_80106BC8(globalCtx) != 0)) {
+ func_80106CCC(globalCtx);
+ if ((this->actor.textId == 0x2D) || (this->actor.textId == 0x85)) {
+ if (Flags_GetSwitch(globalCtx, 0x38)) {
+ Flags_UnsetSwitch(globalCtx, 0x38);
+ }
+ }
+ if (this->minigamePlayStatus == 1) {
+ this->actor.textId = 0x1B;
+ func_8010B720(globalCtx, this->actor.textId);
+ this->dialogState = 5;
+ func_800800F8(globalCtx, 8010, -99, NULL, 0);
+ func_8002DF54(globalCtx, NULL, 8);
+ this->actionFunc = EnBomBowMan_SetupChooseShowPrize;
+ } else {
+ if (this->gameResult == 2) {
+ func_8002DF54(globalCtx, NULL, 7);
+ }
+ this->actionFunc = EnBomBowMan_SetupRunGame;
+ }
+ }
+}
+
+void EnBomBowMan_SetupChooseShowPrize(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ Vec3f accel = { 0.0f, 0.1f, 0.0f };
+ Vec3f velocity = { 0.0f, 0.0f, 0.0f };
+ Vec3f pos;
+
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
+
+ if ((func_8010BDBC(&globalCtx->msgCtx) == this->dialogState) && (func_80106BC8(globalCtx) != 0)) {
+ pos.x = 148.0f;
+ pos.y = 40.0f;
+ pos.z = 300.0f;
+ EffectSsBomb2_SpawnLayered(globalCtx, &pos, &velocity, &accel, 50, 15);
+ Audio_PlayActorSound2(&this->actor, NA_SE_IT_GOODS_APPEAR);
+ this->prizeRevealTimer = 10;
+ this->actionFunc = EnBomBowMan_ChooseShowPrize;
+ }
+}
+
+static Vec3f sPrizePosOffset[] = {
+ { 0.0f, 22.0f, 0.0f }, { 0.0f, 22.0f, 0.0f }, { 0.0f, 8.0f, 0.0f }, { 0.0f, 9.0f, 0.0f }, { 0.0f, -2.0f, 0.0f },
+};
+
+static s16 sPrizeRot[] = { 0x4268, 0x4268, -0x03E8, 0x0000, 0x4268, 0x0000 };
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3820.s")
+void EnBomBowMan_ChooseShowPrize(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ s16 prizeTemp;
+ s32 pad;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C38A8.s")
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C395C.s")
+ if (this->prizeRevealTimer == 0) {
+ switch (this->prizeSelect) {
+ case 0:
+ prizeTemp = 0;
+ if (gSaveContext.itemGetInf[1] & 2) {
+ prizeTemp = 4;
+ }
+ break;
+ case 1:
+ prizeTemp = 4;
+ break;
+ case 2:
+ prizeTemp = 2;
+ break;
+ case 3:
+ prizeTemp = 1;
+ if (gSaveContext.itemGetInf[1] & 4) {
+ prizeTemp = 4;
+ }
+ break;
+ case 4:
+ prizeTemp = 3;
+ break;
+ }
+ this->prizeIndex = prizeTemp;
+ if (BREG(7)) {
+ this->prizeIndex = BREG(7) - 1;
+ }
+ this->exItem = (EnExItem*)Actor_SpawnAsChild(
+ &globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_EX_ITEM,
+ sPrizePosOffset[this->prizeIndex].x + 148.0f, sPrizePosOffset[this->prizeIndex].y + 40.0f,
+ sPrizePosOffset[this->prizeIndex].z + 300.0f, 0, sPrizeRot[this->prizeIndex], 0, this->prizeIndex + 5);
+ if (!this->startedPlaying) {
+ this->bowlPit = (EnBomBowlPit*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx,
+ ACTOR_EN_BOM_BOWL_PIT, 0.0f, 90.0f, -860.0f, 0, 0, 0, 0);
+ if (this->bowlPit != NULL) {
+ this->bowlPit->prizeIndex = this->prizeIndex;
+ }
+ } else {
+ this->bowlPit->prizeIndex = this->prizeIndex;
+ }
+ this->bowlPit->start = 1;
+ this->minigamePlayStatus = 2;
+ this->actor.textId = 0x405A;
+ func_8010B720(globalCtx, this->actor.textId);
+ this->dialogState = 5;
+ // Cycle through prizes in order
+ this->prizeSelect++;
+ if (this->prizeSelect >= 5) {
+ this->prizeSelect = 0;
+ }
+ this->actionFunc = EnBomBowlMan_BeginPlayGame;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C39D0.s")
+void EnBomBowlMan_BeginPlayGame(EnBomBowlMan* this, GlobalContext* globalCtx) {
+ SkelAnime_FrameUpdateMatrix(&this->skelAnime);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3A54.s")
+ if ((func_8010BDBC(&globalCtx->msgCtx) == this->dialogState) && (func_80106BC8(globalCtx) != 0)) {
+ func_80106CCC(globalCtx);
+ func_8005B1A4(ACTIVE_CAM);
+ this->startedPlaying = true;
+ if (BREG(2)) {
+ BREG(2) = 0;
+ }
+ // "Wow"
+ osSyncPrintf(VT_FGCOL(YELLOW) "☆ わー ☆ %d\n" VT_RST, globalCtx->bombchuBowlingAmmo);
+ func_8002DF54(globalCtx, NULL, 7);
+ this->actionFunc = EnBomBowMan_SetupRunGame;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3B50.s")
+void EnBomBowlMan_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnBomBowlMan* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3C7C.s")
+ this->timer++;
+ this->actor.posRot2.pos.y = 60.0f;
+ Actor_SetHeight(&this->actor, 60.0f);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3CD4.s")
+ switch (this->eyeMode) {
+ case CHU_GIRL_EYES_ASLEEP:
+ this->eyeTextureIndex = 2;
+ break;
+ case CHU_GIRL_EYES_OPEN_SLOWLY:
+ if (this->eyeTextureIndex > 0) {
+ this->eyeTextureIndex--;
+ } else {
+ this->blinkTimer = 30;
+ this->eyeMode = CHU_GIRL_EYES_BLINK_RAPIDLY;
+ }
+ break;
+ case CHU_GIRL_EYES_BLINK_RAPIDLY:
+ if ((this->blinkTimer == 0) && (this->eyeTextureIndex > 0)) {
+ this->eyeTextureIndex--;
+ }
+ break;
+ default:
+ if (this->blinkTimer == 0) {
+ this->eyeTextureIndex++;
+ if (this->eyeTextureIndex >= 3) {
+ this->eyeTextureIndex = 0;
+ this->blinkTimer = (s16)Math_Rand_ZeroFloat(60.0f) + 20;
+ }
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3D40.s")
+ func_80038290(globalCtx, &this->actor, &this->unk_218, &this->unk_224, this->actor.posRot2.pos);
+ break;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3DC4.s")
+ DECR(this->prizeRevealTimer);
+ DECR(this->blinkTimer);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C4040.s")
+ this->actionFunc(this, globalCtx);
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C41FC.s")
+s32 EnBomBowlMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
+ void* thisx) {
+ EnBomBowlMan* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C4318.s")
+ if (limbIndex == 4) {
+ rot->x += this->unk_218.y;
+ rot->z += this->unk_218.z;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C441C.s")
+ return 0;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C4664.s")
+void EnBomBowlMan_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ static UNK_PTR eyeTextures[] = { 0x06004110, 0x06004910, 0x06005110 };
+ EnBomBowlMan* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Update.s")
+ OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_bom_bowl_man.c", 907);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C48A8.s")
+ func_80093D18(globalCtx->state.gfxCtx);
+ gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeTextureIndex]));
+ SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, this->skelAnime.dListCount,
+ EnBomBowlMan_OverrideLimbDraw, NULL, this);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Draw.s")
+ CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_bom_bowl_man.c", 923);
+}
diff --git a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h
index d43056810..602a5fff3 100644
--- a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h
+++ b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h
@@ -3,14 +3,40 @@
#include "ultra64.h"
#include "global.h"
+#include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h"
+#include "overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h"
struct EnBomBowlMan;
+typedef void (*EnBomBowlManActionFunc)(struct EnBomBowlMan*, GlobalContext*);
+
typedef struct EnBomBowlMan {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x10C];
- /* 0x0258 */ u8 unk_258;
- /* 0x0259 */ char unk_259[0xB];
+ /* 0x014C */ SkelAnime skelAnime;
+ /* 0x0190 */ Vec3s limbDrawTable[11];
+ /* 0x01D2 */ Vec3s transitionDrawTable[11];
+ /* 0x0214 */ EnBomBowlManActionFunc actionFunc;
+ /* 0x0218 */ Vec3s unk_218;
+ /* 0x021E */ char unk_21E[0x6];
+ /* 0x0224 */ Vec3s unk_224;
+ /* 0x022A */ s16 prizeRevealTimer;
+ /* 0x022C */ s16 timer;
+ /* 0x022E */ s16 dialogState;
+ /* 0x0230 */ s16 prizeIndex;
+ /* 0x0232 */ s16 startedPlaying; // set to true after starting the first round
+ /* 0x0234 */ s16 eyeTextureIndex;
+ /* 0x0236 */ s16 blinkTimer;
+ /* 0x0238 */ s16 eyeMode;
+ /* 0x023A */ s16 blinkCount;
+ /* 0x023C */ s16 playingAgain; // whether player is playing again after a game
+ /* 0x023E */ s16 wallStatus[2];
+ /* 0x0242 */ s16 prizeSelect;
+ /* 0x0244 */ s16 gameResult; // 0 = default, 1 = lost, 2 = won
+ /* 0x0248 */ Vec3f posCopy; // Set and not used
+ /* 0x0254 */ f32 frameCount;
+ /* 0x0258 */ u8 minigamePlayStatus; // 0 = default, 1 = paid, 2 = playing
+ /* 0x025C */ EnBomBowlPit* bowlPit;
+ /* 0x0260 */ EnExItem* exItem;
} EnBomBowlMan; // size = 0x0264
extern const ActorInit En_Bom_Bowl_Man_InitVars;
diff --git a/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c b/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c
index 5c82963fe..7fd591dec 100644
--- a/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c
+++ b/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.c
@@ -1,4 +1,6 @@
#include "z_en_bom_bowl_pit.h"
+#include "vt.h"
+#include "overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h"
#define FLAGS 0x00000010
@@ -8,7 +10,17 @@ void EnBomBowlPit_Init(Actor* thisx, GlobalContext* globalCtx);
void EnBomBowlPit_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnBomBowlPit_Update(Actor* thisx, GlobalContext* globalCtx);
-/*
+void EnBomBowlPit_SetupDetectHit(EnBomBowlPit* this, GlobalContext* globalCtx);
+void EnBomBowlPit_DetectHit(EnBomBowlPit* this, GlobalContext* globalCtx);
+void EnBomBowlPit_CameraDollyIn(EnBomBowlPit* this, GlobalContext* globalCtx);
+void EnBomBowlPit_SpawnPrize(EnBomBowlPit* this, GlobalContext* globalCtx);
+void EnBomBowlPit_SetupGivePrize(EnBomBowlPit* this, GlobalContext* globalCtx);
+void EnBomBowlPit_GivePrize(EnBomBowlPit* this, GlobalContext* globalCtx);
+void EnBomBowlPit_WaitTillPrizeGiven(EnBomBowlPit* this, GlobalContext* globalCtx);
+void EnBomBowlPit_Reset(EnBomBowlPit* this, GlobalContext* globalCtx);
+
+static s32 sGetItemIds[] = { GI_BOMB_BAG_30, GI_HEART_PIECE, GI_BOMBCHUS_10, GI_BOMBS_1, GI_RUPEE_PURPLE };
+
const ActorInit En_Bom_Bowl_Pit_InitVars = {
ACTOR_EN_BOM_BOWL_PIT,
ACTORTYPE_PROP,
@@ -20,25 +32,192 @@ const ActorInit En_Bom_Bowl_Pit_InitVars = {
(ActorFunc)EnBomBowlPit_Update,
NULL,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/EnBomBowlPit_Init.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/EnBomBowlPit_Destroy.s")
+void EnBomBowlPit_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnBomBowlPit* this = THIS;
+
+ this->actionFunc = EnBomBowlPit_SetupDetectHit;
+}
+
+void EnBomBowlPit_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+}
+
+void EnBomBowlPit_SetupDetectHit(EnBomBowlPit* this, GlobalContext* globalCtx) {
+ if (this->start != 0) {
+ this->start = this->status = 0;
+ this->actionFunc = EnBomBowlPit_DetectHit;
+ }
+}
+
+void EnBomBowlPit_DetectHit(EnBomBowlPit* this, GlobalContext* globalCtx) {
+ EnBomChu* chu;
+ Vec3f chuPosDiff;
+
+ if (globalCtx->cameraPtrs[0]->setting == 0x15) {
+ chu = (EnBomChu*)globalCtx->actorCtx.actorList[ACTORTYPE_EXPLOSIVES].first;
+
+ while (chu != NULL) {
+ if ((&chu->actor == &this->actor) || (chu->actor.id != ACTOR_EN_BOM_CHU)) {
+ chu = (EnBomChu*)chu->actor.next;
+ continue;
+ }
+
+ chuPosDiff.x = chu->actor.posRot.pos.x - this->actor.posRot.pos.x;
+ chuPosDiff.y = chu->actor.posRot.pos.y - this->actor.posRot.pos.y;
+ chuPosDiff.z = chu->actor.posRot.pos.z - this->actor.posRot.pos.z;
+
+ if (((fabsf(chuPosDiff.x) < 40.0f) || (BREG(2))) && ((fabsf(chuPosDiff.y) < 40.0f) || (BREG(2))) &&
+ ((fabsf(chuPosDiff.z) < 40.0f) || (BREG(2)))) {
+ func_8002DF54(globalCtx, NULL, 8);
+ chu->unk_150 = 1;
+
+ this->camId = Gameplay_CreateSubCamera(globalCtx);
+ Gameplay_ChangeCameraStatus(globalCtx, 0, 1);
+ Gameplay_ChangeCameraStatus(globalCtx, this->camId, 7);
+
+ this->unk_1C8.x = this->unk_1C8.y = this->unk_1C8.z = 0.1f;
+ this->unk_1A4.x = this->unk_1A4.y = this->unk_1A4.z = 0.1f;
+
+ this->unk_180.x = this->unk_168.x = globalCtx->view.lookAt.x;
+ this->unk_180.y = this->unk_168.y = globalCtx->view.lookAt.y;
+ this->unk_180.z = this->unk_168.z = globalCtx->view.lookAt.z;
+
+ this->unk_18C.x = this->unk_174.x = globalCtx->view.eye.x;
+ this->unk_18C.y = this->unk_174.y = globalCtx->view.eye.y;
+ this->unk_18C.z = this->unk_174.z = globalCtx->view.eye.z;
+
+ this->unk_1BC.x = 20.0f;
+ this->unk_1BC.y = 100.0f;
+ this->unk_1BC.z = -800.0f;
+
+ this->unk_198.x = 20.0f;
+ this->unk_198.y = 50.0f;
+ this->unk_198.z = -485.0f;
+
+ this->unk_1B0.x = fabsf(this->unk_18C.x - this->unk_198.x) * 0.02f;
+ this->unk_1B0.y = fabsf(this->unk_18C.y - this->unk_198.y) * 0.02f;
+ this->unk_1B0.z = fabsf(this->unk_18C.z - this->unk_198.z) * 0.02f;
+
+ this->unk_1D4.x = fabsf(this->unk_180.x - this->unk_1BC.x) * 0.02f;
+ this->unk_1D4.y = fabsf(this->unk_180.y - this->unk_1BC.y) * 0.02f;
+ this->unk_1D4.z = fabsf(this->unk_180.z - this->unk_1BC.z) * 0.02f;
+
+ func_800C04D8(globalCtx, this->camId, &this->unk_180, &this->unk_18C);
+ this->actor.textId = 0xF;
+ func_8010B680(globalCtx, this->actor.textId, NULL);
+ this->unk_154 = 5;
+ func_80078884(NA_SE_EV_HIT_SOUND);
+ func_8002DF54(globalCtx, NULL, 8);
+ this->status = 1;
+ this->actionFunc = EnBomBowlPit_CameraDollyIn;
+ break;
+ } else {
+ chu = (EnBomChu*)chu->actor.next;
+ }
+ }
+ }
+}
+
+void EnBomBowlPit_CameraDollyIn(EnBomBowlPit* this, GlobalContext* globalCtx) {
+ if (this->camId != 0) {
+ Math_SmoothScaleMaxF(&this->unk_180.x, this->unk_1BC.x, this->unk_1C8.x, this->unk_1D4.x);
+ Math_SmoothScaleMaxF(&this->unk_180.y, this->unk_1BC.y, this->unk_1C8.y, this->unk_1D4.y);
+ Math_SmoothScaleMaxF(&this->unk_180.z, this->unk_1BC.z, this->unk_1C8.z, this->unk_1D4.z);
+ Math_SmoothScaleMaxF(&this->unk_18C.x, this->unk_198.x, this->unk_1A4.x, this->unk_1B0.x);
+ Math_SmoothScaleMaxF(&this->unk_18C.y, this->unk_198.y, this->unk_1A4.y, this->unk_1B0.y);
+ Math_SmoothScaleMaxF(&this->unk_18C.z, this->unk_198.z, this->unk_1A4.z, this->unk_1B0.z);
+ }
+
+ func_800C04D8(globalCtx, this->camId, &this->unk_180, &this->unk_18C);
+
+ if ((this->unk_154 == func_8010BDBC(&globalCtx->msgCtx)) && (func_80106BC8(globalCtx) != 0)) {
+ func_80106CCC(globalCtx);
+ }
+
+ if ((fabsf(this->unk_18C.x - this->unk_198.x) < 5.0f) && (fabsf(this->unk_18C.y - this->unk_198.y) < 5.0f) &&
+ (fabsf(this->unk_18C.z - this->unk_198.z) < 5.0f) && (fabsf(this->unk_180.x - this->unk_1BC.x) < 5.0f) &&
+ (fabsf(this->unk_180.y - this->unk_1BC.y) < 5.0f) && (fabsf(this->unk_180.z - this->unk_1BC.z) < 5.0f)) {
+ func_80106CCC(globalCtx);
+ this->timer = 30;
+ this->actionFunc = EnBomBowlPit_SpawnPrize;
+ }
+}
+
+void EnBomBowlPit_SpawnPrize(EnBomBowlPit* this, GlobalContext* globalCtx) {
+ if (this->timer == 0) {
+ this->exItem = (EnExItem*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_EX_ITEM,
+ this->actor.posRot.pos.x, this->actor.posRot.pos.y,
+ this->actor.posRot.pos.z - 70.0f, 0, 0, 0, this->prizeIndex);
+ if (this->exItem != NULL) {
+ this->actionFunc = EnBomBowlPit_SetupGivePrize;
+ }
+ }
+}
+
+void EnBomBowlPit_SetupGivePrize(EnBomBowlPit* this, GlobalContext* globalCtx) {
+ if (this->unk_156 != 0) {
+ switch (this->prizeIndex) {
+ case 0:
+ gSaveContext.itemGetInf[1] |= 2;
+ break;
+ case 1:
+ gSaveContext.itemGetInf[1] |= 4;
+ break;
+ }
+
+ Gameplay_ClearCamera(globalCtx, this->camId);
+ Gameplay_ChangeCameraStatus(globalCtx, 0, 7);
+ func_8002DF54(globalCtx, NULL, 8);
+ this->actionFunc = EnBomBowlPit_GivePrize;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C4E60.s")
+void EnBomBowlPit_GivePrize(EnBomBowlPit* this, GlobalContext* globalCtx) {
+ Player* player = PLAYER;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C4E8C.s")
+ func_8002DF54(globalCtx, NULL, 7);
+ this->getItemId = sGetItemIds[this->prizeIndex];
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C5184.s")
+ if ((this->getItemId == GI_BOMB_BAG_30) && (CUR_CAPACITY(UPG_BOMB_BAG) == 30)) {
+ this->getItemId = GI_BOMB_BAG_40;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C5360.s")
+ player->stateFlags1 &= ~0x20000000;
+ this->actor.parent = NULL;
+ func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f);
+ player->stateFlags1 |= 0x20000000;
+ this->actionFunc = EnBomBowlPit_WaitTillPrizeGiven;
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C53F0.s")
+void EnBomBowlPit_WaitTillPrizeGiven(EnBomBowlPit* this, GlobalContext* globalCtx) {
+ if (Actor_HasParent(&this->actor, globalCtx)) {
+ this->actionFunc = EnBomBowlPit_Reset;
+ } else {
+ func_8002F434(&this->actor, globalCtx, this->getItemId, 2000.0f, 1000.0f);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C54A8.s")
+void EnBomBowlPit_Reset(EnBomBowlPit* this, GlobalContext* globalCtx) {
+ if ((func_8010BDBC(&globalCtx->msgCtx) == 6) && (func_80106BC8(globalCtx) != 0)) {
+ // Normal termination/completion
+ osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST);
+ if (this->getItemId == GI_HEART_PIECE) {
+ gSaveContext.healthAccumulator = 0x140;
+ // Ah recovery! (?)
+ osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆☆ あぁ回復! ☆☆☆☆☆ \n" VT_RST);
+ }
+ this->unk_156 = 0;
+ this->status = 2;
+ this->actionFunc = EnBomBowlPit_SetupDetectHit;
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C55B0.s")
+void EnBomBowlPit_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnBomBowlPit* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C5608.s")
+ this->actionFunc(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/EnBomBowlPit_Update.s")
+ if (this->timer != 0) {
+ this->timer--;
+ }
+}
diff --git a/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h b/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h
index 909dde98e..eb12b867d 100644
--- a/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h
+++ b/src/overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h
@@ -3,12 +3,36 @@
#include "ultra64.h"
#include "global.h"
+#include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h"
struct EnBomBowlPit;
+typedef void (*EnBomBowlPitActionFunc)(struct EnBomBowlPit*, GlobalContext*);
+
typedef struct EnBomBowlPit {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x35B8];
+ /* 0x014C */ EnBomBowlPitActionFunc actionFunc;
+ /* 0x0150 */ u16 unk_150;
+ /* 0x0152 */ s16 camId;
+ /* 0x0154 */ s16 unk_154;
+ /* 0x0156 */ s16 unk_156; // Set by EnExItem?
+ /* 0x0158 */ s16 timer;
+ /* 0x015A */ s16 prizeIndex;
+ /* 0x015C */ s16 start;
+ /* 0x0160 */ s32 getItemId;
+ /* 0x0164 */ u8 status;
+ /* 0x0168 */ Vec3f unk_168; // set and not used?
+ /* 0x0174 */ Vec3f unk_174; // set and not used?
+ /* 0x0180 */ Vec3f unk_180; // camera at (start)
+ /* 0x018C */ Vec3f unk_18C; // camera eye (start)
+ /* 0x0198 */ Vec3f unk_198; // camera eye (end)
+ /* 0x01A4 */ Vec3f unk_1A4; // camera eye (scales)
+ /* 0x01B0 */ Vec3f unk_1B0; // camera eye (maxsteps)
+ /* 0x01BC */ Vec3f unk_1BC; // camera at (end)
+ /* 0x01C8 */ Vec3f unk_1C8; // camera at (scales)
+ /* 0x01D4 */ Vec3f unk_1D4; // camera eye (maxsteps)
+ /* 0x01E0 */ EnExItem* exItem;
+ /* 0x01E4 */ char unk_1E4[0x3520];
} EnBomBowlPit; // size = 0x3704
extern const ActorInit En_Bom_Bowl_Pit_InitVars;
diff --git a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h
index 0da3c24e0..a64ee4ee3 100644
--- a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h
+++ b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h
@@ -6,9 +6,13 @@
struct EnBomChu;
+typedef void (*EnBomChuActionFunc)(struct EnBomChu*, GlobalContext*);
+
typedef struct EnBomChu {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x98];
+ /* 0x014C */ EnBomChuActionFunc actionFunc;
+ /* 0x0150 */ u16 unk_150;
+ /* 0x0152 */ char unk_152[0x92];
} EnBomChu; // size = 0x01E4
extern const ActorInit En_Bom_Chu_InitVars;
diff --git a/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h b/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h
index 62c32cd7a..5060b68ae 100644
--- a/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h
+++ b/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h
@@ -8,7 +8,9 @@ struct EnExItem;
typedef struct EnExItem {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x38];
+ /* 0x014C */ char unk_14C[0x14];
+ /* 0x0160 */ s16 unk_160;
+ /* 0x0162 */ char unk_165[0x22];
} EnExItem; // size = 0x0184
extern const ActorInit En_Ex_Item_InitVars;
diff --git a/src/overlays/actors/ovl_En_Rd/z_en_rd.c b/src/overlays/actors/ovl_En_Rd/z_en_rd.c
index e4a534c1e..4106e80ea 100644
--- a/src/overlays/actors/ovl_En_Rd/z_en_rd.c
+++ b/src/overlays/actors/ovl_En_Rd/z_en_rd.c
@@ -863,7 +863,7 @@ void EnRd_Draw(Actor* thisx, GlobalContext* globalCtx) {
if (this->unk_314 == 0xFF) {
func_80093D18(globalCtx->state.gfxCtx);
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->unk_314);
- gSPSegment(POLY_OPA_DISP++, 8, &D_80116280[2]);
+ gSPSegment(POLY_OPA_DISP++, 0x8, &D_80116280[2]);
POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl,
this->skelAnime.dListCount, EnRd_OverrideLimbDraw, EnRd_PostLimbDraw, this,
POLY_OPA_DISP);
diff --git a/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c b/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c
index 93b6d993e..32e1451f9 100644
--- a/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c
+++ b/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.c
@@ -1,10 +1,14 @@
/*
* File: z_en_wall_tubo.c
* Overlay: ovl_En_Wall_Tubo
- * Description: Bombchu Bowling Alley Wall 2
+ * Description: Bombchu Bowling Alley Bullseyes/Pits
*/
#include "z_en_wall_tubo.h"
+#include "vt.h"
+#include "overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h"
+#include "overlays/actors/ovl_Bg_Bowl_Wall/z_bg_bowl_wall.h"
+#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h"
#define FLAGS 0x00000010
@@ -14,7 +18,10 @@ void EnWallTubo_Init(Actor* thisx, GlobalContext* globalCtx);
void EnWallTubo_Destroy(Actor* thisx, GlobalContext* globalCtx);
void EnWallTubo_Update(Actor* thisx, GlobalContext* globalCtx);
-/*
+void EnWallTubo_FindGirl(EnWallTubo* this, GlobalContext* globalCtx);
+void EnWallTubo_DetectChu(EnWallTubo* this, GlobalContext* globalCtx);
+void EnWallTubo_SetWallFall(EnWallTubo* this, GlobalContext* globalCtx);
+
const ActorInit En_Wall_Tubo_InitVars = {
ACTOR_EN_WALL_TUBO,
ACTORTYPE_PROP,
@@ -26,15 +33,124 @@ const ActorInit En_Wall_Tubo_InitVars = {
(ActorFunc)EnWallTubo_Update,
NULL,
};
-*/
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/EnWallTubo_Init.s")
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/EnWallTubo_Destroy.s")
+void EnWallTubo_Init(Actor* thisx, GlobalContext* globalCtx) {
+ EnWallTubo* this = THIS;
+
+ osSyncPrintf("\n\n");
+ // Wall Target
+ osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 壁のツボ ☆☆☆☆☆ \n" VT_RST);
+ this->unk_164 = this->actor.posRot.pos;
+ this->actionFunc = EnWallTubo_FindGirl;
+}
+
+void EnWallTubo_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+}
+
+void EnWallTubo_FindGirl(EnWallTubo* this, GlobalContext* globalCtx) {
+ Actor* lookForGirl;
+
+ lookForGirl = globalCtx->actorCtx.actorList[ACTORTYPE_NPC].first;
+
+ while (lookForGirl != NULL) {
+ if (lookForGirl->id != ACTOR_EN_BOM_BOWL_MAN) {
+ lookForGirl = lookForGirl->next;
+ } else {
+ this->chuGirl = (EnBomBowlMan*)lookForGirl;
+ break;
+ }
+ }
+
+ this->actionFunc = EnWallTubo_DetectChu;
+}
+
+void EnWallTubo_DetectChu(EnWallTubo* this, GlobalContext* globalCtx) {
+ EnBomChu* chu;
+ s32 pad;
+ Vec3f effAccel = { 0.0f, 0.1f, 0.0f };
+ Vec3f effVelocity = { 0.0f, 0.0f, 0.0f };
+ Vec3f chuPosDiff;
+ s16 quakeIndex;
+
+ if (this->chuGirl->minigamePlayStatus != 0) {
+ if (globalCtx->cameraPtrs[0]->setting == 0x15) {
+ chu = (EnBomChu*)globalCtx->actorCtx.actorList[ACTORTYPE_EXPLOSIVES].first;
+
+ while (chu != NULL) {
+ if ((&chu->actor == &this->actor) || (chu->actor.id != ACTOR_EN_BOM_CHU)) {
+ chu = (EnBomChu*)chu->actor.next;
+ continue;
+ }
+
+ chuPosDiff.x = chu->actor.posRot.pos.x - this->actor.posRot.pos.x;
+ chuPosDiff.y = chu->actor.posRot.pos.y - this->actor.posRot.pos.y;
+ chuPosDiff.z = chu->actor.posRot.pos.z - this->actor.posRot.pos.z;
+
+ if (((fabsf(chuPosDiff.x) < 40.0f) || (BREG(2))) && ((fabsf(chuPosDiff.y) < 40.0f) || (BREG(2))) &&
+ (fabsf(chuPosDiff.z) < 40.0f || (BREG(2)))) {
+ this->chuGirl->wallStatus[this->actor.params] = 1;
+ chu->unk_150 = 2;
+ func_80078884(NA_SE_SY_TRE_BOX_APPEAR);
+ this->timer = 60;
+ EffectSsBomb2_SpawnLayered(globalCtx, &this->explosionCenter, &effVelocity, &effAccel, 200, 40);
+ quakeIndex = Quake_Add(ACTIVE_CAM, 1);
+ Quake_SetSpeed(quakeIndex, 0x7FFF);
+ Quake_SetQuakeValues(quakeIndex, 100, 0, 0, 0);
+ Quake_SetCountdown(quakeIndex, 100);
+ this->actionFunc = EnWallTubo_SetWallFall;
+ break;
+ }
+
+ chu = (EnBomChu*)chu->actor.next;
+ }
+ }
+ }
+}
+
+void EnWallTubo_SetWallFall(EnWallTubo* this, GlobalContext* globalCtx) {
+ BgBowlWall* wall;
+ Vec3f effAccel = { 0.0f, 0.1f, 0.0f };
+ Vec3f effVelocity = { 0.0f, 0.0f, 0.0f };
+ Vec3f effPos;
+
+ if ((globalCtx->gameplayFrames & 1) == 0) {
+ effPos.x = this->explosionCenter.x + Math_Rand_CenteredFloat(300.0f);
+ effPos.y = this->explosionCenter.y + Math_Rand_CenteredFloat(300.0f);
+ effPos.z = this->explosionCenter.z;
+ EffectSsBomb2_SpawnLayered(globalCtx, &effPos, &effVelocity, &effAccel, 100, 30);
+ EffectSsHahen_SpawnBurst(globalCtx, &effPos, 10.0f, 0, 50, 15, 3, HAHEN_OBJECT_DEFAULT, 10, NULL);
+ Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION);
+ }
+
+ if (this->timer == 0) {
+ wall = (BgBowlWall*)this->actor.parent;
+
+ if ((wall != NULL) && (wall->dyna.actor.update != NULL)) {
+ wall->isHit = true;
+ // You did it field! (repeated 5 times)
+ osSyncPrintf(VT_FGCOL(GREEN) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
+ osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
+ osSyncPrintf(VT_FGCOL(BLUE) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
+ osSyncPrintf(VT_FGCOL(PURPLE) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
+ osSyncPrintf(VT_FGCOL(CYAN) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
+ }
+
+ Actor_Kill(&this->actor);
+ }
+}
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/func_80B2EE5C.s")
+void EnWallTubo_Update(Actor* thisx, GlobalContext* globalCtx) {
+ EnWallTubo* this = THIS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/func_80B2EE9C.s")
+ if (this->timer != 0) {
+ this->timer--;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/func_80B2F0B8.s")
+ this->actionFunc(this, globalCtx);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/EnWallTubo_Update.s")
+ if (BREG(0)) {
+ DebugDisplay_AddObject(this->actor.posRot.pos.x, this->actor.posRot.pos.y, this->actor.posRot.pos.z,
+ this->actor.posRot.rot.x, this->actor.posRot.rot.y, this->actor.posRot.rot.z, 1.0f, 1.0f,
+ 1.0f, 0, 0, 255, 255, 4, globalCtx->state.gfxCtx);
+ }
+}
diff --git a/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.h b/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.h
index 9aab46d21..c5392b68e 100644
--- a/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.h
+++ b/src/overlays/actors/ovl_En_Wall_Tubo/z_en_wall_tubo.h
@@ -3,12 +3,19 @@
#include "ultra64.h"
#include "global.h"
+#include "overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h"
struct EnWallTubo;
+typedef void (*EnWallTuboActionFunc)(struct EnWallTubo*, GlobalContext*);
+
typedef struct EnWallTubo {
/* 0x0000 */ Actor actor;
- /* 0x014C */ char unk_14C[0x24];
+ /* 0x014C */ EnWallTuboActionFunc actionFunc;
+ /* 0x0150 */ s16 timer;
+ /* 0x0154 */ Vec3f explosionCenter;
+ /* 0x0160 */ EnBomBowlMan* chuGirl;
+ /* 0x0164 */ Vec3f unk_164;
} EnWallTubo; // size = 0x0170
extern const ActorInit En_Wall_Tubo_InitVars;
diff --git a/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c b/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c
index 234c304f6..e6ccbd5f8 100644
--- a/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c
+++ b/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c
@@ -181,7 +181,7 @@ void func_80B4B010(EnZl1* this, GlobalContext* globalCtx) {
this->actionFunc = func_80B4B240;
func_800F5C64(0x51);
} else {
- if (1) {}; // necessary to match
+ if (1) {} // necessary to match
rotDiff = ABS(this->actor.yawTowardsLink - this->actor.shape.rot.y);
if ((rotDiff < 0x238E) && !(player->actor.posRot.pos.y < this->actor.posRot.pos.y)) {
func_8002F2F4(&this->actor, globalCtx);
diff --git a/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c b/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c
index 8e3c39003..44fce283d 100644
--- a/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c
+++ b/src/overlays/actors/ovl_En_Zl3/z_en_zl3.c
@@ -2732,11 +2732,11 @@ void func_80B59FF4(EnZl3* this, GlobalContext* globalCtx) {
func_80093D18(globalCtx->state.gfxCtx);
- gSPSegment(POLY_OPA_DISP++, 8, SEGMENTED_TO_VIRTUAL(sp78));
- gSPSegment(POLY_OPA_DISP++, 9, SEGMENTED_TO_VIRTUAL(sp78));
- gSPSegment(POLY_OPA_DISP++, 10, SEGMENTED_TO_VIRTUAL(sp6C));
+ gSPSegment(POLY_OPA_DISP++, 0x8, SEGMENTED_TO_VIRTUAL(sp78));
+ gSPSegment(POLY_OPA_DISP++, 0x9, SEGMENTED_TO_VIRTUAL(sp78));
+ gSPSegment(POLY_OPA_DISP++, 0xA, SEGMENTED_TO_VIRTUAL(sp6C));
gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
- gSPSegment(POLY_OPA_DISP++, 11, &D_80116280[2]);
+ gSPSegment(POLY_OPA_DISP++, 0xB, &D_80116280[2]);
POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, skelAnime->skeleton, skelAnime->limbDrawTbl, skelAnime->dListCount,
EnZl3_OverrideLimbDraw, EnZl3_PostLimbDraw, this, POLY_OPA_DISP);