add improved boost-lower trait, helpers for shape change
This commit is contained in:
parent
3135a46450
commit
757f98272a
@ -2,5 +2,6 @@
|
|||||||
|
|
||||||
* [x] Smite
|
* [x] Smite
|
||||||
* [x] Protection
|
* [x] Protection
|
||||||
* Boost/Lower Trait
|
* [x] Boost/Lower Trait
|
||||||
* Summon Ally
|
* [x] Summon Ally (Automated Evocations)
|
||||||
|
* [x] Shape Change (Automated Evocations)
|
||||||
|
|||||||
@ -5,7 +5,7 @@ if (!extra) {
|
|||||||
extra = {};
|
extra = {};
|
||||||
}
|
}
|
||||||
if (!extra.name) { extra.name = effect.label }
|
if (!extra.name) { extra.name = effect.label }
|
||||||
if (!extra.duration) { extra.duration = effect.duration.rounds }
|
if (!extra.duration) { extra.duration = effect.duration?.rounds }
|
||||||
if (!extra.startMessage) {
|
if (!extra.startMessage) {
|
||||||
extra.startMessage = `${effect.label}'s effects start`
|
extra.startMessage = `${effect.label}'s effects start`
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ if (game.modules.get("turnAlert")?.active) {
|
|||||||
}
|
}
|
||||||
await TurnAlert.create(alertData);
|
await TurnAlert.create(alertData);
|
||||||
}
|
}
|
||||||
} else if (game.modules.get("about-time")?.active) {
|
} else if (game.modules.get("about-time")?.active && extra.duration) {
|
||||||
let duration = extra.duration * 6;
|
let duration = extra.duration * 6;
|
||||||
let preDuration = duration - 6;
|
let preDuration = duration - 6;
|
||||||
console.log("effects end in duration:", duration, preDuration)
|
console.log("effects end in duration:", duration, preDuration)
|
||||||
|
|||||||
@ -5,7 +5,16 @@ let assignedActor = args[0].assignedActor;
|
|||||||
let data = {
|
let data = {
|
||||||
actor: {},
|
actor: {},
|
||||||
token: {},
|
token: {},
|
||||||
embedded: {Item: {}}
|
embedded: {
|
||||||
|
ActiveEffect: {
|
||||||
|
"override": {
|
||||||
|
icon: assignedActor.data.img,
|
||||||
|
label: `${assignedActor.data.name} Override`,
|
||||||
|
changes: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Item: {}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const name = `${assignedActor.data.token.name} (${summon.data.token.name})`;
|
const name = `${assignedActor.data.token.name} (${summon.data.token.name})`;
|
||||||
@ -22,11 +31,29 @@ data.token['name'] = name;
|
|||||||
|
|
||||||
for (const attr of keptAttributes) {
|
for (const attr of keptAttributes) {
|
||||||
let attrData = assignedActor.data.data.attributes[attr];
|
let attrData = assignedActor.data.data.attributes[attr];
|
||||||
data.actor[`data.attributes.${attr}`] = attrData;
|
data.embedded.ActiveEffect.override.changes.push({
|
||||||
|
key: `data.attributes.${attr}.die.sides`,
|
||||||
|
value: assignedActor.data.data.attributes[attr].die.sides,
|
||||||
|
mode: foundry.CONST.ACTIVE_EFFECT_MODES.OVERRIDE
|
||||||
|
});
|
||||||
|
data.embedded.ActiveEffect.override.changes.push({
|
||||||
|
key: `data.attributes.${attr}.die.modifier`,
|
||||||
|
value: assignedActor.data.data.attributes[attr].die.modifier,
|
||||||
|
mode: foundry.CONST.ACTIVE_EFFECT_MODES.OVERRIDE
|
||||||
|
});
|
||||||
let skills = assignedActor.items.filter(
|
let skills = assignedActor.items.filter(
|
||||||
i => i.type === 'skill' && i.data.data.attribute === attr)
|
i => i.type === 'skill' && i.data.data.attribute === attr);
|
||||||
for(const skill of skills) {
|
for(const skill of skills) {
|
||||||
data.embedded['Item'][skill.name] = skill.data;
|
data.embedded.ActiveEffect.override.changes.push({
|
||||||
|
"key": `@Skill{${skill.name}}[data.die.sides]`,
|
||||||
|
"value": skill.data.data.die.sides,
|
||||||
|
"mode": foundry.CONST.ACTIVE_EFFECT_MODES.OVERRIDE
|
||||||
|
});
|
||||||
|
data.embedded.ActiveEffect.override.changes.push({
|
||||||
|
"key": `@Skill{${skill.name}}[data.die.modifier]`,
|
||||||
|
"value": skill.data.data.die.modifier,
|
||||||
|
"mode": foundry.CONST.ACTIVE_EFFECT_MODES.OVERRIDE
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const otherItems = assignedActor.items.filter(
|
const otherItems = assignedActor.items.filter(
|
||||||
|
|||||||
238
macros/power_effects/boost-lower-trait.js
Normal file
238
macros/power_effects/boost-lower-trait.js
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
const version = 'v2.0';
|
||||||
|
const UPICON = "icons/magic/life/cross-embers-glow-yellow-purple.webp";
|
||||||
|
const DOWNICON = "icons/magic/movement/chevrons-down-yellow.webp";
|
||||||
|
|
||||||
|
if ( canvas.tokens.controlled[0]===undefined && Array.from(game.user.targets)[0]===undefined ) {
|
||||||
|
ui.notifications.error("Please, select or target a token."); // No Token is Selected
|
||||||
|
} else {
|
||||||
|
main();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
let tokens = [];
|
||||||
|
tokens = tokens.concat(Array.from(game.user.targets));
|
||||||
|
tokens = tokens.concat(canvas.tokens.controlled);
|
||||||
|
|
||||||
|
let groups = {
|
||||||
|
"Attributes": [
|
||||||
|
"Agility",
|
||||||
|
"Smarts",
|
||||||
|
"Spirit",
|
||||||
|
"Strength",
|
||||||
|
"Vigor"
|
||||||
|
],
|
||||||
|
"Skills": [],
|
||||||
|
}
|
||||||
|
let traits = {
|
||||||
|
"Agility": {
|
||||||
|
type: "attribute",
|
||||||
|
name: "Agility",
|
||||||
|
modkey: "data.attributes.agility.die.modifier",
|
||||||
|
diekey: "data.attributes.agility.die.sides"
|
||||||
|
},
|
||||||
|
"Smarts": {
|
||||||
|
type: "attribute",
|
||||||
|
name: "Smarts",
|
||||||
|
modkey: "data.attributes.smarts.die.modifier",
|
||||||
|
diekey: "data.attributes.smarts.die.sides"
|
||||||
|
},
|
||||||
|
"Spirit": {
|
||||||
|
type: "attribute",
|
||||||
|
name: "Spirit",
|
||||||
|
modkey: "data.attributes.spirit.die.modifier",
|
||||||
|
diekey: "data.attributes.spirit.die.sides"
|
||||||
|
},
|
||||||
|
"Strength": {
|
||||||
|
type: "attribute",
|
||||||
|
name: "Strength",
|
||||||
|
modkey: "data.attributes.strength.die.modifier",
|
||||||
|
diekey: "data.attributes.strength.die.sides"
|
||||||
|
},
|
||||||
|
"Vigor": {
|
||||||
|
type: "attribute",
|
||||||
|
name: "Vigor",
|
||||||
|
modkey: "data.attributes.vigor.die.modifier",
|
||||||
|
diekey: "data.attributes.vigor.die.sides"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var token of tokens) {
|
||||||
|
let skills = token.actor.items.filter(e => e.type == "skill");
|
||||||
|
for (const skill of skills) {
|
||||||
|
let name = skill.data.name;
|
||||||
|
traits[name] = {
|
||||||
|
type: "skill", name: name,
|
||||||
|
modkey: `@Skill{${name}}[data.die.modifier]`,
|
||||||
|
diekey: `@Skill{${name}}[data.die.sides]`
|
||||||
|
};
|
||||||
|
groups.Skills.push(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var traitoptions = `<select id="select-trait" name="select-trait">`;
|
||||||
|
for (const group in groups) {
|
||||||
|
traitoptions += `<optgroup label="${group}">`;
|
||||||
|
for (const trait of groups[group]) {
|
||||||
|
traitoptions += `<option value="${trait}">${trait}</option>`;
|
||||||
|
}
|
||||||
|
traitoptions += '</optgroup>';
|
||||||
|
}
|
||||||
|
traitoptions += `</select>`;
|
||||||
|
|
||||||
|
var applyChanges = false;
|
||||||
|
var raise = false;
|
||||||
|
new Dialog({
|
||||||
|
title: `Boost/Lower Trait - ${version}`,
|
||||||
|
content: `
|
||||||
|
<style>
|
||||||
|
div.blueTable {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
.divTable.blueTable .divTableCell, .divTable.blueTable .divTableHead {
|
||||||
|
}
|
||||||
|
.blueTable .tableFootStyle {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.blueTable .tableFootStyle .links {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.blueTable .tableFootStyle .links a{
|
||||||
|
display: inline-block;
|
||||||
|
background: #1C6EA4;
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.blueTable.outerTableFooter {
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
.blueTable.outerTableFooter .tableFootStyle {
|
||||||
|
padding: 3px 5px;
|
||||||
|
}
|
||||||
|
/* DivTable.com */
|
||||||
|
.divTable{ display: table; }
|
||||||
|
.divTableRow { display: table-row; }
|
||||||
|
.divTableHeading { display: table-header-group;}
|
||||||
|
.divTableCell, .divTableHead { display: table-cell;}
|
||||||
|
.divTableHeading { display: table-header-group;}
|
||||||
|
.divTableFoot { display: table-footer-group;}
|
||||||
|
.divTableBody { display: table-row-group;}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="divTable blueTable">
|
||||||
|
<div class="divTableBody">
|
||||||
|
<div class="divTableRow">
|
||||||
|
<div class="divTableCell"><b>Which Trait?</b></div>
|
||||||
|
<div class="divTableCell"><b>Boost or Lower?</b></div>
|
||||||
|
</div>
|
||||||
|
<div class="divTableRow">
|
||||||
|
<div class="divTableCell">${traitoptions}</div>
|
||||||
|
<div class="divTableCell">
|
||||||
|
<select id="select-direction" name="select-direction">
|
||||||
|
<option value="Boost">Boost</option>
|
||||||
|
<option value="Lower">Lower</option>
|
||||||
|
</select
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</br>
|
||||||
|
`,
|
||||||
|
buttons: {
|
||||||
|
apply: {
|
||||||
|
label: "Apply",
|
||||||
|
callback: () => { applyChanges = true; raise }
|
||||||
|
},
|
||||||
|
raise: {
|
||||||
|
label: "Apply with raise",
|
||||||
|
callback: () => { applyChanges = true; raise = true }
|
||||||
|
},
|
||||||
|
cancel: {
|
||||||
|
label: "Cancel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
default: "apply",
|
||||||
|
close: html => {
|
||||||
|
if (applyChanges) {
|
||||||
|
let direction = html.find('[name="select-direction"]')[0].value;
|
||||||
|
let trait = html.find('[name="select-trait"]')[0].value;
|
||||||
|
createEffect(tokens, traits, direction, trait, raise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).render(true);
|
||||||
|
} // end main
|
||||||
|
|
||||||
|
async function createEffect(tokens, traits, direction, trait, raise) {
|
||||||
|
trait = traits[trait];
|
||||||
|
for (var tokenD of tokens) {
|
||||||
|
let currentdie = 0;
|
||||||
|
let currentmod = 0;
|
||||||
|
if (trait["type"] == "attribute") {
|
||||||
|
var part;
|
||||||
|
let value = tokenD.actor.data;
|
||||||
|
for (part of trait["diekey"].split(".")) {
|
||||||
|
value = value[part];
|
||||||
|
}
|
||||||
|
currentdie = value
|
||||||
|
value = tokenD.actor.data
|
||||||
|
for (part of trait["modkey"].split(".")) {
|
||||||
|
value = value[part];
|
||||||
|
}
|
||||||
|
currentmod = value;
|
||||||
|
} else {
|
||||||
|
let skill = tokenD.actor.items.filter(s => s.type == "skill").find(s => s.data.name == trait["name"])
|
||||||
|
if (skill) {
|
||||||
|
currentdie = skill.data.data.die.sides;
|
||||||
|
currentmod = skill.data.data.die.modifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (currentdie == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (currentdie == 4 && direction == "Lower") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let diemod = 2;
|
||||||
|
let modmod = 0;
|
||||||
|
if (direction == "Lower") {
|
||||||
|
diemod = -2;
|
||||||
|
}
|
||||||
|
if (currentdie == 6 && direction == "Lower" && raise) {
|
||||||
|
diemod = -1;
|
||||||
|
} else if (currentdie == 12 && direction == "Boost") {
|
||||||
|
diemod = 0;
|
||||||
|
modmod = 1;
|
||||||
|
}
|
||||||
|
if (raise) {
|
||||||
|
diemod *= 2;
|
||||||
|
modmod *= 2;
|
||||||
|
}
|
||||||
|
if (currentdie == 10 && direction == "Boost" && raise) {
|
||||||
|
diemod = 2;
|
||||||
|
modmod = 1;
|
||||||
|
}
|
||||||
|
var effectData = {
|
||||||
|
label: `${direction} ${trait.name}${raise ? " with raise" : ""}`,
|
||||||
|
id: `${direction}${trait.name}${raise ? "raise" : ""}`,
|
||||||
|
icon: direction == "Lower" ? DOWNICON : UPICON,
|
||||||
|
changes: [{
|
||||||
|
"key": trait["diekey"],
|
||||||
|
"mode": 2,
|
||||||
|
"value": diemod,
|
||||||
|
"priority": 0
|
||||||
|
},{
|
||||||
|
"key": trait["modkey"],
|
||||||
|
"mode": 2,
|
||||||
|
"value": modmod,
|
||||||
|
"priority": 0
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
if (direction == "Boost") {
|
||||||
|
effectData["duration"] = {rounds: 5}
|
||||||
|
}
|
||||||
|
let spellEffect = game.macros.getName("ApplySpellEffect");
|
||||||
|
spellEffect.execute(effectData, [tokenD])
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user