From 374854cc8b72cd90b42048697636cc653080f203 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Sun, 17 May 2026 17:43:33 +0200 Subject: [PATCH] Fix as per CSV sheet tracking + creature explanation --- assets/icons/creature-trait.svg | 13 + assets/ui/icons/resonation.svg | 13 + css/mgne.css | 817 ++++++++++++++++-- fvtt-machine-gods-noxian-expanse.mjs | 21 + lang/en.json | 178 +++- less/base.less | 25 + less/chat.less | 61 ++ less/sheets.less | 672 +++++++++++++- module/applications/_module.mjs | 2 + .../applications/sheets/base-actor-sheet.mjs | 4 + .../applications/sheets/character-sheet.mjs | 18 +- .../applications/sheets/companion-sheet.mjs | 11 - module/applications/sheets/creature-sheet.mjs | 71 +- .../sheets/creature-trait-sheet.mjs | 7 + module/applications/sheets/party-sheet.mjs | 162 ++++ module/applications/sheets/select-options.mjs | 3 +- module/config/system.mjs | 29 + module/documents/actor.mjs | 15 +- module/documents/roll.mjs | 86 ++ module/models/_module.mjs | 2 + module/models/armor.mjs | 8 + module/models/artifact.mjs | 14 +- module/models/character.mjs | 28 + module/models/companion.mjs | 3 +- module/models/creature-trait.mjs | 13 + module/models/creature.mjs | 28 +- module/models/equipment.mjs | 9 + module/models/party.mjs | 20 + module/models/resonance-core.mjs | 9 + module/models/shield.mjs | 8 + module/models/weapon.mjs | 29 +- packs-system/armor/000017.log | 0 packs-system/armor/{000019.ldb => 000024.ldb} | Bin 685 -> 685 bytes packs-system/armor/000026.log | Bin 0 -> 4516 bytes packs-system/armor/CURRENT | 2 +- packs-system/armor/LOG | 15 - packs-system/armor/LOG.old | 18 +- packs-system/armor/MANIFEST-000015 | Bin 339 -> 0 bytes packs-system/armor/MANIFEST-000025 | Bin 0 -> 191 bytes packs-system/companions/000017.log | 0 .../companions/{000019.ldb => 000024.ldb} | Bin 1984 -> 1984 bytes packs-system/companions/000026.log | Bin 0 -> 9135 bytes packs-system/companions/CURRENT | 2 +- packs-system/companions/LOG | 18 +- packs-system/companions/LOG.old | 30 +- packs-system/companions/MANIFEST-000015 | Bin 360 -> 0 bytes packs-system/companions/MANIFEST-000025 | Bin 0 -> 207 bytes packs-system/features/000017.log | 0 .../features/{000019.ldb => 000024.ldb} | Bin 727 -> 727 bytes packs-system/features/000026.log | Bin 0 -> 24800 bytes packs-system/features/CURRENT | 2 +- packs-system/features/LOG | 18 +- packs-system/features/LOG.old | 30 +- packs-system/features/MANIFEST-000015 | Bin 328 -> 0 bytes packs-system/features/MANIFEST-000025 | Bin 0 -> 179 bytes packs-system/names/000018.log | 0 packs-system/names/000020.ldb | Bin 40367 -> 0 bytes packs-system/names/000025.ldb | Bin 0 -> 40426 bytes packs-system/names/000027.log | Bin 0 -> 103348 bytes packs-system/names/CURRENT | 2 +- packs-system/names/LOG | 18 +- packs-system/names/LOG.old | 30 +- packs-system/names/MANIFEST-000016 | Bin 399 -> 0 bytes packs-system/names/MANIFEST-000026 | Bin 0 -> 172 bytes packs-system/resonations/000017.log | 0 .../resonations/{000019.ldb => 000024.ldb} | Bin 910 -> 910 bytes packs-system/resonations/000026.log | Bin 0 -> 15618 bytes packs-system/resonations/CURRENT | 2 +- packs-system/resonations/LOG | 18 +- packs-system/resonations/LOG.old | 30 +- packs-system/resonations/MANIFEST-000015 | Bin 340 -> 0 bytes packs-system/resonations/MANIFEST-000025 | Bin 0 -> 192 bytes packs-system/weapons/000017.log | 0 .../weapons/{000019.ldb => 000024.ldb} | Bin 626 -> 626 bytes packs-system/weapons/000026.log | Bin 0 -> 6894 bytes packs-system/weapons/CURRENT | 2 +- packs-system/weapons/LOG | 18 +- packs-system/weapons/LOG.old | 30 +- packs-system/weapons/MANIFEST-000015 | Bin 328 -> 0 bytes packs-system/weapons/MANIFEST-000025 | Bin 0 -> 180 bytes system.json | 14 +- templates/armor.hbs | 18 +- templates/artifact.hbs | 24 +- templates/character-equipment.hbs | 67 +- templates/character-features.hbs | 2 +- templates/character-overview.hbs | 7 + templates/chat-message.hbs | 11 +- templates/companion-main.hbs | 15 - templates/creature-main.hbs | 134 +-- templates/creature-trait.hbs | 20 + templates/equipment.hbs | 17 + templates/party-loot.hbs | 37 + templates/party-main.hbs | 21 + templates/party-members.hbs | 48 + templates/party-notes.hbs | 10 + templates/party-tabs.hbs | 5 + templates/resonance-core.hbs | 19 +- templates/shield.hbs | 18 +- templates/weapon.hbs | 29 +- 99 files changed, 2716 insertions(+), 464 deletions(-) create mode 100644 assets/icons/creature-trait.svg create mode 100644 assets/ui/icons/resonation.svg create mode 100644 module/applications/sheets/creature-trait-sheet.mjs create mode 100644 module/applications/sheets/party-sheet.mjs create mode 100644 module/models/creature-trait.mjs create mode 100644 module/models/party.mjs delete mode 100644 packs-system/armor/000017.log rename packs-system/armor/{000019.ldb => 000024.ldb} (74%) create mode 100644 packs-system/armor/000026.log delete mode 100644 packs-system/armor/MANIFEST-000015 create mode 100644 packs-system/armor/MANIFEST-000025 delete mode 100644 packs-system/companions/000017.log rename packs-system/companions/{000019.ldb => 000024.ldb} (92%) create mode 100644 packs-system/companions/000026.log delete mode 100644 packs-system/companions/MANIFEST-000015 create mode 100644 packs-system/companions/MANIFEST-000025 delete mode 100644 packs-system/features/000017.log rename packs-system/features/{000019.ldb => 000024.ldb} (79%) create mode 100644 packs-system/features/000026.log delete mode 100644 packs-system/features/MANIFEST-000015 create mode 100644 packs-system/features/MANIFEST-000025 delete mode 100644 packs-system/names/000018.log delete mode 100644 packs-system/names/000020.ldb create mode 100644 packs-system/names/000025.ldb create mode 100644 packs-system/names/000027.log delete mode 100644 packs-system/names/MANIFEST-000016 create mode 100644 packs-system/names/MANIFEST-000026 delete mode 100644 packs-system/resonations/000017.log rename packs-system/resonations/{000019.ldb => 000024.ldb} (84%) create mode 100644 packs-system/resonations/000026.log delete mode 100644 packs-system/resonations/MANIFEST-000015 create mode 100644 packs-system/resonations/MANIFEST-000025 delete mode 100644 packs-system/weapons/000017.log rename packs-system/weapons/{000019.ldb => 000024.ldb} (71%) create mode 100644 packs-system/weapons/000026.log delete mode 100644 packs-system/weapons/MANIFEST-000015 create mode 100644 packs-system/weapons/MANIFEST-000025 create mode 100644 templates/creature-trait.hbs create mode 100644 templates/party-loot.hbs create mode 100644 templates/party-main.hbs create mode 100644 templates/party-members.hbs create mode 100644 templates/party-notes.hbs create mode 100644 templates/party-tabs.hbs diff --git a/assets/icons/creature-trait.svg b/assets/icons/creature-trait.svg new file mode 100644 index 0000000..a72cb72 --- /dev/null +++ b/assets/icons/creature-trait.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/ui/icons/resonation.svg b/assets/ui/icons/resonation.svg new file mode 100644 index 0000000..8663d01 --- /dev/null +++ b/assets/ui/icons/resonation.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/css/mgne.css b/css/mgne.css index 141d5a5..1b8bebd 100644 --- a/css/mgne.css +++ b/css/mgne.css @@ -167,6 +167,39 @@ border: 1px solid rgba(196, 154, 69, 0.16); border-radius: calc(8px - 4px); } +.application.mgne fieldset .editor, +.application.mgne fieldset .editor-content, +.application.mgne fieldset .ProseMirror, +.application.mgne fieldset .document-editor { + color: #d9c6ae; + background: transparent; +} +.application.mgne fieldset .editor-content p, +.application.mgne fieldset .ProseMirror p, +.application.mgne fieldset .editor-content li, +.application.mgne fieldset .ProseMirror li { + color: #d9c6ae; +} +.application.mgne fieldset .editor-content h1, +.application.mgne fieldset .ProseMirror h1, +.application.mgne fieldset .editor-content h2, +.application.mgne fieldset .ProseMirror h2, +.application.mgne fieldset .editor-content h3, +.application.mgne fieldset .ProseMirror h3 { + color: #c49a45; +} +.application.mgne fieldset .editor-content .is-empty::before, +.application.mgne fieldset .ProseMirror .is-empty::before { + color: rgba(196, 154, 69, 0.4); +} +.application.mgne fieldset .editor-menu button { + color: #ab8b68; + background: rgba(19, 16, 15, 0.55); +} +.application.mgne fieldset .editor-menu button:hover { + color: #d9c6ae; + background: rgba(196, 154, 69, 0.2); +} .application.mgne legend { font-family: "CastorTwoMGNE", "Palatino Linotype", serif; text-transform: uppercase; @@ -337,10 +370,15 @@ min-width: 0; } .application.mgne .condition-value-grid { - grid-template-columns: max-content 1fr; + grid-template-columns: max-content minmax(auto, 9rem); align-items: center; margin-bottom: 0.6rem; } +.application.mgne .condition-value-grid select { + width: auto; + min-width: 5rem; + max-width: 9rem; +} .application.mgne .condition-flag-grid { grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr)); gap: 0.3rem 0.6rem; @@ -375,7 +413,6 @@ .application.mgne .resource-box-compact > label { font-size: 0.68rem; letter-spacing: 0.11em; - color: #ab8b68; } .application.mgne .resource-box-inline { flex-direction: row; @@ -610,25 +647,6 @@ justify-content: flex-start; margin-top: 0.12rem; } -.application.mgne .resonation-blocked-banner { - display: flex; - align-items: center; - justify-content: space-between; - gap: 0.4rem; - margin-top: 0.2rem; - padding: 0.28rem 0.5rem; - border-radius: 4px; - background: rgba(180, 40, 20, 0.22); - border-left: 3px solid rgba(220, 80, 40, 0.7); - color: #e69062; - font-size: 0.73rem; -} -.application.mgne .resonation-blocked-banner .btn-clear-block { - flex-shrink: 0; - padding: 0.1rem 0.5rem; - font-size: 0.7rem; - cursor: pointer; -} .application.mgne .resource-box-actions-rest { gap: 0.32rem; flex-wrap: wrap; @@ -695,10 +713,22 @@ gap: 0.35rem; align-items: center; width: fit-content; + padding: 0.1rem 0.3rem 0.1rem 0.2rem; + border-radius: 4px; + transition: background 0.15s, color 0.15s; } .application.mgne .checkbox-line.active { - color: #dd6b2d; + color: #f5dfa0; font-weight: 600; + text-shadow: 0 0 8px rgba(196, 154, 69, 0.55); + background: rgba(196, 154, 69, 0.14); + border: 1px solid rgba(196, 154, 69, 0.28); + margin: -1px; +} +.application.mgne .checkbox-line:not(.active) { + color: #ab8b68; + border: 1px solid transparent; + margin: -1px; } .application.mgne .check-grid input[type="checkbox"], .application.mgne .checkbox-line input[type="checkbox"] { @@ -787,6 +817,572 @@ grid-template-columns: 1fr; } } +.item-weight-badge { + display: inline-flex; + align-items: center; + padding: 0 0.45em; + border-radius: 3px; + font-family: "LoraMGNE", "Book Antiqua", serif; + font-size: 0.7em; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; + white-space: nowrap; + border: 1px solid transparent; +} +.item-weight-badge.weight-trivial { + color: rgba(171, 139, 104, 0.45); + border-color: rgba(171, 139, 104, 0.2); +} +.item-weight-badge.weight-light { + color: #ab8b68; + border-color: rgba(171, 139, 104, 0.35); + background: rgba(171, 139, 104, 0.08); +} +.item-weight-badge.weight-normal { + color: #c49a45; + border-color: rgba(196, 154, 69, 0.4); + background: rgba(196, 154, 69, 0.1); +} +.item-weight-badge.weight-heavy { + color: #7f1d17; + border-color: rgba(127, 29, 23, 0.45); + background: rgba(127, 29, 23, 0.12); +} +.load-display { + font-weight: 700; + letter-spacing: 0.04em; + cursor: default; +} +.load-overloaded { + color: #7f1d17 !important; + text-shadow: 0 0 6px rgba(127, 29, 23, 0.5); +} +.resource-box-overloaded { + border-color: rgba(127, 29, 23, 0.6) !important; + background: rgba(127, 29, 23, 0.1) !important; +} +.resource-box-overloaded .resource-label-accent { + color: #7f1d17 !important; +} +.item-name[data-tooltip] { + cursor: help; +} +.item-name[data-tooltip]:hover { + text-decoration: underline dotted rgba(196, 154, 69, 0.55); +} +#tooltip.mgne-item-tooltip { + max-width: 22rem; + font-family: "LoraMGNE", "Book Antiqua", serif; + font-size: 0.82rem; + line-height: 1.5; + color: #ccb292; + background: rgba(51, 38, 30, 0.66); + border: 1px solid rgba(196, 154, 69, 0.35); + border-radius: 4px; + padding: 0.5rem 0.7rem; + box-shadow: 0 4px 14px rgba(0, 0, 0, 0.55); +} +.item-broken-badge { + display: inline-block; + margin-left: 0.3em; + padding: 0.05em 0.4em; + font-size: 0.65em; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.06em; + color: #7f1d17; + background: rgba(127, 29, 23, 0.14); + border: 1px solid rgba(127, 29, 23, 0.45); + border-radius: 3px; + vertical-align: middle; +} +.item-burned-badge { + color: #c49a45; + background: rgba(196, 154, 69, 0.12); + border-color: rgba(196, 154, 69, 0.4); +} +.item-durability-badge { + display: inline-flex; + align-items: center; + gap: 0.25em; + padding: 0.1em 0.45em; + font-size: 0.7em; + font-weight: 700; + color: rgba(171, 139, 104, 0.65); + border: 1px solid rgba(171, 139, 104, 0.2); + border-radius: 3px; + white-space: nowrap; + letter-spacing: 0.03em; +} +.item-durability-badge.durability-broken { + color: #7f1d17; + border-color: rgba(127, 29, 23, 0.4); + background: rgba(127, 29, 23, 0.1); + text-decoration: line-through; +} +.item-row-broken { + opacity: 0.6; + filter: grayscale(0.4); +} +.item-row-broken .item-name { + text-decoration: line-through; + color: rgba(204, 178, 146, 0.55); +} +.weapon-properties-grid { + display: flex; + flex-wrap: wrap; + gap: 0.35rem 0.6rem; + padding: 0.5rem 0.6rem; + background: rgba(171, 139, 104, 0.04); + border: 1px solid rgba(171, 139, 104, 0.12); + border-radius: 4px; + margin-bottom: 0.5rem; +} +.weapon-properties-grid .property-check { + display: flex; + align-items: center; + gap: 0.3em; + font-family: "LoraMGNE", "Book Antiqua", serif; + font-size: 0.82rem; + color: #ccb292; + cursor: pointer; + white-space: nowrap; + padding: 0.15em 0.4em; + border-radius: 3px; + transition: background 0.15s; +} +.weapon-properties-grid .property-check:hover { + background: rgba(196, 154, 69, 0.08); +} +.weapon-properties-grid .property-check input[type="checkbox"] { + accent-color: #c49a45; +} +.weapon-property-badge { + display: inline-block; + margin-left: 0.3em; + padding: 0.05em 0.35em; + font-size: 0.62em; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + color: rgba(196, 154, 69, 0.85); + background: rgba(196, 154, 69, 0.1); + border: 1px solid rgba(196, 154, 69, 0.3); + border-radius: 3px; + vertical-align: middle; +} +.creature-trait-trigger { + font-size: 0.82em; + color: rgba(204, 178, 146, 0.65); + font-style: italic; + margin-left: 0.2em; +} +.creature-traits-container { + border: 1px solid rgba(127, 29, 23, 0.35); + border-left: 3px solid rgba(127, 29, 23, 0.65); + border-radius: 4px; + background: linear-gradient(135deg, rgba(127, 29, 23, 0.05), transparent 60%), rgba(64, 47, 37, 0.85); + padding: 0.6rem 0.75rem; + display: flex; + flex-direction: column; + gap: 0.5rem; +} +.creature-traits-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + border-bottom: 1px solid rgba(127, 29, 23, 0.25); + padding-bottom: 0.4rem; + margin-bottom: 0.1rem; +} +.creature-traits-header h3 { + margin: 0; + font-family: "CastorTwoMGNE", "Palatino Linotype", serif; + font-size: 0.82rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + color: rgba(127, 29, 23, 0.9); +} +.creature-traits-header button { + font-size: 0.72rem; + padding: 0.15em 0.6em; + background: rgba(127, 29, 23, 0.12); + border: 1px solid rgba(127, 29, 23, 0.35); + color: rgba(127, 29, 23, 0.8); + border-radius: 3px; + cursor: pointer; + transition: background 0.15s, color 0.15s; +} +.creature-traits-header button:hover { + background: rgba(127, 29, 23, 0.22); + color: #aa271f; +} +.creature-traits-list { + display: flex; + flex-direction: column; + gap: 0.3rem; +} +.creature-trait-card { + background: rgba(19, 16, 15, 0.3); + border: 1px solid rgba(127, 29, 23, 0.2); + border-radius: 3px; + padding: 0.35rem 0.5rem; + transition: background 0.15s, border-color 0.15s; +} +.creature-trait-card:hover { + background: rgba(127, 29, 23, 0.08); + border-color: rgba(127, 29, 23, 0.35); +} +.creature-trait-card-header { + display: flex; + align-items: center; + gap: 0.5rem; + flex-wrap: wrap; +} +.creature-trait-name { + display: flex; + align-items: center; + gap: 0.35em; + font-family: "LoraMGNE", "Book Antiqua", serif; + font-size: 0.88rem; + font-weight: 600; + color: #ccb292; + flex: 1; + min-width: 0; + cursor: default; +} +.creature-trait-name i { + color: rgba(127, 29, 23, 0.7); + font-size: 0.75em; +} +.creature-trait-trigger { + font-size: 0.75rem; + font-style: italic; + color: rgba(204, 178, 146, 0.55); + white-space: nowrap; +} +.creature-trait-card .item-actions { + display: flex; + gap: 0.25rem; + margin-left: auto; + flex-shrink: 0; +} +.creature-trait-card .item-actions button { + width: 1.6rem; + height: 1.6rem; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: 1px solid rgba(171, 139, 104, 0.18); + color: rgba(171, 139, 104, 0.5); + border-radius: 3px; + cursor: pointer; + font-size: 0.72rem; + transition: background 0.15s, color 0.15s, border-color 0.15s; +} +.creature-trait-card .item-actions button:hover { + background: rgba(171, 139, 104, 0.1); + color: #ab8b68; + border-color: rgba(171, 139, 104, 0.35); +} +.creature-meta-row { + display: flex; + align-items: center; + gap: 1rem; + flex-wrap: wrap; + padding: 0.45rem 0.6rem; + background: rgba(64, 47, 37, 0.5); + border: 1px solid rgba(183, 70, 31, 0.2); + border-radius: 4px; +} +.creature-meta-label { + font-family: "CastorTwoMGNE", "Palatino Linotype", serif; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.07em; + color: rgba(183, 70, 31, 0.8); + white-space: nowrap; +} +.creature-type-group { + display: flex; + align-items: center; + gap: 0.75rem; + flex: 1; +} +.creature-type-checkbox { + display: flex; + align-items: center; + gap: 0.3em; + font-size: 0.83rem; + color: #ccb292; + cursor: pointer; + user-select: none; +} +.creature-type-checkbox input[type="checkbox"] { + accent-color: #b7461f; + width: 0.9rem; + height: 0.9rem; + cursor: pointer; +} +.creature-number-group { + display: flex; + align-items: center; + gap: 0.4rem; + flex-shrink: 0; +} +.creature-number-input { + width: 4rem; + text-align: center; + font-family: "LoraMGNE", "Book Antiqua", serif; + font-size: 0.9rem; + color: #ccb292; + background: rgba(17, 12, 10, 0.72); + border: 1px solid rgba(183, 70, 31, 0.3); + border-radius: 3px; + padding: 0.15em 0.3em; +} +.creature-number-input:focus { + outline: none; + border-color: rgba(183, 70, 31, 0.6); + background: rgba(17, 12, 10, 0.9); +} +.creature-action-table-section .action-table-drop-zone { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 0.75rem; + border-radius: 4px; + min-height: 2.4rem; + font-size: 0.88rem; + color: #ccb292; +} +.creature-action-table-section .action-table-drop-zone i { + font-size: 1em; + color: #b7461f; +} +.creature-action-table-section .action-table-drop-zone .action-table-name { + font-weight: 600; + font-family: "CastorTwoMGNE", "Palatino Linotype", serif; + color: #ccb292; +} +.creature-action-table-section .action-table-drop-zone.drop-hint { + border: 2px dashed rgba(183, 70, 31, 0.35); + background: rgba(183, 70, 31, 0.04); + color: rgba(204, 178, 146, 0.5); + font-style: italic; + justify-content: center; + cursor: default; + transition: background 0.15s, border-color 0.15s; +} +.creature-action-table-section .action-table-drop-zone.drop-hint i { + color: rgba(183, 70, 31, 0.5); +} +.creature-action-table-section .action-table-drop-zone.drop-hint:hover, +.creature-action-table-section .action-table-drop-zone.drop-hint.drag-over { + background: rgba(183, 70, 31, 0.09); + border-color: rgba(183, 70, 31, 0.6); + color: rgba(204, 178, 146, 0.7); +} +.creature-action-table-section .action-table-drop-zone.drop-hint:hover i, +.creature-action-table-section .action-table-drop-zone.drop-hint.drag-over i { + color: #b7461f; +} +.creature-action-table-section .action-table-buttons { + display: flex; + gap: 0.3rem; + align-items: center; +} +.creature-action-table-section .action-table-buttons button { + font-size: 0.75rem; + padding: 0.15em 0.55em; + background: rgba(183, 70, 31, 0.1); + border: 1px solid rgba(183, 70, 31, 0.3); + color: rgba(183, 70, 31, 0.8); + border-radius: 3px; + cursor: pointer; + transition: background 0.15s, color 0.15s; + display: flex; + align-items: center; + gap: 0.3em; +} +.creature-action-table-section .action-table-buttons button:hover { + background: rgba(183, 70, 31, 0.22); + color: #b7461f; +} +.application.mgne.party .party-credits-row { + display: flex; + align-items: center; + gap: 0.6rem; + margin-top: 0.5rem; + padding: 0.4rem 0.6rem; + border: 1px solid rgba(196, 154, 69, 0.35); + border-radius: 6px; + background: rgba(17, 12, 10, 0.7); +} +.application.mgne.party .party-credits-stepper { + display: flex; + align-items: center; + gap: 0.3rem; +} +.application.mgne.party .credits-input { + width: 5rem; + text-align: center; + font-size: 1.05rem; + font-weight: 700; + font-family: "CastorTwoMGNE", "Palatino Linotype", serif; + color: #c49a45; + background: rgba(19, 16, 15, 0.6); + border: 1px solid rgba(196, 154, 69, 0.3); + border-radius: 6px; + padding: 0.2rem 0.4rem; +} +.application.mgne.party .credits-symbol { + color: #c49a45; + font-family: "CastorTwoMGNE", "Palatino Linotype", serif; + font-size: 1.1rem; + font-weight: 700; + margin: 0 0.1rem; +} +.application.mgne.party .credits-btn { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 2rem; + padding: 0.15rem 0.4rem; + font-size: 0.75rem; + font-weight: 700; + border: 1px solid rgba(171, 139, 104, 0.28); + border-radius: 6px; + background: rgba(17, 12, 10, 0.8); + color: #ab8b68; + cursor: pointer; + user-select: none; + transition: background 0.15s, border-color 0.15s; +} +.application.mgne.party .credits-btn:hover { + background: rgba(196, 154, 69, 0.18); + border-color: rgba(196, 154, 69, 0.55); + color: #c49a45; +} +.application.mgne.party .party-member-list { + display: flex; + flex-direction: column; + gap: 0.25rem; + margin-top: 0.4rem; +} +.application.mgne.party .party-member-row { + display: grid; + grid-template-columns: 2rem 1fr 5rem 6rem 5.5rem; + gap: 0.5rem; + align-items: center; + padding: 0.3rem 0.4rem; + border-radius: 6px; +} +.application.mgne.party .party-member-row.party-member-header { + color: #7e664f; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 1px solid rgba(171, 139, 104, 0.18); + padding-bottom: 0.25rem; + margin-bottom: 0.1rem; +} +.application.mgne.party .party-member-row:not(.party-member-header) { + background: rgba(17, 12, 10, 0.75); + border: 1px solid transparent; +} +.application.mgne.party .party-member-row:not(.party-member-header):hover { + border-color: rgba(196, 154, 69, 0.22); + background: rgba(17, 12, 10, 0.9); +} +.application.mgne.party .party-member-portrait { + width: 2rem; + height: 2rem; + object-fit: cover; + border-radius: 3px; + border: 1px solid rgba(171, 139, 104, 0.25); +} +.application.mgne.party .party-member-name a { + color: #ccb292; + font-weight: 700; + font-size: 0.9rem; +} +.application.mgne.party .party-member-name a:hover { + color: #c49a45; +} +.application.mgne.party .party-member-hp { + color: #dd6b2d; + font-family: "CastorTwoMGNE", "Palatino Linotype", serif; + font-size: 0.82rem; + font-weight: 700; + text-align: center; +} +.application.mgne.party .party-member-type { + color: #7e664f; + font-size: 0.78rem; + font-style: italic; +} +.application.mgne.party .party-loot-list { + display: flex; + flex-direction: column; + gap: 0.25rem; + margin-top: 0.4rem; +} +.application.mgne.party .party-loot-row { + display: grid; + grid-template-columns: 2rem 1fr 7rem 4rem; + gap: 0.5rem; + align-items: center; + padding: 0.3rem 0.4rem; + border-radius: 6px; +} +.application.mgne.party .party-loot-row.party-loot-header { + color: #7e664f; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 1px solid rgba(171, 139, 104, 0.18); + padding-bottom: 0.25rem; + margin-bottom: 0.1rem; +} +.application.mgne.party .party-loot-row:not(.party-loot-header) { + background: rgba(17, 12, 10, 0.75); + border: 1px solid transparent; +} +.application.mgne.party .party-loot-row:not(.party-loot-header):hover { + border-color: rgba(196, 154, 69, 0.22); + background: rgba(17, 12, 10, 0.9); +} +.application.mgne.party .item-portrait { + width: 2rem; + height: 2rem; + object-fit: cover; + border-radius: 3px; + border: 1px solid rgba(171, 139, 104, 0.25); +} +.application.mgne.party .item-type-label { + color: #7e664f; + font-size: 0.78rem; + font-style: italic; +} +.application.mgne.party .party-drop-hint { + color: rgba(126, 102, 79, 0.7); + font-size: 0.75rem; + font-style: italic; + text-align: center; + margin-top: 0.5rem; + padding: 0.3rem; + border: 1px dashed rgba(171, 139, 104, 0.18); + border-radius: 6px; +} .application.mgne.roll-dialog .window-content { padding: 0.55rem; background: radial-gradient(circle at top left, rgba(221, 107, 45, 0.14), transparent 26%), linear-gradient(180deg, rgba(27, 21, 18, 0.26), rgba(19, 16, 15, 0.22)), url("../assets/ui/page_background.webp") center center / cover no-repeat, linear-gradient(180deg, #1b1512, #13100f 120%); @@ -895,52 +1491,117 @@ } .mgne-chat-card .chat-formula { color: #52453c; - font-size: 0.72rem; - font-style: italic; - margin: 0; } .mgne-chat-card .chat-formula code { - color: #ab8b68; - background: rgba(19, 16, 15, 0.65); - padding: 0.08em 0.38em; + color: #ccb292; + background: rgba(19, 16, 15, 0.75); + padding: 0.1em 0.42em; border-radius: 3px; - font-style: normal; } -.mgne-chat-card .chat-outcome { +.mgne-chat-card .chat-result-line { display: flex; justify-content: space-between; - align-items: center; - gap: 0.6rem; + align-items: end; + padding: 0.38rem 0.55rem; + border: 1px solid rgba(196, 154, 69, 0.28); + border-radius: 6px; + background: rgba(19, 16, 15, 0.78); +} +.mgne-chat-card .chat-result-label { + font-family: "CastorTwoMGNE", "Palatino Linotype", serif; + text-transform: uppercase; + letter-spacing: 0.08em; + font-size: 0.62rem; + color: #ccb292; +} +.mgne-chat-card .chat-result-total { + font-family: "CastorTwoMGNE", "Palatino Linotype", serif; + font-size: 1.08rem; + color: #ccb292; +} +.mgne-chat-card .chat-outcome.has-tooltip, +.mgne-chat-card .chat-damage-total.has-tooltip { + cursor: pointer; + user-select: none; +} +.mgne-chat-card .chat-outcome.has-tooltip:hover, +.mgne-chat-card .chat-damage-total.has-tooltip:hover { + filter: brightness(1.12); +} +.mgne-chat-card .chat-outcome .chat-tooltip-icon, +.mgne-chat-card .chat-damage-total .chat-tooltip-icon { + opacity: 0.55; + font-size: 0.75em; + margin-left: 0.3rem; + vertical-align: middle; + transition: opacity 0.15s; +} +.mgne-chat-card .chat-outcome.tooltip-open .chat-tooltip-icon, +.mgne-chat-card .chat-damage-total.tooltip-open .chat-tooltip-icon { + opacity: 1; +} +.mgne-chat-card .chat-dice-tooltip { + margin-top: 0.4rem; + padding: 0.4rem 0.55rem; + background: rgba(19, 16, 15, 0.85); + border: 1px solid rgba(171, 139, 104, 0.22); + border-radius: 6px; +} +.mgne-chat-card .chat-dice-tooltip .dice-roll { + display: flex; + flex-direction: column; + gap: 0.2rem; +} +.mgne-chat-card .chat-dice-tooltip .dice-formula { + font-family: "Courier New", monospace; + font-size: 0.72rem; + color: rgba(204, 178, 146, 0.65); +} +.mgne-chat-card .chat-dice-tooltip .dice-tooltip { + font-size: 0.78rem; +} +.mgne-chat-card .chat-dice-tooltip .dice { + margin: 0.15rem 0; +} +.mgne-chat-card .chat-dice-tooltip .die-icon, +.mgne-chat-card .chat-dice-tooltip .die-face { + color: #c49a45; + font-size: 0.8rem; +} +.mgne-chat-card .chat-dice-tooltip .part-formula { + color: rgba(204, 178, 146, 0.7); + font-size: 0.72rem; +} +.mgne-chat-card .chat-dice-tooltip .part-total { + color: #ccb292; + font-weight: 600; +} +.mgne-chat-card .chat-dice-tooltip .max { + color: #82b0a6; +} +.mgne-chat-card .chat-dice-tooltip .min { + color: #e48a59; +} +.mgne-chat-card .chat-dice-tooltip .dice-total { + font-family: "CastorTwoMGNE", serif; + font-size: 1.05rem; + color: #c49a45; + text-align: right; + border-top: 1px solid rgba(171, 139, 104, 0.2); + padding-top: 0.2rem; + margin-top: 0.15rem; +} +.mgne-chat-card .chat-outcome { + font-family: "CastorTwoMGNE", "Palatino Linotype", serif; + text-transform: uppercase; + letter-spacing: 0.08em; margin: 0; - padding: 0.42rem 0.65rem 0.42rem 0.8rem; + padding: 0.3rem 0.55rem; border-radius: 6px; background: rgba(19, 16, 15, 0.72); border-left: 3px solid rgba(221, 107, 45, 0.7); -} -.mgne-chat-card .chat-outcome-label { - font-family: "CastorTwoMGNE", "Palatino Linotype", serif; - text-transform: uppercase; - letter-spacing: 0.1em; - font-size: 0.88rem; color: #e69062; - line-height: 1.1; -} -.mgne-chat-card .chat-outcome-total { - font-family: "CastorTwoMGNE", "Palatino Linotype", serif; - font-size: 1.7rem; - line-height: 1; - color: rgba(204, 178, 146, 0.88); - text-shadow: 0 0 18px rgba(221, 107, 45, 0.18); - flex-shrink: 0; -} -.mgne-chat-card .chat-damage-total { - text-align: center; - font-family: "CastorTwoMGNE", "Palatino Linotype", serif; - font-size: 2.2rem; - line-height: 1; - color: #e38450; - text-shadow: 0 0 20px rgba(183, 70, 31, 0.3); - padding: 0.3rem 0; + font-size: 0.8rem; } .mgne-chat-card .chat-special { padding: 0.42rem 0.55rem; @@ -948,26 +1609,6 @@ background: rgba(17, 12, 10, 0.85); color: #ccb292; } -.mgne-chat-card .chat-omen-remind { - padding: 0.38rem 0.55rem; - border-left: 3px solid rgba(196, 154, 69, 0.6); - background: rgba(30, 22, 8, 0.82); - color: #c9a84c; - font-size: 0.75rem; - margin: 0; - font-style: italic; -} -.mgne-chat-card .chat-omen-neutralize { - border-left-color: rgba(79, 125, 115, 0.7); - color: #9bc0b8; -} -.mgne-chat-card .chat-omen-used { - padding: 0.28rem 0.55rem; - color: #c9a84c; - font-size: 0.74rem; - margin: 0; - font-style: italic; -} .mgne-chat-card.outcome-critical-success, .mgne-chat-card.outcome-success, .mgne-chat-card.outcome-steady { @@ -976,18 +1617,8 @@ .mgne-chat-card.outcome-critical-success .chat-outcome, .mgne-chat-card.outcome-success .chat-outcome, .mgne-chat-card.outcome-steady .chat-outcome { - border-left-color: rgba(79, 125, 115, 0.8); -} -.mgne-chat-card.outcome-critical-success .chat-outcome-label, -.mgne-chat-card.outcome-success .chat-outcome-label, -.mgne-chat-card.outcome-steady .chat-outcome-label { color: #9bc0b8; -} -.mgne-chat-card.outcome-critical-success .chat-outcome-total, -.mgne-chat-card.outcome-success .chat-outcome-total, -.mgne-chat-card.outcome-steady .chat-outcome-total { - color: rgba(155, 192, 184, 0.9); - text-shadow: 0 0 18px rgba(79, 125, 115, 0.3); + border-left-color: rgba(79, 125, 115, 0.8); } .mgne-chat-card.outcome-failure, .mgne-chat-card.outcome-broken, @@ -997,15 +1628,11 @@ .mgne-chat-card.outcome-failure .chat-outcome, .mgne-chat-card.outcome-broken .chat-outcome, .mgne-chat-card.outcome-fumble .chat-outcome { + color: #eaa37c; border-left-color: rgba(221, 107, 45, 0.8); } -.mgne-chat-card.outcome-failure .chat-outcome-label, -.mgne-chat-card.outcome-broken .chat-outcome-label, -.mgne-chat-card.outcome-fumble .chat-outcome-label { - color: #eaa37c; -} -.mgne-chat-card.mode-apply-damage .chat-damage-total, -.mgne-chat-card.mode-damage .chat-damage-total { +.mgne-chat-card.mode-apply-damage .chat-result-total, +.mgne-chat-card.mode-damage .chat-result-total { color: #e38450; } .mgne-chat-card .chat-card-actions { diff --git a/fvtt-machine-gods-noxian-expanse.mjs b/fvtt-machine-gods-noxian-expanse.mjs index 8ac472c..efe755d 100644 --- a/fvtt-machine-gods-noxian-expanse.mjs +++ b/fvtt-machine-gods-noxian-expanse.mjs @@ -20,6 +20,7 @@ Hooks.once("init", () => { character: models.MGNECharacter, creature: models.MGNECreature, companion: models.MGNECompanion, + party: models.MGNEParty, } CONFIG.Combat.documentClass = documents.MGNECombat @@ -32,6 +33,7 @@ Hooks.once("init", () => { "resonance-core": models.MGNEResonanceCore, artifact: models.MGNEArtifact, feature: models.MGNEFeature, + "creature-trait": models.MGNECreatureTrait, } foundry.applications.sheets.ActorSheetV2 && foundry.documents.collections.Actors.unregisterSheet( @@ -43,6 +45,7 @@ Hooks.once("init", () => { foundry.documents.collections.Actors.registerSheet(SYSTEM_ID, applications.MGNECharacterSheet, { types: ["character"], makeDefault: true, label: SYSTEM.actorTypes.character.label }) foundry.documents.collections.Actors.registerSheet(SYSTEM_ID, applications.MGNECreatureSheet, { types: ["creature"], makeDefault: true, label: SYSTEM.actorTypes.creature.label }) foundry.documents.collections.Actors.registerSheet(SYSTEM_ID, applications.MGNECompanionSheet, { types: ["companion"], makeDefault: true, label: SYSTEM.actorTypes.companion.label }) + foundry.documents.collections.Actors.registerSheet(SYSTEM_ID, applications.MGNEPartySheet, { types: ["party"], makeDefault: true, label: SYSTEM.actorTypes.party.label }) foundry.applications.sheets.ItemSheetV2 && foundry.documents.collections.Items.unregisterSheet( "core", @@ -57,8 +60,15 @@ Hooks.once("init", () => { foundry.documents.collections.Items.registerSheet(SYSTEM_ID, applications.MGNEResonanceCoreSheet, { types: ["resonance-core"], makeDefault: true, label: SYSTEM.itemTypes["resonance-core"].label }) foundry.documents.collections.Items.registerSheet(SYSTEM_ID, applications.MGNEArtifactSheet, { types: ["artifact"], makeDefault: true, label: SYSTEM.itemTypes.artifact.label }) foundry.documents.collections.Items.registerSheet(SYSTEM_ID, applications.MGNEFeatureSheet, { types: ["feature"], makeDefault: true, label: SYSTEM.itemTypes.feature.label }) + foundry.documents.collections.Items.registerSheet(SYSTEM_ID, applications.MGNECreatureTraitSheet, { types: ["creature-trait"], makeDefault: true, label: SYSTEM.itemTypes["creature-trait"].label }) Handlebars.registerHelper("isEqual", (left, right) => left === right) + Handlebars.registerHelper("includes", (collection, value) => { + if (!collection) return false + if (collection instanceof Set) return collection.has(value) + if (Array.isArray(collection)) return collection.includes(value) + return false + }) }) Hooks.once("setup", () => { @@ -111,6 +121,17 @@ Hooks.on("renderChatMessageHTML", (message, element) => { const root = element instanceof HTMLElement ? element : element?.[0] if (!root) return + // Dice tooltip toggle + root.querySelectorAll("[data-action='toggle-dice-tooltip']").forEach(trigger => { + trigger.addEventListener("click", () => { + const tooltip = trigger.closest(".chat-card-body")?.querySelector(".chat-dice-tooltip") + if (!tooltip) return + const isHidden = tooltip.hidden + tooltip.hidden = !isHidden + trigger.classList.toggle("tooltip-open", isHidden) + }) + }) + root.querySelectorAll(".mgne-roll-damage-btn").forEach(btn => { btn.addEventListener("click", async () => { const actorId = btn.dataset.actorId diff --git a/lang/en.json b/lang/en.json index 3beb84e..54e2dd7 100644 --- a/lang/en.json +++ b/lang/en.json @@ -4,7 +4,8 @@ "ActorTypes": { "character": "Character", "creature": "Creature", - "companion": "Companion" + "companion": "Companion", + "party": "Party" }, "ItemTypes": { "weapon": "Weapon", @@ -13,7 +14,8 @@ "equipment": "Equipment", "resonance-core": "Resonance Core", "artifact": "Artifact", - "feature": "Feature" + "feature": "Feature", + "creature-trait": "Creature Trait" }, "Abilities": { "agility": "Agility", @@ -37,6 +39,24 @@ "melee": "Melee", "ranged": "Ranged" }, + "WeaponProperties": { + "ammo": "Ammo", + "awkward": "Awkward", + "binding": "Binding", + "durant": "Durant", + "finesse": "Finesse", + "fling": "Fling", + "fragile": "Fragile", + "glinting": "Glinting", + "overbearing": "Overbearing", + "parrying": "Parrying", + "precise": "Precise", + "razored": "Razored", + "ringing": "Ringing", + "two-handed": "Two-Handed", + "unwieldy": "Unwieldy", + "versatile": "Versatile" + }, "Resonations": { "accelerate": "Accelerate", "blast": "Blast", @@ -71,7 +91,9 @@ "daily": "Daily Resources", "equipment": "Equipment", "features": "Features", - "notes": "Notes" + "notes": "Notes", + "members": "Members", + "loot": "Loot" }, "Character": { "Background": "Background", @@ -92,6 +114,7 @@ "ResonancePerDay": "Resonance per Day", "ArtifactSync": "Artifact Sync", "CarryingCapacity": "Carrying Capacity", + "Load": "Load", "Rations": "Rations", "Kiffol": "Kiffol", "Weapons": "Weapons", @@ -231,22 +254,23 @@ }, "Creature": { "Special": "Special", + "Traits": "Traits", + "AddTrait": "Add Trait", + "Type": "Type", + "Number": "Number", + "ActionTable": "Action Table", + "RollAction": "Roll Action", + "DropTableHint": "Drop a Roll Table here to link it", + "ClearTable": "Clear", + "OpenTable": "Open Table", + "NoTableLinked": "No action table is linked to this creature.", + "TableNotFound": "The linked action table could not be found.", + "Types": { + "Human": "Human", + "Construct": "Construct", + "Animal": "Animal" + }, "FIELDS": { - "abilities": { - "label": "Abilities", - "agility": { - "label": "Agility" - }, - "presence": { - "label": "Presence" - }, - "strength": { - "label": "Strength" - }, - "toughness": { - "label": "Toughness" - } - }, "hp": { "label": "HP", "value": { @@ -265,20 +289,17 @@ "label": "Armor Die" } }, - "attack": { - "label": "Attack", - "damage": { - "label": "Damage" - } + "creatureType": { + "label": "Type" + }, + "number": { + "label": "Number" + }, + "actionTableUuid": { + "label": "Action Table" }, "description": { "label": "Description" - }, - "special": { - "label": "Special" - }, - "notes": { - "label": "Notes" } } }, @@ -354,6 +375,27 @@ } } }, + "Party": { + "Members": "Members", + "Loot": "Shared Loot", + "Credits": "Credits", + "MoveUp": "Move Up", + "MoveDown": "Move Down", + "RemoveMember": "Remove Member", + "DropMemberHint": "Drop a Character or Companion actor here to add them to the party.", + "DropLootHint": "Drop items here to add them to the shared loot.", + "FIELDS": { + "memberRefs": { + "label": "Members" + }, + "credits": { + "label": "Credits" + }, + "notes": { + "label": "Notes" + } + } + }, "DataModel": { "abilities": { "agility": { @@ -373,6 +415,7 @@ "Common": { "Attack": "Attack", "ArmorDie": "Armor Die", + "ArmorSave": "Armor Save", "ArtifactId": "Artifact Id", "Broken": "Broken", "BurnedOut": "Burned Out", @@ -383,6 +426,7 @@ "Current": "Current", "Damage": "Damage", "Depleted": "Depleted", + "Durability": "Durability", "Defense": "Defense", "Delete": "Delete", "Description": "Description", @@ -416,15 +460,23 @@ "Unsynchronized": "Unsynchronized", "Usage": "Usage", "UsageDie": "Usage Die", + "DurabilityDie": "Durability Die", + "RollDurability": "Roll Durability", "Used": "Used", - "Value": "Value" + "Value": "Value", + "Weight": "Weight", + "Name": "Name", + "Type": "Type" }, "Empty": { "NoArtifacts": "No artifacts yet.", "NoEquipment": "No equipment yet.", "NoFeatures": "No features yet.", "NoResonanceCores": "No resonance cores yet.", - "NoWeapons": "No weapons yet." + "NoTraits": "No traits yet.", + "NoWeapons": "No weapons yet.", + "NoMembers": "No members yet. Drop a character or companion here.", + "NoLoot": "No shared loot yet. Drop items here." }, "RulesSnapshot": { "Checks": "Checks use d20 + ability vs DR.", @@ -462,6 +514,8 @@ "ItemBroken": "{item} is broken.", "ItemBurnedOut": "{item} is burned out.", "ItemDepleted": "{item} is already depleted.", + "ItemDurabilityDepleted": "{item} durability is already depleted.", + "NoArmorEquipped": "No armor or shield equipped.", "ResonancePerDayReached": "{actor} has already used all resonations for today.", "ResonationBlocked": "{actor} cannot invoke Resonations — feedback block active (1 hour). Clear it manually once the hour has passed.", "ResonationFeedbackBlocked": "Feedback! {actor} suffers D2 damage (bypasses armor) and cannot invoke Resonations for 1 hour.", @@ -473,6 +527,7 @@ "ApplyDamageTo": "Apply {amount} damage to {target}", "AppliedDamageText": "Applied damage: {amount}.", "ArmorAbsorbed": "Armor absorbed {amount}.", + "ArmorSave": "Armor Save", "ArmorDegradedCritical": "Critical: {item} armor downgraded to {die}.", "ArmorNothingToDegrade": "Critical: no armor to downgrade.", "AttackFumble": "Attack fumble: the weapon breaks.", @@ -504,6 +559,9 @@ "ItemAttackLabel": "{item} Attack", "ItemDamageLabel": "{item} Damage", "ItemNowDepleted": "The item is depleted.", + "ItemNowBroken": "The item is now broken.", + "ItemDurabilityLabel": "{item} Durability", + "DurabilityLabel": "{item} Durability Check", "ItemUsageLabel": "{item} Usage", "MoraleBrokenText": "The actor breaks down and may flee, surrender, or grant +d4 damage to opponents.", "MoraleCheck": "Morale Check", @@ -536,8 +594,10 @@ "Mode": { "action": "Action", "apply-damage": "Damage", + "armor": "Armor", "check": "Check", "damage": "Damage", + "durability": "Durability", "flee": "Fleeing", "generic": "Roll", "morale": "Morale", @@ -573,6 +633,12 @@ }, "broken": { "label": "Broken" + }, + "durabilityDie": { + "label": "Durability Die" + }, + "weight": { + "label": "Weight" } } }, @@ -592,6 +658,12 @@ }, "broken": { "label": "Broken" + }, + "durabilityDie": { + "label": "Durability Die" + }, + "weight": { + "label": "Weight" } } }, @@ -611,6 +683,12 @@ }, "broken": { "label": "Broken" + }, + "durabilityDie": { + "label": "Durability Die" + }, + "weight": { + "label": "Weight" } } }, @@ -636,6 +714,15 @@ }, "consumable": { "label": "Consumable" + }, + "broken": { + "label": "Broken" + }, + "durabilityDie": { + "label": "Durability Die" + }, + "weight": { + "label": "Weight" } } }, @@ -652,6 +739,15 @@ }, "burnedOut": { "label": "Burned Out" + }, + "broken": { + "label": "Broken" + }, + "durabilityDie": { + "label": "Durability Die" + }, + "weight": { + "label": "Weight" } } }, @@ -674,6 +770,12 @@ }, "synchronizedTo": { "label": "Synchronized To" + }, + "durabilityDie": { + "label": "Durability Die" + }, + "weight": { + "label": "Weight" } } }, @@ -686,13 +788,22 @@ "label": "Feature Id" } } + }, + "CreatureTrait": { + "Trigger": "Trigger", + "TriggerPlaceholder": "e.g. When the creature attacks, on a critical hit…", + "FIELDS": { + "description": { "label": "Description" }, + "trigger": { "label": "Trigger" } + } } }, "TYPES": { "Actor": { "character": "Character", "creature": "Creature", - "companion": "Companion" + "companion": "Companion", + "party": "Party" }, "Item": { "weapon": "Weapon", @@ -701,7 +812,8 @@ "equipment": "Equipment", "resonance-core": "Resonance Core", "artifact": "Artifact", - "feature": "Feature" + "feature": "Feature", + "creature-trait": "Creature Trait" } } } diff --git a/less/base.less b/less/base.less index 78002de..13fa953 100644 --- a/less/base.less +++ b/less/base.less @@ -157,6 +157,31 @@ margin: 0; } +// ProseMirror / toggled editor inside fieldset — enforce contrast on dark bg +.application.mgne fieldset { + .editor, + .editor-content, + .ProseMirror, + .document-editor { + color: lighten(@parchment, 8%); + background: transparent; + } + .editor-content, + .ProseMirror { + p, li { color: lighten(@parchment, 8%); } + h1, h2, h3 { color: @gold-acid; } + .is-empty::before { color: fade(@gold-acid, 40%); } + } + .editor-menu button { + color: @bone; + background: fade(@bg-void, 55%); + &:hover { + color: lighten(@parchment, 8%); + background: fade(@gold-acid, 20%); + } + } +} + .application.mgne legend { .caps-heading(); color: @gold-acid; diff --git a/less/chat.less b/less/chat.less index 5b47304..ce7c19e 100644 --- a/less/chat.less +++ b/less/chat.less @@ -85,6 +85,67 @@ color: @parchment; } +.mgne-chat-card .chat-outcome, +.mgne-chat-card .chat-damage-total { + &.has-tooltip { + cursor: pointer; + user-select: none; + &:hover { filter: brightness(1.12); } + } + .chat-tooltip-icon { + opacity: 0.55; + font-size: 0.75em; + margin-left: 0.3rem; + vertical-align: middle; + transition: opacity 0.15s; + } + &.tooltip-open .chat-tooltip-icon { opacity: 1; } +} + +// Dice tooltip reveal panel +.mgne-chat-card .chat-dice-tooltip { + margin-top: 0.4rem; + padding: 0.4rem 0.55rem; + background: fade(@bg-void, 85%); + border: 1px solid fade(@bone, 22%); + border-radius: @radius-sm; + + // Foundry's standard dice-roll markup + .dice-roll { + display: flex; + flex-direction: column; + gap: 0.2rem; + } + .dice-formula { + font-family: "Courier New", monospace; + font-size: 0.72rem; + color: fade(@parchment, 65%); + } + .dice-tooltip { + font-size: 0.78rem; + } + .dice { + margin: 0.15rem 0; + } + .die-icon, .die-face { + color: @gold-acid; + font-size: 0.8rem; + } + .part-formula { color: fade(@parchment, 70%); font-size: 0.72rem; } + .part-total { color: @parchment; font-weight: 600; } + .max { color: lighten(@verdigris, 20%); } + .min { color: lighten(@ember-bright, 10%); } + .dice-total { + font-family: "CastorTwoMGNE", serif; + font-size: 1.05rem; + color: @gold-acid; + text-align: right; + border-top: 1px solid fade(@bone, 20%); + padding-top: 0.2rem; + margin-top: 0.15rem; + } +} + .mgne-chat-card .chat-outcome { .caps-heading(); margin: 0; diff --git a/less/sheets.less b/less/sheets.less index e3ec222..a37094e 100644 --- a/less/sheets.less +++ b/less/sheets.less @@ -123,9 +123,15 @@ } .application.mgne .condition-value-grid { - grid-template-columns: max-content 1fr; + grid-template-columns: max-content minmax(auto, 9rem); align-items: center; margin-bottom: 0.6rem; + + select { + width: auto; + min-width: 5rem; + max-width: 9rem; + } } .application.mgne .condition-flag-grid { @@ -530,10 +536,23 @@ gap: 0.35rem; align-items: center; width: fit-content; + padding: 0.1rem 0.3rem 0.1rem 0.2rem; + border-radius: 4px; + transition: background 0.15s, color 0.15s; &.active { - color: @ember-bright; + color: #f5dfa0; font-weight: 600; + text-shadow: 0 0 8px fade(@gold-acid, 55%); + background: fade(@gold-acid, 14%); + border: 1px solid fade(@gold-acid, 28%); + margin: -1px; // compensate border so layout doesn't shift + } + + &:not(.active) { + color: @bone; + border: 1px solid transparent; + margin: -1px; } } @@ -641,3 +660,652 @@ grid-template-columns: 1fr; } } + +// ─── Weight badges ──────────────────────────────────────────────────────────── +.item-weight-badge { + display: inline-flex; + align-items: center; + padding: 0 0.45em; + border-radius: 3px; + font-family: @font-body; + font-size: 0.7em; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; + white-space: nowrap; + border: 1px solid transparent; + + &.weight-trivial { + color: fade(@bone, 45%); + border-color: fade(@bone, 20%); + } + + &.weight-light { + color: @bone; + border-color: fade(@bone, 35%); + background: fade(@bone, 8%); + } + + &.weight-normal { + color: @gold-acid; + border-color: fade(@gold-acid, 40%); + background: fade(@gold-acid, 10%); + } + + &.weight-heavy { + color: @blood; + border-color: fade(@blood, 45%); + background: fade(@blood, 12%); + } +} + +// ─── Load display ───────────────────────────────────────────────────────────── +.load-display { + font-weight: 700; + letter-spacing: 0.04em; + cursor: default; +} + +.load-overloaded { + color: @blood !important; + text-shadow: 0 0 6px fade(@blood, 50%); +} + +.resource-box-overloaded { + border-color: fade(@blood, 60%) !important; + background: fade(@blood, 10%) !important; + + .resource-label-accent { + color: @blood !important; + } +} + +// ─── Item description tooltip ───────────────────────────────────────────────── +.item-name[data-tooltip] { + cursor: help; + &:hover { text-decoration: underline dotted fade(@gold-acid, 55%); } +} + +#tooltip.mgne-item-tooltip { + max-width: 22rem; + font-family: @font-body; + font-size: 0.82rem; + line-height: 1.5; + color: @parchment; + background: darken(@bg-panel-soft, 4%); + border: 1px solid fade(@gold-acid, 35%); + border-radius: 4px; + padding: 0.5rem 0.7rem; + box-shadow: 0 4px 14px fade(#000, 55%); +} + +// ─── Broken / Durability badges ─────────────────────────────────────────────── +.item-broken-badge { + display: inline-block; + margin-left: 0.3em; + padding: 0.05em 0.4em; + font-size: 0.65em; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.06em; + color: @blood; + background: fade(@blood, 14%); + border: 1px solid fade(@blood, 45%); + border-radius: 3px; + vertical-align: middle; +} + +.item-burned-badge { + color: @gold-acid; + background: fade(@gold-acid, 12%); + border-color: fade(@gold-acid, 40%); +} + +.item-durability-badge { + display: inline-flex; + align-items: center; + gap: 0.25em; + padding: 0.1em 0.45em; + font-size: 0.7em; + font-weight: 700; + color: fade(@bone, 65%); + border: 1px solid fade(@bone, 20%); + border-radius: 3px; + white-space: nowrap; + letter-spacing: 0.03em; + + &.durability-broken { + color: @blood; + border-color: fade(@blood, 40%); + background: fade(@blood, 10%); + text-decoration: line-through; + } +} + +.item-row-broken { + opacity: 0.6; + filter: grayscale(0.4); + + .item-name { + text-decoration: line-through; + color: fade(@parchment, 55%); + } +} + +// ─── Weapon properties ──────────────────────────────────────────────────────── +.weapon-properties-grid { + display: flex; + flex-wrap: wrap; + gap: 0.35rem 0.6rem; + padding: 0.5rem 0.6rem; + background: fade(@bone, 4%); + border: 1px solid fade(@bone, 12%); + border-radius: 4px; + margin-bottom: 0.5rem; + + .property-check { + display: flex; + align-items: center; + gap: 0.3em; + font-family: @font-body; + font-size: 0.82rem; + color: @parchment; + cursor: pointer; + white-space: nowrap; + padding: 0.15em 0.4em; + border-radius: 3px; + transition: background 0.15s; + + &:hover { background: fade(@gold-acid, 8%); } + + input[type="checkbox"] { accent-color: @gold-acid; } + } +} + +.weapon-property-badge { + display: inline-block; + margin-left: 0.3em; + padding: 0.05em 0.35em; + font-size: 0.62em; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + color: fade(@gold-acid, 85%); + background: fade(@gold-acid, 10%); + border: 1px solid fade(@gold-acid, 30%); + border-radius: 3px; + vertical-align: middle; +} + +// ─── Creature trait trigger ─────────────────────────────────────────────────── +.creature-trait-trigger { + font-size: 0.82em; + color: fade(@parchment, 65%); + font-style: italic; + margin-left: 0.2em; +} + +// ─── Creature traits container ──────────────────────────────────────────────── +.creature-traits-container { + border: 1px solid fade(@blood, 35%); + border-left: 3px solid fade(@blood, 65%); + border-radius: 4px; + background: linear-gradient(135deg, fade(@blood, 5%), transparent 60%), + fade(@bg-panel-soft, 85%); + padding: 0.6rem 0.75rem; + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.creature-traits-header { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + border-bottom: 1px solid fade(@blood, 25%); + padding-bottom: 0.4rem; + margin-bottom: 0.1rem; + + h3 { + margin: 0; + font-family: @font-display; + font-size: 0.82rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.08em; + color: fade(@blood, 90%); + } + + button { + font-size: 0.72rem; + padding: 0.15em 0.6em; + background: fade(@blood, 12%); + border: 1px solid fade(@blood, 35%); + color: fade(@blood, 80%); + border-radius: 3px; + cursor: pointer; + transition: background 0.15s, color 0.15s; + + &:hover { + background: fade(@blood, 22%); + color: lighten(@blood, 10%); + } + } +} + +.creature-traits-list { + display: flex; + flex-direction: column; + gap: 0.3rem; +} + +.creature-trait-card { + background: fade(@bg-void, 30%); + border: 1px solid fade(@blood, 20%); + border-radius: 3px; + padding: 0.35rem 0.5rem; + transition: background 0.15s, border-color 0.15s; + + &:hover { + background: fade(@blood, 8%); + border-color: fade(@blood, 35%); + } +} + +.creature-trait-card-header { + display: flex; + align-items: center; + gap: 0.5rem; + flex-wrap: wrap; +} + +.creature-trait-name { + display: flex; + align-items: center; + gap: 0.35em; + font-family: @font-body; + font-size: 0.88rem; + font-weight: 600; + color: @parchment; + flex: 1; + min-width: 0; + cursor: default; + + i { color: fade(@blood, 70%); font-size: 0.75em; } +} + +.creature-trait-trigger { + font-size: 0.75rem; + font-style: italic; + color: fade(@parchment, 55%); + white-space: nowrap; +} + +.creature-trait-card .item-actions { + display: flex; + gap: 0.25rem; + margin-left: auto; + flex-shrink: 0; + + button { + width: 1.6rem; + height: 1.6rem; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: 1px solid fade(@bone, 18%); + color: fade(@bone, 50%); + border-radius: 3px; + cursor: pointer; + font-size: 0.72rem; + transition: background 0.15s, color 0.15s, border-color 0.15s; + + &:hover { + background: fade(@bone, 10%); + color: @bone; + border-color: fade(@bone, 35%); + } + } +} + +// ============================================================ +// CREATURE SHEET — META ROW + ACTION TABLE +// ============================================================ + +.creature-meta-row { + display: flex; + align-items: center; + gap: 1rem; + flex-wrap: wrap; + padding: 0.45rem 0.6rem; + background: fade(@bg-panel-soft, 50%); + border: 1px solid fade(@ember, 20%); + border-radius: 4px; +} + +.creature-meta-label { + font-family: @font-display; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.07em; + color: fade(@ember, 80%); + white-space: nowrap; +} + +.creature-type-group { + display: flex; + align-items: center; + gap: 0.75rem; + flex: 1; +} + +.creature-type-checkbox { + display: flex; + align-items: center; + gap: 0.3em; + font-size: 0.83rem; + color: @parchment; + cursor: pointer; + user-select: none; + + input[type="checkbox"] { + accent-color: @ember; + width: 0.9rem; + height: 0.9rem; + cursor: pointer; + } +} + +.creature-number-group { + display: flex; + align-items: center; + gap: 0.4rem; + flex-shrink: 0; +} + +.creature-number-input { + width: 4rem; + text-align: center; + font-family: @font-body; + font-size: 0.9rem; + color: @parchment; + background: @bg-input; + border: 1px solid fade(@ember, 30%); + border-radius: 3px; + padding: 0.15em 0.3em; + + &:focus { + outline: none; + border-color: fade(@ember, 60%); + background: fade(@bg-input, 90%); + } +} + +.creature-action-table-section { + .action-table-drop-zone { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 0.75rem; + border-radius: 4px; + min-height: 2.4rem; + font-size: 0.88rem; + color: @parchment; + + i { font-size: 1em; color: @ember; } + + .action-table-name { + font-weight: 600; + font-family: @font-display; + color: @parchment; + } + + &.drop-hint { + border: 2px dashed fade(@ember, 35%); + background: fade(@ember, 4%); + color: fade(@parchment, 50%); + font-style: italic; + justify-content: center; + cursor: default; + transition: background 0.15s, border-color 0.15s; + + i { color: fade(@ember, 50%); } + + &:hover, &.drag-over { + background: fade(@ember, 9%); + border-color: fade(@ember, 60%); + color: fade(@parchment, 70%); + i { color: @ember; } + } + } + } + + .action-table-buttons { + display: flex; + gap: 0.3rem; + align-items: center; + + button { + font-size: 0.75rem; + padding: 0.15em 0.55em; + background: fade(@ember, 10%); + border: 1px solid fade(@ember, 30%); + color: fade(@ember, 80%); + border-radius: 3px; + cursor: pointer; + transition: background 0.15s, color 0.15s; + display: flex; + align-items: center; + gap: 0.3em; + + &:hover { + background: fade(@ember, 22%); + color: @ember; + } + } + } +} + +// ============================================================ +// PARTY ACTOR SHEET +// ============================================================ + +.application.mgne.party { + + .party-credits-row { + display: flex; + align-items: center; + gap: 0.6rem; + margin-top: 0.5rem; + padding: 0.4rem 0.6rem; + border: 1px solid fade(@gold-acid, 35%); + border-radius: @radius-sm; + background: fade(@bg-input, 70%); + } + + .party-credits-stepper { + display: flex; + align-items: center; + gap: 0.3rem; + } + + .credits-input { + width: 5rem; + text-align: center; + font-size: 1.05rem; + font-weight: 700; + font-family: @font-display; + color: @gold-acid; + background: fade(@bg-void, 60%); + border: 1px solid fade(@gold-acid, 30%); + border-radius: @radius-sm; + padding: 0.2rem 0.4rem; + } + + .credits-symbol { + color: @gold-acid; + font-family: @font-display; + font-size: 1.1rem; + font-weight: 700; + margin: 0 0.1rem; + } + + .credits-btn { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 2rem; + padding: 0.15rem 0.4rem; + font-size: 0.75rem; + font-weight: 700; + border: 1px solid fade(@bone, 28%); + border-radius: @radius-sm; + background: fade(@bg-input, 80%); + color: @bone; + cursor: pointer; + user-select: none; + transition: background 0.15s, border-color 0.15s; + + &:hover { + background: fade(@gold-acid, 18%); + border-color: fade(@gold-acid, 55%); + color: @gold-acid; + } + } +} + +// ── Party member list ───────────────────────────────────────── +.application.mgne.party .party-member-list { + display: flex; + flex-direction: column; + gap: 0.25rem; + margin-top: 0.4rem; +} + +.application.mgne.party .party-member-row { + display: grid; + grid-template-columns: 2rem 1fr 5rem 6rem 5.5rem; + gap: 0.5rem; + align-items: center; + padding: 0.3rem 0.4rem; + border-radius: @radius-sm; + + &.party-member-header { + color: @dust; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 1px solid fade(@bone, 18%); + padding-bottom: 0.25rem; + margin-bottom: 0.1rem; + } + + &:not(.party-member-header) { + background: fade(@bg-input, 75%); + border: 1px solid transparent; + + &:hover { + border-color: fade(@gold-acid, 22%); + background: fade(@bg-input, 90%); + } + } +} + +.application.mgne.party .party-member-portrait { + width: 2rem; + height: 2rem; + object-fit: cover; + border-radius: 3px; + border: 1px solid fade(@bone, 25%); +} + +.application.mgne.party .party-member-name a { + color: @parchment; + font-weight: 700; + font-size: 0.9rem; + + &:hover { color: @gold-acid; } +} + +.application.mgne.party .party-member-hp { + color: @ember-bright; + font-family: @font-display; + font-size: 0.82rem; + font-weight: 700; + text-align: center; +} + +.application.mgne.party .party-member-type { + color: @dust; + font-size: 0.78rem; + font-style: italic; +} + +// ── Party loot list ──────────────────────────────────────────── +.application.mgne.party .party-loot-list { + display: flex; + flex-direction: column; + gap: 0.25rem; + margin-top: 0.4rem; +} + +.application.mgne.party .party-loot-row { + display: grid; + grid-template-columns: 2rem 1fr 7rem 4rem; + gap: 0.5rem; + align-items: center; + padding: 0.3rem 0.4rem; + border-radius: @radius-sm; + + &.party-loot-header { + color: @dust; + font-size: 0.72rem; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 1px solid fade(@bone, 18%); + padding-bottom: 0.25rem; + margin-bottom: 0.1rem; + } + + &:not(.party-loot-header) { + background: fade(@bg-input, 75%); + border: 1px solid transparent; + + &:hover { + border-color: fade(@gold-acid, 22%); + background: fade(@bg-input, 90%); + } + } +} + +.application.mgne.party .item-portrait { + width: 2rem; + height: 2rem; + object-fit: cover; + border-radius: 3px; + border: 1px solid fade(@bone, 25%); +} + +.application.mgne.party .item-type-label { + color: @dust; + font-size: 0.78rem; + font-style: italic; +} + +// ── Party drop hint ──────────────────────────────────────────── +.application.mgne.party .party-drop-hint { + color: fade(@dust, 70%); + font-size: 0.75rem; + font-style: italic; + text-align: center; + margin-top: 0.5rem; + padding: 0.3rem; + border: 1px dashed fade(@bone, 18%); + border-radius: @radius-sm; +} diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs index 4d29649..387d4f3 100644 --- a/module/applications/_module.mjs +++ b/module/applications/_module.mjs @@ -3,6 +3,7 @@ export { default as MGNEItemSheet } from "./sheets/base-item-sheet.mjs" export { default as MGNECharacterSheet } from "./sheets/character-sheet.mjs" export { default as MGNECreatureSheet } from "./sheets/creature-sheet.mjs" export { default as MGNECompanionSheet } from "./sheets/companion-sheet.mjs" +export { default as MGNEPartySheet } from "./sheets/party-sheet.mjs" export { default as MGNEWeaponSheet } from "./sheets/weapon-sheet.mjs" export { default as MGNEArmorSheet } from "./sheets/armor-sheet.mjs" export { default as MGNEShieldSheet } from "./sheets/shield-sheet.mjs" @@ -10,3 +11,4 @@ export { default as MGNEEquipmentSheet } from "./sheets/equipment-sheet.mjs" export { default as MGNEResonanceCoreSheet } from "./sheets/resonance-core-sheet.mjs" export { default as MGNEArtifactSheet } from "./sheets/artifact-sheet.mjs" export { default as MGNEFeatureSheet } from "./sheets/feature-sheet.mjs" +export { default as MGNECreatureTraitSheet } from "./sheets/creature-trait-sheet.mjs" diff --git a/module/applications/sheets/base-actor-sheet.mjs b/module/applications/sheets/base-actor-sheet.mjs index 0ffe176..c1c891a 100644 --- a/module/applications/sheets/base-actor-sheet.mjs +++ b/module/applications/sheets/base-actor-sheet.mjs @@ -64,6 +64,8 @@ export default class MGNEActorSheet extends HandlebarsApplicationMixin(foundry.a switch (rollType) { case "ability": return this.document.rollAbility(target.dataset.abilityId) + case "armor": + return this.document.rollArmorSave() case "defense": return this.document.rollDefense() case "weapon": @@ -78,6 +80,8 @@ export default class MGNEActorSheet extends HandlebarsApplicationMixin(foundry.a return this.document.rollResonation(itemId) case "morale": return this.document.rollMorale() + case "durability": + return this.document.rollDurability(itemId) case "usage": return this.document.rollUsage(itemId) default: diff --git a/module/applications/sheets/character-sheet.mjs b/module/applications/sheets/character-sheet.mjs index 67cac91..e67224a 100644 --- a/module/applications/sheets/character-sheet.mjs +++ b/module/applications/sheets/character-sheet.mjs @@ -2,6 +2,10 @@ import MGNEActorSheet from "./base-actor-sheet.mjs" import { SYSTEM } from "../../config/system.mjs" import { buildCharacterSelectOptions } from "./select-options.mjs" +export function stripHtml(html) { + return (html ?? "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim() +} + export default class MGNECharacterSheet extends MGNEActorSheet { static DEFAULT_OPTIONS = { classes: ["character"], @@ -79,16 +83,16 @@ export default class MGNECharacterSheet extends MGNEActorSheet { break case "equipment": context.tab = context.tabs.equipment - context.weapons = doc.itemTypes.weapon - context.armors = doc.itemTypes.armor - context.shields = doc.itemTypes.shield - context.equipmentItems = doc.itemTypes.equipment - context.cores = doc.itemTypes["resonance-core"] - context.artifacts = doc.itemTypes.artifact + context.weapons = doc.itemTypes.weapon.map(i => ({ ...i, tooltip: stripHtml(i.system.description) })) + context.armors = doc.itemTypes.armor.map(i => ({ ...i, tooltip: stripHtml(i.system.description) })) + context.shields = doc.itemTypes.shield.map(i => ({ ...i, tooltip: stripHtml(i.system.description) })) + context.equipmentItems = doc.itemTypes.equipment.map(i => ({ ...i, tooltip: stripHtml(i.system.description) })) + context.cores = doc.itemTypes["resonance-core"].map(i => ({ ...i, tooltip: stripHtml(i.system.description) })) + context.artifacts = doc.itemTypes.artifact.map(i => ({ ...i, tooltip: stripHtml(i.system.description) })) break case "features": context.tab = context.tabs.features - context.features = doc.itemTypes.feature + context.features = doc.itemTypes.feature.map(i => ({ ...i, tooltip: stripHtml(i.system.description) })) break case "notes": context.tab = context.tabs.notes diff --git a/module/applications/sheets/companion-sheet.mjs b/module/applications/sheets/companion-sheet.mjs index 06bc4b5..8e924c6 100644 --- a/module/applications/sheets/companion-sheet.mjs +++ b/module/applications/sheets/companion-sheet.mjs @@ -1,5 +1,4 @@ import MGNEActorSheet from "./base-actor-sheet.mjs" -import { SYSTEM } from "../../config/system.mjs" export default class MGNECompanionSheet extends MGNEActorSheet { static DEFAULT_OPTIONS = { @@ -13,14 +12,4 @@ export default class MGNECompanionSheet extends MGNEActorSheet { static PARTS = { main: { template: "systems/fvtt-machine-gods-noxian-expanse/templates/companion-main.hbs" }, } - - async _prepareContext() { - const context = await super._prepareContext() - context.abilityList = SYSTEM.abilityOrder.map(id => ({ - id, - ...SYSTEM.abilities[id], - value: context.source.system.abilities?.[id]?.value ?? 0, - })) - return context - } } diff --git a/module/applications/sheets/creature-sheet.mjs b/module/applications/sheets/creature-sheet.mjs index 5f48f4c..a2444ff 100644 --- a/module/applications/sheets/creature-sheet.mjs +++ b/module/applications/sheets/creature-sheet.mjs @@ -1,12 +1,17 @@ import MGNEActorSheet from "./base-actor-sheet.mjs" -import { SYSTEM } from "../../config/system.mjs" +import { stripHtml } from "./character-sheet.mjs" export default class MGNECreatureSheet extends MGNEActorSheet { static DEFAULT_OPTIONS = { classes: ["creature"], position: { width: 760, - height: 640, + height: 680, + }, + actions: { + rollActionTable: MGNECreatureSheet.prototype._rollActionTable, + clearActionTable: MGNECreatureSheet.prototype._clearActionTable, + openActionTable: MGNECreatureSheet.prototype._openActionTable, }, } @@ -14,13 +19,67 @@ export default class MGNECreatureSheet extends MGNEActorSheet { main: { template: "systems/fvtt-machine-gods-noxian-expanse/templates/creature-main.hbs" }, } + _processSubmitData(event, form, submitData) { + // Foundry sends null for unchecked checkboxes in a SetField array — strip them + if (Array.isArray(submitData.system?.creatureType)) { + submitData.system.creatureType = submitData.system.creatureType.filter(v => v != null && v !== "") + } + return super._processSubmitData(event, form, submitData) + } + async _prepareContext() { const context = await super._prepareContext() - context.abilityList = SYSTEM.abilityOrder.map(id => ({ - id, - ...SYSTEM.abilities[id], - value: context.source.system.abilities?.[id]?.value ?? 0, + context.traits = (this.document.itemTypes["creature-trait"] ?? []) + .map(i => ({ ...i, tooltip: stripHtml(i.system.description) })) + + // Resolve linked action table + const uuid = this.document.system.actionTableUuid + if (uuid) { + const table = await fromUuid(uuid).catch(() => null) + context.actionTable = table ? { name: table.name, uuid } : null + } else { + context.actionTable = null + } + + // Build creature type checkboxes + const typeSet = this.document.system.creatureType ?? new Set() + context.creatureTypes = ["human", "construct", "animal"].map(key => ({ + key, + label: game.i18n.localize(`MGNE.Creature.Types.${key.charAt(0).toUpperCase() + key.slice(1)}`), + checked: typeSet.has(key), })) + return context } + + async _onDrop(event) { + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event) + if (data?.type === "RollTable") { + const table = await fromUuid(data.uuid) + if (table) { + await this.document.update({ "system.actionTableUuid": data.uuid }) + return + } + } + return super._onDrop(event) + } + + async _rollActionTable() { + const uuid = this.document.system.actionTableUuid + if (!uuid) return ui.notifications.warn(game.i18n.localize("MGNE.Creature.NoTableLinked")) + const table = await fromUuid(uuid).catch(() => null) + if (!table) return ui.notifications.warn(game.i18n.localize("MGNE.Creature.TableNotFound")) + await table.draw() + } + + async _clearActionTable() { + await this.document.update({ "system.actionTableUuid": "" }) + } + + async _openActionTable() { + const uuid = this.document.system.actionTableUuid + if (!uuid) return + const table = await fromUuid(uuid).catch(() => null) + if (table) table.sheet.render(true) + } } diff --git a/module/applications/sheets/creature-trait-sheet.mjs b/module/applications/sheets/creature-trait-sheet.mjs new file mode 100644 index 0000000..63c6617 --- /dev/null +++ b/module/applications/sheets/creature-trait-sheet.mjs @@ -0,0 +1,7 @@ +import MGNEItemSheet from "./base-item-sheet.mjs" + +export default class MGNECreatureTraitSheet extends MGNEItemSheet { + static PARTS = { + main: { template: "systems/fvtt-machine-gods-noxian-expanse/templates/creature-trait.hbs" }, + } +} diff --git a/module/applications/sheets/party-sheet.mjs b/module/applications/sheets/party-sheet.mjs new file mode 100644 index 0000000..ca969e9 --- /dev/null +++ b/module/applications/sheets/party-sheet.mjs @@ -0,0 +1,162 @@ +import MGNEActorSheet from "./base-actor-sheet.mjs" + +const SYSTEM_ID = "fvtt-machine-gods-noxian-expanse" + +const PARTY_LOOT_TYPES = new Set(["weapon", "armor", "shield", "equipment", "resonance-core", "artifact"]) + +export default class MGNEPartySheet extends MGNEActorSheet { + /** @override */ + static DEFAULT_OPTIONS = { + classes: ["party"], + position: { width: 820, height: 640 }, + actions: { + openMember: MGNEPartySheet.#onOpenMember, + removeMember: MGNEPartySheet.#onRemoveMember, + moveMemberUp: MGNEPartySheet.#onMoveMemberUp, + moveMemberDown: MGNEPartySheet.#onMoveMemberDown, + adjustCredits: MGNEPartySheet.#onAdjustCredits, + }, + } + + /** @override */ + static PARTS = { + main: { template: `systems/${SYSTEM_ID}/templates/party-main.hbs` }, + tabs: { template: `systems/${SYSTEM_ID}/templates/party-tabs.hbs` }, + members: { template: `systems/${SYSTEM_ID}/templates/party-members.hbs` }, + loot: { template: `systems/${SYSTEM_ID}/templates/party-loot.hbs` }, + notes: { template: `systems/${SYSTEM_ID}/templates/party-notes.hbs` }, + } + + tabGroups = { sheet: "members" } + + #getTabs() { + const tabs = { + members: { id: "members", group: "sheet", label: game.i18n.localize("MGNE.Tabs.members") }, + loot: { id: "loot", group: "sheet", label: game.i18n.localize("MGNE.Tabs.loot") }, + notes: { id: "notes", group: "sheet", label: game.i18n.localize("MGNE.Tabs.notes") }, + } + for (const tab of Object.values(tabs)) { + tab.active = this.tabGroups[tab.group] === tab.id + tab.cssClass = tab.active ? "active" : "" + } + return tabs + } + + /** @override */ + async _prepareContext() { + const context = await super._prepareContext() + context.tabs = this.#getTabs() + return context + } + + /** @override */ + async _preparePartContext(partId, context) { + const doc = this.document + switch (partId) { + case "members": { + context.tab = context.tabs.members + // Build member list using actorId for moves; store refIdx (position in + // memberRefs) so move actions always operate on the correct slot even + // when some refs point to deleted actors. + const refs = doc.system.memberRefs ?? [] + const members = [] + for (let refIdx = 0; refIdx < refs.length; refIdx++) { + const actor = game.actors?.get(refs[refIdx].id) + if (!actor) continue + members.push({ + id: actor.id, + refIdx, + name: actor.name, + img: actor.img, + type: actor.type, + typeLabel: game.i18n.localize(`TYPES.Actor.${actor.type}`), + hp: actor.system.hp + ? `${actor.system.hp.value ?? "—"}/${actor.system.hp.max ?? "—"}` + : "—", + }) + } + // isFirst/isLast based on visible list, but swap uses refIdx + for (let vi = 0; vi < members.length; vi++) { + members[vi].isFirst = vi === 0 + members[vi].isLast = vi === members.length - 1 + } + context.members = members + break + } + + case "loot": { + context.tab = context.tabs.loot + context.lootItems = doc.items.contents + .filter(i => PARTY_LOOT_TYPES.has(i.type)) + .map(i => ({ + id: i.id, + img: i.img, + name: i.name, + typeLabel: game.i18n.localize(`TYPES.Item.${i.type}`), + })) + break + } + + case "notes": + context.tab = context.tabs.notes + break + } + return context + } + + /** @override */ + async _onDrop(event) { + if (!this.isEditable) return + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event) + + if (data.type === "Actor") { + const actor = await fromUuid(data.uuid) + if (!actor || !["character", "companion"].includes(actor.type)) return + const refs = foundry.utils.deepClone(this.document.system.memberRefs ?? []) + if (refs.some(r => r.id === actor.id)) return + refs.push({ id: actor.id }) + return this.document.update({ "system.memberRefs": refs }) + } + + if (data.type === "Item") { + const item = await fromUuid(data.uuid) + if (!item || !PARTY_LOOT_TYPES.has(item.type)) return + return this.document.createEmbeddedDocuments("Item", [item.toObject()]) + } + } + + // ── Actions ───────────────────────────────────────────────────────────────── + + static async #onOpenMember(_event, target) { + const actor = game.actors?.get(target.dataset.actorId) + if (actor) actor.sheet.render(true) + } + + static async #onRemoveMember(_event, target) { + const id = target.dataset.actorId + const refs = (this.document.system.memberRefs ?? []).filter(r => r.id !== id) + await this.document.update({ "system.memberRefs": refs }) + } + + static async #onMoveMemberUp(_event, target) { + const refIdx = parseInt(target.dataset.refIdx, 10) + if (refIdx <= 0) return + const refs = foundry.utils.deepClone(this.document.system.memberRefs ?? []); + [refs[refIdx - 1], refs[refIdx]] = [refs[refIdx], refs[refIdx - 1]] + await this.document.update({ "system.memberRefs": refs }) + } + + static async #onMoveMemberDown(_event, target) { + const refIdx = parseInt(target.dataset.refIdx, 10) + const refs = foundry.utils.deepClone(this.document.system.memberRefs ?? []) + if (refIdx >= refs.length - 1) return; + [refs[refIdx], refs[refIdx + 1]] = [refs[refIdx + 1], refs[refIdx]] + await this.document.update({ "system.memberRefs": refs }) + } + + static async #onAdjustCredits(_event, target) { + const delta = parseInt(target.dataset.delta, 10) + const current = this.document.system.credits ?? 0 + await this.document.update({ "system.credits": Math.max(0, current + delta) }) + } +} diff --git a/module/applications/sheets/select-options.mjs b/module/applications/sheets/select-options.mjs index e7762b7..0967c16 100644 --- a/module/applications/sheets/select-options.mjs +++ b/module/applications/sheets/select-options.mjs @@ -31,12 +31,13 @@ export function buildSharedSelectOptions() { armorPenalties: numericOptions(0, 6), shieldPenalties: numericOptions(0, 4), weaponCategories: objectOptions(SYSTEM.weaponCategories), + weaponProperties: Object.entries(SYSTEM.weaponProperties).map(([key, p]) => ({ value: key, label: p.label, hint: p.hint })), + weightCategories: objectOptions(SYSTEM.weightCategories), usageDice: objectOptions(SYSTEM.usageDieChoices), armorDice: objectOptions(SYSTEM.armorDieChoices), omenDice: objectOptions(SYSTEM.omenDieChoices), resonanceList: objectOptions(SYSTEM.resonanceList), equipmentSubtypes: objectOptions(SYSTEM.equipmentSubtypes), - artifactIds: objectOptions(SYSTEM.artifactChoices), featureIds: objectOptions(SYSTEM.featureChoices), } } diff --git a/module/config/system.mjs b/module/config/system.mjs index 07e8a59..a731c18 100644 --- a/module/config/system.mjs +++ b/module/config/system.mjs @@ -28,6 +28,7 @@ export const SYSTEM = { character: { id: "character", label: "Character" }, creature: { id: "creature", label: "Creature" }, companion: { id: "companion", label: "Companion" }, + party: { id: "party", label: "Party" }, }, itemTypes: { weapon: { id: "weapon", label: "Weapon", icon: itemIcon("weapon") }, @@ -37,6 +38,7 @@ export const SYSTEM = { "resonance-core": { id: "resonance-core", label: "Resonance Core", icon: itemIcon("resonance-core") }, artifact: { id: "artifact", label: "Artifact", icon: itemIcon("artifact") }, feature: { id: "feature", label: "Feature", icon: itemIcon("feature") }, + "creature-trait": { id: "creature-trait", label: "Creature Trait", icon: itemIcon("creature-trait") }, }, abilities: { agility: { id: "agility", label: "Agility" }, @@ -63,10 +65,37 @@ export const SYSTEM = { armorDieChoices: dieChoiceLabels(["d12", "d10", "d8", "d6", "d4", "d2", "0"]), omenDice: ["d2", "d4", "d6", "d8"], omenDieChoices: dieChoiceLabels(["d2", "d4", "d6", "d8"]), + weightCategories: { + trivial: "Trivial", + light: "Light", + normal: "Normal", + heavy: "Heavy", + }, weaponCategories: { melee: "Melee", ranged: "Ranged", }, + weaponProperties: { + ammo: { label: "Ammo", hint: "Requires ammunition. Improvised in melee or without ammo." }, + awkward: { label: "Awkward", hint: "+1 DR to attacks." }, + binding: { label: "Binding", hint: "Beat DR by 4+ on same-size or smaller target: inflict Restrained." }, + durant: { label: "Durant", hint: "Durability die is D8." }, + finesse: { label: "Finesse", hint: "Attacks can use either Presence or Strength." }, + fling: { label: "Fling", hint: "Can make ranged attacks. Roll D4 Usage Die to avoid losing it." }, + fragile: { label: "Fragile", hint: "Durability die is D4." }, + glinting: { label: "Glinting", hint: "After attacking, next attack vs same target this combat gains -1 DR." }, + overbearing:{ label: "Overbearing",hint: "+2 damage." }, + parrying: { label: "Parrying", hint: "-1 DR to avoiding melee attacks while wielding." }, + precise: { label: "Precise", hint: "-1 DR to hit." }, + razored: { label: "Razored", hint: "Beat DR by 4+: inflict Bleeding (1)." }, + ringing: { label: "Ringing", hint: "Beat DR by 4+ and target not Stunned: inflict Stunned (1)." }, + "two-handed":{ label: "Two-Handed",hint: "Requires both hands." }, + unwieldy: { label: "Unwieldy", hint: "Cannot attack more than once per Round." }, + versatile: { label: "Versatile", hint: "Two-handed: -1 DR to hit and +1 damage." }, + }, + get weaponPropertyLabels() { + return Object.fromEntries(Object.entries(this.weaponProperties).map(([k, v]) => [k, v.label])) + }, resonanceList: { accelerate: "Accelerate", blast: "Blast", diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 9690084..741e9e4 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -93,6 +93,10 @@ export default class MGNEActor extends Actor { return result } + async rollArmorSave() { + return MGNERoll.rollArmorSave(this) + } + async rollWeapon(itemId) { const item = this.items.get(itemId) if (!item) return null @@ -129,7 +133,10 @@ export default class MGNEActor extends Actor { async rollProfileAttack() { const attackBaseLabel = normalizeGenericActionLabel(this.system.attack?.label ?? t("MGNE.Common.Attack"), t("MGNE.Common.Attack")) const attackLabel = formatActionLabel(attackBaseLabel, t("MGNE.Common.Attack")) - const result = await this.rollAbility("strength", { + // Creatures have no ability scores; ability value defaults to 0 via roll.mjs + const result = await MGNERoll.promptCheck({ + actor: this, + abilityId: "strength", label: attackLabel, rollType: "attack", }) @@ -220,6 +227,12 @@ export default class MGNEActor extends Actor { return item.rollUsage() } + async rollDurability(itemId) { + const item = this.items.get(itemId) + if (!item) return null + return MGNERoll.rollDurability(item) + } + async quickRest() { const roll = await (new Roll("1d4")).evaluate() const hp = this.system.hp?.value ?? 0 diff --git a/module/documents/roll.mjs b/module/documents/roll.mjs index c33bbff..e92f8ff 100644 --- a/module/documents/roll.mjs +++ b/module/documents/roll.mjs @@ -57,11 +57,15 @@ async function renderCard(context) { const normalizedEyebrow = `${eyebrow}`.trim().toLowerCase() const normalizedLabel = `${context.label ?? ""}`.trim().toLowerCase() + // Render dice tooltip HTML if a roll was provided + const diceTooltip = context._roll ? await context._roll.render() : null + return foundry.applications.handlebars.renderTemplate(`systems/${SYSTEM_ID}/templates/chat-message.hbs`, { ...context, modeClass: context.mode ?? "generic", eyebrow: "", outcomeClass, + diceTooltip, }) } @@ -156,6 +160,7 @@ export default class MGNERoll { damageItemId: showDamageButton ? item.id : null, damageFormula: showDamageButton ? (item.system.damage || "1") : null, damageCritical: showDamageButton && critical, + _roll: roll, }) await ChatMessage.create({ @@ -181,6 +186,7 @@ export default class MGNERoll { total: roll.total, outcome: broken ? t("MGNE.Roll.OutcomeBroken") : t("MGNE.Roll.OutcomeSteady"), specialText: broken ? t("MGNE.Roll.MoraleBrokenText") : "", + _roll: roll, }) await ChatMessage.create({ @@ -236,6 +242,7 @@ export default class MGNERoll { showApplyButton: true, damageTotal: roll.total, damageCritical: isCritical, + _roll: roll, }) await ChatMessage.create({ @@ -267,6 +274,7 @@ export default class MGNERoll { showApplyButton: true, damageTotal: roll.total, damageCritical: isCritical, + _roll: roll, }) await ChatMessage.create({ @@ -278,6 +286,39 @@ export default class MGNERoll { return { roll } } + static async rollArmorSave(actor) { + const formula = actor.getArmorRollFormula() + const items = actor.getEquippedArmorItems() + + if (formula === "0") { + ui.notifications.warn(t("MGNE.Notification.NoArmorEquipped")) + return null + } + + const roll = await (new Roll(formula)).evaluate() + const armorNames = items.map(i => i.name).join(" + ") + + const contentHtml = await renderCard({ + mode: "armor", + actorName: actor.name, + actorImg: actor.img, + label: t("MGNE.Roll.ArmorSave"), + subtitle: armorNames, + formula: roll.formula, + total: roll.total, + outcome: f("MGNE.Roll.ArmorAbsorbed", { amount: roll.total }), + _roll: roll, + }) + + await ChatMessage.create({ + speaker: ChatMessage.getSpeaker({ actor }), + rolls: [roll], + content: contentHtml, + }) + + return roll + } + static async rollUsage(item) { const currentDie = item.system.usageDie if (!currentDie || currentDie === "depleted") { @@ -303,6 +344,7 @@ export default class MGNERoll { total: roll.total, outcome: depleted ? f("MGNE.Roll.DowngradedTo", { die: nextDie.toUpperCase() }) : t("MGNE.Roll.NoChange"), specialText: depleted && nextDie === "depleted" ? t("MGNE.Roll.ItemNowDepleted") : "", + _roll: roll, }) await ChatMessage.create({ @@ -314,6 +356,48 @@ export default class MGNERoll { return { roll, depleted, nextDie } } + static async rollDurability(item) { + const currentDie = item.system.durabilityDie + if (!currentDie || currentDie === "depleted") { + ui.notifications.warn(f("MGNE.Notification.ItemDurabilityDepleted", { item: item.name })) + return null + } + + const roll = await (new Roll(`1${currentDie}`)).evaluate() + const degraded = roll.total <= 2 + const nextDie = degraded ? stepDownDie(currentDie) : currentDie + const nowBroken = degraded && nextDie === "depleted" + const updates = { "system.durabilityDie": nextDie } + if (nowBroken) { + updates["system.broken"] = true + if ("equipped" in (item.system ?? {})) updates["system.equipped"] = false + } + await item.update(updates) + + const contentHtml = await renderCard({ + mode: "durability", + actorName: item.parent?.name ?? item.name, + actorImg: item.img, + label: f("MGNE.Roll.DurabilityLabel", { item: item.name }), + subtitle: f("MGNE.Roll.CurrentDie", { die: currentDie.toUpperCase() }), + formula: roll.formula, + total: roll.total, + outcome: degraded + ? f("MGNE.Roll.DowngradedTo", { die: nextDie.toUpperCase() }) + : t("MGNE.Roll.NoChange"), + specialText: nowBroken ? t("MGNE.Roll.ItemNowBroken") : "", + _roll: roll, + }) + + await ChatMessage.create({ + speaker: ChatMessage.getSpeaker({ actor: item.parent ?? null }), + rolls: [roll], + content: contentHtml, + }) + + return { roll, degraded, nextDie, nowBroken } + } + static async applyDamageCard({ actor, sourceActor = null, sourceItem = null, amount, armorRoll = null, appliedDamage, newHp, breakText = "", defenseFumbleText = "", criticalArmorText = "" }) { const contentHtml = await renderCard({ mode: "apply-damage", @@ -335,6 +419,7 @@ export default class MGNERoll { criticalArmorText, breakText ? f("MGNE.Roll.BreakText", { text: breakText }) : "", ]), + _roll: armorRoll ?? null, }) await ChatMessage.create({ @@ -359,6 +444,7 @@ export default class MGNERoll { total: roll.total, outcome, specialText, + _roll: roll, }) await ChatMessage.create({ diff --git a/module/models/_module.mjs b/module/models/_module.mjs index 7ed6577..7f6ba3b 100644 --- a/module/models/_module.mjs +++ b/module/models/_module.mjs @@ -1,6 +1,7 @@ export { default as MGNECharacter } from "./character.mjs" export { default as MGNECreature } from "./creature.mjs" export { default as MGNECompanion } from "./companion.mjs" +export { default as MGNEParty } from "./party.mjs" export { default as MGNEWeapon } from "./weapon.mjs" export { default as MGNEArmor } from "./armor.mjs" export { default as MGNEShield } from "./shield.mjs" @@ -8,3 +9,4 @@ export { default as MGNEEquipment } from "./equipment.mjs" export { default as MGNEResonanceCore } from "./resonance-core.mjs" export { default as MGNEArtifact } from "./artifact.mjs" export { default as MGNEFeature } from "./feature.mjs" +export { default as MGNECreatureTrait } from "./creature-trait.mjs" diff --git a/module/models/armor.mjs b/module/models/armor.mjs index a3a3cec..6b46869 100644 --- a/module/models/armor.mjs +++ b/module/models/armor.mjs @@ -12,8 +12,16 @@ export default class MGNEArmor extends foundry.abstract.TypeDataModel { choices: SYSTEM.armorDieChoices, }), penalty: numberField(0, 0, 6), + weight: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "heavy", + choices: SYSTEM.weightCategories, + }), equipped: booleanField(false), broken: booleanField(false), + durabilityDie: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "d6", + choices: SYSTEM.usageDieChoices, + }), } } diff --git a/module/models/artifact.mjs b/module/models/artifact.mjs index 1ce67f1..feb6419 100644 --- a/module/models/artifact.mjs +++ b/module/models/artifact.mjs @@ -5,12 +5,6 @@ export default class MGNEArtifact extends foundry.abstract.TypeDataModel { static defineSchema() { return { description: htmlField(""), - artifactId: new foundry.data.fields.StringField({ - required: true, - nullable: false, - initial: "shiver-lens", - choices: SYSTEM.artifactChoices, - }), synchronized: booleanField(false), synchronizedTo: stringField(""), usageDie: new foundry.data.fields.StringField({ @@ -20,6 +14,14 @@ export default class MGNEArtifact extends foundry.abstract.TypeDataModel { choices: SYSTEM.usageDieChoices, }), broken: booleanField(false), + durabilityDie: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "d6", + choices: SYSTEM.usageDieChoices, + }), + weight: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "normal", + choices: SYSTEM.weightCategories, + }), } } diff --git a/module/models/character.mjs b/module/models/character.mjs index eb4eab1..53c4f64 100644 --- a/module/models/character.mjs +++ b/module/models/character.mjs @@ -45,6 +45,34 @@ export default class MGNECharacter extends foundry.abstract.TypeDataModel { this.syncLimit = Math.max(0, this.abilities.toughness?.value ?? 0) this.syncRemaining = Math.max(0, this.syncLimit - (this.artifactSync.used ?? 0)) this.armorFormula = this.parent?.getArmorRollFormula?.() ?? "0" + + // Compute current load per RAW: + // trivial = 0, light = 10 per slot, normal = 1, heavy = fills remaining capacity (max 1) + let normalLoad = 0 + let lightCount = 0 + let heavyCount = 0 + for (const item of (this.parent?.items ?? [])) { + if (item.system?.carried === false) continue // not being carried + const w = item.system?.weight ?? "normal" + if (w === "trivial") continue + else if (w === "light") lightCount++ + else if (w === "normal") normalLoad++ + else if (w === "heavy") heavyCount++ + } + normalLoad += Math.floor(lightCount / 10) + this.lightItemCount = lightCount + this.heavyItemCount = heavyCount + + if (heavyCount >= 2) { + // Can't carry two heavy items — automatically overloaded + this.currentLoad = this.carryCapacity + (heavyCount - 1) + } else if (heavyCount === 1) { + // Heavy fills remaining capacity; other items fit alongside it + this.currentLoad = Math.max(normalLoad, this.carryCapacity) + } else { + this.currentLoad = normalLoad + } + this.overloaded = this.currentLoad > this.carryCapacity } /** @override */ diff --git a/module/models/companion.mjs b/module/models/companion.mjs index e4f41a6..94fd13d 100644 --- a/module/models/companion.mjs +++ b/module/models/companion.mjs @@ -1,12 +1,11 @@ import { SYSTEM } from "../config/system.mjs" -import { abilitySchema, htmlField, numberField, stringField, trackSchema } from "./shared.mjs" +import { htmlField, numberField, stringField, trackSchema } from "./shared.mjs" export default class MGNECompanion extends foundry.abstract.TypeDataModel { static defineSchema() { const fields = foundry.data.fields return { - abilities: abilitySchema(), hp: trackSchema(1, 1), morale: numberField(7, 2, 12), armor: new fields.SchemaField({ diff --git a/module/models/creature-trait.mjs b/module/models/creature-trait.mjs new file mode 100644 index 0000000..d797859 --- /dev/null +++ b/module/models/creature-trait.mjs @@ -0,0 +1,13 @@ +import { htmlField, stringField } from "./shared.mjs" + +export default class MGNECreatureTrait extends foundry.abstract.TypeDataModel { + static defineSchema() { + return { + description: htmlField(""), + trigger: stringField(""), + } + } + + /** @override */ + static LOCALIZATION_PREFIXES = ["MGNE.CreatureTrait"] +} diff --git a/module/models/creature.mjs b/module/models/creature.mjs index bd3d877..b5bed97 100644 --- a/module/models/creature.mjs +++ b/module/models/creature.mjs @@ -1,27 +1,39 @@ import { SYSTEM } from "../config/system.mjs" -import { abilitySchema, htmlField, numberField, stringField, trackSchema } from "./shared.mjs" +import { htmlField, numberField, stringField, trackSchema } from "./shared.mjs" + +const CREATURE_TYPES = ["human", "construct", "animal"] export default class MGNECreature extends foundry.abstract.TypeDataModel { static defineSchema() { const fields = foundry.data.fields return { - abilities: abilitySchema(), hp: trackSchema(1, 1), morale: numberField(7, 2, 12), armor: new fields.SchemaField({ die: new fields.StringField({ required: true, nullable: false, initial: "0", choices: SYSTEM.armorDieChoices }), }), - attack: new fields.SchemaField({ - label: stringField("Attack"), - damage: stringField("1d4"), - }), + creatureType: new fields.SetField( + new fields.StringField({ required: true, choices: CREATURE_TYPES }), + { required: true, nullable: false, initial: [] } + ), + number: stringField("1"), + actionTableUuid: stringField(""), description: htmlField(""), - special: htmlField(""), - notes: htmlField(""), } } /** @override */ static LOCALIZATION_PREFIXES = ["MGNE.Creature"] + + /** @override */ + static migrateData(source) { + // Remove old attack field if present (no longer part of the schema) + if ("attack" in source) delete source.attack + // Form submissions send null for unchecked checkboxes in array fields — filter them out + if (Array.isArray(source.creatureType)) { + source.creatureType = source.creatureType.filter(v => v != null && v !== "") + } + return super.migrateData(source) + } } diff --git a/module/models/equipment.mjs b/module/models/equipment.mjs index 5d251e0..95b4a45 100644 --- a/module/models/equipment.mjs +++ b/module/models/equipment.mjs @@ -21,6 +21,15 @@ export default class MGNEEquipment extends foundry.abstract.TypeDataModel { choices: SYSTEM.usageDieChoices, }), consumable: booleanField(false), + broken: booleanField(false), + durabilityDie: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "d6", + choices: SYSTEM.usageDieChoices, + }), + weight: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "normal", + choices: SYSTEM.weightCategories, + }), } } diff --git a/module/models/party.mjs b/module/models/party.mjs new file mode 100644 index 0000000..c566190 --- /dev/null +++ b/module/models/party.mjs @@ -0,0 +1,20 @@ +import { htmlField } from "./shared.mjs" + +export default class MGNEParty extends foundry.abstract.TypeDataModel { + static defineSchema() { + const fields = foundry.data.fields + + return { + memberRefs: new fields.ArrayField( + new fields.SchemaField({ + id: new fields.StringField({ required: true, nullable: false, blank: false }), + }) + ), + credits: new fields.NumberField({ required: true, nullable: false, integer: true, initial: 0, min: 0 }), + notes: htmlField(""), + } + } + + /** @override */ + static LOCALIZATION_PREFIXES = ["MGNE.Party"] +} diff --git a/module/models/resonance-core.mjs b/module/models/resonance-core.mjs index ca0771a..0f3768e 100644 --- a/module/models/resonance-core.mjs +++ b/module/models/resonance-core.mjs @@ -18,6 +18,15 @@ export default class MGNEResonanceCore extends foundry.abstract.TypeDataModel { choices: SYSTEM.usageDieChoices, }), burnedOut: booleanField(false), + broken: booleanField(false), + durabilityDie: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "d6", + choices: SYSTEM.usageDieChoices, + }), + weight: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "trivial", + choices: SYSTEM.weightCategories, + }), } } diff --git a/module/models/shield.mjs b/module/models/shield.mjs index 4249887..9f766bd 100644 --- a/module/models/shield.mjs +++ b/module/models/shield.mjs @@ -12,8 +12,16 @@ export default class MGNEShield extends foundry.abstract.TypeDataModel { choices: SYSTEM.armorDieChoices, }), penalty: numberField(0, 0, 4), + weight: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "normal", + choices: SYSTEM.weightCategories, + }), equipped: booleanField(false), broken: booleanField(false), + durabilityDie: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "d6", + choices: SYSTEM.usageDieChoices, + }), } } diff --git a/module/models/weapon.mjs b/module/models/weapon.mjs index b38d727..e71e6bf 100644 --- a/module/models/weapon.mjs +++ b/module/models/weapon.mjs @@ -13,7 +13,14 @@ export default class MGNEWeapon extends foundry.abstract.TypeDataModel { }), damage: stringField("1d4"), range: stringField("Touch"), - properties: stringField(""), + properties: new foundry.data.fields.SetField( + new foundry.data.fields.StringField({ required: true, nullable: false, blank: false }), + { required: true, nullable: false, initial: [] } + ), + weight: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "normal", + choices: SYSTEM.weightCategories, + }), usageDie: new foundry.data.fields.StringField({ required: true, nullable: false, @@ -23,9 +30,29 @@ export default class MGNEWeapon extends foundry.abstract.TypeDataModel { quantity: numberField(1, 0), equipped: booleanField(false), broken: booleanField(false), + durabilityDie: new foundry.data.fields.StringField({ + required: true, nullable: false, initial: "d6", + choices: SYSTEM.usageDieChoices, + }), } } /** @override */ static LOCALIZATION_PREFIXES = ["MGNE.Weapon"] + + /** + * Migrate old string-based properties field to the new SetField format. + * @override + */ + static migrateData(source) { + // Old data stored properties as a plain string; convert to empty array + if (typeof source.properties === "string") { + source.properties = [] + } + // Remove any null/undefined/blank entries that may have crept in + if (Array.isArray(source.properties)) { + source.properties = source.properties.filter(p => p != null && p !== "") + } + return super.migrateData(source) + } } diff --git a/packs-system/armor/000017.log b/packs-system/armor/000017.log deleted file mode 100644 index e69de29..0000000 diff --git a/packs-system/armor/000019.ldb b/packs-system/armor/000024.ldb similarity index 74% rename from packs-system/armor/000019.ldb rename to packs-system/armor/000024.ldb index 3319ca1e335738d736d072f09958b6e8dad1214d..923b9a9890d23b0f0f2760c8cf90f16dbe8b380e 100644 GIT binary patch delta 38 ucmZ3>x|UVs6N?Lj@MRXo%#zgHV#U1DoE%1tjUs;;S(pUuR!kOUngIaps0-!* delta 38 ucmZ3>x|UVs6N?Lj@MRXo%#zgHV#U1DoE%1ljUs;;S(bk{crsa(X$AoJi4B+l diff --git a/packs-system/armor/000026.log b/packs-system/armor/000026.log new file mode 100644 index 0000000000000000000000000000000000000000..ad4dc3c9d03ef729a40918ce1efee6126c536f27 GIT binary patch literal 4516 zcmeH~&raJw5XOttL#3Yj1YLY8QtS{wsLCyX3P>QKQuR_*XyYB*EB24OyAFvEm!7J= zL)EI6UivnDnI1bE8z&)AL?FE-m&9Z5x0>}Y-^{@0zc0VNSlf6~exBji+VgepK-zUx z2=V*rb#TF1(DoONKv4-nJJ`=CSL8h7#s!VQ4RRl(MrwnXT&8$s2iA);lb&;-q;bX- zgsEmWRJzZp3Zb7sg1~?){NvvJBaHPr3|A&3M8mV}e?DTE+J;~}tt`%63 z3m&8HWEkIpHf}tIIVD;!Ft>^p9|+o;jX+;1%qZizPmn=E3*m401%jqN?VFnkbbic6 zM`(vEq~ukn2ZpAwfd{ipf-3!xmhy8k+M2@1M{0~P>q(0CsO2$Ka>XSw zHR5Q6%c8janu*IBv>kFLklf{BlAvywd)>K!v^J**8HQ>^!tJ|^?BichfP>0rK*iL8 zM5BtxDeZGv$Zi z6P{*{P{l|hpwGJkR(7(eoqV4O#t{|C|FDw`b?;#(uczF^M@D9{b=ORed?!*l$4EQC(Mc*kBC@Ad zVM|XTzN256$f73lb0!v*WuIW5o?)ZB)Ebiy%Rwkg?YXGzOqq#~)Mhf(ydF`*Kw+(^ z#EA!m_zlrbusPA#^p4GZUCo@DrJzmqD-*FE~t<*N>T) 685 bytes -2026/05/10-10:15:09.204193 7ff6637fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-10:15:09.204306 7ff6637fe6c0 Delete type=2 #14 -2026/05/10-10:15:09.204434 7ff6637fe6c0 Delete type=2 #18 -2026/05/10-10:15:09.221921 7ff6637fe6c0 Manual compaction at level-1 from '!items!null' @ 25 : 1 .. '!items!null' @ 0 : 0; will stop at (end) diff --git a/packs-system/armor/LOG.old b/packs-system/armor/LOG.old index c247e7c..2297a0f 100644 --- a/packs-system/armor/LOG.old +++ b/packs-system/armor/LOG.old @@ -1,15 +1,3 @@ -2026/05/10-00:06:25.472144 7fe7209fd6c0 Recovering log #8 -2026/05/10-00:06:25.483556 7fe7209fd6c0 Delete type=3 #6 -2026/05/10-00:06:25.483623 7fe7209fd6c0 Delete type=0 #8 -2026/05/10-09:35:40.443132 7fe6d37fe6c0 Level-0 table #13: started -2026/05/10-09:35:40.446256 7fe6d37fe6c0 Level-0 table #13: 1354 bytes OK -2026/05/10-09:35:40.453014 7fe6d37fe6c0 Delete type=0 #11 -2026/05/10-09:35:40.470483 7fe6d37fe6c0 Manual compaction at level-0 from '!items!mgne-arm-chainshirt' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) -2026/05/10-09:35:40.476731 7fe6d37fe6c0 Manual compaction at level-1 from '!items!mgne-arm-chainshirt' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 17 : 1 -2026/05/10-09:35:40.476735 7fe6d37fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-09:35:40.479976 7fe6d37fe6c0 Generated table #14@1: 1 keys, 685 bytes -2026/05/10-09:35:40.480043 7fe6d37fe6c0 Compacted 1@1 + 1@2 files => 685 bytes -2026/05/10-09:35:40.486274 7fe6d37fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-09:35:40.486346 7fe6d37fe6c0 Delete type=2 #9 -2026/05/10-09:35:40.486470 7fe6d37fe6c0 Delete type=2 #13 -2026/05/10-09:35:40.504107 7fe6d37fe6c0 Manual compaction at level-1 from '!items!null' @ 17 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-15:40:00.779700 7f1642bfd6c0 Recovering log #22 +2026/05/17-15:40:00.789740 7f1642bfd6c0 Delete type=3 #20 +2026/05/17-15:40:00.789807 7f1642bfd6c0 Delete type=0 #22 diff --git a/packs-system/armor/MANIFEST-000015 b/packs-system/armor/MANIFEST-000015 deleted file mode 100644 index bfb024e8b134ccda3adf774688c394b65592f60b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 339 zcmcaH|6m%K!iX diff --git a/packs-system/armor/MANIFEST-000025 b/packs-system/armor/MANIFEST-000025 new file mode 100644 index 0000000000000000000000000000000000000000..e2efbc4640ed868acb0ac3b9f0719b4836d9448b GIT binary patch literal 191 zcmeBSEZDV@fss)vC$%g!CnZVGsj?)sJhM2}IX|}`u_&=5zlfDlSTVCCHMdwXuQVrz zQIP=**qK;oa4JD1a?|rtbrXwnb(1p^GxLfwGK)$W86oNvk(Cr@r0C|RrT`TH?P6qy gnIy566~zh-hy*sVgIDHzaWF74NpUhTOS5PI0JNqt=Kufz literal 0 HcmV?d00001 diff --git a/packs-system/companions/000017.log b/packs-system/companions/000017.log deleted file mode 100644 index e69de29..0000000 diff --git a/packs-system/companions/000019.ldb b/packs-system/companions/000024.ldb similarity index 92% rename from packs-system/companions/000019.ldb rename to packs-system/companions/000024.ldb index f9d0b98ad8b7587f919a95f3733e787b23d37b93..6fbe886522e0f8a0c32061b9bf57f57d4c060c7a 100644 GIT binary patch delta 21 dcmX@We}I322&2eGQGRxoiYq!dCu^|J002pe2IBw# delta 21 dcmX@We}I322&2G8QGRxo$|Wa0PS#+b0RT)X2V?*M diff --git a/packs-system/companions/000026.log b/packs-system/companions/000026.log new file mode 100644 index 0000000000000000000000000000000000000000..eae1ba5c4d7b45d721e2ac2942049f8ffae57830 GIT binary patch literal 9135 zcmeI1&yF0o5yoR6x8#xlzSCm_k>OdbR$9x>+;+9GC0LRL?ZQfs1O~gidYT?K*(TXL z8VkDQCGrXZa?UMJl0y!;SzBs{O4ak{@}x( zlz%_PpAUZik*<>u@gp}{`>$WTntf-Q*@6%AnbW<@7PDhnj>bx(p8CqlY(7hyf$g>L z2kne^Xfpj0EpZc*^l`sEPie2$b!VLHEqxRBoPTMw+mn~*5oKS;C@Jon+B-;#PGgYU z@qCGq${4f7t64Yj|8s3e%yxf1>-9_geT^SJXehGy&3vW<9w^ors?;3L@Ls2+>lItA zuEcT)RyWkV(Y;<$@SwR*$wp!w%#gT<#q33gWvbN4M%8|_jk4xkl*U8f`j9kMkET|X zag9 z@-gu!U;*4shuI?blE=&NHp~`(_|tqQZ3`u)hwoz2{QU}dD9E=Ms2sq9!`t`nA6#65 zM;AA-T#5_9ay_}0B+Z%OEiFyGZ%k{hw^<$2ld1i9vz6rK71v;=PW^}t-?lg7V0pCU zdNVFAZot(xERUA;bOvWQ3%Ee9-sv$K69=m|PqRb0gBwbp^Vm3C(iVqL=CieFQa4*1 z%x9hOSmd7#u1jf5@{-qubHq@?yv23EW$gEKI$;BU<0coPUETTcyV>H-?awe*e)|3N z)EW#8vpZe`TDpcSfhZ=YcxdrMC`9W6dgi^!VxWtf!2 zjoZc1xOU`iz^XV88zO!AR)V9t6mS4@_t@zMx2X(8w^MBKY6>W2YFvGRfiV>JKwKFb zPeFLix9h{w8y!|oV!lRDB9EFw#KCL4ja$Qrqu<7e+uhNQ5r9TDm=!pi~Q-lu$y&;z^Xp1`7#qbd9dltSkm z9m+OM+r!&ee)9ZY9O!IajMKv#_XtNv+2d|STdSATs)Kfo?;nvDrXA4(J<-##uQ>U| z@fEfnHPrp`Tw{h77m$LJK5$EUH{rZ-K01@3p^;XPmM_?0JNfJDwDXS}Y3F2&$wEi< zMBo;k4jY_=_dz^gOvLj=wrU}s&#@!_8}U4_0wf90{R;COetP$9>iMR?Oz;|EQ4#{W zD*!`u(5iwh5Nm0XAP%RjW_xKRWiT`%wii>WwYIAq25*L%Bh|uhVR&oN^$6mjSFH&$ zS0`WsB~JPbJ100ofQ?%7)pNw`2(N-T&G?%UOt*0QszC(o=IU6eQ^LW3I^YfHwE1-q zVg$+Rl5L(#J4QrtfJNs44;8tP1o8r`ME)3bsyjuZz{ApesI&pdc@^aX`{;Pk<n_`(T@QXJ?)v*MU^dpf`kF zAd1IF4!ZSY?1J|_LU4f+raH(EB{`xh?{i9J2zmotovWwNs$h)5H?|-R0(H<%esfH4 zL_C}^*_5+w8|pn}G?2BsB%6m|0xT5&gG_!Hkv;)nAynb(3;c{_pL>$SzItd#JcACP z35?YX4zAMq^8vWk4-h$q&KrVHL%Knd>RJZoEo#BnYB^+uG%-LHxqAg{T2mP5vpc^+ zz64~}gT9C(Um*>sI_wh?GEfyfWxyx28FVAMl-07!@;4mbstXe{H2Pp+o-f_uy zn6kqZeEjcHE;*~SOS$}Cq+I^?%bN;Jr%1LVQHU}CJUmkt?<3s;7|Geg!z+M-qSG7c zmYV_Pm{I+#8~foJoxGiELH;8MiYr8p0ccR8axzyxjG!|@0s?!BfR7prYeuLo@S7d= zGqvt~L>hu0`>+r~B@0FQtG=?x`w8kHIXu1_SYE)kIqy-88wS>Z!~znbp+X=AVLbFK zTQN6>R^kVe6s2gADFF%tOcL?N)Oc$`J=zQ|6-ot=KY~gI^{JeoS+g!v3DOGu)1X9! zl_G0_6cUyytmsU&rcDy(lIZ-zlDWekrq1{_$ zh;+tc{p zBPDbleM&J%tCGV+UMiv_#_TBZr31+&l%r4qLlFrT5hQt3LUAVUPxYu{kFCly2$^lN zM%~hOtv6AfZcwNQ-kBezVfE^mS!j-$0UmHv%67L-?q7~NM^26fLQx0m;WPGnA(pkr yavYGgO3CJYY*a9YL)HseFsnzK)vaHcIdQ2ryV-cukET;2wLx}TJ>KM4K*YH literal 0 HcmV?d00001 diff --git a/packs-system/companions/CURRENT b/packs-system/companions/CURRENT index 42c62b6..f622090 100644 --- a/packs-system/companions/CURRENT +++ b/packs-system/companions/CURRENT @@ -1 +1 @@ -MANIFEST-000015 +MANIFEST-000025 diff --git a/packs-system/companions/LOG b/packs-system/companions/LOG index f45d8f3..12fa1e1 100644 --- a/packs-system/companions/LOG +++ b/packs-system/companions/LOG @@ -1,15 +1,3 @@ -2026/05/10-10:14:24.400732 7ff671fef6c0 Recovering log #12 -2026/05/10-10:14:24.411244 7ff671fef6c0 Delete type=3 #10 -2026/05/10-10:14:24.411312 7ff671fef6c0 Delete type=0 #12 -2026/05/10-10:15:09.101581 7ff6637fe6c0 Level-0 table #18: started -2026/05/10-10:15:09.104730 7ff6637fe6c0 Level-0 table #18: 4899 bytes OK -2026/05/10-10:15:09.111016 7ff6637fe6c0 Delete type=0 #16 -2026/05/10-10:15:09.121512 7ff6637fe6c0 Manual compaction at level-0 from '!actors!mgne-comp-beguiled-noble' @ 72057594037927935 : 1 .. '!actors!null' @ 0 : 0; will stop at (end) -2026/05/10-10:15:09.141299 7ff6637fe6c0 Manual compaction at level-1 from '!actors!mgne-comp-beguiled-noble' @ 72057594037927935 : 1 .. '!actors!null' @ 0 : 0; will stop at '!actors!null' @ 13 : 1 -2026/05/10-10:15:09.141307 7ff6637fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-10:15:09.144336 7ff6637fe6c0 Generated table #19@1: 1 keys, 1984 bytes -2026/05/10-10:15:09.144349 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 1984 bytes -2026/05/10-10:15:09.150185 7ff6637fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-10:15:09.150242 7ff6637fe6c0 Delete type=2 #14 -2026/05/10-10:15:09.150350 7ff6637fe6c0 Delete type=2 #18 -2026/05/10-10:15:09.159856 7ff6637fe6c0 Manual compaction at level-1 from '!actors!null' @ 13 : 1 .. '!actors!null' @ 0 : 0; will stop at (end) +2026/05/17-15:40:00.750239 7f16423fc6c0 Recovering log #22 +2026/05/17-15:40:00.760411 7f16423fc6c0 Delete type=3 #20 +2026/05/17-15:40:00.760461 7f16423fc6c0 Delete type=0 #22 diff --git a/packs-system/companions/LOG.old b/packs-system/companions/LOG.old index 77cf8b7..ca669bc 100644 --- a/packs-system/companions/LOG.old +++ b/packs-system/companions/LOG.old @@ -1,15 +1,15 @@ -2026/05/10-00:06:25.447076 7fe7211fe6c0 Recovering log #8 -2026/05/10-00:06:25.457896 7fe7211fe6c0 Delete type=3 #6 -2026/05/10-00:06:25.457952 7fe7211fe6c0 Delete type=0 #8 -2026/05/10-09:35:40.366450 7fe6d37fe6c0 Level-0 table #13: started -2026/05/10-09:35:40.369656 7fe6d37fe6c0 Level-0 table #13: 4899 bytes OK -2026/05/10-09:35:40.375570 7fe6d37fe6c0 Delete type=0 #11 -2026/05/10-09:35:40.404682 7fe6d37fe6c0 Manual compaction at level-0 from '!actors!mgne-comp-beguiled-noble' @ 72057594037927935 : 1 .. '!actors!null' @ 0 : 0; will stop at (end) -2026/05/10-09:35:40.404711 7fe6d37fe6c0 Manual compaction at level-1 from '!actors!mgne-comp-beguiled-noble' @ 72057594037927935 : 1 .. '!actors!null' @ 0 : 0; will stop at '!actors!null' @ 9 : 1 -2026/05/10-09:35:40.404715 7fe6d37fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-09:35:40.407947 7fe6d37fe6c0 Generated table #14@1: 1 keys, 1984 bytes -2026/05/10-09:35:40.407960 7fe6d37fe6c0 Compacted 1@1 + 1@2 files => 1984 bytes -2026/05/10-09:35:40.413847 7fe6d37fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-09:35:40.413959 7fe6d37fe6c0 Delete type=2 #9 -2026/05/10-09:35:40.414504 7fe6d37fe6c0 Delete type=2 #13 -2026/05/10-09:35:40.433958 7fe6d37fe6c0 Manual compaction at level-1 from '!actors!null' @ 9 : 1 .. '!actors!null' @ 0 : 0; will stop at (end) +2026/05/17-13:26:05.090885 7f16423fc6c0 Recovering log #17 +2026/05/17-13:26:05.101315 7f16423fc6c0 Delete type=3 #15 +2026/05/17-13:26:05.101364 7f16423fc6c0 Delete type=0 #17 +2026/05/17-15:39:46.172949 7f1641bfb6c0 Level-0 table #23: started +2026/05/17-15:39:46.177184 7f1641bfb6c0 Level-0 table #23: 4899 bytes OK +2026/05/17-15:39:46.183241 7f1641bfb6c0 Delete type=0 #21 +2026/05/17-15:39:46.215307 7f1641bfb6c0 Manual compaction at level-0 from '!actors!mgne-comp-beguiled-noble' @ 72057594037927935 : 1 .. '!actors!null' @ 0 : 0; will stop at (end) +2026/05/17-15:39:46.224653 7f1641bfb6c0 Manual compaction at level-1 from '!actors!mgne-comp-beguiled-noble' @ 72057594037927935 : 1 .. '!actors!null' @ 0 : 0; will stop at '!actors!null' @ 17 : 1 +2026/05/17-15:39:46.224663 7f1641bfb6c0 Compacting 1@1 + 1@2 files +2026/05/17-15:39:46.227820 7f1641bfb6c0 Generated table #24@1: 1 keys, 1984 bytes +2026/05/17-15:39:46.227830 7f1641bfb6c0 Compacted 1@1 + 1@2 files => 1984 bytes +2026/05/17-15:39:46.233855 7f1641bfb6c0 compacted to: files[ 0 0 2 0 0 0 0 ] +2026/05/17-15:39:46.233946 7f1641bfb6c0 Delete type=2 #19 +2026/05/17-15:39:46.234305 7f1641bfb6c0 Delete type=2 #23 +2026/05/17-15:39:46.253812 7f1641bfb6c0 Manual compaction at level-1 from '!actors!null' @ 17 : 1 .. '!actors!null' @ 0 : 0; will stop at (end) diff --git a/packs-system/companions/MANIFEST-000015 b/packs-system/companions/MANIFEST-000015 deleted file mode 100644 index 07084a534636889b2cf3531c85c33c36fb5cb614..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 360 zcmcc6pP9Flfss)vC$%g!CnZVGsj?)sJhM2}IX|}`u_&=5zlfDlL@_ZL$S79KE6vGa zMWPz>jJn4@3s5V9EpTbsP+gOahz?%z`XDVPZm(=0L6>kSok0z|JVNSPfO5 p05-#TA%b(axk!dUb&IeFpnDvuij7f-jfsz)Nf_OoSdE4X0suWbRH*;} diff --git a/packs-system/companions/MANIFEST-000025 b/packs-system/companions/MANIFEST-000025 new file mode 100644 index 0000000000000000000000000000000000000000..0b8db3eb21aad62ef281027b4d8ca60aaad253d4 GIT binary patch literal 207 zcmY$GcwK8J10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei199h+<+gkWs9dSDKT< zD98W?>`bgnMKoYCx#@YSy2(I2x=E?&rI|UYDY|+2Nja&Ej1bjW6c%UZWG3h5=_V)U k0S#wlff*}tfFIRD5r_;{!G^yH?i>t^Oj4W-%+f3(00Q$j#sB~S literal 0 HcmV?d00001 diff --git a/packs-system/features/000017.log b/packs-system/features/000017.log deleted file mode 100644 index e69de29..0000000 diff --git a/packs-system/features/000019.ldb b/packs-system/features/000024.ldb similarity index 79% rename from packs-system/features/000019.ldb rename to packs-system/features/000024.ldb index adcad4b74db32da685e8578a7772a8de4d7be84a..39041c5f9da9a4c5e9a3249a185273abdb5c4362 100644 GIT binary patch delta 38 ucmcc4dYx5d0jmpxa3iZ?W=U#pv0`3nP7dRijUwtyEROdqk4?5`ngIapjSQav delta 38 ucmcc4dYx5d0jmpxa3iZ?W=U#pv0`3nP7dRQjUwtyEZYyCnL62?X$AoB1r0a= diff --git a/packs-system/features/000026.log b/packs-system/features/000026.log new file mode 100644 index 0000000000000000000000000000000000000000..84089a22e8d885a3e0002f684c38cd33a2ffd44e GIT binary patch literal 24800 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 Hj>rE8>0=dF literal 0 HcmV?d00001 diff --git a/packs-system/features/CURRENT b/packs-system/features/CURRENT index 42c62b6..f622090 100644 --- a/packs-system/features/CURRENT +++ b/packs-system/features/CURRENT @@ -1 +1 @@ -MANIFEST-000015 +MANIFEST-000025 diff --git a/packs-system/features/LOG b/packs-system/features/LOG index f9f1246..c5881e4 100644 --- a/packs-system/features/LOG +++ b/packs-system/features/LOG @@ -1,15 +1,3 @@ -2026/05/10-10:14:24.387289 7ff663fff6c0 Recovering log #12 -2026/05/10-10:14:24.397491 7ff663fff6c0 Delete type=3 #10 -2026/05/10-10:14:24.397540 7ff663fff6c0 Delete type=0 #12 -2026/05/10-10:15:09.082119 7ff6637fe6c0 Level-0 table #18: started -2026/05/10-10:15:09.085424 7ff6637fe6c0 Level-0 table #18: 10412 bytes OK -2026/05/10-10:15:09.092167 7ff6637fe6c0 Delete type=0 #16 -2026/05/10-10:15:09.121491 7ff6637fe6c0 Manual compaction at level-0 from '!items!mgne-feat-11' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) -2026/05/10-10:15:09.121551 7ff6637fe6c0 Manual compaction at level-1 from '!items!mgne-feat-11' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 109 : 1 -2026/05/10-10:15:09.121558 7ff6637fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-10:15:09.124679 7ff6637fe6c0 Generated table #19@1: 1 keys, 727 bytes -2026/05/10-10:15:09.124714 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 727 bytes -2026/05/10-10:15:09.130639 7ff6637fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-10:15:09.130747 7ff6637fe6c0 Delete type=2 #14 -2026/05/10-10:15:09.130828 7ff6637fe6c0 Delete type=2 #18 -2026/05/10-10:15:09.159837 7ff6637fe6c0 Manual compaction at level-1 from '!items!null' @ 109 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-15:40:00.736377 7f1643bff6c0 Recovering log #22 +2026/05/17-15:40:00.746313 7f1643bff6c0 Delete type=3 #20 +2026/05/17-15:40:00.746417 7f1643bff6c0 Delete type=0 #22 diff --git a/packs-system/features/LOG.old b/packs-system/features/LOG.old index d65b463..d9e32fe 100644 --- a/packs-system/features/LOG.old +++ b/packs-system/features/LOG.old @@ -1,15 +1,15 @@ -2026/05/10-00:06:25.433796 7fe7209fd6c0 Recovering log #8 -2026/05/10-00:06:25.444473 7fe7209fd6c0 Delete type=3 #6 -2026/05/10-00:06:25.444528 7fe7209fd6c0 Delete type=0 #8 -2026/05/10-09:35:40.395081 7fe6d37fe6c0 Level-0 table #13: started -2026/05/10-09:35:40.398418 7fe6d37fe6c0 Level-0 table #13: 10411 bytes OK -2026/05/10-09:35:40.404589 7fe6d37fe6c0 Delete type=0 #11 -2026/05/10-09:35:40.414572 7fe6d37fe6c0 Manual compaction at level-0 from '!items!mgne-feat-11' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) -2026/05/10-09:35:40.433971 7fe6d37fe6c0 Manual compaction at level-1 from '!items!mgne-feat-11' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 73 : 1 -2026/05/10-09:35:40.433978 7fe6d37fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-09:35:40.437087 7fe6d37fe6c0 Generated table #14@1: 1 keys, 727 bytes -2026/05/10-09:35:40.437108 7fe6d37fe6c0 Compacted 1@1 + 1@2 files => 727 bytes -2026/05/10-09:35:40.442891 7fe6d37fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-09:35:40.442951 7fe6d37fe6c0 Delete type=2 #9 -2026/05/10-09:35:40.443056 7fe6d37fe6c0 Delete type=2 #13 -2026/05/10-09:35:40.453127 7fe6d37fe6c0 Manual compaction at level-1 from '!items!null' @ 73 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-13:26:05.076690 7f1643bff6c0 Recovering log #17 +2026/05/17-13:26:05.087217 7f1643bff6c0 Delete type=3 #15 +2026/05/17-13:26:05.087270 7f1643bff6c0 Delete type=0 #17 +2026/05/17-15:39:46.194394 7f1641bfb6c0 Level-0 table #23: started +2026/05/17-15:39:46.197937 7f1641bfb6c0 Level-0 table #23: 10414 bytes OK +2026/05/17-15:39:46.204111 7f1641bfb6c0 Delete type=0 #21 +2026/05/17-15:39:46.215335 7f1641bfb6c0 Manual compaction at level-0 from '!items!mgne-feat-11' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-15:39:46.234408 7f1641bfb6c0 Manual compaction at level-1 from '!items!mgne-feat-11' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 145 : 1 +2026/05/17-15:39:46.234419 7f1641bfb6c0 Compacting 1@1 + 1@2 files +2026/05/17-15:39:46.238287 7f1641bfb6c0 Generated table #24@1: 1 keys, 727 bytes +2026/05/17-15:39:46.238317 7f1641bfb6c0 Compacted 1@1 + 1@2 files => 727 bytes +2026/05/17-15:39:46.244549 7f1641bfb6c0 compacted to: files[ 0 0 2 0 0 0 0 ] +2026/05/17-15:39:46.244607 7f1641bfb6c0 Delete type=2 #19 +2026/05/17-15:39:46.244675 7f1641bfb6c0 Delete type=2 #23 +2026/05/17-15:39:46.253828 7f1641bfb6c0 Manual compaction at level-1 from '!items!null' @ 145 : 1 .. '!items!null' @ 0 : 0; will stop at (end) diff --git a/packs-system/features/MANIFEST-000015 b/packs-system/features/MANIFEST-000015 deleted file mode 100644 index eb5ab7ebfd48fbcaa73c1e5e6163e124cad1f140..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 328 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 Uvp(UEH~XspzHfD!xAeka0J#6R`~Uy| diff --git a/packs-system/names/000025.ldb b/packs-system/names/000025.ldb new file mode 100644 index 0000000000000000000000000000000000000000..af4aca0d7e392fcbde0dd446d8e6e7043c9ffd3e GIT binary patch literal 40426 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 Z{LUfrV`}%q53l#t{9WJLl6c*@{|51~z|Q~x literal 0 HcmV?d00001 diff --git a/packs-system/names/000027.log b/packs-system/names/000027.log new file mode 100644 index 0000000000000000000000000000000000000000..b19c65ddc15f22f068cad15747b34298e9c34dd9 GIT binary patch literal 103348 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 literal 0 HcmV?d00001 diff --git a/packs-system/names/CURRENT b/packs-system/names/CURRENT index 32108be..8b15215 100644 --- a/packs-system/names/CURRENT +++ b/packs-system/names/CURRENT @@ -1 +1 @@ -MANIFEST-000016 +MANIFEST-000026 diff --git a/packs-system/names/LOG b/packs-system/names/LOG index 302fd28..5d53886 100644 --- a/packs-system/names/LOG +++ b/packs-system/names/LOG @@ -1,15 +1,3 @@ -2026/05/10-10:14:24.437910 7ff6717ee6c0 Recovering log #13 -2026/05/10-10:14:24.448329 7ff6717ee6c0 Delete type=3 #11 -2026/05/10-10:14:24.448394 7ff6717ee6c0 Delete type=0 #13 -2026/05/10-10:15:09.176410 7ff6637fe6c0 Level-0 table #19: started -2026/05/10-10:15:09.181126 7ff6637fe6c0 Level-0 table #19: 36394 bytes OK -2026/05/10-10:15:09.187189 7ff6637fe6c0 Delete type=0 #17 -2026/05/10-10:15:09.193581 7ff6637fe6c0 Manual compaction at level-0 from '!tables!mgne-tbl-armor' @ 72057594037927935 : 1 .. '!tables.results!zuw1vPYn2wNmreKL' @ 0 : 0; will stop at (end) -2026/05/10-10:15:09.204527 7ff6637fe6c0 Manual compaction at level-1 from '!tables!mgne-tbl-armor' @ 72057594037927935 : 1 .. '!tables.results!zuw1vPYn2wNmreKL' @ 0 : 0; will stop at '!tables.results!zuw1vPYn2wNmreKL' @ 1225 : 1 -2026/05/10-10:15:09.204538 7ff6637fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-10:15:09.208350 7ff6637fe6c0 Generated table #20@1: 436 keys, 40367 bytes -2026/05/10-10:15:09.208369 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 40367 bytes -2026/05/10-10:15:09.215216 7ff6637fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/05/10-10:15:09.215286 7ff6637fe6c0 Delete type=2 #15 -2026/05/10-10:15:09.215397 7ff6637fe6c0 Delete type=2 #19 -2026/05/10-10:15:09.221933 7ff6637fe6c0 Manual compaction at level-1 from '!tables.results!zuw1vPYn2wNmreKL' @ 1225 : 1 .. '!tables.results!zuw1vPYn2wNmreKL' @ 0 : 0; will stop at (end) +2026/05/17-15:40:00.792467 7f16423fc6c0 Recovering log #23 +2026/05/17-15:40:00.805587 7f16423fc6c0 Delete type=3 #21 +2026/05/17-15:40:00.805652 7f16423fc6c0 Delete type=0 #23 diff --git a/packs-system/names/LOG.old b/packs-system/names/LOG.old index d1f848e..e4bc91c 100644 --- a/packs-system/names/LOG.old +++ b/packs-system/names/LOG.old @@ -1,15 +1,15 @@ -2026/05/10-00:06:25.485605 7fe7211fe6c0 Recovering log #8 -2026/05/10-00:06:25.496011 7fe7211fe6c0 Delete type=3 #6 -2026/05/10-00:06:25.496075 7fe7211fe6c0 Delete type=0 #8 -2026/05/10-09:35:40.453137 7fe6d37fe6c0 Level-0 table #14: started -2026/05/10-09:35:40.457072 7fe6d37fe6c0 Level-0 table #14: 36470 bytes OK -2026/05/10-09:35:40.463127 7fe6d37fe6c0 Delete type=0 #12 -2026/05/10-09:35:40.476711 7fe6d37fe6c0 Manual compaction at level-0 from '!tables!mgne-tbl-armor' @ 72057594037927935 : 1 .. '!tables.results!zGPTmr9d4kGBxfWN' @ 0 : 0; will stop at (end) -2026/05/10-09:35:40.486568 7fe6d37fe6c0 Manual compaction at level-1 from '!tables!mgne-tbl-armor' @ 72057594037927935 : 1 .. '!tables.results!zGPTmr9d4kGBxfWN' @ 0 : 0; will stop at '!tables.results!zku5SGHgSA4RLSlW' @ 660 : 0 -2026/05/10-09:35:40.486576 7fe6d37fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-09:35:40.490562 7fe6d37fe6c0 Generated table #15@1: 436 keys, 40440 bytes -2026/05/10-09:35:40.490577 7fe6d37fe6c0 Compacted 1@1 + 1@2 files => 40440 bytes -2026/05/10-09:35:40.496634 7fe6d37fe6c0 compacted to: files[ 0 0 1 0 0 0 0 ] -2026/05/10-09:35:40.496732 7fe6d37fe6c0 Delete type=2 #10 -2026/05/10-09:35:40.496846 7fe6d37fe6c0 Delete type=2 #14 -2026/05/10-09:35:40.504136 7fe6d37fe6c0 Manual compaction at level-1 from '!tables.results!zku5SGHgSA4RLSlW' @ 660 : 0 .. '!tables.results!zGPTmr9d4kGBxfWN' @ 0 : 0; will stop at (end) +2026/05/17-13:26:05.132672 7f16423fc6c0 Recovering log #18 +2026/05/17-13:26:05.142773 7f16423fc6c0 Delete type=3 #16 +2026/05/17-13:26:05.142824 7f16423fc6c0 Delete type=0 #18 +2026/05/17-15:39:46.374557 7f1641bfb6c0 Level-0 table #24: started +2026/05/17-15:39:46.380380 7f1641bfb6c0 Level-0 table #24: 36276 bytes OK +2026/05/17-15:39:46.386967 7f1641bfb6c0 Delete type=0 #22 +2026/05/17-15:39:46.393402 7f1641bfb6c0 Manual compaction at level-0 from '!tables!mgne-tbl-armor' @ 72057594037927935 : 1 .. '!tables.results!zjYp8qq96SSCUgBi' @ 0 : 0; will stop at (end) +2026/05/17-15:39:46.403700 7f1641bfb6c0 Manual compaction at level-1 from '!tables!mgne-tbl-armor' @ 72057594037927935 : 1 .. '!tables.results!zjYp8qq96SSCUgBi' @ 0 : 0; will stop at '!tables.results!zuw1vPYn2wNmreKL' @ 1530 : 0 +2026/05/17-15:39:46.403711 7f1641bfb6c0 Compacting 1@1 + 1@2 files +2026/05/17-15:39:46.422351 7f1641bfb6c0 Generated table #25@1: 436 keys, 40426 bytes +2026/05/17-15:39:46.422374 7f1641bfb6c0 Compacted 1@1 + 1@2 files => 40426 bytes +2026/05/17-15:39:46.428514 7f1641bfb6c0 compacted to: files[ 0 0 1 0 0 0 0 ] +2026/05/17-15:39:46.428618 7f1641bfb6c0 Delete type=2 #20 +2026/05/17-15:39:46.428754 7f1641bfb6c0 Delete type=2 #24 +2026/05/17-15:39:46.428833 7f1641bfb6c0 Manual compaction at level-1 from '!tables.results!zuw1vPYn2wNmreKL' @ 1530 : 0 .. '!tables.results!zjYp8qq96SSCUgBi' @ 0 : 0; will stop at (end) diff --git a/packs-system/names/MANIFEST-000016 b/packs-system/names/MANIFEST-000016 deleted file mode 100644 index fd682e69cb9a49264a9ae5ce43168f01163b9757..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 399 zcmbOfbHR2h10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei199hGI!#Qch~IUQuds zX--M8VpVpjX|TITda$EOkWX+nx3H@}GS zCRhyvrfKd0A-P4CDJI$OP8Dh4evCTIV3qfHMKm}W7?}h)8JLAwzOt>~HmA}T$QJ_g zMOapFu`>#949Zc(bY55q531`uFpl6nx3H@}GS vCRhyvrfFG`1r~*cmS(}h&Y|f}nT%`Lz$!V`R$k;}U}Tc!WMGzIxy=gzaW^#Z literal 0 HcmV?d00001 diff --git a/packs-system/resonations/000017.log b/packs-system/resonations/000017.log deleted file mode 100644 index e69de29..0000000 diff --git a/packs-system/resonations/000019.ldb b/packs-system/resonations/000024.ldb similarity index 84% rename from packs-system/resonations/000019.ldb rename to packs-system/resonations/000024.ldb index 905dec0241d60e230f757b1daa6558a94d488f43..ab4250b49df4aa0e61d2b73012687e48f7d9b403 100644 GIT binary patch delta 38 ucmeBU?_(GF&E~=&e1}ajvm`aQSTV0OCxV%GdJN_O diff --git a/packs-system/resonations/000026.log b/packs-system/resonations/000026.log new file mode 100644 index 0000000000000000000000000000000000000000..e906f55013ca20b58fe93e491bc011ee5f83e264 GIT binary patch literal 15618 zcmeI3&yO5O6~_~aA3|LD11fXDR%X{(+cJ^GW$lR-3rwuF!9oZ{HQhBcywN>@cuYWXn-kVV#Z!IaD(#dmODmh|N*x#SLTUDz8D(54`^d`^ z-@0-rFP)0*WMV>8quZ*~wVoO^Ud_1^>!#{B)IO+5@U<#tA??{19r)Fuy04w{jT#$e z-NK)864n~_<2E=`zSlN`yAxeS^YL(CIC#;-!QG$zd^mVNHd^}-B}A{Y=+KIIec@lyNJPVCwDDjl0g-TU`e{mR1Eb3SC-)=#*} zV!cDz&MRB6@7cFOjStQCd)(8+SEUL4j*$g}yKfB#e(AWQnVo0kOmthxFXRs@J(b)3 z_~SF6|MY9SKz~mT&S!BMcpuB&F9Y?bCImaK1dt|7SBfBr8DoMC1%AqSs2pBgnfy4j=W)fJ`^F zkMo%ckgd>j0Y8nqyJ6i7%CZT?3kx;Y#x=sfY&CU4ghglxSV(lv@nXw6^2>!T+O}2` zX!Z8!=q*)S*ES{&m7ehVsO8KSGd1_tH3`IW%}Fq(TEWvW9M^?5$NZF-hTTE395#hc zFf}XWnnKAi4ip#@50`qiNBD&i{`;K>zpwcQgZ=QbghbKr|1#wIOay{fF=uHs1R`OW zp_Cv9v};}I(i%86Nr*Mc4pnIo4M#nZo|ggW5dyjHWCK_eadNLRrUY?AURhTfRK){u zH*MurPp-o?=ML40iA?~d@_Px0Cr#^wjFZTa{r5P%Fi!vXja|wAe$qDTVO6zB8(oeJ zcqJ~r2ay$Rg$RbTW;&FWB=!!k`M4Tw=oZ!$vZO}#*k~L{YNh5Vg+|9Z=>TQB+XCJz z5v9(nN^~^&UlgfU!F!fIfOruBh^e6prtni|Ka`zW)Cjeb6Ii|8Omv6nZ}^y60Xfam zq`_Gl%r9EY?Xve{{vnk>`ZI%Uxi&gcM{i$0RL6b*qLmWSt`5GZSWk3qpU09+ zMCaOOb?*K|X2~_7bRwwvOv;e^fBBTLohbScRL*>WHs7a=uRw?YW2X)uSs}sVvZVMc z#o#eYrW53G9smz&qVSccBouy@XzPRofjE)EF=n-q%hVSr^`ISR74Z0Kp`G%7VK!7Ua?0bo<#8N6yro(kQI#G3uZY0 z?nIM}7I7lrTzr;w&RFW|R49K=xiC~?Nd!@~PAB65(Si_PqIy!GOoLt|wq`qO2%=;h z!7^RsWfZyq zbJ>-V8q8MMV&mtS5UB>;n0LUW*s}TZ1(HOM>dm#=Az&Ka$v#`$L+Qd$`qxeo7Bzql2LYR%P2ck zqgMJ4V3|}bose8D&NODkn;2^MbqFh2a9@+PNyzC;;-fV}y2&ql*XRX0H?yve>W5jQ zK9hDx+BbI=q+>#vh_#lyzn3qn_CDO;Qkxrp+ZijkO;ww!@JDE}t3cIH34#f&pHq-d z9CZDTUX9{x2qLlNz8h6sIX#b%IjAPGQY#IQx3D;J*}!lhmZ-wJCUnwv6`~pY&ErhZkr^-DZt-J!E*Oklh=Rfgx>cgY zCEmwadvY*d+o1H=R#^|{o?~9h?Qy&;jAP3YO3r|WS=d%|_<5Bap4|0$yU#`Ey-IqaG%EL9or^aTKiOGM{=i{?J*Z5aU4=M129EU{I7$-+ zJWa_ogae|7)(Y~-`*M<6>trX)j+&kcygqJil@gLOOEL*P8j;&6If3cX?SmtAjT+6? z^lOf;=cWw1nPzFo6LgEtG~kKh<7q(%|^`D(NBq;%PpSD>O+AHJF=@0SAXSNo_1iuzu z6L|&xLzhv+{=jcQ-J~{Pv?Z#DbWkGfJtgBrMnCvfw!cSr-aP6GMggdL_pv&9Yp5Ox z$r^Pq?4~{t`h9+qq!im);s(3q_{=zoB%QolV&~1@)b!=WLgZMD#uV>t^C(^Wfc>MM z>Pp&^T?PAs*%KLGQN(1)2nu&wlj;~IfqZ5-L zKYVjnlj@NTSix5zsfbTAp%Ij0%Fu)Ay8Ic*srv*d*TX${jt|7yLkJ~qAKhMu89f>@ zhSU)cupxuK-P za_s*7m%o#AXVWl3x>HUk?I~DgeRcT&^37(t=*U4j&s(;ZOqVfT(U*B!A)L3v%zz5z z-n$tvNurG2ZLY)V^JVs_^1`X|S36VXkIYm&q=)W#8&+2#U@3tZETkq9+|VC|--$2! z0t`?@^39ku(hoz-^K{vymGVoB*F1Qmi4HN!oOox-7lp7tDK8C5NW|vJOlj1zfSE~2 zrR2|q`>0sXB5^#RjmRQbY8ur&MpJ*azeJa|SkKiZJft~rrY|5Z4EQ8pQo6c?h|hyR zTyUjaTaU9Kcn{s1qr5vAw?Aov@QWPrmK;&itmNu_JX|;){=L&9eyq_?t4o^#g5b7h zlfPibje=-KArVw)0Y+~)fCuXGu~a{4rT}+MnpeDC6F3VJMdk4-x?wn+g{GB-8Gs_+ z&O5`ByWnQ3b(!Z$QP58lXFUZA%fws~V`87}!FOTs{ds3S{$yrpBwYm-J{JF`gpU9O zEnRmidTw#z;`jq0RY<>tQI_Ek-(f3j0qJefg5 zR{_h&UZ)mD9;^VwsgIwgYXKKUugrzbS~m@r>ag)k#@D(g9237Xwe>l~DYE(V9=Q-f z(Nk$ZA$jd4N*qm){ZFYVI(Vj*#g;}!*C*}K#YvVnTaQ{`L!CWu-e)~2oCY1zdYNz* zgDMTWAu7(!xn+B+lTsVG)hQMtFU^yV*1hWUCT&tpxq8Pk%VVI|j;`;M#D$Z@ufMgc zwtgaGFjpi=Br!3E{F9RfAZt^LKxc$9OKUiJh{=--T4D7ho)^|E57iS!JH2T9zGXsm?HUT4~cdg^RcJo7dWNh zBr7)r;ImZ0=i6rY{`aYV=R$HZI#yzv!4uMd%bwmutXBp3Hc26PflE=$I-RS0UZs^BJ)V z=EW%P<6M$o;++ISnM1@_%a05RvNJTX2*fi;!Gv7Eco6ZMLYw_o2eIaPB3VB1)AJVL z87H2LWs1tBJg+5aDBryJ(uJX*>%9UVC+aVHhJiXxOU2hA6b8Xca0{vRPXl#4)?4Ap zdKjJL;YNOU=KZqe`B-^^6!jyN!FXkQ_-H+FmK_E4UUo2Yds?2~8&X-yk<}DZOX4Yw eN#c&Q$=;0Errp-~kg3&nk|vAyx&O=L{{I8xtC5WW literal 0 HcmV?d00001 diff --git a/packs-system/resonations/CURRENT b/packs-system/resonations/CURRENT index 42c62b6..f622090 100644 --- a/packs-system/resonations/CURRENT +++ b/packs-system/resonations/CURRENT @@ -1 +1 @@ -MANIFEST-000015 +MANIFEST-000025 diff --git a/packs-system/resonations/LOG b/packs-system/resonations/LOG index af090dd..eec0c31 100644 --- a/packs-system/resonations/LOG +++ b/packs-system/resonations/LOG @@ -1,15 +1,3 @@ -2026/05/10-10:14:24.373627 7ff6717ee6c0 Recovering log #12 -2026/05/10-10:14:24.384402 7ff6717ee6c0 Delete type=3 #10 -2026/05/10-10:14:24.384452 7ff6717ee6c0 Delete type=0 #12 -2026/05/10-10:15:09.092296 7ff6637fe6c0 Level-0 table #18: started -2026/05/10-10:15:09.095463 7ff6637fe6c0 Level-0 table #18: 7117 bytes OK -2026/05/10-10:15:09.101458 7ff6637fe6c0 Delete type=0 #16 -2026/05/10-10:15:09.121502 7ff6637fe6c0 Manual compaction at level-0 from '!items!mgne-res-accelerate' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) -2026/05/10-10:15:09.130878 7ff6637fe6c0 Manual compaction at level-1 from '!items!mgne-res-accelerate' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 61 : 1 -2026/05/10-10:15:09.130883 7ff6637fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-10:15:09.133861 7ff6637fe6c0 Generated table #19@1: 1 keys, 910 bytes -2026/05/10-10:15:09.133880 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 910 bytes -2026/05/10-10:15:09.141020 7ff6637fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-10:15:09.141125 7ff6637fe6c0 Delete type=2 #14 -2026/05/10-10:15:09.141229 7ff6637fe6c0 Delete type=2 #18 -2026/05/10-10:15:09.159847 7ff6637fe6c0 Manual compaction at level-1 from '!items!null' @ 61 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-15:40:00.721783 7f16433fe6c0 Recovering log #22 +2026/05/17-15:40:00.732595 7f16433fe6c0 Delete type=3 #20 +2026/05/17-15:40:00.732660 7f16433fe6c0 Delete type=0 #22 diff --git a/packs-system/resonations/LOG.old b/packs-system/resonations/LOG.old index 027e28f..c5d6c91 100644 --- a/packs-system/resonations/LOG.old +++ b/packs-system/resonations/LOG.old @@ -1,15 +1,15 @@ -2026/05/10-00:06:25.421327 7fe7219ff6c0 Recovering log #8 -2026/05/10-00:06:25.431320 7fe7219ff6c0 Delete type=3 #6 -2026/05/10-00:06:25.431377 7fe7219ff6c0 Delete type=0 #8 -2026/05/10-09:35:40.375666 7fe6d37fe6c0 Level-0 table #13: started -2026/05/10-09:35:40.378697 7fe6d37fe6c0 Level-0 table #13: 7117 bytes OK -2026/05/10-09:35:40.385574 7fe6d37fe6c0 Delete type=0 #11 -2026/05/10-09:35:40.404692 7fe6d37fe6c0 Manual compaction at level-0 from '!items!mgne-res-accelerate' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) -2026/05/10-09:35:40.423667 7fe6d37fe6c0 Manual compaction at level-1 from '!items!mgne-res-accelerate' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 41 : 1 -2026/05/10-09:35:40.423674 7fe6d37fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-09:35:40.426694 7fe6d37fe6c0 Generated table #14@1: 1 keys, 910 bytes -2026/05/10-09:35:40.426710 7fe6d37fe6c0 Compacted 1@1 + 1@2 files => 910 bytes -2026/05/10-09:35:40.433702 7fe6d37fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-09:35:40.433797 7fe6d37fe6c0 Delete type=2 #9 -2026/05/10-09:35:40.433894 7fe6d37fe6c0 Delete type=2 #13 -2026/05/10-09:35:40.443122 7fe6d37fe6c0 Manual compaction at level-1 from '!items!null' @ 41 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-13:26:05.061355 7f1642bfd6c0 Recovering log #17 +2026/05/17-13:26:05.072897 7f1642bfd6c0 Delete type=3 #15 +2026/05/17-13:26:05.072969 7f1642bfd6c0 Delete type=0 #17 +2026/05/17-15:39:46.204241 7f1641bfb6c0 Level-0 table #23: started +2026/05/17-15:39:46.207933 7f1641bfb6c0 Level-0 table #23: 7117 bytes OK +2026/05/17-15:39:46.215151 7f1641bfb6c0 Delete type=0 #21 +2026/05/17-15:39:46.215347 7f1641bfb6c0 Manual compaction at level-0 from '!items!mgne-res-accelerate' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-15:39:46.244725 7f1641bfb6c0 Manual compaction at level-1 from '!items!mgne-res-accelerate' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 81 : 1 +2026/05/17-15:39:46.244731 7f1641bfb6c0 Compacting 1@1 + 1@2 files +2026/05/17-15:39:46.247722 7f1641bfb6c0 Generated table #24@1: 1 keys, 910 bytes +2026/05/17-15:39:46.247731 7f1641bfb6c0 Compacted 1@1 + 1@2 files => 910 bytes +2026/05/17-15:39:46.253408 7f1641bfb6c0 compacted to: files[ 0 0 2 0 0 0 0 ] +2026/05/17-15:39:46.253506 7f1641bfb6c0 Delete type=2 #19 +2026/05/17-15:39:46.253663 7f1641bfb6c0 Delete type=2 #23 +2026/05/17-15:39:46.253842 7f1641bfb6c0 Manual compaction at level-1 from '!items!null' @ 81 : 1 .. '!items!null' @ 0 : 0; will stop at (end) diff --git a/packs-system/resonations/MANIFEST-000015 b/packs-system/resonations/MANIFEST-000015 deleted file mode 100644 index 95d761b248858d05822f450dfe7dc0b9b7c5395b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 340 zcmaEVIkkHg10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei199uwrIOYHqP&UTIDa zqb36wurskv*H?l{K3II>n0{Ar{<&rwWTsLLeya>DK5>;&CkotEG}Ubff>cu z$Btr$4MYN)m{NVNH3tJDlK>|JvmlF&Rf*PrQy^Cm$Q5P@U}qFMYmTBV0EU gbr%AmdPP_Q(EJHi#KtJZ#>B_YB#h=nZ017605Q^0CjbBd diff --git a/packs-system/resonations/MANIFEST-000025 b/packs-system/resonations/MANIFEST-000025 new file mode 100644 index 0000000000000000000000000000000000000000..b6dd3c512a26c90b93f9ac57cbf953a663a701fe GIT binary patch literal 192 zcmeZ$y6M;|21Z7yoYb<^oRlOzr^=Gl^338?=ltA)#G=HK{32FHVa3dn)ZAjlywaQ; z#y|!zU}s{TuCD}@$W6~n)h$Xb)=f-KPR&ULYD;Bggs8(%Qe2vwo1d4PSzN*>0y9dY cj~&I16o>>iv4T79>p2)0nWQ)wn59`#0PaOJHvj+t literal 0 HcmV?d00001 diff --git a/packs-system/weapons/000017.log b/packs-system/weapons/000017.log deleted file mode 100644 index e69de29..0000000 diff --git a/packs-system/weapons/000019.ldb b/packs-system/weapons/000024.ldb similarity index 71% rename from packs-system/weapons/000019.ldb rename to packs-system/weapons/000024.ldb index 41ee4fdba1269612c4b19222e31271fcdad20f75..1142f519cc939b4a3180585d59d001fb23716efa 100644 GIT binary patch delta 38 ucmeyw@`*)cD~k(*@H7_1%#zgHV#U1DoE%1*jUtB_S@_-U7f!y#I0FFmaSYD@ delta 38 ucmeyw@`*)cD~k(*@H7_1%#zgHV#U1DoE%1jjUtB_Sr$&>oHY3s;|u`!*9}_$ diff --git a/packs-system/weapons/000026.log b/packs-system/weapons/000026.log new file mode 100644 index 0000000000000000000000000000000000000000..f09842eb532e2dd729997ff93c28c8483fe590d3 GIT binary patch literal 6894 zcmeI1&2G~`5XY&65E48Ar>)QVXhc<2kvKql011TJRB%A3+IYwIiuLYxcOAE?`Wl?L zA#vdbZ@^pd1iS{bcA7NEI7;H)+)J}-dv<62%glc!!v_zK|2)}wcCY+)di=r3m2M73w>%WINRr;lC~eB$)26YXr?p}46g!4QyTjv25cWMgw#Q-%q32w zAOLX6P+8o7AGJ{$jN@SOI*u9G&~WWI?rj)6CzhvL0GWu4#h@gYF)4T6BX4ns36%_3 z40TF2ga5w4)%Lb z4+dzj^yk(55X!K1Wy8?p$vLtL?xL3af!iWX;CTR+Z>f2m8iU=VgiOW%t}&P zt%GH-hih&ZW3&=LO-gd^5<)M4U{E1e^G^uRX|8U93^@Ueiz@*-Y-3G*toi;QfF#4S zZycb)Y8^laTk|u;SW6wpG^OS#$#c|(9v^EO%u>Ir$pJdOBqO7&ov6I{@*Za#UrN&~ z`E|PCY@Ir!4wsQC-WaxhUQ$b3CAQYqLnNKKS*wnt99j$%DB7U;KA#DGwA zwHj(8)Cx89vy!vdO2#%8NIab8K!1QH5qq6~41REMnA>gkrC z6$E{&Bm@iYDv0X+R#OSn^>wy~W4899z;yEi^^7y}7ck7DmSzH4YVqqfyi_ zJm8Si5p$(3RtN#RLLPLsl@y5Vy|HE&!6nZjrtE!zufoAbyOLQWe9xh;zK z%oaJT$iQt8wrv&vt1>~2ec$9xMYNr*um(Vz$Y-gDT?nDAE_yik5*!fS&k{y33Xq$%{{ZR22Z+A^t literal 0 HcmV?d00001 diff --git a/packs-system/weapons/CURRENT b/packs-system/weapons/CURRENT index 42c62b6..f622090 100644 --- a/packs-system/weapons/CURRENT +++ b/packs-system/weapons/CURRENT @@ -1 +1 @@ -MANIFEST-000015 +MANIFEST-000025 diff --git a/packs-system/weapons/LOG b/packs-system/weapons/LOG index 77b5198..dca9fa9 100644 --- a/packs-system/weapons/LOG +++ b/packs-system/weapons/LOG @@ -1,15 +1,3 @@ -2026/05/10-10:14:24.413909 7ff671fef6c0 Recovering log #12 -2026/05/10-10:14:24.424039 7ff671fef6c0 Delete type=3 #10 -2026/05/10-10:14:24.424092 7ff671fef6c0 Delete type=0 #12 -2026/05/10-10:15:09.111128 7ff6637fe6c0 Level-0 table #18: started -2026/05/10-10:15:09.115029 7ff6637fe6c0 Level-0 table #18: 1965 bytes OK -2026/05/10-10:15:09.121359 7ff6637fe6c0 Delete type=0 #16 -2026/05/10-10:15:09.121532 7ff6637fe6c0 Manual compaction at level-0 from '!items!mgne-wpn-club' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) -2026/05/10-10:15:09.150422 7ff6637fe6c0 Manual compaction at level-1 from '!items!mgne-wpn-club' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 37 : 1 -2026/05/10-10:15:09.150429 7ff6637fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-10:15:09.153398 7ff6637fe6c0 Generated table #19@1: 1 keys, 626 bytes -2026/05/10-10:15:09.153408 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 626 bytes -2026/05/10-10:15:09.159589 7ff6637fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-10:15:09.159695 7ff6637fe6c0 Delete type=2 #14 -2026/05/10-10:15:09.159778 7ff6637fe6c0 Delete type=2 #18 -2026/05/10-10:15:09.159866 7ff6637fe6c0 Manual compaction at level-1 from '!items!null' @ 37 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-15:40:00.764360 7f16423fc6c0 Recovering log #22 +2026/05/17-15:40:00.775885 7f16423fc6c0 Delete type=3 #20 +2026/05/17-15:40:00.775980 7f16423fc6c0 Delete type=0 #22 diff --git a/packs-system/weapons/LOG.old b/packs-system/weapons/LOG.old index c1eaa27..1f08e71 100644 --- a/packs-system/weapons/LOG.old +++ b/packs-system/weapons/LOG.old @@ -1,15 +1,15 @@ -2026/05/10-00:06:25.460392 7fe7211fe6c0 Recovering log #8 -2026/05/10-00:06:25.470093 7fe7211fe6c0 Delete type=3 #6 -2026/05/10-00:06:25.470147 7fe7211fe6c0 Delete type=0 #8 -2026/05/10-09:35:40.385681 7fe6d37fe6c0 Level-0 table #13: started -2026/05/10-09:35:40.389078 7fe6d37fe6c0 Level-0 table #13: 1965 bytes OK -2026/05/10-09:35:40.394971 7fe6d37fe6c0 Delete type=0 #11 -2026/05/10-09:35:40.404700 7fe6d37fe6c0 Manual compaction at level-0 from '!items!mgne-wpn-club' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) -2026/05/10-09:35:40.414585 7fe6d37fe6c0 Manual compaction at level-1 from '!items!mgne-wpn-club' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 25 : 1 -2026/05/10-09:35:40.414592 7fe6d37fe6c0 Compacting 1@1 + 1@2 files -2026/05/10-09:35:40.417590 7fe6d37fe6c0 Generated table #14@1: 1 keys, 626 bytes -2026/05/10-09:35:40.417600 7fe6d37fe6c0 Compacted 1@1 + 1@2 files => 626 bytes -2026/05/10-09:35:40.423435 7fe6d37fe6c0 compacted to: files[ 0 0 2 0 0 0 0 ] -2026/05/10-09:35:40.423523 7fe6d37fe6c0 Delete type=2 #9 -2026/05/10-09:35:40.423607 7fe6d37fe6c0 Delete type=2 #13 -2026/05/10-09:35:40.443110 7fe6d37fe6c0 Manual compaction at level-1 from '!items!null' @ 25 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-13:26:05.105018 7f16423fc6c0 Recovering log #17 +2026/05/17-13:26:05.114474 7f16423fc6c0 Delete type=3 #15 +2026/05/17-13:26:05.114527 7f16423fc6c0 Delete type=0 #17 +2026/05/17-15:39:46.183373 7f1641bfb6c0 Level-0 table #23: started +2026/05/17-15:39:46.187330 7f1641bfb6c0 Level-0 table #23: 1965 bytes OK +2026/05/17-15:39:46.194074 7f1641bfb6c0 Delete type=0 #21 +2026/05/17-15:39:46.215323 7f1641bfb6c0 Manual compaction at level-0 from '!items!mgne-wpn-club' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end) +2026/05/17-15:39:46.215362 7f1641bfb6c0 Manual compaction at level-1 from '!items!mgne-wpn-club' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 49 : 1 +2026/05/17-15:39:46.215370 7f1641bfb6c0 Compacting 1@1 + 1@2 files +2026/05/17-15:39:46.218482 7f1641bfb6c0 Generated table #24@1: 1 keys, 626 bytes +2026/05/17-15:39:46.218497 7f1641bfb6c0 Compacted 1@1 + 1@2 files => 626 bytes +2026/05/17-15:39:46.224247 7f1641bfb6c0 compacted to: files[ 0 0 2 0 0 0 0 ] +2026/05/17-15:39:46.224396 7f1641bfb6c0 Delete type=2 #19 +2026/05/17-15:39:46.224564 7f1641bfb6c0 Delete type=2 #23 +2026/05/17-15:39:46.253795 7f1641bfb6c0 Manual compaction at level-1 from '!items!null' @ 49 : 1 .. '!items!null' @ 0 : 0; will stop at (end) diff --git a/packs-system/weapons/MANIFEST-000015 b/packs-system/weapons/MANIFEST-000015 deleted file mode 100644 index 08b70aef9ad15f70f1a7a33db7418461c3c5254d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 328 zcmd;_mUnp`10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAei199uwrIOYHqP&UTIDa zqa*_uursmtbICv@a?|rtb;}F#bdz&RlNcExDljC=GcpSpd0^W4KCz&fs{)b0CMMgX z=f%Om$RxnYz%0n3a^%F+8dD%w5Xco~F<@sDTFZ~3%>av0st_@eKT1mjp?XDF4AA@r VRm8?9#Ky$O&LoWHL~Q0l#Q>e%N*DkD diff --git a/packs-system/weapons/MANIFEST-000025 b/packs-system/weapons/MANIFEST-000025 new file mode 100644 index 0000000000000000000000000000000000000000..b57f97e712882fd22a81fb989d80ad428ecd114c GIT binary patch literal 180 zcmc~j6qrAcfss)vC$%g!CnZVGsj?)sJhM2}IX|}`u_&=5zlfDlSTVCCHMdwXuQVrz z(U1WQ*qK=Sxn!Ucx#@YSy5$9Vy2&}ENsNpT6&RA`8JPu)JTUDNpIA`LwSh=r6SFjI RSk1w}$Rx$dz%0#T0{|HlEm{Bo literal 0 HcmV?d00001 diff --git a/system.json b/system.json index 2d78841..f6530a3 100644 --- a/system.json +++ b/system.json @@ -35,9 +35,7 @@ }, "creature": { "htmlFields": [ - "description", - "special", - "notes" + "description" ] }, "companion": { @@ -45,6 +43,11 @@ "description", "notes" ] + }, + "party": { + "htmlFields": [ + "notes" + ] } }, "Item": { @@ -82,6 +85,11 @@ "htmlFields": [ "description" ] + }, + "creature-trait": { + "htmlFields": [ + "description" + ] } } }, diff --git a/templates/armor.hbs b/templates/armor.hbs index 15735d5..93c7f00 100644 --- a/templates/armor.hbs +++ b/templates/armor.hbs @@ -5,7 +5,7 @@ -

+
+
+ + +
+
+ + +
diff --git a/templates/artifact.hbs b/templates/artifact.hbs index 02e6168..6826feb 100644 --- a/templates/artifact.hbs +++ b/templates/artifact.hbs @@ -6,14 +6,6 @@
-
- - -
+
+ + +
+
+ + +
diff --git a/templates/character-equipment.hbs b/templates/character-equipment.hbs index 0289023..bc74a1c 100644 --- a/templates/character-equipment.hbs +++ b/templates/character-equipment.hbs @@ -1,9 +1,12 @@
-
- +
+
- + + {{system.currentLoad}} / {{system.carryCapacity}} +
@@ -27,14 +30,22 @@
{{#each weapons}} -
-
{{name}}
+
+
+ {{name}}{{#if system.broken}} {{localize "MGNE.Common.Broken"}}{{/if}} + {{#each system.properties}}{{lookup @root.config.weaponPropertyLabels this}}{{/each}} +
{{system.damage}}
{{lookup @root.config.weaponCategories system.category}}
+ {{lookup @root.config.weightCategories system.weight}} + + {{system.durabilityDie}} +
+ @@ -52,24 +63,34 @@
{{#each armors}} -
-
{{name}}
+
+
+ {{name}}{{#if system.broken}} {{localize "MGNE.Common.Broken"}}{{/if}} +
{{system.armorDie}}
{{localize "MGNE.Common.Penalty"}} {{system.penalty}}
+ {{lookup @root.config.weightCategories system.weight}} + {{system.durabilityDie}}
+
{{/each}} {{#each shields}} -
-
{{name}}
+
+
+ {{name}}{{#if system.broken}} {{localize "MGNE.Common.Broken"}}{{/if}} +
{{system.armorDie}}
{{localize "MGNE.ItemTypes.shield"}}
+ {{lookup @root.config.weightCategories system.weight}} + {{system.durabilityDie}}
+
@@ -83,11 +104,16 @@
{{#each equipmentItems}} -
-
{{name}}
+
+
+ {{name}}{{#if system.broken}} {{localize "MGNE.Common.Broken"}}{{/if}} +
{{localize "MGNE.Common.QuantityShort"}} {{system.quantity}}
{{system.usageDie}}
+ {{lookup @root.config.weightCategories system.weight}} + {{system.durabilityDie}}
+ @@ -104,12 +130,18 @@
{{#each cores}} -
-
{{name}}
+
+
+ {{name}}{{#if system.broken}} {{localize "MGNE.Common.Broken"}}{{/if}} + {{#if system.burnedOut}} {{localize "MGNE.Common.BurnedOut"}}{{/if}} +
{{lookup @root.config.resonanceList system.resonationId}}
{{system.usageDie}}
+ {{lookup @root.config.weightCategories system.weight}} + {{system.durabilityDie}}
+ @@ -126,12 +158,17 @@
{{#each artifacts}} -
-
{{name}}
+
+
+ {{name}}{{#if system.broken}} {{localize "MGNE.Common.Broken"}}{{/if}} +
{{#if system.synchronized}}{{localize "MGNE.Common.Synchronized"}}{{else}}{{localize "MGNE.Common.Unsynchronized"}}{{/if}}
{{system.usageDie}}
+ {{lookup @root.config.weightCategories system.weight}} + {{system.durabilityDie}}
+ diff --git a/templates/character-features.hbs b/templates/character-features.hbs index 9a835a3..14b1f53 100644 --- a/templates/character-features.hbs +++ b/templates/character-features.hbs @@ -5,7 +5,7 @@
{{#each features}}
-
{{name}}
+
{{name}}
diff --git a/templates/character-overview.hbs b/templates/character-overview.hbs index 381cdb5..f8d5f3d 100644 --- a/templates/character-overview.hbs +++ b/templates/character-overview.hbs @@ -19,6 +19,13 @@ {{localize "MGNE.Abilities.agility"}}
+
+ +
+ {{#if system.armorFormula}}{{system.armorFormula}}{{else}}—{{/if}} + {{localize "MGNE.Common.ArmorDie"}} +
+
diff --git a/templates/chat-message.hbs b/templates/chat-message.hbs index 21f9c35..a6ee7dd 100644 --- a/templates/chat-message.hbs +++ b/templates/chat-message.hbs @@ -11,12 +11,19 @@ {{#if subtitle}}

{{subtitle}}

{{/if}} {{#if formula}}

{{formula}}

{{/if}} {{#if outcome}} -
+
{{outcome}} {{total}} + {{#if diceTooltip}}{{/if}}
{{else if total}} -
{{total}}
+
+ {{total}} + {{#if diceTooltip}}{{/if}} +
+ {{/if}} + {{#if diceTooltip}} + {{/if}} {{#if specialText}}

{{specialText}}

{{/if}} {{#if omenNeutralizeReminder}}

💡 {{omenNeutralizeReminder}}

{{/if}} diff --git a/templates/companion-main.hbs b/templates/companion-main.hbs index 7763abb..ece76af 100644 --- a/templates/companion-main.hbs +++ b/templates/companion-main.hbs @@ -42,21 +42,6 @@
-
- {{#each abilityList}} -
- -
- -
-
- {{/each}} -
-

{{localize "MGNE.Common.Attack"}}

diff --git a/templates/creature-main.hbs b/templates/creature-main.hbs index c86f8e1..0181a56 100644 --- a/templates/creature-main.hbs +++ b/templates/creature-main.hbs @@ -42,69 +42,91 @@
-
- {{#each abilityList}} -
- -
- -
-
- {{/each}} + +
+
+ {{localize "MGNE.Creature.Type"}} + {{#each creatureTypes}} + + {{/each}} +
+
+ + +
+ +
+
+

{{localize "MGNE.Creature.ActionTable"}}

+ {{#if actionTable}} +
+ + + +
+ {{/if}} +
+
+ {{#if actionTable}} + + {{actionTable.name}} + {{else}} + + {{localize "MGNE.Creature.DropTableHint"}} + {{/if}} +
+
+ + +
+
+

{{localize "MGNE.Creature.Traits"}}

+ +
+
+ {{#each traits}} +
+
+
+ + {{name}} +
+ {{#if system.trigger}} + {{system.trigger}} + {{/if}} +
+ + +
+
+
+ {{else}} +

{{localize "MGNE.Empty.NoTraits"}}

+ {{/each}} +
+
+ +
-

{{localize "MGNE.Common.Attack"}}

+

{{localize "MGNE.Common.Description"}}

-
-
- - -
-
- - -
-
- - - -
-
+ {{formInput systemFields.description enriched=(lookup enrichedFields "description") value=system.description name="system.description" toggled=true}}
-
-
-
-

{{localize "MGNE.Common.Description"}}

-
-
- {{formInput systemFields.description enriched=(lookup enrichedFields "description") value=system.description name="system.description" toggled=true}} -
-
-
-
-

{{localize "MGNE.Creature.Special"}}

-
-
- {{formInput systemFields.special enriched=(lookup enrichedFields "special") value=system.special name="system.special" toggled=true}} -
-
-
- -
-
-

{{localize "MGNE.Common.Notes"}}

-
-
- {{formInput systemFields.notes enriched=(lookup enrichedFields "notes") value=system.notes name="system.notes" toggled=true}} -
-
diff --git a/templates/creature-trait.hbs b/templates/creature-trait.hbs new file mode 100644 index 0000000..bfd739e --- /dev/null +++ b/templates/creature-trait.hbs @@ -0,0 +1,20 @@ +
+
+ {{item.name}} +
+ +
+
+
+
+ + +
+
+
+

{{localize "MGNE.Common.Description"}}

+
+
+ {{formInput systemFields.description enriched=(lookup enrichedFields "description") value=system.description name="system.description" toggled=true}} +
+
diff --git a/templates/equipment.hbs b/templates/equipment.hbs index 3999116..6caf591 100644 --- a/templates/equipment.hbs +++ b/templates/equipment.hbs @@ -14,6 +14,14 @@ {{/each}}
+
+ + +
@@ -26,11 +34,20 @@ {{/each}}
+
+ + +
+

{{localize "MGNE.Common.Description"}}

diff --git a/templates/party-loot.hbs b/templates/party-loot.hbs new file mode 100644 index 0000000..94e63c3 --- /dev/null +++ b/templates/party-loot.hbs @@ -0,0 +1,37 @@ +
+ + +

{{localize "MGNE.Party.DropLootHint"}}

+
diff --git a/templates/party-main.hbs b/templates/party-main.hbs new file mode 100644 index 0000000..198ccf5 --- /dev/null +++ b/templates/party-main.hbs @@ -0,0 +1,21 @@ +
+
+
+ {{actor.name}} +
+
+ +
+ +
+ + + + + + +
+
+
+
+
diff --git a/templates/party-members.hbs b/templates/party-members.hbs new file mode 100644 index 0000000..d4efefa --- /dev/null +++ b/templates/party-members.hbs @@ -0,0 +1,48 @@ +
+
+
+

{{localize "MGNE.Party.Members"}}

+
+ + {{#if members.length}} +
+
+ + {{localize "MGNE.Common.Name"}} + {{localize "MGNE.Common.HP"}} + {{localize "MGNE.Common.Type"}} + +
+ {{#each members as |member|}} +
+ + + {{member.name}} + + {{member.hp}} + {{member.typeLabel}} +
+ {{#unless member.isFirst}} + + + + {{/unless}} + {{#unless member.isLast}} + + + + {{/unless}} + + + +
+
+ {{/each}} +
+ {{else}} +

{{localize "MGNE.Empty.NoMembers"}}

+ {{/if}} +
+ +

{{localize "MGNE.Party.DropMemberHint"}}

+
diff --git a/templates/party-notes.hbs b/templates/party-notes.hbs new file mode 100644 index 0000000..ad86f71 --- /dev/null +++ b/templates/party-notes.hbs @@ -0,0 +1,10 @@ +
+
+
+

{{localize "MGNE.Common.Notes"}}

+
+
+ {{formInput systemFields.notes enriched=(lookup enrichedFields "notes") value=system.notes name="system.notes" toggled=true}} +
+
+
diff --git a/templates/party-tabs.hbs b/templates/party-tabs.hbs new file mode 100644 index 0000000..ba44c2d --- /dev/null +++ b/templates/party-tabs.hbs @@ -0,0 +1,5 @@ + diff --git a/templates/resonance-core.hbs b/templates/resonance-core.hbs index 7baa5cd..3068fd7 100644 --- a/templates/resonance-core.hbs +++ b/templates/resonance-core.hbs @@ -5,7 +5,7 @@
-
+
+
+ + +
+
+ + +
+

{{localize "MGNE.Common.Description"}}

diff --git a/templates/shield.hbs b/templates/shield.hbs index 15735d5..93c7f00 100644 --- a/templates/shield.hbs +++ b/templates/shield.hbs @@ -5,7 +5,7 @@
-
+
+
+ + +
+
+ + +
diff --git a/templates/weapon.hbs b/templates/weapon.hbs index 6c75483..c47f65e 100644 --- a/templates/weapon.hbs +++ b/templates/weapon.hbs @@ -23,8 +23,20 @@
- - + + +
+
+ +
@@ -43,6 +55,19 @@
+
+

{{localize "MGNE.Common.Properties"}}

+
+
+ + {{#each selectOptions.weaponProperties}} + + {{/each}} +

{{localize "MGNE.Common.Description"}}