Skip to content

Commit

Permalink
Update Recipes and Producers to 1.0 game-data
Browse files Browse the repository at this point in the history
  • Loading branch information
mitaa committed Sep 17, 2024
1 parent 715ec8d commit cf6bfee
Show file tree
Hide file tree
Showing 7 changed files with 7,235 additions and 5 deletions.
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
include src/production_planner/*.json
include src/production_planner/gamedata/*.json
include src/production_planner/*.tcss
include src/production_planner/cells/*.tcss
58 changes: 55 additions & 3 deletions src/production_planner/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import json
from pathlib import Path
from typing import Self, Optional
from collections import OrderedDict

import textual
from textual import log
Expand Down Expand Up @@ -198,17 +199,21 @@ def __str__(self):
def __hash__(self):
return hash((self.name, self.count))

def to_json_schema(self):
return [self.count, self.name]


class Recipe(yaml.YAMLObject):
yaml_tag = u"!recipe"

recipe_to_producer_map = {}

def __init__(self, name, cycle_rate, inputs: [(int, str)], outputs: [(int, str)]):
def __init__(self, name, cycle_rate, inputs: [(int, str)], outputs: [(int, str)], is_alternate=False):
self.name = name
self.cycle_rate = cycle_rate
self.inputs = list(Ingredient(name, count) for count, name in inputs)
self.outputs = list(Ingredient(name, count) for count, name in outputs)
self.is_alternate = is_alternate

def __str__(self):
return f"{self.name}/{self.cycle_rate} {', '.join(map(str, self.inputs))} <> {', '.join(map(str, self.outputs))}"
Expand Down Expand Up @@ -244,6 +249,11 @@ def from_dict(cls, ingredients: {str: int}, name="", cycle_rate=60) -> Self:
outputs += [(quantity, ingredient)]
return cls(name, cycle_rate, inputs, outputs)

def to_json_schema(self):
return {
self.name: [self.cycle_rate, [inp.to_json_schema() for inp in self.inputs], [out.to_json_schema() for out in self.outputs], self.is_alternate]
}


class Producer:
def __init__(self, name, *, is_miner, is_pow_gen, max_mk, base_power, recipes, description, abstract=False):
Expand Down Expand Up @@ -278,11 +288,35 @@ def __str__(self):
else:
return self.name

def __repr__(self):
return f"<Producer: {self.name}, recipes: {self.recipes}>"

@property
def is_module(self):
return False


class ProducerEncoder(json.JSONEncoder):
def default(self, producer):
if isinstance(producer, Producer):
recipes = OrderedDict()
for recipe in producer.recipes:
recipes.update(recipe.to_json_schema())

return {
producer.name: {
"description": producer.description,
"is_miner": producer.is_miner,
"is_pow_gen": producer.is_pow_gen,
"max_mk": producer.max_mk,
"base_power": producer.base_power,
"recipes": recipes,
}
}
# Let the base class default method raise the TypeError
return super().default(producer)


class _ModuleProducer(Producer):
module_index = {}

Expand Down Expand Up @@ -432,7 +466,8 @@ def __str__(self):
)

PRODUCERS = [MODULE_PRODUCER]
data_fpath = os.path.join(os.path.split(os.path.abspath(__file__))[0], "production_buildings.json")
data_fpath = os.path.join(os.path.split(os.path.abspath(__file__))[0], "gamedata/production_buildings_v1.0.0.1_366202.json")

with open(data_fpath) as fp:
data = json.load(fp)

Expand Down Expand Up @@ -470,9 +505,22 @@ def all_recipes_producer():
return prod


PRODUCER_ALIASES = {
"Coal Generator": ["Coal-Powered Generator"],
"Fuel Generator": ["Fuel-Powered Generator"],
"Coal-Powered Generator": ["Coal Generator"],
"Fuel-Powered Generator": ["Fuel Generator"],
}


PRODUCER_MAP = {p.name: p for p in ([all_recipes_producer] + PRODUCERS)}
PRODUCER_MAP["Blueprint"] = PRODUCER_MAP["Module"]

for name, aliases in PRODUCER_ALIASES.items():
if name in PRODUCER_MAP:
for alias in aliases:
PRODUCER_MAP[alias] = PRODUCER_MAP[name]


class Node:
yaml_tag = "!Node"
Expand Down Expand Up @@ -602,7 +650,11 @@ def node_constructor(loader, node):
else:
node.recipe = Recipe.empty("! " + data["recipe"])
else:
node.recipe = prod.recipe_map[data["recipe"]]
if data["recipe"] in prod.recipe_map:
node.recipe = prod.recipe_map[data["recipe"]]
else:
node.recipe = prod.recipe_map["Alternate: " + data["recipe"]]
# TODO: do not fail on unrecognized recipe
node.update()
return node

Expand Down
39 changes: 39 additions & 0 deletions src/production_planner/gamedata/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# -*- coding:utf-8 -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

"""__init__.py
Usage:
__init__.py <docs.json-path>
__init__.py (-h | --help)
Options:
-h --help Show this screen.
"""

from docopt import docopt

from production_planner.core import ProducerEncoder

import parse

import json
from pathlib import Path
from collections import OrderedDict


def main():
arguments = docopt(__doc__)
production_buildings = OrderedDict()
data = parse.docs_json(Path(arguments['<docs.json-path>']))
if data:
for prod in data:
p = json.dumps(prod, cls=ProducerEncoder, indent=2)
production_buildings.update(json.loads(p))
print(json.dumps(production_buildings, cls=ProducerEncoder, indent=2))


if __name__ == "__main__":
main()
Loading

0 comments on commit cf6bfee

Please sign in to comment.