Files
website/src/client/models/crafting/crafting_plan.coffee
T
Andrew Miner 93c98e16ac Further fixes of how passthrough items are handled
* When evaluating a plan, only give the pass-through treatment to
  items if the step they're part of was actually executed
* When marking a step "complete", ignore passthrough items
2016-04-16 20:33:05 -07:00

179 lines
5.4 KiB
CoffeeScript

#
# Crafting Guide - crafting_plan.coffee
#
# Copyright © 2014-2016 by Redwood Labs
# All rights reserved.
#
SimpleInventory = require './simple_inventory'
########################################################################################################################
module.exports = class CraftingPlan
constructor: (modPack, want, have, steps)->
if not modPack? then throw new Error 'modPack is required'
if not want? then throw new Error 'want is required'
if not have? then throw new Error 'have is required'
if not steps? then throw new Error 'steps is required'
@_have = have
@_made = null
@_modPack = modPack
@_need = null
@_rawScores = {}
@_scores = {}
@_steps = steps
@_tools = null
@_want = want
@_numberSteps()
# Public Methods ###############################################################################
computeRequired: ->
@_need = new SimpleInventory modPack:@_modPack
@_need.addInventory @_want
@_made = new SimpleInventory modPack:@_modPack
@_made.addInventory @_have
@_tools = new SimpleInventory modPack:@_modPack
for i in [@_steps.length-1..0] by -1
step = @_steps[i]
step.multiplier = 0
recipe = step.recipe
for stack in step.recipe.output
continue if recipe.isPassThroughFor stack.itemSlug
qualifiedSlug = @_modPack.qualifySlug stack.itemSlug
while @_need.quantityOf(qualifiedSlug) > 0
@_executeStep step
if step.multiplier > 0
for stack in step.recipe.output
qualifiedSlug = @_modPack.qualifySlug stack.itemSlug
continue unless recipe.isPassThroughFor stack.itemSlug
continue if @_made.hasAtLeast qualifiedSlug, 1
continue if @_need.hasAtLeast qualifiedSlug, 1
continue if @_tools.hasAtLeast qualifiedSlug, 1
@_need.add qualifiedSlug, 1
@_tools.add qualifiedSlug, 1
@_made.addInventory @_want
@_made.addInventory @_tools
@_pruneEmptySteps()
@_numberSteps()
hasRawScore: (name)->
return @_rawScores[name]?
getRawScore: (name)->
return @_rawScores[name]
setRawScore: (name, rawScore)->
@_rawScores[name] = rawScore
hasScore: (name)->
return @_scores[name]?
getScore: (name)->
return @_scores[name]
setScore: (name, score)->
@_scores[name] = score
# Property Methods #############################################################################
Object.defineProperties @prototype,
have:
get: -> @_have
length:
get: -> @steps.length
made:
get: -> @_made
need:
get: -> @_need
steps:
get: -> @_steps
want:
get: -> @_want
# Object Overrides #############################################################################
toString: ->
result = ["To Make:"]
@_want.each (stack)->
result.push " #{stack}"
result.push "When you already have:"
@_have.each (stack)->
result.push " #{stack}"
result.push "Start with:"
if @_need?
@_need.each (stack)->
result.push " #{stack}"
result.push "Use these recipes:"
for step in @_steps
result.push " #{step}"
result.push "To produce:"
if @_made?
@_made.each (stack)->
result.push " #{stack}"
if _.keys(@_rawScores).length > 0
result.push "Scores:"
for criteria, score of @_rawScores
if @_scores[criteria]?
result.push " #{criteria}: #{score} (#{@_scores[criteria]})"
else
result.push " #{criteria}: #{score}"
return result.join '\n'
# Private Methods ##############################################################################
_executeStep: (step)->
step.multiplier += 1
recipe = step.recipe
for stack in recipe.input
qualifiedSlug = @_modPack.qualifySlug stack.itemSlug
available = @_made.quantityOf qualifiedSlug
required = recipe.getQuantityRequired stack.itemSlug
consumed = Math.min required, available
deficit = required - consumed
@_made.remove qualifiedSlug, consumed
@_need.add qualifiedSlug, deficit
for stack in recipe.output
qualifiedSlug = @_modPack.qualifySlug stack.itemSlug
deficit = @_need.quantityOf qualifiedSlug
created = recipe.getQuantityProduced stack.itemSlug
replenished = Math.min deficit, created
surplus = created - replenished
@_made.add qualifiedSlug, surplus
@_need.remove qualifiedSlug, replenished
_numberSteps: ->
for step, i in @_steps
step.number = i + 1
_pruneEmptySteps: ->
index = 0
while index < @_steps.length
step = @_steps[index]
if step.multiplier is 0
@_steps.splice index, 1
else
index++