This commit is contained in:
Andrew Miner
2015-02-16 11:03:59 -08:00
parent 8804605d99
commit 8236d82ec8
8 changed files with 190 additions and 29 deletions
@@ -3259,3 +3259,16 @@ group: Tools: Painters
input: Dandelion Yellow, Painter input: Dandelion Yellow, Painter
pattern: ... 10. ... pattern: ... 10. ...
update: Iron Ingot
recipe:
input: Crushed Iron Ore, furnace fuel
pattern: .0. ... .1.
tools: Furnace
recipe:
input: Purified Crushed Iron Ore, furnace fuel
pattern: .0. ... .1.
tools: Furnace
recipe:
input: Iron Dust, furnace fuel
pattern: .0. ... .1.
tools: Furnace
+74
View File
@@ -0,0 +1,74 @@
###
Crafting Guide - item_slug.coffee
Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
########################################################################################################################
module.exports = class ItemSlug
constructor: ->
@_item = @_mod = null
if arguments.length is 1
@item = arguments[0]
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 ################################################################################
DELIMITER = '__'
@compare: (a, b)->
if a.isQualified isnt b.isQualified
return -1 if a.isQualified
return +1 if b.isQualified
else if a.mod isnt b.mod
return if a.mod < b.mod then -1 else +1
else if a.item isnt b.item
return if a.item < b.item then -1 else +1
return 0
@equals: (a, b)->
return false unless a.mod is b.mod
return false unless a.item is b.item
return true
# Property Methods #############################################################################
Object.defineProperties @prototype,
isQualified: { get:@prototype.isQualified }
mod: { get:@prototype.getMod, set:@prototype.setMod }
item: { get:@prototype.getItem, set:@prototype.setItem }
qualified: { get:@prototype.getQualified set:@prototype.setQualified }
getItem: ->
return @_item
setItem: (item)->
if not item? then throw new Error 'item is required'
@_item = item
@mod = mod
getMod: ->
return @_mod
setMod: (mod)->
@_qualified = if mod? then "#{@mod}#{ItemSlug.DELIMITER}#{@item}" else @item
@_mod = mod
isQualified: ->
return @_mod?
# Object Overrides #############################################################################
toString: ->
return @_qualified
valueOf: ->
return @_qualified.valueOf()
+1 -3
View File
@@ -56,9 +56,7 @@ module.exports = class ItemPage extends BaseModel
return result return result
findRecipes: -> findRecipes: ->
result = @modPack.findRecipes @item?.qualifiedSlug return @modPack.findRecipes @item?.slug
return null unless result.length > 0
return result
# Private Methods ############################################################################## # Private Methods ##############################################################################
+14 -3
View File
@@ -101,7 +101,8 @@ module.exports = class ModVersion extends BaseModel
return this return this
findName: (slug)-> findName: (slug)->
return @_names[slug] [modSlug, itemSlug] = _.decomposeSlug slug
return @_names[itemSlug]
registerName: (slug, name)-> registerName: (slug, name)->
hasSlug = @_names[slug]? hasSlug = @_names[slug]?
@@ -127,14 +128,24 @@ module.exports = class ModVersion extends BaseModel
return this return this
findRecipes: (itemSlug, result=[])-> findRecipes: (slug, result=[])->
recipeList = @_recipes[itemSlug] recipeList = @_recipes[slug]
if recipeList? if recipeList?
for recipe in recipeList for recipe in recipeList
result.push recipe result.push recipe
return result return result
findExternalRecipes: ->
result = {}
for slug, recipeList of @_recipes
[modSlug, itemSlug] = _.decomposeSlug slug
logger.debug "checking: #{modSlug}, #{itemSlug}"
continue if @_items[itemSlug]?
logger.debug "external: #{recipeList}"
result[itemSlug] = recipeList[..]
return result
hasRecipes: (itemSlug)-> hasRecipes: (itemSlug)->
recipeList = @_recipes[itemSlug] recipeList = @_recipes[itemSlug]
return true if recipeList? and recipeList.length > 0 return true if recipeList? and recipeList.length > 0
@@ -24,6 +24,15 @@ module.exports = class CommandParserVersionBase
@COMMENT = /([^\\]?)#.*/ @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 ############################################################################### # Public Methods ###############################################################################
parse: (text)-> parse: (text)->
@@ -60,7 +60,7 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
_command_item: (name='')-> _command_item: (name='')->
if not name.length > 0 then throw new Error 'the item name cannot be empty' if not name.length > 0 then throw new Error 'the item name cannot be empty'
@_itemData = name:name, line:@_lineNumber, group:@_rawData.group @_itemData = name:name, line:@_lineNumber, group:@_rawData.group, type:'new'
@_rawData.items ?= {} @_rawData.items ?= {}
@_rawData.items[name] = @_itemData @_rawData.items[name] = @_itemData
@@ -107,6 +107,15 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
if name.length is 0 then throw new Error 'tool names cannot be empty' if name.length is 0 then throw new Error 'tool names cannot be empty'
@_recipeData.tools.push name @_recipeData.tools.push name
_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
# Object Creation Methods ###################################################################### # Object Creation Methods ######################################################################
_buildModVersion: (modVersionData, modVersion)-> _buildModVersion: (modVersionData, modVersion)->
@@ -122,24 +131,28 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
itemData.gatherable ?= false itemData.gatherable ?= false
itemData.recipes ?= [] itemData.recipes ?= []
if itemData.type is 'new'
item = new Item name:itemData.name, isGatherable:itemData.gatherable, group:itemData.group item = new Item name:itemData.name, isGatherable:itemData.gatherable, group:itemData.group
modVersion.addItem item modVersion.addItem item
for recipeData in itemData.recipes for recipeData in itemData.recipes
@_handleErrors @_buildRecipe, modVersion, item, recipeData @_handleErrors @_buildRecipe, modVersion, itemData, recipeData
return item return item
_buildRecipe: (modVersion, item, recipeData)-> _buildRecipe: (modVersion, itemData, recipeData)->
@_lineNumber = recipeData.line @_lineNumber = recipeData.line
if not recipeData.input? then throw new Error 'the "input" declaration is required' if not recipeData.input? then throw new Error 'the "input" declaration is required'
if not recipeData.pattern? then throw new Error 'the "pattern" declaration is required' if not recipeData.pattern? then throw new Error 'the "pattern" declaration is required'
itemSlug = _.slugify itemData.name
modVersion.registerName itemSlug, itemData.name
if itemData.type is 'new' then itemSlug = _.composeSlugs modVersion.modSlug, itemSlug
qualifySlug = (name, slug)=> qualifySlug = (name, slug)=>
if @_rawData.items[name]? return slug unless itemData.type is 'new'
return slug unless @_rawData.items[name]?
return _.composeSlugs modVersion.modSlug, slug return _.composeSlugs modVersion.modSlug, slug
else
return slug
recipeData.quantity ?= 1 recipeData.quantity ?= 1
recipeData.extras ?= [] recipeData.extras ?= []
@@ -165,7 +178,8 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
name = modVersion.findName stack.slug name = modVersion.findName stack.slug
throw new Error "#{name} is an input for this recipe, but it is not in the pattern" throw new Error "#{name} is an input for this recipe, but it is not in the pattern"
outputStacks = [ new Stack slug:item.qualifiedSlug, quantity:recipeData.quantity ]
outputStacks = [ new Stack slug:itemSlug, quantity:recipeData.quantity ]
for extraData in recipeData.extras for extraData in recipeData.extras
slug = _.slugify extraData.name slug = _.slugify extraData.name
modVersion.registerName slug, extraData.name modVersion.registerName slug, extraData.name
@@ -179,22 +193,19 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
slug = qualifySlug name, slug slug = qualifySlug name, slug
toolStacks.push new Stack slug:slug, quantity:1 toolStacks.push new Stack slug:slug, quantity:1
attributes = recipe = new Recipe
input: inputStacks input: inputStacks
output: outputStacks output: outputStacks
pattern: recipeData.pattern pattern: recipeData.pattern
tools: toolStacks tools: toolStacks
recipe = new Recipe attributes
modVersion.addRecipe recipe modVersion.addRecipe recipe
logger.debug "adding recipe: #{recipe}"
return recipe return recipe
# Un-parsing Methods ########################################################################### # Un-parsing Methods ###########################################################################
_unparseModVersion: (builder, modVersion)-> _unparseModVersion: (builder, modVersion)->
itemList = []
modVersion.eachItem (item)-> itemList.push item
builder builder
.line 'schema: ', 1 .line 'schema: ', 1
.line() .line()
@@ -202,6 +213,13 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
modVersion.eachGroup (group)=> modVersion.eachGroup (group)=>
@_unparseGroup builder, modVersion, group @_unparseGroup builder, modVersion, group
for itemSlug, recipeList of modVersion.findExternalRecipes()
builder
.line 'update: ', modVersion.findName itemSlug
.indent()
.loop(recipeList, delimiter:'\n\n', onEach:(b, r)=> @_unparseRecipe(b, r))
.outdent()
_unparseGroup: (builder, modVersion, group)-> _unparseGroup: (builder, modVersion, group)->
if group isnt Item.Group.Other if group isnt Item.Group.Other
builder builder
@@ -210,15 +228,14 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
.indent() .indent()
modVersion.eachItemInGroup group, (item)=> modVersion.eachItemInGroup group, (item)=>
@_unparseItem builder, item @_unparseItem builder, modVersion, item
builder.line() builder.line()
if group isnt Item.Group.Other if group isnt Item.Group.Other
builder.outdent() builder.outdent()
_unparseItem: (builder, item)-> _unparseItem: (builder, modVersion, item)->
recipes = [] recipes = modVersion.findRecipes item.qualifiedSlug
item.eachRecipe (recipe)-> recipes.push recipe
builder builder
.line 'item: ', item.name .line 'item: ', item.name
-1
View File
@@ -43,7 +43,6 @@ describe 'crafting_plan.coffee', ->
it 'can craft a single step recipe', -> it 'can craft a single step recipe', ->
plan.want.add 'oak_plank' plan.want.add 'oak_plank'
plan.craft() plan.craft()
logger.debug "plan: #{plan}"
plan.need.toList().should.eql ['oak_log'] plan.need.toList().should.eql ['oak_log']
plan.result.toList().should.eql [[4, 'minecraft__oak_plank']] plan.result.toList().should.eql [[4, 'minecraft__oak_plank']]
@@ -5,6 +5,7 @@ Copyright (c) 2015 by Redwood Labs
All rights reserved. All rights reserved.
### ###
CommandParserVersionBase = require '../../src/scripts/models/parser_versions/command_parser_version_base'
ModVersion = require '../../src/scripts/models/mod_version' ModVersion = require '../../src/scripts/models/mod_version'
ModVersionParserV1 = require '../../src/scripts/models/parser_versions/mod_version_parser_v1' ModVersionParserV1 = require '../../src/scripts/models/parser_versions/mod_version_parser_v1'
@@ -28,7 +29,6 @@ describe 'mod_version_parser_v1.coffee', ->
recipe:; input:Bravo; pattern:... 0.0 ...;" recipe:; input:Bravo; pattern:... 0.0 ...;"
modVersion = parser.parse recipes modVersion = parser.parse recipes
recipes = modVersion.findRecipes 'test__charlie' recipes = modVersion.findRecipes 'test__charlie'
logger.debug "recipes: #{util.inspect(recipes)}"
recipes[0].input[0].slug.should.equal 'alpha' recipes[0].input[0].slug.should.equal 'alpha'
recipes[1].input[0].slug.should.equal 'bravo' recipes[1].input[0].slug.should.equal 'bravo'
@@ -208,3 +208,43 @@ describe 'mod_version_parser_v1.coffee', ->
it 'does not allow a duplicate "tools" declaration', -> it 'does not allow a duplicate "tools" declaration', ->
func = -> parser.parse baseText + 'tools:Crafting Table; tools:Furnace' func = -> parser.parse baseText + 'tools:Crafting Table; tools:Furnace'
expect(func).to.throw Error, 'duplicate declaration of "tools"' expect(func).to.throw Error, 'duplicate declaration of "tools"'
describe "unparsing", ->
beforeEach ->
baseText = """
schema: 1
group: Agriculture
item: Apple
item: Baked Potato
recipe:
input: Potato, furnace fuel
pattern: .0. ... .1.
tools: Furnace
group: Functional Blocks
item: Furnace
recipe:
input: Cobblestone
pattern: 000 0.0 000
tools: Crafting Table
update: Iron Ingot
recipe:
input: Iron Dust, furnace fuel
pattern: .0. ... .1.
tools: Furnace
"""
it 'can round-trip a data file', ->
text = parser.unparse parser.parse baseText
actual = CommandParserVersionBase.simplify text
expected = CommandParserVersionBase.simplify baseText
logger.debug "actual:\n>>>#{actual}<<<\n\n\n"
logger.debug "expected:\n>>>#{expected}<<<"
actual.should.equal expected