Fix as per CSV sheet tracking + creature explanation
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<!-- Claw / trait mark: three slash marks with a radiating spark -->
|
||||
<g fill="none" stroke="#c0392b" stroke-linecap="round" stroke-linejoin="round">
|
||||
<!-- Three diagonal claw marks -->
|
||||
<line x1="22" y1="20" x2="48" y2="62" stroke-width="7" opacity="0.9"/>
|
||||
<line x1="36" y1="18" x2="58" y2="60" stroke-width="7" opacity="0.75"/>
|
||||
<line x1="50" y1="18" x2="68" y2="58" stroke-width="7" opacity="0.6"/>
|
||||
<!-- Bolt / energy accent -->
|
||||
<polyline points="60,30 52,50 64,50 54,72" stroke="#e74c3c" stroke-width="4" opacity="0.85"/>
|
||||
</g>
|
||||
<!-- Outer ring frame -->
|
||||
<circle cx="50" cy="50" r="46" fill="none" stroke="#7f1d1d" stroke-width="3" opacity="0.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 750 B |
@@ -0,0 +1,13 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
|
||||
<!-- Resonation icon: stylised signal/energy wave within a circuit frame -->
|
||||
<circle cx="50" cy="50" r="46" fill="none" stroke="#c8a94a" stroke-width="3" opacity="0.85"/>
|
||||
<circle cx="50" cy="50" r="36" fill="none" stroke="#c8a94a" stroke-width="1.5" opacity="0.45"/>
|
||||
<!-- Wave / resonation lines -->
|
||||
<path d="M18 50 Q26 34 34 50 Q42 66 50 50 Q58 34 66 50 Q74 66 82 50"
|
||||
fill="none" stroke="#dd9b2a" stroke-width="3.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<!-- Corner circuit nodes -->
|
||||
<circle cx="50" cy="18" r="4" fill="#c8a94a" opacity="0.9"/>
|
||||
<circle cx="50" cy="82" r="4" fill="#c8a94a" opacity="0.9"/>
|
||||
<line x1="50" y1="22" x2="50" y2="37" stroke="#c8a94a" stroke-width="2" opacity="0.6"/>
|
||||
<line x1="50" y1="63" x2="50" y2="78" stroke="#c8a94a" stroke-width="2" opacity="0.6"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 892 B |
+722
-95
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
+145
-33
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+670
-2
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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" },
|
||||
}
|
||||
}
|
||||
@@ -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) })
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
@@ -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,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000015
|
||||
MANIFEST-000025
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
2026/05/10-10:14:24.425893 7ff663fff6c0 Recovering log #12
|
||||
2026/05/10-10:14:24.435701 7ff663fff6c0 Delete type=3 #10
|
||||
2026/05/10-10:14:24.435782 7ff663fff6c0 Delete type=0 #12
|
||||
2026/05/10-10:15:09.159943 7ff6637fe6c0 Level-0 table #18: started
|
||||
2026/05/10-10:15:09.164167 7ff6637fe6c0 Level-0 table #18: 1354 bytes OK
|
||||
2026/05/10-10:15:09.170159 7ff6637fe6c0 Delete type=0 #16
|
||||
2026/05/10-10:15:09.193554 7ff6637fe6c0 Manual compaction at level-0 from '!items!mgne-arm-chainshirt' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at (end)
|
||||
2026/05/10-10:15:09.193605 7ff6637fe6c0 Manual compaction at level-1 from '!items!mgne-arm-chainshirt' @ 72057594037927935 : 1 .. '!items!null' @ 0 : 0; will stop at '!items!null' @ 25 : 1
|
||||
2026/05/10-10:15:09.193611 7ff6637fe6c0 Compacting 1@1 + 1@2 files
|
||||
2026/05/10-10:15:09.197820 7ff6637fe6c0 Generated table #19@1: 1 keys, 685 bytes
|
||||
2026/05/10-10:15:09.197839 7ff6637fe6c0 Compacted 1@1 + 1@2 files => 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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000015
|
||||
MANIFEST-000025
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000015
|
||||
MANIFEST-000025
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000016
|
||||
MANIFEST-000026
|
||||
|
||||
+3
-15
@@ -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
|
||||
|
||||
+15
-15
@@ -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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000015
|
||||
MANIFEST-000025
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000015
|
||||
MANIFEST-000025
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
+11
-3
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+17
-1
@@ -5,7 +5,7 @@
|
||||
<input type="text" name="name" value="{{source.name}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-form-grid item-form-grid-two">
|
||||
<div class="item-form-grid item-form-grid-three">
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.ArmorDie"}}</label>
|
||||
<select name="system.armorDie">
|
||||
@@ -22,6 +22,22 @@
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.Weight"}}</label>
|
||||
<select name="system.weight">
|
||||
{{#each selectOptions.weightCategories}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.weight value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.DurabilityDie"}}</label>
|
||||
<select name="system.durabilityDie">
|
||||
{{#each selectOptions.usageDice}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.durabilityDie value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-check-grid check-grid">
|
||||
<label><input type="checkbox" name="system.equipped" {{#if source.system.equipped}}checked{{/if}} /> {{localize "MGNE.Common.Equipped"}}</label>
|
||||
|
||||
+16
-8
@@ -6,14 +6,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-form-grid item-form-grid-three">
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.ArtifactId"}}</label>
|
||||
<select name="system.artifactId">
|
||||
{{#each selectOptions.artifactIds}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.artifactId value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.UsageDie"}}</label>
|
||||
<select name="system.usageDie">
|
||||
@@ -22,6 +14,22 @@
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.Weight"}}</label>
|
||||
<select name="system.weight">
|
||||
{{#each selectOptions.weightCategories}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.weight value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.DurabilityDie"}}</label>
|
||||
<select name="system.durabilityDie">
|
||||
{{#each selectOptions.usageDice}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.durabilityDie value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.SynchronizedTo"}}</label>
|
||||
<input type="text" name="system.synchronizedTo" value="{{source.system.synchronizedTo}}" />
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<section class="tab-panel {{tab.cssClass}}">
|
||||
<div class="resource-bar resource-bar-equipment">
|
||||
<div class="resource-box resource-box-single resource-box-compact resource-box-inline resource-box-inline-single">
|
||||
<label class="resource-label-accent">{{localize "MGNE.Character.CarryingCapacity"}}</label>
|
||||
<div class="resource-box resource-box-single resource-box-compact resource-box-inline resource-box-inline-single {{#if system.overloaded}}resource-box-overloaded{{/if}}">
|
||||
<label class="resource-label-accent">{{localize "MGNE.Character.Load"}}</label>
|
||||
<div class="numeric-pill">
|
||||
<input class="numeric-input numeric-input-readonly" type="number" name="system.carryCapacity" value="{{system.carryCapacity}}" readonly />
|
||||
<span class="numeric-input numeric-input-readonly load-display {{#if system.overloaded}}load-overloaded{{/if}}"
|
||||
title="{{system.lightItemCount}} light items (10 = 1 slot){{#if system.heavyItemCount}} · {{system.heavyItemCount}} heavy{{/if}}">
|
||||
{{system.currentLoad}} / {{system.carryCapacity}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-box resource-box-single resource-box-compact resource-box-inline resource-box-inline-single">
|
||||
@@ -27,14 +30,22 @@
|
||||
<button type="button" data-action="createItem" data-item-type="weapon">{{localize "MGNE.Character.AddWeapon"}}</button>
|
||||
</div>
|
||||
{{#each weapons}}
|
||||
<div class="item-row" data-item-id="{{id}}">
|
||||
<div class="item-name">{{name}}</div>
|
||||
<div class="item-row {{#if system.broken}}item-row-broken{{/if}}" data-item-id="{{id}}">
|
||||
<div class="item-name" {{#if tooltip}}data-tooltip="{{tooltip}}" data-tooltip-class="mgne-item-tooltip"{{/if}}>
|
||||
{{name}}{{#if system.broken}} <span class="item-broken-badge">{{localize "MGNE.Common.Broken"}}</span>{{/if}}
|
||||
{{#each system.properties}}<span class="weapon-property-badge">{{lookup @root.config.weaponPropertyLabels this}}</span>{{/each}}
|
||||
</div>
|
||||
<div>{{system.damage}}</div>
|
||||
<div>{{lookup @root.config.weaponCategories system.category}}</div>
|
||||
<span class="item-weight-badge weight-{{system.weight}}">{{lookup @root.config.weightCategories system.weight}}</span>
|
||||
<span class="item-durability-badge {{#if system.broken}}durability-broken{{/if}}">
|
||||
<i class="fa-solid fa-shield-halved"></i> {{system.durabilityDie}}
|
||||
</span>
|
||||
<div class="item-actions">
|
||||
<button type="button" data-action="toggleEquipped">{{#if system.equipped}}{{localize "MGNE.Common.Unequip"}}{{else}}{{localize "MGNE.Common.Equip"}}{{/if}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="weapon">{{localize "MGNE.Common.Attack"}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="damage">{{localize "MGNE.Common.Damage"}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="durability" data-tooltip="{{localize "MGNE.Common.RollDurability"}}">{{localize "MGNE.Common.Durability"}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="usage">{{localize "MGNE.Common.Usage"}}</button>
|
||||
<button type="button" data-action="editItem">{{localize "MGNE.Common.Edit"}}</button>
|
||||
<button type="button" data-action="deleteItem">{{localize "MGNE.Common.Delete"}}</button>
|
||||
@@ -52,24 +63,34 @@
|
||||
<button type="button" data-action="createItem" data-item-type="shield">{{localize "MGNE.Character.AddShield"}}</button>
|
||||
</div>
|
||||
{{#each armors}}
|
||||
<div class="item-row" data-item-id="{{id}}">
|
||||
<div class="item-name">{{name}}</div>
|
||||
<div class="item-row {{#if system.broken}}item-row-broken{{/if}}" data-item-id="{{id}}">
|
||||
<div class="item-name" {{#if tooltip}}data-tooltip="{{tooltip}}" data-tooltip-class="mgne-item-tooltip"{{/if}}>
|
||||
{{name}}{{#if system.broken}} <span class="item-broken-badge">{{localize "MGNE.Common.Broken"}}</span>{{/if}}
|
||||
</div>
|
||||
<div>{{system.armorDie}}</div>
|
||||
<div>{{localize "MGNE.Common.Penalty"}} {{system.penalty}}</div>
|
||||
<span class="item-weight-badge weight-{{system.weight}}">{{lookup @root.config.weightCategories system.weight}}</span>
|
||||
<span class="item-durability-badge {{#if system.broken}}durability-broken{{/if}}"><i class="fa-solid fa-shield-halved"></i> {{system.durabilityDie}}</span>
|
||||
<div class="item-actions">
|
||||
<button type="button" data-action="toggleEquipped">{{#if system.equipped}}{{localize "MGNE.Common.Unequip"}}{{else}}{{localize "MGNE.Common.Equip"}}{{/if}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="durability">{{localize "MGNE.Common.Durability"}}</button>
|
||||
<button type="button" data-action="editItem">{{localize "MGNE.Common.Edit"}}</button>
|
||||
<button type="button" data-action="deleteItem">{{localize "MGNE.Common.Delete"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{#each shields}}
|
||||
<div class="item-row" data-item-id="{{id}}">
|
||||
<div class="item-name">{{name}}</div>
|
||||
<div class="item-row {{#if system.broken}}item-row-broken{{/if}}" data-item-id="{{id}}">
|
||||
<div class="item-name" {{#if tooltip}}data-tooltip="{{tooltip}}" data-tooltip-class="mgne-item-tooltip"{{/if}}>
|
||||
{{name}}{{#if system.broken}} <span class="item-broken-badge">{{localize "MGNE.Common.Broken"}}</span>{{/if}}
|
||||
</div>
|
||||
<div>{{system.armorDie}}</div>
|
||||
<div>{{localize "MGNE.ItemTypes.shield"}}</div>
|
||||
<span class="item-weight-badge weight-{{system.weight}}">{{lookup @root.config.weightCategories system.weight}}</span>
|
||||
<span class="item-durability-badge {{#if system.broken}}durability-broken{{/if}}"><i class="fa-solid fa-shield-halved"></i> {{system.durabilityDie}}</span>
|
||||
<div class="item-actions">
|
||||
<button type="button" data-action="toggleEquipped">{{#if system.equipped}}{{localize "MGNE.Common.Unequip"}}{{else}}{{localize "MGNE.Common.Equip"}}{{/if}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="durability">{{localize "MGNE.Common.Durability"}}</button>
|
||||
<button type="button" data-action="editItem">{{localize "MGNE.Common.Edit"}}</button>
|
||||
<button type="button" data-action="deleteItem">{{localize "MGNE.Common.Delete"}}</button>
|
||||
</div>
|
||||
@@ -83,11 +104,16 @@
|
||||
<button type="button" data-action="createItem" data-item-type="equipment">{{localize "MGNE.Character.AddEquipment"}}</button>
|
||||
</div>
|
||||
{{#each equipmentItems}}
|
||||
<div class="item-row" data-item-id="{{id}}">
|
||||
<div class="item-name">{{name}}</div>
|
||||
<div class="item-row {{#if system.broken}}item-row-broken{{/if}}" data-item-id="{{id}}">
|
||||
<div class="item-name" {{#if tooltip}}data-tooltip="{{tooltip}}" data-tooltip-class="mgne-item-tooltip"{{/if}}>
|
||||
{{name}}{{#if system.broken}} <span class="item-broken-badge">{{localize "MGNE.Common.Broken"}}</span>{{/if}}
|
||||
</div>
|
||||
<div>{{localize "MGNE.Common.QuantityShort"}} {{system.quantity}}</div>
|
||||
<div>{{system.usageDie}}</div>
|
||||
<span class="item-weight-badge weight-{{system.weight}}">{{lookup @root.config.weightCategories system.weight}}</span>
|
||||
<span class="item-durability-badge {{#if system.broken}}durability-broken{{/if}}"><i class="fa-solid fa-shield-halved"></i> {{system.durabilityDie}}</span>
|
||||
<div class="item-actions">
|
||||
<button type="button" class="rollable" data-roll-type="durability">{{localize "MGNE.Common.Durability"}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="usage">{{localize "MGNE.Common.Usage"}}</button>
|
||||
<button type="button" data-action="editItem">{{localize "MGNE.Common.Edit"}}</button>
|
||||
<button type="button" data-action="deleteItem">{{localize "MGNE.Common.Delete"}}</button>
|
||||
@@ -104,12 +130,18 @@
|
||||
<button type="button" data-action="createItem" data-item-type="resonance-core">{{localize "MGNE.Character.AddCore"}}</button>
|
||||
</div>
|
||||
{{#each cores}}
|
||||
<div class="item-row" data-item-id="{{id}}">
|
||||
<div class="item-name">{{name}}</div>
|
||||
<div class="item-row {{#if system.broken}}item-row-broken{{/if}}" data-item-id="{{id}}">
|
||||
<div class="item-name" {{#if tooltip}}data-tooltip="{{tooltip}}" data-tooltip-class="mgne-item-tooltip"{{/if}}>
|
||||
{{name}}{{#if system.broken}} <span class="item-broken-badge">{{localize "MGNE.Common.Broken"}}</span>{{/if}}
|
||||
{{#if system.burnedOut}} <span class="item-broken-badge item-burned-badge">{{localize "MGNE.Common.BurnedOut"}}</span>{{/if}}
|
||||
</div>
|
||||
<div>{{lookup @root.config.resonanceList system.resonationId}}</div>
|
||||
<div>{{system.usageDie}}</div>
|
||||
<span class="item-weight-badge weight-{{system.weight}}">{{lookup @root.config.weightCategories system.weight}}</span>
|
||||
<span class="item-durability-badge {{#if system.broken}}durability-broken{{/if}}"><i class="fa-solid fa-shield-halved"></i> {{system.durabilityDie}}</span>
|
||||
<div class="item-actions">
|
||||
<button type="button" class="rollable" data-roll-type="resonation">{{localize "MGNE.Common.Invoke"}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="durability">{{localize "MGNE.Common.Durability"}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="usage">{{localize "MGNE.Common.Usage"}}</button>
|
||||
<button type="button" data-action="editItem">{{localize "MGNE.Common.Edit"}}</button>
|
||||
<button type="button" data-action="deleteItem">{{localize "MGNE.Common.Delete"}}</button>
|
||||
@@ -126,12 +158,17 @@
|
||||
<button type="button" data-action="createItem" data-item-type="artifact">{{localize "MGNE.Character.AddArtifact"}}</button>
|
||||
</div>
|
||||
{{#each artifacts}}
|
||||
<div class="item-row" data-item-id="{{id}}">
|
||||
<div class="item-name">{{name}}</div>
|
||||
<div class="item-row {{#if system.broken}}item-row-broken{{/if}}" data-item-id="{{id}}">
|
||||
<div class="item-name" {{#if tooltip}}data-tooltip="{{tooltip}}" data-tooltip-class="mgne-item-tooltip"{{/if}}>
|
||||
{{name}}{{#if system.broken}} <span class="item-broken-badge">{{localize "MGNE.Common.Broken"}}</span>{{/if}}
|
||||
</div>
|
||||
<div>{{#if system.synchronized}}{{localize "MGNE.Common.Synchronized"}}{{else}}{{localize "MGNE.Common.Unsynchronized"}}{{/if}}</div>
|
||||
<div>{{system.usageDie}}</div>
|
||||
<span class="item-weight-badge weight-{{system.weight}}">{{lookup @root.config.weightCategories system.weight}}</span>
|
||||
<span class="item-durability-badge {{#if system.broken}}durability-broken{{/if}}"><i class="fa-solid fa-shield-halved"></i> {{system.durabilityDie}}</span>
|
||||
<div class="item-actions">
|
||||
<button type="button" data-action="syncArtifact">{{#if system.synchronized}}{{localize "MGNE.Common.Desync"}}{{else}}{{localize "MGNE.Common.Sync"}}{{/if}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="durability">{{localize "MGNE.Common.Durability"}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="usage">{{localize "MGNE.Common.Usage"}}</button>
|
||||
<button type="button" data-action="editItem">{{localize "MGNE.Common.Edit"}}</button>
|
||||
<button type="button" data-action="deleteItem">{{localize "MGNE.Common.Delete"}}</button>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</div>
|
||||
{{#each features}}
|
||||
<div class="item-row" data-item-id="{{id}}">
|
||||
<div class="item-name">{{name}}</div>
|
||||
<div class="item-name" {{#if tooltip}}data-tooltip="{{tooltip}}" data-tooltip-class="mgne-item-tooltip"{{/if}}>{{name}}</div>
|
||||
<div class="item-actions">
|
||||
<button type="button" data-action="editItem">{{localize "MGNE.Common.Edit"}}</button>
|
||||
<button type="button" data-action="deleteItem">{{localize "MGNE.Common.Delete"}}</button>
|
||||
|
||||
@@ -19,6 +19,13 @@
|
||||
<small class="ability-defense-sub">{{localize "MGNE.Abilities.agility"}}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ability-card ability-card-armor">
|
||||
<label class="rollable ability-label" data-roll-type="armor">{{localize "MGNE.Common.ArmorSave"}}</label>
|
||||
<div class="ability-score ability-score-text">
|
||||
<span class="ability-defense-main">{{#if system.armorFormula}}{{system.armorFormula}}{{else}}—{{/if}}</span>
|
||||
<small class="ability-defense-sub">{{localize "MGNE.Common.ArmorDie"}}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid two">
|
||||
|
||||
@@ -11,12 +11,19 @@
|
||||
{{#if subtitle}}<p class="chat-subtitle"><strong>{{subtitle}}</strong></p>{{/if}}
|
||||
{{#if formula}}<p class="chat-formula"><code>{{formula}}</code></p>{{/if}}
|
||||
{{#if outcome}}
|
||||
<div class="chat-outcome">
|
||||
<div class="chat-outcome {{#if diceTooltip}}has-tooltip{{/if}}" role="button" tabindex="0" data-action="toggle-dice-tooltip">
|
||||
<span class="chat-outcome-label">{{outcome}}</span>
|
||||
<span class="chat-outcome-total">{{total}}</span>
|
||||
{{#if diceTooltip}}<i class="chat-tooltip-icon fa-solid fa-dice"></i>{{/if}}
|
||||
</div>
|
||||
{{else if total}}
|
||||
<div class="chat-damage-total">{{total}}</div>
|
||||
<div class="chat-damage-total {{#if diceTooltip}}has-tooltip{{/if}}" role="button" tabindex="0" data-action="toggle-dice-tooltip">
|
||||
{{total}}
|
||||
{{#if diceTooltip}}<i class="chat-tooltip-icon fa-solid fa-dice"></i>{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if diceTooltip}}
|
||||
<div class="chat-dice-tooltip" hidden>{{{diceTooltip}}}</div>
|
||||
{{/if}}
|
||||
{{#if specialText}}<p class="chat-special">{{specialText}}</p>{{/if}}
|
||||
{{#if omenNeutralizeReminder}}<p class="chat-omen-remind chat-omen-neutralize">💡 {{omenNeutralizeReminder}}</p>{{/if}}
|
||||
|
||||
@@ -42,21 +42,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ability-grid">
|
||||
{{#each abilityList}}
|
||||
<div class="ability-card">
|
||||
<label class="rollable ability-label" data-roll-type="ability" data-ability-id="{{id}}">{{label}}</label>
|
||||
<div class="ability-score">
|
||||
<select class="numeric-input ability-input" name="system.abilities.{{id}}.value">
|
||||
{{#each @root.selectOptions.abilityValues}}
|
||||
<option value="{{value}}" {{#if (isEqual ../value value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<div class="inventory-section">
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Attack"}}</h3>
|
||||
|
||||
+67
-45
@@ -42,45 +42,84 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ability-grid">
|
||||
{{#each abilityList}}
|
||||
<div class="ability-card">
|
||||
<label class="rollable ability-label" data-roll-type="ability" data-ability-id="{{id}}">{{label}}</label>
|
||||
<div class="ability-score">
|
||||
<select class="numeric-input ability-input" name="system.abilities.{{id}}.value">
|
||||
{{#each @root.selectOptions.abilityValues}}
|
||||
<option value="{{value}}" {{#if (isEqual ../value value)}}selected{{/if}}>{{label}}</option>
|
||||
<!-- Type + Number row -->
|
||||
<div class="creature-meta-row">
|
||||
<div class="creature-type-group">
|
||||
<span class="creature-meta-label">{{localize "MGNE.Creature.Type"}}</span>
|
||||
{{#each creatureTypes}}
|
||||
<label class="creature-type-checkbox">
|
||||
<input type="checkbox" name="system.creatureType" value="{{key}}" {{#if checked}}checked{{/if}} />
|
||||
<span>{{label}}</span>
|
||||
</label>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="creature-number-group">
|
||||
<label class="creature-meta-label" for="creature-number">{{localize "MGNE.Creature.Number"}}</label>
|
||||
<input id="creature-number" class="creature-number-input" type="text" name="system.number" value="{{source.system.number}}" />
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<div class="inventory-section">
|
||||
<!-- Action Table -->
|
||||
<div class="inventory-section creature-action-table-section">
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Attack"}}</h3>
|
||||
<h3>{{localize "MGNE.Creature.ActionTable"}}</h3>
|
||||
{{#if actionTable}}
|
||||
<div class="action-table-buttons">
|
||||
<button type="button" data-action="rollActionTable" class="rollable" data-tooltip="{{localize "MGNE.Creature.RollAction"}}">
|
||||
<i class="fa-solid fa-dice-d20"></i> {{localize "MGNE.Creature.RollAction"}}
|
||||
</button>
|
||||
<button type="button" data-action="openActionTable" data-tooltip="{{localize "MGNE.Creature.OpenTable"}}">
|
||||
<i class="fa-solid fa-table-list"></i> {{localize "MGNE.Creature.OpenTable"}}
|
||||
</button>
|
||||
<button type="button" data-action="clearActionTable" data-tooltip="{{localize "MGNE.Creature.ClearTable"}}">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</button>
|
||||
</div>
|
||||
<fieldset>
|
||||
<div class="grid three">
|
||||
<div>
|
||||
<label>{{localize "MGNE.Common.Label"}}</label>
|
||||
<input type="text" name="system.attack.label" value="{{source.system.attack.label}}" />
|
||||
{{/if}}
|
||||
</div>
|
||||
<div>
|
||||
<label>{{localize "MGNE.Common.Damage"}}</label>
|
||||
<input type="text" name="system.attack.damage" value="{{source.system.attack.damage}}" />
|
||||
<div class="action-table-drop-zone {{#unless actionTable}}drop-hint{{/unless}}">
|
||||
{{#if actionTable}}
|
||||
<i class="fa-solid fa-table-list"></i>
|
||||
<span class="action-table-name">{{actionTable.name}}</span>
|
||||
{{else}}
|
||||
<i class="fa-solid fa-cloud-arrow-down"></i>
|
||||
<span>{{localize "MGNE.Creature.DropTableHint"}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="inline-buttons">
|
||||
<button type="button" class="rollable" data-roll-type="profile-attack">{{localize "MGNE.Common.Attack"}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="profile-damage">{{localize "MGNE.Common.Damage"}}</button>
|
||||
<button type="button" class="rollable" data-roll-type="morale">{{localize "MGNE.Common.Morale"}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div class="grid two">
|
||||
<!-- Traits -->
|
||||
<div class="creature-traits-container">
|
||||
<div class="creature-traits-header">
|
||||
<h3>{{localize "MGNE.Creature.Traits"}}</h3>
|
||||
<button type="button" data-action="createItem" data-item-type="creature-trait">
|
||||
<i class="fa-solid fa-plus"></i> {{localize "MGNE.Creature.AddTrait"}}
|
||||
</button>
|
||||
</div>
|
||||
<div class="creature-traits-list">
|
||||
{{#each traits}}
|
||||
<div class="creature-trait-card" data-item-id="{{id}}">
|
||||
<div class="creature-trait-card-header">
|
||||
<div class="creature-trait-name" {{#if tooltip}}data-tooltip="{{tooltip}}" data-tooltip-class="mgne-item-tooltip"{{/if}}>
|
||||
<i class="fa-solid fa-bolt-lightning"></i>
|
||||
<span>{{name}}</span>
|
||||
</div>
|
||||
{{#if system.trigger}}
|
||||
<span class="creature-trait-trigger">{{system.trigger}}</span>
|
||||
{{/if}}
|
||||
<div class="item-actions">
|
||||
<button type="button" data-action="editItem" data-tooltip="{{localize "MGNE.Common.Edit"}}"><i class="fa-solid fa-pen"></i></button>
|
||||
<button type="button" data-action="deleteItem" data-item-id="{{id}}" data-tooltip="{{localize "MGNE.Common.Delete"}}"><i class="fa-solid fa-trash"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<p class="empty-state">{{localize "MGNE.Empty.NoTraits"}}</p>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Description -->
|
||||
<div class="inventory-section">
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Description"}}</h3>
|
||||
@@ -89,22 +128,5 @@
|
||||
{{formInput systemFields.description enriched=(lookup enrichedFields "description") value=system.description name="system.description" toggled=true}}
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="inventory-section">
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Creature.Special"}}</h3>
|
||||
</div>
|
||||
<fieldset>
|
||||
{{formInput systemFields.special enriched=(lookup enrichedFields "special") value=system.special name="system.special" toggled=true}}
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inventory-section">
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Notes"}}</h3>
|
||||
</div>
|
||||
<fieldset>
|
||||
{{formInput systemFields.notes enriched=(lookup enrichedFields "notes") value=system.notes name="system.notes" toggled=true}}
|
||||
</fieldset>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<section class="mgne-sheet">
|
||||
<div class="sheet-header">
|
||||
<img class="item-portrait" src="{{item.img}}" data-edit="img" data-action="editImage" alt="{{item.name}}" />
|
||||
<div class="header-fields">
|
||||
<input type="text" name="name" value="{{source.name}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-form-grid item-form-grid-one">
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.CreatureTrait.Trigger"}}</label>
|
||||
<input type="text" name="system.trigger" value="{{source.system.trigger}}" placeholder="{{localize "MGNE.CreatureTrait.TriggerPlaceholder"}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Description"}}</h3>
|
||||
</div>
|
||||
<fieldset>
|
||||
{{formInput systemFields.description enriched=(lookup enrichedFields "description") value=system.description name="system.description" toggled=true}}
|
||||
</fieldset>
|
||||
</section>
|
||||
@@ -14,6 +14,14 @@
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.Weight"}}</label>
|
||||
<select name="system.weight">
|
||||
{{#each selectOptions.weightCategories}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.weight value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.Quantity"}}</label>
|
||||
<input type="number" name="system.quantity" value="{{source.system.quantity}}" />
|
||||
@@ -26,11 +34,20 @@
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.DurabilityDie"}}</label>
|
||||
<select name="system.durabilityDie">
|
||||
{{#each selectOptions.usageDice}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.durabilityDie value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-check-grid item-check-grid-three check-grid">
|
||||
<label><input type="checkbox" name="system.carried" {{#if source.system.carried}}checked{{/if}} /> {{localize "MGNE.Common.Carried"}}</label>
|
||||
<label><input type="checkbox" name="system.equipped" {{#if source.system.equipped}}checked{{/if}} /> {{localize "MGNE.Common.Equipped"}}</label>
|
||||
<label><input type="checkbox" name="system.consumable" {{#if source.system.consumable}}checked{{/if}} /> {{localize "MGNE.Common.Consumable"}}</label>
|
||||
<label><input type="checkbox" name="system.broken" {{#if source.system.broken}}checked{{/if}} /> {{localize "MGNE.Common.Broken"}}</label>
|
||||
</div>
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Description"}}</h3>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<section class="tab-panel {{tab.cssClass}}">
|
||||
<div class="inventory-section">
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Party.Loot"}}</h3>
|
||||
</div>
|
||||
|
||||
{{#if lootItems.length}}
|
||||
<div class="party-loot-list">
|
||||
<div class="party-loot-row party-loot-header">
|
||||
<span></span>
|
||||
<span>{{localize "MGNE.Common.Name"}}</span>
|
||||
<span>{{localize "MGNE.Common.Type"}}</span>
|
||||
<span></span>
|
||||
</div>
|
||||
{{#each lootItems as |item|}}
|
||||
<div class="party-loot-row" data-item-id="{{item.id}}">
|
||||
<img src="{{item.img}}" class="item-portrait" />
|
||||
<span class="item-name">{{item.name}}</span>
|
||||
<span class="item-type-label">{{item.typeLabel}}</span>
|
||||
<div class="item-actions">
|
||||
<a data-action="editItem" data-item-id="{{item.id}}" data-tooltip="{{localize 'MGNE.Common.Edit'}}">
|
||||
<i class="fa-solid fa-pen"></i>
|
||||
</a>
|
||||
<a data-action="deleteItem" data-item-id="{{item.id}}" data-tooltip="{{localize 'MGNE.Common.Delete'}}">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
<p class="empty-section-hint">{{localize "MGNE.Empty.NoLoot"}}</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<p class="party-drop-hint">{{localize "MGNE.Party.DropLootHint"}}</p>
|
||||
</section>
|
||||
@@ -0,0 +1,21 @@
|
||||
<section class="mgne-sheet mgne-sheet-header">
|
||||
<div class="sheet-header">
|
||||
<div class="portrait-column">
|
||||
<img class="actor-portrait" src="{{actor.img}}" data-edit="img" data-action="editImage" alt="{{actor.name}}" />
|
||||
</div>
|
||||
<div class="header-fields">
|
||||
<input type="text" name="name" value="{{source.name}}" />
|
||||
<div class="party-credits-row">
|
||||
<label class="resource-label-accent">{{localize "MGNE.Party.Credits"}}</label>
|
||||
<div class="party-credits-stepper">
|
||||
<button type="button" class="credits-btn" data-action="adjustCredits" data-delta="-10">−10</button>
|
||||
<button type="button" class="credits-btn" data-action="adjustCredits" data-delta="-1">−1</button>
|
||||
<input class="numeric-input credits-input" type="number" name="system.credits" value="{{source.system.credits}}" min="0" />
|
||||
<span class="credits-symbol">₵</span>
|
||||
<button type="button" class="credits-btn" data-action="adjustCredits" data-delta="1">+1</button>
|
||||
<button type="button" class="credits-btn" data-action="adjustCredits" data-delta="10">+10</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,48 @@
|
||||
<section class="tab-panel {{tab.cssClass}}">
|
||||
<div class="inventory-section">
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Party.Members"}}</h3>
|
||||
</div>
|
||||
|
||||
{{#if members.length}}
|
||||
<div class="party-member-list">
|
||||
<div class="party-member-row party-member-header">
|
||||
<span></span>
|
||||
<span>{{localize "MGNE.Common.Name"}}</span>
|
||||
<span>{{localize "MGNE.Common.HP"}}</span>
|
||||
<span>{{localize "MGNE.Common.Type"}}</span>
|
||||
<span></span>
|
||||
</div>
|
||||
{{#each members as |member|}}
|
||||
<div class="party-member-row" data-actor-id="{{member.id}}">
|
||||
<img src="{{member.img}}" class="party-member-portrait" />
|
||||
<span class="party-member-name">
|
||||
<a data-action="openMember" data-actor-id="{{member.id}}">{{member.name}}</a>
|
||||
</span>
|
||||
<span class="party-member-hp">{{member.hp}}</span>
|
||||
<span class="party-member-type">{{member.typeLabel}}</span>
|
||||
<div class="item-actions">
|
||||
{{#unless member.isFirst}}
|
||||
<a data-action="moveMemberUp" data-ref-idx="{{member.refIdx}}" data-tooltip="{{localize 'MGNE.Party.MoveUp'}}">
|
||||
<i class="fa-solid fa-chevron-up"></i>
|
||||
</a>
|
||||
{{/unless}}
|
||||
{{#unless member.isLast}}
|
||||
<a data-action="moveMemberDown" data-ref-idx="{{member.refIdx}}" data-tooltip="{{localize 'MGNE.Party.MoveDown'}}">
|
||||
<i class="fa-solid fa-chevron-down"></i>
|
||||
</a>
|
||||
{{/unless}}
|
||||
<a data-action="removeMember" data-actor-id="{{member.id}}" data-tooltip="{{localize 'MGNE.Party.RemoveMember'}}">
|
||||
<i class="fa-solid fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
<p class="empty-section-hint">{{localize "MGNE.Empty.NoMembers"}}</p>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<p class="party-drop-hint">{{localize "MGNE.Party.DropMemberHint"}}</p>
|
||||
</section>
|
||||
@@ -0,0 +1,10 @@
|
||||
<section class="tab-panel {{tab.cssClass}}">
|
||||
<div class="inventory-section">
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Notes"}}</h3>
|
||||
</div>
|
||||
<fieldset>
|
||||
{{formInput systemFields.notes enriched=(lookup enrichedFields "notes") value=system.notes name="system.notes" toggled=true}}
|
||||
</fieldset>
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,5 @@
|
||||
<nav class="sheet-tabs">
|
||||
{{#each tabs}}
|
||||
<button type="button" class="tab-button {{cssClass}}" data-action="changeTab" data-group="{{group}}" data-tab="{{id}}">{{label}}</button>
|
||||
{{/each}}
|
||||
</nav>
|
||||
@@ -5,7 +5,7 @@
|
||||
<input type="text" name="name" value="{{source.name}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-form-grid item-form-grid-two">
|
||||
<div class="item-form-grid item-form-grid-three">
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.UsageDie"}}</label>
|
||||
<select name="system.usageDie">
|
||||
@@ -14,9 +14,26 @@
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.DurabilityDie"}}</label>
|
||||
<select name="system.durabilityDie">
|
||||
{{#each selectOptions.usageDice}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.durabilityDie value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.Weight"}}</label>
|
||||
<select name="system.weight">
|
||||
{{#each selectOptions.weightCategories}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.weight value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-check-grid check-grid">
|
||||
<label><input type="checkbox" name="system.burnedOut" {{#if source.system.burnedOut}}checked{{/if}} /> {{localize "MGNE.Common.BurnedOut"}}</label>
|
||||
<label><input type="checkbox" name="system.broken" {{#if source.system.broken}}checked{{/if}} /> {{localize "MGNE.Common.Broken"}}</label>
|
||||
</div>
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Description"}}</h3>
|
||||
|
||||
+17
-1
@@ -5,7 +5,7 @@
|
||||
<input type="text" name="name" value="{{source.name}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-form-grid item-form-grid-two">
|
||||
<div class="item-form-grid item-form-grid-three">
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.ArmorDie"}}</label>
|
||||
<select name="system.armorDie">
|
||||
@@ -22,6 +22,22 @@
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.Weight"}}</label>
|
||||
<select name="system.weight">
|
||||
{{#each selectOptions.weightCategories}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.weight value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.DurabilityDie"}}</label>
|
||||
<select name="system.durabilityDie">
|
||||
{{#each selectOptions.usageDice}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.durabilityDie value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-check-grid check-grid">
|
||||
<label><input type="checkbox" name="system.equipped" {{#if source.system.equipped}}checked{{/if}} /> {{localize "MGNE.Common.Equipped"}}</label>
|
||||
|
||||
+27
-2
@@ -23,8 +23,20 @@
|
||||
<input type="text" name="system.range" value="{{source.system.range}}" />
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.Properties"}}</label>
|
||||
<input type="text" name="system.properties" value="{{source.system.properties}}" />
|
||||
<label>{{localize "MGNE.Common.Weight"}}</label>
|
||||
<select name="system.weight">
|
||||
{{#each selectOptions.weightCategories}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.weight value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.DurabilityDie"}}</label>
|
||||
<select name="system.durabilityDie">
|
||||
{{#each selectOptions.usageDice}}
|
||||
<option value="{{value}}" {{#if (isEqual ../source.system.durabilityDie value)}}selected{{/if}}>{{label}}</option>
|
||||
{{/each}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="item-form-row">
|
||||
<label>{{localize "MGNE.Common.UsageDie"}}</label>
|
||||
@@ -43,6 +55,19 @@
|
||||
<label><input type="checkbox" name="system.equipped" {{#if source.system.equipped}}checked{{/if}} /> {{localize "MGNE.Common.Equipped"}}</label>
|
||||
<label><input type="checkbox" name="system.broken" {{#if source.system.broken}}checked{{/if}} /> {{localize "MGNE.Common.Broken"}}</label>
|
||||
</div>
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Properties"}}</h3>
|
||||
</div>
|
||||
<div class="weapon-properties-grid">
|
||||
<input type="hidden" name="system.properties" value="" />
|
||||
{{#each selectOptions.weaponProperties}}
|
||||
<label class="property-check" title="{{hint}}">
|
||||
<input type="checkbox" name="system.properties" value="{{value}}"
|
||||
{{#if (includes ../source.system.properties value)}}checked{{/if}} />
|
||||
{{label}}
|
||||
</label>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div class="inventory-header">
|
||||
<h3>{{localize "MGNE.Common.Description"}}</h3>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user