Checkpoint initial implementation
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
import os
|
||||
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class Datapack:
|
||||
|
||||
def __init__(self, path:str):
|
||||
self.path = path
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return os.path.basename(self.path)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
from typing import Any
|
||||
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class BlockState:
|
||||
|
||||
def __init__(self, blockId:str, properties:dict[str,str]=None):
|
||||
self.blockId = blockId
|
||||
self.properties = properties
|
||||
|
||||
def asData(self) -> dict[str,Any]:
|
||||
result = { "Name": self.blockId }
|
||||
|
||||
if self.properties:
|
||||
result["Properties"] = self.properties
|
||||
|
||||
return result
|
||||
@@ -0,0 +1,20 @@
|
||||
from pytest import fixture
|
||||
from tungston.generator.datapack.blockstate import BlockState
|
||||
|
||||
|
||||
# Fixtures #########################################################################################
|
||||
|
||||
@fixture(name="state")
|
||||
def createBlockState():
|
||||
yield BlockState("minecraft:button", {"waterlogged": "true"})
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_asData(state):
|
||||
assert state.asData() == {
|
||||
"Name": "minecraft:button",
|
||||
"Properties": {
|
||||
"waterlogged": "true"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# Class ############################################################################################
|
||||
|
||||
class BlockStateProvider:
|
||||
|
||||
def __init__(self, gameId:str):
|
||||
self.gameId = gameId
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
from tungston.generator.datapack.blockstate import BlockState
|
||||
from tungston.generator.datapack.blockstateprovider import BlockStateProvider
|
||||
from typing import Any
|
||||
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class SimpleStateProvider(BlockStateProvider):
|
||||
|
||||
def __init__(self, state:BlockState):
|
||||
super().__init__("minecraft:simple_state_provider")
|
||||
self.state = state
|
||||
|
||||
def asData(self) -> dict[str, Any]:
|
||||
return {
|
||||
"type": self.gameId,
|
||||
"state": self.state.asData(),
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
from tungston.generator.datapack.blockstate import BlockState
|
||||
from tungston.generator.datapack.blockstateprovider.simplestateprovider import SimpleStateProvider
|
||||
from pytest import fixture
|
||||
|
||||
|
||||
# Fixtures #########################################################################################
|
||||
|
||||
@fixture(name="state")
|
||||
def createBlockState():
|
||||
yield BlockState("minecraft:button", {"waterlogged": "true"})
|
||||
|
||||
@fixture(name="provider")
|
||||
def createProvider(state):
|
||||
return SimpleStateProvider(state)
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_asData(provider):
|
||||
assert provider.asData() == {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:button",
|
||||
"Properties": {
|
||||
"waterlogged": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
# Class ############################################################################################
|
||||
|
||||
class ConfiguredFeature:
|
||||
|
||||
def __init__(self, gameId:str):
|
||||
self.gameId = gameId
|
||||
@@ -0,0 +1,31 @@
|
||||
from tungston.generator.datapack.configuredfeature.configuredfeature import ConfiguredFeature
|
||||
from typing import Any
|
||||
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class RandomPatch(ConfiguredFeature):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
gameId:str,
|
||||
feature:"PlacedFeature",
|
||||
tries:int=128,
|
||||
xzSpread:int=7,
|
||||
ySpread:int=3,
|
||||
):
|
||||
super().__init__("minecraft:random_patch")
|
||||
|
||||
self.feature = feature
|
||||
self.tries = tries
|
||||
self.xzSpread = xzSpread
|
||||
self.ySpread = ySpread
|
||||
|
||||
def asData(self) -> dict[str,Any]:
|
||||
return {
|
||||
"type": self.type,
|
||||
"feature": self.feature.gameId,
|
||||
"tries": self.tries,
|
||||
"xz_spread": self.xySpread,
|
||||
"y_spread": self.ySpread
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
from pytest import fixture
|
||||
from tungston.generator.datapack.blockstate import BlockState
|
||||
from tungston.generator.datapack.blockstateprovider.simplestateprovider import SimpleStateProvider
|
||||
from tungston.generator.datapack.configuredfeature.simpleblock import SimpleBlock
|
||||
|
||||
|
||||
# Fixtures #########################################################################################
|
||||
|
||||
@fixture(name="state")
|
||||
def createBlockState():
|
||||
yield BlockState("minecraft:button", {"waterlogged": "true"})
|
||||
|
||||
@fixture(name="provider")
|
||||
def createProvider(state):
|
||||
return SimpleStateProvider(state)
|
||||
|
||||
@fixture(name="feature")
|
||||
def createSimpleBlockFeature(provider):
|
||||
return SimpleBlock(provider)
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_asData(feature):
|
||||
assert feature.asData() == {
|
||||
"type": "minecraft:simple_block",
|
||||
"config": {
|
||||
"to_place": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:button",
|
||||
"Properties": {
|
||||
"waterlogged": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
from tungston.generator.datapack.blockstateprovider import BlockStateProvider
|
||||
from tungston.generator.datapack.configuredfeature import ConfiguredFeature
|
||||
from typing import Any
|
||||
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class SimpleBlock(ConfiguredFeature):
|
||||
|
||||
def __init__(self, toPlace:BlockStateProvider):
|
||||
super().__init__("minecraft:simple_block")
|
||||
self.toPlace = toPlace
|
||||
|
||||
def asData(self) -> dict[str, Any]:
|
||||
return {
|
||||
"type": self.gameId,
|
||||
"config": {
|
||||
"to_place": self.toPlace.asData()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
from pytest import fixture
|
||||
from tungston.generator.datapack.blockstate import BlockState
|
||||
from tungston.generator.datapack.blockstateprovider.simplestateprovider import SimpleStateProvider
|
||||
from tungston.generator.datapack.configuredfeature.simpleblock import SimpleBlock
|
||||
|
||||
|
||||
# Fixtures #########################################################################################
|
||||
|
||||
@fixture(name="state")
|
||||
def createBlockState():
|
||||
yield BlockState("minecraft:button", {"waterlogged": "true"})
|
||||
|
||||
@fixture(name="provider")
|
||||
def createProvider(state):
|
||||
return SimpleStateProvider(state)
|
||||
|
||||
@fixture(name="feature")
|
||||
def createSimpleBlockFeature(provider):
|
||||
return SimpleBlock(provider)
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_asData(feature):
|
||||
assert feature.asData() == {
|
||||
"type": "minecraft:simple_block",
|
||||
"config": {
|
||||
"to_place": {
|
||||
"type": "minecraft:simple_state_provider",
|
||||
"state": {
|
||||
"Name": "minecraft:button",
|
||||
"Properties": {
|
||||
"waterlogged": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
# Class ############################################################################################
|
||||
|
||||
class HeightMapType:
|
||||
"""
|
||||
A cached record of the top block at all points in the world.
|
||||
|
||||
see: https://minecraft.wiki/w/Heightmap
|
||||
"""
|
||||
|
||||
def __init__(self, gameId:str):
|
||||
self.gameId = gameId
|
||||
|
||||
def asData(self) -> str:
|
||||
return self.gameId
|
||||
|
||||
|
||||
# Constants ########################################################################################
|
||||
|
||||
MOTION_BLOCKING = HeightMapType("MOTION_BLOCKING")
|
||||
MOTION_BLOCKING_NO_LEAVES = HeightMapType("MOTION_BLOCKING_NO_LEAVES")
|
||||
OCEAN_FLOOR = HeightMapType("OCEAN_FLOOR")
|
||||
OCEAN_FLOOR_WG = HeightMapType("OCEAN_FLOOR_WG")
|
||||
WORLD_SURFACE = HeightMapType("WORLD_SURFACE")
|
||||
WORLD_SURFACE_WG = HeightMapType("WORLD_SURFACE_WG")
|
||||
@@ -0,0 +1,7 @@
|
||||
from tungston.generator.datapack.heightmaptype import HeightMapType
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_syntax():
|
||||
pass
|
||||
@@ -0,0 +1,6 @@
|
||||
# Class ############################################################################################
|
||||
|
||||
class PlacedFeature:
|
||||
|
||||
def __init__(self, gameId:str):
|
||||
self.gameId = gameId
|
||||
@@ -0,0 +1,6 @@
|
||||
from tungston.generator.datapack.placedfeature import PlacedFeature
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_syntax():
|
||||
pass
|
||||
@@ -0,0 +1,6 @@
|
||||
# Class ############################################################################################
|
||||
|
||||
class Placement:
|
||||
|
||||
def __init__(self, gameId:str):
|
||||
self.gameId = gameId
|
||||
@@ -0,0 +1,13 @@
|
||||
from tungston.generator.datapack.placement import Placement
|
||||
from typing import Any
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class Biome(Placement):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__("minecraft:biome")
|
||||
|
||||
def asData(self) -> dict[str,Any]:
|
||||
return { "type": self.gameId }
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
from pytest import fixture
|
||||
from tungston.generator.datapack.placement.biome import Biome
|
||||
|
||||
|
||||
# Fixtures #########################################################################################
|
||||
|
||||
@fixture(name="placement")
|
||||
def createPlacement():
|
||||
yield Biome()
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_asData(placement):
|
||||
assert placement.asData() == {
|
||||
"type": "minecraft:biome",
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
from tungston.generator.datapack.placement import Placement
|
||||
from tungston.generator.datapack.heightmaptype import HeightMapType
|
||||
from typing import Any
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class HeightMap(Placement):
|
||||
|
||||
def __init__(self, heightMap:HeightMapType):
|
||||
super().__init__("minecraft:heightmap")
|
||||
self.heightMap = heightMap
|
||||
|
||||
def asData(self) -> dict[str,Any]:
|
||||
return {
|
||||
"type": self.gameId,
|
||||
"heightmap": self.heightMap.asData()
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
from pytest import fixture
|
||||
from tungston.generator.datapack.placement.heightmap import HeightMap
|
||||
from tungston.generator.datapack.heightmaptype import WORLD_SURFACE
|
||||
|
||||
|
||||
# Fixtures #########################################################################################
|
||||
|
||||
@fixture(name="placement")
|
||||
def createPlacement():
|
||||
yield HeightMap(WORLD_SURFACE)
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_asData(placement):
|
||||
assert placement.asData() == {
|
||||
"type": "minecraft:heightmap",
|
||||
"heightmap": "WORLD_SURFACE"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
from tungston.generator.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 }
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
from pytest import fixture
|
||||
from tungston.generator.datapack.placement.insquare import InSquare
|
||||
|
||||
|
||||
# Fixtures #########################################################################################
|
||||
|
||||
@fixture(name="placement")
|
||||
def createPlacement():
|
||||
yield InSquare()
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_asData(placement):
|
||||
assert placement.asData() == {
|
||||
"type": "minecraft:in_square",
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
from tungston.generator.datapack.placement import Placement
|
||||
from typing import Any
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class RarityFilter(Placement):
|
||||
|
||||
def __init__(self, chance:int):
|
||||
super().__init__("minecraft:rarity_filter")
|
||||
self.chance = chance
|
||||
|
||||
def asData(self) -> dict[str,Any]:
|
||||
return {
|
||||
"type": self.gameId,
|
||||
"chance": self.chance
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
from pytest import fixture
|
||||
from tungston.generator.datapack.placement.rarityfilter import RarityFilter
|
||||
|
||||
|
||||
# Fixtures #########################################################################################
|
||||
|
||||
@fixture(name="placement")
|
||||
def createPlacement():
|
||||
yield RarityFilter(4)
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_asData(placement):
|
||||
assert placement.asData() == {
|
||||
"type": "minecraft:rarity_filter",
|
||||
"chance": 4
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
from tungston.core.world import World
|
||||
from tungston.generator.markdown.report import Report
|
||||
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class MineralReport(Report):
|
||||
|
||||
def build(self):
|
||||
for mineral in self.world.minerals.all():
|
||||
self.line(f"# Mineral: {mineral.name}")
|
||||
self.line()
|
||||
|
||||
self.indent()
|
||||
for replacement in mineral.replacements:
|
||||
self.line(str(replacement))
|
||||
self.outdent()
|
||||
|
||||
self.line()
|
||||
@@ -0,0 +1,55 @@
|
||||
from pytest import fixture
|
||||
from tungston.core.geology.mineral import Mineral
|
||||
from tungston.core.geology.mineralcatalog import MineralCatalog
|
||||
from tungston.core.geology.replacement import Replacement
|
||||
from tungston.core.world import World
|
||||
from tungston.generator.markdown.mineralreport import MineralReport
|
||||
|
||||
import textwrap
|
||||
|
||||
|
||||
# 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="minerals")
|
||||
def createMineralCatalog(copper, iron):
|
||||
yield MineralCatalog([copper, iron])
|
||||
|
||||
@fixture(name="world")
|
||||
def createWorld(minerals):
|
||||
yield World(None, None, minerals, None)
|
||||
|
||||
@fixture(name="report")
|
||||
def createReport(world):
|
||||
report = MineralReport(world)
|
||||
report.build()
|
||||
yield report
|
||||
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_report(report):
|
||||
assert str(report) == textwrap.dedent("""
|
||||
# Mineral: copper
|
||||
|
||||
#minecraft:stone_replaceables => minecraft:copper_ore
|
||||
#minecraft:deepslate_replaceables => minecraft:deepslate_copper_ore
|
||||
|
||||
# Mineral: iron
|
||||
|
||||
#minecraft:stone_replaceables => minecraft:iron_ore
|
||||
#minecraft:deepslate_replaceables => minecraft:deepslate_iron_ore
|
||||
""").strip()
|
||||
@@ -0,0 +1,70 @@
|
||||
from collections.abc import Iterator
|
||||
from tungston.core.world import World
|
||||
|
||||
|
||||
# Constants ########################################################################################
|
||||
|
||||
INDENT = " "
|
||||
|
||||
# Class ############################################################################################
|
||||
|
||||
class Report:
|
||||
|
||||
def __init__(self, world:World):
|
||||
self.world = world
|
||||
self.reset()
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "\n".join(self._lines).strip()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return (
|
||||
"Report{" +
|
||||
f"lines: {len(self._lines)} lines, " +
|
||||
f"lineBuffer: {len(self._lineBuffer)} chunks, " +
|
||||
f"indent: {self._indent}" +
|
||||
"}"
|
||||
)
|
||||
|
||||
def build(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def reset(self) -> "Report":
|
||||
self._lineBuffer = []
|
||||
self._lines = []
|
||||
self._indent = 0
|
||||
return self
|
||||
|
||||
def asLines(self) -> Iterator[str]:
|
||||
for line in self._lines:
|
||||
yield line
|
||||
|
||||
# Helper Methods ###########################################################
|
||||
|
||||
def indent(self) -> "Report":
|
||||
self._indent += 1
|
||||
self._lineBuffer.insert(0, INDENT)
|
||||
return self
|
||||
|
||||
def line(self, text:str="") -> "Report":
|
||||
self.text(text)
|
||||
|
||||
self._lines.append("".join(self._lineBuffer))
|
||||
self._lineBuffer = []
|
||||
while len(self._lineBuffer) < self._indent:
|
||||
self._lineBuffer.append(INDENT)
|
||||
|
||||
return self
|
||||
|
||||
def outdent(self) -> "Report":
|
||||
self._indent = max(0, self._indent - 1)
|
||||
|
||||
if self._lineBuffer:
|
||||
if self._lineBuffer[0] == INDENT:
|
||||
self._lineBuffer.pop()
|
||||
|
||||
return self
|
||||
|
||||
def text(self, text:str) -> "Report":
|
||||
self._lineBuffer.append(str(text))
|
||||
return self
|
||||
@@ -0,0 +1,31 @@
|
||||
from pytest import fixture
|
||||
from tungston.generator.markdown.report import Report
|
||||
|
||||
|
||||
# Fixtures #########################################################################################
|
||||
|
||||
@fixture(name="emptyReport")
|
||||
def createEmptyReport():
|
||||
return Report()
|
||||
|
||||
@fixture(name="report")
|
||||
def createReport():
|
||||
return (
|
||||
Report(None)
|
||||
.text("alpha")
|
||||
.line("bravo")
|
||||
.indent()
|
||||
.line("charlie")
|
||||
.indent()
|
||||
.line("delta")
|
||||
.outdent()
|
||||
.line("echo")
|
||||
)
|
||||
|
||||
# Tests ############################################################################################
|
||||
|
||||
def test_repr(report):
|
||||
assert repr(report) == "Report{lines: 4 lines, lineBuffer: 1 chunks, indent: 1}"
|
||||
|
||||
def test_str(report):
|
||||
assert str(report) == "alphabravo\n charlie\n delta\n echo"
|
||||
Reference in New Issue
Block a user