mirror of
https://github.com/Kornstalx/5etools-mirror-2.github.io.git
synced 2025-10-28 20:45:35 -05:00
v1.199.3
This commit is contained in:
@@ -55,8 +55,8 @@ class PageFilterBackgrounds extends PageFilter {
|
||||
if (bg.srd) bg._fMisc.push("SRD");
|
||||
if (bg.basicRules) bg._fMisc.push("Basic Rules");
|
||||
if (SourceUtil.isLegacySourceWotc(bg.source)) bg._fMisc.push("Legacy");
|
||||
if (bg.hasFluff || bg.fluff?.entries) bg._fMisc.push("Has Info");
|
||||
if (bg.hasFluffImages || bg.fluff?.images) bg._fMisc.push("Has Images");
|
||||
if (this._hasFluff(bg)) bg._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(bg)) bg._fMisc.push("Has Images");
|
||||
bg._fOtherBenifits = [];
|
||||
if (bg.feats) bg._fOtherBenifits.push("Feat");
|
||||
if (bg.additionalSpells) bg._fOtherBenifits.push("Additional Spells");
|
||||
|
||||
@@ -342,8 +342,8 @@ class PageFilterBestiary extends PageFilter {
|
||||
if (SourceUtil.isLegacySourceWotc(mon.source)) mon._fMisc.push("Legacy");
|
||||
if (Renderer.monster.hasToken(mon)) mon._fMisc.push("Has Token");
|
||||
if (mon.mythic) mon._fMisc.push("Mythic");
|
||||
if (mon.hasFluff || mon.fluff?.entries) mon._fMisc.push("Has Info");
|
||||
if (mon.hasFluffImages || mon.fluff?.images) mon._fMisc.push("Has Images");
|
||||
if (this._hasFluff(mon)) mon._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(mon)) mon._fMisc.push("Has Images");
|
||||
if (this._isReprinted({reprintedAs: mon.reprintedAs, tag: "creature", prop: "monster", page: UrlUtil.PG_BESTIARY})) mon._fMisc.push("Reprinted");
|
||||
if (this._hasRecharge(mon)) mon._fMisc.push("Has Recharge");
|
||||
if (mon._versionBase_isVersion) mon._fMisc.push("Is Variant");
|
||||
|
||||
@@ -20,8 +20,8 @@ class PageFilterCharCreationOptions extends PageFilter {
|
||||
it._fOptionType = Parser.charCreationOptionTypeToFull(it.optionType);
|
||||
it._fMisc = it.srd ? ["SRD"] : [];
|
||||
if (SourceUtil.isLegacySourceWotc(it.source)) it._fMisc.push("Legacy");
|
||||
if (it.hasFluff || it.fluff?.entries) it._fMisc.push("Has Info");
|
||||
if (it.hasFluffImages || it.fluff?.images) it._fMisc.push("Has Images");
|
||||
if (this._hasFluff(it)) it._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(it)) it._fMisc.push("Has Images");
|
||||
}
|
||||
|
||||
addToFilters (it, isExcluded) {
|
||||
|
||||
@@ -49,11 +49,11 @@ class PageFilterClassesRaw extends PageFilterClassesBase {
|
||||
}
|
||||
|
||||
static async _pGetParentClass_pPrerelease ({sc}) {
|
||||
await this._pGetParentClass_pPrereleaseBrew({sc, brewUtil: PrereleaseUtil});
|
||||
return this._pGetParentClass_pPrereleaseBrew({sc, brewUtil: PrereleaseUtil});
|
||||
}
|
||||
|
||||
static async _pGetParentClass_pBrew ({sc}) {
|
||||
await this._pGetParentClass_pPrereleaseBrew({sc, brewUtil: BrewUtil2});
|
||||
return this._pGetParentClass_pPrereleaseBrew({sc, brewUtil: BrewUtil2});
|
||||
}
|
||||
|
||||
static async _pGetParentClass_pPrereleaseBrew ({sc, brewUtil}) {
|
||||
|
||||
@@ -24,8 +24,8 @@ class PageFilterConditionsDiseases extends PageFilter {
|
||||
if (it.srd) it._fMisc.push("SRD");
|
||||
if (it.basicRules) it._fMisc.push("Basic Rules");
|
||||
if (SourceUtil.isLegacySourceWotc(it.source)) it._fMisc.push("Legacy");
|
||||
if (it.hasFluff || it.fluff?.entries) it._fMisc.push("Has Info");
|
||||
if (it.hasFluffImages || it.fluff?.images) it._fMisc.push("Has Images");
|
||||
if (this._hasFluff(it)) it._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(it)) it._fMisc.push("Has Images");
|
||||
}
|
||||
|
||||
addToFilters (it, isExcluded) {
|
||||
|
||||
@@ -86,8 +86,8 @@ class PageFilterFeats extends PageFilter {
|
||||
feat._fMisc = feat.srd ? ["SRD"] : [];
|
||||
if (feat.basicRules) feat._fMisc.push("Basic Rules");
|
||||
if (SourceUtil.isLegacySourceWotc(feat.source)) feat._fMisc.push("Legacy");
|
||||
if (feat.hasFluff || feat.fluff?.entries) feat._fMisc.push("Has Info");
|
||||
if (feat.hasFluffImages || feat.fluff?.images) feat._fMisc.push("Has Images");
|
||||
if (this._hasFluff(feat)) feat._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(feat)) feat._fMisc.push("Has Images");
|
||||
if (feat.repeatable != null) feat._fMisc.push(feat.repeatable ? "Repeatable" : "Not Repeatable");
|
||||
|
||||
feat._slAbility = ability.asText || VeCt.STR_NONE;
|
||||
|
||||
@@ -96,8 +96,8 @@ class PageFilterEquipment extends PageFilter {
|
||||
if (item.srd) item._fMisc.push("SRD");
|
||||
if (item.basicRules) item._fMisc.push("Basic Rules");
|
||||
if (SourceUtil.isLegacySourceWotc(item.source)) item._fMisc.push("Legacy");
|
||||
if (item.hasFluff || item.fluff?.entries) item._fMisc.push("Has Info");
|
||||
if (item.hasFluffImages || item.fluff?.images) item._fMisc.push("Has Images");
|
||||
if (this._hasFluff(item)) item._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(item)) item._fMisc.push("Has Images");
|
||||
if (item.miscTags) item._fMisc.push(...item.miscTags.map(Parser.itemMiscTagToFull));
|
||||
if (this._isReprinted({reprintedAs: item.reprintedAs, tag: "item", prop: "item", page: UrlUtil.PG_ITEMS})) item._fMisc.push("Reprinted");
|
||||
if (item.stealth) item._fMisc.push("Disadvantage on Stealth");
|
||||
@@ -193,7 +193,15 @@ class PageFilterEquipment extends PageFilter {
|
||||
globalThis.PageFilterEquipment = PageFilterEquipment;
|
||||
|
||||
class PageFilterItems extends PageFilterEquipment {
|
||||
static _DEFAULT_HIDDEN_TYPES = new Set(["treasure", "futuristic", "modern", "renaissance"]);
|
||||
static _DEFAULT_HIDDEN_TYPES = new Set([
|
||||
Parser.ITEM_TYPE_JSON_TO_ABV["$"],
|
||||
Parser.ITEM_TYPE_JSON_TO_ABV["$A"],
|
||||
Parser.ITEM_TYPE_JSON_TO_ABV["$C"],
|
||||
Parser.ITEM_TYPE_JSON_TO_ABV["$G"],
|
||||
"futuristic",
|
||||
"modern",
|
||||
"renaissance",
|
||||
]);
|
||||
static _FILTER_BASE_ITEMS_ATTUNEMENT = ["Requires Attunement", "Requires Attunement By...", "Attunement Optional", VeCt.STR_NO_ATTUNEMENT];
|
||||
|
||||
// region static
|
||||
|
||||
@@ -15,8 +15,8 @@ class PageFilterLanguages extends PageFilter {
|
||||
if (it.srd) it._fMisc.push("SRD");
|
||||
if (it.basicRules) it._fMisc.push("Basic Rules");
|
||||
if (SourceUtil.isLegacySourceWotc(it.source)) it._fMisc.push("Legacy");
|
||||
if (it.hasFluff || it.fluff?.entries) it._fMisc.push("Has Info");
|
||||
if (it.hasFluffImages || it.fluff?.images) it._fMisc.push("Has Images");
|
||||
if (this._hasFluff(it)) it._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(it)) it._fMisc.push("Has Images");
|
||||
}
|
||||
|
||||
addToFilters (it, isExcluded) {
|
||||
|
||||
@@ -11,8 +11,8 @@ class PageFilterObjects extends PageFilter {
|
||||
obj._fMisc = obj.srd ? ["SRD"] : [];
|
||||
if (SourceUtil.isLegacySourceWotc(obj.source)) obj._fMisc.push("Legacy");
|
||||
if (Renderer.object.hasToken(obj)) obj._fMisc.push("Has Token");
|
||||
if (obj.hasFluff || obj.fluff?.entries) obj._fMisc.push("Has Info");
|
||||
if (obj.hasFluffImages || obj.fluff?.images) obj._fMisc.push("Has Images");
|
||||
if (this._hasFluff(obj)) obj._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(obj)) obj._fMisc.push("Has Images");
|
||||
}
|
||||
|
||||
addToFilters (obj, isExcluded) {
|
||||
|
||||
@@ -76,19 +76,19 @@ class PageFilterOptionalFeatures extends PageFilter {
|
||||
this._featureFilter,
|
||||
],
|
||||
});
|
||||
this._miscFilter = new Filter({header: "Miscellaneous", items: ["SRD", "Legacy", "Grants Additional Spells"], isMiscFilter: true});
|
||||
this._miscFilter = new Filter({header: "Miscellaneous", items: ["Has Info", "Has Images", "SRD", "Legacy", "Grants Additional Spells"], isMiscFilter: true});
|
||||
}
|
||||
|
||||
static mutateForFilters (it) {
|
||||
it._fSources = SourceFilter.getCompleteFilterSources(it);
|
||||
static mutateForFilters (ent) {
|
||||
ent._fSources = SourceFilter.getCompleteFilterSources(ent);
|
||||
|
||||
// (Convert legacy string format to array)
|
||||
it.featureType = it.featureType && it.featureType instanceof Array ? it.featureType : it.featureType ? [it.featureType] : ["OTH"];
|
||||
if (it.prerequisite) {
|
||||
it._sPrereq = true;
|
||||
it._fPrereqPact = it.prerequisite.filter(it => it.pact).map(it => it.pact);
|
||||
it._fPrereqPatron = it.prerequisite.filter(it => it.patron).map(it => it.patron);
|
||||
it._fprereqSpell = it.prerequisite
|
||||
ent.featureType = ent.featureType && ent.featureType instanceof Array ? ent.featureType : ent.featureType ? [ent.featureType] : ["OTH"];
|
||||
if (ent.prerequisite) {
|
||||
ent._sPrereq = true;
|
||||
ent._fPrereqPact = ent.prerequisite.filter(it => it.pact).map(it => it.pact);
|
||||
ent._fPrereqPatron = ent.prerequisite.filter(it => it.patron).map(it => it.patron);
|
||||
ent._fprereqSpell = ent.prerequisite
|
||||
.filter(it => it.spell)
|
||||
.map(prereq => {
|
||||
return (prereq.spell || [])
|
||||
@@ -111,17 +111,19 @@ class PageFilterOptionalFeatures extends PageFilter {
|
||||
return `Any ${ptChoose}`;
|
||||
});
|
||||
});
|
||||
it._fprereqFeature = it.prerequisite.filter(it => it.feature).map(it => it.feature);
|
||||
it._fPrereqLevel = it.prerequisite.filter(it => it.level).map(PageFilterOptionalFeatures.getLevelFilterItem.bind(PageFilterOptionalFeatures));
|
||||
ent._fprereqFeature = ent.prerequisite.filter(it => it.feature).map(it => it.feature);
|
||||
ent._fPrereqLevel = ent.prerequisite.filter(it => it.level).map(PageFilterOptionalFeatures.getLevelFilterItem.bind(PageFilterOptionalFeatures));
|
||||
}
|
||||
|
||||
it._dFeatureType = it.featureType.map(ft => Parser.optFeatureTypeToFull(ft));
|
||||
it._lFeatureType = it.featureType.join(", ");
|
||||
it.featureType.sort((a, b) => SortUtil.ascSortLower(Parser.optFeatureTypeToFull(a), Parser.optFeatureTypeToFull(b)));
|
||||
ent._dFeatureType = ent.featureType.map(ft => Parser.optFeatureTypeToFull(ft));
|
||||
ent._lFeatureType = ent.featureType.join(", ");
|
||||
ent.featureType.sort((a, b) => SortUtil.ascSortLower(Parser.optFeatureTypeToFull(a), Parser.optFeatureTypeToFull(b)));
|
||||
|
||||
it._fMisc = it.srd ? ["SRD"] : [];
|
||||
if (SourceUtil.isLegacySourceWotc(it.source)) it._fMisc.push("Legacy");
|
||||
if (it.additionalSpells) it._fMisc.push("Grants Additional Spells");
|
||||
ent._fMisc = ent.srd ? ["SRD"] : [];
|
||||
if (SourceUtil.isLegacySourceWotc(ent.source)) ent._fMisc.push("Legacy");
|
||||
if (ent.additionalSpells) ent._fMisc.push("Grants Additional Spells");
|
||||
if (this._hasFluff(ent)) ent._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(ent)) ent._fMisc.push("Has Images");
|
||||
}
|
||||
|
||||
addToFilters (it, isExcluded) {
|
||||
|
||||
@@ -142,8 +142,8 @@ class PageFilterRaces extends PageFilter {
|
||||
if (r.srd) r._fMisc.push("SRD");
|
||||
if (r.basicRules) r._fMisc.push("Basic Rules");
|
||||
if (SourceUtil.isLegacySourceWotc(r.source)) r._fMisc.push("Legacy");
|
||||
if (r.hasFluff || r.fluff?.entries) r._fMisc.push("Has Info");
|
||||
if (r.hasFluffImages || r.fluff?.images) r._fMisc.push("Has Images");
|
||||
if (this._hasFluff(r)) r._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(r)) r._fMisc.push("Has Images");
|
||||
if (r.lineage) r._fMisc.push("Lineage");
|
||||
if (this._isReprinted({reprintedAs: r.reprintedAs, tag: "race", prop: "race", page: UrlUtil.PG_RACES})) r._fMisc.push("Reprinted");
|
||||
|
||||
|
||||
@@ -60,8 +60,8 @@ class PageFilterRecipes extends PageFilter {
|
||||
it._fTimePreparation = it.time?.preparation ? this._mutateForFilters_getFilterTime(it.time.preparation) : null;
|
||||
it._fTimeCooking = it.time?.cooking ? this._mutateForFilters_getFilterTime(it.time.cooking) : null;
|
||||
it._fDiet = it.diet ? PageFilterRecipes._DIET_TO_FULL[it.diet] || it.diet : null;
|
||||
if (it.hasFluff || it.fluff?.entries) it._fMisc.push("Has Info");
|
||||
if (it.hasFluffImages || it.fluff?.images) it._fMisc.push("Has Images");
|
||||
if (this._hasFluff(it)) it._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(it)) it._fMisc.push("Has Images");
|
||||
}
|
||||
|
||||
static _ONE_DAY_MINS = 24 * 60;
|
||||
|
||||
@@ -36,8 +36,8 @@ class PageFilterTrapsHazards extends PageFilter {
|
||||
if (it.srd) it._fMisc.push("SRD");
|
||||
if (it.basicRules) it._fMisc.push("Basic Rules");
|
||||
if (SourceUtil.isLegacySourceWotc(it.source)) it._fMisc.push("Legacy");
|
||||
if (it.hasFluff || it.fluff?.entries) it._fMisc.push("Has Info");
|
||||
if (it.hasFluffImages || it.fluff?.images) it._fMisc.push("Has Images");
|
||||
if (this._hasFluff(it)) it._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(it)) it._fMisc.push("Has Images");
|
||||
}
|
||||
|
||||
addToFilters (it, isExcluded) {
|
||||
|
||||
@@ -61,8 +61,8 @@ class PageFilterVehicles extends PageFilter {
|
||||
ent._fMisc = ent.srd ? ["SRD"] : [];
|
||||
if (SourceUtil.isLegacySourceWotc(ent.source)) ent._fMisc.push("Legacy");
|
||||
if (Renderer.vehicle.hasToken(ent)) ent._fMisc.push("Has Token");
|
||||
if (ent.hasFluff || ent.fluff?.entries) ent._fMisc.push("Has Info");
|
||||
if (ent.hasFluffImages || ent.fluff?.images) ent._fMisc.push("Has Images");
|
||||
if (this._hasFluff(ent)) ent._fMisc.push("Has Info");
|
||||
if (this._hasFluffImages(ent)) ent._fMisc.push("Has Images");
|
||||
}
|
||||
|
||||
addToFilters (it, isExcluded) {
|
||||
|
||||
@@ -96,6 +96,9 @@ class PageFilter {
|
||||
static getListAliases (ent) {
|
||||
return (ent.alias || []).map(it => `"${it}"`).join(",");
|
||||
}
|
||||
|
||||
static _hasFluff (ent) { return ent.hasFluff || ent.fluff?.entries; }
|
||||
static _hasFluffImages (ent) { return ent.hasFluffImages || ent.fluff?.images; }
|
||||
// endregion
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,9 @@ class OptionalFeaturesPage extends ListPage {
|
||||
|
||||
super({
|
||||
dataSource: DataUtil.optionalfeature.loadJSON.bind(DataUtil.optionalfeature),
|
||||
dataSourceFluff: DataUtil.featFluff.loadJSON.bind(DataUtil.featFluff),
|
||||
|
||||
pFnGetFluff: Renderer.optionalfeature.pGetFluff.bind(Renderer.optionalfeature),
|
||||
|
||||
pageFilter,
|
||||
|
||||
@@ -146,21 +149,31 @@ class OptionalFeaturesPage extends ListPage {
|
||||
}
|
||||
|
||||
_renderStats_doBuildStatsTab ({ent}) {
|
||||
this._$wrpTabs.find(`.opt-feature-type`).remove();
|
||||
const $wrpOptFeatType = $(`<div class="opt-feature-type"/>`).prependTo(this._$wrpTabs);
|
||||
this._$wrpTabs.parent().find(`.opt-feature-type`).remove();
|
||||
|
||||
const commonPrefix = ent.featureType.length > 1 ? MiscUtil.findCommonPrefix(ent.featureType.map(fs => Parser.optFeatureTypeToFull(fs)), {isRespectWordBoundaries: true}) : "";
|
||||
if (commonPrefix) $wrpOptFeatType.append(`${commonPrefix.trim()} `);
|
||||
Promise.any([
|
||||
Renderer.utils.pHasFluffText(ent, "optionalfeatureFluff"),
|
||||
Renderer.utils.pHasFluffImages(ent, "optionalfeatureFluff"),
|
||||
])
|
||||
.then(hasAnyFluff => {
|
||||
const $wrpOptFeatType = $(`<div class="opt-feature-type"></div>`);
|
||||
|
||||
ent.featureType.forEach((ft, i) => {
|
||||
if (i > 0) $wrpOptFeatType.append("/");
|
||||
$(`<span class="roller">${Parser.optFeatureTypeToFull(ft).substring(commonPrefix.length)}</span>`)
|
||||
.click(() => {
|
||||
this._filterBox.setFromValues({"Feature Type": {[ft]: 1}});
|
||||
this.handleFilterChange();
|
||||
})
|
||||
.appendTo($wrpOptFeatType);
|
||||
});
|
||||
if (hasAnyFluff) $wrpOptFeatType.addClass("ml-0 mb-1").insertBefore(this._$wrpTabs);
|
||||
else $wrpOptFeatType.prependTo(this._$wrpTabs);
|
||||
|
||||
const commonPrefix = ent.featureType.length > 1 ? MiscUtil.findCommonPrefix(ent.featureType.map(fs => Parser.optFeatureTypeToFull(fs)), {isRespectWordBoundaries: true}) : "";
|
||||
if (commonPrefix) $wrpOptFeatType.append(`${commonPrefix.trim()} `);
|
||||
|
||||
ent.featureType.forEach((ft, i) => {
|
||||
if (i > 0) $wrpOptFeatType.append("/");
|
||||
$(`<span class="roller">${Parser.optFeatureTypeToFull(ft).substring(commonPrefix.length)}</span>`)
|
||||
.click(() => {
|
||||
this._filterBox.setFromValues({"Feature Type": {[ft]: 1}});
|
||||
this.handleFilterChange();
|
||||
})
|
||||
.appendTo($wrpOptFeatType);
|
||||
});
|
||||
});
|
||||
|
||||
this._$pgContent.empty().append(RenderOptionalFeatures.$getRenderedOptionalFeature(ent));
|
||||
}
|
||||
|
||||
@@ -3604,6 +3604,9 @@ Parser.ITEM_TYPE_JSON_TO_ABV = {
|
||||
"TAH": "tack and harness",
|
||||
"TG": "trade good",
|
||||
"$": "treasure",
|
||||
"$A": "treasure (art object)",
|
||||
"$C": "treasure (coinage)",
|
||||
"$G": "treasure (gemstone)",
|
||||
"VEH": "vehicle (land)",
|
||||
"SHP": "vehicle (water)",
|
||||
"AIR": "vehicle (air)",
|
||||
|
||||
43
js/render.js
43
js/render.js
@@ -6094,6 +6094,14 @@ Renderer.optionalfeature = class {
|
||||
<tr><td colspan="6"><p>${Renderer.get().render(Renderer.optionalfeature.getTypeEntry(ent))}</p></td></tr>
|
||||
`;
|
||||
}
|
||||
|
||||
static pGetFluff (ent) {
|
||||
return Renderer.utils.pGetFluff({
|
||||
entity: ent,
|
||||
fnGetFluffData: DataUtil.optionalfeatureFluff.loadJSON.bind(DataUtil.optionalfeatureFluff),
|
||||
fluffProp: "optionalfeatureFluff",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Renderer.reward = class {
|
||||
@@ -6814,12 +6822,12 @@ Renderer.object = class {
|
||||
`;
|
||||
}
|
||||
|
||||
static hasToken (obj) {
|
||||
return Renderer.generic.hasToken(obj);
|
||||
static hasToken (obj, opts) {
|
||||
return Renderer.generic.hasToken(obj, opts);
|
||||
}
|
||||
|
||||
static getTokenUrl (obj) {
|
||||
return Renderer.generic.getTokenUrl(obj, "objects/tokens");
|
||||
static getTokenUrl (obj, opts) {
|
||||
return Renderer.generic.getTokenUrl(obj, "objects/tokens", opts);
|
||||
}
|
||||
|
||||
static pGetFluff (obj) {
|
||||
@@ -7757,12 +7765,12 @@ Renderer.monster = class {
|
||||
return skills;
|
||||
}
|
||||
|
||||
static hasToken (mon) {
|
||||
return Renderer.generic.hasToken(mon);
|
||||
static hasToken (mon, opts) {
|
||||
return Renderer.generic.hasToken(mon, opts);
|
||||
}
|
||||
|
||||
static getTokenUrl (mon) {
|
||||
return Renderer.generic.getTokenUrl(mon, "bestiary/tokens");
|
||||
static getTokenUrl (mon, opts) {
|
||||
return Renderer.generic.getTokenUrl(mon, "bestiary/tokens", opts);
|
||||
}
|
||||
|
||||
static postProcessFluff (mon, fluff) {
|
||||
@@ -10007,12 +10015,12 @@ Renderer.vehicle = class {
|
||||
});
|
||||
}
|
||||
|
||||
static hasToken (veh) {
|
||||
return Renderer.generic.hasToken(veh);
|
||||
static hasToken (veh, opts) {
|
||||
return Renderer.generic.hasToken(veh, opts);
|
||||
}
|
||||
|
||||
static getTokenUrl (veh) {
|
||||
return Renderer.generic.getTokenUrl(veh, "vehicles/tokens");
|
||||
static getTokenUrl (veh, opts) {
|
||||
return Renderer.generic.getTokenUrl(veh, "vehicles/tokens", opts);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10938,18 +10946,20 @@ Renderer.generic = class {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
static hasToken (ent) {
|
||||
return ent.tokenUrl // TODO(Future) legacy; remove
|
||||
|| ent.hasToken // An implicit token
|
||||
static hasToken (ent, {isIgnoreImplicit = false} = {}) {
|
||||
const fromEntity = ent.tokenUrl // TODO(Future) legacy; remove
|
||||
|| ent.token // An explicit token
|
||||
|| ent.tokenHref // An explicit token URL (local or external)
|
||||
;
|
||||
if (fromEntity || isIgnoreImplicit) return !!fromEntity;
|
||||
return ent.hasToken; // An implicit token
|
||||
}
|
||||
|
||||
static getTokenUrl (ent, mediaDir) {
|
||||
static getTokenUrl (ent, mediaDir, {isIgnoreImplicit = false} = {}) {
|
||||
if (ent.tokenUrl) return ent.tokenUrl; // TODO(Future) legacy; remove
|
||||
if (ent.token) return Renderer.get().getMediaUrl("img", `${mediaDir}/${Parser.sourceJsonToAbv(ent.token.source)}/${Parser.nameToTokenName(ent.token.name)}.webp`);
|
||||
if (ent.tokenHref) return Renderer.utils.getEntryMediaUrl(ent, "tokenHref", "img");
|
||||
if (isIgnoreImplicit) return null;
|
||||
return Renderer.get().getMediaUrl("img", `${mediaDir}/${Parser.sourceJsonToAbv(ent.source)}/${Parser.nameToTokenName(ent.name)}.webp`);
|
||||
}
|
||||
};
|
||||
@@ -12221,6 +12231,7 @@ Renderer.hover = class {
|
||||
case UrlUtil.PG_RACES: return Renderer.race.pGetFluff;
|
||||
case UrlUtil.PG_BACKGROUNDS: return Renderer.background.pGetFluff;
|
||||
case UrlUtil.PG_FEATS: return Renderer.feat.pGetFluff;
|
||||
case UrlUtil.PG_OPT_FEATURES: return Renderer.optionalfeature.pGetFluff;
|
||||
case UrlUtil.PG_LANGUAGES: return Renderer.language.pGetFluff;
|
||||
case UrlUtil.PG_VEHICLES: return Renderer.vehicle.pGetFluff;
|
||||
case UrlUtil.PG_CHAR_CREATION_OPTIONS: return Renderer.charoption.pGetFluff;
|
||||
|
||||
@@ -829,6 +829,14 @@ class _DataTypeLoaderFeatFluff extends _DataTypeLoaderSingleSource {
|
||||
_filename = "fluff-feats.json";
|
||||
}
|
||||
|
||||
class _DataTypeLoaderOptionalfeatureFluff extends _DataTypeLoaderSingleSource {
|
||||
static PROPS = ["optionalfeatureFluff"];
|
||||
static PAGE = UrlUtil.PG_OPT_FEATURES;
|
||||
static IS_FLUFF = true;
|
||||
|
||||
_filename = "fluff-optionalfeatures.json";
|
||||
}
|
||||
|
||||
class _DataTypeLoaderItemFluff extends _DataTypeLoaderSingleSource {
|
||||
static PROPS = ["itemFluff"];
|
||||
static PAGE = UrlUtil.PG_ITEMS;
|
||||
@@ -1701,6 +1709,7 @@ class DataLoader {
|
||||
// region Fluff
|
||||
_DataTypeLoaderBackgroundFluff.register({fnRegister});
|
||||
_DataTypeLoaderFeatFluff.register({fnRegister});
|
||||
_DataTypeLoaderOptionalfeatureFluff.register({fnRegister});
|
||||
_DataTypeLoaderItemFluff.register({fnRegister});
|
||||
_DataTypeLoaderRaceFluff.register({fnRegister});
|
||||
_DataTypeLoaderLanguageFluff.register({fnRegister});
|
||||
|
||||
@@ -77,6 +77,20 @@ PropOrder._ObjectKey = class {
|
||||
this.fnGetOrder = opts.fnGetOrder;
|
||||
this.order = opts.order;
|
||||
}
|
||||
|
||||
static getCopyKey ({fnGetModOrder}) {
|
||||
return new this("_copy", {
|
||||
order: [
|
||||
"name",
|
||||
"source",
|
||||
"_templates",
|
||||
new PropOrder._ObjectKey("_mod", {
|
||||
fnGetOrder: fnGetModOrder,
|
||||
}),
|
||||
"_preserve",
|
||||
],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
PropOrder._ArrayKey = class {
|
||||
@@ -122,17 +136,7 @@ PropOrder._MONSTER = [
|
||||
"summonedByClass",
|
||||
|
||||
"_isCopy",
|
||||
new PropOrder._ObjectKey("_copy", {
|
||||
order: [
|
||||
"name",
|
||||
"source",
|
||||
"_trait",
|
||||
new PropOrder._ObjectKey("_mod", {
|
||||
fnGetOrder: () => PropOrder._MONSTER__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
],
|
||||
}),
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._MONSTER__COPY_MOD}),
|
||||
|
||||
"level",
|
||||
"size",
|
||||
@@ -259,7 +263,7 @@ PropOrder._MONSTER = [
|
||||
fnGetOrder: () => PropOrder._MONSTER__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
"_template",
|
||||
"_abstract",
|
||||
"_implementations",
|
||||
...PropOrder._MONSTER,
|
||||
],
|
||||
@@ -289,17 +293,7 @@ PropOrder._MONSTER_TEMPLATE = [
|
||||
|
||||
"ref",
|
||||
|
||||
new PropOrder._ObjectKey("_copy", {
|
||||
order: [
|
||||
"name",
|
||||
"source",
|
||||
"_trait",
|
||||
new PropOrder._ObjectKey("_mod", {
|
||||
fnGetOrder: () => PropOrder._MONSTER_TEMPLATE__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
],
|
||||
}),
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._MONSTER_TEMPLATE__COPY_MOD}),
|
||||
|
||||
"crMin",
|
||||
"crMax",
|
||||
@@ -363,17 +357,7 @@ PropOrder._SPELL = [
|
||||
"additionalSources",
|
||||
"otherSources",
|
||||
|
||||
new PropOrder._ObjectKey("_copy", {
|
||||
order: [
|
||||
"name",
|
||||
"source",
|
||||
"_trait",
|
||||
new PropOrder._ObjectKey("_mod", {
|
||||
fnGetOrder: () => PropOrder._SPELL__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
],
|
||||
}),
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._SPELL__COPY_MOD}),
|
||||
|
||||
"level",
|
||||
"school",
|
||||
@@ -416,8 +400,8 @@ PropOrder._SPELL = [
|
||||
|
||||
"affectsCreatureType",
|
||||
|
||||
"miscTags",
|
||||
"areaTags",
|
||||
new PropOrder._ArrayKey("miscTags", {fnSort: SortUtil.ascSortLower}),
|
||||
new PropOrder._ArrayKey("areaTags", {fnSort: SortUtil.ascSortLower}),
|
||||
|
||||
"hasFluff",
|
||||
"hasFluffImages",
|
||||
@@ -572,17 +556,7 @@ PropOrder._BACKGROUND = [
|
||||
"additionalSources",
|
||||
"otherSources",
|
||||
|
||||
new PropOrder._ObjectKey("_copy", {
|
||||
order: [
|
||||
"name",
|
||||
"source",
|
||||
"_trait",
|
||||
new PropOrder._ObjectKey("_mod", {
|
||||
fnGetOrder: () => PropOrder._BACKGROUND__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
],
|
||||
}),
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._BACKGROUND__COPY_MOD}),
|
||||
|
||||
"prerequisite",
|
||||
"ability",
|
||||
@@ -633,17 +607,7 @@ PropOrder._LEGENDARY_GROUP = [
|
||||
|
||||
"additionalSources",
|
||||
|
||||
new PropOrder._ObjectKey("_copy", {
|
||||
order: [
|
||||
"name",
|
||||
"source",
|
||||
"_trait",
|
||||
new PropOrder._ObjectKey("_mod", {
|
||||
fnGetOrder: () => PropOrder._LEGENDARY_GROUP__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
],
|
||||
}),
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._LEGENDARY_GROUP__COPY_MOD}),
|
||||
|
||||
"lairActions",
|
||||
"regionalEffects",
|
||||
@@ -1098,6 +1062,8 @@ PropOrder._FEAT = [
|
||||
"additionalSources",
|
||||
"otherSources",
|
||||
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._FEAT__COPY_MOD}),
|
||||
|
||||
"category",
|
||||
"prerequisite",
|
||||
|
||||
@@ -1136,6 +1102,11 @@ PropOrder._FEAT = [
|
||||
"foundryEffects",
|
||||
"foundryImg",
|
||||
];
|
||||
PropOrder._FEAT__COPY_MOD = [
|
||||
"*",
|
||||
"_",
|
||||
...PropOrder._FEAT,
|
||||
];
|
||||
PropOrder._FOUNDRY_FEAT = [
|
||||
"name",
|
||||
"source",
|
||||
@@ -1255,16 +1226,7 @@ PropOrder._ITEM = [
|
||||
"otherSources",
|
||||
"reprintedAs",
|
||||
|
||||
new PropOrder._ObjectKey("_copy", {
|
||||
order: [
|
||||
"name",
|
||||
"source",
|
||||
new PropOrder._ObjectKey("_mod", {
|
||||
fnGetOrder: () => PropOrder._ITEM__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
],
|
||||
}),
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._ITEM__COPY_MOD}),
|
||||
|
||||
"baseItem",
|
||||
|
||||
@@ -1408,7 +1370,7 @@ PropOrder._ITEM = [
|
||||
fnGetOrder: obj => Object.keys(obj).sort(SortUtil.ascSortLower),
|
||||
}),
|
||||
|
||||
"miscTags",
|
||||
new PropOrder._ArrayKey("miscTags", {fnSort: SortUtil.ascSortLower}),
|
||||
|
||||
"hasFluff",
|
||||
"hasFluffImages",
|
||||
@@ -1512,6 +1474,8 @@ PropOrder._OPTIONALFEATURE = [
|
||||
"basicRules",
|
||||
"otherSources",
|
||||
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._OPTIONALFEATURE__COPY_MOD}),
|
||||
|
||||
"isClassFeatureVariant",
|
||||
"previousVersion",
|
||||
|
||||
@@ -1542,11 +1506,21 @@ PropOrder._OPTIONALFEATURE = [
|
||||
|
||||
"entries",
|
||||
|
||||
"hasFluff",
|
||||
"hasFluffImages",
|
||||
|
||||
"fluff",
|
||||
|
||||
"foundrySystem",
|
||||
"foundryFlags",
|
||||
"foundryEffects",
|
||||
"foundryImg",
|
||||
];
|
||||
PropOrder._OPTIONALFEATURE__COPY_MOD = [
|
||||
"*",
|
||||
"_",
|
||||
...PropOrder._OPTIONALFEATURE,
|
||||
];
|
||||
PropOrder._PSIONIC = [
|
||||
"name",
|
||||
|
||||
@@ -1601,16 +1575,7 @@ PropOrder._RACE_SUBRACE = [
|
||||
"otherSources",
|
||||
"reprintedAs",
|
||||
|
||||
new PropOrder._ObjectKey("_copy", {
|
||||
order: [
|
||||
"name",
|
||||
"source",
|
||||
new PropOrder._ObjectKey("_mod", {
|
||||
fnGetOrder: () => PropOrder._RACE__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
],
|
||||
}),
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._RACE__COPY_MOD}),
|
||||
|
||||
"lineage",
|
||||
"creatureTypes",
|
||||
@@ -1667,7 +1632,7 @@ PropOrder._RACE_SUBRACE = [
|
||||
fnGetOrder: () => PropOrder._RACE__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
"_template",
|
||||
"_abstract",
|
||||
"_implementations",
|
||||
...PropOrder._RACE,
|
||||
],
|
||||
@@ -1817,7 +1782,7 @@ PropOrder._RECIPE = [
|
||||
"instructions",
|
||||
"noteCook",
|
||||
|
||||
"miscTags",
|
||||
new PropOrder._ArrayKey("miscTags", {fnSort: SortUtil.ascSortLower}),
|
||||
|
||||
"fluff",
|
||||
|
||||
@@ -1874,16 +1839,7 @@ PropOrder._DECK = [
|
||||
"basicRules",
|
||||
"otherSources",
|
||||
|
||||
new PropOrder._ObjectKey("_copy", {
|
||||
order: [
|
||||
"name",
|
||||
"source",
|
||||
new PropOrder._ObjectKey("_mod", {
|
||||
fnGetOrder: () => PropOrder._DECK__COPY_MOD,
|
||||
}),
|
||||
"_preserve",
|
||||
],
|
||||
}),
|
||||
PropOrder._ObjectKey.getCopyKey({fnGetModOrder: () => PropOrder._DECK__COPY_MOD}),
|
||||
|
||||
"cards",
|
||||
"back",
|
||||
@@ -1959,6 +1915,7 @@ PropOrder._PROP_TO_LIST = {
|
||||
"makebrewCreatureAction": PropOrder._MAKE_BREW_CREATURE_ACTION,
|
||||
"backgroundFluff": PropOrder._GENERIC_FLUFF,
|
||||
"featFluff": PropOrder._GENERIC_FLUFF,
|
||||
"optionalfeatureFluff": PropOrder._GENERIC_FLUFF,
|
||||
"conditionFluff": PropOrder._GENERIC_FLUFF,
|
||||
"itemFluff": PropOrder._GENERIC_FLUFF,
|
||||
"languageFluff": PropOrder._GENERIC_FLUFF,
|
||||
|
||||
83
js/utils.js
83
js/utils.js
@@ -2,7 +2,7 @@
|
||||
|
||||
// in deployment, `IS_DEPLOYED = "<version number>";` should be set below.
|
||||
globalThis.IS_DEPLOYED = undefined;
|
||||
globalThis.VERSION_NUMBER = /* 5ETOOLS_VERSION__OPEN */"1.199.2"/* 5ETOOLS_VERSION__CLOSE */;
|
||||
globalThis.VERSION_NUMBER = /* 5ETOOLS_VERSION__OPEN */"1.199.3"/* 5ETOOLS_VERSION__CLOSE */;
|
||||
globalThis.DEPLOYED_IMG_ROOT = undefined;
|
||||
// for the roll20 script to set
|
||||
globalThis.IS_VTT = false;
|
||||
@@ -4079,7 +4079,8 @@ globalThis.DataUtil = {
|
||||
if (it._copy) await DataUtil.generic._pMergeCopy(impl, page, entryList, it, options);
|
||||
|
||||
// Preload templates, if required
|
||||
const templateData = entry._copy?._trait
|
||||
// TODO(Template) allow templates for other entity types
|
||||
const templateData = entry._copy?._templates
|
||||
? (await DataUtil.loadJSON(`${Renderer.get().baseUrl}data/bestiary/template.json`))
|
||||
: null;
|
||||
return DataUtil.generic.copyApplier.getCopy(impl, MiscUtil.copyFast(it), entry, templateData, options);
|
||||
@@ -4601,26 +4602,50 @@ globalThis.DataUtil = {
|
||||
if (copyMeta._mod) this._normaliseMods(copyMeta);
|
||||
|
||||
// fetch and apply any external template -- append them to existing copy mods where available
|
||||
let template = null;
|
||||
if (copyMeta._trait) {
|
||||
template = templateData.monsterTemplate.find(t => t.name.toLowerCase() === copyMeta._trait.name.toLowerCase() && t.source.toLowerCase() === copyMeta._trait.source.toLowerCase());
|
||||
if (!template) throw new Error(`${msgPtFailed} Could not find traits to apply with name "${copyMeta._trait.name}" and source "${copyMeta._trait.source}"`);
|
||||
template = MiscUtil.copyFast(template);
|
||||
let templates = null;
|
||||
let templateErrors = [];
|
||||
if (copyMeta._templates?.length) {
|
||||
templates = copyMeta._templates
|
||||
.map(({name: templateName, source: templateSource}) => {
|
||||
templateName = templateName.toLowerCase().trim();
|
||||
templateSource = templateSource.toLowerCase().trim();
|
||||
|
||||
if (template.apply._mod) {
|
||||
this._normaliseMods(template.apply);
|
||||
// TODO(Template) allow templates for other entity types
|
||||
const template = templateData.monsterTemplate
|
||||
.find(({name, source}) => name.toLowerCase().trim() === templateName && source.toLowerCase().trim() === templateSource);
|
||||
|
||||
if (copyMeta._mod) {
|
||||
Object.entries(template.apply._mod).forEach(([k, v]) => {
|
||||
if (copyMeta._mod[k]) copyMeta._mod[k] = copyMeta._mod[k].concat(v);
|
||||
else copyMeta._mod[k] = v;
|
||||
});
|
||||
} else copyMeta._mod = template.apply._mod;
|
||||
}
|
||||
if (!template) {
|
||||
templateErrors.push(`Could not find traits to apply with name "${templateName}" and source "${templateSource}"`);
|
||||
return null;
|
||||
}
|
||||
|
||||
delete copyMeta._trait;
|
||||
return MiscUtil.copyFast(template);
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
templates
|
||||
.forEach(template => {
|
||||
if (!template.apply._mod) return;
|
||||
|
||||
this._normaliseMods(template.apply);
|
||||
|
||||
if (!copyMeta._mod) {
|
||||
copyMeta._mod = template.apply._mod;
|
||||
return;
|
||||
}
|
||||
|
||||
Object.entries(template.apply._mod)
|
||||
.forEach(([k, v]) => {
|
||||
if (copyMeta._mod[k]) copyMeta._mod[k] = copyMeta._mod[k].concat(v);
|
||||
else copyMeta._mod[k] = v;
|
||||
});
|
||||
});
|
||||
|
||||
delete copyMeta._templates;
|
||||
}
|
||||
|
||||
if (templateErrors.length) throw new Error(`${msgPtFailed} ${templateErrors.join("; ")}`);
|
||||
|
||||
const copyToRootProps = new Set(Object.keys(copyTo));
|
||||
|
||||
// copy over required values
|
||||
@@ -4633,11 +4658,16 @@ globalThis.DataUtil = {
|
||||
}
|
||||
});
|
||||
|
||||
// apply any root racial properties after doing base copy
|
||||
if (template && template.apply._root) {
|
||||
Object.entries(template.apply._root)
|
||||
.filter(([k, v]) => !copyToRootProps.has(k)) // avoid overwriting any real root properties
|
||||
.forEach(([k, v]) => copyTo[k] = v);
|
||||
// apply any root template properties after doing base copy
|
||||
if (templates?.length) {
|
||||
templates
|
||||
.forEach(template => {
|
||||
if (!template.apply?._root) return;
|
||||
|
||||
Object.entries(template.apply._root)
|
||||
.filter(([k, v]) => !copyToRootProps.has(k)) // avoid overwriting any real root properties
|
||||
.forEach(([k, v]) => copyTo[k] = v);
|
||||
});
|
||||
}
|
||||
|
||||
// apply mods
|
||||
@@ -4742,7 +4772,7 @@ globalThis.DataUtil = {
|
||||
|
||||
return parent._versions
|
||||
.map(ver => {
|
||||
if (ver._template && ver._implementations?.length) return DataUtil.generic._getVersions_template({ver});
|
||||
if (ver._abstract && ver._implementations?.length) return DataUtil.generic._getVersions_template({ver});
|
||||
return DataUtil.generic._getVersions_basic({ver});
|
||||
})
|
||||
.flat()
|
||||
@@ -4752,7 +4782,7 @@ globalThis.DataUtil = {
|
||||
_getVersions_template ({ver}) {
|
||||
return ver._implementations
|
||||
.map(impl => {
|
||||
let cpyTemplate = MiscUtil.copyFast(ver._template);
|
||||
let cpyTemplate = MiscUtil.copyFast(ver._abstract);
|
||||
const cpyImpl = MiscUtil.copyFast(impl);
|
||||
|
||||
DataUtil.generic._getVersions_mutExpandCopy({ent: cpyTemplate});
|
||||
@@ -5517,6 +5547,11 @@ globalThis.DataUtil = {
|
||||
static _FILENAME = "optionalfeatures.json";
|
||||
},
|
||||
|
||||
optionalfeatureFluff: class extends _DataUtilPropConfigSingleSource {
|
||||
static _PAGE = UrlUtil.PG_OPT_FEATURES;
|
||||
static _FILENAME = "fluff-optionalfeatures.json";
|
||||
},
|
||||
|
||||
class: class clazz extends _DataUtilPropConfigCustom {
|
||||
static _PAGE = UrlUtil.PG_CLASSES;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user