Added ability to equip/unequip from character sheet
This commit is contained in:
parent
0cdc7b3def
commit
80e3f212d6
|
@ -1 +1 @@
|
|||
Subproject commit ce9feb35874b0aa2686c80f1b7f56447044b9d74
|
||||
Subproject commit db61f921e8afa9beca31bf1de1d30870f48a17e4
|
|
@ -308,5 +308,92 @@ module TS.SpaceTac.Specs {
|
|||
expect(onTurnEnd).toHaveBeenCalledWith(ship);
|
||||
expect(onShipMove).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("stores items in cargo space", function () {
|
||||
let ship = new Ship();
|
||||
let equipment1 = new Equipment();
|
||||
let equipment2 = new Equipment();
|
||||
|
||||
let result = ship.addCargo(equipment1);
|
||||
expect(result).toBe(false);
|
||||
expect(ship.cargo).toEqual([]);
|
||||
|
||||
ship.setCargoSpace(1);
|
||||
|
||||
result = ship.addCargo(equipment1);
|
||||
expect(result).toBe(true);
|
||||
expect(ship.cargo).toEqual([equipment1]);
|
||||
|
||||
result = ship.addCargo(equipment1);
|
||||
expect(result).toBe(false);
|
||||
expect(ship.cargo).toEqual([equipment1]);
|
||||
|
||||
result = ship.addCargo(equipment2);
|
||||
expect(result).toBe(false);
|
||||
expect(ship.cargo).toEqual([equipment1]);
|
||||
|
||||
ship.setCargoSpace(2);
|
||||
|
||||
result = ship.addCargo(equipment2);
|
||||
expect(result).toBe(true);
|
||||
expect(ship.cargo).toEqual([equipment1, equipment2]);
|
||||
|
||||
ship.setCargoSpace(1);
|
||||
|
||||
expect(ship.cargo).toEqual([equipment1]);
|
||||
|
||||
ship.setCargoSpace(2);
|
||||
|
||||
expect(ship.cargo).toEqual([equipment1]);
|
||||
});
|
||||
|
||||
it("equips items from cargo", function () {
|
||||
let ship = new Ship();
|
||||
let equipment = new Equipment(SlotType.Weapon);
|
||||
let slot = ship.addSlot(SlotType.Weapon);
|
||||
expect(ship.listEquipment()).toEqual([]);
|
||||
|
||||
let result = ship.equip(equipment);
|
||||
expect(result).toBe(false);
|
||||
expect(ship.listEquipment()).toEqual([]);
|
||||
|
||||
ship.setCargoSpace(1);
|
||||
ship.addCargo(equipment);
|
||||
|
||||
result = ship.equip(equipment);
|
||||
expect(result).toBe(true);
|
||||
expect(ship.listEquipment(SlotType.Weapon)).toEqual([equipment]);
|
||||
expect(equipment.attached_to).toEqual(slot);
|
||||
});
|
||||
|
||||
it("removes equipped items", function () {
|
||||
let ship = new Ship();
|
||||
let equipment = new Equipment(SlotType.Weapon);
|
||||
let slot = ship.addSlot(SlotType.Weapon);
|
||||
slot.attach(equipment);
|
||||
|
||||
expect(ship.listEquipment()).toEqual([equipment]);
|
||||
expect(slot.attached).toBe(equipment);
|
||||
expect(equipment.attached_to).toBe(slot);
|
||||
|
||||
let result = ship.unequip(equipment);
|
||||
expect(result).toBe(false);
|
||||
expect(ship.listEquipment()).toEqual([equipment]);
|
||||
expect(ship.cargo).toEqual([]);
|
||||
|
||||
ship.setCargoSpace(10);
|
||||
|
||||
result = ship.unequip(equipment);
|
||||
expect(result).toBe(true);
|
||||
expect(ship.listEquipment()).toEqual([]);
|
||||
expect(ship.cargo).toEqual([equipment]);
|
||||
expect(slot.attached).toBe(null);
|
||||
expect(equipment.attached_to).toBe(null);
|
||||
|
||||
result = ship.unequip(equipment);
|
||||
expect(result).toBe(false);
|
||||
expect(ship.listEquipment()).toEqual([]);
|
||||
expect(ship.cargo).toEqual([equipment]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -443,26 +443,74 @@ module TS.SpaceTac {
|
|||
*/
|
||||
setCargoSpace(cargo: number) {
|
||||
this.cargo_space = cargo;
|
||||
this.cargo.splice(this.cargo_space);
|
||||
}
|
||||
|
||||
// Add an empty equipment slot of the given type
|
||||
/**
|
||||
* Add an equipment to cargo space
|
||||
*
|
||||
* Returns true if successful
|
||||
*/
|
||||
addCargo(item: Equipment): boolean {
|
||||
if (this.cargo.length < this.cargo_space) {
|
||||
return add(this.cargo, item);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Equip an item from cargo to the first available slot
|
||||
*
|
||||
* Returns true if successful
|
||||
*/
|
||||
equip(item: Equipment): boolean {
|
||||
let free_slot = first(this.slots, slot => slot.type == item.slot && !slot.attached);
|
||||
|
||||
if (free_slot && contains(this.cargo, item)) {
|
||||
remove(this.cargo, item);
|
||||
free_slot.attach(item);
|
||||
|
||||
this.updateAttributes();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an equipped item, returning it to cargo
|
||||
*
|
||||
* Returns true if successful
|
||||
*/
|
||||
unequip(item: Equipment): boolean {
|
||||
if (item.attached_to && item.attached_to.attached == item && this.cargo.length < this.cargo_space) {
|
||||
item.detach();
|
||||
add(this.cargo, item);
|
||||
|
||||
this.updateAttributes();
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an empty equipment slot of the given type
|
||||
*/
|
||||
addSlot(type: SlotType): Slot {
|
||||
var result = new Slot(this, type);
|
||||
this.slots.push(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// List all attached equipments of a given type (all types if null)
|
||||
listEquipment(slottype: SlotType = null): Equipment[] {
|
||||
var result: Equipment[] = [];
|
||||
|
||||
this.slots.forEach((slot: Slot) => {
|
||||
if (slot.type === slottype && slot.attached) {
|
||||
result.push(slot.attached);
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
/**
|
||||
* List all equipments attached to slots of a given type (any slot type if null)
|
||||
*/
|
||||
listEquipment(slottype: SlotType | null = null): Equipment[] {
|
||||
return this.slots.filter(slot => slot.attached && (slottype == null || slot.type == slottype)).map(slot => slot.attached);
|
||||
}
|
||||
|
||||
// Get the number of attached equipments
|
||||
|
|
|
@ -171,8 +171,9 @@ module TS.SpaceTac.UI {
|
|||
cursorClicked(): void {
|
||||
if (this.targetting) {
|
||||
this.targetting.validate();
|
||||
} else if (this.ship_hovered) {
|
||||
} else if (this.ship_hovered && this.ship_hovered.getPlayer() == this.player) {
|
||||
this.character_sheet.show(this.ship_hovered);
|
||||
this.setShipHovered(null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,16 +3,33 @@ module TS.SpaceTac.UI {
|
|||
* Display a ship cargo slot
|
||||
*/
|
||||
export class CharacterCargo extends Phaser.Image {
|
||||
sheet: CharacterSheet;
|
||||
|
||||
constructor(sheet: CharacterSheet, x: number, y: number) {
|
||||
super(sheet.game, x, y, "character-cargo-slot");
|
||||
|
||||
this.sheet = sheet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the equipment displayed in the slot
|
||||
* Snap the equipment icon inside the slot
|
||||
*/
|
||||
setEquipment(equipment: CharacterEquipment | null) {
|
||||
this.addChild(equipment);
|
||||
equipment.position.set(98, 98);
|
||||
snapEquipment(equipment: CharacterEquipment) {
|
||||
equipment.position.set(this.x + this.parent.x + 98, this.y + this.parent.y + 98);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an equipment can be dropped in this slot
|
||||
*/
|
||||
canDropEquipment(equipment: Equipment, x: number, y: number): CharacterEquipmentDrop | null {
|
||||
if (this.getBounds().contains(x, y)) {
|
||||
return {
|
||||
message: "Unequip",
|
||||
callback: () => this.sheet.ship.unequip(equipment)
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
module TS.SpaceTac.UI {
|
||||
/**
|
||||
* Interface for any graphical item that may receive an equipment as drop destination
|
||||
*/
|
||||
export interface CharacterEquipmentDestination {
|
||||
canDropEquipment(equipment: Equipment, x: number, y: number): CharacterEquipmentDrop | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a ship equipment, either attached to a slot, in cargo, or being dragged down
|
||||
*/
|
||||
|
@ -9,6 +16,31 @@ module TS.SpaceTac.UI {
|
|||
|
||||
this.anchor.set(0.5, 0.5);
|
||||
this.scale.set(0.5, 0.5);
|
||||
|
||||
this.inputEnabled = true;
|
||||
this.input.enableDrag(false, true);
|
||||
|
||||
let origin: [number, number] | null = null;
|
||||
let drop: CharacterEquipmentDrop | null = null;
|
||||
this.events.onDragStart.add(() => {
|
||||
origin = [this.x, this.y];
|
||||
this.alpha = 0.8;
|
||||
});
|
||||
this.events.onDragUpdate.add(() => {
|
||||
drop = sheet.canDropEquipment(equipment, this.x, this.y);
|
||||
});
|
||||
this.events.onDragStop.add(() => {
|
||||
if (drop) {
|
||||
drop.callback(equipment);
|
||||
sheet.refresh();
|
||||
} else {
|
||||
if (origin) {
|
||||
this.position.set(origin[0], origin[1]);
|
||||
origin = null;
|
||||
}
|
||||
this.alpha = 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
module TS.SpaceTac.UI {
|
||||
export type CharacterEquipmentDrop = {
|
||||
message: string
|
||||
callback: (equipment: Equipment) => any
|
||||
}
|
||||
|
||||
/**
|
||||
* Character sheet, displaying ship characteristics
|
||||
*/
|
||||
|
@ -31,6 +36,9 @@ module TS.SpaceTac.UI {
|
|||
// Fleet's portraits
|
||||
portraits: Phaser.Group;
|
||||
|
||||
// Layer for draggable equipments
|
||||
equipments: Phaser.Group;
|
||||
|
||||
// Credits
|
||||
credits: Phaser.Text;
|
||||
|
||||
|
@ -77,6 +85,9 @@ module TS.SpaceTac.UI {
|
|||
this.credits.anchor.set(0.5, 0.5);
|
||||
this.addChild(this.credits);
|
||||
|
||||
this.equipments = new Phaser.Group(this.game);
|
||||
this.addChild(this.equipments);
|
||||
|
||||
let x1 = 664;
|
||||
let x2 = 1066;
|
||||
let y = 662;
|
||||
|
@ -142,6 +153,8 @@ module TS.SpaceTac.UI {
|
|||
show(ship: Ship, animate = true) {
|
||||
this.ship = ship;
|
||||
|
||||
this.equipments.removeAll(true);
|
||||
|
||||
this.ship_name.setText(ship.name);
|
||||
this.ship_level.setText(ship.level.toString());
|
||||
this.ship_upgrades.setText(ship.upgrade_points.toString());
|
||||
|
@ -162,7 +175,8 @@ module TS.SpaceTac.UI {
|
|||
|
||||
if (slot.attached) {
|
||||
let equipment = new CharacterEquipment(this, slot.attached);
|
||||
slot_display.setEquipment(equipment);
|
||||
this.equipments.addChild(equipment);
|
||||
slot_display.snapEquipment(equipment);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -172,6 +186,12 @@ module TS.SpaceTac.UI {
|
|||
let cargo_slot = new CharacterCargo(this, slotsinfo.positions[idx].x, slotsinfo.positions[idx].y);
|
||||
cargo_slot.scale.set(slotsinfo.scaling, slotsinfo.scaling);
|
||||
this.ship_cargo.addChild(cargo_slot);
|
||||
|
||||
if (idx < this.ship.cargo.length) {
|
||||
let equipment = new CharacterEquipment(this, this.ship.cargo[idx]);
|
||||
this.equipments.addChild(equipment);
|
||||
cargo_slot.snapEquipment(equipment);
|
||||
}
|
||||
});
|
||||
|
||||
this.updateFleet(ship.fleet);
|
||||
|
@ -196,6 +216,25 @@ module TS.SpaceTac.UI {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an equipment can be dropped somewhere
|
||||
*/
|
||||
canDropEquipment(equipment: Equipment, x: number, y: number): CharacterEquipmentDrop | null {
|
||||
let candidates: Iterator<CharacterEquipmentDestination> = ichain(
|
||||
iarray(<CharacterSlot[]>this.ship_slots.children),
|
||||
iarray(<CharacterCargo[]>this.ship_cargo.children)
|
||||
);
|
||||
|
||||
return ifirstmap(candidates, candidate => candidate.canDropEquipment(equipment, x, y));
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the sheet display
|
||||
*/
|
||||
refresh() {
|
||||
this.show(this.ship);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the positions and scaling for slots, to fit in a rectangle group.
|
||||
*/
|
||||
|
|
|
@ -3,20 +3,37 @@ module TS.SpaceTac.UI {
|
|||
* Display a ship slot, with equipment attached to it
|
||||
*/
|
||||
export class CharacterSlot extends Phaser.Image {
|
||||
sheet: CharacterSheet;
|
||||
|
||||
constructor(sheet: CharacterSheet, x: number, y: number, slot: SlotType) {
|
||||
super(sheet.game, x, y, "character-equipment-slot");
|
||||
|
||||
this.sheet = sheet;
|
||||
|
||||
let sloticon = new Phaser.Image(this.game, 150, 150, `character-slot-${SlotType[slot].toLowerCase()}`);
|
||||
sloticon.anchor.set(0.5, 0.5);
|
||||
this.addChild(sloticon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the equipment displayed in the slot
|
||||
* Snap the equipment icon inside the slot
|
||||
*/
|
||||
setEquipment(equipment: CharacterEquipment | null) {
|
||||
this.addChild(equipment);
|
||||
equipment.position.set(84, 83);
|
||||
snapEquipment(equipment: CharacterEquipment) {
|
||||
equipment.position.set(this.x + this.parent.x + 84, this.y + this.parent.y + 83);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an equipment can be dropped in this slot
|
||||
*/
|
||||
canDropEquipment(equipment: Equipment, x: number, y: number): CharacterEquipmentDrop | null {
|
||||
if (this.getBounds().contains(x, y)) {
|
||||
return {
|
||||
message: "Equip",
|
||||
callback: () => this.sheet.ship.equip(equipment)
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue