OBj_Fireshield (#740)

This commit is contained in:
Maide 2022-03-29 18:08:50 +01:00 committed by GitHub
parent 37e82498df
commit a8e9b6c9b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 363 additions and 33 deletions

3
spec
View File

@ -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

View File

@ -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);
}

View File

@ -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;