Skip to content

Commit

Permalink
Merge pull request #1654 from StarWarsFoundryVTT/xp_spending_1629
Browse files Browse the repository at this point in the history
Xp spending 1629
  • Loading branch information
wrycu authored Aug 9, 2024
2 parents d2e70f1 + b37ace3 commit 6163f07
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 62 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
* Features:
* 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
* Generic slot combat tracker: The action to take when removing a combatant 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))
* XP spending now consistently uses a dollar sign to trigger spending instead of the various methods it previously used ([#1629](/~https://github.com/StarWarsFoundryVTT/StarWarsFFG/issues/1629))
* Fixes:
* Includes species characteristics bonus when calculating upgrade cost ([#1638](/~https://github.com/StarWarsFoundryVTT/StarWarsFFG/issues/1638))
* Includes species characteristics bonus when calculating characteristic 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
* Generic slot combat tracker: 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))

`1.902`
Expand Down
8 changes: 7 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"SWFFG.Name": "Name",
"SWFFG.Species": "Species",
"SWFFG.Career": "Career",
"SWFFG.Specializations": "Specializations",
"SWFFG.Specializations": "Specs",
"SWFFG.SignatureAbilities": "Signature Abilities",
"SWFFG.ForcePowers": "Force Powers",
"SWFFG.Wounds": "Wounds",
Expand Down Expand Up @@ -706,6 +706,8 @@
"SWFFG.Actors.Sheets.Purchase.SA.ConfirmText": "Spend {cost} XP to purchase {upgrade}?",
"SWFFG.Actors.Sheets.Purchase.SA.NotSet": "Please set career signature abilities in the career data tab on your career",
"SWFFG.Actors.Sheets.Purchase.SA.NoMatch": "You must purchase the required specialization upgrades to acquire a signature ability",
"SWFFG.Actors.Sheets.Purchase.Specialization.ConfirmTitle": "Purchase Upgrade",
"SWFFG.Actors.Sheets.Purchase.Specialization.ConfirmText": "Spend {cost} XP to purchase {upgrade}?",
"SWFFG.Actors.Sheets.Purchase.Talent.New.ContextMenuText": "Purchase Specialization",
"SWFFG.Actors.Sheets.Purchase.Career.Specialization.DropHint": "(drop specializations here to allow players to purchase them)",
"SWFFG.Actors.Sheets.Purchase.Career.Specializations.Header": "Specializations in this Career",
Expand All @@ -716,6 +718,10 @@
"SWFFG.Actors.Sheets.Purchase.Characteristic.Max": "You cannot buy further levels in this characteristic",
"SWFFG.Actors.Sheets.Purchase.Characteristic.ConfirmTitle": "Purchase level in {characteristic}",
"SWFFG.Actors.Sheets.Purchase.Characteristic.ConfirmText": "Spend {cost} XP to purchase level {level} in {characteristic}?",
"SWFFG.Actors.Sheets.Purchase.Tooltip.Specialization": "Purchase a new Specialization",
"SWFFG.Actors.Sheets.Purchase.Tooltip.ForcePower": "Purchase a new Force Power",
"SWFFG.Actors.Sheets.Purchase.Tooltip.SignatureAbility": "Purchase a new Signature Ability",
"SWFFG.Actors.Sheets.Purchase.Tooltip.SkilLRank": "Purchase a Skill Rank",
"SWFFG.Settings.Purchase.Specialization.Name": "Specialization Compendiums",
"SWFFG.Settings.Purchase.Specialization.Hint": "Comma seperated compendiums to search for buying Specializations (no spaces)",
"SWFFG.Settings.Purchase.ForcePower.Name": "Force Power Compendiums",
Expand Down
138 changes: 84 additions & 54 deletions modules/items/item-sheet-ffg.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export class ItemSheetFFG extends ItemSheet {
if (this.object.flags?.starwarsffg?.ffgIsOwned || this.object.flags?.starwarsffg?.ffgIsTemp) {
data.isTemp = true;
}
data.isOwned = this.object.flags?.starwarsffg?.ffgIsOwned;

switch (this.object.type) {
case "weapon":
Expand Down Expand Up @@ -281,38 +282,9 @@ export class ItemSheetFFG extends ItemSheet {
/** @override */
activateListeners(html) {
super.activateListeners(html);

// Prevent "purchase" context menu options when editing a sheet not attached to a character.
const isOwned = this.object?.flags?.starwarsffg?.ffgIsOwned;
if (isOwned) {
new ContextMenu(html, ".talent-upgrade.specialization-talent", [
{
name: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.Talent.ContextMenuText"),
icon: '<i class="fas fa-dollar"></i>',
callback: (li) => {
this._buyTalent(li);
},
},
]);
new ContextMenu(this.element, ".talent-upgrade.force-power", [
{
name: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.FP.ContextMenuText"),
icon: '<i class="fas fa-dollar"></i>',
callback: (li) => {
this._buyForcePower(li);
},
},
]);
new ContextMenu(this.element, ".talent-upgrade.signature-ability", [
{
name: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.SA.ContextMenuText"),
icon: '<i class="fas fa-dollar"></i>',
callback: (li) => {
this._buySignatureAbility(li);
},
},
]);
}
html.find(".ffg-purchase").click(async (ev) => {
await this._handleItemBuy(ev)
});

// register sheet options
if (["gear", "weapon", "armour"].includes(this.object.type)) {
Expand Down Expand Up @@ -820,7 +792,7 @@ export class ItemSheetFFG extends ItemSheet {
});
}

async _buyHandleClick(li, desired_item_type) {
async _buyHandleClick(cost, desired_item_type) {
const owned = this.object.flags?.starwarsffg?.ffgIsOwned;
const type = this.object.type;
if (type !== desired_item_type || !owned) {
Expand All @@ -847,7 +819,6 @@ export class ItemSheetFFG extends ItemSheet {
}
const availableXP = owner.system.experience.available;
const totalXP = owner.system.experience.total;
const cost = $(li).data("cost");
if (cost > availableXP) {
ui.notifications.warn(game.i18n.localize("SWFFG.Actors.Sheets.Purchase.NotEnoughXP"));
throw new Error("Not enough XP");
Expand Down Expand Up @@ -906,38 +877,51 @@ export class ItemSheetFFG extends ItemSheet {
).render(true);
}

async _buyForcePower(li) {
async _handleItemBuy(event) {
event.preventDefault();
event.stopPropagation();
const action = $(event.target).data("buy-action");
if (action === "forcepower-upgrade") {
await this._buyForcePowerUpgrade(event);
} else if (action === "signatureability-upgrade") {
await this._buySignatureAbilityUpgrade(event);
} else if (action === "specialization-upgrade") {
await this._buySpecializationUpgrade(event);
}
}

async _buyForcePowerUpgrade(event) {
const element = $(event.target);
const cost = element.data("cost");
const baseName = element.data("base-item-name");
const upgradeName = element.data("upgrade-name");
const upgradeId = element.data("upgrade-id");
let owner;
let cost;
let availableXP;
let totalXP;
try {
const basic_data = await this._buyHandleClick(li, "forcepower");
const basic_data = await this._buyHandleClick(cost, "forcepower");
owner = basic_data.owner;
cost = basic_data.cost;
availableXP = basic_data.availableXP;
totalXP = basic_data.totalXP;
} catch (e) {
return;
}
const baseName = $(li).data("base-item-name");
const upgrade = $(".talent-name", li).data("name");
const dialog = new Dialog(
{
title: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.FP.ConfirmTitle"),
content: game.i18n.format("SWFFG.Actors.Sheets.Purchase.FP.ConfirmText", {cost: cost, upgrade: upgrade}),
content: game.i18n.format("SWFFG.Actors.Sheets.Purchase.FP.ConfirmText", {cost: cost, upgrade: upgradeName}),
buttons: {
done: {
icon: '<i class="fas fa-dollar"></i>',
label: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.ConfirmPurchase"),
callback: async (that) => {
// update the form because the fields are read when an update is performed
const talentId = $(li).attr("id");
const input = $(`[name="data.upgrades.${talentId}.islearned"]`, this.element)[0];
const input = $(`[name="data.upgrades.${upgradeId}.islearned"]`, this.element)[0];
input.checked = true;
await this.object.sheet.submit({preventClose: true});
owner.update({system: {experience: {available: availableXP - cost}}});
await xpLogSpend(owner, `force power ${baseName} upgrade ${upgrade}`, cost, availableXP - cost, totalXP);
await xpLogSpend(owner, `force power ${baseName} upgrade ${upgradeName}`, cost, availableXP - cost, totalXP);
},
},
cancel: {
Expand All @@ -952,38 +936,84 @@ export class ItemSheetFFG extends ItemSheet {
).render(true);
}

async _buySignatureAbility(li) {
async _buySignatureAbilityUpgrade(event) {
const element = $(event.target);
const cost = element.data("cost");
const baseName = element.data("base-item-name");
const upgradeName = element.data("upgrade-name");
const upgradeId = element.data("upgrade-id");
let owner;
let cost;
let availableXP;
let totalXP;
try {
const basic_data = await this._buyHandleClick(li, "signatureability");
const basic_data = await this._buyHandleClick(cost, "signatureability");
owner = basic_data.owner;
cost = basic_data.cost;
availableXP = basic_data.availableXP;
totalXP = basic_data.totalXP;
} catch (e) {
return;
}
const baseName = $(li).data("base-item-name");
const upgrade = $(".talent-name", li).data("name");
const dialog = new Dialog(
{
title: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.SA.ConfirmTitle"),
content: game.i18n.format("SWFFG.Actors.Sheets.Purchase.SA.ConfirmText", {cost: cost, upgrade: upgrade}),
content: game.i18n.format("SWFFG.Actors.Sheets.Purchase.SA.ConfirmText", {cost: cost, upgrade: upgradeName}),
buttons: {
done: {
icon: '<i class="fas fa-dollar"></i>',
label: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.ConfirmPurchase"),
callback: async (that) => {
// update the form because the fields are read when an update is performed
const talentId = $(li).attr("id");
const input = $(`[name="data.upgrades.${talentId}.islearned"]`, this.element)[0];
const input = $(`[name="data.upgrades.${upgradeId}.islearned"]`, this.element)[0];
input.checked = true;
await this.object.sheet.submit({preventClose: true});
owner.update({system: {experience: {available: availableXP - cost}}});
await xpLogSpend(owner, `signature ability ${baseName} upgrade ${upgradeName}`, cost, availableXP - cost, totalXP);
},
},
cancel: {
icon: '<i class="fas fa-cancel"></i>',
label: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.CancelPurchase"),
},
},
},
{
classes: ["dialog", "starwarsffg"],
}
).render(true);
}

async _buySpecializationUpgrade(event) {
const element = $(event.target);
const cost = element.data("cost");
const baseName = element.data("base-item-name");
const upgradeName = element.data("upgrade-name");
const upgradeId = element.data("upgrade-id");
let owner;
let availableXP;
let totalXP;
try {
const basic_data = await this._buyHandleClick(cost, "specialization");
owner = basic_data.owner;
availableXP = basic_data.availableXP;
totalXP = basic_data.totalXP;
} catch (e) {
return;
}
const dialog = new Dialog(
{
title: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.Specialization.ConfirmTitle"),
content: game.i18n.format("SWFFG.Actors.Sheets.Purchase.Specialization.ConfirmText", {cost: cost, upgrade: upgradeName}),
buttons: {
done: {
icon: '<i class="fas fa-dollar"></i>',
label: game.i18n.localize("SWFFG.Actors.Sheets.Purchase.ConfirmPurchase"),
callback: async (that) => {
// update the form because the fields are read when an update is performed
const input = $(`[name="data.talents.${upgradeId}.islearned"]`, this.element)[0];
input.checked = true;
await this.object.sheet.submit({preventClose: true});
owner.update({system: {experience: {available: availableXP - cost}}});
await xpLogSpend(owner, `signature ability ${baseName} upgrade ${upgrade}`, cost, availableXP - cost, totalXP);
await xpLogSpend(owner, `specialization ${baseName} upgrade ${upgradeName}`, cost, availableXP - cost, totalXP);
},
},
cancel: {
Expand Down
9 changes: 6 additions & 3 deletions templates/actors/ffg-character-sheet.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ <h2><input name="name" type="text" value="{{actor.name}}" placeholder="{{localiz
<div class="drag-note">{{localize "SWFFG.DragNotes"}}</div>
{{/each_when}}
</td>
<td style="{{#if limited}}display:none;{{/if}}" class="ffg-purchase" data-buy-action="signatureability">
<td style="{{#if limited}}display:none;{{/if}}">
<i class="fas fa-dollar ffg-purchase" data-buy-action="signatureability" title="{{localize "SWFFG.Actors.Sheets.Purchase.Tooltip.SignatureAbility"}}"></i>
{{localize "SWFFG.SignatureAbilities"}}:
</td>
<td style="{{#if limited}}display:none;{{/if}}">
Expand All @@ -53,8 +54,9 @@ <h2><input name="name" type="text" value="{{actor.name}}" placeholder="{{localiz
<div class="drag-note">{{localize "SWFFG.DragNotes"}}</div>
{{/each_when}}
</td>
<td class="ffg-purchase" data-buy-action="forcepower">
<td>
{{#if (or (eq actor.flags.starwarsffg.config.enableForcePool undefined) (eq actor.flags.starwarsffg.config.enableForcePool true) )}}
<i class="fas fa-dollar ffg-purchase" data-buy-action="forcepower" title="{{localize "SWFFG.Actors.Sheets.Purchase.Tooltip.ForcePower"}}"></i>
{{localize "SWFFG.ForcePowers"}}:
{{/if}}
</td>
Expand All @@ -71,7 +73,8 @@ <h2><input name="name" type="text" value="{{actor.name}}" placeholder="{{localiz
</td>
</tr>
<tr style="{{#if limited}}display:none;{{/if}}">
<td class="ffg-purchase" data-buy-action="specialization">
<td>
<i class="fas fa-dollar ffg-purchase" data-buy-action="specialization" title="{{localize "SWFFG.Actors.Sheets.Purchase.Tooltip.Specialization" }}"></i>
{{localize "SWFFG.Specializations"}}:
</td>
<td>
Expand Down
5 changes: 5 additions & 0 deletions templates/items/ffg-forcepower-sheet.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
</div>
<div class="talent-cost">{{ localize "SWFFG.Cost"}}<input name="data.upgrades.{{key}}.cost" type="text" value="{{upgrade.cost}}" data-dtype="String" /></div>
<div class="talent-modifiers">
<a class="talent-action" data-itemid="{{key}}">
{{#if ../item.isOwned }}
<i class="fas fa-dollar ffg-purchase" data-buy-action="forcepower-upgrade" data-cost="{{upgrade.cost}}" data-base-item-name="{{../item.name}}" data-upgrade-name="{{ upgrade.name }}" data-upgrade-id="{{ key }}"></i>
{{/if}}
</a>
<a class="talent-action" data-itemid="{{key}}">
<i class="fas fa-cog"></i>
</a>
Expand Down
5 changes: 5 additions & 0 deletions templates/items/ffg-signatureability-sheet.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@
</div>
<div class="talent-cost">{{ localize "SWFFG.Cost"}}<input name="data.upgrades.{{key}}.cost" type="text" value="{{calculateSignatureAbilityCost key}}" data-dtype="String" /></div>
<div class="talent-modifiers">
<a class="talent-action" data-itemid="{{key}}">
{{#if ../item.isOwned }}
<i class="fas fa-dollar ffg-purchase" data-buy-action="signatureability-upgrade" data-cost="{{upgrade.cost}}" data-base-item-name="{{../item.name}}" data-upgrade-name="{{ upgrade.name }}" data-upgrade-id="{{ key }}"></i>
{{/if}}
</a>
<a class="talent-action" data-itemid="{{key}}">
<i class="fas fa-cog"></i>
</a>
Expand Down
5 changes: 5 additions & 0 deletions templates/items/ffg-specialization-sheet.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
</div>
<div class="talent-name {{#if (ne talent.name '')}}talent-modifiers{{/if}}" data-name="{{talent.name}}">
{{{talent.name}}}
<a class="talent-action" data-itemid="{{key}}">
{{#if ../item.isOwned }}
<i class="fas fa-dollar ffg-purchase" data-buy-action="specialization-upgrade" data-cost="{{talent.cost}}" data-base-item-name="{{../item.name}}" data-upgrade-name="{{ talent.name }}" data-upgrade-id="{{ key }}"></i>
{{/if}}
</a>
</div>
</div>
<div class="talent-body">
Expand Down
2 changes: 1 addition & 1 deletion templates/parts/actor/ffg-skills.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<div data-ability="{{skill.name}}" data-skilltype="{{skill.type}}" data-characteristic="{{skill.characteristic}}" class="pure-g skill" draggable="true">
<div class="pure-u-12-24">
<div class="skill-name">
{{#if (eq ../../this.actor.type "character")}}<i class="fas fa-dollar skill-purchase"></i>{{/if}}
{{#if (eq ../../this.actor.type "character")}}<i class="fas fa-dollar ffg-purchase" data-buy-action="skill" title="{{localize "SWFFG.Purchase.SkillRank"}}"></i>{{/if}}
{{#if skill.useForInitiative}}*{{/if}}{{skill.label}} {{#with (lookup ../../this.FFG.characteristics [characteristic])~}}
<div class="skill-characteristic" data-characteristic="{{skill.characteristic}}">({{localize abrev}})</div>
{{/with}}
Expand Down

0 comments on commit 6163f07

Please sign in to comment.