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) { } }
/// <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))); }
public NotificationProxyTest() { _configuration = SetupConfigurations.GetApplicationConfiguration(Directory.GetCurrentDirectory()); _rootConfiguration = new Mock <IOptionsSnapshot <RootConfigurations> >(); _rootConfiguration.Setup(m => m.Value).Returns(_configuration); _notificationProxy = new NotificationProxy(_rootConfiguration.Object); }
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); } }
/// <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; }
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) { } }
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); }
/// <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); } } } }
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); }
void SetLocalNotification(NotificationProxy notification) { localNotify = notification; }