class Grid { constructor(config) { this.width = config.width; this.height = config.height; this.collision = config.collision ?? {}; } getCoords(tileX, tileY) { const x = 0 + tileX * 24 + !(tileY % 2) * (24 / 2) const y = 0 + tileY * (18 / 2); return { x, y }; } getCell(roundedX, roundedY) { const x = roundedX - 0; const y = roundedY - 0; const isEven = ((Math.floor(y / 9) * 9 - 9) / 18) % 1 !== 0; const xw = isEven ? Math.floor(x / 24) : Math.floor((x + 12) / 24); const xh = Math.floor(y / (18 / 2)); return { xw, xh }; } isValidNode(node) { const blockedTile = this.collision[`${node.xw}-${node.xh}`]; return (!blockedTile && node.xw > 0 && node.xh > 0 && node.xw < this.width / 24 && node.xh < (this.height * 2) / 18); } randomNodeNear(nearToX, nearToY, radius) { let r = radius * Math.sqrt(Math.random()); let a = 2 * Math.PI * Math.random(); let nearX = Math.round(r * Math.cos(a) + nearToX); let nearY = Math.round(r * Math.sin(a) + nearToY); let triedNode = this.getCell(nearX, nearY); const { xw, xh } = triedNode; let { x, y } = this.getCoords(xw, xh); while (!this.isValidNode(triedNode) || (x === nearToX && y === nearToY) || Math.pow(x - nearToX, 2) + Math.pow(y - nearToY, 2) < Math.pow(500, 2)) { r = radius * Math.sqrt(Math.random()); a = 2 * Math.PI * Math.random(); nearX = Math.round(r * Math.cos(a) + nearToX); nearY = Math.round(r * Math.sin(a) + nearToY); triedNode = this.getCell(nearX, nearY); const { xw, xh } = triedNode; const coords = this.getCoords(xw, xh); x = coords.x; y = coords.y; }; return { x, y }; } randomNodeInArea(area) { let xw = 0; let xh = 0; const minimumWidth = area.x - area.width / 2; const maximumWidth = area.x + area.width / 2; const minimumHeight = area.y - area.height / 2; const maximumHeight = area.y + area.height / 2; do { xw = Math.floor((Math.random() * (maximumWidth - minimumWidth + 1) + minimumWidth) / 24); xh = Math.floor((Math.random() * (maximumHeight - minimumHeight + 1) + minimumHeight) / (18 / 2)); } while (!this.isValidNode({ xw, xh })); return this.getCoords(xw, xh); } randomNode(percentage) { let xw = 0; let xh = 0; if (!percentage) percentage = 0; percentage /= 200; const minimumWidth = 0 + this.width * percentage; const maximumWidth = this.width * (1 - percentage); const minimumHeight = 0 + this.height * percentage; const maximumHeight = this.height * (1 - percentage); do { xw = Math.floor((Math.random() * (maximumWidth - minimumWidth + 1) + minimumWidth) / 24); xh = Math.floor((Math.random() * (maximumHeight - minimumHeight + 1) + minimumHeight) / (18 / 2)); } while (!this.isValidNode({ xw, xh })); return this.getCoords(xw, xh); } getNodeNeighbours(node) { const { xw, xh } = node; let rightdown, leftdown, rightup, leftup; if (node.xh % 2 !== 0) { rightdown = { xw, xh: xh + 1 }; leftdown = { xw: xw - 1, xh: xh + 1 }; rightup = { xw, xh: xh - 1 }; leftup = { xw: xw - 1, xh: xh - 1 }; } else { rightdown = { xw: xw + 1, xh: xh + 1 }; leftdown = { xw: xw, xh: xh + 1 }; rightup = { xw: xw + 1, xh: xh - 1 }; leftup = { xw: xw, xh: xh - 1 }; }; return [rightup, leftup, leftdown, rightdown]; } }; module.exports = Grid;