1
0
Fork 0

character sheet: Added tooltips for attributes with description and sources (WIP)

This commit is contained in:
Michaël Lemaire 2017-07-13 01:18:20 +02:00
parent 1c45602586
commit b8bfbb8063
7 changed files with 154 additions and 76 deletions

View File

@ -26,7 +26,7 @@ Character sheet
* Highlight allowed destinations during drag-and-drop, with text hints
* When transferring to another ship, if the item can't be equipped (unmatched requirements), the transfer is cancelled instead of trying cargo
* Effective skill is sometimes not updated when upgrading base skill
* Tooltip to show the sources of attributes
* Tooltip to show the sources of attributes [WIP]
* Forbid to modify escorted ship
* Add merged cargo display for the whole fleet

View File

@ -576,5 +576,25 @@ module TS.SpaceTac.Specs {
new AttributeLimitEffect("precision", 2)
]);
});
it("gets a textual description of an attribute", function () {
let ship = new Ship();
expect(ship.getAttributeDescription("skill_photons")).toEqual("Forces of light, and electromagnetic radiation");
let equipment = new Equipment(SlotType.Engine);
equipment.effects = [new AttributeEffect("skill_photons", 4)];
equipment.name = "Photonic engine";
ship.addSlot(SlotType.Engine).attach(equipment);
expect(ship.getAttribute("skill_photons")).toBe(4);
expect(ship.getAttributeDescription("skill_photons")).toEqual("Forces of light, and electromagnetic radiation\n\nPhotonic engine Mk1: +4");
ship.level.forceLevelUp();
ship.upgradeSkill("skill_photons");
ship.upgradeSkill("skill_photons");
expect(ship.getAttributeDescription("skill_photons")).toEqual("Forces of light, and electromagnetic radiation\n\nLevelled up: +2\nPhotonic engine Mk1: +4");
ship.addStickyEffect(new StickyEffect(new AttributeLimitEffect("skill_photons", 3)));
expect(ship.getAttributeDescription("skill_photons")).toEqual("Forces of light, and electromagnetic radiation\n\nLevelled up: +2\nPhotonic engine Mk1: +4\n???: limit to 3");
});
});
}

View File

@ -1,55 +1,4 @@
/// <reference path="ShipAttribute.ts"/>
/// <reference path="ShipValue.ts"/>
module TS.SpaceTac {
/**
* Set of upgradable skills for a ship
*/
export class ShipSkills {
// Skills
skill_materials = new ShipAttribute("materials skill")
skill_photons = new ShipAttribute("photons skill")
skill_antimatter = new ShipAttribute("antimatter skill")
skill_quantum = new ShipAttribute("quantum skill")
skill_gravity = new ShipAttribute("gravity skill")
skill_time = new ShipAttribute("time skill")
}
/**
* Set of ShipAttribute for a ship
*/
export class ShipAttributes extends ShipSkills {
// Maximal hull value
hull_capacity = new ShipAttribute("hull capacity")
// Maximal shield value
shield_capacity = new ShipAttribute("shield capacity")
// Maximal power value
power_capacity = new ShipAttribute("power capacity")
// Power value recovered each turn
power_generation = new ShipAttribute("power generation")
// Ability to move first and fast
maneuvrability = new ShipAttribute("maneuvrability")
// Ability to fire far and good
precision = new ShipAttribute("precision")
}
/**
* Set of ShipValue for a ship
*/
export class ShipValues {
hull = new ShipValue("hull")
shield = new ShipValue("shield")
power = new ShipValue("power")
}
/**
* Static attributes and values object for name queries
*/
export const SHIP_SKILLS = new ShipSkills();
export const SHIP_ATTRIBUTES = new ShipAttributes();
export const SHIP_VALUES = new ShipValues();
/**
* A single ship in a fleet
*/
@ -783,5 +732,42 @@ module TS.SpaceTac {
private collectEffects(code: string): BaseEffect[] {
return imaterialize(ifilter(this.ieffects(), effect => effect.code == code));
}
/**
* Get a textual description of an attribute, and the origin of its value
*/
getAttributeDescription(attribute: keyof ShipAttributes): string {
let result = this.attributes[attribute].description;
let diffs: string[] = [];
let limits: string[] = [];
function addEffect(base: string, effect: BaseEffect) {
if (effect instanceof AttributeEffect && effect.attrcode == attribute) {
diffs.push(`${base}: ${effect.value > 0 ? "+" + effect.value.toString() : effect.value}`);
} else if (effect instanceof AttributeLimitEffect && effect.attrcode == attribute) {
limits.push(`${base}: limit to ${effect.value}`);
}
}
if (attribute in this.skills) {
let skill = this.skills[<keyof ShipSkills>attribute];
if (skill.get()) {
diffs.push(`Levelled up: +${skill.get()}`);
}
}
this.slots.forEach(slot => {
if (slot.attached) {
let equipment = slot.attached;
equipment.effects.forEach(effect => addEffect(equipment.getFullName(), effect));
}
});
this.sticky_effects.forEach(effect => addEffect("???", effect.base));
let sources = diffs.concat(limits).join("\n");
return sources ? (result + "\n\n" + sources) : result;
}
}
}

View File

@ -1,16 +0,0 @@
/// <reference path="ShipValue.ts"/>
module TS.SpaceTac {
/**
* A ship attribute is a value computed by a sum of contributions from equipments and sticky effects.
*
* A value may be limited by other effects.
*/
export class ShipAttribute extends ShipValue {
// Raw contributions value (without limits)
private raw = 0
// Temporary limits
private limits: number[] = []
}
}

View File

@ -1,4 +1,19 @@
module TS.SpaceTac {
const SHIP_VALUES_DESCRIPTIONS: { [name: string]: string } = {
"materials skill": "Usage of physical materials such as bullets, shells...",
"photons skill": "Forces of light, and electromagnetic radiation",
"antimatter skill": "Manipulation of matter and antimatter particles",
"quantum skill": "Application of quantum uncertainty principle",
"gravity skill": "Interaction with gravitational forces",
"time skill": "Control of relativity's time properties",
"hull capacity": "Maximal Hull value before the ship risks collapsing",
"shield capacity": "Maximal Shield value to protect the hull from damage",
"power capacity": "Maximal Power value to use equipment",
"power generation": "Power generated at the end of the ship's turn",
"maneuvrability": "Ability to move first and fast",
"precision": "Ability to target far and good",
}
/**
* A ship value is a number that may vary and be constrained in a given range.
*/
@ -18,6 +33,10 @@ module TS.SpaceTac {
this.maximal = maximal;
}
get description(): string {
return SHIP_VALUES_DESCRIPTIONS[this.name];
}
/**
* Get the current value
*/
@ -76,4 +95,64 @@ module TS.SpaceTac {
}
}
}
/**
* A ship attribute is a value computed by a sum of contributions from equipments and sticky effects.
*
* A value may be limited by other effects.
*/
export class ShipAttribute extends ShipValue {
// Raw contributions value (without limits)
private raw = 0
// Temporary limits
private limits: number[] = []
}
/**
* Set of upgradable skills for a ship
*/
export class ShipSkills {
// Skills
skill_materials = new ShipAttribute("materials skill")
skill_photons = new ShipAttribute("photons skill")
skill_antimatter = new ShipAttribute("antimatter skill")
skill_quantum = new ShipAttribute("quantum skill")
skill_gravity = new ShipAttribute("gravity skill")
skill_time = new ShipAttribute("time skill")
}
/**
* Set of ShipAttribute for a ship
*/
export class ShipAttributes extends ShipSkills {
// Maximal hull value
hull_capacity = new ShipAttribute("hull capacity")
// Maximal shield value
shield_capacity = new ShipAttribute("shield capacity")
// Maximal power value
power_capacity = new ShipAttribute("power capacity")
// Power value recovered each turn
power_generation = new ShipAttribute("power generation")
// Ability to move first and fast
maneuvrability = new ShipAttribute("maneuvrability")
// Ability to fire far and good
precision = new ShipAttribute("precision")
}
/**
* Set of ShipValue for a ship
*/
export class ShipValues {
hull = new ShipValue("hull")
shield = new ShipValue("shield")
power = new ShipValue("power")
}
/**
* Static attributes and values object for name queries
*/
export const SHIP_SKILLS = new ShipSkills();
export const SHIP_ATTRIBUTES = new ShipAttributes();
export const SHIP_VALUES = new ShipValues();
}

View File

@ -158,22 +158,30 @@ module TS.SpaceTac.UI {
let attrname = capitalize(SHIP_ATTRIBUTES[attribute].name);
let name = new Phaser.Text(this.game, x - 144, y - 2, attrname,
{ align: "center", font: "20pt Arial", fill: "#c9d8ef", stroke: "#395665", strokeThickness: 1 });
name.anchor.set(0.5, 0.5);
name.anchor.set(0.5);
this.addChild(name);
let text = new Phaser.Text(this.game, x, y, "",
{ align: "center", font: "bold 18pt Arial", fill: "#FFFFFF" });
text.anchor.set(0.5, 0.5);
this.addChild(text);
let button_value = new Phaser.Button(this.game, x, y, "common-transparent");
button_value.input.useHandCursor = false;
button_value.anchor.set(0.5);
button_value.width = 58;
button_value.height = 42;
this.addChild(button_value);
this.view.tooltip.bindDynamicText(button_value, () => this.ship.getAttributeDescription(attribute));
this.attributes[attribute] = text;
let value = new Phaser.Text(this.game, x, y, "",
{ align: "center", font: "bold 18pt Arial", fill: "#FFFFFF" });
value.anchor.set(0.5);
this.addChild(value);
this.attributes[attribute] = value;
if (SHIP_SKILLS.hasOwnProperty(attribute)) {
let button = new Phaser.Button(this.game, x + 54, y - 4, "character-skill-upgrade", () => {
this.ship.upgradeSkill(<keyof ShipSkills>attribute);
this.refresh();
});
button.anchor.set(0.5, 0.5);
button.anchor.set(0.5);
this.ship_upgrades.add(button);
this.view.tooltip.bindStaticText(button, `Spend one point to upgrade ${attrname}`);

View File

@ -12,7 +12,8 @@ module TS.SpaceTac.UI {
this.sheet = sheet;
let sloticon = new Phaser.Button(this.game, 150, 150, `character-slot-${SlotType[slot].toLowerCase()}`);
let sloticon = new Phaser.Button(this.game, 150, 150, `character-slots`);
sloticon.frame = slot;
sloticon.anchor.set(0.5, 0.5);
this.addChild(sloticon);
sheet.view.tooltip.bindStaticText(sloticon, `${SlotType[slot]} slot`);