private List <StepNode> CreateStepNodes() { StepNode gameStart = null, mulligan = null, untap = null, upkeep = null, draw = null, firstMain = null, beginOfCombat = null, declareAttackers = null, declareBlockers = null, firstStrikeCombatDamage = null, combatDamage = null, endofCombat = null, secondMain = null, endOfTurn = null, cleanup = null; gameStart = NewStep(Step.GameStart, new Action[] { SelectStartingPlayer, ShuffleLibraries, DrawStartingHands, }, next: () => mulligan, getsPriority: false); mulligan = NewStep(Step.Mulligan, new Action[] { TakeMulligans }, next: () => Players.AnotherMulliganRound ? mulligan : untap, getsPriority: false); untap = NewStep(Step.Untap, new Action[] { () => Turn.NextTurn(), () => { foreach (var permanent in Players.Active.Battlefield) { permanent.HasSummoningSickness = false; if (permanent.Has().DoesNotUntap) { continue; } if (permanent.MayChooseNotToUntap) { Enqueue(new ChooseToUntap( Players.Active, permanent)); } else { permanent.Untap(); } } Players.Active.LandsPlayedCount = 0; } }, next: () => upkeep, getsPriority: false); upkeep = NewStep(Step.Upkeep, next: () => draw, getsPriority: true); draw = NewStep(Step.Draw, new Action[] { () => { if (Turn.TurnCount != 1) { Players.Active.DrawCard(); } } }, next: () => firstMain, getsPriority: true); firstMain = NewStep(Step.FirstMain, next: () => beginOfCombat, getsPriority: true); beginOfCombat = NewStep(Step.BeginningOfCombat, next: () => declareAttackers, getsPriority: true); declareAttackers = NewStep(Step.DeclareAttackers, new Action[] { DeclareAttackers }, next: () => declareBlockers, getsPriority: true); declareBlockers = NewStep(Step.DeclareBlockers, new Action[] { DeclareBlockers, SetDamageAssignmentOrder, }, next: () => Combat.AnyCreaturesWithFirstStrike() ? firstStrikeCombatDamage : combatDamage, getsPriority: true); firstStrikeCombatDamage = NewStep(Step.FirstStrikeCombatDamage, new Action[] { () => Combat.AssignCombatDamage(firstStrike: true), DealAssignedCombatDamage, () => Players.MoveDeadCreaturesToGraveyard() }, next: () => Combat.AnyCreaturesWithNormalStrike() ? combatDamage : endofCombat, getsPriority: true); combatDamage = NewStep(Step.CombatDamage, new Action[] { () => Combat.AssignCombatDamage(), DealAssignedCombatDamage, () => Players.MoveDeadCreaturesToGraveyard() }, next: () => endofCombat, getsPriority: true); endofCombat = NewStep(Step.EndOfCombat, new Action[] { () => Combat.RemoveAll() }, next: () => secondMain, getsPriority: true); secondMain = NewStep(Step.SecondMain, next: () => endOfTurn, getsPriority: true); endOfTurn = NewStep(Step.EndOfTurn, next: () => cleanup, getsPriority: true); cleanup = NewStep(Step.CleanUp, new Action[] { () => { Players.RemoveDamageFromPermanents(); Players.RemoveRegenerationFromPermanents(); DiscardToMaximumHandSize(); Publish(new EndOfTurnEvent()); }, () => Players.ChangeActivePlayer(), }, next: () => untap, getsPriority: false); var all = new List <StepNode> { gameStart, mulligan, untap, upkeep, draw, firstMain, beginOfCombat, declareAttackers, declareBlockers, firstStrikeCombatDamage, combatDamage, endofCombat, secondMain, endOfTurn, cleanup }; return(all); }
private void SetDamageAssignmentOrder() { Combat.SetDamageAssignmentOrder(); }
public Game(GameParameters p) { ChangeTracker = new ChangeTracker(); Stack = new Stack(); Turn = new TurnInfo(); Ai = new SearchRunner(p.SearchParameters, this); Combat = new Combat(); Settings = p.Settings; _decisionQueue = new DecisionQueue(); _publisher = new Publisher(changeTracker: ChangeTracker); _wasStopped = new Trackable <bool>(); _stateMachine = new StateMachine(); var player1 = new Player(p.Player1, p.Player1Controller); var player2 = new Player(p.Player2, p.Player2Controller); Players = new Players(player1, player2); _damagePreventions = new DamagePreventions(); _damageRedirections = new DamageRedirections(); _namedGameModifiers = new NamedGameModifiers(); _costModifiers = new CostModifiers(); _scenario = new Scenario(this); if (p.IsSavedGame) { Random = new RandomGenerator(p.SavedGame.RandomSeed); Recorder = new GameRecorder(this, p.SavedGame.Decisions); } else { Random = new RandomGenerator(); Recorder = new GameRecorder(this); } Initialize(); if (p.IsSavedGame) { p.SavedGame.Decisions.Position = 0; Player looser = null; if (p.Looser != null) { looser = p.Looser == 0 ? player1 : player2; } _stateMachine.Start(() => { if (p.RollBack > 0) { return((Turn.StateCount < p.SavedGame.StateCount - p.RollBack) || (_stateMachine.HasPendingDecisions)); } return(Turn.StateCount < p.SavedGame.StateCount || Recorder.IsPlayback); }, skipPreGame: false, looser: looser); Recorder.DiscardUnloadedResults(); _wasLoaded = true; } }