Merge pull request #10 from deltagreen-foundryvtt/sobrandm/xxx/extra-back-merge

Sobrandm/xxx/extra back merge
This commit is contained in:
Aaron Lutomski
2026-06-18 14:19:33 -07:00
committed by GitHub
21 changed files with 423 additions and 129 deletions
+9 -1
View File
@@ -168,6 +168,7 @@
"DG.Roll.For": "For",
"DG.Roll.Damage": "Damage",
"DG.Roll.Roll": "Roll",
"DG.Roll.CannotRollStat": "A statistic of 0 cannot be rolled.",
"DG.Physical.Wounds": "Wounds",
"DG.Physical.FirstAidLabel": "First Aid Has Already Been Attempted: ",
"DG.Physical.ExhaustionPenalty": "Penalty:",
@@ -237,7 +238,7 @@
"DG.Gear.Armor": "ARMOR",
"DG.Gear.OtherGear": "OTHER GEAR",
"DG.Gear.Name": "Name",
"DG.Gear.DamageOrLethality": "Damage/Lethality",
"DG.Gear.DamageOrLethality": "Damage/ Lethality",
"DG.Gear.ArmorPiercing": "Armor Piercing",
"DG.Gear.ArmorRating": "Armor Rating",
"DG.Gear.Equipped": "Equipped",
@@ -328,6 +329,13 @@
"DG.ModifyDamageRollDialogue.Weapon": "Weapon:",
"DG.ModifyDamageRollDialogue.OuterModifierTooltip": "Use this field to modify the outer part of the formula, such as to double the result.",
"DG.ModifyDamageRollDialogue.InnerModifierTooltip": "Use this field to add a flat modifier such as '+1' or another dice term such as '+1d4'.",
"DG.DamageOrLethalityRoll.Title": "Roll Damage or Lethality",
"DG.DamageOrLethalityRoll.Intro": "This weapon has both damage and lethality. Choose which to roll.",
"DG.DamageOrLethalityRoll.RollDamage": "Roll Damage",
"DG.DamageOrLethalityRoll.RollLethality": "Roll Lethality",
"DG.EditStats.Title": "Edit Statistics",
"DG.EditStats.Button": "Edit Statistics",
"DG.EditStats.DistinguishingFeature": "Distinguishing Feature",
"DG.Roll.Inhuman": "Inhuman",
"DG.Tooltip.BreakPoint": "The current breaking point, reset when current sanity falls to or below this value. The starting breaking point is SAN - POW.",
"DG.Skills.ritual": "Ritual",
+12 -12
View File
@@ -4,19 +4,19 @@ Entry point: [`deltagreen.js`](deltagreen.js) (registered in `system.json`).
## Folder responsibilities
| Path | Purpose |
| ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`config/`](config/) | System constants (`DG`, skill list, template paths) |
| [`data/`](data/) | TypeDataModels (`actor/`, `item/`, `derived/`) |
| [`active-effect/`](active-effect/) | Active effect metadata, data model, document class, runtime sync |
| Path | Purpose |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`config/`](config/) | System constants (`DG`, skill list, template paths) |
| [`data/`](data/) | TypeDataModels (`actor/`, `item/`, `derived/`) |
| [`active-effect/`](active-effect/) | Active effect metadata, data model, document class, runtime sync |
| [`profession/`](profession/) | Profession catalog, validation, character-creation math, deferred commit ([`commit-character-creation.js`](profession/commit-character-creation.js)), Damaged Veteran modifiers ([`damaged-veteran-modifiers.js`](profession/damaged-veteran-modifiers.js)), disorder IDs ([`disorders.js`](profession/disorders.js)) |
| [`roll/`](roll/) | Dice roll subclasses, roll pipeline, and roll UX. [`roll/roll.js`](roll/roll.js) is the public API. Internal Roll subclasses live in [`roll/classes/`](roll/classes/). |
| [`sheets/`](sheets/) | ApplicationV2 sheets and mixins |
| [`applications/`](applications/) | Standalone dialogs, chargen orchestrator ([`profession-setup-flow.js`](applications/profession-setup-flow.js)), shared dialog UI ([`character-creation-ui.js`](applications/character-creation-ui.js)), and dialog factory ([`dg-dialog.js`](applications/dg-dialog.js)) |
| [`actor/`](actor/), [`item/`](item/) | Document subclasses |
| [`chat/`](chat/) | Chat cards ([`dg-chat-card.js`](chat/dg-chat-card.js)) and inline actions |
| [`integrations/`](integrations/) | Optional module hooks (Dice So Nice) |
| [`utils/`](utils/) | Generic helpers only (Handlebars, migration, skill layout/tooltips) |
| [`roll/`](roll/) | Dice roll subclasses, roll pipeline, and roll UX. [`roll/roll.js`](roll/roll.js) is the public API. Internal Roll subclasses live in [`roll/classes/`](roll/classes/). |
| [`sheets/`](sheets/) | ApplicationV2 sheets and mixins |
| [`applications/`](applications/) | Standalone dialogs, chargen orchestrator ([`profession-setup-flow.js`](applications/profession-setup-flow.js)), shared dialog UI ([`character-creation-ui.js`](applications/character-creation-ui.js)), and dialog factory ([`dg-dialog.js`](applications/dg-dialog.js)) |
| [`actor/`](actor/), [`item/`](item/) | Document subclasses |
| [`chat/`](chat/) | Chat cards ([`dg-chat-card.js`](chat/dg-chat-card.js)) and inline actions |
| [`integrations/`](integrations/) | Optional module hooks (Dice So Nice) |
| [`utils/`](utils/) | Generic helpers only (Handlebars, migration, skill layout/tooltips) |
Root-level modules: [`settings.js`](settings.js), [`templates.js`](templates.js).
+15 -3
View File
@@ -1,4 +1,5 @@
import DG, { BASE_TEMPLATE_PATH } from "../config/index.js";
import { applyDialogTheme } from "./dg-dialog.js";
export default class ActorEditStatForm extends foundry.applications.api.HandlebarsApplicationMixin(
foundry.applications.api.ApplicationV2,
@@ -11,9 +12,13 @@ export default class ActorEditStatForm extends foundry.applications.api.Handleba
/** @override */
static DEFAULT_OPTIONS = {
tag: "form",
classes: [DG.ID, "edit-stat-form"],
window: { title: "Edit statistics form", resizable: true },
position: { width: 400, height: 200 },
classes: [DG.ID, "edit-stat-form", "dg-dialog-app"],
window: {
title: "DG.EditStats.Title",
resizable: true,
contentClasses: ["standard-form"],
},
position: { width: 600, height: "auto" },
actions: {},
form: {
handler: this.formHandler,
@@ -28,11 +33,18 @@ export default class ActorEditStatForm extends foundry.applications.api.Handleba
},
});
/** @override */
async _onRender(context, options) {
await super._onRender(context, options);
applyDialogTheme(this);
}
/** @override */
async _prepareContext(options) {
return {
...(await super._prepareContext(options)),
actor: this.actor,
statKeys: DG.statistics,
sourceStatistics:
this.actor._source?.system?.statistics ?? this.actor.system.statistics,
};
+15 -1
View File
@@ -255,6 +255,20 @@ export class DGPercentileRoll extends DGRoll {
return { target, localizedKey, skillPath };
}
/**
* i18n key for a user-facing warning when this roll must not be made, or null if allowed.
* @returns {string|null}
*/
get blockedRollMessage() {
if (this.type !== "stat") return null;
const x5 = Number(this.target);
if (!Number.isFinite(x5) || x5 < 1) {
return "DG.Roll.CannotRollStat";
}
return null;
}
/**
* Create label based on result of roll
*
@@ -392,7 +406,7 @@ export class DGPercentileRoll extends DGRoll {
const { rollTargetModifier } = this;
if (!this.target || Number.isNaN(this.target)) {
if (this.target == null || Number.isNaN(this.target)) {
return null;
}
+40
View File
@@ -7,6 +7,8 @@ const PERCENTILE_ROLL_DIALOG_TEMPLATE =
"systems/deltagreen/templates/dialog/modify-percentile-roll.html";
const DAMAGE_ROLL_DIALOG_TEMPLATE =
"systems/deltagreen/templates/dialog/modify-damage-roll.html";
const DAMAGE_OR_LETHALITY_ROLL_DIALOG_TEMPLATE =
"systems/deltagreen/templates/dialog/damage-or-lethality-roll.html";
const QUICK_MODIFIER_PRESETS = [
{
@@ -215,3 +217,41 @@ export async function showDamageRollModifyDialog({ itemName, formula }) {
],
});
}
/**
* @param {object} options
* @param {string} options.itemName
* @returns {Promise<"damage"|"lethality"|void>}
*/
export async function showDamageOrLethalityChoiceDialog({ itemName }) {
const content = await renderTemplate(
DAMAGE_OR_LETHALITY_ROLL_DIALOG_TEMPLATE,
{
itemName,
},
);
return showDgDialog({
modifier: "damage-or-lethality",
content,
window: {
title: game.i18n.localize("DG.DamageOrLethalityRoll.Title"),
},
close: () => null,
buttons: [
{
default: true,
label: game.i18n.localize("DG.DamageOrLethalityRoll.RollDamage"),
action: "damage",
icon: "fas fa-dice",
callback: () => "damage",
},
{
label: game.i18n.localize("DG.DamageOrLethalityRoll.RollLethality"),
action: "lethality",
icon: "fas fa-skull-crossbones",
callback: () => "lethality",
},
],
});
}
+5
View File
@@ -100,6 +100,11 @@ export async function processDGRoll(event, roll) {
const shiftKey = event?.shiftKey ?? false;
const which = event?.which ?? 0;
if (roll instanceof DGPercentileRoll && roll.blockedRollMessage) {
ui.notifications.warn(roll.blockedRollMessage, { localize: true });
return;
}
if (shiftKey || which === 3) {
if (!(roll instanceof DGSanityDamageRoll)) {
const dialogData = await roll.showDialog();
+19 -2
View File
@@ -1,4 +1,5 @@
import { getDGRollToken } from "../../chat/dg-chat-card.js";
import { showDamageOrLethalityChoiceDialog } from "../../roll/roll-dialogs.js";
import { createDGRollFromDataset, processDGRoll } from "../../roll/roll.js";
/** @param {typeof foundry.applications.api.ApplicationV2} Base */
@@ -36,11 +37,27 @@ export default function RollSheetMixin(Base) {
* @private
*/
static async _onRoll(event, target) {
if (target.classList.contains("not-rollable") || event.which === 2)
if (event.which === 2) return;
if (target.classList.contains("not-rollable")) {
if (target.dataset.rolltype === "stat") {
ui.notifications.warn("DG.Roll.CannotRollStat", { localize: true });
}
return;
}
const item = this.actor.items.get(target.dataset.iid);
const roll = createDGRollFromDataset(target.dataset, {
const rollDataset = { ...target.dataset };
if (rollDataset.rolltype === "damage-or-lethality") {
const choice = await showDamageOrLethalityChoiceDialog({
itemName: item?.name ?? "",
});
if (!choice) return;
rollDataset.rolltype = choice;
}
const roll = createDGRollFromDataset(rollDataset, {
actor: this.actor,
item,
element: target,
+20
View File
@@ -122,4 +122,24 @@ export default function registerHandlebarsHelpers() {
return result;
});
Handlebars.registerHelper("hasWeaponDamage", (damage) => {
const trimmed = String(damage ?? "").trim();
return trimmed !== "" && trimmed !== "0";
});
Handlebars.registerHelper("hasWeaponLethality", (lethality) => {
const value = Number(lethality);
return Number.isFinite(value) && value > 0;
});
Handlebars.registerHelper("hasWeaponDamageAndLethality", (item) => {
const damage = item?.system?.damage;
const lethality = item?.system?.lethality;
const trimmed = String(damage ?? "").trim();
const hasDamage = trimmed !== "" && trimmed !== "0";
const hasLethality =
Number.isFinite(Number(lethality)) && Number(lethality) > 0;
return hasDamage && hasLethality;
});
}
+21 -1
View File
@@ -177,6 +177,22 @@ export function appendRollTargetTooltipSection(
return `${existingTooltip}<br><br>${appendix}`;
}
/**
* @param {string} existingTooltip
* @param {string} [feature]
* @returns {string}
*/
export function appendDistinguishingFeatureSection(existingTooltip, feature) {
const trimmed = String(feature ?? "").trim();
if (!trimmed) return existingTooltip;
const label = game.i18n.localize("DG.EditStats.DistinguishingFeature");
const escaped = foundry.utils.escapeHTML(trimmed);
const section = `<br><br>${foundry.utils.escapeHTML(label)}: ${escaped}`;
if (!existingTooltip) return section;
return `${existingTooltip}${section}`;
}
/**
* Stat and sanity roll-target tooltips for the agent sheet left bar (not skills).
*
@@ -191,8 +207,12 @@ export function prepareAgentStatSanityTooltips(actor) {
for (const [key, stat] of Object.entries(system.statistics ?? {})) {
const base = Number(stat.x5) || 0;
const existing = game.i18n.localize(`DG.Attributes.Tooltip.${key}`);
stat.tooltip = appendRollTargetTooltipSection(
const withFeature = appendDistinguishingFeatureSection(
existing,
stat.distinguishing_feature,
);
stat.tooltip = appendRollTargetTooltipSection(
withFeature,
actor,
"system.rollTarget.statistics",
base,
+5 -1
View File
@@ -69,7 +69,9 @@
}
button.rollable.inline-roll {
display: inline;
display: inline-block;
width: max-content;
max-width: 100%;
margin: 0;
padding: 0;
border: none;
@@ -78,6 +80,8 @@ button.rollable.inline-roll {
color: var(--dg-ink);
line-height: inherit;
vertical-align: baseline;
text-align: inherit;
box-sizing: border-box;
> i {
color: inherit;
+76 -4
View File
@@ -1,6 +1,7 @@
.agent-sheet {
--dg-agent-section-gap: 8px;
--dg-agent-list-row-border: 1px solid rgba(33, 33, 33, 0.25);
--weapons-col-damage-trail: 60px;
.window-content {
display: grid;
@@ -794,10 +795,42 @@
.tab.combat .items-list .item:not(.item-header) {
display: grid;
grid-template-columns:
24px minmax(0, 1fr) minmax(4rem, auto) minmax(3rem, auto)
24px minmax(0, 1fr)
minmax(0, calc(4.25rem + var(--weapons-col-damage-trail)))
minmax(0, 3.5rem)
86px;
align-items: center;
column-gap: 5px;
column-gap: 10px;
}
.tab.combat .items-list .weapons-col-damage,
.tab.combat .items-list .weapons-col-armor-piercing {
display: flex;
justify-content: center;
align-items: center;
min-width: 0;
text-align: center;
white-space: normal;
line-height: 1.2;
overflow-wrap: break-word;
box-sizing: border-box;
}
.tab.combat .items-list .weapons-col-damage {
padding: 0 calc(2px + var(--weapons-col-damage-trail)) 0 2px;
}
.tab.combat .items-list .weapons-col-armor-piercing {
padding: 0 2px;
}
.tab.combat .items-list .weapons-col-damage[data-action="roll"],
.tab.gear .items-list .weapons-col-damage[data-action="roll"] {
cursor: pointer;
flex-wrap: nowrap;
white-space: nowrap;
overflow-wrap: normal;
gap: 0.15em;
}
.tab.combat .items-list .item:not(.item-header) > .flexrow {
@@ -840,8 +873,35 @@
margin-top: var(--dg-agent-section-gap);
}
.tab.gear .items-list .centered-item-property {
flex: 0 0 auto;
.tab.gear .items-list .weapons-col-damage {
flex: 0 0 calc(4.25rem + var(--weapons-col-damage-trail));
max-width: calc(4.25rem + var(--weapons-col-damage-trail));
}
.tab.gear .items-list .weapons-col-armor-piercing {
flex: 0 0 3.5rem;
max-width: 3.5rem;
}
.tab.gear .items-list .weapons-col-damage,
.tab.gear .items-list .weapons-col-armor-piercing {
display: flex;
justify-content: center;
align-items: center;
min-width: 0;
text-align: center;
white-space: normal;
line-height: 1.2;
overflow-wrap: break-word;
box-sizing: border-box;
}
.tab.gear .items-list .weapons-col-damage {
padding: 0 calc(2px + var(--weapons-col-damage-trail)) 0 2px;
}
.tab.gear .items-list .weapons-col-armor-piercing {
padding: 0 2px;
}
/* Personal tab */
@@ -945,9 +1005,21 @@
border-radius: 2.5px;
background-color: rgba(0, 0, 0, 0.185);
font-weight: bold;
color: var(--dg-ink);
&:hover,
&:focus-visible {
color: var(--color-text-dark-header, #406539);
text-decoration: underline;
}
&:visited {
color: var(--dg-ink);
}
i {
flex: 0 0 auto;
color: inherit;
}
span {
+28 -2
View File
@@ -191,16 +191,42 @@ div .exhausted-section {
margin-bottom: 1rem;
}
.tab.about .dg-about-links a {
.deltagreen .tab.about .dg-about-links a {
display: inline-flex;
align-items: center;
gap: 0.5rem;
width: fit-content;
max-width: 100%;
color: var(--dg-ink);
&:hover,
&:focus-visible {
color: var(--color-text-dark-header, #406539);
text-decoration: underline;
}
&:visited {
color: var(--dg-ink);
}
}
.tab.about .dg-about-links a i {
.deltagreen .tab.about .dg-about-links a i {
flex: 0 0 auto;
color: inherit;
}
.deltagreen .tab.about .dg-about-legal a {
color: var(--dg-ink);
&:hover,
&:focus-visible {
color: var(--color-text-dark-header, #406539);
text-decoration: underline;
}
&:visited {
color: var(--dg-ink);
}
}
.tab.about .dg-about-links a span {
+17
View File
@@ -205,6 +205,23 @@
}
}
.deltagreen[id^="dg-settings"] section.window-content {
color: var(--color-text-primary);
.form-group > label {
color: var(--color-form-label);
}
.hint {
color: var(--color-form-hint);
}
input[type="checkbox"]:checked::before,
input[type="radio"]:checked::before {
color: var(--color-text-primary);
}
}
a.btn-tiny {
height: 26px;
margin-left: 5px;
+4 -9
View File
@@ -5,8 +5,8 @@
/* Edit icon */
.stats-edit-btn {
position: absolute;
top: -10px;
right: 0;
top: 50%;
right: -12px;
width: 24px;
height: 24px;
@@ -26,12 +26,13 @@
transition:
opacity 0.15s ease,
transform 0.15s ease;
transform: translateY(-50%) scale(1);
}
/* Show on hover of whole stats block */
.stats-wrapper:hover .stats-edit-btn {
opacity: 1;
transform: scale(1.05);
transform: translateY(-50%) scale(1.05);
}
/* Hover feedback */
@@ -39,12 +40,6 @@
background: var(--color-border-highlight, #c9a227);
}
.edit-stat-form {
label {
color: var(--color-text-primary);
}
}
.physical-stats-outer-grid-2col {
display: grid;
grid-template-columns: 1fr 1fr;
+53 -6
View File
@@ -814,9 +814,15 @@
line-height: 1.4;
}
.dg-dialog--damaged-veterans label.checkbox.damaged-veterans-option > input[type="radio"],
.dg-dialog--things-disorder label.checkbox.things-disorder-option > input[type="radio"],
.dg-dialog--hard-experience label.checkbox.hard-experience-bond-option > input[type="radio"] {
.dg-dialog--damaged-veterans
label.checkbox.damaged-veterans-option
> input[type="radio"],
.dg-dialog--things-disorder
label.checkbox.things-disorder-option
> input[type="radio"],
.dg-dialog--hard-experience
label.checkbox.hard-experience-bond-option
> input[type="radio"] {
margin-top: 0.15rem;
}
@@ -847,9 +853,7 @@
overflow: hidden;
}
.dg-dialog-app.dg-dialog-app--hard-experience
.dialog-form
> .dialog-content {
.dg-dialog-app.dg-dialog-app--hard-experience .dialog-form > .dialog-content {
display: flex;
flex-direction: column;
flex: 1 1 auto;
@@ -881,3 +885,46 @@
padding: 0;
border: 0;
}
/* Edit statistics */
.dg-dialog--edit-stats .edit-stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.75rem 0.5rem;
}
.dg-dialog--edit-stats .edit-stats-stat-block {
display: flex;
flex-direction: column;
gap: 0.35rem;
min-width: 0;
}
.dg-dialog--edit-stats .edit-stats-value-row {
display: flex;
flex-direction: column;
gap: 0.25rem;
align-items: stretch;
}
.dg-dialog--edit-stats .edit-stats-value-row input {
width: 100%;
text-align: center;
}
.dg-dialog--edit-stats .edit-stats-feature-row {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.dg-dialog--edit-stats .edit-stats-feature-row textarea {
width: 100%;
min-height: 2.5rem;
resize: vertical;
}
/* Damage or lethality roll choice */
.dg-dialog--damage-or-lethality .damage-or-lethality-weapon {
margin: 0.5rem 0 0;
}
+20 -20
View File
@@ -1,26 +1,26 @@
<div class="grid grid-3col stats">
{{#each actor.system.statistics as |statistic key| }}
<div class="flex-group-center flex-mid-border">
<div>
<div class="physical-stats-outer-grid-2col">
<label data-tooltip="{{localize (concat 'DG.Attributes.Tooltip.' key)}}"
for="system.statistics.{{key}}.value">
{{localize (concat 'DG.Attributes.' key)}}
</label>
<div class="dg-dialog dg-dialog--edit-stats">
<div class="edit-stats-grid">
{{#each statKeys as |key| }}
{{#with (lookup @root.actor.system.statistics key) as |statistic| }}
<div class="edit-stats-stat-block">
<label class="edit-stats-value-row dg-dialog__field">
<span class="edit-stats-label dg-dialog__field-label">{{localize (concat 'DG.Attributes.' key)}}</span>
<input class="centered"
type="text"
type="number"
name="system.statistics.{{key}}.value"
value="{{lookup (lookup @root.sourceStatistics key) 'value'}}"
data-dtype="Number" />
</div>
<div>
<input type="text"
name="system.statistics.{{key}}.distinguishing_feature"
value="{{statistic.distinguishing_feature}}"
data-dtype="String"
title="{{localize 'DG.Tooltip.DistinguishingFeature'}}" />
</div>
data-dtype="Number"
min="0" />
</label>
<label class="edit-stats-feature-row dg-dialog__field">
<span class="dg-dialog__field-label">{{localize 'DG.EditStats.DistinguishingFeature'}}</span>
<textarea name="system.statistics.{{key}}.distinguishing_feature"
rows="2"
data-dtype="String"
title="{{localize 'DG.Tooltip.DistinguishingFeature'}}">{{statistic.distinguishing_feature}}</textarea>
</label>
</div>
{{/with}}
{{/each}}
</div>
{{/each}}
</div>
@@ -7,7 +7,7 @@
<div class="flex-group-center flex-mid-border">
<div>
<div class="physical-stats-outer-grid-3col">
<label class="rollable resource-label"
<label class="{{if_gt statistic.x5 0 'rollable' 'not-rollable'}} resource-label"
data-action="roll"
data-rolltype="stat"
data-key="{{key}}"
@@ -20,7 +20,7 @@
name="system.statistics.{{key}}.value"
value="{{statistic.value}}"
data-dtype="Number" />
<span class="rollable"
<span class="{{if_gt statistic.x5 0 'rollable' 'not-rollable'}}"
data-action="roll"
data-rolltype="stat"
data-key="{{key}}"
@@ -21,8 +21,8 @@
{{localize 'DG.Gear.Name'}}
<a data-action="browsePack" data-pack-type="weapon"><i class="fas fa-search"></i></a>
</span>
<span class="centered-item-property">{{localize 'DG.Gear.DamageOrLethality'}}</span>
<span class="centered-item-property">{{localize 'DG.Gear.ArmorPiercing'}}</span>
<span class="centered-item-property weapons-col-damage">{{localize 'DG.Gear.DamageOrLethality'}}</span>
<span class="centered-item-property weapons-col-armor-piercing">{{localize 'DG.Gear.ArmorPiercing'}}</span>
<div class="item-controls">
<a class="item-control action-pill"
data-action="itemAction"
@@ -48,65 +48,60 @@
data-rolltype="weapon"
data-key="{{item.system.skill}}"
title="{{localize 'DG.Tooltip.SkillLabel'}} ({{localizeWeaponSkill item.system.skill}})">
<i class="fas fa-dice" inert></i>
<i class="fas fa-dice" aria-hidden="true"></i>
</button>
</span>
</div>
<span class="centered-item-property">
{{#if item.system.lethality }}
{{#if item.system.isLethal }}
<a class="item-control dg-red"
data-action="toggle"
data-prop="system.isLethal"
data-item-id="{{item._id}}"
title="Toggle Lethality (Current Lethality: {{item.system.lethality}}%)">
<i class="fas fa-skull-crossbones"></i>
</a>
{{#if (hasWeaponDamageAndLethality item)}}
<span class="centered-item-property weapons-col-damage rollable"
data-action="roll"
data-rolltype="damage-or-lethality"
data-iid="{{item._id}}"
title="{{localize 'DG.Gear.DamageOrLethality'}}">
{{toUpperCase item.system.damage}}
{{#if_eq item.system.skill 'unarmed_combat' }}
{{actor.system.statistics.str.meleeDamageBonusFormula}}
{{/if_eq}}
{{#if_eq item.system.skill 'melee_weapons' }}
{{actor.system.statistics.str.meleeDamageBonusFormula}}
{{/if_eq}}
/ {{item.system.lethality}}%
<i class="fas fa-dice" aria-hidden="true"></i>
</span>
{{else}}
{{#if (hasWeaponDamage item.system.damage)}}
<span class="centered-item-property weapons-col-damage rollable"
data-action="roll"
data-rolltype="damage"
data-iid="{{item._id}}"
title="{{localize 'DG.Gear.DamageOrLethality'}}">
{{toUpperCase item.system.damage}}
{{#if_eq item.system.skill 'unarmed_combat' }}
{{actor.system.statistics.str.meleeDamageBonusFormula}}
{{/if_eq}}
{{#if_eq item.system.skill 'melee_weapons' }}
{{actor.system.statistics.str.meleeDamageBonusFormula}}
{{/if_eq}}
<i class="fas fa-dice" aria-hidden="true"></i>
</span>
{{else}}
{{#if (hasWeaponLethality item.system.lethality)}}
<span class="centered-item-property weapons-col-damage rollable"
data-action="roll"
data-rolltype="lethality"
data-iid="{{item._id}}"
title="{{localize 'DG.ItemWindow.Weapons.LethalityTooltip'}}">
{{item.system.lethality}}%
<i class="fas fa-dice" aria-hidden="true"></i>
</span>
{{else}}
<a class="item-control"
data-action="toggle"
data-prop="system.isLethal"
data-item-id="{{item._id}}"
title="Toggle Lethality (Currently No Lethality)">
<i class="fas fa-user-injured"></i>
</a>
<span class="centered-item-property weapons-col-damage"></span>
{{/if}}
{{/if}}
{{/if}}
{{#unless item.system.isLethal}}
<button type="button"
class="rollable inline-roll"
data-action="roll"
data-rolltype="damage"
data-iid="{{item._id}}"
title="{{localize 'DG.Gear.DamageOrLethality'}}">
{{toUpperCase item.system.damage}}
{{#if_eq item.system.skill 'unarmed_combat' }}
{{actor.system.statistics.str.meleeDamageBonusFormula}}
{{/if_eq}}
{{#if_eq item.system.skill 'melee_weapons' }}
{{actor.system.statistics.str.meleeDamageBonusFormula}}
{{/if_eq}}
<i class="fas fa-dice" inert></i>
</button>
{{/unless}}
{{#if item.system.isLethal }}
<button type="button"
class="rollable inline-roll"
data-action="roll"
data-rolltype="lethality"
data-iid="{{item._id}}"
title="{{localize 'DG.ItemWindow.Weapons.LethalityTooltip'}}">
{{item.system.lethality}}%
<i class="fas fa-dice" inert></i>
</button>
{{/if}}
</span>
<span class="centered-item-property">{{item.system.armorPiercing}}</span>
<span class="centered-item-property weapons-col-armor-piercing">{{item.system.armorPiercing}}</span>
<div class="item-controls">
<a class="item-control"
+2 -2
View File
@@ -16,7 +16,7 @@
</div>
<div class="stats-wrapper">
<a class="stats-edit-btn" title="{{localize 'Edit Stats'}}" data-action="openStatsEdit">
<a class="stats-edit-btn" title="{{localize 'DG.EditStats.Button'}}" data-action="openStatsEdit">
<i class="fas fa-pen"></i>
</a>
@@ -25,7 +25,7 @@
<div class="flex-group-center flex-mid-border">
<div>
<div class="physical-stats-outer-grid-3col agent-left-bar-stat-grid">
<label class="rollable resource-label"
<label class="{{if_gt statistic.x5 0 'rollable' 'not-rollable'}} resource-label"
data-action="roll"
data-rolltype="stat"
data-key="{{key}}"
@@ -0,0 +1,6 @@
<div class="dg-dialog dg-dialog--damage-or-lethality">
<p class="dg-dialog__intro">{{localize "DG.DamageOrLethalityRoll.Intro"}}</p>
<p class="damage-or-lethality-weapon">
<strong>{{localize "DG.ModifyDamageRollDialogue.Weapon"}}</strong> {{itemName}}
</p>
</div>
+6 -10
View File
@@ -63,17 +63,13 @@
<span class="resource-label">{{localize 'DG.ItemWindow.Weapons.SkillModifier'}}:</span>
<input type="text" name="system.skillModifier" value="{{item.system.skillModifier}}" data-dtype="Number"/>
{{#unless item.system.isLethal}}
<span class="resource-label">{{localize 'DG.ItemWindow.Weapons.Damage'}}:</span>
<input type="text" name="system.damage" value="{{item.system.damage}}" data-dtype="String"/>
{{/unless}}
<span class="resource-label">{{localize 'DG.ItemWindow.Weapons.Damage'}}:</span>
<input type="text" name="system.damage" value="{{item.system.damage}}" data-dtype="String"/>
{{#if item.system.isLethal}}
<span class="resource-label">{{localize 'DG.ItemWindow.Weapons.Lethality'}} %:</span>
<input type="text" name="system.lethality" value="{{item.system.lethality}}" data-dtype="Number"
title="{{localize 'DG.ItemWindow.Weapons.LethalityTooltip'}}"
/>
{{/if}}
<span class="resource-label">{{localize 'DG.ItemWindow.Weapons.Lethality'}} %:</span>
<input type="text" name="system.lethality" value="{{item.system.lethality}}" data-dtype="Number"
title="{{localize 'DG.ItemWindow.Weapons.LethalityTooltip'}}"
/>
<span class="resource-label">{{localize 'DG.ItemWindow.Weapons.Ammo'}}:</span>
<input type="text" name="system.ammo" value="{{item.system.ammo}}" data-dtype="String"/>