mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-04-25 00:43:38 +02:00
Compare commits
4 commits
04befd2e4e
...
16d839a881
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16d839a881 | ||
|
|
57548b4cc4 | ||
|
|
8d71887924 | ||
|
|
98cf6fa6de |
17 changed files with 256 additions and 160 deletions
|
|
@ -10,7 +10,7 @@ import { enricherConfig, enricherRenderSetup } from './module/enrichers/_module.
|
||||||
import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs';
|
import { getCommandTarget, rollCommandToJSON } from './module/helpers/utils.mjs';
|
||||||
import { BaseRoll, DHRoll, DualityRoll, D20Roll, DamageRoll, FateRoll } from './module/dice/_module.mjs';
|
import { BaseRoll, DHRoll, DualityRoll, D20Roll, DamageRoll, FateRoll } from './module/dice/_module.mjs';
|
||||||
import { enrichedDualityRoll } from './module/enrichers/DualityRollEnricher.mjs';
|
import { enrichedDualityRoll } from './module/enrichers/DualityRollEnricher.mjs';
|
||||||
import { enrichedFateRoll, getFateType } from './module/enrichers/FateRollEnricher.mjs';
|
import { enrichedFateRoll, getFateTypeData } from './module/enrichers/FateRollEnricher.mjs';
|
||||||
import {
|
import {
|
||||||
handlebarsRegistration,
|
handlebarsRegistration,
|
||||||
runMigrations,
|
runMigrations,
|
||||||
|
|
@ -322,29 +322,26 @@ Hooks.on('chatMessage', (_, message) => {
|
||||||
if (message.startsWith('/fr')) {
|
if (message.startsWith('/fr')) {
|
||||||
const result =
|
const result =
|
||||||
message.trim().toLowerCase() === '/fr' ? { result: {} } : rollCommandToJSON(message.replace(/\/fr\s?/, ''));
|
message.trim().toLowerCase() === '/fr' ? { result: {} } : rollCommandToJSON(message.replace(/\/fr\s?/, ''));
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateParsing'));
|
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateParsing'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { result: rollCommand, flavor } = result;
|
const { result: rollCommand, flavor } = result;
|
||||||
|
const fateTypeData = getFateTypeData(rollCommand?.type);
|
||||||
|
|
||||||
const fateTypeFromRollCommand = getFateType(rollCommand?.type);
|
if (!fateTypeData)
|
||||||
|
return ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing'));
|
||||||
if (fateTypeFromRollCommand == 'BAD') {
|
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing'));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fateType = fateTypeFromRollCommand;
|
|
||||||
|
|
||||||
|
const { value: fateType, label: fateTypeLabel } = fateTypeData;
|
||||||
const target = getCommandTarget({ allowNull: true });
|
const target = getCommandTarget({ allowNull: true });
|
||||||
const title = fateType + ' Fate Roll';
|
const title = flavor ?? game.i18n.localize('DAGGERHEART.GENERAL.fateRoll');
|
||||||
|
|
||||||
enrichedFateRoll({
|
enrichedFateRoll({
|
||||||
target,
|
target,
|
||||||
title,
|
title,
|
||||||
label: 'test',
|
label: fateTypeLabel,
|
||||||
fateType
|
fateType
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
25
lang/en.json
25
lang/en.json
|
|
@ -237,10 +237,13 @@
|
||||||
"confirmText": "Would you like to level up your companion {name} by {levelChange} levels at this time? (You can do it manually later)"
|
"confirmText": "Would you like to level up your companion {name} by {levelChange} levels at this time? (You can do it manually later)"
|
||||||
},
|
},
|
||||||
"viewLevelups": "View Levelups",
|
"viewLevelups": "View Levelups",
|
||||||
|
"resetCharacter": "Reset Character",
|
||||||
"viewParty": "View Party",
|
"viewParty": "View Party",
|
||||||
"InvalidOldCharacterImportTitle": "Old Character Import",
|
"InvalidOldCharacterImportTitle": "Old Character Import",
|
||||||
"InvalidOldCharacterImportText": "Character data exported prior to system version 1.1 will not generate a complete character. Do you wish to continue?",
|
"InvalidOldCharacterImportText": "Character data exported prior to system version 1.1 will not generate a complete character. Do you wish to continue?",
|
||||||
"cancelBeastform": "Cancel Beastform"
|
"cancelBeastform": "Cancel Beastform",
|
||||||
|
"resetCharacterConfirmationTitle": "Reset Character",
|
||||||
|
"resetCharacterConfirmationContent": "You are reseting all character data except name and portrait. Are you sure?"
|
||||||
},
|
},
|
||||||
"Companion": {
|
"Companion": {
|
||||||
"FIELDS": {
|
"FIELDS": {
|
||||||
|
|
@ -314,6 +317,8 @@
|
||||||
"selectPrimaryWeapon": "Select Primary Weapon",
|
"selectPrimaryWeapon": "Select Primary Weapon",
|
||||||
"selectSecondaryWeapon": "Select Secondary Weapon",
|
"selectSecondaryWeapon": "Select Secondary Weapon",
|
||||||
"selectSubclass": "Select Subclass",
|
"selectSubclass": "Select Subclass",
|
||||||
|
"setupSkipTitle": "Skipping Character Setup",
|
||||||
|
"setupSkipContent": "You are skipping the Character Setup by adding this manually. The character setup is the blinking arrows in the top-right. Are you sure you want to continue?",
|
||||||
"startingItems": "Starting Items",
|
"startingItems": "Starting Items",
|
||||||
"story": "Story",
|
"story": "Story",
|
||||||
"storyExplanation": "Select which background and connection prompts you want to copy into your character's background.",
|
"storyExplanation": "Select which background and connection prompts you want to copy into your character's background.",
|
||||||
|
|
@ -615,9 +620,11 @@
|
||||||
"rerollDice": "Reroll Dice"
|
"rerollDice": "Reroll Dice"
|
||||||
},
|
},
|
||||||
"RiskItAllDialog": {
|
"RiskItAllDialog": {
|
||||||
"title": "Character: {name} - Risk It All - Clear Stress and/or Hit Points",
|
"title": "{name} - Risk It All",
|
||||||
"subtitle": "Clear {hope} Stress and/or Hit Points",
|
"subtitle": "Clear Stress and Hit Points",
|
||||||
"submit": "Submit"
|
"remainingTitle": "Remaining Points",
|
||||||
|
"clearResource": "Clear {resource}",
|
||||||
|
"finalTitle": "Final Character Resources"
|
||||||
},
|
},
|
||||||
"TagTeamSelect": {
|
"TagTeamSelect": {
|
||||||
"title": "Tag Team Roll",
|
"title": "Tag Team Roll",
|
||||||
|
|
@ -2461,10 +2468,6 @@
|
||||||
"label": "Show Resource Change Scrolltexts",
|
"label": "Show Resource Change Scrolltexts",
|
||||||
"hint": "When a character is damaged, uses armor etc, a scrolling text will briefly appear by the token to signify this."
|
"hint": "When a character is damaged, uses armor etc, a scrolling text will briefly appear by the token to signify this."
|
||||||
},
|
},
|
||||||
"playerCanEditSheet": {
|
|
||||||
"label": "Players Can Manually Edit Character Settings",
|
|
||||||
"hint": "Players are allowed to access the manual Character Settings and change their statistics beyond the rules."
|
|
||||||
},
|
|
||||||
"roll": {
|
"roll": {
|
||||||
"roll": {
|
"roll": {
|
||||||
"label": "Roll",
|
"label": "Roll",
|
||||||
|
|
@ -2675,9 +2678,9 @@
|
||||||
"riskItAllCritical": "Critical Rolled, clearing all marked Stress and Hit Points.",
|
"riskItAllCritical": "Critical Rolled, clearing all marked Stress and Hit Points.",
|
||||||
"riskItAllFailure": "The fear die rolled higher. You have crossed through the veil of death.",
|
"riskItAllFailure": "The fear die rolled higher. You have crossed through the veil of death.",
|
||||||
"blazeOfGlory": "Blaze of Glory Effect Added!",
|
"blazeOfGlory": "Blaze of Glory Effect Added!",
|
||||||
"riskItAllClearStressAndHitPoints": "Clear {hope} Stress Or Hit Points.",
|
"riskItAllDialogButton": "Clear Stress And Hit Points.",
|
||||||
"riskItAllSuccessWithEnoughHope": "Hope roll value is more than the marked Stress and Hit Points, clearing both.",
|
"riskItAllSuccessWithEnoughHope": "The Hope value is more than the marked Stress and Hit Points. Both are cleared fully.",
|
||||||
"riskItAllSuccess": "The hope die rolled higher, clear up to {hope} Stress Or Hit Points."
|
"riskItAllSuccess": "The hope die rolled higher, clear up to {hope} Stress And Hit Points."
|
||||||
},
|
},
|
||||||
"dicePool": {
|
"dicePool": {
|
||||||
"title": "Dice Pool"
|
"title": "Dice Pool"
|
||||||
|
|
|
||||||
|
|
@ -14,3 +14,4 @@ export { default as ResourceDiceDialog } from './resourceDiceDialog.mjs';
|
||||||
export { default as ActionSelectionDialog } from './actionSelectionDialog.mjs';
|
export { default as ActionSelectionDialog } from './actionSelectionDialog.mjs';
|
||||||
export { default as GroupRollDialog } from './group-roll-dialog.mjs';
|
export { default as GroupRollDialog } from './group-roll-dialog.mjs';
|
||||||
export { default as TagTeamDialog } from './tagTeamDialog.mjs';
|
export { default as TagTeamDialog } from './tagTeamDialog.mjs';
|
||||||
|
export { default as RiskItAllDialog } from './riskItAllDialog.mjs';
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
context.formula = this.roll.constructFormula(this.config);
|
context.formula = this.roll.constructFormula(this.config);
|
||||||
if (this.actor?.system?.traits) context.abilities = this.getTraitModifiers();
|
if (this.actor?.system?.traits) context.abilities = this.getTraitModifiers();
|
||||||
|
|
||||||
context.showReaction = !this.config.roll?.type || context.rollType === 'DualityRoll';
|
context.showReaction = !this.config.skips?.reaction && context.rollType === 'DualityRoll';
|
||||||
context.reactionOverride = this.reactionOverride;
|
context.reactionOverride = this.reactionOverride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.selectedMove = null;
|
this.selectedMove = null;
|
||||||
this.showRiskItAllButton = false;
|
this.showRiskItAllButton = false;
|
||||||
this.riskItAllButtonLabel = "";
|
this.riskItAllButtonLabel = '';
|
||||||
this.riskItAllHope = 0;
|
this.riskItAllHope = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
|
||||||
label: game.i18n.localize('DAGGERHEART.GENERAL.dualityDice'),
|
label: game.i18n.localize('DAGGERHEART.GENERAL.dualityDice'),
|
||||||
actionType: null,
|
actionType: null,
|
||||||
advantage: null,
|
advantage: null,
|
||||||
customConfig: { skips: { resources: true } }
|
customConfig: { skips: { resources: true, reaction: true } }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!config.roll.result) return;
|
if (!config.roll.result) return;
|
||||||
|
|
@ -108,10 +108,12 @@ export default class DhDeathMove extends HandlebarsApplicationMixin(ApplicationV
|
||||||
config.resourceUpdates.addResources(clearAllStressAndHitpointsUpdates);
|
config.resourceUpdates.addResources(clearAllStressAndHitpointsUpdates);
|
||||||
chatMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.riskItAllSuccessWithEnoughHope');
|
chatMessage = game.i18n.localize('DAGGERHEART.UI.Chat.deathMove.riskItAllSuccessWithEnoughHope');
|
||||||
} else {
|
} else {
|
||||||
chatMessage = game.i18n.format('DAGGERHEART.UI.Chat.deathMove.riskItAllSuccess', { hope: config.roll.hope.value })
|
chatMessage = game.i18n.format('DAGGERHEART.UI.Chat.deathMove.riskItAllSuccess', {
|
||||||
|
hope: config.roll.hope.value
|
||||||
|
});
|
||||||
this.showRiskItAllButton = true;
|
this.showRiskItAllButton = true;
|
||||||
this.riskItAllHope = config.roll.hope.value;
|
this.riskItAllHope = config.roll.hope.value;
|
||||||
this.riskItAllButtonLabel = game.i18n.format('DAGGERHEART.UI.Chat.deathMove.riskItAllClearStressAndHitPoints', { hope: config.roll.hope.value })
|
this.riskItAllButtonLabel = game.i18n.format('DAGGERHEART.UI.Chat.deathMove.riskItAllDialogButton');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
export default class RiskItAllDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
export default class RiskItAllDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
constructor(actor, config) {
|
constructor(actor, resourceValue) {
|
||||||
super({});
|
super({});
|
||||||
|
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.validChoices = null;
|
this.resourceValue = resourceValue;
|
||||||
this.config = config;
|
this.choices = {
|
||||||
|
hitPoints: 0,
|
||||||
|
stress: 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
|
|
@ -14,10 +17,10 @@ export default class RiskItAllDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
classes: ['daggerheart', 'dh-style', 'dialog', 'views', 'risk-it-all'],
|
classes: ['daggerheart', 'dh-style', 'dialog', 'views', 'risk-it-all'],
|
||||||
position: { width: 'auto', height: 'auto' },
|
position: { width: 280, height: 'auto' },
|
||||||
window: { icon: 'fa-solid fa-skull' },
|
window: { icon: 'fa-solid fa-dice fa-xl' },
|
||||||
actions: {
|
actions: {
|
||||||
submit: this.submit
|
finish: RiskItAllDialog.#finish
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -28,42 +31,62 @@ export default class RiskItAllDialog extends HandlebarsApplicationMixin(Applicat
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_attachPartListeners(partId, htmlElement, options) {
|
||||||
|
super._attachPartListeners(partId, htmlElement, options);
|
||||||
|
|
||||||
|
for (const input of htmlElement.querySelectorAll('.resource-container input'))
|
||||||
|
input.addEventListener('change', this.updateChoice.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.RiskItAllDialog = this.RiskItAllDialog;
|
context.resourceValue = this.resourceValue;
|
||||||
context.title = game.i18n.format('DAGGERHEART.APPLICATIONS.RiskItAllDialog.subtitle', { hope: this.config.hope });
|
context.remainingResource = this.resourceValue - this.choices.hitPoints - this.choices.stress;
|
||||||
context.currentHitPointsLabel = "Current Marked Hit Points: " + this.actor.system.resources.hitPoints.value;
|
context.unfinished = context.remainingResource !== 0;
|
||||||
context.currentStressLabel = "Current Marked Stress: " + this.actor.system.resources.stress.value;
|
|
||||||
|
|
||||||
context.newHitPoints = this.actor.system.resources.hitPoints.value;
|
context.choices = this.choices;
|
||||||
context.newStress = this.actor.system.resources.stress.value;
|
context.final = {
|
||||||
|
hitPoints: {
|
||||||
|
value: this.actor.system.resources.hitPoints.value - this.choices.hitPoints,
|
||||||
|
max: this.actor.system.resources.hitPoints.max
|
||||||
|
},
|
||||||
|
stress: {
|
||||||
|
value: this.actor.system.resources.stress.value - this.choices.stress,
|
||||||
|
max: this.actor.system.resources.stress.max
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
context;
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static checkForValidChoice() {
|
updateChoice(event) {
|
||||||
/*
|
let value = Number.parseInt(event.target.value);
|
||||||
TODO:
|
const choiceKey = event.target.dataset.choice;
|
||||||
|
const actorValue = this.actor.system.resources[choiceKey].value;
|
||||||
|
const remaining = this.resourceValue - this.choices.hitPoints - this.choices.stress;
|
||||||
|
const changeAmount = value - this.choices[choiceKey];
|
||||||
|
|
||||||
return (this.config.hope == (this.actor.system.resources.hitPoints.value - newHitPointValue) + (this.actor.system.resources.stress.value - newStressValue));
|
/* If trying to increase beyond remaining resource points, just increase to max available */
|
||||||
*/
|
if (remaining - changeAmount < 0) value = this.choices[choiceKey] + remaining;
|
||||||
return true;
|
else if (actorValue - value < 0) value = actorValue;
|
||||||
|
|
||||||
|
this.choices[choiceKey] = value;
|
||||||
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
static async submit() {
|
static async #finish() {
|
||||||
this.close();
|
const resourceUpdate = Object.keys(this.choices).reduce((acc, resourceKey) => {
|
||||||
// TODO: Update actor with changes.
|
const value = this.actor.system.resources[resourceKey].value - this.choices[resourceKey];
|
||||||
|
acc[resourceKey] = { value };
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
await this.actor.update({
|
await this.actor.update({
|
||||||
system: {
|
'system.resources': resourceUpdate
|
||||||
resources: {
|
|
||||||
hitPoints: {
|
|
||||||
value: 0 // TODO put editted value here
|
|
||||||
},
|
|
||||||
stress: {
|
|
||||||
value: 0 // TODO put editted value here
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
makeDeathMove: CharacterSheet.#makeDeathMove,
|
makeDeathMove: CharacterSheet.#makeDeathMove,
|
||||||
levelManagement: CharacterSheet.#levelManagement,
|
levelManagement: CharacterSheet.#levelManagement,
|
||||||
viewLevelups: CharacterSheet.#viewLevelups,
|
viewLevelups: CharacterSheet.#viewLevelups,
|
||||||
|
resetCharacter: CharacterSheet.#resetCharacter,
|
||||||
toggleEquipItem: CharacterSheet.#toggleEquipItem,
|
toggleEquipItem: CharacterSheet.#toggleEquipItem,
|
||||||
toggleResourceDice: CharacterSheet.#toggleResourceDice,
|
toggleResourceDice: CharacterSheet.#toggleResourceDice,
|
||||||
handleResourceDice: CharacterSheet.#handleResourceDice,
|
handleResourceDice: CharacterSheet.#handleResourceDice,
|
||||||
|
|
@ -42,6 +43,11 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
icon: 'fa-solid fa-angles-up',
|
icon: 'fa-solid fa-angles-up',
|
||||||
label: 'DAGGERHEART.ACTORS.Character.viewLevelups',
|
label: 'DAGGERHEART.ACTORS.Character.viewLevelups',
|
||||||
action: 'viewLevelups'
|
action: 'viewLevelups'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: 'fa-solid fa-arrow-rotate-left',
|
||||||
|
label: 'DAGGERHEART.ACTORS.Character.resetCharacter',
|
||||||
|
action: 'resetCharacter'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -220,13 +226,6 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
async _preparePartContext(partId, context, options) {
|
async _preparePartContext(partId, context, options) {
|
||||||
context = await super._preparePartContext(partId, context, options);
|
context = await super._preparePartContext(partId, context, options);
|
||||||
switch (partId) {
|
switch (partId) {
|
||||||
case 'header':
|
|
||||||
const { playerCanEditSheet, levelupAuto } = game.settings.get(
|
|
||||||
CONFIG.DH.id,
|
|
||||||
CONFIG.DH.SETTINGS.gameSettings.Automation
|
|
||||||
);
|
|
||||||
context.showSettings = game.user.isGM || !levelupAuto || (levelupAuto && playerCanEditSheet);
|
|
||||||
break;
|
|
||||||
case 'loadout':
|
case 'loadout':
|
||||||
await this._prepareLoadoutContext(context, options);
|
await this._prepareLoadoutContext(context, options);
|
||||||
break;
|
break;
|
||||||
|
|
@ -666,6 +665,32 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
new LevelupViewMode(this.document).render({ force: true });
|
new LevelupViewMode(this.document).render({ force: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the character data and removes all embedded documents.
|
||||||
|
*/
|
||||||
|
static async #resetCharacter() {
|
||||||
|
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||||
|
window: {
|
||||||
|
title: game.i18n.localize('DAGGERHEART.ACTORS.Character.resetCharacterConfirmationTitle')
|
||||||
|
},
|
||||||
|
content: game.i18n.localize('DAGGERHEART.ACTORS.Character.resetCharacterConfirmationContent')
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirmed) return;
|
||||||
|
|
||||||
|
await this.document.update({
|
||||||
|
'==system': {}
|
||||||
|
});
|
||||||
|
await this.document.deleteEmbeddedDocuments(
|
||||||
|
'Item',
|
||||||
|
this.document.items.map(x => x.id)
|
||||||
|
);
|
||||||
|
await this.document.deleteEmbeddedDocuments(
|
||||||
|
'ActiveEffect',
|
||||||
|
this.document.effects.map(x => x.id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the Death Move interface for the character.
|
* Opens the Death Move interface for the character.
|
||||||
* @type {ApplicationClickAction}
|
* @type {ApplicationClickAction}
|
||||||
|
|
@ -955,6 +980,18 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
async _onDropItem(event, item) {
|
async _onDropItem(event, item) {
|
||||||
|
const setupCriticalItemTypes = ['class', 'subclass', 'ancestry', 'community'];
|
||||||
|
if (this.document.system.needsCharacterSetup && setupCriticalItemTypes.includes(item.type)) {
|
||||||
|
const confirmed = await foundry.applications.api.DialogV2.confirm({
|
||||||
|
window: {
|
||||||
|
title: game.i18n.localize('DAGGERHEART.APPLICATIONS.CharacterCreation.setupSkipTitle')
|
||||||
|
},
|
||||||
|
content: game.i18n.localize('DAGGERHEART.APPLICATIONS.CharacterCreation.setupSkipContent')
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!confirmed) return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.document.uuid === item.parent?.uuid) {
|
if (this.document.uuid === item.parent?.uuid) {
|
||||||
return super._onDropItem(event, item);
|
return super._onDropItem(event, item);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
import { abilities } from '../../config/actorConfig.mjs';
|
import { abilities } from '../../config/actorConfig.mjs';
|
||||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||||
import RiskItAllDialog from '../dialogs/riskItAllDialog.mjs';
|
|
||||||
|
|
||||||
export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog {
|
export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
|
@ -98,15 +97,17 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
|
|
||||||
/** Ensure the chat theme inherits the interface theme */
|
/** Ensure the chat theme inherits the interface theme */
|
||||||
_replaceHTML(result, content, options) {
|
_replaceHTML(result, content, options) {
|
||||||
const themedElement = result.log?.querySelector(".chat-log");
|
const themedElement = result.log?.querySelector('.chat-log');
|
||||||
themedElement?.classList.remove("themed", "theme-light", "theme-dark");
|
themedElement?.classList.remove('themed', 'theme-light', 'theme-dark');
|
||||||
super._replaceHTML(result, content, options);
|
super._replaceHTML(result, content, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Remove chat log theme from notifications area */
|
/** Remove chat log theme from notifications area */
|
||||||
async _onFirstRender(result, content) {
|
async _onFirstRender(result, content) {
|
||||||
await super._onFirstRender(result, content);
|
await super._onFirstRender(result, content);
|
||||||
document.querySelector("#chat-notifications .chat-log")?.classList.remove("themed", "theme-light", "theme-dark")
|
document
|
||||||
|
.querySelector('#chat-notifications .chat-log')
|
||||||
|
?.classList.remove('themed', 'theme-light', 'theme-dark');
|
||||||
}
|
}
|
||||||
|
|
||||||
async onRollSimple(event, message) {
|
async onRollSimple(event, message) {
|
||||||
|
|
@ -388,14 +389,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
event.target.closest('.group-roll-section').querySelector('.group-roll-content').classList.toggle('closed');
|
event.target.closest('.group-roll-section').querySelector('.group-roll-content').classList.toggle('closed');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async riskItAllClearStressAndHitPoints(event, data) {
|
async riskItAllClearStressAndHitPoints(event, data) {
|
||||||
const hopeValue = event.target.dataset.hope;
|
const resourceValue = event.target.dataset.resourceValue;
|
||||||
const config = {
|
new game.system.api.applications.dialogs.RiskItAllDialog(data.actor, resourceValue).render({ force: true });
|
||||||
hope: hopeValue
|
|
||||||
}
|
|
||||||
await new RiskItAllDialog(data.actor, config).render({ force: true });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,11 +55,6 @@ export default class DhAutomation extends foundry.abstract.DataModel {
|
||||||
initial: true,
|
initial: true,
|
||||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.resourceScrollTexts.label'
|
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.resourceScrollTexts.label'
|
||||||
}),
|
}),
|
||||||
playerCanEditSheet: new fields.BooleanField({
|
|
||||||
required: true,
|
|
||||||
initial: false,
|
|
||||||
label: 'DAGGERHEART.SETTINGS.Automation.FIELDS.playerCanEditSheet.label'
|
|
||||||
}),
|
|
||||||
defeated: new fields.SchemaField({
|
defeated: new fields.SchemaField({
|
||||||
enabled: new fields.BooleanField({
|
enabled: new fields.BooleanField({
|
||||||
required: true,
|
required: true,
|
||||||
|
|
|
||||||
|
|
@ -4,56 +4,35 @@ export default function DhFateRollEnricher(match, _options) {
|
||||||
const roll = rollCommandToJSON(match[1], match[0]);
|
const roll = rollCommandToJSON(match[1], match[0]);
|
||||||
if (!roll) return match[0];
|
if (!roll) return match[0];
|
||||||
|
|
||||||
const fateTypeFromRoll = getFateType(roll?.type);
|
|
||||||
|
|
||||||
if (fateTypeFromRoll == 'BAD') {
|
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return getFateMessage(roll.result, roll?.flavor);
|
return getFateMessage(roll.result, roll?.flavor);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFateType(fateTypeValue) {
|
export function getFateTypeData(fateTypeValue) {
|
||||||
const fateTypeFromValue = fateTypeValue
|
const value = fateTypeValue ? fateTypeValue.capitalize() : 'Hope';
|
||||||
? fateTypeValue.toLowerCase() == 'fear'
|
const lowercased = fateTypeValue?.toLowerCase?.() ?? 'hope';
|
||||||
? 'Fear'
|
switch (lowercased) {
|
||||||
: fateTypeValue.toLowerCase() == 'hope'
|
case 'hope':
|
||||||
? 'Hope'
|
case 'fear':
|
||||||
: 'BAD'
|
return { value, label: game.i18n.localize(`DAGGERHEART.GENERAL.${lowercased}`) };
|
||||||
: 'Hope';
|
default:
|
||||||
|
return null;
|
||||||
return fateTypeFromValue;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFateMessage(roll, flavor) {
|
function getFateMessage(roll, flavor) {
|
||||||
const fateType = getFateType(roll?.type);
|
const fateTypeData = getFateTypeData(roll?.type);
|
||||||
|
|
||||||
if (fateType == 'BAD') {
|
if (!fateTypeData)
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing'));
|
return ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing'));
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const fateTypeLocalized =
|
const { value: fateType, label: fateTypeLabel } = fateTypeData;
|
||||||
fateType === 'Hope'
|
const title = flavor ?? game.i18n.localize('DAGGERHEART.GENERAL.fateRoll');
|
||||||
? game.i18n.localize('DAGGERHEART.GENERAL.hope')
|
|
||||||
: game.i18n.localize('DAGGERHEART.GENERAL.fear');
|
|
||||||
|
|
||||||
const title =
|
|
||||||
flavor ??
|
|
||||||
fateTypeLocalized +
|
|
||||||
' ' +
|
|
||||||
game.i18n.localize('DAGGERHEART.GENERAL.fate') +
|
|
||||||
' ' +
|
|
||||||
game.i18n.localize('DAGGERHEART.GENERAL.roll');
|
|
||||||
|
|
||||||
const dataLabel = game.i18n.localize('DAGGERHEART.GENERAL.fate');
|
|
||||||
|
|
||||||
const fateElement = document.createElement('span');
|
const fateElement = document.createElement('span');
|
||||||
fateElement.innerHTML = `
|
fateElement.innerHTML = `
|
||||||
<button type="button" class="fate-roll-button${roll?.inline ? ' inline' : ''}"
|
<button type="button" class="fate-roll-button${roll?.inline ? ' inline' : ''}"
|
||||||
data-title="${title}"
|
data-title="${title}"
|
||||||
data-label="${dataLabel}"
|
data-label="${fateTypeLabel}"
|
||||||
data-fateType="${fateType}"
|
data-fateType="${fateType}"
|
||||||
>
|
>
|
||||||
${title}
|
${title}
|
||||||
|
|
@ -68,19 +47,17 @@ export const renderFateButton = async event => {
|
||||||
target = getCommandTarget({ allowNull: true });
|
target = getCommandTarget({ allowNull: true });
|
||||||
console.log('button', button);
|
console.log('button', button);
|
||||||
|
|
||||||
const fateTypeFromButton = getFateType(button.dataset?.fatetype);
|
const fateTypeData = getFateTypeData(button.dataset?.fatetype);
|
||||||
|
|
||||||
if (fateTypeFromButton == 'BAD') {
|
if (!fateTypeData) ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing'));
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.fateTypeParsing'));
|
const { value: fateType, label: fateTypeLabel } = fateTypeData;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await enrichedFateRoll(
|
await enrichedFateRoll(
|
||||||
{
|
{
|
||||||
target,
|
target,
|
||||||
title: button.dataset.title,
|
title: button.dataset.title,
|
||||||
label: button.dataset.label,
|
label: button.dataset.label,
|
||||||
fateType: fateTypeFromButton
|
fateType: fateType
|
||||||
},
|
},
|
||||||
event
|
event
|
||||||
);
|
);
|
||||||
|
|
@ -93,7 +70,8 @@ export const enrichedFateRoll = async ({ target, title, label, fateType }, event
|
||||||
headerTitle: label,
|
headerTitle: label,
|
||||||
roll: {},
|
roll: {},
|
||||||
hasRoll: true,
|
hasRoll: true,
|
||||||
fateType: fateType
|
fateType: fateType,
|
||||||
|
skips: { reaction: true }
|
||||||
};
|
};
|
||||||
|
|
||||||
config.data = { experiences: {}, traits: {}, fateType: fateType };
|
config.data = { experiences: {}, traits: {}, fateType: fateType };
|
||||||
|
|
|
||||||
|
|
@ -39,3 +39,5 @@
|
||||||
@import './item-transfer/sheet.less';
|
@import './item-transfer/sheet.less';
|
||||||
|
|
||||||
@import './settings/change-currency-icon.less';
|
@import './settings/change-currency-icon.less';
|
||||||
|
|
||||||
|
@import './risk-it-all/sheet.less';
|
||||||
|
|
|
||||||
60
styles/less/dialog/risk-it-all/sheet.less
Normal file
60
styles/less/dialog/risk-it-all/sheet.less
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
.daggerheart.dialog.dh-style.views.risk-it-all {
|
||||||
|
.risk-it-all-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
header {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: var(--font-size-20);
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-label {
|
||||||
|
font-size: var(--font-size-18);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remaining-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resource-section {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.final-section {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
|
||||||
|
.final-section-values-container {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
|
||||||
|
.final-section-value-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
button {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,33 +1,39 @@
|
||||||
<div>
|
<div>
|
||||||
<header class="dialog-header">
|
|
||||||
<h1>{{title}}</h1>
|
|
||||||
</header>
|
|
||||||
<div>
|
|
||||||
<span>Remaining points to use here.</span>
|
|
||||||
</div>
|
|
||||||
<div class="risk-it-all-container">
|
<div class="risk-it-all-container">
|
||||||
<div class="two-columns even">
|
<header>{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.subtitle"}}</header>
|
||||||
<span>{{currentHitPointsLabel}}</span>
|
|
||||||
<div>
|
|
||||||
<span>New Hit Points Value</span>
|
|
||||||
<input type="text" data-dtype="Number" name="newHitPoints" value="{{newHitPoints}}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<span>{{currentStressLabel}}</span>
|
<div class="remaining-section">
|
||||||
<div>
|
<label class="section-label">{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.remainingTitle"}}</label>
|
||||||
<span>New Stress Value</span>
|
<div>{{this.remainingResource}}</div>
|
||||||
<input type="text" data-dtype="Number" name="newStress" value="{{newStress}}" />
|
</div>
|
||||||
|
|
||||||
|
<div class="resource-section">
|
||||||
|
<div class="resource-container">
|
||||||
|
<label>{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.clearResource" resource=(localize "DAGGERHEART.GENERAL.HitPoints.short")}}: {{this.choices.hitPoints}}</label>
|
||||||
|
<input type="range" step="1" min="0" max="{{this.resourceValue}}" value="{{this.choices.hitPoints}}" name="choices.hitPoints" data-choice="hitPoints" />
|
||||||
|
</div>
|
||||||
|
<div class="resource-container">
|
||||||
|
<label>{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.clearResource" resource=(localize "DAGGERHEART.GENERAL.stress")}}: {{this.choices.stress}}</label>
|
||||||
|
<input type="range" step="1" min="0" max="{{this.resourceValue}}" value="{{this.choices.stress}}" name="choices.stress" data-choice="stress" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="final-section">
|
||||||
|
<label class="section-label">{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.finalTitle"}}</label>
|
||||||
|
<div class="final-section-values-container">
|
||||||
|
<div class="final-section-value-container">
|
||||||
|
<label>{{localize "DAGGERHEART.GENERAL.HitPoints.plural"}}</label>
|
||||||
|
<span>{{this.final.hitPoints.value}}/{{this.final.hitPoints.max}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="final-section-value-container">
|
||||||
|
<label>{{localize "DAGGERHEART.GENERAL.stress"}}</label>
|
||||||
|
<span>{{this.final.stress.value}}/{{this.final.stress.max}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<button type="button" data-action="finish" {{disabled this.unfinished}}>{{localize "Submit"}}</button>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
<footer class="flexrow">
|
|
||||||
<button data-action="close">
|
|
||||||
<span>{{localize "Cancel"}}</span>
|
|
||||||
</button>
|
|
||||||
<button data-action="submit" {{#if (not this.validChoices)}}disabled{{/if}}>
|
|
||||||
<span>
|
|
||||||
{{localize "DAGGERHEART.APPLICATIONS.RiskItAllDialog.submit"}}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
</footer>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -18,7 +18,6 @@
|
||||||
{{formGroup settingFields.schema.fields.hordeDamage value=settingFields._source.hordeDamage localize=true}}
|
{{formGroup settingFields.schema.fields.hordeDamage value=settingFields._source.hordeDamage localize=true}}
|
||||||
{{formGroup settingFields.schema.fields.effects.fields.rangeDependent value=settingFields._source.effects.rangeDependent localize=true}}
|
{{formGroup settingFields.schema.fields.effects.fields.rangeDependent value=settingFields._source.effects.rangeDependent localize=true}}
|
||||||
{{formGroup settingFields.schema.fields.levelupAuto value=settingFields._source.levelupAuto localize=true}}
|
{{formGroup settingFields.schema.fields.levelupAuto value=settingFields._source.levelupAuto localize=true}}
|
||||||
{{formGroup settingFields.schema.fields.playerCanEditSheet value=settingFields._source.playerCanEditSheet localize=true}}
|
|
||||||
{{formGroup settingFields.schema.fields.damageReductionRulesDefault value=settingFields._source.damageReductionRulesDefault localize=true}}
|
{{formGroup settingFields.schema.fields.damageReductionRulesDefault value=settingFields._source.damageReductionRulesDefault localize=true}}
|
||||||
{{formGroup settingFields.schema.fields.resourceScrollTexts value=settingFields._source.resourceScrollTexts localize=true}}
|
{{formGroup settingFields.schema.fields.resourceScrollTexts value=settingFields._source.resourceScrollTexts localize=true}}
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="code-mirror-wrapper {{#if trigger.revealed}}revealed{{/if}}">
|
<div class="code-mirror-wrapper {{#if trigger.revealed}}revealed{{/if}}">
|
||||||
{{formInput @root.fields.triggers.element.fields.command value=trigger.command elementType="code-mirror" name=(concat "triggers." index ".command") aria=(object label=(localize "Test")) }}
|
{{formInput @root.fields.triggers.element.fields.command value=trigger.command elementType="code-mirror" name=(concat "triggers." index ".command") }}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
||||||
|
|
@ -128,9 +128,7 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' showSettings=showSettings }}
|
{{#> 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' }}
|
||||||
{{#if ../showSettings}}
|
<button type="button" data-action="openSettings" data-tooltip-text="{{localize "DAGGERHEART.UI.Tooltip.openSheetSettings"}}"><i class="fa-solid fa-wrench"></i></button>
|
||||||
<button type="button" data-action="openSettings" data-tooltip-text="{{localize "DAGGERHEART.UI.Tooltip.openSheetSettings"}}"><i class="fa-solid fa-wrench"></i></button>
|
|
||||||
{{/if}}
|
|
||||||
{{/'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
|
{{/'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs'}}
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
</div>
|
</div>
|
||||||
{{#if this.showRiskItAllButton}}
|
{{#if this.showRiskItAllButton}}
|
||||||
<div>
|
<div>
|
||||||
<button class="risk-it-all-button" data-hope="{{this.riskItAllHope}}">
|
<button class="risk-it-all-button" data-resource-value="{{this.riskItAllHope}}">
|
||||||
<span>
|
<span>
|
||||||
{{this.riskItAllButtonLabel}}
|
{{this.riskItAllButtonLabel}}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue