mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-11 19:25:21 +01:00
Fixed automatic battleToggles
This commit is contained in:
parent
e32454b7c7
commit
d7bbc9e650
10 changed files with 201 additions and 21 deletions
28
lang/en.json
28
lang/en.json
|
|
@ -914,12 +914,28 @@
|
|||
"hybrid": "Hybrid"
|
||||
},
|
||||
"BPModifiers": {
|
||||
"increaseDamage": "if you add +1d4 (or a static +2) to all adversaries' damage rolls (to increase the challenge without lengthening the battle)",
|
||||
"lessDifficult": "if the fight should be less difficult or shorter.",
|
||||
"lowerTier": "if you choose an adversary from a lower tier.",
|
||||
"manySolos": "if you're using 2 or more Solo adversaries.",
|
||||
"moreDangerous": "if the fight should be more dangerous or last longer",
|
||||
"noToughies": "if you don't include any Bruisers, Hordes, Leaders, or Solos"
|
||||
"increaseDamage": {
|
||||
"description": "if you add +1d4 (or a static +2) to all adversaries' damage rolls (to increase the challenge without lengthening the battle)",
|
||||
"effect": {
|
||||
"name": "Increase Damage",
|
||||
"description": "Add 1d4 to damage"
|
||||
}
|
||||
},
|
||||
"lessDifficult": {
|
||||
"description": "if the fight should be less difficult or shorter."
|
||||
},
|
||||
"lowerTier": {
|
||||
"description": "if you choose an adversary from a lower tier."
|
||||
},
|
||||
"manySolos": {
|
||||
"description": "if you're using 2 or more Solo adversaries."
|
||||
},
|
||||
"moreDangerous": {
|
||||
"description": "if the fight should be more dangerous or last longer"
|
||||
},
|
||||
"noToughies": {
|
||||
"description": "if you don't include any Bruisers, Hordes, Leaders, or Solos"
|
||||
}
|
||||
},
|
||||
"Burden": {
|
||||
"oneHanded": "One-Handed",
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C
|
|||
const modifierBP =
|
||||
this.combats
|
||||
.find(x => x.active)
|
||||
?.system?.battleToggles?.reduce((acc, toggle) => acc + toggle.category, 0) ?? 0;
|
||||
?.system?.extendedBattleToggles?.reduce((acc, toggle) => acc + toggle.category, 0) ?? 0;
|
||||
const maxBP = CONFIG.DH.ENCOUNTER.BaseBPPerEncounter(context.characters.length) + modifierBP;
|
||||
const currentBP = AdversaryBPPerEncounter(context.adversaries, context.characters);
|
||||
|
||||
|
|
|
|||
|
|
@ -75,33 +75,68 @@ export const BPModifiers = {
|
|||
[-2]: {
|
||||
manySolos: {
|
||||
sort: 1,
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.manySolos'
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.manySolos.description',
|
||||
automatic: true,
|
||||
conditional: (_combat, adversaries) => {
|
||||
return adversaries.filter(x => x.system.type === 'solo').length > 1;
|
||||
}
|
||||
},
|
||||
increaseDamage: {
|
||||
sort: 2,
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage'
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage.description',
|
||||
effects: [
|
||||
{
|
||||
name: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage.effect.name',
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.increaseDamage.effect.description',
|
||||
img: 'icons/magic/control/buff-flight-wings-red.webp',
|
||||
changes: [
|
||||
{
|
||||
key: 'system.bonuses.damage.physical.dice',
|
||||
mode: 2,
|
||||
value: '1d4'
|
||||
},
|
||||
{
|
||||
key: 'system.bonuses.damage.magical.dice',
|
||||
mode: 2,
|
||||
value: '1d4'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
[-1]: {
|
||||
lessDifficult: {
|
||||
sort: 2,
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.lessDifficult'
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.lessDifficult.description'
|
||||
}
|
||||
},
|
||||
1: {
|
||||
lowerTier: {
|
||||
sort: 1,
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.lowerTier'
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.lowerTier.description',
|
||||
automatic: true,
|
||||
conditional: (_combat, adversaries, characters) => {
|
||||
const characterMaxTier = characters.reduce((maxTier, character) => {
|
||||
return character.system.tier > maxTier ? character.system.tier : maxTier;
|
||||
}, 1);
|
||||
return adversaries.some(adversary => adversary.system.tier < characterMaxTier);
|
||||
}
|
||||
},
|
||||
noToughies: {
|
||||
sort: 2,
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.noToughies'
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.noToughies.description',
|
||||
automatic: true,
|
||||
conditional: (_combat, adversaries) => {
|
||||
const toughyTypes = ['bruiser', 'horde', 'leader', 'solo'];
|
||||
return !adversaries.some(adversary => toughyTypes.includes(adversary.system.type));
|
||||
}
|
||||
}
|
||||
},
|
||||
2: {
|
||||
moreDangerous: {
|
||||
sort: 2,
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.moreDangerous'
|
||||
description: 'DAGGERHEART.CONFIG.BPModifiers.moreDangerous.description'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -26,3 +26,5 @@ export const userFlags = {
|
|||
welcomeMessage: 'welcome-message',
|
||||
countdownMode: 'countdown-mode'
|
||||
};
|
||||
|
||||
export const combatToggle = 'combat-toggle-origin';
|
||||
|
|
|
|||
|
|
@ -10,4 +10,30 @@ export default class DhCombat extends foundry.abstract.TypeDataModel {
|
|||
)
|
||||
};
|
||||
}
|
||||
|
||||
/** Includes automatic BPModifiers */
|
||||
get extendedBattleToggles() {
|
||||
const modifiers = CONFIG.DH.ENCOUNTER.BPModifiers;
|
||||
const adversaries =
|
||||
this.parent.turns?.filter(x => x.isNPC)?.map(x => ({ ...x.actor, type: x.actor.system.type })) ?? [];
|
||||
const characters = this.parent.turns?.filter(x => !x.isNPC) ?? [];
|
||||
|
||||
const activeAutomatic = Object.keys(modifiers).reduce((acc, categoryKey) => {
|
||||
const category = modifiers[categoryKey];
|
||||
acc.push(
|
||||
...Object.keys(category).reduce((acc, groupingKey) => {
|
||||
const grouping = category[groupingKey];
|
||||
if (grouping.automatic && grouping.conditional?.(this.parent, adversaries, characters)) {
|
||||
acc.push({ category: Number(categoryKey), grouping: groupingKey });
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [])
|
||||
);
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
return [...this.battleToggles, ...activeAutomatic];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,4 +16,57 @@ export default class DhpCombat extends Combat {
|
|||
|
||||
return a.name.localeCompare(b.name);
|
||||
}
|
||||
|
||||
async toggleModifierEffects(add, actors, category, groupingKey) {
|
||||
const effectData = category && groupingKey ? [{ category, grouping: groupingKey }] : this.system.battleToggles;
|
||||
if (add) {
|
||||
const effects = effectData.reduce((acc, toggle) => {
|
||||
const grouping = CONFIG.DH.ENCOUNTER.BPModifiers[toggle.category]?.[toggle.grouping];
|
||||
if (!grouping?.effects?.length) return acc;
|
||||
acc.push(
|
||||
...grouping.effects.map(effect => ({
|
||||
...effect,
|
||||
name: game.i18n.localize(effect.name),
|
||||
description: game.i18n.localize(effect.description),
|
||||
flags: {
|
||||
[`${CONFIG.DH.id}.${CONFIG.DH.FLAGS.combatToggle}`]: {
|
||||
category: toggle.category,
|
||||
grouping: toggle.grouping
|
||||
}
|
||||
}
|
||||
}))
|
||||
);
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
if (!effects.length) return;
|
||||
|
||||
for (let actor of actors) {
|
||||
await actor.createEmbeddedDocuments(
|
||||
'ActiveEffect',
|
||||
effects.map(effect => ({
|
||||
...effect,
|
||||
name: game.i18n.localize(effect.name),
|
||||
description: game.i18n.localize(effect.description)
|
||||
}))
|
||||
);
|
||||
}
|
||||
} else {
|
||||
for (let actor of actors) {
|
||||
await actor.deleteEmbeddedDocuments(
|
||||
'ActiveEffect',
|
||||
actor.effects
|
||||
.filter(x => {
|
||||
const flag = x.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.combatToggle);
|
||||
if (!flag) return false;
|
||||
return effectData.some(
|
||||
data => flag.category == data.category && flag.grouping === data.grouping
|
||||
);
|
||||
})
|
||||
.map(x => x.id)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,8 +72,32 @@ export default class DHToken extends TokenDocument {
|
|||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
|
||||
_shouldRecordMovementHistory() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
static async createCombatants(tokens, combat) {
|
||||
combat ??= game.combats.viewed;
|
||||
if (combat?.system?.battleToggles?.length) {
|
||||
await combat.toggleModifierEffects(
|
||||
true,
|
||||
tokens.map(x => x.actor)
|
||||
);
|
||||
}
|
||||
super.createCombatants(tokens, combat ?? {});
|
||||
}
|
||||
|
||||
/**@inheritdoc */
|
||||
static async deleteCombatants(tokens, { combat } = {}) {
|
||||
combat ??= game.combats.viewed;
|
||||
if (combat?.system?.battleToggles?.length) {
|
||||
await combat.toggleModifierEffects(
|
||||
false,
|
||||
tokens.map(x => x.actor)
|
||||
);
|
||||
}
|
||||
super.deleteCombatants(tokens, combat ?? {});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
|||
|
||||
const nrCharacters = characters.length;
|
||||
const currentBP = AdversaryBPPerEncounter(adversaries, characters);
|
||||
const maxBP = combat.system.battleToggles.reduce(
|
||||
const maxBP = combat.system.extendedBattleToggles.reduce(
|
||||
(acc, toggle) => acc + toggle.category,
|
||||
BaseBPPerEncounter(nrCharacters)
|
||||
);
|
||||
|
|
@ -252,18 +252,21 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
|||
return acc;
|
||||
}, foundry.utils.deepClone(CONFIG.DH.ENCOUNTER.adversaryTypeCostBrackets));
|
||||
|
||||
const extendedBattleToggles = combat.system.extendedBattleToggles;
|
||||
const toggles = Object.keys(CONFIG.DH.ENCOUNTER.BPModifiers)
|
||||
.reduce((acc, categoryKey) => {
|
||||
const category = CONFIG.DH.ENCOUNTER.BPModifiers[categoryKey];
|
||||
acc.push(
|
||||
...Object.keys(category).reduce((acc, toggleKey) => {
|
||||
const grouping = category[toggleKey];
|
||||
acc.push({
|
||||
...category[toggleKey],
|
||||
...grouping,
|
||||
categoryKey: Number(categoryKey),
|
||||
toggleKey,
|
||||
checked: combat.system.battleToggles.find(
|
||||
checked: extendedBattleToggles.find(
|
||||
x => x.category == categoryKey && x.grouping === toggleKey
|
||||
)
|
||||
),
|
||||
disabled: grouping.automatic
|
||||
});
|
||||
|
||||
return acc;
|
||||
|
|
@ -302,6 +305,13 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
|||
}
|
||||
});
|
||||
|
||||
await combat.toggleModifierEffects(
|
||||
event.target.checked,
|
||||
combat.combatants.filter(x => x.actor.type === 'adversary').map(x => x.actor),
|
||||
category,
|
||||
grouping
|
||||
);
|
||||
|
||||
this.tooltip.innerHTML = await this.getBattlepointHTML(combatId);
|
||||
const lockedTooltip = this.lockTooltip();
|
||||
lockedTooltip.querySelectorAll('.battlepoint-toggle-container input').forEach(element => {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,16 @@
|
|||
display: flex;
|
||||
gap: 4px;
|
||||
|
||||
&.inactive {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.grouping-lock {
|
||||
font-size: 17.5px;
|
||||
margin: 0 5px;
|
||||
color: @golden;
|
||||
}
|
||||
|
||||
input {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
{{#if grouping.nr}}
|
||||
<label>{{key}} BP: {{concat (localize grouping.description) ' ' '('grouping.nr 'x)'}}</label>
|
||||
{{else}}
|
||||
<label class="unselected-grouping">{{key}}BP - {{localize grouping.description}}</label>
|
||||
<label class="unselected-grouping">{{key}} BP - {{localize grouping.description}}</label>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/each}}
|
||||
|
|
@ -16,8 +16,12 @@
|
|||
<div class="battlepoint-toggles-container">
|
||||
<h3>{{localize "Modifiers"}}</h3>
|
||||
{{#each toggles as |toggle|}}
|
||||
<div class="battlepoint-toggle-container">
|
||||
<input type="checkbox" data-combat-id="{{@root.combatId}}" data-category="{{toggle.categoryKey}}" data-grouping="{{toggle.toggleKey}}" {{checked toggle.checked}} />
|
||||
<div class="battlepoint-toggle-container {{#if (and toggle.disabled (not toggle.checked))}}inactive{{/if}}">
|
||||
{{#if toggle.disabled}}
|
||||
<i class="grouping-lock fa-solid {{#if toggle.checked}}fa-lock{{else}}fa-unlock{{/if}}"></i>
|
||||
{{else}}
|
||||
<input type="checkbox" data-combat-id="{{@root.combatId}}" data-category="{{toggle.categoryKey}}" data-grouping="{{toggle.toggleKey}}" {{checked toggle.checked}} />
|
||||
{{/if}}
|
||||
<label class="unselected-grouping">{{toggle.categoryKey}} BP: {{localize toggle.description}}</label>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue