Skip to content

Commit

Permalink
Create recipes class
Browse files Browse the repository at this point in the history
  • Loading branch information
Gjum committed Jan 31, 2016
1 parent ac4799e commit 531375a
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 52 deletions.
95 changes: 48 additions & 47 deletions spockbot/mcdata/recipes.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,57 @@


RecipeItem = namedtuple('RecipeItem', 'id meta amount')
Recipe = namedtuple('Recipe', 'result ingredients in_shape out_shape')
# TODO make Recipe a class, make the helpers its methods


def to_recipe(raw):
def reformat_item(raw, default_meta=None):
if isinstance(raw, dict):
raw = raw.copy() # do not modify arg
if 'metadata' not in raw:
raw['metadata'] = default_meta
if 'count' not in raw:
raw['count'] = 1
return RecipeItem(raw['id'], raw['metadata'], raw['count'])
elif isinstance(raw, list):
return RecipeItem(raw[0], raw[1], 1)
else: # single ID or None
return RecipeItem(raw or None, default_meta, 1)
class Recipe(object):
def __init__(self, raw):
self.result = reformat_item(raw['result'], None)
if 'ingredients' in raw:
self.ingredients = [reformat_item(item, 0) for item in raw['ingredients']]
self.in_shape = None
self.out_shape = None
else:
self.in_shape = reformat_shape(raw['inShape'])
self.out_shape = reformat_shape(raw['outShape']) \
if 'outShape' in raw else None
self.ingredients = [item for row in self.in_shape for item in row] # flatten

def reformat_shape(shape):
return [[reformat_item(item, None) for item in row] for row in shape]
@property
def total_ingredient_amounts(self):
totals = defaultdict(int)
for id, meta, amount in self.ingredients:
totals[(id, meta)] += amount
return totals

result = reformat_item(raw['result'], None)
if 'ingredients' in raw:
ingredients = [reformat_item(item, 0) for item in raw['ingredients']]
in_shape = out_shape = None
else:
in_shape = reformat_shape(raw['inShape'])
out_shape = reformat_shape(raw['outShape']) \
if 'outShape' in raw else None
ingredients = [item for row in in_shape for item in row] # flatten
return Recipe(result, ingredients, in_shape, out_shape)
@property
def ingredient_positions(self):
"""
Returns:
dict: In the form { (item_id, metadata) -> [ (x, y, amount), ... ] }
"""
positions = defaultdict(list)
for y, row in enumerate(self.in_shape):
for x, (item_id, metadata, amount) in enumerate(row):
positions[(item_id, metadata)].append((x, y, amount))
return positions


def reformat_item(raw, default_meta=None):
if isinstance(raw, dict):
raw = raw.copy() # do not modify arg
if 'metadata' not in raw:
raw['metadata'] = default_meta
if 'count' not in raw:
raw['count'] = 1
return RecipeItem(raw['id'], raw['metadata'], raw['count'])
elif isinstance(raw, list):
return RecipeItem(raw[0], raw[1], 1)
else: # single ID or None
return RecipeItem(raw or None, default_meta, 1)


def reformat_shape(shape):
return [[reformat_item(item, None) for item in row] for row in shape]


def iter_recipes(item_id, meta=None):
Expand All @@ -46,7 +66,7 @@ def iter_recipes(item_id, meta=None):
return # no recipe found, do not yield anything
else:
for raw in recipes_for_item:
recipe = to_recipe(raw)
recipe = Recipe(raw)
if meta is None or meta == recipe.result.meta:
yield recipe

Expand All @@ -56,22 +76,3 @@ def get_any_recipe(item, meta=None):
for matching in iter_recipes(item, meta):
return matching
return None


def total_ingredient_amounts(recipe):
totals = defaultdict(int)
for id, meta, amount in recipe.ingredients:
totals[(id, meta)] += amount
return totals


def ingredient_positions(recipe):
"""
Returns:
dict: In the form { (item_id, metadata) -> [ (x, y, amount), ... ] }
"""
positions = defaultdict(list)
for y, row in enumerate(recipe.in_shape):
for x, (item_id, metadata, amount) in enumerate(row):
positions[(item_id, metadata)].append((x, y, amount))
return positions
9 changes: 4 additions & 5 deletions spockbot/plugins/helpers/craft.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
"""
from math import ceil

from spockbot.mcdata.recipes import get_any_recipe, ingredient_positions, \
total_ingredient_amounts
from spockbot.mcdata.recipes import get_any_recipe
from spockbot.plugins.base import PluginBase, pl_announce
from spockbot.plugins.tools.task import TaskFailed

Expand Down Expand Up @@ -67,7 +66,7 @@ def craft_task(self, recipe, amount=1):
storage_slots = inv.window.persistent_slots

# check ingredients for recipe
total_amounts_needed = total_ingredient_amounts(recipe)
total_amounts_needed = recipe.total_ingredient_amounts
for ingredient, needed in total_amounts_needed.items():
needed *= craft_times
stored = inv.total_stored(ingredient, storage_slots)
Expand All @@ -76,7 +75,7 @@ def craft_task(self, recipe, amount=1):
% ('%s:%s' % ingredient, stored, needed))

# put ingredients into crafting grid
for ingredient, p in ingredient_positions(recipe).items():
for ingredient, p in recipe.ingredient_positions.items():
for (x, y, ingredient_amount) in p:
slot = grid_slots[x + y * grid_width]
for i in range(ingredient_amount * craft_times):
Expand All @@ -101,7 +100,7 @@ def craft_task(self, recipe, amount=1):
while amount > crafted_amt + inv.cursor_slot.amount:
yield inv.async.click_slot(result_slot)
# TODO check that cursor is non-empty, otherwise we did not craft
result_stack_size = inv.cursor_slot.stack_size
result_stack_size = inv.cursor_slot.item.stack_size
if inv.cursor_slot.amount in (prev_cursor_amt, result_stack_size):
# cursor full, put away
crafted_amt += inv.cursor_slot.amount
Expand Down

0 comments on commit 531375a

Please sign in to comment.