From 52a3fdc32823c997c4242100eba3391e413edecc Mon Sep 17 00:00:00 2001 From: Andrew Miner Date: Wed, 8 Oct 2025 21:55:10 -0600 Subject: [PATCH] Add mypy; Consolidate catalog classes --- mcpacker/__init___test.py | 22 + mcpacker/emit/datapack/locator.py | 3 +- mcpacker/emit/incontrol/__init__.py | 0 mcpacker/emit/incontrol/spawnerruleemitter.py | 4 + mcpacker/emit/markdown/biomereport.py | 2 +- mcpacker/emit/markdown/mineralreport.py | 2 +- mcpacker/emit/markdown/mobreport.py | 4 +- mcpacker/emit/markdown/report.py | 4 +- mcpacker/json.py | 24 + mcpacker/model/catalog.py | 74 +++ mcpacker/model/catalog_test.py | 88 ++++ mcpacker/model/core/dimension.py | 21 + .../mod_test.py => core/dimension_test.py} | 2 +- mcpacker/model/core/ecology/biome.py | 4 +- mcpacker/model/core/ecology/biomecatalog.py | 30 +- mcpacker/model/core/ecology/biomefilter.py | 5 +- mcpacker/model/core/ecology/biometrait.py | 14 +- mcpacker/model/core/ecology/humidity.py | 3 +- mcpacker/model/core/fauna/active.py | 15 +- mcpacker/model/core/fauna/mob.py | 8 +- mcpacker/model/core/fauna/mob_test.py | 12 +- mcpacker/model/core/fauna/mobcatalog.py | 28 +- mcpacker/model/core/fauna/mobplacement.py | 15 - mcpacker/model/core/fauna/mobspawn.py | 20 + ...{mobplacement_test.py => mobspawn_test.py} | 14 +- mcpacker/model/core/fauna/mobspawncatalog.py | 8 + .../model/core/fauna/mobspawncatalog_test.py | 8 + .../model/core/geology/deposit/__init__.py | 1 + .../core/geology/deposit/metaldeposit.py | 5 +- mcpacker/model/core/geology/depositcatalog.py | 27 +- .../model/core/geology/depositcatalog_test.py | 52 +-- mcpacker/model/core/geology/mineral.py | 15 +- mcpacker/model/core/geology/mineralcatalog.py | 26 +- .../model/core/geology/mineralcatalog_test.py | 33 +- mcpacker/model/core/habitat.py | 40 +- mcpacker/model/core/material/block.py | 7 +- mcpacker/model/core/material/blockcatalog.py | 30 +- mcpacker/model/core/material/item.py | 5 +- mcpacker/model/core/material/itemcatalog.py | 9 +- mcpacker/model/core/material/loot.py | 7 +- mcpacker/model/core/material/loottable.py | 8 +- .../model/core/{placement.py => spawn.py} | 16 +- .../core/{placement_test.py => spawn_test.py} | 14 +- mcpacker/model/core/world.py | 15 +- mcpacker/model/datapack/__init__.py | 29 +- mcpacker/model/datapack/blockstate.py | 8 +- mcpacker/model/datapack/blockstate_test.py | 4 +- .../datapack/blockstateprovider/__init__.py | 5 + .../blockstateprovider/simplestateprovider.py | 9 +- .../simplestateprovider_test.py | 6 +- .../datapack/configuredfeature/randompatch.py | 10 +- .../configuredfeature/randompatch_test.py | 8 +- .../datapack/configuredfeature/simpleblock.py | 9 +- .../configuredfeature/simpleblock_test.py | 8 +- mcpacker/model/datapack/mod.py | 17 - mcpacker/model/datapack/moddata.py | 23 + .../mod_test.py => datapack/moddata_test.py} | 3 +- mcpacker/model/incontrol/__init__.py | 0 mcpacker/model/incontrol/condition.py | 38 ++ mcpacker/model/incontrol/extracondition.py | 44 ++ mcpacker/model/incontrol/spawnerrule.py | 41 ++ mcpacker/model/modpack.py | 1 + mcpacker/model/resourcepack/__init__.py | 29 +- mcpacker/model/resourcepack/kind.py | 2 +- mcpacker/model/resourcepack/mod.py | 8 - mcpacker/model/resourcepack/modresource.py | 9 + .../model/resourcepack/modresource_test.py | 8 + mcpacker/pack/mysteriousisland/addblocks.py | 2 +- mcpacker/pack/mysteriousisland/adddeposits.py | 27 +- mcpacker/pack/mysteriousisland/addmobs.py | 436 +++--------------- .../pack/mysteriousisland/addmobspawns.py | 411 +++++++++++++++++ .../mysteriousisland/addmobspawns_test.py | 7 + mcpacker/ui/runner.py | 4 +- requirements.txt | 3 + 74 files changed, 1169 insertions(+), 784 deletions(-) create mode 100644 mcpacker/__init___test.py create mode 100644 mcpacker/emit/incontrol/__init__.py create mode 100644 mcpacker/emit/incontrol/spawnerruleemitter.py create mode 100644 mcpacker/json.py create mode 100644 mcpacker/model/catalog.py create mode 100644 mcpacker/model/catalog_test.py create mode 100644 mcpacker/model/core/dimension.py rename mcpacker/model/{datapack/mod_test.py => core/dimension_test.py} (78%) delete mode 100644 mcpacker/model/core/fauna/mobplacement.py create mode 100644 mcpacker/model/core/fauna/mobspawn.py rename mcpacker/model/core/fauna/{mobplacement_test.py => mobspawn_test.py} (82%) create mode 100644 mcpacker/model/core/fauna/mobspawncatalog.py create mode 100644 mcpacker/model/core/fauna/mobspawncatalog_test.py rename mcpacker/model/core/{placement.py => spawn.py} (57%) rename mcpacker/model/core/{placement_test.py => spawn_test.py} (83%) delete mode 100644 mcpacker/model/datapack/mod.py create mode 100644 mcpacker/model/datapack/moddata.py rename mcpacker/model/{resourcepack/mod_test.py => datapack/moddata_test.py} (76%) create mode 100644 mcpacker/model/incontrol/__init__.py create mode 100644 mcpacker/model/incontrol/condition.py create mode 100644 mcpacker/model/incontrol/extracondition.py create mode 100644 mcpacker/model/incontrol/spawnerrule.py delete mode 100644 mcpacker/model/resourcepack/mod.py create mode 100644 mcpacker/model/resourcepack/modresource.py create mode 100644 mcpacker/model/resourcepack/modresource_test.py create mode 100644 mcpacker/pack/mysteriousisland/addmobspawns.py create mode 100644 mcpacker/pack/mysteriousisland/addmobspawns_test.py diff --git a/mcpacker/__init___test.py b/mcpacker/__init___test.py new file mode 100644 index 0000000..2bfa7f1 --- /dev/null +++ b/mcpacker/__init___test.py @@ -0,0 +1,22 @@ +import subprocess + +#################################################################################################### + +def test_typeCompliance(): + command = [ + "mypy", + #"--allow-untyped-defs", + #"--follow-imports", "skip", + #"--ignore-missing-imports", + #"--no-check-untyped-defs", + "--python-version", "3.10", + "--show-error-codes", + "mcpacker" + ] + result = subprocess.run(command, capture_output=True, text=True) + print(result.stdout) + + returncode = result.returncode + assert returncode == 0 + + diff --git a/mcpacker/emit/datapack/locator.py b/mcpacker/emit/datapack/locator.py index 2b05e63..7b3ff1b 100644 --- a/mcpacker/emit/datapack/locator.py +++ b/mcpacker/emit/datapack/locator.py @@ -5,8 +5,9 @@ from os.path import join class Locator: - def __init__(self, basePath:str): + def __init__(self, basePath:str, mod:str): self.basePath = basePath + self.mod = mod def biomeModifier(self) -> str: return join(self.basePath, "data", self.mod, "neoforge", "biome_modifier") diff --git a/mcpacker/emit/incontrol/__init__.py b/mcpacker/emit/incontrol/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mcpacker/emit/incontrol/spawnerruleemitter.py b/mcpacker/emit/incontrol/spawnerruleemitter.py new file mode 100644 index 0000000..a9aede9 --- /dev/null +++ b/mcpacker/emit/incontrol/spawnerruleemitter.py @@ -0,0 +1,4 @@ +class SpawnerRuleEmitter: + + def __init__(self): + pass diff --git a/mcpacker/emit/markdown/biomereport.py b/mcpacker/emit/markdown/biomereport.py index 8715f7b..8494afc 100644 --- a/mcpacker/emit/markdown/biomereport.py +++ b/mcpacker/emit/markdown/biomereport.py @@ -10,7 +10,7 @@ class BiomeReport(Report): super().__init__("biomes.md", pack) def build(self): - for biome in self.pack.world.biomes.all(): + for biome in self.pack.world.biomes: self.line(f"# Biome: {biome.gameId} ({biome.city})") self.line() diff --git a/mcpacker/emit/markdown/mineralreport.py b/mcpacker/emit/markdown/mineralreport.py index 0dd0ca5..bbb7386 100644 --- a/mcpacker/emit/markdown/mineralreport.py +++ b/mcpacker/emit/markdown/mineralreport.py @@ -10,7 +10,7 @@ class MineralReport(Report): super().__init__("minerals.md", pack) def build(self): - for mineral in self.pack.world.minerals.all(): + for mineral in self.pack.world.minerals: self.line(f"# Mineral: {mineral.name}") self.line() diff --git a/mcpacker/emit/markdown/mobreport.py b/mcpacker/emit/markdown/mobreport.py index c56fecf..bf56b46 100644 --- a/mcpacker/emit/markdown/mobreport.py +++ b/mcpacker/emit/markdown/mobreport.py @@ -11,8 +11,8 @@ class MobReport(Report): super().__init__("mobs.md", pack) def build(self): - for placement in self.pack.world.mobs.all(): - self.line(f"# Mob: {placement.mob.name} <{placement.mob.gameId}>") + for placement in self.pack.world.mobs: + self.line(f"# Mob: {placement.gameId}") self.line() self.indent() diff --git a/mcpacker/emit/markdown/report.py b/mcpacker/emit/markdown/report.py index ce0a4b8..0703daf 100644 --- a/mcpacker/emit/markdown/report.py +++ b/mcpacker/emit/markdown/report.py @@ -32,8 +32,8 @@ class Report: raise NotImplementedError() def reset(self) -> "Report": - self._lineBuffer = [] - self._lines = [] + self._lineBuffer:list[str] = [] + self._lines:list[str] = [] self._indent = 0 return self diff --git a/mcpacker/json.py b/mcpacker/json.py new file mode 100644 index 0000000..ebe9672 --- /dev/null +++ b/mcpacker/json.py @@ -0,0 +1,24 @@ +from json import dump +from json import dumps +from json import load +from json import loads +from typing import TypeAlias + + +# Type Support ##################################################################################### + +JsonBlob:TypeAlias = dict[str, "JsonBlob"] | list["JsonBlob"] | str | int | float | bool | None + + +# Functions ######################################################################################## + +def removeNoneValues(blob:JsonBlob) -> JsonBlob: + if not isinstance(blob, dict): return blob + + for key in list(blob.keys()): + if blob[key] == None: + del blob[key] + else: + removeNoneValues(blob[key]) + + return blob diff --git a/mcpacker/model/catalog.py b/mcpacker/model/catalog.py new file mode 100644 index 0000000..311cda2 --- /dev/null +++ b/mcpacker/model/catalog.py @@ -0,0 +1,74 @@ +from collections.abc import Iterable +from typing import Any +from typing import Callable +from typing import Generic +from typing import Iterator +from typing import Protocol +from typing import TypeVar + + +# Type Support ##################################################################################### + +class HasGameId(Protocol): + + @property + def gameId(self) -> str: ... + +CatalogItem = TypeVar("CatalogItem", bound=HasGameId) + +MapTarget = TypeVar("MapTarget") + + +# Class ############################################################################################ + +class Catalog(Generic[CatalogItem]): + + def __init__(self, items:Iterable[CatalogItem]|None=None): + self._items:dict[str,CatalogItem] = {} + + for item in (items or []): + self.add(item) + + def __contains__(self, gameId:str) -> bool: + return gameId in self._items + + def __delitem__(self, gameId:str): + del self._items[gameId] + + def __eq__(self, other:Any) -> bool: + if type(self) != type(other): return False + if self._items != other._items: return False + return True + + def __getitem__(self, gameId:str) -> CatalogItem: + return self._items[gameId] + + def __iter__(self) -> Iterator[CatalogItem]: + for gameId in sorted([i.gameId for i in self._items.values()]): + yield self._items[gameId] + + def __len__(self) -> int: + return len(self._items) + + def __repr__(self) -> str: + return "".join(str(p) for p in [ + self.__class__.__name__, "[", + ", ".join(str(i) for i in self), + "]" + ]) + + def add(self, item:CatalogItem) -> "Catalog[CatalogItem]": + if item.gameId in self._items: + raise Exception(f"Catalog already contains {item.gameId}") + + self._items[item.gameId] = item + return self + + def filter(self, isAllowed:Callable[[CatalogItem], bool]) -> Iterator[CatalogItem]: + for item in self: + if isAllowed(item): + yield item + + def map(self, doTransform:Callable[[CatalogItem], MapTarget]) -> Iterator[MapTarget]: + for item in self: + yield doTransform(item) diff --git a/mcpacker/model/catalog_test.py b/mcpacker/model/catalog_test.py new file mode 100644 index 0000000..be3d900 --- /dev/null +++ b/mcpacker/model/catalog_test.py @@ -0,0 +1,88 @@ +from mcpacker.model.catalog import Catalog +from pytest import fixture +from typing import Any + + +# Helpers ########################################################################################## + +class SampleItem: + + def __init__(self, gameId:str): + self.gameId = gameId + + def __eq__(self, other:Any): + return self.gameId == other.gameId + + def __repr__(self) -> str: + return self.gameId + + +# Fixtures ######################################################################################### + +@fixture(name="empty") +def buildEmptyCatalog(): + yield Catalog() + +@fixture(name="full") +def buildFullCatalog(): + yield Catalog([ + SampleItem("alpha"), + SampleItem("bravo"), + SampleItem("charlie"), + SampleItem("delta"), + ]) + +@fixture(name="almostFull") +def buildAlmostFullCatalog(full): + del full["bravo"] + yield full + +@fixture(name="almostEmpty") +def buildAlmostEmptyCatalog(empty): + empty.add(SampleItem("echo")) + yield empty + +@fixture(name="filtered") +def buildFilteredList(full): + yield list(full.filter(lambda x: x.gameId.endswith("a"))) + +@fixture(name="mapped") +def buildMappedList(full): + yield list(full.map(lambda x: x.gameId)) + + +# Tests ############################################################################################ + +def test_add(almostEmpty): + assert "echo" in almostEmpty + +def test_contains(empty, full): + assert "bravo" not in empty + assert "bravo" in full + +def test_del(almostFull): + assert "bravo" not in almostFull + +def test_eq(): + assert Catalog([SampleItem("alpha")]) == Catalog([SampleItem("alpha")]) + assert Catalog([SampleItem("alpha")]) != Catalog([SampleItem("bravo")]) + +def test_filter(filtered): + assert [a.gameId for a in filtered] == ["alpha", "delta"] + +def test_getitem(full): + assert full["bravo"].gameId == "bravo" + +def test_iter(full): + assert [s.gameId for s in full] == ["alpha", "bravo", "charlie", "delta"] + +def test_len(empty, full): + assert len(empty) == 0 + assert len(full) == 4 + +def test_map(mapped): + assert mapped == ["alpha", "bravo", "charlie", "delta"] + +def test_repr(empty, full): + assert repr(empty) == "Catalog[]" + assert repr(full) == "Catalog[alpha, bravo, charlie, delta]" diff --git a/mcpacker/model/core/dimension.py b/mcpacker/model/core/dimension.py new file mode 100644 index 0000000..2445e74 --- /dev/null +++ b/mcpacker/model/core/dimension.py @@ -0,0 +1,21 @@ +# Class ############################################################################################ + +class Dimension: + + def __init__(self, name): + self.name = name + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return f"Dimension<{self.name}>" + + +# Constants ######################################################################################## + +OVERWORLD = Dimension("minecraft:overworld") +NETHER = Dimension("minecraft:nether") +END = Dimension("minecraft:end") + +ALL = [OVERWORLD, NETHER, END] diff --git a/mcpacker/model/datapack/mod_test.py b/mcpacker/model/core/dimension_test.py similarity index 78% rename from mcpacker/model/datapack/mod_test.py rename to mcpacker/model/core/dimension_test.py index 84accb5..85789d3 100644 --- a/mcpacker/model/datapack/mod_test.py +++ b/mcpacker/model/core/dimension_test.py @@ -1,4 +1,4 @@ -import mcpacker.model.datapack.mod +import mcpacker.model.core.dimension # Tests ############################################################################################ diff --git a/mcpacker/model/core/ecology/biome.py b/mcpacker/model/core/ecology/biome.py index 5466ba6..4b08764 100644 --- a/mcpacker/model/core/ecology/biome.py +++ b/mcpacker/model/core/ecology/biome.py @@ -37,12 +37,12 @@ class Biome(object): def __eq__(self, other) -> bool: if type(self) != type(other): return False - if self.biomeId != other.biomeId: return False + if self.gameId != other.gameId: return False if self.city != other.city: return False return True def __hash__(self) -> int: - return hash((self.biomeId, self.city)) + return hash((self.gameId, self.city)) def __str__(self) -> str: return f"{self.city}<{self.gameId}>" diff --git a/mcpacker/model/core/ecology/biomecatalog.py b/mcpacker/model/core/ecology/biomecatalog.py index d5e9c97..cabfd5a 100644 --- a/mcpacker/model/core/ecology/biomecatalog.py +++ b/mcpacker/model/core/ecology/biomecatalog.py @@ -1,32 +1,14 @@ -from collections.abc import Iterable -from mcpacker.model.core.ecology.biome import Biome +from mcpacker.model.catalog import Catalog +from mcpacker.model.core.ecology.biome import Biome from mcpacker.model.core.ecology.biomefilter import BiomeFilter +from typing import Iterator # Classes ########################################################################################## -class BiomeCatalog: - """ - A comprehensive list of all available biomes in the modpack. - """ +class BiomeCatalog(Catalog[Biome]): - def __init__(self, biomes:Iterable[Biome]|None=None): - self._biomes = {} - - for biome in (biomes or []): - self.add(biome) - - def add(self, biome:Biome) -> "BiomeCatalog": - if biome.gameId in self._biomes: - raise Exception(f"Catalog already contains {biome.gameId}") - - self._biomes[biome.gameId] = biome - - def all(self) -> Iterable[Biome]: - for gameId in sorted([b.gameId for b in self._biomes.values()]): - yield self._biomes[gameId] - - def matching(self, biomeFilter:BiomeFilter) -> Iterable[Biome]: - for biome in self.all(): + def matching(self, biomeFilter:BiomeFilter) -> Iterator[Biome]: + for biome in self: if biomeFilter.accepts(biome): yield biome diff --git a/mcpacker/model/core/ecology/biomefilter.py b/mcpacker/model/core/ecology/biomefilter.py index 39c38a4..f8e2b62 100644 --- a/mcpacker/model/core/ecology/biomefilter.py +++ b/mcpacker/model/core/ecology/biomefilter.py @@ -1,3 +1,4 @@ +from collections.abc import Iterable from mcpacker.model.core.ecology.biome import Biome from mcpacker.model.core.ecology.biometrait import BiomeTrait @@ -25,8 +26,8 @@ class BiomeFilter: def __init__( self, - required:list[BiomeTrait|list[BiomeTrait]]=None, - prohibited:list[BiomeTrait]=None, + required:Iterable[BiomeTrait|Iterable[BiomeTrait]]|None=None, + prohibited:Iterable[BiomeTrait]|None=None, ): self.required = required or [] self.prohibited = prohibited or [] diff --git a/mcpacker/model/core/ecology/biometrait.py b/mcpacker/model/core/ecology/biometrait.py index 98e8170..2b6d6ee 100644 --- a/mcpacker/model/core/ecology/biometrait.py +++ b/mcpacker/model/core/ecology/biometrait.py @@ -1,3 +1,6 @@ +from typing import TypeVar + + # Class ############################################################################################ class BiomeTrait: @@ -23,9 +26,18 @@ class BiomeTrait: return f"{type(self).__name__}<{self.name}>" +# Type Support ##################################################################################### + +BiomeTraitSubclass = TypeVar("BiomeTraitSubclass", bound=BiomeTrait) + + # Helper Functions ################################################################################# -def within(allTraits:list[BiomeTrait], start:BiomeTrait, end:BiomeTrait) -> list[BiomeTrait]: +def within( + allTraits:list[BiomeTraitSubclass], + start:BiomeTraitSubclass, + end:BiomeTraitSubclass +) -> list[BiomeTraitSubclass]: if not allTraits: return [] start = start if start else allTraits[0] end = end if end else allTraits[-1] diff --git a/mcpacker/model/core/ecology/humidity.py b/mcpacker/model/core/ecology/humidity.py index dacaa3a..1d550a9 100644 --- a/mcpacker/model/core/ecology/humidity.py +++ b/mcpacker/model/core/ecology/humidity.py @@ -1,3 +1,4 @@ +from collections.abc import Iterable from mcpacker.model.core.ecology.biometrait import BiomeTrait import mcpacker.model.core.ecology.biometrait as biomeTrait @@ -23,5 +24,5 @@ ALL = [WET, DAMP, DRY] # Helpers ########################################################################################## -def within(start:Humidity, end:Humidity) -> list[Humidity]: +def within(start:Humidity, end:Humidity) -> Iterable[Humidity]: return biomeTrait.within(ALL, start, end) diff --git a/mcpacker/model/core/fauna/active.py b/mcpacker/model/core/fauna/active.py index 610c258..0159443 100644 --- a/mcpacker/model/core/fauna/active.py +++ b/mcpacker/model/core/fauna/active.py @@ -19,12 +19,17 @@ class Active: # Constants ######################################################################################## -DAY = Active("day", 0, 12000) -NIGHT = Active("night", 13000, 23000) -SUNRISE = Active("sunrise", 23000, 24000) -SUNSET = Active("sunset", 12000, 13000) +DAY = Active("day", 0, 12000) +NIGHT = Active("night", 13000, 23000) +SUNRISE = Active("sunrise", 23000, 24000) +SUNSET = Active("sunset", 12000, 13000) -ANY = (SUNRISE, DAY, SUNSET, NIGHT) +ANY = Active("any", 0, 24000) +RAINY = Active("rainy", 0, 24000) +STORMY = Active("stormy", 0, 24000) +MIDNIGHT = Active("midnight", 18000, 19000) + +ALL = (SUNRISE, DAY, SUNSET, NIGHT) DIURNAL = (DAY) NOCTURNAL = (NIGHT) CREPUSCULAR = (SUNRISE, SUNSET) diff --git a/mcpacker/model/core/fauna/mob.py b/mcpacker/model/core/fauna/mob.py index 66528a3..5f625ac 100644 --- a/mcpacker/model/core/fauna/mob.py +++ b/mcpacker/model/core/fauna/mob.py @@ -1,3 +1,4 @@ +from collections.abc import Iterable from mcpacker.model.core.fauna.active import Active import mcpacker.model.core.fauna.active as AC @@ -10,8 +11,7 @@ class Mob: A creature which may appear in the game world. """ - def __init__(self, name:str, gameId:str, active:tuple[Active]=AC.DIURNAL): - self.name = name + def __init__(self, gameId:str, active:Active|Iterable[Active]=AC.DIURNAL): self.gameId = gameId self.active = active @@ -30,7 +30,7 @@ class Mob: return hash(self.gameId) def __str__(self) -> str: - return self.name + return self.gameId def __repr__(self) -> str: - return f"{self.name}<{self.gameId}>{{active:{self.active}}}" + return f"Mob<{self.gameId}>{{active:{self.active}}}" diff --git a/mcpacker/model/core/fauna/mob_test.py b/mcpacker/model/core/fauna/mob_test.py index 5b5bff3..1619f3c 100644 --- a/mcpacker/model/core/fauna/mob_test.py +++ b/mcpacker/model/core/fauna/mob_test.py @@ -8,11 +8,11 @@ import mcpacker.model.core.fauna.active as AC @fixture(name="squid") def createSquid(): - yield Mob("squid", "minecraft:squid", AC.ANY) + yield Mob("minecraft:squid", AC.ANY) @fixture(name="cow") def createCow(): - yield Mob("cow", "minecraft:cow", AC.DIURNAL) + yield Mob("minecraft:cow", AC.DIURNAL) @fixture(name="mobMap") def createMobMap(cow, squid): @@ -25,15 +25,15 @@ def createMobMap(cow, squid): # Tests ############################################################################################ def test_eq(squid): - assert squid == Mob("squid", "minecraft:squid") - assert squid != Mob("squid", "animalsplus:squid") + assert squid == Mob("minecraft:squid") + assert squid != Mob("animalsplus:squid") def test_hash(cow, squid, mobMap): assert mobMap[cow] == "beef" assert mobMap[squid] == "calamari" def test_str(squid): - assert str(squid) == "squid" + assert str(squid) == "minecraft:squid" def test_repr(cow): - assert repr(cow) == "cow{active:(Active{start:0, end:12000},)}" + assert repr(cow) == "Mob{active:(Active{start:0, end:12000},)}" diff --git a/mcpacker/model/core/fauna/mobcatalog.py b/mcpacker/model/core/fauna/mobcatalog.py index c49488d..01da0f7 100644 --- a/mcpacker/model/core/fauna/mobcatalog.py +++ b/mcpacker/model/core/fauna/mobcatalog.py @@ -1,26 +1,8 @@ -from collections.abc import Iterable -from mcpacker.model.core.fauna.mobplacement import MobPlacement +from mcpacker.model.catalog import Catalog +from mcpacker.model.core.fauna.mob import Mob -# Class ############################################################################################ +# Classes ########################################################################################## -class MobCatalog: - - def __init__(self, mobs:Iterable[MobPlacement]|None=None): - self._mobs = {} - - for mob in (mobs or []): - self.add(mob) - - def add(self, placement:MobPlacement) -> "MobCatalog": - if placement.mob.name in self._mobs: - raise Exception("Catalog already has an entry for {mob.name}") - - self._mobs[placement.mob.name] = placement - - def all(self) -> Iterable[MobPlacement]: - for placement in self._mobs.values(): - yield placement - - def get(self, name:str) -> MobPlacement: - return self._mobs.get(name, None) +class MobCatalog(Catalog[Mob]): + pass diff --git a/mcpacker/model/core/fauna/mobplacement.py b/mcpacker/model/core/fauna/mobplacement.py deleted file mode 100644 index 366f0da..0000000 --- a/mcpacker/model/core/fauna/mobplacement.py +++ /dev/null @@ -1,15 +0,0 @@ -from mcpacker.model.core.habitat import Habitat -from mcpacker.model.core.fauna.mob import Mob -from mcpacker.model.core.placement import Placement - - -# Class ############################################################################################ - -class MobPlacement(Placement): - """ - A description of where a creature should appear in the world. - """ - - def __init__(self, mob:Mob, habitats:list[Habitat]=None): - super().__init__(habitats) - self.mob = mob diff --git a/mcpacker/model/core/fauna/mobspawn.py b/mcpacker/model/core/fauna/mobspawn.py new file mode 100644 index 0000000..b7418af --- /dev/null +++ b/mcpacker/model/core/fauna/mobspawn.py @@ -0,0 +1,20 @@ +from collections.abc import Iterable +from mcpacker.model.core.habitat import Habitat +from mcpacker.model.core.fauna.mob import Mob +from mcpacker.model.core.spawn import Spawn + + +# Class ############################################################################################ + +class MobSpawn(Spawn): + """ + A description of where a creature should appear in the world. + """ + + def __init__(self, mob:Mob, habitats:Iterable[Habitat]|Habitat|None=None): + super().__init__(habitats) + self.mob = mob + + @property + def gameId(self) -> str: + return self.mob.gameId diff --git a/mcpacker/model/core/fauna/mobplacement_test.py b/mcpacker/model/core/fauna/mobspawn_test.py similarity index 82% rename from mcpacker/model/core/fauna/mobplacement_test.py rename to mcpacker/model/core/fauna/mobspawn_test.py index 8036f91..c50438b 100644 --- a/mcpacker/model/core/fauna/mobplacement_test.py +++ b/mcpacker/model/core/fauna/mobspawn_test.py @@ -1,6 +1,6 @@ from mcpacker.model.core.ecology.biomefilter import BiomeFilter from mcpacker.model.core.fauna.mob import Mob -from mcpacker.model.core.fauna.mobplacement import MobPlacement +from mcpacker.model.core.fauna.mobspawn import MobSpawn from mcpacker.model.core.habitat import Habitat from pytest import fixture @@ -18,16 +18,16 @@ def createCow(): def createFieldsHabitat(): yield Habitat(biomeFilter=BiomeFilter([F.FIELD, E.TEMPERATE])) -@fixture(name="placement") -def createMobPlacement(cow, fields): - yield MobPlacement(cow, fields) +@fixture(name="spawn") +def createMobSpawn(cow, fields): + yield MobSpawn(cow, fields) # Tests ############################################################################################ -def test_cowsInFields(placement): - assert str(placement) == ( - "Placement{" + +def test_cowsInFields(spawn): + assert str(spawn) == ( + "Spawn{" + "habitats: [" + "Habitat{" + "altitude: anywhere <-64 to 320>, " + diff --git a/mcpacker/model/core/fauna/mobspawncatalog.py b/mcpacker/model/core/fauna/mobspawncatalog.py new file mode 100644 index 0000000..b531ac1 --- /dev/null +++ b/mcpacker/model/core/fauna/mobspawncatalog.py @@ -0,0 +1,8 @@ +from mcpacker.model.catalog import Catalog +from mcpacker.model.core.fauna.mobspawn import MobSpawn + + +# Classes ########################################################################################## + +class MobSpawnCatalog(Catalog[MobSpawn]): + pass diff --git a/mcpacker/model/core/fauna/mobspawncatalog_test.py b/mcpacker/model/core/fauna/mobspawncatalog_test.py new file mode 100644 index 0000000..ec4745c --- /dev/null +++ b/mcpacker/model/core/fauna/mobspawncatalog_test.py @@ -0,0 +1,8 @@ +import mcpacker.model.core.fauna.mobspawncatalog + + +# Tests ############################################################################################ + +def test_syntax(): + pass + diff --git a/mcpacker/model/core/geology/deposit/__init__.py b/mcpacker/model/core/geology/deposit/__init__.py index 0883fe3..cb5c01b 100644 --- a/mcpacker/model/core/geology/deposit/__init__.py +++ b/mcpacker/model/core/geology/deposit/__init__.py @@ -17,6 +17,7 @@ class Deposit: biomeFilter:BiomeFilter|None=None, ): self.name = name + self.gameId = name self.biomeFilter = biomeFilter or BiomeFilter() self.scarcity = scarcity diff --git a/mcpacker/model/core/geology/deposit/metaldeposit.py b/mcpacker/model/core/geology/deposit/metaldeposit.py index 9053b54..6197a43 100644 --- a/mcpacker/model/core/geology/deposit/metaldeposit.py +++ b/mcpacker/model/core/geology/deposit/metaldeposit.py @@ -1,3 +1,4 @@ +from collections.abc import Iterable from mcpacker.model.core.ecology.biomefilter import BiomeFilter from mcpacker.model.core.geology.bulk import Bulk from mcpacker.model.core.geology.deposit import Deposit @@ -17,10 +18,10 @@ class MetalDeposit(Deposit): def __init__( self, name:str, - inclusions:tuple[Inclusion], + inclusions:Iterable[Inclusion], bulk:Bulk=BU.MEDIUM, proportion:Proportion=PR.BODY, - biomeFilter:BiomeFilter=None, + biomeFilter:BiomeFilter|None=None, scarcity:Scarcity=SC.SPARSE, ): super().__init__(name, scarcity, biomeFilter) diff --git a/mcpacker/model/core/geology/depositcatalog.py b/mcpacker/model/core/geology/depositcatalog.py index c516a54..d09ba97 100644 --- a/mcpacker/model/core/geology/depositcatalog.py +++ b/mcpacker/model/core/geology/depositcatalog.py @@ -1,27 +1,8 @@ +from mcpacker.model.catalog import Catalog from mcpacker.model.core.geology.deposit import Deposit -from mcpacker.model.core.geology.mineralcatalog import MineralCatalog -from typing import Iterator -# Class ############################################################################################ +# Classes ########################################################################################## -class DepositCatalog: - - def __init__(self, deposits:None|tuple[Deposit]=None): - self._deposits = {} - - for deposit in (deposits or []): - self.add(deposit) - - def add(self, deposit:Deposit) -> "DepositCatalog": - if deposit.name in self._deposits: - raise Exception("Catalog already has an entry for {deposit.name}") - - self._deposits[deposit.name] = deposit - - def all(self) -> Iterator[Deposit]: - for deposit in self._deposits.values(): - yield deposit - - def get(self, name:str) -> Deposit|None: - return self._deposits.get(name, None) +class DepositCatalog(Catalog[Deposit]): + pass diff --git a/mcpacker/model/core/geology/depositcatalog_test.py b/mcpacker/model/core/geology/depositcatalog_test.py index 6cdfbb1..528da5f 100644 --- a/mcpacker/model/core/geology/depositcatalog_test.py +++ b/mcpacker/model/core/geology/depositcatalog_test.py @@ -1,53 +1,7 @@ -from mcpacker.model.core.ecology.biomefilter import BiomeFilter -from mcpacker.model.core.geology.deposit import Deposit -from mcpacker.model.core.geology.deposit.metaldeposit import MetalDeposit -from mcpacker.model.core.geology.depositcatalog import DepositCatalog -from mcpacker.model.core.geology.inclusion import Inclusion -from mcpacker.model.core.geology.mineral import Mineral -from mcpacker.model.core.geology.replacement import Replacement -from pytest import fixture - -import mcpacker.model.core.ecology.flora as FL -import mcpacker.model.core.geology.bulk as BU -import mcpacker.model.core.scarcity as SC - - -# Fixtures ######################################################################################### - -@fixture(name="quartz") -def createQuartz(): - yield Mineral("quartz", [ - Replacement("#minecraft:stone_replaceables", "minecraft:quartz_ore"), - Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_quartz_ore") - ]) - -@fixture(name="iron") -def createIron(): - yield Mineral("iron", [ - Replacement("#minecraft:stone_replaceables", "minecraft:iron_ore"), - Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_iron_ore") - ]) - -@fixture(name="bifiron") -def createBifIron(iron, quartz): - yield MetalDeposit( - name = "bif_iron", - scarcity = SC.COMMON, - biomeFilter = BiomeFilter([FL.FOREST]), - inclusions = [Inclusion(iron, 60), Inclusion(quartz, 40)], - bulk = BU.LARGE, - proportion = 0.5, - ) - -@fixture(name="catalog") -def createCatalog(bifiron): - yield DepositCatalog([bifiron]) +import mcpacker.model.core.geology.depositcatalog # Tests ############################################################################################ -def test_all(catalog): - assert [m.name for m in catalog.all()] == ["bif_iron"] - -def test_get(catalog): - assert catalog.get("bif_iron").name == "bif_iron" +def test_syntax(): + pass diff --git a/mcpacker/model/core/geology/mineral.py b/mcpacker/model/core/geology/mineral.py index fde358e..ba36ba9 100644 --- a/mcpacker/model/core/geology/mineral.py +++ b/mcpacker/model/core/geology/mineral.py @@ -1,3 +1,4 @@ +from collections.abc import Iterable from mcpacker.model.core.geology.replacement import Replacement from mcpacker.model.core.resourceid import ResourceId @@ -6,9 +7,10 @@ from mcpacker.model.core.resourceid import ResourceId class Mineral: - def __init__(self, name:str, replacements:None|tuple[Replacement]=None): + def __init__(self, name:str, replacements:Iterable[Replacement]|None=None): self.name = name - self.replacements = replacements or [] + self.gameId = name + self.replacements = list(replacements or []) def __str__(self) -> str: return self.name @@ -21,12 +23,3 @@ class Mineral: "]", "}" ]]) - - def addStoneReplacement(self, blockId:str) -> "Mineral": - blockId = ResourceId.canonical(blockId) - self.replacements.append(Replacement(STONE_REPLACEABLES, blockId)) - return self - - def addDeepslateReplacement(self, blockId:str) -> "Mineral": - blockId = ResourceId.canonical(blockId) - self.replacements.append(Replacement(DEEPSLATE_REPLACEABLES, blockId)) diff --git a/mcpacker/model/core/geology/mineralcatalog.py b/mcpacker/model/core/geology/mineralcatalog.py index d55bb87..b58d96e 100644 --- a/mcpacker/model/core/geology/mineralcatalog.py +++ b/mcpacker/model/core/geology/mineralcatalog.py @@ -1,26 +1,8 @@ +from mcpacker.model.catalog import Catalog from mcpacker.model.core.geology.mineral import Mineral -from typing import Iterator -# Class ############################################################################################ +# Classes ########################################################################################## -class MineralCatalog: - - def __init__(self, minerals:tuple[Mineral]=None): - self._minerals = {} - - for mineral in (minerals or []): - self.add(mineral) - - def add(self, mineral:Mineral) -> "MineralCatalog": - if mineral.name in self._minerals: - raise Exception(f"Catalog already contains an entry for {mineral.name}") - - self._minerals[mineral.name] = mineral - - def all(self) -> Iterator[Mineral]: - for mineral in self._minerals.values(): - yield mineral - - def get(self, name:str) -> Mineral|None: - return self._minerals.get(name, None) +class MineralCatalog(Catalog[Mineral]): + pass diff --git a/mcpacker/model/core/geology/mineralcatalog_test.py b/mcpacker/model/core/geology/mineralcatalog_test.py index c554b43..48dcfb1 100644 --- a/mcpacker/model/core/geology/mineralcatalog_test.py +++ b/mcpacker/model/core/geology/mineralcatalog_test.py @@ -1,34 +1,7 @@ -from mcpacker.model.core.geology.mineral import Mineral -from mcpacker.model.core.geology.mineralcatalog import MineralCatalog -from mcpacker.model.core.geology.replacement import Replacement -from pytest import fixture - - -# Fixtures ######################################################################################### - -@fixture(name="copper") -def createCopper(): - yield Mineral("copper", [ - Replacement("#minecraft:stone_replaceables", "minecraft:copper_ore"), - Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_copper_ore") - ]) - -@fixture(name="iron") -def createIron(): - yield Mineral("iron", [ - Replacement("#minecraft:stone_replaceables", "minecraft:iron_ore"), - Replacement("#minecraft:deepslate_replaceables", "minecraft:deepslate_iron_ore") - ]) - -@fixture(name="catalog") -def createCatalog(copper, iron): - yield MineralCatalog([copper, iron]) +import mcpacker.model.core.geology.mineralcatalog # Tests ############################################################################################ -def test_all(catalog): - assert [m.name for m in catalog.all()] == ["copper", "iron"] - -def test_get(catalog): - assert catalog.get("iron").name == "iron" +def test_syntax(): + pass diff --git a/mcpacker/model/core/habitat.py b/mcpacker/model/core/habitat.py index 0a39747..4dad7d7 100644 --- a/mcpacker/model/core/habitat.py +++ b/mcpacker/model/core/habitat.py @@ -1,15 +1,16 @@ -from mcpacker.model.core.altitude import Altitude +from collections.abc import Iterable +from mcpacker.model.core.altitude import Altitude from mcpacker.model.core.ecology.biomefilter import BiomeFilter -from mcpacker.model.core.fauna.group import Group -from mcpacker.model.core.fauna.location import Location -from mcpacker.model.core.scarcity import Scarcity -from mcpacker.model.core.season import Season +from mcpacker.model.core.fauna.group import Group +from mcpacker.model.core.fauna.location import Location +from mcpacker.model.core.scarcity import Scarcity +from mcpacker.model.core.season import Season -import mcpacker.model.core.altitude as A -import mcpacker.model.core.fauna.group as G +import mcpacker.model.core.altitude as A +import mcpacker.model.core.fauna.group as G import mcpacker.model.core.fauna.location as L -import mcpacker.model.core.scarcity as C -import mcpacker.model.core.season as E +import mcpacker.model.core.scarcity as C +import mcpacker.model.core.season as E # Class ############################################################################################ @@ -23,8 +24,8 @@ class Habitat: self, altitude:Altitude=A.ANYWHERE, - biomeFilter:BiomeFilter=None, - seasons:tuple[Season]=E.ALL, + biomeFilter:BiomeFilter|None=None, + seasons:Iterable[Season]|Season=E.ALL, group:Group=G.SOLO, location:Location=L.OUTSIDE, @@ -32,7 +33,7 @@ class Habitat: ): self.altitude = altitude self.biomeFilter = biomeFilter or BiomeFilter() - self.seasons = (seasons,) if isinstance(seasons, Season) else seasons + self.seasons = [seasons] if isinstance(seasons, Season) else seasons self.group = group self.location = location @@ -42,7 +43,7 @@ class Habitat: def __str__(self) -> str: return "".join([str(p) for p in [ - ", ".join(self.altitude), "|", + self.altitude, "|", self.biomeFilter, "|", ", ".join([str(s) for s in self.seasons]), "|", self.group, "|", @@ -77,13 +78,12 @@ class Habitat: return result - def collect(self) -> "tuple[Habitat]": - result = [] - - current = self + def collect(self) -> "Iterable[Habitat]": + stack:list[Habitat] = [] + current:Habitat|None = self while current: - result.append(current) + stack.append(current) current = current._source - return tuple(reversed(result)) - + while stack: + yield stack.pop() diff --git a/mcpacker/model/core/material/block.py b/mcpacker/model/core/material/block.py index 8af8023..51ef305 100644 --- a/mcpacker/model/core/material/block.py +++ b/mcpacker/model/core/material/block.py @@ -1,6 +1,7 @@ +from collections.abc import Iterable from mcpacker.model.core.material.loottable import LootTable from mcpacker.model.core.material.soundtype import SoundType -from mcpacker.model.core.resourceid import ResourceId +from mcpacker.model.core.resourceid import ResourceId import mcpacker.model.core.material.soundtype as ST @@ -12,11 +13,11 @@ class Block: def __init__( self, name:str, - gameId:ResourceId, + gameId:str, loot:LootTable, requiresTool:bool=False, soundType:SoundType=ST.STONE, - tags:list[str]=None, + tags:Iterable[str]|None=None, ): self.gameId = gameId self.loot = loot diff --git a/mcpacker/model/core/material/blockcatalog.py b/mcpacker/model/core/material/blockcatalog.py index 4c99781..2f43113 100644 --- a/mcpacker/model/core/material/blockcatalog.py +++ b/mcpacker/model/core/material/blockcatalog.py @@ -1,30 +1,8 @@ +from mcpacker.model.catalog import Catalog from mcpacker.model.core.material.block import Block -from typing import Iterator -# Class ############################################################################################ - -class BlockCatalog: - - def __init__(self, blocks:tuple[Block]=None): - self._blocks = {} - - for block in (blocks or []): - self.add(block) - - def __len__(self) -> int: - return len(self._blocks) - - def add(self, block:Block) -> "BlockCatalog": - if block.name in self._blocks: - raise Exception(f"Catalog already contains an entry for {block.name}") - - self._blocks[block.name] = block - - def all(self) -> Iterator[Block]: - for block in self._blocks.values(): - yield block - - def get(self, name:str) -> Block|None: - return self._blocks.get(name, None) +# Classes ########################################################################################## +class BlockCatalog(Catalog[Block]): + pass diff --git a/mcpacker/model/core/material/item.py b/mcpacker/model/core/material/item.py index 8e30ff9..0f0b06d 100644 --- a/mcpacker/model/core/material/item.py +++ b/mcpacker/model/core/material/item.py @@ -5,8 +5,5 @@ from mcpacker.model.core.resourceid import ResourceId class Item: - def __init__(self, gameId:ResourceId): + def __init__(self, gameId:str): self.gameId = gameId - - if not isinstance(self.gameId, ResourceId): - self.gameId = ResourceId.parse(str(self.gameId)) diff --git a/mcpacker/model/core/material/itemcatalog.py b/mcpacker/model/core/material/itemcatalog.py index 8ca6b96..9288b1d 100644 --- a/mcpacker/model/core/material/itemcatalog.py +++ b/mcpacker/model/core/material/itemcatalog.py @@ -1,12 +1,14 @@ +from collections.abc import Iterable +from mcpacker.model.catalog import Catalog from mcpacker.model.core.material.item import Item -from typing import Iterator +from typing import Iterator # Class ############################################################################################ -class ItemCatalog: +class ItemCatalog(Catalog[Item]): - def __init__(self, items:tuple[Item]=None): + def __init__(self, items:Iterable[Item]|None=None): self._items = {} for item in (items or []): @@ -17,6 +19,7 @@ class ItemCatalog: raise Exception(f"Catalog already contains an entry for {item.gameId}") self._items[item.gameId] = item + return self def all(self) -> Iterator[Item]: for item in self._items.values(): diff --git a/mcpacker/model/core/material/loot.py b/mcpacker/model/core/material/loot.py index 682bec1..6154149 100644 --- a/mcpacker/model/core/material/loot.py +++ b/mcpacker/model/core/material/loot.py @@ -5,6 +5,11 @@ from mcpacker.model.core.material.item import Item class Loot: + @staticmethod + def of(item:Item|None, maxCount:int=1, minCount:int=1, weight:int=1) -> "Loot|None": + if not item: return None + return Loot(item, maxCount, minCount, weight) + def __init__(self, item:Item, maxCount:int=1, minCount:int=1, weight:int=1): self.item = item self.maxCount = maxCount @@ -21,4 +26,4 @@ class Loot: ]]) def __str__(self) -> str: - return f"{str(item)} ({self.minCount}..{self.maxCount} @ {self.weight})" + return f"{str(self.item)} ({self.minCount}..{self.maxCount} @ {self.weight})" diff --git a/mcpacker/model/core/material/loottable.py b/mcpacker/model/core/material/loottable.py index ae9d664..765f377 100644 --- a/mcpacker/model/core/material/loottable.py +++ b/mcpacker/model/core/material/loottable.py @@ -1,3 +1,4 @@ +from collections.abc import Iterable from mcpacker.model.core.material.loot import Loot @@ -5,5 +6,8 @@ from mcpacker.model.core.material.loot import Loot class LootTable: - def __init__(self, items:list[Loot]): - self.items = items + def __init__(self, items:Iterable[Loot]|Loot|None): + if isinstance(items, Loot): + items = [items] + + self.items = items or [] diff --git a/mcpacker/model/core/placement.py b/mcpacker/model/core/spawn.py similarity index 57% rename from mcpacker/model/core/placement.py rename to mcpacker/model/core/spawn.py index fe60368..06ae422 100644 --- a/mcpacker/model/core/placement.py +++ b/mcpacker/model/core/spawn.py @@ -1,26 +1,24 @@ +from collections.abc import Iterable from mcpacker.model.core.habitat import Habitat # Class ############################################################################################ -class Placement: +class Spawn: """ Abstract base class for placing something into its various habitats. """ - def __init__(self, habitats:tuple[Habitat]=None): - self.habitats = habitats + def __init__(self, habitats:Iterable[Habitat]|Habitat|None=None): + if isinstance(habitats, Habitat): + habitats = habitats.collect() - if not self.habitats: - self.habitats = () - - if isinstance(self.habitats, Habitat): - self.habitats = self.habitats.collect() + self.habitats = habitats or [] def __repr__(self) -> str: return ( - "Placement{" + + "Spawn{" + f"habitats: [{', '.join([repr(h) for h in self.habitats])}]" + "}" ) diff --git a/mcpacker/model/core/placement_test.py b/mcpacker/model/core/spawn_test.py similarity index 83% rename from mcpacker/model/core/placement_test.py rename to mcpacker/model/core/spawn_test.py index a7cbd06..60f3a74 100644 --- a/mcpacker/model/core/placement_test.py +++ b/mcpacker/model/core/spawn_test.py @@ -1,6 +1,6 @@ from mcpacker.model.core.ecology.biomefilter import BiomeFilter from mcpacker.model.core.habitat import Habitat -from mcpacker.model.core.placement import Placement +from mcpacker.model.core.spawn import Spawn from pytest import fixture import mcpacker.model.core.ecology.flora as F @@ -13,16 +13,16 @@ import mcpacker.model.core.ecology.heat as E def createFieldsHabitat(): yield Habitat(biomeFilter=BiomeFilter([F.FIELD, E.TEMPERATE])) -@fixture(name="placement") -def createPlacement(fields): - yield Placement([fields]) +@fixture(name="spawn") +def createSpawn(fields): + yield Spawn([fields]) # Tests ############################################################################################ -def test_repr(placement): - assert repr(placement) == ( - "Placement{" + +def test_repr(spawn): + assert repr(spawn) == ( + "Spawn{" + "habitats: [" + "Habitat{" + "altitude: anywhere <-64 to 320>, " + diff --git a/mcpacker/model/core/world.py b/mcpacker/model/core/world.py index 7254adf..fd61129 100644 --- a/mcpacker/model/core/world.py +++ b/mcpacker/model/core/world.py @@ -1,5 +1,6 @@ from mcpacker.model.core.ecology.biomecatalog import BiomeCatalog from mcpacker.model.core.fauna.mobcatalog import MobCatalog +from mcpacker.model.core.fauna.mobspawncatalog import MobSpawnCatalog from mcpacker.model.core.geology.depositcatalog import DepositCatalog from mcpacker.model.core.geology.mineralcatalog import MineralCatalog from mcpacker.model.core.material.blockcatalog import BlockCatalog @@ -18,10 +19,12 @@ class World: items:ItemCatalog|None=None, minerals:MineralCatalog|None=None, mobs:MobCatalog|None=None, + mobSpawns:MobSpawnCatalog|None=None ): - self.biomes = biomes or BiomeCatalog() - self.blocks = blocks or BlockCatalog() - self.deposits = deposits or DepositCatalog() - self.items = items or ItemCatalog() - self.minerals = minerals or MineralCatalog() - self.mobs = mobs or MobCatalog() + self.biomes = biomes or BiomeCatalog() + self.blocks = blocks or BlockCatalog() + self.deposits = deposits or DepositCatalog() + self.items = items or ItemCatalog() + self.minerals = minerals or MineralCatalog() + self.mobs = mobs or MobCatalog() + self.mobSpawns = mobSpawns or MobSpawnCatalog() diff --git a/mcpacker/model/datapack/__init__.py b/mcpacker/model/datapack/__init__.py index efe322c..351d994 100644 --- a/mcpacker/model/datapack/__init__.py +++ b/mcpacker/model/datapack/__init__.py @@ -1,39 +1,40 @@ from collections.abc import Iterable -from mcpacker.model.datapack.mod import Mod +from mcpacker.model.datapack.moddata import ModData # Class ############################################################################################ class DataPack: - def __init__(self, name:str, mods:Iterable[Mod]|None=None): + def __init__(self, name:str, mods:Iterable[ModData]|None=None): self.name = name - self._mods = {} - self._defaultMod = None + self._mods:dict[str,ModData] = {} + self._defaultMod:ModData|None = None for mod in (mods or []): self.add(mod) - def add(self, mod:Mod) -> "Datapack": + def add(self, mod:ModData) -> "DataPack": if not self._defaultMod: self._defaultMod = mod self._mods[mod.name] = mod return self - def get(self, modName:str) -> Mod: - return self._mods.get(modName, None) + def get(self, name:str) -> ModData|None: + return self._mods.get(name, None) @property - def defaultMod(self) -> Mod: + def defaultMod(self) -> ModData|None: return self._defaultMod @defaultMod.setter - def setDefaultMod(self, mod:Mod) -> "Datapack": - existingMod = self.get(mod.name) - if not existingMod: - self.add(mod) - elif existingMod != mod: - raise Exception(f"Datapack already has a mod named {mod.name}") + def defaultMod(self, mod:ModData): + if mod: + existingModData = self.get(mod.name) + if not existingModData: + self.add(mod) + elif existingModData != mod: + raise Exception(f"Datapack already has a mod named {mod.name}") self._defaultMod = mod diff --git a/mcpacker/model/datapack/blockstate.py b/mcpacker/model/datapack/blockstate.py index bbbdb44..8414abf 100644 --- a/mcpacker/model/datapack/blockstate.py +++ b/mcpacker/model/datapack/blockstate.py @@ -1,16 +1,18 @@ +from mcpacker.json import JsonBlob from typing import Any +from typing import cast # Class ############################################################################################ class BlockState: - def __init__(self, blockId:str, properties:dict[str,str]=None): + def __init__(self, blockId:str, properties:JsonBlob|None=None): self.blockId = blockId self.properties = properties - def asData(self) -> dict[str,Any]: - result = { "Name": self.blockId } + def asJsonBlob(self) -> JsonBlob: + result = cast(dict[str,JsonBlob], { "Name": self.blockId }) if self.properties: result["Properties"] = self.properties diff --git a/mcpacker/model/datapack/blockstate_test.py b/mcpacker/model/datapack/blockstate_test.py index 39299fe..5ceb314 100644 --- a/mcpacker/model/datapack/blockstate_test.py +++ b/mcpacker/model/datapack/blockstate_test.py @@ -11,8 +11,8 @@ def createBlockState(): # Tests ############################################################################################ -def test_asData(state): - assert state.asData() == { +def test_asData(state:BlockState): + assert state.asJsonBlob() == { "Name": "minecraft:button", "Properties": { "waterlogged": "true" diff --git a/mcpacker/model/datapack/blockstateprovider/__init__.py b/mcpacker/model/datapack/blockstateprovider/__init__.py index 97ec61a..6014397 100644 --- a/mcpacker/model/datapack/blockstateprovider/__init__.py +++ b/mcpacker/model/datapack/blockstateprovider/__init__.py @@ -1,3 +1,6 @@ +from mcpacker.json import JsonBlob + + # Class ############################################################################################ class BlockStateProvider: @@ -5,3 +8,5 @@ class BlockStateProvider: def __init__(self, gameId:str): self.gameId = gameId + def asJsonBlob(self) -> JsonBlob: + raise NotImplementedError() diff --git a/mcpacker/model/datapack/blockstateprovider/simplestateprovider.py b/mcpacker/model/datapack/blockstateprovider/simplestateprovider.py index 03aa8c9..0d9398e 100644 --- a/mcpacker/model/datapack/blockstateprovider/simplestateprovider.py +++ b/mcpacker/model/datapack/blockstateprovider/simplestateprovider.py @@ -1,6 +1,7 @@ -from mcpacker.model.datapack.blockstate import BlockState +from mcpacker.json import JsonBlob +from mcpacker.model.datapack.blockstate import BlockState from mcpacker.model.datapack.blockstateprovider import BlockStateProvider -from typing import Any +from typing import Any # Class ############################################################################################ @@ -11,8 +12,8 @@ class SimpleStateProvider(BlockStateProvider): super().__init__("minecraft:simple_state_provider") self.state = state - def asData(self) -> dict[str, Any]: + def asJsonBlob(self) -> JsonBlob: return { "type": self.gameId, - "state": self.state.asData(), + "state": self.state.asJsonBlob(), } diff --git a/mcpacker/model/datapack/blockstateprovider/simplestateprovider_test.py b/mcpacker/model/datapack/blockstateprovider/simplestateprovider_test.py index 5823498..bc1fa6a 100644 --- a/mcpacker/model/datapack/blockstateprovider/simplestateprovider_test.py +++ b/mcpacker/model/datapack/blockstateprovider/simplestateprovider_test.py @@ -10,14 +10,14 @@ def createBlockState(): yield BlockState("minecraft:button", {"waterlogged": "true"}) @fixture(name="provider") -def createProvider(state): +def createProvider(state:BlockState): return SimpleStateProvider(state) # Tests ############################################################################################ -def test_asData(provider): - assert provider.asData() == { +def test_asData(provider:SimpleStateProvider): + assert provider.asJsonBlob() == { "type": "minecraft:simple_state_provider", "state": { "Name": "minecraft:button", diff --git a/mcpacker/model/datapack/configuredfeature/randompatch.py b/mcpacker/model/datapack/configuredfeature/randompatch.py index 1923824..7368d7a 100644 --- a/mcpacker/model/datapack/configuredfeature/randompatch.py +++ b/mcpacker/model/datapack/configuredfeature/randompatch.py @@ -1,5 +1,9 @@ from mcpacker.model.datapack.configuredfeature import ConfiguredFeature from typing import Any +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from mcpacker.model.datapack.placedfeature import PlacedFeature # Class ############################################################################################ @@ -9,7 +13,7 @@ class RandomPatch(ConfiguredFeature): def __init__( self, gameId:str, - feature:"PlacedFeature", + feature:PlacedFeature, tries:int=128, xzSpread:int=7, ySpread:int=3, @@ -23,9 +27,9 @@ class RandomPatch(ConfiguredFeature): def asData(self) -> dict[str,Any]: return { - "type": self.type, + "type": self.gameId, "feature": self.feature.gameId, "tries": self.tries, - "xz_spread": self.xySpread, + "xz_spread": self.xzSpread, "y_spread": self.ySpread } diff --git a/mcpacker/model/datapack/configuredfeature/randompatch_test.py b/mcpacker/model/datapack/configuredfeature/randompatch_test.py index d3c915a..9cd6a02 100644 --- a/mcpacker/model/datapack/configuredfeature/randompatch_test.py +++ b/mcpacker/model/datapack/configuredfeature/randompatch_test.py @@ -11,18 +11,18 @@ def createBlockState(): yield BlockState("minecraft:button", {"waterlogged": "true"}) @fixture(name="provider") -def createProvider(state): +def createProvider(state:BlockState): return SimpleStateProvider(state) @fixture(name="feature") -def createSimpleBlockFeature(provider): +def createSimpleBlockFeature(provider:SimpleStateProvider): return SimpleBlock(provider) # Tests ############################################################################################ -def test_asData(feature): - assert feature.asData() == { +def test_asData(feature:SimpleBlock): + assert feature.asJsonBlob() == { "type": "minecraft:simple_block", "config": { "to_place": { diff --git a/mcpacker/model/datapack/configuredfeature/simpleblock.py b/mcpacker/model/datapack/configuredfeature/simpleblock.py index 63feaaa..5ee4567 100644 --- a/mcpacker/model/datapack/configuredfeature/simpleblock.py +++ b/mcpacker/model/datapack/configuredfeature/simpleblock.py @@ -1,6 +1,7 @@ +from mcpacker.json import JsonBlob from mcpacker.model.datapack.blockstateprovider import BlockStateProvider -from mcpacker.model.datapack.configuredfeature import ConfiguredFeature -from typing import Any +from mcpacker.model.datapack.configuredfeature import ConfiguredFeature +from typing import Any # Class ############################################################################################ @@ -11,10 +12,10 @@ class SimpleBlock(ConfiguredFeature): super().__init__("minecraft:simple_block") self.toPlace = toPlace - def asData(self) -> dict[str, Any]: + def asJsonBlob(self) -> JsonBlob: return { "type": self.gameId, "config": { - "to_place": self.toPlace.asData() + "to_place": self.toPlace.asJsonBlob() } } diff --git a/mcpacker/model/datapack/configuredfeature/simpleblock_test.py b/mcpacker/model/datapack/configuredfeature/simpleblock_test.py index d3c915a..9cd6a02 100644 --- a/mcpacker/model/datapack/configuredfeature/simpleblock_test.py +++ b/mcpacker/model/datapack/configuredfeature/simpleblock_test.py @@ -11,18 +11,18 @@ def createBlockState(): yield BlockState("minecraft:button", {"waterlogged": "true"}) @fixture(name="provider") -def createProvider(state): +def createProvider(state:BlockState): return SimpleStateProvider(state) @fixture(name="feature") -def createSimpleBlockFeature(provider): +def createSimpleBlockFeature(provider:SimpleStateProvider): return SimpleBlock(provider) # Tests ############################################################################################ -def test_asData(feature): - assert feature.asData() == { +def test_asData(feature:SimpleBlock): + assert feature.asJsonBlob() == { "type": "minecraft:simple_block", "config": { "to_place": { diff --git a/mcpacker/model/datapack/mod.py b/mcpacker/model/datapack/mod.py deleted file mode 100644 index ae11120..0000000 --- a/mcpacker/model/datapack/mod.py +++ /dev/null @@ -1,17 +0,0 @@ -# Class ############################################################################################ - -class Mod: - - def __init__(self): - self.biomeModifiers = [] - self.configuredFeatures = [] - self.functions = [] - self.functionTags = [] - self.lootModifiers = [] - self.lootTables = [] - self.placedFeatures = [] - self.recipes = [] - self.structures = [] - self.structureSets = [] - self.tags = [] - self.templatePools = [] diff --git a/mcpacker/model/datapack/moddata.py b/mcpacker/model/datapack/moddata.py new file mode 100644 index 0000000..ae2d389 --- /dev/null +++ b/mcpacker/model/datapack/moddata.py @@ -0,0 +1,23 @@ +from mcpacker.model.datapack.configuredfeature import ConfiguredFeature +from mcpacker.model.datapack.placedfeature import PlacedFeature +from typing import Any + + +# Class ############################################################################################ + +class ModData: + + def __init__(self, name:str): + self.name = name + self.biomeModifiers:list[Any] = [] + self.configuredFeatures:list[ConfiguredFeature] = [] + self.functions:list[Any] = [] + self.functionTags:list[Any] = [] + self.lootModifiers:list[Any] = [] + self.lootTables:list[Any] = [] + self.placedFeatures:list[PlacedFeature] = [] + self.recipes:list[Any] = [] + self.structures:list[Any] = [] + self.structureSets:list[Any] = [] + self.tags:list[Any] = [] + self.templatePools:list[Any] = [] diff --git a/mcpacker/model/resourcepack/mod_test.py b/mcpacker/model/datapack/moddata_test.py similarity index 76% rename from mcpacker/model/resourcepack/mod_test.py rename to mcpacker/model/datapack/moddata_test.py index be11191..e7d5821 100644 --- a/mcpacker/model/resourcepack/mod_test.py +++ b/mcpacker/model/datapack/moddata_test.py @@ -1,8 +1,7 @@ -import mcpacker.model.resourcepack.mod +import mcpacker.model.datapack.moddata # Tests ############################################################################################ def test_syntax(): pass - diff --git a/mcpacker/model/incontrol/__init__.py b/mcpacker/model/incontrol/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/mcpacker/model/incontrol/condition.py b/mcpacker/model/incontrol/condition.py new file mode 100644 index 0000000..b723d2d --- /dev/null +++ b/mcpacker/model/incontrol/condition.py @@ -0,0 +1,38 @@ +from mcpacker.json import JsonBlob +from mcpacker.model.incontrol.extracondition import ExtraCondition +from mcpacker.model.core.dimension import Dimension + +import mcpacker.json as json +import mcpacker.model.core.altitude as A +import mcpacker.model.core.dimension as D + + +# Class ############################################################################################ + +class Condition: + + def __init__( + self, + dimension:Dimension=D.OVERWORLD, + heightMin:int|None=None, + heightMax:int|None=None, + thisMax:int|None=None, + inWater:bool|None=None, + andCondition:ExtraCondition|None=None, + ): + self.dimension = dimension + self.heightMin = heightMin + self.heightMax = heightMax + self.thisMax = thisMax + self.inWater = inWater + self.andCondition = andCondition + + def asJsonBlob(self) -> JsonBlob: + return json.removeNoneValues({ + "dimension": self.dimension.name, + "heightmin": self.heightMin, + "heightmax": self.heightMax, + "maxthis": self.thisMax, + "inwater": self.inWater, + "and": None if not self.andCondition else self.andCondition.asJsonBlob(), + }) diff --git a/mcpacker/model/incontrol/extracondition.py b/mcpacker/model/incontrol/extracondition.py new file mode 100644 index 0000000..6a69b9c --- /dev/null +++ b/mcpacker/model/incontrol/extracondition.py @@ -0,0 +1,44 @@ +from collections.abc import Iterable +from mcpacker.json import JsonBlob + +import mcpacker.json as json + + +# Class ############################################################################################ + +class ExtraCondition: + + def __init__( + self, + autumn:bool|None=None, + biome:Iterable[str]|None=None, + cave:bool|None=None, + seeSky:bool|None=None, + spring:bool|None=None, + summer:bool|None=None, + timeMax:int|None=None, + timeMin:int|None=None, + winter:bool|None=None, + ): + self.autumn = autumn + self.biome = biome + self.cave = cave + self.seeSky = seeSky + self.spring = spring + self.summer = summer + self.timeMax = timeMax + self.timeMin = timeMin + self.winter = winter + + def asJsonBlob(self) -> JsonBlob: + return json.removeNoneValues({ + "autumn": self.autumn, + "biome": None if not self.biome else "[" + ", ".join(self.biome) + "]", + "cave": self.cave, + "seesky": self.seeSky, + "spring": self.spring, + "summer": self.summer, + "maxtime": self.timeMax, + "mintime": self.timeMin, + "winter": self.winter, + }) diff --git a/mcpacker/model/incontrol/spawnerrule.py b/mcpacker/model/incontrol/spawnerrule.py new file mode 100644 index 0000000..aa95a1c --- /dev/null +++ b/mcpacker/model/incontrol/spawnerrule.py @@ -0,0 +1,41 @@ +from mcpacker.json import JsonBlob +from mcpacker.model.core.fauna.mobspawn import MobSpawn +from mcpacker.model.incontrol.condition import Condition + + +# Class ############################################################################################ + +class SpawnerRule: + + def __init__( + self, + mobGameId:str, + condition:Condition, + amountMin:int=1, + amountMax:int=1, + rate:float=1.0, + attempts:int=1, + weight:int=1, + ): + self.mobGameId = mobGameId + self.amountMin = amountMin + self.amountMax = amountMax + self.rate = rate + self.attempts = attempts + self.weight = weight + self.condition = condition + + def asJsonBlob(self) -> JsonBlob: + return { + "mob": [self.mobGameId], + "amount": { + "minimum": self.amountMin, + "maximum": self.amountMax, + "groupdistance": 4, + }, + "persecond": self.rate, + "attempts": self.attempts, + "weights": [self.weight], + "conditions": self.condition.asJsonBlob(), + } + diff --git a/mcpacker/model/modpack.py b/mcpacker/model/modpack.py index 52d1383..072c977 100644 --- a/mcpacker/model/modpack.py +++ b/mcpacker/model/modpack.py @@ -29,3 +29,4 @@ class ModPack: def augment(self, doAugment:"Callable[[ModPack], None]") -> "ModPack": doAugment(self) + return self diff --git a/mcpacker/model/resourcepack/__init__.py b/mcpacker/model/resourcepack/__init__.py index b2be0b2..221113b 100644 --- a/mcpacker/model/resourcepack/__init__.py +++ b/mcpacker/model/resourcepack/__init__.py @@ -1,40 +1,41 @@ from collections.abc import Iterable -from mcpacker.model.resourcepack.mod import Mod +from mcpacker.model.resourcepack.modresource import ModResource # Class ############################################################################################ class ResourcePack: - def __init__(self, name:str, mods:Iterable[Mod]|None=None): + def __init__(self, name:str, mods:Iterable[ModResource]|None=None): self.name = name - self._mods = {} - self._defaultMod = None + self._mods:dict[str,ModResource] = {} + self._defaultMod:ModResource|None = None for mod in (mods or []): self.add(mod) - def add(self, mod:Mod) -> "Resourcepack": + def add(self, mod:ModResource) -> "ResourcePack": if not self._defaultMod: self._defaultMod = mod self._mods[mod.name] = mod return self - def get(self, modName:str) -> Mod: - return self._mods.get(modName, None) + def get(self, name:str) -> ModResource|None: + return self._mods.get(name, None) @property - def defaultMod(self) -> Mod: + def defaultMod(self) -> ModResource|None: return self._defaultMod @defaultMod.setter - def setDefaultMod(self, mod:Mod) -> "Resourcepack": - existingMod = self.get(mod.name) - if not existingMod: - self.add(mod) - elif existingMod != mod: - raise Exception(f"Resourcepack already has a mod named {mod.name}") + def defaultMod(self, mod:ModResource): + if mod: + existingMod = self.get(mod.name) + if not existingMod: + self.add(mod) + elif existingMod != mod: + raise Exception(f"Resourcepack already has a mod named {mod.name}") self._defaultMod = mod diff --git a/mcpacker/model/resourcepack/kind.py b/mcpacker/model/resourcepack/kind.py index 3af73ec..5d81bb8 100644 --- a/mcpacker/model/resourcepack/kind.py +++ b/mcpacker/model/resourcepack/kind.py @@ -7,7 +7,7 @@ class Kind: def __eq__(self, other) -> bool: if type(self) != type(other): return False - if self.name != othere.name: return False + if self.name != other.name: return False return True def __repr__(self) -> str: diff --git a/mcpacker/model/resourcepack/mod.py b/mcpacker/model/resourcepack/mod.py deleted file mode 100644 index 5c0bc92..0000000 --- a/mcpacker/model/resourcepack/mod.py +++ /dev/null @@ -1,8 +0,0 @@ -# Class ############################################################################################ - -class Mod: - - def __init__(self): - self.blockStates = [] - self.models = [] - self.textures = [] diff --git a/mcpacker/model/resourcepack/modresource.py b/mcpacker/model/resourcepack/modresource.py new file mode 100644 index 0000000..5c866e4 --- /dev/null +++ b/mcpacker/model/resourcepack/modresource.py @@ -0,0 +1,9 @@ +# Class ############################################################################################ + +class ModResource: + + def __init__(self, name:str): + self.name = name + self.blockStates:list[str] = [] + self.models:list[str] = [] + self.textures:list[str] = [] diff --git a/mcpacker/model/resourcepack/modresource_test.py b/mcpacker/model/resourcepack/modresource_test.py new file mode 100644 index 0000000..90ade6a --- /dev/null +++ b/mcpacker/model/resourcepack/modresource_test.py @@ -0,0 +1,8 @@ +import mcpacker.model.resourcepack.modresource + + +# Tests ############################################################################################ + +def test_syntax(): + pass + diff --git a/mcpacker/pack/mysteriousisland/addblocks.py b/mcpacker/pack/mysteriousisland/addblocks.py index 68634dd..97c6995 100644 --- a/mcpacker/pack/mysteriousisland/addblocks.py +++ b/mcpacker/pack/mysteriousisland/addblocks.py @@ -16,7 +16,7 @@ def addBlocks(pack:ModPack): blocks.add(Block( gameId = "kubejs:peat_block", - loot = LootTable(Loot(items.get("kubejs:peat_chunk"), 2, 9)), + loot = LootTable(Loot.of(items.get("kubejs:peat_chunk"), 2, 9)), name = "Peat Block", soundType = SO.DIRT, tags = ["minecraft:mineable/shovel"], diff --git a/mcpacker/pack/mysteriousisland/adddeposits.py b/mcpacker/pack/mysteriousisland/adddeposits.py index 5488efa..f385f05 100644 --- a/mcpacker/pack/mysteriousisland/adddeposits.py +++ b/mcpacker/pack/mysteriousisland/adddeposits.py @@ -3,15 +3,16 @@ from mcpacker.model.core.geology.deposit.metaldeposit import MetalDeposit from mcpacker.model.core.geology.inclusion import Inclusion as I from mcpacker.model.modpack import ModPack -import mcpacker.model.core.altitude as AL -import mcpacker.model.core.ecology.flora as FL -import mcpacker.model.core.ecology.geology as GE -import mcpacker.model.core.ecology.heat as HE -import mcpacker.model.core.ecology.humidity as HU -import mcpacker.model.core.ecology.soil as SO -import mcpacker.model.core.ecology.water as WA -import mcpacker.model.core.geology.bulk as BU -import mcpacker.model.core.scarcity as SC +import mcpacker.model.core.altitude as AL +import mcpacker.model.core.ecology.flora as FL +import mcpacker.model.core.ecology.geology as GE +import mcpacker.model.core.ecology.heat as HE +import mcpacker.model.core.ecology.humidity as HU +import mcpacker.model.core.ecology.soil as SO +import mcpacker.model.core.ecology.water as WA +import mcpacker.model.core.geology.bulk as BU +import mcpacker.model.core.geology.proportion as PR +import mcpacker.model.core.scarcity as SC # Catalog ########################################################################################## @@ -24,10 +25,10 @@ def addDeposits(pack:ModPack): scarcity = SC.COMMON, biomeFilter = BF([GE.METAMORPHIC, (HE.BOREAL, HE.FROZEN), HU.DAMP]), inclusions = [ - I(minerals.get("iron"), 50), - I(minerals.get("quartz"), 45), - I(minerals.get("uranium"), 5) + I(minerals["iron"], 50), + I(minerals["quartz"], 45), + I(minerals["uranium"], 5) ], bulk = BU.LARGE, - proportion = 0.2, + proportion = PR.BED, )) diff --git a/mcpacker/pack/mysteriousisland/addmobs.py b/mcpacker/pack/mysteriousisland/addmobs.py index 178a12b..5a83ffc 100644 --- a/mcpacker/pack/mysteriousisland/addmobs.py +++ b/mcpacker/pack/mysteriousisland/addmobs.py @@ -1,22 +1,7 @@ -from mcpacker.model.core.ecology.biomefilter import BiomeFilter as BF -from mcpacker.model.core.fauna.mob import Mob -from mcpacker.model.core.fauna.mobcatalog import MobCatalog -from mcpacker.model.core.fauna.mobplacement import MobPlacement -from mcpacker.model.core.habitat import Habitat -from mcpacker.model.modpack import ModPack +from mcpacker.model.core.fauna.mob import Mob +from mcpacker.model.modpack import ModPack -import mcpacker.model.core.altitude as AL -import mcpacker.model.core.ecology.flora as FL -import mcpacker.model.core.ecology.geology as GE -import mcpacker.model.core.ecology.heat as HE -import mcpacker.model.core.ecology.humidity as HU -import mcpacker.model.core.ecology.soil as SO -import mcpacker.model.core.ecology.water as WA -import mcpacker.model.core.fauna.active as AC -import mcpacker.model.core.fauna.group as GR -import mcpacker.model.core.fauna.location as LO -import mcpacker.model.core.scarcity as SC -import mcpacker.model.core.season as SE +import mcpacker.model.core.fauna.active as AC # Constants ######################################################################################## @@ -24,354 +9,67 @@ import mcpacker.model.core.season as SE def addMobs(pack:ModPack): mobs = pack.world.mobs - mobs.add( - MobPlacement(Mob("armadillo", "minecraft:armadillo", AC.NOCTURNAL), - Habitat( - altitude = AL.LOWLANDS, - biomeFilter = BF([HE.SUBTROPICAL, HU.DRY]), - seasons = SE.SUMMER, - group = GR.merge(GR.SOLO, GR.PAIR), - scarcity = SC.COMMON - ).derive( - altitude = AL.UPLANDS, scarcity = SC.SPARSE, - ).derive( - altitude = AL.LOWLANDS, seasons = SE.exclude(SE.SUMMER), scarcity = SC.UNCOMMON, - ).derive( - altitude = AL.UPLANDS, scarcity = SC.UNUSUAL, - ) - ) - ) - - mobs.add( - MobPlacement(Mob("black_bear", "bearminimum:black_bear"), - Habitat( - altitude = AL.span(AL.LOWLANDS, AL.ALPINE), - biomeFilter = BF([HE.TEMPERATE, FL.FOREST]), - seasons = SE.AUTUMN, - group = GR.merge(GR.SOLO, GR.FAMILY), - scarcity = SC.UNCOMMON, - ).derive( - seasons = [SE.SPRING, SE.SUMMER], scarcity = SC.SPARSE - ).derive( - seasons = SE.WINTER, scarcity = SC.UNUSUAL - ).derive( - biomeFilter = BF([HE.BOREAL, (FL.CANOPY, FL.FOREST)]), - seasons = SE.AUTUMN, - scarcity = SC.SPARSE - ).derive( - seasons = [SE.SPRING, SE.SUMMER], scarcity = SC.UNUSUAL - ).derive( - seasons = SE.WINTER, scarcity = SC.RARE - ) - ) - ) - - mobs.add( - MobPlacement(Mob("blaze", "minecraft:blaze"), - Habitat( - altitude = AL.PLUTONIC, - location = LO.CAVE, - group = GR.SOLO, - scarcity = SC.UNCOMMON - ) - ) - ) - - mobs.add( - MobPlacement(Mob("bogged", "minecraft:bogged")) - ) - - mobs.add( - MobPlacement(Mob("brown_bear", "bearminimum:brown_bear"), - Habitat( - altitude = AL.span(AL.LOWLANDS, AL.ALPINE), - biomeFilter = BF([HE.BOREAL, (FL.CANOPY, FL.FOREST)]), - seasons = SE.AUTUMN, - group = GR.SOLO, - scarcity = SC.SPARSE - ).derive( - seasons = [SE.SPRING, SE.SUMMER], scarcity = SC.UNUSUAL - ).derive( - seasons = SE.WINTER, scarcity = SC.RARE - ) - ) - ) - - mobs.add( - MobPlacement(Mob("bulwark", "immersiveengineering:bulwark")) - ) - - mobs.add( - MobPlacement(Mob("camel", "minecraft:camel", AC.CREPUSCULAR), - Habitat( - altitude = AL.span(AL.DUNES, AL.LOWLANDS), - biomeFilter = BF([HE.TROPICAL, HU.DRY, FL.BARREN, SO.SANDY]), - seasons = SE.DRY, - group = GR.FAMILY, - scarcity = SC.UNUSUAL, - ).derive( - seasons = SE.WET, scarcity = SC.RARE - ) - ) - ) - - mobs.add( - MobPlacement(Mob("cat", "minecraft:cat")) - ) - - mobs.add( - MobPlacement(Mob("cave_spider", "minecraft:cave_spider"), - Habitat( - altitude = AL.span(AL.OVERBURDEN, AL.HILLS), - location = LO.CAVE, - group = GR.SOLO, - scarcity = SC.UNCOMMON - ) - ) - ) - - mobs.add( - MobPlacement(Mob("chameleon", "cold_sweat:chameleon"), - Habitat( - altitude = AL.span(AL.DUNES, AL.UPLANDS), - biomeFilter = BF([HE.TROPICAL, HU.WET, [FL.CANOPY, FL.FOREST]]), - seasons = SE.WET, - group = GR.merge(GR.SOLO, GR.FAMILY), - scarcity = SC.COMMON, - ).derive( - seasons = SE.DRY, scarcity = SC.UNCOMMON, - ).derive( - biomeFilter = BF([HE.TROPICAL, HU.WET, FL.CLEARING]), - seasons = SE.WET, - scarcity = SC.UNCOMMON - ).derive( - seasons = SE.DRY, scarcity = SC.SPARSE, - ) - ) - ) - - mobs.add( - MobPlacement(Mob("chicken", "minecraft:chicken"), - Habitat( - altitude = AL.span(AL.LOWLANDS, AL.UPLANDS), - biomeFilter = BF([HE.TROPICAL, HU.WET, FL.within(FL.CANOPY, FL.CLEARING)]), - seasons = SE.SUMMER, - group = GR.TROUP, - scarcity = SC.COMMON, - ).derive( - seasons = SE.exclude(SE.SUMMER), scarcity = SC.UNCOMMON - ) - ) - ) - - mobs.add( - MobPlacement(Mob("cod", "minecraft:cod")) - ) - - mobs.add( - MobPlacement(Mob("commando", "immersiveengineering:commando")) - ) - - mobs.add( - MobPlacement(Mob("cow", "minecraft:cow")) - ) - - mobs.add( - MobPlacement(Mob("crab", "crabbersdelight:crab")) - ) - - mobs.add( - MobPlacement(Mob("creeper", "minecraft:creeper")) - ) - - mobs.add( - MobPlacement(Mob("dolphin", "minecraft:dolphin")) - ) - - mobs.add( - MobPlacement(Mob("donkey", "minecraft:donkey")) - ) - - mobs.add( - MobPlacement(Mob("drowned", "minecraft:drowned")) - ) - - mobs.add( - MobPlacement(Mob("enderman", "minecraft:enderman")) - ) - - mobs.add( - MobPlacement(Mob("evoker", "minecraft:evoker")) - ) - - mobs.add( - MobPlacement(Mob("fox", "minecraft:fox")) - ) - - mobs.add( - MobPlacement(Mob("frog", "minecraft:frog")) - ) - - mobs.add( - MobPlacement(Mob("fusilier", "immersiveengineering:fusilier")) - ) - - mobs.add( - MobPlacement(Mob("glow_squid", "minecraft:glow_squid")) - ) - - mobs.add( - MobPlacement(Mob("goat", "minecraft:goat")) - ) - - mobs.add( - MobPlacement(Mob("hoglin", "minecraft:hoglin")) - ) - - mobs.add( - MobPlacement(Mob("horse", "minecraft:horse")) - ) - - mobs.add( - MobPlacement(Mob("husk", "minecraft:husk")) - ) - - mobs.add( - MobPlacement(Mob("llama", "minecraft:llama")) - ) - - mobs.add( - MobPlacement(Mob("magma_cube", "minecraft:magma_cube")) - ) - - mobs.add( - MobPlacement(Mob("mooshroom", "minecraft:mooshroom")) - ) - - mobs.add( - MobPlacement(Mob("mule", "minecraft:mule")) - ) - - mobs.add( - MobPlacement(Mob("ocelot", "minecraft:ocelot")) - ) - - mobs.add( - MobPlacement(Mob("panda", "minecraft:panda")) - ) - - mobs.add( - MobPlacement(Mob("parrot", "minecraft:parrot")) - ) - - mobs.add( - MobPlacement(Mob("pig", "minecraft:pig")) - ) - - mobs.add( - MobPlacement(Mob("pillager", "minecraft:pillager")) - ) - - mobs.add( - MobPlacement(Mob("polar_bear", "minecraft:polar_bear")) - ) - - mobs.add( - MobPlacement(Mob("pufferfish", "minecraft:pufferfish")) - ) - - mobs.add( - MobPlacement(Mob("rabbit", "minecraft:rabbit")) - ) - - mobs.add( - MobPlacement(Mob("raccoon", "animalplus:raccoon")) - ) - - mobs.add( - MobPlacement(Mob("ravager", "minecraft:ravager")) - ) - - mobs.add( - MobPlacement(Mob("red_panda", "animalplus:red_panda")) - ) - - mobs.add( - MobPlacement(Mob("salmon", "minecraft:salmon")) - ) - - mobs.add( - MobPlacement(Mob("sheep", "minecraft:sheep")) - ) - - mobs.add( - MobPlacement(Mob("skeleton", "minecraft:skeleton")) - ) - - mobs.add( - MobPlacement(Mob("slime", "minecraft:slime")) - ) - - mobs.add( - MobPlacement(Mob("spider", "minecraft:spider")) - ) - - mobs.add( - MobPlacement(Mob("squid", "minecraft:squid")) - ) - - mobs.add( - MobPlacement(Mob("tropical_fish", "minecraft:tropical_fish")) - ) - - mobs.add( - MobPlacement(Mob("turtle", "minecraft:turtle")) - ) - - mobs.add( - MobPlacement(Mob("vex", "minecraft:vex")) - ) - - mobs.add( - MobPlacement(Mob("villager", "minecraft:villager")) - ) - - mobs.add( - MobPlacement(Mob("vindicator", "minecraft:vindicator")) - ) - - mobs.add( - MobPlacement(Mob("wandering_trader", "minecraft:wandering_trader")) - ) - - mobs.add( - MobPlacement(Mob("warden", "minecraft:warden")) - ) - - mobs.add( - MobPlacement(Mob("witch", "minecraft:witch")) - ) - - mobs.add( - MobPlacement(Mob("wither_skeleton", "minecraft:wither_skeleton")) - ) - - mobs.add( - MobPlacement(Mob("wither", "minecraft:wither")) - ) - - mobs.add( - MobPlacement(Mob("wolf", "minecraft:wolf")) - ) - - mobs.add( - MobPlacement(Mob("zoglin", "minecraft:zoglin")) - ) - - mobs.add( - MobPlacement(Mob("zombie_villager", "minecraft:zombie_villager")) - ) - - mobs.add( - MobPlacement(Mob("zombie", "minecraft:zombie")) - ) + mobs.add(Mob("animalplus:raccoon", AC.NOCTURNAL)) + mobs.add(Mob("animalplus:red_panda", AC.CREPUSCULAR)) + mobs.add(Mob("bearminimum:black_bear", AC.CREPUSCULAR)) + mobs.add(Mob("bearminimum:brown_bear", AC.CREPUSCULAR)) + mobs.add(Mob("cold_sweat:chameleon", AC.DIURNAL)) + mobs.add(Mob("crabbersdelight:crab", AC.CREPUSCULAR)) + mobs.add(Mob("immersiveengineering:bulwark")) + mobs.add(Mob("immersiveengineering:commando")) + mobs.add(Mob("immersiveengineering:fusilier")) + mobs.add(Mob("minecraft:armadillo", AC.NOCTURNAL)) + mobs.add(Mob("minecraft:blaze", AC.ANY)) + mobs.add(Mob("minecraft:bogged", AC.MIDNIGHT)) + mobs.add(Mob("minecraft:camel", AC.CREPUSCULAR)) + mobs.add(Mob("minecraft:cat", AC.CREPUSCULAR)) + mobs.add(Mob("minecraft:cave_spider", AC.NOCTURNAL)) + mobs.add(Mob("minecraft:chicken", AC.DIURNAL)) + mobs.add(Mob("minecraft:cod", AC.DIURNAL)) + mobs.add(Mob("minecraft:cow", AC.DIURNAL)) + mobs.add(Mob("minecraft:creeper", AC.STORMY)) + mobs.add(Mob("minecraft:dolphin", AC.DIURNAL)) + mobs.add(Mob("minecraft:donkey", AC.DIURNAL)) + mobs.add(Mob("minecraft:drowned", AC.MIDNIGHT)) + mobs.add(Mob("minecraft:enderman")) + mobs.add(Mob("minecraft:evoker")) + mobs.add(Mob("minecraft:fox", AC.CREPUSCULAR)) + mobs.add(Mob("minecraft:frog", AC.CREPUSCULAR)) + mobs.add(Mob("minecraft:glow_squid", AC.CREPUSCULAR)) + mobs.add(Mob("minecraft:goat", AC.DIURNAL)) + mobs.add(Mob("minecraft:hoglin")) + mobs.add(Mob("minecraft:horse", AC.DIURNAL)) + mobs.add(Mob("minecraft:husk", AC.MIDNIGHT)) + mobs.add(Mob("minecraft:llama", AC.DIURNAL)) + mobs.add(Mob("minecraft:magma_cube", AC.ANY)) + mobs.add(Mob("minecraft:mooshroom", AC.DIURNAL)) + mobs.add(Mob("minecraft:mule", AC.DIURNAL)) + mobs.add(Mob("minecraft:ocelot", AC.NOCTURNAL)) + mobs.add(Mob("minecraft:panda", AC.CREPUSCULAR)) + mobs.add(Mob("minecraft:parrot", AC.DIURNAL)) + mobs.add(Mob("minecraft:pig", AC.DIURNAL)) + mobs.add(Mob("minecraft:pillager")) + mobs.add(Mob("minecraft:polar_bear", AC.CREPUSCULAR)) + mobs.add(Mob("minecraft:pufferfish", AC.DIURNAL)) + mobs.add(Mob("minecraft:rabbit", AC.CREPUSCULAR)) + mobs.add(Mob("minecraft:ravager")) + mobs.add(Mob("minecraft:salmon", AC.DIURNAL)) + mobs.add(Mob("minecraft:sheep", AC.DIURNAL)) + mobs.add(Mob("minecraft:skeleton")) + mobs.add(Mob("minecraft:slime", AC.RAINY)) + mobs.add(Mob("minecraft:spider", AC.NOCTURNAL)) + mobs.add(Mob("minecraft:squid", AC.CREPUSCULAR)) + mobs.add(Mob("minecraft:tropical_fish", AC.DIURNAL)) + mobs.add(Mob("minecraft:turtle", AC.NOCTURNAL)) + mobs.add(Mob("minecraft:vex")) + mobs.add(Mob("minecraft:villager")) + mobs.add(Mob("minecraft:vindicator")) + mobs.add(Mob("minecraft:wandering_trader")) + mobs.add(Mob("minecraft:warden")) + mobs.add(Mob("minecraft:witch")) + mobs.add(Mob("minecraft:wither_skeleton")) + mobs.add(Mob("minecraft:wither")) + mobs.add(Mob("minecraft:wolf", AC.NOCTURNAL)) + mobs.add(Mob("minecraft:zoglin")) + mobs.add(Mob("minecraft:zombie_villager", AC.MIDNIGHT)) + mobs.add(Mob("minecraft:zombie")) diff --git a/mcpacker/pack/mysteriousisland/addmobspawns.py b/mcpacker/pack/mysteriousisland/addmobspawns.py new file mode 100644 index 0000000..d1d0729 --- /dev/null +++ b/mcpacker/pack/mysteriousisland/addmobspawns.py @@ -0,0 +1,411 @@ +from mcpacker.model.core.ecology.biomefilter import BiomeFilter as BF +from mcpacker.model.core.fauna.mob import Mob +from mcpacker.model.core.fauna.mobcatalog import MobCatalog +from mcpacker.model.core.fauna.mobspawn import MobSpawn +from mcpacker.model.core.habitat import Habitat +from mcpacker.model.modpack import ModPack + +import mcpacker.model.core.altitude as AL +import mcpacker.model.core.ecology.flora as FL +import mcpacker.model.core.ecology.geology as GE +import mcpacker.model.core.ecology.heat as HE +import mcpacker.model.core.ecology.humidity as HU +import mcpacker.model.core.ecology.soil as SO +import mcpacker.model.core.ecology.water as WA +import mcpacker.model.core.fauna.active as AC +import mcpacker.model.core.fauna.group as GR +import mcpacker.model.core.fauna.location as LO +import mcpacker.model.core.scarcity as SC +import mcpacker.model.core.season as SE + + +# Constants ######################################################################################## + +def addMobs(pack:ModPack): + mobs = pack.world.mobs + spawns = pack.world.mobSpawns + + spawns.add( + MobSpawn(mobs["animalplus:raccoon"]) + ) + + spawns.add( + MobSpawn(mobs["animalplus:red_panda"]) + ) + + spawns.add( + MobSpawn(mobs["bearminimum:black_bear"], + Habitat( + altitude = AL.span(AL.LOWLANDS, AL.ALPINE), + biomeFilter = BF([HE.TEMPERATE, FL.FOREST]), + seasons = SE.AUTUMN, + group = GR.merge(GR.SOLO, GR.FAMILY), + scarcity = SC.UNCOMMON, + ).derive( + seasons = [SE.SPRING, SE.SUMMER], scarcity = SC.SPARSE + ).derive( + seasons = SE.WINTER, scarcity = SC.UNUSUAL + ).derive( + biomeFilter = BF([HE.BOREAL, (FL.CANOPY, FL.FOREST)]), + seasons = SE.AUTUMN, + scarcity = SC.SPARSE + ).derive( + seasons = [SE.SPRING, SE.SUMMER], scarcity = SC.UNUSUAL + ).derive( + seasons = SE.WINTER, scarcity = SC.RARE + ) + ) + ) + + spawns.add( + MobSpawn(mobs["minecraft:armadillo"], + Habitat( + altitude = AL.LOWLANDS, + biomeFilter = BF([HE.SUBTROPICAL, HU.DRY]), + seasons = SE.SUMMER, + group = GR.merge(GR.SOLO, GR.PAIR), + scarcity = SC.COMMON + ).derive( + altitude = AL.UPLANDS, scarcity = SC.SPARSE, + ).derive( + altitude = AL.LOWLANDS, seasons = SE.exclude(SE.SUMMER), scarcity = SC.UNCOMMON, + ).derive( + altitude = AL.UPLANDS, scarcity = SC.UNUSUAL, + ) + ) + ) + + spawns.add( + MobSpawn(mobs["minecraft:blaze"], + Habitat( + altitude = AL.PLUTONIC, + location = LO.CAVE, + group = GR.SOLO, + scarcity = SC.UNCOMMON + ) + ) + ) + + spawns.add( + MobSpawn(mobs["minecraft:bogged"]) + ) + + spawns.add( + MobSpawn(mobs["bearminimum:brown_bear"], + Habitat( + altitude = AL.span(AL.LOWLANDS, AL.ALPINE), + biomeFilter = BF([HE.BOREAL, (FL.CANOPY, FL.FOREST)]), + seasons = SE.AUTUMN, + group = GR.SOLO, + scarcity = SC.SPARSE + ).derive( + seasons = [SE.SPRING, SE.SUMMER], scarcity = SC.UNUSUAL + ).derive( + seasons = SE.WINTER, scarcity = SC.RARE + ) + ) + ) + + spawns.add( + MobSpawn(mobs["minecraft:camel"], + Habitat( + altitude = AL.span(AL.DUNES, AL.LOWLANDS), + biomeFilter = BF([HE.TROPICAL, HU.DRY, FL.BARREN, SO.SANDY]), + seasons = SE.DRY, + group = GR.FAMILY, + scarcity = SC.UNUSUAL, + ).derive( + seasons = SE.WET, scarcity = SC.RARE + ) + ) + ) + + spawns.add( + MobSpawn(mobs["minecraft:cave_spider"], + Habitat( + altitude = AL.span(AL.OVERBURDEN, AL.HILLS), + location = LO.CAVE, + group = GR.SOLO, + scarcity = SC.UNCOMMON + ) + ) + ) + + spawns.add( + MobSpawn(mobs["cold_sweat:chameleon"], + Habitat( + altitude = AL.span(AL.DUNES, AL.UPLANDS), + biomeFilter = BF([HE.TROPICAL, HU.WET, [FL.CANOPY, FL.FOREST]]), + seasons = SE.WET, + group = GR.merge(GR.SOLO, GR.FAMILY), + scarcity = SC.COMMON, + ).derive( + seasons = SE.DRY, + scarcity = SC.UNCOMMON, + ).derive( + biomeFilter = BF([HE.TROPICAL, HU.WET, FL.CLEARING]), + seasons = SE.WET, + scarcity = SC.UNCOMMON + ).derive( + seasons = SE.DRY, + scarcity = SC.SPARSE, + ) + ) + ) + + spawns.add( + MobSpawn(mobs["minecraft:chicken"], + Habitat( + altitude = AL.span(AL.LOWLANDS, AL.UPLANDS), + biomeFilter = BF([HE.TROPICAL, HU.WET, FL.within(FL.CANOPY, FL.CLEARING)]), + seasons = SE.SUMMER, + group = GR.TROUP, + scarcity = SC.COMMON, + ).derive( + seasons = SE.exclude(SE.SUMMER), + scarcity = SC.UNCOMMON + ) + ) + ) + + spawns.add( + MobSpawn(mobs["minecraft:cod"], + Habitat( + altitude = AL.span(AL.SHALLOWS, AL.DEEPS), + biomeFilter = BF([WA.OCEAN, [HE.TEMPERATE, HE.BOREAL]]), + seasons = SE.ALL, + group = GR.HERD, + scarcity = SC.COMMON, + ).derive( + biomeFilter = BF([WA.OCEAN, HE.FROZEN]), + scarcity = SC.SPARSE, + ) + ) + ) + + spawns.add( + MobSpawn(mobs["minecraft:cow"], + Habitat( + altitude = AL.span(AL.LOWLANDS, AL.UPLANDS), + biomeFilter = BF( + [ + HE.within(HE.SUBTROPICAL, HE.BOREAL), + [HU.DAMP, HU.DRY], + FL.FIELD, + ], [ + SO.FUNGAL + ] + ), + seasons = [SE.SPRING, SE.SUMMER], + group = GR.HERD, + scarcity = SC.COMMON, + ).derive( + altitude = AL.LOWLANDS, + seasons = [SE.AUTUMN, SE.WINTER], + groups = GR.TROUP, + scarcity = SC.SPARSE, + ) + ) + ) + + spawns.add( + MobSpawn(mobs["crabbersdelight:crab"], + Habitat( + altitude = AL.DUNES, + biomeFilter = BF([WA.COAST, [HE.TROPICAL, HE.SUBTROPICAL]]), + seasons = SE.ALL, + group = GR.SOLO, + scarcity = SC.COMMON, + ).derive( + biomeFilter = BF([WA.COAST, [HE.TEMPERATE, HE.BOREAL]]), + scarcity = SC.UNCOMMON, + ) + ) + ) + + spawns.add( + MobSpawn(mobs["minecraft:dolphin"], + Habitat( + altitude = AL.span(AL.SURFACE, AL.DEEPS), + biomeFilter = BF([WA.OCEAN, [HE.SUBTROPICAL, HE.TEMPERATE]]), + location = LO.WATER, + seasons = SE.SUMMER, + group = GR.FAMILY, + scarcity = SC.UNCOMMON, + ).derive( + seasons = SE.exclude(SE.SUMMER), + scarcity = SC.SPARSE, + ) + ) + ) + + spawns.add(MobSpawn(mobs["minecraft:donkey"], + Habitat( + altitude = AL.span(AL.UPLANDS, AL.HILLS), + biomeFilter = BF([HE.SUBTROPICAL, HU.DRY, FL.FIELD]), + seasons = [SE.SUMMER, SE.AUTUMN], + group = GR.FAMILY, + scarcity = SC.UNCOMMON, + ).derive( + seasons = [SE.WINTER, SE.SPRING], + scarcity = SC.SPARSE, + ) + )) + + spawns.add(MobSpawn(mobs["minecraft:fox"], + Habitat( + altitude = AL.span(AL.LOWLANDS, AL.HILLS), + biomeFilter = BF([HE.within(HE.TEMPERATE, HE.FROZEN), FL.FOREST]), + seasons = [SE.SPRING], + group = GR.FAMILY, + scarcity = SC.UNCOMMON, + ).derive( + seasons = SE.exclude(SE.SPRING), + group = GR.SOLO, + scarcity = SC.SPARSE, + ) + )) + + spawns.add( + MobSpawn(mobs["minecraft:frog"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:glow_squid"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:goat"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:horse"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:husk"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:llama"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:magma_cube"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:mooshroom"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:mule"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:ocelot"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:panda"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:parrot"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:pig"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:polar_bear"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:pufferfish"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:rabbit"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:salmon"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:sheep"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:skeleton"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:slime"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:spider"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:squid"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:tropical_fish"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:turtle"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:vex"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:villager"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:vindicator"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:wandering_trader"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:warden"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:witch"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:wither_skeleton"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:wither"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:wolf"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:zoglin"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:zombie_villager"]) + ) + + spawns.add( + MobSpawn(mobs["minecraft:zombie"]) + ) diff --git a/mcpacker/pack/mysteriousisland/addmobspawns_test.py b/mcpacker/pack/mysteriousisland/addmobspawns_test.py new file mode 100644 index 0000000..cfb93ff --- /dev/null +++ b/mcpacker/pack/mysteriousisland/addmobspawns_test.py @@ -0,0 +1,7 @@ +import mcpacker.pack.mysteriousisland.addmobspawns + + +# Class ############################################################################################ + +def test_syntax(): + pass diff --git a/mcpacker/ui/runner.py b/mcpacker/ui/runner.py index b923633..009edf2 100644 --- a/mcpacker/ui/runner.py +++ b/mcpacker/ui/runner.py @@ -27,7 +27,7 @@ class Runner: def run(self, argv:list[str]): if len(sys.argv) < 2: - abort("Please provide a command name") + self.abort("Please provide a command name") commandName = "_command_" + argv[1] for name, doCommand in inspect.getmembers(self): @@ -35,7 +35,7 @@ class Runner: doCommand(*argv[2:]) sys.exit(0) - abort("No command named: " + argv[1]) + self.abort("No command named: " + argv[1]) # Commands ################################################################# diff --git a/requirements.txt b/requirements.txt index 5a0b69d..45bd628 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,11 @@ exceptiongroup==1.3.0 iniconfig==2.1.0 jedi==0.19.2 +mypy==1.18.2 +mypy_extensions==1.1.0 packaging==25.0 parso==0.8.4 +pathspec==0.12.1 pluggy==1.6.0 Pygments==2.19.2 pytest==8.4.2