Add biome modifier to remove managed spawns
* add formatters for biome modifiers * streamline building writers in the runner
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
from mcpacker.json import JsonBlob
|
||||||
|
|
||||||
|
|
||||||
|
# Classes ##########################################################################################
|
||||||
|
|
||||||
|
class BiomeModifier:
|
||||||
|
|
||||||
|
def asJsonBlob(self) -> JsonBlob:
|
||||||
|
return {
|
||||||
|
"type": "neoforge:none",
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
from collections.abc import Iterable
|
||||||
|
from mcpacker.format.datapack.biomemodifier import BiomeModifier
|
||||||
|
from mcpacker.format.datapack.biomemodifier.generationstep import GenerationStep
|
||||||
|
from mcpacker.json import JsonBlob
|
||||||
|
|
||||||
|
|
||||||
|
# Class ############################################################################################
|
||||||
|
|
||||||
|
class AddFeatureBiomeModifier(BiomeModifier):
|
||||||
|
|
||||||
|
def __init__(self, biomes:Iterable[str]|str, features:Iterable[str]|str, step:GenerationStep):
|
||||||
|
if isinstance(biomes, str):
|
||||||
|
biomes = [biomes]
|
||||||
|
|
||||||
|
if isinstance(features, str):
|
||||||
|
features = [features]
|
||||||
|
|
||||||
|
self.biomes = biomes
|
||||||
|
self.features = features
|
||||||
|
self.step = step
|
||||||
|
|
||||||
|
def asJsobBlob(self) -> JsonBlob:
|
||||||
|
return {
|
||||||
|
"type": "neoforge:add_features",
|
||||||
|
"biomes": list(self.biomes),
|
||||||
|
"features": list(self.features),
|
||||||
|
"step": str(self.step),
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
# Class ############################################################################################
|
||||||
|
|
||||||
|
class GenerationStep:
|
||||||
|
|
||||||
|
def __init__(self, gameId:str):
|
||||||
|
self.gameId = gameId
|
||||||
|
|
||||||
|
def __eq__(self, other:Any) -> bool:
|
||||||
|
if type(self) != type(other): return False
|
||||||
|
if self.gameId != other.gameId: return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __hash__(self) -> int:
|
||||||
|
return hash(self.gameId)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"GenerationStep(gameId={repr(self.gameId)})"
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return self.gameId
|
||||||
|
|
||||||
|
|
||||||
|
# Constants ########################################################################################
|
||||||
|
|
||||||
|
RAW_GENERATION = GenerationStep("raw_generation")
|
||||||
|
LAKES = GenerationStep("lakes")
|
||||||
|
LOCAL_MODIFICATIONS = GenerationStep("local_modifications")
|
||||||
|
UNDERGROUND_STRUCTURES = GenerationStep("underground_structures")
|
||||||
|
SURFACE_STRUCTURES = GenerationStep("surface_structures")
|
||||||
|
STRONGHOLDS = GenerationStep("strongholds")
|
||||||
|
UNDERGROUND_ORES = GenerationStep("underground_ores")
|
||||||
|
UNDERGROUND_DECORATION = GenerationStep("underground_decoration")
|
||||||
|
FLUID_SPRINGS = GenerationStep("fluid_springs")
|
||||||
|
VEGETAL_DECORATION = GenerationStep("vegetal_decoration")
|
||||||
|
TOP_LAYER_MODIFICATION = GenerationStep("top_layer_modification")
|
||||||
|
|
||||||
|
ALL = [
|
||||||
|
RAW_GENERATION,
|
||||||
|
LAKES,
|
||||||
|
LOCAL_MODIFICATIONS,
|
||||||
|
UNDERGROUND_STRUCTURES,
|
||||||
|
SURFACE_STRUCTURES,
|
||||||
|
STRONGHOLDS,
|
||||||
|
UNDERGROUND_ORES,
|
||||||
|
UNDERGROUND_DECORATION,
|
||||||
|
FLUID_SPRINGS,
|
||||||
|
VEGETAL_DECORATION,
|
||||||
|
TOP_LAYER_MODIFICATION,
|
||||||
|
]
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
from collections.abc import Iterable
|
||||||
|
from mcpacker.format.datapack.biomemodifier import BiomeModifier
|
||||||
|
from mcpacker.format.datapack.biomemodifier.generationstep import GenerationStep
|
||||||
|
from mcpacker.json import JsonBlob
|
||||||
|
|
||||||
|
|
||||||
|
# Classes ##########################################################################################
|
||||||
|
|
||||||
|
class RemoveFeatureBiomeModifier(BiomeModifier):
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
biomes:Iterable[str]|str,
|
||||||
|
features:Iterable[str]|str,
|
||||||
|
step:GenerationStep|None=None
|
||||||
|
):
|
||||||
|
if isinstance(biomes, str):
|
||||||
|
biomes = [biomes]
|
||||||
|
|
||||||
|
if isinstance(features, str):
|
||||||
|
features = [features]
|
||||||
|
|
||||||
|
self.biomes = biomes
|
||||||
|
self.features = features
|
||||||
|
self.step = step
|
||||||
|
|
||||||
|
def asJsobBlob(self) -> JsonBlob:
|
||||||
|
result:dict[str,JsonBlob] = {
|
||||||
|
"type": "neoforge:remove_features",
|
||||||
|
"biomes": list(self.biomes),
|
||||||
|
"features": list(self.features),
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.step:
|
||||||
|
result["step"] = str(self.step)
|
||||||
|
|
||||||
|
return result
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
from collections.abc import Iterable
|
||||||
|
from mcpacker.format.datapack.biomemodifier import BiomeModifier
|
||||||
|
from mcpacker.json import JsonBlob
|
||||||
|
|
||||||
|
|
||||||
|
# Classes ##########################################################################################
|
||||||
|
|
||||||
|
class RemoveSpawnBiomeModifier(BiomeModifier):
|
||||||
|
|
||||||
|
def __init__(self, biomes:Iterable[str]|str, entityTypes:Iterable[str]):
|
||||||
|
if isinstance(biomes, str):
|
||||||
|
biomes = [biomes]
|
||||||
|
|
||||||
|
self.biomes = biomes
|
||||||
|
self.entityTypes = entityTypes
|
||||||
|
|
||||||
|
def asJsonBlob(self) -> JsonBlob:
|
||||||
|
return {
|
||||||
|
"type": "neoforge:remove_spawns",
|
||||||
|
"biomes": list(self.biomes),
|
||||||
|
"entity_types": list(self.entityTypes),
|
||||||
|
}
|
||||||
+20
-12
@@ -4,6 +4,7 @@ from mcpacker.format.report.mineralreport import MineralReport
|
|||||||
from mcpacker.format.report.mobspawnreport import MobSpawnReport
|
from mcpacker.format.report.mobspawnreport import MobSpawnReport
|
||||||
from mcpacker.model.modpack import ModPack
|
from mcpacker.model.modpack import ModPack
|
||||||
from mcpacker.write.compositewriter import CompositeWriter
|
from mcpacker.write.compositewriter import CompositeWriter
|
||||||
|
from mcpacker.write.datapack.disablespawnwriter import DisableSpawnWriter
|
||||||
from mcpacker.write.datapack.metawriter import DataPackMetaWriter
|
from mcpacker.write.datapack.metawriter import DataPackMetaWriter
|
||||||
from mcpacker.write.datapack.writer import DataPackWriter
|
from mcpacker.write.datapack.writer import DataPackWriter
|
||||||
from mcpacker.write.incontrol.spawnerwriter import SpawnerWriter
|
from mcpacker.write.incontrol.spawnerwriter import SpawnerWriter
|
||||||
@@ -49,21 +50,28 @@ class Runner:
|
|||||||
# Commands #################################################################
|
# Commands #################################################################
|
||||||
|
|
||||||
def _command_writeReports(self):
|
def _command_writeReports(self):
|
||||||
CompositeWriter(self.pack, self.outputDir, [
|
p = self.pack
|
||||||
ReportWriter(self.pack, BiomeReport, self.outputDir, "biomes.txt"),
|
o = self.outputDir
|
||||||
ReportWriter(self.pack, DepositReport, self.outputDir, "deposits.txt"),
|
|
||||||
ReportWriter(self.pack, MineralReport, self.outputDir, "minerals.txt"),
|
CompositeWriter(p, o, [
|
||||||
ReportWriter(self.pack, MobSpawnReport, self.outputDir, "mobspawns.txt"),
|
ReportWriter(p, BiomeReport, o, "biomes.txt"),
|
||||||
|
ReportWriter(p, DepositReport, o, "deposits.txt"),
|
||||||
|
ReportWriter(p, MineralReport, o, "minerals.txt"),
|
||||||
|
ReportWriter(p, MobSpawnReport, o, "mobspawns.txt"),
|
||||||
]).write()
|
]).write()
|
||||||
|
|
||||||
def _command_writeModPack(self):
|
def _command_writeModPack(self):
|
||||||
CompositeWriter(self.pack, self.outputDir, [
|
p = self.pack
|
||||||
StaticWriter(self.pack, self.outputDir),
|
o = self.outputDir
|
||||||
SpawnerWriter(self.pack, self.outputDir),
|
|
||||||
DataPackWriter(self.pack, self.outputDir, [
|
CompositeWriter(p, o, [
|
||||||
DataPackMetaWriter(self.pack, self.outputDir, 48),
|
StaticWriter(p, o),
|
||||||
|
SpawnerWriter(p, o),
|
||||||
|
DataPackWriter(p, o, [
|
||||||
|
DataPackMetaWriter(p, o, 48),
|
||||||
|
DisableSpawnWriter(p, o),
|
||||||
]),
|
]),
|
||||||
ResourcePackWriter(self.pack, self.outputDir, [
|
ResourcePackWriter(p, o, [
|
||||||
ResourcePackMetaWriter(self.pack, self.outputDir, 34),
|
ResourcePackMetaWriter(p, o, 34),
|
||||||
]),
|
]),
|
||||||
]).write()
|
]).write()
|
||||||
|
|||||||
@@ -92,9 +92,11 @@ def createReportRunner(tmp_path:Path, pack:ModPack):
|
|||||||
|
|
||||||
def test_writeModPack(tmp_path:Path, modPackRunner:Runner):
|
def test_writeModPack(tmp_path:Path, modPackRunner:Runner):
|
||||||
assert (tmp_path/"testpack"/"config"/"incontrol"/"spawner.json").exists()
|
assert (tmp_path/"testpack"/"config"/"incontrol"/"spawner.json").exists()
|
||||||
|
assert (tmp_path/"testpack"/"datapacks"/"testpack.jar").exists()
|
||||||
assert (tmp_path/"testpack"/"test.md").exists()
|
assert (tmp_path/"testpack"/"test.md").exists()
|
||||||
|
|
||||||
def test_writeReports(tmp_path:Path, reportRunner:Runner):
|
def test_writeReports(tmp_path:Path, reportRunner:Runner):
|
||||||
assert (tmp_path/"testpack"/"reports"/"biomes.txt").exists()
|
assert (tmp_path/"testpack"/"reports"/"biomes.txt").exists()
|
||||||
|
assert (tmp_path/"testpack"/"reports"/"deposits.txt").exists()
|
||||||
assert (tmp_path/"testpack"/"reports"/"minerals.txt").exists()
|
assert (tmp_path/"testpack"/"reports"/"minerals.txt").exists()
|
||||||
assert (tmp_path/"testpack"/"reports"/"mobspawns.txt").exists()
|
assert (tmp_path/"testpack"/"reports"/"mobspawns.txt").exists()
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from mcpacker.model.modpack import ModPack
|
from mcpacker.model.modpack import ModPack
|
||||||
|
from mcpacker.write.locator import Locator
|
||||||
from mcpacker.write.writer import Writer
|
from mcpacker.write.writer import Writer
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -12,13 +13,10 @@ class CompositeWriter(Writer):
|
|||||||
self,
|
self,
|
||||||
pack:ModPack,
|
pack:ModPack,
|
||||||
outputDir:Path,
|
outputDir:Path,
|
||||||
writers:Iterable[Writer]|None=None
|
writers:Iterable[Writer]|None=None,
|
||||||
):
|
):
|
||||||
super().__init__(pack, outputDir)
|
super().__init__(pack, outputDir)
|
||||||
|
self._writers:list[Writer] = list(writers or [])
|
||||||
self._writers:list[Writer] = []
|
|
||||||
for writer in (writers or []):
|
|
||||||
self._writers.append(writer)
|
|
||||||
|
|
||||||
def doWrite(self):
|
def doWrite(self):
|
||||||
for writer in self._writers:
|
for writer in self._writers:
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
from mcpacker.format.datapack.biomemodifier.removespawn import RemoveSpawnBiomeModifier
|
||||||
|
from mcpacker.write.writer import Writer
|
||||||
|
|
||||||
|
import mcpacker.json as json
|
||||||
|
|
||||||
|
|
||||||
|
# Class ############################################################################################
|
||||||
|
|
||||||
|
class DisableSpawnWriter(Writer):
|
||||||
|
"""
|
||||||
|
Writes files to disable vanilla spawns for mobs who are to be spawned using custom rules.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def doWrite(self):
|
||||||
|
entityTypes = [m.gameId for m in self.pack.world.mobs]
|
||||||
|
modifier = RemoveSpawnBiomeModifier("#c:is_overworld", entityTypes)
|
||||||
|
path = self.locator.biomeModifiers() / "remove_managed_mob_spawns.json"
|
||||||
|
self.resetOutputFile(path)
|
||||||
|
path.write_text(json.dumps(modifier.asJsonBlob(), indent=json.INDENT))
|
||||||
@@ -56,7 +56,7 @@ class Locator:
|
|||||||
return self.dataPackMod(modName, dataPackName) / "worldgen" / "configured_feature"
|
return self.dataPackMod(modName, dataPackName) / "worldgen" / "configured_feature"
|
||||||
|
|
||||||
def dataPack(self, dataPackName:str|None=None):
|
def dataPack(self, dataPackName:str|None=None):
|
||||||
return self.dataPacks() / (dataPackName or f"{self.pack.name}_override")
|
return self.dataPacks() / (dataPackName or f"{self.pack.name}")
|
||||||
|
|
||||||
def dataPackMod(self, modName:str|None=None, dataPackName:str|None=None):
|
def dataPackMod(self, modName:str|None=None, dataPackName:str|None=None):
|
||||||
return self.dataPack(dataPackName) / "data" / (modName or self.pack.name)
|
return self.dataPack(dataPackName) / "data" / (modName or self.pack.name)
|
||||||
@@ -83,7 +83,7 @@ class Locator:
|
|||||||
return self.dataPackMod(modName, dataPackName) / "recipes"
|
return self.dataPackMod(modName, dataPackName) / "recipes"
|
||||||
|
|
||||||
def resourcePack(self, resourcePackName:str|None=None) -> Path:
|
def resourcePack(self, resourcePackName:str|None=None) -> Path:
|
||||||
return self.resourcePacks() / (resourcePackName or f"{self.pack.name}_override")
|
return self.resourcePacks() / (resourcePackName or f"{self.pack.name}")
|
||||||
|
|
||||||
def resourcePackMod(self, modName:str|None=None, resourcePackName:str|None=None) -> Path:
|
def resourcePackMod(self, modName:str|None=None, resourcePackName:str|None=None) -> Path:
|
||||||
return self.resourcePack(resourcePackName) / "assets" / (modName or self.pack.name)
|
return self.resourcePack(resourcePackName) / "assets" / (modName or self.pack.name)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ def test_blockStates(locator:Locator):
|
|||||||
assert (
|
assert (
|
||||||
locator.blockStates() ==
|
locator.blockStates() ==
|
||||||
Path(
|
Path(
|
||||||
"output/testPack/resourcepacks/testPack_override/" +
|
"output/testPack/resourcepacks/testPack/" +
|
||||||
"assets/testPack/blockstates"
|
"assets/testPack/blockstates"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -26,7 +26,7 @@ def test_configuredFeatures(locator:Locator):
|
|||||||
assert (
|
assert (
|
||||||
locator.configuredFeatures() ==
|
locator.configuredFeatures() ==
|
||||||
Path(
|
Path(
|
||||||
"output/testPack/datapacks/testPack_override/" +
|
"output/testPack/datapacks/testPack/" +
|
||||||
"data/testPack/worldgen/configured_feature"
|
"data/testPack/worldgen/configured_feature"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -44,7 +44,7 @@ def test_configuredFeaturesSpecificMod(locator:Locator):
|
|||||||
assert (
|
assert (
|
||||||
locator.configuredFeatures("farmersdelight") ==
|
locator.configuredFeatures("farmersdelight") ==
|
||||||
Path(
|
Path(
|
||||||
"output/testPack/datapacks/testPack_override/" +
|
"output/testPack/datapacks/testPack/" +
|
||||||
"data/farmersdelight/worldgen/configured_feature"
|
"data/farmersdelight/worldgen/configured_feature"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class ReportWriter(Writer):
|
|||||||
pack:ModPack,
|
pack:ModPack,
|
||||||
composerClass:type[ReportComposer],
|
composerClass:type[ReportComposer],
|
||||||
outputDir:Path,
|
outputDir:Path,
|
||||||
name:str|Path
|
name:str|Path,
|
||||||
):
|
):
|
||||||
super().__init__(pack, outputDir)
|
super().__init__(pack, outputDir)
|
||||||
self.composerClass = composerClass
|
self.composerClass = composerClass
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import mcpacker.write.report.writer
|
||||||
|
|
||||||
|
|
||||||
|
# Tests ############################################################################################
|
||||||
|
|
||||||
|
def test_syntax():
|
||||||
|
pass
|
||||||
@@ -14,9 +14,6 @@ SOURCE_BASE = Path("mcpacker") / "pack"
|
|||||||
|
|
||||||
class StaticWriter(Writer):
|
class StaticWriter(Writer):
|
||||||
|
|
||||||
def __init__(self, pack:ModPack, outputDir:Path):
|
|
||||||
super().__init__(pack, outputDir)
|
|
||||||
|
|
||||||
def doWrite(self):
|
def doWrite(self):
|
||||||
sourcePath = SOURCE_BASE / self.pack.name / "static"
|
sourcePath = SOURCE_BASE / self.pack.name / "static"
|
||||||
targetPath = self.locator.root()
|
targetPath = self.locator.root()
|
||||||
|
|||||||
Reference in New Issue
Block a user