diff --git a/app/lib/surface/CocoSprite.coffee b/app/lib/surface/CocoSprite.coffee index 509b735e0..92d2a5f9b 100644 --- a/app/lib/surface/CocoSprite.coffee +++ b/app/lib/surface/CocoSprite.coffee @@ -391,7 +391,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass rotationType = @thangType.get('rotationType') return if rotationType is 'fixed' rotation = @getRotation() - if @thangType.get('name') in ['Arrow', 'Spear'] + if @thangType.get('name') in ['Arrow', 'Spear'] and @thang.velocity # Rotates the arrow to see it arc based on velocity.z. # Notice that rotation here does not affect thang's state - it is just the effect. # Thang's rotation is always pointing where it is heading. diff --git a/app/lib/surface/SpriteBoss.coffee b/app/lib/surface/SpriteBoss.coffee index fb30b505a..634d5ea2d 100644 --- a/app/lib/surface/SpriteBoss.coffee +++ b/app/lib/surface/SpriteBoss.coffee @@ -180,7 +180,11 @@ module.exports = class SpriteBoss extends CocoClass adjustSpriteExistence: -> # Add anything new, remove anything old, update everything current updateCache = false + itemsJustEquipped = [] for thang in @world.thangs when thang.exists + if thang.equip and not thang.equipped + thang.equip() # Pretty hacky, since initialize may not be called + itemsJustEquipped.push thang if sprite = @sprites[thang.id] sprite.setThang thang # make sure Sprite has latest Thang else @@ -188,6 +192,7 @@ module.exports = class SpriteBoss extends CocoClass Backbone.Mediator.publish 'surface:new-thang-added', thang:thang, sprite:sprite updateCache = updateCache or sprite.imageObject.parent is @spriteLayers['Obstacle'] sprite.playSounds() + item.modifyStats() for item in itemsJustEquipped for thangID, sprite of @sprites missing = not (sprite.notOfThisWorld or @world.thangMap[thangID]?.exists) isObstacle = sprite.imageObject.parent is @spriteLayers['Obstacle'] diff --git a/app/lib/world/world.coffee b/app/lib/world/world.coffee index f94a6d26a..ca61daddb 100644 --- a/app/lib/world/world.coffee +++ b/app/lib/world/world.coffee @@ -240,7 +240,7 @@ module.exports = class World calculateBounds: -> bounds = {left: 0, top: 0, right: 0, bottom: 0} hasLand = _.some @thangs, 'isLand' - for thang in @thangs when thang.isLand or not hasLand # Look at Lands only + for thang in @thangs when thang.isLand or (not hasLand and thang.rectangle) # Look at Lands only rect = thang.rectangle().axisAlignedBoundingBox() bounds.left = Math.min(bounds.left, rect.x - rect.width / 2) bounds.right = Math.max(bounds.right, rect.x + rect.width / 2) diff --git a/app/schemas/models/thang_type.coffee b/app/schemas/models/thang_type.coffee index 0203287af..d93b0e625 100644 --- a/app/schemas/models/thang_type.coffee +++ b/app/schemas/models/thang_type.coffee @@ -105,7 +105,7 @@ _.extend ThangTypeSchema.properties, shapes: c.object {title: 'Shapes', additionalProperties: ShapeObjectSchema} containers: c.object {title: 'Containers', additionalProperties: ContainerObjectSchema} animations: c.object {title: 'Animations', additionalProperties: RawAnimationObjectSchema} - kind: c.shortString {enum: ['Unit', 'Floor', 'Wall', 'Doodad', 'Misc', 'Mark'], default: 'Misc', title: 'Kind'} + kind: c.shortString {enum: ['Unit', 'Floor', 'Wall', 'Doodad', 'Misc', 'Mark', 'Item'], default: 'Misc', title: 'Kind'} actions: c.object {title: 'Actions', additionalProperties: {$ref: '#/definitions/action'}} soundTriggers: c.object {title: 'Sound Triggers', additionalProperties: c.array({}, {$ref: '#/definitions/sound'})}, diff --git a/app/styles/editor/level/thangs_tab.sass b/app/styles/editor/level/thangs_tab.sass index 0bbf859e1..e8175462f 100644 --- a/app/styles/editor/level/thangs_tab.sass +++ b/app/styles/editor/level/thangs_tab.sass @@ -110,6 +110,12 @@ $mobile: 1050px .treema-node.treema-Wall display: block + &.hide-except-Item + .treema-node + display: none + .treema-node.treema-Item + display: block + &.hide-except-Misc .treema-node display: none diff --git a/app/templates/editor/level/thangs_tab.jade b/app/templates/editor/level/thangs_tab.jade index 54eb93f7e..3cb870ddd 100644 --- a/app/templates/editor/level/thangs_tab.jade +++ b/app/templates/editor/level/thangs_tab.jade @@ -15,6 +15,8 @@ button.navbar-toggle.toggle.btn-primary#thangs-palette-toggle(type="button", dat i.icon-globe button.btn.btn-primary(value="Doodad", title="Doodad") i.icon-leaf + button.btn.btn-primary(value="Item", title="Item") + i.icon-gift button.btn.btn-primary(value="Misc", title="Misc") i.icon-question-sign .editor-nano-container.nano diff --git a/app/views/editor/level/modals/SaveLevelModal.coffee b/app/views/editor/level/modals/SaveLevelModal.coffee index 04c32e670..2cbf62b9c 100644 --- a/app/views/editor/level/modals/SaveLevelModal.coffee +++ b/app/views/editor/level/modals/SaveLevelModal.coffee @@ -47,7 +47,7 @@ module.exports = class SaveLevelModal extends SaveVersionModal shouldSaveEntity: (m) -> return false unless m.hasWriteAccess() - return false unless m.hasLocalChanges() + return true if m.hasLocalChanges() return true if (m.get('version').major is 0 and m.get('version').minor is 0) or not m.isPublished() and not m.collection # Sometimes we have two versions: one in a search collection and one with a URL. We only save changes to the latter. false diff --git a/app/views/editor/level/modals/TerrainRandomizeModal.coffee b/app/views/editor/level/modals/TerrainRandomizeModal.coffee index 632617678..c9decc61c 100644 --- a/app/views/editor/level/modals/TerrainRandomizeModal.coffee +++ b/app/views/editor/level/modals/TerrainRandomizeModal.coffee @@ -10,35 +10,35 @@ clusters = { 'trees': { 'thangs': ['Tree 1', 'Tree 2', 'Tree 3', 'Tree 4'] 'margin': 0 - } + } 'shrubs': { 'thangs': ['Shrub 1', 'Shrub 2', 'Shrub 3'] 'margin': 0 - } + } 'houses': { 'thangs': ['House 1', 'House 2', 'House 3', 'House 4'] 'margin': 4 - } + } 'animals': { 'thangs': ['Cow', 'Horse'] 'margin': 1 - } + } 'wood': { 'thangs': ['Firewood 1', 'Firewood 2', 'Firewood 3', 'Barrel'] 'margin': 1 - } + } 'farm': { 'thangs': ['Farm'] 'margin': 9 - } + } 'cave': { 'thangs': ['Cave'] 'margin': 5 - } + } 'stone': { 'thangs': ['Gargoyle', 'Rock Cluster 1', 'Rock Cluster 2', 'Rock Cluster 3'] 'margin': 1 - } + } 'doors': { 'thangs': ['Dungeon Door'] 'margin': -1 @@ -46,15 +46,15 @@ clusters = { 'grass_floor': { 'thangs': ['Grass01', 'Grass02', 'Grass03', 'Grass04', 'Grass05'] 'margin': -1 - } + } 'dungeon_wall': { 'thangs': ['Dungeon Wall'] - 'margin': -1 - } + 'margin': 2 + } 'dungeon_floor': { 'thangs': ['Dungeon Floor'] 'margin': -1 - } + } } presets = { @@ -79,7 +79,7 @@ presets = { 'width': [12, 20] 'height': [8, 16] 'thickness': [2,2] - 'cluster': 'dungeon_wall' + 'cluster': 'dungeon_wall' } } } @@ -241,7 +241,7 @@ module.exports = class TerrainRandomizeModal extends ModalView 'height':decoration.height } break if @addRect rect - + for cluster, range of decoration.clusters for i in _.range(_.random(range[0], range[1])) while not @addThang { @@ -259,11 +259,14 @@ module.exports = class TerrainRandomizeModal extends ModalView while true rect = { 'width':sizeFactor * (room.width[0] + preset.borderSize * _.random(0, (room.width[1] - room.width[0])/preset.borderSize)) - 'height':sizeFactor * (room.height[0] + preset.borderSize * _.random(0, (room.height[1] - room.height[0])/preset.borderSize)) + 'height':sizeFactor * (room.height[0] + preset.borderSize * _.random(0, (room.height[1] - room.height[0])/preset.borderSize)) } roomThickness = _.random(room.thickness[0], room.thickness[1]) rect.x = _.random(rect.width/2 + preset.borderSize * (roomThickness+1), presetSize.x - rect.width/2 - preset.borderSize * (roomThickness+1)) rect.y = _.random(rect.height/2 + preset.borderSize * (roomThickness+1), presetSize.y - rect.height/2 - preset.borderSize * (roomThickness+1)) + # Snap room walls to the wall grid. + rect.x = Math.round((rect.x - preset.borderSize / 2) / preset.borderSize) * preset.borderSize + preset.borderSize / 2 + rect.y = Math.round((rect.y - preset.borderSize / 2) / preset.borderSize) * preset.borderSize + preset.borderSize / 2 break if @addRect { 'x': rect.x 'y': rect.y @@ -333,9 +336,9 @@ module.exports = class TerrainRandomizeModal extends ModalView for existingThang in @thangs if existingThang.margin is -1 or thang.margin is -1 continue - if Math.abs(existingThang.pos.x - thang.pos.x) <= thang.margin + existingThang.margin and Math.abs(existingThang.pos.y - thang.pos.y) <= thang.margin + existingThang.margin + if Math.abs(existingThang.pos.x - thang.pos.x) < thang.margin + existingThang.margin and Math.abs(existingThang.pos.y - thang.pos.y) < thang.margin + existingThang.margin @falseCount++ - return false + return false @thangs.push thang true @@ -345,9 +348,9 @@ module.exports = class TerrainRandomizeModal extends ModalView @falseCount = 0 return true for existingRect in @rects - if Math.abs(existingRect.x - rect.x) <= rect.width/2 + existingRect.width/2 and Math.abs(existingRect.y - rect.y) <= rect.height/2 + existingRect.height/2 + if Math.abs(existingRect.x - rect.x) < rect.width/2 + existingRect.width/2 and Math.abs(existingRect.y - rect.y) < rect.height/2 + existingRect.height/2 @falseCount++ - return false + return false @rects.push rect true diff --git a/app/views/editor/level/thangs/ThangsTabView.coffee b/app/views/editor/level/thangs/ThangsTabView.coffee index 45d652a94..5f28b1279 100644 --- a/app/views/editor/level/thangs/ThangsTabView.coffee +++ b/app/views/editor/level/thangs/ThangsTabView.coffee @@ -116,7 +116,7 @@ module.exports = class ThangsTabView extends CocoView $(window).resize @onWindowResize @addThangsView = @insertSubView new AddThangsView world: @world, supermodel: @supermodel @buildInterface() # refactor to not have this trigger when this view re-renders? - if @thangsTreema.data.length + if @thangsTreema.data.length @$el.find('#canvas-overlay').css('display', 'none') onFilterExtantThangs: (e) -> @@ -500,7 +500,7 @@ class ThangNode extends TreemaObjectNode s = "#{@data.thangType}" if isObjectID s unless name = ThangNode.thangNameMap[s] - thangType = _.find @settings.supermodel.getModels(ThangType), (m) -> m.get('original') is s + thangType = _.find @settings.supermodel.getModels(ThangType), (m) -> m.get('original') is s and m.get('kind') name = ThangNode.thangNameMap[s] = thangType.get 'name' ThangNode.thangKindMap[s] = thangType.get 'kind' kind = ThangNode.thangKindMap[s] diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index d55dcadbe..55b45884f 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -166,7 +166,7 @@ module.exports = class Handler ids = ids.split(',') if _.isString ids ids = _.uniq ids - project = {name:1, original:1} + project = {name:1, original:1, kind:1} sort = {'version.major':-1, 'version.minor':-1} makeFunc = (id) => @@ -450,4 +450,3 @@ module.exports = class Handler projection = {} projection[field] = 0 for field in model.privateProperties projection -