mapgen/game/maze.coffee

211 lines
7.7 KiB
CoffeeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class Maze
# карта игры, см. map.ods
# forest - лес
# shore - берег
# lake - озеро
# stream - ручей
# stones - камни
# rock - скалы
# mouth - устье
# bank - берег ручья
# cave - вход в пещеру
# ucavei - вход в подводную пещеру
# ucavee - выход из подводной пещеры
map: [
['forest', 'shore', 'lake', 'shore', 'forest', 'forest', 'shore', 'lake', 'stones','stones']
['shore', 'lake', 'lake', 'shore', 'forest', 'forest', 'shore', 'lake', 'stones','stones']
['lake', 'lake', 'lake', 'shore', 'shore', 'shore', 'shore', 'lake', 'stones','stones']
['lake', 'lake', 'lake', 'lake', 'lake', 'lake', 'lake', 'lake', 'stones','stones']
['lake', 'ucavei','lake', 'lake', 'lake', 'lake', 'lake', 'lake', 'shore', 'stones']
['lake', 'lake', 'lake', 'lake', 'lake', 'lake', 'lake', 'lake', 'shore', 'forest']
['shore', 'shore', 'shore', 'shore', 'shore', 'mouth', 'shore', 'shore', 'shore', 'forest']
['forest', 'forest','forest','forest','bank', 'stream', 'bank', 'forest','forest','forest']
['forest', 'cave', 'forest','forest','bank', 'stream', 'bank', 'forest','rock', 'rock' ]
['forest', 'forest','forest','forest','bank', 'stream', 'bank', 'forest','rock', 'rock' ]
['forest', 'forest','forest','forest','bank', 'stream', 'bank', 'forest','forest','forest']
['forest', 'rock', 'rock', 'forest','bank', 'stream', 'stream','bank', 'cave', 'forest']
['rock', 'rock', 'rock', 'forest','forest', 'bank', 'stream','bank', 'forest','forest']
['rock', 'ucavee','rock', 'forest','forest', 'bank', 'stream','stream','bank', 'forest']
['forest', 'forest','rock', 'forest','forest', 'forest', 'bank', 'stream','stream','bank' ]
['forest', 'forest','rock', 'forest','forest', 'forest', 'forest','bank', 'stream','bank' ]
]
gridData: (x, y) ->
maptype = @map[y][x]
# тип ячейки:
# lowstones - камни лёгкого наклона
# medstones - камни среднего наклона
# histones - камни крутого наклона
# rareforest - редкий лес
# thickforest - густой лес
# deepforest - дремучий лес
# thickshrub - густой кустарник
# openfield - открытое поле
# swamp - болото
# jungle - густые джунгли кустарника
# calmstream - тихая заводь ручья
# lake - озеро
# stream - ручей
# rock - скалы
# cave - пещера
# ucavei - вход в подводную пещеру
# ucavee - выход из подводной пещеры
switch maptype
when "forest"
rnd = salet.rnd.rand(20)
switch
when rnd < 4 then type = "thickforest"
when rnd < 8 then type = "rareforest"
when rnd < 12 then type = "openfield"
when rnd < 16 then type = "deepforest"
else type = "swamp"
when "stones"
rnd = salet.rnd.rand(12)
switch
when rnd < 4 then type = "lowstones"
when rnd < 8 then type = "medstones"
else type = "histones"
when "bank"
rnd = salet.rnd.rand(20)
switch
when rnd < 5 then type = "rareforest"
when rnd < 10 then type = "jungle"
when rnd < 15 then type = "thickforest"
else type = "calmstream"
else
type = maptype
return type
constructor: (@width, @height) ->
@data = []
for y in [0..(@height-1)]
for x in [0..(@width-1)]
@data[x] ?= []
@data[x][y] = new Maze.Cell
@data[x][y].setTag('type', @gridData(x, y))
# special encounters
specialEncounters = Object.keys(salet.specials).shuffle()
plotEncounters = ["meet1"]
# зд. возможно что две особых встречи упадут на одну клетку.
for event in specialEncounters
rnd = salet.rnd.rand(20) # вероятность 5%
if plotEncounters.indexOf(event) != false
rnd = 1 # вероятность 100%
if rnd != 1
continue
x = salet.rnd.rand(@width-1)
y = salet.rnd.rand(@height-1)
@data[x][y].setTag('special', event)
console.log "Special encounter set to (#{x}, #{y})"
return true
at: (x, y) -> return @data[x][y]
describe: (x, y, improv) ->
model = @data[x][y]
model = setAdjacent(model)
return improv.gen('description', model)
isEast: (x, y) -> return (x+1) <= (@width - 1)
isWest: (x, y) -> return (x-1) >= 0
isNorth: (x, y) -> return (y-1) >= 0
isSouth: (x, y) -> return (y+1) <= (@height - 1)
getEast: (x, y) ->
if @isEast(x, y)
return @at(x+1, y)
return false
getWest: (x, y) ->
if @isWest(x, y)
return @at(x-1, y)
return false
getNorth: (x, y) ->
if @isNorth(x, y)
return @at(x, y-1)
return false
getSouth: (x, y) ->
if @isSouth(x, y)
return @at(x+1, y+1)
return false
log: () ->
map = ""
for y in [0..(@height-1)]
for x in [0..(@width-1)]
map += @data[x][y].log()
map += "\n"
console.log map
bezier: (type) ->
halfheight = Math.floor(@height/2)
halfwidth = Math.floor(@width/2)
rnd = salet.rnd.rand(2)
if rnd == 1
# P0 is in the lower left quadrant
x0 = salet.rnd.rand(halfwidth)
y0 = halfheight + salet.rnd.rand(halfheight)
else
# P0 is in the lower right quadrant
x0 = halfwidth + salet.rnd.rand(halfwidth)
y0 = halfheight + salet.rnd.rand(halfheight)
rnd = salet.rnd.rand(2)
if rnd == 1
# P1 - higher left
x1 = salet.rnd.rand(halfwidth)
y1 = salet.rnd.rand(halfheight)
else
# P1 - lower left
x1 = salet.rnd.rand(halfwidth)
y1 = halfheight + salet.rnd.rand(halfheight)
# P2 - always higher right
x2 = halfwidth+salet.rnd.rand(halfwidth)
y2 = salet.rnd.rand(halfheight)
# quadratic bezier curve
for t in [0..@width] by 0.1
xp = Math.floor(Math.pow((1-t), 2)*x0+2*t*x1-2*Math.pow(t, 2)*x1+Math.pow(t, 2)*x2)
yp = Math.floor(Math.pow((1-t), 2)*y0+2*t*y1-2*Math.pow(t, 2)*y1+Math.pow(t, 2)*y2)
if @data[xp] == undefined or @data[xp][yp] == undefined
break
@data[xp][yp].setTag('type', type)
class Maze.Cell
constructor: () ->
@tags = []
getTag: (tagName) ->
for tag in @tags
if tag[0] == tagName
return tag[1]
return undefined
hasTag: (tagName) ->
for tag in @tags
if tag[0] == tagName
return true
return false
setTag: (tagName, value) ->
for tag, index in @tags
if tag[0] == tagName
@tags[index][1] = value
return true
@tags.push([tagName, value])
return true
setTagIfNotPresent: (tagName, value) ->
if @getTag(tagName) == undefined
@tags.push([tagName, value])
log: () ->
type = @getTag('type')
switch type
when "lowstones" then return "s"
when "medstones" then return "s"
when "histones" then return "s"
when "rareforest" then return "f"
when "thickforest" then return "f"
when "deepforest" then return "f"
when "thickshrub" then return "t"
when "openfield" then return "o"
when "swamp" then return "w"
when "jungle" then return "j"
when "calmstream" then return "c"
when "lake" then return "l"
when "stream" then return "s"
when "rock" then return "r"
when "cave" then return "a"
when "ucavee" then return "a"
when "ucavei" then return "a"
when "special" then return "!"
when "shore" then return "h"
else return "?"