Наследование: GameEventArgs
Пример #1
0
        /// <summary>
        /// 造成伤害
        /// </summary>
        /// <param name="source">伤害来源</param>
        /// <param name="dest">伤害目标</param>
        /// <param name="magnitude">伤害点数</param>
        /// <param name="elemental">伤害属性</param>
        /// <param name="cards">造成伤害的牌</param>
        public void DoDamage(Player source, Player dest, int magnitude, DamageElement elemental, ICard card, ReadOnlyCard readonlyCard)
        {
            var damageArgs = new DamageEventArgs() { Source = source, Targets = new List<Player>(), Magnitude = magnitude, Element = elemental };
            HealthChangedEventArgs healthChangedArgs;
            int ironShackledDamage = 0;
            DamageElement ironShackledDamageElement = DamageElement.None;
            damageArgs.ReadonlyCard = readonlyCard;
            if (card is CompositeCard)
            {
                if ((card as CompositeCard).Subcards != null)
                {
                    damageArgs.Cards = new List<Card>((card as CompositeCard).Subcards);
                }
            }
            else if (card is Card)
            {
                damageArgs.Cards = new List<Card>() { card as Card };
            }
            else
            {
                damageArgs.Cards = new List<Card>();
            }
            damageArgs.Targets.Add(dest);
            damageArgs.Card = card;

            try
            {
                Game.CurrentGame.Emit(GameEvent.DamageSourceConfirmed, damageArgs);
                Game.CurrentGame.Emit(GameEvent.DamageElementConfirmed, damageArgs);
                Game.CurrentGame.Emit(GameEvent.BeforeDamageComputing, damageArgs);
                Game.CurrentGame.Emit(GameEvent.DamageComputingStarted, damageArgs);
                Game.CurrentGame.Emit(GameEvent.DamageCaused, damageArgs);
                Game.CurrentGame.Emit(GameEvent.DamageInflicted, damageArgs);
                if (damageArgs.Magnitude == 0)
                {
                    Trace.TraceInformation("Damage is 0, aborting");
                    return;
                }
                if (damageArgs.Targets[0].IsIronShackled && damageArgs.Element != DamageElement.None)
                {
                    ironShackledDamage = damageArgs.Magnitude;
                    Trace.TraceInformation("IronShackled damage {0}", ironShackledDamage);
                    ironShackledDamageElement = damageArgs.Element;
                    damageArgs.Targets[0].IsIronShackled = false;
                }
                healthChangedArgs = new HealthChangedEventArgs(damageArgs);
                Game.CurrentGame.Emit(GameEvent.BeforeHealthChanged, healthChangedArgs);
                damageArgs.Magnitude = -healthChangedArgs.Delta;
            }
            catch (TriggerResultException e)
            {
                if (e.Status == TriggerResult.End)
                {
                    Trace.TraceInformation("Damage Aborted");
                    return;
                }
                Trace.Assert(false);
                return;
            }

            Trace.Assert(damageArgs.Targets.Count == 1);
            damageArgs.Targets[0].Health -= damageArgs.Magnitude;
            Trace.TraceInformation("Player {0} Lose {1} hp, @ {2} hp", damageArgs.Targets[0].Id, damageArgs.Magnitude, damageArgs.Targets[0].Health);
            NotificationProxy.NotifyDamage(source, damageArgs.Targets[0], damageArgs.Magnitude, damageArgs.Element);

            try
            {
                Game.CurrentGame.Emit(GameEvent.AfterHealthChanged, healthChangedArgs);
            }
            catch (TriggerResultException)
            {
            }
            Game.CurrentGame.Emit(GameEvent.AfterDamageCaused, damageArgs);
            Game.CurrentGame.Emit(GameEvent.AfterDamageInflicted, damageArgs);
            Game.CurrentGame.Emit(GameEvent.DamageComputingFinished, damageArgs);
            if (ironShackledDamage != 0)
            {
                List<Player> toProcess = new List<Player>(Game.CurrentGame.AlivePlayers);
                Game.CurrentGame.SortByOrderOfComputation(damageArgs.Targets[0], toProcess);
                foreach (Player p in toProcess)
                {
                    if (p.IsIronShackled)
                    {
                        DoDamage(damageArgs.Source, p, ironShackledDamage, ironShackledDamageElement, card, readonlyCard);
                    }
                }
            }
        }
Пример #2
0
 public HealthChangedEventArgs(DamageEventArgs args)
 {
     CopyFrom(args);
     Delta = -args.Magnitude;
 }
Пример #3
0
 public HealthChangedEventArgs(DamageEventArgs args)
 {
     CopyFrom(args);
     Delta = -args.Magnitude;
 }
Пример #4
0
        /// <summary>
        /// 造成伤害
        /// </summary>
        /// <param name="source">伤害来源</param>
        /// <param name="dest">伤害目标</param>
        /// <param name="originalTarget">最初的伤害目标</param>
        /// <param name="magnitude">伤害点数</param>
        /// <param name="elemental">伤害属性</param>
        /// <param name="cards">造成伤害的牌</param>
        public void DoDamage(Player source, Player dest, Player originalTarget, int magnitude, DamageElement elemental, ICard card, ReadOnlyCard readonlyCard)
        {
            if (dest.IsDead) return;
            var damageArgs = new DamageEventArgs() { Source = source, OriginalTarget = originalTarget, Targets = new List<Player>(), Magnitude = magnitude, Element = elemental };
            HealthChangedEventArgs healthChangedArgs;
            int ironShackledDamage = 0;
            DamageElement ironShackledDamageElement = DamageElement.None;
            if (readonlyCard == null)
            {
                readonlyCard = new ReadOnlyCard(new Card() { Place = new DeckPlace(null, null) });
            }
            damageArgs.ReadonlyCard = readonlyCard;
            if (card is CompositeCard)
            {
                if ((card as CompositeCard).Subcards != null)
                {
                    damageArgs.Cards = new List<Card>((card as CompositeCard).Subcards);
                }
            }
            else if (card is Card)
            {
                damageArgs.Cards = new List<Card>() { card as Card };
            }
            else
            {
                damageArgs.Cards = new List<Card>();
            }
            damageArgs.Targets.Add(dest);
            damageArgs.Card = card;

            try
            {
                //伤害来源与基数、属性的确定发生在伤害结算前,连环,以及转移的伤害不会重新确定来源与基数,所以不会多次触发【裸衣】,以及【酒】
                while (damageArgs.ReadonlyCard[SourceAndElementIsConfirmed] == 0)
                {
                    Emit(GameEvent.DamageSourceConfirmed, damageArgs);
                    Emit(GameEvent.DamageElementConfirmed, damageArgs);
                    damageArgs.ReadonlyCard[SourceAndElementIsConfirmed] = 1;
                    break;
                }
                Emit(GameEvent.BeforeDamageComputing, damageArgs);
                Emit(GameEvent.DamageComputingStarted, damageArgs);
                Emit(GameEvent.DamageCaused, damageArgs);
                Emit(GameEvent.DamageInflicted, damageArgs);
                if (damageArgs.Magnitude == 0)
                {
                    Trace.TraceInformation("Damage is 0, aborting");
                    return;
                }
                if (damageArgs.Targets[0].IsIronShackled && damageArgs.Element != DamageElement.None)
                {
                    ironShackledDamage = damageArgs.Magnitude;
                    Trace.TraceInformation("IronShackled damage {0}", ironShackledDamage);
                    ironShackledDamageElement = damageArgs.Element;
                    damageArgs.Targets[0].IsIronShackled = false;
                    // if this is TieSuo damage already, prevent itself from spreading...
                    if (readonlyCard[IsIronShackleDamage] == 1) ironShackledDamage = 0;
                }
                healthChangedArgs = new HealthChangedEventArgs(damageArgs);
                Emit(GameEvent.BeforeHealthChanged, healthChangedArgs);
                damageArgs.Magnitude = -healthChangedArgs.Delta;
            }
            catch (TriggerResultException e)
            {
                if (e.Status == TriggerResult.End)
                {
                    //伤害结算完毕事件应该总是被触发
                    //受到伤害的角色如果存活能发动的技能/会执行的技能效果:【酒诗②】、执行【天香】摸牌的效果。
                    Emit(GameEvent.DamageComputingFinished, damageArgs);
                    Trace.TraceInformation("Damage Aborted");
                    return;
                }
                Trace.Assert(false);
                return;
            }

            Trace.Assert(damageArgs.Targets.Count == 1);
            damageArgs.Targets[0].Health -= damageArgs.Magnitude;
            Trace.TraceInformation("Player {0} Lose {1} hp, @ {2} hp", damageArgs.Targets[0].Id, damageArgs.Magnitude, damageArgs.Targets[0].Health);
            NotificationProxy.NotifyDamage(source, damageArgs.Targets[0], damageArgs.Magnitude, damageArgs.Element);

            try
            {
                Emit(GameEvent.AfterHealthChanged, healthChangedArgs);
            }
            catch (TriggerResultException)
            {
            }
            Emit(GameEvent.AfterDamageCaused, damageArgs);
            Emit(GameEvent.AfterDamageInflicted, damageArgs);
            Emit(GameEvent.DamageComputingFinished, damageArgs);
            if (ironShackledDamage != 0)
            {
                List<Player> toProcess = new List<Player>(AlivePlayers);
                SortByOrderOfComputation(CurrentPlayer, toProcess);
                foreach (Player p in toProcess)
                {
                    if (p.IsIronShackled)
                    {
                        GameDelays.Delay(GameDelayTypes.TieSuoDamage);
                        readonlyCard[IsIronShackleDamage] = 1;
                        DoDamage(damageArgs.Source, p, originalTarget, ironShackledDamage, ironShackledDamageElement, card, readonlyCard);
                    }
                }
            }
        }