Add ranged attacks for monsters
This commit is contained in:
@@ -1,148 +1,283 @@
|
||||
{
|
||||
"d30_dice_results": {
|
||||
"30": {
|
||||
"melee_attack": "Possible Lethal or Vital Strike or Add D20E to Attack",
|
||||
"ranged_attack": "Possible Lethal or Vital Strike or Add D20E to Attack",
|
||||
"melee_defense": "Possible Flawless or Legendary Defense or Add D20E to Defense",
|
||||
"arcane_spell_attack": "Possible Lethal or Vital Magical Strike or Add D20E to Spell Attack",
|
||||
"arcane_spell_defense": "Possible Spell Catastrophe or adds D20E to Spell Defense",
|
||||
"skill_rolls": "Skill Succeeds Regardless of Opposing Roll"
|
||||
"melee_attack": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "special_strike", "options": ["lethal", "vital"] },
|
||||
{ "type": "bonus_dice", "dice": "D20E", "target": "attack" }
|
||||
],
|
||||
"description": "Possible Lethal or Vital Strike or Add D20E to Attack"
|
||||
},
|
||||
"ranged_attack": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "special_strike", "options": ["lethal", "vital"] },
|
||||
{ "type": "bonus_dice", "dice": "D20E", "target": "attack" }
|
||||
],
|
||||
"description": "Possible Lethal or Vital Strike or Add D20E to Attack"
|
||||
},
|
||||
"melee_defense": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "special_defense", "options": ["flawless", "legendary"] },
|
||||
{ "type": "bonus_dice", "dice": "D20E", "target": "defense" }
|
||||
],
|
||||
"description": "Possible Flawless or Legendary Defense or Add D20E to Defense"
|
||||
},
|
||||
"arcane_spell_attack": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "special_strike", "options": ["lethal_magical", "vital_magical"] },
|
||||
{ "type": "bonus_dice", "dice": "D20E", "target": "spell_attack" }
|
||||
],
|
||||
"description": "Possible Lethal or Vital Magical Strike or Add D20E to Spell Attack"
|
||||
},
|
||||
"arcane_spell_defense": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "spell_calamity" },
|
||||
{ "type": "bonus_dice", "dice": "D20E", "target": "spell_defense" }
|
||||
],
|
||||
"description": "Possible Spell Catastrophe or adds D20E to Spell Defense"
|
||||
},
|
||||
"skill_rolls": {
|
||||
"type": "skill_auto_success",
|
||||
"description": "Skill Succeeds Regardless of Opposing Roll"
|
||||
}
|
||||
},
|
||||
"29": {
|
||||
"melee_attack": "Gain 1 Grit",
|
||||
"ranged_attack": "Gain 1 Grit",
|
||||
"melee_defense": "Gain 1 Grit",
|
||||
"arcane_spell_attack": "Gain 1 Grit",
|
||||
"arcane_spell_defense": "Gain 1 Grit",
|
||||
"skill_rolls": "Gain 1 Grit"
|
||||
"melee_attack": { "type": "gain_grit", "amount": 1, "description": "Gain 1 Grit" },
|
||||
"ranged_attack": { "type": "gain_grit", "amount": 1, "description": "Gain 1 Grit" },
|
||||
"melee_defense": { "type": "gain_grit", "amount": 1, "description": "Gain 1 Grit" },
|
||||
"arcane_spell_attack": { "type": "gain_grit", "amount": 1, "description": "Gain 1 Grit" },
|
||||
"arcane_spell_defense": { "type": "gain_grit", "amount": 1, "description": "Gain 1 Grit" },
|
||||
"skill_rolls": { "type": "gain_grit", "amount": 1, "description": "Gain 1 Grit" }
|
||||
},
|
||||
"28": {
|
||||
"melee_attack": "Shield Destruction",
|
||||
"ranged_attack": "empty",
|
||||
"melee_defense": "empty",
|
||||
"arcane_spell_attack": "empty",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "empty"
|
||||
"melee_attack": { "type": "shield_destruction", "description": "Shield Destruction" }
|
||||
},
|
||||
"27": {
|
||||
"melee_attack": "Granted D6 (1-6) Attack Modifier for This Melee Attack",
|
||||
"ranged_attack": "Granted D6 (1-6) Attack Modifier for This Ranged Attack",
|
||||
"melee_defense": "Granted 1 Luck dice for Use in This Combat Only",
|
||||
"arcane_spell_attack": "No Spell Lethargy the Aether Approves of Characters Efforts",
|
||||
"arcane_spell_defense": "Caster Suffers Severe pain and will be under a flash of pain for 1D6E seconds",
|
||||
"skill_rolls": "empty"
|
||||
"melee_attack": {
|
||||
"type": "bonus_dice", "dice": "D6", "target": "attack",
|
||||
"description": "Granted D6 (1-6) Attack Modifier for This Melee Attack"
|
||||
},
|
||||
"ranged_attack": {
|
||||
"type": "bonus_dice", "dice": "D6", "target": "attack",
|
||||
"description": "Granted D6 (1-6) Attack Modifier for This Ranged Attack"
|
||||
},
|
||||
"melee_defense": {
|
||||
"type": "luck_die", "scope": "combat",
|
||||
"description": "Granted 1 Luck dice for Use in This Combat Only"
|
||||
},
|
||||
"arcane_spell_attack": {
|
||||
"type": "no_lethargy",
|
||||
"description": "No Spell Lethargy the Aether Approves of Characters Efforts"
|
||||
},
|
||||
"arcane_spell_defense": {
|
||||
"type": "flash_of_pain", "duration_dice": "1D6E", "target": "caster",
|
||||
"description": "Caster Suffers Severe pain and will be under a flash of pain for 1D6E seconds"
|
||||
}
|
||||
},
|
||||
"26": {
|
||||
"melee_attack": "Shield Destruction",
|
||||
"ranged_attack": "empty",
|
||||
"melee_defense": "empty",
|
||||
"arcane_spell_attack": "empty",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "empty"
|
||||
"melee_attack": { "type": "shield_destruction", "description": "Shield Destruction" }
|
||||
},
|
||||
"25": {
|
||||
"melee_attack": "empty",
|
||||
"ranged_attack": "empty",
|
||||
"melee_defense": "empty",
|
||||
"arcane_spell_attack": "empty",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "Add 1 to Skill Roll"
|
||||
"skill_rolls": {
|
||||
"type": "bonus_flat", "amount": 1, "target": "skill",
|
||||
"description": "Add 1 to Skill Roll"
|
||||
}
|
||||
},
|
||||
"21": {
|
||||
"melee_attack": "Hit Inflicts Flash of Pain 1D6E seconds",
|
||||
"ranged_attack": "Hit Inflicts Flash of Pain 1D6E seconds",
|
||||
"melee_defense": "Defender Recovers or ignores any flash of pain",
|
||||
"arcane_spell_attack": "Magical Damage inflicts Flash of pain 1D6E seconds",
|
||||
"arcane_spell_defense": "Caster Suffers Severe pain and will be under a flash of pain for 1D6E seconds",
|
||||
"skill_rolls": "Granted D6 (1-6) Skill Modifier for this Skill Attempt"
|
||||
"melee_attack": {
|
||||
"type": "flash_of_pain", "duration_dice": "1D6E", "target": "defender",
|
||||
"description": "Hit Inflicts Flash of Pain 1D6E seconds"
|
||||
},
|
||||
"ranged_attack": {
|
||||
"type": "flash_of_pain", "duration_dice": "1D6E", "target": "defender",
|
||||
"description": "Hit Inflicts Flash of Pain 1D6E seconds"
|
||||
},
|
||||
"melee_defense": {
|
||||
"type": "recover_pain",
|
||||
"description": "Defender Recovers or ignores any flash of pain"
|
||||
},
|
||||
"arcane_spell_attack": {
|
||||
"type": "flash_of_pain", "duration_dice": "1D6E", "target": "defender",
|
||||
"description": "Magical Damage inflicts Flash of pain 1D6E seconds"
|
||||
},
|
||||
"arcane_spell_defense": {
|
||||
"type": "flash_of_pain", "duration_dice": "1D6E", "target": "caster",
|
||||
"description": "Caster Suffers Severe pain and will be under a flash of pain for 1D6E seconds"
|
||||
},
|
||||
"skill_rolls": {
|
||||
"type": "bonus_dice", "dice": "D6", "target": "skill",
|
||||
"description": "Granted D6 (1-6) Skill Modifier for this Skill Attempt"
|
||||
}
|
||||
},
|
||||
"20": {
|
||||
"melee_attack": "Possible Vicious Strike or Add D12 to attack",
|
||||
"ranged_attack": "Possible Vicious Strike or add D12 to attack",
|
||||
"melee_defense": "Possible 20/20 defense that avoids Any Attack Except a Lethal Strike or adds D12 to defense",
|
||||
"arcane_spell_attack": "Possible Vicious Application of a Magical Attack or add D12 to attack",
|
||||
"arcane_spell_defense": "Possible 20/20 Spell defense that Saves Against Any Magical Attack Except a Lethal Magical Strike or add D12 to defense",
|
||||
"skill_rolls": "20 Added to Skill Roll"
|
||||
"melee_attack": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "special_strike", "options": ["vicious"] },
|
||||
{ "type": "bonus_dice", "dice": "D12", "target": "attack" }
|
||||
],
|
||||
"description": "Possible Vicious Strike or Add D12 to attack"
|
||||
},
|
||||
"ranged_attack": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "special_strike", "options": ["vicious"] },
|
||||
{ "type": "bonus_dice", "dice": "D12", "target": "attack" }
|
||||
],
|
||||
"description": "Possible Vicious Strike or add D12 to attack"
|
||||
},
|
||||
"melee_defense": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "special_defense", "options": ["perfect"] },
|
||||
{ "type": "bonus_dice", "dice": "D12", "target": "defense" }
|
||||
],
|
||||
"description": "Possible 20/20 defense that avoids Any Attack Except a Lethal Strike or adds D12 to defense"
|
||||
},
|
||||
"arcane_spell_attack": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "special_strike", "options": ["vicious_magical"] },
|
||||
{ "type": "bonus_dice", "dice": "D12", "target": "spell_attack" }
|
||||
],
|
||||
"description": "Possible Vicious Application of a Magical Attack or add D12 to attack"
|
||||
},
|
||||
"arcane_spell_defense": {
|
||||
"type": "choice",
|
||||
"choices": [
|
||||
{ "type": "special_defense", "options": ["perfect_spell"] },
|
||||
{ "type": "bonus_dice", "dice": "D12", "target": "spell_defense" }
|
||||
],
|
||||
"description": "Possible 20/20 Spell defense that Saves Against Any Magical Attack Except a Lethal Magical Strike or add D12 to defense"
|
||||
},
|
||||
"skill_rolls": {
|
||||
"type": "bonus_flat", "amount": 20, "target": "skill",
|
||||
"description": "20 Added to Skill Roll"
|
||||
}
|
||||
},
|
||||
"15": {
|
||||
"melee_attack": "Bleed, Knock-back on Hit",
|
||||
"ranged_attack": "Bleed",
|
||||
"melee_defense": "Kick, Punch or Shield Bash",
|
||||
"arcane_spell_attack": "empty",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "Add 1 to Skill Roll"
|
||||
},
|
||||
"13": {
|
||||
"melee_attack": "empty",
|
||||
"ranged_attack": "empty",
|
||||
"melee_defense": "empty",
|
||||
"arcane_spell_attack": "empty",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "empty"
|
||||
"melee_attack": {
|
||||
"type": "combo",
|
||||
"effects": [
|
||||
{ "type": "bleed" },
|
||||
{ "type": "knockback" }
|
||||
],
|
||||
"description": "Bleed, Knock-back on Hit"
|
||||
},
|
||||
"ranged_attack": { "type": "bleed", "description": "Bleed" },
|
||||
"melee_defense": {
|
||||
"type": "counter_attack",
|
||||
"options": ["kick", "punch", "shield_bash"],
|
||||
"description": "Kick, Punch or Shield Bash"
|
||||
},
|
||||
"skill_rolls": {
|
||||
"type": "bonus_flat", "amount": 1, "target": "skill",
|
||||
"description": "Add 1 to Skill Roll"
|
||||
}
|
||||
},
|
||||
"13": {},
|
||||
"11": {
|
||||
"melee_attack": "Flurry Attack or Hit to Miss",
|
||||
"ranged_attack": "Roll 2x Damage Dice",
|
||||
"melee_defense": "empty",
|
||||
"arcane_spell_attack": "empty",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "empty"
|
||||
"melee_attack": {
|
||||
"type": "flurry", "condition": "hit_or_miss",
|
||||
"description": "Flurry Attack or Hit to Miss"
|
||||
},
|
||||
"ranged_attack": { "type": "double_damage_dice", "description": "Roll 2x Damage Dice" }
|
||||
},
|
||||
"10": {
|
||||
"melee_attack": "Bleed, Knock-back on Hit",
|
||||
"ranged_attack": "Bleed",
|
||||
"melee_defense": "Kick, Punch or Shield Bash",
|
||||
"arcane_spell_attack": "empty",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "Add 1 to Skill Roll"
|
||||
"melee_attack": {
|
||||
"type": "combo",
|
||||
"effects": [
|
||||
{ "type": "bleed" },
|
||||
{ "type": "knockback" }
|
||||
],
|
||||
"description": "Bleed, Knock-back on Hit"
|
||||
},
|
||||
"ranged_attack": { "type": "bleed", "description": "Bleed" },
|
||||
"melee_defense": {
|
||||
"type": "counter_attack",
|
||||
"options": ["kick", "punch", "shield_bash"],
|
||||
"description": "Kick, Punch or Shield Bash"
|
||||
},
|
||||
"skill_rolls": {
|
||||
"type": "bonus_flat", "amount": 1, "target": "skill",
|
||||
"description": "Add 1 to Skill Roll"
|
||||
}
|
||||
},
|
||||
"8": {
|
||||
"melee_attack": "Mulligan, Can Choose to Re-roll This Attack",
|
||||
"ranged_attack": "Mulligan, Can Choose to Re-Roll This Attack",
|
||||
"melee_defense": "Mulligan, Can Choose to Re-Roll This Defense",
|
||||
"arcane_spell_attack": "Mulligan, Can Re-Roll This Spell Attack",
|
||||
"arcane_spell_defense": "Mulligan, Can Re-Roll This Spell Defense",
|
||||
"skill_rolls": "Mulligan, Can Re-Roll This Skill roll"
|
||||
"melee_attack": { "type": "mulligan", "description": "Mulligan, Can Choose to Re-roll This Attack" },
|
||||
"ranged_attack": { "type": "mulligan", "description": "Mulligan, Can Choose to Re-Roll This Attack" },
|
||||
"melee_defense": { "type": "mulligan", "description": "Mulligan, Can Choose to Re-Roll This Defense" },
|
||||
"arcane_spell_attack": { "type": "mulligan", "description": "Mulligan, Can Re-Roll This Spell Attack" },
|
||||
"arcane_spell_defense": { "type": "mulligan", "description": "Mulligan, Can Re-Roll This Spell Defense" },
|
||||
"skill_rolls": { "type": "mulligan", "description": "Mulligan, Can Re-Roll This Skill roll" }
|
||||
},
|
||||
"7": {
|
||||
"melee_attack": "Flurry Attack on Hit or Miss",
|
||||
"ranged_attack": "Roll 2x Damage Dice",
|
||||
"melee_defense": "empty",
|
||||
"arcane_spell_attack": "empty",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "empty"
|
||||
"melee_attack": {
|
||||
"type": "flurry", "condition": "hit_or_miss",
|
||||
"description": "Flurry Attack on Hit or Miss"
|
||||
},
|
||||
"ranged_attack": { "type": "double_damage_dice", "description": "Roll 2x Damage Dice" }
|
||||
},
|
||||
"5": {
|
||||
"melee_attack": "Bleed, Knock-back on Hit",
|
||||
"ranged_attack": "Bleed",
|
||||
"melee_defense": "Kick, Punch, or Shield Bash",
|
||||
"arcane_spell_attack": "empty",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "Add 1 to Skill Roll"
|
||||
"melee_attack": {
|
||||
"type": "combo",
|
||||
"effects": [
|
||||
{ "type": "bleed" },
|
||||
{ "type": "knockback" }
|
||||
],
|
||||
"description": "Bleed, Knock-back on Hit"
|
||||
},
|
||||
"ranged_attack": { "type": "bleed", "description": "Bleed" },
|
||||
"melee_defense": {
|
||||
"type": "counter_attack",
|
||||
"options": ["kick", "punch", "shield_bash"],
|
||||
"description": "Kick, Punch, or Shield Bash"
|
||||
},
|
||||
"skill_rolls": {
|
||||
"type": "bonus_flat", "amount": 1, "target": "skill",
|
||||
"description": "Add 1 to Skill Roll"
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"melee_attack": "Triple Damage",
|
||||
"ranged_attack": "Triple Damage",
|
||||
"melee_defense": "DR Tripled including Shield",
|
||||
"arcane_spell_attack": "Triple Damage on Spell Damage",
|
||||
"arcane_spell_defense": "D12 Added to Spell Defense Modifier",
|
||||
"skill_rolls": "empty"
|
||||
"melee_attack": { "type": "damage_multiplier", "multiplier": 3, "description": "Triple Damage" },
|
||||
"ranged_attack": { "type": "damage_multiplier", "multiplier": 3, "description": "Triple Damage" },
|
||||
"melee_defense": {
|
||||
"type": "dr_multiplier", "multiplier": 3, "includes_shield": true,
|
||||
"description": "DR Tripled including Shield"
|
||||
},
|
||||
"arcane_spell_attack": { "type": "damage_multiplier", "multiplier": 3, "description": "Triple Damage on Spell Damage" },
|
||||
"arcane_spell_defense": {
|
||||
"type": "bonus_dice", "dice": "D12", "target": "spell_defense",
|
||||
"description": "D12 Added to Spell Defense Modifier"
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"melee_attack": "Double Damage",
|
||||
"ranged_attack": "Double Damage",
|
||||
"melee_defense": "DR Doubled including Shield",
|
||||
"arcane_spell_attack": "Double Damage on Spell Damage",
|
||||
"arcane_spell_defense": "D6 Added to Spell Defense Modifier",
|
||||
"skill_rolls": "empty"
|
||||
"melee_attack": { "type": "damage_multiplier", "multiplier": 2, "description": "Double Damage" },
|
||||
"ranged_attack": { "type": "damage_multiplier", "multiplier": 2, "description": "Double Damage" },
|
||||
"melee_defense": {
|
||||
"type": "dr_multiplier", "multiplier": 2, "includes_shield": true,
|
||||
"description": "DR Doubled including Shield"
|
||||
},
|
||||
"arcane_spell_attack": { "type": "damage_multiplier", "multiplier": 2, "description": "Double Damage on Spell Damage" },
|
||||
"arcane_spell_defense": {
|
||||
"type": "bonus_dice", "dice": "D6", "target": "spell_defense",
|
||||
"description": "D6 Added to Spell Defense Modifier"
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"melee_attack": "empty",
|
||||
"ranged_attack": "Possible Fumble Ranged ammo is broken unrecoverable",
|
||||
"melee_defense": "empty",
|
||||
"arcane_spell_attack": "Possible Spell Calamity or Catastrophe",
|
||||
"arcane_spell_defense": "empty",
|
||||
"skill_rolls": "empty"
|
||||
"ranged_attack": {
|
||||
"type": "fumble", "detail": "ranged_ammo_broken",
|
||||
"description": "Possible Fumble Ranged ammo is broken unrecoverable"
|
||||
},
|
||||
"arcane_spell_attack": {
|
||||
"type": "spell_calamity",
|
||||
"description": "Possible Spell Calamity or Catastrophe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
||||
@@ -47,11 +47,11 @@ export default class D30Roll {
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le résultat d'un jet de D30
|
||||
* Récupère le résultat d'un jet de D30 sous forme d'objet structuré.
|
||||
* @param {number} diceValue La valeur du dé (1-30)
|
||||
* @param {string} rollType Le type de jet externe (ex: "weapon-attack", "spell-attack", etc.)
|
||||
* @param {Object} weapon L'arme ou l'objet utilisé (optionnel, nécessaire pour certains types)
|
||||
* @returns {string|null} Le résultat correspondant ou null si vide/non trouvé
|
||||
* @returns {Object|null} L'objet effet `{ type, description, ...fields }` ou null si aucun effet
|
||||
*/
|
||||
static getResult(diceValue, rollType, weapon = null) {
|
||||
if (!this.resultsTable) {
|
||||
@@ -59,13 +59,11 @@ export default class D30Roll {
|
||||
return null
|
||||
}
|
||||
|
||||
// Validation des paramètres
|
||||
if (diceValue < 1 || diceValue > 30) {
|
||||
console.warn(`D30Roll | Invalid dice value: ${diceValue}. Must be between 1 and 30.`)
|
||||
return null
|
||||
}
|
||||
|
||||
// Convert external rollType to internal rollType
|
||||
const internalType = this.convertToInternalType(rollType, weapon)
|
||||
|
||||
if (!internalType) {
|
||||
@@ -85,13 +83,16 @@ export default class D30Roll {
|
||||
}
|
||||
|
||||
const result = resultEntry[internalType]
|
||||
return result ?? null
|
||||
}
|
||||
|
||||
// Retourne null si le résultat est "empty"
|
||||
if (result === "empty" || !result) {
|
||||
return null
|
||||
}
|
||||
|
||||
return result
|
||||
/**
|
||||
* Retourne le type d'effet d'un résultat D30.
|
||||
* @param {Object|null} result L'objet retourné par getResult()
|
||||
* @returns {string|null} Le type d'effet ou null
|
||||
*/
|
||||
static getEffectType(result) {
|
||||
return result?.type ?? null
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,11 +178,11 @@ export default class D30Roll {
|
||||
|
||||
/**
|
||||
* Vérifie si un résultat est vide
|
||||
* @param {string} result Le résultat à vérifier
|
||||
* @param {Object|null} result Le résultat à vérifier
|
||||
* @returns {boolean} True si le résultat est vide
|
||||
*/
|
||||
static isEmptyResult(result) {
|
||||
return !result || result === "empty"
|
||||
return !result || !result.type
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1105,6 +1105,7 @@ export default class LethalFantasyRoll extends Roll {
|
||||
// Merge rollContext object into options object
|
||||
options = { ...options, ...rollContext }
|
||||
options.rollName = "Ranged Defense"
|
||||
options.rollType = "weapon-defense"
|
||||
|
||||
const rollBase = new this(rollContext.movement, options.data, rollData)
|
||||
const rollModifier = new Roll(modifierFormula, options.data, rollData)
|
||||
@@ -1112,6 +1113,7 @@ export default class LethalFantasyRoll extends Roll {
|
||||
await rollBase.evaluate()
|
||||
let rollD30 = await new Roll("1D30").evaluate()
|
||||
options.D30result = rollD30.total
|
||||
options.D30message = D30Roll.getResult(rollD30.total, options.rollType, options.rollTarget?.weapon)
|
||||
|
||||
let badResult = 0
|
||||
if (rollContext.movement.includes("kh")) {
|
||||
@@ -1154,6 +1156,7 @@ export default class LethalFantasyRoll extends Roll {
|
||||
rollBase.options.rollTarget = options.rollTarget
|
||||
rollBase.options.titleFormula = `1D20E + ${modifierFormula}`
|
||||
rollBase.options.D30result = options.D30result
|
||||
rollBase.options.D30message = options.D30message
|
||||
rollBase.options.rollName = "Ranged Defense"
|
||||
rollBase.options.badResult = badResult
|
||||
rollBase.options.rollData = foundry.utils.duplicate(rollData)
|
||||
|
||||
@@ -127,6 +127,19 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
|
||||
attack2: attackField("2")
|
||||
})
|
||||
|
||||
schema.attackMode = new fields.StringField({
|
||||
required: true,
|
||||
nullable: false,
|
||||
initial: "melee",
|
||||
choices: { melee: "Melee", ranged: "Ranged" }
|
||||
})
|
||||
|
||||
schema.rangedAttacks = new fields.SchemaField({
|
||||
attack1: attackField("1"),
|
||||
attack2: attackField("2"),
|
||||
attack3: attackField("3"),
|
||||
attack4: attackField("4")
|
||||
})
|
||||
|
||||
return schema
|
||||
}
|
||||
@@ -165,14 +178,16 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
|
||||
switch (rollType) {
|
||||
case "monster-attack":
|
||||
case "monster-defense":
|
||||
case "monster-damage":
|
||||
rollTarget = foundry.utils.duplicate(this.attacks[rollKey])
|
||||
case "monster-damage": {
|
||||
const attacksSet = this.attackMode === "ranged" ? this.rangedAttacks : this.attacks
|
||||
rollTarget = foundry.utils.duplicate(attacksSet[rollKey])
|
||||
rollTarget.rollKey = rollKey
|
||||
// Si damageModifier est fourni (depuis le chat), l'utiliser au lieu de celui de la fiche
|
||||
if (damageModifier !== undefined && rollType === "monster-damage") {
|
||||
rollTarget.damageModifier = damageModifier
|
||||
}
|
||||
break
|
||||
}
|
||||
case "monster-attack-hth":
|
||||
case "monster-defense-hth":
|
||||
case "monster-damage-hth":
|
||||
@@ -304,8 +319,9 @@ export default class LethalFantasyMonster extends foundry.abstract.TypeDataModel
|
||||
}
|
||||
|
||||
let hasAttack = false
|
||||
for (let key in this.attacks) {
|
||||
let attack = this.attacks[key]
|
||||
const attacksSet = this.attackMode === "ranged" ? this.rangedAttacks : this.attacks
|
||||
for (let key in attacksSet) {
|
||||
let attack = attacksSet[key]
|
||||
if (attack.enabled && attack.attackScore > 0 && attack.attackScore === roll.total) {
|
||||
hasAttack = true
|
||||
const messageContent = await foundry.applications.handlebars.renderTemplate(
|
||||
|
||||
+3
-2
@@ -304,7 +304,8 @@ export default class LethalFantasyUtils {
|
||||
|
||||
// Pour les monstres, récupérer les attaques activées
|
||||
if (isMonster) {
|
||||
const enabledAttacks = Object.entries(defender.system.attacks).filter(([key, attack]) => attack.enabled)
|
||||
const attacksSet = defender.system.attackMode === "ranged" ? defender.system.rangedAttacks : defender.system.attacks
|
||||
const enabledAttacks = Object.entries(attacksSet).filter(([key, attack]) => attack.enabled)
|
||||
|
||||
if (enabledAttacks.length === 0) {
|
||||
ui.notifications.warn("No enabled attacks available for defense")
|
||||
@@ -448,7 +449,7 @@ export default class LethalFantasyUtils {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static hasD30Reroll(d30Message) {
|
||||
return /mulligan|re-?roll/i.test(d30Message || "")
|
||||
return d30Message?.type === "mulligan"
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
Reference in New Issue
Block a user