Skip to content

Commit

Permalink
Load newest game-data rather than hardcode version
Browse files Browse the repository at this point in the history
  • Loading branch information
mitaa committed Sep 17, 2024
1 parent 8487bda commit 0d75bf1
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 10 deletions.
17 changes: 11 additions & 6 deletions src/production_planner/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,11 @@ def __str__(self):
)

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

# TODO: reorganize files
from . import gamedata
# TODO: add selected game version to CONFIG
data_fpath = gamedata.get()

with open(data_fpath) as fp:
data = json.load(fp)
Expand Down Expand Up @@ -650,14 +654,15 @@ def node_constructor(loader, node):
else:
node.recipe = Recipe.empty("! " + data["recipe"])
else:
if data["recipe"] in prod.recipe_map:
node.recipe = prod.recipe_map[data["recipe"]]
recipe_name = data["recipe"].removeprefix("!").strip()
if recipe_name in prod.recipe_map:
node.recipe = prod.recipe_map[recipe_name]
else:
alternate = "Alternate: " + data["recipe"]
alternate = "Alternate: " + recipe_name
if alternate in prod.recipe_map:
node.recipe = prod.recipe_map["Alternate: " + data["recipe"]]
node.recipe = prod.recipe_map["Alternate: " + recipe_name]
else:
node.recipe = Recipe(f"! { data['recipe'] }", 60, [], [], False)
node.recipe = Recipe(f"! { recipe_name }", 60, [], [], False)
node.update()
return node

Expand Down
106 changes: 103 additions & 3 deletions src/production_planner/gamedata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,116 @@

from docopt import docopt

from production_planner.core import ProducerEncoder

import parse
from . import parse

import os
import re
import json
from pathlib import Path
from collections import OrderedDict
from dataclasses import dataclass
from typing import Optional, ClassVar


@dataclass
class GameDataFileVersion:
fpath: Path
major: int
minor: int
patch: int
postfix: int | str
build: int

file_versions: ClassVar = []

def __post_init__(self):
self.file_versions += [self]

def __index__(self, idx):
return GameDataFilter(self)[idx]


class GameDataFilter:
def __init__(self):
self._version_names = ["postfix", "patch", "minor", "major"]
self.version_sequence = []

def __getitem__(self, idx):
self.version_sequence = [(self._version_names.pop(), idx)]
return self

def get(self, pool=None, selected=None) -> [GameDataFileVersion]:
if selected is None:
selected = self.version_sequence[:]

if not selected:
return GameDataFileVersion.file_versions[:]

selected_one = selected[0]

if pool is None:
pool = GameDataFileVersion.file_versions

filtered_pool = []
for version in pool:
if getattr(version, selected_one[0]) == selected_one[1]:
filtered_pool += [version]
selected = selected[1:]
if selected:
filtered_pool = self.get(pool=filtered_pool, selected=selected)

return filtered_pool

def latest(self) -> GameDataFileVersion:
pool = self.get()
latest_seen = None

for version in pool:
if not latest_seen:
latest_seen = version
elif latest_seen.build < version.build:
latest_seen = version

return latest_seen

@classmethod
def get_build(self, build: int) -> Optional[GameDataFileVersion]:
for version in GameDataFileVersion.file_versions:
if version.build == build:
return version


def get(major=None, minor=None, patch=None, postfix=None, build=None) -> Path:
from production_planner.core import CONFIG

re_parse_fname = re.compile("production_buildings_v(?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.(?P<postfix>\d+)_(?P<build>\d+).json")

dpath = os.path.split(os.path.abspath(__file__))[0]
for entry in os.scandir(dpath):
match = re_parse_fname.match(entry.name)
if entry.is_file() and match:
GameDataFileVersion(entry.path,
int(match.group("major")),
int(match.group("minor")),
int(match.group("patch")),
int(match.group("postfix")),
int(match.group("build")))
if build:
version = GameDataFilter.get_build(build)
return Path(version.fpath)
else:
filt = GameDataFilter()
for v in [major, minor, patch, postfix]:
if v is None:
break
filt[v]
version = filt.latest()
return Path(version.fpath)


def main():
from production_planner.core import ProducerEncoder

arguments = docopt(__doc__)
production_buildings = OrderedDict()
data = parse.docs_json(Path(arguments['<docs.json-path>']))
Expand Down
2 changes: 1 addition & 1 deletion src/production_planner/gamedata/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# 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/.

from production_planner import core
from .. import core

import re
from typing import Optional, Self
Expand Down

0 comments on commit 0d75bf1

Please sign in to comment.