Core/Creature: Implemented sparring with max health percent thresholds

Port From (https://github.com/TrinityCore/TrinityCore/commit/0750b7f8455df39a64462636ca296c6f2aa2b048)
This commit is contained in:
hondacrx
2023-04-25 08:38:55 -04:00
parent 9d4be0003b
commit bd2eb5baab
9 changed files with 138 additions and 3 deletions
@@ -30,6 +30,7 @@ namespace Game.Entities
uint _gossipMenuId;
uint? _trainerId;
float _sparringHealthPct;
public ulong m_PlayerDamageReq;
public float m_SightDistance;
+59 -1
View File
@@ -413,7 +413,7 @@ namespace Game.Entities
InitializeMovementFlags();
LoadCreaturesAddon();
LoadCreaturesSparringHealth();
LoadTemplateImmunities();
GetThreatManager().EvaluateSuppressed();
@@ -855,7 +855,9 @@ namespace Game.Entities
m_corpseDelay = WorldConfig.GetUIntValue(WorldCfg.CorpseDecayNormal);
break;
}
LoadCreaturesAddon();
LoadCreaturesSparringHealth();
//! Need to be called after LoadCreaturesAddon - MOVEMENTFLAG_HOVER is set there
posZ += GetHoverOffset();
@@ -1570,6 +1572,54 @@ namespace Game.Entities
}
}
float GetSparringHealthPct() { return _sparringHealthPct; }
public void OverrideSparringHealthPct(List<float> healthPct)
{
_sparringHealthPct = healthPct.SelectRandom();
}
public uint CalculateDamageForSparring(Unit attacker, uint damage)
{
if (GetSparringHealthPct() == 0)
return damage;
if (!attacker.IsCreature() || attacker.IsCharmedOwnedByPlayerOrPlayer() || IsCharmedOwnedByPlayerOrPlayer())
return damage;
if (GetHealthPct() <= GetSparringHealthPct())
return 0;
uint sparringHealth = (uint)(GetMaxHealth() * GetSparringHealthPct() / 100);
if (GetHealth() - damage <= sparringHealth)
return (uint)(GetHealth() - sparringHealth);
if (damage >= GetHealth())
return (uint)(GetHealth() - 1);
return damage;
}
public bool ShouldFakeDamageFrom(Unit attacker)
{
if (GetSparringHealthPct() == 0)
return false;
if (!attacker)
return false;
if (!attacker.IsCreature())
return false;
if (attacker.IsCharmedOwnedByPlayerOrPlayer() || IsCharmedOwnedByPlayerOrPlayer())
return false;
if (GetHealthPct() > GetSparringHealthPct())
return false;
return true;
}
bool CreateFromProto(ulong guidlow, uint entry, CreatureData data = null, uint vehId = 0)
{
SetZoneScript();
@@ -1960,6 +2010,7 @@ namespace Game.Entities
InitializeMovementAI();
base.SetDeathState(DeathState.Alive);
LoadCreaturesAddon();
LoadCreaturesSparringHealth();
}
}
@@ -2462,6 +2513,13 @@ namespace Game.Entities
return true;
}
public void LoadCreaturesSparringHealth()
{
var templateValues = Global.ObjectMgr.GetCreatureTemplateSparringValues(GetCreatureTemplate().Entry);
if (!templateValues.Empty())
_sparringHealthPct = templateValues.SelectRandom();
}
// Send a message to LocalDefense channel for players opposition team in the zone
public void SendZoneUnderAttackMessage(Player attacker)
{
+9
View File
@@ -564,6 +564,15 @@ namespace Game.Entities
CalculateMeleeDamage(victim, out damageInfo, attType);
// Send log damage message to client
DealDamageMods(damageInfo.Attacker, victim, ref damageInfo.Damage, ref damageInfo.Absorb);
// sparring
Creature victimCreature = victim.ToCreature();
if (victimCreature != null)
{
if (victimCreature.ShouldFakeDamageFrom(damageInfo.Attacker))
damageInfo.HitInfo |= HitInfo.FakeDamage;
}
SendAttackStateUpdate(damageInfo);
_lastDamagedTargetGuid = victim.GetGUID();
+13
View File
@@ -2489,6 +2489,11 @@ namespace Game.Entities
{
uint tmpDamage = damageTaken;
// sparring
Creature victimCreature = victim.ToCreature();
if (victimCreature != null)
tmpDamage = victimCreature.CalculateDamageForSparring(attacker, tmpDamage);
victim.GetAI()?.DamageTaken(attacker, ref tmpDamage, damagetype, spellProto);
attacker?.GetAI()?.DamageDealt(victim, ref tmpDamage, damagetype);
@@ -3652,6 +3657,14 @@ namespace Game.Entities
uint split_absorb = 0;
DealDamageMods(damageInfo.GetAttacker(), caster, ref splitDamage, ref split_absorb);
// sparring
Creature victimCreature = damageInfo.GetVictim().ToCreature();
if (victimCreature != null)
{
if (victimCreature.ShouldFakeDamageFrom(damageInfo.GetAttacker()))
damageInfo.ModifyDamage((int)(damageInfo.GetDamage() * -1));
}
SpellNonMeleeDamage log = new(damageInfo.GetAttacker(), caster, itr.GetSpellInfo(), itr.GetBase().GetSpellVisual(), damageInfo.GetSchoolMask(), itr.GetBase().GetCastId());
CleanDamage cleanDamage = new(splitDamage, 0, WeaponAttackType.BaseAttack, MeleeHitOutcome.Normal);
DealDamage(damageInfo.GetAttacker(), caster, splitDamage, cleanDamage, DamageEffectType.Direct, damageInfo.GetSchoolMask(), itr.GetSpellInfo(), false);