From a8e9b6c9b36104dc1aeda528ca7e17c0d49e4235 Mon Sep 17 00:00:00 2001 From: Maide <34639600+Kelebek1@users.noreply.github.com> Date: Tue, 29 Mar 2022 18:08:50 +0100 Subject: [PATCH] OBj_Fireshield (#740) --- spec | 3 +- .../ovl_Obj_Fireshield/z_obj_fireshield.c | 373 ++++++++++++++++-- .../ovl_Obj_Fireshield/z_obj_fireshield.h | 20 +- 3 files changed, 363 insertions(+), 33 deletions(-) diff --git a/spec b/spec index 5d82b9e2fd..a300d6d9c8 100644 --- a/spec +++ b/spec @@ -2883,8 +2883,7 @@ beginseg name "ovl_Obj_Fireshield" compress include "build/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.o" - include "build/data/ovl_Obj_Fireshield/ovl_Obj_Fireshield.data.o" - include "build/data/ovl_Obj_Fireshield/ovl_Obj_Fireshield.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Fireshield/ovl_Obj_Fireshield_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.c b/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.c index 00810af230..705dc93bf0 100644 --- a/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.c +++ b/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.c @@ -5,6 +5,7 @@ */ #include "z_obj_fireshield.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS (ACTOR_FLAG_10) @@ -15,12 +16,12 @@ void ObjFireshield_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjFireshield_Update(Actor* thisx, GlobalContext* globalCtx); void ObjFireshield_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80A4CABC(ObjFireshield* this, GlobalContext* globalCtx); -void func_80A4CB7C(ObjFireshield* this, GlobalContext* globalCtx); -void func_80A4CCBC(ObjFireshield* this, GlobalContext* globalCtx); -void func_80A4CD28(ObjFireshield* this, GlobalContext* globalCtx); +void func_80A4CABC(ObjFireshield* this); +void func_80A4CB7C(ObjFireshield* this); +void func_80A4CC54(ObjFireshield* this); +void func_80A4CCBC(ObjFireshield* this); +void func_80A4CD28(ObjFireshield* this); -#if 0 const ActorInit Obj_Fireshield_InitVars = { ACTOR_OBJ_FIRESHIELD, ACTORCAT_PROP, @@ -33,49 +34,365 @@ const ActorInit Obj_Fireshield_InitVars = { (ActorFunc)ObjFireshield_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A4D820 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x01, 0x04 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_ON, + }, { 28, 144, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A4D8A4[] = { +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ f32 unk_04; +} ObjFireshieldStruct; // size = 0x8 + +ObjFireshieldStruct D_80A4D84C[] = { + { 1.0f, 200.0f }, + { 2.0f, 400.0f }, + { 3.0f, 700.0f }, +}; + +s32 D_80A4D864[] = { 0, 0, 0, 0 }; +s32 D_80A4D874[] = { 0, 0, 0, 0 }; +s32 D_80A4D884[] = { 0, 0, 0, 0 }; +s32 D_80A4D894[] = { 0, 0, 0, 0 }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void func_80A4CA90(ObjFireshield* this) { + if (this->actor.cutscene >= 0) { + this->actionFunc = func_80A4CABC; + } else { + this->actionFunc = func_80A4CC54; + } +} -extern ColliderCylinderInit D_80A4D820; -extern InitChainEntry D_80A4D8A4[]; +void func_80A4CABC(ObjFireshield* this) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CA90.s") + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + s32 sp18 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 temp_a0 = (sp18 & ~0x1F) >> 5; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CABC.s") + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->actionFunc = func_80A4CB7C; + this->unk_194 = 20; + D_80A4D884[temp_a0] |= 1 << (sp18 & 0x1F); + D_80A4D894[temp_a0] |= 1 << (sp18 & 0x1F); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CB7C.s") +void func_80A4CB7C(ObjFireshield* this) { + s32 pad; + s32 sp18 = OBJFIRESHIELD_GET_7F(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CC54.s") + if (this->unk_194 > 0) { + if (this->unk_194 == 20) { + D_80A4D884[(sp18 & ~0x1F) >> 5] &= ~(1 << (sp18 & 0x1F)); + } + this->unk_194--; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CCBC.s") + ActorCutscene_Stop(this->actor.cutscene); + this->actionFunc = func_80A4CD28; + D_80A4D894[(sp18 & ~0x1F) >> 5] &= ~(1 << (sp18 & 0x1F)); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CD28.s") +void func_80A4CC54(ObjFireshield* this) { + s32 temp_v0 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 temp_v1 = 1 << (temp_v0 & 0x1F); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CD34.s") + this->actionFunc = func_80A4CCBC; + D_80A4D884[(temp_v0 & ~0x1F) >> 5] |= temp_v1; + D_80A4D894[(temp_v0 & ~0x1F) >> 5] |= temp_v1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CE28.s") +void func_80A4CCBC(ObjFireshield* this) { + s32 temp_v0 = OBJFIRESHIELD_GET_7F(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4D174.s") + this->actionFunc = func_80A4CD28; + D_80A4D884[(temp_v0 & ~0x1F) >> 5] &= ~(1 << (temp_v0 & 0x1F)); + D_80A4D894[(temp_v0 & ~0x1F) >> 5] &= ~(1 << (temp_v0 & 0x1F)); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4D1CC.s") +void func_80A4CD28(ObjFireshield* this) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/ObjFireshield_Init.s") +void func_80A4CD34(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjFireshield* this = THIS; + s32 sp24 = Flags_GetSwitch(globalCtx, OBJFIRESHIELD_GET_7F(&this->actor)); + s32 phi_v1; + s32 phi_a0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/ObjFireshield_Destroy.s") + if (this->unk_1A8 == 0) { + if (OBJFIRESHIELD_GET_2000(&this->actor)) { + phi_v1 = false; + phi_a0 = false; + } else { + phi_v1 = Flags_GetTreasure(globalCtx, OBJFIRESHIELD_GET_1F00(&this->actor)); + phi_a0 = false; + } + } else { + phi_a0 = Flags_GetSwitch(globalCtx, OBJFIRESHIELD_GET_3F80(&this->actor)); + phi_v1 = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/ObjFireshield_Update.s") + if (phi_v1 || phi_a0) { + this->unk_19C = 0; + } else if (sp24) { + this->unk_19C = 0; + } else { + this->unk_19C = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/ObjFireshield_Draw.s") + if (this->unk_19C == 0) { + this->unk_198 = 0.0f; + } else { + this->unk_198 = 1.0f; + } +} + +void func_80A4CE28(ObjFireshield* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp30 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 pad2[2]; + s32 sp24; + s32 sp20; + + if (this->unk_1A8 == 0) { + if (OBJFIRESHIELD_GET_2000(&this->actor)) { + sp24 = false; + sp20 = false; + } else { + sp24 = Flags_GetTreasure(globalCtx, OBJFIRESHIELD_GET_1F00(&this->actor)); + sp20 = false; + } + } else { + sp20 = Flags_GetSwitch(globalCtx, OBJFIRESHIELD_GET_3F80(&this->actor)); + sp24 = false; + } + + if (!sp24 || !sp20 || (this->unk_19C != 0)) { + s32 sp1C = Flags_GetSwitch(globalCtx, sp30); + s32 temp_v0 = (sp30 & ~0x1F) >> 5; + + if (this->unk_19C == 2) { + if (Math_StepToF(&this->unk_198, 1.0f, 0.03f)) { + this->unk_19C = 1; + if (((this->actor.home.rot.z * 10) > 0) && (this->unk_1A7 != 0)) { + Flags_UnsetSwitch(globalCtx, sp30); + sp1C = false; + } + } + } else if (this->unk_19C == 3) { + if (Math_StepToF(&this->unk_198, 0.0f, 0.03f)) { + this->unk_19C = 0; + } + } + + if ((this->unk_1A0 > 0) && (this->unk_19C == 1) && ((this->actor.home.rot.z * 10) > 0) && + !(D_80A4D894[temp_v0] & (1 << (sp30 & 0x1F)))) { + this->unk_1A0 = 0; + } + + if ((this->unk_19C == 0) || (this->unk_19C == 3)) { + if (!sp24 && !sp20) { + if ((this->actor.home.rot.z * 10) > 0) { + if (this->unk_1A0 > 1) { + this->unk_1A0--; + } + + if (this->unk_1A0 == 1) { + this->unk_19C = 2; + } + } + + if (!sp1C) { + this->unk_19C = 2; + } + } + } else if (sp24 || sp20) { + this->unk_19C = 3; + } else if (sp1C && ((this->unk_19C == 1) || (this->unk_19C == 2))) { + if ((D_80A4D884[temp_v0] & 1 << (sp30 & 0x1F)) && !(D_80A4D874[temp_v0] & 1 << (sp30 & 0x1F))) { + this->unk_19C = 3; + } else if (((this->actor.home.rot.z * 10) == 0) || (this->unk_1A0 == 0)) { + if ((this->actor.home.rot.z * 10) > 0) { + this->unk_1A0 = this->actor.home.rot.z * 10; + } + + if (this->unk_1A7 != 0) { + func_80A4CA90(this); + } + } + } + } +} + +void func_80A4D174(ObjFireshield* this) { + s32 temp_v0 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 temp_v1 = 1 << (temp_v0 & 0x1F); + + if (!(D_80A4D864[(temp_v0 & ~0x1F) >> 5] & temp_v1)) { + this->unk_1A7 = 1; + D_80A4D864[(temp_v0 & ~0x1F) >> 5] |= temp_v1; + } +} + +void func_80A4D1CC(void) { + D_80A4D864[0] = 0; + D_80A4D864[1] = 0; + D_80A4D864[2] = 0; + D_80A4D864[3] = 0; +} + +void ObjFireshield_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjFireshield* this = THIS; + s32 temp = 0x8000; + ObjFireshieldStruct* sp2C = &D_80A4D84C[OBJFIRESHIELD_GET_C000(&this->actor)]; + s32 sp28 = OBJFIRESHIELD_GET_ROTX(&this->actor); + + Actor_ProcessInitChain(&this->actor, sInitChain); + + if (sp28) { + this->actor.shape.rot.z = temp; + } else { + this->actor.shape.rot.z = 0; + } + + this->actor.world.rot.z = 0; + this->actor.shape.rot.x = 0; + this->actor.world.rot.x = 0; + + this->actor.scale.x = sp2C->unk_00 * 0.0348f; + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = 0.05f; + + this->actor.uncullZoneScale = sp2C->unk_04; + this->unk_1A4 = Rand_ZeroOne() * 128.0f; + + if ((this->actor.home.rot.z * 10) < 0) { + this->unk_1A8 = 1; + this->actor.home.rot.z = -thisx->home.rot.z; + } + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider); + + this->collider.dim.radius *= sp2C->unk_00; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + func_80A4D174(this); + func_80A4CD34(&this->actor, globalCtx); + this->actionFunc = func_80A4CD28; +} + +void ObjFireshield_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjFireshield* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void ObjFireshield_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjFireshield* this = THIS; + ObjFireshield* this2 = THIS; + s32 sp44 = OBJFIRESHIELD_GET_ROTX(&this->actor); + s32 sp40 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 temp_a0; + s32 temp_v1; + + func_80A4D1CC(); + + if (this->unk_1A7 != 0) { + temp_a0 = (sp40 & ~0x1F) >> 5; + temp_v1 = 1 << (sp40 & 0x1F); + if ((D_80A4D884[temp_a0] & temp_v1)) { + D_80A4D874[temp_a0] |= temp_v1; + } else { + D_80A4D874[temp_a0] &= ~temp_v1; + } + } + + this->unk_1A4++; + + this->actionFunc(this); + + if (this->actionFunc == func_80A4CABC) { + this->collider.base.atFlags &= ~AT_HIT; + } else if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + func_800B8D98(globalCtx, &this->actor, 5.0f, this->actor.yawTowardsPlayer, 1.0f); + } + + func_80A4CE28(this, globalCtx); + + this->actor.world.pos.y = ((sp44 ? 144.0f : -144.0f) * (1.0f - this2->unk_198)) + this->actor.home.pos.y; + + this->unk_1A6 = this->unk_198 * 255.0f; + + if (this->unk_198 >= 0.7f) { + Player* player = GET_PLAYER(globalCtx); + + this->collider.dim.height = this->unk_198 * 80.0f; + + if (sp44) { + this->collider.dim.yShift = + (s32)(this->actor.home.pos.y - this->actor.world.pos.y) - this->collider.dim.height; + } else { + this->collider.dim.yShift = this->actor.home.pos.y - this->actor.world.pos.y; + } + + func_800B9010(&this->actor, NA_SE_EV_BURNING - SFX_FLAG); + + if (player->transformation == PLAYER_FORM_GORON) { + this->collider.info.toucher.damage = 0; + this->collider.info.toucher.effect = 0; + } else { + this->collider.info.toucher.damage = 4; + this->collider.info.toucher.effect = 1; + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void ObjFireshield_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjFireshield* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 220, 0, this->unk_1A6); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, this->unk_1A4 & 0x7F, 0, 0x20, 0x40, 1, 0, + (this->unk_1A4 * -15) & 0xFF, 0x20, 0x40)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_02E510); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.h b/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.h index f39039793b..4d6a971eb0 100644 --- a/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.h +++ b/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.h @@ -5,13 +5,27 @@ struct ObjFireshield; -typedef void (*ObjFireshieldActionFunc)(struct ObjFireshield*, GlobalContext*); +typedef void (*ObjFireshieldActionFunc)(struct ObjFireshield*); + +#define OBJFIRESHIELD_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJFIRESHIELD_GET_1F00(thisx) (((thisx)->params >> 8) & 0x1F) +#define OBJFIRESHIELD_GET_2000(thisx) (((thisx)->params >> 0xD) & 1) +#define OBJFIRESHIELD_GET_3F80(thisx) (((thisx)->params >> 7) & 0x7F) +#define OBJFIRESHIELD_GET_C000(thisx) (((thisx)->params >> 0xE) & 3) +#define OBJFIRESHIELD_GET_ROTX(thisx) ((thisx)->home.rot.x & 1) typedef struct ObjFireshield { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4C]; + /* 0x0144 */ ColliderCylinder collider; /* 0x0190 */ ObjFireshieldActionFunc actionFunc; - /* 0x0194 */ char unk_194[0x18]; + /* 0x0194 */ s32 unk_194; + /* 0x0198 */ f32 unk_198; + /* 0x019C */ s32 unk_19C; + /* 0x01A0 */ s32 unk_1A0; + /* 0x01A4 */ s16 unk_1A4; + /* 0x01A6 */ u8 unk_1A6; + /* 0x01A7 */ s8 unk_1A7; + /* 0x01A8 */ s8 unk_1A8; } ObjFireshield; // size = 0x1AC extern const ActorInit Obj_Fireshield_InitVars;