From 1e7109403a7595877bf8dbd6aeec00e37cbf015f Mon Sep 17 00:00:00 2001
From: anima
Date: Fri, 13 Nov 2026 00:59:44 +0100
Subject: [PATCH] initial code snippets
---
libs/utils/general.py | 4 ++
libs/utils/item.py | 59 +++++++++++++++++++++
libs/utils/map.py | 120 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 183 insertions(+)
create mode 100644 libs/utils/general.py
create mode 100644 libs/utils/item.py
create mode 100644 libs/utils/map.py
diff --git a/libs/utils/general.py b/libs/utils/general.py
new file mode 100644
index 0000000..59c78c7
--- /dev/null
+++ b/libs/utils/general.py
@@ -0,0 +1,4 @@
+console = get_component("console")
+
+def default():
+ console.clear()
diff --git a/libs/utils/item.py b/libs/utils/item.py
new file mode 100644
index 0000000..4653794
--- /dev/null
+++ b/libs/utils/item.py
@@ -0,0 +1,59 @@
+from __builtins__ import OutpostComponent, OutpostRef, LargeWarehouse, Warehouse, StorageBin
+
+class Item:
+ @staticmethod
+ def get_storages(
+ item: str, outpost: OutpostComponent | OutpostRef | str = None,
+ sbin: bool = True, whouse: bool = True,
+ nearest: tuple[int, int] | None = None
+ ) -> list[StorageBin | Warehouse | LargeWarehouse]:
+ """get all storages (without inventory) for with a given item
+
+ Args:
+ item (str): item id
+ outpost (OutpostComponent | OutpostRef | str): outpost to search for storages
+ sbin (bool): control StorageBin search. default True
+ whouse (bool): control Warehouese & LargeWarehouse search. default True
+ TODO: nearest (tuple[int, int] | None): on True get only the nearest storage for position (x, y). None = get all. default None (planed!)
+ Return:
+ list[StorageBin | Warehouse | LargeWarehouse]
+ """
+ # check type of item
+ if not isinstance(item, str):
+ return list()
+
+ # check type of outpost
+ if outpost is None:
+ # get all outposts
+ for op in get_component("outpost_network").outposts():
+ outposts = get_component("outpost_network").outposts()
+ else:
+ # ensure outpost is a OutpostComponent
+ if isinstance(outpost, str): outpost = get_component(outpost)
+ if isinstance(outpost, OutpostRef): outpost = get_component(outpost.id)
+ if not isinstance(outpost, OutpostComponent):
+ return list()
+ outposts = [outpost]
+
+ storages = list()
+ for outpost in outposts:
+ # search for StorgageBins
+ if sbin:
+ for b in outpost.buildings("storage_bin"):
+ storage = get_component(b.id)
+ if item == storage.get_material(): storages.append(storage)
+
+ # search for Warehouse and LargeWarehouse
+ if whouse:
+ for w in outpost.buildings("warehouse"):
+ storage = get_component(w.id)
+ if item in storage.materials(): storages.append(storage)
+
+ # check if nearest is a tuple and has 2 int insert
+ if isinstance(nearest, tuple) and len(nearest) == 2 and all(isinstance(v, int) for v in nearest):
+ pass # TODO
+ return storages
+
+ def count(item, outpost: str = None):
+ pass
+
diff --git a/libs/utils/map.py b/libs/utils/map.py
new file mode 100644
index 0000000..3712f4f
--- /dev/null
+++ b/libs/utils/map.py
@@ -0,0 +1,120 @@
+from __builtins__ import MiningSite, PointOfInterest
+import json
+
+
+
+class Map:
+ """Utility class for map interactions"""
+ journal = get_component("journal")
+ planet = get_component("nocturna")
+ marks = get_component("markers")
+ outposts = get_component("outpost_network")
+ note = get_component("notebook")
+ construct = get_component("construction_blueprint")
+
+ ## point of intrest methods
+ @staticmethod
+ def get_unknown_pois() -> list[PointOfInterest]:
+ """return all unscanned points of intrests"""
+ return [poi for poi in Map.planet.points_of_interest() if not poi.scanned]
+
+ @staticmethod
+ def get_known_pois() -> list[PointOfInterest]:
+ """return all scanned points of intrests"""
+ return [poi for poi in Map.planet.points_of_interest() if poi.scanned]
+
+ @staticmethod
+ def filter_blocklist_pois(pois: list[PointOfInterest], sonar: str) -> list[PointOfInterest]:
+ if not isinstance(pois, list):
+ return list()
+ blocklist = Map.get_blocklist_pois(sonar)
+ if not isinstance(blocklist, list) or len(blocklist) == 0:
+ return pois
+ filterd_pois = list()
+ for poi in pois:
+ if not isinstance(poi, PointOfInterest):
+ continue
+ if not f"{poi.x}{poi.y}" in blocklist:
+ filterd_pois.append(poi)
+ return filterd_pois
+
+ @staticmethod
+ def get_blocklist_pois(sonar: str) -> list[str]:
+ """get blocklisted point of interests for sonar level
+
+ Args:
+ sonar (int): sonar tier. get via vehicle.sonar.tier()
+ Return:
+ list[str]: list of coords from blocklist, point of intersts like str(x) + str(y)
+ """
+ if not sonar in ["basic", "wide", "deep", "seismic"]:
+ return list()
+ pointer = f"map.scan.blocked.{sonar}"
+ if not Map.note.has(pointer):
+ return list()
+ response = json.loads( Map.note.get(pointer) )
+ return response
+
+ @staticmethod
+ def add_blocklist_poi(poi: PointOfInterest, sonar: str) -> bool:
+ """add a new poi to blocklist for sonar level
+
+ Args:
+ poi (PointOfInterest): poi to blacklist
+ sonar (int): sonar tier. get via vehicle.sonar.tier()
+ Return:
+ bool: True if saved successfully
+ """
+ if not isinstance(poi, PointOfInterest):
+ return False
+ if not sonar in ["basic", "wide", "deep", "seismic"]:
+ return False
+ blocklist = Map.get_blocklist_pois(sonar)
+ blocklist.append(f"{poi.x}{poi.y}")
+ blocklist = json.dumps( blocklist )
+ response = Map.note.set( f"map.scan.blocked.{sonar}", blocklist )
+ if response == "ok": return True
+ return False
+
+ ## mining methods
+ @staticmethod
+ def get_mines_by_ressource(ressource: str) -> list[MiningSite]:
+ """collect all known mines with ressource type
+ [[helper]]
+
+ Args:
+ ressources (str): ressource id name like `iron_ore` or `silicon`
+ Return:
+ `list[MiningSite]`: known mines of type `ressource`
+ """
+ mines_by_item = dict()
+
+ # collect all MiningSites and sort by type
+ for site in Map.journal.discovered_sites("nocturna"):
+ if not isinstance(site, MiningSite):
+ continue
+ if site.item_id not in mines_by_item:
+ mines_by_item[site.item_id] = list()
+
+ mines_by_item[site.item_id].append(site)
+
+ # check if ressource in mines and return a list
+ if ressource in mines_by_item.keys():
+ return mines_by_item[ressource]
+ else: return list()
+
+ @staticmethod
+ def get_mines_iron() -> list[MiningSite]:
+ """short method for `get_mines_by_ressources` directly for ìron_ore`"""
+ return Map.get_mines_by_ressource("iron_ore")
+
+ @staticmethod
+ def get_mines_silicon() -> list[MiningSite]:
+ """short method for `get_mines_by_ressources` directly for `silicon`"""
+ return Map.get_mines_by_ressource("silicon")
+
+ @staticmethod
+ def get_mines_titan() -> list[MiningSite]:
+ """short method for `get_mines_by_ressources` directly for `titanium`"""
+ return Map.get_mines_by_ressource("titanium")
+
\ No newline at end of file