mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Merge pull request #42 from Foundryborne/#24/Updating-Adversaries
Updating adversaries
This commit is contained in:
commit
ad1e968888
87 changed files with 5588 additions and 5069 deletions
|
|
@ -4,3 +4,4 @@ package.json
|
|||
.github
|
||||
*.hbs
|
||||
styles/daggerheart.css
|
||||
src/packs
|
||||
|
|
@ -75,6 +75,7 @@ Hooks.once('init', () => {
|
|||
CONFIG.ChatMessage.dataModels = {
|
||||
dualityRoll: models.DhpDualityRoll,
|
||||
adversaryRoll: models.DhpAdversaryRoll,
|
||||
damageRoll: models.DhpDamageRoll,
|
||||
abilityUse: models.DhpAbilityUse
|
||||
};
|
||||
CONFIG.ChatMessage.documentClass = applications.DhpChatMessage;
|
||||
|
|
|
|||
27
lang/en.json
27
lang/en.json
|
|
@ -86,7 +86,8 @@
|
|||
"SecondaryEquipWhileTwohanded": "A secondary weapon can't be equipped together with a Two-Handed weapon.",
|
||||
"TwohandedEquipWhileSecondary": "Can't equip a Two-Handed weapon together with a secondary weapon.",
|
||||
"SelectClassBeforeSubclass": "Select a Class before selecting a Subclass.",
|
||||
"SubclassNotOfClass": "This Subclass doesn't belong to your current Class."
|
||||
"SubclassNotOfClass": "This Subclass doesn't belong to your current Class.",
|
||||
"AttackTargetDoesNotExist": "The target token no longer exists"
|
||||
},
|
||||
"Error": {
|
||||
"NoClassSelected": "Your character has no class selected!",
|
||||
|
|
@ -101,8 +102,14 @@
|
|||
"Hope": "Hope",
|
||||
"Fear": "Fear",
|
||||
"CriticalSuccess": "Critical Success",
|
||||
"Advantage": "Advantage",
|
||||
"Disadvantage": "Disadvantage",
|
||||
"Advantage": {
|
||||
"Full": "Advantage",
|
||||
"Short": "Adv"
|
||||
},
|
||||
"Disadvantage": {
|
||||
"Full": "Disadvantage",
|
||||
"Short": "Dis"
|
||||
},
|
||||
"OK": "OK",
|
||||
"Cancel": "Cancel",
|
||||
"Or": "Or",
|
||||
|
|
@ -704,6 +711,9 @@
|
|||
"Title": "{actor} - Death Move",
|
||||
"TakeMove": "Take Death Move"
|
||||
},
|
||||
"RollSelection": {
|
||||
"Title": "Roll Options"
|
||||
},
|
||||
"Settings": {
|
||||
"Title": "Daggerheart Settings"
|
||||
},
|
||||
|
|
@ -725,9 +735,14 @@
|
|||
},
|
||||
"Chat": {
|
||||
"DualityRoll": {
|
||||
"AdvantageChooseTitle": "Select Hope Dice"
|
||||
"AbilityCheckTitle": "{ability} Check"
|
||||
},
|
||||
"AttackRoll": {
|
||||
"Title": "Attack - {attack}"
|
||||
},
|
||||
"DamageRoll": {
|
||||
"Title": "Damage - {damage}",
|
||||
"DealDamageToTargets": "Damage Hit Targets",
|
||||
"DealDamage": "Deal Damage"
|
||||
},
|
||||
"HealingRoll": {
|
||||
|
|
@ -879,8 +894,8 @@
|
|||
"Stress": "Stress",
|
||||
"Experience": "Experience",
|
||||
"Experiences": "Experiences",
|
||||
"Moves": "Moves",
|
||||
"NewMove": "New Move"
|
||||
"Features": "Features",
|
||||
"NewFeature": "New Feature"
|
||||
},
|
||||
"Environment": {
|
||||
"ToneAndFeel": "Tone And feel",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
export default class DhpChatMesssage extends ChatMessage {
|
||||
async renderHTML() {
|
||||
if (this.type === 'dualityRoll' || this.type === 'adversaryRoll' || this.type === 'abilityUse') {
|
||||
if (
|
||||
this.type === 'dualityRoll' ||
|
||||
this.type === 'adversaryRoll' ||
|
||||
this.type === 'damageRoll' ||
|
||||
this.type === 'abilityUse'
|
||||
) {
|
||||
this.content = await foundry.applications.handlebars.renderTemplate(this.content, this.system);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
|
||||
export default class DamageSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(rollString, bonusDamage, hope, resolve) {
|
||||
constructor(rollString, bonusDamage, resolve, hope = 0) {
|
||||
super({});
|
||||
|
||||
this.data = {
|
||||
|
|
@ -122,64 +122,3 @@ export default class DamageSelectionDialog extends HandlebarsApplicationMixin(Ap
|
|||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
// export default class DamageSelectionDialog extends FormApplication {
|
||||
// constructor(rollString, bonusDamage, resolve){
|
||||
// super({}, {});
|
||||
|
||||
// this.data = {
|
||||
// rollString,
|
||||
// bonusDamage: bonusDamage.map(x => ({
|
||||
// ...x,
|
||||
// hopeUses: 0
|
||||
// })),
|
||||
// }
|
||||
// this.resolve = resolve;
|
||||
// }
|
||||
|
||||
// get title (){
|
||||
// return 'Damage Options';
|
||||
// }
|
||||
|
||||
// static get defaultOptions() {
|
||||
// const defaults = super.defaultOptions;
|
||||
// const overrides = {
|
||||
// height: 'auto',
|
||||
// width: 400,
|
||||
// id: 'damage-selection',
|
||||
// template: 'systems/daggerheart/templates/views/damageSelection.hbs',
|
||||
// closeOnSubmit: false,
|
||||
// classes: ["daggerheart", "views", "damage-selection"],
|
||||
// };
|
||||
|
||||
// const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
|
||||
|
||||
// return mergedOptions;
|
||||
// }
|
||||
|
||||
// async getData(){
|
||||
// const context = super.getData();
|
||||
// context.rollString = this.data.rollString;
|
||||
// context.bonusDamage = this.data.bonusDamage;
|
||||
|
||||
// return context;
|
||||
// }
|
||||
|
||||
// activateListeners(html) {
|
||||
// super.activateListeners(html);
|
||||
|
||||
// html.find('.roll-button').click(this.finish.bind(this));
|
||||
// html.find('.').change();
|
||||
// }
|
||||
|
||||
// // async _updateObject(_, formData) {
|
||||
// // const data = foundry.utils.expandObject(formData);
|
||||
// // this.data = foundry.utils.mergeObject(this.data, data);
|
||||
// // this.render(true);
|
||||
// // }
|
||||
|
||||
// finish(){
|
||||
// this.resolve(this.data);
|
||||
// this.close();
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -1,81 +1,79 @@
|
|||
export default class NpcRollSelectionDialog extends FormApplication {
|
||||
constructor(experiences, resolve, isNpc) {
|
||||
super({}, {});
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class NpcRollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(experiences, resolve, reject) {
|
||||
super({});
|
||||
|
||||
this.experiences = experiences;
|
||||
this.resolve = resolve;
|
||||
this.reject = reject;
|
||||
this.selectedExperiences = [];
|
||||
this.data = {
|
||||
nrDice: 1,
|
||||
advantage: null
|
||||
};
|
||||
}
|
||||
|
||||
get title() {
|
||||
return 'Roll Options';
|
||||
return game.i18n.localize('DAGGERHEART.Application.Settings.Title');
|
||||
}
|
||||
|
||||
static get defaultOptions() {
|
||||
const defaults = super.defaultOptions;
|
||||
const overrides = {
|
||||
height: 'auto',
|
||||
width: 400,
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
id: 'roll-selection',
|
||||
template: 'systems/daggerheart/templates/views/npcRollSelection.hbs',
|
||||
closeOnSubmit: false,
|
||||
submitOnChange: true,
|
||||
classes: ['daggerheart', 'views', 'npc-roll-selection']
|
||||
classes: ['daggerheart', 'views', 'npc-roll-selection'],
|
||||
position: { width: '500', height: 'auto' },
|
||||
actions: {
|
||||
updateIsAdvantage: this.updateIsAdvantage,
|
||||
selectExperience: this.selectExperience
|
||||
},
|
||||
form: { handler: this.updateData, submitOnChange: false }
|
||||
};
|
||||
|
||||
const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
|
||||
|
||||
return mergedOptions;
|
||||
static PARTS = {
|
||||
main: {
|
||||
id: 'main',
|
||||
template: 'systems/daggerheart/templates/views/npcRollSelection.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
async getData() {
|
||||
const context = super.getData();
|
||||
context.nrDice = this.data.nrDice;
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.advantage = this.data.advantage;
|
||||
context.experiences = this.experiences.map(x => ({
|
||||
context.experiences = Object.values(this.experiences).map(x => ({
|
||||
...x,
|
||||
selected: this.selectedExperiences.find(selected => selected.id === x.id)
|
||||
selected: this.selectedExperiences.find(selected => selected.id === x.id),
|
||||
value: `${x.value >= 0 ? '+' : '-'}${x.value}`
|
||||
}));
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
html.find('.increase').click(_ => this.updateNrDice(1));
|
||||
html.find('.decrease').click(_ => this.updateNrDice(-1));
|
||||
html.find('.advantage').click(_ => this.updateIsAdvantage(true));
|
||||
html.find('.disadvantage').click(_ => this.updateIsAdvantage(false));
|
||||
html.find('.roll-button').click(this.finish.bind(this));
|
||||
html.find('.roll-dialog-chip').click(this.selectExperience.bind(this));
|
||||
}
|
||||
|
||||
updateNrDice(value) {
|
||||
this.data.nrDice += value;
|
||||
this.render();
|
||||
}
|
||||
|
||||
updateIsAdvantage(advantage) {
|
||||
static updateIsAdvantage(_, button) {
|
||||
const advantage = Boolean(button.dataset.advantage);
|
||||
this.data.advantage = this.data.advantage === advantage ? null : advantage;
|
||||
this.render();
|
||||
}
|
||||
|
||||
selectExperience(event) {
|
||||
const experience = this.experiences[event.currentTarget.dataset.key];
|
||||
this.selectedExperiences = this.selectedExperiences.find(x => x.name === experience.name)
|
||||
? this.selectedExperiences.filter(x => x.name !== experience.name)
|
||||
static selectExperience(_, button) {
|
||||
const experience = Object.values(this.experiences).find(experience => experience.id === button.id);
|
||||
this.selectedExperiences = this.selectedExperiences.find(x => x.id === experience.id)
|
||||
? this.selectedExperiences.filter(x => x.id !== experience.id)
|
||||
: [...this.selectedExperiences, experience];
|
||||
|
||||
this.render();
|
||||
}
|
||||
|
||||
finish() {
|
||||
static async updateData() {
|
||||
this.resolve({ ...this.data, experiences: this.selectedExperiences });
|
||||
this.close();
|
||||
this.close({ updateClose: true });
|
||||
}
|
||||
|
||||
async close(options = {}) {
|
||||
const { updateClose, ...baseOptions } = options;
|
||||
if (!updateClose) {
|
||||
this.reject();
|
||||
}
|
||||
|
||||
await super.close(baseOptions);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
|||
};
|
||||
|
||||
get title() {
|
||||
return `Roll Options`;
|
||||
return game.i18n.localize('DAGGERHEART.Application.RollSelection.Title');
|
||||
}
|
||||
|
||||
async _prepareContext(_options) {
|
||||
|
|
@ -157,134 +157,3 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
|
|||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
// V1.3
|
||||
// const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
|
||||
// export default class RollSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
// constructor(experiences, bonusDamage, hopeResource, resolve, isNpc){
|
||||
// super({}, {});
|
||||
|
||||
// this.experiences = experiences;
|
||||
// this.resolve = resolve;
|
||||
// this.isNpc;
|
||||
// this.selectedExperiences = [];
|
||||
// this.data = {
|
||||
// diceOptions: [{ name: 'd12', value: 'd12' }, { name: 'd20', value: 'd20' }],
|
||||
// hope: ['d12'],
|
||||
// fear: ['d12'],
|
||||
// advantage: null,
|
||||
// disadvantage: null,
|
||||
// bonusDamage: bonusDamage.reduce((acc, x) => {
|
||||
// if(x.appliesOn === SYSTEM.EFFECTS.applyLocations.attackRoll.id){
|
||||
// acc.push(({
|
||||
// ...x,
|
||||
// hopeUses: 0
|
||||
// }));
|
||||
// }
|
||||
|
||||
// return acc;
|
||||
// }, []),
|
||||
// hopeResource: hopeResource,
|
||||
// };
|
||||
// }
|
||||
|
||||
// static DEFAULT_OPTIONS = {
|
||||
// tag: 'form',
|
||||
// classes: ["daggerheart", "views", "roll-selection"],
|
||||
// position: {
|
||||
// width: 400,
|
||||
// height: "auto"
|
||||
// },
|
||||
// actions: {
|
||||
// selectExperience: this.selectExperience,
|
||||
// decreaseHopeUse: this.decreaseHopeUse,
|
||||
// increaseHopeUse: this.increaseHopeUse,
|
||||
// finish: this.finish,
|
||||
// },
|
||||
// form: {
|
||||
// handler: this.updateSelection,
|
||||
// submitOnChange: true,
|
||||
// closeOnSubmit: false,
|
||||
// }
|
||||
// };
|
||||
|
||||
// /** @override */
|
||||
// static PARTS = {
|
||||
// damageSelection: {
|
||||
// id: "damageSelection",
|
||||
// template: "systems/daggerheart/templates/views/rollSelection.hbs"
|
||||
// }
|
||||
// }
|
||||
|
||||
// get title() {
|
||||
// return `Roll Options`;
|
||||
// }
|
||||
|
||||
// async _prepareContext(_options) {
|
||||
// const context = await super._prepareContext(_options);
|
||||
// context.isNpc = this.isNpc;
|
||||
// context.diceOptions = this.data.diceOptions;
|
||||
// context.hope = this.data.hope;
|
||||
// context.fear = this.data.fear;
|
||||
// context.advantage = this.data.advantage;
|
||||
// context.disadvantage = this.data.disadvantage;
|
||||
// context.experiences = this.experiences.map(x => ({ ...x, selected: this.selectedExperiences.find(selected => selected.id === x.id) }));
|
||||
// context.bonusDamage = this.data.bonusDamage;
|
||||
// context.hopeResource = this.data.hopeResource+1;
|
||||
// context.hopeUsed = this.getHopeUsed();
|
||||
|
||||
// return context;
|
||||
// }
|
||||
|
||||
// static updateSelection(event, _, formData){
|
||||
// const { bonusDamage, ...rest } = foundry.utils.expandObject(formData.object);
|
||||
|
||||
// for(var index in bonusDamage){
|
||||
// this.data.bonusDamage[index].initiallySelected = bonusDamage[index].initiallySelected;
|
||||
// if(bonusDamage[index].hopeUses){
|
||||
// const value = Number.parseInt(bonusDamage[index].hopeUses);
|
||||
// if(!Number.isNaN(value)) this.data.bonusDamage[index].hopeUses = value;
|
||||
// }
|
||||
// }
|
||||
|
||||
// this.data = foundry.utils.mergeObject(this.data, rest);
|
||||
// this.render(true);
|
||||
// }
|
||||
|
||||
// static selectExperience(_, button){
|
||||
// if(this.selectedExperiences.find(x => x.id === button.dataset.key)){
|
||||
// this.selectedExperiences = this.selectedExperiences.filter(x => x.id !== button.dataset.key);
|
||||
// } else {
|
||||
// this.selectedExperiences = [...this.selectedExperiences, this.experiences.find(x => x.id === button.dataset.key)];
|
||||
// }
|
||||
|
||||
// this.render();
|
||||
// }
|
||||
|
||||
// getHopeUsed(){
|
||||
// return this.data.bonusDamage.reduce((acc, x) => acc+x.hopeUses, 0);
|
||||
// }
|
||||
|
||||
// static decreaseHopeUse(_, button){
|
||||
// const index = Number.parseInt(button.dataset.index);
|
||||
// if(this.data.bonusDamage[index].hopeUses - 1 >= 0) {
|
||||
// this.data.bonusDamage[index].hopeUses -= 1;
|
||||
// this.render(true);
|
||||
// }
|
||||
// }
|
||||
|
||||
// static increaseHopeUse(_, button){
|
||||
// const index = Number.parseInt(button.dataset.index);
|
||||
// if(this.data.bonusDamage[index].hopeUses <= this.data.hopeResource+1) {
|
||||
// this.data.bonusDamage[index].hopeUses += 1;
|
||||
// this.render(true);
|
||||
// }
|
||||
// }
|
||||
|
||||
// static finish(){
|
||||
// const { diceOptions, ...rest } = this.data;
|
||||
// this.resolve({ ...rest, experiences: this.selectedExperiences, hopeUsed: this.getHopeUsed(), bonusDamage: this.data.bonusDamage.reduce((acc, x) => acc.concat(` + ${1+x.hopeUses}${x.value}`), "") });
|
||||
// this.close();
|
||||
// }
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -349,7 +349,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
static async attackRoll(event, button) {
|
||||
const modifier = Number.parseInt(button.dataset.value);
|
||||
|
||||
const { roll, diceResults, modifiers } = await this.actor.diceRoll(
|
||||
const { roll, dice, advantageState, modifiers } = await this.actor.diceRoll(
|
||||
{ title: `${this.actor.name} - Attack Roll`, value: modifier },
|
||||
event.shiftKey
|
||||
);
|
||||
|
|
@ -365,11 +365,15 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
const cls = getDocumentClass('ChatMessage');
|
||||
const msg = new cls({
|
||||
type: 'adversaryRoll',
|
||||
sound: CONFIG.sounds.dice,
|
||||
system: {
|
||||
title: button.dataset.name,
|
||||
origin: this.document.id,
|
||||
roll: roll._formula,
|
||||
advantageState,
|
||||
total: roll._total,
|
||||
modifiers: modifiers,
|
||||
diceResults: diceResults,
|
||||
dice: dice,
|
||||
targets: targets,
|
||||
damage: { value: button.dataset.damage, type: button.dataset.damageType }
|
||||
},
|
||||
|
|
@ -381,16 +385,15 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
}
|
||||
|
||||
static async addExperience() {
|
||||
const experienceId = foundry.utils.randomID();
|
||||
await this.document.update({
|
||||
'system.experiences': [...this.document.system.experiences, { name: 'Experience', value: 1 }]
|
||||
[`system.experiences.${experienceId}`]: { id: experienceId, name: 'Experience', value: 1 }
|
||||
});
|
||||
}
|
||||
|
||||
static async removeExperience(_, button) {
|
||||
await this.document.update({
|
||||
'system.experiences': this.document.system.experiences.filter(
|
||||
(_, index) => index !== Number.parseInt(button.dataset.experience)
|
||||
)
|
||||
[`system.experiences.-=${button.dataset.experience}`]: null
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import DhpDowntime from '../downtime.mjs';
|
|||
import DhpLevelup from '../levelup.mjs';
|
||||
import AncestrySelectionDialog from '../ancestrySelectionDialog.mjs';
|
||||
import DaggerheartSheet from './daggerheart-sheet.mjs';
|
||||
import { abilities } from '../../config/actorConfig.mjs';
|
||||
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
const { TextEditor } = foundry.applications.ux;
|
||||
|
|
@ -481,9 +482,9 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
this.render();
|
||||
}
|
||||
|
||||
static async rollAttribute(event, target) {
|
||||
static async rollAttribute(event, button) {
|
||||
const { roll, hope, fear, advantage, disadvantage, modifiers } = await this.document.dualityRoll(
|
||||
{ title: 'Attribute Bonus', value: event.target.dataset.value },
|
||||
{ title: 'Attribute Bonus', value: button.dataset.value },
|
||||
event.shiftKey
|
||||
);
|
||||
|
||||
|
|
@ -491,6 +492,10 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
const msgData = {
|
||||
type: 'dualityRoll',
|
||||
system: {
|
||||
title: game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', {
|
||||
ability: game.i18n.localize(abilities[button.dataset.attribute].label)
|
||||
}),
|
||||
origin: this.document.id,
|
||||
roll: roll._formula,
|
||||
modifiers: modifiers,
|
||||
hope: hope,
|
||||
|
|
@ -551,8 +556,8 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
await this.document.update({ [update]: newValue });
|
||||
}
|
||||
|
||||
static async attackRoll(_, event) {
|
||||
const weapon = await fromUuid(event.currentTarget.dataset.weapon);
|
||||
static async attackRoll(event, button) {
|
||||
const weapon = await fromUuid(button.dataset.weapon);
|
||||
const damage = {
|
||||
value: `${this.document.system.proficiency.value}${weapon.system.damage.value}`,
|
||||
type: weapon.system.damage.type,
|
||||
|
|
@ -580,7 +585,10 @@ export default class PCSheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
const cls = getDocumentClass('ChatMessage');
|
||||
const msg = new cls({
|
||||
type: 'dualityRoll',
|
||||
sound: CONFIG.sounds.dice,
|
||||
system: {
|
||||
title: weapon.name,
|
||||
origin: this.document.id,
|
||||
roll: roll._formula,
|
||||
modifiers: modifiers,
|
||||
hope: hope,
|
||||
|
|
|
|||
|
|
@ -14,5 +14,6 @@ export { default as DhpWeapon } from './weapon.mjs';
|
|||
export { default as DhpArmor } from './armor.mjs';
|
||||
export { default as DhpDualityRoll } from './dualityRoll.mjs';
|
||||
export { default as DhpAdversaryRoll } from './adversaryRoll.mjs';
|
||||
export { default as DhpDamageRoll } from './damageRoll.mjs';
|
||||
export { default as DhpAbilityUse } from './abilityUse.mjs';
|
||||
export { default as DhpEnvironment } from './environment.mjs';
|
||||
|
|
|
|||
|
|
@ -33,20 +33,20 @@ export default class DhpAdversary extends foundry.abstract.TypeDataModel {
|
|||
}),
|
||||
difficulty: new fields.NumberField({ initial: 1, integer: true }),
|
||||
damageThresholds: new fields.SchemaField({
|
||||
minor: new fields.NumberField({ initial: 0, integer: true }),
|
||||
major: new fields.NumberField({ initial: 0, integer: true }),
|
||||
severe: new fields.NumberField({ initial: 0, integer: true })
|
||||
}),
|
||||
experiences: new fields.ArrayField(
|
||||
experiences: new fields.TypedObjectField(
|
||||
new fields.SchemaField({
|
||||
name: new fields.StringField({}),
|
||||
id: new fields.StringField({ required: true }),
|
||||
name: new fields.StringField(),
|
||||
value: new fields.NumberField({ integer: true, nullable: true, initial: null })
|
||||
})
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
get moves() {
|
||||
get features() {
|
||||
return this.parent.items.filter(x => x.type === 'feature');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ export default class DhpAdversaryRoll extends foundry.abstract.TypeDataModel {
|
|||
const fields = foundry.data.fields;
|
||||
|
||||
return {
|
||||
title: new fields.StringField(),
|
||||
origin: new fields.StringField({ required: true }),
|
||||
roll: new fields.StringField({}),
|
||||
total: new fields.NumberField({ integer: true }),
|
||||
modifiers: new fields.ArrayField(
|
||||
|
|
@ -12,12 +14,8 @@ export default class DhpAdversaryRoll extends foundry.abstract.TypeDataModel {
|
|||
title: new fields.StringField({})
|
||||
})
|
||||
),
|
||||
diceResults: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
value: new fields.NumberField({ integer: true }),
|
||||
discarded: new fields.BooleanField({ initial: false })
|
||||
})
|
||||
),
|
||||
advantageState: new fields.NumberField({ required: true, choices: [0, 1, 2], initial: 0 }),
|
||||
dice: new fields.EmbeddedDataField(DhpAdversaryRollDice),
|
||||
targets: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({}),
|
||||
|
|
@ -39,17 +37,18 @@ export default class DhpAdversaryRoll extends foundry.abstract.TypeDataModel {
|
|||
}
|
||||
|
||||
prepareDerivedData() {
|
||||
const diceKeys = Object.keys(this.diceResults);
|
||||
const highestIndex = 0;
|
||||
for (var index in diceKeys) {
|
||||
const resultIndex = Number.parseInt(index);
|
||||
if (highestIndex === resultIndex) continue;
|
||||
|
||||
const current = this.diceResults[resultIndex];
|
||||
const highest = this.diceResults[highestIndex];
|
||||
|
||||
if (current.value > highest.value) this.diceResults[highestIndex].discarded = true;
|
||||
else this.diceResults[resultIndex].discarded = true;
|
||||
const diceKeys = Object.keys(this.dice.rolls);
|
||||
const highestDiceIndex =
|
||||
diceKeys.length < 2
|
||||
? null
|
||||
: this.dice.rolls[diceKeys[0]].value > this.dice.rolls[diceKeys[1]].value
|
||||
? 0
|
||||
: 1;
|
||||
if (highestDiceIndex !== null) {
|
||||
this.dice.rolls = this.dice.rolls.map((roll, index) => ({
|
||||
...roll,
|
||||
discarded: this.advantageState === 1 ? index !== highestDiceIndex : index === highestDiceIndex
|
||||
}));
|
||||
}
|
||||
|
||||
this.targets.forEach(target => {
|
||||
|
|
@ -57,3 +56,23 @@ export default class DhpAdversaryRoll extends foundry.abstract.TypeDataModel {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
class DhpAdversaryRollDice extends foundry.abstract.DataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
return {
|
||||
type: new fields.StringField({ required: true }),
|
||||
rolls: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
value: new fields.NumberField({ required: true, integer: true }),
|
||||
discarded: new fields.BooleanField({ initial: false })
|
||||
})
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
get rollTotal() {
|
||||
return this.rolls.reduce((acc, roll) => acc + (!roll.discarded ? roll.value : 0), 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
43
module/data/damageRoll.mjs
Normal file
43
module/data/damageRoll.mjs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
export default class DhpDamageRoll extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
return {
|
||||
title: new fields.StringField(),
|
||||
roll: new fields.StringField({ required: true }),
|
||||
damage: new fields.SchemaField({
|
||||
total: new fields.NumberField({ required: true, integer: true }),
|
||||
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false })
|
||||
}),
|
||||
dice: new fields.ArrayField(new fields.EmbeddedDataField(DhpDamageDice)),
|
||||
modifiers: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
value: new fields.NumberField({ required: true, integer: true }),
|
||||
operator: new fields.StringField({ required: true, choices: ['+', '-', '*', '/'] })
|
||||
})
|
||||
),
|
||||
targets: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({ required: true }),
|
||||
name: new fields.StringField(),
|
||||
img: new fields.StringField()
|
||||
})
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class DhpDamageDice extends foundry.abstract.DataModel {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
return {
|
||||
type: new fields.StringField({ required: true }),
|
||||
rolls: new fields.ArrayField(new fields.NumberField({ required: true, integer: true }))
|
||||
};
|
||||
}
|
||||
|
||||
get rollTotal() {
|
||||
return this.rolls.reduce((acc, roll) => acc + roll, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@ const diceField = () =>
|
|||
export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
|
||||
static defineSchema() {
|
||||
return {
|
||||
title: new fields.StringField(),
|
||||
origin: new fields.StringField({ required: true }),
|
||||
roll: new fields.StringField({}),
|
||||
modifiers: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
|
|
@ -20,7 +22,6 @@ export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
|
|||
fear: diceField(),
|
||||
advantage: diceField(),
|
||||
disadvantage: diceField(),
|
||||
advantageSelected: new fields.NumberField({ initial: 0 }),
|
||||
targets: new fields.ArrayField(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({}),
|
||||
|
|
@ -57,8 +58,16 @@ export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
|
|||
|
||||
get total() {
|
||||
const modifiers = this.modifiers.reduce((acc, x) => acc + x.value, 0);
|
||||
const advantage = (this.advantage.value ?? this.disadvantage.value) ? -this.disadvantage.value : 0;
|
||||
return this.hope.value + this.fear.value + advantage + modifiers;
|
||||
const advantage = this.advantage.value
|
||||
? this.advantage.value
|
||||
: this.disadvantage.value
|
||||
? -this.disadvantage.value
|
||||
: 0;
|
||||
return this.highestRoll + advantage + modifiers;
|
||||
}
|
||||
|
||||
get highestRoll() {
|
||||
return Math.max(this.hope.value, this.fear.value);
|
||||
}
|
||||
|
||||
get totalLabel() {
|
||||
|
|
@ -75,6 +84,9 @@ export default class DhpDualityRoll extends foundry.abstract.TypeDataModel {
|
|||
prepareDerivedData() {
|
||||
const total = this.total;
|
||||
|
||||
this.hope.discarded = this.hope.value < this.fear.value;
|
||||
this.fear.discarded = this.fear.value < this.hope.value;
|
||||
|
||||
this.targets.forEach(target => {
|
||||
target.hit = target.difficulty ? total >= target.difficulty : total >= target.evasion;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
|
||||
async npcRoll(modifier, shiftKey) {
|
||||
let nrDice = 1;
|
||||
let advantage = null;
|
||||
|
||||
const modifiers = [
|
||||
|
|
@ -84,7 +83,6 @@ export default class DhpActor extends Actor {
|
|||
});
|
||||
const result = await dialogClosed;
|
||||
|
||||
nrDice = result.nrDice;
|
||||
advantage = result.advantage;
|
||||
result.experiences.forEach(x =>
|
||||
modifiers.push({
|
||||
|
|
@ -95,13 +93,20 @@ export default class DhpActor extends Actor {
|
|||
);
|
||||
}
|
||||
|
||||
const roll = new Roll(
|
||||
`${nrDice}d20${advantage === true ? 'kh' : advantage === false ? 'kl' : ''} ${modifiers.map(x => `+ ${x.value}`).join(' ')}`
|
||||
const roll = Roll.create(
|
||||
`${advantage === true || advantage === false ? 2 : 1}d20${advantage === true ? 'kh' : advantage === false ? 'kl' : ''} ${modifiers.map(x => `+ ${x.value}`).join(' ')}`
|
||||
);
|
||||
let rollResult = await roll.evaluate();
|
||||
const diceResults = rollResult.dice.flatMap(x => x.results.flatMap(result => ({ value: result.result })));
|
||||
const dice = [];
|
||||
for (var i = 0; i < rollResult.terms.length; i++) {
|
||||
const term = rollResult.terms[i];
|
||||
if (term.faces) {
|
||||
dice.push({ type: `d${term.faces}`, rolls: term.results.map(x => ({ value: x.result })) });
|
||||
}
|
||||
}
|
||||
|
||||
return { roll, diceResults: diceResults, modifiers: modifiers };
|
||||
// There is Only ever one dice term here
|
||||
return { roll, dice: dice[0], modifiers, advantageState: advantage === true ? 1 : advantage === false ? 2 : 0 };
|
||||
}
|
||||
|
||||
async dualityRoll(modifier, shiftKey, bonusDamage = []) {
|
||||
|
|
@ -202,10 +207,9 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
|
||||
const hope = rollResult.dice[0].results[0].result;
|
||||
const advantage = advantageDice ? rollResult.dice[1].results[0].result : null;
|
||||
const disadvantage = disadvantageDice ? rollResult.dice[1].results[0].result : null;
|
||||
const fear =
|
||||
advantage || disadvantage ? rollResult.dice[2].results[0].result : rollResult.dice[1].results[0].result;
|
||||
const fear = rollResult.dice[1].results[0].result;
|
||||
const advantage = advantageDice ? rollResult.dice[2].results[0].result : null;
|
||||
const disadvantage = disadvantageDice ? rollResult.dice[2].results[0].result : null;
|
||||
|
||||
if (disadvantage) {
|
||||
rollResult = { ...rollResult, total: rollResult.total - Math.max(hope, disadvantage) };
|
||||
|
|
@ -245,14 +249,12 @@ export default class DhpActor extends Actor {
|
|||
};
|
||||
}
|
||||
|
||||
async damageRoll(damage, shiftKey) {
|
||||
async damageRoll(title, damage, targets, shiftKey) {
|
||||
let rollString = damage.value;
|
||||
let bonusDamage = damage.bonusDamage?.filter(x => x.initiallySelected) ?? [];
|
||||
if (!shiftKey) {
|
||||
const dialogClosed = new Promise((resolve, _) => {
|
||||
new DamageSelectionDialog(rollString, bonusDamage, this.system.resources.hope.value, resolve).render(
|
||||
true
|
||||
);
|
||||
new DamageSelectionDialog(rollString, bonusDamage, resolve).render(true);
|
||||
});
|
||||
const result = await dialogClosed;
|
||||
bonusDamage = result.bonusDamage;
|
||||
|
|
@ -274,23 +276,31 @@ export default class DhpActor extends Actor {
|
|||
for (var i = 0; i < rollResult.terms.length; i++) {
|
||||
const term = rollResult.terms[i];
|
||||
if (term.faces) {
|
||||
dice.push({ type: `d${term.faces}`, value: term.total });
|
||||
dice.push({ type: `d${term.faces}`, rolls: term.results.map(x => x.result) });
|
||||
} else if (term.operator) {
|
||||
} else if (term.number) {
|
||||
const operator = i === 0 ? '' : rollResult.terms[i - 1].operator;
|
||||
modifiers.push(`${operator}${term.number}`);
|
||||
modifiers.push({ value: term.number, operator: operator });
|
||||
}
|
||||
}
|
||||
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const msg = new cls({
|
||||
type: 'damageRoll',
|
||||
user: game.user.id,
|
||||
content: await renderTemplate('systems/daggerheart/templates/chat/damage-roll.hbs', {
|
||||
sound: CONFIG.sounds.dice,
|
||||
system: {
|
||||
title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: title }),
|
||||
roll: rollString,
|
||||
damage: {
|
||||
total: rollResult.total,
|
||||
type: damage.type
|
||||
},
|
||||
dice: dice,
|
||||
modifiers: modifiers
|
||||
}),
|
||||
modifiers: modifiers,
|
||||
targets: targets
|
||||
},
|
||||
content: 'systems/daggerheart/templates/chat/damage-roll.hbs',
|
||||
rolls: [roll]
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -17,16 +17,21 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
html.querySelectorAll('.roll-damage-button').forEach(element =>
|
||||
element.addEventListener('click', event => this.onRollDamage(event, data.message))
|
||||
);
|
||||
html.querySelectorAll('.target-container').forEach(element =>
|
||||
element.addEventListener('hover', hover(this.hoverTarget, this.unhoverTarget))
|
||||
); // ????
|
||||
// html.find('.target-container').mouseout(this.unhoverTarget);
|
||||
html.querySelectorAll('.damage-button').forEach(element => element.addEventListener('click', this.onDamage));
|
||||
html.querySelectorAll('.target-container').forEach(element => {
|
||||
element.addEventListener('mouseenter', this.hoverTarget);
|
||||
element.addEventListener('mouseleave', this.unhoverTarget);
|
||||
element.addEventListener('click', this.clickTarget);
|
||||
});
|
||||
html.querySelectorAll('.damage-button').forEach(element =>
|
||||
element.addEventListener('click', event => this.onDamage(event, data.message))
|
||||
);
|
||||
html.querySelectorAll('.healing-button').forEach(element => element.addEventListener('click', this.onHealing));
|
||||
html.querySelectorAll('.target-indicator').forEach(element =>
|
||||
element.addEventListener('click', this.onToggleTargets)
|
||||
);
|
||||
html.querySelectorAll('.advantage').forEach(element => element.hover(this.hoverAdvantage)); // ??
|
||||
html.querySelectorAll('.advantage').forEach(element =>
|
||||
element.addEventListener('mouseenter', this.hoverAdvantage)
|
||||
);
|
||||
html.querySelectorAll('.advantage').forEach(element =>
|
||||
element.addEventListener('click', event => this.selectAdvantage.bind(this)(event, data.message))
|
||||
);
|
||||
|
|
@ -46,31 +51,50 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
|
||||
onRollDamage = async (event, message) => {
|
||||
event.stopPropagation();
|
||||
const actor = game.actors.get(message.system.origin);
|
||||
if (!actor || !game.user.isGM) return true;
|
||||
|
||||
await game.user.character.damageRoll(message.system.damage, event.shiftKey);
|
||||
await actor.damageRoll(
|
||||
message.system.title,
|
||||
message.system.damage,
|
||||
message.system.targets.filter(x => x.hit).map(x => ({ id: x.id, name: x.name, img: x.img })),
|
||||
event.shiftKey
|
||||
);
|
||||
};
|
||||
|
||||
hoverTarget = event => {
|
||||
event.stopPropagation();
|
||||
const token = canvas.tokens.get(event.currentTarget.dataset.token);
|
||||
if (!token.controlled) token._onHoverIn(event, { hoverOutOthers: true });
|
||||
if (!token?.controlled) token._onHoverIn(event, { hoverOutOthers: true });
|
||||
};
|
||||
|
||||
unhoverTarget = event => {
|
||||
const token = canvas.tokens.get(event.currentTarget.dataset.token);
|
||||
if (!token.controlled) token._onHoverOut(event);
|
||||
if (!token?.controlled) token._onHoverOut(event);
|
||||
};
|
||||
|
||||
onDamage = async event => {
|
||||
clickTarget = event => {
|
||||
event.stopPropagation();
|
||||
const damage = Number.parseInt(event.currentTarget.dataset.value);
|
||||
const targets = Array.from(game.user.targets);
|
||||
const token = canvas.tokens.get(event.currentTarget.dataset.token);
|
||||
if (!token) {
|
||||
ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.AttackTargetDoesNotExist'));
|
||||
return;
|
||||
}
|
||||
|
||||
game.canvas.pan(token);
|
||||
};
|
||||
|
||||
onDamage = async (event, message) => {
|
||||
event.stopPropagation();
|
||||
const targets = event.currentTarget.dataset.targetHit
|
||||
? message.system.targets.map(target => game.canvas.tokens.get(target.id))
|
||||
: Array.from(game.user.targets);
|
||||
|
||||
if (targets.length === 0)
|
||||
ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.NoTargetsSelected'));
|
||||
|
||||
for (var target of targets) {
|
||||
await target.actor.takeDamage(damage, event.currentTarget.dataset.type);
|
||||
await target.actor.takeDamage(message.system.damage.total, message.system.damage.type);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "yKicceU4LesCgKwF",
|
||||
"img": "systems/daggerheart/assets/icons/classes/bard.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"grace",
|
||||
"codex"
|
||||
],
|
||||
"domains": ["grace", "codex"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "HEh27jDQCJmnPsXH",
|
||||
"img": "systems/daggerheart/assets/icons/classes/druid.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"sage",
|
||||
"arcana"
|
||||
],
|
||||
"domains": ["sage", "arcana"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "HPzaWaZBc6RvElKd",
|
||||
"img": "systems/daggerheart/assets/icons/classes/fighter.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"bone",
|
||||
"valor"
|
||||
],
|
||||
"domains": ["bone", "valor"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "hyfigmrAoLxFPOW2",
|
||||
"img": "systems/daggerheart/assets/icons/classes/guardian.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"valor",
|
||||
"blade"
|
||||
],
|
||||
"domains": ["valor", "blade"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "XoUsU9sCxEq8t3We",
|
||||
"img": "systems/daggerheart/assets/icons/classes/ranger.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"bone",
|
||||
"sage"
|
||||
],
|
||||
"domains": ["bone", "sage"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "V1a5AKCLe8qtoPlA",
|
||||
"img": "systems/daggerheart/assets/icons/classes/rogue.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"midnight",
|
||||
"grace"
|
||||
],
|
||||
"domains": ["midnight", "grace"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "qW7yLIe87vd5bbto",
|
||||
"img": "systems/daggerheart/assets/icons/classes/seraph.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"splendor",
|
||||
"valor"
|
||||
],
|
||||
"domains": ["splendor", "valor"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "aacMxI9mOTmLO4cj",
|
||||
"img": "systems/daggerheart/assets/icons/classes/sorcerer.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"arcana",
|
||||
"midnight"
|
||||
],
|
||||
"domains": ["arcana", "midnight"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -33,16 +33,8 @@
|
|||
"suggestedSecondaryWeapon": null,
|
||||
"suggestedArmor": null,
|
||||
"characterDescription": {},
|
||||
"backgroundQuestions": [
|
||||
"",
|
||||
"",
|
||||
""
|
||||
],
|
||||
"connections": [
|
||||
"",
|
||||
"",
|
||||
""
|
||||
]
|
||||
"backgroundQuestions": ["", "", ""],
|
||||
"connections": ["", "", ""]
|
||||
},
|
||||
"multiclass": null,
|
||||
"description": ""
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "ishqAXCT8xLgEbBp",
|
||||
"img": "systems/daggerheart/assets/icons/classes/warrior.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"blade",
|
||||
"bone"
|
||||
],
|
||||
"domains": ["blade", "bone"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@
|
|||
"_id": "uhj2mZPOC8nbIMTy",
|
||||
"img": "systems/daggerheart/assets/icons/classes/wizard.png",
|
||||
"system": {
|
||||
"domains": [
|
||||
"codex",
|
||||
"splendor"
|
||||
],
|
||||
"domains": ["codex", "splendor"],
|
||||
"classItems": [],
|
||||
"damageThresholds": {
|
||||
"minor": 0,
|
||||
|
|
|
|||
|
|
@ -296,6 +296,7 @@ div.daggerheart.views.multiclass {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: @fullMargin;
|
||||
gap: 16px;
|
||||
|
||||
.dice-container {
|
||||
display: flex;
|
||||
|
|
@ -306,6 +307,7 @@ div.daggerheart.views.multiclass {
|
|||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
|
|
@ -319,12 +321,24 @@ div.daggerheart.views.multiclass {
|
|||
|
||||
.dice-number {
|
||||
position: absolute;
|
||||
top: calc(50% - 14px);
|
||||
left: calc(50% - 7px);
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.advantage-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
flex: 1;
|
||||
|
||||
.advantage-button {
|
||||
&.active,
|
||||
&:hover {
|
||||
background: var(--button-hover-background-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -333,33 +347,19 @@ div.daggerheart.views.multiclass {
|
|||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
gap: @halfMargin;
|
||||
flex: 2;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
|
||||
.roll-dialog-chip {
|
||||
border: @thinBorder solid black;
|
||||
border-radius: 6px;
|
||||
flex-basis: calc(50% - 2px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
padding: @fullPadding;
|
||||
background: grey;
|
||||
overflow: hidden;
|
||||
|
||||
&.hover {
|
||||
filter: drop-shadow(0 0 3px @mainShadow);
|
||||
}
|
||||
|
||||
span {
|
||||
overflow: hidden;
|
||||
.experience-chip {
|
||||
opacity: 0.6;
|
||||
border-radius: 16px;
|
||||
width: calc(50% - 4px);
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&.selected i {
|
||||
color: green;
|
||||
&.active,
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
background: var(--button-hover-background-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,11 +29,14 @@
|
|||
}
|
||||
|
||||
&.roll {
|
||||
.dice-flavor {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
.dice-tooltip {
|
||||
.dice-rolls {
|
||||
.dice-rolls.duality {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
|
||||
.dice-hope-container {
|
||||
display: flex;
|
||||
|
|
@ -57,12 +60,18 @@
|
|||
-webkit-text-stroke-color: @hope;
|
||||
-webkit-text-stroke-width: 1.5px;
|
||||
font-weight: 400;
|
||||
&:not(.discarded) {
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
&.fear {
|
||||
color: white;
|
||||
-webkit-text-stroke-color: @fear;
|
||||
-webkit-text-stroke-width: 1.5px;
|
||||
font-weight: 400;
|
||||
&:not(.discarded) {
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
&.disadvantage {
|
||||
color: white;
|
||||
|
|
@ -93,6 +102,11 @@
|
|||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.attack-roll-advantage-container {
|
||||
text-align: end;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.dice-total {
|
||||
|
|
@ -159,10 +173,22 @@
|
|||
}
|
||||
}
|
||||
|
||||
.roll-damage-button {
|
||||
.dice-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.dice-result {
|
||||
.roll-damage-button,
|
||||
.damage-button {
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.domain-card {
|
||||
display: flex;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -37,9 +37,10 @@
|
|||
"combat": {}
|
||||
},
|
||||
"ChatMessage": {
|
||||
"types": ["dualityRoll", "adversaryRoll", "abilityUse"],
|
||||
"types": ["dualityRoll", "adversaryRoll", "damageRoll", "abilityUse"],
|
||||
"dualityRoll": {},
|
||||
"adversaryRoll": {},
|
||||
"damageRoll": {},
|
||||
"abilityUse": {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,30 @@
|
|||
<div class="dice-roll daggerheart chat roll">
|
||||
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
||||
<div class="dice-flavor">{{localize "DAGGERHEART.Chat.AttackRoll.Title" attack=this.title}}</div>
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{roll}}</div>
|
||||
<div class="dice-tooltip">
|
||||
<div class="wrapper">
|
||||
<section class="tooltip-part">
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">{{this.dice.rolls.length}}{{this.dice.type}}</span>
|
||||
<span class="part-total">{{this.dice.rollTotal}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<div class="dice-hope-container">
|
||||
{{#each diceResults}}
|
||||
<li class="roll die d20 {{#if this.discarded}}discarded{{/if}}">{{this.value}}</li>
|
||||
{{#each this.dice.rolls}}
|
||||
<li class="roll die {{../dice.type}} {{#if this.discarded}}discarded{{/if}} min">{{this.value}}</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="modifiers-container">
|
||||
{{#each modifiers}}
|
||||
<li class="modifier-value" data-value="{{this.value}}" title="{{this.title}}">{{this.label}}</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
</ol>
|
||||
<div class="attack-roll-advantage-container">{{#if (eq this.advantageState 1)}}{{localize "DAGGERHEART.General.Advantage.Full"}}{{/if}}{{#if (eq this.advantageState 2)}}{{localize "DAGGERHEART.General.Disadvantage.Full"}}{{/if}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dice-total">
|
||||
<div class="dice-total-value">{{total}}</div>
|
||||
<div class="dice-total-value">{{this.total}}</div>
|
||||
</div>
|
||||
{{#if (gt targets.length 0)}}
|
||||
<div class="target-section">
|
||||
|
|
@ -30,6 +38,8 @@
|
|||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="flexrow">
|
||||
<button class="roll-damage-button" data-value="{{this.total.normal}}" data-damage="{{this.damage.value}}" data-damage-type="{{this.damage.type}}" {{#if this.damage.disabled}}disabled{{/if}}><span>Roll Damage</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,35 +1,64 @@
|
|||
<div class="dice-roll daggerheart chat roll">
|
||||
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
||||
<div class="dice-flavor">{{localize "DAGGERHEART.Chat.AttackRoll.Title" attack=this.title}}</div>
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{roll}}</div>
|
||||
<div class="dice-tooltip {{#if advantage.value}}expanded{{/if}}">
|
||||
<ol class="dice-rolls">
|
||||
<div class="dice-hope-container">
|
||||
<li id="hope" class="roll die {{hope.dice}} hope {{#if (or (eq advantageSelected 2) (and disadvantage.value (gt hope.value disadvantage.value)))}}unused{{/if}} {{#if (and advantage.value (eq advantageSelected 0))}}advantage{{/if}}">{{hope.value}}</li>
|
||||
|
||||
<div class="dice-tooltip">
|
||||
<div class="wrapper">
|
||||
<section class="tooltip-part">
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{hope.dice}}</span>
|
||||
|
|
||||
<span>1{{fear.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{this.highestRoll}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls duality">
|
||||
<li class="roll die {{hope.dice}} {{#if hope.discarded}}discarded{{/if}} hope min" title="{{localize "DAGGERHEART.General.Hope"}}">{{hope.value}}</li>
|
||||
<li class="roll die {{fear.dice}} {{#if fear.discarded}}discarded{{/if}} fear min" title="{{localize "DAGGERHEART.General.Fear"}}">{{fear.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{#if advantage.value}}
|
||||
<li class="roll die {{advantage.dice}} hope {{#if (eq advantageSelected 1)}}unused{{/if}} {{#if (eq advantageSelected 0)}}advantage{{/if}}">{{ advantage.value}}</li>
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{advantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{advantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{advantage.dice}} hope min">{{advantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if disadvantage.value}}
|
||||
<li class="roll die {{disadvantage.dice}} disadvantage {{#if (gte disadvantage.value hope.value)}}unused{{/if}}">{{disadvantage.value}}</li>
|
||||
{{/if}}
|
||||
</div>
|
||||
<li class="roll die {{fear.dice}} fear">{{fear.value}}</li>
|
||||
<div class="modifiers-container">
|
||||
{{#each modifiers}}
|
||||
<li class="modifier-value" data-value="{{this.value}}" title="{{this.title}}">{{this.label}}</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{disadvantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{disadvantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{disadvantage.dice}} hope min">{{disadvantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dice-total">
|
||||
<div class="dice-total-label">{{totalLabel}}</div>
|
||||
<div class="dice-total-value">
|
||||
{{#if total.alternate}}
|
||||
{{#with dualityDiceStates}}
|
||||
<span class="{{this.hope}}">{{../total.normal}}</span> - <span class="{{this.alternate}}">{{../total.alternate}}</span>
|
||||
{{/with}}
|
||||
{{else}}
|
||||
{{total.normal}}
|
||||
{{/if}}
|
||||
{{this.total}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if (gt targets.length 0)}}
|
||||
|
|
@ -44,6 +73,8 @@
|
|||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<button class="roll-damage-button" data-value="{{this.total.normal}}" data-damage="{{this.damage.value}}" data-damage-type="{{this.damage.type}}" {{#if this.damage.disabled}}disabled{{/if}}><span>Roll Damage</span></button>
|
||||
<div class="flexrow">
|
||||
<button class="roll-damage-button" data-value="{{this.total}}" data-damage="{{this.damage.value}}" data-damage-type="{{this.damage.type}}" {{#if this.damage.disabled}}disabled{{/if}}><span>Roll Damage</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,19 +1,33 @@
|
|||
<div class="dice-roll daggerheart chat roll">
|
||||
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
||||
<div class="dice-flavor">{{this.title}}</div>
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{this.roll}}</div>
|
||||
|
||||
<div class="dice-tooltip">
|
||||
<ol class="dice-rolls">
|
||||
<div class="wrapper">
|
||||
<section class="tooltip-part">
|
||||
{{#each dice}}
|
||||
<li class="roll die {{this.type}}">{{this.value}}</li>
|
||||
{{/each}}
|
||||
{{#each modifiers}}
|
||||
<li class="modifier-value">{{this}}</li>
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">{{this.rolls.length}}{{this.type}}</span>
|
||||
|
||||
<span class="part-total">{{this.rollTotal}}</span>
|
||||
</header>
|
||||
<ol class="dice-rolls">
|
||||
{{#each this.rolls}}
|
||||
<li class="roll die {{../type}} min">{{this}}</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
</div>
|
||||
<div class="dice-total">{{this.total}}</div>
|
||||
<div class="flexrow">
|
||||
<button class="damage-button" data-value="{{this.total}}" data-type="{{this.type}}"><span>{{localize "DAGGERHEART.Chat.DamageRoll.DealDamage"}}</span></button>
|
||||
{{/each}}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dice-total">{{this.damage.total}}</div>
|
||||
<div class="dice-actions">
|
||||
<button class="damage-button" data-target-hit="true" {{#if (eq this.targets.length 0)}}disabled{{/if}}>{{localize "DAGGERHEART.Chat.DamageRoll.DealDamageToTargets"}}</button>
|
||||
<button class="damage-button">{{localize "DAGGERHEART.Chat.DamageRoll.DealDamage"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,25 +1,59 @@
|
|||
<div class="dice-roll daggerheart chat roll">
|
||||
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
||||
<div class="dice-flavor">{{this.title}}</div>
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{roll}}</div>
|
||||
<div class="dice-tooltip {{#if advantage.value}}expanded{{/if}}">
|
||||
<ol class="dice-rolls">
|
||||
<div class="dice-hope-container">
|
||||
<li id="hope" class="roll die {{hope.dice}} hope" title="{{localize "DAGGERHEART.General.Hope"}}">{{hope.value}}</li>
|
||||
<li class="roll die {{fear.dice}} fear" title="{{localize "DAGGERHEART.General.Fear"}}">{{fear.value}}</li>
|
||||
<div class="dice-tooltip">
|
||||
<div class="wrapper">
|
||||
<section class="tooltip-part">
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{hope.dice}}</span>
|
||||
|
|
||||
<span>1{{fear.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{this.highestRoll}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls duality">
|
||||
<li class="roll die {{hope.dice}} {{#if hope.discarded}}discarded{{/if}} hope min" title="{{localize "DAGGERHEART.General.Hope"}}">{{hope.value}}</li>
|
||||
<li class="roll die {{fear.dice}} {{#if fear.discarded}}discarded{{/if}} fear min" title="{{localize "DAGGERHEART.General.Fear"}}">{{fear.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{#if advantage.value}}
|
||||
<li class="roll die {{advantage.dice}} advantage" title="{{localize "DAGGERHEART.General.Advantage"}}">{{ advantage.value}}</li>
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{advantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{advantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{advantage.dice}} hope min">{{advantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if disadvantage.value}}
|
||||
<li class="roll die {{disadvantage.dice}} disadvantage" title="{{localize "DAGGERHEART.General.Disadvantage"}}">{{disadvantage.value}}</li>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="modifiers-container">
|
||||
{{#each modifiers}}
|
||||
<li class="modifier-value" data-value="{{this.value}}" title="{{this.title}}">{{this.label}}</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="dice">
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">
|
||||
<span>1{{disadvantage.dice}}</span>
|
||||
</span>
|
||||
<span class="part-total">{{disadvantage.value}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
<li class="roll die {{disadvantage.dice}} hope min">{{disadvantage.value}}</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dice-total">
|
||||
<div class="dice-total-label">{{totalLabel}}</div>
|
||||
<div class="dice-total-value">
|
||||
|
|
@ -28,41 +62,3 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- V1.3 --}}
|
||||
{{!-- <div class="dice-roll daggerheart chat roll">
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{roll}}</div>
|
||||
<div class="dice-tooltip {{#if advantage.value}}expanded{{/if}}">
|
||||
<ol class="dice-rolls">
|
||||
<div class="dice-hope-container">
|
||||
<li id="hope" class="roll die {{hope.dice}} hope {{#if (or (eq advantageSelected 2) (and disadvantage.value (gt hope.value disadvantage.value)))}}unused{{/if}} {{#if (and advantage.value (eq advantageSelected 0))}}advantage{{/if}}">{{hope.value}}</li>
|
||||
{{#if advantage.value}}
|
||||
<li class="roll die {{advantage.dice}} hope {{#if (eq advantageSelected 1)}}unused{{/if}} {{#if (eq advantageSelected 0)}}advantage{{/if}}">{{ advantage.value}}</li>
|
||||
{{/if}}
|
||||
{{#if disadvantage.value}}
|
||||
<li class="roll die {{disadvantage.dice}} disadvantage {{#if (gte disadvantage.value hope.value)}}unused{{/if}}">{{disadvantage.value}}</li>
|
||||
{{/if}}
|
||||
</div>
|
||||
<li class="roll die {{fear.dice}} fear">{{fear.value}}</li>
|
||||
<div class="modifiers-container">
|
||||
{{#each modifiers}}
|
||||
<li class="modifier-value" data-value="{{this.value}}" title="{{this.title}}">{{this.label}}</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="dice-total">
|
||||
<div class="dice-total-label">{{totalLabel}}</div>
|
||||
<div class="dice-total-value">
|
||||
{{#if total.alternate}}
|
||||
{{#with dualityDiceStates}}
|
||||
<span class="{{this.hope}}">{{../total.normal}}</span> - <span class="{{this.alternate}}">{{../total.alternate}}</span>
|
||||
{{/with}}
|
||||
{{else}}
|
||||
{{total.normal}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> --}}
|
||||
|
|
@ -94,8 +94,6 @@
|
|||
<div class="form-group">
|
||||
<label>{{localize "DAGGERHEART.Sheets.Adversary.DamageThresholds.Title"}}</label>
|
||||
<div class="form-fields adversary-damage-threshold-container">
|
||||
<label>{{localize "DAGGERHEART.Sheets.Adversary.DamageThresholds.Minor"}}</label>
|
||||
<input type="text" name="system.damageThresholds.minor" value="{{source.system.damageThresholds.minor}}" data-dtype="Number" />
|
||||
<label>{{localize "DAGGERHEART.Sheets.Adversary.DamageThresholds.Major"}}</label>
|
||||
<input type="text" name="system.damageThresholds.major" value="{{source.system.damageThresholds.major}}" data-dtype="Number" />
|
||||
<label>{{localize "DAGGERHEART.Sheets.Adversary.DamageThresholds.Severe"}}</label>
|
||||
|
|
@ -124,21 +122,21 @@
|
|||
<div class="experience-chip">
|
||||
<input class="experience.value" type="text" name="system.experiences.{{index}}.name" value="{{experience.name}}" />
|
||||
<input class="experience-value" type="text" name="system.experiences.{{index}}.value" value="{{experience.value}}" data-dtype="Number" />
|
||||
<button class="experience-button"><i data-action="removeExperience" data-experience="{{index}}" class="fa-solid fa-x"></i></button>
|
||||
<button class="experience-button" data-action="removeExperience" data-experience="{{experience.id}}"><i class="fa-solid fa-x"></i></button>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="adversary-moves-container">
|
||||
<h2 class="moves-edit-container">{{localize "DAGGERHEART.Sheets.Adversary.Moves"}} <i class="fa-solid fa-plus" data-action="addMove"></i></h2>
|
||||
{{#each this.data.moves as |move key|}}
|
||||
<h2 class="moves-edit-container">{{localize "DAGGERHEART.Sheets.Adversary.Features"}} <i class="fa-solid fa-plus" data-action="addMove"></i></h2>
|
||||
{{#each this.data.features as |feature key|}}
|
||||
<div class="chip-container">
|
||||
<div class="chip-inner-container">
|
||||
<img src="{{move.img}}" />
|
||||
<div class="move-title">{{move.name}}</div>
|
||||
<img src="{{feature.img}}" />
|
||||
<div class="move-title">{{feature.name}}</div>
|
||||
</div>
|
||||
<div class="chip-inner-container">
|
||||
<button data-action="viewMove" data-move={{move.uuid}}><i class="fa-solid fa-fw fa-search"></i></button>
|
||||
<button data-action="removeMove" data-move={{move.uuid}}><i class="fa-solid fa-trash"></i></button>
|
||||
<button data-action="viewMove" data-move={{feature.uuid}}><i class="fa-solid fa-fw fa-search"></i></button>
|
||||
<button data-action="removeMove" data-move={{feature.uuid}}><i class="fa-solid fa-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
|
@ -177,7 +175,7 @@
|
|||
<div class="statistic-row">
|
||||
<label class="statistic-title">{{localize "DAGGERHEART.Sheets.Adversary.Attack.Modifier"}}:</label>
|
||||
<span class="statistic-value">+{{this.data.attack.attackModifier}}</span>
|
||||
<img class="adversary-roll" data-action="attackRoll" data-value="{{this.data.attack.attackModifier}}" data-damage="{{this.data.attack.damage.value}}" data-damage-type="{{this.data.attack.damage.type}}" src="icons/svg/d20-grey.svg" />
|
||||
<img class="adversary-roll" data-action="attackRoll" data-value="{{this.data.attack.attackModifier}}" data-name="{{this.data.attack.name}}" data-damage="{{this.data.attack.damage.value}}" data-damage-type="{{this.data.attack.damage.type}}" src="icons/svg/d20-grey.svg" />
|
||||
</div>
|
||||
<div class="statistic-row">
|
||||
<label class="statistic-title">{{localize this.data.attack.name}}</label>
|
||||
|
|
@ -186,9 +184,6 @@
|
|||
</div>
|
||||
<div class="statistic-section">
|
||||
<div class="statistic-row">
|
||||
<label class="statistic-title">{{localize "DAGGERHEART.Sheets.PC.Health.Minor"}}</label>
|
||||
<span class="statistic-value">{{this.data.damageThresholds.minor}}</span>
|
||||
<div class="vertical-separator" style="height: 16px; margin: 0 4px;"></div>
|
||||
<label class="statistic-title">{{localize "DAGGERHEART.Sheets.PC.Health.Major"}}</label>
|
||||
<span class="statistic-value">{{this.data.damageThresholds.major}}</span>
|
||||
<div class="vertical-separator" style="height: 16px; margin: 0 4px;"></div>
|
||||
|
|
@ -228,11 +223,11 @@
|
|||
</div> --}}
|
||||
</div>
|
||||
<div class="adversary-moves-container">
|
||||
<div class="moves-title">{{localize "DAGGERHEART.Sheets.Adversary.Moves"}}</div>
|
||||
{{#each this.data.moves as |move index|}}
|
||||
<div class="moves-title">{{localize "DAGGERHEART.Sheets.Adversary.Features"}}</div>
|
||||
{{#each this.data.features as |feature index|}}
|
||||
<div class="move-container">
|
||||
<label class="moves-name">{{move.name}}</label>
|
||||
<div class="move-description">{{{move.system.description}}}</div>
|
||||
<label class="moves-name">{{feature.name}}</label>
|
||||
<div class="move-description">{{{feature.system.description}}}</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
<textarea name="system.potentialAdversaries">{{source.system.potentialAdversaries}}</textarea>
|
||||
</div>
|
||||
<div class="adversary-moves-container">
|
||||
<h2 class="moves-edit-container">{{localize "DAGGERHEART.Sheets.Adversary.Moves"}} <i class="fa-solid fa-plus" data-action="addFeature"></i></h2>
|
||||
<h2 class="moves-edit-container">{{localize "DAGGERHEART.Sheets.Adversary.Features"}} <i class="fa-solid fa-plus" data-action="addFeature"></i></h2>
|
||||
{{#each data.features as |feature key|}}
|
||||
<div class="chip-container">
|
||||
<div class="chip-inner-container">
|
||||
|
|
@ -97,7 +97,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="adversary-moves-container">
|
||||
<div class="moves-title">{{localize "DAGGERHEART.Sheets.Adversary.Moves"}}</div>
|
||||
<div class="moves-title">{{localize "DAGGERHEART.Sheets.Adversary.Features"}}</div>
|
||||
{{#each data.features as |feature index|}}
|
||||
<div class="move-container" data-action="useFeature" data-feature="{{feature.uuid}}" data-action-type="{{feature.system.actionType}}">
|
||||
<label class="moves-name">{{feature.name}} - {{feature.system.actionType}}</label>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
{{#each this.attributes as |attribute key|}}
|
||||
<div class="attribute">
|
||||
<div class="attribute-banner">
|
||||
<img class="attribute-roll" data-action="attributeRoll" data-value="{{attribute.data.value}}" src="icons/svg/d12-grey.svg" />
|
||||
<img class="attribute-roll" data-action="attributeRoll" data-attribute="{{key}}" data-value="{{attribute.data.value}}" src="icons/svg/d12-grey.svg" />
|
||||
<div class="attribute-text">{{key}}</div>
|
||||
</div>
|
||||
<div class="attribute-mark {{#if (and (not attribute.levelMark) (and (not (includes attribute.levelMarks ../document.system.levelData.currentLevel)) (gt ../document.system.availableAttributeMarks.length 0)))}}selectable{{/if}}" data-action="toggleAttributeMark" data-attribute="{{key}}">
|
||||
|
|
|
|||
|
|
@ -4,27 +4,20 @@
|
|||
<div class="dice-container">
|
||||
<div class="dice-inner-container">
|
||||
<img src="icons/svg/d20-grey.svg" />
|
||||
<div class="dice-number">{{this.nrDice}}</div>
|
||||
<div class="dice-number">d20</div>
|
||||
</div>
|
||||
<div class="flexcol" style="margin-right: 4px;">
|
||||
<i class="fa-solid fa-chevron-up icon-button increase"></i>
|
||||
<i class="fa-solid fa-chevron-down icon-button decrease"></i>
|
||||
</div>
|
||||
<div class="flexcol">
|
||||
<div class="icon-button {{#if this.advantage}}active{{/if}} advantage">Adv</div>
|
||||
<div class="icon-button {{#if (eq this.advantage false)}}active{{/if}} disadvantage">Dis</div>
|
||||
<div class="advantage-container">
|
||||
<button class="advantage-button {{#if this.advantage}}active{{/if}} advantage" data-action="updateIsAdvantage" data-advantage="true">{{localize "DAGGERHEART.General.Advantage.Full"}}</button>
|
||||
<button class="advantage-button {{#if (eq this.advantage false)}}active{{/if}} disadvantage" data-action="updateIsAdvantage">{{localize "DAGGERHEART.General.Disadvantage.Full"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="roll-dialog-experience-container">
|
||||
{{#each this.experiences as |experience key|}}
|
||||
<div class="roll-dialog-chip {{#if experience.selected}}selected{{/if}}" data-action="selectExperience" data-key="{{key}}">
|
||||
<span>{{experience.name}}</span>
|
||||
<i class="fa-solid fa-circle-check"></i>
|
||||
</div>
|
||||
{{#each this.experiences as |experience|}}
|
||||
<button class="experience-chip {{#if experience.selected}}active{{/if}}" data-action="selectExperience" id="{{id}}">{{experience.name}} {{experience.value}}</button>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
<button class="roll-button">Roll</button>
|
||||
<footer class="flexrow">
|
||||
<button type="submit" class="roll-button">Roll</button>
|
||||
</footer>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue