public static void Heal(this IEffectHolder holder, double heal, PopupHelper popupHelper)
        {
            var damageEffects = holder.GetEffects <EffectDamage>().ToList();
            var totalDamage   = damageEffects.Sum(x => x.Amount);
            var totalHeal     = heal + Math.Max(0, totalDamage - holder.GetStat(Stat.HP));
            var healAmounts   = Util.ProportionalSplit(damageEffects.Select(x => x.Amount), totalHeal);
            int i             = 0;

            foreach (var damage in damageEffects)
            {
                damage.Amount -= healAmounts[i];
                if (damage.Amount <= 0)
                {
                    damage.Remove();
                }
                i++;
            }

            popupHelper?.Add(new MessageHeal(holder, heal));
        }
Beispiel #2
0
        public virtual IEnumerable <Wait> RoutineStart()
        {
            CalculateDamage();
            CalculateArmor();

            yield return(Attacker.OnStartAttack(this));

            yield return(Defender.OnStartDefend(this));

            List <Wait> waits = new List <Wait>();

            foreach (var effect in ExtraEffects)
            {
                waits.Add(effect.Start(this));
            }
            yield return(new WaitAll(waits));

            FinalDamage = Elements.ToDictionary(pair => pair.Key, pair => CalculateSplitElement(pair.Key, pair.Value * Damage));

            if (!Unblockable)
            {
                var blockChance     = Defender.GetStat(Stat.BlockChance);
                var critBlockChance = Defender.GetStat(Stat.CritBlockChance);

                CheckBlock(blockChance, critBlockChance, ref Blocked, ref CritBlocked);
            }

            if (Blocked || CritBlocked)
            {
                var blockValue = Defender.GetStat(Stat.BlockValue);
                var blockRate  = Defender.GetStat(Stat.BlockRate);

                BlockDamage(blockValue, blockRate);
                PopupHelper.Add(new MessageText(Defender, "Blocked!"));
            }

            foreach (var damage in FinalDamage)
            {
                if (damage.Value >= 0)
                {
                    Defender.TakeDamage(damage.Value, damage.Key, PopupHelper);
                }
                else
                {
                    Defender.Heal(-damage.Value, PopupHelper);
                }
            }
            foreach (var statusEffect in StatusEffects)
            {
                Defender.AddStatusEffect(statusEffect);
            }
            double total = FinalDamage.Sum(x => Math.Abs(x.Value));

            Effect.Apply(new EffectLastHit(Defender, Attacker, total));

            if (Defender is Creature creature)
            {
                if (HitEffects.Empty() && !NoStandardEffect)
                {
                    GenerateHitEffects(creature);
                }
                Scheduler.Instance.Run(RoutineHitEffects(creature));
            }

            waits.Clear();
            foreach (var effect in ExtraEffects)
            {
                waits.Add(effect.End(this));
            }
            yield return(new WaitAll(waits));

            yield return(Attacker.OnAttack(this));

            yield return(Defender.OnDefend(this));

            yield return(new WaitAll(Waits));

            if (CheckDeath && Defender is Creature targetCreature)
            {
                targetCreature.CheckDead(HitDirection);
            }
        }