forked from GitHub-Mirrors/foundry-sw5e
100 lines
3.4 KiB
JavaScript
100 lines
3.4 KiB
JavaScript
![]() |
/**
|
||
|
* Extend the base TokenDocument class to implement system-specific HP bar logic.
|
||
|
* @extends {TokenDocument}
|
||
|
*/
|
||
|
export class TokenDocument5e extends TokenDocument {
|
||
|
|
||
|
/** @inheritdoc */
|
||
|
getBarAttribute(...args) {
|
||
|
const data = super.getBarAttribute(...args);
|
||
|
if ( data && (data.attribute === "attributes.hp") ) {
|
||
|
data.value += parseInt(getProperty(this.actor.data, "data.attributes.hp.temp") || 0);
|
||
|
data.max += parseInt(getProperty(this.actor.data, "data.attributes.hp.tempmax") || 0);
|
||
|
}
|
||
|
return data;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/* -------------------------------------------- */
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Extend the base Token class to implement additional system-specific logic.
|
||
|
* @extends {Token}
|
||
|
*/
|
||
|
export class Token5e extends Token {
|
||
|
|
||
|
/** @inheritdoc */
|
||
|
_drawBar(number, bar, data) {
|
||
|
if ( data.attribute === "attributes.hp" ) return this._drawHPBar(number, bar, data);
|
||
|
return super._drawBar(number, bar, data);
|
||
|
}
|
||
|
|
||
|
/* -------------------------------------------- */
|
||
|
|
||
|
/**
|
||
|
* Specialized drawing function for HP bars.
|
||
|
* @param {number} number The Bar number
|
||
|
* @param {PIXI.Graphics} bar The Bar container
|
||
|
* @param {object} data Resource data for this bar
|
||
|
* @private
|
||
|
*/
|
||
|
_drawHPBar(number, bar, data) {
|
||
|
|
||
|
// Extract health data
|
||
|
let {value, max, temp, tempmax} = this.document.actor.data.data.attributes.hp;
|
||
|
temp = Number(temp || 0);
|
||
|
tempmax = Number(tempmax || 0);
|
||
|
|
||
|
// Differentiate between effective maximum and displayed maximum
|
||
|
const effectiveMax = Math.max(0, max + tempmax);
|
||
|
let displayMax = max + (tempmax > 0 ? tempmax : 0);
|
||
|
|
||
|
// Allocate percentages of the total
|
||
|
const tempPct = Math.clamped(temp, 0, displayMax) / displayMax;
|
||
|
const valuePct = Math.clamped(value, 0, effectiveMax) / displayMax;
|
||
|
const colorPct = Math.clamped(value, 0, effectiveMax) / displayMax;
|
||
|
|
||
|
// Determine colors to use
|
||
|
const blk = 0x000000;
|
||
|
const hpColor = PIXI.utils.rgb2hex([(1-(colorPct/2)), colorPct, 0]);
|
||
|
const c = CONFIG.SW5E.tokenHPColors;
|
||
|
|
||
|
// Determine the container size (logic borrowed from core)
|
||
|
const w = this.w;
|
||
|
let h = Math.max((canvas.dimensions.size / 12), 8);
|
||
|
if ( this.data.height >= 2 ) h *= 1.6;
|
||
|
const bs = Math.clamped(h / 8, 1, 2);
|
||
|
const bs1 = bs+1;
|
||
|
|
||
|
// Overall bar container
|
||
|
bar.clear()
|
||
|
bar.beginFill(blk, 0.5).lineStyle(bs, blk, 1.0).drawRoundedRect(0, 0, w, h, 3);
|
||
|
|
||
|
// Temporary maximum HP
|
||
|
if (tempmax > 0) {
|
||
|
const pct = max / effectiveMax;
|
||
|
bar.beginFill(c.tempmax, 1.0).lineStyle(1, blk, 1.0).drawRoundedRect(pct*w, 0, (1-pct)*w, h, 2);
|
||
|
}
|
||
|
|
||
|
// Maximum HP penalty
|
||
|
else if (tempmax < 0) {
|
||
|
const pct = (max + tempmax) / max;
|
||
|
bar.beginFill(c.negmax, 1.0).lineStyle(1, blk, 1.0).drawRoundedRect(pct*w, 0, (1-pct)*w, h, 2);
|
||
|
}
|
||
|
|
||
|
// Health bar
|
||
|
bar.beginFill(hpColor, 1.0).lineStyle(bs, blk, 1.0).drawRoundedRect(0, 0, valuePct*w, h, 2)
|
||
|
|
||
|
// Temporary hit points
|
||
|
if ( temp > 0 ) {
|
||
|
bar.beginFill(c.temp, 1.0).lineStyle(0).drawRoundedRect(bs1, bs1, (tempPct*w)-(2*bs1), h-(2*bs1), 1);
|
||
|
}
|
||
|
|
||
|
// Set position
|
||
|
let posY = (number === 0) ? (this.h - h) : 0;
|
||
|
bar.position.set(0, posY);
|
||
|
}
|
||
|
}
|