mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-01 11:27:14 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
7cc18e0278
16 changed files with 41 additions and 69 deletions
|
@ -98,7 +98,10 @@ module.exports = class World
|
||||||
continueLaterFn = =>
|
continueLaterFn = =>
|
||||||
@loadFrames(loadedCallback, errorCallback, loadProgressCallback, preloadedCallback, skipDeferredLoading, loadUntilFrame) unless @destroyed
|
@loadFrames(loadedCallback, errorCallback, loadProgressCallback, preloadedCallback, skipDeferredLoading, loadUntilFrame) unless @destroyed
|
||||||
if @realTime and not @countdownFinished
|
if @realTime and not @countdownFinished
|
||||||
@realTimeSpeedFactor ?= 1
|
if @levelID in ['the-first-kithmaze', 'the-second-kithmaze', 'the-final-kithmaze']
|
||||||
|
@realTimeSpeedFactor = 3
|
||||||
|
else
|
||||||
|
@realTimeSpeedFactor = 1
|
||||||
return setTimeout @finishCountdown(continueLaterFn), REAL_TIME_COUNTDOWN_DELAY
|
return setTimeout @finishCountdown(continueLaterFn), REAL_TIME_COUNTDOWN_DELAY
|
||||||
t1 = now()
|
t1 = now()
|
||||||
@t0 ?= t1
|
@t0 ?= t1
|
||||||
|
@ -193,8 +196,7 @@ module.exports = class World
|
||||||
@flagHistory.push flagEvent
|
@flagHistory.push flagEvent
|
||||||
|
|
||||||
loadFromLevel: (level, willSimulate=true) ->
|
loadFromLevel: (level, willSimulate=true) ->
|
||||||
if level.slug in ['the-first-kithmaze', 'the-second-kithmaze', 'the-final-kithmaze']
|
@levelID = level.slug
|
||||||
@realTimeSpeedFactor = 3
|
|
||||||
@levelComponents = level.levelComponents
|
@levelComponents = level.levelComponents
|
||||||
@thangTypes = level.thangTypes
|
@thangTypes = level.thangTypes
|
||||||
@loadSystemsFromLevel level
|
@loadSystemsFromLevel level
|
||||||
|
|
|
@ -23,8 +23,8 @@ LevelSessionSchema = c.object
|
||||||
title: 'Session'
|
title: 'Session'
|
||||||
description: 'A single session for a given level.'
|
description: 'A single session for a given level.'
|
||||||
default:
|
default:
|
||||||
codeLanguage: 'javascript'
|
codeLanguage: 'python'
|
||||||
submittedCodeLanguage: 'javascript'
|
submittedCodeLanguage: 'python'
|
||||||
playtime: 0
|
playtime: 0
|
||||||
|
|
||||||
_.extend LevelSessionSchema.properties,
|
_.extend LevelSessionSchema.properties,
|
||||||
|
|
|
@ -106,8 +106,8 @@ _.extend UserSchema.properties,
|
||||||
wizard: c.object {},
|
wizard: c.object {},
|
||||||
colorConfig: c.object {additionalProperties: c.colorConfig()}
|
colorConfig: c.object {additionalProperties: c.colorConfig()}
|
||||||
|
|
||||||
aceConfig: c.object { default: { language: 'javascript', keyBindings: 'default', invisibles: false, indentGuides: false, behaviors: false, liveCompletion: true }},
|
aceConfig: c.object { default: { language: 'python', keyBindings: 'default', invisibles: false, indentGuides: false, behaviors: false, liveCompletion: true }},
|
||||||
language: {type: 'string', 'enum': ['javascript', 'coffeescript', 'python', 'clojure', 'lua', 'io']}
|
language: {type: 'string', 'enum': ['python', 'javascript', 'coffeescript', 'clojure', 'lua', 'io']}
|
||||||
keyBindings: {type: 'string', 'enum': ['default', 'vim', 'emacs']}
|
keyBindings: {type: 'string', 'enum': ['default', 'vim', 'emacs']}
|
||||||
invisibles: {type: 'boolean' }
|
invisibles: {type: 'boolean' }
|
||||||
indentGuides: {type: 'boolean' }
|
indentGuides: {type: 'boolean' }
|
||||||
|
|
|
@ -171,7 +171,7 @@ me.FunctionArgumentSchema = me.object {
|
||||||
description: 'Examples by code language.',
|
description: 'Examples by code language.',
|
||||||
additionalProperties: me.shortString(description: 'Example value for the argument.')
|
additionalProperties: me.shortString(description: 'Example value for the argument.')
|
||||||
format: 'code-languages-object'
|
format: 'code-languages-object'
|
||||||
default: {javascript: ''}
|
default: {javascript: '', python: ''}
|
||||||
}
|
}
|
||||||
me.shortString(title: 'Example', description: 'Example value for the argument.')
|
me.shortString(title: 'Example', description: 'Example value for the argument.')
|
||||||
]
|
]
|
||||||
|
@ -183,7 +183,7 @@ me.FunctionArgumentSchema = me.object {
|
||||||
description: 'Example argument descriptions by code language.',
|
description: 'Example argument descriptions by code language.',
|
||||||
additionalProperties: {type: 'string', description: 'Description of the argument.', maxLength: 1000}
|
additionalProperties: {type: 'string', description: 'Description of the argument.', maxLength: 1000}
|
||||||
format: 'code-languages-object'
|
format: 'code-languages-object'
|
||||||
default: {javascript: ''}
|
default: {javascript: '', python: ''}
|
||||||
}
|
}
|
||||||
{title: 'Description', type: 'string', description: 'Description of the argument.', maxLength: 1000}
|
{title: 'Description', type: 'string', description: 'Description of the argument.', maxLength: 1000}
|
||||||
]
|
]
|
||||||
|
|
|
@ -258,7 +258,7 @@ class JavaScriptTreema extends CodeTreema
|
||||||
|
|
||||||
class InternationalizationNode extends TreemaNode.nodeMap.object
|
class InternationalizationNode extends TreemaNode.nodeMap.object
|
||||||
findLanguageName: (languageCode) ->
|
findLanguageName: (languageCode) ->
|
||||||
# to get around mongoose emtpy object bug, there's a prop in the object which needs to be ignored
|
# to get around mongoose empty object bug, there's a prop in the object which needs to be ignored
|
||||||
return '' if languageCode is '-'
|
return '' if languageCode is '-'
|
||||||
locale[languageCode]?.nativeDescription or "#{languageCode} Not Found"
|
locale[languageCode]?.nativeDescription or "#{languageCode} Not Found"
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ module.exports = class HomeView extends RootView
|
||||||
console.warn 'no more jquery browser version...'
|
console.warn 'no more jquery browser version...'
|
||||||
c.isEnglish = (me.get('preferredLanguage') or 'en').startsWith 'en'
|
c.isEnglish = (me.get('preferredLanguage') or 'en').startsWith 'en'
|
||||||
c.languageName = me.get('preferredLanguage')
|
c.languageName = me.get('preferredLanguage')
|
||||||
c.codeLanguage = (me.get('aceConfig') ? {}).language or 'javascript'
|
c.codeLanguage = (me.get('aceConfig') ? {}).language or 'python'
|
||||||
c.codeLanguageCountMap = @codeLanguageCountMap
|
c.codeLanguageCountMap = @codeLanguageCountMap
|
||||||
c
|
c
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ module.exports = class HomeView extends RootView
|
||||||
href = href.join('/')
|
href = href.join('/')
|
||||||
playLink.attr('href', href)
|
playLink.attr('href', href)
|
||||||
|
|
||||||
codeLanguage = (me.get('aceConfig') ? {}).language or 'javascript'
|
codeLanguage = (me.get('aceConfig') ? {}).language or 'python'
|
||||||
@$el.find(".code-language[data-code-language=#{codeLanguage}]").addClass 'selected-language'
|
@$el.find(".code-language[data-code-language=#{codeLanguage}]").addClass 'selected-language'
|
||||||
@updateLanguageLogos codeLanguage
|
@updateLanguageLogos codeLanguage
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ module.exports = class HomeView extends RootView
|
||||||
@$el.find('.code-language').removeClass 'selected-language'
|
@$el.find('.code-language').removeClass 'selected-language'
|
||||||
target.addClass 'selected-language'
|
target.addClass 'selected-language'
|
||||||
aceConfig = me.get('aceConfig') ? {}
|
aceConfig = me.get('aceConfig') ? {}
|
||||||
return if (aceConfig.language or 'javascript') is codeLanguage
|
return if (aceConfig.language or 'python') is codeLanguage
|
||||||
aceConfig.language = codeLanguage
|
aceConfig.language = codeLanguage
|
||||||
me.set 'aceConfig', aceConfig
|
me.set 'aceConfig', aceConfig
|
||||||
me.save() # me.patch() doesn't work if aceConfig previously existed and we switched just once
|
me.save() # me.patch() doesn't work if aceConfig previously existed and we switched just once
|
||||||
|
|
|
@ -34,7 +34,7 @@ module.exports = class LevelSessionCodeView extends CocoView
|
||||||
editor.setReadOnly true
|
editor.setReadOnly true
|
||||||
editors.push editor
|
editors.push editor
|
||||||
aceSession = editor.getSession()
|
aceSession = editor.getSession()
|
||||||
aceSession.setMode 'ace/mode/javascript'
|
aceSession.setMode 'ace/mode/javascript' # TODO: they're not all JS
|
||||||
@editors = editors
|
@editors = editors
|
||||||
|
|
||||||
organizeCode: ->
|
organizeCode: ->
|
||||||
|
|
|
@ -35,7 +35,7 @@ module.exports = class ComponentsDocumentationView extends CocoView
|
||||||
c = super()
|
c = super()
|
||||||
c.components = @componentDocs.models
|
c.components = @componentDocs.models
|
||||||
c.marked = marked
|
c.marked = marked
|
||||||
c.codeLanguage = me.get('aceConfig')?.language ? 'javascript'
|
c.codeLanguage = me.get('aceConfig')?.language ? 'python'
|
||||||
c
|
c
|
||||||
|
|
||||||
onToggleAllCode: (e) ->
|
onToggleAllCode: (e) ->
|
||||||
|
|
|
@ -35,7 +35,7 @@ module.exports = class SystemsDocumentationView extends CocoView
|
||||||
c = super()
|
c = super()
|
||||||
c.systems = @systemDocs.models
|
c.systems = @systemDocs.models
|
||||||
c.marked = marked
|
c.marked = marked
|
||||||
c.codeLanguage = me.get('aceConfig')?.language ? 'javascript'
|
c.codeLanguage = me.get('aceConfig')?.language ? 'python'
|
||||||
c
|
c
|
||||||
|
|
||||||
onToggleAllCode: (e) ->
|
onToggleAllCode: (e) ->
|
||||||
|
|
|
@ -311,7 +311,7 @@ module.exports = class InventoryView extends CocoView
|
||||||
'the-final-kithmaze': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
'the-final-kithmaze': {feet: 'simple-boots', 'right-hand': 'longsword', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
||||||
'kithgard-gates': {feet: 'simple-boots', 'right-hand': 'builders-hammer', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
'kithgard-gates': {feet: 'simple-boots', 'right-hand': 'builders-hammer', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
||||||
'defence-of-plainswood': {feet: 'simple-boots', 'right-hand': 'builders-hammer', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
'defence-of-plainswood': {feet: 'simple-boots', 'right-hand': 'builders-hammer', torso: 'leather-tunic', 'programming-book': 'programmaticon-i', eyes: 'crude-glasses'}
|
||||||
necessaryGear = gearByLevel[@options.levelID]
|
return unless necessaryGear = gearByLevel[@options.levelID]
|
||||||
for slot, item of necessaryGear ? {}
|
for slot, item of necessaryGear ? {}
|
||||||
@equipment[slot] ?= gear[item]
|
@equipment[slot] ?= gear[item]
|
||||||
|
|
||||||
|
|
|
@ -617,6 +617,7 @@ hero = [
|
||||||
description: 'Escape the Kithgard dungeons and don\'t let the guardians get you.'
|
description: 'Escape the Kithgard dungeons and don\'t let the guardians get you.'
|
||||||
x: 47.38
|
x: 47.38
|
||||||
y: 70.55
|
y: 70.55
|
||||||
|
disabled: true
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
name: 'Defence of Plainswood'
|
name: 'Defence of Plainswood'
|
||||||
|
@ -626,6 +627,7 @@ hero = [
|
||||||
description: 'Protect the peasants from the pursuing ogres.'
|
description: 'Protect the peasants from the pursuing ogres.'
|
||||||
x: 52.66
|
x: 52.66
|
||||||
y: 69.66
|
y: 69.66
|
||||||
|
disabled: true
|
||||||
}
|
}
|
||||||
#{
|
#{
|
||||||
# name: ''
|
# name: ''
|
||||||
|
|
|
@ -89,9 +89,9 @@ module.exports = class LadderPlayModal extends ModalView
|
||||||
ctx.otherTeamID = @otherTeam
|
ctx.otherTeamID = @otherTeam
|
||||||
ctx.tutorialLevelExists = @tutorialLevelExists
|
ctx.tutorialLevelExists = @tutorialLevelExists
|
||||||
ctx.languages = [
|
ctx.languages = [
|
||||||
|
{id: 'python', name: 'Python'}
|
||||||
{id: 'javascript', name: 'JavaScript'}
|
{id: 'javascript', name: 'JavaScript'}
|
||||||
{id: 'coffeescript', name: 'CoffeeScript'}
|
{id: 'coffeescript', name: 'CoffeeScript'}
|
||||||
{id: 'python', name: 'Python (Experimental)'}
|
|
||||||
{id: 'clojure', name: 'Clojure (Experimental)'}
|
{id: 'clojure', name: 'Clojure (Experimental)'}
|
||||||
{id: 'lua', name: 'Lua (Experimental)'}
|
{id: 'lua', name: 'Lua (Experimental)'}
|
||||||
{id: 'io', name: 'Io (Experimental)'}
|
{id: 'io', name: 'Io (Experimental)'}
|
||||||
|
|
|
@ -8,7 +8,7 @@ module.exports = class EditorConfigModal extends ModalView
|
||||||
aceConfig: {}
|
aceConfig: {}
|
||||||
|
|
||||||
defaultConfig:
|
defaultConfig:
|
||||||
language: 'javascript'
|
language: 'python'
|
||||||
keyBindings: 'default'
|
keyBindings: 'default'
|
||||||
invisibles: false
|
invisibles: false
|
||||||
indentGuides: false
|
indentGuides: false
|
||||||
|
@ -32,9 +32,9 @@ module.exports = class EditorConfigModal extends ModalView
|
||||||
@aceConfig = _.defaults @aceConfig, @defaultConfig
|
@aceConfig = _.defaults @aceConfig, @defaultConfig
|
||||||
c = super()
|
c = super()
|
||||||
c.languages = [
|
c.languages = [
|
||||||
|
{id: 'python', name: 'Python'}
|
||||||
{id: 'javascript', name: 'JavaScript'}
|
{id: 'javascript', name: 'JavaScript'}
|
||||||
{id: 'coffeescript', name: 'CoffeeScript'}
|
{id: 'coffeescript', name: 'CoffeeScript'}
|
||||||
{id: 'python', name: 'Python (Experimental)'}
|
|
||||||
{id: 'clojure', name: 'Clojure (Experimental)'}
|
{id: 'clojure', name: 'Clojure (Experimental)'}
|
||||||
{id: 'lua', name: 'Lua (Experimental)'}
|
{id: 'lua', name: 'Lua (Experimental)'}
|
||||||
{id: 'io', name: 'Io (Experimental)'}
|
{id: 'io', name: 'Io (Experimental)'}
|
||||||
|
|
|
@ -36,8 +36,6 @@ ThangListView = require './ThangListView'
|
||||||
SpellPaletteView = require './SpellPaletteView'
|
SpellPaletteView = require './SpellPaletteView'
|
||||||
CastButtonView = require './CastButtonView'
|
CastButtonView = require './CastButtonView'
|
||||||
|
|
||||||
window.SHIM_WORKER_PATH = '/javascripts/workers/catiline_worker_shim.js'
|
|
||||||
|
|
||||||
module.exports = class TomeView extends CocoView
|
module.exports = class TomeView extends CocoView
|
||||||
id: 'tome-view'
|
id: 'tome-view'
|
||||||
template: template
|
template: template
|
||||||
|
@ -108,7 +106,7 @@ module.exports = class TomeView extends CocoView
|
||||||
return teamSpellMap
|
return teamSpellMap
|
||||||
|
|
||||||
createSpells: (programmableThangs, world) ->
|
createSpells: (programmableThangs, world) ->
|
||||||
language = @options.session.get('codeLanguage') ? me.get('aceConfig')?.language ? 'javascript'
|
language = @options.session.get('codeLanguage') ? me.get('aceConfig')?.language ? 'python'
|
||||||
pathPrefixComponents = ['play', 'level', @options.levelID, @options.session.id, 'code']
|
pathPrefixComponents = ['play', 'level', @options.levelID, @options.session.id, 'code']
|
||||||
@spells ?= {}
|
@spells ?= {}
|
||||||
@thangSpells ?= {}
|
@thangSpells ?= {}
|
||||||
|
|
|
@ -93,7 +93,7 @@ LevelHandler = class LevelHandler extends Handler
|
||||||
access: 'write'
|
access: 'write'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
initVals.codeLanguage = req.user.get('aceConfig')?.language ? 'javascript'
|
initVals.codeLanguage = req.user.get('aceConfig')?.language ? 'python'
|
||||||
session = new Session(initVals)
|
session = new Session(initVals)
|
||||||
|
|
||||||
session.save (err) =>
|
session.save (err) =>
|
||||||
|
|
|
@ -29,43 +29,13 @@ describe 'InventoryView', ->
|
||||||
expect(inventoryView.getSelectedSlot().data('slot')).toBeUndefined()
|
expect(inventoryView.getSelectedSlot().data('slot')).toBeUndefined()
|
||||||
|
|
||||||
it 'selects an available item when you click it', ->
|
it 'selects an available item when you click it', ->
|
||||||
inventoryView.getAvailableItemContainer('boots-of-leaping-id').click()
|
inventoryView.getAvailableItemContainer('boots-of-leaping').click()
|
||||||
expect(inventoryView.getSelectedAvailableItemContainer().data('item-id')).toBe('boots-of-leaping-id')
|
expect(inventoryView.getSelectedAvailableItemContainer().data('item-id')).toBe('boots-of-leaping')
|
||||||
|
|
||||||
it 'equips an available item when you double click it', ->
|
it 'equips an available item when you double click it', ->
|
||||||
inventoryView.getAvailableItemContainer('crossbow-id').click().dblclick()
|
inventoryView.getAvailableItemContainer('crossbow').click().dblclick()
|
||||||
expect(inventoryView.getCurrentEquipmentConfig()['right-hand']).toBeTruthy()
|
expect(inventoryView.getCurrentEquipmentConfig()['right-hand']).toBeTruthy()
|
||||||
|
|
||||||
it 'unequips an itm when you double click it', ->
|
it 'unequips an item when you double click it', ->
|
||||||
inventoryView.getSlot('eyes').find('.item-view').click().dblclick()
|
inventoryView.getSlot('eyes').find('.item-view').click().dblclick()
|
||||||
expect(inventoryView.getCurrentEquipmentConfig().eyes).toBeUndefined()
|
expect(inventoryView.getCurrentEquipmentConfig().eyes).toBeUndefined()
|
||||||
|
|
||||||
describe 'swap button', ->
|
|
||||||
it 'does nothing if nothing is selected', ->
|
|
||||||
inventoryView.$el.find('#swap-button').click()
|
|
||||||
expect(inventoryView.getSelectedSlot()[0]).toBeFalsy()
|
|
||||||
expect(inventoryView.getSelectedAvailableItemContainer()[0]).toBeFalsy()
|
|
||||||
|
|
||||||
it 'unequips and selects the unequipped item if just an equipped slot is chosen', ->
|
|
||||||
expect(inventoryView.getCurrentEquipmentConfig().eyes).toBeTruthy()
|
|
||||||
slot = inventoryView.getSlot('eyes')
|
|
||||||
inventoryView.selectSlot(slot)
|
|
||||||
inventoryView.$el.find('#swap-button').click()
|
|
||||||
expect(inventoryView.getCurrentEquipmentConfig().eyes).toBeUndefined()
|
|
||||||
expect(inventoryView.getSelectedAvailableItemContainer().data('item-id')).toBe('crude-glasses-id')
|
|
||||||
|
|
||||||
it 'equips the selected item if just an available item is selected', ->
|
|
||||||
expect(inventoryView.getCurrentEquipmentConfig()['right-hand']).toBeUndefined()
|
|
||||||
inventoryView.getAvailableItemContainer('crossbow-id').click()
|
|
||||||
inventoryView.$el.find('#swap-button').click()
|
|
||||||
expect(inventoryView.getCurrentEquipmentConfig()['right-hand']).toBeTruthy()
|
|
||||||
expect(inventoryView.getSelectedAvailableItemContainer().data('item-id')).toBeUndefined()
|
|
||||||
expect(inventoryView.getSelectedSlot().data('slot')).toBe('right-hand')
|
|
||||||
|
|
||||||
it 'swaps items if both a slot and item are selected, and keeps them selected', ->
|
|
||||||
inventoryView.getAvailableItemContainer('boots-of-leaping-id').click()
|
|
||||||
inventoryView.getSlot('feet').click()
|
|
||||||
inventoryView.$el.find('#swap-button').click()
|
|
||||||
expect(inventoryView.getCurrentEquipmentConfig()['feet']).toBe('boots-of-leaping')
|
|
||||||
expect(inventoryView.getSelectedAvailableItemContainer().data('item-id')).toBe('boots-id')
|
|
||||||
expect(inventoryView.getSelectedSlot().data('slot')).toBe('feet')
|
|
Loading…
Reference in a new issue