diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4e74cb8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Python +*.pyc +*.pyo +build/ +dist/ +.venv +__pycache__ + +# Nix +result +result-* + +# Ignore generated files by default +/mapcrafter +/bluemap diff --git a/README.md b/README.md new file mode 100644 index 0000000..8a9fbb6 --- /dev/null +++ b/README.md @@ -0,0 +1,112 @@ +# minecraft-kartverket + +Map markers for PVV's minecraft server + +## What is this? + +This project is meant to let PVV members contribute map data for PVV's minecraft server, like coordinates for bases, cities, and other points of interest. +These markers are written in python so that we can do things like generating points in a loop, calculating distances, and other types of automation. + +There is also a cli tool that we use to export these points into the formats of several minecraft map implementations. + +## Marker sets + +Here is an overview of the different marker sets, and what they are meant for. + +- **Overworld** + - Area Names: larger areas with names + - Buildings: important buildings and world wonders. + - Cities: an area that consist of several bases and/or public infrastructure. + - Homes: single bases consisting of 1-3 people. + - Huts: small huts, meant for visitors and travelers. + - Infrastructure: public infrastructure, like bridges, ports, tunnels, etc. + - Mines: public mines + - Nature: similar to "Area Names", but specifically for mostly untouched nature-named areas. + - Other: anything that doesn't fit into the other categories + - Railways: railways + - Roads: roads + - Villages: villages generated by minecraft (as opposed to player made cities) + +- **Nether** + - Ice Tracks: ice tracks meant for boats. + - Other: anything that doesn't fit into the other categories + - Portals: named portals that lead back to the overworld. + - Railways: railways + +- **The End** + - Other: anything that doesn't fit into the other categories + - Portals: end portals that send you back to the center of the map + +## How to add a point marker + +1. Find the correct marker set file in `src/marker_sets/`. +2. Add the marker to the list in the file. You can look at neighbouring markers for inspiration. +3. Run the cli tool to verify that the marker has been added correctly. + +```bash +uv run mckart verify +uv run mckart print +``` + +4. Open a PR + +## How to add a railway / road + +This is very similar to adding a point marker, but the content of the marker is different. + +You can follow the previous guide, but for step 3, use this template or look at other markers for inspiration. + +```python +from lib_marker import Track + +MARKERS = [ + ..., + Track( + name="Nordbanen", + points = [ + (848, 70, 1583), + (920, 70, 1583), + (920, 70, 1200), + ... + ], + ), + ..., +] +``` + +## How to add a new marker set + +To add a new marker set, you need to: + +1. Create a new file the other marker sets in `src/marker_sets/`. +2. Create a marker set in this file, using this template: + +```python +from lib_marker.marker_set import MarkerSet + +MARKER_SET = MarkerSet( + name="My Marker Set", + markers=[ + ], +) +``` + +3. Add the marker set to the `MARKER_SETS` list in `src/marker_sets//__init__.py`. + +```python +from . import MARKER_SET as _marker_set + +MARKER_SETS = [ + ... + portals_marker_set, +] +``` + +See the other marker sets for inspiration. + +4. Add the marker set with a description to this README file. + +## See also + +- [BlueMap documentation for markers](https://bluemap.bluecolored.de/wiki/customization/Markers.html) +- [Mapcrafter documentation for markers](https://mapcrafter.readthedocs.io/en/latest/markers.html) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..4e45c8a --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1762482733, + "narHash": "sha256-g/da4FzvckvbiZT075Sb1/YDNDr+tGQgh4N8i5ceYMg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e1ebeec86b771e9d387dd02d82ffdc77ac753abc", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix index e7784aa..ca8ee8b 100644 --- a/flake.nix +++ b/flake.nix @@ -1,7 +1,122 @@ { - inputs = { }; - outputs = inputs@{ self, ...}: { - map-markers = import ./map-markers; - map-lib = import ./map-markers/lib.nix; + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + outputs = { self, nixpkgs }: let + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + + forAllSystems = f: nixpkgs.lib.genAttrs systems (system: let + pkgs = nixpkgs.legacyPackages.${system}; + in f system pkgs); + + inherit (nixpkgs) lib; + + in { + apps = forAllSystems (system: pkgs: { + default = { + type = "app"; + program = lib.getExe self.packages.${system}.default; + meta.description = "The 'mckart' cli tool with all map data embedded"; + }; + }); + + devShells = forAllSystems (_: pkgs: { + default = pkgs.mkShell { + packages = with pkgs; [ + uv + ruff + python3 + # (python3.withPackages (ps: with ps; [])) + biome + ]; + }; + }); + + overlays.default = final: prev: self.packages.${final.system}; + + checks = forAllSystems (system: pkgs: { + inherit (self.packages.${system}) bluemap-export mapcrafter-export; + + hocon-include = let + format = pkgs.formats.hocon { }; + in format.generate "minecraft-kartverket-test-hocon-include" { + _includes = [ + (format.lib.mkInclude "${self.packages.${system}.bluemap-export}/overworld.hocon") + (format.lib.mkInclude "${self.packages.${system}.bluemap-export}/nether.hocon") + (format.lib.mkInclude "${self.packages.${system}.bluemap-export}/the-end.hocon") + ]; + }; + }); + + packages = forAllSystems (system: pkgs: { + default = self.packages.${system}.mckart; + + mckart = let + pyproject = builtins.fromTOML (builtins.readFile ./pyproject.toml); + in with pkgs.python3Packages; buildPythonPackage { + pname = pyproject.project.name; + version = pyproject.project.version; + src = lib.cleanSource ./.; + + format = "pyproject"; + + build-system = [ hatchling ]; + dependencies = []; + + meta.mainProgram = "mckart"; + }; + + bluemap-export = let + # from pkgs/pkgs-lib/formats/hocon/default.nix + hocon-validator = + pkgs.writers.writePython3Bin "hocon-validator" + { + libraries = [ pkgs.python3Packages.pyhocon ]; + } + '' + from sys import argv + from pyhocon import ConfigFactory + + if not len(argv) == 2: + print("USAGE: hocon-validator ") + + ConfigFactory.parse_file(argv[1]) + ''; + in pkgs.runCommand "bluemap-export" { + nativeBuildInputs = [ + (self.packages.${system}.mckart) + hocon-validator + ]; + } '' + mckart export-bluemap --output-dir "$out" + + for file in "$out"/*.hocon; do + hocon-validator "$file" + done + ''; + + mapcrafter-export = pkgs.runCommand "mapcrafter-export" { + buildInputs = [ + (self.packages.${system}.mckart) + pkgs.biome + ]; + + biomeConf = builtins.toJSON { + formatter = { + indentStyle = "space"; + lineWidth = 100; + }; + }; + passAsFile = [ "biomeConf" ]; + } '' + mckart export-mapcrafter --output-dir "$out" + cp "$biomeConfPath" ./biome.json + biome format --config-path=./biome.json "$out"/* --write + ''; + }); }; } diff --git a/icons/.gitkeep b/icons/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/map-markers/default.nix b/map-markers/default.nix deleted file mode 100644 index 180d065..0000000 --- a/map-markers/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -let - lib = import ./lib.nix; - icons = import ./icons; -in { - vanillaSurvival = import ./vanillaSurvival { inherit lib icons; }; -} diff --git a/map-markers/lib.nix b/map-markers/lib.nix deleted file mode 100644 index c6dd773..0000000 --- a/map-markers/lib.nix +++ /dev/null @@ -1,11 +0,0 @@ -rec { - mkPoi = label: pos: attr: { - type = "poi"; - position = { - x = builtins.elemAt pos 0; - y = builtins.elemAt pos 2; - z = builtins.elemAt pos 1; - }; - label = label; - } // attr; -} diff --git a/map-markers/mapcrafter/markers.js b/map-markers/mapcrafter/markers.js deleted file mode 100644 index a5d4e39..0000000 --- a/map-markers/mapcrafter/markers.js +++ /dev/null @@ -1,380 +0,0 @@ -var MAPCRAFTER_MARKERS = [ - { - "id" : "byer", - "name" : "Byer og steder", - "showDefault" : true, - "markers" : { - "verden" : [ - // Sorter markoerene etter lengdegrad. - { - "pos" : [-2204, 447, 64], - "title" : "Vestlandet", - }, - { - "pos" : [-1818, 98, 64], - "title" : "Vestsumpland", - }, - { - "pos" : [-1760, -2440, 64], - "title" : "Smedby", - }, - { - "pos" : [-1654, -654, 64], - "title" : "Snøklippan", - }, - { - "pos" : [-1563, -1966, 64], - "title" : "Dypskiferhytta", - }, - { - "pos" : [-1189, 1556, 75], - "title" : "England", - }, - { - "pos" : [-980, 4090, 64], - "title" : "Hemmelig mesabiom", - }, - { - "pos" : [-800, 0, 64], - "title" : "Vestisødet", - }, - { - "pos" : [-378, 153, 64], - "title" : "Isjungelkatedralen", - }, - { - "pos" : [-370, 2390, 64], - "title" : "Svartskoghavn", - }, - { - "pos" : [-334, 473, 116], - "title" : "Kystbasen", - }, - { - "pos" : [-305, 535, 64], - "title" : "Langstrand", - }, - { - "pos" : [-220, 2890, 64], - "title" : "Summefjord", - }, - { - "pos" : [-206, -35, 64], - "title" : "Slimegruva", - }, - { - "pos" : [-160, 1480, 64], - "title" : "Turrikkelmyra", - }, - { - "pos" : [-128, -1460, 64], - "title" : "Akasienborg", - }, - { - "pos" : [-110, 3465, 64], - "title" : "Summevatn", - }, - { - "pos" : [-99, 1025, 99], - "title" : "Tegltårnet", - }, - { - "pos" : [-54, 234, 64], - "title" : "Huløyeid", - }, - { - "pos" : [-47, 146, 64], - "title" : "Trangdalen", - }, - { - "pos" : [-22, 67, 76], - "title" : "Tårnodden", - }, - { - "pos" : [0, -485, 67], - "title" : "Nordørkenen", - }, - { - "pos" : [4, 800, 64], - "title" : "Naturreservat", - }, - { - "pos" : [56, -266, 67], - "title" : "Sandsteingruva", - }, - { - "pos" : [58, -2860, 63], - "title" : "Tangen", - }, - { - "pos" : [77, -348, 69], - "title" : "Smalelvbro", - }, - { - "pos" : [100, -3830, 64], - "title" : "Ittoqqortoormiit", - }, - { - "pos" : [102, 37, 77], - "title" : "Bjerkepalasset", - }, - { - "pos" : [150, 80, 64], - "title" : "Piratbukta", - }, - { - "pos" : [177, 177, 64], - "title" : "Heimfjell", - }, - { - "pos" : [240, 3070, 64], - "title" : "Hulevatna", - }, - { - "pos" : [267, -496, 89], - "title" : "Hodeskallegrotten", - }, - { - "pos" : [280, -2800, 64], - "title" : "Jesus Christ Superstore", - }, - { - "pos" : [337, -853, 64], - "title" : "NPC-landsby nord", - }, - { - "pos" : [360, -460, 64], - "title" : "Vikingelandsbyen", - }, - { - "pos" : [473, -3043, 78], - "title" : "Bjørnebukten", - }, - { - "pos" : [512, -3320, 64], - "title" : "Leirhavn", - }, - { - "pos" : [550, -1480, 64], - "title" : "Grensebuelvbu", - }, - { - "pos" : [675, 362, 64], - "title" : "Storvatnet", - }, - { - "pos" : [695, 2812, 64], - "title" : "Kløfteby", - }, - { - "pos" : [723, -2380, 64], - "title" : "Isbjørnby", - }, - { - "pos" : [730, -1900, 64], - "title" : "Lille isbjørnelv", - }, - { - "pos" : [800, -3300, 64], - "title" : "Gammelleirnes", - }, - { - "pos" : [834, -3089, 65], - "title" : "Biosfæren", - }, - { - "pos" : [848, 1583, 70], - "title" : "Nyverdenhytta", - }, - { - "pos" : [850, -2130, 64], - "title" : "Store isbjørnelv", - }, - { - "pos" : [874, 160, 65], - "title" : "Blindodden", - }, - { - "pos" : [910, 3050, 64], - "title" : "Ulveelva", - }, - { - "pos" : [960, 460, 64], - "title" : "Tosjødalen", - }, - { - "pos" : [1005, 1335, 64], - "title" : "Storhavskanalen", - }, - { - "pos" : [1278, -397, 64], - "title" : "NPC-landsby", - }, - { - "pos" : [1570, 3285, 64], - "title" : "SuperTheodors fiskehus", - }, - { - "pos" : [1810, -1630, 64], - "title" : "Lamafjellet", - }, - { - "pos" : [2111, 3777, 64], - "title" : "SuperTheodors strand", - }, - { - "pos" : [2300, 250, 64], - "title" : "Andøya", - }, - { - "pos" : [2350, -136, 64], - "title" : "Grantrebukta", - }, - { - "pos" : [2734, -984, 64], - "title" : "Hestelandsby", - }, - { - "pos" : [2950, 270, 64], - "title" : "Bikkjeby", - }, - { - "pos" : [3000, 1000, 64], - "title" : "Storhavet i øst", - }, - { - "pos" : [3085, 424, 64], - "title" : "Fyret", - }, - { - "pos" : [3481, 210, 75], - "title" : "Vinterstranda hotel & resort", - }, - { - "pos" : [4468, 1337, 64], - "title" : "Holmgard", - }, - { - "pos" : [4630, 270, 64], - "title" : "Der Kölner Dom", - }, - { - "pos" : [5470, -270, 64], - "title" : "Storsnøfjella", - }, - { - "pos" : [6200, -300, 64], - "title" : "Bondeby", - }, - { - "pos" : [6880, -465, 64], - "title" : "Kirkemyr", - }, - ], - "underverden" : [ - // Sorter markoerene etter lengdegrad. - { - "pos" : [-900, 27, 64], - "title" : "Grisebukta", - }, - { - "pos" : [-120, 510, 64], - "title" : "Hemmelig mesabiom, ca.", - }, - { - "pos" : [120, -420, 64], - "title" : "Biosfæren, ca.", - }, - { - "pos" : [520, 220, 64], - "title" : "Holmgard, ca.", - }, - ], - }, - }, - { - "id" : "spesial", - "name" : "Spesielle steder", - "showDefault" : true, - "icon" : "marker-icon-green.png", - "iconSize" : [25, 41], - "markers" : { - "verden" : [ - { - "pos" : [0, 0, 64], - "title" : "Nullpunkt", - }, - ], - "underverden" : [ - { - "pos" : [0, 0, 64], - "title" : "Nullpunkt", - }, - ], - }, - }, - { - // - // Tegner et rutenett som viser regiongrensene, og - // koordinatene for hver region. - // - "id" : "regioner", - "name" : "Regioner", - "showDefault" : false, - "createMarker" : function(ui, groupInfo, markerInfo) { - var rmax = 15; - var objekter = []; - - var multilatlngs = []; - - for (var rx = -rmax; rx < rmax; rx++) { - var latlngs = []; - var miny = -rmax*512; - var maxy = rmax*512; - var x = rx*512; - // use the ui.mcToLatLng-function to convert Minecraft coords to LatLngs - latlngs.push(ui.mcToLatLng(x, miny, 64)); - latlngs.push(ui.mcToLatLng(x, maxy, 64)); - multilatlngs.push(latlngs); - } - - for (var ry = -rmax; ry < rmax; ry++) { - var latlngs = []; - var minx = -rmax*512; - var maxx = rmax*512; - var y = ry*512; - // use the ui.mcToLatLng-function to convert Minecraft coords to LatLngs - latlngs.push(ui.mcToLatLng(minx, y, 64)); - latlngs.push(ui.mcToLatLng(maxx, y, 64)); - multilatlngs.push(latlngs); - } - - for (var rx = -rmax; rx < rmax; rx++) { - for (var ry = -rmax; ry < rmax; ry++) { - var x = rx*512 + 256; - var y = ry*512 + 256; - - var myIcon = L.divIcon({iconSize: L.point(55, 20), html: "
r." + String(rx) + "." + String(ry) + "
"}); - var myMarker = L.marker(ui.mcToLatLng(x, y, 64), {icon: myIcon}); - objekter.push(myMarker); - } - } - - var linjer = []; - if (L.version.startsWith("0.7.")) { - linjer = L.multiPolyline(multilatlngs, {"color" : markerInfo.color}); - } else { - linjer = L.polyline(multilatlngs, {"color" : markerInfo.color}); - } - objekter.push(linjer); - return L.layerGroup(objekter); - }, - "markers" : { - "verden" : [ - { - "color" : "yellow", - }, - ], - }, - }, -]; diff --git a/map-markers/vanillaSurvival/default.nix b/map-markers/vanillaSurvival/default.nix deleted file mode 100644 index 78836f0..0000000 --- a/map-markers/vanillaSurvival/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{ lib, icons, ... }: - -{ - verden = import ./verden { inherit lib icons; }; - underverden = import ./underverden { inherit lib icons; }; - # enden = import ./enden { inherit lib icons; }; -} diff --git a/map-markers/vanillaSurvival/underverden/byer.nix b/map-markers/vanillaSurvival/underverden/byer.nix deleted file mode 100644 index d8239b0..0000000 --- a/map-markers/vanillaSurvival/underverden/byer.nix +++ /dev/null @@ -1,8 +0,0 @@ -{ lib, icons }: - -{ - "Grisebukta" = lib.mkPoi "Grisebukta" [(-900) (27) (64)] { }; - "Hemmelig mesabiom, ca." = lib.mkPoi "Hemmelig mesabiom, ca." [(-120) (510) (64)] { }; - "Biosfæren, ca." = lib.mkPoi "Biosfæren, ca." [(120) (-420) (64)] { }; - "Holmgard, ca." = lib.mkPoi "Holmgard, ca." [(520) (220) (64)] { }; -} diff --git a/map-markers/vanillaSurvival/underverden/default.nix b/map-markers/vanillaSurvival/underverden/default.nix deleted file mode 100644 index 78a934f..0000000 --- a/map-markers/vanillaSurvival/underverden/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ lib, icons }: - -{ - byer = import ./byer.nix { inherit lib icons; }; - spesial = import ./spesial.nix { inherit lib icons; }; -} diff --git a/map-markers/vanillaSurvival/underverden/spesial.nix b/map-markers/vanillaSurvival/underverden/spesial.nix deleted file mode 100644 index 78d086c..0000000 --- a/map-markers/vanillaSurvival/underverden/spesial.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ lib, icons }: - -{ - label = "Spesielle steder"; - toggleable = true; - default-hidden = false; - sorting = 100; - - markers = { - nullpunkt = lib.mkPoi "Nullpunkt" [0 0 64] { /*icon = icons.green*/ }; - }; -} diff --git a/map-markers/vanillaSurvival/verden/byer.nix b/map-markers/vanillaSurvival/verden/byer.nix deleted file mode 100644 index ca5c0ec..0000000 --- a/map-markers/vanillaSurvival/verden/byer.nix +++ /dev/null @@ -1,76 +0,0 @@ -{ lib, ... }: - -{ - label = "Byer og steder"; - toggleable = true; - default-hidden = false; - sorting = 0; - markers = { - "Vestlandet" = lib.mkPoi "Vestlandet" [(-2204) (447) (64)] { }; - "Vestsumpland" = lib.mkPoi "Vestsumpland" [(-1818) (98) (64)] { }; - "Smedby" = lib.mkPoi "Smedby" [(-1760) (-2440) (64)] { }; - "Snøklippan" = lib.mkPoi "Snøklippan" [(-1654) (-654) (64)] { }; - "Dypskiferhytta" = lib.mkPoi "Dypskiferhytta" [(-1563) (-1966) (64)] { }; - "England" = lib.mkPoi "England" [(-1189) (1556) (75)] { }; - "Hemmelig mesabiom" = lib.mkPoi "Hemmelig mesabiom" [(-980) (4090) (64)] { }; - "Vestisødet" = lib.mkPoi "Vestisødet" [(-800) (0) (64)] { }; - "Isjungelkatedralen" = lib.mkPoi "Isjungelkatedralen" [(-378) (153) (64)] { }; - "Svartskoghavn" = lib.mkPoi "Svartskoghavn" [(-370) (2390) (64)] { }; - "Kystbasen" = lib.mkPoi "Kystbasen" [(-334) (473) (116)] { }; - "Langstrand" = lib.mkPoi "Langstrand" [(-305) (535) (64)] { }; - "Summefjord" = lib.mkPoi "Summefjord" [(-220) (2890) (64)] { }; - "Slimegruva" = lib.mkPoi "Slimegruva" [(-206) (-35) (64)] { }; - "Turrikkelmyra" = lib.mkPoi "Turrikkelmyra" [(-160) (1480) (64)] { }; - "Akasienborg" = lib.mkPoi "Akasienborg" [(-128) (-1460) (64)] { }; - "Summevatn" = lib.mkPoi "Summevatn" [(-110) (3465) (64)] { }; - "Tegltårnet" = lib.mkPoi "Tegltårnet" [(-99) (1025) (99)] { }; - "Huløyeid" = lib.mkPoi "Huløyeid" [(-54) (234) (64)] { }; - "Trangdalen" = lib.mkPoi "Trangdalen" [(-47) (146) (64)] { }; - "Tårnodden" = lib.mkPoi "Tårnodden" [(-22) (67) (76)] { }; - "Nordørkenen" = lib.mkPoi "Nordørkenen" [(0) (-485) (67)] { }; - "Naturreservat" = lib.mkPoi "Naturreservat" [(4) (800) (64)] { }; - "Sandsteingruva" = lib.mkPoi "Sandsteingruva" [(56) (-266) (67)] { }; - "Tangen" = lib.mkPoi "Tangen" [(58) (-2860) (63)] { }; - "Smalelvbro" = lib.mkPoi "Smalelvbro" [(77) (-348) (69)] { }; - "Ittoqqortoormiit" = lib.mkPoi "Ittoqqortoormiit" [(100) (-3830) (64)] { }; - "Bjerkepalasset" = lib.mkPoi "Bjerkepalasset" [(102) (37) (77)] { }; - "Piratbukta" = lib.mkPoi "Piratbukta" [(150) (80) (64)] { }; - "Heimfjell" = lib.mkPoi "Heimfjell" [(177) (177) (64)] { }; - "Hulevatna" = lib.mkPoi "Hulevatna" [(240) (3070) (64)] { }; - "Hodeskallegrotten" = lib.mkPoi "Hodeskallegrotten" [(267) (-496) (89)] { }; - "Jesus Christ Superstore" = lib.mkPoi "Jesus Christ Superstore" [(280) (-2800) (64)] { }; - "NPC-landsby nord" = lib.mkPoi "NPC-landsby nord" [(337) (-853) (64)] { }; - "Vikingelandsbyen" = lib.mkPoi "Vikingelandsbyen" [(360) (-460) (64)] { }; - "Bjørnebukten" = lib.mkPoi "Bjørnebukten" [(473) (-3043) (78)] { }; - "Leirhavn" = lib.mkPoi "Leirhavn" [(512) (-3320) (64)] { }; - "Grensebuelvbu" = lib.mkPoi "Grensebuelvbu" [(550) (-1480) (64)] { }; - "Storvatnet" = lib.mkPoi "Storvatnet" [(675) (362) (64)] { }; - "Kløfteby" = lib.mkPoi "Kløfteby" [(695) (2812) (64)] { }; - "Isbjørnby" = lib.mkPoi "Isbjørnby" [(723) (-2380) (64)] { }; - "Lille isbjørnelv" = lib.mkPoi "Lille isbjørnelv" [(730) (-1900) (64)] { }; - "Gammelleirnes" = lib.mkPoi "Gammelleirnes" [(800) (-3300) (64)] { }; - "Biosfæren" = lib.mkPoi "Biosfæren" [(834) (-3089) (65)] { }; - "Nyverdenhytta" = lib.mkPoi "Nyverdenhytta" [(848) (1583) (70)] { }; - "Store isbjørnelv" = lib.mkPoi "Store isbjørnelv" [(850) (-2130) (64)] { }; - "Blindodden" = lib.mkPoi "Blindodden" [(874) (160) (65)] { }; - "Ulveelva" = lib.mkPoi "Ulveelva" [(910) (3050) (64)] { }; - "Tosjødalen" = lib.mkPoi "Tosjødalen" [(960) (460) (64)] { }; - "Storhavskanalen" = lib.mkPoi "Storhavskanalen" [(1005) (1335) (64)] { }; - "NPC-landsby" = lib.mkPoi "NPC-landsby" [(1278) (-397) (64)] { }; - "SuperTheodors fiskehus" = lib.mkPoi "SuperTheodors fiskehus" [(1570) (3285) (64)] { }; - "Lamafjellet" = lib.mkPoi "Lamafjellet" [(1810) (-1630) (64)] { }; - "SuperTheodors strand" = lib.mkPoi "SuperTheodors strand" [(2111) (3777) (64)] { }; - "Andøya" = lib.mkPoi "Andøya" [(2300) (250) (64)] { }; - "Grantrebukta" = lib.mkPoi "Grantrebukta" [(2350) (-136) (64)] { }; - "Hestelandsby" = lib.mkPoi "Hestelandsby" [(2734) (-984) (64)] { }; - "Bikkjeby" = lib.mkPoi "Bikkjeby" [(2950) (270) (64)] { }; - "Storhavet i øst" = lib.mkPoi "Storhavet i øst" [(3000) (1000) (64)] { }; - "Fyret" = lib.mkPoi "Fyret" [(3085) (424) (64)] { }; - "Vinterstranda hotel & resort" = lib.mkPoi "Vinterstranda hotel & resort" [(3481) (210) (75)] { }; - "Holmgard" = lib.mkPoi "Holmgard" [(4468) (1337) (64)] { }; - "Der Kölner Dom" = lib.mkPoi "Der Kölner Dom" [(4630) (270) (64)] { }; - "Storsnøfjella" = lib.mkPoi "Storsnøfjella" [(5470) (-270) (64)] { }; - "Bondeby" = lib.mkPoi "Bondeby" [(6200) (-300) (64)] { }; - "Kirkemyr" = lib.mkPoi "Kirkemyr" [(6880) (-465) (64)] { }; - }; -} diff --git a/map-markers/vanillaSurvival/verden/default.nix b/map-markers/vanillaSurvival/verden/default.nix deleted file mode 100644 index 78a934f..0000000 --- a/map-markers/vanillaSurvival/verden/default.nix +++ /dev/null @@ -1,6 +0,0 @@ -{ lib, icons }: - -{ - byer = import ./byer.nix { inherit lib icons; }; - spesial = import ./spesial.nix { inherit lib icons; }; -} diff --git a/map-markers/vanillaSurvival/verden/spesial.nix b/map-markers/vanillaSurvival/verden/spesial.nix deleted file mode 100644 index 78d086c..0000000 --- a/map-markers/vanillaSurvival/verden/spesial.nix +++ /dev/null @@ -1,12 +0,0 @@ -{ lib, icons }: - -{ - label = "Spesielle steder"; - toggleable = true; - default-hidden = false; - sorting = 100; - - markers = { - nullpunkt = lib.mkPoi "Nullpunkt" [0 0 64] { /*icon = icons.green*/ }; - }; -} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..c0c4c05 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,26 @@ +[project] +name = "minecraft-kartverket" +version = "0.1.0" +description = "Map data for our favourite minecraft server" +readme = "README.md" +authors = [ + { name = "pvv", email = "projects@pvv.ntnu.no" } +] +requires-python = ">=3.12" +dependencies = [] + +[project.scripts] +mckart = "cli.main:main" + +[tool.hatch.build.targets.wheel] +packages = [ + "src/cli", + "src/lib_marker", + "src/bluemap_exporter", + "src/mapcrafter_exporter", + "src/marker_sets", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" diff --git a/src/bluemap_exporter/__init__.py b/src/bluemap_exporter/__init__.py new file mode 100644 index 0000000..c64c5ad --- /dev/null +++ b/src/bluemap_exporter/__init__.py @@ -0,0 +1,3 @@ +from .exporter import generate_bluemap_output + +__all__ = ["generate_bluemap_output"] diff --git a/src/bluemap_exporter/exporter.py b/src/bluemap_exporter/exporter.py new file mode 100644 index 0000000..e4dca80 --- /dev/null +++ b/src/bluemap_exporter/exporter.py @@ -0,0 +1,80 @@ +import json +from textwrap import indent +from typing import Any +from pathlib import Path + +from marker_sets import WORLDS +from lib_marker import Point + + +def generate_bluemap_output(output_dir: Path): + output_dir.mkdir(parents=True, exist_ok=True) + + data = convert_data_to_bluemap_structure() + + for world_name, marker_sets in data.items(): + with open(output_dir / f"{slug(world_name)}.hocon", "w") as f: + f.write(to_hocon(marker_sets)) + + +def slug(s: str) -> str: + return ( + s.lower() + .replace(" ", "-") + .replace("ø", "o") + .replace("æ", "ae") + .replace("å", "a") + ) + + +def convert_data_to_bluemap_structure() -> dict: + result = {} + + for world_name, marker_sets in WORLDS.items(): + result[world_name] = {} + + for marker_set in marker_sets: + result[world_name][slug(marker_set.name)] = { + "label": marker_set.name, + "toggleable": True, + "default-hidden": not marker_set.show_by_default, + "markers": {}, + } + + for marker in marker_set.markers: + if isinstance(marker, Point): + result[world_name][slug(marker_set.name)][slug(marker.name)] = { + "type": "poi", + "label": marker.name, + "position": { + "x": marker.x, + "y": marker.y, + "z": marker.z, + }, + } + else: + raise NotImplementedError(f"Unknown marker type: {marker}") + + return result + + +def to_hocon(x: Any) -> str: + if isinstance(x, str): + return json.dumps(x, ensure_ascii=False) + elif isinstance(x, int): + return str(x) + elif isinstance(x, float): + return str(x) + elif isinstance(x, bool): + return str(x).lower() + elif isinstance(x, list): + items = [indent(to_hocon(y), " ") for y in x] + return f"[\n{'\n'.join(items)}\n]" + elif isinstance(x, dict): + items = [ + f' "{k}": {indent(to_hocon(v), ' ').removeprefix(' ')}' + for k, v in x.items() + ] + return f"{{\n{'\n'.join(items)}\n}}" + else: + raise ValueError(f"Unknown type: {x}") diff --git a/src/cli/__init__.py b/src/cli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/cli/main.py b/src/cli/main.py new file mode 100644 index 0000000..70f0ab5 --- /dev/null +++ b/src/cli/main.py @@ -0,0 +1,65 @@ +import argparse +from pathlib import Path + +from .print import pretty_print_marker_data +from .validate import validate_marker_data + +from mapcrafter_exporter import generate_mapcrafter_output +from bluemap_exporter import generate_bluemap_output + + +def parse_args(): + parser = argparse.ArgumentParser(description="Minecraft map data exporter cli") + + subparsers = parser.add_subparsers(dest="command") + + ebh_parser = subparsers.add_parser( + "export-bluemap", help="Export map data to Bluemap format" + ) + ebh_parser.add_argument( + "--output-dir", + help="Output dir", + type=Path, + metavar="DIR", + default=Path("bluemap"), + ) + + emj_parser = subparsers.add_parser( + "export-mapcrafter", help="Export map data to Mapcrafter format" + ) + emj_parser.add_argument( + "--output-dir", + help="Output dir", + type=Path, + metavar="DIR", + default=Path("mapcrafter"), + ) + + subparsers.add_parser("validate", help="Validate the map data") + subparsers.add_parser("print", help="Print the map data") + + return parser.parse_args() + + +def main(): + args = parse_args() + + match args.command: + case "export-bluemap": + generate_bluemap_output(args.output_dir) + + case "export-mapcrafter": + generate_mapcrafter_output(args.output_dir) + + case "validate": + validate_marker_data() + + case "print": + pretty_print_marker_data() + + case _: + print("Unknown command") + + +if __name__ == "__main__": + main() diff --git a/src/cli/print.py b/src/cli/print.py new file mode 100644 index 0000000..45fdfb4 --- /dev/null +++ b/src/cli/print.py @@ -0,0 +1,55 @@ +from lib_marker import MarkerSet, Marker, Point, Track, Area +from marker_sets import WORLDS + + +def pretty_print_marker_data() -> None: + tree = format_tree( + "Worlds", [format_world(name, world) for name, world in WORLDS.items()] + ) + print(tree) + + +def format_world(name: str, world: list[MarkerSet]) -> str: + tree = format_tree(name, [format_marker_set(marker_set) for marker_set in world]) + return tree + + +def format_marker_set(marker_set: MarkerSet) -> str: + tree = format_tree( + marker_set.name, [format_marker(marker) for marker in marker_set.markers] + ) + return tree + + +def format_marker(marker: Marker) -> str: + if isinstance(marker, Point): + return format_point_marker(marker) + elif isinstance(marker, Track): + raise NotImplementedError("Track markers are not supported") + elif isinstance(marker, Area): + raise NotImplementedError("Area markers are not supported") + else: + raise ValueError(f"Unknown marker type: {marker}") + + +def format_point_marker(marker: Point) -> str: + return f"{marker.name} ({marker.x}, {marker.y}, {marker.z})" + + +def format_tree(name: str, items: list[str]) -> str: + result = [name] + for i, item in enumerate(items): + if i == len(items) - 1: + for k, line in enumerate(item.splitlines()): + if k == 0: + result.append(f"└─ {line}") + else: + result.append(f" {line}") + else: + for k, line in enumerate(item.splitlines()): + if k == 0: + result.append(f"├─ {line}") + else: + result.append(f"│ {line}") + + return "\n".join(result) diff --git a/src/cli/validate.py b/src/cli/validate.py new file mode 100644 index 0000000..44fb3ba --- /dev/null +++ b/src/cli/validate.py @@ -0,0 +1,200 @@ +from marker_sets import WORLDS +from lib_marker import Point, Track + + +def validate_marker_data() -> None: + for test_name, test_f in _tests.items(): + results = test_f() + if len(results) > 0: + print(f"[X] {test_name}") + for result in results: + print(f" {result}") + else: + print(f"[✓] {test_name}") + + +def validate_no_non_included_files() -> list: + # TODO: Implement this function + return [] + + +def validate_no_invalid_y_values() -> list: + result = [] + + for world_name, marker_sets in WORLDS.items(): + for marker_set in marker_sets: + for marker in marker_set.markers: + if isinstance(marker, Point): + if marker.y < 0 or marker.y > 255: + result.append( + { + "error_type": "invalid_y_value", + "full_marker_name": ( + world_name, + marker_set.name, + marker.name, + ), + "y_value": marker.y, + } + ) + elif isinstance(marker, Track): + for i, point in enumerate(marker.points): + _, y, _ = point + if y < 0 or y > 255: + result.append( + { + "error_type": "invalid_y_value", + "full_marker_name": ( + world_name, + marker_set.name, + marker.name, + ), + "index": i, + "y_value": y, + } + ) + + return result + + +def validate_no_duplicate_points_in_tracks() -> list: + result = [] + + for world_name, marker_sets in WORLDS.items(): + for marker_set in marker_sets: + for marker in marker_set.markers: + if isinstance(marker, Track): + points = {} + for point in marker.points: + if point in points: + result.append( + { + "error_type": "duplicate_point", + "point_a": points[point], + "point_b": ( + world_name, + marker_set.name, + marker.name, + ), + "coordinates": point, + } + ) + points[point] = (world_name, marker_set.name, marker.name) + + return result + + +def validate_no_duplicate_marker_names() -> list: + result = [] + + marker_names = set() + for world_name, marker_sets in WORLDS.items(): + for marker_set in marker_sets: + for marker in marker_set.markers: + full_name = (world_name, marker_set.name, marker.name) + if full_name in marker_names: + result.append( + { + "error_type": "duplicate_marker_name", + "full_marker_name": full_name, + } + ) + marker_names.add(full_name) + + return result + + +def validate_no_duplicate_marker_set_names() -> list: + result = [] + + marker_set_names = set() + for world_name, marker_sets in WORLDS.items(): + for marker_set in marker_sets: + if (world_name, marker_set.name) in marker_set_names: + result.append( + { + "error_type": "duplicate_marker_set_name", + "full_marker_set_name": (world_name, marker_set.name), + } + ) + marker_set_names.add((world_name, marker_set.name)) + + return result + + +def validate_no_unused_icons() -> list: + # TODO: Implement this function + return [] + + +def validate_no_duplicate_points() -> list: + result = [] + + for world_name, marker_sets in WORLDS.items(): + points = {} + for marker_set in marker_sets: + for marker in marker_set.markers: + if isinstance(marker, Point): + point = (marker.x, marker.y, marker.z) + if point in points: + result.append( + { + "error_type": "duplicate_point", + "point_a": points[point], + "point_b": (world_name, marker_set.name, marker.name), + "coordinates": point, + } + ) + points[point] = (world_name, marker_set.name, marker.name) + elif isinstance(marker, Track): + for i, point in enumerate(marker.points): + if point in points: + result.append( + { + "error_type": "duplicate_point", + "point_a": points[point], + "point_b": ( + world_name, + marker_set.name, + marker.name, + ), + "index": i, + "coordinates": point, + } + ) + points[point] = (world_name, marker_set.name, marker.name) + + return result + + +def validate_all_tracks_have_at_least_two_points() -> list: + result = [] + + for world_name, marker_sets in WORLDS.items(): + for marker_set in marker_sets: + for marker in marker_set.markers: + if isinstance(marker, Track) and len(marker.points) < 2: + result.append( + { + "error_type": "track_too_short", + "full_marker_name": ( + world_name, + marker_set.name, + marker.name, + ), + } + ) + + return result + + +_tests = { + "No non-included files": validate_no_non_included_files, + "No invalid y coordinates": validate_no_invalid_y_values, + "No duplicate points in tracks": validate_no_duplicate_points_in_tracks, + "No duplicate marker names": validate_no_duplicate_marker_names, + "No duplicate marker-set names": validate_no_duplicate_marker_set_names, + "No unused icons": validate_no_unused_icons, + "No duplicate points": validate_no_duplicate_points, + "All tracks have at least two points": validate_all_tracks_have_at_least_two_points, +} diff --git a/src/lib_marker/__init__.py b/src/lib_marker/__init__.py new file mode 100644 index 0000000..6d8b91a --- /dev/null +++ b/src/lib_marker/__init__.py @@ -0,0 +1,15 @@ +from .area import Area +from .color import Color +from .marker import Marker +from .marker_set import MarkerSet +from .point import Point +from .track import Track + +__all__ = [ + "Area", + "Color", + "Marker", + "MarkerSet", + "Point", + "Track", +] diff --git a/src/lib_marker/area.py b/src/lib_marker/area.py new file mode 100644 index 0000000..74fc682 --- /dev/null +++ b/src/lib_marker/area.py @@ -0,0 +1,9 @@ +from dataclasses import dataclass + +from .marker import Marker + + +@dataclass +class Area(Marker): + points: list[tuple[int, int, int]] + icon: str | None = None diff --git a/src/lib_marker/color.py b/src/lib_marker/color.py new file mode 100644 index 0000000..a2cac04 --- /dev/null +++ b/src/lib_marker/color.py @@ -0,0 +1,8 @@ +from dataclasses import dataclass + + +@dataclass +class Color: + r: int + g: int + b: int diff --git a/src/lib_marker/marker.py b/src/lib_marker/marker.py new file mode 100644 index 0000000..32902bd --- /dev/null +++ b/src/lib_marker/marker.py @@ -0,0 +1,8 @@ +from abc import ABC +from dataclasses import dataclass + + +@dataclass +class Marker(ABC): + name: str + # icon: str | None = None diff --git a/src/lib_marker/marker_set.py b/src/lib_marker/marker_set.py new file mode 100644 index 0000000..cb47bc5 --- /dev/null +++ b/src/lib_marker/marker_set.py @@ -0,0 +1,26 @@ +from dataclasses import dataclass + +from .color import Color +from .marker import Marker + + +@dataclass +class MarkerSet: + name: str + + markers: list[Marker] + + # Icon to use for the marker group. If None, the default icon will be used. + icon: str | None = None + + # Default icon to use for the markers in the group. If None, the default icon will be used. + default_icon: str | None = None + + # Default icon size to use for the markers in the group. If None, the default icon size will be used. + default_icon_size: tuple[int, int] | None = None + + # Default color to use for the markers in the group. If None, the default color will be used. + default_color: Color | None = None + + # Whether to show this marker group by default. + show_by_default: bool = True diff --git a/src/lib_marker/point.py b/src/lib_marker/point.py new file mode 100644 index 0000000..6289da2 --- /dev/null +++ b/src/lib_marker/point.py @@ -0,0 +1,11 @@ +from dataclasses import dataclass + +from .marker import Marker + + +@dataclass +class Point(Marker): + x: int + y: int + z: int + icon: str | None = None diff --git a/src/lib_marker/track.py b/src/lib_marker/track.py new file mode 100644 index 0000000..9fd965d --- /dev/null +++ b/src/lib_marker/track.py @@ -0,0 +1,9 @@ +from dataclasses import dataclass + +from .marker import Marker + + +@dataclass +class Track(Marker): + points: list[tuple[int, int, int]] + icon: str | None = None diff --git a/src/mapcrafter_exporter/__init__.py b/src/mapcrafter_exporter/__init__.py new file mode 100644 index 0000000..5438395 --- /dev/null +++ b/src/mapcrafter_exporter/__init__.py @@ -0,0 +1,3 @@ +from .exporter import generate_mapcrafter_output + +__all__ = ["generate_mapcrafter_output"] diff --git a/src/mapcrafter_exporter/exporter.py b/src/mapcrafter_exporter/exporter.py new file mode 100644 index 0000000..6444cc2 --- /dev/null +++ b/src/mapcrafter_exporter/exporter.py @@ -0,0 +1,57 @@ +import json +from pathlib import Path + +from marker_sets import WORLDS +from lib_marker import Point, Track, Area + + +def generate_mapcrafter_output(output_dir: Path): + output_dir.mkdir(parents=True, exist_ok=True) + + with (Path(__file__).parent / "markers-template.js").open( + "r", encoding="utf-8" + ) as f: + template = f.read() + + exported_markers_json = json.dumps( + convert_data_to_mapcrafter_structure(), + indent=2, + ensure_ascii=False, + ) + + template = template.replace('"@EXPORTED_MARKERS@"', exported_markers_json) + + with (output_dir / "markers.js").open("w", encoding="utf-8") as f: + f.write(template) + + +def convert_data_to_mapcrafter_structure() -> dict: + result = {} + + for world_name, world_marker_sets in WORLDS.items(): + for marker_set in world_marker_sets: + if marker_set.name not in result: + result[marker_set.name] = { + "id": marker_set.name.lower().replace(" ", "-"), + "name": marker_set.name, + "showDefault": marker_set.show_by_default, + "markers": {}, + } + + result[marker_set.name]["markers"][world_name] = [] + for marker in marker_set.markers: + if isinstance(marker, Point): + result[marker_set.name]["markers"][world_name].append( + {"pos": [marker.x, marker.y, marker.z], "title": marker.name} + ) + + elif isinstance(marker, Track): + raise NotImplementedError("Track markers are not supported") + + elif isinstance(marker, Area): + raise NotImplementedError("Area markers are not supported") + + else: + raise ValueError(f"Unknown marker type: {marker}") + + return result diff --git a/src/mapcrafter_exporter/markers-template.js b/src/mapcrafter_exporter/markers-template.js new file mode 100644 index 0000000..24d6930 --- /dev/null +++ b/src/mapcrafter_exporter/markers-template.js @@ -0,0 +1,60 @@ +const MAPCRAFTER_MARKERS = [ + "@EXPORTED_MARKERS@", + { + // + // Tegner et rutenett som viser regiongrensene, og + // koordinatene for hver region. + // + "id" : "regioner", + "name" : "Regioner", + "showDefault" : false, + "createMarker" : function(ui, groupInfo, markerInfo) { + var rmax = 15; + var objekter = []; + + var multilatlngs = []; + + for (var rx = -rmax; rx < rmax; rx++) { + var latlngs = []; + var miny = -rmax*512; + var maxy = rmax*512; + var x = rx*512; + // use the ui.mcToLatLng-function to convert Minecraft coords to LatLngs + latlngs.push(ui.mcToLatLng(x, miny, 64)); + latlngs.push(ui.mcToLatLng(x, maxy, 64)); + multilatlngs.push(latlngs); + } + + for (var ry = -rmax; ry < rmax; ry++) { + var latlngs = []; + var minx = -rmax*512; + var maxx = rmax*512; + var y = ry*512; + // use the ui.mcToLatLng-function to convert Minecraft coords to LatLngs + latlngs.push(ui.mcToLatLng(minx, y, 64)); + latlngs.push(ui.mcToLatLng(maxx, y, 64)); + multilatlngs.push(latlngs); + } + + for (var rx = -rmax; rx < rmax; rx++) { + for (var ry = -rmax; ry < rmax; ry++) { + var x = rx*512 + 256; + var y = ry*512 + 256; + + var myIcon = L.divIcon({iconSize: L.point(55, 20), html: "
r." + String(rx) + "." + String(ry) + "
"}); + var myMarker = L.marker(ui.mcToLatLng(x, y, 64), {icon: myIcon}); + objekter.push(myMarker); + } + } + + var linjer = []; + if (L.version.startsWith("0.7.")) { + linjer = L.multiPolyline(multilatlngs, {"color" : markerInfo.color}); + } else { + linjer = L.polyline(multilatlngs, {"color" : markerInfo.color}); + } + objekter.push(linjer); + return L.layerGroup(objekter); + }, + }, +]; diff --git a/src/marker_sets/__init__.py b/src/marker_sets/__init__.py new file mode 100644 index 0000000..f4ad95e --- /dev/null +++ b/src/marker_sets/__init__.py @@ -0,0 +1,11 @@ +from lib_marker import MarkerSet + +from .nether import MARKER_SETS as nether_marker_sets +from .overworld import MARKER_SETS as overworld_marker_sets +from .the_end import MARKER_SETS as the_end_marker_sets + +WORLDS: dict[str, list[MarkerSet]] = { + "Nether": nether_marker_sets, + "Overworld": overworld_marker_sets, + "The End": the_end_marker_sets, +} diff --git a/src/marker_sets/nether/__init__.py b/src/marker_sets/nether/__init__.py new file mode 100644 index 0000000..ab88ae3 --- /dev/null +++ b/src/marker_sets/nether/__init__.py @@ -0,0 +1,14 @@ +from .area_names import MARKER_SET as area_names_marker_set +from .ice_tracks import MARKER_SET as ice_tracks_marker_set +from .other import MARKER_SET as other_marker_set +from .portals import MARKER_SET as portals_marker_set +from .railways import MARKER_SET as railways_marker_set + + +MARKER_SETS = [ + area_names_marker_set, + ice_tracks_marker_set, + other_marker_set, + portals_marker_set, + railways_marker_set, +] diff --git a/src/marker_sets/nether/area_names.py b/src/marker_sets/nether/area_names.py new file mode 100644 index 0000000..ad5cf7f --- /dev/null +++ b/src/marker_sets/nether/area_names.py @@ -0,0 +1,14 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Area Names", + markers=[ + Point( + name="Grisebukta", + icon=None, + x=-900, + y=64, + z=27, + ), + ], +) diff --git a/src/marker_sets/nether/ice_tracks.py b/src/marker_sets/nether/ice_tracks.py new file mode 100644 index 0000000..86a2446 --- /dev/null +++ b/src/marker_sets/nether/ice_tracks.py @@ -0,0 +1,7 @@ +from lib_marker import MarkerSet + + +MARKER_SET = MarkerSet( + name="Ice tracks", + markers=[], +) diff --git a/src/marker_sets/nether/other.py b/src/marker_sets/nether/other.py new file mode 100644 index 0000000..6d160b7 --- /dev/null +++ b/src/marker_sets/nether/other.py @@ -0,0 +1,7 @@ +from lib_marker import MarkerSet + + +MARKER_SET = MarkerSet( + name="Other", + markers=[], +) diff --git a/src/marker_sets/nether/portals.py b/src/marker_sets/nether/portals.py new file mode 100644 index 0000000..07f8e47 --- /dev/null +++ b/src/marker_sets/nether/portals.py @@ -0,0 +1,7 @@ +from lib_marker import MarkerSet + + +MARKER_SET = MarkerSet( + name="Portals", + markers=[], +) diff --git a/src/marker_sets/nether/railways.py b/src/marker_sets/nether/railways.py new file mode 100644 index 0000000..5cbe19e --- /dev/null +++ b/src/marker_sets/nether/railways.py @@ -0,0 +1,7 @@ +from lib_marker import MarkerSet + + +MARKER_SET = MarkerSet( + name="Railways", + markers=[], +) diff --git a/src/marker_sets/overworld/__init__.py b/src/marker_sets/overworld/__init__.py new file mode 100644 index 0000000..908089f --- /dev/null +++ b/src/marker_sets/overworld/__init__.py @@ -0,0 +1,27 @@ +from .area_names import MARKER_SET as area_names_marker_set +from .buildings import MARKER_SET as buildings_marker_set +from .cities import MARKER_SET as cities_marker_set +from .homes import MARKER_SET as homes_marker_set +from .huts import MARKER_SET as huts_marker_set +from .infrastructure import MARKER_SET as infrastructure_marker_set +from .mines import MARKER_SET as mines_marker_set +from .nature import MARKER_SET as nature_marker_set +from .other import MARKER_SET as other_marker_set +from .railways import MARKER_SET as railways_marker_set +from .roads import MARKER_SET as roads_marker_set +from .villages import MARKER_SET as villages_marker_set + +MARKER_SETS = [ + area_names_marker_set, + buildings_marker_set, + cities_marker_set, + homes_marker_set, + huts_marker_set, + infrastructure_marker_set, + mines_marker_set, + nature_marker_set, + other_marker_set, + railways_marker_set, + roads_marker_set, + villages_marker_set, +] diff --git a/src/marker_sets/overworld/area_names.py b/src/marker_sets/overworld/area_names.py new file mode 100644 index 0000000..0b65aad --- /dev/null +++ b/src/marker_sets/overworld/area_names.py @@ -0,0 +1,42 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Area Names", + markers=[ + Point( + name="Andøya", + icon=None, + x=2300, + y=64, + z=250, + ), + Point( + name="England", + icon=None, + x=-1189, + y=64, + z=1556, + ), + Point( + name="Hemmelig mesabiom", + icon=None, + x=-980, + y=64, + z=4090, + ), + Point( + name="Summefjord", + icon=None, + x=-220, + y=64, + z=2890, + ), + Point( + name="Vestisødet", + icon=None, + x=-800, + y=64, + z=0, + ), + ], +) diff --git a/src/marker_sets/overworld/buildings.py b/src/marker_sets/overworld/buildings.py new file mode 100644 index 0000000..4c141bb --- /dev/null +++ b/src/marker_sets/overworld/buildings.py @@ -0,0 +1,70 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Buildings", + markers=[ + Point( + name="Der Kölner Dom", + icon=None, + x=4630, + y=64, + z=270, + ), + Point( + name="Fyret", + icon=None, + x=3085, + y=64, + z=424, + ), + Point( + name="Hodeskallegrotten", + icon=None, + x=267, + y=89, + z=-496, + ), + Point( + name="Isjungelkatedralen", + icon=None, + x=-378, + y=64, + z=153, + ), + Point( + name="Jesus Christ Superstore", + icon=None, + x=280, + y=64, + z=-2800, + ), + Point( + name="Kystbasen", + icon=None, + x=-334, + y=116, + z=473, + ), + Point( + name="Tårnodden", + icon=None, + x=-22, + y=76, + z=67, + ), + Point( + name="Tegltårnet", + icon=None, + x=-99, + y=99, + z=1025, + ), + Point( + name="Vinterstranda hotel & resort", + icon=None, + x=3481, + y=75, + z=210, + ), + ], +) diff --git a/src/marker_sets/overworld/cities.py b/src/marker_sets/overworld/cities.py new file mode 100644 index 0000000..9e0f698 --- /dev/null +++ b/src/marker_sets/overworld/cities.py @@ -0,0 +1,42 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Cities", + markers=[ + Point( + name="Heimfjell", + icon=None, + x=177, + y=64, + z=177, + ), + Point( + name="Holmgard", + icon=None, + x=4468, + y=64, + z=1337, + ), + Point( + name="Tangen", + icon=None, + x=58, + y=63, + z=-2860, + ), + Point( + name="Tosjødalen", + icon=None, + x=960, + y=64, + z=460, + ), + Point( + name="Vikingelandsbyen", + icon=None, + x=360, + y=64, + z=-460, + ), + ], +) diff --git a/src/marker_sets/overworld/homes.py b/src/marker_sets/overworld/homes.py new file mode 100644 index 0000000..0121b4f --- /dev/null +++ b/src/marker_sets/overworld/homes.py @@ -0,0 +1,84 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Homes", + markers=[ + Point( + name="Akasienborg", + icon=None, + x=-128, + y=64, + z=1460, + ), + Point( + name="Bikkjeby", + icon=None, + x=2950, + y=64, + z=270, + ), + Point( + name="Biosfæren", + icon=None, + x=834, + y=65, + z=-3089, + ), + Point( + name="Bjørkeholmen", + icon=None, + x=102, + y=77, + z=37, + ), + Point( + name="Bjørnebukten", + icon=None, + x=473, + y=78, + z=-3043, + ), + Point( + name="Huløyeid", + icon=None, + x=-54, + y=64, + z=234, + ), + Point( + name="Singapore", + icon=None, + x=-600, + y=64, + z=1130, + ), + Point( + name="Summevatn", + icon=None, + x=-110, + y=64, + z=3465, + ), + Point( + name="SuperTheodors fiskehus", + icon=None, + x=1570, + y=64, + z=3285, + ), + Point( + name="Svartskoghavn", + icon=None, + x=-370, + y=64, + z=2390, + ), + Point( + name="Vestlandet", + icon=None, + x=-2204, + y=64, + z=447, + ), + ], +) diff --git a/src/marker_sets/overworld/huts.py b/src/marker_sets/overworld/huts.py new file mode 100644 index 0000000..f051f20 --- /dev/null +++ b/src/marker_sets/overworld/huts.py @@ -0,0 +1,28 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Huts", + markers=[ + Point( + name="Dypskiferhytta", + icon=None, + x=-1563, + y=64, + z=-1966, + ), + Point( + name="Grensebuelvbu", + icon=None, + x=550, + y=64, + z=-1480, + ), + Point( + name="Nyverdenhytta", + icon=None, + x=848, + y=70, + z=1583, + ), + ], +) diff --git a/src/marker_sets/overworld/infrastructure.py b/src/marker_sets/overworld/infrastructure.py new file mode 100644 index 0000000..dae0b59 --- /dev/null +++ b/src/marker_sets/overworld/infrastructure.py @@ -0,0 +1,21 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Infrastructure", + markers=[ + Point( + name="Grantrebukta", + icon=None, + x=2350, + y=64, + z=-136, + ), + Point( + name="Smalelvbro", + icon=None, + x=77, + y=69, + z=-348, + ), + ], +) diff --git a/src/marker_sets/overworld/mines.py b/src/marker_sets/overworld/mines.py new file mode 100644 index 0000000..902aeef --- /dev/null +++ b/src/marker_sets/overworld/mines.py @@ -0,0 +1,21 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Mines", + markers=[ + Point( + name="Sandsteingruva", + icon=None, + x=56, + y=67, + z=-266, + ), + Point( + name="Slimegruva", + icon=None, + x=-206, + y=64, + z=-35, + ), + ], +) diff --git a/src/marker_sets/overworld/nature.py b/src/marker_sets/overworld/nature.py new file mode 100644 index 0000000..8faf7f5 --- /dev/null +++ b/src/marker_sets/overworld/nature.py @@ -0,0 +1,140 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Nature", + markers=[ + Point( + name="Blindodden", + icon=None, + x=874, + y=65, + z=160, + ), + Point( + name="Hulevatna", + icon=None, + x=240, + y=64, + z=3070, + ), + Point( + name="Kirkemyr", + icon=None, + x=6880, + y=64, + z=-465, + ), + Point( + name="Lamafjellet", + icon=None, + x=1810, + y=64, + z=-1630, + ), + Point( + name="Langstrand", + icon=None, + x=-305, + y=64, + z=535, + ), + Point( + name="Lille isbjørnelv", + icon=None, + x=730, + y=64, + z=-1900, + ), + Point( + name="Naturreservat", + icon=None, + x=4, + y=64, + z=800, + ), + Point( + name="Piratbukta", + icon=None, + x=150, + y=64, + z=80, + ), + Point( + name="Snøklippan", + icon=None, + x=-1654, + y=64, + z=-654, + ), + Point( + name="Store isbjørnelv", + icon=None, + x=850, + y=64, + z=-2130, + ), + Point( + name="Storhavet i øst", + icon=None, + x=3000, + y=64, + z=1000, + ), + Point( + name="Storhavskanalen", + icon=None, + x=1005, + y=64, + z=1335, + ), + Point( + name="Storsnøfjella", + icon=None, + x=5470, + y=64, + z=-270, + ), + Point( + name="Storvatnet", + icon=None, + x=675, + y=64, + z=362, + ), + Point( + name="SuperTheodors strand", + icon=None, + x=2111, + y=64, + z=3777, + ), + Point( + name="Trangdalen", + icon=None, + x=-47, + y=64, + z=146, + ), + Point( + name="Turrikkelmyra", + icon=None, + x=-160, + y=64, + z=1480, + ), + Point( + name="Ulveelva", + icon=None, + x=910, + y=64, + z=3050, + ), + Point( + name="Vestsumpland", + icon=None, + x=-1818, + y=64, + z=98, + ), + ], +) diff --git a/src/marker_sets/overworld/other.py b/src/marker_sets/overworld/other.py new file mode 100644 index 0000000..0b1f64b --- /dev/null +++ b/src/marker_sets/overworld/other.py @@ -0,0 +1,21 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Other", + markers=[ + Point( + name="Leirhavn", + icon=None, + x=512, + y=64, + z=-3320, + ), + Point( + name="Nullpunkt", + icon=None, + x=0, + y=64, + z=0, + ), + ], +) diff --git a/src/marker_sets/overworld/railways.py b/src/marker_sets/overworld/railways.py new file mode 100644 index 0000000..5cbe19e --- /dev/null +++ b/src/marker_sets/overworld/railways.py @@ -0,0 +1,7 @@ +from lib_marker import MarkerSet + + +MARKER_SET = MarkerSet( + name="Railways", + markers=[], +) diff --git a/src/marker_sets/overworld/roads.py b/src/marker_sets/overworld/roads.py new file mode 100644 index 0000000..3db4f78 --- /dev/null +++ b/src/marker_sets/overworld/roads.py @@ -0,0 +1,7 @@ +from lib_marker import MarkerSet + + +MARKER_SET = MarkerSet( + name="Roads", + markers=[], +) diff --git a/src/marker_sets/overworld/villages.py b/src/marker_sets/overworld/villages.py new file mode 100644 index 0000000..6a91b9f --- /dev/null +++ b/src/marker_sets/overworld/villages.py @@ -0,0 +1,70 @@ +from lib_marker import MarkerSet, Point + +MARKER_SET = MarkerSet( + name="Villages", + markers=[ + Point( + name="Bondeby", + icon=None, + x=6200, + y=64, + z=-300, + ), + Point( + name="Gammelleirnes", + icon=None, + x=800, + y=64, + z=-3300, + ), + Point( + name="Hestelandsby", + icon=None, + x=2734, + y=64, + z=-984, + ), + Point( + name="Isbjørnby", + icon=None, + x=723, + y=64, + z=-2380, + ), + Point( + name="Ittoqqortoormiit", + icon=None, + x=100, + y=64, + z=-3830, + ), + Point( + name="Kløfteby", + icon=None, + x=695, + y=64, + z=2812, + ), + Point( + name="NPC-landsby nord", + icon=None, + x=337, + y=64, + z=-853, + ), + Point( + name="NPC-landsby", + icon=None, + x=1278, + y=64, + z=-397, + ), + Point( + name="Smedby", + icon=None, + x=-1760, + y=64, + z=-2440, + ), + ], +) diff --git a/src/marker_sets/the_end/__init__.py b/src/marker_sets/the_end/__init__.py new file mode 100644 index 0000000..ee65ee7 --- /dev/null +++ b/src/marker_sets/the_end/__init__.py @@ -0,0 +1,7 @@ +from .other import MARKER_SET as other_marker_set +from .portals import MARKER_SET as portals_marker_set + +MARKER_SETS = [ + other_marker_set, + portals_marker_set, +] diff --git a/src/marker_sets/the_end/other.py b/src/marker_sets/the_end/other.py new file mode 100644 index 0000000..6d160b7 --- /dev/null +++ b/src/marker_sets/the_end/other.py @@ -0,0 +1,7 @@ +from lib_marker import MarkerSet + + +MARKER_SET = MarkerSet( + name="Other", + markers=[], +) diff --git a/src/marker_sets/the_end/portals.py b/src/marker_sets/the_end/portals.py new file mode 100644 index 0000000..07f8e47 --- /dev/null +++ b/src/marker_sets/the_end/portals.py @@ -0,0 +1,7 @@ +from lib_marker import MarkerSet + + +MARKER_SET = MarkerSet( + name="Portals", + markers=[], +) diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..fa9f551 --- /dev/null +++ b/uv.lock @@ -0,0 +1,7 @@ +version = 1 +requires-python = ">=3.12" + +[[package]] +name = "minecraft-kartverket" +version = "0.1.0" +source = { editable = "." }