mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 10:06:08 -05:00
77 lines
3 KiB
CoffeeScript
77 lines
3 KiB
CoffeeScript
# TODO: this thing needs a bit of thinking/testing for grid square alignments, exclusive vs. inclusive mins/maxes, etc.
|
|
|
|
module.exports = class Grid
|
|
constructor: (thangs, @width, @height, @padding=0, @left=0, @bottom=0) ->
|
|
@width = Math.ceil @width
|
|
@height = Math.ceil @height
|
|
@left = Math.floor @left
|
|
@bottom = Math.floor @bottom
|
|
@update thangs
|
|
|
|
update: (thangs) ->
|
|
@grid = []
|
|
for y in [0 .. @height]
|
|
@grid.push []
|
|
for x in [0 .. @width]
|
|
@grid[y].push []
|
|
for thang in thangs when thang.collides
|
|
rect = thang.rectangle()
|
|
[minX, maxX, minY, maxY] = [9001, -9001, 9001, -9001]
|
|
for v in rect.vertices()
|
|
minX = Math.min(minX, v.x - @padding)
|
|
minY = Math.min(minY, v.y - @padding)
|
|
maxX = Math.max(maxX, v.x + @padding)
|
|
maxY = Math.max(maxY, v.y + @padding)
|
|
for y in @columns minY, maxY
|
|
for x in @rows minX, maxX
|
|
@grid[y][x].push thang
|
|
|
|
contents: (gx, gy, width=1, height=1) ->
|
|
thangs = []
|
|
for y in @columns gy - height / 2, gy + height / 2
|
|
for x in @rows gx - width / 2, gx + width / 2
|
|
for thang in @grid[y][x]
|
|
thangs.push thang if thang.collides and not (thang in thangs) and thang.id isnt "Add Thang Phantom"
|
|
thangs
|
|
|
|
clampColumn: (y) ->
|
|
y = Math.max 0, Math.floor(y) - @bottom
|
|
Math.min @grid.length, Math.ceil(y) - @bottom
|
|
|
|
clampRow: (x) ->
|
|
x = Math.max 0, Math.floor(x) - @left
|
|
Math.min @grid[0]?.length or 0, Math.ceil(x) - @left
|
|
|
|
columns: (minY, maxY) ->
|
|
[@clampColumn(minY) ... @clampColumn(maxY)]
|
|
|
|
rows: (minX, maxX) ->
|
|
[@clampRow(minX) ... @clampRow(maxX)]
|
|
|
|
toString: ->
|
|
upsideDown = _.clone @grid
|
|
upsideDown.reverse()
|
|
(((if thangs.length then ("" + thangs.length) else " ") for thangs in row).join(" ") for row in upsideDown).join("\n")
|
|
|
|
wallNameFor: (gx, gy, tileSize) ->
|
|
# This doesn't work because we need to be able to place more than one tile at once
|
|
# Also since refactoring grid to have @left and @bottom, this logic doesn't work.
|
|
wallNames = ["dungeon_wall_000011011", "dungeon_wall_000110110", "dungeon_wall_000111111", "dungeon_wall_011011000", "dungeon_wall_110110000", "dungeon_wall_011011011", "dungeon_wall_110110110", "dungeon_wall_011111111", "dungeon_wall_110111111", "dungeon_wall_111111000", "dungeon_wall_111111011", "dungeon_wall_111111110", "dungeon_wall_111111111"]
|
|
s = "dungeon_wall_"
|
|
for y in [gy - tileSize, gy, gy + tileSize]
|
|
for x in [gx - tileSize, gx, gx + tileSize]
|
|
thangs = @grid[y][x]
|
|
if thangs.length is 0
|
|
if y == gy and x == gx
|
|
s += "1" # the center wall we're placing
|
|
else
|
|
s += "0"
|
|
else if thangs.length is 1 and (thangs[0].spriteName is "Dungeon Wall" or thangs[0].spriteName.match "dungeon_wall")
|
|
s += "1"
|
|
else
|
|
return null
|
|
if s is "dungeon_wall_000010000"
|
|
s = "dungeon_wall_111111000"
|
|
if s not in wallNames
|
|
return null
|
|
return s
|