mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-17 07:36:26 +01:00
Downtime can now display both ShortRest and LongRest options depending on character rules
This commit is contained in:
parent
ab56f2c23e
commit
475a63f120
8 changed files with 161 additions and 55 deletions
29
lang/en.json
29
lang/en.json
|
|
@ -251,6 +251,8 @@
|
||||||
"Downtime": {
|
"Downtime": {
|
||||||
"downtimeHeader": "Downtime Moves ({current}/{max})",
|
"downtimeHeader": "Downtime Moves ({current}/{max})",
|
||||||
"longRest": {
|
"longRest": {
|
||||||
|
"title": "Long Rest",
|
||||||
|
"moves": "Long Rest Moves ({current}/{max})",
|
||||||
"clearStress": {
|
"clearStress": {
|
||||||
"description": "Describe how you blow off steam or pull yourself together, and clear all marked Stress.",
|
"description": "Describe how you blow off steam or pull yourself together, and clear all marked Stress.",
|
||||||
"name": "Clear Stress"
|
"name": "Clear Stress"
|
||||||
|
|
@ -267,7 +269,6 @@
|
||||||
"description": "Describe how you patch yourself up and remove all marked Hit Points. You may also do this on an ally instead.",
|
"description": "Describe how you patch yourself up and remove all marked Hit Points. You may also do this on an ally instead.",
|
||||||
"name": "Tend to Wounds"
|
"name": "Tend to Wounds"
|
||||||
},
|
},
|
||||||
"title": "Long Rest",
|
|
||||||
"workOnAProject": {
|
"workOnAProject": {
|
||||||
"description": "Establish or continue work on a project.",
|
"description": "Establish or continue work on a project.",
|
||||||
"name": "Work on a Project"
|
"name": "Work on a Project"
|
||||||
|
|
@ -275,6 +276,7 @@
|
||||||
},
|
},
|
||||||
"shortRest": {
|
"shortRest": {
|
||||||
"title": "Short Rest",
|
"title": "Short Rest",
|
||||||
|
"moves": "Short Rest Moves ({current}/{max})",
|
||||||
"tendToWounds": {
|
"tendToWounds": {
|
||||||
"name": "Tend to Wounds",
|
"name": "Tend to Wounds",
|
||||||
"description": "Describe how you hastily patch yourself up, then clear a number of Hit Points equal to 1d4 + your tier. You can do this to an ally instead."
|
"description": "Describe how you hastily patch yourself up, then clear a number of Hit Points equal to 1d4 + your tier. You can do this to an ally instead."
|
||||||
|
|
@ -291,7 +293,8 @@
|
||||||
"name": "Prepare",
|
"name": "Prepare",
|
||||||
"description": "Describe how you prepare yourself for the path ahead, then gain a Hope. If you choose to Prepare with one or more members of your party, you each gain 2 Hope."
|
"description": "Describe how you prepare yourself for the path ahead, then gain a Hope. If you choose to Prepare with one or more members of your party, you each gain 2 Hope."
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"takeDowntime": "Take Downtime"
|
||||||
},
|
},
|
||||||
"HUD": {
|
"HUD": {
|
||||||
"tokenHUD": {
|
"tokenHUD": {
|
||||||
|
|
@ -1161,6 +1164,28 @@
|
||||||
"hint": "The cost in stress you can pay to reduce minor damage to none."
|
"hint": "The cost in stress you can pay to reduce minor damage to none."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"rest": {
|
||||||
|
"shortRest": {
|
||||||
|
"shortRestMoves": {
|
||||||
|
"label": "Short Rest: Short Rest Moves",
|
||||||
|
"hint": "The number of Short Rest Moves the character can take during a Short Rest."
|
||||||
|
},
|
||||||
|
"longRestMoves": {
|
||||||
|
"label": "Short Rest: Long Rest Moves",
|
||||||
|
"hint": "The number of Long Rest Moves the character can take during a Short Rest."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"longRest": {
|
||||||
|
"shortRestMoves": {
|
||||||
|
"label": "Long Rest: Short Rest Moves",
|
||||||
|
"hint": "The number of Short Rest Moves the character can take during a Long Rest."
|
||||||
|
},
|
||||||
|
"longRestMoves": {
|
||||||
|
"label": "Long Rest: Long Rest Moves",
|
||||||
|
"hint": "The number of Long Rest Moves the character can take during a Long Rest."
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Tabs": {
|
"Tabs": {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,16 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.shortrest = shortrest;
|
this.shortrest = shortrest;
|
||||||
|
|
||||||
const options = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves;
|
this.moveData = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).restMoves;
|
||||||
this.moveData = shortrest ? options.shortRest : options.longRest;
|
this.nrChoices = {
|
||||||
|
shortRest: {
|
||||||
|
max: actor.system.rules.rest[`${shortrest ? 'short' : 'long'}Rest`].shortMoves
|
||||||
|
},
|
||||||
|
longRest: {
|
||||||
|
max: actor.system.rules.rest[`${shortrest ? 'short' : 'long'}Rest`].longMoves
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.nrChoices.total = { max: this.nrChoices.shortRest.max + this.nrChoices.longRest.max };
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
|
|
@ -17,7 +25,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
|
|
||||||
static DEFAULT_OPTIONS = {
|
static DEFAULT_OPTIONS = {
|
||||||
tag: 'form',
|
tag: 'form',
|
||||||
classes: ['daggerheart', 'views', 'downtime'],
|
classes: ['daggerheart', 'views', 'dh-style', 'downtime'],
|
||||||
position: { width: 680, height: 'auto' },
|
position: { width: 680, height: 'auto' },
|
||||||
actions: {
|
actions: {
|
||||||
selectMove: this.selectMove,
|
selectMove: this.selectMove,
|
||||||
|
|
@ -29,7 +37,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
static PARTS = {
|
static PARTS = {
|
||||||
application: {
|
application: {
|
||||||
id: 'downtime',
|
id: 'downtime',
|
||||||
template: 'systems/daggerheart/templates/dialogs/downtime.hbs'
|
template: 'systems/daggerheart/templates/dialogs/downtime/downtime.hbs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -45,38 +53,70 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.selectedActivity = this.selectedActivity;
|
context.selectedActivity = this.selectedActivity;
|
||||||
context.moveData = this.moveData;
|
context.moveData = this.moveData;
|
||||||
context.nrCurrentChoices = Object.values(this.moveData.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0);
|
context.nrCurrentChoices = Object.values(this.moveData).reduce((acc, category) => {
|
||||||
context.disabledDowntime = context.nrCurrentChoices < context.moveData.nrChoices;
|
acc += Object.values(category.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0);
|
||||||
|
return acc;
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
context.nrChoices = {
|
||||||
|
...this.nrChoices,
|
||||||
|
shortRest: {
|
||||||
|
...this.nrChoices.shortRest,
|
||||||
|
current: Object.values(this.moveData.shortRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0)
|
||||||
|
},
|
||||||
|
longRest: {
|
||||||
|
...this.nrChoices.longRest,
|
||||||
|
current: Object.values(this.moveData.longRest.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
context.nrChoices.total = {
|
||||||
|
...this.nrChoices.total,
|
||||||
|
current: context.nrChoices.shortRest.current + context.nrChoices.longRest.current
|
||||||
|
};
|
||||||
|
|
||||||
|
context.shortRestMoves = this.nrChoices.shortRest.max > 0 ? this.moveData.shortRest : null;
|
||||||
|
context.longRestMoves = this.nrChoices.longRest.max > 0 ? this.moveData.longRest : null;
|
||||||
|
|
||||||
|
context.disabledDowntime = context.nrChoices.total.current < context.nrChoices.total.max;
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
static selectMove(_, button) {
|
static selectMove(_, target) {
|
||||||
const nrSelected = Object.values(this.moveData.moves).reduce((acc, x) => acc + (x.selected ?? 0), 0);
|
const nrSelected = Object.values(this.moveData[target.dataset.category].moves).reduce(
|
||||||
if (nrSelected === this.moveData.nrChoices) {
|
(acc, x) => acc + (x.selected ?? 0),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nrSelected === this.nrChoices[target.dataset.category].max) {
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noMoreMoves'));
|
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noMoreMoves'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const move = button.dataset.move;
|
const move = target.dataset.move;
|
||||||
this.moveData.moves[move].selected = this.moveData.moves[move].selected
|
this.moveData[target.dataset.category].moves[move].selected = this.moveData[target.dataset.category].moves[move]
|
||||||
? this.moveData.moves[move].selected + 1
|
.selected
|
||||||
|
? this.moveData[target.dataset.category].moves[move].selected + 1
|
||||||
: 1;
|
: 1;
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
deselectMove(event) {
|
deselectMove(event) {
|
||||||
const move = event.currentTarget.dataset.move;
|
const button = event.target.closest('.activity-image');
|
||||||
this.moveData.moves[move].selected = this.moveData.moves[move].selected
|
const move = button.dataset.move;
|
||||||
? this.moveData.moves[move].selected - 1
|
this.moveData[button.dataset.category].moves[move].selected = this.moveData[button.dataset.category].moves[move]
|
||||||
|
.selected
|
||||||
|
? this.moveData[button.dataset.category].moves[move].selected - 1
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
static async takeDowntime() {
|
static async takeDowntime() {
|
||||||
const moves = Object.values(this.moveData.moves).filter(x => x.selected);
|
const moves = Object.values(this.moveData).flatMap(category => {
|
||||||
|
return Object.values(category.moves).filter(x => x.selected);
|
||||||
|
});
|
||||||
|
|
||||||
const cls = getDocumentClass('ChatMessage');
|
const cls = getDocumentClass('ChatMessage');
|
||||||
const msg = new cls({
|
const msg = new cls({
|
||||||
|
|
|
||||||
|
|
@ -122,12 +122,9 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
label: 'DAGGERHEART.GENERAL.Range.other'
|
label: 'DAGGERHEART.GENERAL.Range.other'
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
rally: new fields.ArrayField(
|
rally: new fields.ArrayField(new fields.StringField(), {
|
||||||
new fields.StringField(),
|
|
||||||
{
|
|
||||||
label: 'DAGGERHEART.CLASS.Feature.rallyDice'
|
label: 'DAGGERHEART.CLASS.Feature.rallyDice'
|
||||||
}
|
})
|
||||||
)
|
|
||||||
}),
|
}),
|
||||||
companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }),
|
companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }),
|
||||||
rules: new fields.SchemaField({
|
rules: new fields.SchemaField({
|
||||||
|
|
@ -174,6 +171,44 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
*/
|
*/
|
||||||
flipMinDiceValue: new fields.BooleanField({ intial: false })
|
flipMinDiceValue: new fields.BooleanField({ intial: false })
|
||||||
}),
|
}),
|
||||||
|
rest: new fields.SchemaField({
|
||||||
|
shortRest: new fields.SchemaField({
|
||||||
|
shortMoves: new fields.NumberField({
|
||||||
|
required: true,
|
||||||
|
integer: true,
|
||||||
|
min: 1,
|
||||||
|
initial: 2,
|
||||||
|
label: 'DAGGERHEART.GENERAL.Rules.rest.shortRest.shortRestMoves.label',
|
||||||
|
hint: 'DAGGERHEART.GENERAL.Rules.rest.shortRest.shortRestMoves.hint'
|
||||||
|
}),
|
||||||
|
longMoves: new fields.NumberField({
|
||||||
|
required: true,
|
||||||
|
integer: true,
|
||||||
|
min: 0,
|
||||||
|
initial: 0,
|
||||||
|
label: 'DAGGERHEART.GENERAL.Rules.rest.shortRest.longRestMoves.label',
|
||||||
|
hint: 'DAGGERHEART.GENERAL.Rules.rest.shortRest.longRestMoves.hint'
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
longRest: new fields.SchemaField({
|
||||||
|
shortMoves: new fields.NumberField({
|
||||||
|
required: true,
|
||||||
|
integer: true,
|
||||||
|
min: 0,
|
||||||
|
initial: 0,
|
||||||
|
label: 'DAGGERHEART.GENERAL.Rules.rest.longRest.shortRestMoves.label',
|
||||||
|
hint: 'DAGGERHEART.GENERAL.Rules.rest.longRest.shortRestMoves.hint'
|
||||||
|
}),
|
||||||
|
longMoves: new fields.NumberField({
|
||||||
|
required: true,
|
||||||
|
integer: true,
|
||||||
|
min: 1,
|
||||||
|
initial: 2,
|
||||||
|
label: 'DAGGERHEART.GENERAL.Rules.rest.longRest.longRestMoves.label',
|
||||||
|
hint: 'DAGGERHEART.GENERAL.Rules.rest.longRest.longRestMoves.hint'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}),
|
||||||
runeWard: new fields.BooleanField({ initial: false })
|
runeWard: new fields.BooleanField({ initial: false })
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ export const preloadHandlebarsTemplates = async function () {
|
||||||
'systems/daggerheart/templates/settings/components/settings-item-line.hbs',
|
'systems/daggerheart/templates/settings/components/settings-item-line.hbs',
|
||||||
'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs',
|
'systems/daggerheart/templates/ui/chat/parts/damage-chat.hbs',
|
||||||
'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs',
|
'systems/daggerheart/templates/ui/chat/parts/target-chat.hbs',
|
||||||
'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs'
|
'systems/daggerheart/templates/ui/tooltip/parts/tooltipTags.hbs',
|
||||||
|
'systems/daggerheart/templates/dialogs/downtime/activities.hbs'
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,6 @@
|
||||||
|
|
||||||
.daggerheart.views {
|
.daggerheart.views {
|
||||||
.downtime-container {
|
.downtime-container {
|
||||||
.downtime-header {
|
|
||||||
margin: 0;
|
|
||||||
color: light-dark(@dark-blue, @golden);
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-container {
|
.activity-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -73,6 +67,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
margin-top: 8px;
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
&.downtime {
|
&.downtime {
|
||||||
.activity-text-area {
|
.activity-text-area {
|
||||||
resize: none;
|
resize: none;
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
<div>
|
|
||||||
<div class="downtime-container">
|
|
||||||
<h2 class="downtime-header">{{localize "DAGGERHEART.APPLICATIONS.Downtime.downtimeHeader" current=nrCurrentChoices max=moveData.nrChoices}}</h2>
|
|
||||||
{{#each moveData.moves as |move key|}}
|
|
||||||
<div class="activity-container">
|
|
||||||
<div class="activity-title">
|
|
||||||
<div class="activity-image {{#if this.selected}}selected{{/if}}" data-action="selectMove" data-move="{{key}}">
|
|
||||||
{{#if this.selected}}<div class="activity-select-label">{{move.selected}}</div>{{/if}}
|
|
||||||
<img src="{{move.img}}" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<span class="activity-title-text">{{localize this.name}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="activity-body">
|
|
||||||
{{localize this.description}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
<footer class="flexrow">
|
|
||||||
<button type="button" data-action="close">{{localize "DAGGERHEART.Application.Cancel"}}</button>
|
|
||||||
<button type="button" data-action="takeDowntime" {{#if this.disabledDowntime}}disabled{{/if}}>{{localize "DAGGERHEART.Application.Downtime.TakeDowntime"}}</button>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
19
templates/dialogs/downtime/activities.hbs
Normal file
19
templates/dialogs/downtime/activities.hbs
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<fieldset class="one-column">
|
||||||
|
<legend>{{localize (concat "DAGGERHEART.APPLICATIONS.Downtime." category ".moves") max=nrChoices.max current=nrChoices.current}}</legend>
|
||||||
|
|
||||||
|
{{#each moves as |move key|}}
|
||||||
|
<div class="activity-container">
|
||||||
|
<div class="activity-title">
|
||||||
|
<div class="activity-image {{#if move.selected}}selected{{/if}}" data-action="selectMove" data-category="{{../category}}" data-move="{{key}}">
|
||||||
|
{{#if move.selected}}<div class="activity-select-label">{{move.selected}}</div>{{/if}}
|
||||||
|
<img src="{{move.img}}" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<span class="activity-title-text">{{localize move.name}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="activity-body">
|
||||||
|
{{localize move.description}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</fieldset>
|
||||||
10
templates/dialogs/downtime/downtime.hbs
Normal file
10
templates/dialogs/downtime/downtime.hbs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
<div>
|
||||||
|
<div class="downtime-container">
|
||||||
|
{{#if shortRestMoves.moves}}{{> "systems/daggerheart/templates/dialogs/downtime/activities.hbs" moves=shortRestMoves.moves category='shortRest' nrChoices=nrChoices.shortRest}}{{/if}}
|
||||||
|
{{#if longRestMoves.moves}}{{> "systems/daggerheart/templates/dialogs/downtime/activities.hbs" moves=longRestMoves.moves category='longRest' nrChoices=nrChoices.longRest}}{{/if}}
|
||||||
|
</div>
|
||||||
|
<footer class="flexrow">
|
||||||
|
<button type="button" data-action="close">{{localize "Cancel"}}</button>
|
||||||
|
<button type="button" data-action="takeDowntime" {{#if disabledDowntime}}disabled{{/if}}>{{localize "DAGGERHEART.APPLICATIONS.Downtime.takeDowntime"}}</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue