Update published system to v0.9.4
Brings the public system repo up to date with the current build: - Dice So Nice: the VANITY peacock dice are now forced for every player, with a roll hook stamping the colourset on every die (red Bane dice preserved). - Character sheet: conditions strip moved to the foot, rebuilt as an even grid with larger (34px) icons. - Twist the Knife no longer spends the banked Bane — the tab only clears through humility, a rest, or the Reckoning. - Equipment: +50 items (weapons, armour & shields, gear, consumables). - New compendium: VANITY · Treasures & Relics — 100 magic items, and the Forge's richer hoards now surface them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
<!doctype html><html><head><meta charset="utf-8"><style>
|
||||
html,body{margin:0;padding:0;background:#03100d;width:1920px;height:1080px;overflow:hidden}
|
||||
img{display:block;width:1920px;height:1080px}
|
||||
</style></head><body><img src="vanity-splash.svg"></body></html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 258 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.3 MiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 130 KiB |
Binary file not shown.
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.408746 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.409498 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.409719 170237000 Level-0 table #5: 1282 bytes OK
|
||||
2026/07/14-09:38:57.409845 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.409925 170237000 Manual compaction at level-0 from '!items!GOAakTqMDZSCDOdE' @ 72057594037927935 : 1 .. '!items!jf5ovEG8ufV1oiUf' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:36.994122 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:36.994965 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:36.995304 1726ab000 Level-0 table #5: 2618 bytes OK
|
||||
2026/07/14-22:09:36.995487 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:36.995615 1726ab000 Manual compaction at level-0 from '!items!GOAakTqMDZSCDOdE' @ 72057594037927935 : 1 .. '!items!vHyUhdri4IKpq9CW' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.438743 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.439229 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.439444 170237000 Level-0 table #5: 5226 bytes OK
|
||||
2026/07/14-09:38:57.439529 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.439587 170237000 Manual compaction at level-0 from '!actors!351sA95uALULY3Kv' @ 72057594037927935 : 1 .. '!actors!rPfEYHmSoprnQdrY' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:37.067644 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.068205 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.068437 1726ab000 Level-0 table #5: 5226 bytes OK
|
||||
2026/07/14-22:09:37.068519 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.068571 1726ab000 Manual compaction at level-0 from '!actors!351sA95uALULY3Kv' @ 72057594037927935 : 1 .. '!actors!rPfEYHmSoprnQdrY' @ 0 : 0; will stop at (end)
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.429069 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.429648 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.429879 170237000 Level-0 table #5: 5417 bytes OK
|
||||
2026/07/14-09:38:57.429999 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.430077 170237000 Manual compaction at level-0 from '!items!21hRQJtWGk5fDQlo' @ 72057594037927935 : 1 .. '!items!zMphj752klzDFU3Q' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:37.056786 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.057417 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.057682 1726ab000 Level-0 table #5: 5417 bytes OK
|
||||
2026/07/14-22:09:37.057805 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.057901 1726ab000 Manual compaction at level-0 from '!items!21hRQJtWGk5fDQlo' @ 72057594037927935 : 1 .. '!items!zMphj752klzDFU3Q' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.413966 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.414551 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.414799 170237000 Level-0 table #5: 3221 bytes OK
|
||||
2026/07/14-09:38:57.414887 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.414944 170237000 Manual compaction at level-0 from '!items!27LcrYsIEEF3KYHA' @ 72057594037927935 : 1 .. '!items!yo48EzCVEwNdpkXF' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:37.005326 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.005985 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.006294 1726ab000 Level-0 table #5: 9529 bytes OK
|
||||
2026/07/14-22:09:37.006403 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.006497 1726ab000 Manual compaction at level-0 from '!items!27LcrYsIEEF3KYHA' @ 72057594037927935 : 1 .. '!items!yo48EzCVEwNdpkXF' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.460195 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.460906 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.461170 170237000 Level-0 table #5: 10149 bytes OK
|
||||
2026/07/14-09:38:57.461298 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.461375 170237000 Manual compaction at level-0 from '!journal!JJEgDJvtWBnFbyZA' @ 72057594037927935 : 1 .. '!journal.pages!kBclT2QiwEQmOsX1.HSVD8c7BenQjb45v' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:37.085141 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.085689 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.085988 1726ab000 Level-0 table #5: 10149 bytes OK
|
||||
2026/07/14-22:09:37.086085 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.086167 1726ab000 Manual compaction at level-0 from '!journal!JJEgDJvtWBnFbyZA' @ 72057594037927935 : 1 .. '!journal.pages!kBclT2QiwEQmOsX1.HSVD8c7BenQjb45v' @ 0 : 0; will stop at (end)
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.444631 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.448892 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.449570 170237000 Level-0 table #5: 23539 bytes OK
|
||||
2026/07/14-09:38:57.449745 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.449971 170237000 Manual compaction at level-0 from '!actors!WDcRWtpmw3YGHDSi' @ 72057594037927935 : 1 .. '!actors.items!z6lMSAkEENJFTvIP.wwJcCyyHbp1gt9iq' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:37.074451 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.075086 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.075456 1726ab000 Level-0 table #5: 23539 bytes OK
|
||||
2026/07/14-22:09:37.075539 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.075600 1726ab000 Manual compaction at level-0 from '!actors!WDcRWtpmw3YGHDSi' @ 72057594037927935 : 1 .. '!actors.items!z6lMSAkEENJFTvIP.wwJcCyyHbp1gt9iq' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.454787 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.455790 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.456601 170237000 Level-0 table #5: 63789 bytes OK
|
||||
2026/07/14-09:38:57.456761 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.456863 170237000 Manual compaction at level-0 from '!journal!9PRuE5Q81BnO22fH' @ 72057594037927935 : 1 .. '!journal.pages!9PRuE5Q81BnO22fH.qCt9jGDZePPN5S6G' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:37.079746 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.080784 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.081591 1726ab000 Level-0 table #5: 63868 bytes OK
|
||||
2026/07/14-22:09:37.081700 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.081862 1726ab000 Manual compaction at level-0 from '!journal!9PRuE5Q81BnO22fH' @ 72057594037927935 : 1 .. '!journal.pages!9PRuE5Q81BnO22fH.qCt9jGDZePPN5S6G' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.422502 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.423123 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.423395 170237000 Level-0 table #5: 11569 bytes OK
|
||||
2026/07/14-09:38:57.423488 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.423549 170237000 Manual compaction at level-0 from '!items!13KOIsQOsgYqdVEX' @ 72057594037927935 : 1 .. '!items!zywiqamhRlcCgLJY' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:37.050594 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.051265 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.051557 1726ab000 Level-0 table #5: 11569 bytes OK
|
||||
2026/07/14-22:09:37.051647 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.051708 1726ab000 Manual compaction at level-0 from '!items!13KOIsQOsgYqdVEX' @ 72057594037927935 : 1 .. '!items!zywiqamhRlcCgLJY' @ 0 : 0; will stop at (end)
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.465680 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.466297 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.466636 170237000 Level-0 table #5: 12927 bytes OK
|
||||
2026/07/14-09:38:57.466760 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.466830 170237000 Manual compaction at level-0 from '!tables!JEOcxCxjK6S6pVEZ' @ 72057594037927935 : 1 .. '!tables.results!rurx5ZPcPObdbNDD.bWBU56ZArkeat9DO' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:37.091924 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.092662 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.093008 1726ab000 Level-0 table #5: 12927 bytes OK
|
||||
2026/07/14-22:09:37.093109 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.093180 1726ab000 Manual compaction at level-0 from '!tables!JEOcxCxjK6S6pVEZ' @ 72057594037927935 : 1 .. '!tables.results!rurx5ZPcPObdbNDD.bWBU56ZArkeat9DO' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
MANIFEST-000002
|
||||
@@ -0,0 +1,5 @@
|
||||
2026/07/14-22:09:37.041630 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.042589 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.043013 1726ab000 Level-0 table #5: 27619 bytes OK
|
||||
2026/07/14-22:09:37.043119 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.043193 1726ab000 Manual compaction at level-0 from '!items!0NDwQbhQQNeCCEco' @ 72057594037927935 : 1 .. '!items!yxds1AZFNXBpERdk' @ 0 : 0; will stop at (end)
|
||||
Binary file not shown.
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.432838 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.433254 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.433533 170237000 Level-0 table #5: 1461 bytes OK
|
||||
2026/07/14-09:38:57.433620 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.433675 170237000 Manual compaction at level-0 from '!items!7kO3VzfFPt8QRVXT' @ 72057594037927935 : 1 .. '!items!s50CZgFUaS5puSOp' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:37.060948 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:37.061687 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:37.061961 1726ab000 Level-0 table #5: 1461 bytes OK
|
||||
2026/07/14-22:09:37.062129 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:37.062277 1726ab000 Manual compaction at level-0 from '!items!7kO3VzfFPt8QRVXT' @ 72057594037927935 : 1 .. '!items!s50CZgFUaS5puSOp' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
+5
-5
@@ -1,5 +1,5 @@
|
||||
2026/07/14-09:38:57.402153 16e987000 Delete type=3 #1
|
||||
2026/07/14-09:38:57.404481 170237000 Level-0 table #5: started
|
||||
2026/07/14-09:38:57.404888 170237000 Level-0 table #5: 4010 bytes OK
|
||||
2026/07/14-09:38:57.405081 170237000 Delete type=0 #3
|
||||
2026/07/14-09:38:57.405192 170237000 Manual compaction at level-0 from '!items!2XKXBWRByluX4WDG' @ 72057594037927935 : 1 .. '!items!qAvk2AcDGNNy1Ce9' @ 0 : 0; will stop at (end)
|
||||
2026/07/14-22:09:36.985504 171e13000 Delete type=3 #1
|
||||
2026/07/14-22:09:36.988878 1726ab000 Level-0 table #5: started
|
||||
2026/07/14-22:09:36.989190 1726ab000 Level-0 table #5: 7415 bytes OK
|
||||
2026/07/14-22:09:36.989351 1726ab000 Delete type=0 #3
|
||||
2026/07/14-22:09:36.989442 1726ab000 Manual compaction at level-0 from '!items!0d6FZCtl78jEPkof' @ 72057594037927935 : 1 .. '!items!v3IghflF7cI2FzbU' @ 0 : 0; will stop at (end)
|
||||
|
||||
Binary file not shown.
+32
-20
@@ -904,40 +904,52 @@
|
||||
/* ============================================================
|
||||
Conditions — grouped icon chips + a details panel at the foot
|
||||
============================================================ */
|
||||
.vanity-sheet .v-conditions {
|
||||
.vanity-sheet .v-cond-foot {
|
||||
flex: none;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px 10px;
|
||||
padding: 4px 2px 7px;
|
||||
margin-bottom: 6px;
|
||||
border-bottom: 1.5px dotted var(--v-line);
|
||||
margin: 12px 2px 0;
|
||||
padding-top: 8px;
|
||||
border-top: 1.5px dotted var(--v-line);
|
||||
}
|
||||
.vanity-sheet .v-cond-title {
|
||||
font-family: "Cinzel", Georgia, serif;
|
||||
font-size: 9px; letter-spacing: 0.14em; text-transform: uppercase;
|
||||
color: var(--v-ink2); margin-bottom: 7px;
|
||||
}
|
||||
/* An even grid: every condition is an equal-sized tile, aligned in tidy rows. */
|
||||
.vanity-sheet .v-conditions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
|
||||
gap: 6px;
|
||||
}
|
||||
.vanity-sheet .cond-group { display: flex; flex-wrap: wrap; gap: 3px; padding-right: 8px; }
|
||||
.vanity-sheet .cond-group + .cond-group { border-left: 1px solid var(--v-line); padding-left: 10px; }
|
||||
.vanity-sheet .cond-badge {
|
||||
display: inline-flex;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 4px;
|
||||
padding: 1px 8px 1px 2px;
|
||||
border: 1.3px solid transparent;
|
||||
border-radius: 12px;
|
||||
padding: 7px 4px 6px;
|
||||
border: 1.4px solid var(--v-line);
|
||||
border-radius: 8px;
|
||||
background: var(--v-paper2);
|
||||
cursor: pointer;
|
||||
opacity: 0.62;
|
||||
transition: opacity 0.12s, background 0.12s, box-shadow 0.12s;
|
||||
opacity: 0.6;
|
||||
text-align: center;
|
||||
transition: opacity 0.12s, background 0.12s, box-shadow 0.12s, border-color 0.12s;
|
||||
}
|
||||
.vanity-sheet .cond-badge img {
|
||||
width: 20px; height: 20px; flex: none;
|
||||
filter: grayscale(0.55);
|
||||
width: 34px; height: 34px; flex: none;
|
||||
filter: grayscale(0.6);
|
||||
transition: filter 0.12s;
|
||||
}
|
||||
.vanity-sheet .cond-badge .cond-name { font-size: 10.5px; color: var(--v-ink2); white-space: nowrap; }
|
||||
.vanity-sheet .cond-badge:hover { opacity: 0.9; background: rgba(176,135,47,0.08); }
|
||||
.vanity-sheet .cond-badge .cond-name {
|
||||
font-size: 10.5px; line-height: 1.15; color: var(--v-ink2);
|
||||
}
|
||||
.vanity-sheet .cond-badge:hover { opacity: 0.92; background: rgba(176,135,47,0.10); }
|
||||
.vanity-sheet .cond-badge.on {
|
||||
opacity: 1;
|
||||
background: #fff;
|
||||
border-color: var(--cc, var(--v-gold));
|
||||
box-shadow: 0 0 5px var(--ccg, rgba(176,135,47,.45));
|
||||
box-shadow: 0 0 6px var(--ccg, rgba(176,135,47,.45));
|
||||
}
|
||||
.vanity-sheet .cond-badge.on img { filter: none; }
|
||||
.vanity-sheet .cond-badge.on .cond-name { color: var(--v-ink); font-weight: 600; }
|
||||
|
||||
+8
-1
@@ -2,7 +2,7 @@
|
||||
"id": "vanity",
|
||||
"title": "VANITY — the Vanity Role-Playing Game",
|
||||
"description": "A generic d6 RPG where ego is a resource and the universe keeps score. Pool = Attribute + Knack + situation; 5–6 = a Success; fail with two 1s = a Stumble that banks a Bane of Karma (Draft 13). No hit points — Grit. Vanity, Karma and Glory drive play. Includes the full Draft 13 rulebook, all spells and gear, the starter bestiary, five ready-to-play characters and the one-shot adventure The Vain Crown.",
|
||||
"version": "0.9.0",
|
||||
"version": "0.9.4",
|
||||
"compatibility": {
|
||||
"minimum": 13,
|
||||
"verified": "14.364"
|
||||
@@ -55,6 +55,13 @@
|
||||
"type": "Item",
|
||||
"system": "vanity"
|
||||
},
|
||||
{
|
||||
"name": "treasure",
|
||||
"label": "VANITY · Treasures & Relics",
|
||||
"path": "packs/treasure",
|
||||
"type": "Item",
|
||||
"system": "vanity"
|
||||
},
|
||||
{
|
||||
"name": "spells",
|
||||
"label": "VANITY · Spells & Nature Tricks",
|
||||
|
||||
@@ -18,19 +18,6 @@
|
||||
{{else if sys.rattled}}<div class="v-banner rattled">RATTLED — −1 die on everything until you recover</div>{{/if}}
|
||||
{{#if sys.reckoning}}<div class="v-banner reckoning">SIX BANES — THE RECKONING IS DUE</div>{{/if}}
|
||||
|
||||
{{!-- Conditions strip — grouped icon chips, always visible, click to toggle & read below --}}
|
||||
<div class="v-conditions">
|
||||
{{#each conditionGroups}}
|
||||
<div class="cond-group {{group}}">
|
||||
{{#each items}}
|
||||
<span class="cond-badge {{../group}} {{#if active}}on{{/if}}" data-cond="{{id}}" title="{{name}} — {{short}} · ends: {{ends}}">
|
||||
<img src="{{img}}" alt=""><span class="cond-name">{{name}}</span>
|
||||
</span>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<nav class="sheet-tabs tabs" data-group="primary">
|
||||
<a class="item" data-tab="main">Character</a>
|
||||
<a class="item" data-tab="combat">Combat & Gear</a>
|
||||
@@ -307,7 +294,20 @@
|
||||
|
||||
</section>
|
||||
|
||||
{{!-- Conditions in play — pinned to the foot of the sheet, across every tab --}}
|
||||
{{!-- Conditions — an even grid at the foot, across every tab; click to toggle & read below --}}
|
||||
<div class="v-cond-foot">
|
||||
<div class="v-cond-title">Conditions · click to set & read</div>
|
||||
<div class="v-conditions">
|
||||
{{#each conditionGroups}}
|
||||
{{#each items}}
|
||||
<span class="cond-badge {{../group}} {{#if active}}on{{/if}}" data-cond="{{id}}" title="{{name}} — {{short}} · ends: {{ends}}">
|
||||
<img src="{{img}}" alt=""><span class="cond-name">{{name}}</span>
|
||||
</span>
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if focusCond}}
|
||||
<div class="v-cond-detail {{focusCond.group}}">
|
||||
<img src="{{focusCond.img}}" alt="">
|
||||
|
||||
+44
-14
@@ -353,10 +353,18 @@ function renderRollCard({ label, sublabel, results, threshold, pushed, context,
|
||||
* Roll a VANITY pool and post the chat card.
|
||||
* options: { threshold, context ("spell"|"attack"|...), spellUuid, sublabel }
|
||||
*/
|
||||
/** Stamp the VANITY dice appearance on a roll so it shows the peacock dice regardless
|
||||
* of the player's own Dice So Nice settings (belt-and-suspenders with the roll hook). */
|
||||
function lockVanityDice(roll, colorset = "vanity") {
|
||||
for (const die of roll.dice) die.options.appearance = { system: "vanity", colorset };
|
||||
return roll;
|
||||
}
|
||||
|
||||
async function rollPool(actor, pool, label, options = {}) {
|
||||
pool = Math.max(1, Math.floor(pool));
|
||||
const roll = new Roll(`${pool}d6`);
|
||||
await roll.evaluate();
|
||||
lockVanityDice(roll);
|
||||
const results = roll.dice[0].results.map(r => r.result);
|
||||
|
||||
// The Stumble (Draft 11): bank 1 Bane only on a failed roll with two or more 1s.
|
||||
@@ -463,6 +471,7 @@ async function handlePush(message) {
|
||||
if (rerollCount > 0) {
|
||||
roll = new Roll(`${rerollCount}d6`);
|
||||
await roll.evaluate();
|
||||
lockVanityDice(roll);
|
||||
newResults = keep.concat(roll.dice[0].results.map(r => r.result));
|
||||
if (game.dice3d) await game.dice3d.showForRoll(roll, game.user, true);
|
||||
}
|
||||
@@ -947,7 +956,9 @@ class VanityItemSheet extends foundry.appv1.sheets.ItemSheet {
|
||||
/* -------------------------------------------- */
|
||||
|
||||
Hooks.once("diceSoNiceReady", dice3d => {
|
||||
dice3d.addSystem({ id: "vanity", name: "VANITY — Peacock & Gold" }, "preferred");
|
||||
// "force" locks the VANITY dice system (the custom plume/crown/Bane faces) on for
|
||||
// every player, overriding whatever dice they picked personally.
|
||||
dice3d.addSystem({ id: "vanity", name: "VANITY — Peacock & Gold" }, "force");
|
||||
|
||||
dice3d.addColorset({
|
||||
name: "vanity",
|
||||
@@ -990,6 +1001,18 @@ Hooks.once("diceSoNiceReady", dice3d => {
|
||||
}, "default");
|
||||
});
|
||||
|
||||
// Lock the VANITY colours onto every die of every roll, whatever the player's own
|
||||
// Dice So Nice settings. Fires for pool rolls, Pushes, initiative and manual rolls
|
||||
// alike. Dice already flagged as the blood-red Bane set are left untouched.
|
||||
Hooks.on("diceSoNiceRollStart", (messageId, context) => {
|
||||
const roll = context?.roll;
|
||||
if (!roll?.dice) return;
|
||||
for (const die of roll.dice) {
|
||||
if (die.options?.appearance?.colorset === "vanity-bane") continue;
|
||||
die.options.appearance = { system: "vanity", colorset: "vanity" };
|
||||
}
|
||||
});
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Twist the Knife — the GM spends the tab */
|
||||
/* -------------------------------------------- */
|
||||
@@ -1008,7 +1031,7 @@ async function getVanityTable(name) {
|
||||
|
||||
/** Roll dice on the playing surface in the blood-red Bane set, without ever blocking. */
|
||||
async function showBaneDice(roll) {
|
||||
for (const d of roll.dice) d.options.appearance = { colorset: "vanity-bane" };
|
||||
for (const d of roll.dice) d.options.appearance = { system: "vanity", colorset: "vanity-bane" };
|
||||
if (game.dice3d && !game.settings.get("dice-so-nice", "animateRollTable")) {
|
||||
await Promise.race([
|
||||
game.dice3d.showForRoll(roll, game.user, true).catch(() => {}),
|
||||
@@ -1050,8 +1073,9 @@ async function reckoningNow({ actorUuid = "" } = {}) {
|
||||
|
||||
/**
|
||||
* GM-only: roll the d66 on Twist the Knife with the blood-red Bane dice.
|
||||
* A paid twist (actorUuid set) deducts the row's Bane cost from the tab.
|
||||
* A free twist (lone unbanked 1) burns the button on its source card.
|
||||
* The twist is the Bane's BITE, not its price — it never reduces the tab. A banked
|
||||
* Bane stays put (building toward the Reckoning) and only clears through humility,
|
||||
* a rest, or the Reckoning at six. A free twist (lone unbanked 1) burns its button.
|
||||
*/
|
||||
async function twistTheKnife({ actorUuid = "", free = false, sourceMessage = null } = {}) {
|
||||
if (!game.user.isGM) return ui.notifications.warn("Only the GM may twist the knife.");
|
||||
@@ -1067,15 +1091,14 @@ async function twistTheKnife({ actorUuid = "", free = false, sourceMessage = nul
|
||||
await table.toMessage(results, { roll });
|
||||
const draw = { roll, results };
|
||||
|
||||
// The twist bites, but the tab holds — a banked Bane is never spent by twisting.
|
||||
if (!free && actorUuid) {
|
||||
const actor = await fromUuid(actorUuid);
|
||||
if (actor?.type === "character") {
|
||||
const cost = draw.roll.total >= 61 ? 2 : 1;
|
||||
const karma = Math.max(0, (actor.system.karma ?? 0) - cost);
|
||||
await actor.update({ "system.karma": karma });
|
||||
const karma = actor.system.karma ?? 0;
|
||||
await ChatMessage.create({
|
||||
speaker: { alias: "The Tab" },
|
||||
content: `<div class="vanity-roll vanity-tab-note"><p><b>${cost} Bane${cost > 1 ? "s" : ""} spent</b> against ${actor.name} — the tab now reads <b>${karma}</b> of 6.</p></div>`
|
||||
content: `<div class="vanity-roll vanity-tab-note"><p>The knife twists — but the Bane stays banked. ${actor.name}'s tab still reads <b>${karma}</b> of 6.</p></div>`
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1501,16 +1524,16 @@ const FORGE_HOOKS = [
|
||||
];
|
||||
|
||||
const HOARDS = {
|
||||
pocket: { label: "Pocket", coin: () => `${sum(rollDice(2, 6))} sp`, draws: 0, consum: 0.3, trinkets: [0, 1], hook: 0.15 },
|
||||
cache: { label: "Cache", coin: () => `${sum(rollDice(1, 6))} gp, ${sum(rollDice(2, 6))} sp`, draws: 1, consum: 0.8, trinkets: [0, 1], hook: 0.3 },
|
||||
chest: { label: "Chest", coin: () => `${sum(rollDice(4, 6))} gp`, draws: 2, consum: 1, trinkets: [1, 1], hook: 0.5 },
|
||||
vault: { label: "Vault", coin: () => `${sum(rollDice(2, 6)) * 10} gp`, draws: 3, consum: 1, trinkets: [1, 2], hook: 1 },
|
||||
kingly: { label: "Kingly", coin: () => `${sum(rollDice(6, 6)) * 10} gp`, draws: 5, consum: 1, trinkets: [2, 2], hook: 1, centerpiece: true }
|
||||
pocket: { label: "Pocket", coin: () => `${sum(rollDice(2, 6))} sp`, draws: 0, consum: 0.3, trinkets: [0, 1], hook: 0.15, relics: 0 },
|
||||
cache: { label: "Cache", coin: () => `${sum(rollDice(1, 6))} gp, ${sum(rollDice(2, 6))} sp`, draws: 1, consum: 0.8, trinkets: [0, 1], hook: 0.3, relics: 0.2 },
|
||||
chest: { label: "Chest", coin: () => `${sum(rollDice(4, 6))} gp`, draws: 2, consum: 1, trinkets: [1, 1], hook: 0.5, relics: 0.5 },
|
||||
vault: { label: "Vault", coin: () => `${sum(rollDice(2, 6)) * 10} gp`, draws: 3, consum: 1, trinkets: [1, 2], hook: 1, relics: 1 },
|
||||
kingly: { label: "Kingly", coin: () => `${sum(rollDice(6, 6)) * 10} gp`, draws: 5, consum: 1, trinkets: [2, 2], hook: 1, centerpiece: true, relics: 2 }
|
||||
};
|
||||
|
||||
async function forgeHoard({ size = "chest" } = {}) {
|
||||
const tier = HOARDS[size] ?? HOARDS.chest;
|
||||
const [weapons, armour, gear] = await Promise.all(["weapons", "armour", "gear"].map(packDocs));
|
||||
const [weapons, armour, gear, treasure] = await Promise.all(["weapons", "armour", "gear", "treasure"].map(packDocs));
|
||||
const consumables = gear.filter(g => g.system.consumable);
|
||||
const mundane = [...weapons, ...armour, ...gear.filter(g => !g.system.consumable)];
|
||||
|
||||
@@ -1522,6 +1545,13 @@ async function forgeHoard({ size = "chest" } = {}) {
|
||||
for (let i = 0; i < tier.draws; i++) found.push(rnd(mundane));
|
||||
if (found.length) lines.push(`<b>Goods:</b> ${found.map(d => `@UUID[${d.uuid}]{${d.name}}`).join(" · ")}`);
|
||||
|
||||
// A magic relic or two in the richer hoards (a fraction is a chance, an integer a count).
|
||||
const nRelics = (tier.relics ?? 0) >= 1 ? tier.relics : (Math.random() < (tier.relics ?? 0) ? 1 : 0);
|
||||
if (nRelics && treasure.length) {
|
||||
const relics = pickN(treasure, Math.min(nRelics, treasure.length));
|
||||
lines.push(`<b>Relic${relics.length > 1 ? "s" : ""}:</b> ${relics.map(d => `@UUID[${d.uuid}]{${d.name}}`).join(" · ")}`);
|
||||
}
|
||||
|
||||
const nTr = between(tier.trinkets);
|
||||
if (nTr) lines.push(`<b>Vanities:</b> ${pickN(FORGE_TRINKETS, nTr).map(([t, v]) => `${t} <i>(${v} gp)</i>`).join(" · ")}`);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user