public void SelectAbility(int index)
        {
            var currentMob = _game.CurrentMob;

            if (currentMob == null)
            {
                return;
            }

            var mobInfo = _game.MobManager.MobInfos[currentMob.Value];

            if (index >= mobInfo.Abilities.Count)
            {
                Utils.Log(LogSeverity.Info, nameof(GameBoardController),
                          "Trying to select an ability index higher than the number of abilities.");
                return;
            }
            var ability = mobInfo.Abilities[index];

            if (SelectedAbilityIndex.HasValue)
            {
                if (SelectedAbilityIndex.Value == index)
                {
                    SelectedAbilityIndex = null;
                }
                else if (GameInvariants.IsAbilityUsableNoTarget(_game, currentMob.Value, ability))
                {
                    SelectedAbilityIndex = index;
                }
            }
            else if (GameInvariants.IsAbilityUsableNoTarget(_game, currentMob.Value, ability))
            {
                SelectedAbilityIndex = index;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Generates possible direct ability use actions.
        /// </summary>
        public static bool GenerateDirectAbilityUse(GameInstance state,
                                                    CachedMob mob,
                                                    List <UctAction> result)
        {
            bool foundAbilityUse = false;
            var  mobInfo         = mob.MobInfo;
            var  mobId           = mob.MobId;

            foreach (var abilityId in mobInfo.Abilities)
            {
                if (!GameInvariants.IsAbilityUsableNoTarget(state, mobId, abilityId))
                {
                    continue;
                }

                foreach (var targetId in state.MobManager.Mobs)
                {
                    if (GameInvariants.IsAbilityUsable(state, mob, state.CachedMob(targetId), abilityId))
                    {
                        foundAbilityUse = true;

                        var action = UctAction.AbilityUseAction(abilityId, mobId, targetId);
                        GameInvariants.AssertValidAction(state, action);

                        result.Add(action);
                    }
                }
            }

            return(foundAbilityUse);
        }
Beispiel #3
0
        public void Render(Entity entity, SpriteBatch batch, AssetManager assetManager)
        {
            var effect = assetManager.LoadEffect(AssetManager.ShaderAbility);

            batch.Begin(effect: effect, samplerState: Camera2D.SamplerState);

            var mob = _mobFunc();

            if (mob != null)
            {
                var abilityId = mob.MobInfo.Abilities[_abilityIndex];

                var isActive = _gameBoardController.SelectedAbilityIndex == _abilityIndex;

                if (GameInvariants.IsAbilityUsableNoTarget(_game, mob.MobId, abilityId))
                {
                    isActive = true;
                }

                var ability = _game.MobManager.Abilities[abilityId];
                batch.Draw(assetManager[AssetManager.SpellBg], entity.RenderPosition);

                if (entity.AABB.Contains(InputManager.Instance.MousePosition))
                {
                    batch.Draw(assetManager[AssetManager.SpellHighlight], entity.RenderPosition);
                }
            }
            else
            {
                Debug.WriteLine("ERROR - Rendering abilities, but no mob is currently active.");
                batch.Draw(assetManager[AssetManager.NoTexture], entity.RenderPosition);
            }

            batch.End();
        }
        private void UnselectAbilityIfNeeded()
        {
            var mobId = _game.CurrentMob;

            if (mobId == null || !SelectedAbilityIndex.HasValue)
            {
                return;
            }

            var mobInfo         = _game.MobManager.MobInfos[mobId.Value];
            var selectedAbility = mobInfo.Abilities[SelectedAbilityIndex.Value];

            if (!GameInvariants.IsAbilityUsableNoTarget(_game, mobId.Value, selectedAbility))
            {
                SelectedAbilityIndex = null;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Calculates an action according to a simple default policy. Used mainly
        /// in MCTS playouts.
        /// </summary>
        public static UctAction DefaultPolicyAction(GameInstance state)
        {
            var mobId = state.CurrentMob;

            if (mobId == null)
            {
                throw new InvalidOperationException("Requesting mob action when there is no current mob.");
            }

            Debug.Assert(state.State.MobInstances[mobId.Value].Hp > 0, "Current mob is dead");

            var mob = state.CachedMob(mobId.Value);

            if (mob.MobInstance.Ap == 0)
            {
                return(UctAction.EndTurnAction());
            }

            var abilityIds = new List <int>();

            foreach (var possibleAbilityId in mob.MobInfo.Abilities)
            {
                if (GameInvariants.IsAbilityUsableNoTarget(state, mobId.Value, possibleAbilityId))
                {
                    abilityIds.Add(possibleAbilityId);
                }
            }

            int moveTargetId = MobInstance.InvalidId;

            var actions = new List <UctAction>();

            foreach (var possibleTargetId in state.MobManager.Mobs)
            {
                var possibleTarget = state.CachedMob(possibleTargetId);

                moveTargetId = possibleTargetId;

                if (!GameInvariants.IsTargetable(state, mob, possibleTarget))
                {
                    continue;
                }

                if (abilityIds.Count == 0)
                {
                    continue;
                }

                foreach (var abilityId in abilityIds)
                {
                    if (GameInvariants.IsAbilityUsableApRangeCheck(state, mob, possibleTarget, abilityId))
                    {
                        actions.Add(UctAction.AbilityUseAction(abilityId, mob.MobId, possibleTargetId));
                    }
                }
            }

            if (actions.Count > 0)
            {
                return(MaxAbilityRatio(state, actions));
            }

            if (moveTargetId != MobInstance.InvalidId)
            {
                return(PickMoveTowardsEnemyAction(state, state.CachedMob(mobId.Value),
                                                  state.CachedMob(moveTargetId)));
            }
            else
            {
                Utils.Log(LogSeverity.Error, nameof(ActionGenerator), "No targets, game should be over");

                throw new InvalidOperationException("No targets, game should be over.");
            }
        }