565 lines
16 KiB
Plaintext
565 lines
16 KiB
Plaintext
import standard;
|
|
import random;
|
|
|
|
//constants mapped to the given atlas file "tileset.png"
|
|
var tileset: [string : [int]] const = [
|
|
"empty": [-1, -1, 0],
|
|
|
|
"temple-pillar": [0, 0, 0],
|
|
|
|
"temple-floor-0": [0, 1, 1],
|
|
"temple-floor-1": [1, 1, 1],
|
|
"temple-floor-2": [2, 1, 1],
|
|
"temple-floor-3": [3, 1, 1],
|
|
|
|
"temple-wall-t": [0, 2, 0],
|
|
"temple-wall-b": [1, 2, 0],
|
|
"temple-wall-l": [2, 2, 0],
|
|
"temple-wall-r": [3, 2, 0],
|
|
|
|
"temple-corner-tl": [0, 3, 0],
|
|
"temple-corner-tr": [1, 3, 0],
|
|
"temple-corner-bl": [2, 3, 0],
|
|
"temple-corner-br": [3, 3, 0],
|
|
|
|
"temple-edge-tl": [0, 4, 0],
|
|
"temple-edge-tr": [1, 4, 0],
|
|
"temple-edge-bl": [3, 4, 0], //would be great if these were the right way around...
|
|
"temple-edge-br": [2, 4, 0]
|
|
];
|
|
|
|
var themes: [string] const = [
|
|
"temple"
|
|
];
|
|
|
|
|
|
//constants for generating maps
|
|
var ROOM_MIN_WIDTH: int const = 4; //minimum safe value 4
|
|
var ROOM_MIN_HEIGHT: int const = 4;
|
|
|
|
var ROOM_MAX_WIDTH: int const = 12; //minimum safe value ROOM_MIN_* + 1
|
|
var ROOM_MAX_HEIGHT: int const = 12;
|
|
|
|
var CELL_WIDTH: int const = 16; //minimum safe value ROOM_MAX_* + 4
|
|
var CELL_HEIGHT: int const = 16;
|
|
|
|
var CELL_COUNT_X: int const = 3;
|
|
var CELL_COUNT_Y: int const = 3;
|
|
|
|
var MAP_GRID_WIDTH: int const = CELL_WIDTH * CELL_COUNT_X;
|
|
var MAP_GRID_HEIGHT: int const = CELL_HEIGHT * CELL_COUNT_Y;
|
|
|
|
|
|
//raw interleaved tile data
|
|
var tilemap: [int] = null;
|
|
|
|
//room metadata for placing entities
|
|
var metadata: [[[string: any]]] = null;
|
|
|
|
//public functions
|
|
fn generateTilemapData(rng: opaque) {
|
|
//generate a grid filled with only empty tiles, as a starting point
|
|
tilemap = [];
|
|
|
|
for (var j: int = 0; j < CELL_COUNT_Y * CELL_HEIGHT; j++) {
|
|
for (var i: int = 0; i < CELL_COUNT_X * CELL_WIDTH; i++) {
|
|
tilemap.push(-1); //x
|
|
tilemap.push(-1); //y
|
|
tilemap.push(0); //collision
|
|
}
|
|
}
|
|
|
|
//generate the metadata of each room
|
|
var roomData = [];
|
|
|
|
for (var i: int = 0; i < CELL_COUNT_X; i++) {
|
|
|
|
var inner = []; //inner decl
|
|
|
|
for (var j: int = 0; j < CELL_COUNT_Y; j++) {
|
|
var metadata = generateRoomMetadata(rng,
|
|
//add a border within the cell that the doors can't touch
|
|
i * CELL_WIDTH + 1,
|
|
j * CELL_HEIGHT + 1,
|
|
CELL_WIDTH - 2,
|
|
CELL_HEIGHT - 2
|
|
);
|
|
|
|
inner.push(metadata); //BUG: see Toy #70
|
|
}
|
|
|
|
roomData.push(inner);
|
|
}
|
|
|
|
//generate corridor metadata
|
|
var corridorData = generateCorridorData(rng);
|
|
|
|
//etch each tile string into the tilemap
|
|
for (var j: int = 0; j < CELL_COUNT_Y; j++) {
|
|
for (var i: int = 0; i < CELL_COUNT_X; i++) {
|
|
etchRoom(rng, roomData[i][j]);
|
|
}
|
|
}
|
|
|
|
//etch the corridors
|
|
etchCorridors(roomData, corridorData, rng);
|
|
|
|
//etch the walls with marching squares, based on the room's themes
|
|
etchWalls(roomData);
|
|
|
|
//save the metadata for later retrieval
|
|
metadata = roomData;
|
|
}
|
|
|
|
fn generateRoomMetadata(rng: opaque, left: int, top: int, width: int, height: int) {
|
|
//I expected this line to break, but I must've fixed calls within indexes at some point
|
|
var theme: string = themes[rng.generateRandomNumber() % themes.length()];
|
|
|
|
var x: int = rng.generateRandomNumber() % (ROOM_MAX_WIDTH - width) + left;
|
|
var y: int = rng.generateRandomNumber() % (ROOM_MAX_HEIGHT - height) + top;
|
|
var w: int = rng.generateRandomNumber() % (ROOM_MAX_WIDTH - ROOM_MIN_WIDTH) + ROOM_MIN_WIDTH;
|
|
var h: int = rng.generateRandomNumber() % (ROOM_MAX_HEIGHT - ROOM_MIN_HEIGHT) + ROOM_MIN_HEIGHT;
|
|
|
|
var doorX: int = x + 1 + rng.generateRandomNumber() % (w - 2);
|
|
var doorY: int = y + 1 + rng.generateRandomNumber() % (h - 2);
|
|
|
|
var metadata: [string: any] = [
|
|
"theme" : theme,
|
|
"x" : x,
|
|
"y" : y,
|
|
"w" : w,
|
|
"h" : h,
|
|
"doorX": doorX,
|
|
"doorY": doorY
|
|
];
|
|
|
|
return metadata;
|
|
}
|
|
|
|
fn etchRoom(rng: opaque, metadata: [string: any]) {
|
|
//NOTE: using unrolled assignments in this function for speed reasons
|
|
|
|
var theme: string = metadata["theme"];
|
|
var x: int = metadata["x"];
|
|
var y: int = metadata["y"];
|
|
var w: int = metadata["w"];
|
|
var h: int = metadata["h"];
|
|
|
|
//etch the floor-space
|
|
for (var j: int = y; j < y + h; j++) {
|
|
for (var i: int = x; i < x + w; i++) {
|
|
var floorIndex = rng.generateRandomNumber() % 4; //NOTE: there might not always be only 4 floor sprites
|
|
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 0] = tileset[theme + "-floor-" + string floorIndex][0];
|
|
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 1] = tileset[theme + "-floor-" + string floorIndex][1];
|
|
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 2] = tileset[theme + "-floor-" + string floorIndex][2];
|
|
}
|
|
}
|
|
}
|
|
|
|
fn generateCorridorData(rng: opaque) {
|
|
var result = [];
|
|
|
|
//generate the corridor graph
|
|
for (var i: int = 0; i < CELL_COUNT_X; i++) {
|
|
var inner = []; //inner decl
|
|
for (var j: int = 0; j < CELL_COUNT_Y; j++) {
|
|
inner.push([:]);
|
|
}
|
|
result.push(inner);
|
|
}
|
|
|
|
//while the corridors are incomplete
|
|
while (!checkCorridorsValid(result)) {
|
|
//randomly link two neighbouring rooms that aren't already linked
|
|
result = randomlyLinkTwoRooms(rng, result);
|
|
}
|
|
|
|
//finally
|
|
return result;
|
|
}
|
|
|
|
fn checkCorridorsValid(corridors) {
|
|
//mark all rooms connected to [0, 0]
|
|
fn markRoomAndFlood(x: int, y: int) {
|
|
//base case
|
|
if (corridors[x][y]["marked"] == true) {
|
|
return;
|
|
}
|
|
|
|
//this room is now marked
|
|
corridors[x][y]["marked"] = true;
|
|
|
|
//flood to neighbouring rooms
|
|
if (corridors[x][y]["-1,0"] == true) {
|
|
markRoomAndFlood(x-1, y);
|
|
}
|
|
|
|
if (corridors[x][y]["+1,0"] == true) {
|
|
markRoomAndFlood(x+1, y);
|
|
}
|
|
|
|
if (corridors[x][y]["0,-1"] == true) {
|
|
markRoomAndFlood(x, y-1);
|
|
}
|
|
|
|
if (corridors[x][y]["0,+1"] == true) {
|
|
markRoomAndFlood(x, y+1);
|
|
}
|
|
}
|
|
|
|
//kickoff
|
|
markRoomAndFlood(0, 0);
|
|
|
|
//look for any unmarked rooms
|
|
for (var i: int = 0; i < CELL_COUNT_X; i++) {
|
|
for (var j: int = 0; j < CELL_COUNT_Y; j++) {
|
|
if (corridors[i][j]["marked"] != true) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
//all rooms are connected
|
|
return true;
|
|
}
|
|
|
|
fn randomlyLinkTwoRooms(rng: opaque, corridors) {
|
|
//the number of corridors
|
|
var count: int = CELL_COUNT_X * (CELL_COUNT_Y - 1) + (CELL_COUNT_X - 1) * CELL_COUNT_Y;
|
|
|
|
//find a random corridor index
|
|
for (var index: int = rng.generateRandomNumber() % count; /* EMPTY */ ; index = (index + 1) % count) {
|
|
//determine where the corridor is
|
|
if (index < floor(count / 2)) {
|
|
var x: int = floor(index % (CELL_COUNT_X - 1));
|
|
var y: int = floor(index / (CELL_COUNT_Y - 1));
|
|
|
|
//left-right
|
|
if (corridors[x][y]["+1,0"] == true || corridors[x+1][y]["-1,0"] == true) {
|
|
continue;
|
|
}
|
|
|
|
corridors[x][y]["+1,0"] = true;
|
|
corridors[x+1][y]["-1,0"] = true;
|
|
break;
|
|
}
|
|
else {
|
|
var idx = index - floor(count / 2); //adjust
|
|
var x: int = floor(idx / (CELL_COUNT_X - 1));
|
|
var y: int = floor(idx % (CELL_COUNT_Y - 1));
|
|
|
|
//top-bottom
|
|
if (corridors[x][y]["0,+1"] == true || corridors[x][y+1]["0,-1"] == true) {
|
|
continue;
|
|
}
|
|
|
|
corridors[x][y]["0,+1"] = true;
|
|
corridors[x][y+1]["0,-1"] = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
return corridors;
|
|
}
|
|
|
|
fn etchCorridors(roomData, corridorData, rng) {
|
|
//for each room that has a corridor, etch that corridor
|
|
for (var i: int = 0; i < CELL_COUNT_X; i++) {
|
|
for (var j: int = 0; j < CELL_COUNT_Y; j++) {
|
|
if (corridorData[i][j]["+1,0"] == true) {
|
|
//mark me and my linked room as false, then etch our connection
|
|
corridorData[i][j]["+1,0"] = false;
|
|
corridorData[i+1][j]["-1,0"] = false;
|
|
|
|
etchOneCorridor(
|
|
roomData[i][j]["doorX"],
|
|
roomData[i][j]["doorY"],
|
|
roomData[i+1][j]["doorX"],
|
|
roomData[i+1][j]["doorY"],
|
|
roomData[i][j]["theme"],
|
|
rng
|
|
);
|
|
}
|
|
|
|
if (corridorData[i][j]["-1,0"] == true) {
|
|
//mark me and my linked room as false, then etch our connection
|
|
corridorData[i][j]["-1,0"] = false;
|
|
corridorData[i-1][j]["+1,0"] = false;
|
|
|
|
etchOneCorridor(
|
|
roomData[i][j]["doorX"],
|
|
roomData[i][j]["doorY"],
|
|
roomData[i-1][j]["doorX"],
|
|
roomData[i-1][j]["doorY"],
|
|
roomData[i][j]["theme"],
|
|
rng
|
|
);
|
|
}
|
|
|
|
if (corridorData[i][j]["0,+1"] == true) {
|
|
//mark me and my linked room as false, then etch our connection
|
|
corridorData[i][j]["0,+1"] = false;
|
|
corridorData[i][j+1]["0,-1"] = false;
|
|
|
|
etchOneCorridor(
|
|
roomData[i][j]["doorX"],
|
|
roomData[i][j]["doorY"],
|
|
roomData[i][j+1]["doorX"],
|
|
roomData[i][j+1]["doorY"],
|
|
roomData[i][j]["theme"],
|
|
rng
|
|
);
|
|
}
|
|
|
|
if (corridorData[i][j]["0,-1"] == true) {
|
|
//mark me and my linked room as false, then etch our connection
|
|
corridorData[i][j]["0,-1"] = false;
|
|
corridorData[i][j-1]["0,+1"] = false;
|
|
|
|
etchOneCorridor(
|
|
roomData[i][j]["doorX"],
|
|
roomData[i][j]["doorY"],
|
|
roomData[i][j-1]["doorX"],
|
|
roomData[i][j-1]["doorY"],
|
|
roomData[i][j]["theme"],
|
|
rng
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn etchOneCorridor(x1, y1, x2, y2, theme, rng) {
|
|
//determine longest path, with a deliberate kink in the middle
|
|
if (x2 - x1 > y2 - y1) {
|
|
//determine half-length
|
|
var xdir = floor((x2 - x1) / 2);
|
|
|
|
//etch
|
|
etchLine(x1, y1, xdir, 0, theme, rng);
|
|
etchLine(x1 + xdir, y1, 0, y2-y1, theme, rng);
|
|
etchLine(x1 + xdir, y2, (x2 - x1) - xdir, 0, theme, rng);
|
|
}
|
|
else {
|
|
//determine half-length
|
|
var ydir = floor((y2 - y1) / 2);
|
|
|
|
//etch
|
|
etchLine(x1, y1, 0, ydir, theme, rng);
|
|
etchLine(x1, y1 + ydir, x2-x1, 0, theme, rng);
|
|
etchLine(x2, y1 + ydir, 0, (y2 - y1) - ydir, theme, rng);
|
|
}
|
|
}
|
|
|
|
fn etchLine(x: int, y: int, xLength: int, yLength: int, theme: string, rng: opaque) {
|
|
//lengths can be negative, so handle it
|
|
while (abs(xLength) > 0 || abs(yLength) > 0) {
|
|
//etch floor at this position
|
|
var floorIndex = rng.generateRandomNumber() % 4; //NOTE: there might not always be only 4 floor sprites
|
|
tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 0] = tileset[theme + "-floor-" + string floorIndex][0];
|
|
tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 1] = tileset[theme + "-floor-" + string floorIndex][1];
|
|
tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 2] = tileset[theme + "-floor-" + string floorIndex][2];
|
|
|
|
//tick down
|
|
if (abs(xLength) > 0) {
|
|
xLength -= sign(xLength);
|
|
x += sign(xLength);
|
|
}
|
|
|
|
if (abs(yLength) > 0) {
|
|
yLength -= sign(yLength);
|
|
y += sign(yLength);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn etchWalls(roomData) {
|
|
//zero'd signals
|
|
var signals: [string] = [];
|
|
|
|
for (var j: int = 0; j < CELL_COUNT_Y * CELL_HEIGHT; j++) {
|
|
for (var i: int = 0; i < CELL_COUNT_X * CELL_WIDTH; i++) {
|
|
signals.push(""); //empty
|
|
}
|
|
}
|
|
|
|
//determine the walls' layout from the tilemap
|
|
for (var i: int = 0; i < MAP_GRID_WIDTH; i++) {
|
|
for (var j: int = 0; j < MAP_GRID_HEIGHT; j++) {
|
|
signals[j * MAP_GRID_WIDTH + i] = parseTilemapAt(i, j);
|
|
}
|
|
}
|
|
|
|
//etch the walls into the tilemap, based on the room theme
|
|
for (var i: int = 0; i < MAP_GRID_WIDTH; i++) {
|
|
for (var j: int = 0; j < MAP_GRID_HEIGHT; j++) {
|
|
if (signals[j * MAP_GRID_WIDTH + i] == "") {
|
|
continue;
|
|
}
|
|
|
|
var theme = roomData[floor(i / CELL_WIDTH)][floor(j / CELL_HEIGHT)]["theme"];
|
|
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 0] = tileset[theme + "-" + signals[j * MAP_GRID_WIDTH + i]][0];
|
|
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 1] = tileset[theme + "-" + signals[j * MAP_GRID_WIDTH + i]][1];
|
|
tilemap[j * CELL_WIDTH * CELL_COUNT_X * 3 + i * 3 + 2] = tileset[theme + "-" + signals[j * MAP_GRID_WIDTH + i]][2];
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
//lets say snapshot looks like this
|
|
snapshot:
|
|
|
|
0, 0, 1
|
|
0, 0, 1
|
|
0, 0, 1
|
|
|
|
result should be "wall-l",
|
|
|
|
//lets say filter looks like this
|
|
filter:
|
|
|
|
1 1 1 1 1
|
|
1 0 0 0 1
|
|
1 0 0 0 1
|
|
1 0 0 0 1
|
|
1 1 1 1 1
|
|
|
|
find the position within the filter, that gives the result "wall-l"
|
|
|
|
//lets say result looks like this
|
|
|
|
"edge-br" "wall-b" "edge-bl"
|
|
"wall-r" "pillar" "wall-l"
|
|
"edge-tr" "wall-t" "edge-tl"
|
|
|
|
let's try this...
|
|
|
|
*/
|
|
|
|
/* 9x9
|
|
var marchingFilter: [int] const = [
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 0, 0, 0, 0, 0, 0, 0, 1,
|
|
1, 0, 0, 0, 0, 0, 0, 0, 1,
|
|
1, 0, 0, 1, 1, 1, 0, 0, 1,
|
|
1, 0, 0, 1, 1, 1, 0, 0, 1,
|
|
1, 0, 0, 1, 1, 1, 0, 0, 1,
|
|
1, 0, 0, 0, 0, 0, 0, 0, 1,
|
|
1, 0, 0, 0, 0, 0, 0, 0, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1
|
|
];
|
|
|
|
var marchingFilterResult: [string] const = [
|
|
"", "", "", "", "", "", "", "", "",
|
|
"", "edge-tr", "wall-b", "wall-b", "wall-b", "wall-b", "wall-b", "edge-tl", "",
|
|
"", "wall-r", "corner-tl", "wall-t", "wall-t", "wall-t", "corner-tr", "wall-l", "",
|
|
"", "wall-r", "wall-l", "", "", "", "wall-r", "wall-l", "",
|
|
"", "wall-r", "wall-l", "", "", "", "wall-r", "wall-l", "",
|
|
"", "wall-r", "wall-l", "", "", "", "wall-r", "wall-l", "",
|
|
"", "wall-r", "corner-bl", "wall-b", "wall-b", "wall-b", "corner-br", "wall-l", "",
|
|
"", "edge-br", "wall-t", "wall-t", "wall-t", "wall-t", "wall-t", "edge-bl", "",
|
|
"", "", "", "", "", "", "", "", ""
|
|
];
|
|
*/
|
|
|
|
|
|
//this is a nightmare
|
|
var marchingFilter: [int] const = [
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
|
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
|
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
|
1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1,
|
|
1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1,
|
|
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
|
1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1,
|
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
|
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
|
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
|
];
|
|
|
|
var marchingFilterResult: [string] const = [
|
|
"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,
|
|
"" ,"" ,"edge-tl" ,"wall-b" ,"wall-b" ,"wall-b" ,"wall-b" ,"wall-b" ,"wall-b" ,"edge-tr" ,"" ,"" ,
|
|
"" ,"edge-tl" ,"corner-br" ,"" ,"corner-tl" ,"wall-t" ,"wall-t" ,"corner-tr" ,"" ,"corner-bl" ,"edge-tr" ,"" ,
|
|
"" ,"wall-r" ,"" ,"" ,"wall-l" ,"" ,"" ,"wall-r" ,"" ,"" ,"wall-l" ,"" ,
|
|
"" ,"wall-r" ,"corner-tl" ,"wall-t" ,"edge-br" ,"" ,"" ,"edge-bl" ,"wall-t" ,"corner-tr" ,"wall-l" ,"" ,
|
|
"" ,"wall-r" ,"wall-l" ,"" ,"" ,"" ,"" ,"" ,"" ,"wall-r" ,"wall-l" ,"" ,
|
|
"" ,"wall-r" ,"wall-l" ,"" ,"" ,"" ,"" ,"" ,"" ,"wall-r" ,"wall-l" ,"" ,
|
|
"" ,"wall-r" ,"corner-bl" ,"wall-b" ,"edge-tr" ,"" ,"" ,"edge-tl" ,"wall-b" ,"corner-br" ,"wall-l" ,"" ,
|
|
"" ,"wall-r" ,"" ,"" ,"wall-l" ,"" ,"" ,"wall-r" ,"" ,"" ,"wall-l" ,"" ,
|
|
"" ,"edge-bl" ,"corner-tr" ,"" ,"corner-bl" ,"wall-b" ,"wall-b" ,"corner-br" ,"" ,"corner-tl" ,"edge-br" ,"" ,
|
|
"" ,"" ,"edge-bl" ,"wall-t" ,"wall-t" ,"wall-t" ,"wall-t" ,"wall-t" ,"wall-t" ,"edge-br" ,"" ,"" ,
|
|
"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,"" ,""
|
|
];
|
|
|
|
|
|
//if walkable is below, then return top, etc.
|
|
fn parseTilemapAt(x: int, y: int) {
|
|
//parse based on walkability, for now
|
|
if (tilemap[y * CELL_WIDTH * CELL_COUNT_X * 3 + x * 3 + 2] != 0) {
|
|
return ""; //empty
|
|
}
|
|
|
|
//generate the snapshot of the current position
|
|
var snapshot = generateSnapshotAt(x, y);
|
|
|
|
//find the snapshot's position within the filter
|
|
for (var i: int = 0; i < 12 -2; i++) {
|
|
for (var j: int = 0; j < 12 -2; j++) {
|
|
if (
|
|
marchingFilter[(j + 0) * 12 + (i + 0)] == snapshot[0 * 3 + 0] &&
|
|
marchingFilter[(j + 0) * 12 + (i + 1)] == snapshot[0 * 3 + 1] &&
|
|
marchingFilter[(j + 0) * 12 + (i + 2)] == snapshot[0 * 3 + 2] &&
|
|
|
|
marchingFilter[(j + 1) * 12 + (i + 0)] == snapshot[1 * 3 + 0] &&
|
|
marchingFilter[(j + 1) * 12 + (i + 1)] == snapshot[1 * 3 + 1] &&
|
|
marchingFilter[(j + 1) * 12 + (i + 2)] == snapshot[1 * 3 + 2] &&
|
|
|
|
marchingFilter[(j + 2) * 12 + (i + 0)] == snapshot[2 * 3 + 0] &&
|
|
marchingFilter[(j + 2) * 12 + (i + 1)] == snapshot[2 * 3 + 1] &&
|
|
marchingFilter[(j + 2) * 12 + (i + 2)] == snapshot[2 * 3 + 2]
|
|
)
|
|
{
|
|
return marchingFilterResult[(j+1) * 12 + (i+1)];
|
|
}
|
|
}
|
|
}
|
|
|
|
//anything else, just plop down a pillar
|
|
fn nonZero(key: int, value: int) {
|
|
return value != 0;
|
|
}
|
|
|
|
if (snapshot.some(nonZero)) {
|
|
return "pillar";
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
fn generateSnapshotAt(x: int, y: int) {
|
|
var result: [int] = [];
|
|
|
|
for (var j: int = -1; j < 2; j++) {
|
|
for (var i: int = -1; i < 2; i++) {
|
|
if (x + i < 0 || y + j < 0 || x + i >= MAP_GRID_WIDTH || y + j >= MAP_GRID_HEIGHT) {
|
|
result.push(0);
|
|
}
|
|
else {
|
|
result.push(tilemap[(y+j) * CELL_WIDTH * CELL_COUNT_X * 3 + (x+i) * 3 + 2] != 0 ? 1 : 0); //walkable
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//polyfill
|
|
fn sign(x) {
|
|
if (x > 0) return 1;
|
|
return -1;
|
|
}
|