Skip to content

Commit

Permalink
v2.4.40
Browse files Browse the repository at this point in the history
fix a minor bug with spell casting dialog.
  • Loading branch information
misthero committed Feb 22, 2025
1 parent b646f9b commit df4673e
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 62 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# CHANGELOG

## [2.4.40]

### Compatibility release

- Bugfix for D&D system 4.3.3

## [2.4.32]

### Fixed some bug with auto calculation and pact magic
Expand Down
6 changes: 3 additions & 3 deletions module.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": "dnd5e-spellpoints",
"title": "Advanced Magic - Spell Points System 5e",
"description": "FoundryVTT module for Spell Points System in D&D5e. This module use the optional rules found on DMG to allow character to cast spells using a resource named 'Spell Points'",
"version": "2.4.32",
"version": "2.4.40",
"compatibility": {
"minimum": "12",
"verified": "12.331"
Expand All @@ -14,15 +14,15 @@
"type": "system",
"manifest": "https://raw.githubusercontent.com/foundryvtt/dnd5e/master/system.json",
"compatibility": {
"verified": "4.0.2",
"verified": "4.3.3",
"minimum": "4.0.0"
}
}
]
},
"url": "https://github.com/misthero/dnd5e-spellpoints",
"manifest": "https://github.com/misthero/dnd5e-spellpoints/releases/latest/download/module.json",
"download": "https://github.com/misthero/dnd5e-spellpoints/releases/download/v2.4.32/dnd5e-spellpoints.zip",
"download": "https://github.com/misthero/dnd5e-spellpoints/releases/download/v2.4.40/dnd5e-spellpoints.zip",
"authors": [
{
"name": "misthero",
Expand Down
4 changes: 4 additions & 0 deletions scripts/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ Hooks.on("renderActivityUsageDialog", async (dialog, html) => {
SpellPoints.checkDialogSpellPoints(dialog, html);
})

Hooks.on("dnd5e.preUseActivity", async (activity, usageConfig, dialogConfig, messageConfig) => {
SpellPoints.checkPreUseActivity(activity, usageConfig, dialogConfig, messageConfig);
})

/** render activity sheet to add consume spellpoints **/
Hooks.on("renderActivitySheet", async (sheet, html) => {
SpellPoints.alterActivityDialogSP(sheet, html);
Expand Down
130 changes: 72 additions & 58 deletions scripts/spellpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,43 @@ export class SpellPoints {
return [item, consume, options];
}


// prepare the spellpoints configuration.
static async checkPreUseActivity(activity, usageConfig, dialogConfig, messageConfig) {
if (!activity.isSpell) {
// exit if not a spell
return [activity, usageConfig, dialogConfig, messageConfig];
}

const actor = activity.actor;
const spellPointItem = SpellPoints.getSpellPointsItem(actor);

if (!this.isActorCharacter(actor) || !spellPointItem) {
// exit if the actor is not a character or if the actor has no spell point resource
return [activity, usageConfig, dialogConfig, messageConfig];
}

// is a spell, is a character, and has a spell point resource
usageConfig.consume.shouldUseSpellpoints = true;
usageConfig.spellPointsItem = spellPointItem;

// add custom classes to the dialog
if (!dialogConfig.applicationClass.DEFAULT_OPTIONS.classes.includes('spellpoints-cast')) {
dialogConfig.applicationClass.DEFAULT_OPTIONS.classes.push('spellpoints-cast');
}

if (!usageConfig.consume.spellSlot) {
// set consume spellPoints to false and exit if not consuming a spell slot
usageConfig.consume.spellPoints = false;
return [activity, usageConfig, dialogConfig, messageConfig];
}

usageConfig.consume.spellPoints = true;
usageConfig.consume.spellSlot = false;

return [activity, usageConfig, dialogConfig, messageConfig];
}

/**
* renderActivityUsageDialog hook
* It checks if the spell is being cast by a player character, and if so, it replaces the spell slot
Expand All @@ -334,105 +371,82 @@ export class SpellPoints {
*/
static async checkDialogSpellPoints(dialog, html) {

var Appconfig = foundry.utils.getProperty(dialog, "config");
var usageConfig = foundry.utils.getProperty(dialog, "config");

// Declare settings as a separate variable because jQuery overrides `this` when in an each() block
let settings = this.settings;

if (typeof Appconfig?.consume?.spellPoints == 'undefined') {
if (dialog.config.spell.slot == 'pact' && settings.spFormula == 'DMG') {
// do nothing
} else {
dialog.config.consume.spellSlot = false;
dialog.config.consume.spellPoints = true;
}
if (usageConfig?.consume?.shouldUseSpellpoints !== true) {
return;
}

if (dialog.activity.consumption.spellSlot == false) {
return [dialog, html];
}
//console.log('checkDialogSpellPoints usageConfig', usageConfig);

Appconfig = foundry.utils.getProperty(dialog, "config");
// Declare settings as a separate variable because jQuery overrides `this` when in an each() block
let settings = this.settings;

/** check if actor is a player character **/
let actor = foundry.utils.getProperty(dialog, "item.actor");

if (!this.isActorCharacter(actor))
return;




/** check if this is a spell **/
// TODO: maybe this check is not correct anymore
if (foundry.utils.getProperty(dialog, "item.type") !== "spell")
return;

$(html).addClass('spellpoints-cast');

const spell = dialog.item.system;
const preparation = spell.preparation.mode; //prepared,pact,always,atwill,innate

// spell level can change later if casting it with a greater slot, baseSpellLvl is the default
const baseSpellLvl = spell.level;

/** get spellpoints **/

const spellPointItem = SpellPoints.getSpellPointsItem(actor);
if (!spellPointItem) {
// this actor has no spell point resource what to do?
return;
}
const spellPointItem = usageConfig.spellPointsItem;

if (spellPointItem && spellPointItem.flags?.spellpoints?.override) {
settings = isset(spellPointItem.flags?.spellpoints?.config) ? spellPointItem.flags?.spellpoints?.config : settings;
}

let level = 'none';
let cost = 0;
let actualSpellPoints = spellPointItem.system.uses.value;

/** Replace list of spell slots with list of spell point costs **/
$('select[name="spell.slot"] option', $(html)).each(function () {
let selectValue = $(this).val();
if (usageConfig.consume.spellPoints) {
$('select[name="spell.slot"] option', $(html)).each(function () {
let optionValue = $(this).val();

if (selectValue == 'pact') {
level = actor.system.spells.pact.level;
} else {
level = selectValue.replace('spell', '');
}
//console.log('LEVEL', level);
cost = SpellPoints.withActorData(settings.spellPointsCosts[level], actor);
if (settings.spFormula == 'DMG' && selectValue == 'pact') {
// do nothing
} else {
let newText = `${CONFIG.DND5E.spellLevels[level]} (${game.i18n.format(SP_MODULE_NAME + ".spellCost", { amount: cost, SpellPoints: spellPointItem.name })})`
$(this).text(newText);
}
})
if (optionValue == 'pact') {
level = actor.system.spells.pact.level;
} else {
level = optionValue.replace('spell', '');
}

cost = SpellPoints.withActorData(settings.spellPointsCosts[level], actor);
if (settings.spFormula == 'DMG' && optionValue == 'pact') {
// do nothing
} else {
const spCostText = game.i18n.format(SP_MODULE_NAME + ".spellCost", { amount: cost + '/' + actualSpellPoints, SpellPoints: spellPointItem.name });
let newText = `${CONFIG.DND5E.spellLevels[level]} (${spCostText})`;
if (usageConfig.consume.spellSlot) {
newText = $(this).text() + ' (' + spCostText + ')';
}

$(this).text(newText);
}
})
}

let consumeInput = $('dnd5e-checkbox[name="consume.spellSlot"]', $(html)).parents('.form-group');
const consumeString = game.i18n.format(SP_MODULE_NAME + ".consumeSpellSlotInput", { SpellPoints: spellPointItem.name });
const consumeSpellPoints = Appconfig.consume.spellPoints ? "checked" : '';
const consumeSpellPoints = usageConfig.consume.spellPoints ? "checked" : '';
consumeInput.parent().append(`<div class="form-group">
<label>${consumeString}</label>
<div class="form-fields">
<input type="checkbox" name="consume.spellPoints" ${consumeSpellPoints}></div></div>`);

if (!dialog.config.consume.spellSlot) {
$('dnd5e-checkbox[name="consume.spellSlot"]', $(html)).removeAttr('checked');
}

if (level == 'none')
return;

/** Calculate spell point cost and warn user if they have none left */
let spellPointCost = 0;
let actualSpellPoints = spellPointItem.system.uses.value;

if (preparation == 'pact')
if (preparation == 'pact') {
spellPointCost = cost;
else
} else {
spellPointCost = SpellPoints.withActorData(settings.spellPointsCosts[baseSpellLvl], actor);
}
const missing_points = (typeof actualSpellPoints === 'undefined' || actualSpellPoints - spellPointCost < 0);
const messageNotEnough = game.i18n.format(SP_MODULE_NAME + ".youNotEnough", { SpellPoints: spellPointItem.name });

Expand Down
2 changes: 1 addition & 1 deletion scripts/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const checkUpdate = function () {
updateSuccess = update2_4_12();
}

// update previous version
// update previous version setting
if (updateSuccess) {
const currentVersion = game.modules.get(SP_MODULE_NAME).version;
game.settings.set(SP_MODULE_NAME, "spPrevVersion", currentVersion);
Expand Down
9 changes: 9 additions & 0 deletions templates/spellpoint-module-config.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<input type="hidden" name="spellPointsByLevel.{{level}}" value="{{cost}}"/>
{{/each}}

<!--
<div class="form-group">
<label>{{localize "dnd5e-spellpoints.resourceLabel"}}</label>
<input
Expand All @@ -24,6 +25,14 @@
/>
<p class="notes">{{localize "dnd5e-spellpoints.resourceNote"}}</p>
</div>
-->
<input
type="hidden"
name="spResource"
data-dtype="string"
value="{{spResource}}"
/>

<div class="description new-item">
<p>{{localize "dnd5e-spellpoints.newV3ItemUsage"}}</p>
<a
Expand Down

0 comments on commit df4673e

Please sign in to comment.