mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
Merged with action branch
This commit is contained in:
commit
90e7000b9c
19 changed files with 280 additions and 496 deletions
|
|
@ -60,9 +60,12 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
|||
context.tabs = this._getTabs();
|
||||
context.config = SYSTEM;
|
||||
if (!!this.action.effects) context.effects = this.action.effects.map(e => this.action.item.effects.get(e._id));
|
||||
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.disableOption = this.disableOption.bind(this);
|
||||
context.isNPC = this.action.actor.type !== 'character';
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
@ -74,9 +77,9 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
|||
disableOption(index, options, choices) {
|
||||
const filtered = foundry.utils.deepClone(options);
|
||||
Object.keys(filtered).forEach(o => {
|
||||
if(choices.find((c, idx) => c.type === o && index !== idx)) delete filtered[o];
|
||||
if (choices.find((c, idx) => c.type === o && index !== idx)) delete filtered[o];
|
||||
});
|
||||
return filtered
|
||||
return filtered;
|
||||
}
|
||||
|
||||
getRealIndex(index) {
|
||||
|
|
@ -95,11 +98,18 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) {
|
|||
static async updateForm(event, _, formData) {
|
||||
const submitData = this._prepareSubmitData(event, formData),
|
||||
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
|
||||
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 });
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl
|
|||
}
|
||||
|
||||
async _prepareContext(_options) {
|
||||
console.log(this.costs);
|
||||
const updatedCosts = this.action.calcCosts(this.costs),
|
||||
updatedUses = this.action.calcUses(this.uses);
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export class DHRoll extends Roll {
|
|||
config = await DialogClass.configure(config, message);
|
||||
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) {
|
||||
if (Hooks.call(`${SYSTEM.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false)
|
||||
|
|
@ -101,9 +101,6 @@ export class DualityDie extends foundry.dice.terms.Die {
|
|||
export class D20Roll extends DHRoll {
|
||||
constructor(formula, data = {}, options = {}) {
|
||||
super(formula, data, options);
|
||||
// console.log(data, options)
|
||||
// this.options = this._prepareData(data);
|
||||
// this.options = options;
|
||||
this.createBaseDice();
|
||||
this.configureModifiers();
|
||||
|
||||
|
|
@ -194,10 +191,10 @@ export class D20Roll extends DHRoll {
|
|||
this.applyBaseBonus();
|
||||
|
||||
this.options.experiences?.forEach(m => {
|
||||
if (this.options.actor.experiences?.[m])
|
||||
if (this.options.data.experiences?.[m])
|
||||
this.options.roll.modifiers.push({
|
||||
label: this.options.actor.experiences[m].description,
|
||||
value: this.options.actor.experiences[m].total
|
||||
label: this.options.data.experiences[m].description,
|
||||
value: this.options.data.experiences[m].total
|
||||
});
|
||||
});
|
||||
this.options.roll.modifiers?.forEach(m => {
|
||||
|
|
@ -214,31 +211,17 @@ export class D20Roll extends DHRoll {
|
|||
}
|
||||
|
||||
applyBaseBonus() {
|
||||
// if(this.options.action) {
|
||||
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));
|
||||
}) */
|
||||
// }
|
||||
this.terms.push(...this.formatModifier(this.options.data.attack.roll.bonus));
|
||||
}
|
||||
|
||||
static async postEvaluate(roll, config = {}) {
|
||||
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 => {
|
||||
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion;
|
||||
target.hit = roll.total >= 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.formula = roll.formula;
|
||||
config.roll.advantage = {
|
||||
|
|
@ -247,10 +230,19 @@ export class D20Roll extends DHRoll {
|
|||
value: roll.dAdvantage?.total
|
||||
};
|
||||
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() {
|
||||
return this.options.actor.getRollData();
|
||||
return this.options.data();
|
||||
}
|
||||
|
||||
formatModifier(modifier) {
|
||||
|
|
@ -357,7 +349,6 @@ export class DualityRoll extends D20Roll {
|
|||
const dieFaces = 6,
|
||||
bardRallyFaces = this.hasBarRally,
|
||||
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 (bardRallyFaces) {
|
||||
|
|
@ -376,22 +367,15 @@ export class DualityRoll extends D20Roll {
|
|||
}
|
||||
|
||||
applyBaseBonus() {
|
||||
// if(this.options.action) {
|
||||
// console.log(this.options, this.options.actor.system.traits[this.options.roll.trait].bonus)
|
||||
// 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)); */
|
||||
if (!this.options.roll.modifiers) this.options.roll.modifiers = [];
|
||||
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
|
||||
value: this.options.data.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 = {}) {
|
||||
console.log(roll, config);
|
||||
super.postEvaluate(roll, config);
|
||||
config.roll.hope = {
|
||||
dice: roll.dHope.denomination,
|
||||
|
|
@ -427,30 +411,10 @@ export class DamageRoll extends DHRoll {
|
|||
static DefaultDialog = DamageDialog;
|
||||
|
||||
static async postEvaluate(roll, config = {}) {
|
||||
console.log(roll, config);
|
||||
config.roll = {
|
||||
// formula : config.formula,
|
||||
result: roll.total,
|
||||
dice: roll.dice
|
||||
};
|
||||
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';
|
||||
|
||||
const { ActorSheetV2 } = foundry.applications.sheets;
|
||||
|
|
@ -9,6 +10,7 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
actions: {
|
||||
reactionRoll: this.reactionRoll,
|
||||
attackRoll: this.attackRoll,
|
||||
attackConfigure: this.attackConfigure,
|
||||
addExperience: this.addExperience,
|
||||
removeExperience: this.removeExperience,
|
||||
toggleHP: this.toggleHP,
|
||||
|
|
@ -51,7 +53,9 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
const context = await super._prepareContext(_options);
|
||||
context.document = this.document;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -78,25 +82,11 @@ export default class AdversarySheet extends DaggerheartSheet(ActorSheetV2) {
|
|||
}
|
||||
|
||||
static async attackRoll(event) {
|
||||
const { modifier, damage, name: attackName } = this.actor.system.attack,
|
||||
config = {
|
||||
event: event,
|
||||
title: attackName,
|
||||
roll: {
|
||||
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);
|
||||
this.actor.system.attack.use(event);
|
||||
}
|
||||
|
||||
static async attackConfigure(event) {
|
||||
await new DHActionConfig(this.document.system.attack).render(true);
|
||||
}
|
||||
|
||||
static async addExperience() {
|
||||
|
|
|
|||
|
|
@ -300,13 +300,15 @@ export const diceTypes = {
|
|||
d4: 'd4',
|
||||
d6: 'd6',
|
||||
d8: 'd8',
|
||||
d10: 'd10',
|
||||
d12: 'd12',
|
||||
d20: 'd20'
|
||||
};
|
||||
|
||||
export const multiplierTypes = {
|
||||
proficiency: 'Proficiency',
|
||||
spellcast: 'Spellcast'
|
||||
spellcast: 'Spellcast',
|
||||
flat: 'Flat'
|
||||
};
|
||||
|
||||
export const getDiceSoNicePresets = () => {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import DamageSelectionDialog from '../../applications/damageSelectionDialog.mjs'
|
|||
import CostSelectionDialog from '../../applications/costSelectionDialog.mjs';
|
||||
import { abilities } from '../../config/actorConfig.mjs';
|
||||
import { DHActionDiceData, DHDamageData, DHDamageField } from './actionDice.mjs';
|
||||
import DhpActor from '../../documents/actor.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
|
|
@ -86,8 +87,8 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
range: new fields.StringField({
|
||||
choices: SYSTEM.GENERAL.range,
|
||||
required: false,
|
||||
blank: true,
|
||||
initial: null
|
||||
blank: true
|
||||
// initial: null
|
||||
}),
|
||||
...this.defineExtraSchema()
|
||||
};
|
||||
|
|
@ -99,7 +100,8 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
roll: new fields.SchemaField({
|
||||
type: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.GENERAL.rollTypes }),
|
||||
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({
|
||||
trait: new fields.StringField({ nullable: true, initial: null, choices: SYSTEM.ACTOR.abilities }),
|
||||
|
|
@ -151,7 +153,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
get actor() {
|
||||
return this.item?.actor;
|
||||
return this.item instanceof DhpActor ? this.item : this.item?.actor;
|
||||
}
|
||||
|
||||
get chatTemplate() {
|
||||
|
|
@ -203,6 +205,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
source: {
|
||||
item: this.item._id,
|
||||
action: this._id
|
||||
// action: this
|
||||
},
|
||||
type: this.type,
|
||||
hasDamage: !!this.damage?.parts?.length,
|
||||
|
|
@ -236,25 +239,25 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
this.spendCost(config.costs.values);
|
||||
this.spendUses(config.uses);
|
||||
|
||||
// console.log(config)
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/* ROLL */
|
||||
hasRoll() {
|
||||
return this.roll?.type && this.roll?.trait;
|
||||
// return this.roll?.type && this.roll?.trait;
|
||||
return this.roll?.type;
|
||||
}
|
||||
|
||||
async proceedRoll(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,
|
||||
roll: {
|
||||
modifiers: [],
|
||||
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,
|
||||
difficulty: this.roll?.difficulty
|
||||
}
|
||||
|
|
@ -359,7 +362,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
name: actor.actor.name,
|
||||
img: actor.actor.img,
|
||||
difficulty: actor.actor.system.difficulty,
|
||||
evasion: actor.actor.system.evasion?.value
|
||||
evasion: actor.actor.system.evasion?.total
|
||||
};
|
||||
}
|
||||
/* TARGET */
|
||||
|
|
@ -375,7 +378,6 @@ export class DHBaseAction extends foundry.abstract.DataModel {
|
|||
async applyEffects(event, data, force = false) {
|
||||
if (!this.effects?.length || !data.system.targets.length) return;
|
||||
data.system.targets.forEach(async token => {
|
||||
// console.log(token, force)
|
||||
if (!token.hit && !force) return;
|
||||
this.effects.forEach(async e => {
|
||||
const actor = canvas.tokens.get(token.id)?.actor,
|
||||
|
|
@ -497,7 +499,6 @@ export class DHHealingAction extends DHBaseAction {
|
|||
}
|
||||
|
||||
async rollHealing(event, data) {
|
||||
console.log(event, data);
|
||||
let formula = this.healing.value.getFormula(this.actor);
|
||||
|
||||
if (!formula || formula == '') return;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export class DHActionDiceData extends foundry.abstract.DataModel {
|
|||
initial: 'proficiency',
|
||||
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' }),
|
||||
bonus: new fields.NumberField({ nullable: true, initial: null, label: 'Bonus' }),
|
||||
custom: new fields.SchemaField({
|
||||
|
|
@ -21,9 +22,10 @@ export class DHActionDiceData extends foundry.abstract.DataModel {
|
|||
}
|
||||
|
||||
getFormula(actor) {
|
||||
const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : actor.system[this.multiplier]?.total;
|
||||
return this.custom.enabled
|
||||
? 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';
|
||||
|
||||
const resourceField = () =>
|
||||
|
|
@ -39,7 +42,7 @@ export default class DhpAdversary extends BaseDataActor {
|
|||
hitPoints: resourceField(),
|
||||
stress: resourceField()
|
||||
}),
|
||||
attack: new fields.SchemaField({
|
||||
/* attack: new fields.SchemaField({
|
||||
name: new fields.StringField({}),
|
||||
modifier: new fields.NumberField({ required: true, integer: true, initial: 0 }),
|
||||
range: new fields.StringField({
|
||||
|
|
@ -55,6 +58,45 @@ export default class DhpAdversary extends BaseDataActor {
|
|||
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(
|
||||
new fields.SchemaField({
|
||||
|
|
@ -65,4 +107,21 @@ export default class DhpAdversary extends BaseDataActor {
|
|||
/* 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 {
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
|
||||
return {
|
||||
title: new fields.StringField(),
|
||||
origin: new fields.StringField({ required: true }),
|
||||
dice: 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(
|
||||
new fields.SchemaField({
|
||||
id: new fields.StringField({}),
|
||||
|
|
@ -29,24 +19,13 @@ export default class DHAdversaryRoll extends foundry.abstract.TypeDataModel {
|
|||
})
|
||||
),
|
||||
hasDamage: new fields.BooleanField({ initial: false }),
|
||||
hasHealing: new fields.BooleanField({ initial: false }),
|
||||
hasEffect: new fields.BooleanField({ initial: false }),
|
||||
/* damage: new fields.SchemaField(
|
||||
{
|
||||
value: new fields.StringField({}),
|
||||
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false })
|
||||
},
|
||||
{ nullable: true, initial: null }
|
||||
), */
|
||||
action: new fields.SchemaField({
|
||||
itemId: new fields.StringField(),
|
||||
actionId: new fields.StringField()
|
||||
source: new fields.SchemaField({
|
||||
actor: new fields.StringField(),
|
||||
item: new fields.StringField(),
|
||||
action: 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 diceField = () =>
|
||||
new fields.SchemaField({
|
||||
dice: new fields.StringField({}),
|
||||
value: new fields.NumberField({ integer: true })
|
||||
});
|
||||
|
||||
export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
|
||||
static dualityResult = {
|
||||
|
|
@ -17,18 +10,7 @@ export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
|
|||
static defineSchema() {
|
||||
return {
|
||||
title: new fields.StringField(),
|
||||
/* origin: new fields.StringField({ required: true }), */
|
||||
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(
|
||||
new fields.SchemaField({
|
||||
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,11 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
this.config.experiences = [];
|
||||
|
||||
if (config.source?.action) {
|
||||
this.item = config.actor.parent.items.get(config.source.item);
|
||||
this.action = this.item.system.actions.find(a => a._id === config.source.action);
|
||||
this.item = config.data.parent.items.get(config.source.item);
|
||||
this.action =
|
||||
config.data.attack?._id == config.source.action
|
||||
? config.data.attack
|
||||
: this.item.system.actions.find(a => a._id === config.source.action);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -47,9 +50,9 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.experiences = Object.keys(this.config.actor.experiences).map(id => ({
|
||||
context.experiences = Object.keys(this.config.data.experiences).map(id => ({
|
||||
id,
|
||||
...this.config.actor.experiences[id]
|
||||
...this.config.data.experiences[id]
|
||||
}));
|
||||
context.selectedExperiences = this.config.experiences;
|
||||
context.advantage = this.config.advantage;
|
||||
|
|
|
|||
|
|
@ -266,153 +266,14 @@ export default class DhpActor extends Actor {
|
|||
* @param {object} [config.costs]
|
||||
*/
|
||||
async diceRoll(config, action) {
|
||||
// console.log(config)
|
||||
config.source = { ...(config.source ?? {}), actor: this.id };
|
||||
const newConfig = {
|
||||
...config,
|
||||
actor: this.system
|
||||
};
|
||||
const roll =
|
||||
await CONFIG.Dice.daggerheart[this.type === 'character' ? 'DualityRoll' : 'D20Roll'].build(newConfig);
|
||||
config.source = { ...(config.source ?? {}), actor: this._id };
|
||||
config.data = this.getRollData();
|
||||
const roll = await CONFIG.Dice.daggerheart[this.type === 'character' ? 'DualityRoll' : 'D20Roll'].build(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) {
|
||||
const dialogClosed = new Promise((resolve, _) => {
|
||||
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; */
|
||||
getRollData() {
|
||||
return this.system;
|
||||
}
|
||||
|
||||
formatRollModifier(roll) {
|
||||
|
|
@ -575,104 +436,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,48 +60,51 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
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) => {
|
||||
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(message.system.source.item && message.system.source.action) {
|
||||
const item = actor.items.get(message.system.source.item),
|
||||
action = item?.system?.actions?.find(a => a._id === message.system.source.action);
|
||||
if(!item || !action || !action?.rollDamage) return;
|
||||
if (message.system.source.item && message.system.source.action) {
|
||||
const action = this.getAction(actor, message.system.source.item, message.system.source.action);
|
||||
if (!action || !action?.rollDamage) return;
|
||||
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) => {
|
||||
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(message.system.source.item && message.system.source.action) {
|
||||
const item = actor.items.get(message.system.source.item),
|
||||
action = item?.system?.actions?.find(a => a._id === message.system.source.action);
|
||||
if(!item || !action || !action?.rollHealing) return;
|
||||
if (message.system.source.item && message.system.source.action) {
|
||||
const action = this.getAction(actor, message.system.source.item, message.system.source.action);
|
||||
if (!action || !action?.rollHealing) return;
|
||||
await action.rollHealing(event, message);
|
||||
}
|
||||
};
|
||||
|
||||
onApplyEffect = async (event, message) => {
|
||||
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(message.system.source.item && message.system.source.action) {
|
||||
const item = actor.items.get(message.system.source.item),
|
||||
action = item?.system?.actions?.find(a => a._id === message.system.source.action);
|
||||
if(!item || !action || !action.applyEffects) return;
|
||||
if (message.system.source.item && message.system.source.action) {
|
||||
const action = this.getAction(actor, message.system.source.item, message.system.source.action);
|
||||
if (!action || !action?.applyEffects) return;
|
||||
await action.applyEffects(event, message);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
hoverTarget = event => {
|
||||
event.stopPropagation();
|
||||
|
|
@ -148,7 +151,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
ui.notifications.info(game.i18n.localize('DAGGERHEART.Notification.Info.NoTargetsSelected'));
|
||||
|
||||
for (var target of targets) {
|
||||
await target.actor.modifyResource([{value: healing, type: event.currentTarget.dataset.type}]);
|
||||
await target.actor.modifyResource([{ value: healing, type: event.currentTarget.dataset.type }]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,33 +1,51 @@
|
|||
<div class="dice-roll daggerheart chat roll" data-action="expandRoll">
|
||||
<div class="dice-flavor">{{title}}</div>
|
||||
<div class="dice-result">
|
||||
<div class="dice-formula">{{roll.formula}}</div>
|
||||
<div class="dice-tooltip">
|
||||
<ol class="dice-rolls">
|
||||
<div class="dice-hope-container">
|
||||
{{#each dice}}
|
||||
<div class="wrapper">
|
||||
<section class="tooltip-part">
|
||||
<div class="dice">
|
||||
{{#each roll.dice}}
|
||||
<header class="part-header flexrow">
|
||||
<span class="part-formula">{{number}}{{denomination}}</span>
|
||||
<span class="part-formula">{{formula}}</span>
|
||||
<span class="part-total">{{total}}</span>
|
||||
</header>
|
||||
<div class="flexrow">
|
||||
<ol class="dice-rolls">
|
||||
{{#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}}
|
||||
</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>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="modifiers-container">
|
||||
{{#each modifiers}}
|
||||
<li class="modifier-value" data-value="{{value}}" title="{{title}}">{{label}}</li>
|
||||
{{/each}}
|
||||
</div>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dice-total">
|
||||
<div class="dice-total-value">{{roll.total}}</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>
|
||||
|
|
@ -49,13 +49,43 @@
|
|||
|
||||
<fieldset class="two-columns even">
|
||||
<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}}
|
||||
<button data-action="attackRoll">Attack</button>
|
||||
{{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.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>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -33,8 +33,10 @@
|
|||
</fieldset>
|
||||
</div>
|
||||
<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/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}}
|
||||
</div>
|
||||
<div class="tab {{this.tabs.effect.cssClass}}" data-group="primary" data-tab="effect">
|
||||
|
|
|
|||
|
|
@ -4,33 +4,49 @@
|
|||
<div>Damage</div>
|
||||
</legend>
|
||||
<div class="action-category-data open">
|
||||
<div class="fas fa-plus icon-button" data-action="addDamage"></div>
|
||||
{{#if @root.hasBaseDamage}}
|
||||
<div>
|
||||
{{!-- <input type="checkbox" data-action="addBaseDamage"{{#if @root.hasBaseDamage}} checked{{/if}}> --}}
|
||||
{{formField @root.fields.damage.fields.includeBase value=@root.source.damage.includeBase label="Include Item Damage" name="damage.includeBase" }}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#unless @root.isNPC}}
|
||||
<div class="fas fa-plus icon-button" data-action="addDamage"></div>
|
||||
{{#if @root.hasBaseDamage}}
|
||||
<div>
|
||||
{{!-- <input type="checkbox" data-action="addBaseDamage"{{#if @root.hasBaseDamage}} checked{{/if}}> --}}
|
||||
{{formField @root.fields.damage.fields.includeBase value=@root.source.damage.includeBase label="Include Item Damage" name="damage.includeBase" }}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
{{#each source.parts as |dmg index|}}
|
||||
{{#with (@root.getRealIndex index) as | realIndex |}}
|
||||
<fieldset{{#if dmg.base}} disabled{{/if}}>
|
||||
{{#unless dmg.base}}
|
||||
{{formField ../../fields.custom.fields.enabled value=dmg.custom.enabled name=(concat "damage.parts." realIndex ".custom.enabled")}}
|
||||
{{/unless}}
|
||||
{{#if @root.isNPC}}
|
||||
{{formField ../fields.custom.fields.enabled value=dmg.custom.enabled name=(concat ../path "damage.parts." index ".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}}
|
||||
<div class="multi-display">
|
||||
{{formField ../../fields.multiplier value=dmg.multiplier name=(concat "damage.parts." realIndex ".multiplier") localize=true}}
|
||||
{{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}}
|
||||
{{formField ../fields.flatMultiplier value=dmg.flatMultiplier name=(concat "damage.parts." realIndex ".flatMultiplier") label="Multiplier" }}
|
||||
{{formField ../fields.dice value=dmg.dice name=(concat ../path "damage.parts." index ".dice")}}
|
||||
{{formField ../fields.bonus value=dmg.bonus name=(concat ../path "damage.parts." index ".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}}
|
||||
{{else}}
|
||||
{{#with (@root.getRealIndex index) as | realIndex |}}
|
||||
<fieldset{{#if dmg.base}} disabled{{/if}}>
|
||||
{{#unless dmg.base}}
|
||||
{{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}}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
|
@ -3,15 +3,15 @@
|
|||
<div>Range{{#if fields.target}} & Target{{/if}}</div>
|
||||
</legend>
|
||||
<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>
|
||||
{{#if fields.target}}
|
||||
<div class="action-category-data open">
|
||||
<div class="multi-display">
|
||||
{{#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}}
|
||||
{{ 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>
|
||||
{{/if}}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,12 @@
|
|||
<div>Roll</div>
|
||||
</legend>
|
||||
<div class="action-category-data open">
|
||||
{{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 @root.isNPC}}
|
||||
{{formField fields.bonus label="Bonus" name="roll.bonus" value=source.bonus}}
|
||||
{{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>
|
||||
</fieldset>
|
||||
Loading…
Add table
Add a link
Reference in a new issue