Skip to content

Commit

Permalink
Final fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Haxxer committed Oct 4, 2023
1 parent 529dcf1 commit 0d0257f
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 12 deletions.
10 changes: 8 additions & 2 deletions languages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
},
"OverkillDamage": {
"Title": "Overkill Damage!",
"Label1": "You can destroy a total of {targets} \"${name}\" minions within your weapon's range.",
"Label2": "Once you're happy with your targets, press OK."
"MeleeLabel1": "You can destroy a total of {max_targets} \"{name}\" minions within your attack's range.",
"RangedLabel1": "You can destroy a total of {max_targets} \"{name}\" minions directly behind the original target and within your attack's range.",
"Label2": "Total targets remaining: {total_targets}/{max_targets}",
"Label3": "Once you're happy with your targets, press OK."
}
},
"ActorContextMenu": {
Expand All @@ -35,6 +37,10 @@
"Title": "Enable Overkill Damage",
"Hint": "When enabled, if minion is hit by an attack that exceeds its hit points, the attacker is allowed to transfer the remaining damage to adjacent similar minions, repeating until the damage reaches 0."
},
"EnableRangedOverkill": {
"Title": "Enable Ranged Overkill Damage",
"Hint": "When enabled, ranged attacks also trigger overkill damage. The MDCM rules allow this, so long the subsequent targets are in a line directly behind the original target."
},
"EnableGroupAttacks": {
"Title": "Enable Minion Group Attacks",
"Hint": "When enabled, minion group attacks automatically prompt to ask how many minions are attacking the target."
Expand Down
12 changes: 12 additions & 0 deletions scripts/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const CONSTANTS = {
}
}],
ATTACK_TYPES: ["mwak", "rwak", "msak", "rsak"],
MELEE_ATTACKS: ["mwak", "msak"],
RANGED_ATTACKS: ["rwak", "rsak"],
FLAGS: {
COMBATANTS: `${FLAG}.combatants`,
GROUP_NUMBER: `${FLAG}.groupNumber`,
Expand All @@ -25,6 +27,7 @@ const CONSTANTS = {
CONSTANTS["SETTING_KEYS"] = {
DEBUG: "debug",
ENABLE_OVERKILL_DAMAGE: "enableOverkillDamage",
ENABLE_RANGED_OVERKILL: "enableRangedOverkill",
ENABLE_GROUP_ATTACKS: "enableGroupAttacks",
ENABLE_GROUP_ATTACK_BONUS: "enableGroupAttackBonus",
ENABLE_MINION_SUPER_SAVE: "enableMinionSuperSave",
Expand All @@ -51,6 +54,15 @@ CONSTANTS["SETTINGS"] = {
type: Boolean
},

[CONSTANTS.SETTING_KEYS.ENABLE_RANGED_OVERKILL]: {
name: "MINIONMANAGER.Settings.EnableRangedOverkill.Title",
hint: "MINIONMANAGER.Settings.EnableRangedOverkill.Hint",
scope: "world",
config: true,
default: true,
type: Boolean
},

[CONSTANTS.SETTING_KEYS.ENABLE_GROUP_ATTACKS]: {
name: "MINIONMANAGER.Settings.EnableGroupAttacks.Title",
hint: "MINIONMANAGER.Settings.EnableGroupAttacks.Hint",
Expand Down
49 changes: 39 additions & 10 deletions scripts/minion.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,10 @@ export function initializeMinions() {

// Overkill management
const actionType = workflow.item.system?.actionType;
const isRangedAttack = CONSTANTS.RANGED_ATTACKS.includes(actionType);

if (!actionType || !(actionType === "mwak" || actionType === "msak")) return true;
if (!actionType || !CONSTANTS.ATTACK_TYPES.includes(actionType)) return true;
if (!lib.getSetting(CONSTANTS.SETTING_KEYS.ENABLE_RANGED_OVERKILL) && isRangedAttack) return true;
if (!workflow.hitTargets.size) return true;

const hitTarget = Array.from(workflow.hitTargets)[0]
Expand All @@ -98,26 +100,48 @@ export function initializeMinions() {
damageTotal -= minionHP;

const closestTokens = new Set(canvas.tokens.placeables
.filter(_token => hitTarget.actor.name === _token.actor.name && canvas.grid.measureDistance(workflow.token, _token) <= workflow.item.system.range.value + 2.5)
.filter(_token => {
const withinRange = canvas.grid.measureDistance(workflow.token, _token) <= workflow.item.system.range.value + 2.5;
return hitTarget.actor.name === _token.actor.name && withinRange;
})
.sort((a, b) => canvas.grid.measureDistance(workflow.token, b) - canvas.grid.measureDistance(workflow.token, a)));

closestTokens.delete(game.user.targets.first())
closestTokens.delete(game.user.targets.first());

let maxAdditionalTargets = Math.ceil(damageTotal / minionHP);
Array.from(closestTokens)
.slice(0, maxAdditionalTargets)
.forEach(_token => _token.setTarget(true, { releaseOthers: false }));

await Dialog.confirm({
const label1Localization = "MINIONMANAGER.Dialogs.OverkillDamage." + (isRangedAttack ? "RangedLabel1" : "MeleeLabel1");
const label1 = game.i18n.format(label1Localization, {
max_targets: maxAdditionalTargets + 1,
total_targets: game.user.targets.size,
name: hitTarget.actor.name
});

let label2 = game.i18n.format("MINIONMANAGER.Dialogs.OverkillDamage.Label2", {
max_targets: maxAdditionalTargets + 1,
total_targets: game.user.targets.size
});

let targetingHookId = false;
await Dialog.prompt({
"title": game.i18n.localize("MINIONMANAGER.Dialogs.OverkillDamage.Title"),
"content": `
<p style='text-align:center;'>${game.i18n.format("MINIONMANAGER.Dialogs.OverkillDamage.Label1", {
targets: maxAdditionalTargets + 1,
name: hitTarget.actor.name
})}</p>
<p style='text-align:center;'>${game.i18n.localize("MINIONMANAGER.Dialogs.OverkillDamage.Label2")}</p>
<p style='text-align:center;'>${label1}</p>
<p style='text-align:center;' class="minion-manager-targets">${label2}</p>
<p style='text-align:center;'>${game.i18n.localize("MINIONMANAGER.Dialogs.OverkillDamage.Label3")}</p>
`,
"rejectClose": false,
render: (html) => {
targetingHookId = Hooks.on("targetToken", () => {
html.find(".minion-manager-targets").text(game.i18n.format("MINIONMANAGER.Dialogs.OverkillDamage.Label2", {
max_targets: maxAdditionalTargets + 1,
total_targets: game.user.targets.size
}))
})
},
options: { top: 150 }
});

Expand All @@ -127,7 +151,12 @@ export function initializeMinions() {

userTargets.delete(hitTarget);

[...userTargets].slice(0, maxAdditionalTargets).forEach(target => workflow.hitTargets.add(target));
await MidiQOL.applyTokenDamage(
workflow.damageDetail,
workflow.damageTotal,
new Set([...userTargets].slice(0, maxAdditionalTargets)),
workflow.item
)

return true;

Expand Down

0 comments on commit 0d0257f

Please sign in to comment.