z_obj_mure.c (#364)

* a bunch of OKs and close functions

* OK All but 1 function

* Clean up code

* Match

* implement suggestions

* OBJMURE_CHILD_STATE_DEAD

* Update src/overlays/actors/ovl_Obj_Mure/z_obj_mure.c

Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>

* use enum for type tests

* add OBJMURE_TYPE_MAX

Co-authored-by: Kelebek1 <eeeedddccc@hotmail.co.uk>
Co-authored-by: Kenix3 <kenixwhisperwind@gmail.com>
Co-authored-by: engineer124 <47598039+engineer124@users.noreply.github.com>
This commit is contained in:
mzxrules 2021-11-30 20:18:58 -05:00 committed by GitHub
parent 6b493d3f9d
commit ce1de034df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 382 additions and 47 deletions

3
spec
View File

@ -1189,8 +1189,7 @@ beginseg
name "ovl_Obj_Mure" name "ovl_Obj_Mure"
compress compress
include "build/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.o" include "build/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.o"
include "build/data/ovl_Obj_Mure/ovl_Obj_Mure.data.o" include "build/src/overlays/actors/ovl_Obj_Mure/ovl_Obj_Mure_reloc.o"
include "build/data/ovl_Obj_Mure/ovl_Obj_Mure.reloc.o"
endseg endseg
beginseg beginseg

View File

@ -14,11 +14,12 @@ void ObjMure_Init(Actor* thisx, GlobalContext* globalCtx);
void ObjMure_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjMure_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjMure_Update(Actor* thisx, GlobalContext* globalCtx); void ObjMure_Update(Actor* thisx, GlobalContext* globalCtx);
void func_808D7FFC(ObjMure* this, GlobalContext* globalCtx); void ObjMure_InitialAction(ObjMure* this, GlobalContext* globalCtx);
void func_808D8014(ObjMure* this, GlobalContext* globalCtx); void ObjMure_CulledState(ObjMure* this, GlobalContext* globalCtx);
void func_808D8678(ObjMure* this, GlobalContext* globalCtx); void ObjMure_ActiveState(ObjMure* this, GlobalContext* globalCtx);
void ObjMure_KillActors(ObjMure* this, GlobalContext* globalCtx);
void ObjMure_CheckChildren(ObjMure* this, GlobalContext* globalCtx);
#if 0
const ActorInit Obj_Mure_InitVars = { const ActorInit Obj_Mure_InitVars = {
ACTOR_OBJ_MURE, ACTOR_OBJ_MURE,
ACTORCAT_ITEMACTION, ACTORCAT_ITEMACTION,
@ -31,53 +32,368 @@ const ActorInit Obj_Mure_InitVars = {
(ActorFunc)NULL, (ActorFunc)NULL,
}; };
// static InitChainEntry sInitChain[] = { static f32 sZClip[] = {
static InitChainEntry D_808D87BC[] = { 1600.0f, 1600.0f, 1000.0f, 1000.0f, 1000.0f,
};
static s32 sMaxChildSpawns[] = {
12,
9,
8,
0,
};
static s16 sSpawnActorIds[] = {
ACTOR_EN_KUSA, 0, ACTOR_EN_FISH, ACTOR_EN_INSECT, ACTOR_EN_BUTTE,
};
static s16 sSpawnParams[] = {
0, 2, -1, 0, -1,
};
static InitChainEntry sInitChain[] = {
ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 1200, ICHAIN_STOP), ICHAIN_F32(uncullZoneDownward, 1200, ICHAIN_STOP),
}; };
#endif typedef enum {
/* 0 */ OBJMURE_TYPE_GRASS,
/* 1 */ OBJMURE_TYPE_UNDEFINED,
/* 2 */ OBJMURE_TYPE_FISH,
/* 3 */ OBJMURE_TYPE_BUGS,
/* 4 */ OBJMURE_TYPE_BUTTERFLY,
/* 5 */ OBJMURE_TYPE_MAX
} ObjMureType;
extern InitChainEntry D_808D87BC[]; typedef enum {
/* 0 */ OBJMURE_CHILD_STATE_0,
/* 1 */ OBJMURE_CHILD_STATE_DEAD,
/* 2 */ OBJMURE_CHILD_STATE_2
} ObjMureChildState;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D78D0.s") s32 func_808D78D0(ObjMure* this, GlobalContext* globalCtx) {
if (this->type == OBJMURE_TYPE_FISH || this->type == OBJMURE_TYPE_BUGS || this->type == OBJMURE_TYPE_BUTTERFLY) {
Actor_ProcessInitChain(&this->actor, sInitChain);
} else {
return false;
}
return true;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7928.s") s32 func_808D7928(ObjMure* this, GlobalContext* globalCtx) {
if (!func_808D78D0(this, globalCtx)) {
return false;
}
return true;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/ObjMure_Init.s") void ObjMure_Init(Actor* thisx, GlobalContext* globalCtx) {
ObjMure* this = THIS;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/ObjMure_Destroy.s") this->chNum = OBJ_MURE_GET_CHNUM(this->actor.params);
this->ptn = OBJ_MURE_GET_PTN(this->actor.params);
this->svNum = OBJ_MURE_GET_SVNUM(this->actor.params);
this->type = OBJ_MURE_GET_TYPE(this->actor.params);
if (this->ptn >= 4) {
Actor_MarkForDeath(&this->actor);
return;
}
if (this->type >= OBJMURE_TYPE_MAX) {
Actor_MarkForDeath(&this->actor);
return;
}
if (!func_808D7928(this, globalCtx)) {
Actor_MarkForDeath(&this->actor);
return;
}
this->actionFunc = ObjMure_InitialAction;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7A14.s") void ObjMure_Destroy(Actor* thisx, GlobalContext* globalCtx) {
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7A40.s") s32 ObjMure_GetMaxChildSpawns(ObjMure* this) {
if (this->chNum == 0) {
return sMaxChildSpawns[this->ptn];
}
return this->chNum;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7A68.s") void ObjMure_GetSpawnPos(Vec3f* outPos, Vec3f* inPos, s32 ptn, s32 idx) {
*outPos = *inPos;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7C64.s") void ObjMure_SpawnActors0(Actor* thisx, GlobalContext* globalCtx) {
ObjMure* this = THIS;
s32 i;
Vec3f pos;
s32 pad;
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7DC4.s") for (i = 0; i < maxChildren; i++) {
switch (this->childrenStates[i]) {
case OBJMURE_CHILD_STATE_DEAD:
break;
case OBJMURE_CHILD_STATE_2:
ObjMure_GetSpawnPos(&pos, &this->actor.world.pos, this->ptn, i);
this->children[i] = Actor_SpawnAsChildAndCutscene(
&globalCtx->actorCtx, globalCtx, sSpawnActorIds[this->type], pos.x, pos.y, pos.z,
this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, sSpawnParams[this->type],
this->actor.cutscene, this->actor.unk20, NULL);
if (this->children[i] != NULL) {
if (this->type == 0x90) {
((ObjMureChild*)this->children[i])->unk_197 = 1;
}
this->children[i]->room = this->actor.room;
}
break;
default:
ObjMure_GetSpawnPos(&pos, &this->actor.world.pos, this->ptn, i);
this->children[i] = Actor_SpawnAsChildAndCutscene(
&globalCtx->actorCtx, globalCtx, sSpawnActorIds[this->type], pos.x, pos.y, pos.z,
this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, sSpawnParams[this->type],
this->actor.cutscene, this->actor.unk20, NULL);
if (this->children[i] != NULL) {
this->children[i]->room = this->actor.room;
}
break;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7E14.s") void ObjMure_SpawnActors1(ObjMure* this, GlobalContext* globalCtx) {
GlobalContext* globalCtx2 = globalCtx;
Actor* actor = &this->actor;
Vec3f spawnPos;
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7F0C.s") for (i = 0; i < maxChildren; i++) {
ObjMure_GetSpawnPos(&spawnPos, &actor->world.pos, this->ptn, i);
this->children[i] = Actor_SpawnAsChildAndCutscene(
&globalCtx->actorCtx, globalCtx, sSpawnActorIds[this->type], spawnPos.x, spawnPos.y, spawnPos.z,
actor->world.rot.x, actor->world.rot.y, actor->world.rot.z,
(this->type == OBJMURE_TYPE_BUTTERFLY && i == 0) ? 1 : sSpawnParams[this->type], this->actor.cutscene,
this->actor.unk20, NULL);
if (this->children[i] != NULL) {
this->childrenStates[i] = OBJMURE_CHILD_STATE_0;
this->children[i]->room = actor->room;
} else {
this->childrenStates[i] = OBJMURE_CHILD_STATE_DEAD;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7F2C.s") void ObjMure_SpawnActors(ObjMure* this, GlobalContext* globalCtx) {
switch (this->svNum) {
case 0:
ObjMure_SpawnActors0(&this->actor, globalCtx);
break;
case 1:
ObjMure_SpawnActors1(this, globalCtx);
break;
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7FFC.s") void ObjMure_KillActorsImpl(ObjMure* this, GlobalContext* globalCtx) {
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D8014.s") for (i = 0; i < maxChildren; i++) {
switch (this->childrenStates[i]) {
case OBJMURE_CHILD_STATE_DEAD:
this->children[i] = NULL;
break;
case OBJMURE_CHILD_STATE_2:
if (this->children[i] != NULL) {
Actor_MarkForDeath(this->children[i]);
this->children[i] = NULL;
}
break;
default:
if (this->children[i] != NULL) {
if (Actor_HasParent(this->children[i], globalCtx)) {
this->children[i] = NULL;
} else {
Actor_MarkForDeath(this->children[i]);
this->children[i] = NULL;
}
}
break;
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D8074.s") void ObjMure_KillActors(ObjMure* this, GlobalContext* globalCtx) {
ObjMure_KillActorsImpl(this, globalCtx);
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D814C.s") void ObjMure_CheckChildren(ObjMure* this, GlobalContext* globalCtx) {
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
s32 i;
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D82CC.s") for (i = 0; i < maxChildren; i++) {
if (this->children[i] != NULL) {
if (this->childrenStates[i] == OBJMURE_CHILD_STATE_0) {
if (this->children[i]->update != NULL) {
if ((this->type == 0x90) && (((ObjMureChild*)this->children[i])->unk_197 != 0)) {
this->childrenStates[i] = OBJMURE_CHILD_STATE_2;
}
} else {
this->childrenStates[i] = OBJMURE_CHILD_STATE_DEAD;
this->children[i] = NULL;
}
} else if (this->childrenStates[i] == OBJMURE_CHILD_STATE_2 && this->children[i]->update == NULL) {
this->childrenStates[i] = OBJMURE_CHILD_STATE_DEAD;
this->children[i] = NULL;
}
}
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D84F4.s") void ObjMure_InitialAction(ObjMure* this, GlobalContext* globalCtx) {
this->actionFunc = ObjMure_CulledState;
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D8678.s") void ObjMure_CulledState(ObjMure* this, GlobalContext* globalCtx) {
if (fabsf(this->actor.projectedPos.z) < sZClip[this->type]) {
this->actionFunc = ObjMure_ActiveState;
this->actor.flags |= 0x10;
ObjMure_SpawnActors(this, globalCtx);
}
}
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/ObjMure_Update.s") void ObjMure_SetFollowTargets(ObjMure* this, f32 randMax) {
s32 index;
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
s32 i;
for (i = 0; i < maxChildren; i++) {
if (this->children[i] != NULL) {
this->children[i]->child = NULL;
if (Rand_ZeroOne() <= randMax) {
index = Rand_ZeroOne() * (maxChildren - 0.5f);
if (i != index) {
this->children[i]->child = this->children[index];
}
}
}
}
}
/**
* Selects a child that will follow after the player
* `idx1` is the index + 1 of the child that will follow the player. If `idx1` is zero, no actor will follow the player
*/
void ObjMure_SetChildToFollowPlayer(ObjMure* this, s32 idx1) {
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
s32 i;
s32 i2;
s32 j;
for (i = 0, i2 = 0; i < maxChildren; i++) {
if (this->children[i] != NULL) {
if (i2 < idx1) {
i2++;
this->children[i]->child = this->children[i];
for (j = 0; j < maxChildren; j++) {
if (i != j && this->children[j]->child == this->children[i]) {
this->children[j]->child = NULL;
}
}
} else if (this->children[i]->child == this->children[i]) {
this->children[i]->child = NULL;
}
}
}
}
// Fish, Bugs
void ObjMure_GroupBehavior0(ObjMure* this, GlobalContext* globalCtx) {
if (this->unk_19C <= 0) {
if (this->unk_19E) {
this->unk_19E = false;
ObjMure_SetFollowTargets(this, (Rand_ZeroOne() * 0.5f) + 0.1f);
if (this->actor.xzDistToPlayer < 60.0f) {
this->unk_19C = (s32)(Rand_ZeroOne() * 5.5f) + 4;
} else {
this->unk_19C = (s32)(Rand_ZeroOne() * 40.5f) + 4;
}
} else {
this->unk_19E = true;
if (this->actor.xzDistToPlayer < 60.0f) {
this->unk_19C = (s32)(Rand_ZeroOne() * 10.5f) + 4;
ObjMure_SetFollowTargets(this, (Rand_ZeroOne() * 0.2f) + 0.8f);
} else {
this->unk_19C = (s32)(Rand_ZeroOne() * 10.5f) + 4;
ObjMure_SetFollowTargets(this, (Rand_ZeroOne() * 0.2f) + 0.6f);
}
}
}
if (this->actor.xzDistToPlayer < 120.0f) {
this->unk_1A0++;
} else {
this->unk_1A0 = 0;
}
if (this->unk_1A0 >= 80) {
ObjMure_SetChildToFollowPlayer(this, 1);
} else {
ObjMure_SetChildToFollowPlayer(this, 0);
}
}
// Butterflies
void ObjMure_GroupBehavior1(ObjMure* this, GlobalContext* globalCtx) {
s32 maxChildren;
s32 i;
if (this->unk_19C <= 0) {
if (this->unk_19E) {
this->unk_19E = false;
ObjMure_SetFollowTargets(this, Rand_ZeroOne() * 0.2f);
if (this->actor.xzDistToPlayer < 60.0f) {
this->unk_19C = (s32)(Rand_ZeroOne() * 5.5f) + 4;
} else {
this->unk_19C = (s32)(Rand_ZeroOne() * 40.5f) + 4;
}
} else {
this->unk_19E = true;
ObjMure_SetFollowTargets(this, Rand_ZeroOne() * 0.7f);
this->unk_19C = (s32)(Rand_ZeroOne() * 10.5f) + 4;
}
}
maxChildren = ObjMure_GetMaxChildSpawns(this);
for (i = 0; i < maxChildren; i++) {
if (this->children[i] != NULL) {
if (this->children[i]->child != NULL && this->children[i]->child->update == NULL) {
this->children[i]->child = NULL;
}
}
}
}
static ObjMureActionFunc sTypeGroupBehaviorFunc[] = {
NULL, NULL, ObjMure_GroupBehavior0, ObjMure_GroupBehavior0, ObjMure_GroupBehavior1,
};
void ObjMure_ActiveState(ObjMure* this, GlobalContext* globalCtx) {
ObjMure_CheckChildren(this, globalCtx);
if (sZClip[this->type] + 40.0f <= fabsf(this->actor.projectedPos.z)) {
this->actionFunc = ObjMure_CulledState;
this->actor.flags &= ~0x10;
ObjMure_KillActors(this, globalCtx);
} else if (sTypeGroupBehaviorFunc[this->type] != NULL) {
sTypeGroupBehaviorFunc[this->type](this, globalCtx);
}
}
void ObjMure_Update(Actor* thisx, GlobalContext* globalCtx) {
ObjMure* this = THIS;
if (this->unk_19C > 0) {
this->unk_19C--;
}
this->actionFunc(this, globalCtx);
}

View File

@ -7,12 +7,33 @@ struct ObjMure;
typedef void (*ObjMureActionFunc)(struct ObjMure*, GlobalContext*); typedef void (*ObjMureActionFunc)(struct ObjMure*, GlobalContext*);
#define OBJMURE_MAX_SPAWNS 15
typedef struct {
Actor actor;
/* 0x144 */ char unk_144[0x53];
/* 0x197 */ u8 unk_197;
} ObjMureChild;
typedef struct ObjMure { typedef struct ObjMure {
/* 0x0000 */ Actor actor; /* 0x0000 */ Actor actor;
/* 0x0144 */ ObjMureActionFunc actionFunc; /* 0x0144 */ ObjMureActionFunc actionFunc;
/* 0x0148 */ char unk_144[0x5C]; /* 0x0148 */ s16 chNum;
/* 0x014A */ s16 ptn;
/* 0x014C */ s16 svNum;
/* 0x014E */ s16 type;
/* 0x0150 */ Actor* children[OBJMURE_MAX_SPAWNS];
/* 0x018C */ u8 childrenStates[OBJMURE_MAX_SPAWNS];
/* 0x019C */ s16 unk_19C;
/* 0x019E */ s16 unk_19E;
/* 0x01A0 */ s16 unk_1A0;
} ObjMure; // size = 0x1A4 } ObjMure; // size = 0x1A4
extern const ActorInit Obj_Mure_InitVars; extern const ActorInit Obj_Mure_InitVars;
#define OBJ_MURE_GET_CHNUM(params) ((params >> 12) & 0xF)
#define OBJ_MURE_GET_PTN(params) ((params >> 8) & 0x7)
#define OBJ_MURE_GET_SVNUM(params) ((params >> 5) & 0x3)
#define OBJ_MURE_GET_TYPE(params) (params & 0x1F)
#endif // Z_OBJ_MURE_H #endif // Z_OBJ_MURE_H

View File

@ -6401,21 +6401,21 @@
0x808D7928:("func_808D7928",), 0x808D7928:("func_808D7928",),
0x808D7954:("ObjMure_Init",), 0x808D7954:("ObjMure_Init",),
0x808D7A04:("ObjMure_Destroy",), 0x808D7A04:("ObjMure_Destroy",),
0x808D7A14:("func_808D7A14",), 0x808D7A14:("ObjMure_GetMaxChildSpawns",),
0x808D7A40:("func_808D7A40",), 0x808D7A40:("ObjMure_GetSpawnPos",),
0x808D7A68:("func_808D7A68",), 0x808D7A68:("ObjMure_SpawnActors0",),
0x808D7C64:("func_808D7C64",), 0x808D7C64:("ObjMure_SpawnActors1",),
0x808D7DC4:("func_808D7DC4",), 0x808D7DC4:("ObjMure_SpawnActors",),
0x808D7E14:("func_808D7E14",), 0x808D7E14:("ObjMure_KillActorsImpl",),
0x808D7F0C:("func_808D7F0C",), 0x808D7F0C:("ObjMure_KillActors",),
0x808D7F2C:("func_808D7F2C",), 0x808D7F2C:("ObjMure_CheckChildren",),
0x808D7FFC:("func_808D7FFC",), 0x808D7FFC:("ObjMure_InitialAction",),
0x808D8014:("func_808D8014",), 0x808D8014:("ObjMure_CulledState",),
0x808D8074:("func_808D8074",), 0x808D8074:("ObjMure_SetFollowTargets",),
0x808D814C:("func_808D814C",), 0x808D814C:("ObjMure_SetChildToFollowPlayer",),
0x808D82CC:("func_808D82CC",), 0x808D82CC:("ObjMure_GroupBehavior0",),
0x808D84F4:("func_808D84F4",), 0x808D84F4:("ObjMure_GroupBehavior1",),
0x808D8678:("func_808D8678",), 0x808D8678:("ObjMure_ActiveState",),
0x808D8720:("ObjMure_Update",), 0x808D8720:("ObjMure_Update",),
0x808D8940:("func_808D8940",), 0x808D8940:("func_808D8940",),
0x808D8B58:("func_808D8B58",), 0x808D8B58:("func_808D8B58",),

View File

@ -7130,7 +7130,6 @@
0x808D784C:("D_808D784C","f32","",0x4), 0x808D784C:("D_808D784C","f32","",0x4),
0x808D7850:("D_808D7850","f32","",0x4), 0x808D7850:("D_808D7850","f32","",0x4),
0x808D8760:("Obj_Mure_InitVars","UNK_TYPE1","",0x1), 0x808D8760:("Obj_Mure_InitVars","UNK_TYPE1","",0x1),
0x808D8780:("D_808D8780","UNK_TYPE1","",0x1),
0x808DB9C0:("En_Sw_InitVars","UNK_TYPE1","",0x1), 0x808DB9C0:("En_Sw_InitVars","UNK_TYPE1","",0x1),
0x808DB9E0:("D_808DB9E0","UNK_TYPE1","",0x1), 0x808DB9E0:("D_808DB9E0","UNK_TYPE1","",0x1),
0x808DBA0C:("D_808DBA0C","UNK_PTR","",0x4), 0x808DBA0C:("D_808DBA0C","UNK_PTR","",0x4),