Set up ability to run commands from the terminal

This commit is contained in:
Andrew Miner
2025-10-06 20:57:46 -06:00
parent a8b6e6b15e
commit 4637137152
18 changed files with 231 additions and 49 deletions
+2 -2
View File
@@ -59,8 +59,8 @@ class Biome(object):
"}"
]])
def traits(self) -> set[BiomeTrait]:
return set([
def traits(self) -> list[BiomeTrait]:
return list([
self.flora,
self.geology,
self.heat,
+1 -1
View File
@@ -17,7 +17,7 @@ class BiomeTrait:
return hash((type(self).__name__, self.name))
def __str__(self):
return self.name
return f"{type(self).__name__}: {self.name}"
def __repr__(self) -> str:
return f"{type(self).__name__}<{self.name}>"
+1 -1
View File
@@ -52,7 +52,7 @@ def test_repr(green):
assert repr(green) == "BiomeTrait<green>"
def test_str(green):
assert str(green) == "green"
assert str(green) == "BiomeTrait: green"
def test_within(traitList, green, yellow, orange):
assert biomeTrait.within(traitList, green, orange) == [green, yellow, orange]
@@ -0,0 +1,22 @@
from tungston.core.world import World
from tungston.generator.markdown.report import Report
# Class ############################################################################################
class BiomeReport(Report):
def __init__(self, world:World):
super().__init__("biomes.md", world)
def build(self):
for biome in self.world.biomes.all():
self.line(f"# Biome: {biome.city} <{biome.gameId}>")
self.line()
self.indent()
for trait in biome.traits():
self.text("* ").line(trait)
self.outdent()
self.line()
@@ -0,0 +1,61 @@
from pytest import fixture
from tungston.core.ecology.biome import Biome
from tungston.core.ecology.biomecatalog import BiomeCatalog
from tungston.core.world import World
from tungston.generator.markdown.biomereport import BiomeReport
import tungston.core.ecology.flora as F
import tungston.core.ecology.geology as G
import tungston.core.ecology.heat as E
import tungston.core.ecology.humidity as U
import tungston.core.ecology.soil as S
import tungston.core.ecology.water as W
import textwrap
# Fixtures #########################################################################################
@fixture(name="biomes")
def createCatalog():
yield BiomeCatalog([
Biome("dallas", "minecraft:savanna",
F.FIELD, G.SEDIMENTARY, E.SUBTROPICAL, U.DRY, S.SANDY, W.INLAND
),
Biome("kansascity", "minecraft:plains",
F.FIELD, G.SEDIMENTARY, E.TEMPERATE, U.DAMP, S.LOAMY, W.INLAND
),
])
@fixture(name="world")
def createWorld(biomes):
yield World(biomes, None, None, None)
@fixture(name="report")
def createReport(world):
report = BiomeReport(world)
report.build()
yield report
# Tests ############################################################################################
def test_report(report):
assert str(report) == textwrap.dedent("""
# Biome: dallas <minecraft:savanna>
* Flora: field
* Geology: sedimentary
* Heat: subtropical
* Humidity: dry
* Soil: sandy
* Water: inland
# Biome: kansascity <minecraft:plains>
* Flora: field
* Geology: sedimentary
* Heat: temperate
* Humidity: damp
* Soil: loamy
* Water: inland
""").strip()
+4 -1
View File
@@ -6,6 +6,9 @@ from tungston.generator.markdown.report import Report
class MineralReport(Report):
def __init__(self, world:World):
super().__init__("minerals.md", world)
def build(self):
for mineral in self.world.minerals.all():
self.line(f"# Mineral: {mineral.name}")
@@ -13,7 +16,7 @@ class MineralReport(Report):
self.indent()
for replacement in mineral.replacements:
self.line(str(replacement))
self.text("* ").line(str(replacement))
self.outdent()
self.line()
@@ -45,11 +45,11 @@ def test_report(report):
assert str(report) == textwrap.dedent("""
# Mineral: copper
#minecraft:stone_replaceables => minecraft:copper_ore
#minecraft:deepslate_replaceables => minecraft:deepslate_copper_ore
* #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
* #minecraft:stone_replaceables => minecraft:iron_ore
* #minecraft:deepslate_replaceables => minecraft:deepslate_iron_ore
""").strip()
+3 -2
View File
@@ -4,13 +4,14 @@ from tungston.core.world import World
# Constants ########################################################################################
INDENT = " "
INDENT = " "
# Class ############################################################################################
class Report:
def __init__(self, world:World):
def __init__(self, name:str, world:World):
self.name = name
self.world = world
self.reset()
+2 -6
View File
@@ -4,14 +4,10 @@ from tungston.generator.markdown.report import Report
# Fixtures #########################################################################################
@fixture(name="emptyReport")
def createEmptyReport():
return Report()
@fixture(name="report")
def createReport():
return (
Report(None)
Report("test", None)
.text("alpha")
.line("bravo")
.indent()
@@ -28,4 +24,4 @@ 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"
assert str(report) == "alphabravo\n charlie\n delta\n echo"
@@ -0,0 +1,24 @@
from tungston.generator.markdown.report import Report
import shutil
import os
# Class ############################################################################################
class ReportWriter:
def __init__(self, reports:list[Report]):
self._reports = reports
def write(self, reportDirPath:str):
if os.path.exists(reportDirPath):
shutil.rmtree(reportDirPath)
os.makedirs(reportDirPath, exist_ok=True)
for report in self._reports:
report.build()
path = os.path.join(reportDirPath, report.name)
with open(path, "w") as file:
file.write(str(report))
+28
View File
@@ -0,0 +1,28 @@
from tungston.core.world import World
import inspect
import sys
# Class ############################################################################################
class Runner:
def __init__(self, world:World):
self.world = world
def abort(self, message:str, status:int=-1):
print(message)
sys.exit(status)
def run(self, argv:list[str]):
if len(sys.argv) < 2:
abort("Please provide a command name")
commandName = "_command_" + argv[1]
for name, doCommand in inspect.getmembers(self):
if name == commandName:
doCommand(*argv[2:])
sys.exit(0)
abort("No command named: " + argv[1])
+7
View File
@@ -0,0 +1,7 @@
from tungston.interface.runner import Runner
# Tests ############################################################################################
def test_syntax():
pass
@@ -1,7 +1,7 @@
from tungston.core.ecology.biomefilter import BiomeFilter as BF
from tungston.core.geology.depositcatalog import DepositCatalog
from tungston.core.geology.deposit.inclusion import Inclusion as I
from tungston.core.geology.deposit.metaldeposit import MetalDeposit
from tungston.core.geology.depositcatalog import DepositCatalog
from tungston.core.geology.inclusion import Inclusion as I
from tungston.modpack.mysteriousisland.mineralcatalog import CATALOG as M
import tungston.core.altitude as AL
@@ -16,13 +16,13 @@ import tungston.core.scarcity as SC
# Catalog ##########################################################################################
CATALOG = C = DepositCatalog(minerals)
CATALOG = C = DepositCatalog()
C.add(MetalDeposit(
name = "bif_iron",
biomeFilter = BF([GE.METAMORPHIC, (HE.BOREAL, HE.FROZEN), HU.DAMP]),
scarcity = SC.COMMON,
minerals = [I(M.get("iron"), 50), I(M.get("quartz"), 45), I(M.get("uranium"), 5)],
biomeFilter = BF([GE.METAMORPHIC, (HE.BOREAL, HE.FROZEN), HU.DAMP]),
inclusions = [I(M.get("iron"), 50), I(M.get("quartz"), 45), I(M.get("uranium"), 5)],
bulk = BU.LARGE,
proportion = 0.2,
))
@@ -16,27 +16,27 @@ def makeMineral(name:str, blockId:str, deepslateBlockId:None|str=None) -> Minera
deepslateBlockId = deepslateBlockId if deepslateBlockId else blockId
return Mineral(name, [
R.inStone(blockId),
R.inDeepslate(blockId)
Replacement.inStone(blockId),
Replacement.inDeepslate(blockId)
])
def makeOreMineral(name:str) -> Mineral:
return Mineral(name, [
R.inStone(f"{name}_ore"),
R.inDeepslate(f"deepslate_{name}_ore")
Replacement.inStone(f"{name}_ore"),
Replacement.inDeepslate(f"deepslate_{name}_ore")
])
def makeImmersiveEngineeringOreMineral(name:str) -> Mineral:
return Mineral(name, [
R.inStone(f"{IE}:ore_{name}"),
R.inDeepslate("{IE}:deepslate_ore_{name}")
]),
Replacement.inStone(f"{IE}:ore_{name}"),
Replacement.inDeepslate("{IE}:deepslate_ore_{name}")
])
def makeRailcraftOreMineral(name:str) -> Mineral:
return Mineral(name, [
R.inStone(f"{RC}:{name}_ore"),
R.inDeepslate("{RC}:deepslate_{name}_ore")
]),
Replacement.inStone(f"{RC}:{name}_ore"),
Replacement.inDeepslate("{RC}:deepslate_{name}_ore")
])
# Catalog ##########################################################################################
@@ -56,7 +56,7 @@ C.add(makeOreMineral("redstone"))
# Crystals
C.add(makeMineral("amethyst", "amethyst_block"))
C.add(makeMineral("glowstone", "glowstone"))
C.add(makeMineral("quartz", f"{OQ}:quartz_ore") f"{OQ}:deepslate_quartz_ore")
C.add(makeMineral("quartz", f"{OQ}:quartz_ore", f"{OQ}:deepslate_quartz_ore"))
C.add(makeMineral("salt", "butcher:saltblock"))
# Earth, gravel, etc.
+17 -16
View File
@@ -1,9 +1,9 @@
from tungston.core.ecology.biomefilter import BiomeFilter as BF
from tungston.core.habitat import Habitat
from tungston.core.fauna.mob import Mob
from tungston.core.fauna.mobplacement import MobPlacement
from tungston.core.fauna.mobcatalog import MobCatalog
from tungston.core.fauna.mobplacement import MobPlacement
import tungston.core.active as AC
import tungston.core.altitude as AL
import tungston.core.ecology.flora as FL
import tungston.core.ecology.geology as GE
@@ -11,6 +11,7 @@ import tungston.core.ecology.heat as HE
import tungston.core.ecology.humidity as HU
import tungston.core.ecology.soil as SO
import tungston.core.ecology.water as WA
import tungston.core.fauna.active as AC
import tungston.core.fauna.group as GR
import tungston.core.fauna.location as LO
import tungston.core.scarcity as SC
@@ -22,17 +23,17 @@ import tungston.core.season as SE
CATALOG = MobCatalog([
MobPlacement(Mob("armadillo", "minecraft:armadillo", AC.NOCTURNAL),
Habitat(
altitude = AL.LOWLANDS,
altitudes = 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,
altitudes = AL.UPLANDS, scarcity = SC.SPARSE,
).derive(
altitude = AL.LOWLANDS, SE.excluding(SE.SUMMER), scarcity = SC.UNCOMMON,
altitudes = AL.LOWLANDS, seasons = SE.excluding(SE.SUMMER), scarcity = SC.UNCOMMON,
).derive(
altitude = AL.UPLANDS, scarcity = SC.UNUSUAL,
altitudes = AL.UPLANDS, scarcity = SC.UNUSUAL,
)
),
MobPlacement(Mob("black_bear", "bearminimum:black_bear"),
@@ -47,7 +48,7 @@ CATALOG = MobCatalog([
).derive(
seasons = SE.WINTER, scarcity = SC.UNUSUAL
).derive(
biomeFilter = BF([HE.BOREAL, (HE.CANOPY, HE.FOREST)]),
biomeFilter = BF([HE.BOREAL, (FL.CANOPY, FL.FOREST)]),
seasons = SE.AUTUMN,
scarcity = SC.SPARSE
).derive(
@@ -65,7 +66,7 @@ CATALOG = MobCatalog([
)
),
MobPlacement(Mob("bogged", "minecraft:bogged")),
MobPlacement(Mob("brown_bear", "bearminimum:brown_bear")
MobPlacement(Mob("brown_bear", "bearminimum:brown_bear"),
Habitat(
altitudes = AL.span(AL.LOWLANDS, AL.ALPINE),
biomeFilter = BF([HE.BOREAL, (FL.CANOPY, FL.FOREST)]),
@@ -93,7 +94,7 @@ CATALOG = MobCatalog([
MobPlacement(Mob("cat", "minecraft:cat")),
MobPlacement(Mob("cave_spider", "minecraft:cave_spider"),
Habitat(
altitudes = AL.SPAN(AL.OVERBURDEN, AL.HILLS),
altitudes = AL.span(AL.OVERBURDEN, AL.HILLS),
location = LO.CAVE,
group = GR.SOLO,
scarcity = SC.UNCOMMON
@@ -102,27 +103,27 @@ CATALOG = MobCatalog([
MobPlacement(Mob("chameleon", "cold_sweat:chameleon"),
Habitat(
altitudes = AL.span(AL.DUNES, AL.UPLANDS),
biomeFilters = BF([HE.TROPICAL, HU.WET, [FL.CANOPY, FL.FOREST]]),
biomeFilter = BF([HE.TROPICAL, HU.WET, [FL.CANOPY, FL.FOREST]]),
seasons = SE.WET,
groups = GR.merge(GR.SOLO, GR.FAMILY),
group = GR.merge(GR.SOLO, GR.FAMILY),
scarcity = SC.COMMON,
).derive(
seasons = SE.DRY, scarcity = SC.UNCOMMON,
).derive(
biomeFilters = BF([HE.TROPICAL, HU.WET, FL.CLEARING]),
biomeFilter = BF([HE.TROPICAL, HU.WET, FL.CLEARING]),
seasons = SE.WET,
scarcity = SC.UNCOMMON
).derive(
seasons = SE.DRY, scarcity = SC.SPARSE,
)
),
MobPlacement(Mob("chicken", "minecraft:chicken")
MobPlacement(Mob("chicken", "minecraft:chicken"),
Habitat(
altitudes = AL.span(AL.LOWLANDS, AL.UPLANDS),
biomeFilters = BF([HE.TROPICAL, HU.WET, FL.within(FL.CANOPY, FL.CLEARING)]),
biomeFilter = BF([HE.TROPICAL, HU.WET, FL.within(FL.CANOPY, FL.CLEARING)]),
seasons = SE.SUMMER,
groups = GR.TROUP,
scarcity.COMMON,
group = GR.TROUP,
scarcity = SC.COMMON,
).derive(
seasons = SE.excluding(SE.SUMMER), scarcity = SC.UNCOMMON
)
@@ -0,0 +1,35 @@
from tungston.interface.runner import Runner as BaseRunner
from tungston.core.world import World
from tungston.modpack.mysteriousisland.biomecatalog import CATALOG as biomes
from tungston.modpack.mysteriousisland.depositcatalog import CATALOG as deposits
from tungston.modpack.mysteriousisland.mineralcatalog import CATALOG as minerals
from tungston.modpack.mysteriousisland.mobcatalog import CATALOG as mobs
from tungston.generator.markdown.reportwriter import ReportWriter
from tungston.generator.markdown.biomereport import BiomeReport
from tungston.generator.markdown.mineralreport import MineralReport
import sys
# Constants ########################################################################################
REPORT_PATH = "./output/markdown/mysteriousisland"
# Class ############################################################################################
class Runner(BaseRunner):
def _command_writeReports(self):
writer = ReportWriter([
BiomeReport(self.world),
MineralReport(self.world)
])
writer.write(REPORT_PATH)
# Script ###########################################################################################
if __name__ == "__main__":
Runner(World(biomes, deposits, minerals, mobs)).run(sys.argv)