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) { } }
protected override void GetJudgeCards(List <Card> list) { if (list[0].Suit == SuitType.Heart) { return; } GameDelays.Delay(GameDelays.JudgeEnd); GameDelays.Delay(GameDelays.JudgeEnd); CardsMovement move = new CardsMovement(); move.Cards = new List <Card>(list); move.To = new DeckPlace(Owner, TianDeck); move.Helper.PrivateDeckHeroTag = tag; Game.CurrentGame.MoveCards(move); }
void Run(Player Owner, GameEvent gameEvent, GameEventArgs eventArgs) { Owner[FenXinUsed] = 1; Player target = eventArgs.Targets[0]; Card role1 = Game.CurrentGame.Decks[Owner, RoleGame.RoleDeckType][0]; Card role2 = Game.CurrentGame.Decks[target, RoleGame.RoleDeckType][0]; Game.CurrentGame.SyncCard(target, ref role1); Game.CurrentGame.SyncCard(Owner, ref role2); List <CardsMovement> moves = new List <CardsMovement>(); CardsMovement move1 = new CardsMovement(); move1.Cards = new List <Card>() { role1 }; move1.To = new DeckPlace(target, RoleGame.RoleDeckType); moves.Add(move1); CardsMovement move2 = new CardsMovement(); move2.Cards = new List <Card>() { role2 }; move2.To = new DeckPlace(Owner, RoleGame.RoleDeckType); moves.Add(move2); Game.CurrentGame.MoveCards(moves); var role = role2.Type as RoleCardHandler; if (role != null) { Owner.Role = role.Role; } role = role1.Type as RoleCardHandler; if (role != null) { target.Role = role.Role; } GameDelays.Delay(GameDelays.RoleDistribute); }
public override void Run(GameEvent gameEvent, GameEventArgs eventArgs) { Pk1v1Game game = Game.CurrentGame as Pk1v1Game; foreach (Player pp in game.Players) { game.HandCardVisibility.Add(pp, new List <Player>() { pp }); } // Put the whole deck in the dealing deck foreach (Card card in game.CardSet) { // We don't want hero cards if (card.Type is HeroCardHandler) { game.Decks[DeckType.Heroes].Add(card); card.Place = new DeckPlace(null, DeckType.Heroes); } else if (card.Type is RoleCardHandler) { card.Place = new DeckPlace(null, RoleDeckType); } else { game.Decks[DeckType.Dealing].Add(card); card.Place = new DeckPlace(null, DeckType.Dealing); } } if (game.Players.Count == 0) { return; } // Await role decision int seed = DateTime.Now.Millisecond; game.Seed = seed; Trace.TraceError("Seed is {0}", seed); if (game.RandomGenerator == null) { game.RandomGenerator = new Random(seed); Random random = game.RandomGenerator; } int selectorId = game.RandomGenerator.Next(2); int rulerId = 0; bool selectorIs0 = selectorId == 0; game.SyncConfirmationStatus(ref selectorIs0); if (selectorIs0) { selectorId = 0; } else { selectorId = 1; } int wantToBeRuler = 0; game.Players[selectorId].AskForMultipleChoice(new MultipleChoicePrompt("BeRuler"), OptionPrompt.YesNoChoices, out wantToBeRuler); rulerId = 1 - (wantToBeRuler ^ selectorId); Trace.Assert(rulerId >= 0 && rulerId <= 1); Trace.Assert(game.Players.Count == 2); if (rulerId == 0) { game.AvailableRoles.Add(Role.Ruler); game.AvailableRoles.Add(Role.Defector); game.Decks[null, RoleDeckType].Add(_FindARoleCard(Role.Ruler)); game.Decks[null, RoleDeckType].Add(_FindARoleCard(Role.Defector)); } else { game.AvailableRoles.Add(Role.Defector); game.AvailableRoles.Add(Role.Ruler); game.Decks[null, RoleDeckType].Add(_FindARoleCard(Role.Defector)); game.Decks[null, RoleDeckType].Add(_FindARoleCard(Role.Ruler)); } List <CardsMovement> moves = new List <CardsMovement>(); int i = 0; foreach (Player p in game.Players) { CardsMovement move = new CardsMovement(); move.Cards = new List <Card>() { game.Decks[null, RoleDeckType][i] }; move.To = new DeckPlace(p, RoleDeckType); moves.Add(move); i++; } game.MoveCards(moves, null, GameDelays.GameStart); GameDelays.Delay(GameDelays.RoleDistribute); //hero allocation game.Shuffle(game.Decks[DeckType.Heroes]); List <Card> heroPool = new List <Card>(); int toDraw = 12; for (int rc = 0; rc < toDraw; rc++) { game.SyncImmutableCardAll(game.Decks[DeckType.Heroes][rc]); heroPool.Add(game.Decks[DeckType.Heroes][rc]); } game.SyncImmutableCards(game.Players[rulerId], heroPool); DeckType tempHero = DeckType.Register("TempHero"); game.Decks[null, tempHero].AddRange(heroPool); Trace.TraceInformation("Ruler is {0}", rulerId); game.Players[rulerId].Role = Role.Ruler; game.Players[1 - rulerId].Role = Role.Defector; List <int> heroSelectCount = new List <int>() { 1, 2, 2, 2, 2, 2, 1 }; int seq = 0; int turn = rulerId; Dictionary <int, int> map = new Dictionary <int, int>(); map.Add(0, 0); map.Add(1, 1); var deckPlace = new DeckPlace(null, tempHero); game.NotificationProxy.NotifyTwoSidesCardPickStart(new CardChoicePrompt("Pk1v1.InitHeroPick.Init"), deckPlace, map, 6, 6); while (heroSelectCount.Count > seq) { List <DeckPlace> sourceDecks = new List <DeckPlace>(); sourceDecks.Add(new DeckPlace(null, tempHero)); List <string> resultDeckNames = new List <string>(); resultDeckNames.Add("HeroChoice"); List <int> resultDeckMaximums = new List <int>(); int numHeroes = heroSelectCount[seq]; resultDeckMaximums.Add(numHeroes); List <List <Card> > answer; var newVer = new Pk1v1HeroChoiceVerifier(1, seq + 1 == heroSelectCount.Count ? -(Game.CurrentGame.Settings.TimeOutSeconds - 2) : 0); for (int j = 0; j < numHeroes; j++) { var option = new AdditionalCardChoiceOptions(); option.IsTwoSidesCardChoice = true; if (!game.UiProxies[game.Players[turn]].AskForCardChoice(new CardChoicePrompt("Pk1v1.InitHeroPick", numHeroes), sourceDecks, resultDeckNames, resultDeckMaximums, newVer, out answer, option)) { answer = new List <List <Card> >(); answer.Add(new List <Card>()); answer[0].Add(game.Decks[null, tempHero].First(h => !answer[0].Contains(h) && !game.Decks[game.Players[turn], SelectedHero].Contains(h) && !game.Decks[game.Players[1 - turn], SelectedHero].Contains(h))); } game.Decks[game.Players[turn], SelectedHero].AddRange(answer[0]); game.NotificationProxy.NotifyTwoSidesCardPicked(turn == 0, game.Decks[deckPlace].IndexOf(answer[0][0])); } seq++; turn = 1 - turn; } GameDelays.Delay(GameDelays.Pk1v1EndOfSelection); game.NotificationProxy.NotifyTwoSidesCardPickEnd(); game.Shuffle(game.Decks[null, DeckType.Dealing]); Player current = game.CurrentPlayer = game.Players[1 - rulerId]; Dictionary <Player, List <Card> > restDraw = new Dictionary <Player, List <Card> >(); List <Player> players = new List <Player>(game.Players); foreach (Player p in players) { restDraw.Add(p, new List <Card>(game.Decks[p, SelectedHero])); } var heroSelection = new Dictionary <Player, List <Card> >(); int numberOfHeroes = Game.CurrentGame.Settings.DualHeroMode ? 2 : 1; game.GlobalProxy.AskForHeroChoice(restDraw, heroSelection, numberOfHeroes, new RequireCardsChoiceVerifier(numberOfHeroes, false, true)); bool notUsed = true; game.SyncConfirmationStatus(ref notUsed); foreach (var pxy in game.UiProxies) { pxy.Value.Freeze(); } for (int repeat = 0; repeat < numberOfHeroes; repeat++) { foreach (Player p in players) { Card c; int idx; //only server has the result if (!game.IsClient) { idx = repeat; if (heroSelection.ContainsKey(p)) { c = heroSelection[p][repeat]; idx = restDraw[p].IndexOf(c); } else { c = restDraw[p][idx]; } if (game.GameServer != null) { foreach (Player player in game.Players) { game.GameServer.SendPacket(player.Id, new StatusSync() { Status = idx }); } game.GameServer.SendPacket(game.Players.Count, new StatusSync() { Status = idx }); } } // you are client else { idx = (int)game.GameClient.Receive(); c = restDraw[p][idx]; } game.Decks[p, SelectedHero].Remove(c); var h = (HeroCardHandler)c.Type; Trace.TraceInformation("Assign {0} to player {1}", h.Hero.Name, p.Id); var hero = h.Hero.Clone() as Hero; foreach (var skill in new List <ISkill>(hero.Skills)) { if (skill.IsRulerOnly) { hero.Skills.Remove(skill); } } if (repeat == 0) { p.Hero = hero; p.Allegiance = hero.Allegiance; p.IsMale = hero.IsMale; p.IsFemale = !hero.IsMale; if (numberOfHeroes == 1) { p.MaxHealth = hero.MaxHealth; p.Health = hero.MaxHealth; } } else if (repeat == 1) { p.Hero2 = hero; int aveHp = (p.Hero2.MaxHealth + p.Hero.MaxHealth) / 2; p.MaxHealth = aveHp; p.Health = aveHp; } } } foreach (var rm in heroPool) { game.Decks[DeckType.Heroes].Remove(rm); } foreach (var st in game.Decks[game.Players[0], SelectedHero]) { st.Place = new DeckPlace(game.Players[0], SelectedHero); } foreach (var st in game.Decks[game.Players[1], SelectedHero]) { st.Place = new DeckPlace(game.Players[1], SelectedHero); } game.Shuffle(game.Decks[DeckType.Heroes]); if (game.IsClient) { foreach (var card in game.Decks[DeckType.Heroes]) { card.Type = new UnknownHeroCardHandler(); card.Id = Card.UnknownHeroId; } } GameDelays.Delay(GameDelays.GameBeforeStart); Game.CurrentGame.NotificationProxy.NotifyGameStart(); GameDelays.Delay(GameDelays.GameStart); GameDelays.Delay(GameDelays.GameStart); foreach (var pl in game.Players) { StartGameDeal(game, pl); } foreach (var pl in game.Players) { try { game.Emit(GameEvent.HeroDebut, new GameEventArgs() { Source = pl }); } catch (EndOfTurnException) { game.CurrentPlayer = game.Players[1 - game.CurrentPlayer.Id]; } } foreach (var act in game.AlivePlayers) { game.Emit(GameEvent.PlayerGameStartAction, new GameEventArgs() { Source = act }); } //redo this: current player might change current = game.CurrentPlayer; while (true) { GameEventArgs args = new GameEventArgs(); args.Source = current; game.CurrentPhaseEventIndex = 0; game.CurrentPhase = TurnPhase.BeforeStart; game.CurrentPlayer = current; game.Emit(GameEvent.DoPlayer, args); current = game.NextAlivePlayer(current); } }
/// <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); }