-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Apply damage to original attack target #368
Changes from 5 commits
7600edd
919788d
5615806
e651df8
4c51f92
36e610c
5576ec5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,21 @@ | ||
import { OseActor } from "./actor/entity"; | ||
|
||
function canApplyDamage(html: JQuery) { | ||
if (!html.find('.dice-total').length) return false; | ||
switch (game.settings.get(game.system.id, "applyDamageOption")) { | ||
case CONFIG.OSE.apply_damage_options.originalTarget: | ||
return !!html.find(".chat-target").last().data("id"); | ||
case CONFIG.OSE.apply_damage_options.targeted: | ||
return !!game.user?.targets?.size; | ||
case CONFIG.OSE.apply_damage_options.selected: | ||
return !!canvas.tokens?.controlled.length; | ||
default: { | ||
console.log('unknown setting'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should make this more specific, and a UI warning. We shouldn't end up here, but if we do, it'd be helpful if a user could tell us how they got here! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
return false; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* This function is used to hook into the Chat Log context menu to add additional options to each message | ||
* These options make it easy to conveniently apply damage to controlled tokens based on the value of a Roll | ||
|
@@ -8,8 +24,7 @@ export const addChatMessageContextOptions = function ( | |
_: JQuery, | ||
options: ContextMenuEntry[] | ||
) { | ||
let canApply: ContextMenuEntry["condition"] = (li) => | ||
!!canvas.tokens?.controlled.length && !!li.find(".dice-roll").length; | ||
let canApply: ContextMenuEntry["condition"] = (li) => canApplyDamage(li) && !!li.find(".dice-roll").length; | ||
options.push( | ||
{ | ||
name: game.i18n.localize("OSE.messages.applyDamage"), | ||
|
@@ -45,15 +60,15 @@ export const addChatMessageButtons = function (msg: ChatMessage, html: JQuery) { | |
} | ||
// Buttons | ||
let roll = html.find(".damage-roll"); | ||
if (roll.length > 0) { | ||
if (roll.length > 0 && canApplyDamage(html)) { | ||
roll.append( | ||
$( | ||
`<div class="dice-damage"><button type="button" data-action="apply-damage"><i class="fas fa-tint"></i></button></div>` | ||
) | ||
); | ||
roll.find('button[data-action="apply-damage"]').on("click", (ev) => { | ||
ev.preventDefault(); | ||
applyChatCardDamage(roll, 1); | ||
applyChatCardDamage(html, 1); | ||
}); | ||
} | ||
}; | ||
|
@@ -62,25 +77,33 @@ export const addChatMessageButtons = function (msg: ChatMessage, html: JQuery) { | |
* Apply rolled dice damage to the token or tokens which are currently controlled. | ||
* This allows for damage to be scaled by a multiplier to account for healing, critical hits, or resistance | ||
* | ||
* @param {HTMLElement} roll The chat entry which contains the roll data | ||
* @param {HTMLElement} html The chat entry which contains the roll data | ||
* @param {Number} multiplier A damage multiplier to apply to the rolled damage. | ||
* @return {Promise} | ||
*/ | ||
function applyChatCardDamage(roll: JQuery, multiplier: 1 | -1) { | ||
const amount = roll.find(".dice-total").last().text(); | ||
function applyChatCardDamage(html: JQuery, multiplier: 1 | -1) { | ||
const amount = html.find(".dice-total").last().text(); | ||
const dmgTgt = game.settings.get(game.system.id, "applyDamageOption"); | ||
if (dmgTgt === `targeted`) { | ||
game.user?.targets.forEach(async (t) => { | ||
if (game.user?.isGM && t.actor instanceof OseActor) | ||
await t.actor.applyDamage(amount, multiplier); | ||
}); | ||
if (dmgTgt === CONFIG.OSE.apply_damage_options.originalTarget) { | ||
const victimId = html.find(".chat-target").last().data("id"); | ||
(async () => { | ||
const actor = ((await fromUuid(victimId || '')) as TokenDocument)?.actor; | ||
await applyDamageToTarget(actor, amount, multiplier, actor?.name || victimId || 'original target'); | ||
})(); | ||
} | ||
if (dmgTgt === `selected`) { | ||
canvas.tokens?.controlled.forEach(async (t) => { | ||
if (game.user?.isGM && t.actor instanceof OseActor) | ||
await t.actor.applyDamage(amount, multiplier); | ||
}); | ||
if (dmgTgt === CONFIG.OSE.apply_damage_options.targeted) { | ||
game.user?.targets.forEach((t) => applyDamageToTarget(t.actor, amount, multiplier, t.name)); | ||
} | ||
if (dmgTgt === CONFIG.OSE.apply_damage_options.selected) { | ||
canvas.tokens?.controlled.forEach((t) => applyDamageToTarget(t.actor, amount, multiplier, t.name)); | ||
} | ||
} | ||
|
||
async function applyDamageToTarget(actor: Actor | null, amount: string, multiplier: 1 | -1, nameOrId: string) { | ||
if (!game.user?.isGM || !(actor instanceof OseActor)) { | ||
ui.notifications?.error(`Can't deal damage to ${nameOrId}`); | ||
return; | ||
} | ||
await actor.applyDamage(amount, multiplier); | ||
} | ||
/* -------------------------------------------- */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ export type OseConfig = { | |
saves_short: Record<Save, string>; | ||
saves_long: Record<Save, string>; | ||
armor: Record<Armor, string>; | ||
apply_damage_options: Record<ApplyDamageOption, ApplyDamageOption>; | ||
colors: Record<Color, string>; | ||
languages: string[]; | ||
auto_tags: {[n: string]: {label: string, icon: string}}; | ||
|
@@ -41,6 +42,7 @@ export type ExplorationSkill = "ld" | "od" | "sd" | "fs"; | |
export type RollType = "result" | "above" | "below"; | ||
export type Save = "death" | "wand" | "paralysis" | "breath" | "spell"; | ||
export type Armor = "unarmored" | "light" | "heavy" | "shield"; | ||
export type ApplyDamageOption = "selected" | "targeted" | "originalTarget"; | ||
export type Color = | ||
| "green" | ||
| "red" | ||
|
@@ -59,7 +61,6 @@ export type InventoryItemTag = | |
| "splash" | ||
| "reload" | ||
| "charge"; | ||
|
||
export const OSE: OseConfig = { | ||
systemPath(): string { | ||
return `${this.systemRoot}/dist`; | ||
|
@@ -133,6 +134,11 @@ export const OSE: OseConfig = { | |
heavy: "OSE.armor.heavy", | ||
shield: "OSE.armor.shield", | ||
}, | ||
apply_damage_options: { | ||
selected : "selected", | ||
targeted : "selected", | ||
originalTarget : "selected", | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this causes an error in the switch statement. It will always be the default case unless There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. eeek! |
||
colors: { | ||
green: "OSE.colors.green", | ||
red: "OSE.colors.red", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,8 +12,8 @@ <h2>{{title}}</h2> | |
{{/if}} | ||
</div> | ||
{{#if result.victim}} | ||
<div class="chat-target"> | ||
vs {{result.victim}} | ||
<div class="chat-target" data-id="{{result.victim.document.uuid}}"> | ||
vs {{result.victim.name}} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like this :) |
||
</div> | ||
{{/if}} | ||
<div class="blindable" data-blind="{{data.roll.blindroll}}"> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bakbakbakbakbak Just a heads up, I forget if you had tests written for this file or the other stuff in this PR, but this might change things for you.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the notice, I'll take a look at this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably best to revisit in a later revision of 0.8.x and leave the test as-is until after merging. We're probably expecting a non-zero amount of other surprises after such a large merge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I am having quite a bit on my plate right now either, and I have noticed that I procrastinate on this check here.