diff --git a/TODO b/TODO index a5a0105..673be91 100644 --- a/TODO +++ b/TODO @@ -3,4 +3,3 @@ * Add retreat from battle * Refactor the tooltip system to use it more * Flash ship icons that receive damage -* Add a ship model system \ No newline at end of file diff --git a/src/app/game/Ship.ts b/src/app/game/Ship.ts index 3aaa7c4..8b6d1d3 100644 --- a/src/app/game/Ship.ts +++ b/src/app/game/Ship.ts @@ -14,6 +14,9 @@ module SpaceTac.Game { // Name of the ship name: string; + // Code of the ShipModel used to create it + model: string; + // Flag indicating if the ship is alive alive: boolean; @@ -67,6 +70,7 @@ module SpaceTac.Game { this.fleet = fleet || new Fleet(); this.level = 1; this.name = name; + this.model = "default"; this.alive = true; this.initiative = this.newAttribute(AttributeCode.Initiative); this.initiative.setMaximal(1); diff --git a/src/app/game/ShipGenerator.ts b/src/app/game/ShipGenerator.ts index 3706c48..69994fb 100644 --- a/src/app/game/ShipGenerator.ts +++ b/src/app/game/ShipGenerator.ts @@ -13,16 +13,20 @@ module SpaceTac.Game { // Generate a ship of a given level // The ship will not be named, nor will be a member of any fleet - generate(level: number): Ship { + generate(level: number, model: ShipModel = null): Ship { var result = new Ship(); var loot = new LootGenerator(this.random); - // Add equipment slots - result.addSlot(SlotType.Armor); - result.addSlot(SlotType.Engine); - result.addSlot(SlotType.Power); - result.addSlot(SlotType.Shield); - result.addSlot(SlotType.Weapon); + if (!model) { + // Get a random model + model = ShipModel.getRandomModel(level, this.random); + } + + // Apply model + result.model = model.code; + model.slots.forEach((slot: SlotType) => { + result.addSlot(slot); + }); // Fill equipment slots result.slots.forEach((slot: Slot) => { diff --git a/src/app/game/ShipModel.ts b/src/app/game/ShipModel.ts new file mode 100644 index 0000000..5a4c9c3 --- /dev/null +++ b/src/app/game/ShipModel.ts @@ -0,0 +1,48 @@ +module SpaceTac.Game { + "use strict"; + + // A model of ship + // It defines the ship looks, and available slots for equipment + export class ShipModel { + // Code to identify the model + code: string; + + // Minimal level to use this model + level: number; + + // Available slots + slots: SlotType[]; + + constructor(code: string, level: number, ...slots: SlotType[]) { + this.code = code; + this.level = level; + this.slots = slots; + } + + // Get the default ship model collection available in-game + static getDefaultCollection(): ShipModel[] { + // TODO Store in cache + var result = []; + + result.push(new ShipModel("scout", 1, SlotType.Armor, SlotType.Engine, SlotType.Power, SlotType.Weapon)); + + result.push(new ShipModel("whirlwind", 1, SlotType.Armor, SlotType.Engine, SlotType.Power, SlotType.Shield, + SlotType.Weapon, SlotType.Weapon)); + + return result; + } + + // Pick a random model in the default collection + static getRandomModel(level: Number, random: RandomGenerator = new RandomGenerator()): ShipModel { + var collection = this.getDefaultCollection(); + collection = collection.filter((model: ShipModel) => { + return model.level <= level; + }); + var result = random.choice(collection); + if (!result) { + console.error("Couldn't pick a random model for level " + level.toString()); + } + return result; + } + } +} diff --git a/src/app/game/specs/Ship.spec.ts b/src/app/game/specs/Ship.spec.ts index 8efbc38..4f75721 100644 --- a/src/app/game/specs/Ship.spec.ts +++ b/src/app/game/specs/Ship.spec.ts @@ -1,6 +1,6 @@ /// -module SpaceTac.Game { +module SpaceTac.Game.Specs { "use strict"; describe("Ship", function () { diff --git a/src/app/game/specs/ShipGenerator.spec.ts b/src/app/game/specs/ShipGenerator.spec.ts new file mode 100644 index 0000000..ac35afa --- /dev/null +++ b/src/app/game/specs/ShipGenerator.spec.ts @@ -0,0 +1,18 @@ +/// + +module SpaceTac.Game.Specs { + "use strict"; + + describe("ShipGenerator", function () { + it("can use ship model", function () { + var gen = new ShipGenerator(); + var model = new ShipModel("test", 1, SlotType.Shield, SlotType.Weapon, SlotType.Weapon); + var ship = gen.generate(1, model); + expect(ship.model).toBe("test"); + expect(ship.slots.length).toBe(3); + expect(ship.slots[0].type).toBe(SlotType.Shield); + expect(ship.slots[1].type).toBe(SlotType.Weapon); + expect(ship.slots[2].type).toBe(SlotType.Weapon); + }); + }); +} diff --git a/src/app/view/battle/ArenaShip.ts b/src/app/view/battle/ArenaShip.ts index 5b8df18..31422c4 100644 --- a/src/app/view/battle/ArenaShip.ts +++ b/src/app/view/battle/ArenaShip.ts @@ -22,7 +22,7 @@ module SpaceTac.View { super(battleview.game); // Add ship sprite - this.sprite = new Phaser.Button(battleview.game, 0, 0, "ship-scout-sprite"); + this.sprite = new Phaser.Button(battleview.game, 0, 0, "ship-" + ship.model + "-sprite"); this.sprite.rotation = ship.arena_angle; this.sprite.anchor.set(0.5, 0.5); this.addChild(this.sprite); diff --git a/src/app/view/battle/ShipListItem.ts b/src/app/view/battle/ShipListItem.ts index 0c4db4c..6c877c6 100644 --- a/src/app/view/battle/ShipListItem.ts +++ b/src/app/view/battle/ShipListItem.ts @@ -41,7 +41,7 @@ module SpaceTac.View { this.layer_base = new Phaser.Image(this.game, 0, 0, "battle-shiplist-base", 0); this.addChild(this.layer_base); - this.layer_portrait = new Phaser.Image(this.game, 30, 30, "ship-scout-portrait", 0); + this.layer_portrait = new Phaser.Image(this.game, 30, 30, "ship-" + ship.model + "-portrait", 0); this.layer_portrait.anchor.set(0.5, 0.5); this.layer_portrait.scale.set(0.19, 0.19); this.addChild(this.layer_portrait);