public void TryAskForCardUsage(Prompt prompt, ICardUsageVerifier verifier) { ISkill skill; List <Card> cards; List <Player> players; if (!IsPlayable) { if (IsUiDetached) { return; } uiProxy.AskForCardUsage(prompt, verifier, out skill, out cards, out players); return; } if (IsUiDetached || !uiProxy.AskForCardUsage(prompt, verifier, out skill, out cards, out players)) { Trace.TraceInformation("Invalid answer"); client.Send(AskForCardUsageResponse.Parse(numQuestionsAsked, null, null, null, client.SelfId)); } else { client.Send(AskForCardUsageResponse.Parse(numQuestionsAsked, skill, cards, players, client.SelfId)); } }
protected override void Process(Player source, Player dest, ICard card, ReadOnlyCard readonlyCard, GameEventArgs inResponseTo) { IPlayerProxy ui = Game.CurrentGame.UiProxies[dest]; HuoGongCardChoiceVerifier v1 = new HuoGongCardChoiceVerifier(); ISkill s; List <Player> p; List <Card> cards; if (dest.IsDead) { return; } if (!ui.AskForCardUsage(new CardUsagePrompt("HuoGong", source), v1, out s, out cards, out p)) { Trace.TraceInformation("Player {0} Invalid answer", dest); cards = new List <Card>(); if (Game.CurrentGame.Decks[dest, DeckType.Hand].Count == 0) { Trace.TraceError("HuoGong Cannot Show Card! This should NOT have happened!"); return; } cards.Add(Game.CurrentGame.Decks[dest, DeckType.Hand][0]); } var theCard = cards[0]; Game.CurrentGame.SyncCardAll(ref theCard); Trace.TraceInformation("Player {0} HuoGong showed {1}, ", dest.Id, theCard); Game.CurrentGame.NotificationProxy.NotifyShowCard(dest, theCard); if (source.IsDead) { return; } ui = Game.CurrentGame.UiProxies[source]; HuoGongCardMatchVerifier v2 = new HuoGongCardMatchVerifier(theCard.Suit); Game.CurrentGame.HideHandCard(theCard); v2.Owner = source; if (ui.AskForCardUsage(new CardUsagePrompt("HuoGong2", dest, theCard.Suit), v2, out s, out cards, out p)) { Game.CurrentGame.HandleCardDiscard(source, cards); Game.CurrentGame.DoDamage(source, dest, 1, DamageElement.Fire, card, readonlyCard); } else { Trace.TraceInformation("HuoGong aborted, failed to provide card"); } }
protected override void Process(Player source, Player dest, ICard card, ReadOnlyCard readonlyCard, GameEventArgs inResponseTo) { SingleCardUsageVerifier v1 = new SingleCardUsageVerifier((c) => { return(RequiredCard.GetType().IsAssignableFrom(c.Type.GetType())); }, false, RequiredCard); List <Player> sourceList = new List <Player>(); sourceList.Add(source); GameEventArgs args = new GameEventArgs(); args.Source = dest; args.Targets = sourceList; args.Card = new CompositeCard(); args.Card.Type = RequiredCard; args.ReadonlyCard = readonlyCard; try { Game.CurrentGame.Emit(GameEvent.PlayerRequireCard, args); } catch (TriggerResultException e) { if (e.Status == TriggerResult.Success) { Game.CurrentGame.HandleCardPlay(dest, args.Skill, args.Cards, sourceList); return; } } while (true) { IPlayerProxy ui = Game.CurrentGame.UiProxies[dest]; ISkill skill; List <Player> p; List <Card> cards; Game.CurrentGame.Emit(GameEvent.PlayerIsAboutToPlayCard, new PlayerIsAboutToUseOrPlayCardEventArgs() { Source = dest, Verifier = v1 }); if (!ui.AskForCardUsage(new CardUsagePrompt(UsagePromptString, source), v1, out skill, out cards, out p)) { Trace.TraceInformation("Player {0} Invalid answer", dest); Game.CurrentGame.DoDamage(source.IsDead ? null : source, dest, 1, DamageElement.None, card, readonlyCard); } else { if (!Game.CurrentGame.HandleCardPlay(dest, skill, cards, sourceList)) { continue; } Trace.TraceInformation("Player {0} Responded. ", dest.Id); } break; } }
protected override bool DoTransformSideEffect(CompositeCard card, object arg, List <Player> targets, bool isPlay) { ICard result = null; List <Player> toProcess = new List <Player>(Game.CurrentGame.AlivePlayers); toProcess.Remove(Owner); bool noAnswer = true; foreach (var player in toProcess) { if (player.Allegiance == Core.Heroes.Allegiance.Shu) { bool failToRespond = false; while (true) { IPlayerProxy ui = Game.CurrentGame.UiProxies[player]; SingleCardUsageVerifier v1 = new SingleCardUsageVerifier((c) => { return(c.Type is Sha); }, false); ISkill skill; List <Player> p; List <Card> cards; Game.CurrentGame.Emit(isPlay? GameEvent.PlayerIsAboutToPlayCard : GameEvent.PlayerIsAboutToUseCard, new PlayerIsAboutToUseOrPlayCardEventArgs() { Source = player, Verifier = v1 }); if (!ui.AskForCardUsage(new CardUsagePrompt("JiJiang", Owner), v1, out skill, out cards, out p)) { failToRespond = true; break; } if (!Game.CurrentGame.CommitCardTransform(player, skill, cards, out result, targets, isPlay)) { continue; } noAnswer = false; Trace.TraceInformation("Player {0} Responded JiJiang with SHA, ", player.Id); break; } if (failToRespond) { continue; } break; } } Game.CurrentGame.LastAction = this; if (noAnswer) { Owner[JiJiangFailed] = 1; return(false); } Owner[JiJiangFailed] = 0; Trace.Assert(result != null); card.Subcards = new List <Card>(); if (result is CompositeCard) { card.Subcards.AddRange(((CompositeCard)result).Subcards); card.Type = ((CompositeCard)result).Type; } else { Trace.Assert(result is Card); card.Subcards.Add((Card)result); card.Type = ((Card)result).Type; } return(true); }
public override void Run(GameEvent gameEvent, GameEventArgs eventArgs) { if (eventArgs.ReadonlyCard == null) { return; } if (!(eventArgs.ReadonlyCard.Type is Sha)) { return; } Player source = eventArgs.Source; Player dest = eventArgs.Targets[0]; ICard card = eventArgs.Card; List <Player> sourceList = new List <Player>() { source }; GameEventArgs args = new GameEventArgs(); Game.CurrentGame.Emit(PlayerShaTargetShanModifier, eventArgs); // this number is 0 for normal Sha/Shan. Lv Bu would like this to be 1 int numberOfShanRequired = eventArgs.ReadonlyCard[ShaCancellationCount] = eventArgs.ReadonlyCard[CardAttribute.TargetRequireTwoResponses[dest]] + 1; bool cannotUseShan = (eventArgs.ReadonlyCard[CannotProvideShan[dest]] & 1) == 1; eventArgs.ReadonlyCard[CannotProvideShan[dest]] >>= 1; bool cannotProvideShan = false; while (numberOfShanRequired > 0 && !cannotUseShan) { args.Source = dest; args.Targets = sourceList; args.Card = new CompositeCard(); args.Card.Type = new Shan(); args.ReadonlyCard = eventArgs.ReadonlyCard; try { Game.CurrentGame.Emit(GameEvent.PlayerRequireCard, args); } catch (TriggerResultException e) { if (e.Status == TriggerResult.Success) { GameEventArgs arg = new GameEventArgs(); arg.Source = dest; arg.Targets = sourceList; arg.Skill = args.Skill; arg.Cards = args.Cards; arg.InResponseTo = eventArgs; Game.CurrentGame.Emit(GameEvent.CommitActionToTargets, arg); #if SB_FAQ numberOfShanRequired--; #else numberOfShanRequired = eventArgs.ReadonlyCard[ShaCancellationCount]; #endif continue; } } while (true) { IPlayerProxy ui = Game.CurrentGame.UiProxies[dest]; SingleCardUsageVerifier v1 = new SingleCardUsageVerifier((c) => { return(c.Type is Shan); }, true, new Shan()); ISkill skill; List <Player> p; List <Card> cards; Game.CurrentGame.Emit(GameEvent.PlayerIsAboutToUseCard, new PlayerIsAboutToUseOrPlayCardEventArgs() { Source = dest, Verifier = v1 }); if (!ui.AskForCardUsage(new CardUsagePrompt("Sha.Shan", source), v1, out skill, out cards, out p)) { cannotProvideShan = true; break; } try { GameEventArgs arg = new GameEventArgs(); arg.Source = dest; arg.Targets = sourceList; arg.Skill = skill; arg.Cards = cards; arg.InResponseTo = eventArgs; Game.CurrentGame.Emit(GameEvent.CommitActionToTargets, arg); } catch (TriggerResultException e) { Trace.Assert(e.Status == TriggerResult.Retry); continue; } break; } if (cannotProvideShan) { break; } #if SB_FAQ numberOfShanRequired--; #else numberOfShanRequired = eventArgs.ReadonlyCard[ShaCancellationCount]; #endif } if (cannotUseShan || #if SB_FAQ eventArgs.ReadonlyCard[ShaCancellationCount] > 0 #else numberOfShanRequired > 0 #endif ) { return; } Trace.TraceInformation("Successfully dodged"); args = new GameEventArgs(); args.Source = source; args.Targets = new List <Player>(); args.Targets.Add(dest); args.Card = card; args.ReadonlyCard = eventArgs.ReadonlyCard; try { Game.CurrentGame.Emit(PlayerShaTargetDodged, args); } catch (TriggerResultException) { Trace.Assert(false); } throw new TriggerResultException(TriggerResult.End); }
public override void Run(GameEvent gameEvent, GameEventArgs eventArgs) { Player currentPlayer = Game.CurrentGame.CurrentPlayer; Trace.TraceInformation("Player {0} action.", currentPlayer.Id); while (!currentPlayer.IsDead) { bool newturn = false; foreach (var pl in Game.CurrentGame.Players) { if (GetReadyToGo(pl) && pl == currentPlayer) { newturn = true; } } if (newturn) { return; } Trace.Assert(Game.CurrentGame.UiProxies.ContainsKey(currentPlayer)); IPlayerProxy proxy = Game.CurrentGame.UiProxies[currentPlayer]; ISkill skill; List <Card> cards; List <Player> players; PlayerActionStageVerifier v = new PlayerActionStageVerifier(); Game.CurrentGame.Emit(GameEvent.PlayerIsAboutToUseCard, new PlayerIsAboutToUseOrPlayCardEventArgs() { Source = currentPlayer, Verifier = v }); if (!proxy.AskForCardUsage(new Prompt(Prompt.PlayingPhasePrompt), v, out skill, out cards, out players)) { break; } if (skill != null) { if (skill is CheatSkill) { if (!Game.CurrentGame.Settings.CheatEnabled) { break; } CheatSkill cs = skill as CheatSkill; if (cs.CheatType == CheatType.Card) { if (Game.CurrentGame.IsClient) { Game.CurrentGame.SyncUnknownLocationCardAll(null); } else { foreach (var searchCard in Game.CurrentGame.CardSet) { if (searchCard.Id == cs.CardId) { Game.CurrentGame.SyncUnknownLocationCardAll(searchCard); break; } } } foreach (var searchCard in Game.CurrentGame.CardSet) { if (searchCard.Id == cs.CardId) { CardsMovement move = new CardsMovement(); move.Cards = new List <Card>() { searchCard }; move.To = new DeckPlace(Game.CurrentGame.CurrentPlayer, DeckType.Hand); move.Helper = new MovementHelper(); Game.CurrentGame.MoveCards(move); break; } } } else if (cs.CheatType == CheatType.Skill) { foreach (var hero in Game.CurrentGame.OriginalCardSet) { bool found = false; if (hero.Type is HeroCardHandler) { foreach (var sk in (hero.Type as HeroCardHandler).Hero.Skills) { if (sk.GetType().Name == cs.SkillName) { Game.CurrentGame.PlayerAcquireAdditionalSkill(currentPlayer, sk.Clone() as ISkill, currentPlayer.Hero); found = true; break; } } } if (found) { break; } } } continue; } else if (skill is ActiveSkill) { GameEventArgs arg = new GameEventArgs(); arg.Source = Game.CurrentGame.CurrentPlayer; arg.Targets = players; arg.Cards = cards; ((ActiveSkill)skill).NotifyAndCommit(arg); Game.CurrentGame.NotificationProxy.NotifyActionComplete(); Game.CurrentGame.LastAction = skill; continue; } CompositeCard c; CardTransformSkill s = (CardTransformSkill)skill; VerifierResult r = s.TryTransform(cards, players, out c); Trace.TraceInformation("Player used {0}", c.Type); } else { Trace.Assert(cards[0] != null && cards.Count == 1); Trace.TraceInformation("Player used {0}", cards[0].Type); } try { Game.CurrentGame.Emit(GameEvent.CommitActionToTargets, new Triggers.GameEventArgs() { Skill = skill, Source = Game.CurrentGame.CurrentPlayer, Targets = players, Cards = cards }); } catch (TriggerResultException) { } Game.CurrentGame.NotificationProxy.NotifyActionComplete(); Game.CurrentGame.LastAction = skill; } }
protected override void Process(Player source, Player dest, ICard card, ReadOnlyCard readonlyCard, GameEventArgs inResponseTo) { Player current = dest; bool firstTime = true; while (true) { List <Player> sourceList = new List <Player>(); if (current == dest) { sourceList.Add(source); } else { sourceList.Add(dest); } IPlayerProxy ui = Game.CurrentGame.UiProxies[current]; SingleCardUsageVerifier v1 = new SingleCardUsageVerifier((c) => { return(c.Type is Sha); }, false, new Sha()); ISkill skill; List <Player> p; List <Card> cards; CardUsagePrompt prompt; if (current.IsDead) { return; } if (firstTime) { prompt = new CardUsagePrompt("JueDou", source);; } else { prompt = new CardUsagePrompt("JueDou2", current == dest ? source : dest); firstTime = false; } int numberOfShaRequired = current == dest ? readonlyCard[CardAttribute.TargetRequireTwoResponses[dest]] + 1 : readonlyCard[CardAttribute.SourceRequireTwoResponses] + 1; bool cannotProvideSha = false; while (numberOfShaRequired > 0) { Game.CurrentGame.Emit(GameEvent.PlayerIsAboutToPlayCard, new PlayerIsAboutToUseOrPlayCardEventArgs() { Source = current, Verifier = v1 }); if (!ui.AskForCardUsage(prompt, v1, out skill, out cards, out p)) { Trace.TraceInformation("Player {0} Invalid answer", current); cannotProvideSha = true; break; } if (!Game.CurrentGame.HandleCardPlay(current, skill, cards, sourceList)) { continue; } numberOfShaRequired--; } if (cannotProvideSha) { break; } Trace.TraceInformation("Player {0} SHA, ", current.Id); if (current == dest) { current = source; } else { current = dest; } } Player won = current == dest ? source : dest; Game.CurrentGame.DoDamage(won, current, 1, DamageElement.None, card, readonlyCard); }
void CallOfShan(Player Owner, GameEvent gameEvent, GameEventArgs eventArgs) { ICard result = null; List<Player> toProcess = new List<Player>(Game.CurrentGame.AlivePlayers); toProcess.Remove(Owner); bool noAnswer = true; foreach (var player in toProcess) { if (player.Allegiance == Core.Heroes.Allegiance.Wei) { bool failToRespond = false; GameEventArgs args = new GameEventArgs(); args.Source = player; args.Targets = eventArgs.Targets; args.Card = new CompositeCard(); args.Card.Type = new Shan(); args.ReadonlyCard = eventArgs.ReadonlyCard; try { Game.CurrentGame.Emit(GameEvent.PlayerRequireCard, args); } catch (TriggerResultException e) { if (e.Status == TriggerResult.Success) { eventArgs.Skill = args.Skill; eventArgs.Cards = new List<Card>(args.Cards); throw new TriggerResultException(TriggerResult.Success); } } while (true) { IPlayerProxy ui = Game.CurrentGame.UiProxies[player]; SingleCardUsageVerifier v1 = new SingleCardUsageVerifier((c) => { return c.Type is Shan; }, false, new Shan()); ISkill skill; List<Player> p; List<Card> cards; Game.CurrentGame.Emit(GameEvent.PlayerIsAboutToPlayCard, new PlayerIsAboutToUseOrPlayCardEventArgs() { Source = player, Verifier = v1 }); if (!ui.AskForCardUsage(new CardUsagePrompt("HuJia", Owner), v1, out skill, out cards, out p)) { failToRespond = true; break; } if (!Game.CurrentGame.CommitCardTransform(player, skill, cards, out result, eventArgs.Targets, true)) { continue; } if (result is CompositeCard) { eventArgs.Cards = new List<Card>((result as CompositeCard).Subcards); eventArgs.Skill = new CardWrapper(Owner, new Shan()); } else { eventArgs.Cards = new List<Card>() { result as Card }; eventArgs.Skill = null; } noAnswer = false; Trace.TraceInformation("Player {0} Responded HuJia with SHAN, ", player.Id); break; } if (failToRespond) { continue; } break; } } if (noAnswer) { return; } Trace.Assert(result != null); eventArgs.Cards = new List<Card>(); if (result is CompositeCard) { eventArgs.Cards.AddRange(((CompositeCard)result).Subcards); } else { Trace.Assert(result is Card); eventArgs.Cards.Add((Card)result); } throw new TriggerResultException(TriggerResult.Success); }
public void ForcePlayerDiscard(Player player, NumberOfCardsToForcePlayerDiscard numberOfCards, bool canDiscardEquipment, bool atOnce = true) { if (player.IsDead) { return; } Trace.TraceInformation("Player {0} discard.", player); int cannotBeDiscarded = 0; int numberOfCardsDiscarded = 0; while (true) { int handCardCount = Decks[player, DeckType.Hand].Count; // 玩家手牌数 int equipCardCount = Decks[player, DeckType.Equipment].Count; // 玩家装备牌数 int toDiscard = numberOfCards(player, numberOfCardsDiscarded); // Have we finished discarding everything? // We finish if // 玩家手牌数 小于等于 我们要强制弃掉的数目 // 或者玩家手牌数 (小于)等于 不可弃的牌的数目(此时装备若可弃,必须弃光) if (toDiscard == 0 || (handCardCount <= cannotBeDiscarded && (!canDiscardEquipment || equipCardCount == 0))) { break; } Trace.Assert(UiProxies.ContainsKey(player)); IPlayerProxy proxy = UiProxies[player]; ISkill skill; List <Card> cards; List <Player> players; cannotBeDiscarded = 0; foreach (Card c in Decks[player, DeckType.Hand]) { if (!PlayerCanDiscardCard(player, c)) { cannotBeDiscarded++; } } //如果玩家无法达到弃牌要求 则 摊牌 bool status = cannotBeDiscarded == 0 || ((canDiscardEquipment ? equipCardCount : 0) + handCardCount - toDiscard >= cannotBeDiscarded); SyncConfirmationStatus(ref status); if (!status) { SyncImmutableCardsAll(Decks[player, DeckType.Hand]); ShowHandCards(player, Decks[player, DeckType.Hand]); if (Game.CurrentGame.IsClient) { //刷新所有客户端该玩家不可弃掉的牌的数目 cannotBeDiscarded = 0; foreach (Card c in Decks[player, DeckType.Hand]) { if (!PlayerCanDiscardCard(player, c)) { cannotBeDiscarded++; } } } } int minimum; if (!atOnce) { minimum = 1; } else { minimum = status ? toDiscard : (canDiscardEquipment ? equipCardCount : 0) + handCardCount - cannotBeDiscarded; } PlayerForceDiscardVerifier v = new PlayerForceDiscardVerifier(toDiscard, canDiscardEquipment, minimum); if (!proxy.AskForCardUsage(new Prompt(Prompt.DiscardPhasePrompt, toDiscard), v, out skill, out cards, out players)) { //玩家没有回应(default) Trace.TraceInformation("Invalid answer, choosing for you"); cards = new List <Card>(); int cardsDiscarded = 0; var chooseFrom = new List <Card>(Decks[player, DeckType.Hand]); if (canDiscardEquipment) { chooseFrom.AddRange(Decks[player, DeckType.Equipment]); } foreach (Card c in chooseFrom) { if (PlayerCanDiscardCard(player, c)) { cards.Add(c); cardsDiscarded++; } if (cardsDiscarded == toDiscard) { SyncCardsAll(cards); break; } } } numberOfCardsDiscarded += cards.Count; if (cards.Count != 0) { HandleCardDiscard(player, cards); } } }