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:
Johannes Loher 2021-10-02 01:55:02 +00:00
commit 5697bdb4f3
10 changed files with 1086 additions and 359 deletions

View file

@ -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",

View file

@ -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",

View file

@ -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",

View file

@ -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 });
} }
} }

View file

@ -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,

View file

@ -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);
} }
/** /**

View file

@ -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: {

View file

@ -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

View file

@ -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&auml;lt GEI+AU als Bonus auf St&auml;rke und H&auml;rte.</p>", "description": "<p>Erh&auml;lt GEI+AU als Bonus auf St&auml;rke und H&auml;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",