Skip to content

Commit

Permalink
Merge pull request dmdorman#1316 from phBalance/phBalance/skill-roll-…
Browse files Browse the repository at this point in the history
…resource-use-improvements

Skills can now use STUN for END or END reserves
  • Loading branch information
phBalance authored Oct 14, 2024
2 parents fd90a81 + b02ff3b commit a8b7ea2
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 54 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Version 4.0.2 (So far...) [Hero System 6e (Unofficial) v2](https://github.com/dmdorman/hero6e-foundryvtt)

- Strength rolls now use endurance. [#1253](https://github.com/dmdorman/hero6e-foundryvtt/issues/1253)
- Skills can now use STUN for END and END reserves.
- Encumbrance related improvements.
- Fix for 5e DAMAGE RESISTANCE and PD/ED purchased as a power, where the PD/ED was counted twice. [#1297](https://github.com/dmdorman/hero6e-foundryvtt/issues/1297)
- Improved KNOWLEDGE_SKILL descriptions. [#1278](https://github.com/dmdorman/hero6e-foundryvtt/issues/1278)
Expand Down
10 changes: 6 additions & 4 deletions module/item/item-attack.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ export async function AttackToHit(item, options) {
// (so we can be sneaky and not tell the target's DCV out loud).
heroRoller.addDice(-3);

// Consume resources
// Make sure there are enough resources and consume them
const {
error: resourceError,
warning: resourceWarning,
Expand Down Expand Up @@ -3051,9 +3051,11 @@ async function _calcKnockback(body, item, options, knockbackMultiplier) {
/**
* Multistage helper function useful for most item activations.
* 1. Make sure the actor associated with the item has enough resources to activate the item.
* 2. Display `ui.notification.error` prompts if actor does not have enough resources and return error.
* 3. If the user can use STUN in place of END prompt them for permission to do so
* 4. If there are enough resources, spend the resources and return full information.
* 2. Return an error if actor does not have enough resources.
* a. If the item doesn't have enough charges it is an error.
* b. If the item uses an endurance battery and doesn't have enough END it is an error.
* c. If the user can use STUN in place of END prompt them for permission to do so. Return a warning if they don't want to use STUN.
* 3. If there are enough resources, spend the resources and return full information.
*
* @param {HeroSystem6eItem} item
* @param {Object} options
Expand Down
70 changes: 20 additions & 50 deletions module/item/skill.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { HEROSYS } from "../herosystem6e.mjs";
import { HeroRoller } from "../utility/dice.mjs";
import { userInteractiveVerifyOptionallyPromptThenSpendResources } from "./item-attack.mjs";

async function _renderSkillForm(item, actor, stateData) {
const token = actor.token;
Expand Down Expand Up @@ -84,41 +85,22 @@ async function skillRoll(item, actor, html) {
const speaker = ChatMessage.getSpeaker({ actor: actor, token });
speaker.alias = actor.name;

// Charges?
const charges = item.findModsByXmlid("CHARGES");
if (charges) {
if (!item.system.charges?.value || parseInt(item.system.charges?.value) <= 0) {
const chatData = {
user: game.user._id,
content: `${item.name} has no charges remaining.`,
speaker: speaker,
};

await ChatMessage.create(chatData);
return;
}
}

// Cost END?
const endUse = parseInt(item.system.end);
const costEnd = item.findModsByXmlid("COSTSEND");
if (costEnd && endUse && item.actor) {
const newEnd = parseInt(item.actor.system.characteristics.end.value) - endUse;
// Make sure there are enough resources and consume them
const {
error: resourceError,
warning: resourceWarning,
resourcesRequired,
resourcesUsedDescription,
} = await userInteractiveVerifyOptionallyPromptThenSpendResources(item, {});
if (resourceError || resourceWarning) {
const chatData = {
user: game.user._id,
content: resourceError || resourceWarning,
speaker: speaker,
};

if (newEnd >= 0) {
await item.actor.update({
"system.characteristics.end.value": newEnd,
});
} else {
const chatData = {
user: game.user._id,
content: `Insufficient END to use ${item.name}.`,
speaker: speaker,
};

await ChatMessage.create(chatData);
return;
}
await ChatMessage.create(chatData);
return;
}

const formElement = html[0].querySelector("form");
Expand Down Expand Up @@ -169,29 +151,15 @@ async function skillRoll(item, actor, html) {
}

await skillRoller.makeSuccessRoll(true, successValue).roll();
let succeeded = skillRoller.getSuccess();
const succeeded = skillRoller.getSuccess();
const autoSuccess = skillRoller.getAutoSuccess();
const total = skillRoller.getSuccessTotal();
const margin = successValue - total;

const flavor = `${item.name.toUpperCase()} (${successValue}-) roll ${succeeded ? "succeeded" : "failed"} by ${
autoSuccess === undefined ? `${Math.abs(margin)}` : `rolling ${total}`
}`;
let rollHtml = await skillRoller.render(flavor);

// Charges
if (charges) {
await item.update({
"system.charges.value": parseInt(item.system.charges.value) - 1,
});
await item._postUpload();
rollHtml += `<p>Spent 1 charge.</p>`;
}

// END
if (costEnd && endUse && item.actor) {
rollHtml += `<p>Spent ${endUse} END.</p>`;
}
const rollHtml = await skillRoller.render(flavor);

// render card
const cardData = {
Expand All @@ -200,6 +168,8 @@ async function skillRoll(item, actor, html) {
}),
rolls: skillRoller.rawRolls(),
renderedRoll: rollHtml,
resourcesUsedDescription:
resourcesRequired.charges > 0 || resourcesRequired.end > 0 ? resourcesUsedDescription : undefined,
user: game.user._id,
speaker: speaker,
};
Expand Down
6 changes: 6 additions & 0 deletions templates/chat/skill-success-roll-card.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
{{/each}}
</div>

{{#if resourcesUsedDescription}}
<div class="card-section">
<div class="description-tiny">{{{ resourcesUsedDescription }}}</div>
</div>
{{/if}}

<div class="card-section">
<div class="hit-roll">{{{ renderedRoll }}}</div>
</div>
Expand Down

0 comments on commit a8b7ea2

Please sign in to comment.