codecombat/app/views/editor/level/modals/TerrainRandomizeModal.coffee

259 lines
7.5 KiB
CoffeeScript
Raw Normal View History

ModalView = require 'views/kinds/ModalView'
2014-07-13 20:31:09 -04:00
template = require 'templates/editor/level/modal/terrain_randomize'
CocoModel = require 'models/CocoModel'
clusters = {
'rocks': {
'thangs': ['Rock 1', 'Rock 2', 'Rock 3', 'Rock 4', 'Rock 5', 'Rock Cluster 1', 'Rock Cluster 2', 'Rock Cluster 3']
'margin': 1
}
'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
}
'grass_floor': {
'thangs': ['Grass01', 'Grass02', 'Grass03', 'Grass04', 'Grass05']
'margin': -1
}
'dungeon_wall': {
'thangs': ['Dungeon Wall']
'margin': 0
}
'dungeon_floor': {
'thangs': ['Dungeon Floor']
'margin': -1
}
}
presets = {
'dungeon': {
'type':'dungeon'
'borders':'dungeon_wall'
'borderNoise':0
'borderSize':4
'floors':'dungeon_floor'
'decorations': {
'cave': {
'num':[1,1]
'width': 20
'height': 20
'clusters': {
'cave':[1,1]
'stone':[2,4]
}
}
}
}
'grassy': {
'type':'grassy'
'borders':'trees'
'borderNoise':1
'borderSize':0
'floors':'grass_floor'
'decorations': {
'house': {
'num':[1,2] #min-max
'width': 15
'height': 15
'clusters': {
'houses':[1,1]
'trees':[1,2]
'shrubs':[0,3]
'rocks':[1,2]
}
}
'farm': {
'num':[1,1] #min-max
'width': 25
'height': 15
'clusters': {
'farm':[1,1]
'shrubs':[2,3]
'wood':[2,4]
'animals':[2,3]
}
}
}
}
}
presetSizes = {
'small': {
'x':80
'y':68
}
'large': {
'x':160
'y':136
}
}
thangSizes = {
'floorSize': {
'x':20
'y':17
}
'borderSize': {
'x':4
'y':4
'thickness':3
}
}
2014-07-13 20:31:09 -04:00
module.exports = class TerrainRandomizeModal extends ModalView
id: 'terrain-randomize-modal'
template: template
thangs = []
events:
2014-07-13 20:31:09 -04:00
'click .choose-option': 'onRandomize'
onRevertModel: (e) ->
id = $(e.target).val()
CocoModel.backedUp[id].revert()
$(e.target).closest('tr').remove()
@reloadOnClose = true
2014-07-13 20:31:09 -04:00
onRandomize: (e) ->
target = $(e.target)
presetType = target.attr 'data-preset-type'
presetSize = target.attr 'data-preset-size'
2014-07-13 20:31:09 -04:00
@randomizeThangs presetType, presetSize
2014-07-15 21:08:00 -04:00
Backbone.Mediator.publish('randomize:terrain-generated',
'thangs': @thangs
)
@hide()
2014-07-13 20:31:09 -04:00
randomizeThangs: (presetName, presetSize) ->
preset = presets[presetName]
presetSize = presetSizes[presetSize]
@thangs = []
2014-07-13 20:31:09 -04:00
@randomizeFloor preset, presetSize
@randomizeBorder preset, presetSize, preset.borderNoise
2014-07-13 20:31:09 -04:00
@randomizeDecorations preset, presetSize
2014-07-13 20:31:09 -04:00
randomizeFloor: (preset, presetSize) ->
for i in _.range(0, presetSize.x, thangSizes.floorSize.x)
for j in _.range(0, presetSize.y, thangSizes.floorSize.y)
@thangs.push {
'id': @getRandomThang(clusters[preset.floors].thangs)
'pos': {
'x': i + thangSizes.floorSize.x/2
'y': j + thangSizes.floorSize.y/2
}
'margin': clusters[preset.floors].margin
}
randomizeBorder: (preset, presetSize, noiseFactor=1) ->
for i in _.range(0, presetSize.x, thangSizes.borderSize.x)
for j in _.range(thangSizes.borderSize.thickness)
while not @addThang {
'id': @getRandomThang(clusters[preset.borders].thangs)
'pos': {
'x': i + preset.borderSize/2 + noiseFactor * _.random(-thangSizes.borderSize.x/2, thangSizes.borderSize.x/2)
'y': 0 + preset.borderSize/2 + noiseFactor * _.random(-thangSizes.borderSize.y/2, thangSizes.borderSize.y)
}
'margin': clusters[preset.borders].margin
}
continue
while not @addThang {
'id': @getRandomThang(clusters[preset.borders].thangs)
'pos': {
'x': i + preset.borderSize/2 + noiseFactor * _.random(-thangSizes.borderSize.x/2, thangSizes.borderSize.x/2)
'y': presetSize.y - preset.borderSize/2 + noiseFactor * _.random(-thangSizes.borderSize.y, thangSizes.borderSize.y/2)
}
'margin': clusters[preset.borders].margin
}
continue
for i in _.range(0, presetSize.y, thangSizes.borderSize.y)
for j in _.range(3)
while not @addThang {
'id': @getRandomThang(clusters[preset.borders].thangs)
'pos': {
'x': 0 + preset.borderSize/2 + noiseFactor * _.random(-thangSizes.borderSize.x/2, thangSizes.borderSize.x)
'y': i + preset.borderSize/2 + noiseFactor * _.random(-thangSizes.borderSize.y/2, thangSizes.borderSize.y/2)
}
'margin': clusters[preset.borders].margin
}
continue
while not @addThang {
'id': @getRandomThang(clusters[preset.borders].thangs)
'pos': {
'x': presetSize.x - preset.borderSize/2 + noiseFactor * _.random(-thangSizes.borderSize.x, thangSizes.borderSize.x/2)
'y': i + preset.borderSize/2 + noiseFactor * _.random(-thangSizes.borderSize.y/2, thangSizes.borderSize.y/2)
}
'margin': clusters[preset.borders].margin
}
continue
2014-07-13 20:31:09 -04:00
randomizeDecorations: (preset, presetSize)->
if presetSize is presetSizes['small'] then sizeFactor = 1 else sizeFactor = 2
for name, decoration of preset.decorations
for num in _.range(sizeFactor * _.random(decoration.num[0], decoration.num[1]))
rect = {
'x':_.random(decoration.width/2 + preset.borderSize/2 + thangSizes.borderSize.x, presetSize.x - decoration.width/2 - preset.borderSize/2 - thangSizes.borderSize.x),
'y':_.random(decoration.height/2 + preset.borderSize/2 + thangSizes.borderSize.y, presetSize.y - decoration.height/2 - preset.borderSize/2 - thangSizes.borderSize.y)
'width':decoration.width
'height':decoration.height
}
for cluster, range of decoration.clusters
for i in _.range(_.random(range[0], range[1]))
while not @addThang {
'id':@getRandomThang(clusters[cluster].thangs)
'pos':{
'x':_.random(rect.x - rect.width/2, rect.x + rect.width/2)
'y':_.random(rect.y - rect.height/2, rect.y + rect.height/2)
}
'margin':clusters[cluster].margin
}
continue
addThang: (thang) ->
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
return false
@thangs.push thang
true
getRandomThang: (thangList) ->
return thangList[_.random(0, thangList.length-1)]
getRenderData: ->
c = super()
c.presets = presets
c.presetSizes = presetSizes
c
onHidden: ->
location.reload() if @reloadOnClose