-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
574 additions
and
575 deletions.
There are no files selected for viewing
File renamed without changes.
56 changes: 28 additions & 28 deletions
56
classes/cleric/eyes_of_night.js → classes/cleric/_DEPRECATED_eyes-of-night.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,28 @@ | ||
// EYES OF NIGHT | ||
// Required modules: warpgate, itemacro | ||
|
||
const range = 120; | ||
const targets = game.user.targets; | ||
const mod = Math.max(actor.system.abilities.wis.mod, 1); | ||
|
||
if (!targets.size.between(1, mod)) { | ||
ui.notifications.error(`Please target between 1 and ${mod} creatures.`); | ||
return; | ||
} | ||
|
||
const updates = { | ||
actor: {"system.attributes.senses.darkvision": range}, | ||
token: {"sight.visionMode": "darkvision", "sight.range": range} | ||
}; | ||
|
||
const options = { | ||
name: `Darkvision (${range}ft)`, | ||
description: `You are being granted ${range} feet of darkvision.` | ||
}; | ||
|
||
const use = await item.use(); | ||
if (!use) return; | ||
|
||
for (const target of targets) { | ||
await warpgate.mutate(target.document, updates, {}, options); | ||
} | ||
// EYES OF NIGHT | ||
// Required modules: warpgate, itemacro | ||
|
||
const range = 120; | ||
const targets = game.user.targets; | ||
const mod = Math.max(actor.system.abilities.wis.mod, 1); | ||
|
||
if (!targets.size.between(1, mod)) { | ||
ui.notifications.error(`Please target between 1 and ${mod} creatures.`); | ||
return; | ||
} | ||
|
||
const updates = { | ||
actor: {"system.attributes.senses.darkvision": range}, | ||
token: {"sight.visionMode": "darkvision", "sight.range": range} | ||
}; | ||
|
||
const options = { | ||
name: `Darkvision (${range}ft)`, | ||
description: `You are being granted ${range} feet of darkvision.` | ||
}; | ||
|
||
const use = await item.use(); | ||
if (!use) return; | ||
|
||
for (const target of targets) { | ||
await warpgate.mutate(target.document, updates, {}, options); | ||
} |
110 changes: 55 additions & 55 deletions
110
classes/cleric/harness_divine_power.js → ...leric/_DEPRECATED_harness-divine-power.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,55 @@ | ||
// HARNESS DIVINE POWER | ||
// required modules: itemacro | ||
|
||
const data = actor.getRollData(); | ||
const maxLevel = Math.ceil(data.attributes.prof / 2); | ||
const validLevels = []; | ||
for (let i = 1; i <= maxLevel; i++) { | ||
const key = `spell${i}`; | ||
if ((data.spells[key].value < data.spells[key].max) && (data.spells[key].max > 0)) { | ||
validLevels.push(key); | ||
} | ||
} | ||
const pact = data.spells.pact; | ||
if ((pact.max > 0) && (pact.level <= maxLevel) && (pact.value < pact.max)) validLevels.push("pact"); | ||
|
||
// bail out if you are not missing any spell slots or if the item has no remaining uses (limited uses and resources). | ||
if (!validLevels.length) return ui.notifications.warn("You are not missing any valid spell slots."); | ||
if (!item.system.uses.value) return ui.notifications.warn("You have no uses left of Harness Divine Power."); | ||
|
||
const resourceItem = actor.items.get(item.system.consume.target); | ||
const uses = resourceItem.system.uses; | ||
if (!uses.value) return ui.notifications.warn("You have no uses of Channel Divinity left."); | ||
|
||
// define dialog contents | ||
const options = validLevels.reduce((acc, e) => { | ||
const spells = data.spells[e]; | ||
const label = e === "pact" ? "Pact Slots" : CONFIG.DND5E.spellLevels[e.at(-1)]; | ||
return acc + `<option value="${e}">${label} (${spells.value} / ${spells.max})</option>`; | ||
}, ""); | ||
|
||
return Dialog.prompt({ | ||
title: item.name, | ||
rejectClose: false, | ||
label: "Recover", | ||
content: ` | ||
<p>Select a spell slot level.</p> | ||
<form> | ||
<div class="form-group"> | ||
<label>Spell Slot:</label> | ||
<div class="form-fields"> | ||
<select>${options}</select> | ||
</div> | ||
</div> | ||
</form>`, | ||
callback: async (html) => { | ||
const level = html[0].querySelector("select").value; | ||
const value = data.spells[level].value + 1; | ||
await actor.update({[`system.spells.${level}.value`]: value}); | ||
await actor.updateEmbeddedDocuments("Item", [ | ||
{_id: resourceItem.id, "system.uses.value": uses.value - 1}, | ||
{_id: item.id, "system.uses.value": item.uses.value - 1} | ||
]); | ||
ui.notifications.info("Recovered a spell slot!"); | ||
} | ||
}); | ||
// HARNESS DIVINE POWER | ||
// required modules: itemacro | ||
|
||
const data = actor.getRollData(); | ||
const maxLevel = Math.ceil(data.attributes.prof / 2); | ||
const validLevels = []; | ||
for (let i = 1; i <= maxLevel; i++) { | ||
const key = `spell${i}`; | ||
if ((data.spells[key].value < data.spells[key].max) && (data.spells[key].max > 0)) { | ||
validLevels.push(key); | ||
} | ||
} | ||
const pact = data.spells.pact; | ||
if ((pact.max > 0) && (pact.level <= maxLevel) && (pact.value < pact.max)) validLevels.push("pact"); | ||
|
||
// bail out if you are not missing any spell slots or if the item has no remaining uses (limited uses and resources). | ||
if (!validLevels.length) return ui.notifications.warn("You are not missing any valid spell slots."); | ||
if (!item.system.uses.value) return ui.notifications.warn("You have no uses left of Harness Divine Power."); | ||
|
||
const resourceItem = actor.items.get(item.system.consume.target); | ||
const uses = resourceItem.system.uses; | ||
if (!uses.value) return ui.notifications.warn("You have no uses of Channel Divinity left."); | ||
|
||
// define dialog contents | ||
const options = validLevels.reduce((acc, e) => { | ||
const spells = data.spells[e]; | ||
const label = e === "pact" ? "Pact Slots" : CONFIG.DND5E.spellLevels[e.at(-1)]; | ||
return acc + `<option value="${e}">${label} (${spells.value} / ${spells.max})</option>`; | ||
}, ""); | ||
|
||
return Dialog.prompt({ | ||
title: item.name, | ||
rejectClose: false, | ||
label: "Recover", | ||
content: ` | ||
<p>Select a spell slot level.</p> | ||
<form> | ||
<div class="form-group"> | ||
<label>Spell Slot:</label> | ||
<div class="form-fields"> | ||
<select>${options}</select> | ||
</div> | ||
</div> | ||
</form>`, | ||
callback: async (html) => { | ||
const level = html[0].querySelector("select").value; | ||
const value = data.spells[level].value + 1; | ||
await actor.update({[`system.spells.${level}.value`]: value}); | ||
await actor.updateEmbeddedDocuments("Item", [ | ||
{_id: resourceItem.id, "system.uses.value": uses.value - 1}, | ||
{_id: item.id, "system.uses.value": item.uses.value - 1} | ||
]); | ||
ui.notifications.info("Recovered a spell slot!"); | ||
} | ||
}); |
45 changes: 23 additions & 22 deletions
45
classes/cleric/steps_of_night.js → classes/cleric/_DEPRECATED_steps-of-night.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,23 @@ | ||
// STEPS OF NIGHT | ||
// required modules: itemacro | ||
|
||
const id = item.name.slugify({strict: true}); | ||
const effect = actor.effects.find(e => e.statuses.has(id)); | ||
if (effect) return effect.delete(); | ||
const use = await item.use(); | ||
if (!use) return; | ||
|
||
return actor.createEmbeddedDocuments("ActiveEffect", [{ | ||
name: item.name, | ||
changes: [{ | ||
key: "system.attributes.movement.fly", | ||
mode: CONST.ACTIVE_EFFECT_MODES.UPGRADE, | ||
value: actor.system.attributes.movement.walk | ||
}], | ||
duration: {seconds: 60}, | ||
icon: item.img, | ||
statuses: [id], | ||
description: "<p>You have a flying speed equal to your walking speed.</p>", | ||
"flags.visual-active-effects.data.content": item.system.description.value | ||
}]); | ||
// STEPS OF NIGHT | ||
// required modules: itemacro | ||
|
||
const id = item.name.slugify({strict: true}); | ||
const effect = actor.effects.find(e => e.statuses.has(id)); | ||
if (effect) return effect.delete(); | ||
const use = await item.use(); | ||
if (!use) return; | ||
|
||
return actor.createEmbeddedDocuments("ActiveEffect", [{ | ||
name: item.name, | ||
changes: [{ | ||
key: "system.attributes.movement.fly", | ||
mode: CONST.ACTIVE_EFFECT_MODES.UPGRADE, | ||
value: actor.system.attributes.movement.walk | ||
}], | ||
duration: {seconds: 60}, | ||
icon: item.img, | ||
statuses: [id], | ||
description: "<p>You have a flying speed equal to your walking speed.</p>", | ||
"flags.visual-active-effects.data.content": item.system.description.value | ||
}]); | ||
|
124 changes: 62 additions & 62 deletions
124
classes/cleric/twilight_sanctuary.js → .../cleric/_DEPRECATED_twilight-sanctuary.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,62 @@ | ||
// TWILIGHT SANCTUARY | ||
// required modules: itemacro, sequencer, jb2a-patreon, warpgate | ||
|
||
// CONSTS | ||
const file = "jb2a.markers.circle_of_stars.orangepurple"; | ||
const error = "Please target a token."; | ||
const target = game.user.targets.first(); | ||
|
||
// find Sequencer effect | ||
const [effect] = Sequencer.EffectManager.getEffects({name: item.name}); | ||
|
||
if (!effect) { | ||
const use = await item.use(); | ||
if (!use) return; | ||
return new Sequence() | ||
.effect() | ||
.attachTo(token) | ||
.persist() | ||
.name(item.name) | ||
.file(file) | ||
.size(canvas.grid.size * 8) | ||
.scaleIn(0, 800, {ease: "easeOutCubic"}) | ||
.rotateIn(180, 1200, {ease: "easeOutCubic"}) | ||
.scaleOut(0, 500, {ease: "easeOutCubic"}) | ||
.fadeOut(500, {ease: "easeOutCubic"}) | ||
.play(); | ||
} | ||
|
||
new Dialog({ | ||
title: item.name, | ||
buttons: { | ||
hp: { | ||
icon: "<i class='fa-solid fa-heart'></i>", | ||
label: "Grant temp HP", | ||
callback: async () => { | ||
if (!target) return ui.notifications.error(error); | ||
const roll = new Roll("1d6 + @classes.cleric.levels", actor.getRollData()); | ||
const {total} = await roll.evaluate({async: true}); | ||
await roll.toMessage({speaker, flavor: item.name}); | ||
const temp = target.actor.system.attributes.hp.temp ?? 0; | ||
const updates = {actor: {"system.attributes.hp.temp": total}}; | ||
const config = {permanent: true, name: item.name, description: `You are being granted ${total} temporary hit points.`}; | ||
if (total > temp) return warpgate.mutate(target.document, updates, {}, config); | ||
} | ||
}, | ||
effect: { | ||
icon: "<i class='fa-solid fa-check'></i>", | ||
label: "End an effect", | ||
callback: async () => { | ||
if (!target) return ui.notifications.error(error); | ||
return ChatMessage.create({speaker, content: `${actor.name} ends the charmed or frightened condition on ${target.name}.`}); | ||
} | ||
}, | ||
end: { | ||
icon: "<i class='fa-solid fa-times'></i>", | ||
label: "End Sanctuary", | ||
callback: async () => { | ||
return Sequencer.EffectManager.endEffects({name: item.name}); | ||
} | ||
} | ||
} | ||
}).render(true); | ||
// TWILIGHT SANCTUARY | ||
// required modules: itemacro, sequencer, jb2a-patreon, warpgate | ||
|
||
// CONSTS | ||
const file = "jb2a.markers.circle_of_stars.orangepurple"; | ||
const error = "Please target a token."; | ||
const target = game.user.targets.first(); | ||
|
||
// find Sequencer effect | ||
const [effect] = Sequencer.EffectManager.getEffects({name: item.name}); | ||
|
||
if (!effect) { | ||
const use = await item.use(); | ||
if (!use) return; | ||
return new Sequence() | ||
.effect() | ||
.attachTo(token) | ||
.persist() | ||
.name(item.name) | ||
.file(file) | ||
.size(canvas.grid.size * 8) | ||
.scaleIn(0, 800, {ease: "easeOutCubic"}) | ||
.rotateIn(180, 1200, {ease: "easeOutCubic"}) | ||
.scaleOut(0, 500, {ease: "easeOutCubic"}) | ||
.fadeOut(500, {ease: "easeOutCubic"}) | ||
.play(); | ||
} | ||
|
||
new Dialog({ | ||
title: item.name, | ||
buttons: { | ||
hp: { | ||
icon: "<i class='fa-solid fa-heart'></i>", | ||
label: "Grant temp HP", | ||
callback: async () => { | ||
if (!target) return ui.notifications.error(error); | ||
const roll = new Roll("1d6 + @classes.cleric.levels", actor.getRollData()); | ||
const {total} = await roll.evaluate({async: true}); | ||
await roll.toMessage({speaker, flavor: item.name}); | ||
const temp = target.actor.system.attributes.hp.temp ?? 0; | ||
const updates = {actor: {"system.attributes.hp.temp": total}}; | ||
const config = {permanent: true, name: item.name, description: `You are being granted ${total} temporary hit points.`}; | ||
if (total > temp) return warpgate.mutate(target.document, updates, {}, config); | ||
} | ||
}, | ||
effect: { | ||
icon: "<i class='fa-solid fa-check'></i>", | ||
label: "End an effect", | ||
callback: async () => { | ||
if (!target) return ui.notifications.error(error); | ||
return ChatMessage.create({speaker, content: `${actor.name} ends the charmed or frightened condition on ${target.name}.`}); | ||
} | ||
}, | ||
end: { | ||
icon: "<i class='fa-solid fa-times'></i>", | ||
label: "End Sanctuary", | ||
callback: async () => { | ||
return Sequencer.EffectManager.endEffects({name: item.name}); | ||
} | ||
} | ||
} | ||
}).render(true); |
Oops, something went wrong.