mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 19:51:08 +01:00
Merged with development
This commit is contained in:
commit
0712ea70ae
24 changed files with 587 additions and 368 deletions
|
|
@ -55,9 +55,12 @@ export default class DHActorRoll extends foundry.abstract.TypeDataModel {
|
|||
}
|
||||
|
||||
get action() {
|
||||
const actionItem = this.actionItem;
|
||||
if (!actionItem || !this.source.action) return null;
|
||||
return actionItem.system.actionsList?.find(a => a.id === this.source.action);
|
||||
const actionActor = this.actionActor,
|
||||
actionItem = this.actionItem;
|
||||
if (!this.source.action) return null;
|
||||
if (actionItem) return actionItem.system.actionsList?.find(a => a.id === this.source.action);
|
||||
else if (actionActor?.system.attack?._id === this.source.action) return actionActor.system.attack;
|
||||
return null;
|
||||
}
|
||||
|
||||
get targetMode() {
|
||||
|
|
|
|||
|
|
@ -30,8 +30,13 @@ export default class DamageField extends fields.SchemaField {
|
|||
* @param {boolean} [force=false] If the method should be executed outside of Action workflow, for ChatMessage button for example.
|
||||
*/
|
||||
static async execute(config, messageId = null, force = false) {
|
||||
if(!this.hasDamage && !this.hasHealing) return;
|
||||
if((this.hasRoll && DamageField.getAutomation() === CONFIG.DH.SETTINGS.actionAutomationChoices.never.id) && !force) return;
|
||||
if (!this.hasDamage && !this.hasHealing) return;
|
||||
if (
|
||||
this.hasRoll &&
|
||||
DamageField.getAutomation() === CONFIG.DH.SETTINGS.actionAutomationChoices.never.id &&
|
||||
!force
|
||||
)
|
||||
return;
|
||||
|
||||
let formulas = this.damage.parts.map(p => ({
|
||||
formula: DamageField.getFormulaValue.call(this, p, config).getFormula(this.actor),
|
||||
|
|
@ -51,17 +56,18 @@ export default class DamageField extends fields.SchemaField {
|
|||
};
|
||||
delete damageConfig.evaluate;
|
||||
|
||||
if(DamageField.getAutomation() === CONFIG.DH.SETTINGS.actionAutomationChoices.always.id) damageConfig.dialog.configure = false;
|
||||
if (DamageField.getAutomation() === CONFIG.DH.SETTINGS.actionAutomationChoices.always.id)
|
||||
damageConfig.dialog.configure = false;
|
||||
if (config.hasSave) config.onSave = damageConfig.onSave = this.save.damageMod;
|
||||
|
||||
|
||||
damageConfig.source.message = config.message?._id ?? messageId;
|
||||
damageConfig.directDamage = !!damageConfig.source?.message;
|
||||
|
||||
if(damageConfig.source?.message && game.modules.get('dice-so-nice')?.active)
|
||||
await game.dice3d.waitFor3DAnimationByMessageID(damageConfig.source.message);
|
||||
// if(damageConfig.source?.message && game.modules.get('dice-so-nice')?.active)
|
||||
// await game.dice3d.waitFor3DAnimationByMessageID(damageConfig.source.message);
|
||||
|
||||
const damageResult = await CONFIG.Dice.daggerheart.DamageRoll.build(damageConfig);
|
||||
if(!damageResult) return false;
|
||||
if (!damageResult) return false;
|
||||
config.damage = damageResult.damage;
|
||||
config.message ??= damageConfig.message;
|
||||
}
|
||||
|
|
@ -70,19 +76,15 @@ export default class DamageField extends fields.SchemaField {
|
|||
* Apply Damage/Healing Action Worflow part.
|
||||
* @param {object} config Object that contains workflow datas. Usually made from Action Fields prepareConfig methods.
|
||||
* @param {*[]} targets Arrays of targets to bypass pre-selected ones.
|
||||
* @param {boolean} force If the method should be executed outside of Action workflow, for ChatMessage button for example.
|
||||
* @param {boolean} force If the method should be executed outside of Action workflow, for ChatMessage button for example.
|
||||
*/
|
||||
static async applyDamage(config, targets = null, force = false) {
|
||||
targets ??= config.targets.filter(target => target.hit);
|
||||
if(!config.damage || !targets?.length || (!DamageField.getApplyAutomation() && !force)) return;
|
||||
if (!config.damage || !targets?.length || (!DamageField.getApplyAutomation() && !force)) return;
|
||||
for (let target of targets) {
|
||||
const actor = fromUuidSync(target.actorId);
|
||||
if(!actor) continue;
|
||||
if (
|
||||
!config.hasHealing &&
|
||||
config.onSave &&
|
||||
target.saved?.success === true
|
||||
) {
|
||||
if (!actor) continue;
|
||||
if (!config.hasHealing && config.onSave && target.saved?.success === true) {
|
||||
const mod = CONFIG.DH.ACTIONS.damageOnSave[config.onSave]?.mod ?? 1;
|
||||
Object.entries(config.damage).forEach(([k, v]) => {
|
||||
v.total = 0;
|
||||
|
|
@ -97,17 +99,17 @@ export default class DamageField extends fields.SchemaField {
|
|||
else actor.takeDamage(config.damage, config.isDirect);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return value or valueAlt from damage part
|
||||
* Must be called within Action context or similar.
|
||||
* @param {object} part Damage Part
|
||||
* @param {object} part Damage Part
|
||||
* @param {object} data Action getRollData
|
||||
* @returns Formula value object
|
||||
*/
|
||||
static getFormulaValue(part, data) {
|
||||
let formulaValue = part.value;
|
||||
|
||||
|
||||
if (data.hasRoll && part.resultBased && data.roll.result.duality === -1) return part.valueAlt;
|
||||
|
||||
const isAdversary = this.actor.type === 'adversary';
|
||||
|
|
@ -123,8 +125,8 @@ export default class DamageField extends fields.SchemaField {
|
|||
* Prepare formulas for Damage Roll
|
||||
* Must be called within Action context or similar.
|
||||
* @param {object[]} formulas Array of formatted formulas object
|
||||
* @param {object} data Action getRollData
|
||||
* @returns
|
||||
* @param {object} data Action getRollData
|
||||
* @returns
|
||||
*/
|
||||
static formatFormulas(formulas, data) {
|
||||
const formattedFormulas = [];
|
||||
|
|
@ -145,16 +147,25 @@ export default class DamageField extends fields.SchemaField {
|
|||
* @returns {string} Id from settingsConfig.mjs actionAutomationChoices
|
||||
*/
|
||||
static getAutomation() {
|
||||
return (game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damage.gm) || (!game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damage.players)
|
||||
return (
|
||||
(game.user.isGM &&
|
||||
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damage.gm) ||
|
||||
(!game.user.isGM &&
|
||||
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damage.players)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the automation setting for applyDamage method for current user role
|
||||
* @returns {boolean} If applyDamage should be triggered automatically
|
||||
*/
|
||||
static getApplyAutomation() {
|
||||
return (game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damageApply.gm) || (!game.user.isGM && game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damageApply.players)
|
||||
return (
|
||||
(game.user.isGM &&
|
||||
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damageApply.gm) ||
|
||||
(!game.user.isGM &&
|
||||
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).roll.damageApply.players)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ export default class DHClass extends BaseDataItem {
|
|||
suggestedSecondaryWeapon: new ForeignDocumentUUIDField({ type: 'Item' }),
|
||||
suggestedArmor: new ForeignDocumentUUIDField({ type: 'Item' })
|
||||
}),
|
||||
backgroundQuestions: new fields.ArrayField(new fields.StringField(), { initial: ['', '', ''] }),
|
||||
connections: new fields.ArrayField(new fields.StringField(), { initial: ['', '', ''] }),
|
||||
isMulticlass: new fields.BooleanField({ initial: false })
|
||||
};
|
||||
}
|
||||
|
|
@ -96,6 +98,20 @@ export default class DHClass extends BaseDataItem {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!data.system.isMulticlass) {
|
||||
const addQuestions = (base, questions) => {
|
||||
return `${base}${questions.map(q => `<p><strong>${q}</strong></p>`).join('<br/>')}`;
|
||||
};
|
||||
const backgroundQuestions = data.system.backgroundQuestions.filter(x => x);
|
||||
const connections = data.system.connections.filter(x => x);
|
||||
await this.actor.update({
|
||||
'system.biography': {
|
||||
background: addQuestions(this.actor.system.biography.background, backgroundQuestions),
|
||||
connections: addQuestions(this.actor.system.biography.connections, connections)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const allowed = await super._preCreate(data, options, user);
|
||||
|
|
|
|||
|
|
@ -1,100 +1,46 @@
|
|||
import { fearDisplay } from '../../config/generalConfig.mjs';
|
||||
|
||||
export default class DhAppearance extends foundry.abstract.DataModel {
|
||||
static LOCALIZATION_PREFIXES = ['DAGGERHEART.SETTINGS.Appearance'];
|
||||
|
||||
static defineSchema() {
|
||||
const fields = foundry.data.fields;
|
||||
const { StringField, ColorField, BooleanField, SchemaField } = foundry.data.fields;
|
||||
|
||||
// helper to create dice style schema
|
||||
const diceStyle = ({ fg, bg, outline, edge }) =>
|
||||
new SchemaField({
|
||||
foreground: new ColorField({ required: true, initial: fg }),
|
||||
background: new ColorField({ required: true, initial: bg }),
|
||||
outline: new ColorField({ required: true, initial: outline }),
|
||||
edge: new ColorField({ required: true, initial: edge }),
|
||||
texture: new StringField({ initial: 'astralsea', required: true, blank: false }),
|
||||
colorset: new StringField({ initial: 'inspired', required: true, blank: false }),
|
||||
material: new StringField({ initial: 'metal', required: true, blank: false }),
|
||||
system: new StringField({ initial: 'standard', required: true, blank: false })
|
||||
});
|
||||
|
||||
return {
|
||||
displayFear: new fields.StringField({
|
||||
displayFear: new StringField({
|
||||
required: true,
|
||||
choices: fearDisplay,
|
||||
initial: fearDisplay.token.value,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.displayFear.label'
|
||||
choices: CONFIG.DH.GENERAL.fearDisplay,
|
||||
initial: CONFIG.DH.GENERAL.fearDisplay.token.value
|
||||
}),
|
||||
diceSoNice: new fields.SchemaField({
|
||||
hope: new fields.SchemaField({
|
||||
foreground: new fields.ColorField({ required: true, initial: '#ffffff' }),
|
||||
background: new fields.ColorField({ required: true, initial: '#ffe760' }),
|
||||
outline: new fields.ColorField({ required: true, initial: '#000000' }),
|
||||
edge: new fields.ColorField({ required: true, initial: '#ffffff' }),
|
||||
texture: new fields.StringField({ initial: 'astralsea' }),
|
||||
colorset: new fields.StringField({ initial: 'inspired' }),
|
||||
material: new fields.StringField({ initial: 'metal' }),
|
||||
system: new fields.StringField({ initial: 'standard' })
|
||||
}),
|
||||
fear: new fields.SchemaField({
|
||||
foreground: new fields.ColorField({ required: true, initial: '#000000' }),
|
||||
background: new fields.ColorField({ required: true, initial: '#0032b1' }),
|
||||
outline: new fields.ColorField({ required: true, initial: '#ffffff' }),
|
||||
edge: new fields.ColorField({ required: true, initial: '#000000' }),
|
||||
texture: new fields.StringField({ initial: 'astralsea' }),
|
||||
colorset: new fields.StringField({ initial: 'inspired' }),
|
||||
material: new fields.StringField({ initial: 'metal' }),
|
||||
system: new fields.StringField({ initial: 'standard' })
|
||||
}),
|
||||
advantage: new fields.SchemaField({
|
||||
foreground: new fields.ColorField({ required: true, initial: '#ffffff' }),
|
||||
background: new fields.ColorField({ required: true, initial: '#008000' }),
|
||||
outline: new fields.ColorField({ required: true, initial: '#000000' }),
|
||||
edge: new fields.ColorField({ required: true, initial: '#ffffff' }),
|
||||
texture: new fields.StringField({ initial: 'astralsea' }),
|
||||
colorset: new fields.StringField({ initial: 'inspired' }),
|
||||
material: new fields.StringField({ initial: 'metal' }),
|
||||
system: new fields.StringField({ initial: 'standard' })
|
||||
}),
|
||||
disadvantage: new fields.SchemaField({
|
||||
foreground: new fields.ColorField({ required: true, initial: '#000000' }),
|
||||
background: new fields.ColorField({ required: true, initial: '#b30000' }),
|
||||
outline: new fields.ColorField({ required: true, initial: '#ffffff' }),
|
||||
edge: new fields.ColorField({ required: true, initial: '#000000' }),
|
||||
texture: new fields.StringField({ initial: 'astralsea' }),
|
||||
colorset: new fields.StringField({ initial: 'inspired' }),
|
||||
material: new fields.StringField({ initial: 'metal' }),
|
||||
system: new fields.StringField({ initial: 'standard' })
|
||||
})
|
||||
diceSoNice: new SchemaField({
|
||||
hope: diceStyle({ fg: '#ffffff', bg: '#ffe760', outline: '#000000', edge: '#ffffff' }),
|
||||
fear: diceStyle({ fg: '#000000', bg: '#0032b1', outline: '#ffffff', edge: '#000000' }),
|
||||
advantage: diceStyle({ fg: '#ffffff', bg: '#008000', outline: '#000000', edge: '#ffffff' }),
|
||||
disadvantage: diceStyle({ fg: '#000000', bg: '#b30000', outline: '#ffffff', edge: '#000000' })
|
||||
}),
|
||||
showGenericStatusEffects: new fields.BooleanField({
|
||||
initial: true,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.showGenericStatusEffects.label'
|
||||
extendCharacterDescriptions: new BooleanField(),
|
||||
extendAdversaryDescriptions: new BooleanField(),
|
||||
extendEnvironmentDescriptions: new BooleanField(),
|
||||
extendItemDescriptions: new BooleanField(),
|
||||
expandRollMessage: new SchemaField({
|
||||
desc: new BooleanField(),
|
||||
roll: new BooleanField(),
|
||||
damage: new BooleanField(),
|
||||
target: new BooleanField()
|
||||
}),
|
||||
extendCharacterDescriptions: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.extendCharacterDescriptions.label'
|
||||
}),
|
||||
extendAdversaryDescriptions: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.extendAdversaryDescriptions.label'
|
||||
}),
|
||||
extendEnvironmentDescriptions: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.extendEnvironmentDescriptions.label'
|
||||
}),
|
||||
extendItemDescriptions: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.extendItemDescriptions.label'
|
||||
}),
|
||||
expandRollMessage: new fields.SchemaField({
|
||||
desc: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.expandRollMessageDesc.label'
|
||||
}),
|
||||
roll: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.expandRollMessageRoll.label'
|
||||
}),
|
||||
damage: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.expandRollMessageDamage.label'
|
||||
}),
|
||||
target: new fields.BooleanField({
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.expandRollMessageTarget.label'
|
||||
})
|
||||
}),
|
||||
hideAttribution: new fields.BooleanField({
|
||||
required: true,
|
||||
initial: false,
|
||||
label: 'DAGGERHEART.SETTINGS.Appearance.FIELDS.hideAttribution.label'
|
||||
})
|
||||
hideAttribution: new BooleanField(),
|
||||
showGenericStatusEffects: new BooleanField({ initial: true })
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue