From 08ff2a618427bf7f63891853547271d7fc32b11d Mon Sep 17 00:00:00 2001 From: Tom Overton Date: Mon, 11 Jul 2022 20:10:24 -0700 Subject: [PATCH] object_rotlift documented, various cleanup of Deku Flower stuff, finish documentation of ObjRotlift (#879) * Make params-packing macro * Move limb enum to object * Minor deku flower cleanup * Document object_rotlift * Rotlift cleanup and documentation * Respond to review --- assets/xml/objects/gameplay_keep.xml | 44 +++++++++---------- assets/xml/objects/object_rotlift.xml | 28 +++++++----- .../actors/ovl_Dm_Char01/z_dm_char01.c | 7 ++- .../actors/ovl_En_Dekunuts/z_en_dekunuts.c | 4 +- .../actors/ovl_Obj_Etcetera/z_obj_etcetera.c | 30 +++++++++---- .../actors/ovl_Obj_Etcetera/z_obj_etcetera.h | 30 +++---------- .../actors/ovl_Obj_Raillift/z_obj_raillift.c | 4 +- .../actors/ovl_Obj_Rotlift/z_obj_rotlift.c | 38 ++++++++++------ .../actors/ovl_Obj_Rotlift/z_obj_rotlift.h | 7 ++- 9 files changed, 108 insertions(+), 84 deletions(-) diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml index 8317b3ee7f..f0de8666cc 100644 --- a/assets/xml/objects/gameplay_keep.xml +++ b/assets/xml/objects/gameplay_keep.xml @@ -786,17 +786,17 @@ - - - - - - - - - - - + + + + + + + + + + + @@ -810,17 +810,17 @@ - - - - - - - - - - - + + + + + + + + + + + diff --git a/assets/xml/objects/object_rotlift.xml b/assets/xml/objects/object_rotlift.xml index 403f7d3dd9..da5db27d74 100644 --- a/assets/xml/objects/object_rotlift.xml +++ b/assets/xml/objects/object_rotlift.xml @@ -1,16 +1,20 @@  + - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c index 3f3e833829..35fc84ccfd 100644 --- a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c +++ b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c @@ -6,6 +6,7 @@ #include "z_dm_char01.h" #include "objects/object_mtoride/object_mtoride.h" +#include "overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h" #define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) @@ -127,7 +128,8 @@ void DmChar01_Init(Actor* thisx, PlayState* play) { return; } - Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_ETCETERA, 5.0f, 202.0f, 294.0f, 0, 0, 0, 0x80); + Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_ETCETERA, 5.0f, 202.0f, 294.0f, 0, 0, 0, + DEKU_FLOWER_PARAMS(DEKU_FLOWER_TYPE_PINK_WITH_INITIAL_BOUNCE)); DynaPolyActor_Init(&this->dyna, 0); DynaPolyActor_LoadMesh(play, &this->dyna, &object_mtoride_Colheader_00FE5C); @@ -331,7 +333,8 @@ void func_80AA8F2C(DmChar01* this, PlayState* play) { Math_SmoothStepToF(&this->unk_348, 0.0f, 0.01f, 0.5f, 0.4f); if ((s32)this->dyna.actor.world.pos.y >= 0) { D_80AAAE26 = 2; - Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_ETCETERA, 5.0f, 202.0f, 294.0f, 0, 0, 0, 0x80); + Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_ETCETERA, 5.0f, 202.0f, 294.0f, 0, 0, 0, + DEKU_FLOWER_PARAMS(DEKU_FLOWER_TYPE_PINK_WITH_INITIAL_BOUNCE)); this->actionFunc = func_80AA90F4; } } diff --git a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c index e29ac86a87..15ae675a16 100644 --- a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c +++ b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c @@ -5,6 +5,7 @@ */ #include "z_en_dekunuts.h" +#include "overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) @@ -539,7 +540,8 @@ void func_808BE4D4(EnDekunuts* this, PlayState* play) { EffectSsHahen_SpawnBurst(play, &sp40, 3.0f, 0, 12, 3, 15, HAHEN_OBJECT_DEFAULT, 10, NULL); Item_DropCollectibleRandom(play, &this->actor, &this->actor.world.pos, 0xE0); Actor_Spawn(&play->actorCtx, play, ACTOR_OBJ_ETCETERA, this->actor.home.pos.x, this->actor.home.pos.y, - this->actor.home.pos.z, 0, this->actor.home.rot.y, 0, 0x80); + this->actor.home.pos.z, 0, this->actor.home.rot.y, 0, + DEKU_FLOWER_PARAMS(DEKU_FLOWER_TYPE_PINK_WITH_INITIAL_BOUNCE)); EffectSsHahen_SpawnBurst(play, &this->actor.home.pos, 6.0f, 0, 6, 2, 15, OBJECT_DEKUNUTS, 10, gDekuScrubFlowerFragmentDL); Actor_MarkForDeath(&this->actor); diff --git a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c index fb7681f310..ff5a6365ba 100644 --- a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c +++ b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c @@ -5,7 +5,6 @@ */ #include "z_obj_etcetera.h" -#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS (ACTOR_FLAG_10) @@ -80,10 +79,12 @@ void ObjEtcetera_Init(Actor* thisx, PlayState* play) { if ((type < DEKU_FLOWER_TYPE_PINK) || (type >= DEKU_FLOWER_TYPE_MAX)) { type = DEKU_FLOWER_TYPE_PINK; } + objectIndex = Object_GetIndex(&play->objectCtx, objectIds[type]); if (objectIndex >= 0) { this->objIndex = objectIndex; } + pos.x = this->dyna.actor.world.pos.x; pos.y = this->dyna.actor.world.pos.y + 10.0f; pos.z = this->dyna.actor.world.pos.z; @@ -163,6 +164,7 @@ void ObjEtcetera_Idle(ObjEtcetera* this, PlayState* play) { // start of launching this->oscillationTimer = 10; } + this->burrowFlag |= 1; } else { if (this->burrowFlag & 1) { @@ -170,13 +172,16 @@ void ObjEtcetera_Idle(ObjEtcetera* this, PlayState* play) { this->oscillationTimer = 10; ObjEtcetera_StartRustleAnimation(this); } + this->burrowFlag &= ~1; } } + if ((this->collider.base.acFlags & AC_HIT)) { this->oscillationTimer = 10; ObjEtcetera_StartRustleAnimation(this); } + ObjEtcetera_DoNormalOscillation(this, play); } @@ -186,10 +191,12 @@ void ObjEtcetera_PlayRustleAnimation(ObjEtcetera* this, PlayState* play) { } else { this->burrowFlag &= ~1; } + if (SkelAnime_Update(&this->skelAnime)) { this->dyna.actor.draw = ObjEtcetera_DrawIdle; this->actionFunc = ObjEtcetera_Idle; } + ObjEtcetera_DoNormalOscillation(this, play); } @@ -210,7 +217,9 @@ void ObjEtcetera_DoBounceOscillation(ObjEtcetera* this, PlayState* play) { } else { this->burrowFlag &= ~1; } + SkelAnime_Update(&this->skelAnime); + if (this->oscillationTimer > 0) { this->oscillationTimer--; } else { @@ -222,6 +231,7 @@ void ObjEtcetera_DoBounceOscillation(ObjEtcetera* this, PlayState* play) { this->bounceOscillationScale = 0.0f; return; } + this->bounceOscillationScale *= 0.8f; this->bounceOscillationScale -= (this->dyna.actor.scale.x - 0.01f) * 0.4f; scaleTemp = dyna->actor.scale.x + this->bounceOscillationScale; @@ -251,24 +261,26 @@ void ObjEtcetera_Setup(ObjEtcetera* this, PlayState* play) { Actor_SetObjectDependency(play, &this->dyna.actor); DynaPolyActor_Init(&this->dyna, 1); thisCollisionHeader = collisionHeaders[type]; - if (thisCollisionHeader != 0) { + if (thisCollisionHeader != NULL) { CollisionHeader_GetVirtual(thisCollisionHeader, &colHeader); } + this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader); type = DEKU_FLOWER_TYPE(&this->dyna.actor); switch (type) { case DEKU_FLOWER_TYPE_PINK: - case DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB: + case DEKU_FLOWER_TYPE_PINK_WITH_INITIAL_BOUNCE: SkelAnime_Init(play, &this->skelAnime, &gPinkDekuFlowerSkel, &gDekuFlowerBounceAnim, this->jointTable, - this->morphTable, DEKU_FLOWER_LIMB_MAX); + this->morphTable, PINK_DEKU_FLOWER_LIMB_MAX); this->dList = gPinkDekuFlowerIdleDL; break; + case DEKU_FLOWER_TYPE_GOLD: - case DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB: + case DEKU_FLOWER_TYPE_GOLD_WITH_INITIAL_BOUNCE: this->dList = gGoldDekuFlowerIdleDL; SkelAnime_Init(play, &this->skelAnime, &gGoldDekuFlowerSkel.sh, &gDekuFlowerBounceAnim, - this->jointTable, this->morphTable, DEKU_FLOWER_LIMB_MAX); + this->jointTable, this->morphTable, GOLD_DEKU_FLOWER_LIMB_MAX); this->collider.dim.height = 20; break; } @@ -284,8 +296,9 @@ void ObjEtcetera_Setup(ObjEtcetera* this, PlayState* play) { this->dyna.actor.focus.pos.y = this->dyna.actor.home.pos.y + 10.0f; this->dyna.actor.targetMode = 3; break; - case DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB: - case DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB: + + case DEKU_FLOWER_TYPE_PINK_WITH_INITIAL_BOUNCE: + case DEKU_FLOWER_TYPE_GOLD_WITH_INITIAL_BOUNCE: Animation_Change(&this->skelAnime, &gDekuFlowerBounceAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gDekuFlowerBounceAnim), 2, 0.0f); this->dyna.actor.draw = ObjEtcetera_DrawAnimated; @@ -311,6 +324,7 @@ void ObjEtcetera_Update(Actor* thisx, PlayState* play) { func_800FAAB4(play, SurfaceType_GetLightSettingIndex(&play->colCtx, floorPoly, floorBgId)); } } + this->actionFunc(this, play); CollisionCheck_SetAC(play, &play->colChkCtx, &this->collider.base); } diff --git a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h index 83bcba080d..33810ae06a 100644 --- a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h +++ b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h @@ -2,37 +2,19 @@ #define Z_OBJ_ETCETERA_H #include "global.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define DEKU_FLOWER_TYPE(thisx) (((thisx)->params & 0xFF80) >> 7) +#define DEKU_FLOWER_PARAMS(type) (((type) << 7) & 0xFF80) typedef enum { /* 0 */ DEKU_FLOWER_TYPE_PINK, - /* 1 */ DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB, + /* 1 */ DEKU_FLOWER_TYPE_PINK_WITH_INITIAL_BOUNCE, /* 2 */ DEKU_FLOWER_TYPE_GOLD, - /* 3 */ DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB, + /* 3 */ DEKU_FLOWER_TYPE_GOLD_WITH_INITIAL_BOUNCE, /* 4 */ DEKU_FLOWER_TYPE_MAX, } DekuFlowerType; -/** - * For the petal/leaf directions, "back" is negative and "front" is positive - * on the flower's local Z-axis. "Left" and "right" are relative to the front - * and back. - */ -typedef enum { - /* 0 */ DEKU_FLOWER_LIMB_NONE, - /* 1 */ DEKU_FLOWER_LIMB_BASE, - /* 2 */ DEKU_FLOWER_LIMB_CENTER, - /* 3 */ DEKU_FLOWER_LIMB_BACK_PETAL_OR_LEAF, - /* 4 */ DEKU_FLOWER_LIMB_FRONT_PETAL_OR_LEAF, - /* 5 */ DEKU_FLOWER_LIMB_FRONT_RIGHT_PETAL, - /* 6 */ DEKU_FLOWER_LIMB_BACK_RIGHT_PETAL, - /* 7 */ DEKU_FLOWER_LIMB_RIGHT_PETAL_OR_LEAF, - /* 8 */ DEKU_FLOWER_LIMB_FRONT_LEFT_PETAL, - /* 9 */ DEKU_FLOWER_LIMB_LEFT_PETAL_OR_LEAF, - /* 10 */ DEKU_FLOWER_LIMB_BACK_LEFT_PETAL, - /* 11 */ DEKU_FLOWER_LIMB_MAX, -} DekuFlowerLimbs; - struct ObjEtcetera; typedef void (*ObjEtceteraActionFunc)(struct ObjEtcetera*, PlayState*); @@ -41,8 +23,8 @@ typedef struct ObjEtcetera { /* 0x000 */ DynaPolyActor dyna; /* 0x15C */ SkelAnime skelAnime; /* 0x1A0 */ ColliderCylinder collider; - /* 0x1EC */ Vec3s jointTable[DEKU_FLOWER_LIMB_MAX]; - /* 0x22E */ Vec3s morphTable[DEKU_FLOWER_LIMB_MAX]; + /* 0x1EC */ Vec3s jointTable[PINK_DEKU_FLOWER_LIMB_MAX]; + /* 0x22E */ Vec3s morphTable[PINK_DEKU_FLOWER_LIMB_MAX]; /* 0x270 */ f32 bounceOscillationScale; /* 0x274 */ s16 oscillationTimer; /* 0x276 */ u16 burrowFlag; diff --git a/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c b/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c index 05349cfacc..616fb341c6 100644 --- a/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c +++ b/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c @@ -6,6 +6,7 @@ #include "z_obj_raillift.h" #include "objects/object_raillift/object_raillift.h" +#include "overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h" #define FLAGS (ACTOR_FLAG_10) @@ -74,7 +75,8 @@ void ObjRaillift_Init(Actor* thisx, PlayState* play) { } if (type == DEKU_FLOWER_PLATFORM) { Actor_SpawnAsChild(&play->actorCtx, thisx, play, ACTOR_OBJ_ETCETERA, thisx->world.pos.x, thisx->world.pos.y, - thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y, thisx->shape.rot.z, 0); + thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y, thisx->shape.rot.z, + DEKU_FLOWER_PARAMS(DEKU_FLOWER_TYPE_PINK)); if (isColorful) { thisx->draw = ObjRaillift_DrawDekuFlowerPlatformColorful; } else { diff --git a/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.c b/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.c index 2d984f7269..9d3476ff67 100644 --- a/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.c +++ b/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.c @@ -6,6 +6,7 @@ #include "z_obj_rotlift.h" #include "objects/object_rotlift/object_rotlift.h" +#include "overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h" #define FLAGS 0x00000000 @@ -38,14 +39,14 @@ const ActorInit Obj_Rotlift_InitVars = { struct ModelInfo sModelInfo[] = { { - object_rotlift_DL_000400, - object_rotlift_Matanimheader_001F98, - &object_rotlift_Colheader_002190, + gDekuMoonDungeonRotatingPlatformsDL, + gDekuMoonDungeonRotatingPlatformsUnusedTexAnim, + &gDekuMoonDungeonRotatingPlatformsCol, }, { - object_rotlift_DL_002CE0, - object_rotlift_Matanimheader_004A08, - &object_rotlift_Colheader_004DF0, + gDekuMoonDungeonRotatingSpikesDL, + gDekuMoonDungeonRotatingSpikesUnusedTexAnim, + &gDekuMoonDungeonRotatingSpikesCol, }, }; @@ -64,6 +65,7 @@ void ObjRotlift_MoveDekuFlowers(ObjRotlift* this) { for (i = 0; i < ARRAY_COUNT(this->dekuFlowers); i++, dekuFlower++) { curDekuFlower = *dekuFlower; + if (curDekuFlower->dyna.actor.update == NULL) { *dekuFlower = NULL; } else { @@ -74,6 +76,7 @@ void ObjRotlift_MoveDekuFlowers(ObjRotlift* this) { this->dyna.actor.world.pos.z + posOffset * Math_CosS(this->dyna.actor.shape.rot.y); curDekuFlower->dyna.actor.shape.rot.y = this->dyna.actor.shape.rot.y; } + posOffset -= 600.0f; } } @@ -82,26 +85,32 @@ void ObjRotlift_Init(Actor* thisx, PlayState* play2) { PlayState* play = play2; ObjRotlift* this = THIS; s32 type = OBJROTLIFT_GET_TYPE(&this->dyna.actor); - s32 dekuFlowerType; + s32 dekuFlowerParams; s32 i; ModelInfo* modelInfo; ObjEtcetera** dekuFlowers; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - if (type == 0) { + if (type == OBJROTLIFT_TYPE_PLATFORMS) { for (dekuFlowers = this->dekuFlowers, i = 0; i < ARRAY_COUNT(this->dekuFlowers); i++, dekuFlowers++) { - if (!OBJROTLIFT_GET_4000(thisx) || (i != 0)) { - dekuFlowerType = 0; + // Depending on the params, the platforms can be configured in one of two ways: + // 1. Pink Deku Flower, Pink Deku Flower + // 2. Gold Deku Flower, Pink Deku Flower + if (!OBJROTLIFT_FIRST_DEKU_FLOWER_IS_GOLD(thisx) || (i != 0)) { + dekuFlowerParams = DEKU_FLOWER_PARAMS(DEKU_FLOWER_TYPE_PINK); } else { - dekuFlowerType = 0x100; + dekuFlowerParams = DEKU_FLOWER_PARAMS(DEKU_FLOWER_TYPE_GOLD); } + *dekuFlowers = (ObjEtcetera*)Actor_SpawnAsChild( &play->actorCtx, &this->dyna.actor, play, ACTOR_OBJ_ETCETERA, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, this->dyna.actor.shape.rot.x, - this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, dekuFlowerType); + this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, dekuFlowerParams); } + ObjRotlift_MoveDekuFlowers(this); } + DynaPolyActor_Init(&this->dyna, 3); modelInfo = &sModelInfo[type]; @@ -120,14 +129,16 @@ void ObjRotlift_Update(Actor* thisx, PlayState* play) { s16 angShift; s32 angVelocity; - if (OBJROTLIFT_GET_TYPE(&this->dyna.actor) == 0) { + if (OBJROTLIFT_GET_TYPE(&this->dyna.actor) == OBJROTLIFT_TYPE_PLATFORMS) { ObjRotlift_MoveDekuFlowers(this); } + if (thisx->params >= 0) { angVelocity = -0xC8; } else { angVelocity = 0xC8; } + angShift = angVelocity; this->dyna.actor.shape.rot.y += angShift; } @@ -137,6 +148,7 @@ void ObjRotlift_Draw(Actor* thisx, PlayState* play) { ObjRotlift* this = THIS; ModelInfo* modelInfo = &sModelInfo[OBJROTLIFT_GET_TYPE(&this->dyna.actor)]; + // Neither of the displaylists reference other segments, so this call is ultimately pointless. AnimatedMat_Draw(play, modelInfo->animMat); Gfx_DrawDListOpa(play, modelInfo->dList); } diff --git a/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.h b/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.h index cc627a2955..46cbef0eed 100644 --- a/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.h +++ b/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.h @@ -6,7 +6,12 @@ #include "overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h" #define OBJROTLIFT_GET_TYPE(thisx) ((thisx)->params & 1) -#define OBJROTLIFT_GET_4000(thisx) ((thisx)->params & 0x4000) +#define OBJROTLIFT_FIRST_DEKU_FLOWER_IS_GOLD(thisx) ((thisx)->params & 0x4000) + +typedef enum { + /* 0 */ OBJROTLIFT_TYPE_PLATFORMS, + /* 1 */ OBJROTLIFT_TYPE_SPIKES, +} ObjRotliftType; struct ObjRotlift;