Skip to content

Commit

Permalink
Make Advantage automation v10 compatible
Browse files Browse the repository at this point in the history
- Handle outmanoeuvring and winning opposed tests
- Move Advantage flagging to combatant
- Set flag for charging, winning and opposed tests
- Update socket handling
  • Loading branch information
Jagusti committed Aug 19, 2022
1 parent f27889e commit fb83fb7
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 52 deletions.
96 changes: 50 additions & 46 deletions modules/advantage.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default class Advantage {
* Entry point for adjustments to Advantage through .
* @param {Object} character : Token
* @param {string} adjustment : increase (+1), clear (=0), reduce (-1)
* // TODO: add support for numeric adjustment values
* @param {string} context : macro, wfrp4e:opposedTestResult, wfrp4e:applyDamage, createCombatant, preDeleteCombatant, createActiveEffect, loseMomentum
* @returns {Array} update : outcome (String: increased, reduced, min, max, reset, no change),
* starting (Number: what the character's Advantage was at the start of the routine)
Expand All @@ -18,7 +19,7 @@ export default class Advantage {
if (adjustment === null) return // ... no adjustment set
if (
(character === undefined) // ... no character set
|| (character?.document?.documentName !== "Token") // ... not a Token
|| (character?.document?.documentName !== "Token") // ... not a Token.
|| (context === "macro" && canvas.tokens.controlled.length !== 1) // ... only one Token is not selected when using the macros
) {
return ui.notifications.error(game.i18n.localize("GMTOOLKIT.Token.SingleSelect"), { console: true })
Expand All @@ -29,14 +30,7 @@ export default class Advantage {
}

// Gather key character info into a single convenient object
const characterInfo = {
name: character.name,
linked: character.document.actorLink,
inCombat: character.inCombat,
flags: character.document.flags,
combatant: character.combatant,
combatantFlags: character.combatant?.flags
}
const characterInfo = { name: character.name }
characterInfo.advantage = {
personal: {
current: character.actor.status.advantage.value,
Expand All @@ -52,15 +46,15 @@ export default class Advantage {
// Make the adjustment to the token actor and capture the outcome
const updatedAdvantage = await this.adjust(
character,
characterInfo.advantage.personal, // _ resourceBase,
characterInfo.advantage.personal,
adjustment
)

// Report the outcome to the user
const update = await this.report(
updatedAdvantage,
character,
characterInfo.advantage.personal, // _ resourceBase,
characterInfo.advantage.personal,
context
)
update.outcome = updatedAdvantage.outcome
Expand Down Expand Up @@ -176,10 +170,14 @@ export default class Advantage {
return update
}

// Clears flags set for increasing token Advantage during combat
/**
* Clears combatant flags set for increasing token Advantage during combat.
* @param {Array} advantaged : Array of Combatant
* @param {boolean} startOfRound : Unset sorAdvantage flag at end of round
**/
static unsetFlags (advantaged, startOfRound = false) {
advantaged.filter(a => a.token.actor.unsetFlag("wfrp4e-gm-toolkit", "advantage"))
if (startOfRound) advantaged.filter(a => a.token.actor.unsetFlag("wfrp4e-gm-toolkit", "sorAdvantage"))
advantaged.filter(c => c.unsetFlag("wfrp4e-gm-toolkit", "advantage"))
if (startOfRound) advantaged.filter(c => c.unsetFlag("wfrp4e-gm-toolkit", "sorAdvantage"))
GMToolkit.log(false, "Advantage Flags: Unset.")
}

Expand Down Expand Up @@ -291,20 +289,24 @@ Hooks.on("wfrp4e:applyDamage", async function (scriptArgs) {

// Clear advantage on actor that has taken damage when not using Group Advantage
if (!game.settings.get("wfrp4e", "useGroupAdvantage")) {
const character = scriptArgs.actor.data.token
const character = Array.from(game.combats.active.combatants)
.filter(c => c.actor === scriptArgs.actor)[0]
.token.object
await Advantage.update(character, "clear", "wfrp4e:applyDamage" )
}

// Increase advantage on actor that dealt damage, as long as it has not already been updated for this test
const character = scriptArgs.attacker.data.token
if (character.document.getFlag(GMToolkit.MODULE_ID, "advantage")?.outmanoeuvre !== scriptArgs.opposedTest.attackerTest.message.id) {
const character = Array.from(game.combats.active.combatants)
.filter(c => c.actor === scriptArgs.attacker)[0]
.token.object
if (character.combatant.getFlag(GMToolkit.MODULE_ID, "advantage")?.outmanoeuvre !== scriptArgs.opposedTest.attackerTest.message.id) {
await Advantage.update(character, "increase", "wfrp4e:applyDamage")

if (!character.actor.ownership[game.user.id]) {
await game.socket.emit(`module.${GMToolkit.MODULE_ID}`, {
type: "setFlag",
payload: {
character: character,
character: character.combatant,
updateData: {
flag: "advantage",
key: "outmanoeuvre",
Expand All @@ -313,7 +315,7 @@ Hooks.on("wfrp4e:applyDamage", async function (scriptArgs) {
}
})
} else {
await character.document.setFlag(GMToolkit.MODULE_ID, "advantage", { outmanoeuvre: scriptArgs.opposedTest.attackerTest.message.id })
await character.combatant.setFlag(GMToolkit.MODULE_ID, "advantage", { outmanoeuvre: scriptArgs.opposedTest.attackerTest.message.id })
}

} else {
Expand All @@ -335,7 +337,8 @@ Hooks.on("wfrp4e:opposedTestResult", async function (opposedTest, attackerTest,
await game.socket.emit(`module.${GMToolkit.MODULE_ID}`, {
type: "setFlag",
payload: {
character: opposedTest.attacker.data.token,
character: Array.from(game.combats.active.combatants)
.filter(c => c.actor === opposedTest.attacker)[0],
updateData: {
flag: "advantage",
key: "charging",
Expand All @@ -344,7 +347,9 @@ Hooks.on("wfrp4e:opposedTestResult", async function (opposedTest, attackerTest,
}
})
} else {
await opposedTest.attacker.setFlag(GMToolkit.MODULE_ID, "advantage", { charging: opposedTest.attackerTest.message.id })
await Array.from(game.combats.active.combatants)
.filter(c => c.actor === opposedTest.attacker)[0]
.setFlag(GMToolkit.MODULE_ID, "advantage", { charging: opposedTest.attackerTest.message.id })
}
}
// Flag defender charging
Expand All @@ -353,7 +358,8 @@ Hooks.on("wfrp4e:opposedTestResult", async function (opposedTest, attackerTest,
await game.socket.emit(`module.${GMToolkit.MODULE_ID}`, {
type: "setFlag",
payload: {
character: opposedTest.defender.data.token,
character: Array.from(game.combats.active.combatants)
.filter(c => c.actor === opposedTest.defender)[0],
updateData: {
flag: "advantage",
key: "charging",
Expand All @@ -362,11 +368,14 @@ Hooks.on("wfrp4e:opposedTestResult", async function (opposedTest, attackerTest,
}
})
} else {
await opposedTest.defender.setFlag(GMToolkit.MODULE_ID, "advantage", { charging: opposedTest.attackerTest.message.id })
await Array.from(game.combats.active.combatants)
.filter(c => c.actor === opposedTest.defender)[0]
.setFlag(GMToolkit.MODULE_ID, "advantage", { charging: opposedTest.attackerTest.message.id })
}
}
} // END: Flag for CHARGING

// WINNING: Update Advantage for Opposed Tests
if (defenderTest.context.unopposed) return // Unopposed Test. Advantage from outmanouevring is handled if damage is applied (on wfrp4e:applyDamage hook)
if (!game.settings.get(GMToolkit.MODULE_ID, "automateOpposedTestAdvantage")) return

Expand All @@ -384,22 +393,26 @@ Hooks.on("wfrp4e:opposedTestResult", async function (opposedTest, attackerTest,

if (game.user.isGM) {ui.notifications.notify(message, type, options)}

// Clear advantage on actor that has lost opposed test when not using Group Advantage
// Clear advantage on actor token that has lost opposed test when not using Group Advantage
if (!game.settings.get("wfrp4e", "useGroupAdvantage")) {
const character = loser.data.token
const character = Array.from(game.combats.active.combatants)
.filter(c => c.actor === loser)[0]
.token.object
await Advantage.update(character, "clear", "wfrp4e:opposedTestResult" )
}

// Increase advantage on actor that has won opposed test, as long as it has not already been updated for this test.
const character = winner.data.token
if (character.document.getFlag(GMToolkit.MODULE_ID, "advantage")?.opposed !== opposedTest.attackerTest.message.id) {
// Increase advantage on actor token that has won opposed test, as long as it has not already been updated for this test.
const character = Array.from(game.combats.active.combatants)
.filter(c => c.actor === winner)[0]
.token.object
if (character.combatant.getFlag(GMToolkit.MODULE_ID, "advantage")?.opposed !== opposedTest.attackerTest.message.id) {
await Advantage.update(character, "increase", "wfrp4e:opposedTestResult")

if (!character.actor.ownership[game.user.id]) {
if (!winner.ownership[game.user.id]) {
await game.socket.emit(`module.${GMToolkit.MODULE_ID}`, {
type: "setFlag",
payload: {
character: character,
character: character.combatant,
updateData: {
flag: "advantage",
key: "opposed",
Expand All @@ -408,9 +421,11 @@ Hooks.on("wfrp4e:opposedTestResult", async function (opposedTest, attackerTest,
}
})
} else {
await character.document.setFlag(GMToolkit.MODULE_ID, "advantage", { opposed: opposedTest.attackerTest.message.id })
await character.combatant
.setFlag(GMToolkit.MODULE_ID, "advantage",
{ opposed: opposedTest.attackerTest.message.id }
)
}
// Console.log(character, character.document.getFlag(GMToolkit.MODULE_ID, 'advantage'))
} else {
console.log(`Advantage increase already applied to ${character.name} for winning opposed test.`)
}
Expand Down Expand Up @@ -465,7 +480,6 @@ Hooks.on("deleteCombatant", function (combatant) {
const token = canvas.tokens.placeables
.filter(a => a.id === combatant.tokenId)[0]
Advantage.update(token, "clear", "deleteCombatant")
Advantage.unsetFlags([combatant], true)
}
})

Expand All @@ -490,7 +504,7 @@ Hooks.on("preUpdateCombat", async function (combat, change) {
// Clear Advantage flags when the combat round changes
// Still required when Group Advantage is used because of Opposed Test flags
console.log("preUpdateCombat: unsetting Advantage flags")
const advFlagged = combat.combatants.filter(a => a.token.actor.getFlag("wfrp4e-gm-toolkit", "advantage"))
const advFlagged = combat.combatants.filter(c => c.getFlag("wfrp4e-gm-toolkit", "advantage"))
if (advFlagged.length) await Advantage.unsetFlags(advFlagged)
})

Expand All @@ -503,18 +517,8 @@ Hooks.on("updateCombat", async function (combat, change) {
// Skip individual start of round Advantage tracking if Group Advantage is being used
if (combat.turns && combat.isActive && !game.settings.get("wfrp4e", "useGroupAdvantage")) {
combat.combatants.forEach(async c => {
await c.token.actor.setFlag("wfrp4e-gm-toolkit", "sorAdvantage", c.token.actor.data.data.status?.advantage?.value ?? 0)
GMToolkit.log(false, `${c.name}: ${c.token.actor.getFlag("wfrp4e-gm-toolkit", "sorAdvantage")}`)
await c.setFlag("wfrp4e-gm-toolkit", "sorAdvantage", c.token.actor.system.status?.advantage?.value ?? 0)
GMToolkit.log(false, `${c.name}: ${c.getFlag("wfrp4e-gm-toolkit", "sorAdvantage")}`)
})
}
})


Hooks.on("preDeleteCombat", async function (combat) {
GMToolkit.log(false, "preDeleteCombat: clear Advantage flags")
if (!game.user.isUniqueGM || !combat.combatants.size) return
const advFlagged = combat.combatants.filter(a => a.token.actor.getFlag("wfrp4e-gm-toolkit", "advantage"))
if (advFlagged.length) await Advantage.unsetFlags(advFlagged)
await Advantage.unsetFlags(combat.combatants, true)
})

12 changes: 6 additions & 6 deletions wfrp4e-gm-toolkit.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -136,19 +136,19 @@ export class SocketHandlers {
.update(data.payload.updateData)
}

// Used for updating Advantage flags when the opposed test is resolved by a player character that does not own the opposing character
// Used for updating Advantage flags on combatant when the opposed test is resolved by a player character that does not own the opposing actor
static async setFlag (data) {
console.log("Socket: setFlag", data)
if (!game.user.isUniqueGM) return
ui.notifications.notify(`Setting flag "${data.payload.updateData.key}" on ${data.payload.character.name} as GM`, "info", { permanent: true })
ui.notifications.notify(`Setting flag "${data.payload.updateData.key}" on ${data.payload.character.name} as GM`, "info", { permanent: true, console: true })

const { character } = data.payload
const { character } = data.payload // This should be a Combatant

const actorToChange = game.scenes.active.tokens
.filter(t => t.actor.id === character.actorId)[0].actor
// const actorToChange = game.scenes.active.tokens
// .filter(t => t.actor.id === character.actorId)[0].actor

let updated = ""
return updated = await actorToChange.setFlag(
return updated = await character.setFlag(
GMToolkit.MODULE_ID,
data.payload.updateData.flag,
{ [data.payload.updateData.key]: data.payload.updateData.value }
Expand Down

0 comments on commit fb83fb7

Please sign in to comment.