Пример #1
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);
        }