diff --git a/linker_scripts/code_script.txt b/linker_scripts/code_script.txt index ab02f135a7..0a24259854 100644 --- a/linker_scripts/code_script.txt +++ b/linker_scripts/code_script.txt @@ -1677,7 +1677,7 @@ SECTIONS ovl_En_Encount2 : AT(RomLocation) { build/src/overlays/actors/ovl_En_Encount2/z_en_encount2.o(.text) - build/asm/overlays/ovl_En_Encount2_data.o(.data) + build/src/overlays/actors/ovl_En_Encount2/z_en_encount2.o(.data) build/src/overlays/actors/ovl_En_Encount2/z_en_encount2.o(.rodata) build/asm/overlays/ovl_En_Encount2_rodata.o(.rodata) } diff --git a/linker_scripts/object_script.txt b/linker_scripts/object_script.txt index 1e414ae69e..91988b3b62 100644 --- a/linker_scripts/object_script.txt +++ b/linker_scripts/object_script.txt @@ -56,6 +56,11 @@ D_06001470 = 0x06001470; /* z_en_nnh */ D_06001510 = 0x06001510; +/* en_encount2 */ +D_06000A00 = 0x6000A00; +D_06000D78 = 0x6000D78; +D_06002420 = 0x6002420; + /* bg_haka_curtain */ D_06001410 = 0x06001410; D_06001588 = 0x06001588; diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c index 96703320fb..7ad696242f 100644 --- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c +++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c @@ -9,7 +9,14 @@ void EnEncount2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnEncount2_Update(Actor* thisx, GlobalContext* globalCtx); void EnEncount2_Draw(Actor* thisx, GlobalContext* globalCtx); -/* +void EnEncount2_Idle(EnEncount2* this, GlobalContext* globalCtx); +void EnEncount2_Popped(EnEncount2* this, GlobalContext* globalCtx); +void EnEncount2_Die(EnEncount2* this, GlobalContext* globalCtx); +void EnEncount2_SetIdle(EnEncount2* this); +void EnEncount2_InitParticles(EnEncount2* this, Vec3f* vec, s16 fadeDelay); +void EnEncount2_UpdateParticles(EnEncount2* this, GlobalContext* globalCtx); +void EnEncount2_DrawParticles(EnEncount2* this, GlobalContext* globalCtx); + const ActorInit En_Encount2_InitVars = { ACTOR_EN_ENCOUNT2, ACTORCAT_PROP, @@ -21,26 +28,205 @@ const ActorInit En_Encount2_InitVars = { (ActorFunc)EnEncount2_Update, (ActorFunc)EnEncount2_Draw }; -*/ -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/EnEncount2_Init.asm") +static ColliderJntSphElementInit sJntSphElementsInit[1] = { + { + { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { 1, { { 0, 0, 0 }, 0 }, 1 }, + }, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/EnEncount2_Destroy.asm") +static ColliderJntSphInit sJntSphInit = { + { COLTYPE_HARD, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, + 1, sJntSphElementsInit, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/func_808E16FC.asm") +DamageTable damageTable[] = { + 0xF0, 0xF0, 0x00, 0xF0, 0xE1, 0xE1, 0x00, 0xE1, 0xF0, 0xF0, 0xF0, 0xE1, 0xE1, 0xE1, 0xF0, 0xF0, + 0xE1, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0xE1, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, +}; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/func_808E1714.asm") +void EnEncount2_Init(Actor* thisx, GlobalContext* globalCtx) { + EnEncount2* this = THIS; + s32 pad; + CollisionHeader* colHeader = NULL; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/func_808E17C4.asm") + BcCheck3_BgActorInit(&this->dynaActor, 0); + BgCheck_RelocateMeshHeader(&D_06002420, &colHeader); + this->dynaActor.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dynaActor, colHeader); + ActorShape_Init(&this->dynaActor.actor.shape, 0.0f, func_800B3FC0, 25.0f); + this->dynaActor.actor.colChkInfo.mass = 0xFF; + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->dynaActor, &sJntSphInit, &this->colElement); -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/func_808E18A8.asm") + this->dynaActor.actor.targetMode = 6; + this->dynaActor.actor.colChkInfo.health = 1; + this->scale = 0.1; + this->switchFlag = GET_ENCOUNT2_SWITCH_FLAG(this); -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/EnEncount2_Update.asm") + if (this->switchFlag == 0x7F) { + this->switchFlag = -1; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/EnEncount2_Draw.asm") + if ((this->switchFlag >= 0) && (Actor_GetSwitchFlag(globalCtx, this->switchFlag))) { + Actor_MarkForDeath(&this->dynaActor.actor); + return; + } -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/func_808E1A24.asm") + this->collider.elements->dim.modelSphere.radius = 0x39; + this->collider.elements->dim.scale = 1.0f; + this->collider.elements->dim.modelSphere.center.x = 0; + this->collider.elements->dim.modelSphere.center.y = -4; + this->collider.elements->dim.modelSphere.center.z = 0; -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/func_808E1B4C.asm") + this->dynaActor.actor.colChkInfo.damageTable = &damageTable; + EnEncount2_SetIdle(this); +} -#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/func_808E1C9C.asm") +void EnEncount2_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnEncount2* this = THIS; + BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dynaActor.bgId); + Collider_DestroyJntSph(globalCtx, &this->collider); +} + +void EnEncount2_SetIdle(EnEncount2* this) { + this->isPopped = 0; + this->actionFunc = &EnEncount2_Idle; +} + +void EnEncount2_Idle(EnEncount2* this, GlobalContext* globalCtx) { + this->oscillationAngle += 1500.0f; + this->dynaActor.actor.velocity.y = Math_SinS(this->oscillationAngle); + Math_ApproachF(&this->scale, 0.1f, 0.3f, 0.01f); + if (((this->collider.base.acFlags & AC_HIT) != 0) && (this->dynaActor.actor.colChkInfo.damageEffect == 0xE)) { + this->dynaActor.actor.colChkInfo.health = 0; + this->isPopped = 1; + this->actionFunc = EnEncount2_Popped; + } +} + +void EnEncount2_Popped(EnEncount2* this, GlobalContext* globalCtx) { + s32 i; + Vec3f curPos; + + Math_Vec3f_Copy(&curPos, &this->dynaActor.actor.world.pos); + curPos.y += 60.0f; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, curPos.x, curPos.y, curPos.z, + 0xFF, 0xFF, 0xC8, 0x0001); + + for(i = 0; i != 100; ++i){ + EnEncount2_InitParticles(this, &curPos, 10); + } + + Audio_PlayActorSound2(this, 0x2949); // NA_SE_EV_MUJURA_BALLOON_BROKEN + this->deathTimer = 30; + this->actionFunc = EnEncount2_Die; +} + +void EnEncount2_Die(EnEncount2* this, GlobalContext* globalCtx) { + if (this->deathTimer == 0) { + if (this->switchFlag >= 0) { + Actor_SetSwitchFlag(globalCtx, this->switchFlag); + } + Actor_MarkForDeath(&this->dynaActor.actor); + } +} + +void EnEncount2_Update(Actor* thisx, GlobalContext* globalCtx) { + EnEncount2* this = THIS; + s32 pad; + + DECR(this->deathTimer); + + this->dynaActor.actor.shape.rot.y = this->dynaActor.actor.world.rot.y; + Actor_SetHeight(&this->dynaActor.actor, 30.0f); + Actor_SetScale(&this->dynaActor.actor, this->scale); + this->actionFunc(this, globalCtx); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->dynaActor.actor); + EnEncount2_UpdateParticles(this, globalCtx); + + if (! this->isPopped) { + Collider_UpdateSpheresElement(&this->collider, 0, &this->dynaActor.actor); + CollisionCheck_SetAC(globalCtx, &globalCtx->colCheckCtx, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colCheckCtx, &this->collider); + } +} + +void EnEncount2_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnEncount2* this = THIS; + if (this->isPopped != 1) { + func_800BDFC0(globalCtx, &D_06000A00); + func_800BDFC0(globalCtx, &D_06000D78); + } + EnEncount2_DrawParticles(this, globalCtx); +} + +void EnEncount2_InitParticles(EnEncount2* this, Vec3f *vec, s16 fadeDelay) { + s16 i; + EnEncount2Particle *sPtr = &this->particles; + + for (i = 0; i < 200; ++i) { + if ( ! sPtr->enabled) { + sPtr->enabled = 1; + sPtr->pos = *vec; + sPtr->alphaFadeDelay = fadeDelay; + sPtr->alpha = 0xFF; + + sPtr->accel.x = (Rand_ZeroOne() - 0.5f) * 10.0f; + sPtr->accel.y = (Rand_ZeroOne() - 0.5f) * 10.0f; + sPtr->accel.z = (Rand_ZeroOne() - 0.5f) * 10.0f; + + sPtr->vel.x = Rand_ZeroOne() - 0.5f; + sPtr->vel.y = Rand_ZeroOne() - 0.5f; + sPtr->vel.z = Rand_ZeroOne() - 0.5f; + + sPtr->scale = (Rand_ZeroFloat(1.0f) * 0.5f) + 2.0f; + return; + } + sPtr++; + } +} + +void EnEncount2_UpdateParticles(EnEncount2* this, GlobalContext* globalCtx) { + s32 i; + EnEncount2Particle *sPtr = &this->particles; + + for(i = 0 ; i < 200; i += 2) { + if (sPtr->enabled) { + sPtr->pos.x += sPtr->vel.x; + sPtr->pos.y += sPtr->vel.y; + sPtr->pos.z += sPtr->vel.z; + sPtr->vel.x += sPtr->accel.x; + sPtr->vel.y += sPtr->accel.y; + sPtr->vel.z += sPtr->accel.z; + if (sPtr->alphaFadeDelay != 0) { + sPtr->alphaFadeDelay--; + } else { + sPtr->alpha -= 10; + if (sPtr->alpha < 10) { + sPtr->enabled = 0; + } + } + } + sPtr++; + + if (sPtr->enabled) { + sPtr->pos.x += sPtr->vel.x; + sPtr->pos.y += sPtr->vel.y; + sPtr->pos.z += sPtr->vel.z; + sPtr->vel.x += sPtr->accel.x; + sPtr->vel.y += sPtr->accel.y; + sPtr->vel.z += sPtr->accel.z; + if (sPtr->alphaFadeDelay != 0) { + sPtr->alphaFadeDelay--; + } else { + sPtr->alpha -= 10; + if (sPtr->alpha < 10) { + sPtr->enabled = 0; + } + } + } + sPtr++; + } +} + +#pragma GLOBAL_ASM("./asm/non_matchings/overlays/ovl_En_Encount2_0x808E1560/EnEncount2_DrawParticles.asm") diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h index 89da358c0e..5430282d1b 100644 --- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h +++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.h @@ -3,13 +3,41 @@ #include +typedef void (*EnEncount2ActionFunc)(struct EnEncount2*, GlobalContext*); + +typedef struct EnEncount2Particle{ + /* 0x00 */ u8 enabled; + /* 0x04 */ Vec3f pos; + /* 0x14 */ s16 alpha; + /* 0x16 */ s16 alphaFadeDelay; // frame count before alpha fade starts + /* 0x18 */ Vec3f vel; + /* 0x24 */ Vec3f accel; + /* 0x30 */ f32 scale; + +} EnEncount2Particle; // size = 0x34 + struct EnEncount2; typedef struct EnEncount2 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_0144[0x292C]; + /* 0x0000 */ DynaPolyActor dynaActor; + /* 0x015C */ EnEncount2ActionFunc actionFunc; + /* 0x0160 */ s16 deathTimer; + /* 0x0162 */ s16 isPopped; + /* 0x0164 */ s16 switchFlag; + /* 0x0168 */ f32 scale; + /* 0x016C */ f32 oscillationAngle; + /* 0x0170 */ ColliderJntSph collider; + /* 0x0190 */ ColliderJntSphElement colElement; + /* 0x01D0 */ EnEncount2Particle particles[200]; } EnEncount2; // size = 0x2A70 +#define GET_ENCOUNT2_SWITCH_FLAG(this)((s16) (this->dynaActor.actor.params & 0x7F)) + extern const ActorInit En_Encount2_InitVars; +extern CollisionHeader D_06002420; + +extern s32 D_06000A00; +extern s32 D_06000D78; + #endif // Z_EN_ENCOUNT2_H diff --git a/tables/functions.txt b/tables/functions.txt index 0a25691530..02d7f38570 100644 --- a/tables/functions.txt +++ b/tables/functions.txt @@ -6530,15 +6530,15 @@ 0x808E13FC:("DemoTreLgt_Draw",), 0x808E1560:("EnEncount2_Init",), 0x808E16B4:("EnEncount2_Destroy",), - 0x808E16FC:("func_808E16FC",), - 0x808E1714:("func_808E1714",), - 0x808E17C4:("func_808E17C4",), - 0x808E18A8:("func_808E18A8",), + 0x808E16FC:("EnEncount2_SetIdle",), + 0x808E1714:("EnEncount2_Idle",), + 0x808E17C4:("EnEncount2_Popped",), + 0x808E18A8:("EnEncount2_Die",), 0x808E18F8:("EnEncount2_Update",), 0x808E19C4:("EnEncount2_Draw",), - 0x808E1A24:("func_808E1A24",), - 0x808E1B4C:("func_808E1B4C",), - 0x808E1C9C:("func_808E1C9C",), + 0x808E1A24:("EnEncount2_InitParticles",), + 0x808E1B4C:("EnEncount2_UpdateParticles",), + 0x808E1C9C:("EnEncount2_DrawParticles",), 0x808E1FE0:("EnFireRock_Init",), 0x808E1FF0:("EnFireRock_Destroy",), 0x808E2000:("EnFireRock_Update",),