Fix bugs with new crafting algo

This commit is contained in:
Andrew Miner
2015-11-10 20:08:03 -08:00
parent 4e95ab998f
commit ff398b4a2f
23 changed files with 255 additions and 78 deletions
+2 -2
View File
@@ -95,8 +95,8 @@ GitHub.file.itemDescription.fileName = _.template "item.cg"
GitHub.file.itemDescription.path = _.template "/data/<%= modSlug %>/items/<%= itemSlug %>" GitHub.file.itemDescription.path = _.template "/data/<%= modSlug %>/items/<%= itemSlug %>"
exports.Limits = Limits = {} exports.Limits = Limits = {}
Limits.maximumGraphSize = 10000 Limits.maximumGraphSize = 5000
Limits.maximumPlanCount = 10000 Limits.maximumPlanCount = 5000
exports.Login = Login = {} exports.Login = Login = {}
Login.authorizeUrl = _.template "https://github.com/login/oauth/authorize" + Login.authorizeUrl = _.template "https://github.com/login/oauth/authorize" +
@@ -5,13 +5,14 @@ Copyright (c) 2014-2015 by Redwood Labs
All rights reserved. All rights reserved.
### ###
_ = require 'underscore'
AdsenseController = require './adsense_controller' AdsenseController = require './adsense_controller'
CraftPage = require '../models/craft_page' CraftPage = require '../models/craft_page'
CraftsmanWorkingController = require './craftsman_working_controller'
{Event} = require '../constants'
InventoryController = require './inventory_controller' InventoryController = require './inventory_controller'
PageController = require './page_controller' PageController = require './page_controller'
StepController = require './step_controller' StepController = require './step_controller'
_ = require 'underscore'
{Event} = require '../constants'
{Text} = require '../constants' {Text} = require '../constants'
{Url} = require '../constants' {Url} = require '../constants'
@@ -32,15 +33,13 @@ module.exports = class CraftPageController extends PageController
@modPack = options.modPack @modPack = options.modPack
@storage = options.storage @storage = options.storage
@model.craftsman.on Event.change, => @tryRefresh()
# Event Methods ################################################################################ # Event Methods ################################################################################
onHaveInventoryChanged: -> onHaveInventoryChanged: ->
@storage.store 'crafting-plan:have', @model.craftsman.have.unparse() @storage.store 'crafting-plan:have', @model.craftsman.have.unparse()
onMoveNeedToHave: (itemSlug)-> onMoveNeedToHave: (itemSlug)->
quantity = @model.craftsman.need.quantityOf itemSlug quantity = @needInventoryController.model.quantityOf itemSlug
@model.craftsman.have.add itemSlug, quantity @model.craftsman.have.add itemSlug, quantity
@onHaveInventoryChanged() @onHaveInventoryChanged()
@@ -106,12 +105,16 @@ module.exports = class CraftPageController extends PageController
firstButtonType: 'up' firstButtonType: 'up'
@needInventoryController.on Event.button.first, (c, s)=> @onMoveNeedToHave(s) @needInventoryController.on Event.button.first, (c, s)=> @onMoveNeedToHave(s)
@workingSectionController = @addChild CraftsmanWorkingController, '.view__craftsman_working',
model: @model.craftsman
@$instructionsSection = @$('.instructions.section') @$instructionsSection = @$('.instructions.section')
@$makeSection = @$('.make.section') @$makeSection = @$('.make.section')
@$toolsSection = @$('.tools.section') @$toolsSection = @$('.tools.section')
@$ingredientsSection = @$('.ingredients.section') @$ingredientsSection = @$('.ingredients.section')
@$stepsSection = @$('.steps.section') @$stepsSection = @$('.steps.section')
@$stepsContainer = @$('.steps.section .panel') @$stepsContainer = @$('.steps.section .panel')
@$workingSection = @$('.view__craftsman_working')
super super
@@ -139,14 +142,23 @@ module.exports = class CraftPageController extends PageController
return not @model.craftsman.want.hasAtLeast controller.model.outputItemSlug return not @model.craftsman.want.hasAtLeast controller.model.outputItemSlug
_refreshSectionVisibility: -> _refreshSectionVisibility: ->
return unless @_rendered
if @model.craftsman.want.isEmpty if @model.craftsman.want.isEmpty
for $el in [@$toolsSection, @$ingredientsSection, @$stepsSection] for $el in [@$toolsSection, @$ingredientsSection, @$stepsSection]
@hide $el @hide $el
@show @$instructionsSection @show @$instructionsSection
@hide @$workingSection
else if not @model.craftsman.complete
for $el in [@$toolsSection, @$ingredientsSection, @$stepsSection]
@hide $el
@hide @$instructionsSection
@show @$workingSection
else else
for $el in [@$toolsSection, @$ingredientsSection, @$stepsSection] for $el in [@$toolsSection, @$ingredientsSection, @$stepsSection]
@show $el @show $el
@hide @$instructionsSection @hide @$instructionsSection
@hide @$workingSection
_refreshSteps: -> _refreshSteps: ->
steps = @model.craftsman.plan?.steps or [] steps = @model.craftsman.plan?.steps or []
@@ -0,0 +1,54 @@
###
Crafting Guide - crafting_grid_controller.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
BaseController = require './base_controller'
Craftsman = require '../models/crafting/craftsman'
{Event} = require '../constants'
########################################################################################################################
module.exports = class CraftsmanWorkingController extends BaseController
constructor: (options={})->
if not options.model then throw new Error 'options.model is required'
options.templateName = 'craftsman_working'
super options
@model.on Event.change, => @_refreshStatusText()
# BaseController Methods #######################################################################
onDidRender: ->
@$message = @$('.message p')
@$count = @$('.count p')
super
refresh: ->
@_refreshStatusText()
super
# Private Methods ##############################################################################
_refreshStatusText: ->
return unless @$message? and @$count?
switch @model.stage
when Craftsman::STAGE.WAITING
@$message.html 'Preparing crafting calculation...'
@$count.html ''
when Craftsman::STAGE.GRAPHING
@$message.html 'Researching recipes...'
@$count.html "Found #{@model.stageCount} recipes so far..."
when Craftsman::STAGE.PLANNING
@$message.html 'Figuring out possible crafting plans...'
@$count.html "Found #{@model.stageCount} possibilities so far..."
when Craftsman::STAGE.ANALYZING
@$message.html 'Looking for the best plan...'
@$count.html "Finished checking #{@model.stageCount} so far..."
when Craftsman::STAGE.COMPLETE
@$message.html 'All done!'
@$count.html ''
@@ -72,7 +72,7 @@ module.exports = class FullRecipeController extends BaseController
if @model? if @model?
for stack in @model.input for stack in @model.input
inputs.add stack.itemSlug, stack.quantity inputs.add stack.itemSlug, @model.getQuantityRequired stack.itemSlug
_refreshOutputs: -> _refreshOutputs: ->
@@ -81,7 +81,7 @@ module.exports = class FullRecipeController extends BaseController
if @model? if @model?
for stack in @model.output for stack in @model.output
outputs.add stack.itemSlug, stack.quantity outputs.add stack.itemSlug, @model.getQuantityProduced stack.itemSlug
_refreshTools: -> _refreshTools: ->
@$toolContainer.empty() @$toolContainer.empty()
+2 -1
View File
@@ -23,7 +23,8 @@ module.exports = class CraftPage extends BaseModel
@modPack.on Event.change, => @_consumeParams() @modPack.on Event.change, => @_consumeParams()
@on Event.change + ':params', => @_consumeParams() @on Event.change + ':params', => @_consumeParams()
@craftsman.on Event.change, => @trigger Event.change, this @craftsman.on Event.change + ':stage', => @trigger Event.change, this
@craftsman.on Event.change + ':complete', => @trigger Event.change, this
# Private Methods ############################################################################## # Private Methods ##############################################################################
@@ -12,11 +12,13 @@ SimpleInventory = require '../simple_inventory'
module.exports = class CraftingPlan module.exports = class CraftingPlan
constructor: (steps, want, modPack)-> constructor: (modPack, want, have, steps)->
if not modPack? then throw new Error 'modPack is required' if not modPack? then throw new Error 'modPack is required'
if not steps? then throw new Error 'steps is required'
if not want? then throw new Error 'want 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 @_made = null
@_modPack = modPack @_modPack = modPack
@_need = null @_need = null
@@ -31,9 +33,11 @@ module.exports = class CraftingPlan
computeRequired: -> computeRequired: ->
@_need = new SimpleInventory modPack:@_modPack @_need = new SimpleInventory modPack:@_modPack
@_made = new SimpleInventory modPack:@_modPack
@_need.addInventory @_want @_need.addInventory @_want
@_made = new SimpleInventory modPack:@_modPack
@_made.addInventory @_have
for i in [@_steps.length-1..0] by -1 for i in [@_steps.length-1..0] by -1
step = @_steps[i] step = @_steps[i]
step.multiplier = 0 step.multiplier = 0
@@ -47,6 +51,8 @@ module.exports = class CraftingPlan
@_executeStep step @_executeStep step
@_made.addInventory @_want @_made.addInventory @_want
@_pruneEmptySteps()
@_numberSteps()
hasRawScore: (name)-> hasRawScore: (name)->
return @_rawScores[name]? return @_rawScores[name]?
@@ -69,6 +75,8 @@ module.exports = class CraftingPlan
# Property Methods ############################################################################# # Property Methods #############################################################################
Object.defineProperties @prototype, Object.defineProperties @prototype,
have:
get: -> @_have
length: length:
get: -> @steps.length get: -> @steps.length
made: made:
@@ -87,6 +95,10 @@ module.exports = class CraftingPlan
@_want.each (stack)-> @_want.each (stack)->
result.push " #{stack}" result.push " #{stack}"
result.push "When you already have:"
@_have.each (stack)->
result.push " #{stack}"
result.push "Start with:" result.push "Start with:"
@_need.each (stack)-> @_need.each (stack)->
result.push " #{stack}" result.push " #{stack}"
@@ -140,3 +152,12 @@ module.exports = class CraftingPlan
_numberSteps: -> _numberSteps: ->
for step, i in @_steps for step, i in @_steps
step.number = i + 1 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++
+17 -18
View File
@@ -18,11 +18,11 @@ w = require 'when'
module.exports = class Craftsman extends BaseModel module.exports = class Craftsman extends BaseModel
@::ANALYZE_STEP_INCREMENT = 100 @::ANALYZE_STEP_INCREMENT = 29
@::GRAPH_STEP_INCREMENT = 10 @::GRAPH_STEP_INCREMENT = 59
@::PLAN_STEP_INCREMENT = 50 @::PLAN_STEP_INCREMENT = 39
@::STAGE = @::STAGE =
WAITING: 'waiting' WAITING: 'waiting'
@@ -43,32 +43,29 @@ module.exports = class Craftsman extends BaseModel
reset = _.throttle (=> @reset()), 100 reset = _.throttle (=> @reset()), 100
@_have = new Inventory @_have = new Inventory modPack:@_modPack
@_have.on Event.change, reset @_have.on Event.change, reset
@_want = new Inventory @_want = new Inventory modPack:@_modPack
@_want.on Event.change, reset @_want.on Event.change, reset
@on Event.change + ':paused', reset @on Event.change + ':paused', reset
@on Event.change + ':stage', => logger.info "Craftsman has started #{@stage}..." @on Event.change + ':stage', => logger.info "Craftsman has started #{@stage}..."
@on 'scheduleNextWork', => @_scheduleNextWork()
@reset() @reset()
# Public Methods ############################################################################### # Public Methods ###############################################################################
work: -> work: ->
return if @_want.isEmpty return if @_want.isEmpty
logger.verbose => "stage: #{@stage}(#{@stageCount}) working..."
if not @_graphBuilder? if not @_graphBuilder?
want = new Inventory {modPack:@_modPack}, clone:@_want @_want.localize()
want.localize() @_have.localize()
have = new Inventory {modPack:@_modPack}, clone:@_have logger.info -> "Craftsman starting to build #{@_want} from #{@_have}"
have.localize()
logger.info -> "Craftsman starting to build #{want} from #{have}" @_graphBuilder = new GraphBuilder modPack:@_modPack, want:@_want, have:@_have
@_graphBuilder = new GraphBuilder modPack:@_modPack, want:want, have:have
@stage = @STAGE.GRAPHING @stage = @STAGE.GRAPHING
@stageCount = 0 @stageCount = 0
else if not @_graphBuilder.complete else if not @_graphBuilder.complete
@@ -77,7 +74,7 @@ module.exports = class Craftsman extends BaseModel
else if not @_planBuilder? else if not @_planBuilder?
logger.debug => "Craftsman finished computing graph:\n#{@_graphBuilder.rootNode}" logger.debug => "Craftsman finished computing graph:\n#{@_graphBuilder.rootNode}"
@_planBuilder = new PlanBuilder @_graphBuilder.rootNode, @_modPack, want:@_graphBuilder.want @_planBuilder = new PlanBuilder @_graphBuilder.rootNode, @_modPack, have:@_have, want:@_want
@stage = @STAGE.PLANNING @stage = @STAGE.PLANNING
@stageCount = 0 @stageCount = 0
else if not @_planBuilder.complete else if not @_planBuilder.complete
@@ -96,11 +93,13 @@ module.exports = class Craftsman extends BaseModel
@_planEvaluator.findBestPlan PlanEvaluator::CRITERIA.LEAST_MATERIALS @_planEvaluator.findBestPlan PlanEvaluator::CRITERIA.LEAST_MATERIALS
] ]
@_plans[0].computeRequired() @_plans[0].computeRequired()
logger.info => "Craftsman has finished with plans: #{(p.toString() for p in @_plans).join('\n')}" @stage = @STAGE.COMPLETE
@trigger Event.change + ':complete', this @stageCount = 0
@trigger Event.change, this
@_scheduleNextWork() logger.info => "Craftsman has finished with plans: #{(p.toString() for p in @_plans).join('\n')}"
@trigger Event.change, this
@trigger 'scheduleNextWork'
return @complete return @complete
reset: -> reset: ->
@@ -28,7 +28,7 @@ module.exports = class InventoryNode extends CraftingNode
@inventory.each (stack)=> @inventory.each (stack)=>
item = @modPack.findItem stack.itemSlug item = @modPack.findItem stack.itemSlug
if not item? then throw new Error "Could not find an item for slug: #{stack.itemSlug}" if not item? then throw new Error "Could not find an item for slug: #{stack.itemSlug}"
result.push new ItemNode modPack:@modPack, item:item result.push new ItemNode modPack:@modPack, item:item, ignoreGatherable:true
return result return result
_checkCompleteness: -> _checkCompleteness: ->
+7 -3
View File
@@ -17,21 +17,25 @@ module.exports = class ItemNode extends CraftingNode
@::TYPE = CraftingNode::TYPES.ITEM @::TYPE = CraftingNode::TYPES.ITEM
constructor: (options={})-> constructor: (options={})->
if not options.item? if not options.item? then throw new Error 'options.item is required'
throw new Error 'options.item is required'
super options super options
@item = options.item @item = options.item
@_ignoreGatherable = options.ignoreGatherable ?= false
@_recipes = null @_recipes = null
# Property Methods ############################################################################# # Property Methods #############################################################################
getRecipes: -> getRecipes: ->
if not @_recipes? if not @_recipes?
@_recipes = @modPack.findRecipes @item.slug @_recipes = @modPack.findRecipes @item.slug, forCrafting:true, onlyPrimary:true
if not @_recipes
@_recipes = @modPack.findRecipes @item.slug, forCrafting:true
return @_recipes or [] return @_recipes or []
isGatherable: -> isGatherable: ->
if not @_ignoreGatherable
return true if @item.isGatherable return true if @item.isGatherable
return true if @getRecipes().length is 0 return true if @getRecipes().length is 0
return false return false
@@ -17,8 +17,10 @@ module.exports = class PlanBuilder
constructor: (rootNode, modPack, options={})-> constructor: (rootNode, modPack, options={})->
if not rootNode? then throw new Error 'rootNode is required' if not rootNode? then throw new Error 'rootNode is required'
if not modPack? then throw new Error 'modPack is required'
@want = options.want @want = options.want
@have = options.have
@_choiceNodes = [] @_choiceNodes = []
@_complete = false @_complete = false
@@ -53,6 +55,10 @@ module.exports = class PlanBuilder
complete: complete:
get: -> @_complete get: -> @_complete
have:
get: -> @_have
set: (have)-> @_have = have or new Inventory
maxPlanCount: maxPlanCount:
get: -> @_maxPlanCount get: -> @_maxPlanCount
set: (value)-> @_maxPlanCount = value set: (value)-> @_maxPlanCount = value
@@ -95,7 +101,7 @@ module.exports = class PlanBuilder
seenRecipes[recipeSlug] = true seenRecipes[recipeSlug] = true
steps.push new CraftingStep node.recipe, @_modPack steps.push new CraftingStep node.recipe, @_modPack
plan = new CraftingPlan steps, @_want, @_modPack plan = new CraftingPlan @_modPack, @_want, @_have, steps
return plan return plan
_incrementChoiceNodes: -> _incrementChoiceNodes: ->
@@ -6,7 +6,9 @@ All rights reserved.
### ###
CraftingNode = require './crafting_node' CraftingNode = require './crafting_node'
Item = require '../item'
# ItemNode = require './item_node' # don't include here, causes a cycle # ItemNode = require './item_node' # don't include here, causes a cycle
ItemSlug = require '../item_slug'
######################################################################################################################## ########################################################################################################################
@@ -29,6 +31,9 @@ module.exports = class RecipeNode extends CraftingNode
for stack in @recipe.input for stack in @recipe.input
item = @modPack.findItem stack.itemSlug item = @modPack.findItem stack.itemSlug
if not item?
name = @modPack.findName stack.itemSlug
item = new Item name:name, slug:stack.itemSlug, gatherable:true
result.push new ItemNode modPack:@modPack, item:item result.push new ItemNode modPack:@modPack, item:item
return result return result
@@ -39,6 +44,7 @@ module.exports = class RecipeNode extends CraftingNode
_checkValidity: -> _checkValidity: ->
return false if @_isRepeatedRecipe() return false if @_isRepeatedRecipe()
return false if @_requiresToolBeingMade()
for child in @children for child in @children
return false unless child.valid return false unless child.valid
@@ -55,6 +61,18 @@ module.exports = class RecipeNode extends CraftingNode
return false return false
_requiresToolBeingMade: ->
for toolStack in @recipe.tools
toolSlug = toolStack.itemSlug
nextParent = @parent
while nextParent?
if ItemSlug.equal toolSlug, nextParent.item?.slug
return true
nextParent = nextParent.parent
return false
# Object Overrides ############################################################################ # Object Overrides ############################################################################
toString: (options={})-> toString: (options={})->
+3
View File
@@ -35,6 +35,8 @@ module.exports = class ItemSlug
return 0 return 0
@equal: (a, b)-> @equal: (a, b)->
return true if not a? and not b?
return false unless a? and b?
return false unless a.mod is b.mod return false unless a.mod is b.mod
return false unless a.item is b.item return false unless a.item is b.item
return true return true
@@ -56,6 +58,7 @@ module.exports = class ItemSlug
return ItemSlug.compare this, that return ItemSlug.compare this, that
matches: (slug, options={exact:false})-> matches: (slug, options={exact:false})->
return false unless slug?
return false unless typeof(slug.matches) is 'function' return false unless typeof(slug.matches) is 'function'
if slug.isQualified and this.isQualified if slug.isQualified and this.isQualified
+2
View File
@@ -139,6 +139,7 @@ module.exports = class ModVersion extends BaseModel
findRecipes: (itemSlug, result=[], options={})-> findRecipes: (itemSlug, result=[], options={})->
options.onlyPrimary ?= false options.onlyPrimary ?= false
options.forCrafting ?= false
primaryRecipes = [] primaryRecipes = []
otherRecipes = [] otherRecipes = []
@@ -146,6 +147,7 @@ module.exports = class ModVersion extends BaseModel
for recipe in _.values @_recipes for recipe in _.values @_recipes
continue unless recipe.isConditionSatisfied() continue unless recipe.isConditionSatisfied()
continue unless recipe.hasAllTools() continue unless recipe.hasAllTools()
continue if options.forCrafting and recipe.ignoreDuringCrafting
if recipe.itemSlug.matches itemSlug if recipe.itemSlug.matches itemSlug
primaryRecipes.push recipe primaryRecipes.push recipe
@@ -64,11 +64,11 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
@_recipeData = null @_recipeData = null
_command_ignoreDuringCrafting: (value)-> _command_ignoreDuringCrafting: (value)->
if not @_itemData? then throw new Error 'cannot declare "ignoreDuringCraft" before "item"' if not @_recipeData? then throw new Error 'cannot declare "ignoreDuringCrafting" before "recipe"'
if @_itemData.ignoreDuringCrafting? then throw new Error 'duplicate declaration of "ignoreDuringCraft"' if @_recipeData.ignoreDuringCrafting? then throw new Error 'duplicate declaration of "ignoreDuringCrafting"'
if not (value in ['yes', 'no']) then throw new Error 'ignoreDuringCraft must be either "yes" or "no"' if not (value in ['yes', 'no']) then throw new Error 'ignoreDuringCrafting must be either "yes" or "no"'
@_itemData.ignoreDuringCrafting = (value is 'yes') @_recipeData.ignoreDuringCrafting = (value is 'yes')
_command_input: (inputNames...)-> _command_input: (inputNames...)->
if not @_recipeData? then throw new Error 'cannot declare "input" before "recipe"' if not @_recipeData? then throw new Error 'cannot declare "input" before "recipe"'
@@ -183,6 +183,7 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
recipe = new Recipe recipe = new Recipe
condition: recipeData.condition condition: recipeData.condition
ignoreDuringCrafting: recipeData.ignoreDuringCrafting
input: @_buildStackList modVersion, recipeData.input, recipeData.pattern input: @_buildStackList modVersion, recipeData.input, recipeData.pattern
output: @_buildStackList modVersion, recipeData.output output: @_buildStackList modVersion, recipeData.output
pattern: recipeData.pattern pattern: recipeData.pattern
@@ -311,6 +312,7 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
.push 'extras: ' .push 'extras: '
.call => @_unparseStackList builder, extraOutputs .call => @_unparseStackList builder, extraOutputs
.line() .line()
.onlyIf recipe.ignoreDuringCrafting, => builder.line 'ignoreDuringCrafting: yes'
.push 'input: ' .push 'input: '
.loop inputNames .loop inputNames
.line() .line()
+1
View File
@@ -30,6 +30,7 @@ module.exports = class Recipe extends BaseModel
attributes.pattern = @_parsePattern attributes.pattern attributes.pattern = @_parsePattern attributes.pattern
attributes.condition ?= null attributes.condition ?= null
attributes.ignoreDuringCrafting ?= false
attributes.modVersion ?= null attributes.modVersion ?= null
attributes.tools ?= [] attributes.tools ?= []
options.logEvents ?= false options.logEvents ?= false
+4 -2
View File
@@ -108,8 +108,10 @@ module.exports = class SimpleInventory
stack.quantity -= quantity stack.quantity -= quantity
if stack.quantity is 0 if stack.quantity is 0
delete @_stacks[itemSlug] for currentItemSlug, index in @_itemSlugs
@_itemSlugs = (s for s in @_itemSlugs when not ItemSlug.equal(s, itemSlug)) if ItemSlug.equal itemSlug, currentItemSlug
@_itemSlugs.splice index, 1
break
return this return this
+1 -10
View File
@@ -16,16 +16,7 @@
.panel .panel
.view__inventory.large.editable .view__inventory.large.editable
//- .tools.section.hideable.hidden .view__craftsman_working.section
//- h2 Tools
//- .panel
//- .inUse
//- h3 In Use
//- .view__inventory.large
//-
//- .options
//- h3 More Options
//- .view__inventory.large
.ingredients.section.hideable.hidden .ingredients.section.hideable.hidden
h2 Ingredients h2 Ingredients
+15
View File
@@ -0,0 +1,15 @@
//-
//- Crafting Guide - item_group.jade
//-
//- Copyright (c) 2015 by Redwood Labs
//- All rights reserved.
//-
.view__item_group.section.hideable.hidden
.content
.waiting
img(src='/images/wait.gif')
.message
p
.count
p
+35
View File
@@ -0,0 +1,35 @@
/*
Crafting Table - crafting_table.scss
Copyright (c) 2014-2015 by Redwood Labs
All rights reserved.
*/
.view__craftsman_working .content {
align-items: center;
background: $color-white;
box-shadow: none;
display: flex;
flex-direction: column;
padding: 3em;
.waiting {
margin-bottom: 3em;
}
.message {
margin-bottom: 1em;
p {
font-family: $font-family-header;
font-size: $font-size-large;
}
}
.count {
p {
font-family: $font-family-header;
font-size: $font-size-normal;
}
}
}
+3 -2
View File
@@ -8,8 +8,9 @@ All rights reserved.
@import 'adsense'; @import 'adsense';
@import 'browse_page'; @import 'browse_page';
@import 'crafting_grid'; @import 'crafting_grid';
@import 'craft_page';
@import 'crafting_table'; @import 'crafting_table';
@import 'craft_page';
@import 'craftsman_working';
@import 'feedback'; @import 'feedback';
@import 'full_recipe'; @import 'full_recipe';
@import 'home_page'; @import 'home_page';
@@ -27,8 +28,8 @@ All rights reserved.
@import 'mod_pack'; @import 'mod_pack';
@import 'mod_page'; @import 'mod_page';
@import 'mod_selector'; @import 'mod_selector';
@import 'stack';
@import 'slot'; @import 'slot';
@import 'stack';
@import 'step'; @import 'step';
@import 'tutorial'; @import 'tutorial';
@import 'video'; @import 'video';
+8 -2
View File
@@ -19,6 +19,11 @@ MOD_VERSION_FILE =
""" """
schema: 1 schema: 1
item: Bed
recipe:
input: Oak Planks, Wool
pattern: ... 000 111
item: Charcoal item: Charcoal
recipe: recipe:
input: 8 Oak Wood, Coal input: 8 Oak Wood, Coal
@@ -140,14 +145,15 @@ module.exports = fixtures =
makePlans: (stacks...)-> makePlans: (stacks...)->
modPack = fixtures.makeModPack() modPack = fixtures.makeModPack()
have = new Inventory
want = new Inventory want = new Inventory
for stack in stacks for stack in stacks
want.add ItemSlug.slugify(stack[1]), stack[0] want.add ItemSlug.slugify(stack[1]), stack[0]
graphBuilder = new GraphBuilder modPack:fixtures.makeModPack(), want:want graphBuilder = new GraphBuilder modPack:modPack, want:want
graphBuilder.expandGraph() graphBuilder.expandGraph()
planBuilder = new PlanBuilder graphBuilder.rootNode, modPack, want:graphBuilder.want planBuilder = new PlanBuilder graphBuilder.rootNode, modPack, want:want, have:have
return planBuilder.producePlans() return planBuilder.producePlans()
makeTree: (itemSlug, quantity=1)-> makeTree: (itemSlug, quantity=1)->
+4 -1
View File
@@ -71,4 +71,7 @@ describe 'GraphBuilder.coffee', ->
runSingleItemTreeBuildingTest 'test__copper_ingot', 6, 15 runSingleItemTreeBuildingTest 'test__copper_ingot', 6, 15
it 'an item which gatherable and craftable', -> it 'an item which gatherable and craftable', ->
runSingleItemTreeBuildingTest 'test__wool', 2, 2 runSingleItemTreeBuildingTest 'test__wool', 4, 4
it 'an item which requires a gatherable and craftable item', ->
runSingleItemTreeBuildingTest 'test__bed', 6, 7
+4 -3
View File
@@ -52,9 +52,10 @@ describe 'plan_evaluator.coffee', ->
beforeEach -> beforeEach ->
modPack = fixtures.makeModPack() modPack = fixtures.makeModPack()
wanted = new Inventory modPack:modPack wanted = new Inventory modPack:modPack
planA = new CraftingPlan [], wanted, modPack have = new Inventory modPack:modPack
planB = new CraftingPlan [], wanted, modPack planA = new CraftingPlan modPack, wanted, have, []
planC = new CraftingPlan [], wanted, modPack planB = new CraftingPlan modPack, wanted, have, []
planC = new CraftingPlan modPack, wanted, have, []
plans = [planA, planB, planC] plans = [planA, planB, planC]
evaluator = new PlanEvaluator plans evaluator = new PlanEvaluator plans
criteria = PlanEvaluator::CRITERIA.FEWEST_STEPS criteria = PlanEvaluator::CRITERIA.FEWEST_STEPS