Style fixes

This commit is contained in:
Aaron Lutomski
2026-05-30 12:17:35 -07:00
parent 00b77081c2
commit f2cea4e166
18 changed files with 316 additions and 338 deletions
+7 -6
View File
@@ -230,6 +230,7 @@
"DG.Mental.AdaptedToHelplessness": "Adapted to Helplessness",
"DG.Mental.Motivations": "Motivation",
"DG.Mental.Disorders": "Disorder",
"DG.Gear.SelectCompendium": "Select Compendium",
"DG.Gear.WeaponTypes.Firearms": "Firearms",
"DG.Gear.WeaponTypes.Melee": "Melee",
"DG.Gear.Weapons": "WEAPONS",
@@ -342,8 +343,9 @@
"DG.Sheet.BlockHeaders.PersonalInfoCV": "PERSONAL INFORMATION / CV",
"DG.Sheet.BlockHeaders.ScenarioInformation": "SCENARIO INFORMATION",
"DG.Sheet.BlockHeaders.BondsRelationshipsContacts": "BONDS / RELATIONSHIPS / CONTACTS",
"DG.AgentSheet.ProfessionPlaceholder": "PROFESSION (RANK IF APPLICABLE)",
"DG.AgentSheet.OpenProfessionToEdit": "Click to edit profession",
"DG.AgentSheet.ProfessionPlaceholder": "PROFESSION (RANK)",
"DG.AgentSheet.RenameProfession.Title": "Rename Profession",
"DG.AgentSheet.RenameProfession.Tooltip": "Click to rename profession",
"DG.UnnaturalSheet.HideUntrainedSkillsLabel": "Hide Untrained",
"DG.UnnaturalSheet.ShortDescriptionPlaceholder": "Description of creature or creature type",
"DG.UnnaturalSheet.ShowUntrainedSkillsLabel": "Show Untrained",
@@ -389,14 +391,13 @@
"DG.Profession.Dialog.SkillTotalsHint": "Skills in green have been increased by your profession. Hover over a skill to see what it does or consult the Agent's Handbook for the full description.",
"DG.Profession.Dialog.SkillsOptionsHeader": "Skills Options ({picks} picks)",
"DG.Profession.Dialog.BonusSkillsIntro": "Select skills from the dropdowns to add 20% to their total. A skill may be selected multiple times. Unnatural cannot be selected, nor can any skill be increased above 80% at character creation.",
"DG.Profession.Dialog.BonusSkillAlreadyAtCap": "{skill} may not be increased further. Please select a different bonus skill.",
"DG.Profession.Dialog.BonusSkillWasteTooHigh": "Bonus increases to {skill} would waste {waste} skill points (at most {maxWaste} may be wasted per skill).",
"DG.Profession.Dialog.BonusSkillWasteTooHigh": "{skill} cannot be increased above 80. Select a different bonus skill.",
"DG.Profession.Dialog.BondsIntro": "Bonds are the important relationships in your agent's life, such as family, friends, and other loved ones. They can provide a buffer against SAN loss, at the cost of that relationship. Initial relationship score is equal to CHA.",
"DG.Profession.Dialog.BondFieldLabel": "Bond{number}",
"DG.Profession.Dialog.SelectSkill": "Select a skill…",
"DG.Profession.Dialog.SkillTypePlaceholder": "Type or specialization",
"DG.Profession.Dialog.Submit": "Submit",
"DG.Profession.Dialog.CapWarning": "{skill} is being raised to {attempted} but is capped at 80 during agent creation. This is wasting {waste} skill points.",
"DG.Profession.Dialog.CapWarning": "{skill} is being raised to {attempted} but is capped at 80 during agent creation, wasting {waste} skill points.",
"DG.Profession.Dialog.DuplicateTypedName": "Duplicate {type} ({name}) detected. Please choose unique names.",
"DG.Profession.ChooseOnePlaceholder": "choose one",
"DG.Profession.Dialog.ChooseOneNamesHeader": "Name Skill Specializations",
@@ -419,7 +420,7 @@
"DG.ItemWindow.Profession.SkillsTab": "Skills",
"DG.ItemWindow.Profession.Name": "Profession Name",
"DG.ItemWindow.Profession.Bonds": "Bonds",
"DG.ItemWindow.Profession.BondsTooltip": "Number of bond slots granted when this profession is assigned to an agent (0–5).",
"DG.ItemWindow.Profession.BondsTooltip": "Number of bond slots granted when this profession is assigned to an agent (1 – 5).",
"DG.ItemWindow.Profession.AutomaticSkills": "Automatic Skills",
"DG.ItemWindow.Profession.OptionSkills": "Skill Options",
"DG.ItemWindow.Profession.OptionPicks": "Option Picks",
+10 -8
View File
@@ -462,16 +462,16 @@ class AddProfessionDialogController {
* @returns {{
* validationMessages: string[],
* capWarnings: { warning: string }[],
* atCapMessages: string[],
* wasteMessages: string[],
* }}
*/
#getDisplayMessages(computed) {
const atCapPrefix = "bonusAtCap:";
const wastePrefix = "bonusWaste:";
const mainErrors = computed.validationErrors.filter(
(code) => !code.startsWith(atCapPrefix),
(code) => !code.startsWith(wastePrefix),
);
const atCapErrors = computed.validationErrors.filter((code) =>
code.startsWith(atCapPrefix),
const wasteErrors = computed.validationErrors.filter((code) =>
code.startsWith(wastePrefix),
);
return {
@@ -485,7 +485,7 @@ class AddProfessionDialogController {
waste: w.waste,
}),
})),
atCapMessages: formatProfessionValidationMessages(atCapErrors, {
wasteMessages: formatProfessionValidationMessages(wasteErrors, {
optionPicks: this.optionPicks,
}),
};
@@ -496,7 +496,7 @@ class AddProfessionDialogController {
* @returns {string}
*/
#buildMessagesHtml(computed) {
const { validationMessages, capWarnings, atCapMessages } =
const { validationMessages, capWarnings, wasteMessages } =
this.#getDisplayMessages(computed);
const toErrorHtml = (messages) =>
@@ -519,7 +519,9 @@ class AddProfessionDialogController {
.join("");
return (
toErrorHtml(validationMessages) + capHtml + toErrorHtml(atCapMessages)
toErrorHtml(validationMessages) +
capHtml +
toErrorHtml(wasteMessages)
);
}
@@ -0,0 +1,45 @@
import { BASE_TEMPLATE_PATH } from "../config/index.js";
import { getDialogContentRoot, showDgDialog } from "./dg-dialog.js";
const { renderTemplate } = foundry.applications.handlebars;
/**
* @param {Item} professionItem
* @returns {Promise<boolean>} True if the name was updated.
*/
export async function showRenameProfessionDialog(professionItem) {
if (professionItem.type !== "profession") return false;
const content = await renderTemplate(
`${BASE_TEMPLATE_PATH}/dialog/rename-profession.html`,
{ name: professionItem.name },
);
const result = await showDgDialog({
modifier: "rename-profession",
content,
position: { width: 360 },
window: {
title: game.i18n.localize("DG.AgentSheet.RenameProfession.Title"),
},
default: "submit",
buttons: [
{
default: true,
action: "submit",
label: game.i18n.localize("DG.Profession.Dialog.Submit"),
callback: (_event, _button, dialog) => {
const name = getDialogContentRoot(dialog)
?.querySelector("[name='profession-rename']")
?.value?.trim();
return name || null;
},
},
],
});
if (!result || result === professionItem.name) return false;
await professionItem.update({ name: result });
return true;
}
+9 -5
View File
@@ -1,3 +1,5 @@
import { showDgDialog } from "../applications/dg-dialog.js";
function GetAttacksFromInput(inputText) {
const attacks = [];
try {
@@ -661,14 +663,16 @@ async function GetUserInput() {
</div>
</form>`;
new foundry.applications.api.DialogV2({
window: { title: "Stat Block Parser" },
await showDgDialog({
modifier: "stat-parser",
content,
window: { title: "Stat Block Parser" },
buttons: [
{
label: "PARSE",
action: "roll",
callback: (event, button, dialog) => {
default: true,
callback: (_event, _button, dialog) => {
const textInput =
dialog.element.querySelector("[name=parse-input]")?.value;
@@ -679,9 +683,9 @@ async function GetUserInput() {
},
},
],
}).render(true);
});
}
export default async function ParseDeltaGreenStatBlock() {
GetUserInput();
await GetUserInput();
}
+3 -7
View File
@@ -143,7 +143,7 @@ function getBonusTrackBaseValue(trackKey, baseFixed, baseTyped, defaults) {
}
/**
* Bonus skill slots that would waste 20+ points or raise a skill already at the creation cap.
* Bonus skill slots that would waste 20+ points over the creation cap (skill below 80).
*
* @param {Record<string, number>} baseFixed
* @param {Record<string, { group: string, label: string, value: number }>} baseTyped
@@ -191,7 +191,7 @@ export function collectBonusCapValidationErrors(
);
const final = base + count * BONUS_SKILL_INCREMENT;
const waste = Math.max(0, final - SKILL_CAP);
if (base >= SKILL_CAP || waste >= MAX_ALLOWED_BONUS_WASTE) {
if (base < SKILL_CAP && waste >= MAX_ALLOWED_BONUS_WASTE) {
violatingTrackKeys.add(trackKey);
}
}
@@ -212,11 +212,7 @@ export function collectBonusCapValidationErrors(
const final = base + count * BONUS_SKILL_INCREMENT;
const waste = Math.max(0, final - SKILL_CAP);
if (base >= SKILL_CAP) {
errors.push(`bonusAtCap:${i}|${trackKey}`);
} else {
errors.push(`bonusWaste:${i}|${waste}|${trackKey}`);
}
errors.push(`bonusWaste:${i}|${waste}|${trackKey}`);
}
return errors;
+5 -17
View File
@@ -1,4 +1,4 @@
import { BONUS_SKILL_COUNT, MAX_ALLOWED_BONUS_WASTE } from "./constants.js";
import { BONUS_SKILL_COUNT } from "./constants.js";
import { catalogIdToSkillRef, getBonusTrackLabel } from "./catalog.js";
import {
getTypedGroupDisplayName,
@@ -135,7 +135,7 @@ export function formatProfessionValidationMessages(
/** @type {Set<string>} */
const typedNameRequiredGroups = new Set();
/** @type {string[]} */
const bonusAtCapTrackKeys = [];
const bonusWasteTrackKeys = [];
for (const code of errors) {
if (code === "optionPicks") {
@@ -150,21 +150,9 @@ export function formatProfessionValidationMessages(
needsBondRelationship = true;
continue;
}
const bonusAtCap = code.match(/^bonusAtCap:\d+\|(.+)$/);
if (bonusAtCap) {
bonusAtCapTrackKeys.push(bonusAtCap[1]);
continue;
}
const bonusWaste = code.match(/^bonusWaste:\d+\|(\d+)\|(.+)$/);
if (bonusWaste) {
push(
game.i18n.format("DG.Profession.Dialog.BonusSkillWasteTooHigh", {
skill: getBonusTrackLabel(bonusWaste[2]),
waste: Number(bonusWaste[1]),
maxWaste: MAX_ALLOWED_BONUS_WASTE - 1,
}),
);
bonusWasteTrackKeys.push(bonusWaste[2]);
continue;
}
@@ -226,9 +214,9 @@ export function formatProfessionValidationMessages(
push(game.i18n.localize("DG.Profession.Dialog.BondRelationshipRequired"));
}
for (const trackKey of bonusAtCapTrackKeys) {
for (const trackKey of bonusWasteTrackKeys) {
push(
game.i18n.format("DG.Profession.Dialog.BonusSkillAlreadyAtCap", {
game.i18n.format("DG.Profession.Dialog.BonusSkillWasteTooHigh", {
skill: getBonusTrackLabel(trackKey),
}),
);
+12 -10
View File
@@ -1,5 +1,6 @@
import { createDGChatMessage } from "../chat/dg-chat-card.js";
import DG from "../config/index.js";
import { formatProfessionSkillLabel } from "../profession/index.js";
/**
* @param {"1"|"d3"|"d4"|"d4-1"} baseFormula
@@ -68,23 +69,24 @@ export async function createSkillImprovementChatMessage({
failedTypedSkills,
resultObj,
}) {
const localizeFailedSkills = (skillsArray) => {
const localizeFailedSkills = (skillsArray, kind) => {
return skillsArray.map((skill) => {
const increment = resultObj[skill.key] ?? 1;
const label =
skill.label ?? game.i18n.localize(`DG.Skills.${skill.key}`);
const groupLabel = skill.group
? `${game.i18n.localize(
`DG.TypeSkills.${skill.group.replace(/\s+/g, "")}`,
)} (${label})`
: label;
kind === "typed"
? formatProfessionSkillLabel({
kind: "typed",
group: skill.group,
label: skill.label,
})
: formatProfessionSkillLabel({ kind: "fixed", key: skill.key });
return `${groupLabel}: <b>+${increment}%</b>`;
return `${label}: <b>+${increment}%</b>`;
});
};
const failedSkillNames = localizeFailedSkills(failedSkills);
const failedTypedSkillNames = localizeFailedSkills(failedTypedSkills);
const failedSkillNames = localizeFailedSkills(failedSkills, "fixed");
const failedTypedSkillNames = localizeFailedSkills(failedTypedSkills, "typed");
const content = [...failedSkillNames, ...failedTypedSkillNames].join(", ");
const label = game.i18n.format(
+26 -14
View File
@@ -19,6 +19,7 @@ import {
} from "../active-effect/runtime/stimulant-effect.js";
import { assignProfessionToAgent } from "../applications/profession-setup-flow.js";
import { showDgDialog } from "../applications/dg-dialog.js";
import { showRenameProfessionDialog } from "../applications/rename-profession-dialog.js";
import { PROFESSION_OPTION_PICKS_KEY } from "../data/item/profession.js";
const { renderTemplate } = foundry.applications.handlebars;
@@ -292,12 +293,13 @@ export default class DGAgentSheet extends AgentSheetBase {
* @param {PointerEvent} _event
* @param {HTMLElement} target
*/
static _openProfessionItem(_event, target) {
static async _openProfessionItem(_event, target) {
const itemId =
target.dataset.itemId ??
target.closest("[data-item-id]")?.dataset?.itemId;
const item = this.actor.items.get(itemId);
if (item?.type === "profession") item.sheet.render(true);
if (item?.type !== "profession") return;
await showRenameProfessionDialog(item);
}
static _clearBondDamage() {
@@ -550,6 +552,18 @@ export default class DGAgentSheet extends AgentSheetBase {
});
}
/**
* @param {Record<string, object>} skillMap
* @returns {object[]}
*/
static _collectFailedSkills(skillMap) {
return Object.entries(skillMap)
.filter(
([, skill]) => skill.failure && !skill.cannotBeImprovedByFailure,
)
.map(([key, skill]) => ({ ...skill, key }));
}
/**
* Runs through the whole process of improving skills,
* i.e., prompting the user, rolling, and creating the chat card.
@@ -559,12 +573,8 @@ export default class DGAgentSheet extends AgentSheetBase {
static async _processSkillImprovements() {
const { skills, typedSkills } = this.actor.system;
const failedSkills = Object.values(skills).filter(
(skill) => skill.failure && !skill.cannotBeImprovedByFailure,
);
const failedTypedSkills = Object.values(typedSkills).filter(
(skill) => skill.failure && !skill.cannotBeImprovedByFailure,
);
const failedSkills = DGAgentSheet._collectFailedSkills(skills);
const failedTypedSkills = DGAgentSheet._collectFailedSkills(typedSkills);
if (failedSkills.length + failedTypedSkills.length === 0) {
ui.notifications.warn("DG.Skills.ApplySkillImprovements.Warning", {
@@ -640,14 +650,16 @@ export default class DGAgentSheet extends AgentSheetBase {
failedTypedSkills,
) {
const localizedFailedSkills = failedSkills.map((skill) =>
game.i18n.localize(`DG.Skills.${skill.key}`),
formatProfessionSkillLabel({ kind: "fixed", key: skill.key }),
);
const localizedFailedTypedSkills = failedTypedSkills.map((skill) => {
const groupKey = `DG.TypeSkills.${skill.group.replace(/\s+/g, "")}`;
const groupLabel = game.i18n.localize(groupKey);
return `${groupLabel} (${skill.label})`;
});
const localizedFailedTypedSkills = failedTypedSkills.map((skill) =>
formatProfessionSkillLabel({
kind: "typed",
group: skill.group,
label: skill.label,
}),
);
const failedSkillNames = [
...localizedFailedSkills,
+37 -35
View File
@@ -1,4 +1,4 @@
const { DialogV2 } = foundry.applications.api;
import { showDgDialog } from "../../applications/dg-dialog.js";
/** @param {typeof foundry.applications.api.ApplicationV2} Base */
export default function ItemListMixin(Base) {
@@ -189,41 +189,43 @@ export default function ItemListMixin(Base) {
static _browsePack(event, target) {
const { packType } = target.dataset;
switch (packType) {
case "weapon": {
new DialogV2({
window: { title: "Select Compendium" },
buttons: [
{
action: "firearms",
label: game.i18n.localize("DG.Gear.WeaponTypes.Firearms"),
icon: '<i class="fas fa-crosshairs"></i>',
callback: () =>
game.packs
.find((k) => k.collection === "deltagreen.firearms")
.render(true),
},
{
action: "melee",
label: game.i18n.localize("DG.Gear.WeaponTypes.Melee"),
icon: '<i class="far fa-hand-rock"></i>',
callback: () =>
game.packs
.find(
(k) => k.collection === "deltagreen.hand-to-hand-weapons",
)
.render(true),
},
],
}).render(true);
break;
}
default:
game.packs
.find((k) => k.collection === `deltagreen.${packType}`)
.render(true);
break;
if (packType === "weapon") {
void this._browseWeaponPack();
return;
}
game.packs
.find((k) => k.collection === `deltagreen.${packType}`)
.render(true);
}
async _browseWeaponPack() {
await showDgDialog({
modifier: "browse-weapon-pack",
window: {
title: game.i18n.localize("DG.Gear.SelectCompendium"),
},
buttons: [
{
action: "firearms",
label: game.i18n.localize("DG.Gear.WeaponTypes.Firearms"),
icon: '<i class="fas fa-crosshairs"></i>',
callback: () =>
game.packs
.find((k) => k.collection === "deltagreen.firearms")
.render(true),
},
{
action: "melee",
label: game.i18n.localize("DG.Gear.WeaponTypes.Melee"),
icon: '<i class="far fa-hand-rock"></i>',
callback: () =>
game.packs
.find((k) => k.collection === "deltagreen.hand-to-hand-weapons")
.render(true),
},
],
});
}
/**
@@ -1,4 +1,4 @@
const { DialogV2 } = foundry.applications.api;
import { showDgDialog } from "../../applications/dg-dialog.js";
/** @param {typeof foundry.applications.api.ApplicationV2} Base */
export default function SpecialTrainingMixin(Base) {
@@ -23,7 +23,7 @@ export default function SpecialTrainingMixin(Base) {
}
break;
default:
this._showSpecialTrainingDialog(actionType, id);
void this._showSpecialTrainingDialog(actionType, id);
break;
}
}
@@ -95,7 +95,8 @@ export default function SpecialTrainingMixin(Base) {
`DG.SpecialTraining.Dialog.${action.capitalize()}SpecialTraining`,
);
new DialogV2({
await showDgDialog({
modifier: "special-training",
content,
window: {
title: game.i18n.localize("DG.SpecialTraining.Dialog.Title"),
@@ -106,7 +107,7 @@ export default function SpecialTrainingMixin(Base) {
default: true,
action: "confirm",
label: buttonLabel,
callback: (event, button, dialog) => {
callback: (_event, _button, dialog) => {
const specialTrainingLabel = dialog.element.querySelector(
"[name='special-training-label']",
)?.value;
@@ -127,7 +128,7 @@ export default function SpecialTrainingMixin(Base) {
},
},
],
}).render(true);
});
}
_createSpecialTraining(label, attribute) {
+66 -198
View File
@@ -1,4 +1,23 @@
const { DialogV2 } = foundry.applications.api;
import { showDgDialog } from "../../applications/dg-dialog.js";
import { BASE_TEMPLATE_PATH } from "../../config/index.js";
import {
TYPED_GROUP_I18N,
TYPED_SKILL_TEMPLATE_GROUPS,
} from "../../profession/constants.js";
const { renderTemplate } = foundry.applications.handlebars;
/**
* @param {string} [selectedGroup]
* @returns {{ value: string, label: string, selected: boolean }[]}
*/
function buildTypedSkillGroupOptions(selectedGroup) {
return TYPED_SKILL_TEMPLATE_GROUPS.map((value) => ({
value,
label: game.i18n.localize(TYPED_GROUP_I18N[value]),
selected: value === selectedGroup,
}));
}
/** @param {typeof foundry.applications.api.ApplicationV2} Base */
export default function TypedSkillMixin(Base) {
@@ -7,10 +26,13 @@ export default function TypedSkillMixin(Base) {
const { actionType, typedskill } = target.dataset;
switch (actionType) {
case "create":
this._showNewTypeSkillDialog();
void this._showTypedSkillDialog({ mode: "create" });
break;
case "edit":
this._showNewEditTypeSkillDialog(typedskill);
void this._showTypedSkillDialog({
mode: "edit",
targetSkill: typedskill,
});
break;
case "delete":
this.actor.update({ [`system.typedSkills.-=${typedskill}`]: null });
@@ -20,215 +42,61 @@ export default function TypedSkillMixin(Base) {
}
}
_showNewEditTypeSkillDialog(targetSkill) {
const { typedSkills } = this.actor.system;
const currentLabel = typedSkills[targetSkill].label;
const currentGroup = typedSkills[targetSkill].group;
/**
* @param {{ mode: "create" | "edit", targetSkill?: string }} options
*/
async _showTypedSkillDialog({ mode, targetSkill }) {
const isEdit = mode === "edit";
const typedSkills = this.actor.system.typedSkills;
const currentLabel = isEdit ? typedSkills[targetSkill].label : "";
const currentGroup = isEdit
? typedSkills[targetSkill].group
: TYPED_SKILL_TEMPLATE_GROUPS[0];
let htmlContent = `<div>`;
htmlContent += ` <label>${
game.i18n.translations.DG?.Skills?.SkillGroup ?? "Skill Group"
}:</label>`;
htmlContent += ` <select name="new-type-skill-group" />`;
if (currentGroup === game.i18n.translations.DG?.TypeSkills?.Art ?? "Art") {
htmlContent += ` <option value="Art" selected>${
game.i18n.translations.DG?.TypeSkills?.Art ?? "Art"
}</option>`;
} else {
htmlContent += ` <option value="Art">${
game.i18n.translations.DG?.TypeSkills?.Art ?? "Art"
}</option>`;
}
if (
currentGroup === game.i18n.translations.DG?.TypeSkills?.Craft ??
"Craft"
) {
htmlContent += ` <option value="Craft" selected>${
game.i18n.translations.DG?.TypeSkills?.Craft ?? "Craft"
}</option>`;
} else {
htmlContent += ` <option value="Craft">${
game.i18n.translations.DG?.TypeSkills?.Craft ?? "Craft"
}</option>`;
}
if (
currentGroup ===
(game.i18n.translations.DG?.TypeSkills?.ForeignLanguage ??
"Foreign Language")
) {
htmlContent += ` <option value="ForeignLanguage" selected>${
game.i18n.translations.DG?.TypeSkills?.ForeignLanguage ??
"Foreign Language"
}</option>`;
} else {
htmlContent += ` <option value="ForeignLanguage">${
game.i18n.translations.DG?.TypeSkills?.ForeignLanguage ??
"Foreign Language"
}</option>`;
}
if (
currentGroup ===
(game.i18n.translations.DG?.TypeSkills?.MilitaryScience ??
"Military Science")
) {
htmlContent += ` <option value="MilitaryScience" selected>${
game.i18n.translations.DG?.TypeSkills?.MilitaryScience ??
"Military Science"
}</option>`;
} else {
htmlContent += ` <option value="MilitaryScience">${
game.i18n.translations.DG?.TypeSkills?.MilitaryScience ??
"Military Science"
}</option>`;
}
if (
currentGroup === game.i18n.translations.DG?.TypeSkills?.Pilot ?? "Pilot"
) {
htmlContent += ` <option value="Pilot" selected>${
game.i18n.translations.DG?.TypeSkills?.Pilot ?? "Pilot"
}</option>`;
} else {
htmlContent += ` <option value="Pilot">${
game.i18n.translations.DG?.TypeSkills?.Pilot ?? "Pilot"
}</option>`;
}
if (
currentGroup ===
(game.i18n.translations.DG?.TypeSkills?.Science ?? "Science")
) {
htmlContent += ` <option value="Science" selected>${
game.i18n.translations.DG?.TypeSkills?.Science ?? "Science"
}</option>`;
} else {
htmlContent += ` <option value="Science">${
game.i18n.translations.DG?.TypeSkills?.Science ?? "Science"
}</option>`;
}
if (
currentGroup === game.i18n.translations.DG?.TypeSkills?.Other ?? "Other"
) {
htmlContent += ` <option value="Other" selected>${
game.i18n.translations.DG?.TypeSkills?.Other ?? "Other"
}</option>`;
} else {
htmlContent += ` <option value="Other">${
game.i18n.translations.DG?.TypeSkills?.Other ?? "Other"
}</option>`;
}
htmlContent += ` </select>`;
htmlContent += `</div>`;
htmlContent += `<div>`;
htmlContent += ` <label>${
game.i18n.translations.DG?.Skills.SkillName ?? "Skill Name"
}</label>`;
htmlContent += ` <input type="text" name="new-type-skill-label" value="${currentLabel}" />`;
htmlContent += `</div>`;
new DialogV2({
content: htmlContent,
window: {
title:
game.i18n.translations.DG?.Skills?.EditTypedOrCustomSkill ??
"Edit Typed or Custom Skill",
const content = await renderTemplate(
`${BASE_TEMPLATE_PATH}/dialog/typed-skill.html`,
{
groups: buildTypedSkillGroupOptions(currentGroup),
label: currentLabel,
},
);
const titleKey = isEdit
? "DG.Skills.EditTypedOrCustomSkill"
: "DG.Skills.AddTypedOrCustomSkill";
const buttonKey = isEdit ? "DG.Skills.EditSkill" : "DG.Skills.AddSkill";
await showDgDialog({
modifier: "typed-skill",
content,
position: { width: 320 },
window: { title: game.i18n.localize(titleKey) },
default: "submit",
buttons: [
{
default: true,
action: "add",
label: game.i18n.translations.DG?.Skills?.EditSkill ?? "Edit Skill",
callback: (event, button, dialog) => {
action: "submit",
label: game.i18n.localize(buttonKey),
callback: (_event, _button, dialog) => {
const newTypeSkillLabel = dialog.element.querySelector(
"[name='new-type-skill-label']",
)?.value;
const newTypeSkillGroup = dialog.element.querySelector(
"[name='new-type-skill-group']",
)?.value;
this._updateTypedSkill(
targetSkill,
newTypeSkillLabel,
newTypeSkillGroup,
);
if (isEdit) {
this._updateTypedSkill(
targetSkill,
newTypeSkillLabel,
newTypeSkillGroup,
);
} else {
this._addNewTypedSkill(newTypeSkillLabel, newTypeSkillGroup);
}
},
},
],
}).render(true);
}
_showNewTypeSkillDialog() {
let htmlContent = "";
htmlContent += `<div>`;
htmlContent += ` <label>${
game.i18n.translations.DG?.Skills?.SkillGroup ?? "Skill Group"
}:</label>`;
htmlContent += ` <select name="new-type-skill-group" />`;
htmlContent += ` <option value="Art">${
game.i18n.translations.DG?.TypeSkills?.Art ?? "Art"
}</option>`;
htmlContent += ` <option value="Craft">${
game.i18n.translations.DG?.TypeSkills?.Craft ?? "Craft"
}</option>`;
htmlContent += ` <option value="ForeignLanguage">${
game.i18n.translations.DG?.TypeSkills?.ForeignLanguage ??
"Foreign Language"
}</option>`;
htmlContent += ` <option value="MilitaryScience">${
game.i18n.translations.DG?.TypeSkills?.MilitaryScience ??
"Military Science"
}</option>`;
htmlContent += ` <option value="Pilot">${
game.i18n.translations.DG?.TypeSkills?.Pilot ?? "Pilot"
}</option>`;
htmlContent += ` <option value="Science">${
game.i18n.translations.DG?.TypeSkills?.Science ?? "Science"
}</option>`;
htmlContent += ` <option value="Other">${
game.i18n.translations.DG?.TypeSkills?.Other ?? "Other"
}</option>`;
htmlContent += ` </select>`;
htmlContent += `</div>`;
htmlContent += `<div>`;
htmlContent += ` <label>${
game.i18n.translations.DG?.Skills.SkillName ?? "Skill Name"
}</label>`;
htmlContent += ` <input type="text" name="new-type-skill-label" />`;
htmlContent += `</div>`;
new DialogV2({
content: htmlContent,
window: {
title:
game.i18n.translations.DG?.Skills?.AddTypedOrCustomSkill ??
"Add Typed or Custom Skill",
},
default: "add",
buttons: [
{
default: true,
action: "add",
label: game.i18n.translations.DG?.Skills?.AddSkill ?? "Add Skill",
callback: (event, button, dialog) => {
const newTypeSkillLabel = dialog.element.querySelector(
"[name='new-type-skill-label']",
)?.value;
const newTypeSkillGroup = dialog.element.querySelector(
"[name='new-type-skill-group']",
)?.value;
this._addNewTypedSkill(newTypeSkillLabel, newTypeSkillGroup);
},
},
],
}).render(true);
});
}
_addNewTypedSkill(newSkillLabel, newSkillGroup) {
+37 -18
View File
@@ -17,15 +17,26 @@
padding: 3px;
}
.left-bar .profession-subname-link {
display: block;
box-sizing: border-box;
padding: 1px 2px;
line-height: var(--line-height-18, 1.125rem);
text-decoration: none;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
/* DG global form inputs use height: unset; restore Foundry sizing in the header. */
.left-bar .header-name-fields > input {
height: var(--input-height);
line-height: var(--input-height);
}
.left-bar .header-name-fields > input + input {
margin-top: 2px;
}
.left-bar .header-name-fields > input.profession-subname-display[readonly] {
cursor: pointer;
--input-background-color: rgba(0, 0, 0, 0.1);
--input-border-color: var(--color-dark-6);
--input-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
--input-text-color: inherit;
&:hover {
--input-background-color: rgba(0, 0, 0, 0.12);
}
}
.stats-wrapper {
@@ -244,18 +255,18 @@
.resources .resource-inner-grid-3col input {
box-sizing: border-box;
width: 1.5rem;
height: 1.5rem;
width: 1.75rem;
height: 1.75rem;
padding: 1px;
line-height: calc(1.5rem - 4px);
line-height: calc(1.75rem - 4px);
}
.resources .resource-inner-grid-3col .max-resource-value {
box-sizing: border-box;
width: 1.5rem;
height: 1.5rem;
min-width: 1.5rem;
min-height: 1.5rem;
width: 1.7rem;
height: 1.75rem;
min-width: 1.75rem;
min-height: 1.75rem;
}
.breaking-point-inline {
@@ -807,8 +818,16 @@
.tab.motivations .items-list .item-header .acute-episode-col,
.tab.motivations .items-list .item .acute-episode-col {
flex: 0 0 5.5rem;
text-align: center;
flex: 0 0 7.75rem;
min-width: 7.75rem;
display: flex;
justify-content: center;
align-items: center;
white-space: nowrap;
input[type="checkbox"] {
margin: 0;
}
}
/* Equipment tab */
+10 -2
View File
@@ -93,8 +93,16 @@
}
.deltagreen .motivations .acute-episode-col {
flex: 0 0 5.5rem;
text-align: center;
flex: 0 0 7.75rem;
min-width: 7.75rem;
display: flex;
justify-content: center;
align-items: center;
white-space: nowrap;
input[type="checkbox"] {
margin: 0;
}
}
.deltagreen .motivations li.acute-episode-active {
@@ -1,12 +1,13 @@
{{#if professionItem}}
<a class="content-link profession-subname-link fill-remaining-space"
data-action="openProfessionItem"
data-item-id="{{professionItem.id}}"
title="{{localize 'DG.AgentSheet.OpenProfessionToEdit'}}">
<i class="fas fa-briefcase"></i> {{professionItem.name}}
</a>
<input class="fill-remaining-space profession-subname-display"
type="text"
readonly
value="{{professionItem.name}}"
data-action="openProfessionItem"
data-item-id="{{professionItem.id}}"
title="{{localize 'DG.AgentSheet.RenameProfession.Tooltip'}}" />
{{else}}
<input class="fill-remaining-space profession-input"
<input class="fill-remaining-space"
name="system.biography.profession"
type="text"
value="{{actor.system.biography.profession}}"
@@ -14,8 +14,8 @@
<li class="item flexrow item-header">
<div class="item-name">{{localize 'DG.Mental.Motivations'}}</div>
<div class="item-name acute-episode-col">{{localize 'DG.ItemWindow.Motivations.AcuteEpisode'}}</div>
<div class="item-name">{{localize 'DG.Mental.Disorders'}}</div>
<div class="item-name acute-episode-col">{{localize 'DG.ItemWindow.Motivations.AcuteEpisode'}}</div>
<div class="item-controls">
<a class="item-control action-pill"
data-action="itemAction"
@@ -36,6 +36,10 @@
{{item.name}}
</span>
<span class="item-name">
{{#if item.system.crossedOut }}{{item.system.disorder}}{{/if}}
</span>
<span class="acute-episode-col">
<input type="checkbox"
{{checked item.system.acuteEpisode}}
@@ -44,10 +48,6 @@
title="{{localize 'DG.ItemWindow.Motivations.AcuteEpisodeTooltip'}}" />
</span>
{{#if item.system.crossedOut }}
<span class="item-name">{{item.system.disorder}}</span>
{{/if}}
<div class="item-controls">
<a class="item-control"
data-action="itemAction"
+10
View File
@@ -0,0 +1,10 @@
<div class="dg-dialog dg-dialog--rename-profession">
<div class="dg-dialog__field form-group">
<label class="dg-dialog__field-label" for="profession-rename">{{localize "DG.ItemWindow.Profession.Name"}}</label>
<input id="profession-rename"
type="text"
name="profession-rename"
value="{{name}}"
autofocus />
</div>
</div>
+3 -1
View File
@@ -1,3 +1,4 @@
<div class="dg-dialog dg-dialog--special-training">
<form class="flexcol">
<div class="flexrow">
<label>
@@ -11,4 +12,5 @@
</label>
{{{selectElement}}}
</div>
</form>
</form>
</div>
+17
View File
@@ -0,0 +1,17 @@
<div class="dg-dialog dg-dialog--typed-skill">
<div class="dg-dialog__field form-group">
<label class="dg-dialog__field-label" for="typed-skill-group">{{localize "DG.Skills.SkillGroup"}}</label>
<select id="typed-skill-group" name="new-type-skill-group">
{{#each groups}}
<option value="{{value}}" {{#if selected}}selected{{/if}}>{{label}}</option>
{{/each}}
</select>
</div>
<div class="dg-dialog__field form-group">
<label class="dg-dialog__field-label" for="typed-skill-label">{{localize "DG.Skills.SkillName"}}</label>
<input id="typed-skill-label"
type="text"
name="new-type-skill-label"
value="{{label}}" />
</div>
</div>