Skip to content

Commit

Permalink
Fixes #137, added #127, added #126
Browse files Browse the repository at this point in the history
  • Loading branch information
Haxxer committed Feb 27, 2023
1 parent 00add27 commit 435868d
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 32 deletions.
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Rest Recovery Changelog

## Version 1.4.10
- Added support for the War Wizard's Power Surge feature
- Fixed hit dice recovery fraction not being respected when long rest hit dice rolling was not enabled
- Fixed Configure Resource Recovery stretching to take all available space on most character sheets

## Version 1.4.9
- Added option to prevent users from initiating rests without being prompted
- Fixed module being visible and activatable in other systems
Expand Down
5 changes: 5 additions & 0 deletions languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"FeatureNames": {
"ArcaneRecovery": "Arcane Recovery",
"NaturalRecovery": "Natural Recovery",
"PowerSurge": "Power Surge",
"SongOfRest": "Song of Rest",
"ChefFeat": "Chef",
"ChefTools": "Cook's Utensils",
Expand Down Expand Up @@ -518,6 +519,10 @@
"Title": "Arcane Recovery name",
"Hint": "Here you can configure what a wizard's Arcane Recovery feature is called in your game. This can be a localized string."
},
"PowerSurge": {
"Title": "Power Surge name",
"Hint": "Here you can configure what a wizard's Power Surge feature is called in your game. This can be a localized string."
},
"NaturalRecovery": {
"Title": "Natural Recovery name",
"Hint": "Here you can configure what a druid's Natural Recovery feature is called in your game. This can be a localized string."
Expand Down
11 changes: 11 additions & 0 deletions scripts/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const CONSTANTS = {
DRUID_CLASS: "druid-class-name",
BARD_CLASS: "bard-class-name",
ARCANE_RECOVERY: "arcane-recovery-feature-name",
POWER_SURGE: "power-surge-feature-name",
NATURAL_RECOVERY: "natural-recovery-feature-name",
SONG_OF_REST: "song-of-rest-name",
CHEF_FEAT: "chef-feat-name",
Expand Down Expand Up @@ -844,6 +845,16 @@ CONSTANTS.DEFAULT_SETTINGS = {
default: "REST-RECOVERY.FeatureNames.ArcaneRecovery",
type: String
},
[CONSTANTS.SETTINGS.POWER_SURGE]: {
name: "REST-RECOVERY.Settings.ItemNames.PowerSurge.Title",
hint: "REST-RECOVERY.Settings.ItemNames.PowerSurge.Hint",
scope: "world",
group: "itemnames",
config: false,
localize: true,
default: "REST-RECOVERY.FeatureNames.PowerSurge",
type: String
},
[CONSTANTS.SETTINGS.NATURAL_RECOVERY]: {
name: "REST-RECOVERY.Settings.ItemNames.NaturalRecovery.Title",
hint: "REST-RECOVERY.Settings.ItemNames.NaturalRecovery.Hint",
Expand Down
8 changes: 7 additions & 1 deletion scripts/libwrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import CONSTANTS from "./constants.js";
import RestWorkflow from "./rest-workflow.js";
import LongRestDialog from "./formapplications/long-rest/long-rest.js";
import { custom_warning, getSetting } from "./lib/lib.js";
import * as lib from "./lib/lib.js";

export default function registerLibwrappers() {

Expand Down Expand Up @@ -244,7 +245,12 @@ function patch_getRestHitDiceRecovery() {
CONSTANTS.MODULE_NAME,
"CONFIG.Actor.documentClass.prototype._getRestHitDiceRecovery",
function (wrapped, args) {
return RestWorkflow.wrapperFn(this, wrapped, args, "_getRestHitDiceRecovery", true);
const rest = RestWorkflow.get(this)
const maxHitDice = rest ? { maxHitDice: rest._getMaxHitDiceRecovery() } : args;
if(lib.getSetting(CONSTANTS.SETTINGS.PRE_REST_REGAIN_HIT_DICE)){
return RestWorkflow.wrapperFn(this, wrapped, maxHitDice, "_getPostRestHitDiceRecovery");
}
return wrapped(maxHitDice);
}
)
}
Expand Down
69 changes: 39 additions & 30 deletions scripts/rest-workflow.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ export default class RestWorkflow {
this.consumableData = { items: [] };
}

static get LongRestItemNameHandlers() {
return {
[lib.getSetting(CONSTANTS.SETTINGS.POWER_SURGE, true)]: "_handlePowerSurgeFeature"
}
}

get maxHP() {
return this.actor.system.attributes.hp.max + (this.actor.system.attributes.hp.tempmax ?? 0)
}
Expand Down Expand Up @@ -575,17 +581,10 @@ export default class RestWorkflow {
}
}

static wrapperFn(actor, wrapped, args, fnName, runWrap = true) {
static wrapperFn(actor, wrapped, args, fnName) {

const workflow = this.get(actor);

if (!runWrap) {
if (workflow && workflow[fnName]) {
return wrapped(workflow[fnName](args));
}
return wrapped(args);
}

let updates = wrapped(args);
if (workflow && workflow[fnName]) {
updates = workflow[fnName](updates, args);
Expand All @@ -595,17 +594,10 @@ export default class RestWorkflow {

}

static async asyncWrappedFn(actor, wrapped, args, fnName, runWrap = true) {
static async asyncWrappedFn(actor, wrapped, args, fnName) {

const workflow = this.get(actor);

if (!runWrap) {
if (workflow && workflow[fnName]) {
return wrapped(workflow[fnName](args));
}
return wrapped(args);
}

let updates = await wrapped(args);
if (workflow && workflow[fnName]) {
updates = workflow[fnName](updates, args);
Expand All @@ -619,7 +611,7 @@ export default class RestWorkflow {

if (!lib.getSetting(CONSTANTS.SETTINGS.PRE_REST_REGAIN_HIT_DICE)) return;

let { maxHitDice } = this._getMaxHitDiceRecovery();
const maxHitDice = this._getMaxHitDiceRecovery();

this.preRestRegainHitDice = true;
let { updates, hitDiceRecovered } = this.actor._getRestHitDiceRecovery({ maxHitDice });
Expand Down Expand Up @@ -662,7 +654,7 @@ export default class RestWorkflow {
}
}

let { maxHitDice } = this._getMaxHitDiceRecovery();
const maxHitDice = this._getMaxHitDiceRecovery();
let { hitDiceRecovered } = this.actor._getRestHitDiceRecovery();

if (this.longRest) {
Expand Down Expand Up @@ -934,16 +926,11 @@ export default class RestWorkflow {

}

_getRestHitDiceRecovery(results) {

if (this.preRestRegainHitDice || !lib.getSetting(CONSTANTS.SETTINGS.PRE_REST_REGAIN_HIT_DICE)) {
return results;
}

_getPostRestHitDiceRecovery(results) {
if(this.preRestRegainHitDice) return results;
results.hitDiceRecovered = Math.max(0, Math.min(this.actor.system.details.level, this.totalHitDice) - this.healthData.startingHitDice);
results.updates = [];
return results;

}

_getMaxHitDiceRecovery({ maxHitDice = undefined } = {}) {
Expand Down Expand Up @@ -987,7 +974,7 @@ export default class RestWorkflow {
maxHitDice = 0;
}

return { maxHitDice };
return maxHitDice;

}

Expand Down Expand Up @@ -1143,8 +1130,13 @@ export default class RestWorkflow {

const actorRollData = this.actor.getRollData();

const longRestItemNameHandlers = RestWorkflow.LongRestItemNameHandlers;

for (const item of this.actor.items) {
if (item.system.uses) {
const itemHandlerFn = longRestItemNameHandlers[item.name];
if(recoverLongRestUses && itemHandlerFn){
this[itemHandlerFn](actorRollData, updates, item, rolls);
} else if (item.system.uses) {
if (recoverDailyUses && item.system.uses.per === "day") {
this._recoverItemUse(actorRollData, updates, item, dailyMultiplier, rolls);
} else if (recoverLongRestUses && item.system.uses.per === "lr") {
Expand All @@ -1170,7 +1162,7 @@ export default class RestWorkflow {
}


_recoverItemUse(actor, updates, item, multiplier = 1.0, rolls) {
_recoverItemUse(actorRollData, updates, item, multiplier = 1.0, rolls) {

const usesMax = item.system.uses.max;
const usesCur = item.system.uses.value;
Expand All @@ -1183,7 +1175,7 @@ export default class RestWorkflow {
let recoverValue;
if (customRecovery && customFormula) {
const customRoll = lib.evaluateFormula(customFormula, {
actor: actor,
actor: actorRollData,
item: foundry.utils.deepClone(item.system)
});
rolls.push(customRoll)
Expand Down Expand Up @@ -1213,6 +1205,24 @@ export default class RestWorkflow {

}

_handlePowerSurgeFeature(actorRollData, updates, item) {

const numSurges = getProperty(item, "system.uses.value");
if(numSurges === 1) return;

const update = updates.find(update => update._id === item.id);

if (update) {
update["system.uses.value"] = 1;
} else {
updates.push({
_id: item.id,
"system.uses.value": 1
});
}

}

async _handleFoodAndWaterItems(updates) {

if (!lib.getSetting(CONSTANTS.SETTINGS.ENABLE_FOOD_AND_WATER)) return updates;
Expand Down Expand Up @@ -1330,7 +1340,6 @@ export default class RestWorkflow {

}


static _patchConsumableItem(item, updates) {
if (!lib.getSetting(CONSTANTS.SETTINGS.ENABLE_FOOD_AND_WATER)) return;
updates["system.uses.value"] = 1;
Expand Down
2 changes: 1 addition & 1 deletion scripts/sheet-overrides.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ function patch_actorSheet(app, html, data) {
targetElem = html.find('.center-pane .resources')[0];
if (!targetElem) return;
}
const elem = $(`<div class="form-group" style="${border ? "border-bottom: 2px groove #eeede0; padding-bottom: 0.25rem;" : "padding-top: 0.25rem;"}" title="Module: Rest Recovery for 5e">
const elem = $(`<div class="form-group" style="${border ? "border-bottom: 2px groove #eeede0; padding-bottom: 0.25rem;" : "padding-top: 0.25rem;"} flex:0;" title="Module: Rest Recovery for 5e">
<label style="flex: none; line-height: 20px; font-weight: bold; margin: 0 10px 0 0;">${game.i18n.localize("REST-RECOVERY.Dialogs.Resources.Configure")}</label>
<a class="config-button" title="${game.i18n.localize("REST-RECOVERY.Dialogs.Resources.Configure")}" style="flex:1;">
<i class="fas fa-cog" style="float: right; margin-right: 3px; text-align: right; color: #999;"></i>
Expand Down

0 comments on commit 435868d

Please sign in to comment.