mirror of
https://github.com/zeldaret/oot.git
synced 2025-08-06 06:10:21 +00:00
ovl_En_Siofuki (#456)
* ovl_En_Siofuki * PR review * Rebase * PR review
This commit is contained in:
parent
84a0acc9cf
commit
0453c7d3cf
17 changed files with 307 additions and 961 deletions
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* File: z_en_siofuki.c
|
||||
* Overlay: ovl_En_Siofuki
|
||||
* Description: Water Spout
|
||||
*/
|
||||
|
||||
#include "z_en_siofuki.h"
|
||||
|
||||
#define FLAGS 0x00000030
|
||||
|
@ -9,7 +15,10 @@ void EnSiofuki_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
|||
void EnSiofuki_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnSiofuki_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
/*
|
||||
void func_80AFC34C(EnSiofuki* this, GlobalContext* globalCtx);
|
||||
void func_80AFC544(EnSiofuki* this, GlobalContext* globalCtx);
|
||||
void func_80AFC478(EnSiofuki* this, GlobalContext* globalCtx);
|
||||
|
||||
const ActorInit En_Siofuki_InitVars = {
|
||||
ACTOR_EN_SIOFUKI,
|
||||
ACTORTYPE_BG,
|
||||
|
@ -21,27 +30,286 @@ const ActorInit En_Siofuki_InitVars = {
|
|||
(ActorFunc)EnSiofuki_Update,
|
||||
(ActorFunc)EnSiofuki_Draw,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/EnSiofuki_Init.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/EnSiofuki_Destroy.s")
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/func_80AFBDC8.s")
|
||||
extern Gfx D_06000B70[];
|
||||
extern UNK_TYPE D_06000D78;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/func_80AFBE8C.s")
|
||||
void EnSiofuki_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnSiofuki* this = THIS;
|
||||
s32 type;
|
||||
ColHeader* colHeader = NULL;
|
||||
s32 pad;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/func_80AFC1D0.s")
|
||||
if ((thisx->room == 10) && Flags_GetSwitch(globalCtx, 0x1E)) {
|
||||
Actor_Kill(thisx);
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/func_80AFC218.s")
|
||||
Actor_ProcessInitChain(thisx, sInitChain);
|
||||
DynaPolyInfo_SetActorMove(&this->dyna, DPM_PLAYER);
|
||||
DynaPolyInfo_Alloc(&D_06000D78, &colHeader);
|
||||
this->dyna.dynaPolyId = DynaPolyInfo_RegisterActor(globalCtx, &globalCtx->colCtx.dyna, thisx, colHeader);
|
||||
this->sfxFlags |= 1;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/func_80AFC34C.s")
|
||||
type = ((u16)thisx->params >> 0xC) & 0xF;
|
||||
if (!((type == 0) || (type == 1))) {
|
||||
Actor_Kill(thisx);
|
||||
return;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/func_80AFC3C8.s")
|
||||
this->initPosY = thisx->posRot.pos.y;
|
||||
this->unk_174 = 35.0f;
|
||||
this->unk_170 = -6058.0f + this->unk_174;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/func_80AFC478.s")
|
||||
if (thisx->shape.rot.x != 0) {
|
||||
this->maxHeight = thisx->shape.rot.x * 40.0f;
|
||||
this->currentHeight = this->maxHeight;
|
||||
}
|
||||
this->activeTime = 0;
|
||||
if (thisx->shape.rot.y != 0) {
|
||||
this->activeTime = thisx->shape.rot.y;
|
||||
}
|
||||
if (thisx->shape.rot.z != 0) {
|
||||
thisx->scale.x = thisx->shape.rot.z * (1.0f / 1.73f) * 0.1f;
|
||||
thisx->scale.z = thisx->shape.rot.z * 0.5f * 0.1f;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/func_80AFC544.s")
|
||||
thisx->posRot.rot.x = 0;
|
||||
thisx->posRot.rot.y = 0;
|
||||
thisx->posRot.rot.z = 0;
|
||||
thisx->shape.rot.x = 0;
|
||||
thisx->shape.rot.y = 0;
|
||||
thisx->shape.rot.z = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/EnSiofuki_Update.s")
|
||||
type = ((u16)thisx->params >> 0xC) & 0xF;
|
||||
if (type == EN_SIOFUKI_RAISING) {
|
||||
this->currentHeight = 10.0f;
|
||||
this->targetHeight = 10.0f;
|
||||
this->actionFunc = func_80AFC34C;
|
||||
} else if (type == EN_SIOFUKI_LOWERING) {
|
||||
if (Flags_GetTreasure(globalCtx, (u16)thisx->params & 0x3F)) {
|
||||
this->currentHeight = -45.0f;
|
||||
this->targetHeight = -45.0f;
|
||||
this->actionFunc = func_80AFC544;
|
||||
} else {
|
||||
this->targetHeight = this->currentHeight;
|
||||
this->actionFunc = func_80AFC478;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Siofuki/EnSiofuki_Draw.s")
|
||||
void EnSiofuki_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnSiofuki* this = THIS;
|
||||
|
||||
DynaPolyInfo_Free(globalCtx, &globalCtx->colCtx.dyna, this->dyna.dynaPolyId);
|
||||
}
|
||||
|
||||
void func_80AFBDC8(EnSiofuki* this, GlobalContext* globalCtx) {
|
||||
this->oscillation = sinf((globalCtx->gameplayFrames & 0x1F) / 32.0f * M_PI * 2.0f) * 4.0f;
|
||||
this->unk_170 = this->unk_174 * 10.0f + -6058.0f - this->oscillation * 10.0f;
|
||||
this->unk_174 = 35.0f;
|
||||
this->dyna.actor.posRot.pos.y = this->initPosY + this->currentHeight + this->oscillation;
|
||||
}
|
||||
|
||||
void func_80AFBE8C(EnSiofuki* this, GlobalContext* globalCtx) {
|
||||
Player* player = PLAYER;
|
||||
f32 dX;
|
||||
f32 dY;
|
||||
f32 dZ;
|
||||
s16 angle;
|
||||
s16 dAngle;
|
||||
f32 dist2d;
|
||||
f32 speedScale;
|
||||
|
||||
dX = player->actor.posRot.pos.x - this->dyna.actor.posRot.pos.x;
|
||||
dY = player->actor.posRot.pos.y - this->dyna.actor.posRot.pos.y;
|
||||
dZ = player->actor.posRot.pos.z - this->dyna.actor.posRot.pos.z;
|
||||
|
||||
if ((dX > (this->dyna.actor.scale.x * -346.0f)) && (dX < (this->dyna.actor.scale.x * 346.0f)) &&
|
||||
(dZ > (this->dyna.actor.scale.z * -400.0f)) && (dZ < (this->dyna.actor.scale.z * 400.0f)) && (dY < 0.0f)) {
|
||||
if (func_8004356C(&this->dyna)) {
|
||||
if (this->splashTimer <= 0) {
|
||||
EffectSsGSplash_Spawn(globalCtx, &player->actor.posRot.pos, NULL, NULL, 1, 1);
|
||||
this->splashTimer = 10;
|
||||
} else {
|
||||
this->splashTimer--;
|
||||
}
|
||||
|
||||
this->applySpeed = false;
|
||||
this->appliedSpeed = 0.0f;
|
||||
this->targetAppliedSpeed = 0.0f;
|
||||
} else {
|
||||
dist2d = sqrtf(SQ(dX) + SQ(dZ));
|
||||
this->applySpeed = true;
|
||||
this->splashTimer = 0;
|
||||
angle = Math_atan2f(dX, dZ) * (0x8000 / M_PI);
|
||||
dAngle = (player->actor.posRot.rot.y ^ 0x8000) - angle;
|
||||
player->actor.gravity = 0.0f;
|
||||
player->actor.velocity.y = 0.0f;
|
||||
Math_SmoothScaleMaxMinF(&player->actor.posRot.pos.y, this->dyna.actor.posRot.pos.y, 0.5f, 4.0f, 1.0f);
|
||||
|
||||
if ((dAngle < 0x4000) && (dAngle > -0x4000)) {
|
||||
this->appliedYaw = player->actor.posRot.rot.y ^ 0x8000;
|
||||
speedScale = dist2d / (this->dyna.actor.scale.x * 40.0f * 10.0f);
|
||||
speedScale = CLAMP_MIN(speedScale, 0.0f);
|
||||
speedScale = CLAMP_MAX(speedScale, 1.0f);
|
||||
player->linearVelocity *= speedScale;
|
||||
Math_SmoothScaleMaxF(&this->targetAppliedSpeed, 3.0f, 1.0f, 1.0f);
|
||||
Math_SmoothScaleMaxF(&this->appliedSpeed, this->targetAppliedSpeed, 1.0f, 0.3f * speedScale);
|
||||
} else {
|
||||
this->appliedYaw = player->actor.posRot.rot.y;
|
||||
player->linearVelocity /= 2.0f;
|
||||
Math_SmoothScaleMaxF(&this->targetAppliedSpeed, 3.0f, 1.0f, 1.0f);
|
||||
Math_SmoothScaleMaxF(&this->appliedSpeed, this->targetAppliedSpeed, 1.0f, 0.1f);
|
||||
}
|
||||
|
||||
player->windDirection = this->appliedYaw;
|
||||
player->windSpeed = this->appliedSpeed;
|
||||
}
|
||||
} else {
|
||||
if (this->applySpeed) {
|
||||
player->linearVelocity = this->appliedSpeed + player->linearVelocity;
|
||||
player->currentYaw = this->appliedYaw;
|
||||
}
|
||||
|
||||
this->targetAppliedSpeed = 0.0f;
|
||||
this->appliedSpeed = 0.0f;
|
||||
this->applySpeed = false;
|
||||
}
|
||||
}
|
||||
|
||||
void func_80AFC1D0(EnSiofuki* this, GlobalContext* globalCtx) {
|
||||
Math_SmoothScaleMaxMinF(&this->currentHeight, this->targetHeight, 0.8f, 3.0f, 0.01f);
|
||||
}
|
||||
|
||||
void func_80AFC218(EnSiofuki* this, GlobalContext* globalCtx) {
|
||||
func_80AFBDC8(this, globalCtx);
|
||||
func_80AFBE8C(this, globalCtx);
|
||||
func_80AFC1D0(this, globalCtx);
|
||||
|
||||
this->timer--;
|
||||
if (this->timer < 0) {
|
||||
Flags_UnsetSwitch(globalCtx, ((u16)this->dyna.actor.params >> 6) & 0x3F);
|
||||
switch (((u16)this->dyna.actor.params >> 0xC) & 0xF) {
|
||||
case EN_SIOFUKI_RAISING:
|
||||
this->targetHeight = 10.0f;
|
||||
this->actionFunc = func_80AFC34C;
|
||||
break;
|
||||
case EN_SIOFUKI_LOWERING:
|
||||
this->targetHeight = this->maxHeight;
|
||||
this->actionFunc = func_80AFC478;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
func_8002F994(&this->dyna.actor, this->timer);
|
||||
}
|
||||
|
||||
if (((((u16)this->dyna.actor.params >> 0xC) & 0xF) == EN_SIOFUKI_LOWERING) &&
|
||||
Flags_GetTreasure(globalCtx, (u16)this->dyna.actor.params & 0x3F)) {
|
||||
this->currentHeight = -45.0f;
|
||||
this->targetHeight = -45.0f;
|
||||
Flags_UnsetSwitch(globalCtx, ((u16)this->dyna.actor.params >> 6) & 0x3F);
|
||||
this->actionFunc = func_80AFC544;
|
||||
}
|
||||
}
|
||||
|
||||
void func_80AFC34C(EnSiofuki* this, GlobalContext* globalCtx) {
|
||||
func_80AFBDC8(this, globalCtx);
|
||||
func_80AFBE8C(this, globalCtx);
|
||||
func_80AFC1D0(this, globalCtx);
|
||||
|
||||
if (Flags_GetSwitch(globalCtx, ((u16)this->dyna.actor.params >> 6) & 0x3F)) {
|
||||
this->targetHeight = 400.0f;
|
||||
this->timer = 300;
|
||||
this->actionFunc = func_80AFC218;
|
||||
}
|
||||
}
|
||||
|
||||
void func_80AFC3C8(EnSiofuki* this, GlobalContext* globalCtx) {
|
||||
func_80AFBDC8(this, globalCtx);
|
||||
func_80AFBE8C(this, globalCtx);
|
||||
func_80AFC1D0(this, globalCtx);
|
||||
|
||||
this->timer--;
|
||||
if (this->timer < 0) {
|
||||
this->timer = this->activeTime * 20;
|
||||
this->targetHeight = -45.0f;
|
||||
this->actionFunc = func_80AFC218;
|
||||
}
|
||||
|
||||
if (Flags_GetTreasure(globalCtx, (u16)this->dyna.actor.params & 0x3F)) {
|
||||
this->currentHeight = -45.0f;
|
||||
this->targetHeight = -45.0f;
|
||||
this->actionFunc = func_80AFC544;
|
||||
}
|
||||
}
|
||||
|
||||
void func_80AFC478(EnSiofuki* this, GlobalContext* globalCtx) {
|
||||
func_80AFBDC8(this, globalCtx);
|
||||
func_80AFBE8C(this, globalCtx);
|
||||
func_80AFC1D0(this, globalCtx);
|
||||
|
||||
if (((u16)this->dyna.actor.params >> 0xC & 0xF) == EN_SIOFUKI_LOWERING) {
|
||||
if (Flags_GetSwitch(globalCtx, ((u16)this->dyna.actor.params >> 6) & 0x3F)) {
|
||||
this->timer = 20;
|
||||
this->actionFunc = func_80AFC3C8;
|
||||
func_800800F8(globalCtx, 0x1392, 0x28, &this->dyna.actor, 0);
|
||||
}
|
||||
|
||||
if (Flags_GetTreasure(globalCtx, (u16)this->dyna.actor.params & 0x3F)) {
|
||||
this->currentHeight = -45.0f;
|
||||
this->targetHeight = -45.0f;
|
||||
this->actionFunc = func_80AFC544;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_80AFC544(EnSiofuki* this, GlobalContext* globalCtx) {
|
||||
func_80AFBDC8(this, globalCtx);
|
||||
func_80AFC1D0(this, globalCtx);
|
||||
}
|
||||
|
||||
void EnSiofuki_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnSiofuki* this = THIS;
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
}
|
||||
|
||||
void EnSiofuki_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
EnSiofuki* this = THIS;
|
||||
u32 x;
|
||||
u32 y;
|
||||
u32 gameplayFrames = globalCtx->gameplayFrames;
|
||||
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_siofuki.c", 654);
|
||||
func_80093D84(globalCtx->state.gfxCtx);
|
||||
Matrix_Translate(0.0f, this->unk_170, 0.0f, MTXMODE_APPLY);
|
||||
Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx, "../z_en_siofuki.c", 662),
|
||||
G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
x = gameplayFrames * 15;
|
||||
y = gameplayFrames * -15;
|
||||
gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, x, y, 64, 64, 1, x, y, 64, 64));
|
||||
gSPDisplayList(POLY_XLU_DISP++, D_06000B70);
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_siofuki.c", 674);
|
||||
|
||||
if (this->sfxFlags & 1) {
|
||||
f32 heightRatio;
|
||||
switch (((u16)thisx->params >> 0xC) & 0xF) {
|
||||
case EN_SIOFUKI_RAISING:
|
||||
heightRatio = (this->currentHeight - 10.0f) / (400.0f - 10.0f);
|
||||
func_800F436C(&thisx->projectedPos, NA_SE_EV_FOUNTAIN - SFX_FLAG, 1.0f + heightRatio);
|
||||
break;
|
||||
case EN_SIOFUKI_LOWERING:
|
||||
if (this->currentHeight > -35.0f) {
|
||||
heightRatio = (this->currentHeight - -35.0f) / (this->maxHeight - -35.0f);
|
||||
func_800F436C(&thisx->projectedPos, NA_SE_EV_FOUNTAIN - SFX_FLAG, 1.0f + heightRatio);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,33 @@
|
|||
#include "ultra64.h"
|
||||
#include "global.h"
|
||||
|
||||
typedef enum {
|
||||
/* 0x00 */ EN_SIOFUKI_RAISING,
|
||||
/* 0x01 */ EN_SIOFUKI_LOWERING
|
||||
} EnSiofukiType;
|
||||
|
||||
struct EnSiofuki;
|
||||
|
||||
typedef void (*EnSiofukiActionFunc)(struct EnSiofuki*, GlobalContext*);
|
||||
|
||||
typedef struct EnSiofuki {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x54];
|
||||
/* 0x0000 */ DynaPolyActor dyna;
|
||||
/* 0x0164 */ EnSiofukiActionFunc actionFunc;
|
||||
/* 0x0168 */ s32 timer;
|
||||
/* 0x016C */ f32 initPosY;
|
||||
/* 0x0170 */ f32 unk_170;
|
||||
/* 0x0174 */ f32 unk_174;
|
||||
/* 0x0178 */ f32 oscillation;
|
||||
/* 0x017C */ f32 targetHeight;
|
||||
/* 0x0180 */ f32 currentHeight;
|
||||
/* 0x0184 */ s32 splashTimer;
|
||||
/* 0x0188 */ s32 applySpeed;
|
||||
/* 0x018C */ f32 appliedSpeed;
|
||||
/* 0x0190 */ f32 targetAppliedSpeed;
|
||||
/* 0x0194 */ s16 appliedYaw;
|
||||
/* 0x0196 */ s16 activeTime;
|
||||
/* 0x0198 */ f32 maxHeight;
|
||||
/* 0x019C */ u8 sfxFlags;
|
||||
} EnSiofuki; // size = 0x01A0
|
||||
|
||||
extern const ActorInit En_Siofuki_InitVars;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue