Files
website/src/client/models/crafting/plan_builder.coffee
T

93 lines
2.8 KiB
CoffeeScript

#
# Crafting Guide - plan_builder.coffee
#
# Copyright © 2014-2016 by Redwood Labs
# All rights reserved.
#
CraftingPlan = require "./crafting_plan"
CraftingPlanStep = require "./crafting_plan_step"
########################################################################################################################
module.exports = class PlanBuilder
constructor: (evaluator)->
@evaluator = evaluator
# Properties ###################################################################################
Object.defineProperties @prototype,
evaluator:
get: -> return @_evaluator
set: (evaluator)->
if not evaluator? then throw new Error "evaluator is required"
if @_evaluator is evaluator then return
if @_evaluator? then throw new Error "evaluator cannot be reassigned"
@_evaluator = evaluator
# Public Methods ###############################################################################
createPlan: (want, have)->
@_alreadyMaking = {}
@_recipesInUse = {}
stepList = []
for itemId, stack of want.stacks
steps = @_findStepsForItem stack.item, stack.quantity
return null unless steps?
stepList.push steps
plan = new CraftingPlan want:want, have:have, steps:_.flatten(stepList)
return plan
# Private Methods ##############################################################################
_findStepsForItem: (item, quantity=1)->
steps = null
if not @_alreadyMaking[item.id]
@_alreadyMaking[item.id] = true
recipes = @_evaluator.getOrderedRecipes item, quantity
if recipes.length is 0
steps = []
else
for recipe in recipes
continue if @_recipesInUse[recipe.id]?
steps = @_findStepsForRecipe recipe, quantity
break if steps?
delete @_alreadyMaking[item.id]
return steps
_findStepsForRecipe: (recipe, quantity=1)->
steps = null
if not @_recipesInUse[recipe.id]
@_recipesInUse[recipe.id] = true
invalidRecipe = false
for itemId, item of recipe.inputs
inputSteps = @_findStepsForItem item, quantity * recipe.computeQuantityRequired(item)
if not inputSteps?
invalidRecipe = true
break
steps ?= []
for step in inputSteps
steps.push step
if invalidRecipe
steps = null
else
steps.push new CraftingPlanStep recipe
delete @_recipesInUse[recipe.id]
return steps