2017-09-24 22:23:22 +00:00
|
|
|
module TK.SpaceTac.UI {
|
2017-03-05 23:29:02 +00:00
|
|
|
/**
|
2017-03-22 21:16:59 +00:00
|
|
|
* Interface for any graphical area that may contain or receive an equipment
|
2017-03-05 23:29:02 +00:00
|
|
|
*/
|
2017-03-22 21:16:59 +00:00
|
|
|
export interface CharacterEquipmentContainer {
|
|
|
|
/**
|
|
|
|
* Check if a point in the character sheet is inside the container
|
|
|
|
*/
|
|
|
|
isInside(x: number, y: number): boolean
|
|
|
|
/**
|
|
|
|
* Get a centric anchor point and scaling to snap the equipment
|
|
|
|
*/
|
2017-07-24 23:02:49 +00:00
|
|
|
getEquipmentAnchor(): { x: number, y: number, scale: number, alpha: number }
|
2017-03-23 18:58:09 +00:00
|
|
|
/**
|
|
|
|
* Get a vertical offset to position the price tag
|
|
|
|
*/
|
|
|
|
getPriceOffset(): number
|
2017-03-22 21:16:59 +00:00
|
|
|
/**
|
|
|
|
* Add an equipment to the container
|
|
|
|
*/
|
|
|
|
addEquipment(equipment: CharacterEquipment, source: CharacterEquipmentContainer | null, test: boolean): boolean
|
|
|
|
/**
|
|
|
|
* Remove an equipment from the container
|
|
|
|
*/
|
|
|
|
removeEquipment(equipment: CharacterEquipment, destination: CharacterEquipmentContainer | null, test: boolean): boolean
|
2017-03-05 23:29:02 +00:00
|
|
|
}
|
|
|
|
|
2017-03-05 17:48:13 +00:00
|
|
|
/**
|
|
|
|
* Display a ship equipment, either attached to a slot, in cargo, or being dragged down
|
|
|
|
*/
|
2017-03-15 21:40:19 +00:00
|
|
|
export class CharacterEquipment extends Phaser.Button {
|
2017-03-22 21:16:59 +00:00
|
|
|
sheet: CharacterSheet
|
|
|
|
item: Equipment
|
|
|
|
container: CharacterEquipmentContainer
|
2017-03-23 18:58:09 +00:00
|
|
|
price: number
|
2017-03-14 17:48:04 +00:00
|
|
|
|
2017-03-22 21:16:59 +00:00
|
|
|
constructor(sheet: CharacterSheet, equipment: Equipment, container: CharacterEquipmentContainer) {
|
2017-07-26 22:54:56 +00:00
|
|
|
let icon = sheet.view.getImageInfo(`equipment-${equipment.code}`);
|
|
|
|
super(sheet.game, 0, 0, icon.key, undefined, undefined, icon.frame, icon.frame);
|
2017-03-05 17:48:13 +00:00
|
|
|
|
2017-03-22 21:16:59 +00:00
|
|
|
this.sheet = sheet;
|
|
|
|
this.item = equipment;
|
|
|
|
this.container = container;
|
2017-03-23 18:58:09 +00:00
|
|
|
this.price = 0;
|
2017-03-22 21:16:59 +00:00
|
|
|
|
2017-03-05 17:48:13 +00:00
|
|
|
this.anchor.set(0.5, 0.5);
|
2017-03-05 23:29:02 +00:00
|
|
|
|
2017-10-11 22:28:33 +00:00
|
|
|
this.setupDragDrop();
|
2017-03-22 21:16:59 +00:00
|
|
|
this.snapToContainer();
|
2017-03-15 21:40:19 +00:00
|
|
|
|
2017-05-14 23:00:36 +00:00
|
|
|
sheet.view.tooltip.bind(this, filler => this.fillTooltip(filler));
|
2017-03-22 21:16:59 +00:00
|
|
|
}
|
|
|
|
|
2017-04-25 18:24:43 +00:00
|
|
|
jasmineToString() {
|
|
|
|
return this.item.jasmineToString();
|
|
|
|
}
|
|
|
|
|
2017-03-22 21:16:59 +00:00
|
|
|
/**
|
|
|
|
* Find the container under a specific screen location
|
|
|
|
*/
|
|
|
|
findContainerAt(x: number, y: number): CharacterEquipmentContainer | null {
|
|
|
|
return ifirst(this.sheet.iEquipmentContainers(), container => container.isInside(x, y));
|
|
|
|
}
|
|
|
|
|
2017-03-23 18:58:09 +00:00
|
|
|
/**
|
|
|
|
* Display a price tag
|
|
|
|
*/
|
|
|
|
setPrice(price: number) {
|
|
|
|
if (!price || this.price) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.price = price;
|
|
|
|
|
2017-10-10 17:01:09 +00:00
|
|
|
let tag = this.sheet.view.newImage("character-price-tag");
|
2017-03-23 18:58:09 +00:00
|
|
|
let yoffset = this.container.getPriceOffset();
|
|
|
|
tag.position.set(0, -yoffset * 2 + tag.height);
|
|
|
|
tag.anchor.set(0.5, 0.5);
|
|
|
|
tag.scale.set(2, 2);
|
|
|
|
tag.alpha = 0.85;
|
|
|
|
this.addChild(tag);
|
|
|
|
|
2017-10-10 17:01:09 +00:00
|
|
|
let text = this.sheet.view.newText(price.toString(), -8, 2, 18, "#ffffcc");
|
2017-03-23 18:58:09 +00:00
|
|
|
tag.addChild(text);
|
|
|
|
}
|
|
|
|
|
2017-03-22 21:16:59 +00:00
|
|
|
/**
|
|
|
|
* Snap in place to its current container
|
|
|
|
*/
|
|
|
|
snapToContainer() {
|
|
|
|
let info = this.container.getEquipmentAnchor();
|
|
|
|
this.position.set(info.x, info.y);
|
|
|
|
this.scale.set(0.5 * info.scale, 0.5 * info.scale);
|
2017-07-24 23:02:49 +00:00
|
|
|
this.alpha = info.alpha;
|
2017-03-14 17:48:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Enable dragging to another slot
|
|
|
|
*/
|
2017-10-11 22:28:33 +00:00
|
|
|
setupDragDrop() {
|
2017-07-24 23:02:49 +00:00
|
|
|
if (this.container.removeEquipment(this, null, true)) {
|
2017-10-11 22:28:33 +00:00
|
|
|
this.sheet.view.inputs.setDragDrop(this, () => {
|
|
|
|
// Drag
|
|
|
|
this.scale.set(0.5, 0.5);
|
|
|
|
this.alpha = 0.8;
|
|
|
|
}, () => {
|
|
|
|
// Drop
|
|
|
|
let destination = this.findContainerAt(this.x, this.y);
|
|
|
|
if (destination && destination != this.container) {
|
|
|
|
if (this.applyDragDrop(this.container, destination, false)) {
|
|
|
|
this.container = destination;
|
|
|
|
this.snapToContainer();
|
2017-10-12 19:11:58 +00:00
|
|
|
this.setupDragDrop();
|
2017-10-11 22:28:33 +00:00
|
|
|
this.sheet.refresh(); // TODO Only if required (destination is "virtual")
|
|
|
|
} else {
|
|
|
|
this.snapToContainer();
|
|
|
|
}
|
2017-04-25 18:24:43 +00:00
|
|
|
} else {
|
|
|
|
this.snapToContainer();
|
|
|
|
}
|
2017-10-11 22:28:33 +00:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.sheet.view.inputs.setDragDrop(this);
|
|
|
|
}
|
2017-03-05 17:48:13 +00:00
|
|
|
}
|
2017-03-14 17:48:04 +00:00
|
|
|
|
|
|
|
/**
|
2017-03-22 21:16:59 +00:00
|
|
|
* Apply drag and drop between two containers
|
2017-04-25 18:24:43 +00:00
|
|
|
*
|
|
|
|
* Return true if something changed (or would change, if test=true).
|
2017-03-14 17:48:04 +00:00
|
|
|
*/
|
2017-04-25 18:24:43 +00:00
|
|
|
applyDragDrop(source: CharacterEquipmentContainer, destination: CharacterEquipmentContainer, test: boolean): boolean {
|
|
|
|
let possible = 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;
|
2017-03-22 21:16:59 +00:00
|
|
|
} else {
|
2017-04-25 18:24:43 +00:00
|
|
|
console.error("Destination container refused to accept equipment", this, source, destination);
|
|
|
|
// Go back to source
|
|
|
|
if (source.addEquipment(this, null, false)) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
console.error("Equipment lost in bad exchange !", this, source, destination);
|
|
|
|
return true;
|
|
|
|
}
|
2017-03-22 21:16:59 +00:00
|
|
|
}
|
2017-04-25 18:24:43 +00:00
|
|
|
} else {
|
|
|
|
console.error("Source container refused to give away equipment", this, source, destination);
|
|
|
|
return false;
|
2017-03-22 21:16:59 +00:00
|
|
|
}
|
2017-04-25 18:24:43 +00:00
|
|
|
} else {
|
|
|
|
return false;
|
2017-03-22 21:16:59 +00:00
|
|
|
}
|
2017-03-14 17:48:04 +00:00
|
|
|
}
|
2017-04-18 22:55:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Fill a tooltip with equipment data
|
|
|
|
*/
|
2017-05-14 23:00:36 +00:00
|
|
|
fillTooltip(filler: TooltipFiller): boolean {
|
2017-05-28 22:24:41 +00:00
|
|
|
let title = this.item.getFullName();
|
|
|
|
if (this.item.slot_type !== null) {
|
|
|
|
title += ` (${SlotType[this.item.slot_type]})`;
|
|
|
|
}
|
2017-10-10 22:32:46 +00:00
|
|
|
filler.text(title, 0, 0, { color: "#cccccc", size: 20, bold: true });
|
|
|
|
filler.text(this.item.getFullDescription(), 0, 40, { color: "#cccccc", size: 18, width: 700 });
|
2017-04-18 22:55:59 +00:00
|
|
|
return true;
|
|
|
|
}
|
2017-03-05 17:48:13 +00:00
|
|
|
}
|
|
|
|
}
|