fix(combat): prevent double dice rolls in handleAttackBoosted
Release Creation / build (release) Successful in 52s
Release Creation / build (release) Successful in 52s
When a GM-owned attacker attacks a player character, both the createChatMessage hook and handleAttackBoosted ran on the player's client — rolling D30 bonus dice, grit, luck, shield, and mulligan dice twice. Now handleAttackBoosted early-returns when the attacker is not cross-client (GM-owned), leaving the hook as the sole handler.
This commit is contained in:
@@ -105,8 +105,24 @@ export async function handleAttackBoosted(msg) {
|
||||
} = msg
|
||||
|
||||
const defender = game.actors.get(defenderId)
|
||||
const attacker = game.actors.get(attackerId)
|
||||
if (!defender) return
|
||||
|
||||
// When the attacker is GM-owned (not a PC on another client), the createChatMessage
|
||||
// hook on the defender's client already handles everything: D30 bonus dice, defense
|
||||
// reaction dialog (grit/luck/shield/mulligan), and the comparison message. Running
|
||||
// handleAttackBoosted too would double-roll all dice and show duplicate dialogs.
|
||||
// Only proceed when the hook is suppressed (attacker is a PC on another client).
|
||||
const attackerHasNonGMOwner = attacker && game.users.some(u => u.active && !u.isGM && attacker.testUserPermission(u, "OWNER"))
|
||||
const _isPrimaryController = actor => {
|
||||
if (!actor) return false
|
||||
const activePlayerOwners = game.users.filter(u => u.active && !u.isGM && actor.testUserPermission(u, "OWNER"))
|
||||
if (activePlayerOwners.length > 0) return activePlayerOwners[0].id === game.user.id
|
||||
return game.user.isGM
|
||||
}
|
||||
const attackerIsCrossClient = attackerHasNonGMOwner && !_isPrimaryController(attacker)
|
||||
if (!attackerIsCrossClient) return
|
||||
|
||||
let updatedDefenseRoll = defenseRoll
|
||||
let shieldBlocked = false
|
||||
let shieldReaction = null
|
||||
|
||||
Reference in New Issue
Block a user