Shipwright/soh/src/overlays/actors/ovl_Bg_Haka_Ship/z_bg_haka_ship.c

236 lines
8.7 KiB
C

/*
* File: z_bg_haka_ship.c
* Overlay: ovl_Bg_Haka_Ship
* Description: Shadow Temple Ship
*/
#include "z_bg_haka_ship.h"
#include "objects/object_haka_objects/object_haka_objects.h"
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
void BgHakaShip_Init(Actor* thisx, GlobalContext* globalCtx);
void BgHakaShip_Destroy(Actor* thisx, GlobalContext* globalCtx);
void BgHakaShip_Update(Actor* thisx, GlobalContext* globalCtx);
void BgHakaShip_Draw(Actor* thisx, GlobalContext* globalCtx);
void BgHakaShip_ChildUpdatePosition(BgHakaShip* this, GlobalContext* globalCtx);
void BgHakaShip_WaitForSong(BgHakaShip* this, GlobalContext* globalCtx);
void BgHakaShip_CutsceneStationary(BgHakaShip* this, GlobalContext* globalCtx);
void BgHakaShip_Move(BgHakaShip* this, GlobalContext* globalCtx);
void BgHakaShip_SetupCrash(BgHakaShip* this, GlobalContext* globalCtx);
void BgHakaShip_CrashShake(BgHakaShip* this, GlobalContext* globalCtx);
void BgHakaShip_CrashFall(BgHakaShip* this, GlobalContext* globalCtx);
const ActorInit Bg_Haka_Ship_InitVars = {
ACTOR_BG_HAKA_SHIP,
ACTORCAT_BG,
FLAGS,
OBJECT_HAKA_OBJECTS,
sizeof(BgHakaShip),
(ActorFunc)BgHakaShip_Init,
(ActorFunc)BgHakaShip_Destroy,
(ActorFunc)BgHakaShip_Update,
(ActorFunc)BgHakaShip_Draw,
NULL,
};
static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
};
void BgHakaShip_Init(Actor* thisx, GlobalContext* globalCtx) {
BgHakaShip* this = (BgHakaShip*)thisx;
s32 pad;
CollisionHeader* colHeader = NULL;
Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
DynaPolyActor_Init(&this->dyna, 1);
this->switchFlag = (thisx->params >> 8) & 0xFF;
this->dyna.actor.params &= 0xFF;
if (this->dyna.actor.params == 0) {
CollisionHeader_GetVirtual(&object_haka_objects_Col_00E408, &colHeader);
this->counter = 8;
this->actionFunc = BgHakaShip_WaitForSong;
} else {
CollisionHeader_GetVirtual(&object_haka_objects_Col_00ED7C, &colHeader);
this->actionFunc = BgHakaShip_ChildUpdatePosition;
}
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y - 0x4000;
this->yOffset = 0;
if (this->dyna.actor.params == 0 &&
Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_BG_HAKA_SHIP,
this->dyna.actor.world.pos.x + -10.0f, this->dyna.actor.world.pos.y + 82.0f,
this->dyna.actor.world.pos.z, 0, 0, 0, 1) == NULL) {
Actor_Kill(&this->dyna.actor);
}
}
void BgHakaShip_Destroy(Actor* thisx, GlobalContext* globalCtx) {
BgHakaShip* this = (BgHakaShip*)thisx;
DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
Audio_StopSfxByPos(&this->bellSoundPos);
}
void BgHakaShip_ChildUpdatePosition(BgHakaShip* this, GlobalContext* globalCtx) {
Actor* parent = this->dyna.actor.parent;
if (parent != NULL && parent->update != NULL) {
this->dyna.actor.world.pos.x = parent->world.pos.x + -10.0f;
this->dyna.actor.world.pos.y = parent->world.pos.y + 82.0f;
this->dyna.actor.world.pos.z = parent->world.pos.z;
} else {
this->dyna.actor.parent = NULL;
}
}
void BgHakaShip_WaitForSong(BgHakaShip* this, GlobalContext* globalCtx) {
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
if (this->counter) {
this->counter--;
}
if (this->counter == 0) {
this->counter = 130;
this->actionFunc = BgHakaShip_CutsceneStationary;
osSyncPrintf("シーン 外輪船 ... アァクション!!\n");
OnePointCutscene_Init(globalCtx, 3390, 999, &this->dyna.actor, MAIN_CAM);
}
}
}
void BgHakaShip_CutsceneStationary(BgHakaShip* this, GlobalContext* globalCtx) {
if (this->counter) {
this->counter--;
}
this->yOffset = sinf(this->counter * (M_PI / 25)) * 6144.0f;
if (this->counter == 0) {
this->counter = 50;
this->actionFunc = BgHakaShip_Move;
}
}
void BgHakaShip_Move(BgHakaShip* this, GlobalContext* globalCtx) {
f32 distanceFromHome;
Actor* child;
if (this->counter) {
this->counter--;
}
if (this->counter == 0) {
this->counter = 50;
}
this->dyna.actor.world.pos.y = (sinf(this->counter * (M_PI / 25)) * 50.0f) + this->dyna.actor.home.pos.y;
distanceFromHome = this->dyna.actor.home.pos.x - this->dyna.actor.world.pos.x;
if (distanceFromHome > 7650.0f) {
this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x - 7650.0f;
this->dyna.actor.speedXZ = 0.0f;
}
if (distanceFromHome > 7600.0f && !Gameplay_InCsMode(globalCtx)) {
this->counter = 40;
this->dyna.actor.speedXZ = 0.0f;
Message_StartTextbox(globalCtx, 0x5071, NULL);
this->actionFunc = BgHakaShip_SetupCrash;
} else {
Math_StepToF(&this->dyna.actor.speedXZ, 4.0f, 0.2f);
}
child = this->dyna.actor.child;
if (child != NULL && child->update != NULL) {
child->shape.rot.z += ((655.0f / 13.0f) * this->dyna.actor.speedXZ);
} else {
this->dyna.actor.child = NULL;
}
this->yOffset = sinf(this->counter * (M_PI / 25)) * 6144.0f;
}
void BgHakaShip_SetupCrash(BgHakaShip* this, GlobalContext* globalCtx) {
if (this->counter) {
this->counter--;
}
if (this->counter == 0) {
this->counter = 40;
this->actionFunc = BgHakaShip_CrashShake;
}
Math_ScaledStepToS(&this->yOffset, 0, 128);
}
void BgHakaShip_CrashShake(BgHakaShip* this, GlobalContext* globalCtx) {
if (this->counter != 0) {
this->counter--;
}
this->dyna.actor.world.pos.y = this->counter % 4 * 3 - 6 + this->dyna.actor.home.pos.y;
if (!this->counter) {
this->dyna.actor.gravity = -1.0f;
this->actionFunc = BgHakaShip_CrashFall;
}
func_8002F974(&this->dyna.actor, NA_SE_EV_BLOCKSINK - SFX_FLAG);
}
void BgHakaShip_CrashFall(BgHakaShip* this, GlobalContext* globalCtx) {
Actor* child;
if (this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y > 2000.0f) {
Actor_Kill(&this->dyna.actor);
child = this->dyna.actor.child;
if (child != NULL && child->update != NULL) {
Actor_Kill(child);
}
} else {
Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCKSINK - SFX_FLAG);
if ((this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y > 500.0f) && func_8004356C(&this->dyna)) {
Gameplay_TriggerVoidOut(globalCtx);
}
}
}
void BgHakaShip_Update(Actor* thisx, GlobalContext* globalCtx) {
BgHakaShip* this = (BgHakaShip*)thisx;
this->actionFunc(this, globalCtx);
if (this->dyna.actor.params == 0) {
Actor_MoveForward(&this->dyna.actor);
}
}
void BgHakaShip_Draw(Actor* thisx, GlobalContext* globalCtx) {
BgHakaShip* this = (BgHakaShip*)thisx;
f32 angleTemp;
OPEN_DISPS(globalCtx->state.gfxCtx);
func_80093D18(globalCtx->state.gfxCtx);
if (this->dyna.actor.params == 0) {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, object_haka_objects_DL_00D330);
angleTemp = this->yOffset * (M_PI / 0x8000);
Matrix_Translate(-3670.0f, 620.0f, 1150.0f, MTXMODE_APPLY);
Matrix_RotateZ(angleTemp, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, object_haka_objects_DL_005A70);
Matrix_Translate(0.0f, 0.0f, -2300.0f, MTXMODE_APPLY);
Matrix_RotateZ(-(2.0f * angleTemp), MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, object_haka_objects_DL_005A70);
} else {
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_OPA_DISP++, object_haka_objects_DL_00E910);
}
CLOSE_DISPS(globalCtx->state.gfxCtx);
if (this->actionFunc == BgHakaShip_CutsceneStationary || this->actionFunc == BgHakaShip_Move) {
s32 pad;
Vec3f sp2C;
sp2C.x = this->dyna.actor.world.pos.x + -367.0f;
sp2C.y = this->dyna.actor.world.pos.y + 62.0f;
sp2C.z = this->dyna.actor.world.pos.z;
SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &sp2C, &this->bellSoundPos);
func_80078914(&this->bellSoundPos, NA_SE_EV_SHIP_BELL - SFX_FLAG);
}
}