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