poi-plugin-compass 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -0
- package/air-status.js +28 -0
- package/assets/compass.css +647 -0
- package/assets/kcnav/icons/map_common/136.png +0 -0
- package/assets/kcnav/icons/map_common/137.png +0 -0
- package/assets/kcnav/icons/map_common/19.png +0 -0
- package/assets/kcnav/icons/map_main/17.png +0 -0
- package/assets/kcnav/icons/map_main/18.png +0 -0
- package/assets/kcnav/icons/map_main/40.png +0 -0
- package/assets/kcnav/icons/map_main/42.png +0 -0
- package/assets/kcnav/icons/map_main/46.png +0 -0
- package/assets/kcnav/icons/map_main/47.png +0 -0
- package/assets/kcnav/icons/map_main/48.png +0 -0
- package/assets/kcnav/icons/map_main/53.png +0 -0
- package/assets/kcnav/icons/map_main/54.png +0 -0
- package/assets/kcnav/icons/map_main/62.png +0 -0
- package/assets/kcnav/maps/1-1.webp +0 -0
- package/assets/kcnav/maps/1-2.webp +0 -0
- package/assets/kcnav/maps/1-3.webp +0 -0
- package/assets/kcnav/maps/1-4.webp +0 -0
- package/assets/kcnav/maps/1-5.webp +0 -0
- package/assets/kcnav/maps/1-6.webp +0 -0
- package/assets/kcnav/maps/2-1.webp +0 -0
- package/assets/kcnav/maps/2-2.webp +0 -0
- package/assets/kcnav/maps/2-3.webp +0 -0
- package/assets/kcnav/maps/2-4.webp +0 -0
- package/assets/kcnav/maps/2-5.webp +0 -0
- package/assets/kcnav/maps/3-1.webp +0 -0
- package/assets/kcnav/maps/3-2.webp +0 -0
- package/assets/kcnav/maps/3-3.webp +0 -0
- package/assets/kcnav/maps/3-4.webp +0 -0
- package/assets/kcnav/maps/3-5.webp +0 -0
- package/assets/kcnav/maps/4-1.webp +0 -0
- package/assets/kcnav/maps/4-2.webp +0 -0
- package/assets/kcnav/maps/4-3.webp +0 -0
- package/assets/kcnav/maps/4-4.webp +0 -0
- package/assets/kcnav/maps/4-5.webp +0 -0
- package/assets/kcnav/maps/5-1.webp +0 -0
- package/assets/kcnav/maps/5-2.webp +0 -0
- package/assets/kcnav/maps/5-3.webp +0 -0
- package/assets/kcnav/maps/5-4.webp +0 -0
- package/assets/kcnav/maps/5-5.webp +0 -0
- package/assets/kcnav/maps/5-6.webp +0 -0
- package/assets/kcnav/maps/6-1.webp +0 -0
- package/assets/kcnav/maps/6-2.webp +0 -0
- package/assets/kcnav/maps/6-3.webp +0 -0
- package/assets/kcnav/maps/6-4.webp +0 -0
- package/assets/kcnav/maps/6-5.webp +0 -0
- package/assets/kcnav/maps/7-1.webp +0 -0
- package/assets/kcnav/maps/7-2.webp +0 -0
- package/assets/kcnav/maps/7-3.webp +0 -0
- package/assets/kcnav/maps/7-4.webp +0 -0
- package/assets/kcnav/maps/7-5.webp +0 -0
- package/data/kc3kai-master-ids.json +1 -0
- package/data/kc3kai-ship-stats.json +21545 -0
- package/data/kcnav-node-types-by-map.json +606 -0
- package/data/kcnav-node-types.json +176 -0
- package/data/los-config.json +42 -0
- package/data/maps.json +590 -0
- package/data/normal-maps.json +1590 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-1/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-1/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-1/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-2/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-2/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-2/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-2/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-3/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-3/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-3/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-3/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-4/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-4/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-4/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-4/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-4/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-4/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-5/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-5/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-5/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-5/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-5/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-5/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-5/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-5/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-6/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-6/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-6/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-6/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-6/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-6/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-6/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-6/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/1-6/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-1/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-1/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-1/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-1/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-1/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-2/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-2/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-2/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-2/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-2/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-3/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-3/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-3/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-3/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-3/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-3/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-3/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-4/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-4/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-4/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-4/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-4/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-4/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-4/P.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-5/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-5/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-5/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-5/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-5/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-5/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/2-5/O.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-1/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-1/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-1/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-1/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-1/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-2/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-2/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-2/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-2/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-2/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-2/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-3/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-3/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-3/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-3/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-3/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-3/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-4/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-4/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-4/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-4/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-4/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-4/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-4/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-4/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-4/P.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-5/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-5/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-5/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-5/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-5/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-5/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/3-5/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-1/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-1/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-1/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-1/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-1/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-1/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-1/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-2/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-2/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-2/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-2/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-2/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-2/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-2/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-2/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-3/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-3/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-3/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-3/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-3/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-3/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-3/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-3/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-3/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-4/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-4/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-4/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-4/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-4/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-4/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-4/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-4/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/O.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/S.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/4-5/T.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-1/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-1/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-1/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-1/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-1/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-1/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-2/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-2/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-2/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-2/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-2/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-2/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-2/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-2/O.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-3/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-3/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-3/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-3/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-3/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-3/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-3/P.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-3/Q.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-4/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-4/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-4/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-4/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-4/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-4/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-4/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-4/P.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/P.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-5/S.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/A1.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/A2.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/C1.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/C2.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/K1.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/K2.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/P.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/Q.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/Q1.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/Q2.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/T.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/U.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/V.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/W.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/X.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/5-6/Z.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-1/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-1/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-1/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-1/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-1/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-1/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-1/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-2/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-2/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-2/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-2/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-2/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-2/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-2/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-3/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-3/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-3/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-3/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-3/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-3/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-4/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/6-5/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-1/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-1/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-1/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-1/F.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-1/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-1/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-1/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-2/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-2/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-2/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-2/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-2/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-2/I.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-2/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-2/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-3/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-3/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-3/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-3/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-3/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-3/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-3/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-3/P.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/H.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-4/P.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/A.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/B.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/C.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/D.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/E.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/G.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/J.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/K.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/L.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/M.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/N.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/Q.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/R.json +1 -0
- package/data/sources/kcnav/enemies/2026-08-11_2026-09-11/7-5/T.json +1 -0
- package/data/sources/kcnav/enemies/manifest.json +2120 -0
- package/data/sources/kcnav/maps/1-1.json +175 -0
- package/data/sources/kcnav/maps/1-2.json +277 -0
- package/data/sources/kcnav/maps/1-3.json +517 -0
- package/data/sources/kcnav/maps/1-4.json +652 -0
- package/data/sources/kcnav/maps/1-5.json +553 -0
- package/data/sources/kcnav/maps/1-6.json +668 -0
- package/data/sources/kcnav/maps/2-1.json +451 -0
- package/data/sources/kcnav/maps/2-2.json +557 -0
- package/data/sources/kcnav/maps/2-3.json +757 -0
- package/data/sources/kcnav/maps/2-4.json +817 -0
- package/data/sources/kcnav/maps/2-5.json +779 -0
- package/data/sources/kcnav/maps/3-1.json +379 -0
- package/data/sources/kcnav/maps/3-2.json +588 -0
- package/data/sources/kcnav/maps/3-3.json +654 -0
- package/data/sources/kcnav/maps/3-4.json +910 -0
- package/data/sources/kcnav/maps/3-5.json +643 -0
- package/data/sources/kcnav/maps/4-1.json +561 -0
- package/data/sources/kcnav/maps/4-2.json +664 -0
- package/data/sources/kcnav/maps/4-3.json +867 -0
- package/data/sources/kcnav/maps/4-4.json +690 -0
- package/data/sources/kcnav/maps/4-5.json +1232 -0
- package/data/sources/kcnav/maps/5-1.json +517 -0
- package/data/sources/kcnav/maps/5-2.json +791 -0
- package/data/sources/kcnav/maps/5-3.json +889 -0
- package/data/sources/kcnav/maps/5-4.json +851 -0
- package/data/sources/kcnav/maps/5-5.json +1070 -0
- package/data/sources/kcnav/maps/5-6.json +3200 -0
- package/data/sources/kcnav/maps/6-1.json +527 -0
- package/data/sources/kcnav/maps/6-2.json +717 -0
- package/data/sources/kcnav/maps/6-3.json +501 -0
- package/data/sources/kcnav/maps/6-4.json +870 -0
- package/data/sources/kcnav/maps/6-5.json +814 -0
- package/data/sources/kcnav/maps/7-1.json +640 -0
- package/data/sources/kcnav/maps/7-2.json +976 -0
- package/data/sources/kcnav/maps/7-3.json +1529 -0
- package/data/sources/kcnav/maps/7-4.json +1000 -0
- package/data/sources/kcnav/maps/7-5.json +1570 -0
- package/data/sources/kcnav/maps/manifest.json +340 -0
- package/data/sources/kcwiki/routes/1-1.wiki +2 -0
- package/data/sources/kcwiki/routes/1-2.wiki +1 -0
- package/data/sources/kcwiki/routes/1-3.wiki +1 -0
- package/data/sources/kcwiki/routes/1-4.wiki +1 -0
- package/data/sources/kcwiki/routes/1-5.wiki +1 -0
- package/data/sources/kcwiki/routes/1-6.wiki +1 -0
- package/data/sources/kcwiki/routes/2-1.wiki +1 -0
- package/data/sources/kcwiki/routes/2-2.wiki +1 -0
- package/data/sources/kcwiki/routes/2-3.wiki +1 -0
- package/data/sources/kcwiki/routes/2-4.wiki +81 -0
- package/data/sources/kcwiki/routes/2-5.wiki +1 -0
- package/data/sources/kcwiki/routes/3-1.wiki +1 -0
- package/data/sources/kcwiki/routes/3-2.wiki +1 -0
- package/data/sources/kcwiki/routes/3-3.wiki +1 -0
- package/data/sources/kcwiki/routes/3-4.wiki +1 -0
- package/data/sources/kcwiki/routes/3-5.wiki +1 -0
- package/data/sources/kcwiki/routes/4-1.wiki +1 -0
- package/data/sources/kcwiki/routes/4-2.wiki +1 -0
- package/data/sources/kcwiki/routes/4-3.wiki +1 -0
- package/data/sources/kcwiki/routes/4-4.wiki +1 -0
- package/data/sources/kcwiki/routes/4-5.wiki +1 -0
- package/data/sources/kcwiki/routes/5-1.wiki +57 -0
- package/data/sources/kcwiki/routes/5-2.wiki +1 -0
- package/data/sources/kcwiki/routes/5-3.wiki +1 -0
- package/data/sources/kcwiki/routes/5-4.wiki +1 -0
- package/data/sources/kcwiki/routes/5-5.wiki +80 -0
- package/data/sources/kcwiki/routes/5-6.wiki +753 -0
- package/data/sources/kcwiki/routes/6-1.wiki +1 -0
- package/data/sources/kcwiki/routes/6-2.wiki +1 -0
- package/data/sources/kcwiki/routes/6-3.wiki +1 -0
- package/data/sources/kcwiki/routes/6-4.wiki +1 -0
- package/data/sources/kcwiki/routes/6-5.wiki +1 -0
- package/data/sources/kcwiki/routes/7-1.wiki +1 -0
- package/data/sources/kcwiki/routes/7-2.wiki +1 -0
- package/data/sources/kcwiki/routes/7-3.wiki +1 -0
- package/data/sources/kcwiki/routes/7-4.wiki +1 -0
- package/data/sources/kcwiki/routes/7-5.wiki +1 -0
- package/data/sources/kcwiki/routes/README.md +11 -0
- package/data/sources/kcwiki/routes/manifest.json +450 -0
- package/docs/research.md +445 -0
- package/docs/sources.md +85 -0
- package/enemies.js +56 -0
- package/exporters.js +182 -0
- package/index.js +1081 -0
- package/logic.js +603 -0
- package/overview.js +54 -0
- package/package.json +66 -0
- package/scripts/cache-kcnav-enemies.js +97 -0
- package/scripts/cache-kcnav-maps.js +109 -0
- package/scripts/cache-kcwiki-routes.js +96 -0
- package/scripts/compact-kcnav-enemies.js +53 -0
- package/scripts/compress-kcnav-maps.js +90 -0
package/exporters.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { routeDecision } = require('./logic')
|
|
4
|
+
const { loadEnemies } = require('./enemies')
|
|
5
|
+
const nodeCatalog = require('./data/kcnav-node-types.json')
|
|
6
|
+
const nodeTypes = require('./data/kcnav-node-types-by-map.json')
|
|
7
|
+
const kc3Ids = require('./data/kc3kai-master-ids.json')
|
|
8
|
+
const kc3Stats = require('./data/kc3kai-ship-stats.json')
|
|
9
|
+
const kc3Ships = new Set(Object.keys(kc3Stats.ships).map(Number))
|
|
10
|
+
const kc3Equips = new Set(kc3Ids.equips)
|
|
11
|
+
const submarines = new Set(kc3Ids.submarines)
|
|
12
|
+
|
|
13
|
+
function enumerateRoutes(definition, geometry, context, overrides = {}) {
|
|
14
|
+
const routes = []
|
|
15
|
+
const blocked = new Set()
|
|
16
|
+
const edges = Object.values(geometry.route || {}).filter((edge) => edge[0] && edge[1])
|
|
17
|
+
const outgoing = new Set(edges.map(([from]) => from))
|
|
18
|
+
let visits = 0
|
|
19
|
+
function walk(node, nodes, probability, score, estimated) {
|
|
20
|
+
if (++visits > 10000) throw new Error('候选路线过多,请先在地图上指定部分能动分歧')
|
|
21
|
+
if (nodes.includes(node)) { blocked.add(node); return }
|
|
22
|
+
const path = [...nodes, node]
|
|
23
|
+
const decision = routeDecision(definition, node, { ...context, passedNodes: nodes }, overrides)
|
|
24
|
+
if (decision.status === 'terminal' || !outgoing.has(node) && !decision.outcomes.length && !decision.rule) {
|
|
25
|
+
routes.push({ key: path.join('>'), nodes: path, probability, score, estimated, boss: node === definition.boss })
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
const outcomes = decision.manualChoiceRequired ? decision.manualOutcomes || decision.baseOutcomes : decision.outcomes
|
|
29
|
+
if (decision.status === 'unknown' && !decision.manualChoiceRequired || !outcomes.length) { blocked.add(node); return }
|
|
30
|
+
for (const outcome of outcomes) {
|
|
31
|
+
if (outcome.probability === 0) continue
|
|
32
|
+
const virtualStart = node === '1' && outcome.to === '2' && ['6-4-start-right-lha', '6-4-start-right-heavy', '6-5-start-right'].includes(decision.rule?.id)
|
|
33
|
+
if (!virtualStart && !edges.some(([from, to]) => from === node && to === outcome.to)) { blocked.add(node); continue }
|
|
34
|
+
const p = decision.manualChoiceRequired ? null : outcome.probability
|
|
35
|
+
walk(outcome.to, path, probability == null || p == null ? null : probability * p,
|
|
36
|
+
score * (p ?? 1 / outcomes.length), estimated || outcome.estimated === true)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
walk(definition.start, [], 1, 1, false)
|
|
40
|
+
routes.sort((a, b) => Number(b.boss) - Number(a.boss) || b.score - a.score || a.key.localeCompare(b.key))
|
|
41
|
+
return { routes, blocked: [...blocked] }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function battleNodes(mapId, route, geometry, loader = loadEnemies) {
|
|
45
|
+
return route.nodes.flatMap((node, index) => {
|
|
46
|
+
const type = nodeTypes[mapId]?.[node]
|
|
47
|
+
if (!nodeCatalog[type]?.hasEnemies) return []
|
|
48
|
+
const edge = Object.entries(geometry.route).find(([, value]) => value[0] === route.nodes[index - 1] && value[1] === node)
|
|
49
|
+
if (!edge) throw new Error(`${node} 点缺少实际路线编号`)
|
|
50
|
+
const data = loader(mapId, node)
|
|
51
|
+
const rows = data.status === 'ready' ? data.rows.filter((entry) => entry.count > 0) : []
|
|
52
|
+
const subOnly = rows.length > 0 && rows.every((entry) => [...entry.mainFleet, ...entry.escortFleet].every((ship) => submarines.has(ship.id)))
|
|
53
|
+
return [{ node, cell: Number(edge[0]), type, rows, subOnly, formation: subOnly ? 5 : [7, 10].includes(type) ? 3 : 1 }]
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function required(value, label) {
|
|
58
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) throw new Error(`poi 数据不可用:${label}`)
|
|
59
|
+
return value
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function playerFleet(state, deckId = 1) {
|
|
63
|
+
const fleet = state.info?.fleets?.[deckId - 1]
|
|
64
|
+
if (!Array.isArray(fleet?.api_ship)) throw new Error(`poi 数据不可用:舰队 ${deckId}`)
|
|
65
|
+
const ships = fleet.api_ship.filter((id) => id > 0).map((id) => {
|
|
66
|
+
const ship = state.info?.ships?.[id]
|
|
67
|
+
const master = state.const?.$ships?.[ship?.api_ship_id]
|
|
68
|
+
if (!ship || !master || !Array.isArray(ship.api_slot) || !Array.isArray(ship.api_onslot) || !Array.isArray(ship.api_kyouka)) throw new Error(`poi 数据不可用:舰娘 #${id}`)
|
|
69
|
+
const slotCount = required(ship.api_slotnum, '装备槽数')
|
|
70
|
+
const items = [...ship.api_slot.slice(0, slotCount), ship.api_slot_ex ?? -1].map((equipId, index) => {
|
|
71
|
+
if (equipId <= 0) return null
|
|
72
|
+
const equip = state.info?.equips?.[equipId]
|
|
73
|
+
const equipMaster = state.const?.$equips?.[equip?.api_slotitem_id]
|
|
74
|
+
if (!equip || !equipMaster) throw new Error(`poi 数据不可用:装备 #${equipId}`)
|
|
75
|
+
return { id: equip.api_slotitem_id, rf: required(equip.api_level, '装备改修'), mas: equip.api_alv ?? 0, ac: index < slotCount ? required(ship.api_onslot[index], '当前搭载') : 0 }
|
|
76
|
+
})
|
|
77
|
+
const level = required(ship.api_lv, '等级')
|
|
78
|
+
const statsBase = {}
|
|
79
|
+
for (const [key, field, mod] of [['fp', 'api_houg', 0], ['tp', 'api_raig', 1], ['aa', 'api_tyku', 2], ['ar', 'api_souk', 3]]) {
|
|
80
|
+
statsBase[key] = required(master[field]?.[0], field) + required(ship.api_kyouka[mod], '近代化改修')
|
|
81
|
+
}
|
|
82
|
+
statsBase.luk = required(ship.api_lucky?.[0], '运')
|
|
83
|
+
return { ship, master, items, slotCount, level, statsBase }
|
|
84
|
+
})
|
|
85
|
+
if (!ships.length || ships.length > 6) throw new Error('仅支持所选舰队的 1~6 艘单舰队导出')
|
|
86
|
+
return { ships, admiralLevel: required(state.info?.basic?.api_level, '司令部等级') }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function validateBattles(battles) {
|
|
90
|
+
if (!battles.length) throw new Error('此路线没有战斗节点')
|
|
91
|
+
const missing = battles.filter((battle) => !battle.rows.length)
|
|
92
|
+
if (missing.length) throw new Error(`${missing.map((b) => b.node).join('、')} 点尚未缓存或本月无敌编成样本`)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function kc3Enemy(ship) {
|
|
96
|
+
if (!kc3Ships.has(ship.id)) throw new Error(`KC3Kai 数据未收录敌舰 #${ship.id}`)
|
|
97
|
+
const equips = ship.equips.filter((id) => id > 0).map((id) => ({ mstId: id > 500 && id < 1000 ? id + 1000 : id, rank: 0 }))
|
|
98
|
+
if (ship.exslot > 0) equips.push({ mstId: ship.exslot, rank: 0 })
|
|
99
|
+
for (const equip of equips) if (!kc3Equips.has(equip.mstId)) throw new Error(`KC3Kai 数据未收录装备 #${equip.mstId}`)
|
|
100
|
+
return { mstId: ship.id, level: ship.lvl, hp: ship.hp, hpInit: ship.hp,
|
|
101
|
+
statsBase: { fp: ship.fp, tp: ship.torp, aa: ship.aa, ar: ship.armor }, equips }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function kc3Save(state, mapId, battles, formations = {}, deckId = 1) {
|
|
105
|
+
validateBattles(battles)
|
|
106
|
+
if (battles.length > 9) throw new Error('KC3Kai 最多支持 9 个战斗节点')
|
|
107
|
+
const excessive = battles.find((battle) => battle.rows.length > 12)
|
|
108
|
+
if (excessive) throw new Error(`KC3Kai 每节点最多支持 12 套敌编成,${excessive.node} 点有 ${excessive.rows.length} 套;请改用 noro6 选择单套编成`)
|
|
109
|
+
const unknownType = battles.find((battle) => ![4, 5, 7, 10, 11].includes(battle.type))
|
|
110
|
+
if (unknownType) throw new Error(`${unknownType.node} 点战斗类型尚未适配 KC3Kai`)
|
|
111
|
+
const { ships } = playerFleet(state, deckId)
|
|
112
|
+
const players = ships.map(({ ship, master, items, slotCount, level, statsBase }) => {
|
|
113
|
+
if (!kc3Ships.has(master.api_id)) throw new Error(`KC3Kai 数据未收录舰娘 #${master.api_id}`)
|
|
114
|
+
for (const item of items) if (item && !kc3Equips.has(item.id)) throw new Error(`KC3Kai 数据未收录装备 #${item.id}`)
|
|
115
|
+
// Missing EV/LOS/ASW are derived by KC3Kai from level. Only override ASW
|
|
116
|
+
// when modernization cannot be represented by level alone.
|
|
117
|
+
const aswModernization = required(ship.api_kyouka[6], '对潜改修')
|
|
118
|
+
const exportedStats = { ...statsBase }
|
|
119
|
+
if (aswModernization > 0) {
|
|
120
|
+
const growth = kc3Stats.ships[master.api_id]
|
|
121
|
+
if (!Number.isFinite(growth?.ASWbase) || !Number.isFinite(growth?.ASW)) throw new Error(`KC3Kai 本地缓存缺少 #${master.api_id} 对潜成长数据`)
|
|
122
|
+
exportedStats.asw = growth.ASWbase + Math.floor((growth.ASW - growth.ASWbase) * level / 99) + aswModernization
|
|
123
|
+
}
|
|
124
|
+
return { mstId: master.api_id, level, hp: required(ship.api_maxhp, '最大耐久'), hpInit: required(ship.api_nowhp, '当前耐久'),
|
|
125
|
+
morale: required(ship.api_cond, '士气'), fuelInit: required(ship.api_fuel, '燃油') / required(master.api_fuel_max, '燃油上限') * 100,
|
|
126
|
+
ammoInit: required(ship.api_bull, '弹药') / required(master.api_bull_max, '弹药上限') * 100,
|
|
127
|
+
statsBase: exportedStats, slots: ship.api_onslot.slice(0, slotCount),
|
|
128
|
+
equips: items.map((item) => item ? { mstId: item.id, level: item.rf, rank: item.mas } : null) }
|
|
129
|
+
})
|
|
130
|
+
return {
|
|
131
|
+
version: 2, fleetFMain: { version: 2, type: 0, formation: 1, ships: players },
|
|
132
|
+
useSupportN: false, useSupportB: false, useFF: false, fleetsFFriend: [], landBases: [],
|
|
133
|
+
settings: { airRaidCostW6: mapId.startsWith('6-') },
|
|
134
|
+
battles: battles.map((battle, index) => ({
|
|
135
|
+
id: index + 1, ind: index, formation: Number(formations[battle.node] || battle.formation),
|
|
136
|
+
nodeType: ({ 11: 2, 7: 4, 10: 6 })[battle.type] || 1,
|
|
137
|
+
doNB: battle.type === 5, doNBCond: '', subOnly: battle.subOnly,
|
|
138
|
+
lbasWaves: [false, false, false, false, false, false],
|
|
139
|
+
enemyComps: battle.rows.map((entry, compIndex) => ({ num: compIndex + 1, rate: entry.count,
|
|
140
|
+
fleet: { version: 2, type: entry.escortFleet.length ? 1 : 0, formation: entry.formation,
|
|
141
|
+
ships: entry.mainFleet.map(kc3Enemy), ...(entry.escortFleet.length ? { shipsEscort: entry.escortFleet.map(kc3Enemy) } : {}) } })),
|
|
142
|
+
})),
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function noroDeck(state, mapId, battles, selected = {}, formations = {}, deckId = 1) {
|
|
147
|
+
validateBattles(battles)
|
|
148
|
+
const { ships, admiralLevel } = playerFleet(state, deckId)
|
|
149
|
+
const f1 = { name: `舰队 ${deckId}`, t: 0 }
|
|
150
|
+
ships.forEach(({ ship, master, level, items, slotCount }, index) => {
|
|
151
|
+
const equipment = {}
|
|
152
|
+
items.forEach((item, i) => { if (item) equipment[i === slotCount ? 'ix' : `i${i + 1}`] = item })
|
|
153
|
+
f1[`s${index + 1}`] = { id: master.api_id, lv: level, luck: ship.api_lucky[0], hp: ship.api_maxhp,
|
|
154
|
+
asw: required(ship.api_taisen?.[0], '对潜'), exa: ship.api_slot_ex !== 0, items: equipment }
|
|
155
|
+
})
|
|
156
|
+
const [a, i] = mapId.split('-').map(Number)
|
|
157
|
+
const fleet = (shipsE) => ({ s: shipsE.map((ship) => ({ id: ship.id, items: ship.equips.filter((id) => id > 0).map((id) => ({ id })) })) })
|
|
158
|
+
return { version: 4, hqlv: admiralLevel, f1, s: { a, i, c: battles.map((battle) => {
|
|
159
|
+
const entry = battle.rows.find((row) => compositionKey(row) === selected[battle.node]) || battle.rows[0]
|
|
160
|
+
return { c: battle.cell, pf: Number(formations[battle.node] || battle.formation), ef: entry.formation,
|
|
161
|
+
f1: fleet(entry.mainFleet), ...(entry.escortFleet.length ? { f2: fleet(entry.escortFleet) } : {}) }
|
|
162
|
+
}) } }
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function compositionKey(entry) {
|
|
166
|
+
return JSON.stringify([entry.masterId, entry.formation, entry.mainFleet, entry.escortFleet])
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function kc3Url(save) {
|
|
170
|
+
return new Promise((resolve, reject) => {
|
|
171
|
+
require('lzma').compress(JSON.stringify(save), 1, (bytes, error) => {
|
|
172
|
+
if (error) reject(error)
|
|
173
|
+
else resolve(`https://kc3kai.github.io/kancolle-replay/simulator.html#backup=${Buffer.from(bytes).toString('base64')}`)
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function noroUrl(deck) {
|
|
179
|
+
return `https://noro6.github.io/kc-web/?predeck=${encodeURIComponent(JSON.stringify(deck))}#/`
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
module.exports = { enumerateRoutes, battleNodes, playerFleet, kc3Save, noroDeck, compositionKey, kc3Url, noroUrl }
|