private List <EncounterAction> MoveAndAttack(EncounterState state, int dx, int dy) { var positionComponent = state.Player.GetComponent <PositionComponent>(); var oldPos = positionComponent.EncounterPosition; var newPos = new EncounterPosition(oldPos.X + dx, oldPos.Y + dy); // TODO: maybe not hostile? var hostiles = AIUtils.HostilesInPosition(state, FactionName.PLAYER, newPos.X, newPos.Y); if (hostiles.Count > 0) { var attackAction = new MeleeAttackAction(state.Player.EntityId, hostiles[state.EncounterRand.Next(hostiles.Count)]); return(new List <EncounterAction>() { attackAction }); } else { var moveAction = new MoveAction(state.Player.EntityId, newPos); return(new List <EncounterAction>() { moveAction }); } }
public static List <Entity> AdjacentHostiles(EncounterState state, FactionName parentFaction, EncounterPosition position) { var adjacentHostiles = new List <Entity>(); foreach (var newpos in state.AdjacentPositions(position)) { adjacentHostiles.AddRange(AIUtils.HostilesInPosition(state, parentFaction, newpos.X, newpos.Y)); } return(adjacentHostiles); }
private bool positionNotTooFarAheadAndMovable(EncounterState state, EncounterPosition parentPos, Unit unit, EncounterPosition possible) { var entitiesAtPos = state.EntitiesAtPosition(possible.X, possible.Y); if (!AIUtils.IsNextRowTooFarAhead(parentPos, unit) && entitiesAtPos.Count == 0) { return(true); } var hostilesAtPos = AIUtils.HostilesInPosition(state, FactionName.PLAYER, possible.X, possible.Y); if (hostilesAtPos.Count > 0) { return(true); } return(false); }
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); }