Document Twinmold Effects (#896)

This commit is contained in:
Tom Overton 2022-07-11 19:29:01 -07:00 committed by GitHub
parent 9969b204bc
commit c667452329
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 128 additions and 118 deletions

View File

@ -27,20 +27,20 @@ void func_809DAB78(Boss02* this, PlayState* play);
void func_809DC218(Actor* thisx, PlayState* play);
void func_809DC78C(Actor* thisx, PlayState* play);
void func_809DD0A8(Actor* thisx, PlayState* play);
void func_809DD0CC(PlayState* play);
void func_809DD2F8(PlayState* play);
void Boss02_UpdateEffects(PlayState* play);
void Boss02_DrawEffects(PlayState* play);
void func_809DD934(Boss02* this, PlayState* play);
void func_809DEAC4(Boss02* this, PlayState* play);
u8 D_809E0420;
u8 D_809E0421;
u8 D_809E0422;
u8 D_809E0422; // 0 when the giant's mask is off, 1 when the giant's mask is on
Boss02* D_809E0424;
Boss02* D_809E0428;
Boss02* D_809E042C;
u8 D_809E0430;
DoorWarp1* D_809E0434;
Boss02Effects D_809E0438[150];
TwinmoldEffect D_809E0438[150];
static DamageTable sDamageTable1 = {
/* Deku Nut */ DMG_ENTRY(0, 0x0),
@ -478,60 +478,60 @@ void func_809DA24C(PlayState* play) {
MREG(64) = 0;
}
void func_809DA264(Boss02Effects* effects, Vec3f* vec, f32 arg2) {
void Boss02_SpawnEffectSand(TwinmoldEffect* effects, Vec3f* pos, f32 scale) {
s16 i;
for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effects++) {
if (effects->unk_24 == 0) {
effects->unk_24 = 1;
effects->unk_00 = *vec;
effects->unk_0C.x = randPlusMinusPoint5Scaled(30.0f);
effects->unk_0C.y = Rand_ZeroFloat(7.0f) + 7.0f;
effects->unk_0C.z = randPlusMinusPoint5Scaled(30.0f);
effects->unk_18.y = -0.3f;
effects->unk_34 = arg2;
effects->unk_2C = 255;
effects->unk_26 = 0;
effects->unk_38 = 2.0f * arg2;
effects->unk_18.x = effects->unk_18.z = 0.0f;
if (effects->type == TWINMOLD_EFFECT_NONE) {
effects->type = TWINMOLD_EFFECT_SAND;
effects->pos = *pos;
effects->velocity.x = randPlusMinusPoint5Scaled(30.0f);
effects->velocity.y = Rand_ZeroFloat(7.0f) + 7.0f;
effects->velocity.z = randPlusMinusPoint5Scaled(30.0f);
effects->accel.y = -0.3f;
effects->scale = scale;
effects->alpha = 255;
effects->timer = 0;
effects->targetScale = 2.0f * scale;
effects->accel.x = effects->accel.z = 0.0f;
break;
}
}
}
void func_809DA344(Boss02Effects* effects, Vec3f* vec) {
void Boss02_SpawnEffectFragment(TwinmoldEffect* effects, Vec3f* pos) {
s16 i;
for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effects++) {
if (effects->unk_24 == 0) {
effects->unk_24 = 3;
effects->unk_00 = *vec;
effects->unk_26 = Rand_ZeroFloat(20.0f);
effects->unk_0C.x = randPlusMinusPoint5Scaled(50.0f);
effects->unk_0C.y = randPlusMinusPoint5Scaled(50.0f);
effects->unk_0C.z = randPlusMinusPoint5Scaled(50.0f);
effects->unk_18.z = 0.0f;
effects->unk_18.x = 0.0f;
effects->unk_18.y = -1.5f;
effects->unk_34 = Rand_ZeroFloat(0.04f) + 0.02f;
effects->unk_30 = Rand_ZeroFloat(32767.0f);
effects->unk_2E = Rand_ZeroFloat(32767.0f);
if (effects->type == TWINMOLD_EFFECT_NONE) {
effects->type = TWINMOLD_EFFECT_FRAGMENT;
effects->pos = *pos;
effects->timer = Rand_ZeroFloat(20.0f);
effects->velocity.x = randPlusMinusPoint5Scaled(50.0f);
effects->velocity.y = randPlusMinusPoint5Scaled(50.0f);
effects->velocity.z = randPlusMinusPoint5Scaled(50.0f);
effects->accel.z = 0.0f;
effects->accel.x = 0.0f;
effects->accel.y = -1.5f;
effects->scale = Rand_ZeroFloat(0.04f) + 0.02f;
effects->rotY = Rand_ZeroFloat(32767.0f);
effects->rotX = Rand_ZeroFloat(32767.0f);
break;
}
}
}
void func_809DA460(Boss02Effects* effects, Vec3f* vec) {
void Boss02_SpawnEffectFlash(TwinmoldEffect* effects, Vec3f* pos) {
s16 i;
for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effects++) {
if ((effects->unk_24 == 0) || (effects->unk_24 == 3)) {
effects->unk_24 = 4;
effects->unk_00 = *vec;
Math_Vec3f_Copy(&effects->unk_0C, &gZeroVec3f);
Math_Vec3f_Copy(&effects->unk_18, &gZeroVec3f);
effects->unk_2C = 0xFF;
effects->unk_34 = 0.0f;
if ((effects->type == TWINMOLD_EFFECT_NONE) || (effects->type == TWINMOLD_EFFECT_FRAGMENT)) {
effects->type = TWINMOLD_EFFECT_FLASH;
effects->pos = *pos;
Math_Vec3f_Copy(&effects->velocity, &gZeroVec3f);
Math_Vec3f_Copy(&effects->accel, &gZeroVec3f);
effects->alpha = 255;
effects->scale = 0.0f;
break;
}
}
@ -949,10 +949,10 @@ void func_809DAB78(Boss02* this, PlayState* play) {
this->unk_0146[0] = 3;
for (i = 0; i < 35; i++) {
func_809DA344(play->specialEffects, &this->unk_147C[this->unk_1678]);
Boss02_SpawnEffectFragment(play->specialEffects, &this->unk_147C[this->unk_1678]);
}
func_809DA460(play->specialEffects, &this->unk_147C[this->unk_1678]);
Boss02_SpawnEffectFlash(play->specialEffects, &this->unk_147C[this->unk_1678]);
play_sound(NA_SE_EV_EXPLOSION);
this->unk_1678--;
@ -1006,7 +1006,7 @@ void func_809DAB78(Boss02* this, PlayState* play) {
play_sound(NA_SE_EV_LIGHTNING);
for (i = 0; i < 30; i++) {
func_809DA344(play->specialEffects, &this->unk_0170);
Boss02_SpawnEffectFragment(play->specialEffects, &this->unk_0170);
}
this->unk_0146[0] = 10;
@ -1206,14 +1206,14 @@ void Boss02_Update(Actor* thisx, PlayState* play) {
sp3C.x = randPlusMinusPoint5Scaled(100.0f * D_809DF5B0) + this->unk_0170.x;
sp3C.y = randPlusMinusPoint5Scaled(50.0f * D_809DF5B0) + this->unk_0170.y;
sp3C.z = randPlusMinusPoint5Scaled(100.0f * D_809DF5B0) + this->unk_0170.z;
func_809DA264(play->specialEffects, &sp3C, Rand_ZeroFloat(3.0f) + 6.0f);
Boss02_SpawnEffectSand(play->specialEffects, &sp3C, Rand_ZeroFloat(3.0f) + 6.0f);
}
if ((this->unk_014C % 2) == 0) {
sp3C.x = randPlusMinusPoint5Scaled(100.0f * D_809DF5B0) + this->unk_0170.x;
sp3C.y = randPlusMinusPoint5Scaled(50.0f * D_809DF5B0) + this->unk_0170.y;
sp3C.z = randPlusMinusPoint5Scaled(100.0f * D_809DF5B0) + this->unk_0170.z;
func_809DA264(play->specialEffects, &sp3C, Rand_ZeroFloat(3.0f) + 6.0f);
Boss02_SpawnEffectSand(play->specialEffects, &sp3C, Rand_ZeroFloat(3.0f) + 6.0f);
}
}
@ -1313,7 +1313,7 @@ void func_809DC78C(Actor* thisx, PlayState* play) {
}
}
func_809DD0CC(play);
Boss02_UpdateEffects(play);
func_809DEAC4(this, play);
func_809DD934(this, play);
}
@ -1463,60 +1463,61 @@ void Boss02_Draw(Actor* thisx, PlayState* play2) {
}
void func_809DD0A8(Actor* thisx, PlayState* play) {
func_809DD2F8(play);
Boss02_DrawEffects(play);
}
void func_809DD0CC(PlayState* play) {
Boss02Effects* effect = (Boss02Effects*)play->specialEffects;
f32 phi_f22;
void Boss02_UpdateEffects(PlayState* play) {
TwinmoldEffect* effect = (TwinmoldEffect*)play->specialEffects;
f32 floorY;
s16 i;
if (D_809E0422 == 0) {
phi_f22 = 0.0f;
floorY = 0.0f;
} else {
phi_f22 = 3150.0f;
floorY = 3150.0f;
}
for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effect++) {
if (effect->unk_24) {
effect->unk_26++;
effect->unk_00.x += effect->unk_0C.x * D_809DF5B0;
effect->unk_00.y += effect->unk_0C.y * D_809DF5B0;
effect->unk_00.z += effect->unk_0C.z * D_809DF5B0;
effect->unk_0C.y += effect->unk_18.y;
if (effect->type) {
effect->timer++;
effect->pos.x += effect->velocity.x * D_809DF5B0;
effect->pos.y += effect->velocity.y * D_809DF5B0;
effect->pos.z += effect->velocity.z * D_809DF5B0;
effect->velocity.y += effect->accel.y;
if (effect->unk_24 < 3) {
Math_ApproachF(&effect->unk_34, effect->unk_38, 0.1f, 0.1f);
if (effect->unk_24 == 2) {
effect->unk_2C -= 18;
if (effect->type < TWINMOLD_EFFECT_FRAGMENT) {
Math_ApproachF(&effect->scale, effect->targetScale, 0.1f, 0.1f);
if (effect->type == TWINMOLD_EFFECT_BLACK_DUST) {
effect->alpha -= 18;
} else {
effect->unk_2C -= 15;
effect->alpha -= 15;
}
if (effect->unk_2C <= 0) {
effect->unk_24 = 0;
if (effect->alpha <= 0) {
effect->type = TWINMOLD_EFFECT_NONE;
}
} else if (effect->unk_24 == 3) {
effect->unk_2E += 0x1000;
effect->unk_30 += 0x1500;
if ((effect->unk_00.y < phi_f22) || (effect->unk_26 > 50)) {
effect->unk_24 = 0;
} else if (effect->type == TWINMOLD_EFFECT_FRAGMENT) {
effect->rotX += 0x1000;
effect->rotY += 0x1500;
if ((effect->pos.y < floorY) || (effect->timer > 50)) {
effect->type = TWINMOLD_EFFECT_NONE;
}
} else if (effect->unk_24 == 4) {
Math_ApproachF(&effect->unk_34, 80.0f, 0.2f, 20.0f);
effect->unk_2C -= 15;
if (effect->unk_2C <= 0) {
effect->unk_24 = 0;
} else if (effect->type == TWINMOLD_EFFECT_FLASH) {
Math_ApproachF(&effect->scale, 80.0f, 0.2f, 20.0f);
effect->alpha -= 15;
if (effect->alpha <= 0) {
effect->type = TWINMOLD_EFFECT_NONE;
}
}
}
}
}
void func_809DD2F8(PlayState* play) {
void Boss02_DrawEffects(PlayState* play) {
u8 flag = false;
Boss02Effects* effect = (Boss02Effects*)play->specialEffects;
TwinmoldEffect* effect = (TwinmoldEffect*)play->specialEffects;
s16 i;
u8 phi_a0;
u8 alpha;
OPEN_DISPS(play->state.gfxCtx);
@ -1524,45 +1525,46 @@ void func_809DD2F8(PlayState* play) {
func_8012C2DC(play->state.gfxCtx);
for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effect++) {
if (effect->unk_24 == 1) {
if (effect->type == TWINMOLD_EFFECT_SAND) {
if (!flag) {
gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL);
gDPSetEnvColor(POLY_XLU_DISP++, 185, 140, 70, 128);
flag++;
}
phi_a0 = effect->unk_2C;
if (effect->unk_2C > 255) {
phi_a0 = 255;
alpha = effect->alpha;
if (effect->alpha > 255) {
alpha = 255;
}
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 185, 140, 70, phi_a0);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 185, 140, 70, alpha);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(play->state.gfxCtx, 0, effect->unk_26 + (i * 3), (effect->unk_26 + (i * 3)) * 5,
Gfx_TwoTexScroll(play->state.gfxCtx, 0, effect->timer + (i * 3), (effect->timer + (i * 3)) * 5,
32, 64, 1, 0, 0, 32, 32));
Matrix_Translate(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW);
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, 1.0f, MTXMODE_APPLY);
Matrix_Scale(effect->scale * D_809DF5B0, effect->scale * D_809DF5B0, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustModelDL);
}
}
effect = (Boss02Effects*)play->specialEffects;
effect = (TwinmoldEffect*)play->specialEffects;
for (i = 0, flag = false; i < ARRAY_COUNT(D_809E0438); i++, effect++) {
if (effect->unk_24 == 3) {
if (effect->type == TWINMOLD_EFFECT_FRAGMENT) {
if (!flag) {
gDPSetCombineLERP(POLY_OPA_DISP++, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE,
0, SHADE, 0, PRIMITIVE, 0);
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x01, 100, 100, 120, 255);
flag++;
}
Matrix_Translate(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW);
Matrix_RotateYS(effect->unk_30, MTXMODE_APPLY);
Matrix_RotateXS(effect->unk_2E, MTXMODE_APPLY);
Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0,
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_RotateYS(effect->rotY, MTXMODE_APPLY);
Matrix_RotateXS(effect->rotX, MTXMODE_APPLY);
Matrix_Scale(effect->scale * D_809DF5B0, effect->scale * D_809DF5B0, effect->scale * D_809DF5B0,
MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
@ -1570,42 +1572,42 @@ void func_809DD2F8(PlayState* play) {
}
}
effect = (Boss02Effects*)play->specialEffects;
effect = (TwinmoldEffect*)play->specialEffects;
for (i = 0, flag = false; i < ARRAY_COUNT(D_809E0438); i++, effect++) {
if (effect->unk_24 == 4) {
if (effect->type == TWINMOLD_EFFECT_FLASH) {
if (!flag) { //! @bug - dev forgot to set flag to 1, should only apply to first entry?
gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL);
gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 128);
}
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)effect->unk_2C);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)effect->alpha);
Matrix_Translate(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW);
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, 1.0f, MTXMODE_APPLY);
Matrix_Scale(effect->scale * D_809DF5B0, effect->scale * D_809DF5B0, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL);
}
}
effect = (Boss02Effects*)play->specialEffects;
effect = (TwinmoldEffect*)play->specialEffects;
for (i = 0, flag = false; i < ARRAY_COUNT(D_809E0438); i++, effect++) {
if (effect->unk_24 == 2) {
if (effect->type == TWINMOLD_EFFECT_BLACK_DUST) {
if (!flag) {
gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL);
gDPSetEnvColor(POLY_XLU_DISP++, 30, 30, 30, 128);
flag++;
}
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 30, 30, 30, (u8)effect->unk_2C);
gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 30, 30, 30, (u8)effect->alpha);
gSPSegment(POLY_XLU_DISP++, 0x08,
Gfx_TwoTexScroll(play->state.gfxCtx, 0, effect->unk_26 + (i * 3), (effect->unk_26 + (i * 3)) * 5,
Gfx_TwoTexScroll(play->state.gfxCtx, 0, effect->timer + (i * 3), (effect->timer + (i * 3)) * 5,
32, 64, 1, 0, 0, 32, 32));
Matrix_Translate(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW);
Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW);
Matrix_ReplaceRotation(&play->billboardMtxF);
Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, 1.0f, MTXMODE_APPLY);
Matrix_Scale(effect->scale * D_809DF5B0, effect->scale * D_809DF5B0, 1.0f, MTXMODE_APPLY);
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustModelDL);

View File

@ -9,18 +9,26 @@ struct Boss02;
typedef void (*Boss02ActionFunc)(struct Boss02*, PlayState*);
typedef struct {
/* 0x00 */ Vec3f unk_00;
/* 0x0C */ Vec3f unk_0C;
/* 0x18 */ Vec3f unk_18;
/* 0x24 */ u8 unk_24;
/* 0x26 */ s16 unk_26;
/* 0x00 */ Vec3f pos;
/* 0x0C */ Vec3f velocity;
/* 0x18 */ Vec3f accel;
/* 0x24 */ u8 type;
/* 0x26 */ s16 timer;
/* 0x28 */ UNK_TYPE1 unk_28[0x4];
/* 0x2C */ s16 unk_2C;
/* 0x2E */ s16 unk_2E;
/* 0x30 */ s16 unk_30;
/* 0x34 */ f32 unk_34;
/* 0x38 */ f32 unk_38;
} Boss02Effects; // size = 0x3C
/* 0x2C */ s16 alpha;
/* 0x2E */ s16 rotX;
/* 0x30 */ s16 rotY;
/* 0x34 */ f32 scale;
/* 0x38 */ f32 targetScale;
} TwinmoldEffect; // size = 0x3C
typedef enum {
/* 0 */ TWINMOLD_EFFECT_NONE,
/* 1 */ TWINMOLD_EFFECT_SAND, // The sand kicked up when Twinmold touches the ground
/* 2 */ TWINMOLD_EFFECT_BLACK_DUST, // Unused
/* 3 */ TWINMOLD_EFFECT_FRAGMENT, // The fragments that fly off when the parts of Twinmold explode
/* 4 */ TWINMOLD_EFFECT_FLASH, // The flashes of light that appear when the parts of Twinmold explode
} TwinmoldEffectType;
typedef struct Boss02 {
/* 0x0000 */ Actor actor;

View File

@ -9295,9 +9295,9 @@
0x809DA1D0:("func_809DA1D0",),
0x809DA22C:("func_809DA22C",),
0x809DA24C:("func_809DA24C",),
0x809DA264:("func_809DA264",),
0x809DA344:("func_809DA344",),
0x809DA460:("func_809DA460",),
0x809DA264:("Boss02_SpawnEffectSand",),
0x809DA344:("Boss02_SpawnEffectFragment",),
0x809DA460:("Boss02_SpawnEffectFlash",),
0x809DA50C:("func_809DA50C",),
0x809DA5AC:("Boss02_Init",),
0x809DAA64:("Boss02_Destroy",),
@ -9311,8 +9311,8 @@
0x809DC78C:("func_809DC78C",),
0x809DCA00:("Boss02_Draw",),
0x809DD0A8:("func_809DD0A8",),
0x809DD0CC:("func_809DD0CC",),
0x809DD2F8:("func_809DD2F8",),
0x809DD0CC:("Boss02_UpdateEffects",),
0x809DD2F8:("Boss02_DrawEffects",),
0x809DD934:("func_809DD934",),
0x809DEAC4:("func_809DEAC4",),
0x809E2760:("Boss03_PlayUnderwaterSfx",),