2019-03-27 01:05:29 -05:00
|
|
|
import * as I from 'immutable';
|
|
|
|
|
2019-04-28 23:45:03 -05:00
|
|
|
import {compose, EventEmitter} from '@avocado/core';
|
2019-03-25 19:03:34 -05:00
|
|
|
import {Rectangle, Vector} from '@avocado/math';
|
|
|
|
|
2019-05-13 21:07:51 -05:00
|
|
|
import {TileUpdatePacket} from './packets/tile-update.packet';
|
|
|
|
|
2019-09-29 13:19:57 -05:00
|
|
|
const CHUNK_AXIS = 10;
|
|
|
|
|
2019-03-25 19:03:34 -05:00
|
|
|
const decorate = compose(
|
2019-03-27 19:25:00 -05:00
|
|
|
EventEmitter,
|
2019-03-25 19:03:34 -05:00
|
|
|
Vector.Mixin('size', 'width', 'height', {
|
|
|
|
default: [0, 0],
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
2019-04-16 17:52:56 -05:00
|
|
|
export class Tiles extends decorate(class {}) {
|
2019-03-25 19:03:34 -05:00
|
|
|
|
2019-05-13 21:07:51 -05:00
|
|
|
constructor(json) {
|
2019-03-27 16:18:27 -05:00
|
|
|
super();
|
2019-09-29 13:19:57 -05:00
|
|
|
// this.chunks = [];
|
2019-05-13 21:07:51 -05:00
|
|
|
this.data = [];
|
|
|
|
if ('undefined' !== typeof json) {
|
|
|
|
this.fromJSON(json);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
acceptPacket(packet) {
|
2019-09-29 13:19:57 -05:00
|
|
|
// if (packet instanceof TileUpdatePacket) {
|
|
|
|
// const unpackedPosition = [
|
|
|
|
// packet.data.position & 0xFFFF,
|
|
|
|
// packet.data.position >> 16,
|
|
|
|
// ];
|
|
|
|
// this.setTileAt(unpackedPosition, packet.data.tile);
|
|
|
|
// }
|
2019-03-27 01:05:29 -05:00
|
|
|
}
|
|
|
|
|
2019-09-29 13:19:57 -05:00
|
|
|
// chunkIndexAtPosition(position) {
|
|
|
|
// const chunkCount = Vector.ceil(Vector.scale(this.size, 1 / CHUNK_AXIS));
|
|
|
|
// const chunkPosition = Vector.floor(Vector.scale(position, 1 / CHUNK_AXIS));
|
|
|
|
// const chunkIndex = chunkPosition[1] * chunkCount[0] + chunkPosition[0];
|
|
|
|
// return chunkIndex;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// static createChunkFromData(position, size, data) {
|
|
|
|
// const chunk = Array(CHUNK_AXIS * CHUNK_AXIS).fill(0);
|
|
|
|
// let chunkIndex = 0;
|
|
|
|
// const chunkPosition = Vector.scale(position, CHUNK_AXIS);
|
|
|
|
// let dataIndex = size[0] * chunkPosition[1] + chunkPosition[0];
|
|
|
|
// for (let y = 0; y < CHUNK_AXIS; ++y) {
|
|
|
|
// for (let x = 0; x < CHUNK_AXIS; ++x) {
|
|
|
|
// if (chunkPosition[0] < size[0] && chunkPosition[1] < size[1]) {
|
|
|
|
// chunk[chunkIndex] = data[dataIndex];
|
|
|
|
// }
|
|
|
|
// chunkIndex += 1;
|
|
|
|
// chunkPosition[0] += 1;
|
|
|
|
// dataIndex += 1;
|
|
|
|
// }
|
|
|
|
// chunkPosition[0] -= CHUNK_AXIS;
|
|
|
|
// chunkPosition[1] += 1;
|
|
|
|
// dataIndex -= CHUNK_AXIS;
|
|
|
|
// dataIndex += size[0];
|
|
|
|
// }
|
|
|
|
// return chunk;
|
|
|
|
// }
|
|
|
|
|
|
|
|
// forEachTile(fn) {
|
|
|
|
// let [x, y] = [0, 0];
|
|
|
|
// let [width, height] = this.size;
|
|
|
|
// let i = 0;
|
|
|
|
// for (let k = 0; k < height; ++k) {
|
|
|
|
// for (let j = 0; j < width; ++j) {
|
|
|
|
// fn(this.data[i], x, y, i);
|
|
|
|
// ++i;
|
|
|
|
// ++x;
|
|
|
|
// }
|
|
|
|
// x = 0;
|
|
|
|
// ++y;
|
|
|
|
// }
|
|
|
|
// }
|
2019-04-12 20:16:31 -05:00
|
|
|
|
|
|
|
fromJSON(json) {
|
|
|
|
if (json.size) {
|
2019-09-29 13:19:57 -05:00
|
|
|
super.size = json.size;
|
2019-04-12 20:16:31 -05:00
|
|
|
}
|
2019-09-29 13:19:57 -05:00
|
|
|
// this.chunks = [];
|
|
|
|
// const chunkCount = Vector.ceil(Vector.scale(this.size, 1 / CHUNK_AXIS));
|
|
|
|
// if (json.data && json.data.length > 0) {
|
|
|
|
// for (let y = 0; y < chunkCount[1]; ++y) {
|
|
|
|
// for (let x = 0; x < chunkCount[0]; ++x) {
|
|
|
|
// this.chunks.push(Tiles.createChunkFromData(
|
|
|
|
// [x, y],
|
|
|
|
// this.size,
|
|
|
|
// json.data
|
|
|
|
// ));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// if (json.chunks && json.chunks.length > 0) {
|
|
|
|
|
|
|
|
// }
|
|
|
|
if (json.data && json.data.length > 0) {
|
2019-05-13 21:07:51 -05:00
|
|
|
this.data = json.data.slice(0);
|
2019-04-12 20:16:31 -05:00
|
|
|
}
|
2019-09-29 13:19:57 -05:00
|
|
|
// Instantiate blank tiles if we got size but no data.
|
|
|
|
else {
|
|
|
|
this.data = Array(Vector.area(this.size)).fill(0);
|
|
|
|
}
|
2019-04-12 20:16:31 -05:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2019-09-29 13:19:57 -05:00
|
|
|
// indexAt(position) {
|
|
|
|
// return this.width * position[1] + position[0];
|
|
|
|
// }
|
2019-06-12 22:15:56 -05:00
|
|
|
|
2019-09-29 13:19:57 -05:00
|
|
|
// packetsForUpdate() {
|
|
|
|
// const packetsForUpdate = this.updatePackets;
|
|
|
|
// this.updatePackets = [];
|
|
|
|
// return packetsForUpdate;
|
|
|
|
// }
|
2019-05-27 21:51:21 -05:00
|
|
|
|
2019-03-25 19:03:34 -05:00
|
|
|
get rectangle() {
|
|
|
|
return Rectangle.compose([0, 0], this.size);
|
|
|
|
}
|
|
|
|
|
2019-05-27 18:13:09 -05:00
|
|
|
setTileAt(position, tile) {
|
|
|
|
const oldTile = this.tileAt(position);
|
2019-03-27 19:25:00 -05:00
|
|
|
if (oldTile === tile) {
|
|
|
|
return;
|
|
|
|
}
|
2019-05-27 18:13:09 -05:00
|
|
|
const index = position[1] * this.width + position[0];
|
2019-05-13 21:07:51 -05:00
|
|
|
if (index < 0 || index >= this.data.length) {
|
2019-03-25 20:49:16 -05:00
|
|
|
return;
|
|
|
|
}
|
2019-05-13 21:07:51 -05:00
|
|
|
this.data[index] = tile;
|
2019-05-27 21:51:21 -05:00
|
|
|
const packedPosition = position[1] << 16 | position[0];
|
2019-09-29 13:19:57 -05:00
|
|
|
// this.updatePackets.push(new TileUpdatePacket({
|
|
|
|
// position: packedPosition,
|
|
|
|
// tile,
|
|
|
|
// }));
|
2019-03-27 19:25:00 -05:00
|
|
|
this.emit('dataChanged');
|
2019-03-25 20:49:16 -05:00
|
|
|
}
|
|
|
|
|
2019-09-29 13:19:57 -05:00
|
|
|
get size() {
|
|
|
|
return super.size;
|
|
|
|
}
|
|
|
|
|
|
|
|
set size(size) {
|
|
|
|
super.size = size;
|
|
|
|
// const newChunks = [];
|
|
|
|
// const chunkCount = Vector.ceil(Vector.div(size, [CHUNK_AXIS, CHUNK_AXIS]));
|
|
|
|
// const chunkLinearCount = Vector.area(chunkCount);
|
|
|
|
// for (let i = 0; i < chunkLinearCount; ++i) {
|
|
|
|
// newChunks.
|
|
|
|
// }
|
|
|
|
// for (let y = 0; y < chunkCount[1]; y++) {
|
|
|
|
// for (let x = 0; x < chunkCount[0]; x++) {
|
|
|
|
// newChunks[y][x]
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
2019-03-25 19:03:34 -05:00
|
|
|
slice(rectangle) {
|
|
|
|
const tilesRectangle = this.rectangle;
|
2019-03-25 20:49:42 -05:00
|
|
|
// Get intersection.
|
2019-03-25 19:03:34 -05:00
|
|
|
if (!Rectangle.intersects(rectangle, tilesRectangle)) {
|
|
|
|
return [];
|
|
|
|
}
|
2019-03-25 20:49:42 -05:00
|
|
|
let [x, y, sliceWidth, sliceHeight] = Rectangle.intersection(
|
|
|
|
rectangle,
|
|
|
|
tilesRectangle,
|
|
|
|
);
|
|
|
|
// No muls in the loop.
|
|
|
|
let sliceRow = y * sliceWidth;
|
|
|
|
const dataWidth = this.width;
|
|
|
|
let dataRow = y * dataWidth;
|
|
|
|
// Copy slice.
|
|
|
|
const slice = new Array(sliceWidth * sliceHeight);
|
|
|
|
for (let j = 0; j < sliceHeight; ++j) {
|
|
|
|
for (let i = 0; i < sliceWidth; ++i) {
|
2019-05-13 21:07:51 -05:00
|
|
|
slice[sliceRow + x] = this.data[dataRow + x];
|
2019-03-25 19:03:34 -05:00
|
|
|
x++;
|
|
|
|
}
|
2019-03-25 20:49:42 -05:00
|
|
|
sliceRow += sliceWidth;
|
|
|
|
dataRow += dataWidth;
|
|
|
|
x -= sliceWidth;
|
2019-03-25 19:03:34 -05:00
|
|
|
}
|
|
|
|
return slice;
|
|
|
|
}
|
|
|
|
|
2019-05-27 18:13:09 -05:00
|
|
|
tileAt(position) {
|
2019-09-29 13:19:57 -05:00
|
|
|
const index = this.indexAt(position);
|
|
|
|
if (index < 0 || index >= this.data.length) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
return this.data[index];
|
2019-03-25 19:03:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
toJSON() {
|
2019-03-25 20:50:11 -05:00
|
|
|
return {
|
2019-09-29 13:19:57 -05:00
|
|
|
size: this.size,
|
|
|
|
data: this.data,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
toNetwork(informed) {
|
|
|
|
return {
|
|
|
|
size: this.size,
|
|
|
|
data: this.data,
|
2019-03-25 20:50:11 -05:00
|
|
|
};
|
2019-03-25 19:03:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|