WIP: Macros
parent
7ab45a1e49
commit
60377a2393
|
@ -143,12 +143,18 @@
|
||||||
"OSE.items.Cost": "Cost",
|
"OSE.items.Cost": "Cost",
|
||||||
"OSE.items.Quantity": "Qt.",
|
"OSE.items.Quantity": "Qt.",
|
||||||
"OSE.items.Roll": "Roll",
|
"OSE.items.Roll": "Roll",
|
||||||
|
"OSE.items.BlindRoll": "Blind",
|
||||||
"OSE.items.Damage": "Damage",
|
"OSE.items.Damage": "Damage",
|
||||||
"OSE.items.Melee": "Melee",
|
"OSE.items.Melee": "Melee",
|
||||||
"OSE.items.Missile": "Missile",
|
"OSE.items.Missile": "Missile",
|
||||||
"OSE.items.Slow": "Slow",
|
"OSE.items.Slow": "Slow",
|
||||||
"OSE.items.ArmorAC": "AC",
|
"OSE.items.ArmorAC": "AC",
|
||||||
"OSE.items.ArmorAAC": "AAC",
|
"OSE.items.ArmorAAC": "AAC",
|
||||||
|
|
||||||
|
"OSE.armor.type": "Armor Type",
|
||||||
|
"OSE.armor.unarmored": "Unarmored",
|
||||||
|
"OSE.armor.light": "Light",
|
||||||
|
"OSE.armor.heavy": "Heavy",
|
||||||
|
|
||||||
"OSE.spells.Memorized": "Memorized",
|
"OSE.spells.Memorized": "Memorized",
|
||||||
"OSE.spells.Cast": "Cast",
|
"OSE.spells.Cast": "Cast",
|
||||||
|
|
|
@ -21,4 +21,9 @@ export const OSE = {
|
||||||
breath: "OSE.saves.breath.long",
|
breath: "OSE.saves.breath.long",
|
||||||
spell: "OSE.saves.spell.long",
|
spell: "OSE.saves.spell.long",
|
||||||
},
|
},
|
||||||
|
armor : {
|
||||||
|
unarmored: "OSE.armor.unarmored",
|
||||||
|
light: "OSE.armor.light",
|
||||||
|
heavy: "OSE.armor.heavy",
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,6 +47,7 @@ export class OseDice {
|
||||||
speaker: speaker,
|
speaker: speaker,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let templateData = {
|
let templateData = {
|
||||||
title: title,
|
title: title,
|
||||||
flavor: flavor,
|
flavor: flavor,
|
||||||
|
@ -62,6 +63,15 @@ export class OseDice {
|
||||||
// Convert the roll to a chat message and return the roll
|
// Convert the roll to a chat message and return the roll
|
||||||
let rollMode = game.settings.get("core", "rollMode");
|
let rollMode = game.settings.get("core", "rollMode");
|
||||||
rollMode = form ? form.rollMode.value : rollMode;
|
rollMode = form ? form.rollMode.value : rollMode;
|
||||||
|
|
||||||
|
// Force blind roll (ability formulas)
|
||||||
|
if (data.rollData.blindroll) {
|
||||||
|
rollMode = "blindroll";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (["gmroll", "blindroll"].includes(rollMode)) chatData["whisper"] = ChatMessage.getWhisperRecipients("GM");
|
||||||
|
if (rollMode === "selfroll") chatData["whisper"] = [game.user._id];
|
||||||
|
if (rollMode === "blindroll") chatData["blind"] = true;
|
||||||
|
|
||||||
templateData.result = OseDice.digestResult(data, roll);
|
templateData.result = OseDice.digestResult(data, roll);
|
||||||
|
|
||||||
|
@ -148,6 +158,10 @@ export class OseDice {
|
||||||
// Convert the roll to a chat message and return the roll
|
// Convert the roll to a chat message and return the roll
|
||||||
let rollMode = game.settings.get("core", "rollMode");
|
let rollMode = game.settings.get("core", "rollMode");
|
||||||
rollMode = form ? form.rollMode.value : rollMode;
|
rollMode = form ? form.rollMode.value : rollMode;
|
||||||
|
|
||||||
|
if (["gmroll", "blindroll"].includes(rollMode)) chatData["whisper"] = ChatMessage.getWhisperRecipients("GM");
|
||||||
|
if (rollMode === "selfroll") chatData["whisper"] = [game.user._id];
|
||||||
|
if (rollMode === "blindroll") chatData["blind"] = true;
|
||||||
|
|
||||||
templateData.result = OseDice.digestAttackResult(data, roll);
|
templateData.result = OseDice.digestAttackResult(data, roll);
|
||||||
|
|
||||||
|
@ -209,14 +223,13 @@ export class OseDice {
|
||||||
title = null,
|
title = null,
|
||||||
item = false,
|
item = false,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
let rollMode = game.settings.get("core", "rollMode");
|
|
||||||
let rolled = false;
|
let rolled = false;
|
||||||
|
|
||||||
const template = "systems/ose/templates/chat/roll-dialog.html";
|
const template = "systems/ose/templates/chat/roll-dialog.html";
|
||||||
let dialogData = {
|
let dialogData = {
|
||||||
formula: parts.join(" "),
|
formula: parts.join(" "),
|
||||||
data: data,
|
data: data,
|
||||||
rollMode: rollMode,
|
rollMode: game.settings.get('core', 'rollMode'),
|
||||||
rollModes: CONFIG.Dice.rollModes,
|
rollModes: CONFIG.Dice.rollModes,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -225,7 +238,7 @@ export class OseDice {
|
||||||
data: data,
|
data: data,
|
||||||
title: title,
|
title: title,
|
||||||
flavor: flavor,
|
flavor: flavor,
|
||||||
speaker: speaker,
|
speaker: speaker
|
||||||
};
|
};
|
||||||
|
|
||||||
if (skipDialog) {
|
if (skipDialog) {
|
||||||
|
|
|
@ -72,7 +72,8 @@ export class OseItem extends Item {
|
||||||
...this.data,
|
...this.data,
|
||||||
...{
|
...{
|
||||||
rollData: {
|
rollData: {
|
||||||
type: "Formula"
|
type: "Formula",
|
||||||
|
blindroll: this.data.data.blindroll
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
/* Hotbar Macros */
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Macro from an Item drop.
|
||||||
|
* Get an existing item macro if one exists, otherwise create a new one.
|
||||||
|
* @param {Object} data The dropped data
|
||||||
|
* @param {number} slot The hotbar slot to use
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
export async function createOseMacro(data, slot) {
|
||||||
|
if ( data.type !== "Item" ) return;
|
||||||
|
if (!( "data" in data ) ) return ui.notifications.warn("You can only create macro buttons for owned Items");
|
||||||
|
const item = data.data;
|
||||||
|
|
||||||
|
// Create the macro command
|
||||||
|
const command = `game.dnd5e.rollItemMacro("${item.name}");`;
|
||||||
|
let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command));
|
||||||
|
if ( !macro ) {
|
||||||
|
macro = await Macro.create({
|
||||||
|
name: item.name,
|
||||||
|
type: "script",
|
||||||
|
img: item.img,
|
||||||
|
command: command,
|
||||||
|
flags: {"dnd5e.itemMacro": true}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
game.user.assignHotbarMacro(macro, slot);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Macro from an Item drop.
|
||||||
|
* Get an existing item macro if one exists, otherwise create a new one.
|
||||||
|
* @param {string} itemName
|
||||||
|
* @return {Promise}
|
||||||
|
*/
|
||||||
|
export function rollItemMacro(itemName) {
|
||||||
|
const speaker = ChatMessage.getSpeaker();
|
||||||
|
let actor;
|
||||||
|
if ( speaker.token ) actor = game.actors.tokens[speaker.token];
|
||||||
|
if ( !actor ) actor = game.actors.get(speaker.actor);
|
||||||
|
|
||||||
|
// Get matching items
|
||||||
|
const items = actor ? actor.items.filter(i => i.name === itemName) : [];
|
||||||
|
if ( items.length > 1 ) {
|
||||||
|
ui.notifications.warn(`Your controlled Actor ${actor.name} has more than one Item with name ${itemName}. The first matched item will be chosen.`);
|
||||||
|
} else if ( items.length === 0 ) {
|
||||||
|
return ui.notifications.warn(`Your controlled Actor does not have an item named ${itemName}`);
|
||||||
|
}
|
||||||
|
const item = items[0];
|
||||||
|
|
||||||
|
// Trigger the item roll
|
||||||
|
if ( item.data.type === "spell" ) return actor.useSpell(item);
|
||||||
|
return item.roll();
|
||||||
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { OSE } from "./module/config.js";
|
||||||
import { registerSettings } from './module/settings.js';
|
import { registerSettings } from './module/settings.js';
|
||||||
import { registerHelpers } from './module/helpers.js';
|
import { registerHelpers } from './module/helpers.js';
|
||||||
import * as chat from "./module/chat.js";
|
import * as chat from "./module/chat.js";
|
||||||
|
import * as macros from "./module/macros.js";
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
/* Foundry VTT Initialization */
|
/* Foundry VTT Initialization */
|
||||||
|
@ -56,7 +57,7 @@ Hooks.once("init", async function () {
|
||||||
*/
|
*/
|
||||||
Hooks.once("setup", function () {
|
Hooks.once("setup", function () {
|
||||||
// Localize CONFIG objects once up-front
|
// Localize CONFIG objects once up-front
|
||||||
const toLocalize = ["saves_short", "saves_long", "scores"];
|
const toLocalize = ["saves_short", "saves_long", "scores", "armor"];
|
||||||
for (let o of toLocalize) {
|
for (let o of toLocalize) {
|
||||||
CONFIG.OSE[o] = Object.entries(CONFIG.OSE[o]).reduce((obj, e) => {
|
CONFIG.OSE[o] = Object.entries(CONFIG.OSE[o]).reduce((obj, e) => {
|
||||||
obj[e[0]] = game.i18n.localize(e[1]);
|
obj[e[0]] = game.i18n.localize(e[1]);
|
||||||
|
@ -65,5 +66,9 @@ Hooks.once("setup", function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Hooks.once("ready", () => {
|
||||||
|
Hooks.on("hotbarDrop", (bar, data, slot) => macros.createOseMacro(data, slot));
|
||||||
|
});
|
||||||
|
|
||||||
Hooks.on("renderChatLog", (app, html, data) => OseItem.chatListeners(html));
|
Hooks.on("renderChatLog", (app, html, data) => OseItem.chatListeners(html));
|
||||||
Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions);
|
Hooks.on("getChatLogEntryContext", chat.addChatMessageContextOptions);
|
|
@ -178,6 +178,7 @@
|
||||||
"description": "",
|
"description": "",
|
||||||
"ac": 9,
|
"ac": 9,
|
||||||
"aac": 10,
|
"aac": 10,
|
||||||
|
"type": "light",
|
||||||
"cost": 0,
|
"cost": 0,
|
||||||
"equipped": false,
|
"equipped": false,
|
||||||
"weight": 0
|
"weight": 0
|
||||||
|
@ -196,6 +197,7 @@
|
||||||
"ability": {
|
"ability": {
|
||||||
"requirements": "",
|
"requirements": "",
|
||||||
"roll": "",
|
"roll": "",
|
||||||
|
"blindroll": false,
|
||||||
"description": ""
|
"description": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if data.roll}}
|
{{#if data.roll}}
|
||||||
<button data-action="formula">{{ localize "OSE.Roll"}} {{data.roll}}</button>
|
<button data-action="formula">{{ localize "OSE.Roll"}} {{data.roll}} {{#if data.blindroll}}({{localize 'OSE.items.BlindRoll'}}){{/if}}</button>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,12 @@
|
||||||
<input type="text" name="data.roll" value="{{data.roll}}" data-dtype="String" />
|
<input type="text" name="data.roll" value="{{data.roll}}" data-dtype="String" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{localize 'OSE.items.BlindRoll'}}</label>
|
||||||
|
<div class="form-fields">
|
||||||
|
<input type="checkbox" name="data.blindroll" value="{{data.blindroll}}" {{checked data.blindroll}} data-dtype="Number"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
{{editor content=data.description target="data.description" button=true
|
{{editor content=data.description target="data.description" button=true
|
||||||
|
|
|
@ -22,6 +22,19 @@
|
||||||
<input type="text" name="data.aac.value" value="{{data.aac.value}}" data-dtype="Number" />
|
<input type="text" name="data.aac.value" value="{{data.aac.value}}" data-dtype="Number" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{localize 'OSE.armor.type'}}</label>
|
||||||
|
<div class="form-fields">
|
||||||
|
<select name="data.type">
|
||||||
|
{{#select data.type}}
|
||||||
|
<option value=""></option>
|
||||||
|
{{#each config.armor as |armor a|}}
|
||||||
|
<option value="{{a}}">{{armor}}</option>
|
||||||
|
{{/each}}
|
||||||
|
{{/select}}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>{{localize 'OSE.items.Cost'}}</label>
|
<label>{{localize 'OSE.items.Cost'}}</label>
|
||||||
<div class="form-fields">
|
<div class="form-fields">
|
||||||
|
|
Loading…
Reference in New Issue