1
0
Fork 0
This commit is contained in:
Michaël Lemaire 2018-07-09 16:59:17 +02:00
parent c608ac2a08
commit fc0f9210dd
20 changed files with 96 additions and 38 deletions

View file

@ -41,6 +41,7 @@ Battle
------ ------
* Fix tactical information being hidden when changing selected action * Fix tactical information being hidden when changing selected action
* Right click while targetting switch to edit mode (move target and fire target are then draggable) - this will be the default on mobile
* Improve arena ships layering (sometimes information is displayed behind other sprites) * Improve arena ships layering (sometimes information is displayed behind other sprites)
* In the ship tooltip, show power cost, toggled and overheat states * In the ship tooltip, show power cost, toggled and overheat states
* Display shield (and its (dis)appearance) * Display shield (and its (dis)appearance)

View file

@ -5,6 +5,18 @@ module TK.SpaceTac.Specs {
} }
testing("HexagonalArenaGrid", test => { testing("HexagonalArenaGrid", test => {
test.case("checks coordinates", check => {
let grid = new HexagonalArenaGrid(5, 1);
check.equals(grid.check({ x: 0, y: 0 }), true, "0,0");
check.equals(grid.check({ x: 1, y: 0 }), false, "1,0");
check.equals(grid.check({ x: 5, y: 0 }), true, "5,0");
check.equals(grid.check({ x: 6, y: 0 }), false, "6,0");
check.equals(grid.check({ x: 0, y: 5 }), false, "0,5");
check.equals(grid.check({ x: 2.5, y: 5 }), true, "2.5,5");
check.equals(grid.check({ x: 5, y: 5 }), false, "5,5");
check.equals(grid.check({ x: 7.5, y: 5 }), true, "7.5,5");
});
test.case("snaps coordinates to the nearest grid point, on a biased grid", check => { test.case("snaps coordinates to the nearest grid point, on a biased grid", check => {
let grid = new HexagonalArenaGrid(4, 0.75); let grid = new HexagonalArenaGrid(4, 0.75);
checkLocation(check, grid.snap({ x: 0, y: 0 }), 0, 0); checkLocation(check, grid.snap({ x: 0, y: 0 }), 0, 0);

View file

@ -2,21 +2,59 @@ module TK.SpaceTac {
/** /**
* Abstract grid for the arena where the battle takes place * Abstract grid for the arena where the battle takes place
* *
* The grid is used to snap arena coordinates for ships and targets * The grid is used to snap arena coordinates on grid vertices, for ships and targets
*
* The default implementation does not enforce any grid or unit (leaves coordinates as they are)
*/ */
export interface IArenaGrid { export class ArenaGrid {
snap(loc: IArenaLocation): IArenaLocation; /**
* Get the base unit of measurement between two points
*/
getUnit(): number {
return 1;
}
/**
* Check that an arena location is on a grid vertex
*/
check(loc: IArenaLocation): boolean {
return arenaDistance(loc, this.snap(loc)) < 1e-8;
}
/**
* Snap a floating point arena location to a grid vertex
*/
snap(loc: IArenaLocation): IArenaLocation {
return loc;
}
/**
* Measure the distance between two points
*
* This returns a distance in grid units
*/
measure(loc1: IArenaLocation, loc2: IArenaLocation): number {
return arenaDistance(this.snap(loc1), this.snap(loc2));
}
} }
/** /**
* Pixel grid * Pixel unbounded grid
* *
* This will only round the coordinates to the pixels * This will only round the coordinates to the pixels, with an optional unit for distance measurements
*/ */
export class PixelGrid implements IArenaGrid { export class PixelGrid extends ArenaGrid {
constructor(protected readonly unit = 1) {
super();
}
snap(loc: IArenaLocation): IArenaLocation { snap(loc: IArenaLocation): IArenaLocation {
return new ArenaLocation(Math.round(loc.x), Math.round(loc.y)); return new ArenaLocation(Math.round(loc.x), Math.round(loc.y));
} }
measure(loc1: IArenaLocation, loc2: IArenaLocation): number {
return Math.round(super.measure(loc1, loc2) / this.unit);
}
} }
/** /**
@ -24,10 +62,12 @@ module TK.SpaceTac {
* *
* This grid is composed of regular hexagons where all vertices are at a same distance "unit" of the hexagon center * This grid is composed of regular hexagons where all vertices are at a same distance "unit" of the hexagon center
*/ */
export class HexagonalArenaGrid implements IArenaGrid { export class HexagonalArenaGrid extends PixelGrid {
private yunit: number; private readonly yunit: number;
constructor(unit: number, yfactor = Math.sqrt(0.75)) {
super(unit);
constructor(private unit: number, private yfactor = Math.sqrt(0.75)) {
this.yunit = unit * yfactor; this.yunit = unit * yfactor;
} }

View file

@ -4,7 +4,7 @@ module TK.SpaceTac {
*/ */
export class Battle { export class Battle {
// Grid for the arena // Grid for the arena
grid: IArenaGrid grid: ArenaGrid
// Battle outcome, if the battle has ended // Battle outcome, if the battle has ended
outcome: BattleOutcome | null = null outcome: BattleOutcome | null = null
@ -34,8 +34,6 @@ module TK.SpaceTac {
// Size of the battle area // Size of the battle area
width: number width: number
height: number height: number
border = 50
ship_separation = 100
// Indicator that an AI is playing // Indicator that an AI is playing
ai_playing = false ai_playing = false

View file

@ -115,8 +115,6 @@ module TK.SpaceTac.Specs {
battle.fleets[0].addShip(ship); battle.fleets[0].addShip(ship);
let ship1 = battle.fleets[0].addShip(); let ship1 = battle.fleets[0].addShip();
let moveaction = nn(simulator.findEngine()); let moveaction = nn(simulator.findEngine());
(<any>moveaction).safety_distance = 30;
battle.ship_separation = 30;
check.same(simulator.getApproach(moveaction, Target.newFromLocation(350, 200), 100), ApproachSimulationError.NO_MOVE_NEEDED); check.same(simulator.getApproach(moveaction, Target.newFromLocation(350, 200), 100), ApproachSimulationError.NO_MOVE_NEEDED);
check.same(simulator.getApproach(moveaction, Target.newFromLocation(400, 200), 100), ApproachSimulationError.NO_MOVE_NEEDED); check.same(simulator.getApproach(moveaction, Target.newFromLocation(400, 200), 100), ApproachSimulationError.NO_MOVE_NEEDED);

View file

@ -50,7 +50,7 @@ module TK.SpaceTac {
// Playing ship // Playing ship
private ship: Ship, private ship: Ship,
// Coordinates grid // Coordinates grid
private grid: IArenaGrid private grid: ArenaGrid
) { } ) { }
/** /**

View file

@ -78,6 +78,18 @@ module TK.SpaceTac {
return new ArenaLocationAngle(this.arena_x, this.arena_y, this.arena_angle); return new ArenaLocationAngle(this.arena_x, this.arena_y, this.arena_angle);
} }
/**
* Return the current grid for the ship
*/
get grid(): ArenaGrid {
let battle = this.getBattle();
if (battle) {
return battle.grid;
} else {
return new ArenaGrid();
}
}
/** /**
* Returns the name of this ship * Returns the name of this ship
*/ */

View file

@ -37,7 +37,7 @@ module TK.SpaceTac {
/** /**
* Snap to battle grid * Snap to battle grid
*/ */
snap(grid: IArenaGrid): Target { snap(grid: ArenaGrid): Target {
if (this.ship_id) { if (this.ship_id) {
return this; return this;
} else { } else {

View file

@ -75,7 +75,7 @@ module TK.SpaceTac {
if (this.distance_per_power == 0) { if (this.distance_per_power == 0) {
return Infinity; return Infinity;
} else if (target) { } else if (target) {
let distance = Target.newFromShip(ship).getDistanceTo(target); let distance = ship.grid.measure(ship.location, target);
return Math.ceil(distance / this.distance_per_power); return Math.ceil(distance / this.distance_per_power);
} else { } else {
return 0; return 0;
@ -83,19 +83,16 @@ module TK.SpaceTac {
} }
getRangeRadius(ship: Ship): number { getRangeRadius(ship: Ship): number {
return this.getRangeRadiusForPower(ship); return ship.getValue("power") * this.distance_per_power * ship.grid.getUnit();
}
/**
* Get the distance reachable with a given power
*/
getRangeRadiusForPower(ship: Ship, power = ship.getValue("power")): number {
return power * this.distance_per_power;
} }
checkLocationTarget(ship: Ship, target: Target): boolean { checkLocationTarget(ship: Ship, target: Target): boolean {
// TODO Check it's on the grid if (!ship.grid.check(target)) {
return false;
}
// TODO Check the space is not occupied // TODO Check the space is not occupied
return true; return true;
} }

View file

@ -12,7 +12,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 60, distance_per_power: 1,
}); });
engine.configureCooldown(1, 1); engine.configureCooldown(1, 1);

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 460, distance_per_power: 9,
}); });
engine.configureCooldown(2, 1); engine.configureCooldown(2, 1);

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 120, distance_per_power: 3,
}); });
let laser = new TriggerAction("Wingspan Laser", { let laser = new TriggerAction("Wingspan Laser", {

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 240, distance_per_power: 5,
}); });
let gatling = new TriggerAction("Gatling Gun", { let gatling = new TriggerAction("Gatling Gun", {

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 130, distance_per_power: 3,
}); });
let missile = new TriggerAction("SubMunition Missile", { let missile = new TriggerAction("SubMunition Missile", {

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Main Engine", { let engine = new MoveAction("Main Engine", {
distance_per_power: 420, distance_per_power: 8,
}); });
let depleter = new TriggerAction("Power Depleter", { let depleter = new TriggerAction("Power Depleter", {

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 310, distance_per_power: 6,
}); });
let missile = new TriggerAction("SubMunition Missile", { let missile = new TriggerAction("SubMunition Missile", {

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 120, distance_per_power: 2,
}); });
let gatling = new TriggerAction("Gatling Gun", { let gatling = new TriggerAction("Gatling Gun", {

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 120, distance_per_power: 2,
}); });
let gatling1 = new TriggerAction("Primary Gatling", { let gatling1 = new TriggerAction("Primary Gatling", {

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 220, distance_per_power: 3,
}); });
engine.configureCooldown(1, 1); engine.configureCooldown(1, 1);

View file

@ -13,7 +13,7 @@ module TK.SpaceTac {
getLevelUpgrades(level: number): ShipUpgrade[] { getLevelUpgrades(level: number): ShipUpgrade[] {
if (level == 1) { if (level == 1) {
let engine = new MoveAction("Engine", { let engine = new MoveAction("Engine", {
distance_per_power: 280, distance_per_power: 5,
}); });
let laser = new TriggerAction("Prokhorov Laser", { let laser = new TriggerAction("Prokhorov Laser", {
@ -29,7 +29,7 @@ module TK.SpaceTac {
hull.configureCooldown(1, 4); hull.configureCooldown(1, 4);
let disengage = new MoveAction("Disengage", { let disengage = new MoveAction("Disengage", {
distance_per_power: 1000, distance_per_power: 20,
}, "ionthruster"); }, "ionthruster");
disengage.configureCooldown(1, 3); disengage.configureCooldown(1, 3);