1
0
Fork 0
spacetac/src/scripts/game/Battle.ts

150 lines
5.5 KiB
TypeScript
Raw Normal View History

2014-12-29 00:00:00 +00:00
module SpaceTac.Game {
2015-01-07 00:00:00 +00:00
"use strict";
2014-12-29 00:00:00 +00:00
// A turn-based battle between fleets
export class Battle {
2014-12-31 00:00:00 +00:00
// Log of all battle events
log: BattleLog;
2014-12-29 00:00:00 +00:00
// List of fleets engaged in battle
fleets: Fleet[];
// List of ships, sorted by their initiative throw
play_order: Ship[];
// Current ship whose turn it is to play
playing_ship_index: number;
playing_ship: Ship;
// Boolean indicating if its the first turn
first_turn: boolean;
2014-12-29 00:00:00 +00:00
// Create a battle between two fleets
constructor(fleet1: Fleet = null, fleet2: Fleet = null) {
2014-12-31 00:00:00 +00:00
this.log = new BattleLog();
this.fleets = [fleet1 || new Fleet(), fleet2 || new Fleet()];
this.play_order = [];
this.playing_ship_index = null;
this.playing_ship = null;
this.first_turn = true;
this.fleets.forEach((fleet: Fleet) => {
fleet.setBattle(this);
});
}
2015-01-07 00:00:00 +00:00
// Create a quick random battle, for testing purposes
static newQuickRandom(): Battle {
var player1 = Player.newQuickRandom("John");
var player2 = Player.newQuickRandom("Carl");
var result = new Battle(player1.fleet, player2.fleet);
result.start();
return result;
}
// Create play order, performing an initiative throw
throwInitiative(gen: RandomGenerator = new RandomGenerator()): void {
var play_order: Ship[] = [];
// Throw each ship's initiative
2015-01-07 00:00:00 +00:00
this.fleets.forEach(function (fleet: Fleet) {
fleet.ships.forEach(function (ship: Ship) {
ship.throwInitiative(gen);
play_order.push(ship);
});
});
// Sort by throw result
play_order.sort(function (ship1: Ship, ship2: Ship) {
return (ship2.initiative.current - ship1.initiative.current);
});
this.play_order = play_order;
2014-12-29 00:00:00 +00:00
}
// Defines the initial ship positions of all engaged fleets
placeShips(): void {
this.first_turn = true;
2015-02-03 00:00:00 +00:00
this.placeFleetShips(this.fleets[0], 50, 300, 0);
this.placeFleetShips(this.fleets[1], 800, 300, Math.PI);
}
// End the current ship turn, passing control to the next one in play order
// If at the end of the play order, next turn will start automatically
// Member 'play_order' must be defined before calling this function
2015-01-07 00:00:00 +00:00
advanceToNextShip(log: boolean = true): void {
2014-12-31 00:00:00 +00:00
var previous_ship = this.playing_ship;
2015-01-07 00:00:00 +00:00
if (this.play_order.length === 0) {
this.playing_ship_index = null;
this.playing_ship = null;
} else {
if (this.playing_ship_index == null) {
this.playing_ship_index = 0;
} else {
this.playing_ship_index += 1;
}
if (this.playing_ship_index >= this.play_order.length) {
this.playing_ship_index = 0;
this.first_turn = false;
}
this.playing_ship = this.play_order[this.playing_ship_index];
}
2014-12-31 00:00:00 +00:00
if (this.playing_ship) {
this.playing_ship.startTurn(this.first_turn);
}
2014-12-31 00:00:00 +00:00
if (log) {
this.log.add(new ShipChangeEvent(previous_ship, this.playing_ship));
2014-12-31 00:00:00 +00:00
}
}
// Start the battle
// This will call all necessary initialization steps (initiative, placement...)
2014-12-31 00:00:00 +00:00
// This will not add any event to the battle log
start(): void {
this.placeShips();
this.throwInitiative();
this.play_order.forEach((ship: Ship) => {
ship.updateAttributes();
ship.restoreHealth();
});
2014-12-31 00:00:00 +00:00
this.advanceToNextShip(false);
}
// Force an injection of events in the battle log to simulate the initial state
// For instance, this may be called after 'start', to use the log subscription system
// to initialize a battle UI
2014-12-31 00:00:00 +00:00
// Attributes 'play_order' and 'playing_ship' should be defined before calling this
2014-12-31 00:00:00 +00:00
injectInitialEvents(): void {
2014-12-31 00:00:00 +00:00
var log = this.log;
// Simulate initial ship placement
2015-01-07 00:00:00 +00:00
this.play_order.forEach((ship: Ship) => {
log.add(new MoveEvent(ship, ship.arena_x, ship.arena_y));
2014-12-31 00:00:00 +00:00
});
2014-12-31 00:00:00 +00:00
// Simulate game turn
log.add(new ShipChangeEvent(this.playing_ship, this.playing_ship));
}
2015-01-07 00:00:00 +00:00
// Defines the initial ship positions for one fleet
// x and y are the center of the fleet placement
// facing_angle is the forward angle in radians
private placeFleetShips(fleet: Fleet, x: number, y: number, facing_angle: number): void {
var side_angle = facing_angle + Math.PI * 0.5;
2015-02-03 00:00:00 +00:00
var spacing = 150;
2015-01-07 00:00:00 +00:00
var total_length = spacing * (fleet.ships.length - 1);
var dx = Math.cos(side_angle);
var dy = Math.sin(side_angle);
x -= dx * total_length * 0.5;
y -= dy * total_length * 0.5;
for (var i = 0; i < fleet.ships.length; i++) {
fleet.ships[i].setArenaPosition(x + i * dx * spacing, y + i * dy * spacing);
fleet.ships[i].setArenaFacingAngle(facing_angle);
}
2014-12-29 00:00:00 +00:00
}
}
2015-01-07 00:00:00 +00:00
}