211 lines
7.7 KiB
CoffeeScript
211 lines
7.7 KiB
CoffeeScript
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 "?"
|