forked from GitHub-Mirrors/foundry-sw5e
119 lines
4.3 KiB
JavaScript
119 lines
4.3 KiB
JavaScript
|
|
/**
|
|
* Highlight critical success or failure on d20 rolls
|
|
*/
|
|
export const highlightCriticalSuccessFailure = function(message, html, data) {
|
|
if ( !message.isRoll || !message.isContentVisible ) return;
|
|
|
|
// Highlight rolls where the first part is a d20 roll
|
|
const roll = message.roll;
|
|
if ( !roll.dice.length ) return;
|
|
const d = roll.dice[0];
|
|
|
|
// Ensure it is an un-modified d20 roll
|
|
const isD20 = (d.faces === 20) && ( d.values.length === 1 );
|
|
if ( !isD20 ) return;
|
|
const isModifiedRoll = ("success" in d.results[0]) || d.options.marginSuccess || d.options.marginFailure;
|
|
if ( isModifiedRoll ) return;
|
|
|
|
// Highlight successes and failures
|
|
const critical = d.options.critical || 20;
|
|
const fumble = d.options.fumble || 1;
|
|
if ( d.total >= critical ) html.find(".dice-total").addClass("critical");
|
|
else if ( d.total <= fumble ) html.find(".dice-total").addClass("fumble");
|
|
else if ( d.options.target ) {
|
|
if ( roll.total >= d.options.target ) html.find(".dice-total").addClass("success");
|
|
else html.find(".dice-total").addClass("failure");
|
|
}
|
|
};
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/**
|
|
* Optionally hide the display of chat card action buttons which cannot be performed by the user
|
|
*/
|
|
export const displayChatActionButtons = function(message, html, data) {
|
|
const chatCard = html.find(".sw5e.chat-card");
|
|
if ( chatCard.length > 0 ) {
|
|
const flavor = html.find(".flavor-text");
|
|
if ( flavor.text() === html.find(".item-name").text() ) flavor.remove();
|
|
|
|
// If the user is the message author or the actor owner, proceed
|
|
let actor = game.actors.get(data.message.speaker.actor);
|
|
if ( actor && actor.owner ) return;
|
|
else if ( game.user.isGM || (data.author.id === game.user.id)) return;
|
|
|
|
// Otherwise conceal action buttons except for saving throw
|
|
const buttons = chatCard.find("button[data-action]");
|
|
buttons.each((i, btn) => {
|
|
if ( btn.dataset.action === "save" ) return;
|
|
btn.style.display = "none"
|
|
});
|
|
}
|
|
};
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/**
|
|
* This function is used to hook into the Chat Log context menu to add additional options to each message
|
|
* These options make it easy to conveniently apply damage to controlled tokens based on the value of a Roll
|
|
*
|
|
* @param {HTMLElement} html The Chat Message being rendered
|
|
* @param {Array} options The Array of Context Menu options
|
|
*
|
|
* @return {Array} The extended options Array including new context choices
|
|
*/
|
|
export const addChatMessageContextOptions = function(html, options) {
|
|
let canApply = li => {
|
|
const message = game.messages.get(li.data("messageId"));
|
|
return message?.isRoll && message?.isContentVisible && canvas?.tokens.controlled.length;
|
|
};
|
|
options.push(
|
|
{
|
|
name: game.i18n.localize("SW5E.ChatContextDamage"),
|
|
icon: '<i class="fas fa-user-minus"></i>',
|
|
condition: canApply,
|
|
callback: li => applyChatCardDamage(li, 1)
|
|
},
|
|
{
|
|
name: game.i18n.localize("SW5E.ChatContextHealing"),
|
|
icon: '<i class="fas fa-user-plus"></i>',
|
|
condition: canApply,
|
|
callback: li => applyChatCardDamage(li, -1)
|
|
},
|
|
{
|
|
name: game.i18n.localize("SW5E.ChatContextDoubleDamage"),
|
|
icon: '<i class="fas fa-user-injured"></i>',
|
|
condition: canApply,
|
|
callback: li => applyChatCardDamage(li, 2)
|
|
},
|
|
{
|
|
name: game.i18n.localize("SW5E.ChatContextHalfDamage"),
|
|
icon: '<i class="fas fa-user-shield"></i>',
|
|
condition: canApply,
|
|
callback: li => applyChatCardDamage(li, 0.5)
|
|
}
|
|
);
|
|
return options;
|
|
};
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/**
|
|
* Apply rolled dice damage to the token or tokens which are currently controlled.
|
|
* This allows for damage to be scaled by a multiplier to account for healing, critical hits, or resistance
|
|
*
|
|
* @param {HTMLElement} li The chat entry which contains the roll data
|
|
* @param {Number} multiplier A damage multiplier to apply to the rolled damage.
|
|
* @return {Promise}
|
|
*/
|
|
function applyChatCardDamage(li, multiplier) {
|
|
const message = game.messages.get(li.data("messageId"));
|
|
const roll = message.roll;
|
|
return Promise.all(canvas.tokens.controlled.map(t => {
|
|
const a = t.actor;
|
|
return a.applyDamage(roll.total, multiplier);
|
|
}));
|
|
}
|
|
|
|
/* -------------------------------------------- */
|