mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-17 15:39:02 +01:00
Merge branch 'Foundryborne:main' into iss4-attach-items
This commit is contained in:
commit
4d80c2fcf1
13 changed files with 202 additions and 4666 deletions
|
|
@ -120,6 +120,7 @@ Hooks.once('init', () => {
|
||||||
CONFIG.ChatMessage.documentClass = documents.DhChatMessage;
|
CONFIG.ChatMessage.documentClass = documents.DhChatMessage;
|
||||||
|
|
||||||
CONFIG.Canvas.rulerClass = placeables.DhRuler;
|
CONFIG.Canvas.rulerClass = placeables.DhRuler;
|
||||||
|
CONFIG.Canvas.layers.templates.layerClass = placeables.DhTemplateLayer;
|
||||||
CONFIG.Combat.documentClass = documents.DhpCombat;
|
CONFIG.Combat.documentClass = documents.DhpCombat;
|
||||||
CONFIG.ui.combat = applications.ui.DhCombatTracker;
|
CONFIG.ui.combat = applications.ui.DhCombatTracker;
|
||||||
CONFIG.ui.chat = applications.ui.DhChatLog;
|
CONFIG.ui.chat = applications.ui.DhChatLog;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@
|
||||||
"environment": "Environment"
|
"environment": "Environment"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTROLS": {
|
||||||
|
"inFront": "In Front"
|
||||||
|
},
|
||||||
"DAGGERHEART": {
|
"DAGGERHEART": {
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"Config": {
|
"Config": {
|
||||||
|
|
@ -107,7 +110,8 @@
|
||||||
"sendToChat": "Send To Chat",
|
"sendToChat": "Send To Chat",
|
||||||
"toLoadout": "Send to Loadout",
|
"toLoadout": "Send to Loadout",
|
||||||
"toVault": "Send to Vault",
|
"toVault": "Send to Vault",
|
||||||
"unequip": "Unequip"
|
"unequip": "Unequip",
|
||||||
|
"useItem": "Use Item"
|
||||||
},
|
},
|
||||||
"faith": "Faith",
|
"faith": "Faith",
|
||||||
"levelUp": "You can level up",
|
"levelUp": "You can level up",
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
||||||
context.tabs.advancements.progress = { selected: selections, max: currentLevel.maxSelections };
|
context.tabs.advancements.progress = { selected: selections, max: currentLevel.maxSelections };
|
||||||
context.showTabs = this.tabGroups.primary !== 'summary';
|
context.showTabs = this.tabGroups.primary !== 'summary';
|
||||||
break;
|
break;
|
||||||
const { current: currentActorLevel, changed: changedActorLevel } = this.actor.system.levelData.level;
|
|
||||||
const actorArmor = this.actor.system.armor;
|
const actorArmor = this.actor.system.armor;
|
||||||
const levelKeys = Object.keys(this.levelup.levels);
|
const levelKeys = Object.keys(this.levelup.levels);
|
||||||
let achivementProficiency = 0;
|
let achivementProficiency = 0;
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.Sheets.PC.ContextMenu.UseItem',
|
name: 'DAGGERHEART.ACTORS.Character.contextMenu.useItem',
|
||||||
icon: '<i class="fa-solid fa-burst"></i>',
|
icon: '<i class="fa-solid fa-burst"></i>',
|
||||||
condition: el => {
|
condition: el => {
|
||||||
const item = getItem(el);
|
const item = getItem(el);
|
||||||
|
|
@ -216,7 +216,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
callback: (button, event) => CharacterSheet.useItem.call(this, event, button)
|
callback: (button, event) => CharacterSheet.useItem.call(this, event, button)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.Sheets.PC.ContextMenu.Equip',
|
name: 'DAGGERHEART.ACTORS.Character.contextMenu.equip',
|
||||||
icon: '<i class="fa-solid fa-hands"></i>',
|
icon: '<i class="fa-solid fa-hands"></i>',
|
||||||
condition: el => {
|
condition: el => {
|
||||||
const item = getItem(el);
|
const item = getItem(el);
|
||||||
|
|
@ -225,7 +225,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
callback: CharacterSheet.#toggleEquipItem.bind(this)
|
callback: CharacterSheet.#toggleEquipItem.bind(this)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.Sheets.PC.ContextMenu.Unequip',
|
name: 'DAGGERHEART.ACTORS.Character.contextMenu.unequip',
|
||||||
icon: '<i class="fa-solid fa-hands"></i>',
|
icon: '<i class="fa-solid fa-hands"></i>',
|
||||||
condition: el => {
|
condition: el => {
|
||||||
const item = getItem(el);
|
const item = getItem(el);
|
||||||
|
|
@ -234,7 +234,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
callback: CharacterSheet.#toggleEquipItem.bind(this)
|
callback: CharacterSheet.#toggleEquipItem.bind(this)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.Sheets.PC.ContextMenu.ToLoadout',
|
name: 'DAGGERHEART.ACTORS.Character.contextMenu.toLoadout',
|
||||||
icon: '<i class="fa-solid fa-arrow-up"></i>',
|
icon: '<i class="fa-solid fa-arrow-up"></i>',
|
||||||
condition: el => {
|
condition: el => {
|
||||||
const item = getItem(el);
|
const item = getItem(el);
|
||||||
|
|
@ -243,7 +243,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
callback: target => getItem(target).update({ 'system.inVault': false })
|
callback: target => getItem(target).update({ 'system.inVault': false })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.Sheets.PC.ContextMenu.ToVault',
|
name: 'DAGGERHEART.ACTORS.Character.contextMenu.toVault',
|
||||||
icon: '<i class="fa-solid fa-arrow-down"></i>',
|
icon: '<i class="fa-solid fa-arrow-down"></i>',
|
||||||
condition: el => {
|
condition: el => {
|
||||||
const item = getItem(el);
|
const item = getItem(el);
|
||||||
|
|
@ -252,17 +252,17 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
callback: target => getItem(target).update({ 'system.inVault': true })
|
callback: target => getItem(target).update({ 'system.inVault': true })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.Sheets.PC.ContextMenu.SendToChat',
|
name: 'DAGGERHEART.ACTORS.Character.contextMenu.sendToChat',
|
||||||
icon: '<i class="fa-regular fa-message"></i>',
|
icon: '<i class="fa-regular fa-message"></i>',
|
||||||
callback: CharacterSheet.toChat.bind(this)
|
callback: CharacterSheet.toChat.bind(this)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.Sheets.PC.ContextMenu.Edit',
|
name: 'CONTROLS.CommonEdit',
|
||||||
icon: '<i class="fa-solid fa-pen-to-square"></i>',
|
icon: '<i class="fa-solid fa-pen-to-square"></i>',
|
||||||
callback: target => getItem(target).sheet.render({ force: true })
|
callback: target => getItem(target).sheet.render({ force: true })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.Sheets.PC.ContextMenu.Delete',
|
name: 'CONTROLS.CommonDelete',
|
||||||
icon: '<i class="fa-solid fa-trash"></i>',
|
icon: '<i class="fa-solid fa-trash"></i>',
|
||||||
callback: async el => {
|
callback: async el => {
|
||||||
const item = getItem(el);
|
const item = getItem(el);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
export { default as DhMeasuredTemplate } from './measuredTemplate.mjs';
|
export { default as DhMeasuredTemplate } from './measuredTemplate.mjs';
|
||||||
export { default as DhRuler } from './ruler.mjs';
|
export { default as DhRuler } from './ruler.mjs';
|
||||||
|
export { default as DhTemplateLayer } from './templateLayer.mjs';
|
||||||
export { default as DhTokenRuler } from './tokenRuler.mjs';
|
export { default as DhTokenRuler } from './tokenRuler.mjs';
|
||||||
|
|
|
||||||
116
module/canvas/placeables/templateLayer.mjs
Normal file
116
module/canvas/placeables/templateLayer.mjs
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
export default class DhTemplateLayer extends foundry.canvas.layers.TemplateLayer {
|
||||||
|
static prepareSceneControls() {
|
||||||
|
const sc = foundry.applications.ui.SceneControls;
|
||||||
|
return {
|
||||||
|
name: 'templates',
|
||||||
|
order: 2,
|
||||||
|
title: 'CONTROLS.GroupMeasure',
|
||||||
|
icon: 'fa-solid fa-ruler-combined',
|
||||||
|
visible: game.user.can('TEMPLATE_CREATE'),
|
||||||
|
onChange: (event, active) => {
|
||||||
|
if (active) canvas.templates.activate();
|
||||||
|
},
|
||||||
|
onToolChange: () => canvas.templates.setAllRenderFlags({ refreshState: true }),
|
||||||
|
tools: {
|
||||||
|
circle: {
|
||||||
|
name: 'circle',
|
||||||
|
order: 1,
|
||||||
|
title: 'CONTROLS.MeasureCircle',
|
||||||
|
icon: 'fa-regular fa-circle',
|
||||||
|
toolclip: {
|
||||||
|
src: 'toolclips/tools/measure-circle.webm',
|
||||||
|
heading: 'CONTROLS.MeasureCircle',
|
||||||
|
items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete'])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cone: {
|
||||||
|
name: 'cone',
|
||||||
|
order: 2,
|
||||||
|
title: 'CONTROLS.MeasureCone',
|
||||||
|
icon: 'fa-solid fa-angle-left',
|
||||||
|
toolclip: {
|
||||||
|
src: 'toolclips/tools/measure-cone.webm',
|
||||||
|
heading: 'CONTROLS.MeasureCone',
|
||||||
|
items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete', 'rotate'])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inFront: {
|
||||||
|
name: 'inFront',
|
||||||
|
order: 3,
|
||||||
|
title: 'CONTROLS.inFront',
|
||||||
|
icon: 'fa-solid fa-eye',
|
||||||
|
toolclip: {
|
||||||
|
src: 'toolclips/tools/measure-cone.webm',
|
||||||
|
heading: 'CONTROLS.inFront',
|
||||||
|
items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete', 'rotate'])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rect: {
|
||||||
|
name: 'rect',
|
||||||
|
order: 4,
|
||||||
|
title: 'CONTROLS.MeasureRect',
|
||||||
|
icon: 'fa-regular fa-square',
|
||||||
|
toolclip: {
|
||||||
|
src: 'toolclips/tools/measure-rect.webm',
|
||||||
|
heading: 'CONTROLS.MeasureRect',
|
||||||
|
items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete', 'rotate'])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ray: {
|
||||||
|
name: 'ray',
|
||||||
|
order: 5,
|
||||||
|
title: 'CONTROLS.MeasureRay',
|
||||||
|
icon: 'fa-solid fa-up-down',
|
||||||
|
toolclip: {
|
||||||
|
src: 'toolclips/tools/measure-ray.webm',
|
||||||
|
heading: 'CONTROLS.MeasureRay',
|
||||||
|
items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete', 'rotate'])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clear: {
|
||||||
|
name: 'clear',
|
||||||
|
order: 6,
|
||||||
|
title: 'CONTROLS.MeasureClear',
|
||||||
|
icon: 'fa-solid fa-trash',
|
||||||
|
visible: game.user.isGM,
|
||||||
|
onChange: () => canvas.templates.deleteAll(),
|
||||||
|
button: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
activeTool: 'circle'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDragLeftStart(event) {
|
||||||
|
const interaction = event.interactionData;
|
||||||
|
|
||||||
|
// Snap the origin to the grid
|
||||||
|
if (!event.shiftKey) interaction.origin = this.getSnappedPoint(interaction.origin);
|
||||||
|
|
||||||
|
// Create a pending MeasuredTemplateDocument
|
||||||
|
const tool = game.activeTool === 'inFront' ? 'cone' : game.activeTool;
|
||||||
|
const previewData = {
|
||||||
|
user: game.user.id,
|
||||||
|
t: tool,
|
||||||
|
x: interaction.origin.x,
|
||||||
|
y: interaction.origin.y,
|
||||||
|
sort: Math.max(this.getMaxSort() + 1, 0),
|
||||||
|
distance: 1,
|
||||||
|
direction: 0,
|
||||||
|
fillColor: game.user.color || '#FF0000',
|
||||||
|
hidden: event.altKey
|
||||||
|
};
|
||||||
|
const defaults = CONFIG.MeasuredTemplate.defaults;
|
||||||
|
if (game.activeTool === 'cone') previewData.angle = defaults.angle;
|
||||||
|
else if (game.activeTool === 'inFront') previewData.angle = 180;
|
||||||
|
else if (game.activeTool === 'ray') previewData.width = defaults.width * canvas.dimensions.distance;
|
||||||
|
const cls = foundry.utils.getDocumentClass('MeasuredTemplate');
|
||||||
|
const doc = new cls(previewData, { parent: canvas.scene });
|
||||||
|
|
||||||
|
// Create a preview MeasuredTemplate object
|
||||||
|
const template = new this.constructor.placeableClass(doc);
|
||||||
|
doc._object = template;
|
||||||
|
interaction.preview = this.preview.addChild(template);
|
||||||
|
template.draw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { burden } from '../../config/generalConfig.mjs';
|
import { burden } from '../../config/generalConfig.mjs';
|
||||||
import ActionField from '../fields/actionField.mjs';
|
|
||||||
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
|
||||||
import DhLevelData from '../levelData.mjs';
|
import DhLevelData from '../levelData.mjs';
|
||||||
import BaseDataActor from './base.mjs';
|
import BaseDataActor from './base.mjs';
|
||||||
|
|
@ -29,7 +28,7 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
return foundry.utils.mergeObject(super.metadata, {
|
return foundry.utils.mergeObject(super.metadata, {
|
||||||
label: 'TYPES.Actor.character',
|
label: 'TYPES.Actor.character',
|
||||||
type: 'character',
|
type: 'character',
|
||||||
isNPC: false,
|
isNPC: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,12 @@ export default class DhLevelData extends foundry.abstract.DataModel {
|
||||||
data: new fields.ArrayField(new fields.StringField({ required: true })),
|
data: new fields.ArrayField(new fields.StringField({ required: true })),
|
||||||
secondaryData: new fields.TypedObjectField(new fields.StringField({ required: true })),
|
secondaryData: new fields.TypedObjectField(new fields.StringField({ required: true })),
|
||||||
itemUuid: new fields.DocumentUUIDField({ required: true }),
|
itemUuid: new fields.DocumentUUIDField({ required: true }),
|
||||||
featureIds: new fields.ArrayField(new fields.StringField())
|
features: new fields.ArrayField(
|
||||||
|
new fields.SchemaField({
|
||||||
|
onPartner: new fields.BooleanField(),
|
||||||
|
id: new fields.StringField()
|
||||||
|
})
|
||||||
|
)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
@ -51,10 +56,6 @@ export default class DhLevelData extends foundry.abstract.DataModel {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get actions() {
|
|
||||||
return Object.values(this.levelups).flatMap(level => level.selections.flatMap(s => s.actions));
|
|
||||||
}
|
|
||||||
|
|
||||||
get canLevelUp() {
|
get canLevelUp() {
|
||||||
return this.level.current < this.level.changed;
|
return this.level.current < this.level.changed;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,8 @@ export const CompanionLevelOptionType = {
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.APPLICATIONS.Levelup.actions.creatureComfort.name',
|
name: 'DAGGERHEART.APPLICATIONS.Levelup.actions.creatureComfort.name',
|
||||||
img: 'icons/magic/life/heart-cross-purple-orange.webp',
|
img: 'icons/magic/life/heart-cross-purple-orange.webp',
|
||||||
description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.creatureComfort.description'
|
description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.creatureComfort.description',
|
||||||
|
toPartner: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -81,7 +82,8 @@ export const CompanionLevelOptionType = {
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.APPLICATIONS.Levelup.actions.armored.name',
|
name: 'DAGGERHEART.APPLICATIONS.Levelup.actions.armored.name',
|
||||||
img: 'icons/equipment/shield/kite-wooden-oak-glow.webp',
|
img: 'icons/equipment/shield/kite-wooden-oak-glow.webp',
|
||||||
description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.armored.description'
|
description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.armored.description',
|
||||||
|
toPartner: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -100,7 +102,8 @@ export const CompanionLevelOptionType = {
|
||||||
{
|
{
|
||||||
name: 'DAGGERHEART.APPLICATIONS.Levelup.actions.bonded.name',
|
name: 'DAGGERHEART.APPLICATIONS.Levelup.actions.bonded.name',
|
||||||
img: 'icons/magic/life/heart-red-blue.webp',
|
img: 'icons/magic/life/heart-red-blue.webp',
|
||||||
description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.bonded.description'
|
description: 'DAGGERHEART.APPLICATIONS.Levelup.actions.bonded.description',
|
||||||
|
toPartner: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,7 @@ export default class DHRoll extends Roll {
|
||||||
export const registerRollDiceHooks = () => {
|
export const registerRollDiceHooks = () => {
|
||||||
Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async (config, message) => {
|
Hooks.on(`${CONFIG.DH.id}.postRollDuality`, async (config, message) => {
|
||||||
if (
|
if (
|
||||||
|
!config.source?.actor ||
|
||||||
!game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).hope ||
|
!game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).hope ||
|
||||||
config.roll.type === 'reaction'
|
config.roll.type === 'reaction'
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ import { LevelOptionType } from '../data/levelTier.mjs';
|
||||||
import DHFeature from '../data/item/feature.mjs';
|
import DHFeature from '../data/item/feature.mjs';
|
||||||
|
|
||||||
export default class DhpActor extends Actor {
|
export default class DhpActor extends Actor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the first Actor active owner.
|
* Return the first Actor active owner.
|
||||||
*/
|
*/
|
||||||
get owner() {
|
get owner() {
|
||||||
const user = this.hasPlayerOwner && game.users.players.find(u => this.testUserPermission(u, "OWNER") && u.active);;
|
const user =
|
||||||
if(!user) return game.user.isGM ? game.user : null;
|
this.hasPlayerOwner && game.users.players.find(u => this.testUserPermission(u, 'OWNER') && u.active);
|
||||||
|
if (!user) return game.user.isGM ? game.user : null;
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ export default class DhpActor extends Actor {
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const featureIds = [];
|
const features = [];
|
||||||
const domainCards = [];
|
const domainCards = [];
|
||||||
const experiences = [];
|
const experiences = [];
|
||||||
const subclassFeatureState = { class: null, multiclass: null };
|
const subclassFeatureState = { class: null, multiclass: null };
|
||||||
|
|
@ -74,7 +74,7 @@ export default class DhpActor extends Actor {
|
||||||
const advancementCards = level.selections.filter(x => x.type === 'domainCard').map(x => x.itemUuid);
|
const advancementCards = level.selections.filter(x => x.type === 'domainCard').map(x => x.itemUuid);
|
||||||
domainCards.push(...achievementCards, ...advancementCards);
|
domainCards.push(...achievementCards, ...advancementCards);
|
||||||
experiences.push(...Object.keys(level.achievements.experiences));
|
experiences.push(...Object.keys(level.achievements.experiences));
|
||||||
featureIds.push(...level.selections.flatMap(x => x.featureIds));
|
features.push(...level.selections.flatMap(x => x.features));
|
||||||
|
|
||||||
const subclass = level.selections.find(x => x.type === 'subclass');
|
const subclass = level.selections.find(x => x.type === 'subclass');
|
||||||
if (subclass) {
|
if (subclass) {
|
||||||
|
|
@ -88,8 +88,11 @@ export default class DhpActor extends Actor {
|
||||||
multiclass = level.selections.find(x => x.type === 'multiclass');
|
multiclass = level.selections.find(x => x.type === 'multiclass');
|
||||||
});
|
});
|
||||||
|
|
||||||
for (let featureId of featureIds) {
|
for (let feature of features) {
|
||||||
this.items.get(featureId).delete();
|
if (feature.onPartner && !this.system.partner) continue;
|
||||||
|
|
||||||
|
const document = feature.onPartner ? this.system.partner : this;
|
||||||
|
document.items.get(feature.id)?.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (experiences.length > 0) {
|
if (experiences.length > 0) {
|
||||||
|
|
@ -153,7 +156,6 @@ export default class DhpActor extends Actor {
|
||||||
}
|
}
|
||||||
|
|
||||||
async levelUp(levelupData) {
|
async levelUp(levelupData) {
|
||||||
const actions = [];
|
|
||||||
const levelups = {};
|
const levelups = {};
|
||||||
for (var levelKey of Object.keys(levelupData)) {
|
for (var levelKey of Object.keys(levelupData)) {
|
||||||
const level = levelupData[levelKey];
|
const level = levelupData[levelKey];
|
||||||
|
|
@ -237,7 +239,9 @@ export default class DhpActor extends Actor {
|
||||||
...featureData,
|
...featureData,
|
||||||
description: game.i18n.localize(featureData.description)
|
description: game.i18n.localize(featureData.description)
|
||||||
});
|
});
|
||||||
const embeddedItem = await this.createEmbeddedDocuments('Item', [
|
|
||||||
|
const document = featureData.toPartner && this.system.partner ? this.system.partner : this;
|
||||||
|
const embeddedItem = await document.createEmbeddedDocuments('Item', [
|
||||||
{
|
{
|
||||||
...featureData,
|
...featureData,
|
||||||
name: game.i18n.localize(featureData.name),
|
name: game.i18n.localize(featureData.name),
|
||||||
|
|
@ -245,9 +249,13 @@ export default class DhpActor extends Actor {
|
||||||
system: feature
|
system: feature
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
addition.checkbox.featureIds = !addition.checkbox.featureIds
|
const newFeature = {
|
||||||
? [embeddedItem[0].id]
|
onPartner: Boolean(featureData.toPartner && this.system.partner),
|
||||||
: [...addition.checkbox.featureIds, embeddedItem[0].id];
|
id: embeddedItem[0].id
|
||||||
|
};
|
||||||
|
addition.checkbox.features = !addition.checkbox.features
|
||||||
|
? [newFeature]
|
||||||
|
: [...addition.checkbox.features, newFeature];
|
||||||
}
|
}
|
||||||
|
|
||||||
selections.push(addition.checkbox);
|
selections.push(addition.checkbox);
|
||||||
|
|
@ -317,7 +325,6 @@ export default class DhpActor extends Actor {
|
||||||
|
|
||||||
await this.update({
|
await this.update({
|
||||||
system: {
|
system: {
|
||||||
actions: [...this.system.actions, ...actions],
|
|
||||||
levelData: {
|
levelData: {
|
||||||
level: {
|
level: {
|
||||||
current: this.system.levelData.level.changed
|
current: this.system.levelData.level.changed
|
||||||
|
|
@ -369,16 +376,16 @@ export default class DhpActor extends Actor {
|
||||||
const modifier = roll.modifier !== null ? Number.parseInt(roll.modifier) : null;
|
const modifier = roll.modifier !== null ? Number.parseInt(roll.modifier) : null;
|
||||||
return modifier !== null
|
return modifier !== null
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
value: modifier,
|
value: modifier,
|
||||||
label: roll.label
|
label: roll.label
|
||||||
? modifier >= 0
|
? modifier >= 0
|
||||||
? `${roll.label} +${modifier}`
|
? `${roll.label} +${modifier}`
|
||||||
: `${roll.label} ${modifier}`
|
: `${roll.label} ${modifier}`
|
||||||
: null,
|
: null,
|
||||||
title: roll.label
|
title: roll.label
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -460,7 +467,7 @@ export default class DhpActor extends Actor {
|
||||||
|
|
||||||
if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null;
|
if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null;
|
||||||
|
|
||||||
if(!hpDamage) return;
|
if (!hpDamage) return;
|
||||||
|
|
||||||
const updates = [{ value: hpDamage, type: 'hitPoints' }];
|
const updates = [{ value: hpDamage, type: 'hitPoints' }];
|
||||||
|
|
||||||
|
|
@ -469,8 +476,8 @@ export default class DhpActor extends Actor {
|
||||||
this.system.armor &&
|
this.system.armor &&
|
||||||
this.system.armor.system.marks.value < this.system.armorScore
|
this.system.armor.system.marks.value < this.system.armorScore
|
||||||
) {
|
) {
|
||||||
const armorStackResult = await this.owner.query('armorStack', {actorId: this.uuid, damage: hpDamage});
|
const armorStackResult = await this.owner.query('armorStack', { actorId: this.uuid, damage: hpDamage });
|
||||||
if(armorStackResult) {
|
if (armorStackResult) {
|
||||||
const { modifiedDamage, armorSpent, stressSpent } = armorStackResult;
|
const { modifiedDamage, armorSpent, stressSpent } = armorStackResult;
|
||||||
updates.find(u => u.type === 'hitPoints').value = modifiedDamage;
|
updates.find(u => u.type === 'hitPoints').value = modifiedDamage;
|
||||||
updates.push(
|
updates.push(
|
||||||
|
|
@ -493,7 +500,7 @@ export default class DhpActor extends Actor {
|
||||||
async modifyResource(resources) {
|
async modifyResource(resources) {
|
||||||
if (!resources.length) return;
|
if (!resources.length) return;
|
||||||
|
|
||||||
if(resources.find(r => r.type === 'stress')) this.convertStressDamageToHP(resources);
|
if (resources.find(r => r.type === 'stress')) this.convertStressDamageToHP(resources);
|
||||||
let updates = { actor: { target: this, resources: {} }, armor: { target: this.system.armor, resources: {} } };
|
let updates = { actor: { target: this, resources: {} }, armor: { target: this.system.armor, resources: {} } };
|
||||||
resources.forEach(r => {
|
resources.forEach(r => {
|
||||||
switch (r.type) {
|
switch (r.type) {
|
||||||
|
|
@ -521,7 +528,12 @@ export default class DhpActor extends Actor {
|
||||||
});
|
});
|
||||||
Object.values(updates).forEach(async u => {
|
Object.values(updates).forEach(async u => {
|
||||||
if (Object.keys(u.resources).length > 0) {
|
if (Object.keys(u.resources).length > 0) {
|
||||||
await emitAsGM(GMUpdateEvent.UpdateDocument, u.target.update.bind(u.target), u.resources, u.target.uuid);
|
await emitAsGM(
|
||||||
|
GMUpdateEvent.UpdateDocument,
|
||||||
|
u.target.update.bind(u.target),
|
||||||
|
u.resources,
|
||||||
|
u.target.uuid
|
||||||
|
);
|
||||||
/* if (game.user.isGM) {
|
/* if (game.user.isGM) {
|
||||||
await u.target.update(u.resources);
|
await u.target.update(u.resources);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -540,27 +552,28 @@ export default class DhpActor extends Actor {
|
||||||
|
|
||||||
convertDamageToThreshold(damage) {
|
convertDamageToThreshold(damage) {
|
||||||
return damage >= this.system.damageThresholds.severe
|
return damage >= this.system.damageThresholds.severe
|
||||||
? 3
|
? 3
|
||||||
: damage >= this.system.damageThresholds.major
|
: damage >= this.system.damageThresholds.major
|
||||||
? 2
|
? 2
|
||||||
: damage >= this.system.damageThresholds.minor
|
: damage >= this.system.damageThresholds.minor
|
||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
convertStressDamageToHP(resources) {
|
convertStressDamageToHP(resources) {
|
||||||
const stressDamage = resources.find(r => r.type === 'stress'),
|
const stressDamage = resources.find(r => r.type === 'stress'),
|
||||||
newValue = this.system.resources.stress.value + stressDamage.value;
|
newValue = this.system.resources.stress.value + stressDamage.value;
|
||||||
if(newValue <= this.system.resources.stress.maxTotal) return;
|
if (newValue <= this.system.resources.stress.maxTotal) return;
|
||||||
const hpDamage = resources.find(r => r.type === 'hitPoints');
|
const hpDamage = resources.find(r => r.type === 'hitPoints');
|
||||||
if(hpDamage) hpDamage.value++;
|
if (hpDamage) hpDamage.value++;
|
||||||
else resources.push({
|
else
|
||||||
type: 'hitPoints',
|
resources.push({
|
||||||
value: 1
|
type: 'hitPoints',
|
||||||
})
|
value: 1
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const registerDHActorHooks = () => {
|
export const registerDHActorHooks = () => {
|
||||||
CONFIG.queries.armorStack = DamageReductionDialog.armorStackQuery;
|
CONFIG.queries.armorStack = DamageReductionDialog.armorStackQuery;
|
||||||
}
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
export default class DhTooltipManager extends foundry.helpers.interaction.TooltipManager {
|
export default class DhTooltipManager extends foundry.helpers.interaction.TooltipManager {
|
||||||
async activate(element, options = {}) {
|
async activate(element, options = {}) {
|
||||||
let html = options.html;
|
let html = options.html;
|
||||||
if (element.dataset.tooltip.startsWith('#item#')) {
|
if (element.dataset.tooltip?.startsWith('#item#')) {
|
||||||
const item = await foundry.utils.fromUuid(element.dataset.tooltip.slice(6));
|
const item = await foundry.utils.fromUuid(element.dataset.tooltip.slice(6));
|
||||||
if (item) {
|
if (item) {
|
||||||
html = await foundry.applications.handlebars.renderTemplate(
|
html = await foundry.applications.handlebars.renderTemplate(
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue