diff --git a/data/ascension_overrides.json b/data/ascension_overrides.json new file mode 100644 index 0000000..fb18404 --- /dev/null +++ b/data/ascension_overrides.json @@ -0,0 +1,12 @@ +{ + "_comment": "Ascension-specific corrections to the upstream kg / AtlasLoot data. Each entry overrides where an enemy/extra is rendered. Match by tile_key + name (case-insensitive substring). pos is in kg pixel space (z=4 stitched image, 6144x4096). kg_floor_id picks the floor (omit if the dungeon is single-floor).", + "overrides": [ + { + "tile_key": "stratholme", + "name": "Magistrate Barthilas", + "kg_floor_id": 235, + "pos": [3498, 3300], + "note": "Ascension moved Barthilas to the southern courtyard of the Undead Side" + } + ] +} diff --git a/data/atlasloot_extras.json b/data/atlasloot_extras.json index 3a8879e..4cc6d63 100644 --- a/data/atlasloot_extras.json +++ b/data/atlasloot_extras.json @@ -1,164 +1,249 @@ { "_comment": "Supplemental rare bosses + interactives lifted from AtlasLootAscension and transformed into keystone.guru pixel space. Generated by tools/atlasloot_extras.py.", "transforms": { - "RagefireChasm\u2192ragefire_chasm": [ + "RagefireChasm\u2192ragefire_chasm@floor216": [ 73.72443668498734, -643.6866761504352, 42.96310607515248, -122.87047634576129 ], - "TheDeadmines\u2192deadmines": [ - 38.86529733570145, - 795.3768071048042, - 42.675714797527434, - -4.190671073545933 + "TheDeadmines\u2192deadmines@floor196": [ + 66.26591999999972, + -234.06111999998757, + 44.597466666666755, + -303.3821333333399 ], - "WailingCaverns\u2192wailing_caverns": [ + "TheDeadmines\u2192deadmines@floor197": [ + 76.22242622951025, + -1563.346570491929, + 61.14531050583661, + -717.1209612451378 + ], + "WailingCaverns\u2192wailing_caverns@floor240": [ 81.43623828914878, -747.3569080929979, 34.84088492074497, 115.17092826840326 ], - "ShadowfangKeep\u2192shadowfang_keep": [ - 61.65109512912707, - 44.20626976136464, - 40.982516838487975, - -50.47485979381463 + "ShadowfangKeep\u2192shadowfang_keep@floor227": [ + 61.02459999999999, + 65.04460000000063, + 46.426533333333886, + -409.4137333333706 ], - "TheStockade\u2192the_stockade": [ + "ShadowfangKeep\u2192shadowfang_keep@floor228": [ + 62.30417777777773, + -50.73653333333141, + 43.851689795918375, + -132.65531428571467 + ], + "ShadowfangKeep\u2192shadowfang_keep@floor232": [ + 29.689000000000306, + 1920.5397999999814, + 34.11870476190476, + 138.36030476190467 + ], + "TheStockade\u2192the_stockade@floor236": [ 59.842452519084006, 61.74031633587583, 39.897596145904984, 21.673417205782425 ], - "Gnomeregan\u2192gnomeregan": [ - 111.07253811659204, - -1434.4782521973132, - 38.1758651250788, - 220.98302089552416 + "Gnomeregan\u2192gnomeregan@floor205": [ + 128.41971199999992, + -1675.7119999999968, + 54.99048421052646, + -1017.2874105263245 ], - "RazorfenKraul\u2192razorfen_kraul": [ + "Gnomeregan\u2192gnomeregan@floor207": [ + -7.172800000000279, + 2156.0112000000086, + 81.23751111111113, + -1217.8997333333346 + ], + "RazorfenKraul\u2192razorfen_kraul@floor218": [ 60.513804000979846, 88.27979514983198, 43.452935250680056, -74.45083218033032 ], - "RazorfenDowns\u2192razorfen_downs": [ + "RazorfenDowns\u2192razorfen_downs@floor217": [ 63.04291758924619, -290.16402952444923, 41.07698629536258, 102.3108550816687 ], - "ScarletMonastery\u2192scarlet_monastery_cathedral": [ + "ScarletMonastery\u2192scarlet_monastery_cathedral@floor220": [ 50.76749473684181, 557.1932350877345, 32.20170256410254, 167.73567179487236 ], - "ScarletMonastery\u2192scarlet_monastery_graveyard": [ + "ScarletMonastery\u2192scarlet_monastery_graveyard@floor221": [ 60.84316666666665, 37.29200000000128, 23.45159999999305, 995.9040000004034 ], - "ScarletMonastery\u2192scarlet_monastery_library": [ + "ScarletMonastery\u2192scarlet_monastery_library@floor222": [ 59.125464150943436, 212.3352754716957, 74.09100000000035, -2662.1046000000283 ], - "Uldaman\u2192uldaman": [ - 63.19322527727629, - -86.87969584730672, - 41.52615397709141, - -41.35400744707431 + "Uldaman\u2192uldaman@floor238": [ + 62.88415904279804, + -78.21449940175133, + 41.43594680607743, + -28.07042326417234 ], - "ZulFarrak\u2192zul_farrak": [ + "ZulFarrak\u2192zul_farrak@floor241": [ 71.87339593345645, -512.6565965671986, 39.668194090909076, -1.3930740909086776 ], - "Maraudon\u2192maraudon": [ - 61.77912121471568, - 25.543185142141738, - 42.19282336665975, - -65.8431254967295 + "Maraudon\u2192maraudon@floor214": [ + 66.7837434402333, + -211.68715102041006, + 41.3733804475854, + -96.69095123674924 ], - "BlackrockDepths\u2192blackrock_depths": [ - 63.390884474140194, - -129.9214250730094, - 43.72115533672626, - -43.96230823056116 + "Maraudon\u2192maraudon@floor215": [ + 56.73022056074778, + 249.97455476635076, + 41.50276494730274, + 12.258980149063428 ], - "BlackrockSpire\u2192lower_blackrock_spire": [ - 70.31609043478278, - -550.6383026087042, - 47.429734477825605, - -521.5857562231853 + "BlackrockDepths\u2192blackrock_depths@floor194": [ + 63.63756840148695, + -162.67121375464484, + 40.4048188308329, + 8.987177030522435 ], - "BlackrockSpire\u2192upper_blackrock_spire": [ - 61.504197773872264, - -76.49282249560493, - 34.005210582010584, - 222.27234962962956 + "BlackrockDepths\u2192blackrock_depths@floor195": [ + 62.94900546673541, + -86.73139102630073, + 46.48759478082394, + -77.53748107315732 ], - "Stratholme\u2192stratholme": [ - 47.28673540151238, - 713.5643322963654, - 42.71814474125836, - -161.87918672865834 + "BlackrockSpire\u2192upper_blackrock_spire@floor251": [ + 61.70100000000002, + -56.735800000000836, + 37.522399999999834, + 88.06320000000551 ], - "Scholomance\u2192scholomance": [ - 68.16995676302486, - -376.1030967834516, - 46.6690874521118, - -292.56897919878884 + "BlackrockSpire\u2192upper_blackrock_spire@floor252": [ + 63.47862546689313, + -192.3194648556922, + 32.72667881548972, + 280.8202697038737 ], - "DireMaul\u2192dire_maul_north": [ + "Stratholme\u2192stratholme@floor234": [ + 41.10740482022913, + 953.3460469379711, + 45.46983390016457, + -394.0354483817887 + ], + "Stratholme\u2192stratholme@floor235": [ + 62.999233525796434, + -128.2447165580294, + 42.25970441767067, + -69.48502811244937 + ], + "Scholomance\u2192scholomance@floor225": [ + 67.03862919012546, + -301.39203984408016, + 44.58635943070333, + -260.60278192621263 + ], + "Scholomance\u2192scholomance@floor226": [ + 68.56349344262266, + -379.79195901637434, + 52.39632279411766, + -445.17640367647107 + ], + "DireMaul\u2192dire_maul_north@floor198": [ 63.69477659517125, -52.97349769615799, 40.323820514843405, -15.287907437179715 ], - "DireMaul\u2192dire_maul_east": [ - 23.186187151976394, - 2032.82655823259, - 72.13990548255808, - -968.0175378916643 + "DireMaul\u2192dire_maul_east@floor203": [ + 6.555779141104249, + 3087.766655214726, + 86.08977339901453, + -1322.4088512315175 ], - "DireMaul\u2192dire_maul_west": [ - 50.567135013423375, - 526.7297255113892, - 37.66845336733329, - 254.15845163333543 + "DireMaul\u2192dire_maul_west@floor199": [ + 11.51677611940289, + 1694.8836776119429, + 48.91311020408154, + -444.9409959183613 ], - "MoltenCore\u2192moltencore": [ + "DireMaul\u2192dire_maul_west@floor201": [ + 63.43969465648849, + -82.18605190839389, + 32.69369302325585, + 460.44843534883603 + ], + "MoltenCore\u2192moltencore@floor309": [ 63.802558332453295, -161.93769244746218, 46.40771496165673, -344.9887211648951 ], - "BlackwingLair\u2192blackwinglair": [ - 56.096746961325906, - 325.5217337016602, - 24.000187425480892, - 738.8363241595489 + "BlackwingLair\u2192blackwinglair@floor310": [ + -87.09831111111109, + 5766.327466666666, + -30.799717647058795, + 3012.748894117646 ], - "Naxxramas60\u2192naxxramas_classic": [ - 54.729314117996196, - 329.7412320416867, - 13.38947624976002, - 1066.3540111552927 + "BlackwingLair\u2192blackwinglair@floor312": [ + 44.53386938775538, + 829.3184653061107, + 49.16421052631577, + -498.62152982456064 + ], + "BlackwingLair\u2192blackwinglair@floor313": [ + 71.16791057401812, + -516.2994392749242, + 43.71123200000003, + -257.80390400000215 + ], + "Naxxramas60\u2192naxxramas_classic@floor138": [ + 63.58405165354333, + -131.6644535433079, + 41.1352763693271, + 1.9000788732382716 + ], + "Naxxramas60\u2192naxxramas_classic@floor139": [ + 66.4364096514745, + -225.34979660410923, + 35.50802017654478, + 110.69960756620367 + ], + "Naxxramas60\u2192naxxramas_classic@floor141": [ + 63.421989155693126, + -63.41635135553042, + 42.14327589424573, + -69.00678071539703 + ], + "Naxxramas60\u2192naxxramas_classic@floor143": [ + -61.489040000000095, + 5753.316880000005, + -40.52355555555556, + 3695.091377777778 ] }, "extras": { "deadmines": [ { "name": "Defias Gunpowder", - "x": 1572.7, - "y": 2343.0, + "x": 1091.3, + "y": 2149.5, "rare": false, + "kg_floor_id": 196, "source": "atlasloot" } ], @@ -168,52 +253,49 @@ "x": 3080.1, "y": 1961.7, "rare": false, + "kg_floor_id": 240, "source": "atlasloot" } ], "shadowfang_keep": [ { "name": "Investigator Fezzen Brasstacks (Love is in the Air)", - "x": 3373.4, - "y": 2654.4, + "x": 3523.7, + "y": 2390.2, "rare": false, + "kg_floor_id": 232, "source": "atlasloot" }, { "name": "Deathstalker Vincent", - "x": 3558.3, - "y": 2408.5, + "x": 3612.8, + "y": 2185.5, "rare": false, + "kg_floor_id": 232, "source": "atlasloot" }, { "name": "Apothecary Trio (Love is in the Air)", - "x": 2448.6, - "y": 2039.6, + "x": 2445.0, + "y": 1958.3, "rare": false, + "kg_floor_id": 227, "source": "atlasloot" }, { "name": "Fel Steed", - "x": 2202.0, - "y": 2326.5, + "x": 2200.9, + "y": 2283.3, "rare": false, + "kg_floor_id": 227, "source": "atlasloot" }, { "name": "Deathsworn Captain (Rare)", - "x": 3681.6, - "y": 2121.6, + "x": 3672.2, + "y": 1946.7, "rare": true, - "source": "atlasloot" - } - ], - "gnomeregan": [ - { - "name": "Clean Room", - "x": 5674.2, - "y": 2664.2, - "rare": false, + "kg_floor_id": 232, "source": "atlasloot" } ], @@ -223,6 +305,7 @@ "x": 4021.7, "y": 2011.3, "rare": false, + "kg_floor_id": 218, "source": "atlasloot" }, { @@ -230,6 +313,7 @@ "x": 753.9, "y": 1272.6, "rare": true, + "kg_floor_id": 218, "source": "atlasloot" } ], @@ -239,6 +323,7 @@ "x": 4212.5, "y": 2099.8, "rare": false, + "kg_floor_id": 220, "source": "atlasloot" }, { @@ -246,6 +331,7 @@ "x": 2384.8, "y": 2196.4, "rare": false, + "kg_floor_id": 220, "source": "atlasloot" }, { @@ -253,6 +339,7 @@ "x": 1775.6, "y": 1971.0, "rare": false, + "kg_floor_id": 220, "source": "atlasloot" }, { @@ -260,6 +347,7 @@ "x": 2080.2, "y": 2904.9, "rare": false, + "kg_floor_id": 220, "source": "atlasloot" }, { @@ -267,6 +355,7 @@ "x": 4770.9, "y": 2647.3, "rare": false, + "kg_floor_id": 220, "source": "atlasloot" }, { @@ -274,6 +363,7 @@ "x": 4567.8, "y": 522.0, "rare": false, + "kg_floor_id": 220, "source": "atlasloot" } ], @@ -283,6 +373,7 @@ "x": 1862.6, "y": 2989.3, "rare": false, + "kg_floor_id": 221, "source": "atlasloot" }, { @@ -290,6 +381,7 @@ "x": 5087.3, "y": 2801.7, "rare": false, + "kg_floor_id": 221, "source": "atlasloot" }, { @@ -297,6 +389,7 @@ "x": 4843.9, "y": 1253.9, "rare": false, + "kg_floor_id": 221, "source": "atlasloot" }, { @@ -304,6 +397,7 @@ "x": 3444.5, "y": 1605.6, "rare": false, + "kg_floor_id": 221, "source": "atlasloot" }, { @@ -311,6 +405,7 @@ "x": 3018.6, "y": 1676.0, "rare": false, + "kg_floor_id": 221, "source": "atlasloot" }, { @@ -318,6 +413,7 @@ "x": 2957.8, "y": 1394.6, "rare": false, + "kg_floor_id": 221, "source": "atlasloot" } ], @@ -327,6 +423,7 @@ "x": 4469.4, "y": 1783.4, "rare": false, + "kg_floor_id": 222, "source": "atlasloot" }, { @@ -334,29 +431,33 @@ "x": 1631.3, "y": 1487.0, "rare": false, + "kg_floor_id": 222, "source": "atlasloot" } ], "uldaman": [ { "name": "Remains of a Paladin", - "x": 3262.4, - "y": 2616.3, + "x": 3254.6, + "y": 2623.8, "rare": false, + "kg_floor_id": 238, "source": "atlasloot" }, { "name": "The Discs of Norgannon (Lower)", - "x": 2440.8, - "y": 332.4, + "x": 2437.2, + "y": 344.9, "rare": false, + "kg_floor_id": 238, "source": "atlasloot" }, { "name": "The Discs of Norgannon (Lower)", - "x": 3072.8, - "y": 1370.5, + "x": 3066.0, + "y": 1380.8, "rare": false, + "kg_floor_id": 238, "source": "atlasloot" } ], @@ -366,459 +467,393 @@ "x": 1284.2, "y": 712.6, "rare": false, + "kg_floor_id": 241, "source": "atlasloot" } ], "maraudon": [ { "name": "Veng ", - "x": 3732.3, - "y": 946.8, + "x": 3795.3, + "y": 896.3, "rare": false, + "kg_floor_id": 214, "source": "atlasloot" }, { "name": "Maraudos ", - "x": 3299.8, - "y": 3056.4, + "x": 3256.7, + "y": 3083.5, "rare": false, + "kg_floor_id": 215, "source": "atlasloot" } ], "blackrock_depths": [ { "name": "Kharan Mighthammer", - "x": 3166.4, - "y": 3541.2, + "x": 3146.5, + "y": 3322.2, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "Commander Gor'shak ", - "x": 3293.2, - "y": 3759.8, + "x": 3273.8, + "y": 3524.2, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "Marshal Windsor", - "x": 3229.8, - "y": 4065.8, + "x": 3210.1, + "y": 3807.0, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "Ring of Law", - "x": 3103.0, - "y": 2623.0, + "x": 3082.8, + "y": 2473.7, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "The Vault", - "x": 3673.5, - "y": 2841.6, + "x": 3655.6, + "y": 2675.7, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "Ring of Law", - "x": 3103.0, - "y": 3847.2, + "x": 3082.8, + "y": 3605.0, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "Shadowforge Lock", - "x": 2532.5, - "y": 3934.7, + "x": 2510.1, + "y": 3685.8, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "The Grim Guzzler", - "x": 3039.6, - "y": 2710.5, + "x": 3019.2, + "y": 2554.5, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "Summoner's Tomb", - "x": 3293.2, - "y": 1049.1, + "x": 3273.8, + "y": 1019.1, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "The Lyceum", - "x": 4117.3, - "y": 480.7, + "x": 4101.0, + "y": 493.8, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "The Black Forge", - "x": 3863.7, - "y": 1049.1, + "x": 3846.5, + "y": 1019.1, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" }, { "name": "Molten Core", - "x": 4180.7, - "y": 1530.0, - "rare": false, - "source": "atlasloot" - } - ], - "lower_blackrock_spire": [ - { - "name": "Mother Smolderweb", - "x": 3949.6, - "y": 2798.5, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Burning Felguard (Rare, Summon)", - "x": 2473.0, - "y": 2039.6, - "rare": true, - "source": "atlasloot" - }, - { - "name": "Vaelan (Upper)", - "x": 3105.8, - "y": 1423.0, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Warosh (Wanders)", - "x": 3738.6, - "y": 1517.9, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Bijou", - "x": 3879.3, - "y": 2134.5, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Roughshod Pike", - "x": 4160.5, - "y": 2229.3, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Spirestone Butcher (Rare)", - "x": 3035.5, - "y": 2229.3, - "rare": true, - "source": "atlasloot" - }, - { - "name": "Human Remains (Lower)", - "x": 2473.0, - "y": 2134.5, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Urok's Tribute Pile", - "x": 2683.9, - "y": 2087.0, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Halycon", - "x": 2121.4, - "y": 3509.9, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Pyroguard Emberseer", - "x": 1629.2, - "y": 759.0, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Solakar Flamewreath", - "x": 2191.7, - "y": 1328.2, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Goraluk Anvilcrack ", - "x": 1769.8, - "y": 759.0, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Warchief Rend Blackhand", - "x": 2894.9, - "y": 759.0, - "rare": false, - "source": "atlasloot" - }, - { - "name": "The Beast", - "x": 3949.6, - "y": 996.2, - "rare": false, - "source": "atlasloot" - }, - { - "name": "General Drakkisath", - "x": 1980.7, - "y": 1849.9, + "x": 4164.7, + "y": 1463.6, "rare": false, + "kg_floor_id": 194, "source": "atlasloot" } ], "upper_blackrock_spire": [ { "name": "War Master Voone", - "x": 3121.7, - "y": 2058.6, + "x": 3108.6, + "y": 2048.1, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Mother Smolderweb", - "x": 3859.8, - "y": 2602.6, + "x": 3870.3, + "y": 2571.7, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Burning Felguard (Rare, Summon)", - "x": 2568.2, - "y": 2058.6, + "x": 2537.3, + "y": 2048.1, "rare": true, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Shadow Hunter Vosh'gajin", - "x": 3367.7, - "y": 2602.6, + "x": 3362.5, + "y": 2571.7, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Vaelan (Upper)", - "x": 3121.7, - "y": 1616.5, + "x": 3151.7, + "y": 1626.5, "rare": false, + "kg_floor_id": 251, "source": "atlasloot" }, { "name": "Warosh (Wanders)", - "x": 3675.3, - "y": 1684.5, + "x": 3679.9, + "y": 1688.1, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Highlord Omokk", - "x": 2322.2, - "y": 2262.6, + "x": 2283.3, + "y": 2244.4, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Urok's Tribute Pile", - "x": 2752.7, - "y": 2092.6, + "x": 2727.7, + "y": 2080.8, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Bannok Grimaxe (Rare)", - "x": 2752.7, - "y": 2432.6, + "x": 2727.7, + "y": 2408.1, "rare": true, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Quartermaster Zigris ", - "x": 3306.2, - "y": 3112.7, + "x": 3299.0, + "y": 3062.6, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Darkstone Tablet", - "x": 1891.6, - "y": 1650.5, + "x": 1917.7, + "y": 1664.0, "rare": false, + "kg_floor_id": 251, "source": "atlasloot" }, { "name": "Overlord Wyrmthalak", - "x": 3490.8, - "y": 2398.6, + "x": 3489.4, + "y": 2375.3, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Jed Runewatcher (Rare)", - "x": 2260.7, - "y": 1038.4, + "x": 2287.9, + "y": 988.6, "rare": true, + "kg_floor_id": 251, "source": "atlasloot" }, { "name": "Goraluk Anvilcrack ", - "x": 1953.1, - "y": 1140.4, + "x": 1979.4, + "y": 1101.2, "rare": false, + "kg_floor_id": 251, "source": "atlasloot" }, { "name": "Awbee", - "x": 2937.2, - "y": 1446.5, + "x": 2918.1, + "y": 1459.0, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" }, { "name": "Blackwing Lair", - "x": 3306.2, - "y": 970.4, + "x": 3299.0, + "y": 1000.8, "rare": false, + "kg_floor_id": 252, "source": "atlasloot" } ], "stratholme": [ { "name": "Crusaders' Square Postbox", - "x": 2415.9, - "y": 1333.3, + "x": 2433.2, + "y": 1197.4, "rare": false, + "kg_floor_id": 234, "source": "atlasloot" }, { "name": "Market Row Postbox", - "x": 3976.3, - "y": 1034.2, + "x": 4218.7, + "y": 1113.8, "rare": false, + "kg_floor_id": 235, "source": "atlasloot" }, { "name": "Festival Lane Postbox", - "x": 4496.5, - "y": 1076.9, + "x": 4241.9, + "y": 924.6, "rare": false, + "kg_floor_id": 234, "source": "atlasloot" }, { "name": "King's Square Postbox", - "x": 3739.9, - "y": 2102.2, + "x": 3903.7, + "y": 2170.3, "rare": false, + "kg_floor_id": 235, "source": "atlasloot" }, { "name": "Fras Siabi's Postbox", - "x": 3314.3, - "y": 2785.7, + "x": 3336.7, + "y": 2846.4, "rare": false, + "kg_floor_id": 235, "source": "atlasloot" }, { "name": "Atiesh (Summon)", - "x": 4780.2, - "y": 1461.4, + "x": 4488.6, + "y": 1333.8, "rare": false, + "kg_floor_id": 234, "source": "atlasloot" }, { "name": "Elder Farwhisper (Lunar Festival)", - "x": 4449.2, - "y": 564.3, + "x": 4200.8, + "y": 379.0, "rare": false, + "kg_floor_id": 234, "source": "atlasloot" }, { "name": "Malor the Zealous", - "x": 2132.2, - "y": 1632.3, + "x": 2186.6, + "y": 1515.7, "rare": false, + "kg_floor_id": 234, "source": "atlasloot" }, { "name": "Crimson Hammersmith (Summon)", - "x": 1328.3, - "y": 1888.6, + "x": 1487.7, + "y": 1788.5, "rare": false, + "kg_floor_id": 234, "source": "atlasloot" }, { "name": "Cannon Master Willey", - "x": 950.0, - "y": 2016.7, + "x": 1158.9, + "y": 1924.9, "rare": false, + "kg_floor_id": 234, "source": "atlasloot" }, { "name": "Archivist Galford", - "x": 2037.6, - "y": 2999.3, + "x": 2104.4, + "y": 2970.7, "rare": false, + "kg_floor_id": 234, "source": "atlasloot" }, { "name": "Elders' Square Postbox", - "x": 3881.8, - "y": 3084.7, + "x": 4092.7, + "y": 3142.3, "rare": false, + "kg_floor_id": 235, "source": "atlasloot" }, { "name": "Aurius", - "x": 3929.1, - "y": 2999.3, + "x": 4155.7, + "y": 3057.7, "rare": false, + "kg_floor_id": 235, "source": "atlasloot" }, { "name": "Stonespine (Rare)", - "x": 4023.6, - "y": 2016.7, + "x": 4281.7, + "y": 2085.8, "rare": true, + "kg_floor_id": 235, "source": "atlasloot" } ], "scholomance": [ { "name": "Blood Steward of Kirtonos", - "x": 5213.8, - "y": 1854.2, + "x": 5195.8, + "y": 1790.4, "rare": false, + "kg_floor_id": 225, "source": "atlasloot" }, { "name": "The Deed to Tarren Mill", - "x": 1737.2, - "y": 2367.6, + "x": 1776.8, + "y": 2280.8, "rare": false, + "kg_floor_id": 225, "source": "atlasloot" }, { "name": "Torch Lever", - "x": 2964.2, - "y": 2274.2, + "x": 2983.5, + "y": 2191.6, "rare": false, + "kg_floor_id": 225, "source": "atlasloot" } ], @@ -828,6 +863,7 @@ "x": 1220.9, "y": 3130.0, "rare": false, + "kg_floor_id": 198, "source": "atlasloot" }, { @@ -835,6 +871,7 @@ "x": 2074.4, "y": 2142.0, "rare": false, + "kg_floor_id": 198, "source": "atlasloot" }, { @@ -842,6 +879,7 @@ "x": 1985.3, "y": 1811.4, "rare": false, + "kg_floor_id": 198, "source": "atlasloot" }, { @@ -849,6 +887,7 @@ "x": 2189.1, "y": 2327.5, "rare": false, + "kg_floor_id": 198, "source": "atlasloot" }, { @@ -856,6 +895,7 @@ "x": 896.1, "y": 2230.7, "rare": false, + "kg_floor_id": 198, "source": "atlasloot" }, { @@ -863,6 +903,7 @@ "x": 3857.9, "y": 593.6, "rare": false, + "kg_floor_id": 198, "source": "atlasloot" }, { @@ -870,6 +911,7 @@ "x": 2558.5, "y": 1968.6, "rare": false, + "kg_floor_id": 198, "source": "atlasloot" }, { @@ -877,6 +919,7 @@ "x": 2781.4, "y": 1863.8, "rare": false, + "kg_floor_id": 198, "source": "atlasloot" }, { @@ -884,217 +927,231 @@ "x": 3596.7, "y": 1150.1, "rare": false, + "kg_floor_id": 198, "source": "atlasloot" } ], "dire_maul_east": [ - { - "name": "Stomper Kreeg ", - "x": 3447.2, - "y": 3937.5, - "rare": false, - "source": "atlasloot" - }, { "name": "Guard Slip'kik", - "x": 2647.3, - "y": 3201.7, + "x": 3261.5, + "y": 3653.6, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Captain Kromcrush", - "x": 2770.1, - "y": 2740.0, + "x": 3296.2, + "y": 3102.6, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "King Gordok", - "x": 2774.8, - "y": 1030.3, + "x": 3297.6, + "y": 1062.3, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Pylons", - "x": 3655.9, - "y": 2711.1, + "x": 3546.7, + "y": 3068.2, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Pylons", - "x": 2960.3, - "y": 619.1, + "x": 3350.0, + "y": 571.6, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Tendris Warpwood", - "x": 2807.2, - "y": 2891.5, + "x": 3306.7, + "y": 3283.4, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Magister Kalendris", - "x": 2774.8, - "y": 2299.9, + "x": 3297.6, + "y": 2577.5, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Tsu'zee (Rare)", - "x": 3616.4, - "y": 756.1, + "x": 3535.5, + "y": 735.1, "rare": true, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Immol'thar", - "x": 2849.0, - "y": 3223.3, + "x": 3318.5, + "y": 3679.4, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Lord Hel'nurath (Summon)", - "x": 2378.3, - "y": 3050.2, + "x": 3185.4, + "y": 3472.8, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Prince Tortheldrin", - "x": 3456.5, - "y": 121.3, + "x": 3490.3, + "y": -22.5, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" }, { "name": "Pylons", - "x": 3053.0, - "y": 1556.9, - "rare": false, - "source": "atlasloot" - }, - { - "name": "Old Ironbark", - "x": 2960.3, - "y": 3937.5, + "x": 3376.2, + "y": 1690.7, "rare": false, + "kg_floor_id": 203, "source": "atlasloot" } ], "dire_maul_west": [ { "name": "Guard Mol'dar", - "x": 4061.4, - "y": 3117.0, + "x": 4352.2, + "y": 2945.2, "rare": false, + "kg_floor_id": 201, "source": "atlasloot" }, { "name": "Stomper Kreeg ", - "x": 3611.3, - "y": 2815.6, + "x": 3787.6, + "y": 2683.6, "rare": false, + "kg_floor_id": 201, "source": "atlasloot" }, { "name": "Guard Fengus", - "x": 2696.1, - "y": 3177.2, + "x": 2639.4, + "y": 2997.5, "rare": false, + "kg_floor_id": 201, "source": "atlasloot" }, { "name": "Guard Slip'kik", - "x": 1866.8, - "y": 2431.4, + "x": 2000.1, + "y": 2382.2, "rare": false, + "kg_floor_id": 199, "source": "atlasloot" }, { "name": "Captain Kromcrush", - "x": 2134.8, - "y": 2190.3, + "x": 2061.1, + "y": 2069.2, "rare": false, + "kg_floor_id": 199, "source": "atlasloot" }, { "name": "King Gordok", - "x": 2144.9, - "y": 1297.6, + "x": 2063.4, + "y": 910.0, "rare": false, + "kg_floor_id": 199, "source": "atlasloot" }, { "name": "Lord Hel'nurath (Summon)", - "x": 1280.2, - "y": 2352.3, + "x": 1866.5, + "y": 2279.5, "rare": false, + "kg_floor_id": 199, "source": "atlasloot" }, { "name": "Hydrospawn", - "x": 2600.0, - "y": 2107.4, + "x": 2167.1, + "y": 1961.6, "rare": false, + "kg_floor_id": 199, "source": "atlasloot" }, { "name": "Lethtendris", - "x": 2777.0, - "y": 2009.5, + "x": 2207.4, + "y": 1834.4, "rare": false, + "kg_floor_id": 199, "source": "atlasloot" }, { "name": "Alzzin the Wildshaper", - "x": 3424.2, - "y": 1342.8, + "x": 3552.9, + "y": 1405.3, "rare": false, + "kg_floor_id": 201, "source": "atlasloot" } ], "blackwinglair": [ { "name": "Draconic for Dummies (Chapter VII)", - "x": 2120.6, - "y": 1770.8, + "x": 2254.4, + "y": 1615.4, "rare": false, + "kg_floor_id": 312, "source": "atlasloot" }, { "name": "Master Elemental Shaper Krixix", - "x": 2569.4, - "y": 1722.8, + "x": 2610.7, + "y": 1517.1, "rare": false, + "kg_floor_id": 312, "source": "atlasloot" } ], "naxxramas_classic": [ { "name": "|cffcc6666Instructor Razuvious", - "x": 2683.1, - "y": 1682.3, + "x": 2602.4, + "y": 1894.1, "rare": false, + "kg_floor_id": 138, "source": "atlasloot" }, { "name": "|cffcc6666Gothik the Harvester", - "x": 3996.6, - "y": 1869.7, + "x": 4128.5, + "y": 2470.0, "rare": false, + "kg_floor_id": 138, "source": "atlasloot" }, { "name": "|cffcc6666Four Horsemen Chest", - "x": 1971.6, - "y": 2097.3, + "x": 1839.2, + "y": 3176.0, "rare": false, + "kg_floor_id": 141, "source": "atlasloot" } ] diff --git a/tools/atlasloot_extras.py b/tools/atlasloot_extras.py index 9ca20ba..859703f 100644 --- a/tools/atlasloot_extras.py +++ b/tools/atlasloot_extras.py @@ -98,28 +98,26 @@ def parse_js_var(p: Path) -> dict: def get_kg_bosses_per_floor(tile_key: str): - """Return list of (npc_id, name, x_px, y_px, classification) for - boss-like enemies in the dungeon's first floor only — enough to fit - a transform; later floors share the same coord scale anyway.""" + """Return list of dicts per boss-like enemy across ALL floors. + Caller groups by floor_id when fitting per-floor transforms.""" sf = parse_js_var(KG_DIR / tile_key / "split_floors.js") lang = parse_js_var(KG_DIR / tile_key / "lang.js") name_by_id = {n["id"]: n["name"] for n in lang.get("dungeonNpcs", [])} cls_by_id = {n["id"]: n.get("classification_id") for n in lang.get("dungeonNpcs", [])} - # First floor: pick the lowest floor_id present - enemies = sf["dungeon"].get("enemies", []) - if not enemies: - return [] out = [] - for e in enemies: + for e in sf["dungeon"].get("enemies", []): npc_id = e.get("npc_id") name = name_by_id.get(npc_id, "?") cls = cls_by_id.get(npc_id, 0) if cls < 3: - continue # only bosses - # kg coord transform: pixel_x = lng*16, pixel_y = -lat*16 (z=4) - pix_x = e["lng"] * 16 - pix_y = -e["lat"] * 16 - out.append((npc_id, name, pix_x, pix_y, cls, e.get("floor_id"))) + continue + out.append({ + "name": name, + "x": e["lng"] * 16, + "y": -e["lat"] * 16, + "cls": cls, + "floor_id": e.get("floor_id"), + }) return out @@ -192,40 +190,12 @@ def main() -> int: if not al_dungeon: continue al_entries = list(collect_al_entries(al_dungeon)) - # Match AL entries to kg bosses by normalized name - al_by_norm = {norm_name(e[0]): e for e in al_entries if not e[3]} # non-rare bosses for fitting - # For each kg wing, fit a transform from anchors that match + al_by_norm = {norm_name(e[0]): e for e in al_entries if not e[3]} + for kg_key in kg_keys: kg_b = kg_bosses.get(kg_key, []) if not kg_b: continue - kg_by_norm = {norm_name(b[1]): b for b in kg_b} - common_names = set(al_by_norm) & set(kg_by_norm) - if len(common_names) < 2: - summary.append(f"{al_id} → {kg_key}: only {len(common_names)} anchor(s); skipping") - continue - al_pts = [] - kg_pts = [] - for n in sorted(common_names): - al_e = al_by_norm[n] - kg_e = kg_by_norm[n] - al_pts.append((al_e[1], al_e[2])) - kg_pts.append((kg_e[2], kg_e[3])) - tr = fit_transform(al_pts, kg_pts) - if not tr: - summary.append(f"{al_id} → {kg_key}: degenerate fit") - continue - sx, ox, sy, oy = tr - transforms[(al_id, kg_key)] = tr - summary.append( - f"{al_id} → {kg_key}: {len(common_names)} anchors, " - f"scale=({sx:.2f},{sy:.2f}) offset=({ox:.0f},{oy:.0f})" - ) - - # Apply transform to AL entries that don't already exist as kg bosses - kg_existing_norms = {norm_name(b[1]) for b in kg_b} - # Build the set of "this dungeon's bosses pinned to a different - # wing" so we can exclude them here. other_wings = [k for k in kg_keys if k != kg_key] forced_elsewhere = set() for w in other_wings: @@ -233,24 +203,63 @@ def main() -> int: forced_elsewhere.add(needle.lower()) this_wing_pins = {n.lower() for n in WING_FORCE.get(kg_key, [])} + # Group kg bosses by floor_id and fit one transform per floor + # so a boss on floor B doesn't drag the floor-A fit off. + by_floor = defaultdict(list) + for b in kg_b: + by_floor[b["floor_id"]].append(b) + + floor_transforms = {} # floor_id → (sx, ox, sy, oy, anchor_pts) + for fid, fb in by_floor.items(): + kg_by_norm = {norm_name(b["name"]): b for b in fb} + common = set(al_by_norm) & set(kg_by_norm) + if len(common) < 2: + continue + al_pts, kg_pts = [], [] + for n in sorted(common): + al_pts.append((al_by_norm[n][1], al_by_norm[n][2])) + kg_pts.append((kg_by_norm[n]["x"], kg_by_norm[n]["y"])) + tr = fit_transform(al_pts, kg_pts) + if not tr: + continue + floor_transforms[fid] = (*tr, al_pts, kg_pts) + transforms[(al_id, kg_key, fid)] = tr + summary.append( + f"{al_id} → {kg_key} floor={fid}: {len(common)} anchors, " + f"scale=({tr[0]:.2f},{tr[2]:.2f}) offset=({tr[1]:.0f},{tr[3]:.0f})" + ) + + if not floor_transforms: + summary.append(f"{al_id} → {kg_key}: no per-floor transform fit") + continue + + kg_existing = set() + for fb in by_floor.values(): + for b in fb: + kg_existing.add(norm_name(b["name"])) + for e in al_entries: name = e[0] lname = name.lower() - if norm_name(name) in kg_existing_norms: - continue # already in kg - # If this boss is force-pinned to another wing, skip here. + if norm_name(name) in kg_existing: + continue if any(p in lname for p in forced_elsewhere) and \ not any(p in lname for p in this_wing_pins): continue + # Pick the floor whose anchors are nearest the AL coord — + # that's the floor this entry most likely belongs to. + best_fid = None + best_dist = float("inf") + for fid, (sx, ox, sy, oy, al_pts, kg_pts) in floor_transforms.items(): + d = min(((e[1] - a[0]) ** 2 + (e[2] - a[1]) ** 2) ** 0.5 for a in al_pts) + if d < best_dist: + best_dist = d + best_fid = fid + sx, ox, sy, oy, al_pts, kg_pts = floor_transforms[best_fid] px = e[1] * sx + ox py = e[2] * sy + oy - # Reject points outside the kg image bounds (multi-wing - # dungeons: a boss in a wing is OOB on a different wing's - # image). if not (-200 <= px <= 6344 and -200 <= py <= 4296): continue - # Also reject points that are >1.5x the diagonal away from - # all anchors — likely a wrong-wing match. anchor_dists = [ ((px - a[0]) ** 2 + (py - a[1]) ** 2) ** 0.5 for a in kg_pts ] @@ -261,12 +270,13 @@ def main() -> int: "x": round(px, 1), "y": round(py, 1), "rare": e[3], + "kg_floor_id": best_fid, "source": "atlasloot", }) OUT.write_text(json.dumps({ "_comment": "Supplemental rare bosses + interactives lifted from AtlasLootAscension and transformed into keystone.guru pixel space. Generated by tools/atlasloot_extras.py.", - "transforms": {f"{k[0]}→{k[1]}": v for k, v in transforms.items()}, + "transforms": {f"{k[0]}→{k[1]}@floor{k[2]}": v for k, v in transforms.items()}, "extras": dict(extras), }, indent=2)) diff --git a/tools/kg_build_data.py b/tools/kg_build_data.py index 6acd59c..ced05ae 100644 --- a/tools/kg_build_data.py +++ b/tools/kg_build_data.py @@ -26,6 +26,7 @@ REGISTRY = DATA / "kg_dungeons.json" WEB_ASSETS = ROOT / "web" / "assets" WEB_MAPS = WEB_ASSETS / "maps" EXTRAS_PATH = DATA / "atlasloot_extras.json" +OVERRIDES_PATH = DATA / "ascension_overrides.json" OUT_PATH = WEB_ASSETS / "dungeons.json" # Map kg's mapIconType names → simple labels we render in the UI. @@ -223,6 +224,22 @@ def main() -> int: if EXTRAS_PATH.exists(): extras_db = json.loads(EXTRAS_PATH.read_text()).get("extras", {}) + overrides = [] + if OVERRIDES_PATH.exists(): + overrides = json.loads(OVERRIDES_PATH.read_text()).get("overrides", []) + + def apply_overrides(tile_key, name, pos, floor_id): + """Return (pos, floor_id) possibly replaced by an Ascension override.""" + for o in overrides: + if o["tile_key"] != tile_key: + continue + if o["name"].lower() not in name.lower(): + continue + new_floor = o.get("kg_floor_id", floor_id) + new_pos = o.get("pos", pos) + return new_pos, new_floor + return pos, floor_id + # Build a global icon-type index from the static.js if present, else # fall back to known IDs. icon_index: dict[int, str] = { @@ -261,9 +278,25 @@ def main() -> int: "pos": [e["x"], e["y"]], "rare": bool(e.get("rare")), "source": e.get("source", "atlasloot"), + "kg_floor_id": e.get("kg_floor_id"), } for e in extras ] + + # Ascension overrides: swap pos / floor for a specific named entity + for m in entry["maps"]: + for e in m["enemies"]: + new_pos, new_floor = apply_overrides(d["tile_key"], e["name"], e["pos"], m.get("kg_floor_id")) + if new_pos is not e["pos"]: + e["pos"] = list(new_pos) + e["ascension_override"] = True + for ex in entry.get("extras", []): + new_pos, new_floor = apply_overrides(d["tile_key"], ex["name"], ex["pos"], ex.get("kg_floor_id")) + if new_pos is not ex["pos"]: + ex["pos"] = list(new_pos) + ex["kg_floor_id"] = new_floor + ex["ascension_override"] = True + dungeons.append(entry) dungeons.sort(key=lambda d: d["name"]) diff --git a/web/app.js b/web/app.js index 25f911d..39002f0 100644 --- a/web/app.js +++ b/web/app.js @@ -194,13 +194,17 @@ function renderOverlay() { } } - // AtlasLoot-derived extras: rare bosses + interactives kg doesn't ship. - // These are dungeon-level (not per-floor) and only render on floor 0 - // unless we get richer data; for single-floor dungeons that's all that - // matters, and for multi-floor we leave them on the first floor by - // default — the user can drag a Note over them on any floor. - if (state.floorIndex === 0 && state.current?.extras) { + // AtlasLoot-derived extras: render only ones that match the current + // floor. Single-floor dungeons have kg_floor_id null on every extra, + // so they all render on floor 0. + if (state.current?.extras) { + const curFloor = m.kg_floor_id; for (const ex of state.current.extras) { + // If the extra has no floor assignment, show only on floor 0. + // If it does, show on the matching floor only. + const fid = ex.kg_floor_id; + const matches = fid == null ? state.floorIndex === 0 : fid === curFloor; + if (!matches) continue; svg.appendChild(makeExtraPin(ex)); } } @@ -1175,6 +1179,16 @@ function hookEvents() { $("export").addEventListener("click", exportJson); const importBtn = $("import"); if (importBtn) importBtn.addEventListener("click", importJson); + // Layer toggles — repaint overlay on change. Persisted in state.show. + for (const layer of ["enemies", "packs", "patrols", "icons"]) { + const cb = $(`layer-${layer}`); + if (!cb) continue; + cb.checked = state.show[layer]; + cb.addEventListener("change", () => { + state.show[layer] = cb.checked; + renderOverlay(); + }); + } $("tool-route").addEventListener("click", () => setTool("route")); $("tool-pull").addEventListener("click", () => setTool("pull")); const noteBtn = $("tool-note"); diff --git a/web/assets/dungeons.json b/web/assets/dungeons.json index a14ac34..ac4d8f6 100644 --- a/web/assets/dungeons.json +++ b/web/assets/dungeons.json @@ -24986,110 +24986,122 @@ { "name": "Kharan Mighthammer", "pos": [ - 3166.4, - 3541.2 + 3146.5, + 3322.2 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "Commander Gor'shak ", "pos": [ - 3293.2, - 3759.8 + 3273.8, + 3524.2 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "Marshal Windsor", "pos": [ - 3229.8, - 4065.8 + 3210.1, + 3807.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "Ring of Law", "pos": [ - 3103.0, - 2623.0 + 3082.8, + 2473.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "The Vault", "pos": [ - 3673.5, - 2841.6 + 3655.6, + 2675.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "Ring of Law", "pos": [ - 3103.0, - 3847.2 + 3082.8, + 3605.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "Shadowforge Lock", "pos": [ - 2532.5, - 3934.7 + 2510.1, + 3685.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "The Grim Guzzler", "pos": [ - 3039.6, - 2710.5 + 3019.2, + 2554.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "Summoner's Tomb", "pos": [ - 3293.2, - 1049.1 + 3273.8, + 1019.1 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "The Lyceum", "pos": [ - 4117.3, - 480.7 + 4101.0, + 493.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "The Black Forge", "pos": [ - 3863.7, - 1049.1 + 3846.5, + 1019.1 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 }, { "name": "Molten Core", "pos": [ - 4180.7, - 1530.0 + 4164.7, + 1463.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 194 } ] }, @@ -27458,20 +27470,22 @@ { "name": "Draconic for Dummies (Chapter VII)", "pos": [ - 2120.6, - 1770.8 + 2254.4, + 1615.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 312 }, { "name": "Master Elemental Shaper Krixix", "pos": [ - 2569.4, - 1722.8 + 2610.7, + 1517.1 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 312 } ] }, @@ -34730,131 +34744,125 @@ } ], "extras": [ - { - "name": "Stomper Kreeg ", - "pos": [ - 3447.2, - 3937.5 - ], - "rare": false, - "source": "atlasloot" - }, { "name": "Guard Slip'kik", "pos": [ - 2647.3, - 3201.7 + 3261.5, + 3653.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Captain Kromcrush", "pos": [ - 2770.1, - 2740.0 + 3296.2, + 3102.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "King Gordok", "pos": [ - 2774.8, - 1030.3 + 3297.6, + 1062.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Pylons", "pos": [ - 3655.9, - 2711.1 + 3546.7, + 3068.2 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Pylons", "pos": [ - 2960.3, - 619.1 + 3350.0, + 571.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Tendris Warpwood", "pos": [ - 2807.2, - 2891.5 + 3306.7, + 3283.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Magister Kalendris", "pos": [ - 2774.8, - 2299.9 + 3297.6, + 2577.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Tsu'zee (Rare)", "pos": [ - 3616.4, - 756.1 + 3535.5, + 735.1 ], "rare": true, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Immol'thar", "pos": [ - 2849.0, - 3223.3 + 3318.5, + 3679.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Lord Hel'nurath (Summon)", "pos": [ - 2378.3, - 3050.2 + 3185.4, + 3472.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Prince Tortheldrin", "pos": [ - 3456.5, - 121.3 + 3490.3, + -22.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 }, { "name": "Pylons", "pos": [ - 3053.0, - 1556.9 + 3376.2, + 1690.7 ], "rare": false, - "source": "atlasloot" - }, - { - "name": "Old Ironbark", - "pos": [ - 2960.3, - 3937.5 - ], - "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 203 } ] }, @@ -40991,7 +40999,8 @@ 3130.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 198 }, { "name": "Tendris Warpwood", @@ -41000,7 +41009,8 @@ 2142.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 198 }, { "name": "Magister Kalendris", @@ -41009,7 +41019,8 @@ 1811.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 198 }, { "name": "Immol'thar", @@ -41018,7 +41029,8 @@ 2327.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 198 }, { "name": "Lord Hel'nurath (Summon)", @@ -41027,7 +41039,8 @@ 2230.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 198 }, { "name": "Prince Tortheldrin", @@ -41036,7 +41049,8 @@ 593.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 198 }, { "name": "Hydrospawn", @@ -41045,7 +41059,8 @@ 1968.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 198 }, { "name": "Lethtendris", @@ -41054,7 +41069,8 @@ 1863.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 198 }, { "name": "Alzzin the Wildshaper", @@ -41063,7 +41079,8 @@ 1150.1 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 198 } ] }, @@ -46691,92 +46708,102 @@ { "name": "Guard Mol'dar", "pos": [ - 4061.4, - 3117.0 + 4352.2, + 2945.2 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 201 }, { "name": "Stomper Kreeg ", "pos": [ - 3611.3, - 2815.6 + 3787.6, + 2683.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 201 }, { "name": "Guard Fengus", "pos": [ - 2696.1, - 3177.2 + 2639.4, + 2997.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 201 }, { "name": "Guard Slip'kik", "pos": [ - 1866.8, - 2431.4 + 2000.1, + 2382.2 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 199 }, { "name": "Captain Kromcrush", "pos": [ - 2134.8, - 2190.3 + 2061.1, + 2069.2 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 199 }, { "name": "King Gordok", "pos": [ - 2144.9, - 1297.6 + 2063.4, + 910.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 199 }, { "name": "Lord Hel'nurath (Summon)", "pos": [ - 1280.2, - 2352.3 + 1866.5, + 2279.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 199 }, { "name": "Hydrospawn", "pos": [ - 2600.0, - 2107.4 + 2167.1, + 1961.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 199 }, { "name": "Lethtendris", "pos": [ - 2777.0, - 2009.5 + 2207.4, + 1834.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 199 }, { "name": "Alzzin the Wildshaper", "pos": [ - 3424.2, - 1342.8 + 3552.9, + 1405.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 201 } ] }, @@ -54589,17 +54616,6 @@ } ] } - ], - "extras": [ - { - "name": "Clean Room", - "pos": [ - 5674.2, - 2664.2 - ], - "rare": false, - "source": "atlasloot" - } ] }, { @@ -64214,152 +64230,6 @@ "patrols": [], "icons": [] } - ], - "extras": [ - { - "name": "Mother Smolderweb", - "pos": [ - 3949.6, - 2798.5 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Burning Felguard (Rare, Summon)", - "pos": [ - 2473.0, - 2039.6 - ], - "rare": true, - "source": "atlasloot" - }, - { - "name": "Vaelan (Upper)", - "pos": [ - 3105.8, - 1423.0 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Warosh (Wanders)", - "pos": [ - 3738.6, - 1517.9 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Bijou", - "pos": [ - 3879.3, - 2134.5 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Roughshod Pike", - "pos": [ - 4160.5, - 2229.3 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Spirestone Butcher (Rare)", - "pos": [ - 3035.5, - 2229.3 - ], - "rare": true, - "source": "atlasloot" - }, - { - "name": "Human Remains (Lower)", - "pos": [ - 2473.0, - 2134.5 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Urok's Tribute Pile", - "pos": [ - 2683.9, - 2087.0 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Halycon", - "pos": [ - 2121.4, - 3509.9 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Pyroguard Emberseer", - "pos": [ - 1629.2, - 759.0 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Solakar Flamewreath", - "pos": [ - 2191.7, - 1328.2 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Goraluk Anvilcrack ", - "pos": [ - 1769.8, - 759.0 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "Warchief Rend Blackhand", - "pos": [ - 2894.9, - 759.0 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "The Beast", - "pos": [ - 3949.6, - 996.2 - ], - "rare": false, - "source": "atlasloot" - }, - { - "name": "General Drakkisath", - "pos": [ - 1980.7, - 1849.9 - ], - "rare": false, - "source": "atlasloot" - } ] }, { @@ -78110,20 +77980,22 @@ { "name": "Veng ", "pos": [ - 3732.3, - 946.8 + 3795.3, + 896.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 214 }, { "name": "Maraudos ", "pos": [ - 3299.8, - 3056.4 + 3256.7, + 3083.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 215 } ] }, @@ -100268,29 +100140,32 @@ { "name": "|cffcc6666Instructor Razuvious", "pos": [ - 2683.1, - 1682.3 + 2602.4, + 1894.1 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 138 }, { "name": "|cffcc6666Gothik the Harvester", "pos": [ - 3996.6, - 1869.7 + 4128.5, + 2470.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 138 }, { "name": "|cffcc6666Four Horsemen Chest", "pos": [ - 1971.6, - 2097.3 + 1839.2, + 3176.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 141 } ] }, @@ -114583,7 +114458,8 @@ 2011.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 218 }, { "name": "Blind Hunter (Rare)", @@ -114592,7 +114468,8 @@ 1272.6 ], "rare": true, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 218 } ] }, @@ -119053,7 +118930,8 @@ 2099.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 220 }, { "name": "Pumpkin Shrine (Hallow's End)", @@ -119062,7 +118940,8 @@ 2196.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 220 }, { "name": "Bloodmage Thalnos", @@ -119071,7 +118950,8 @@ 1971.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 220 }, { "name": "Houndmaster Loksey", @@ -119080,7 +118960,8 @@ 2904.9 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 220 }, { "name": "Arcanist Doan", @@ -119089,7 +118970,8 @@ 2647.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 220 }, { "name": "Herod ", @@ -119098,7 +118980,8 @@ 522.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 220 } ] }, @@ -121327,7 +121210,8 @@ 2989.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 221 }, { "name": "Arcanist Doan", @@ -121336,7 +121220,8 @@ 2801.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 221 }, { "name": "Herod ", @@ -121345,7 +121230,8 @@ 1253.9 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 221 }, { "name": "High Inquisitor Fairbanks", @@ -121354,7 +121240,8 @@ 1605.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 221 }, { "name": "Scarlet Commander Mograine", @@ -121363,7 +121250,8 @@ 1676.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 221 }, { "name": "High Inquisitor Whitemane", @@ -121372,7 +121260,8 @@ 1394.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 221 } ] }, @@ -123539,7 +123428,8 @@ 1783.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 222 }, { "name": "Bloodmage Thalnos", @@ -123548,7 +123438,8 @@ 1487.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 222 } ] }, @@ -131991,29 +131882,32 @@ { "name": "Blood Steward of Kirtonos", "pos": [ - 5213.8, - 1854.2 + 5195.8, + 1790.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 225 }, { "name": "The Deed to Tarren Mill", "pos": [ - 1737.2, - 2367.6 + 1776.8, + 2280.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 225 }, { "name": "Torch Lever", "pos": [ - 2964.2, - 2274.2 + 2983.5, + 2191.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 225 } ] }, @@ -135675,47 +135569,52 @@ { "name": "Investigator Fezzen Brasstacks (Love is in the Air)", "pos": [ - 3373.4, - 2654.4 + 3523.7, + 2390.2 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 232 }, { "name": "Deathstalker Vincent", "pos": [ - 3558.3, - 2408.5 + 3612.8, + 2185.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 232 }, { "name": "Apothecary Trio (Love is in the Air)", "pos": [ - 2448.6, - 2039.6 + 2445.0, + 1958.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 227 }, { "name": "Fel Steed", "pos": [ - 2202.0, - 2326.5 + 2200.9, + 2283.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 227 }, { "name": "Deathsworn Captain (Rare)", "pos": [ - 3681.6, - 2121.6 + 3672.2, + 1946.7 ], "rare": true, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 232 } ] }, @@ -141403,15 +141302,16 @@ "npc_id": 10435, "name": "Magistrate Barthilas", "pos": [ - 3497.7872, - 615.7024 + 3498, + 3300 ], "classification": 3, "skippable": false, "required": false, "kill_priority": null, "pack_id": null, - "patrol_id": null + "patrol_id": null, + "ascension_override": true }, { "id": 33074, @@ -145174,128 +145074,142 @@ { "name": "Crusaders' Square Postbox", "pos": [ - 2415.9, - 1333.3 + 2433.2, + 1197.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 234 }, { "name": "Market Row Postbox", "pos": [ - 3976.3, - 1034.2 + 4218.7, + 1113.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 235 }, { "name": "Festival Lane Postbox", "pos": [ - 4496.5, - 1076.9 + 4241.9, + 924.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 234 }, { "name": "King's Square Postbox", "pos": [ - 3739.9, - 2102.2 + 3903.7, + 2170.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 235 }, { "name": "Fras Siabi's Postbox", "pos": [ - 3314.3, - 2785.7 + 3336.7, + 2846.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 235 }, { "name": "Atiesh (Summon)", "pos": [ - 4780.2, - 1461.4 + 4488.6, + 1333.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 234 }, { "name": "Elder Farwhisper (Lunar Festival)", "pos": [ - 4449.2, - 564.3 + 4200.8, + 379.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 234 }, { "name": "Malor the Zealous", "pos": [ - 2132.2, - 1632.3 + 2186.6, + 1515.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 234 }, { "name": "Crimson Hammersmith (Summon)", "pos": [ - 1328.3, - 1888.6 + 1487.7, + 1788.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 234 }, { "name": "Cannon Master Willey", "pos": [ - 950.0, - 2016.7 + 1158.9, + 1924.9 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 234 }, { "name": "Archivist Galford", "pos": [ - 2037.6, - 2999.3 + 2104.4, + 2970.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 234 }, { "name": "Elders' Square Postbox", "pos": [ - 3881.8, - 3084.7 + 4092.7, + 3142.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 235 }, { "name": "Aurius", "pos": [ - 3929.1, - 2999.3 + 4155.7, + 3057.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 235 }, { "name": "Stonespine (Rare)", "pos": [ - 4023.6, - 2016.7 + 4281.7, + 2085.8 ], "rare": true, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 235 } ] }, @@ -150838,11 +150752,12 @@ { "name": "Defias Gunpowder", "pos": [ - 1572.7, - 2343.0 + 1091.3, + 2149.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 196 } ] }, @@ -158803,29 +158718,32 @@ { "name": "Remains of a Paladin", "pos": [ - 3262.4, - 2616.3 + 3254.6, + 2623.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 238 }, { "name": "The Discs of Norgannon (Lower)", "pos": [ - 2440.8, - 332.4 + 2437.2, + 344.9 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 238 }, { "name": "The Discs of Norgannon (Lower)", "pos": [ - 3072.8, - 1370.5 + 3066.0, + 1380.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 238 } ] }, @@ -164357,146 +164275,162 @@ { "name": "War Master Voone", "pos": [ - 3121.7, - 2058.6 + 3108.6, + 2048.1 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Mother Smolderweb", "pos": [ - 3859.8, - 2602.6 + 3870.3, + 2571.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Burning Felguard (Rare, Summon)", "pos": [ - 2568.2, - 2058.6 + 2537.3, + 2048.1 ], "rare": true, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Shadow Hunter Vosh'gajin", "pos": [ - 3367.7, - 2602.6 + 3362.5, + 2571.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Vaelan (Upper)", "pos": [ - 3121.7, - 1616.5 + 3151.7, + 1626.5 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 251 }, { "name": "Warosh (Wanders)", "pos": [ - 3675.3, - 1684.5 + 3679.9, + 1688.1 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Highlord Omokk", "pos": [ - 2322.2, - 2262.6 + 2283.3, + 2244.4 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Urok's Tribute Pile", "pos": [ - 2752.7, - 2092.6 + 2727.7, + 2080.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Bannok Grimaxe (Rare)", "pos": [ - 2752.7, - 2432.6 + 2727.7, + 2408.1 ], "rare": true, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Quartermaster Zigris ", "pos": [ - 3306.2, - 3112.7 + 3299.0, + 3062.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Darkstone Tablet", "pos": [ - 1891.6, - 1650.5 + 1917.7, + 1664.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 251 }, { "name": "Overlord Wyrmthalak", "pos": [ - 3490.8, - 2398.6 + 3489.4, + 2375.3 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Jed Runewatcher (Rare)", "pos": [ - 2260.7, - 1038.4 + 2287.9, + 988.6 ], "rare": true, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 251 }, { "name": "Goraluk Anvilcrack ", "pos": [ - 1953.1, - 1140.4 + 1979.4, + 1101.2 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 251 }, { "name": "Awbee", "pos": [ - 2937.2, - 1446.5 + 2918.1, + 1459.0 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 }, { "name": "Blackwing Lair", "pos": [ - 3306.2, - 970.4 + 3299.0, + 1000.8 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 252 } ] }, @@ -172276,7 +172210,8 @@ 1961.7 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 240 } ] }, @@ -179000,7 +178935,8 @@ 712.6 ], "rare": false, - "source": "atlasloot" + "source": "atlasloot", + "kg_floor_id": 241 } ] }, diff --git a/web/index.html b/web/index.html index 2f8ea17..d1a6448 100644 --- a/web/index.html +++ b/web/index.html @@ -33,6 +33,12 @@ + + + + + + diff --git a/web/style.css b/web/style.css index 9661b57..1b5380f 100644 --- a/web/style.css +++ b/web/style.css @@ -194,6 +194,26 @@ body { border-color: var(--accent); font-weight: 600; } +.toolbar-sep { + width: 1px; + height: 22px; + background: var(--line); + align-self: center; + margin: 0 4px; +} +.layer-toggle { + display: inline-flex; + align-items: center; + gap: 5px; + font-size: 12px; + color: var(--text-dim); + cursor: pointer; + padding: 4px 6px; + user-select: none; + white-space: nowrap; +} +.layer-toggle:hover { color: var(--text); } +.layer-toggle input { margin: 0; cursor: pointer; } /* --- canvas / overlay ----------------------------------------------------- */