1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-04 15:04:31 +00:00

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>
This commit is contained in:
EllipticEllipsis 2020-12-06 18:48:51 +00:00 committed by GitHub
parent b097c58caf
commit dadee87f94
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 1082 additions and 3387 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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 },
};
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F260.s")
static s16 sTargetRot[] = { 0x0000, 0x0000, 0x3FFF, -0x3FFF };
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F440.s")
void BgBowlWall_Init(Actor* thisx, GlobalContext* globalCtx) {
BgBowlWall* this = THIS;
s32 pad1;
s32 pad2;
ColHeader* colHeader = NULL;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F464.s")
DynaPolyInfo_SetActorMove(&this->dyna, 0);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F718.s")
if (this->dyna.actor.params == 0) {
DynaPolyInfo_Alloc(&D_06000CB8, &colHeader);
} else {
DynaPolyInfo_Alloc(&D_06001B00, &colHeader);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/func_8086F7F8.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/BgBowlWall_Update.s")
void BgBowlWall_Destroy(Actor* thisx, GlobalContext* globalCtx) {
BgBowlWall* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Bg_Bowl_Wall/BgBowlWall_Draw.s")
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;
if (this->timer != 0) {
this->timer--;
}
this->actionFunc(this, globalCtx);
}
void BgBowlWall_Draw(Actor* thisx, GlobalContext* globalCtx) {
GlobalContext* globalCtx2 = globalCtx;
BgBowlWall* this = THIS;
u32 frames;
OPEN_DISPS(globalCtx2->state.gfxCtx, "../z_bg_bowl_wall.c", 441);
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);
if (this->dyna.actor.params == 0) {
gSPDisplayList(POLY_OPA_DISP++, D_06000610);
} else {
gSPDisplayList(POLY_OPA_DISP++, D_06001390);
}
CLOSE_DISPS(globalCtx2->state.gfxCtx, "../z_bg_bowl_wall.c", 464);
}

View file

@ -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;

View file

@ -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);

View file

@ -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;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3820.s")
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);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C38A8.s")
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];
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C395C.s")
this->prizeSelect = (s16)Math_Rand_ZeroFloat(4.99f);
this->actor.unk_1F = 1;
this->actionFunc = EnBomBowMan_SetupWaitAsleep;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C39D0.s")
void EnBomBowlMan_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3A54.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3B50.s")
void EnBomBowMan_WaitAsleep(EnBomBowlMan* this, GlobalContext* globalCtx) {
s16 yawDiff;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3C7C.s")
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3CD4.s")
if (func_8002F194(&this->actor, globalCtx)) {
this->actionFunc = EnBomBowMan_TalkAsleep;
} else {
yawDiff = ABS((s16)(this->actor.yawTowardsLink - this->actor.shape.rot.y));
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3D40.s")
if (!(this->actor.xzDistFromLink > 120.0f) && (yawDiff < 0x4300)) {
func_8002F2CC(&this->actor, globalCtx, 120.0f);
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C3DC4.s")
void EnBomBowMan_TalkAsleep(EnBomBowlMan* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C4040.s")
if ((func_8010BDBC(&globalCtx->msgCtx) == this->dialogState) && (func_80106BC8(globalCtx) != 0)) {
globalCtx->msgCtx.msgMode = 0x37;
this->actionFunc = EnBomBowMan_WakeUp;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C41FC.s")
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;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C4318.s")
void EnBomBowMan_BlinkAwake(EnBomBowlMan* this, GlobalContext* globalCtx) {
f32 frameCount = this->skelAnime.animCurrentFrame;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C441C.s")
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);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C4664.s")
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;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Update.s")
void EnBomBowMan_CheckBeatenDC(EnBomBowlMan* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/func_809C48A8.s")
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;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Draw.s")
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 };
void EnBomBowMan_ChooseShowPrize(EnBomBowlMan* this, GlobalContext* globalCtx) {
s16 prizeTemp;
s32 pad;
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
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;
}
}
void EnBomBowlMan_BeginPlayGame(EnBomBowlMan* this, GlobalContext* globalCtx) {
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
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;
}
}
void EnBomBowlMan_Update(Actor* thisx, GlobalContext* globalCtx) {
EnBomBowlMan* this = THIS;
this->timer++;
this->actor.posRot2.pos.y = 60.0f;
Actor_SetHeight(&this->actor, 60.0f);
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;
}
}
func_80038290(globalCtx, &this->actor, &this->unk_218, &this->unk_224, this->actor.posRot2.pos);
break;
}
DECR(this->prizeRevealTimer);
DECR(this->blinkTimer);
this->actionFunc(this, globalCtx);
}
s32 EnBomBowlMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
void* thisx) {
EnBomBowlMan* this = THIS;
if (limbIndex == 4) {
rot->x += this->unk_218.y;
rot->z += this->unk_218.z;
}
return 0;
}
void EnBomBowlMan_Draw(Actor* thisx, GlobalContext* globalCtx) {
static UNK_PTR eyeTextures[] = { 0x06004110, 0x06004910, 0x06005110 };
EnBomBowlMan* this = THIS;
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_bom_bowl_man.c", 907);
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);
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_bom_bowl_man.c", 923);
}

View file

@ -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;

View file

@ -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;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C4E60.s")
this->actionFunc = EnBomBowlPit_SetupDetectHit;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C4E8C.s")
void EnBomBowlPit_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C5184.s")
void EnBomBowlPit_SetupDetectHit(EnBomBowlPit* this, GlobalContext* globalCtx) {
if (this->start != 0) {
this->start = this->status = 0;
this->actionFunc = EnBomBowlPit_DetectHit;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C5360.s")
void EnBomBowlPit_DetectHit(EnBomBowlPit* this, GlobalContext* globalCtx) {
EnBomChu* chu;
Vec3f chuPosDiff;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C53F0.s")
if (globalCtx->cameraPtrs[0]->setting == 0x15) {
chu = (EnBomChu*)globalCtx->actorCtx.actorList[ACTORTYPE_EXPLOSIVES].first;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C54A8.s")
while (chu != NULL) {
if ((&chu->actor == &this->actor) || (chu->actor.id != ACTOR_EN_BOM_CHU)) {
chu = (EnBomChu*)chu->actor.next;
continue;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C55B0.s")
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;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/func_809C5608.s")
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;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Bom_Bowl_Pit/EnBomBowlPit_Update.s")
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;
}
}
void EnBomBowlPit_GivePrize(EnBomBowlPit* this, GlobalContext* globalCtx) {
Player* player = PLAYER;
func_8002DF54(globalCtx, NULL, 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;
}
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;
}
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);
}
}
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;
}
}
void EnBomBowlPit_Update(Actor* thisx, GlobalContext* globalCtx) {
EnBomBowlPit* this = THIS;
this->actionFunc(this, globalCtx);
if (this->timer != 0) {
this->timer--;
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/func_80B2EE5C.s")
osSyncPrintf("\n\n");
// Wall Target
osSyncPrintf(VT_FGCOL(YELLOW) "☆☆☆☆☆ 壁のツボ ☆☆☆☆☆ \n" VT_RST);
this->unk_164 = this->actor.posRot.pos;
this->actionFunc = EnWallTubo_FindGirl;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/func_80B2EE9C.s")
void EnWallTubo_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/func_80B2F0B8.s")
void EnWallTubo_FindGirl(EnWallTubo* this, GlobalContext* globalCtx) {
Actor* lookForGirl;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Wall_Tubo/EnWallTubo_Update.s")
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);
}
}
void EnWallTubo_Update(Actor* thisx, GlobalContext* globalCtx) {
EnWallTubo* this = THIS;
if (this->timer != 0) {
this->timer--;
}
this->actionFunc(this, globalCtx);
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);
}
}

View file

@ -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;

View file

@ -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);

View file

@ -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);