character sheet: Added info message when dragging equipment
This commit is contained in:
parent
c548793523
commit
4e498cbdbd
9
TODO.md
9
TODO.md
|
@ -25,8 +25,7 @@ Character sheet
|
|||
|
||||
* Disable interaction during battle (except for loot screen)
|
||||
* Improve eye-catching for shop and loot section
|
||||
* Highlight allowed destinations during drag-and-drop, with text hints (for success or error)
|
||||
* When transferring to another ship, if the item can't be equipped (unmatched requirements), the transfer is cancelled instead of trying cargo
|
||||
* Highlight allowed destinations during drag-and-drop
|
||||
* Effective skill is sometimes not updated when upgrading base skill
|
||||
* Add merged cargo display for the whole fleet
|
||||
* Allow to change/buy ship model
|
||||
|
@ -34,6 +33,7 @@ Character sheet
|
|||
* Allow to cancel spent skill points (and confirm when closing the sheet)
|
||||
* Add filters and sort options for cargo and shop
|
||||
* Display level and slot type on equipment
|
||||
* Fixed tooltips not being visible in loot mode (at the end of battle)
|
||||
|
||||
Battle
|
||||
------
|
||||
|
@ -93,7 +93,6 @@ Artificial Intelligence
|
|||
Common UI
|
||||
---------
|
||||
|
||||
* Split atlases by asset stage
|
||||
* UIBuilder.button should be able to handle hover and pushed images
|
||||
* If ProgressiveMessage animation performance is bad, show the text directly
|
||||
* Add caret/focus to text input
|
||||
|
@ -104,8 +103,9 @@ Common UI
|
|||
Technical
|
||||
---------
|
||||
|
||||
* Pack all images in atlases
|
||||
* Pack all images in atlases, and split them by stage
|
||||
* Pack sounds
|
||||
* Use shaders for backgrounds, with fallback images
|
||||
* Replace jasmine with mocha+chai
|
||||
|
||||
Network
|
||||
|
@ -126,7 +126,6 @@ Postponed
|
|||
* Formation or deployment phase
|
||||
* Add ship personality (with icons to identify?), with reaction dialogs
|
||||
* New battle internal flow: any game state change should be done through revertable events
|
||||
* Animated arena background, instead of big picture
|
||||
* Hide enemy information (shield, hull, weapons), until they are in play, or until a "spy" effect is used
|
||||
* Invocation/reinforcements (need to up the 10 ships limit)
|
||||
* Dynamic music composition
|
||||
|
|
|
@ -124,8 +124,8 @@ module TK.SpaceTac {
|
|||
*
|
||||
* This does not check where the equipment currently is (except if is it already attached and should be detached first).
|
||||
*/
|
||||
canBeEquipped(skills: ShipAttributes): boolean {
|
||||
if (this.attached_to) {
|
||||
canBeEquipped(skills: ShipAttributes, check_unattached = true): boolean {
|
||||
if (check_unattached && this.attached_to) {
|
||||
return false;
|
||||
} else {
|
||||
var able = true;
|
||||
|
|
|
@ -12,18 +12,18 @@ module TK.SpaceTac.UI.Specs {
|
|||
let equipment = new CharacterEquipment(sheet, new Equipment(), source);
|
||||
|
||||
let destination = new CharacterCargo(sheet, 0, 0);
|
||||
expect(destination.addEquipment(equipment, null, true)).toBe(false);
|
||||
expect(destination.addEquipment(equipment, null, true)).toEqual({ success: false, info: 'put in cargo', error: 'not enough cargo space' });
|
||||
ship.setCargoSpace(1);
|
||||
expect(destination.addEquipment(equipment, null, true)).toBe(true);
|
||||
expect(destination.addEquipment(equipment, null, true)).toEqual({ success: true, info: 'put in cargo' });
|
||||
ship.critical = true;
|
||||
expect(destination.addEquipment(equipment, null, true)).toBe(false);
|
||||
expect(destination.addEquipment(equipment, null, true)).toEqual({ success: false, info: 'put in cargo', error: 'not a fleet member' });
|
||||
ship.critical = false;
|
||||
|
||||
expect(source.removeEquipment(equipment, null, true)).toBe(false);
|
||||
expect(source.removeEquipment(equipment, null, true)).toEqual({ success: false, info: 'remove from cargo', error: 'not in cargo!' });
|
||||
ship.addCargo(equipment.item);
|
||||
expect(source.removeEquipment(equipment, null, true)).toBe(true);
|
||||
expect(source.removeEquipment(equipment, null, true)).toEqual({ success: true, info: 'remove from cargo' });
|
||||
ship.critical = true;
|
||||
expect(source.removeEquipment(equipment, null, true)).toBe(false);
|
||||
expect(source.removeEquipment(equipment, null, true)).toEqual({ success: false, info: 'remove from cargo', error: 'not a fleet member' });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -35,30 +35,34 @@ module TK.SpaceTac.UI {
|
|||
getPriceOffset(): number {
|
||||
return 66;
|
||||
}
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
let info = "put in cargo";
|
||||
if (this.sheet.ship.critical) {
|
||||
return false;
|
||||
return { success: false, info: info, error: "not a fleet member" };
|
||||
} if (this.sheet.ship.getFreeCargoSpace() > 0) {
|
||||
if (test) {
|
||||
return true;
|
||||
return { success: true, info: info };
|
||||
} else {
|
||||
return this.sheet.ship.addCargo(equipment.item);
|
||||
let success = this.sheet.ship.addCargo(equipment.item);
|
||||
return { success: success, info: info };
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return { success: false, info: info, error: "not enough cargo space" };
|
||||
}
|
||||
}
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
let info = "remove from cargo";
|
||||
if (this.sheet.ship.critical) {
|
||||
return false;
|
||||
return { success: false, info: info, error: "not a fleet member" };
|
||||
} else if (contains(this.sheet.ship.cargo, equipment.item)) {
|
||||
if (test) {
|
||||
return true;
|
||||
return { success: true, info: info };
|
||||
} else {
|
||||
return this.sheet.ship.removeCargo(equipment.item);
|
||||
let success = this.sheet.ship.removeCargo(equipment.item);
|
||||
return { success: success, info: info };
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return { success: false, info: info, error: "not in cargo!" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,41 +23,45 @@ module TK.SpaceTac.UI.Specs {
|
|||
getPriceOffset(): number {
|
||||
return 12;
|
||||
}
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
if (this.x < 150) {
|
||||
if (!test) {
|
||||
this.inside = equipment;
|
||||
}
|
||||
return true;
|
||||
return { success: true, info: "" };
|
||||
} else {
|
||||
return false;
|
||||
return { success: false, info: "" };
|
||||
}
|
||||
}
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
if (this.inside === equipment) {
|
||||
if (!test) {
|
||||
this.inside = null;
|
||||
}
|
||||
return true;
|
||||
return { success: true, info: "" };
|
||||
} else {
|
||||
return false;
|
||||
return { success: false, info: "" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it("handles drag-and-drop to move equipment", function () {
|
||||
function createBasicCase(positions: number[]): [CharacterSheet, CharacterEquipment, FakeContainer[], Function] {
|
||||
let view = testgame.view;
|
||||
let sheet = new CharacterSheet(view);
|
||||
sheet.show(new Ship());
|
||||
let refresh = spyOn(sheet, "refresh").and.stub();
|
||||
|
||||
let container1 = new FakeContainer("container1", 0);
|
||||
let container2 = new FakeContainer("container2", 100);
|
||||
let container3 = new FakeContainer("container3", 200);
|
||||
let equipment = new CharacterEquipment(sheet, new Equipment(), container1);
|
||||
container1.inside = equipment;
|
||||
let containers = positions.map((x, idx) => new FakeContainer(`container${idx + 1}`, x));
|
||||
let equipment = new CharacterEquipment(sheet, new Equipment(), containers[0]);
|
||||
containers[0].inside = equipment;
|
||||
equipment.setupDragDrop();
|
||||
spyOn(sheet, "iEquipmentContainers").and.returnValue(iarray([container1, container2, container3]));
|
||||
spyOn(sheet, "iEquipmentContainers").and.returnValue(iarray(containers));
|
||||
|
||||
return [sheet, equipment, containers, refresh];
|
||||
}
|
||||
|
||||
it("handles drag-and-drop to move equipment", function () {
|
||||
let [sheet, equipment, [container1, container2, container3], refresh] = createBasicCase([0, 100, 200]);
|
||||
|
||||
expect(equipment.inputEnabled).toBe(true, "Input should be enabled");
|
||||
expect(equipment.input.draggable).toBe(true, "Equipment should be draggable");
|
||||
|
@ -97,7 +101,7 @@ module TK.SpaceTac.UI.Specs {
|
|||
|
||||
// broken destination, should return to source
|
||||
let log = spyOn(console, "error").and.stub();
|
||||
spyOn(container3, "addEquipment").and.returnValues(true, false, true, false);
|
||||
spyOn(container3, "addEquipment").and.callFake((equ: any, src: any, test: boolean) => { return { success: test } });
|
||||
equipment.events.onDragStart.dispatch();
|
||||
equipment.x = 200;
|
||||
equipment.events.onDragStop.dispatch();
|
||||
|
@ -107,14 +111,44 @@ module TK.SpaceTac.UI.Specs {
|
|||
expect(log).toHaveBeenCalledWith('Destination container refused to accept equipment', equipment, container2, container3);
|
||||
|
||||
// broken destination and source, item is lost !
|
||||
spyOn(container2, "addEquipment").and.returnValue(false);
|
||||
spyOn(container2, "addEquipment").and.callFake((equ: any, src: any, test: boolean) => { return { success: test } });
|
||||
equipment.events.onDragStart.dispatch();
|
||||
equipment.x = 200;
|
||||
equipment.events.onDragStop.dispatch();
|
||||
expect(equipment.container).toBe(container3);
|
||||
expect(equipment.x).toBe(200);
|
||||
expect(refresh).toHaveBeenCalledTimes(2);
|
||||
expect(log).toHaveBeenCalledWith('Equipment lost in bad exchange !', equipment, container2, container3);
|
||||
expect(log).toHaveBeenCalledWith('Equipment lost in bad exchange!', equipment, container2, container3);
|
||||
});
|
||||
|
||||
it("defines the sheet's action message", function () {
|
||||
let [sheet, equipment, [container1, container2], refresh] = createBasicCase([0, 1]);
|
||||
|
||||
spyOn(container1, "removeEquipment").and.returnValues(
|
||||
{ success: true, info: "detach" },
|
||||
{ success: false, info: "detach", error: "cannot detach" },
|
||||
{ success: true, info: "detach" },
|
||||
{ success: false, info: "detach", error: "cannot detach" }
|
||||
)
|
||||
spyOn(container2, "addEquipment").and.returnValues(
|
||||
{ success: true, info: "attach" },
|
||||
{ success: true, info: "attach" },
|
||||
{ success: false, info: "attach", error: "cannot attach" },
|
||||
{ success: false, info: "attach", error: "cannot attach" }
|
||||
)
|
||||
|
||||
expect(sheet.action_message.text).toEqual("");
|
||||
equipment.events.onDragStart.dispatch();
|
||||
expect(sheet.action_message.text).toEqual("");
|
||||
equipment.x = 1;
|
||||
equipment.events.onDragUpdate.dispatch();
|
||||
expect(sheet.action_message.text).toEqual("Detach, attach");
|
||||
equipment.events.onDragUpdate.dispatch();
|
||||
expect(sheet.action_message.text).toEqual("Detach, attach (cannot detach)");
|
||||
equipment.events.onDragUpdate.dispatch();
|
||||
expect(sheet.action_message.text).toEqual("Detach, attach (cannot attach)");
|
||||
equipment.events.onDragUpdate.dispatch();
|
||||
expect(sheet.action_message.text).toEqual("Detach, attach (cannot detach)");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,11 +18,28 @@ module TK.SpaceTac.UI {
|
|||
/**
|
||||
* Add an equipment to the container
|
||||
*/
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): boolean
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer
|
||||
/**
|
||||
* Remove an equipment from the container
|
||||
*/
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): boolean
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of an equipment transfer operation
|
||||
*/
|
||||
export type CharacterEquipmentTransfer = {
|
||||
success: boolean,
|
||||
info: string,
|
||||
error?: string
|
||||
}
|
||||
|
||||
function mergeTransfer(leave: CharacterEquipmentTransfer, enter: CharacterEquipmentTransfer): CharacterEquipmentTransfer {
|
||||
return {
|
||||
success: leave.success && enter.success,
|
||||
info: [leave.info, enter.info].join(', '),
|
||||
error: leave.error || enter.error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,9 +121,10 @@ module TK.SpaceTac.UI {
|
|||
this.alpha = 0.8;
|
||||
}, () => {
|
||||
// Drop
|
||||
this.sheet.setActionMessage();
|
||||
let destination = this.findContainerAt(this.x, this.y);
|
||||
if (destination && destination != this.container) {
|
||||
if (this.applyDragDrop(this.container, destination, false)) {
|
||||
if (this.applyDragDrop(this.container, destination, false).success) {
|
||||
this.container = destination;
|
||||
this.snapToContainer();
|
||||
this.setupDragDrop();
|
||||
|
@ -117,6 +135,19 @@ module TK.SpaceTac.UI {
|
|||
} else {
|
||||
this.snapToContainer();
|
||||
}
|
||||
}, () => {
|
||||
// Update
|
||||
let destination = this.findContainerAt(this.x, this.y);
|
||||
if (destination && destination != this.container) {
|
||||
let simulation = this.applyDragDrop(this.container, destination, true);
|
||||
let message = capitalize(simulation.info);
|
||||
if (simulation.error) {
|
||||
message += ` (${simulation.error})`;
|
||||
}
|
||||
this.sheet.setActionMessage(message, simulation.success ? "#ffffff" : "#f04240");
|
||||
} else {
|
||||
this.sheet.setActionMessage();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.sheet.view.inputs.setDragDrop(this);
|
||||
|
@ -128,30 +159,39 @@ module TK.SpaceTac.UI {
|
|||
*
|
||||
* Return true if something changed (or would change, if test=true).
|
||||
*/
|
||||
applyDragDrop(source: CharacterEquipmentContainer, destination: CharacterEquipmentContainer, test: boolean): boolean {
|
||||
let possible = source.removeEquipment(this, destination, true) && destination.addEquipment(this, source, true);
|
||||
applyDragDrop(source: CharacterEquipmentContainer, destination: CharacterEquipmentContainer, test: boolean): CharacterEquipmentTransfer {
|
||||
let transfer_test = mergeTransfer(source.removeEquipment(this, destination, true), destination.addEquipment(this, source, true));
|
||||
|
||||
if (test) {
|
||||
return possible;
|
||||
} else if (possible) {
|
||||
if (source.removeEquipment(this, destination, false)) {
|
||||
if (destination.addEquipment(this, source, false)) {
|
||||
return true;
|
||||
return transfer_test;
|
||||
} else if (transfer_test.success) {
|
||||
let transfer_out = source.removeEquipment(this, destination, false);
|
||||
if (transfer_out.success) {
|
||||
let transfer_in = destination.addEquipment(this, source, false);
|
||||
let transfer = mergeTransfer(transfer_out, transfer_in);
|
||||
if (transfer_in.success) {
|
||||
return transfer;
|
||||
} else {
|
||||
console.error("Destination container refused to accept equipment", this, source, destination);
|
||||
// Go back to source
|
||||
if (source.addEquipment(this, null, false)) {
|
||||
return false;
|
||||
let transfer_back = source.addEquipment(this, null, false);
|
||||
if (transfer_back.success) {
|
||||
return transfer;
|
||||
} else {
|
||||
console.error("Equipment lost in bad exchange !", this, source, destination);
|
||||
return true;
|
||||
console.error("Equipment lost in bad exchange!", this, source, destination);
|
||||
return {
|
||||
success: true,
|
||||
info: transfer.info,
|
||||
error: "Equipment was critically damaged in transfer!"
|
||||
};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error("Source container refused to give away equipment", this, source, destination);
|
||||
return false;
|
||||
return transfer_out;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return transfer_test;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,9 +60,9 @@ module TK.SpaceTac.UI.Specs {
|
|||
|
||||
// Cannot transfer to escorted ship
|
||||
ship2.setCargoSpace(2);
|
||||
expect(equ.applyDragDrop(source, dest, true)).toBe(true);
|
||||
expect(equ.applyDragDrop(source, dest, true)).toEqual({ success: true, info: 'remove from cargo, transfer to unnamed', error: undefined });
|
||||
ship2.critical = true;
|
||||
expect(equ.applyDragDrop(source, dest, true)).toBe(false);
|
||||
expect(equ.applyDragDrop(source, dest, true)).toEqual({ success: false, info: 'remove from cargo, transfer to unnamed', error: 'not a fleet member' });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ module TK.SpaceTac.UI {
|
|||
* CharacterEquipmentContainer interface
|
||||
*/
|
||||
isInside(x: number, y: number): boolean {
|
||||
return this.getBounds().contains(x, y);
|
||||
return this.getBounds().contains(x, y) && this.ship !== this.sheet.ship;
|
||||
}
|
||||
getEquipmentAnchor(): { x: number, y: number, scale: number, alpha: number } {
|
||||
// not needed, equipment is never shown snapped in the slot
|
||||
|
@ -50,35 +50,41 @@ module TK.SpaceTac.UI {
|
|||
getPriceOffset(): number {
|
||||
return 0;
|
||||
}
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
let info = `transfer to ${this.ship.name}`;
|
||||
if (this.ship.critical) {
|
||||
return false;
|
||||
return { success: false, info: info, error: "not a fleet member" };
|
||||
} else if (this.ship != this.sheet.ship && equipment.item.slot_type !== null) {
|
||||
// First, try to equip
|
||||
let slot = this.ship.getFreeSlot(equipment.item.slot_type);
|
||||
if (slot) {
|
||||
if (slot && equipment.item.canBeEquipped(this.ship.attributes, false)) {
|
||||
info = `equip on ${this.ship.name}`;
|
||||
if (test) {
|
||||
return true;
|
||||
return { success: true, info: info };
|
||||
} else {
|
||||
return this.ship.equip(equipment.item, false);
|
||||
}
|
||||
} else {
|
||||
if (this.ship.getFreeCargoSpace() > 0) {
|
||||
if (test) {
|
||||
return true;
|
||||
} else {
|
||||
return this.ship.addCargo(equipment.item);
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
let success = this.ship.equip(equipment.item, false);
|
||||
return { success: true, info: info };
|
||||
}
|
||||
}
|
||||
|
||||
// If cannot be equipped, go to cargo
|
||||
if (this.ship.getFreeCargoSpace() > 0) {
|
||||
if (test) {
|
||||
return { success: true, info: info };
|
||||
} else {
|
||||
let success = this.ship.addCargo(equipment.item);
|
||||
return { success: success, info: info };
|
||||
}
|
||||
} else {
|
||||
return { success: false, info: info, error: "not enough cargo space" };
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return { success: false, info: info, error: "drop on cargo or slots" };
|
||||
}
|
||||
}
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
// should never happen
|
||||
return false;
|
||||
return { success: false, info: "" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,21 +6,23 @@ module TK.SpaceTac.UI {
|
|||
* Display a loot slot
|
||||
*/
|
||||
export class CharacterLootSlot extends CharacterCargo {
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
if (!test) {
|
||||
add(this.sheet.loot_items, equipment.item);
|
||||
}
|
||||
return true;
|
||||
return { success: true, info: "leave equipment" };
|
||||
}
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
let info = "Loot equipment";
|
||||
if (contains(this.sheet.loot_items, equipment.item)) {
|
||||
if (test) {
|
||||
return true;
|
||||
return { success: true, info: info };
|
||||
} else {
|
||||
return remove(this.sheet.loot_items, equipment.item);
|
||||
let success = remove(this.sheet.loot_items, equipment.item);
|
||||
return { success: success, info: info };
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return { success: false, info: info, error: "not lootable!" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,9 @@ module TK.SpaceTac.UI {
|
|||
// Ship cargo
|
||||
ship_cargo: Phaser.Group
|
||||
|
||||
// Mode title
|
||||
mode_title: Phaser.Text
|
||||
// Dynamic texts
|
||||
mode_title: UIText
|
||||
action_message: UIText
|
||||
|
||||
// Loot items
|
||||
loot_slots: Phaser.Group
|
||||
|
@ -88,6 +89,7 @@ module TK.SpaceTac.UI {
|
|||
this.close_button = this.builder.button("character-close", 1920, 0, onclose, "Close the character sheet");
|
||||
this.close_button.anchor.set(1, 0);
|
||||
|
||||
this.builder.text("Cargo", 1566, 36, { size: 24 });
|
||||
this.builder.text("Level", 420, 1052, { size: 24 });
|
||||
this.builder.text("Available points", 894, 1052, { size: 24 });
|
||||
|
||||
|
@ -101,6 +103,7 @@ module TK.SpaceTac.UI {
|
|||
this.portraits = this.builder.group("portraits", 152, 0);
|
||||
this.credits = this.builder.text("", 136, 38, { size: 30 });
|
||||
this.mode_title = this.builder.text("", 1566, 648, { size: 18 });
|
||||
this.action_message = this.builder.text("", 1566, 1056, { size: 18 });
|
||||
this.loot_next = this.builder.button("common-arrow-right", 1890, 850, () => this.paginate(1), "Show next items");
|
||||
this.loot_next.anchor.set(0.5);
|
||||
this.loot_prev = this.builder.button("common-arrow-left", 1238, 850, () => this.paginate(-1), "Show previous items");
|
||||
|
@ -189,6 +192,7 @@ module TK.SpaceTac.UI {
|
|||
this.ship = ship;
|
||||
|
||||
this.layer_equipments.removeAll(true);
|
||||
this.setActionMessage();
|
||||
|
||||
let upgrade_points = ship.getAvailableUpgradePoints();
|
||||
|
||||
|
@ -211,11 +215,11 @@ module TK.SpaceTac.UI {
|
|||
let slot_display = new CharacterSlot(this, slotsinfo.positions[idx].x, slotsinfo.positions[idx].y, slot.type);
|
||||
slot_display.scale.set(slotsinfo.scaling, slotsinfo.scaling);
|
||||
slot_display.alpha = ship.critical ? 0.5 : 1;
|
||||
this.ship_slots.addChild(slot_display);
|
||||
this.ship_slots.add(slot_display);
|
||||
|
||||
if (slot.attached) {
|
||||
let equipment = new CharacterEquipment(this, slot.attached, slot_display);
|
||||
this.layer_equipments.addChild(equipment);
|
||||
this.layer_equipments.add(equipment);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -225,11 +229,11 @@ module TK.SpaceTac.UI {
|
|||
let cargo_slot = new CharacterCargo(this, slotsinfo.positions[idx].x, slotsinfo.positions[idx].y);
|
||||
cargo_slot.scale.set(slotsinfo.scaling, slotsinfo.scaling);
|
||||
cargo_slot.alpha = ship.critical ? 0.5 : 1;
|
||||
this.ship_cargo.addChild(cargo_slot);
|
||||
this.ship_cargo.add(cargo_slot);
|
||||
|
||||
if (idx < this.ship.cargo.length) {
|
||||
let equipment = new CharacterEquipment(this, this.ship.cargo[idx], cargo_slot);
|
||||
this.layer_equipments.addChild(equipment);
|
||||
this.layer_equipments.add(equipment);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -273,6 +277,16 @@ module TK.SpaceTac.UI {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the action message (mainly used while dragging equipment to explain what is happening)
|
||||
*/
|
||||
setActionMessage(message = "", color = "#ffffff"): void {
|
||||
if (message != this.action_message.text) {
|
||||
this.action_message.setText(message);
|
||||
this.action_message.fill = color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of lootable equipment
|
||||
*
|
||||
|
@ -337,13 +351,13 @@ module TK.SpaceTac.UI {
|
|||
range(per_page).forEach(idx => {
|
||||
let loot_slot = this.shop ? new CharacterShopSlot(this, info.positions[idx].x, info.positions[idx].y) : new CharacterLootSlot(this, info.positions[idx].x, info.positions[idx].y);
|
||||
loot_slot.scale.set(info.scaling, info.scaling);
|
||||
this.loot_slots.addChild(loot_slot);
|
||||
this.loot_slots.add(loot_slot);
|
||||
|
||||
idx += per_page * this.loot_page;
|
||||
|
||||
if (idx < items.length) {
|
||||
let equipment = new CharacterEquipment(this, items[idx], loot_slot);
|
||||
this.layer_equipments.addChild(equipment);
|
||||
this.layer_equipments.add(equipment);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -5,34 +5,41 @@ module TK.SpaceTac.UI {
|
|||
* Display a shop slot
|
||||
*/
|
||||
export class CharacterShopSlot extends CharacterLootSlot {
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
let shop = this.sheet.shop;
|
||||
if (shop && !contains(shop.getStock(), equipment.item)) {
|
||||
let price = shop.getPrice(equipment.item);
|
||||
let info = `sell for ${price} zotys`;
|
||||
if (test) {
|
||||
return true;
|
||||
return { success: true, info: info };
|
||||
} else {
|
||||
return shop.buyFromFleet(equipment.item, this.sheet.fleet);
|
||||
let success = shop.buyFromFleet(equipment.item, this.sheet.fleet);
|
||||
return { success: success, info: info };
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return { success: false, info: "sell equipment", error: "it's already mine!" };
|
||||
}
|
||||
}
|
||||
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
let shop = this.sheet.shop;
|
||||
if (shop && contains(shop.getStock(), equipment.item)) {
|
||||
let price = shop.getPrice(equipment.item);
|
||||
let info = `buy for ${price} zotys`;
|
||||
if (destination) {
|
||||
let price = shop.getPrice(equipment.item);
|
||||
if (test) {
|
||||
return price <= this.sheet.fleet.credits;
|
||||
if (price > this.sheet.fleet.credits) {
|
||||
return { success: false, info: info, error: "not enough zotys" };
|
||||
} else if (test) {
|
||||
return { success: true, info: info };
|
||||
} else {
|
||||
return shop.sellToFleet(equipment.item, this.sheet.fleet);
|
||||
let success = shop.sellToFleet(equipment.item, this.sheet.fleet);
|
||||
return { success: success, info: info };
|
||||
}
|
||||
} else {
|
||||
return test;
|
||||
return { success: test, info: info };
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
return { success: false, info: "buy equipment", error: "it's not mine to sell!" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,34 +13,34 @@ module TK.SpaceTac.UI.Specs {
|
|||
let equipment = new CharacterEquipment(sheet, new Equipment(SlotType.Engine), source);
|
||||
|
||||
let slot = new CharacterSlot(sheet, 0, 0, SlotType.Engine);
|
||||
expect(slot.addEquipment(equipment, source, true)).toBe(false);
|
||||
expect(slot.removeEquipment(equipment, source, true)).toBe(false);
|
||||
expect(slot.addEquipment(equipment, source, true)).toEqual({ success: false, info: 'equip in engine slot', error: 'no free slot' });
|
||||
expect(slot.removeEquipment(equipment, source, true)).toEqual({ success: false, info: 'unequip from engine slot', error: 'not equipped!' });
|
||||
|
||||
ship.addSlot(SlotType.Engine);
|
||||
expect(slot.addEquipment(equipment, source, true)).toBe(true);
|
||||
expect(slot.addEquipment(equipment, source, true)).toEqual({ success: true, info: 'equip in engine slot' });
|
||||
|
||||
equipment.item.requirements["skill_time"] = 1;
|
||||
expect(slot.addEquipment(equipment, source, true)).toBe(false);
|
||||
expect(slot.addEquipment(equipment, source, true)).toEqual({ success: false, info: 'equip in engine slot', error: 'missing skills' });
|
||||
|
||||
ship.upgradeSkill("skill_time");
|
||||
expect(slot.addEquipment(equipment, source, true)).toBe(true);
|
||||
expect(slot.addEquipment(equipment, source, true)).toEqual({ success: true, info: 'equip in engine slot' });
|
||||
|
||||
ship.critical = true;
|
||||
expect(slot.addEquipment(equipment, source, true)).toBe(false);
|
||||
expect(slot.addEquipment(equipment, source, true)).toEqual({ success: false, info: 'equip in engine slot', error: 'not a fleet member' });
|
||||
ship.critical = false;
|
||||
|
||||
expect(ship.listEquipment(SlotType.Engine)).toEqual([]);
|
||||
let result = slot.addEquipment(equipment, source, false);
|
||||
expect(result).toBe(true);
|
||||
expect(result).toEqual({ success: true, info: 'equip in engine slot' });
|
||||
expect(ship.listEquipment(SlotType.Engine)).toEqual([equipment.item]);
|
||||
|
||||
expect(slot.removeEquipment(equipment, source, true)).toBe(true);
|
||||
expect(slot.removeEquipment(equipment, source, true)).toEqual({ success: true, info: 'unequip from engine slot' });
|
||||
ship.critical = true;
|
||||
expect(slot.removeEquipment(equipment, source, true)).toBe(false);
|
||||
expect(slot.removeEquipment(equipment, source, true)).toEqual({ success: false, info: 'unequip from engine slot', error: 'not a fleet member' });
|
||||
ship.critical = false;
|
||||
|
||||
result = slot.removeEquipment(equipment, source, false);
|
||||
expect(result).toBe(true);
|
||||
expect(result).toEqual({ success: true, info: 'unequip from engine slot' });
|
||||
expect(ship.listEquipment(SlotType.Engine)).toEqual([]);
|
||||
|
||||
});
|
||||
|
|
|
@ -37,30 +37,36 @@ module TK.SpaceTac.UI {
|
|||
getPriceOffset(): number {
|
||||
return 66;
|
||||
}
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
let info = equipment.item.slot_type ? `equip in ${SlotType[equipment.item.slot_type].toLowerCase()} slot` : "equip";
|
||||
if (this.sheet.ship.critical) {
|
||||
return false;
|
||||
} if (this.sheet.ship.canEquip(equipment.item)) {
|
||||
if (test) {
|
||||
return true;
|
||||
} else {
|
||||
return this.sheet.ship.equip(equipment.item, false);
|
||||
}
|
||||
return { success: false, info: info, error: "not a fleet member" };
|
||||
} else if (!equipment.item.canBeEquipped(this.sheet.ship.attributes, false)) {
|
||||
return { success: false, info: info, error: "missing skills" };
|
||||
} else if (equipment.item.slot_type && !this.sheet.ship.getFreeSlot(equipment.item.slot_type)) {
|
||||
return { success: false, info: info, error: "no free slot" };
|
||||
} else {
|
||||
return false;
|
||||
if (test) {
|
||||
return { success: true, info: info };
|
||||
} else {
|
||||
let success = this.sheet.ship.equip(equipment.item, false);
|
||||
return { success: success, info: info };
|
||||
}
|
||||
}
|
||||
}
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): boolean {
|
||||
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): CharacterEquipmentTransfer {
|
||||
let info = equipment.item.slot_type ? `unequip from ${SlotType[equipment.item.slot_type].toLowerCase()} slot` : "unequip";
|
||||
if (this.sheet.ship.critical) {
|
||||
return false;
|
||||
} if (contains(this.sheet.ship.listEquipment(equipment.item.slot_type), equipment.item)) {
|
||||
if (test) {
|
||||
return true;
|
||||
} else {
|
||||
return this.sheet.ship.unequip(equipment.item, false);
|
||||
}
|
||||
return { success: false, info: info, error: "not a fleet member" };
|
||||
} if (!contains(this.sheet.ship.listEquipment(equipment.item.slot_type), equipment.item)) {
|
||||
return { success: false, info: info, error: "not equipped!" };
|
||||
} else {
|
||||
return false;
|
||||
if (test) {
|
||||
return { success: true, info: info };
|
||||
} else {
|
||||
let success = this.sheet.ship.unequip(equipment.item, false);
|
||||
return { success: success, info: info };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ module TK.SpaceTac.UI {
|
|||
this.infinite_shop = new Shop(1, basic_equipments(), 0, basic_equipments);
|
||||
|
||||
this.character_sheet = new CharacterSheet(this, undefined, undefined, () => this.validateFleet());
|
||||
this.character_sheet.setShop(this.infinite_shop, "Initial basic equipment");
|
||||
this.character_sheet.setShop(this.infinite_shop, "Available stock (from Master Merchant Guild)");
|
||||
this.character_sheet.show(this.built_fleet.ships[0], false);
|
||||
this.getLayer("characters").add(this.character_sheet);
|
||||
}
|
||||
|
|
|
@ -135,10 +135,13 @@ module TK.SpaceTac.UI {
|
|||
* Setup dragging on an UI component
|
||||
*
|
||||
* If no drag or drop function is defined, dragging is disabled
|
||||
*
|
||||
* If update function is defined, it will receive (a lot of) cursor moves while dragging
|
||||
*/
|
||||
setDragDrop(obj: Phaser.Button | Phaser.Image, drag?: Function, drop?: Function): void {
|
||||
setDragDrop(obj: Phaser.Button | Phaser.Image, drag?: Function, drop?: Function, update?: Function): void {
|
||||
obj.events.onDragStart.removeAll();
|
||||
obj.events.onDragStop.removeAll();
|
||||
obj.events.onDragUpdate.removeAll();
|
||||
|
||||
if (drag && drop) {
|
||||
obj.inputEnabled = true;
|
||||
|
@ -149,10 +152,17 @@ module TK.SpaceTac.UI {
|
|||
this.view.audio.playOnce("ui-drag");
|
||||
drag();
|
||||
});
|
||||
|
||||
obj.events.onDragStop.add(() => {
|
||||
this.view.audio.playOnce("ui-drop");
|
||||
drop();
|
||||
});
|
||||
|
||||
if (update) {
|
||||
obj.events.onDragUpdate.add(() => {
|
||||
update();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
obj.input.disableDrag();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue