302 lines
10 KiB
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);
|
|
}
|