Merge branch 'master' into production

This commit is contained in:
Nick Winter 2014-05-20 12:01:19 -07:00
commit 465721fbda
12 changed files with 70 additions and 36 deletions

View file

@ -9,7 +9,7 @@ module.exports = class CocoClass
@nicksUsed: {} @nicksUsed: {}
@remainingNicks: [] @remainingNicks: []
@nextNick: -> @nextNick: ->
return "CocoClass " + classCount unless @nicks.length return (@name or "CocoClass") + " " + classCount unless @nicks.length
@remainingNicks = if @remainingNicks.length then @remainingNicks else @nicks.slice() @remainingNicks = if @remainingNicks.length then @remainingNicks else @nicks.slice()
baseNick = @remainingNicks.splice(Math.floor(Math.random() * @remainingNicks.length), 1)[0] baseNick = @remainingNicks.splice(Math.floor(Math.random() * @remainingNicks.length), 1)[0]
i = 0 i = 0
@ -37,7 +37,7 @@ module.exports = class CocoClass
destroy: -> destroy: ->
# teardown subscriptions, prevent new ones # teardown subscriptions, prevent new ones
@stopListening?() @stopListening?()
@off() @off?()
@unsubscribeAll() @unsubscribeAll()
@stopListeningToShortcuts() @stopListeningToShortcuts()
@constructor.nicksUsed[@nick] = false @constructor.nicksUsed[@nick] = false
@ -65,6 +65,7 @@ module.exports = class CocoClass
Backbone.Mediator.subscribe(channel, func, @) Backbone.Mediator.subscribe(channel, func, @)
unsubscribeAll: -> unsubscribeAll: ->
return unless Backbone?.Mediator?
for channel, func of @subscriptions for channel, func of @subscriptions
func = utils.normalizeFunc(func, @) func = utils.normalizeFunc(func, @)
Backbone.Mediator.unsubscribe(channel, func, @) Backbone.Mediator.unsubscribe(channel, func, @)

View file

@ -165,16 +165,27 @@ module.exports = class LevelLoader extends CocoClass
app.tracker.updatePlayState(@level, @session) unless @headless app.tracker.updatePlayState(@level, @session) unless @headless
buildLoop: => buildLoop: =>
return if @lastBuilt and new Date().getTime() - @lastBuilt < 10 someLeft = false
return clearInterval @buildLoopInterval unless @spriteSheetsToBuild.length
for spriteSheetResource, i in @spriteSheetsToBuild for spriteSheetResource, i in @spriteSheetsToBuild
if spriteSheetResource.thangType.loaded continue if spriteSheetResource.spriteSheetKeys
@buildSpriteSheetsForThangType spriteSheetResource.thangType someLeft = true
@spriteSheetsToBuild.splice i, 1 thangType = spriteSheetResource.thangType
@lastBuilt = new Date().getTime() if thangType.loaded and not thangType.loading
keys = @buildSpriteSheetsForThangType spriteSheetResource.thangType
if keys and keys.length
@listenTo spriteSheetResource.thangType, 'build-complete', @onBuildComplete
spriteSheetResource.spriteSheetKeys = keys
else
spriteSheetResource.markLoaded() spriteSheetResource.markLoaded()
return
clearInterval @buildLoopInterval unless someLeft
onBuildComplete: (e) ->
resource = null
for resource in @spriteSheetsToBuild
break if e.thangType is resource.thangType
resource.spriteSheetKeys = (k for k in resource.spriteSheetKeys when k isnt e.key)
resource.markLoaded() if resource.spriteSheetKeys.length is 0
denormalizeSession: -> denormalizeSession: ->
return if @headless or @sessionDenormalized or @spectateMode return if @headless or @sessionDenormalized or @spectateMode
@ -201,13 +212,16 @@ module.exports = class LevelLoader extends CocoClass
# queue = new createjs.LoadQueue() # queue = new createjs.LoadQueue()
# queue.loadFile('/file/'+f) # queue.loadFile('/file/'+f)
@grabThangTypeTeams() unless @thangTypeTeams @grabThangTypeTeams() unless @thangTypeTeams
keys = []
for team in @thangTypeTeams[thangType.get('original')] ? [null] for team in @thangTypeTeams[thangType.get('original')] ? [null]
spriteOptions = {resolutionFactor: SPRITE_RESOLUTION_FACTOR, async: false} spriteOptions = {resolutionFactor: SPRITE_RESOLUTION_FACTOR, async: true}
if thangType.get('kind') is 'Floor' if thangType.get('kind') is 'Floor'
spriteOptions.resolutionFactor = 2 spriteOptions.resolutionFactor = 2
if team and color = @teamConfigs[team]?.color if team and color = @teamConfigs[team]?.color
spriteOptions.colorConfig = team: color spriteOptions.colorConfig = team: color
@buildSpriteSheet thangType, spriteOptions key = @buildSpriteSheet thangType, spriteOptions
if _.isString(key) then keys.push key
keys
grabThangTypeTeams: -> grabThangTypeTeams: ->
@grabTeamConfigs() @grabTeamConfigs()

View file

@ -33,6 +33,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
camera: null camera: null
spriteSheetCache: null spriteSheetCache: null
showInvisible: false showInvisible: false
async: true
possessed: false possessed: false
flipped: false flipped: false
@ -75,28 +76,32 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@ranges = [] @ranges = []
@handledDisplayEvents = {} @handledDisplayEvents = {}
@age = 0 @age = 0
@stillLoading = true
if @thangType.isFullyLoaded() if @thangType.isFullyLoaded()
@setupSprite() @setupSprite()
else else
@stillLoading = true
@thangType.fetch() @thangType.fetch()
@listenToOnce(@thangType, 'sync', @setupSprite) @listenToOnce(@thangType, 'sync', @setupSprite)
setupSprite: -> setupSprite: ->
for trigger, sounds of @thangType.get('soundTriggers') or {} when trigger isnt 'say' for trigger, sounds of @thangType.get('soundTriggers') or {} when trigger isnt 'say'
AudioPlayer.preloadSoundReference sound for sound in sounds AudioPlayer.preloadSoundReference sound for sound in sounds
@stillLoading = false
if @thangType.get('raster') if @thangType.get('raster')
@stillLoading = false
@actions = {} @actions = {}
@isRaster = true @isRaster = true
@setUpRasterImage() @setUpRasterImage()
else else
result = @buildSpriteSheet()
if _.isString result # async build
@listenToOnce @thangType, 'build-complete', @setupSprite
else
@stillLoading = false
@actions = @thangType.getActions() @actions = @thangType.getActions()
@buildFromSpriteSheet @buildSpriteSheet() @buildFromSpriteSheet result
@createMarks() @createMarks()
finishSetup: -> finishSetup: ->
return unless @thang
@updateBaseScale() @updateBaseScale()
@scaleFactor = @thang.scaleFactor if @thang?.scaleFactor @scaleFactor = @thang.scaleFactor if @thang?.scaleFactor
@update true # Reflect initial scale and other state @update true # Reflect initial scale and other state
@ -120,7 +125,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
buildSpriteSheet: -> buildSpriteSheet: ->
options = _.extend @options, @thang?.getSpriteOptions?() ? {} options = _.extend @options, @thang?.getSpriteOptions?() ? {}
options.colorConfig = @options.colorConfig if @options.colorConfig options.colorConfig = @options.colorConfig if @options.colorConfig
options.async = false options.async = @options.async
@thangType.getSpriteSheet options @thangType.getSpriteSheet options
setImageObject: (newImageObject) -> setImageObject: (newImageObject) ->
@ -677,6 +682,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
updateGold: -> updateGold: ->
# TODO: eventually this should be moved into some sort of team-based update # TODO: eventually this should be moved into some sort of team-based update
# rather than an each-thang-that-shows-gold-per-team thing. # rather than an each-thang-that-shows-gold-per-team thing.
return unless @thang
return if @thang.gold is @lastGold return if @thang.gold is @lastGold
gold = Math.floor @thang.gold gold = Math.floor @thang.gold
if @thang.world.age is 0 if @thang.world.age is 0

View file

@ -181,7 +181,8 @@ module.exports = class Mark extends CocoClass
return @listenToOnce(@thangType, 'sync', @onLoadedThangType) if not @thangType.loaded return @listenToOnce(@thangType, 'sync', @onLoadedThangType) if not @thangType.loaded
CocoSprite = require './CocoSprite' CocoSprite = require './CocoSprite'
markSprite = new CocoSprite @thangType, @thangType.spriteOptions # don't bother with making these render async for now, but maybe later for fun and more complexity of code
markSprite = new CocoSprite @thangType, {async: false}
markSprite.queueAction 'idle' markSprite.queueAction 'idle'
@mark = markSprite.imageObject @mark = markSprite.imageObject
@markSprite = markSprite @markSprite = markSprite

View file

@ -39,8 +39,6 @@ module.exports = class WizardSprite extends IndieSprite
else if options.name else if options.name
@setNameLabel options.name @setNameLabel options.name
finishSetup: -> # No initial setup update needed.
makeIndieThang: (thangType, thangID, pos) -> makeIndieThang: (thangType, thangID, pos) ->
thang = super thangType, thangID, pos thang = super thangType, thangID, pos
thang.isSelectable = false thang.isSelectable = false

View file

@ -14,6 +14,7 @@ module.exports = class GoalManager extends CocoClass
# If you want weird goals or hybrid goals, make a custom goal. # If you want weird goals or hybrid goals, make a custom goal.
nextGoalID: 0 nextGoalID: 0
nicks: ["GoalManager"]
constructor: (@world, @initialGoals, @team) -> constructor: (@world, @initialGoals, @team) ->
super() super()

View file

@ -62,7 +62,7 @@ module.exports = class ThangType extends CocoModel
@options = @fillOptions options @options = @fillOptions options
key = @spriteSheetKey(@options) key = @spriteSheetKey(@options)
if ss = @spriteSheets[key] then return ss if ss = @spriteSheets[key] then return ss
return if @building[key] return key if @building[key]
@t0 = new Date().getTime() @t0 = new Date().getTime()
@initBuild(options) @initBuild(options)
@addGeneralFrames() unless @options.portraitOnly @addGeneralFrames() unless @options.portraitOnly
@ -151,25 +151,34 @@ module.exports = class ThangType extends CocoModel
buildQueue.push @builder buildQueue.push @builder
@builder.t0 = new Date().getTime() @builder.t0 = new Date().getTime()
@builder.buildAsync() unless buildQueue.length > 1 @builder.buildAsync() unless buildQueue.length > 1
@builder.on 'complete', @onBuildSpriteSheetComplete, @, true, key @builder.on 'complete', @onBuildSpriteSheetComplete, @, true, [@builder, key, @options]
return true @builder = null
return key
spriteSheet = @builder.build() spriteSheet = @builder.build()
console.debug "Built #{@get('name')}#{if @options.portraitOnly then ' portrait' else ''} in #{new Date().getTime() - @t0}ms." @logBuild @t0, false, @options.portraitOnly
@spriteSheets[key] = spriteSheet @spriteSheets[key] = spriteSheet
delete @building[key] delete @building[key]
@builder = null
spriteSheet spriteSheet
onBuildSpriteSheetComplete: (e, key) -> onBuildSpriteSheetComplete: (e, data) ->
console.log "Built #{@get('name')}#{if @options.portraitOnly then ' portrait' else ''} async in #{new Date().getTime() - @builder.t0}ms." if @builder [builder, key, options] = data
@logBuild builder.t0, true, options.portraitOnly
buildQueue = buildQueue.slice(1) buildQueue = buildQueue.slice(1)
buildQueue[0].t0 = new Date().getTime() if buildQueue[0] buildQueue[0].t0 = new Date().getTime() if buildQueue[0]
buildQueue[0]?.buildAsync() buildQueue[0]?.buildAsync()
@spriteSheets[key] = e.target.spriteSheet @spriteSheets[key] = e.target.spriteSheet
delete @building[key] delete @building[key]
@trigger 'build-complete' @trigger 'build-complete', {key:key, thangType:@}
@builder = null
@vectorParser = null @vectorParser = null
logBuild: (startTime, async, portrait) ->
kind = if async then 'Async' else 'Sync '
portrait = if portrait then '(Portrait)' else ''
name = _.string.rpad @get('name'), 20
time = _.string.lpad '' + new Date().getTime() - startTime, 6
console.debug "Built sheet: #{name} #{time}ms #{kind} #{portrait}"
spriteSheetKey: (options) -> spriteSheetKey: (options) ->
colorConfigs = [] colorConfigs = []
for groupName, config of options.colorConfig or {} for groupName, config of options.colorConfig or {}
@ -196,6 +205,7 @@ module.exports = class ThangType extends CocoModel
options = if _.isPlainObject spriteOptionsOrKey then spriteOptionsOrKey else {} options = if _.isPlainObject spriteOptionsOrKey then spriteOptionsOrKey else {}
options.portraitOnly = true options.portraitOnly = true
spriteSheet = @buildSpriteSheet(options) spriteSheet = @buildSpriteSheet(options)
return if _.isString spriteSheet
return unless spriteSheet return unless spriteSheet
canvas = $("<canvas width='#{size}' height='#{size}'></canvas>") canvas = $("<canvas width='#{size}' height='#{size}'></canvas>")
stage = new createjs.Stage(canvas[0]) stage = new createjs.Stage(canvas[0])

View file

@ -638,7 +638,7 @@ block content
.tab-pane.well#rules .tab-pane.well#rules
h1(data-i18n="ladder.tournament_rules") Tournament Rules h1(data-i18n="ladder.tournament_rules") Tournament Rules
h2 General h2 General
p You don't have to buy anything to participate in the tournament, and trying to pay us won't increase your odds of winning. p You don't have to buy anything to participate in the tournament, and trying to pay us won't increase your odds of winning. Although we don't anticipate the rules changing, they are subject to change.
h2 Dates and Times h2 Dates and Times
p The tournament starts on Tuesday, May 20 at 8:30AM and ends on Tuesday, June 10 at 5:00PM PDT. After the tournament finishes, we will check the games manually to prevent duplicate entries and cheating. We will email all the winners within two weeks of the end date. p The tournament starts on Tuesday, May 20 at 8:30AM and ends on Tuesday, June 10 at 5:00PM PDT. After the tournament finishes, we will check the games manually to prevent duplicate entries and cheating. We will email all the winners within two weeks of the end date.

View file

@ -150,6 +150,7 @@ module.exports = class LadderTabView extends CocoView
# LADDER LOADING # LADDER LOADING
refreshLadder: -> refreshLadder: ->
@supermodel.resetProgress()
@ladderLimit ?= parseInt @getQueryVariable('top_players', 20) @ladderLimit ?= parseInt @getQueryVariable('top_players', 20)
for team in @teams for team in @teams
@leaderboards[team.id]?.destroy() @leaderboards[team.id]?.destroy()

View file

@ -25,6 +25,7 @@ module.exports = class ThangAvatarView extends View
# couldn't get the level view to load properly through the supermodel # couldn't get the level view to load properly through the supermodel
# so just doing it manually this time. # so just doing it manually this time.
@listenTo @thangType, 'sync', @render @listenTo @thangType, 'sync', @render
@listenTo @thangType, 'build-complete', @render
getSpriteThangType: -> getSpriteThangType: ->
thangs = @supermodel.getModels(ThangType) thangs = @supermodel.getModels(ThangType)
@ -36,7 +37,7 @@ module.exports = class ThangAvatarView extends View
context = super context context = super context
context.thang = @thang context.thang = @thang
options = @thang?.getSpriteOptions() or {} options = @thang?.getSpriteOptions() or {}
options.async = false options.async = true
context.avatarURL = @thangType.getPortraitSource(options) unless @thangType.loading context.avatarURL = @thangType.getPortraitSource(options) unless @thangType.loading
context.includeName = @includeName context.includeName = @includeName
context context

View file

@ -290,6 +290,7 @@ module.exports = class PlayLevelView extends View
unless @isEditorPreview unless @isEditorPreview
@loadEndTime = new Date() @loadEndTime = new Date()
loadDuration = @loadEndTime - @loadStartTime loadDuration = @loadEndTime - @loadStartTime
console.debug "Level unveiled after #{(loadDuration / 1000).toFixed(2)}s"
application.tracker?.trackEvent 'Finished Level Load', level: @levelID, label: @levelID, loadDuration: loadDuration application.tracker?.trackEvent 'Finished Level Load', level: @levelID, label: @levelID, loadDuration: loadDuration
application.tracker?.trackTiming loadDuration, 'Level Load Time', @levelID, @levelID application.tracker?.trackTiming loadDuration, 'Level Load Time', @levelID, @levelID