189 lines
5.0 KiB
JavaScript
189 lines
5.0 KiB
JavaScript
import * as DGRolls from "../roll/roll.js";
|
|
|
|
const { fromUuid } = foundry.utils;
|
|
|
|
/* -------------------------------------------- */
|
|
/* 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 createDeltaGreenMacro(data, slot) {
|
|
if (data.type !== "Item") {
|
|
return;
|
|
}
|
|
|
|
if (!data.uuid.includes("Actor.") && !data.uuid.includes("Token.")) {
|
|
ui.notifications.warn("You can only create macro buttons for owned Items");
|
|
return;
|
|
}
|
|
|
|
const item = await fromUuid(data.uuid);
|
|
|
|
if (item === null || typeof item === "undefined") {
|
|
ui.notifications.warn("Bad item passed to macro hotbar.");
|
|
return;
|
|
}
|
|
|
|
let command = "";
|
|
if (item.type !== "weapon") {
|
|
// this should just open the item sheet for this item
|
|
command = `(await fromUuid("${data.uuid}")).sheet.render(true)`;
|
|
} else {
|
|
command =
|
|
"// If a damage roll on a successful attack should not be automatically rolled, change the last argument from 'true' to 'false':";
|
|
command += `\ngame.deltagreen.rollSkillTestAndDamageForOwnedItem("${data.uuid}", true);`;
|
|
}
|
|
|
|
// Create the weapon macro command
|
|
const macro = await Macro.create({
|
|
name: item.name,
|
|
type: "script",
|
|
img: item.img,
|
|
thumbnail: item.img,
|
|
command,
|
|
flags: { "deltagreen.itemMacro": true },
|
|
});
|
|
|
|
await game.user.assignHotbarMacro(macro, slot);
|
|
}
|
|
|
|
/**
|
|
* 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 async function rollItemMacro(itemId) {
|
|
const speaker = ChatMessage.getSpeaker();
|
|
let actor;
|
|
if (speaker.token) actor = game.actors.tokens[speaker.token];
|
|
if (!actor) actor = game.actors.get(speaker.actor);
|
|
|
|
if (!actor)
|
|
return ui.notifications.warn("Must have an Actor selected first.");
|
|
|
|
let item = actor ? actor.items.find((i) => i._id === itemId) : null;
|
|
|
|
// for backwards compatibility with older macros, where I unwisely set it to use name instead of id
|
|
if (!item) {
|
|
item = actor ? actor.items.find((i) => i.name === itemId) : null;
|
|
}
|
|
|
|
if (!item)
|
|
return ui.notifications.warn(
|
|
`Your controlled Actor does not have an item named ${itemId}`,
|
|
);
|
|
|
|
// Trigger the item roll
|
|
const r = await item.roll();
|
|
|
|
return r;
|
|
}
|
|
|
|
export function rollItemSkillCheckMacro(itemId) {
|
|
const speaker = ChatMessage.getSpeaker();
|
|
let actor;
|
|
if (speaker.token) actor = game.actors.tokens[speaker.token];
|
|
if (!actor) actor = game.actors.get(speaker.actor);
|
|
|
|
if (!actor)
|
|
return ui.notifications.warn("Must have an Actor selected first.");
|
|
|
|
let item = actor ? actor.items.find((i) => i._id === itemId) : null;
|
|
|
|
// for backwards compatibility with older macros, where I unwisely set it to use name instead of id
|
|
if (!item) {
|
|
item = actor ? actor.items.find((i) => i.name === itemId) : null;
|
|
}
|
|
|
|
if (!item)
|
|
return ui.notifications.warn(
|
|
`Your controlled Actor does not have an item '${item.name}'`,
|
|
);
|
|
|
|
const skillName = item.system.skill.toString();
|
|
|
|
const roll = new DGRolls.DGPercentileRoll(
|
|
"1D100",
|
|
{},
|
|
{ rollType: "weapon", key: skillName, actor, item },
|
|
);
|
|
return actor.sheet.processRoll({}, roll);
|
|
}
|
|
|
|
export function rollSkillMacro(skillName) {
|
|
const speaker = ChatMessage.getSpeaker();
|
|
let actor;
|
|
if (speaker.token) actor = game.actors.tokens[speaker.token];
|
|
if (!actor) actor = game.actors.get(speaker.actor);
|
|
|
|
if (!actor)
|
|
return ui.notifications.warn("Must have an Actor selected first.");
|
|
|
|
const skill = actor.system.skills[skillName];
|
|
|
|
if (!skill) return ui.notifications.warn("Bad skill name passed to macro.");
|
|
|
|
const roll = new DGRolls.DGPercentileRoll(
|
|
"1D100",
|
|
{},
|
|
{ rollType: "skill", key: skillName, actor },
|
|
);
|
|
return actor.sheet.processRoll({}, roll);
|
|
}
|
|
|
|
/**
|
|
* Roll a skill check for an item that is owned by a specific actor.
|
|
* @param {*} itemId
|
|
* @param {*} actorId
|
|
* @returns {null|Boolean}
|
|
*/
|
|
export async function rollSkillTestAndDamageForOwnedItem(
|
|
itemUuId,
|
|
rollDamageOnSuccess,
|
|
) {
|
|
let item;
|
|
|
|
try {
|
|
item = await fromUuid(itemUuId);
|
|
|
|
if (item == null) {
|
|
return ui.notifications.warn("Invalid item targeted in macro.");
|
|
}
|
|
|
|
if (item.type !== "weapon") {
|
|
return ui.notifications.warn(
|
|
"Can only roll weapons/attacks as item macros.",
|
|
);
|
|
}
|
|
} catch {
|
|
return ui.notifications.warn("Invalid item targeted in macro.");
|
|
}
|
|
|
|
const rollOptions = {
|
|
rollType: "weapon",
|
|
key: item.system.skill,
|
|
actor: item.parent,
|
|
specialTrainingName: null, // Only applies to Special Training Rolls
|
|
item,
|
|
};
|
|
|
|
const roll = new DGRolls.DGPercentileRoll("1D100", {}, rollOptions);
|
|
|
|
await roll.evaluate();
|
|
|
|
roll.toChat();
|
|
|
|
if (roll.isSuccess && rollDamageOnSuccess) {
|
|
item.roll(roll.isCritical);
|
|
}
|
|
|
|
return roll.isSuccess;
|
|
}
|