Compare commits
32 Commits
rewrite-in
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
2618e434e4
|
|||
|
8ef19f8051
|
|||
|
7cb7e0c0e7
|
|||
|
306d35fb23
|
|||
|
86f68fdd9a
|
|||
|
5cd25d1717
|
|||
|
06c99de7eb
|
|||
|
1fe46eea88
|
|||
|
|
0892890d4f | ||
|
|
3fae06f53f | ||
|
040294f2e1
|
|||
|
a74844b877
|
|||
|
db319f65e6
|
|||
|
|
2112ddd214 | ||
|
73a818de79
|
|||
|
|
20babc9d50 | ||
|
3bc8867f06
|
|||
|
83c7740a55
|
|||
|
1ca8495fa2
|
|||
|
b0c855dc43
|
|||
|
584fd6379c
|
|||
|
6fae27b165
|
|||
|
d3bb5c7e8c
|
|||
|
7c86d342e6
|
|||
|
1af4bbc330
|
|||
|
be638b2ade
|
|||
|
1b3a7d0e90
|
|||
|
89e9d8827c
|
|||
|
08507b8d53
|
|||
|
30e1aabde9
|
|||
|
1168d37d7e
|
|||
|
c20520b400
|
93
.gitea/workflows/build.yml
Normal file
93
.gitea/workflows/build.yml
Normal file
@@ -0,0 +1,93 @@
|
||||
name: "Build maps"
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
jobs:
|
||||
build-mapcrafter:
|
||||
runs-on: debian-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
|
||||
- name: Build map
|
||||
run: uv run mckart export-mapcrafter
|
||||
|
||||
# - name: Setup Biome
|
||||
# uses: biomejs/setup-biome@v2
|
||||
|
||||
# - name: Format map
|
||||
# run: biome format ./mapcrafter/* --write
|
||||
|
||||
- name: Transfer results
|
||||
uses: https://git.pvv.ntnu.no/Projects/rsync-action@v1
|
||||
with:
|
||||
source: ./mapcrafter/
|
||||
target: ${{ gitea.ref_name }}/mapcrafter/
|
||||
username: gitea-web
|
||||
ssh-key: ${{ secrets.WEB_SYNC_SSH_KEY }}
|
||||
host: pages.pvv.ntnu.no
|
||||
known-hosts: "pages.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2QjfFB+city1SYqltkVqWACfo1j37k+oQQfj13mtgg"
|
||||
|
||||
- name: Upload deb package artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: minecraft-kartverket-mapcrafter-export-${{ gitea.sha }}.zip
|
||||
path: ./mapcrafter/
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
compression: 7
|
||||
|
||||
build-bluemap:
|
||||
runs-on: debian-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
|
||||
- name: Build map
|
||||
run: uv run mckart export-bluemap
|
||||
|
||||
- name: Transfer results
|
||||
uses: https://git.pvv.ntnu.no/Projects/rsync-action@v1
|
||||
with:
|
||||
source: ./bluemap/
|
||||
target: ${{ gitea.ref_name }}/bluemap/
|
||||
username: gitea-web
|
||||
ssh-key: ${{ secrets.WEB_SYNC_SSH_KEY }}
|
||||
host: pages.pvv.ntnu.no
|
||||
known-hosts: "pages.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH2QjfFB+city1SYqltkVqWACfo1j37k+oQQfj13mtgg"
|
||||
|
||||
- name: Upload deb package artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: minecraft-kartverket-bluemap-export-${{ gitea.sha }}.zip
|
||||
path: ./bluemap/
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
compression: 7
|
||||
|
||||
validate:
|
||||
runs-on: debian-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v7
|
||||
|
||||
- name: Validate map data
|
||||
run: uv run mckart validate
|
||||
|
||||
# build-nix:
|
||||
# runs-on: debian-latest
|
||||
# steps:
|
||||
# - name: Install sudo
|
||||
# run: apt-get update && apt-get -y install sudo
|
||||
|
||||
# - name: Install nix
|
||||
# uses: https://github.com/cachix/install-nix-action@v31
|
||||
|
||||
# - name: Configure nix
|
||||
# run: echo -e "show-trace = true\nmax-jobs = auto\ntrusted-users = root\nexperimental-features = nix-command flakes\nbuild-users-group =" > /etc/nix/nix.conf
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -13,3 +13,4 @@ result-*
|
||||
# Ignore generated files by default
|
||||
/mapcrafter
|
||||
/bluemap
|
||||
/out
|
||||
|
||||
28
LICENSE
Normal file
28
LICENSE
Normal file
@@ -0,0 +1,28 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2026, Programvareverkstedet <projects@pvv.ntnu.no>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
20
Makefile
Normal file
20
Makefile
Normal file
@@ -0,0 +1,20 @@
|
||||
.PHONY: all clean validate
|
||||
|
||||
all: bluemap mapcrafter
|
||||
|
||||
export PYTHONPATH := $(CURDIR)/src/
|
||||
|
||||
OUT := $(CURDIR)/out
|
||||
|
||||
validate:
|
||||
python -m cli.main validate
|
||||
|
||||
bluemap: validate
|
||||
python -m cli.main export-bluemap --output-dir "$(OUT)/bluemap"
|
||||
|
||||
mapcrafter: validate
|
||||
python -m cli.main export-mapcrafter --output-dir "$(OUT)/mapcrafter"
|
||||
|
||||
clean:
|
||||
rm -rf ./bluemap
|
||||
rm -rf ./mapcrafter
|
||||
147
README.md
147
README.md
@@ -4,38 +4,104 @@ 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.
|
||||
This project is mainly a collection of markers for PVV's minecraft server.
|
||||
It 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.
|
||||
The codebase includes a CLI tool that we use to export this data into the formats of several minecraft map implementations.
|
||||
|
||||
Grab the latest exports here:
|
||||
|
||||
- Bluemap:
|
||||
- https://pages.pvv.ntnu.no/Projects/minecraft-kartverket/main/bluemap/overworld.hocon
|
||||
- https://pages.pvv.ntnu.no/Projects/minecraft-kartverket/main/bluemap/nether.hocon
|
||||
- https://pages.pvv.ntnu.no/Projects/minecraft-kartverket/main/bluemap/the-end.hocon
|
||||
- Mapcrafter:
|
||||
- https://pages.pvv.ntnu.no/Projects/minecraft-kartverket/main/mapcrafter/markers.js
|
||||
|
||||
## Marker sets
|
||||
|
||||
Here is an overview of the different marker sets, and what they are meant for.
|
||||
Here is an overview of the different marker sets, and a short description of what goes where:
|
||||
|
||||
- **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)
|
||||
### Overworld
|
||||
|
||||
- **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
|
||||
| Directory | Description |
|
||||
|----------------|-------------|
|
||||
| Area Names | Large named areas or biomes |
|
||||
| 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, sea ports, tunnels, etc. |
|
||||
| Mines | Public mines |
|
||||
| Nature | Similar to `Area Names`, but meant for mostly untouched nature reserves or national parks. |
|
||||
| Other | Anything that doesn't fit into the other categories |
|
||||
| Railways | Railways, train tracks for transportation |
|
||||
| Roads | Roads and paths, for walking |
|
||||
| Tunnels | Underground passages, usually for transportation |
|
||||
| Villages | Villages generated by minecraft (player made cities go in `Cities`) |
|
||||
|
||||
- **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
|
||||
### Nether
|
||||
|
||||
| Directory | Description |
|
||||
|------------|-------------|
|
||||
| Ice Tracks | Ice tracks meant for highspeed travel with boats |
|
||||
| Other | Anything that doesn't fit into the other categories |
|
||||
| Portals | Nether portals that lead back to the overworld |
|
||||
| Railways | Railways, train tracks for transportation |
|
||||
|
||||
### The End
|
||||
|
||||
| Directory | Description |
|
||||
|------------|-------------|
|
||||
| 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 run the python code
|
||||
|
||||
> [!NOTE]
|
||||
> There should be no external dependencies required to run the code.
|
||||
> Please keep it that way.
|
||||
|
||||
You can either use `uv`, `nix` or the bundled `Makefile` with a bare python installation to run the project.
|
||||
|
||||
### Using uv
|
||||
|
||||
If you have [uv](https://docs.astral.sh/uv/) installed, running the code is as easy as executing
|
||||
|
||||
```bash
|
||||
uv run mckart <args>
|
||||
```
|
||||
|
||||
### Using the Makefile
|
||||
|
||||
The makefile will validate the map data, and generate both types of map exports in a directory named `out`
|
||||
|
||||
You can invoke it with:
|
||||
|
||||
```bash
|
||||
make
|
||||
ls out
|
||||
```
|
||||
|
||||
### Using nix
|
||||
|
||||
```bash
|
||||
# Run the cli tool
|
||||
nix run .# <args>
|
||||
|
||||
# Build the exports
|
||||
nix build .#bluemap-export
|
||||
nix build .#mapcrafter-export
|
||||
|
||||
# Get a python environment with development tooling
|
||||
nix develop
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> In the following sections of the readme,
|
||||
> we will assume that you are using `uv`.
|
||||
> But the other methods can also be adapted to the instructions.
|
||||
|
||||
## How to add a point marker
|
||||
|
||||
@@ -44,11 +110,11 @@ Here is an overview of the different marker sets, and what they are meant for.
|
||||
3. Run the cli tool to verify that the marker has been added correctly.
|
||||
|
||||
```bash
|
||||
uv run mckart verify
|
||||
uv run mckart validate
|
||||
uv run mckart print
|
||||
```
|
||||
|
||||
4. Open a PR
|
||||
4. Open a pull request at https://git.pvv.ntnu.no/Projects/minecraft-kartverket/pulls
|
||||
|
||||
## How to add a railway / road
|
||||
|
||||
@@ -106,6 +172,35 @@ See the other marker sets for inspiration.
|
||||
|
||||
4. Add the marker set with a description to this README file.
|
||||
|
||||
## Making exceptions for the validation tool
|
||||
|
||||
Sometimes, you might want to add a marker that doesn't pass validation.
|
||||
You can do this by setting the `skip_validation` parameter to `True` when creating the marker.
|
||||
|
||||
```python
|
||||
from lib_marker import Point, Track
|
||||
|
||||
MARKERS = [
|
||||
...,
|
||||
Point(
|
||||
name="My Invalid Marker",
|
||||
x=100,
|
||||
y=200,
|
||||
z=300,
|
||||
skip_validation=True,
|
||||
),
|
||||
Track(
|
||||
name="My Invalid Track",
|
||||
points=[
|
||||
(0, 64, 0),
|
||||
(10000, 64, 10000),
|
||||
],
|
||||
skip_validation=True,
|
||||
),
|
||||
...,
|
||||
]
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- [BlueMap documentation for markers](https://bluemap.bluecolored.de/wiki/customization/Markers.html)
|
||||
|
||||
6
flake.lock
generated
6
flake.lock
generated
@@ -2,11 +2,11 @@
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1762482733,
|
||||
"narHash": "sha256-g/da4FzvckvbiZT075Sb1/YDNDr+tGQgh4N8i5ceYMg=",
|
||||
"lastModified": 1764947035,
|
||||
"narHash": "sha256-EYHSjVM4Ox4lvCXUMiKKs2vETUSL5mx+J2FfutM7T9w=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "e1ebeec86b771e9d387dd02d82ffdc77ac753abc",
|
||||
"rev": "a672be65651c80d3f592a89b3945466584a22069",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
};
|
||||
});
|
||||
|
||||
overlays.default = final: prev: self.packages.${final.system};
|
||||
overlays.default = final: prev: self.packages.${final.stdenv.hostPlatform.system};
|
||||
|
||||
checks = forAllSystems (system: pkgs: {
|
||||
inherit (self.packages.${system}) bluemap-export mapcrafter-export;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
from textwrap import indent
|
||||
from typing import Any
|
||||
from pathlib import Path
|
||||
|
||||
from lib_marker import Point, Track
|
||||
from marker_sets import WORLDS
|
||||
from lib_marker import Point
|
||||
|
||||
|
||||
def generate_bluemap_output(output_dir: Path):
|
||||
@@ -42,8 +42,11 @@ def convert_data_to_bluemap_structure() -> dict:
|
||||
}
|
||||
|
||||
for marker in marker_set.markers:
|
||||
poi_markers = result[world_name][slug(marker_set.name)]["markers"]
|
||||
track_markers = result[world_name][slug(marker_set.name)]["markers"]
|
||||
if isinstance(marker, Point):
|
||||
result[world_name][slug(marker_set.name)][slug(marker.name)] = {
|
||||
# https://bluemap.bluecolored.de/wiki/customization/Markers.html#poi-markers
|
||||
poi_markers[slug(marker.name)] = {
|
||||
"type": "poi",
|
||||
"label": marker.name,
|
||||
"position": {
|
||||
@@ -52,6 +55,21 @@ def convert_data_to_bluemap_structure() -> dict:
|
||||
"z": marker.z,
|
||||
},
|
||||
}
|
||||
elif isinstance(marker, Track):
|
||||
# https://bluemap.bluecolored.de/wiki/customization/Markers.html#line-markers
|
||||
track_markers[slug(marker.name)] = {
|
||||
"type": "line",
|
||||
# TODO: Calculate the median point of the track for the label position
|
||||
"position": {
|
||||
"x": marker.points[0][0],
|
||||
"y": marker.points[0][1],
|
||||
"z": marker.points[0][2],
|
||||
},
|
||||
"label": marker.name,
|
||||
"line": [
|
||||
{"x": p[0], "y": p[1], "z": p[2]} for p in marker.points
|
||||
],
|
||||
}
|
||||
else:
|
||||
raise NotImplementedError(f"Unknown marker type: {marker}")
|
||||
|
||||
@@ -72,7 +90,7 @@ def to_hocon(x: Any) -> str:
|
||||
return f"[\n{'\n'.join(items)}\n]"
|
||||
elif isinstance(x, dict):
|
||||
items = [
|
||||
f' "{k}": {indent(to_hocon(v), ' ').removeprefix(' ')}'
|
||||
f' "{k}": {indent(to_hocon(v), " ").removeprefix(" ")}'
|
||||
for k, v in x.items()
|
||||
]
|
||||
return f"{{\n{'\n'.join(items)}\n}}"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from .print import pretty_print_marker_data
|
||||
from .validate import validate_marker_data
|
||||
from .print import main as pretty_print_marker_data
|
||||
from .validate import main as validate_marker_data
|
||||
|
||||
from mapcrafter_exporter import generate_mapcrafter_output
|
||||
from bluemap_exporter import generate_bluemap_output
|
||||
|
||||
@@ -2,7 +2,7 @@ from lib_marker import MarkerSet, Marker, Point, Track, Area
|
||||
from marker_sets import WORLDS
|
||||
|
||||
|
||||
def pretty_print_marker_data() -> None:
|
||||
def main() -> None:
|
||||
tree = format_tree(
|
||||
"Worlds", [format_world(name, world) for name, world in WORLDS.items()]
|
||||
)
|
||||
@@ -25,9 +25,9 @@ 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")
|
||||
return f"{marker.name} - {marker.points[0]} <--[{len(marker.points)}]--> {marker.points[-1]}"
|
||||
elif isinstance(marker, Area):
|
||||
raise NotImplementedError("Area markers are not supported")
|
||||
return f"{marker.name} ({len(marker.points)} points)"
|
||||
else:
|
||||
raise ValueError(f"Unknown marker type: {marker}")
|
||||
|
||||
|
||||
@@ -1,136 +1,248 @@
|
||||
from dataclasses import dataclass
|
||||
from textwrap import indent
|
||||
from typing import Any, Callable
|
||||
|
||||
from lib_marker import MarkerSet, Point, Track
|
||||
from marker_sets import WORLDS
|
||||
from lib_marker import Point, Track
|
||||
|
||||
|
||||
def validate_marker_data() -> None:
|
||||
def main() -> None:
|
||||
result_is_ok = True
|
||||
|
||||
worlds_to_be_validated = remove_markers_not_to_be_validated(WORLDS)
|
||||
|
||||
for test_name, test_f in _tests.items():
|
||||
results = test_f()
|
||||
results = test_f(worlds_to_be_validated)
|
||||
if len(results) > 0:
|
||||
result_is_ok = False
|
||||
print(f"[X] {test_name}")
|
||||
print()
|
||||
for result in results:
|
||||
print(f" {result}")
|
||||
print(indent(result.pretty_print(), " "))
|
||||
print()
|
||||
else:
|
||||
print(f"[✓] {test_name}")
|
||||
|
||||
if not result_is_ok:
|
||||
exit(1)
|
||||
|
||||
def validate_no_non_included_files() -> list:
|
||||
|
||||
class ValidationError:
|
||||
error_type: str
|
||||
world_name: str | None
|
||||
marker_set_name: str | None
|
||||
marker_name: str | None
|
||||
note: str | None
|
||||
details: dict[str, Any]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
error_type: str,
|
||||
world_name: str | None = None,
|
||||
marker_set_name: str | None = None,
|
||||
marker_name: str | None = None,
|
||||
note: str | None = None,
|
||||
**details,
|
||||
):
|
||||
self.error_type = error_type
|
||||
self.world_name = world_name
|
||||
self.marker_set_name = marker_set_name
|
||||
self.marker_name = marker_name
|
||||
self.note = note
|
||||
self.details = details
|
||||
|
||||
def pretty_print(self) -> str:
|
||||
result = []
|
||||
|
||||
location_parts = [
|
||||
x
|
||||
for x in (self.world_name, self.marker_set_name, self.marker_name)
|
||||
if x is not None
|
||||
]
|
||||
if len(location_parts) > 0:
|
||||
result.append(f"[{'/'.join(location_parts)}] ")
|
||||
else:
|
||||
result.append("[]")
|
||||
|
||||
result.append(indent(f"type: {self.error_type}", " "))
|
||||
|
||||
if self.note:
|
||||
result.append(indent(f"note: {self.note.removesuffix('.')}", " "))
|
||||
|
||||
for key, value in self.details.items():
|
||||
result.append(indent(f"{key}: {value}", " "))
|
||||
|
||||
return "\n".join(result)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ValidationErrorPoint:
|
||||
x: int
|
||||
y: int
|
||||
z: int
|
||||
|
||||
def __init__(self, x: int, y: int, z: int) -> None:
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = z
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"({self.x}, {self.y}, {self.z})"
|
||||
|
||||
|
||||
def remove_markers_not_to_be_validated(
|
||||
worlds: dict[str, list[MarkerSet]],
|
||||
) -> dict[str, list[MarkerSet]]:
|
||||
result = {}
|
||||
|
||||
for world_name, marker_sets in worlds.items():
|
||||
result[world_name] = []
|
||||
for marker_set in marker_sets:
|
||||
new_marker_set = MarkerSet(
|
||||
name=marker_set.name,
|
||||
show_by_default=marker_set.show_by_default,
|
||||
markers=[
|
||||
marker
|
||||
for marker in marker_set.markers
|
||||
if not marker.skip_validation
|
||||
],
|
||||
)
|
||||
result[world_name].append(new_marker_set)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def validate_no_non_included_files(
|
||||
worlds: dict[str, list[MarkerSet]],
|
||||
) -> list[ValidationError]:
|
||||
# TODO: Implement this function
|
||||
return []
|
||||
|
||||
|
||||
def validate_no_invalid_y_values() -> list:
|
||||
def validate_no_invalid_y_values(
|
||||
worlds: dict[str, list[MarkerSet]],
|
||||
) -> list[ValidationError]:
|
||||
result = []
|
||||
|
||||
for world_name, marker_sets in WORLDS.items():
|
||||
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:
|
||||
if marker.y < -64 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,
|
||||
}
|
||||
ValidationError(
|
||||
error_type="invalid_y_value",
|
||||
world_name=world_name,
|
||||
marker_set_name=marker_set.name,
|
||||
marker_name=marker.name,
|
||||
y_value=marker.y,
|
||||
note="Point has coordinate above 255 or below -64.",
|
||||
)
|
||||
)
|
||||
elif isinstance(marker, Track):
|
||||
for i, point in enumerate(marker.points):
|
||||
_, y, _ = point
|
||||
if y < 0 or y > 255:
|
||||
if y < -64 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,
|
||||
}
|
||||
ValidationError(
|
||||
error_type="invalid_y_value",
|
||||
world_name=world_name,
|
||||
marker_set_name=marker_set.name,
|
||||
marker_name=marker.name,
|
||||
index=i,
|
||||
y_value=y,
|
||||
note="Track point has coordinate above 255 or below -64.",
|
||||
)
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def validate_no_duplicate_points_in_tracks() -> list:
|
||||
def validate_no_consecutive_duplicate_points_in_tracks(
|
||||
worlds: dict[str, list[MarkerSet]],
|
||||
) -> list[ValidationError]:
|
||||
result = []
|
||||
|
||||
for world_name, marker_sets in WORLDS.items():
|
||||
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:
|
||||
for p1, p2 in zip(marker.points, marker.points[1:]):
|
||||
if p1 == p2:
|
||||
result.append(
|
||||
{
|
||||
"error_type": "duplicate_point",
|
||||
"point_a": points[point],
|
||||
"point_b": (
|
||||
world_name,
|
||||
marker_set.name,
|
||||
marker.name,
|
||||
),
|
||||
"coordinates": point,
|
||||
}
|
||||
ValidationError(
|
||||
error_type="duplicate_point_in_track",
|
||||
world_name=world_name,
|
||||
marker_set_name=marker_set.name,
|
||||
marker_name=marker.name,
|
||||
point=ValidationErrorPoint(*p1),
|
||||
note="Consecutive points in a track must not be identical, this is likely a copy-paste error.",
|
||||
)
|
||||
)
|
||||
points[point] = (world_name, marker_set.name, marker.name)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def validate_no_duplicate_marker_names() -> list:
|
||||
def validate_no_duplicate_marker_names(
|
||||
worlds: dict[str, list[MarkerSet]],
|
||||
) -> list[ValidationError]:
|
||||
result = []
|
||||
|
||||
marker_names = set()
|
||||
for world_name, marker_sets in WORLDS.items():
|
||||
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,
|
||||
}
|
||||
ValidationError(
|
||||
error_type="duplicate_marker_name",
|
||||
world_name=world_name,
|
||||
marker_set_name=marker_set.name,
|
||||
marker_name=marker.name,
|
||||
note="Marker names must be unique within a marker set.",
|
||||
)
|
||||
)
|
||||
marker_names.add(full_name)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def validate_no_duplicate_marker_set_names() -> list:
|
||||
def validate_no_duplicate_marker_set_names(
|
||||
worlds: dict[str, list[MarkerSet]],
|
||||
) -> list[ValidationError]:
|
||||
result = []
|
||||
|
||||
marker_set_names = set()
|
||||
for world_name, marker_sets in WORLDS.items():
|
||||
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),
|
||||
}
|
||||
ValidationError(
|
||||
error_type="duplicate_marker_set_name",
|
||||
world_name=world_name,
|
||||
marker_set_name=marker_set.name,
|
||||
note="Marker set names must be unique within a world.",
|
||||
)
|
||||
)
|
||||
marker_set_names.add((world_name, marker_set.name))
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def validate_no_unused_icons() -> list:
|
||||
def validate_no_unused_icons(
|
||||
worlds: dict[str, list[MarkerSet]],
|
||||
) -> list[ValidationError]:
|
||||
# TODO: Implement this function
|
||||
return []
|
||||
|
||||
|
||||
def validate_no_duplicate_points() -> list:
|
||||
def validate_no_duplicate_points(
|
||||
worlds: dict[str, list[MarkerSet]],
|
||||
) -> list[ValidationError]:
|
||||
result = []
|
||||
|
||||
for world_name, marker_sets in WORLDS.items():
|
||||
for world_name, marker_sets in worlds.items():
|
||||
points = {}
|
||||
for marker_set in marker_sets:
|
||||
for marker in marker_set.markers:
|
||||
@@ -138,63 +250,147 @@ def validate_no_duplicate_points() -> list:
|
||||
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,
|
||||
}
|
||||
ValidationError(
|
||||
error_type="duplicate_point",
|
||||
world_name=world_name,
|
||||
marker_set_name=points[point][1],
|
||||
marker_name=points[point][2],
|
||||
other_marker_set_name=marker_set.name,
|
||||
other_marker_name=marker.name,
|
||||
location=ValidationErrorPoint(*point),
|
||||
note="Two markers should not share the same coordinates.",
|
||||
)
|
||||
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:
|
||||
def validate_all_tracks_have_at_least_two_points(
|
||||
worlds: dict[str, list[MarkerSet]],
|
||||
) -> list[ValidationError]:
|
||||
result = []
|
||||
|
||||
for world_name, marker_sets in WORLDS.items():
|
||||
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,
|
||||
),
|
||||
}
|
||||
ValidationError(
|
||||
error_type="track_too_short",
|
||||
world_name=world_name,
|
||||
marker_set_name=marker_set.name,
|
||||
marker_name=marker.name,
|
||||
note="Tracks must have at least two points.",
|
||||
)
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
def validate_track_points_only_change_in_two_directions_at_once(worlds: dict[str, list[MarkerSet]]) -> list[ValidationError]:
|
||||
result = []
|
||||
|
||||
_tests = {
|
||||
for world_name, marker_sets in worlds.items():
|
||||
for marker_set in marker_sets:
|
||||
for marker in marker_set.markers:
|
||||
if isinstance(marker, Track):
|
||||
for i in range(len(marker.points) - 1):
|
||||
x1, y1, z1 = marker.points[i]
|
||||
x2, y2, z2 = marker.points[i + 1]
|
||||
|
||||
changes = sum([
|
||||
x1 != x2,
|
||||
y1 != y2,
|
||||
z1 != z2,
|
||||
])
|
||||
|
||||
if changes > 2:
|
||||
result.append(
|
||||
ValidationError(
|
||||
error_type = "invalid_track_movement",
|
||||
world_name = world_name,
|
||||
marker_set_name = marker_set.name,
|
||||
marker_name = marker.name,
|
||||
point_indices = (i, i + 1),
|
||||
point_a = ValidationErrorPoint(*marker.points[i]),
|
||||
point_b = ValidationErrorPoint(*marker.points[i + 1]),
|
||||
note = "All of X, Y, and Z changed between these two points, please only change in two directions at once.",
|
||||
)
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
def validate_xy_zy_track_ratios(worlds: dict[str, list[MarkerSet]]) -> list[ValidationError]:
|
||||
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):
|
||||
for i in range(len(marker.points) - 1):
|
||||
x1, y1, z1 = marker.points[i]
|
||||
x2, y2, z2 = marker.points[i + 1]
|
||||
|
||||
if y1 == y2:
|
||||
continue
|
||||
|
||||
if x1 != x2 and z1 != z2:
|
||||
continue
|
||||
|
||||
dy = abs(y2 - y1)
|
||||
dh = abs(x2 - x1) + abs(z2 - z1)
|
||||
|
||||
if dh == 0:
|
||||
result.append(
|
||||
ValidationError(
|
||||
error_type = "vertical_movement",
|
||||
world_name = world_name,
|
||||
marker_set_name = marker_set.name,
|
||||
marker_name = marker.name,
|
||||
point_indices = (i, i + 1),
|
||||
point_a = ValidationErrorPoint(*marker.points[i]),
|
||||
point_b = ValidationErrorPoint(*marker.points[i + 1]),
|
||||
)
|
||||
)
|
||||
elif dy - dh > 1:
|
||||
result.append(
|
||||
ValidationError(
|
||||
error_type = "excessive_slope",
|
||||
world_name = world_name,
|
||||
marker_set_name = marker_set.name,
|
||||
marker_name = marker.name,
|
||||
point_indices = (i, i + 1),
|
||||
point_a = ValidationErrorPoint(*marker.points[i]),
|
||||
point_b = ValidationErrorPoint(*marker.points[i + 1]),
|
||||
dy = dy,
|
||||
dh = dh,
|
||||
)
|
||||
)
|
||||
elif dh - dy > 1:
|
||||
result.append(
|
||||
ValidationError(
|
||||
error_type = "shallow_slope",
|
||||
world_name = world_name,
|
||||
marker_set_name = marker_set.name,
|
||||
marker_name = marker.name,
|
||||
point_indices = (i, i + 1),
|
||||
point_a = ValidationErrorPoint(*marker.points[i]),
|
||||
point_b = ValidationErrorPoint(*marker.points[i + 1]),
|
||||
dy = dy,
|
||||
dh = dh,
|
||||
)
|
||||
)
|
||||
return result
|
||||
|
||||
_tests: dict[str, Callable[[dict[str, list[MarkerSet]]], list[ValidationError]]] = {
|
||||
"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 consecutive duplicate points in tracks": validate_no_consecutive_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,
|
||||
"Track points only change in two directions at once": validate_track_points_only_change_in_two_directions_at_once,
|
||||
"Track slopes are not too steep or too shallow": validate_xy_zy_track_ratios,
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
from .marker import Marker
|
||||
|
||||
|
||||
@dataclass
|
||||
class Area(Marker):
|
||||
points: list[tuple[int, int, int]]
|
||||
icon: str | None = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
points: list[tuple[int, int, int]],
|
||||
icon: str | None = None,
|
||||
skip_validation: bool = False,
|
||||
) -> None:
|
||||
super().__init__(name, skip_validation)
|
||||
self.points = points
|
||||
self.icon = icon
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from abc import ABC
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Marker(ABC):
|
||||
name: str
|
||||
skip_validation: bool = False
|
||||
# icon: str | None = None
|
||||
|
||||
def __init__(self, name: str, skip_validation: bool = False) -> None:
|
||||
self.name = name
|
||||
self.skip_validation = skip_validation
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
from .marker import Marker
|
||||
|
||||
|
||||
@dataclass
|
||||
class Point(Marker):
|
||||
x: int
|
||||
y: int
|
||||
z: int
|
||||
icon: str | None = None
|
||||
skip_validation: bool = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
x: int,
|
||||
y: int,
|
||||
z: int,
|
||||
icon: str | None = None,
|
||||
skip_validation: bool = False,
|
||||
) -> None:
|
||||
super().__init__(name, skip_validation)
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.z = z
|
||||
self.icon = icon
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
from .marker import Marker
|
||||
|
||||
|
||||
@dataclass
|
||||
class Track(Marker):
|
||||
points: list[tuple[int, int, int]]
|
||||
icon: str | None = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
points: list[tuple[int, int, int]],
|
||||
icon: str | None = None,
|
||||
skip_validation: bool = False,
|
||||
) -> None:
|
||||
super().__init__(name, skip_validation)
|
||||
self.points = points
|
||||
self.icon = icon
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
from lib_marker import Area, Point, Track
|
||||
from marker_sets import WORLDS
|
||||
from lib_marker import Point, Track, Area
|
||||
|
||||
|
||||
def generate_mapcrafter_output(output_dir: Path):
|
||||
@@ -19,37 +20,71 @@ def generate_mapcrafter_output(output_dir: Path):
|
||||
ensure_ascii=False,
|
||||
)
|
||||
|
||||
# Fjern "[" "]" rundt teksten.
|
||||
exported_markers_json = re.sub(
|
||||
r'^\s*\[\s*(.*\})\s*\]\s*$',
|
||||
r'\1',
|
||||
exported_markers_json,
|
||||
flags=re.DOTALL)
|
||||
|
||||
template = template.replace('"@EXPORTED_MARKERS@"', exported_markers_json)
|
||||
|
||||
with (output_dir / "markers.js").open("w", encoding="utf-8") as f:
|
||||
f.write(template)
|
||||
|
||||
def get_list_entry(lst, name):
|
||||
for dings in lst:
|
||||
if 'id' in dings and dings['id'] == name:
|
||||
return dings
|
||||
return None
|
||||
|
||||
def convert_data_to_mapcrafter_structure() -> dict:
|
||||
result = {}
|
||||
def get_mapcrafter_world_name(name):
|
||||
names = {
|
||||
"Overworld": "verden",
|
||||
"Nether": "underverden",
|
||||
"The End": "enden",
|
||||
}
|
||||
|
||||
if name in names:
|
||||
return names[name]
|
||||
|
||||
raise ValueError(f"Unknown world name: {name}")
|
||||
|
||||
|
||||
def convert_data_to_mapcrafter_structure() -> list:
|
||||
result = []
|
||||
|
||||
for world_name, world_marker_sets in WORLDS.items():
|
||||
mapc_world_name = get_mapcrafter_world_name(world_name)
|
||||
for marker_set in world_marker_sets:
|
||||
if marker_set.name not in result:
|
||||
result[marker_set.name] = {
|
||||
"id": marker_set.name.lower().replace(" ", "-"),
|
||||
# https://mapcrafter.readthedocs.io/en/latest/markers.html#manually-specifying-markers
|
||||
id = marker_set.name.lower().replace(" ", "-")
|
||||
result_entry = get_list_entry(result, id)
|
||||
if not result_entry:
|
||||
result_entry = {
|
||||
"id": id,
|
||||
"name": marker_set.name,
|
||||
"showDefault": marker_set.show_by_default,
|
||||
"markers": {},
|
||||
}
|
||||
result.append(result_entry)
|
||||
|
||||
result[marker_set.name]["markers"][world_name] = []
|
||||
result_entry["markers"][mapc_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}
|
||||
result_entry["markers"][mapc_world_name].append(
|
||||
{"pos": [marker.x, marker.z, marker.y], "title": marker.name}
|
||||
)
|
||||
|
||||
elif isinstance(marker, Track):
|
||||
raise NotImplementedError("Track markers are not supported")
|
||||
print(
|
||||
f"Track markers are not natively supported in Mapcrafter, skipping '{marker.name}'..."
|
||||
)
|
||||
|
||||
elif isinstance(marker, Area):
|
||||
raise NotImplementedError("Area markers are not supported")
|
||||
print(
|
||||
f"Area markers are not natively supported in Mapcrafter, skipping '{marker.name}'..."
|
||||
)
|
||||
|
||||
else:
|
||||
raise ValueError(f"Unknown marker type: {marker}")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const MAPCRAFTER_MARKERS = [
|
||||
var MAPCRAFTER_MARKERS = [
|
||||
"@EXPORTED_MARKERS@",
|
||||
{
|
||||
//
|
||||
@@ -56,5 +56,12 @@ const MAPCRAFTER_MARKERS = [
|
||||
objekter.push(linjer);
|
||||
return L.layerGroup(objekter);
|
||||
},
|
||||
"markers" : {
|
||||
"verden" : [
|
||||
{
|
||||
"color" : "yellow",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -1,7 +1,24 @@
|
||||
from lib_marker import MarkerSet
|
||||
from lib_marker import MarkerSet, Track
|
||||
|
||||
|
||||
MARKER_SET = MarkerSet(
|
||||
name="Ice tracks",
|
||||
markers=[],
|
||||
markers=[
|
||||
Track(
|
||||
name="Sentralskøytebane Sør",
|
||||
points=[
|
||||
(0, 65, 42),
|
||||
(0, 65, 821),
|
||||
(206, 65, 821),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Sentralskøytebane Mer Sør",
|
||||
points=[
|
||||
(232, 46, 814),
|
||||
(232, 46, 1025),
|
||||
(397, 46, 1025),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
from lib_marker import MarkerSet
|
||||
from lib_marker import MarkerSet, Point
|
||||
|
||||
|
||||
MARKER_SET = MarkerSet(
|
||||
name="Other",
|
||||
markers=[],
|
||||
markers=[
|
||||
Point(
|
||||
name="Nullpunkt",
|
||||
icon=None,
|
||||
x=0,
|
||||
y=64,
|
||||
z=0,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,7 +1,36 @@
|
||||
from lib_marker import MarkerSet
|
||||
from lib_marker import MarkerSet, Point
|
||||
|
||||
|
||||
MARKER_SET = MarkerSet(
|
||||
name="Portals",
|
||||
markers=[],
|
||||
markers=[
|
||||
Point(
|
||||
name="Til Grisebukta",
|
||||
icon=None,
|
||||
x=-900,
|
||||
y=64,
|
||||
z=27,
|
||||
),
|
||||
Point(
|
||||
name="Til Hemmelig mesabiom",
|
||||
icon=None,
|
||||
x=-120,
|
||||
y=64,
|
||||
z=510,
|
||||
),
|
||||
Point(
|
||||
name="Til Biosfæren",
|
||||
icon=None,
|
||||
x=120,
|
||||
y=64,
|
||||
z=-420,
|
||||
),
|
||||
Point(
|
||||
name="Til Holmgard",
|
||||
icon=None,
|
||||
x=520,
|
||||
y=64,
|
||||
z=220,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -1,7 +1,62 @@
|
||||
from lib_marker import MarkerSet
|
||||
from lib_marker import MarkerSet, Track
|
||||
|
||||
|
||||
MARKER_SET = MarkerSet(
|
||||
name="Railways",
|
||||
markers=[],
|
||||
markers=[
|
||||
Track(
|
||||
name="Distriktsbane Sør",
|
||||
points=[
|
||||
(-24, 90, -112),
|
||||
(-22, 90, -112),
|
||||
(-22, 90, -113),
|
||||
(-22, 78, -126),
|
||||
(-22, 78, -128),
|
||||
(-19, 78, -128),
|
||||
(-19, 78, -127),
|
||||
(-19, 53, -101),
|
||||
(-19, 53, -100),
|
||||
(-18, 53, -100),
|
||||
(-13, 49, -100),
|
||||
(-13, 49, -98),
|
||||
(-13, 16, -64),
|
||||
(-13, 16, -1610),
|
||||
(-13, 35, -1630),
|
||||
(-13, 35, -1641),
|
||||
(-13, 36, -1643),
|
||||
(-13, 36, -1646),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Gruvebane Øst",
|
||||
points=[
|
||||
(-11, 16, -61),
|
||||
(1030, 16, -61),
|
||||
(1030, 16, -253),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Distriktsbane Øst",
|
||||
points=[
|
||||
(4, 90, -123),
|
||||
(1352, 90, -123),
|
||||
(1352, 90, -124),
|
||||
(1352, 85, -130),
|
||||
(1355, 85, -130),
|
||||
(1355, 85, -140),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Griseruta",
|
||||
points=[
|
||||
(4, 64, -366),
|
||||
(4, 64, -397),
|
||||
(-823, 64, -397),
|
||||
(-823, 64, -4),
|
||||
(-823, 37, 24),
|
||||
(-823, 37, 31),
|
||||
(-881, 37, 31),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@ 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 .tunnels import MARKER_SET as tunnels_marker_set
|
||||
from .villages import MARKER_SET as villages_marker_set
|
||||
|
||||
MARKER_SETS = [
|
||||
@@ -23,5 +24,6 @@ MARKER_SETS = [
|
||||
other_marker_set,
|
||||
railways_marker_set,
|
||||
roads_marker_set,
|
||||
tunnels_marker_set,
|
||||
villages_marker_set,
|
||||
]
|
||||
|
||||
@@ -4,11 +4,25 @@ MARKER_SET = MarkerSet(
|
||||
name="Area Names",
|
||||
markers=[
|
||||
Point(
|
||||
name="Andøya",
|
||||
name="Storhavet i vest",
|
||||
icon=None,
|
||||
x=2300,
|
||||
x=-2700,
|
||||
y=64,
|
||||
z=250,
|
||||
z=-500,
|
||||
),
|
||||
Point(
|
||||
name="Storhavet i vest",
|
||||
icon=None,
|
||||
x=-2100,
|
||||
y=64,
|
||||
z=1700,
|
||||
),
|
||||
Point(
|
||||
name="Snøgolfen",
|
||||
icon=None,
|
||||
x=-1300,
|
||||
y=64,
|
||||
z=380,
|
||||
),
|
||||
Point(
|
||||
name="England",
|
||||
@@ -25,11 +39,11 @@ MARKER_SET = MarkerSet(
|
||||
z=4090,
|
||||
),
|
||||
Point(
|
||||
name="Summefjord",
|
||||
name="Shirobukta",
|
||||
icon=None,
|
||||
x=-220,
|
||||
x=-940,
|
||||
y=64,
|
||||
z=2890,
|
||||
z=-1300,
|
||||
),
|
||||
Point(
|
||||
name="Vestisødet",
|
||||
@@ -38,5 +52,75 @@ MARKER_SET = MarkerSet(
|
||||
y=64,
|
||||
z=0,
|
||||
),
|
||||
Point(
|
||||
name="Svartehavet",
|
||||
icon=None,
|
||||
x=-700,
|
||||
y=64,
|
||||
z=2240,
|
||||
),
|
||||
Point(
|
||||
name="Heimhavet",
|
||||
icon=None,
|
||||
x=-500,
|
||||
y=64,
|
||||
z=1000,
|
||||
),
|
||||
Point(
|
||||
name="Summefjord",
|
||||
icon=None,
|
||||
x=-220,
|
||||
y=64,
|
||||
z=2890,
|
||||
),
|
||||
Point(
|
||||
name="Tangenhavet",
|
||||
icon=None,
|
||||
x=0,
|
||||
y=67,
|
||||
z=-2300,
|
||||
),
|
||||
Point(
|
||||
name="Nordørkenen",
|
||||
icon=None,
|
||||
x=0,
|
||||
y=67,
|
||||
z=-485,
|
||||
),
|
||||
Point(
|
||||
name="Nordhavet",
|
||||
icon=None,
|
||||
x=1050,
|
||||
y=64,
|
||||
z=-1350,
|
||||
),
|
||||
Point(
|
||||
name="Ishavet",
|
||||
icon=None,
|
||||
x=1730,
|
||||
y=64,
|
||||
z=-3070,
|
||||
),
|
||||
Point(
|
||||
name="Andøya",
|
||||
icon=None,
|
||||
x=2300,
|
||||
y=64,
|
||||
z=250,
|
||||
),
|
||||
Point(
|
||||
name="Ishavet",
|
||||
icon=None,
|
||||
x=2350,
|
||||
y=64,
|
||||
z=-2050,
|
||||
),
|
||||
Point(
|
||||
name="Bjørkesjø",
|
||||
icon=None,
|
||||
x=3050,
|
||||
y=64,
|
||||
z=-500,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -38,5 +38,19 @@ MARKER_SET = MarkerSet(
|
||||
y=64,
|
||||
z=-460,
|
||||
),
|
||||
Point(
|
||||
name="Shiro",
|
||||
icon=None,
|
||||
x=-790,
|
||||
y=64,
|
||||
z=-837,
|
||||
),
|
||||
Point(
|
||||
name="Singapore",
|
||||
icon=None,
|
||||
x=-600,
|
||||
y=64,
|
||||
z=-1130,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -38,6 +38,13 @@ MARKER_SET = MarkerSet(
|
||||
y=78,
|
||||
z=-3043,
|
||||
),
|
||||
Point(
|
||||
name="Blomenholm",
|
||||
icon=None,
|
||||
x=-295,
|
||||
y=64,
|
||||
z=2372,
|
||||
),
|
||||
Point(
|
||||
name="Huløyeid",
|
||||
icon=None,
|
||||
@@ -45,6 +52,13 @@ MARKER_SET = MarkerSet(
|
||||
y=64,
|
||||
z=234,
|
||||
),
|
||||
Point(
|
||||
name="Linder",
|
||||
icon=None,
|
||||
x=4321,
|
||||
y=64,
|
||||
z=-8778,
|
||||
),
|
||||
Point(
|
||||
name="Singapore",
|
||||
icon=None,
|
||||
@@ -80,5 +94,12 @@ MARKER_SET = MarkerSet(
|
||||
y=64,
|
||||
z=447,
|
||||
),
|
||||
Point(
|
||||
name="Østsumpøyene",
|
||||
icon=None,
|
||||
x=4070,
|
||||
y=64,
|
||||
z=2900,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
@@ -17,6 +17,13 @@ MARKER_SET = MarkerSet(
|
||||
y=64,
|
||||
z=-1480,
|
||||
),
|
||||
Point(
|
||||
name="Tretopphuset",
|
||||
icon=None,
|
||||
x=642,
|
||||
y=105,
|
||||
z=13,
|
||||
),
|
||||
Point(
|
||||
name="Nyverdenhytta",
|
||||
icon=None,
|
||||
|
||||
@@ -1,7 +1,539 @@
|
||||
from lib_marker import MarkerSet
|
||||
|
||||
from lib_marker import MarkerSet, Track
|
||||
|
||||
MARKER_SET = MarkerSet(
|
||||
name="Railways",
|
||||
markers=[],
|
||||
markers=[
|
||||
Track(
|
||||
name="Sentralbane vest",
|
||||
points=[
|
||||
(147, 71, 127),
|
||||
(44, 71, 127),
|
||||
(41, 71, 123),
|
||||
(-32, 71, 123),
|
||||
(-32, 71, 126),
|
||||
(-34, 71, 128),
|
||||
(-53, 71, 128),
|
||||
(-68, 71, 128),
|
||||
(-77, 71, 128),
|
||||
(-106, 71, 173),
|
||||
(-106, 71, 180),
|
||||
(-129, 71, 203),
|
||||
(-271, 71, 203),
|
||||
(-308, 71, 165),
|
||||
(-358, 71, 165),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Sentralbane nord",
|
||||
points=[
|
||||
(147, 71, 127),
|
||||
(147, 71, 16),
|
||||
(157, 71, 7),
|
||||
(157, 71, -65),
|
||||
(216, 71, -123),
|
||||
(216, 71, -132),
|
||||
(275, 71, -190),
|
||||
(275, 71, -203),
|
||||
(297, 71, -224),
|
||||
(297, 71, -236),
|
||||
(333, 71, -271),
|
||||
(333, 71, -272),
|
||||
(333, 72, -274),
|
||||
(333, 72, -286),
|
||||
(350, 72, -302),
|
||||
(350, 72, -424),
|
||||
(350, 72, -421),
|
||||
(328, 72, -421),
|
||||
(310, 72, -439),
|
||||
(310, 72, -481),
|
||||
(293, 72, -497),
|
||||
(293, 72, -518),
|
||||
(285, 72, -525),
|
||||
(285, 72, -647),
|
||||
(306, 72, -667),
|
||||
(306, 72, -852),
|
||||
(304, 72, -852),
|
||||
(304, 72, -854),
|
||||
(302, 72, -854),
|
||||
(306, 72, -854),
|
||||
(306, 72, -1003),
|
||||
(345, 72, -1041),
|
||||
(345, 72, -1095),
|
||||
(412, 72, -1161),
|
||||
(412, 72, -1181),
|
||||
(482, 72, -1250),
|
||||
(482, 72, -1278),
|
||||
(564, 72, -1359),
|
||||
(564, 72, -1374),
|
||||
(642, 72, -1451),
|
||||
(642, 72, -1464),
|
||||
(716, 72, -1537),
|
||||
(716, 72, -1552),
|
||||
(775, 72, -1610),
|
||||
(775, 72, -2316),
|
||||
(770, 72, -2316),
|
||||
(770, 72, -2318),
|
||||
(776, 72, -2318),
|
||||
(775, 72, -2318),
|
||||
(775, 72, -2319),
|
||||
(776, 72, -2319),
|
||||
(776, 72, -2323),
|
||||
(776, 81, -2333),
|
||||
(776, 81, -2554),
|
||||
(776, 86, -2560),
|
||||
(776, 86, -2700),
|
||||
(729, 86, -2700),
|
||||
(729, 86, -2989),
|
||||
(729, 88, -2992),
|
||||
(729, 88, -3011),
|
||||
(685, 88, -3011),
|
||||
(685, 88, -3010),
|
||||
(682, 88, -3010),
|
||||
(682, 88, -3012),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Biosfæren Lokaltog",
|
||||
points=[
|
||||
(684, 88, -3014),
|
||||
(687, 88, -3014),
|
||||
(689, 87, -3014),
|
||||
(692, 85, -3014),
|
||||
(693, 85, -3014),
|
||||
(695, 84, -3014),
|
||||
(697, 83, -3014),
|
||||
(699, 82, -3014),
|
||||
(701, 81, -3014),
|
||||
(703, 80, -3014),
|
||||
(705, 79, -3014),
|
||||
(707, 78, -3014),
|
||||
(710, 76, -3014),
|
||||
(713, 74, -3014),
|
||||
(715, 73, -3014),
|
||||
(718, 71, -3014),
|
||||
(722, 68, -3014),
|
||||
(727, 64, -3014),
|
||||
(729, 63, -3014),
|
||||
(732, 61, -3014),
|
||||
(737, 62, -3014),
|
||||
(739, 63, -3014),
|
||||
(741, 64, -3014),
|
||||
(745, 67, -3014),
|
||||
(747, 67, -3014),
|
||||
(747, 67, -3020),
|
||||
(747, 66, -3022),
|
||||
(747, 66, -3041),
|
||||
(747, 67, -3043),
|
||||
(747, 67, -3045),
|
||||
(747, 68, -3047),
|
||||
(747, 68, -3048),
|
||||
(747, 70, -3051),
|
||||
(747, 71, -3053),
|
||||
(747, 71, -3057),
|
||||
(747, 72, -3059),
|
||||
(747, 72, -3062),
|
||||
(747, 73, -3064),
|
||||
(747, 73, -3072),
|
||||
(807, 132, -3072),
|
||||
(809, 132, -3072),
|
||||
(809, 132, -3070),
|
||||
(830, 132, -3070),
|
||||
(830, 132, -3068),
|
||||
(833, 132, -3068),
|
||||
(833, 132, -3070),
|
||||
(834, 132, -3070),
|
||||
(833, 132, -3070),
|
||||
(833, 132, -3068),
|
||||
(830, 132, -3070),
|
||||
(830, 132, -3076),
|
||||
(809, 132, -3076),
|
||||
(809, 132, -3074),
|
||||
(807, 132, -3074),
|
||||
(747, 73, -3074),
|
||||
(747, 73, -3073),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Tangenbanen",
|
||||
points=[
|
||||
(680, 88, -3014),
|
||||
(523, 88, -3014),
|
||||
(508, 74, -3014),
|
||||
(483, 74, -3014),
|
||||
(483, 74, -3016),
|
||||
(475, 74, -3016),
|
||||
(473, 75, -3016),
|
||||
(451, 75, -3016),
|
||||
(446, 79, -3016),
|
||||
(445, 79, -3016),
|
||||
(445, 79, -3017),
|
||||
(440, 79, -3017),
|
||||
(440, 79, -3016),
|
||||
(440, 79, -3018),
|
||||
(435, 79, -3018),
|
||||
(431, 82, -3018),
|
||||
(485, 82, -3018),
|
||||
(474, 72, -3018),
|
||||
(306, 72, -3018),
|
||||
(306, 72, -2998),
|
||||
(83, 72, -2998),
|
||||
(83, 72, -3000),
|
||||
(79, 72, -3000),
|
||||
(79, 72, -2998),
|
||||
(76, 72, -2998),
|
||||
(72, 69, -2998),
|
||||
(72, 65, -3003),
|
||||
(63, 57, -3003),
|
||||
(60, 57, -3003),
|
||||
(60, 57, -2965),
|
||||
(58, 57, -2963),
|
||||
(58, 57, -2951),
|
||||
(47, 57, -2951),
|
||||
(44, 59, -2951),
|
||||
(44, 59, -2895),
|
||||
(22, 59, -2895),
|
||||
(22, 59, -2887),
|
||||
(17, 59, -2887),
|
||||
(17, 59, -2877),
|
||||
(17, 59, -2887),
|
||||
(28, 59, -2887),
|
||||
(28, 59, -2889),
|
||||
(38, 68, -2889),
|
||||
(40, 68, -2889),
|
||||
(40, 72, -2884),
|
||||
(36, 72, -2884),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Sentralbane Sør",
|
||||
points=[
|
||||
(156, 71, 132),
|
||||
(156, 71, 176),
|
||||
(175, 71, 194),
|
||||
(175, 71, 653),
|
||||
(164, 71, 663),
|
||||
(164, 71, 725),
|
||||
(126, 71, 763),
|
||||
(94, 71, 763),
|
||||
(69, 71, 788),
|
||||
(69, 71, 797),
|
||||
(31, 71, 835),
|
||||
(19, 71, 835),
|
||||
(1, 71, 854),
|
||||
(-21, 71, 854),
|
||||
(-60, 71, 893),
|
||||
(-60, 71, 991),
|
||||
(-58, 71, 991),
|
||||
(-58, 71, 993),
|
||||
(-58, 71, 985),
|
||||
(61, 71, 985),
|
||||
(88, 71, 1013),
|
||||
(117, 71, 1013),
|
||||
(120, 71, 1016),
|
||||
(120, 71, 1034),
|
||||
(173, 71, 1086),
|
||||
(173, 71, 1338),
|
||||
(139, 71, 1371),
|
||||
(139, 71, 1501),
|
||||
(71, 71, 1569),
|
||||
(-11, 71, 1569),
|
||||
(-67, 71, 1626),
|
||||
(-149, 71, 1626),
|
||||
(-194, 71, 1671),
|
||||
(-194, 71, 1961),
|
||||
(-243, 71, 2010),
|
||||
(-291, 71, 2010),
|
||||
(-314, 71, 2033),
|
||||
(-314, 71, 2065),
|
||||
(-358, 71, 2109),
|
||||
(-387, 71, 2109),
|
||||
(-399, 71, 2122),
|
||||
(-406, 71, 2122),
|
||||
(-424, 71, 2140),
|
||||
(-424, 71, 2260),
|
||||
(-416, 71, 2267),
|
||||
(-416, 71, 2294),
|
||||
(-395, 71, 2314),
|
||||
(-395, 71, 2406),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Sentralbane Øst",
|
||||
points=[
|
||||
(157, 71, 129),
|
||||
(230, 71, 129),
|
||||
(239, 71, 139),
|
||||
(286, 71, 139),
|
||||
(325, 71, 179),
|
||||
(422, 71, 179),
|
||||
(426, 74, 179),
|
||||
(437, 74, 179),
|
||||
(455, 74, 160),
|
||||
(479, 74, 160),
|
||||
(515, 74, 123),
|
||||
(547, 74, 123),
|
||||
(565, 74, 104),
|
||||
(636, 74, 104),
|
||||
(646, 74, 93),
|
||||
(727, 74, 93),
|
||||
(748, 74, 71),
|
||||
(760, 74, 71),
|
||||
(786, 74, 44),
|
||||
(811, 74, 44),
|
||||
(811, 74, 43),
|
||||
(812, 74, 43),
|
||||
(814, 73, 43),
|
||||
(820, 73, 43),
|
||||
(822, 74, 43),
|
||||
(826, 74, 43),
|
||||
(846, 74, 23),
|
||||
(846, 74, 7),
|
||||
(886, 74, -33),
|
||||
(908, 74, -33),
|
||||
(946, 74, -71),
|
||||
(946, 74, -83),
|
||||
(977, 74, -114),
|
||||
(984, 74, -114),
|
||||
(1022, 74, -152),
|
||||
(1022, 74, -164),
|
||||
(1054, 74, -195),
|
||||
(1054, 74, -202),
|
||||
(1079, 74, -227),
|
||||
(1086, 74, -227),
|
||||
(1117, 74, -259),
|
||||
(1124, 74, -259),
|
||||
(1155, 74, -291),
|
||||
(1167, 74, -291),
|
||||
(1188, 74, -313),
|
||||
(1223, 74, -313),
|
||||
(1249, 74, -340),
|
||||
(1257, 74, -340),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Østbane B",
|
||||
points=[
|
||||
(817, 73, 43),
|
||||
(817, 73, 46),
|
||||
(817, 74, 48),
|
||||
(817, 74, 49),
|
||||
(817, 72, 52),
|
||||
(828, 72, 62),
|
||||
(828, 72, 63),
|
||||
(828, 71, 65),
|
||||
(828, 71, 71),
|
||||
(828, 70, 73),
|
||||
(828, 70, 164),
|
||||
(830, 70, 166),
|
||||
(848, 70, 166),
|
||||
(848, 70, 167),
|
||||
(851, 70, 167),
|
||||
(851, 70, 168),
|
||||
(853, 70, 168),
|
||||
(857, 70, 173),
|
||||
(860, 70, 173),
|
||||
(860, 70, 174),
|
||||
(940, 70, 174),
|
||||
(944, 70, 178),
|
||||
(944, 70, 213),
|
||||
(944, 69, 215),
|
||||
(944, 69, 216),
|
||||
(944, 68, 218),
|
||||
(944, 67, 220),
|
||||
(944, 66, 222),
|
||||
(944, 65, 224),
|
||||
(944, 65, 473),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Tosjødalen gruveekspress",
|
||||
points=[
|
||||
(943, 65, 473),
|
||||
(943, 65, 436),
|
||||
(941, 65, 436),
|
||||
(941, 64, 438),
|
||||
(941, 64, 439),
|
||||
(941, 63, 441),
|
||||
(941, 62, 443),
|
||||
(941, 62, 444),
|
||||
(940, 62, 444),
|
||||
(938, 61, 444),
|
||||
(937, 61, 444),
|
||||
(935, 60, 444),
|
||||
(934, 60, 444),
|
||||
(934, 60, 443),
|
||||
(934, 59, 441),
|
||||
(934, 58, 439),
|
||||
(934, 58, 438),
|
||||
(935, 58, 438),
|
||||
(937, 57, 438),
|
||||
(938, 57, 438),
|
||||
(940, 56, 438),
|
||||
(942, 56, 438),
|
||||
(942, 56, 512),
|
||||
(946, 56, 512),
|
||||
(954, 63, 512),
|
||||
(954, 63, 519),
|
||||
(954, 64, 521),
|
||||
(954, 64, 522),
|
||||
(960, 64, 522),
|
||||
(962, 65, 522),
|
||||
(969, 65, 522),
|
||||
(971, 64, 522),
|
||||
(972, 64, 522),
|
||||
(974, 63, 522),
|
||||
(974, 63, 625),
|
||||
(972, 63, 625),
|
||||
(970, 64, 625),
|
||||
(966, 67, 625),
|
||||
(957, 75, 625),
|
||||
(956, 75, 625),
|
||||
(952, 72, 625),
|
||||
(935, 72, 625),
|
||||
(935, 72, 621),
|
||||
(928, 72, 621),
|
||||
(928, 72, 623),
|
||||
(929, 72, 623),
|
||||
(929, 70, 626),
|
||||
(927, 69, 626),
|
||||
(927, 68, 624),
|
||||
(929, 67, 624),
|
||||
(929, 65, 627),
|
||||
(928, 65, 627),
|
||||
(928, 64, 629),
|
||||
(927, 64, 629),
|
||||
(927, 64, 628),
|
||||
(927, 61, 624),
|
||||
(927, 61, 623),
|
||||
(931, 61, 623),
|
||||
(933, 60, 623),
|
||||
(933, 59, 625),
|
||||
(932, 59, 625),
|
||||
(930, 58, 625),
|
||||
(930, 58, 624),
|
||||
(930, 57, 622),
|
||||
(932, 56, 622),
|
||||
(932, 56, 623),
|
||||
(933, 56, 623),
|
||||
(933, 55, 625),
|
||||
(931, 54, 625),
|
||||
(931, 53, 623),
|
||||
(933, 52, 623),
|
||||
(933, 51, 625),
|
||||
(932, 51, 625),
|
||||
(930, 50, 625),
|
||||
(930, 49, 623),
|
||||
(932, 48, 623),
|
||||
# TODO: denne går egentlig lengre, men kartet viser ikke mer.
|
||||
# Må undersøkes i spillet selv.
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Shiro Monorail",
|
||||
points=[
|
||||
(-689, 73, -770),
|
||||
(-685, 73, -770),
|
||||
(-685, 73, -765),
|
||||
(-685, 74, -764),
|
||||
(-685, 74, -760),
|
||||
(-720, 74, -760),
|
||||
(-737, 76, -760),
|
||||
(-737, 76, -646),
|
||||
(-739, 77, -646),
|
||||
(-742, 77, -646),
|
||||
(-744, 78, -646),
|
||||
(-759, 92, -646),
|
||||
(-815, 92, -646),
|
||||
(-815, 92, -643),
|
||||
(-815, 101, -633),
|
||||
(-815, 101, -385),
|
||||
(-815, 97, -380),
|
||||
(-815, 97, -377),
|
||||
(-815, 90, -370),
|
||||
(-813, 90, -370),
|
||||
(-813, 73, -352),
|
||||
(-813, 73, -306),
|
||||
(-813, 68, -300),
|
||||
(-813, 68, -298),
|
||||
(-817, 68, -298),
|
||||
(-819, 67, -298),
|
||||
(-822, 67, -298),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Chikatetsu End-sen",
|
||||
points=[
|
||||
(-772, 63, -953),
|
||||
(-780, 63, -953),
|
||||
(-780, 63, -952),
|
||||
(-787, 63, -952),
|
||||
(-789, 63, -942),
|
||||
(-789, 62, -940),
|
||||
(-789, 61, -938),
|
||||
(-789, 60, -936),
|
||||
(-789, 59, -934),
|
||||
(-789, 58, -932),
|
||||
(-789, 57, -930),
|
||||
(-789, 56, -928),
|
||||
(-789, 55, -926),
|
||||
(-789, 54, -924),
|
||||
(-789, 53, -922),
|
||||
(-789, 52, -920),
|
||||
(-789, 51, -918),
|
||||
(-789, 50, -916),
|
||||
(-789, 49, -914),
|
||||
(-789, 48, -912),
|
||||
(-789, 47, -910),
|
||||
(-789, 46, -908),
|
||||
(-789, 45, -906),
|
||||
(-789, 44, -904),
|
||||
(-789, 43, -902),
|
||||
(-789, 42, -900),
|
||||
(-789, 41, -898),
|
||||
(-789, 40, -896),
|
||||
(-789, 39, -894),
|
||||
(-789, 38, -892),
|
||||
(-789, 37, -890),
|
||||
(-789, 36, -888),
|
||||
(-789, 35, -886),
|
||||
(-789, 34, -884),
|
||||
(-789, 33, -882),
|
||||
(-789, 32, -880),
|
||||
(-789, 31, -878),
|
||||
(-789, 30, -876),
|
||||
(-789, 29, -874),
|
||||
(-789, 28, -872),
|
||||
(-789, 27, -870),
|
||||
(-789, 26, -868),
|
||||
(-789, 25, -866),
|
||||
(-789, 25, -857),
|
||||
(-756, 25, -825),
|
||||
(-756, 25, -218),
|
||||
(-765, 25, -218),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Chikatetsu Kyassuru-sen",
|
||||
points=[
|
||||
(-772, 63, -945),
|
||||
(-780, 63, -945),
|
||||
(-780, 60, -941),
|
||||
(-780, 60, -523),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Chikatetsu Doukutsu-sen",
|
||||
points=[
|
||||
(-688, 72, -772),
|
||||
(-682, 72, -772),
|
||||
(-682, 72, -765),
|
||||
(-682, 31, -723),
|
||||
(-682, 31, -715),
|
||||
(-682, 15, -698),
|
||||
(-682, 15, -691),
|
||||
(-682, -48, -627),
|
||||
(-802, -48, -627),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
30
src/marker_sets/overworld/tunnels.py
Normal file
30
src/marker_sets/overworld/tunnels.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from lib_marker import MarkerSet, Track
|
||||
|
||||
MARKER_SET = MarkerSet(
|
||||
name="Tunnels",
|
||||
markers=[
|
||||
Track(
|
||||
name="Danio's Warp Tunnel End Connection",
|
||||
points=[
|
||||
(-829, 23, -196),
|
||||
(-981, 23, -196),
|
||||
(-997, 15, -196),
|
||||
(-1000, 15, -196),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Danio's Warp Tunnel North",
|
||||
points=[
|
||||
(-1000, 23, -1161),
|
||||
(-1000, 23, 1000),
|
||||
],
|
||||
),
|
||||
Track(
|
||||
name="Danio's Warp Tunnel South",
|
||||
points=[
|
||||
(-1000, 23, 1000),
|
||||
(-1000, 23, 4980),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
Reference in New Issue
Block a user