diff --git a/src/scripts/game/Ship.ts b/src/scripts/game/Ship.ts index b0725e9..6692f3b 100644 --- a/src/scripts/game/Ship.ts +++ b/src/scripts/game/Ship.ts @@ -29,16 +29,31 @@ module SpaceTac.Game { // Last initiative throw initative_throw: number; + // Current number of action points + ap_current: number; + + // Maximal number of action points + ap_maximal: number; + + // Number of action points recovered by turn + ap_recover: number; + + // Number of action points used to make a 1.0 move + movement_cost: number; + // Create a new ship inside a fleet constructor(fleet: Fleet, name: string) { this.fleet = fleet; this.name = name; this.initiative_level = 1; - fleet.addShip(this); + if (fleet) { + fleet.addShip(this); + } } // Set position in the arena + // This does not consumes action points setArenaPosition(x: number, y: number) { this.arena_x = x; this.arena_y = y; @@ -63,5 +78,40 @@ module SpaceTac.Game { getPlayer(): Player { return this.fleet.player; } + + // Consumes action points + useActionPoints(ap: number): void { + this.ap_current -= ap; + + if (this.ap_current <= 0.001) { + this.ap_current = 0; + } + } + + // Get the maximal position reachable in the arena with current action points + getLongestMove(x: number, y: number): number[] { + var dx = x - this.arena_x; + var dy = y - this.arena_y; + var length = Math.sqrt(dx * dx + dy * dy); + var max_length = this.ap_current / this.movement_cost; + if (max_length >= length) { + return [x, y]; + } else { + var factor = max_length / length; + return [this.arena_x + dx * factor, this.arena_y + dy * factor]; + } + } + + // Move toward a location, consuming action points + moveTo(x: number, y: number): void { + var dest = this.getLongestMove(x, y); + var dx = dest[0] - this.arena_x; + var dy = dest[1] - this.arena_y; + var distance = Math.sqrt(dx * dx + dy * dy); + var cost = distance * this.movement_cost; + + this.setArenaPosition(this.arena_x + dx, this.arena_y + dy); + this.useActionPoints(cost); + } } } \ No newline at end of file diff --git a/src/scripts/specs/Ship.spec.ts b/src/scripts/specs/Ship.spec.ts new file mode 100644 index 0000000..3662fa8 --- /dev/null +++ b/src/scripts/specs/Ship.spec.ts @@ -0,0 +1,36 @@ +/// + +module SpaceTac.Specs { + describe("Ship", function(){ + it("limits movement range by action points", function(){ + var ship = new Game.Ship(null, "Test"); + ship.ap_current = 8; + ship.movement_cost = 3; + ship.setArenaPosition(50, 50); + + var point = ship.getLongestMove(51, 52); + expect(point).toEqual([51, 52]); + + var point = ship.getLongestMove(60, 55); + expect(point[0]).toBeCloseTo(52.385139, 0.0001); + expect(point[1]).toBeCloseTo(51.19256, 0.0001); + }); + + it("moves and consumes action points", function(){ + var ship = new Game.Ship(null, "Test"); + ship.ap_current = 8; + ship.movement_cost = 3; + ship.setArenaPosition(50, 50); + + ship.moveTo(51, 50); + expect(ship.ap_current).toEqual(5); + expect(ship.arena_x).toEqual(51); + expect(ship.arena_y).toEqual(50); + + ship.moveTo(53, 50); + expect(ship.ap_current).toBe(0); + expect(ship.arena_x).toBeCloseTo(52.333333, 0.00001); + expect(ship.arena_y).toEqual(50); + }); + }); +} \ No newline at end of file