/
chat.js
107 lines (95 loc) · 3.62 KB
/
chat.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
* Highlight critical success or failure on d20 rolls
*/
export const highlightCriticalSuccessFailure = function (message, html, data) {
if (!message.roll || !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 a d20 roll or a custom roll
const rollData = d.options.morkborg
const needsHighlight = ((d.faces === 20) && (d.results.length === 1)) || rollData
if (!needsHighlight) return
// Default highlight settings for a d20
let upperThreshold = 20
let lowerThreshold = 1
let upperClass = 'critical'
let lowerClass = 'fumble'
// Apply MB specific highlighting settings
if (rollData) {
// Highlight max result on any die if requested
if (rollData.highlightMax) {
upperThreshold = d.faces
// Otherwise apply upper threshold if provided
} else if (rollData.upperThreshold) {
upperThreshold = rollData.upperThreshold
}
// Apply a lower threshold if provided
if (rollData.lowerThreshold) {
lowerThreshold = rollData.lowerThreshold
}
// Swap class for rolls above or below the threshold if rolling under
if (rollData.rollUnder) {
upperClass = 'fumble'
lowerClass = 'critical'
}
}
// Apply highlights
if (d.total >= upperThreshold) {
html.find('.dice-total').addClass(upperClass)
} else if (d.total <= lowerThreshold) {
html.find('.dice-total').addClass(lowerClass)
}
}
/* -------------------------------------------- */
/**
* 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) {
const canApply = function (li) {
if (canvas.tokens.controlled.length === 0) return false
if (li.find('.damage-applyable').length) return true
if (li.find('.dice-total').length) return true
}
options.push(
{
name: game.i18n.localize('MB.ChatContextDamage'),
icon: '<i class="fas fa-user-minus"></i>',
condition: canApply,
callback: li => applyChatCardDamage(li, 1)
}
)
options.push(
{
name: game.i18n.localize('MB.ChatContextHealing'),
icon: '<i class="fas fa-user-plus"></i>',
condition: canApply,
callback: li => applyChatCardDamage(li, -1)
}
)
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} roll The chat entry which contains the roll data
* @param {Number} multiplier A damage multiplier to apply to the rolled damage.
* @return {Promise}
*/
function applyChatCardDamage (roll, multiplier) {
const amount = roll.find('.damage-applyable').attr('data-damage') ||
roll.find('.dice-total').text()
return Promise.all(canvas.tokens.controlled.map(t => {
const a = t.actor
return a.applyDamage(amount, multiplier)
}))
}