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
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
findRecipes: ->
result = @modPack.findRecipes @item?.qualifiedSlug
return null unless result.length > 0
return result
return @modPack.findRecipes @item?.slug
# Private Methods ##############################################################################
+14 -3
View File
@@ -101,7 +101,8 @@ module.exports = class ModVersion extends BaseModel
return this
findName: (slug)->
return @_names[slug]
[modSlug, itemSlug] = _.decomposeSlug slug
return @_names[itemSlug]
registerName: (slug, name)->
hasSlug = @_names[slug]?
@@ -127,14 +128,24 @@ module.exports = class ModVersion extends BaseModel
return this
findRecipes: (itemSlug, result=[])->
recipeList = @_recipes[itemSlug]
findRecipes: (slug, result=[])->
recipeList = @_recipes[slug]
if recipeList?
for recipe in recipeList
result.push recipe
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)->
recipeList = @_recipes[itemSlug]
return true if recipeList? and recipeList.length > 0
@@ -24,6 +24,15 @@ module.exports = class CommandParserVersionBase
@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)->
@@ -60,7 +60,7 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
_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
@_itemData = name:name, line:@_lineNumber, group:@_rawData.group, type:'new'
@_rawData.items ?= {}
@_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'
@_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 ######################################################################
_buildModVersion: (modVersionData, modVersion)->
@@ -122,24 +131,28 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
itemData.gatherable ?= false
itemData.recipes ?= []
if itemData.type is 'new'
item = new Item name:itemData.name, isGatherable:itemData.gatherable, group:itemData.group
modVersion.addItem item
for recipeData in itemData.recipes
@_handleErrors @_buildRecipe, modVersion, item, recipeData
@_handleErrors @_buildRecipe, modVersion, itemData, recipeData
return item
_buildRecipe: (modVersion, item, recipeData)->
_buildRecipe: (modVersion, itemData, recipeData)->
@_lineNumber = recipeData.line
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'
itemSlug = _.slugify itemData.name
modVersion.registerName itemSlug, itemData.name
if itemData.type is 'new' then itemSlug = _.composeSlugs modVersion.modSlug, itemSlug
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
else
return slug
recipeData.quantity ?= 1
recipeData.extras ?= []
@@ -165,7 +178,8 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
name = modVersion.findName stack.slug
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
slug = _.slugify extraData.name
modVersion.registerName slug, extraData.name
@@ -179,22 +193,19 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
slug = qualifySlug name, slug
toolStacks.push new Stack slug:slug, quantity:1
attributes =
recipe = new Recipe
input: inputStacks
output: outputStacks
pattern: recipeData.pattern
tools: toolStacks
recipe = new Recipe attributes
modVersion.addRecipe recipe
logger.debug "adding recipe: #{recipe}"
return recipe
# Un-parsing Methods ###########################################################################
_unparseModVersion: (builder, modVersion)->
itemList = []
modVersion.eachItem (item)-> itemList.push item
builder
.line 'schema: ', 1
.line()
@@ -202,6 +213,13 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
modVersion.eachGroup (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)->
if group isnt Item.Group.Other
builder
@@ -210,15 +228,14 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
.indent()
modVersion.eachItemInGroup group, (item)=>
@_unparseItem builder, item
@_unparseItem builder, modVersion, item
builder.line()
if group isnt Item.Group.Other
builder.outdent()
_unparseItem: (builder, item)->
recipes = []
item.eachRecipe (recipe)-> recipes.push recipe
_unparseItem: (builder, modVersion, item)->
recipes = modVersion.findRecipes item.qualifiedSlug
builder
.line 'item: ', item.name
-1
View File
@@ -43,7 +43,6 @@ describe 'crafting_plan.coffee', ->
it 'can craft a single step recipe', ->
plan.want.add 'oak_plank'
plan.craft()
logger.debug "plan: #{plan}"
plan.need.toList().should.eql ['oak_log']
plan.result.toList().should.eql [[4, 'minecraft__oak_plank']]
@@ -5,6 +5,7 @@ Copyright (c) 2015 by Redwood Labs
All rights reserved.
###
CommandParserVersionBase = require '../../src/scripts/models/parser_versions/command_parser_version_base'
ModVersion = require '../../src/scripts/models/mod_version'
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 ...;"
modVersion = parser.parse recipes
recipes = modVersion.findRecipes 'test__charlie'
logger.debug "recipes: #{util.inspect(recipes)}"
recipes[0].input[0].slug.should.equal 'alpha'
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', ->
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: 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