diff --git a/assets/xml/objects/object_bg.xml b/assets/xml/objects/object_bg.xml
index 133de136f6a..b66cf6366da 100644
--- a/assets/xml/objects/object_bg.xml
+++ b/assets/xml/objects/object_bg.xml
@@ -1,80 +1,66 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/xml/objects/object_bowl.xml b/assets/xml/objects/object_bowl.xml
index 31fd9eb8416..a6d51c2b7cd 100644
--- a/assets/xml/objects/object_bowl.xml
+++ b/assets/xml/objects/object_bowl.xml
@@ -6,20 +6,20 @@
-
-
+
+
-
-
-
+
+
+
-
+
-
+
diff --git a/include/save.h b/include/save.h
index 4f83a84d88f..7628d39093c 100644
--- a/include/save.h
+++ b/include/save.h
@@ -745,8 +745,8 @@ typedef enum LinkAge {
#define ITEMGETINF_0E 0x0E
#define ITEMGETINF_0F 0x0F
#define ITEMGETINF_10 0x10
-#define ITEMGETINF_11 0x11
-#define ITEMGETINF_12 0x12
+#define ITEMGETINF_BOWLING_BOMB_BAG 0x11
+#define ITEMGETINF_BOWLING_HEART_PIECE 0x12
#define ITEMGETINF_13 0x13
#define ITEMGETINF_15 0x15
#define ITEMGETINF_16 0x16
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 e773a20c4c2..487edb3e5cb 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
@@ -1,7 +1,7 @@
/*
* File: z_bg_bom_guard.c
* Overlay: Bg_Bom_Guard
- * Description: Bombchu Bowling Alley Walls
+ * Description: Bombchu Bowling Alley invisible wall locking the player in the game area
*/
#include "z_bg_bom_guard.h"
@@ -21,7 +21,7 @@ void BgBomGuard_Init(Actor* thisx, PlayState* play);
void BgBomGuard_Destroy(Actor* thisx, PlayState* play);
void BgBomGuard_Update(Actor* thisx, PlayState* play);
-void func_8086E638(BgBomGuard* this, PlayState* play);
+void BgBomGuard_UpdateImpl(BgBomGuard* this, PlayState* play);
ActorProfile Bg_Bom_Guard_Profile = {
/**/ ACTOR_BG_BOM_GUARD,
@@ -45,17 +45,17 @@ void BgBomGuard_Init(Actor* thisx, PlayState* play) {
CollisionHeader* colHeader = NULL;
DynaPolyActor_Init(&this->dyna, 0);
- CollisionHeader_GetVirtual(&gBowlingDefaultCol, &colHeader);
- this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, thisx, colHeader);
+ CollisionHeader_GetVirtual(&gBowlingBgBomGuardCol, &colHeader);
+ this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader);
PRINTF("\n\n");
PRINTF(VT_FGCOL(GREEN) T(" ☆☆☆☆☆ 透明ガード出現 ☆☆☆☆☆ \n", " ☆☆☆☆☆ Transparent guard appears ☆☆☆☆☆ \n") VT_RST);
- thisx->scale.x = 1.0f;
- thisx->scale.y = 1.0f;
- thisx->scale.z = 1.0f;
- this->unk_16C = thisx->world.pos;
- BgBomGuard_SetupAction(this, func_8086E638);
+ this->dyna.actor.scale.x = 1.0f;
+ this->dyna.actor.scale.y = 1.0f;
+ this->dyna.actor.scale.z = 1.0f;
+ this->homePos = this->dyna.actor.world.pos;
+ BgBomGuard_SetupAction(this, BgBomGuard_UpdateImpl);
}
void BgBomGuard_Destroy(Actor* thisx, PlayState* play) {
@@ -64,27 +64,27 @@ void BgBomGuard_Destroy(Actor* thisx, PlayState* play) {
DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
}
-void func_8086E638(BgBomGuard* this, PlayState* play) {
+void BgBomGuard_UpdateImpl(BgBomGuard* this, PlayState* play) {
Actor* it = play->actorCtx.actorLists[ACTORCAT_NPC].head;
- Actor* thisx = &this->dyna.actor;
- this->unk_168 = 0;
+ this->isActive = false;
while (it != NULL) {
if (it->id == ACTOR_EN_BOM_BOWL_MAN) {
- if ((((EnBomBowlMan*)it)->minigamePlayStatus != 0) && (fabsf(play->view.eye.x) > -20.0f) &&
- (fabsf(play->view.eye.y) > 110.0f)) {
- this->unk_168 = 1;
+ if ((((EnBomBowlMan*)it)->gameStartStatus != EN_BOM_BOWL_MAN_GAME_START_STATUS_INACTIVE) &&
+ (fabsf(play->view.eye.x) > -20.0f) && (fabsf(play->view.eye.y) > 110.0f)) {
+ this->isActive = true;
}
break;
}
it = it->next;
}
- if (this->unk_168 == 0) {
- thisx->world.pos.y = sREG(64) + -200.0f;
+ if (!this->isActive) {
+ // Move under ground
+ this->dyna.actor.world.pos.y = sREG(64) + -200.0f;
} else {
- thisx->world.pos.y = 0.0f;
+ this->dyna.actor.world.pos.y = 0.0f;
}
}
diff --git a/src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.h b/src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.h
index 707027f443e..909fcc7adb1 100644
--- a/src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.h
+++ b/src/overlays/actors/ovl_Bg_Bom_Guard/z_bg_bom_guard.h
@@ -11,8 +11,8 @@ typedef void (*BgBomGuardActionFunc)(struct BgBomGuard*, struct PlayState*);
typedef struct BgBomGuard {
/* 0x0000 */ DynaPolyActor dyna;
/* 0x0164 */ BgBomGuardActionFunc actionFunc;
- /* 0x0168 */ u8 unk_168;
- /* 0x016C */ Vec3f unk_16C;
+ /* 0x0168 */ u8 isActive;
+ /* 0x016C */ Vec3f homePos;
} BgBomGuard; // size = 0x0178
#endif
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 57a5b0b9e6b..1fee0dfa891 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,9 +5,8 @@
*/
#include "z_bg_bowl_wall.h"
+#include "overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.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"
-
#include "gfx.h"
#include "gfx_setupdl.h"
#include "printf.h"
@@ -15,12 +14,10 @@
#include "rand.h"
#include "sfx.h"
#include "sys_matrix.h"
-#include "terminal.h"
-#include "translation.h"
#include "z_lib.h"
+#include "bgcheck.h"
#include "effect.h"
#include "play_state.h"
-
#include "assets/objects/object_bowl/object_bowl.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
@@ -28,13 +25,13 @@
void BgBowlWall_Init(Actor* thisx, PlayState* play);
void BgBowlWall_Destroy(Actor* thisx, PlayState* play);
void BgBowlWall_Update(Actor* thisx, PlayState* play);
-void BgBowlWall_Draw(Actor* thisx, PlayState* play2);
+void BgBowlWall_Draw(Actor* thisx, PlayState* play);
-void BgBowlWall_SpawnBullseyes(BgBowlWall* this, PlayState* play);
-void BgBowlWall_WaitForHit(BgBowlWall* this, PlayState* play);
-void BgBowlWall_FallDoEffects(BgBowlWall* this, PlayState* play);
-void BgBowlWall_FinishFall(BgBowlWall* this, PlayState* play);
-void BgBowlWall_Reset(BgBowlWall* this, PlayState* play);
+void BgBowlWall_InitImpl(BgBowlWall* this, PlayState* play);
+void BgBowlWall_WaitTargetHit(BgBowlWall* this, PlayState* play);
+void BgBowlWall_Explode(BgBowlWall* this, PlayState* play);
+void BgBowlWall_Disappear(BgBowlWall* this, PlayState* play);
+void BgBowlWall_WaitReappear(BgBowlWall* this, PlayState* play);
ActorProfile Bg_Bowl_Wall_Profile = {
/**/ ACTOR_BG_BOWL_WALL,
@@ -48,122 +45,118 @@ ActorProfile Bg_Bowl_Wall_Profile = {
/**/ BgBowlWall_Draw,
};
-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 Vec3f sWallTargetPositions[4] = {
+ { 0.0f, 210.0f, -20.0f }, // First wall, top
+ { 0.0f, 170.0f, -20.0f }, // Second wall, top
+ { -170.0f, 0.0f, -20.0f }, // Second wall, left
+ { 170.0f, 0.0f, -20.0f }, // Second wall, right
+};
+static s16 sWallRots[4] = {
+ 0,
+ 0, // Second wall, upright
+ 0x3FFF, // Second wall, target on the left
+ -0x3FFF, // Second wall, target on the right
};
-
-static s16 sTargetRot[] = { 0x0000, 0x0000, 0x3FFF, -0x3FFF };
void BgBowlWall_Init(Actor* thisx, PlayState* play) {
BgBowlWall* this = (BgBowlWall*)thisx;
- s32 pad1;
- s32 pad2;
- CollisionHeader* colHeader = NULL;
+ s32 pad1[2];
+ CollisionHeader* colHeader;
+ colHeader = NULL;
DynaPolyActor_Init(&this->dyna, 0);
-
- if (this->dyna.actor.params == 0) {
- CollisionHeader_GetVirtual(&gBowlingFirstAndFinalRoundCol, &colHeader);
+ if (this->dyna.actor.params == BG_BOWL_WALL_TYPE_FIRST_WALL) {
+ CollisionHeader_GetVirtual(&gBowlingFirstWallCol, &colHeader);
} else {
- CollisionHeader_GetVirtual(&gBowlingSecondRoundCol, &colHeader);
+ CollisionHeader_GetVirtual(&gBowlingSecondWallCol, &colHeader);
}
-
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader);
- this->initPos = this->dyna.actor.world.pos;
+ this->homePos = this->dyna.actor.world.pos;
PRINTF("\n\n");
- PRINTF(VT_FGCOL(GREEN)
- T(" ☆☆☆☆☆ ボーリングおじゃま壁発生 ☆☆☆☆☆ %d\n", " ☆☆☆☆☆ Bowling obstacle wall spawns ☆☆☆☆☆ %d\n") VT_RST,
- this->dyna.actor.params);
- this->actionFunc = BgBowlWall_SpawnBullseyes;
+ PRINTF(VT_FGCOL(GREEN) " ☆☆☆☆☆ ボーリングおじゃま壁発生 ☆☆☆☆☆ %d\n" VT_RST, this->dyna.actor.params);
+ this->actionFunc = BgBowlWall_InitImpl;
this->dyna.actor.scale.x = this->dyna.actor.scale.y = this->dyna.actor.scale.z = 1.0f;
}
void BgBowlWall_Destroy(Actor* thisx, PlayState* play) {
BgBowlWall* this = (BgBowlWall*)thisx;
- DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, this->dyna.bgId);
+ DynaPoly_DeleteBgActor(play, &play->colCtx.dyna, (s32)this->dyna.bgId);
}
-void BgBowlWall_SpawnBullseyes(BgBowlWall* this, PlayState* play) {
+void BgBowlWall_InitImpl(BgBowlWall* this, PlayState* play) {
+ Actor* actor;
+ EnWallTubo* target;
s32 pad;
- EnWallTubo* bullseye;
- Actor* lookForGirl;
- s16 type;
+ s16 type = this->dyna.actor.params;
- type = this->dyna.actor.params;
- if (type != 0) {
+ if (type != BG_BOWL_WALL_TYPE_FIRST_WALL) {
type += (s16)Rand_ZeroFloat(2.99f);
- this->dyna.actor.shape.rot.z = this->dyna.actor.world.rot.z = sTargetRot[type];
+ this->dyna.actor.shape.rot.z = this->dyna.actor.world.rot.z = sWallRots[type];
PRINTF("\n\n");
}
- this->bullseyeCenter.x = sBullseyeOffset[type].x + this->dyna.actor.world.pos.x;
- this->bullseyeCenter.y = sBullseyeOffset[type].y + this->dyna.actor.world.pos.y;
- this->bullseyeCenter.z = sBullseyeOffset[type].z + this->dyna.actor.world.pos.z;
- if (1) {}
- bullseye = (EnWallTubo*)Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, 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.world.pos;
+ this->effCenterPos.x = sWallTargetPositions[type].x + this->dyna.actor.world.pos.x;
+ this->effCenterPos.y = sWallTargetPositions[type].y + this->dyna.actor.world.pos.y;
+ this->effCenterPos.z = sWallTargetPositions[type].z + this->dyna.actor.world.pos.z;
+ if (0) {}
+ target = (EnWallTubo*)Actor_SpawnAsChild(&play->actorCtx, &this->dyna.actor, play, ACTOR_EN_WALL_TUBO,
+ this->effCenterPos.x, this->effCenterPos.y, this->effCenterPos.z, 0, 0, 0,
+ this->dyna.actor.params);
+ if (target != NULL) {
+ target->effCenterPos = this->effCenterPos;
+ if (type != BG_BOWL_WALL_TYPE_FIRST_WALL) {
+ target->effCenterPos = this->effCenterPos = this->dyna.actor.world.pos;
}
- if (this->chuGirl == NULL) {
- lookForGirl = play->actorCtx.actorLists[ACTORCAT_NPC].head;
- while (lookForGirl != NULL) {
- if (lookForGirl->id != ACTOR_EN_BOM_BOWL_MAN) {
- lookForGirl = lookForGirl->next;
- } else {
- this->chuGirl = (EnBomBowlMan*)lookForGirl;
- break;
+ if (this->bowlingGirl == NULL) {
+ actor = play->actorCtx.actorLists[ACTORCAT_NPC].head;
+ while (actor != NULL) {
+ if (actor->id != ACTOR_EN_BOM_BOWL_MAN) {
+ actor = actor->next;
+ continue;
}
+ this->bowlingGirl = (EnBomBowlMan*)actor;
+ break;
}
}
- this->actionFunc = BgBowlWall_WaitForHit;
+ this->actionFunc = BgBowlWall_WaitTargetHit;
}
}
-void BgBowlWall_WaitForHit(BgBowlWall* this, PlayState* play) {
- if (this->isHit) {
- this->actionFunc = BgBowlWall_FallDoEffects;
+void BgBowlWall_WaitTargetHit(BgBowlWall* this, PlayState* play) {
+ if (this->targetHit) {
+ this->actionFunc = BgBowlWall_Explode;
}
}
-void BgBowlWall_FallDoEffects(BgBowlWall* this, PlayState* play) {
- s16 pad;
- Vec3f effectAccel = { 0.0f, 0.1f, 0.0f };
- Vec3f effectVelocity = { 0.0f, 0.0f, 0.0f };
- Vec3f effectPos;
+void BgBowlWall_Explode(BgBowlWall* this, PlayState* play) {
+ s32 explode;
+ Vec3f effAccel = { 0.0f, 0.1f, 0.0f };
+ Vec3f effVel = { 0.0f, 0.0f, 0.0f };
+ Vec3f effPos;
s16 quakeIndex;
- s32 wallFallen;
s32 i;
- wallFallen = false;
-
- if (this->dyna.actor.params == 0) { // wall collapses backwards
- Math_SmoothStepToS(&this->dyna.actor.shape.rot.x, -0x3E80, 3, 500, 0);
+ explode = false;
+ if (this->dyna.actor.params == BG_BOWL_WALL_TYPE_FIRST_WALL) {
+ Math_SmoothStepToS(&this->dyna.actor.shape.rot.x, -0x3E80, 3, 0x1F4, 0);
this->dyna.actor.world.rot.x = this->dyna.actor.shape.rot.x;
if (this->dyna.actor.shape.rot.x < -0x3C1E) {
- wallFallen = true;
+ explode = true;
}
- } else { // wall slides downwards
- Math_ApproachF(&this->dyna.actor.world.pos.y, this->initPos.y - 450.0f, 0.3f, 10.0f);
- if (this->dyna.actor.world.pos.y < (this->initPos.y - 400.0f)) {
- wallFallen = true;
+ } else {
+ Math_ApproachF(&this->dyna.actor.world.pos.y, this->homePos.y - 450.0f, 0.3f, 10.0f);
+ if (this->dyna.actor.world.pos.y < (this->homePos.y - 400.0f)) {
+ explode = true;
}
}
-
- if (wallFallen) {
+ if (explode) {
for (i = 0; i < 15; i++) {
- effectPos.x = Rand_CenteredFloat(300.0f) + this->bullseyeCenter.x;
- effectPos.y = -100.0f;
- effectPos.z = Rand_CenteredFloat(400.0f) + this->bullseyeCenter.z;
- EffectSsBomb2_SpawnLayered(play, &effectPos, &effectVelocity, &effectAccel, 100, 30);
- effectPos.y = -50.0f;
- EffectSsHahen_SpawnBurst(play, &effectPos, 10.0f, 0, 50, 15, 3, HAHEN_OBJECT_DEFAULT, 10, NULL);
+ effPos.x = Rand_CenteredFloat(300.0f) + this->effCenterPos.x;
+ effPos.y = -100.0f;
+ effPos.z = Rand_CenteredFloat(400.0f) + this->effCenterPos.z;
+ EffectSsBomb2_SpawnLayered(play, &effPos, &effVel, &effAccel, 100, 30);
+ effPos.y = -50.0f;
+ EffectSsHahen_SpawnBurst(play, &effPos, 10.0f, 0, 50, 15, 3, -1, 10, NULL);
Actor_PlaySfx(&this->dyna.actor, NA_SE_IT_BOMB_EXPLOSION);
}
quakeIndex = Quake_Request(GET_ACTIVE_CAM(play), QUAKE_TYPE_1);
@@ -171,32 +164,32 @@ void BgBowlWall_FallDoEffects(BgBowlWall* this, PlayState* play) {
Quake_SetPerturbations(quakeIndex, 300, 0, 0, 0);
Quake_SetDuration(quakeIndex, 30);
this->timer = 20;
- this->actionFunc = BgBowlWall_FinishFall;
+ this->actionFunc = BgBowlWall_Disappear;
}
}
-void BgBowlWall_FinishFall(BgBowlWall* this, PlayState* play) {
+void BgBowlWall_Disappear(BgBowlWall* this, PlayState* play) {
if (this->timer >= 2) {
- if (this->dyna.actor.params == 0) {
- Math_SmoothStepToS(&this->dyna.actor.shape.rot.x, -0x3E80, 1, 200, 0);
+ if (this->dyna.actor.params == BG_BOWL_WALL_TYPE_FIRST_WALL) {
+ Math_SmoothStepToS(&this->dyna.actor.shape.rot.x, -0x3E80, 1, 0xC8, 0);
} else {
- Math_ApproachF(&this->dyna.actor.world.pos.y, this->initPos.y - 450.0f, 0.3f, 10.0f);
+ Math_ApproachF(&this->dyna.actor.world.pos.y, this->homePos.y - 450.0f, 0.3f, 10.0f);
}
} else if (this->timer == 1) {
+ this->dyna.actor.world.pos.y = this->homePos.y - 450.0f;
this->dyna.actor.world.rot.x = this->dyna.actor.shape.rot.x = 0;
- this->dyna.actor.world.pos.y = this->initPos.y - 450.0f;
- this->chuGirl->wallStatus[this->dyna.actor.params] = 2;
- this->actionFunc = BgBowlWall_Reset;
+ this->bowlingGirl->wallsState[this->dyna.actor.params] = EN_BOM_BOWL_MAN_WALL_STATE_DISAPPEARED;
+ this->actionFunc = BgBowlWall_WaitReappear;
}
}
-void BgBowlWall_Reset(BgBowlWall* this, PlayState* play) {
- if (this->chuGirl->wallStatus[this->dyna.actor.params] != 2) {
- Math_ApproachF(&this->dyna.actor.world.pos.y, this->initPos.y, 0.3f, 50.0f);
- if (fabsf(this->dyna.actor.world.pos.y - this->initPos.y) <= 10.0f) {
- this->dyna.actor.world.pos.y = this->initPos.y;
- this->isHit = false;
- this->actionFunc = BgBowlWall_SpawnBullseyes;
+void BgBowlWall_WaitReappear(BgBowlWall* this, PlayState* play) {
+ if (this->bowlingGirl->wallsState[this->dyna.actor.params] != EN_BOM_BOWL_MAN_WALL_STATE_DISAPPEARED) {
+ Math_ApproachF(&this->dyna.actor.world.pos.y, this->homePos.y, 0.3f, 50.0f);
+ if (fabsf(this->dyna.actor.world.pos.y - this->homePos.y) <= 10.0f) {
+ this->dyna.actor.world.pos.y = this->homePos.y;
+ this->targetHit = false;
+ this->actionFunc = BgBowlWall_InitImpl;
}
}
}
@@ -207,27 +200,24 @@ void BgBowlWall_Update(Actor* thisx, PlayState* play) {
if (this->timer != 0) {
this->timer--;
}
-
this->actionFunc(this, play);
}
-void BgBowlWall_Draw(Actor* thisx, PlayState* play2) {
- PlayState* play = play2;
+void BgBowlWall_Draw(Actor* thisx, PlayState* play) {
+ u32 new_var2;
BgBowlWall* this = (BgBowlWall*)thisx;
- u32 frames;
+ s32 pad;
OPEN_DISPS(play->state.gfxCtx, "../z_bg_bowl_wall.c", 441);
-
Gfx_SetupDL_25Xlu(play->state.gfxCtx);
- gSPSegment(POLY_OPA_DISP++, 0x8, Gfx_TexScroll(play->state.gfxCtx, 0, -2 * (frames = play->state.frames), 16, 16));
+ gSPSegment(POLY_OPA_DISP++, 0x8,
+ Gfx_TexScroll(play->state.gfxCtx, 0, (new_var2 = play->state.frames) * -2, 16, 16));
gDPPipeSync(POLY_OPA_DISP++);
MATRIX_FINALIZE_AND_LOAD(POLY_OPA_DISP++, play->state.gfxCtx, "../z_bg_bowl_wall.c", 453);
-
- if (this->dyna.actor.params == 0) {
- gSPDisplayList(POLY_OPA_DISP++, gBowlingRound1WallDL);
+ if (this->dyna.actor.params == BG_BOWL_WALL_TYPE_FIRST_WALL) {
+ gSPDisplayList(POLY_OPA_DISP++, gBowlingFirstWallDL);
} else {
- gSPDisplayList(POLY_OPA_DISP++, gBowlingRound2WallDL);
+ gSPDisplayList(POLY_OPA_DISP++, gBowlingSecondWallDL);
}
-
CLOSE_DISPS(play->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 c1084475755..adf5816c009 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,20 +3,24 @@
#include "ultra64.h"
#include "actor.h"
-#include "overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h"
+
+typedef enum BgBowlWallType {
+ BG_BOWL_WALL_TYPE_FIRST_WALL,
+ BG_BOWL_WALL_TYPE_SECOND_WALL
+} BgBowlWallType;
struct BgBowlWall;
typedef void (*BgBowlWallActionFunc)(struct BgBowlWall*, struct PlayState*);
typedef struct BgBowlWall {
- /* 0x0000 */ DynaPolyActor dyna;
- /* 0x0164 */ BgBowlWallActionFunc actionFunc;
- /* 0x0168 */ Vec3f initPos;
- /* 0x0174 */ Vec3f bullseyeCenter;
- /* 0x0180 */ s16 isHit;
- /* 0x0182 */ s16 timer;
- /* 0x0184 */ EnBomBowlMan* chuGirl;
-} BgBowlWall; // size = 0x0188
+ /* 0x000 */ DynaPolyActor dyna;
+ /* 0x164 */ BgBowlWallActionFunc actionFunc;
+ /* 0x168 */ Vec3f homePos;
+ /* 0x174 */ Vec3f effCenterPos;
+ /* 0x180 */ s16 targetHit;
+ /* 0x182 */ s16 timer;
+ /* 0x184 */ struct EnBomBowlMan* bowlingGirl;
+} BgBowlWall; // size = 0x188
#endif
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 2fff5313e5c..fd9dc6b5918 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,4 +1,12 @@
+/*
+ * File: z_en_bom_bowl_man.c
+ * Overlay: ovl_En_Bom_Bowl_Man
+ * Description: Bombchu Bowling Alley girl
+ */
+
#include "z_en_bom_bowl_man.h"
+#include "overlays/actors/ovl_En_Bom_Bowl_Pit/z_en_bom_bowl_pit.h"
+#include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h"
#include "overlays/actors/ovl_En_Syateki_Niw/z_en_syateki_niw.h"
#include "gfx.h"
@@ -9,8 +17,6 @@
#include "regs.h"
#include "segmented_address.h"
#include "sfx.h"
-#include "terminal.h"
-#include "translation.h"
#include "effect.h"
#include "play_state.h"
#include "player.h"
@@ -22,33 +28,31 @@
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_FRIENDLY | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
ACTOR_FLAG_DRAW_CULLING_DISABLED | ACTOR_FLAG_LOCK_ON_DISABLED)
-typedef enum BombchuGirlEyeMode {
- /* 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, PlayState* play2);
void EnBomBowlMan_Destroy(Actor* thisx, PlayState* play);
void EnBomBowlMan_Update(Actor* thisx, PlayState* play);
void EnBomBowlMan_Draw(Actor* thisx, PlayState* play);
-void EnBomBowlMan_SetupWaitAsleep(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_WaitAsleep(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_TalkAsleep(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_WakeUp(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_BlinkAwake(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_CheckBeatenDC(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_WaitNotBeatenDC(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_TalkNotBeatenDC(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_SetupRunGame(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_RunGame(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_HandlePlayChoice(EnBomBowlMan* this, PlayState* play);
-void func_809C41FC(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_SetupChooseShowPrize(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_ChooseShowPrize(EnBomBowlMan* this, PlayState* play);
-void EnBomBowlMan_BeginPlayGame(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_SetupAsleepWaitTalk(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_AsleepWaitTalk(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_AsleepTalking(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_SetupWakingUpTalking(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_WakingUpTalking(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_FinishWakingUpTalking(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_NotOpenWaitTalk(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_NotOpenTalking(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_WaitGameEndOrTalk(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_WaitPlayAnswer(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_Talking(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_WaitToShowReward(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_ShowReward(EnBomBowlMan* this, PlayState* play);
+void EnBomBowlMan_WaitGameStart(EnBomBowlMan* this, PlayState* play);
+
+typedef enum EnBomBowlManGameEndStatus {
+ EN_BOM_BOWL_MAN_GAME_END_STATUS_ONGOING,
+ EN_BOM_BOWL_MAN_GAME_END_STATUS_ENDED_WON,
+ EN_BOM_BOWL_MAN_GAME_END_STATUS_ENDED_LOST
+} EnBomBowlManGameEndStatus;
ActorProfile En_Bom_Bowl_Man_Profile = {
/**/ ACTOR_EN_BOM_BOWL_MAN,
@@ -62,483 +66,450 @@ ActorProfile En_Bom_Bowl_Man_Profile = {
/**/ EnBomBowlMan_Draw,
};
+typedef struct CuccoColliderDim {
+ f32 radius;
+ f32 height;
+ s32 unk_8; // unused
+} CuccoColliderDim;
+static CuccoColliderDim sCuccoColliderDims[2] = { { 16.0f, 46.0f, 0 }, { 36.0f, 56.0f, 0 } };
+static Vec3f sCuccoPositions[2] = { { 60.0f, -60.0f, -430.0f }, { 0.0f, -120.0f, -620.0f } };
+static f32 sCuccoScales[2] = { 0.01f, 0.03f };
+
void EnBomBowlMan_Init(Actor* thisx, PlayState* play2) {
- 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 = (EnBomBowlMan*)thisx;
- EnSyatekiNiw* cucco;
- s32 i;
PlayState* play = play2;
+ s32 i;
+ EnSyatekiNiw* cucco;
ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f);
- SkelAnime_InitFlex(play, &this->skelAnime, &gChuGirlSkel, &gChuGirlNoddingOffAnim, this->jointTable,
- this->morphTable, 11);
- PRINTF(VT_FGCOL(GREEN) T("☆ もー 肩こっちゃうよねぇ〜 \t\t ☆ \n", "☆ Man, my shoulders hurt~ \t\t ☆ \n") VT_RST);
- PRINTF(VT_FGCOL(GREEN) T("☆ もっとラクしてもうかるバイトないかしら? ☆ %d\n",
- "☆ Isn't there some sort of job that will pay better and be more relaxing? ☆ %d\n") VT_RST,
- play->bombchuBowlingStatus);
- this->posCopy = this->actor.world.pos;
+ SkelAnime_InitFlex(play, &this->skelAnime, &gBowlingGirlSkel, &gBowlingGirlSleepingAnim, this->jointTable,
+ this->morphTable, BOWLING_GIRL_LIMB_MAX);
+ PRINTF(VT_FGCOL(GREEN) "☆ もー 肩こっちゃうよねぇ〜 \t\t ☆ \n" VT_RST);
+ PRINTF(VT_FGCOL(GREEN) "☆ もっとラクしてもうかるバイトないかしら? ☆ %d\n" VT_RST, play->bombchuBowlingStatus);
+ this->homePos = this->actor.world.pos;
this->actor.shape.yOffset = -60.0f;
Actor_SetScale(&this->actor, 0.013f);
-
for (i = 0; i < 2; i++) {
- cucco = (EnSyatekiNiw*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SYATEKI_NIW, cuccoSpawnPos[i].x,
- cuccoSpawnPos[i].y, cuccoSpawnPos[i].z, 0, 0, 0, SYATEKI_MINIGAME_ALLEY);
+ cucco = (EnSyatekiNiw*)Actor_Spawn(&play->actorCtx, play, ACTOR_EN_SYATEKI_NIW, sCuccoPositions[i].x,
+ sCuccoPositions[i].y, sCuccoPositions[i].z, 0, 0, 0, SYATEKI_MINIGAME_ALLEY);
if (cucco != NULL) {
- cucco->scale = cuccoScales[i];
- cucco->collider.dim.radius = (s16)cuccoColliderDims[i][0];
- cucco->collider.dim.height = (s16)cuccoColliderDims[i][1];
+ cucco->scale = sCuccoScales[i];
+ cucco->collider.dim.radius = sCuccoColliderDims[i].radius;
+ cucco->collider.dim.height = sCuccoColliderDims[i].height;
}
}
-
- this->prizeSelect = (s16)Rand_ZeroFloat(4.99f);
+ this->rewardState = Rand_ZeroFloat(4.99f);
this->actor.attentionRangeType = ATTENTION_RANGE_1;
- this->actionFunc = EnBomBowlMan_SetupWaitAsleep;
+ this->actionFunc = EnBomBowlMan_SetupAsleepWaitTalk;
}
void EnBomBowlMan_Destroy(Actor* thisx, PlayState* play) {
}
-void EnBomBowlMan_SetupWaitAsleep(EnBomBowlMan* this, PlayState* play) {
- this->frameCount = (f32)Animation_GetLastFrame(&gChuGirlNoddingOffAnim);
- Animation_Change(&this->skelAnime, &gChuGirlNoddingOffAnim, 1.0f, 0.0f, this->frameCount, ANIMMODE_LOOP, -10.0f);
+void EnBomBowlMan_SetupAsleepWaitTalk(EnBomBowlMan* this, PlayState* play) {
+ this->curAnimFrameCount = Animation_GetLastFrame(&gBowlingGirlSleepingAnim);
+ Animation_Change(&this->skelAnime, &gBowlingGirlSleepingAnim, 1.0f, 0.0f, this->curAnimFrameCount, ANIMMODE_LOOP,
+ -10.0f);
this->actor.textId = 0xC0;
- this->dialogState = TEXT_STATE_EVENT;
- this->actionFunc = EnBomBowlMan_WaitAsleep;
+ this->waitMessageState = TEXT_STATE_EVENT;
+ this->actionFunc = EnBomBowlMan_AsleepWaitTalk;
}
-void EnBomBowlMan_WaitAsleep(EnBomBowlMan* this, PlayState* play) {
- s16 yawDiff;
+void EnBomBowlMan_AsleepWaitTalk(EnBomBowlMan* this, PlayState* play) {
+ s16 relYawTowardsPlayer;
+ s16 absRelYawTowardsPlayer;
SkelAnime_Update(&this->skelAnime);
-
if (Actor_TalkOfferAccepted(&this->actor, play)) {
- this->actionFunc = EnBomBowlMan_TalkAsleep;
+ this->actionFunc = EnBomBowlMan_AsleepTalking;
} else {
- yawDiff = ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y));
-
- if (!(this->actor.xzDistToPlayer > 120.0f) && (yawDiff < 0x4300)) {
+ relYawTowardsPlayer = this->actor.yawTowardsPlayer - this->actor.shape.rot.y;
+ absRelYawTowardsPlayer = ABS(relYawTowardsPlayer);
+ if (!(this->actor.xzDistToPlayer > 120.0f) && (absRelYawTowardsPlayer < 0x4300)) {
Actor_OfferTalk(&this->actor, play, 120.0f);
}
}
}
-void EnBomBowlMan_TalkAsleep(EnBomBowlMan* this, PlayState* play) {
+void EnBomBowlMan_AsleepTalking(EnBomBowlMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
-
- if ((Message_GetState(&play->msgCtx) == this->dialogState) && Message_ShouldAdvance(play)) {
+ if ((this->waitMessageState == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) {
play->msgCtx.msgMode = MSGMODE_PAUSED;
- this->actionFunc = EnBomBowlMan_WakeUp;
+ this->actionFunc = EnBomBowlMan_SetupWakingUpTalking;
}
}
-void EnBomBowlMan_WakeUp(EnBomBowlMan* this, PlayState* play) {
- this->frameCount = (f32)Animation_GetLastFrame(&gChuGirlWakeUpAnim);
- Animation_Change(&this->skelAnime, &gChuGirlWakeUpAnim, 1.0f, 0.0f, this->frameCount, ANIMMODE_ONCE, -10.0f);
- this->eyeMode = CHU_GIRL_EYES_OPEN_SLOWLY;
- this->actionFunc = EnBomBowlMan_BlinkAwake;
+void EnBomBowlMan_SetupWakingUpTalking(EnBomBowlMan* this, PlayState* play) {
+ this->curAnimFrameCount = Animation_GetLastFrame(&gBowlingGirlWakingUpAnim);
+ Animation_Change(&this->skelAnime, &gBowlingGirlWakingUpAnim, 1.0f, 0.0f, this->curAnimFrameCount, ANIMMODE_ONCE,
+ -10.0f);
+ this->eyesState = 1;
+ this->actionFunc = EnBomBowlMan_WakingUpTalking;
}
-void EnBomBowlMan_BlinkAwake(EnBomBowlMan* this, PlayState* play) {
- f32 frameCount = this->skelAnime.curFrame;
+void EnBomBowlMan_WakingUpTalking(EnBomBowlMan* this, PlayState* play) {
+ f32 prevFrame;
+ prevFrame = this->skelAnime.curFrame;
SkelAnime_Update(&this->skelAnime);
- if (frameCount == 30.0f) {
- this->dialogState = TEXT_STATE_EVENT;
-
- // Check for beaten Dodongo's Cavern
- if (GET_EVENTCHKINF(EVENTCHKINF_25) || BREG(2)) {
+ if (prevFrame == 30.0f) {
+ this->waitMessageState = TEXT_STATE_EVENT;
+ if (GET_EVENTCHKINF(EVENTCHKINF_25) || (BREG(2) != 0)) {
this->actor.textId = 0xBF;
} else {
this->actor.textId = 0x7058;
}
}
Message_ContinueTextbox(play, 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 = EnBomBowlMan_CheckBeatenDC;
+ if ((this->eyeTexIndex == 0) && (this->eyesState == 2) && (this->eyesTimer == 0)) {
+ this->eyeTexIndex = 2;
+ this->wakingUpTimer++;
+ if (this->wakingUpTimer >= 3) {
+ this->actionFunc = EnBomBowlMan_FinishWakingUpTalking;
}
}
}
-void EnBomBowlMan_CheckBeatenDC(EnBomBowlMan* this, PlayState* play) {
+void EnBomBowlMan_FinishWakingUpTalking(EnBomBowlMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
-
- if ((Message_GetState(&play->msgCtx) == this->dialogState) && Message_ShouldAdvance(play)) {
+ if ((this->waitMessageState == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) {
Message_CloseTextbox(play);
- this->frameCount = (f32)Animation_GetLastFrame(&gChuGirlLeanOverCounterAnim);
- Animation_Change(&this->skelAnime, &gChuGirlLeanOverCounterAnim, 1.0f, 0.0f, this->frameCount, ANIMMODE_LOOP,
- -10.0f);
- this->eyeMode = CHU_GIRL_EYES_AWAKE;
- this->blinkTimer = (s16)Rand_ZeroFloat(60.0f) + 20;
-
- // Check for beaten Dodongo's Cavern
- if (!(GET_EVENTCHKINF(EVENTCHKINF_25) || BREG(2))) {
- this->actionFunc = EnBomBowlMan_WaitNotBeatenDC;
+ this->curAnimFrameCount = Animation_GetLastFrame(&gBowlingGirlHandsOnCounterAnim);
+ Animation_Change(&this->skelAnime, &gBowlingGirlHandsOnCounterAnim, 1.0f, 0.0f, this->curAnimFrameCount,
+ ANIMMODE_LOOP, -10.0f);
+ this->eyesState = 3;
+ this->eyesTimer = (s16)Rand_ZeroFloat(60.0f) + 20;
+ if (!(GET_EVENTCHKINF(EVENTCHKINF_25) || (BREG(2) != 0))) {
+ this->actionFunc = EnBomBowlMan_NotOpenWaitTalk;
} else {
this->actor.textId = 0x18;
- this->dialogState = TEXT_STATE_CHOICE;
+ this->waitMessageState = TEXT_STATE_CHOICE;
Message_ContinueTextbox(play, this->actor.textId);
- this->actionFunc = EnBomBowlMan_HandlePlayChoice;
+ this->actionFunc = EnBomBowlMan_WaitPlayAnswer;
}
}
}
-void EnBomBowlMan_WaitNotBeatenDC(EnBomBowlMan* this, PlayState* play) {
+void EnBomBowlMan_NotOpenWaitTalk(EnBomBowlMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
-
if (Actor_TalkOfferAccepted(&this->actor, play)) {
- this->actionFunc = EnBomBowlMan_TalkNotBeatenDC;
+ this->actionFunc = EnBomBowlMan_NotOpenTalking;
} else {
Actor_OfferTalk(&this->actor, play, 120.0f);
}
}
-void EnBomBowlMan_TalkNotBeatenDC(EnBomBowlMan* this, PlayState* play) {
+void EnBomBowlMan_NotOpenTalking(EnBomBowlMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
-
- if ((Message_GetState(&play->msgCtx) == this->dialogState) && Message_ShouldAdvance(play)) {
+ if ((this->waitMessageState == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) {
Message_CloseTextbox(play);
- this->actionFunc = EnBomBowlMan_WaitNotBeatenDC;
+ this->actionFunc = EnBomBowlMan_NotOpenWaitTalk;
}
}
-void EnBomBowlMan_SetupRunGame(EnBomBowlMan* this, PlayState* play) {
+void EnBomBowlMan_SetupWaitGameEndOrTalk(EnBomBowlMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
-
- if (this->minigamePlayStatus == 0) {
- if (!this->startedPlaying) {
+ if (this->gameStartStatus == EN_BOM_BOWL_MAN_GAME_START_STATUS_INACTIVE) {
+ if (!this->hasPlayedBefore) {
this->actor.textId = 0x18;
} else {
this->actor.textId = 0x1A;
}
-
- this->dialogState = TEXT_STATE_CHOICE;
+ this->waitMessageState = TEXT_STATE_CHOICE;
} else {
this->actor.textId = 0x19;
- this->dialogState = TEXT_STATE_EVENT;
+ this->waitMessageState = TEXT_STATE_EVENT;
}
-
- this->actionFunc = EnBomBowlMan_RunGame;
+ this->actionFunc = EnBomBowlMan_WaitGameEndOrTalk;
}
-void EnBomBowlMan_RunGame(EnBomBowlMan* this, PlayState* play) {
- s16 yawDiff;
+void EnBomBowlMan_WaitGameEndOrTalk(EnBomBowlMan* this, PlayState* play) {
+ s16 relYawTowardsPlayer;
+ s16 absRelYawTowardsPlayer;
SkelAnime_Update(&this->skelAnime);
-
- if (BREG(3)) {
+ if (BREG(3) != 0) {
PRINTF(VT_FGCOL(RED) "☆ game_play->bomchu_game_flag ☆ %d\n" VT_RST, play->bombchuBowlingStatus);
- PRINTF(VT_FGCOL(RED) T("☆ 壁1の状態どう? ☆ %d\n", "☆ What's the state of wall 1? ☆ %d\n") VT_RST,
- this->wallStatus[0]);
- PRINTF(VT_FGCOL(RED) T("☆ 壁2の状態どう? ☆ %d\n", "☆ What's the state of wall 2? ☆ %d\n") VT_RST,
- this->wallStatus[1]);
- PRINTF(VT_FGCOL(RED) T("☆ 穴情報\t ☆ %d\n", "☆ Hole Information\t ☆ %d\n") VT_RST,
- this->bowlPit->status);
+ PRINTF(VT_FGCOL(RED) "☆ 壁1の状態どう? ☆ %d\n" VT_RST, this->wallsState[0]);
+ PRINTF(VT_FGCOL(RED) "☆ 壁2の状態どう? ☆ %d\n" VT_RST, this->wallsState[1]);
+ PRINTF(VT_FGCOL(RED) "☆ 穴情報\t ☆ %d\n" VT_RST, this->finalTargetManager->rewardState);
PRINTF("\n\n");
}
-
- this->gameResult = 0;
-
- if (this->bowlPit != NULL) {
- if ((this->wallStatus[0] != 1) && (this->wallStatus[1] != 1) && (this->bowlPit->status == 2)) {
- this->gameResult = 1; // Won
- this->bowlPit->status = 0;
- PRINTF(VT_FGCOL(MAGENTA) T("☆☆☆☆☆ 中央HIT!!!! ☆☆☆☆☆ \n", "☆☆☆☆☆ Center HIT!!!! ☆☆☆☆☆ \n") VT_RST);
+ this->gameEndStatus = EN_BOM_BOWL_MAN_GAME_END_STATUS_ONGOING;
+ if (this->finalTargetManager != NULL) {
+ if ((this->wallsState[0] != EN_BOM_BOWL_MAN_WALL_STATE_HIT) &&
+ (this->wallsState[1] != EN_BOM_BOWL_MAN_WALL_STATE_HIT) &&
+ (this->finalTargetManager->rewardState == EN_BOM_BOWL_PIT_REWARD_STATE_REWARD_GIVEN)) {
+ this->gameEndStatus = EN_BOM_BOWL_MAN_GAME_END_STATUS_ENDED_WON;
+ this->finalTargetManager->rewardState = EN_BOM_BOWL_PIT_REWARD_STATE_WAIT_HIT;
+ PRINTF(VT_FGCOL(MAGENTA) "☆☆☆☆☆ 中央HIT!!!! ☆☆☆☆☆ \n" VT_RST);
}
-
if ((play->bombchuBowlingStatus == -1) && (play->actorCtx.actorLists[ACTORCAT_EXPLOSIVE].length == 0) &&
- (this->bowlPit->status == 0) && (this->wallStatus[0] != 1) && (this->wallStatus[1] != 1)) {
- this->gameResult = 2; // Lost
- PRINTF(VT_FGCOL(MAGENTA) T("☆☆☆☆☆ ボムチュウ消化 ☆☆☆☆☆ \n", "☆☆☆☆☆ Bombchu digestion ☆☆☆☆☆ \n") VT_RST);
+ (this->finalTargetManager->rewardState == EN_BOM_BOWL_PIT_REWARD_STATE_WAIT_HIT) &&
+ (this->wallsState[0] != EN_BOM_BOWL_MAN_WALL_STATE_HIT) &&
+ (this->wallsState[1] != EN_BOM_BOWL_MAN_WALL_STATE_HIT)) {
+ this->gameEndStatus = EN_BOM_BOWL_MAN_GAME_END_STATUS_ENDED_LOST;
+ PRINTF(VT_FGCOL(MAGENTA) "☆☆☆☆☆ ボムチュウ消化 ☆☆☆☆☆ \n" VT_RST);
}
}
-
- if (this->gameResult != 0) { // won or lost
+ if (this->gameEndStatus != EN_BOM_BOWL_MAN_GAME_END_STATUS_ONGOING) {
this->actor.textId = 0x1A;
- this->dialogState = TEXT_STATE_CHOICE;
- this->minigamePlayStatus = 0;
-
- if ((this->exItem != NULL) && (this->exItem->actor.update != NULL)) {
- this->exItem->killItem = true;
- this->exItem = NULL;
+ this->waitMessageState = TEXT_STATE_CHOICE;
+ this->gameStartStatus = EN_BOM_BOWL_MAN_GAME_START_STATUS_INACTIVE;
+ if ((this->rewardItemOnCounter != NULL) && (this->rewardItemOnCounter->actor.update != NULL)) {
+ this->rewardItemOnCounter->killItem = true;
+ this->rewardItemOnCounter = NULL;
}
-
play->bombchuBowlingStatus = 0;
- this->playingAgain = true;
+ this->isAskingToPlayAgain = true;
Message_StartTextbox(play, this->actor.textId, NULL);
-
- if (this->gameResult == 2) {
+ if (this->gameEndStatus == EN_BOM_BOWL_MAN_GAME_END_STATUS_ENDED_LOST) {
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_8);
}
- this->actionFunc = EnBomBowlMan_HandlePlayChoice;
- } else {
- if (Actor_TalkOfferAccepted(&this->actor, play)) {
- if (this->minigamePlayStatus == 0) {
- this->actionFunc = EnBomBowlMan_HandlePlayChoice;
- } else {
- this->actionFunc = func_809C41FC;
- }
+ this->actionFunc = EnBomBowlMan_WaitPlayAnswer;
+ } else if (Actor_TalkOfferAccepted(&this->actor, play)) {
+ if (this->gameStartStatus == EN_BOM_BOWL_MAN_GAME_START_STATUS_INACTIVE) {
+ this->actionFunc = EnBomBowlMan_WaitPlayAnswer;
} else {
- yawDiff = ABS((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y));
-
- if (!(this->actor.xzDistToPlayer > 120.0f) && (yawDiff < 0x4300)) {
- Actor_OfferTalk(&this->actor, play, 120.0f);
- }
+ this->actionFunc = EnBomBowlMan_Talking;
+ }
+ } else {
+ relYawTowardsPlayer = this->actor.yawTowardsPlayer - this->actor.shape.rot.y;
+ absRelYawTowardsPlayer = ABS(relYawTowardsPlayer);
+ if (!(this->actor.xzDistToPlayer > 120.0f) && (absRelYawTowardsPlayer < 0x4300)) {
+ Actor_OfferTalk(&this->actor, play, 120.0f);
}
}
}
-void EnBomBowlMan_HandlePlayChoice(EnBomBowlMan* this, PlayState* play) {
+void EnBomBowlMan_WaitPlayAnswer(EnBomBowlMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
-
- if ((Message_GetState(&play->msgCtx) == this->dialogState) && Message_ShouldAdvance(play)) {
+ if ((this->waitMessageState == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) {
Message_CloseTextbox(play);
-
switch (play->msgCtx.choiceIndex) {
- case 0: // Yes
+ case 0: // yes
if (gSaveContext.save.info.playerData.rupees >= 30) {
Rupees_ChangeBy(-30);
- this->minigamePlayStatus = 1;
- this->wallStatus[0] = this->wallStatus[1] = 0;
+ this->gameStartStatus = EN_BOM_BOWL_MAN_GAME_START_STATUS_PAID;
+ this->wallsState[0] = this->wallsState[1] = EN_BOM_BOWL_MAN_WALL_STATE_STANDING;
play->bombchuBowlingStatus = 10;
Flags_SetSwitch(play, 0x38);
-
- if (!this->startedPlaying && !this->playingAgain) {
+ if (!this->hasPlayedBefore && !this->isAskingToPlayAgain) {
this->actor.textId = 0x19;
Message_ContinueTextbox(play, this->actor.textId);
- this->dialogState = TEXT_STATE_EVENT;
- this->actionFunc = func_809C41FC;
+ this->waitMessageState = TEXT_STATE_EVENT;
+ this->actionFunc = EnBomBowlMan_Talking;
} else {
this->actor.textId = 0x1B;
Message_ContinueTextbox(play, this->actor.textId);
- this->dialogState = TEXT_STATE_EVENT;
+ this->waitMessageState = TEXT_STATE_EVENT;
OnePointCutscene_Init(play, 8010, -99, NULL, CAM_ID_MAIN);
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_8);
- this->actionFunc = EnBomBowlMan_SetupChooseShowPrize;
+ this->actionFunc = EnBomBowlMan_WaitToShowReward;
}
} else {
- this->playingAgain = false;
+ this->isAskingToPlayAgain = false;
this->actor.textId = 0x85;
Message_ContinueTextbox(play, this->actor.textId);
- this->dialogState = TEXT_STATE_EVENT;
- this->actionFunc = func_809C41FC;
+ this->waitMessageState = TEXT_STATE_EVENT;
+ this->actionFunc = EnBomBowlMan_Talking;
}
break;
-
- case 1: // No
- this->playingAgain = false;
+ case 1: // no
+ this->isAskingToPlayAgain = false;
this->actor.textId = 0x2D;
Message_ContinueTextbox(play, this->actor.textId);
- this->dialogState = TEXT_STATE_EVENT;
- this->actionFunc = func_809C41FC;
+ this->waitMessageState = TEXT_STATE_EVENT;
+ this->actionFunc = EnBomBowlMan_Talking;
+ break;
}
}
}
-void func_809C41FC(EnBomBowlMan* this, PlayState* play) {
+void EnBomBowlMan_Talking(EnBomBowlMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
- if ((Message_GetState(&play->msgCtx) == this->dialogState) && Message_ShouldAdvance(play)) {
+ if ((this->waitMessageState == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) {
Message_CloseTextbox(play);
-
if (((this->actor.textId == 0x2D) || (this->actor.textId == 0x85)) && Flags_GetSwitch(play, 0x38)) {
Flags_UnsetSwitch(play, 0x38);
}
-
- if (this->minigamePlayStatus == 1) {
+ if (this->gameStartStatus == EN_BOM_BOWL_MAN_GAME_START_STATUS_PAID) {
this->actor.textId = 0x1B;
Message_ContinueTextbox(play, this->actor.textId);
- this->dialogState = TEXT_STATE_EVENT;
+ this->waitMessageState = TEXT_STATE_EVENT;
OnePointCutscene_Init(play, 8010, -99, NULL, CAM_ID_MAIN);
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_8);
- this->actionFunc = EnBomBowlMan_SetupChooseShowPrize;
+ this->actionFunc = EnBomBowlMan_WaitToShowReward;
} else {
- if (this->gameResult == 2) {
+ if (this->gameEndStatus == EN_BOM_BOWL_MAN_GAME_END_STATUS_ENDED_LOST) {
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_7);
}
- this->actionFunc = EnBomBowlMan_SetupRunGame;
+ this->actionFunc = EnBomBowlMan_SetupWaitGameEndOrTalk;
}
}
}
-void EnBomBowlMan_SetupChooseShowPrize(EnBomBowlMan* this, PlayState* play) {
- Vec3f accel = { 0.0f, 0.1f, 0.0f };
- Vec3f velocity = { 0.0f, 0.0f, 0.0f };
- Vec3f pos;
+void EnBomBowlMan_WaitToShowReward(EnBomBowlMan* this, PlayState* play) {
+ Vec3f effAccel = { 0.0f, 0.1f, 0.0f };
+ Vec3f effVel = { 0.0f, 0.0f, 0.0f };
+ Vec3f effPos;
SkelAnime_Update(&this->skelAnime);
-
- if ((Message_GetState(&play->msgCtx) == this->dialogState) && Message_ShouldAdvance(play)) {
- pos.x = 148.0f;
- pos.y = 40.0f;
- pos.z = 300.0f;
- EffectSsBomb2_SpawnLayered(play, &pos, &velocity, &accel, 50, 15);
+ if ((this->waitMessageState == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) {
+ effPos.x = 148.0f;
+ effPos.y = 40.0f;
+ effPos.z = 300.0f;
+ EffectSsBomb2_SpawnLayered(play, &effPos, &effVel, &effAccel, 50, 15);
Actor_PlaySfx(&this->actor, NA_SE_IT_GOODS_APPEAR);
- this->prizeRevealTimer = 10;
- this->actionFunc = EnBomBowlMan_ChooseShowPrize;
+ this->rewardAppearTimer = 10;
+ this->actionFunc = EnBomBowlMan_ShowReward;
}
}
-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 };
-
-void EnBomBowlMan_ChooseShowPrize(EnBomBowlMan* this, PlayState* play) {
- s16 prizeTemp;
+void EnBomBowlMan_ShowReward(EnBomBowlMan* this, PlayState* play) {
+ static Vec3f sCounterRewardPosOffset[5] = {
+ { 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 sCounterRewardSpawnYaw[5] = { 0x4268, 0x4268, -0x3E8, 0, 0x4268 };
+ s16 reward;
s32 pad;
SkelAnime_Update(&this->skelAnime);
-
- if (this->prizeRevealTimer == 0) {
- switch (this->prizeSelect) {
+ if (this->rewardAppearTimer == 0) {
+ switch (this->rewardState) {
case 0:
- prizeTemp = EXITEM_BOMB_BAG_BOWLING;
- if (GET_ITEMGETINF(ITEMGETINF_11)) {
- prizeTemp = EXITEM_PURPLE_RUPEE_BOWLING;
+ reward = EXITEM_BOMB_BAG_BOWLING;
+ if (GET_ITEMGETINF(ITEMGETINF_BOWLING_BOMB_BAG)) {
+ reward = EXITEM_PURPLE_RUPEE_BOWLING;
}
break;
case 1:
- prizeTemp = EXITEM_PURPLE_RUPEE_BOWLING;
+ reward = EXITEM_PURPLE_RUPEE_BOWLING;
break;
case 2:
- prizeTemp = EXITEM_BOMBCHUS_BOWLING;
+ reward = EXITEM_BOMBCHUS_BOWLING;
break;
case 3:
- prizeTemp = EXITEM_HEART_PIECE_BOWLING;
- if (GET_ITEMGETINF(ITEMGETINF_12)) {
- prizeTemp = EXITEM_PURPLE_RUPEE_BOWLING;
+ reward = EXITEM_HEART_PIECE_BOWLING;
+ if (GET_ITEMGETINF(ITEMGETINF_BOWLING_HEART_PIECE)) {
+ reward = EXITEM_PURPLE_RUPEE_BOWLING;
}
break;
case 4:
- prizeTemp = EXITEM_BOMBS_BOWLING;
+ reward = EXITEM_BOMBS_BOWLING;
break;
}
-
- this->prizeIndex = prizeTemp;
-
- if (BREG(7)) {
- this->prizeIndex = BREG(7) - 1;
+ this->reward = reward;
+ if (BREG(7) != 0) {
+ this->reward = BREG(7) - 1;
}
-
- this->exItem = (EnExItem*)Actor_SpawnAsChild(
- &play->actorCtx, &this->actor, play, 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 + EXITEM_BOMB_BAG_COUNTER);
-
- if (!this->startedPlaying) {
- this->bowlPit = (EnBomBowlPit*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play,
- ACTOR_EN_BOM_BOWL_PIT, 0.0f, 90.0f, -860.0f, 0, 0, 0, 0);
- if (this->bowlPit != NULL) {
- this->bowlPit->prizeIndex = this->prizeIndex;
+ this->rewardItemOnCounter = (EnExItem*)Actor_SpawnAsChild(
+ &play->actorCtx, &this->actor, play, ACTOR_EN_EX_ITEM, sCounterRewardPosOffset[this->reward].x + 148.0f,
+ sCounterRewardPosOffset[this->reward].y + 40.0f, sCounterRewardPosOffset[this->reward].z + 300.0f, 0,
+ sCounterRewardSpawnYaw[this->reward], 0, this->reward + EXITEM_BOMB_BAG_COUNTER);
+ if (!this->hasPlayedBefore) {
+ // Spawn in the center of the final wall target
+ this->finalTargetManager = (EnBomBowlPit*)Actor_SpawnAsChild(
+ &play->actorCtx, &this->actor, play, ACTOR_EN_BOM_BOWL_PIT, 0.0f, 90.0f, -860.0f, 0, 0, 0, 0);
+ if (this->finalTargetManager != NULL) {
+ this->finalTargetManager->reward = this->reward;
}
} else {
- this->bowlPit->prizeIndex = this->prizeIndex;
+ this->finalTargetManager->reward = this->reward;
}
-
- this->bowlPit->start = 1;
- this->minigamePlayStatus = 2;
+ this->finalTargetManager->gameStarted = true;
+ this->gameStartStatus = EN_BOM_BOWL_MAN_GAME_START_STATUS_STARTED;
this->actor.textId = 0x405A;
Message_ContinueTextbox(play, this->actor.textId);
- this->dialogState = TEXT_STATE_EVENT;
-
- // Cycle through prizes in order
- this->prizeSelect++;
- if (this->prizeSelect >= 5) {
- this->prizeSelect = 0;
+ this->waitMessageState = TEXT_STATE_EVENT;
+ this->rewardState += 1;
+ if (this->rewardState >= 5) {
+ this->rewardState = 0;
}
- this->actionFunc = EnBomBowlMan_BeginPlayGame;
+ this->actionFunc = EnBomBowlMan_WaitGameStart;
}
}
-void EnBomBowlMan_BeginPlayGame(EnBomBowlMan* this, PlayState* play) {
+void EnBomBowlMan_WaitGameStart(EnBomBowlMan* this, PlayState* play) {
SkelAnime_Update(&this->skelAnime);
-
- if ((Message_GetState(&play->msgCtx) == this->dialogState) && Message_ShouldAdvance(play)) {
+ if ((this->waitMessageState == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) {
Message_CloseTextbox(play);
- Camera_SetFinishedFlag(GET_ACTIVE_CAM(play));
- this->startedPlaying = true;
-
- if (BREG(2)) {
+ Camera_SetFinishedFlag(play->cameraPtrs[play->activeCamId]);
+ this->hasPlayedBefore = true;
+ if (BREG(2) != 0) {
BREG(2) = 0;
}
-
- PRINTF(VT_FGCOL(YELLOW) T("☆ わー ☆ %d\n", "☆ Wow ☆ %d\n") VT_RST, play->bombchuBowlingStatus);
+ PRINTF(VT_FGCOL(YELLOW) "☆ わー ☆ %d\n" VT_RST, play->bombchuBowlingStatus);
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_7);
- this->actionFunc = EnBomBowlMan_SetupRunGame;
+ this->actionFunc = EnBomBowlMan_SetupWaitGameEndOrTalk;
}
}
void EnBomBowlMan_Update(Actor* thisx, PlayState* play) {
EnBomBowlMan* this = (EnBomBowlMan*)thisx;
- this->timer++;
+ this->unk_22C++;
this->actor.focus.pos.y = 60.0f;
Actor_SetFocus(&this->actor, 60.0f);
-
- switch (this->eyeMode) {
- case CHU_GIRL_EYES_ASLEEP:
- this->eyeTextureIndex = 2;
+ switch (this->eyesState) {
+ case 0:
+ this->eyeTexIndex = 2;
break;
- case CHU_GIRL_EYES_OPEN_SLOWLY:
- if (this->eyeTextureIndex > 0) {
- this->eyeTextureIndex--;
+ case 1:
+ if (this->eyeTexIndex > 0) {
+ this->eyeTexIndex--;
} else {
- this->blinkTimer = 30;
- this->eyeMode = CHU_GIRL_EYES_BLINK_RAPIDLY;
+ this->eyesTimer = 30;
+ this->eyesState = 2;
}
break;
- case CHU_GIRL_EYES_BLINK_RAPIDLY:
- if ((this->blinkTimer == 0) && (this->eyeTextureIndex > 0)) {
- this->eyeTextureIndex--;
+ case 2:
+ if (this->eyesTimer == 0) {
+ if (this->eyeTexIndex > 0) {
+ this->eyeTexIndex--;
+ }
}
break;
default:
- if (this->blinkTimer == 0) {
- this->eyeTextureIndex++;
- if (this->eyeTextureIndex >= 3) {
- this->eyeTextureIndex = 0;
- this->blinkTimer = (s16)Rand_ZeroFloat(60.0f) + 20;
+ if (this->eyesTimer == 0) {
+ this->eyeTexIndex += 1;
+ if (this->eyeTexIndex >= 3) {
+ this->eyeTexIndex = 0;
+ this->eyesTimer = (s16)Rand_ZeroFloat(60.0f) + 20;
}
}
-
- Actor_TrackPlayer(play, &this->actor, &this->unk_218, &this->unk_224, this->actor.focus.pos);
+ Actor_TrackPlayer(play, &this->actor, &this->headRot, &this->torsoRot, this->actor.focus.pos);
break;
}
+ if (this->rewardAppearTimer == 0) {
- DECR(this->prizeRevealTimer);
- DECR(this->blinkTimer);
-
+ } else {
+ this->rewardAppearTimer--;
+ }
+ if (this->eyesTimer != 0) {
+ this->eyesTimer--;
+ }
this->actionFunc(this, play);
}
s32 EnBomBowlMan_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, void* thisx) {
- EnBomBowlMan* this = (EnBomBowlMan*)thisx;
+ EnBomBowlMan* this = thisx;
- if (limbIndex == 4) { // head
- rot->x += this->unk_218.y;
- rot->z += this->unk_218.z;
+ if (limbIndex == BOWLING_GIRL_LIMB_HEAD) {
+ rot->x += this->headRot.y;
+ rot->z += this->headRot.z;
}
-
- return false;
+ return 0;
}
void EnBomBowlMan_Draw(Actor* thisx, PlayState* play) {
- static void* eyeTextures[] = { gChuGirlEyeOpenTex, gChuGirlEyeHalfTex, gChuGirlEyeClosedTex };
+ static void* sEyeTextures[] = { gBowlingGirlEyeOpenTex, gBowlingGirlEyeHalfTex, gBowlingGirlEyeClosedTex };
EnBomBowlMan* this = (EnBomBowlMan*)thisx;
OPEN_DISPS(play->state.gfxCtx, "../z_en_bom_bowl_man.c", 907);
-
Gfx_SetupDL_25Opa(play->state.gfxCtx);
- gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(eyeTextures[this->eyeTextureIndex]));
+ gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(sEyeTextures[this->eyeTexIndex]));
SkelAnime_DrawFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount,
EnBomBowlMan_OverrideLimbDraw, NULL, this);
-
CLOSE_DISPS(play->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 2b85ab84acd..e162188ee1e 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,40 +3,54 @@
#include "ultra64.h"
#include "actor.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"
+
+#include "assets/objects/object_bg/object_bg.h"
+
+typedef enum EnBomBowlManWallState {
+ EN_BOM_BOWL_MAN_WALL_STATE_STANDING,
+ EN_BOM_BOWL_MAN_WALL_STATE_HIT,
+ EN_BOM_BOWL_MAN_WALL_STATE_DISAPPEARED
+} EnBomBowlManWallState;
+
+typedef enum EnBomBowlManGameStartStatus {
+ EN_BOM_BOWL_MAN_GAME_START_STATUS_INACTIVE,
+ EN_BOM_BOWL_MAN_GAME_START_STATUS_PAID,
+ EN_BOM_BOWL_MAN_GAME_START_STATUS_STARTED
+} EnBomBowlManGameStartStatus;
struct EnBomBowlMan;
typedef void (*EnBomBowlManActionFunc)(struct EnBomBowlMan*, struct PlayState*);
typedef struct EnBomBowlMan {
- /* 0x0000 */ Actor actor;
- /* 0x014C */ SkelAnime skelAnime;
- /* 0x0190 */ Vec3s jointTable[11];
- /* 0x01D2 */ Vec3s morphTable[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;
+ /* 0x000 */ Actor actor;
+ /* 0x14C */ SkelAnime skelAnime;
+ /* 0x190 */ Vec3s jointTable[BOWLING_GIRL_LIMB_MAX];
+ /* 0x1D2 */ Vec3s morphTable[BOWLING_GIRL_LIMB_MAX];
+ /* 0x214 */ EnBomBowlManActionFunc actionFunc;
+ /* 0x218 */ Vec3s headRot;
+ /* 0x21E */ char pad_21E[6];
+ /* 0x224 */ Vec3s torsoRot;
+ /* 0x22A */ s16 rewardAppearTimer;
+ /* 0x22C */ s16 unk_22C; // unused
+ /* 0x22E */ s16 waitMessageState;
+ /* 0x230 */ s16 reward;
+ /* 0x232 */ s16 hasPlayedBefore;
+ /* 0x234 */ s16 eyeTexIndex;
+ /* 0x236 */ s16 eyesTimer;
+ /* 0x238 */ s16 eyesState;
+ /* 0x23A */ s16 wakingUpTimer;
+ /* 0x23C */ s16 isAskingToPlayAgain;
+ /* 0x23E */ s16 wallsState[2]; // State of the first two walls
+ /* 0x242 */ s16 rewardState;
+ /* 0x244 */ s16 gameEndStatus;
+ /* 0x246 */ char pad_246[2];
+ /* 0x248 */ Vec3f homePos;
+ /* 0x254 */ f32 curAnimFrameCount;
+ /* 0x258 */ u8 gameStartStatus;
+ /* 0x259 */ char pad_259[3];
+ /* 0x25C */ struct EnBomBowlPit* finalTargetManager;
+ /* 0x260 */ struct EnExItem* rewardItemOnCounter;
} EnBomBowlMan; // size = 0x0264
#endif
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 43207a9992b..4aca24992a5 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,15 +1,21 @@
+/*
+ * File: z_en_bom_bowl_pit.c
+ * Overlay: ovl_En_Bom_Bowl_Pit
+ * Description: Bowling Alley bombchu detector for the final wall
+ */
+
#include "z_en_bom_bowl_pit.h"
#include "overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h"
+#include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h"
#include "printf.h"
#include "regs.h"
-#include "sfx.h"
-#include "terminal.h"
-#include "translation.h"
-#include "z_lib.h"
+#include "camera.h"
#include "play_state.h"
#include "player.h"
#include "save.h"
+#include "sfx.h"
+#include "z_lib.h"
#define FLAGS ACTOR_FLAG_UPDATE_CULLING_DISABLED
@@ -17,16 +23,22 @@ void EnBomBowlPit_Init(Actor* thisx, PlayState* play);
void EnBomBowlPit_Destroy(Actor* thisx, PlayState* play);
void EnBomBowlPit_Update(Actor* thisx, PlayState* play);
-void EnBomBowlPit_SetupDetectHit(EnBomBowlPit* this, PlayState* play);
-void EnBomBowlPit_DetectHit(EnBomBowlPit* this, PlayState* play);
-void EnBomBowlPit_CameraDollyIn(EnBomBowlPit* this, PlayState* play);
-void EnBomBowlPit_SpawnPrize(EnBomBowlPit* this, PlayState* play);
-void EnBomBowlPit_SetupGivePrize(EnBomBowlPit* this, PlayState* play);
-void EnBomBowlPit_GivePrize(EnBomBowlPit* this, PlayState* play);
-void EnBomBowlPit_WaitTillPrizeGiven(EnBomBowlPit* this, PlayState* play);
-void EnBomBowlPit_Reset(EnBomBowlPit* this, PlayState* play);
-
-static s32 sGetItemIds[] = { GI_BOMB_BAG_30, GI_HEART_PIECE, GI_BOMBCHUS_10, GI_BOMBS_1, GI_RUPEE_PURPLE };
+void EnBomBowlPit_WaitGameStarted(EnBomBowlPit* this, PlayState* play);
+void EnBomBowlPit_WaitHit(EnBomBowlPit* this, PlayState* play);
+void EnBomBowlPit_WaitCutscene(EnBomBowlPit* this, PlayState* play);
+void EnBomBowlPit_SpawnReward(EnBomBowlPit* this, PlayState* play);
+void EnBomBowlPit_WaitRewardFinishedAppearing(EnBomBowlPit* this, PlayState* play);
+void EnBomBowlPit_GiveReward(EnBomBowlPit* this, PlayState* play);
+void EnBomBowlPit_WaitRewardGiven(EnBomBowlPit* this, PlayState* play);
+void EnBomBowlPit_WaitRewardText(EnBomBowlPit* this, PlayState* play);
+
+static s32 sGetItemIdRewards[5] = {
+ GI_BOMB_BAG_30, // EXITEM_BOMB_BAG_BOWLING
+ GI_HEART_PIECE, // EXITEM_HEART_PIECE_BOWLING
+ GI_BOMBCHUS_10, // EXITEM_BOMBCHUS_BOWLING
+ GI_BOMBS_1, // EXITEM_BOMBS_BOWLING
+ GI_RUPEE_PURPLE, // EXITEM_PURPLE_RUPEE_BOWLING
+};
ActorProfile En_Bom_Bowl_Pit_Profile = {
/**/ ACTOR_EN_BOM_BOWL_PIT,
@@ -43,89 +55,79 @@ ActorProfile En_Bom_Bowl_Pit_Profile = {
void EnBomBowlPit_Init(Actor* thisx, PlayState* play) {
EnBomBowlPit* this = (EnBomBowlPit*)thisx;
- this->actionFunc = EnBomBowlPit_SetupDetectHit;
+ this->actionFunc = EnBomBowlPit_WaitGameStarted;
}
void EnBomBowlPit_Destroy(Actor* thisx, PlayState* play) {
}
-void EnBomBowlPit_SetupDetectHit(EnBomBowlPit* this, PlayState* play) {
- if (this->start != 0) {
- this->start = this->status = 0;
- this->actionFunc = EnBomBowlPit_DetectHit;
+void EnBomBowlPit_WaitGameStarted(EnBomBowlPit* this, PlayState* play) {
+ if (this->gameStarted) {
+ this->gameStarted = this->rewardState = 0; // false, EN_BOM_BOWL_PIT_REWARD_STATE_WAIT_HIT
+ this->actionFunc = EnBomBowlPit_WaitHit;
}
}
-void EnBomBowlPit_DetectHit(EnBomBowlPit* this, PlayState* play) {
- EnBomChu* chu;
- Vec3f chuPosDiff;
+void EnBomBowlPit_WaitHit(EnBomBowlPit* this, PlayState* play) {
+ Actor* explosive;
+ EnBomChu* bombchu;
+ Vec3f diff;
+ Actor* thisx = &this->actor;
if (play->cameraPtrs[CAM_ID_MAIN]->setting == CAM_SET_CHU_BOWLING) {
- chu = (EnBomChu*)play->actorCtx.actorLists[ACTORCAT_EXPLOSIVE].head;
-
- while (chu != NULL) {
- if ((&chu->actor == &this->actor) || (chu->actor.id != ACTOR_EN_BOM_CHU)) {
- chu = (EnBomChu*)chu->actor.next;
+ explosive = play->actorCtx.actorLists[ACTORCAT_EXPLOSIVE].head;
+ while (explosive != NULL) {
+ if ((explosive == thisx) || (explosive->id != ACTOR_EN_BOM_CHU)) {
+ explosive = explosive->next;
continue;
}
-
- chuPosDiff.x = chu->actor.world.pos.x - this->actor.world.pos.x;
- chuPosDiff.y = chu->actor.world.pos.y - this->actor.world.pos.y;
- chuPosDiff.z = chu->actor.world.pos.z - this->actor.world.pos.z;
-
- if (((fabsf(chuPosDiff.x) < 40.0f) || (BREG(2))) && ((fabsf(chuPosDiff.y) < 40.0f) || (BREG(2))) &&
- ((fabsf(chuPosDiff.z) < 40.0f) || (BREG(2)))) {
+ diff.x = explosive->world.pos.x - this->actor.world.pos.x;
+ diff.y = explosive->world.pos.y - this->actor.world.pos.y;
+ diff.z = explosive->world.pos.z - this->actor.world.pos.z;
+ if (((fabsf(diff.x) < 40.0f) || (BREG(2) != 0)) && ((fabsf(diff.y) < 40.0f) || (BREG(2) != 0)) &&
+ ((fabsf(diff.z) < 40.0f) || (BREG(2) != 0))) {
+ bombchu = (EnBomChu*)explosive;
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_8);
- chu->timer = 1;
-
+ bombchu->timer = 1;
this->subCamId = Play_CreateSubCamera(play);
Play_ChangeCameraStatus(play, CAM_ID_MAIN, CAM_STAT_WAIT);
Play_ChangeCameraStatus(play, this->subCamId, CAM_STAT_ACTIVE);
-
this->subCamAtMaxVelFrac.x = this->subCamAtMaxVelFrac.y = this->subCamAtMaxVelFrac.z = 0.1f;
this->subCamEyeMaxVelFrac.x = this->subCamEyeMaxVelFrac.y = this->subCamEyeMaxVelFrac.z = 0.1f;
-
this->subCamAt.x = this->viewAt.x = play->view.at.x;
this->subCamAt.y = this->viewAt.y = play->view.at.y;
this->subCamAt.z = this->viewAt.z = play->view.at.z;
-
this->subCamEye.x = this->viewEye.x = play->view.eye.x;
this->subCamEye.y = this->viewEye.y = play->view.eye.y;
this->subCamEye.z = this->viewEye.z = play->view.eye.z;
-
this->subCamAtNext.x = 20.0f;
this->subCamAtNext.y = 100.0f;
this->subCamAtNext.z = -800.0f;
-
this->subCamEyeNext.x = 20.0f;
this->subCamEyeNext.y = 50.0f;
this->subCamEyeNext.z = -485.0f;
-
this->subCamEyeVel.x = fabsf(this->subCamEye.x - this->subCamEyeNext.x) * 0.02f;
this->subCamEyeVel.y = fabsf(this->subCamEye.y - this->subCamEyeNext.y) * 0.02f;
this->subCamEyeVel.z = fabsf(this->subCamEye.z - this->subCamEyeNext.z) * 0.02f;
-
this->subCamAtVel.x = fabsf(this->subCamAt.x - this->subCamAtNext.x) * 0.02f;
this->subCamAtVel.y = fabsf(this->subCamAt.y - this->subCamAtNext.y) * 0.02f;
this->subCamAtVel.z = fabsf(this->subCamAt.z - this->subCamAtNext.z) * 0.02f;
-
Play_SetCameraAtEye(play, this->subCamId, &this->subCamAt, &this->subCamEye);
this->actor.textId = 0xF;
Message_StartTextbox(play, this->actor.textId, NULL);
- this->unk_154 = TEXT_STATE_EVENT;
+ this->waitMessageState = TEXT_STATE_EVENT;
Sfx_PlaySfxCentered(NA_SE_EV_HIT_SOUND);
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_8);
- this->status = 1;
- this->actionFunc = EnBomBowlPit_CameraDollyIn;
- break;
- } else {
- chu = (EnBomChu*)chu->actor.next;
+ this->rewardState = EN_BOM_BOWL_PIT_REWARD_STATE_GIVING_REWARD;
+ this->actionFunc = EnBomBowlPit_WaitCutscene;
+ return;
}
+ explosive = explosive->next;
}
}
}
-void EnBomBowlPit_CameraDollyIn(EnBomBowlPit* this, PlayState* play) {
+void EnBomBowlPit_WaitCutscene(EnBomBowlPit* this, PlayState* play) {
if (this->subCamId != SUB_CAM_ID_DONE) {
Math_ApproachF(&this->subCamAt.x, this->subCamAtNext.x, this->subCamAtMaxVelFrac.x, this->subCamAtVel.x);
Math_ApproachF(&this->subCamAt.y, this->subCamAtNext.y, this->subCamAtMaxVelFrac.y, this->subCamAtVel.y);
@@ -134,13 +136,10 @@ void EnBomBowlPit_CameraDollyIn(EnBomBowlPit* this, PlayState* play) {
Math_ApproachF(&this->subCamEye.y, this->subCamEyeNext.y, this->subCamEyeMaxVelFrac.y, this->subCamEyeVel.y);
Math_ApproachF(&this->subCamEye.z, this->subCamEyeNext.z, this->subCamEyeMaxVelFrac.z, this->subCamEyeVel.z);
}
-
Play_SetCameraAtEye(play, this->subCamId, &this->subCamAt, &this->subCamEye);
-
- if ((this->unk_154 == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) {
+ if ((this->waitMessageState == Message_GetState(&play->msgCtx)) && Message_ShouldAdvance(play)) {
Message_CloseTextbox(play);
}
-
if ((fabsf(this->subCamEye.x - this->subCamEyeNext.x) < 5.0f) &&
(fabsf(this->subCamEye.y - this->subCamEyeNext.y) < 5.0f) &&
(fabsf(this->subCamEye.z - this->subCamEyeNext.z) < 5.0f) &&
@@ -149,74 +148,71 @@ void EnBomBowlPit_CameraDollyIn(EnBomBowlPit* this, PlayState* play) {
(fabsf(this->subCamAt.z - this->subCamAtNext.z) < 5.0f)) {
Message_CloseTextbox(play);
this->timer = 30;
- this->actionFunc = EnBomBowlPit_SpawnPrize;
+ this->actionFunc = EnBomBowlPit_SpawnReward;
}
}
-void EnBomBowlPit_SpawnPrize(EnBomBowlPit* this, PlayState* play) {
+void EnBomBowlPit_SpawnReward(EnBomBowlPit* this, PlayState* play) {
if (this->timer == 0) {
- this->exItem = (EnExItem*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_EX_ITEM,
- this->actor.world.pos.x, this->actor.world.pos.y,
- this->actor.world.pos.z - 70.0f, 0, 0, 0, this->prizeIndex);
- if (this->exItem != NULL) {
- this->actionFunc = EnBomBowlPit_SetupGivePrize;
+ this->rewardItem =
+ Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_EN_EX_ITEM, this->actor.world.pos.x,
+ this->actor.world.pos.y, this->actor.world.pos.z - 70.0f, 0, 0, 0, this->reward);
+ if (this->rewardItem != NULL) {
+ this->actionFunc = EnBomBowlPit_WaitRewardFinishedAppearing;
}
}
}
-void EnBomBowlPit_SetupGivePrize(EnBomBowlPit* this, PlayState* play) {
- if (this->exItemDone != 0) {
- switch (this->prizeIndex) {
+void EnBomBowlPit_WaitRewardFinishedAppearing(EnBomBowlPit* this, PlayState* play) {
+ if (this->hasRewardFinishedAppearing) {
+ switch (this->reward) {
case EXITEM_BOMB_BAG_BOWLING:
- SET_ITEMGETINF(ITEMGETINF_11);
+ SET_ITEMGETINF(ITEMGETINF_BOWLING_BOMB_BAG);
break;
case EXITEM_HEART_PIECE_BOWLING:
- SET_ITEMGETINF(ITEMGETINF_12);
+ SET_ITEMGETINF(ITEMGETINF_BOWLING_HEART_PIECE);
break;
}
-
Play_ClearCamera(play, this->subCamId);
Play_ChangeCameraStatus(play, CAM_ID_MAIN, CAM_STAT_ACTIVE);
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_8);
- this->actionFunc = EnBomBowlPit_GivePrize;
+ this->actionFunc = EnBomBowlPit_GiveReward;
}
}
-void EnBomBowlPit_GivePrize(EnBomBowlPit* this, PlayState* play) {
+void EnBomBowlPit_GiveReward(EnBomBowlPit* this, PlayState* play) {
Player* player = GET_PLAYER(play);
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_7);
- this->getItemId = sGetItemIds[this->prizeIndex];
-
- if ((this->getItemId == GI_BOMB_BAG_30) && (CUR_CAPACITY(UPG_BOMB_BAG) == 30)) {
- this->getItemId = GI_BOMB_BAG_40;
+ this->rewardGetItemId = sGetItemIdRewards[this->reward];
+ if ((this->rewardGetItemId == GI_BOMB_BAG_30) && (CUR_CAPACITY(UPG_BOMB_BAG) == 30)) {
+ this->rewardGetItemId = GI_BOMB_BAG_40;
}
-
player->stateFlags1 &= ~PLAYER_STATE1_29;
this->actor.parent = NULL;
- Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f);
+ Actor_OfferGetItem(&this->actor, play, this->rewardGetItemId, 2000.0f, 1000.0f);
player->stateFlags1 |= PLAYER_STATE1_29;
- this->actionFunc = EnBomBowlPit_WaitTillPrizeGiven;
+ this->actionFunc = EnBomBowlPit_WaitRewardGiven;
}
-void EnBomBowlPit_WaitTillPrizeGiven(EnBomBowlPit* this, PlayState* play) {
+void EnBomBowlPit_WaitRewardGiven(EnBomBowlPit* this, PlayState* play) {
if (Actor_HasParent(&this->actor, play)) {
- this->actionFunc = EnBomBowlPit_Reset;
- } else {
- Actor_OfferGetItem(&this->actor, play, this->getItemId, 2000.0f, 1000.0f);
+ this->actionFunc = EnBomBowlPit_WaitRewardText;
+ return;
}
+ Actor_OfferGetItem(&this->actor, play, this->rewardGetItemId, 2000.0f, 1000.0f);
}
-void EnBomBowlPit_Reset(EnBomBowlPit* this, PlayState* play) {
+void EnBomBowlPit_WaitRewardText(EnBomBowlPit* this, PlayState* play) {
if ((Message_GetState(&play->msgCtx) == TEXT_STATE_DONE) && Message_ShouldAdvance(play)) {
- PRINTF(VT_FGCOL(GREEN) T("☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n", "☆☆☆☆☆ Normal termination ☆☆☆☆☆ \n") VT_RST);
- if (this->getItemId == GI_HEART_PIECE) {
+ PRINTF(VT_FGCOL(GREEN) "☆☆☆☆☆ 正常終了 ☆☆☆☆☆ \n" VT_RST);
+ if (this->rewardGetItemId == GI_HEART_PIECE) {
gSaveContext.healthAccumulator = 0x140;
- PRINTF(VT_FGCOL(GREEN) T("☆☆☆☆☆ あぁ回復! ☆☆☆☆☆ \n", "☆☆☆☆☆ Ah recovery! ☆☆☆☆☆ \n") VT_RST);
+ PRINTF(VT_FGCOL(GREEN) "☆☆☆☆☆ あぁ回復! ☆☆☆☆☆ \n" VT_RST);
}
- this->exItemDone = 0;
- this->status = 2;
- this->actionFunc = EnBomBowlPit_SetupDetectHit;
+ this->hasRewardFinishedAppearing = false;
+ this->rewardState = EN_BOM_BOWL_PIT_REWARD_STATE_REWARD_GIVEN;
+ this->actionFunc = EnBomBowlPit_WaitGameStarted;
}
}
@@ -224,7 +220,6 @@ void EnBomBowlPit_Update(Actor* thisx, PlayState* play) {
EnBomBowlPit* this = (EnBomBowlPit*)thisx;
this->actionFunc(this, play);
-
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 a75f4a9f729..12612a72834 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,7 +3,12 @@
#include "ultra64.h"
#include "actor.h"
-#include "overlays/actors/ovl_En_Ex_Item/z_en_ex_item.h"
+
+typedef enum EnBomBowlPitRewardState {
+ EN_BOM_BOWL_PIT_REWARD_STATE_WAIT_HIT,
+ EN_BOM_BOWL_PIT_REWARD_STATE_GIVING_REWARD,
+ EN_BOM_BOWL_PIT_REWARD_STATE_REWARD_GIVEN
+} EnBomBowlPitRewardState;
struct EnBomBowlPit;
@@ -12,17 +17,17 @@ typedef void (*EnBomBowlPitActionFunc)(struct EnBomBowlPit*, struct PlayState*);
typedef struct EnBomBowlPit {
/* 0x0000 */ Actor actor;
/* 0x014C */ EnBomBowlPitActionFunc actionFunc;
- /* 0x0150 */ u16 unk_150;
+ /* 0x0150 */ char pad_150[2];
/* 0x0152 */ s16 subCamId;
- /* 0x0154 */ s16 unk_154;
- /* 0x0156 */ s16 exItemDone; // Set by EnExItem?
+ /* 0x0154 */ s16 waitMessageState;
+ /* 0x0156 */ s16 hasRewardFinishedAppearing;
/* 0x0158 */ s16 timer;
- /* 0x015A */ s16 prizeIndex;
- /* 0x015C */ s16 start;
- /* 0x0160 */ s32 getItemId;
- /* 0x0164 */ u8 status;
- /* 0x0168 */ Vec3f viewAt; // set and not used
- /* 0x0174 */ Vec3f viewEye; // set and not used
+ /* 0x015A */ s16 reward;
+ /* 0x015C */ s16 gameStarted;
+ /* 0x0160 */ s32 rewardGetItemId;
+ /* 0x0164 */ u8 rewardState;
+ /* 0x0168 */ Vec3f viewAt;
+ /* 0x0174 */ Vec3f viewEye;
/* 0x0180 */ Vec3f subCamAt;
/* 0x018C */ Vec3f subCamEye;
/* 0x0198 */ Vec3f subCamEyeNext;
@@ -31,8 +36,8 @@ typedef struct EnBomBowlPit {
/* 0x01BC */ Vec3f subCamAtNext;
/* 0x01C8 */ Vec3f subCamAtMaxVelFrac;
/* 0x01D4 */ Vec3f subCamAtVel;
- /* 0x01E0 */ EnExItem* exItem;
- /* 0x01E4 */ char unk_1E4[0x3520];
-} EnBomBowlPit; // size = 0x3704
+ /* 0x01E0 */ Actor* rewardItem;
+ /* 0x01E4 */ char pad_1E4[0x3520]; //! @bug Large unused amount of memory
+} EnBomBowlPit; // size = 0x3704
#endif
diff --git a/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c b/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c
index 95bdbd2ee2e..62d658490a0 100644
--- a/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c
+++ b/src/overlays/actors/ovl_En_Ex_Item/z_en_ex_item.c
@@ -161,7 +161,7 @@ void EnExItem_WaitForObject(EnExItem* this, PlayState* play) {
this->timer = 65;
this->prizeRotateTimer = 35;
this->scale = 0.5f;
- if (onCounter == 0) {
+ if (!onCounter) {
this->actionFunc = EnExItem_BowlPrize;
} else {
this->actionFunc = EnExItem_SetupBowlCounter;
@@ -325,7 +325,7 @@ void EnExItem_BowlPrize(EnExItem* this, PlayState* play) {
PRINTF(VT_FGCOL(GREEN) T(" ☆☆☆☆☆ 動いてねー? ☆☆☆☆☆ %x\n", " ☆☆☆☆☆ Is it moving? ☆☆☆☆☆ %x\n") VT_RST,
this->actor.parent->update);
if ((this->actor.parent != NULL) && (this->actor.parent->update != NULL)) {
- ((EnBomBowlPit*)this->actor.parent)->exItemDone = 1;
+ ((EnBomBowlPit*)this->actor.parent)->hasRewardFinishedAppearing = true;
PRINTF(VT_FGCOL(GREEN) T(" ☆☆☆☆☆ さぁきえるぞ! ☆☆☆☆☆ \n", " ☆☆☆☆☆ Now it's gone! ☆☆☆☆☆ \n") VT_RST);
}
Actor_Kill(&this->actor);
@@ -402,30 +402,30 @@ void EnExItem_TargetPrizeApproach(EnExItem* this, PlayState* play) {
this->actor.world.pos.z += (tmpf3 / tmpf4) * 5.0f;
}
} else {
- s32 getItemId;
+ s32 itemId;
this->actor.draw = NULL;
Player_SetCsActionWithHaltedActors(play, NULL, PLAYER_CSACTION_7);
this->actor.parent = NULL;
if (CUR_UPG_VALUE(UPG_BULLET_BAG) == 1) {
- getItemId = GI_BULLET_BAG_40;
+ itemId = GI_BULLET_BAG_40;
} else {
- getItemId = GI_BULLET_BAG_50;
+ itemId = GI_BULLET_BAG_50;
}
- Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f);
+ Actor_OfferGetItem(&this->actor, play, itemId, 2000.0f, 1000.0f);
this->actionFunc = EnExItem_TargetPrizeGive;
}
}
void EnExItem_TargetPrizeGive(EnExItem* this, PlayState* play) {
- s32 getItemId;
+ s32 itemId;
if (Actor_HasParent(&this->actor, play)) {
this->actionFunc = EnExItem_TargetPrizeFinish;
} else {
- getItemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40;
+ itemId = (CUR_UPG_VALUE(UPG_BULLET_BAG) == 2) ? GI_BULLET_BAG_50 : GI_BULLET_BAG_40;
- Actor_OfferGetItem(&this->actor, play, getItemId, 2000.0f, 1000.0f);
+ Actor_OfferGetItem(&this->actor, play, itemId, 2000.0f, 1000.0f);
}
}
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 cda2c07dc04..dd11f699a61 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,13 +1,13 @@
/*
* File: z_en_wall_tubo.c
* Overlay: ovl_En_Wall_Tubo
- * Description: Bombchu Bowling Alley Bullseyes/Pits
+ * Description: Bowling Alley bombchu detector for the first two walls
*/
#include "z_en_wall_tubo.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"
+#include "overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h"
+#include "overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h"
#include "rand.h"
#include "regs.h"
@@ -15,7 +15,6 @@
#include "printf.h"
#include "quake.h"
#include "terminal.h"
-#include "translation.h"
#include "z_lib.h"
#include "debug_display.h"
#include "effect.h"
@@ -27,9 +26,9 @@ void EnWallTubo_Init(Actor* thisx, PlayState* play);
void EnWallTubo_Destroy(Actor* thisx, PlayState* play);
void EnWallTubo_Update(Actor* thisx, PlayState* play);
-void EnWallTubo_FindGirl(EnWallTubo* this, PlayState* play);
-void EnWallTubo_DetectChu(EnWallTubo* this, PlayState* play);
-void EnWallTubo_SetWallFall(EnWallTubo* this, PlayState* play);
+void EnWallTubo_InitImpl(EnWallTubo* this, PlayState* play);
+void EnWallTubo_WaitTargetHit(EnWallTubo* this, PlayState* play);
+void EnWallTubo_Explode(EnWallTubo* this, PlayState* play);
ActorProfile En_Wall_Tubo_Profile = {
/**/ ACTOR_EN_WALL_TUBO,
@@ -47,102 +46,91 @@ void EnWallTubo_Init(Actor* thisx, PlayState* play) {
EnWallTubo* this = (EnWallTubo*)thisx;
PRINTF("\n\n");
- PRINTF(VT_FGCOL(YELLOW) T("☆☆☆☆☆ 壁のツボ ☆☆☆☆☆ \n", "☆☆☆☆☆ Points on the wall ☆☆☆☆☆ \n") VT_RST);
- this->unk_164 = this->actor.world.pos;
- this->actionFunc = EnWallTubo_FindGirl;
+ PRINTF(VT_FGCOL(YELLOW) "☆☆☆☆☆ 壁のツボ ☆☆☆☆☆ \n" VT_RST);
+ this->homePos = this->actor.world.pos;
+ this->actionFunc = EnWallTubo_InitImpl;
}
void EnWallTubo_Destroy(Actor* thisx, PlayState* play) {
}
-void EnWallTubo_FindGirl(EnWallTubo* this, PlayState* play) {
- Actor* lookForGirl;
-
- lookForGirl = play->actorCtx.actorLists[ACTORCAT_NPC].head;
+void EnWallTubo_InitImpl(EnWallTubo* this, PlayState* play) {
+ Actor* actor;
- while (lookForGirl != NULL) {
- if (lookForGirl->id != ACTOR_EN_BOM_BOWL_MAN) {
- lookForGirl = lookForGirl->next;
- } else {
- this->chuGirl = (EnBomBowlMan*)lookForGirl;
- break;
+ actor = play->actorCtx.actorLists[4].head;
+ while (actor != NULL) {
+ if (actor->id != ACTOR_EN_BOM_BOWL_MAN) {
+ actor = actor->next;
+ continue;
}
+ this->bowlingGirl = (EnBomBowlMan*)actor;
+ break;
}
-
- this->actionFunc = EnWallTubo_DetectChu;
+ this->actionFunc = EnWallTubo_WaitTargetHit;
}
-void EnWallTubo_DetectChu(EnWallTubo* this, PlayState* play) {
- EnBomChu* chu;
- s32 pad;
+void EnWallTubo_WaitTargetHit(EnWallTubo* this, PlayState* play) {
+ Actor* explosive;
+ Actor* thisx = &this->actor;
Vec3f effAccel = { 0.0f, 0.1f, 0.0f };
- Vec3f effVelocity = { 0.0f, 0.0f, 0.0f };
- Vec3f chuPosDiff;
+ Vec3f effVel = { 0.0f, 0.0f, 0.0f };
+ Vec3f diff;
s16 quakeIndex;
- if (this->chuGirl->minigamePlayStatus != 0) {
- if (play->cameraPtrs[CAM_ID_MAIN]->setting == CAM_SET_CHU_BOWLING) {
- chu = (EnBomChu*)play->actorCtx.actorLists[ACTORCAT_EXPLOSIVE].head;
-
- 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.world.pos.x - this->actor.world.pos.x;
- chuPosDiff.y = chu->actor.world.pos.y - this->actor.world.pos.y;
- chuPosDiff.z = chu->actor.world.pos.z - this->actor.world.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->timer = 2;
- Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR);
- this->timer = 60;
- EffectSsBomb2_SpawnLayered(play, &this->explosionCenter, &effVelocity, &effAccel, 200, 40);
- quakeIndex = Quake_Request(GET_ACTIVE_CAM(play), QUAKE_TYPE_1);
- Quake_SetSpeed(quakeIndex, 0x7FFF);
- Quake_SetPerturbations(quakeIndex, 100, 0, 0, 0);
- Quake_SetDuration(quakeIndex, 100);
- this->actionFunc = EnWallTubo_SetWallFall;
- break;
- }
-
- chu = (EnBomChu*)chu->actor.next;
+ if ((this->bowlingGirl->gameStartStatus != EN_BOM_BOWL_MAN_GAME_START_STATUS_INACTIVE) &&
+ (play->cameraPtrs[CAM_ID_MAIN]->setting == CAM_SET_CHU_BOWLING)) {
+ explosive = play->actorCtx.actorLists[ACTORCAT_EXPLOSIVE].head;
+ while (explosive != NULL) {
+ if ((explosive == thisx) || (explosive->id != ACTOR_EN_BOM_CHU)) {
+ explosive = explosive->next;
+ continue;
+ }
+ diff.x = explosive->world.pos.x - this->actor.world.pos.x;
+ diff.y = explosive->world.pos.y - this->actor.world.pos.y;
+ diff.z = explosive->world.pos.z - this->actor.world.pos.z;
+ if (((fabsf(diff.x) < 40.0f) || (BREG(2) != 0)) && ((fabsf(diff.y) < 40.0f) || (BREG(2) != 0)) &&
+ ((fabsf(diff.z) < 40.0f) || (BREG(2) != 0))) {
+ this->bowlingGirl->wallsState[this->actor.params] = EN_BOM_BOWL_MAN_WALL_STATE_HIT;
+ ((EnBomChu*)explosive)->timer = 2;
+ Sfx_PlaySfxCentered(NA_SE_SY_TRE_BOX_APPEAR);
+ this->timer = 60;
+ EffectSsBomb2_SpawnLayered(play, &this->effCenterPos, &effVel, &effAccel, 200, 40);
+ quakeIndex = Quake_Request(play->cameraPtrs[play->activeCamId], QUAKE_TYPE_1);
+ Quake_SetSpeed(quakeIndex, 0x7FFF);
+ Quake_SetPerturbations(quakeIndex, 100, 0, 0, 0);
+ Quake_SetDuration(quakeIndex, 100);
+ this->actionFunc = EnWallTubo_Explode;
+ return;
}
+ explosive = explosive->next;
}
}
}
-void EnWallTubo_SetWallFall(EnWallTubo* this, PlayState* play) {
+void EnWallTubo_Explode(EnWallTubo* this, PlayState* play) {
BgBowlWall* wall;
Vec3f effAccel = { 0.0f, 0.1f, 0.0f };
- Vec3f effVelocity = { 0.0f, 0.0f, 0.0f };
+ Vec3f effVel = { 0.0f, 0.0f, 0.0f };
Vec3f effPos;
if ((play->gameplayFrames & 1) == 0) {
- effPos.x = this->explosionCenter.x + Rand_CenteredFloat(300.0f);
- effPos.y = this->explosionCenter.y + Rand_CenteredFloat(300.0f);
- effPos.z = this->explosionCenter.z;
- EffectSsBomb2_SpawnLayered(play, &effPos, &effVelocity, &effAccel, 100, 30);
- EffectSsHahen_SpawnBurst(play, &effPos, 10.0f, 0, 50, 15, 3, HAHEN_OBJECT_DEFAULT, 10, NULL);
+ effPos.x = Rand_CenteredFloat(300.0f) + this->effCenterPos.x;
+ effPos.y = Rand_CenteredFloat(300.0f) + this->effCenterPos.y;
+ effPos.z = this->effCenterPos.z;
+ EffectSsBomb2_SpawnLayered(play, &effPos, &effVel, &effAccel, 100, 30);
+ EffectSsHahen_SpawnBurst(play, &effPos, 10.0f, 0, 50, 15, 3, -1, 10, NULL);
Actor_PlaySfx(&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;
- // "Hara" may stand for the developer name Kuzuhara
- PRINTF(VT_FGCOL(GREEN) T("☆☆☆☆ やった原! ☆☆☆☆☆ \n", "☆☆☆☆ I did it! -Hara ☆☆☆☆☆ \n") VT_RST);
- PRINTF(VT_FGCOL(YELLOW) T("☆☆☆☆ やった原! ☆☆☆☆☆ \n", "☆☆☆☆ I did it! -Hara ☆☆☆☆☆ \n") VT_RST);
- PRINTF(VT_FGCOL(BLUE) T("☆☆☆☆ やった原! ☆☆☆☆☆ \n", "☆☆☆☆ I did it! -Hara ☆☆☆☆☆ \n") VT_RST);
- PRINTF(VT_FGCOL(MAGENTA) T("☆☆☆☆ やった原! ☆☆☆☆☆ \n", "☆☆☆☆ I did it! -Hara ☆☆☆☆☆ \n") VT_RST);
- PRINTF(VT_FGCOL(CYAN) T("☆☆☆☆ やった原! ☆☆☆☆☆ \n", "☆☆☆☆ I did it! -Hara ☆☆☆☆☆ \n") VT_RST);
+ wall->targetHit = true;
+ PRINTF(VT_FGCOL(GREEN) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
+ PRINTF(VT_FGCOL(YELLOW) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
+ PRINTF(VT_FGCOL(BLUE) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
+ PRINTF(VT_FGCOL(MAGENTA) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
+ PRINTF(VT_FGCOL(CYAN) "☆☆☆☆ やった原! ☆☆☆☆☆ \n" VT_RST);
}
-
Actor_Kill(&this->actor);
}
}
@@ -153,10 +141,8 @@ void EnWallTubo_Update(Actor* thisx, PlayState* play) {
if (this->timer != 0) {
this->timer--;
}
-
this->actionFunc(this, play);
-
- if (DEBUG_FEATURES && BREG(0) != 0) {
+ if (DEBUG_FEATURES && (BREG(0) != 0)) {
DebugDisplay_AddObject(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z,
this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, 1.0f, 1.0f,
1.0f, 0, 0, 255, 255, 4, play->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 5cbbb878e73..72a22243028 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,19 +3,19 @@
#include "ultra64.h"
#include "actor.h"
-#include "overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h"
struct EnWallTubo;
typedef void (*EnWallTuboActionFunc)(struct EnWallTubo*, struct PlayState*);
typedef struct EnWallTubo {
- /* 0x0000 */ Actor actor;
- /* 0x014C */ EnWallTuboActionFunc actionFunc;
- /* 0x0150 */ s16 timer;
- /* 0x0154 */ Vec3f explosionCenter;
- /* 0x0160 */ EnBomBowlMan* chuGirl;
- /* 0x0164 */ Vec3f unk_164;
+ /* 0x000 */ Actor actor;
+ /* 0x14C */ EnWallTuboActionFunc actionFunc;
+ /* 0x150 */ s16 timer;
+ /* 0x152 */ char pad_152[2];
+ /* 0x154 */ Vec3f effCenterPos;
+ /* 0x160 */ struct EnBomBowlMan* bowlingGirl;
+ /* 0x164 */ Vec3f homePos;
} EnWallTubo; // size = 0x0170
#endif