diff --git a/spec b/spec index 8a587b0c03..158cca3711 100644 --- a/spec +++ b/spec @@ -3595,8 +3595,7 @@ beginseg name "ovl_En_Elfbub" compress include "build/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.o" - include "build/data/ovl_En_Elfbub/ovl_En_Elfbub.data.o" - include "build/data/ovl_En_Elfbub/ovl_En_Elfbub.reloc.o" + include "build/src/overlays/actors/ovl_En_Elfbub/ovl_En_Elfbub_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c index 954e5fa066..7d492ac1d4 100644 --- a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c +++ b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c @@ -1,3 +1,9 @@ +/* + * File: z_en_elfbub.c + * Overlay: ovl_En_Elfbub + * Description: Stray fairy in bubble + */ + #include "z_en_elfbub.h" #define FLAGS 0x00000001 @@ -9,7 +15,9 @@ void EnElfbub_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnElfbub_Update(Actor* thisx, GlobalContext* globalCtx); void EnElfbub_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnElfbub_Pop(EnElfbub* this, GlobalContext* globalCtx); +void EnElfbub_Idle(EnElfbub* this, GlobalContext* globalCtx); + const ActorInit En_Elfbub_InitVars = { ACTOR_EN_ELFBUB, ACTORCAT_MISC, @@ -22,27 +30,138 @@ const ActorInit En_Elfbub_InitVars = { (ActorFunc)EnElfbub_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80ACE270 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 16, 32, 0, { 0, 0, 0 } }, }; -#endif +extern Gfx D_06001000[]; -extern ColliderCylinderInit D_80ACE270; +void EnElfbub_Init(Actor* thisx, GlobalContext* globalCtx) { + EnElfbub* this = THIS; + Actor* childActor; -extern UNK_TYPE D_06001000; + if (Flags_GetSwitch(globalCtx, ENELFBUB_GET_SWITCHFLAG(&this->actor))) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfbub/EnElfbub_Init.s") + ActorShape_Init(&this->actor.shape, 16.0f, func_800B3FC0, 0.2f); + this->actor.hintId = 0x16; + Actor_SetScale(&this->actor, 1.25f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfbub/EnElfbub_Destroy.s") + this->actionFunc = EnElfbub_Idle; + this->zRot = randPlusMinusPoint5Scaled(0x10000); + this->zRotDelta = 1000; + this->xScale = 0.08f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfbub/func_80ACDE60.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfbub/func_80ACE030.s") + childActor = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_ELFORG, + this->actor.world.pos.x, this->actor.world.pos.y + 12.0f, this->actor.world.pos.z, + this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, + ((ENELFBUB_GET_SWITCHFLAG(&this->actor) & 0x7F) << 9) | 2); + if (childActor != NULL) { + childActor->parent = &this->actor; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfbub/EnElfbub_Update.s") + this->oscillationAngle = 0; + this->actor.flags &= ~1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfbub/EnElfbub_Draw.s") +void EnElfbub_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnElfbub* this = THIS; + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnElfbub_Pop(EnElfbub* this, GlobalContext* globalCtx) { + static Color_RGBA8 sPrimColor = { 255, 255, 255, 255 }; + static Color_RGBA8 sEnvColor = { 150, 150, 150, 0 }; + static Vec3f sAccel = { 0.0f, -0.5f, 0.0f }; + s32 effectCounter; + Vec3f velocity; + Vec3f pos; + + Math_SmoothStepToF(&this->xyScale, 3.0f, 0.1f, 1000.0f, 0.0f); + Math_SmoothStepToF(&this->xScale, 0.2f, 0.1f, 1000.0f, 0.0f); + this->zRotDelta += 1000; + this->zRot += this->zRotDelta; + this->popTimer--; + if (this->popTimer <= 0) { + pos.x = this->actor.world.pos.x; + pos.y = this->actor.world.pos.y; + pos.z = this->actor.world.pos.z; + + for (effectCounter = 0; effectCounter < 20; effectCounter++) { + velocity.x = (Rand_ZeroOne() - 0.5f) * 7.0f; + velocity.y = Rand_ZeroOne() * 7.0f; + velocity.z = (Rand_ZeroOne() - 0.5f) * 7.0f; + EffectSsDtBubble_SpawnCustomColor(globalCtx, &pos, &velocity, &sAccel, &sPrimColor, &sEnvColor, + Rand_S16Offset(100, 50), 25, 0); + } + + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 60, NA_SE_EN_AWA_BREAK); + Actor_MarkForDeath(&this->actor); + } +} + +void EnElfbub_Idle(EnElfbub* this, GlobalContext* globalCtx) { + s32 pad; + + this->zRot += this->zRotDelta; + this->actor.world.pos.y += Math_SinS(this->oscillationAngle); + this->oscillationAngle += 0x200; + + if (this->collider.base.acFlags & AC_HIT || this->collider.base.ocFlags1 & OC1_HIT) { + this->actionFunc = EnElfbub_Pop; + this->popTimer = 6; + return; + } + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void EnElfbub_Update(Actor* thisx, GlobalContext* globalCtx) { + EnElfbub* this = THIS; + Collider_UpdateCylinder(&this->actor, &this->collider); + this->actionFunc(this, globalCtx); + Actor_SetHeight(&this->actor, this->actor.shape.yOffset); +} + +void EnElfbub_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnElfbub* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + SysMatrix_InsertTranslation(0.0f, 0.0f, 1.0f, 1); + SysMatrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_Scale(this->xyScale + 1.0f, this->xyScale + 1.0f, 1.0f, 1); + SysMatrix_InsertZRotation_s(this->zRot, 1); + Matrix_Scale(this->xScale + 1.0f, 1.0f, 1.0f, 1); + SysMatrix_InsertZRotation_s(this->zRot * -1, 1); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_06001000); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.h b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.h index 47151cf6ff..62a4b69a6c 100644 --- a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.h +++ b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.h @@ -3,13 +3,21 @@ #include "global.h" +#define ENELFBUB_GET_SWITCHFLAG(thisx) ((((thisx)->params) & 0xFE00) >> 9) + struct EnElfbub; typedef void (*EnElfbubActionFunc)(struct EnElfbub*, GlobalContext*); typedef struct EnElfbub { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x5C]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ s16 zRot; + /* 0x0192 */ s16 zRotDelta; + /* 0x0194 */ s16 oscillationAngle; + /* 0x0196 */ s16 popTimer; + /* 0x0198 */ f32 xScale; + /* 0x019C */ f32 xyScale; /* 0x01A0 */ EnElfbubActionFunc actionFunc; } EnElfbub; // size = 0x1A4