summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Overton <tom-overton@users.noreply.github.com>2021-08-23 19:14:18 -0700
committerGitHub <noreply@github.com>2021-08-23 22:14:18 -0400
commitf0749d583cba45b0fa29e45bded267ea50ac095f (patch)
treecca5961d95197ca1f2f24d0b4698fc5f1d7a19cb /src
parent04343a12025c02030450b60f4de0698c04058567 (diff)
Obj_Kibako2 OK (#249)
* Data migrated and ObjKibako2_Init OK * ObjKibako2_Destroy OK * func_8098EC68 OK * Commit what I have on Update as I figure it out * Name skulltulaNoiseTimer and get a little closer to matching Update * Wrap Update in NON_MATCHING for now * Get this ready to push up * func_8098ED20 OK (but it's not an actionFunc???) * ObjKibako2_Draw OK * func_8098E9C4 OK * Turns out globalCtx *is* needed * func_8098E8A8 OK * Save my progress on func_8098E5C0 for now * func_8098E900 OK * func_8098EB78 OK * Clean up some if-conditionals * Delete pointless forward declaration * ObjKibako2_Break OK * Update names to match OoT equivalent * func_8098E5C0 OK (though a little weird) * ObjKibako2_Update OK * Clean, document, and name ObjKibako2_ShouldBreak * Clean and name ObjKibako2_ContainsSkulltula * Some more cleanup * Why did I mix snake case with camel case lol * Update spec now that everything matches * Actually rename the data * sn/cs -> sin/cos * Use true/false in ObjKibako2_ShouldBreak * Use the AC_HIT macro and don't use the temp where it isn't needed * Use macro and enum for contents * Get rid of fake temp in Init * Macros for collectible ID/Flag * 0xFFFD -> ~AC_HIT * In macros, x -> this * Just kidding, use thisx for macros * Add description to the top of C file * Run ./format.sh after installing clang-format-11 * char -> UNK_TYPE1 * Remove unnecessary struct padding * Initialize thisPos at the same time it's declared * Clean up parentheses for bitwise operations to make it clearer what they do * Clean up control flow in ObjKibako2_Idle * Remove extraneous parentheses * Move instantialization up in ObjKibako2_ContainsSkulltula * Move tempRand instantiation up in ObjKibako2_Break * Move collectible instantiation up in ObjKibako2_SpawnCollectible * Remove extra brackets * Remove extra brackets (again) * Move contents instantiation up in ObjKibako2_Init
Diffstat (limited to 'src')
-rw-r--r--src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c261
-rw-r--r--src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h17
2 files changed, 236 insertions, 42 deletions
diff --git a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c
index 36c01554c..eb5fa284c 100644
--- a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c
+++ b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c
@@ -1,4 +1,11 @@
+/*
+ * File: z_obj_kibako2.c
+ * Overlay: ovl_Obj_Kibako2
+ * Description: Large wooden crate
+ */
+
#include "z_obj_kibako2.h"
+#include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h"
#define FLAGS 0x00000000
@@ -8,8 +15,9 @@ void ObjKibako2_Init(Actor* thisx, GlobalContext* globalCtx);
void ObjKibako2_Destroy(Actor* thisx, GlobalContext* globalCtx);
void ObjKibako2_Update(Actor* thisx, GlobalContext* globalCtx);
void ObjKibako2_Draw(Actor* thisx, GlobalContext* globalCtx);
+void ObjKibako2_Idle(ObjKibako2* this, GlobalContext* globalCtx);
+void ObjKibako2_Kill(ObjKibako2* this, GlobalContext* globalCtx);
-#if 0
const ActorInit Obj_Kibako2_InitVars = {
ACTOR_OBJ_KIBAKO2,
ACTORCAT_BG,
@@ -22,50 +30,225 @@ const ActorInit Obj_Kibako2_InitVars = {
(ActorFunc)ObjKibako2_Draw,
};
-// static ColliderCylinderInit sCylinderInit = {
-static ColliderCylinderInit D_8098EE60 = {
- { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_2, COLSHAPE_CYLINDER, },
- { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x80000508, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
+static ColliderCylinderInit sCylinderInit = {
+ {
+ COLTYPE_NONE,
+ AT_NONE,
+ AC_ON | AC_TYPE_PLAYER,
+ OC1_NONE,
+ OC2_TYPE_2,
+ COLSHAPE_CYLINDER,
+ },
+ {
+ ELEMTYPE_UNK0,
+ { 0x00000000, 0x00, 0x00 },
+ { 0x80000508, 0x00, 0x00 },
+ TOUCH_NONE | TOUCH_SFX_NORMAL,
+ BUMP_ON,
+ OCELEM_NONE,
+ },
{ 31, 48, 0, { 0, 0, 0 } },
};
-// static InitChainEntry sInitChain[] = {
-static InitChainEntry D_8098EE8C[] = {
+static InitChainEntry sInitChain[] = {
ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE),
ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP),
};
-#endif
-
-extern ColliderCylinderInit D_8098EE60;
-extern InitChainEntry D_8098EE8C[];
-
-extern UNK_TYPE D_06000960;
-extern UNK_TYPE D_06000B70;
-extern UNK_TYPE D_06001040;
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/func_8098E5C0.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/func_8098E62C.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/func_8098E8A8.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/func_8098E900.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/func_8098E9C4.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/ObjKibako2_Init.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/ObjKibako2_Destroy.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/func_8098EB78.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/func_8098EC68.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/func_8098ED20.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/ObjKibako2_Update.s")
-
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kibako2/ObjKibako2_Draw.s")
+extern Gfx D_06000960[];
+extern CollisionHeader D_06000B70;
+extern Gfx D_06001040[];
+
+s32 ObjKibako2_ContainsSkulltula(ObjKibako2* this, GlobalContext* globalCtx) {
+ s32 actorSpawnParam = KIBAKO2_SKULLTULA_SPAWN_PARAM(&this->dyna.actor);
+ s32 flag = -1;
+
+ if ((u16)actorSpawnParam & 3) {
+ flag = ((actorSpawnParam & 0x3FC) >> 2) & 0xFF;
+ }
+ return !(flag >= 0 && Actor_GetChestFlag(globalCtx, flag));
+}
+
+void ObjKibako2_Break(ObjKibako2* this, GlobalContext* globalCtx) {
+ s32 pad[2];
+ Vec3f* thisPos = &this->dyna.actor.world.pos;
+ Vec3f pos;
+ Vec3f velocity;
+ s16 angle;
+ s32 i;
+
+ for (i = 0, angle = 0; i < 0x10; i++, angle += 0x4E20) {
+ f32 sin = Math_SinS(angle);
+ f32 cos = Math_CosS(angle);
+ f32 tempRand = Rand_ZeroOne() * 30.0f;
+ s32 phi_s0;
+
+ pos.x = sin * tempRand;
+ pos.y = (Rand_ZeroOne() * 10.0f) + 2.0f;
+ pos.z = cos * tempRand;
+ velocity.x = pos.x * 0.2f;
+ velocity.y = (Rand_ZeroOne() * 10.0f) + 2.0f;
+ velocity.z = pos.z * 0.2f;
+ pos.x += thisPos->x;
+ pos.y += thisPos->y;
+ pos.z += thisPos->z;
+ tempRand = Rand_ZeroOne();
+ if (tempRand < 0.05f) {
+ phi_s0 = 0x60;
+ } else if (tempRand < 0.7f) {
+ phi_s0 = 0x40;
+ } else {
+ phi_s0 = 0x20;
+ }
+ EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &pos, -200, phi_s0, 28, 2, 0, (Rand_ZeroOne() * 30.0f) + 5.0f,
+ 0, 0, 70, KAKERA_COLOR_NONE, OBJECT_KIBAKO2, D_06001040);
+ }
+ func_800BBFB0(globalCtx, thisPos, 90.0f, 6, 100, 160, 1);
+}
+
+void ObjKibako2_SpawnCollectible(ObjKibako2* this, GlobalContext* globalCtx) {
+ s32 collectible = func_800A8150(KIBAKO2_COLLECTIBLE_ID(&this->dyna.actor));
+
+ if (collectible >= 0) {
+ Item_DropCollectible(globalCtx, &this->dyna.actor.world.pos,
+ collectible | KIBAKO2_COLLECTIBLE_FLAG(&this->dyna.actor) << 8);
+ }
+}
+
+void ObjKibako2_SpawnSkulltula(ObjKibako2* this, GlobalContext* globalCtx) {
+ s16 yRotation;
+ s32 actorSpawnParam;
+ Actor* skulltula;
+
+ if (ObjKibako2_ContainsSkulltula(this, globalCtx)) {
+ actorSpawnParam = KIBAKO2_SKULLTULA_SPAWN_PARAM(&this->dyna.actor);
+ yRotation = ((u32)Rand_Next() >> 0x11) + this->dyna.actor.yawTowardsPlayer + 0xC000;
+ skulltula =
+ Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_SW, this->dyna.actor.world.pos.x,
+ this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, yRotation, 0, actorSpawnParam);
+ if (skulltula != NULL) {
+ skulltula->parent = &this->dyna.actor;
+ skulltula->velocity.y = 13.0f;
+ skulltula->speedXZ = 0.0f;
+ }
+ }
+}
+
+void ObjKibako2_SpawnContents(ObjKibako2* this, GlobalContext* globalCtx) {
+ if (KIBAKO2_CONTENTS(&this->dyna.actor) == CONTENTS_COLLECTIBLE) {
+ ObjKibako2_SpawnCollectible(this, globalCtx);
+ } else {
+ ObjKibako2_SpawnSkulltula(this, globalCtx);
+ }
+}
+
+void ObjKibako2_Init(Actor* thisx, GlobalContext* globalCtx) {
+ ObjKibako2* this = THIS;
+ s32 pad;
+ ObjKibako2Contents contents = KIBAKO2_CONTENTS(&this->dyna.actor);
+
+ BcCheck3_BgActorInit(&this->dyna, 0);
+ Collider_InitCylinder(globalCtx, &this->collider);
+ Actor_ProcessInitChain(&this->dyna.actor, sInitChain);
+ BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000B70);
+ Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit);
+ Collider_UpdateCylinder(&this->dyna.actor, &this->collider);
+ this->dyna.actor.home.rot.z = 0;
+ this->dyna.actor.world.rot.z = 0;
+ this->dyna.actor.shape.rot.z = 0;
+ this->dyna.actor.world.rot.x = 0;
+ this->dyna.actor.shape.rot.x = 0;
+ if (contents == CONTENTS_COLLECTIBLE) {
+ if (func_800A81A4(globalCtx, KIBAKO2_COLLECTIBLE_ID(&this->dyna.actor),
+ KIBAKO2_COLLECTIBLE_FLAG(&this->dyna.actor))) {
+ this->unk_1AC = 1;
+ this->dyna.actor.flags |= 0x10;
+ }
+ }
+ if ((contents != CONTENTS_SKULLTULA) || !ObjKibako2_ContainsSkulltula(this, globalCtx)) {
+ this->skulltulaNoiseTimer = -1;
+ }
+ this->actionFunc = ObjKibako2_Idle;
+}
+
+void ObjKibako2_Destroy(Actor* thisx, GlobalContext* globalCtx) {
+ ObjKibako2* this = THIS;
+
+ Collider_DestroyCylinder(globalCtx, &this->collider);
+ BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
+}
+
+s32 ObjKibako2_ShouldBreak(ObjKibako2* this) {
+ u8 acFlags = this->collider.base.acFlags;
+ s32 shouldBreak = false;
+
+ if (this->collider.base.acFlags & AC_HIT) {
+ Actor* ac = this->collider.base.ac;
+ this->collider.base.acFlags = acFlags & ~AC_HIT;
+ if (ac != NULL) {
+ if (this->collider.info.acHitInfo->toucher.dmgFlags & (1 << 31)) {
+ // Powder Keg
+ if (Math3D_DistanceSquared(&this->dyna.actor.world.pos, &ac->world.pos) < SQ(160.0f)) {
+ shouldBreak = true;
+ }
+ } else if (this->collider.info.acHitInfo->toucher.dmgFlags & (1 << 3)) {
+ // Explosives
+ if (Math3D_DistanceSquared(&this->dyna.actor.world.pos, &ac->world.pos) < SQ(100.0f)) {
+ shouldBreak = true;
+ }
+ } else if (this->collider.info.acHitInfo->toucher.dmgFlags & (1 << 8 | 1 << 10)) {
+ // Goron Punch/Pound
+ shouldBreak = true;
+ }
+ }
+ } else if (this->dyna.actor.home.rot.z != 0) {
+ shouldBreak = true;
+ }
+ return shouldBreak;
+}
+
+void ObjKibako2_Idle(ObjKibako2* this, GlobalContext* globalCtx) {
+ if (ObjKibako2_ShouldBreak(this)) {
+ ObjKibako2_Break(this, globalCtx);
+ func_800F0568(globalCtx, &this->dyna.actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK);
+ this->dyna.actor.flags |= 0x10;
+ func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
+ this->dyna.actor.draw = NULL;
+ this->actionFunc = ObjKibako2_Kill;
+ } else if (this->dyna.actor.xzDistToPlayer < 600.0f) {
+ CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
+ }
+}
+
+void ObjKibako2_Kill(ObjKibako2* this, GlobalContext* globalCtx) {
+ ObjKibako2_SpawnContents(this, globalCtx);
+ Actor_MarkForDeath(&this->dyna.actor);
+}
+
+void ObjKibako2_Update(Actor* thisx, GlobalContext* globalCtx) {
+ ObjKibako2* this = THIS;
+
+ if (this->unk_1AC != 0) {
+ globalCtx->actorCtx.unk5 |= 8;
+ }
+
+ if (this->skulltulaNoiseTimer >= 0) {
+ if (this->skulltulaNoiseTimer == 0) {
+ Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EN_STALGOLD_ROLL);
+ if (Rand_ZeroOne() < 0.1f) {
+ this->skulltulaNoiseTimer = Rand_S16Offset(40, 80);
+ } else {
+ this->skulltulaNoiseTimer = 8;
+ }
+ } else {
+ this->skulltulaNoiseTimer--;
+ }
+ }
+ this->actionFunc(this, globalCtx);
+}
+
+void ObjKibako2_Draw(Actor* thisx, GlobalContext* globalCtx) {
+ func_800BDFC0(globalCtx, D_06000960);
+}
diff --git a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h
index 5f84912b2..b6de7da89 100644
--- a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h
+++ b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h
@@ -3,15 +3,26 @@
#include "global.h"
+#define KIBAKO2_COLLECTIBLE_ID(thisx) ((thisx)->params & 0x3F)
+#define KIBAKO2_COLLECTIBLE_FLAG(thisx) (((thisx)->params >> 0x8) & 0x7F)
+#define KIBAKO2_SKULLTULA_SPAWN_PARAM(thisx) ((((thisx)->params & 0x1F) << 2) | 0xFF01)
+#define KIBAKO2_CONTENTS(thisx) (((thisx)->params >> 0xF) & 1)
+
+typedef enum {
+ /* 0 */ CONTENTS_COLLECTIBLE,
+ /* 1 */ CONTENTS_SKULLTULA
+} ObjKibako2Contents;
+
struct ObjKibako2;
typedef void (*ObjKibako2ActionFunc)(struct ObjKibako2*, GlobalContext*);
typedef struct ObjKibako2 {
- /* 0x0000 */ Actor actor;
- /* 0x0144 */ char unk_144[0x64];
+ /* 0x0000 */ DynaPolyActor dyna;
+ /* 0x015C */ ColliderCylinder collider;
/* 0x01A8 */ ObjKibako2ActionFunc actionFunc;
- /* 0x01AC */ char unk_1AC[0x4];
+ /* 0x01AC */ s8 unk_1AC;
+ /* 0x01AD */ s8 skulltulaNoiseTimer;
} ObjKibako2; // size = 0x1B0
extern const ActorInit Obj_Kibako2_InitVars;