Merge branch 'compendium-corrections' into 'master'
fix: fix some creatures in the creature compendium pack See merge request dungeonslayers/ds4!146
This commit is contained in:
commit
5697bdb4f3
10 changed files with 1086 additions and 359 deletions
36
gulpfile.js
36
gulpfile.js
|
@ -51,6 +51,39 @@ function buildStyles() {
|
||||||
.pipe(gulp.dest(path.join(distDirectory, "css")));
|
.pipe(gulp.dest(path.join(distDirectory, "css")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove unwanted data from a pack entry
|
||||||
|
*/
|
||||||
|
function cleanPackEntry(entry, cleanSourceId = true) {
|
||||||
|
if (cleanSourceId) {
|
||||||
|
delete entry.flags?.core?.sourceId;
|
||||||
|
}
|
||||||
|
Object.keys(entry.flags).forEach((scope) => {
|
||||||
|
if (Object.keys(entry.flags[scope]).length === 0) {
|
||||||
|
delete entry.flags[scope];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (entry.permission) entry.permission = { default: 0 };
|
||||||
|
|
||||||
|
const embeddedDocumentCollections = [
|
||||||
|
"drawings",
|
||||||
|
"effects",
|
||||||
|
"items",
|
||||||
|
"lights",
|
||||||
|
"notes",
|
||||||
|
"results",
|
||||||
|
"sounds",
|
||||||
|
"templates",
|
||||||
|
"tiles",
|
||||||
|
"tokens",
|
||||||
|
"walls",
|
||||||
|
];
|
||||||
|
embeddedDocumentCollections
|
||||||
|
.flatMap((embeddedDocumentCollection) => entry[embeddedDocumentCollection] ?? [])
|
||||||
|
.forEach((embeddedEntry) => cleanPackEntry(embeddedEntry, false));
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a stream of JSON files to NeDB files
|
* Convert a stream of JSON files to NeDB files
|
||||||
*/
|
*/
|
||||||
|
@ -60,6 +93,7 @@ const jsonToNeDB = () =>
|
||||||
try {
|
try {
|
||||||
file.contents = Buffer.from(
|
file.contents = Buffer.from(
|
||||||
JSON.parse(file.contents.toString())
|
JSON.parse(file.contents.toString())
|
||||||
|
.map(cleanPackEntry)
|
||||||
.map((entry) => JSON.stringify(entry))
|
.map((entry) => JSON.stringify(entry))
|
||||||
.join("\n") + "\n",
|
.join("\n") + "\n",
|
||||||
);
|
);
|
||||||
|
@ -97,7 +131,7 @@ const neDBToJSON = () =>
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
file.contents = Buffer.from(JSON.stringify(docs, undefined, 4) + "\n");
|
file.contents = Buffer.from(JSON.stringify(docs.map(cleanPackEntry), undefined, 4) + "\n");
|
||||||
file.path = path.join(
|
file.path = path.join(
|
||||||
path.dirname(file.path),
|
path.dirname(file.path),
|
||||||
path.basename(file.path, path.extname(file.path)) + ".json",
|
path.basename(file.path, path.extname(file.path)) + ".json",
|
||||||
|
|
|
@ -94,6 +94,8 @@
|
||||||
"DS4.ArmorMaterialTypeChainAbbr": "Ketten",
|
"DS4.ArmorMaterialTypeChainAbbr": "Ketten",
|
||||||
"DS4.ArmorMaterialTypePlate": "Platten",
|
"DS4.ArmorMaterialTypePlate": "Platten",
|
||||||
"DS4.ArmorMaterialTypePlateAbbr": "Platten",
|
"DS4.ArmorMaterialTypePlateAbbr": "Platten",
|
||||||
|
"DS4.ArmorMaterialTypeNatural": "Natürlich",
|
||||||
|
"DS4.ArmorMaterialTypeNaturalAbbr": "Natürlich",
|
||||||
"DS4.SpellType": "Zauberspruchtyp",
|
"DS4.SpellType": "Zauberspruchtyp",
|
||||||
"DS4.SpellTypeAbbr": "T",
|
"DS4.SpellTypeAbbr": "T",
|
||||||
"DS4.SpellTypeSpellcasting": "Zaubern",
|
"DS4.SpellTypeSpellcasting": "Zaubern",
|
||||||
|
|
|
@ -94,6 +94,8 @@
|
||||||
"DS4.ArmorMaterialTypeChainAbbr": "Chain",
|
"DS4.ArmorMaterialTypeChainAbbr": "Chain",
|
||||||
"DS4.ArmorMaterialTypePlate": "Plate",
|
"DS4.ArmorMaterialTypePlate": "Plate",
|
||||||
"DS4.ArmorMaterialTypePlateAbbr": "Plate",
|
"DS4.ArmorMaterialTypePlateAbbr": "Plate",
|
||||||
|
"DS4.ArmorMaterialTypeNatural": "Natural",
|
||||||
|
"DS4.ArmorMaterialTypeNaturalAbbr": "Natural",
|
||||||
"DS4.SpellType": "Spell Type",
|
"DS4.SpellType": "Spell Type",
|
||||||
"DS4.SpellTypeAbbr": "T",
|
"DS4.SpellTypeAbbr": "T",
|
||||||
"DS4.SpellTypeSpellcasting": "Spellcasting",
|
"DS4.SpellTypeSpellcasting": "Spellcasting",
|
||||||
|
|
|
@ -43,7 +43,8 @@ export class DS4ActiveEffect extends ActiveEffect {
|
||||||
if (!(this.parent instanceof DS4Actor)) {
|
if (!(this.parent instanceof DS4Actor)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const [, , , itemId] = this.data.origin?.split(".") ?? [];
|
const itemIdRegex = /Item\.([a-zA-Z0-9]+)/;
|
||||||
|
const itemId = this.data.origin?.match(itemIdRegex)?.[1];
|
||||||
if (!itemId) {
|
if (!itemId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -92,17 +93,15 @@ export class DS4ActiveEffect extends ActiveEffect {
|
||||||
/**
|
/**
|
||||||
* Create a new {@link DS4ActiveEffect} using default data.
|
* Create a new {@link DS4ActiveEffect} using default data.
|
||||||
*
|
*
|
||||||
* @param context The context for the creation of the effect, requiring a parent {@link DS4Actor} or {@link DS4Item}.
|
* @param parent The parent {@link DS4Actor} or {@link DS4Item} of the effect.
|
||||||
* @returns A promise that resolved to the created effect or udifined of the creation was prevented.
|
* @returns A promise that resolved to the created effect or udifined of the creation was prevented.
|
||||||
*/
|
*/
|
||||||
static async createDefault(
|
static async createDefault(parent: DS4Actor | DS4Item): Promise<DS4ActiveEffect | undefined> {
|
||||||
context: DocumentModificationContext & { parent: DS4Actor | DS4Item },
|
|
||||||
): Promise<DS4ActiveEffect | undefined> {
|
|
||||||
const createData = {
|
const createData = {
|
||||||
label: getGame().i18n.localize(`DS4.NewEffectLabel`),
|
label: getGame().i18n.localize(`DS4.NewEffectLabel`),
|
||||||
icon: this.FALLBACK_ICON,
|
icon: this.FALLBACK_ICON,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.create(createData, context);
|
return this.create(createData, { parent, pack: parent.pack ?? undefined });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import { ModifiableDataBaseTotal } from "../common/common-data";
|
import { ModifiableDataBaseTotal } from "../common/common-data";
|
||||||
import { DS4 } from "../config";
|
import { DS4 } from "../config";
|
||||||
import { getGame } from "../helpers";
|
import { getGame } from "../helpers";
|
||||||
|
import { DS4Item } from "../item/item";
|
||||||
import { DS4ArmorDataProperties, DS4ShieldDataProperties } from "../item/item-data-properties";
|
import { DS4ArmorDataProperties, DS4ShieldDataProperties } from "../item/item-data-properties";
|
||||||
import { ItemType } from "../item/item-data-source";
|
import { ItemType } from "../item/item-data-source";
|
||||||
import { createCheckRoll } from "../rolls/check-factory";
|
import { createCheckRoll } from "../rolls/check-factory";
|
||||||
|
@ -117,8 +118,8 @@ export class DS4Actor extends Actor {
|
||||||
* @override
|
* @override
|
||||||
*/
|
*/
|
||||||
prepareDerivedData(): void {
|
prepareDerivedData(): void {
|
||||||
this._prepareCombatValues();
|
this.prepareCombatValues();
|
||||||
this._prepareChecks();
|
this.prepareChecks();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,9 +190,10 @@ export class DS4Actor extends Actor {
|
||||||
/**
|
/**
|
||||||
* Prepares the combat values of the actor.
|
* Prepares the combat values of the actor.
|
||||||
*/
|
*/
|
||||||
protected _prepareCombatValues(): void {
|
protected prepareCombatValues(): void {
|
||||||
const data = this.data.data;
|
const data = this.data.data;
|
||||||
const armorValueOfEquippedItems = this._calculateArmorValueOfEquippedItems();
|
const armorValueOfEquippedItems = this.calculateArmorValueOfEquippedItems();
|
||||||
|
const spellMalusOfEquippedItems = this.calculateSpellMaluesOfEquippedItems();
|
||||||
|
|
||||||
data.combatValues.hitPoints.base = data.attributes.body.total + data.traits.constitution.total + 10;
|
data.combatValues.hitPoints.base = data.attributes.body.total + data.traits.constitution.total + 10;
|
||||||
data.combatValues.defense.base =
|
data.combatValues.defense.base =
|
||||||
|
@ -201,9 +203,9 @@ export class DS4Actor extends Actor {
|
||||||
data.combatValues.meleeAttack.base = data.attributes.body.total + data.traits.strength.total;
|
data.combatValues.meleeAttack.base = data.attributes.body.total + data.traits.strength.total;
|
||||||
data.combatValues.rangedAttack.base = data.attributes.mobility.total + data.traits.dexterity.total;
|
data.combatValues.rangedAttack.base = data.attributes.mobility.total + data.traits.dexterity.total;
|
||||||
data.combatValues.spellcasting.base =
|
data.combatValues.spellcasting.base =
|
||||||
data.attributes.mind.total + data.traits.aura.total - armorValueOfEquippedItems;
|
data.attributes.mind.total + data.traits.aura.total - spellMalusOfEquippedItems;
|
||||||
data.combatValues.targetedSpellcasting.base =
|
data.combatValues.targetedSpellcasting.base =
|
||||||
data.attributes.mind.total + data.traits.dexterity.total - armorValueOfEquippedItems;
|
data.attributes.mind.total + data.traits.dexterity.total - spellMalusOfEquippedItems;
|
||||||
|
|
||||||
Object.values(data.combatValues).forEach(
|
Object.values(data.combatValues).forEach(
|
||||||
(combatValue: ModifiableDataBaseTotal<number>) => (combatValue.total = combatValue.base + combatValue.mod),
|
(combatValue: ModifiableDataBaseTotal<number>) => (combatValue.total = combatValue.base + combatValue.mod),
|
||||||
|
@ -211,24 +213,40 @@ export class DS4Actor extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the total armor value of all equipped items.
|
* Calculates the total armor value of the equipped items.
|
||||||
*/
|
*/
|
||||||
protected _calculateArmorValueOfEquippedItems(): number {
|
protected calculateArmorValueOfEquippedItems(): number {
|
||||||
return this.items
|
return this.getEquippedItemsWithArmor()
|
||||||
.map((item) => item.data)
|
.map((item) => item.data.data.armorValue)
|
||||||
.filter(
|
|
||||||
(data): data is foundry.data.ItemData & (DS4ArmorDataProperties | DS4ShieldDataProperties) =>
|
|
||||||
data.type === "armor" || data.type === "shield",
|
|
||||||
)
|
|
||||||
.filter((data) => data.data.equipped)
|
|
||||||
.map((data) => data.data.armorValue)
|
|
||||||
.reduce((a, b) => a + b, 0);
|
.reduce((a, b) => a + b, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the spell malus from equipped items.
|
||||||
|
*/
|
||||||
|
protected calculateSpellMaluesOfEquippedItems(): number {
|
||||||
|
return this.getEquippedItemsWithArmor()
|
||||||
|
.filter(
|
||||||
|
(item) =>
|
||||||
|
!(item.data.type === "armor" && ["cloth", "natural"].includes(item.data.data.armorMaterialType)),
|
||||||
|
)
|
||||||
|
.map((item) => item.data.data.armorValue)
|
||||||
|
.reduce((a, b) => a + b, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private getEquippedItemsWithArmor() {
|
||||||
|
return this.items
|
||||||
|
.filter(
|
||||||
|
(item): item is DS4Item & { data: DS4ArmorDataProperties | DS4ShieldDataProperties } =>
|
||||||
|
item.data.type === "armor" || item.data.type === "shield",
|
||||||
|
)
|
||||||
|
.filter((item) => item.data.data.equipped);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares the check target numbers of checks for the actor.
|
* Prepares the check target numbers of checks for the actor.
|
||||||
*/
|
*/
|
||||||
protected _prepareChecks(): void {
|
protected prepareChecks(): void {
|
||||||
const data = this.data.data;
|
const data = this.data.data;
|
||||||
data.checks = {
|
data.checks = {
|
||||||
appraise: data.attributes.mind.total + data.traits.intellect.total,
|
appraise: data.attributes.mind.total + data.traits.intellect.total,
|
||||||
|
|
|
@ -141,7 +141,7 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD
|
||||||
type: type,
|
type: type,
|
||||||
data: data,
|
data: data,
|
||||||
};
|
};
|
||||||
Item.create(itemData, { parent: this.actor });
|
Item.create(itemData, { parent: this.actor, pack: this.actor.pack ?? undefined });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -205,7 +205,7 @@ export class DS4ActorSheet extends ActorSheet<ActorSheet.Options, DS4ActorSheetD
|
||||||
* @param event - The originating click event
|
* @param event - The originating click event
|
||||||
*/
|
*/
|
||||||
protected onCreateEffect(): void {
|
protected onCreateEffect(): void {
|
||||||
DS4ActiveEffect.createDefault({ parent: this.actor });
|
DS4ActiveEffect.createDefault(this.actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -75,6 +75,7 @@ const i18nKeys = {
|
||||||
leather: "DS4.ArmorMaterialTypeLeather",
|
leather: "DS4.ArmorMaterialTypeLeather",
|
||||||
chain: "DS4.ArmorMaterialTypeChain",
|
chain: "DS4.ArmorMaterialTypeChain",
|
||||||
plate: "DS4.ArmorMaterialTypePlate",
|
plate: "DS4.ArmorMaterialTypePlate",
|
||||||
|
natural: "DS4.ArmorMaterialTypeNatural",
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,6 +86,7 @@ const i18nKeys = {
|
||||||
leather: "DS4.ArmorMaterialTypeLeatherAbbr",
|
leather: "DS4.ArmorMaterialTypeLeatherAbbr",
|
||||||
chain: "DS4.ArmorMaterialTypeChainAbbr",
|
chain: "DS4.ArmorMaterialTypeChainAbbr",
|
||||||
plate: "DS4.ArmorMaterialTypePlateAbbr",
|
plate: "DS4.ArmorMaterialTypePlateAbbr",
|
||||||
|
natural: "DS4.ArmorMaterialTypeNaturalAbbr",
|
||||||
},
|
},
|
||||||
|
|
||||||
spellTypes: {
|
spellTypes: {
|
||||||
|
|
|
@ -99,7 +99,7 @@ export class DS4ItemSheet extends ItemSheet<ItemSheet.Options, DS4ItemSheetData>
|
||||||
* Create a new ActiveEffect for the item using default data.
|
* Create a new ActiveEffect for the item using default data.
|
||||||
*/
|
*/
|
||||||
protected createActiveEffect(): void {
|
protected createActiveEffect(): void {
|
||||||
DS4ActiveEffect.createDefault({ parent: this.item });
|
DS4ActiveEffect.createDefault(this.item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -512,17 +512,44 @@
|
||||||
{
|
{
|
||||||
"_id": "ZkgZiFI5xy8aevG8",
|
"_id": "ZkgZiFI5xy8aevG8",
|
||||||
"name": "Totenkraft",
|
"name": "Totenkraft",
|
||||||
"permission": {
|
|
||||||
"default": 0
|
|
||||||
},
|
|
||||||
"type": "specialCreatureAbility",
|
"type": "specialCreatureAbility",
|
||||||
|
"img": "systems/ds4/assets/icons/official/special-creature-abilities/power-of-the-dead.png",
|
||||||
"data": {
|
"data": {
|
||||||
"description": "<p>Erhält GEI+AU als Bonus auf Stärke und Härte.</p>",
|
"description": "<p>Erhält GEI+AU als Bonus auf Stärke und Härte.</p>",
|
||||||
"experiencePoints": 10
|
"experiencePoints": 10
|
||||||
},
|
},
|
||||||
|
"effects": [
|
||||||
|
{
|
||||||
|
"_id": "xw1OyyTdDwkNe2jC",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "data.traits.strength.total",
|
||||||
|
"mode": 2,
|
||||||
|
"value": "@data.attributes.mind.total + @data.traits.aura.total"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "data.traits.constitution.total",
|
||||||
|
"mode": 2,
|
||||||
|
"value": "@data.attributes.mind.total + @data.traits.aura.total"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"disabled": false,
|
||||||
|
"duration": {
|
||||||
|
"startTime": null
|
||||||
|
},
|
||||||
|
"icon": "icons/svg/aura.svg",
|
||||||
|
"label": "GEI + AU als Bonus auf Stärke und Härte",
|
||||||
|
"transfer": true,
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"img": "systems/ds4/assets/icons/official/special-creature-abilities/power-of-the-dead.png",
|
"tint": null
|
||||||
"effects": []
|
}
|
||||||
|
],
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"permission": {
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"flags": {}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"_id": "aOsmsf7jIK7hU9U8",
|
"_id": "aOsmsf7jIK7hU9U8",
|
||||||
|
|
Loading…
Reference in a new issue