93 lines
2.8 KiB
CoffeeScript
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
|