Esempio n. 1
0
        public void LoseHealth(Player source, int magnitude)
        {
            if (source.IsDead)
            {
                return;
            }
            var args = new HealthChangedEventArgs()
            {
                Source = null, Delta = -magnitude
            };

            args.Targets.Add(source);

            Emit(GameEvent.BeforeHealthChanged, args);

            Trace.Assert(args.Targets.Count == 1);
            args.Targets[0].Health += args.Delta;
            Trace.TraceInformation("Player {0} lose {1} hp, @ {2} hp", args.Targets[0].Id, -args.Delta, args.Targets[0].Health);
            NotificationProxy.NotifyLoseHealth(args.Targets[0], -args.Delta);
            GameDelays.Delay(GameDelays.Damage);

            try
            {
                Emit(GameEvent.AfterHealthChanged, args);
            }
            catch (TriggerResultException)
            {
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a <see cref="EventMapper"/> for a notification interface event.
        /// </summary>
        /// <param name="eventRegistration">The expression registering for the mapped event.</param>
        /// <returns>The method mapper.</returns>
        /// <exception cref="InvalidCommandMethodExpressionException">
        ///     Thrown when the <paramref name="eventRegistration"/> expression does not contain a event registration call on the
        ///     notification interface.
        /// </exception>
        /// <exception cref="TypeIsNotAValidCommandSetException">
        ///     Thrown when the delegate type of the event is not a <see cref="EventHandler"/> or a <see cref="EventHandler{T}"/>.
        /// </exception>
        public EventMapper From(Action <TNotification> eventRegistration)
        {
            var proxy  = new NotificationProxy();
            var tester = (TNotification)proxy.GetTransparentProxy();

            eventRegistration(tester);

            var eventName = proxy.Invocations.FirstOrDefault();

            if (eventName == null)
            {
                throw new InvalidNotificationMethodExpressionException();
            }

            var eventInfo = typeof(TNotification).GetEvent(eventName);

            if (eventInfo == null)
            {
                throw new InvalidNotificationMethodExpressionException();
            }

            return(new EventMapper(
                       StoreDefinition,
                       NotificationId.Create(eventInfo)));
        }
Esempio n. 3
0
        public NotificationProxyTest()
        {
            _configuration = SetupConfigurations.GetApplicationConfiguration(Directory.GetCurrentDirectory());

            _rootConfiguration = new Mock <IOptionsSnapshot <RootConfigurations> >();
            _rootConfiguration.Setup(m => m.Value).Returns(_configuration);
            _notificationProxy = new NotificationProxy(_rootConfiguration.Object);
        }
Esempio n. 4
0
        public void ShowHandCards(Player p, List <Card> cards)
        {
            if (cards.Count == 0)
            {
                return;
            }
            NotificationProxy.NotifyShowCardsStart(p, cards);
            Dictionary <Player, int> answers;

            GlobalProxy.AskForMultipleChoice(new MultipleChoicePrompt("ShowCards", p), new List <OptionPrompt>()
            {
                OptionPrompt.YesChoice
            }, AlivePlayers, out answers);
            NotificationProxy.NotifyShowCardsEnd();
            foreach (Card c in cards)
            {
                Game.CurrentGame.HideHandCard(c);
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Load the device.
        /// </summary>
        /// <exception cref="IOException"></exception>
        /// <exception cref="NotSupportedException"></exception>
        public void Load()
        {
            NotificationCenter = NotificationProxy.GetNotificationCenter();

            if (LSRetailPosis.Settings.HardwareProfiles.LineDisplay.DeviceType != DeviceTypes.OPOS)
            {
                return;
            }

            NetTracer.Information("Peripheral [LineDisplay] - OPOS device loading: {0}", DeviceName ?? "<Undefined>");

            // If character set is not supported by OS, then error out.
            if (!Encoding.GetEncodings().Any(p => p.CodePage == characterSet))
            {
                throw new NotSupportedException(string.Format("Peripheral [LineDisplay] - Character set '{0}' is not supported by Windows OS", characterSet));
            }

            oposLineDisplay = new OPOSLineDisplayClass();

            //Open
            oposLineDisplay.Open(DeviceName);
            Peripherals.CheckResultCode(this, oposLineDisplay.ResultCode);

            // Claim
            oposLineDisplay.ClaimDevice(Peripherals.ClaimTimeOut);
            Peripherals.CheckResultCode(this, oposLineDisplay.ResultCode);

            // Enable/Configure
            oposLineDisplay.DeviceEnabled = true;

            // If character set is not supported by device, then disable and error out.
            if (!oposLineDisplay.CharacterSetList.Split(CharacterSetListSeparator).Any(p => p.Equals(characterSet.ToString(), StringComparison.OrdinalIgnoreCase)))
            {
                oposLineDisplay.ReleaseDevice();
                oposLineDisplay.Close();

                throw new NotSupportedException(string.Format("Peripheral [LineDisplay] - Character set '{0}' is not supported by device.", characterSet));
            }

            oposLineDisplay.CharacterSet = characterSet;
            IsActive = true;
        }
Esempio n. 6
0
        public void RecoverHealth(Player source, Player target, int magnitude)
        {
            if (target.IsDead)
            {
                return;
            }
            if (target.Health >= target.MaxHealth)
            {
                return;
            }
            var args = new HealthChangedEventArgs()
            {
                Source = source, Delta = magnitude
            };

            args.Targets.Add(target);

            Emit(GameEvent.BeforeHealthChanged, args);

            Trace.Assert(args.Targets.Count == 1);
            if (args.Targets[0].Health + args.Delta > args.Targets[0].MaxHealth)
            {
                args.Targets[0].Health = args.Targets[0].MaxHealth;
            }
            else
            {
                args.Targets[0].Health += args.Delta;
            }

            Trace.TraceInformation("Player {0} gain {1} hp, @ {2} hp", args.Targets[0].Id, args.Delta, args.Targets[0].Health);
            NotificationProxy.NotifyRecoverHealth(args.Targets[0], args.Delta);

            try
            {
                Emit(GameEvent.AfterHealthChanged, args);
            }
            catch (TriggerResultException)
            {
            }
        }
Esempio n. 7
0
        public bool?PinDianReturnCards(Player from, Player to, out Card c1, out Card c2, ISkill skill, out bool c1Taken, out bool c2Taken)
        {
            NotificationProxy.NotifyLogEvent(new LogEvent("PinDianStart", from, to), new List <Player>()
            {
                from, to
            }, false);
            NotificationProxy.NotifyPinDianStart(from, to, skill);
            Dictionary <Player, ISkill>         aSkill;
            Dictionary <Player, List <Card> >   aCards;
            Dictionary <Player, List <Player> > aPlayers;

            GlobalProxy.AskForMultipleCardUsage(new CardUsagePrompt("PinDian"), new PinDianVerifier(), new List <Player>()
            {
                from, to
            }, out aSkill, out aCards, out aPlayers);
            Card card1, card2;

            if (!aCards.ContainsKey(from) || aCards[from].Count == 0)
            {
                card1 = Decks[from, DeckType.Hand][0];
                SyncImmutableCardAll(card1);
            }
            else
            {
                card1 = aCards[from][0];
            }
            if (!aCards.ContainsKey(to) || aCards[to].Count == 0)
            {
                card2 = Decks[to, DeckType.Hand][0];
                SyncImmutableCardAll(card2);
            }
            else
            {
                card2 = aCards[to][0];
            }
            c1 = card1;
            c2 = card2;
            NotificationProxy.NotifyPinDianEnd(c1, c2);
            NotificationProxy.NotifyLogEvent(new LogEvent("PinDianCard", from, c1), new List <Player>()
            {
                from, to
            }, false, false);
            NotificationProxy.NotifyLogEvent(new LogEvent("PinDianCard", to, c2), new List <Player>()
            {
                from, to
            }, false, false);
            NotificationProxy.NotifyLogEvent(new LogEvent("PinDianResult", from, to, new LogEventArg(c1.Rank > c2.Rank ? "Win" : "notWin")), new List <Player>()
            {
                from, to
            }, false);
            bool?ret = null;

            if (card1.Rank > card2.Rank)
            {
                ret = true;
            }
            if (card1.Rank < card2.Rank)
            {
                ret = false;
            }
            var arg = new PinDianCompleteEventArgs();

            arg.Source  = from;
            arg.Targets = new List <Player>()
            {
                to
            };
            arg.Cards = new List <Card>()
            {
                c1, c2
            };
            arg.CardsResult = new List <bool>()
            {
                false, false
            };
            arg.PinDianResult = ret;
            Emit(GameEvent.PinDianComplete, arg);
            c1Taken = arg.CardsResult[0];
            c2Taken = arg.CardsResult[1];
            return(ret);
        }
Esempio n. 8
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(damageArgs.Source, damageArgs.Targets[0], damageArgs.Magnitude, damageArgs.Element);
            GameDelays.Delay(GameDelays.Damage);

            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)
                    {
                        readonlyCard[IsIronShackleDamage] = 1;
                        DoDamage(damageArgs.Source, p, originalTarget, ironShackledDamage, ironShackledDamageElement, card, readonlyCard);
                    }
                }
            }
        }
Esempio n. 9
0
        public ReadOnlyCard Judge(Player player, ISkill skill = null, ICard handler = null, JudgementResultSucceed del = null)
        {
            ActionLog log = new ActionLog();

            log.SkillAction = skill;
            log.CardAction  = handler;
            log.Source      = player;
            log.GameAction  = GameAction.Judge;
            CardsMovement move = new CardsMovement();
            Card          c;
            int           initCount = decks[player, DeckType.JudgeResult].Count;

            SyncImmutableCardAll(PeekCard(0));
            c          = DrawCard();
            c.Log      = log;
            move       = new CardsMovement();
            move.Cards = new List <Card>();
            move.Cards.Add(c);
            move.To = new DeckPlace(player, DeckType.JudgeResult);
            MoveCards(move, false, GameDelays.None);
            GameEventArgs args = new GameEventArgs();

            args.Source = player;
            if (triggers.ContainsKey(GameEvent.PlayerJudgeBegin) && triggers[GameEvent.PlayerJudgeBegin].Count > 0)
            {
                NotifyIntermediateJudgeResults(player, log, del);
            }
            Emit(GameEvent.PlayerJudgeBegin, args);
            c = Decks[player, DeckType.JudgeResult].Last();
            args.ReadonlyCard = new ReadOnlyCard(c);
            args.Cards        = new List <Card>()
            {
                c
            };
            args.Skill = skill;
            args.Card  = handler;
            bool?succeed = null;

            if (del != null)
            {
                succeed = del(args.ReadonlyCard);
            }

            Card uiCard = new Card(args.ReadonlyCard);

            uiCard.Id = (args.ReadonlyCard as ReadOnlyCard).Id;
            if (uiCard.Log == null)
            {
                uiCard.Log = new ActionLog();
            }
            uiCard.Log = log;
            NotificationProxy.NotifyJudge(player, uiCard, log, succeed);
            Emit(GameEvent.PlayerJudgeDone, args);
            Trace.Assert(args.Source == player);
            Trace.Assert(args.ReadonlyCard is ReadOnlyCard);

            if (decks[player, DeckType.JudgeResult].Count > initCount)
            {
                c          = decks[player, DeckType.JudgeResult].Last();
                move       = new CardsMovement();
                move.Cards = new List <Card>();
                move.Cards.Add(c);
                List <Card> backup = new List <Card>(move.Cards);
                move.To     = new DeckPlace(null, DeckType.Discard);
                move.Helper = new MovementHelper();
                PlayerAboutToDiscardCard(player, move.Cards, DiscardReason.Judge);
                MoveCards(move, false, GameDelays.None);
                PlayerDiscardedCard(player, backup, DiscardReason.Judge);
            }
            GameDelays.Delay(GameDelays.JudgeEnd);
            return(args.ReadonlyCard as ReadOnlyCard);
        }
Esempio n. 10
0
 void SetLocalNotification(NotificationProxy notification)
 {
     localNotify = notification;
 }