Ejemplo n.º 1
0
        public TaskState Process()
        {
            CurrentTask = TaskList.OrderBy(p => p.Source.OrderOfPlay).First();
            TaskList.Remove(CurrentTask);
            Game.Log(LogLevel.VERBOSE, BlockType.TRIGGER, "TaskQueue", $"LazyTask[{CurrentTask.Source}]: '{CurrentTask.GetType().Name}' is processed!" +
                     $"'{CurrentTask.Source.Card.Text?.Replace("\n", " ")}'");


            // power block
            if (Game.History)
            {
                Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.POWER, CurrentTask.Source.Id, "", -1, CurrentTask.Target?.Id ?? 0));
            }

            TaskState success = CurrentTask.Process();

            if (Game.History)
            {
                Game.PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
            }

            // reset between task execution
            Game.TaskStack.Reset();

            //if (Game.Splits.Count == 0 && CurrentTask.Splits != null && CurrentTask.Splits.Count > 0)
            //{
            //    Log.Info($"Parallel-threading splits '{CurrentTask.Splits.Count}' starting now! [Info: {Game.Splits.Count}]");
            //    Game.Splits = CurrentTask.Splits;
            //}
            return(success);
        }
Ejemplo n.º 2
0
        public override TaskState Process()
        {
            switch (Controller.Choice.ChoiceType)
            {
            case ChoiceType.MULLIGAN:
                Generic.ChoiceMulligan.Invoke(Controller, Choices);
                if (Controller.Game.History)
                {
                    Controller.Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, Controller.Id, "", 7, 0));
                }
                Controller.MulliganState = Enums.Mulligan.DONE;
                if (Controller.Game.History)
                {
                    Controller.Game.PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
                }
                return(TaskState.COMPLETE);

            case ChoiceType.GENERAL:
                if (!Generic.ChoicePick.Invoke(Controller, Choices[0]))
                {
                    return(TaskState.STOP);
                }
                Controller.NumOptionsPlayedThisTurn++;
                Game.ProcessTasks();
                Game.DeathProcessingAndAuraUpdate();
                return(TaskState.COMPLETE);

            case ChoiceType.INVALID:
                throw new NotImplementedException();
            }
            return(TaskState.STOP);
        }
Ejemplo n.º 3
0
        public override TaskState Process()
        {
            switch (Controller.Choice.ChoiceType)
            {
            case ChoiceType.MULLIGAN:
                Generic.ChoiceMulligan.Invoke(Controller, Choices);
                if (Controller.Game.History)
                {
                    Controller.Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, Controller.Id, "", 7, 0));
                }
                Controller.MulliganState = Enums.Mulligan.DONE;
                if (Controller.Game.History)
                {
                    Controller.Game.PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
                }
                return(TaskState.COMPLETE);

            case ChoiceType.GENERAL:
                Generic.ChoicePick.Invoke(Controller, Choices[0]);
                Controller.Game.NextStep = Step.MAIN_CLEANUP;
                return(TaskState.COMPLETE);

            case ChoiceType.INVALID:
                throw new NotImplementedException();
            }
            return(TaskState.STOP);
        }
Ejemplo n.º 4
0
        public TaskState Process()
        {
            ISimpleTask currentTask = CurrentQueue.Dequeue();

            CurrentTask = currentTask;

            //if (currentTask is StateTaskList tasks)
            //	tasks.Stack = new TaskStack(_game);

            _game.Log(LogLevel.VERBOSE, BlockType.TRIGGER, "TaskQueue", !_game.Logging ? "" : $"LazyTask[{currentTask.Source}]: '{currentTask.GetType().Name}' is processed!" +
                      $"'{currentTask.Source.Card.Text?.Replace("\n", " ")}'");
            if (_game.History)
            {
                _game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(currentTask.IsTrigger ? BlockType.TRIGGER : BlockType.POWER, currentTask.Source.Id, "", -1, currentTask.Target?.Id ?? 0));
            }

            TaskState success = currentTask.Process();

            if (_game.History)
            {
                _game.PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
            }

            // reset between task execution
            //_game.TaskStack.Reset();

            CurrentTask = null;

            return(success);
        }
Ejemplo n.º 5
0
        /// <summary>Initializes a new instance of the <see cref="Game"/> class.</summary>
        /// <param name="gameConfig">The game configuration.</param>
        /// <param name="setupHeroes"></param>
        public Game(GameConfig gameConfig, bool setupHeroes = true)
            : base(null, Card.CardGame, new Dictionary <GameTag, int>
        {
            [GameTag.ENTITY_ID] = GAME_ENTITYID,
            [GameTag.ZONE]      = (int)Enums.Zone.PLAY,
            [GameTag.CARDTYPE]  = (int)CardType.GAME
        })
        {
            _gameConfig       = gameConfig;
            Game              = this;
            GamesEventManager = new GameEventManager(this);

            _players[0] = new Controller(this, gameConfig.Player1Name, 1, 2);
            _players[1] = new Controller(this, gameConfig.Player2Name, 2, 3);

            // add power history create game
            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.CreateGame(this, _players));
            }

            if (setupHeroes)
            {
                _players[0].AddHeroAndPower(Cards.HeroCard(gameConfig.Player1HeroClass));
                _players[1].AddHeroAndPower(Cards.HeroCard(gameConfig.Player2HeroClass));
            }

            TaskQueue = new TaskQueue(this);
            TaskStack = new TaskStack(this);
        }
Ejemplo n.º 6
0
        private void DeApply(Minion m)
        {
            for (int i = 0; i < _effects.Length; i++)
            {
                _effects[i].RemoveAuraFrom(m);
            }

            if (EnchantmentCard != null && (_history || EnchantmentCard.Power.Trigger != null))
            {
                int cardId = EnchantmentCard.AssetId;
                List <Enchantment> enchantments = m.AppliedEnchantments;
                for (int i = enchantments.Count - 1; i >= 0; i--)
                {
                    if (enchantments[i].Creator == _owner && enchantments[i].Card.AssetId == cardId)
                    {
                        enchantments.RemoveAt(i);
                        break;
                    }
                }

                if (_history)
                {
                    for (int i = 0; i < _effects.Length; i++)
                    {
                        _owner.Game.PowerHistory.Add(
                            PowerHistoryBuilder.TagChange(_owner.Id, _effects[i].Tag, _owner[_effects[i].Tag]));
                    }
                }
            }
        }
Ejemplo n.º 7
0
        public void Execute(ISimpleTask task, Controller controller, IPlayable source, IPlayable target)
        {
            ISimpleTask clone = task.Clone();

            clone.Game       = controller.Game;
            clone.Controller = controller;
            clone.Source     = source;
            clone.Target     = target;
            Game.Log(LogLevel.VERBOSE, BlockType.TRIGGER, "TaskQueue", $"PriorityTask[{clone.Source}]: '{clone.GetType().Name}' is processed!" +
                     $"'{clone.Source.Card.Text?.Replace("\n", " ")}'");

            // power block
            if (controller.Game.History)
            {
                controller.Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.POWER, source.Id, "", -1, target?.Id ?? 0));
            }

            clone.Process();

            if (controller.Game.History)
            {
                controller.Game.PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
            }

            Game.TaskStack.Reset();
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Sets the native value without any trigger activated.
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="value"></param>
        public void SetNativeGameTag(GameTag tag, int value)
        {
            _data[tag] = value;

            if (Game.History && (int)tag < 1000)
            {
                Game.PowerHistory.Add(PowerHistoryBuilder.TagChange(Id, tag, value));
            }
        }
Ejemplo n.º 9
0
        public static IPlayable Draw(Controller c, int index)
        {
            IPlayable playable = c.DeckZone.Remove(index);

            c.Game.Log(LogLevel.INFO, BlockType.ACTION, "DrawPhase", !c.Game.Logging ? "" : $"{c.Name} draws {playable}");

            c.NumCardsDrawnThisTurn++;
            c.NumCardsDrawnThisGame++;
            c.LastCardDrawn = playable.Id;

            if (AddHandPhase.Invoke(c, playable))
            {
                // DrawTrigger vs TOPDECK ?? not sure which one is first

                Game game = c.Game;

                game.TaskQueue.StartEvent();
                game.TriggerManager.OnDrawTrigger(playable);
                game.ProcessTasks();
                game.TaskQueue.EndEvent();

                ISimpleTask task = playable.Power?.TopDeckTask;
                if (task != null)
                {
                    if (game.History)
                    {
                        // TODO: triggerkeyword: TOPDECK
                        game.PowerHistory.Add(
                            PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, playable.Id, "", 0, 0));
                    }

                    c.SetasideZone.Add(c.HandZone.Remove(playable));

                    game.Log(LogLevel.INFO, BlockType.TRIGGER, "TOPDECK",
                             !game.Logging ? "" : $"{playable}'s TOPDECK effect is activated.");

                    task.Process(game, c, playable, null);

                    if (game.History)
                    {
                        game.PowerHistory.Add(
                            PowerHistoryBuilder.BlockEnd());
                    }
                }
            }

            c.DeckZone.ResetPositions();

            return(playable);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING &amp;&amp; NEXTSTEP = MAIN_READY
        /// </summary>
        public void MainReady()
        {
            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, CurrentPlayer.Id, "", 1, 0));
            }

            Characters.ForEach(p =>
            {
                p.NumTurnsInPlay++;
                p.NumAttacksThisTurn = 0;
            });

            Heroes.ForEach(p =>
            {
                p.Controller.NumCardsDrawnThisTurn              = 0;
                p.Controller.NumCardsPlayedThisTurn             = 0;
                p.Controller.NumMinionsPlayedThisTurn           = 0;
                p.Controller.NumOptionsPlayedThisTurn           = 0;
                p.Controller.NumFriendlyMinionsThatDiedThisTurn = 0;
            });

            CurrentPlayer.Hero.IsExhausted       = false;
            CurrentPlayer.Hero.Power.IsExhausted = false;
            foreach (var e in CurrentPlayer.BoardZone)
            {
                e.IsSummoned  = false;
                e.IsExhausted = false;
            }

            // De-activate combo buff
            CurrentPlayer.IsComboActive = false;

            CurrentPlayer.NumMinionsPlayerKilledThisTurn         = 0;
            CurrentOpponent.NumMinionsPlayerKilledThisTurn       = 0;
            CurrentPlayer.NumFriendlyMinionsThatAttackedThisTurn = 0;
            NumMinionsKilledThisTurn = 0;
            CurrentPlayer.HeroPowerActivationsThisTurn = 0;

            CurrentPlayer.NumElementalsPlayedLastTurn = CurrentPlayer.NumElementalsPlayedThisTurn;
            CurrentPlayer.NumElementalsPlayedThisTurn = 0;

            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
            }

            // set next step
            NextStep = Step.MAIN_START_TRIGGERS;
        }
Ejemplo n.º 11
0
 public void AddWeapon(Weapon weapon)
 {
     RemoveWeapon();
     weapon.SetOrderOfPlay("WEAPON");
     Weapon = weapon;
     Weapon[GameTag.ZONE]          = (int)Enums.Zone.PLAY;
     Weapon[GameTag.ZONE_POSITION] = 0;
     if (Game.History)
     {
         Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.POWER, Weapon.Id, "", -1, 0));
         Game.PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
     }
     EquippedWeapon = weapon.Id;
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING &amp;&amp; NEXTSTEP = MAIN_DRAW
        /// </summary>
        public void MainDraw()
        {
            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, CurrentPlayer.Id, "", 0, 0));                 // turn start effect
            }
            //CurrentPlayer.NumCardsToDraw = 1;
            Generic.Draw(CurrentPlayer);

            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
            }

            // set next step
            NextStep = Step.MAIN_START;
        }
Ejemplo n.º 13
0
        private void Apply(Minion m)
        {
            for (int i = 0; i < _effects.Length; i++)
            {
                _effects[i].ApplyAuraTo(m);
            }

            if (EnchantmentCard != null && _history)
            {
                Enchantment.GetInstance(m.Controller, _owner, m, in EnchantmentCard);
                for (int i = 0; i < _effects.Length; i++)
                {
                    _owner.Game.PowerHistory.Add(
                        PowerHistoryBuilder.TagChange(_owner.Id, _effects[i].Tag, _owner[_effects[i].Tag]));
                }
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING &amp;&amp; NEXTSTEP = MAIN_START_TRIGGERS
        /// </summary>
        public void MainStartTriggers()
        {
            CurrentPlayer.TurnStart = true;
            DeathProcessingAndAuraUpdate();

            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, CurrentPlayer.Id, "", 8, 0));
            }

            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
            }

            // set next step
            NextStep = Step.MAIN_RESOURCE;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING &amp;&amp; NEXTSTEP = BEGIN_DRAW
        /// </summary>
        public void BeginDraw()
        {
            Log(LogLevel.VERBOSE, BlockType.PLAY, "Game", $"Begin Draw.");

            //FirstPlayer.NumCardsToDraw = 3;
            //FirstPlayer.Opponent.NumCardsToDraw = 4;

            _players.ToList().ForEach(p =>
            {
                // quest draw if there is
                var quest = p.DeckZone.GetAll.Where(q => q is Spell && ((Spell)q).IsQuest).FirstOrDefault();
                Generic.Draw(p, quest != null ? quest : null);
                Generic.Draw(p);
                Generic.Draw(p);

                if (p != FirstPlayer)
                {
                    // 4th card for second player
                    Generic.Draw(p);

                    var coin = FromCard(FirstPlayer.Opponent, Cards.FromId("GAME_005"), new Dictionary <GameTag, int>()
                    {
                        [GameTag.ZONE]     = (int)Enums.Zone.HAND,
                        [GameTag.CARDTYPE] = (int)CardType.SPELL,
                        [GameTag.CREATOR]  = FirstPlayer.Opponent.PlayerId
                    });
                    Generic.AddHandPhase(FirstPlayer.Opponent, coin);
                }

                p.NumTurnsLeft = 1;
            });

            Player1.TimeOut = 75;
            Player2.TimeOut = 75;

            // ending mulligan draw block
            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
            }

            NextStep = _gameConfig.SkipMulligan ? Step.MAIN_BEGIN : Step.BEGIN_MULLIGAN;
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING &amp;&amp; NEXTSTEP = MAIN_NEXT
        /// </summary>
        public void MainNext()
        {
            if (History)
            {
                PowerHistoryBuilder.BlockStart(Enums.BlockType.TRIGGER, this.Id, "", -1, 0);
            }

            CurrentPlayer.NumTurnsLeft   = 0;
            CurrentOpponent.NumTurnsLeft = 1;

            // After a player ends their turn (just before the next player's Start of
            // Turn Phase), un-Freeze all characters they control that are Frozen,
            // don't have summoning sickness (or do have Charge) and have not attacked
            // that turn.
            CurrentPlayer.BoardZone.GetAll.ForEach(p =>
            {
                var minion = p as Minion;
                if (minion != null && minion.IsFrozen && minion.NumAttacksThisTurn == 0 && (!minion.IsSummoned || minion.HasCharge))
                {
                    minion.IsFrozen = false;
                }
            });
            if (CurrentPlayer.Hero.IsFrozen && CurrentPlayer.Hero.NumAttacksThisTurn == 0)
            {
                CurrentPlayer.Hero.IsFrozen = false;
            }

            // set player for next turn ...
            CurrentPlayer = CurrentOpponent;

            // count next turn
            Turn++;

            Log(LogLevel.INFO, BlockType.PLAY, "Game", $"CurentPlayer {CurrentPlayer.Name}.");

            if (History)
            {
                PowerHistoryBuilder.BlockEnd();
            }

            // set next step
            NextStep = Step.MAIN_READY;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING &amp;&amp; NEXTSTEP = MAIN_CLEANUP
        /// </summary>
        public void MainCleanUp()
        {
            if (History)
            {
                PowerHistoryBuilder.BlockStart(Enums.BlockType.TRIGGER, CurrentPlayer.Id, "", 5, 0);
            }

            DeathProcessingAndAuraUpdate();

            if (History)
            {
                PowerHistoryBuilder.BlockEnd();
            }

            // move forward if game isn't won by any player now!
            NextStep = _players.ToList().TrueForAll(p => p.PlayState == PlayState.PLAYING)
                                ? Step.MAIN_ACTION
                                : Step.FINAL_WRAPUP;
        }
Ejemplo n.º 18
0
        public override bool Process()
        {
            Choice choice = Controller.Choice;

            if (choice == null)
            {
                return(false);
            }

            switch (choice.ChoiceType)
            {
            case ChoiceType.MULLIGAN:
                Generic.ChoiceMulligan.Invoke(Controller, Choices);
                if (Controller.Game.History)
                {
                    Controller.Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, Controller.Id, "", 7, 0));
                }
                Controller.MulliganState = Enums.Mulligan.DONE;
                if (Controller.Game.History)
                {
                    Controller.Game.PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
                }
                return(true);

            case ChoiceType.GENERAL:
                //Game.CurrentEventData =
                //	new EventMetaData(Game.IdEntityDic[choice.SourceId], Game.IdEntityDic[Choices[0]]);
                if (!Generic.ChoicePick.Invoke(Controller, Game, Choices[0]))
                {
                    return(false);
                }
                Controller.NumOptionsPlayedThisTurn++;
                Game.ProcessTasks();
                Game.DeathProcessingAndAuraUpdate();
                //Game.CurrentEventData = null;
                return(true);

            case ChoiceType.INVALID:
                throw new NotImplementedException();
            }
            return(false);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING &amp;&amp; NEXTSTEP = MAIN_END
        /// </summary>
        public void MainEnd()
        {
            Log(LogLevel.INFO, BlockType.PLAY, "Game", $"End turn proccessed by player {CurrentPlayer}");

            if (History)
            {
                PowerHistoryBuilder.BlockStart(Enums.BlockType.TRIGGER, CurrentPlayer.Id, "", 4, 0);
            }

            CurrentPlayer.TurnStart = false;
            DeathProcessingAndAuraUpdate();

            if (History)
            {
                PowerHistoryBuilder.BlockEnd();
            }

            // set next step
            NextStep = Step.MAIN_NEXT;
        }
Ejemplo n.º 20
0
        public override TaskState Process()
        {
            if (Game.History)
            {
                Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.JOUST, Source.Id, "", 0, 0));
            }
            IPlayable playable = Generic.JoustBlock.Invoke(Controller, _type);

            if (Game.History)
            {
                Game.PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
            }
            if (playable != null)
            {
                // add joust card winner to stack
                Playables = new List <IPlayable> {
                    playable
                };

                SuccessJoustTask.Game       = Game;
                SuccessJoustTask.Controller = Controller;
                SuccessJoustTask.Source     = Source;
                SuccessJoustTask.Target     = Target;

                return(SuccessJoustTask.Process());
            }

            if (FailedJoustTask != null)
            {
                FailedJoustTask.Game       = Game;
                FailedJoustTask.Controller = Controller;
                FailedJoustTask.Source     = Source;
                FailedJoustTask.Target     = Target;

                return(FailedJoustTask.Process());
            }

            Game.OnRandomHappened(true);

            return(TaskState.COMPLETE);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Apply this Enchant's <see cref="Effect"/>s to the given entity.
        /// </summary>
        /// <param name="entity">The target entity.</param>
        /// <param name="num1">Integer value for GameTag.TAG_SCRIPT_DATA_NUM_1.</param>
        /// <param name="num2">Integer value for GameTag.TAG_SCRIPT_DATA_NUM_2.</param>
        public virtual void ActivateTo(IEntity entity, int num1 = -1, int num2 = -1)
        {
            IEffect[] effects = Effects;
            if (!UseScriptTag)
            {
                for (int i = 0; i < effects.Length; i++)
                {
                    effects[i].ApplyTo(entity, IsOneTurnEffect);
                }
            }
            else
            {
                effects[0].ChangeValue(num1).ApplyTo(entity, IsOneTurnEffect);

                if (effects.Length >= 2)
                {
                    if (num2 >= 0)
                    {
                        effects[1].ChangeValue(num2).ApplyTo(entity, IsOneTurnEffect);
                    }
                    else
                    {
                        effects[1].ChangeValue(num1).ApplyTo(entity, IsOneTurnEffect);
                    }

                    for (int i = 2; i < effects.Length; i++)
                    {
                        effects[i].ApplyTo(entity, IsOneTurnEffect);
                    }
                }
            }

            if (entity.Game.History)
            {
                for (int i = 0; i < effects.Length; i++)
                {
                    entity.Game.PowerHistory.Add(
                        PowerHistoryBuilder.TagChange(entity.Id, effects[i].Tag, entity[effects[i].Tag]));
                }
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING &amp;&amp; NEXTSTEP = BEGIN_MULLIGAN
        /// </summary>
        public void BeginMulligan()
        {
            Log(LogLevel.VERBOSE, BlockType.PLAY, "Game", $"Begin Mulligan.");

            // starting mulligan draw block
            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, this.Id, "", -1, 0));
            }

            Player1.MulliganState = Mulligan.INPUT;
            Player2.MulliganState = Mulligan.INPUT;

            Generic.CreateChoice.Invoke(Player1, this, ChoiceType.MULLIGAN, ChoiceAction.HAND, Player1.HandZone.Select(p => p.Id).ToList());
            Generic.CreateChoice.Invoke(Player2, this, ChoiceType.MULLIGAN, ChoiceAction.HAND, Player2.HandZone.Select(p => p.Id).ToList());

            // ending mulligan draw block
            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockEnd());
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Move destroyed entities from <see cref="Zone.PLAY"/> <see cref="Zone{T}"/> into
        /// <see cref="Zone.GRAVEYARD"/>
        /// </summary>
        public void GraveYard()
        {
            // remove dead weapons
            var heroesBadWeapons =
                Heroes.Where(p => p.Weapon != null && (p.Weapon.Durability == 0 || p.Weapon.ToBeDestroyed)).ToList();

            heroesBadWeapons.ForEach(p => p.RemoveWeapon());

            // check for dead minions to carry to the graveyard
            Minions.Where(p => p.IsDead).ToList().ForEach(p =>
            {
                Log(LogLevel.INFO, BlockType.PLAY, "Game", $"{p} is Dead! Graveyard say 'Hello'!");
                p.Zone.Remove(p);
                if (p.HasDeathrattle)
                {
                    p.ApplyEnchantments(EnchantmentActivation.DEATHRATTLE, Enums.Zone.GRAVEYARD);
                }
                if (History)
                {
                    PowerHistoryBuilder.BlockStart(BlockType.DEATHS, 1, "", 0, 0);
                }
                p.IsExhausted = false;
                p.Controller.GraveyardZone.Add(p);
                p.Controller.NumFriendlyMinionsThatDiedThisTurn++;
                CurrentPlayer.NumMinionsPlayerKilledThisTurn++;
                NumMinionsKilledThisTurn++;
                p.Damage = 0;
                if (History)
                {
                    PowerHistoryBuilder.BlockEnd();
                }
            });

            // check for dead heroes
            var deadHeroes = Heroes.Where(p => p.IsDead).ToList();

            deadHeroes.ForEach(p => p.Controller.PlayState = deadHeroes.Count > 1 ? PlayState.TIED : PlayState.LOSING);
        }
Ejemplo n.º 24
0
        public override int this[GameTag t]
        {
            get
            {
                _data.TryGetValue(t, out int value);
                return(value + ControllerAuraEffects[t]);
            }
            set
            {
                //20200405 Connor - Turning off the logging for now
                //if (_logging)
                //	Game.Log(LogLevel.DEBUG, BlockType.TRIGGER, "Entity", !Game.Logging ? "" : $"{this} set data {t} to {value}");
                if (_history && (int)t < 1000)
                {
                    if (value + ControllerAuraEffects[t] != this[t])
                    {
                        Game.PowerHistory.Add(PowerHistoryBuilder.TagChange(Id, t, value));
                    }
                }

                _data[t] = value;
            }
        }
Ejemplo n.º 25
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING.
        /// </summary>
        public void StartGame()
        {
            Log(LogLevel.INFO, BlockType.PLAY, "Game", "Starting new game now!");

            // setting up the decks ...
            _gameConfig.Player1Deck?.ForEach(p => Entity.FromCard(Player1, p, null, Player1.DeckZone));
            _gameConfig.Player2Deck?.ForEach(p => Entity.FromCard(Player2, p, null, Player2.DeckZone));
            if (_gameConfig.FillDecks)
            {
                Player1.DeckZone.Fill();
                Player2.DeckZone.Fill();
            }

            // set gamestats
            State = State.RUNNING;
            _players.ToList().ForEach(p => p.PlayState = PlayState.PLAYING);

            // starting mulligan draw block
            if (History)
            {
                PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, this.Id, "", -1, 0));
            }

            // getting first player
            FirstPlayer = _gameConfig.StartPlayer < 0
                                ? _players[Util.Random.Next(0, 2)]
                                : _players[_gameConfig.StartPlayer - 1];
            CurrentPlayer = FirstPlayer;

            Log(LogLevel.INFO, BlockType.PLAY, "Game", $"Starting Player is {CurrentPlayer.Name}.");

            // first turn
            Turn = 1;

            // set next step
            NextStep = Step.BEGIN_FIRST;
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Part of the state machine.
        /// Runs when STATE = RUNNING &amp;&amp; NEXTSTEP = FINAL_WRAPUP
        /// </summary>
        public void FinalWrapUp()
        {
            if (History)
            {
                PowerHistoryBuilder.BlockStart(Enums.BlockType.TRIGGER, Id, "", -1, 0);
            }

            Heroes.ForEach(p =>
            {
                if (p.Controller.PlayState == PlayState.LOSING || p.Controller.PlayState == PlayState.CONCEDED)
                {
                    p.Controller.PlayState          = PlayState.LOST;
                    p.Controller.Opponent.PlayState = PlayState.WON;
                }
            });

            if (History)
            {
                PowerHistoryBuilder.BlockEnd();
            }

            // set next step
            NextStep = Step.FINAL_GAMEOVER;
        }
Ejemplo n.º 27
0
        public void Update()
        {
            if (_triggerType != TriggerType.NONE)
            {
                if (_initialisationFunction != null)
                {
                    _owner._costManager.UpdateAdaptiveEffect(_cachedValue);
                }
                else
                {
                    if (!_isTriggered)
                    {
                        return;
                    }

                    if (_isAppliedThisTurn)
                    {
                        return;
                    }

                    _owner._costManager.UpdateAdaptiveEffect(_value);

                    _isAppliedThisTurn = true;
                }
            }
            else
            {
                _owner._costManager.UpdateAdaptiveEffect();
            }

            if (_owner.Game.History)
            {
                _owner.Game.PowerHistory.Add(PowerHistoryBuilder
                                             .TagChange(_owner.Id, GameTag.COST, _owner.Cost));
            }
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Inflict damage onto this character.
        /// The actual amount still needs to be determined by the current
        /// state of the game. eg: The presence of immunity effects can cause
        /// the damage to be ignored.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="damage"></param>
        /// <returns></returns>
        public int TakeDamage(IPlayable source, int damage)
        {
            var hero   = this as Hero;
            var minion = this as Minion;

            if (minion != null && minion.Zone.Type != Enums.Zone.PLAY)
            {
                return(0);
            }

            bool fatigue = hero != null && this == source;

            if (fatigue)
            {
                hero.Fatigue = damage;
            }

            if (minion != null && minion.HasDivineShield)
            {
                Game.Log(LogLevel.INFO, BlockType.ACTION, "Character", !Game.Logging? "":$"{this} divine shield absorbed incoming damage.");
                minion.HasDivineShield = false;
                return(0);
            }

            int armor = hero?.Armor ?? 0;

            int amount = hero == null ? damage : armor < damage ? damage - armor : 0;

            // added pre damage
            PreDamage = amount;

            // Predamage triggers (Ice Block)
            if (PreDamageTrigger != null)
            {
                PreDamageTrigger.Invoke(this);
                amount = PreDamage;
            }
            if (IsImmune)
            {
                Game.Log(LogLevel.INFO, BlockType.ACTION, "Character", !Game.Logging ? "" : $"{this} is immune.");
                PreDamage = 0;
                return(0);
            }

            // remove armor first from hero ....
            if (armor > 0)
            {
                hero.Armor = armor < damage ? 0 : armor - damage;
            }

            // final damage is beeing accumulated
            Damage += amount;

            Game.Log(LogLevel.INFO, BlockType.ACTION, "Character", !Game.Logging? "":$"{this} took damage for {PreDamage}({damage}). {(fatigue ? "(fatigue)" : "")}");

            // reset predamage
            PreDamage = 0;

            //LastAffectedBy = source.Id;	TODO


            // Damage event is created
            // Collect all the tasks and sort them by order of play
            // Death phase and aura update are not emerge here

            // place event related data
            Game.TaskQueue.StartEvent();
            EventMetaData temp = Game.CurrentEventData;

            Game.CurrentEventData = new EventMetaData(source, this, amount);

            // on-damage triggers
            TakeDamageTrigger?.Invoke(this);
            Game.TriggerManager.OnDamageTrigger(this);
            Game.TriggerManager.OnDealDamageTrigger(source);
            Game.ProcessTasks();
            Game.TaskQueue.EndEvent();
            Game.CurrentEventData = temp;

            if (source.HasLifeSteal && !_lifestealChecker)
            {
                if (_history)
                {
                    Game.PowerHistory.Add(PowerHistoryBuilder.BlockStart(BlockType.TRIGGER, source.Id, source.Card.Id, -1, 0));                     // TriggerKeyword=LIFESTEAL
                }
                Game.Log(LogLevel.VERBOSE, BlockType.ATTACK, "TakeDamage", !_logging ? "" : $"lifesteal source {source} has damaged target for {amount}.");
                source.Controller.Hero.TakeHeal(source, amount);
                if (_history)
                {
                    Game.PowerHistory.Add(new PowerHistoryBlockEnd());
                }

                if (source.Controller.Hero.ToBeDestroyed && source.Controller.Hero.Health > 0)
                {
                    source.Controller.Hero.ToBeDestroyed = false;
                }
            }

            if (this is Hero h)
            {
                h.IsDamagedThisTurn = true;
            }

            return(amount);
        }
Ejemplo n.º 29
0
        /// <summary>Builds a new subclass of entity that can be added to a SabberStone game instance.</summary>
        /// <param name="controller">The controller of the entity.</param>
        /// <param name="card">The card from which the entity must be derived.</param>
        /// <param name="tags">The tags preset for the entity.</param>
        /// <param name="zone">The zone in which the entity must spawn.</param>
        /// <param name="id">The EntityID to assign to the newly created entity.</param>
        /// <returns></returns>
        /// <exception cref="EntityException"></exception>
        public static IPlayable FromCard(Controller controller, Card card, Dictionary <GameTag, int> tags = null, IZone zone = null, int id = -1)
        {
            tags = tags ?? new Dictionary <GameTag, int>();
            tags[GameTag.ENTITY_ID]  = id > 0 ? id : controller.Game.NextId;
            tags[GameTag.CONTROLLER] = controller.PlayerId;
            tags[GameTag.ZONE]       = zone != null ? (int)zone.Type : 0;
            //tags[GameTag.CARD_ID] = card.AssetId;

            IPlayable result = null;

            switch (card.Type)
            {
            case CardType.MINION:
                result = new Minion(controller, card, tags);
                break;

            case CardType.SPELL:
                result = new Spell(controller, card, tags);
                break;

            case CardType.WEAPON:
                result = new Weapon(controller, card, tags);
                break;

            case CardType.HERO:

                // removing this because it's always the cards health or it is given by previous heros like for deathknight
                //tags[GameTag.HEALTH] = card[GameTag.HEALTH];

                tags[GameTag.ZONE] = (int)Enums.Zone.PLAY;
                //tags[GameTag.FACTION] = card[GameTag.FACTION];
                tags[GameTag.CARDTYPE] = card[GameTag.CARDTYPE];
                //tags[GameTag.RARITY] = card[GameTag.RARITY];
                //tags[GameTag.HERO_POWER] = card[GameTag.HERO_POWER];

                result = new Hero(controller, card, tags);
                break;

            case CardType.HERO_POWER:
                tags[GameTag.COST] = card[GameTag.COST];
                tags[GameTag.ZONE] = (int)Enums.Zone.PLAY;
                //tags[GameTag.FACTION] = card[GameTag.FACTION];
                tags[GameTag.CARDTYPE] = card[GameTag.CARDTYPE];
                //tags[GameTag.RARITY] = card[GameTag.RARITY];
                //tags[GameTag.TAG_LAST_KNOWN_COST_IN_HAND] = card[GameTag.COST];
                result = new HeroPower(controller, card, tags);
                break;

            default:
                throw new EntityException($"Couldn't create entity, because of an unknown cardType {card.Type}.");
            }

            // add entity to the game dic
            controller.Game.IdEntityDic.Add(result.Id, result);

            // add power history full entity
            if (controller.Game.History)
            {
                controller.Game.PowerHistory.Add(PowerHistoryBuilder.FullEntity(result));
            }

            // add entity to the appropriate zone if it was given
            zone?.Add(result);

            if (result.ChooseOne)
            {
                result.ChooseOnePlayables[0] =
                    id < 0 ? FromCard(controller,
                                      Cards.FromId(result.Card.Id + "a"),
                                      new Dictionary <GameTag, int>
                {
                    [GameTag.CREATOR]     = result.Id,
                    [GameTag.PARENT_CARD] = result.Id
                },
                                      controller.SetasideZone) :
                    controller.SetasideZone.GetAll.Find(p => p[GameTag.CREATOR] == result.Id && p.Card.Id == result.Card.Id + "a");

                result.ChooseOnePlayables[1] =
                    id < 0 ? FromCard(controller,
                                      Cards.FromId(result.Card.Id + "b"),
                                      new Dictionary <GameTag, int>
                {
                    [GameTag.CREATOR]     = result.Id,
                    [GameTag.PARENT_CARD] = result.Id
                },
                                      controller.SetasideZone) :
                    controller.SetasideZone.GetAll.Find(p => p[GameTag.CREATOR] == result.Id && p.Card.Id == result.Card.Id + "b");
            }

            return(result);
        }
Ejemplo n.º 30
0
        /// <summary>Process the specified task.
        /// The game will execute the desired task and all effects coupled either
        /// directly or indirectly in synchronous manner.
        ///
        /// Call <see cref="Controller.Options(bool)"/> on the <see cref="CurrentPlayer"/>
        /// instance for tasks which are accepted as arguments.
        /// After this method returns, check <see cref="Controller.Options(bool)"/>
        /// again until only <see cref="EndTurnTask"/> remains, which will
        /// start the turn of <see cref="CurrentOpponent"/>.
        /// </summary>
        /// <param name="gameTask">The game task to execute.</param>
        public void Process(PlayerTask gameTask)
        {
            // start with no splits ...
            Splits = new List <Game>();

            Log(LogLevel.INFO, BlockType.PLAY, "Game", gameTask.FullPrint());

            // clear last power history
            PowerHistory.Last.Clear();

            // make sure that we only use task for this game ...
            gameTask.Game = this;
            gameTask.Process();

            // add enchantment and buff tag changes
            if (History)
            {
                Enchants.ForEach(p =>
                                 p.Effects.Keys.ToList().ForEach(t =>
                                                                 IdEntityDic.Values.ToList().ForEach(o =>
                                                                                                     PowerHistory.Add(PowerHistoryBuilder.TagChange(o.Id, t, o[t])))));

                foreach (var controller in _players)
                {
                    controller.Hero.Enchants.ForEach(p =>
                                                     p.Effects.Keys.ToList().ForEach(t =>
                                                                                     PowerHistory.Add(PowerHistoryBuilder.TagChange(Game.CurrentPlayer.Hero.Id, t, Game.CurrentPlayer.Hero[t]))));

                    //CurrentPlayer.Hero.Weapon?.Enchants.ForEach(p => p.IsEnabled());
                    //CurrentPlayer.Hero.Weapon?.Triggers.ForEach(p => p.IsEnabled());
                    //CurrentOpponent.Hero.Weapon?.Enchants.ForEach(p => p.IsEnabled());
                    //CurrentOpponent.Hero.Weapon?.Triggers.ForEach(p => p.IsEnabled());

                    controller.ControlledZones.Where(z => z != null).ToList().ForEach(z =>
                                                                                      z.Enchants.ForEach(p =>
                                                                                                         p.Effects.Keys.ToList().ForEach(t =>
                                                                                                                                         z.GetAll.ForEach(o =>
                                                                                                                                                          PowerHistory.Add(PowerHistoryBuilder.TagChange(o.Id, t, o[t]))))));
                }

                Characters.ForEach(c =>
                                   c.Enchants.ForEach(p =>
                                                      p.Effects.Keys.ToList().ForEach(t =>
                                                                                      PowerHistory.Add(PowerHistoryBuilder.TagChange(c.Id, t, c[t])))));
            }

            if (Splitting)
            {
                var finalSplits = SplitNode.GetSolutions(this, 10, 10000);
                Dump("Split", $"found {finalSplits.Count} final splits of {finalSplits.Sum(p => p.SameState + 1)}!");
                finalSplits.GroupBy(p => p.SameState)
                .Select(i => new { Word = i.Key, Count = i.Count() })
                .ToList().ForEach(p => Dump("Split", $" {p.Count},  with {p.Word} same states"));
                FinalSplits = finalSplits;
            }
        }