mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-07-21 18:09:54 +02:00
[Fix] TagTag/GroupRoll Resource Handling (#2022)
This commit is contained in:
parent
29be8c1395
commit
08b95e48d6
6 changed files with 92 additions and 47 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { ResourceUpdateMap } from '../../data/action/baseAction.mjs';
|
||||
import { shouldUseHopeFearAutomation } from '../../helpers/utils.mjs';
|
||||
import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
import Party from '../sheets/actors/party.mjs';
|
||||
|
||||
|
|
@ -480,19 +481,22 @@ export default class GroupRollDialog extends HandlebarsApplicationMixin(Applicat
|
|||
|
||||
await cls.create(msgData);
|
||||
|
||||
const resourceMap = new ResourceUpdateMap(actor);
|
||||
if (totalRoll.isCritical) {
|
||||
resourceMap.addResources([
|
||||
{ key: 'stress', value: -1 },
|
||||
{ key: 'hope', value: 1 }
|
||||
]);
|
||||
} else if (totalRoll.withHope) {
|
||||
resourceMap.addResources([{ key: 'hope', value: 1 }]);
|
||||
} else {
|
||||
resourceMap.addResources([{ key: 'fear', value: 1 }]);
|
||||
}
|
||||
/* Handle resource updates for the finished GroupRoll */
|
||||
if (shouldUseHopeFearAutomation({ gmAsPlayer: true })) {
|
||||
const resourceMap = new ResourceUpdateMap(actor);
|
||||
if (totalRoll.isCritical) {
|
||||
resourceMap.addResources([
|
||||
{ key: 'stress', value: -1 },
|
||||
{ key: 'hope', value: 1 }
|
||||
]);
|
||||
} else if (totalRoll.withHope) {
|
||||
resourceMap.addResources([{ key: 'hope', value: 1 }]);
|
||||
} else {
|
||||
resourceMap.addResources([{ key: 'fear', value: 1 }]);
|
||||
}
|
||||
|
||||
resourceMap.updateResources();
|
||||
resourceMap.updateResources();
|
||||
}
|
||||
|
||||
/* Fin */
|
||||
this.cancelRoll({ confirm: false });
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { ResourceUpdateMap } from '../../data/action/baseAction.mjs';
|
||||
import { MemberData } from '../../data/tagTeamData.mjs';
|
||||
import { getCritDamageBonus } from '../../helpers/utils.mjs';
|
||||
import { getCritDamageBonus, shouldUseHopeFearAutomation } from '../../helpers/utils.mjs';
|
||||
import { emitGMUpdate, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
import Party from '../sheets/actors/party.mjs';
|
||||
|
||||
|
|
@ -9,6 +10,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
constructor(party) {
|
||||
super({ id: `TagTeamDialog-${party.id}` });
|
||||
|
||||
this.usesTagTeamHopeCost = true;
|
||||
this.party = party;
|
||||
this.partyMembers = party.system.partyMembers
|
||||
.filter(x => Party.DICE_ROLL_ACTOR_TYPES.includes(x.type))
|
||||
|
|
@ -20,7 +22,9 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
owned: member.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
|
||||
}));
|
||||
|
||||
this.initiator = { cost: 3 };
|
||||
this.initiator = { cost:
|
||||
this.party.system.schema.fields.tagTeam.fields.initiator.fields.cost.initial
|
||||
};
|
||||
this.openForAllPlayers = true;
|
||||
|
||||
this.tabGroups.application = Object.keys(party.system.tagTeam.members).length
|
||||
|
|
@ -94,9 +98,13 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
?.addEventListener('input', this.updateInitiatorMemberField.bind(this));
|
||||
|
||||
htmlElement
|
||||
.querySelector('.initiator-cost-field')
|
||||
.querySelector('.initiator-cost-input')
|
||||
?.addEventListener('input', this.updateInitiatorCostField.bind(this));
|
||||
|
||||
htmlElement
|
||||
.querySelector('.initiator-cost-enabled-checkbox')
|
||||
?.addEventListener('change', this.toggleInitiatorCostEnabled.bind(this));
|
||||
|
||||
htmlElement
|
||||
.querySelector('.openforall-field')
|
||||
?.addEventListener('change', this.updateOpenForAllField.bind(this));
|
||||
|
|
@ -156,6 +164,7 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
.map(x => ({ value: x.id, label: x.name }));
|
||||
partContext.initiatorDisabled = !selectedMembers.length;
|
||||
partContext.openForAllPlayers = this.openForAllPlayers;
|
||||
partContext.usesTagTeamHopeCost = this.usesTagTeamHopeCost;
|
||||
|
||||
break;
|
||||
case 'tagTeamRoll':
|
||||
|
|
@ -397,6 +406,13 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
this.render();
|
||||
}
|
||||
|
||||
toggleInitiatorCostEnabled(_event) {
|
||||
this.usesTagTeamHopeCost = !this.usesTagTeamHopeCost;
|
||||
this.initiator.cost = this.usesTagTeamHopeCost ?
|
||||
this.party.system.schema.fields.tagTeam.fields.initiator.fields.cost.initial : 0;
|
||||
this.render();
|
||||
}
|
||||
|
||||
updateOpenForAllField(event) {
|
||||
this.openForAllPlayers = event.target.checked;
|
||||
this.render();
|
||||
|
|
@ -752,33 +768,38 @@ export default class TagTeamDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
|
||||
/* Handle resource updates from the finished TagTeamRoll */
|
||||
const tagTeamData = this.party.system.tagTeam;
|
||||
const fearUpdate = { key: 'fear', value: null, enabled: true };
|
||||
for (let memberId in tagTeamData.members) {
|
||||
const resourceUpdates = [];
|
||||
const rollGivesHope = finalRoll.isCritical || finalRoll.withHope;
|
||||
if (memberId === tagTeamData.initiator.memberId) {
|
||||
const value = tagTeamData.initiator.cost
|
||||
? rollGivesHope
|
||||
? 1 - tagTeamData.initiator.cost
|
||||
: -tagTeamData.initiator.cost
|
||||
: 1;
|
||||
resourceUpdates.push({ key: 'hope', value: value, enabled: true });
|
||||
} else if (rollGivesHope) {
|
||||
resourceUpdates.push({ key: 'hope', value: 1, enabled: true });
|
||||
}
|
||||
if (finalRoll.isCritical) resourceUpdates.push({ key: 'stress', value: -1, enabled: true });
|
||||
if (finalRoll.withFear) {
|
||||
fearUpdate.value = fearUpdate.value === null ? 1 : fearUpdate.value + 1;
|
||||
fearUpdate.total = fearUpdate.total === null ? -1 : fearUpdate.total - 1;
|
||||
}
|
||||
|
||||
game.actors.get(memberId).modifyResource(resourceUpdates);
|
||||
const actorResourceMaps = Object.keys(tagTeamData.members).reduce((acc, key) => {
|
||||
acc[key] = new ResourceUpdateMap(game.actors.get(key));
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
if (shouldUseHopeFearAutomation({ gmAsPlayer: true })) {
|
||||
const fearResourceMap = actorResourceMaps[tagTeamData.initiator.memberId];
|
||||
for (const memberId in tagTeamData.members) {
|
||||
const resourceMap = actorResourceMaps[memberId];
|
||||
if (finalRoll.isCritical) {
|
||||
resourceMap.addResources([
|
||||
{ key: 'stress', value: -1, enabled: true },
|
||||
{ key: 'hope', value: 1, enabled: true }
|
||||
]);
|
||||
} else if (finalRoll.withHope) {
|
||||
resourceMap.addResources([{ key: 'hope', value: 1, enabled: true }]);
|
||||
} else if (finalRoll.withFear) {
|
||||
fearResourceMap.addResources([{ key: 'fear', value: 1, enabled: true }]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fearUpdate.value) {
|
||||
mainActor.modifyResource([fearUpdate]);
|
||||
/* Even with Hope/Fear automation off, the hope cost of performing the TagTeamRoll can still optionally be subtracted */
|
||||
if (tagTeamData.initiator.cost) {
|
||||
const resourceMap = actorResourceMaps[tagTeamData.initiator.memberId];
|
||||
resourceMap.addResources([{ key: 'hope', value: -tagTeamData.initiator.cost, enabled: true }]);
|
||||
}
|
||||
|
||||
for (const resourceMap of Object.values(actorResourceMaps))
|
||||
resourceMap.updateResources();
|
||||
|
||||
/* Fin */
|
||||
this.cancelRoll({ confirm: false });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs';
|
||||
import D20Roll from './d20Roll.mjs';
|
||||
import { parseRallyDice, setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
|
||||
import { parseRallyDice, setDiceSoNiceForDualityRoll, shouldUseHopeFearAutomation } from '../helpers/utils.mjs';
|
||||
import { getDiceSoNicePresets } from '../config/generalConfig.mjs';
|
||||
import { updateResourcesForDualityReroll } from './helpers.mjs';
|
||||
|
||||
|
|
@ -312,11 +312,9 @@ export default class DualityRoll extends D20Roll {
|
|||
}
|
||||
|
||||
static async addDualityResourceUpdates(config) {
|
||||
const automationSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
||||
const hopeFearAutomation = automationSettings.hopeFear;
|
||||
if (
|
||||
!config.source?.actor ||
|
||||
(game.user.isGM ? !hopeFearAutomation.gm : !hopeFearAutomation.players) ||
|
||||
!shouldUseHopeFearAutomation() ||
|
||||
config.actionType === 'reaction' ||
|
||||
config.skips?.resources
|
||||
)
|
||||
|
|
|
|||
|
|
@ -885,3 +885,8 @@ export async function triggerChatRollFx(rolls, options = { whisper: false, blind
|
|||
foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice });
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldUseHopeFearAutomation(options = { gmAsPlayer: true }) {
|
||||
const { hopeFear } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
||||
return (!game.user.isGM || options.gmAsPlayer) ? hopeFear.players : hopeFear.gm;
|
||||
}
|
||||
|
|
@ -88,9 +88,21 @@
|
|||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
|
||||
&.inactive {
|
||||
.inactive {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.initiator-cost-fields {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
.initiator-cost-inputs {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
|
|
|
|||
|
|
@ -26,10 +26,15 @@
|
|||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="initiator-cost-fields">
|
||||
<label>{{localize "DAGGERHEART.APPLICATIONS.TagTeamSelect.FIELDS.initiator.cost.label"}}</label>
|
||||
<div class="form-fields">
|
||||
<input type="text" data-dtype="Number" value="{{initiator.cost}}" class="initiator-cost-field" {{#if initiatorDisabled}}disabled{{/if}} />
|
||||
<div class="initiator-cost-inputs">
|
||||
<input type="checkbox" class="initiator-cost-enabled-checkbox {{#if initiatorDisabled}}inactive{{/if}}" {{checked usesTagTeamHopeCost}} {{#if initiatorDisabled}}disabled{{/if}} />
|
||||
<input
|
||||
type="text" data-dtype="Number" value="{{initiator.cost}}"
|
||||
class="initiator-cost-input {{#if (or initiatorDisabled (not usesTagTeamHopeCost))}}inactive{{/if}}"
|
||||
{{#if (or initiatorDisabled (not usesTagTeamHopeCost))}}disabled{{/if}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue