New fleet creation mode for character sheet (allow to change ship model)
6
TODO.md
|
@ -24,9 +24,9 @@ Map/story
|
||||||
Character sheet
|
Character sheet
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
* Replace the close icon by a validation icon in creation view
|
* Improve action and attribute tooltips
|
||||||
* Allow to change/buy ship model
|
* Implement sliders for personality traits
|
||||||
* Add personality indicators (editable in creation view)
|
* Center the portraits when there are less than 5
|
||||||
|
|
||||||
Battle
|
Battle
|
||||||
------
|
------
|
||||||
|
|
BIN
data/stage2/image/character/creation-help.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 849 B After Width: | Height: | Size: 2.1 KiB |
BIN
data/stage2/image/character/model-next-hover.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
data/stage2/image/character/model-next.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
data/stage2/image/character/model-prev-hover.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
data/stage2/image/character/model-prev.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 7.7 KiB |
BIN
data/stage2/image/character/personality-background.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
data/stage2/image/character/personality-trait-base.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
data/stage2/image/character/personality-trait-cursor-hover.png
Normal file
After Width: | Height: | Size: 802 B |
BIN
data/stage2/image/character/personality-trait-cursor.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 474 B After Width: | Height: | Size: 497 B |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 4.9 KiB |
BIN
data/stage2/image/character/section-title.png
Normal file
After Width: | Height: | Size: 777 B |
BIN
data/stage2/image/character/ship-column-left.png
Normal file
After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 8 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.4 KiB |
BIN
data/stage2/image/character/validate-creation-hover.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
data/stage2/image/character/validate-creation.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
|
@ -1,5 +1,14 @@
|
||||||
# UI style guidelines
|
# UI style guidelines
|
||||||
|
|
||||||
|
## Shapes
|
||||||
|
|
||||||
|
Main UI shapes are:
|
||||||
|
|
||||||
|
* long hexagon
|
||||||
|
* rectangles, optionally with left and/or right side tilted (if both are tilted, it should be symmetrical)
|
||||||
|
|
||||||
|
Buttons should be lit by a pure white line in top-left corner (~75% of the border length)
|
||||||
|
|
||||||
## Color palette
|
## Color palette
|
||||||
|
|
||||||
http://paletton.com/#uid=63D0c0kcBwN43YM8AMYhnnWlyeQ
|
http://paletton.com/#uid=63D0c0kcBwN43YM8AMYhnnWlyeQ
|
||||||
|
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 136 KiB |
|
@ -143,6 +143,23 @@ module TK.SpaceTac {
|
||||||
return this.model.getActivatedUpgrades(this.level.get(), this.level.getUpgrades());
|
return this.model.getActivatedUpgrades(this.level.get(), this.level.getUpgrades());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh the actions and attributes from the bound model
|
||||||
|
*/
|
||||||
|
refreshFromModel(): void {
|
||||||
|
this.updateAttributes();
|
||||||
|
this.actions.updateFromShip(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the ship model
|
||||||
|
*/
|
||||||
|
setModel(model: ShipModel): void {
|
||||||
|
this.model = model;
|
||||||
|
this.level.clearUpgrades();
|
||||||
|
this.refreshFromModel();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle an upgrade
|
* Toggle an upgrade
|
||||||
*/
|
*/
|
||||||
|
@ -151,8 +168,7 @@ module TK.SpaceTac {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.level.activateUpgrade(upgrade, on);
|
this.level.activateUpgrade(upgrade, on);
|
||||||
this.updateAttributes();
|
this.refreshFromModel();
|
||||||
this.actions.updateFromShip(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -39,5 +39,32 @@ module TK.SpaceTac.Specs {
|
||||||
level.forceLevel(10);
|
level.forceLevel(10);
|
||||||
check.equals(level.get(), 10);
|
check.equals(level.get(), 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test.case("manages upgrades", check => {
|
||||||
|
let up1 = { code: "test1" };
|
||||||
|
let up2 = { code: "test2" };
|
||||||
|
|
||||||
|
let level = new ShipLevel();
|
||||||
|
check.equals(level.getUpgrades(), []);
|
||||||
|
check.equals(level.hasUpgrade(up1), false);
|
||||||
|
|
||||||
|
level.activateUpgrade(up1, true);
|
||||||
|
check.equals(level.getUpgrades(), ["test1"]);
|
||||||
|
check.equals(level.hasUpgrade(up1), true);
|
||||||
|
|
||||||
|
level.activateUpgrade(up1, true);
|
||||||
|
check.equals(level.getUpgrades(), ["test1"]);
|
||||||
|
check.equals(level.hasUpgrade(up1), true);
|
||||||
|
|
||||||
|
level.activateUpgrade(up1, false);
|
||||||
|
check.equals(level.getUpgrades(), []);
|
||||||
|
check.equals(level.hasUpgrade(up1), false);
|
||||||
|
|
||||||
|
level.activateUpgrade(up1, true);
|
||||||
|
level.activateUpgrade(up2, true);
|
||||||
|
check.equals(level.getUpgrades(), ["test1", "test2"]);
|
||||||
|
level.clearUpgrades();
|
||||||
|
check.equals(level.getUpgrades(), []);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,5 +108,12 @@ module TK.SpaceTac {
|
||||||
hasUpgrade(upgrade: ShipUpgrade): boolean {
|
hasUpgrade(upgrade: ShipUpgrade): boolean {
|
||||||
return contains(this.upgrades, upgrade.code);
|
return contains(this.upgrades, upgrade.code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all activated upgrades
|
||||||
|
*/
|
||||||
|
clearUpgrades(): void {
|
||||||
|
this.upgrades = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ module TK.SpaceTac.UI {
|
||||||
this.layer_borders, this.getWidth() - 112, 0);
|
this.layer_borders, this.getWidth() - 112, 0);
|
||||||
this.ship_list.bindToLog(this.log_processor);
|
this.ship_list.bindToLog(this.log_processor);
|
||||||
this.ship_tooltip = new ShipTooltip(this);
|
this.ship_tooltip = new ShipTooltip(this);
|
||||||
this.character_sheet = new CharacterSheet(this);
|
this.character_sheet = new CharacterSheet(this, CharacterSheetMode.DISPLAY);
|
||||||
this.layer_sheets.add(this.character_sheet);
|
this.layer_sheets.add(this.character_sheet);
|
||||||
|
|
||||||
// Targetting info
|
// Targetting info
|
||||||
|
@ -286,7 +286,7 @@ module TK.SpaceTac.UI {
|
||||||
if (this.targetting.active) {
|
if (this.targetting.active) {
|
||||||
this.validationPressed();
|
this.validationPressed();
|
||||||
} else if (this.ship_hovered && this.player.is(this.ship_hovered.fleet.player) && this.interacting) {
|
} else if (this.ship_hovered && this.player.is(this.ship_hovered.fleet.player) && this.interacting) {
|
||||||
this.character_sheet.show(this.ship_hovered, CharacterSheetMode.DISPLAY);
|
this.character_sheet.show(this.ship_hovered);
|
||||||
this.setShipHovered(null);
|
this.setShipHovered(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
67
src/ui/character/CharacterPersonality.ts
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
module TK.SpaceTac.UI {
|
||||||
|
/**
|
||||||
|
* Character personality traits editor
|
||||||
|
*/
|
||||||
|
export class CharacterPersonality {
|
||||||
|
private view: BaseView
|
||||||
|
private background: UIImage
|
||||||
|
private name: UIText
|
||||||
|
private ship?: Ship
|
||||||
|
|
||||||
|
constructor(builder: UIBuilder, x: number, y: number) {
|
||||||
|
this.view = builder.view;
|
||||||
|
|
||||||
|
this.background = builder.image("character-personality-background", x, y);
|
||||||
|
builder = builder.in(this.background);
|
||||||
|
|
||||||
|
builder.in(builder.image("character-section-title", 0, 0, false)).text("Pilot", 80, 45, { color: "#dce9f9", size: 32 });
|
||||||
|
|
||||||
|
this.name = builder.in(builder.image("character-name-display", 430, 50, true)).text("", 0, 0, { size: 28 });
|
||||||
|
|
||||||
|
builder.button("character-name-button", 664, 0, () => this.renamePersonality(), "Rename personality");
|
||||||
|
|
||||||
|
builder.text("AVAILABLE SOON !", 690, 528, { size: 20, color: "#a7b3db" });
|
||||||
|
|
||||||
|
builder.styled({ size: 24, color: "#dbeff9" }, builder => {
|
||||||
|
builder.image("character-personality-trait-base", 420, 198, true);
|
||||||
|
builder.text("Courageous", 144, 140);
|
||||||
|
builder.text("Wise", 725, 140);
|
||||||
|
|
||||||
|
builder.image("character-personality-trait-base", 420, 316, true);
|
||||||
|
builder.text("Kind", 144, 268);
|
||||||
|
builder.text("Resilient", 725, 268);
|
||||||
|
|
||||||
|
builder.image("character-personality-trait-base", 420, 444, true);
|
||||||
|
builder.text("Shrewd", 144, 388);
|
||||||
|
builder.text("Funny", 725, 388);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the content to display a ship's personality
|
||||||
|
*/
|
||||||
|
displayShip(ship: Ship) {
|
||||||
|
let builder = new UIBuilder(this.view);
|
||||||
|
this.ship = ship;
|
||||||
|
|
||||||
|
builder.change(this.name, ship.name || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a dialog to rename the ship's personality
|
||||||
|
*/
|
||||||
|
renamePersonality(): void {
|
||||||
|
if (!this.ship) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let ship = this.ship;
|
||||||
|
|
||||||
|
UITextDialog.ask(this.view, "Choose a name for this ship's personality", ship.name || undefined).then(name => {
|
||||||
|
if (bool(name)) {
|
||||||
|
ship.name = name;
|
||||||
|
this.displayShip(ship);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ module TK.SpaceTac.UI.Specs {
|
||||||
test.case("displays fleet and ship information", check => {
|
test.case("displays fleet and ship information", check => {
|
||||||
let view = testgame.view;
|
let view = testgame.view;
|
||||||
check.patch(view, "getWidth", () => 1240);
|
check.patch(view, "getWidth", () => 1240);
|
||||||
let sheet = new CharacterSheet(view);
|
let sheet = new CharacterSheet(view, CharacterSheetMode.DISPLAY);
|
||||||
|
|
||||||
check.equals(sheet.x, -1240);
|
check.equals(sheet.x, -1240);
|
||||||
|
|
||||||
|
@ -17,40 +17,38 @@ module TK.SpaceTac.UI.Specs {
|
||||||
let ship2 = fleet.addShip();
|
let ship2 = fleet.addShip();
|
||||||
ship2.name = "Ship 2";
|
ship2.name = "Ship 2";
|
||||||
|
|
||||||
sheet.show(ship1, undefined, false);
|
sheet.show(ship1, false);
|
||||||
|
|
||||||
check.equals(sheet.x, 0);
|
check.equals(sheet.x, 0);
|
||||||
check.equals(sheet.group_portraits.length, 2);
|
check.equals(sheet.group_portraits.length, 2);
|
||||||
|
|
||||||
check.equals(sheet.text_name.text, "Ship 1");
|
check.equals(sheet.text_name && sheet.text_name.text, "Ship 1");
|
||||||
|
|
||||||
let portrait = as(Phaser.Button, sheet.group_portraits.getChildAt(1));
|
let portrait = as(Phaser.Button, sheet.group_portraits.getChildAt(1));
|
||||||
portrait.onInputUp.dispatch();
|
portrait.onInputUp.dispatch();
|
||||||
|
|
||||||
check.equals(sheet.text_name.text, "Ship 2");
|
check.equals(sheet.text_name && sheet.text_name.text, "Ship 2");
|
||||||
});
|
});
|
||||||
|
|
||||||
test.case("controls global interactivity state", check => {
|
test.case("controls global interactivity state", check => {
|
||||||
let sheet = new CharacterSheet(testgame.view);
|
let sheet = new CharacterSheet(testgame.view, CharacterSheetMode.EDITION);
|
||||||
check.equals(sheet.isInteractive(), false, "no ship");
|
check.equals(sheet.isInteractive(), false, "no ship");
|
||||||
|
|
||||||
let ship = new Ship();
|
let ship = new Ship();
|
||||||
ship.critical = true;
|
ship.critical = true;
|
||||||
sheet.show(ship, CharacterSheetMode.EDITION);
|
sheet.show(ship);
|
||||||
check.equals(sheet.isInteractive(), false, "critical ship");
|
check.equals(sheet.isInteractive(), false, "critical ship");
|
||||||
|
|
||||||
ship.critical = false;
|
ship.critical = false;
|
||||||
sheet.show(ship, CharacterSheetMode.EDITION);
|
sheet.show(ship);
|
||||||
check.equals(sheet.isInteractive(), true, "normal ship");
|
check.equals(sheet.isInteractive(), true, "normal ship");
|
||||||
|
|
||||||
sheet.show(ship, CharacterSheetMode.DISPLAY);
|
sheet = new CharacterSheet(testgame.view, CharacterSheetMode.DISPLAY);
|
||||||
|
sheet.show(ship);
|
||||||
check.equals(sheet.isInteractive(), false, "interactivity disabled");
|
check.equals(sheet.isInteractive(), false, "interactivity disabled");
|
||||||
|
|
||||||
sheet.show(ship, CharacterSheetMode.DISPLAY);
|
sheet.show(ship);
|
||||||
check.equals(sheet.isInteractive(), false, "interactivity stays disabled");
|
check.equals(sheet.isInteractive(), false, "interactivity stays disabled");
|
||||||
|
|
||||||
sheet.show(ship, CharacterSheetMode.EDITION);
|
|
||||||
check.equals(sheet.isInteractive(), true, "interactivity reenabled");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,7 +10,7 @@ module TK.SpaceTac.UI {
|
||||||
*/
|
*/
|
||||||
export class CharacterSheet extends Phaser.Image {
|
export class CharacterSheet extends Phaser.Image {
|
||||||
// Global sheet mode
|
// Global sheet mode
|
||||||
mode: CharacterSheetMode = CharacterSheetMode.DISPLAY
|
mode: CharacterSheetMode
|
||||||
|
|
||||||
// Parent view
|
// Parent view
|
||||||
view: BaseView
|
view: BaseView
|
||||||
|
@ -18,20 +18,20 @@ module TK.SpaceTac.UI {
|
||||||
// UI components builder
|
// UI components builder
|
||||||
builder: UIBuilder
|
builder: UIBuilder
|
||||||
|
|
||||||
|
// Close/validate button
|
||||||
|
close_button: UIButton
|
||||||
|
|
||||||
// X positions
|
// X positions
|
||||||
xshown = 0
|
xshown = 0
|
||||||
xhidden = -2000
|
xhidden = -2000
|
||||||
|
|
||||||
// Groups
|
// Groups
|
||||||
|
group_level: Phaser.Group
|
||||||
group_portraits: Phaser.Group
|
group_portraits: Phaser.Group
|
||||||
group_attributes: Phaser.Image
|
group_attributes: Phaser.Image
|
||||||
group_actions: Phaser.Image
|
group_actions: Phaser.Image
|
||||||
group_upgrades: Phaser.Group
|
group_upgrades: Phaser.Group
|
||||||
|
|
||||||
// Buttons
|
|
||||||
close_button: UIButton
|
|
||||||
rename_button: UIButton
|
|
||||||
|
|
||||||
// Currently displayed fleet
|
// Currently displayed fleet
|
||||||
fleet?: Fleet
|
fleet?: Fleet
|
||||||
|
|
||||||
|
@ -39,33 +39,33 @@ module TK.SpaceTac.UI {
|
||||||
ship?: Ship
|
ship?: Ship
|
||||||
|
|
||||||
// Variable data
|
// Variable data
|
||||||
|
personality?: CharacterPersonality
|
||||||
image_portrait: Phaser.Image
|
image_portrait: Phaser.Image
|
||||||
text_model: Phaser.Text
|
text_model: Phaser.Text
|
||||||
text_description: Phaser.Text
|
text_description: Phaser.Text
|
||||||
text_name: Phaser.Text
|
text_name?: Phaser.Text
|
||||||
text_level: Phaser.Text
|
text_level: Phaser.Text
|
||||||
text_upgrade_points: Phaser.Text
|
text_upgrade_points: Phaser.Text
|
||||||
valuebar_experience: ValueBar
|
valuebar_experience: ValueBar
|
||||||
|
|
||||||
constructor(view: BaseView, onclose?: Function) {
|
constructor(view: BaseView, mode: CharacterSheetMode, onclose?: Function) {
|
||||||
super(view.game, 0, 0, view.getImageInfo("character-sheet").key, view.getImageInfo("character-sheet").frame);
|
super(view.game, 0, 0, view.getImageInfo("character-sheet").key, view.getImageInfo("character-sheet").frame);
|
||||||
|
|
||||||
|
if (!onclose) {
|
||||||
|
onclose = () => this.hide();
|
||||||
|
}
|
||||||
|
|
||||||
this.view = view;
|
this.view = view;
|
||||||
this.builder = new UIBuilder(view, this).styled({ color: "#e7ebf0", size: 16, shadow: true });
|
this.mode = mode;
|
||||||
|
this.builder = new UIBuilder(view, this).styled({ color: "#dce9f9", size: 16, shadow: true });
|
||||||
|
|
||||||
this.xhidden = -this.view.getWidth();
|
this.xhidden = -this.view.getWidth();
|
||||||
this.x = this.xhidden;
|
this.x = this.xhidden;
|
||||||
this.inputEnabled = true;
|
this.inputEnabled = true;
|
||||||
|
|
||||||
if (!onclose) {
|
|
||||||
onclose = () => this.hide();
|
|
||||||
}
|
|
||||||
this.close_button = this.builder.button("character-close-button", 1920, 0, onclose, "Close the character sheet");
|
|
||||||
this.close_button.anchor.set(1, 0);
|
|
||||||
|
|
||||||
this.image_portrait = this.builder.image("translucent", 435, 271, true);
|
this.image_portrait = this.builder.image("translucent", 435, 271, true);
|
||||||
|
|
||||||
this.builder.image("character-entry", 28, 740);
|
this.builder.image("character-entry", 24, 740);
|
||||||
|
|
||||||
this.group_portraits = this.builder.group("portraits", 90, 755);
|
this.group_portraits = this.builder.group("portraits", 90, 755);
|
||||||
|
|
||||||
|
@ -75,27 +75,55 @@ module TK.SpaceTac.UI {
|
||||||
let description_bg = this.builder.image("character-ship-description", 434, 654, true);
|
let description_bg = this.builder.image("character-ship-description", 434, 654, true);
|
||||||
this.text_description = this.builder.in(description_bg).text("", 0, 0, { color: "#a0afc3", width: 510 });
|
this.text_description = this.builder.in(description_bg).text("", 0, 0, { color: "#a0afc3", width: 510 });
|
||||||
|
|
||||||
this.group_attributes = this.builder.image("character-ship-column", 30, 30);
|
this.group_attributes = this.builder.image("character-ship-column-left", 28, 28);
|
||||||
this.group_actions = this.builder.image("character-ship-column", 698, 30);
|
this.group_actions = this.builder.image("character-ship-column-right", 698, 28);
|
||||||
|
|
||||||
let name_bg = this.builder.image("character-name-display", 434, 940, true);
|
this.group_level = this.builder.group("level");
|
||||||
this.text_name = this.builder.in(name_bg).text("", 0, 0, { size: 28 });
|
let points_bg = this.builder.in(this.group_level).image("character-level-upgrades", 582, 986);
|
||||||
|
|
||||||
this.rename_button = this.builder.button("character-name-button", 656, 890, () => this.renamePersonality(), "Rename personality");
|
|
||||||
|
|
||||||
let points_bg = this.builder.image("character-level-upgrades", 582, 986);
|
|
||||||
this.builder.in(points_bg, builder => {
|
this.builder.in(points_bg, builder => {
|
||||||
builder.text("Upgrade points", 46, 10, { center: false, vcenter: false });
|
builder.text("Upgrade points", 46, 10, { center: false, vcenter: false });
|
||||||
builder.image("character-upgrade-point", 147, 59, true);
|
builder.image("character-upgrade-point", 147, 59, true);
|
||||||
});
|
});
|
||||||
this.text_upgrade_points = this.builder.in(points_bg).text("", 106, 60, { size: 28 });
|
this.text_upgrade_points = this.builder.in(points_bg).text("", 106, 60, { size: 28 });
|
||||||
|
|
||||||
let level_bg = this.builder.image("character-level-display", 434, 1032, true);
|
let level_bg = this.builder.in(this.group_level).image("character-level-display", 434, 1032, true);
|
||||||
this.text_level = this.builder.in(level_bg).text("", 0, 4, { size: 28 });
|
this.text_level = this.builder.in(level_bg).text("", 0, 4, { size: 28 });
|
||||||
this.valuebar_experience = this.builder.in(level_bg).valuebar("character-level-experience", -level_bg.width * 0.5, -level_bg.height * 0.5);
|
this.valuebar_experience = this.builder.in(level_bg).valuebar("character-level-experience", -level_bg.width * 0.5, -level_bg.height * 0.5);
|
||||||
|
|
||||||
this.group_upgrades = this.builder.group("upgrades");
|
this.group_upgrades = this.builder.group("upgrades");
|
||||||
|
|
||||||
|
if (this.mode == CharacterSheetMode.CREATION) {
|
||||||
|
this.builder.in(this.builder.image("character-section-title", 180, 30, false)).text("Ship", 80, 45, { color: "#dce9f9", size: 32 });
|
||||||
|
|
||||||
|
this.personality = new CharacterPersonality(this.builder, 950, 30);
|
||||||
|
|
||||||
|
this.close_button = this.builder.button("character-validate-creation", 140, 930, onclose,
|
||||||
|
"Validate the team, and start the campaign", undefined, {
|
||||||
|
hover_bottom: true,
|
||||||
|
text: "Validate team",
|
||||||
|
text_x: 295,
|
||||||
|
text_y: 57,
|
||||||
|
text_style: { size: 32, color: "#fff3df" }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.builder.in(this.builder.image("character-creation-help", 970, 680), builder => {
|
||||||
|
builder.text("Compose your initial team by choosing a model for each ship, and customize the name and personality of the Artificial Intelligence pilot",
|
||||||
|
405, 150, { color: "#a3bbd9", size: 22, width: 500 });
|
||||||
|
});
|
||||||
|
|
||||||
|
this.builder.button("character-model-prev", 216, 500, () => this.changeModel(-1), "Select previous model", undefined, { center: true });
|
||||||
|
this.builder.button("character-model-next", 654, 500, () => this.changeModel(1), "Select next model", undefined, { center: true });
|
||||||
|
|
||||||
|
this.group_level.visible = false;
|
||||||
|
this.group_upgrades.visible = false;
|
||||||
|
} else {
|
||||||
|
this.text_name = this.builder.in(this.builder.image("character-name-display", 434, 940, true)).text("", 0, 0, { size: 28 });
|
||||||
|
|
||||||
|
this.close_button = this.builder.button("character-close-button", 1920, 0, onclose, "Close the character sheet");
|
||||||
|
this.close_button.anchor.set(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
this.refreshUpgrades();
|
this.refreshUpgrades();
|
||||||
this.refreshAttributes();
|
this.refreshAttributes();
|
||||||
this.refreshActions();
|
this.refreshActions();
|
||||||
|
@ -109,20 +137,22 @@ module TK.SpaceTac.UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a dialog to rename the ship's personality
|
* Change the ship model
|
||||||
*/
|
*/
|
||||||
renamePersonality(): void {
|
changeModel(offset: number): void {
|
||||||
if (!this.ship) {
|
if (this.mode == CharacterSheetMode.CREATION && this.ship) {
|
||||||
return;
|
let models = ShipModel.getDefaultCollection();
|
||||||
}
|
|
||||||
let ship = this.ship;
|
|
||||||
|
|
||||||
UITextDialog.ask(this.view, "Choose a name for this ship's personality", ship.name || undefined).then(name => {
|
let idx = models.map(model => model.code).indexOf(this.ship.model.code) + offset;
|
||||||
if (bool(name)) {
|
if (idx < 0) {
|
||||||
ship.name = name;
|
idx = models.length - 1;
|
||||||
this.refreshShipInfo();
|
} else if (idx >= models.length) {
|
||||||
|
idx = 0;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
this.ship.setModel(models[idx]);
|
||||||
|
this.refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,13 +162,17 @@ module TK.SpaceTac.UI {
|
||||||
if (this.ship) {
|
if (this.ship) {
|
||||||
let ship = this.ship;
|
let ship = this.ship;
|
||||||
this.builder.change(this.image_portrait, `ship-${ship.model.code}-portrait`);
|
this.builder.change(this.image_portrait, `ship-${ship.model.code}-portrait`);
|
||||||
this.text_name.setText(ship.name || "");
|
if (this.text_name) {
|
||||||
|
this.text_name.setText(ship.name || "");
|
||||||
|
}
|
||||||
|
if (this.personality) {
|
||||||
|
this.personality.displayShip(ship);
|
||||||
|
}
|
||||||
this.text_model.setText(ship.model.name);
|
this.text_model.setText(ship.model.name);
|
||||||
this.text_level.setText(`Level ${ship.level.get()}`);
|
this.text_level.setText(`Level ${ship.level.get()}`);
|
||||||
this.text_description.setText(ship.model.getDescription());
|
this.text_description.setText(ship.model.getDescription());
|
||||||
this.text_upgrade_points.setText(`${ship.getAvailableUpgradePoints()}`);
|
this.text_upgrade_points.setText(`${ship.getAvailableUpgradePoints()}`);
|
||||||
this.valuebar_experience.setValue(ship.level.getExperience(), ship.level.getNextGoal());
|
this.valuebar_experience.setValue(ship.level.getExperience(), ship.level.getNextGoal());
|
||||||
this.rename_button.visible = this.mode == CharacterSheetMode.CREATION;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +183,7 @@ module TK.SpaceTac.UI {
|
||||||
let builder = this.builder.in(this.group_upgrades);
|
let builder = this.builder.in(this.group_upgrades);
|
||||||
builder.clear();
|
builder.clear();
|
||||||
|
|
||||||
if (!this.ship) {
|
if (!this.ship || this.mode == CharacterSheetMode.CREATION) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let ship = this.ship;
|
let ship = this.ship;
|
||||||
|
@ -196,7 +230,7 @@ module TK.SpaceTac.UI {
|
||||||
center: true,
|
center: true,
|
||||||
vcenter: true,
|
vcenter: true,
|
||||||
size: 28,
|
size: 28,
|
||||||
color: ship.level.get() >= (i + 1) ? "#e7ebf0" : "#808285"
|
color: ship.level.get() >= (i + 1) ? "#dce9f9" : "#293038"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -225,7 +259,7 @@ module TK.SpaceTac.UI {
|
||||||
let builder = this.builder.in(this.group_attributes);
|
let builder = this.builder.in(this.group_attributes);
|
||||||
builder.clear();
|
builder.clear();
|
||||||
|
|
||||||
builder.text("Attributes", 74, 20, { color: "#a0afc3" });
|
builder.text("Attributes", 74, 20, { color: "#a3bbd9" });
|
||||||
|
|
||||||
if (this.ship) {
|
if (this.ship) {
|
||||||
let ship = this.ship;
|
let ship = this.ship;
|
||||||
|
@ -248,7 +282,7 @@ module TK.SpaceTac.UI {
|
||||||
let builder = this.builder.in(this.group_actions);
|
let builder = this.builder.in(this.group_actions);
|
||||||
builder.clear();
|
builder.clear();
|
||||||
|
|
||||||
builder.text("Actions", 74, 20, { color: "#a0afc3" });
|
builder.text("Actions", 74, 20, { color: "#a3bbd9" });
|
||||||
|
|
||||||
if (this.ship) {
|
if (this.ship) {
|
||||||
let ship = this.ship;
|
let ship = this.ship;
|
||||||
|
@ -265,20 +299,20 @@ module TK.SpaceTac.UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the fleet sidebar
|
* Refresh the fleet display
|
||||||
*/
|
*/
|
||||||
updateFleet(fleet: Fleet) {
|
private refreshFleet(): void {
|
||||||
if (fleet !== this.fleet || fleet.ships.length != this.group_portraits.length) {
|
destroyChildren(this.group_portraits);
|
||||||
destroyChildren(this.group_portraits);
|
|
||||||
this.fleet = fleet;
|
|
||||||
|
|
||||||
|
if (this.fleet) {
|
||||||
let builder = this.builder.in(this.group_portraits);
|
let builder = this.builder.in(this.group_portraits);
|
||||||
fleet.ships.forEach((ship, idx) => {
|
this.fleet.ships.forEach((ship, idx) => {
|
||||||
let button: UIButton;
|
let button: UIButton;
|
||||||
button = new CharacterPortrait(ship).draw(builder, 64 + idx * 140, 64, () => {
|
button = new CharacterPortrait(ship).draw(builder, 64 + idx * 140, 64, () => {
|
||||||
if (button) {
|
if (button) {
|
||||||
builder.select(button);
|
builder.select(button);
|
||||||
this.ship = ship;
|
this.ship = ship;
|
||||||
|
|
||||||
this.refreshShipInfo();
|
this.refreshShipInfo();
|
||||||
this.refreshActions();
|
this.refreshActions();
|
||||||
this.refreshAttributes();
|
this.refreshAttributes();
|
||||||
|
@ -303,16 +337,18 @@ module TK.SpaceTac.UI {
|
||||||
/**
|
/**
|
||||||
* Show the sheet for a given ship
|
* Show the sheet for a given ship
|
||||||
*/
|
*/
|
||||||
show(ship: Ship, mode: CharacterSheetMode = CharacterSheetMode.DISPLAY, animate = true, sound = true) {
|
show(ship: Ship, animate = true, sound = true) {
|
||||||
this.ship = ship;
|
this.ship = ship;
|
||||||
this.mode = mode;
|
this.fleet = ship.fleet;
|
||||||
|
|
||||||
this.refreshShipInfo();
|
this.refreshShipInfo();
|
||||||
this.refreshUpgrades();
|
this.refreshUpgrades();
|
||||||
this.refreshAttributes();
|
this.refreshAttributes();
|
||||||
this.refreshActions();
|
this.refreshActions();
|
||||||
|
|
||||||
this.updateFleet(ship.fleet);
|
if (ship.fleet !== this.fleet || ship.fleet.ships.length != this.group_portraits.length) {
|
||||||
|
this.refreshFleet();
|
||||||
|
}
|
||||||
|
|
||||||
if (sound) {
|
if (sound) {
|
||||||
this.view.audio.playOnce("ui-dialog-open");
|
this.view.audio.playOnce("ui-dialog-open");
|
||||||
|
@ -343,7 +379,12 @@ module TK.SpaceTac.UI {
|
||||||
*/
|
*/
|
||||||
refresh() {
|
refresh() {
|
||||||
if (this.ship) {
|
if (this.ship) {
|
||||||
this.show(this.ship, this.mode, false, false);
|
this.refreshShipInfo();
|
||||||
|
this.refreshUpgrades();
|
||||||
|
this.refreshAttributes();
|
||||||
|
this.refreshActions();
|
||||||
|
|
||||||
|
this.refreshFleet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,8 @@ module TK.SpaceTac.UI {
|
||||||
this.built_fleet.addShip(new Ship(null, MissionGenerator.generateCharacterName(), models[1]));
|
this.built_fleet.addShip(new Ship(null, MissionGenerator.generateCharacterName(), models[1]));
|
||||||
this.built_fleet.credits = this.built_fleet.ships.length * 1000;
|
this.built_fleet.credits = this.built_fleet.ships.length * 1000;
|
||||||
|
|
||||||
this.character_sheet = new CharacterSheet(this, () => this.validateFleet());
|
this.character_sheet = new CharacterSheet(this, CharacterSheetMode.CREATION, () => this.validateFleet());
|
||||||
this.character_sheet.show(this.built_fleet.ships[0], CharacterSheetMode.CREATION, false);
|
this.character_sheet.show(this.built_fleet.ships[0], false);
|
||||||
this.getLayer("characters").add(this.character_sheet);
|
this.getLayer("characters").add(this.character_sheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,18 +58,35 @@ module TK.SpaceTac.UI {
|
||||||
* Button options
|
* Button options
|
||||||
*/
|
*/
|
||||||
export type UIButtonOptions = {
|
export type UIButtonOptions = {
|
||||||
|
// Centering
|
||||||
|
center?: boolean
|
||||||
|
|
||||||
// Name of the hover picture (by default, the button name, with "-hover" appended)
|
// Name of the hover picture (by default, the button name, with "-hover" appended)
|
||||||
hover_name?: string
|
hover_name?: string
|
||||||
|
|
||||||
// Name of the "on" picture (by default, the button name, with "-on" appended)
|
// Name of the "on" picture (by default, the button name, with "-on" appended)
|
||||||
on_name?: string
|
on_name?: string
|
||||||
|
|
||||||
|
// Whether "hover" picture should stay near the button (otherwise will be on top)
|
||||||
|
hover_bottom?: boolean
|
||||||
|
|
||||||
|
// Whether "on" picture should stay near the button (otherwise will be on top)
|
||||||
|
on_bottom?: boolean
|
||||||
|
|
||||||
|
// Text content
|
||||||
|
text?: string
|
||||||
|
text_x?: number
|
||||||
|
text_y?: number
|
||||||
|
|
||||||
|
// Text content style override
|
||||||
|
text_style?: UITextStyleI
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main UI builder tool
|
* Main UI builder tool
|
||||||
*/
|
*/
|
||||||
export class UIBuilder {
|
export class UIBuilder {
|
||||||
private view: BaseView
|
view: BaseView
|
||||||
private game: MainUI
|
private game: MainUI
|
||||||
private parent: UIContainer
|
private parent: UIContainer
|
||||||
private text_style: UITextStyle
|
private text_style: UITextStyle
|
||||||
|
@ -201,6 +218,10 @@ module TK.SpaceTac.UI {
|
||||||
let result = new Phaser.Button(this.game, x, y, info.key, undefined, null, info.frame, info.frame);
|
let result = new Phaser.Button(this.game, x, y, info.key, undefined, null, info.frame, info.frame);
|
||||||
result.name = name;
|
result.name = name;
|
||||||
|
|
||||||
|
if (options.center) {
|
||||||
|
result.anchor.set(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
let clickable = bool(onclick);
|
let clickable = bool(onclick);
|
||||||
result.input.useHandCursor = clickable;
|
result.input.useHandCursor = clickable;
|
||||||
if (clickable) {
|
if (clickable) {
|
||||||
|
@ -216,7 +237,7 @@ module TK.SpaceTac.UI {
|
||||||
let on_info = this.view.getImageInfo(options.on_name || (name + "-on"));
|
let on_info = this.view.getImageInfo(options.on_name || (name + "-on"));
|
||||||
if (on_info.exists) {
|
if (on_info.exists) {
|
||||||
on_mask = new Phaser.Image(this.game, 0, 0, on_info.key, on_info.frame);
|
on_mask = new Phaser.Image(this.game, 0, 0, on_info.key, on_info.frame);
|
||||||
on_mask.name = "*on*";
|
on_mask.name = options.on_bottom ? "on" : "*on*";
|
||||||
on_mask.visible = false;
|
on_mask.visible = false;
|
||||||
result.addChild(on_mask);
|
result.addChild(on_mask);
|
||||||
}
|
}
|
||||||
|
@ -236,7 +257,7 @@ module TK.SpaceTac.UI {
|
||||||
let hover_mask: Phaser.Image | null = null;
|
let hover_mask: Phaser.Image | null = null;
|
||||||
if (hover_info.exists) {
|
if (hover_info.exists) {
|
||||||
hover_mask = new Phaser.Image(this.game, 0, 0, hover_info.key, hover_info.frame);
|
hover_mask = new Phaser.Image(this.game, 0, 0, hover_info.key, hover_info.frame);
|
||||||
hover_mask.name = "*hover*";
|
hover_mask.name = options.hover_bottom ? "hover" : "*hover*";
|
||||||
hover_mask.visible = false;
|
hover_mask.visible = false;
|
||||||
result.addChild(hover_mask);
|
result.addChild(hover_mask);
|
||||||
}
|
}
|
||||||
|
@ -268,6 +289,10 @@ module TK.SpaceTac.UI {
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.text) {
|
||||||
|
this.in(result).text(options.text, options.text_x || 0, options.text_y || 0, options.text_style);
|
||||||
|
}
|
||||||
|
|
||||||
this.add(result);
|
this.add(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ module TK.SpaceTac.UI {
|
||||||
this.button_options = builder.button("map-options", 1628, 0, () => this.showOptions(), "Game options");
|
this.button_options = builder.button("map-options", 1628, 0, () => this.showOptions(), "Game options");
|
||||||
});
|
});
|
||||||
|
|
||||||
this.character_sheet = new CharacterSheet(this);
|
this.character_sheet = new CharacterSheet(this, CharacterSheetMode.EDITION);
|
||||||
this.layer_overlay.add(this.character_sheet);
|
this.layer_overlay.add(this.character_sheet);
|
||||||
|
|
||||||
this.conversation = new MissionConversationDisplay(this);
|
this.conversation = new MissionConversationDisplay(this);
|
||||||
|
@ -165,7 +165,7 @@ module TK.SpaceTac.UI {
|
||||||
this.backToRouter();
|
this.backToRouter();
|
||||||
} else {
|
} else {
|
||||||
this.setZoom(this.zoom);
|
this.setZoom(this.zoom);
|
||||||
this.character_sheet.updateFleet(this.player.fleet);
|
this.character_sheet.refresh();
|
||||||
this.player_fleet.updateShipSprites();
|
this.player_fleet.updateShipSprites();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ module TK.SpaceTac.UI {
|
||||||
openShop(): void {
|
openShop(): void {
|
||||||
let location = this.session.getLocation();
|
let location = this.session.getLocation();
|
||||||
if (this.interactive && location && location.shop) {
|
if (this.interactive && location && location.shop) {
|
||||||
this.character_sheet.show(this.player.fleet.ships[0], CharacterSheetMode.EDITION);
|
this.character_sheet.show(this.player.fleet.ships[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|