2022-03-21 21:51:23 -04:00
|
|
|
/*
|
|
|
|
* File: z_bg_mizu_water.c
|
|
|
|
* Overlay: ovl_Bg_Mizu_Water
|
|
|
|
* Description: Water plane in Water Temple. Changes height based on switches 0x1C, 0x1D, 0x1E.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "z_bg_mizu_water.h"
|
|
|
|
#include "objects/object_mizu_objects/object_mizu_objects.h"
|
|
|
|
|
|
|
|
#define FLAGS (ACTOR_FLAG_4 | ACTOR_FLAG_5)
|
|
|
|
|
|
|
|
void BgMizuWater_Init(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
void BgMizuWater_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
void BgMizuWater_Update(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
void BgMizuWater_Draw(Actor* thisx, GlobalContext* globalCtx);
|
|
|
|
|
|
|
|
void BgMizuWater_WaitForAction(BgMizuWater* this, GlobalContext* globalCtx);
|
|
|
|
void BgMizuWater_ChangeWaterLevel(BgMizuWater* this, GlobalContext* globalCtx);
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
s32 switchFlag;
|
|
|
|
s32 yDiff;
|
|
|
|
} WaterLevel;
|
|
|
|
|
|
|
|
static WaterLevel sWaterLevels[] = {
|
|
|
|
{ 0x00, 0 },
|
|
|
|
{ WATER_TEMPLE_WATER_F3_FLAG, 0 },
|
|
|
|
{ WATER_TEMPLE_WATER_F2_FLAG, WATER_TEMPLE_WATER_F2_Y - WATER_TEMPLE_WATER_F3_Y },
|
|
|
|
{ WATER_TEMPLE_WATER_F1_FLAG, WATER_TEMPLE_WATER_F1_Y - WATER_TEMPLE_WATER_F3_Y },
|
|
|
|
};
|
|
|
|
|
|
|
|
const ActorInit Bg_Mizu_Water_InitVars = {
|
|
|
|
ACTOR_BG_MIZU_WATER,
|
|
|
|
ACTORCAT_BG,
|
|
|
|
FLAGS,
|
|
|
|
OBJECT_MIZU_OBJECTS,
|
|
|
|
sizeof(BgMizuWater),
|
|
|
|
(ActorFunc)BgMizuWater_Init,
|
|
|
|
(ActorFunc)BgMizuWater_Destroy,
|
|
|
|
(ActorFunc)BgMizuWater_Update,
|
|
|
|
(ActorFunc)BgMizuWater_Draw,
|
|
|
|
NULL,
|
|
|
|
};
|
|
|
|
|
|
|
|
static f32 sUnused1 = 0;
|
|
|
|
static f32 sUnused2 = 110.0f;
|
|
|
|
|
|
|
|
static u32 sWaterBoxIndexes[] = { 2, 3, 5, 7, 12, 20, 21, 22 };
|
|
|
|
|
|
|
|
static InitChainEntry sInitChain[] = {
|
|
|
|
ICHAIN_VEC3F(scale, 1, ICHAIN_STOP),
|
|
|
|
};
|
|
|
|
|
|
|
|
u32 BgMizuWater_GetWaterLevelActionIndex(s16 switchFlag, GlobalContext* globalCtx) {
|
|
|
|
u32 ret;
|
|
|
|
|
|
|
|
if (bREG(0) != 0) {
|
|
|
|
switch (bREG(1)) {
|
|
|
|
case 0:
|
|
|
|
Flags_SetSwitch(globalCtx, WATER_TEMPLE_WATER_F1_FLAG);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
Flags_SetSwitch(globalCtx, WATER_TEMPLE_WATER_F2_FLAG);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
Flags_SetSwitch(globalCtx, WATER_TEMPLE_WATER_F3_FLAG);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
bREG(0) = 0;
|
|
|
|
}
|
|
|
|
if (Flags_GetSwitch(globalCtx, WATER_TEMPLE_WATER_F1_FLAG) && (switchFlag != WATER_TEMPLE_WATER_F1_FLAG)) {
|
|
|
|
ret = 3;
|
|
|
|
} else if (Flags_GetSwitch(globalCtx, WATER_TEMPLE_WATER_F2_FLAG) && (switchFlag != WATER_TEMPLE_WATER_F2_FLAG)) {
|
|
|
|
ret = 2;
|
|
|
|
} else if (Flags_GetSwitch(globalCtx, WATER_TEMPLE_WATER_F3_FLAG) && (switchFlag != WATER_TEMPLE_WATER_F3_FLAG)) {
|
|
|
|
ret = 1;
|
|
|
|
} else {
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BgMizuWater_SetWaterBoxesHeight(WaterBox* waterBoxes, s16 height) {
|
|
|
|
u32 i;
|
|
|
|
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
waterBoxes[sWaterBoxIndexes[i]].ySurface = height;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BgMizuWater_Init(Actor* thisx, GlobalContext* globalCtx) {
|
|
|
|
BgMizuWater* this = (BgMizuWater*)thisx;
|
|
|
|
f32 initialActorY;
|
|
|
|
WaterBox* waterBoxes;
|
|
|
|
s32 waterLevelActionIndex;
|
|
|
|
|
|
|
|
waterBoxes = globalCtx->colCtx.colHeader->waterBoxes;
|
|
|
|
this->type = this->actor.params & 0xFF;
|
|
|
|
this->switchFlag = (this->actor.params >> 8) & 0xFF;
|
|
|
|
Actor_ProcessInitChain(&this->actor, sInitChain);
|
|
|
|
initialActorY = this->actor.world.pos.y;
|
|
|
|
this->baseY = initialActorY;
|
|
|
|
this->targetY = initialActorY;
|
|
|
|
|
|
|
|
switch (this->type) {
|
|
|
|
case 0:
|
|
|
|
if (bREG(15) == 0) {
|
|
|
|
osSyncPrintf("<コンストラクト>%x %x %x\n", Flags_GetSwitch(globalCtx, WATER_TEMPLE_WATER_F1_FLAG),
|
|
|
|
Flags_GetSwitch(globalCtx, WATER_TEMPLE_WATER_F2_FLAG),
|
|
|
|
Flags_GetSwitch(globalCtx, WATER_TEMPLE_WATER_F3_FLAG));
|
|
|
|
}
|
|
|
|
waterLevelActionIndex = BgMizuWater_GetWaterLevelActionIndex(-1, globalCtx);
|
|
|
|
this->actor.world.pos.y = sWaterLevels[waterLevelActionIndex].yDiff + this->baseY;
|
|
|
|
BgMizuWater_SetWaterBoxesHeight(waterBoxes, this->actor.world.pos.y);
|
|
|
|
this->actor.params = sWaterLevels[waterLevelActionIndex].switchFlag;
|
|
|
|
Flags_UnsetSwitch(globalCtx, WATER_TEMPLE_WATER_F1_FLAG);
|
|
|
|
Flags_UnsetSwitch(globalCtx, WATER_TEMPLE_WATER_F2_FLAG);
|
|
|
|
Flags_UnsetSwitch(globalCtx, WATER_TEMPLE_WATER_F3_FLAG);
|
|
|
|
|
|
|
|
switch (this->actor.params) {
|
|
|
|
case 0x1E:
|
|
|
|
Flags_SetSwitch(globalCtx, WATER_TEMPLE_WATER_F3_FLAG);
|
|
|
|
break;
|
|
|
|
case 0x1D:
|
|
|
|
Flags_SetSwitch(globalCtx, WATER_TEMPLE_WATER_F2_FLAG);
|
|
|
|
break;
|
|
|
|
case 0x1C:
|
|
|
|
default:
|
|
|
|
Flags_SetSwitch(globalCtx, WATER_TEMPLE_WATER_F1_FLAG);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
this->targetY = this->actor.world.pos.y;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
|
|
|
this->actor.world.pos.y = this->baseY + 85.0f;
|
|
|
|
}
|
|
|
|
waterBoxes[6].ySurface = this->actor.world.pos.y;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
|
|
|
this->actor.world.pos.y = this->baseY + 110.0f;
|
|
|
|
this->targetY = this->actor.world.pos.y;
|
|
|
|
}
|
|
|
|
waterBoxes[8].ySurface = this->actor.world.pos.y;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
|
|
|
this->actor.world.pos.y = this->baseY + 160.0f;
|
|
|
|
this->targetY = this->actor.world.pos.y;
|
|
|
|
}
|
|
|
|
waterBoxes[16].ySurface = this->actor.world.pos.y;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->actionFunc = BgMizuWater_WaitForAction;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BgMizuWater_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
|
|
|
}
|
|
|
|
|
|
|
|
void BgMizuWater_WaitForAction(BgMizuWater* this, GlobalContext* globalCtx) {
|
|
|
|
s32 pad;
|
|
|
|
s32 waterLevelActionIndex;
|
|
|
|
s16 prevSwitchFlag;
|
|
|
|
|
|
|
|
switch (this->type) {
|
|
|
|
case 0:
|
|
|
|
prevSwitchFlag = this->actor.params;
|
|
|
|
waterLevelActionIndex = BgMizuWater_GetWaterLevelActionIndex(this->actor.params, globalCtx);
|
|
|
|
if (waterLevelActionIndex != 0) {
|
|
|
|
if (prevSwitchFlag != sWaterLevels[waterLevelActionIndex].switchFlag) {
|
|
|
|
OnePointCutscene_Init(globalCtx, 3120, -100 - waterLevelActionIndex, NULL, MAIN_CAM);
|
|
|
|
this->actor.params = sWaterLevels[waterLevelActionIndex].switchFlag;
|
|
|
|
this->targetY = sWaterLevels[waterLevelActionIndex].yDiff + this->baseY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((prevSwitchFlag != this->actor.params) && (prevSwitchFlag != 0)) {
|
|
|
|
Flags_UnsetSwitch(globalCtx, prevSwitchFlag);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
|
|
|
this->targetY = this->baseY + 85.0f;
|
|
|
|
} else {
|
|
|
|
this->targetY = this->baseY;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
|
|
|
this->targetY = this->baseY + 110.0f;
|
|
|
|
} else {
|
|
|
|
this->targetY = this->baseY;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
|
|
|
this->targetY = this->baseY + 160.0f;
|
|
|
|
} else {
|
|
|
|
this->targetY = this->baseY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->targetY != this->actor.world.pos.y) {
|
|
|
|
this->actionFunc = BgMizuWater_ChangeWaterLevel;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BgMizuWater_ChangeWaterLevel(BgMizuWater* this, GlobalContext* globalCtx) {
|
|
|
|
s32 pad;
|
|
|
|
s16 prevSwitchFlag;
|
|
|
|
s32 waterLevelActionIndex;
|
|
|
|
WaterBox* waterBoxes;
|
|
|
|
|
|
|
|
waterBoxes = globalCtx->colCtx.colHeader->waterBoxes;
|
|
|
|
switch (this->type) {
|
|
|
|
case 0:
|
|
|
|
prevSwitchFlag = this->actor.params;
|
|
|
|
waterLevelActionIndex = BgMizuWater_GetWaterLevelActionIndex(this->actor.params, globalCtx);
|
|
|
|
if (waterLevelActionIndex != 0) {
|
|
|
|
if (prevSwitchFlag != sWaterLevels[waterLevelActionIndex].switchFlag) {
|
|
|
|
this->actor.params = sWaterLevels[waterLevelActionIndex].switchFlag;
|
|
|
|
this->targetY = sWaterLevels[waterLevelActionIndex].yDiff + this->baseY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((prevSwitchFlag != this->actor.params) && (prevSwitchFlag != 0)) {
|
|
|
|
Flags_UnsetSwitch(globalCtx, prevSwitchFlag);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Math_StepToF(&this->actor.world.pos.y, this->targetY, 5.0f)) {
|
|
|
|
globalCtx->roomCtx.unk_74[0] = 0;
|
|
|
|
this->actionFunc = BgMizuWater_WaitForAction;
|
|
|
|
Message_CloseTextbox(globalCtx);
|
|
|
|
}
|
|
|
|
BgMizuWater_SetWaterBoxesHeight(globalCtx->colCtx.colHeader->waterBoxes, this->actor.world.pos.y);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
|
|
|
this->targetY = this->baseY + 85.0f;
|
|
|
|
} else {
|
|
|
|
this->targetY = this->baseY;
|
|
|
|
}
|
|
|
|
if (Math_StepToF(&this->actor.world.pos.y, this->targetY, 1.0f)) {
|
|
|
|
globalCtx->roomCtx.unk_74[0] = 0;
|
|
|
|
this->actionFunc = BgMizuWater_WaitForAction;
|
|
|
|
}
|
|
|
|
waterBoxes[6].ySurface = this->actor.world.pos.y;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
|
|
|
this->targetY = this->baseY + 110.0f;
|
|
|
|
} else {
|
|
|
|
this->targetY = this->baseY;
|
|
|
|
}
|
|
|
|
if (Math_StepToF(&this->actor.world.pos.y, this->targetY, 1.0f)) {
|
|
|
|
globalCtx->roomCtx.unk_74[0] = 0;
|
|
|
|
this->actionFunc = BgMizuWater_WaitForAction;
|
|
|
|
}
|
|
|
|
waterBoxes[8].ySurface = this->actor.world.pos.y;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
if (Flags_GetSwitch(globalCtx, this->switchFlag)) {
|
|
|
|
this->targetY = this->baseY + 160.0f;
|
|
|
|
} else {
|
|
|
|
this->targetY = this->baseY;
|
|
|
|
}
|
|
|
|
if (Math_StepToF(&this->actor.world.pos.y, this->targetY, 1.0f)) {
|
|
|
|
globalCtx->roomCtx.unk_74[0] = 0;
|
|
|
|
this->actionFunc = BgMizuWater_WaitForAction;
|
|
|
|
}
|
|
|
|
waterBoxes[16].ySurface = this->actor.world.pos.y;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->targetY < this->actor.world.pos.y) {
|
|
|
|
func_800AA000(0.0f, 0x78, 0x14, 0xA);
|
|
|
|
func_8002F948(&this->actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG);
|
|
|
|
} else if (this->targetY > this->actor.world.pos.y) {
|
|
|
|
func_800AA000(0.0f, 0x78, 0x14, 0xA);
|
|
|
|
func_8002F948(&this->actor, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void BgMizuWater_Update(Actor* thisx, GlobalContext* globalCtx) {
|
|
|
|
BgMizuWater* this = (BgMizuWater*)thisx;
|
|
|
|
s32 posY;
|
|
|
|
s32 unk0;
|
|
|
|
s32 unk1;
|
|
|
|
s32 pad;
|
|
|
|
|
|
|
|
if (bREG(15) == 0) {
|
|
|
|
osSyncPrintf("%x %x %x\n", Flags_GetSwitch(globalCtx, WATER_TEMPLE_WATER_F1_FLAG),
|
|
|
|
Flags_GetSwitch(globalCtx, WATER_TEMPLE_WATER_F2_FLAG),
|
|
|
|
Flags_GetSwitch(globalCtx, WATER_TEMPLE_WATER_F3_FLAG));
|
|
|
|
}
|
|
|
|
if (this->type == 0) {
|
|
|
|
posY = this->actor.world.pos.y;
|
|
|
|
unk0 = 0;
|
|
|
|
unk1 = 0;
|
|
|
|
if (posY < WATER_TEMPLE_WATER_F1_Y) {
|
|
|
|
unk0 = 0;
|
|
|
|
unk1 = (posY - WATER_TEMPLE_WATER_B1_Y) / (WATER_TEMPLE_WATER_F1_Y - WATER_TEMPLE_WATER_B1_Y) * 200;
|
|
|
|
} else if (posY < WATER_TEMPLE_WATER_F2_Y) {
|
|
|
|
unk0 = 1;
|
|
|
|
unk1 = 255 - (s32)((posY - WATER_TEMPLE_WATER_F1_Y) / (WATER_TEMPLE_WATER_F2_Y - WATER_TEMPLE_WATER_F1_Y) *
|
|
|
|
(255 - 160));
|
|
|
|
} else if (posY <= WATER_TEMPLE_WATER_F3_Y) {
|
|
|
|
unk0 = 2;
|
|
|
|
unk1 = 255 - (s32)((posY - WATER_TEMPLE_WATER_F2_Y) / (WATER_TEMPLE_WATER_F3_Y - WATER_TEMPLE_WATER_F2_Y) *
|
|
|
|
(255 - 160));
|
|
|
|
}
|
|
|
|
globalCtx->roomCtx.unk_74[1] = ((u8)unk0 << 8) | (unk1 & 0xFF);
|
|
|
|
}
|
|
|
|
|
|
|
|
this->actionFunc(this, globalCtx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BgMizuWater_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
|
|
|
BgMizuWater* this = (BgMizuWater*)thisx;
|
|
|
|
s32 gameplayFrames;
|
|
|
|
|
2022-07-05 19:29:34 -04:00
|
|
|
OPEN_DISPS(globalCtx->state.gfxCtx);
|
2022-03-21 21:51:23 -04:00
|
|
|
gameplayFrames = globalCtx->gameplayFrames;
|
|
|
|
func_80093D84(globalCtx->state.gfxCtx);
|
|
|
|
|
|
|
|
gSPSegment(POLY_XLU_DISP++, 0x0C,
|
|
|
|
Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, -gameplayFrames * 1, gameplayFrames * 1, 32, 32, 1, 0,
|
|
|
|
-gameplayFrames * 1, 32, 32));
|
|
|
|
|
2022-07-05 19:29:34 -04:00
|
|
|
gSPMatrix(POLY_XLU_DISP++, MATRIX_NEWMTX(globalCtx->state.gfxCtx),
|
2022-03-21 21:51:23 -04:00
|
|
|
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
|
|
|
|
|
|
|
gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 128);
|
|
|
|
|
|
|
|
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 102);
|
|
|
|
|
|
|
|
gSPDisplayList(POLY_XLU_DISP++, gObjectMizuObjectsWaterDL_004B20);
|
|
|
|
|
2022-07-05 19:29:34 -04:00
|
|
|
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
2022-03-21 21:51:23 -04:00
|
|
|
}
|