diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml
index 935cec70fc..96a5fa1d7b 100644
--- a/assets/xml/objects/gameplay_keep.xml
+++ b/assets/xml/objects/gameplay_keep.xml
@@ -1345,9 +1345,9 @@
-
-
-
+
+
+
diff --git a/include/functions.h b/include/functions.h
index 285ef524ba..6c5b1333de 100644
--- a/include/functions.h
+++ b/include/functions.h
@@ -568,7 +568,7 @@ void EffectSsEnIce_Spawn(PlayState* play, Vec3f* pos, f32 scale, Vec3f* velocity
// void EffectSsFireTail_Spawn(UNK_TYPE4 uParm1, UNK_TYPE4 uParm2, Vec3f* pzParm3, UNK_TYPE4 uParm4, Vec3f* param_5, UNK_TYPE2 param_6, Color_RGBA8* param_7, Color_RGBA8* param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10, UNK_TYPE4 param_11);
// void EffectSsFireTail_SpawnFlame(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE4 param_6);
// void EffectSsFireTail_SpawnFlameOnPlayer(void);
-void EffectSsEnFire_SpawnVec3f(PlayState* play, Actor* actor, Vec3f* pos, s16 scale, s16 arg4, s16 flags, s16 bodyPart);
+void EffectSsEnFire_SpawnVec3f(PlayState* play, Actor* actor, Vec3f* pos, s16 scale, s16 params, s16 flags, s16 bodyPart);
// void EffectSsEnFire_SpawnVec3s(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7);
void EffectSsExtra_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scoreIdx);
void EffectSsDeadDb_Spawn(PlayState* play, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* prim, Color_RGBA8* env, s16 scale, s16 scaleStep, s32 unk);
diff --git a/spec b/spec
index 7d6c6f5b03..56aa7c21d8 100644
--- a/spec
+++ b/spec
@@ -1922,8 +1922,7 @@ beginseg
name "ovl_Effect_Ss_En_Fire"
compress
include "build/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.o"
- include "build/data/ovl_Effect_Ss_En_Fire/ovl_Effect_Ss_En_Fire.data.o"
- include "build/data/ovl_Effect_Ss_En_Fire/ovl_Effect_Ss_En_Fire.reloc.o"
+ include "build/src/overlays/effects/ovl_Effect_Ss_En_Fire/ovl_Effect_Ss_En_Fire_reloc.o"
endseg
beginseg
diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c
index 7a56a6732a..b28e50364d 100644
--- a/src/code/z_effect_soft_sprite_old_init.c
+++ b/src/code/z_effect_soft_sprite_old_init.c
@@ -872,14 +872,14 @@ void EffectSsFireTail_SpawnFlameOnPlayer(PlayState* play, f32 scale, s16 bodyPar
// EffectSsEnFire Spawn Functions
-void EffectSsEnFire_SpawnVec3f(PlayState* play, Actor* actor, Vec3f* pos, s16 scale, s16 arg4, s16 flags,
+void EffectSsEnFire_SpawnVec3f(PlayState* play, Actor* actor, Vec3f* pos, s16 scale, s16 params, s16 flags,
s16 bodyPart) {
EffectSsEnFireInitParams initParams;
Math_Vec3f_Copy(&initParams.pos, pos);
initParams.actor = actor;
initParams.scale = scale;
- initParams.unk_12 = arg4;
+ initParams.params = params;
initParams.flags = flags;
initParams.bodyPart = bodyPart;
@@ -890,7 +890,7 @@ void EffectSsEnFire_SpawnVec3f(PlayState* play, Actor* actor, Vec3f* pos, s16 sc
EffectSs_Spawn(play, EFFECT_SS_EN_FIRE, 128, &initParams);
}
-void EffectSsEnFire_SpawnVec3s(PlayState* play, Actor* actor, Vec3s* pos, s16 scale, s16 arg4, s16 flags,
+void EffectSsEnFire_SpawnVec3s(PlayState* play, Actor* actor, Vec3s* pos, s16 scale, s16 params, s16 flags,
s16 bodyPart) {
EffectSsEnFireInitParams initParams;
@@ -899,8 +899,8 @@ void EffectSsEnFire_SpawnVec3s(PlayState* play, Actor* actor, Vec3s* pos, s16 sc
initParams.pos.z = pos->z;
initParams.actor = actor;
initParams.scale = scale;
- initParams.unk_12 = arg4;
- initParams.flags = flags | 0x8000;
+ initParams.params = params;
+ initParams.flags = flags | ENFIRE_FLAGS_BODYPART_POS_VEC3S;
initParams.bodyPart = bodyPart;
if (actor != NULL) {
diff --git a/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c b/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c
index 49448b32ec..fab6f87880 100644
--- a/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c
+++ b/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.c
@@ -5,23 +5,144 @@
*/
#include "z_eff_ss_en_fire.h"
+#include "objects/gameplay_keep/gameplay_keep.h"
+
+#define rScaleMax regs[0]
+#define rScale regs[1]
+#define rLifespan regs[2]
+#define rUnused regs[3]
+#define rPitch regs[4]
+#define rYaw regs[5]
+#define rReg6 regs[6]
+#define rBodyPart regs[7]
+#define rFlags regs[8]
+#define rScroll regs[9]
#define PARAMS ((EffectSsEnFireInitParams*)initParamsx)
-s32 EffectSsEnFire_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx);
+u32 EffectSsEnFire_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx);
void EffectSsEnFire_Update(PlayState* play, u32 index, EffectSs* this);
void EffectSsEnFire_Draw(PlayState* play, u32 index, EffectSs* this);
-#if 0
const EffectSsInit Effect_Ss_En_Fire_InitVars = {
EFFECT_SS_EN_FIRE,
EffectSsEnFire_Init,
};
-#endif
+u32 EffectSsEnFire_Init(PlayState* play, u32 index, EffectSs* this, void* initParamsx) {
+ EffectSsEnFireInitParams* initParams = PARAMS;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_En_Fire/EffectSsEnFire_Init.s")
+ Math_Vec3f_Copy(&this->pos, &initParams->pos);
+ Math_Vec3f_Copy(&this->velocity, &gZeroVec3f);
+ Math_Vec3f_Copy(&this->accel, &gZeroVec3f);
+ this->life = 20;
+ this->rLifespan = this->life;
+ this->actor = initParams->actor;
+ this->rScroll = Rand_ZeroOne() * 20.0f;
+ this->draw = EffectSsEnFire_Draw;
+ this->update = EffectSsEnFire_Update;
+ this->rUnused = -15;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_En_Fire/EffectSsEnFire_Draw.s")
+ if (initParams->bodyPart < 0) {
+ this->rYaw = Math_Vec3f_Yaw(&initParams->actor->world.pos, &initParams->pos) - initParams->actor->shape.rot.y;
+ this->rPitch =
+ Math_Vec3f_Pitch(&initParams->actor->world.pos, &initParams->pos) - initParams->actor->shape.rot.x;
+ this->vec.z = Math_Vec3f_DistXYZ(&initParams->pos, &initParams->actor->world.pos);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_En_Fire/EffectSsEnFire_Update.s")
+ this->rScaleMax = initParams->scale;
+
+ if (initParams->params & ENFIRE_PARAMS_USE_SCALE) {
+ this->rScale = initParams->scale;
+ } else {
+ this->rScale = 0;
+ }
+
+ this->rReg6 = initParams->params & 0x7FFF;
+ this->rBodyPart = initParams->bodyPart;
+ this->rFlags = initParams->flags;
+
+ return 1;
+}
+
+void EffectSsEnFire_Draw(PlayState* play, u32 index, EffectSs* this) {
+ GraphicsContext* gfxCtx = play->state.gfxCtx;
+ f32 scale;
+ s16 camYaw;
+ s32 pad[3];
+ s16 redGreen;
+
+ OPEN_DISPS(gfxCtx);
+
+ Matrix_Translate(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW);
+ camYaw = (Camera_GetCamDirYaw(GET_ACTIVE_CAM(play)) + 0x8000);
+ Matrix_RotateYS(camYaw, MTXMODE_APPLY);
+
+ scale = Math_SinS(this->life * 0x333) * (this->rScale * 0.00005f);
+ Matrix_Scale(scale, scale, scale, MTXMODE_APPLY);
+ gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+
+ redGreen = this->life - 5;
+
+ if (redGreen < 0) {
+ redGreen = 0;
+ }
+
+ func_8012C2DC(play->state.gfxCtx);
+ gDPSetEnvColor(POLY_XLU_DISP++, redGreen * 12.7f, 0, 0, 0);
+ gDPSetPrimColor(POLY_XLU_DISP++, 0x0, 0x80, redGreen * 12.7f, redGreen * 12.7f, 0, 255);
+ gSPSegment(
+ POLY_XLU_DISP++, 0x08,
+ Gfx_TwoTexScroll(play->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (this->rScroll * -20) & 0x1FF, 0x20, 0x80));
+
+ if ((this->rFlags & 0x7FFF) || (this->life < 18)) {
+ gSPDisplayList(POLY_XLU_DISP++, gEffFire2DL);
+ } else {
+ gSPDisplayList(POLY_XLU_DISP++, gEffFire1DL);
+ }
+
+ CLOSE_DISPS(gfxCtx);
+}
+
+typedef struct {
+ /* 0x000 */ Actor actor;
+ /* 0x14C */ Vec3f firePos[10];
+} FireActorF; // size = 0x1BC
+
+typedef struct {
+ /* 0x000 */ Actor actor;
+ /* 0x14C */ Vec3s firePos[10];
+} FireActorS; // size = 0x180
+
+void EffectSsEnFire_Update(PlayState* play, u32 index, EffectSs* this) {
+ this->rScroll++;
+
+ if (this->actor != NULL) {
+ if (this->actor->colorFilterTimer >= 22) {
+ this->life++;
+ }
+ if (this->actor->update != NULL) {
+ Math_SmoothStepToS(&this->rScale, this->rScaleMax, 1, this->rScaleMax >> 3, 0);
+
+ if (this->rBodyPart < 0) {
+ Matrix_Translate(this->actor->world.pos.x, this->actor->world.pos.y, this->actor->world.pos.z,
+ MTXMODE_NEW);
+ Matrix_RotateYS(this->rYaw + this->actor->shape.rot.y, MTXMODE_APPLY);
+ Matrix_RotateXS(this->rPitch + this->actor->shape.rot.x, MTXMODE_APPLY);
+ Matrix_MultVec3f(&this->vec, &this->pos);
+ } else if (this->rFlags & ENFIRE_FLAGS_BODYPART_POS_VEC3S) {
+ this->pos.x = ((FireActorS*)this->actor)->firePos[this->rBodyPart].x;
+ this->pos.y = ((FireActorS*)this->actor)->firePos[this->rBodyPart].y;
+ this->pos.z = ((FireActorS*)this->actor)->firePos[this->rBodyPart].z;
+ } else {
+ this->pos.x = ((FireActorF*)this->actor)->firePos[this->rBodyPart].x;
+ this->pos.y = ((FireActorF*)this->actor)->firePos[this->rBodyPart].y;
+ this->pos.z = ((FireActorF*)this->actor)->firePos[this->rBodyPart].z;
+ }
+ } else if (this->rReg6 != 0) {
+ this->life = 0;
+ } else {
+ this->actor = NULL;
+ }
+ }
+}
diff --git a/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.h b/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.h
index 987e426dad..9fb9598249 100644
--- a/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.h
+++ b/src/overlays/effects/ovl_Effect_Ss_En_Fire/z_eff_ss_en_fire.h
@@ -3,11 +3,14 @@
#include "global.h"
+#define ENFIRE_FLAGS_BODYPART_POS_VEC3S (1 << 15)
+#define ENFIRE_PARAMS_USE_SCALE (1 << 15)
+
typedef struct {
/* 0x00 */ Actor* actor;
/* 0x04 */ Vec3f pos;
/* 0x10 */ s16 scale;
- /* 0x12 */ s16 unk_12;
+ /* 0x12 */ s16 params;
/* 0x14 */ s16 flags;
/* 0x16 */ s16 bodyPart;
} EffectSsEnFireInitParams; // size = 0x18