Fix group/individual initiative

master
John Downey 2022-04-09 17:24:00 -05:00
parent 483cd49f9a
commit 60e61da5c4
3 changed files with 107 additions and 54 deletions

View File

@ -86,10 +86,10 @@ Hooks.on("renderSidebarTab", async (object, html) => {
} }
}); });
Hooks.on("preCreateCombatant", (combat, data, options, id) => { Hooks.on("createCombatant", async (combatant, options, userId) => {
let init = game.settings.get("acks", "initiative"); let init = game.settings.get("acks", "initiative");
if (init == "group") { if (init == "group") {
AcksCombat.addCombatant(combat, data, options, id); await AcksCombat.addCombatant(combatant, options, userId);
} }
}); });

View File

@ -1,79 +1,112 @@
export class AcksCombat { export class AcksCombat {
static rollInitiative(combat, data) { static async rollInitiative(combat, data) {
// Check groups // Initialize groups.
data.combatants = []; data.combatants = [];
let groups = {}; let groups = {};
combat.data.combatants.forEach((cbt) => { combat.data.combatants.forEach((cbt) => {
groups[cbt.data.flags.acks.group] = { present: true }; groups[cbt.data.flags.acks.group] = {present: true};
data.combatants.push(cbt); data.combatants.push(cbt);
}); });
// Roll init // Roll initiative for each group.
Object.keys(groups).forEach((group) => { for (const group in groups) {
let roll = new Roll("1d6").roll(); const roll = new Roll("1d6");
roll.toMessage({ await roll.evaluate({async: true});
flavor: game.i18n.format('ACKS.roll.initiative', { group: CONFIG["ACKS"].colors[group] }), await roll.toMessage({
}); flavor: game.i18n.format('ACKS.roll.initiative', {
groups[group].initiative = roll.total; group: CONFIG["ACKS"].colors[group],
}),
}); });
// Set init groups[group].initiative = roll.total;
for (let i = 0; i < data.combatants.length; ++i) { }
if (!data.combatants[i].actor) {
// Set the inititative for each group combatant.
for (const combatant of data.combatants) {
if (!combatant.actor) {
return; return;
} }
data.combatants[i].initiative =
groups[data.combatants[i].data.flags.acks.group].initiative; let initiative = groups[combatant.data.flags.acks.group].initiative;
if (data.combatants[i].actor.data.data.isSlow) { if (combatant.actor.data.data.isSlow) {
data.combatants[i].initiative -= 1; initiative -= 1;
} }
await combatant.update({
initiative: initiative,
});
} }
combat.setupTurns(); combat.setupTurns();
} }
static async resetInitiative(combat, data) { static async resetInitiative(combat, data) {
let reroll = game.settings.get("acks", "initiative"); const reroll = game.settings.get("acks", "initiativePersistence");
if (!["reset", "reroll"].includes(reroll)) { if (!["reset", "reroll"].includes(reroll)) {
return; return;
} }
combat.resetAll(); combat.resetAll();
} }
static async individualInitiative(combat, data) { static async individualInitiative(combat, data) {
let updates = []; const updates = [];
let messages = []; const messages = [];
combat.data.combatants.forEach((c, i) => {
// This comes from foundry.js, had to remove the update turns thing let index = 0;
// Roll initiative
const cf = combat._getInitiativeFormula(c); for (const [id, combatant] of combat.data.combatants.entries()) {
const roll = combat._getInitiativeRoll(c, cf); const roll = combatant.getInitiativeRoll();
await roll.evaluate({async: true});
let value = roll.total; let value = roll.total;
if (combat.settings.skipDefeated && c.defeated) {
if (combat.settings.skipDefeated && combatant.defeated) {
value = -790; value = -790;
} }
updates.push({ _id: c._id, initiative: value });
updates.push({
_id: id,
initiative: value,
});
// Determine the roll mode // Determine the roll mode
let rollMode = game.settings.get("core", "rollMode"); let rollMode = game.settings.get("core", "rollMode");
if ((c.token.hidden || c.hidden) && (rollMode === "roll")) rollMode = "gmroll"; if ((combatant.token.hidden || combatant.hidden)
&& (rollMode === "roll")) {
rollMode = "gmroll";
}
// Construct chat message data // Construct chat message data
let messageData = mergeObject({ const messageData = mergeObject({
speaker: { speaker: {
scene: canvas.scene._id, scene: canvas.scene._id,
actor: c.actor ? c.actor._id : null, actor: combatant.actor?.id || null,
token: c.token._id, token: combatant.token.id,
alias: c.token.name alias: combatant.token.name
}, },
flavor: game.i18n.format('ACKS.roll.individualInit', { name: c.token.name }) flavor: game.i18n.format('ACKS.roll.individualInit', {
name: combatant.token.name,
}),
}, {}); }, {});
const chatData = roll.toMessage(messageData, { rollMode, create: false });
if (i > 0) chatData.sound = null; // Only play 1 sound for the whole set const chatData = await roll.toMessage(messageData, {
messages.push(chatData); rollMode,
create: false,
}); });
await combat.updateEmbeddedEntity("Combatant", updates);
await CONFIG.ChatMessage.entityClass.create(messages); // Only play one sound for the whole set.
if (index > 0) {
chatData.sound = null;
}
messages.push(chatData);
++index;
}
await combat.updateEmbeddedDocuments("Combatant", updates);
await CONFIG.ChatMessage.documentClass.create(messages);
data.turn = 0; data.turn = 0;
} }
@ -128,8 +161,8 @@ export class AcksCombat {
$(ct).find(".roll").remove(); $(ct).find(".roll").remove();
// Get group color // Get group color
const cmbtant = object.combat.getCombatant(ct.dataset.combatantId); const combatant = object.viewed.combatants.get(ct.dataset.combatantId);
let color = cmbtant.data.flags.acks.group; let color = combatant.data.flags.acks?.group;
// Append colored flag // Append colored flag
let controls = $(ct).find(".combatant-controls"); let controls = $(ct).find(".combatant-controls");
@ -137,6 +170,7 @@ export class AcksCombat {
`<a class='combatant-control flag' style='color:${color}' title="${CONFIG.ACKS.colors[color]}"><i class='fas fa-flag'></i></a>` `<a class='combatant-control flag' style='color:${color}' title="${CONFIG.ACKS.colors[color]}"><i class='fas fa-flag'></i></a>`
); );
}); });
AcksCombat.addListeners(html); AcksCombat.addListeners(html);
} }
@ -223,7 +257,11 @@ export class AcksCombat {
const combatant = game.combat.combatants.get(id); const combatant = game.combat.combatants.get(id);
await combatant.update({ await combatant.update({
_id: id, _id: id,
flags: { acks: { group: colors[index] } }, flags: {
acks: {
group: colors[index],
},
},
}); });
}); });
@ -239,10 +277,9 @@ export class AcksCombat {
}); });
} }
static addCombatant(combat, data, options, id) { static async addCombatant(combatant, options, userId) {
let token = canvas.tokens.get(data.tokenId);
let color = "black"; let color = "black";
switch (token.data.disposition) { switch (combatant.token.data.disposition) {
case -1: case -1:
color = "red"; color = "red";
break; break;
@ -253,12 +290,16 @@ export class AcksCombat {
color = "green"; color = "green";
break; break;
} }
data.flags = {
await combatant.update({
flags: {
acks: { acks: {
group: color, group: color,
}, },
}; },
});
} }
static activateCombatant(li) { static activateCombatant(li) {
const turn = game.combat.turns.findIndex(turn => turn._id === li.data('combatant-id')); const turn = game.combat.turns.findIndex(turn => turn._id === li.data('combatant-id'));
game.combat.update({turn: turn}) game.combat.update({turn: turn})
@ -274,7 +315,7 @@ export class AcksCombat {
static async preUpdateCombat(combat, data, diff, id) { static async preUpdateCombat(combat, data, diff, id) {
let init = game.settings.get("acks", "initiative"); let init = game.settings.get("acks", "initiative");
let reroll = game.settings.get("acks", "initiative"); let reroll = game.settings.get("acks", "initiativePersistence");
if (!data.round) { if (!data.round) {
return; return;
} }

View File

@ -1,6 +1,18 @@
export const registerSettings = function () { export const registerSettings = () => {
game.settings.register("acks", "initiative", { game.settings.register("acks", "initiative", {
name: game.i18n.localize("ACKS.Setting.Initiative"),
hint: game.i18n.localize("ACKS.Setting.InitiativeHint"),
default: "individual",
scope: "world",
type: String,
config: true,
choices: {
individual: "ACKS.Setting.InitiativeIndividual",
group: "ACKS.Setting.InitiativeGroup",
},
});
game.settings.register("acks", "initiativePersistence", {
name: game.i18n.localize("ACKS.Setting.RerollInitiative"), name: game.i18n.localize("ACKS.Setting.RerollInitiative"),
hint: game.i18n.localize("ACKS.Setting.RerollInitiativeHint"), hint: game.i18n.localize("ACKS.Setting.RerollInitiativeHint"),
default: "reset", default: "reset",