rewrite in python #3

Closed
oysteikt wants to merge 13 commits from rewrite-in-python into master
57 changed files with 1584 additions and 528 deletions

1
.envrc Normal file
View File

@@ -0,0 +1 @@
use flake

15
.gitignore vendored Normal file
View File

@@ -0,0 +1,15 @@
# Python
*.pyc
*.pyo
build/
dist/
.venv
__pycache__
# Nix
result
result-*
# Ignore generated files by default
/mapcrafter
/bluemap

112
README.md Normal file
View File

@@ -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/<world>`.
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/<world>`.
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/<world>/__init__.py`.
```python
from .<marker_set_name> import MARKER_SET as <marker_set_name>_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)

27
flake.lock generated Normal file
View File

@@ -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
}

123
flake.nix
View File

@@ -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 <file>")
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
'';
});
};
}

0
icons/.gitkeep Normal file
View File

View File

@@ -1,6 +0,0 @@
let
lib = import ./lib.nix;
icons = import ./icons;
in {
vanillaSurvival = import ./vanillaSurvival { inherit lib icons; };
}

View File

@@ -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;
}

View File

@@ -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: "<center>r." + String(rx) + "." + String(ry) + "</center>"});
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",
},
],
},
},
];

View File

@@ -1,7 +0,0 @@
{ lib, icons, ... }:
{
verden = import ./verden { inherit lib icons; };
underverden = import ./underverden { inherit lib icons; };
# enden = import ./enden { inherit lib icons; };
}

View File

@@ -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)] { };
}

View File

@@ -1,6 +0,0 @@
{ lib, icons }:
{
byer = import ./byer.nix { inherit lib icons; };
spesial = import ./spesial.nix { inherit lib icons; };
}

View File

@@ -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*/ };
};
}

View File

@@ -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)] { };
};
}

View File

@@ -1,6 +0,0 @@
{ lib, icons }:
{
byer = import ./byer.nix { inherit lib icons; };
spesial = import ./spesial.nix { inherit lib icons; };
}

View File

@@ -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*/ };
};
}

26
pyproject.toml Normal file
View File

@@ -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"

View File

@@ -0,0 +1,3 @@
from .exporter import generate_bluemap_output
__all__ = ["generate_bluemap_output"]

View File

@@ -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}")

0
src/cli/__init__.py Normal file
View File

65
src/cli/main.py Normal file
View File

@@ -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()

55
src/cli/print.py Normal file
View File

@@ -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)

200
src/cli/validate.py Normal file
View File

@@ -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,
}

View File

@@ -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",
]

9
src/lib_marker/area.py Normal file
View File

@@ -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

8
src/lib_marker/color.py Normal file
View File

@@ -0,0 +1,8 @@
from dataclasses import dataclass
@dataclass
class Color:
r: int
g: int
b: int

8
src/lib_marker/marker.py Normal file
View File

@@ -0,0 +1,8 @@
from abc import ABC
from dataclasses import dataclass
@dataclass
class Marker(ABC):
name: str
# icon: str | None = None

View File

@@ -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

11
src/lib_marker/point.py Normal file
View File

@@ -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

9
src/lib_marker/track.py Normal file
View File

@@ -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

View File

@@ -0,0 +1,3 @@
from .exporter import generate_mapcrafter_output
__all__ = ["generate_mapcrafter_output"]

View File

@@ -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

View File

@@ -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: "<center>r." + String(rx) + "." + String(ry) + "</center>"});
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);
},
},
];

View File

@@ -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,
}

View File

@@ -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,
]

View File

@@ -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,
),
],
)

View File

@@ -0,0 +1,7 @@
from lib_marker import MarkerSet
MARKER_SET = MarkerSet(
name="Ice tracks",
markers=[],
)

View File

@@ -0,0 +1,7 @@
from lib_marker import MarkerSet
MARKER_SET = MarkerSet(
name="Other",
markers=[],
)

View File

@@ -0,0 +1,7 @@
from lib_marker import MarkerSet
MARKER_SET = MarkerSet(
name="Portals",
markers=[],
)

View File

@@ -0,0 +1,7 @@
from lib_marker import MarkerSet
MARKER_SET = MarkerSet(
name="Railways",
markers=[],
)

View File

@@ -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,
]

View File

@@ -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,
),
],
)

View File

@@ -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,
),
],
)

View File

@@ -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,
),
],
)

View File

@@ -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,
),
],
)

View File

@@ -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,
),
],
)

View File

@@ -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,
),
],
)

View File

@@ -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,
),
],
)

View File

@@ -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,
),
],
)

View File

@@ -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,
),
],
)

View File

@@ -0,0 +1,7 @@
from lib_marker import MarkerSet
MARKER_SET = MarkerSet(
name="Railways",
markers=[],
)

View File

@@ -0,0 +1,7 @@
from lib_marker import MarkerSet
MARKER_SET = MarkerSet(
name="Roads",
markers=[],
)

View File

@@ -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,
),
],
)

View File

@@ -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,
]

View File

@@ -0,0 +1,7 @@
from lib_marker import MarkerSet
MARKER_SET = MarkerSet(
name="Other",
markers=[],
)

View File

@@ -0,0 +1,7 @@
from lib_marker import MarkerSet
MARKER_SET = MarkerSet(
name="Portals",
markers=[],
)

7
uv.lock generated Normal file
View File

@@ -0,0 +1,7 @@
version = 1
requires-python = ">=3.12"
[[package]]
name = "minecraft-kartverket"
version = "0.1.0"
source = { editable = "." }