Merge branch 'master' into production
|
@ -14,7 +14,8 @@ module.exports = class CocoRouter extends Backbone.Router
|
||||||
Backbone.Mediator.subscribe 'router:navigate', @onNavigate, @
|
Backbone.Mediator.subscribe 'router:navigate', @onNavigate, @
|
||||||
|
|
||||||
routes:
|
routes:
|
||||||
'': go('HomeView')
|
'': go('HomeView') # This will go somewhere deprecated when FrontView is done.
|
||||||
|
'front': go('FrontView') # This will become '' when it is done.
|
||||||
|
|
||||||
'about': go('AboutView')
|
'about': go('AboutView')
|
||||||
|
|
||||||
|
@ -73,7 +74,8 @@ module.exports = class CocoRouter extends Backbone.Router
|
||||||
|
|
||||||
'multiplayer': go('MultiplayerView')
|
'multiplayer': go('MultiplayerView')
|
||||||
|
|
||||||
'play': go('play/MainPlayView')
|
'play': go('play/MainPlayView') # This will become 'play-old' or something.
|
||||||
|
'play-hero': go('play/WorldMapView') # This will become 'play' when it is done.
|
||||||
'play/ladder/:levelID': go('play/ladder/LadderView')
|
'play/ladder/:levelID': go('play/ladder/LadderView')
|
||||||
'play/ladder': go('play/ladder/MainLadderView')
|
'play/ladder': go('play/ladder/MainLadderView')
|
||||||
'play/level/:levelID': go('play/level/PlayLevelView')
|
'play/level/:levelID': go('play/level/PlayLevelView')
|
||||||
|
|
BIN
app/assets/images/pages/front/play_web.jpg
Normal file
After Width: | Height: | Size: 59 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
BIN
app/assets/images/pages/play/map_forest.jpg
Normal file
After Width: | Height: | Size: 1.1 MiB |
BIN
app/assets/images/pages/play/menu_icons.png
Normal file
After Width: | Height: | Size: 83 KiB |
|
@ -202,7 +202,7 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
thangsToLoad = _.uniq( (t.spriteName for t in @world.thangs when t.exists) )
|
thangsToLoad = _.uniq( (t.spriteName for t in @world.thangs when t.exists) )
|
||||||
nameModelTuples = ([thangType.get('name'), thangType] for thangType in @thangNames.models)
|
nameModelTuples = ([thangType.get('name'), thangType] for thangType in @thangNames.models)
|
||||||
nameModelMap = _.zipObject nameModelTuples
|
nameModelMap = _.zipObject nameModelTuples
|
||||||
@spriteSheetsToBuild = []
|
@spriteSheetsToBuild ?= []
|
||||||
|
|
||||||
for thangTypeName in thangsToLoad
|
for thangTypeName in thangsToLoad
|
||||||
thangType = nameModelMap[thangTypeName]
|
thangType = nameModelMap[thangTypeName]
|
||||||
|
@ -230,7 +230,7 @@ module.exports = class LevelLoader extends CocoClass
|
||||||
|
|
||||||
buildLoop: =>
|
buildLoop: =>
|
||||||
someLeft = false
|
someLeft = false
|
||||||
for spriteSheetResource, i in @spriteSheetsToBuild
|
for spriteSheetResource, i in @spriteSheetsToBuild ? []
|
||||||
continue if spriteSheetResource.spriteSheetKeys
|
continue if spriteSheetResource.spriteSheetKeys
|
||||||
someLeft = true
|
someLeft = true
|
||||||
thangType = spriteSheetResource.thangType
|
thangType = spriteSheetResource.thangType
|
||||||
|
|
|
@ -79,6 +79,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
@handledDisplayEvents = {}
|
@handledDisplayEvents = {}
|
||||||
@age = 0
|
@age = 0
|
||||||
@stillLoading = true
|
@stillLoading = true
|
||||||
|
@setNameLabel @thang.id if @thang?.showsName and not @thang.health <= 0
|
||||||
if @thangType.isFullyLoaded()
|
if @thangType.isFullyLoaded()
|
||||||
@setUpSprite()
|
@setUpSprite()
|
||||||
else
|
else
|
||||||
|
@ -488,6 +489,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
rotation = @getRotation()
|
rotation = @getRotation()
|
||||||
if relatedActions['111111111111'] # has grid-surrounding-wall-based actions
|
if relatedActions['111111111111'] # has grid-surrounding-wall-based actions
|
||||||
if @wallGrid
|
if @wallGrid
|
||||||
|
@hadWallGrid = true
|
||||||
action = ''
|
action = ''
|
||||||
tileSize = 4
|
tileSize = 4
|
||||||
[gx, gy] = [@thang.pos.x, @thang.pos.y]
|
[gx, gy] = [@thang.pos.x, @thang.pos.y]
|
||||||
|
@ -514,6 +516,8 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
break
|
break
|
||||||
#console.log 'returning', matchedAction, 'for', @thang.id, 'at', gx, gy
|
#console.log 'returning', matchedAction, 'for', @thang.id, 'at', gx, gy
|
||||||
return relatedActions[matchedAction]
|
return relatedActions[matchedAction]
|
||||||
|
else if @hadWallGrid
|
||||||
|
return null
|
||||||
else
|
else
|
||||||
keys = _.keys relatedActions
|
keys = _.keys relatedActions
|
||||||
index = Math.max 0, Math.floor((179 + rotation) / 360 * keys.length)
|
index = Math.max 0, Math.floor((179 + rotation) / 360 * keys.length)
|
||||||
|
@ -527,13 +531,15 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
|
||||||
relatedActions[direction]
|
relatedActions[direction]
|
||||||
|
|
||||||
updateStats: ->
|
updateStats: ->
|
||||||
|
return unless @thang and @thang.health isnt @lastHealth
|
||||||
|
@lastHealth = @thang.health
|
||||||
if bar = @healthBar
|
if bar = @healthBar
|
||||||
return if @thang.health is @lastHealth
|
|
||||||
@lastHealth = @thang.health
|
|
||||||
healthPct = Math.max(@thang.health / @thang.maxHealth, 0)
|
healthPct = Math.max(@thang.health / @thang.maxHealth, 0)
|
||||||
bar.scaleX = healthPct / bar.baseScale
|
bar.scaleX = healthPct / bar.baseScale
|
||||||
healthOffset = @getOffset 'aboveHead'
|
healthOffset = @getOffset 'aboveHead'
|
||||||
[bar.x, bar.y] = [healthOffset.x - bar.width / 2, healthOffset.y]
|
[bar.x, bar.y] = [healthOffset.x - bar.width / 2, healthOffset.y]
|
||||||
|
if @thang.showsName
|
||||||
|
@setNameLabel(if @thang.health <= 0 then '' else @thang.id)
|
||||||
|
|
||||||
configureMouse: ->
|
configureMouse: ->
|
||||||
@imageObject.cursor = 'pointer' if @thang?.isSelectable
|
@imageObject.cursor = 'pointer' if @thang?.isSelectable
|
||||||
|
|
|
@ -22,7 +22,7 @@ module.exports = class RegionChooser extends CocoClass
|
||||||
onMouseMove: (e) =>
|
onMouseMove: (e) =>
|
||||||
return unless @firstPoint
|
return unless @firstPoint
|
||||||
@secondPoint = @options.camera.screenToWorld {x: e.stageX, y: e.stageY}
|
@secondPoint = @options.camera.screenToWorld {x: e.stageX, y: e.stageY}
|
||||||
@restrictRegion() if @options.restrictRatio
|
@restrictRegion() if @options.restrictRatio or key.alt
|
||||||
@updateShape()
|
@updateShape()
|
||||||
|
|
||||||
onMouseUp: (e) =>
|
onMouseUp: (e) =>
|
||||||
|
|
|
@ -186,11 +186,11 @@ module.exports = class SpriteBoss extends CocoClass
|
||||||
sprite.update frameChanged for sprite in @spriteArray
|
sprite.update frameChanged for sprite in @spriteArray
|
||||||
@updateSelection()
|
@updateSelection()
|
||||||
@spriteLayers['Default'].updateLayerOrder()
|
@spriteLayers['Default'].updateLayerOrder()
|
||||||
@cache()
|
@cacheObstacles()
|
||||||
|
|
||||||
adjustSpriteExistence: ->
|
adjustSpriteExistence: ->
|
||||||
# Add anything new, remove anything old, update everything current
|
# Add anything new, remove anything old, update everything current
|
||||||
updateCache = false
|
updatedObstacles = []
|
||||||
itemsJustEquipped = []
|
itemsJustEquipped = []
|
||||||
for thang in @world.thangs when thang.exists and thang.pos
|
for thang in @world.thangs when thang.exists and thang.pos
|
||||||
itemsJustEquipped = itemsJustEquipped.concat @equipNewItems thang
|
itemsJustEquipped = itemsJustEquipped.concat @equipNewItems thang
|
||||||
|
@ -199,16 +199,16 @@ module.exports = class SpriteBoss extends CocoClass
|
||||||
else
|
else
|
||||||
sprite = @addThangToSprites(thang)
|
sprite = @addThangToSprites(thang)
|
||||||
Backbone.Mediator.publish 'surface:new-thang-added', thang: thang, sprite: sprite
|
Backbone.Mediator.publish 'surface:new-thang-added', thang: thang, sprite: sprite
|
||||||
updateCache = updateCache or sprite.imageObject.parent is @spriteLayers['Obstacle']
|
updatedObstacles.push sprite if sprite.imageObject.parent is @spriteLayers['Obstacle']
|
||||||
sprite.playSounds()
|
sprite.playSounds()
|
||||||
item.modifyStats() for item in itemsJustEquipped
|
item.modifyStats() for item in itemsJustEquipped
|
||||||
for thangID, sprite of @sprites
|
for thangID, sprite of @sprites
|
||||||
missing = not (sprite.notOfThisWorld or @world.thangMap[thangID]?.exists)
|
missing = not (sprite.notOfThisWorld or @world.thangMap[thangID]?.exists)
|
||||||
isObstacle = sprite.imageObject.parent is @spriteLayers['Obstacle']
|
isObstacle = sprite.imageObject.parent is @spriteLayers['Obstacle']
|
||||||
updateCache = updateCache or (isObstacle and (missing or sprite.hasMoved))
|
updatedObstacles.push sprite if isObstacle and (missing or sprite.hasMoved)
|
||||||
sprite.hasMoved = false
|
sprite.hasMoved = false
|
||||||
@removeSprite sprite if missing
|
@removeSprite sprite if missing
|
||||||
@cache true if updateCache and @cached
|
@cacheObstacles updatedObstacles if updatedObstacles.length and @cachedObstacles
|
||||||
|
|
||||||
# mainly for handling selecting thangs from session when the thang is not always in existence
|
# mainly for handling selecting thangs from session when the thang is not always in existence
|
||||||
if @willSelectThang and @sprites[@willSelectThang[0]]
|
if @willSelectThang and @sprites[@willSelectThang[0]]
|
||||||
|
@ -229,25 +229,26 @@ module.exports = class SpriteBoss extends CocoClass
|
||||||
itemsJustEquipped.push item
|
itemsJustEquipped.push item
|
||||||
return itemsJustEquipped
|
return itemsJustEquipped
|
||||||
|
|
||||||
cache: (update=false) ->
|
cacheObstacles: (updatedObstacles=null) ->
|
||||||
return if @cached and not update
|
return if @cachedObstacles and not updatedObstacles
|
||||||
wallSprites = (sprite for sprite in @spriteArray when sprite.thangType?.get('name').search(/(dungeon|indoor).wall/i) isnt -1)
|
wallSprites = (sprite for sprite in @spriteArray when sprite.thangType?.get('name').search(/(dungeon|indoor).wall/i) isnt -1)
|
||||||
return if _.any (s.stillLoading for s in wallSprites)
|
return if _.any (s.stillLoading for s in wallSprites)
|
||||||
walls = (sprite.thang for sprite in wallSprites)
|
walls = (sprite.thang for sprite in wallSprites)
|
||||||
@world.calculateBounds()
|
@world.calculateBounds()
|
||||||
wallGrid = new Grid walls, @world.size()...
|
wallGrid = new Grid walls, @world.size()...
|
||||||
for wallSprite in wallSprites
|
if updatedObstacles
|
||||||
|
possiblyUpdatedWallSprites = (sprite for sprite in wallSprites when _.find updatedObstacles, (w2) -> sprite is w2 or (Math.abs(sprite.thang.pos.x - w2.thang.pos.x) + Math.abs(sprite.thang.pos.y - w2.thang.pos.y)) <= 16)
|
||||||
|
else
|
||||||
|
possiblyUpdatedWallSprites = wallSprites
|
||||||
|
#console.log 'updating up to', possiblyUpdatedWallSprites.length, 'of', wallSprites.length, 'wall sprites from updatedObstacles', updatedObstacles
|
||||||
|
for wallSprite in possiblyUpdatedWallSprites
|
||||||
wallSprite.updateActionDirection wallGrid
|
wallSprite.updateActionDirection wallGrid
|
||||||
wallSprite.updateScale()
|
wallSprite.updateScale()
|
||||||
wallSprite.updatePosition()
|
wallSprite.updatePosition()
|
||||||
#console.log @wallGrid.toString()
|
#console.log @wallGrid.toString()
|
||||||
@spriteLayers['Obstacle'].uncache() if @spriteLayers['Obstacle'].cacheID # might have changed sizes
|
@spriteLayers['Obstacle'].uncache() if @spriteLayers['Obstacle'].cacheID # might have changed sizes
|
||||||
@spriteLayers['Obstacle'].cache()
|
@spriteLayers['Obstacle'].cache()
|
||||||
# test performance of doing land layer, too, to see if it's faster
|
@cachedObstacles = true
|
||||||
# @spriteLayers['Land'].uncache() if @spriteLayers['Land'].cacheID # might have changed sizes
|
|
||||||
# @spriteLayers['Land'].cache()
|
|
||||||
# I don't notice much difference - Scott
|
|
||||||
@cached = true
|
|
||||||
|
|
||||||
spriteFor: (thangID) -> @sprites[thangID]
|
spriteFor: (thangID) -> @sprites[thangID]
|
||||||
|
|
||||||
|
|
|
@ -488,7 +488,7 @@ module.exports = Surface = class Surface extends CocoClass
|
||||||
#- Canvas callbacks
|
#- Canvas callbacks
|
||||||
|
|
||||||
onResize: (e) =>
|
onResize: (e) =>
|
||||||
return if @destroyed
|
return if @destroyed or @options.choosing
|
||||||
oldWidth = parseInt @canvas.attr('width'), 10
|
oldWidth = parseInt @canvas.attr('width'), 10
|
||||||
oldHeight = parseInt @canvas.attr('height'), 10
|
oldHeight = parseInt @canvas.attr('height'), 10
|
||||||
aspectRatio = oldWidth / oldHeight
|
aspectRatio = oldWidth / oldHeight
|
||||||
|
|
|
@ -139,7 +139,7 @@ module.exports = class GoalManager extends CocoClass
|
||||||
@initGoalState(state, [[], keepFrom.keepFromLocation?.who], 'arrived')
|
@initGoalState(state, [[], keepFrom.keepFromLocation?.who], 'arrived')
|
||||||
@initGoalState(state, [goal.getToLocations?.who, goal.keepFromLocations?.who], 'arrived')
|
@initGoalState(state, [goal.getToLocations?.who, goal.keepFromLocations?.who], 'arrived')
|
||||||
@initGoalState(state, [goal.leaveOffSides?.who, goal.keepFromLeavingOffSides?.who], 'left')
|
@initGoalState(state, [goal.leaveOffSides?.who, goal.keepFromLeavingOffSides?.who], 'left')
|
||||||
@initGoalState(state, [goal.collectThangs?.who, goal.keepFromCollectingThangs?.who], 'collected')
|
@initGoalState(state, [goal.collectThangs?.targets, goal.keepFromCollectingThangs?.targets], 'collected')
|
||||||
@goalStates[goal.id] = state
|
@goalStates[goal.id] = state
|
||||||
|
|
||||||
onThangDied: (e, frameNumber) ->
|
onThangDied: (e, frameNumber) ->
|
||||||
|
@ -169,23 +169,23 @@ module.exports = class GoalManager extends CocoClass
|
||||||
|
|
||||||
onThangLeftMap: (e, frameNumber) ->
|
onThangLeftMap: (e, frameNumber) ->
|
||||||
for goal in @goals ? []
|
for goal in @goals ? []
|
||||||
@checkLeft(goal.id, goal.leaveOffSides.who, goal.leaveOffSides.sides, e.thang.id, e.side, frameNumber) if goal.leaveOffSides?
|
@checkLeft(goal.id, goal.leaveOffSides.who, goal.leaveOffSides.sides, e.thang, e.side, frameNumber) if goal.leaveOffSides?
|
||||||
@checkLeft(goal.id, goal.keepFromLeavingOffSides.who, goal.keepFromLeavingOffSides.sides, e.thang.id, e.side, frameNumber) if goal.keepFromLeavingOffSides?
|
@checkLeft(goal.id, goal.keepFromLeavingOffSides.who, goal.keepFromLeavingOffSides.sides, e.thang, e.side, frameNumber) if goal.keepFromLeavingOffSides?
|
||||||
|
|
||||||
checkLeft: (goalID, who, sides, thangID, side, frameNumber) ->
|
checkLeft: (goalID, who, sides, thang, side, frameNumber) ->
|
||||||
return if sides and side and not (side in sides)
|
return if sides and side and not (side in sides)
|
||||||
return unless thangID in who
|
return unless thang.id in who or thang.team in who
|
||||||
@updateGoalState(goalID, thangID, 'left', frameNumber)
|
@updateGoalState(goalID, thang.id, 'left', frameNumber)
|
||||||
|
|
||||||
onThangCollectedItem: (e, frameNumber) ->
|
onThangCollectedItem: (e, frameNumber) ->
|
||||||
for goal in @goals ? []
|
for goal in @goals ? []
|
||||||
@checkCollected(goal.id, goal.collectThangs.who, goal.collectThangs.targets, e.actor.id, e.item.id, frameNumber) if goal.collectThangs?
|
@checkCollected(goal.id, goal.collectThangs.who, goal.collectThangs.targets, e.actor, e.item.id, frameNumber) if goal.collectThangs?
|
||||||
@checkCollected(goal.id, goal.keepFromCollectingThangs.who, goal.keepFromCollectingThangs.targets, e.actor.id, e.item.id, frameNumber) if goal.keepFromCollectingThangs?
|
@checkCollected(goal.id, goal.keepFromCollectingThangs.who, goal.keepFromCollectingThangs.targets, e.actor, e.item.id, frameNumber) if goal.keepFromCollectingThangs?
|
||||||
|
|
||||||
checkCollected: (goalID, who, targets, thangID, itemID, frameNumber) ->
|
checkCollected: (goalID, who, targets, thang, itemID, frameNumber) ->
|
||||||
return unless itemID in targets
|
return unless itemID in targets
|
||||||
return unless thangID in who
|
return unless thang.id in who or thang.team in who
|
||||||
@updateGoalState(goalID, thangID, 'collected', frameNumber)
|
@updateGoalState(goalID, itemID, 'collected', frameNumber)
|
||||||
|
|
||||||
wrapUpGoalStates: (finalFrame) ->
|
wrapUpGoalStates: (finalFrame) ->
|
||||||
for goalID, state of @goalStates
|
for goalID, state of @goalStates
|
||||||
|
|
|
@ -131,6 +131,19 @@
|
||||||
spectate: "Spectate"
|
spectate: "Spectate"
|
||||||
players: "players"
|
players: "players"
|
||||||
hours_played: "hours played"
|
hours_played: "hours played"
|
||||||
|
items: "Items"
|
||||||
|
heroes: "Heroes"
|
||||||
|
achievements: "Achievements"
|
||||||
|
account: "Account"
|
||||||
|
settings: "Settings"
|
||||||
|
|
||||||
|
items:
|
||||||
|
armor: "Armor"
|
||||||
|
hands: "Hands"
|
||||||
|
accessories: "Accessories"
|
||||||
|
books: "Books"
|
||||||
|
minions: "Minions"
|
||||||
|
misc: "Misc"
|
||||||
|
|
||||||
contact:
|
contact:
|
||||||
contact_us: "Contact CodeCombat"
|
contact_us: "Contact CodeCombat"
|
||||||
|
@ -878,7 +891,6 @@
|
||||||
tutorial_play_first: "Play the Tutorial first."
|
tutorial_play_first: "Play the Tutorial first."
|
||||||
simple_ai: "Simple AI"
|
simple_ai: "Simple AI"
|
||||||
warmup: "Warmup"
|
warmup: "Warmup"
|
||||||
vs: "VS"
|
|
||||||
friends_playing: "Friends Playing"
|
friends_playing: "Friends Playing"
|
||||||
log_in_for_friends: "Log in to play with your friends!"
|
log_in_for_friends: "Log in to play with your friends!"
|
||||||
social_connect_blurb: "Connect and play against your friends!"
|
social_connect_blurb: "Connect and play against your friends!"
|
||||||
|
|
|
@ -62,7 +62,7 @@ class CocoModel extends Backbone.Model
|
||||||
super(attribute)
|
super(attribute)
|
||||||
|
|
||||||
set: (attributes, options) ->
|
set: (attributes, options) ->
|
||||||
delete @attributesWithDefaults
|
delete @attributesWithDefaults unless attributes is 'thangs' # unless attributes is 'thangs': performance optimization for Levels keeping their cache.
|
||||||
inFlux = @loading or not @loaded
|
inFlux = @loading or not @loaded
|
||||||
@markToRevert() unless inFlux or @_revertAttributes or @project or options?.fromMerge
|
@markToRevert() unless inFlux or @_revertAttributes or @project or options?.fromMerge
|
||||||
res = super attributes, options
|
res = super attributes, options
|
||||||
|
@ -125,8 +125,12 @@ class CocoModel extends Backbone.Model
|
||||||
error(@, res) if error
|
error(@, res) if error
|
||||||
return unless @notyErrors
|
return unless @notyErrors
|
||||||
errorMessage = "Error saving #{@get('name') ? @type()}"
|
errorMessage = "Error saving #{@get('name') ? @type()}"
|
||||||
console.error errorMessage, res.responseJSON
|
console.log 'going to log an error message'
|
||||||
noty text: "#{errorMessage}: #{res.status} #{res.statusText}", layout: 'topCenter', type: 'error', killer: false, timeout: 10000
|
console.warn errorMessage, res.responseJSON
|
||||||
|
try
|
||||||
|
noty text: "#{errorMessage}: #{res.status} #{res.statusText}", layout: 'topCenter', type: 'error', killer: false, timeout: 10000
|
||||||
|
catch notyError
|
||||||
|
console.warn "Couldn't even show noty error for", error, "because", notyError
|
||||||
@trigger 'save', @
|
@trigger 'save', @
|
||||||
return super attrs, options
|
return super attrs, options
|
||||||
|
|
||||||
|
|
|
@ -170,14 +170,31 @@ module.exports = class Level extends CocoModel
|
||||||
thang.components = sorted
|
thang.components = sorted
|
||||||
|
|
||||||
fillInDefaultComponentConfiguration: (thangs, levelComponents) ->
|
fillInDefaultComponentConfiguration: (thangs, levelComponents) ->
|
||||||
|
# This is slow, so I inserted some optimizations to speed it up by caching the eventual defaults of commonly-used Components.
|
||||||
|
@defaultComponentConfigurations ?= {}
|
||||||
|
cached = 0
|
||||||
|
missed = 0
|
||||||
|
cachedConfigs = 0
|
||||||
for thang in thangs ? []
|
for thang in thangs ? []
|
||||||
for component in thang.components or []
|
for component in thang.components or []
|
||||||
|
isPhysical = component.original is LevelComponent.PhysicalID
|
||||||
|
if not isPhysical and defaultConfiguration = _.find @defaultComponentConfigurations[component.original], ((d) -> _.isEqual component, d.originalComponent)
|
||||||
|
component.config = defaultConfiguration.defaultedConfig
|
||||||
|
++cached
|
||||||
|
continue
|
||||||
continue unless lc = _.find levelComponents, {original: component.original}
|
continue unless lc = _.find levelComponents, {original: component.original}
|
||||||
|
unless isPhysical
|
||||||
|
originalComponent = $.extend true, {}, component
|
||||||
component.config ?= {}
|
component.config ?= {}
|
||||||
TreemaUtils.populateDefaults(component.config, lc.configSchema, tv4)
|
TreemaUtils.populateDefaults(component.config, lc.configSchema ? {}, tv4)
|
||||||
@lastType = 'component'
|
@lastType = 'component'
|
||||||
@lastOriginal = component.original
|
@lastOriginal = component.original
|
||||||
@walkDefaults component.config, lc.configSchema.properties
|
unless isPhysical
|
||||||
|
@defaultComponentConfigurations[component.original] ?= []
|
||||||
|
@defaultComponentConfigurations[component.original].push originalComponent: originalComponent, defaultedConfig: component.config
|
||||||
|
++cachedConfigs
|
||||||
|
++missed
|
||||||
|
#console.log 'cached', cached, 'missed', missed
|
||||||
|
|
||||||
fillInDefaultSystemConfiguration: (levelSystems) ->
|
fillInDefaultSystemConfiguration: (levelSystems) ->
|
||||||
for system in levelSystems ? []
|
for system in levelSystems ? []
|
||||||
|
@ -185,21 +202,6 @@ module.exports = class Level extends CocoModel
|
||||||
TreemaUtils.populateDefaults(system.config, system.model.configSchema, tv4)
|
TreemaUtils.populateDefaults(system.config, system.model.configSchema, tv4)
|
||||||
@lastType = 'system'
|
@lastType = 'system'
|
||||||
@lastOriginal = system.model.name
|
@lastOriginal = system.model.name
|
||||||
@walkDefaults system.config, system.model.configSchema.properties
|
|
||||||
|
|
||||||
walkDefaults: (config, properties) ->
|
|
||||||
# This function is redundant, but is the old implementation.
|
|
||||||
# Remove it and calls to it once we stop seeing these warnings.
|
|
||||||
return unless properties
|
|
||||||
for prop, schema of properties
|
|
||||||
if schema.default? and config[prop] is undefined
|
|
||||||
console.warn 'Setting default of', config, 'for', prop, 'to', schema.default, 'but this method is deprecated... check your config schema!', @lastType, @lastOriginal
|
|
||||||
config[prop] = schema.default
|
|
||||||
if schema.type is 'object' and config[prop]
|
|
||||||
@walkDefaults config[prop], schema.properties
|
|
||||||
else if schema.type is 'array' and config[prop]
|
|
||||||
for item in config[prop] or []
|
|
||||||
@walkDefaults item, schema.items
|
|
||||||
|
|
||||||
dimensions: ->
|
dimensions: ->
|
||||||
width = 0
|
width = 0
|
||||||
|
|
|
@ -104,7 +104,7 @@ NoteGroupSchema = c.object {title: 'Note Group', description: 'A group of notes
|
||||||
target: c.shortString(title: 'Target', description: 'Target highlight element DOM selector string.')
|
target: c.shortString(title: 'Target', description: 'Target highlight element DOM selector string.')
|
||||||
delay: {type: 'integer', minimum: 0, title: 'Delay', description: 'Show the highlight after this many milliseconds. Doesn\'t affect the dim shade cutout highlight method.'}
|
delay: {type: 'integer', minimum: 0, title: 'Delay', description: 'Show the highlight after this many milliseconds. Doesn\'t affect the dim shade cutout highlight method.'}
|
||||||
offset: _.extend _.cloneDeep(PointSchema), {title: 'Offset', description: 'Pointing arrow tip offset in pixels from the default target.', format: null}
|
offset: _.extend _.cloneDeep(PointSchema), {title: 'Offset', description: 'Pointing arrow tip offset in pixels from the default target.', format: null}
|
||||||
rotation: {type: 'number', minimum: 0, title: 'Rotation', description: 'Rotation of the pointing arrow, in radians. PI / 2 points left, PI points up, etc.'}
|
rotation: {type: 'number', minimum: 0, title: 'Rotation', description: 'Rotation of the pointing arrow, in radians. PI / 2 points left, PI points up, etc.', format: 'radians'}
|
||||||
sides: c.array {title: 'Sides', description: 'Which sides of the target element to point at.'}, {type: 'string', 'enum': ['left', 'right', 'top', 'bottom'], title: 'Side', description: 'A side of the target element to point at.'}
|
sides: c.array {title: 'Sides', description: 'Which sides of the target element to point at.'}, {type: 'string', 'enum': ['left', 'right', 'top', 'bottom'], title: 'Side', description: 'A side of the target element to point at.'}
|
||||||
lock: {title: 'Lock', description: 'Whether the interface should be locked so that the player\'s focus is on the script, or specific areas to lock.', type: ['boolean', 'array'], items: {type: 'string', enum: ['surface', 'editor', 'palette', 'hud', 'playback', 'playback-hover', 'level']}}
|
lock: {title: 'Lock', description: 'Whether the interface should be locked so that the player\'s focus is on the script, or specific areas to lock.', type: ['boolean', 'array'], items: {type: 'string', enum: ['surface', 'editor', 'palette', 'hud', 'playback', 'playback-hover', 'level']}}
|
||||||
letterbox: {type: 'boolean', title: 'Letterbox', description: 'Turn letterbox mode on or off. Disables surface and playback controls.'}
|
letterbox: {type: 'boolean', title: 'Letterbox', description: 'Turn letterbox mode on or off. Disables surface and playback controls.'}
|
||||||
|
|
|
@ -102,7 +102,7 @@ DependencySchema = c.object {
|
||||||
LevelComponentSchema = c.object {
|
LevelComponentSchema = c.object {
|
||||||
title: 'Component'
|
title: 'Component'
|
||||||
description: 'A Component which can affect Thang behavior.'
|
description: 'A Component which can affect Thang behavior.'
|
||||||
required: ['system', 'name', 'description', 'code', 'dependencies', 'propertyDocumentation', 'codeLanguage']
|
required: ['system', 'name', 'code']
|
||||||
default:
|
default:
|
||||||
system: 'ai'
|
system: 'ai'
|
||||||
name: 'AttacksSelf'
|
name: 'AttacksSelf'
|
||||||
|
|
|
@ -24,6 +24,10 @@ module.exports =
|
||||||
'editor:edit-level-thang': c.object {required: ['thangID']},
|
'editor:edit-level-thang': c.object {required: ['thangID']},
|
||||||
thangID: {type: 'string'}
|
thangID: {type: 'string'}
|
||||||
|
|
||||||
|
'editor:level-thang-edited': c.object {required: ['thangData', 'oldPath']},
|
||||||
|
thangData: {type: 'object'}
|
||||||
|
oldPath: {type: 'string'}
|
||||||
|
|
||||||
'editor:level-thang-done-editing': c.object {required: ['thangData', 'oldPath']},
|
'editor:level-thang-done-editing': c.object {required: ['thangData', 'oldPath']},
|
||||||
thangData: {type: 'object'}
|
thangData: {type: 'object'}
|
||||||
oldPath: {type: 'string'}
|
oldPath: {type: 'string'}
|
||||||
|
|
30
app/styles/front-view.sass
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
@import "bootstrap/mixins"
|
||||||
|
@import "bootstrap/variables"
|
||||||
|
|
||||||
|
#front-view
|
||||||
|
h1
|
||||||
|
text-align: center
|
||||||
|
margin-top: 0
|
||||||
|
|
||||||
|
.platform-choices
|
||||||
|
a
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
.panel
|
||||||
|
@include transition(background-color 0.5s ease)
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
text-decoration: none
|
||||||
|
|
||||||
|
.panel
|
||||||
|
background-color: rgb(230, 230, 255)
|
||||||
|
|
||||||
|
.platform-ios
|
||||||
|
img
|
||||||
|
transform: scaleY(-1)
|
||||||
|
|
||||||
|
@media only screen and (max-width: 800px)
|
||||||
|
#front-view
|
||||||
|
#site-slogan
|
||||||
|
font-size: 30px
|
||||||
|
margin-bottom: 30px
|
|
@ -47,3 +47,17 @@
|
||||||
color: black
|
color: black
|
||||||
text-shadow: 0 1px 0 white
|
text-shadow: 0 1px 0 white
|
||||||
|
|
||||||
|
|
||||||
|
.modal.play-modal
|
||||||
|
.modal-header
|
||||||
|
border: 0
|
||||||
|
text-align: center
|
||||||
|
padding: 0
|
||||||
|
margin: 0 25px
|
||||||
|
|
||||||
|
h3
|
||||||
|
margin-bottom: 0
|
||||||
|
|
||||||
|
.modal-body
|
||||||
|
padding-top: 0
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,7 @@
|
||||||
height: 100px
|
height: 100px
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
background: white
|
background: white
|
||||||
border: 1px solid #333
|
border-radius: 8px
|
||||||
border-radius: 5px
|
|
||||||
position: relative
|
position: relative
|
||||||
-webkit-transition: opacity 0.3s ease-in-out
|
-webkit-transition: opacity 0.3s ease-in-out
|
||||||
-moz-transition: opacity 0.3s ease-in-out
|
-moz-transition: opacity 0.3s ease-in-out
|
||||||
|
@ -46,15 +45,15 @@
|
||||||
.my-team-icon
|
.my-team-icon
|
||||||
height: 60px
|
height: 60px
|
||||||
position: relative
|
position: relative
|
||||||
top: -10px
|
top: -3.5px
|
||||||
left: 10px
|
left: 13.5px
|
||||||
z-index: 0
|
z-index: 0
|
||||||
|
|
||||||
.opponent-team-icon
|
.opponent-team-icon
|
||||||
height: 60px
|
height: 60px
|
||||||
position: relative
|
position: relative
|
||||||
top: 10px
|
top: 16.5px
|
||||||
right: 10px
|
right: 13.5px
|
||||||
z-index: 0
|
z-index: 0
|
||||||
float: right
|
float: right
|
||||||
-moz-transform: scaleX(-1)
|
-moz-transform: scaleX(-1)
|
||||||
|
@ -78,19 +77,19 @@
|
||||||
z-index: 1
|
z-index: 1
|
||||||
|
|
||||||
.name-label
|
.name-label
|
||||||
border-bottom: 20px solid lightslategray
|
height: 20px
|
||||||
height: 0
|
|
||||||
width: 40%
|
width: 40%
|
||||||
position: absolute
|
position: absolute
|
||||||
bottom: 0
|
bottom: 0
|
||||||
color: black
|
color: white
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
|
text-shadow: -1px -1px 0px black
|
||||||
text-align: center
|
text-align: center
|
||||||
z-index: 2
|
z-index: 2
|
||||||
|
|
||||||
span
|
span
|
||||||
position: relative
|
position: relative
|
||||||
top: 1px
|
top: 4px
|
||||||
|
|
||||||
.code-language
|
.code-language
|
||||||
position: absolute
|
position: absolute
|
||||||
|
@ -116,9 +115,6 @@
|
||||||
right: 3px
|
right: 3px
|
||||||
|
|
||||||
.difficulty
|
.difficulty
|
||||||
border-top: 25px solid darkgray
|
|
||||||
border-left: 20px solid transparent
|
|
||||||
border-right: 20px solid transparent
|
|
||||||
height: 0
|
height: 0
|
||||||
width: 30%
|
width: 30%
|
||||||
position: absolute
|
position: absolute
|
||||||
|
@ -131,17 +127,21 @@
|
||||||
|
|
||||||
span
|
span
|
||||||
position: relative
|
position: relative
|
||||||
top: -25px
|
top: 6px
|
||||||
|
|
||||||
.easy-option .difficulty
|
.play-option
|
||||||
border-top: 25px solid limegreen
|
background-image: url(/images/pages/play/ladder/warmup_button.png)
|
||||||
|
|
||||||
.medium-option .difficulty
|
.easy-option
|
||||||
border-top: 25px solid darkorange
|
background-image: url(/images/pages/play/ladder/easy_button.png)
|
||||||
|
|
||||||
.hard-option .difficulty
|
.medium-option
|
||||||
border-top: 25px solid black
|
background-image: url(/images/pages/play/ladder/medium_button.png)
|
||||||
color: white
|
|
||||||
|
.hard-option
|
||||||
|
background-image: url(/images/pages/play/ladder/hard_button.png)
|
||||||
|
.difficulty
|
||||||
|
color: white
|
||||||
|
|
||||||
.vs
|
.vs
|
||||||
position: absolute
|
position: absolute
|
||||||
|
|
4
app/styles/play/modal/play-account-modal.sass
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#play-account-modal
|
||||||
|
.account-view
|
||||||
|
color: black
|
||||||
|
|
4
app/styles/play/modal/play-achievements-modal.sass
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#play-achievements-modal
|
||||||
|
.achievement-view
|
||||||
|
color: black
|
||||||
|
|
4
app/styles/play/modal/play-heroes-modal.sass
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#play-heroes-modal
|
||||||
|
.hero-view
|
||||||
|
color: black
|
||||||
|
|
8
app/styles/play/modal/play-items-modal.sass
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#play-items-modal
|
||||||
|
.item-view
|
||||||
|
width: 420px
|
||||||
|
float: left
|
||||||
|
background-color: white
|
||||||
|
border-radius: 6px
|
||||||
|
margin: 5px
|
||||||
|
|
4
app/styles/play/modal/play-settings-modal.sass
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
#play-settings-modal
|
||||||
|
.settings-view
|
||||||
|
color: black
|
||||||
|
|
151
app/styles/play/world-map-view.sass
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
@import "app/styles/bootstrap/mixins"
|
||||||
|
@import "app/styles/bootstrap/variables"
|
||||||
|
|
||||||
|
$forestMapWidth: 2500
|
||||||
|
$forestMapHeight: 1536
|
||||||
|
$forestMapSeaBackground: #71bad0
|
||||||
|
$levelDotWidth: 2%
|
||||||
|
$levelDotHeight: $levelDotWidth * $forestMapWidth / $forestMapHeight
|
||||||
|
$levelDotZ: $levelDotHeight * 0.25
|
||||||
|
$levelDotHoverZ: $levelDotZ * 2
|
||||||
|
$levelDotShadowWidth: 0.8 * $levelDotWidth
|
||||||
|
$levelDotShadowHeight: 0.8 * $levelDotHeight
|
||||||
|
$levelClickRadius: 40px
|
||||||
|
$gameControlSize: 80px
|
||||||
|
$gameControlMargin: 40px
|
||||||
|
|
||||||
|
#world-map-view
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
background-color: $forestMapSeaBackground
|
||||||
|
|
||||||
|
.map
|
||||||
|
//background: white url("/images/pages/play/map_forest.jpg") no-repeat center center
|
||||||
|
position: relative
|
||||||
|
|
||||||
|
.map-background
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
|
||||||
|
.level, .level-shadow
|
||||||
|
position: absolute
|
||||||
|
border-radius: 100%
|
||||||
|
transform: scaleY(0.75)
|
||||||
|
|
||||||
|
.level
|
||||||
|
z-index: 2
|
||||||
|
width: $levelDotWidth
|
||||||
|
height: $levelDotHeight
|
||||||
|
margin-left: -0.5 * $levelDotWidth
|
||||||
|
margin-bottom: -$levelDotHeight / 3 + $levelDotZ
|
||||||
|
border: 2px groove white
|
||||||
|
@include transition(margin-bottom 0.5s ease)
|
||||||
|
|
||||||
|
&.disabled
|
||||||
|
opacity: 0.7
|
||||||
|
|
||||||
|
&.first
|
||||||
|
width: 2 * $levelDotWidth
|
||||||
|
height: 2 * $levelDotHeight
|
||||||
|
margin-left: -0.5 * 2 * $levelDotWidth
|
||||||
|
margin-bottom: -2 * $levelDotHeight / 3 + 2 * $levelDotZ
|
||||||
|
|
||||||
|
.level-shadow
|
||||||
|
z-index: 1
|
||||||
|
width: $levelDotShadowWidth
|
||||||
|
height: $levelDotShadowHeight
|
||||||
|
margin-left: -0.5 * $levelDotShadowWidth
|
||||||
|
margin-bottom: -$levelDotShadowHeight / 3
|
||||||
|
background-color: black
|
||||||
|
box-shadow: 0px 0px 10px black
|
||||||
|
@include opacity(0.75)
|
||||||
|
|
||||||
|
&.first
|
||||||
|
width: 2 * $levelDotShadowWidth
|
||||||
|
height: 2 * $levelDotShadowHeight
|
||||||
|
margin-left: -0.5 * 2 * $levelDotShadowWidth
|
||||||
|
margin-bottom: -2 * $levelDotShadowHeight / 3
|
||||||
|
|
||||||
|
.level:hover
|
||||||
|
margin-bottom: -$levelDotHeight / 3 + $levelDotHoverZ
|
||||||
|
|
||||||
|
.level
|
||||||
|
a
|
||||||
|
display: block
|
||||||
|
padding: $levelClickRadius
|
||||||
|
margin-left: -0.5 * $levelClickRadius
|
||||||
|
margin-top: -0.5 * $levelClickRadius
|
||||||
|
border-radius: $levelClickRadius
|
||||||
|
|
||||||
|
&.first a
|
||||||
|
padding: 2 * $levelClickRadius
|
||||||
|
margin-left: 2 * -0.5 * $levelClickRadius
|
||||||
|
margin-top: 2 * -0.5 * $levelClickRadius
|
||||||
|
border-radius: 2 * $levelClickRadius
|
||||||
|
|
||||||
|
.level-info-container
|
||||||
|
display: none
|
||||||
|
position: absolute
|
||||||
|
z-index: 3
|
||||||
|
padding: 10px 10px 30px 10px
|
||||||
|
border-image: url(/images/level/popover_background.png) 18 fill round
|
||||||
|
border-width: 15px
|
||||||
|
|
||||||
|
.level-image
|
||||||
|
float: left
|
||||||
|
margin-right: 20px
|
||||||
|
|
||||||
|
.level-info.complete h3:after
|
||||||
|
content: " - Complete!"
|
||||||
|
color: green
|
||||||
|
|
||||||
|
.level-info.started h3:after
|
||||||
|
content: " - Started"
|
||||||
|
color: desaturate(green, 50%)
|
||||||
|
|
||||||
|
.level-info
|
||||||
|
width: 330px
|
||||||
|
float: left
|
||||||
|
|
||||||
|
h3
|
||||||
|
margin-top: 0
|
||||||
|
margin-bottom: 0px
|
||||||
|
|
||||||
|
.level-description
|
||||||
|
color: black
|
||||||
|
text-shadow: 0 1px 0 white
|
||||||
|
|
||||||
|
.campaign-label
|
||||||
|
text-shadow: 0 1px 0 white
|
||||||
|
|
||||||
|
.game-controls
|
||||||
|
position: absolute
|
||||||
|
right: 1%
|
||||||
|
bottom: 1%
|
||||||
|
|
||||||
|
button.btn
|
||||||
|
&:not(:first-child)
|
||||||
|
margin-left: $gameControlMargin
|
||||||
|
width: $gameControlSize
|
||||||
|
height: $gameControlSize
|
||||||
|
background: url(/images/pages/play/menu_icons.png) no-repeat
|
||||||
|
background-size: cover
|
||||||
|
@include transition(0.5s ease)
|
||||||
|
box-shadow: 0 0 0 #bbf
|
||||||
|
border: 0
|
||||||
|
border-radius: 12px
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
box-shadow: 0 0 12px #bbf
|
||||||
|
|
||||||
|
&:active
|
||||||
|
box-shadow: 0 0 20px white
|
||||||
|
|
||||||
|
&.heroes
|
||||||
|
background-position-x: -1 * $gameControlSize
|
||||||
|
&.achievements
|
||||||
|
background-position-x: -2 * $gameControlSize
|
||||||
|
&.account
|
||||||
|
background-position-x: -3 * $gameControlSize
|
||||||
|
&.settings
|
||||||
|
background-position-x: -4 * $gameControlSize
|
|
@ -177,7 +177,7 @@ block content
|
||||||
if !editing && !myProfile
|
if !editing && !myProfile
|
||||||
button#contact-candidate.btn.btn-large.btn-inverse.flat-button
|
button#contact-candidate.btn.btn-large.btn-inverse.flat-button
|
||||||
span(data-i18n="account_profile.contact") Contact
|
span(data-i18n="account_profile.contact") Contact
|
||||||
| #{profile.name.split(' ')[0]}
|
| #{(profile.name || user.get('name') || 'Anonymous').split(' ')[0]}
|
||||||
if me.isAdmin()
|
if me.isAdmin()
|
||||||
select#admin-contact.form-control
|
select#admin-contact.form-control
|
||||||
for contact in adminContacts
|
for contact in adminContacts
|
||||||
|
|
|
@ -24,9 +24,14 @@ block modal-body-content
|
||||||
div.alert.alert-info
|
div.alert.alert-info
|
||||||
strong Shift-drag
|
strong Shift-drag
|
||||||
| to select
|
| to select
|
||||||
div.alert.alert-info
|
if flexibleRegion
|
||||||
strong Enter
|
div.alert.alert-info
|
||||||
| to confirm
|
strong Alt-shift-drag
|
||||||
|
| to select ratio
|
||||||
|
else
|
||||||
|
div.alert.alert-info
|
||||||
|
strong Enter
|
||||||
|
| to confirm
|
||||||
canvas(width=924, height=589)
|
canvas(width=924, height=589)
|
||||||
|
|
||||||
block modal-footer-content
|
block modal-footer-content
|
||||||
|
|
28
app/templates/front-view.jade
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
extends /templates/base
|
||||||
|
|
||||||
|
block content
|
||||||
|
|
||||||
|
.page-header
|
||||||
|
h1#site-slogan
|
||||||
|
span(data-i18n="home.slogan") Learn to Code by Playing a Game
|
||||||
|
small.spl.spr -
|
||||||
|
small free!
|
||||||
|
|
||||||
|
.row.platform-choices
|
||||||
|
.col-xs-6.platform-ios
|
||||||
|
a(href="#")
|
||||||
|
.panel.panel-default
|
||||||
|
.panel-body
|
||||||
|
h1 Play on iPad
|
||||||
|
img.img-responsive(src="/images/pages/front/play_web.jpg")
|
||||||
|
p.lead Get the app!
|
||||||
|
|
||||||
|
.col-xs-6.platform-web
|
||||||
|
a(href="/play-hero")
|
||||||
|
.panel.panel-default
|
||||||
|
.panel-body
|
||||||
|
h1 Play on web
|
||||||
|
img.img-responsive(src="/images/pages/front/play_web.jpg")
|
||||||
|
p.lead Play right now!
|
||||||
|
|
||||||
|
.clearfix
|
26
app/templates/front.jade
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
extends /templates/base
|
||||||
|
|
||||||
|
block content
|
||||||
|
|
||||||
|
.page-header
|
||||||
|
h1#site-slogan
|
||||||
|
span(data-i18n="home.slogan") Learn to Code by Playing a Game
|
||||||
|
small.spl.spr -
|
||||||
|
small free!
|
||||||
|
|
||||||
|
.row.platform-choices
|
||||||
|
.col-xs-6.platform-ios
|
||||||
|
a(href="#")
|
||||||
|
.panel.panel-default
|
||||||
|
.panel-body
|
||||||
|
h1 Play on iPad
|
||||||
|
em - get the app!
|
||||||
|
|
||||||
|
.col-xs-6.platform-web
|
||||||
|
a(href="/play")
|
||||||
|
.panel.panel-default
|
||||||
|
.panel-body
|
||||||
|
h1 Play on web
|
||||||
|
em - play right now!
|
||||||
|
|
||||||
|
.clearfix
|
|
@ -6,14 +6,20 @@
|
||||||
if closeButton
|
if closeButton
|
||||||
.button.close(type="button", data-dismiss="modal", aria-hidden="true") ×
|
.button.close(type="button", data-dismiss="modal", aria-hidden="true") ×
|
||||||
block modal-header-content
|
block modal-header-content
|
||||||
h3 man bites God
|
if headerContent
|
||||||
|
h3!= headerContent
|
||||||
|
else
|
||||||
|
h3 man bites God
|
||||||
|
|
||||||
block modal-body
|
block modal-body
|
||||||
.modal-body
|
.modal-body
|
||||||
block modal-body-content
|
block modal-body-content
|
||||||
p Man Bites God are the bad boys of the Melbourne live music and comedy scene. It is like being drowned in a bathtub of harmony.
|
if bodyContent
|
||||||
img(src="http://www.manbitesgod.com/images/picturecoupleb.jpg")
|
div!= bodyContent
|
||||||
img(src="http://www.manbitesgod.com/images/manrantb.jpg")
|
else
|
||||||
|
p Man Bites God are the bad boys of the Melbourne live music and comedy scene. It is like being drowned in a bathtub of harmony.
|
||||||
|
img(src="http://www.manbitesgod.com/images/picturecoupleb.jpg")
|
||||||
|
img(src="http://www.manbitesgod.com/images/manrantb.jpg")
|
||||||
|
|
||||||
.modal-body.wait.secret
|
.modal-body.wait.secret
|
||||||
block modal-body-wait-content
|
block modal-body-wait-content
|
||||||
|
|
|
@ -55,6 +55,18 @@ block content
|
||||||
|
|
|
|
||||||
a(href="http://blog.codecombat.com/6-programming-languages-one-victor-codecombats-newest-tournament", data-i18n="ladder.tournament_blurb_blog") on our blog
|
a(href="http://blog.codecombat.com/6-programming-languages-one-victor-codecombats-newest-tournament", data-i18n="ladder.tournament_blurb_blog") on our blog
|
||||||
| .
|
| .
|
||||||
|
p
|
||||||
|
strong Tournament ended!
|
||||||
|
a(href="#winners") Behold the winners
|
||||||
|
| . Thanks for playing! You can
|
||||||
|
strong still play
|
||||||
|
| Criss-Cross and all of our other
|
||||||
|
a(href="/play/ladder") multiplayer arenas
|
||||||
|
| .
|
||||||
|
p
|
||||||
|
| Want to commiserate? Head over to
|
||||||
|
a(href="http://discourse.codecombat.com/") the forum
|
||||||
|
| and discuss your strategies, your triumphs, and your turmoils.
|
||||||
|
|
||||||
div#columns.row
|
div#columns.row
|
||||||
div.column.col-md-2
|
div.column.col-md-2
|
||||||
|
@ -86,7 +98,7 @@ block content
|
||||||
if level.get('name') == 'Greed'
|
if level.get('name') == 'Greed'
|
||||||
li
|
li
|
||||||
a(href="#rules", data-toggle="tab", data-i18n="ladder.rules") Rules
|
a(href="#rules", data-toggle="tab", data-i18n="ladder.rules") Rules
|
||||||
if level.get('name') == 'Greed' || (level.get('name') == 'Criss-Cross!!!')
|
if level.get('name') == 'Greed' || (level.get('name') == 'Criss-Cross')
|
||||||
li
|
li
|
||||||
a(href="#winners", data-toggle="tab", data-i18n="ladder.winners") Winners
|
a(href="#winners", data-toggle="tab", data-i18n="ladder.winners") Winners
|
||||||
|
|
||||||
|
@ -725,7 +737,7 @@ block content
|
||||||
a(href="http://discourse.codecombat.com/") Discourse forum
|
a(href="http://discourse.codecombat.com/") Discourse forum
|
||||||
| .
|
| .
|
||||||
|
|
||||||
if level.get('name') == 'Greed' || level.get('name') == 'Criss-Cross!!!'
|
if level.get('name') == 'Greed' || level.get('name') == 'Criss-Cross'
|
||||||
.tab-pane.well#winners
|
.tab-pane.well#winners
|
||||||
h1(data-i18n="ladder.winners") Winners
|
h1(data-i18n="ladder.winners") Winners
|
||||||
|
|
||||||
|
@ -734,9 +746,15 @@ block content
|
||||||
tr
|
tr
|
||||||
th(data-i18n="ladder_prizes.rank") Rank
|
th(data-i18n="ladder_prizes.rank") Rank
|
||||||
th Human
|
th Human
|
||||||
th Human wins/losses/ties
|
if level.get('name') == 'Greed'
|
||||||
|
th Human wins/losses/ties
|
||||||
|
else
|
||||||
|
th Human score
|
||||||
th Ogre
|
th Ogre
|
||||||
th Ogre wins/losses/ties
|
if level.get('name') == 'Greed'
|
||||||
|
th Ogre wins/losses/ties
|
||||||
|
else
|
||||||
|
th Ogre score
|
||||||
th Spectate
|
th Spectate
|
||||||
tbody
|
tbody
|
||||||
each human, index in winners.humans
|
each human, index in winners.humans
|
||||||
|
@ -744,20 +762,28 @@ block content
|
||||||
tr
|
tr
|
||||||
td= human.rank
|
td= human.rank
|
||||||
td= human.name
|
td= human.name
|
||||||
td
|
if level.get('name') == 'Greed'
|
||||||
span.win= human.wins
|
td
|
||||||
| -
|
span.win= human.wins
|
||||||
span.loss= human.losses
|
| -
|
||||||
| -
|
span.loss= human.losses
|
||||||
span.tie= 377 - human.wins - human.losses
|
| -
|
||||||
|
span.tie= 377 - human.wins - human.losses
|
||||||
|
else
|
||||||
|
td
|
||||||
|
span= Math.round(100 * human.score)
|
||||||
if ogre
|
if ogre
|
||||||
td= ogre.name
|
td= ogre.name
|
||||||
td
|
if level.get('name') == 'Greed'
|
||||||
span.win= ogre.wins
|
td
|
||||||
| -
|
span.win= ogre.wins
|
||||||
span.loss= ogre.losses
|
| -
|
||||||
| -
|
span.loss= ogre.losses
|
||||||
span.tie= 407 - ogre.wins - ogre.losses
|
| -
|
||||||
|
span.tie= 407 - ogre.wins - ogre.losses
|
||||||
|
else
|
||||||
|
td
|
||||||
|
span= Math.round(100 * ogre.score)
|
||||||
td
|
td
|
||||||
a(href="/play/spectate/" + level.get('slug') + "?session-one=" + human.sessionID + "&session-two=" + ogre.sessionID) Watch the battle
|
a(href="/play/spectate/" + level.get('slug') + "?session-one=" + human.sessionID + "&session-two=" + ogre.sessionID) Watch the battle
|
||||||
else
|
else
|
||||||
|
|
|
@ -37,7 +37,6 @@ block modal-body-content
|
||||||
//span.code-language(style="background-image: url(/images/common/code_languages/javascript_small.png)")
|
//span.code-language(style="background-image: url(/images/common/code_languages/javascript_small.png)")
|
||||||
div.difficulty
|
div.difficulty
|
||||||
span(data-i18n="ladder.warmup") Warmup
|
span(data-i18n="ladder.warmup") Warmup
|
||||||
div(data-i18n="ladder.vs").vs VS
|
|
||||||
|
|
||||||
if challengers.easy
|
if challengers.easy
|
||||||
a(href="/play/level/#{levelID}?team=#{teamID}&opponent=#{challengers.easy.sessionID}")
|
a(href="/play/level/#{levelID}?team=#{teamID}&opponent=#{challengers.easy.sessionID}")
|
||||||
|
@ -54,7 +53,6 @@ block modal-body-content
|
||||||
span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.easy.codeLanguage + "_small.png)")
|
span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.easy.codeLanguage + "_small.png)")
|
||||||
div.difficulty
|
div.difficulty
|
||||||
span(data-i18n="general.easy") Easy
|
span(data-i18n="general.easy") Easy
|
||||||
div(data-i18n="ladder.vs").vs VS
|
|
||||||
|
|
||||||
if challengers.medium
|
if challengers.medium
|
||||||
a(href="/play/level/#{levelID}?team=#{teamID}&opponent=#{challengers.medium.sessionID}")
|
a(href="/play/level/#{levelID}?team=#{teamID}&opponent=#{challengers.medium.sessionID}")
|
||||||
|
@ -71,7 +69,6 @@ block modal-body-content
|
||||||
span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.medium.codeLanguage + "_small.png)")
|
span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.medium.codeLanguage + "_small.png)")
|
||||||
div.difficulty
|
div.difficulty
|
||||||
span(data-i18n="general.medium") Medium
|
span(data-i18n="general.medium") Medium
|
||||||
div(data-i18n="ladder.vs").vs VS
|
|
||||||
|
|
||||||
if challengers.hard
|
if challengers.hard
|
||||||
a(href="/play/level/#{levelID}?team=#{teamID}&opponent=#{challengers.hard.sessionID}")
|
a(href="/play/level/#{levelID}?team=#{teamID}&opponent=#{challengers.hard.sessionID}")
|
||||||
|
@ -88,6 +85,5 @@ block modal-body-content
|
||||||
span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.hard.codeLanguage + "_small.png)")
|
span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.hard.codeLanguage + "_small.png)")
|
||||||
div.difficulty
|
div.difficulty
|
||||||
span(data-i18n="general.hard") Hard
|
span(data-i18n="general.hard") Hard
|
||||||
div(data-i18n="ladder.vs").vs VS
|
|
||||||
|
|
||||||
block modal-footer
|
block modal-footer
|
7
app/templates/play/modal/play-account-modal.jade
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
extends /templates/modal/modal_base
|
||||||
|
|
||||||
|
block modal-header-content
|
||||||
|
h3(data-i18n="play.account") Account
|
||||||
|
|
||||||
|
block modal-body-content
|
||||||
|
p TODO: show all dem account
|
7
app/templates/play/modal/play-achievements-modal.jade
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
extends /templates/modal/modal_base
|
||||||
|
|
||||||
|
block modal-header-content
|
||||||
|
h3(data-i18n="play.achievements") Achievements
|
||||||
|
|
||||||
|
block modal-body-content
|
||||||
|
p TODO: show all dem achievements
|
7
app/templates/play/modal/play-heroes-modal.jade
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
extends /templates/modal/modal_base
|
||||||
|
|
||||||
|
block modal-header-content
|
||||||
|
h3(data-i18n="play.heroes") Heroes
|
||||||
|
|
||||||
|
block modal-body-content
|
||||||
|
p TODO: show all dem heroes
|
17
app/templates/play/modal/play-items-modal.jade
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
extends /templates/modal/modal_base
|
||||||
|
|
||||||
|
block modal-header-content
|
||||||
|
h3(data-i18n="play.items") Items
|
||||||
|
|
||||||
|
block modal-body-content
|
||||||
|
ul.nav.nav-tabs
|
||||||
|
for slotGroup, index in slotGroupsArray
|
||||||
|
li(class=index ? "" : "active")
|
||||||
|
a(href="#slot-group-" + slotGroup, data-toggle="tab")
|
||||||
|
span= slotGroupsNames[index]
|
||||||
|
.tab-content
|
||||||
|
for slotGroup, index in slotGroupsArray
|
||||||
|
.tab-pane(id="slot-group-" + slotGroup, class=index ? "" : "active")
|
||||||
|
h3 buy some #{slotGroupsNames[index]} yo:
|
||||||
|
for item in slotGroups[slotGroup]
|
||||||
|
.replace-me(data-item-id=item.id)
|
7
app/templates/play/modal/play-settings-modal.jade
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
extends /templates/modal/modal_base
|
||||||
|
|
||||||
|
block modal-header-content
|
||||||
|
h3(data-i18n="play.settings") Settings
|
||||||
|
|
||||||
|
block modal-body-content
|
||||||
|
p TODO: show all dem settings
|
34
app/templates/play/world-map-view.jade
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
.map
|
||||||
|
img.map-background(src="/images/pages/play/map_forest.jpg", alt="")
|
||||||
|
|
||||||
|
each campaign in campaigns
|
||||||
|
each level in campaign.levels
|
||||||
|
div(style="left: #{level.x}%; bottom: #{level.y}%; background-color: #{campaign.color}", class="level" + (level.first ? " first" : "") + (level.disabled ? " disabled" : ""), data-level-id=level.id)
|
||||||
|
a(href=level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.id}", disabled=level.disabled, class=levelStatusMap[level.id] || "")
|
||||||
|
div(style="left: #{level.x}%; bottom: #{level.y}%", class="level-shadow" + (level.first ? " first" : ""))
|
||||||
|
.level-info-container(data-level-id=level.id)
|
||||||
|
if level.image
|
||||||
|
img.level-image(src="#{level.image}", alt="#{level.name}")
|
||||||
|
else
|
||||||
|
img.level-image(src="/images/generic-icon.png", alt="#{level.name}")
|
||||||
|
div(class="level-info " + (levelStatusMap[level.id] || ""))
|
||||||
|
h3= level.name + (level.disabled ? " (Coming soon!)" : "")
|
||||||
|
.level-description= level.description
|
||||||
|
span(data-i18n="play.level_difficulty") Difficulty:
|
||||||
|
each i in Array(level.difficulty)
|
||||||
|
i.icon-star
|
||||||
|
- var playCount = levelPlayCountMap[level.id]
|
||||||
|
if playCount
|
||||||
|
div
|
||||||
|
span.spr #{playCount.sessions}
|
||||||
|
span(data-i18n="play.players") players
|
||||||
|
span.spr , #{Math.round(playCount.playtime / 3600)}
|
||||||
|
span(data-i18n="play.hours_played") hours played
|
||||||
|
.campaign-label(style="color: #{campaign.color}")= campaign.name
|
||||||
|
|
||||||
|
.game-controls
|
||||||
|
button.btn.items(data-toggle='coco-modal', data-target='play/modal/PlayItemsModal', data-i18n="[title]play.items")
|
||||||
|
button.btn.heroes(data-toggle='coco-modal', data-target='play/modal/PlayHeroesModal', data-i18n="[title]play.heroes")
|
||||||
|
button.btn.achievements(data-toggle='coco-modal', data-target='play/modal/PlayAchievementsModal', data-i18n="[title]play.achievements")
|
||||||
|
button.btn.account(data-toggle='coco-modal', data-target='play/modal/PlayAccountModal', data-i18n="[title]play.account")
|
||||||
|
button.btn.settings(data-toggle='coco-modal', data-target='play/modal/PlaySettingsModal', data-i18n="[title]play.settings")
|
34
app/views/FrontView.coffee
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
RootView = require 'views/kinds/RootView'
|
||||||
|
template = require 'templates/front-view'
|
||||||
|
{me} = require '/lib/auth'
|
||||||
|
ModalView = require 'views/kinds/ModalView'
|
||||||
|
|
||||||
|
module.exports = class FrontView extends RootView
|
||||||
|
id: 'front-view'
|
||||||
|
template: template
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click .platform-ios a': 'onIOSClicked'
|
||||||
|
|
||||||
|
getRenderData: ->
|
||||||
|
c = super()
|
||||||
|
if $.browser
|
||||||
|
majorVersion = $.browser.versionNumber
|
||||||
|
c.isOldBrowser = true if $.browser.mozilla && majorVersion < 21
|
||||||
|
c.isOldBrowser = true if $.browser.chrome && majorVersion < 17
|
||||||
|
c.isOldBrowser = true if $.browser.safari && majorVersion < 6
|
||||||
|
else
|
||||||
|
console.warn 'no more jquery browser version...'
|
||||||
|
c
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
||||||
|
|
||||||
|
onIOSClicked: (e) ->
|
||||||
|
header = 'Sorry, the iPad app isn\'t ready yet'
|
||||||
|
body = '''
|
||||||
|
<p class="lead">We are working on it!</p>
|
||||||
|
<p>For now, try playing on the web, and totally sign up (with emails enabled) so you can be the first to hear when it is ready.</p>
|
||||||
|
'''
|
||||||
|
notImplementedModal = new ModalView headerContent: header, bodyContent: body
|
||||||
|
@openModalView notImplementedModal
|
|
@ -26,7 +26,7 @@ module.exports = class NewLevelComponentModal extends ModalView
|
||||||
component = new LevelComponent()
|
component = new LevelComponent()
|
||||||
component.set 'system', system
|
component.set 'system', system
|
||||||
component.set 'name', name
|
component.set 'name', name
|
||||||
component.set 'code', component.get('code').replace(/AttacksSelf/g, name)
|
component.set 'code', component.get('code', true).replace(/AttacksSelf/g, name)
|
||||||
component.set 'permissions', [{access: 'owner', target: me.id}] # Private until saved in a published Level
|
component.set 'permissions', [{access: 'owner', target: me.id}] # Private until saved in a published Level
|
||||||
res = component.save()
|
res = component.save()
|
||||||
return unless res
|
return unless res
|
||||||
|
|
|
@ -31,11 +31,11 @@ module.exports = class WorldSelectModal extends ModalView
|
||||||
getRenderData: (c={}) =>
|
getRenderData: (c={}) =>
|
||||||
c = super(c)
|
c = super(c)
|
||||||
c.selectingPoint = @dataType is 'point'
|
c.selectingPoint = @dataType is 'point'
|
||||||
|
c.flexibleRegion = @dataType is 'region'
|
||||||
c
|
c
|
||||||
|
|
||||||
afterInsert: ->
|
afterInsert: ->
|
||||||
super()
|
super()
|
||||||
window.e = @$el
|
|
||||||
@initSurface()
|
@initSurface()
|
||||||
|
|
||||||
# surface setup
|
# surface setup
|
||||||
|
@ -54,7 +54,6 @@ module.exports = class WorldSelectModal extends ModalView
|
||||||
thangTypes: @supermodel.getModels(ThangType)
|
thangTypes: @supermodel.getModels(ThangType)
|
||||||
showInvisible: true
|
showInvisible: true
|
||||||
}
|
}
|
||||||
window.s = @surface
|
|
||||||
@surface.playing = false
|
@surface.playing = false
|
||||||
@surface.setWorld @world
|
@surface.setWorld @world
|
||||||
@surface.camera.zoomTo({x: 262, y: -164}, 1.66, 0)
|
@surface.camera.zoomTo({x: 262, y: -164}, 1.66, 0)
|
||||||
|
|
|
@ -19,6 +19,8 @@ module.exports = class LevelThangEditView extends CocoView
|
||||||
'click #thang-type-link span': 'toggleTypeEdit'
|
'click #thang-type-link span': 'toggleTypeEdit'
|
||||||
'blur #thang-name-link input': 'toggleNameEdit'
|
'blur #thang-name-link input': 'toggleNameEdit'
|
||||||
'blur #thang-type-link input': 'toggleTypeEdit'
|
'blur #thang-type-link input': 'toggleTypeEdit'
|
||||||
|
'keydown #thang-name-link input': 'toggleNameEditIfReturn'
|
||||||
|
'keydown #thang-type-link input': 'toggleTypeEditIfReturn'
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
options ?= {}
|
options ?= {}
|
||||||
|
@ -27,6 +29,7 @@ module.exports = class LevelThangEditView extends CocoView
|
||||||
@thangData = $.extend true, {}, options.thangData ? {}
|
@thangData = $.extend true, {}, options.thangData ? {}
|
||||||
@level = options.level
|
@level = options.level
|
||||||
@oldPath = options.oldPath
|
@oldPath = options.oldPath
|
||||||
|
@reportChanges = _.debounce @reportChanges, 1000
|
||||||
|
|
||||||
getRenderData: (context={}) ->
|
getRenderData: (context={}) ->
|
||||||
context = super(context)
|
context = super(context)
|
||||||
|
@ -83,5 +86,16 @@ module.exports = class LevelThangEditView extends CocoView
|
||||||
if thangType and wasEditing
|
if thangType and wasEditing
|
||||||
@thangData.thangType = thangType.get('original')
|
@thangData.thangType = thangType.get('original')
|
||||||
|
|
||||||
|
toggleNameEditIfReturn: (e) ->
|
||||||
|
@$el.find('#thang-name-link input').blur() if e.which is 13
|
||||||
|
|
||||||
|
toggleTypeEditIfReturn: (e) ->
|
||||||
|
@$el.find('#thang-type-link input').blur() if e.which is 13
|
||||||
|
|
||||||
onComponentsChanged: (components) =>
|
onComponentsChanged: (components) =>
|
||||||
@thangData.components = components
|
@thangData.components = components
|
||||||
|
@reportChanges()
|
||||||
|
|
||||||
|
reportChanges: =>
|
||||||
|
return if @destroyed
|
||||||
|
Backbone.Mediator.publish 'editor:level-thang-edited', {thangData: $.extend(true, {}, @thangData), oldPath: @oldPath}
|
||||||
|
|
|
@ -16,7 +16,7 @@ MOVE_MARGIN = 0.15
|
||||||
MOVE_SPEED = 13
|
MOVE_SPEED = 13
|
||||||
|
|
||||||
# Let us place these on top of other Thangs
|
# Let us place these on top of other Thangs
|
||||||
overlappableThangTypeNames = ['Torch', 'Chains', 'Bird', 'Cloud 1', 'Cloud 2', 'Cloud 3', 'Waterfall', 'Obstacle']
|
overlappableThangTypeNames = ['Torch', 'Chains', 'Bird', 'Cloud 1', 'Cloud 2', 'Cloud 3', 'Waterfall', 'Obstacle', 'Electrowall']
|
||||||
|
|
||||||
class ThangTypeSearchCollection extends CocoCollection
|
class ThangTypeSearchCollection extends CocoCollection
|
||||||
url: '/db/thang.type?project=original,name,version,slug,kind,components'
|
url: '/db/thang.type?project=original,name,version,slug,kind,components'
|
||||||
|
@ -33,12 +33,14 @@ module.exports = class ThangsTabView extends CocoView
|
||||||
'surface:mouse-over': 'onSurfaceMouseOver'
|
'surface:mouse-over': 'onSurfaceMouseOver'
|
||||||
'surface:mouse-out': 'onSurfaceMouseOut'
|
'surface:mouse-out': 'onSurfaceMouseOut'
|
||||||
'editor:edit-level-thang': 'editThang'
|
'editor:edit-level-thang': 'editThang'
|
||||||
|
'editor:level-thang-edited': 'onLevelThangEdited'
|
||||||
'editor:level-thang-done-editing': 'onLevelThangDoneEditing'
|
'editor:level-thang-done-editing': 'onLevelThangDoneEditing'
|
||||||
'editor:view-switched': 'onViewSwitched'
|
'editor:view-switched': 'onViewSwitched'
|
||||||
'sprite:dragged': 'onSpriteDragged'
|
'sprite:dragged': 'onSpriteDragged'
|
||||||
'sprite:mouse-up': 'onSpriteMouseUp'
|
'sprite:mouse-up': 'onSpriteMouseUp'
|
||||||
'sprite:mouse-down': 'onSpriteMouseDown'
|
'sprite:mouse-down': 'onSpriteMouseDown'
|
||||||
'sprite:double-clicked': 'onSpriteDoubleClicked'
|
'sprite:double-clicked': 'onSpriteDoubleClicked'
|
||||||
|
'surface:stage-mouse-down': 'onStageMouseDown'
|
||||||
'surface:stage-mouse-up': 'onStageMouseUp'
|
'surface:stage-mouse-up': 'onStageMouseUp'
|
||||||
'editor:random-terrain-generated': 'onRandomTerrainGenerated'
|
'editor:random-terrain-generated': 'onRandomTerrainGenerated'
|
||||||
|
|
||||||
|
@ -225,8 +227,17 @@ module.exports = class ThangsTabView extends CocoView
|
||||||
# if e.originalEvent.nativeEvent.button == 2
|
# if e.originalEvent.nativeEvent.button == 2
|
||||||
# @onSpriteContextMenu e
|
# @onSpriteContextMenu e
|
||||||
|
|
||||||
|
onStageMouseDown: (e) ->
|
||||||
|
return unless @addThangSprite?.thangType.get('kind') is 'Wall'
|
||||||
|
@surface.camera.dragDisabled = true
|
||||||
|
@paintingWalls = true
|
||||||
|
|
||||||
onStageMouseUp: (e) ->
|
onStageMouseUp: (e) ->
|
||||||
if @addThangSprite
|
if @paintingWalls
|
||||||
|
# We need to stop painting walls, but we may also stop in onExtantThangSelected.
|
||||||
|
_.defer =>
|
||||||
|
@paintingWalls = @paintedWalls = @surface.camera.dragDisabled = false
|
||||||
|
else if @addThangSprite
|
||||||
@surface.camera.lock()
|
@surface.camera.lock()
|
||||||
# If we click on the background, we need to add @addThangSprite, but not if onSpriteMouseUp will fire.
|
# If we click on the background, we need to add @addThangSprite, but not if onSpriteMouseUp will fire.
|
||||||
@backgroundAddClickTimeout = _.defer => @onExtantThangSelected {}
|
@backgroundAddClickTimeout = _.defer => @onExtantThangSelected {}
|
||||||
|
@ -295,7 +306,12 @@ module.exports = class ThangsTabView extends CocoView
|
||||||
@selectedExtantSprite?.setNameLabel? null unless @selectedExtantSprite is e.sprite
|
@selectedExtantSprite?.setNameLabel? null unless @selectedExtantSprite is e.sprite
|
||||||
@selectedExtantThang = e.thang
|
@selectedExtantThang = e.thang
|
||||||
@selectedExtantSprite = e.sprite
|
@selectedExtantSprite = e.sprite
|
||||||
if e.thang and (key.alt or key.meta)
|
paintedAWall = @paintedWalls
|
||||||
|
@paintingWalls = @paintedWalls = @surface.camera.dragDisabled = false
|
||||||
|
if paintedAWall
|
||||||
|
# Skip adding a wall now, because we already dragged to add one
|
||||||
|
null
|
||||||
|
else if e.thang and (key.alt or key.meta)
|
||||||
# We alt-clicked, so create a clone addThang
|
# We alt-clicked, so create a clone addThang
|
||||||
@selectAddThangType e.thang.spriteName, @selectedExtantThang
|
@selectAddThangType e.thang.spriteName, @selectedExtantThang
|
||||||
else if @justAdded()
|
else if @justAdded()
|
||||||
|
@ -389,6 +405,16 @@ module.exports = class ThangsTabView extends CocoView
|
||||||
wop = @surface.camera.screenToWorld x: e.x, y: e.y
|
wop = @surface.camera.screenToWorld x: e.x, y: e.y
|
||||||
wop.z = 0.5
|
wop.z = 0.5
|
||||||
@adjustThangPos @addThangSprite, @addThangSprite.thang, wop
|
@adjustThangPos @addThangSprite, @addThangSprite.thang, wop
|
||||||
|
if @paintingWalls
|
||||||
|
unless _.find @surface.spriteBoss.spriteArray, ((sprite) =>
|
||||||
|
sprite.thangType.get('kind') is 'Wall' and
|
||||||
|
Math.abs(sprite.thang.pos.x - @addThangSprite.thang.pos.x) < 2 and
|
||||||
|
Math.abs(sprite.thang.pos.y - @addThangSprite.thang.pos.y) < 2 and
|
||||||
|
sprite isnt @addThangSprite
|
||||||
|
)
|
||||||
|
@addThang @addThangType, @addThangSprite.thang.pos
|
||||||
|
@lastAddTime = new Date()
|
||||||
|
@paintedWalls = true
|
||||||
null
|
null
|
||||||
|
|
||||||
onSurfaceMouseOver: (e) ->
|
onSurfaceMouseOver: (e) ->
|
||||||
|
@ -427,6 +453,7 @@ module.exports = class ThangsTabView extends CocoView
|
||||||
|
|
||||||
deleteSelectedExtantThang: (e) =>
|
deleteSelectedExtantThang: (e) =>
|
||||||
return if $(e.target).hasClass 'treema-node'
|
return if $(e.target).hasClass 'treema-node'
|
||||||
|
return unless @selectedExtantThang
|
||||||
thang = @getThangByID(@selectedExtantThang.id)
|
thang = @getThangByID(@selectedExtantThang.id)
|
||||||
@thangsTreema.delete(@pathForThang(thang))
|
@thangsTreema.delete(@pathForThang(thang))
|
||||||
Thang.resetThangIDs() # TODO: find some way to do this when we delete from treema, too
|
Thang.resetThangIDs() # TODO: find some way to do this when we delete from treema, too
|
||||||
|
@ -547,14 +574,19 @@ module.exports = class ThangsTabView extends CocoView
|
||||||
onLevelThangDoneEditing: (e) ->
|
onLevelThangDoneEditing: (e) ->
|
||||||
@removeSubView @editThangView
|
@removeSubView @editThangView
|
||||||
@editThangView = null
|
@editThangView = null
|
||||||
newThang = e.thangData
|
@updateEditedThang e.thangData, e.oldPath
|
||||||
|
@$el.find('>').show()
|
||||||
|
|
||||||
|
onLevelThangEdited: (e) ->
|
||||||
|
@updateEditedThang e.thangData, e.oldPath
|
||||||
|
|
||||||
|
updateEditedThang: (newThang, oldPath) ->
|
||||||
@hush = true
|
@hush = true
|
||||||
@thangsTreema.delete e.oldPath
|
@thangsTreema.delete oldPath
|
||||||
@populateFoldersForThang(newThang)
|
@populateFoldersForThang(newThang)
|
||||||
@thangsTreema.set(@pathForThang(newThang), newThang)
|
@thangsTreema.set(@pathForThang(newThang), newThang)
|
||||||
@hush = false
|
@hush = false
|
||||||
@onThangsChanged()
|
@onThangsChanged()
|
||||||
@$el.find('>').show()
|
|
||||||
|
|
||||||
preventDefaultContextMenu: (e) ->
|
preventDefaultContextMenu: (e) ->
|
||||||
return unless $(e.target).closest('#canvas-wrapper').length
|
return unless $(e.target).closest('#canvas-wrapper').length
|
||||||
|
|
|
@ -41,6 +41,7 @@ module.exports = class GameMenuModal extends ModalView
|
||||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-tab-switch', volume: 1
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-tab-switch', volume: 1
|
||||||
|
|
||||||
onHidden: ->
|
onHidden: ->
|
||||||
|
super()
|
||||||
subview.onHidden?() for subviewKey, subview of @subviews
|
subview.onHidden?() for subviewKey, subview of @subviews
|
||||||
me.patch()
|
me.patch()
|
||||||
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
||||||
|
|
|
@ -176,7 +176,7 @@ module.exports = class CocoView extends Backbone.View
|
||||||
target = elem.data('target')
|
target = elem.data('target')
|
||||||
Modal = require 'views/'+target
|
Modal = require 'views/'+target
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@openModalView new Modal
|
@openModalView new Modal supermodel: @supermodal
|
||||||
|
|
||||||
openModalView: (modalView, softly=false) ->
|
openModalView: (modalView, softly=false) ->
|
||||||
return if waitingModal # can only have one waiting at once
|
return if waitingModal # can only have one waiting at once
|
||||||
|
|
|
@ -7,6 +7,7 @@ module.exports = class ModalView extends CocoView
|
||||||
modalWidthPercent: null
|
modalWidthPercent: null
|
||||||
plain: false
|
plain: false
|
||||||
instant: false
|
instant: false
|
||||||
|
template: require 'templates/modal/modal_base'
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click a': 'toggleModal'
|
'click a': 'toggleModal'
|
||||||
|
@ -26,6 +27,8 @@ module.exports = class ModalView extends CocoView
|
||||||
getRenderData: (context={}) ->
|
getRenderData: (context={}) ->
|
||||||
context = super(context)
|
context = super(context)
|
||||||
context.closeButton = @closeButton
|
context.closeButton = @closeButton
|
||||||
|
context.headerContent = @options.headerContent
|
||||||
|
context.bodyContent = @options.bodyContent
|
||||||
context
|
context
|
||||||
|
|
||||||
subscriptions:
|
subscriptions:
|
||||||
|
|
472
app/views/play/WorldMapView.coffee
Normal file
|
@ -0,0 +1,472 @@
|
||||||
|
RootView = require 'views/kinds/RootView'
|
||||||
|
template = require 'templates/play/world-map-view'
|
||||||
|
LevelSession = require 'models/LevelSession'
|
||||||
|
CocoCollection = require 'collections/CocoCollection'
|
||||||
|
AudioPlayer = require 'lib/AudioPlayer'
|
||||||
|
|
||||||
|
class LevelSessionsCollection extends CocoCollection
|
||||||
|
url: ''
|
||||||
|
model: LevelSession
|
||||||
|
|
||||||
|
constructor: (model) ->
|
||||||
|
super()
|
||||||
|
@url = "/db/user/#{me.id}/level.sessions?project=state.complete,levelID"
|
||||||
|
|
||||||
|
module.exports = class MainPlayView extends RootView
|
||||||
|
id: 'world-map-view'
|
||||||
|
template: template
|
||||||
|
|
||||||
|
events:
|
||||||
|
'click .map': 'onClickMap'
|
||||||
|
'click .game-controls button': 'onClickGameControl'
|
||||||
|
'mouseenter .level a': 'onMouseEnterLevel'
|
||||||
|
'mouseleave .level a': 'onMouseLeaveLevel'
|
||||||
|
'mousemove .map': 'onMouseMoveMap'
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super options
|
||||||
|
@levelStatusMap = {}
|
||||||
|
@levelPlayCountMap = {}
|
||||||
|
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', null, 0).model
|
||||||
|
@listenToOnce @sessions, 'sync', @onSessionsLoaded
|
||||||
|
@getLevelPlayCounts()
|
||||||
|
$(window).on 'resize', @onWindowResize
|
||||||
|
|
||||||
|
getLevelPlayCounts: ->
|
||||||
|
success = (levelPlayCounts) =>
|
||||||
|
return if @destroyed
|
||||||
|
for level in levelPlayCounts
|
||||||
|
@levelPlayCountMap[level._id] = playtime: level.playtime, sessions: level.sessions
|
||||||
|
@render() if @supermodel.finished()
|
||||||
|
|
||||||
|
levelIDs = []
|
||||||
|
for campaign in campaigns
|
||||||
|
for level in campaign.levels
|
||||||
|
levelIDs.push level.id
|
||||||
|
levelPlayCountsRequest = @supermodel.addRequestResource 'play_counts', {
|
||||||
|
url: '/db/level/-/play_counts'
|
||||||
|
data: {ids: levelIDs}
|
||||||
|
method: 'POST'
|
||||||
|
success: success
|
||||||
|
}, 0
|
||||||
|
levelPlayCountsRequest.load()
|
||||||
|
|
||||||
|
getRenderData: (context={}) ->
|
||||||
|
context = super(context)
|
||||||
|
context.campaigns = campaigns
|
||||||
|
for campaign in context.campaigns
|
||||||
|
for level in campaign.levels
|
||||||
|
level.x ?= 10 + 80 * Math.random()
|
||||||
|
level.y ?= 10 + 80 * Math.random()
|
||||||
|
context.levelStatusMap = @levelStatusMap
|
||||||
|
context.levelPlayCountMap = @levelPlayCountMap
|
||||||
|
context
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
||||||
|
@onWindowResize()
|
||||||
|
_.defer => @$el.find('.game-controls button').tooltip() # Have to defer or i18n doesn't take effect.
|
||||||
|
|
||||||
|
onSessionsLoaded: (e) ->
|
||||||
|
for session in @sessions.models
|
||||||
|
@levelStatusMap[session.get('levelID')] = if session.get('state')?.complete then 'complete' else 'started'
|
||||||
|
@render()
|
||||||
|
|
||||||
|
onClickMap: (e) ->
|
||||||
|
# Easy-ish way of figuring out coordinates for placing level dots.
|
||||||
|
x = e.offsetX / @$el.find('.map-background').width()
|
||||||
|
y = (1 - e.offsetY / @$el.find('.map-background').height())
|
||||||
|
console.log " x: #{(100 * x).toFixed(2)}\n y: #{(100 * y).toFixed(2)}\n"
|
||||||
|
|
||||||
|
onClickGameControl: (e) ->
|
||||||
|
|
||||||
|
|
||||||
|
onMouseEnterLevel: (e) ->
|
||||||
|
levelID = $(e.target).parents('.level').data('level-id')
|
||||||
|
@$levelInfo = @$el.find(".level-info-container[data-level-id=#{levelID}]").show()
|
||||||
|
@adjustLevelInfoPosition e
|
||||||
|
|
||||||
|
onMouseLeaveLevel: (e) ->
|
||||||
|
levelID = $(e.target).parents('.level').data('level-id')
|
||||||
|
@$el.find(".level-info-container[data-level-id='#{levelID}']").hide()
|
||||||
|
|
||||||
|
onMouseMoveMap: (e) ->
|
||||||
|
@adjustLevelInfoPosition e
|
||||||
|
|
||||||
|
adjustLevelInfoPosition: (e) ->
|
||||||
|
return unless @$levelInfo
|
||||||
|
@$map ?= @$el.find('.map')
|
||||||
|
mapOffset = @$map.offset()
|
||||||
|
mapX = e.pageX - mapOffset.left
|
||||||
|
mapY = e.pageY - mapOffset.top
|
||||||
|
margin = 20
|
||||||
|
width = @$levelInfo.outerWidth()
|
||||||
|
@$levelInfo.css('left', Math.min(Math.max(margin, mapX - width / 2), @$map.width() - width - margin))
|
||||||
|
height = @$levelInfo.outerHeight()
|
||||||
|
top = mapY - @$levelInfo.outerHeight() - 60
|
||||||
|
if top < 20
|
||||||
|
top = mapY + 60
|
||||||
|
@$levelInfo.css('top', top)
|
||||||
|
|
||||||
|
onWindowResize: (e) =>
|
||||||
|
forestMapWidth = 2401
|
||||||
|
forestMapHeight = 1536
|
||||||
|
aspectRatio = forestMapWidth / forestMapHeight
|
||||||
|
pageWidth = $(window).width()
|
||||||
|
pageHeight = $(window).height()
|
||||||
|
widthRatio = pageWidth / forestMapWidth
|
||||||
|
heightRatio = pageHeight / forestMapHeight
|
||||||
|
if widthRatio > heightRatio
|
||||||
|
resultingWidth = pageWidth
|
||||||
|
resultingHeight = resultingWidth / aspectRatio
|
||||||
|
else
|
||||||
|
resultingHeight = pageHeight
|
||||||
|
resultingWidth = resultingHeight * aspectRatio
|
||||||
|
resultingMarginX = (pageWidth - resultingWidth) / 2
|
||||||
|
resultingMarginY = (pageHeight - resultingHeight) / 2
|
||||||
|
@$el.find('.map').css(width: resultingWidth, height: resultingHeight, 'margin-left': resultingMarginX, 'margin-top': resultingMarginY)
|
||||||
|
|
||||||
|
tutorials = [
|
||||||
|
{
|
||||||
|
name: 'Rescue Mission'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'rescue-mission'
|
||||||
|
image: '/file/db/level/52740644904ac0411700067c/rescue_mission_icon.png'
|
||||||
|
description: 'Tharin has been captured! Start here.'
|
||||||
|
first: true
|
||||||
|
x: 17.23
|
||||||
|
y: 36.94
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Grab the Mushroom'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'grab-the-mushroom'
|
||||||
|
image: '/file/db/level/529662dfe0df8f0000000007/grab_the_mushroom_icon.png'
|
||||||
|
description: 'Grab a powerup and smash a big ogre.'
|
||||||
|
x: 22.6
|
||||||
|
y: 35.1
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Drink Me'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'drink-me'
|
||||||
|
image: '/file/db/level/525dc5589a0765e496000006/drink_me_icon.png'
|
||||||
|
description: 'Drink up and slay two munchkins.'
|
||||||
|
x: 27.74
|
||||||
|
y: 35.17
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Taunt the Guards'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'taunt-the-guards'
|
||||||
|
image: '/file/db/level/5276c9bdcf83207a2801ff8f/taunt_icon.png'
|
||||||
|
description: 'Tharin, if clever, can escape with Phoebe.'
|
||||||
|
x: 32.7
|
||||||
|
y: 36.7
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'It\'s a Trap'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'its-a-trap'
|
||||||
|
image: '/file/db/level/528aea2d7f37fc4e0700016b/its_a_trap_icon.png'
|
||||||
|
description: 'Organize a dungeon ambush with archers.'
|
||||||
|
x: 37.6
|
||||||
|
y: 40.0
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Break the Prison'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'break-the-prison'
|
||||||
|
image: '/file/db/level/5275272c69abdcb12401216e/break_the_prison_icon.png'
|
||||||
|
description: 'More comrades are imprisoned!'
|
||||||
|
x: 44.1
|
||||||
|
y: 39.5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Taunt'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'taunt'
|
||||||
|
image: '/file/db/level/525f150306e1ab0962000018/taunt_icon.png'
|
||||||
|
description: 'Taunt the ogre to claim victory.'
|
||||||
|
x: 38.5
|
||||||
|
y: 44.1
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Cowardly Taunt'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'cowardly-taunt'
|
||||||
|
image: '/file/db/level/525abfd9b12777d78e000009/cowardly_taunt_icon.png'
|
||||||
|
description: 'Lure infuriated ogres to their doom.'
|
||||||
|
x: 39.2
|
||||||
|
y: 50.1
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Commanding Followers'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'commanding-followers'
|
||||||
|
image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
|
||||||
|
description: 'Lead allied soldiers into battle.'
|
||||||
|
x: 39.1
|
||||||
|
y: 54.7
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Mobile Artillery'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'mobile-artillery'
|
||||||
|
image: '/file/db/level/525085419851b83f4b000001/mobile_artillery_icon.png'
|
||||||
|
description: 'Blow ogres up!'
|
||||||
|
x: 39.5
|
||||||
|
y: 60.2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
experienced = [
|
||||||
|
{
|
||||||
|
name: 'Hunter Triplets'
|
||||||
|
difficulty: 2
|
||||||
|
id: 'hunter-triplets'
|
||||||
|
image: '/file/db/level/526711d9add4f8965f000002/hunter_triplets_icon.png'
|
||||||
|
description: 'Three soldiers go ogre hunting.'
|
||||||
|
x: 51.76
|
||||||
|
y: 35.5
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Emphasis on Aim'
|
||||||
|
difficulty: 2
|
||||||
|
id: 'emphasis-on-aim'
|
||||||
|
image: '/file/db/level/525f384d96cd77000000000f/munchkin_masher_icon.png'
|
||||||
|
description: 'Choose your targets carefully.'
|
||||||
|
x: 61.47
|
||||||
|
y: 33.46
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Zone of Danger'
|
||||||
|
difficulty: 3
|
||||||
|
id: 'zone-of-danger'
|
||||||
|
image: '/file/db/level/526ae95c1e5cd30000000008/zone_of_danger_icon.png'
|
||||||
|
description: 'Target the ogres swarming into arrow range.'
|
||||||
|
x: 65.72
|
||||||
|
y: 26.72
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Molotov Medic'
|
||||||
|
difficulty: 2
|
||||||
|
id: 'molotov-medic'
|
||||||
|
image: '/file/db/level/52602ecb026e8481e7000001/generic_1.png'
|
||||||
|
description: 'Tharin must play support in this dungeon battle.'
|
||||||
|
x: 70.95
|
||||||
|
y: 18.64
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Gridmancer'
|
||||||
|
difficulty: 5
|
||||||
|
id: 'gridmancer'
|
||||||
|
image: '/file/db/level/52ae2460ef42c52f13000008/gridmancer_icon.png'
|
||||||
|
description: 'Super algorithm challenge level!'
|
||||||
|
x: 61.41
|
||||||
|
y: 17.22
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
arenas = [
|
||||||
|
{
|
||||||
|
name: 'Criss-Cross'
|
||||||
|
difficulty: 5
|
||||||
|
id: 'criss-cross'
|
||||||
|
image: '/file/db/level/528aea2d7f37fc4e0700016b/its_a_trap_icon.png'
|
||||||
|
description: 'Participate in a bidding war with opponents to reach the other side!'
|
||||||
|
levelPath: 'ladder'
|
||||||
|
x: 49.43
|
||||||
|
y: 21.48
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Greed'
|
||||||
|
difficulty: 4
|
||||||
|
id: 'greed'
|
||||||
|
image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png'
|
||||||
|
description: 'Liked Dungeon Arena and Gold Rush? Put them together in this economic arena!'
|
||||||
|
levelPath: 'ladder'
|
||||||
|
x: 45.00
|
||||||
|
y: 23.34
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Dungeon Arena'
|
||||||
|
difficulty: 3
|
||||||
|
id: 'dungeon-arena'
|
||||||
|
image: '/file/db/level/526ae95c1e5cd30000000008/zone_of_danger_icon.png'
|
||||||
|
description: 'Play head-to-head against fellow Wizards in a dungeon melee!'
|
||||||
|
levelPath: 'ladder'
|
||||||
|
x: 36.82
|
||||||
|
y: 23.17
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Gold Rush'
|
||||||
|
difficulty: 3
|
||||||
|
id: 'gold-rush'
|
||||||
|
image: '/file/db/level/52602ecb026e8481e7000001/generic_1.png'
|
||||||
|
description: 'Prove you are better at collecting gold than your opponent!'
|
||||||
|
levelPath: 'ladder'
|
||||||
|
x: 30.8
|
||||||
|
y: 16.87
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Brawlwood'
|
||||||
|
difficulty: 4
|
||||||
|
id: 'brawlwood'
|
||||||
|
image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
|
||||||
|
description: 'Combat the armies of other Wizards in a strategic forest arena! (Fast computer required.)'
|
||||||
|
levelPath: 'ladder'
|
||||||
|
x: 41.93
|
||||||
|
y: 12.79
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Sky Span (Testing)'
|
||||||
|
difficulty: 3
|
||||||
|
id: 'sky-span'
|
||||||
|
image: '/file/db/level/526ae95c1e5cd30000000008/zone_of_danger_icon.png'
|
||||||
|
description: 'Preview version of an upgraded Dungeon Arena. Help us with hero balance before release!'
|
||||||
|
levelPath: 'ladder'
|
||||||
|
x: 53.12
|
||||||
|
y: 11.37
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
classicAlgorithms = [
|
||||||
|
{
|
||||||
|
name: 'Bubble Sort Bootcamp Battle'
|
||||||
|
difficulty: 3
|
||||||
|
id: 'bubble-sort-bootcamp-battle'
|
||||||
|
image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
|
||||||
|
description: 'Write a bubble sort to organize your soldiers. - by Alexandru Caciulescu'
|
||||||
|
x: 26.37
|
||||||
|
y: 93.02
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Ogres of Hanoi'
|
||||||
|
difficulty: 3
|
||||||
|
id: 'ogres-of-hanoi'
|
||||||
|
image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png'
|
||||||
|
description: 'Transfer a stack of ogres while preserving their honor. - by Alexandru Caciulescu'
|
||||||
|
x: 32.39
|
||||||
|
y: 92.67
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Danger! Minefield'
|
||||||
|
difficulty: 3
|
||||||
|
id: 'danger-minefield'
|
||||||
|
image: '/file/db/level/526bda3fe79aefde2a003e36/mobile_artillery_icon.png'
|
||||||
|
description: 'Learn how to find prime numbers while defusing mines! - by Alexandru Caciulescu'
|
||||||
|
x: 38.07
|
||||||
|
y: 92.76
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'K-means++ Cluster Wars'
|
||||||
|
difficulty: 4
|
||||||
|
id: 'k-means-cluster-wars'
|
||||||
|
image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
|
||||||
|
description: 'Learn cluster analysis while leading armies into battle! - by Alexandru Caciulescu'
|
||||||
|
x: 43.75
|
||||||
|
y: 90.36
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Quicksort the Spiral'
|
||||||
|
difficulty: 3
|
||||||
|
id: 'quicksort-the-spiral'
|
||||||
|
image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
|
||||||
|
description: 'Learn Quicksort while sorting a spiral of ogres! - by Alexandru Caciulescu'
|
||||||
|
x: 48.97
|
||||||
|
y: 87.08
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Minimax Tic-Tac-Toe'
|
||||||
|
difficulty: 4
|
||||||
|
id: 'minimax-tic-tac-toe'
|
||||||
|
image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
|
||||||
|
description: 'Learn how to make a game AI with the Minimax algorithm. - by Alexandru Caciulescu'
|
||||||
|
x: 55.96
|
||||||
|
y: 82.73
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
playerCreated = [
|
||||||
|
{
|
||||||
|
name: 'Extra Extrapolation'
|
||||||
|
difficulty: 2
|
||||||
|
id: 'extra-extrapolation'
|
||||||
|
image: '/file/db/level/526bda3fe79aefde2a003e36/mobile_artillery_icon.png'
|
||||||
|
description: 'Predict your target\'s position for deadly aim. - by Sootn'
|
||||||
|
x: 42.67
|
||||||
|
y: 67.98
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'The Right Route'
|
||||||
|
difficulty: 1
|
||||||
|
id: 'the-right-route'
|
||||||
|
image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png'
|
||||||
|
description: 'Strike at the weak point in an array of enemies. - by Aftermath'
|
||||||
|
x: 47.38
|
||||||
|
y: 70.55
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Sword Loop'
|
||||||
|
difficulty: 2
|
||||||
|
id: 'sword-loop'
|
||||||
|
image: '/file/db/level/525dc5589a0765e496000006/drink_me_icon.png'
|
||||||
|
description: 'Kill the ogres and save the peasants with for-loops. - by Prabh Simran Singh Baweja'
|
||||||
|
x: 52.66
|
||||||
|
y: 69.66
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Coin Mania'
|
||||||
|
difficulty: 2
|
||||||
|
id: 'coin-mania'
|
||||||
|
image: '/file/db/level/529662dfe0df8f0000000007/grab_the_mushroom_icon.png'
|
||||||
|
description: 'Learn while-loops to grab coins and potions. - by Prabh Simran Singh Baweja'
|
||||||
|
x: 58.46
|
||||||
|
y: 66.38
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Find the Spy'
|
||||||
|
difficulty: 2
|
||||||
|
id: 'find-the-spy'
|
||||||
|
image: '/file/db/level/526ae95c1e5cd30000000008/zone_of_danger_icon.png'
|
||||||
|
description: 'Identify the spies hidden among your soldiers - by Nathan Gossett'
|
||||||
|
x: 63.11
|
||||||
|
y: 62.74
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Harvest Time'
|
||||||
|
difficulty: 2
|
||||||
|
id: 'harvest-time'
|
||||||
|
image: '/file/db/level/529662dfe0df8f0000000007/grab_the_mushroom_icon.png'
|
||||||
|
description: 'Collect a hundred mushrooms in just five lines of code - by Nathan Gossett'
|
||||||
|
x: 69.19
|
||||||
|
y: 60.61
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: 'Guide Everyone Home'
|
||||||
|
difficulty: 2
|
||||||
|
id: 'guide-everyone-home'
|
||||||
|
image: '/file/db/level/52740644904ac0411700067c/rescue_mission_icon.png'
|
||||||
|
description: 'Fetch the wizards teleporting into the area - by Nathan Gossett'
|
||||||
|
x: 77.54
|
||||||
|
y: 65.94
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name: "Let's go Fly a Kite"
|
||||||
|
difficulty: 3
|
||||||
|
id: 'lets-go-fly-a-kite'
|
||||||
|
image: '/file/db/level/526711d9add4f8965f000002/hunter_triplets_icon.png'
|
||||||
|
description: 'There is a horde of ogres marching on your village. Stay out of reach and use your bow to take them out! - by Danny Whittaker'
|
||||||
|
x: 84.29
|
||||||
|
y: 61.23
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
campaigns = [
|
||||||
|
{id: 'beginner', name: 'Beginner Campaign', description: '... in which you learn the wizardry of programming.', levels: tutorials, color: "rgb(255, 80, 60)"}
|
||||||
|
{id: 'multiplayer', name: 'Multiplayer Arenas', description: '... in which you code head-to-head against other players.', levels: arenas, color: "rgb(80, 5, 60)"}
|
||||||
|
{id: 'dev', name: 'Random Harder Levels', description: '... in which you learn the interface while doing something a little harder.', levels: experienced, color: "rgb(80, 60, 255)"}
|
||||||
|
{id: 'classic' ,name: 'Classic Algorithms', description: '... in which you learn the most popular algorithms in Computer Science.', levels: classicAlgorithms, color: "rgb(110, 80, 120)"}
|
||||||
|
{id: 'player_created', name: 'Player-Created', description: '... in which you battle against the creativity of your fellow <a href=\"/contribute#artisan\">Artisan Wizards</a>.', levels: playerCreated, color: "rgb(160, 160, 180)"}
|
||||||
|
]
|
|
@ -1,4 +1,4 @@
|
||||||
module.exports = results = greed: {}
|
module.exports = results = greed: {}, 'criss-cross': {}
|
||||||
|
|
||||||
results.greed.humans = [
|
results.greed.humans = [
|
||||||
{team: 'humans', rank: 1, sessionID: '5381e3537585483905a829c1', name: 'Wizard Dude', playtime: 63184, wins: 363, losses: 0, score: 363}
|
{team: 'humans', rank: 1, sessionID: '5381e3537585483905a829c1', name: 'Wizard Dude', playtime: 63184, wins: 363, losses: 0, score: 363}
|
||||||
|
@ -550,3 +550,199 @@ results.greed.ogres = [
|
||||||
{team: 'ogres', rank: 269, sessionID: '537b96b16c13497e05de82a8', name: 'Krris', playtime: 2618, wins: 0, losses: 379, score: -379}
|
{team: 'ogres', rank: 269, sessionID: '537b96b16c13497e05de82a8', name: 'Krris', playtime: 2618, wins: 0, losses: 379, score: -379}
|
||||||
{team: 'ogres', rank: 270, sessionID: '537bc1b81db8c8ac063a3b7b', name: 'jpiasetz', playtime: 14565, wins: 0, losses: 380, score: -380}
|
{team: 'ogres', rank: 270, sessionID: '537bc1b81db8c8ac063a3b7b', name: 'jpiasetz', playtime: 14565, wins: 0, losses: 380, score: -380}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
results['criss-cross'].humans = [
|
||||||
|
{team: 'humans', rank: 1, sessionID: '53f63c00f7bc7336054f14f5', codeLanguage: 'javascript', name: 'mdz', score: 89.27983686}
|
||||||
|
{team: 'humans', rank: 2, sessionID: '53f5fdb054e4f234059ff58d', codeLanguage: 'javascript', name: 'Nafaya', score: 84.77623255}
|
||||||
|
{team: 'humans', rank: 3, sessionID: '53f4c7f454e4f234059e97a0', codeLanguage: 'javascript', name: 'nino48', score: 84.62650458}
|
||||||
|
{team: 'humans', rank: 4, sessionID: '53f66c3af7bc7336054f4b93', codeLanguage: 'javascript', name: 'Cracker', score: 82.04044463}
|
||||||
|
{team: 'humans', rank: 5, sessionID: '53f3b7751171a83405504419', codeLanguage: 'javascript', name: 'c11ris', score: 68.68840693}
|
||||||
|
{team: 'humans', rank: 6, sessionID: '5400515cff5d7535058f274e', codeLanguage: 'javascript', name: 'fireantik', score: 67.38125522}
|
||||||
|
{team: 'humans', rank: 7, sessionID: '53f6924ff7bc7336054f6007', codeLanguage: 'javascript', name: 'Alexei2', score: 66.05333713}
|
||||||
|
{team: 'humans', rank: 8, sessionID: '53f4c91c54e4f234059e9824', codeLanguage: 'javascript', name: 'Mortimer Blackwood', score: 65.94607122}
|
||||||
|
{team: 'humans', rank: 9, sessionID: '53a35c928dd4b200006b0573', codeLanguage: 'python', name: 'Nick', score: 63.06756959}
|
||||||
|
{team: 'humans', rank: 10, sessionID: '53f6c36ffda22e3305c025cb', codeLanguage: 'javascript', name: 'lichens', score: 60.19465423}
|
||||||
|
{team: 'humans', rank: 11, sessionID: '53f397aae7a7643005c042f7', codeLanguage: 'javascript', name: 'qwe', score: 60.03001559}
|
||||||
|
{team: 'humans', rank: 12, sessionID: '53f45a49fda22e3305bd9009', codeLanguage: 'javascript', name: 'paulgator', score: 59.8852267}
|
||||||
|
{team: 'humans', rank: 13, sessionID: '5406519efcbd8f33059c4ea8', codeLanguage: 'javascript', name: 'shadowfire', score: 59.61113289}
|
||||||
|
{team: 'humans', rank: 14, sessionID: '53ac4b7123798d3605a87f9f', codeLanguage: 'javascript', name: 'DollarAkshay', score: 56.10811426}
|
||||||
|
{team: 'humans', rank: 15, sessionID: '53f7d4dbbc7e716d14e80de6', codeLanguage: 'javascript', name: 'cholesky', score: 55.27757899}
|
||||||
|
{team: 'humans', rank: 16, sessionID: '53f39df01171a834055013df', codeLanguage: 'javascript', name: 'Wizard Dude', score: 55.22843626}
|
||||||
|
{team: 'humans', rank: 17, sessionID: '53b2ba14102a853605e48f39', codeLanguage: 'javascript', name: 'nemoyatpeace', score: 54.3862373}
|
||||||
|
{team: 'humans', rank: 18, sessionID: '53f6be67fda22e3305c02523', codeLanguage: 'javascript', name: 'Ibyoki', score: 54.28563847}
|
||||||
|
{team: 'humans', rank: 19, sessionID: '53f554c6d822c23505b7b48d', codeLanguage: 'javascript', name: 'Valiant', score: 53.70432642}
|
||||||
|
{team: 'humans', rank: 20, sessionID: '53ba3f1194abf748058eb864', codeLanguage: 'javascript', name: 'Jex', score: 51.53868217}
|
||||||
|
{team: 'humans', rank: 21, sessionID: '53f3956e7c1c003605e8ab74', codeLanguage: 'javascript', name: 'piThrower', score: 51.38189056}
|
||||||
|
{team: 'humans', rank: 22, sessionID: '53d02fbc7b4eee430a5f238a', codeLanguage: 'javascript', name: 'dcm', score: 51.079906}
|
||||||
|
{team: 'humans', rank: 23, sessionID: '53f5b34154e4f234059fcc34', codeLanguage: 'javascript', name: 'zbanana', score: 50.4276462}
|
||||||
|
{team: 'humans', rank: 24, sessionID: '53f401c2e7a7643005c1358d', codeLanguage: 'javascript', name: 'Jerigan', score: 49.98484298}
|
||||||
|
{team: 'humans', rank: 25, sessionID: '53fbcdd07c3dc73405009ca5', codeLanguage: 'javascript', name: 'ojannen', score: 49.70746541}
|
||||||
|
{team: 'humans', rank: 26, sessionID: '53f59a2fd822c23505b80aff', codeLanguage: 'javascript', name: 'gorunir', score: 48.68311327}
|
||||||
|
{team: 'humans', rank: 27, sessionID: '53f3a5b3e7a7643005c05d11', codeLanguage: 'javascript', name: 'Tilorian', score: 47.32564935}
|
||||||
|
{team: 'humans', rank: 28, sessionID: '53f38b90e7a7643005c0150d', codeLanguage: 'javascript', name: 'MyWizard', score: 46.616599}
|
||||||
|
{team: 'humans', rank: 29, sessionID: '53f3dbf3e7a7643005c0dd43', codeLanguage: 'javascript', name: 'Terebijoke', score: 45.40772291}
|
||||||
|
{team: 'humans', rank: 30, sessionID: '53c22de027d0244a057ecbd8', codeLanguage: 'javascript', name: 'JavaCaster1', score: 45.08075025}
|
||||||
|
{team: 'humans', rank: 31, sessionID: '53f8f7de67ab263605e41dc6', codeLanguage: 'javascript', name: 'Moojo', score: 43.91409757}
|
||||||
|
{team: 'humans', rank: 32, sessionID: '53f49f28d822c23505b6ccdb', codeLanguage: 'clojure', name: 'jChuck', score: 43.69648547}
|
||||||
|
{team: 'humans', rank: 33, sessionID: '53f3ecaa8165533205fb46a2', codeLanguage: 'javascript', name: 'MCS', score: 43.65500921}
|
||||||
|
{team: 'humans', rank: 34, sessionID: '53f51289fda22e3305beac6a', codeLanguage: 'javascript', name: 'anykey', score: 43.52308768}
|
||||||
|
{team: 'humans', rank: 35, sessionID: '53f3a645e7a7643005c05dd8', codeLanguage: 'javascript', name: 'Nazywam', score: 42.76690262}
|
||||||
|
{team: 'humans', rank: 36, sessionID: '53f3b7a6e7a7643005c08b17', codeLanguage: 'javascript', name: 'Lunt', score: 42.5117331}
|
||||||
|
{team: 'humans', rank: 37, sessionID: '53fb57b85cfd700d099b733e', codeLanguage: 'python', name: 'other019', score: 42.46817345}
|
||||||
|
{team: 'humans', rank: 38, sessionID: '53fb51c83baef834054b5f87', codeLanguage: 'python', name: 'KiPu', score: 42.37172766}
|
||||||
|
{team: 'humans', rank: 39, sessionID: '53f7b114c5baa2f41501231a', codeLanguage: 'javascript', name: 'Pop-up', score: 42.10472537}
|
||||||
|
{team: 'humans', rank: 40, sessionID: '53f3866b7c1c003605e886cf', codeLanguage: 'javascript', name: 'Plak87', score: 40.75472545}
|
||||||
|
{team: 'humans', rank: 41, sessionID: '53f4c876f7bc7336054d84cf', codeLanguage: 'javascript', name: 'chriswen', score: 40.2773747}
|
||||||
|
{team: 'humans', rank: 42, sessionID: '53fad79467ab263605e5daff', codeLanguage: 'python', name: 'JLeow00', score: 40.23592348}
|
||||||
|
{team: 'humans', rank: 43, sessionID: '53f3909e7c1c003605e8a089', codeLanguage: 'javascript', name: 'juckele', score: 39.71481956}
|
||||||
|
{team: 'humans', rank: 44, sessionID: '53f387abe7a7643005c01095', codeLanguage: 'python', name: 'parseval', score: 39.40974773}
|
||||||
|
{team: 'humans', rank: 45, sessionID: '53f387b47c1c003605e8878a', codeLanguage: 'javascript', name: 'NicRio', score: 39.06434886}
|
||||||
|
{team: 'humans', rank: 46, sessionID: '53f6377154e4f23405a05ce6', codeLanguage: 'javascript', name: 'Moji', score: 38.60381239}
|
||||||
|
{team: 'humans', rank: 47, sessionID: '54022fd6973a642e10f08679', codeLanguage: 'javascript', name: 'droidwarrior', score: 38.12258027}
|
||||||
|
{team: 'humans', rank: 48, sessionID: '53f47e87fda22e3305bdbc2d', codeLanguage: 'javascript', name: 'Santinell', score: 37.77333035}
|
||||||
|
{team: 'humans', rank: 49, sessionID: '53fcfddf10bddbd805b1606a', codeLanguage: 'javascript', name: '[i].Lashes', score: 37.10129461}
|
||||||
|
{team: 'humans', rank: 50, sessionID: '54034c2a0557f27b0c33577a', codeLanguage: 'javascript', name: 'Finwe', score: 36.33095077}
|
||||||
|
{team: 'humans', rank: 51, sessionID: '53f490dcd822c23505b6c346', codeLanguage: 'python', name: 'AlienHunter3010', score: 35.57859105}
|
||||||
|
{team: 'humans', rank: 52, sessionID: '53f3e780e7a7643005c0ecd5', codeLanguage: 'javascript', name: 'Plloi', score: 34.79515433}
|
||||||
|
{team: 'humans', rank: 53, sessionID: '53fe1d04450764220abe3ff4', codeLanguage: 'javascript', name: 'Ehrks', score: 34.79168316}
|
||||||
|
{team: 'humans', rank: 54, sessionID: '53f3927fe7a7643005c03438', codeLanguage: 'javascript', name: 'taz', score: 34.2703216}
|
||||||
|
{team: 'humans', rank: 55, sessionID: '53f37d707c1c003605e87b1a', codeLanguage: 'javascript', name: 'zero_degrees', score: 33.64927149}
|
||||||
|
{team: 'humans', rank: 56, sessionID: '53f47bbdd822c23505b6a40a', codeLanguage: 'javascript', name: 'liorst1', score: 33.60823861}
|
||||||
|
{team: 'humans', rank: 57, sessionID: '541413a75117a4d10e468fe5', codeLanguage: 'python', name: 'Ever', score: 33.5904028}
|
||||||
|
{team: 'humans', rank: 58, sessionID: '53f671acfda22e3305c009a2', codeLanguage: 'python', name: 'Gnu', score: 33.42381407}
|
||||||
|
{team: 'humans', rank: 59, sessionID: '53fdb707a1a2c92409fd3fae', codeLanguage: 'javascript', name: 'gyuri', score: 32.56147128}
|
||||||
|
{team: 'humans', rank: 60, sessionID: '53dee08059839b35051fb52f', codeLanguage: 'javascript', name: 'Lanner', score: 31.89927824}
|
||||||
|
{team: 'humans', rank: 61, sessionID: '53f566b3f7bc7336054e3f4f', codeLanguage: 'javascript', name: 'redWizzard', score: 31.71795432}
|
||||||
|
{team: 'humans', rank: 62, sessionID: '53f38d58e7a7643005c0205e', codeLanguage: 'javascript', name: 'Maixck', score: 31.13482773}
|
||||||
|
{team: 'humans', rank: 63, sessionID: '5416ada992fc490115ce300c', codeLanguage: 'javascript', name: 'DanielAwesome', score: 30.0249466}
|
||||||
|
{team: 'humans', rank: 64, sessionID: '53f3f08d1171a8340550b8e3', codeLanguage: 'python', name: 'Handsome2734', score: 29.61969526}
|
||||||
|
{team: 'humans', rank: 65, sessionID: '540d9481a6128791125a1765', codeLanguage: 'javascript', name: 'Thom VB', score: 29.59295282}
|
||||||
|
{team: 'humans', rank: 66, sessionID: '5415d931fed2785a13ccac3b', codeLanguage: 'python', name: 'RedPill', score: 28.6484878}
|
||||||
|
{team: 'humans', rank: 67, sessionID: '53f3969f7c1c003605e8aeda', codeLanguage: 'python', name: 'Icatpasdu', score: 28.59919383}
|
||||||
|
{team: 'humans', rank: 68, sessionID: '53f422abe7a7643005c17609', codeLanguage: 'python', name: 'akhtyamovpavel', score: 28.53107357}
|
||||||
|
{team: 'humans', rank: 69, sessionID: '53a341aeaa66a7afbe3d1175', codeLanguage: 'javascript', name: 'Scott', score: 28.13105798}
|
||||||
|
{team: 'humans', rank: 70, sessionID: '5408bee18d0b993805d6e2ed', codeLanguage: 'python', name: 'Juan13', score: 27.72431383}
|
||||||
|
{team: 'humans', rank: 71, sessionID: '53f3827c8165533205fa7e53', codeLanguage: 'coffeescript', name: 'Anomander', score: 27.48633158}
|
||||||
|
{team: 'humans', rank: 72, sessionID: '53f4e25cf7bc7336054dcb1e', codeLanguage: 'javascript', name: 'Eterm', score: 27.44590315}
|
||||||
|
{team: 'humans', rank: 73, sessionID: '53f3e09f1171a83405509857', codeLanguage: 'javascript', name: 'stuntman_fx', score: 27.31894123}
|
||||||
|
{team: 'humans', rank: 74, sessionID: '54022bcd0557f27b0c32a26a', codeLanguage: 'javascript', name: 'matom', score: 26.92817056}
|
||||||
|
{team: 'humans', rank: 75, sessionID: '540eaeae25c82d2b06e84e6e', codeLanguage: 'python', name: 'JamiePilgrim', score: 26.66085117}
|
||||||
|
{team: 'humans', rank: 76, sessionID: '53f39bef8165533205faaf1c', codeLanguage: 'python', name: 'Gybseaa', score: 25.67104323}
|
||||||
|
{team: 'humans', rank: 77, sessionID: '53f5266dfda22e3305bec4d4', codeLanguage: 'python', name: 'sdetfaewtgswrf', score: 25.11200369}
|
||||||
|
{team: 'humans', rank: 78, sessionID: '53f3bade7c1c003605e912e8', codeLanguage: 'javascript', name: 'Tyler', score: 24.45104378}
|
||||||
|
{team: 'humans', rank: 79, sessionID: '54145e81e8c6b8ed0ec3c0de', codeLanguage: 'javascript', name: 'yuvi', score: 23.35851543}
|
||||||
|
{team: 'humans', rank: 80, sessionID: '53f37c861171a834054fd63f', codeLanguage: 'python', name: 'pbd', score: 21.95799255}
|
||||||
|
{team: 'humans', rank: 81, sessionID: '53f67052f7bc7336054f4d9f', codeLanguage: 'python', name: 'Napillo', score: 21.59848035}
|
||||||
|
{team: 'humans', rank: 82, sessionID: '53f5a34ed822c23505b80e62', codeLanguage: 'javascript', name: 'Sailor', score: 19.88903243}
|
||||||
|
{team: 'humans', rank: 83, sessionID: '53f60815fda22e3305bf8d14', codeLanguage: 'javascript', name: 'Gordon2012', score: 19.3703958}
|
||||||
|
{team: 'humans', rank: 84, sessionID: '53f3a49ce7a7643005c05c28', codeLanguage: 'clojure', name: 'Oze', score: 19.15746715}
|
||||||
|
{team: 'humans', rank: 85, sessionID: '53f3cee5e7a7643005c0cd04', codeLanguage: 'javascript', name: 'Frewdicket', score: 18.32983195}
|
||||||
|
{team: 'humans', rank: 86, sessionID: '53f3dfe07c1c003605e9560b', codeLanguage: 'python', name: 'Wizardioo', score: 17.24637409}
|
||||||
|
{team: 'humans', rank: 87, sessionID: '53f73786d822c23505b99bdc', codeLanguage: 'javascript', name: 'WOUN', score: 16.09512312}
|
||||||
|
{team: 'humans', rank: 88, sessionID: '53fb3c3567ab263605e64525', codeLanguage: 'javascript', name: 'Uyjen', score: 15.41176492}
|
||||||
|
{team: 'humans', rank: 89, sessionID: '5412232591cb5534055f9df1', codeLanguage: 'javascript', name: 'alltom', score: 14.93217724}
|
||||||
|
{team: 'humans', rank: 90, sessionID: '53a35877367e5794b2f5d430', codeLanguage: 'javascript', name: 'Michael S.', score: 14.69737904}
|
||||||
|
{team: 'humans', rank: 91, sessionID: '53f3959a7c1c003605e8ab90', codeLanguage: 'javascript', name: 'Xyphex', score: 14.60922258}
|
||||||
|
{team: 'humans', rank: 92, sessionID: '53fdfc25bfe0d7f308a6c2f8', codeLanguage: 'javascript', name: 'BEFOR', score: 14.09951331}
|
||||||
|
{team: 'humans', rank: 93, sessionID: '53f39293e7a7643005c03596', codeLanguage: 'python', name: 'melondonkey', score: 13.66123744}
|
||||||
|
{team: 'humans', rank: 94, sessionID: '53f5865efda22e3305bf2296', codeLanguage: 'python', name: 'hax0r00110', score: 13.27129663}
|
||||||
|
{team: 'humans', rank: 95, sessionID: '53fb87786c1ea23605924fc5', codeLanguage: 'lua', name: 'Joker78', score: 12.82530944}
|
||||||
|
{team: 'humans', rank: 96, sessionID: '54127ddcb2f1cc3605cf7454', codeLanguage: 'javascript', name: 'yakotaki', score: 12.80841814}
|
||||||
|
{team: 'humans', rank: 97, sessionID: '54172c214580e6bb21433b96', codeLanguage: 'javascript', name: 'VictorMGB', score: 11.79712559}
|
||||||
|
{team: 'humans', rank: 98, sessionID: '5410b0520e98527205cf23b8', codeLanguage: 'python', name: 'SliceNDiceSpud', score: 11.7339923}
|
||||||
|
{team: 'humans', rank: 99, sessionID: '53fd248cb14343450634feda', codeLanguage: 'python', name: 'Galvan', score: 11.2788073}
|
||||||
|
{team: 'humans', rank: 100, sessionID: '53ff3dcf919148a7074c9608', codeLanguage: 'clojure', name: 'jjjjj', score: 10.28409032}
|
||||||
|
{team: 'humans', rank: 101, sessionID: '53b4a6862082f23505b849f7', codeLanguage: 'javascript', name: 'Anonymous', score: 10.10879041}
|
||||||
|
{team: 'humans', rank: 102, sessionID: '5415de2dc6f5ec4e13326a22', codeLanguage: 'javascript', name: 'Anonymous', score: 10.08833109}
|
||||||
|
{team: 'humans', rank: 103, sessionID: '53f803b0bc7e716d14e82fde', codeLanguage: 'javascript', name: 'Aaryan', score: 10.0045068}
|
||||||
|
{team: 'humans', rank: 104, sessionID: '53f848714d9388fa15d1a457', codeLanguage: 'python', name: 'null000llun', score: 9.753414719}
|
||||||
|
{team: 'humans', rank: 105, sessionID: '53fc7b9a7c3dc7340500f09a', codeLanguage: 'javascript', name: 'Hackrylix', score: 9.704839891}
|
||||||
|
{team: 'humans', rank: 106, sessionID: '53f9aa35549ae742068f9f7e', codeLanguage: 'javascript', name: 'AlexTelon', score: 9.357260227}
|
||||||
|
{team: 'humans', rank: 107, sessionID: '53f72633fda22e3305c06b56', codeLanguage: 'javascript', name: 'eellson', score: 8.949914084}
|
||||||
|
{team: 'humans', rank: 108, sessionID: '54049a2011058b421307e0e1', codeLanguage: 'javascript', name: 'ugly loaf', score: 8.813606154}
|
||||||
|
{team: 'humans', rank: 109, sessionID: '53f98c823baef834054a0544', codeLanguage: 'javascript', name: 'Gamagori-sama', score: 8.52660922}
|
||||||
|
{team: 'humans', rank: 110, sessionID: '54019e1e49086dee0ddaf200', codeLanguage: 'javascript', name: 'akonand', score: 7.542416738}
|
||||||
|
{team: 'humans', rank: 111, sessionID: '53f39b918165533205faaed6', codeLanguage: 'python', name: 'roshan360', score: 6.740957014}
|
||||||
|
{team: 'humans', rank: 112, sessionID: '54046519e2b6e64a1832659d', codeLanguage: 'javascript', name: 'Val-per', score: 6.444447281}
|
||||||
|
{team: 'humans', rank: 113, sessionID: '53fe8cee95fba83305f4592d', codeLanguage: 'javascript', name: 'Bendalf0', score: 6.003282371}
|
||||||
|
{team: 'humans', rank: 114, sessionID: '53a39f1a573d6d3505b187de', codeLanguage: 'javascript', name: '┬─┬ノ( º _ ºノ)', score: 5.650008807}
|
||||||
|
{team: 'humans', rank: 115, sessionID: '540efacbba536e450767b2e8', codeLanguage: 'javascript', name: 'cole3', score: 5.314407805}
|
||||||
|
{team: 'humans', rank: 116, sessionID: '540fb13d098c622109a769e5', codeLanguage: 'python', name: 'Crunchy Meatball', score: 5.107994897}
|
||||||
|
{team: 'humans', rank: 117, sessionID: '53b36e22bb61aa3405d50f18', codeLanguage: 'javascript', name: 'sjarvie', score: 4.846878355}
|
||||||
|
]
|
||||||
|
|
||||||
|
results['criss-cross'].ogres = [
|
||||||
|
{team: 'ogres', rank: 1, sessionID: '5404bc1a2c6432b618fdbc41', codeLanguage: 'javascript', name: 'HighSea', score: 86.69028832}
|
||||||
|
{team: 'ogres', rank: 2, sessionID: '53f3ba2d1171a834055046f2', codeLanguage: 'javascript', name: 'matthewd', score: 82.94918281}
|
||||||
|
{team: 'ogres', rank: 3, sessionID: '53f397528165533205faabbf', codeLanguage: 'clojure', name: 'Driphter', score: 78.85897022}
|
||||||
|
{team: 'ogres', rank: 4, sessionID: '53f3ac981171a83405503789', codeLanguage: 'javascript', name: 'Forsaken', score: 78.63231082}
|
||||||
|
{team: 'ogres', rank: 5, sessionID: '53f4d91d54e4f234059ea96c', codeLanguage: 'javascript', name: 'Tehvudgaw', score: 76.79927673}
|
||||||
|
{team: 'ogres', rank: 6, sessionID: '53fe21d197d25d030aae69c8', codeLanguage: 'javascript', name: 'Blash', score: 74.05348884}
|
||||||
|
{team: 'ogres', rank: 7, sessionID: '53f8f7c967ab263605e41dbf', codeLanguage: 'javascript', name: 'Aldo', score: 73.47433531}
|
||||||
|
{team: 'ogres', rank: 8, sessionID: '53f94a206c1ea23605902730', codeLanguage: 'javascript', name: 'ThatOtherPerson', score: 69.82052272}
|
||||||
|
{team: 'ogres', rank: 9, sessionID: '54171cd74580e6bb2143312d', codeLanguage: 'javascript', name: 'Tech', score: 68.94907702}
|
||||||
|
{team: 'ogres', rank: 10, sessionID: '53f86f3cbc7e716d14e8a15c', codeLanguage: 'python', name: 'CookieMonster', score: 66.97949263}
|
||||||
|
{team: 'ogres', rank: 11, sessionID: '53f49a36d822c23505b6cb63', codeLanguage: 'python', name: 'odoacre', score: 65.53452876}
|
||||||
|
{team: 'ogres', rank: 12, sessionID: '53f6f84654e4f23405a1070e', codeLanguage: 'javascript', name: 'Arkhaix', score: 62.24714335}
|
||||||
|
{team: 'ogres', rank: 13, sessionID: '53f3b0257c1c003605e8ee11', codeLanguage: 'python', name: 'Buddy7', score: 61.63398791}
|
||||||
|
{team: 'ogres', rank: 14, sessionID: '53f39dce7c1c003605e8bdab', codeLanguage: 'javascript', name: 'CryZe', score: 61.00336334}
|
||||||
|
{team: 'ogres', rank: 15, sessionID: '53f38d7f7c1c003605e893b7', codeLanguage: 'javascript', name: 'Interimo', score: 57.77153143}
|
||||||
|
{team: 'ogres', rank: 16, sessionID: '53ced120f5ef3848053b9033', codeLanguage: 'javascript', name: 'chess', score: 55.44106174}
|
||||||
|
{team: 'ogres', rank: 17, sessionID: '53f39bde1171a83405500eab', codeLanguage: 'javascript', name: 'MyWizardlyName', score: 52.78486678}
|
||||||
|
{team: 'ogres', rank: 18, sessionID: '53f7e3e0b8a67b731487de15', codeLanguage: 'python', name: 'nineties', score: 52.48111694}
|
||||||
|
{team: 'ogres', rank: 19, sessionID: '540f6761098c622109a74a7d', codeLanguage: 'javascript', name: 'snake-345', score: 50.92666589}
|
||||||
|
{team: 'ogres', rank: 20, sessionID: '53f3f1468165533205fb63e1', codeLanguage: 'javascript', name: 'jmmk', score: 48.92922599}
|
||||||
|
{team: 'ogres', rank: 21, sessionID: '53f39896e7a7643005c0443d', codeLanguage: 'javascript', name: 'aggressiveFloor', score: 48.14095491}
|
||||||
|
{team: 'ogres', rank: 22, sessionID: '53f389d48165533205fa8599', codeLanguage: 'javascript', name: 'RustyDoorknobs', score: 47.26139895}
|
||||||
|
{team: 'ogres', rank: 23, sessionID: '53f44cfafda22e3305bd815c', codeLanguage: 'python', name: 'PugachAG', score: 47.04215583}
|
||||||
|
{team: 'ogres', rank: 24, sessionID: '53f3f12b1171a8340550c098', codeLanguage: 'python', name: 'lanzafame', score: 46.62859491}
|
||||||
|
{team: 'ogres', rank: 25, sessionID: '540725e9fedc2a55092aedf5', codeLanguage: 'python', name: 'Snooze', score: 44.8836671}
|
||||||
|
{team: 'ogres', rank: 26, sessionID: '53b36ac7bb61aa3405d50df3', codeLanguage: 'javascript', name: 'differentmatt', score: 44.48371038}
|
||||||
|
{team: 'ogres', rank: 27, sessionID: '53ffbc9c4fa75bc805dc8fd7', codeLanguage: 'javascript', name: 'kwksilver', score: 43.89457566}
|
||||||
|
{team: 'ogres', rank: 28, sessionID: '53f86ac64d9388fa15d1cb81', codeLanguage: 'javascript', name: 'Burhub', score: 43.15569365}
|
||||||
|
{team: 'ogres', rank: 29, sessionID: '5407b788e2007791053bb498', codeLanguage: 'javascript', name: 'SocioDude', score: 43.15346459}
|
||||||
|
{team: 'ogres', rank: 30, sessionID: '53f46bbb54e4f234059e118f', codeLanguage: 'javascript', name: 'Diruna', score: 43.14092027}
|
||||||
|
{team: 'ogres', rank: 31, sessionID: '53fad85d6c1ea2360591b7bc', codeLanguage: 'python', name: 'XY00', score: 42.82746659}
|
||||||
|
{team: 'ogres', rank: 32, sessionID: '53f4d3ef54e4f234059ea632', codeLanguage: 'javascript', name: 'Kefir', score: 42.12141876}
|
||||||
|
{team: 'ogres', rank: 33, sessionID: '5402249e42fb9c380ad1ee81', codeLanguage: 'python', name: 'mattmatt', score: 41.89852019}
|
||||||
|
{team: 'ogres', rank: 34, sessionID: '53f4c47e54e4f234059e95bb', codeLanguage: 'javascript', name: 'Trefader', score: 41.30414337}
|
||||||
|
{team: 'ogres', rank: 35, sessionID: '53fa70243baef834054ab75a', codeLanguage: 'javascript', name: 'haydennedyah', score: 41.22021639}
|
||||||
|
{team: 'ogres', rank: 36, sessionID: '53fdc936bfe0d7f308a6911c', codeLanguage: 'python', name: 'Luogbelnu', score: 40.96555677}
|
||||||
|
{team: 'ogres', rank: 37, sessionID: '53ffc7e4a1e10bbd05ae2e1b', codeLanguage: 'python', name: 'bob0the0mighty', score: 40.41223631}
|
||||||
|
{team: 'ogres', rank: 38, sessionID: '53f5d0f2fda22e3305bf67ed', codeLanguage: 'javascript', name: 'lifeline', score: 39.0406456}
|
||||||
|
{team: 'ogres', rank: 39, sessionID: '53f379ca7c1c003605e8793d', codeLanguage: 'coffeescript', name: 'Makaze', score: 38.88913774}
|
||||||
|
{team: 'ogres', rank: 40, sessionID: '53f39b577c1c003605e8b97a', codeLanguage: 'javascript', name: 'Braleigh', score: 38.19984465}
|
||||||
|
{team: 'ogres', rank: 41, sessionID: '53f4b841fda22e3305be136a', codeLanguage: 'python', name: 'qeinar', score: 38.13867335}
|
||||||
|
{team: 'ogres', rank: 42, sessionID: '53fbf5e7547f52350547a66f', codeLanguage: 'javascript', name: 'Ziroby', score: 37.48383317}
|
||||||
|
{team: 'ogres', rank: 43, sessionID: '54161f1dc6f5ec4e13328bd8', codeLanguage: 'javascript', name: 'MrCrepe', score: 37.3907791}
|
||||||
|
{team: 'ogres', rank: 44, sessionID: '53f4e5efd822c23505b74ecd', codeLanguage: 'javascript', name: 'Ryan Matte', score: 36.780337}
|
||||||
|
{team: 'ogres', rank: 45, sessionID: '541721b34580e6bb21433509', codeLanguage: 'javascript', name: 'Ryemane', score: 36.40478416}
|
||||||
|
{team: 'ogres', rank: 46, sessionID: '53f4f349d822c23505b758a0', codeLanguage: 'python', name: 'ChadM', score: 34.0284634}
|
||||||
|
{team: 'ogres', rank: 47, sessionID: '540d00a18b7031c212067cfe', codeLanguage: 'javascript', name: 'mch82', score: 33.45805275}
|
||||||
|
{team: 'ogres', rank: 48, sessionID: '53f37d318165533205fa7af0', codeLanguage: 'python', name: 'Mateo', score: 33.31751134}
|
||||||
|
{team: 'ogres', rank: 49, sessionID: '53f57005fda22e3305befc0d', codeLanguage: 'python', name: 'liewjianwei7', score: 32.86449352}
|
||||||
|
{team: 'ogres', rank: 50, sessionID: '540a44e6a8fb9e2908864a95', codeLanguage: 'python', name: 'NupTup', score: 31.54057431}
|
||||||
|
{team: 'ogres', rank: 51, sessionID: '53ff7b1e620719340501eb62', codeLanguage: 'javascript', name: 'korrident', score: 30.36103457}
|
||||||
|
{team: 'ogres', rank: 52, sessionID: '5413faed64e0ac4609bc0506', codeLanguage: 'javascript', name: 'Vhr', score: 29.57257834}
|
||||||
|
{team: 'ogres', rank: 53, sessionID: '53fe610581b81d3505175aa4', codeLanguage: 'javascript', name: 'Anonymous', score: 26.11692793}
|
||||||
|
{team: 'ogres', rank: 54, sessionID: '53f4320a1171a8340551357c', codeLanguage: 'python', name: 'igemon', score: 25.57886325}
|
||||||
|
{team: 'ogres', rank: 55, sessionID: '53f44441f7bc7336054cec4c', codeLanguage: 'python', name: 'Willybe', score: 25.31132405}
|
||||||
|
{team: 'ogres', rank: 56, sessionID: '54092dfb4236843405e684e6', codeLanguage: 'javascript', name: 'Noidificus', score: 25.24067489}
|
||||||
|
{team: 'ogres', rank: 57, sessionID: '5408aac5901c3f7007b60799', codeLanguage: 'javascript', name: 'Robert7', score: 25.15177276}
|
||||||
|
{team: 'ogres', rank: 58, sessionID: '53f5364a54e4f234059f3d3b', codeLanguage: 'javascript', name: 'Bage', score: 24.80093885}
|
||||||
|
{team: 'ogres', rank: 59, sessionID: '53fc1b22547f52350547be8a', codeLanguage: 'javascript', name: 'Christian S.', score: 24.51828741}
|
||||||
|
{team: 'ogres', rank: 60, sessionID: '53f3efd17c1c003605e97769', codeLanguage: 'javascript', name: 'Dodrithard', score: 24.25374686}
|
||||||
|
{team: 'ogres', rank: 61, sessionID: '53f4e550fda22e3305be7032', codeLanguage: 'javascript', name: 'Saikarsis', score: 24.03641464}
|
||||||
|
{team: 'ogres', rank: 62, sessionID: '53f64591d822c23505b8b536', codeLanguage: 'javascript', name: 'SurferIX', score: 22.50107203}
|
||||||
|
{team: 'ogres', rank: 63, sessionID: '53f89788bc7e716d14e8e536', codeLanguage: 'javascript', name: 'Ezrael', score: 22.06693778}
|
||||||
|
{team: 'ogres', rank: 64, sessionID: '53f39c91e7a7643005c04751', codeLanguage: 'javascript', name: 'ksj00', score: 16.40406633}
|
||||||
|
{team: 'ogres', rank: 65, sessionID: '53f396f41171a834055008e0', codeLanguage: 'javascript', name: 'no_login_found', score: 14.50374011}
|
||||||
|
{team: 'ogres', rank: 66, sessionID: '53f6ac1fd822c23505b91f29', codeLanguage: 'javascript', name: 'soccer66', score: 13.95564768}
|
||||||
|
{team: 'ogres', rank: 67, sessionID: '53f394978165533205faa44a', codeLanguage: 'javascript', name: 'skeltoac', score: 13.77314387}
|
||||||
|
{team: 'ogres', rank: 68, sessionID: '53fdeef0a1a2c92409fd7dd1', codeLanguage: 'javascript', name: 'Luke Lunsford', score: 12.31318938}
|
||||||
|
{team: 'ogres', rank: 69, sessionID: '53ed2e5c5d4d593305f9d006', codeLanguage: 'python', name: 'Sir Giroto', score: 11.90012214}
|
||||||
|
{team: 'ogres', rank: 70, sessionID: '53a3a012573d6d3505b1882b', codeLanguage: 'javascript', name: 'Quantanaray', score: 11.7169867}
|
||||||
|
{team: 'ogres', rank: 71, sessionID: '5414d693e4fb6fc61274e974', codeLanguage: 'javascript', name: 'XxDavidxX', score: 11.32103184}
|
||||||
|
{team: 'ogres', rank: 72, sessionID: '53f4847afda22e3305bdbea5', codeLanguage: 'javascript', name: 'CodeMinion', score: 9.706964015}
|
||||||
|
{team: 'ogres', rank: 73, sessionID: '53fba49c3baef834054b98c6', codeLanguage: 'javascript', name: 'Moises Banales', score: 8.991630973}
|
||||||
|
]
|
||||||
|
|
|
@ -27,7 +27,10 @@ module.exports = class LevelChatView extends CocoView
|
||||||
|
|
||||||
updateMultiplayerVisibility: ->
|
updateMultiplayerVisibility: ->
|
||||||
return unless @$el?
|
return unless @$el?
|
||||||
@$el.toggle Boolean @session.get('multiplayer')
|
try
|
||||||
|
@$el.toggle Boolean @session.get('multiplayer')
|
||||||
|
catch e
|
||||||
|
console.error "Couldn't toggle the style on the LevelChatView to #{Boolean @session.get('multiplayer')} because of an error:", e
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
@chatTables = $('table', @$el)
|
@chatTables = $('table', @$el)
|
||||||
|
|
28
app/views/play/modal/PlayAccountModal.coffee
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
ModalView = require 'views/kinds/ModalView'
|
||||||
|
template = require 'templates/play/modal/play-account-modal'
|
||||||
|
|
||||||
|
module.exports = class PlayAccountModal extends ModalView
|
||||||
|
className: 'modal fade play-modal'
|
||||||
|
template: template
|
||||||
|
modalWidthPercent: 90
|
||||||
|
id: 'play-account-modal'
|
||||||
|
#instant: true
|
||||||
|
|
||||||
|
#events:
|
||||||
|
# 'change input.select': 'onSelectionChanged'
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super options
|
||||||
|
|
||||||
|
getRenderData: (context={}) ->
|
||||||
|
context = super(context)
|
||||||
|
context
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
||||||
|
return unless @supermodel.finished()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
|
||||||
|
|
||||||
|
onHidden: ->
|
||||||
|
super()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
35
app/views/play/modal/PlayAchievementsModal.coffee
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
ModalView = require 'views/kinds/ModalView'
|
||||||
|
template = require 'templates/play/modal/play-achievements-modal'
|
||||||
|
CocoCollection = require 'collections/CocoCollection'
|
||||||
|
Achievement = require 'models/Achievement'
|
||||||
|
#AchievementView = require 'views/game-menu/AchievementView'
|
||||||
|
|
||||||
|
module.exports = class PlayAchievementsModal extends ModalView
|
||||||
|
className: 'modal fade play-modal'
|
||||||
|
template: template
|
||||||
|
modalWidthPercent: 90
|
||||||
|
id: 'play-achievements-modal'
|
||||||
|
#instant: true
|
||||||
|
|
||||||
|
#events:
|
||||||
|
# 'change input.select': 'onSelectionChanged'
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super options
|
||||||
|
#@achievements = new CocoCollection([], {model: Achievement})
|
||||||
|
#@achievements.url = '/db/thang.type?view=achievements&project=name,description,components,original,rasterIcon'
|
||||||
|
#@supermodel.loadCollection(@achievements, 'achievements')
|
||||||
|
|
||||||
|
getRenderData: (context={}) ->
|
||||||
|
context = super(context)
|
||||||
|
#context.achievements = @achievements.models
|
||||||
|
context
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
||||||
|
return unless @supermodel.finished()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
|
||||||
|
|
||||||
|
onHidden: ->
|
||||||
|
super()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
47
app/views/play/modal/PlayHeroesModal.coffee
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
ModalView = require 'views/kinds/ModalView'
|
||||||
|
template = require 'templates/play/modal/play-heroes-modal'
|
||||||
|
CocoCollection = require 'collections/CocoCollection'
|
||||||
|
ThangType = require 'models/ThangType'
|
||||||
|
#HeroView = require 'views/game-menu/HeroView'
|
||||||
|
|
||||||
|
module.exports = class PlayHeroesModal extends ModalView
|
||||||
|
className: 'modal fade play-modal'
|
||||||
|
template: template
|
||||||
|
modalWidthPercent: 90
|
||||||
|
id: 'play-heroes-modal'
|
||||||
|
#instant: true
|
||||||
|
|
||||||
|
#events:
|
||||||
|
# 'change input.select': 'onSelectionChanged'
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super options
|
||||||
|
@heroes = new CocoCollection([], {model: ThangType})
|
||||||
|
@heroes.url = '/db/thang.type?view=heroes&project=name,description,components,original,rasterIcon'
|
||||||
|
@supermodel.loadCollection(@heroes, 'heroes')
|
||||||
|
|
||||||
|
getRenderData: (context={}) ->
|
||||||
|
context = super(context)
|
||||||
|
context.heroes = @heroes.models
|
||||||
|
context
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
||||||
|
return unless @supermodel.finished()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
|
||||||
|
#@addHeroViews()
|
||||||
|
|
||||||
|
onHidden: ->
|
||||||
|
super()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
||||||
|
|
||||||
|
#addHeroViews: ->
|
||||||
|
# keys = (hero.id for hero in @heroes.models)
|
||||||
|
# heroMap = _.zipObject keys, @heroes.models
|
||||||
|
# for heroStub in @$el.find('.replace-me')
|
||||||
|
# heroID = $(heroStub).data('hero-id')
|
||||||
|
# hero = heroMap[heroID]
|
||||||
|
# heroView = new HeroView({hero: hero, includes: {name: true, stats: true, props: true}})
|
||||||
|
# heroView.render()
|
||||||
|
# $(heroStub).replaceWith(heroView.$el)
|
||||||
|
# @registerSubView(heroView)
|
66
app/views/play/modal/PlayItemsModal.coffee
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
ModalView = require 'views/kinds/ModalView'
|
||||||
|
template = require 'templates/play/modal/play-items-modal'
|
||||||
|
CocoCollection = require 'collections/CocoCollection'
|
||||||
|
ThangType = require 'models/ThangType'
|
||||||
|
ItemView = require 'views/game-menu/ItemView'
|
||||||
|
|
||||||
|
module.exports = class PlayItemsModal extends ModalView
|
||||||
|
className: 'modal fade play-modal'
|
||||||
|
template: template
|
||||||
|
modalWidthPercent: 90
|
||||||
|
id: 'play-items-modal'
|
||||||
|
#instant: true
|
||||||
|
slotGroups:
|
||||||
|
armor: ['torso', 'head', 'gloves', 'feet']
|
||||||
|
hands: ['right-hand', 'left-hand']
|
||||||
|
accessories: ['eyes', 'neck', 'left-ring', 'right-ring', 'waist']
|
||||||
|
books: ['programming-book', 'spellbook']
|
||||||
|
minions: ['minion', 'pet']
|
||||||
|
misc: ['misc-0', 'misc-1', 'misc-2', 'misc-3', 'misc-4']
|
||||||
|
|
||||||
|
#events:
|
||||||
|
# 'change input.select': 'onSelectionChanged'
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super options
|
||||||
|
@items = new CocoCollection([], {model: ThangType})
|
||||||
|
@items.url = '/db/thang.type?view=items&project=name,description,components,original,rasterIcon'
|
||||||
|
@supermodel.loadCollection(@items, 'items')
|
||||||
|
|
||||||
|
groupItems: ->
|
||||||
|
groups = {}
|
||||||
|
for item in @items.models
|
||||||
|
itemSlots = item.getAllowedSlots()
|
||||||
|
for group, groupSlots of @slotGroups
|
||||||
|
if _.find itemSlots, ((slot) -> slot in groupSlots)
|
||||||
|
groups[group] ?= []
|
||||||
|
groups[group].push item
|
||||||
|
groups
|
||||||
|
|
||||||
|
getRenderData: (context={}) ->
|
||||||
|
context = super(context)
|
||||||
|
context.slotGroups = @groupItems()
|
||||||
|
context.slotGroupsArray = _.keys context.slotGroups
|
||||||
|
context.slotGroupsNames = ($.i18n.t "items.#{slotGroup}" for slotGroup in context.slotGroupsArray)
|
||||||
|
context
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
||||||
|
return unless @supermodel.finished()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
|
||||||
|
@addItemViews()
|
||||||
|
|
||||||
|
onHidden: ->
|
||||||
|
super()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|
||||||
|
|
||||||
|
addItemViews: ->
|
||||||
|
keys = (item.id for item in @items.models)
|
||||||
|
itemMap = _.zipObject keys, @items.models
|
||||||
|
for itemStub in @$el.find('.replace-me')
|
||||||
|
itemID = $(itemStub).data('item-id')
|
||||||
|
item = itemMap[itemID]
|
||||||
|
itemView = new ItemView({item: item, includes: {name: true, stats: true, props: true}})
|
||||||
|
itemView.render()
|
||||||
|
$(itemStub).replaceWith(itemView.$el)
|
||||||
|
@registerSubView(itemView)
|
28
app/views/play/modal/PlaySettingsModal.coffee
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
ModalView = require 'views/kinds/ModalView'
|
||||||
|
template = require 'templates/play/modal/play-settings-modal'
|
||||||
|
|
||||||
|
module.exports = class PlaySettingsModal extends ModalView
|
||||||
|
className: 'modal fade play-modal'
|
||||||
|
template: template
|
||||||
|
modalWidthPercent: 90
|
||||||
|
id: 'play-settings-modal'
|
||||||
|
#instant: true
|
||||||
|
|
||||||
|
#events:
|
||||||
|
# 'change input.select': 'onSelectionChanged'
|
||||||
|
|
||||||
|
constructor: (options) ->
|
||||||
|
super options
|
||||||
|
|
||||||
|
getRenderData: (context={}) ->
|
||||||
|
context = super(context)
|
||||||
|
context
|
||||||
|
|
||||||
|
afterRender: ->
|
||||||
|
super()
|
||||||
|
return unless @supermodel.finished()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-open', volume: 1
|
||||||
|
|
||||||
|
onHidden: ->
|
||||||
|
super()
|
||||||
|
Backbone.Mediator.publish 'audio-player:play-sound', trigger: 'game-menu-close', volume: 1
|