Add support for conditional recipes
This commit is contained in:
@@ -144,6 +144,8 @@ module.exports = class ModVersion extends BaseModel
|
|||||||
otherRecipes = []
|
otherRecipes = []
|
||||||
|
|
||||||
for recipe in _.values @_recipes
|
for recipe in _.values @_recipes
|
||||||
|
continue unless recipe.isConditionSatisfied()
|
||||||
|
|
||||||
if recipe.itemSlug.matches itemSlug
|
if recipe.itemSlug.matches itemSlug
|
||||||
primaryRecipes.push recipe
|
primaryRecipes.push recipe
|
||||||
else if recipe.produces itemSlug
|
else if recipe.produces itemSlug
|
||||||
|
|||||||
@@ -70,6 +70,21 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
|
|||||||
for name in inputNames
|
for name in inputNames
|
||||||
@_recipeData.input.push @_parseStack name
|
@_recipeData.input.push @_parseStack name
|
||||||
|
|
||||||
|
_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='')->
|
_command_pattern: (pattern='')->
|
||||||
if not @_recipeData? then throw new Error 'cannot declare "pattern" before "recipe"'
|
if not @_recipeData? then throw new Error 'cannot declare "pattern" before "recipe"'
|
||||||
if @_recipeData.pattern? then throw new Error 'duplicate declaration of "pattern"'
|
if @_recipeData.pattern? then throw new Error 'duplicate declaration of "pattern"'
|
||||||
@@ -155,10 +170,11 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
|
|||||||
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'
|
||||||
|
|
||||||
recipe = new Recipe
|
recipe = new Recipe
|
||||||
input: @_buildStackList modVersion, recipeData.input, recipeData.pattern
|
condition: recipeData.condition
|
||||||
output: @_buildStackList modVersion, recipeData.output
|
input: @_buildStackList modVersion, recipeData.input, recipeData.pattern
|
||||||
pattern: recipeData.pattern
|
output: @_buildStackList modVersion, recipeData.output
|
||||||
tools: @_buildStackList modVersion, recipeData.tools
|
pattern: recipeData.pattern
|
||||||
|
tools: @_buildStackList modVersion, recipeData.tools
|
||||||
|
|
||||||
modVersion.addRecipe recipe
|
modVersion.addRecipe recipe
|
||||||
return recipe
|
return recipe
|
||||||
@@ -274,6 +290,10 @@ module.exports = class ModVersionParserV1 extends CommandParserVersionBase
|
|||||||
builder
|
builder
|
||||||
.line 'recipe:'
|
.line 'recipe:'
|
||||||
.indent()
|
.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, =>
|
.onlyIf extraOutputs.length > 0, =>
|
||||||
builder
|
builder
|
||||||
.push 'extras: '
|
.push 'extras: '
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ module.exports = class Recipe extends BaseModel
|
|||||||
|
|
||||||
attributes.pattern = @_parsePattern attributes.pattern
|
attributes.pattern = @_parsePattern attributes.pattern
|
||||||
|
|
||||||
|
attributes.condition ?= null
|
||||||
attributes.modVersion ?= null
|
attributes.modVersion ?= null
|
||||||
attributes.tools ?= []
|
attributes.tools ?= []
|
||||||
options.logEvents ?= false
|
options.logEvents ?= false
|
||||||
@@ -114,6 +115,22 @@ module.exports = class Recipe extends BaseModel
|
|||||||
|
|
||||||
return total
|
return total
|
||||||
|
|
||||||
|
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)->
|
isPassThroughFor: (itemSlug)->
|
||||||
amountCreated = 0
|
amountCreated = 0
|
||||||
for stack in @output
|
for stack in @output
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ describe 'mod_version.coffee', ->
|
|||||||
item: Cake
|
item: Cake
|
||||||
recipe:; input: Milk, Sugar, Egg, Wheat; pattern: 000 121 333; extras: 3 Bucket
|
recipe:; input: Milk, Sugar, Egg, Wheat; pattern: 000 121 333; extras: 3 Bucket
|
||||||
recipe:; input: Milk, Cocoa Beans, Egg, Wheat; pattern: 000 121 333; extras: 3 Bucket
|
recipe:; input: Milk, Cocoa Beans, Egg, Wheat; pattern: 000 121 333; extras: 3 Bucket
|
||||||
|
recipe:; input: Cake Slice; pattern: 000 000 000; onlyIf: item Cake Slice
|
||||||
item: Bucket
|
item: Bucket
|
||||||
recipe:; input: Iron Ingot; pattern: ... 0.0 .0.
|
recipe:; input: Iron Ingot; pattern: ... 0.0 .0.
|
||||||
"""
|
"""
|
||||||
@@ -94,3 +95,7 @@ describe 'mod_version.coffee', ->
|
|||||||
it 'finds all recipes which list item as output', ->
|
it 'finds all recipes which list item as output', ->
|
||||||
recipes = modVersion.findRecipes ItemSlug.slugify('test__bucket')
|
recipes = modVersion.findRecipes ItemSlug.slugify('test__bucket')
|
||||||
(r.output[0].itemSlug.item for r in recipes).sort().should.eql ['bucket', 'cake', 'cake']
|
(r.output[0].itemSlug.item for r in recipes).sort().should.eql ['bucket', 'cake', 'cake']
|
||||||
|
|
||||||
|
it 'skip recipes whose conditions are not met', ->
|
||||||
|
recipes = modVersion.findRecipes ItemSlug.slugify 'test__cake'
|
||||||
|
recipes.length.should.equal 2
|
||||||
|
|||||||
@@ -158,6 +158,40 @@ describe 'mod_version_parser_v1.coffee', ->
|
|||||||
func = -> parser.parse 'item:Bravo; quantity:12; recipe:;'
|
func = -> parser.parse 'item:Bravo; quantity:12; recipe:;'
|
||||||
expect(func).to.throw Error, 'cannot declare "quantity" before "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', ->
|
describe 'output', ->
|
||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@@ -250,6 +284,11 @@ describe 'mod_version_parser_v1.coffee', ->
|
|||||||
input: furnace fuel, Iron Dust
|
input: furnace fuel, Iron Dust
|
||||||
pattern: .1. ... .0.
|
pattern: .1. ... .0.
|
||||||
tools: Furnace
|
tools: Furnace
|
||||||
|
recipe:
|
||||||
|
onlyIf: item Redstone Furnace
|
||||||
|
input: Iron Ore
|
||||||
|
pattern: ... .0. ...
|
||||||
|
tools: Redstone Furnace
|
||||||
"""
|
"""
|
||||||
|
|
||||||
it 'can round-trip a data file', ->
|
it 'can round-trip a data file', ->
|
||||||
|
|||||||
Reference in New Issue
Block a user