This commit is contained in:
Nick Winter 2014-02-07 16:47:38 -08:00
commit b2bf4db222
8 changed files with 226 additions and 23 deletions

View file

@ -120,6 +120,8 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@actionQueue.push @currentRootAction.relatedActions.end if @currentRootAction?.relatedActions?.end
@actionQueue.push action.relatedActions.begin if action.relatedActions?.begin
@actionQueue.push action
if action.goesTo and nextAction = @actions[action.goesTo]
@actionQueue.push nextAction if nextAction
@currentRootAction = action
@playNextAction()

View file

@ -420,7 +420,7 @@ module.exports = class World
pos = camera.worldToSurface {x: pos.x, y: pos.y} if camera # without z
if not lastPos.x? or (Math.abs(lastPos.x - pos.x) + Math.abs(lastPos.y - pos.y)) > 1
lastPos = pos
allPoints.push lastPos.y, lastPos.x
allPoints.push lastPos.y, lastPos.x unless lastPos.y is 0 and lastPos.x is 0
allPoints.reverse()
@pointsForThangCache[cacheKey] = allPoints

View file

@ -1,31 +1,31 @@
module.exports = nativeDescription: "עברית", englishDescription: "Hebrew", translation:
common:
loading: "Loading..."
# saving: "Saving..."
# sending: "Sending..."
# cancel: "Cancel"
# save: "Save"
# delay_1_sec: "1 second"
# delay_3_sec: "3 seconds"
# delay_5_sec: "5 seconds"
# manual: "Manual"
loading: "...טוען"
saving: "...שומר"
sending: "...שולח"
cancel: "ביטול"
save: "שמור"
delay_1_sec: "שניה אחת"
delay_3_sec: "שלוש שניות"
delay_5_sec: "חמש שניות"
manual: "מדריך"
# fork: "Fork"
# play: "Play"
play: "שחק"
# modal:
# close: "Close"
# okay: "Okay"
modal:
close: "סגור"
okay: "אישור"
# not_found:
# page_not_found: "Page not found"
not_found:
page_not_found: "העמוד לא נמצא"
# nav:
# play: "Levels"
# editor: "Editor"
# blog: "Blog"
# forum: "Forum"
# admin: "Admin"
# home: "Home"
nav:
play: "שלבים"
editor: "עורך"
blog: "בלוג"
forum: "פורום"
admin: "אדמין"
home: "בית"
# contribute: "Contribute"
# legal: "Legal"
# about: "About"

View file

@ -0,0 +1,2 @@
#ladder-view
color: black

View file

@ -0,0 +1,31 @@
extends /templates/base
block content
div#level-column
h3= level.get('name')
div#level-description
!{description}
div#leaderboard-column
ul.nav.nav-pills
for team in teams
li
a(href="#team-#{team.id}", data-toggle="tab")= team.name
.tab-content
for team in teams
.tab-pane(id="team-#{team.id}")
.leaderboard
h4 Leaderboard
table.table
for session in team.leaderboard.topPlayers.models
tr= session.get('creatorName')
.challengers
h4 Challengers
if team.easyChallenger
div.challenger-select
| Easy challenger:
button
a(href=link+'?team='+team.id+'&opponent='+team.easyChallenger.id)
//TODO: finish once the scoring system is finished

View file

@ -0,0 +1,138 @@
RootView = require 'views/kinds/RootView'
Level = require 'models/Level'
LevelSession = require 'models/LevelSession'
CocoCollection = require 'models/CocoCollection'
HIGHEST_SCORE = 1000000
class LevelSessionsCollection extends CocoCollection
url: ''
model: LevelSession
constructor: (levelID) ->
super()
@url = "/db/level/#{levelID}/all_sessions"
class LeaderboardCollection extends CocoCollection
url: ''
model: LevelSession
constructor: (level, options) ->
super()
options ?= {}
@url = "/db/level/#{level.get('original')}.#{level.get('version').major}/leaderboard?#{$.param(options)}"
module.exports = class LadderView extends RootView
id: 'ladder-view'
template: require 'templates/play/ladder'
startsLoading: true
constructor: (options, levelID) ->
super(options)
@level = new Level(_id:levelID)
@level.fetch()
@level.once 'sync', @onLevelLoaded, @
@sessions = new LevelSessionsCollection(levelID)
@sessions.fetch({})
@sessions.once 'sync', @onMySessionsLoaded, @
onLevelLoaded: -> @startLoadingPhaseTwoMaybe()
onMySessionsLoaded: -> @startLoadingPhaseTwoMaybe()
startLoadingPhaseTwoMaybe: ->
return unless @level.loaded and @sessions.loaded
@loadPhaseTwo()
loadPhaseTwo: ->
alliedSystem = _.find @level.get('systems'), (value) -> value.config?.teams?
teams = []
for teamName, teamConfig of alliedSystem.config.teams
continue unless teamConfig.playable
teams.push teamName
@teams = teams
@leaderboards = {}
@challengers = {}
for team in teams
teamSession = _.find @sessions.models, (session) -> session.get('team') is team
@leaderboards[team] = new LeaderboardData(@level, team, teamSession)
@leaderboards[team].once 'sync', @onLeaderboardLoaded, @
@challengers[team] = new ChallengersData(@level, team, teamSession)
@challengers[team].once 'sync', @onChallengersLoaded, @
onChallengersLoaded: -> @renderMaybe()
onLeaderboardLoaded: -> @renderMaybe()
renderMaybe: ->
loaders = _.values(@leaderboards).concat(_.values(@challengers))
return unless _.every loaders, (loader) -> loader.loaded
@startsLoading = false
@render()
getRenderData: ->
ctx = super()
ctx.level = @level
description = @level.get('description')
ctx.description = if description then marked(description) else ''
ctx.link = "/play/level/#{@level.get('name')}"
ctx.teams = []
for team in @teams or []
ctx.teams.push({
id: team
name: _.string.titleize(team)
leaderboard: @leaderboards[team]
easyChallenger: @challengers[team].easyPlayer.models[0]
mediumChallenger: @challengers[team].mediumPlayer.models[0]
hardChallenger: @challengers[team].hardPlayer.models[0]
})
ctx
afterRender: ->
super()
@$el.find('#leaderboard-column .nav a:first').tab('show')
class LeaderboardData
constructor: (@level, @team, @session) ->
_.extend @, Backbone.Events
@topPlayers = new LeaderboardCollection(@level, {order:-1, scoreOffset: HIGHEST_SCORE, team: @team, limit: if @session then 10 else 20})
@topPlayers.fetch()
@topPlayers.once 'sync', @leaderboardPartLoaded, @
if @session
score = @session.get('score') or 25
@playersAbove = new LeaderboardCollection(@level, {order:1, scoreOffset: score, limit: 4, team: @team})
@playersAbove.fetch()
@playersAbove.once 'sync', @leaderboardPartLoaded, @
@playersBelow = new LeaderboardCollection(@level, {order:-1, scoreOffset: score, limit: 4, team: @team})
@playersBelow.fetch()
@playersBelow.once 'sync', @leaderboardPartLoaded, @
leaderboardPartLoaded: ->
if @session
if @topPlayers.loaded and @playersAbove.loaded and @playersBelow.loaded
@loaded = true
@trigger 'sync'
else
@loaded = true
@trigger 'sync'
class ChallengersData
constructor: (@level, @team, @session) ->
_.extend @, Backbone.Events
score = @session?.get('score') or 25
@easyPlayer = new LeaderboardCollection(@level, {order:1, scoreOffset: score - 5, limit: 1, team: @team})
@easyPlayer.fetch()
@easyPlayer.once 'sync', @challengerLoaded, @
@mediumPlayer = new LeaderboardCollection(@level, {order:1, scoreOffset: score, limit: 1, team: @team})
@mediumPlayer.fetch()
@mediumPlayer.once 'sync', @challengerLoaded, @
@hardPlayer = new LeaderboardCollection(@level, {order:-1, scoreOffset: score + 5, limit: 1, team: @team})
@hardPlayer.fetch()
@hardPlayer.once 'sync', @challengerLoaded, @
challengerLoaded: ->
if @easyPlayer.loaded and @mediumPlayer.loaded and @hardPlayer.loaded
@loaded = true
@trigger 'sync'

View file

@ -23,6 +23,8 @@ LevelHandler = class LevelHandler extends Handler
getByRelationship: (req, res, args...) ->
return @getSession(req, res, args[0]) if args[1] is 'session'
return @getLeaderboard(req, res, args[0]) if args[1] is 'leaderboard'
return @getAllSessions(req, res, args[0]) if args[1] is 'all_sessions'
return @getFeedback(req, res, args[0]) if args[1] is 'feedback'
return @sendNotFoundError(res)
@ -36,6 +38,9 @@ LevelHandler = class LevelHandler extends Handler
level: {original: level.original.toString(), majorVersion: level.version.major}
creator: req.user.id
}
sessionQuery.team = req.query.team if req.query.team
Session.findOne(sessionQuery).exec (err, doc) =>
return @sendDatabaseError(res, err) if err
if doc
@ -45,6 +50,7 @@ LevelHandler = class LevelHandler extends Handler
initVals = sessionQuery
initVals.state = {complete:false, scripts:{currentScript:null}} # will not save empty objects
initVals.permissions = [{target:req.user.id, access:'owner'}, {target:'public', access:'write'}]
initVals.team = req.query.team if req.query.team
session = new Session(initVals)
session.save (err) =>
return @sendDatabaseError(res, err) if err
@ -53,6 +59,29 @@ LevelHandler = class LevelHandler extends Handler
# associated with the handler, because the handler might return a different type
# of model, like in this case. Refactor to move that logic to the model instead.
getAllSessions: (req, res, id) ->
@getDocumentForIdOrSlug id, (err, level) =>
return @sendDatabaseError(res, err) if err
return @sendNotFoundError(res) unless level?
return @sendUnauthorizedError(res) unless @hasAccessToDocument(req, level)
sessionQuery = {
level: {original: level.original.toString(), majorVersion: level.version.major}
creator: req.user.id
}
Session.find(sessionQuery).exec (err, results) =>
return @sendDatabaseError(res, err) if err
res.send(results)
res.end()
getLeaderboard: (req, res, id) ->
# stub handler
# [original, version] = id.split('.')
# version = parseInt version
# console.log 'get leaderboard for', original, version, req.query
return res.send([])
getFeedback: (req, res, id) ->
@getDocumentForIdOrSlug id, (err, level) =>
return @sendDatabaseError(res, err) if err

View file

@ -25,6 +25,7 @@ _.extend LevelSessionSchema.properties,
creator: c.objectId(links: [{rel: 'extra', href: "/db/user/{($)}"}])
created: c.date( { title: 'Created', readOnly: true })
changed: c.date( { title: 'Changed', readOnly: true })
team: c.shortString()
level: LevelSessionLevelSchema
screenshot: { type: 'string' }
state: c.object {}, {