mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-12 03:31:07 +01:00
[PR] [Feature] Party Sheet (#1230)
* start development * finish party members tab * start resources tab * finish resources tab * finish inventory tab and add inital template to projects tab * add resource buttons actions methods * add group roll dialog * Main implementation * Fixed costs * Minor fixes and tweaks for the party sheet (#1239) * Minor fixes and tweaks for the party sheet * Fix scroll restoration for party sheet tabs * Finished GroupRoll * Removed/commented-out not yet implemented things * Commented out Difficulty since it's not used yet * Re-render party when members update (#1242) * Fixed so style applies in preview chat message * Added the clown car * Fixed so items can be dropped into the Party sheet * Added delete icon to inventory * Fixed TokenHUD token property useage. Fixed skipping roll message * Added visible modifier to GroupRoll leader result * Leader roll displays the large result display right away after rolling * Corrected tokenHUD for non-player-tokens * Fixed clowncar tokenData * Fixed TagTeam roll message and sound * Removed final TagTeamRoll roll sound * [PR] [Party Sheets] Sidebar character sheet changes (#1249) * Something experimenting * I am silly (wearning Dunce hat) * Stressful task * Armor functional to be hit * CSS Changes to accomadate pip boy * last minute change to resource section for better visual feeling * restoring old css for toggle * Added setting to toggle pip/number display * toggle functionality added * Fixed light-mode in characterSheet * Fixed multi-row resource pips display for character * Fixed separators * Added pip-display to Adversary and Companion. Some fixing on armor display --------- Co-authored-by: WBHarry <williambjrklund@gmail.com> * Fixed party height and resource armor update * Fixed deletebutton padding * Only showing expand-me icon on InventoryItem if there is a description to show * . * Fixed menu icon to be beige instead of white in dark mode --------- Co-authored-by: moliloo <dev.murilobrito@gmail.com> Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com> Co-authored-by: Nikhil Nagarajan <potter.nikhil@gmail.com>
This commit is contained in:
parent
f53252a369
commit
261a3a68b0
91 changed files with 3769 additions and 271 deletions
|
|
@ -11,3 +11,5 @@ export { default as OwnershipSelection } from './ownershipSelection.mjs';
|
|||
export { default as RerollDamageDialog } from './rerollDamageDialog.mjs';
|
||||
export { default as ResourceDiceDialog } from './resourceDiceDialog.mjs';
|
||||
export { default as ActionSelectionDialog } from './actionSelectionDialog.mjs';
|
||||
export { default as GroupRollDialog } from './group-roll-dialog.mjs';
|
||||
export { default as TagTeamDialog } from './tagTeamDialog.mjs';
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
updateIsAdvantage: this.updateIsAdvantage,
|
||||
selectExperience: this.selectExperience,
|
||||
toggleReaction: this.toggleReaction,
|
||||
toggleTagTeamRoll: this.toggleTagTeamRoll,
|
||||
submitRoll: this.submitRoll
|
||||
},
|
||||
form: {
|
||||
|
|
@ -120,6 +121,13 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
context.showReaction = !this.config.roll?.type && context.rollType === 'DualityRoll';
|
||||
context.reactionOverride = this.reactionOverride;
|
||||
}
|
||||
|
||||
const tagTeamSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll);
|
||||
if (tagTeamSetting.members[this.actor.id] && !this.config.skips?.createMessage) {
|
||||
context.activeTagTeamRoll = true;
|
||||
context.tagTeamSelected = this.config.tagTeamSelected;
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
@ -195,6 +203,11 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
|
|||
}
|
||||
}
|
||||
|
||||
static toggleTagTeamRoll() {
|
||||
this.config.tagTeamSelected = !this.config.tagTeamSelected;
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async submitRoll() {
|
||||
await this.close({ submitted: true });
|
||||
}
|
||||
|
|
|
|||
196
module/applications/dialogs/group-roll-dialog.mjs
Normal file
196
module/applications/dialogs/group-roll-dialog.mjs
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
import autocomplete from 'autocompleter';
|
||||
import { abilities } from '../../config/actorConfig.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class GroupRollDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(actors) {
|
||||
super();
|
||||
this.actors = actors;
|
||||
this.actorLeader = {};
|
||||
this.actorsMembers = [];
|
||||
}
|
||||
|
||||
get title() {
|
||||
return 'Group Roll';
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'group-roll'],
|
||||
position: { width: 'auto', height: 'auto' },
|
||||
window: {
|
||||
title: 'DAGGERHEART.UI.Chat.groupRoll.title'
|
||||
},
|
||||
actions: {
|
||||
roll: GroupRollDialog.#roll,
|
||||
removeLeader: GroupRollDialog.#removeLeader,
|
||||
removeMember: GroupRollDialog.#removeMember
|
||||
},
|
||||
form: { handler: this.updateData, submitOnChange: true, closeOnSubmit: false }
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
application: {
|
||||
id: 'group-roll',
|
||||
template: 'systems/daggerheart/templates/dialogs/group-roll/group-roll.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
_attachPartListeners(partId, htmlElement, options) {
|
||||
super._attachPartListeners(partId, htmlElement, options);
|
||||
const leaderChoices = this.actors.filter(x => this.actorsMembers.every(member => member.actor?.id !== x.id));
|
||||
const memberChoices = this.actors.filter(
|
||||
x => this.actorLeader?.actor?.id !== x.id && this.actorsMembers.every(member => member.actor?.id !== x.id)
|
||||
);
|
||||
|
||||
htmlElement.querySelectorAll('.leader-change-input').forEach(element => {
|
||||
autocomplete({
|
||||
input: element,
|
||||
fetch: function (text, update) {
|
||||
if (!text) {
|
||||
update(leaderChoices);
|
||||
} else {
|
||||
text = text.toLowerCase();
|
||||
var suggestions = leaderChoices.filter(n => n.name.toLowerCase().includes(text));
|
||||
update(suggestions);
|
||||
}
|
||||
},
|
||||
render: function (actor, search) {
|
||||
const actorName = game.i18n.localize(actor.name);
|
||||
const matchIndex = actorName.toLowerCase().indexOf(search);
|
||||
|
||||
const beforeText = actorName.slice(0, matchIndex);
|
||||
const matchText = actorName.slice(matchIndex, matchIndex + search.length);
|
||||
const after = actorName.slice(matchIndex + search.length, actorName.length);
|
||||
const img = document.createElement('img');
|
||||
img.src = actor.img;
|
||||
|
||||
const element = document.createElement('li');
|
||||
element.appendChild(img);
|
||||
|
||||
const label = document.createElement('span');
|
||||
label.innerHTML = `${beforeText}${matchText ? `<strong>${matchText}</strong>` : ''}${after}`;
|
||||
element.appendChild(label);
|
||||
|
||||
return element;
|
||||
},
|
||||
renderGroup: function (label) {
|
||||
const itemElement = document.createElement('div');
|
||||
itemElement.textContent = game.i18n.localize(label);
|
||||
return itemElement;
|
||||
},
|
||||
onSelect: actor => {
|
||||
element.value = actor.uuid;
|
||||
this.actorLeader = { actor: actor, trait: 'agility', difficulty: 0 };
|
||||
this.render();
|
||||
},
|
||||
click: e => e.fetch(),
|
||||
customize: function (_input, _inputRect, container) {
|
||||
container.style.zIndex = foundry.applications.api.ApplicationV2._maxZ;
|
||||
},
|
||||
minLength: 0
|
||||
});
|
||||
});
|
||||
|
||||
htmlElement.querySelectorAll('.team-push-input').forEach(element => {
|
||||
autocomplete({
|
||||
input: element,
|
||||
fetch: function (text, update) {
|
||||
if (!text) {
|
||||
update(memberChoices);
|
||||
} else {
|
||||
text = text.toLowerCase();
|
||||
var suggestions = memberChoices.filter(n => n.name.toLowerCase().includes(text));
|
||||
update(suggestions);
|
||||
}
|
||||
},
|
||||
render: function (actor, search) {
|
||||
const actorName = game.i18n.localize(actor.name);
|
||||
const matchIndex = actorName.toLowerCase().indexOf(search);
|
||||
|
||||
const beforeText = actorName.slice(0, matchIndex);
|
||||
const matchText = actorName.slice(matchIndex, matchIndex + search.length);
|
||||
const after = actorName.slice(matchIndex + search.length, actorName.length);
|
||||
const img = document.createElement('img');
|
||||
img.src = actor.img;
|
||||
|
||||
const element = document.createElement('li');
|
||||
element.appendChild(img);
|
||||
|
||||
const label = document.createElement('span');
|
||||
label.innerHTML = `${beforeText}${matchText ? `<strong>${matchText}</strong>` : ''}${after}`;
|
||||
element.appendChild(label);
|
||||
|
||||
return element;
|
||||
},
|
||||
renderGroup: function (label) {
|
||||
const itemElement = document.createElement('div');
|
||||
itemElement.textContent = game.i18n.localize(label);
|
||||
return itemElement;
|
||||
},
|
||||
onSelect: actor => {
|
||||
element.value = actor.uuid;
|
||||
this.actorsMembers.push({ actor: actor, trait: 'agility', difficulty: 0 });
|
||||
this.render({ force: true });
|
||||
},
|
||||
click: e => e.fetch(),
|
||||
customize: function (_input, _inputRect, container) {
|
||||
container.style.zIndex = foundry.applications.api.ApplicationV2._maxZ;
|
||||
},
|
||||
minLength: 0
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.leader = this.actorLeader;
|
||||
context.members = this.actorsMembers;
|
||||
context.traitList = abilities;
|
||||
|
||||
context.allSelected = this.actorsMembers.length + (this.actorLeader?.actor ? 1 : 0) === this.actors.length;
|
||||
context.rollDisabled = context.members.length === 0 || !this.actorLeader?.actor;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static updateData(event, _, formData) {
|
||||
const { actorLeader, actorsMembers } = foundry.utils.expandObject(formData.object);
|
||||
this.actorLeader = foundry.utils.mergeObject(this.actorLeader, actorLeader);
|
||||
this.actorsMembers = foundry.utils.mergeObject(this.actorsMembers, actorsMembers);
|
||||
this.render(true);
|
||||
}
|
||||
|
||||
static async #removeLeader(_, button) {
|
||||
this.actorLeader = null;
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #removeMember(_, button) {
|
||||
this.actorsMembers = this.actorsMembers.filter(m => m.actor.uuid !== button.dataset.memberUuid);
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #roll() {
|
||||
const cls = getDocumentClass('ChatMessage');
|
||||
const systemData = {
|
||||
leader: this.actorLeader,
|
||||
members: this.actorsMembers
|
||||
};
|
||||
const msg = {
|
||||
type: 'groupRoll',
|
||||
user: game.user.id,
|
||||
speaker: cls.getSpeaker(),
|
||||
title: game.i18n.localize('DAGGERHEART.UI.Chat.groupRoll.title'),
|
||||
system: systemData,
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/ui/chat/groupRoll.hbs',
|
||||
{ system: systemData }
|
||||
)
|
||||
};
|
||||
|
||||
cls.create(msg);
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
import { RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
|
||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||
|
||||
export default class RerollDamageDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
|
@ -122,6 +124,15 @@ export default class RerollDamageDialog extends HandlebarsApplicationMixin(Appli
|
|||
}, {})
|
||||
};
|
||||
await this.message.update(update);
|
||||
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.TagTeamRoll });
|
||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: {
|
||||
refreshType: RefreshType.TagTeamRoll
|
||||
}
|
||||
});
|
||||
|
||||
await this.close();
|
||||
}
|
||||
|
||||
|
|
|
|||
315
module/applications/dialogs/tagTeamDialog.mjs
Normal file
315
module/applications/dialogs/tagTeamDialog.mjs
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
import { GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
export default class TagTeamDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(party) {
|
||||
super();
|
||||
|
||||
this.data = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll);
|
||||
this.party = party;
|
||||
|
||||
this.setupHooks = Hooks.on(socketEvent.Refresh, ({ refreshType }) => {
|
||||
if (refreshType === RefreshType.TagTeamRoll) {
|
||||
this.data = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll);
|
||||
this.render();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
get title() {
|
||||
return game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.title');
|
||||
}
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: 'form',
|
||||
classes: ['daggerheart', 'views', 'dh-style', 'dialog', 'tag-team-dialog'],
|
||||
position: { width: 550, height: 'auto' },
|
||||
actions: {
|
||||
removeMember: TagTeamDialog.#removeMember,
|
||||
unlinkMessage: TagTeamDialog.#unlinkMessage,
|
||||
selectMessage: TagTeamDialog.#selectMessage,
|
||||
createTagTeam: TagTeamDialog.#createTagTeam
|
||||
},
|
||||
form: { handler: this.updateData, submitOnChange: true, closeOnSubmit: false }
|
||||
};
|
||||
|
||||
static PARTS = {
|
||||
application: {
|
||||
id: 'tag-team-dialog',
|
||||
template: 'systems/daggerheart/templates/dialogs/tagTeamDialog.hbs'
|
||||
}
|
||||
};
|
||||
|
||||
async _prepareContext(_options) {
|
||||
const context = await super._prepareContext(_options);
|
||||
context.hopeCost = this.hopeCost;
|
||||
context.data = this.data;
|
||||
|
||||
context.memberOptions = this.party.filter(c => !this.data.members[c.id]);
|
||||
context.selectedCharacterOptions = this.party.filter(c => this.data.members[c.id]);
|
||||
|
||||
context.members = Object.keys(this.data.members).map(id => {
|
||||
const roll = this.data.members[id].messageId ? game.messages.get(this.data.members[id].messageId) : null;
|
||||
|
||||
context.usesDamage =
|
||||
context.usesDamage === undefined
|
||||
? roll?.system.hasDamage
|
||||
: context.usesDamage && roll?.system.hasDamage;
|
||||
return {
|
||||
character: this.party.find(x => x.id === id),
|
||||
selected: this.data.members[id].selected,
|
||||
roll: roll,
|
||||
damageValues: roll
|
||||
? Object.keys(roll.system.damage).map(key => ({
|
||||
key: key,
|
||||
name: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[key].label),
|
||||
total: roll.system.damage[key].total
|
||||
}))
|
||||
: null
|
||||
};
|
||||
});
|
||||
|
||||
const initiatorChar = this.party.find(x => x.id === this.data.initiator.id);
|
||||
context.initiator = {
|
||||
character: initiatorChar,
|
||||
cost: this.data.initiator.cost
|
||||
};
|
||||
|
||||
context.selectedData = Object.values(context.members).reduce(
|
||||
(acc, member) => {
|
||||
if (!member.roll) return acc;
|
||||
if (member.selected) {
|
||||
acc.result = `${member.roll.system.roll.total} ${member.roll.system.roll.result.label}`;
|
||||
}
|
||||
|
||||
if (context.usesDamage) {
|
||||
if (!acc.damageValues) acc.damageValues = {};
|
||||
for (let damage of member.damageValues) {
|
||||
if (acc.damageValues[damage.key]) {
|
||||
acc.damageValues[damage.key].total += damage.total;
|
||||
} else {
|
||||
acc.damageValues[damage.key] = foundry.utils.deepClone(damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
{ result: null, damageValues: null }
|
||||
);
|
||||
context.showResult = Object.values(context.members).reduce((enabled, member) => {
|
||||
if (!member.roll) return enabled;
|
||||
if (context.usesDamage) {
|
||||
enabled = enabled === null ? member.damageValues.length > 0 : enabled && member.damageValues.length > 0;
|
||||
} else {
|
||||
enabled = enabled === null ? Boolean(member.roll) : enabled && Boolean(member.roll);
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}, null);
|
||||
|
||||
context.createDisabled =
|
||||
!context.selectedData.result ||
|
||||
!this.data.initiator.id ||
|
||||
Object.keys(this.data.members).length === 0 ||
|
||||
Object.values(context.members).some(x =>
|
||||
context.usesDamage ? !x.damageValues || x.damageValues.length === 0 : !x.roll
|
||||
);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
async updateSource(update) {
|
||||
await this.data.updateSource(update);
|
||||
|
||||
if (game.user.isGM) {
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll, this.data.toObject());
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.TagTeamRoll });
|
||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: {
|
||||
refreshType: RefreshType.TagTeamRoll
|
||||
}
|
||||
});
|
||||
} else {
|
||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.GMUpdate,
|
||||
data: {
|
||||
action: GMUpdateEvent.UpdateSetting,
|
||||
uuid: CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll,
|
||||
update: this.data.toObject(),
|
||||
refresh: { refreshType: RefreshType.TagTeamRoll }
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static async updateData(_event, _element, formData) {
|
||||
const { selectedAddMember, initiator } = foundry.utils.expandObject(formData.object);
|
||||
const update = { initiator: initiator };
|
||||
if (selectedAddMember) {
|
||||
const member = await foundry.utils.fromUuid(selectedAddMember);
|
||||
update[`members.${member.id}`] = { messageId: null };
|
||||
}
|
||||
|
||||
await this.updateSource(update);
|
||||
this.render();
|
||||
}
|
||||
|
||||
static async #removeMember(_, button) {
|
||||
const update = { [`members.-=${button.dataset.characterId}`]: null };
|
||||
if (this.data.initiator.id === button.dataset.characterId) {
|
||||
update.iniator = { id: null };
|
||||
}
|
||||
|
||||
await this.updateSource(update);
|
||||
}
|
||||
|
||||
static async #unlinkMessage(_, button) {
|
||||
await this.updateSource({ [`members.${button.id}.messageId`]: null });
|
||||
}
|
||||
|
||||
static async #selectMessage(_, button) {
|
||||
const member = this.data.members[button.id];
|
||||
const currentSelected = Object.keys(this.data.members).find(key => this.data.members[key].selected);
|
||||
const curretSelectedUpdate =
|
||||
currentSelected && currentSelected !== button.id ? { [`${currentSelected}`]: { selected: false } } : {};
|
||||
await this.updateSource({
|
||||
members: {
|
||||
[`${button.id}`]: { selected: !member.selected },
|
||||
...curretSelectedUpdate
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static async #createTagTeam() {
|
||||
const mainRollId = Object.keys(this.data.members).find(key => this.data.members[key].selected);
|
||||
const mainRoll = game.messages.get(this.data.members[mainRollId].messageId);
|
||||
|
||||
if (this.data.initiator.cost) {
|
||||
const initiator = this.party.find(x => x.id === this.data.initiator.id);
|
||||
if (initiator.system.resources.hope.value < this.data.initiator.cost) {
|
||||
return ui.notifications.warn(
|
||||
game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.insufficientHope')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const secondaryRolls = Object.keys(this.data.members)
|
||||
.filter(key => key !== mainRollId)
|
||||
.map(key => game.messages.get(this.data.members[key].messageId));
|
||||
|
||||
const systemData = foundry.utils.deepClone(mainRoll).system.toObject();
|
||||
for (let roll of secondaryRolls) {
|
||||
if (roll.system.hasDamage) {
|
||||
for (let key in roll.system.damage) {
|
||||
var damage = roll.system.damage[key];
|
||||
if (systemData.damage[key]) {
|
||||
systemData.damage[key].total += damage.total;
|
||||
systemData.damage[key].parts = [...systemData.damage[key].parts, ...damage.parts];
|
||||
} else {
|
||||
systemData.damage[key] = damage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
systemData.title = game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.chatMessageRollTitle');
|
||||
|
||||
const cls = getDocumentClass('ChatMessage'),
|
||||
msgData = {
|
||||
type: 'dualityRoll',
|
||||
user: game.user.id,
|
||||
title: game.i18n.localize('DAGGERHEART.APPLICATIONS.TagTeamSelect.title'),
|
||||
speaker: cls.getSpeaker({ actor: this.party.find(x => x.id === mainRollId) }),
|
||||
system: systemData,
|
||||
rolls: mainRoll.rolls,
|
||||
sound: null,
|
||||
flags: { core: { RollTable: true } }
|
||||
};
|
||||
|
||||
await cls.create(msgData);
|
||||
|
||||
const fearUpdate = { key: 'fear', value: null, total: null, enabled: true };
|
||||
for (let memberId of Object.keys(this.data.members)) {
|
||||
const resourceUpdates = [];
|
||||
if (systemData.roll.isCritical || systemData.roll.result.duality === 1) {
|
||||
const value =
|
||||
memberId !== this.data.initiator.id
|
||||
? 1
|
||||
: this.data.initiator.cost
|
||||
? 1 - this.data.initiator.cost
|
||||
: 1;
|
||||
resourceUpdates.push({ key: 'hope', value: value, total: -value, enabled: true });
|
||||
}
|
||||
if (systemData.roll.isCritical) resourceUpdates.push({ key: 'stress', value: -1, total: 1, enabled: true });
|
||||
if (systemData.roll.result.duality === -1) {
|
||||
fearUpdate.value = fearUpdate.value === null ? 1 : fearUpdate.value + 1;
|
||||
fearUpdate.total = fearUpdate.total === null ? -1 : fearUpdate.total - 1;
|
||||
}
|
||||
|
||||
this.party.find(x => x.id === memberId).modifyResource(resourceUpdates);
|
||||
}
|
||||
|
||||
if (fearUpdate.value) {
|
||||
this.party.find(x => x.id === mainRollId).modifyResource([fearUpdate]);
|
||||
}
|
||||
|
||||
/* Improve by fetching default from schema */
|
||||
const update = { members: [], initiator: { id: null, cost: 3 } };
|
||||
if (game.user.isGM) {
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll, update);
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.TagTeamRoll });
|
||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: {
|
||||
refreshType: RefreshType.TagTeamRoll
|
||||
}
|
||||
});
|
||||
} else {
|
||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.GMUpdate,
|
||||
data: {
|
||||
action: GMUpdateEvent.UpdateSetting,
|
||||
uuid: CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll,
|
||||
update: update,
|
||||
refresh: { refreshType: RefreshType.TagTeamRoll }
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static async assignRoll(char, message) {
|
||||
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll);
|
||||
const character = settings.members[char.id];
|
||||
if (!character) return;
|
||||
|
||||
await settings.updateSource({ [`members.${char.id}.messageId`]: message.id });
|
||||
|
||||
if (game.user.isGM) {
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll, settings);
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.TagTeamRoll });
|
||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: {
|
||||
refreshType: RefreshType.TagTeamRoll
|
||||
}
|
||||
});
|
||||
} else {
|
||||
await game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.GMUpdate,
|
||||
data: {
|
||||
action: GMUpdateEvent.UpdateSetting,
|
||||
uuid: CONFIG.DH.SETTINGS.gameSettings.TagTeamRoll,
|
||||
update: settings,
|
||||
refresh: { refreshType: RefreshType.TagTeamRoll }
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async close(options = {}) {
|
||||
Hooks.off(socketEvent.Refresh, this.setupHooks);
|
||||
await super.close(options);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue