Files
KingshearthLegacy/Source/KingshearthLegacy/AttributeSets/StaminaAttributeSet.cpp
T
Dolobarsch 64f4a59b0b Integriere Gameplay Ability System (GAS)
Ersetze HealthComponent und StaminaComponent durch GAS-basierte AttributeSets (`UHealthAttributeSet`, `UStaminaAttributeSet`) und füge `UAbilitySystemComponent` hinzu.

Implementiere neue GameplayEffects (`UGE_HealthDamage`, `UGE_HealthHealing`, `UGE_HealthDebuff`, `UGE_StaminaFatiguePenalty`) und eine Modifikator-Berechnung (`UMMC_MaxStaminaFatiguePenalty`).

Erweitere `AKingshearthLegacyCharacter` um Methoden zur Attributmanipulation (`ApplyDamage`, `SpendStamina`, etc.) und Stamina-Regeneration.

Aktualisiere UI-Widgets (`HealthBarWidget`, `StaminaBarWidget`) zur Nutzung der neuen AttributeSets. Entferne Legacy-Code für Health- und Stamina-Komponenten.

Füge neue Assets (Niagara-Systeme, Materialien, Texturen) hinzu und passe Projektkonfiguration an (z. B. `GameplayAbilities`-Modul, `r.Substrate`).
2026-09-04 22:54:46 +02:00

87 lines
2.3 KiB
C++

#include "StaminaAttributeSet.h"
UStaminaAttributeSet::UStaminaAttributeSet()
{
InitStamina(100.0f);
InitMaxStamina(100.0f);
InitFatigue(0.0f);
}
void UStaminaAttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
{
Super::PreAttributeChange(Attribute, NewValue);
if (Attribute == GetStaminaAttribute())
{
NewValue = FMath::Clamp(NewValue, 0.0f, GetMaxStamina());
}
else if (Attribute == GetMaxStaminaAttribute())
{
NewValue = FMath::Max(NewValue, 0.0f);
}
else if (Attribute == GetFatigueAttribute())
{
NewValue = FMath::Clamp(NewValue, 0.0f, 1.0f);
}
}
void UStaminaAttributeSet::PreAttributeBaseChange(const FGameplayAttribute& Attribute, float& NewValue) const
{
Super::PreAttributeBaseChange(Attribute, NewValue);
// ApplyModToAttribute (SpendStamina/RestoreStamina/regen) writes BaseValue through this hook, not
// PreAttributeChange - without clamping here, a large delta (e.g. RestoreStamina's debug "fill to max")
// pushes BaseValue past MaxStamina. PreAttributeChange still clamps the displayed CurrentValue, but the
// bloated BaseValue then absorbs every subsequent spend/regen delta before CurrentValue moves again.
if (Attribute == GetStaminaAttribute())
{
NewValue = FMath::Clamp(NewValue, 0.0f, GetMaxStamina());
}
else if (Attribute == GetMaxStaminaAttribute())
{
NewValue = FMath::Max(NewValue, 0.0f);
}
else if (Attribute == GetFatigueAttribute())
{
NewValue = FMath::Clamp(NewValue, 0.0f, 1.0f);
}
}
void UStaminaAttributeSet::PostAttributeChange(const FGameplayAttribute& Attribute, float OldValue, float NewValue)
{
Super::PostAttributeChange(Attribute, OldValue, NewValue);
if (Attribute == GetStaminaAttribute())
{
if (!FMath::IsNearlyEqual(OldValue, NewValue))
{
OnStaminaChanged.Broadcast(NewValue);
}
if (OldValue > 0.0f && NewValue <= 0.0f)
{
OnExhausted.Broadcast();
}
}
else if (Attribute == GetMaxStaminaAttribute())
{
if (!FMath::IsNearlyEqual(OldValue, NewValue))
{
// MaxStamina shrank/grew (typically GE_StaminaFatiguePenalty re-evaluating) - pull Stamina back in range.
ClampStamina();
}
}
else if (Attribute == GetFatigueAttribute())
{
if (!FMath::IsNearlyEqual(OldValue, NewValue))
{
OnFatigueChanged.Broadcast(NewValue);
}
}
}
void UStaminaAttributeSet::ClampStamina()
{
SetStamina(FMath::Clamp(GetStamina(), 0.0f, GetMaxStamina()));
}