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
* 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)
* In the ship tooltip, show power cost, toggled and overheat states
* Display shield (and its (dis)appearance)

View file

@ -5,6 +5,18 @@ module TK.SpaceTac.Specs {
}
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 => {
let grid = new HexagonalArenaGrid(4, 0.75);
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
*
* 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 {
snap(loc: IArenaLocation): IArenaLocation;
export class ArenaGrid {
/**
* 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 {
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
*/
export class HexagonalArenaGrid implements IArenaGrid {
private yunit: number;
export class HexagonalArenaGrid extends PixelGrid {
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;
}

View file

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

View file

@ -115,8 +115,6 @@ module TK.SpaceTac.Specs {
battle.fleets[0].addShip(ship);
let ship1 = battle.fleets[0].addShip();
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(400, 200), 100), ApproachSimulationError.NO_MOVE_NEEDED);

View file

@ -50,7 +50,7 @@ module TK.SpaceTac {
// Playing ship
private ship: Ship,
// 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 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
*/

View file

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

View file

@ -75,7 +75,7 @@ module TK.SpaceTac {
if (this.distance_per_power == 0) {
return Infinity;
} 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);
} else {
return 0;
@ -83,19 +83,16 @@ module TK.SpaceTac {
}
getRangeRadius(ship: Ship): number {
return this.getRangeRadiusForPower(ship);
}
/**
* Get the distance reachable with a given power
*/
getRangeRadiusForPower(ship: Ship, power = ship.getValue("power")): number {
return power * this.distance_per_power;
return ship.getValue("power") * this.distance_per_power * ship.grid.getUnit();
}
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
return true;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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