mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-04-22 07:23:37 +02:00
Initial
This commit is contained in:
parent
f1f5102af1
commit
c6bf482b07
12 changed files with 280 additions and 94 deletions
|
|
@ -33,6 +33,7 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
handleResourceDice: CharacterSheet.#handleResourceDice,
|
||||
advanceResourceDie: CharacterSheet.#advanceResourceDie,
|
||||
cancelBeastform: CharacterSheet.#cancelBeastform,
|
||||
toggleResourceManagement: CharacterSheet.#toggleResourceManagement,
|
||||
useDowntime: this.useDowntime,
|
||||
viewParty: CharacterSheet.#viewParty
|
||||
},
|
||||
|
|
@ -942,6 +943,71 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
});
|
||||
}
|
||||
|
||||
static async #toggleResourceManagement(_event, button) {
|
||||
const existingTooltip = document.body.querySelector('.locked-tooltip .resource-management-container');
|
||||
if (existingTooltip) {
|
||||
game.tooltip.dismissLockedTooltips();
|
||||
return;
|
||||
}
|
||||
|
||||
const extraResources = Object.values(CONFIG.DH.ACTOR.characterResources).reduce((acc, resource) => {
|
||||
if (CONFIG.DH.ACTOR.characterBaseResources[resource.id]) return acc;
|
||||
|
||||
const resourceData = this.document.system.resources[resource.id];
|
||||
acc[resource.id] = {
|
||||
id: resource.id,
|
||||
label: game.i18n.localize(resource.label),
|
||||
value: resourceData.value,
|
||||
max: resourceData.max
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const html = document.createElement('div');
|
||||
html.innerHTML = await foundry.applications.handlebars.renderTemplate(
|
||||
`systems/daggerheart/templates/ui/tooltip/resourceManagement.hbs`,
|
||||
{
|
||||
resources: extraResources
|
||||
}
|
||||
);
|
||||
|
||||
const target = button.closest('.resource-section');
|
||||
|
||||
game.tooltip.dismissLockedTooltips();
|
||||
game.tooltip.activate(target, {
|
||||
html,
|
||||
locked: true,
|
||||
cssClass: 'bordered-tooltip',
|
||||
direction: 'DOWN'
|
||||
});
|
||||
|
||||
for (const element of html.querySelectorAll('.resource-value'))
|
||||
element.addEventListener('click', CharacterSheet.resourceUpdate.bind(this));
|
||||
}
|
||||
|
||||
static async resourceUpdate(event) {
|
||||
const target = event.target.closest('.resource-value');
|
||||
const { resource, value: textValue } = target.dataset;
|
||||
|
||||
const inputValue = Number.parseInt(textValue);
|
||||
const decreasing = inputValue <= this.document.system.resources[resource].value;
|
||||
const value = decreasing ? inputValue - 1 : inputValue;
|
||||
await this.document.update({ [`system.resources.${resource}.value`]: value });
|
||||
|
||||
/* Update resource symbols */
|
||||
const section = target.closest('.resource-section');
|
||||
for (const element of section.querySelectorAll('.resource-value')) {
|
||||
if (Number.parseInt(element.dataset.value) <= value) {
|
||||
element.querySelector('.fa-diamond').classList.remove('hidden');
|
||||
element.querySelector('.fa-circle').classList.add('hidden');
|
||||
} else {
|
||||
element.querySelector('.fa-diamond').classList.add('hidden');
|
||||
element.querySelector('.fa-circle').classList.remove('hidden');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the downtime application.
|
||||
* @type {ApplicationClickAction}
|
||||
|
|
|
|||
|
|
@ -55,24 +55,47 @@ export const abilities = {
|
|||
}
|
||||
};
|
||||
|
||||
export const scrollingTextResource = {
|
||||
const baseResources = {
|
||||
hitPoints: {
|
||||
id: 'hitPoints',
|
||||
initial: 0,
|
||||
max: 0,
|
||||
reverse: true,
|
||||
label: 'DAGGERHEART.GENERAL.HitPoints.plural',
|
||||
reversed: true
|
||||
maxLabel: 'DAGGERHEART.ACTORS.Character.maxHPBonus'
|
||||
},
|
||||
stress: {
|
||||
label: 'DAGGERHEART.GENERAL.stress',
|
||||
reversed: true
|
||||
id: 'stress',
|
||||
initial: 0,
|
||||
max: 6,
|
||||
reverse: true,
|
||||
label: 'DAGGERHEART.GENERAL.stress'
|
||||
},
|
||||
hope: {
|
||||
id: 'hope',
|
||||
initial: 2,
|
||||
min: 0,
|
||||
reverse: false,
|
||||
label: 'DAGGERHEART.GENERAL.hope'
|
||||
},
|
||||
armor: {
|
||||
label: 'DAGGERHEART.GENERAL.armor',
|
||||
reversed: true
|
||||
}
|
||||
};
|
||||
|
||||
export const characterBaseResources = {
|
||||
...baseResources
|
||||
};
|
||||
|
||||
export const characterResources = {
|
||||
...characterBaseResources
|
||||
};
|
||||
|
||||
export const getScrollingTextResources = actorType => ({
|
||||
armor: {
|
||||
label: 'DAGGERHEART.GENERAL.armor',
|
||||
reverse: true
|
||||
},
|
||||
...(actorType === 'character' ? characterResources : {})
|
||||
});
|
||||
|
||||
export const featureProperties = {
|
||||
agility: {
|
||||
name: 'DAGGERHEART.CONFIG.Traits.agility.name',
|
||||
|
|
@ -506,8 +529,8 @@ export const subclassFeatureLabels = {
|
|||
* @property {number[]} damage
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {Record<string, Record<2 | 3 | 4, TierData>}
|
||||
/**
|
||||
* @type {Record<string, Record<2 | 3 | 4, TierData>}
|
||||
* Scaling data used to change an adversary's tier. Each rank is applied incrementally.
|
||||
*/
|
||||
export const adversaryScalingData = {
|
||||
|
|
@ -518,7 +541,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 10,
|
||||
hp: 1,
|
||||
stress: 2,
|
||||
attack: 2,
|
||||
attack: 2
|
||||
},
|
||||
3: {
|
||||
difficulty: 2,
|
||||
|
|
@ -526,7 +549,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 15,
|
||||
hp: 1,
|
||||
stress: 0,
|
||||
attack: 2,
|
||||
attack: 2
|
||||
},
|
||||
4: {
|
||||
difficulty: 2,
|
||||
|
|
@ -534,7 +557,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 25,
|
||||
hp: 1,
|
||||
stress: 0,
|
||||
attack: 2,
|
||||
attack: 2
|
||||
}
|
||||
},
|
||||
horde: {
|
||||
|
|
@ -544,7 +567,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 8,
|
||||
hp: 2,
|
||||
stress: 0,
|
||||
attack: 0,
|
||||
attack: 0
|
||||
},
|
||||
3: {
|
||||
difficulty: 2,
|
||||
|
|
@ -552,7 +575,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 12,
|
||||
hp: 0,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
4: {
|
||||
difficulty: 2,
|
||||
|
|
@ -560,7 +583,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 15,
|
||||
hp: 2,
|
||||
stress: 0,
|
||||
attack: 0,
|
||||
attack: 0
|
||||
}
|
||||
},
|
||||
leader: {
|
||||
|
|
@ -570,7 +593,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 10,
|
||||
hp: 0,
|
||||
stress: 0,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
3: {
|
||||
difficulty: 2,
|
||||
|
|
@ -578,7 +601,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 15,
|
||||
hp: 1,
|
||||
stress: 0,
|
||||
attack: 2,
|
||||
attack: 2
|
||||
},
|
||||
4: {
|
||||
difficulty: 2,
|
||||
|
|
@ -586,7 +609,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 25,
|
||||
hp: 1,
|
||||
stress: 1,
|
||||
attack: 3,
|
||||
attack: 3
|
||||
}
|
||||
},
|
||||
minion: {
|
||||
|
|
@ -596,7 +619,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 0,
|
||||
hp: 0,
|
||||
stress: 0,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
3: {
|
||||
difficulty: 2,
|
||||
|
|
@ -604,7 +627,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 0,
|
||||
hp: 0,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
4: {
|
||||
difficulty: 2,
|
||||
|
|
@ -612,7 +635,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 0,
|
||||
hp: 0,
|
||||
stress: 0,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
}
|
||||
},
|
||||
ranged: {
|
||||
|
|
@ -622,7 +645,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 6,
|
||||
hp: 1,
|
||||
stress: 0,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
3: {
|
||||
difficulty: 2,
|
||||
|
|
@ -630,7 +653,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 14,
|
||||
hp: 1,
|
||||
stress: 1,
|
||||
attack: 2,
|
||||
attack: 2
|
||||
},
|
||||
4: {
|
||||
difficulty: 2,
|
||||
|
|
@ -638,7 +661,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 10,
|
||||
hp: 1,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
}
|
||||
},
|
||||
skulk: {
|
||||
|
|
@ -648,7 +671,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 8,
|
||||
hp: 1,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
3: {
|
||||
difficulty: 2,
|
||||
|
|
@ -656,7 +679,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 12,
|
||||
hp: 1,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
4: {
|
||||
difficulty: 2,
|
||||
|
|
@ -664,7 +687,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 10,
|
||||
hp: 1,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
}
|
||||
},
|
||||
solo: {
|
||||
|
|
@ -674,7 +697,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 10,
|
||||
hp: 0,
|
||||
stress: 1,
|
||||
attack: 2,
|
||||
attack: 2
|
||||
},
|
||||
3: {
|
||||
difficulty: 2,
|
||||
|
|
@ -682,7 +705,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 15,
|
||||
hp: 2,
|
||||
stress: 1,
|
||||
attack: 2,
|
||||
attack: 2
|
||||
},
|
||||
4: {
|
||||
difficulty: 2,
|
||||
|
|
@ -690,7 +713,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 25,
|
||||
hp: 0,
|
||||
stress: 1,
|
||||
attack: 3,
|
||||
attack: 3
|
||||
}
|
||||
},
|
||||
standard: {
|
||||
|
|
@ -700,7 +723,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 8,
|
||||
hp: 0,
|
||||
stress: 0,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
3: {
|
||||
difficulty: 2,
|
||||
|
|
@ -708,7 +731,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 15,
|
||||
hp: 1,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
4: {
|
||||
difficulty: 2,
|
||||
|
|
@ -716,7 +739,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 15,
|
||||
hp: 0,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
}
|
||||
},
|
||||
support: {
|
||||
|
|
@ -726,7 +749,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 8,
|
||||
hp: 1,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
3: {
|
||||
difficulty: 2,
|
||||
|
|
@ -734,7 +757,7 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 12,
|
||||
hp: 0,
|
||||
stress: 0,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
},
|
||||
4: {
|
||||
difficulty: 2,
|
||||
|
|
@ -742,27 +765,27 @@ export const adversaryScalingData = {
|
|||
severeThreshold: 10,
|
||||
hp: 1,
|
||||
stress: 1,
|
||||
attack: 1,
|
||||
attack: 1
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* Scaling data used for an adversary's damage.
|
||||
* Tier 4 is missing certain adversary types and therefore skews upwards.
|
||||
* We manually set tier 4 data to hopefully lead to better results
|
||||
*/
|
||||
export const adversaryExpectedDamage = {
|
||||
basic: {
|
||||
1: { mean: 7.321428571428571, deviation: 1.962519002770912 },
|
||||
2: { mean: 12.444444444444445, deviation: 2.0631069425529676 },
|
||||
3: { mean: 15.722222222222221, deviation: 2.486565208464823 },
|
||||
4: { mean: 26, deviation: 5.2 }
|
||||
},
|
||||
minion: {
|
||||
1: { mean: 2.142857142857143, deviation: 1.0690449676496976 },
|
||||
2: { mean: 5, deviation: 0.816496580927726 },
|
||||
3: { mean: 6.5, deviation: 2.1213203435596424 },
|
||||
4: { mean: 11, deviation: 1 }
|
||||
}
|
||||
basic: {
|
||||
1: { mean: 7.321428571428571, deviation: 1.962519002770912 },
|
||||
2: { mean: 12.444444444444445, deviation: 2.0631069425529676 },
|
||||
3: { mean: 15.722222222222221, deviation: 2.486565208464823 },
|
||||
4: { mean: 26, deviation: 5.2 }
|
||||
},
|
||||
minion: {
|
||||
1: { mean: 2.142857142857143, deviation: 1.0690449676496976 },
|
||||
2: { mean: 5, deviation: 0.816496580927726 },
|
||||
3: { mean: 6.5, deviation: 2.1213203435596424 },
|
||||
4: { mean: 11, deviation: 1 }
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
|
|||
const textData = Object.keys(changes.system.resources).reduce((acc, key) => {
|
||||
const resource = changes.system.resources[key];
|
||||
if (resource.value !== undefined && resource.value !== this.resources[key].value) {
|
||||
acc.push(getScrollTextData(this.resources, resource, key));
|
||||
acc.push(getScrollTextData(this.resources, resource, key, this.parent.type));
|
||||
}
|
||||
|
||||
return acc;
|
||||
|
|
|
|||
|
|
@ -28,26 +28,32 @@ export default class DhCharacter extends DhCreature {
|
|||
return {
|
||||
...super.defineSchema(),
|
||||
resources: new fields.SchemaField({
|
||||
hitPoints: resourceField(
|
||||
0,
|
||||
0,
|
||||
'DAGGERHEART.GENERAL.HitPoints.plural',
|
||||
true,
|
||||
'DAGGERHEART.ACTORS.Character.maxHPBonus'
|
||||
),
|
||||
stress: resourceField(6, 0, 'DAGGERHEART.GENERAL.stress', true),
|
||||
hope: new fields.SchemaField(
|
||||
{
|
||||
value: new fields.NumberField({
|
||||
initial: 2,
|
||||
min: 0,
|
||||
integer: true,
|
||||
label: 'DAGGERHEART.GENERAL.hope'
|
||||
}),
|
||||
isReversed: new fields.BooleanField({ initial: false })
|
||||
},
|
||||
{ label: 'DAGGERHEART.GENERAL.hope' }
|
||||
)
|
||||
...Object.values(CONFIG.DH.ACTOR.characterResources).reduce((acc, resource) => {
|
||||
if (resource.max !== undefined) {
|
||||
acc[resource.id] = resourceField(
|
||||
resource.max,
|
||||
resource.initial,
|
||||
resource.label,
|
||||
resource.reverse,
|
||||
resource.maxLabel
|
||||
);
|
||||
} else {
|
||||
acc[resource.id] = new fields.SchemaField(
|
||||
{
|
||||
value: new fields.NumberField({
|
||||
initial: resource.initial,
|
||||
min: resource.min,
|
||||
integer: true,
|
||||
label: resource.label
|
||||
}),
|
||||
isReversed: new fields.BooleanField({ initial: resource.reverse })
|
||||
},
|
||||
{ label: resource.label }
|
||||
);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {})
|
||||
}),
|
||||
traits: new fields.SchemaField({
|
||||
agility: attributeField('DAGGERHEART.CONFIG.Traits.agility.name'),
|
||||
|
|
|
|||
|
|
@ -224,7 +224,12 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
|||
const armorChanged =
|
||||
changed.system?.marks?.value !== undefined && changed.system.marks.value !== this.marks.value;
|
||||
if (armorChanged && autoSettings.resourceScrollTexts && this.parent.parent?.type === 'character') {
|
||||
const armorData = getScrollTextData(this.parent.parent.system.resources, changed.system.marks, 'armor');
|
||||
const armorData = getScrollTextData(
|
||||
this.parent.parent.system.resources,
|
||||
changed.system.marks,
|
||||
'armor',
|
||||
this.parent.parent.type
|
||||
);
|
||||
options.scrollingTextData = [armorData];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -378,17 +378,17 @@ export const arraysEqual = (a, b) =>
|
|||
|
||||
export const setsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value));
|
||||
|
||||
export function getScrollTextData(resources, resource, key) {
|
||||
const { reversed, label } = CONFIG.DH.ACTOR.scrollingTextResource[key];
|
||||
export function getScrollTextData(resources, resource, key, actorType) {
|
||||
const { reverse, label } = CONFIG.DH.ACTOR.getScrollingTextResources(actorType)[key];
|
||||
const { BOTTOM, TOP } = CONST.TEXT_ANCHOR_POINTS;
|
||||
const increased = resources[key].value < resource.value;
|
||||
const value = -1 * (resources[key].value - resource.value);
|
||||
|
||||
const text = `${game.i18n.localize(label)} ${value.signedString()}`;
|
||||
|
||||
const stroke = increased ? (reversed ? 0xffffff : 0x000000) : reversed ? 0x000000 : 0xffffff;
|
||||
const fill = increased ? (reversed ? 0x0032b1 : 0xffe760) : reversed ? 0xffe760 : 0x0032b1;
|
||||
const direction = increased ? (reversed ? BOTTOM : TOP) : reversed ? TOP : BOTTOM;
|
||||
const stroke = increased ? (reverse ? 0xffffff : 0x000000) : reverse ? 0x000000 : 0xffffff;
|
||||
const fill = increased ? (reverse ? 0x0032b1 : 0xffe760) : reverse ? 0xffe760 : 0x0032b1;
|
||||
const direction = increased ? (reverse ? BOTTOM : TOP) : reverse ? TOP : BOTTOM;
|
||||
|
||||
return { text, stroke, fill, direction };
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue