WIP: Macros

master
U~man 2020-07-07 00:22:21 +02:00
parent 7ab45a1e49
commit 60377a2393
10 changed files with 118 additions and 6 deletions

View File

@ -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",

View File

@ -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",
}
};

View File

@ -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) {

View File

@ -72,7 +72,8 @@ export class OseItem extends Item {
...this.data,
...{
rollData: {
type: "Formula"
type: "Formula",
blindroll: this.data.data.blindroll
},
},
};

61
src/module/macros.js Normal file
View File

@ -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();
}

View File

@ -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);

View File

@ -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": ""
}
}

View File

@ -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>

View File

@ -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

View File

@ -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">