Improved character sheet tooltips
This commit is contained in:
parent
41f9b1ad6f
commit
69a65b0735
File diff suppressed because it is too large
Load diff
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 95 KiB |
|
@ -1 +1 @@
|
|||
Subproject commit 2882c791e8af845517fd030c6e789296d347213d
|
||||
Subproject commit 0fcd953719ed8dbaab92cfaf525a2e34078b069a
|
|
@ -15,7 +15,7 @@ module TK.SpaceTac {
|
|||
var fleet = new Fleet(player);
|
||||
var ship_generator = new ShipGenerator(this.random);
|
||||
|
||||
let models = this.random.sample(BaseModel.getDefaultCollection(), ship_count);
|
||||
let models = this.random.sample(ShipModel.getDefaultCollection(), ship_count);
|
||||
|
||||
range(ship_count).forEach(i => {
|
||||
var ship = ship_generator.generate(level, models[i] || null, upgrade);
|
||||
|
|
|
@ -5,7 +5,7 @@ module TK.SpaceTac.Specs {
|
|||
check.equals(ship.getName(false), "Ship");
|
||||
check.equals(ship.getName(true), "Level 1 Ship");
|
||||
|
||||
ship.model = new BaseModel("test", "Hauler");
|
||||
ship.model = new ShipModel("test", "Hauler");
|
||||
check.equals(ship.getName(false), "Hauler");
|
||||
check.equals(ship.getName(true), "Level 1 Hauler");
|
||||
|
||||
|
@ -35,7 +35,7 @@ module TK.SpaceTac.Specs {
|
|||
});
|
||||
|
||||
test.case("applies permanent effects of ship model on attributes", check => {
|
||||
let model = new BaseModel();
|
||||
let model = new ShipModel();
|
||||
let ship = new Ship(null, null, model);
|
||||
|
||||
check.patch(model, "getEffects", () => [
|
||||
|
@ -151,17 +151,19 @@ module TK.SpaceTac.Specs {
|
|||
let ship = new Ship();
|
||||
check.equals(ship.getAttributeDescription("maneuvrability"), "Ability to move first, fast and to evade weapons");
|
||||
|
||||
check.patch(ship.model, "getEffects", () => [new AttributeEffect("maneuvrability", 4)]);
|
||||
ship.updateAttributes();
|
||||
check.equals(ship.getAttribute("maneuvrability"), 4);
|
||||
check.equals(ship.getAttributeDescription("maneuvrability"), "Ability to move first, fast and to evade weapons\n\nLevel 1 Ship: +4");
|
||||
check.patch(ship, "getUpgrades", () => [
|
||||
{ code: "Base", effects: [new AttributeEffect("maneuvrability", 3)] },
|
||||
{ code: "Up1", effects: [new AttributeEffect("precision", 1)] },
|
||||
{ code: "Up2", effects: [new AttributeEffect("precision", 1), new AttributeEffect("maneuvrability", 1)] }
|
||||
]);
|
||||
check.equals(ship.getAttributeDescription("maneuvrability"), "Ability to move first, fast and to evade weapons\n\nBase: +3\nUp2: +1");
|
||||
|
||||
ship.active_effects.add(new StickyEffect(new AttributeLimitEffect("maneuvrability", 3)));
|
||||
check.equals(ship.getAttributeDescription("maneuvrability"), "Ability to move first, fast and to evade weapons\n\nLevel 1 Ship: +4\nSticky effect: limit to 3");
|
||||
check.equals(ship.getAttributeDescription("maneuvrability"), "Ability to move first, fast and to evade weapons\n\nBase: +3\nUp2: +1\nSticky effect: limit to 3");
|
||||
|
||||
ship.active_effects.remove(ship.active_effects.list()[0]);
|
||||
ship.active_effects.add(new AttributeEffect("maneuvrability", -1));
|
||||
check.equals(ship.getAttributeDescription("maneuvrability"), "Ability to move first, fast and to evade weapons\n\nLevel 1 Ship: +4\nActive effect: -1");
|
||||
check.equals(ship.getAttributeDescription("maneuvrability"), "Ability to move first, fast and to evade weapons\n\nBase: +3\nUp2: +1\nActive effect: -1");
|
||||
});
|
||||
|
||||
test.case("produces death diffs", check => {
|
||||
|
|
|
@ -6,7 +6,7 @@ module TK.SpaceTac {
|
|||
*/
|
||||
export class Ship extends RObject {
|
||||
// Ship model
|
||||
model: BaseModel
|
||||
model: ShipModel
|
||||
|
||||
// Fleet this ship is a member of
|
||||
fleet: Fleet
|
||||
|
@ -52,7 +52,7 @@ module TK.SpaceTac {
|
|||
play_priority = 0
|
||||
|
||||
// Create a new ship inside a fleet
|
||||
constructor(fleet: Fleet | null = null, name: string | null = null, model = new BaseModel()) {
|
||||
constructor(fleet: Fleet | null = null, name: string | null = null, model = new ShipModel()) {
|
||||
super();
|
||||
|
||||
this.fleet = fleet || new Fleet();
|
||||
|
@ -139,14 +139,14 @@ module TK.SpaceTac {
|
|||
/**
|
||||
* Get the list of activated upgrades
|
||||
*/
|
||||
getUpgrades(): ModelUpgrade[] {
|
||||
getUpgrades(): ShipUpgrade[] {
|
||||
return this.model.getActivatedUpgrades(this.level.get(), this.level.getUpgrades());
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle an upgrade
|
||||
*/
|
||||
activateUpgrade(upgrade: ModelUpgrade, on: boolean): void {
|
||||
activateUpgrade(upgrade: ShipUpgrade, on: boolean): void {
|
||||
if (on && (upgrade.cost || 0) > this.getAvailableUpgradePoints()) {
|
||||
return;
|
||||
}
|
||||
|
@ -402,8 +402,10 @@ module TK.SpaceTac {
|
|||
}
|
||||
}
|
||||
|
||||
this.getModelEffects().forEach(effect => {
|
||||
addEffect(`Level ${this.level.get()} ${this.model.name}`, effect);
|
||||
this.getUpgrades().forEach(upgrade => {
|
||||
if (upgrade.effects) {
|
||||
upgrade.effects.forEach(effect => addEffect(upgrade.code, effect));
|
||||
}
|
||||
});
|
||||
|
||||
this.active_effects.list().forEach(effect => {
|
||||
|
|
|
@ -2,7 +2,7 @@ module TK.SpaceTac.Specs {
|
|||
testing("ShipGenerator", test => {
|
||||
test.case("can use ship model", check => {
|
||||
var gen = new ShipGenerator();
|
||||
var model = new BaseModel("test", "Test");
|
||||
var model = new ShipModel("test", "Test");
|
||||
var ship = gen.generate(3, model, false);
|
||||
check.same(ship.model, model);
|
||||
check.same(ship.level.get(), 3);
|
||||
|
|
|
@ -15,10 +15,10 @@ module TK.SpaceTac {
|
|||
*
|
||||
* If *upgrade* is true, random levelling options will be chosen
|
||||
*/
|
||||
generate(level: number, model: BaseModel | null = null, upgrade = true): Ship {
|
||||
generate(level: number, model: ShipModel | null = null, upgrade = true): Ship {
|
||||
if (!model) {
|
||||
// Get a random model
|
||||
model = BaseModel.getRandomModel(level, this.random);
|
||||
model = ShipModel.getRandomModel(level, this.random);
|
||||
}
|
||||
|
||||
let result = new Ship(null, null, model);
|
||||
|
|
|
@ -94,7 +94,7 @@ module TK.SpaceTac {
|
|||
*
|
||||
* This does not check the upgrade points needed
|
||||
*/
|
||||
activateUpgrade(upgrade: ModelUpgrade, active: boolean): void {
|
||||
activateUpgrade(upgrade: ShipUpgrade, active: boolean): void {
|
||||
if (active) {
|
||||
add(this.upgrades, upgrade.code);
|
||||
} else {
|
||||
|
@ -105,7 +105,7 @@ module TK.SpaceTac {
|
|||
/**
|
||||
* Check if an upgrade is active
|
||||
*/
|
||||
hasUpgrade(upgrade: ModelUpgrade): boolean {
|
||||
hasUpgrade(upgrade: ShipUpgrade): boolean {
|
||||
return contains(this.upgrades, upgrade.code);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ module TK.SpaceTac {
|
|||
* Set a ship attributes (by changing its model)
|
||||
*/
|
||||
static setShipModel(ship: Ship, hull: number, shield = 0, power = 0, level = 1, actions: BaseAction[] = [], effects: BaseEffect[] = []) {
|
||||
let model = new BaseModel();
|
||||
let model = new ShipModel();
|
||||
ship.level.forceLevel(level);
|
||||
ship.model = model;
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ module TK.SpaceTac.Specs {
|
|||
let actions = new ActionList();
|
||||
check.equals(actions.listAll(), [EndTurnAction.SINGLETON]);
|
||||
|
||||
let model = new BaseModel();
|
||||
let model = new ShipModel();
|
||||
let ship = new Ship(null, null, model);
|
||||
actions.updateFromShip(ship);
|
||||
check.equals(actions.listAll(), [EndTurnAction.SINGLETON]);
|
||||
|
@ -17,8 +17,8 @@ module TK.SpaceTac.Specs {
|
|||
check.equals(actions.listAll(), [action1, action2, EndTurnAction.SINGLETON]);
|
||||
check.called(mock, [[3, []]]);
|
||||
|
||||
let up1: ModelUpgrade = { code: "up1" };
|
||||
let up2: ModelUpgrade = { code: "up2" };
|
||||
let up1: ShipUpgrade = { code: "up1" };
|
||||
let up2: ShipUpgrade = { code: "up2" };
|
||||
check.patch(model, "getLevelUpgrades", () => [up1, up2]);
|
||||
ship.level.activateUpgrade(up1, true);
|
||||
actions.updateFromShip(ship);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelAvenger extends BaseModel {
|
||||
export class ModelAvenger extends ShipModel {
|
||||
constructor() {
|
||||
super("avenger", "Avenger");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A heavy ship, dedicated to firing high precision charged shots across great distances.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 50,
|
||||
safety_distance: 250,
|
||||
|
@ -35,19 +35,10 @@ module TK.SpaceTac {
|
|||
}, "submunitionmissile");
|
||||
long_range_missile.configureCooldown(1, 2);
|
||||
|
||||
let shield_booster = new TriggerAction("Shield Booster", {
|
||||
effects: [
|
||||
new StickyEffect(new AttributeEffect("shield_capacity", 50), 2),
|
||||
new ValueEffect("shield", 70),
|
||||
],
|
||||
power: 2
|
||||
}, "forcefield");
|
||||
shield_booster.configureCooldown(1, 4);
|
||||
|
||||
if (level == 1) {
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Avenger Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 8),
|
||||
new AttributeEffect("maneuvrability", 0),
|
||||
|
@ -73,28 +64,41 @@ module TK.SpaceTac {
|
|||
return [
|
||||
{
|
||||
code: "Laser Targetting",
|
||||
description: "Improved targetting, using fine-grained laser sensors",
|
||||
cost: 1,
|
||||
effects: [new AttributeEffect("precision", 2)]
|
||||
effects: [new AttributeEffect("precision", 2)],
|
||||
},
|
||||
{
|
||||
code: "Basic Countermeasures",
|
||||
description: "Chaffs and lures to divert enemy fire",
|
||||
cost: 1,
|
||||
effects: [new AttributeEffect("maneuvrability", 2)]
|
||||
effects: [new AttributeEffect("maneuvrability", 2)],
|
||||
},
|
||||
{
|
||||
code: "Targetting Assist",
|
||||
description: "Share your targetting subnetwork with nearby ships",
|
||||
cost: 3,
|
||||
actions: [new ToggleAction("Targetting Assist", {
|
||||
power: 3,
|
||||
radius: 300,
|
||||
effects: [new AttributeEffect("precision", 2)]
|
||||
}, "precisionboost")]
|
||||
}, "precisionboost")],
|
||||
},
|
||||
];
|
||||
} else if (level == 3) {
|
||||
let shield_booster = new TriggerAction("Shield Booster", {
|
||||
effects: [
|
||||
new StickyEffect(new AttributeEffect("shield_capacity", 50), 2),
|
||||
new ValueEffect("shield", 70),
|
||||
],
|
||||
power: 2
|
||||
}, "forcefield");
|
||||
shield_booster.configureCooldown(1, 4);
|
||||
|
||||
return [
|
||||
{
|
||||
code: "Gyroscopic Stabilizers",
|
||||
description: "Heavy mercury gyroscopes, used to stabilize the whole ship while firing",
|
||||
cost: 1,
|
||||
effects: [
|
||||
new AttributeEffect("precision", 3),
|
||||
|
@ -103,11 +107,13 @@ module TK.SpaceTac {
|
|||
},
|
||||
{
|
||||
code: "Shield Booster",
|
||||
description: "Temporary power surge directed toward the shield mainframe, to boost its output",
|
||||
cost: 3,
|
||||
actions: [shield_booster]
|
||||
},
|
||||
{
|
||||
code: "Hard Coated Hull",
|
||||
description: "Improved metal coating of outer hull layers, making them more damage resistant",
|
||||
cost: 2,
|
||||
effects: [new AttributeEffect("hull_capacity", 10)]
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelBreeze extends BaseModel {
|
||||
export class ModelBreeze extends ShipModel {
|
||||
constructor() {
|
||||
super("breeze", "Breeze");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A swift piece of maneuvrability, able to go deep behind enemy lines, and come back without a scratch.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 300,
|
||||
|
@ -36,7 +36,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Breeze Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 3),
|
||||
new AttributeEffect("maneuvrability", 12),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelCommodore extends BaseModel {
|
||||
export class ModelCommodore extends ShipModel {
|
||||
constructor() {
|
||||
super("commodore", "Commodore");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A devil whirlwind, very dangerous to surround.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 150,
|
||||
|
@ -33,7 +33,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Commodore Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 5),
|
||||
new AttributeEffect("maneuvrability", 6),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelCreeper extends BaseModel {
|
||||
export class ModelCreeper extends ShipModel {
|
||||
constructor() {
|
||||
super("creeper", "Creeper");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A fast ship, with low firepower but extensive support modules.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 220,
|
||||
|
@ -40,7 +40,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Creeper Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 3),
|
||||
new AttributeEffect("maneuvrability", 12),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelFalcon extends BaseModel {
|
||||
export class ModelFalcon extends ShipModel {
|
||||
constructor() {
|
||||
super("falcon", "Falcon");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A ship with an efficient targetting system, allowing to hit multiple foes.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 130,
|
||||
|
@ -32,7 +32,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Falcon Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 8),
|
||||
new AttributeEffect("maneuvrability", 4),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelFlea extends BaseModel {
|
||||
export class ModelFlea extends ShipModel {
|
||||
constructor() {
|
||||
super("flea", "Flea");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "An agile but weak ship, specialized in disruptive technologies.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 400,
|
||||
|
@ -32,7 +32,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Flea Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 0),
|
||||
new AttributeEffect("maneuvrability", 15),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelJumper extends BaseModel {
|
||||
export class ModelJumper extends ShipModel {
|
||||
constructor() {
|
||||
super("jumper", "Jumper");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A mid-range action ship, with support abilities.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 200,
|
||||
|
@ -38,7 +38,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Jumper Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 9),
|
||||
new AttributeEffect("maneuvrability", 3),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelRhino extends BaseModel {
|
||||
export class ModelRhino extends ShipModel {
|
||||
constructor() {
|
||||
super("rhino", "Rhino");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A sturdy ship, able to sustain massive damage.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 140,
|
||||
|
@ -32,7 +32,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Rhino Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 4),
|
||||
new AttributeEffect("maneuvrability", 3),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelTomahawk extends BaseModel {
|
||||
export class ModelTomahawk extends ShipModel {
|
||||
constructor() {
|
||||
super("tomahawk", "Tomahawk");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A ship compensating its somewhat weak equipments with high power and usability.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 160,
|
||||
|
@ -49,7 +49,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Tomahawk Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 8),
|
||||
new AttributeEffect("maneuvrability", 3),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelTrapper extends BaseModel {
|
||||
export class ModelTrapper extends ShipModel {
|
||||
constructor() {
|
||||
super("trapper", "Trapper");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A mostly defensive ship, used to protect allies from enemy fire.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 220,
|
||||
|
@ -38,7 +38,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Trapper Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 3),
|
||||
new AttributeEffect("maneuvrability", 2),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// <reference path="BaseModel.ts" />
|
||||
/// <reference path="ShipModel.ts" />
|
||||
|
||||
module TK.SpaceTac {
|
||||
export class ModelXander extends BaseModel {
|
||||
export class ModelXander extends ShipModel {
|
||||
constructor() {
|
||||
super("xander", "Xander");
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ module TK.SpaceTac {
|
|||
return "A ship with impressive survival capabilities.";
|
||||
}
|
||||
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
if (level == 1) {
|
||||
let engine = new MoveAction("Engine", {
|
||||
distance_per_power: 150,
|
||||
|
@ -37,7 +37,7 @@ module TK.SpaceTac {
|
|||
|
||||
return [
|
||||
{
|
||||
code: "Base Attributes",
|
||||
code: "Xander Base",
|
||||
effects: [
|
||||
new AttributeEffect("precision", 8),
|
||||
new AttributeEffect("maneuvrability", 5),
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
module TK.SpaceTac.Specs {
|
||||
testing("BaseModel", test => {
|
||||
testing("ShipModel", test => {
|
||||
test.case("picks random models from default collection", check => {
|
||||
check.patch(console, "error", null);
|
||||
check.patch(BaseModel, "getDefaultCollection", iterator([
|
||||
[new BaseModel("a")],
|
||||
check.patch(ShipModel, "getDefaultCollection", iterator([
|
||||
[new ShipModel("a")],
|
||||
[],
|
||||
[new BaseModel("a"), new BaseModel("b")],
|
||||
[new BaseModel("a")],
|
||||
[new ShipModel("a"), new ShipModel("b")],
|
||||
[new ShipModel("a")],
|
||||
[],
|
||||
]));
|
||||
|
||||
check.equals(BaseModel.getRandomModel(), new BaseModel("a"), "pick from a one-item list");
|
||||
check.equals(BaseModel.getRandomModel(), new BaseModel(), "pick from an empty list");
|
||||
check.equals(ShipModel.getRandomModel(), new ShipModel("a"), "pick from a one-item list");
|
||||
check.equals(ShipModel.getRandomModel(), new ShipModel(), "pick from an empty list");
|
||||
|
||||
check.equals(sorted(BaseModel.getRandomModels(2), (a, b) => cmp(a.code, b.code)), [new BaseModel("a"), new BaseModel("b")], "sample from good-sized list");
|
||||
check.equals(BaseModel.getRandomModels(2), [new BaseModel("a"), new BaseModel("a")], "sample from too small list");
|
||||
check.equals(BaseModel.getRandomModels(2), [new BaseModel(), new BaseModel()], "sample from empty list");
|
||||
check.equals(sorted(ShipModel.getRandomModels(2), (a, b) => cmp(a.code, b.code)), [new ShipModel("a"), new ShipModel("b")], "sample from good-sized list");
|
||||
check.equals(ShipModel.getRandomModels(2), [new ShipModel("a"), new ShipModel("a")], "sample from too small list");
|
||||
check.equals(ShipModel.getRandomModels(2), [new ShipModel(), new ShipModel()], "sample from empty list");
|
||||
});
|
||||
|
||||
test.case("makes upgrades available by level", check => {
|
||||
let model = new BaseModel();
|
||||
let model = new ShipModel();
|
||||
|
||||
function verify(desc: string, level: number, specific: string[], available: string[], activated: string[], chosen: string[] = []) {
|
||||
check.in(`${desc} level ${level}`, check => {
|
||||
|
@ -31,7 +31,7 @@ module TK.SpaceTac.Specs {
|
|||
|
||||
verify("initial", 1, [], [], []);
|
||||
|
||||
check.patch(model, "getLevelUpgrades", (level: number): ModelUpgrade[] => {
|
||||
check.patch(model, "getLevelUpgrades", (level: number): ShipUpgrade[] => {
|
||||
if (level == 1) {
|
||||
return [
|
||||
{ code: "l1" },
|
|
@ -4,11 +4,13 @@ module TK.SpaceTac {
|
|||
*
|
||||
* Upgrades allow for customizing a model, and are unlocked at given levels
|
||||
*/
|
||||
export type ModelUpgrade = {
|
||||
export type ShipUpgrade = {
|
||||
// Displayable upgrade name, should be unique on the model
|
||||
code: string
|
||||
// Upgrade points cost (may be used to balance upgrades)
|
||||
cost?: number
|
||||
// Textual description of the upgrade
|
||||
description?: string
|
||||
// Optional list of upgrade codes that must be activated for this one to be available
|
||||
depends?: string[]
|
||||
// Optional list of upgrade codes that this upgrade will fully replace
|
||||
|
@ -26,7 +28,7 @@ module TK.SpaceTac {
|
|||
*
|
||||
* A model defines the ship's design, actions, permanent effects, and levelling options.
|
||||
*/
|
||||
export class BaseModel {
|
||||
export class ShipModel {
|
||||
constructor(
|
||||
// Code to identify the model
|
||||
readonly code = "default",
|
||||
|
@ -52,7 +54,7 @@ module TK.SpaceTac {
|
|||
/**
|
||||
* Get basic level upgrades
|
||||
*/
|
||||
protected getStandardUpgrades(level: number): ModelUpgrade[] {
|
||||
protected getStandardUpgrades(level: number): ShipUpgrade[] {
|
||||
return [
|
||||
{ code: `Hull upgrade Lv${level - 1}`, effects: [new AttributeEffect("hull_capacity", 5)], cost: 2 },
|
||||
{ code: `Shield upgrade Lv${level - 1}`, effects: [new AttributeEffect("shield_capacity", 5)], cost: 2 },
|
||||
|
@ -63,15 +65,15 @@ module TK.SpaceTac {
|
|||
/**
|
||||
* Get the list of upgrades unlocked at a given level
|
||||
*/
|
||||
getLevelUpgrades(level: number): ModelUpgrade[] {
|
||||
getLevelUpgrades(level: number): ShipUpgrade[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of upgrades activated, given a ship level and an upgrade set
|
||||
*/
|
||||
getActivatedUpgrades(level: number, upgrade_codes: string[]): ModelUpgrade[] {
|
||||
let result: ModelUpgrade[] = [];
|
||||
getActivatedUpgrades(level: number, upgrade_codes: string[]): ShipUpgrade[] {
|
||||
let result: ShipUpgrade[] = [];
|
||||
|
||||
range(level).forEach(i => {
|
||||
let upgrades = this.getLevelUpgrades(i + 1);
|
||||
|
@ -95,7 +97,7 @@ module TK.SpaceTac {
|
|||
*
|
||||
* This does not filter the upgrades on dependencies
|
||||
*/
|
||||
getAvailableUpgrades(level: number): ModelUpgrade[] {
|
||||
getAvailableUpgrades(level: number): ShipUpgrade[] {
|
||||
return flatten(range(level).map(i => this.getLevelUpgrades(i + 1)));
|
||||
}
|
||||
|
||||
|
@ -120,14 +122,14 @@ module TK.SpaceTac {
|
|||
*
|
||||
* This scans the current namespace for model classes starting with 'Model'.
|
||||
*/
|
||||
static getDefaultCollection(): BaseModel[] {
|
||||
let result: BaseModel[] = [];
|
||||
static getDefaultCollection(): ShipModel[] {
|
||||
let result: ShipModel[] = [];
|
||||
let namespace: any = TK.SpaceTac;
|
||||
|
||||
for (let class_name in namespace) {
|
||||
if (class_name && class_name.indexOf("Model") == 0) {
|
||||
let model_class = namespace[class_name];
|
||||
if (model_class.prototype instanceof BaseModel) {
|
||||
if (model_class.prototype instanceof ShipModel) {
|
||||
let model = new model_class();
|
||||
result.push(model);
|
||||
}
|
||||
|
@ -140,15 +142,15 @@ module TK.SpaceTac {
|
|||
/**
|
||||
* Pick a random model in the default collection
|
||||
*/
|
||||
static getRandomModel(level?: number, random = RandomGenerator.global): BaseModel {
|
||||
let collection = BaseModel.getDefaultCollection();
|
||||
static getRandomModel(level?: number, random = RandomGenerator.global): ShipModel {
|
||||
let collection = ShipModel.getDefaultCollection();
|
||||
if (level) {
|
||||
collection = collection.filter(model => model.isAvailable(level));
|
||||
}
|
||||
|
||||
if (collection.length == 0) {
|
||||
console.error("Couldn't pick a random ship model");
|
||||
return new BaseModel();
|
||||
return new ShipModel();
|
||||
} else {
|
||||
return random.choice(collection);
|
||||
}
|
||||
|
@ -159,17 +161,17 @@ module TK.SpaceTac {
|
|||
*
|
||||
* At first it tries to pick unique models, then fill with duplicates
|
||||
*/
|
||||
static getRandomModels(count: number, level?: number, random = RandomGenerator.global): BaseModel[] {
|
||||
let collection = BaseModel.getDefaultCollection();
|
||||
static getRandomModels(count: number, level?: number, random = RandomGenerator.global): ShipModel[] {
|
||||
let collection = ShipModel.getDefaultCollection();
|
||||
if (level) {
|
||||
collection = collection.filter(model => model.isAvailable(level));
|
||||
}
|
||||
|
||||
if (collection.length == 0) {
|
||||
console.error("Couldn't pick a random model");
|
||||
return range(count).map(() => new BaseModel());
|
||||
return range(count).map(() => new ShipModel());
|
||||
} else {
|
||||
let result: BaseModel[] = [];
|
||||
let result: ShipModel[] = [];
|
||||
while (count > 0) {
|
||||
let picked = random.sample(collection, Math.min(count, collection.length));
|
||||
result = result.concat(picked);
|
|
@ -7,7 +7,7 @@ module TK.SpaceTac.UI.Specs {
|
|||
let ship = testgame.view.battle.play_order[2];
|
||||
TestTools.setShipModel(ship, 58, 140, 12);
|
||||
ship.name = "Fury";
|
||||
ship.model = new BaseModel("fake", "Fury");
|
||||
ship.model = new ShipModel("fake", "Fury");
|
||||
check.patch(ship.model, "getDescription", () => "Super ship model !");
|
||||
TestTools.addWeapon(ship, 50);
|
||||
TestTools.setAttribute(ship, "precision", 7);
|
||||
|
|
75
src/ui/character/CharacterUpgrade.spec.ts
Normal file
75
src/ui/character/CharacterUpgrade.spec.ts
Normal file
|
@ -0,0 +1,75 @@
|
|||
/// <reference path="../TestGame.ts"/>
|
||||
|
||||
module TK.SpaceTac.UI.Specs {
|
||||
testing("CharacterUpgrade", test => {
|
||||
let testgame = setupSingleView(test, () => [new BaseView(), []]);
|
||||
|
||||
test.acase("fills tooltip content", async check => {
|
||||
let ship = new Ship();
|
||||
let upgrade: ShipUpgrade = {
|
||||
code: "Test Upgrade",
|
||||
description: "A super ship upgrade",
|
||||
effects: [
|
||||
new AttributeEffect("hull_capacity", 10),
|
||||
new AttributeEffect("shield_capacity", 5),
|
||||
]
|
||||
};
|
||||
|
||||
let display = new CharacterUpgrade(ship, upgrade, 3);
|
||||
let tooltip = new TooltipContainer(testgame.view);
|
||||
let builder = new TooltipBuilder(tooltip);
|
||||
display.fillTooltip(builder);
|
||||
check.equals(cfilter(tooltip.content.children, Phaser.Text).map(child => child.text), [
|
||||
"Test Upgrade",
|
||||
"Permanent effects:",
|
||||
"• hull capacity +10",
|
||||
"• shield capacity +5",
|
||||
"A super ship upgrade",
|
||||
]);
|
||||
|
||||
upgrade.effects = [];
|
||||
upgrade.actions = [new TriggerAction("Test action", {
|
||||
range: 50,
|
||||
effects: [new DamageEffect(10)]
|
||||
})];
|
||||
|
||||
builder.clear();
|
||||
display.fillTooltip(builder);
|
||||
check.equals(cfilter(tooltip.content.children, Phaser.Text).map(child => child.text), [
|
||||
"Test Upgrade",
|
||||
"Fire (power 1, range 50km):",
|
||||
"• do 10 damage on target",
|
||||
"A super ship upgrade",
|
||||
]);
|
||||
})
|
||||
|
||||
test.acase("gets an appropriate icon", async check => {
|
||||
let ship = new Ship();
|
||||
let upgrade: ShipUpgrade = {
|
||||
code: "Test Upgrade",
|
||||
effects: [
|
||||
new AttributeEffect("hull_capacity", 10),
|
||||
new AttributeEffect("shield_capacity", 5),
|
||||
]
|
||||
};
|
||||
let display = new CharacterUpgrade(ship, upgrade, 3);
|
||||
check.equals(display.getIcon(), "attribute-hull_capacity");
|
||||
|
||||
upgrade.effects = [];
|
||||
upgrade.actions = [new BaseAction("Test Action")];
|
||||
check.equals(display.getIcon(), "action-testaction");
|
||||
|
||||
upgrade.actions = [];
|
||||
check.equals(display.getIcon(), "translucent");
|
||||
|
||||
upgrade.effects = [new DamageEffect(10)];
|
||||
check.equals(display.getIcon(), "translucent");
|
||||
|
||||
upgrade.effects = [
|
||||
new DamageEffect(10),
|
||||
new AttributeMultiplyEffect("precision", 2)
|
||||
];
|
||||
check.equals(display.getIcon(), "attribute-precision");
|
||||
})
|
||||
})
|
||||
}
|
|
@ -5,7 +5,7 @@ module TK.SpaceTac.UI {
|
|||
export class CharacterUpgrade {
|
||||
constructor(
|
||||
readonly ship: Ship,
|
||||
readonly upgrade: ModelUpgrade,
|
||||
readonly upgrade: ShipUpgrade,
|
||||
readonly level: number
|
||||
) {
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ module TK.SpaceTac.UI {
|
|||
if (enabled) {
|
||||
builder.text(this.upgrade.code, 166, 40, { size: 16, color: "#e7ebf0", width: 210 });
|
||||
|
||||
let icon = builder.image(this.getIcon(this.upgrade), 40, 40, true);
|
||||
let icon = builder.image(this.getIcon(), 40, 40, true);
|
||||
if (icon.width && icon.width > 64) {
|
||||
icon.scale.set(64 / icon.width);
|
||||
}
|
||||
|
@ -60,32 +60,43 @@ module TK.SpaceTac.UI {
|
|||
/**
|
||||
* Fill the tooltip for this upgrade
|
||||
*/
|
||||
private fillTooltip(builder: TooltipBuilder): boolean {
|
||||
fillTooltip(builder: TooltipBuilder): boolean {
|
||||
builder.text(this.upgrade.code, 0, 0, { size: 20 });
|
||||
|
||||
let y = 30;
|
||||
let y = 42;
|
||||
|
||||
if (this.upgrade.effects) {
|
||||
if (bool(this.upgrade.effects)) {
|
||||
builder.text("Permanent effects:", 0, y);
|
||||
y += 30;
|
||||
this.upgrade.effects.forEach(effect => {
|
||||
builder.text(effect.getDescription(), 0, y);
|
||||
builder.text(`• ${effect.getDescription()}`, 0, y);
|
||||
y += 30;
|
||||
});
|
||||
}
|
||||
|
||||
if (this.upgrade.actions) {
|
||||
if (bool(this.upgrade.actions)) {
|
||||
this.upgrade.actions.forEach(action => {
|
||||
builder.text(action.getEffectsDescription(), 0, y);
|
||||
y += 60;
|
||||
action.getEffectsDescription().split('\n').forEach(line => {
|
||||
builder.text(line, 0, y);
|
||||
y += 30;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (bool(this.upgrade.description)) {
|
||||
y += 10;
|
||||
builder.text(this.upgrade.description, 0, y, { size: 14, color: "#999999", width: 540 });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an icon code for an upgrade
|
||||
*/
|
||||
private getIcon(upgrade: ModelUpgrade): string {
|
||||
getIcon(): string {
|
||||
let upgrade = this.upgrade;
|
||||
|
||||
if (upgrade.actions && upgrade.actions.length) {
|
||||
return `action-${upgrade.actions[0].code}`;
|
||||
} else if (upgrade.effects && upgrade.effects.length) {
|
||||
|
|
|
@ -12,7 +12,7 @@ module TK.SpaceTac.UI {
|
|||
create() {
|
||||
super.create();
|
||||
|
||||
let models = BaseModel.getRandomModels(2);
|
||||
let models = ShipModel.getRandomModels(2);
|
||||
|
||||
this.built_fleet = new Fleet();
|
||||
this.built_fleet.addShip(new Ship(null, MissionGenerator.generateCharacterName(), models[0]));
|
||||
|
|
|
@ -4,7 +4,7 @@ module TK.SpaceTac.UI {
|
|||
|
||||
export type TooltipFiller = string | ((filler: TooltipBuilder) => string) | ((filler: TooltipBuilder) => boolean);
|
||||
|
||||
class TooltipContainer extends Phaser.Group {
|
||||
export class TooltipContainer extends Phaser.Group {
|
||||
view: BaseView
|
||||
background: Phaser.Graphics
|
||||
content: Phaser.Group
|
||||
|
|
Loading…
Reference in a new issue