From d3e12fa8e1230d4e3d4f65f4bcf8b9e5dc2c73b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Thu, 9 Mar 2017 18:11:00 +0100 Subject: [PATCH] typescript: Added strict null checks --- TODO | 1 - bower.json | 2 +- package.json | 6 +-- src/common | 2 +- src/core/Battle.spec.ts | 16 +++---- src/core/Battle.ts | 24 ++++++----- src/core/BattleLog.spec.ts | 31 +++++++------ src/core/BattleOutcome.ts | 12 +++--- src/core/Equipment.ts | 6 +-- src/core/Fleet.ts | 10 ++--- src/core/FleetGenerator.ts | 4 +- src/core/GameSession.spec.ts | 2 +- src/core/GameSession.ts | 2 +- src/core/LootGenerator.spec.ts | 13 +++--- src/core/LootGenerator.ts | 14 +++--- src/core/LootTemplate.spec.ts | 2 +- src/core/LootTemplate.ts | 19 ++++---- src/core/MoveFireSimulator.spec.ts | 13 +++--- src/core/NameGenerator.ts | 2 +- src/core/Player.ts | 4 +- src/core/Range.ts | 4 +- src/core/Ship.ts | 26 ++++------- src/core/ShipGenerator.ts | 11 ++--- src/core/ShipModel.ts | 2 +- src/core/Slot.ts | 9 ++-- src/core/Star.ts | 2 +- src/core/StarLink.ts | 2 +- src/core/StarLocation.spec.ts | 8 ++-- src/core/StarLocation.ts | 14 +++--- src/core/Universe.spec.ts | 8 ++-- src/core/Universe.ts | 9 ++-- src/core/actions/BaseAction.ts | 18 ++++---- src/core/actions/DeployDroneAction.ts | 2 + src/core/actions/FireWeaponAction.ts | 18 +++++--- src/core/actions/MoveAction.spec.ts | 9 ++-- src/core/actions/MoveAction.ts | 5 ++- src/core/ai/AIDuel.ts | 31 +++++++------ src/core/ai/AbstractAI.ts | 9 ++-- src/core/ai/BullyAI.spec.ts | 36 +++++++++++----- src/core/ai/BullyAI.ts | 43 ++++++++++++------- src/core/ai/TacticalAI.spec.ts | 2 +- src/core/ai/TacticalAI.ts | 13 ++++-- src/core/ai/TacticalAIHelpers.ts | 2 +- src/core/equipments/AbstractDrone.ts | 6 +-- src/core/equipments/AbstractWeapon.ts | 6 +-- src/core/events/BaseLogEvent.ts | 24 +++++++++-- src/core/events/DamageEvent.ts | 2 +- src/core/events/DeathEvent.ts | 2 +- src/core/events/DroneAppliedEvent.ts | 2 +- src/core/events/DroneDeployedEvent.ts | 2 +- src/core/events/DroneDestroyedEvent.ts | 2 +- src/core/events/EffectAddedEvent.ts | 2 +- src/core/events/EffectDurationChangedEvent.ts | 2 +- src/core/events/EffectRemovedEvent.ts | 2 +- src/core/events/FireEvent.ts | 2 +- src/core/events/MoveEvent.ts | 2 +- src/core/events/ShipChangeEvent.ts | 2 +- src/core/events/ValueChangeEvent.ts | 2 +- src/ui/TestGame.ts | 13 +++--- src/ui/battle/ActionBar.ts | 4 +- src/ui/battle/ActionIcon.ts | 35 +++++++++------ src/ui/battle/ActionTooltip.spec.ts | 11 ++--- src/ui/battle/ActionTooltip.ts | 2 +- src/ui/battle/Arena.ts | 42 ++++++++++-------- src/ui/battle/ArenaShip.spec.ts | 4 +- src/ui/battle/BattleView.spec.ts | 24 +++++------ src/ui/battle/BattleView.ts | 32 ++++---------- src/ui/battle/LogProcessor.ts | 15 ++++--- src/ui/battle/RangeHint.ts | 2 +- src/ui/battle/ShipList.ts | 29 ++++++++----- src/ui/battle/Targetting.ts | 23 ++++++---- src/ui/common/Audio.ts | 2 +- src/ui/common/InputManager.ts | 6 +-- src/ui/map/FleetDisplay.spec.ts | 14 +++--- src/ui/map/FleetDisplay.ts | 8 ++-- src/ui/map/UniverseMapView.ts | 24 ++++++----- tsconfig.json | 2 +- typings.json | 4 +- 78 files changed, 461 insertions(+), 363 deletions(-) diff --git a/TODO b/TODO index 5dabd26..434faf4 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,3 @@ -* Enable strict null checking in typescript * Ensure that tweens and particle emitters get destroyed once animation is done (or view changes) * Highlight ships that will be included as target of current action * Controls: Do not focus on ship while targetting for area effects (dissociate hover and target) diff --git a/bower.json b/bower.json index 1cf7847..51725a6 100644 --- a/bower.json +++ b/bower.json @@ -9,7 +9,7 @@ "homepage": "", "private": true, "dependencies": { - "phaser": "2.6.2", + "phaser-ce": "2.7.3", "jasmine-core": "jasmine#^2.5.2", "deep-diff": "0.3.0" } diff --git a/package.json b/package.json index f11ce9d..a30a6a8 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,13 @@ "bower": "~1.8", "codecov": "~1.0", "jasmine": "~2.5", - "karma": "~1.4", + "karma": "~1.5", "karma-coverage": "~1.1", "karma-jasmine": "~1.1", "karma-phantomjs-launcher": "~1.0", - "remap-istanbul": "~0.8", + "remap-istanbul": "~0.9", "live-server": "~1.2", "typescript": "~2.2", - "typings": "~1.4" + "typings": "~2.1" } } \ No newline at end of file diff --git a/src/common b/src/common index db61f92..79e3c64 160000 --- a/src/common +++ b/src/common @@ -1 +1 @@ -Subproject commit db61f921e8afa9beca31bf1de1d30870f48a17e4 +Subproject commit 79e3c649cf7a411d06af7372aa825518e0d8df30 diff --git a/src/core/Battle.spec.ts b/src/core/Battle.spec.ts index 2e50b63..3cc438d 100644 --- a/src/core/Battle.spec.ts +++ b/src/core/Battle.spec.ts @@ -1,8 +1,8 @@ module TS.SpaceTac { describe("Battle", function () { it("defines play order by initiative throws", function () { - var fleet1 = new Fleet(null); - var fleet2 = new Fleet(null); + var fleet1 = new Fleet(); + var fleet2 = new Fleet(); var ship1 = new Ship(fleet1, "F1S1"); ship1.setAttribute("initiative", 2); @@ -26,8 +26,8 @@ module TS.SpaceTac { }); it("places ships on lines, facing the arena center", function () { - var fleet1 = new Fleet(null); - var fleet2 = new Fleet(null); + var fleet1 = new Fleet(); + var fleet2 = new Fleet(); var ship1 = new Ship(fleet1, "F1S1"); var ship2 = new Ship(fleet1, "F1S2"); @@ -60,8 +60,8 @@ module TS.SpaceTac { }); it("advances to next ship in play order", function () { - var fleet1 = new Fleet(null); - var fleet2 = new Fleet(null); + var fleet1 = new Fleet(); + var fleet2 = new Fleet(); var ship1 = new Ship(fleet1, "F1S1"); var ship2 = new Ship(fleet1, "F1S2"); @@ -113,8 +113,8 @@ module TS.SpaceTac { }); it("calls startTurn on ships", function () { - var fleet1 = new Fleet(null); - var fleet2 = new Fleet(null); + var fleet1 = new Fleet(); + var fleet2 = new Fleet(); var ship1 = new Ship(fleet1, "F1S1"); var ship2 = new Ship(fleet1, "F1S2"); diff --git a/src/core/Battle.ts b/src/core/Battle.ts index bee2c88..b36a69d 100644 --- a/src/core/Battle.ts +++ b/src/core/Battle.ts @@ -20,8 +20,8 @@ module TS.SpaceTac { turn: number; // Current ship whose turn it is to play - playing_ship_index: number; - playing_ship: Ship; + playing_ship_index: number | null; + playing_ship: Ship | null; // List of deployed drones drones: Drone[] = []; @@ -34,9 +34,9 @@ module TS.SpaceTac { timer = Timer.global; // Create a battle between two fleets - constructor(fleet1: Fleet = null, fleet2: Fleet = null, width = 1780, height = 948) { + constructor(fleet1 = new Fleet(), fleet2 = new Fleet(), width = 1780, height = 948) { this.log = new BattleLog(); - this.fleets = [fleet1 || new Fleet(), fleet2 || new Fleet()]; + this.fleets = [fleet1, fleet2]; this.play_order = []; this.playing_ship_index = null; this.playing_ship = null; @@ -129,7 +129,7 @@ module TS.SpaceTac { } // Ends a battle and sets the outcome - endBattle(winner: Fleet, log: boolean = true) { + endBattle(winner: Fleet | null, log: boolean = true) { this.ended = true; this.outcome = new BattleOutcome(winner); if (winner) { @@ -153,7 +153,7 @@ module TS.SpaceTac { this.endBattle(null, log); } else if (alive_fleets === 1) { // We have a winner - var winner: Fleet = null; + var winner: Fleet | null = null; this.fleets.forEach((fleet: Fleet) => { if (fleet.isAlive()) { winner = fleet; @@ -198,7 +198,7 @@ module TS.SpaceTac { this.playing_ship.startTurn(); } - if (log) { + if (log && previous_ship && this.playing_ship) { this.log.add(new ShipChangeEvent(previous_ship, this.playing_ship)); } } @@ -207,11 +207,13 @@ module TS.SpaceTac { * Make an AI play the current ship */ playAI(ai: AbstractAI | null = null) { - if (!ai) { - // TODO Use an AI adapted to the fleet - ai = new BullyAI(this.playing_ship, this.timer); + if (this.playing_ship) { + if (!ai) { + // TODO Use an AI adapted to the fleet + ai = new BullyAI(this.playing_ship, this.timer); + } + ai.play(); } - ai.play(); } // Start the battle diff --git a/src/core/BattleLog.spec.ts b/src/core/BattleLog.spec.ts index 56cc1c0..9802002 100644 --- a/src/core/BattleLog.spec.ts +++ b/src/core/BattleLog.spec.ts @@ -3,7 +3,7 @@ module TS.SpaceTac { // Check a single game log event function checkEvent(got: BaseLogEvent, ship: Ship, code: string, - target_ship: Ship = null, target_x: number = null, target_y: number = null): void { + target_ship: Ship | null = null, target_x: number | null = null, target_y: number | null = null): void { if (target_ship) { if (target_x === null) { target_x = target_ship.arena_x; @@ -15,23 +15,27 @@ module TS.SpaceTac { expect(got.ship).toBe(ship); expect(got.code).toEqual(code); - expect(got.target.ship).toBe(target_ship); - if (target_x === null) { - expect(got.target.x).toBeNull(); + if (got.target) { + expect(got.target.ship).toBe(target_ship); + if (target_x === null) { + expect(got.target.x).toBeNull(); + } else { + expect(got.target.x).toBeCloseTo(target_x, 0.000001); + } + if (target_y === null) { + expect(got.target.y).toBeNull(); + } else { + expect(got.target.y).toBeCloseTo(target_y, 0.000001); + } } else { - expect(got.target.x).toBeCloseTo(target_x, 0.000001); - } - if (target_y === null) { - expect(got.target.y).toBeNull(); - } else { - expect(got.target.y).toBeCloseTo(target_y, 0.000001); + fail("Got no target"); } } // Fake event class FakeEvent extends BaseLogEvent { constructor() { - super("fake"); + super("fake", new Ship()); } } @@ -68,7 +72,8 @@ module TS.SpaceTac { }); it("can receive simulated initial state events", function () { - var battle = Battle.newQuickRandom(); + let battle = Battle.newQuickRandom(); + let playing = nn(battle.playing_ship); battle.log.clear(); battle.log.addFilter("value"); expect(battle.log.events.length).toBe(0); @@ -80,7 +85,7 @@ module TS.SpaceTac { checkEvent(battle.log.events[i], battle.play_order[i], "move", null, battle.play_order[i].arena_x, battle.play_order[i].arena_y); } - checkEvent(battle.log.events[8], battle.playing_ship, "ship_change", battle.playing_ship); + checkEvent(battle.log.events[8], playing, "ship_change", playing); }); }); } diff --git a/src/core/BattleOutcome.ts b/src/core/BattleOutcome.ts index 7749f23..2b7c67c 100644 --- a/src/core/BattleOutcome.ts +++ b/src/core/BattleOutcome.ts @@ -5,12 +5,12 @@ module TS.SpaceTac { draw: boolean; // Victorious fleet - winner: Fleet; + winner: Fleet | null; // Retrievable loot loot: Equipment[]; - constructor(winner: Fleet) { + constructor(winner: Fleet | null) { this.winner = winner; this.draw = winner ? false : true; this.loot = []; @@ -27,8 +27,10 @@ module TS.SpaceTac { var count = random.randInt(0, ship.getEquipmentCount()); while (count > 0) { var salvaged = ship.getRandomEquipment(random); - salvaged.detach(); - this.loot.push(salvaged); + if (salvaged) { + salvaged.detach(); + this.loot.push(salvaged); + } count--; } @@ -61,7 +63,7 @@ module TS.SpaceTac { // Generate a special loot item for the winner fleet // The equipment will be in the dead ship range - generateLootItem(random: RandomGenerator, base_level: number): Equipment { + generateLootItem(random: RandomGenerator, base_level: number): Equipment | null { var generator = this.getLootGenerator(random); var level = new IntegerRange(base_level - 1, base_level + 1); return generator.generate(level); diff --git a/src/core/Equipment.ts b/src/core/Equipment.ts index 4e95839..9844862 100644 --- a/src/core/Equipment.ts +++ b/src/core/Equipment.ts @@ -2,10 +2,10 @@ module TS.SpaceTac { // Piece of equipment to attach in slots export class Equipment { // Actual slot this equipment is attached to - attached_to: Slot; + attached_to: Slot | null = null; // Type of slot this equipment can fit in - slot: SlotType; + slot: SlotType | null; // Identifiable equipment code (may be used by UI to customize visual effects) code: string; @@ -41,7 +41,7 @@ module TS.SpaceTac { target_effects: BaseEffect[]; // Basic constructor - constructor(slot: SlotType = null, code: string = null) { + constructor(slot: SlotType | null = null, code = "equiment") { this.slot = slot; this.code = code; this.name = code; diff --git a/src/core/Fleet.ts b/src/core/Fleet.ts index a342b18..fc8576c 100644 --- a/src/core/Fleet.ts +++ b/src/core/Fleet.ts @@ -10,17 +10,17 @@ module TS.SpaceTac { ships: Ship[]; // Current fleet location - location: StarLocation; + location: StarLocation | null; // Current battle in which the fleet is engaged (null if not fighting) - battle: Battle; + battle: Battle | null; // Amount of credits available credits = 0; // Create a fleet, bound to a player - constructor(player: Player = null) { - this.player = player || new Player(); + constructor(player = new Player()) { + this.player = player; this.ships = []; this.location = null; this.battle = null; @@ -59,7 +59,7 @@ module TS.SpaceTac { } // Set the current battle - setBattle(battle: Battle): void { + setBattle(battle: Battle | null): void { this.battle = battle; } diff --git a/src/core/FleetGenerator.ts b/src/core/FleetGenerator.ts index 512309d..aba98f5 100644 --- a/src/core/FleetGenerator.ts +++ b/src/core/FleetGenerator.ts @@ -4,12 +4,12 @@ module TS.SpaceTac { // Random generator to use random: RandomGenerator; - constructor(random: RandomGenerator = new RandomGenerator()) { + constructor(random = RandomGenerator.global) { this.random = random; } // Generate a fleet of a given level - generate(level: number, player: Player = null, ship_count: number = 3): Fleet { + generate(level: number, player?: Player, ship_count = 3): Fleet { var fleet = new Fleet(player); var ship_generator = new ShipGenerator(this.random); diff --git a/src/core/GameSession.spec.ts b/src/core/GameSession.spec.ts index 9327ac1..c8685d2 100644 --- a/src/core/GameSession.spec.ts +++ b/src/core/GameSession.spec.ts @@ -12,7 +12,7 @@ module TS.SpaceTac.Specs { * Apply deterministic game steps */ function applyGameSteps(session: GameSession): void { - var battle = session.getBattle(); + var battle = nn(session.getBattle()); battle.advanceToNextShip(); // TODO Make some fixed moves (AI?) battle.endBattle(battle.fleets[0]); diff --git a/src/core/GameSession.ts b/src/core/GameSession.ts index f619d14..c4cc242 100644 --- a/src/core/GameSession.ts +++ b/src/core/GameSession.ts @@ -48,7 +48,7 @@ module TS.SpaceTac { } // Get currently played battle, null when none is in progress - getBattle(): Battle { + getBattle(): Battle | null { return this.player.getBattle(); } diff --git a/src/core/LootGenerator.spec.ts b/src/core/LootGenerator.spec.ts index f5e55a6..a4827ce 100644 --- a/src/core/LootGenerator.spec.ts +++ b/src/core/LootGenerator.spec.ts @@ -17,11 +17,14 @@ module TS.SpaceTac.Specs { generator.random = new SkewedRandomGenerator([0.5]); var equipment = generator.generate(new IntegerRange(3, 6)); - - expect(equipment.slot).toBe(SlotType.Shield); - expect(equipment.name).toEqual("Hexagrid Shield"); - expect(equipment.min_level).toBe(5); - expect(equipment.ap_usage).toBeCloseTo(6.2727, 0.00001); + if (equipment) { + expect(equipment.slot).toBe(SlotType.Shield); + expect(equipment.name).toEqual("Hexagrid Shield"); + expect(equipment.min_level).toBe(5); + expect(equipment.ap_usage).toBeCloseTo(6.2727, 0.00001); + } else { + fail("No equipment generated"); + } }); }); } diff --git a/src/core/LootGenerator.ts b/src/core/LootGenerator.ts index d99fcba..307901b 100644 --- a/src/core/LootGenerator.ts +++ b/src/core/LootGenerator.ts @@ -35,22 +35,22 @@ module TS.SpaceTac { // If slot is specified, it will generate an equipment for this slot type specifically // If level is specified, it will generate an equipment with level requirement inside this range // If no equipment could be generated from available templates, null is returned - generate(level: IntegerRange = null, slot: SlotType = null): Equipment { + generate(level: IntegerRange | null = null, slot: SlotType | null = null): Equipment | null { // Generate equipments matching conditions, with each template var equipments: Equipment[] = []; this.templates.forEach((template: LootTemplate) => { - if (slot !== null && slot !== template.slot) { + if (slot && slot != template.slot) { return; } - var equipment: Equipment; - if (level === null) { - equipment = template.generate(this.random); - } else { + var equipment: Equipment | null; + if (level) { equipment = template.generateInLevelRange(level, this.random); + } else { + equipment = template.generate(this.random); } - if (equipment !== null) { + if (equipment) { equipments.push(equipment); } }); diff --git a/src/core/LootTemplate.spec.ts b/src/core/LootTemplate.spec.ts index b044a86..ef6e0cf 100644 --- a/src/core/LootTemplate.spec.ts +++ b/src/core/LootTemplate.spec.ts @@ -61,7 +61,7 @@ module TS.SpaceTac.Specs { var template = new LootTemplate(SlotType.Weapon, "Bulletator"); template.min_level = new IntegerRange(4, 7); - var result: Range; + var result: any; result = template.getPowerRangeForLevel(new IntegerRange(4, 7)); expect(result.min).toBe(0); diff --git a/src/core/LootTemplate.ts b/src/core/LootTemplate.ts index 7e34d5e..c46a6a4 100644 --- a/src/core/LootTemplate.ts +++ b/src/core/LootTemplate.ts @@ -46,7 +46,7 @@ module TS.SpaceTac { } // Set a capability requirement - addRequirement(capability: keyof ShipAttributes, min: number, max: number = null): void { + addRequirement(capability: keyof ShipAttributes, min: number, max: number | null = null): void { this.requirements[capability] = new IntegerRange(min, max); } @@ -70,7 +70,10 @@ module TS.SpaceTac { result.ap_usage = this.ap_usage.getProportional(power); result.min_level = this.min_level.getProportional(power); - result.action = this.getActionForEquipment(result); + let action = this.getActionForEquipment(result) + if (action) { + result.action = action; + } iteritems(this.requirements, (key: string, requirement: IntegerRange) => { if (requirement) { @@ -89,7 +92,7 @@ module TS.SpaceTac { } // Find the power range that will result in the level range - getPowerRangeForLevel(level: IntegerRange): Range { + getPowerRangeForLevel(level: IntegerRange): Range | null { if (level.min > this.min_level.max || level.max < this.min_level.min) { return null; } else { @@ -113,7 +116,7 @@ module TS.SpaceTac { // Generate an equipment that will have its level requirement in the given range // May return null if level range is not compatible with the template - generateInLevelRange(level: IntegerRange, random = RandomGenerator.global): Equipment { + generateInLevelRange(level: IntegerRange, random = RandomGenerator.global): Equipment | null { var random_range = this.getPowerRangeForLevel(level); if (random_range) { var power = random.random() * (random_range.max - random_range.min) + random_range.min; @@ -126,7 +129,7 @@ module TS.SpaceTac { /** * Convenience function to add a modulated effect to the equipment */ - addEffect(effect: BaseEffect, min_value: number, max_value: number = null, target = true) { + addEffect(effect: BaseEffect, min_value: number, max_value: number | null = null, target = true) { var template = new EffectTemplate(effect); template.addModifier("value", new IntegerRange(min_value, max_value)); if (target) { @@ -139,8 +142,8 @@ module TS.SpaceTac { /** * Convenience function to add a modulated sticky effect to the equipment */ - addStickyEffect(effect: BaseEffect, min_value: number, max_value: number = null, min_duration: number = 1, - max_duration: number = null, on_stick = false, on_turn_start = false, target = true): void { + addStickyEffect(effect: BaseEffect, min_value: number, max_value: number | null = null, min_duration: number = 1, + max_duration: number | null = null, on_stick = false, on_turn_start = false, target = true): void { var template = new EffectTemplate(new StickyEffect(effect, 0, on_stick, on_turn_start)); template.addModifier("value", new IntegerRange(min_value, max_value)); template.addModifier("duration", new IntegerRange(min_duration, max_duration)); @@ -177,7 +180,7 @@ module TS.SpaceTac { } // Method to reimplement to assign an action to a generated equipment - protected getActionForEquipment(equipment: Equipment): BaseAction { + protected getActionForEquipment(equipment: Equipment): BaseAction | null { return null; } } diff --git a/src/core/MoveFireSimulator.spec.ts b/src/core/MoveFireSimulator.spec.ts index e569656..03fdc4f 100644 --- a/src/core/MoveFireSimulator.spec.ts +++ b/src/core/MoveFireSimulator.spec.ts @@ -21,8 +21,9 @@ module TS.SpaceTac.Specs { let engine2 = TestTools.addEngine(ship, 120); let engine3 = TestTools.addEngine(ship, 150); let engine4 = TestTools.addEngine(ship, 70); - expect(simulator.findBestEngine()).toBe(engine3); - expect(simulator.findBestEngine().distance).toBe(150); + let best = simulator.findBestEngine(); + expect(best).toBe(engine3); + expect((best).distance).toBe(150); }); it("fires directly when in range", function () { @@ -36,7 +37,7 @@ module TS.SpaceTac.Specs { expect(result.total_fire_ap).toBe(3, 'total_fire_ap'); expect(result.parts).toEqual([ - { action: jasmine.objectContaining({ code: "fire-null" }), target: new Target(ship.arena_x + 5, ship.arena_y, null), ap: 3, possible: true } + { action: jasmine.objectContaining({ code: "fire-equiment" }), target: new Target(ship.arena_x + 5, ship.arena_y, null), ap: 3, possible: true } ]); }); @@ -50,7 +51,7 @@ module TS.SpaceTac.Specs { expect(result.total_fire_ap).toBe(3, 'total_fire_ap'); expect(result.parts).toEqual([ - { action: jasmine.objectContaining({ code: "fire-null" }), target: new Target(ship.arena_x + 5, ship.arena_y, null), ap: 3, possible: false } + { action: jasmine.objectContaining({ code: "fire-equiment" }), target: new Target(ship.arena_x + 5, ship.arena_y, null), ap: 3, possible: false } ]); }); @@ -68,7 +69,7 @@ module TS.SpaceTac.Specs { expect(result.parts).toEqual([ { action: jasmine.objectContaining({ code: "move" }), target: new Target(ship.arena_x + 5, ship.arena_y, null), ap: 1, possible: true }, - { action: jasmine.objectContaining({ code: "fire-null" }), target: new Target(ship.arena_x + 15, ship.arena_y, null), ap: 3, possible: true } + { action: jasmine.objectContaining({ code: "fire-equiment" }), target: new Target(ship.arena_x + 15, ship.arena_y, null), ap: 3, possible: true } ]); }); @@ -86,7 +87,7 @@ module TS.SpaceTac.Specs { expect(result.parts).toEqual([ { action: jasmine.objectContaining({ code: "move" }), target: new Target(ship.arena_x + 10, ship.arena_y, null), ap: 2, possible: true }, - { action: jasmine.objectContaining({ code: "fire-null" }), target: new Target(ship.arena_x + 18, ship.arena_y, null), ap: 2, possible: false } + { action: jasmine.objectContaining({ code: "fire-equiment" }), target: new Target(ship.arena_x + 18, ship.arena_y, null), ap: 2, possible: false } ]); }); diff --git a/src/core/NameGenerator.ts b/src/core/NameGenerator.ts index 791a55b..f2c6ba8 100644 --- a/src/core/NameGenerator.ts +++ b/src/core/NameGenerator.ts @@ -13,7 +13,7 @@ module TS.SpaceTac { } // Get a new unique name from available choices - getName(): string { + getName(): string | null { if (this.choices.length === 0) { return null; } diff --git a/src/core/Player.ts b/src/core/Player.ts index 2df48e3..306ad45 100644 --- a/src/core/Player.ts +++ b/src/core/Player.ts @@ -63,10 +63,10 @@ module TS.SpaceTac { } // Get currently played battle, null when none is in progress - getBattle(): Battle { + getBattle(): Battle | null { return this.fleet.battle; } - setBattle(battle: Battle): void { + setBattle(battle: Battle | null): void { this.fleet.setBattle(battle); } diff --git a/src/core/Range.ts b/src/core/Range.ts index 45f7b8b..839f888 100644 --- a/src/core/Range.ts +++ b/src/core/Range.ts @@ -8,12 +8,12 @@ module TS.SpaceTac { max: number; // Create a range of values - constructor(min: number, max: number = null) { + constructor(min: number, max: number | null = null) { this.set(min, max); } // Change the range - set(min: number, max: number = null) { + set(min: number, max: number | null = null) { this.min = min; if (max === null) { this.max = this.min; diff --git a/src/core/Ship.ts b/src/core/Ship.ts index 15b37ca..f7a75ae 100644 --- a/src/core/Ship.ts +++ b/src/core/Ship.ts @@ -95,7 +95,7 @@ module TS.SpaceTac { upgrade_points = 0; // Create a new ship inside a fleet - constructor(fleet: Fleet = null, name = "Ship") { + constructor(fleet: Fleet | null = null, name = "Ship") { this.fleet = fleet || new Fleet(); this.level = 1; this.name = name; @@ -146,20 +146,12 @@ module TS.SpaceTac { // Return the player owning this ship getPlayer(): Player { - if (this.fleet) { - return this.fleet.player; - } else { - return null; - } + return this.fleet.player; } // get the current battle this ship is engaged in - getBattle(): Battle { - if (this.fleet) { - return this.fleet.battle; - } else { - return null; - } + getBattle(): Battle | null { + return this.fleet.battle; } // Get the list of actions available @@ -257,7 +249,7 @@ module TS.SpaceTac { // Initialize the action points counter // This should be called once at the start of a battle // If no value is provided, the attribute ap_initial will be used - initializeActionPoints(value: number = null): void { + initializeActionPoints(value: number | null = null): void { if (value === null) { value = this.attributes.power_initial.get(); } @@ -267,7 +259,7 @@ module TS.SpaceTac { // Recover action points // This should be called once at the end of a turn // If no value is provided, the current attribute ap_recovery will be used - recoverActionPoints(value: number = null): void { + recoverActionPoints(value: number | null = null): void { if (this.alive) { if (value === null) { value = this.attributes.power_recovery.get(); @@ -510,7 +502,7 @@ module TS.SpaceTac { * List all equipments attached to slots of a given type (any slot type if null) */ listEquipment(slottype: SlotType | null = null): Equipment[] { - return this.slots.filter(slot => slot.attached && (slottype == null || slot.type == slottype)).map(slot => slot.attached); + return nna(this.slots.filter(slot => slot.attached && (slottype == null || slot.type == slottype)).map(slot => slot.attached)); } // Get the number of attached equipments @@ -525,13 +517,13 @@ module TS.SpaceTac { } // Get a random attached equipment, null if no equipment is attached - getRandomEquipment(random = RandomGenerator.global): Equipment { + getRandomEquipment(random = RandomGenerator.global): Equipment | null { var count = this.getEquipmentCount(); if (count === 0) { return null; } else { var picked = random.randInt(0, count - 1); - var result: Equipment = null; + var result: Equipment | null = null; var index = 0; this.slots.forEach((slot: Slot) => { if (slot.attached) { diff --git a/src/core/ShipGenerator.ts b/src/core/ShipGenerator.ts index e154a08..794650f 100644 --- a/src/core/ShipGenerator.ts +++ b/src/core/ShipGenerator.ts @@ -4,14 +4,13 @@ module TS.SpaceTac { // Random number generator used random: RandomGenerator; - // Create a default ship generator - constructor(random: RandomGenerator = null) { - this.random = random || new RandomGenerator(); + constructor(random = RandomGenerator.global) { + this.random = random; } // Generate a ship of a given level // The ship will not be named, nor will be a member of any fleet - generate(level: number, model: ShipModel = null): Ship { + generate(level: number, model: ShipModel | null = null): Ship { var result = new Ship(); var loot = new LootGenerator(this.random); @@ -30,7 +29,9 @@ module TS.SpaceTac { // Fill equipment slots result.slots.forEach((slot: Slot) => { var equipment = loot.generate(new IntegerRange(level, level), slot.type); - slot.attach(equipment); + if (equipment) { + slot.attach(equipment); + } }); return result; diff --git a/src/core/ShipModel.ts b/src/core/ShipModel.ts index 34d0fe0..8355076 100644 --- a/src/core/ShipModel.ts +++ b/src/core/ShipModel.ts @@ -24,7 +24,7 @@ module TS.SpaceTac { // Get the default ship model collection available in-game static getDefaultCollection(): ShipModel[] { // TODO Store in cache - var result = []; + var result: ShipModel[] = []; result.push(new ShipModel("scout", 1, 2, SlotType.Hull, SlotType.Power, SlotType.Power, SlotType.Engine, SlotType.Weapon)); diff --git a/src/core/Slot.ts b/src/core/Slot.ts index c62c705..6f6a7d6 100644 --- a/src/core/Slot.ts +++ b/src/core/Slot.ts @@ -17,7 +17,7 @@ module TS.SpaceTac { type: SlotType; // Currently attached equipment, null if none - attached: Equipment; + attached: Equipment | null; // Create an empty slot for a ship constructor(ship: Ship, type: SlotType) { @@ -27,7 +27,7 @@ module TS.SpaceTac { } // Attach an equipment in this slot - attach(equipment: Equipment): Equipment | null { + attach(equipment: Equipment): Equipment { if (this.type === equipment.slot && equipment.canBeEquipped(this.ship)) { this.attached = equipment; equipment.attached_to = this; @@ -35,11 +35,8 @@ module TS.SpaceTac { if (this.ship) { this.ship.updateAttributes(); } - - return equipment; - } else { - return null; } + return equipment; } } diff --git a/src/core/Star.ts b/src/core/Star.ts index bca6b3d..8ec8134 100644 --- a/src/core/Star.ts +++ b/src/core/Star.ts @@ -75,7 +75,7 @@ module TS.SpaceTac { // Base level for encounters in this system level: number; - constructor(universe: Universe = null, x = 0, y = 0, name = "") { + constructor(universe: Universe | null = null, x = 0, y = 0, name = "") { this.universe = universe || new Universe(); this.x = x; this.y = y; diff --git a/src/core/StarLink.ts b/src/core/StarLink.ts index 829a816..6ec53c8 100644 --- a/src/core/StarLink.ts +++ b/src/core/StarLink.ts @@ -36,7 +36,7 @@ module TS.SpaceTac { } // Get the other side of the link, for a given side - getPeer(star: Star): Star { + getPeer(star: Star): Star | null { if (star === this.first) { return this.second; } else if (star === this.second) { diff --git a/src/core/StarLocation.spec.ts b/src/core/StarLocation.spec.ts index a07b5e1..306588c 100644 --- a/src/core/StarLocation.spec.ts +++ b/src/core/StarLocation.spec.ts @@ -1,7 +1,7 @@ module TS.SpaceTac.Specs { describe("StarLocation", () => { it("removes generated encounters that lose", function () { - var location = new StarLocation(null, StarLocationType.PLANET, 0, 0); + var location = new StarLocation(undefined, StarLocationType.PLANET, 0, 0); var fleet = new Fleet(); var random = new SkewedRandomGenerator([0]); var battle = location.enterLocation(fleet, random); @@ -9,13 +9,13 @@ module TS.SpaceTac.Specs { expect(location.encounter).not.toBeNull(); expect(battle).not.toBeNull(); - battle.endBattle(fleet); + nn(battle).endBattle(fleet); expect(location.encounter).toBeNull(); }); it("leaves generated encounters that win", function () { - var location = new StarLocation(null, StarLocationType.PLANET, 0, 0); + var location = new StarLocation(undefined, StarLocationType.PLANET, 0, 0); var fleet = new Fleet(); var random = new SkewedRandomGenerator([0]); var battle = location.enterLocation(fleet, random); @@ -23,7 +23,7 @@ module TS.SpaceTac.Specs { expect(location.encounter).not.toBeNull(); expect(battle).not.toBeNull(); - battle.endBattle(location.encounter); + nn(battle).endBattle(location.encounter); expect(location.encounter).not.toBeNull(); }); diff --git a/src/core/StarLocation.ts b/src/core/StarLocation.ts index d85a280..31f8113 100644 --- a/src/core/StarLocation.ts +++ b/src/core/StarLocation.ts @@ -24,14 +24,14 @@ module TS.SpaceTac { universe_y: number; // Destination for jump, if its a WARP location - jump_dest: StarLocation; + jump_dest: StarLocation | null; // Enemy encounter - encounter: Fleet; + encounter: Fleet | null; encounter_gen: boolean; - constructor(star: Star, type: StarLocationType = StarLocationType.PLANET, x: number = 0, y: number = 0) { - this.star = star || new Star(); + constructor(star = new Star(), type: StarLocationType = StarLocationType.PLANET, x: number = 0, y: number = 0) { + this.star = star; this.type = type; this.x = x; this.y = y; @@ -52,14 +52,14 @@ module TS.SpaceTac { // Call this when first probing a location to generate the possible encounter // Returns the encountered fleet, null if no encounter happens - tryGenerateEncounter(random = RandomGenerator.global): Fleet { + tryGenerateEncounter(random = RandomGenerator.global): Fleet | null { if (!this.encounter_gen) { this.encounter_gen = true; if (random.random() < 0.8) { var fleet_generator = new FleetGenerator(random); var ship_count = random.randInt(1, 5); - this.encounter = fleet_generator.generate(this.star.level, null, ship_count); + this.encounter = fleet_generator.generate(this.star.level, undefined, ship_count); } } @@ -69,7 +69,7 @@ module TS.SpaceTac { // Call this when entering a location to generate the possible encounter // *fleet* is the player fleet, entering the location // Returns the engaged battle, null if no encounter happens - enterLocation(fleet: Fleet, random = RandomGenerator.global): Battle { + enterLocation(fleet: Fleet, random = RandomGenerator.global): Battle | null { var encounter = this.tryGenerateEncounter(random); if (encounter) { var battle = new Battle(fleet, encounter); diff --git a/src/core/Universe.spec.ts b/src/core/Universe.spec.ts index 892a9f1..e3cdbd3 100644 --- a/src/core/Universe.spec.ts +++ b/src/core/Universe.spec.ts @@ -60,17 +60,17 @@ module TS.SpaceTac.Specs { var warps = getWarps(universe.stars[0]); expect(warps.length).toBe(2); - expect(warps[0].jump_dest.star).toBe(universe.stars[1]); - expect(warps[1].jump_dest.star).toBe(universe.stars[2]); + expect(nn(warps[0].jump_dest).star).toBe(universe.stars[1]); + expect(nn(warps[1].jump_dest).star).toBe(universe.stars[2]); expect(universe.stars[0].getWarpLocationTo(universe.stars[1])).toBe(warps[0]); expect(universe.stars[0].getWarpLocationTo(universe.stars[2])).toBe(warps[1]); warps = getWarps(universe.stars[1]); expect(warps.length).toBe(1); - expect(warps[0].jump_dest.star).toBe(universe.stars[0]); + expect(nn(warps[0].jump_dest).star).toBe(universe.stars[0]); expect(universe.stars[1].getWarpLocationTo(universe.stars[2])).toBeNull(); warps = getWarps(universe.stars[2]); expect(warps.length).toBe(1); - expect(warps[0].jump_dest.star).toBe(universe.stars[0]); + expect(nn(warps[0].jump_dest).star).toBe(universe.stars[0]); }); }); } diff --git a/src/core/Universe.ts b/src/core/Universe.ts index b9a00e2..93c5140 100644 --- a/src/core/Universe.ts +++ b/src/core/Universe.ts @@ -46,7 +46,7 @@ module TS.SpaceTac { continue; } - star.name = names.getName(); + star.name = names.getName() || "Star"; result.push(star); count--; @@ -104,15 +104,12 @@ module TS.SpaceTac { } // Get the star nearest to another - getNearestTo(star: Star, others: Star[] = null): Star { - if (others === null) { - others = this.stars; - } + getNearestTo(star: Star, others = this.stars): Star | null { if (others.length === 0) { return null; } else { var mindist = this.radius * 2.0; - var nearest: Star = null; + var nearest: Star | null = null; others.forEach((istar: Star) => { if (istar !== star) { var dist = star.getDistanceTo(istar); diff --git a/src/core/actions/BaseAction.ts b/src/core/actions/BaseAction.ts index 7547e9b..66a26ea 100644 --- a/src/core/actions/BaseAction.ts +++ b/src/core/actions/BaseAction.ts @@ -11,10 +11,10 @@ module TS.SpaceTac { needs_target: boolean; // Equipment that triggers this action - equipment: Equipment; + equipment: Equipment | null; // Create the action - constructor(code: string, name: string, needs_target: boolean, equipment: Equipment = null) { + constructor(code: string, name: string, needs_target: boolean, equipment: Equipment | null = null) { this.code = code; this.name = name; this.needs_target = needs_target; @@ -28,7 +28,7 @@ module TS.SpaceTac { * * Returns an informative message indicating why the action cannot be used, null otherwise */ - checkCannotBeApplied(ship: Ship, remaining_ap: number = null): string | null { + checkCannotBeApplied(ship: Ship, remaining_ap: number | null = null): string | null { let battle = ship.getBattle(); if (battle && battle.playing_ship !== ship) { // Ship is not playing @@ -48,7 +48,7 @@ module TS.SpaceTac { } // Get the number of action points the action applied to a target would use - getActionPointsUsage(ship: Ship, target: Target): number { + getActionPointsUsage(ship: Ship, target: Target | null): number { if (this.equipment) { return this.equipment.ap_usage; } else { @@ -76,7 +76,7 @@ module TS.SpaceTac { // Method to check if a target is applicable for this action // Will call checkLocationTarget or checkShipTarget by default - checkTarget(ship: Ship, target: Target): Target { + checkTarget(ship: Ship, target: Target | null): Target | null { if (this.checkCannotBeApplied(ship)) { return null; } else if (target) { @@ -92,18 +92,18 @@ module TS.SpaceTac { // Method to reimplement to check if a space target is applicable // Must return null if the target can't be applied, an altered target, or the original target - checkLocationTarget(ship: Ship, target: Target): Target { + checkLocationTarget(ship: Ship, target: Target): Target | null { return null; } // Method to reimplement to check if a ship target is applicable // Must return null if the target can't be applied, an altered target, or the original target - checkShipTarget(ship: Ship, target: Target): Target { + checkShipTarget(ship: Ship, target: Target): Target | null { return null; } // Apply an action, returning true if it was successful - apply(ship: Ship, target: Target): boolean { + apply(ship: Ship, target: Target | null): boolean { let reject = this.checkCannotBeApplied(ship); if (reject == null) { let checked_target = this.checkTarget(ship, target); @@ -127,7 +127,7 @@ module TS.SpaceTac { } // Method to reimplement to apply a action - protected customApply(ship: Ship, target: Target) { + protected customApply(ship: Ship, target: Target | null) { } } } diff --git a/src/core/actions/DeployDroneAction.ts b/src/core/actions/DeployDroneAction.ts index e403531..7782975 100644 --- a/src/core/actions/DeployDroneAction.ts +++ b/src/core/actions/DeployDroneAction.ts @@ -5,6 +5,8 @@ module TS.SpaceTac { * Action to deploy a drone in space */ export class DeployDroneAction extends BaseAction { + equipment: Equipment; + constructor(equipment: Equipment) { super("deploy-" + equipment.code, "Deploy", true, equipment); } diff --git a/src/core/actions/FireWeaponAction.ts b/src/core/actions/FireWeaponAction.ts index 6176044..bf9aa3e 100644 --- a/src/core/actions/FireWeaponAction.ts +++ b/src/core/actions/FireWeaponAction.ts @@ -6,14 +6,17 @@ module TS.SpaceTac { // Boolean set to true if the weapon can target space can_target_space: boolean; + // Equipment cannot be null + equipment: Equipment; + constructor(equipment: Equipment, can_target_space = false, name = "Fire") { super("fire-" + equipment.code, name, true, equipment); this.can_target_space = can_target_space; } - checkLocationTarget(ship: Ship, target: Target): Target { - if (this.can_target_space) { + checkLocationTarget(ship: Ship, target: Target): Target | null { + if (target && this.can_target_space) { target = target.constraintInRange(ship.arena_x, ship.arena_y, this.equipment.distance); return target; } else { @@ -21,8 +24,8 @@ module TS.SpaceTac { } } - checkShipTarget(ship: Ship, target: Target): Target { - if (ship.getPlayer() === target.ship.getPlayer()) { + checkShipTarget(ship: Ship, target: Target): Target | null { + if (target.ship && ship.getPlayer() === target.ship.getPlayer()) { // No friendly fire return null; } else { @@ -40,10 +43,11 @@ module TS.SpaceTac { /** * Collect the effects applied by this action */ - getEffects(battle: Battle, ship: Ship, target: Target): [Ship, BaseEffect][] { + getEffects(ship: Ship, target: Target): [Ship, BaseEffect][] { let result: [Ship, BaseEffect][] = []; let blast = this.getBlastRadius(ship); - let ships = blast ? battle.collectShipsInCircle(target, blast, true) : ((target.ship && target.ship.alive) ? [target.ship] : []); + let battle = ship.getBattle(); + let ships = (blast && battle) ? battle.collectShipsInCircle(target, blast, true) : ((target.ship && target.ship.alive) ? [target.ship] : []); ships.forEach(ship => { this.equipment.target_effects.forEach(effect => result.push([ship, effect])); }); @@ -58,7 +62,7 @@ module TS.SpaceTac { ship.addBattleEvent(new FireEvent(ship, this.equipment, target)); // Apply effects - let effects = this.getEffects(ship.getBattle(), ship, target); + let effects = this.getEffects(ship, target); effects.forEach(([ship, effect]) => effect.applyOnShip(ship)); } } diff --git a/src/core/actions/MoveAction.spec.ts b/src/core/actions/MoveAction.spec.ts index 5cc1563..1772ee5 100644 --- a/src/core/actions/MoveAction.spec.ts +++ b/src/core/actions/MoveAction.spec.ts @@ -29,7 +29,7 @@ module TS.SpaceTac { it("forbids targetting a ship", function () { var ship1 = new Ship(null, "Test1"); var ship2 = new Ship(null, "Test2"); - var action = new MoveAction(null); + var action = new MoveAction(new Equipment()); var result = action.checkTarget(ship1, Target.newFromShip(ship1)); expect(result).toBeNull(); @@ -74,9 +74,10 @@ module TS.SpaceTac { expect(battle.log.events[1].code).toEqual("move"); expect(battle.log.events[1].ship).toBe(ship); - expect(battle.log.events[1].target.ship).toBeNull(); - expect(battle.log.events[1].target.x).toBeCloseTo(3.535533, 0.00001); - expect(battle.log.events[1].target.y).toBeCloseTo(3.535533, 0.00001); + let target: any = battle.log.events[1].target; + expect(target.ship).toBeNull(); + expect(target.x).toBeCloseTo(3.535533, 0.00001); + expect(target.y).toBeCloseTo(3.535533, 0.00001); }); it("can't move too much near another ship", function () { diff --git a/src/core/actions/MoveAction.ts b/src/core/actions/MoveAction.ts index dcaa528..f5db421 100644 --- a/src/core/actions/MoveAction.ts +++ b/src/core/actions/MoveAction.ts @@ -5,13 +5,16 @@ module TS.SpaceTac { // Safety distance from other ships safety_distance: number; + // Equipment cannot be null (engine) + equipment: Equipment; + constructor(equipment: Equipment) { super("move", "Move", true, equipment); this.safety_distance = 50; } - checkCannotBeApplied(ship: Ship, remaining_ap: number = null): string | null { + checkCannotBeApplied(ship: Ship, remaining_ap: number | null = null): string | null { let base = super.checkCannotBeApplied(ship, Infinity); if (base) { return base; diff --git a/src/core/ai/AIDuel.ts b/src/core/ai/AIDuel.ts index 8b7ccc4..14429dc 100644 --- a/src/core/ai/AIDuel.ts +++ b/src/core/ai/AIDuel.ts @@ -76,18 +76,23 @@ module TS.SpaceTac { // console.debug(`Turn ${battle.turn} - Ship ${battle.play_order.indexOf(playing)} - Player ${battle.fleets.indexOf(playing.fleet)}`); - let ai = (playing.fleet == battle.fleets[0]) ? this.ai1 : this.ai2; - ai.timer = Timer.synchronous; - ai.ship = playing; - ai.play(); + if (playing) { + let ai = (playing.fleet == battle.fleets[0]) ? this.ai1 : this.ai2; + ai.timer = Timer.synchronous; + ai.ship = playing; + ai.play(); + } else { + console.error("No ship playing"); + break; + } if (!battle.ended && battle.playing_ship == playing) { - console.error(`${ai.name} did not end its turn !`); + console.error("AI did not end its turn !"); battle.advanceToNextShip(); } } - if (battle.ended && !battle.outcome.draw) { + if (battle.ended && !battle.outcome.draw && battle.outcome.winner) { this.update(battle.fleets.indexOf(battle.outcome.winner)); } else { this.update(-1); @@ -101,7 +106,8 @@ module TS.SpaceTac { * Setup the duel HTML page */ static setup(element: HTMLElement) { - let ais = [new BullyAI(null), new TacticalAI(null), new AbstractAI(null)]; + let fakeship = new Ship(); + let ais = [new BullyAI(fakeship), new TacticalAI(fakeship), new AbstractAI(fakeship)]; ais.forEach((ai, idx) => { let selects = element.getElementsByTagName("select"); for (let i = 0; i < selects.length; i++) { @@ -122,11 +128,12 @@ module TS.SpaceTac { console.clear(); let ai1 = parseInt(element.getElementsByTagName("select").item(0).value); let ai2 = parseInt(element.getElementsByTagName("select").item(1).value); - AIDuel.current = new AIDuel(ais[ai1], ais[ai2]); - AIDuel.current.start(() => { - element.getElementsByClassName("win1").item(0).textContent = AIDuel.current.win1.toString(); - element.getElementsByClassName("win2").item(0).textContent = AIDuel.current.win2.toString(); - element.getElementsByClassName("draw").item(0).textContent = AIDuel.current.draw.toString(); + let duel = new AIDuel(ais[ai1], ais[ai2]); + AIDuel.current = duel; + duel.start(() => { + element.getElementsByClassName("win1").item(0).textContent = duel.win1.toString(); + element.getElementsByClassName("win2").item(0).textContent = duel.win2.toString(); + element.getElementsByClassName("draw").item(0).textContent = duel.draw.toString(); }); button.textContent = "Stop !"; } diff --git a/src/core/ai/AbstractAI.ts b/src/core/ai/AbstractAI.ts index 97c7dfd..193d649 100644 --- a/src/core/ai/AbstractAI.ts +++ b/src/core/ai/AbstractAI.ts @@ -22,7 +22,7 @@ module TS.SpaceTac { // When the queue is empty, the ship will end its turn. private workqueue: Function[]; - constructor(ship: Ship, timer = Timer.global, name: string = null) { + constructor(ship: Ship, timer = Timer.global, name?: string) { this.name = name || classname(this); this.ship = ship; this.workqueue = []; @@ -52,7 +52,7 @@ module TS.SpaceTac { } // Add a work item to the work queue - addWorkItem(item: Function, delay = 100): void { + addWorkItem(item: Function | null, delay = 100): void { if (this.timer.isSynchronous()) { if (item) { item(); @@ -90,7 +90,9 @@ module TS.SpaceTac { } else { // Take the first item var item = this.workqueue.shift(); - item(); + if (item) { + item(); + } } } else { this.endTurn(); @@ -108,7 +110,6 @@ module TS.SpaceTac { if (this.ship.playing) { let battle = this.ship.getBattle(); this.ship.endTurn(); - this.ship = null; if (battle) { battle.advanceToNextShip(); } diff --git a/src/core/ai/BullyAI.spec.ts b/src/core/ai/BullyAI.spec.ts index e866745..58b93a3 100644 --- a/src/core/ai/BullyAI.spec.ts +++ b/src/core/ai/BullyAI.spec.ts @@ -56,9 +56,13 @@ module TS.SpaceTac.Specs { enemy.arena_x = 3; enemy.arena_y = 0; var result = ai.checkBullyManeuver(enemy, weapon); - expect(result.simulation.need_move).toBe(false); - expect(result.simulation.fire_location).toEqual(Target.newFromShip(enemy)); - expect(result.equipment).toBe(weapon); + if (result) { + expect(result.simulation.need_move).toBe(false); + expect(result.simulation.fire_location).toEqual(Target.newFromShip(enemy)); + expect(result.equipment).toBe(weapon); + } else { + fail("No maneuver proposed"); + } // enemy out of range, but moving can bring it in range ship.values.power.set(8); @@ -67,9 +71,13 @@ module TS.SpaceTac.Specs { enemy.arena_x = 6; enemy.arena_y = 0; result = ai.checkBullyManeuver(enemy, weapon); - expect(result.simulation.move_location).toEqual(Target.newFromLocation(3, 0)); - expect(result.simulation.fire_location).toEqual(Target.newFromShip(enemy)); - expect(result.equipment).toBe(weapon); + if (result) { + expect(result.simulation.move_location).toEqual(Target.newFromLocation(3, 0)); + expect(result.simulation.fire_location).toEqual(Target.newFromShip(enemy)); + expect(result.equipment).toBe(weapon); + } else { + fail("No maneuver proposed"); + } // enemy out of range, but moving can bring it in range, except for the safety margin ai.move_margin = 0.1; @@ -110,7 +118,7 @@ module TS.SpaceTac.Specs { expect(result).toBeNull(); // no engine, can't move - ship.slots[0].attached.detach(); + engine.detach(); ship.values.power.set(8); ship.arena_x = 1; ship.arena_y = 0; @@ -155,7 +163,7 @@ module TS.SpaceTac.Specs { var engine = TestTools.addEngine(ai.ship, 100); (engine.action).safety_distance = 20; - var maneuver: BullyManeuver; + var maneuver: BullyManeuver | null; battle.fleets[1].ships.forEach((ship: Ship) => { ai.ship.setArenaPosition(0, 0); @@ -172,10 +180,18 @@ module TS.SpaceTac.Specs { // Move towards an enemy (up to minimal distance) ai.ship.setArenaPosition(30, 0); maneuver = ai.getFallbackManeuver(); - expect(maneuver.simulation.move_location).toEqual(Target.newFromLocation(25, 0)); + if (maneuver) { + expect(maneuver.simulation.move_location).toEqual(Target.newFromLocation(25, 0)); + } else { + fail("No maneuver proposed"); + } ai.ship.setArenaPosition(25, 0); maneuver = ai.getFallbackManeuver(); - expect(maneuver.simulation.move_location).toEqual(Target.newFromLocation(22.5, 0)); + if (maneuver) { + expect(maneuver.simulation.move_location).toEqual(Target.newFromLocation(22.5, 0)); + } else { + fail("No maneuver proposed"); + } }); it("applies the chosen move", function () { diff --git a/src/core/ai/BullyAI.ts b/src/core/ai/BullyAI.ts index 2c26a88..daba26a 100644 --- a/src/core/ai/BullyAI.ts +++ b/src/core/ai/BullyAI.ts @@ -18,7 +18,7 @@ module TS.SpaceTac { if (this.ship.getValue("power") > 0) { this.addWorkItem(() => { var maneuvers = this.listAllManeuvers(); - var maneuver: BullyManeuver; + var maneuver: BullyManeuver | null; if (maneuvers.length > 0) { maneuver = this.pickManeuver(maneuvers); @@ -39,11 +39,14 @@ module TS.SpaceTac { listAllEnemies(): Ship[] { var result: Ship[] = []; - this.ship.getBattle().play_order.forEach((ship: Ship) => { - if (ship.alive && ship.getPlayer() !== this.ship.getPlayer()) { - result.push(ship); - } - }); + let battle = this.ship.getBattle(); + if (battle) { + battle.play_order.forEach((ship: Ship) => { + if (ship.alive && ship.getPlayer() !== this.ship.getPlayer()) { + result.push(ship); + } + }); + } return result; } @@ -73,7 +76,7 @@ module TS.SpaceTac { } // Get an equipped engine to make a move - getEngine(): Equipment { + getEngine(): Equipment | null { var engines = this.ship.listEquipment(SlotType.Engine); if (engines.length === 0) { return null; @@ -95,7 +98,7 @@ module TS.SpaceTac { } // When no bully action is available, pick a random enemy, and go towards it - getFallbackManeuver(): BullyManeuver { + getFallbackManeuver(): BullyManeuver | null { var enemies = this.listAllEnemies(); if (enemies.length === 0) { return null; @@ -107,12 +110,20 @@ module TS.SpaceTac { var target = Target.newFromShip(picked); var distance = target.getDistanceTo(Target.newFromShip(this.ship)); var engine = this.getEngine(); - var safety_distance = (engine.action).safety_distance; - if (distance > safety_distance) { // Don't move too close - target = target.constraintInRange(this.ship.arena_x, this.ship.arena_y, - (distance - safety_distance) * APPROACH_FACTOR); - target = engine.action.checkLocationTarget(this.ship, target); - return new BullyManeuver(this.ship, engine, target); + if (engine) { + var safety_distance = (engine.action).safety_distance; + if (distance > safety_distance) { // Don't move too close + target = target.constraintInRange(this.ship.arena_x, this.ship.arena_y, + (distance - safety_distance) * APPROACH_FACTOR); + let loctarget = engine.action.checkLocationTarget(this.ship, target); + if (loctarget) { + return new BullyManeuver(this.ship, engine, loctarget); + } else { + return null; + } + } else { + return null; + } } else { return null; } @@ -120,7 +131,7 @@ module TS.SpaceTac { // Pick a maneuver from a list of available ones // By default, it chooses the nearest enemy - pickManeuver(available: BullyManeuver[]): BullyManeuver { + pickManeuver(available: BullyManeuver[]): BullyManeuver | null { if (available.length === 0) { return null; } @@ -134,7 +145,7 @@ module TS.SpaceTac { } // Effectively apply the chosen maneuver - applyManeuver(maneuver: BullyManeuver): void { + applyManeuver(maneuver: BullyManeuver | null): void { if (maneuver) { this.addWorkItem(() => { maneuver.apply(); diff --git a/src/core/ai/TacticalAI.spec.ts b/src/core/ai/TacticalAI.spec.ts index c9efce3..fadff17 100644 --- a/src/core/ai/TacticalAI.spec.ts +++ b/src/core/ai/TacticalAI.spec.ts @@ -15,7 +15,7 @@ module TS.SpaceTac.Specs { // producer of FixedManeuver from a list of scores let producer = (...scores: number[]) => imap(iarray(scores), score => new FixedManeuver(score)); - let applied = []; + let applied: number[] = []; beforeEach(function () { applied = []; diff --git a/src/core/ai/TacticalAI.ts b/src/core/ai/TacticalAI.ts index c3469e8..3531ac3 100644 --- a/src/core/ai/TacticalAI.ts +++ b/src/core/ai/TacticalAI.ts @@ -52,12 +52,16 @@ module TS.SpaceTac { while (done < 1000 && this.producers.length > 0) { // Produce a maneuver - let maneuver: Maneuver; + let maneuver: Maneuver | null = null; let producer = this.producers.shift(); - [maneuver, producer] = producer(); + if (producer) { + [maneuver, producer] = producer(); + } if (maneuver) { - this.producers.push(producer); + if (producer) { + this.producers.push(producer); + } // Evaluate the maneuver let score = this.evaluate(maneuver); @@ -88,7 +92,7 @@ module TS.SpaceTac { TacticalAIHelpers.produceBlastShots, TacticalAIHelpers.produceRandomMoves, ] - producers.forEach(producer => this.producers.push(producer(this.ship, this.ship.getBattle()))); + producers.forEach(producer => this.producers.push(producer(this.ship, this.ship.getBattle() || new Battle()))); } /** @@ -101,6 +105,7 @@ module TS.SpaceTac { scaled(TacticalAIHelpers.evaluateDamageToEnemy, 30), scaled(TacticalAIHelpers.evaluateClustering, 3), ] + // TODO evaluator typing is lost evaluators.forEach(evaluator => this.evaluators.push((maneuver: Maneuver) => evaluator(this.ship, this.ship.getBattle(), maneuver))); } } diff --git a/src/core/ai/TacticalAIHelpers.ts b/src/core/ai/TacticalAIHelpers.ts index 835f190..7e016aa 100644 --- a/src/core/ai/TacticalAIHelpers.ts +++ b/src/core/ai/TacticalAIHelpers.ts @@ -72,7 +72,7 @@ module TS.SpaceTac { } let damage = 0; let dead = 0; - let effects = action.getEffects(battle, ship, maneuver.target); + let effects = action.getEffects(ship, maneuver.target); effects.forEach(([ship, effect]) => { if (effect instanceof DamageEffect && contains(enemies, ship)) { let [shield, hull] = effect.getEffectiveDamage(ship); diff --git a/src/core/equipments/AbstractDrone.ts b/src/core/equipments/AbstractDrone.ts index d460344..96806b7 100644 --- a/src/core/equipments/AbstractDrone.ts +++ b/src/core/equipments/AbstractDrone.ts @@ -14,21 +14,21 @@ module TS.SpaceTac.Equipments { * * Be aware that *min_distance* means the MAXIMAL reachable distance, but on a low-power loot ! */ - setDeployDistance(min_distance: number, max_distance: number = null): void { + setDeployDistance(min_distance: number, max_distance: number | null = null): void { this.distance = new Range(min_distance, max_distance); } /** * Set the effect radius of the deployed drone */ - setEffectRadius(min_radius: number, max_radius: number = null): void { + setEffectRadius(min_radius: number, max_radius: number | null = null): void { this.blast = new IntegerRange(min_radius, max_radius); } /** * Set the drone lifetime */ - setLifetime(min_lifetime: number, max_lifetime: number = null): void { + setLifetime(min_lifetime: number, max_lifetime: number | null = null): void { this.duration = new IntegerRange(min_lifetime, max_lifetime); } diff --git a/src/core/equipments/AbstractWeapon.ts b/src/core/equipments/AbstractWeapon.ts index c8cc3fb..d7bede4 100644 --- a/src/core/equipments/AbstractWeapon.ts +++ b/src/core/equipments/AbstractWeapon.ts @@ -6,7 +6,7 @@ module TS.SpaceTac.Equipments { // Boolean set to true if the weapon can target space can_target_space: boolean; - constructor(name: string, min_damage: number = 0, max_damage: number = null) { + constructor(name: string, min_damage: number = 0, max_damage: number | null = null) { super(SlotType.Weapon, name); this.can_target_space = false; @@ -18,13 +18,13 @@ module TS.SpaceTac.Equipments { // Set the range for this weapon // Pay attention that *min_distance* means the MAXIMAL reachable distance, but on a low-power loot - setRange(min_distance: number, max_distance: number = null, can_target_space: boolean = false): void { + setRange(min_distance: number, max_distance: number | null = null, can_target_space = false): void { this.distance = new Range(min_distance, max_distance); this.can_target_space = can_target_space; } // Set the effect radius (blast) for this weapon - setBlast(min_blast: number, max_blast: number = null): void { + setBlast(min_blast: number, max_blast: number | null = null): void { this.blast = new IntegerRange(min_blast, max_blast); } diff --git a/src/core/events/BaseLogEvent.ts b/src/core/events/BaseLogEvent.ts index 183fb27..371625a 100644 --- a/src/core/events/BaseLogEvent.ts +++ b/src/core/events/BaseLogEvent.ts @@ -5,18 +5,36 @@ module TS.SpaceTac { code: string; // The ship causing the event (the one whose turn it is to play) - ship: Ship; + ship: Ship | null; // Target of the event - target: Target; + target: Target | null; // Boolean at true if the event is used to set initial battle conditions initial = false; - constructor(code: string, ship: Ship = null, target: Target = null) { + constructor(code: string, ship: Ship | null = null, target: Target | null = null) { this.code = code; this.ship = ship; this.target = target; } } + + // Base class for a BattleLog event linked to a ship + export class BaseLogShipEvent extends BaseLogEvent { + ship: Ship; + + constructor(code: string, ship: Ship, target: Target | null = null) { + super(code, ship, target); + } + } + + // Base class for a BattleLog event linked to a ship, and with a target + export class BaseLogShipTargetEvent extends BaseLogShipEvent { + target: Target; + + constructor(code: string, ship: Ship, target: Target) { + super(code, ship, target); + } + } } diff --git a/src/core/events/DamageEvent.ts b/src/core/events/DamageEvent.ts index 1bfa38f..93d328f 100644 --- a/src/core/events/DamageEvent.ts +++ b/src/core/events/DamageEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a ship takes damage - export class DamageEvent extends BaseLogEvent { + export class DamageEvent extends BaseLogShipEvent { // Damage to hull hull: number; diff --git a/src/core/events/DeathEvent.ts b/src/core/events/DeathEvent.ts index d7efb00..13c7a30 100644 --- a/src/core/events/DeathEvent.ts +++ b/src/core/events/DeathEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a ship is dead - export class DeathEvent extends BaseLogEvent { + export class DeathEvent extends BaseLogShipEvent { constructor(ship: Ship) { super("death", ship); } diff --git a/src/core/events/DroneAppliedEvent.ts b/src/core/events/DroneAppliedEvent.ts index 82ba163..9ef006b 100644 --- a/src/core/events/DroneAppliedEvent.ts +++ b/src/core/events/DroneAppliedEvent.ts @@ -4,7 +4,7 @@ module TS.SpaceTac { /** * Event logged when a drone applies its effects */ - export class DroneAppliedEvent extends BaseLogEvent { + export class DroneAppliedEvent extends BaseLogShipEvent { // Pointer to the drone drone: Drone; diff --git a/src/core/events/DroneDeployedEvent.ts b/src/core/events/DroneDeployedEvent.ts index 28c9964..58bbda5 100644 --- a/src/core/events/DroneDeployedEvent.ts +++ b/src/core/events/DroneDeployedEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a drone is deployed by a ship - export class DroneDeployedEvent extends BaseLogEvent { + export class DroneDeployedEvent extends BaseLogShipEvent { // Pointer to the drone drone: Drone; diff --git a/src/core/events/DroneDestroyedEvent.ts b/src/core/events/DroneDestroyedEvent.ts index 04ab313..52a0ff0 100644 --- a/src/core/events/DroneDestroyedEvent.ts +++ b/src/core/events/DroneDestroyedEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a drone is destroyed - export class DroneDestroyedEvent extends BaseLogEvent { + export class DroneDestroyedEvent extends BaseLogShipEvent { // Pointer to the drone drone: Drone; diff --git a/src/core/events/EffectAddedEvent.ts b/src/core/events/EffectAddedEvent.ts index 7afd2c9..a1f41ba 100644 --- a/src/core/events/EffectAddedEvent.ts +++ b/src/core/events/EffectAddedEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a sticky effect is added to a ship - export class EffectAddedEvent extends BaseLogEvent { + export class EffectAddedEvent extends BaseLogShipEvent { // Pointer to the effect effect: StickyEffect; diff --git a/src/core/events/EffectDurationChangedEvent.ts b/src/core/events/EffectDurationChangedEvent.ts index a0e2bd7..df4d44a 100644 --- a/src/core/events/EffectDurationChangedEvent.ts +++ b/src/core/events/EffectDurationChangedEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a sticky effect is added to a ship - export class EffectDurationChangedEvent extends BaseLogEvent { + export class EffectDurationChangedEvent extends BaseLogShipEvent { // Pointer to the effect effect: StickyEffect; diff --git a/src/core/events/EffectRemovedEvent.ts b/src/core/events/EffectRemovedEvent.ts index 37bbe52..d2e3358 100644 --- a/src/core/events/EffectRemovedEvent.ts +++ b/src/core/events/EffectRemovedEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a sticky effect is removed from a ship - export class EffectRemovedEvent extends BaseLogEvent { + export class EffectRemovedEvent extends BaseLogShipEvent { // Pointer to the effect effect: StickyEffect; diff --git a/src/core/events/FireEvent.ts b/src/core/events/FireEvent.ts index 3ded308..2a3ac45 100644 --- a/src/core/events/FireEvent.ts +++ b/src/core/events/FireEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a weapon is used on a target - export class FireEvent extends BaseLogEvent { + export class FireEvent extends BaseLogShipTargetEvent { // Weapon used weapon: Equipment; diff --git a/src/core/events/MoveEvent.ts b/src/core/events/MoveEvent.ts index dfee8cc..5231d35 100644 --- a/src/core/events/MoveEvent.ts +++ b/src/core/events/MoveEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a ship moves - export class MoveEvent extends BaseLogEvent { + export class MoveEvent extends BaseLogShipTargetEvent { // New facing angle, in radians facing_angle: number; diff --git a/src/core/events/ShipChangeEvent.ts b/src/core/events/ShipChangeEvent.ts index 8f1f848..68f36cd 100644 --- a/src/core/events/ShipChangeEvent.ts +++ b/src/core/events/ShipChangeEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Battle event, when a ship turn ended, and advanced to a new one - export class ShipChangeEvent extends BaseLogEvent { + export class ShipChangeEvent extends BaseLogShipEvent { // Ship that starts playing new_ship: Ship; diff --git a/src/core/events/ValueChangeEvent.ts b/src/core/events/ValueChangeEvent.ts index b186d15..e262b5f 100644 --- a/src/core/events/ValueChangeEvent.ts +++ b/src/core/events/ValueChangeEvent.ts @@ -2,7 +2,7 @@ module TS.SpaceTac { // Event logged when a ship value or attribute changed - export class ValueChangeEvent extends BaseLogEvent { + export class ValueChangeEvent extends BaseLogShipEvent { // Saved version of the current value value: ShipValue; diff --git a/src/ui/TestGame.ts b/src/ui/TestGame.ts index 899e503..23c33b8 100644 --- a/src/ui/TestGame.ts +++ b/src/ui/TestGame.ts @@ -45,12 +45,11 @@ module TS.SpaceTac.UI.Specs { afterEach(function () { let ui = testgame.ui; - window.requestAnimationFrame(() => ui.destroy()); - - testgame.ui = null; - testgame.baseview = null; - testgame.battleview = null; - testgame.mapview = null; + window.requestAnimationFrame(() => { + if (ui) { + ui.destroy(); + } + }); }); return testgame; @@ -74,7 +73,7 @@ module TS.SpaceTac.UI.Specs { testgame.battleview = new BattleView(); let battle = Battle.newQuickRandom(); - let player = battle.playing_ship.getPlayer(); + let player = battle.playing_ship ? battle.playing_ship.getPlayer() : new Player(); return [testgame.battleview, [player, battle]]; }); diff --git a/src/ui/battle/ActionBar.ts b/src/ui/battle/ActionBar.ts index fb4c710..92cccbb 100644 --- a/src/ui/battle/ActionBar.ts +++ b/src/ui/battle/ActionBar.ts @@ -18,7 +18,7 @@ module TS.SpaceTac.UI { icon_waiting: Phaser.Image; // Current ship, whose actions are displayed - ship: Ship; + ship: Ship | null; ship_power_capacity: number; ship_power_value: number; @@ -170,7 +170,7 @@ module TS.SpaceTac.UI { * *power_usage* is the consumption of currently selected action. */ updateSelectedActionPower(power_usage: number): void { - var remaining_ap = this.ship.values.power.get() - power_usage; + var remaining_ap = this.ship ? (this.ship.values.power.get() - power_usage) : 0; if (remaining_ap < 0) { remaining_ap = 0; } diff --git a/src/ui/battle/ActionIcon.ts b/src/ui/battle/ActionIcon.ts index 4b3d4d1..6000734 100644 --- a/src/ui/battle/ActionIcon.ts +++ b/src/ui/battle/ActionIcon.ts @@ -23,7 +23,7 @@ module TS.SpaceTac.UI { fading: boolean; // Current targetting - private targetting: Targetting; + private targetting: Targetting | null; // Action icon - image representing the action private layer_icon: Phaser.Image; @@ -101,7 +101,9 @@ module TS.SpaceTac.UI { this.bar.actionStarted(); // Update range hint - this.battleview.arena.range_hint.setPrimary(this.ship, this.action); + if (this.battleview.arena.range_hint) { + this.battleview.arena.range_hint.setPrimary(this.ship, this.action); + } // Update fading statuses this.bar.updateSelectedActionPower(this.action.getActionPointsUsage(this.ship, null)); @@ -110,13 +112,18 @@ module TS.SpaceTac.UI { this.setSelected(true); if (this.action.needs_target) { - // Switch to targetting mode (will apply action when a target is selected) - this.targetting = this.battleview.enterTargettingMode(); - this.targetting.setSource(this.battleview.arena.findShipSprite(this.ship)); - this.targetting.targetSelected.add(this.processSelection, this); - this.targetting.targetHovered.add(this.processHover, this); - if (this.action instanceof MoveAction) { - this.targetting.setApIndicatorsInterval(this.action.getDistanceByActionPoint(this.ship)); + let sprite = this.battleview.arena.findShipSprite(this.ship); + if (sprite) { + // Switch to targetting mode (will apply action when a target is selected) + this.targetting = this.battleview.enterTargettingMode(); + if (this.targetting) { + this.targetting.setSource(sprite); + this.targetting.targetSelected.add(this.processSelection, this); + this.targetting.targetHovered.add(this.processHover, this); + if (this.action instanceof MoveAction) { + this.targetting.setApIndicatorsInterval(this.action.getDistanceByActionPoint(this.ship)); + } + } } } else { // No target needed, apply action immediately @@ -127,13 +134,15 @@ module TS.SpaceTac.UI { // Called when a target is hovered // This will check the target against current action and adjust it if needed processHover(target: Target): void { - target = this.action.checkTarget(this.ship, target); - this.targetting.setTarget(target, false, this.action.getBlastRadius(this.ship)); - this.bar.updateSelectedActionPower(this.action.getActionPointsUsage(this.ship, target)); + let correct_target = this.action.checkTarget(this.ship, target); + if (this.targetting) { + this.targetting.setTarget(correct_target, false, this.action.getBlastRadius(this.ship)); + } + this.bar.updateSelectedActionPower(this.action.getActionPointsUsage(this.ship, correct_target)); } // Called when a target is selected - processSelection(target: Target): void { + processSelection(target: Target | null): void { if (this.action.apply(this.ship, target)) { this.bar.actionEnded(); } diff --git a/src/ui/battle/ActionTooltip.spec.ts b/src/ui/battle/ActionTooltip.spec.ts index 538ab9e..674dae0 100644 --- a/src/ui/battle/ActionTooltip.spec.ts +++ b/src/ui/battle/ActionTooltip.spec.ts @@ -10,13 +10,14 @@ module TS.SpaceTac.UI.Specs { let tooltip = bar.tooltip; bar.clearAll(); - let a1 = bar.addAction(battleview.battle.playing_ship, new MoveAction(new Equipment())); - a1.action.equipment.name = "Engine"; + let ship = nn(battleview.battle.playing_ship); + let a1 = bar.addAction(ship, new MoveAction(new Equipment())); + nn(a1.action.equipment).name = "Engine"; a1.action.name = "Move"; - let a2 = bar.addAction(battleview.battle.playing_ship, new FireWeaponAction(new Equipment())); - a2.action.equipment.name = "Weapon"; + let a2 = bar.addAction(ship, new FireWeaponAction(new Equipment())); + nn(a2.action.equipment).name = "Weapon"; a2.action.name = "Fire"; - let a3 = bar.addAction(battleview.battle.playing_ship, new EndTurnAction()); + let a3 = bar.addAction(ship, new EndTurnAction()); a3.action.name = "End turn"; tooltip.setAction(a1); diff --git a/src/ui/battle/ActionTooltip.ts b/src/ui/battle/ActionTooltip.ts index c5712c0..a8f0683 100644 --- a/src/ui/battle/ActionTooltip.ts +++ b/src/ui/battle/ActionTooltip.ts @@ -39,7 +39,7 @@ module TS.SpaceTac.UI { } // Set current action to display, null to hide - setAction(action: ActionIcon): void { + setAction(action: ActionIcon | null): void { if (action) { if (this.icon) { this.icon.destroy(true); diff --git a/src/ui/battle/Arena.ts b/src/ui/battle/Arena.ts index d47b3d8..33009a2 100644 --- a/src/ui/battle/Arena.ts +++ b/src/ui/battle/Arena.ts @@ -21,9 +21,9 @@ module TS.SpaceTac.UI { private drone_sprites: ArenaDrone[] = []; // Currently hovered ship - private hovered: ArenaShip; + private hovered: ArenaShip | null; // Currently playing ship - private playing: ArenaShip; + private playing: ArenaShip | null; // Layer for particles layer_weapon_effects: Phaser.Group; @@ -35,7 +35,7 @@ module TS.SpaceTac.UI { this.battleview = battleview; this.playing = null; this.hovered = null; - this.range_hint = null; + this.range_hint = new RangeHint(this); var offset_x = 133; var offset_y = 132; @@ -60,9 +60,8 @@ module TS.SpaceTac.UI { }, null); this.position.set(offset_x, offset_y); - this.addChild(this.background); - this.range_hint = new RangeHint(this); + this.addChild(this.background); this.addChild(this.range_hint); this.init(); @@ -100,8 +99,8 @@ module TS.SpaceTac.UI { } // Find the sprite for a ship - findShipSprite(ship: Ship): ArenaShip { - var result: ArenaShip = null; + findShipSprite(ship: Ship): ArenaShip | null { + var result: ArenaShip | null = null; this.ship_sprites.forEach((sprite: ArenaShip) => { if (sprite.ship === ship) { result = sprite; @@ -111,27 +110,36 @@ module TS.SpaceTac.UI { } // Set the hovered state on a ship sprite - setShipHovered(ship: Ship): void { + setShipHovered(ship: Ship | null): void { if (this.hovered) { this.hovered.setHovered(false); } - var arena_ship = this.findShipSprite(ship); - if (arena_ship) { - arena_ship.setHovered(true); + + if (ship) { + var arena_ship = this.findShipSprite(ship); + if (arena_ship) { + arena_ship.setHovered(true); + } + this.hovered = arena_ship; + } else { + this.hovered = null; } - this.hovered = arena_ship; } // Set the playing state on a ship sprite - setShipPlaying(ship: Ship): void { + setShipPlaying(ship: Ship | null): void { if (this.playing) { this.playing.setPlaying(false); + this.playing = null; } - var arena_ship = this.findShipSprite(ship); - if (arena_ship) { - arena_ship.setPlaying(true); + + if (ship) { + var arena_ship = this.findShipSprite(ship); + if (arena_ship) { + arena_ship.setPlaying(true); + } + this.playing = arena_ship; } - this.playing = arena_ship; this.battleview.gameui.audio.playOnce("battle-ship-change"); } diff --git a/src/ui/battle/ArenaShip.spec.ts b/src/ui/battle/ArenaShip.spec.ts index 998e6c8..c91df9f 100644 --- a/src/ui/battle/ArenaShip.spec.ts +++ b/src/ui/battle/ArenaShip.spec.ts @@ -5,8 +5,8 @@ module TS.SpaceTac.UI.Specs { let testgame = setupBattleview(); it("adds effects display", function () { - let ship = testgame.battleview.battle.playing_ship; - let sprite = testgame.battleview.arena.findShipSprite(ship); + let ship = nn(testgame.battleview.battle.playing_ship); + let sprite = nn(testgame.battleview.arena.findShipSprite(ship)); expect(sprite.effects.children.length).toBe(0); diff --git a/src/ui/battle/BattleView.spec.ts b/src/ui/battle/BattleView.spec.ts index d9af65c..8eab261 100644 --- a/src/ui/battle/BattleView.spec.ts +++ b/src/ui/battle/BattleView.spec.ts @@ -13,7 +13,7 @@ module TS.SpaceTac.UI.Specs { expect(battleview.targetting).toBeNull(); // Enter targetting mode - var result = battleview.enterTargettingMode(); + var result = nn(battleview.enterTargettingMode()); expect(battleview.targetting).toBeTruthy(); expect(result).toBe(battleview.targetting); @@ -32,7 +32,7 @@ module TS.SpaceTac.UI.Specs { battleview.cursorInSpace(8, 4); expect(battleview.ship_hovered).toBeNull(); - expect(battleview.targetting.target_corrected).toEqual(Target.newFromLocation(8, 4)); + expect(nn(battleview.targetting).target_corrected).toEqual(Target.newFromLocation(8, 4)); // Process a click on space battleview.cursorClicked(); @@ -40,20 +40,20 @@ module TS.SpaceTac.UI.Specs { // Forward ship hovering battleview.cursorOnShip(battleview.battle.play_order[0]); - expect(battleview.ship_hovered).toEqual(battleview.battle.playing_ship); - expect(battleview.targetting.target_corrected).toEqual(Target.newFromShip(battleview.battle.playing_ship)); + expect(battleview.ship_hovered).toEqual(battleview.battle.play_order[0]); + expect(nn(battleview.targetting).target_corrected).toEqual(Target.newFromShip(battleview.battle.play_order[0])); // Don't leave a ship we're not hovering battleview.cursorOffShip(battleview.battle.play_order[1]); - expect(battleview.ship_hovered).toEqual(battleview.battle.playing_ship); - expect(battleview.targetting.target_corrected).toEqual(Target.newFromShip(battleview.battle.playing_ship)); + expect(battleview.ship_hovered).toEqual(battleview.battle.play_order[0]); + expect(nn(battleview.targetting).target_corrected).toEqual(Target.newFromShip(battleview.battle.play_order[0])); // Don't move in space while on ship battleview.cursorInSpace(1, 3); - expect(battleview.ship_hovered).toEqual(battleview.battle.playing_ship); - expect(battleview.targetting.target_corrected).toEqual(Target.newFromShip(battleview.battle.playing_ship)); + expect(battleview.ship_hovered).toEqual(battleview.battle.play_order[0]); + expect(nn(battleview.targetting).target_corrected).toEqual(Target.newFromShip(battleview.battle.play_order[0])); // Process a click on ship battleview.cursorClicked(); @@ -62,7 +62,7 @@ module TS.SpaceTac.UI.Specs { battleview.cursorOffShip(battleview.battle.play_order[0]); expect(battleview.ship_hovered).toBeNull(); - expect(battleview.targetting.target_corrected).toBeNull(); + expect(nn(battleview.targetting).target_corrected).toBeNull(); // Quit targetting battleview.exitTargettingMode(); @@ -73,7 +73,7 @@ module TS.SpaceTac.UI.Specs { battleview.cursorInSpace(8, 4); expect(battleview.ship_hovered).toBeNull(); battleview.cursorOnShip(battleview.battle.play_order[0]); - expect(battleview.ship_hovered).toEqual(battleview.battle.playing_ship); + expect(battleview.ship_hovered).toEqual(battleview.battle.play_order[0]); // Quit twice don't do anything battleview.exitTargettingMode(); @@ -81,12 +81,12 @@ module TS.SpaceTac.UI.Specs { // Check collected targetting events expect(hovered).toEqual([ Target.newFromLocation(8, 4), - Target.newFromShip(battleview.battle.playing_ship), + Target.newFromShip(battleview.battle.play_order[0]), null ]); expect(clicked).toEqual([ Target.newFromLocation(8, 4), - Target.newFromShip(battleview.battle.playing_ship), + Target.newFromShip(battleview.battle.play_order[0]), ]); }); }); diff --git a/src/ui/battle/BattleView.ts b/src/ui/battle/BattleView.ts index f7bb28b..6e27cfa 100644 --- a/src/ui/battle/BattleView.ts +++ b/src/ui/battle/BattleView.ts @@ -17,10 +17,10 @@ module TS.SpaceTac.UI { arena: Arena; // Background image - background: Phaser.Image; + background: Phaser.Image | null; // Targetting mode (null if we're not in this mode) - targetting: Targetting; + targetting: Targetting | null; // Ship list ship_list: ShipList; @@ -29,7 +29,7 @@ module TS.SpaceTac.UI { action_bar: ActionBar; // Currently hovered ship - ship_hovered: Ship; + ship_hovered: Ship | null; // Ship tooltip ship_tooltip: ShipTooltip; @@ -51,7 +51,6 @@ module TS.SpaceTac.UI { this.battle = battle; this.targetting = null; this.ship_hovered = null; - this.log_processor = null; this.background = null; this.battle.timer = this.timer; @@ -97,7 +96,7 @@ module TS.SpaceTac.UI { this.battle.endBattle(this.player.fleet); }); this.inputs.bindCheat(Phaser.Keyboard.A, "Use AI to play", () => { - if (this.interacting) { + if (this.interacting && this.battle.playing_ship) { this.setInteractionEnabled(false); this.battle.playAI(new TacticalAI(this.battle.playing_ship)); } @@ -111,22 +110,9 @@ module TS.SpaceTac.UI { shutdown() { this.exitTargettingMode(); - if (this.log_processor) { - this.log_processor.destroy(); - this.log_processor = null; - } - - if (this.ui) { - this.ui.destroy(); - this.ui = null; - } - - if (this.arena) { - this.arena.destroy(); - this.arena = null; - } - - this.battle = null; + this.log_processor.destroy(); + this.ui.destroy(); + this.arena.destroy(); super.shutdown(); } @@ -178,7 +164,7 @@ module TS.SpaceTac.UI { } // Set the currently hovered ship - setShipHovered(ship: Ship): void { + setShipHovered(ship: Ship | null): void { this.ship_hovered = ship; this.arena.setShipHovered(ship); this.ship_list.setHovered(ship); @@ -201,7 +187,7 @@ module TS.SpaceTac.UI { // Enter targetting mode // While in this mode, the Targetting object will receive hover and click events, and handle them - enterTargettingMode(): Targetting { + enterTargettingMode(): Targetting | null { if (!this.interacting) { return null; } diff --git a/src/ui/battle/LogProcessor.ts b/src/ui/battle/LogProcessor.ts index 93557fa..bff3667 100644 --- a/src/ui/battle/LogProcessor.ts +++ b/src/ui/battle/LogProcessor.ts @@ -101,7 +101,7 @@ module TS.SpaceTac.UI { this.processDroneDestroyedEvent(event); } else if (event instanceof DroneAppliedEvent) { this.processDroneAppliedEvent(event); - } else if (event.code == "effectadd" || event.code == "effectduration" || event.code == "effectdel") { + } else if (event instanceof EffectAddedEvent || event instanceof EffectRemovedEvent ||  event instanceof EffectDurationChangedEvent) { this.processEffectEvent(event); } } @@ -116,8 +116,13 @@ module TS.SpaceTac.UI { // Playing ship changed private processShipChangeEvent(event: ShipChangeEvent): void { - this.view.arena.setShipPlaying(event.target.ship); - this.view.ship_list.setPlaying(event.target.ship); + if (event.target && event.target.ship) { + this.view.arena.setShipPlaying(event.target.ship); + this.view.ship_list.setPlaying(event.target.ship); + } else { + this.view.arena.setShipPlaying(null); + this.view.ship_list.setPlaying(null); + } if (this.battle.canPlay(this.view.player)) { // Player turn @@ -196,7 +201,7 @@ module TS.SpaceTac.UI { private processEndBattleEvent(event: EndBattleEvent): void { this.view.setInteractionEnabled(false); - if (event.outcome.winner.player === this.view.player) { + if (event.outcome.winner && event.outcome.winner.player === this.view.player) { // Victory ! // TODO Loot screen this.view.player.exitBattle(); @@ -207,7 +212,7 @@ module TS.SpaceTac.UI { } // Sticky effect on ship added, changed or removed - private processEffectEvent(event: BaseLogEvent): void { + private processEffectEvent(event: EffectAddedEvent | EffectRemovedEvent | EffectDurationChangedEvent): void { var item = this.view.ship_list.findItem(event.ship); if (item) { item.updateEffects(); diff --git a/src/ui/battle/RangeHint.ts b/src/ui/battle/RangeHint.ts index e208a0e..7e9a1cc 100644 --- a/src/ui/battle/RangeHint.ts +++ b/src/ui/battle/RangeHint.ts @@ -8,7 +8,7 @@ module TS.SpaceTac.UI { circle: Phaser.Graphics; // Stored information of primary circle, when secondary one overrides it - primary: Phaser.Circle; + primary: Phaser.Circle | null; constructor(parent: Arena) { super(parent.game, parent); diff --git a/src/ui/battle/ShipList.ts b/src/ui/battle/ShipList.ts index 21cf508..0839fc7 100644 --- a/src/ui/battle/ShipList.ts +++ b/src/ui/battle/ShipList.ts @@ -8,10 +8,10 @@ module TS.SpaceTac.UI { ships: ShipListItem[]; // Playing ship - playing: ShipListItem; + playing: ShipListItem | null; // Hovered ship - hovered: ShipListItem; + hovered: ShipListItem | null; // Create an empty action bar constructor(battleview: BattleView) { @@ -57,8 +57,8 @@ module TS.SpaceTac.UI { // Find an item for a ship // Returns null if not found - findItem(ship: Ship): ShipListItem { - var found: ShipListItem = null; + findItem(ship: Ship): ShipListItem | null { + var found: ShipListItem | null = null; this.ships.forEach((item: ShipListItem) => { if (item.ship === ship) { found = item; @@ -71,7 +71,7 @@ module TS.SpaceTac.UI { findPlayPosition(ship: Ship): number { var battle = this.battleview.battle; var idx = battle.play_order.indexOf(ship); - var diff = idx - battle.playing_ship_index; + var diff = idx - (battle.playing_ship_index || 0); if (diff < 0) { diff += battle.play_order.length; } @@ -100,19 +100,26 @@ module TS.SpaceTac.UI { } // Set the currently playing ship - setPlaying(ship: Ship): void { - this.playing = this.findItem(ship); + setPlaying(ship: Ship | null): void { + if (ship) { + this.playing = this.findItem(ship); + } else { + this.playing = null; + } this.updateItemsLocation(); } // Set the currently hovered ship - setHovered(ship: Ship): void { + setHovered(ship: Ship | null): void { if (this.hovered) { this.hovered.setHovered(false); + this.hovered = null; } - this.hovered = this.findItem(ship); - if (this.hovered) { - this.hovered.setHovered(true); + if (ship) { + this.hovered = this.findItem(ship); + if (this.hovered) { + this.hovered.setHovered(true); + } } } } diff --git a/src/ui/battle/Targetting.ts b/src/ui/battle/Targetting.ts index f61eb37..3671f16 100644 --- a/src/ui/battle/Targetting.ts +++ b/src/ui/battle/Targetting.ts @@ -3,11 +3,11 @@ module TS.SpaceTac.UI { // Allows to pick a target for an action export class Targetting { // Initial target (as pointed by the user) - target_initial: Target; + target_initial: Target | null; line_initial: Phaser.Graphics; // Corrected target (applying action rules) - target_corrected: Target; + target_corrected: Target | null; line_corrected: Phaser.Graphics; // Circle for effect radius @@ -25,13 +25,13 @@ module TS.SpaceTac.UI { ap_indicators: Phaser.Image[] = []; // Access to the parent battle view - private battleview: BattleView; + private battleview: BattleView | null; // Source of the targetting - private source: PIXI.DisplayObject; + private source: PIXI.DisplayObject | null; // Create a default targetting mode - constructor(battleview: BattleView) { + constructor(battleview: BattleView | null) { this.battleview = battleview; this.targetHovered = new Phaser.Signal(); this.targetSelected = new Phaser.Signal(); @@ -116,6 +116,10 @@ module TS.SpaceTac.UI { // Update the AP indicators display updateApIndicators() { + if (!this.battleview || !this.source || !this.target_corrected) { + return; + } + // Get indicator count let count = 0; let distance = 0; @@ -139,10 +143,11 @@ module TS.SpaceTac.UI { // Spread indicators if (count > 0 && distance > 0) { - let dx = this.ap_interval * (this.target_corrected.x - this.source.x) / distance; - let dy = this.ap_interval * (this.target_corrected.y - this.source.y) / distance; + let source = this.source; + let dx = this.ap_interval * (this.target_corrected.x - source.x) / distance; + let dy = this.ap_interval * (this.target_corrected.y - source.y) / distance; this.ap_indicators.forEach((indicator, index) => { - indicator.position.set(this.source.x + dx * index, this.source.y + dy * index); + indicator.position.set(source.x + dx * index, source.y + dy * index); }); } } @@ -153,7 +158,7 @@ module TS.SpaceTac.UI { } // Set a target from a target object - setTarget(target: Target, dispatch: boolean = true, blast_radius: number = 0): void { + setTarget(target: Target | null, dispatch: boolean = true, blast_radius: number = 0): void { this.target_corrected = target; this.blast_radius = blast_radius; if (dispatch) { diff --git a/src/ui/common/Audio.ts b/src/ui/common/Audio.ts index 39289ec..c92e86f 100644 --- a/src/ui/common/Audio.ts +++ b/src/ui/common/Audio.ts @@ -4,7 +4,7 @@ module TS.SpaceTac.UI { private game: MainUI; - private music: Phaser.Sound; + private music: Phaser.Sound | null; constructor(game: MainUI) { this.game = game; diff --git a/src/ui/common/InputManager.ts b/src/ui/common/InputManager.ts index 6e307ca..b018c30 100644 --- a/src/ui/common/InputManager.ts +++ b/src/ui/common/InputManager.ts @@ -33,7 +33,7 @@ module TS.SpaceTac.UI { this.bind(Phaser.Keyboard.M, "Toggle sound", () => { this.game.audio.toggleMute(); }); - this.bind(Phaser.Keyboard.NUMPAD_ADD, null, () => { + this.bind(Phaser.Keyboard.NUMPAD_ADD, "", () => { if (this.cheats_enabled) { this.cheat = !this.cheat; this.game.displayMessage(this.cheat ? "Cheats enabled" : "Cheats disabled"); @@ -48,9 +48,9 @@ module TS.SpaceTac.UI { // Bind a key to a cheat action bindCheat(key: number, desc: string, action: Function): void { - this.bind(key, null, () => { + this.bind(key, `Cheat: ${desc}`, () => { if (this.cheat) { - console.warn("Cheat ! " + desc); + console.warn(`Cheat ! ${desc}`); action(); } }); diff --git a/src/ui/map/FleetDisplay.spec.ts b/src/ui/map/FleetDisplay.spec.ts index b210d5e..1252d6c 100644 --- a/src/ui/map/FleetDisplay.spec.ts +++ b/src/ui/map/FleetDisplay.spec.ts @@ -11,11 +11,15 @@ module TS.SpaceTac.UI.Specs { mapview.game.tweens.update(); let tween = first(mapview.game.tweens.getAll(), tw => tw.target == fleet); - let tweendata = tween.generateData(0.1); - expect(tweendata.length).toEqual(3); - expect(tweendata[0].rotation).toBeCloseTo(-Math.PI * 2 / 3); - expect(tweendata[1].rotation).toBeCloseTo(-Math.PI * 4 / 3); - expect(tweendata[2].rotation).toBeCloseTo(-Math.PI * 2); + if (tween) { + let tweendata = tween.generateData(0.1); + expect(tweendata.length).toEqual(3); + expect(tweendata[0].rotation).toBeCloseTo(-Math.PI * 2 / 3); + expect(tweendata[1].rotation).toBeCloseTo(-Math.PI * 4 / 3); + expect(tweendata[2].rotation).toBeCloseTo(-Math.PI * 2); + } else { + fail("No tween found"); + } }); }); } diff --git a/src/ui/map/FleetDisplay.ts b/src/ui/map/FleetDisplay.ts index 699181c..5f64fd3 100644 --- a/src/ui/map/FleetDisplay.ts +++ b/src/ui/map/FleetDisplay.ts @@ -29,7 +29,9 @@ module TS.SpaceTac.UI { sprite.anchor.set(0.5, 0.5); }); - this.position.set(fleet.location.star.x + fleet.location.x, fleet.location.star.y + fleet.location.y); + if (fleet.location) { + this.position.set(fleet.location.star.x + fleet.location.x, fleet.location.star.y + fleet.location.y); + } this.scale.set(SCALING, SCALING); this.tween = this.game.tweens.create(this); @@ -68,8 +70,8 @@ module TS.SpaceTac.UI { /** * Make the fleet move to another location in the same system */ - moveToLocation(location: StarLocation, speed = 1, on_leave: (duration: number) => any | null = null) { - if (location != this.fleet.location) { + moveToLocation(location: StarLocation, speed = 1, on_leave: ((duration: number) => any) | null = null) { + if (this.fleet.location && location != this.fleet.location) { let dx = location.universe_x - this.fleet.location.universe_x; let dy = location.universe_y - this.fleet.location.universe_y; let distance = Math.sqrt(dx * dx + dy * dy); diff --git a/src/ui/map/UniverseMapView.ts b/src/ui/map/UniverseMapView.ts index 77f5195..bca65d4 100644 --- a/src/ui/map/UniverseMapView.ts +++ b/src/ui/map/UniverseMapView.ts @@ -6,10 +6,10 @@ module TS.SpaceTac.UI { */ export class UniverseMapView extends BaseView { // Displayed universe - universe: Universe; + universe = new Universe(); // Interacting player - player: Player; + player = new Player(); // Star systems group: Phaser.Group; @@ -52,9 +52,11 @@ module TS.SpaceTac.UI { let loc2 = starlink.second.getWarpLocationTo(starlink.first); let result = new Phaser.Graphics(this.game); - result.lineStyle(0.005, 0x8bbeff); - result.moveTo(starlink.first.x - 0.5 + loc1.x, starlink.first.y - 0.5 + loc1.y); - result.lineTo(starlink.second.x - 0.5 + loc2.x, starlink.second.y - 0.5 + loc2.y); + if (loc1 && loc2) { + result.lineStyle(0.005, 0x8bbeff); + result.moveTo(starlink.first.x - 0.5 + loc1.x, starlink.first.y - 0.5 + loc1.y); + result.lineTo(starlink.second.x - 0.5 + loc2.x, starlink.second.y - 0.5 + loc2.y); + } return result; }); this.starlinks.forEach(starlink => this.group.addChild(starlink)); @@ -92,8 +94,8 @@ module TS.SpaceTac.UI { * Leaving the view, unbind and destroy */ shutdown() { - this.universe = null; - this.player = null; + this.universe = new Universe(); + this.player = new Player(); super.shutdown(); } @@ -105,7 +107,7 @@ module TS.SpaceTac.UI { this.starsystems.forEach(system => system.updateInfo()); let location = this.player.fleet.location; - if (location.type == StarLocationType.WARP) { + if (location && location.type == StarLocationType.WARP) { let angle = Math.atan2(location.y, location.x); this.button_jump.scale.set(location.star.radius * 0.002, location.star.radius * 0.002); this.button_jump.position.set(location.star.x + location.x + 0.02 * Math.cos(angle), location.star.y + location.y + 0.02 * Math.sin(angle)); @@ -140,8 +142,8 @@ module TS.SpaceTac.UI { * Set the current zoom level (0, 1 or 2) */ setZoom(level: number) { - let current_star = this.player.fleet.location.star; - if (level <= 0) { + let current_star = this.player.fleet.location ? this.player.fleet.location.star : null; + if (!current_star || level <= 0) { this.setCamera(0, 0, this.universe.radius * 2); this.zoom = 0; } else if (level == 1) { @@ -158,7 +160,7 @@ module TS.SpaceTac.UI { * Do the jump animation to another system */ doJump() { - if (this.player.fleet.location.type == StarLocationType.WARP && this.player.fleet.location.jump_dest) { + if (this.player.fleet.location && this.player.fleet.location.type == StarLocationType.WARP && this.player.fleet.location.jump_dest) { Animation.setVisibility(this.game, this.button_jump, false, 300); let dest_location = this.player.fleet.location.jump_dest; diff --git a/tsconfig.json b/tsconfig.json index c6dd0e5..56d14a4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,7 @@ "removeComments": true, "preserveConstEnums": true, "out": "out/build.js", - "strictNullChecks": false, + "strictNullChecks": true, "sourceMap": true, "target": "es5" }, diff --git a/typings.json b/typings.json index 29c4f27..5110347 100644 --- a/typings.json +++ b/typings.json @@ -1,8 +1,8 @@ { - "name": "succession", + "name": "spacetac", "dependencies": {}, "globalDependencies": { "jasmine": "registry:dt/jasmine#2.5.0+20161003201800", - "phaser": "github:photonstorm/phaser/typescript/typings.json#v2.6.2" + "phaser": "github:thunderk/phaser-ce/typescript/typings.json#v2.7.3a" } } \ No newline at end of file