summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStickyThwomp <89738536+StickyThwomp@users.noreply.github.com>2023-05-28 21:17:43 -0500
committerGitHub <noreply@github.com>2023-05-28 22:17:43 -0400
commit1ec875f6dccf7efd9d637cd27a1a500f35eed43e (patch)
treedf01afd59323422fcbea677c824dc47037fb6ce3 /src
parent92bdfe68c212d50ac6569fdb871b93be6230b3ad (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/overlays/actors/ovl_Boss_02/z_boss_02.c10
-rw-r--r--src/overlays/actors/ovl_Boss_03/z_boss_03.c6
-rw-r--r--src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c101
-rw-r--r--src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h14
4 files changed, 114 insertions, 17 deletions
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 76889e41e..7220b5d06 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 a9096048a..ddd9d4830 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 c41f45579..661d24636 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),
+};
+
+void ItemBHeart_Init(Actor* thisx, PlayState* play) {
+ ItemBHeart* this = THIS;
+
+ 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;
+}
+
+void ItemBHeart_Destroy(Actor* thisx, PlayState* play) {
+}
+
+/**
+ * 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);
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Item_B_Heart/ItemBHeart_Destroy.s")
+ actorIt = play->actorCtx.actorLists[ACTORCAT_ITEMACTION].first;
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Item_B_Heart/ItemBHeart_Update.s")
+ while (actorIt != NULL) {
+ if ((actorIt->id == ACTOR_DOOR_WARP1) && (actorIt->projectedPos.z > this->actor.projectedPos.z)) {
+ drawTranslucent = true;
+ break;
+ }
+ actorIt = actorIt->next;
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Item_B_Heart/func_808BCF54.s")
+ 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);
+ }
-#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Item_B_Heart/ItemBHeart_Draw.s")
+ 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 4e3126e25..7a071a8ec 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