mirror of
https://github.com/zeldaret/oot.git
synced 2025-08-05 22:00:15 +00:00
z_obj_mure OK (#875)
* almost matching init, matching data * more matchings, some non-matching progress * finishing up SpawnActor, fixing .data types * first decompile pass done, few non matchings * cleanup/update matchings and remove asm * format code * pick up some OKs * 1 non_matching left, some documentation * z_obj_mure OK... but at what cost? * implement suggested changes, some more documentation * Implement Fig's suggestions * review Co-authored-by: Sam Lyon <sam.c.lyon@gmail.com> Co-authored-by: fig02 <fig02srl@gmail.com>
This commit is contained in:
parent
e8f93099d1
commit
a209195183
25 changed files with 388 additions and 1322 deletions
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* File: z_obj_mure.c
|
||||
* Overlay: ovl_Obj_Mure
|
||||
* Description: Fish, Bugs, Butterflies
|
||||
* Description: Spawns Fish, Bug, Butterfly
|
||||
*/
|
||||
|
||||
#include "z_obj_mure.h"
|
||||
|
@ -14,7 +14,12 @@ void ObjMure_Init(Actor* thisx, GlobalContext* globalCtx);
|
|||
void ObjMure_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void ObjMure_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
|
||||
/*
|
||||
void ObjMure_InitialAction(ObjMure* this, GlobalContext* globalCtx);
|
||||
void ObjMure_CulledState(ObjMure* this, GlobalContext* globalCtx);
|
||||
void ObjMure_ActiveState(ObjMure* this, GlobalContext* globalCtx);
|
||||
|
||||
s32 ObjMure_GetMaxChildSpawns(ObjMure* this);
|
||||
|
||||
const ActorInit Obj_Mure_InitVars = {
|
||||
ACTOR_OBJ_MURE,
|
||||
ACTORCAT_ITEMACTION,
|
||||
|
@ -26,43 +31,388 @@ const ActorInit Obj_Mure_InitVars = {
|
|||
(ActorFunc)ObjMure_Update,
|
||||
NULL,
|
||||
};
|
||||
*/
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B98AA0.s")
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B98B1C.s")
|
||||
typedef enum {
|
||||
/* 0 */ OBJMURE_TYPE_GRASS,
|
||||
/* 1 */ OBJMURE_TYPE_UNDEFINED,
|
||||
/* 2 */ OBJMURE_TYPE_FISH,
|
||||
/* 3 */ OBJMURE_TYPE_BUGS,
|
||||
/* 4 */ OBJMURE_TYPE_BUTTERFLY
|
||||
} ObjMureType;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/ObjMure_Init.s")
|
||||
typedef enum {
|
||||
/* 0 */ OBJMURE_CHILD_STATE_0,
|
||||
/* 1 */ OBJMURE_CHILD_STATE_1, // Dead
|
||||
/* 2 */ OBJMURE_CHILD_STATE_2
|
||||
} ObjMureChildState;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/ObjMure_Destroy.s")
|
||||
static f32 sZClip[] = { 1600.0f, 1600.0f, 1000.0f, 1000.0f, 1000.0f };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B98C88.s")
|
||||
static s32 sMaxChildSpawns[] = { 12, 9, 8, 0 };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B98CB4.s")
|
||||
static s16 sSpawnActorIds[] = { ACTOR_EN_KUSA, 0, ACTOR_EN_FISH, ACTOR_EN_INSECT, ACTOR_EN_BUTTE };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B98D18.s")
|
||||
static s16 sSpawnParams[] = { 0, 2, -1, 0, -1 };
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B98F38.s")
|
||||
static InitChainEntry sInitChain[] = {
|
||||
ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE),
|
||||
ICHAIN_F32(uncullZoneDownward, 1200, ICHAIN_STOP),
|
||||
};
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B990BC.s")
|
||||
s32 ObjMure_SetCullingImpl(Actor* thisx, GlobalContext* globalCtx) {
|
||||
ObjMure* this = THIS;
|
||||
s32 result;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B9910C.s")
|
||||
switch (this->type) {
|
||||
case OBJMURE_TYPE_FISH:
|
||||
case OBJMURE_TYPE_BUGS:
|
||||
case OBJMURE_TYPE_BUTTERFLY:
|
||||
Actor_ProcessInitChain(&this->actor, sInitChain);
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
// Translation: "Error : Culling is not set.(%s %d)(arg_data 0x%04x)"
|
||||
osSyncPrintf("Error : カリングの設定がされていません。(%s %d)(arg_data 0x%04x)\n", "../z_obj_mure.c", 204,
|
||||
this->actor.params);
|
||||
return false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B99204.s")
|
||||
s32 ObjMure_SetCulling(Actor* thisx, GlobalContext* globalCtx) {
|
||||
if (!ObjMure_SetCullingImpl(thisx, globalCtx)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B99224.s")
|
||||
void ObjMure_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
ObjMure* this = THIS;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B992E4.s")
|
||||
this->chNum = (thisx->params >> 0xC) & 0x0F;
|
||||
this->ptn = (thisx->params >> 8) & 0x07;
|
||||
this->svNum = (thisx->params >> 5) & 0x03;
|
||||
this->type = thisx->params & 0x1F;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B992F8.s")
|
||||
if (this->ptn >= 4) {
|
||||
osSyncPrintf("Error 群れな敵 (%s %d)(arg_data 0x%04x)\n", "../z_obj_mure.c", 237, thisx->params);
|
||||
Actor_Kill(&this->actor);
|
||||
return;
|
||||
} else if (this->type >= 5) {
|
||||
osSyncPrintf("Error 群れな敵 (%s %d)(arg_data 0x%04x)\n", "../z_obj_mure.c", 245, thisx->params);
|
||||
Actor_Kill(&this->actor);
|
||||
return;
|
||||
} else if (!ObjMure_SetCulling(thisx, globalCtx)) {
|
||||
Actor_Kill(&this->actor);
|
||||
return;
|
||||
}
|
||||
this->actionFunc = ObjMure_InitialAction;
|
||||
osSyncPrintf("群れな敵 (arg_data 0x%04x)(chNum(%d) ptn(%d) svNum(%d) type(%d))\n", thisx->params, this->chNum,
|
||||
this->ptn, this->svNum, this->type);
|
||||
if (ObjMure_GetMaxChildSpawns(this) <= 0) {
|
||||
osSyncPrintf("Warning : 個体数が設定されていません(%s %d)(arg_data 0x%04x)\n", "../z_obj_mure.c", 268,
|
||||
thisx->params);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B99358.s")
|
||||
void ObjMure_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B9942C.s")
|
||||
s32 ObjMure_GetMaxChildSpawns(ObjMure* this) {
|
||||
if (this->chNum == 0) {
|
||||
return sMaxChildSpawns[this->ptn];
|
||||
}
|
||||
return this->chNum;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B995A4.s")
|
||||
void ObjMure_GetSpawnPos(Vec3f* outPos, Vec3f* inPos, s32 ptn, s32 idx) {
|
||||
if (ptn >= 4) {
|
||||
osSyncPrintf("おかしなの (%s %d)\n", "../z_obj_mure.c", 307);
|
||||
}
|
||||
*outPos = *inPos;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B997CC.s")
|
||||
void ObjMure_SpawnActors0(ObjMure* this, GlobalContext* globalCtx) {
|
||||
ActorContext* ac;
|
||||
s32 i;
|
||||
Vec3f pos;
|
||||
s32 pad;
|
||||
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/func_80B99950.s")
|
||||
for (i = 0; i < maxChildren; i++) {
|
||||
if (this->children[i] != NULL) {
|
||||
// Translation: "Error: I already have a child(%s %d)(arg_data 0x%04x)
|
||||
osSyncPrintf("Error : 既に子供がいる(%s %d)(arg_data 0x%04x)\n", "../z_obj_mure.c", 333,
|
||||
this->actor.params);
|
||||
}
|
||||
switch (this->childrenStates[i]) {
|
||||
case OBJMURE_CHILD_STATE_1:
|
||||
break;
|
||||
case OBJMURE_CHILD_STATE_2:
|
||||
ac = &globalCtx->actorCtx;
|
||||
ObjMure_GetSpawnPos(&pos, &this->actor.world.pos, this->ptn, i);
|
||||
this->children[i] =
|
||||
Actor_Spawn(ac, 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]);
|
||||
if (this->children[i] != NULL) {
|
||||
this->children[i]->flags |= 0x800;
|
||||
this->children[i]->room = this->actor.room;
|
||||
} else {
|
||||
osSyncPrintf("warning 発生失敗 (%s %d)\n", "../z_obj_mure.c", 359);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ac = &globalCtx->actorCtx;
|
||||
ObjMure_GetSpawnPos(&pos, &this->actor.world.pos, this->ptn, i);
|
||||
this->children[i] =
|
||||
Actor_Spawn(ac, 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]);
|
||||
if (this->children[i] != NULL) {
|
||||
this->children[i]->room = this->actor.room;
|
||||
} else {
|
||||
osSyncPrintf("warning 発生失敗 (%s %d)\n", "../z_obj_mure.c", 382);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_Obj_Mure/ObjMure_Update.s")
|
||||
void ObjMure_SpawnActors1(ObjMure* this, GlobalContext* globalCtx) {
|
||||
ActorContext* ac = (ActorContext*)globalCtx; // fake match
|
||||
Actor* actor = &this->actor;
|
||||
Vec3f spawnPos;
|
||||
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < maxChildren; i++) {
|
||||
if (this->children[i] != NULL) {
|
||||
osSyncPrintf("Error : 既に子供がいる(%s %d)(arg_data 0x%04x)\n", "../z_obj_mure.c", 407, actor->params);
|
||||
}
|
||||
ac = &globalCtx->actorCtx;
|
||||
ObjMure_GetSpawnPos(&spawnPos, &actor->world.pos, this->ptn, i);
|
||||
this->children[i] = Actor_Spawn(ac, globalCtx, sSpawnActorIds[this->type], spawnPos.x, spawnPos.y, spawnPos.z,
|
||||
actor->world.rot.x, actor->world.rot.y, actor->world.rot.z,
|
||||
(this->type == 4 && i == 0) ? 1 : sSpawnParams[this->type]);
|
||||
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_1;
|
||||
osSyncPrintf("warning 発生失敗 (%s %d)\n", "../z_obj_mure.c", 438);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjMure_SpawnActors(ObjMure* this, GlobalContext* globalCtx) {
|
||||
switch (this->svNum) {
|
||||
case 0:
|
||||
ObjMure_SpawnActors0(this, globalCtx);
|
||||
break;
|
||||
case 1:
|
||||
ObjMure_SpawnActors1(this, globalCtx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjMure_KillActorsImpl(ObjMure* this, GlobalContext* globalCtx) {
|
||||
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
|
||||
s32 i;
|
||||
|
||||
for (i = 0; i < maxChildren; i++) {
|
||||
switch (this->childrenStates[i]) {
|
||||
case OBJMURE_CHILD_STATE_1:
|
||||
this->children[i] = NULL;
|
||||
break;
|
||||
case OBJMURE_CHILD_STATE_2:
|
||||
if (this->children[i] != NULL) {
|
||||
Actor_Kill(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_Kill(this->children[i]);
|
||||
this->children[i] = NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjMure_KillActors(ObjMure* this, GlobalContext* globalCtx) {
|
||||
ObjMure_KillActorsImpl(this, globalCtx);
|
||||
}
|
||||
|
||||
void ObjMure_CheckChildren(ObjMure* this, GlobalContext* globalCtx) {
|
||||
s32 maxChildren = ObjMure_GetMaxChildSpawns(this);
|
||||
s32 i;
|
||||
|
||||
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->children[i]->flags & 0x800) {
|
||||
this->childrenStates[i] = OBJMURE_CHILD_STATE_2;
|
||||
}
|
||||
} else {
|
||||
this->childrenStates[i] = OBJMURE_CHILD_STATE_1;
|
||||
this->children[i] = NULL;
|
||||
}
|
||||
} else if (this->childrenStates[i] == OBJMURE_CHILD_STATE_2 && this->children[i]->update == NULL) {
|
||||
this->childrenStates[i] = OBJMURE_CHILD_STATE_1;
|
||||
this->children[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjMure_InitialAction(ObjMure* this, GlobalContext* globalCtx) {
|
||||
this->actionFunc = ObjMure_CulledState;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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_1A4 <= 0) {
|
||||
if (this->unk_1A6) {
|
||||
this->unk_1A6 = false;
|
||||
ObjMure_SetFollowTargets(this, (Rand_ZeroOne() * 0.5f) + 0.1f);
|
||||
if (this->actor.xzDistToPlayer < 60.0f) {
|
||||
this->unk_1A4 = (s16)(Rand_ZeroOne() * 5.5f) + 4;
|
||||
} else {
|
||||
this->unk_1A4 = (s16)(Rand_ZeroOne() * 40.5f) + 4;
|
||||
}
|
||||
} else {
|
||||
this->unk_1A6 = true;
|
||||
if (this->actor.xzDistToPlayer < 60.0f) {
|
||||
this->unk_1A4 = (s16)(Rand_ZeroOne() * 10.5f) + 4;
|
||||
ObjMure_SetFollowTargets(this, (Rand_ZeroOne() * 0.2f) + 0.8f);
|
||||
} else {
|
||||
this->unk_1A4 = (s16)(Rand_ZeroOne() * 10.5f) + 4;
|
||||
ObjMure_SetFollowTargets(this, (Rand_ZeroOne() * 0.2f) + 0.6f);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this->actor.xzDistToPlayer < 120.0f) {
|
||||
this->unk_1A8++;
|
||||
} else {
|
||||
this->unk_1A8 = 0;
|
||||
}
|
||||
if (this->unk_1A8 >= 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_1A4 <= 0) {
|
||||
if (this->unk_1A6) {
|
||||
this->unk_1A6 = false;
|
||||
ObjMure_SetFollowTargets(this, Rand_ZeroOne() * 0.2f);
|
||||
if (this->actor.xzDistToPlayer < 60.0f) {
|
||||
this->unk_1A4 = (s16)(Rand_ZeroOne() * 5.5f) + 4;
|
||||
} else {
|
||||
this->unk_1A4 = (s16)(Rand_ZeroOne() * 40.5f) + 4;
|
||||
}
|
||||
} else {
|
||||
this->unk_1A6 = true;
|
||||
ObjMure_SetFollowTargets(this, Rand_ZeroOne() * 0.7f);
|
||||
this->unk_1A4 = (s16)(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_1A4 > 0) {
|
||||
this->unk_1A4--;
|
||||
}
|
||||
this->actionFunc(this, globalCtx);
|
||||
}
|
||||
|
|
|
@ -6,9 +6,22 @@
|
|||
|
||||
struct ObjMure;
|
||||
|
||||
typedef void (*ObjMureActionFunc)(struct ObjMure*, GlobalContext*);
|
||||
|
||||
#define OBJMURE_MAX_SPAWNS 15
|
||||
|
||||
typedef struct ObjMure {
|
||||
/* 0x0000 */ Actor actor;
|
||||
/* 0x014C */ char unk_14C[0x60];
|
||||
/* 0x014C */ ObjMureActionFunc actionFunc;
|
||||
/* 0x0150 */ s16 chNum;
|
||||
/* 0x0152 */ s16 ptn;
|
||||
/* 0x0154 */ s16 svNum;
|
||||
/* 0x0156 */ s16 type;
|
||||
/* 0x0158 */ Actor* children[OBJMURE_MAX_SPAWNS];
|
||||
/* 0x0194 */ u8 childrenStates[OBJMURE_MAX_SPAWNS];
|
||||
/* 0x01A4 */ s16 unk_1A4;
|
||||
/* 0x01A6 */ s16 unk_1A6;
|
||||
/* 0x01A8 */ s16 unk_1A8;
|
||||
} ObjMure; // size = 0x01AC
|
||||
|
||||
extern const ActorInit Obj_Mure_InitVars;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue