mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-24 16:17:57 -05:00
260 lines
8.4 KiB
CoffeeScript
260 lines
8.4 KiB
CoffeeScript
View = require 'views/kinds/RootView'
|
|
template = require 'templates/home'
|
|
WizardSprite = require 'lib/surface/WizardSprite'
|
|
ThangType = require 'models/ThangType'
|
|
LevelLoader = require 'lib/LevelLoader'
|
|
God = require 'lib/God'
|
|
|
|
GoalManager = require 'lib/world/GoalManager'
|
|
|
|
module.exports = class HomeView extends View
|
|
id: 'home-view'
|
|
template: template
|
|
|
|
events:
|
|
'mouseover #beginner-campaign': 'onMouseOverButton'
|
|
'mouseout #beginner-campaign': 'onMouseOutButton'
|
|
'click #simulate-button': 'onSimulateButtonClick'
|
|
|
|
getRenderData: ->
|
|
c = super()
|
|
if $.browser
|
|
majorVersion = parseInt($.browser.version.split('.')[0])
|
|
c.isOldBrowser = true if $.browser.mozilla && majorVersion < 21
|
|
c.isOldBrowser = true if $.browser.chrome && majorVersion < 17
|
|
c.isOldBrowser = true if $.browser.safari && majorVersion < 536
|
|
else
|
|
console.warn 'no more jquery browser version...'
|
|
c
|
|
|
|
afterRender: ->
|
|
super()
|
|
@$el.find('.modal').on 'shown.bs.modal', ->
|
|
$('input:visible:first', @).focus()
|
|
|
|
wizOriginal = "52a00d55cf1818f2be00000b"
|
|
url = "/db/thang_type/#{wizOriginal}/version"
|
|
@wizardType = new ThangType()
|
|
@wizardType.url = -> url
|
|
@wizardType.fetch()
|
|
@wizardType.once 'sync', @initCanvas
|
|
|
|
# Try to find latest level and set "Play" link to go to that level
|
|
if localStorage?
|
|
lastLevel = localStorage["lastLevel"]
|
|
if lastLevel? and lastLevel isnt ""
|
|
playLink = @$el.find("#beginner-campaign")
|
|
if playLink?
|
|
href = playLink.attr("href").split("/")
|
|
href[href.length-1] = lastLevel if href.length isnt 0
|
|
href = href.join("/")
|
|
playLink.attr("href", href)
|
|
else
|
|
console.log("TODO: Insert here code to get latest level played from the database. If this can't be found, we just let the user play the first level.")
|
|
|
|
initCanvas: =>
|
|
@stage = new createjs.Stage($('#beginner-campaign canvas', @$el)[0])
|
|
@createWizard()
|
|
|
|
turnOnStageUpdates: ->
|
|
clearInterval @turnOff
|
|
@interval = setInterval(@updateStage, 40) unless @interval
|
|
|
|
turnOffStageUpdates: ->
|
|
turnOffFunc = =>
|
|
clearInterval @interval
|
|
clearInterval @turnOff
|
|
@interval = null
|
|
@turnOff = null
|
|
@turnOff = setInterval turnOffFunc, 2000
|
|
|
|
createWizard: (scale=1.0) ->
|
|
spriteOptions = thangID: "Beginner Wizard", resolutionFactor: scale
|
|
@wizardSprite = new WizardSprite @wizardType, spriteOptions
|
|
@wizardSprite.update()
|
|
wizardDisplayObject = @wizardSprite.displayObject
|
|
wizardDisplayObject.x = 120
|
|
wizardDisplayObject.y = 35
|
|
wizardDisplayObject.scaleX = wizardDisplayObject.scaleY = scale
|
|
wizardDisplayObject.scaleX *= -1
|
|
@stage.addChild wizardDisplayObject
|
|
@stage.update()
|
|
|
|
onMouseOverButton: ->
|
|
@turnOnStageUpdates()
|
|
@wizardSprite?.queueAction 'cast'
|
|
|
|
onMouseOutButton: ->
|
|
@turnOffStageUpdates()
|
|
@wizardSprite?.queueAction 'idle'
|
|
|
|
updateStage: =>
|
|
@stage?.update()
|
|
|
|
willDisappear: ->
|
|
super()
|
|
clearInterval(@interval) if @interval
|
|
@interval = null
|
|
|
|
didReappear: ->
|
|
super()
|
|
@turnOnStageUpdates()
|
|
|
|
destroy: ->
|
|
@wizardSprite?.destroy()
|
|
super()
|
|
|
|
onSimulateButtonClick: (e) =>
|
|
@alreadyPostedResults = false
|
|
console.log "Simulating world!"
|
|
$.ajax
|
|
url: "/queue/scoring"
|
|
type: "GET"
|
|
error: (data) =>
|
|
console.log "There are no games to score. Error: #{JSON.stringify data}"
|
|
console.log "Retrying in ten seconds..."
|
|
_.delay @onSimulateButtonClick, 10000
|
|
success: (data) =>
|
|
console.log data
|
|
levelName = data.sessions[0].levelID
|
|
#TODO: Refactor. So much refactor.
|
|
@taskData = data
|
|
@teamSessionMap = @generateTeamSessionMap data
|
|
world = {}
|
|
god = new God()
|
|
levelLoader = new LevelLoader(levelName, @supermodel, data.sessions[0].sessionID)
|
|
levelLoader.once 'loaded-all', =>
|
|
world = levelLoader.world
|
|
level = levelLoader.level
|
|
levelLoader.destroy()
|
|
god.level = level.serialize @supermodel
|
|
god.worldClassMap = world.classMap
|
|
god.goalManager = new GoalManager(world)
|
|
#move goals in here
|
|
goalsToAdd = god.goalManager.world.scripts[0].noteChain[0].goals.add
|
|
god.goalManager.goals = goalsToAdd
|
|
god.goalManager.goalStates =
|
|
"destroy-humans":
|
|
keyFrame: 0
|
|
killed:
|
|
"Human Base": false
|
|
status: "incomplete"
|
|
"destroy-ogres":
|
|
keyFrame:0
|
|
killed:
|
|
"Ogre Base": false
|
|
status: "incomplete"
|
|
god.spells = @filterProgrammableComponents level.attributes.thangs, @generateSpellToSourceMap data.sessions
|
|
god.createWorld()
|
|
@god = god
|
|
Backbone.Mediator.subscribeOnce 'god:new-world-created', @onWorldCreated, @
|
|
|
|
onWorldCreated: (data) ->
|
|
return if @alreadyPostedResults
|
|
taskResults = @translateGoalStatesIntoTaskResults data.goalStates
|
|
@god?.destroy()
|
|
|
|
$.ajax
|
|
url: "/queue/scoring"
|
|
data: taskResults
|
|
type: 'PUT'
|
|
success: (result) =>
|
|
console.log "TASK REGISTRATION RESULT:#{JSON.stringify result}"
|
|
error: (error) =>
|
|
console.log "TASK REGISTRATION ERROR:#{JSON.stringify error}"
|
|
complete: (result) =>
|
|
@alreadyPostedResults = true
|
|
@onSimulateButtonClick()
|
|
|
|
|
|
translateGoalStatesIntoTaskResults: (goalStates) =>
|
|
taskResults = {}
|
|
taskResults =
|
|
taskID: @taskData.taskID
|
|
receiptHandle: @taskData.receiptHandle
|
|
calculationTime: 500
|
|
sessions: []
|
|
|
|
for session in @taskData.sessions
|
|
sessionResult =
|
|
sessionID: session.sessionID
|
|
sessionChangedTime: session.sessionChangedTime
|
|
metrics:
|
|
rank: @calculateSessionRank session.sessionID, goalStates
|
|
taskResults.sessions.push sessionResult
|
|
taskResults
|
|
|
|
calculateSessionRank: (sessionID, goalStates) ->
|
|
humansDestroyed = goalStates["destroy-humans"].status is "success"
|
|
ogresDestroyed = goalStates["destroy-ogres"].status is "success"
|
|
console.log "Humans destroyed:#{humansDestroyed}"
|
|
console.log "Ogres destroyed:#{ogresDestroyed}"
|
|
console.log "Team Session Map: #{JSON.stringify @teamSessionMap}"
|
|
if humansDestroyed is ogresDestroyed
|
|
return 0
|
|
else if humansDestroyed and @teamSessionMap["ogres"] is sessionID
|
|
return 0
|
|
else if humansDestroyed and @teamSessionMap["ogres"] isnt sessionID
|
|
return 1
|
|
else if ogresDestroyed and @teamSessionMap["humans"] is sessionID
|
|
return 0
|
|
else
|
|
return 1
|
|
|
|
|
|
generateTeamSessionMap: (task) ->
|
|
teamSessionMap = {}
|
|
for session in @taskData.sessions
|
|
teamSessionMap[session.team] = session.sessionID
|
|
teamSessionMap
|
|
|
|
|
|
|
|
filterProgrammableComponents: (thangs, spellToSourceMap) =>
|
|
spells = {}
|
|
for thang in thangs
|
|
isTemplate = false
|
|
for component in thang.components
|
|
if component.config? and _.has component.config,'programmableMethods'
|
|
for methodName, method of component.config.programmableMethods
|
|
if typeof method is 'string'
|
|
isTemplate = true
|
|
break
|
|
|
|
pathComponents = [thang.id,methodName]
|
|
pathComponents[0] = _.string.slugify pathComponents[0]
|
|
spellKey = pathComponents.join '/'
|
|
spells[spellKey] ?= {}
|
|
spells[spellKey].thangs ?= {}
|
|
spells[spellKey].name = methodName
|
|
thangID = _.string.slugify thang.id
|
|
spells[spellKey].thangs[thang.id] ?= {}
|
|
spells[spellKey].thangs[thang.id].aether = @createAether methodName, method
|
|
if spellToSourceMap[thangID]? then source = spellToSourceMap[thangID][methodName] else source = ""
|
|
spells[spellKey].thangs[thang.id].aether.transpile source
|
|
if isTemplate
|
|
break
|
|
|
|
spells
|
|
|
|
createAether : (methodName, method) ->
|
|
aetherOptions =
|
|
functionName: methodName
|
|
protectAPI: false
|
|
includeFlow: false
|
|
return new Aether aetherOptions
|
|
|
|
generateSpellToSourceMap: (sessions) ->
|
|
spellKeyToSourceMap = {}
|
|
spellSources = {}
|
|
for session in sessions
|
|
teamSpells = session.teamSpells[session.team]
|
|
_.merge spellSources, _.pick(session.code, teamSpells)
|
|
|
|
#merge common ones, this overwrites until the last session
|
|
commonSpells = session.teamSpells["common"]
|
|
if commonSpells?
|
|
_.merge spellSources, _.pick(session.code, commonSpells)
|
|
|
|
spellSources
|
|
|