Exemplo n.º 1
0
        public static List <Entity> AdjacentFriendlies(EncounterState state, Entity entity, FactionName parentFaction, EncounterPosition position)
        {
            var adjacentFriendlies = new List <Entity>();

            foreach (var newpos in state.AdjacentPositions(position))
            {
                adjacentFriendlies.AddRange(AIUtils.FriendliesInPosition(state, entity, parentFaction, newpos.X, newpos.Y));
            }
            return(adjacentFriendlies);
        }
Exemplo n.º 2
0
        private static List <EncounterAction> ActionsUnitAdvanceRotateOut(EncounterState state, Entity parent, Unit unit, bool backSecure)
        {
            var actions = new List <EncounterAction>();

            var unitComponent     = parent.GetComponent <UnitComponent>();
            var parentPos         = parent.GetComponent <PositionComponent>().EncounterPosition;
            var parentFaction     = parent.GetComponent <FactionComponent>().Faction;
            var rotationComponent = parent.GetComponent <AIRotationComponent>();

            var positionBack = AIUtils.RotateAndProject(parentPos, 0, 1, unit.UnitFacing);

            var  friendliesParent = AIUtils.FriendliesInPosition(state, parent, parentFaction, parentPos.X, parentPos.Y);
            bool parentPosSecure  = false;

            foreach (var friendly in friendliesParent)
            {
                if (!friendly.IsRotating())
                {
                    parentPosSecure = true;
                    break;
                }
            }

            // If nobody is in your square or behind you, hold position
            // Issue: if you have 2 units that are retreating, they'll form a self-reinforcing rout, which...I mean. lol.
            if (backSecure || parentPosSecure)
            {
                actions.Add(new MoveAction(parent.EntityId, positionBack));
            }
            else
            {
                rotationComponent.NotifyRotationCompleted();
                actions.Add(new WaitAction(parent.EntityId));
            }

            return(actions);
        }
Exemplo n.º 3
0
        private static List <EncounterAction> ActionsUnitAdvanceFight(EncounterState state, Entity parent, Unit unit)
        {
            var actions = new List <EncounterAction>();

            var unitComponent = parent.GetComponent <UnitComponent>();
            var parentPos     = parent.GetComponent <PositionComponent>().EncounterPosition;
            var parentFaction = parent.GetComponent <FactionComponent>().Faction;

            var  targetEndPos = parentPos;
            bool tryAdvance   = true;

            if (tryAdvance)
            {
                if (IsNextRowTooFarAhead(parentPos, unit))
                {
                    tryAdvance = false;
                }
            }

            // Override for if you're too far back
            if (IsPositionTooFarBehind(AIUtils.RotateAndProject(parentPos, 0, -1, unit.UnitFacing), unit))
            {
                var aheadPos = AIUtils.RotateAndProject(parentPos, 0, -1, unit.UnitFacing);
                actions.Add(new MoveAction(parent.EntityId, aheadPos));
                TryAddAttackAdjacent(state, parent, actions, parentFaction, aheadPos);
                return(actions);
            }

            // Morale check for advancing directly into an enemy
            if (tryAdvance)
            {
                var twoStepsAhead = AIUtils.RotateAndProject(parentPos, 0, -2, unit.UnitFacing);
                if (AIUtils.HostilesInPosition(state, parentFaction, twoStepsAhead.X, twoStepsAhead.Y).Count > 0)
                {
                    var moraleState = parent.GetComponent <AIMoraleComponent>().CurrentMoraleState;
                    if (moraleState == MoraleState.WAVERING)
                    {
                        if (state.EncounterRand.Next(2) == 0)
                        {
                            tryAdvance = false;
                        }
                    }
                    else if (moraleState < MoraleState.WAVERING)
                    {
                        tryAdvance = false;
                    }
                }
            }

            if (tryAdvance)
            {
                // We're gonna have some serious Phalanx Drift goin' on I guess?
                var forwardPositions = new List <EncounterPosition>()
                {
                    AIUtils.RotateAndProject(parentPos, 0, -1, unit.UnitFacing)
                };
                if (!(unit.RightFlank && AIUtils.IsOnFlank(parentPos.X, parentPos.Y, unit, Flank.RIGHT)))
                {
                    forwardPositions.Add(AIUtils.RotateAndProject(parentPos, 1, -1, unit.UnitFacing));
                }
                if (!(unit.LeftFlank && AIUtils.IsOnFlank(parentPos.X, parentPos.Y, unit, Flank.LEFT)))
                {
                    forwardPositions.Add(AIUtils.RotateAndProject(parentPos, -1, -1, unit.UnitFacing));
                }

                foreach (var forwardPos in forwardPositions)
                {
                    if (state.EntitiesAtPosition(forwardPos.X, forwardPos.Y).Count == 0)
                    {
                        // Never go into a square unless it's flanked by an existing friendly
                        bool supported = false;
                        for (int y = -1; y < 2; y++)
                        {
                            var leftPos = AIUtils.RotateAndProject(forwardPos, -1, y, unit.UnitFacing);
                            if (AIUtils.FriendliesInPosition(state, parent, parentFaction, leftPos.X, leftPos.Y).Count > 0)
                            {
                                supported = true;
                                break;
                            }
                            var rightPos = AIUtils.RotateAndProject(forwardPos, 1, y, unit.UnitFacing);
                            if (AIUtils.FriendliesInPosition(state, parent, parentFaction, rightPos.X, rightPos.Y).Count > 0)
                            {
                                supported = true;
                                break;
                            }
                        }
                        if (supported)
                        {
                            targetEndPos = forwardPos;
                            break;
                        }
                    }
                }
                if (targetEndPos != parentPos)
                {
                    actions.Add(new MoveAction(parent.EntityId, targetEndPos));
                }
            }
            TryAddAttackAdjacent(state, parent, actions, parentFaction, targetEndPos);
            if (actions.Count == 0)
            {
                actions.Add(new WaitAction(parent.EntityId));
            }

            return(actions);
        }