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); }
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); } }
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); } }
private static void RegisterRoutAtPercentage(CommanderAIComponent commanderAIComponent, Unit unit, float percentage) { var trigger = new OrderTrigger(OrderTriggerType.UNIT_BELOW_STRENGTH_PERCENT, false, watchedUnitIds: new List <string>() { unit.UnitId }, belowStrengthPercent: percentage); commanderAIComponent.RegisterTriggeredOrder(trigger, new Order(unit.UnitId, OrderType.ROUT)); var laneClearTrigger = new OrderTrigger(OrderTriggerType.LANE_CLEAR_OF_UNITS_FROM_FACTION, false, watchedUnitIds: new List <string>() { unit.UnitId }, triggerFaction: unit.UnitFaction.Opposite()); commanderAIComponent.RegisterTriggeredOrder(laneClearTrigger, new Order(unit.UnitId, OrderType.PREPARE_SWEEP_NEXT_LANE)); }