Merge pull request #10 from deltagreen-foundryvtt/sobrandm/xxx/extra-back-merge
Sobrandm/xxx/extra back merge
This commit is contained in:
+9
-1
@@ -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
@@ -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).
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
@@ -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"/>
|
||||
|
||||
Reference in New Issue
Block a user