mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-14 20:51:07 +01:00
Merge pull request #173 from Foundryborne/feature/169-adversary-action
https://github.com/Foundryborne/daggerheart/issues/169
This commit is contained in:
commit
e1dd59454c
19 changed files with 269 additions and 499 deletions
|
|
@ -63,6 +63,8 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
||||||
if (this.action.damage?.hasOwnProperty('includeBase') && this.action.type === 'attack') context.hasBaseDamage = !!this.action.parent.damage;
|
if (this.action.damage?.hasOwnProperty('includeBase') && this.action.type === 'attack') context.hasBaseDamage = !!this.action.parent.damage;
|
||||||
context.getRealIndex = this.getRealIndex.bind(this);
|
context.getRealIndex = this.getRealIndex.bind(this);
|
||||||
context.disableOption = this.disableOption.bind(this);
|
context.disableOption = this.disableOption.bind(this);
|
||||||
|
context.isNPC = this.action.actor.type !== 'character';
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,11 +97,16 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
||||||
static async updateForm(event, _, formData) {
|
static async updateForm(event, _, formData) {
|
||||||
const submitData = this._prepareSubmitData(event, formData),
|
const submitData = this._prepareSubmitData(event, formData),
|
||||||
data = foundry.utils.expandObject(foundry.utils.mergeObject(this.action.toObject(), submitData)),
|
data = foundry.utils.expandObject(foundry.utils.mergeObject(this.action.toObject(), submitData)),
|
||||||
|
container = foundry.utils.getProperty(this.action.parent, this.action.systemPath);
|
||||||
|
let newActions;
|
||||||
|
if(Array.isArray(container)) {
|
||||||
newActions = foundry.utils.getProperty(this.action.parent, this.action.systemPath).map(x => x.toObject()); // Find better way
|
newActions = foundry.utils.getProperty(this.action.parent, this.action.systemPath).map(x => x.toObject()); // Find better way
|
||||||
if (!newActions.findSplice(x => x._id === data._id, data)) newActions.push(data);
|
if (!newActions.findSplice(x => x._id === data._id, data)) newActions.push(data);
|
||||||
|
} else newActions = data;
|
||||||
|
|
||||||
const updates = await this.action.parent.parent.update({ [`system.${this.action.systemPath}`]: newActions });
|
const updates = await this.action.parent.parent.update({ [`system.${this.action.systemPath}`]: newActions });
|
||||||
if (!updates) return;
|
if (!updates) return;
|
||||||
this.action = foundry.utils.getProperty(updates.system, this.action.systemPath)[this.action.index];
|
this.action = Array.isArray(container) ? foundry.utils.getProperty(updates.system, this.action.systemPath)[this.action.index] : foundry.utils.getProperty(updates.system, this.action.systemPath);
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl
|
||||||
}
|
}
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
|
console.log(this.costs)
|
||||||
const updatedCosts = this.action.calcCosts(this.costs),
|
const updatedCosts = this.action.calcCosts(this.costs),
|
||||||
updatedUses = this.action.calcUses(this.uses);
|
updatedUses = this.action.calcUses(this.uses);
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -27,18 +27,14 @@ export class DHRoll extends Roll {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.applyKeybindings(config);
|
this.applyKeybindings(config);
|
||||||
|
|
||||||
// let roll;
|
|
||||||
// if(config.dialog?.configure === false) {
|
|
||||||
// roll = new this('', config.actor, config);
|
|
||||||
// } else {
|
|
||||||
if(config.dialog.configure !== false) {
|
if(config.dialog.configure !== false) {
|
||||||
// Open Roll Dialog
|
// Open Roll Dialog
|
||||||
const DialogClass = config.dialog?.class ?? this.DefaultDialog;
|
const DialogClass = config.dialog?.class ?? this.DefaultDialog;
|
||||||
config = await DialogClass.configure(config, message);
|
config = await DialogClass.configure(config, message);
|
||||||
if(!config) return;
|
if(!config) return;
|
||||||
}
|
}
|
||||||
let roll = new this(config.formula, config.actor, config);
|
let roll = new this(config.formula, config.data, config);
|
||||||
|
|
||||||
for ( const hook of config.hooks ) {
|
for ( const hook of config.hooks ) {
|
||||||
if ( Hooks.call(`${SYSTEM.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false ) return [];
|
if ( Hooks.call(`${SYSTEM.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false ) return [];
|
||||||
|
|
@ -101,9 +97,6 @@ export class DualityDie extends foundry.dice.terms.Die {
|
||||||
export class D20Roll extends DHRoll {
|
export class D20Roll extends DHRoll {
|
||||||
constructor(formula, data={}, options={}) {
|
constructor(formula, data={}, options={}) {
|
||||||
super(formula, data, options);
|
super(formula, data, options);
|
||||||
// console.log(data, options)
|
|
||||||
// this.options = this._prepareData(data);
|
|
||||||
// this.options = options;
|
|
||||||
this.createBaseDice();
|
this.createBaseDice();
|
||||||
this.configureModifiers();
|
this.configureModifiers();
|
||||||
|
|
||||||
|
|
@ -195,10 +188,10 @@ export class D20Roll extends DHRoll {
|
||||||
this.applyBaseBonus();
|
this.applyBaseBonus();
|
||||||
|
|
||||||
this.options.experiences?.forEach(m => {
|
this.options.experiences?.forEach(m => {
|
||||||
if(this.options.actor.experiences?.[m]) this.options.roll.modifiers.push(
|
if(this.options.data.experiences?.[m]) this.options.roll.modifiers.push(
|
||||||
{
|
{
|
||||||
label: this.options.actor.experiences[m].description,
|
label: this.options.data.experiences[m].description,
|
||||||
value: this.options.actor.experiences[m].total
|
value: this.options.data.experiences[m].total
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
|
@ -212,30 +205,16 @@ export class D20Roll extends DHRoll {
|
||||||
}
|
}
|
||||||
|
|
||||||
applyBaseBonus() {
|
applyBaseBonus() {
|
||||||
// if(this.options.action) {
|
if(this.options.type === "attack") this.terms.push(...this.formatModifier(this.options.data.attack.roll.bonus));
|
||||||
if(this.options.type === "attack") this.terms.push(...this.formatModifier(this.options.actor.system.attack.modifier));
|
|
||||||
/* this.options.roll.modifiers?.forEach(m => {
|
|
||||||
this.terms.push(...this.formatModifier(m));
|
|
||||||
}) */
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async postEvaluate(roll, config={}) {
|
static async postEvaluate(roll, config={}) {
|
||||||
if (config.targets?.length) {
|
if (config.targets?.length) {
|
||||||
/* targets = config.targets.map(target => {
|
|
||||||
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion
|
|
||||||
target.hit = roll.total >= difficulty;
|
|
||||||
return target;
|
|
||||||
}); */
|
|
||||||
config.targets.forEach(target => {
|
config.targets.forEach(target => {
|
||||||
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion
|
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion
|
||||||
target.hit = roll.total >= difficulty;
|
target.hit = roll.total >= difficulty;
|
||||||
})
|
})
|
||||||
} else if(config.roll.difficulty) roll.success = roll.total >= config.roll.difficulty;
|
} else if(config.roll.difficulty) roll.success = roll.total >= config.roll.difficulty;
|
||||||
// config.roll.advantage = {
|
|
||||||
// dice: roll.dHope.faces,
|
|
||||||
// value: roll.dHope.total
|
|
||||||
// }
|
|
||||||
config.roll.total = roll.total;
|
config.roll.total = roll.total;
|
||||||
config.roll.formula = roll.formula;
|
config.roll.formula = roll.formula;
|
||||||
config.roll.advantage = {
|
config.roll.advantage = {
|
||||||
|
|
@ -244,10 +223,19 @@ export class D20Roll extends DHRoll {
|
||||||
value: roll.dAdvantage?.total
|
value: roll.dAdvantage?.total
|
||||||
}
|
}
|
||||||
config.roll.modifierTotal = config.roll.modifiers.reduce((a,c) => a + c.value, 0);
|
config.roll.modifierTotal = config.roll.modifiers.reduce((a,c) => a + c.value, 0);
|
||||||
|
config.roll.dice = [];
|
||||||
|
roll.dice.forEach(d => {
|
||||||
|
config.roll.dice.push({
|
||||||
|
dice: d.denomination,
|
||||||
|
total: d.total,
|
||||||
|
formula: d.formula,
|
||||||
|
results: d.results
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getRollData() {
|
getRollData() {
|
||||||
return this.options.actor.getRollData();
|
return this.options.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
formatModifier(modifier) {
|
formatModifier(modifier) {
|
||||||
|
|
@ -348,7 +336,6 @@ export class DualityRoll extends D20Roll {
|
||||||
const dieFaces = 6,
|
const dieFaces = 6,
|
||||||
bardRallyFaces = this.hasBarRally,
|
bardRallyFaces = this.hasBarRally,
|
||||||
advDie = new foundry.dice.terms.Die({faces: dieFaces});
|
advDie = new foundry.dice.terms.Die({faces: dieFaces});
|
||||||
// console.log(this.hasAdvantage, this.hasDisadvantage)
|
|
||||||
if(this.hasAdvantage || this.hasDisadvantage || bardRallyFaces) this.terms.push(new foundry.dice.terms.OperatorTerm({operator:'+'}));
|
if(this.hasAdvantage || this.hasDisadvantage || bardRallyFaces) this.terms.push(new foundry.dice.terms.OperatorTerm({operator:'+'}));
|
||||||
if(bardRallyFaces) {
|
if(bardRallyFaces) {
|
||||||
const rallyDie = new foundry.dice.terms.Die({faces: bardRallyFaces});
|
const rallyDie = new foundry.dice.terms.Die({faces: bardRallyFaces});
|
||||||
|
|
@ -364,23 +351,16 @@ export class DualityRoll extends D20Roll {
|
||||||
}
|
}
|
||||||
|
|
||||||
applyBaseBonus() {
|
applyBaseBonus() {
|
||||||
// if(this.options.action) {
|
if(!this.options.roll.modifiers) this.options.roll.modifiers = [];
|
||||||
// console.log(this.options, this.options.actor.system.traits[this.options.roll.trait].bonus)
|
if(this.options.roll?.trait) this.options.roll.modifiers.push(
|
||||||
// console.log(this.options.actor.system);
|
{
|
||||||
/* if(this.options.roll?.trait) this.terms.push(...this.formatModifier(this.options.actor.traits[this.options.roll.trait].total)); */
|
label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`,
|
||||||
if(!this.options.roll.modifiers) this.options.roll.modifiers = [];
|
value: this.options.data.traits[this.options.roll.trait].total
|
||||||
if(this.options.roll?.trait) this.options.roll.modifiers.push(
|
}
|
||||||
{
|
);
|
||||||
label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`,
|
|
||||||
value: this.options.actor.traits[this.options.roll.trait].total
|
|
||||||
}
|
|
||||||
);
|
|
||||||
console.log(this.options)
|
|
||||||
// } else if(this.options.trait) this.terms.push(...this.formatModifier(this.options.actor.system.traits[this.options.roll.trait].total));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async postEvaluate(roll, config={}) {
|
static async postEvaluate(roll, config={}) {
|
||||||
console.log(roll,config);
|
|
||||||
super.postEvaluate(roll, config);
|
super.postEvaluate(roll, config);
|
||||||
config.roll.hope = {
|
config.roll.hope = {
|
||||||
dice: roll.dHope.denomination,
|
dice: roll.dHope.denomination,
|
||||||
|
|
@ -416,30 +396,10 @@ export class DamageRoll extends DHRoll {
|
||||||
static DefaultDialog = DamageDialog;
|
static DefaultDialog = DamageDialog;
|
||||||
|
|
||||||
static async postEvaluate(roll, config={}) {
|
static async postEvaluate(roll, config={}) {
|
||||||
console.log(roll, config)
|
|
||||||
config.roll = {
|
config.roll = {
|
||||||
// formula : config.formula,
|
|
||||||
result: roll.total,
|
result: roll.total,
|
||||||
dice: roll.dice
|
dice: roll.dice
|
||||||
}
|
}
|
||||||
if(roll.healing) config.roll.type = roll.healing.type
|
if(roll.healing) config.roll.type = roll.healing.type
|
||||||
/* const dice = [];
|
|
||||||
const modifiers = [];
|
|
||||||
for (var i = 0; i < roll.terms.length; i++) {
|
|
||||||
const term = roll.terms[i];
|
|
||||||
if (term.faces) {
|
|
||||||
dice.push({
|
|
||||||
type: `d${term.faces}`,
|
|
||||||
rolls: term.results.map(x => x.result),
|
|
||||||
total: term.results.reduce((acc, x) => acc + x.result, 0)
|
|
||||||
});
|
|
||||||
} else if (term.operator) {
|
|
||||||
} else if (term.number) {
|
|
||||||
const operator = i === 0 ? '' : roll.terms[i - 1].operator;
|
|
||||||
modifiers.push({ value: term.number, operator: operator });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
config.roll.dice = dice;
|
|
||||||
config.roll.modifiers = modifiers; */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import DHActionConfig from '../config/Action.mjs';
|
||||||
import DaggerheartSheet from './daggerheart-sheet.mjs';
|
import DaggerheartSheet from './daggerheart-sheet.mjs';
|
||||||
|
|
||||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||||
|
|
@ -9,6 +10,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
actions: {
|
actions: {
|
||||||
reactionRoll: this.reactionRoll,
|
reactionRoll: this.reactionRoll,
|
||||||
attackRoll: this.attackRoll,
|
attackRoll: this.attackRoll,
|
||||||
|
attackConfigure: this.attackConfigure,
|
||||||
addExperience: this.addExperience,
|
addExperience: this.addExperience,
|
||||||
removeExperience: this.removeExperience,
|
removeExperience: this.removeExperience,
|
||||||
toggleHP: this.toggleHP,
|
toggleHP: this.toggleHP,
|
||||||
|
|
@ -51,7 +53,9 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.document = this.document;
|
context.document = this.document;
|
||||||
context.tabs = super._getTabs(this.constructor.TABS);
|
context.tabs = super._getTabs(this.constructor.TABS);
|
||||||
|
context.systemFields.attack.fields = this.document.system.attack.schema.fields;
|
||||||
|
context.isNPC = true;
|
||||||
|
console.log(context)
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,25 +82,11 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static async attackRoll(event) {
|
static async attackRoll(event) {
|
||||||
const { modifier, damage, name: attackName } = this.actor.system.attack,
|
this.actor.system.attack.use(event);
|
||||||
config = {
|
}
|
||||||
event: event,
|
|
||||||
title: attackName,
|
static async attackConfigure(event) {
|
||||||
roll: {
|
await new DHActionConfig(this.document.system.attack).render(true);
|
||||||
modifier: modifier,
|
|
||||||
type: 'action'
|
|
||||||
},
|
|
||||||
chatMessage: {
|
|
||||||
type: 'adversaryRoll',
|
|
||||||
template: 'systems/daggerheart/templates/chat/adversary-attack-roll.hbs'
|
|
||||||
},
|
|
||||||
damage: {
|
|
||||||
value: damage.value,
|
|
||||||
type: damage.type
|
|
||||||
},
|
|
||||||
checkTarget: true
|
|
||||||
};
|
|
||||||
this.actor.diceRoll(config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async addExperience() {
|
static async addExperience() {
|
||||||
|
|
|
||||||
|
|
@ -300,13 +300,15 @@ export const diceTypes = {
|
||||||
d4: 'd4',
|
d4: 'd4',
|
||||||
d6: 'd6',
|
d6: 'd6',
|
||||||
d8: 'd8',
|
d8: 'd8',
|
||||||
|
d10: 'd10',
|
||||||
d12: 'd12',
|
d12: 'd12',
|
||||||
d20: 'd20'
|
d20: 'd20'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const multiplierTypes = {
|
export const multiplierTypes = {
|
||||||
proficiency: 'Proficiency',
|
proficiency: 'Proficiency',
|
||||||
spellcast: 'Spellcast'
|
spellcast: 'Spellcast',
|
||||||
|
flat: 'Flat'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDiceSoNicePresets = () => {
|
export const getDiceSoNicePresets = () => {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import DamageSelectionDialog from '../../applications/damageSelectionDialog.mjs'
|
||||||
import CostSelectionDialog from '../../applications/costSelectionDialog.mjs';
|
import CostSelectionDialog from '../../applications/costSelectionDialog.mjs';
|
||||||
import { abilities } from '../../config/actorConfig.mjs';
|
import { abilities } from '../../config/actorConfig.mjs';
|
||||||
import { DHActionDiceData, DHDamageData, DHDamageField } from './actionDice.mjs';
|
import { DHActionDiceData, DHDamageData, DHDamageField } from './actionDice.mjs';
|
||||||
|
import DhpActor from '../../documents/actor.mjs';
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
|
@ -87,7 +88,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
choices: SYSTEM.GENERAL.range,
|
choices: SYSTEM.GENERAL.range,
|
||||||
required: false,
|
required: false,
|
||||||
blank: true,
|
blank: true,
|
||||||
initial: null
|
// initial: null
|
||||||
}),
|
}),
|
||||||
...this.defineExtraSchema()
|
...this.defineExtraSchema()
|
||||||
};
|
};
|
||||||
|
|
@ -99,7 +100,8 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
roll: new fields.SchemaField({
|
roll: new fields.SchemaField({
|
||||||
type: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.GENERAL.rollTypes }),
|
type: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.GENERAL.rollTypes }),
|
||||||
trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }),
|
trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }),
|
||||||
difficulty: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 })
|
difficulty: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 }),
|
||||||
|
bonus: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 })
|
||||||
}),
|
}),
|
||||||
save: new fields.SchemaField({
|
save: new fields.SchemaField({
|
||||||
trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }),
|
trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }),
|
||||||
|
|
@ -150,7 +152,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
get actor() {
|
get actor() {
|
||||||
return this.item?.actor;
|
return this.item instanceof DhpActor ? this.item : this.item?.actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
get chatTemplate() {
|
get chatTemplate() {
|
||||||
|
|
@ -197,6 +199,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
source: {
|
source: {
|
||||||
item: this.item._id,
|
item: this.item._id,
|
||||||
action: this._id
|
action: this._id
|
||||||
|
// action: this
|
||||||
},
|
},
|
||||||
type: this.type,
|
type: this.type,
|
||||||
hasDamage: !!this.damage?.parts?.length,
|
hasDamage: !!this.damage?.parts?.length,
|
||||||
|
|
@ -229,25 +232,25 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
this.spendCost(config.costs.values);
|
this.spendCost(config.costs.values);
|
||||||
this.spendUses(config.uses);
|
this.spendUses(config.uses);
|
||||||
|
|
||||||
// console.log(config)
|
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ROLL */
|
/* ROLL */
|
||||||
hasRoll() {
|
hasRoll() {
|
||||||
return this.roll?.type && this.roll?.trait;
|
// return this.roll?.type && this.roll?.trait;
|
||||||
|
return this.roll?.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
async proceedRoll(config) {
|
async proceedRoll(config) {
|
||||||
if (!this.hasRoll()) return config;
|
if (!this.hasRoll()) return config;
|
||||||
const modifierValue = this.actor.system.traits[this.roll.trait].value;
|
// const modifierValue = this.actor.system.traits[this.roll.trait].value;
|
||||||
config = {
|
config = {
|
||||||
...config,
|
...config,
|
||||||
roll: {
|
roll: {
|
||||||
modifiers: [],
|
modifiers: [],
|
||||||
trait: this.roll?.trait,
|
trait: this.roll?.trait,
|
||||||
label: game.i18n.localize(abilities[this.roll.trait].label),
|
// label: game.i18n.localize(abilities[this.roll.trait].label),
|
||||||
|
label: 'Attack',
|
||||||
type: this.actionType,
|
type: this.actionType,
|
||||||
difficulty: this.roll?.difficulty
|
difficulty: this.roll?.difficulty
|
||||||
}
|
}
|
||||||
|
|
@ -347,7 +350,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
name: actor.actor.name,
|
name: actor.actor.name,
|
||||||
img: actor.actor.img,
|
img: actor.actor.img,
|
||||||
difficulty: actor.actor.system.difficulty,
|
difficulty: actor.actor.system.difficulty,
|
||||||
evasion: actor.actor.system.evasion?.value
|
evasion: actor.actor.system.evasion?.total
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* TARGET */
|
/* TARGET */
|
||||||
|
|
@ -363,7 +366,6 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
||||||
async applyEffects(event, data, force=false) {
|
async applyEffects(event, data, force=false) {
|
||||||
if(!this.effects?.length || !data.system.targets.length) return;
|
if(!this.effects?.length || !data.system.targets.length) return;
|
||||||
data.system.targets.forEach(async (token) => {
|
data.system.targets.forEach(async (token) => {
|
||||||
// console.log(token, force)
|
|
||||||
if(!token.hit && !force) return;
|
if(!token.hit && !force) return;
|
||||||
this.effects.forEach(async (e) => {
|
this.effects.forEach(async (e) => {
|
||||||
const actor = canvas.tokens.get(token.id)?.actor,
|
const actor = canvas.tokens.get(token.id)?.actor,
|
||||||
|
|
@ -417,7 +419,7 @@ export class DHDamageAction extends DHBaseAction {
|
||||||
|
|
||||||
async rollDamage(event, data) {
|
async rollDamage(event, data) {
|
||||||
let formula = this.damage.parts.map(p => p.getFormula(this.actor)).join(' + ');
|
let formula = this.damage.parts.map(p => p.getFormula(this.actor)).join(' + ');
|
||||||
|
|
||||||
if (!formula || formula == '') return;
|
if (!formula || formula == '') return;
|
||||||
let roll = { formula: formula, total: formula },
|
let roll = { formula: formula, total: formula },
|
||||||
bonusDamage = [];
|
bonusDamage = [];
|
||||||
|
|
@ -427,7 +429,7 @@ export class DHDamageAction extends DHBaseAction {
|
||||||
formula,
|
formula,
|
||||||
targets: (data.system?.targets ?? data.targets).map(x => ({ id: x.id, name: x.name, img: x.img, hit: true }))
|
targets: (data.system?.targets ?? data.targets).map(x => ({ id: x.id, name: x.name, img: x.img, hit: true }))
|
||||||
}
|
}
|
||||||
|
|
||||||
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config)
|
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -479,7 +481,6 @@ export class DHHealingAction extends DHBaseAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
async rollHealing(event, data) {
|
async rollHealing(event, data) {
|
||||||
console.log(event, data)
|
|
||||||
let formula = this.healing.value.getFormula(this.actor);
|
let formula = this.healing.value.getFormula(this.actor);
|
||||||
|
|
||||||
if (!formula || formula == '') return;
|
if (!formula || formula == '') return;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ export class DHActionDiceData extends foundry.abstract.DataModel {
|
||||||
initial: 'proficiency',
|
initial: 'proficiency',
|
||||||
label: 'Multiplier'
|
label: 'Multiplier'
|
||||||
}),
|
}),
|
||||||
|
flatMultiplier : new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }),
|
||||||
dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6', label: 'Formula' }),
|
dice: new fields.StringField({ choices: SYSTEM.GENERAL.diceTypes, initial: 'd6', label: 'Formula' }),
|
||||||
bonus: new fields.NumberField({ nullable: true, initial: null, label: 'Bonus' }),
|
bonus: new fields.NumberField({ nullable: true, initial: null, label: 'Bonus' }),
|
||||||
custom: new fields.SchemaField({
|
custom: new fields.SchemaField({
|
||||||
|
|
@ -21,9 +22,10 @@ export class DHActionDiceData extends foundry.abstract.DataModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormula(actor) {
|
getFormula(actor) {
|
||||||
|
const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : actor.system[this.multiplier]?.total;
|
||||||
return this.custom.enabled
|
return this.custom.enabled
|
||||||
? this.custom.formula
|
? this.custom.formula
|
||||||
: `${actor.system[this.multiplier]?.total ?? 1}${this.dice}${this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : ''}`;
|
: `${multiplier ?? 1}${this.dice}${this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : ''}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
import DhpItem from '../../documents/item.mjs';
|
||||||
|
import ActionField from '../fields/actionField.mjs';
|
||||||
|
import DHWeapon from '../item/weapon.mjs';
|
||||||
import BaseDataActor from './base.mjs';
|
import BaseDataActor from './base.mjs';
|
||||||
|
|
||||||
const resourceField = () =>
|
const resourceField = () =>
|
||||||
|
|
@ -39,7 +42,7 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
hitPoints: resourceField(),
|
hitPoints: resourceField(),
|
||||||
stress: resourceField()
|
stress: resourceField()
|
||||||
}),
|
}),
|
||||||
attack: new fields.SchemaField({
|
/* attack: new fields.SchemaField({
|
||||||
name: new fields.StringField({}),
|
name: new fields.StringField({}),
|
||||||
modifier: new fields.NumberField({ required: true, integer: true, initial: 0 }),
|
modifier: new fields.NumberField({ required: true, integer: true, initial: 0 }),
|
||||||
range: new fields.StringField({
|
range: new fields.StringField({
|
||||||
|
|
@ -55,6 +58,43 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
initial: SYSTEM.GENERAL.damageTypes.physical.id
|
initial: SYSTEM.GENERAL.damageTypes.physical.id
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
}), */
|
||||||
|
/* attack: new fields.EmbeddedDocumentField(DhpItem,
|
||||||
|
{
|
||||||
|
// type: 'weapon'
|
||||||
|
// initial: new DhpItem(
|
||||||
|
// {
|
||||||
|
// name: 'Attack',
|
||||||
|
// type: 'weapon'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// parent: this.parent,
|
||||||
|
// parentCollection: 'items'
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// initial: {type: 'weapon'}
|
||||||
|
}
|
||||||
|
), */
|
||||||
|
attack: new ActionField({
|
||||||
|
initial: {
|
||||||
|
name: 'Attack',
|
||||||
|
_id: foundry.utils.randomID(),
|
||||||
|
systemPath: 'attack',
|
||||||
|
type: 'attack',
|
||||||
|
range: 'melee',
|
||||||
|
target: {
|
||||||
|
type: 'any',
|
||||||
|
amount: 1
|
||||||
|
},
|
||||||
|
roll: {
|
||||||
|
type: 'weapon'
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
parts: [{
|
||||||
|
multiplier: 'flat'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
experiences: new fields.TypedObjectField(
|
experiences: new fields.TypedObjectField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
|
|
@ -65,4 +105,21 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
/* Features waiting on pseudo-document data model addition */
|
/* Features waiting on pseudo-document data model addition */
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepareBaseData() {
|
||||||
|
// console.log(this.attack)
|
||||||
|
/* if(!this.attack) {
|
||||||
|
this.attack = new DhpItem(
|
||||||
|
{
|
||||||
|
name: 'Attack',
|
||||||
|
type: 'weapon',
|
||||||
|
_id: foundry.utils.randomID()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
parent: this.parent,
|
||||||
|
parentCollection: 'items'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,13 @@
|
||||||
|
import DhpActor from "../../documents/actor.mjs";
|
||||||
|
import ActionField from "../fields/actionField.mjs";
|
||||||
|
|
||||||
export default class DHAdversaryRoll extends foundry.abstract.TypeDataModel {
|
export default class DHAdversaryRoll extends foundry.abstract.TypeDataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: new fields.StringField(),
|
title: new fields.StringField(),
|
||||||
origin: new fields.StringField({ required: true }),
|
|
||||||
dice: new fields.DataField(),
|
|
||||||
roll: new fields.DataField(),
|
roll: new fields.DataField(),
|
||||||
modifiers: new fields.ArrayField(
|
|
||||||
new fields.SchemaField({
|
|
||||||
value: new fields.NumberField({ integer: true }),
|
|
||||||
label: new fields.StringField({})
|
|
||||||
})
|
|
||||||
),
|
|
||||||
advantageState: new fields.BooleanField({ nullable: true, initial: null }),
|
|
||||||
advantage: new fields.SchemaField({
|
|
||||||
dice: new fields.StringField({}),
|
|
||||||
value: new fields.NumberField({ integer: true })
|
|
||||||
}),
|
|
||||||
targets: new fields.ArrayField(
|
targets: new fields.ArrayField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
id: new fields.StringField({}),
|
id: new fields.StringField({}),
|
||||||
|
|
@ -29,24 +19,13 @@ export default class DHAdversaryRoll extends foundry.abstract.TypeDataModel {
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
hasDamage: new fields.BooleanField({ initial: false }),
|
hasDamage: new fields.BooleanField({ initial: false }),
|
||||||
|
hasHealing: new fields.BooleanField({ initial: false }),
|
||||||
hasEffect: new fields.BooleanField({ initial: false }),
|
hasEffect: new fields.BooleanField({ initial: false }),
|
||||||
/* damage: new fields.SchemaField(
|
source: new fields.SchemaField({
|
||||||
{
|
actor: new fields.StringField(),
|
||||||
value: new fields.StringField({}),
|
item: new fields.StringField(),
|
||||||
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false })
|
action: new fields.StringField()
|
||||||
},
|
|
||||||
{ nullable: true, initial: null }
|
|
||||||
), */
|
|
||||||
action: new fields.SchemaField({
|
|
||||||
itemId: new fields.StringField(),
|
|
||||||
actionId: new fields.StringField()
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
prepareDerivedData() {
|
|
||||||
this.targets.forEach(target => {
|
|
||||||
target.hit = target.difficulty ? this.total >= target.difficulty : this.total >= target.evasion;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,4 @@
|
||||||
import { DualityRollColor } from '../settings/Appearance.mjs';
|
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
const diceField = () =>
|
|
||||||
new fields.SchemaField({
|
|
||||||
dice: new fields.StringField({}),
|
|
||||||
value: new fields.NumberField({ integer: true })
|
|
||||||
});
|
|
||||||
|
|
||||||
export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
|
export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
|
||||||
static dualityResult = {
|
static dualityResult = {
|
||||||
|
|
@ -17,18 +10,7 @@ export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
return {
|
return {
|
||||||
title: new fields.StringField(),
|
title: new fields.StringField(),
|
||||||
/* origin: new fields.StringField({ required: true }), */
|
|
||||||
roll: new fields.DataField({}),
|
roll: new fields.DataField({}),
|
||||||
/* modifiers: new fields.ArrayField(
|
|
||||||
new fields.SchemaField({
|
|
||||||
value: new fields.NumberField({ integer: true }),
|
|
||||||
label: new fields.StringField({})
|
|
||||||
})
|
|
||||||
), */
|
|
||||||
/* hope: diceField(),
|
|
||||||
fear: diceField(),
|
|
||||||
advantageState: new fields.BooleanField({ nullable: true, initial: null }), */
|
|
||||||
/* advantage: diceField(), */
|
|
||||||
targets: new fields.ArrayField(
|
targets: new fields.ArrayField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
id: new fields.StringField({}),
|
id: new fields.StringField({}),
|
||||||
|
|
@ -49,47 +31,4 @@ export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get diceTotal() {
|
|
||||||
return this.hope.value + this.fear.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get modifierTotal() {
|
|
||||||
const total = this.modifiers.reduce((acc, x) => acc + x.value, 0);
|
|
||||||
return {
|
|
||||||
value: total,
|
|
||||||
label: total > 0 ? `+${total}` : total < 0 ? `${total}` : ''
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get dualityResult() {
|
|
||||||
return this.hope.value > this.fear.value
|
|
||||||
? this.constructor.dualityResult.hope
|
|
||||||
: this.fear.value > this.hope.value
|
|
||||||
? this.constructor.dualityResult.fear
|
|
||||||
: this.constructor.dualityResult.critical;
|
|
||||||
}
|
|
||||||
|
|
||||||
get totalLabel() {
|
|
||||||
const label =
|
|
||||||
this.hope.value > this.fear.value
|
|
||||||
? 'DAGGERHEART.General.Hope'
|
|
||||||
: this.fear.value > this.hope.value
|
|
||||||
? 'DAGGERHEART.General.Fear'
|
|
||||||
: 'DAGGERHEART.General.CriticalSuccess';
|
|
||||||
|
|
||||||
return game.i18n.localize(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
get colorful() {
|
|
||||||
return (
|
|
||||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).dualityColorScheme ===
|
|
||||||
DualityRollColor.colorful.value
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
prepareDerivedData() {
|
|
||||||
this.hope.discarded = this.hope.value < this.fear.value;
|
|
||||||
this.fear.discarded = this.fear.value < this.hope.value;
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
this.config.experiences = [];
|
this.config.experiences = [];
|
||||||
|
|
||||||
if(config.source?.action) {
|
if(config.source?.action) {
|
||||||
this.item = config.actor.parent.items.get(config.source.item);
|
this.item = config.data.parent.items.get(config.source.item);
|
||||||
this.action = this.item.system.actions.find(a => a._id === config.source.action);
|
this.action = config.data.attack?._id == config.source.action ? config.data.attack : this.item.system.actions.find(a => a._id === config.source.action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
||||||
|
|
||||||
async _prepareContext(_options) {
|
async _prepareContext(_options) {
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.experiences = Object.keys(this.config.actor.experiences).map(id => ({ id, ...this.config.actor.experiences[id] }));
|
context.experiences = Object.keys(this.config.data.experiences).map(id => ({ id, ...this.config.data.experiences[id] }));
|
||||||
context.selectedExperiences = this.config.experiences;
|
context.selectedExperiences = this.config.experiences;
|
||||||
context.advantage = this.config.advantage;
|
context.advantage = this.config.advantage;
|
||||||
/* context.diceOptions = this.diceOptions; */
|
/* context.diceOptions = this.diceOptions; */
|
||||||
|
|
|
||||||
|
|
@ -265,152 +265,14 @@ export default class DhpActor extends Actor {
|
||||||
* @param {object} [config.costs]
|
* @param {object} [config.costs]
|
||||||
*/
|
*/
|
||||||
async diceRoll(config, action) {
|
async diceRoll(config, action) {
|
||||||
// console.log(config)
|
config.source = {...(config.source ?? {}), actor: this._id};
|
||||||
config.source = {...(config.source ?? {}), actor: this.id};
|
config.data = this.getRollData()
|
||||||
const newConfig = {
|
const roll = await CONFIG.Dice.daggerheart[this.type === 'character' ? 'DualityRoll' : 'D20Roll'].build(config)
|
||||||
...config,
|
|
||||||
actor: this.system
|
|
||||||
}
|
|
||||||
const roll = await CONFIG.Dice.daggerheart[this.type === 'character' ? 'DualityRoll' : 'D20Roll'].build(newConfig)
|
|
||||||
return config;
|
return config;
|
||||||
/* let hopeDice = 'd12',
|
}
|
||||||
fearDice = 'd12',
|
|
||||||
advantageDice = 'd6',
|
|
||||||
disadvantageDice = 'd6',
|
|
||||||
advantage = config.event.altKey ? true : config.event.ctrlKey ? false : null,
|
|
||||||
targets,
|
|
||||||
modifiers = this.formatRollModifier(config.roll),
|
|
||||||
rollConfig,
|
|
||||||
formula,
|
|
||||||
hope,
|
|
||||||
fear;
|
|
||||||
|
|
||||||
if (!config.event.shiftKey && !config.event.altKey && !config.event.ctrlKey) {
|
getRollData() {
|
||||||
const dialogClosed = new Promise((resolve, _) => {
|
return this.system;
|
||||||
this.type === 'character'
|
|
||||||
? new RollSelectionDialog(
|
|
||||||
this.system.experiences,
|
|
||||||
config.costs,
|
|
||||||
action,
|
|
||||||
resolve
|
|
||||||
).render(true)
|
|
||||||
: new NpcRollSelectionDialog(
|
|
||||||
this.system.experiences,
|
|
||||||
resolve
|
|
||||||
).render(true);
|
|
||||||
});
|
|
||||||
rollConfig = await dialogClosed;
|
|
||||||
|
|
||||||
advantage = rollConfig.advantage;
|
|
||||||
hopeDice = rollConfig.hope;
|
|
||||||
fearDice = rollConfig.fear;
|
|
||||||
if(rollConfig.costs) config.costs = rollConfig.costs;
|
|
||||||
|
|
||||||
rollConfig.experiences.forEach(x =>
|
|
||||||
modifiers.push({
|
|
||||||
value: x.value,
|
|
||||||
label: x.value >= 0 ? `+${x.value}` : `-${x.value}`,
|
|
||||||
title: x.description
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
if (this.type === 'character') {
|
|
||||||
const automateHope = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).hope;
|
|
||||||
|
|
||||||
if (automateHope && result.hopeUsed) {
|
|
||||||
await this.update({
|
|
||||||
'system.resources.hope.value': this.system.resources.hope.value - result.hopeUsed
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.type === 'character') {
|
|
||||||
formula = `1${hopeDice} + 1${fearDice}${advantage === true ? ` + 1d6` : advantage === false ? ` - 1d6` : ''}`;
|
|
||||||
} else {
|
|
||||||
formula = `${advantage === true || advantage === false ? 2 : 1}d20${advantage === true ? 'kh' : advantage === false ? 'kl' : ''}`;
|
|
||||||
}
|
|
||||||
formula += ` ${modifiers.map(x => `+ ${x.value}`).join(' ')}`;
|
|
||||||
const roll = await Roll.create(formula).evaluate(),
|
|
||||||
dice = roll.dice.flatMap(dice => ({
|
|
||||||
denomination: dice.denomination,
|
|
||||||
number: dice.number,
|
|
||||||
total: dice.total,
|
|
||||||
results: dice.results.map(result => ({ result: result.result, discarded: !result.active }))
|
|
||||||
}));
|
|
||||||
config.roll.evaluated = roll;
|
|
||||||
|
|
||||||
if (this.type === 'character') {
|
|
||||||
setDiceSoNiceForDualityRoll(roll, advantage);
|
|
||||||
hope = roll.dice[0].results[0].result;
|
|
||||||
fear = roll.dice[1].results[0].result;
|
|
||||||
if (
|
|
||||||
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation).hope &&
|
|
||||||
config.roll.type === 'action'
|
|
||||||
) {
|
|
||||||
if (hope > fear) {
|
|
||||||
await this.update({
|
|
||||||
'system.resources.hope.value': Math.min(
|
|
||||||
this.system.resources.hope.value + 1,
|
|
||||||
this.system.resources.hope.max
|
|
||||||
)
|
|
||||||
});
|
|
||||||
} else if (hope === fear) {
|
|
||||||
await this.update({
|
|
||||||
'system.resources': {
|
|
||||||
'hope.value': Math.min(
|
|
||||||
this.system.resources.hope.value + 1,
|
|
||||||
this.system.resources.hope.max
|
|
||||||
),
|
|
||||||
'stress.value': Math.max(this.system.resources.stress.value - 1, 0)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.targets?.length) {
|
|
||||||
targets = config.targets.map(target => {
|
|
||||||
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion
|
|
||||||
target.hit = roll.total >= difficulty;
|
|
||||||
return target;
|
|
||||||
});
|
|
||||||
} else if(config.roll.difficulty) roll.success = roll.total >= config.roll.difficulty;
|
|
||||||
|
|
||||||
if (config.chatMessage) {
|
|
||||||
const configRoll = {
|
|
||||||
title: config.title,
|
|
||||||
origin: this.id,
|
|
||||||
dice,
|
|
||||||
roll,
|
|
||||||
modifiers: modifiers.filter(x => x.label),
|
|
||||||
advantageState: advantage,
|
|
||||||
action: config.source,
|
|
||||||
hasDamage: config.hasDamage,
|
|
||||||
hasEffect: config.hasEffect
|
|
||||||
};
|
|
||||||
if (this.type === 'character') {
|
|
||||||
configRoll.hope = { dice: hopeDice, value: hope };
|
|
||||||
configRoll.fear = { dice: fearDice, value: fear };
|
|
||||||
configRoll.advantage = { dice: advantageDice, value: roll.dice[2]?.results[0].result ?? null };
|
|
||||||
}
|
|
||||||
// if (damage) configRoll.damage = damage;
|
|
||||||
if (targets) configRoll.targets = targets;
|
|
||||||
const systemData =
|
|
||||||
this.type === 'character' && !config.roll.simple ? new DHDualityRoll(configRoll) : configRoll,
|
|
||||||
cls = getDocumentClass('ChatMessage'),
|
|
||||||
msg = new cls({
|
|
||||||
type: config.chatMessage.type ?? 'dualityRoll',
|
|
||||||
sound: config.chatMessage.mute ? null : CONFIG.sounds.dice,
|
|
||||||
system: systemData,
|
|
||||||
content: config.chatMessage.template,
|
|
||||||
rolls: [roll]
|
|
||||||
});
|
|
||||||
|
|
||||||
await cls.create(msg.toObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
return config; */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
formatRollModifier(roll) {
|
formatRollModifier(roll) {
|
||||||
|
|
@ -561,104 +423,4 @@ export default class DhpActor extends Actor {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/* async takeHealing(healing, type) {
|
|
||||||
let update = {};
|
|
||||||
switch (type) {
|
|
||||||
case SYSTEM.GENERAL.healingTypes.health.id:
|
|
||||||
update = {
|
|
||||||
'system.resources.hitPoints.value': Math.min(
|
|
||||||
this.system.resources.hitPoints.value + healing,
|
|
||||||
this.system.resources.hitPoints.max
|
|
||||||
)
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case SYSTEM.GENERAL.healingTypes.stress.id:
|
|
||||||
update = {
|
|
||||||
'system.resources.stress.value': Math.min(
|
|
||||||
this.system.resources.stress.value + healing,
|
|
||||||
this.system.resources.stress.max
|
|
||||||
)
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (game.user.isGM) {
|
|
||||||
await this.update(update);
|
|
||||||
} else {
|
|
||||||
await game.socket.emit(`system.${SYSTEM.id}`, {
|
|
||||||
action: socketEvent.GMUpdate,
|
|
||||||
data: {
|
|
||||||
action: GMUpdateEvent.UpdateDocument,
|
|
||||||
uuid: this.uuid,
|
|
||||||
update: update
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
//Move to action-scope?
|
|
||||||
/* async useAction(action) {
|
|
||||||
const userTargets = Array.from(game.user.targets);
|
|
||||||
const otherTarget = action.target.type === SYSTEM.ACTIONS.targetTypes.other.id;
|
|
||||||
if (otherTarget && userTargets.length === 0) {
|
|
||||||
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.ActionRequiresTarget'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action.cost.type != null && action.cost.value != null) {
|
|
||||||
if (
|
|
||||||
this.system.resources[action.cost.type].value - action.cost.value <=
|
|
||||||
this.system.resources[action.cost.type].min
|
|
||||||
) {
|
|
||||||
ui.notifications.error(game.i18n.localize(`Insufficient ${action.cost.type} to use this ability`));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// const targets = otherTarget ? userTargets : [game.user.character];
|
|
||||||
if (action.damage.type) {
|
|
||||||
let roll = { formula: action.damage.value, result: action.damage.value };
|
|
||||||
if (Number.isNaN(Number.parseInt(action.damage.value))) {
|
|
||||||
roll = await new Roll(`1${action.damage.value}`).evaluate();
|
|
||||||
}
|
|
||||||
|
|
||||||
const cls = getDocumentClass('ChatMessage');
|
|
||||||
const msg = new cls({
|
|
||||||
user: game.user.id,
|
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
|
||||||
'systems/daggerheart/templates/chat/damage-roll.hbs',
|
|
||||||
{
|
|
||||||
roll: roll.formula,
|
|
||||||
total: roll.result,
|
|
||||||
type: action.damage.type
|
|
||||||
}
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
cls.create(msg.toObject());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (action.healing.type) {
|
|
||||||
let roll = { formula: action.healing.value, result: action.healing.value };
|
|
||||||
if (Number.isNaN(Number.parseInt(action.healing.value))) {
|
|
||||||
roll = await new Roll(`1${action.healing.value}`).evaluate();
|
|
||||||
}
|
|
||||||
|
|
||||||
const cls = getDocumentClass('ChatMessage');
|
|
||||||
const msg = new cls({
|
|
||||||
user: game.user.id,
|
|
||||||
content: await foundry.applications.handlebars.renderTemplate(
|
|
||||||
'systems/daggerheart/templates/chat/healing-roll.hbs',
|
|
||||||
{
|
|
||||||
roll: roll.formula,
|
|
||||||
total: roll.result,
|
|
||||||
type: action.healing.type
|
|
||||||
}
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
cls.create(msg.toObject());
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,45 +60,45 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
||||||
super.close(options);
|
super.close(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getActor(id) {
|
||||||
|
return game.actors.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
getAction(actor, itemId, actionId) {
|
||||||
|
const item = actor.items.get(itemId),
|
||||||
|
action = actor.system.attack?._id === actionId ? actor.system.attack : item?.system?.actions?.find(a => a._id === actionId);
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
onRollDamage = async (event, message) => {
|
onRollDamage = async (event, message) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const actor = game.actors.get(message.system.source.actor);
|
const actor = this.getActor(message.system.source.actor);
|
||||||
if (!actor || !game.user.isGM) return true;
|
if (!actor || !game.user.isGM) return true;
|
||||||
if(message.system.source.item && message.system.source.action) {
|
if(message.system.source.item && message.system.source.action) {
|
||||||
const item = actor.items.get(message.system.source.item),
|
const action = this.getAction(actor, message.system.source.item, message.system.source.action);
|
||||||
action = item?.system?.actions?.find(a => a._id === message.system.source.action);
|
if(!action || !action?.rollDamage) return;
|
||||||
if(!item || !action || !action?.rollDamage) return;
|
|
||||||
await action.rollDamage(event, message);
|
await action.rollDamage(event, message);
|
||||||
} else {
|
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onRollHealing = async (event, message) => {
|
onRollHealing = async (event, message) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const actor = game.actors.get(message.system.source.actor);
|
const actor = this.getActor(message.system.source.actor);
|
||||||
if (!actor || !game.user.isGM) return true;
|
if (!actor || !game.user.isGM) return true;
|
||||||
if(message.system.source.item && message.system.source.action) {
|
if(message.system.source.item && message.system.source.action) {
|
||||||
const item = actor.items.get(message.system.source.item),
|
const action = this.getAction(actor, message.system.source.item, message.system.source.action);
|
||||||
action = item?.system?.actions?.find(a => a._id === message.system.source.action);
|
if(!action || !action?.rollHealing) return;
|
||||||
if(!item || !action || !action?.rollHealing) return;
|
|
||||||
await action.rollHealing(event, message);
|
await action.rollHealing(event, message);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
onApplyEffect = async (event, message) => {
|
onApplyEffect = async (event, message) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
const actor = game.actors.get(message.system.source.actor);
|
const actor = this.getActor(message.system.source.actor);
|
||||||
if (!actor || !game.user.isGM) return true;
|
if (!actor || !game.user.isGM) return true;
|
||||||
if(message.system.source.item && message.system.source.action) {
|
if(message.system.source.item && message.system.source.action) {
|
||||||
const item = actor.items.get(message.system.source.item),
|
const action = this.getAction(actor, message.system.source.item, message.system.source.action);
|
||||||
action = item?.system?.actions?.find(a => a._id === message.system.source.action);
|
if(!action || !action?.applyEffects) return;
|
||||||
if(!item || !action || !action.applyEffects) return;
|
|
||||||
await action.applyEffects(event, message);
|
await action.applyEffects(event, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,51 @@
|
||||||
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
||||||
|
<div class="dice-flavor">{{title}}</div>
|
||||||
<div class="dice-result">
|
<div class="dice-result">
|
||||||
<div class="dice-formula">{{roll.formula}}</div>
|
<div class="dice-formula">{{roll.formula}}</div>
|
||||||
<div class="dice-tooltip">
|
<div class="dice-tooltip">
|
||||||
<ol class="dice-rolls">
|
<div class="wrapper">
|
||||||
<div class="dice-hope-container">
|
<section class="tooltip-part">
|
||||||
{{#each dice}}
|
<div class="dice">
|
||||||
|
{{#each roll.dice}}
|
||||||
<header class="part-header flexrow">
|
<header class="part-header flexrow">
|
||||||
<span class="part-formula">{{number}}{{denomination}}</span>
|
<span class="part-formula">{{formula}}</span>
|
||||||
<span class="part-total">{{total}}</span>
|
<span class="part-total">{{total}}</span>
|
||||||
</header>
|
</header>
|
||||||
<div class="flexrow">
|
<div class="flexrow">
|
||||||
<ol class="dice-rolls">
|
<ol class="dice-rolls">
|
||||||
{{#each results}}
|
{{#each results}}
|
||||||
<li class="roll die {{../denomination}}{{#if discarded}} discarded{{/if}} min">{{result}}</li>
|
<li class="roll die {{../dice}}{{#if discarded}} discarded{{/if}} min">{{result}}</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ol>
|
</ol>
|
||||||
<div class="attack-roll-advantage-container">{{#if ../advantageState}}{{localize "DAGGERHEART.General.Advantage.Full"}}{{/if}}{{#if (eq ../advantageState false)}}{{localize "DAGGERHEART.General.Disadvantage.Full"}}{{/if}}</div>
|
<div class="attack-roll-advantage-container">
|
||||||
|
{{#if (eq ../roll.advantage.type 1)}}{{localize "DAGGERHEART.General.Advantage.Full"}}{{/if}}{{#if (eq ../roll.advantage.type -1)}}{{localize "DAGGERHEART.General.Disadvantage.Full"}}{{/if}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
<div class="modifiers-container">
|
</section>
|
||||||
{{#each modifiers}}
|
</div>
|
||||||
<li class="modifier-value" data-value="{{value}}" title="{{title}}">{{label}}</li>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
</ol>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="dice-total">
|
<div class="dice-total">
|
||||||
<div class="dice-total-value">{{roll.total}}</div>
|
<div class="dice-total-value">{{roll.total}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{#if (gt targets.length 0)}}
|
||||||
|
<div class="target-section">
|
||||||
|
{{#each targets as |target|}}
|
||||||
|
<div class="dice-total target-container {{#if target.hit}}hit{{else}}miss{{/if}}" data-token="{{target.id}}">
|
||||||
|
<img src="{{target.img}}" />
|
||||||
|
<div class="target-inner-container">
|
||||||
|
{{#if target.hit}}{{localize "Hit"}}{{else}}{{localize "Miss"}}{{/if}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if hasDamage}}
|
||||||
|
<div class="flexrow">
|
||||||
|
<button class="duality-action duality-action-damage" data-value="{{roll.total}}"><span>Roll Damage</span></button>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -49,13 +49,43 @@
|
||||||
|
|
||||||
<fieldset class="two-columns even">
|
<fieldset class="two-columns even">
|
||||||
<legend>{{localize "DAGGERHEART.Sheets.Adversary.Attack"}}</legend>
|
<legend>{{localize "DAGGERHEART.Sheets.Adversary.Attack"}}</legend>
|
||||||
|
<button data-action="attackConfigure">Configure</button>
|
||||||
|
<button data-action="attackRoll">Attack</button>
|
||||||
|
<fieldset class="action-category" style="grid-column: 1 / -1;">
|
||||||
|
<legend class="action-category-label" data-action="toggleSection" data-section="range">
|
||||||
|
<div>Name</div>
|
||||||
|
</legend>
|
||||||
|
<div class="action-category-data open">
|
||||||
|
{{formGroup systemFields.attack.fields.name value=source.system.attack.name name="system.attack.name"}}
|
||||||
|
{{formGroup systemFields.attack.fields.img value=source.img label="Icon" name="system.attack.img"}}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<div>
|
||||||
|
<fieldset class="action-category">
|
||||||
|
<legend class="action-category-label" data-action="toggleSection" data-section="range">
|
||||||
|
<div>Bonus</div>
|
||||||
|
</legend>
|
||||||
|
<div class="action-category-data open">
|
||||||
|
{{formField systemFields.attack.fields.roll.fields.bonus value=source.system.attack.roll.bonus name="system.attack.roll.bonus"}}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
{{> 'systems/daggerheart/templates/views/actionTypes/range-target.hbs' fields=(object range=systemFields.attack.fields.range target=systemFields.attack.fields.target.fields) source=(object target=source.system.attack.target range=source.system.attack.range) path="system.attack."}}
|
||||||
|
</div>
|
||||||
|
{{> 'systems/daggerheart/templates/views/actionTypes/damage.hbs' fields=systemFields.attack.fields.damage.fields.parts.element.fields source=source.system.attack.damage path="system.attack."}}
|
||||||
|
<div style="grid-column: 1 / -1;">
|
||||||
|
{{> 'systems/daggerheart/templates/views/actionTypes/effect.hbs'}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{{!-- <legend>{{localize "DAGGERHEART.Sheets.Adversary.Attack"}}</legend>
|
||||||
|
|
||||||
{{formGroup systemFields.attack.fields.name value=source.system.attack.name}}
|
{{formGroup systemFields.attack.fields.name value=source.system.attack.name}}
|
||||||
<button data-action="attackRoll">Attack</button>
|
<button data-action="attackRoll">Attack</button>
|
||||||
{{formGroup systemFields.attack.fields.modifier value=source.system.attack.modifier}}
|
{{formGroup systemFields.attack.fields.modifier value=source.system.attack.modifier}}
|
||||||
{{formGroup systemFields.attack.fields.range value=source.system.attack.range localize=true}}
|
{{formGroup systemFields.attack.fields.range value=source.system.attack.range localize=true}}
|
||||||
{{formGroup systemFields.attack.fields.damage.fields.value value=source.system.attack.damage.value}}
|
{{formGroup systemFields.attack.fields.damage.fields.value value=source.system.attack.damage.value}}
|
||||||
{{formGroup systemFields.attack.fields.damage.fields.type value=source.system.attack.damage.type localize=true}}
|
{{formGroup systemFields.attack.fields.damage.fields.type value=source.system.attack.damage.type localize=true}} --}}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,10 @@
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
<div class="tab {{this.tabs.config.cssClass}}" data-group="primary" data-tab="config">
|
<div class="tab {{this.tabs.config.cssClass}}" data-group="primary" data-tab="config">
|
||||||
|
{{#unless isNPC}}
|
||||||
{{> 'systems/daggerheart/templates/views/actionTypes/uses.hbs' fields=fields.uses.fields source=source.uses}}
|
{{> 'systems/daggerheart/templates/views/actionTypes/uses.hbs' fields=fields.uses.fields source=source.uses}}
|
||||||
{{> 'systems/daggerheart/templates/views/actionTypes/cost.hbs' fields=fields.cost.element.fields source=source.cost}}
|
{{> 'systems/daggerheart/templates/views/actionTypes/cost.hbs' fields=fields.cost.element.fields source=source.cost}}
|
||||||
|
{{/unless}}
|
||||||
{{#if fields.target}}{{> 'systems/daggerheart/templates/views/actionTypes/range-target.hbs' fields=(object range=fields.range target=fields.target.fields) source=(object target=source.target range=source.range)}}{{/if}}
|
{{#if fields.target}}{{> 'systems/daggerheart/templates/views/actionTypes/range-target.hbs' fields=(object range=fields.range target=fields.target.fields) source=(object target=source.target range=source.range)}}{{/if}}
|
||||||
</div>
|
</div>
|
||||||
<div class="tab {{this.tabs.effect.cssClass}}" data-group="primary" data-tab="effect">
|
<div class="tab {{this.tabs.effect.cssClass}}" data-group="primary" data-tab="effect">
|
||||||
|
|
|
||||||
|
|
@ -4,33 +4,49 @@
|
||||||
<div>Damage</div>
|
<div>Damage</div>
|
||||||
</legend>
|
</legend>
|
||||||
<div class="action-category-data open">
|
<div class="action-category-data open">
|
||||||
<div class="fas fa-plus icon-button" data-action="addDamage"></div>
|
{{#unless @root.isNPC}}
|
||||||
{{#if @root.hasBaseDamage}}
|
<div class="fas fa-plus icon-button" data-action="addDamage"></div>
|
||||||
<div>
|
{{#if @root.hasBaseDamage}}
|
||||||
{{!-- <input type="checkbox" data-action="addBaseDamage"{{#if @root.hasBaseDamage}} checked{{/if}}> --}}
|
<div>
|
||||||
{{formField @root.fields.damage.fields.includeBase value=@root.source.damage.includeBase label="Include Item Damage" name="damage.includeBase" }}
|
{{!-- <input type="checkbox" data-action="addBaseDamage"{{#if @root.hasBaseDamage}} checked{{/if}}> --}}
|
||||||
</div>
|
{{formField @root.fields.damage.fields.includeBase value=@root.source.damage.includeBase label="Include Item Damage" name="damage.includeBase" }}
|
||||||
{{/if}}
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{/unless}}
|
||||||
{{#each source.parts as |dmg index|}}
|
{{#each source.parts as |dmg index|}}
|
||||||
{{#with (@root.getRealIndex index) as | realIndex |}}
|
{{#if @root.isNPC}}
|
||||||
<fieldset{{#if dmg.base}} disabled{{/if}}>
|
{{formField ../fields.custom.fields.enabled value=dmg.custom.enabled name=(concat ../path "damage.parts." index ".custom.enabled")}}
|
||||||
{{#unless dmg.base}}
|
|
||||||
{{formField ../../fields.custom.fields.enabled value=dmg.custom.enabled name=(concat "damage.parts." realIndex ".custom.enabled")}}
|
|
||||||
{{/unless}}
|
|
||||||
{{#if dmg.custom.enabled}}
|
{{#if dmg.custom.enabled}}
|
||||||
{{formField ../../fields.custom.fields.formula value=dmg.custom.formula name=(concat "damage.parts." realIndex ".custom.formula") localize=true}}
|
{{formField ../fields.custom.fields.formula value=dmg.custom.formula name=(concat ../path "damage.parts." index ".custom.formula") localize=true}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="multi-display">
|
<div class="multi-display">
|
||||||
{{formField ../../fields.multiplier value=dmg.multiplier name=(concat "damage.parts." realIndex ".multiplier") localize=true}}
|
{{formField ../fields.flatMultiplier value=dmg.flatMultiplier name=(concat "damage.parts." realIndex ".flatMultiplier") label="Multiplier" }}
|
||||||
{{formField ../../fields.dice value=dmg.dice name=(concat "damage.parts." realIndex ".dice")}}
|
{{formField ../fields.dice value=dmg.dice name=(concat ../path "damage.parts." index ".dice")}}
|
||||||
{{formField ../../fields.bonus value=dmg.bonus name=(concat "damage.parts." realIndex ".bonus") localize=true}}
|
{{formField ../fields.bonus value=dmg.bonus name=(concat ../path "damage.parts." index ".bonus") localize=true}}
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}}
|
{{else}}
|
||||||
<input type="hidden" name="damage.parts.{{realIndex}}.base" value="{{dmg.base}}">
|
{{#with (@root.getRealIndex index) as | realIndex |}}
|
||||||
{{#unless dmg.base}}<div class="fas fa-trash" data-action="removeDamage" data-index="{{realIndex}}"></div>{{/unless}}
|
<fieldset{{#if dmg.base}} disabled{{/if}}>
|
||||||
</fieldset>
|
{{#unless dmg.base}}
|
||||||
{{/with}}
|
{{formField ../../fields.custom.fields.enabled value=dmg.custom.enabled name=(concat "damage.parts." realIndex ".custom.enabled")}}
|
||||||
|
{{/unless}}
|
||||||
|
{{#if dmg.custom.enabled}}
|
||||||
|
{{formField ../../fields.custom.fields.formula value=dmg.custom.formula name=(concat "damage.parts." realIndex ".custom.formula") localize=true}}
|
||||||
|
{{else}}
|
||||||
|
<div class="multi-display">
|
||||||
|
{{formField ../../fields.multiplier value=dmg.multiplier name=(concat "damage.parts." realIndex ".multiplier") localize=true}}
|
||||||
|
{{#if (eq dmg.multiplier 'flat')}}{{formField ../../fields.flatMultiplier value=dmg.flatMultiplier name=(concat "damage.parts." realIndex ".flatMultiplier") }}{{/if}}
|
||||||
|
{{formField ../../fields.dice value=dmg.dice name=(concat "damage.parts." realIndex ".dice")}}
|
||||||
|
{{formField ../../fields.bonus value=dmg.bonus name=(concat "damage.parts." realIndex ".bonus") localize=true}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
{{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}}
|
||||||
|
<input type="hidden" name="damage.parts.{{realIndex}}.base" value="{{dmg.base}}">
|
||||||
|
{{#unless dmg.base}}<div class="fas fa-trash" data-action="removeDamage" data-index="{{realIndex}}"></div>{{/unless}}
|
||||||
|
</fieldset>
|
||||||
|
{{/with}}
|
||||||
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
@ -3,15 +3,15 @@
|
||||||
<div>Range{{#if fields.target}} & Target{{/if}}</div>
|
<div>Range{{#if fields.target}} & Target{{/if}}</div>
|
||||||
</legend>
|
</legend>
|
||||||
<div class="action-category-data open">
|
<div class="action-category-data open">
|
||||||
{{formField fields.range value=source.range label="Range" name="range" localize=true}}
|
{{formField fields.range value=source.range label="Range" name=(concat path "range") localize=true}}
|
||||||
</div>
|
</div>
|
||||||
{{#if fields.target}}
|
{{#if fields.target}}
|
||||||
<div class="action-category-data open">
|
<div class="action-category-data open">
|
||||||
<div class="multi-display">
|
<div class="multi-display">
|
||||||
{{#if (and source.target.type (not (eq source.target.type 'self')))}}
|
{{#if (and source.target.type (not (eq source.target.type 'self')))}}
|
||||||
{{ formField fields.target.amount value=source.target.amount label="Amount" name="target.amount" }}
|
{{ formField fields.target.amount value=source.target.amount label="Amount" name=(concat path "target.amount") }}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{ formField fields.target.type value=source.target.type label="Target" name="target.type" localize=true }}
|
{{ formField fields.target.type value=source.target.type label="Target" name=(concat path "target.type") localize=true }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,12 @@
|
||||||
<div>Roll</div>
|
<div>Roll</div>
|
||||||
</legend>
|
</legend>
|
||||||
<div class="action-category-data open">
|
<div class="action-category-data open">
|
||||||
{{formField fields.type label="Type" name="roll.type" value=source.type localize=true}}
|
{{#if @root.isNPC}}
|
||||||
{{formField fields.trait label="Trait" name="roll.trait" value=source.trait localize=true}}
|
{{formField fields.bonus label="Bonus" name="roll.bonus" value=source.bonus}}
|
||||||
{{formField fields.difficulty label="Difficulty" name="roll.difficulty" value=source.difficulty}}
|
{{else}}
|
||||||
|
{{formField fields.type label="Type" name="roll.type" value=source.type localize=true}}
|
||||||
|
{{formField fields.trait label="Trait" name="roll.trait" value=source.trait localize=true}}
|
||||||
|
{{formField fields.difficulty label="Difficulty" name="roll.difficulty" value=source.difficulty}}
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue