mirror of
https://github.com/zeldaret/mm.git
synced 2024-11-23 12:59:44 +00:00
Obj_Etcetera (Deku Flower) OK and somewhat documented (#326)
* Migrate data to C * ObjEtcetera_Init OK * ObjEtcetera_Destroy OK * ObjEtcetera_Update OK * func_80A7C690 OK * func_80A7C718 OK * func_80A7C168 OK * func_80A7BE8C OK * Make the draw functions take Actor* * CollisionCheck_SetAC should take a Collider * func_80A7BDC8 OK (with silly dummy label meme) * func_80A7C1F0 OK * unk_276 is almost certainly a u16 since I constantly have to cast it, so just retype it * func_80A7BF08 OK * Some minor cleanup * Convert D_80A7C80C to array of CollisionHeader* * Finish defining struct to prepare for func_80A7C308 * func_80A7C308 OK * Move gameplay_keep symbols to variables.h * Explanatory comment at the top * Type gameplay_keep animation headers too * Update the spec (why do I always forget this?) * Rename func_80A7BDC8 to ObjEtcetera_PerformFlutter (name still up for debate) * Name objIndex * Document the types of flowers * Name displayListPtr * Name burrowFlag and provide a macro * Name specialFlutterScale and clean up some things with newer understanding * Give the draw functions (bad) names * Name ObjEtcetera_Idle * Name ObjEtcetera_Setup (name sucks but oh well lol) * Name ObjEtcetera_ReturnToIdle. These names all suck but they're a start * Document some of ObjEtcetera_Idle's behavior * Name and document objectIds * Remove the burrow macro because it's frankly more confusing for now * Name the draw functions something slightly better * MUCH better names for things + more documentation * Clean up ObjEtcetera_Setup a bit * Call it NUMBER_OF_FLOWER_TYPES instead * A few more name changes * Link -> Player in comments * displayListPtr -> dList * Trailing commas + format * Move initialization of type up * Improve conditional check * Use BGCHECK_SCENE macro * Move initialization of floorBgId up * Use documentation comment style * Match ObjEtcetera_DoNormalOscillation without a dummy label * param_2 -> arg1 * Insert blank line after scoped pad * OBJETCETERA_TYPE -> DEKU_FLOWER_TYPE * Cleanup and rename enum * Break up ObjEtcetera_Setup a bit and convert DekuFlowerType to an s32 to remove warnings * Whoops, run format * Delete leading 0 on struct comments * Rename pad to requiredScopeTemp to match my other PR
This commit is contained in:
parent
27e41b73a8
commit
0f4bdbc020
@ -1762,7 +1762,7 @@ void func_800F9824(GlobalContext* globalCtx, EnvironmentContext* envCtx, View* v
|
|||||||
// void func_800FA39C(void);
|
// void func_800FA39C(void);
|
||||||
// void func_800FA3C4(void);
|
// void func_800FA3C4(void);
|
||||||
// void func_800FA9FC(void);
|
// void func_800FA9FC(void);
|
||||||
// void func_800FAAB4(void);
|
void func_800FAAB4(GlobalContext* globalCtx, u8 arg1);
|
||||||
// void func_800FAC20(void);
|
// void func_800FAC20(void);
|
||||||
// void func_800FAF74(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5);
|
// void func_800FAF74(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5);
|
||||||
// void func_800FB010(void);
|
// void func_800FB010(void);
|
||||||
|
@ -3954,8 +3954,14 @@ extern UNK_TYPE D_0400E3D8;
|
|||||||
extern UNK_TYPE D_0400E408;
|
extern UNK_TYPE D_0400E408;
|
||||||
extern UNK_TYPE D_0400E410;
|
extern UNK_TYPE D_0400E410;
|
||||||
extern UNK_TYPE D_0400E418;
|
extern UNK_TYPE D_0400E418;
|
||||||
extern UNK_TYPE D_0400EB7C;
|
extern CollisionHeader D_0400E710; // Pink Deku Flower collision
|
||||||
extern UNK_TYPE D_040117A8;
|
extern AnimationHeader D_0400EB7C; // Deku Flower intense flutter animation
|
||||||
|
extern Gfx D_0400ED80; // Pink Deku Flower display list
|
||||||
|
extern SkeletonHeader D_04011518; // Pink Deku Flower skeleton
|
||||||
|
extern AnimationHeader D_040117A8; // Deku Flower small flutter animation
|
||||||
|
extern CollisionHeader D_040118D8; // Gold Deku Flower collision
|
||||||
|
extern Gfx D_04011BD0; // Gold Deku Flower display list
|
||||||
|
extern SkeletonHeader D_040127E8; // Gold Deku Flower skeleton
|
||||||
extern UNK_TYPE D_04012860;
|
extern UNK_TYPE D_04012860;
|
||||||
extern UNK_TYPE D_040128BC;
|
extern UNK_TYPE D_040128BC;
|
||||||
extern UNK_TYPE D_04015FA0;
|
extern UNK_TYPE D_04015FA0;
|
||||||
|
3
spec
3
spec
@ -3206,8 +3206,7 @@ beginseg
|
|||||||
name "ovl_Obj_Etcetera"
|
name "ovl_Obj_Etcetera"
|
||||||
compress
|
compress
|
||||||
include "build/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.o"
|
include "build/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.o"
|
||||||
include "build/data/ovl_Obj_Etcetera/ovl_Obj_Etcetera.data.o"
|
include "build/src/overlays/actors/ovl_Obj_Etcetera/ovl_Obj_Etcetera_reloc.o"
|
||||||
include "build/data/ovl_Obj_Etcetera/ovl_Obj_Etcetera.reloc.o"
|
|
||||||
endseg
|
endseg
|
||||||
|
|
||||||
beginseg
|
beginseg
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
/*
|
||||||
|
* File: z_obj_etcetera.c
|
||||||
|
* Overlay: ovl_Obj_Etcetera
|
||||||
|
* Description: Deku Flower
|
||||||
|
*/
|
||||||
|
|
||||||
#include "z_obj_etcetera.h"
|
#include "z_obj_etcetera.h"
|
||||||
|
|
||||||
#define FLAGS 0x00000010
|
#define FLAGS 0x00000010
|
||||||
@ -8,12 +14,12 @@ void ObjEtcetera_Init(Actor* thisx, GlobalContext* globalCtx);
|
|||||||
void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||||
void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx);
|
void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||||
|
|
||||||
void func_80A7BF08(ObjEtcetera* this, GlobalContext* globalCtx);
|
void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* globalCtx);
|
||||||
void func_80A7C168(ObjEtcetera* this, GlobalContext* globalCtx);
|
void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCtx);
|
||||||
void func_80A7C1F0(ObjEtcetera* this, GlobalContext* globalCtx);
|
void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx);
|
||||||
void func_80A7C308(ObjEtcetera* this, GlobalContext* globalCtx);
|
void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx);
|
||||||
|
void ObjEtcetera_DrawAnimated(Actor* thisx, GlobalContext* globalCtx);
|
||||||
|
|
||||||
#if 0
|
|
||||||
const ActorInit Obj_Etcetera_InitVars = {
|
const ActorInit Obj_Etcetera_InitVars = {
|
||||||
ACTOR_OBJ_ETCETERA,
|
ACTOR_OBJ_ETCETERA,
|
||||||
ACTORCAT_BG,
|
ACTORCAT_BG,
|
||||||
@ -26,35 +32,290 @@ const ActorInit Obj_Etcetera_InitVars = {
|
|||||||
(ActorFunc)NULL,
|
(ActorFunc)NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
// static ColliderCylinderInit sCylinderInit = {
|
static ColliderCylinderInit sCylinderInit = {
|
||||||
static ColliderCylinderInit D_80A7C790 = {
|
{
|
||||||
{ COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, },
|
COLTYPE_NONE,
|
||||||
{ ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x01000202, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, },
|
AT_NONE,
|
||||||
|
AC_ON | AC_TYPE_PLAYER,
|
||||||
|
OC1_NONE,
|
||||||
|
OC2_TYPE_1,
|
||||||
|
COLSHAPE_CYLINDER,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ELEMTYPE_UNK0,
|
||||||
|
{ 0x00000000, 0x00, 0x00 },
|
||||||
|
{ 0x01000202, 0x00, 0x00 },
|
||||||
|
TOUCH_NONE | TOUCH_SFX_NORMAL,
|
||||||
|
BUMP_ON,
|
||||||
|
OCELEM_NONE,
|
||||||
|
},
|
||||||
{ 20, 14, 0, { 0, 0, 0 } },
|
{ 20, 14, 0, { 0, 0, 0 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern ColliderCylinderInit D_80A7C790;
|
extern ColliderCylinderInit D_80A7C790;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/ObjEtcetera_Init.s")
|
static s16 objectIds[] = {
|
||||||
|
GAMEPLAY_KEEP,
|
||||||
|
GAMEPLAY_KEEP,
|
||||||
|
GAMEPLAY_KEEP,
|
||||||
|
GAMEPLAY_KEEP,
|
||||||
|
};
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/ObjEtcetera_Destroy.s")
|
/**
|
||||||
|
* Most interactions with a Deku Flower cause it to slightly oscillate on the X and Z axes.
|
||||||
|
* When these small oscillations happen, the game determines how to scale the appropriate
|
||||||
|
* axes by using this table.
|
||||||
|
*/
|
||||||
|
static f32 oscillationTable[] = {
|
||||||
|
-1.0, -1.0, -1.0, -0.7, 0.0, 0.7, 1.0, 0.7, 0.0, -0.7, -1.0, -0.7, 0.0, 0.7, 1.0, 0.7, 0.0, -0.7,
|
||||||
|
};
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7BDC8.s")
|
void ObjEtcetera_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||||
|
s32 pad;
|
||||||
|
ObjEtcetera* this = THIS;
|
||||||
|
s32 objectIndex;
|
||||||
|
s32 type = DEKU_FLOWER_TYPE(&this->dyna.actor);
|
||||||
|
s32 floorBgId;
|
||||||
|
Vec3f pos;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7BE8C.s")
|
if ((type < DEKU_FLOWER_TYPE_PINK) || (type >= DEKU_FLOWER_TYPE_MAX)) {
|
||||||
|
type = DEKU_FLOWER_TYPE_PINK;
|
||||||
|
}
|
||||||
|
objectIndex = Object_GetIndex(&globalCtx->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;
|
||||||
|
func_800C411C(&globalCtx->colCtx, &this->dyna.actor.floorPoly, &floorBgId, &this->dyna.actor, &pos);
|
||||||
|
this->dyna.actor.floorBgId = floorBgId;
|
||||||
|
Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit);
|
||||||
|
Collider_UpdateCylinder(&this->dyna.actor, &this->collider);
|
||||||
|
this->actionFunc = ObjEtcetera_Setup;
|
||||||
|
Actor_SetScale(&this->dyna.actor, 0.01f);
|
||||||
|
this->dyna.actor.scale.y = 0.02f;
|
||||||
|
this->burrowFlag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7BF08.s")
|
void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||||
|
ObjEtcetera* this = THIS;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C168.s")
|
BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
||||||
|
Collider_DestroyCylinder(globalCtx, &this->collider);
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C1F0.s")
|
void ObjEtcetera_DoNormalOscillation(ObjEtcetera* this, GlobalContext* globalCtx) {
|
||||||
|
if (this->oscillationTimer > 0) {
|
||||||
|
s32 requiredScopeTemp;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C308.s")
|
Actor_SetScale(&this->dyna.actor,
|
||||||
|
(oscillationTable[globalCtx->gameplayFrames % 18] * (0.0001f * this->oscillationTimer)) + 0.01f);
|
||||||
|
this->dyna.actor.scale.y = 0.02f;
|
||||||
|
this->oscillationTimer--;
|
||||||
|
} else {
|
||||||
|
Actor_SetScale(&this->dyna.actor, 0.01f);
|
||||||
|
this->dyna.actor.scale.y = 0.02f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/ObjEtcetera_Update.s")
|
void ObjEtcetera_StartSmallFlutterAnimation(ObjEtcetera* this) {
|
||||||
|
SkelAnime_ChangeAnim(&this->skelAnime, &D_040117A8, 1.0f, 0.0f, SkelAnime_GetFrameCount(&D_040117A8.common), 2,
|
||||||
|
0.0f);
|
||||||
|
this->dyna.actor.draw = ObjEtcetera_DrawAnimated;
|
||||||
|
this->actionFunc = ObjEtcetera_PlaySmallFlutterAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C690.s")
|
void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) {
|
||||||
|
s16 minOscillationTimer;
|
||||||
|
Player* player = PLAYER;
|
||||||
|
|
||||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Etcetera/func_80A7C718.s")
|
if ((player->stateFlags3 & 0x200) && (this->dyna.actor.xzDistToPlayer < 20.0f)) {
|
||||||
|
// Player is launching out of the Deku Flower
|
||||||
|
SkelAnime_ChangeAnim(&this->skelAnime, &D_0400EB7C, 1.0f, 0.0f, SkelAnime_GetFrameCount(&D_0400EB7C.common), 2,
|
||||||
|
0.0f);
|
||||||
|
this->dyna.actor.draw = ObjEtcetera_DrawAnimated;
|
||||||
|
this->actionFunc = ObjEtcetera_DoIntenseOscillation;
|
||||||
|
Actor_SetScale(&this->dyna.actor, 0.01f);
|
||||||
|
this->dyna.actor.scale.y = 0.02f;
|
||||||
|
this->intenseOscillationScale = 0.003f;
|
||||||
|
this->oscillationTimer = 30;
|
||||||
|
this->burrowFlag &= ~1;
|
||||||
|
} else if ((player->stateFlags3 & 0x2000) && (this->dyna.actor.xzDistToPlayer < 30.0f) &&
|
||||||
|
(this->dyna.actor.yDistToPlayer > 0.0f)) {
|
||||||
|
// Player is hovering above the Deku Flower
|
||||||
|
minOscillationTimer = 10 - (s32)(this->dyna.actor.yDistToPlayer * 0.05f);
|
||||||
|
if (this->oscillationTimer < minOscillationTimer) {
|
||||||
|
this->oscillationTimer = minOscillationTimer;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (func_800CAF70(&this->dyna)) {
|
||||||
|
if (!(this->burrowFlag & 1)) {
|
||||||
|
// Player is walking onto the Deku Flower, or falling on it from a height
|
||||||
|
this->oscillationTimer = 10;
|
||||||
|
ObjEtcetera_StartSmallFlutterAnimation(this);
|
||||||
|
} else if ((player->actor.speedXZ > 0.1f) || ((player->unk_ABC < 0.0f) && !(player->stateFlags3 & 0x100))) {
|
||||||
|
// Player is walking on top of the Deku Flower, is at the very start of burrowing, or is at the very
|
||||||
|
// start of launching
|
||||||
|
this->oscillationTimer = 10;
|
||||||
|
}
|
||||||
|
this->burrowFlag |= 1;
|
||||||
|
} else {
|
||||||
|
if (this->burrowFlag & 1) {
|
||||||
|
// Player is walking off the Deku Flower
|
||||||
|
this->oscillationTimer = 10;
|
||||||
|
ObjEtcetera_StartSmallFlutterAnimation(this);
|
||||||
|
}
|
||||||
|
this->burrowFlag &= ~1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((this->collider.base.acFlags & AC_HIT)) {
|
||||||
|
this->oscillationTimer = 10;
|
||||||
|
ObjEtcetera_StartSmallFlutterAnimation(this);
|
||||||
|
}
|
||||||
|
ObjEtcetera_DoNormalOscillation(this, globalCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* globalCtx) {
|
||||||
|
if (func_800CAF70(&this->dyna)) {
|
||||||
|
this->burrowFlag |= 1;
|
||||||
|
} else {
|
||||||
|
this->burrowFlag &= ~1;
|
||||||
|
}
|
||||||
|
if (SkelAnime_FrameUpdateMatrix(&this->skelAnime)) {
|
||||||
|
this->dyna.actor.draw = ObjEtcetera_DrawIdle;
|
||||||
|
this->actionFunc = ObjEtcetera_Idle;
|
||||||
|
}
|
||||||
|
ObjEtcetera_DoNormalOscillation(this, globalCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCtx) {
|
||||||
|
// In order to match, we are seemingly required to access scale.x at one point
|
||||||
|
// without using this. We can create a thisx or dyna pointer to achieve that, but
|
||||||
|
// it's more likely they used dyna given that func_800CAF70 takes a DynaPolyActor.
|
||||||
|
DynaPolyActor* dyna = &this->dyna;
|
||||||
|
f32 scaleTemp;
|
||||||
|
|
||||||
|
if (func_800CAF70(dyna)) {
|
||||||
|
this->burrowFlag |= 1;
|
||||||
|
} else {
|
||||||
|
this->burrowFlag &= ~1;
|
||||||
|
}
|
||||||
|
SkelAnime_FrameUpdateMatrix(&this->skelAnime);
|
||||||
|
if (this->oscillationTimer > 0) {
|
||||||
|
this->oscillationTimer--;
|
||||||
|
} else {
|
||||||
|
this->dyna.actor.draw = ObjEtcetera_DrawIdle;
|
||||||
|
this->actionFunc = ObjEtcetera_Idle;
|
||||||
|
Actor_SetScale(&this->dyna.actor, 0.01f);
|
||||||
|
this->dyna.actor.scale.y = 0.02f;
|
||||||
|
this->oscillationTimer = 0;
|
||||||
|
this->intenseOscillationScale = 0.0f;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->intenseOscillationScale *= 0.8f;
|
||||||
|
this->intenseOscillationScale -= (this->dyna.actor.scale.x - 0.01f) * 0.4f;
|
||||||
|
scaleTemp = dyna->actor.scale.x + this->intenseOscillationScale;
|
||||||
|
Actor_SetScale(&this->dyna.actor, scaleTemp);
|
||||||
|
this->dyna.actor.scale.y = 2.0f * scaleTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx) {
|
||||||
|
CollisionHeader* colHeader = NULL;
|
||||||
|
s32 type;
|
||||||
|
CollisionHeader* collisionHeaders[] = { &D_0400E710, &D_0400E710, &D_040118D8, &D_040118D8 };
|
||||||
|
s32 pad;
|
||||||
|
CollisionHeader* thisCollisionHeader;
|
||||||
|
|
||||||
|
type = DEKU_FLOWER_TYPE(&this->dyna.actor);
|
||||||
|
if ((type < DEKU_FLOWER_TYPE_PINK) || (type >= DEKU_FLOWER_TYPE_MAX)) {
|
||||||
|
type = DEKU_FLOWER_TYPE_PINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) {
|
||||||
|
this->dyna.actor.objBankIndex = this->objIndex;
|
||||||
|
Actor_SetObjectSegment(globalCtx, &this->dyna.actor);
|
||||||
|
BcCheck3_BgActorInit(&this->dyna, 1);
|
||||||
|
thisCollisionHeader = collisionHeaders[type];
|
||||||
|
if (thisCollisionHeader != 0) {
|
||||||
|
BgCheck_RelocateMeshHeader(thisCollisionHeader, &colHeader);
|
||||||
|
}
|
||||||
|
this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, colHeader);
|
||||||
|
|
||||||
|
type = DEKU_FLOWER_TYPE(&this->dyna.actor);
|
||||||
|
switch (type) {
|
||||||
|
case DEKU_FLOWER_TYPE_PINK:
|
||||||
|
case DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB:
|
||||||
|
SkelAnime_Init(globalCtx, &this->skelAnime, &D_04011518, &D_0400EB7C, this->jointTable,
|
||||||
|
this->morphTable, 11);
|
||||||
|
this->dList = &D_0400ED80;
|
||||||
|
break;
|
||||||
|
case DEKU_FLOWER_TYPE_GOLD:
|
||||||
|
case DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB:
|
||||||
|
this->dList = &D_04011BD0;
|
||||||
|
SkelAnime_Init(globalCtx, &this->skelAnime, &D_040127E8, &D_0400EB7C, this->jointTable,
|
||||||
|
this->morphTable, 11);
|
||||||
|
this->collider.dim.height = 20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = DEKU_FLOWER_TYPE(&this->dyna.actor);
|
||||||
|
switch (type) {
|
||||||
|
case DEKU_FLOWER_TYPE_PINK:
|
||||||
|
case DEKU_FLOWER_TYPE_GOLD:
|
||||||
|
this->dyna.actor.draw = ObjEtcetera_DrawIdle;
|
||||||
|
this->actionFunc = ObjEtcetera_Idle;
|
||||||
|
Actor_SetScale(&this->dyna.actor, 0.01f);
|
||||||
|
this->dyna.actor.scale.y = 0.02f;
|
||||||
|
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:
|
||||||
|
SkelAnime_ChangeAnim(&this->skelAnime, &D_0400EB7C, 1.0f, 0.0f,
|
||||||
|
SkelAnime_GetFrameCount(&D_0400EB7C.common), 2, 0.0f);
|
||||||
|
this->dyna.actor.draw = ObjEtcetera_DrawAnimated;
|
||||||
|
this->actionFunc = ObjEtcetera_DoIntenseOscillation;
|
||||||
|
Actor_SetScale(&this->dyna.actor, 0.0f);
|
||||||
|
this->oscillationTimer = 30;
|
||||||
|
this->intenseOscillationScale = 0.0f;
|
||||||
|
this->dyna.actor.focus.pos.y = this->dyna.actor.home.pos.y + 10.0f;
|
||||||
|
this->dyna.actor.targetMode = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx) {
|
||||||
|
ObjEtcetera* this = THIS;
|
||||||
|
CollisionPoly* floorPoly;
|
||||||
|
u8 floorBgId = this->dyna.actor.floorBgId;
|
||||||
|
|
||||||
|
if (floorBgId == BGCHECK_SCENE) {
|
||||||
|
floorPoly = this->dyna.actor.floorPoly;
|
||||||
|
if (floorPoly != NULL && this->burrowFlag & 1) {
|
||||||
|
func_800FAAB4(globalCtx, func_800C9C9C(&globalCtx->colCtx, floorPoly, floorBgId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->actionFunc(this, globalCtx);
|
||||||
|
CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx) {
|
||||||
|
ObjEtcetera* this = THIS;
|
||||||
|
|
||||||
|
OPEN_DISPS(globalCtx->state.gfxCtx);
|
||||||
|
|
||||||
|
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||||
|
func_8012C28C(globalCtx->state.gfxCtx);
|
||||||
|
gSPDisplayList(POLY_OPA_DISP++, this->dList);
|
||||||
|
|
||||||
|
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjEtcetera_DrawAnimated(Actor* thisx, GlobalContext* globalCtx) {
|
||||||
|
ObjEtcetera* this = THIS;
|
||||||
|
|
||||||
|
func_8012C5B0(globalCtx->state.gfxCtx);
|
||||||
|
SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.limbDrawTbl, NULL, NULL, &this->dyna.actor);
|
||||||
|
}
|
||||||
|
@ -3,14 +3,32 @@
|
|||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
|
#define DEKU_FLOWER_TYPE(thisx) (((thisx)->params & 0xFF80) >> 7)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
/* 0 */ DEKU_FLOWER_TYPE_PINK,
|
||||||
|
/* 1 */ DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB,
|
||||||
|
/* 2 */ DEKU_FLOWER_TYPE_GOLD,
|
||||||
|
/* 3 */ DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB,
|
||||||
|
/* 4 */ DEKU_FLOWER_TYPE_MAX,
|
||||||
|
} DekuFlowerType;
|
||||||
|
|
||||||
struct ObjEtcetera;
|
struct ObjEtcetera;
|
||||||
|
|
||||||
typedef void (*ObjEtceteraActionFunc)(struct ObjEtcetera*, GlobalContext*);
|
typedef void (*ObjEtceteraActionFunc)(struct ObjEtcetera*, GlobalContext*);
|
||||||
|
|
||||||
typedef struct ObjEtcetera {
|
typedef struct ObjEtcetera {
|
||||||
/* 0x0000 */ Actor actor;
|
/* 0x000 */ DynaPolyActor dyna;
|
||||||
/* 0x0144 */ char unk_144[0x13C];
|
/* 0x15C */ SkelAnime skelAnime;
|
||||||
/* 0x0280 */ ObjEtceteraActionFunc actionFunc;
|
/* 0x1A0 */ ColliderCylinder collider;
|
||||||
|
/* 0x1EC */ Vec3s jointTable[11];
|
||||||
|
/* 0x22E */ Vec3s morphTable[11];
|
||||||
|
/* 0x270 */ f32 intenseOscillationScale;
|
||||||
|
/* 0x274 */ s16 oscillationTimer;
|
||||||
|
/* 0x276 */ u16 burrowFlag;
|
||||||
|
/* 0x278 */ s8 objIndex;
|
||||||
|
/* 0x27C */ Gfx* dList;
|
||||||
|
/* 0x280 */ ObjEtceteraActionFunc actionFunc;
|
||||||
} ObjEtcetera; // size = 0x284
|
} ObjEtcetera; // size = 0x284
|
||||||
|
|
||||||
extern const ActorInit Obj_Etcetera_InitVars;
|
extern const ActorInit Obj_Etcetera_InitVars;
|
||||||
|
@ -11103,15 +11103,15 @@
|
|||||||
0x80A7AFA8:("EnJso2_Draw",),
|
0x80A7AFA8:("EnJso2_Draw",),
|
||||||
0x80A7BC70:("ObjEtcetera_Init",),
|
0x80A7BC70:("ObjEtcetera_Init",),
|
||||||
0x80A7BD80:("ObjEtcetera_Destroy",),
|
0x80A7BD80:("ObjEtcetera_Destroy",),
|
||||||
0x80A7BDC8:("func_80A7BDC8",),
|
0x80A7BDC8:("ObjEtcetera_DoNormalOscillation",),
|
||||||
0x80A7BE8C:("func_80A7BE8C",),
|
0x80A7BE8C:("ObjEtcetera_StartSmallFlutterAnimation",),
|
||||||
0x80A7BF08:("func_80A7BF08",),
|
0x80A7BF08:("ObjEtcetera_Idle",),
|
||||||
0x80A7C168:("func_80A7C168",),
|
0x80A7C168:("ObjEtcetera_PlaySmallFlutterAnimation",),
|
||||||
0x80A7C1F0:("func_80A7C1F0",),
|
0x80A7C1F0:("ObjEtcetera_DoIntenseOscillation",),
|
||||||
0x80A7C308:("func_80A7C308",),
|
0x80A7C308:("ObjEtcetera_Setup",),
|
||||||
0x80A7C5EC:("ObjEtcetera_Update",),
|
0x80A7C5EC:("ObjEtcetera_Update",),
|
||||||
0x80A7C690:("func_80A7C690",),
|
0x80A7C690:("ObjEtcetera_DrawIdle",),
|
||||||
0x80A7C718:("func_80A7C718",),
|
0x80A7C718:("ObjEtcetera_DrawAnimated",),
|
||||||
0x80A7C990:("func_80A7C990",),
|
0x80A7C990:("func_80A7C990",),
|
||||||
0x80A7CA18:("func_80A7CA18",),
|
0x80A7CA18:("func_80A7CA18",),
|
||||||
0x80A7CBC4:("func_80A7CBC4",),
|
0x80A7CBC4:("func_80A7CBC4",),
|
||||||
|
@ -379,8 +379,10 @@ D_0400E418 = 0x0400E418;
|
|||||||
D_0400E430 = 0x0400E430;
|
D_0400E430 = 0x0400E430;
|
||||||
D_0400EB7C = 0x0400EB7C;
|
D_0400EB7C = 0x0400EB7C;
|
||||||
D_0400ED80 = 0x0400ED80;
|
D_0400ED80 = 0x0400ED80;
|
||||||
|
D_0400E710 = 0x0400E710;
|
||||||
D_04011518 = 0x04011518;
|
D_04011518 = 0x04011518;
|
||||||
D_040117A8 = 0x040117A8;
|
D_040117A8 = 0x040117A8;
|
||||||
|
D_040118D8 = 0x040118D8;
|
||||||
D_04011BD0 = 0x04011BD0;
|
D_04011BD0 = 0x04011BD0;
|
||||||
D_040127E8 = 0x040127E8;
|
D_040127E8 = 0x040127E8;
|
||||||
D_04012860 = 0x04012860;
|
D_04012860 = 0x04012860;
|
||||||
|
Loading…
Reference in New Issue
Block a user