1
0
Fork 0

Ship tooltip now displays precision and maneuvrability

This commit is contained in:
Michaël Lemaire 2017-12-11 01:31:16 +01:00
parent 231484f7a8
commit 0197fad710
23 changed files with 1813 additions and 566 deletions

View File

@ -36,7 +36,6 @@ Character sheet
Battle
------
* Display precision and maneuvrability in ship tooltip
* Add a voluntary retreat option
* Add scroll buttons when there are too many actions
* Toggle bar/text display in power section of action bar

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 32 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 323 KiB

After

Width:  |  Height:  |  Size: 361 KiB

View File

@ -109,6 +109,44 @@ module TK.SpaceTac.UI.Specs {
});
}
/**
* Crawn through the children of a node
*/
export function crawlChildren(node: UIContainer, recursive: boolean, callback: (child: any) => void): void {
node.children.forEach(child => {
callback(child);
if (recursive && (child instanceof Phaser.Group || child instanceof Phaser.Image)) {
crawlChildren(child, true, callback);
}
});
}
/**
* Collect all image codes in a node
*/
export function collectImages(node: UIContainer, recursive = true): (string | null)[] {
let result: (string | null)[] = [];
crawlChildren(node, recursive, child => {
if (child instanceof Phaser.Image) {
result.push(child.name || null);
}
});
return result;
}
/**
* Collect all texts in a node
*/
export function collectTexts(node: UIContainer, recursive = true): (string | null)[] {
let result: (string | null)[] = [];
crawlChildren(node, recursive, child => {
if (child instanceof Phaser.Text) {
result.push(child.text || null);
}
});
return result;
}
/**
* Check a given text node
*/

View File

@ -18,21 +18,21 @@ module TK.SpaceTac.UI.Specs {
let action3 = new EndTurnAction();
check.patch(action3, "getVerb", () => "End turn");
ActionTooltip.fill(tooltip.getFiller(), ship, action1, 0);
ActionTooltip.fill(tooltip.getBuilder(), ship, action1, 0);
checkText(check, (<any>tooltip).container.content.children[1], "Engine");
checkText(check, (<any>tooltip).container.content.children[2], "Cost: 1 power per 0km");
checkText(check, (<any>tooltip).container.content.children[3], "Move: 0km per power point (safety: 120km)");
checkText(check, (<any>tooltip).container.content.children[4], "[ 1 ]");
tooltip.hide();
ActionTooltip.fill(tooltip.getFiller(), ship, action2, 1);
ActionTooltip.fill(tooltip.getBuilder(), ship, action2, 1);
checkText(check, (<any>tooltip).container.content.children[1], "Weapon");
checkText(check, (<any>tooltip).container.content.children[2], "Cost: 2 power");
checkText(check, (<any>tooltip).container.content.children[3], "Fire (power 2, range 50km):\n• do 12 damage on target");
checkText(check, (<any>tooltip).container.content.children[4], "[ 2 ]");
tooltip.hide();
ActionTooltip.fill(tooltip.getFiller(), ship, action3, 2);
ActionTooltip.fill(tooltip.getBuilder(), ship, action3, 2);
checkText(check, (<any>tooltip).container.content.children[1], "End turn");
checkText(check, (<any>tooltip).container.content.children[2], "End the current ship's turn.\nWill also generate power and cool down equipments.");
checkText(check, (<any>tooltip).container.content.children[3], "[ space ]");

View File

@ -6,7 +6,7 @@ module TK.SpaceTac.UI {
/**
* Fill the tooltip
*/
static fill(filler: TooltipFiller, ship: Ship, action: BaseAction, position: number) {
static fill(filler: TooltipBuilder, ship: Ship, action: BaseAction, position: number) {
let builder = filler.styled({ size: 20 });
let icon = builder.image([`equipment-${action.equipment ? action.equipment.code : "---"}`, `action-${action.code}`]);
@ -40,17 +40,17 @@ module TK.SpaceTac.UI {
if (action.equipment && action.equipment.cooldown.overheat) {
let cooldown = action.equipment.cooldown;
if (cooldown.heat > 0) {
builder.text("Cooling down ...", 150, 80, { color: "#c9604c" });
builder.text("Cooling down ...", 150, 80, { color: "#d8894d" });
} else if (cooldown.willOverheat() && cost != "Not enough power") {
if (cooldown.cooling > 1) {
let turns = cooldown.cooling - 1;
builder.text(`Unavailable for ${turns} turn${turns > 1 ? "s" : ""} if used`, 150, 80, { color: "#c9604c" });
builder.text(`Unavailable for ${turns} turn${turns > 1 ? "s" : ""} if used`, 150, 80, { color: "#d8894d" });
} else {
builder.text("Unavailable until next turn if used", 150, 80, { color: "#c9604c" });
builder.text("Unavailable until next turn if used", 150, 80, { color: "#d8894d" });
}
}
} else if (action instanceof ToggleAction && action.activated) {
builder.text(`Activated`, 150, 80, { color: "#c9604c" });
builder.text(`Activated`, 150, 80, { color: "#dbe748" });
}
let description = action.getEffectsDescription();

View File

@ -12,24 +12,26 @@ module TK.SpaceTac.UI.Specs {
TestTools.setShipHP(ship, 58, 140);
TestTools.setShipAP(ship, 12);
TestTools.addWeapon(ship, 50);
TestTools.setAttribute(ship, "precision", 7);
TestTools.setAttribute(ship, "maneuvrability", 3);
ship.setValue("hull", 57);
ship.setValue("shield", 100);
ship.setValue("power", 9);
ship.active_effects.add(new AttributeEffect("hull_capacity", 50));
ship.active_effects.add(new StickyEffect(new DamageModifierEffect(-15), 3));
ship.active_effects.add(new AttributeLimitEffect("precision", 10));
tooltip.setShip(ship);
let content = (<any>tooltip).container.content;
check.equals(content.children[0].name, "ship-fake-portrait");
check.equals(content.children[1].text, "Phil's Level 1 Fury");
check.equals(content.children[2].text, "Plays in 2 turns");
check.equals(content.children[3].text, "Hull\n58/58");
check.equals(content.children[4].text, "Shield\n140/140");
check.equals(content.children[5].text, "Power\n12/12");
check.equals(content.children[6].text, "Active effects");
check.equals(content.children[7].text, "• hull capacity +50");
check.equals(content.children[8].text, "• damage -15% for 3 turns");
check.equals(content.children[9].text, "• limit precision to 10");
check.equals(content.children[10].text, "Weapons");
check.equals(content.children[11].text, "• equipment Mk1");
let images = collectImages((<any>tooltip).container);
let texts = collectTexts((<any>tooltip).container);
check.contains(images, "ship-fake-portrait");
check.contains(images, "equipment-equipment");
check.equals(texts, [
"Phil's Level 1 Fury", "Plays in 2 turns",
"7", "3", "9", "max", "12", "57", "max", "58", "100", "max", "140",
"Active effects", "• hull capacity +50", "• damage -15% for 3 turns", "• limit precision to 10",
"Weapons", "equipment Mk1"
]);
});
});
}

View File

@ -19,47 +19,54 @@ module TK.SpaceTac.UI {
setShip(ship: Ship): void {
this.hide();
let filler = this.getFiller();
let builder = this.getBuilder();
filler.configure(10, 6, this.battleview.arena.getBoundaries());
builder.configure(10, 6, this.battleview.arena.getBoundaries());
let portrait = filler.image(`ship-${ship.model.code}-portrait`);
portrait.scale.set(0.5);
let portrait_bg = builder.image("battle-tooltip-ship-portrait");
builder.in(portrait_bg, builder => {
let portrait = builder.image(`ship-${ship.model.code}-portrait`, portrait_bg.width / 2, portrait_bg.height / 2);
portrait.anchor.set(0.5);
portrait.scale.set(0.5);
});
let enemy = !ship.getPlayer().is(this.battleview.player);
filler.text(ship.getFullName(), 140, 0, { color: enemy ? "#cc0d00" : "#ffffff", size: 22, bold: true });
builder.text(ship.getFullName(), 168, 0, { color: enemy ? "#cc0d00" : "#ffffff", size: 22, bold: true });
if (ship.alive) {
let turns = this.battleview.battle.getPlayOrder(ship);
filler.text((turns == 0) ? "Playing" : ((turns == 1) ? "Plays next" : `Plays in ${turns} turns`), 140, 36, { color: "#cccccc", size: 18 });
builder.text((turns == 0) ? "Playing" : ((turns == 1) ? "Plays next" : `Plays in ${turns} turns`), 168, 36, { color: "#cccccc", size: 18 });
let hsp_builder = filler.styled({ color: "#eb4e4a", size: 20, center: true, vcenter: true, bold: true });
hsp_builder.text(`Hull\n${ship.getValue("hull")}/${ship.getAttribute("hull_capacity")}`, 200, 106, { color: "#eb4e4a" });
hsp_builder.text(`Shield\n${ship.getValue("shield")}/${ship.getAttribute("shield_capacity")}`, 340, 106, { color: "#2ad8dc" });
hsp_builder.text(`Power\n${ship.getValue("power")}/${ship.getAttribute("power_capacity")}`, 480, 106, { color: "#ffdd4b" });
ShipTooltip.addValue(builder, 0, "#aa6f33", "character-attribute-precision", ship.getAttribute("precision"));
ShipTooltip.addValue(builder, 1, "#c1f06b", "character-attribute-maneuvrability", ship.getAttribute("maneuvrability"));
ShipTooltip.addValue(builder, 2, "#ffdd4b", "character-value-power", ship.getValue("power"), ship.getAttribute("power_capacity"));
ShipTooltip.addValue(builder, 3, "#eb4e4a", "character-value-hull", ship.getValue("hull"), ship.getAttribute("hull_capacity"));
ShipTooltip.addValue(builder, 4, "#2ad8dc", "character-value-shield", ship.getValue("shield"), ship.getAttribute("shield_capacity"));
let iy = 148;
let iy = 170;
let effects = ship.active_effects.list();
if (effects.length > 0) {
filler.text("Active effects", 0, iy, { color: "#ffffff", size: 18, bold: true });
builder.text("Active effects", 0, iy, { color: "#ffffff", size: 18, bold: true });
iy += 30;
effects.forEach(effect => {
filler.text(`${effect.getDescription()}`, 0, iy, { color: effect.isBeneficial() ? "#afe9c6" : "#e9afaf" });
builder.text(`${effect.getDescription()}`, 0, iy, { color: effect.isBeneficial() ? "#afe9c6" : "#e9afaf" });
iy += 26;
});
}
let weapons = ship.listEquipment(SlotType.Weapon);
if (weapons.length > 0) {
filler.text("Weapons", 0, iy, { size: 18, bold: true });
builder.text("Weapons", 0, iy, { size: 18, bold: true });
iy += 30;
weapons.forEach(weapon => {
filler.text(`${weapon.getFullName()}`, 0, iy);
let icon = builder.image(`equipment-${weapon.code}`, 0, iy);
icon.scale.set(0.1);
builder.text(weapon.getFullName(), 32, iy);
iy += 26;
});
}
} else {
filler.text("Emergency Stasis Protocol\nship disabled", 140, 36, { color: "#a899db", size: 20, center: true, vcenter: true });
builder.text("Emergency Stasis Protocol\nship disabled", 140, 36, { color: "#a899db", size: 20, center: true, vcenter: true });
}
let sprite = this.battleview.arena.findShipSprite(ship);
@ -67,5 +74,18 @@ module TK.SpaceTac.UI {
this.container.show(sprite.frame.getBounds());
}
}
private static addValue(builder: UIBuilder, idx: number, color: string, icon: string, val: number, max?: number) {
let bg = builder.image("battle-tooltip-ship-value", 190 + idx * 72, 110, true);
builder.in(bg).styled({ color: color, size: 18, center: true, vcenter: true, bold: true }, builder => {
builder.image(icon, 0, -14, true);
builder.text(`${val}`, 0, 28);
if (max) {
builder.text("max", 0, 58, { size: 10 });
builder.text(`${max}`, 0, 72, { size: 10 });
}
});
}
}
}

View File

@ -200,7 +200,7 @@ module TK.SpaceTac.UI {
/**
* Fill a tooltip with equipment data
*/
fillTooltip(filler: TooltipFiller): boolean {
fillTooltip(filler: TooltipBuilder): boolean {
let title = this.item.getFullName();
if (this.item.slot_type !== null) {
title += ` (${SlotType[this.item.slot_type]})`;

View File

@ -77,13 +77,14 @@ module TK.SpaceTac.UI {
/**
* Functions used to fill a tooltip content
*/
export class TooltipFiller extends UIBuilder {
export class TooltipBuilder extends UIBuilder {
private container: TooltipContainer;
constructor(container: TooltipContainer) {
let style = new UITextStyle();
style.center = false;
style.vcenter = false;
style.shadow = true;
super(container.view, container.content, style);
this.container = container;
@ -118,10 +119,10 @@ module TK.SpaceTac.UI {
}
/**
* Get a tooltip filler
* Get a tooltip builder
*/
getFiller(): TooltipFiller {
return new TooltipFiller(this.container);
getBuilder(): TooltipBuilder {
return new TooltipBuilder(this.container);
}
/**
@ -129,12 +130,12 @@ module TK.SpaceTac.UI {
*
* When the component is hovered, the function is called to allow filling the tooltip container
*/
bind(obj: Phaser.Button, func: (filler: TooltipFiller) => boolean): void {
bind(obj: Phaser.Button, func: (filler: TooltipBuilder) => boolean): void {
this.view.inputs.setHoverClick(obj,
// enter
() => {
this.hide();
if (func(this.getFiller())) {
if (func(this.getBuilder())) {
this.container.show(obj.getBounds());
}
},

View File

@ -160,7 +160,7 @@ module TK.SpaceTac.UI {
/**
* Add an image
*/
image(name: string | string[], x = 0, y = 0): UIImage {
image(name: string | string[], x = 0, y = 0, centered = false): UIImage {
if (typeof name != "string") {
name = this.view.getFirstImage(...name);
}
@ -168,6 +168,9 @@ module TK.SpaceTac.UI {
let info = this.view.getImageInfo(name);
let result = this.game.add.image(x, y, info.key, info.frame);
result.name = name;
if (centered) {
result.anchor.set(0.5)
}
this.add(result);
return result;
}