mirror of
https://github.com/Kornstalx/5etools-mirror-2.github.io.git
synced 2025-10-28 20:45:35 -05:00
v1.198.1
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
import {
|
||||
INITIATIVE_APPLICABILITY_NOT_APPLICABLE,
|
||||
InitiativeTrackerStatColumnFactory,
|
||||
} from "./dmscreen-initiativetracker-statcolumns.js";
|
||||
import {DmScreenUtil} from "../dmscreen-util.js";
|
||||
import {InitiativeTrackerSort} from "./dmscreen-initiativetracker-sort.js";
|
||||
|
||||
/** @abstract */
|
||||
class _InitiativeTrackerRowStateBuilderBase {
|
||||
constructor ({comp, roller}) {
|
||||
this._comp = comp;
|
||||
this._roller = roller;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @param {?array} rows Existing/partial rows, for calculating ordinal.
|
||||
* @param {?boolean} isActive
|
||||
* @param {?boolean} isPlayerVisible
|
||||
* @param {?string} name
|
||||
* @param {?string} displayName
|
||||
* @param {?number} scaledCr
|
||||
* @param {?number} scaledSummonSpellLevel
|
||||
* @param {?number} scaledSummonClassLevel
|
||||
* @param {?string} customName
|
||||
* @param {?string} source
|
||||
* @param {?number} hpCurrent
|
||||
* @param {?number} hpMax
|
||||
* @param {?number} initiative
|
||||
* @param {?number} ordinal
|
||||
* @param {?array} rowStatColData
|
||||
* @param {?array} conditions
|
||||
*/
|
||||
async pGetNewRowState (
|
||||
{
|
||||
rows = null,
|
||||
|
||||
isActive = null,
|
||||
isPlayerVisible = null,
|
||||
name = null,
|
||||
displayName = null,
|
||||
scaledCr = null,
|
||||
scaledSummonSpellLevel = null,
|
||||
scaledSummonClassLevel = null,
|
||||
customName = null,
|
||||
source = null,
|
||||
hpCurrent = null,
|
||||
hpMax = null,
|
||||
initiative = null,
|
||||
ordinal = null,
|
||||
rowStatColData = null,
|
||||
conditions = null,
|
||||
} = {},
|
||||
) {
|
||||
if (rowStatColData == null) rowStatColData = this._getInitialRowStatColData();
|
||||
|
||||
return {
|
||||
id: CryptUtil.uid(),
|
||||
entity: {
|
||||
isActive: !!isActive,
|
||||
isPlayerVisible: !!isPlayerVisible,
|
||||
name,
|
||||
displayName,
|
||||
scaledCr,
|
||||
scaledSummonSpellLevel,
|
||||
scaledSummonClassLevel,
|
||||
customName,
|
||||
source,
|
||||
hpCurrent,
|
||||
hpMax,
|
||||
initiative,
|
||||
ordinal,
|
||||
rowStatColData: rowStatColData ?? [],
|
||||
conditions: conditions ?? [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?object} mon
|
||||
* @param {?object} fluff
|
||||
*/
|
||||
_getInitialRowStatColData ({mon = null, fluff = null} = {}) {
|
||||
return this._comp._state.statsCols
|
||||
.map(data => {
|
||||
return InitiativeTrackerStatColumnFactory.fromStateData({data})
|
||||
.getInitialCellStateData({mon, fluff});
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
async pGetRowInitiativeMeta ({row}) {
|
||||
const out = {mon: null, initiativeModifier: null};
|
||||
|
||||
const {entity} = row;
|
||||
|
||||
const initiativeInfos = this._comp._state.statsCols
|
||||
.map(data => {
|
||||
const cell = entity.rowStatColData.find(cell => cell.id === data.id);
|
||||
if (!cell) return null;
|
||||
return {
|
||||
id: cell.id,
|
||||
...InitiativeTrackerStatColumnFactory.fromStateData({data})
|
||||
.getInitiativeInfo({state: cell}),
|
||||
};
|
||||
})
|
||||
.filter(Boolean)
|
||||
.filter(info => info.applicability !== INITIATIVE_APPLICABILITY_NOT_APPLICABLE)
|
||||
.sort(InitiativeTrackerSort.sortInitiativeInfos.bind(InitiativeTrackerSort));
|
||||
|
||||
const maxApplicability = Math.max(INITIATIVE_APPLICABILITY_NOT_APPLICABLE, ...initiativeInfos.map(info => info.applicability));
|
||||
if (maxApplicability !== INITIATIVE_APPLICABILITY_NOT_APPLICABLE) {
|
||||
const initiativeInfosApplicable = initiativeInfos.filter(info => info.applicability === maxApplicability);
|
||||
out.initiativeModifier = Math.max(...initiativeInfosApplicable.map(info => info.initiative));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
export class InitiativeTrackerRowStateBuilderActive extends _InitiativeTrackerRowStateBuilderBase {
|
||||
_prop = "rows";
|
||||
|
||||
async pGetScaledCreature ({isMon, name, source, scaledCr, scaledSummonSpellLevel, scaledSummonClassLevel}) {
|
||||
if (!isMon) return null;
|
||||
return DmScreenUtil.pGetScaledCreature({name, source, scaledCr, scaledSummonSpellLevel, scaledSummonClassLevel});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
async pGetNewRowState (
|
||||
{
|
||||
rows = null,
|
||||
|
||||
isActive = null,
|
||||
isPlayerVisible = null,
|
||||
name = null,
|
||||
displayName = null,
|
||||
scaledCr = null,
|
||||
scaledSummonSpellLevel = null,
|
||||
scaledSummonClassLevel = null,
|
||||
customName = null,
|
||||
source = null,
|
||||
hpCurrent = null,
|
||||
hpMax = null,
|
||||
initiative = null,
|
||||
ordinal = null,
|
||||
rowStatColData = null,
|
||||
conditions = null,
|
||||
} = {},
|
||||
) {
|
||||
const isMon = name && source;
|
||||
const mon = await this.pGetScaledCreature({isMon, name, source, scaledCr, scaledSummonSpellLevel, scaledSummonClassLevel});
|
||||
if (isMon && !mon) return null;
|
||||
|
||||
const fluff = mon ? await Renderer.monster.pGetFluff(mon) : null;
|
||||
|
||||
if (isMon) {
|
||||
if (hpCurrent == null && hpMax == null) {
|
||||
hpCurrent = hpMax = await this._roller.pGetOrRollHp(mon, {isRollHp: this._comp._state.isRollHp});
|
||||
}
|
||||
|
||||
if (initiative == null && this._comp._state.isRollInit) {
|
||||
initiative = await this._roller.pGetRollInitiative({mon});
|
||||
}
|
||||
|
||||
if (ordinal == null) {
|
||||
const existingCreatures = this.getSimilarRows({
|
||||
rows,
|
||||
rowEntity: {
|
||||
name,
|
||||
customName,
|
||||
scaledCr,
|
||||
scaledSummonSpellLevel,
|
||||
scaledSummonClassLevel,
|
||||
source,
|
||||
},
|
||||
});
|
||||
|
||||
ordinal = existingCreatures.length + 1;
|
||||
}
|
||||
|
||||
if (isPlayerVisible == null) isPlayerVisible = !this._comp._state.playerInitHideNewMonster;
|
||||
}
|
||||
|
||||
if (!isMon) {
|
||||
if (isPlayerVisible == null) isPlayerVisible = true;
|
||||
}
|
||||
|
||||
if (rowStatColData == null) rowStatColData = this._getInitialRowStatColData({mon, fluff});
|
||||
|
||||
return {
|
||||
id: CryptUtil.uid(),
|
||||
entity: {
|
||||
isActive: !!isActive,
|
||||
isPlayerVisible: !!isPlayerVisible,
|
||||
name,
|
||||
displayName,
|
||||
scaledCr,
|
||||
scaledSummonSpellLevel,
|
||||
scaledSummonClassLevel,
|
||||
customName,
|
||||
source,
|
||||
hpCurrent,
|
||||
hpMax,
|
||||
initiative,
|
||||
ordinal,
|
||||
rowStatColData: rowStatColData ?? [],
|
||||
conditions: conditions ?? [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
async pGetRowInitiativeMeta ({row}) {
|
||||
const out = await super.pGetRowInitiativeMeta({row});
|
||||
|
||||
const mon = await this.pGetScaledCreature(row.entity);
|
||||
if (!mon) return out;
|
||||
|
||||
out.mon = mon;
|
||||
out.initiativeModifier ||= Parser.getAbilityModifier(mon.dex);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
static _SIMILAR_ROW_PROPS = [
|
||||
"name",
|
||||
"customName",
|
||||
"scaledCr",
|
||||
"scaledSummonSpellLevel",
|
||||
"scaledSummonClassLevel",
|
||||
"source",
|
||||
];
|
||||
|
||||
static getSimilarRowEntityHash ({rowEntity}) {
|
||||
return this._SIMILAR_ROW_PROPS
|
||||
.map(prop => JSON.stringify(rowEntity[prop] ?? null))
|
||||
.join("__");
|
||||
}
|
||||
|
||||
getSimilarRows (
|
||||
{
|
||||
rows = null,
|
||||
|
||||
rowEntity,
|
||||
},
|
||||
) {
|
||||
const rowEntityHash = this.constructor.getSimilarRowEntityHash({rowEntity});
|
||||
|
||||
return (rows || this._comp._state[this._prop])
|
||||
.filter(({entity}) => {
|
||||
return this.constructor.getSimilarRowEntityHash({rowEntity: entity}) === rowEntityHash;
|
||||
});
|
||||
}
|
||||
|
||||
getSimilarRowCounts (
|
||||
{
|
||||
rows = null,
|
||||
},
|
||||
) {
|
||||
return (rows || this._comp._state[this._prop])
|
||||
.reduce(
|
||||
(accum, {entity}) => {
|
||||
const rowEntityHash = InitiativeTrackerRowStateBuilderActive.getSimilarRowEntityHash({rowEntity: entity});
|
||||
accum[rowEntityHash] = (accum[rowEntityHash] || 0) + 1;
|
||||
return accum;
|
||||
},
|
||||
{},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class InitiativeTrackerRowStateBuilderDefaultParty extends _InitiativeTrackerRowStateBuilderBase {
|
||||
_prop = "rowsDefaultParty";
|
||||
}
|
||||
Reference in New Issue
Block a user