diff --git a/src/client/models/site/item_page.coffee b/src/client/models/site/item_page.coffee
index 88fcba6ba..b0c62ccd8 100644
--- a/src/client/models/site/item_page.coffee
+++ b/src/client/models/site/item_page.coffee
@@ -48,8 +48,11 @@ module.exports = class ItemPage extends Observable
return @_findItemsWithMatchingRecipes (recipe)=>
recipe.computeQuantityRequired @item
+ findMultiblockRecipes: ->
+ return (recipe for recipeId, recipe of @item.recipes when recipes.depth > 1)
+
findRecipes: ->
- return (recipe for recipeId, recipe of @item.recipes)
+ return (recipe for recipeId, recipe of @item.recipes when recipe.depth is 1)
findSimilarItems: ->
group = @mod.itemGroups[@item.groupName]
diff --git a/src/client/models/site/multiblock_display.coffee b/src/client/models/site/multiblock_display.coffee
new file mode 100644
index 000000000..64df5b37d
--- /dev/null
+++ b/src/client/models/site/multiblock_display.coffee
@@ -0,0 +1,53 @@
+#
+# Crafting Guide - multiblock_display.coffee
+#
+# Copyright © 2014-2017 by Redwood Labs
+# All rights reserved.
+#
+
+{Inventory} = require("crafting-guide-common").models
+{Observable} = require("crafting-guide-common").util
+
+########################################################################################################################
+
+module.exports = class MultiblockDisplay extends Observable
+
+ constructor: (recipe)->
+ @_layerInventories = []
+ @recipe = recipe
+
+ # Properties ###################################################################################
+
+ Object.defineProperties @prototype,
+
+ recipe:
+ get: -> return @_recipe
+ set: (recipe)->
+ if not recipe? then throw new Error "recipe is required"
+ if @_recipe? then throw new Error "recipe cannot be reassigned"
+ @_recipe = recipe
+
+ # Public Methods ###############################################################################
+
+ getInventory: (z)->
+ if not z?
+ return @_fullInventory ?= @_createFullInventory()
+ else
+ return @_layerInventories[z] ?= @_addLayerInventory z
+
+ # Private Methods ##############################################################################
+
+ _addLayerInventory: (z, inventory=null)->
+ inventory ?= new Inventory
+ for x in [0..@recipe.width]
+ for y in [0..@recipe.height]
+ stack = @recipe.getInputAt x, y, z
+ continue unless stack?
+ inventory.add stack.item, stack.quantity
+ return inventory
+
+ _createFullInventory: (inventory=null)->
+ inventory ?= new Inventory()
+ for z in [0..@recipe.depth]
+ @_addLayerInventory z, inventory
+ return inventory
diff --git a/src/client/site/item_page/multiblock_viewer/multiblock/multiblock_controller.coffee b/src/client/site/item_page/multiblock_viewer/multiblock/multiblock_controller.coffee
index 5829784bc..51e11991e 100644
--- a/src/client/site/item_page/multiblock_viewer/multiblock/multiblock_controller.coffee
+++ b/src/client/site/item_page/multiblock_viewer/multiblock/multiblock_controller.coffee
@@ -1,11 +1,11 @@
-###
-Crafting Guide - multiblock_controller.coffee
+#
+# Crafting Guide - multiblock_controller.coffee
+#
+# Copyright (c) 2014-2017 by Redwood Labs
+# All rights reserved.
+#
-Copyright (c) 2014-2015 by Redwood Labs
-All rights reserved.
-###
-
-BaseController = require '../../../base_controller'
+BaseController = require "../../../base_controller"
ItemDisplay = require "../../../../models/site/item_display"
########################################################################################################################
@@ -26,9 +26,9 @@ module.exports = class MultiblockController extends BaseController
@::MAX_DROP_DELAY = 250 # ms
constructor: (options={})->
- if not options.imageLoader? then throw new Error 'options.imageLoader is required'
- if not options.modPack? then throw new Error 'options.modPack is required'
- options.templateName = 'item_page/multiblock_viewer/multiblock'
+ if not options.imageLoader? then throw new Error "options.imageLoader is required"
+ if not options.modPack? then throw new Error "options.modPack is required"
+ options.templateName = "item_page/multiblock_viewer/multiblock"
super options
@_currentLayer = 0
@@ -64,11 +64,11 @@ module.exports = class MultiblockController extends BaseController
# BaseController Overrides #####################################################################
onDidRender: ->
- @$outline = @$('.outline')
+ @$outline = @$(".outline")
super
refresh: ->
- @$el.css 'height':@_computeMinHeight(), 'width':@_computeMinWidth()
+ @$el.css "height":@_computeMinHeight(), "width":@_computeMinWidth()
@_refreshBlockCache()
@_refreshAllBlocks()
@@ -77,7 +77,7 @@ module.exports = class MultiblockController extends BaseController
# Private Methods ##############################################################################
_computePosition: (x, y, z, options={})->
- if not @model? then return left:0, top:-@IMAGE_SIZE, 'z-index':0, opacity:0.0
+ if not @model? then return left:0, top:-@IMAGE_SIZE, "z-index":0, opacity:0.0
options.hideUpperLayers ?= false
pxWidth = @$el.width()
@@ -94,7 +94,7 @@ module.exports = class MultiblockController extends BaseController
zindex = ((@model.width - x) + (@model.depth - z) + ((@model.width * @model.depth) * y)) * 2
- return left:left, top:top, 'z-index':zindex, opacity:opacity
+ return left:left, top:top, "z-index":zindex, opacity:opacity
_computeMinHeight: ->
return 0 unless @model?
@@ -131,14 +131,14 @@ module.exports = class MultiblockController extends BaseController
for z in [0...@model.depth]
@_blockCache[x][y][z] ?= null
- for el in @$('.block')
+ for el in @$(".block")
$el = $(el)
- @_blockCache[$el.data('x')][$el.data('y')][$el.data('z')] = $el
+ @_blockCache[$el.data("x")][$el.data("y")][$el.data("z")] = $el
_refreshBlock: (x, y, z)->
return unless @model?
- stack = @model.getStackAt x, y, z
+ stack = @model.getInputAt x, y, z
$block = @_blockCache[x][y][z]
position = @_computePosition x, y, z, hideUpperLayers:true
move = false
@@ -147,7 +147,7 @@ module.exports = class MultiblockController extends BaseController
itemDisplay = new ItemDisplay stack.item
if not $block?
- $block = $("
")
+ $block = $("
")
$block.css position, top:-@IMAGE_SIZE, opacity:0.0
@_registerHoverHandlers $block, y, itemDisplay
@_imageLoader.load itemDisplay.iconUrl, $block
@@ -155,10 +155,10 @@ module.exports = class MultiblockController extends BaseController
@$el.append $block
move = true
else
- $block.attr 'src', itemDisplay.iconUrl
+ $block.attr "src", itemDisplay.iconUrl
move = true
else if $block?
- $block.attr 'src', ''
+ $block.attr "src", ""
move = true
if move then _.delay (-> $block.css position), @_randomDropDelay()
@@ -175,10 +175,10 @@ module.exports = class MultiblockController extends BaseController
_registerHoverHandlers: ($el, y, itemDisplay)->
startHovering = =>
return unless y is @_currentLayer
- zIndex = parseInt($el.css('z-index')) + 1
+ zIndex = parseInt($el.css("z-index")) + 1
zIndex = if _.isNaN(zIndex) then 0 else zIndex
- @$outline.css opacity:1.0, top:$el.css('top'), left:$el.css('left'), 'z-index':zIndex
+ @$outline.css opacity:1.0, top:$el.css("top"), left:$el.css("left"), "z-index":zIndex
@_onHovering itemDisplay
if @_hoverTimer? then clearTimeout @_hoverTimer
diff --git a/src/client/site/item_page/multiblock_viewer/multiblock_viewer_controller.coffee b/src/client/site/item_page/multiblock_viewer/multiblock_viewer_controller.coffee
index 068118934..8d993bab1 100644
--- a/src/client/site/item_page/multiblock_viewer/multiblock_viewer_controller.coffee
+++ b/src/client/site/item_page/multiblock_viewer/multiblock_viewer_controller.coffee
@@ -5,19 +5,20 @@
# All rights reserved.
#
-BaseController = require '../../base_controller'
-InventoryController = require '../../common/inventory/inventory_controller'
-MultiblockController = require './multiblock/multiblock_controller'
+BaseController = require "../../base_controller"
+InventoryController = require "../../common/inventory/inventory_controller"
+MultiblockController = require "./multiblock/multiblock_controller"
+MultiblockDisplay = require "../../../models/site/multiblock_display"
########################################################################################################################
module.exports = class MultiblockViewerController extends BaseController
constructor: (options={})->
- if not options.imageLoader? then throw new Error 'options.imageLoader is required'
- if not options.modPack? then throw new Error 'options.modPack is required'
- if not options.router? then throw new Error 'options.router is required'
- options.templateName = 'item_page/multiblock_viewer'
+ if not options.imageLoader? then throw new Error "options.imageLoader is required"
+ if not options.modPack? then throw new Error "options.modPack is required"
+ if not options.router? then throw new Error "options.router is required"
+ options.templateName = "item_page/multiblock_viewer"
super options
@_imageLoader = options.imageLoader
@@ -28,66 +29,70 @@ module.exports = class MultiblockViewerController extends BaseController
# Event Methods ################################################################################
onBackClicked: ->
- return if @$backButton.hasClass 'disabled'
- tracker.trackEvent c.tracking.category.multiblock, 'back'
+ return if @$backButton.hasClass "disabled"
+ tracker.trackEvent c.tracking.category.multiblock, "back"
@multiblockController.goBackLayer()
@refresh()
onNextClicked: ->
- return if @$nextButton.hasClass 'disabled'
- tracker.trackEvent c.tracking.category.multiblock, 'next'
+ return if @$nextButton.hasClass "disabled"
+ tracker.trackEvent c.tracking.category.multiblock, "next"
@multiblockController.goNextLayer()
@refresh()
onBlockHovered: (itemDisplay)->
if itemDisplay?
- @$captionText.html itemDisplay.itemName
+ @$captionText.html itemDisplay.name
@_imageLoader.load itemDisplay.iconUrl, @$captionIcon
else
- @$captionText.html ' '
- @$captionIcon.attr 'src', '/images/empty.png'
+ @$captionText.html " "
+ @$captionIcon.attr "src", "/images/empty.png"
# BaseController Overrides #####################################################################
onDidRender: ->
- @completeInventoryController = @addChild InventoryController, '.view__inventory.complete',
+ @completeInventoryController = @addChild InventoryController, ".view__inventory.complete",
editable: false
imageLoader: @_imageLoader
modPack: @_modPack
router: @_router
- @layerInventoryController = @addChild InventoryController, '.view__inventory.layer',
+ @layerInventoryController = @addChild InventoryController, ".view__inventory.layer",
editable: false
imageLoader: @_imageLoader
modPack: @_modPack
router: @_router
- @multiblockController = @addChild MultiblockController, '.view__multiblock',
+ @multiblockController = @addChild MultiblockController, ".view__multiblock",
imageLoader: @_imageLoader
modPack: @_modPack
onHovering: (itemDisplay)=> @onBlockHovered(itemDisplay)
- @$backButton = @$('.button.back')
- @$nextButton = @$('.button.next')
- @$captionText = @$('.caption p')
- @$captionIcon = @$('.caption img')
+ @$backButton = @$(".button.back")
+ @$nextButton = @$(".button.next")
+ @$captionText = @$(".caption p")
+ @$captionIcon = @$(".caption img")
super
+ onWillChangeModel: (oldModel, newModel)->
+ @_display = new MultiblockDisplay newModel
+ super oldModel, newModel
+
refresh: ->
- if @model?
- @completeInventoryController.model = @model.inventory
- @layerInventoryController.model = @model.getLayerInventory @multiblockController.currentLayer
+ if @model? and @_display?
+ @completeInventoryController.model = @_display.getInventory()
+ @layerInventoryController.model = @_display.getInventory @multiblockController.currentLayer
@multiblockController.model = @model
if @multiblockController.hasBackLayer()
- @$backButton.removeClass 'disabled'
+ @$backButton.removeClass "disabled"
else
- @$backButton.addClass 'disabled'
+ @$backButton.addClass "disabled"
if @multiblockController.hasNextLayer()
- @$nextButton.removeClass 'disabled'
+ @$nextButton.removeClass "disabled"
else
- @$nextButton.addClass 'disabled'
+ @$nextButton.addClass "disabled"
super
@@ -95,5 +100,5 @@ module.exports = class MultiblockViewerController extends BaseController
events: ->
_.extend super,
- 'click .button.back': 'onBackClicked'
- 'click .button.next': 'onNextClicked'
+ "click .button.back": "onBackClicked"
+ "click .button.next": "onNextClicked"