Nouvelles corrections sur la fiche
This commit is contained in:
@@ -105,6 +105,9 @@
|
||||
"AWEMMY.Weapon.Damage": "Damage",
|
||||
"AWEMMY.Weapon.DamageType": "Damage Type",
|
||||
"AWEMMY.Weapon.AttackAttribute": "Attack Attribute",
|
||||
"AWEMMY.Weapon.AttackRoll": "Attack Roll",
|
||||
"AWEMMY.Weapon.Hit": "Hit",
|
||||
"AWEMMY.Weapon.CriticalHit": "Critical Hit!",
|
||||
"AWEMMY.Field.KeyAttribute": "Key Attribute",
|
||||
"AWEMMY.Field.KeyAttribute2": "Secondary Key Attribute",
|
||||
"AWEMMY.Field.Specializations": "Specializations",
|
||||
|
||||
@@ -19,7 +19,8 @@ export default class AwECharacterSheet extends AwEActorSheet {
|
||||
createEquipment: AwECharacterSheet.#onCreateEquipment,
|
||||
flowPointsPlus: AwECharacterSheet.#onFlowPointsPlus,
|
||||
flowPointsMinus: AwECharacterSheet.#onFlowPointsMinus,
|
||||
rollField: AwECharacterSheet.#onRollField
|
||||
rollField: AwECharacterSheet.#onRollField,
|
||||
rollWeapon: AwECharacterSheet.#onRollWeapon
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,6 +241,13 @@ export default class AwECharacterSheet extends AwEActorSheet {
|
||||
})
|
||||
}
|
||||
|
||||
static async #onRollWeapon(event, target) {
|
||||
const itemId = target.closest("[data-item-id]")?.dataset.itemId
|
||||
const item = this.document.items.get(itemId)
|
||||
if (!item) return
|
||||
await this.document.rollWeapon(item)
|
||||
}
|
||||
|
||||
/** Slugify a string for loose name matching (lowercase, trim, spaces→dash, strip non-alphanum). */
|
||||
static #slugify(str) {
|
||||
return (str ?? "").toLowerCase().trim().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "")
|
||||
|
||||
@@ -32,6 +32,38 @@ export default class AwEActor extends Actor {
|
||||
if (actorData.type !== "creature") return
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll a weapon attack: attack roll + damage if hit.
|
||||
* @param {Item} weaponItem - The weapon item being used.
|
||||
* @param {object} options - Additional roll options.
|
||||
* @returns {Promise<AwERoll|null>} The evaluated roll, or null if cancelled.
|
||||
*/
|
||||
async rollWeapon(weaponItem, options = {}) {
|
||||
const attrId = weaponItem.system.attackAttribute
|
||||
const attribute = this.system.attributes[attrId]
|
||||
if (!attribute) return null
|
||||
|
||||
const knowledgeBonuses = this.itemTypes.field?.map(f => ({
|
||||
label: f.name,
|
||||
bonus: f.system.knowledgeBonus ?? ""
|
||||
})).filter(f => f.bonus !== "") ?? []
|
||||
|
||||
return AwERoll.prompt({
|
||||
attributeKey: attrId,
|
||||
modifier: attribute.mod ?? 0,
|
||||
attributeBonus: attribute.bonus ?? 0,
|
||||
knowledgeBonuses,
|
||||
actorId: this.id,
|
||||
actorName: this.name,
|
||||
actorImage: this.img,
|
||||
sourceItemName: weaponItem.name,
|
||||
sourceItemImg: weaponItem.img,
|
||||
damageFormula: weaponItem.system.damageFormula,
|
||||
damageType: weaponItem.system.damageType,
|
||||
...options
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll an attribute check.
|
||||
* @param {string} attributeId - The attribute to roll.
|
||||
|
||||
@@ -19,6 +19,10 @@ export default class AwERoll extends Roll {
|
||||
get actorImage() { return this.options.actorImage }
|
||||
get sourceItemName() { return this.options.sourceItemName }
|
||||
get sourceItemImg() { return this.options.sourceItemImg }
|
||||
get damageFormula() { return this.options.damageFormula }
|
||||
get damageType() { return this.options.damageType }
|
||||
get damageResult() { return this.options.damageResult }
|
||||
get damageCritical() { return this.options.damageCritical ?? false }
|
||||
|
||||
// --- Outcome calculation ---
|
||||
|
||||
@@ -170,6 +174,23 @@ export default class AwERoll extends Roll {
|
||||
roll.options.outcome = AwERoll.computeOutcome(roll.total, dc, d20Value)
|
||||
}
|
||||
|
||||
// If this is a weapon attack and it hit, roll damage
|
||||
if (options.damageFormula && roll.options.outcome) {
|
||||
const isHit = roll.options.outcome === "success" || roll.options.outcome === "criticalSuccess"
|
||||
const isCrit = roll.options.outcome === "criticalSuccess"
|
||||
if (isHit) {
|
||||
// Double the dice count on critical success
|
||||
const formula = isCrit
|
||||
? options.damageFormula.replace(/(\d+)d(\d+)/gi, (_, n, d) => `${Number(n) * 2}d${d}`)
|
||||
: options.damageFormula
|
||||
const dmgRoll = new Roll(formula)
|
||||
await dmgRoll.evaluate()
|
||||
roll.options.damageResult = dmgRoll.total
|
||||
roll.options.damageCritical = isCrit
|
||||
roll.options.damageType = options.damageType
|
||||
}
|
||||
}
|
||||
|
||||
await roll.toMessage({
|
||||
speaker: ChatMessage.getSpeaker({ actor: game.actors.get(options.actorId) }),
|
||||
flavor: attrLabel,
|
||||
@@ -197,6 +218,9 @@ export default class AwERoll extends Roll {
|
||||
actorImage: this.actorImage,
|
||||
sourceItemName: this.sourceItemName,
|
||||
sourceItemImg: this.sourceItemImg,
|
||||
damageResult: isPrivate ? null : this.damageResult,
|
||||
damageCritical: this.damageCritical,
|
||||
damageType: this.damageType,
|
||||
isPrivate
|
||||
}
|
||||
)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
<div class="item-damage">{{item.system.damageFormula}} ({{item.system.damageType}})</div>
|
||||
<div class="item-range">{{localize "AWEMMY.Weapon.Range"}}: {{item.system.range}}</div>
|
||||
<div class="item-controls">
|
||||
<a data-action="rollWeapon" data-item-id="{{item.id}}" data-tooltip="{{localize "AWEMMY.Weapon.AttackRoll"}}"><i class="fas fa-dice-d20"></i></a>
|
||||
<a data-action="edit" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}"><i class="fas fa-edit"></i></a>
|
||||
{{#if ../isEditMode}}
|
||||
<a data-action="delete" data-item-id="{{item.id}}" data-item-uuid="{{item.uuid}}"><i class="fas fa-trash"></i></a>
|
||||
|
||||
@@ -65,6 +65,21 @@
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{!-- Weapon damage (only on a successful attack with a DC) --}}
|
||||
{{#if damageResult}}
|
||||
<div class="chat-damage {{#if damageCritical}}critical{{/if}}">
|
||||
<span class="damage-label">
|
||||
{{#if damageCritical}}
|
||||
<i class="fa-solid fa-explosion"></i> {{localize "AWEMMY.Weapon.CriticalHit"}}
|
||||
{{else}}
|
||||
<i class="fa-solid fa-burst"></i> {{localize "AWEMMY.Weapon.Hit"}}
|
||||
{{/if}}
|
||||
</span>
|
||||
<span class="damage-value">{{damageResult}}</span>
|
||||
{{#if damageType}}<span class="damage-type">({{damageType}})</span>{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{else}}
|
||||
<div class="private-result">
|
||||
<i class="fa-solid fa-eye-slash"></i> {{localize "AWEMMY.Roll.Private"}}
|
||||
|
||||
Reference in New Issue
Block a user