mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-18 07:59:03 +01:00
Add Resistances
This commit is contained in:
parent
70239ec06a
commit
7b24cc01eb
11 changed files with 62 additions and 53 deletions
|
|
@ -974,6 +974,11 @@
|
||||||
"minor": "Minor",
|
"minor": "Minor",
|
||||||
"none": "None"
|
"none": "None"
|
||||||
},
|
},
|
||||||
|
"DamageResistance": {
|
||||||
|
"none": "None",
|
||||||
|
"resistance": "Resistance",
|
||||||
|
"immunity": "Immunity"
|
||||||
|
},
|
||||||
"DamageThresholds": {
|
"DamageThresholds": {
|
||||||
"title": "Damage Thresholds",
|
"title": "Damage Thresholds",
|
||||||
"minor": "Minor",
|
"minor": "Minor",
|
||||||
|
|
|
||||||
|
|
@ -76,11 +76,7 @@ export class DHActionDiceData extends foundry.abstract.DataModel {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormula(actor) {
|
getFormula() {
|
||||||
/* const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : actor.system[this.multiplier]?.total;
|
|
||||||
return this.custom.enabled
|
|
||||||
? this.custom.formula
|
|
||||||
: `${multiplier ?? 1}${this.dice}${this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : ''}`; */
|
|
||||||
const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : `@${this.multiplier}`,
|
const multiplier = this.multiplier === 'flat' ? this.flatMultiplier : `@${this.multiplier}`,
|
||||||
bonus = this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : '';
|
bonus = this.bonus ? (this.bonus < 0 ? ` - ${Math.abs(this.bonus)}` : ` + ${this.bonus}`) : '';
|
||||||
return this.custom.enabled ? this.custom.formula : `${multiplier ?? 1}${this.dice}${bonus}`;
|
return this.custom.enabled ? this.custom.formula : `${multiplier ?? 1}${this.dice}${bonus}`;
|
||||||
|
|
@ -93,7 +89,6 @@ export class DHDamageField extends fields.SchemaField {
|
||||||
parts: new fields.ArrayField(new fields.EmbeddedDataField(DHDamageData)),
|
parts: new fields.ArrayField(new fields.EmbeddedDataField(DHDamageData)),
|
||||||
includeBase: new fields.BooleanField({ initial: false })
|
includeBase: new fields.BooleanField({ initial: false })
|
||||||
};
|
};
|
||||||
// if (hasBase) damageFields.includeBase = new fields.BooleanField({ initial: true });
|
|
||||||
super(damageFields, options, context);
|
super(damageFields, options, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import BaseDataActor from './base.mjs';
|
||||||
const resourceField = () =>
|
const resourceField = () =>
|
||||||
new foundry.data.fields.SchemaField({
|
new foundry.data.fields.SchemaField({
|
||||||
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
|
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
bonus: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
|
||||||
max: new foundry.data.fields.NumberField({ initial: 0, integer: true })
|
max: new foundry.data.fields.NumberField({ initial: 0, integer: true })
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -22,6 +23,7 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return {
|
return {
|
||||||
|
...super.defineSchema(),
|
||||||
tier: new fields.StringField({
|
tier: new fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
choices: CONFIG.DH.GENERAL.tiers,
|
choices: CONFIG.DH.GENERAL.tiers,
|
||||||
|
|
@ -32,7 +34,6 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
choices: CONFIG.DH.ACTOR.adversaryTypes,
|
choices: CONFIG.DH.ACTOR.adversaryTypes,
|
||||||
initial: CONFIG.DH.ACTOR.adversaryTypes.standard.id
|
initial: CONFIG.DH.ACTOR.adversaryTypes.standard.id
|
||||||
}),
|
}),
|
||||||
description: new fields.StringField(),
|
|
||||||
motivesAndTactics: new fields.StringField(),
|
motivesAndTactics: new fields.StringField(),
|
||||||
notes: new fields.HTMLField(),
|
notes: new fields.HTMLField(),
|
||||||
difficulty: new fields.NumberField({ required: true, initial: 1, integer: true }),
|
difficulty: new fields.NumberField({ required: true, initial: 1, integer: true }),
|
||||||
|
|
@ -93,4 +94,9 @@ export default class DhpAdversary extends BaseDataActor {
|
||||||
get features() {
|
get features() {
|
||||||
return this.parent.items.filter(x => x.type === 'feature');
|
return this.parent.items.filter(x => x.type === 'feature');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prepareDerivedData() {
|
||||||
|
this.resources.hitPoints.maxTotal = this.resources.hitPoints.max + this.resources.hitPoints.bonus;
|
||||||
|
this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
import DHBaseActorSettings from "../../applications/sheets/api/actor-setting.mjs";
|
import DHBaseActorSettings from "../../applications/sheets/api/actor-setting.mjs";
|
||||||
|
|
||||||
|
const resistanceField = () =>
|
||||||
|
new foundry.data.fields.SchemaField({
|
||||||
|
resistance: new foundry.data.fields.BooleanField({ initial: false }),
|
||||||
|
immunity: new foundry.data.fields.BooleanField({ initial: false })
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes metadata about the actor data model type
|
* Describes metadata about the actor data model type
|
||||||
* @typedef {Object} ActorDataModelMetadata
|
* @typedef {Object} ActorDataModelMetadata
|
||||||
|
|
@ -16,6 +22,7 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
|
||||||
type: 'base',
|
type: 'base',
|
||||||
isNPC: true,
|
isNPC: true,
|
||||||
settingSheet: null,
|
settingSheet: null,
|
||||||
|
hasResistances: true
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,10 +34,16 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
|
||||||
/** @inheritDoc */
|
/** @inheritDoc */
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
const schema = {};
|
||||||
|
|
||||||
return {
|
if(this.metadata.isNPC)
|
||||||
description: new fields.HTMLField({ required: true, nullable: true })
|
schema.description = new fields.HTMLField({ required: true, nullable: true });
|
||||||
};
|
if(this.metadata.hasResistances)
|
||||||
|
schema.resistance = new fields.SchemaField({
|
||||||
|
physical: resistanceField(),
|
||||||
|
magical: resistanceField()
|
||||||
|
})
|
||||||
|
return schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
...super.defineSchema(),
|
||||||
resources: new fields.SchemaField({
|
resources: new fields.SchemaField({
|
||||||
hitPoints: new fields.SchemaField({
|
hitPoints: new fields.SchemaField({
|
||||||
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
|
value: new foundry.data.fields.NumberField({ initial: 0, integer: true }),
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ export default class DhCompanion extends BaseDataActor {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
...super.defineSchema(),
|
||||||
partner: new ForeignDocumentUUIDField({ type: 'Actor' }),
|
partner: new ForeignDocumentUUIDField({ type: 'Actor' }),
|
||||||
resources: new fields.SchemaField({
|
resources: new fields.SchemaField({
|
||||||
stress: new fields.SchemaField({
|
stress: new fields.SchemaField({
|
||||||
|
|
|
||||||
|
|
@ -9,20 +9,21 @@ export default class DhEnvironment extends BaseDataActor {
|
||||||
return foundry.utils.mergeObject(super.metadata, {
|
return foundry.utils.mergeObject(super.metadata, {
|
||||||
label: 'TYPES.Actor.environment',
|
label: 'TYPES.Actor.environment',
|
||||||
type: 'environment',
|
type: 'environment',
|
||||||
settingSheet: DHEnvironmentSettings
|
settingSheet: DHEnvironmentSettings,
|
||||||
|
hasResistances: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static defineSchema() {
|
static defineSchema() {
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
return {
|
return {
|
||||||
|
...super.defineSchema(),
|
||||||
tier: new fields.StringField({
|
tier: new fields.StringField({
|
||||||
required: true,
|
required: true,
|
||||||
choices: CONFIG.DH.GENERAL.tiers,
|
choices: CONFIG.DH.GENERAL.tiers,
|
||||||
initial: CONFIG.DH.GENERAL.tiers.tier1.id
|
initial: CONFIG.DH.GENERAL.tiers.tier1.id
|
||||||
}),
|
}),
|
||||||
type: new fields.StringField({ choices: CONFIG.DH.ACTOR.environmentTypes }),
|
type: new fields.StringField({ choices: CONFIG.DH.ACTOR.environmentTypes }),
|
||||||
description: new fields.StringField(),
|
|
||||||
impulses: new fields.StringField(),
|
impulses: new fields.StringField(),
|
||||||
difficulty: new fields.NumberField({ required: true, initial: 11, integer: true }),
|
difficulty: new fields.NumberField({ required: true, initial: 11, integer: true }),
|
||||||
potentialAdversaries: new fields.TypedObjectField(
|
potentialAdversaries: new fields.TypedObjectField(
|
||||||
|
|
|
||||||
|
|
@ -480,11 +480,7 @@ export default class DhpActor extends Actor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const flatReduction = this.system.bonuses.damageReduction[type];
|
const hpDamage = this.calculateDamage(baseDamage, type);
|
||||||
const damage = Math.max(baseDamage - (flatReduction ?? 0), 0);
|
|
||||||
const hpDamage = this.convertDamageToThreshold(damage);
|
|
||||||
|
|
||||||
if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null;
|
|
||||||
|
|
||||||
if (!hpDamage) return;
|
if (!hpDamage) return;
|
||||||
|
|
||||||
|
|
@ -511,6 +507,21 @@ export default class DhpActor extends Actor {
|
||||||
if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damage, type) === false) return null;
|
if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damage, type) === false) return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
calculateDamage(baseDamage, type) {
|
||||||
|
if (Hooks.call(`${CONFIG.DH.id}.preCalculateDamage`, this, baseDamage, type) === false) return null;
|
||||||
|
|
||||||
|
if(this.system.resistance[type].immunity) return 0;
|
||||||
|
if(this.system.resistance[type].resistance) baseDamage = Math.ceil(baseDamage / 2);
|
||||||
|
|
||||||
|
const flatReduction = this.system.bonuses.damageReduction[type];
|
||||||
|
const damage = Math.max(baseDamage - (flatReduction ?? 0), 0);
|
||||||
|
const hpDamage = this.convertDamageToThreshold(damage);
|
||||||
|
|
||||||
|
if (Hooks.call(`${CONFIG.DH.id}.postCalculateDamage`, this, baseDamage, type) === false) return null;
|
||||||
|
|
||||||
|
return hpDamage;
|
||||||
|
}
|
||||||
|
|
||||||
async takeHealing(resources) {
|
async takeHealing(resources) {
|
||||||
resources.forEach(r => (r.value *= -1));
|
resources.forEach(r => (r.value *= -1));
|
||||||
await this.modifyResource(resources);
|
await this.modifyResource(resources);
|
||||||
|
|
@ -553,18 +564,6 @@ export default class DhpActor extends Actor {
|
||||||
u.resources,
|
u.resources,
|
||||||
u.target.uuid
|
u.target.uuid
|
||||||
);
|
);
|
||||||
/* if (game.user.isGM) {
|
|
||||||
await u.target.update(u.resources);
|
|
||||||
} else {
|
|
||||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
|
||||||
action: socketEvent.GMUpdate,
|
|
||||||
data: {
|
|
||||||
action: GMUpdateEvent.UpdateDocument,
|
|
||||||
uuid: u.target.uuid,
|
|
||||||
update: u.resources
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
||||||
|
|
||||||
if (this.type === 'dualityRoll') {
|
if (this.type === 'dualityRoll') {
|
||||||
html.classList.add('duality');
|
html.classList.add('duality');
|
||||||
|
console.log(this.system)
|
||||||
switch (this.system.roll.result.duality) {
|
switch (this.system.roll.result.duality) {
|
||||||
case 1:
|
case 1:
|
||||||
html.classList.add('hope');
|
html.classList.add('hope');
|
||||||
|
|
|
||||||
|
|
@ -236,16 +236,7 @@ Roll.replaceFormulaData = function (formula, data = {}, { missing, warn = false
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDamageKey = damage => {
|
export const getDamageKey = damage => {
|
||||||
switch (damage) {
|
return ['none', 'minor', 'major', 'severe'][damage];
|
||||||
case 3:
|
|
||||||
return 'severe';
|
|
||||||
case 2:
|
|
||||||
return 'major';
|
|
||||||
case 1:
|
|
||||||
return 'minor';
|
|
||||||
case 0:
|
|
||||||
return 'none';
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getDamageLabel = damage => {
|
export const getDamageLabel = damage => {
|
||||||
|
|
@ -253,16 +244,12 @@ export const getDamageLabel = damage => {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const damageKeyToNumber = key => {
|
export const damageKeyToNumber = key => {
|
||||||
switch (key) {
|
return {
|
||||||
case 'severe':
|
'none': 0,
|
||||||
return 3;
|
'minor': 1,
|
||||||
case 'major':
|
'major': 2,
|
||||||
return 2;
|
'severe': 3
|
||||||
case 'minor':
|
}[key];
|
||||||
return 1;
|
|
||||||
case 'none':
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function constructHTMLButton({
|
export default function constructHTMLButton({
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@
|
||||||
<div class='status-value'>
|
<div class='status-value'>
|
||||||
<p><input class="bar-input" name="system.resources.hitPoints.value" value="{{source.system.resources.hitPoints.value}}" type="number"></p>
|
<p><input class="bar-input" name="system.resources.hitPoints.value" value="{{source.system.resources.hitPoints.value}}" type="number"></p>
|
||||||
<p>/</p>
|
<p>/</p>
|
||||||
<p class="bar-label">{{source.system.resources.hitPoints.max}}</p>
|
<p class="bar-label">{{source.system.resources.hitPoints.maxTotal}}</p>
|
||||||
</div>
|
</div>
|
||||||
<progress
|
<progress
|
||||||
class='progress-bar'
|
class='progress-bar'
|
||||||
value='{{source.system.resources.hitPoints.value}}'
|
value='{{source.system.resources.hitPoints.value}}'
|
||||||
max='{{source.system.resources.hitPoints.max}}'
|
max='{{source.system.resources.hitPoints.maxTotal}}'
|
||||||
></progress>
|
></progress>
|
||||||
<div class="status-label">
|
<div class="status-label">
|
||||||
<h4>HP</h4>
|
<h4>HP</h4>
|
||||||
|
|
@ -26,12 +26,12 @@
|
||||||
<div class='status-value'>
|
<div class='status-value'>
|
||||||
<p><input class="bar-input" name="system.resources.stress.value" value="{{source.system.resources.stress.value}}" type="number"></p>
|
<p><input class="bar-input" name="system.resources.stress.value" value="{{source.system.resources.stress.value}}" type="number"></p>
|
||||||
<p>/</p>
|
<p>/</p>
|
||||||
<p class="bar-label">{{source.system.resources.stress.max}}</p>
|
<p class="bar-label">{{source.system.resources.stress.maxTotal}}</p>
|
||||||
</div>
|
</div>
|
||||||
<progress
|
<progress
|
||||||
class='progress-bar stress-color'
|
class='progress-bar stress-color'
|
||||||
value='{{source.system.resources.stress.value}}'
|
value='{{source.system.resources.stress.value}}'
|
||||||
max='{{source.system.resources.stress.max}}'
|
max='{{source.system.resources.stress.maxTotal}}'
|
||||||
></progress>
|
></progress>
|
||||||
<div class="status-label">
|
<div class="status-label">
|
||||||
<h4>Stress</h4>
|
<h4>Stress</h4>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue