mirror of https://github.com/zeldaret/mm.git
Document the function that handles the Giant's Mask cutscene in Boss02 (#1345)
* Document the function that handles the Giant's Mask cutscene in Boss02 * Remove newline between fallthrough and next case
This commit is contained in:
parent
5625603b56
commit
27ccadc77e
|
@ -31,12 +31,42 @@ void Boss02_Static_Update(Actor* thisx, PlayState* play);
|
|||
void Boss02_Static_Draw(Actor* thisx, PlayState* play);
|
||||
void Boss02_UpdateEffects(PlayState* play);
|
||||
void Boss02_DrawEffects(PlayState* play);
|
||||
void func_809DD934(Boss02* this, PlayState* play);
|
||||
void Boss02_HandleGiantsMaskCutscene(Boss02* this, PlayState* play);
|
||||
void func_809DEAC4(Boss02* this, PlayState* play);
|
||||
|
||||
u8 D_809E0420;
|
||||
u8 D_809E0421;
|
||||
typedef enum {
|
||||
/* 0 */ GIANTS_MASK_CS_STATE_WAITING_FOR_MASK, // Starts the cutscene when the player puts on/takes off the mask.
|
||||
/* 1 */ GIANTS_MASK_CS_STATE_MASK_ON, // Controls the cutscene where the player puts the mask on.
|
||||
/* 2 */ GIANTS_MASK_CS_STATE_MASK_ON_SKIPPED, // Moves to the "done" state when the mask-on cutscene is skipped.
|
||||
/* 10 */ GIANTS_MASK_CS_STATE_MASK_OFF = 10, // Controls the cutscene where the player takes the mask off.
|
||||
/* 11 */ GIANTS_MASK_CS_STATE_MASK_OFF_SKIPPED, // Moves to the "done" state when the mask-off cutscene is skipped.
|
||||
/* 20 */ GIANTS_MASK_CS_STATE_DONE = 20 // Stops the cutscene and resets the player's scale back to normal.
|
||||
} GiantsMaskCsState;
|
||||
|
||||
typedef enum {
|
||||
/* 0 */ GIANTS_MASK_CS_FLASH_STATE_NOT_STARTED, // Does nothing at all.
|
||||
/* 1 */ GIANTS_MASK_CS_FLASH_STATE_STARTED, // Plays the "mask flash" SFX and initializes a white FillScreen.
|
||||
/* 2 */ GIANTS_MASK_CS_FLASH_STATE_INCREASE_ALPHA, // Increases the alpha for the FillScreen on every frame.
|
||||
/* 3 */ GIANTS_MASK_CS_FLASH_STATE_DECREASE_ALPHA // Decreases the alpha for the FillScreen on every frame.
|
||||
} GiantsMaskCsFlashState;
|
||||
|
||||
/**
|
||||
* If set to true, the player can skip the cutscene of putting on the Giant's Mask
|
||||
* by pressing A, B, or any C-button. If false, they must watch it in full.
|
||||
*/
|
||||
u8 sCanSkipMaskOnCs;
|
||||
|
||||
/**
|
||||
* If set to true, the player can skip the cutscene of taking off the Giant's Mask
|
||||
* by pressing A, B, or any C-button. If false, they must watch it in full.
|
||||
*/
|
||||
u8 sCanSkipMaskOffCs;
|
||||
|
||||
/**
|
||||
* True when the player is giant-sized (i.e. wearing the Giant's Mask), false when the player is normal-sized.
|
||||
*/
|
||||
u8 sIsInGiantMode;
|
||||
|
||||
Boss02* sRedTwinmold;
|
||||
Boss02* sBlueTwinmold;
|
||||
Boss02* sTwinmoldStatic;
|
||||
|
@ -468,7 +498,7 @@ Vec3f D_809DFA2C[] = {
|
|||
{ -800.0f, -1000.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f },
|
||||
};
|
||||
|
||||
void func_809DA1D0(PlayState* play, u8 red, u8 green, u8 blue, u8 alpha) {
|
||||
void Boss02_FillScreen(PlayState* play, u8 red, u8 green, u8 blue, u8 alpha) {
|
||||
R_PLAY_FILL_SCREEN_ON = true;
|
||||
R_PLAY_FILL_SCREEN_R = red;
|
||||
R_PLAY_FILL_SCREEN_G = green;
|
||||
|
@ -476,11 +506,11 @@ void func_809DA1D0(PlayState* play, u8 red, u8 green, u8 blue, u8 alpha) {
|
|||
R_PLAY_FILL_SCREEN_ALPHA = alpha;
|
||||
}
|
||||
|
||||
void func_809DA22C(PlayState* play, u8 alpha) {
|
||||
void Boss02_SetFillScreenAlpha(PlayState* play, u8 alpha) {
|
||||
R_PLAY_FILL_SCREEN_ALPHA = alpha;
|
||||
}
|
||||
|
||||
void func_809DA24C(PlayState* play) {
|
||||
void Boss02_StopFillScreen(PlayState* play) {
|
||||
R_PLAY_FILL_SCREEN_ON = false;
|
||||
}
|
||||
|
||||
|
@ -572,7 +602,7 @@ void Boss02_Init(Actor* thisx, PlayState* play) {
|
|||
this->actor.update = Boss02_Static_Update;
|
||||
this->actor.draw = Boss02_Static_Draw;
|
||||
this->actor.flags &= ~ACTOR_FLAG_1;
|
||||
this->unk_1D70 = 0.00999999977648f;
|
||||
this->playerScale = 0.01f;
|
||||
if ((KREG(64) != 0) || CHECK_EVENTINF(EVENTINF_55) || (sBlueWarp != NULL)) {
|
||||
this->unk_1D20 = 0;
|
||||
sMusicStartTimer = KREG(15) + 20;
|
||||
|
@ -1181,7 +1211,7 @@ void Boss02_Twinmold_Update(Actor* thisx, PlayState* play) {
|
|||
Actor_SetScale(&this->actor, 0.060000001f);
|
||||
}
|
||||
|
||||
if (sTwinmoldStatic->unk_1D18 == 0) {
|
||||
if (sTwinmoldStatic->giantsMaskCsState == GIANTS_MASK_CS_STATE_WAITING_FOR_MASK) {
|
||||
for (i = 0; i < ARRAY_COUNT(this->unk_0146); i++) {
|
||||
if (this->unk_0146[i] != 0) {
|
||||
this->unk_0146[i]--;
|
||||
|
@ -1294,17 +1324,17 @@ void Boss02_Static_Update(Actor* thisx, PlayState* play) {
|
|||
play->envCtx.sandstormState = 0xD;
|
||||
|
||||
if (sBlueWarp != NULL) {
|
||||
this->unk_1D74 = KREG(23) + -15.0f;
|
||||
this->fogNear = KREG(23) + -15.0f;
|
||||
D_801F4E30 = 0;
|
||||
play->envCtx.lightSettingOverride = 1;
|
||||
play->skyboxId = SKYBOX_NORMAL_SKY;
|
||||
} else if (!sIsInGiantMode) {
|
||||
this->unk_1D74 = 0.0f;
|
||||
this->fogNear = 0.0f;
|
||||
D_801F4E30 = this->unk_1D7C;
|
||||
play->envCtx.lightSettingOverride = 0;
|
||||
play->skyboxId = SKYBOX_2;
|
||||
} else {
|
||||
this->unk_1D74 = KREG(23) + -15.0f;
|
||||
this->fogNear = KREG(23) + -15.0f;
|
||||
D_801F4E30 = ((KREG(24) * 0.1f) + 1.0f) * this->unk_1D7C;
|
||||
play->envCtx.lightSettingOverride = 1;
|
||||
play->skyboxId = SKYBOX_NORMAL_SKY;
|
||||
|
@ -1327,7 +1357,7 @@ void Boss02_Static_Update(Actor* thisx, PlayState* play) {
|
|||
|
||||
Boss02_UpdateEffects(play);
|
||||
func_809DEAC4(this, play);
|
||||
func_809DD934(this, play);
|
||||
Boss02_HandleGiantsMaskCutscene(this, play);
|
||||
}
|
||||
|
||||
Gfx* D_809DFA9C[] = {
|
||||
|
@ -1630,158 +1660,181 @@ void Boss02_DrawEffects(PlayState* play) {
|
|||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
void func_809DD934(Boss02* this, PlayState* play) {
|
||||
/**
|
||||
* This function is primarily responsible for handling the cutscene where the player puts on
|
||||
* or takes off the Giant's Mask. It does some manual camera control, adjusts the player's
|
||||
* scale, switches between the "Normal" and "Giant" variations of the arena, and creates a
|
||||
* "flash" when the cutscene ends by filling the screen with white. In addition, this function
|
||||
* is responsible for updating the EnvironmentContext's fogNear variable, which it does even
|
||||
* when the Giant's Mask cutscene is not playing.
|
||||
*/
|
||||
void Boss02_HandleGiantsMaskCutscene(Boss02* this, PlayState* play) {
|
||||
Player* player = GET_PLAYER(play);
|
||||
s16 i;
|
||||
Actor* temp_a0_5;
|
||||
Vec3f sp58;
|
||||
u8 sp57 = 0;
|
||||
f32 phi_f0_2;
|
||||
Actor* actorIter;
|
||||
Vec3f subCamEyeOffset;
|
||||
u8 switchArena = false;
|
||||
f32 scale;
|
||||
s16 alpha;
|
||||
|
||||
this->unk_1D14++;
|
||||
this->giantsMaskCsTimer++;
|
||||
|
||||
switch (this->unk_1D18) {
|
||||
case 0:
|
||||
switch (this->giantsMaskCsState) {
|
||||
case GIANTS_MASK_CS_STATE_WAITING_FOR_MASK:
|
||||
if (player->stateFlags1 & PLAYER_STATE1_100) {
|
||||
Cutscene_StartManual(play, &play->csCtx);
|
||||
this->subCamId = Play_CreateSubCamera(play);
|
||||
Play_ChangeCameraStatus(play, CAM_ID_MAIN, CAM_STATUS_WAIT);
|
||||
Play_ChangeCameraStatus(play, this->subCamId, CAM_STATUS_ACTIVE);
|
||||
Play_EnableMotionBlur(150);
|
||||
this->unk_1D14 = 0;
|
||||
this->giantsMaskCsTimer = 0;
|
||||
this->subCamAtVel = 0.0f;
|
||||
this->unk_1D58 = 0.0f;
|
||||
this->subCamUpRotZScale = 0.0f;
|
||||
if (!sIsInGiantMode) {
|
||||
this->unk_1D18 = 1;
|
||||
this->unk_1D68 = 10.0f;
|
||||
this->unk_1D64 = 60.0f;
|
||||
this->unk_1D6C = 23.0f;
|
||||
this->unk_1D70 = 0.01f;
|
||||
this->unk_1D74 = 0.0f;
|
||||
goto label1;
|
||||
this->giantsMaskCsState = GIANTS_MASK_CS_STATE_MASK_ON;
|
||||
this->subCamEyeOffsetY = 10.0f;
|
||||
this->subCamDistZFromPlayer = 60.0f;
|
||||
this->subCamAtOffsetY = 23.0f;
|
||||
this->playerScale = 0.01f;
|
||||
this->fogNear = 0.0f;
|
||||
goto maskOn; // Jumps to this label to prevent the player from skipping the cutscene immediately.
|
||||
} else {
|
||||
this->unk_1D18 = 10;
|
||||
this->unk_1D68 = 10.0f;
|
||||
this->unk_1D64 = 200.0f;
|
||||
this->unk_1D6C = 273.0f;
|
||||
this->unk_1D70 = 0.1f;
|
||||
this->unk_1D74 = -100.0f;
|
||||
sp57 = 1;
|
||||
goto label2;
|
||||
this->giantsMaskCsState = GIANTS_MASK_CS_STATE_MASK_OFF;
|
||||
this->subCamEyeOffsetY = 10.0f;
|
||||
this->subCamDistZFromPlayer = 200.0f;
|
||||
this->subCamAtOffsetY = 273.0f;
|
||||
this->playerScale = 0.1f;
|
||||
this->fogNear = -100.0f;
|
||||
switchArena = true;
|
||||
goto maskOff; // Jumps to this label to prevent the player from skipping the cutscene immediately.
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if ((this->unk_1D14 < 80) && (D_809E0420 != 0) &&
|
||||
case GIANTS_MASK_CS_STATE_MASK_ON:
|
||||
if ((this->giantsMaskCsTimer < 80) && sCanSkipMaskOnCs &&
|
||||
CHECK_BTN_ANY(CONTROLLER1(&play->state)->press.button,
|
||||
BTN_A | BTN_B | BTN_CUP | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT)) {
|
||||
this->unk_1D18++;
|
||||
this->unk_1D78 = 1;
|
||||
this->unk_1D14 = 0;
|
||||
this->giantsMaskCsState++;
|
||||
this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_STARTED;
|
||||
this->giantsMaskCsTimer = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
maskOn:
|
||||
if (this->giantsMaskCsTimer >= 50) {
|
||||
if (this->giantsMaskCsTimer == (u32)(BREG(43) + 60)) {
|
||||
Audio_PlaySfx(NA_SE_PL_TRANSFORM_GIANT);
|
||||
}
|
||||
|
||||
// Makes the camera quickly move away from the player and look upwards as the player
|
||||
// increases in size. Also decreases the fogNear from 0.0f to -100.0f.
|
||||
Math_ApproachF(&this->subCamDistZFromPlayer, 200.0f, 0.1f, this->subCamAtVel * 640.0f);
|
||||
Math_ApproachF(&this->subCamAtOffsetY, 273.0f, 0.1f, this->subCamAtVel * 150.0f);
|
||||
Math_ApproachF(&this->playerScale, 0.1f, 0.2f, this->subCamAtVel * 0.1f);
|
||||
Math_ApproachF(&this->fogNear, -100.0f, 1.0f, this->subCamAtVel * 100.0f);
|
||||
Math_ApproachF(&this->subCamAtVel, 1.0f, 1.0f, 0.001f);
|
||||
} else {
|
||||
label1:
|
||||
if (this->unk_1D14 >= 50) {
|
||||
if (this->unk_1D14 == (u32)(BREG(43) + 60)) {
|
||||
Audio_PlaySfx(NA_SE_PL_TRANSFORM_GIANT);
|
||||
}
|
||||
Math_ApproachF(&this->unk_1D64, 200.0f, 0.1f, this->subCamAtVel * 640.0f);
|
||||
Math_ApproachF(&this->unk_1D6C, 273.0f, 0.1f, this->subCamAtVel * 150.0f);
|
||||
Math_ApproachF(&this->unk_1D70, 0.1f, 0.2f, this->subCamAtVel * 0.1f);
|
||||
Math_ApproachF(&this->unk_1D74, -100.0f, 1.0f, this->subCamAtVel * 100.0f);
|
||||
Math_ApproachF(&this->subCamAtVel, 1.0f, 1.0f, 0.001f);
|
||||
} else {
|
||||
Math_ApproachF(&this->unk_1D64, 30.0f, 0.1f, 1.0f);
|
||||
}
|
||||
// Makes the camera slowly approach the player.
|
||||
Math_ApproachF(&this->subCamDistZFromPlayer, 30.0f, 0.1f, 1.0f);
|
||||
}
|
||||
|
||||
if (this->unk_1D14 > 50) {
|
||||
Math_ApproachZeroF(&this->unk_1D58, 1.0f, 0.06f);
|
||||
} else {
|
||||
Math_ApproachF(&this->unk_1D58, 0.4f, 1.0f, 0.02f);
|
||||
}
|
||||
// Makes the camera roll side-to-side at the start of the cutscene, and stops
|
||||
// the camera from rolling after 51 frames have passed.
|
||||
if (this->giantsMaskCsTimer > 50) {
|
||||
Math_ApproachZeroF(&this->subCamUpRotZScale, 1.0f, 0.06f);
|
||||
} else {
|
||||
Math_ApproachF(&this->subCamUpRotZScale, 0.4f, 1.0f, 0.02f);
|
||||
}
|
||||
|
||||
if (this->unk_1D14 == 107) {
|
||||
this->unk_1D78 = 1;
|
||||
}
|
||||
if (this->giantsMaskCsTimer == 107) {
|
||||
this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_STARTED;
|
||||
}
|
||||
|
||||
if (this->unk_1D14 < 121) {
|
||||
break;
|
||||
}
|
||||
|
||||
sp57 = 1;
|
||||
D_809E0420 = 1;
|
||||
goto block_38;
|
||||
if (this->giantsMaskCsTimer > 120) {
|
||||
switchArena = true;
|
||||
sCanSkipMaskOnCs = true;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (this->unk_1D14 < 8) {
|
||||
break;
|
||||
case GIANTS_MASK_CS_STATE_MASK_ON_SKIPPED:
|
||||
if (this->giantsMaskCsTimer >= 8) {
|
||||
switchArena = true;
|
||||
goto done;
|
||||
}
|
||||
sp57 = 1;
|
||||
goto block_38;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
if ((this->unk_1D14 < 30) && (D_809E0421 != 0) &&
|
||||
case GIANTS_MASK_CS_STATE_MASK_OFF:
|
||||
if ((this->giantsMaskCsTimer < 30) && sCanSkipMaskOffCs &&
|
||||
CHECK_BTN_ANY(CONTROLLER1(&play->state)->press.button,
|
||||
BTN_A | BTN_B | BTN_CUP | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT)) {
|
||||
this->unk_1D18++;
|
||||
this->unk_1D78 = 1;
|
||||
this->unk_1D14 = 0;
|
||||
this->giantsMaskCsState++;
|
||||
this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_STARTED;
|
||||
this->giantsMaskCsTimer = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
label2:
|
||||
if (this->unk_1D14 != 0) {
|
||||
if (this->unk_1D14 == (u32)(BREG(44) + 10)) {
|
||||
maskOff:
|
||||
if (this->giantsMaskCsTimer != 0) {
|
||||
if (this->giantsMaskCsTimer == (u32)(BREG(44) + 10)) {
|
||||
Audio_PlaySfx(NA_SE_PL_TRANSFORM_NORAML);
|
||||
}
|
||||
Math_ApproachF(&this->unk_1D64, 60.0f, 0.1f, this->subCamAtVel * 640.0f);
|
||||
Math_ApproachF(&this->unk_1D6C, 23.0f, 0.1f, this->subCamAtVel * 150.0f);
|
||||
Math_ApproachF(&this->unk_1D70, 0.01f, 0.1f, 0.003f);
|
||||
Math_ApproachF(&this->unk_1D74, 0.0f, 1.0f, this->subCamAtVel * 100.0f);
|
||||
|
||||
// Makes the camera move slowly towards the player and look downwards as the player
|
||||
// decreases in size. Also increases the fogNear from -100.0f to 0.0f.
|
||||
Math_ApproachF(&this->subCamDistZFromPlayer, 60.0f, 0.1f, this->subCamAtVel * 640.0f);
|
||||
Math_ApproachF(&this->subCamAtOffsetY, 23.0f, 0.1f, this->subCamAtVel * 150.0f);
|
||||
Math_ApproachF(&this->playerScale, 0.01f, 0.1f, 0.003f);
|
||||
Math_ApproachF(&this->fogNear, 0.0f, 1.0f, this->subCamAtVel * 100.0f);
|
||||
Math_ApproachF(&this->subCamAtVel, 2.0f, 1.0f, 0.01f);
|
||||
}
|
||||
|
||||
if (this->unk_1D14 == 42) {
|
||||
this->unk_1D78 = 1;
|
||||
if (this->giantsMaskCsTimer == 42) {
|
||||
this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_STARTED;
|
||||
}
|
||||
|
||||
if (this->unk_1D14 > 50) {
|
||||
D_809E0421 = 1;
|
||||
goto block_38;
|
||||
if (this->giantsMaskCsTimer > 50) {
|
||||
sCanSkipMaskOffCs = true;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
case 11:
|
||||
if (this->unk_1D14 < 8) {
|
||||
break;
|
||||
case GIANTS_MASK_CS_STATE_MASK_OFF_SKIPPED:
|
||||
if (this->giantsMaskCsTimer >= 8) {
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
block_38:
|
||||
case 20:
|
||||
this->unk_1D18 = 0;
|
||||
done:
|
||||
case GIANTS_MASK_CS_STATE_DONE:
|
||||
// Ends the cutscene and restores the player's scale to its "original" value of 0.1f.
|
||||
// This might seem strange in the case where the player has put on the Giant's Mask,
|
||||
// since they seem so large after the cutscene ends. However, the player is still
|
||||
// their normal size; the arena and everything in it has shrunk instead.
|
||||
this->giantsMaskCsState = GIANTS_MASK_CS_STATE_WAITING_FOR_MASK;
|
||||
func_80169AFC(play, this->subCamId, 0);
|
||||
this->subCamId = SUB_CAM_ID_DONE;
|
||||
Cutscene_StopManual(play, &play->csCtx);
|
||||
this->actor.flags |= ACTOR_FLAG_1;
|
||||
player->stateFlags1 &= ~PLAYER_STATE1_100;
|
||||
this->unk_1D70 = 0.01f;
|
||||
this->playerScale = 0.01f;
|
||||
Play_DisableMotionBlur();
|
||||
break;
|
||||
}
|
||||
|
||||
if (player->transformation == PLAYER_FORM_FIERCE_DEITY) {
|
||||
Actor_SetScale(&player->actor, this->unk_1D70 * 1.5f);
|
||||
Actor_SetScale(&player->actor, this->playerScale * 1.5f);
|
||||
} else {
|
||||
Actor_SetScale(&player->actor, this->unk_1D70);
|
||||
Actor_SetScale(&player->actor, this->playerScale);
|
||||
}
|
||||
|
||||
play->envCtx.lightSettings.fogNear = this->unk_1D74;
|
||||
play->envCtx.lightSettings.fogNear = this->fogNear;
|
||||
|
||||
if (sp57) {
|
||||
sIsInGiantMode = 1 - sIsInGiantMode;
|
||||
// Switches from the "normal" variation of the arena to the "giant" variation (or vice versa)
|
||||
// at the appropriate point in the Giant's Mask cutscene.
|
||||
if (switchArena) {
|
||||
sIsInGiantMode = true - sIsInGiantMode;
|
||||
if (!sIsInGiantMode) {
|
||||
sGiantModeScaleFactor = 1.0f;
|
||||
} else {
|
||||
|
@ -1789,7 +1842,12 @@ void func_809DD934(Boss02* this, PlayState* play) {
|
|||
}
|
||||
|
||||
this->giantModeScaleFactor = sGiantModeScaleFactor;
|
||||
|
||||
if (!sIsInGiantMode) {
|
||||
// In this case, the player is switching from the "giant" arena to the "normal" arena.
|
||||
// The "giant" arena sits 3150 units above the "normal" arena, so this moves the player,
|
||||
// Twinmold, and the blue warp down and scales their world coordinates upwards to be
|
||||
// appropriate for the larger arena.
|
||||
if (sBlueWarp != NULL) {
|
||||
sBlueWarp->unk_203 = 0;
|
||||
sBlueWarp->unk_204 = 1.0f;
|
||||
|
@ -1802,6 +1860,10 @@ void func_809DD934(Boss02* this, PlayState* play) {
|
|||
player->fallStartHeight = player->actor.world.pos.y;
|
||||
player->actor.world.pos.z *= 10.0f;
|
||||
|
||||
// If the blue warp exists, and if the player is within 60 units of its center after switching
|
||||
// to the "normal" arena, this code will move the player to a fixed point next to the blue warp.
|
||||
// This prevents the player from instantly activating the blue warp after switching arenas, and
|
||||
// it relies on the blue warp's XZ-coordinates being (0, 0) as they are in Twinmold's boss room.
|
||||
if ((sBlueWarp != NULL) && ((SQ(player->actor.world.pos.z) + SQ(player->actor.world.pos.x)) < SQ(60.0f))) {
|
||||
player->actor.world.pos.z = 60.0f;
|
||||
player->actor.world.pos.x = 60.0f;
|
||||
|
@ -1862,7 +1924,11 @@ void func_809DD934(Boss02* this, PlayState* play) {
|
|||
sBlueTwinmold->unk_0188.y *= 10.0f;
|
||||
|
||||
} else {
|
||||
if (sBlueWarp != 0) {
|
||||
// In this case, the player is switching from the "normal" arena to the "giant" arena.
|
||||
// The "giant" arena sits 3150 units above the "normal" arena, so this moves the player,
|
||||
// Twinmold, and the blue warp up and scales their world coordinates downwards to be
|
||||
// appropriate for the smaller arena.
|
||||
if (sBlueWarp != NULL) {
|
||||
sBlueWarp->unk_203 = 1;
|
||||
sBlueWarp->unk_204 = 0.1f;
|
||||
sBlueWarp->dyna.actor.world.pos.y = 3155.0f;
|
||||
|
@ -1932,113 +1998,120 @@ void func_809DD934(Boss02* this, PlayState* play) {
|
|||
player->actor.home.pos = player->actor.world.pos;
|
||||
player->actor.prevPos = player->actor.world.pos;
|
||||
|
||||
temp_a0_5 = play->actorCtx.actorLists[ACTORCAT_BG].first;
|
||||
while (temp_a0_5 != NULL) {
|
||||
if (temp_a0_5->id == ACTOR_BG_INIBS_MOVEBG) {
|
||||
Actor_Kill(temp_a0_5);
|
||||
// Kills the existing instance of Twinmold's arena and spawns a new instance with the appropriate
|
||||
// scale and at the appropriate height.
|
||||
actorIter = play->actorCtx.actorLists[ACTORCAT_BG].first;
|
||||
while (actorIter != NULL) {
|
||||
if (actorIter->id == ACTOR_BG_INIBS_MOVEBG) {
|
||||
Actor_Kill(actorIter);
|
||||
break;
|
||||
}
|
||||
temp_a0_5 = temp_a0_5->next;
|
||||
|
||||
actorIter = actorIter->next;
|
||||
}
|
||||
{
|
||||
f32 tmp = sIsInGiantMode ? 3150.0f : 0.0f;
|
||||
f32 arenaPosY = sIsInGiantMode ? 3150.0f : 0.0f;
|
||||
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_BG_INIBS_MOVEBG, 0, tmp, 0, 0, 0, 0, sIsInGiantMode);
|
||||
Actor_Spawn(&play->actorCtx, play, ACTOR_BG_INIBS_MOVEBG, 0, arenaPosY, 0, 0, 0, 0, sIsInGiantMode);
|
||||
}
|
||||
|
||||
temp_a0_5 = play->actorCtx.actorLists[ACTORCAT_BOSS].first;
|
||||
while (temp_a0_5 != NULL) {
|
||||
if ((temp_a0_5->id == ACTOR_EN_TANRON5) || (temp_a0_5->id == ACTOR_ITEM_B_HEART)) {
|
||||
// Moves the props in Twinmold's arena and the Heart Container 3150 units up or down
|
||||
// so they're in the appropriate arena and scales them accordingly.
|
||||
actorIter = play->actorCtx.actorLists[ACTORCAT_BOSS].first;
|
||||
while (actorIter != NULL) {
|
||||
if ((actorIter->id == ACTOR_EN_TANRON5) || (actorIter->id == ACTOR_ITEM_B_HEART)) {
|
||||
if (!sIsInGiantMode) {
|
||||
temp_a0_5->world.pos.y -= 3150.0f;
|
||||
temp_a0_5->world.pos.y *= 10.0f;
|
||||
actorIter->world.pos.y -= 3150.0f;
|
||||
actorIter->world.pos.y *= 10.0f;
|
||||
|
||||
temp_a0_5->floorHeight -= 3150.0f;
|
||||
temp_a0_5->floorHeight *= 10.0f;
|
||||
actorIter->floorHeight -= 3150.0f;
|
||||
actorIter->floorHeight *= 10.0f;
|
||||
|
||||
phi_f0_2 = 10.0f;
|
||||
scale = 10.0f;
|
||||
} else {
|
||||
temp_a0_5->world.pos.y *= 0.1f;
|
||||
temp_a0_5->world.pos.y += 3150.0f;
|
||||
actorIter->world.pos.y *= 0.1f;
|
||||
actorIter->world.pos.y += 3150.0f;
|
||||
|
||||
temp_a0_5->floorHeight *= 0.1f;
|
||||
temp_a0_5->floorHeight += 3150.0f;
|
||||
actorIter->floorHeight *= 0.1f;
|
||||
actorIter->floorHeight += 3150.0f;
|
||||
|
||||
phi_f0_2 = 0.1f;
|
||||
scale = 0.1f;
|
||||
}
|
||||
|
||||
temp_a0_5->world.pos.x *= phi_f0_2;
|
||||
temp_a0_5->world.pos.z *= phi_f0_2;
|
||||
actorIter->world.pos.x *= scale;
|
||||
actorIter->world.pos.z *= scale;
|
||||
|
||||
temp_a0_5->speed *= phi_f0_2;
|
||||
actorIter->speed *= scale;
|
||||
|
||||
temp_a0_5->velocity.x *= phi_f0_2;
|
||||
temp_a0_5->velocity.y *= phi_f0_2;
|
||||
temp_a0_5->velocity.z *= phi_f0_2;
|
||||
actorIter->velocity.x *= scale;
|
||||
actorIter->velocity.y *= scale;
|
||||
actorIter->velocity.z *= scale;
|
||||
|
||||
temp_a0_5->gravity *= phi_f0_2;
|
||||
temp_a0_5->terminalVelocity *= phi_f0_2;
|
||||
actorIter->gravity *= scale;
|
||||
actorIter->terminalVelocity *= scale;
|
||||
|
||||
temp_a0_5->scale.x *= phi_f0_2;
|
||||
temp_a0_5->scale.y *= phi_f0_2;
|
||||
temp_a0_5->scale.z *= phi_f0_2;
|
||||
actorIter->scale.x *= scale;
|
||||
actorIter->scale.y *= scale;
|
||||
actorIter->scale.z *= scale;
|
||||
|
||||
if (temp_a0_5->id == ACTOR_ITEM_B_HEART) {
|
||||
((ItemBHeart*)temp_a0_5)->baseScale *= phi_f0_2;
|
||||
if (actorIter->id == ACTOR_ITEM_B_HEART) {
|
||||
((ItemBHeart*)actorIter)->baseScale *= scale;
|
||||
}
|
||||
}
|
||||
temp_a0_5 = temp_a0_5->next;
|
||||
|
||||
actorIter = actorIter->next;
|
||||
}
|
||||
}
|
||||
|
||||
switch (this->unk_1D78) {
|
||||
case 0:
|
||||
switch (this->giantsMaskCsFlashState) {
|
||||
case GIANTS_MASK_CS_FLASH_STATE_NOT_STARTED:
|
||||
break;
|
||||
|
||||
case 1:
|
||||
this->unk_1D7A = 0;
|
||||
func_809DA1D0(play, 255, 255, 255, 0);
|
||||
this->unk_1D78 = 2;
|
||||
case GIANTS_MASK_CS_FLASH_STATE_STARTED:
|
||||
this->giantsMaskCsFlashAlpha = 0;
|
||||
Boss02_FillScreen(play, 255, 255, 255, 0);
|
||||
this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_INCREASE_ALPHA;
|
||||
Audio_PlaySfx(NA_SE_SY_TRANSFORM_MASK_FLASH);
|
||||
|
||||
case 2:
|
||||
this->unk_1D7A += 40;
|
||||
if (this->unk_1D7A >= 400) {
|
||||
this->unk_1D78 = 3;
|
||||
// fallthrough
|
||||
case GIANTS_MASK_CS_FLASH_STATE_INCREASE_ALPHA:
|
||||
this->giantsMaskCsFlashAlpha += 40;
|
||||
if (this->giantsMaskCsFlashAlpha >= 400) {
|
||||
this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_DECREASE_ALPHA;
|
||||
}
|
||||
alpha = this->unk_1D7A;
|
||||
|
||||
alpha = this->giantsMaskCsFlashAlpha;
|
||||
alpha = CLAMP_MAX(alpha, 255);
|
||||
func_809DA22C(play, alpha);
|
||||
Boss02_SetFillScreenAlpha(play, alpha);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
this->unk_1D7A -= 40;
|
||||
if (this->unk_1D7A <= 0) {
|
||||
this->unk_1D7A = 0;
|
||||
this->unk_1D78 = 0;
|
||||
func_809DA24C(play);
|
||||
case GIANTS_MASK_CS_FLASH_STATE_DECREASE_ALPHA:
|
||||
this->giantsMaskCsFlashAlpha -= 40;
|
||||
if (this->giantsMaskCsFlashAlpha <= 0) {
|
||||
this->giantsMaskCsFlashAlpha = 0;
|
||||
this->giantsMaskCsFlashState = GIANTS_MASK_CS_FLASH_STATE_NOT_STARTED;
|
||||
Boss02_StopFillScreen(play);
|
||||
} else {
|
||||
alpha = this->unk_1D7A;
|
||||
alpha = this->giantsMaskCsFlashAlpha;
|
||||
alpha = CLAMP_MAX(alpha, 255);
|
||||
func_809DA22C(play, alpha);
|
||||
Boss02_SetFillScreenAlpha(play, alpha);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ((this->unk_1D18 != 0) && (this->subCamId != SUB_CAM_ID_DONE)) {
|
||||
if ((this->giantsMaskCsState != GIANTS_MASK_CS_STATE_WAITING_FOR_MASK) && (this->subCamId != SUB_CAM_ID_DONE)) {
|
||||
Matrix_RotateYS(player->actor.shape.rot.y, MTXMODE_NEW);
|
||||
Matrix_MultVecZ(this->unk_1D64, &sp58);
|
||||
Matrix_MultVecZ(this->subCamDistZFromPlayer, &subCamEyeOffset);
|
||||
|
||||
this->subCamEye.x = player->actor.world.pos.x + sp58.x;
|
||||
this->subCamEye.y = player->actor.world.pos.y + sp58.y + this->unk_1D68;
|
||||
this->subCamEye.z = player->actor.world.pos.z + sp58.z;
|
||||
this->subCamEye.x = player->actor.world.pos.x + subCamEyeOffset.x;
|
||||
this->subCamEye.y = player->actor.world.pos.y + subCamEyeOffset.y + this->subCamEyeOffsetY;
|
||||
this->subCamEye.z = player->actor.world.pos.z + subCamEyeOffset.z;
|
||||
|
||||
this->subCamAt.x = player->actor.world.pos.x;
|
||||
this->subCamAt.y = player->actor.world.pos.y + this->unk_1D6C;
|
||||
this->subCamAt.y = player->actor.world.pos.y + this->subCamAtOffsetY;
|
||||
this->subCamAt.z = player->actor.world.pos.z;
|
||||
|
||||
this->unk_1D54 = Math_SinS(this->unk_1D14 * 1512) * this->unk_1D58;
|
||||
Matrix_RotateZF(this->unk_1D54, MTXMODE_APPLY);
|
||||
this->subCamUpRotZ = Math_SinS(this->giantsMaskCsTimer * 1512) * this->subCamUpRotZScale;
|
||||
Matrix_RotateZF(this->subCamUpRotZ, MTXMODE_APPLY);
|
||||
Matrix_MultVecY(1.0f, &this->subCamUp);
|
||||
Play_SetCameraAtEyeUp(play, this->subCamId, &this->subCamAt, &this->subCamEye, &this->subCamUp);
|
||||
ShrinkWindow_Letterbox_SetSizeTarget(27);
|
||||
|
@ -2049,7 +2122,7 @@ void func_809DEAC4(Boss02* this, PlayState* play) {
|
|||
Player* player = GET_PLAYER(play);
|
||||
Boss02* sp68;
|
||||
Vec3f subCamEye;
|
||||
f32 sp58 = 0.0f;
|
||||
f32 subCamEyeOffset = 0.0f;
|
||||
|
||||
this->unk_1D1C++;
|
||||
if (this->unk_0194 == 0) {
|
||||
|
@ -2089,7 +2162,7 @@ void func_809DEAC4(Boss02* this, PlayState* play) {
|
|||
Rumble_Override(0.0f, 50, 200, 1);
|
||||
}
|
||||
this->unk_0150 += 0x4000;
|
||||
sp58 = (Math_SinS(this->unk_0150) * (BREG(19) + 5)) * 0.1f;
|
||||
subCamEyeOffset = (Math_SinS(this->unk_0150) * (BREG(19) + 5)) * 0.1f;
|
||||
Matrix_RotateZF(Math_SinS(this->unk_1D1C * 0x3000) * ((KREG(28) * 0.001f) + 0.017f), MTXMODE_NEW);
|
||||
Matrix_MultVecY(1.0f, &this->subCamUp);
|
||||
Audio_PlaySfx_2(NA_SE_EV_EARTHQUAKE_LAST - SFX_FLAG);
|
||||
|
@ -2208,8 +2281,8 @@ void func_809DEAC4(Boss02* this, PlayState* play) {
|
|||
|
||||
case 103:
|
||||
this->unk_0150 += 0x4000;
|
||||
sp58 = Math_SinS(this->unk_0150);
|
||||
sp58 = (sp58 * this->unk_0146[0]) * 1.5f;
|
||||
subCamEyeOffset = Math_SinS(this->unk_0150);
|
||||
subCamEyeOffset = (subCamEyeOffset * this->unk_0146[0]) * 1.5f;
|
||||
if (this->unk_1D1C == 30) {
|
||||
func_80169AFC(play, this->subCamId, 0);
|
||||
this->subCamId = SUB_CAM_ID_DONE;
|
||||
|
@ -2248,7 +2321,7 @@ void func_809DEAC4(Boss02* this, PlayState* play) {
|
|||
|
||||
if ((this->unk_1D20 != 0) && (this->subCamId != SUB_CAM_ID_DONE)) {
|
||||
subCamEye = this->subCamEye;
|
||||
subCamEye.y += sp58 * sGiantModeScaleFactor;
|
||||
subCamEye.y += subCamEyeOffset * sGiantModeScaleFactor;
|
||||
Play_SetCameraAtEyeUp(play, this->subCamId, &this->subCamAt, &subCamEye, &this->subCamUp);
|
||||
this->subCamUp.z = this->subCamUp.x = 0.0f;
|
||||
this->subCamUp.y = 1.0f;
|
||||
|
|
|
@ -87,8 +87,8 @@ typedef struct Boss02 {
|
|||
/* 0x1C28 */ ColliderJntSph colliderSphere2;
|
||||
/* 0x1C48 */ ColliderJntSphElement colliderSphere2Elements[2];
|
||||
/* 0x1CC8 */ ColliderCylinder colliderCylinder;
|
||||
/* 0x1D14 */ u32 unk_1D14;
|
||||
/* 0x1D18 */ s16 unk_1D18;
|
||||
/* 0x1D14 */ u32 giantsMaskCsTimer;
|
||||
/* 0x1D18 */ s16 giantsMaskCsState;
|
||||
/* 0x1D1A */ s16 unk_1D1A;
|
||||
/* 0x1D1C */ u32 unk_1D1C;
|
||||
/* 0x1D20 */ s16 unk_1D20;
|
||||
|
@ -97,17 +97,17 @@ typedef struct Boss02 {
|
|||
/* 0x1D30 */ Vec3f subCamAt;
|
||||
/* 0x1D3C */ Vec3f subCamUp;
|
||||
/* 0x1D48 */ Vec3f subCamAtNext;
|
||||
/* 0x1D54 */ f32 unk_1D54;
|
||||
/* 0x1D58 */ f32 unk_1D58;
|
||||
/* 0x1D54 */ f32 subCamUpRotZ;
|
||||
/* 0x1D58 */ f32 subCamUpRotZScale;
|
||||
/* 0x1D5C */ f32 subCamAtVel;
|
||||
/* 0x1D60 */ UNK_TYPE1 unk1D60[0x4];
|
||||
/* 0x1D64 */ f32 unk_1D64;
|
||||
/* 0x1D68 */ f32 unk_1D68;
|
||||
/* 0x1D6C */ f32 unk_1D6C;
|
||||
/* 0x1D70 */ f32 unk_1D70;
|
||||
/* 0x1D74 */ f32 unk_1D74;
|
||||
/* 0x1D78 */ u8 unk_1D78;
|
||||
/* 0x1D7A */ s16 unk_1D7A;
|
||||
/* 0x1D64 */ f32 subCamDistZFromPlayer;
|
||||
/* 0x1D68 */ f32 subCamEyeOffsetY;
|
||||
/* 0x1D6C */ f32 subCamAtOffsetY;
|
||||
/* 0x1D70 */ f32 playerScale;
|
||||
/* 0x1D74 */ f32 fogNear;
|
||||
/* 0x1D78 */ u8 giantsMaskCsFlashState;
|
||||
/* 0x1D7A */ s16 giantsMaskCsFlashAlpha;
|
||||
/* 0x1D7C */ s16 unk_1D7C;
|
||||
/* 0x1D7E */ s16 unk_1D7E;
|
||||
} Boss02; // size = 0x1D80
|
||||
|
|
|
@ -9292,9 +9292,9 @@
|
|||
0x809D6C98:("func_809D6C98",),
|
||||
0x809D6E7C:("func_809D6E7C",),
|
||||
0x809D73D4:("func_809D73D4",),
|
||||
0x809DA1D0:("func_809DA1D0",),
|
||||
0x809DA22C:("func_809DA22C",),
|
||||
0x809DA24C:("func_809DA24C",),
|
||||
0x809DA1D0:("Boss02_FillScreen",),
|
||||
0x809DA22C:("Boss02_SetFillScreenAlpha",),
|
||||
0x809DA24C:("Boss02_StopFillScreen",),
|
||||
0x809DA264:("Boss02_SpawnEffectSand",),
|
||||
0x809DA344:("Boss02_SpawnEffectFragment",),
|
||||
0x809DA460:("Boss02_SpawnEffectFlash",),
|
||||
|
@ -9313,7 +9313,7 @@
|
|||
0x809DD0A8:("Boss02_Static_Draw",),
|
||||
0x809DD0CC:("Boss02_UpdateEffects",),
|
||||
0x809DD2F8:("Boss02_DrawEffects",),
|
||||
0x809DD934:("func_809DD934",),
|
||||
0x809DD934:("Boss02_HandleGiantsMaskCutscene",),
|
||||
0x809DEAC4:("func_809DEAC4",),
|
||||
0x809E2760:("Boss03_PlayUnderwaterSfx",),
|
||||
0x809E2788:("Boss03_SpawnEffectWetSpot",),
|
||||
|
|
|
@ -10109,9 +10109,9 @@
|
|||
0x809DFD34:("D_809DFD34","f32","",0x4),
|
||||
0x809DFD38:("D_809DFD38","f32","",0x4),
|
||||
0x809DFD3C:("D_809DFD3C","f32","",0x4),
|
||||
0x809E0420:("D_809E0420","UNK_TYPE1","",0x1),
|
||||
0x809E0421:("D_809E0421","UNK_TYPE1","",0x1),
|
||||
0x809E0422:("D_809E0422","UNK_TYPE1","",0x1),
|
||||
0x809E0420:("sCanSkipMaskOnCs","UNK_TYPE1","",0x1),
|
||||
0x809E0421:("sCanSkipMaskOffCs","UNK_TYPE1","",0x1),
|
||||
0x809E0422:("sIsInGiantMode","UNK_TYPE1","",0x1),
|
||||
0x809E0424:("sRedTwinmold","UNK_TYPE4","",0x4),
|
||||
0x809E0428:("sBlueTwinmold","UNK_TYPE4","",0x4),
|
||||
0x809E042C:("sTwinmoldStatic","UNK_TYPE4","",0x4),
|
||||
|
|
Loading…
Reference in New Issue