Exemplo n.º 1
0
        /// <summary>
        /// Inflict damage onto this character.
        /// The actual amount still needs to be determined by the current
        /// state of the game. eg: The presence of immunity effects can cause
        /// the damage to be ignored.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="damage"></param>
        /// <returns></returns>
        public int TakeDamage(IPlayable source, int damage)
        {
            var hero   = this as Hero;
            var minion = this as Minion;

            if (minion != null && minion.Zone.Type != Enums.Zone.PLAY)
            {
                return(0);
            }

            bool fatigue = hero != null && this == source;

            if (fatigue)
            {
                hero.Fatigue = damage;
            }

            if (minion != null && minion.HasDivineShield)
            {
                Game.Log(LogLevel.INFO, BlockType.ACTION, "Character", !Game.Logging? "":$"{this} divine shield absorbed incoming damage.");
                minion.HasDivineShield = false;
                return(0);
            }

            int armor = hero?.Armor ?? 0;

            int amount = hero == null ? damage : armor < damage ? damage - armor : 0;

            // added pre damage
            PreDamage = amount;

            // Predamage triggers (Ice Block)
            if (PreDamageTrigger != null)
            {
                PreDamageTrigger.Invoke(this);
                amount = PreDamage;
            }
            if (IsImmune)
            {
                Game.Log(LogLevel.INFO, BlockType.ACTION, "Character", !Game.Logging ? "" : $"{this} is immune.");
                PreDamage = 0;
                return(0);
            }

            // remove armor first from hero ....
            if (armor > 0)
            {
                hero.Armor = armor < damage ? 0 : armor - damage;
            }

            // final damage is beeing accumulated
            Damage += amount;

            Game.Log(LogLevel.INFO, BlockType.ACTION, "Character", !Game.Logging? "":$"{this} took damage for {PreDamage}({damage}). {(fatigue ? "(fatigue)" : "")}");

            // reset predamage
            PreDamage = 0;

            //LastAffectedBy = source.Id;	TODO


            // Damage event is created
            // Collect all the tasks and sort them by order of play
            // Death phase and aura update are not emerge here

            // place event related data
            Game.TaskQueue.StartEvent();
            EventMetaData temp = Game.CurrentEventData;

            Game.CurrentEventData = new EventMetaData(source, this, amount);

            // on-damage triggers
            TakeDamageTrigger?.Invoke(this);
            Game.TriggerManager.OnDamageTrigger(this);
            Game.TriggerManager.OnDealDamageTrigger(source);
            Game.ProcessTasks();
            Game.TaskQueue.EndEvent();
            Game.CurrentEventData = temp;

            if (source.HasLifeSteal && !_lifestealChecker)
            {
                if (_history)
                {
                    Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, source.Id, source.Card.Id, -1, 0));                     // TriggerKeyword=LIFESTEAL
                }
                Game.Log(LogLevel.VERBOSE, BlockType.ATTACK, "TakeDamage", !_logging ? "" : $"lifesteal source {source} has damaged target for {amount}.");
                source.Controller.Hero.TakeHeal(source, amount);
                if (_history)
                {
                    Game.PowerHistory.Add(new PowerHistoryBlockEnd());
                }

                if (source.Controller.Hero.ToBeDestroyed && source.Controller.Hero.Health > 0)
                {
                    source.Controller.Hero.ToBeDestroyed = false;
                }
            }

            if (this is Hero h)
            {
                h.IsDamagedThisTurn = true;
            }

            return(amount);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Inflict damage onto this character.
        /// The actual amount still needs to be determined by the current
        /// state of the game. eg: The presence of immunity effects can cause
        /// the damage to be ignored.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="damage"></param>
        /// <returns></returns>
        public int TakeDamage(IPlayable source, int damage)
        {
            var hero   = this as Hero;
            var minion = this as Minion;

            bool fatigue = hero != null && this == source;

            if (fatigue)
            {
                hero.Fatigue = damage;
            }

            if (minion != null && minion.HasDivineShield)
            {
                Game.Log(LogLevel.INFO, BlockType.ACTION, "Character", !Game.Logging? "":$"{this} divine shield absorbed incoming damage.");
                minion.HasDivineShield = false;
                return(0);
            }

            int armor = hero?.Armor ?? 0;

            // added pre damage
            int preDamage = hero == null ? damage : armor < damage ? damage - armor : 0;

            PreDamage = preDamage;



            // Predamage triggers
            Game.TaskStack.SetDamageMetaData(source, this);
            PreDamageTrigger?.Invoke(this, preDamage);

            // reflect changes from tasks
            preDamage = PreDamage;
            if (this.IsImmune)
            {
                Game.Log(LogLevel.INFO, BlockType.ACTION, "Character", !Game.Logging? "":$"{this} is immune.");
                PreDamage = 0;
                Trigger.Invalidate(Game, SequenceType.DamageDealt);
                return(0);
            }

            // remove armor first from hero ....
            if (armor > 0)
            {
                hero.Armor = armor < damage ? 0 : armor - damage;
            }


            // final damage is beeing accumulated
            Damage += preDamage;

            Game.Log(LogLevel.INFO, BlockType.ACTION, "Character", !Game.Logging? "":$"{this} took damage for {PreDamage}({damage}). {(fatigue ? "(fatigue)" : "")}");

            // check if there was damage done
            int tookDamage = preDamage;

            // reset predamage
            PreDamage = 0;

            LastAffectedBy = source.Id;

            // Damage event is created
            // Collect all the tasks and sort them by order of play
            // Death phase and aura update is not emerge here

            // on-damage triggers
            Game.TaskQueue.StartEvent();
            Game.TriggerManager.OnDamageTrigger(this);
            Game.TriggerManager.OnDealDamageTrigger(source, preDamage);
            Game.ProcessTasks();
            Game.TaskQueue.EndEvent();
            if (source.HasLifeSteal && !_lifestealChecker)
            {
                if (_history)
                {
                    Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, source.Id, source.Card.Id, -1, 0));                     // TriggerKeyword=LIFESTEAL
                }
                Game.Log(LogLevel.VERBOSE, BlockType.ATTACK, "TakeDamage", !_logging ? "" : $"lifesteal source {source} has damaged target for {preDamage}.");
                source.Controller.Hero.TakeHeal(source, preDamage);
                if (_history)
                {
                    Game.PowerHistory.Add(new PowerHistoryBlockEnd());
                }

                if (source.Controller.Hero.ToBeDestroyed && source.Controller.Hero.Health > 0)
                {
                    source.Controller.Hero.ToBeDestroyed = false;
                }
            }

            return(tookDamage);
        }