예제 #1
0
        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));
            }
        }
예제 #2
0
        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();
        }