From bd96bc65751f845701f735ab0c2de0ac59f47e6e Mon Sep 17 00:00:00 2001 From: Andrew Miner Date: Tue, 2 May 2017 18:34:53 -0700 Subject: [PATCH] Move model files to crafting-guide-common --- Gruntfile.coffee | 35 -- package.json | 3 +- src/client/client.coffee | 4 +- src/client/models-old/base_model.coffee | 129 ------ src/client/models-old/converter.coffee | 45 --- src/client/models-old/event_recorder.coffee | 36 -- src/client/models-old/game/inventory.coffee | 243 ----------- src/client/models-old/game/item.coffee | 90 ----- src/client/models-old/game/item_slug.coffee | 96 ----- src/client/models-old/game/mod.coffee | 234 ----------- src/client/models-old/game/mod_pack.coffee | 202 ---------- src/client/models-old/game/mod_version.coffee | 200 --------- src/client/models-old/game/multiblock.coffee | 85 ---- src/client/models-old/game/recipe.coffee | 247 ------------ .../models-old/game/simple_stack.coffee | 33 -- src/client/models-old/game/stack.coffee | 23 -- .../command_parser_version_base.coffee | 138 ------- .../command_parser_version_base.test.coffee | 48 --- .../models-old/parsing/item_parser.coffee | 19 - .../models-old/parsing/item_parser_v1.coffee | 72 ---- .../parsing/item_parser_v1.test.coffee | 99 ----- .../models-old/parsing/mod_parser.coffee | 19 - .../models-old/parsing/mod_parser_v1.coffee | 94 ----- .../parsing/mod_version_parser.coffee | 19 - .../parsing/mod_version_parser_v1.coffee | 380 ------------------ .../parsing/mod_version_parser_v1.test.coffee | 344 ---------------- .../models-old/parsing/tutorial_parser.coffee | 19 - .../parsing/tutorial_parser_v1.coffee | 65 --- .../parsing/versioned_parser_base.coffee | 51 --- src/client/models-old/site/tutorial.coffee | 33 -- src/client/models/base_model.coffee | 129 ------ .../models/crafting/crafting_plan.coffee | 144 ------- .../models/crafting/crafting_plan.test.coffee | 99 ----- .../models/crafting/crafting_plan_step.coffee | 39 -- src/client/models/crafting/evaluation.coffee | 105 ----- src/client/models/crafting/evaluator.coffee | 102 ----- .../models/crafting/plan_builder.coffee | 92 ----- .../models/crafting/plan_builder.test.coffee | 158 -------- .../crafting/resources_evaluator.coffee | 40 -- .../crafting/resources_evaluator.test.coffee | 129 ------ .../models/crafting/steps_evaluator.coffee | 41 -- src/client/models/event_recorder.coffee | 36 -- src/client/models/fixtures.coffee | 319 --------------- src/client/models/game/inventory.coffee | 90 ----- src/client/models/game/item.coffee | 96 ----- src/client/models/game/mod.coffee | 62 --- src/client/models/game/mod_pack.coffee | 59 --- src/client/models/game/recipe.coffee | 174 -------- src/client/models/game/recipe.test.coffee | 72 ---- src/client/models/game/stack.coffee | 42 -- .../models/parsing/mod_pack_json.test.coffee | 124 ------ .../parsing/mod_pack_json_formatter.coffee | 101 ----- .../parsing/mod_pack_json_parser.coffee | 164 -------- src/client/models/site/craft_page.coffee | 10 +- src/client/models/site/editable_file.coffee | 3 +- src/client/models/site/file_cache.coffee | 2 + src/client/models/site/file_cache.test.coffee | 6 + src/client/models/site/github_user.coffee | 2 +- src/client/models/site/item_page.coffee | 2 +- src/client/models/site/item_selector.coffee | 4 +- .../models/site/markdown_image_list.coffee | 2 +- src/client/models/site/tutorial.coffee | 33 -- .../models/stores/mod_pack_store.coffee | 1 + .../browse_page/browse_page_controller.coffee | 2 +- .../common/adsense/adsense_controller.coffee | 2 +- .../item_selector_controller.coffee | 1 + .../common/recipe/recipe_controller.coffee | 2 +- .../craft_page/craft_page_controller.coffee | 5 +- .../craftsman_working_controller.coffee | 2 +- .../craft_page/step/step_controller.coffee | 2 +- .../site/feedback/feedback_controller.coffee | 1 + .../item_page/item_page_controller.coffee | 5 +- .../recipe_detail_controller.coffee | 4 +- .../login_page/login_page_controller.coffee | 2 +- .../site/mod_page/mod_page_controller.coffee | 6 +- src/client/site/router.coffee | 18 +- src/client/site/site_controller.coffee | 23 +- src/client/tracker.coffee | 2 + src/common/constants.coffee | 91 ++--- src/common/underscore.coffee | 31 +- src/index.coffee | 11 +- src/server/crafting_guide_server.coffee | 1 + src/server/server.coffee | 6 - src/test_helper.coffee | 6 +- src/underscore.coffee | 10 + 85 files changed, 134 insertions(+), 5686 deletions(-) delete mode 100644 src/client/models-old/base_model.coffee delete mode 100644 src/client/models-old/converter.coffee delete mode 100644 src/client/models-old/event_recorder.coffee delete mode 100644 src/client/models-old/game/inventory.coffee delete mode 100644 src/client/models-old/game/item.coffee delete mode 100644 src/client/models-old/game/item_slug.coffee delete mode 100644 src/client/models-old/game/mod.coffee delete mode 100644 src/client/models-old/game/mod_pack.coffee delete mode 100644 src/client/models-old/game/mod_version.coffee delete mode 100644 src/client/models-old/game/multiblock.coffee delete mode 100644 src/client/models-old/game/recipe.coffee delete mode 100644 src/client/models-old/game/simple_stack.coffee delete mode 100644 src/client/models-old/game/stack.coffee delete mode 100644 src/client/models-old/parsing/command_parser_version_base.coffee delete mode 100644 src/client/models-old/parsing/command_parser_version_base.test.coffee delete mode 100644 src/client/models-old/parsing/item_parser.coffee delete mode 100644 src/client/models-old/parsing/item_parser_v1.coffee delete mode 100644 src/client/models-old/parsing/item_parser_v1.test.coffee delete mode 100644 src/client/models-old/parsing/mod_parser.coffee delete mode 100644 src/client/models-old/parsing/mod_parser_v1.coffee delete mode 100644 src/client/models-old/parsing/mod_version_parser.coffee delete mode 100644 src/client/models-old/parsing/mod_version_parser_v1.coffee delete mode 100644 src/client/models-old/parsing/mod_version_parser_v1.test.coffee delete mode 100644 src/client/models-old/parsing/tutorial_parser.coffee delete mode 100644 src/client/models-old/parsing/tutorial_parser_v1.coffee delete mode 100644 src/client/models-old/parsing/versioned_parser_base.coffee delete mode 100644 src/client/models-old/site/tutorial.coffee delete mode 100644 src/client/models/base_model.coffee delete mode 100644 src/client/models/crafting/crafting_plan.coffee delete mode 100644 src/client/models/crafting/crafting_plan.test.coffee delete mode 100644 src/client/models/crafting/crafting_plan_step.coffee delete mode 100644 src/client/models/crafting/evaluation.coffee delete mode 100644 src/client/models/crafting/evaluator.coffee delete mode 100644 src/client/models/crafting/plan_builder.coffee delete mode 100644 src/client/models/crafting/plan_builder.test.coffee delete mode 100644 src/client/models/crafting/resources_evaluator.coffee delete mode 100644 src/client/models/crafting/resources_evaluator.test.coffee delete mode 100644 src/client/models/crafting/steps_evaluator.coffee delete mode 100644 src/client/models/event_recorder.coffee delete mode 100644 src/client/models/fixtures.coffee delete mode 100644 src/client/models/game/inventory.coffee delete mode 100644 src/client/models/game/item.coffee delete mode 100644 src/client/models/game/mod.coffee delete mode 100644 src/client/models/game/mod_pack.coffee delete mode 100644 src/client/models/game/recipe.coffee delete mode 100644 src/client/models/game/recipe.test.coffee delete mode 100644 src/client/models/game/stack.coffee delete mode 100644 src/client/models/parsing/mod_pack_json.test.coffee delete mode 100644 src/client/models/parsing/mod_pack_json_formatter.coffee delete mode 100644 src/client/models/parsing/mod_pack_json_parser.coffee delete mode 100644 src/client/models/site/tutorial.coffee create mode 100644 src/underscore.coffee diff --git a/Gruntfile.coffee b/Gruntfile.coffee index ce937dacb..1f09793e0 100644 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -17,29 +17,6 @@ EXTERNAL_LIBS = [ './vendor/email.js:emailjs' ] -PUBLISHED_FILES = [ - './client/models/base_model.coffee' - './client/models/game/inventory.coffee' - './client/models/game/item.coffee' - './client/models/game/item_slug.coffee' - './client/models/game/mod.coffee' - './client/models/game/mod_version.coffee' - './client/models/game/multiblock.coffee' - './client/models/game/recipe.coffee' - './client/models/game/stack.coffee' - './client/models/game/simple_stack.coffee' - './client/models/parsing/command_parser_version_base.coffee' - './client/models/parsing/mod_parser.coffee' - './client/models/parsing/mod_parser_v1.coffee' - './client/models/parsing/mod_version_parser.coffee' - './client/models/parsing/mod_version_parser_v1.coffee' - './client/models/parsing/versioned_parser_base.coffee' - './client/models/site/tutorial.coffee' - './common/constants.coffee' - './common/underscore.coffee' - './index.coffee' -] - ######################################################################################################################## module.exports = (grunt)-> @@ -61,15 +38,6 @@ module.exports = (grunt)-> {expand: true, cwd:'./build/static', src:'**/*.txt', dest:'./dist/'} ] - coffee: - npm_package: - options: { - bare: true - } - files: [ - {expand:true, cwd:'./src', src:PUBLISHED_FILES, dest:'./dist', ext:'.js'} - ] - copy: assets_build: files: [ @@ -216,9 +184,6 @@ module.exports = (grunt)-> grunt.registerTask 'dist', 'build the project to be run from Amazon S3', ['build', 'copy:build_to_dist', 'uglify', 'compress'] - grunt.registerTask 'prepublish', 'build the project to be published to NPM as shared code', - ['clean', 'coffee'] - grunt.registerTask 'publish', 'publish the project to NPM', ['prepublish', 'script:publish', 'clean', 'build'] diff --git a/package.json b/package.json index 4f7606cef..9617daca9 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,6 @@ "repository": "http://github.com/andrewminer/crafting-guide", "scripts": { "build": "grunt build", - "prepublish": "grunt prepublish", "start": "grunt start", "test": "grunt test" }, @@ -37,7 +36,7 @@ "body-parser": "^1.13.3", "client-sessions": "^0.7.0", "cookie-parser": "^1.3.5", - "crafting-guide-common": "^2.0.0", + "crafting-guide-common": "^3.2.0", "dotenv": "^2.0.0", "express": "^4.13.3", "express-session": "^1.11.3", diff --git a/src/client/client.coffee b/src/client/client.coffee index 87b1f114d..2b417c1a9 100644 --- a/src/client/client.coffee +++ b/src/client/client.coffee @@ -18,7 +18,7 @@ global.π = Math.PI global.ε = 0.0001 global.w = require 'when' -{Logger} = require 'crafting-guide-common' +{Logger} = require('crafting-guide-common').util global.logger = new Logger Tracker = require './tracker' @@ -63,7 +63,7 @@ storage = new Storage storage:global.localStorage tracker.trackPageView() -{CraftingGuideClient} = require 'crafting-guide-common' +{CraftingGuideClient} = require('crafting-guide-common').api client = _(new CraftingGuideClient(baseUrl:apiBaseUrl)).extend Backbone.Events client.onStatusChanged = (client, oldStatus, newStatus)-> logger.info "Crafting Guide server status changed from #{oldStatus} to #{newStatus}" diff --git a/src/client/models-old/base_model.coffee b/src/client/models-old/base_model.coffee deleted file mode 100644 index 8da42e281..000000000 --- a/src/client/models-old/base_model.coffee +++ /dev/null @@ -1,129 +0,0 @@ -# -# Crafting Guide - base_model.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class BaseModel extends Backbone.Model - - @_loadingQueue = [] - @_isDraining = false - - constructor: (attributes={}, options={})-> - options.logEvents ?= true - super attributes, options - - makeGetter = (name)-> return -> @get name - makeSetter = (name)-> return (value)-> @set name, value - for name, value of attributes - continue if name is 'id' - Object.defineProperty this, name, get:makeGetter(name), set:makeSetter(name) - - @fileCache = options.fileCache or null - @loading = null - @logEvents = options.logEvents or false - @state = c.modelState.unloaded - - Object.defineProperties this, - isUnloaded: { get:-> @state is c.modelState.unloaded } - isLoading: { get:-> @state is c.modelState.loading } - isLoaded: { get:-> @state is c.modelState.loaded } - isError: { get:-> @state is c.modelState.error } - - # Event Methods ################################################################################ - - onLoadSucceeded: (text, status, xhr)-> - try - @set @parse text - - @state = c.modelState.loaded - @trigger c.event.change, this - @trigger c.event.sync, this - logger.info => "#{@constructor.name}.#{@cid} loaded successfully" - catch e - logger.error -> "A parsing error occured: #{e.stack}" - @onLoadFailed e.message, 'parsing failed', xhr - - onLoadFailed: (error, status, xhr)-> - @state = c.modelState.error - logger.error => "#{@constructor.name}.#{@cid} failed to load: status:#{status}, message:#{error}" - @trigger c.event.error, this, error - - # Backbone.Model Overrides ##################################################################### - - fetch: (options={})-> - options.force ?= false - return if (@isLoading or @isLoaded) and not options.force - - url = @url() - logger.info => "#{@constructor.name}.#{@cid} reading from url: #{url}" - - @state = c.modelState.loading - @trigger c.event.request, this - - loadFromServer = => - w.promise (resolve, reject)=> - $.ajax - url: url - dataType: 'text' - success: (text, status, xhr)=> resolve @onLoadSucceeded text, status, xhr - error: (xhr, status, error)=> reject @onLoadFailed error, status, xhr - - if @fileCache? - @loading = @fileCache.loading.then => - if @fileCache.hasFile url - return @_addToLoadingQueue @fileCache.getFile(url), 'success', {url:url} - else - @loading = loadFromServer() - else - @loading = loadFromServer() - - @loading.catch (e)-> # do nothing - return @loading - - parse: (text)-> - return JSON.parse text - - sync: (method, model)-> - throw new Error "#{@constructor.name}.#{@cid} is not permitted to #{method}" - - trigger: (name, model, args...)-> - if @logEvents - argText = ("#{arg}"[0..50] for arg in args).join ", " - logger.trace => "#{@constructor.name}.#{@cid} triggered event #{name} with args: #{argText}" - super - - # Object Overrides ############################################################################# - - toString: -> - return "#{@constructor.name}.#{@cid}" - - # Private Methods ############################################################################## - - _addToLoadingQueue: (text, status, xhr)-> - deferred = w.defer() - - BaseModel._loadingQueue.push resolve:deferred.resolve, func:(=> @onLoadSucceeded text, status, xhr) - @_drainLoadingQueue() - return deferred.promise - - _drainLoadingQueue: -> - return if @_isDraining - @_isDraining = true - - drainDelay = 50 - drain = => - toLoad = BaseModel._loadingQueue.shift() - if not toLoad? - @_isDraining = false - else - toLoad.func() - toLoad.resolve(true) - - _.delay drain, drainDelay - - _.delay drain, drainDelay - diff --git a/src/client/models-old/converter.coffee b/src/client/models-old/converter.coffee deleted file mode 100644 index d765a13b6..000000000 --- a/src/client/models-old/converter.coffee +++ /dev/null @@ -1,45 +0,0 @@ -# -# Crafting Guide - converter.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -Item = require "../models/game/item" -Mod = require "../models/game/mod" -ModPack = require "../models/game/mod_pack" - -######################################################################################################################## - -module.exports = class Converter - - # Public Methods ############################################################################### - - convert: (id, displayName, oldModPack)-> - modSlugToIdMap = {} - itemSlugToIdMap = {} - - newModPack = new ModPack id:id, displayName:displayName - oldModPack.eachMod (oldMod)=> - newMod = new Mod id:_.uniqueId("mod-"), displayName:oldMod.name, modPack:newModPack - modSlugToIdMap[oldMod.slug.toString()] = newMod.id - - oldMod.eachItem (oldItem)=> - newItem = new Item id:_.uniqueId("item-"), displayName:oldItem.name, mod:newMod - itemSlugToIdMap[oldItem.slug.toString()] = newItem.id - - if oldItem.isGatherable? - newItem.isGatherable = oldItem.isGatherable - - oldModPack.eachMod (oldMod)=> - newMod = newModPack.mods[modSlugToIdMap[oldMod.slug.toString()]] - - - return newModPack - - # Private Methods ############################################################################## - - _convertItem: (oldItem, newMod)-> - - _convertMod: (oldMod, newModPack)-> - return newMod \ No newline at end of file diff --git a/src/client/models-old/event_recorder.coffee b/src/client/models-old/event_recorder.coffee deleted file mode 100644 index 507ed32cd..000000000 --- a/src/client/models-old/event_recorder.coffee +++ /dev/null @@ -1,36 +0,0 @@ -# -# Crafting Guide - event_recorder.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -util = require 'util' - -######################################################################################################################## - -module.exports = class EventRecorder - - constructor: (model)-> - if not model? then throw new Error 'model is required' - - @model = model - @events = [] - - @model.on 'all', (event, model, args...)=> - logger.verbose -> "#{model?.constructor?.name}(#{model?.cid}) emitted #{event} - with args: #{util.inspect(args)}" - @events.push id:model?.cid, event:event, args:args - - # Public Methods ############################################################################### - - reset: -> - @events = [] - - # Property Methods ############################################################################# - - getNames: -> - return (e.event for e in @events) - - Object.defineProperties @prototype, - names: {get:@prototype.getNames} diff --git a/src/client/models-old/game/inventory.coffee b/src/client/models-old/game/inventory.coffee deleted file mode 100644 index a024cb2d7..000000000 --- a/src/client/models-old/game/inventory.coffee +++ /dev/null @@ -1,243 +0,0 @@ -# -# Crafting Guide - inventory.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' -ItemSlug = require './item_slug' -Stack = require './stack' - -######################################################################################################################## - -module.exports = class Inventory extends BaseModel - - constructor: (attributes={}, options={})-> - super attributes, options - attributes.modPack ?= null - @clear() - - if options.clone? - @addInventory options.clone - - # Class Methods ################################################################################ - - @Delimiters = - Item: '.' - Stack: ':' - - # Public Methods ############################################################################### - - add: (itemSlug, quantity=1, options={})-> - return this unless quantity > 0 - - @_add itemSlug, quantity, options - @trigger c.event.add, this, itemSlug, quantity - @trigger c.event.change, this - return this - - addInventory: (inventory)-> - inventory.each (stack)=> @_add stack.itemSlug, stack.quantity - - @trigger c.event.change, this - return this - - clear: (options={})-> - @_stacks = {} - @_itemSlugs = [] - - @trigger c.event.change, this - - clone: -> - inventory = new Inventory - inventory.addInventory this - return inventory - - each: (callback)-> - for itemSlug in @_itemSlugs - stack = @_stacks[itemSlug] - continue unless stack? - callback stack - - getSlugs: -> - return @_itemSlugs[..] - - hasAtLeast: (itemSlug, quantity=1)-> - if quantity is 0 then return true - - stack = @_stacks[itemSlug] - return false unless stack? - return stack.quantity >= quantity - - localize: -> - if not @modPack? then throw new Error 'localize requires @modPack' - - changed = false - newSlugs = [] - newStacks = [] - for itemSlug in @_itemSlugs - stack = @_stacks[itemSlug] - continue unless stack? - - qualifiedSlug = if itemSlug.isQualified then itemSlug else null - if not qualifiedSlug? - qualifiedSlug = @modPack.findItem(itemSlug)?.slug - changed = qualifiedSlug? - - if qualifiedSlug? - newSlugs.push qualifiedSlug - newStacks.push new Stack itemSlug:qualifiedSlug, quantity:stack.quantity - else - newSlugs.push itemSlug - newStacks.push stack - - if changed - for itemSlug, stack of @_stacks - @stopListening stack - - @_itemSlugs = newSlugs - @_stacks = {} - for stack in newStacks - @_stacks[stack.itemSlug] = stack - @listenTo stack, c.event.change, => @trigger c.event.change, this - - @_sort() - @trigger c.event.change, this - - pop: -> - itemSlug = @_itemSlugs.pop() - return null unless itemSlug? - - stack = @_stacks[itemSlug] - delete @_stacks[itemSlug] - - @trigger c.event.remove, this, stack.itemSlug, stack.quantity - @trigger c.event.change, this - return stack - - quantityOf: (itemSlug)-> - stack = @_stacks[itemSlug] - return stack.quantity if stack - return 0 - - remove: (itemSlug, quantity=null)-> - stack = @_stacks[itemSlug] - return this unless stack? - - quantity ?= stack.quantity - return this unless quantity > 0 - - if stack.quantity < quantity - throw new Error "cannot remove #{quantity}: only #{stack.quantity} #{itemSlug} in this inventory" - - stack.quantity -= quantity - if stack.quantity is 0 - @stopListening stack - delete @_stacks[itemSlug] - @_itemSlugs = (s for s in @_itemSlugs when not ItemSlug.equal(s, itemSlug)) - - @trigger c.event.remove, this, itemSlug, quantity - @trigger c.event.change, this - return this - - toDescription: -> - return null if @isEmpty - return null unless @modPack? - - item = @modPack.findItem @_itemSlugs[0] - extras = @_itemSlugs.length - 1 - - result = "#{item.name}" - if extras > 0 then result += " and #{extras} more..." - - return result - - # Parsing Methods ############################################################################## - - parse: (data)-> - return this if not data? or data.length is 0 - - stacks = data.split Inventory.Delimiters.Stack - for stackText in stacks - stackParts = stackText.split Inventory.Delimiters.Item - if stackParts.length is 2 - quantity = parseInt stackParts[0], 10 - itemSlug = ItemSlug.slugify stackParts[1] - else if stackParts.length is 1 - quantity = 1 - itemSlug = ItemSlug.slugify stackParts[0] - else - throw new Error "expected #{stackText} to have 0 or 1 parts" - - if itemSlug.qualified.length > 0 - @add itemSlug, quantity - - return this - - unparse: (options={})-> - parts = [] - @each (stack)=> - slugText = stack.itemSlug.item - if @modPack? - item = @modPack.findItem ItemSlug.slugify slugText - if item? and item.slug.qualified isnt stack.itemSlug.qualified - slugText = stack.itemSlug.qualified - - if stack.quantity is 1 - parts.push slugText - else - parts.push "#{stack.quantity}#{Inventory.Delimiters.Item}#{slugText}" - - return parts.join Inventory.Delimiters.Stack - - # Property Methods ############################################################################# - - Object.defineProperties @prototype, - isEmpty: - get: -> @_itemSlugs.length is 0 - - totalQuantity: - get: -> - total = 0 - @each (stack)-> - total += stack.quantity - return total - - # Object Overrides ############################################################################# - - toString: -> - result = [@constructor.name, " (", @cid, ") {items: ["] - - needsDelimiter = false - @each (stack)-> - if needsDelimiter then result.push ', ' - result.push stack.toString() - needsDelimiter = true - result.push ']' - - result.push '}' - return result.join '' - - # Private Methods ############################################################################## - - _add: (itemSlug, quantity=1, options={})-> - options.insert ?= false - return unless itemSlug? - return unless quantity > 0 - - stack = @_stacks[itemSlug] - if not stack? - stack = new Stack itemSlug:itemSlug, quantity:quantity - @listenTo stack, c.event.change, => @trigger c.event.change, this - @_stacks[itemSlug] = stack - if options.insert - @_itemSlugs.unshift itemSlug - else - @_itemSlugs.push itemSlug - @_sort() - else - stack.quantity += quantity - - _sort: -> - @_itemSlugs.sort (a, b)-> ItemSlug.compare a, b diff --git a/src/client/models-old/game/item.coffee b/src/client/models-old/game/item.coffee deleted file mode 100644 index 9ab2545aa..000000000 --- a/src/client/models-old/game/item.coffee +++ /dev/null @@ -1,90 +0,0 @@ -# -# Crafting Guide - item.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' -ItemSlug = require './item_slug' -Recipe = require './recipe' -{StringBuilder} = require 'crafting-guide-common' - -######################################################################################################################## - -module.exports = class Item extends BaseModel - - @Group = Other:'Other' - - constructor: (attributes={}, options={})-> - if not attributes.name? then throw new Error 'attributes.name is required' - - attributes.description ?= null - attributes.group ?= Item.Group.Other - attributes.ignoreDuringCrafting ?= false - attributes.isGatherable ?= false - attributes.modVersion ?= null - attributes.officialUrl ?= null - attributes.slug ?= ItemSlug.slugify attributes.name - attributes.videos ?= [] - - options.logEvents ?= false - super attributes, options - - @on c.event.change + ':modVersion', => - @_isCraftable = null - @slug.mod = @modVersion?.modSlug - - # Public Methods ############################################################################### - - compareTo: (that)-> - if this.slug isnt that.slug - return if this.slug < that.slug then -1 else +1 - if this.name isnt that.name - return if this.name < that.name then -1 else +1 - return 0 - - unparse: -> - ItemParser = require '../parsing/item_parser' # to avoid require cycles - @_parser ?= new ItemParser model:this - return @_parser.unparse() - - # Property Methods ############################################################################# - - getIsCraftable: -> - if not @_isCraftable? - @_isCraftable = false - if @modVersion? - @_isCraftable = @modVersion.hasRecipes @slug - - return @_isCraftable - - Object.defineProperties @prototype, - isCraftable: {get:@prototype.getIsCraftable} - - # Backbone.Model Overrides ##################################################################### - - parse: (text)-> - ItemParser = require '../parsing/item_parser' # to avoid require cycles - @_parser ?= new ItemParser model:this - @_parser.parse text - - return null # prevent calling `set` - - url: -> - return c.url.itemData modSlug:@slug.mod, itemSlug:@slug.item - - # Object Overrides ############################################################################# - - toString: -> - builder = new StringBuilder - return builder - .push @constructor.name, ' (', @cid, ') { ' - .push 'name:"', @name, '", ' - .push 'isCraftable:', @isCraftable, ', ' - .push 'isGatherable:', @isGatherable, ', ' - .onlyIf (@group isnt Item.Group.Other), (b)=> - b.push 'group:"', @group, '", ' - .push 'slug:"', @slug, '", ' - .push '}' - .toString() diff --git a/src/client/models-old/game/item_slug.coffee b/src/client/models-old/game/item_slug.coffee deleted file mode 100644 index 78e2ecb1f..000000000 --- a/src/client/models-old/game/item_slug.coffee +++ /dev/null @@ -1,96 +0,0 @@ -# -# Crafting Guide - item_slug.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class ItemSlug - - constructor: -> - @_item = @_mod = null - - if arguments.length is 1 - parts = _.decomposeSlug arguments[0] - @_mod = _.slugify parts[0] - @item = _.slugify parts[1] - else if arguments.length is 2 - @_mod = arguments[0] - @item = arguments[1] - else - throw new Error 'expected arguments to be "modSlug, itemSlug" or just "itemSlug"' - - # Class Methods ################################################################################ - - @compare: (a, b)-> - if a.item isnt b.item - return if a.item < b.item then -1 else +1 - if a.mod isnt b.mod - return if a.mod < b.mod then -1 else +1 - return 0 - - @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.item is b.item - return true - - @slugify: (arg)-> - return arg if arg?.constructor?.name is 'ItemSlug' - - [modSlug, itemSlug] = _.decomposeSlug arg - itemSlug = _.slugify itemSlug - - if modSlug? - return new ItemSlug modSlug, itemSlug - else - return new ItemSlug itemSlug - - # Public Methods ############################################################################### - - compareTo: (that)-> - return ItemSlug.compare this, that - - matches: (slug, options={exact:false})-> - return false unless slug? - return false unless typeof(slug.matches) is 'function' - - if slug.isQualified and this.isQualified - return slug.qualified is this.qualified - else - return slug.item is this.item - - # Property Methods ############################################################################# - - Object.defineProperties @prototype, - isQualified: - get: -> @_mod? - - item: - get: -> @_item - - set: (newItem)-> - if not newItem? then throw new Error 'item is required' - @_item = newItem - @mod = @mod # reset @_qualified - - mod: - get: -> @_mod - - set: (newMod)-> - @_mod = newMod - @_qualified = if @_mod? then _.composeSlugs(@_mod, @_item) else @_item - - qualified: - get: -> @_qualified - - # Object Overrides ############################################################################# - - toString: -> - return @_qualified - - valueOf: -> - return @_qualified.valueOf() diff --git a/src/client/models-old/game/mod.coffee b/src/client/models-old/game/mod.coffee deleted file mode 100644 index e5e058564..000000000 --- a/src/client/models-old/game/mod.coffee +++ /dev/null @@ -1,234 +0,0 @@ -# -# Crafting Guide - mod.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' - -######################################################################################################################## - -module.exports = class Mod extends BaseModel - - constructor: (attributes={}, options={})-> - if not attributes.slug? then throw new Error 'attributes.slug is required' - - attributes.author ?= '' - attributes.description ?= '' - attributes.documentationUrl ?= null - attributes.downloadUrl ?= null - attributes.homePageUrl ?= null - attributes.modPack ?= null - attributes.name ?= '' - - super attributes, options - - @_activeModVersion = null - @_activeVersion = null - @_modVersions = [] - @_tutorials = [] - - # Class Methods ################################################################################## - - @Version: Version = - None: 'none' - Latest: 'latest' - - # Public Methods ################################################################################# - - compareTo: (that)-> - thisRequired = this.slug in c.requiredMods - thatRequired = that.slug in c.requiredMods - - if thisRequired isnt thatRequired - return -1 if thisRequired - return +1 if thatRequired - else if this.slug isnt that.slug - return if this.slug < that.slug then -1 else +1 - - return 0 - - # Property Methods ############################################################################# - - Object.defineProperties @prototype, - - activeModVersion: - get: -> @_activeModVersion - - activeVersion: - get: -> - return @_activeVersion - - set: (version)-> - return if version is @_activeVersion - - version ?= Mod.Version.None - if version is Mod.Version.Latest then version = _.last(@_modVersions).version - - if version is Mod.Version.None - @_activeVersion = version - @_activateModVersion null - - @trigger c.event.change + ':activeVersion', this, @_activeVersion - @trigger c.event.change, this - else - for modVersion in @_modVersions - if version is modVersion.version - @_activateModVersion modVersion - break - - @_activeVersion = version - @trigger c.event.change + ':activeVersion', this, @_activeVersion - @trigger c.event.change, this - - enabled: - get: -> @_activeModVersion? - - modVersions: - get: -> @_modVersions[..] - - tutorials: - get: -> @getAllTutorials() - - # Item Methods ################################################################################# - - chooseRandomItem: -> - effectiveModVersion = @_activeModVersion or @getModVersion Mod.Version.Latest - return null unless effectiveModVersion? - - return effectiveModVersion.chooseRandomItem() - - eachItem: (callback)-> - effectiveModVersion = @_activeModVersion or @getModVersion Mod.Version.Latest - effectiveModVersion.eachItem callback - - findItem: (slug, options={})-> - options.includeDisabled ?= false - options.enableAsNeeded ?= false - - if not options.includeDisabled - return unless @_activeModVersion? - return @_activeModVersion.findItem slug - else - for modVersion in @_modVersions - modVersion.fetch() - - item = modVersion.findItem slug - if item? - if options.enableAsNeeded then @setActiveVersion modVersion.version - return item - - return null - - findItemByName: (name)-> - return unless @_activeModVersion? - @_activeModVersion.findItemByName name - - # ModVersion Methods ########################################################################### - - addModVersion: (modVersion)-> - return unless modVersion? - return if @_modVersions.indexOf(modVersion) isnt -1 - - @_modVersions.push modVersion - @listenTo modVersion, c.event.change, => @trigger c.event.change, this - modVersion.fileCache = this.fileCache - modVersion.mod = this - - @trigger c.event.add + ':modVersion', modVersion, this - @trigger c.event.change + ':version', modVersion, this - @trigger c.event.change, this - - if not @activeVersion? then @activeVersion = modVersion.version - if modVersion.version is @_activeVersion then @_activateModVersion modVersion - return this - - eachModVersion: (callback)-> - for modVersion in @_modVersions - callback modVersion - - getAllModVersions: -> - return @_modVersions[..] - - getModVersion: (version)-> - return null if version is Mod.Version.None - return @_modVersions[0] if version is Mod.Version.Latest - - for modVersion in @_modVersions - return modVersion if modVersion.version is version - - return null - - # Name Methods ################################################################################# - - eachName: (callback)-> - effectiveModVersion = @_activeModVersion or @getModVersion Mod.Version.Latest - effectiveModVersion.eachName callback - - findName: (itemSlug)-> - return unless @_activeModVersion? - @_activeModVersion.findName itemSlug - - # Recipe Methods ############################################################################### - - eachRecipe: (callback)-> - effectiveModVersion = @_activeModVersion or @getModVersion Mod.Version.Latest - effectiveModVersion.eachRecipe callback - - findRecipes: (itemSlug, result=[], options={})-> - options.alwaysFromOwningMod ?= false - - if @_activeModVersion? - return @_activeModVersion.findRecipes itemSlug, result, options - else if options.alwaysFromOwningMod and itemSlug.mod is @slug - return @getModVersion(Mod.Version.Latest).findRecipes itemSlug, result, options - - return null - - # Tutorial Methods ############################################################################# - - addTutorial: (tutorial)-> - return unless tutorial? - if @getTutorial(tutorial.slug)? then throw new Error "duplicate tutorial: #{tutorial.name}" - @_tutorials.push tutorial - tutorial.modSlug = @slug - - getAllTutorials: -> - return @_tutorials[..] - - getTutorial: (tutorialSlug)-> - for tutorial in @_tutorials - return tutorial if tutorial.slug is tutorialSlug - return null - - # Backbone.Model Overrides ##################################################################### - - parse: (text)-> - ModParser = require '../parsing/mod_parser' # to avoid require cycles - @_parser ?= new ModParser model:this - @_parser.parse text - - @_verifyActiveModVersion() - - return null # prevent calling `set` - - url: -> - return c.url.modData modSlug:@slug - - # Private Methods ############################################################################## - - _activateModVersion: (modVersion)-> - if @_activeModVersion? then @stopListening @_activeModVersion - @_activeModVersion = modVersion - @trigger c.event.change + ':activeModVersion', this, @_activeModVersion - - logger.verbose => "#{@slug} switched to version #{@_activeVersion}" - - if @_activeModVersion? - @listenTo @_activeModVersion, 'all', -> @trigger.apply this, arguments - - _verifyActiveModVersion: -> - if (@_activeVersion isnt Version.None) and (not @_activeModVersion?) - logger.warning => "#{@slug} no longer has a version #{@_activeVersion}, using latest instead" - @activeVersion = Version.Latest diff --git a/src/client/models-old/game/mod_pack.coffee b/src/client/models-old/game/mod_pack.coffee deleted file mode 100644 index 50dd10493..000000000 --- a/src/client/models-old/game/mod_pack.coffee +++ /dev/null @@ -1,202 +0,0 @@ -# -# Crafting Guide - mod_pack.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' -Mod = require './mod' -ModVersionParser = require '../parsing/mod_version_parser' -Recipe = require './recipe' -SimpleInventory = require '../crafting/simple_inventory' - -######################################################################################################################## - -module.exports = class ModPack extends BaseModel - - constructor: (attributes={}, options={})-> - super attributes, options - - @_mods = [] - @_cache = {} - - @on c.event.change, => @_cache = {} - - # Item Methods ################################################################################# - - chooseRandomItem: -> - return null unless @_mods.length > 0 - - modIndex = Math.floor Math.random() * @_mods.length - return @_mods[modIndex].chooseRandomItem() - - findItem: (itemSlug, options={})-> - options.includeDisabled ?= false - - key = "#{itemSlug}-#{options.includeDisabled}" - @_cache.itemBySlug ?= {} - item = @_cache.itemBySlug[key] - return item if item? - - if itemSlug.isQualified - mod = @getMod itemSlug.mod - if mod? - item = mod.findItem itemSlug, options - - if not item? - for mod in @_mods - continue unless mod.enabled or options.includeDisabled - item = mod.findItem itemSlug, options - break if item? - - if item? - @_cache.itemBySlug[key] = item - - return item - - findItemByName: (name, options={})-> - options.enableAsNeeded ?= false - options.includeDisabled = true if options.enableAsNeeded - - for mod in @_mods - continue unless mod.enabled or options.includeDisabled - item = mod.findItemByName name, options - return item if item? - - return null - - findItemDisplay: (itemSlug)-> - if not itemSlug? then throw new Error 'itemSlug is required' - - result = {slug:itemSlug} - item = @findItem itemSlug, includeDisabled:true - if item? - result.itemName = item.name - result.itemSlug = item.slug.item - result.modSlug = item.slug.mod - result.modVersion = item.modVersion.version - else - result.itemName = @findName itemSlug, includeDisabled:true - result.itemSlug = itemSlug.item - result.modSlug = @_mods[0].slug - result.modVersion = @_mods[0].activeVersion - - craftingUrlInventory = new SimpleInventory modPack:this - if item?.multiblock? - craftingUrlInventory.addInventory item.multiblock.inventory - else - craftingUrlInventory.add itemSlug - - result.craftingUrl = c.url.crafting inventoryText:craftingUrlInventory.unparse() - result.iconUrl = c.url.itemIcon result - result.itemUrl = c.url.item result - result.modName = @getMod(result.modSlug).name - return result - - qualifySlug: (itemSlug)-> - return itemSlug if itemSlug.isQualified - - item = @findItem itemSlug - return item.slug if item? - return itemSlug - - # Mod Methods ################################################################################## - - addMod: (mod)-> - if not mod? then throw new Error 'mod is required' - return if @_mods.indexOf(mod) isnt -1 - - mod.modPack = this - @_mods.push mod - @listenTo mod, c.event.change, (modVersion)=> @_onModVersionLoaded modVersion - @trigger c.event.add + ':mod', mod, this - - @_mods.sort (a, b)-> a.compareTo b - @trigger c.event.sort + ':mod', this - @trigger c.event.change, this - - return this - - eachMod: (callback)-> - for mod in @_mods - callback mod - - getMod: (slug)-> - for mod in @_mods - return mod if mod.slug is slug - return null - - getAllMods: -> - return @_mods[..] - - removeMod: (mod)-> - index = @_mods.indexOf mod - return unless index >= 0 - - @_mods.splice index, 1 - - @trigger c.event.remove, this, mod.slug - @trigger c.event.change, this - - # Name Methods ################################################################################# - - findName: (slug, options={})-> - options.includeDisabled ?= false - - for mod in @_mods - continue unless mod.enabled or options.includeDisabled - name = mod.findName slug - return name if name - - return null - - # Recipe Methods ############################################################################### - - findRecipes: (itemSlug, options={})-> - options.alwaysFromOwningMod ?= false - return null unless itemSlug? - - key = "#{itemSlug}-#{options.alwaysFromOwningMod}" - @_cache.recipesBySlug ?= {} - result = @_cache.recipesBySlug[key] - return result if result? - - result = [] - for mod in @_mods - if not mod.enabled - owningMod = itemSlug.isQualified and (itemSlug.mod is mod.slug) - continue unless owningMod and options.alwaysFromOwningMod - - mod.findRecipes itemSlug, result, options - - @_cache.recipesBySlug[key] = result - return if result.length > 0 then result else null - - # Object Overrides ############################################################################# - - toString: -> - return "ModPack (#{@cid}) {modVersions:«#{@_mods.length} items»}" - - # Private Methods ############################################################################## - - _onModVersionLoaded: (modVersion)-> - mods = @getAllMods() - return true unless mods.length > 0 - - for mod in mods - if mod.isError - @removeMod mod - continue - - modVersions = mod.getAllModVersions() - return true unless modVersions.length > 0 - continue if mod.activeVersion is Mod.Version.None - - activeModVersion = mod.activeModVersion - return true unless activeModVersion? - return true if activeModVersion.isUnloaded - return true if activeModVersion.isLoading - - @trigger c.event.change, this - @trigger c.event.sync, this diff --git a/src/client/models-old/game/mod_version.coffee b/src/client/models-old/game/mod_version.coffee deleted file mode 100644 index 7d5268406..000000000 --- a/src/client/models-old/game/mod_version.coffee +++ /dev/null @@ -1,200 +0,0 @@ -# -# Crafting Guide - mod_version.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' -Item = require './item' -ItemSlug = require './item_slug' -Recipe = require './recipe' - -######################################################################################################################## - -module.exports = class ModVersion extends BaseModel - - constructor: (attributes={}, options={})-> - if not attributes.modSlug? then throw new Error 'attributes.modSlug is required' - if not attributes.version? then throw new Error 'attributes.version is required' - attributes.mod ?= null - super attributes, options - - @_groups = {} - @_items = {} - @_names = {} - @_recipes = {} - @_slugs = [] - - # Public Methods ############################################################################### - - compareTo: (that)-> - if this.mod? and that.mod? - return this.mod.compareTo that.mod - - if this.modSlug isnt that.modSlug - return if this.modSlug < that.modSlug then -1 else +1 - - return 0 - - sort: -> - @_slugs.sort (a, b)-> ItemSlug.compare a, b - - # Item Methods ################################################################################# - - addItem: (item)-> - if @findItem(item.slug)? then throw new Error "duplicate item for #{item.name}" - - item.modVersion = this - @_items[item.slug.item] = item - @_groups[item.group] ?= {} - @_groups[item.group][item.slug.item] = item - - @registerName item.slug, item.name - return this - - allItemsInGroup: (group)-> - result = [] - @eachItemInGroup group, (item)-> result.push item - return null if result.length is 0 - return result - - chooseRandomItem: -> - itemIndex = Math.floor Math.random() * @_slugs.length - return @_slugs[itemIndex] - - eachItem: (callback)-> - for slug in @_slugs - item = @findItem slug - continue unless item? - callback item - return this - - eachItemInGroup: (group, callback)-> - itemMap = @_groups[group] - return unless itemMap? - - items = _.values(itemMap).sort (a, b)-> a.compareTo b - for item in items - callback item - - findItem: (itemSlug)-> - return @_items[itemSlug.item] - - findItemByName: (name)-> - for itemSlug, item of @_items - return item if item.name is name - return null - - # Group Methods ################################################################################ - - getAllGroups: -> - result = [] - @eachGroup (group)-> result.push group - return result - - eachGroup: (callback)-> - groupNames = _.keys @_groups - groupNames.sort (a, b)-> - if a is b then return 0 - if a is Item.Group.Other then return -1 - if b is Item.Group.Other then return +1 - return if a < b then -1 else +1 - - for groupName in groupNames - callback groupName - - # Name Methods ################################################################################# - - eachName: (callback)-> - for slug in @_slugs - callback @_names[slug.item], slug - return this - - findName: (itemSlug)-> - return @_names[itemSlug.item] - - registerName: (itemSlug, name)-> - return if @_names[itemSlug.item] - @_names[itemSlug.item] = name - @_slugs.push itemSlug - return this - - # Recipe Methods ############################################################################### - - addRecipe: (recipe)-> - return unless recipe? - - recipe.modVersion = this - if @_recipes[recipe.slug]? then throw new Error "duplicate recipe: #{recipe.slug}" - - @_recipes[recipe.slug] = recipe - return this - - eachRecipe: (callback)-> - recipes = _.values(@_recipes).sort (a, b)-> Recipe.compareFor a, b - for recipe in recipes - callback recipe - return this - - findRecipes: (itemSlug, result=[], options={})-> - options.onlyPrimary ?= false - options.forCrafting ?= false - - primaryRecipes = [] - otherRecipes = [] - - for recipe in _.values @_recipes - continue unless recipe.isConditionSatisfied() - continue unless recipe.hasAllTools() - continue if options.forCrafting and recipe.ignoreDuringCrafting - - if recipe.itemSlug.matches itemSlug - primaryRecipes.push recipe - else if recipe.produces itemSlug - otherRecipes.push recipe - - for recipe in primaryRecipes - result.push recipe - - if not options.onlyPrimary and result.length is 0 - for recipe in otherRecipes - result.push recipe - - return result - - findExternalRecipes: -> - result = {} - for k, recipe of @_recipes - continue if recipe.itemSlug.isQualified - - recipeList = result[recipe.itemSlug] - if not recipeList then recipeList = result[recipe.itemSlug] = [] - - recipeList.push recipe - - return result - - hasRecipes: (itemSlug)-> - for k, recipe of @_recipes - return true if recipe.produces itemSlug - return false - - # Backbone.Model Overrides ##################################################################### - - parse: (text)-> - ModVersionParser = require '../parsing/mod_version_parser' # to avoid require cycles - @_parser ?= new ModVersionParser model:this - @_parser.parse text - - return null # prevent calling `set` - - url: -> - return c.url.modVersionData modSlug:@modSlug, modVersion:@version - - # Object Overrides ############################################################################# - - toString: -> - return "ModVersion (#{@cid}) { - modSlug:#{@modSlug}, version:#{@version}, items:«#{@_slugs.length} items» - }" diff --git a/src/client/models-old/game/multiblock.coffee b/src/client/models-old/game/multiblock.coffee deleted file mode 100644 index 273dfd702..000000000 --- a/src/client/models-old/game/multiblock.coffee +++ /dev/null @@ -1,85 +0,0 @@ -# -# Crafting Guide - multiblock.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' -Inventory = require './inventory' - -######################################################################################################################## - -module.exports = class Multiblock extends BaseModel - - constructor: (attributes={}, options={})-> - if not attributes.input? then throw new Error 'attributes.input is required' - if not attributes.layers? then throw new Error 'attributes.layers is required' - if attributes.layers.length < 1 then throw new Error 'attributes.layers.length must be >= 1' - super attributes, options - - @_analyzePattern() - - # Public Methods ############################################################################### - - getStackAt: (x, y, z)-> - value = @_stackCache[y]?[z]?[x] - return null if value is undefined - return value - - getLayerInventory: (y)-> - @_layerInventories ?= [] - result = @_layerInventories[y] - if not result? then result = @_layerInventories[y] = new Inventory - return result - - # Property Methods ############################################################################# - - Object.defineProperties @prototype, - depth: - get: -> @_depth - - height: - get: -> @_height - - inventory: - get: -> @_inventory - - width: - get: -> @_width - - # Private Methods ############################################################################## - - _analyzeLayer: (layer, y, stackCacheLayer)-> - rows = layer.split ' ' - @_depth = Math.max @_depth, rows.length - - for row in rows - @_width = Math.max @_width, row.length - stackCacheRow = [] - stackCacheLayer.push stackCacheRow - @_analyzeRow row, stackCacheRow, @getLayerInventory(y) - - _analyzePattern: -> - @_depth = @_height = @_width = 0 - @_inventory = new Inventory - @_stackCache = [] - - for layer, y in @layers - stackCacheLayer = [] - @_stackCache.push stackCacheLayer - @_analyzeLayer layer, y, stackCacheLayer - - @_height = @layers.length - - _analyzeRow: (row, stackCacheRow, layerInventory)-> - for cell, x in row.split '' - index = parseInt cell - stack = null - - if not _.isNaN index - stack = @input[index] - @_inventory.add stack.itemSlug, stack.quantity - layerInventory.add stack.itemSlug, stack.quantity - - stackCacheRow.push stack diff --git a/src/client/models-old/game/recipe.coffee b/src/client/models-old/game/recipe.coffee deleted file mode 100644 index a3416a42f..000000000 --- a/src/client/models-old/game/recipe.coffee +++ /dev/null @@ -1,247 +0,0 @@ -# -# Crafting Guide - recipe.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' -ItemSlug = require './item_slug' -Stack = require './stack' -{StringBuilder} = require 'crafting-guide-common' - -######################################################################################################################## - -module.exports = class Recipe extends BaseModel - - constructor: (attributes={}, options={})-> - if not attributes.input? then throw new Error 'attributes.input is required' - if not attributes.pattern? then throw new Error 'attributes.pattern is required' - - if attributes.itemSlug? and not attributes.output? - attributes.output = [new Stack itemSlug:attributes.itemSlug, quantity:1] - else if attributes.output? and not attributes.itemSlug? - if attributes.output.length is 0 then throw new Error 'attributes.output cannot be empty' - attributes.itemSlug = attributes.output[0].itemSlug - else - throw new Error 'attributes.itemSlug or attributes.output is required' - - attributes.pattern = @_parsePattern attributes.pattern - - attributes.condition ?= null - attributes.ignoreDuringCrafting ?= false - attributes.modVersion ?= null - attributes.tools ?= [] - options.logEvents ?= false - super attributes, options - - @_computeQuantities attributes.pattern - - @on c.event.change + ':modVersion', => @_slug = null - @on c.event.change + ':pattern', => @_patternCache = null - - # Class Methods ################################################################################ - - @compareFor: (a, b, itemSlug)-> - if itemSlug? - aValue = a.itemSlug.matches itemSlug - bValue = b.itemSlug.matches itemSlug - if aValue isnt bValue - return -1 if aValue - return +1 if bValue - - aValue = a.getQuantityProduced itemSlug - bValue = b.getQuantityProduced itemSlug - if aValue isnt bValue - return if aValue > bValue then -1 else +1 - - return 0 - - # Public Methods ############################################################################### - - getStackAtSlot: (patternSlot)-> - trueIndex = 0:0, 1:1, 2:2, 3:4, 4:5, 5:6, 6:8, 7:9, 8:10 - patternDigit = @pattern[trueIndex[patternSlot]] - return null unless patternDigit? - return null unless patternDigit.match /[0-9]/ - - stack = @input[parseInt(patternDigit)] - return null unless stack? - - return stack - - getQuantityProduced: (itemSlug)-> - total = 0 - for stack in @output - if stack.itemSlug.matches itemSlug - total += stack.quantity - - return total - - getQuantityRequired: (itemSlug)-> - total = 0 - for stack, index in @input - if ItemSlug.equal stack.itemSlug, itemSlug - total += @_quantities[index] * stack.quantity - - return total - - hasAllTools: (modPack)-> - modPack ?= @modVersion?.mod?.modPack - return true unless modPack? - - for stack in @tools - return false unless modPack.findItem stack.itemSlug - return true - - isConditionSatisfied: (modPack)-> - return true unless @condition? - modPack ?= @modVersion?.mod?.modPack - - result = false - if @condition.verb is 'item' - if modPack?.findItemByName(@condition.noun)? - result = true - else if @condition.verb is 'mod' - modPack.eachMod (mod)=> - if mod.name is @condition.noun - result = true - - if @condition.inverted then result = not result - return result - - isPassThroughFor: (itemSlug)-> - return @getQuantityProduced(itemSlug) is @getQuantityRequired(itemSlug) - - produces: (itemSlug)-> - if not @_produces? - @_produces = {} - - for stack in @output - actuallyProduces = not @isPassThroughFor stack.itemSlug - @_produces[stack.itemSlug.qualified] = actuallyProduces - - result = @_produces[itemSlug.qualified] or @_produces[itemSlug.item] - return result - - requires: (itemSlug)-> - for stack in @input - if stack.itemSlug.matches itemSlug - return true - return false - - requiresTool: (itemSlug)-> - for stack in @tools - if stack.itemSlug.matches itemSlug - return true - - # Property Methods ############################################################################# - - Object.defineProperties @prototype, - - slug: - get: -> - if not @_slug? - builder = new StringBuilder - delimiterNeeded = false - for stack in @input - if delimiterNeeded then builder.push ',' - delimiterNeeded = true - - if stack.quantity > 1 then builder.push stack.quantity, ' ' - builder.push stack.itemSlug.qualified - - builder.push '>' - builder.push @pattern - builder.push '>' - for stack in @tools - builder.push stack.itemSlug.qualified - builder.push '>' - - delimiterNeeded = false - for stack in @output - if delimiterNeeded then builder.push ',' - delimiterNeeded = true - - if stack.quantity > 1 then builder.push stack.quantity, ' ' - builder.push stack.itemSlug.qualified - - @_slug = builder.toString() - - return @_slug - - # Object Overrides ############################################################################# - - toString: -> - result = [@constructor.name, " (", @cid, ") { name:", @name] - - result.push ", input:[" - needsDelimiter = false - for stack in @input - if needsDelimiter then result.push ', ' - result.push @getQuantityRequired stack.itemSlug - result.push ' ' - result.push stack.itemSlug - needsDelimiter = true - result.push ']' - - result.push ", output:[" - needsDelimiter = false - for stack in @output - if needsDelimiter then result.push ', ' - result.push @getQuantityProduced stack.itemSlug - result.push ' ' - result.push stack.itemSlug - needsDelimiter = true - result.push ']' - - if @tools.length > 0 - result.push ", tools:[" - needsDelimiter = false - for stack in @tools - if needsDelimiter then result.push ', ' - result.push stack.toString() - needsDelimiter = true - result.push ']' - - result.push '}' - return result.join '' - - # Private Methods ############################################################################## - - _computeQuantities: (pattern)-> - quantityMap = {} - - index = 0 - while index < pattern.length - c = pattern[index] - index += 1 - - continue if c is '.' - continue if c is ' ' - - if quantityMap[c]? - quantityMap[c] += 1 - else - quantityMap[c] = 1 - - @_quantities = [] - for i in [0...@input.length] - @_quantities.push quantityMap["#{i}"] - - _parsePattern: (pattern)-> - return unless pattern? - - pattern = pattern.replace /\ /g, '' - return if pattern.length is 0 - - pattern = pattern.replace /[^0-9]/g, '.' - - array = pattern.split '' - array = array[0...9] - while array.length isnt 9 - array.push '.' - - pattern = array.join '' - pattern = pattern.replace /(...)(...)(...)/, '$1 $2 $3' - return pattern diff --git a/src/client/models-old/game/simple_stack.coffee b/src/client/models-old/game/simple_stack.coffee deleted file mode 100644 index d077f4c58..000000000 --- a/src/client/models-old/game/simple_stack.coffee +++ /dev/null @@ -1,33 +0,0 @@ -# -# Crafting Guide - simple_stack.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -ItemSlug = require './item_slug' - -######################################################################################################################## - -module.exports = class Stack - - constructor: (attributes={}, options={})-> - if not attributes.itemSlug? then throw new Error 'attributes.itemSlug is required' - attributes.quantity ?= 1 - - @itemSlug = attributes.itemSlug - @quantity = attributes.quantity - - # Class Methods ################################################################################ - - @compare: (a, b)-> - if a? and not b? then return -1 - if not a? and b? then return +1 - if a.quantity isnt b.quantity - return if a.quantity > b.quantity then -1 else +1 - return ItemSlug.compare a.itemSlug, b.itemSlug - - # Object Overrides ############################################################################# - - toString: -> - return "#{@quantity} #{@itemSlug}" diff --git a/src/client/models-old/game/stack.coffee b/src/client/models-old/game/stack.coffee deleted file mode 100644 index 6797330dd..000000000 --- a/src/client/models-old/game/stack.coffee +++ /dev/null @@ -1,23 +0,0 @@ -# -# Crafting Guide - stack.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' - -######################################################################################################################## - -module.exports = class Stack extends BaseModel - - constructor: (attributes={}, options={})-> - if not attributes.itemSlug? then throw new Error 'attributes.itemSlug is required' - attributes.quantity ?= 1 - options.logEvents ?= false - super attributes, options - - # Object Overrides ############################################################################# - - toString: -> - return "#{@quantity} #{@itemSlug}" diff --git a/src/client/models-old/parsing/command_parser_version_base.coffee b/src/client/models-old/parsing/command_parser_version_base.coffee deleted file mode 100644 index 00e0e0ab0..000000000 --- a/src/client/models-old/parsing/command_parser_version_base.coffee +++ /dev/null @@ -1,138 +0,0 @@ -# -# Crafting Guide - command_parser_version_base.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -{StringBuilder} = require 'crafting-guide-common' - -######################################################################################################################## - -module.exports = class CommandParserVersionBase - - constructor: (options={})-> - if not options.model? then throw new Error 'options.model is required' - options.showAllErrors ?= false - - @_model = options.model - @_showAllErrors = options.showAllErrors - @errors = [] - - # Class Methods ################################################################################ - - @COMMAND = /\ *([^:]*):?(.*)/ - - @COMMENT = /([^\\]?)#.*/ - - @simplify: (text)-> - text = text.trim() - text = text.replace /\ */g , ' ' - text = text.replace /\n/g, ';' - text = text.replace /; */g, ';' - text = text.replace /;;*/g, ';' - text = text.replace /: /g, ':' - return text - - # Public Methods ############################################################################### - - parse: (text)-> - @_rawData = {} - @_lineNumber = 1 - @errors = [] - - @_lines = text.split '\n' - @_lineNumber = 0 - while @_lineNumber < @_lines.length - @_lineNumber += 1 - commands = @_parseLine @_lines[@_lineNumber - 1] - for command in commands - @_handleErrors @_execute, command - - @_handleErrors @_buildModel, @_rawData, @_model - return @_model - - unparse: -> - builder = new StringBuilder context:@_model - @_unparseModel builder, @_model - return builder.toString() - - # Subclass Methods ############################################################################# - - _buildModel: (rawData, model)-> - throw new Error 'Subclasses must override this method' - - _unparseModel: (builder, model)-> - throw new Error 'Subclasses must override this method' - - _command_schema: -> # do nothing - - # Private Methods ############################################################################## - - _execute: (command)-> - method = this["_command_#{command.name}"] - if not method? then throw new Error "Unknown command: #{command.name}" - - @_handleErrors method, command.args - - _parseLine: (line)-> - line = line.replace CommandParserVersionBase.COMMENT, '$1' - line = line.trim() - return [] if line.length is 0 - - [line, hereDoc] = @_parseHereDoc line - - lineParts = (part.trim() for part in line.split(';')) - commands = [] - for linePart in lineParts - continue if linePart.length is 0 - - match = CommandParserVersionBase.COMMAND.exec linePart - if not match? then throw new Error "Expected : , but found: \"#{linePart}\"" - - args = [] - args = (s for s in match[2].split(',') when s.length > 0) if match[2]? - args = (s.trim() for s in args) - args = (s for s in args when s.length > 0) - args.push hereDoc if hereDoc? - commands.push name:match[1], args:args - - return commands - - _handleErrors: (callback, args...)-> - if args.length is 1 and _.isArray(args[0]) then args = args[0] - - try - callback.apply this, args - catch e - e.message = "line #{@_lineNumber}: #{e.message}" - if not @_showAllErrors then throw e - @errors.push e - logger.error -> e.message - - _parseHereDoc: (line)-> - hereDocIndex = line.indexOf '<<-' - return [line, null] unless hereDocIndex isnt -1 - - hereDocStopText = line[hereDocIndex+3...line.length] - line = line[0...hereDocIndex] - - hereDocLines = [] - while true - @_lineNumber += 1 - break if @_lineNumber >= @_lines.length - - nextLine = @_lines[@_lineNumber-1] - break if nextLine.trim() is hereDocStopText - hereDocLines.push nextLine - - shortestIndent = Number.MAX_VALUE - for hereDocLine in hereDocLines - continue if hereDocLine.trim().length is 0 - shortestIndent = Math.min hereDocLine.match(/( *).*/)[1].length, shortestIndent - - for i in [0...hereDocLines.length] - hereDocLines[i] = hereDocLines[i][shortestIndent..] - - return [line, null] unless hereDocLines.length > 0 - return [line, hereDocLines.join('\n')] diff --git a/src/client/models-old/parsing/command_parser_version_base.test.coffee b/src/client/models-old/parsing/command_parser_version_base.test.coffee deleted file mode 100644 index 903e5adef..000000000 --- a/src/client/models-old/parsing/command_parser_version_base.test.coffee +++ /dev/null @@ -1,48 +0,0 @@ -# -# Crafting Guide - command_parser_version_base.test.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -CommandParserVersionBase = require './command_parser_version_base' - -######################################################################################################################## - -parser = null - -######################################################################################################################## - -describe 'command_parser_version_base.coffee', -> - - beforeEach -> parser = new CommandParserVersionBase model:{} - - describe '_parseHereDoc', -> - - it 'returns null for non-heredoc lines', -> - result = parser._parseHereDoc 'foobar: baz' - expect(result[1]).to.be.null - - it 'identifies the right text for a real heredoc', -> - parser._lines = ['command: <<-END', 'alpha', 'bravo', 'charlie', 'END', 'command1: arg2'] - parser._lineNumber = 1 - - result = parser._parseHereDoc parser._lines[0] - result[0].should.equal 'command: ' - result[1].should.equal 'alpha\nbravo\ncharlie' - - it 'identifies an empty heredoc', -> - parser._lines = ['command: <<-END', 'END'] - parser._lineNumber = 1 - - result = parser._parseHereDoc parser._lines[0] - result[0].should.equal 'command: ' - expect(result[1]).to.be.null - - it 'trims smallest leading whitespace', -> - parser._lines = ['command: <<-END', ' alpha', ' bravo', '', ' charlie', 'END', 'command1: arg2'] - parser._lineNumber = 1 - - result = parser._parseHereDoc parser._lines[0] - result[0].should.equal 'command: ' - result[1].should.equal 'alpha\n bravo\n\ncharlie' diff --git a/src/client/models-old/parsing/item_parser.coffee b/src/client/models-old/parsing/item_parser.coffee deleted file mode 100644 index eb0d5cfa0..000000000 --- a/src/client/models-old/parsing/item_parser.coffee +++ /dev/null @@ -1,19 +0,0 @@ -# -# Crafting Guide - item_parser.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -VersionedParserBase = require './versioned_parser_base' -ItemParserV1 = require './item_parser_v1' - -######################################################################################################################## - -module.exports = class ItemParser extends VersionedParserBase - - # VersionedParserBase Overrides ################################################################ - - _createParsers: (options)-> - return result = - '1': new ItemParserV1 options diff --git a/src/client/models-old/parsing/item_parser_v1.coffee b/src/client/models-old/parsing/item_parser_v1.coffee deleted file mode 100644 index 32c9a6a95..000000000 --- a/src/client/models-old/parsing/item_parser_v1.coffee +++ /dev/null @@ -1,72 +0,0 @@ -# -# Crafting Guide - item_parser_v1.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -CommandParserVersionBase = require './command_parser_version_base' - -######################################################################################################################## - -module.exports = class ItemParserV1 extends CommandParserVersionBase - - # CommandParserVersionBase Overrides ########################################################### - - _buildModel: (rawData, model)-> - @_buildItem rawData, model - - _unparseModel: (builder, model)-> - builder.line 'schema: ', 1 - builder.line() - - @_unparseItem builder, model - - # Command Methods ############################################################################## - - _command_description: (textParts...)-> - if not @_rawData.description? - @_rawData.description = '' - else - @_rawData.description += '\n' - @_rawData.description += textParts.join ', ' - - _command_officialUrl: (officialUrl)-> - if @_rawData.officialUrl? then throw new Error 'duplicate declaration of "officialUrl"' - if not officialUrl? or (officialUrl.length is 0) then throw new Error 'officialUrl cannot be empty' - @_rawData.officialUrl = officialUrl - - _command_video: (youTubeId, nameParts...)-> - if not youTubeId?.length then throw new Error 'video declaration requires a YouTubeID' - name = nameParts.join ', ' - if not name?.length then throw new Error 'video declaration requires a name' - - @_rawData.videos ?= [] - @_rawData.videos.push youTubeId:youTubeId, name:name - - # Object Building Methods ###################################################################### - - _buildItem: (rawData, model)-> - model.description = rawData.description if rawData.description? - model.officialUrl = rawData.officialUrl if rawData.officialUrl? - model.videos = rawData.videos if rawData.videos? - - # Un-parsing Methods ########################################################################### - - _unparseItem: (builder, model)-> - if model.officialUrl? - builder.line 'officialUrl: ', model.officialUrl - builder.line() - - if model.description? - if model.description.indexOf('\n') isnt -1 - builder.line 'description: <<-END' - builder.line model.description - builder.line 'END' - else - builder.line 'description: ', model.description - builder.line() - - for video in model.videos - builder.line 'video: ', video.youTubeId, ', ', video.name - builder.line() diff --git a/src/client/models-old/parsing/item_parser_v1.test.coffee b/src/client/models-old/parsing/item_parser_v1.test.coffee deleted file mode 100644 index 25f6e7f5c..000000000 --- a/src/client/models-old/parsing/item_parser_v1.test.coffee +++ /dev/null @@ -1,99 +0,0 @@ -# -# Crafting Guide - item_parser_v1.test.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -Item = require '../game/item' -ItemParserV1 = require './item_parser_v1' - -######################################################################################################################## - -baseText = item = parser = null - -######################################################################################################################## - -describe 'item_parser_v1.coffee', -> - - beforeEach -> - item = new Item name:'alpha' - parser = new ItemParserV1 model:item - - describe 'officialUrl', -> - - it 'may be omitted', -> - parser.parse 'schema: 1\nvideo: youtubeid, Video Alpha\ndescription: Bravo, Charlie' - expect(item.officialUrl).to.be.null - - it 'is assigned properly when given', -> - parser.parse 'schema: 1\nofficialUrl: http://testurl.com' - item.officialUrl.should.equal 'http://testurl.com' - - it 'does not allow duplicate declarations', -> - func = -> parser.parse 'schema: 1\nofficialUrl: http://testurl.com\nofficialUrl: http://testurl2.com' - expect(func).to.throw Error, 'duplicate' - - it 'does not allow an empty value if given', -> - func = -> parser.parse 'schema: 1\nofficialUrl:' - expect(func).to.throw Error, 'empty' - - describe 'description', -> - - it 'may be omitted', -> - parser.parse 'schema: 1\nvideo: youTubeId, Video Alpha\nofficialUrl: http://testurl.com' - expect(item.description).to.be.null - - it 'is assigned properly when given', -> - parser.parse 'schema: 1\ndescription: Alpha Bravo Charlie' - item.description.should.equal 'Alpha Bravo Charlie' - - it 'can be a heredoc', -> - parser.parse 'schema: 1\ndescription: <<-END\nAlpha\nBravo\nCharlie\nEND' - item.description.should.equal 'Alpha\nBravo\nCharlie' - - it 'concatenates multiple declarations', -> - parser.parse 'schema: 1\ndescription: Alpha\ndescription: Bravo' - item.description.should.equal 'Alpha\nBravo' - - describe 'video', -> - - it 'may be omitted', -> - parser.parse 'schema: 1\nofficialUrl: http://testurl.com\ndescription: Alpha Bravo Charlie' - item.videos.should.eql [] - - it 'is assigned properly when given', -> - parser.parse 'schema: 1\nvideo: youtubeid, Alpha Bravo' - item.videos[0].should.eql youTubeId:'youtubeid', name:'Alpha Bravo' - item.videos.length.should.equal 1 - - it 'may be included multiple times', -> - parser.parse 'schema: 1\nvideo: youtubeid1, Alpha\nvideo: youtubeid2, Bravo' - item.videos[0].should.eql youTubeId:'youtubeid1', name:'Alpha' - item.videos[1].should.eql youTubeId:'youtubeid2', name:'Bravo' - item.videos.length.should.equal 2 - - it 'requires a YouTubeId and name', -> - func = -> parser.parse 'schema: 1\nvideo: alpha' - expect(func).to.throw Error, 'requires a name' - - describe 'unparsing', -> - - it 'can round-trip a fully described item', -> - text = """ - schema: 1 - - officialUrl: http://testurl.com - - description: <<-END - Alpha - Bravo - END - - video: youtubeid1, Alpha Bravo - video: youtubeid2, Charlie Delta - - - """ - parser.parse text - parser.unparse().should.equal text diff --git a/src/client/models-old/parsing/mod_parser.coffee b/src/client/models-old/parsing/mod_parser.coffee deleted file mode 100644 index 03f368b96..000000000 --- a/src/client/models-old/parsing/mod_parser.coffee +++ /dev/null @@ -1,19 +0,0 @@ -# -# Crafting Guide - mod_parser.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -VersionedParserBase = require './versioned_parser_base' -ModParserV1 = require './mod_parser_v1' - -######################################################################################################################## - -module.exports = class ModParser extends VersionedParserBase - - # VersionedParserBase Overrides ################################################################ - - _createParsers: (options)-> - return result = - '1': new ModParserV1 options diff --git a/src/client/models-old/parsing/mod_parser_v1.coffee b/src/client/models-old/parsing/mod_parser_v1.coffee deleted file mode 100644 index f0f9ab5b8..000000000 --- a/src/client/models-old/parsing/mod_parser_v1.coffee +++ /dev/null @@ -1,94 +0,0 @@ -# -# Crafting Guide - mod_parser_v1.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -CommandParserVersionBase = require './command_parser_version_base' -Mod = require '../game/mod' -ModVersion = require '../game/mod_version' -Tutorial = require '../site/tutorial' - -######################################################################################################################## - -module.exports = class ModParserV1 extends CommandParserVersionBase - - # CommandParserVersionBase Overrides ########################################################### - - _buildModel: (rawData, model)-> - @_buildMod rawData, model - - _unparseModel: (builder, model)-> - @_unparseMod builder, model - - # Command Methods ############################################################################## - - _command_author: (authorParts...)-> - if @_rawData.author? then throw new Error 'duplicate declaration of "author"' - author = authorParts.join ', ' - if author.length is 0 then throw new Error '"author" cannot be empty, but may be omitted' - - @_rawData.author = author - - _command_description: (descriptionParts...)-> - if @_rawData.description? then throw new Error 'duplicate declaration of "description"' - description = descriptionParts.join ', ' - if description.length is 0 then throw new Error '"description" cannot be empty, but may be omitted' - - @_rawData.description = description - - _command_documentationUrl: (documentationUrl)-> - documentationUrl ?= '' - if @_rawData.documentationUrl? then throw new Error 'duplicate declaration of "documentationUrl"' - if documentationUrl.length is 0 then throw new Error 'documentationUrl cannot be empty (omit it instead)' - @_rawData.documentationUrl = documentationUrl - - _command_downloadUrl: (downloadUrl)-> - if @_rawData.downloadUrl? then throw new Error 'duplicate declaration of "downloadUrl"' - if downloadUrl.length is 0 then throw new Error 'downloadUrl cannot be empty (omit it instead)' - @_rawData.downloadUrl = downloadUrl - - _command_homePageUrl: (homePageUrl='')-> - if @_rawData.homePageUrl? then throw new Error 'duplicate declaration of "homePageUrl"' - if homePageUrl.length is 0 then throw new Error 'homePageUrl cannot be empty' - - @_rawData.homePageUrl = homePageUrl - - _command_name: (name)-> - if @_rawData.name? then throw new Error 'duplicate declaration of "name"' - if name.length is 0 then throw new Error '"name" cannot be empty' - @_rawData.name = name - - _command_tutorial: (nameParts...)-> - name = nameParts.join(', ').trim() - if name.length is 0 then throw new Error '"name" cannot be empty' - @_rawData.tutorialNames ?= [] - @_rawData.tutorialNames.push name - - _command_version: (version='')-> - if version.length is 0 then throw new Error 'version cannot be empty' - - @_rawData.versions ?= [] - @_rawData.versions.push version - - # Object Building Methods ###################################################################### - - _buildMod: (rawData, model)-> - if not rawData.name? then throw new Error 'the "name" declaration is required' - if not rawData.homePageUrl? then throw new Error 'the "homePageUrl" declaration is required' - if not rawData.versions? then throw new Error 'at least one "version" declaration is required' - - model.author = rawData.author if rawData.author? - model.description = rawData.description if rawData.description? - model.documentationUrl = rawData.documentationUrl if rawData.documentationUrl? - model.downloadUrl = rawData.downloadUrl if rawData.downloadUrl? - model.name = rawData.name - model.homePageUrl = rawData.homePageUrl - - if rawData.tutorialNames? - for tutorialName in rawData.tutorialNames - model.addTutorial new Tutorial name:tutorialName - - for version in rawData.versions - model.addModVersion new ModVersion modSlug:model.slug, version:version diff --git a/src/client/models-old/parsing/mod_version_parser.coffee b/src/client/models-old/parsing/mod_version_parser.coffee deleted file mode 100644 index 2ba90d6c7..000000000 --- a/src/client/models-old/parsing/mod_version_parser.coffee +++ /dev/null @@ -1,19 +0,0 @@ -# -# Crafting Guide - mod_version_parser.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -VersionedParserBase = require './versioned_parser_base' -ModVersionParserV1 = require './mod_version_parser_v1' - -######################################################################################################################## - -module.exports = class ModVersionParser extends VersionedParserBase - - # VersionedParserBase Overrides ################################################################ - - _createParsers: (options)-> - return result = - '1': new ModVersionParserV1 options diff --git a/src/client/models-old/parsing/mod_version_parser_v1.coffee b/src/client/models-old/parsing/mod_version_parser_v1.coffee deleted file mode 100644 index 9248b6ad8..000000000 --- a/src/client/models-old/parsing/mod_version_parser_v1.coffee +++ /dev/null @@ -1,380 +0,0 @@ -# -# Crafting Guide - mod_version_parser_v1.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -CommandParserVersionBase = require './command_parser_version_base' -Item = require '../game/item' -ItemSlug = require '../game/item_slug' -ModVersion = require '../game/mod_version' -Multiblock = require '../game/multiblock' -Recipe = require '../game/recipe' -Stack = require '../game/simple_stack' -{StringBuilder} = require 'crafting-guide-common' - -######################################################################################################################## - -module.exports = class ModVersionParserV1 extends CommandParserVersionBase - - # Class Methods ################################################################################ - - @INTEGER = /[0-9]+/ - - @PATTERN = /^[0-9.]{3} ?[0-9.]{3} ?[0-9.]{3}$/ - - @STACK = /^([0-9]+) +(.*)$/ - - # CommandParserVersionBase Overrides ########################################################### - - _buildModel: (rawData, model)-> - @_buildModVersion rawData, model - - _unparseModel: (builder, model)-> - @_unparseModVersion builder, model - - # Command Methods ############################################################################## - - _command_extras: (extraTerms...)-> - if not @_recipeData? then throw new Error 'cannot declare "extras" before "recipe"' - if @_recipeData.output.length isnt 1 then throw new Error 'duplicate declaration of "extras"' - - for term in extraTerms - @_recipeData.output.push @_parseStack term - - _command_gatherable: (gatherable)-> - if not @_itemData? then throw new Error 'cannot declare "gatherable" before "item"' - if @_itemData.gatherable? then throw new Error 'duplicate declaration of "gatherable"' - if not (gatherable in ['yes', 'no']) then throw new Error 'gatherable must be either "yes" or "no"' - - @_itemData.gatherable = (gatherable is 'yes') - - _command_group: (group)-> - if group.length is 0 then throw new Error 'a group name cannot be empty' - @_rawData.group = group - - _command_item: (name='')-> - if not name.length > 0 then throw new Error 'the item name cannot be empty' - - @_itemData = name:name, line:@_lineNumber, group:@_rawData.group, type:'new' - @_rawData.items ?= {} - @_rawData.items[name] = @_itemData - - @_recipeData = null - - _command_ignoreDuringCrafting: (value)-> - if not @_recipeData? then throw new Error 'cannot declare "ignoreDuringCrafting" before "recipe"' - if @_recipeData.ignoreDuringCrafting? then throw new Error 'duplicate declaration of "ignoreDuringCrafting"' - if not (value in ['yes', 'no']) then throw new Error 'ignoreDuringCrafting must be either "yes" or "no"' - - @_recipeData.ignoreDuringCrafting = (value is 'yes') - - _command_input: (stackDescriptions...)-> - activeData = if @_recipeData? then @_recipeData else @_multiblockData - - if not activeData? then throw new Error 'cannot declare "input" before "recipe" or "multiblock"' - if activeData.input.length isnt 0 then throw new Error 'duplicate declaration of "input"' - - for stackDescription in stackDescriptions - activeData.input.push @_parseStack stackDescription - - _command_layer: (layerText)-> - if not @_multiblockData? then throw new Error 'cannot declare "layer" before "multiblock"' - if not layerText? then throw new Error 'cannot have an empty layer' - if layerText.length is 0 then throw new Error 'cannot have an empty layer' - - @_multiblockData.layers.push layerText - - _command_multiblock: -> - if not @_itemData? then throw new Error 'cannot declare "multiblock" before "item"' - if @_itemData.multiblockData? then throw new Error 'duplicate declaration of "multiblock"' - - @_recipeData = null - @_multiblockData = input:[], layers:[], line:@_lineNumber - @_itemData.multiblockData = @_multiblockData - - _command_onlyIf: (condition)-> - words = condition.split ' ' - if words.length < 2 then throw new Error 'condition must include a verb followed by a noun' - - inverted = false - if words[0] is 'not' - inverted = true - words.shift() - - verb = words[0] - noun = words[1..].join ' ' - - if not (verb in ['item', 'mod']) then throw new Error "unknown verb: #{verb}" - @_recipeData.condition = verb:verb, noun:noun, inverted:inverted - - _command_pattern: (pattern='')-> - if not @_recipeData? then throw new Error 'cannot declare "pattern" before "recipe"' - if @_recipeData.pattern? then throw new Error 'duplicate declaration of "pattern"' - if not ModVersionParserV1.PATTERN.test pattern - throw new Error 'a pattern must have 9 digits using 0-9 for items and "." for an empty spot; - spaces are optional' - - @_recipeData.pattern = pattern - - _command_quantity: (quantity)-> - if not @_recipeData? then throw new Error 'cannot declare "quantity" before "recipe"' - if @_recipeData.quantity? then throw new Error 'duplicate declaration of "quantity"' - if not ModVersionParserV1.INTEGER.test(quantity) then throw new Error 'quantity must be an integer' - - @_recipeData.quantity = quantity - @_recipeData.output[0].quantity = parseInt quantity - - _command_recipe: -> - if not @_itemData? then throw new Error 'cannot delcare "recipe" before "item"' - - @_multiblockData = null - @_recipeData = line:@_lineNumber, input:[], output:[{quantity:1, name:@_itemData.name}], tools:[] - @_itemData.recipes ?= [] - @_itemData.recipes.push @_recipeData - - _command_tools: (toolNames...)-> - if not @_recipeData? then throw new Error 'cannot declare "tools" before "recipe"' - if @_recipeData.tools.length isnt 0 then throw new Error 'duplicate declaration of "tools"' - - for name in toolNames - if name.length is 0 then throw new Error 'tool names cannot be empty' - @_recipeData.tools.push name:name, quantity:1 - - _command_update: (name='')-> - if not name.length > 0 then throw new 'the item name cannot be empty' - - @_itemData = name:name, line:@_lineNumber, type:'update' - @_recipeData = null - - @_rawData.items ?= {} - @_rawData.items[name] = @_itemData - - # Parsing Helpers ############################################################################## - - _parseStack: (stackText)-> - match = ModVersionParserV1.STACK.exec stackText - if match? - return quantity:parseInt(match[1]), name:match[2] - else - return quantity:1, name:stackText - - # Object Creation Methods ###################################################################### - - _buildModVersion: (modVersionData, modVersion)-> - modVersionData.items ?= [] - - for itemName, itemData of modVersionData.items - @_handleErrors @_buildItem, modVersion, itemData - - modVersion.sort() - return modVersion - - _buildItem: (modVersion, itemData)-> - @_lineNumber = itemData.line - itemData.gatherable ?= false - itemData.ignoreDuringCrafting ?= false - itemData.recipes ?= [] - - if itemData.type is 'new' - item = new Item - name: itemData.name, - ignoreDuringCrafting: itemData.ignoreDuringCrafting, - isGatherable: itemData.gatherable, - group: itemData.group - modVersion.addItem item - itemData.slug = item.slug - else - itemData.slug = ItemSlug.slugify itemData.name - modVersion.registerName itemData.slug, itemData.name - - if itemData.multiblockData - item.multiblock = @_handleErrors @_buildMultiblock, modVersion, item, itemData.multiblockData - - for recipeData in itemData.recipes - @_handleErrors @_buildRecipe, modVersion, itemData, recipeData - - return item - - _buildMultiblock: (modVersion, item, multiblockData)-> - @_lineNumber = multiblockData.line - if multiblockData.layers.length is 0 then throw new Error '"multiblock" requires at least one "layer"' - if multiblockData.input.length is 0 then throw new Error '"multiblock" requires at least one "input"' - - input = @_buildStackList modVersion, multiblockData.input - multiblock = new Multiblock input:input, layers:multiblockData.layers - return multiblock - - _buildRecipe: (modVersion, itemData, recipeData)-> - @_lineNumber = recipeData.line - if recipeData.input.length is 0 then throw new Error 'the "input" declaration is required' - if not recipeData.pattern? then throw new Error 'the "pattern" declaration is required' - - recipe = new Recipe - condition: recipeData.condition - ignoreDuringCrafting: recipeData.ignoreDuringCrafting - input: @_buildStackList modVersion, recipeData.input, recipeData.pattern - output: @_buildStackList modVersion, recipeData.output - pattern: recipeData.pattern - tools: @_buildStackList modVersion, recipeData.tools - - modVersion.addRecipe recipe - return recipe - - _buildStackList: (modVersion, data, pattern=null)-> - createSlug = (name)=> - item = @_rawData.items[name] - if item? and item.type isnt 'update' - slug = new ItemSlug modVersion.modSlug, _.slugify name - else - slug = new ItemSlug name - modVersion.registerName slug, name - return slug - - stacks = [] - for stackData in data - itemSlug = createSlug stackData.name - stacks.push new Stack itemSlug:itemSlug, quantity:stackData.quantity - - if pattern? - expectedIndexes = _.reduce [0...stacks.length], ((obj, i)-> obj[i] = true; return obj), {} - for c in pattern - continue if c is '.' - continue if c is ' ' - delete expectedIndexes[c] - if not stacks[parseInt(c)]? then throw new Error "there is no item #{c} in this recipe" - - unusedNames = _.map(_.keys(expectedIndexes), ((i)-> data[parseInt(i)].name)) - if unusedNames.length > 1 - throw new Error "#{unusedNames.join(', ')} are listed for this recipe, but do not appear in the pattern" - else if unusedNames.length is 1 - throw new Error "#{unusedNames[0]} is listed for this recipe, but does not appear in the pattern" - - return stacks - - # Un-parsing Methods ########################################################################### - - _unparseModVersion: (builder, modVersion)-> - builder - .line 'schema: ', 1 - .line() - - modVersion.eachGroup (group)=> - @_unparseGroup builder, modVersion, group - - externalRecipes = modVersion.findExternalRecipes() - keys = _.keys(externalRecipes).sort() - for itemSlugText in keys - recipeList = externalRecipes[itemSlugText] - - builder - .line 'update: ', modVersion.findName ItemSlug.slugify(itemSlugText) - .indent() - .loop(recipeList, delimiter:'', onEach:(b, r)=> @_unparseRecipe(b, r)) - .outdent() - .line() - - _unparseGroup: (builder, modVersion, group)-> - if group isnt Item.Group.Other - builder - .line 'group: ', group - .line() - .indent() - - modVersion.eachItemInGroup group, (item)=> - @_unparseItem builder, modVersion, item - builder.line() - - if group isnt Item.Group.Other - builder.outdent() - - _unparseItem: (builder, modVersion, item)-> - recipes = modVersion.findRecipes item.slug, [], onlyPrimary:true - - builder - .line 'item: ', item.name - .indent() - .onlyIf item.isGatherable, => builder.line 'gatherable: yes' - .onlyIf item.multiblock?, => - builder - .indent() - .call => @_unparseMultiblock builder, item.multiblock - .outdent() - .onlyIf recipes.length > 0, => - builder.loop recipes, delimiter:'', onEach:(b, r)=> @_unparseRecipe(b, r) - .outdent() - - _unparseMultiblock: (builder, multiblock)-> - builder - .line 'multiblock:' - .indent() - .push "input: " - .call => @_unparseStackList builder, multiblock.input - .push ";\n" - .loop(multiblock.layers, delimiter:'', onEach:(builder, layer)=> builder.line "layer: #{layer}") - .outdent() - - _unparseRecipe: (builder, recipe)-> - inputStacks = recipe.input[..] - inputStacks.sort (a, b)-> Stack.compare a, b - inputNames = [] - for stack in inputStacks - name = builder.context.findName stack.itemSlug - if stack.quantity > 1 - inputNames.push "#{stack.quantity} #{name}" - else - inputNames.push name - - patternMap = {'.', '.'} - for i in [0...recipe.input.length] - stack = recipe.input[i] - name = builder.context.findName(stack.itemSlug) - name = "#{stack.quantity} #{name}" if stack.quantity > 1 - patternMap["#{i}"] = "#{inputNames.indexOf name}" - - pattern = recipe.pattern or recipe.defaultPattern - newPattern = [] - for c in pattern.split('') - newPattern.push patternMap[c] - newPattern = newPattern.join '' - newPattern = newPattern.replace /(...)(...)(...)/, '$1 $2 $3' - - quantity = recipe.output[0].quantity - - extraOutputs = recipe.output[0...recipe.output.length] - extraOutputs.shift() - - builder - .line 'recipe:' - .indent() - .onlyIf recipe.condition?, => - builder.push 'onlyIf: ' - .onlyIf recipe.condition.inverted, -> builder.push 'not ' - .line recipe.condition.verb, ' ', recipe.condition.noun - .onlyIf extraOutputs.length > 0, => - builder - .push 'extras: ' - .call => @_unparseStackList builder, extraOutputs - .line() - .onlyIf recipe.ignoreDuringCrafting, => builder.line 'ignoreDuringCrafting: yes' - .push 'input: ' - .loop inputNames - .line() - .line 'pattern: ', newPattern - .onlyIf quantity > 1, => builder.line 'quantity: ', quantity - .onlyIf recipe.tools.length > 0, => - builder - .push 'tools: ' - .call => @_unparseStackList builder, recipe.tools - .line() - .outdent() - - _unparseStackList: (builder, stackList)-> - if stackList.length is 1 and stackList[0].quantity is 1 - builder.push builder.context.findName(stackList[0].itemSlug) - else - builder.loop stackList, onEach:(b, stack)=> - builder - .onlyIf stack.quantity > 1, => builder.push stack.quantity, ' ' - .push builder.context.findName stack.itemSlug diff --git a/src/client/models-old/parsing/mod_version_parser_v1.test.coffee b/src/client/models-old/parsing/mod_version_parser_v1.test.coffee deleted file mode 100644 index 657f9bf60..000000000 --- a/src/client/models-old/parsing/mod_version_parser_v1.test.coffee +++ /dev/null @@ -1,344 +0,0 @@ -# -# Crafting Guide - mod_version_parser_v1.test.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -CommandParserVersionBase = require './command_parser_version_base' -ItemSlug = require '../game/item_slug' -ModVersion = require '../game/mod_version' -ModVersionParserV1 = require './mod_version_parser_v1' - -######################################################################################################################## - -baseText = modVersion = parser = null - -######################################################################################################################## - -describe 'mod_version_parser_v1.coffee', -> - - beforeEach -> - modVersion = new ModVersion modSlug:'test', version:'0.0' - parser = new ModVersionParserV1 model:modVersion - - describe 'Item', -> - - it 'allows multiple recipes', -> - recipes = "item: Charlie; - recipe:; input:Alpha; pattern:... .0. ...; - recipe:; input:Bravo; pattern:... 0.0 ...;" - modVersion = parser.parse recipes - recipes = modVersion.findRecipes ItemSlug.slugify 'test__charlie' - recipes[0].input[0].itemSlug.qualified.should.equal 'alpha' - recipes[1].input[0].itemSlug.qualified.should.equal 'bravo' - - describe 'name', -> - - it 'adds the name when present', -> - modVersion = parser.parse 'item: Charlie' - modVersion._items.charlie.name.should.equal 'Charlie' - - it 'requires a non-empty name', -> - func = -> parser.parse 'item: \n' - expect(func).to.throw Error, 'cannot be empty' - - describe 'gatherable', -> - - it 'adds "gatherable" when present', -> - modVersion = parser.parse 'item: Alpha Bravo; gatherable: yes' - modVersion._items.alpha_bravo.isGatherable.should.be.true - - it 'does not allow a duplicate "gatherable" declaration', -> - func = -> parser.parse 'item: Alpha Bravo; gatherable: yes; gatherable: yes' - expect(func).to.throw Error, 'duplicate' - - it 'requires "gatherable" to be "yes" or "no"', -> - func = -> parser.parse 'item: Alpha Bravo; gatherable: true' - expect(func).to.throw Error, 'gatherable must be' - - it 'does not allow "gatherable" before "item"', -> - func = -> parser.parse 'gatherable: yes; item: Alpha Bravo; gatherable: yes' - expect(func).to.throw Error, '"gatherable" before "item"' - - describe 'Multiblock', -> - - it 'adds a "multiblock" when present', -> - modVersion = parser.parse 'item: Alpha; multiblock:; input:Bravo; layer: 0' - item = modVersion.findItemByName 'Alpha' - item.multiblock.height.should.equal 1 - - it 'requires "item" be declared before "multiblock"', -> - func = -> parser.parse "multiblock:" - expect(func).to.throw Error, '"multiblock" before "item"' - - it 'prohibits multiple "multiblock" commands per item"', -> - func = -> parser.parse "item: Alpha; multiblock:; multiblock:" - expect(func).to.throw Error, 'duplicate' - - it 'prohibits multiblocks with no inputs', -> - func = -> parser.parse "item: Alpha; multiblock:; layer: 000" - expect(func).to.throw Error, 'at least one "input"' - - describe 'layer', -> - - it 'allows multiple "layer" commands', -> - modVersion = parser.parse 'item: Alpha; multiblock:; input:Bravo, Charlie; layer: 01 10; layer: 10 01' - item = modVersion.findItemByName 'Alpha' - item.multiblock.depth.should.equal 2 - item.multiblock.height.should.equal 2 - item.multiblock.width.should.equal 2 - - it 'prohibits empty layers', -> - func = -> parser.parse 'item: Alpha; multiblock:; input: Bravo; layer:; layer: 00 00' - expect(func).to.throw Error, 'empty layer' - - it 'prohibits multiblocks with no layers', -> - func = -> parser.parse "item: Alpha; multiblock:; input: Bravo" - expect(func).to.throw Error, 'at least one "layer"' - - describe 'Recipe', -> - - beforeEach -> baseText = 'item: Charlie; ' - - describe 'input', -> - - it 'adds "input" when present', -> - modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo; pattern: ... 010 ...' - charlieSlug = ItemSlug.slugify('test__charlie') - slugs = (s.itemSlug.item for s in modVersion.findRecipes(charlieSlug)[0].input) - slugs.should.eql ['alpha', 'bravo'] - - it 'requires an "input" declaration', -> - func = -> parser.parse baseText + 'recipe:; pattern: ... .0. ...' - expect(func).to.throw Error, 'the "input" declaration is required' - - it 'does not allow a duplicate "input" declaration', -> - func = -> parser.parse baseText + 'recipe:; input:Alpha; pattern:....0....; input:Bravo' - expect(func).to.throw Error, 'duplicate declaration of "input"' - - it 'does not allow "input" before "recipe"', -> - func = -> parser.parse baseText + 'input:Alpha, Bravo; recipe:; pattern:....0....' - expect(func).to.throw Error, 'cannot declare "input" before "recipe"' - - it 'registers slugs for each input name', -> - modVersion = parser.parse baseText + 'recipe:; input:Delta, Echo, Foxtrot; pattern:...012...' - (s.item for s in modVersion._slugs).should.eql ['charlie', 'delta', 'echo', 'foxtrot'] - - it 'correctly handles recipes which use the same input multiple times', -> - modVersion = parser.parse baseText + 'recipe:; input:Alpha; pattern:.0..0....' - recipe = _.values(modVersion._recipes)[0] - recipe.getQuantityRequired(ItemSlug.slugify('alpha')).should.equal 2 - - it 'allows a quantity for each input', -> - modVersion = parser.parse baseText + 'recipe:; input: 12 Delta, 3 Echo; pattern:... 0.1 ...' - recipe = _.values(modVersion._recipes)[0] - recipe.input[0].quantity.should.equal 12 - recipe.input[0].itemSlug.qualified.should.equal 'delta' - recipe.input[1].quantity.should.equal 3 - recipe.input[1].itemSlug.qualified.should.equal 'echo' - - describe 'pattern', -> - - it 'adds "pattern" when present', -> - modVersion = parser.parse baseText + 'recipe:; input:Alpha, Bravo; pattern:... .0. .1.' - modVersion.findRecipes(ItemSlug.slugify('test__charlie'))[0].pattern.should.equal '... .0. .1.' - - it 'requires a "pattern" declaration', -> - func = -> parser.parse baseText + 'recipe:; input:Alpha, Bravo' - expect(func).to.throw Error, 'the "pattern" declaration is required' - - it 'does not allow a duplicate "pattern" declaration', -> - func = -> parser.parse baseText + 'recipe:; input:Alpha, Bravo; pattern:....0..1.; pattern:01.......' - expect(func).to.throw Error, 'duplicate declaration of "pattern"' - - it 'requires pattern to be the right length', -> - func = -> parser.parse baseText + 'recipe:; input:Alpha; pattern:000' - expect(func).to.throw Error, 'a pattern must have' - - it 'requires pattern to only use proper characters', -> - func = -> parser.parse baseText + 'recipe:; input:Alpha; pattern:abc def ghi' - expect(func).to.throw Error, 'a pattern must have' - - it 'requires pattern to only refer to existing items', -> - func = -> parser.parse baseText + 'recipe:; input:Alpha; pattern:... 010 ...' - expect(func).to.throw Error, 'there is no item 1 in this recipe' - - it 'requires all items to appear in the pattern', -> - func = -> parser.parse baseText + 'recipe:; input:Alpha, Bravo; pattern: 000 0.0 000' - expect(func).to.throw Error, 'Bravo is listed' - - it 'does not allow "pattern" before "recipe"', -> - func = -> parser.parse baseText + 'pattern:... .0. ...; recipe:; inputs:Alpha' - expect(func).to.throw Error, 'cannot declare "pattern" before "recipe"' - - describe 'quantity', -> - - beforeEach -> - baseText = 'item: Charlie; recipe:; input:Alpha; pattern:...0.0...; ' - - it 'adds "quantity" when present', -> - modVersion = parser.parse baseText + 'quantity: 2' - modVersion.findRecipes(ItemSlug.slugify('test__charlie'))[0].output[0].quantity.should.equal 2 - - it 'does not allow a duplicate "quantity" declaration', -> - func = -> parser.parse baseText + 'quantity:1; quantity:2' - expect(func).to.throw Error, 'duplicate declaration of "quantity"' - - it 'requires quantity to be an integer', -> - func = -> parser.parse baseText + 'quantity:ten' - expect(func).to.throw Error, 'quantity must be an integer' - - it 'assumes a quantity of 1 by default', -> - modVersion = parser.parse baseText - modVersion.findRecipes(ItemSlug.slugify('test__charlie'))[0].output[0].quantity.should.equal 1 - - it 'does not allow "quantity" before recipe', -> - func = -> parser.parse 'item:Bravo; quantity:12; recipe:;' - expect(func).to.throw Error, 'cannot declare "quantity" before "recipe"' - - describe 'onlyIf', -> - - beforeEach -> - baseText = 'item: Charlie; recipe:; input:Alpha; pattern:...0.0...; ' - - it 'understands the "item" verb', -> - modVersion = parser.parse baseText + 'onlyIf: item Iron Ingot' - recipes = [] - modVersion.eachRecipe (recipe)-> recipes.push recipe - recipe = recipes[0] - recipe.condition.should.eql verb:'item', noun:'Iron Ingot', inverted:false - - it 'understands the "mod" verb', -> - modVersion = parser.parse baseText + 'onlyIf: mod BuildCraft' - recipes = [] - modVersion.eachRecipe (recipe)-> recipes.push recipe - recipe = recipes[0] - recipe.condition.should.eql verb:'mod', noun:'BuildCraft', inverted:false - - it 'understands inverting verbs', -> - modVersion = parser.parse baseText + 'onlyIf: not item Iron Ingot' - recipes = [] - modVersion.eachRecipe (recipe)-> recipes.push recipe - recipe = recipes[0] - recipe.condition.should.eql verb:'item', noun:'Iron Ingot', inverted:true - - it 'requires at least two words', -> - func = -> parser.parse baseText + 'onlyIf: item' - expect(func).to.throw Error, 'verb followed by a noun' - - it 'only allows known verbs', -> - func = -> parser.parse baseText + 'onlyIf: foo Iron Ingot' - expect(func).to.throw Error, 'unknown verb' - - describe 'output', -> - - beforeEach -> - baseText = 'item: Delta; item:Bravo; recipe:; input:Charlie; pattern:... .0. ...; ' - - it 'adds a single item as the default output', -> - modVersion = parser.parse baseText - stack = modVersion.findRecipes(ItemSlug.slugify('test__bravo'))[0].output[0] - stack.itemSlug.qualified.should.equal 'test__bravo' - stack.quantity.should.equal 1 - - it 'can add multiple extras with quantities', -> - modVersion = parser.parse baseText + 'extras:2 Delta, 4 Echo' - output = modVersion.findRecipes(ItemSlug.slugify('test__bravo'))[0].output - output[0].itemSlug.qualified.should.equal 'test__bravo' - output[0].quantity.should.equal 1 - output[1].itemSlug.qualified.should.equal 'test__delta' - output[1].quantity.should.equal 2 - output[2].itemSlug.qualified.should.equal 'echo' - output[2].quantity.should.equal 4 - - it 'does not allow "extras" before "recipe"', -> - func = -> parser.parse 'item:Bravo; extras:Charlie' - expect(func).to.throw Error, 'cannot declare "extras" before "recipe"' - - it 'registers slugs for each output name', -> - modVersion = parser.parse baseText + 'extras:Delta, Echo' - (s.qualified for s in modVersion._slugs).should.eql [ - 'test__bravo', 'charlie', 'test__delta', 'echo' - ] - - it 'does not allow a duplicate "extras" declaration', -> - func = -> parser.parse baseText + 'extras:Echo; extras:Delta' - expect(func).to.throw Error, 'duplicate declaration of "extras"' - - describe 'tools', -> - - beforeEach -> - baseText = 'item:Bravo; recipe:; input:Charlie; pattern:... .0. ...; ' - - it 'can add a single tool', -> - modVersion = parser.parse baseText + 'tools: Furnace' - modVersion.findRecipes(ItemSlug.slugify('test__bravo'))[0].tools[0].itemSlug.item.should.equal 'furnace' - - it 'can add multiple tools', -> - modVersion = parser.parse baseText + 'tools: Crafting Table, Furnace' - tools = modVersion.findRecipes(ItemSlug.slugify('test__bravo'))[0].tools - tools[0].itemSlug.item.should.equal 'crafting_table' - tools[1].itemSlug.item.should.equal 'furnace' - - it 'registers slugs for each tool name', -> - modVersion = parser.parse baseText + 'tools: Crafting Table, Furnace' - (s.item for s in modVersion._slugs).should.eql ['bravo', 'charlie', 'crafting_table', 'furnace'] - - it 'does not allow a duplicate "tools" declaration', -> - func = -> parser.parse baseText + 'tools:Crafting Table; tools:Furnace' - expect(func).to.throw Error, 'duplicate declaration of "tools"' - - describe "unparsing", -> - - beforeEach -> - baseText = """ - schema: 1 - - group: Agriculture - - item: Apple - - item: Baked Potato - recipe: - input: furnace fuel, Potato - pattern: .1. ... .0. - tools: Furnace - - item: (filled) Canned Food - recipe: - input: 4 (Empty) Tin Can, Apple - pattern: .1. .0. ... - - item: Pyramid - multiblock: - input: Cobblestone - layer: 000 000 000 - layer: ... .0. ... - - group: Functional Blocks - - item: Furnace - recipe: - input: Cobblestone - pattern: 000 0.0 000 - tools: Crafting Table - - update: Iron Ingot - recipe: - input: furnace fuel, Iron Dust - pattern: .1. ... .0. - tools: Furnace - recipe: - onlyIf: item Redstone Furnace - input: Iron Ore - pattern: ... .0. ... - tools: Redstone Furnace - """ - - it 'can round-trip a data file', -> - text = parser.unparse parser.parse baseText - actual = CommandParserVersionBase.simplify text - expected = CommandParserVersionBase.simplify baseText - - actual.should.equal expected diff --git a/src/client/models-old/parsing/tutorial_parser.coffee b/src/client/models-old/parsing/tutorial_parser.coffee deleted file mode 100644 index 40579a1aa..000000000 --- a/src/client/models-old/parsing/tutorial_parser.coffee +++ /dev/null @@ -1,19 +0,0 @@ -# -# Crafting Guide - tutorial_parser.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -VersionedParserBase = require './versioned_parser_base' -TutorialParserV1 = require './tutorial_parser_v1' - -######################################################################################################################## - -module.exports = class TutorialParser extends VersionedParserBase - - # VersionedParserBase Overrides ################################################################ - - _createParsers: (options)-> - return result = - '1': new TutorialParserV1 options diff --git a/src/client/models-old/parsing/tutorial_parser_v1.coffee b/src/client/models-old/parsing/tutorial_parser_v1.coffee deleted file mode 100644 index a3577ee54..000000000 --- a/src/client/models-old/parsing/tutorial_parser_v1.coffee +++ /dev/null @@ -1,65 +0,0 @@ -# -# Crafting Guide - tutorial_parser_v1.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -CommandParserVersionBase = require './command_parser_version_base' -Tutorial = require '../site/tutorial' - -######################################################################################################################## - -module.exports = class TutorialParserV1 extends CommandParserVersionBase - - # CommandParserVersionBase Overrides ########################################################### - - _buildModel: (rawData, model)-> - @_buildTutorial rawData, model - - _unparseModel: (builder, model)-> - @_unparseTutorial builder, model - - # Command Methods ############################################################################## - - _command_content: (contentParts...)-> - if not @_rawData.currentSection? then throw new Error 'cannot declare "title" before "section"' - if @_rawData.currentSection.content? then throw new Error 'duplicate declaration of content' - content = contentParts.join(', ').trim() - if not content.length > 0 then throw new Error 'content cannot be empty' - - @_rawData.currentSection.content = content - - _command_officialUrl: (officialUrl)-> - if @_rawData.officialUrl? then throw new Error 'duplicate declaration of "officialUrl"' - if officialUrl.length is 0 then throw new Error 'officialUrl cannot be empty' - @_rawData.officialUrl = officialUrl - - _command_section: (textParts...)-> - @_rawData.sections ?= [] - @_rawData.sections.push @_rawData.currentSection = {} - - _command_title: (titleParts...)-> - if not @_rawData.currentSection? then throw new Error 'cannot declare "title" before "section"' - if @_rawData.currentSection.title? then throw new Error 'duplicate declaration of title' - title = titleParts.join(', ').trim() - if not title.length > 0 then throw new Error 'title cannot be empty' - - @_rawData.currentSection.title = title - - _command_video: (youTubeId, nameParts...)-> - if not youTubeId?.length then throw new Error 'video declaration requires a YouTubeID' - name = nameParts.join ', ' - if not name?.length then throw new Error 'video declaration requires a name' - - @_rawData.videos ?= [] - @_rawData.videos.push youTubeId:youTubeId, name:name - - # Object Building Methods ###################################################################### - - _buildTutorial: (rawData, model)-> - if not rawData.sections? then throw new Error 'the "section" declaration is required' - - model.officialUrl = rawData.officialUrl - model.videos = rawData.videos - model.sections = rawData.sections diff --git a/src/client/models-old/parsing/versioned_parser_base.coffee b/src/client/models-old/parsing/versioned_parser_base.coffee deleted file mode 100644 index 6642420ad..000000000 --- a/src/client/models-old/parsing/versioned_parser_base.coffee +++ /dev/null @@ -1,51 +0,0 @@ -# -# Crafting Guide - versioned_parser_base.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class VersionedParserBase - - constructor: (options={})-> - @_parsers = @_createParsers options - @_currentSchema = _.chain(@_parsers).keys().last().value() - @errors = [] - - # Class Members ################################################################################ - - @SCHEMA = /schema: *([0-9]+)/ - - # Public Methods ############################################################################### - - parse: (text)-> - return unless text? - - schema = @_identifySchema text - parser = @_parsers[schema] - if not parser? then throw new Error "schema version #{schema} is not supported" - - parser.parse text - @errors = parser.errors - - return @_model - - unparse: (schema=null)-> - schema ?= @_currentSchema - - parser = @_parsers["#{schema}"] - if not parser? then throw new Error "version #{schema} is not supported" - - return parser.unparse() - - # Overridable Methods ########################################################################## - - _createParsers: (options)-> - throw new Error 'subclasses must override this method' - - _identifySchema: (text)-> - match = VersionedParserBase.SCHEMA.exec text - if not match? then throw new Error 'missing "schema" declaration' - return match[1] diff --git a/src/client/models-old/site/tutorial.coffee b/src/client/models-old/site/tutorial.coffee deleted file mode 100644 index 702f0d718..000000000 --- a/src/client/models-old/site/tutorial.coffee +++ /dev/null @@ -1,33 +0,0 @@ -# -# Crafting Guide - tutorial.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' - -######################################################################################################################## - -module.exports = class Tutorial extends BaseModel - - constructor: (attributes={}, options={})-> - if not attributes.name?.length > 0 then throw new Error "attributes.name cannot be empty" - attributes.modSlug ?= null - attributes.officialUrl ?= null - attributes.sections ?= [] - attributes.slug ?= _.slugify attributes.name - attributes.videos ?= [] - super attributes, options - - # Backbone.Model Overrides ##################################################################### - - parse: (text)-> - TutorialParser = require '../parsing/tutorial_parser' # to avoid require cycles - @_parser ?= new TutorialParser model:this - @_parser.parse text - - return null # prevent calling `set` - - url: -> - return c.url.tutorialData modSlug:@modSlug, tutorialSlug:@slug diff --git a/src/client/models/base_model.coffee b/src/client/models/base_model.coffee deleted file mode 100644 index 8da42e281..000000000 --- a/src/client/models/base_model.coffee +++ /dev/null @@ -1,129 +0,0 @@ -# -# Crafting Guide - base_model.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class BaseModel extends Backbone.Model - - @_loadingQueue = [] - @_isDraining = false - - constructor: (attributes={}, options={})-> - options.logEvents ?= true - super attributes, options - - makeGetter = (name)-> return -> @get name - makeSetter = (name)-> return (value)-> @set name, value - for name, value of attributes - continue if name is 'id' - Object.defineProperty this, name, get:makeGetter(name), set:makeSetter(name) - - @fileCache = options.fileCache or null - @loading = null - @logEvents = options.logEvents or false - @state = c.modelState.unloaded - - Object.defineProperties this, - isUnloaded: { get:-> @state is c.modelState.unloaded } - isLoading: { get:-> @state is c.modelState.loading } - isLoaded: { get:-> @state is c.modelState.loaded } - isError: { get:-> @state is c.modelState.error } - - # Event Methods ################################################################################ - - onLoadSucceeded: (text, status, xhr)-> - try - @set @parse text - - @state = c.modelState.loaded - @trigger c.event.change, this - @trigger c.event.sync, this - logger.info => "#{@constructor.name}.#{@cid} loaded successfully" - catch e - logger.error -> "A parsing error occured: #{e.stack}" - @onLoadFailed e.message, 'parsing failed', xhr - - onLoadFailed: (error, status, xhr)-> - @state = c.modelState.error - logger.error => "#{@constructor.name}.#{@cid} failed to load: status:#{status}, message:#{error}" - @trigger c.event.error, this, error - - # Backbone.Model Overrides ##################################################################### - - fetch: (options={})-> - options.force ?= false - return if (@isLoading or @isLoaded) and not options.force - - url = @url() - logger.info => "#{@constructor.name}.#{@cid} reading from url: #{url}" - - @state = c.modelState.loading - @trigger c.event.request, this - - loadFromServer = => - w.promise (resolve, reject)=> - $.ajax - url: url - dataType: 'text' - success: (text, status, xhr)=> resolve @onLoadSucceeded text, status, xhr - error: (xhr, status, error)=> reject @onLoadFailed error, status, xhr - - if @fileCache? - @loading = @fileCache.loading.then => - if @fileCache.hasFile url - return @_addToLoadingQueue @fileCache.getFile(url), 'success', {url:url} - else - @loading = loadFromServer() - else - @loading = loadFromServer() - - @loading.catch (e)-> # do nothing - return @loading - - parse: (text)-> - return JSON.parse text - - sync: (method, model)-> - throw new Error "#{@constructor.name}.#{@cid} is not permitted to #{method}" - - trigger: (name, model, args...)-> - if @logEvents - argText = ("#{arg}"[0..50] for arg in args).join ", " - logger.trace => "#{@constructor.name}.#{@cid} triggered event #{name} with args: #{argText}" - super - - # Object Overrides ############################################################################# - - toString: -> - return "#{@constructor.name}.#{@cid}" - - # Private Methods ############################################################################## - - _addToLoadingQueue: (text, status, xhr)-> - deferred = w.defer() - - BaseModel._loadingQueue.push resolve:deferred.resolve, func:(=> @onLoadSucceeded text, status, xhr) - @_drainLoadingQueue() - return deferred.promise - - _drainLoadingQueue: -> - return if @_isDraining - @_isDraining = true - - drainDelay = 50 - drain = => - toLoad = BaseModel._loadingQueue.shift() - if not toLoad? - @_isDraining = false - else - toLoad.func() - toLoad.resolve(true) - - _.delay drain, drainDelay - - _.delay drain, drainDelay - diff --git a/src/client/models/crafting/crafting_plan.coffee b/src/client/models/crafting/crafting_plan.coffee deleted file mode 100644 index 283bb073a..000000000 --- a/src/client/models/crafting/crafting_plan.coffee +++ /dev/null @@ -1,144 +0,0 @@ -# -# Crafting Guide - crafting_plan.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -Inventory = require "../game/inventory" -{StringBuilder} = require "crafting-guide-common" - -######################################################################################################################## - -module.exports = class CraftingPlan - - constructor: (attributes={})-> - @_id = _.uniqueId "crafting-plan-" - @_make = null - @_need = null - @have = attributes.have - @steps = attributes.steps - @want = attributes.want - - @_computeResources() - @_consolidateSteps() - - # Properties ################################################################################### - - Object.defineProperties @prototype, - - have: # an Inventory specifying what the player already has - get: -> return @_have - set: (have)-> - have ?= new Inventory - if @_have is have then return - if @_have? then throw new Error "have cannot be reassigned" - @_have = new Inventory have - - id: # a string uniquely specifying this crafting plan - get: -> return @_id - set: -> throw new Error "id is not assignabled" - - make: # an Inventory specifying what the results of executing the plan will be - get: -> return @_make - set: -> throw new Error "make cannot be assigned" - - need: # an Inventory specifying what the player will need to gather before executing the plan - get: -> return @_need - set: -> throw new Error "need cannot be assigned" - - want: # an Inventory specifying what the player wants to make - get: -> return @_want - set: (want)-> - if not want? then throw new Error "want is required" - if want.isEmpty then throw new Error "want cannot be empty" - if @_want is want then return - if @_want? then throw new Error "want cannot be reassigned" - @_want = new Inventory want - - steps: # an array of CraftingPlanSteps detailing the steps of the plan - get: -> return @_steps - set: (steps)-> - steps ?= [] - if steps is @_steps then return - if @_steps? then throw new Error "steps cannot be reassigned" - @_steps = steps - - # Object Overrides ############################################################################# - - toString: (options={})-> - options.full ?= false - - if options.full - b = new StringBuilder - b.line "CraftingPlan<", @_id, ">" - b.indent() - b.line "have: ", @_have.toString full:true - b.line "want: ", @_want.toString full:true - b.line "need: ", @_need.toString full:true - b.line "steps:" - b.indent() - b.loop @_steps, delimiter:"\n", onEach:(b, step)-> - b.push step.count, " × ", step.recipe.toString(full:true) - b.line() - b.outdent() - b.line "make: ", @_make.toString full:true - b.outdent() - - return b.toString() - else - return "CraftingPlan:#{@_make.toString(full:true)}<#{@_id}>" - - # Private Methods ############################################################################## - - _computeResources: -> - need = new Inventory @_want - make = new Inventory @_have - steps = @_steps[..].reverse() - - for step in steps - step.count = 0 - - for productStack in step.recipe.allProducts - continue unless need.contains productStack.item - productCount = Math.ceil need.getQuantity(productStack.item) / productStack.quantity - step.count = Math.max step.count, productCount - - continue unless step.count > 0 - - for itemId, item of step.recipe.inputs - amountNeeded = step.count * step.recipe.computeQuantityRequired item - amountAvailable = make.getQuantity item - amountUsed = Math.min amountAvailable, amountNeeded - amountMissing = amountNeeded - amountUsed - - make.remove item, amountUsed - need.add item, amountMissing - - for productStack in step.recipe.allProducts - amountCreated = step.count * productStack.quantity - amountNeeded = need.getQuantity productStack.item - amountFulfilled = Math.min amountNeeded, amountCreated - amountSurplus = amountCreated - amountFulfilled - - need.remove productStack.item, amountFulfilled - make.add productStack.item, amountSurplus - - make.merge @_want - - @_make = make - @_need = need - - _consolidateSteps: -> - steps = [] - stepsByRecipeId = {} - - for step in @_steps - priorStep = stepsByRecipeId[step.recipe.id] - if priorStep? - priorStep.count += step.count - else if step.count > 0 - steps.push step - stepsByRecipeId[step.recipe.id] = step - - @_steps = steps diff --git a/src/client/models/crafting/crafting_plan.test.coffee b/src/client/models/crafting/crafting_plan.test.coffee deleted file mode 100644 index 4011acd40..000000000 --- a/src/client/models/crafting/crafting_plan.test.coffee +++ /dev/null @@ -1,99 +0,0 @@ -# -# Crafting Guide - crafting_plan.test.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -CraftingPlan = require './crafting_plan' -CraftingPlanStep = require './crafting_plan_step' -Inventory = require '../game/inventory' -fixtures = require '../fixtures' - -######################################################################################################################## - -describe "CraftingPlan", -> - - beforeEach -> - @mod = fixtures.createMod() - @want = new Inventory - @have = new Inventory - - describe "with a single step plan", -> - - beforeEach -> - @oakPlank = fixtures.configureOakPlank @mod - @want.add @oakPlank, 11 - - @plan = new CraftingPlan want:@want, steps:[ - new CraftingPlanStep @oakPlank.firstRecipe - ] - - it "correctly computes the step counts", -> - @plan.steps[0].count.should.equal 3 - - it "correctly determines the inputs needed", -> - @plan.need.toString(full:true).should.equal "3 Oak Wood" - - it "correctly computes the products created", -> - @plan.make.toString(full:true).should.equal "12 Oak Planks" - - describe "with a multi-step plan", -> - - beforeEach -> - @ironIngot = fixtures.configureIronIngot @mod - @ironSword = fixtures.configureIronSword @mod - @oakPlank = fixtures.configureOakPlank @mod - @stick = fixtures.configureStick @mod - - @want.add @ironSword, 20 - - @plan = new CraftingPlan want:@want, steps:[ - new CraftingPlanStep @oakPlank.firstRecipe - new CraftingPlanStep @stick.firstRecipe - new CraftingPlanStep @ironIngot.firstRecipe - new CraftingPlanStep @ironSword.firstRecipe - ] - - it "correctly computes the step counts", -> - @plan.steps[0].count.should.equal 3 - @plan.steps[1].count.should.equal 5 - @plan.steps[2].count.should.equal 5 - @plan.steps[3].count.should.equal 20 - - it "correctly determines the inputs needed", -> - @plan.need.toString(full:true).should.equal "5 Coal, 40 Iron Ore, 3 Oak Wood" - - it "correctly computes the products created", -> - @plan.make.toString(full:true).should.equal "20 Iron Sword, 2 Oak Planks" - - describe "with a plan which recycles some items", -> - - beforeEach -> - @bucket = fixtures.configureBucket @mod - @cake = fixtures.configureCake @mod - @ironIngot = fixtures.configureIronIngot @mod - @milkBucket = fixtures.configureMilkBucket @mod - @sugar = fixtures.configureSugar @mod - - @want.add @cake, 2 - - @plan = new CraftingPlan want:@want, steps:[ - new CraftingPlanStep @ironIngot.firstRecipe - new CraftingPlanStep @bucket.firstRecipe - new CraftingPlanStep @milkBucket.firstRecipe - new CraftingPlanStep @sugar.firstRecipe - new CraftingPlanStep @cake.firstRecipe - ] - - it "correctly computes the step counts", -> - @plan.steps.length.should.equal 3 - @plan.steps[0].count.should.equal 6 - @plan.steps[1].count.should.equal 4 - @plan.steps[2].count.should.equal 2 - - it "correctly determines the inputs needed", -> - @plan.need.toString(full:true).should.equal "2 Egg, 6 Milk, 4 Sugar Cane, 6 Wheat" - - it "correctly computes the products created", -> - @plan.make.toString(full:true).should.equal "2 Cake" diff --git a/src/client/models/crafting/crafting_plan_step.coffee b/src/client/models/crafting/crafting_plan_step.coffee deleted file mode 100644 index 2986e2b4e..000000000 --- a/src/client/models/crafting/crafting_plan_step.coffee +++ /dev/null @@ -1,39 +0,0 @@ -# -# Crafting Guide - crafting_plan_step.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class CraftingPlanStep - - constructor: (recipe, count=1)-> - @_id = _.uniqueId "crafting-plan-step-" - @recipe = recipe - @count = count - - # Properties ################################################################################### - - Object.defineProperties @prototype, - - recipe: - get: -> return @_recipe - set: (recipe)-> - if not recipe? then throw new Error 'recipe is required' - if @_recipe is recipe then return - if @_recipe? then throw new Error 'recipe cannot be reassigned' - @_recipe = recipe - - count: - get: -> return @_count - set: (count)-> - count = parseInt "#{count}" - count = if Number.isNaN(count) then 0 else Math.max 0, count - @_count = count - - # Object Overrides ############################################################################# - - toString: -> - return "CraftingPlanStep:#{@_recipe}×#{@_count}<#{@_id}>" diff --git a/src/client/models/crafting/evaluation.coffee b/src/client/models/crafting/evaluation.coffee deleted file mode 100644 index c5ff49a52..000000000 --- a/src/client/models/crafting/evaluation.coffee +++ /dev/null @@ -1,105 +0,0 @@ -# -# Crafting Guide - evaluation.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class Evaluation - - constructor: (attributes={})-> - @evaluator = attributes.evaluator - @item = attributes.item if attributes.item? - @recipe = attributes.recipe if attributes.recipe? - @baseScore = attributes.baseScore - - @_id = _.uniqueId "evaluation-" - @_includedTools = {} - @_toolScore = null - - # Properties ################################################################################### - - Object.defineProperties @prototype, - - baseScore: - get: -> return @_baseScore - set: (baseScore)-> - baseScore = parseFloat "#{baseScore}" - baseScore = if Number.isNaN(baseScore) then null else baseScore - @_baseScore = baseScore - - 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 - - includedTools: - get: -> return @_includedTools - set: -> throw new Error "includedTools cannot be assigned" - - item: - get: -> return @_item - set: (item)-> - if @_recipe? then throw new Error "this evaluation is for a recipe: cannot set an item" - if @_item is item then return - if not item? then throw new Error "item cannot be assigned null" - if @_item? then throw new Error "item cannot be reassigned" - @_item = item - - recipe: - get: -> return @_recipe - set: (recipe)-> - if @_item? then throw new Error "this evaluation is for an item: cannot set an recipe" - if @_recipe is recipe then return - if not recipe? then throw new Error "recipe cannot be assigned null" - if @_recipe? then throw new Error "recipe cannot be reassigned" - @_recipe = recipe - - toolScore: - get: -> @_computeToolScore() - set: -> throw new Error "toolScore cannot be assigned" - - # Public Methods ############################################################################### - - addIncludedTool: (item)-> - return if @_includedTools[item.id]? - @_includedTools[item.id] = item - @_toolScore = null - - addIncludedToolsFrom: (evaluation)-> - for id, toolItem of evaluation.includedTools - @addIncludedTool toolItem - - computeTotalScore: (quantity=1)-> - if @item? - multiplier = quantity - else if @recipe? - multiplier = Math.ceil 1.0 * quantity / @recipe.output.quantity - - return @baseScore * multiplier + @toolScore - - isToolIncluded: (item)-> - return @_includedTools[item.id]? - - # Object Overrides ############################################################################# - - toString: -> - obj = if @item? then @item else @recipe - return "#{@evaluator.constructor.name}:#{obj}@#{@baseScore}<#{@_id}>" - - # Private Methods ############################################################################## - - _computeToolScore: -> - if not @_toolScore? - @_toolScore = 0 - for id, toolItem of @_includedTools - evaluation = @evaluator.evaluateItem toolItem - continue unless evaluation?.baseScore? - @_toolScore += evaluation.baseScore - - return @_toolScore diff --git a/src/client/models/crafting/evaluator.coffee b/src/client/models/crafting/evaluator.coffee deleted file mode 100644 index 386550090..000000000 --- a/src/client/models/crafting/evaluator.coffee +++ /dev/null @@ -1,102 +0,0 @@ -# -# Crafting Guide - evaluator.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -Evaluation = require './evaluation' - -######################################################################################################################## - -module.exports = class Evaluator - - constructor: -> - @_id = _.uniqueId "evaluator-" - @_evaluations = {} - - # Property Methods ############################################################################# - - Object.defineProperties @prototype, - - id: - get: -> return @_id - set: -> throw new Error "id cannot be assigned" - - # Public Methods ############################################################################### - - evaluateItem: (item)-> - return null unless item? - - evaluation = @_evaluations[item.id] - if not evaluation? - evaluation = @_evaluations[item.id] = new Evaluation evaluator:this, item:item - - recipeEvaluation = @_findBestRecipeEvaluationFor item - if recipeEvaluation? - evaluation.baseScore = recipeEvaluation.baseScore - evaluation.addIncludedToolsFrom recipeEvaluation - else - @_computeGatherableItemScore item, evaluation - - return evaluation - - evaluateRecipe: (recipe)-> - return null unless recipe? - - evaluation = @_evaluations[recipe.id] - if not evaluation? - evaluation = @_evaluations[recipe.id] = new Evaluation evaluator:this, recipe:recipe - @_computeRecipeScore recipe, evaluation - - for id, item of recipe.inputs - inputEvaluation = @evaluateItem item - evaluation.addIncludedToolsFrom inputEvaluation - - for id, toolItem of recipe.tools - evaluation.addIncludedTool toolItem - evaluation.addIncludedToolsFrom @evaluateItem toolItem - - return evaluation - - getOrderedRecipes: (item, quantity=1)-> - recipes = (recipe for recipeId, recipe of item.recipes) - - recipes.sort (a, b)=> - scoreA = @evaluateRecipe(a).computeTotalScore quantity - scoreB = @evaluateRecipe(b).computeTotalScore quantity - - if scoreA isnt scoreB - return if scoreA < scoreB then -1 else +1 - - return 0 - - return recipes - - # Object Overrides ############################################################################# - - toString: -> - return "#{@constructor.name}<#{@id}>" - - # Overrideable Methods ######################################################################### - - _computeGatherableItemScore: (item, evaluation)-> - throw new Error "#{@constructor.name} must override _computeGatherableItemScore" - - _computeRecipeScore: (recipe, evaluation)-> - throw new Error "#{@constructor.name} must override _computeRecipeScore" - - # Private Methods ############################################################################## - - _findBestRecipeEvaluationFor: (item)-> - return null if item.isGatherable - result = null - - for id, recipe of item.recipes - evaluation = @evaluateRecipe recipe - continue unless evaluation?.baseScore? - - if not result? then result = evaluation - if evaluation.baseScore < result.baseScore then result = evaluation - - return result diff --git a/src/client/models/crafting/plan_builder.coffee b/src/client/models/crafting/plan_builder.coffee deleted file mode 100644 index 47ad57257..000000000 --- a/src/client/models/crafting/plan_builder.coffee +++ /dev/null @@ -1,92 +0,0 @@ -# -# 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 diff --git a/src/client/models/crafting/plan_builder.test.coffee b/src/client/models/crafting/plan_builder.test.coffee deleted file mode 100644 index e374fc102..000000000 --- a/src/client/models/crafting/plan_builder.test.coffee +++ /dev/null @@ -1,158 +0,0 @@ -# -# Crafting Guide - plan_builder.test.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -fixtures = require '../fixtures' -Inventory = require '../game/inventory' -PlanBuilder = require './plan_builder' -ResourcesEvaluator = require './resources_evaluator' - -######################################################################################################################## - -describe "PlanBuilder", -> - - beforeEach -> - @planner = new PlanBuilder new ResourcesEvaluator - @mod = fixtures.createMod() - @want = new Inventory - @have = new Inventory - - describe "for a gatherable item, creates a plan that", -> - - beforeEach -> - @oakWood = fixtures.configureOakWood @mod - @want.add @oakWood, 2 - @plan = @planner.createPlan @want - - it "has no steps at all", -> - @plan.steps.length.should.equal 0 - - it "demands the item itself as the input", -> - @plan.need.toString(full:true).should.equal "2 Oak Wood" - - it "produces the item as the result", -> - @plan.make.toString(full:true).should.equal "2 Oak Wood" - - describe "for a single item with a one-step recipe, it creates a plan that", -> - - beforeEach -> - @oakPlank = fixtures.configureOakPlank @mod - @want.add @oakPlank, 63 - @plan = @planner.createPlan @want - - it "has the recipe as the only step", -> - @plan.steps.length.should.equal 1 - @plan.steps[0].recipe.output.item.displayName.should.equal "Oak Planks" - - it "demands the right inputs", -> - @plan.need.toString(full:true).should.equal "16 Oak Wood" - - it "produces the right results", -> - @plan.make.toString(full:true).should.equal "64 Oak Planks" - - describe "for a single item with a complex recipe, it creates a plan that", -> - - beforeEach -> - @ironSword = fixtures.configureIronSword @mod - @want.add @ironSword, 2 - @plan = @planner.createPlan @want - - it "has the right steps", -> - @plan.steps.length.should.equal 4 - @plan.steps[0].recipe.output.item.displayName.should.equal "Iron Ingot" - @plan.steps[1].recipe.output.item.displayName.should.equal "Oak Planks" - @plan.steps[2].recipe.output.item.displayName.should.equal "Stick" - @plan.steps[3].recipe.output.item.displayName.should.equal "Iron Sword" - - it "demands the right inputs", -> - @plan.need.toString(full:true).should.equal "1 Coal, 8 Iron Ore, 1 Oak Wood" - - it "produces the right results", -> - @plan.make.toString(full:true).should.equal "4 Iron Ingot, 2 Iron Sword, 2 Oak Planks, 2 Stick" - - describe "for multiple items with complex recipes, it creates a plan that", -> - - beforeEach -> - @ironSword = fixtures.configureIronSword @mod - @ironShovel = fixtures.configureIronShovel @mod - @want.add @ironSword, 3 - @want.add @ironShovel, 3 - @plan = @planner.createPlan @want - - it "has consolidated the common steps", -> - (step.recipe.output.item.displayName for step in @plan.steps).should.eql [ - "Iron Ingot", "Oak Planks", "Stick", "Iron Sword", "Iron Shovel" - ] - - it "requires the correct repetitions for each step", -> - (step.count for step in @plan.steps).should.eql [ 2, 2, 3, 3, 3 ] - - it "demands the right inputs", -> - @plan.need.toString(full:true).should.equal "2 Coal, 16 Iron Ore, 2 Oak Wood" - - it "produces the right results", -> - @plan.make.toString(full:true).should.equal( - "7 Iron Ingot, 3 Iron Shovel, 3 Iron Sword, 2 Oak Planks, 3 Stick" - ) - - describe "for an item which has a recursive recipe, it creates a plan that", -> - - beforeEach -> - @ironBlock = fixtures.configureIronBlock @mod - @want.add @ironBlock, 4 - @plan = @planner.createPlan @want - - it "avoids the recursive options", -> - (step.recipe.output.item.displayName for step in @plan.steps).should.eql [ - "Iron Ingot", "Iron Block" - ] - - it "requires the correct repetitions for each step", -> - (step.count for step in @plan.steps).should.eql [ 5, 4 ] - - it "demands the right inputs", -> - @plan.need.toString(full:true).should.equal "5 Coal, 40 Iron Ore" - - it "produces the right results", -> - @plan.make.toString(full:true).should.equal( - "4 Iron Block, 4 Iron Ingot" - ) - - describe "when making enormous quantities of something simple", -> - - beforeEach -> - @oakPlank = fixtures.configureOakPlank @mod - @want.add @oakPlank, Number.MAX_VALUE / 2 - @start = Date.now() - @plan = @planner.createPlan @want - @duration = Date.now() - @start - - it "doesn't take forever to create the plan", -> - @duration.should.be.lessThan 10 - - describe "when making an item which can be made with and without a tool, for a", -> - - beforeEach -> - @oakPlank = fixtures.configureOakPlank @mod - @saw = fixtures.configureSaw @mod - - describe "small batch, the plan", -> - - beforeEach -> - @want.add @oakPlank, 2 - @plan = @planner.createPlan @want - - it "avoids the expensive tool", -> - (step.recipe.needsTools for step in @plan.steps).should.eql [ false ] - - describe "large batch, the plan", -> - - beforeEach -> - @want.add @oakPlank, 2048 - @plan = @planner.createPlan @want - - it "uses the tool for efficiency", -> - (step.recipe.needsTools for step in @plan.steps).should.eql [ true ] diff --git a/src/client/models/crafting/resources_evaluator.coffee b/src/client/models/crafting/resources_evaluator.coffee deleted file mode 100644 index 55756cc0d..000000000 --- a/src/client/models/crafting/resources_evaluator.coffee +++ /dev/null @@ -1,40 +0,0 @@ -# -# Crafting Guide - resources_evaluator.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -Evaluator = require './evaluator' - -######################################################################################################################## - -module.exports = class ResourcesEvaluator extends Evaluator - - # Evaluator Overrides ########################################################################## - - _computeRecipeScore: (recipe, evaluation)-> - evaluation.baseScore = 0 - - for x in [0...recipe.width] - for y in [0...recipe.height] - for z in [0...recipe.depth] - stack = recipe.getInputAt x, y, z - continue unless stack? - - inputEvaluation = @evaluateItem stack.item - if inputEvaluation?.baseScore? - evaluation.baseScore += inputEvaluation.baseScore * stack.quantity - else - evaluation.baseScore = null - return - - for id, extraStack of recipe.extras - extraEvaluation = @evaluateItem extraStack.item - continue unless extraEvaluation?.baseScore? - evaluation.baseScore -= extraStack.quantity * extraEvaluation.baseScore - - evaluation.baseScore = evaluation.baseScore / recipe.output.quantity - - _computeGatherableItemScore: (item, evaluation)-> - evaluation.baseScore = 1 diff --git a/src/client/models/crafting/resources_evaluator.test.coffee b/src/client/models/crafting/resources_evaluator.test.coffee deleted file mode 100644 index 324a3087c..000000000 --- a/src/client/models/crafting/resources_evaluator.test.coffee +++ /dev/null @@ -1,129 +0,0 @@ -# -# Crafting Guide - resources_evaluator.test.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -ResourcesEvaluator = require './resources_evaluator' -fixtures = require '../fixtures' - -######################################################################################################################## - -describe "ResourcesEvaluator", -> - - beforeEach -> - @evaluator = new ResourcesEvaluator - @mod = fixtures.createMod() - - describe 'evaluating a gatherable item', -> - - beforeEach -> - @cobblestone = fixtures.configureCobblestone @mod - @evaluation = @evaluator.evaluateItem @cobblestone - - it 'should return a score of 1 for each item', -> - # 1 cobblestone - @evaluation.computeTotalScore().should.equal 1 - - describe 'evaluating a first-level recipe', -> - - beforeEach -> - @craftingTable = fixtures.configureCraftingTable @mod - @evaluation = @evaluator.evaluateItem @craftingTable - - it 'should return a score which is the sum of all resources', -> - # 1 oak wood => 4 planks (1/4) - # 4 oak planks => 1 crafting table (4 * 1/4 = 1) - @evaluation.computeTotalScore().should.equal 1 - - describe 'evaluating a recipe which requires a tool', -> - - beforeEach -> - @furnace = fixtures.configureFurnace @mod - @evaluation = @evaluator.evaluateItem @furnace - - it 'includes the cost of the tool', -> - # 1 oak wood => 4 planks (1/4) - # 4 oak planks => 1 crafting table (4 * 1/4 = 1) - # 8 cobblestone =(crafting table)=> 1 furnace (8 + 1 = 9) - @evaluation.computeTotalScore().should.equal 9 - - describe 'evaluating a recipe where a tool requires a tool', -> - - beforeEach -> - @ironIngot = fixtures.configureIronIngot @mod - @evaluation = @evaluator.evaluateItem @ironIngot - - it 'should include both tools in the score', -> - # raw ingredients: - # 8 iron ore + 1 coal =(furnace)=> 8 iron ingots ((8 + 1) / 8 = 1.125) - # tools: - # 8 cobblestone =(crafting table)=> 1 furnace (8) - # 4 oak planks => 1 crafting table (4 * 1/4 = 1) - # 1 oak wood => 4 planks (1/4) - @evaluation.computeTotalScore().should.equal 10.125 - - describe 'evaluating a recipe which requires a tool multiple times', -> - - beforeEach -> - @ironSword = fixtures.configureIronSword @mod - @evaluation = @evaluator.evaluateItem @ironSword - - it 'should include the tool only once', -> - # raw ingredients: - # 1 oak wood ==> 4 planks (0.25) - # 2 oak planks ==> 4 sticks (0.125) - # 8 iron ore + 1 coal =(furnace)=> 8 iron ingots (1.125) - # 2 iron ingot + 1 stick =(crafting table)=> 1 iron sword (2.375) - # - # tools: - # 8 cobblestone =(crafting table)=> 1 furnace (8) - # - # 1 oak wood => 4 planks (0.25) - # 4 oak planks => 1 crafting table (1) - # - @evaluation.computeTotalScore().should.equal 11.375 - - describe 'evaluating a recipe which has a recursive recipe', -> - - beforeEach -> - @ironBlock = fixtures.configureIronBlock @mod - @evaluation = @evaluator.evaluateItem @ironBlock - - it 'should avoid the recursive recipes', -> - # raw ingredients: - # 8 iron ore + 1 coal =(furnace)=> 8 iron ingots ((8 + 1) / 8 = 1.125) - # 9 iron ingot =(crafting table)=> 1 iron block (10.125) - # - # tools: - # 8 cobblestone =(crafting table)=> 1 furnace (8) - # 4 oak planks => 1 crafting table (4 * 1/4 = 1) - # 1 oak wood => 4 planks (1/4) - @evaluation.computeTotalScore().should.equal 19.125 - - describe 'evaluating a recipe with multiple ouputs', -> - - beforeEach -> - @cake = fixtures.configureCake @mod - @evaluation = @evaluator.evaluateItem @cake - - it 'should discount the extra outputs', -> - # raw ingredients: - # 8 iron ore + 1 coal =(furnace)=> 8 iron ingot (1.125) - # 3 iron ingot =(crafting table)=> 1 bucket (3.375) - # 1 milk + 1 bucket ==> 1 milk bucket (4.375) - # 1 sugar cane ==> 1 sugar (1) - # 3 wheat + 1 egg + 2 sugar + 3 milk bucket =(crafting table)=> 1 cake, 3 buckets (9) - # - # furnace: - # 8 cobblestone =(crafting table)=> 1 furnace (8) - # - # crafting table - # 1 oak wood ==> 4 oak planks (0.25) - # 4 planks ==> 1 crafting table (1) - @evaluation.computeTotalScore().should.equal 18 - - describe 'evaluating a recipe which is only ever made as an extra', -> - - it 'should still be able to come up with an evaluation' diff --git a/src/client/models/crafting/steps_evaluator.coffee b/src/client/models/crafting/steps_evaluator.coffee deleted file mode 100644 index 41472ce73..000000000 --- a/src/client/models/crafting/steps_evaluator.coffee +++ /dev/null @@ -1,41 +0,0 @@ -# -# Crafting Guide - steps_evaluator.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -Evaluator = require './evaluator' - -######################################################################################################################## - -module.exports = class StepsEvaluator extends Evaluator - - # Evaluator Overrides ########################################################################## - - _computeRecipeScore: (recipe, evaluation)-> - evaluation.score = 0 - - for id, stack of recipe.inputs - inputEvaluation = @evaluateItem stack.item - if not inputEvaluation?.score? - evaluation.score = null - return - - evaluation.score = Math.min evaluation.score, inputEvaluation.score + 1 - - for id, item of recipe.tools - continue if evaluation.isToolIncluded item - - toolEvaluation = @evaluateItem stack.item - if not toolEvaluation?.score? - evaluation.score = null - return - - evaluation.addIncludedTool item - evaluation.score += toolEvaluation.score - - return result - - _computeGatherableItemScore: (item, evaluation)-> - evaluation.score = 0 diff --git a/src/client/models/event_recorder.coffee b/src/client/models/event_recorder.coffee deleted file mode 100644 index 507ed32cd..000000000 --- a/src/client/models/event_recorder.coffee +++ /dev/null @@ -1,36 +0,0 @@ -# -# Crafting Guide - event_recorder.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -util = require 'util' - -######################################################################################################################## - -module.exports = class EventRecorder - - constructor: (model)-> - if not model? then throw new Error 'model is required' - - @model = model - @events = [] - - @model.on 'all', (event, model, args...)=> - logger.verbose -> "#{model?.constructor?.name}(#{model?.cid}) emitted #{event} - with args: #{util.inspect(args)}" - @events.push id:model?.cid, event:event, args:args - - # Public Methods ############################################################################### - - reset: -> - @events = [] - - # Property Methods ############################################################################# - - getNames: -> - return (e.event for e in @events) - - Object.defineProperties @prototype, - names: {get:@prototype.getNames} diff --git a/src/client/models/fixtures.coffee b/src/client/models/fixtures.coffee deleted file mode 100644 index ebc346a09..000000000 --- a/src/client/models/fixtures.coffee +++ /dev/null @@ -1,319 +0,0 @@ -# -# Crafting Guide - fixtures.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -Item = require "./game/item" -Mod = require "./game/mod" -ModPack = require "./game/mod_pack" -Recipe = require "./game/recipe" -Stack = require "./game/stack" - -# Instance Creation Fixtures ########################################################################################### - -exports.createModPack = createModPack = (attributes={})-> - attributes.id ?= _.uniqueId "mod-pack-" - attributes.displayName ?= "Test ModPack" - return new ModPack attributes - -exports.createMod = createMod = (attributes={})-> - attributes.modPack ?= createModPack() - attributes.id ?= _.uniqueId "mod-" - attributes.displayName ?= "Test Mod" - return new Mod attributes - -exports.createItem = createItem = (attributes={})-> - attributes.mod ?= createMod() - attributes.id ?= _.uniqueId "item-" - attributes.displayName ?= _.uniqueId "Test Item " - return new Item attributes - -exports.createRecipe = createRecipe = (attributes={})-> - attributes.id ?= _.uniqueId "recipe-" - attributes.output ?= createItem() - return new Recipe attributes - -exports.createStack = createStack = (attributes={})-> - attributes.item ?= createItem() - attributes.quantity ?= 1 - return new Stack attributes - -# Item Configuration Fixtures ########################################################################################## - -exports.configureBucket = configureBucket = (mod)-> - bucket = mod.modPack.findItem "bucket" - if not bucket? - ironIngot = configureIronIngot mod - bucket = createItem mod:mod, id:"bucket", displayName:"Bucket" - craftingTable = configureCraftingTable mod - - recipe = createRecipe output:createStack item:bucket - recipe.setInputAt 0, 0, createStack item:ironIngot - recipe.setInputAt 1, 1, createStack item:ironIngot - recipe.setInputAt 2, 0, createStack item:ironIngot - recipe.addTool craftingTable - - return bucket - -exports.configureCake = configureCake = (mod)-> - cake = mod.modPack.findItem "cake" - if not cake? - bucket = configureBucket mod - cake = createItem mod:mod, id:"cake", displayName:"Cake" - craftingTable = configureCraftingTable mod - egg = configureEgg mod - milkBucket = configureMilkBucket mod - sugar = configureSugar mod - wheat = configureWheat mod - - recipe = createRecipe output:createStack item:cake - recipe.setInputAt 0, 0, createStack item:milkBucket - recipe.setInputAt 1, 0, createStack item:milkBucket - recipe.setInputAt 2, 0, createStack item:milkBucket - recipe.setInputAt 0, 1, createStack item:sugar - recipe.setInputAt 1, 1, createStack item:egg - recipe.setInputAt 2, 1, createStack item:sugar - recipe.setInputAt 0, 2, createStack item:wheat - recipe.setInputAt 1, 2, createStack item:wheat - recipe.setInputAt 2, 2, createStack item:wheat - recipe.addTool craftingTable - recipe.addExtra createStack item:bucket, quantity:3 - - return cake - -exports.configureCoal = configureCoal = (mod)-> - coal = mod.modPack.findItem "coal" - if not coal? - coal = createItem mod:mod, id:"coal", displayName:"Coal" - return coal - -exports.configureCobblestone = configureCobblestone = (mod)-> - cobblestone = mod.modPack.findItem "cobblestone" - if not cobblestone? - cobblestone = createItem mod:mod, displayName:"Cobblestone" - return cobblestone - -exports.configureCraftingTable = configureCraftingTable = (mod)-> - craftingTable = mod.modPack.findItem "crafting_table" - if not craftingTable? - craftingTable = createItem mod:mod, id:"crafting_table", displayName:"Crafting Table" - oakPlanks = configureOakPlank mod - - recipe = createRecipe output:createStack item:craftingTable - recipe.setInputAt 0, 0, createStack item:oakPlanks - recipe.setInputAt 1, 0, createStack item:oakPlanks - recipe.setInputAt 0, 1, createStack item:oakPlanks - recipe.setInputAt 1, 1, createStack item:oakPlanks - - return craftingTable - -exports.configureEgg = configureEgg = (mod)-> - egg = mod.modPack.findItem "egg" - if not egg? - egg = createItem mod:mod, id:"egg", displayName:"Egg" - return egg - -exports.configureFurnace = configureFurnace = (mod)-> - furnace = mod.modPack.findItem "furnace" - if not furnace? - cobblestone = configureCobblestone mod - craftingTable = configureCraftingTable mod - furnace = createItem mod:mod, displayName:"Furnace" - - recipe = createRecipe output:createStack item:furnace - recipe.setInputAt 0, 0, createStack item:cobblestone - recipe.setInputAt 1, 0, createStack item:cobblestone - recipe.setInputAt 2, 0, createStack item:cobblestone - recipe.setInputAt 0, 1, createStack item:cobblestone - recipe.setInputAt 2, 1, createStack item:cobblestone - recipe.setInputAt 0, 2, createStack item:cobblestone - recipe.setInputAt 1, 2, createStack item:cobblestone - recipe.setInputAt 2, 2, createStack item:cobblestone - recipe.addTool craftingTable - - return furnace - -exports.configureIronIngot = configureIronIngot = (mod)-> - ironIngot = mod.modPack.findItem "iron_ingot" - if not ironIngot? - coal = configureCoal mod - furnace = configureFurnace mod - ironIngot = createItem mod:mod, id:"iron_ingot", displayName:"Iron Ingot" - ironOre = configureIronOre mod - - recipe = createRecipe output:createStack item:ironIngot, quantity:8 - recipe.setInputAt 1, 0, createStack item:ironOre, quantity:8 - recipe.setInputAt 1, 2, createStack item:coal - recipe.addTool furnace - - return ironIngot - -exports.configureIronBlock = configureIronBlock = (mod)-> - ironBlock = mod.modPack.findItem "iron_block" - if not ironBlock? - craftingTable = configureCraftingTable mod - ironBlock = createItem mod:mod, id:"iron_block", displayName:"Iron Block" - ironIngot = configureIronIngot mod - - recipe = createRecipe output:createStack item:ironBlock - for x in [0..2] - for y in [0..2] - recipe.setInputAt x, y, createStack item:ironIngot - recipe.addTool craftingTable - - recipe = createRecipe output:createStack item:ironIngot, quantity:9 - recipe.setInputAt 1, 1, createStack item:ironBlock - - return ironBlock - -exports.configureIronSword = configureIronSword = (mod)-> - ironSword = mod.modPack.findItem "iron_sword" - if not ironSword? - craftingTable = configureCraftingTable mod - ironIngot = configureIronIngot mod - ironSword = createItem mod:mod, id:"iron_sword", displayName:"Iron Sword" - stick = configureStick mod - - recipe = createRecipe output:createStack item:ironSword - recipe.setInputAt 1, 0, createStack item:ironIngot - recipe.setInputAt 1, 1, createStack item:ironIngot - recipe.setInputAt 1, 2, createStack item:stick - recipe.addTool craftingTable - - return ironSword - -exports.configureIronShovel = configureIronShovel = (mod)-> - ironShovel = mod.modPack.findItem "iron_shovel" - if not ironShovel? - craftingTable = configureCraftingTable mod - ironIngot = configureIronIngot mod - ironShovel = createItem mod:mod, id:"iron_shovel", displayName:"Iron Shovel" - stick = configureStick mod - - recipe = createRecipe output:createStack item:ironShovel - recipe.setInputAt 1, 0, createStack item:ironIngot - recipe.setInputAt 1, 1, createStack item:stick - recipe.setInputAt 1, 2, createStack item:stick - recipe.addTool craftingTable - - return ironShovel - -exports.configureIronOre = configureIronOre = (mod)-> - ironOre = mod.modPack.findItem "iron_ore" - if not ironOre? - ironOre = createItem mod:mod, id:"iron_ore", displayName:"Iron Ore" - return ironOre - -exports.configureMilk = configureMilk = (mod)-> - milk = mod.modPack.findItem "milk" - if not milk? - milk = createItem mod:mod, id:"milk", displayName:"Milk" - return milk - -exports.configureMilkBucket = configureMilkBucket = (mod)-> - milkBucket = mod.modPack.findItem "milk_bucket" - if not milkBucket? - bucket = configureBucket mod - milk = configureMilk mod - milkBucket = createItem mod:mod, id:"milkBucket", displayName:"Milk Bucket" - - recipe = createRecipe output:createStack item:milkBucket - recipe.setInputAt 1, 0, createStack item:milk - recipe.setInputAt 1, 1, createStack item:bucket - - return milkBucket - -exports.configureOakPlank = configureOakPlank = (mod)-> - oakPlanks = mod.modPack.findItem "oak_planks" - if not oakPlanks? - oakPlanks = createItem mod:mod, id:"oak_planks", displayName:"Oak Planks" - oakWood = configureOakWood mod - - recipe = createRecipe output:createStack item:oakPlanks, quantity:4 - recipe.setInputAt 1, 1, createStack item:oakWood - - return oakPlanks - -exports.configureOakWood = configureOakWood = (mod)-> - oakWood = mod.modPack.findItem "oak_wood" - if not oakWood? - oakWood = createItem mod:mod, id:"oak_wood", displayName:"Oak Wood" - return oakWood - -exports.configureObsidian = configureObsidian = (mod)-> - obsidian = mod.modPack.findItem "obsidian" - if not obsidian? - obsidian = createItem mod:mod, id:"obsidian", displayName:"Obsidian" - return obsidian - -exports.configureRedstoneDust = configureRedstoneDust = (mod)-> - redstoneDust = mod.modPack.findItem "redstone_dust" - if not redstoneDust? - redstoneDust = createItem mod:mod, id:"redstone_dust", displayName:"Redstone Dust" - return redstoneDust - -exports.configureStick = configureStick = (mod)-> - stick = mod.modPack.findItem "stick" - if not stick? - oakPlanks = configureOakPlank mod - stick = createItem mod:mod, id:"stick", displayName:"Stick" - - recipe = createRecipe output:createStack item:stick, quantity:4 - recipe.setInputAt 0, 0, createStack item:oakPlanks - recipe.setInputAt 0, 1, createStack item:oakPlanks - - return stick - -exports.configureSugar = configureSugar = (mod)-> - sugar = mod.modPack.findItem "sugar" - if not sugar? - sugar = createItem mod:mod, id:"sugar", displayName:"Sugar" - sugarCane = configureSugarCane mod - - recipe = createRecipe output:createStack item:sugar - recipe.setInputAt 1, 1, createStack item:sugarCane - - return sugar - -exports.configureSaw = configureSaw = (mod)-> - saw = mod.modPack.findItem "saw" - if not saw? - craftingTable = configureCraftingTable mod - ironBlock = configureIronBlock mod - ironIngot = configureIronIngot mod - oakPlank = configureOakPlank mod - oakWood = configureOakWood mod - redstoneDust = configureRedstoneDust mod - saw = createItem mod:mod, id:"saw", displayName:"Saw" - - recipe = createRecipe output:createStack item:saw - recipe.setInputAt 0, 0, createStack item:oakPlank - recipe.setInputAt 1, 0, createStack item:ironIngot - recipe.setInputAt 2, 0, createStack item:oakPlank - recipe.setInputAt 0, 1, createStack item:oakPlank - recipe.setInputAt 1, 1, createStack item:ironBlock - recipe.setInputAt 2, 1, createStack item:oakPlank - recipe.setInputAt 0, 2, createStack item:oakPlank - recipe.setInputAt 1, 2, createStack item:redstoneDust - recipe.setInputAt 2, 2, createStack item:oakPlank - recipe.addTool craftingTable - - recipe = createRecipe output:createStack item:oakPlank, quantity:8 - recipe.setInputAt 1, 1, createStack item:oakWood - recipe.addTool saw - - return saw - -exports.configureSugarCane = configureSugarCane = (mod)-> - sugarCane = mod.modPack.findItem "sugar_cane" - if not sugarCane? - sugarCane = createItem mod:mod, id:"sugar_cane", displayName:"Sugar Cane" - return sugarCane - -exports.configureWheat = configureWheat = (mod)-> - wheat = mod.modPack.findItem "wheat" - if not wheat? - wheat = createItem mod:mod, id:"wheat", displayName:"Wheat" - return wheat diff --git a/src/client/models/game/inventory.coffee b/src/client/models/game/inventory.coffee deleted file mode 100644 index 4eadaa7ba..000000000 --- a/src/client/models/game/inventory.coffee +++ /dev/null @@ -1,90 +0,0 @@ -# -# Crafting Guide - inventory.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -Stack = require './stack' - -######################################################################################################################## - -module.exports = class Inventory - - constructor: (inventory=null)-> - @_id = _.uniqueId "inventory-" - @_stacks = {} - - if inventory? then @merge inventory - - # Properties ################################################################################### - - Object.defineProperties @prototype, - - isEmpty: - get: -> (id for id, stack of @_stacks).length is 0 - - stacks: - get: -> return @_stacks - set: -> throw new Error "stacks cannot be replaced" - - # Public Methods ############################################################################### - - add: (item, quantity)-> - return unless item? - return if quantity is 0 - - existingStack = @_stacks[item.id] - if existingStack? - if existingStack.quantity + quantity < 0 then throw new Error "cannot have a negative quantity" - existingStack.quantity += quantity - else - if quantity < 0 then throw new Error "cannot have a negative quantity" - @_stacks[item.id] = new Stack item:item, quantity:quantity - - if @_stacks[item.id].quantity is 0 - delete @_stacks[item.id] - - clear: -> - @_stacks = {} - - contains: (item)-> - return @_stacks[item.id]? - - getQuantity: (item)-> - existingStack = @_stacks[item.id] - return 0 unless existingStack? - return existingStack.quantity - - merge: (inventory)-> - for id, stack of inventory.stacks - @add stack.item, stack.quantity - - remove: (item, quantity)-> - @add item, -1 * quantity - - # Object Overrides ############################################################################# - - toString: (options={})-> - options.full ?= false - - if options.full - result = [] - needsDelimiter = false - - stackList = (stack for itemId, stack of @_stacks) - stackList.sort (a, b)-> - if a.item.displayName isnt b.item.displayName - return if a.item.displayName < b.item.displayName then -1 else +1 - return 0 - - for stack in stackList - if needsDelimiter then result.push ", " - needsDelimiter = true - - result.push stack.quantity - result.push " " - result.push stack.item.displayName - return result.join "" - else - return "Inventory<#{@_id}>@#{(id for id, item of @_stacks).length}" diff --git a/src/client/models/game/item.coffee b/src/client/models/game/item.coffee deleted file mode 100644 index 2e0a4796e..000000000 --- a/src/client/models/game/item.coffee +++ /dev/null @@ -1,96 +0,0 @@ -# -# Crafting Guide - item.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class Item - - constructor: (attributes={})-> - @id = attributes.id - @displayName = attributes.displayName - @isGatherable = attributes.isGatherable - @mod = attributes.mod - - @_hasPrimaryRecipe = false - @_recipesAsPrimary = {} - @_recipesAsExtra = {} - - # Property Methods ############################################################################# - - Object.defineProperties @prototype, - - displayName: # a string containing the user-facing name of this item - get: -> return @_displayName - set: (displayName)-> - if not displayName? then throw new Error "displayName is required" - @_displayName = displayName - - firstRecipe: # the first Recipe returned by iterating the `recipes` property - get: -> - recipeList = (recipe for id, recipe of @recipes) - return null unless recipeList.length > 0 - return recipeList[0] - set: -> throw new Error "firstRecipe cannot be assigned" - - id: # a string containing a unique identifier for this item - get: -> return @_id - set: (id)-> - if not id? then throw new Error "id is required" - return if @_id is id - if @_id? then throw new Error "id cannot be reassigned" - @_id = id - - isGatherable: # whether this item can be gathered directly without needing to be crafted - get: -> - return true if @_isGatherable is true - return false if (id for id, recipe of @_recipesAsPrimary).length > 0 - return false if (id for id, recipe of @_recipesAsExtra).length > 0 - return true - set: (isGatherable)-> - @_isGatherable = null unless isGatherable? - @_isGatherable = !!isGatherable - - mod: # the Mod which adds this item to the game - get: -> return @_mod - set: (mod)-> - if not mod? then throw new Error "mod is required" - if @_mod is mod then return - if @_mod? then throw new Error "mod cannot be reassigned" - @_mod = mod - @_mod.addItem this - - modPack: # the ModPack containing this item - get: -> return @_mod.modPack - set: -> throw new Error "modPack cannot be assigned" - - recipes: # a hash of recipeId to Recipe containing `recipesAsPrimary` if not empty or else `recipesAsExtra` - get: -> return if @_hasPrimaryRecipe then @_recipesAsPrimary else @_recipesAsExtra - set: -> throw new Error "recipes cannot be assigned" - - recipesAsPrimary: # a hash of recipeId to Recipe where this item is the primary output - get: -> return @_recipesAsPrimary - set: -> throw new Error "recipes cannot be assigned" - - recipesAsExtra: # a hash of recipeId to Recipe where this item is an extra output - get: -> return @_recipesAsExtra - set: -> throw new Error "recipesAsExtra cannot be assigned" - - # Public Recipes ############################################################################### - - addRecipe: (recipe)-> - if recipe.output.item is this - @_recipesAsPrimary[recipe.id] = recipe - @_hasPrimaryRecipe = true - else if recipe.extras[this.id]?.item is this - @_recipesAsExtra[recipe.id] = recipe - else - throw new Error "recipe<#{recipe.id}> does not produce this item<#{@id}>" - - # Object Overrides ############################################################################# - - toString: -> - return "Item:#{@displayName}<#{@id}>" diff --git a/src/client/models/game/mod.coffee b/src/client/models/game/mod.coffee deleted file mode 100644 index b4e013b86..000000000 --- a/src/client/models/game/mod.coffee +++ /dev/null @@ -1,62 +0,0 @@ -# -# Crafting Guide - mod.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class Mod - - constructor: (attributes={})-> - @id = attributes.id - @displayName = attributes.displayName - @modPack = attributes.modPack - - @_items = {} - - # Properties ################################################################################### - - Object.defineProperties @prototype, - - displayName: - get: -> return @_displayName - set: (displayName)-> - if not displayName? then throw new Error "displayName is required" - return if @_displayName is displayName - @_displayName = displayName - - id: - get: -> return @_id - set: (id)-> - if not id? then throw new Error "id is required" - return if @_id is id - if @_id? then throw new Error "id cannot be reassigned" - @_id = id - - items: - get: -> return @_items - set: -> throw new Error "items cannot be replaced" - - modPack: - get: -> return @_modPack - set: (modPack)-> - if not modPack? then throw new Error "modPack is required" - if @_modPack is modPack then return - if @_modPack? then throw new Error "modPack cannot be reassigned" - @_modPack = modPack - @_modPack.addMod this - - # Public Methods ############################################################################### - - addItem: (item)-> - if not item? then return - if @_items[item.id] is item then return - @_items[item.id] = item - item.mod = this - - # Object Overrides ############################################################################# - - toString: -> - return "Mod:#{@displayName}<#{@id}>" diff --git a/src/client/models/game/mod_pack.coffee b/src/client/models/game/mod_pack.coffee deleted file mode 100644 index f7e3842a9..000000000 --- a/src/client/models/game/mod_pack.coffee +++ /dev/null @@ -1,59 +0,0 @@ -# -# Crafting Guide - mod_pack.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class ModPack - - constructor: (attributes={})-> - @id = attributes.id - @displayName = attributes.displayName - - @_mods = {} - - # Property Methods ############################################################################# - - Object.defineProperties @prototype, - - displayName: # a string containing the user-displayable name of this ModPack - get: -> return @_displayName - set: (displayName)-> - if not displayName? then throw new Error "displayName is required" - if @_displayName is displayName then return - @_displayName = displayName - - id: # a string which uniquely identifies this ModPack - get: -> return @_id - set: (id)-> - if not id? then throw new Error "id is required" - if @_id is id then return - if @_id? then throw new Error "id cannot be reassigned" - @_id = id - - mods: # a hash of mod id to Mod containing all the mods which are part of this ModPack - get: -> return @_mods - set: -> throw new Error "mods cannot be replaced" - - # Public Methods ############################################################################### - - addMod: (mod)-> - if not mod? then return - if @_mods[mod.id] is mod then return - @_mods[mod.id] = mod - mod.modPack = this - - findItem: (itemId)-> - for modId, mod of @mods - item = mod.items[itemId] - return item if item? - - return null - - # Object Overrides ############################################################################# - - toString: -> - return "ModPack:#{@displayName}<#{@id}>" diff --git a/src/client/models/game/recipe.coffee b/src/client/models/game/recipe.coffee deleted file mode 100644 index 8cb220542..000000000 --- a/src/client/models/game/recipe.coffee +++ /dev/null @@ -1,174 +0,0 @@ -# -# Crafting Guide - recipe.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -{StringBuilder} = require 'crafting-guide-common' - -######################################################################################################################## - -module.exports = class Recipe - - constructor: (attributes={})-> - @depth = attributes.depth - @height = attributes.height - @id = attributes.id - @output = attributes.output - @width = attributes.width - - @_extras = {} - @_inputs = {} - @_inputGrid = [] - @_tools = {} - - # Properties ################################################################################### - - Object.defineProperties @prototype, - - allProducts: # an array of Stacks starting the the primary output of this recipe - get: -> return [].concat @output, (stack for id, stack of @extras) - set: -> throw new Error "allProducts cannot be assigned" - - depth: # an integer specifying the number of layers to this recipe - get: -> return @_depth - set: (depth)-> - depth = parseInt "#{depth}" - depth = if Number.isNaN(depth) then 0 else Math.max(0, depth) - @_depth = depth - - extras: # a hash of item id to Stack of all the non-primary outputs of this recipe - get: -> return @_extras - set: -> throw new Error "extras cannot be replaced" - - id: # a string which uniquely identifies this recipe - get: -> return @_id - set: (id)-> - if not id? then throw new Error "id is required" - if @_id is id then return - if @_id? then throw new Error "id cannot be reassigned" - @_id = id - - height: # an integer specifying the number of rows needed by this recipe - get: -> return @_height - set: (height)-> - height = parseInt "#{height}" - height = if Number.isNaN(height) then 0 else Math.max(0, height) - @_height = height - - inputs: # a hash of item id to Item containing all the inputs to this recipe - get: -> return @_inputs - set: -> throw new Error "inputs cannot be replaced" - - needsTools: # a boolean indicating whether this recipe requires a tool - get: -> return (id for id, toolItem of @_tools).length > 0 - - output: # a Stack specifying the primary output of this recipe - get: -> return @_output - set: (output)-> - if not output? then throw new Error "output is required" - if @_output is output then return - if @_output? then throw new Error "output cannot be reassigned" - @_output = output - @_output.item.addRecipe this - - modPack: # the ModPack to which this recipe belongs - get: -> return @_output.modPack - set: -> throw new Error "modPack cannot be replaced" - - tools: # a hash of item id to Item of all the tools required for this recipe - get: -> return @_tools - set: -> throw new Error "tools cannot be assigned" - - width: # an integer specifying the number of columns needed by this recipe - get: -> return @_width - set: (width)-> - width = parseInt "#{width}" - width = if Number.isNaN(width) then 0 else Math.max(0, width) - @_width = width - - # Public Methods ############################################################################### - - addExtra: (stack)-> - return unless stack - return if @_extras[stack.item.id] is stack - @_extras[stack.item.id] = stack - stack.item.addRecipe this - - addTool: (item)-> - return unless item - @_tools[item.id] = item - - computeQuantityRequired: (item)-> - result = 0 - - for x in [0...@width] - for y in [0...@height] - for z in [0...@depth] - stack = @getInputAt x, y, z - continue unless stack? - continue unless stack.item.id is item.id - result += stack.quantity - - return result - - computeQuantityProduced: (item)-> - result = 0 - - if @_output.item.id is item.id - result += @_output.quantity - - for itemId, stack of @_extras - continue unless itemId is item.id - result += stack.quantity - - return result - - getInputAt: -> - [x, y, z] = [0, 0, 0] - if arguments.length is 3 - [x, y, z] = arguments - else - [x, y] = arguments - - return @_inputGrid[x]?[y]?[z] or null - - setInputAt: -> - [x, y, z, stack] = [0, 0, 0, null] - if arguments.length is 4 - [x, y, z, stack] = arguments - else - [x, y, stack] = arguments - - @_depth = Math.max @_depth, z + 1 - @_height = Math.max @_height, y + 1 - @_width = Math.max @_width, x + 1 - - @_inputGrid[x] ?= [] - @_inputGrid[x][y] ?= [] - @_inputGrid[x][y][z] = stack - - if stack?.item? then @_inputs[stack.item.id] = stack.item - - # Object Overrides ############################################################################# - - toString: (options={})-> - options.full ?= false - - if options.full - b = new StringBuilder - b.loop (item for id, item of @inputs), delimiter:" + ", onEach:(b, item)=> - b.push @computeQuantityRequired(item), " ", item.displayName - b.push " =" - b.onlyIf @needsTools, (b)=> - b.push "(" - b.loop (toolItem for id, toolItem of @tools), onEach:(b, toolItem)-> b.push toolItem.displayName - b.push ")" - b.push "=> " - b.loop @allProducts, delimiter:" + ", onEach:(b, stack)=> - b.push stack.quantity, " ", stack.item.displayName - - return b.toString() - else - return "Recipe:#{@output}<#{@id}>" diff --git a/src/client/models/game/recipe.test.coffee b/src/client/models/game/recipe.test.coffee deleted file mode 100644 index ef9bffda0..000000000 --- a/src/client/models/game/recipe.test.coffee +++ /dev/null @@ -1,72 +0,0 @@ -# -# Crafting Guide - recipe.test.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -fixtures = require "../fixtures" -Item = require "./item" -Recipe = require "./recipe" -Stack = require "./stack" - -######################################################################################################################## - -describe "Recipe", -> - - beforeEach -> - @mod = fixtures.createMod() - @stick = fixtures.configureStick @mod - @ironIngot = fixtures.configureIronIngot @mod - @obsidian = fixtures.configureObsidian @mod - - @ironSword = new Item id:"iron_sword", displayName:"Iron Sword", mod:@mod - @obsidianBox = new Item id:"obsidian_box", displayName:"Obsidian Box", mod:@mod - - describe "getting & setting inputs", -> - - describe "for 2D recipes", -> - - beforeEach -> - @recipe = new Recipe id:"test1", output:new Stack item:@ironSword - @recipe.setInputAt 1, 0, new Stack item:@ironIngot - @recipe.setInputAt 1, 1, new Stack item:@ironIngot - @recipe.setInputAt 1, 2, new Stack item:@stick - - it "returns assigned values as expected", -> - expect(@recipe.getInputAt(0, 0)).to.equal null - @recipe.getInputAt(1, 0).item.displayName.should.equal "Iron Ingot" - @recipe.getInputAt(1, 1).item.displayName.should.equal "Iron Ingot" - @recipe.getInputAt(1, 2).item.displayName.should.equal "Stick" - expect(@recipe.getInputAt(2, 2)).to.equal null - - it "determines the correct dimentions", -> - @recipe.depth.should.equal 1 - @recipe.height.should.equal 3 - @recipe.width.should.equal 2 - - describe "for 3D recipes", -> - - beforeEach -> - @recipe = new Recipe id:"test2", output:new Stack item:@obsidianBox - for x in [0..2] - for y in [0..2] - for z in [0..2] - continue if x is 1 and y is 1 - continue if x is 1 and z is 1 - continue if y is 1 and z is 1 - - @recipe.setInputAt x, y, z, new Stack item:@obsidian - - it "returns assigned values as expected", -> - @recipe.getInputAt(0, 0, 0).item.displayName.should.equal "Obsidian" - @recipe.getInputAt(2, 0, 0).item.displayName.should.equal "Obsidian" - @recipe.getInputAt(0, 2, 0).item.displayName.should.equal "Obsidian" - @recipe.getInputAt(2, 2, 2).item.displayName.should.equal "Obsidian" - expect(@recipe.getInputAt(1, 1, 1)).to.equal null - expect(@recipe.getInputAt(1, 1, 0)).to.equal null - - it "determines the correct dimentions", -> - @recipe.depth.should.equal 3 - @recipe.height.should.equal 3 - @recipe.width.should.equal 3 \ No newline at end of file diff --git a/src/client/models/game/stack.coffee b/src/client/models/game/stack.coffee deleted file mode 100644 index aa8541cfc..000000000 --- a/src/client/models/game/stack.coffee +++ /dev/null @@ -1,42 +0,0 @@ -# -# Crafting Guide - stack.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class Stack - - constructor: (attributes={})-> - @item = attributes.item - @quantity = attributes.quantity - - # Properties ################################################################################### - - Object.defineProperties @prototype, - - item: - get: -> return @_item - set: (item)-> - if not item? then throw new Error "item is required" - if @_item is item then return - if @_item? then throw new Error "item cannot be reassigned" - @_item = item - - modPack: - get: -> return @_item.modPack - set: -> throw new Error "modPack cannot be replaced" - - quantity: - get: -> return @_quantity - set: (quantity)-> - quantity = parseInt "#{quantity}" - quantity = if Number.isNaN(quantity) then 0 else Math.max(0, quantity) - @_quantity = quantity - - # Object Overrides ############################################################################# - - toString: -> - return "Stack:#{@item}×#{@quantity}" \ No newline at end of file diff --git a/src/client/models/parsing/mod_pack_json.test.coffee b/src/client/models/parsing/mod_pack_json.test.coffee deleted file mode 100644 index 6053ed7ad..000000000 --- a/src/client/models/parsing/mod_pack_json.test.coffee +++ /dev/null @@ -1,124 +0,0 @@ -# -# Crafting Guide - mod_pack_json.test.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -fixtures = require "../fixtures" -ModPackJsonFormatter = require "./mod_pack_json_formatter" -ModPackJsonParser = require "./mod_pack_json_parser" - -######################################################################################################################## - -describe "ModPackJsonParser & ModPackJsonFormatter", -> - - beforeEach -> - @formatter = new ModPackJsonFormatter - @parser = new ModPackJsonParser - - @modPack = fixtures.createModPack id:"alpha", displayName:"ALPHA" - - @runTest = => - @string1 = @formatter.format @modPack - @string2 = @formatter.format @parser.parse @string1 - @result = @parser.parse @string2 - - describe "an empty modpack", -> - - beforeEach -> @runTest() - - it "can survive a round trip", -> - @string1.should.equal @string2 - - it "contains the modpack's own properties", -> - @result.id.should.equal @modPack.id - @result.displayName.should.equal @modPack.displayName - - it "doesn't contain a mods list", -> - expect(@result.mods).to.beUndefined - - describe "a modpack with a single mod", -> - - beforeEach -> - @mod = fixtures.createMod modPack:@modPack, id:"bravo", displayName:"BRAVO" - - describe "containing only a gatherable item", -> - - beforeEach -> - @oakWood = fixtures.configureOakWood @mod - @runTest() - - it "can survive a round trip", -> - @string1.should.equal @string2 - - it "contains the correct mod", -> - mod = @result.mods[@mod.id] - mod.displayName.should.equal @mod.displayName - - it "contains the item", -> - item = @result.mods[@mod.id].items[@oakWood.id] - item.displayName.should.equal @oakWood.displayName - - describe "containing a multi-step item & it's requirements", -> - - beforeEach -> - @craftingTable = fixtures.configureCraftingTable @mod - @oakPlank = fixtures.configureOakPlank @mod - @runTest() - - it "can survive a round trip", -> - @string1.should.equal @string2 - - it "contains oak planks", -> - item = @result.mods[@mod.id].items[@oakPlank.id] - item.displayName.should.equal @oakPlank.displayName - - it "has the recipe for a crafting table", -> - recipe = @result.mods[@mod.id].items[@craftingTable.id].firstRecipe - recipe.getInputAt(0, 0).item.id.should.equal @oakPlank.id - recipe.getInputAt(0, 1).item.id.should.equal @oakPlank.id - recipe.getInputAt(1, 0).item.id.should.equal @oakPlank.id - recipe.getInputAt(1, 1).item.id.should.equal @oakPlank.id - recipe.output.quantity.should.equal 1 - - describe "containing a complex item which needs tools & it's requirements", -> - - beforeEach -> - @cake = fixtures.configureCake @mod - @runTest() - - it "can survive a round trip", -> - @string1.should.equal @string2 - - it "has the recipe for a cake", -> - recipe = @result.mods[@mod.id].items[@cake.id].firstRecipe - - describe "a modpack with multiple mods", -> - - beforeEach -> - @modA = fixtures.createMod modPack:@modPack, id:"bravo", displayName:"BRAVO" - @modB = fixtures.createMod modPack:@modPack, id:"charlie", displayName:"CHARLIE" - - describe "where items are used in recipes crossing mods", -> - - beforeEach -> - @stick = fixtures.configureStick @modA - @ironIngot = fixtures.configureIronIngot @modA - @ironSword = fixtures.configureIronSword @modB - @runTest() - - it "can survive a round trip", -> - @string1.should.equal @string2 - - it "has each item in the correct mod", -> - @result.mods[@modA.id].items[@ironIngot.id].displayName.should.equal @ironIngot.displayName - @result.mods[@modB.id].items[@ironSword.id].displayName.should.equal @ironSword.displayName - - it "has the correct recipe for an iron sword", -> - recipe = @result.mods[@modB.id].items[@ironSword.id].firstRecipe - recipe.output.item.id.should.equal @ironSword.id - recipe.output.quantity.should.equal 1 - recipe.getInputAt(1, 0).item.id.should.equal @ironIngot.id - recipe.getInputAt(1, 1).item.id.should.equal @ironIngot.id - recipe.getInputAt(1, 2).item.id.should.equal @stick.id diff --git a/src/client/models/parsing/mod_pack_json_formatter.coffee b/src/client/models/parsing/mod_pack_json_formatter.coffee deleted file mode 100644 index f0032a1de..000000000 --- a/src/client/models/parsing/mod_pack_json_formatter.coffee +++ /dev/null @@ -1,101 +0,0 @@ -# -# Crafting Guide - mod_pack_json_formatter.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -######################################################################################################################## - -module.exports = class ModPackJsonParser - - constructor: -> - @_reset() - - # Public Methods ############################################################################### - - format: (modPack)-> - @_reset() - return JSON.stringify @_formatModPack modPack - - # Private Methods ############################################################################## - - _formatItem: (item)-> - result = {} - result.id = item.id - result.displayName = item.displayName - - if item.isGatherable and item.firstRecipe? - result.gatherable = true - - return result - - _formatMod: (mod)-> - result = {} - result.id = mod.id - result.displayName = mod.displayName - - for itemId, item of mod.items - result.items ?= [] - @_itemIndexById[item.id] = @_itemIndex++ - result.items.push @_formatItem item - - return result - - _formatModPack: (modPack)-> - result = {} - result.id = modPack.id - result.displayName = modPack.displayName - - for modId, mod of modPack.mods - result.mods ?= [] - result.mods.push @_formatMod mod - - if result.mods? - for modResult in result.mods - for itemResult in modResult.items - item = modPack.mods[modResult.id].items[itemResult.id] - for recipeId, recipe of item.recipesAsPrimary - itemResult.recipes ?= [] - itemResult.recipes.push @_formatRecipe recipe - - return result - - _formatRecipe: (recipe)-> - result = {} - result.id = recipe.id - - if recipe.output.quantity > 1 - result.quantity = recipe.output.quantity - - result.width = recipe.width - result.height = recipe.height - result.depth = recipe.depth if recipe.depth > 1 - result.inputs = [] - - for x in [0...recipe.width] - for y in [0...recipe.height] - for z in [0...recipe.depth] - inputStack = @_formatStack recipe.getInputAt x, y, z - result.inputs.push inputStack - - for itemId, stack of recipe.extras - result.extras ?= [] - result.extras.push @_formatStack stack - - for itemId, item of recipe.tools - result.tools ?= [] - result.tools.push @_itemIndexById[itemId] - - return result - - _formatStack: (stack)-> - return null unless stack? - - itemIndex = @_itemIndexById[stack.item.id] - if stack.quantity is 1 then return itemIndex - return [itemIndex, stack.quantity] - - _reset: -> - @_itemIndex = 0 - @_itemIndexById = {} diff --git a/src/client/models/parsing/mod_pack_json_parser.coffee b/src/client/models/parsing/mod_pack_json_parser.coffee deleted file mode 100644 index e0aa25f74..000000000 --- a/src/client/models/parsing/mod_pack_json_parser.coffee +++ /dev/null @@ -1,164 +0,0 @@ -# -# Crafting Guide - mod_pack_json_parser.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -Item = require "../game/item" -Mod = require "../game/mod" -ModPack = require "../game/mod_pack" -Recipe = require "../game/recipe" -Stack = require "../game/stack" - -######################################################################################################################## - -module.exports = class ModPackJsonParser - - constructor: -> - @_reset() - - # Public Methods ############################################################################### - - parse: (arg, fileName=null)-> - @_reset() - @_fileName = fileName - - if _.isString arg - @_parseText arg - else - @_parseObject arg - - return @_modPack - - # Private Methods ############################################################################## - - _parseInteger: (text, defaultValue)-> - result = parseInt "#{text}" - result = if Number.isNaN result then defaultValue else result - return result - - _parseText: (text)-> - try - obj = JSON.parse text - catch error - @_throwError "could not parse JSON: #{error}" - - @_parseObject obj - - _parseObject: (obj)-> - @_data = obj - @_parseModPack() - @_parseMods() - @_parseItems() - @_parseRecipes() - - _parseModPack: -> - if not @_data? then @_throwError "there is no valid data" - if not @_data.id? then @_throwError "modPack requires an id" - if not @_data.displayName? then @_throwError "modPack requires a displayName" - - @_modPack = new ModPack id:@_data.id, displayName:@_data.displayName - - _parseMods: -> - return unless @_data.mods? - - for modData, index in @_data.mods - @_location = "mods[#{index}]" - if not modData.id? then @_throwError "mod requires an id" - if not modData.displayName? then @_throwError "mod requires a displayName" - - new Mod modPack:@_modPack, id:modData.id, displayName:modData.displayName - - _parseItems: -> - return unless @_data.mods? - - for modData in @_data.mods - continue unless modData.items? - - mod = @_modPack.mods[modData.id] - for itemData, index in modData.items - @_location = "<#{mod.id}>.items[#{index}]" - if not itemData.id? then @_throwError "item requires an id" - if not itemData.displayName? then @_throwError "item requires a displayName" - - item = new Item mod:mod, id:itemData.id, displayName:itemData.displayName - item.gatherable = itemData.gatherable if itemData.gatherable? - @_items.push item - - _parseRecipes: -> - return unless @_data.mods? - - for modData in @_data.mods - continue unless modData.items? - - mod = @_modPack.mods[modData.id] - for itemData, index in modData.items - continue unless itemData.recipes? - - item = mod.items[itemData.id] - for recipeData, index in itemData.recipes - @_location = "<#{itemData.id}>.recipes[#{index}]" - if not recipeData.id? then @_throwError "recipe requires id" - if not recipeData.inputs? then @_throwError "recipe requires inputs" - - quantity = @_parseInteger recipeData.quantity, 1 - outputStack = new Stack item:item, quantity:quantity - recipe = new Recipe id:recipeData.id, output:outputStack - - depth = @_parseInteger recipeData.depth, 1 - height = @_parseInteger recipeData.height, 3 - width = @_parseInteger recipeData.width, 3 - - index = 0 - for x in [0...width] - for y in [0...height] - for z in [0...depth] - stack = @_parseStack recipeData.inputs[index] - if stack? then recipe.setInputAt x, y, z, stack - index++ - - if recipeData.extras - for stackData in recipeData.extras - recipe.addExtra @_parseStack stackData - - if recipeData.tools - for index in recipeData.tools - toolItem = @_items[index] - if not toolItem? then @_throwError "there is no item #{index}" - recipe.addTool toolItem - - _parseStack: (stackData)-> - return null unless stackData? - if _.isArray(stackData) - if stackData.length isnt 2 then @_throwError "input stacks must have an item index and a quantity" - index = stackData[0] - quantity = stackData[1] - else - index = stackData - quantity = 1 - - item = @_items[index] - if not item? then @_throwError "there is no item #{index}" - - return new Stack item:item, quantity:quantity - - _reset: -> - @_data = null - @_fileName = null - @_items = [] - @_location = null - @_modPack = null - - _throwError: (message, cause=null)-> - if @_location? then message = "#{@_location}: #{message}" - if @_fileName? and @_location? then message = "@#{message}" - if @_fileName? then message = "#{@_fileName}#{message}" - if cause? then message = "#{message}: #{cause}" - - error = new Error message - error.cause = cause if cause? - error.fileName = @_fileName if @_fileName? - error.location = @_location if @_location? - - throw error diff --git a/src/client/models/site/craft_page.coffee b/src/client/models/site/craft_page.coffee index 3085cc24f..712a53ff8 100644 --- a/src/client/models/site/craft_page.coffee +++ b/src/client/models/site/craft_page.coffee @@ -5,10 +5,12 @@ # All rights reserved. # -BaseModel = require '../base_model' -Craftsman = require '../crafting/craftsman' -Inventory = require '../game/inventory' -ModPack = require '../game/mod_pack' +CraftingGuideCommon = require "crafting-guide-common" + +{BaseModel} = CraftingGuideCommon.deprecated +{Craftsman} = CraftingGuideCommon.deprecated.crafting +{Inventory} = CraftingGuideCommon.deprecated.game +{ModPack} = CraftingGuideCommon.deprecated.game ######################################################################################################################## diff --git a/src/client/models/site/editable_file.coffee b/src/client/models/site/editable_file.coffee index b37bda8b5..7c05503ed 100644 --- a/src/client/models/site/editable_file.coffee +++ b/src/client/models/site/editable_file.coffee @@ -5,7 +5,8 @@ # All rights reserved. # -BaseModel = require '../base_model' +{BaseModel} = require("crafting-guide-common").deprecated +w = require "when" ######################################################################################################################## diff --git a/src/client/models/site/file_cache.coffee b/src/client/models/site/file_cache.coffee index 2ddd6580c..521d71559 100644 --- a/src/client/models/site/file_cache.coffee +++ b/src/client/models/site/file_cache.coffee @@ -5,6 +5,8 @@ # All rights reserved. # +w = require "when" + ######################################################################################################################## module.exports = class FileCache extends Backbone.Events diff --git a/src/client/models/site/file_cache.test.coffee b/src/client/models/site/file_cache.test.coffee index 737778c47..2fef672e7 100644 --- a/src/client/models/site/file_cache.test.coffee +++ b/src/client/models/site/file_cache.test.coffee @@ -1,3 +1,9 @@ +# +# Crafting Guide - file_cache.test.coffee +# +# Copyright © 2014-2016 by Redwood Labs +# All rights reserved. +# FileCache = require './file_cache' diff --git a/src/client/models/site/github_user.coffee b/src/client/models/site/github_user.coffee index fb2afe354..35f718fad 100644 --- a/src/client/models/site/github_user.coffee +++ b/src/client/models/site/github_user.coffee @@ -5,7 +5,7 @@ # All rights reserved. # -BaseModel = require '../base_model' +{BaseModel} = require("crafting-guide-common").deprecated ######################################################################################################################## diff --git a/src/client/models/site/item_page.coffee b/src/client/models/site/item_page.coffee index e673f004a..052e4768a 100644 --- a/src/client/models/site/item_page.coffee +++ b/src/client/models/site/item_page.coffee @@ -5,7 +5,7 @@ # All rights reserved. # -BaseModel = require '../base_model' +{BaseModel} = require("crafting-guide-common").deprecated ######################################################################################################################## diff --git a/src/client/models/site/item_selector.coffee b/src/client/models/site/item_selector.coffee index ae6ec3071..3c543d7bf 100644 --- a/src/client/models/site/item_selector.coffee +++ b/src/client/models/site/item_selector.coffee @@ -5,8 +5,8 @@ # All rights reserved. # -BaseModel = require '../base_model' -ItemSlug = require '../game/item_slug' +{BaseModel} = require('crafting-guide-common').deprecated +{ItemSlug} = require('crafting-guide-common').deprecated.game ######################################################################################################################## diff --git a/src/client/models/site/markdown_image_list.coffee b/src/client/models/site/markdown_image_list.coffee index 9ad3331e3..acac909fb 100644 --- a/src/client/models/site/markdown_image_list.coffee +++ b/src/client/models/site/markdown_image_list.coffee @@ -5,7 +5,7 @@ # All rights reserved. # -BaseModel = require '../base_model' +{BaseModel} = require('crafting-guide-common').deprecated MarkdownImage = require './markdown_image' ######################################################################################################################## diff --git a/src/client/models/site/tutorial.coffee b/src/client/models/site/tutorial.coffee deleted file mode 100644 index 702f0d718..000000000 --- a/src/client/models/site/tutorial.coffee +++ /dev/null @@ -1,33 +0,0 @@ -# -# Crafting Guide - tutorial.coffee -# -# Copyright © 2014-2016 by Redwood Labs -# All rights reserved. -# - -BaseModel = require '../base_model' - -######################################################################################################################## - -module.exports = class Tutorial extends BaseModel - - constructor: (attributes={}, options={})-> - if not attributes.name?.length > 0 then throw new Error "attributes.name cannot be empty" - attributes.modSlug ?= null - attributes.officialUrl ?= null - attributes.sections ?= [] - attributes.slug ?= _.slugify attributes.name - attributes.videos ?= [] - super attributes, options - - # Backbone.Model Overrides ##################################################################### - - parse: (text)-> - TutorialParser = require '../parsing/tutorial_parser' # to avoid require cycles - @_parser ?= new TutorialParser model:this - @_parser.parse text - - return null # prevent calling `set` - - url: -> - return c.url.tutorialData modSlug:@modSlug, tutorialSlug:@slug diff --git a/src/client/models/stores/mod_pack_store.coffee b/src/client/models/stores/mod_pack_store.coffee index 4ddcfe86e..5c8bcf947 100644 --- a/src/client/models/stores/mod_pack_store.coffee +++ b/src/client/models/stores/mod_pack_store.coffee @@ -6,6 +6,7 @@ # ModPackJsonParser = require "../parsing/mod_pack_json_parser" +w = require "when" ######################################################################################################################## diff --git a/src/client/site/browse_page/browse_page_controller.coffee b/src/client/site/browse_page/browse_page_controller.coffee index 2f1422129..b1972a414 100644 --- a/src/client/site/browse_page/browse_page_controller.coffee +++ b/src/client/site/browse_page/browse_page_controller.coffee @@ -5,10 +5,10 @@ # All rights reserved. # +{CraftingGuideClient} = require('crafting-guide-common').api ModBallotController = require './mod_ballot/mod_ballot_controller' ModTileController = require './mod_tile/mod_tile_controller' PageController = require '../page_controller' -{CraftingGuideClient} = require 'crafting-guide-common' ######################################################################################################################## diff --git a/src/client/site/common/adsense/adsense_controller.coffee b/src/client/site/common/adsense/adsense_controller.coffee index f0143d6d2..90d1fb6c8 100644 --- a/src/client/site/common/adsense/adsense_controller.coffee +++ b/src/client/site/common/adsense/adsense_controller.coffee @@ -140,7 +140,7 @@ module.exports = class AdsenseController adCount = @_computeAdCount @_computeAdType() if adCount is 0 - logger.verbose "Adsense is waiting for room to insert ads" + logger.trace "Adsense is waiting for room to insert ads" @_waiting = true _.delay (=> @_waiting = false; @_waitForPageReadiness()), c.adsense.readinessCheckInterval else diff --git a/src/client/site/common/item_selector/item_selector_controller.coffee b/src/client/site/common/item_selector/item_selector_controller.coffee index ed108ba08..f5a5feeee 100644 --- a/src/client/site/common/item_selector/item_selector_controller.coffee +++ b/src/client/site/common/item_selector/item_selector_controller.coffee @@ -8,6 +8,7 @@ BaseController = require '../../base_controller' ItemSelector = require '../../../models/site/item_selector' ElementController = require './element/element_controller' +w = require "when" ######################################################################################################################## diff --git a/src/client/site/common/recipe/recipe_controller.coffee b/src/client/site/common/recipe/recipe_controller.coffee index 274d40566..e1b82e99b 100644 --- a/src/client/site/common/recipe/recipe_controller.coffee +++ b/src/client/site/common/recipe/recipe_controller.coffee @@ -8,7 +8,7 @@ BaseController = require '../../base_controller' CraftingGridController = require '../crafting_grid/crafting_grid_controller' SlotController = require '../slot/slot_controller' -{StringBuilder} = require 'crafting-guide-common' +{StringBuilder} = require('crafting-guide-common').util ######################################################################################################################## diff --git a/src/client/site/craft_page/craft_page_controller.coffee b/src/client/site/craft_page/craft_page_controller.coffee index 47a9dc634..05b79758a 100644 --- a/src/client/site/craft_page/craft_page_controller.coffee +++ b/src/client/site/craft_page/craft_page_controller.coffee @@ -7,11 +7,11 @@ BaseController = require '../base_controller' CraftPage = require '../../models/site/craft_page' -Craftsman = require '../../models/crafting/craftsman' +{Craftsman} = require('crafting-guide-common').deprecated.crafting CraftsmanWorkingController = require './craftsman_working/craftsman_working_controller' InventoryController = require '../common/inventory/inventory_controller' PageController = require '../page_controller' -SimpleInventory = require '../../models/crafting/simple_inventory' +{SimpleInventory} = require('crafting-guide-common').deprecated.crafting StepController = require './step/step_controller' ######################################################################################################################## @@ -64,6 +64,7 @@ module.exports = class CraftPageController extends PageController sampleInventory.parse inventoryText @model.craftsman.want.addInventory sampleInventory @_scrollTo @$workingSection + @onWantInventoryChanged() return false diff --git a/src/client/site/craft_page/craftsman_working/craftsman_working_controller.coffee b/src/client/site/craft_page/craftsman_working/craftsman_working_controller.coffee index 36498fb1c..934854582 100644 --- a/src/client/site/craft_page/craftsman_working/craftsman_working_controller.coffee +++ b/src/client/site/craft_page/craftsman_working/craftsman_working_controller.coffee @@ -6,7 +6,7 @@ # BaseController = require '../../base_controller' -Craftsman = require '../../../models/crafting/craftsman' +{Craftsman} = require('crafting-guide-common').deprecated.crafting ######################################################################################################################## diff --git a/src/client/site/craft_page/step/step_controller.coffee b/src/client/site/craft_page/step/step_controller.coffee index 4015c6e06..cf6df7d74 100644 --- a/src/client/site/craft_page/step/step_controller.coffee +++ b/src/client/site/craft_page/step/step_controller.coffee @@ -8,7 +8,7 @@ BaseController = require '../../base_controller' InventoryController = require '../../common/inventory/inventory_controller' RecipeController = require '../../common/recipe/recipe_controller' -SimpleInventory = require '../../../models/crafting/simple_inventory' +{SimpleInventory} = require('crafting-guide-common').deprecated.crafting ######################################################################################################################## diff --git a/src/client/site/feedback/feedback_controller.coffee b/src/client/site/feedback/feedback_controller.coffee index 0157099e4..70f8bcc6f 100644 --- a/src/client/site/feedback/feedback_controller.coffee +++ b/src/client/site/feedback/feedback_controller.coffee @@ -7,6 +7,7 @@ BaseController = require '../base_controller' EmailClient = require '../../models/site/email_client' +w = require "when" ######################################################################################################################## diff --git a/src/client/site/item_page/item_page_controller.coffee b/src/client/site/item_page/item_page_controller.coffee index f78e95ed0..ea811d61e 100644 --- a/src/client/site/item_page/item_page_controller.coffee +++ b/src/client/site/item_page/item_page_controller.coffee @@ -6,15 +6,16 @@ # EditableFile = require '../../models/site/editable_file' -Item = require '../../models/game/item' +{Item} = require('crafting-guide-common').deprecated.game ItemGroupController = require '../common/item_group/item_group_controller' ItemPage = require '../../models/site/item_page' -ItemSlug = require '../../models/game/item_slug' +{ItemSlug} = require('crafting-guide-common').deprecated.game MarkdownSectionController = require '../common/markdown_section/markdown_section_controller' MultiblockViewerController = require './multiblock_viewer/multiblock_viewer_controller' PageController = require '../page_controller' RecipeDetailController = require './recipe_detail/recipe_detail_controller' VideoController = require '../common/video/video_controller' +w = require "when" ######################################################################################################################## diff --git a/src/client/site/item_page/recipe_detail/recipe_detail_controller.coffee b/src/client/site/item_page/recipe_detail/recipe_detail_controller.coffee index e386a27b2..16a3bb99f 100644 --- a/src/client/site/item_page/recipe_detail/recipe_detail_controller.coffee +++ b/src/client/site/item_page/recipe_detail/recipe_detail_controller.coffee @@ -7,9 +7,9 @@ BaseController = require '../../base_controller' CraftingGridController = require '../../common/crafting_grid/crafting_grid_controller' -Inventory = require '../../../models/game/inventory' +{Inventory} = require('crafting-guide-common').deprecated.game InventoryController = require '../../common/inventory/inventory_controller' -{StringBuilder} = require 'crafting-guide-common' +{StringBuilder} = require('crafting-guide-common').util ######################################################################################################################## diff --git a/src/client/site/login_page/login_page_controller.coffee b/src/client/site/login_page/login_page_controller.coffee index c63a185cc..8256258f2 100644 --- a/src/client/site/login_page/login_page_controller.coffee +++ b/src/client/site/login_page/login_page_controller.coffee @@ -7,7 +7,7 @@ PageController = require '../page_controller' GitHubUser = require '../../models/site/github_user' -{CraftingGuideClient} = require 'crafting-guide-common' +{CraftingGuideClient} = require('crafting-guide-common').api ######################################################################################################################## diff --git a/src/client/site/mod_page/mod_page_controller.coffee b/src/client/site/mod_page/mod_page_controller.coffee index 3bc5ce730..1daf88343 100644 --- a/src/client/site/mod_page/mod_page_controller.coffee +++ b/src/client/site/mod_page/mod_page_controller.coffee @@ -5,10 +5,10 @@ # All rights reserved. # -PageController = require '../page_controller' -Item = require '../../models/game/item' +{Item} = require('crafting-guide-common').deprecated.game ItemGroupController = require '../common/item_group/item_group_controller' -Mod = require '../../models/game/mod' +{Mod} = require('crafting-guide-common').deprecated.game +PageController = require '../page_controller' TutorialController = require './tutorial/tutorial_controller' ######################################################################################################################## diff --git a/src/client/site/router.coffee b/src/client/site/router.coffee index c2b4eca18..e4b047710 100644 --- a/src/client/site/router.coffee +++ b/src/client/site/router.coffee @@ -5,15 +5,15 @@ # All rights reserved. # -BrowsePageController = require './browse_page/browse_page_controller' -CraftPageController = require './craft_page/craft_page_controller' -ItemPageController = require './item_page/item_page_controller' -ItemSlug = require '../models/game/item_slug' -LoginPageController = require './login_page/login_page_controller' -ModPageController = require './mod_page/mod_page_controller' -NewsPageController = require './news_page/news_page_controller' -TutorialPageController = require './tutorial_page/tutorial_page_controller' -UrlParams = require './url_params' +BrowsePageController = require './browse_page/browse_page_controller' +CraftPageController = require './craft_page/craft_page_controller' +ItemPageController = require './item_page/item_page_controller' +{ItemSlug} = require('crafting-guide-common').deprecated.game +LoginPageController = require './login_page/login_page_controller' +ModPageController = require './mod_page/mod_page_controller' +NewsPageController = require './news_page/news_page_controller' +TutorialPageController = require './tutorial_page/tutorial_page_controller' +UrlParams = require './url_params' ######################################################################################################################## diff --git a/src/client/site/site_controller.coffee b/src/client/site/site_controller.coffee index 5c51d3a7a..13f050d04 100644 --- a/src/client/site/site_controller.coffee +++ b/src/client/site/site_controller.coffee @@ -13,9 +13,8 @@ FooterController = require './footer/footer_controller' GitHubUser = require '../models/site/github_user' HeaderController = require './header/header_controller' ImageLoader = require './image_loader' -Mod = require '../models/game/mod' -ModPack = require '../models/game/mod_pack' -ModPackStore = require '../models/store/mod_pack_store' +{Mod} = require('crafting-guide-common').deprecated.game +{ModPack} = require('crafting-guide-common').deprecated.game Router = require './router' ######################################################################################################################## @@ -31,6 +30,7 @@ module.exports = class SiteController extends BaseController @client = options.client @fileCache = new FileCache c.url.modpackArchive() @imageLoader = new ImageLoader defaultUrl:'/images/unknown.png' + @modPack = new ModPack {}, fileCache:@fileCache @router = new Router this @storage = options.storage @@ -41,6 +41,23 @@ module.exports = class SiteController extends BaseController # Public Methods ############################################################################### + loadDefaultModPack: -> + makeResponder = (m)-> return -> + m.activeModVersion.fetch() if m.activeModVersion? + + for modSlug, modData of c.defaultMods + mod = new Mod {slug:modSlug}, {fileCache:@fileCache} + mod.on c.event.change + ':activeModVersion', makeResponder mod + @storage.register "mod:#{mod.slug}", mod, 'activeVersion', modData.defaultVersion + mod.fetch() + + @modPack.addMod mod + + if global.env isnt 'prerender' + @modPack.once c.event.sync, => + @$pageContent.removeClass 'hidden' + @$pageContentLoading.addClass 'hidden' + loadCurrentUser: -> @client.getCurrentUser() .then (response)=> diff --git a/src/client/tracker.coffee b/src/client/tracker.coffee index f67681d62..2ad3edbe7 100644 --- a/src/client/tracker.coffee +++ b/src/client/tracker.coffee @@ -5,6 +5,8 @@ # All rights reserved. # +w = require "when" + ######################################################################################################################## module.exports = class Tracker diff --git a/src/common/constants.coffee b/src/common/constants.coffee index 78d35d37a..b059663fe 100644 --- a/src/common/constants.coffee +++ b/src/common/constants.coffee @@ -5,6 +5,9 @@ # All rights reserved. # +_ = require "./underscore" +_.extend exports, require("crafting-guide-common").constants + ######################################################################################################################## exports.adsense = adsense = {} @@ -29,31 +32,52 @@ adsense.skyscraper.margin = 24 # px adsense.skyscraper.slotIds = ['7613920409', '9574673605', '3388539204'] adsense.skyscraper.width = 160 # px +exports.defaultMods = defaultMods = {} +defaultMods.minecraft = { defaultVersion: '1.7.10' } # Minecraft must be first + +defaultMods.advanced_solar_panels = { defaultVersion: '3.5.1' } +defaultMods.agricraft = { defaultVersion: '1.7.10_1.5.0' } +defaultMods.applied_energistics_2 = { defaultVersion: 'rv1-stable-1' } +defaultMods.big_reactors = { defaultVersion: '0.4.2A2' } +defaultMods.buildcraft = { defaultVersion: '1.7.18' } +defaultMods.computercraft = { defaultVersion: '1.74' } +defaultMods.draconic_evolution = { defaultVersion: '1.0.2h' } +defaultMods.ender_storage = { defaultVersion: '1.4.5.29' } +defaultMods.enderio = { defaultVersion: '2.2.7.325' } +defaultMods.extra_cells = { defaultVersion: '2.2.73b129' } +defaultMods.extra_utilities = { defaultVersion: '1.2.2' } +defaultMods.forestry = { defaultVersion: '3.4.0.7' } +defaultMods.forge_multipart = { defaultVersion: '1.2.0.345' } +defaultMods.galacticraft = { defaultVersion: '3.0.12.404' } +defaultMods.hydraulicraft = { defaultVersion: '2.1.242' } +defaultMods.ic2_classic = { defaultVersion: 'none' } +defaultMods.industrial_craft_2 = { defaultVersion: '2.2.663' } +defaultMods.iron_chests = { defaultVersion: '6.0.62.742' } +defaultMods.jabba = { defaultVersion: '1.2.1a' } +defaultMods.logistics_pipes = { defaultVersion: '0.9.3.100' } +defaultMods.mekanism = { defaultVersion: '7.1.1.127' } +defaultMods.minefactory_reloaded = { defaultVersion: '2.8.0RC8-86' } +defaultMods.modular_powersuits = { defaultVersion: '0.11.0-300-thermal-expansion' } +defaultMods.opencomputers = { defaultVersion: '1.5.22' } +defaultMods.quantum_flux = { defaultVersion: '1.3.4' } +defaultMods.project_red = { defaultVersion: '4.5.16.77' } +defaultMods.redstone_arsenal = { defaultVersion: '9.5.0' } +defaultMods.railcraft = { defaultVersion: '9.5.0' } +defaultMods.simply_jetpacks = { defaultVersion: '1.4.1' } +defaultMods.solar_expansion = { defaultVersion: '1.6a' } +defaultMods.solar_flux = { defaultVersion: '0.5b' } +defaultMods.storage_drawers = { defaultVersion: '1.7.10-1.6.2' } +defaultMods.thermal_dynamics = { defaultVersion: '1.7.10r1.2.0' } +defaultMods.thermal_expansion = { defaultVersion: '1.7.10r4.1.4' } +defaultMods.thermal_foundation = { defaultVersion: '1.7.10r1.2.5' } +defaultMods.tinkers_construct = { defaultVersion: '1.7.10-1.8.8' } + exports.duration = duration = {} duration.snap = 100 duration.fast = 200 duration.normal = 400 duration.slow = 1200 -exports.event = event = {} -event.add = 'add' # collection, item... -event.button = {} -event.button.complete = 'button:complete' # controller -event.button.first = 'button:first' # controller, buttonType -event.button.second = 'button:second' # controller, buttonType -event.change = 'change' # model -event.click = 'click' # event -event.load = {} -event.load.started = 'load:started' # controller, url -event.load.succeeded = 'load:succeeded' # controller, book -event.load.failed = 'load:failed' # controller, error message -event.load.finished = 'load:finished' # controller -event.remove = 'remove' # collection, item... -event.request = 'request' # model -event.route = 'route' -event.sort = 'sort' -event.sync = 'sync' # model, response - exports.gitHub = gitHub = {} gitHub.file = {} gitHub.file.itemDescription = {} @@ -67,10 +91,6 @@ key.escape = 27 key.upArrow = 38 key.downArrow = 40 -exports.limits = limits = {} -limits.maximumGraphSize = 5000 -limits.maximumPlanCount = 5000 - exports.login = login = {} login.authorizeUrl = _.template "https://github.com/login/oauth/authorize" + "?client_id=<%= clientId %>&scope=public_repo&state=<%= state %>" @@ -82,12 +102,6 @@ login.clientIds = exports.modpack = modpack = {} modpack.default = "crafting-guide-default" -exports.modelState = modelState = {} -modelState.unloaded = 'unloaded' -modelState.loading = 'loading' -modelState.loaded = 'loaded' -modelState.failed = 'failed' - exports.opacity = opacity = {} opacity.hidden = 1e-6 opacity.shown = 1 @@ -138,22 +152,3 @@ tracking.category.modVote = 'mod-vote' tracking.category.multiblock = 'multiblock' tracking.category.navigate = 'navigate' tracking.category.search = 'search' - -exports.url = url = {} -url.crafting = _.template "/craft/<%= inventoryText %>" -url.item = _.template "/browse/<%= modSlug %>/<%= itemSlug %>/" -url.itemData = _.template "/data/<%= modSlug %>/items/<%= itemSlug %>/item.cg" -url.itemIcon = _.template "/data/<%= modSlug %>/items/<%= itemSlug %>/icon.png" -url.itemImageDir = _.template "/data/<%= modSlug %>/items/<%= itemSlug %>" -url.login = _.template "/login" -url.mod = _.template "/browse/<%= modSlug %>/" -url.modData = _.template "/data/<%= modSlug %>/mod.cg" -url.modIcon = _.template "/data/<%= modSlug %>/icon.png" -url.modPackData = _.template "/data/<%= modPackId %>/modpack.json" -url.modVersionData = _.template "/data/<%= modSlug %>/versions/<%= modVersion %>/mod-version.cg" -url.root = _.template "/" -url.tutorial = _.template "/browse/<%= modSlug %>/tutorials/<%= tutorialSlug %>/" -url.tutorialData = _.template "/data/<%= modSlug %>/tutorials/<%= tutorialSlug %>/tutorial.cg" -url.tutorialIcon = _.template "/data/<%= modSlug %>/tutorials/<%= tutorialSlug %>/icon.png" -url.tutorialIcon = _.template "/data/<%= modSlug %>/tutorials/<%= tutorialSlug %>/icon.png" -url.tutorialImageDir = _.template "/data/<%= modSlug %>/tutorials/<%= tutorialSlug %>" diff --git a/src/common/underscore.coffee b/src/common/underscore.coffee index af599c914..776b89d24 100644 --- a/src/common/underscore.coffee +++ b/src/common/underscore.coffee @@ -5,33 +5,4 @@ # All rights reserved. # -module.exports = _ = require 'underscore' - -_.mixin require 'underscore.inflections' -_.mixin require('crafting-guide-common').stringMixins - -_.mixin - parseMarkdown: (text)-> - return markdown.parse text, 'Maruku' - - slugify: (text)-> - return null unless text? - - result = text.toLowerCase() - result = result.replace /[^a-zA-Z0-9_]/g, '_' - result = result.replace /__+/g, '_' - result = result.replace /^_/, '' - result = result.replace /_$/, '' - return result - - composeSlugs: (part1, part2)-> - return "#{part1}__#{part2}" - - decomposeSlug: (slug)-> - return [null, null] unless slug? - - parts = slug.split '__' - if parts.length is 1 - parts = [ null, parts[0] ] - - return parts +module.exports = _ = require('crafting-guide-common')._ diff --git a/src/index.coffee b/src/index.coffee index 77e6e047c..8e32e472b 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -7,13 +7,4 @@ ######################################################################################################################## -global.Backbone = require 'backbone' -global._ = require './common/underscore' -global.c = require './common/constants' - -module.exports = - constants: require './common/constants' - Mod: require './client/models/game/mod' - ModParser: require './client/models/parsing/mod_parser' - ModVersion: require './client/models/game/mod_version' - ModVersionParser: require './client/models/parsing/mod_version_parser' +# Just to keep NPM happy... nothing is actually exported. diff --git a/src/server/crafting_guide_server.coffee b/src/server/crafting_guide_server.coffee index 2e2faa82d..3459e7fac 100644 --- a/src/server/crafting_guide_server.coffee +++ b/src/server/crafting_guide_server.coffee @@ -9,6 +9,7 @@ express = require 'express' http = require 'http' middleware = require './middleware' routes = require './routes' +w = require "when" ############################################################################################################ diff --git a/src/server/server.coffee b/src/server/server.coffee index 01e7e8feb..0cf899533 100644 --- a/src/server/server.coffee +++ b/src/server/server.coffee @@ -9,12 +9,6 @@ require('dotenv').config() ######################################################################################################################## -global._ = require './underscore' -global.c = require './constants' -global.w = require 'when' - -######################################################################################################################## - CraftingGuideServer = require './crafting_guide_server' server = new CraftingGuideServer process.env.WEBSITE_SERVER_PORT server.start() diff --git a/src/test_helper.coffee b/src/test_helper.coffee index e5a1a7bfc..6aad498d1 100644 --- a/src/test_helper.coffee +++ b/src/test_helper.coffee @@ -1,9 +1,9 @@ -### +# # Crafting Guide - test.coffee # # Copyright (c) 2014-2015 by Redwood Labs # All rights reserved. -### +# # Test Set-up ########################################################################################################## @@ -27,5 +27,5 @@ global.π = Math.PI global.Backbone = Backbone = require 'backbone' Backbone.$ = $ -{Logger} = require 'crafting-guide-common' +{Logger} = require('crafting-guide-common').util global.logger = new Logger level:Logger.FATAL diff --git a/src/underscore.coffee b/src/underscore.coffee new file mode 100644 index 000000000..d8860dcfb --- /dev/null +++ b/src/underscore.coffee @@ -0,0 +1,10 @@ +# +# Crafting Guide - underscore.coffee +# +# Copyright (c) 2014-2017 by Redwood Labs +# All rights reserved. +# + +######################################################################################################################## + +module.exports = _ = require("crafting-guide-common")._