diff --git a/src/assets/ui/thumbnail.webp b/src/assets/ui/thumbnail.webp new file mode 100644 index 00000000..952b9e38 Binary files /dev/null and b/src/assets/ui/thumbnail.webp differ diff --git a/src/lang/en.json b/src/lang/en.json index 979e0a93..fef11d5d 100644 --- a/src/lang/en.json +++ b/src/lang/en.json @@ -16,6 +16,7 @@ "language": "Language", "path": "Path", "profession": "Profession", + "relic": "Relic", "specialaction": "Special action", "spell": "Spell", "talent": "Talent", @@ -86,6 +87,7 @@ "DL.TabsTalents": "Talents", "DL.TabsMagic": "Magic", "DL.TabsItems": "Items", + "DL.TabsRelics": "Relics", "DL.TabsInventory": "Inventory", "DL.TabsBackground": "Background", "DL.TabsAttributes": "Attributes", @@ -315,6 +317,9 @@ "DL.ItemName": "Item name", "DL.ItemAmount": "Amount", "DL.ItemValue": "Price", + "DL.ItemAddRelic": "Add relic", + "DL.ItemEditRelic": "Edit relic", + "DL.ItemDeleteRelic": "Delete relic", "DL.ItemEnchantment": "Enchantment", "DL.ItemDamage": "Damage", "DL.ItemDefenseModifier": "Defense Modifier", diff --git a/src/lang/es.json b/src/lang/es.json index 5b4728e6..15818b0c 100644 --- a/src/lang/es.json +++ b/src/lang/es.json @@ -16,6 +16,7 @@ "language": "Idioma", "path": "Senda", "profession": "Profesión", + "relic": "Reliquia", "specialaction": "Acción Especial", "spell": "Conjuro", "talent": "Talento", @@ -86,6 +87,7 @@ "DL.TabsTalents": "Talentos", "DL.TabsMagic": "Magia", "DL.TabsItems": "Objetos", + "DL.TabsRelics": "Reliquias", "DL.TabsInventory": "Inventario", "DL.TabsBackground": "Trasfondo", "DL.TabsAttributes": "Atributos", @@ -312,6 +314,9 @@ "DL.ItemName": "Nombre del objeto", "DL.ItemAmount": "Cantidad", "DL.ItemValue": "Precio", + "DL.ItemAddRelic": "Añadir Reliquia", + "DL.ItemEditRelic": "Editar Reliquia", + "DL.ItemDeleteRelic": "Borrar Reliquia", "DL.ItemEnchantment": "Encantamiento", "DL.ItemDamage": "Daño", "DL.ItemDefenseModifier": "Modificador de Defensa", diff --git a/src/module/actor/actor.js b/src/module/actor/actor.js index dc087534..31a5f691 100644 --- a/src/module/actor/actor.js +++ b/src/module/actor/actor.js @@ -14,7 +14,7 @@ import { postSpellToChat, postTalentToChat, } from '../chat/roll-messages' -import {handleCreateAncestry, handleCreatePath, handleCreateRole } from '../item/nested-objects' +import {handleCreateAncestry, handleCreatePath, handleCreateRole, handleCreateRelic } from '../item/nested-objects' import {TokenManager} from '../pixi/token-manager' import {findAddEffect, findDeleteEffect} from "../demonlord"; @@ -186,7 +186,7 @@ export class DemonlordActor extends Actor { // Final armor computation system.characteristics.defense += system.bonuses.armor.defense system.characteristics.defense = system.bonuses.armor.override || system.characteristics.defense - for (let change of effectChanges.filter(e => e.key.includes("defense") && !e.key.startsWith("system.characteristics"))) { + for (let change of effectChanges.filter(e => e.key.includes("defense") && (this.type === 'character' ? e.key.startsWith("system.characteristics") : false))) { const result = change.effect.apply(this, change) if (result !== null) this.overrides[change.key] = result } @@ -252,6 +252,8 @@ export class DemonlordActor extends Actor { await handleCreatePath(this, doc) } else if (doc.type === 'creaturerole') { await handleCreateRole(this, doc) + } else if (doc.type === 'relic') { + await handleCreateRelic(this, doc) } await DLActiveEffects.embedActiveEffects(this, doc, 'create') diff --git a/src/module/actor/sheets/character-sheet.js b/src/module/actor/sheets/character-sheet.js index 9473a8da..2fc13219 100644 --- a/src/module/actor/sheets/character-sheet.js +++ b/src/module/actor/sheets/character-sheet.js @@ -62,6 +62,9 @@ export default class DLCharacterSheet extends DLBaseActorSheet { data.itemEffects = prepareActiveEffectCategories( this.actor.effects.filter(effect => effect.flags?.sourceType === 'creaturerole'), ) + data.itemEffects = prepareActiveEffectCategories( + this.actor.effects.filter(effect => effect.flags?.sourceType === 'relic'), + ) this.prepareItems(data) return data } @@ -74,6 +77,7 @@ export default class DLCharacterSheet extends DLBaseActorSheet { const m = sheetData._itemsByType const actorData = sheetData.actor actorData.gear = m.get('item') || [] + actorData.relics = m.get('relic') || [] actorData.armor = m.get('armor') || [] actorData.ammo = m.get('ammo') || [] actorData.ancestry = m.get('ancestry') || [] @@ -139,6 +143,14 @@ export default class DLCharacterSheet extends DLBaseActorSheet { else if (ev.button == 2) await role.delete({ parent: this.actor }) } + async _onRelicEdit(ev) { + const div = $(ev.currentTarget) + const role = this.actor.getEmbeddedDocument('Item', div.data('itemId')) + + if (ev.button == 0) role.sheet.render(true) + else if (ev.button == 2) await role.delete({ parent: this.actor }) + } + /* -------------------------------------------- */ async _updateObject(event, formData) { @@ -237,6 +249,9 @@ export default class DLCharacterSheet extends DLBaseActorSheet { // Role edit html.on('mousedown', '.role-edit', async ev => await this._onRoleEdit(ev)) + // Relic edit + html.on('mousedown', '.relic-edit', async ev => await this._onRelicEdit(ev)) + // Wealth edit html .find('.wealth-edit') diff --git a/src/module/actor/sheets/creature-sheet.js b/src/module/actor/sheets/creature-sheet.js index 6eafde8a..a84225f8 100644 --- a/src/module/actor/sheets/creature-sheet.js +++ b/src/module/actor/sheets/creature-sheet.js @@ -55,7 +55,7 @@ export default class DLCreatureSheet extends DLBaseActorSheet { /** @override */ async checkDroppedItem(itemData) { - if (['armor', 'ammo', 'ancestry', 'path', 'profession', 'item', 'language'].includes(itemData.type)) return false + if (['armor', 'ammo', 'ancestry', 'path', 'profession', 'item', 'language', 'relic'].includes(itemData.type)) return false return true } diff --git a/src/module/actor/sheets/vehicle-sheet.js b/src/module/actor/sheets/vehicle-sheet.js index 22fd3bfb..96b5e1cc 100644 --- a/src/module/actor/sheets/vehicle-sheet.js +++ b/src/module/actor/sheets/vehicle-sheet.js @@ -45,7 +45,7 @@ export default class DLVehicleSheet extends DLBaseActorSheet { /** @override */ async checkDroppedItem(itemData) { - if (['armor', 'ammo', 'ancestry', 'path', 'profession', 'item', 'language', 'creaturerole'].includes(itemData.type)) return false + if (['armor', 'ammo', 'ancestry', 'path', 'profession', 'item', 'language', 'creaturerole', 'relic'].includes(itemData.type)) return false return true } diff --git a/src/module/demonlord.js b/src/module/demonlord.js index 731c643f..eef0adaa 100644 --- a/src/module/demonlord.js +++ b/src/module/demonlord.js @@ -90,6 +90,7 @@ Hooks.once('init', async function () { 'weapon', 'armor', 'ammo', + 'relic', 'specialaction', 'endoftheround', 'profession', diff --git a/src/module/item/item.js b/src/module/item/item.js index 15ffed1d..c30d22fa 100644 --- a/src/module/item/item.js +++ b/src/module/item/item.js @@ -16,10 +16,10 @@ export class DemonlordItem extends Item { _onUpdate(changed, options, userId) { super._onUpdate(changed, options, userId) // Search for open path/ancestry/role sheets and re-render them. This allows the nested objects to fetch new values - if (!['path', 'ancestry', 'creaturerole', 'item'].includes(this.type)) { + if (!['path', 'ancestry', 'creaturerole', 'item', 'relic'].includes(this.type)) { // eslint-disable-next-line no-prototype-builtins let openSheets = Object.entries(ui.windows).map(i => i[1]).filter(i => Item.prototype.isPrototypeOf(i.object)) - openSheets = openSheets.filter(s => ['path', 'ancestry', 'creaturerole', 'item'].includes(s.object.type)) + openSheets = openSheets.filter(s => ['path', 'ancestry', 'creaturerole', 'item', 'relic'].includes(s.object.type)) openSheets.forEach(s => s.render()) } } @@ -53,7 +53,7 @@ export class DemonlordItem extends Item { } // Delete nested objects if ancestry, path or role - if (['ancestry', 'path', 'creaturerole'].includes(this.type)) await deleteActorNestedItems(this.parent, this.id, null) + if (['ancestry', 'path', 'creaturerole', 'relic'].includes(this.type)) await deleteActorNestedItems(this.parent, this.id, null) return await Promise.resolve() } diff --git a/src/module/item/nested-objects.js b/src/module/item/nested-objects.js index 922a5167..882df9d0 100644 --- a/src/module/item/nested-objects.js +++ b/src/module/item/nested-objects.js @@ -246,6 +246,15 @@ export async function handleCreateRole(actor, roleItem) { return await Promise.resolve() } +export async function handleCreateRelic(actor, relicItem) { + const relicData = relicItem.system + const talents = await Promise.all(relicData.contents.map(t => { + return fromUuid(t.uuid) + })) + await createActorNestedItems(actor, talents, relicItem.id) + return await Promise.resolve() +} + export async function handleLevelChange(actor, newLevel, curLevel = undefined) { curLevel = parseInt(curLevel ?? actor.system.level) newLevel = parseInt(newLevel) diff --git a/src/module/item/sheets/base-item-sheet.js b/src/module/item/sheets/base-item-sheet.js index 6b756a01..f3e7a310 100644 --- a/src/module/item/sheets/base-item-sheet.js +++ b/src/module/item/sheets/base-item-sheet.js @@ -361,7 +361,24 @@ export default class DLBaseItemSheet extends ItemSheet { if (itemData.type === 'Item') { let actor const item = await fromUuid(itemData.uuid) - if (!item || !['ammo', 'armor', 'item', 'weapon'].includes(item.type)) return + + let acceptedItemTypes = [] + + // Filter drops depending on the item type + switch (this.item.type) { + case 'item': + acceptedItemTypes = ['ammo', 'armor', 'item', 'weapon'] + break + case 'relic': + acceptedItemTypes = ['talent'] + break + default: + acceptedItemTypes = [] + break + } + + if (!item && !acceptedItemTypes.includes(item.type)) return + const itemUpdate = {'_id': item._id} if (itemData.uuid.startsWith('Actor.')) { actor = item.parent diff --git a/src/system.json b/src/system.json index 60676739..5572297f 100644 --- a/src/system.json +++ b/src/system.json @@ -18,6 +18,7 @@ "name": "Ferrer" } ], + "background": "systems/demonlord/assets/ui/thumbnail.webp", "compatibility": { "minimum": 11, "verified": 11 diff --git a/src/template.json b/src/template.json index e223cc6b..7b328a8d 100644 --- a/src/template.json +++ b/src/template.json @@ -166,6 +166,7 @@ "language", "path", "profession", + "relic", "specialaction", "spell", "talent", @@ -254,6 +255,9 @@ "feature": { "templates": ["base"] }, + "relic": { + "templates": ["base", "container"] + }, "spell": { "tradition": "", "edit": false, diff --git a/src/templates/item/item-relic-sheet.hbs b/src/templates/item/item-relic-sheet.hbs new file mode 100644 index 00000000..ce0dde8f --- /dev/null +++ b/src/templates/item/item-relic-sheet.hbs @@ -0,0 +1,86 @@ +
+ {{> "systems/demonlord/templates/item/partial/item-sheet-header.hbs" item=item placeholderName="Relic Name"}} + + {{!-- Sheet Tab Navigation --}} + + + {{!-- Sheet Body --}} +
+
+ {{!-- Attributes Tab --}} +
+ +
+
+ {{item.name}} +
+
+
+ +
+
+ {{localize "DL.SpellRequirements"}} +
+ {{dlDropdownValue "system.requirement.attribute" system.requirement.attribute "system.requirement.minvalue" system.requirement.minvalue }} +
+
+
+
+ + {{#if system.description}} +
+
{{localize "DL.TabsDescription"}}
+
+ {{{system.enrichedDescription}}} +
+
+
+ {{/if}} + + {{#if system.contents}} +
+
+
{{localize "DL.TabsEffects"}}
+
+ {{#each item.system.contents as |content index|}} +
+
+
+ + +
+ {{localize "DL.ItemShowInfo"}} +
+
+
+ + + +
+
+ {{#if content.system.description}} + + {{/if}} +
+ {{/each}} +
+
+ {{/if}} +
+ + {{> "systems/demonlord/templates/item/partial/item-description.hbs"}} + + {{#if effects}}{{> "systems/demonlord/templates/item/partial/item-effects.hbs"}}{{/if}} +
+
+
diff --git a/src/templates/tabs/item.hbs b/src/templates/tabs/item.hbs index a5aeab2f..06d6189b 100644 --- a/src/templates/tabs/item.hbs +++ b/src/templates/tabs/item.hbs @@ -96,3 +96,39 @@ {{/if}} {{/each}} + + +
+
{{localize "DL.TabsRelics"}}
+
+ +
+
+ +{{#each actor.relics as |item id|}} +
+
+
+ + +
+ {{localize "DL.ItemShowInfo"}} +
+
+
+ + + +
+
+ {{#if item.system.description}} + + {{/if}} +
+{{/each}}