public void HandleGlobal(TakeDamageEvent msg) { _eventLog.Add(msg); if (msg.Amount <= 0) { return; } var node = msg.Target; if (node == null) { return; } var logSystem = World.Get <GameLogSystem>(); logSystem.StartNewMessage(out var dmgMsg, out var dmgHoverMsg); var blockDamage = node.Entity.Get <BlockDamage>(); if (blockDamage != null) { for (int i = 0; i < blockDamage.DamageBlockers.Count; i++) { if (blockDamage.DamageBlockers[i](msg)) { dmgMsg.Append(msg.Target.GetName()); dmgMsg.Append(" completely blocked damage from "); dmgMsg.Append(msg.Origin.GetName()); logSystem.PostCurrentStrings(GameLogSystem.DamageColor); return; } } } var damageAmount = msg.Amount; if (node.StatDefend != null) { for (int i = 0; i < node.StatDefend.Count; i++) { if (node.StatDefend[i].DamageType != msg.DamageType) { continue; } var defAmt = RulesSystem.GetDefenseAmount(damageAmount, node.StatDefend[i].Stat.Value); if (defAmt <= 0) { continue; } damageAmount = Mathf.Max(0, damageAmount - defAmt); dmgHoverMsg.Append(node.StatDefend[i].Stat.Stat.Label); dmgHoverMsg.Append(" Reduced Damage by "); dmgHoverMsg.AppendNewLine(defAmt.ToString("F1")); } } if (node.DamageAbsorb != null) { for (int i = 0; i < node.DamageAbsorb.Count; i++) { if (node.DamageAbsorb[i].DamageType != msg.DamageType) { continue; } var defAmt = RulesSystem.GetDefenseAmount(damageAmount, node.DamageAbsorb[i].Amount); if (defAmt <= 0) { continue; } if (defAmt > node.DamageAbsorb[i].Remaining) { defAmt = node.DamageAbsorb[i].Remaining; } damageAmount = Mathf.Max(0, damageAmount - defAmt); dmgHoverMsg.Append(node.DamageAbsorb[i].Source); dmgHoverMsg.Append(" Absorbed "); dmgHoverMsg.Append(defAmt.ToString("F1")); dmgHoverMsg.AppendNewLine(" Damage"); node.DamageAbsorb[i].Remaining -= defAmt; } node.DamageAbsorb.CheckLimits(); } float previousValue = 0; var stats = node.Stats; var vital = stats.GetVital(msg.TargetVital); if (vital == null) { vital = stats.GetVital(GameData.Vitals.GetID(msg.TargetVital)); } if (vital != null) { dmgHoverMsg.Append(vital.ToLabelString()); dmgHoverMsg.Append(" - "); dmgHoverMsg.Append(damageAmount); dmgHoverMsg.Append(" = "); previousValue = vital.Current; vital.Current -= damageAmount; dmgHoverMsg.Append(vital.ToLabelString()); } dmgMsg.Append(msg.Target.GetName()); dmgMsg.Append(" took "); dmgMsg.Append(damageAmount.ToString("F1")); dmgMsg.Append(" damage "); if (damageAmount > 0) { node.Entity.Post(new CombatStatusUpdate(node.Entity, damageAmount.ToString("F1"), Color.red)); msg.Impact.Source.PostAll(new CausedDamageEvent(damageAmount, msg)); } if (vital != null && vital.Current <= 0 && msg.TargetVital == Stats.Health) { node.Entity.Post(new DeathEvent(msg.Origin, msg.Target, damageAmount - previousValue)); } }
public void RuleEventRun(ref TakeDamageEvent msg) { _eventLog.Add(msg); if (msg.Target.IsDead) { msg.Clear(); return; } var target = msg.Target; var logSystem = World.Get <GameLogSystem>(); logSystem.StartNewMessage(out var dmgMsg, out var dmgHoverMsg); if (msg.Hit.Result == CollisionResult.CriticalHit) { dmgMsg.Append("<b>"); dmgHoverMsg.Append("<b>"); } if (target.StatDefend != null) { for (int i = 0; i < target.StatDefend.Count; i++) { for (int d = msg.Entries.Count - 1; d >= 0; d--) { var dmg = msg.Entries[d]; if (target.StatDefend[i].DamageType != dmg.DamageType) { continue; } var defAmt = RulesSystem.GetDefenseAmount(dmg.Amount, target.StatDefend[i].Stat.Value); if (defAmt <= 0) { continue; } var amount = Mathf.Max(0, dmg.Amount - defAmt); dmgHoverMsg.Append(target.StatDefend[i].Stat.Stat.Label); dmgHoverMsg.Append(" Reduced Damage by "); dmgHoverMsg.AppendNewLine(defAmt.ToString("F1")); msg.Entries.Remove(dmg); msg.Entries.Add(new DamageEntry(amount, dmg.DamageType, dmg.TargetVital, dmg.Description)); } } } if (target.DamageAbsorb != null) { for (int i = 0; i < target.DamageAbsorb.Count; i++) { for (int d = msg.Entries.Count - 1; d >= 0; d--) { var dmg = msg.Entries[d]; if (target.DamageAbsorb[i].DamageType != dmg.DamageType) { continue; } var defAmt = RulesSystem.GetDefenseAmount(dmg.Amount, target.DamageAbsorb[i].Amount); if (defAmt <= 0) { continue; } if (defAmt > target.DamageAbsorb[i].Remaining) { defAmt = target.DamageAbsorb[i].Remaining; } var amount = Mathf.Max(0, dmg.Amount - defAmt); dmgHoverMsg.Append(target.DamageAbsorb[i].Source); dmgHoverMsg.Append(" Absorbed "); dmgHoverMsg.Append(defAmt.ToString("F1")); dmgHoverMsg.AppendNewLine(" Damage"); target.DamageAbsorb[i].Remaining -= defAmt; target.DamageAbsorb.CheckLimits(); msg.Entries.Remove(dmg); msg.Entries.Add(new DamageEntry(amount, dmg.DamageType, dmg.TargetVital, dmg.Description)); } } } float totalDmg = 0; for (int i = 0; i < msg.Entries.Count; i++) { if (msg.Target.IsDead) { break; } var dmg = msg.Entries[i]; var damageAmount = dmg.Amount; totalDmg += damageAmount; float previousValue = 0; var stats = target.Stats; var vital = stats.GetVital(dmg.TargetVital); if (vital == null) { vital = stats.GetVital(GameData.Vitals.GetID(dmg.TargetVital)); } if (vital != null) { dmgHoverMsg.Append(vital.ToLabelString()); dmgHoverMsg.Append(" - "); dmgHoverMsg.Append(damageAmount); dmgHoverMsg.Append(" = "); previousValue = vital.Current; vital.Current -= damageAmount; dmgHoverMsg.Append(vital.ToLabelString()); } dmgMsg.Append(msg.Target.GetName()); dmgMsg.Append(" took "); dmgMsg.Append(damageAmount.ToString("F1")); dmgMsg.Append(" damage "); if (vital != null && vital.Current <= 0 && dmg.TargetVital == Stats.Health) { target.Entity.Post(new DeathEvent(msg.Origin, msg.Target, msg.Hit.Point, damageAmount - previousValue)); } } if (totalDmg > 0) { target.Entity.Post(new CombatStatusUpdate(target.Entity, totalDmg.ToString("F1"), Color.red)); msg.Origin.Post(new CausedDamageEvent(totalDmg, msg)); msg.Target.Post(new ReceivedDamageEvent(totalDmg, msg)); } logSystem.PostCurrentStrings(GameLogSystem.DamageColor); msg.Clear(); }