Add the ability to disable existing placed features

This commit is contained in:
Andrew Miner
2025-10-16 17:59:20 -06:00
parent 87b6362d12
commit 286ba774d6
19 changed files with 156 additions and 51 deletions
@@ -1,6 +1,15 @@
from mcpacker.json import JsonBlob
# Class ############################################################################################
class ConfiguredFeature:
def __init__(self, gameId:str):
self.gameId = gameId
def asJsonBlob(self) -> JsonBlob:
return {
"type": self.gameId,
"config": {},
}
@@ -1,4 +1,5 @@
from mcpacker.format.datapack.configuredfeature import ConfiguredFeature
from mcpacker.json import JsonBlob
from typing import Any
from typing import TYPE_CHECKING
@@ -13,7 +14,7 @@ class RandomPatch(ConfiguredFeature):
def __init__(
self,
gameId:str,
feature:PlacedFeature,
feature:"PlacedFeature",
tries:int=128,
xzSpread:int=7,
ySpread:int=3,
@@ -25,7 +26,7 @@ class RandomPatch(ConfiguredFeature):
self.xzSpread = xzSpread
self.ySpread = ySpread
def asData(self) -> dict[str,Any]:
def asJsonBlob(self) -> JsonBlob:
return {
"type": self.gameId,
"feature": self.feature.gameId,
@@ -1,6 +1,7 @@
from mcpacker.format.datapack.blockstate import BlockState
from mcpacker.format.datapack.placedfeature import PlacedFeature
from mcpacker.format.datapack.blockstateprovider.simplestateprovider import SimpleStateProvider
from mcpacker.format.datapack.configuredfeature.simpleblock import SimpleBlock
from mcpacker.format.datapack.configuredfeature.randompatch import RandomPatch
from pytest import fixture
@@ -14,25 +15,22 @@ def createBlockState():
def createProvider(state:BlockState):
return SimpleStateProvider(state)
@fixture(name="placedFeature")
def createPlacedFeature():
return PlacedFeature("noop", [])
@fixture(name="feature")
def createSimpleBlockFeature(provider:SimpleStateProvider):
return SimpleBlock(provider)
def createFeature(placedFeature:PlacedFeature):
return RandomPatch("test", placedFeature)
# Tests ############################################################################################
def test_asData(feature:SimpleBlock):
def test_asJsonBlob(feature:RandomPatch):
assert feature.asJsonBlob() == {
"type": "minecraft:simple_block",
"config": {
"to_place": {
"type": "minecraft:simple_state_provider",
"state": {
"Name": "minecraft:button",
"Properties": {
"waterlogged": "true"
}
}
}
}
"type": "minecraft:random_patch",
"feature": "noop",
"tries": 128,
"xz_spread": 7,
"y_spread": 3,
}
+9 -1
View File
@@ -1,10 +1,18 @@
from collections.abc import Iterable
from mcpacker.format.datapack.placement import Placement
from mcpacker.json import JsonBlob
# Class ############################################################################################
class PlacedFeature:
def __init__(self, gameId:str, placements:list[Placement]):
def __init__(self, gameId:str, placements:Iterable[Placement]):
self.gameId = gameId
self.placements = placements
def asJsonBlob(self) -> JsonBlob:
return {
"feature": self.gameId,
"placements": [p.asJsonBlob() for p in self.placements],
}
@@ -1,6 +1,14 @@
from mcpacker.json import JsonBlob
# Class ############################################################################################
class Placement:
def __init__(self, gameId:str):
self.gameId = gameId
def asJsonBlob(self) -> JsonBlob:
return {
"type": self.gameId,
}
@@ -7,7 +7,3 @@ class Biome(Placement):
def __init__(self):
super().__init__("minecraft:biome")
def asData(self) -> dict[str,Any]:
return { "type": self.gameId }
@@ -12,7 +12,7 @@ def createPlacement():
# Tests ############################################################################################
def test_asData(placement):
assert placement.asData() == {
assert placement.asJsonBlob() == {
"type": "minecraft:biome",
}
@@ -1,7 +1,9 @@
from mcpacker.format.datapack.heightmaptype import HeightMapType
from mcpacker.format.datapack.placement import Placement
from mcpacker.json import JsonBlob
from typing import Any
# Class ############################################################################################
class HeightMap(Placement):
@@ -10,7 +12,7 @@ class HeightMap(Placement):
super().__init__("minecraft:heightmap")
self.heightMap = heightMap
def asData(self) -> dict[str,Any]:
def asJsonBlob(self) -> JsonBlob:
return {
"type": self.gameId,
"heightmap": self.heightMap.asData()
@@ -13,7 +13,7 @@ def createPlacement():
# Tests ############################################################################################
def test_asData(placement):
assert placement.asData() == {
assert placement.asJsonBlob() == {
"type": "minecraft:heightmap",
"heightmap": "WORLD_SURFACE"
}
@@ -1,13 +1,10 @@
from mcpacker.format.datapack.placement import Placement
from typing import Any
# Class ############################################################################################
class InSquare(Placement):
def __init__(self):
super().__init__("minecraft:in_square")
def asData(self) -> dict[str,Any]:
return { "type": self.gameId }
@@ -12,7 +12,7 @@ def createPlacement():
# Tests ############################################################################################
def test_asData(placement):
assert placement.asData() == {
assert placement.asJsonBlob() == {
"type": "minecraft:in_square",
}
@@ -1,6 +1,8 @@
from mcpacker.format.datapack.placement import Placement
from mcpacker.json import JsonBlob
from typing import Any
# Class ############################################################################################
class RarityFilter(Placement):
@@ -9,9 +11,9 @@ class RarityFilter(Placement):
super().__init__("minecraft:rarity_filter")
self.chance = chance
def asData(self) -> dict[str,Any]:
def asJsonBlob(self) -> JsonBlob:
return {
"type": self.gameId,
"chance": self.chance
"chance": self.chance,
}
@@ -12,7 +12,7 @@ def createPlacement():
# Tests ############################################################################################
def test_asData(placement):
assert placement.asData() == {
assert placement.asJsonBlob() == {
"type": "minecraft:rarity_filter",
"chance": 4
}
+8 -7
View File
@@ -1,6 +1,7 @@
from collections.abc import Iterable
from mcpacker.model.core.world import World
from mcpacker.format.datapack import DataPack
from mcpacker.model.core.resourceid import ResourceId
from mcpacker.model.core.world import World
from mcpacker.model.mod import Mod
from mcpacker.model.resourcepack import ResourcePack
from typing import Callable
@@ -23,15 +24,15 @@ class ModPack:
world:World|None=None,
dataPack:DataPack|None=None,
resourcePack:ResourcePack|None=None,
disabledFeatures:Iterable[ResourceId]|None=None
):
self.name = name
self.world = world or World()
self.dataPack = dataPack or DataPack(self.name)
self.resourcePack = resourcePack or ResourcePack(self.name)
self._mods = {}
for mod in (mods or []):
self._mods[mod.name] = mod
self.dataPack = dataPack or DataPack(self.name)
self.mods = {mod.name: mod for mod in (mods or [])}
self.disabledFeatures = list(disabledFeatures or [])
self.resourcePack = resourcePack or ResourcePack(self.name)
self.world = world or World()
def augment(self, doAugment:AugmentFunc) -> Self:
doAugment(self)
@@ -0,0 +1,32 @@
from mcpacker.model.core.resourceid import ResourceId
from mcpacker.model.modpack import ModPack
# Helper Functions #################################################################################
def addDisabledFeatures(pack:ModPack):
d = pack.disabledFeatures
def add(resourceText:str):
pack.disabledFeatures.append(ResourceId.parse(resourceText))
# Disable Vanilla ore generation
add("minecraft:ore_coal_lower")
add("minecraft:ore_coal_upper")
add("minecraft:ore_copper_large")
add("minecraft:ore_copper")
add("minecraft:ore_diamond_buried")
add("minecraft:ore_diamond_large")
add("minecraft:ore_diamond_medium")
add("minecraft:ore_diamond")
add("minecraft:ore_emerald")
add("minecraft:ore_gold_deltas")
add("minecraft:ore_gold_extra")
add("minecraft:ore_gold_lower")
add("minecraft:ore_gold")
add("minecraft:ore_iron_middle")
add("minecraft:ore_iron_small")
add("minecraft:ore_iron_upper")
add("minecraft:ore_lapis_buried")
add("minecraft:ore_lapis")
add("minecraft:ore_redstone_lower")
add("minecraft:ore_redstone")
@@ -0,0 +1,7 @@
import mcpacker.pack.mysteriousisland.adddisabledfeatures
# Tests ############################################################################################
def test_syntax():
pass
@@ -3,6 +3,7 @@ from mcpacker.pack.mysteriousisland.addbiomes import addBiomes
from mcpacker.pack.mysteriousisland.addblocks import addBlocks
from mcpacker.pack.mysteriousisland.adddatapack import addDataPack
from mcpacker.pack.mysteriousisland.adddeposits import addDeposits
from mcpacker.pack.mysteriousisland.adddisabledfeatures import addDisabledFeatures
from mcpacker.pack.mysteriousisland.additems import addItems
from mcpacker.pack.mysteriousisland.addminerals import addMinerals
from mcpacker.pack.mysteriousisland.addmobs import addMobs
@@ -23,6 +24,7 @@ def buildModPack():
pack.augment(addDeposits)
pack.augment(addMobs)
pack.augment(addMobSpawns)
pack.augment(addDisabledFeatures)
pack.augment(addResourcePack)
pack.augment(addDataPack)
+2
View File
@@ -4,6 +4,7 @@ from mcpacker.format.report.mineralreport import MineralReport
from mcpacker.format.report.mobspawnreport import MobSpawnReport
from mcpacker.model.modpack import ModPack
from mcpacker.write.compositewriter import CompositeWriter
from mcpacker.write.datapack.disablefeaturewriter import DisableFeatureWriter
from mcpacker.write.datapack.disablespawnwriter import DisableSpawnWriter
from mcpacker.write.datapack.metawriter import DataPackMetaWriter
from mcpacker.write.datapack.writer import DataPackWriter
@@ -69,6 +70,7 @@ class Runner:
SpawnerWriter(p, o),
DataPackWriter(p, o, [
DataPackMetaWriter(p, o, 48),
DisableFeatureWriter(p, o),
DisableSpawnWriter(p, o),
]),
ResourcePackWriter(p, o, [
@@ -0,0 +1,40 @@
from mcpacker.format.datapack.biomemodifier.removefeature import RemoveFeatureBiomeModifier
from mcpacker.format.datapack.configuredfeature import ConfiguredFeature
from mcpacker.format.datapack.placedfeature import PlacedFeature
from mcpacker.write.writer import Writer
import mcpacker.json as json
# Class ############################################################################################
class DisableFeatureWriter(Writer):
def doWrite(self):
if not self.pack.disabledFeatures: return
self._writeRemoveFeaturesBiomeModifier()
self._writeNoopConfiguredFeature()
self._writeNoopPlacedFeatures()
# Private Methods ##########################################################
def _writeNoopConfiguredFeature(self):
feature = ConfiguredFeature("minecraft:no_op")
path = self.locator.configuredFeatures() / "noop.json"
self.resetOutputFile(path)
path.write_text(json.dumps(feature.asJsonBlob(), indent=json.INDENT))
def _writeNoopPlacedFeatures(self):
for placedFeature in self.pack.disabledFeatures:
path = self.locator.placedFeatures(placedFeature.mod) / f"{placedFeature.name}.json"
self.resetOutputFile(path)
feature = PlacedFeature(f"{self.pack.name}:noop", [])
path.write_text(json.dumps(feature.asJsonBlob(), indent=json.INDENT))
def _writeRemoveFeaturesBiomeModifier(self):
features = [str(f) for f in self.pack.disabledFeatures]
modifier = RemoveFeatureBiomeModifier("#c:is_overworld", features)
path = self.locator.biomeModifiers() / "remove_disabled_features.json"
self.resetOutputFile(path)
path.write_text(json.dumps(modifier.asJsobBlob(), indent=json.INDENT))