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] Protection
|
||||
* Boost/Lower Trait
|
||||
* Summon Ally
|
||||
* [x] Boost/Lower Trait
|
||||
* [x] Summon Ally (Automated Evocations)
|
||||
* [x] Shape Change (Automated Evocations)
|
||||
|
||||
@ -5,7 +5,7 @@ if (!extra) {
|
||||
extra = {};
|
||||
}
|
||||
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) {
|
||||
extra.startMessage = `${effect.label}'s effects start`
|
||||
}
|
||||
@ -64,7 +64,7 @@ if (game.modules.get("turnAlert")?.active) {
|
||||
}
|
||||
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 preDuration = duration - 6;
|
||||
console.log("effects end in duration:", duration, preDuration)
|
||||
|
||||
@ -5,7 +5,16 @@ let assignedActor = args[0].assignedActor;
|
||||
let data = {
|
||||
actor: {},
|
||||
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})`;
|
||||
@ -22,11 +31,29 @@ data.token['name'] = name;
|
||||
|
||||
for (const attr of keptAttributes) {
|
||||
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(
|
||||
i => i.type === 'skill' && i.data.data.attribute === attr)
|
||||
i => i.type === 'skill' && i.data.data.attribute === attr);
|
||||
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(
|
||||
|
||||
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