* Change default item URL to fall under /mod/<mod slug>/<item slug> but kept the old URL pattern around with the old behavior (i.e., find the first item with that slug) * Update Item to have a `qualifiedSlug` property which combines the item's own slug with its Mod's slug. Updated a lot of code all over to use this in preference to the plain slug. * Add a `localizeTo` method to Inventory to allow non-qualified slugs to be converted into qualified slugs within the inventory's stacks * Update ModPack to work with either qualified or unqualified slugs for relevant methods * Fix model state changes to happen before related events are triggered * Add a debounce to the CraftingPlan object when triggering a recraft due to changes in related objects (esp. its inventories) * Update the Inventory's sort to keep items sorted by mod before name with the Minecraft items sorted to the top * Fix `ModPack.findItemByName` to actually recursively use the Mod's method instead of slugifying the given name and looking for the slug (since this won't necessarily work anymore). * Ensure each Mod is assigned a reference to its containing ModPack * Fix NameFinder to only consider an item non-gatherable if it is also craftable * Update ModVersionParserV1 to assign qualified slugs to recipes for any items which are in the same mod (leaving any other slugs unqualified) * Add Underscore mixins for composing and decomposing slugs * Update old tests for the use of qualified slugs, and some new tests for the new methods added
177 lines
5.8 KiB
CoffeeScript
177 lines
5.8 KiB
CoffeeScript
###
|
|
Crafting Guide - mod.coffee
|
|
|
|
Copyright (c) 2015 by Redwood Labs
|
|
All rights reserved.
|
|
###
|
|
|
|
BaseModel = require './base_model'
|
|
{Event} = require '../constants'
|
|
{RequiredMods} = require '../constants'
|
|
{Url} = require '../constants'
|
|
|
|
########################################################################################################################
|
|
|
|
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 = []
|
|
|
|
Object.defineProperties this,
|
|
'activeModVersion': { get:-> @_activeModVersion }
|
|
'activeVersion': { get:@getActiveVersion, set:@setActiveVersion }
|
|
'enabled': { get:-> @_activeModVersion? }
|
|
|
|
# Class Methods ##################################################################################
|
|
|
|
@Version =
|
|
None: 'none'
|
|
Latest: 'latest'
|
|
|
|
# Public Methods #################################################################################
|
|
|
|
compareTo: (that)->
|
|
thisRequired = this.slug in RequiredMods
|
|
thatRequired = that.slug in RequiredMods
|
|
|
|
if thisRequired isnt thatRequired
|
|
return -1 if thisRequired
|
|
return +1 if thatRequired
|
|
else
|
|
if this.name isnt that.name
|
|
return if this.name < that.name then -1 else +1
|
|
|
|
return 0
|
|
|
|
# ModVersion Proxy Methods #####################################################################
|
|
|
|
eachItem: (callback)->
|
|
return unless @_activeModVersion?
|
|
@_activeModVersion.eachItem callback
|
|
|
|
eachName: (callback)->
|
|
return unless @_activeModVersion?
|
|
@_activeModVersion.eachName 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
|
|
|
|
findName: (slug)->
|
|
return unless @_activeModVersion?
|
|
@_activeModVersion.findName slug
|
|
|
|
findRecipes: (slug, result=[])->
|
|
return result unless @_activeModVersion?
|
|
@_activeModVersion.findRecipes slug, result
|
|
|
|
# Property Methods #############################################################################
|
|
|
|
addModVersion: (modVersion)->
|
|
return unless modVersion?
|
|
return if @_modVersions.indexOf(modVersion) isnt -1
|
|
|
|
@_modVersions.push modVersion
|
|
@listenTo modVersion, Event.change, => @trigger Event.change, this
|
|
modVersion.mod = this
|
|
|
|
@trigger Event.add + ':modVersion', modVersion, this
|
|
@trigger Event.change + ':version', modVersion, this
|
|
@trigger 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
|
|
|
|
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
|
|
|
|
getActiveVersion: ->
|
|
return @_activeVersion
|
|
|
|
setActiveVersion: (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 Event.change + ':activeVersion', this, @_activeVersion
|
|
@trigger Event.change, this
|
|
else
|
|
for modVersion in @_modVersions
|
|
if version is modVersion.version
|
|
@_activateModVersion modVersion
|
|
break
|
|
|
|
@_activeVersion = version
|
|
@trigger Event.change + ':activeVersion', this, @_activeVersion
|
|
@trigger Event.change, this
|
|
|
|
|
|
# Backbone.View Overrides ######################################################################
|
|
|
|
parse: (text)->
|
|
ModParser = require './mod_parser' # to avoid require cycles
|
|
@_parser ?= new ModParser model:this
|
|
@_parser.parse text
|
|
|
|
return null # prevent calling `set`
|
|
|
|
url: ->
|
|
return Url.modData modSlug:@slug
|
|
|
|
# Private Methods ##############################################################################
|
|
|
|
_activateModVersion: (modVersion)->
|
|
if @_activeModVersion? then @stopListening @_activeModVersion
|
|
@_activeModVersion = modVersion
|
|
@trigger Event.change + ':activeModVersion', this, @_activeModVersion
|
|
|
|
logger.verbose => "#{@slug} switched to version #{@_activeVersion}"
|
|
|
|
if @_activeModVersion?
|
|
@listenTo @_activeModVersion, 'all', -> @trigger.apply this, arguments
|