WIP: Macros
parent
7ab45a1e49
commit
60377a2393
|
@ -143,12 +143,18 @@
|
|||
"OSE.items.Cost": "Cost",
|
||||
"OSE.items.Quantity": "Qt.",
|
||||
"OSE.items.Roll": "Roll",
|
||||
"OSE.items.BlindRoll": "Blind",
|
||||
"OSE.items.Damage": "Damage",
|
||||
"OSE.items.Melee": "Melee",
|
||||
"OSE.items.Missile": "Missile",
|
||||
"OSE.items.Slow": "Slow",
|
||||
"OSE.items.ArmorAC": "AC",
|
||||
"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.Cast": "Cast",
|
||||
|
|
|
@ -21,4 +21,9 @@ export const OSE = {
|
|||
breath: "OSE.saves.breath.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,
|
||||
};
|
||||
|
||||
|
||||
let templateData = {
|
||||
title: title,
|
||||
flavor: flavor,
|
||||
|
@ -62,6 +63,15 @@ export class OseDice {
|
|||
// Convert the roll to a chat message and return the roll
|
||||
let rollMode = game.settings.get("core", "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);
|
||||
|
||||
|
@ -148,6 +158,10 @@ export class OseDice {
|
|||
// Convert the roll to a chat message and return the roll
|
||||
let rollMode = game.settings.get("core", "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);
|
||||
|
||||
|
@ -209,14 +223,13 @@ export class OseDice {
|
|||
title = null,
|
||||
item = false,
|
||||
} = {}) {
|
||||
let rollMode = game.settings.get("core", "rollMode");
|
||||
let rolled = false;
|
||||
|
||||
const template = "systems/ose/templates/chat/roll-dialog.html";
|
||||
let dialogData = {
|
||||
formula: parts.join(" "),
|
||||
data: data,
|
||||
rollMode: rollMode,
|
||||
rollMode: game.settings.get('core', 'rollMode'),
|
||||
rollModes: CONFIG.Dice.rollModes,
|
||||
};
|
||||
|
||||
|
@ -225,7 +238,7 @@ export class OseDice {
|
|||
data: data,
|
||||
title: title,
|
||||
flavor: flavor,
|
||||
speaker: speaker,
|
||||
speaker: speaker
|
||||
};
|
||||
|
||||
if (skipDialog) {
|
||||
|
|
|
@ -72,7 +72,8 @@ export class OseItem extends Item {
|
|||
...this.data,
|
||||
...{
|
||||
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 { registerHelpers } from './module/helpers.js';
|
||||
import * as chat from "./module/chat.js";
|
||||
import * as macros from "./module/macros.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Foundry VTT Initialization */
|
||||
|
@ -56,7 +57,7 @@ Hooks.once("init", async function () {
|
|||
*/
|
||||
Hooks.once("setup", function () {
|
||||
// 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) {
|
||||
CONFIG.OSE[o] = Object.entries(CONFIG.OSE[o]).reduce((obj, e) => {
|
||||
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("getChatLogEntryContext", chat.addChatMessageContextOptions);
|
|
@ -178,6 +178,7 @@
|
|||
"description": "",
|
||||
"ac": 9,
|
||||
"aac": 10,
|
||||
"type": "light",
|
||||
"cost": 0,
|
||||
"equipped": false,
|
||||
"weight": 0
|
||||
|
@ -196,6 +197,7 @@
|
|||
"ability": {
|
||||
"requirements": "",
|
||||
"roll": "",
|
||||
"blindroll": false,
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
{{/if}}
|
||||
|
||||
{{#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}}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -22,6 +22,12 @@
|
|||
<input type="text" name="data.roll" value="{{data.roll}}" data-dtype="String" />
|
||||
</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 class="description">
|
||||
{{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" />
|
||||
</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">
|
||||
<label>{{localize 'OSE.items.Cost'}}</label>
|
||||
<div class="form-fields">
|
||||
|
|
Loading…
Reference in New Issue