mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-08-14 02:27:21 -07:00
Convert actor health bars to use ObjectExtension (#5565)
This commit is contained in:
parent
abb0a93945
commit
dbc2ff09b5
6 changed files with 50 additions and 15 deletions
|
@ -266,9 +266,6 @@ typedef struct Actor {
|
|||
/* 0x134 */ ActorFunc draw; // Draw Routine. Called by `Actor_Draw`
|
||||
/* 0x138 */ ActorResetFunc reset;
|
||||
/* 0x13C */ char dbgPad[0x10]; // Padding that only exists in the debug rom
|
||||
// #region SOH [General]
|
||||
/* */ u8 maximumHealth; // Max health value for use with health bars, set on actor init
|
||||
// #endregion
|
||||
} Actor; // size = 0x14C
|
||||
|
||||
typedef enum {
|
||||
|
|
29
soh/soh/ObjectExtension/ActorMaximumHealth.cpp
Normal file
29
soh/soh/ObjectExtension/ActorMaximumHealth.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
#include "ActorMaximumHealth.h"
|
||||
#include "soh/ObjectExtension/ObjectExtension.h"
|
||||
#include "soh/ShipInit.hpp"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor.h"
|
||||
|
||||
struct ActorMaximumHealth {
|
||||
u8 maximumHealth = 0;
|
||||
};
|
||||
static ObjectExtension::Register<ActorMaximumHealth> ActorMaximumHealthRegister;
|
||||
|
||||
u8 GetActorMaximumHealth(const Actor* actor) {
|
||||
const ActorMaximumHealth* maxHealth = ObjectExtension::GetInstance().Get<ActorMaximumHealth>(actor);
|
||||
return maxHealth != nullptr ? maxHealth->maximumHealth : ActorMaximumHealth{}.maximumHealth;
|
||||
}
|
||||
|
||||
void SetActorMaximumHealth(const Actor* actor, u8 maximumHealth) {
|
||||
ObjectExtension::GetInstance().Set<ActorMaximumHealth>(actor, ActorMaximumHealth{ maximumHealth });
|
||||
}
|
||||
|
||||
static void ActorMaximumHealth_Register() {
|
||||
COND_HOOK(OnActorInit, true, [](void* ptr) {
|
||||
Actor* actor = static_cast<Actor*>(ptr);
|
||||
if (actor->category == ACTORCAT_ENEMY) {
|
||||
SetActorMaximumHealth(actor, actor->colChkInfo.health);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RegisterShipInitFunc actorMaximumHealthInit(ActorMaximumHealth_Register);
|
17
soh/soh/ObjectExtension/ActorMaximumHealth.h
Normal file
17
soh/soh/ObjectExtension/ActorMaximumHealth.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef ACTOR_MAXIMUM_HEALTH_H
|
||||
#define ACTOR_MAXIMUM_HEALTH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include "z64actor.h"
|
||||
#endif
|
||||
|
||||
// Max health value for use with health bars, set on actor init
|
||||
u8 GetActorMaximumHealth(const Actor* actor);
|
||||
void SetActorMaximumHealth(const Actor* actor, u8 maximumHealth);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ACTOR_MAXIMUM_HEALTH_H
|
|
@ -1260,11 +1260,6 @@ void Actor_Init(Actor* actor, PlayState* play) {
|
|||
actor->init = NULL;
|
||||
|
||||
GameInteractor_ExecuteOnActorInit(actor);
|
||||
|
||||
// For enemy health bar we need to know the max health during init
|
||||
if (actor->category == ACTORCAT_ENEMY) {
|
||||
actor->maximumHealth = actor->colChkInfo.health;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2625,11 +2620,6 @@ void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) {
|
|||
actor->init = NULL;
|
||||
|
||||
GameInteractor_ExecuteOnActorInit(actor);
|
||||
|
||||
// For enemy health bar we need to know the max health during init
|
||||
if (actor->category == ACTORCAT_ENEMY) {
|
||||
actor->maximumHealth = actor->colChkInfo.health;
|
||||
}
|
||||
}
|
||||
actor = actor->next;
|
||||
} else if (!Object_IsLoaded(&play->objectCtx, actor->objBankIndex)) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "soh/OTRGlobals.h"
|
||||
#include "soh/ResourceManagerHelpers.h"
|
||||
#include "soh/Enhancements/gameplaystats.h"
|
||||
#include "soh/ObjectExtension/ActorMaximumHealth.h"
|
||||
|
||||
#include "message_data_static.h"
|
||||
extern MessageTableEntry* sNesMessageEntryTablePtr;
|
||||
|
@ -3643,7 +3644,7 @@ void Interface_DrawEnemyHealthBar(TargetContext* targetCtx, PlayState* play) {
|
|||
f32 scaleY = -0.75f;
|
||||
f32 scaledHeight = -texHeight * scaleY;
|
||||
f32 halfBarWidth = endTexWidth + ((f32)healthbar_fillWidth / 2);
|
||||
s16 healthBarFill = ((f32)actor->colChkInfo.health / actor->maximumHealth) * healthbar_fillWidth;
|
||||
s16 healthBarFill = ((f32)actor->colChkInfo.health / GetActorMaximumHealth(actor)) * healthbar_fillWidth;
|
||||
|
||||
if (anchorType == ENEMYHEALTH_ANCHOR_ACTOR) {
|
||||
// Get actor projected position
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "objects/object_fz/object_fz.h"
|
||||
#include "soh/frame_interpolation.h"
|
||||
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
|
||||
#include "soh/ObjectExtension/ActorMaximumHealth.h"
|
||||
|
||||
#define FLAGS \
|
||||
(ACTOR_FLAG_ATTENTION_ENABLED | ACTOR_FLAG_HOSTILE | ACTOR_FLAG_UPDATE_CULLING_DISABLED | \
|
||||
|
@ -725,7 +726,7 @@ void EnFz_Draw(Actor* thisx, PlayState* play) {
|
|||
// displayLists, so we need to recompute the index based on the scaled health (using the maximum health value) and
|
||||
// clamp the final result for safety.
|
||||
if (CVarGetInteger(CVAR_ENHANCEMENT("EnemySizeScalesHealth"), 0)) {
|
||||
u8 scaledHealth = (u8)(((f32)this->actor.colChkInfo.health / this->actor.maximumHealth) * 6);
|
||||
u8 scaledHealth = (u8)(((f32)this->actor.colChkInfo.health / GetActorMaximumHealth(this)) * 6);
|
||||
index = (6 - scaledHealth) >> 1;
|
||||
index = CLAMP(index, 0, 2);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue