mirror of
https://github.com/Kornstalx/5etools-mirror-2.github.io.git
synced 2025-10-28 20:45:35 -05:00
v1.209.2
This commit is contained in:
@@ -1223,6 +1223,14 @@
|
|||||||
"width": 3165,
|
"width": 3165,
|
||||||
"height": 4096,
|
"height": 4096,
|
||||||
"id": "4ab",
|
"id": "4ab",
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 165,
|
||||||
|
"offsetX": 25,
|
||||||
|
"offsetY": 48,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
|
},
|
||||||
"mapRegions": [
|
"mapRegions": [
|
||||||
{
|
{
|
||||||
"area": "03f",
|
"area": "03f",
|
||||||
@@ -1873,6 +1881,14 @@
|
|||||||
"credit": "Mike Schley",
|
"credit": "Mike Schley",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "4ab"
|
"id": "4ab"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 165,
|
||||||
|
"offsetX": 25,
|
||||||
|
"offsetY": 48,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -3262,6 +3278,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/018-map-2.02-buried-ziggurat-4.webp"
|
"path": "adventure/QftIS/thumbnail/018-map-2.02-buried-ziggurat-4.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 193,
|
||||||
|
"offsetX": 85,
|
||||||
|
"offsetY": -16,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -3277,6 +3301,14 @@
|
|||||||
"credit": "Mike Schley",
|
"credit": "Mike Schley",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "59a"
|
"id": "59a"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 193,
|
||||||
|
"offsetX": 85,
|
||||||
|
"offsetY": -16,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -4153,6 +4185,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/021-map-2.03-buried-ziggurat-5.webp"
|
"path": "adventure/QftIS/thumbnail/021-map-2.03-buried-ziggurat-5.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 147,
|
||||||
|
"offsetX": 34,
|
||||||
|
"offsetY": 6,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -4168,6 +4208,14 @@
|
|||||||
"credit": "Mike Schley",
|
"credit": "Mike Schley",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "59b"
|
"id": "59b"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 147,
|
||||||
|
"offsetX": 34,
|
||||||
|
"offsetY": 6,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -6033,6 +6081,13 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/025-map-2.04-expanded-ziggurat.webp"
|
"path": "adventure/QftIS/thumbnail/025-map-2.04-expanded-ziggurat.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 114,
|
||||||
|
"offsetX": -6,
|
||||||
|
"offsetY": 19,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -6048,6 +6103,13 @@
|
|||||||
"credit": "Mike Schley",
|
"credit": "Mike Schley",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "59c"
|
"id": "59c"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 114,
|
||||||
|
"offsetX": -6,
|
||||||
|
"offsetY": 19,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -6559,6 +6621,11 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/028-map-2.05-underground-city.webp"
|
"path": "adventure/QftIS/thumbnail/028-map-2.05-underground-city.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "none",
|
||||||
|
"size": 148,
|
||||||
|
"distance": 200
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -6574,6 +6641,11 @@
|
|||||||
"credit": "Marco Bernardini",
|
"credit": "Marco Bernardini",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "59d"
|
"id": "59d"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "none",
|
||||||
|
"size": 148,
|
||||||
|
"distance": 200
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -7228,6 +7300,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/033-map-3.01-tegefed-mountains.webp"
|
"path": "adventure/QftIS/thumbnail/033-map-3.01-tegefed-mountains.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "hexColsOdd",
|
||||||
|
"size": 181,
|
||||||
|
"offsetX": -67,
|
||||||
|
"offsetY": 46,
|
||||||
|
"distance": 4,
|
||||||
|
"units": "miles"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -7243,6 +7323,14 @@
|
|||||||
"credit": "Marco Bernardini",
|
"credit": "Marco Bernardini",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "59e"
|
"id": "59e"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "hexColsOdd",
|
||||||
|
"size": 181,
|
||||||
|
"offsetX": -67,
|
||||||
|
"offsetY": 46,
|
||||||
|
"distance": 4,
|
||||||
|
"units": "miles"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -7994,6 +8082,13 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/036-map-3.02-derwyths-homestead.webp"
|
"path": "adventure/QftIS/thumbnail/036-map-3.02-derwyths-homestead.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 167,
|
||||||
|
"offsetX": -42,
|
||||||
|
"offsetY": -47,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -8009,6 +8104,13 @@
|
|||||||
"credit": "Sean Macdonald",
|
"credit": "Sean Macdonald",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "59f"
|
"id": "59f"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 167,
|
||||||
|
"offsetX": -42,
|
||||||
|
"offsetY": -47,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -9463,6 +9565,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/039-map-3.03-derro-lair.webp"
|
"path": "adventure/QftIS/thumbnail/039-map-3.03-derro-lair.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 226,
|
||||||
|
"offsetX": 140,
|
||||||
|
"offsetY": 123,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -9478,6 +9588,14 @@
|
|||||||
"credit": "Jason A. Engle",
|
"credit": "Jason A. Engle",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a0"
|
"id": "5a0"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 226,
|
||||||
|
"offsetX": 140,
|
||||||
|
"offsetY": 123,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -9871,6 +9989,13 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/043-map-3.04-therno-lake.webp"
|
"path": "adventure/QftIS/thumbnail/043-map-3.04-therno-lake.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 306,
|
||||||
|
"offsetX": 111,
|
||||||
|
"offsetY": -89,
|
||||||
|
"distance": 50
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -9886,6 +10011,13 @@
|
|||||||
"credit": "Marco Bernardini",
|
"credit": "Marco Bernardini",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a1"
|
"id": "5a1"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 306,
|
||||||
|
"offsetX": 111,
|
||||||
|
"offsetY": -89,
|
||||||
|
"distance": 50
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -11298,6 +11430,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/046-map-3.05-tower-of-the-heavens.webp"
|
"path": "adventure/QftIS/thumbnail/046-map-3.05-tower-of-the-heavens.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 160,
|
||||||
|
"offsetX": -44,
|
||||||
|
"offsetY": 64,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -11313,6 +11453,14 @@
|
|||||||
"credit": "Sean Macdonald",
|
"credit": "Sean Macdonald",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a2"
|
"id": "5a2"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 160,
|
||||||
|
"offsetX": -44,
|
||||||
|
"offsetY": 64,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -13562,6 +13710,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/050-map-3.06-forge-of-the-kagu-svirfneblin.webp"
|
"path": "adventure/QftIS/thumbnail/050-map-3.06-forge-of-the-kagu-svirfneblin.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 209,
|
||||||
|
"offsetX": 27,
|
||||||
|
"offsetY": 28,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -13577,6 +13733,14 @@
|
|||||||
"credit": "Damien Mammoliti",
|
"credit": "Damien Mammoliti",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a3"
|
"id": "5a3"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 209,
|
||||||
|
"offsetX": 27,
|
||||||
|
"offsetY": 28,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -15123,6 +15287,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/058-map-4.01-cave-of-echoes.webp"
|
"path": "adventure/QftIS/thumbnail/058-map-4.01-cave-of-echoes.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 201,
|
||||||
|
"offsetX": -21,
|
||||||
|
"offsetY": 21,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -15138,6 +15310,14 @@
|
|||||||
"credit": "Marc Moureau",
|
"credit": "Marc Moureau",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a4"
|
"id": "5a4"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 201,
|
||||||
|
"offsetX": -21,
|
||||||
|
"offsetY": 21,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -16017,6 +16197,13 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/061-map-4.02-eternal-garden.webp"
|
"path": "adventure/QftIS/thumbnail/061-map-4.02-eternal-garden.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 81,
|
||||||
|
"offsetX": 24,
|
||||||
|
"offsetY": 29,
|
||||||
|
"distance": 50
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -16032,6 +16219,13 @@
|
|||||||
"credit": "Marc Moureau",
|
"credit": "Marc Moureau",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a5"
|
"id": "5a5"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 81,
|
||||||
|
"offsetX": 24,
|
||||||
|
"offsetY": 29,
|
||||||
|
"distance": 50
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -17631,6 +17825,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/069-map-4.03-palace-of-spires.webp"
|
"path": "adventure/QftIS/thumbnail/069-map-4.03-palace-of-spires.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 209,
|
||||||
|
"offsetX": 95,
|
||||||
|
"offsetY": -18,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -17646,6 +17848,14 @@
|
|||||||
"credit": "Marc Moureau",
|
"credit": "Marc Moureau",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a6"
|
"id": "5a6"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 209,
|
||||||
|
"offsetX": 95,
|
||||||
|
"offsetY": -18,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -18914,6 +19124,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/076-map-5.01-false-tomb.webp"
|
"path": "adventure/QftIS/thumbnail/076-map-5.01-false-tomb.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 206,
|
||||||
|
"offsetX": 68,
|
||||||
|
"offsetY": -61,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -18929,6 +19147,14 @@
|
|||||||
"credit": "Stacey Allan & William Doyle",
|
"credit": "Stacey Allan & William Doyle",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a7"
|
"id": "5a7"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 206,
|
||||||
|
"offsetX": 68,
|
||||||
|
"offsetY": -61,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -19953,6 +20179,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/079-map-5.02-maze-of-mists-map.webp"
|
"path": "adventure/QftIS/thumbnail/079-map-5.02-maze-of-mists-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 191,
|
||||||
|
"offsetX": -89,
|
||||||
|
"offsetY": -52,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -19968,6 +20202,14 @@
|
|||||||
"credit": "Stacey Allan & William Doyle",
|
"credit": "Stacey Allan & William Doyle",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a8"
|
"id": "5a8"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 191,
|
||||||
|
"offsetX": -89,
|
||||||
|
"offsetY": -52,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -21724,6 +21966,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/082-map-5.04-halls-of-the-upper-priesthood-map.webp"
|
"path": "adventure/QftIS/thumbnail/082-map-5.04-halls-of-the-upper-priesthood-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 190,
|
||||||
|
"offsetX": -67,
|
||||||
|
"offsetY": -56,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -21739,6 +21989,14 @@
|
|||||||
"credit": "Stacey Allan & William Doyle",
|
"credit": "Stacey Allan & William Doyle",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5a9"
|
"id": "5a9"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 190,
|
||||||
|
"offsetX": -67,
|
||||||
|
"offsetY": -56,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -22207,6 +22465,9 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/084-map-5.05-dome-of-flight-map.webp"
|
"path": "adventure/QftIS/thumbnail/084-map-5.05-dome-of-flight-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "none"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -22222,6 +22483,9 @@
|
|||||||
"credit": "Marc Moureau",
|
"credit": "Marc Moureau",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5ab"
|
"id": "5ab"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "none"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -22470,7 +22734,10 @@
|
|||||||
"credit": "Marc Moureau",
|
"credit": "Marc Moureau",
|
||||||
"width": 2400,
|
"width": 2400,
|
||||||
"height": 3000,
|
"height": 3000,
|
||||||
"id": "5ac"
|
"id": "5ac",
|
||||||
|
"grid": {
|
||||||
|
"type": "none"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "image",
|
"type": "image",
|
||||||
@@ -22485,6 +22752,9 @@
|
|||||||
"credit": "Marc Moureau",
|
"credit": "Marc Moureau",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5ac"
|
"id": "5ac"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "none"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -23518,6 +23788,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/089-map-5.07-gauntlet.webp"
|
"path": "adventure/QftIS/thumbnail/089-map-5.07-gauntlet.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 225,
|
||||||
|
"offsetX": 36,
|
||||||
|
"offsetY": -55,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -23533,6 +23811,14 @@
|
|||||||
"credit": "Stacey Allan & William Doyle",
|
"credit": "Stacey Allan & William Doyle",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5ad"
|
"id": "5ad"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 225,
|
||||||
|
"offsetX": 36,
|
||||||
|
"offsetY": -55,
|
||||||
|
"scale": 2,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -23969,6 +24255,13 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/092-map-5.08-tomb-of-amun-sa-map.webp"
|
"path": "adventure/QftIS/thumbnail/092-map-5.08-tomb-of-amun-sa-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 87,
|
||||||
|
"offsetX": -10,
|
||||||
|
"offsetY": -36,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -23984,6 +24277,13 @@
|
|||||||
"credit": "Stacey Allan & William Doyle",
|
"credit": "Stacey Allan & William Doyle",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5ae"
|
"id": "5ae"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 87,
|
||||||
|
"offsetX": -10,
|
||||||
|
"offsetY": -36,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -24426,7 +24726,16 @@
|
|||||||
"credit": "Marc Moureau",
|
"credit": "Marc Moureau",
|
||||||
"width": 2550,
|
"width": 2550,
|
||||||
"height": 3300,
|
"height": 3300,
|
||||||
"id": "5af"
|
"id": "5af",
|
||||||
|
"grid": {
|
||||||
|
"type": "hexRowsOdd",
|
||||||
|
"size": 240,
|
||||||
|
"offsetX": 142,
|
||||||
|
"offsetY": 98,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 4,
|
||||||
|
"units": "miles"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "image",
|
"type": "image",
|
||||||
@@ -24441,6 +24750,15 @@
|
|||||||
"credit": "Marc Moureau",
|
"credit": "Marc Moureau",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5af"
|
"id": "5af"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "hexRowsOdd",
|
||||||
|
"size": 240,
|
||||||
|
"offsetX": 142,
|
||||||
|
"offsetY": 98,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 4,
|
||||||
|
"units": "miles"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -29141,6 +29459,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/102-map-6.02-lesser-caverns-map.webp"
|
"path": "adventure/QftIS/thumbnail/102-map-6.02-lesser-caverns-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 211,
|
||||||
|
"offsetX": 34,
|
||||||
|
"offsetY": -42,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -29156,6 +29482,14 @@
|
|||||||
"credit": "Mike Schley",
|
"credit": "Mike Schley",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5b0"
|
"id": "5b0"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 211,
|
||||||
|
"offsetX": 34,
|
||||||
|
"offsetY": -42,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -35175,6 +35509,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/106-map-6.03-greater-caverns-map.webp"
|
"path": "adventure/QftIS/thumbnail/106-map-6.03-greater-caverns-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 193,
|
||||||
|
"offsetX": -40,
|
||||||
|
"offsetY": 95,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -35190,6 +35532,14 @@
|
|||||||
"credit": "Mike Schley",
|
"credit": "Mike Schley",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5b1"
|
"id": "5b1"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 193,
|
||||||
|
"offsetX": -40,
|
||||||
|
"offsetY": 95,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -38883,6 +39233,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/117-map-7.01-spaceship-level-1-map.webp"
|
"path": "adventure/QftIS/thumbnail/117-map-7.01-spaceship-level-1-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 218,
|
||||||
|
"offsetX": -76,
|
||||||
|
"offsetY": 26,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -38898,6 +39256,14 @@
|
|||||||
"credit": "Damien Mammoliti",
|
"credit": "Damien Mammoliti",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5b2"
|
"id": "5b2"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 218,
|
||||||
|
"offsetX": -76,
|
||||||
|
"offsetY": 26,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -41203,6 +41569,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/121-map-7.02-spaceship-level-2-map.webp"
|
"path": "adventure/QftIS/thumbnail/121-map-7.02-spaceship-level-2-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 218,
|
||||||
|
"offsetX": -76,
|
||||||
|
"offsetY": 26,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -41218,6 +41592,14 @@
|
|||||||
"credit": "Damien Mammoliti",
|
"credit": "Damien Mammoliti",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5b3"
|
"id": "5b3"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 218,
|
||||||
|
"offsetX": -76,
|
||||||
|
"offsetY": 26,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -43782,6 +44164,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/125-map-7.03-spaceship-level-3-map.webp"
|
"path": "adventure/QftIS/thumbnail/125-map-7.03-spaceship-level-3-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 218,
|
||||||
|
"offsetX": -76,
|
||||||
|
"offsetY": 26,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -43797,6 +44187,14 @@
|
|||||||
"credit": "Damien Mammoliti",
|
"credit": "Damien Mammoliti",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5b4"
|
"id": "5b4"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 218,
|
||||||
|
"offsetX": -76,
|
||||||
|
"offsetY": 26,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -44507,6 +44905,14 @@
|
|||||||
"hrefThumbnail": {
|
"hrefThumbnail": {
|
||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "adventure/QftIS/thumbnail/129-map-7.04-spaceship-level-4-map.webp"
|
"path": "adventure/QftIS/thumbnail/129-map-7.04-spaceship-level-4-map.webp"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 218,
|
||||||
|
"offsetX": -76,
|
||||||
|
"offsetY": 26,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -44522,6 +44928,14 @@
|
|||||||
"credit": "Damien Mammoliti",
|
"credit": "Damien Mammoliti",
|
||||||
"mapParent": {
|
"mapParent": {
|
||||||
"id": "5b5"
|
"id": "5b5"
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"type": "square",
|
||||||
|
"size": 218,
|
||||||
|
"offsetX": -76,
|
||||||
|
"offsetY": 26,
|
||||||
|
"scale": 3,
|
||||||
|
"distance": 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -3707,8 +3707,7 @@
|
|||||||
"grid": {
|
"grid": {
|
||||||
"type": "square",
|
"type": "square",
|
||||||
"size": 66,
|
"size": 66,
|
||||||
"offsetX": 17,
|
"offsetX": -18,
|
||||||
"offsetY": 9,
|
|
||||||
"scale": 2
|
"scale": 2
|
||||||
},
|
},
|
||||||
"width": 1127,
|
"width": 1127,
|
||||||
|
|||||||
@@ -7281,6 +7281,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Androsphinx",
|
"name": "Androsphinx",
|
||||||
|
"group": [
|
||||||
|
"Sphinxes"
|
||||||
|
],
|
||||||
"source": "MM",
|
"source": "MM",
|
||||||
"page": 281,
|
"page": 281,
|
||||||
"srd": true,
|
"srd": true,
|
||||||
@@ -19833,6 +19836,12 @@
|
|||||||
"type": "internal",
|
"type": "internal",
|
||||||
"path": "bestiary/svirfneblin.mp3"
|
"path": "bestiary/svirfneblin.mp3"
|
||||||
},
|
},
|
||||||
|
"altArt": [
|
||||||
|
{
|
||||||
|
"name": "Svirfneblin",
|
||||||
|
"source": "QftIS"
|
||||||
|
}
|
||||||
|
],
|
||||||
"attachedItems": [
|
"attachedItems": [
|
||||||
"war pick|phb"
|
"war pick|phb"
|
||||||
],
|
],
|
||||||
@@ -37055,6 +37064,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Gynosphinx",
|
"name": "Gynosphinx",
|
||||||
|
"group": [
|
||||||
|
"Sphinxes"
|
||||||
|
],
|
||||||
"source": "MM",
|
"source": "MM",
|
||||||
"page": 282,
|
"page": 282,
|
||||||
"srd": true,
|
"srd": true,
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
{
|
{
|
||||||
"_meta": {
|
"_meta": {
|
||||||
|
"dependencies": {
|
||||||
|
"monster": [
|
||||||
|
"MM"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"internalCopies": [
|
||||||
|
"monster"
|
||||||
|
],
|
||||||
"otherSources": {
|
"otherSources": {
|
||||||
"monster": {
|
"monster": {
|
||||||
"MM": "QftIS",
|
"MM": "QftIS",
|
||||||
@@ -9,6 +17,25 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"monster": [
|
"monster": [
|
||||||
|
{
|
||||||
|
"name": "Amun Sa",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Ghost",
|
||||||
|
"source": "MM",
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the ghost",
|
||||||
|
"with": "Amun",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Android",
|
"name": "Android",
|
||||||
"source": "QftIS",
|
"source": "QftIS",
|
||||||
@@ -160,8 +187,169 @@
|
|||||||
"constitution",
|
"constitution",
|
||||||
"strength"
|
"strength"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true,
|
||||||
|
"_versions": [
|
||||||
|
{
|
||||||
|
"name": "Android Aerialist",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_mod": {
|
||||||
|
"trait": {
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": "Design Specialization"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"speed": {
|
||||||
|
"walk": 30,
|
||||||
|
"fly": {
|
||||||
|
"number": 30,
|
||||||
|
"condition": "(hover)"
|
||||||
|
},
|
||||||
|
"canHover": true
|
||||||
|
},
|
||||||
|
"senses": [
|
||||||
|
"darkvision 60 ft."
|
||||||
|
],
|
||||||
|
"spellcasting": null,
|
||||||
|
"reaction": null,
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Android Diplomat",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_mod": {
|
||||||
|
"trait": {
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": "Design Specialization"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"speed": {
|
||||||
|
"walk": 30
|
||||||
|
},
|
||||||
|
"senses": [
|
||||||
|
"darkvision 60 ft."
|
||||||
|
],
|
||||||
|
"spellcasting": [
|
||||||
|
{
|
||||||
|
"name": "Spellcasting",
|
||||||
|
"type": "spellcasting",
|
||||||
|
"headerEntries": [
|
||||||
|
"The android casts one of the following spells, requiring no material components and using Intelligence as the spellcasting ability:"
|
||||||
|
],
|
||||||
|
"daily": {
|
||||||
|
"2e": [
|
||||||
|
"{@spell Identify}",
|
||||||
|
"{@spell Tongues}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ability": "int",
|
||||||
|
"displayAs": "action"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"reaction": null,
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Android Diver",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_mod": {
|
||||||
|
"trait": {
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": "Design Specialization"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"speed": {
|
||||||
|
"walk": 30,
|
||||||
|
"swim": 30
|
||||||
|
},
|
||||||
|
"senses": [
|
||||||
|
"darkvision 60 ft."
|
||||||
|
],
|
||||||
|
"spellcasting": null,
|
||||||
|
"reaction": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Android Duelist",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_mod": {
|
||||||
|
"trait": {
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": "Design Specialization"
|
||||||
|
},
|
||||||
|
"reaction": {
|
||||||
|
"mode": "renameArr",
|
||||||
|
"renames": {
|
||||||
|
"rename": "Parry (Duelist Only)",
|
||||||
|
"with": "Parry"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"speed": {
|
||||||
|
"walk": 30
|
||||||
|
},
|
||||||
|
"senses": [
|
||||||
|
"darkvision 60 ft."
|
||||||
|
],
|
||||||
|
"spellcasting": null,
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Android Medic",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_mod": {
|
||||||
|
"trait": {
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": "Design Specialization"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"speed": {
|
||||||
|
"walk": 30
|
||||||
|
},
|
||||||
|
"senses": [
|
||||||
|
"darkvision 60 ft."
|
||||||
|
],
|
||||||
|
"spellcasting": [
|
||||||
|
{
|
||||||
|
"name": "Spellcasting",
|
||||||
|
"type": "spellcasting",
|
||||||
|
"headerEntries": [
|
||||||
|
"The android casts one of the following spells, requiring no material components and using Intelligence as the spellcasting ability:"
|
||||||
|
],
|
||||||
|
"daily": {
|
||||||
|
"2e": [
|
||||||
|
"{@spell Cure Wounds} (as a 3rd-level spell)",
|
||||||
|
"{@spell Identify}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ability": "int",
|
||||||
|
"displayAs": "action"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"reaction": null,
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Android Sentry",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_mod": {
|
||||||
|
"trait": {
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": "Design Specialization"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"speed": {
|
||||||
|
"walk": 30
|
||||||
|
},
|
||||||
|
"senses": [
|
||||||
|
"blindsight 60 ft.",
|
||||||
|
"darkvision 60 ft."
|
||||||
|
],
|
||||||
|
"spellcasting": null,
|
||||||
|
"reaction": null,
|
||||||
|
"hasToken": true
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Barkburr",
|
"name": "Barkburr",
|
||||||
@@ -270,6 +458,7 @@
|
|||||||
"savingThrowForced": [
|
"savingThrowForced": [
|
||||||
"constitution"
|
"constitution"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -379,6 +568,7 @@
|
|||||||
"RW",
|
"RW",
|
||||||
"THW"
|
"THW"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true
|
"hasFluff": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -476,6 +666,7 @@
|
|||||||
"MLW",
|
"MLW",
|
||||||
"MW"
|
"MW"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true
|
"hasFluff": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -602,8 +793,38 @@
|
|||||||
"dexterity",
|
"dexterity",
|
||||||
"wisdom"
|
"wisdom"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true
|
"hasFluff": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Cipolla",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Tower Sage",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_templates": [
|
||||||
|
{
|
||||||
|
"name": "Dragonborn (Silver)",
|
||||||
|
"source": "PHB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the tower sage",
|
||||||
|
"with": "Cipolla",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"alignment": [
|
||||||
|
"L",
|
||||||
|
"E"
|
||||||
|
],
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Combat Robot",
|
"name": "Combat Robot",
|
||||||
"source": "QftIS",
|
"source": "QftIS",
|
||||||
@@ -746,6 +967,7 @@
|
|||||||
"constitution",
|
"constitution",
|
||||||
"dexterity"
|
"dexterity"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -875,6 +1097,7 @@
|
|||||||
"savingThrowForcedSpell": [
|
"savingThrowForcedSpell": [
|
||||||
"wisdom"
|
"wisdom"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -973,6 +1196,7 @@
|
|||||||
"MW",
|
"MW",
|
||||||
"RW"
|
"RW"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -1112,6 +1336,7 @@
|
|||||||
"constitution",
|
"constitution",
|
||||||
"strength"
|
"strength"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -1291,6 +1516,7 @@
|
|||||||
"constitution",
|
"constitution",
|
||||||
"wisdom"
|
"wisdom"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -1441,6 +1667,7 @@
|
|||||||
"intelligence",
|
"intelligence",
|
||||||
"strength"
|
"strength"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -1520,9 +1747,29 @@
|
|||||||
"miscTags": [
|
"miscTags": [
|
||||||
"MW"
|
"MW"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Grisdelfawr",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Young Red Dragon",
|
||||||
|
"source": "MM",
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the dragon",
|
||||||
|
"with": "Grisdelfawr",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Guardian of Gorm",
|
"name": "Guardian of Gorm",
|
||||||
"source": "QftIS",
|
"source": "QftIS",
|
||||||
@@ -1606,6 +1853,7 @@
|
|||||||
"RW",
|
"RW",
|
||||||
"THW"
|
"THW"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -1717,8 +1965,180 @@
|
|||||||
"constitution",
|
"constitution",
|
||||||
"dexterity"
|
"dexterity"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true,
|
||||||
|
"_versions": [
|
||||||
|
{
|
||||||
|
"name": "Horrid Plant Dew Drinker",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_mod": {
|
||||||
|
"trait": {
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": "Horrid Plant Varieties"
|
||||||
|
},
|
||||||
|
"bonus": [
|
||||||
|
{
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": [
|
||||||
|
"Sap Squirt (Purple Blossom Only)",
|
||||||
|
"Spiked Leaves (Snapper Saw Only)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "renameArr",
|
||||||
|
"renames": {
|
||||||
|
"rename": "Vampiric Tendril (Dew Drinker Only)",
|
||||||
|
"with": "Vampiric Tendril"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Horrid Plant Purple Blossom",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_mod": {
|
||||||
|
"trait": {
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": "Horrid Plant Varieties"
|
||||||
|
},
|
||||||
|
"bonus": [
|
||||||
|
{
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": [
|
||||||
|
"Spiked Leaves (Snapper Saw Only)",
|
||||||
|
"Vampiric Tendril (Dew Drinker Only)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "renameArr",
|
||||||
|
"renames": {
|
||||||
|
"rename": "Sap Squirt (Purple Blossom Only)",
|
||||||
|
"with": "Sap Squirt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Horrid Plant Snapper Saw",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_mod": {
|
||||||
|
"trait": {
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": "Horrid Plant Varieties"
|
||||||
|
},
|
||||||
|
"bonus": [
|
||||||
|
{
|
||||||
|
"mode": "removeArr",
|
||||||
|
"names": [
|
||||||
|
"Sap Squirt (Purple Blossom Only)",
|
||||||
|
"Vampiric Tendril (Dew Drinker Only)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "renameArr",
|
||||||
|
"renames": {
|
||||||
|
"rename": "Spiked Leaves (Snapper Saw Only)",
|
||||||
|
"with": "Spiked Leaves"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Iaseda",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Acolyte",
|
||||||
|
"source": "MM",
|
||||||
|
"_templates": [
|
||||||
|
{
|
||||||
|
"name": "Human",
|
||||||
|
"source": "PHB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the acolyte",
|
||||||
|
"with": "Iaseda",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"alignment": [
|
||||||
|
"L",
|
||||||
|
"G"
|
||||||
|
],
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Isabela Folcarae",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Bandit Captain",
|
||||||
|
"source": "MM",
|
||||||
|
"_templates": [
|
||||||
|
{
|
||||||
|
"name": "Human",
|
||||||
|
"source": "PHB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the captain",
|
||||||
|
"with": "Isabela",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"alignment": [
|
||||||
|
"L",
|
||||||
|
"G"
|
||||||
|
],
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Juliana",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Noble",
|
||||||
|
"source": "MM",
|
||||||
|
"_templates": [
|
||||||
|
{
|
||||||
|
"name": "Human",
|
||||||
|
"source": "PHB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the noble",
|
||||||
|
"with": "Juliana",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"alignment": [
|
||||||
|
"N",
|
||||||
|
"G"
|
||||||
|
],
|
||||||
|
"ac": [
|
||||||
|
11
|
||||||
|
],
|
||||||
|
"action": null,
|
||||||
|
"hasToken": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Leprechaun",
|
"name": "Leprechaun",
|
||||||
@@ -1875,6 +2295,7 @@
|
|||||||
"savingThrowForcedSpell": [
|
"savingThrowForcedSpell": [
|
||||||
"intelligence"
|
"intelligence"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -1964,6 +2385,7 @@
|
|||||||
"dexterity",
|
"dexterity",
|
||||||
"wisdom"
|
"wisdom"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -2085,6 +2507,7 @@
|
|||||||
"constitution",
|
"constitution",
|
||||||
"dexterity"
|
"dexterity"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -2187,6 +2610,7 @@
|
|||||||
"savingThrowForced": [
|
"savingThrowForced": [
|
||||||
"intelligence"
|
"intelligence"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -2418,6 +2842,7 @@
|
|||||||
"savingThrowForced": [
|
"savingThrowForced": [
|
||||||
"strength"
|
"strength"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -2609,9 +3034,43 @@
|
|||||||
"constitution",
|
"constitution",
|
||||||
"wisdom"
|
"wisdom"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Orlando",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Noble",
|
||||||
|
"source": "MM",
|
||||||
|
"_templates": [
|
||||||
|
{
|
||||||
|
"name": "Human",
|
||||||
|
"source": "PHB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the noble",
|
||||||
|
"with": "Orlando",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"alignment": [
|
||||||
|
"N",
|
||||||
|
"G"
|
||||||
|
],
|
||||||
|
"ac": [
|
||||||
|
11
|
||||||
|
],
|
||||||
|
"action": null,
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Pech",
|
"name": "Pech",
|
||||||
"source": "QftIS",
|
"source": "QftIS",
|
||||||
@@ -2756,9 +3215,169 @@
|
|||||||
"savingThrowForcedSpell": [
|
"savingThrowForcedSpell": [
|
||||||
"dexterity"
|
"dexterity"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Piyarz",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Tower Sage",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_templates": [
|
||||||
|
{
|
||||||
|
"name": "Human",
|
||||||
|
"source": "PHB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the tower sage",
|
||||||
|
"with": "Piyarz",
|
||||||
|
"flags": "i"
|
||||||
|
},
|
||||||
|
"trait": {
|
||||||
|
"mode": "appendArr",
|
||||||
|
"items": {
|
||||||
|
"name": "Special Equipment",
|
||||||
|
"entries": [
|
||||||
|
"Piyarz wears a {@item Ring of Fire Resistance}, granting him resistance to fire damage."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"alignment": [
|
||||||
|
"L",
|
||||||
|
"E"
|
||||||
|
],
|
||||||
|
"resist": [
|
||||||
|
"fire"
|
||||||
|
],
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Porro",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Tower Sage",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_templates": [
|
||||||
|
{
|
||||||
|
"name": "Stout Halfling",
|
||||||
|
"source": "PHB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the tower sage",
|
||||||
|
"with": "Porro",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"alignment": [
|
||||||
|
"L",
|
||||||
|
"E"
|
||||||
|
],
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Queen Zanobis",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Wight",
|
||||||
|
"source": "MM",
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the wight",
|
||||||
|
"with": "Queen Zanobis",
|
||||||
|
"flags": "i"
|
||||||
|
},
|
||||||
|
"action": [
|
||||||
|
{
|
||||||
|
"mode": "replaceArr",
|
||||||
|
"replace": "Multiattack",
|
||||||
|
"items": {
|
||||||
|
"name": "Multiattack",
|
||||||
|
"entries": [
|
||||||
|
"The wight makes two scepter attacks or two longbow attacks. It can use its Life Drain in place of one scepter attack."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mode": "replaceArr",
|
||||||
|
"replace": "Longsword",
|
||||||
|
"items": {
|
||||||
|
"name": "Longsword",
|
||||||
|
"entries": [
|
||||||
|
"{@atk mw} {@hit 4} to hit, reach 5 ft., one target. {@h}6 ({@damage 1d8 + 2}) bludgeoning damage, or 7 ({@damage 1d10 + 2}) bludgeoning damage if used with two hands."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Shalfey",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Tower Sage",
|
||||||
|
"source": "QftIS",
|
||||||
|
"_templates": [
|
||||||
|
{
|
||||||
|
"name": "Human",
|
||||||
|
"source": "PHB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the tower sage",
|
||||||
|
"with": "Shalfey",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"alignment": [
|
||||||
|
"L",
|
||||||
|
"G"
|
||||||
|
],
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Silverlily",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Unicorn",
|
||||||
|
"source": "MM",
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the unicorn",
|
||||||
|
"with": "Silverlily",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Sion",
|
"name": "Sion",
|
||||||
"isNpc": true,
|
"isNpc": true,
|
||||||
@@ -2918,9 +3537,48 @@
|
|||||||
"savingThrowForced": [
|
"savingThrowForced": [
|
||||||
"charisma"
|
"charisma"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Spirit of Hunger",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Wraith",
|
||||||
|
"source": "MM",
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the wraith",
|
||||||
|
"with": "Spirit of Hunger",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Stargleam",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Unicorn",
|
||||||
|
"source": "MM",
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the unicorn",
|
||||||
|
"with": "Stargleam",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Swarm of Gibberlings",
|
"name": "Swarm of Gibberlings",
|
||||||
"source": "QftIS",
|
"source": "QftIS",
|
||||||
@@ -3022,6 +3680,7 @@
|
|||||||
"miscTags": [
|
"miscTags": [
|
||||||
"MW"
|
"MW"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -3226,6 +3885,7 @@
|
|||||||
"savingThrowForced": [
|
"savingThrowForced": [
|
||||||
"constitution"
|
"constitution"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -3322,6 +3982,7 @@
|
|||||||
"MW",
|
"MW",
|
||||||
"RW"
|
"RW"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -3439,9 +4100,35 @@
|
|||||||
"constitution",
|
"constitution",
|
||||||
"dexterity"
|
"dexterity"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Uma",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Knight",
|
||||||
|
"source": "MM",
|
||||||
|
"_templates": [
|
||||||
|
{
|
||||||
|
"name": "Human",
|
||||||
|
"source": "PHB"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the knight",
|
||||||
|
"with": "Uma",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Vegepygmy Moldmaker",
|
"name": "Vegepygmy Moldmaker",
|
||||||
"source": "QftIS",
|
"source": "QftIS",
|
||||||
@@ -3556,6 +4243,7 @@
|
|||||||
"savingThrowForced": [
|
"savingThrowForced": [
|
||||||
"constitution"
|
"constitution"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -3665,6 +4353,7 @@
|
|||||||
"MW",
|
"MW",
|
||||||
"RW"
|
"RW"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -3764,9 +4453,29 @@
|
|||||||
"savingThrowForced": [
|
"savingThrowForced": [
|
||||||
"strength"
|
"strength"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Vuuthramis",
|
||||||
|
"isNpc": true,
|
||||||
|
"isNamedCreature": true,
|
||||||
|
"source": "QftIS",
|
||||||
|
"_copy": {
|
||||||
|
"name": "Young Bronze Dragon",
|
||||||
|
"source": "MM",
|
||||||
|
"_mod": {
|
||||||
|
"*": {
|
||||||
|
"mode": "replaceTxt",
|
||||||
|
"replace": "the dragon",
|
||||||
|
"with": "Vuuthramis",
|
||||||
|
"flags": "i"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"hasToken": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Warrior of Madarua",
|
"name": "Warrior of Madarua",
|
||||||
"source": "QftIS",
|
"source": "QftIS",
|
||||||
@@ -3844,6 +4553,7 @@
|
|||||||
"RW",
|
"RW",
|
||||||
"THW"
|
"THW"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -3946,6 +4656,7 @@
|
|||||||
"MW",
|
"MW",
|
||||||
"RCH"
|
"RCH"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -4053,6 +4764,7 @@
|
|||||||
"savingThrowForced": [
|
"savingThrowForced": [
|
||||||
"constitution"
|
"constitution"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
},
|
},
|
||||||
@@ -4243,6 +4955,7 @@
|
|||||||
"constitution",
|
"constitution",
|
||||||
"dexterity"
|
"dexterity"
|
||||||
],
|
],
|
||||||
|
"hasToken": true,
|
||||||
"hasFluff": true,
|
"hasFluff": true,
|
||||||
"hasFluffImages": true
|
"hasFluffImages": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -275,6 +275,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Dragonborn (Silver)",
|
||||||
|
"source": "PHB",
|
||||||
|
"page": 32,
|
||||||
|
"ref": "{@race Dragonborn||Dragonborn (Silver)}",
|
||||||
|
"apply": {
|
||||||
|
"_root": {
|
||||||
|
"size": [
|
||||||
|
"M"
|
||||||
|
],
|
||||||
|
"type": {
|
||||||
|
"type": "humanoid",
|
||||||
|
"tags": [
|
||||||
|
"dragonborn"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"_mod": {
|
||||||
|
"resist": {
|
||||||
|
"mode": "appendIfNotExistsArr",
|
||||||
|
"items": "cold"
|
||||||
|
},
|
||||||
|
"languages": {
|
||||||
|
"mode": "appendIfNotExistsArr",
|
||||||
|
"items": "Draconic"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Drow",
|
"name": "Drow",
|
||||||
"source": "PHB",
|
"source": "PHB",
|
||||||
@@ -1677,6 +1706,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Human",
|
||||||
|
"source": "PHB",
|
||||||
|
"page": 29,
|
||||||
|
"ref": "{@race Human}",
|
||||||
|
"apply": {
|
||||||
|
"_root": {
|
||||||
|
"size": [
|
||||||
|
"M"
|
||||||
|
],
|
||||||
|
"type": {
|
||||||
|
"type": "humanoid",
|
||||||
|
"tags": [
|
||||||
|
"human"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Kenku",
|
"name": "Kenku",
|
||||||
"source": "VGM",
|
"source": "VGM",
|
||||||
|
|||||||
@@ -2736,5 +2736,10 @@
|
|||||||
"ver": "1.209.1",
|
"ver": "1.209.1",
|
||||||
"date": "2024-07-10",
|
"date": "2024-07-10",
|
||||||
"txt": "- Improved mobile footer layout on Bestiary, Items, Spells, and Psionics pages"
|
"txt": "- Improved mobile footer layout on Bestiary, Items, Spells, and Psionics pages"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ver": "1.209.2",
|
||||||
|
"date": "2024-07-19",
|
||||||
|
"txt": "- Added Quests from the Infinite Staircase tokens; NPCs/other creatures\n- Added `p`/`P` hotkeys to pin/unpin sublist items\n- Fixed Classes Page outline filling up with junk items after hovering other content\n- (Homebrew) Fixed Adventure/Book pages failing to load un-loaded but repo-available homebrew on navigation\n- (Fixed typos/added tags)"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -214,7 +214,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Elven",
|
"pantheon": "Elven",
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Elven",
|
"pantheon": "Elven",
|
||||||
@@ -1686,7 +1686,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Dwarven",
|
"pantheon": "Dwarven",
|
||||||
@@ -1715,7 +1715,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Dwarven",
|
"pantheon": "Dwarven",
|
||||||
@@ -1904,7 +1904,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
@@ -1939,7 +1939,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
@@ -2663,7 +2663,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Halfling",
|
"pantheon": "Halfling",
|
||||||
@@ -2691,7 +2691,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Halfling",
|
"pantheon": "Halfling",
|
||||||
@@ -3214,7 +3214,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Forgotten Realms",
|
"pantheon": "Forgotten Realms",
|
||||||
@@ -3242,7 +3242,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Faerûnian",
|
"pantheon": "Faerûnian",
|
||||||
@@ -4161,7 +4161,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Gnome",
|
"pantheon": "Gnome",
|
||||||
@@ -4188,7 +4188,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Gnomish",
|
"pantheon": "Gnomish",
|
||||||
@@ -10321,7 +10321,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Dragonlance",
|
"pantheon": "Dragonlance",
|
||||||
@@ -11482,7 +11482,7 @@
|
|||||||
"additionalSources": [
|
"additionalSources": [
|
||||||
{
|
{
|
||||||
"source": "TCE",
|
"source": "TCE",
|
||||||
"page": 32
|
"page": 33
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Greyhawk",
|
"pantheon": "Greyhawk",
|
||||||
@@ -16677,6 +16677,10 @@
|
|||||||
{
|
{
|
||||||
"source": "SCAG",
|
"source": "SCAG",
|
||||||
"page": 125
|
"page": 125
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"source": "TCE",
|
||||||
|
"page": 31
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"pantheon": "Greyhawk",
|
"pantheon": "Greyhawk",
|
||||||
|
|||||||
@@ -45,7 +45,8 @@
|
|||||||
"value": "5"
|
"value": "5"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"enchantmentRiderParent": "XY7pERdPxxb8bjlq"
|
"enchantmentRiderParent": "XY7pERdPxxb8bjlq",
|
||||||
|
"transfer": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Arcane Propulsion",
|
"name": "Arcane Propulsion",
|
||||||
@@ -432,23 +433,14 @@
|
|||||||
"mode": "ADD",
|
"mode": "ADD",
|
||||||
"value": "1"
|
"value": "1"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"key": "system.bonuses.msak.damage",
|
|
||||||
"mode": "ADD",
|
|
||||||
"value": "1"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"key": "system.bonuses.rsak.attack",
|
"key": "system.bonuses.rsak.attack",
|
||||||
"mode": "ADD",
|
"mode": "ADD",
|
||||||
"value": "1"
|
"value": "1"
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "system.bonuses.rsak.damage",
|
|
||||||
"mode": "ADD",
|
|
||||||
"value": "1"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"enchantmentRiderParent": "syx3ZXUoQwVJUZxP"
|
"enchantmentRiderParent": "syx3ZXUoQwVJUZxP",
|
||||||
|
"transfer": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Enhanced Arcane Focus +2",
|
"name": "Enhanced Arcane Focus +2",
|
||||||
@@ -458,23 +450,14 @@
|
|||||||
"mode": "ADD",
|
"mode": "ADD",
|
||||||
"value": "2"
|
"value": "2"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"key": "system.bonuses.msak.damage",
|
|
||||||
"mode": "ADD",
|
|
||||||
"value": "2"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"key": "system.bonuses.rsak.attack",
|
"key": "system.bonuses.rsak.attack",
|
||||||
"mode": "ADD",
|
"mode": "ADD",
|
||||||
"value": "2"
|
"value": "2"
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "system.bonuses.rsak.damage",
|
|
||||||
"mode": "ADD",
|
|
||||||
"value": "2"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"enchantmentRiderParent": "I4qB050rdgSsoIEd"
|
"enchantmentRiderParent": "I4qB050rdgSsoIEd",
|
||||||
|
"transfer": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -697,7 +680,8 @@
|
|||||||
"mode": "ADD",
|
"mode": "ADD",
|
||||||
"value": "+2"
|
"value": "+2"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"transfer": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -799,7 +783,8 @@
|
|||||||
"mode": "ADD",
|
"mode": "ADD",
|
||||||
"value": "slashing"
|
"value": "slashing"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"transfer": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -565,6 +565,9 @@ class BookUtil {
|
|||||||
if (await this._booksHashChange_pDoLoadPrerelease({bookId, $contents, hashParts, isNewBook})) return;
|
if (await this._booksHashChange_pDoLoadPrerelease({bookId, $contents, hashParts, isNewBook})) return;
|
||||||
if (await this._booksHashChange_pDoLoadBrew({bookId, $contents, hashParts, isNewBook})) return;
|
if (await this._booksHashChange_pDoLoadBrew({bookId, $contents, hashParts, isNewBook})) return;
|
||||||
|
|
||||||
|
// if it's prerelease/homebrew but hasn't been loaded
|
||||||
|
if (await this._booksHashChange_pDoFetchPrereleaseBrew({bookId, $contents, hashParts, isNewBook})) return;
|
||||||
|
|
||||||
return this._booksHashChange_handleNotFound({$contents, bookId});
|
return this._booksHashChange_handleNotFound({$contents, bookId});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,6 +598,27 @@ class BookUtil {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async _booksHashChange_pDoFetchPrereleaseBrew ({bookId, $contents, hashParts, isNewBook}) {
|
||||||
|
const {source} = await UrlUtil.pAutoDecodeHash(bookId);
|
||||||
|
|
||||||
|
const loaded = await DataLoader.pCacheAndGetHash(UrlUtil.getCurrentPage(), bookId, {isSilent: true});
|
||||||
|
if (!loaded) return false;
|
||||||
|
|
||||||
|
return [
|
||||||
|
PrereleaseUtil,
|
||||||
|
BrewUtil2,
|
||||||
|
]
|
||||||
|
.some(brewUtil => {
|
||||||
|
if (
|
||||||
|
brewUtil.hasSourceJson(source)
|
||||||
|
&& brewUtil.isReloadRequired()
|
||||||
|
) {
|
||||||
|
brewUtil.doLocationReload({isRetainHash: true});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static _booksHashChange_getCleanName (fromIndex) {
|
static _booksHashChange_getCleanName (fromIndex) {
|
||||||
if (fromIndex.parentSource) {
|
if (fromIndex.parentSource) {
|
||||||
const fullParentSource = Parser.sourceJsonToFull(fromIndex.parentSource);
|
const fullParentSource = Parser.sourceJsonToFull(fromIndex.parentSource);
|
||||||
|
|||||||
@@ -88,11 +88,9 @@ class UtilClassesPage {
|
|||||||
Renderer.get().setFirstSection(true);
|
Renderer.get().setFirstSection(true);
|
||||||
|
|
||||||
if (hasEntries) {
|
if (hasEntries) {
|
||||||
const renderer = Renderer.get();
|
Renderer.get().withDepthTracker(
|
||||||
|
depthArr || [],
|
||||||
if (depthArr) renderer.setDepthTracker(depthArr, {additionalPropsInherited: ["_isStandardSource"]});
|
({renderer}) => {
|
||||||
else renderer.setDepthTracker([]);
|
|
||||||
|
|
||||||
entFluff.entries.filter(f => f.source === ent.source).forEach(f => f._isStandardSource = true);
|
entFluff.entries.filter(f => f.source === ent.source).forEach(f => f._isStandardSource = true);
|
||||||
|
|
||||||
entFluff.entries.forEach((f, i) => {
|
entFluff.entries.forEach((f, i) => {
|
||||||
@@ -123,6 +121,9 @@ class UtilClassesPage {
|
|||||||
|
|
||||||
stack += renderer.render(cpy);
|
stack += renderer.render(cpy);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
{additionalPropsInherited: ["_isStandardSource"]},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasImages) {
|
if (hasImages) {
|
||||||
@@ -2158,10 +2159,16 @@ class ClassesPage extends MixinComponentGlobalState(MixinBaseComponent(MixinProx
|
|||||||
if (source === cls.source) return {isSkip: true};
|
if (source === cls.source) return {isSkip: true};
|
||||||
},
|
},
|
||||||
fn: () => {
|
fn: () => {
|
||||||
|
return Renderer.get().withDepthTracker(
|
||||||
|
depthArr,
|
||||||
|
({renderer}) => {
|
||||||
return $(`<tr data-scroll-id="${ixLvl}-${ixFeature}" data-feature-type="class" class="cls-main__linked-titles"><td colspan="6"></td></tr>`)
|
return $(`<tr data-scroll-id="${ixLvl}-${ixFeature}" data-feature-type="class" class="cls-main__linked-titles"><td colspan="6"></td></tr>`)
|
||||||
.fastSetHtml(Renderer.get().setDepthTracker(depthArr, {additionalProps: ["isReprinted"], additionalPropsInherited: ["_isStandardSource", "isClassFeatureVariant"]}).render(feature))
|
.fastSetHtml(renderer.render(feature))
|
||||||
.appendTo($content);
|
.appendTo($content);
|
||||||
},
|
},
|
||||||
|
{additionalProps: ["isReprinted"], additionalPropsInherited: ["_isStandardSource", "isClassFeatureVariant"]},
|
||||||
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
this._trackOutlineCfData(ixLvl, ixFeature, depthArr);
|
this._trackOutlineCfData(ixLvl, ixFeature, depthArr);
|
||||||
|
|
||||||
@@ -2173,7 +2180,7 @@ class ClassesPage extends MixinComponentGlobalState(MixinBaseComponent(MixinProx
|
|||||||
|
|
||||||
// Add a placeholder feature to display when no subclasses are active
|
// Add a placeholder feature to display when no subclasses are active
|
||||||
const $trSubclassFeature = $(`<tr class="cls-main__sc-feature" data-subclass-none-message="true"><td colspan="6"></td></tr>`)
|
const $trSubclassFeature = $(`<tr class="cls-main__sc-feature" data-subclass-none-message="true"><td colspan="6"></td></tr>`)
|
||||||
.fastSetHtml(Renderer.get().setDepthTracker([]).render({type: "entries", entries: [{name: `{@note No Subclass Selected}`, type: "entries", entries: [`{@note <span class="clickable roller" data-jump-select-a-subclass="true">Select a subclass</span> to view its feature(s) here.}`]}]}))
|
.fastSetHtml(Renderer.get().withDepthTracker([], ({renderer}) => renderer.render({type: "entries", entries: [{name: `{@note No Subclass Selected}`, type: "entries", entries: [`{@note <span class="clickable roller" data-jump-select-a-subclass="true">Select a subclass</span> to view its feature(s) here.}`]}]})))
|
||||||
.appendTo($content);
|
.appendTo($content);
|
||||||
|
|
||||||
await cls.subclasses.pSerialAwaitMap(async sc => {
|
await cls.subclasses.pSerialAwaitMap(async sc => {
|
||||||
@@ -2224,7 +2231,9 @@ class ClassesPage extends MixinComponentGlobalState(MixinBaseComponent(MixinProx
|
|||||||
},
|
},
|
||||||
fn: () => {
|
fn: () => {
|
||||||
const $trSubclassFeature = $(`<tr class="cls-main__sc-feature" data-subclass-id="${UrlUtil.getStateKeySubclass(sc)}"><td colspan="6"></td></tr>`)
|
const $trSubclassFeature = $(`<tr class="cls-main__sc-feature" data-subclass-id="${UrlUtil.getStateKeySubclass(sc)}"><td colspan="6"></td></tr>`)
|
||||||
.fastSetHtml(Renderer.get().setDepthTracker(depthArr, {additionalProps: ["isReprinted"], additionalPropsInherited: ["_isStandardSource", "isClassFeatureVariant"]}).render(toRender))
|
.fastSetHtml(
|
||||||
|
Renderer.get().withDepthTracker(depthArr, ({renderer}) => renderer.render(toRender), {additionalProps: ["isReprinted"], additionalPropsInherited: ["_isStandardSource", "isClassFeatureVariant"]}),
|
||||||
|
)
|
||||||
.appendTo($content);
|
.appendTo($content);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -422,11 +422,11 @@ class SublistManager {
|
|||||||
await this.pDoSublistRemove({entity, doFinalize: true});
|
await this.pDoSublistRemove({entity, doFinalize: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
getTitleBtnAdd () { return `Add (SHIFT for ${this._shiftCountAddSubtract})`; }
|
getTitleBtnAdd () { return `Add (SHIFT for ${this._shiftCountAddSubtract}) (Hotkey: p)`; }
|
||||||
getTitleBtnSubtract () { return `Subtract (SHIFT for ${this._shiftCountAddSubtract})`; }
|
getTitleBtnSubtract () { return `Subtract (SHIFT for ${this._shiftCountAddSubtract}) (Hotkey: P)`; }
|
||||||
|
|
||||||
async pHandleClick_btnAdd ({evt, entity}) {
|
async pHandleClick_btnAdd ({entity, isMultiple = false}) {
|
||||||
const addCount = evt.shiftKey ? this._shiftCountAddSubtract : 1;
|
const addCount = isMultiple ? this._shiftCountAddSubtract : 1;
|
||||||
return this.pDoSublistAdd({
|
return this.pDoSublistAdd({
|
||||||
index: Hist.lastLoadedId,
|
index: Hist.lastLoadedId,
|
||||||
entity,
|
entity,
|
||||||
@@ -435,8 +435,8 @@ class SublistManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async pHandleClick_btnSubtract ({evt, entity}) {
|
async pHandleClick_btnSubtract ({entity, isMultiple = false}) {
|
||||||
const subtractCount = evt.shiftKey ? this._shiftCountAddSubtract : 1;
|
const subtractCount = isMultiple ? this._shiftCountAddSubtract : 1;
|
||||||
return this.pDoSublistSubtract({
|
return this.pDoSublistSubtract({
|
||||||
index: Hist.lastLoadedId,
|
index: Hist.lastLoadedId,
|
||||||
entity,
|
entity,
|
||||||
@@ -1567,7 +1567,7 @@ class ListPage {
|
|||||||
|
|
||||||
const key = EventUtil.getKeyIgnoreCapsLock(evt);
|
const key = EventUtil.getKeyIgnoreCapsLock(evt);
|
||||||
switch (key) {
|
switch (key) {
|
||||||
// K up; J down
|
// k up; j down
|
||||||
case "k":
|
case "k":
|
||||||
case "j": {
|
case "j": {
|
||||||
// don't switch if the user is typing somewhere else
|
// don't switch if the user is typing somewhere else
|
||||||
@@ -1576,6 +1576,24 @@ class ListPage {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// p: toggle pinned/add 1 to sublist
|
||||||
|
case "p": {
|
||||||
|
if (EventUtil.isInInput(evt)) return;
|
||||||
|
if (!this._sublistManager) return;
|
||||||
|
if (this._sublistManager.isSublistItemsCountable) this._sublistManager.pHandleClick_btnAdd({entity: this._lastRender.entity}).then(null);
|
||||||
|
else this._sublistManager.pHandleClick_btnPin({entity: this._lastRender.entity}).then(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// P: toggle pinned/remove 1 from sublist
|
||||||
|
case "P": {
|
||||||
|
if (EventUtil.isInInput(evt)) return;
|
||||||
|
if (!this._sublistManager) return;
|
||||||
|
if (this._sublistManager.isSublistItemsCountable) this._sublistManager.pHandleClick_btnSubtract({entity: this._lastRender.entity}).then(null);
|
||||||
|
else this._sublistManager.pHandleClick_btnPin({entity: this._lastRender.entity}).then(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// m: expand/collapse current selection
|
||||||
case "m": {
|
case "m": {
|
||||||
if (EventUtil.isInInput(evt)) return;
|
if (EventUtil.isInInput(evt)) return;
|
||||||
const it = Hist.getSelectedListElementWithLocation();
|
const it = Hist.getSelectedListElementWithLocation();
|
||||||
@@ -1735,21 +1753,21 @@ class ListPage {
|
|||||||
this._getOrTabRightButton(`pin`, `pushpin`)
|
this._getOrTabRightButton(`pin`, `pushpin`)
|
||||||
.off("click")
|
.off("click")
|
||||||
.on("click", () => this._sublistManager.pHandleClick_btnPin({entity: this._lastRender.entity}))
|
.on("click", () => this._sublistManager.pHandleClick_btnPin({entity: this._lastRender.entity}))
|
||||||
.title("Pin (Toggle)");
|
.title("Pin (Toggle) (Hotkey: p/P)");
|
||||||
}
|
}
|
||||||
|
|
||||||
_bindAddButton () {
|
_bindAddButton () {
|
||||||
this._getOrTabRightButton(`sublist-add`, `plus`)
|
this._getOrTabRightButton(`sublist-add`, `plus`)
|
||||||
.off("click")
|
.off("click")
|
||||||
.title(this._sublistManager.getTitleBtnAdd())
|
.title(this._sublistManager.getTitleBtnAdd())
|
||||||
.on("click", evt => this._sublistManager.pHandleClick_btnAdd({evt, entity: this._lastRender.entity}));
|
.on("click", evt => this._sublistManager.pHandleClick_btnAdd({entity: this._lastRender.entity, isMultiple: !!evt.shiftKey}));
|
||||||
}
|
}
|
||||||
|
|
||||||
_bindSubtractButton () {
|
_bindSubtractButton () {
|
||||||
this._getOrTabRightButton(`sublist-subtract`, `minus`)
|
this._getOrTabRightButton(`sublist-subtract`, `minus`)
|
||||||
.off("click")
|
.off("click")
|
||||||
.title(this._sublistManager.getTitleBtnSubtract())
|
.title(this._sublistManager.getTitleBtnSubtract())
|
||||||
.on("click", evt => this._sublistManager.pHandleClick_btnSubtract({evt, entity: this._lastRender.entity}));
|
.on("click", evt => this._sublistManager.pHandleClick_btnSubtract({entity: this._lastRender.entity, isMultiple: !!evt.shiftKey}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -915,8 +915,7 @@ class IndexableFileQuickReference extends IndexableFile {
|
|||||||
|
|
||||||
static getChapterNameMetas (it, {isRequireQuickrefFlag = true} = {}) {
|
static getChapterNameMetas (it, {isRequireQuickrefFlag = true} = {}) {
|
||||||
const trackedNames = [];
|
const trackedNames = [];
|
||||||
const renderer = Renderer.get().setDepthTracker(trackedNames);
|
Renderer.get().withDepthTracker(trackedNames, ({renderer}) => renderer.render(it));
|
||||||
renderer.render(it);
|
|
||||||
|
|
||||||
const nameCounts = {};
|
const nameCounts = {};
|
||||||
trackedNames.forEach(meta => {
|
trackedNames.forEach(meta => {
|
||||||
|
|||||||
82
js/render.js
82
js/render.js
@@ -243,6 +243,50 @@ globalThis.Renderer = function () {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify an array where the renderer will record rendered header depths.
|
||||||
|
* Items added to the array are of the form: `{name: "Header Name", depth: 1, type: "entries", source: "PHB"}`
|
||||||
|
* @param arr
|
||||||
|
* @param additionalProps Additional data props which should be tracked per-entry.
|
||||||
|
* @param additionalPropsInherited As per additionalProps, but if a parent entry has the prop, it should be passed
|
||||||
|
* to its children.
|
||||||
|
*/
|
||||||
|
this.setDepthTracker = function (arr, {additionalProps, additionalPropsInherited} = {}) {
|
||||||
|
this._depthTracker = arr;
|
||||||
|
this._depthTrackerAdditionalProps = additionalProps || [];
|
||||||
|
this._depthTrackerAdditionalPropsInherited = additionalPropsInherited || [];
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.withDepthTracker = function (arr, fn, {additionalProps, additionalPropsInherited} = {}) {
|
||||||
|
const depthTrackerPrev = this._depthTracker;
|
||||||
|
const depthTrackerAdditionalPropsPrev = this._depthTrackerAdditionalProps;
|
||||||
|
const depthTrackerAdditionalPropsInheritedPrev = this._depthTrackerAdditionalPropsInherited;
|
||||||
|
|
||||||
|
let out;
|
||||||
|
try {
|
||||||
|
this.setDepthTracker(
|
||||||
|
arr,
|
||||||
|
{
|
||||||
|
additionalProps,
|
||||||
|
additionalPropsInherited,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
out = fn({renderer: this});
|
||||||
|
} finally {
|
||||||
|
this.setDepthTracker(
|
||||||
|
depthTrackerPrev,
|
||||||
|
{
|
||||||
|
additionalProps: depthTrackerAdditionalPropsPrev,
|
||||||
|
additionalPropsInherited: depthTrackerAdditionalPropsInheritedPrev,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
// region Plugins
|
// region Plugins
|
||||||
this.addPlugin = function (pluginType, fnPlugin) {
|
this.addPlugin = function (pluginType, fnPlugin) {
|
||||||
MiscUtil.getOrSet(this._plugins, pluginType, []).push(fnPlugin);
|
MiscUtil.getOrSet(this._plugins, pluginType, []).push(fnPlugin);
|
||||||
@@ -309,21 +353,6 @@ globalThis.Renderer = function () {
|
|||||||
};
|
};
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify an array where the renderer will record rendered header depths.
|
|
||||||
* Items added to the array are of the form: `{name: "Header Name", depth: 1, type: "entries", source: "PHB"}`
|
|
||||||
* @param arr
|
|
||||||
* @param additionalProps Additional data props which should be tracked per-entry.
|
|
||||||
* @param additionalPropsInherited As per additionalProps, but if a parent entry has the prop, it should be passed
|
|
||||||
* to its children.
|
|
||||||
*/
|
|
||||||
this.setDepthTracker = function (arr, {additionalProps, additionalPropsInherited} = {}) {
|
|
||||||
this._depthTracker = arr;
|
|
||||||
this._depthTrackerAdditionalProps = additionalProps || [];
|
|
||||||
this._depthTrackerAdditionalPropsInherited = additionalPropsInherited || [];
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.getLineBreak = function () { return "<br>"; };
|
this.getLineBreak = function () { return "<br>"; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1431,19 +1460,26 @@ globalThis.Renderer = function () {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this._renderStatblock = function (entry, textStack, meta, options) {
|
this._renderStatblock = function (entry, textStack, meta, options) {
|
||||||
this._renderPrefix(entry, textStack, meta, options);
|
|
||||||
|
|
||||||
const page = entry.prop || Renderer.tag.getPage(entry.tag);
|
const page = entry.prop || Renderer.tag.getPage(entry.tag);
|
||||||
const source = Parser.getTagSource(entry.tag, entry.source);
|
const source = Parser.getTagSource(entry.tag, entry.source);
|
||||||
const hash = entry.hash || (UrlUtil.URL_TO_HASH_BUILDER[page] ? UrlUtil.URL_TO_HASH_BUILDER[page]({...entry, name: entry.name, source}) : null);
|
const hash = entry.hash || (UrlUtil.URL_TO_HASH_BUILDER[page] ? UrlUtil.URL_TO_HASH_BUILDER[page]({...entry, name: entry.name, source}) : null);
|
||||||
|
const tag = entry.tag || Parser.getPropTag(entry.prop);
|
||||||
|
|
||||||
const asTag = `{@${entry.tag} ${entry.name}|${source}${entry.displayName ? `|${entry.displayName}` : ""}}`;
|
const asTag = `{@${tag} ${entry.name}|${source}${entry.displayName ? `|${entry.displayName}` : ""}}`;
|
||||||
|
|
||||||
|
const fromPlugins = this._applyPlugins_useFirst(
|
||||||
|
"statblock_render",
|
||||||
|
{textStack, meta, options},
|
||||||
|
{input: {entry, page, source, hash, tag, asTag}},
|
||||||
|
);
|
||||||
|
if (fromPlugins) return void (textStack[0] += fromPlugins);
|
||||||
|
|
||||||
if (!page || !source || !hash) {
|
if (!page || !source || !hash) {
|
||||||
|
this._renderPrefix(entry, textStack, meta, options);
|
||||||
this._renderDataHeader(textStack, entry.name, entry.style);
|
this._renderDataHeader(textStack, entry.name, entry.style);
|
||||||
textStack[0] += `<tr>
|
textStack[0] += `<tr>
|
||||||
<td colspan="6">
|
<td colspan="6">
|
||||||
<i class="text-danger">Cannot load ${entry.tag ? `"${asTag}"` : entry.displayName || entry.name}! An unknown tag/prop, source, or hash was provided.</i>
|
<i class="text-danger">Cannot load ${tag ? `"${asTag}"` : entry.displayName || entry.name}! An unknown tag/prop, source, or hash was provided.</i>
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
this._renderDataFooter(textStack);
|
this._renderDataFooter(textStack);
|
||||||
@@ -1452,10 +1488,11 @@ globalThis.Renderer = function () {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._renderPrefix(entry, textStack, meta, options);
|
||||||
this._renderDataHeader(textStack, entry.displayName || entry.name, entry.style, {isCollapsed: entry.collapsed});
|
this._renderDataHeader(textStack, entry.displayName || entry.name, entry.style, {isCollapsed: entry.collapsed});
|
||||||
textStack[0] += `<tr>
|
textStack[0] += `<tr>
|
||||||
<td colspan="6" data-rd-tag="${(entry.tag || "").qq()}" data-rd-page="${(page || "").qq()}" data-rd-source="${(source || "").qq()}" data-rd-hash="${(hash || "").qq()}" data-rd-name="${(entry.name || "").qq()}" data-rd-display-name="${(entry.displayName || "").qq()}" data-rd-style="${(entry.style || "").qq()}">
|
<td colspan="6" data-rd-tag="${(tag || "").qq()}" data-rd-page="${(page || "").qq()}" data-rd-source="${(source || "").qq()}" data-rd-hash="${(hash || "").qq()}" data-rd-name="${(entry.name || "").qq()}" data-rd-display-name="${(entry.displayName || "").qq()}" data-rd-style="${(entry.style || "").qq()}">
|
||||||
<i>Loading ${entry.tag ? `${Renderer.get().render(asTag)}` : entry.displayName || entry.name}...</i>
|
<i>Loading ${tag ? `${Renderer.get().render(asTag)}` : entry.displayName || entry.name}...</i>
|
||||||
<style onload="Renderer.events.handleLoad_inlineStatblock(this)"></style>
|
<style onload="Renderer.events.handleLoad_inlineStatblock(this)"></style>
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
@@ -10494,7 +10531,7 @@ Renderer.recipe = class {
|
|||||||
? `{@b {@style Makes|small-caps}} ${ent._scaleFactor ? `${ent._scaleFactor}× ` : ""}${ent.makes}`
|
? `{@b {@style Makes|small-caps}} ${ent._scaleFactor ? `${ent._scaleFactor}× ` : ""}${ent.makes}`
|
||||||
: null,
|
: null,
|
||||||
entryServes: ent.serves
|
entryServes: ent.serves
|
||||||
? `{@b {@style Serves|small-caps}} ${ent.serves.min ?? ent.serves.exact}${ent.serves.min != null ? " to " : ""}${ent.serves.max ?? ""}`
|
? `{@b {@style Serves|small-caps}} ${ent.serves.min ?? ent.serves.exact}${ent.serves.min != null ? " to " : ""}${ent.serves.max ?? ""}${ent.serves.note ? ` ${ent.serves.note}` : ""}`
|
||||||
: null,
|
: null,
|
||||||
entryMetasTime: Renderer.recipe._getEntryMetasTime(ent),
|
entryMetasTime: Renderer.recipe._getEntryMetasTime(ent),
|
||||||
entryIngredients: {entries: ent._fullIngredients},
|
entryIngredients: {entries: ent._fullIngredients},
|
||||||
@@ -10680,6 +10717,7 @@ Renderer.recipe = class {
|
|||||||
"tablespoon",
|
"tablespoon",
|
||||||
"teaspoon",
|
"teaspoon",
|
||||||
"wedge",
|
"wedge",
|
||||||
|
"fist",
|
||||||
];
|
];
|
||||||
static _UNITS_SINGLE_TO_PLURAL_ES = [
|
static _UNITS_SINGLE_TO_PLURAL_ES = [
|
||||||
"dash",
|
"dash",
|
||||||
|
|||||||
@@ -113,9 +113,11 @@ export class BrewUtil2Base {
|
|||||||
|
|
||||||
isReloadRequired () { return this._isDirty; }
|
isReloadRequired () { return this._isDirty; }
|
||||||
|
|
||||||
doLocationReload () {
|
doLocationReload ({isRetainHash = false} = {}) {
|
||||||
|
if (!isRetainHash) {
|
||||||
if (typeof Hist !== "undefined") Hist.doPreLocationReload();
|
if (typeof Hist !== "undefined") Hist.doPreLocationReload();
|
||||||
else window.location.hash = "";
|
else window.location.hash = "";
|
||||||
|
}
|
||||||
|
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
@@ -513,6 +515,8 @@ export class BrewUtil2Base {
|
|||||||
pLoadPropIndex (urlRoot) { throw new Error("Unimplemented!"); }
|
pLoadPropIndex (urlRoot) { throw new Error("Unimplemented!"); }
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
pLoadMetaIndex (urlRoot) { throw new Error("Unimplemented!"); }
|
pLoadMetaIndex (urlRoot) { throw new Error("Unimplemented!"); }
|
||||||
|
/** @abstract */
|
||||||
|
pLoadAdventureBookIdsIndex (urlRoot) { throw new Error("Unimplemented!"); }
|
||||||
|
|
||||||
async pGetCombinedIndexes () {
|
async pGetCombinedIndexes () {
|
||||||
const urlRoot = await this.pGetCustomUrl();
|
const urlRoot = await this.pGetCustomUrl();
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ export class BrewUtil2_ extends BrewUtil2Base {
|
|||||||
|
|
||||||
pLoadMetaIndex (urlRoot) { return DataUtil.brew.pLoadMetaIndex(urlRoot); }
|
pLoadMetaIndex (urlRoot) { return DataUtil.brew.pLoadMetaIndex(urlRoot); }
|
||||||
|
|
||||||
|
pLoadAdventureBookIdsIndex (urlRoot) { return DataUtil.brew.pLoadAdventureBookIdsIndex(urlRoot); }
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
// region Editable
|
// region Editable
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ export class PrereleaseUtil_ extends BrewUtil2Base {
|
|||||||
|
|
||||||
pLoadMetaIndex (urlRoot) { return DataUtil.prerelease.pLoadMetaIndex(urlRoot); }
|
pLoadMetaIndex (urlRoot) { return DataUtil.prerelease.pLoadMetaIndex(urlRoot); }
|
||||||
|
|
||||||
|
pLoadAdventureBookIdsIndex (urlRoot) { return DataUtil.prerelease.pLoadAdventureBookIdsIndex(urlRoot); }
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
// region Editable
|
// region Editable
|
||||||
|
|||||||
@@ -1987,7 +1987,7 @@ class DataLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async pCacheAndGetHash (page, hash, opts) {
|
static async pCacheAndGetHash (page, hash, opts) {
|
||||||
const {source} = UrlUtil.autoDecodeHash(hash, {page});
|
const {source} = await UrlUtil.pAutoDecodeHash(hash, {page});
|
||||||
if (!source) {
|
if (!source) {
|
||||||
if (opts.isRequired) throw new Error(`Could not find entity for page "${page}" with hash "${hash}"`);
|
if (opts.isRequired) throw new Error(`Could not find entity for page "${page}" with hash "${hash}"`);
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1907,6 +1907,8 @@ PropOrder._VARIANTRULE = [
|
|||||||
|
|
||||||
"type",
|
"type",
|
||||||
"entries",
|
"entries",
|
||||||
|
|
||||||
|
"foundryImg",
|
||||||
];
|
];
|
||||||
PropOrder._RACE_SUBRACE = [
|
PropOrder._RACE_SUBRACE = [
|
||||||
"page",
|
"page",
|
||||||
|
|||||||
@@ -965,7 +965,7 @@ class ListUiUtil {
|
|||||||
let elePreviewWrp;
|
let elePreviewWrp;
|
||||||
if (item.ele.children.length === 1) {
|
if (item.ele.children.length === 1) {
|
||||||
elePreviewWrp = e_({
|
elePreviewWrp = e_({
|
||||||
ag: "div",
|
tag: "div",
|
||||||
clazz: "ve-hidden ve-flex",
|
clazz: "ve-hidden ve-flex",
|
||||||
children: [
|
children: [
|
||||||
e_({tag: "div", clazz: "ve-col-0-5"}),
|
e_({tag: "div", clazz: "ve-col-0-5"}),
|
||||||
|
|||||||
71
js/utils.js
71
js/utils.js
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// in deployment, `IS_DEPLOYED = "<version number>";` should be set below.
|
// in deployment, `IS_DEPLOYED = "<version number>";` should be set below.
|
||||||
globalThis.IS_DEPLOYED = undefined;
|
globalThis.IS_DEPLOYED = undefined;
|
||||||
globalThis.VERSION_NUMBER = /* 5ETOOLS_VERSION__OPEN */"1.209.1"/* 5ETOOLS_VERSION__CLOSE */;
|
globalThis.VERSION_NUMBER = /* 5ETOOLS_VERSION__OPEN */"1.209.2"/* 5ETOOLS_VERSION__CLOSE */;
|
||||||
globalThis.DEPLOYED_IMG_ROOT = undefined;
|
globalThis.DEPLOYED_IMG_ROOT = undefined;
|
||||||
// for the roll20 script to set
|
// for the roll20 script to set
|
||||||
globalThis.IS_VTT = false;
|
globalThis.IS_VTT = false;
|
||||||
@@ -2812,7 +2812,24 @@ globalThis.UrlUtil = {
|
|||||||
return hash.split(HASH_LIST_SEP).map(it => decodeURIComponent(it));
|
return hash.split(HASH_LIST_SEP).map(it => decodeURIComponent(it));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param hash
|
||||||
|
* @param {?string} page
|
||||||
|
*/
|
||||||
|
async pAutoDecodeHash (hash, {page = null} = {}) {
|
||||||
|
page ||= UrlUtil.getCurrentPage();
|
||||||
|
|
||||||
|
if ([UrlUtil.PG_ADVENTURE, UrlUtil.PG_BOOK].includes(page)) return UrlUtil._pAutoDecodeHashAdventureBookHash(hash, {page});
|
||||||
|
return UrlUtil.autoDecodeHash(hash, {page});
|
||||||
|
},
|
||||||
|
|
||||||
// TODO(Future) expand
|
// TODO(Future) expand
|
||||||
|
/**
|
||||||
|
* @param hash
|
||||||
|
* @param {?string} page
|
||||||
|
*/
|
||||||
autoDecodeHash (hash, {page = null} = {}) {
|
autoDecodeHash (hash, {page = null} = {}) {
|
||||||
page ||= UrlUtil.getCurrentPage();
|
page ||= UrlUtil.getCurrentPage();
|
||||||
const parts = UrlUtil.decodeHash(hash.toLowerCase().trim());
|
const parts = UrlUtil.decodeHash(hash.toLowerCase().trim());
|
||||||
@@ -2822,10 +2839,57 @@ globalThis.UrlUtil = {
|
|||||||
return {name, pantheon, source};
|
return {name, pantheon, source};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(Future) this is broken for docs where the id != the source
|
||||||
|
// consider indexing
|
||||||
|
// + homebrew
|
||||||
|
if (page === UrlUtil.PG_ADVENTURE || page === UrlUtil.PG_BOOK) {
|
||||||
|
const [source] = parts;
|
||||||
|
return {source};
|
||||||
|
}
|
||||||
|
|
||||||
const [name, source] = parts;
|
const [name, source] = parts;
|
||||||
return {name, source};
|
return {name, source};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param hash
|
||||||
|
* @param {?string} page
|
||||||
|
*/
|
||||||
|
async _pAutoDecodeHashAdventureBookHash (hash, {page = null} = {}) {
|
||||||
|
page ||= UrlUtil.getCurrentPage();
|
||||||
|
const parts = UrlUtil.decodeHash(hash.toLowerCase().trim());
|
||||||
|
|
||||||
|
if (![UrlUtil.PG_ADVENTURE, UrlUtil.PG_BOOK].includes(page)) throw new Error(`Unhandled page "${page}"!`);
|
||||||
|
|
||||||
|
const [id] = parts;
|
||||||
|
|
||||||
|
for (const {prop, contentsUrl} of [
|
||||||
|
{
|
||||||
|
prop: "adventure",
|
||||||
|
contentsUrl: `${Renderer.get().baseUrl}data/adventures.json`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "book",
|
||||||
|
contentsUrl: `${Renderer.get().baseUrl}data/books.json`,
|
||||||
|
},
|
||||||
|
]) {
|
||||||
|
const contents = await DataUtil.loadJSON(contentsUrl);
|
||||||
|
|
||||||
|
const ent = contents[prop].find(it => it.id.toLowerCase() === id);
|
||||||
|
if (ent) return {name: ent.name, source: ent.source, id: ent.id};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const brewUtil of [PrereleaseUtil, BrewUtil2]) {
|
||||||
|
const urlRoot = await brewUtil.pGetCustomUrl();
|
||||||
|
const idsIndex = await brewUtil.pLoadAdventureBookIdsIndex(urlRoot);
|
||||||
|
if (idsIndex[id]) return idsIndex[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
getSluggedHash (hash) {
|
getSluggedHash (hash) {
|
||||||
return Parser.stringToSlug(decodeURIComponent(hash)).replace(/_/g, "-");
|
return Parser.stringToSlug(decodeURIComponent(hash)).replace(/_/g, "-");
|
||||||
},
|
},
|
||||||
@@ -3758,6 +3822,11 @@ class _DataUtilBrewHelper {
|
|||||||
return DataUtil.loadJSON(`${urlRoot}_generated/index-sources.json`);
|
return DataUtil.loadJSON(`${urlRoot}_generated/index-sources.json`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async pLoadAdventureBookIdsIndex (urlRoot) {
|
||||||
|
urlRoot = this._getCleanUrlRoot(urlRoot);
|
||||||
|
return DataUtil.loadJSON(`${urlRoot}_generated/index-adventure-book-ids.json`);
|
||||||
|
}
|
||||||
|
|
||||||
getFileUrl (path, urlRoot) {
|
getFileUrl (path, urlRoot) {
|
||||||
urlRoot = this._getCleanUrlRoot(urlRoot);
|
urlRoot = this._getCleanUrlRoot(urlRoot);
|
||||||
return `${urlRoot}${path}`;
|
return `${urlRoot}${path}`;
|
||||||
|
|||||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "5etools",
|
"name": "5etools",
|
||||||
"version": "1.209.1",
|
"version": "1.209.2",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "5etools",
|
"name": "5etools",
|
||||||
"version": "1.209.1",
|
"version": "1.209.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"5etools-utils": "^0.12.19",
|
"5etools-utils": "^0.12.20",
|
||||||
"ajv": "^8.12.0",
|
"ajv": "^8.12.0",
|
||||||
"ajv-formats": "^2.1.1",
|
"ajv-formats": "^2.1.1",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
@@ -3926,9 +3926,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/5etools-utils": {
|
"node_modules/5etools-utils": {
|
||||||
"version": "0.12.19",
|
"version": "0.12.20",
|
||||||
"resolved": "https://registry.npmjs.org/5etools-utils/-/5etools-utils-0.12.19.tgz",
|
"resolved": "https://registry.npmjs.org/5etools-utils/-/5etools-utils-0.12.20.tgz",
|
||||||
"integrity": "sha512-0VyiX585H93CxKshYX7sUq0mqTjmBUQSe0AgeCpD9MqCq3wTtQCs1nIFBxjb8zQR1DqNDUc+JiMLfmEe/XHGug==",
|
"integrity": "sha512-PA5ZMMId+jvoUJvr19eNOq3skfTw2h57iHR4hO3YU2YDKOojtLB35vbasayZ7zJmoelDIqyAk/LF4j/lDpTZrg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^8.12.0",
|
"ajv": "^8.12.0",
|
||||||
@@ -14589,9 +14589,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"5etools-utils": {
|
"5etools-utils": {
|
||||||
"version": "0.12.19",
|
"version": "0.12.20",
|
||||||
"resolved": "https://registry.npmjs.org/5etools-utils/-/5etools-utils-0.12.19.tgz",
|
"resolved": "https://registry.npmjs.org/5etools-utils/-/5etools-utils-0.12.20.tgz",
|
||||||
"integrity": "sha512-0VyiX585H93CxKshYX7sUq0mqTjmBUQSe0AgeCpD9MqCq3wTtQCs1nIFBxjb8zQR1DqNDUc+JiMLfmEe/XHGug==",
|
"integrity": "sha512-PA5ZMMId+jvoUJvr19eNOq3skfTw2h57iHR4hO3YU2YDKOojtLB35vbasayZ7zJmoelDIqyAk/LF4j/lDpTZrg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ajv": "^8.12.0",
|
"ajv": "^8.12.0",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "5etools",
|
"name": "5etools",
|
||||||
"author": "TheGiddyLimit",
|
"author": "TheGiddyLimit",
|
||||||
"version": "1.209.1",
|
"version": "1.209.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"description": "A site dedicated to making playing games with your friends as easy as possible.",
|
"description": "A site dedicated to making playing games with your friends as easy as possible.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
"url": "git+https://github.com/5etools-mirror-2/5etools-mirror-2.github.io.git"
|
"url": "git+https://github.com/5etools-mirror-2/5etools-mirror-2.github.io.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"5etools-utils": "^0.12.19",
|
"5etools-utils": "^0.12.20",
|
||||||
"ajv": "^8.12.0",
|
"ajv": "^8.12.0",
|
||||||
"ajv-formats": "^2.1.1",
|
"ajv-formats": "^2.1.1",
|
||||||
"commander": "^12.0.0",
|
"commander": "^12.0.0",
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,6 +2,7 @@ import fs from "fs";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import "../js/parser.js";
|
import "../js/parser.js";
|
||||||
import "../js/utils.js";
|
import "../js/utils.js";
|
||||||
|
import "../js/render.js";
|
||||||
import * as ut from "../node/util.js";
|
import * as ut from "../node/util.js";
|
||||||
import {listFiles} from "../node/util.js";
|
import {listFiles} from "../node/util.js";
|
||||||
|
|
||||||
@@ -41,6 +42,8 @@ class _TestTokenImages {
|
|||||||
.forEach(file => {
|
.forEach(file => {
|
||||||
ut.readJson(`./data/bestiary/${file}`).monster
|
ut.readJson(`./data/bestiary/${file}`).monster
|
||||||
.forEach(m => {
|
.forEach(m => {
|
||||||
|
m.__prop = "monster";
|
||||||
|
|
||||||
const implicitTokenPath = `${this._PATH_BASE}/${m.source}/${Parser.nameToTokenName(m.name)}.${this._EXT}`;
|
const implicitTokenPath = `${this._PATH_BASE}/${m.source}/${Parser.nameToTokenName(m.name)}.${this._EXT}`;
|
||||||
|
|
||||||
if (m.hasToken) this._expectedFromHashToken[implicitTokenPath] = true;
|
if (m.hasToken) this._expectedFromHashToken[implicitTokenPath] = true;
|
||||||
@@ -59,6 +62,14 @@ class _TestTokenImages {
|
|||||||
.forEach(entry => this._expected.add(`${this._PATH_BASE}/${entry.token.source}/${Parser.nameToTokenName(entry.token.name)}.${this._EXT}`));
|
.forEach(entry => this._expected.add(`${this._PATH_BASE}/${entry.token.source}/${Parser.nameToTokenName(entry.token.name)}.${this._EXT}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add tokens specified as part of versions
|
||||||
|
const versions = DataUtil.proxy.getVersions(m.__prop, m, {isExternalApplicationIdentityOnly: true});
|
||||||
|
versions
|
||||||
|
.forEach(mVer => {
|
||||||
|
if (!Renderer.monster.hasToken(mVer)) return;
|
||||||
|
this._expected.add(`${this._PATH_BASE}/${mVer.source}/${Parser.nameToTokenName(mVer.name)}.${this._EXT}`);
|
||||||
|
});
|
||||||
|
|
||||||
// add tokens specified as alt art
|
// add tokens specified as alt art
|
||||||
if (m.altArt) {
|
if (m.altArt) {
|
||||||
m.altArt
|
m.altArt
|
||||||
|
|||||||
Reference in New Issue
Block a user