253 lines
9.4 KiB
C
253 lines
9.4 KiB
C
/*
|
|
* File: z_bg_jya_bigmirror.c
|
|
* Overlay: ovl_Bg_Jya_Bigmirror
|
|
* Description: Ceiling mirror and puzzle in Spirit Temple top rooms
|
|
*/
|
|
|
|
#include "z_bg_jya_bigmirror.h"
|
|
#include "objects/object_jya_obj/object_jya_obj.h"
|
|
|
|
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
|
|
|
void BgJyaBigmirror_Init(Actor* thisx, GlobalContext* globalCtx);
|
|
void BgJyaBigmirror_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|
void BgJyaBigmirror_Update(Actor* thisx, GlobalContext* globalCtx);
|
|
void BgJyaBigmirror_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
static u8 sKankyoIsSpawned = false;
|
|
|
|
const ActorInit Bg_Jya_Bigmirror_InitVars = {
|
|
ACTOR_BG_JYA_BIGMIRROR,
|
|
ACTORCAT_BG,
|
|
FLAGS,
|
|
OBJECT_JYA_OBJ,
|
|
sizeof(BgJyaBigmirror),
|
|
(ActorFunc)BgJyaBigmirror_Init,
|
|
(ActorFunc)BgJyaBigmirror_Destroy,
|
|
(ActorFunc)BgJyaBigmirror_Update,
|
|
(ActorFunc)BgJyaBigmirror_Draw,
|
|
NULL,
|
|
};
|
|
|
|
typedef struct {
|
|
/* 0x00 */ Vec3f pos;
|
|
/* 0x0C */ s16 params;
|
|
/* 0x0E */ s16 solvedRotY;
|
|
/* 0x10 */ s16 initRotY;
|
|
} BigMirrorDataEntry; // size = 0x14
|
|
|
|
static BigMirrorDataEntry sCobraSpawnData[] = {
|
|
{ { -560.0f, 1743.0f, -310.0f }, 0xFF01, 0x4000, 0x8000 },
|
|
{ { 60.0f, 1743.0f, -310.0f }, 0xFF02, 0x8000, 0xA000 },
|
|
};
|
|
|
|
void BgJyaBigmirror_SetRoomFlag(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
|
|
|
this->puzzleFlags &=
|
|
~(BIGMIR_PUZZLE_IN_STATUE_ROOM | BIGMIR_PUZZLE_IN_1ST_TOP_ROOM | BIGMIR_PUZZLE_IN_2ND_TOP_ROOM);
|
|
if (globalCtx->roomCtx.curRoom.num == 5) {
|
|
this->puzzleFlags |= BIGMIR_PUZZLE_IN_STATUE_ROOM;
|
|
} else if (globalCtx->roomCtx.curRoom.num == 0x19) {
|
|
this->puzzleFlags |= BIGMIR_PUZZLE_IN_1ST_TOP_ROOM;
|
|
} else if (globalCtx->roomCtx.curRoom.num == 0x1A) {
|
|
this->puzzleFlags |= BIGMIR_PUZZLE_IN_2ND_TOP_ROOM;
|
|
}
|
|
}
|
|
|
|
void BgJyaBigmirror_HandleCobra(Actor* thisx, GlobalContext* globalCtx) {
|
|
static u8 cobraPuzzleFlags[] = { BIGMIR_PUZZLE_COBRA1_SOLVED, BIGMIR_PUZZLE_COBRA2_SOLVED };
|
|
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
|
BigMirrorDataEntry* curSpawnData;
|
|
BigmirrorCobra* curCobraInfo;
|
|
s32 i;
|
|
|
|
if (this->puzzleFlags & (BIGMIR_PUZZLE_IN_1ST_TOP_ROOM | BIGMIR_PUZZLE_IN_2ND_TOP_ROOM)) {
|
|
for (i = 0; i < 2; i++) {
|
|
curSpawnData = &sCobraSpawnData[i];
|
|
curCobraInfo = &this->cobraInfo[i];
|
|
if (curCobraInfo->cobra != NULL) {
|
|
curCobraInfo->rotY = curCobraInfo->cobra->dyna.actor.shape.rot.y;
|
|
|
|
if (curCobraInfo->rotY == curSpawnData->solvedRotY) {
|
|
this->puzzleFlags |= cobraPuzzleFlags[i];
|
|
} else {
|
|
this->puzzleFlags &= ~cobraPuzzleFlags[i];
|
|
}
|
|
|
|
if (curCobraInfo->cobra->dyna.actor.update == NULL) {
|
|
// "Cobra deleted"
|
|
osSyncPrintf("Error : コブラ削除された (%s %d)\n", __FILE__, __LINE__);
|
|
}
|
|
} else {
|
|
curCobraInfo->cobra = (BgJyaCobra*)Actor_SpawnAsChild(
|
|
&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_BG_JYA_COBRA, curSpawnData->pos.x,
|
|
curSpawnData->pos.y, curSpawnData->pos.z, 0, curCobraInfo->rotY, 0, curSpawnData->params);
|
|
this->actor.child = NULL;
|
|
|
|
if (&curCobraInfo->cobra->dyna.actor == NULL) {
|
|
// "Cobra generation failed"
|
|
osSyncPrintf("Error : コブラ発生失敗 (%s %d)\n", __FILE__, __LINE__);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
curCobraInfo = &this->cobraInfo[i];
|
|
if (curCobraInfo->cobra != NULL) {
|
|
if (curCobraInfo->cobra->dyna.actor.child != NULL) {
|
|
Actor_Kill(curCobraInfo->cobra->dyna.actor.child);
|
|
curCobraInfo->cobra->dyna.actor.child = NULL;
|
|
}
|
|
Actor_Kill(&curCobraInfo->cobra->dyna.actor);
|
|
curCobraInfo->cobra = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void BgJyaBigmirror_SetBombiwaFlag(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
|
|
|
if (Flags_GetSwitch(globalCtx, 0x29)) {
|
|
this->puzzleFlags |= BIGMIR_PUZZLE_BOMBIWA_DESTROYED;
|
|
} else {
|
|
this->puzzleFlags &= ~(BIGMIR_PUZZLE_BOMBIWA_DESTROYED);
|
|
}
|
|
}
|
|
|
|
void BgJyaBigmirror_HandleMirRay(Actor* thisx, GlobalContext* globalCtx) {
|
|
static s16 sMirRayParamss[] = { 0x0005, 0x0007, 0x0008 };
|
|
static Vec3f sMirRayPoss[] = {
|
|
{ 60.0f, 1802.0f, -1102.0f },
|
|
{ -560.0f, 1800.0f, -310.0f },
|
|
{ 60.0f, 1800.0f, -310.0f },
|
|
};
|
|
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
|
s32 puzzleSolved;
|
|
s32 lightBeamToggles[3];
|
|
s32 i;
|
|
s32 objBankIndex;
|
|
|
|
objBankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MIR_RAY);
|
|
|
|
if ((objBankIndex < 0) || (objBankIndex != this->mirRayObjIndex)) {
|
|
this->lightBeams[2] = NULL;
|
|
this->lightBeams[1] = NULL;
|
|
this->lightBeams[0] = NULL;
|
|
} else {
|
|
puzzleSolved = !!(this->puzzleFlags & (BIGMIR_PUZZLE_IN_STATUE_ROOM | BIGMIR_PUZZLE_IN_1ST_TOP_ROOM));
|
|
|
|
if (puzzleSolved) {
|
|
puzzleSolved = !!(this->puzzleFlags & BIGMIR_PUZZLE_COBRA2_SOLVED);
|
|
|
|
if (puzzleSolved) {
|
|
puzzleSolved = !!(this->puzzleFlags & BIGMIR_PUZZLE_COBRA1_SOLVED);
|
|
}
|
|
}
|
|
lightBeamToggles[0] = puzzleSolved; // Only spawn if puzzle solved
|
|
lightBeamToggles[1] = lightBeamToggles[2] =
|
|
this->puzzleFlags & (BIGMIR_PUZZLE_IN_1ST_TOP_ROOM | BIGMIR_PUZZLE_IN_2ND_TOP_ROOM);
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
if (lightBeamToggles[i]) {
|
|
if ((this->lightBeams[i] == NULL) && Object_IsLoaded(&globalCtx->objectCtx, objBankIndex)) {
|
|
this->lightBeams[i] = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_MIR_RAY, sMirRayPoss[i].x,
|
|
sMirRayPoss[i].y, sMirRayPoss[i].z, 0, 0, 0, sMirRayParamss[i]);
|
|
|
|
if (this->lightBeams[i] == NULL) {
|
|
// "Mir Ray generation failed"
|
|
osSyncPrintf("Error : Mir Ray 発生失敗 (%s %d)\n", __FILE__, __LINE__);
|
|
}
|
|
}
|
|
} else {
|
|
if (this->lightBeams[i] != NULL) {
|
|
Actor_Kill(this->lightBeams[i]);
|
|
this->lightBeams[i] = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
this->mirRayObjIndex = objBankIndex;
|
|
}
|
|
|
|
void BgJyaBigmirror_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
|
|
|
if (sKankyoIsSpawned) {
|
|
Actor_Kill(&this->actor);
|
|
return;
|
|
}
|
|
|
|
Actor_SetScale(&this->actor, 0.1f);
|
|
this->cobraInfo[0].rotY = sCobraSpawnData[0].initRotY;
|
|
this->cobraInfo[1].rotY = sCobraSpawnData[1].initRotY;
|
|
this->actor.room = -1;
|
|
sKankyoIsSpawned = true;
|
|
this->spawned = true;
|
|
this->mirRayObjIndex = -1;
|
|
|
|
// "jya Bigmirror"
|
|
osSyncPrintf("(jya 大鏡)(arg_data 0x%04x)\n", this->actor.params);
|
|
}
|
|
|
|
void BgJyaBigmirror_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
|
|
|
if (this->spawned) {
|
|
sKankyoIsSpawned = false;
|
|
}
|
|
}
|
|
|
|
void BgJyaBigmirror_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgJyaBigmirror_SetRoomFlag(thisx, globalCtx);
|
|
BgJyaBigmirror_HandleCobra(thisx, globalCtx);
|
|
BgJyaBigmirror_SetBombiwaFlag(thisx, globalCtx);
|
|
BgJyaBigmirror_HandleMirRay(thisx, globalCtx);
|
|
}
|
|
|
|
void BgJyaBigmirror_DrawLightBeam(Actor* thisx, GlobalContext* globalCtx) {
|
|
static Vec3s D_80893F4C = { 0, 0, 0 };
|
|
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
|
Actor* lift;
|
|
|
|
OPEN_DISPS(globalCtx->state.gfxCtx);
|
|
func_80093D84(globalCtx->state.gfxCtx);
|
|
lift = Actor_Find(&globalCtx->actorCtx, ACTOR_BG_JYA_LIFT, ACTORCAT_BG);
|
|
if (lift != NULL) {
|
|
this->liftHeight = lift->world.pos.y;
|
|
}
|
|
Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y + 40.0f, this->actor.world.pos.z,
|
|
&this->actor.shape.rot);
|
|
Matrix_Scale(0.1f, (this->liftHeight * -(1.0f / 1280.0f)) + (1779.4f / 1280.0f), 0.1f, MTXMODE_APPLY);
|
|
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPDisplayList(POLY_XLU_DISP++, gBigMirror1DL);
|
|
|
|
if (lift != NULL) {
|
|
Matrix_SetTranslateRotateYXZ(lift->world.pos.x, lift->world.pos.y, lift->world.pos.z, &D_80893F4C);
|
|
Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY);
|
|
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
gSPDisplayList(POLY_XLU_DISP++, gBigMirror2DL);
|
|
}
|
|
|
|
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
|
}
|
|
|
|
void BgJyaBigmirror_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|
BgJyaBigmirror* this = (BgJyaBigmirror*)thisx;
|
|
|
|
if (this->puzzleFlags & BIGMIR_PUZZLE_IN_1ST_TOP_ROOM) {
|
|
Gfx_DrawDListOpa(globalCtx, gBigMirror3DL);
|
|
Gfx_DrawDListXlu(globalCtx, gBigMirror4DL);
|
|
}
|
|
|
|
if ((this->puzzleFlags &
|
|
(BIGMIR_PUZZLE_IN_STATUE_ROOM | BIGMIR_PUZZLE_IN_1ST_TOP_ROOM | BIGMIR_PUZZLE_IN_2ND_TOP_ROOM)) &&
|
|
(this->puzzleFlags & BIGMIR_PUZZLE_COBRA2_SOLVED) && (this->puzzleFlags & BIGMIR_PUZZLE_COBRA1_SOLVED)) {
|
|
BgJyaBigmirror_DrawLightBeam(&this->actor, globalCtx);
|
|
}
|
|
}
|