From 1ec875f6dccf7efd9d637cd27a1a500f35eed43e Mon Sep 17 00:00:00 2001 From: StickyThwomp <89738536+StickyThwomp@users.noreply.github.com> Date: Sun, 28 May 2023 21:17:43 -0500 Subject: [PATCH] ItemBHeart (Heart Container) OK and Documented (#1236) * ItemBHeart (Heart Container) OK and Documented * Add missing spawn params. * z_item_b_heart updates from review. * Rename ItemBHeart_UpdateRotationAndScale to ItemBHeart_UpdateModel * Address comments from review. * Rename unitScale to baseScale. * Fixed function names after master merge. --- spec | 3 +- src/overlays/actors/ovl_Boss_02/z_boss_02.c | 10 +- src/overlays/actors/ovl_Boss_03/z_boss_03.c | 6 +- .../actors/ovl_Item_B_Heart/z_item_b_heart.c | 101 ++++++++++++++++-- .../actors/ovl_Item_B_Heart/z_item_b_heart.h | 14 ++- tools/disasm/functions.txt | 2 +- tools/disasm/variables.txt | 2 +- 7 files changed, 117 insertions(+), 21 deletions(-) diff --git a/spec b/spec index 003c76dd4e..4d327dc207 100644 --- a/spec +++ b/spec @@ -995,8 +995,7 @@ beginseg name "ovl_Item_B_Heart" compress include "build/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.o" - include "build/data/ovl_Item_B_Heart/ovl_Item_B_Heart.data.o" - include "build/data/ovl_Item_B_Heart/ovl_Item_B_Heart.reloc.o" + include "build/src/overlays/actors/ovl_Item_B_Heart/ovl_Item_B_Heart_reloc.o" endseg beginseg diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/src/overlays/actors/ovl_Boss_02/z_boss_02.c index 76889e41ee..7220b5d061 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -553,7 +553,7 @@ void Boss02_Init(Actor* thisx, PlayState* play) { if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_STONE_TOWER_TEMPLE) && (this->actor.params == TWINMOLD_RED)) { sBlueWarp = (DoorWarp1*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, 60.0f, 0.0f, 0, 0, 0, 1); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, 30.0f, -150.0f, 0, 1, 0, 0); + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, 30.0f, -150.0f, 0, 1, 0, BHEART_PARAM_NORMAL); } this->actor.targetMode = 10; @@ -1971,7 +1971,7 @@ void func_809DD934(Boss02* this, PlayState* play) { temp_a0_5->scale.z *= phi_f0_2; if (temp_a0_5->id == ACTOR_ITEM_B_HEART) { - ((ItemBHeart*)temp_a0_5)->unk_168 *= phi_f0_2; + ((ItemBHeart*)temp_a0_5)->baseScale *= phi_f0_2; } } temp_a0_5 = temp_a0_5->next; @@ -2210,10 +2210,12 @@ void func_809DEAC4(Boss02* this, PlayState* play) { this->unk_1D7E = 0; if (!sIsInGiantMode) { - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, 30.0f, -150.0f, 0, 1, 0, 0); + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, 30.0f, -150.0f, 0, 1, 0, + BHEART_PARAM_NORMAL); phi_f0 = 60.0f; } else { - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, 3153.0f, -15.0f, 0, 1, 0, 35); + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, 3153.0f, -15.0f, 0, 1, 0, + BHEART_PARAM_SMALL); phi_f0 = 3155.0f; } sBlueWarp = (DoorWarp1*)Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, diff --git a/src/overlays/actors/ovl_Boss_03/z_boss_03.c b/src/overlays/actors/ovl_Boss_03/z_boss_03.c index a9096048aa..ddd9d48301 100644 --- a/src/overlays/actors/ovl_Boss_03/z_boss_03.c +++ b/src/overlays/actors/ovl_Boss_03/z_boss_03.c @@ -51,6 +51,7 @@ #include "z_boss_03.h" #include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" #include "overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h" +#include "overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h" #include "objects/gameplay_keep/gameplay_keep.h" #include "objects/object_water_effect/object_water_effect.h" @@ -451,7 +452,8 @@ void Boss03_Init(Actor* thisx, PlayState* play2) { if (CHECK_WEEKEVENTREG(WEEKEVENTREG_CLEARED_GREAT_BAY_TEMPLE)) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, PLATFORM_HEIGHT, 200.0f, 0, 0, 0, ENDOORWARP1_FF_1); - Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, PLATFORM_HEIGHT, 0.0f, 0, 0, 0, 0); + Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, 0.0f, PLATFORM_HEIGHT, 0.0f, 0, 0, 0, + BHEART_PARAM_NORMAL); Actor_Kill(&this->actor); return; } @@ -1610,7 +1612,7 @@ void Boss03_DeathCutscene(Boss03* this, PlayState* play) { Actor_SpawnAsChild(&play->actorCtx, &this->actor, play, ACTOR_DOOR_WARP1, 0.0f, PLATFORM_HEIGHT, 200.0f, 0, 0, 0, ENDOORWARP1_FF_1); Actor_Spawn(&play->actorCtx, play, ACTOR_ITEM_B_HEART, this->actor.focus.pos.x, PLATFORM_HEIGHT, - this->actor.focus.pos.z, 0, 0, 0, 0); + this->actor.focus.pos.z, 0, 0, 0, BHEART_PARAM_NORMAL); this->csTimer = 0; Actor_SetScale(&this->actor, 0.0f); AudioSfx_StopByPos(&this->actor.projectedPos); diff --git a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index c41f455798..661d246369 100644 --- a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -1,3 +1,9 @@ +/* + * File: z_item_b_heart.c + * Overlay: ovl_Item_B_Heart + * Description: Heart Container + */ + #include "z_item_b_heart.h" #include "objects/object_gi_hearts/object_gi_hearts.h" @@ -10,7 +16,8 @@ void ItemBHeart_Destroy(Actor* thisx, PlayState* play); void ItemBHeart_Update(Actor* thisx, PlayState* play); void ItemBHeart_Draw(Actor* thisx, PlayState* play); -/* +void ItemBHeart_UpdateModel(ItemBHeart* this, PlayState* play); + const ActorInit Item_B_Heart_InitVars = { ACTOR_ITEM_B_HEART, ACTORCAT_BOSS, @@ -20,16 +27,94 @@ const ActorInit Item_B_Heart_InitVars = { (ActorFunc)ItemBHeart_Init, (ActorFunc)ItemBHeart_Destroy, (ActorFunc)ItemBHeart_Update, - (ActorFunc)ItemBHeart_Draw + (ActorFunc)ItemBHeart_Draw, }; -*/ -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Item_B_Heart/ItemBHeart_Init.s") +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3F_DIV1000(scale, 0, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Item_B_Heart/ItemBHeart_Destroy.s") +void ItemBHeart_Init(Actor* thisx, PlayState* play) { + ItemBHeart* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Item_B_Heart/ItemBHeart_Update.s") + if (Flags_GetCollectible(play, 0x1F)) { + Actor_Kill(&this->actor); + return; + } + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.8f); + if (this->actor.params == BHEART_PARAM_SMALL) { + this->baseScale = BHEART_SCALE_SMALL; + } else { + this->baseScale = BHEART_SCALE_NORMAL; + } + this->actor.world.pos.y += 20.0f * this->baseScale; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Item_B_Heart/func_808BCF54.s") +void ItemBHeart_Destroy(Actor* thisx, PlayState* play) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Item_B_Heart/ItemBHeart_Draw.s") +/** + * Adjusts size and handles collection (if of proper baseScale) + */ +void ItemBHeart_Update(Actor* thisx, PlayState* play) { + ItemBHeart* this = THIS; + + ItemBHeart_UpdateModel(this, play); + + if (!(this->baseScale < BHEART_SCALE_MIN_COLLECTIBLE)) { + if (Actor_HasParent(&this->actor, play)) { + Flags_SetCollectible(play, 0x1F); + Actor_Kill(&this->actor); + return; + } + Actor_OfferGetItem(&this->actor, play, GI_HEART_CONTAINER, 30.0f, 80.0f); + } +} + +/** + * Rotate continuously while approaching 40% of object's unit scale. + */ +void ItemBHeart_UpdateModel(ItemBHeart* this, PlayState* play) { + this->actor.shape.rot.y += 0x400; + Math_ApproachF(&this->variableScale, 0.4f, 0.1f, 0.01f); + Actor_SetScale(&this->actor, this->variableScale * this->baseScale); +} + +/** + * Draw translucently when in front of a boss warp portal + */ +void ItemBHeart_Draw(Actor* thisx, PlayState* play) { + ItemBHeart* this = THIS; + Actor* actorIt; + u8 drawTranslucent = false; + + OPEN_DISPS(play->state.gfxCtx); + + actorIt = play->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + + while (actorIt != NULL) { + if ((actorIt->id == ACTOR_DOOR_WARP1) && (actorIt->projectedPos.z > this->actor.projectedPos.z)) { + drawTranslucent = true; + break; + } + actorIt = actorIt->next; + } + + if (drawTranslucent || (this->actor.world.rot.y != 0)) { + Gfx_SetupDL25_Xlu(play->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gGiHeartBorderDL); + gSPDisplayList(POLY_XLU_DISP++, &gGiHeartContainerDL); + } else { + Gfx_SetupDL25_Opa(play->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, &gGiHeartBorderDL); + gSPDisplayList(POLY_OPA_DISP++, &gGiHeartContainerDL); + } + + CLOSE_DISPS(play->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h index 4e3126e252..7a071a8eca 100644 --- a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h +++ b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h @@ -3,12 +3,20 @@ #include "global.h" -struct ItemBHeart; +typedef enum { + /* 0 */ BHEART_PARAM_NORMAL, // Spawn Parameter for Normal Scale. + /* 35 */ BHEART_PARAM_SMALL = 35, // Spawn Parameter for Small Scale. +} ItemBHeartParams; + +#define BHEART_SCALE_SMALL (0.1f) // Scale value for Small Mode +#define BHEART_SCALE_NORMAL (1.0f) // Scale value for Normal Mode +#define BHEART_SCALE_MIN_COLLECTIBLE (0.5f) // baseScale <50% will disable collection typedef struct ItemBHeart { /* 0x000 */ Actor actor; - /* 0x144 */ UNK_TYPE1 unk_144[0x24]; - /* 0x168 */ f32 unk_168; + /* 0x144 */ UNK_TYPE1 unk_144[0x20]; + /* 0x164 */ f32 variableScale; + /* 0x168 */ f32 baseScale; } ItemBHeart; // size = 0x16C #endif // Z_ITEM_B_HEART_H diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index d4cb99aed3..127fb34bf4 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -6033,7 +6033,7 @@ 0x808BCDF0:("ItemBHeart_Init",), 0x808BCEA8:("ItemBHeart_Destroy",), 0x808BCEB8:("ItemBHeart_Update",), - 0x808BCF54:("func_808BCF54",), + 0x808BCF54:("ItemBHeart_UpdateModel",), 0x808BCFC4:("ItemBHeart_Draw",), 0x808BD1E0:("EnDekunuts_Init",), 0x808BD31C:("EnDekunuts_Destroy",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index d09486c56c..f3f90ba256 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -6470,7 +6470,7 @@ 0x808BCD44:("D_808BCD44","f32","",0x4), 0x808BCDE0:("sNumLitTorchesInGroup","UNK_TYPE1","",0x1), 0x808BD160:("Item_B_Heart_InitVars","UNK_TYPE1","",0x1), - 0x808BD180:("D_808BD180","UNK_TYPE1","",0x1), + 0x808BD180:("sInitChain","UNK_TYPE1","",0x1), 0x808BD190:("D_808BD190","f32","",0x4), 0x808BEF10:("En_Dekunuts_InitVars","UNK_TYPE1","",0x1), 0x808BEF30:("D_808BEF30","UNK_TYPE1","",0x1),