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;