Bunch of fixes to get the level editor working again.

This commit is contained in:
Scott Erickson 2014-08-25 20:34:46 -07:00
parent d392994a83
commit 1406a970ea
13 changed files with 102 additions and 37 deletions

View file

@ -209,7 +209,7 @@ module.exports = class World
@thangMap = {}
# Load new Thangs
toAdd = (@loadThangFromLevel thangConfig, level.levelComponents, level.thangTypes for thangConfig in level.thangs)
toAdd = (@loadThangFromLevel thangConfig, level.levelComponents, level.thangTypes for thangConfig in level.thangs ? [])
@extraneousThangs = consolidateThangs toAdd if willSimulate # Combine walls, for example; serialize the leftovers later
@addThang thang for thang in toAdd
null

View file

@ -95,7 +95,7 @@ module.exports = class Level extends CocoModel
#console.log 'sorted systems adding', systemModel.name
sorted.push {model: systemModel, config: _.cloneDeep system.config}
originalsSeen[system.original] = true
visit system for system in levelSystems
visit system for system in levelSystems ? []
sorted
sortThangComponents: (thangs, levelComponents, parentType) ->
@ -106,7 +106,7 @@ module.exports = class Level extends CocoModel
# Decision? Just special case the sort logic in here until we have more examples than these two and decide how best to handle most of the cases then, since we don't really know the whole of the problem yet.
# TODO: anything that depends on Programmable will break right now.
for thang in thangs
for thang in thangs ? []
sorted = []
visit = (c) ->
return if c in sorted
@ -137,7 +137,7 @@ module.exports = class Level extends CocoModel
# TODO DEFAULTS
fillInDefaultComponentConfiguration: (thangs, levelComponents) ->
for thang in thangs
for thang in thangs ? []
for component in thang.components or []
continue unless lc = _.find levelComponents, {original: component.original}
component.config ?= {}

View file

@ -207,7 +207,7 @@ GeneralArticleSchema = c.object {
LevelSchema = c.object {
title: 'Level'
description: 'A spectacular level which will delight and educate its stalwart players with the sorcery of coding.'
required: ['name', 'description', 'scripts', 'thangs', 'documentation']
required: ['name']
'default':
name: 'Ineffable Wizardry'
description: 'This level is indescribably flarmy.'

View file

@ -103,7 +103,7 @@ LevelComponentSchema = c.object {
title: 'Component'
description: 'A Component which can affect Thang behavior.'
required: ['system', 'name', 'description', 'code', 'dependencies', 'propertyDocumentation', 'codeLanguage']
'default':
default:
system: 'ai'
name: 'AttacksSelf'
description: 'This Component makes the Thang attack itself.'

View file

@ -4,3 +4,6 @@
.treema-root
border: 0
padding: 0 5px
.is-default-component
background-color: lightgray

View file

@ -29,6 +29,9 @@
bottom: 0
overflow: scroll
.treema-key, .treema-description
display: none
.dependent
background-color: rgba(128, 64, 255, 0.10)

View file

@ -1,5 +1,5 @@
.panel.panel-default
.panel-heading
.panel-heading(class=isDefaultComponent ? "is-default-component" : "")
em #{component.system}.
strong.panel-title.spr= component.name
span#description.text-muted= component.description

View file

@ -416,7 +416,7 @@ class LevelComponentReferenceNode extends LatestVersionReferenceNode
# supermodels.
buildSearchURL: (term) -> "#{@url}?term=#{term}&project=name,system,original,version,dependencies,configSchema,description"
modelToString: (model) -> model.get('system') + '.' + model.get('name')
canEdit: -> not @data.original # only allow editing if the row's data hasn't been set yet
canEdit: -> not @getData().original # only allow editing if the row's data hasn't been set yet
LatestVersionReferenceNode.prototype.search = _.debounce(LatestVersionReferenceNode.prototype.search, 200)

View file

@ -17,6 +17,7 @@ module.exports = class ThangComponentConfigView extends CocoView
super options
@component = options.component
@config = options.config or {}
@additionalDefaults = options.additionalDefaults
@world = options.world
@level = options.level
@callback = options.callback
@ -25,12 +26,18 @@ module.exports = class ThangComponentConfigView extends CocoView
context = super(context)
context.component = @component.attributes
context.configProperties = []
context.isDefaultComponent = @isDefaultComponent
context
afterRender: ->
super()
@buildTreema()
setIsDefaultComponent: (isDefaultComponent) ->
changed = @isDefaultComponent isnt isDefaultComponent
@isDefaultComponent = isDefaultComponent
@render() if changed
buildTreema: ->
thangs = if @level? then @level.get('thangs') else []
thangIDs = _.filter(_.pluck(thangs, 'id'))
@ -39,6 +46,9 @@ module.exports = class ThangComponentConfigView extends CocoView
superteams = _.union(teams, superteams)
config = $.extend true, {}, @config
schema = $.extend true, {}, @component.get('configSchema')
schema.default ?= {}
_.merge schema.default, @additionalDefaults if @additionalDefaults
if @level?.get('type') is 'hero'
schema.required = []
treemaOptions =

View file

@ -28,13 +28,18 @@ module.exports = class ThangComponentsEditView extends CocoView
@originalsLoaded = {}
@components = options.components or []
@components = $.extend true, [], @components # just to be sure
@setThangType options.thangType
@lastComponentLength = @components.length
@world = options.world
@level = options.level
@loadComponents(@components)
# Need to grab the ThangTypes so that we can autocomplete items in inventory based on them.
@itemThangTypes = @supermodel.loadCollection(new ItemThangTypeSearchCollection(), 'thangs').model
setThangType: (@thangType) ->
return unless componentRefs = @thangType?.get('components')
@loadComponents(componentRefs)
loadComponents: (components) ->
for componentRef in components
# just to handle if ever somehow the same component is loaded twice, through bad data and alike
@ -59,26 +64,20 @@ module.exports = class ThangComponentsEditView extends CocoView
@addThangComponentConfigViews()
buildComponentsTreema: ->
components = _.zipObject((c.original for c in @components), @components)
defaultValue = undefined
if thangTypeComponents = @thangType?.get('components', true)
defaultValue = _.zipObject((c.original for c in thangTypeComponents), thangTypeComponents)
treemaOptions =
supermodel: @supermodel
schema: Level.schema.properties.thangs.items.properties.components
data: $.extend true, [], @components
schema: {
type: 'object'
default: defaultValue
additionalProperties: Level.schema.properties.thangs.items.properties.components.items
},
data: $.extend true, {}, components
callbacks: {select: @onSelectComponent, change: @onComponentsTreemaChanged}
noSortable: true
nodeClasses:
'thang-components-array': ThangComponentsArrayNode
'point2d': nodes.WorldPointNode
'viewport': nodes.WorldViewportNode
'bounds': nodes.WorldBoundsNode
'radians': nodes.RadiansNode
'team': nodes.TeamNode
'superteam': nodes.SuperteamNode
'meters': nodes.MetersNode
'kilograms': nodes.KilogramsNode
'seconds': nodes.SecondsNode
'speed': nodes.SpeedNode
'acceleration': nodes.AccelerationNode
'item-thang-type': nodes.ItemThangTypeNode
@componentsTreema = @$el.find('#thang-components-column .treema').treema treemaOptions
@componentsTreema.build()
@ -91,7 +90,7 @@ module.exports = class ThangComponentsEditView extends CocoView
componentMap[component.original] = component
newComponentsList = []
for component in @componentsTreema.data
for component in _.values(@componentsTreema.data)
newComponentsList.push(componentMap[component.original] or component)
@components = newComponentsList
@ -204,12 +203,26 @@ module.exports = class ThangComponentsEditView extends CocoView
# Put back config views into the DOM based on the component list ordering,
# adding and registering new ones as needed.
configsEl = @$el.find('#thang-component-configs')
for componentRef in @componentsTreema.data
componentRefs = _.merge {}, @componentsTreema.data
if thangTypeComponents = @thangType?.get('components')
thangComponentRefs = _.zipObject((c.original for c in thangTypeComponents), thangTypeComponents)
for thangTypeComponent in thangTypeComponents
if componentRef = componentRefs[thangTypeComponent.original]
componentRef.additionalDefaults = thangTypeComponent.config
else
modifiedRef = _.merge {}, thangTypeComponent
modifiedRef.additionalDefaults = modifiedRef.config
delete modifiedRef.additionalDefaults
componentRefs[thangTypeComponent.original] = modifiedRef
for componentRef in _.values(componentRefs)
subview = componentConfigViews[componentRef.original]
if not subview
subview = @makeThangComponentConfigView(componentRef)
continue unless subview
@registerSubView(subview)
subview.setIsDefaultComponent(not @componentsTreema.data[componentRef.original])
configsEl.append(subview.$el)
makeThangComponentConfigView: (thangComponent) ->
@ -222,15 +235,29 @@ module.exports = class ThangComponentsEditView extends CocoView
world: @world
config: config
component: component
additionalDefaults: thangComponent.additionalDefaults
})
configView.render()
@listenTo configView, 'changed', @onConfigChanged
configView
onConfigChanged: (e) ->
foundComponent = false
for thangComponent in @components
if thangComponent.original is e.component.get('original')
thangComponent.config = e.config
foundComponent = true
break
if not foundComponent
@components.push({
original: e.component.get('original')
majorVersion: e.component.get('version').major
config: e.config
})
@onComponentsChanged()
@updateComponentsList()
@reportChanges()
onSelectComponent: (e, nodes) =>
@ -239,28 +266,28 @@ module.exports = class ThangComponentsEditView extends CocoView
# find dependent components
dependents = {}
dependents[nodes[0].data.original] = true
componentsToCheck = [nodes[0].data.original]
dependents[nodes[0].getData().original] = true
componentsToCheck = [nodes[0].getData().original]
while componentsToCheck.length
componentOriginal = componentsToCheck.pop()
for otherComponentRef in @components
continue if otherComponentRef.original is componentOriginal
continue if dependents[otherComponentRef.original]
otherComponent = @supermodel.getModelByOriginal(LevelComponent, otherComponentRef.original)
for dependency in otherComponent.get('dependencies')
for dependency in otherComponent.get('dependencies', true)
if dependents[dependency.original]
dependents[otherComponentRef.original] = true
componentsToCheck.push otherComponentRef.original
# highlight them
for child in _.values(@componentsTreema.childrenTreemas)
if dependents[child.data.original]
if dependents[child.getData().original]
child.$el.addClass('dependent')
# scroll to the config
for subview in _.values(@subviews)
continue unless subview instanceof ThangComponentConfigView
if subview.component.get('original') is nodes[0].data.original
if subview.component.get('original') is nodes[0].getData().original
subview.$el[0].scrollIntoView()
break

View file

@ -47,7 +47,7 @@ module.exports = class SettingsTabView extends CocoView
@settingsTreema.open()
getThangIDs: ->
(t.id for t in @level.get('thangs') when t.id isnt 'Interface')
(t.id for t in @level.get('thangs') ? [] when t.id isnt 'Interface')
onSettingsChanged: (e) =>
$('.level-title').text @settingsTreema.data.name

View file

@ -7,7 +7,7 @@ exports.config =
'public': 'public'
conventions:
ignored: (path) -> startsWith(sysPath.basename(path), '_')
sourceMaps: false
sourceMaps: true
files:
javascripts:
defaultExtension: 'coffee'

View file

@ -1,4 +1,5 @@
ThangComponentEditView = require('views/editor/component/ThangComponentsEditView')
ThangType = require 'models/ThangType'
responses =
'/db/level.component/A/version/0': {
@ -6,8 +7,13 @@ responses =
original: 'A'
version: { major: 0, minor: 0 }
name: 'A'
configSchema: { type: 'object', properties: { propA: { type: 'number' }, propB: { type: 'string' }} }
configSchema: {
type: 'object'
properties: {
propA: { type: 'number' }
propB: { type: 'string' }
}
}
}
'/db/level.component/B/version/0': {
system: 'System'
@ -22,6 +28,16 @@ responses =
version: { major: 0, minor: 0 }
name: 'C (depends on B)'
dependencies: [{original:'B', majorVersion: 0}]
configSchema: {
type: 'object'
default: { propC: 'Default property from component config' }
}
}
'/db/level.component/D/version/0': {
system: 'System'
original: 'D'
version: { major: 0, minor: 0 }
name: 'D (comes from ThangType components)'
}
'/db/thang.type': []
@ -32,6 +48,12 @@ module.exports = ->
{ original: 'B', majorVersion: 0 }
{ original: 'C', majorVersion: 0 }
]
thangType: new ThangType({
components: [
{ original: 'C', majorVersion: 0, config: {propD: 'Default property from thang type component.'} }
{ original: 'D', majorVersion: 0 }
]
})
})
view.render()