public void RecordCommand(Command command, List<Hit> hits)
        {
            var enemy = command.Character;
            if (!_threat.ContainsKey(enemy))
            {
                _threat.Add(enemy, 0);
            }

            foreach (var hit in hits)
            {
                var target = BattleBoard.GetCharacterAt(hit.Target);
                var damage = hit.Damage;

                // if nobody is at this spot, ignore it. this shouldn't come up
                // since a hit is only generated it someone is there, but i'll
                // account for it anyway
                if (target == null) continue;

                // hits against the players team (heal/friendly fire) are inverted
                // to maintain sanity. healing raises threat, friendly fire lowers it
                if (target.Faction == 0) damage = 0 - damage;

                _threat[enemy] += damage;
            }
        }
Exemple #2
0
        /// <summary>
        /// Create a callback function to process if the player chooses to have a character attack. This callback will display the targetting grid
        /// and bind _aimAbility to a function that queues an attack command from the character onto the target.
        /// </summary>
        /// <param name="character">The character whose attack is being chosen.</param>
        /// <param name="ability">The ability currently being aimed.</param>
        /// <returns></returns>
        private void SelectAbilityTarget(Combatant character, Ability ability)
        {
            _state = BattleState.AimingAbility;
            Gui.Screen.Desktop.Children.Remove(_radialMenuControl);

            _battleBoardLayer.SetTargettingGrid(
                ability.Name == "Move" ?
                    character.GetMovementGrid(BattleBoard.GetAccessibleGrid(character.Faction)) :
                    ability.GenerateTargetGrid(BattleBoard.Sandbag.Clone()),
                ability.GenerateImpactGrid()
            );

            _battleBoardLayer.AbilityAim = true;

            _aimAbility = (x, y) =>
                {
                    // only target enemies with angry spells and allies with friendly spells
                    if (!ability.CanTarget(BattleBoard.IsOccupied(new Point(x, y))))
                        return false;

                    character.Avatar.UpdateVelocity(x - character.Avatar.Location.X, y - character.Avatar.Location.Y);
                    character.Avatar.UpdateVelocity(0, 0);

                    // make sure the ability knows who is casting it. this probably shouldn't
                    // be done here, but there are issues doing it elsewhere.
                    ability.Character = character;

                    var command = new Command
                        {
                            Character = character,
                            Target = new Point(x, y),
                            Ability = ability
                        };

                    if(ability.Name == "Move")
                    {
                        ExecuteCommand(command);
                        return true;
                    }

                    character.CanAct = false;
                    QueuedCommands.Add(command);
                    _queuedCommands.UpdateControls();
                    _state = BattleState.Delay;
                    _delayState = BattleState.PlayerTurn;
                    _delayTimer = 0.05F;
                    ResetState();

                    return true;
                };
        }
Exemple #3
0
        private void UpdateBattleStateEnemyTurn()
        {
            var combatants = (from c in BattleBoard.Characters where c.Faction == 1 && c.CanMove select c).ToArray();

            if (combatants.Any())
            {
                // find first character that can move
                _selectedCharacter = combatants[0];

                // find the optimal location
                var decision = _commander.CalculateAction(_selectedCharacter);

                // create move command to that location
                var moveCommand = new Command
                    {
                        Ability = Ability.Factory(Game, "move"),
                        Character = _selectedCharacter,
                        Target = decision.Destination
                    };

                QueuedCommands.Add(moveCommand);

                if (decision.Command.Ability != null)
                    QueuedCommands.Add(decision.Command);

                ExecuteQueuedCommands();

                return;
            }

            ExecuteQueuedCommands();

            // all enemy players have moved / attacked
            ChangeFaction(0);
        }
Exemple #4
0
        /// <summary>
        /// Process a command given by either the AI or the player. These commands can be attacking, casting a spell,
        /// using an item or moving.
        /// </summary>
        /// <param name="command">The command to be executed.</param>
        public void ExecuteCommand(Command command)
        {
            _state = BattleState.ExecutingCommand;

            switch (command.Ability.Name)
            {
                case "Move":
                    {
                        // special case for movement
                        var grid = BattleBoard.GetAccessibleGrid(command.Character.Faction);

                        // run an A* pathfinding algorithm to get a route
                        var coords = grid.Pathfind(new Point((int)command.Character.Avatar.Location.X, (int)command.Character.Avatar.Location.Y), command.Target);

                        // remove any points on the path that don't require a direction change
                        for (var i = coords.Count - 2; i > 0; i--)
                        {
                            if(coords[i - 1].X == coords[i + 1].X || coords[i - 1].Y == coords[i + 1].Y)
                            {
                                coords.RemoveAt(i);
                            }
                        }

                        _movementCoords = coords;

                        _state = BattleState.MovingCharacter;

                        command.Character.CanMove = false;

                        if (FactionTurn == 1) break;

                        // if this character has any queued commands, cancel them upon moving
                        var queuedCommands = (from c in QueuedCommands where c.Character == command.Character select c).ToArray();

                        if(queuedCommands.Length > 0)
                        {
                            QueuedCommands.Remove(queuedCommands[0]);
                            command.Character.CanAct = true;
                        }
                    }
                    break;
                default:
                    var hits = command.Ability.GenerateHits(BattleBoard, command.Target);

                    // remove any hits on characters that no longer exist
                    for (var i = hits.Count - 1; i >= 0; i--)
                    {
                        if(BattleBoard.GetCharacterAt(hits[i].Target) == null)
                        {
                            hits.RemoveAt(i);
                        }
                    }

                    _commander.RecordCommand(command, hits);

                    // if this ability still has hits left, process them normally
                    if (hits.Count > 0)
                    {
                        command.Character.CanAct = false;
                        DisplayHits(hits);
                        command.Character.CurrentMana -= command.Ability.ManaCost;
                    }

                    break;
            }
        }