Merge pull request from jayant1992/temp

Terrain generator
This commit is contained in:
Nick Winter 2014-08-12 08:42:15 -07:00
commit a4663bf5e4
5 changed files with 151 additions and 15 deletions

Binary file not shown.

After

(image error) Size: 88 KiB

Binary file not shown.

After

(image error) Size: 88 KiB

Binary file not shown.

After

(image error) Size: 82 KiB

Binary file not shown.

After

(image error) Size: 84 KiB

View file

@ -24,7 +24,7 @@ clusters = {
'margin': 1 'margin': 1
} }
'wood': { 'wood': {
'thangs': ['Firewood 1', 'Firewood 2', 'Firewood 3', 'Barrel'] 'thangs': ['Firewood 1', 'Firewood 2', 'Firewood 3']
'margin': 1 'margin': 1
} }
'farm': { 'farm': {
@ -39,6 +39,18 @@ clusters = {
'thangs': ['Gargoyle', 'Rock Cluster 1', 'Rock Cluster 2', 'Rock Cluster 3'] 'thangs': ['Gargoyle', 'Rock Cluster 1', 'Rock Cluster 2', 'Rock Cluster 3']
'margin': 1 'margin': 1
} }
'torch': {
'thangs': ['Torch']
'margin': 0
}
'chains': {
'thangs': ['Chains']
'margin': 0
}
'barrel': {
'thangs': ['Barrel']
'margin': 1
}
'doors': { 'doors': {
'thangs': ['Dungeon Door'] 'thangs': ['Dungeon Door']
'margin': -1 'margin': -1
@ -55,6 +67,18 @@ clusters = {
'thangs': ['Dungeon Floor'] 'thangs': ['Dungeon Floor']
'margin': -1 'margin': -1
} }
'indoor_wall': {
'thangs': ['Indoor Wall']
'margin': 2
}
'indoor_floor': {
'thangs': ['Indoor Floor']
'margin': -1
}
'furniture': {
'thangs': ['Bookshelf', 'Chair', 'Table', 'Candle', 'Treasure Chest']
'margin': -1
}
} }
presets = { presets = {
@ -63,8 +87,23 @@ presets = {
'borders':'dungeon_wall' 'borders':'dungeon_wall'
'borderNoise':0 'borderNoise':0
'borderSize':4 'borderSize':4
'borderThickness':1
'floors':'dungeon_floor' 'floors':'dungeon_floor'
'decorations': { 'decorations': {
'Room': {
'num': [1,1]
'width': [12, 20]
'height': [8, 16]
'thickness': [2,2]
'cluster': 'dungeon_wall'
}
'Barrels': {
'num': [1,1]
'width': [8, 12]
'height': [8, 12]
'numBarrels': [4,6]
'cluster': 'barrel'
}
'cave': { 'cave': {
'num':[1,1] 'num':[1,1]
'width': 10 'width': 10
@ -74,12 +113,30 @@ presets = {
'stone':[2,4] 'stone':[2,4]
} }
} }
}
}
'indoor': {
'type':'indoor'
'borders':'indoor_wall'
'borderNoise':0
'borderSize':4
'borderThickness':1
'floors':'indoor_floor'
'decorations': {
'Room': { 'Room': {
'num': [1,1] 'num': [1,1]
'width': [12, 20] 'width': [12, 20]
'height': [8, 16] 'height': [8, 16]
'thickness': [2,2] 'thickness': [2,2]
'cluster': 'dungeon_wall' 'cluster': 'indoor_wall'
}
'furniture': {
'num':[1,2]
'width': 15
'height': 15
'clusters': {
'furniture':[2,4]
}
} }
} }
} }
@ -88,6 +145,7 @@ presets = {
'borders':'trees' 'borders':'trees'
'borderNoise':1 'borderNoise':1
'borderSize':0 'borderSize':0
'borderThickness':3
'floors':'grass_floor' 'floors':'grass_floor'
'decorations': { 'decorations': {
'house': { 'house': {
@ -120,10 +178,12 @@ presetSizes = {
'small': { 'small': {
'x':80 'x':80
'y':68 'y':68
'sizeFactor':1
} }
'large': { 'large': {
'x':160 'x':160
'y':136 'y':136
'sizeFactor':2
} }
} }
@ -135,7 +195,6 @@ thangSizes = {
'borderSize': { 'borderSize': {
'x':4 'x':4
'y':4 'y':4
'thickness':3
} }
} }
@ -185,7 +244,8 @@ module.exports = class TerrainRandomizeModal extends ModalView
randomizeBorder: (preset, presetSize, noiseFactor=1) -> randomizeBorder: (preset, presetSize, noiseFactor=1) ->
for i in _.range(0, presetSize.x, thangSizes.borderSize.x) for i in _.range(0, presetSize.x, thangSizes.borderSize.x)
for j in _.range(thangSizes.borderSize.thickness) for j in _.range(preset.borderThickness)
# Bottom wall
while not @addThang { while not @addThang {
'id': @getRandomThang(clusters[preset.borders].thangs) 'id': @getRandomThang(clusters[preset.borders].thangs)
'pos': { 'pos': {
@ -195,6 +255,8 @@ module.exports = class TerrainRandomizeModal extends ModalView
'margin': clusters[preset.borders].margin 'margin': clusters[preset.borders].margin
} }
continue continue
# Top wall
while not @addThang { while not @addThang {
'id': @getRandomThang(clusters[preset.borders].thangs) 'id': @getRandomThang(clusters[preset.borders].thangs)
'pos': { 'pos': {
@ -205,8 +267,38 @@ module.exports = class TerrainRandomizeModal extends ModalView
} }
continue continue
# Double wall on top
if preset.type is 'dungeon'
@addThang {
'id': @getRandomThang(clusters[preset.borders].thangs)
'pos': {
'x': i + preset.borderSize/2
'y': presetSize.y - 3 * preset.borderSize/2
}
'margin': clusters[preset.borders].margin
}
if ( i / preset.borderSize ) % 2 and i isnt presetSize.x - thangSizes.borderSize.x
@addThang {
'id': @getRandomThang(clusters['torch'].thangs)
'pos': {
'x': i + preset.borderSize
'y': presetSize.y - preset.borderSize
}
'margin': clusters['torch'].margin
}
else if ( i / preset.borderSize ) % 2 is 0 and i and _.random(100) < 30
@addThang {
'id': @getRandomThang(clusters['chains'].thangs)
'pos': {
'x': i + preset.borderSize
'y': presetSize.y - preset.borderSize
}
'margin': clusters['chains'].margin
}
for i in _.range(0, presetSize.y, thangSizes.borderSize.y) for i in _.range(0, presetSize.y, thangSizes.borderSize.y)
for j in _.range(3) for j in _.range(preset.borderThickness)
# Left wall
while not @addThang { while not @addThang {
'id': @getRandomThang(clusters[preset.borders].thangs) 'id': @getRandomThang(clusters[preset.borders].thangs)
'pos': { 'pos': {
@ -216,6 +308,8 @@ module.exports = class TerrainRandomizeModal extends ModalView
'margin': clusters[preset.borders].margin 'margin': clusters[preset.borders].margin
} }
continue continue
# Right wall
while not @addThang { while not @addThang {
'id': @getRandomThang(clusters[preset.borders].thangs) 'id': @getRandomThang(clusters[preset.borders].thangs)
'pos': { 'pos': {
@ -227,9 +321,8 @@ module.exports = class TerrainRandomizeModal extends ModalView
continue continue
randomizeDecorations: (preset, presetSize)-> randomizeDecorations: (preset, presetSize)->
if presetSize is presetSizes['small'] then sizeFactor = 1 else sizeFactor = 2
for name, decoration of preset.decorations for name, decoration of preset.decorations
for num in _.range(sizeFactor * _.random(decoration.num[0], decoration.num[1])) for num in _.range(presetSize.sizeFactor * _.random(decoration.num[0], decoration.num[1]))
if @['build'+name] isnt undefined if @['build'+name] isnt undefined
@['build'+name](preset, presetSize, decoration) @['build'+name](preset, presetSize, decoration)
continue continue
@ -255,23 +348,22 @@ module.exports = class TerrainRandomizeModal extends ModalView
continue continue
buildRoom: (preset, presetSize, room) -> buildRoom: (preset, presetSize, room) ->
if presetSize is presetSizes['small'] then sizeFactor = 1 else sizeFactor = 2
while true while true
rect = { rect = {
'width':sizeFactor * (room.width[0] + preset.borderSize * _.random(0, (room.width[1] - room.width[0])/preset.borderSize)) 'width':presetSize.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':presetSize.sizeFactor * (room.height[0] + preset.borderSize * _.random(0, (room.height[1] - room.height[0])/preset.borderSize))
} }
roomThickness = _.random(room.thickness[0], room.thickness[1]) 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.x = _.random(rect.width/2 + preset.borderSize * (roomThickness+1.5), presetSize.x - rect.width/2 - preset.borderSize * (roomThickness+1.5))
rect.y = _.random(rect.height/2 + preset.borderSize * (roomThickness+1), presetSize.y - rect.height/2 - preset.borderSize * (roomThickness+1)) rect.y = _.random(rect.height/2 + preset.borderSize * (roomThickness+2.5), presetSize.y - rect.height/2 - preset.borderSize * (roomThickness+3.5))
# Snap room walls to the wall grid. # Snap room walls to the wall grid.
rect.x = Math.round((rect.x - preset.borderSize / 2) / preset.borderSize) * preset.borderSize + preset.borderSize / 2 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 rect.y = Math.round((rect.y - preset.borderSize / 2) / preset.borderSize) * preset.borderSize + preset.borderSize / 2
break if @addRect { break if @addRect {
'x': rect.x 'x': rect.x
'y': rect.y 'y': rect.y
'width': rect.width + 2 * roomThickness * preset.borderSize 'width': rect.width + 2.5 * roomThickness * preset.borderSize
'height': rect.height + 2 * roomThickness * preset.borderSize 'height': rect.height + 2.5 * roomThickness * preset.borderSize
} }
xRange = _.range(rect.x - rect.width/2 + preset.borderSize, rect.x + rect.width/2, preset.borderSize) xRange = _.range(rect.x - rect.width/2 + preset.borderSize, rect.x + rect.width/2, preset.borderSize)
@ -282,6 +374,7 @@ module.exports = class TerrainRandomizeModal extends ModalView
for t in _.range(0, roomThickness+1) for t in _.range(0, roomThickness+1)
for i in _.range(rect.x - rect.width/2 - (t-1) * preset.borderSize, rect.x + rect.width/2 + t * preset.borderSize, preset.borderSize) for i in _.range(rect.x - rect.width/2 - (t-1) * preset.borderSize, rect.x + rect.width/2 + t * preset.borderSize, preset.borderSize)
# Bottom wall
thang = { thang = {
'id': @getRandomThang(clusters[room.cluster].thangs) 'id': @getRandomThang(clusters[room.cluster].thangs)
'pos': { 'pos': {
@ -295,6 +388,18 @@ module.exports = class TerrainRandomizeModal extends ModalView
thang.pos.y -= preset.borderSize/3 thang.pos.y -= preset.borderSize/3
@addThang thang unless i is bottomDoorX and t isnt roomThickness and bottomDoor @addThang thang unless i is bottomDoorX and t isnt roomThickness and bottomDoor
if t is roomThickness and i isnt rect.x - rect.width/2 - (t-1) * preset.borderSize and preset.type is 'dungeon'
if ( i isnt bottomDoorX and i isnt bottomDoorX + preset.borderSize ) or not bottomDoor
@addThang {
'id': @getRandomThang(clusters['torch'].thangs)
'pos': {
'x': thang.pos.x - preset.borderSize / 2
'y': thang.pos.y + preset.borderSize / 2
}
'margin': clusters['torch'].margin
}
# Top wall
thang = { thang = {
'id': @getRandomThang(clusters[room.cluster].thangs) 'id': @getRandomThang(clusters[room.cluster].thangs)
'pos': { 'pos': {
@ -310,6 +415,7 @@ module.exports = class TerrainRandomizeModal extends ModalView
for t in _.range(0, roomThickness) for t in _.range(0, roomThickness)
for i in _.range(rect.y - rect.height/2 - t * preset.borderSize, rect.y + rect.height/2 + (t+1) * preset.borderSize, preset.borderSize) for i in _.range(rect.y - rect.height/2 - t * preset.borderSize, rect.y + rect.height/2 + (t+1) * preset.borderSize, preset.borderSize)
# Left wall
@addThang { @addThang {
'id': @getRandomThang(clusters[room.cluster].thangs) 'id': @getRandomThang(clusters[room.cluster].thangs)
'pos': { 'pos': {
@ -319,6 +425,7 @@ module.exports = class TerrainRandomizeModal extends ModalView
'margin': clusters[room.cluster].margin 'margin': clusters[room.cluster].margin
} }
# Right wall
@addThang { @addThang {
'id': @getRandomThang(clusters[room.cluster].thangs) 'id': @getRandomThang(clusters[room.cluster].thangs)
'pos': { 'pos': {
@ -328,6 +435,35 @@ module.exports = class TerrainRandomizeModal extends ModalView
'margin': clusters[room.cluster].margin 'margin': clusters[room.cluster].margin
} }
buildBarrels: (preset, presetSize, decoration) ->
rect = {
'width':presetSize.sizeFactor * ( _.random( decoration.width[0], decoration.width[1] ) )
'height':presetSize.sizeFactor * ( _.random( decoration.height[0], decoration.height[1] ) )
}
x = [ rect.width/2 + preset.borderSize , presetSize.x - rect.width/2 - preset.borderSize ]
y = [ rect.height/2 + preset.borderSize , presetSize.y - rect.height/2 - 2 * preset.borderSize ]
for i in x
for j in y
if _.random(100) < 40
rect = {
'x': i
'y': j
'width': rect.width
'height': rect.height
}
if @addRect rect
for num in _.range( _.random( decoration.numBarrels[0], decoration.numBarrels[1] ) )
while not @addThang {
'id': @getRandomThang(clusters[decoration.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[decoration.cluster].margin
}
continue
addThang: (thang) -> addThang: (thang) ->
if @falseCount > 100 if @falseCount > 100
console.log 'infinite loop', thang console.log 'infinite loop', thang
@ -348,7 +484,7 @@ module.exports = class TerrainRandomizeModal extends ModalView
@falseCount = 0 @falseCount = 0
return true return true
for existingRect in @rects 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++ @falseCount++
return false return false
@rects.push rect @rects.push rect