Skip to content

Commit

Permalink
Indirect fire
Browse files Browse the repository at this point in the history
- Need some more work for this to work online
- Remove last "uncorrected" units
  • Loading branch information
layagyasz committed Jun 1, 2018
1 parent e7d8ba5 commit 83ae7d8
Show file tree
Hide file tree
Showing 36 changed files with 390 additions and 165 deletions.
9 changes: 5 additions & 4 deletions AI/PositionalDeploymentHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ public IEnumerable<Order> Handle(PositionalDeployment Deployment)
.Where(i => Deployment.Validate(unit, i) == OrderInvalidReason.NONE)
.ArgMax(i => ScoreSeedTile(unit, i, coveredTiles));
deployments.Add(unit, tile);
foreach (var t in unit.GetFieldOfSight(AttackMethod.NORMAL_FIRE, tile))
coveredTiles.Add(t.Item1.Final);
foreach (var t in unit.GetFieldOfSight(AttackMethod.DIRECT_FIRE, tile))
coveredTiles.Add(t.Final);
yield return new PositionalDeployOrder(unit, tile);
}

Expand Down Expand Up @@ -74,8 +74,9 @@ double ScoreSeedTile(Unit Unit, Tile Tile, HashSet<Tile> CoveredTiles)
{
List<Tile> tiles =
Unit.GetFieldOfSight(
Unit.Configuration.SpotRange > 0 ? Unit.Configuration.SpotRange : 20, Tile, true)
.Select(i => i.Item1.Final)
Unit.Configuration.SpotRange > 0
? Unit.Configuration.SpotRange : 20, Tile, AttackMethod.DIRECT_FIRE)
.Select(i => i.Final)
.ToList();
return BaseTileScore(Tile) * (tiles.Count + tiles.Except(CoveredTiles).Count());
}
Expand Down
10 changes: 5 additions & 5 deletions AI/TileEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void ReEvaluate()
.Where(i => i.Configuration.Team != Root.Army.Configuration.Team)
.SelectMany(i => i.Units))
{
foreach (LineOfSight los in unit.GetFieldOfSight(AttackMethod.NORMAL_FIRE).Select(i => i.Item1))
foreach (var los in unit.GetFieldOfSight(AttackMethod.DIRECT_FIRE))
{
AddThreat(los.Final, GetThreat(unit, los, true), GetThreat(unit, los, false));
}
Expand All @@ -47,7 +47,7 @@ public double GetPotentialRating(Tile Tile, Unit Unit)
.Where(i => i.Configuration.Team != Root.Army.Configuration.Team)
.SelectMany(i => i.Units)
.Where(i => i.Position.HexCoordinate.Distance(Tile.HexCoordinate)
<= Unit.Configuration.GetRange(AttackMethod.NORMAL_FIRE, false)))
<= Unit.Configuration.GetRange(AttackMethod.DIRECT_FIRE, false)))
{
potential += unit.GetPointValue() * GetPotential(Unit, new LineOfSight(Tile, unit.Position))
/ unit.Configuration.Defense;
Expand All @@ -73,15 +73,15 @@ void AddThreat(Tile Tile, double Armored, double UnArmored)
double GetThreat(Unit Unit, LineOfSight LineOfSight, bool EnemyArmored)
{
return Math.Max(
new AttackFactorCalculation(Unit, AttackMethod.NORMAL_FIRE, EnemyArmored, LineOfSight, true).Attack,
new AttackFactorCalculation(Unit, AttackMethod.NORMAL_FIRE, EnemyArmored, LineOfSight, false).Attack);
new AttackFactorCalculation(Unit, AttackMethod.DIRECT_FIRE, EnemyArmored, LineOfSight, true).Attack,
new AttackFactorCalculation(Unit, AttackMethod.DIRECT_FIRE, EnemyArmored, LineOfSight, false).Attack);
}

double GetPotential(Unit Unit, LineOfSight LineOfSight)
{
IEnumerable<Unit> defenders =
LineOfSight.Final.Units.Where(
i => i.CanBeAttackedBy(Root.Army, AttackMethod.NORMAL_FIRE, true) == OrderInvalidReason.NONE);
i => i.CanBeAttackedBy(Root.Army, AttackMethod.DIRECT_FIRE, true) == OrderInvalidReason.NONE);
var armoredCount = defenders.Count(i => i.Configuration.IsArmored);
var unArmoredCount = defenders.Count(i => !i.Configuration.IsArmored);
if (armoredCount > unArmoredCount
Expand Down
3 changes: 2 additions & 1 deletion Controller/ArmyBuilder/ArmyBuilderStateController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ void HandleFinished(object Sender, EventArgs E)
ProgramStateTransitionEventArgs transition = null;
if (builder.Armies.All(i => i.Validate()))
transition = new ProgramStateTransitionEventArgs(
ProgramState.MATCH, new MatchContext(new Match(builder.BuildScenario())));
ProgramState.MATCH,
new MatchContext(new Match(builder.BuildScenario(), FullOrderAutomater.PROVIDER)));
else transition = new ProgramStateTransitionEventArgs(ProgramState.BUILD_ARMY, _Context);
OnProgramStateTransition(this, transition);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void HandleStartScenario(object Sender, ValuedEventArgs<Scenario> E)
{
OnProgramStateTransition(
this, new ProgramStateTransitionEventArgs(
ProgramState.MATCH, new MatchContext(new Match(E.Value))));
ProgramState.MATCH, new MatchContext(new Match(E.Value, FullOrderAutomater.PROVIDER))));
}
}
}
25 changes: 10 additions & 15 deletions Controller/Match/HumanMatchPlayerController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,6 @@ public class HumanMatchPlayerController : MatchPlayerController
new Color(255, 0, 0, 120)
};

public static readonly Color[] DIM_HIGHLIGHT_COLORS =
{
new Color(0, 255, 0, 60),
new Color(255, 255, 0, 60),
new Color(255, 128, 0, 60),
new Color(255, 0, 0, 60)
};

enum HighlightToggle { ENEMY_SIGHT_FIELD, VICTORY_CONDITION_FIELD };

public readonly MatchAdapter Match;
Expand Down Expand Up @@ -228,14 +220,13 @@ public void Highlight(IEnumerable<Tuple<Tile, Color>> Highlight)
}

public Color GetRangeColor(
LineOfSight LineOfSight, Unit Unit, bool DirectFire, AttackMethod AttackMethod = AttackMethod.NORMAL_FIRE)
LineOfSight LineOfSight, Unit Unit, AttackMethod AttackMethod = AttackMethod.DIRECT_FIRE)
{
return (DirectFire ? HIGHLIGHT_COLORS : DIM_HIGHLIGHT_COLORS)[
PosterizeLineOfSight(LineOfSight, Unit, AttackMethod)];
return HIGHLIGHT_COLORS[PosterizeLineOfSight(LineOfSight, Unit, AttackMethod)];
}

public int PosterizeLineOfSight(
LineOfSight LineOfSight, Unit Unit, AttackMethod AttackMethod = AttackMethod.NORMAL_FIRE)
LineOfSight LineOfSight, Unit Unit, AttackMethod AttackMethod = AttackMethod.DIRECT_FIRE)
{
return Math.Min(
LineOfSight.Range * HIGHLIGHT_COLORS.Length / (Unit.Configuration.GetRange(AttackMethod, false) + 1),
Expand All @@ -258,8 +249,8 @@ void HighlightEnemyFieldOfSight(byte Team)
.Where(i => i.Configuration.Team != Team)
.SelectMany(i => i.Units)
.SelectMany(i =>
i.GetFieldOfSight(AttackMethod.NORMAL_FIRE).Select(
j => new Tuple<Tile, int>(j.Item1.Final, PosterizeLineOfSight(j.Item1, i))))
i.GetFieldOfSight(AttackMethod.DIRECT_FIRE).Select(
j => new Tuple<Tile, int>(j.Final, PosterizeLineOfSight(j, i))))
.GroupBy(i => i.Item1)
.Select(i => new Tuple<Tile, Color>(i.Key, HIGHLIGHT_COLORS[i.Min(j => j.Item2)])));
_HighlightToggles[(int)HighlightToggle.ENEMY_SIGHT_FIELD] = true;
Expand Down Expand Up @@ -601,7 +592,11 @@ void OnUnitRightClick(object sender, MouseEventArgs e)
{
TurnInfo phase = Match.GetTurn().TurnInfo;
if (AllowedArmies.Contains(phase.Army))
_Controllers[phase.TurnComponent].HandleUnitRightClick(((UnitView)sender).Unit);
{
if (Keyboard.IsKeyPressed(Keyboard.Key.LShift))
_Controllers[phase.TurnComponent].HandleUnitShiftRightClick(((UnitView)sender).Unit);
else _Controllers[phase.TurnComponent].HandleUnitRightClick(((UnitView)sender).Unit);
}
}

void OnKeyPressed(object sender, KeyPressedEventArgs E)
Expand Down
1 change: 1 addition & 0 deletions Controller/Match/MatchRecordReplayPlayerController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public void DoTurnAsync(Turn Turn)
didAnything |= !(o is ResetOrder);
}
if (didAnything) Thread.Sleep(WaitMillis(Turn.TurnInfo.TurnComponent));
if (_Orders.Count < 2) Thread.Sleep(2500);
_Match.ExecuteOrder(_Orders.Dequeue());
}
catch (Exception e) { Console.WriteLine(e); }
Expand Down
4 changes: 2 additions & 2 deletions Controller/Match/Subcontroller/AircraftController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ void SetAircraftHighlight(Unit Unit)
{
_Controller.Highlight(Unit.GetFieldOfSight(AttackMethod.AIR).Select(
i => new Tuple<Tile, Color>(
i.Item1.Final,
_Controller.GetRangeColor(i.Item1, Unit, i.Item2, AttackMethod.AIR))));
i.Final,
_Controller.GetRangeColor(i, Unit, AttackMethod.AIR))));
}
}
}
36 changes: 28 additions & 8 deletions Controller/Match/Subcontroller/AttackController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Linq;

using SFML.Graphics;
using SFML.Window;

namespace PanzerBlitz
{
Expand All @@ -16,14 +17,23 @@ public override void HandleTileRightClick(Tile Tile) { }

public override void HandleUnitLeftClick(Unit Unit)
{
if (Unit.Army == _Controller.CurrentTurn.Army
&& Unit.CanAttack(AttackMethod.NORMAL_FIRE) == OrderInvalidReason.NONE)
HandleClick(Unit, AttackMethod.DIRECT_FIRE);
}

public override void HandleUnitShiftLeftClick(Unit Unit)
{
HandleClick(Unit, AttackMethod.INDIRECT_FIRE);
}

void HandleClick(Unit Unit, AttackMethod AttackMethod)
{
if (Unit.Army == _Controller.CurrentTurn.Army && Unit.CanAttack(AttackMethod) == OrderInvalidReason.NONE)
{
_Controller.SelectUnit(Unit);

_Controller.Highlight(
Unit.GetFieldOfSight(AttackMethod.NORMAL_FIRE).Select(
i => new Tuple<Tile, Color>(i.Item1.Final, _Controller.GetRangeColor(i.Item1, Unit, i.Item2))));
Unit.GetFieldOfSight(AttackMethod).Select(
i => new Tuple<Tile, Color>(i.Final, _Controller.GetRangeColor(i, Unit))));
}
else if (Unit.Army != _Controller.CurrentTurn.Army)
{
Expand All @@ -38,10 +48,20 @@ public override void HandleUnitLeftClick(Unit Unit)
}
else
{
AddAttack(
Unit.Position,
new NormalSingleAttackOrder(
_Controller.SelectedUnit, Unit, _Controller.UseSecondaryWeapon()));
if (AttackMethod == AttackMethod.INDIRECT_FIRE)
{
AddAttack(
Unit.Position,
new IndirectFireSingleAttackOrder(
_Controller.SelectedUnit, Unit.Position, _Controller.UseSecondaryWeapon()));
}
else
{
AddAttack(
Unit.Position,
new DirectFireSingleAttackOrder(
_Controller.SelectedUnit, Unit, _Controller.UseSecondaryWeapon()));
}
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion Controller/Match/Subcontroller/BaseController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,12 @@ public virtual bool CanEmplace()
public abstract void HandleUnitRightClick(Unit Unit);
public abstract void HandleKeyPress(Keyboard.Key Key);

public void HandleUnitShiftLeftClick(Unit Unit)
public virtual void HandleUnitShiftLeftClick(Unit Unit)
{
return;
}

public void HandleUnitShiftRightClick(Unit Unit)
{
_Controller.Clear();
var pane = new UnitInfoPane(Unit, _Controller.UnitConfigurationRenderer);
Expand Down
4 changes: 2 additions & 2 deletions Controller/Match/Subcontroller/CloseAssaultController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ void SetCloseAssaultHighlight(Unit Unit)
{
var attackRange = Unit.GetFieldOfSight(AttackMethod.CLOSE_ASSAULT).Select(
i => new Tuple<Tile, Color>(
i.Item1.Final,
_Controller.GetRangeColor(i.Item1, Unit, i.Item2, AttackMethod.CLOSE_ASSAULT)));
i.Final,
_Controller.GetRangeColor(i, Unit, AttackMethod.CLOSE_ASSAULT)));

var moveRange = Unit.GetFieldOfMovement(true).Select(
i => new Tuple<Tile, Color>(
Expand Down
1 change: 1 addition & 0 deletions Controller/Match/Subcontroller/Subcontroller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public interface Subcontroller
void HandleUnitLeftClick(Unit Unit);
void HandleUnitShiftLeftClick(Unit Unit);
void HandleUnitRightClick(Unit Unit);
void HandleUnitShiftRightClick(Unit Unit);
void HandleKeyPress(Keyboard.Key key);
}
}
2 changes: 1 addition & 1 deletion Controller/MatchLobby/MatchLobbyContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public ChatAdapter MakeChatAdapter()

public MatchContext MakeMatchContext()
{
var match = new Match(Lobby.Scenario, IsHost);
var match = new Match(Lobby.Scenario, IsHost ? FullOrderAutomater.PROVIDER : i => null);
var serializer = new OrderSerializer(match);

if (IsHost)
Expand Down
10 changes: 6 additions & 4 deletions Model/Match.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class Match

IEnumerator<Turn> _TurnOrder;

OrderAutomator _OrderAutomater;
OrderAutomater _OrderAutomater;
List<Order> _OrderBuffer = new List<Order>();
Random _Random = new Random();

Expand All @@ -30,7 +30,7 @@ public Turn CurrentTurn
}
}

public Match(Scenario Scenario, bool AutomateTurns = true)
public Match(Scenario Scenario, Func<Match, OrderAutomater> OrderAutomater)
{
this.Scenario = Scenario;
Map = Scenario.MapConfiguration.GenerateMap(Scenario.Environment, IdGenerator);
Expand All @@ -48,7 +48,7 @@ public Match(Scenario Scenario, bool AutomateTurns = true)
u.OnMove += UpdateUnitVisibilityFromMove;
u.OnFire += UpdateUnitVisibilityFromFire;
}
if (AutomateTurns) _OrderAutomater = new OrderAutomator(this);
_OrderAutomater = OrderAutomater(this);
}

public Dictionary<Army, ObjectiveSuccessLevel> GetArmyObjectiveSuccessLevels()
Expand Down Expand Up @@ -127,7 +127,7 @@ public OrderInvalidReason ExecuteOrder(Order Order)
var r = ValidateOrder(Order);
if (r != OrderInvalidReason.NONE) return r;

ExecutedOrders.Add(Order);
if (!ExecutedOrders.Contains(Order)) ExecutedOrders.Add(Order);

if (Order is NextPhaseOrder)
{
Expand All @@ -138,7 +138,9 @@ public OrderInvalidReason ExecuteOrder(Order Order)

var executed = Order.Execute(_Random);
if (executed == OrderStatus.IN_PROGRESS && _OrderAutomater != null)
{
_OrderAutomater.BufferOrder(Order, _TurnOrder.Current.TurnInfo);
}
if (executed == OrderStatus.ILLEGAL)
throw new Exception(string.Format("Tried to execute illegal order. {0} {1}", Order, Order.Validate()));

Expand Down
2 changes: 1 addition & 1 deletion Model/MatchRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public MatchRecord(Match Match, OrderSerializer OrderSerializer)

public MatchRecord(SerializationInputStream Stream)
{
Match = new Match(new Scenario(Stream), false);
Match = new Match(new Scenario(Stream), MultiTurnOrderAutomater.PROVIDER);
OrderSerializer = new OrderSerializer(Match);
Orders = Stream.ReadEnumerable(() => OrderSerializer.Deserialize(Stream)).ToList();
}
Expand Down
22 changes: 13 additions & 9 deletions Model/Orders/Attack/AttackFactorCalculation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,22 @@ public AttackFactorCalculation(
LineOfSight LineOfSight,
bool UseSecondaryWeapon)
{
if (Unit.CanAttack(AttackMethod, EnemyArmored, LineOfSight, UseSecondaryWeapon) != OrderInvalidReason.NONE)
{
Attack = 0;
Factors = new List<AttackFactorCalculationFactor> { AttackFactorCalculationFactor.CANNOT_ATTACK };
return;
}

switch (AttackMethod)
{
case AttackMethod.NORMAL_FIRE:
case AttackMethod.DIRECT_FIRE:
GetNormalAttack(Unit, EnemyArmored, LineOfSight, UseSecondaryWeapon);
break;
case AttackMethod.INDIRECT_FIRE:
GetNormalAttack(Unit, EnemyArmored, LineOfSight, UseSecondaryWeapon);
Attack /= 4;
Factors.Add(AttackFactorCalculationFactor.INDIRECT_FIRE);
break;
case AttackMethod.AIR:
GetAirAttack(Unit, EnemyArmored, UseSecondaryWeapon);
Expand Down Expand Up @@ -85,14 +97,6 @@ void GetAirAttack(Unit Unit, bool EnemyArmored, bool UseSecondaryWeapon)

void GetNormalAttack(Unit Unit, bool EnemyArmored, LineOfSight LineOfSight, bool UseSecondaryWeapon)
{
if (Unit.CanAttack(
AttackMethod.NORMAL_FIRE, EnemyArmored, LineOfSight, UseSecondaryWeapon) != OrderInvalidReason.NONE)
{
Attack = 0;
Factors = new List<AttackFactorCalculationFactor> { AttackFactorCalculationFactor.CANNOT_ATTACK };
return;
}

var weapon = Unit.Configuration.GetWeapon(UseSecondaryWeapon);
Factors = new List<AttackFactorCalculationFactor>();
Attack = weapon.Attack;
Expand Down
3 changes: 2 additions & 1 deletion Model/Orders/Attack/AttackMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
public enum AttackMethod
{
NONE,
NORMAL_FIRE,
DIRECT_FIRE,
INDIRECT_FIRE,
CLOSE_ASSAULT,
OVERRUN,
MINEFIELD,
Expand Down
Loading

0 comments on commit 83ae7d8

Please sign in to comment.