diff --git a/README.md b/README.md
index a5c7fe48..5e2bbcec 100644
--- a/README.md
+++ b/README.md
@@ -43,3 +43,15 @@ Now you should be able to build the app using `npm start`
## Contributing
Looking to contribute to the project? Look no further, check out our [contributing guide](contributing.md), and keep the [Code of Conduct](coc.md) in mind when working on things.
+
+## Disclaimer:
+
+**Daggerheart System**
+Daggerheart is a trademark of Darrington Press LLC. All original content, mechanics, and intellectual property related to the Daggerheart roleplaying game are © Darrington Press LLC.
+
+This project is intended for personal or non-commercial use. All rights to Daggerheart’s original materials remain with their respective owners.
+
+**Free Icons**
+Some Icons used in this project are provided by https://game-icons.net and are licensed under the Creative Commons Attribution 3.0 Unported (CC BY 3.0).
+
+This project is an unofficial fan creation and is not affiliated with or endorsed by Darrington Press or Critical Role.
diff --git a/assets/icons/documents/actors/capybara.svg b/assets/icons/documents/actors/capybara.svg
new file mode 100644
index 00000000..90deb64a
--- /dev/null
+++ b/assets/icons/documents/actors/capybara.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/actors/dragon-head.svg b/assets/icons/documents/actors/dragon-head.svg
new file mode 100644
index 00000000..d9e008f5
--- /dev/null
+++ b/assets/icons/documents/actors/dragon-head.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/actors/forest.svg b/assets/icons/documents/actors/forest.svg
new file mode 100644
index 00000000..8f7117e8
--- /dev/null
+++ b/assets/icons/documents/actors/forest.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/battered-axe.svg b/assets/icons/documents/items/battered-axe.svg
new file mode 100644
index 00000000..5d7be27d
--- /dev/null
+++ b/assets/icons/documents/items/battered-axe.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/card-play.svg b/assets/icons/documents/items/card-play.svg
new file mode 100644
index 00000000..587cb1c1
--- /dev/null
+++ b/assets/icons/documents/items/card-play.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/chest-armor.svg b/assets/icons/documents/items/chest-armor.svg
new file mode 100644
index 00000000..2cef80a6
--- /dev/null
+++ b/assets/icons/documents/items/chest-armor.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/family-tree.svg b/assets/icons/documents/items/family-tree.svg
new file mode 100644
index 00000000..d95c935d
--- /dev/null
+++ b/assets/icons/documents/items/family-tree.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/laurel-crown.svg b/assets/icons/documents/items/laurel-crown.svg
new file mode 100644
index 00000000..34a54d2a
--- /dev/null
+++ b/assets/icons/documents/items/laurel-crown.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/laurels.svg b/assets/icons/documents/items/laurels.svg
new file mode 100644
index 00000000..2c3cdf63
--- /dev/null
+++ b/assets/icons/documents/items/laurels.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/open-treasure-chest.svg b/assets/icons/documents/items/open-treasure-chest.svg
new file mode 100644
index 00000000..172a8003
--- /dev/null
+++ b/assets/icons/documents/items/open-treasure-chest.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/round-potion.svg b/assets/icons/documents/items/round-potion.svg
new file mode 100644
index 00000000..7f981914
--- /dev/null
+++ b/assets/icons/documents/items/round-potion.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/stars-stack.svg b/assets/icons/documents/items/stars-stack.svg
new file mode 100644
index 00000000..19c197f6
--- /dev/null
+++ b/assets/icons/documents/items/stars-stack.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/village.svg b/assets/icons/documents/items/village.svg
new file mode 100644
index 00000000..c28d742b
--- /dev/null
+++ b/assets/icons/documents/items/village.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/documents/items/wolf-head.svg b/assets/icons/documents/items/wolf-head.svg
new file mode 100644
index 00000000..2be500c1
--- /dev/null
+++ b/assets/icons/documents/items/wolf-head.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/module/data/actor/adversary.mjs b/module/data/actor/adversary.mjs
index c0cecb59..e64c64f3 100644
--- a/module/data/actor/adversary.mjs
+++ b/module/data/actor/adversary.mjs
@@ -105,6 +105,13 @@ export default class DhpAdversary extends BaseDataActor {
};
}
+ /* -------------------------------------------- */
+
+ /**@inheritdoc */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/actors/dragon-head.svg';
+
+ /* -------------------------------------------- */
+
get attackBonus() {
return this.attack.roll.bonus;
}
diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs
index f0db33e9..386b9695 100644
--- a/module/data/actor/base.mjs
+++ b/module/data/actor/base.mjs
@@ -69,6 +69,16 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
return schema;
}
+ /* -------------------------------------------- */
+
+ /**
+ * The default icon used for newly created Actors documents
+ * @type {string}
+ */
+ static DEFAULT_ICON = null;
+
+ /* -------------------------------------------- */
+
/**
* Obtain a data object used to evaluate any dice rolls associated with this Item Type
* @param {object} [options] - Options which modify the getRollData method.
diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs
index 7cb51d33..8e665265 100644
--- a/module/data/actor/character.mjs
+++ b/module/data/actor/character.mjs
@@ -7,8 +7,10 @@ import { ActionField } from '../fields/actionField.mjs';
import DHCharacterSettings from '../../applications/sheets-configs/character-settings.mjs';
export default class DhCharacter extends BaseDataActor {
+ /**@override */
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Character'];
+ /**@inheritdoc */
static get metadata() {
return foundry.utils.mergeObject(super.metadata, {
label: 'TYPES.Actor.character',
@@ -18,6 +20,7 @@ export default class DhCharacter extends BaseDataActor {
});
}
+ /**@inheritdoc */
static defineSchema() {
const fields = foundry.data.fields;
@@ -303,6 +306,8 @@ export default class DhCharacter extends BaseDataActor {
};
}
+ /* -------------------------------------------- */
+
get tier() {
const currentLevel = this.levelData.level.current;
return currentLevel === 1
diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs
index 3d00661f..7a11f1d1 100644
--- a/module/data/actor/companion.mjs
+++ b/module/data/actor/companion.mjs
@@ -9,6 +9,7 @@ import { resourceField, bonusField } from '../fields/actorField.mjs';
export default class DhCompanion extends BaseDataActor {
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Companion'];
+ /**@inheritdoc */
static get metadata() {
return foundry.utils.mergeObject(super.metadata, {
label: 'TYPES.Actor.companion',
@@ -18,6 +19,7 @@ export default class DhCompanion extends BaseDataActor {
});
}
+ /**@inheritdoc */
static defineSchema() {
const fields = foundry.data.fields;
@@ -87,6 +89,13 @@ export default class DhCompanion extends BaseDataActor {
};
}
+ /* -------------------------------------------- */
+
+ /**@inheritdoc */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/actors/capybara.svg';
+
+ /* -------------------------------------------- */
+
get proficiency() {
return this.partner?.system?.proficiency ?? 1;
}
diff --git a/module/data/actor/environment.mjs b/module/data/actor/environment.mjs
index e9a484b3..adb7dabc 100644
--- a/module/data/actor/environment.mjs
+++ b/module/data/actor/environment.mjs
@@ -3,8 +3,10 @@ import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayFie
import DHEnvironmentSettings from '../../applications/sheets-configs/environment-settings.mjs';
export default class DhEnvironment extends BaseDataActor {
+ /**@override */
static LOCALIZATION_PREFIXES = ['DAGGERHEART.ACTORS.Environment'];
+ /**@inheritdoc */
static get metadata() {
return foundry.utils.mergeObject(super.metadata, {
label: 'TYPES.Actor.environment',
@@ -14,6 +16,7 @@ export default class DhEnvironment extends BaseDataActor {
});
}
+ /**@inheritdoc */
static defineSchema() {
const fields = foundry.data.fields;
return {
@@ -37,6 +40,13 @@ export default class DhEnvironment extends BaseDataActor {
};
}
+ /* -------------------------------------------- */
+
+ /**@inheritdoc */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/actors/forest.svg';
+
+ /* -------------------------------------------- */
+
get features() {
return this.parent.items.filter(x => x.type === 'feature');
}
diff --git a/module/data/item/ancestry.mjs b/module/data/item/ancestry.mjs
index ecffcb1b..6abdd334 100644
--- a/module/data/item/ancestry.mjs
+++ b/module/data/item/ancestry.mjs
@@ -19,10 +19,26 @@ export default class DHAncestry extends BaseDataItem {
};
}
+
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/family-tree.svg';
+
+ /* -------------------------------------------- */
+
+ /**
+ * Gets the primary feature.
+ * @type {foundry.documents.Item|null} Returns the item of the first feature with type "primary" or null if none is found.
+ */
get primaryFeature() {
return this.features.find(x => x.type === CONFIG.DH.ITEM.featureSubTypes.primary)?.item;
}
+ /**
+ * Gets the secondary feature.
+ * @type {foundry.documents.Item|null} Returns the item of the first feature with type "secondary" or null if none is found.
+ */
get secondaryFeature() {
return this.features.find(x => x.type === CONFIG.DH.ITEM.featureSubTypes.secondary)?.item;
}
diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs
index e8a6e35b..3aefc86f 100644
--- a/module/data/item/armor.mjs
+++ b/module/data/item/armor.mjs
@@ -42,12 +42,20 @@ export default class DHArmor extends AttachableItem {
};
}
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/chest-armor.svg';
+
+ /* -------------------------------------------- */
+
get customActions() {
return this.actions.filter(
action => !this.armorFeatures.some(feature => feature.actionIds.includes(action.id))
);
}
+ /**@inheritdoc */
async _preUpdate(changes, options, user) {
const allowed = await super._preUpdate(changes, options, user);
if (allowed === false) return false;
@@ -68,7 +76,7 @@ export default class DHArmor extends AttachableItem {
return acc;
}, {});
- for (var feature of added) {
+ for (const feature of added) {
const featureData = armorFeatures[feature.value];
if (featureData.effects?.length > 0) {
const embeddedItems = await this.parent.createEmbeddedDocuments(
diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs
index 1f55e878..4203f5cc 100644
--- a/module/data/item/base.mjs
+++ b/module/data/item/base.mjs
@@ -79,6 +79,16 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
return schema;
}
+ /* -------------------------------------------- */
+
+ /**
+ * The default icon used for newly created Item documents
+ * @type {string}
+ */
+ static DEFAULT_ICON = null;
+
+ /* -------------------------------------------- */
+
/**
* Convenient access to the item's actor, if it exists.
* @returns {foundry.documents.Actor | null}
diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs
index d17fbf82..4ebcfade 100644
--- a/module/data/item/beastform.mjs
+++ b/module/data/item/beastform.mjs
@@ -81,6 +81,13 @@ export default class DHBeastform extends BaseDataItem {
};
}
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/wolf-head.svg';
+
+ /* -------------------------------------------- */
+
async _preCreate() {
if (!this.actor) return;
diff --git a/module/data/item/class.mjs b/module/data/item/class.mjs
index 72f58b8b..45e8b4ab 100644
--- a/module/data/item/class.mjs
+++ b/module/data/item/class.mjs
@@ -53,6 +53,13 @@ export default class DHClass extends BaseDataItem {
};
}
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/laurel-crown.svg';
+
+ /* -------------------------------------------- */
+
get hopeFeatures() {
return this.features.filter(x => x.type === CONFIG.DH.ITEM.featureSubTypes.hope).map(x => x.item);
}
diff --git a/module/data/item/community.mjs b/module/data/item/community.mjs
index b2827242..a8000144 100644
--- a/module/data/item/community.mjs
+++ b/module/data/item/community.mjs
@@ -13,10 +13,15 @@ export default class DHCommunity extends BaseDataItem {
/** @inheritDoc */
static defineSchema() {
- const fields = foundry.data.fields;
return {
...super.defineSchema(),
features: new ForeignDocumentUUIDArrayField({ type: 'Item' })
};
}
+
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/village.svg';
+
}
diff --git a/module/data/item/consumable.mjs b/module/data/item/consumable.mjs
index cd192dfe..dad6a95c 100644
--- a/module/data/item/consumable.mjs
+++ b/module/data/item/consumable.mjs
@@ -22,4 +22,10 @@ export default class DHConsumable extends BaseDataItem {
consumeOnUse: new fields.BooleanField({ initial: false })
};
}
+
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/round-potion.svg';
+
}
diff --git a/module/data/item/domainCard.mjs b/module/data/item/domainCard.mjs
index 1dd89023..8d050158 100644
--- a/module/data/item/domainCard.mjs
+++ b/module/data/item/domainCard.mjs
@@ -33,6 +33,13 @@ export default class DHDomainCard extends BaseDataItem {
};
}
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/card-play.svg';
+
+ /* -------------------------------------------- */
+
/**@inheritdoc */
async _preCreate(data, options, user) {
const allowed = await super._preCreate(data, options, user);
diff --git a/module/data/item/feature.mjs b/module/data/item/feature.mjs
index 53e4d2d6..1ca32660 100644
--- a/module/data/item/feature.mjs
+++ b/module/data/item/feature.mjs
@@ -13,6 +13,13 @@ export default class DHFeature extends BaseDataItem {
});
}
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/stars-stack.svg';
+
+ /* -------------------------------------------- */
+
/** @inheritDoc */
static defineSchema() {
const fields = foundry.data.fields;
diff --git a/module/data/item/loot.mjs b/module/data/item/loot.mjs
index 2a23d338..cdb0855e 100644
--- a/module/data/item/loot.mjs
+++ b/module/data/item/loot.mjs
@@ -19,4 +19,11 @@ export default class DHLoot extends BaseDataItem {
...super.defineSchema()
};
}
+
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/open-treasure-chest.svg';
+
+ /* -------------------------------------------- */
}
diff --git a/module/data/item/subclass.mjs b/module/data/item/subclass.mjs
index 0a6685ab..735adb27 100644
--- a/module/data/item/subclass.mjs
+++ b/module/data/item/subclass.mjs
@@ -28,6 +28,13 @@ export default class DHSubclass extends BaseDataItem {
};
}
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/laurels.svg';
+
+ /* -------------------------------------------- */
+
get foundationFeatures() {
return this.features.filter(x => x.type === CONFIG.DH.ITEM.featureSubTypes.foundation).map(x => x.item);
}
diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs
index aab5a895..c0d88c2c 100644
--- a/module/data/item/weapon.mjs
+++ b/module/data/item/weapon.mjs
@@ -80,6 +80,13 @@ export default class DHWeapon extends AttachableItem {
};
}
+ /* -------------------------------------------- */
+
+ /**@override */
+ static DEFAULT_ICON = 'systems/daggerheart/assets/icons/documents/items/battered-axe.svg';
+
+ /* -------------------------------------------- */
+
get actionsList() {
return [this.attack, ...this.actions];
}
diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs
index 156e9f31..ce9ffc89 100644
--- a/module/documents/actor.mjs
+++ b/module/documents/actor.mjs
@@ -22,6 +22,23 @@ export default class DhpActor extends Actor {
return this.system.metadata.isNPC;
}
+ /* -------------------------------------------- */
+
+ /**@inheritdoc */
+ static getDefaultArtwork(actorData) {
+ const { type } = actorData;
+ const Model = CONFIG.Actor.dataModels[type];
+ const img = Model.DEFAULT_ICON ?? this.DEFAULT_ICON;
+ return {
+ img,
+ texture: {
+ src: img
+ }
+ };
+ }
+
+ /* -------------------------------------------- */
+
/** @inheritDoc */
getEmbeddedDocument(embeddedName, id, options) {
let doc;
@@ -39,6 +56,7 @@ export default class DhpActor extends Actor {
return doc;
}
+ /**@inheritdoc */
async _preCreate(data, options, user) {
if ((await super._preCreate(data, options, user)) === false) return false;
@@ -455,6 +473,7 @@ export default class DhpActor extends Actor {
return ActiveEffect.implementation.create(effect, { parent: this, keepId: true });
}
+ /**@inheritdoc */
getRollData() {
const rollData = super.getRollData();
rollData.system = this.system.getRollData();
@@ -540,8 +559,8 @@ export default class DhpActor extends Actor {
updates.forEach(
u =>
- (u.value =
- u.key === 'fear' || this.system?.resources?.[u.key]?.isReversed === false ? u.value * -1 : u.value)
+ (u.value =
+ u.key === 'fear' || this.system?.resources?.[u.key]?.isReversed === false ? u.value * -1 : u.value)
);
await this.modifyResource(updates);
@@ -587,9 +606,9 @@ export default class DhpActor extends Actor {
updates.forEach(
u =>
- (u.value = !(u.key === 'fear' || this.system?.resources?.[u.key]?.isReversed === false)
- ? u.value * -1
- : u.value)
+ (u.value = !(u.key === 'fear' || this.system?.resources?.[u.key]?.isReversed === false)
+ ? u.value * -1
+ : u.value)
);
await this.modifyResource(updates);
diff --git a/module/documents/item.mjs b/module/documents/item.mjs
index 5c7f7dfc..96d4596b 100644
--- a/module/documents/item.mjs
+++ b/module/documents/item.mjs
@@ -74,8 +74,8 @@ export default class DHItem extends foundry.documents.Item {
isInventoryItem === true
? 'Inventory Items' //TODO localize
: isInventoryItem === false
- ? 'Character Items' //TODO localize
- : 'Other'; //TODO localize
+ ? 'Character Items' //TODO localize
+ : 'Other'; //TODO localize
return { value: type, label, group };
}
@@ -118,6 +118,19 @@ export default class DHItem extends foundry.documents.Item {
return labels;
}
+ /* -------------------------------------------- */
+
+ /**@inheritdoc */
+ static getDefaultArtwork(itemData) {
+ const { type } = itemData;
+ const Model = CONFIG.Item.dataModels[type];
+ const img = Model.DEFAULT_ICON ?? this.DEFAULT_ICON;
+ return { img };
+ }
+
+ /* -------------------------------------------- */
+
+
async use(event) {
const actions = new Set(this.system.actionsList);
if (actions?.size) {
@@ -139,10 +152,10 @@ export default class DHItem extends foundry.documents.Item {
this.type === 'ancestry'
? game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.ancestryTitle')
: this.type === 'community'
- ? game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.communityTitle')
- : this.type === 'feature'
- ? game.i18n.localize('TYPES.Item.feature')
- : game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.subclassFeatureTitle'),
+ ? game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.communityTitle')
+ : this.type === 'feature'
+ ? game.i18n.localize('TYPES.Item.feature')
+ : game.i18n.localize('DAGGERHEART.UI.Chat.foundationCard.subclassFeatureTitle'),
origin: origin,
img: this.img,
item: {