Skip to content

Commit

Permalink
feat(items): drag-and-drop XP spending
Browse files Browse the repository at this point in the history
* prompt to spend XP on dropping a relevant item onto an actor

#1588
  • Loading branch information
wrycu committed Aug 8, 2024
1 parent aff3c99 commit d137005
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 4 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
* Updated "item cards" to match the Mandar theme
* This change includes many minor improvements to the cards, such as showing damage on weapons and purchased talents on specializations
* The action to take when removing a combatant from combat is now configurable. This is in place of the previously-confusing (and quite annoying) behavior where you had to claim a slot in order to remove a combatant
* Dragging-and-dropping items on actors now prompts for spending XP to purchase that item ([#1588](https://github.com/StarWarsFoundryVTT/StarWarsFFG/issues/1588))
* Fixes:
* Includes species characteristics bonus when calculating upgrade cost ([#1638](https://github.com/StarWarsFoundryVTT/StarWarsFFG/issues/1638))
* Specializations: Talents are now correctly looked up in compendium
* Removed "unused" slot checking (on combatant defeat) as they would sometimes lead to actors being unable to act
* Weapon "special" text now properly renders dice icons ([#1625](https://github.com/StarWarsFoundryVTT/StarWarsFFG/issues/1625))
* Weapon `special` text now properly renders dice icons ([#1625](https://github.com/StarWarsFoundryVTT/StarWarsFFG/issues/1625))

`1.902`
* Features:
Expand Down
6 changes: 5 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -723,5 +723,9 @@
"SWFFG.Settings.Purchase.SignatureAbility.Name": "Signature Abilities Compendiums",
"SWFFG.Settings.Purchase.SignatureAbility.Hint": "Comma seperated compendiums to search for buying Signature Abilities (no spaces)",
"SWFFG.Settings.Purchase.Talent.Name": "Talent Compendiums",
"SWFFG.Settings.Purchase.Talent.Hint": "Comma seperated compendiums to search for buying Talents (no spaces)"
"SWFFG.Settings.Purchase.Talent.Hint": "Comma seperated compendiums to search for buying Talents (no spaces)",
"SWFFG.DragDrop.Title": "Purchase item, or grant for 0 xp?",
"SWFFG.DragDrop.PurchaseItem": "Purchase",
"SWFFG.DragDrop.GrantItem": "Grant",
"SWFFG.DragDrop.XPLog": "drag-and-drop"
}
79 changes: 77 additions & 2 deletions modules/actors/actor-sheet-ffg.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,88 @@ export class ActorSheetFFG extends ActorSheet {
await xpLogEarn(this.actor, startingXP, curAvailable + startingXP, curTotal + startingXP, game.i18n.format("SWFFG.GrantXPSpecies", {species: itemData.name}) );
}

if (this.actor.type === "character" && ["talent", "specialization", "signatureability", "forcepower"].includes(itemData.type)) {
const cost = await this.calcPurchasePrice(itemData);
const availableXP = this.actor.system.experience.available;
if (cost > 0 && cost < availableXP) {
new Dialog(
{
title: game.i18n.localize("SWFFG.DragDrop.Title"),
buttons: {
purchase: {
icon: '<i class="fas fa-hourglass"></i>',
label: game.i18n.localize("SWFFG.DragDrop.PurchaseItem"),
callback: async (that) => {
if (cost > 0) {
await this.object.update({
system: {
experience: {
available: availableXP - cost,
}
}
});
await xpLogSpend(
this.actor, `${game.i18n.localize("SWFFG.DragDrop.XPLog")} ${itemData.type} ${itemData.name}`,
cost,
this.actor.system.experience.available,
this.actor.system.experience.total
);
}
},
},
grant: {
icon: '<i class="fas fa-recycle"></i>',
label: game.i18n.localize("SWFFG.DragDrop.GrantItem"),
},
},
},
{
classes: ["dialog", "starwarsffg"],
}
).render(true);
}
}

// Create the owned item
return this._onDropItemCreate(itemData);
} else {
return super._onDropItem(event, data);
}
}

async calcPurchasePrice(itemData) {
let cost = 0;
if (itemData.type === "specialization") {
// check if the specialization is in career
const career = this.actor.items.find(i => i.type === "career");
if (career) {
const inCareerSpecializations = Object.values(career?.system?.specializations) || [];
let inCareer = false;
for (const careerSpecialization of inCareerSpecializations) {
if (careerSpecialization.name === itemData.name) {
inCareer = true;
break;
}
}
const specializationCount = (this.actor.items.filter(i => i.type === "specialization") || []).length;
cost = (specializationCount + 1) * 10;
if (!inCareer) {
cost += 10;
}
return cost;
} else {
return -1;
}
} else if (itemData.type === "talent") {
return -1;
} else if (itemData.type === "signatureability") {
return itemData.system.base_cost;
} else if (itemData.type === "forcepower") {
return itemData.system.base_cost;
}
return -1;
}

/* -------------------------------------------- */

/** @override */
Expand Down Expand Up @@ -1990,7 +2065,7 @@ export class ActorSheetFFG extends ActorSheet {
}
worldItemsPack = sortDataBy(worldItemsPack, "name");
selectableItems.push({pack: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.Talent.WorldItemsGroup"), items: worldItemsPack});

for (const source of sources) {
const pack = game.packs.get(source);
if (!pack) {
Expand Down Expand Up @@ -2080,7 +2155,7 @@ export class ActorSheetFFG extends ActorSheet {
const characteristicCurrentRank = this.actor.system.attributes[characteristic].value;
// this is the value without items that modify it
const characteristicCostValue = ModifierHelpers.getBaseValue(this.actor.items, characteristic, "Characteristic") + characteristicCurrentRank;

if (characteristicValue >= game.settings.get("starwarsffg", "maxAttribute")) {
ui.notifications.warn(game.i18n.localize("SWFFG.Actors.Sheets.Purchase.Characteristic.Max"));
return;
Expand Down

0 comments on commit d137005

Please sign in to comment.