mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-12-24 14:32:24 -05:00
be78f4049c
Was only happening when HeroPlaceholder had HasPet component. Presumably because the collection was loaded by HasPet, but the thang node for the inventory node needed to populate its autocomplete array.
296 lines
11 KiB
CoffeeScript
296 lines
11 KiB
CoffeeScript
WorldSelectModal = require './modals/WorldSelectModal'
|
|
ThangType = require '/models/ThangType'
|
|
LevelComponent = require 'models/LevelComponent'
|
|
CocoCollection = require 'collections/CocoCollection'
|
|
require 'vendor/treema'
|
|
|
|
makeButton = -> $('<a class="btn btn-primary btn-xs treema-map-button"><span class="glyphicon glyphicon-screenshot"></span></a>')
|
|
shorten = (f) -> parseFloat(f.toFixed(1))
|
|
WIDTH = 924
|
|
|
|
module.exports.WorldPointNode = class WorldPointNode extends TreemaNode.nodeMap.point2d
|
|
constructor: (args...) ->
|
|
super(args...)
|
|
console.error 'Point Treema node needs a World included in the settings.' unless @settings.world?
|
|
console.error 'Point Treema node needs a RootView included in the settings.' unless @settings.view?
|
|
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('.treema-shortened').prepend(makeButton())
|
|
|
|
buildValueForEditing: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('.treema-shortened').prepend(makeButton())
|
|
|
|
onClick: (e) ->
|
|
btn = $(e.target).closest('.treema-map-button')
|
|
if btn.length then @openMap() else super(arguments...)
|
|
|
|
openMap: ->
|
|
modal = new WorldSelectModal(world: @settings.world, dataType: 'point', default: @getData(), supermodel: @settings.supermodel)
|
|
modal.callback = @callback
|
|
@settings.view.openModalView modal
|
|
|
|
callback: (e) =>
|
|
return unless e?.point?
|
|
@data.x = shorten(e.point.x)
|
|
@data.y = shorten(e.point.y)
|
|
@refreshDisplay()
|
|
|
|
class WorldRegionNode extends TreemaNode.nodeMap.object
|
|
# this class is not yet used, later will be used to configure the Physical component
|
|
|
|
constructor: (args...) ->
|
|
super(args...)
|
|
console.error 'Region Treema node needs a World included in the settings.' unless @settings.world?
|
|
console.error 'Region Treema node needs a RootView included in the settings.' unless @settings.view?
|
|
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('.treema-shortened').prepend(makeButton())
|
|
|
|
buildValueForEditing: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('.treema-shortened').prepend(makeButton())
|
|
|
|
onClick: (e) ->
|
|
btn = $(e.target).closest('.treema-map-button')
|
|
if btn.length then @openMap() else super(arguments...)
|
|
|
|
openMap: ->
|
|
modal = new WorldSelectModal(world: @settings.world, dataType: 'region', default: @createWorldBounds(), supermodel: @settings.supermodel)
|
|
modal.callback = @callback
|
|
@settings.view.openModalView modal
|
|
|
|
callback: (e) =>
|
|
x = Math.min e.points[0].x, e.points[1].x
|
|
y = Math.min e.points[0].y, e.points[1].y
|
|
@data.pos = {x: x, y: y, z: 0}
|
|
@data.width = Math.abs e.points[0].x - e.points[1].x
|
|
@data.height = Math.min e.points[0].y - e.points[1].y
|
|
@refreshDisplay()
|
|
|
|
createWorldBounds: ->
|
|
# not yet written
|
|
|
|
module.exports.WorldViewportNode = class WorldViewportNode extends TreemaNode.nodeMap.object
|
|
# selecting ratio'd dimensions in the world, ie the camera in level scripts
|
|
constructor: (args...) ->
|
|
super(args...)
|
|
console.error 'Viewport Treema node needs a World included in the settings.' unless @settings.world?
|
|
console.error 'Viewport Treema node needs a RootView included in the settings.' unless @settings.view?
|
|
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('.treema-shortened').prepend(makeButton())
|
|
|
|
buildValueForEditing: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('.treema-shortened').prepend(makeButton())
|
|
|
|
onClick: (e) ->
|
|
btn = $(e.target).closest('.treema-map-button')
|
|
if btn.length then @openMap() else super(arguments...)
|
|
|
|
openMap: ->
|
|
# can't really get the bounds from this data, so will have to hack this solution
|
|
options = world: @settings.world, dataType: 'ratio-region'
|
|
data = @getData()
|
|
options.defaultFromZoom = data if data?.target?.x?
|
|
options.supermodel = @settings.supermodel
|
|
modal = new WorldSelectModal(options)
|
|
modal.callback = @callback
|
|
@settings.view.openModalView modal
|
|
|
|
callback: (e) =>
|
|
return unless e
|
|
target = {
|
|
x: shorten((e.points[0].x + e.points[1].x) / 2)
|
|
y: shorten((e.points[0].y + e.points[1].y) / 2)
|
|
}
|
|
@set('target', target)
|
|
bounds = e.camera.normalizeBounds(e.points)
|
|
@set('zoom', shorten(WIDTH / bounds.width))
|
|
@refreshDisplay()
|
|
|
|
module.exports.WorldBoundsNode = class WorldBoundsNode extends TreemaNode.nodeMap.array
|
|
# selecting camera boundaries for a world
|
|
dataType: 'region'
|
|
|
|
constructor: (args...) ->
|
|
super(args...)
|
|
console.error 'Bounds Treema node needs a World included in the settings.' unless @settings.world?
|
|
console.error 'Bounds Treema node needs a RootView included in the settings.' unless @settings.view?
|
|
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('.treema-shortened').prepend(makeButton())
|
|
|
|
buildValueForEditing: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('.treema-shortened').prepend(makeButton())
|
|
|
|
onClick: (e) ->
|
|
btn = $(e.target).closest('.treema-map-button')
|
|
if btn.length then @openMap() else super(arguments...)
|
|
|
|
openMap: ->
|
|
bounds = @getData() or [{x: 0, y: 0}, {x: 100, y: 80}]
|
|
modal = new WorldSelectModal(world: @settings.world, dataType: 'region', default: bounds, supermodel: @settings.supermodel)
|
|
modal.callback = @callback
|
|
@settings.view.openModalView modal
|
|
|
|
callback: (e) =>
|
|
return unless e
|
|
@set '/0', {x: shorten(e.points[0].x), y: shorten(e.points[0].y)}
|
|
@set '/1', {x: shorten(e.points[1].x), y: shorten(e.points[1].y)}
|
|
|
|
module.exports.ThangNode = class ThangNode extends TreemaNode.nodeMap.string
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('input').autocomplete(source: @settings.thangIDs, minLength: 0, delay: 0, autoFocus: true)
|
|
valEl
|
|
|
|
module.exports.TeamNode = class TeamNode extends TreemaNode.nodeMap.string
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('input').autocomplete(source: @settings.teams, minLength: 0, delay: 0, autoFocus: true)
|
|
valEl
|
|
|
|
module.exports.SuperteamNode = class SuperteamNode extends TreemaNode.nodeMap.string
|
|
buildValueForEditing: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.find('input').autocomplete(source: @settings.superteams, minLength: 0, delay: 0, autoFocus: true)
|
|
valEl
|
|
|
|
module.exports.RadiansNode = class RadiansNode extends TreemaNode.nodeMap.number
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
deg = data / Math.PI * 180
|
|
valEl.text valEl.text() + "rad (#{deg.toFixed(0)}˚)"
|
|
|
|
module.exports.MetersNode = class MetersNode extends TreemaNode.nodeMap.number
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.text valEl.text() + 'm'
|
|
|
|
module.exports.KilogramsNode = class KilogramsNode extends TreemaNode.nodeMap.number
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.text valEl.text() + 'kg'
|
|
|
|
module.exports.SecondsNode = class SecondsNode extends TreemaNode.nodeMap.number
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.text valEl.text() + 's'
|
|
|
|
module.exports.MillisecondsNode = class MillisecondsNode extends TreemaNode.nodeMap.number
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.text valEl.text() + 'ms'
|
|
|
|
module.exports.SpeedNode = class SpeedNode extends TreemaNode.nodeMap.number
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.text valEl.text() + 'm/s'
|
|
|
|
module.exports.AccelerationNode = class AccelerationNode extends TreemaNode.nodeMap.number
|
|
buildValueForDisplay: (valEl, data) ->
|
|
super(valEl, data)
|
|
valEl.text valEl.text() + 'm/s^2'
|
|
|
|
module.exports.ThangTypeNode = class ThangTypeNode extends TreemaNode.nodeMap.string
|
|
valueClass: 'treema-thang-type'
|
|
@thangTypes: null
|
|
@thangTypesCollection: null
|
|
|
|
constructor: (args...) ->
|
|
super args...
|
|
data = @getData()
|
|
@thangType = _.find @settings.supermodel.getModels(ThangType), (m) => m.get('original') is data if data
|
|
|
|
buildValueForDisplay: (valEl) ->
|
|
@buildValueForDisplaySimply(valEl, @thangType?.get('name') or 'None')
|
|
|
|
buildValueForEditing: (valEl, data) ->
|
|
super(valEl, data)
|
|
thangTypeNames = (m.get('name') for m in @settings.supermodel.getModels ThangType)
|
|
input = valEl.find('input').autocomplete(source: thangTypeNames, minLength: 0, delay: 0, autoFocus: true)
|
|
input.val(@thangType?.get('name') or 'None')
|
|
valEl
|
|
|
|
saveChanges: ->
|
|
thangTypeName = @$el.find('input').val()
|
|
@thangType = _.find @settings.supermodel.getModels(ThangType), (m) -> m.get('name') is thangTypeName
|
|
if @thangType
|
|
@data = @thangType.get('original')
|
|
else
|
|
@data = null
|
|
|
|
module.exports.ThangTypeNode = ThangTypeNode = class ThangTypeNode extends TreemaNode.nodeMap.string
|
|
valueClass: 'treema-thang-type'
|
|
@thangTypesCollection: null # Lives in ThangTypeNode parent class
|
|
@thangTypes: null # Lives in ThangTypeNode or subclasses
|
|
|
|
constructor: ->
|
|
super(arguments...)
|
|
@getThangTypes()
|
|
unless ThangTypeNode.thangTypesCollection.loaded
|
|
ThangTypeNode.thangTypesCollection.once('sync', @refreshDisplay, @)
|
|
|
|
buildValueForDisplay: (valEl, data) ->
|
|
@buildValueForDisplaySimply(valEl, @getCurrentThangType() or '')
|
|
valEl
|
|
|
|
buildValueForEditing: (valEl, data) ->
|
|
super(valEl, data)
|
|
input = valEl.find 'input'
|
|
if @constructor.thangTypes
|
|
source = (thangType.name for thangType in @constructor.thangTypes when @filterThangType thangType)
|
|
input.autocomplete(source: source, minLength: 0, delay: 0, autoFocus: true)
|
|
input.val(@getCurrentThangType() or '')
|
|
valEl
|
|
|
|
filterThangType: (thangType) -> true
|
|
|
|
getCurrentThangType: ->
|
|
return null unless @constructor.thangTypes
|
|
return null unless original = @getData()
|
|
thangType = _.find @constructor.thangTypes, { original: original }
|
|
thangType?.name or '...'
|
|
|
|
getThangTypes: ->
|
|
if ThangTypeNode.thangTypesCollection
|
|
if not @constructor.thangTypes
|
|
@processThangTypes(ThangTypeNode.thangTypesCollection)
|
|
return
|
|
ThangTypeNode.thangTypesCollection = new CocoCollection([], {
|
|
url: '/db/thang.type'
|
|
project:['name', 'components', 'original']
|
|
model: ThangType
|
|
})
|
|
res = ThangTypeNode.thangTypesCollection.fetch()
|
|
ThangTypeNode.thangTypesCollection.once 'sync', => @processThangTypes(ThangTypeNode.thangTypesCollection)
|
|
|
|
processThangTypes: (thangTypeCollection) ->
|
|
@constructor.thangTypes = []
|
|
@processThangType thangType for thangType in thangTypeCollection.models
|
|
|
|
processThangType: (thangType) ->
|
|
@constructor.thangTypes.push name: thangType.get('name'), original: thangType.get('original')
|
|
|
|
saveChanges: ->
|
|
thangTypeName = @$el.find('input').val()
|
|
thangType = _.find(@constructor.thangTypes, {name: thangTypeName})
|
|
return @remove() unless thangType
|
|
@data = thangType.original
|
|
|
|
module.exports.ItemThangTypeNode = ItemThangTypeNode = class ItemThangTypeNode extends ThangTypeNode
|
|
valueClass: 'treema-item-thang-type'
|
|
|
|
filterThangType: (thangType) ->
|
|
@keyForParent in thangType.slots
|
|
|
|
processThangType: (thangType) ->
|
|
return unless itemComponent = _.find thangType.get('components'), {original: LevelComponent.ItemID}
|
|
@constructor.thangTypes.push name: thangType.get('name'), original: thangType.get('original'), slots: itemComponent.config?.slots ? ['right-hand']
|