Shipwright/soh/src/overlays/actors/ovl_Bg_Mori_Hashigo/z_bg_mori_hashigo.c

302 lines
10 KiB
C

/*
* File: z_bg_mori_hashigo.c
* Overlay: ovl_Bg_Mori_Hashigo
* Description: Falling ladder and clasp that holds it. Unused.
*/
#include "z_bg_mori_hashigo.h"
#include "objects/object_mori_objects/object_mori_objects.h"
#define FLAGS 0
void BgMoriHashigo_Init(Actor* thisx, GlobalContext* globalCtx);
void BgMoriHashigo_Destroy(Actor* thisx, GlobalContext* globalCtx);
void BgMoriHashigo_Update(Actor* thisx, GlobalContext* globalCtx);
void BgMoriHashigo_Draw(Actor* thisx, GlobalContext* globalCtx);
void BgMoriHashigo_SetupWaitForMoriTex(BgMoriHashigo* this);
void BgMoriHashigo_WaitForMoriTex(BgMoriHashigo* this, GlobalContext* globalCtx);
void BgMoriHashigo_SetupClasp(BgMoriHashigo* this);
void BgMoriHashigo_Clasp(BgMoriHashigo* this, GlobalContext* globalCtx);
void BgMoriHashigo_SetupLadderWait(BgMoriHashigo* this);
void BgMoriHashigo_LadderWait(BgMoriHashigo* this, GlobalContext* globalCtx);
void BgMoriHashigo_SetupLadderFall(BgMoriHashigo* this);
void BgMoriHashigo_LadderFall(BgMoriHashigo* this, GlobalContext* globalCtx);
void BgMoriHashigo_SetupLadderRest(BgMoriHashigo* this);
const ActorInit Bg_Mori_Hashigo_InitVars = {
ACTOR_BG_MORI_HASHIGO,
ACTORCAT_BG,
FLAGS,
OBJECT_MORI_OBJECTS,
sizeof(BgMoriHashigo),
(ActorFunc)BgMoriHashigo_Init,
(ActorFunc)BgMoriHashigo_Destroy,
(ActorFunc)BgMoriHashigo_Update,
NULL,
NULL,
};
static ColliderJntSphElementInit sJntSphElementsInit[1] = {
{
{
ELEMTYPE_UNK4,
{ 0x00000000, 0x00, 0x00 },
{ 0x0001F820, 0x00, 0x00 },
TOUCH_NONE,
BUMP_ON,
OCELEM_NONE,
},
{ 0, { { 0, 0, 0 }, 25 }, 100 },
},
};
static ColliderJntSphInit sJntSphInit = {
{
COLTYPE_NONE,
AT_NONE,
AC_ON | AC_TYPE_PLAYER,
OC1_NONE,
OC2_NONE,
COLSHAPE_JNTSPH,
},
1,
sJntSphElementsInit,
};
static InitChainEntry sInitChainClasp[] = {
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_CONTINUE), ICHAIN_U8(targetMode, 3, ICHAIN_CONTINUE),
ICHAIN_F32(targetArrowOffset, 40, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP),
};
static InitChainEntry sInitChainLadder[] = {
ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_CONTINUE),
ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP),
};
void BgMoriHashigo_InitDynapoly(BgMoriHashigo* this, GlobalContext* globalCtx, CollisionHeader* collision,
s32 moveFlag) {
s32 pad;
CollisionHeader* colHeader;
s32 pad2;
colHeader = NULL;
DynaPolyActor_Init(&this->dyna, moveFlag);
CollisionHeader_GetVirtual(collision, &colHeader);
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
if (this->dyna.bgId == BG_ACTOR_MAX) {
// "Warning : move BG login failed"
osSyncPrintf("Warning : move BG 登録失敗(%s %d)(name %d)(arg_data 0x%04x)\n", __FILE__, __LINE__,
this->dyna.actor.id, this->dyna.actor.params);
}
}
void BgMoriHashigo_InitCollider(BgMoriHashigo* this, GlobalContext* globalCtx) {
s32 pad;
Collider_InitJntSph(globalCtx, &this->collider);
Collider_SetJntSph(globalCtx, &this->collider, &this->dyna.actor, &sJntSphInit, this->colliderItems);
this->collider.elements[0].dim.worldSphere.center.x = (s16)this->dyna.actor.world.pos.x;
this->collider.elements[0].dim.worldSphere.center.y = (s16)this->dyna.actor.world.pos.y + 21;
this->collider.elements[0].dim.worldSphere.center.z = (s16)this->dyna.actor.world.pos.z;
this->collider.elements[0].dim.worldSphere.radius = 19;
}
s32 BgMoriHashigo_SpawnLadder(BgMoriHashigo* this, GlobalContext* globalCtx) {
f32 sn;
f32 cs;
Vec3f pos;
Actor* ladder;
cs = Math_CosS(this->dyna.actor.shape.rot.y);
sn = Math_SinS(this->dyna.actor.shape.rot.y);
pos.x = 6.0f * sn + this->dyna.actor.world.pos.x;
pos.y = -210.0f + this->dyna.actor.world.pos.y;
pos.z = 6.0f * cs + this->dyna.actor.world.pos.z;
ladder = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_BG_MORI_HASHIGO, pos.x, pos.y,
pos.z, this->dyna.actor.world.rot.x, this->dyna.actor.world.rot.y,
this->dyna.actor.world.rot.z, 0);
if (ladder != NULL) {
return true;
} else {
// "Ladder failure"
osSyncPrintf("Error : 梯子の発生失敗(%s %d)(arg_data 0x%04x)\n", __FILE__, __LINE__,
this->dyna.actor.params);
return false;
}
}
s32 BgMoriHashigo_InitClasp(BgMoriHashigo* this, GlobalContext* globalCtx) {
Actor_ProcessInitChain(&this->dyna.actor, sInitChainClasp);
this->dyna.actor.flags |= ACTOR_FLAG_0;
Actor_SetFocus(&this->dyna.actor, 55.0f);
BgMoriHashigo_InitCollider(this, globalCtx);
if ((this->dyna.actor.params == HASHIGO_CLASP) && !BgMoriHashigo_SpawnLadder(this, globalCtx)) {
return false;
} else {
return true;
}
}
s32 BgMoriHashigo_InitLadder(BgMoriHashigo* this, GlobalContext* globalCtx) {
BgMoriHashigo_InitDynapoly(this, globalCtx, &gMoriHashigoCol, DPM_UNK);
Actor_ProcessInitChain(&this->dyna.actor, sInitChainLadder);
return true;
}
void BgMoriHashigo_Init(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriHashigo* this = (BgMoriHashigo*)thisx;
if (this->dyna.actor.params == HASHIGO_CLASP) {
if (!BgMoriHashigo_InitClasp(this, globalCtx)) {
Actor_Kill(&this->dyna.actor);
return;
}
} else if (this->dyna.actor.params == HASHIGO_LADDER) {
if (!BgMoriHashigo_InitLadder(this, globalCtx)) {
Actor_Kill(&this->dyna.actor);
return;
}
}
this->moriTexObjIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MORI_TEX);
if (this->moriTexObjIndex < 0) {
// "Bank danger!"
osSyncPrintf("Error : バンク危険!(arg_data 0x%04x)(%s %d)\n", this->dyna.actor.params,
__FILE__, __LINE__);
Actor_Kill(&this->dyna.actor);
} else {
BgMoriHashigo_SetupWaitForMoriTex(this);
// "(Forest Temple Ladder and its clasp)"
osSyncPrintf("(森の神殿 梯子とその留め金)(arg_data 0x%04x)\n", this->dyna.actor.params);
}
}
void BgMoriHashigo_Destroy(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriHashigo* this = (BgMoriHashigo*)thisx;
if (this->dyna.actor.params == HASHIGO_LADDER) {
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
}
if (this->dyna.actor.params == HASHIGO_CLASP) {
Collider_DestroyJntSph(globalCtx, &this->collider);
}
}
void BgMoriHashigo_SetupWaitForMoriTex(BgMoriHashigo* this) {
this->actionFunc = BgMoriHashigo_WaitForMoriTex;
}
void BgMoriHashigo_WaitForMoriTex(BgMoriHashigo* this, GlobalContext* globalCtx) {
if (Object_IsLoaded(&globalCtx->objectCtx, this->moriTexObjIndex)) {
if (this->dyna.actor.params == HASHIGO_CLASP) {
BgMoriHashigo_SetupClasp(this);
} else if (this->dyna.actor.params == HASHIGO_LADDER) {
BgMoriHashigo_SetupLadderWait(this);
}
this->dyna.actor.draw = BgMoriHashigo_Draw;
}
}
void BgMoriHashigo_SetupClasp(BgMoriHashigo* this) {
this->actionFunc = BgMoriHashigo_Clasp;
}
void BgMoriHashigo_Clasp(BgMoriHashigo* this, GlobalContext* globalCtx) {
if (this->hitTimer <= 0) {
if (this->collider.base.acFlags & AC_HIT) {
this->collider.base.acFlags &= ~AC_HIT;
this->hitTimer = 10;
} else {
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
}
}
}
void BgMoriHashigo_SetupLadderWait(BgMoriHashigo* this) {
this->actionFunc = BgMoriHashigo_LadderWait;
}
void BgMoriHashigo_LadderWait(BgMoriHashigo* this, GlobalContext* globalCtx) {
BgMoriHashigo* clasp = (BgMoriHashigo*)this->dyna.actor.parent;
if (clasp->hitTimer > 0) {
BgMoriHashigo_SetupLadderFall(this);
}
}
void BgMoriHashigo_SetupLadderFall(BgMoriHashigo* this) {
this->bounceCounter = 0;
this->actionFunc = BgMoriHashigo_LadderFall;
this->dyna.actor.gravity = -1.0f;
this->dyna.actor.minVelocityY = -10.0f;
this->dyna.actor.velocity.y = 2.0f;
}
void BgMoriHashigo_LadderFall(BgMoriHashigo* this, GlobalContext* globalCtx) {
static f32 bounceSpeed[3] = { 4.0f, 2.7f, 1.7f };
Actor* thisx = &this->dyna.actor;
Actor_MoveForward(thisx);
if ((thisx->bgCheckFlags & 1) && (thisx->velocity.y < 0.0f)) {
if (this->bounceCounter >= ARRAY_COUNT(bounceSpeed)) {
BgMoriHashigo_SetupLadderRest(this);
} else {
Actor_UpdateBgCheckInfo(globalCtx, thisx, 0.0f, 0.0f, 0.0f, 0x1C);
thisx->velocity.y = bounceSpeed[this->bounceCounter];
this->bounceCounter++;
}
} else {
Actor_UpdateBgCheckInfo(globalCtx, thisx, 0.0f, 0.0f, 0.0f, 0x1C);
}
}
void BgMoriHashigo_SetupLadderRest(BgMoriHashigo* this) {
this->actionFunc = NULL;
this->dyna.actor.gravity = 0.0f;
this->dyna.actor.velocity.y = 0.0f;
this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight;
}
void BgMoriHashigo_Update(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriHashigo* this = (BgMoriHashigo*)thisx;
if (this->hitTimer > 0) {
this->hitTimer--;
}
if (this->actionFunc != NULL) {
this->actionFunc(this, globalCtx);
}
}
void BgMoriHashigo_Draw(Actor* thisx, GlobalContext* globalCtx) {
s32 pad;
BgMoriHashigo* this = (BgMoriHashigo*)thisx;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_80093D18(globalCtx->state.gfxCtx);
gSPSegment(POLY_OPA_DISP++, 0x08, globalCtx->objectCtx.status[this->moriTexObjIndex].segment);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
switch (this->dyna.actor.params) {
case HASHIGO_CLASP:
gSPDisplayList(POLY_OPA_DISP++, gMoriHashigoClaspDL);
break;
case HASHIGO_LADDER:
gSPDisplayList(POLY_OPA_DISP++, gMoriHashigoLadderDL);
break;
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
}