示例#1
0
        private static Unit CreateAndDeployUnit(Random seededRand, EncounterState state, FactionName faction,
                                                Lane lane, int lanePosition, UnitOrder order, FormationType type, FormationFacing facing, int size,
                                                Func <int, Unit, Entity> entityFn, CommanderAIComponent commanderAI)
        {
            var center = lane.PositionFor(facing, lanePosition);
            var unit   = new Unit(Guid.NewGuid().ToString(), faction, center, order, type, facing);

            state.AddUnit(unit);
            commanderAI.RegisterUnit(unit);
            lane.RegisterUnitAtPosition(unit, lanePosition);

            var width = (int)Math.Ceiling(Math.Sqrt(size));

            List <EncounterPosition> positions = new List <EncounterPosition>();

            for (int x = 0 - width; x < width; x++)
            {
                for (int y = 0 - width; y < width; y++)
                {
                    positions.Add(new EncounterPosition(x, y));
                }
            }
            GameUtils.Shuffle(seededRand, positions);

            for (int i = 0; i < size; i++)
            {
                var entity = entityFn(i, unit);
                state.PlaceEntity(entity, new EncounterPosition(center.X + positions[i].X, center.Y + positions[i].Y));
                unit.RegisterBattleReadyEntity(entity);
            }

            return(unit);
        }
示例#2
0
        private static CommanderAIComponent CreateAndPlaceCommander(EncounterState state)
        {
            var commanderUnitId = "Invisible Commander AI Unit";
            var commander       = EntityBuilder.CreateCommanderEntity(state.CurrentTick, FactionName.NEUTRAL);
            var commanderAI     = commander.GetComponent <CommanderAIComponent>();

            state.PlaceEntity(commander, new EncounterPosition(1, 1)); // Invisible and unreachable but you CAN mouse over it, lol. it's fiiine

            // Commander unit is required for non-targeted commands to resolve properly
            var commanderUnit = new Unit(commanderUnitId, FactionName.NEUTRAL, commander.GetComponent <PositionComponent>().EncounterPosition,
                                         UnitOrder.REFORM, FormationType.LINE_20, FormationFacing.SOUTH);

            state.AddUnit(commanderUnit);
            commanderAI.RegisterUnit(commanderUnit);

            // Boilerplate conditions
            var playerRouted = new OrderTrigger(OrderTriggerType.ALL_UNITS_OF_FACTION_ROUTED, false, triggerFaction: FactionName.PLAYER);

            commanderAI.RegisterTriggeredOrder(playerRouted, new Order(commanderUnitId, OrderType.DECLARE_DEFEAT));
            var enemyRouted = new OrderTrigger(OrderTriggerType.ALL_UNITS_OF_FACTION_ROUTED, false, triggerFaction: FactionName.ENEMY);

            commanderAI.RegisterTriggeredOrder(enemyRouted, new Order(commanderUnitId, OrderType.DECLARE_VICTORY));

            return(commanderAI);
        }
示例#3
0
 private static Func <int, Unit, Entity> SecondLineEnemyFn(EncounterState state, Random seededRand)
 {
     if (seededRand.Next(2) == 0)
     {
         return((formationNum, unit) => EntityBuilder.CreateGallicVeteranInfantry(state.CurrentTick, formationNum, unit, FactionName.ENEMY));
     }
     else
     {
         return((formationNum, unit) => EntityBuilder.CreatePunicVeteranInfantry(state.CurrentTick, formationNum, unit, FactionName.ENEMY));
     }
 }
示例#4
0
        private static void PopulatePlayerFactionLane(int dungeonLevel, EncounterState state, Random seededRand,
                                                      DeploymentInfo deploymentInfo, CommanderAIComponent commanderAI, Lane lane)
        {
            var numLines = seededRand.Next(3) + 1;
            // var numLines = 2;

            Unit hastatusUnit = null;

            if (numLines > 0)
            {
                var numHastati = seededRand.Next(80, 120);
                Func <int, Unit, Entity> hastatusFn = (formationNum, unit) => EntityBuilder.CreateHastatusEntity(state.CurrentTick, formationNum, unit, FactionName.PLAYER);
                if (lane.LaneIdx == deploymentInfo.NumLanes / 2)
                {
                    hastatusFn = WrapWithPlayerFn(state, hastatusFn, numHastati - 3);
                    // hastatusFn = WrapWithPlayerFn(state, hastatusFn, 9);
                }
                hastatusUnit = CreateAndDeployUnit(seededRand, state, FactionName.PLAYER,
                                                   lane, 1, UnitOrder.REFORM, FormationType.MANIPULE_CLOSED,
                                                   deploymentInfo.PlayerFacing,
                                                   numHastati,
                                                   hastatusFn, commanderAI);
                commanderAI.RegisterDeploymentOrder(20, new Order(hastatusUnit.UnitId, OrderType.OPEN_MANIPULE));
                commanderAI.RegisterDeploymentOrder(ADVANCE_AT_TURN, new Order(hastatusUnit.UnitId, OrderType.ADVANCE));
                RegisterRoutAtPercentage(commanderAI, hastatusUnit, .80f);
            }
            Unit princepsUnit = null;

            if (numLines > 1)
            {
                Func <int, Unit, Entity> princepsFn = (formationNum, unit) => EntityBuilder.CreatePrincepsEntity(state.CurrentTick, formationNum, unit, FactionName.PLAYER);
                princepsUnit = CreateAndDeployUnit(seededRand, state, FactionName.PLAYER,
                                                   lane, 2, UnitOrder.REFORM, FormationType.MANIPULE_CLOSED,
                                                   deploymentInfo.PlayerFacing,
                                                   seededRand.Next(80, 120),
                                                   // 20,
                                                   princepsFn, commanderAI);
                commanderAI.RegisterDeploymentOrder(30, new Order(princepsUnit.UnitId, OrderType.OPEN_MANIPULE));
                commanderAI.RegisterTriggeredOrder(TriggeredOrder.AdvanceIfUnitRetreatsRoutsOrWithdraws(hastatusUnit, princepsUnit));
                RegisterRoutAtPercentage(commanderAI, princepsUnit, .60f);
            }
            Unit triariusUnit = null;

            if (numLines > 2)
            {
                Func <int, Unit, Entity> triariusFn = (formationNum, unit) => EntityBuilder.CreateTriariusEntity(state.CurrentTick, formationNum, unit, FactionName.PLAYER);
                triariusUnit = CreateAndDeployUnit(seededRand, state, FactionName.PLAYER,
                                                   lane, 3, UnitOrder.REFORM, FormationType.MANIPULE_CLOSED,
                                                   deploymentInfo.PlayerFacing, seededRand.Next(40, 60), triariusFn, commanderAI);
                commanderAI.RegisterDeploymentOrder(40, new Order(triariusUnit.UnitId, OrderType.OPEN_MANIPULE));
                commanderAI.RegisterTriggeredOrder(TriggeredOrder.AdvanceIfUnitRetreatsRoutsOrWithdraws(princepsUnit, triariusUnit));
                RegisterRoutAtPercentage(commanderAI, triariusUnit, .40f);
            }
        }
示例#5
0
 private static void InitializeMap(EncounterState state, int width, int height)
 {
     // Initialize the map with empty tiles
     state.MapWidth        = width;
     state.MapHeight       = height;
     state._encounterTiles = new EncounterTile[width, height];
     for (int x = 0; x < width; x++)
     {
         for (int y = 0; y < height; y++)
         {
             state._encounterTiles[x, y] = new EncounterTile();
         }
     }
 }
示例#6
0
 private static Func <int, Unit, Entity> WrapWithPlayerFn(EncounterState state, Func <int, Unit, Entity> unitFn, int playerFormationNum)
 {
     return(delegate(int formationNum, Unit unit) {
         if (formationNum == playerFormationNum)
         {
             AddPlayerToUnit(state.Player, unit, playerFormationNum);
             return state.Player;
         }
         else
         {
             return EntityBuilder.CreateHastatusEntity(state.CurrentTick, formationNum, unit, FactionName.PLAYER);
         }
     });
 }
示例#7
0
        private static void PopulateEnemyFactionLane(int dungeonLevel, EncounterState state, Random seededRand,
                                                     DeploymentInfo deploymentInfo, CommanderAIComponent commanderAI, Lane lane)
        {
            var numLines = seededRand.Next(3) + 1;
            // var numLines = 1;

            Unit firstRankUnit = null;

            if (numLines > 0)
            {
                var enemyFn = FirstLineEnemyFn(state, seededRand);
                firstRankUnit = CreateAndDeployUnit(seededRand, state, FactionName.ENEMY,
                                                    lane, 1, UnitOrder.REFORM, FormationType.LINE_20,
                                                    deploymentInfo.EnemyFacing,
                                                    seededRand.Next(80, 120),
                                                    // 20,
                                                    enemyFn, commanderAI);
                commanderAI.RegisterDeploymentOrder(ADVANCE_AT_TURN - 5, new Order(firstRankUnit.UnitId, OrderType.ADVANCE));
                RegisterRoutAtPercentage(commanderAI, firstRankUnit, .80f);
            }
            Unit secondRankUnit = null;

            if (numLines > 1)
            {
                var enemyFn = SecondLineEnemyFn(state, seededRand);
                secondRankUnit = CreateAndDeployUnit(seededRand, state, FactionName.ENEMY,
                                                     lane, 2, UnitOrder.REFORM, FormationType.LINE_20,
                                                     deploymentInfo.EnemyFacing,
                                                     seededRand.Next(80, 120),
                                                     // 20,
                                                     enemyFn, commanderAI);
                commanderAI.RegisterTriggeredOrder(TriggeredOrder.AdvanceIfUnitRetreatsRoutsOrWithdraws(firstRankUnit, secondRankUnit));
                RegisterRoutAtPercentage(commanderAI, secondRankUnit, .60f);
            }
            Unit thirdRankUnit = null;

            if (numLines > 2)
            {
                var enemyFn = ThirdLineEnemyFn(state, seededRand);
                thirdRankUnit = CreateAndDeployUnit(seededRand, state, FactionName.ENEMY,
                                                    lane, 3, UnitOrder.REFORM, FormationType.LINE_20,
                                                    deploymentInfo.EnemyFacing, seededRand.Next(40, 60), enemyFn, commanderAI);
                commanderAI.RegisterTriggeredOrder(TriggeredOrder.AdvanceIfUnitRetreatsRoutsOrWithdraws(secondRankUnit, thirdRankUnit));
                RegisterRoutAtPercentage(commanderAI, thirdRankUnit, .40f);
            }
        }
示例#8
0
        public static void PopulateStateForLevel(Entity player, int dungeonLevel, EncounterState state, Random seededRand,
                                                 int width = 300, int height = 300, int maxZoneGenAttempts = 100)
        {
            InitializeMap(state, width, height);

            // Reset player's start
            // Heal the player
            player.GetComponent <PlayerComponent>().StartOfLevel = true;
            player.GetComponent <DefenderComponent>().RestoreHP(9999);

            var commanderAI = CreateAndPlaceCommander(state);

            var numLanes       = seededRand.Next(4) + 1;
            var deploymentInfo = DeploymentInfo.Create(width, height, seededRand, numLanes);

            state.DeploymentInfo = deploymentInfo;

            foreach (var lane in deploymentInfo.Lanes)
            {
                PopulatePlayerFactionLane(dungeonLevel, state, seededRand, deploymentInfo, commanderAI, lane);
                PopulateEnemyFactionLane(dungeonLevel, state, seededRand, deploymentInfo, commanderAI, lane);
            }
        }
示例#9
0
 private static Func <int, Unit, Entity> ThirdLineEnemyFn(EncounterState state, Random seededRand)
 {
     return((formationNum, unit) => EntityBuilder.CreatePunicHeavyInfantry(state.CurrentTick, formationNum, unit, FactionName.ENEMY));
 }