/** * @class * Dungeon feature; has own .create() method */ ROT.Map.Feature = function() {} ROT.Map.Feature.prototype.isValid = function(canBeDugCallback) {} ROT.Map.Feature.prototype.create = function(digCallback) {} ROT.Map.Feature.prototype.debug = function() {} ROT.Map.Feature.createRandomAt = function(x, y, dx, dy, options) {} /** * @class Room * @augments ROT.Map.Feature * @param {int} x1 * @param {int} y1 * @param {int} x2 * @param {int} y2 * @param {int} [doorX] * @param {int} [doorY] */ ROT.Map.Feature.Room = function(x1, y1, x2, y2, doorX, doorY) { this._x1 = x1; this._y1 = y1; this._x2 = x2; this._y2 = y2; this._doors = {}; if (arguments.length > 4) { this.addDoor(doorX, doorY); } } ROT.Map.Feature.Room.extend(ROT.Map.Feature); /** * Room of random size, with a given doors and direction */ ROT.Map.Feature.Room.createRandomAt = function(x, y, dx, dy, options) { var min = options.roomWidth[0]; var max = options.roomWidth[1]; var width = min + Math.floor(ROT.RNG.getUniform()*(max-min+1)); var min = options.roomHeight[0]; var max = options.roomHeight[1]; var height = min + Math.floor(ROT.RNG.getUniform()*(max-min+1)); if (dx == 1) { /* to the right */ var y2 = y - Math.floor(ROT.RNG.getUniform() * height); return new this(x+1, y2, x+width, y2+height-1, x, y); } if (dx == -1) { /* to the left */ var y2 = y - Math.floor(ROT.RNG.getUniform() * height); return new this(x-width, y2, x-1, y2+height-1, x, y); } if (dy == 1) { /* to the bottom */ var x2 = x - Math.floor(ROT.RNG.getUniform() * width); return new this(x2, y+1, x2+width-1, y+height, x, y); } if (dy == -1) { /* to the top */ var x2 = x - Math.floor(ROT.RNG.getUniform() * width); return new this(x2, y-height, x2+width-1, y-1, x, y); } } /** * Room of random size, positioned around center coords */ ROT.Map.Feature.Room.createRandomCenter = function(cx, cy, options) { var min = options.roomWidth[0]; var max = options.roomWidth[1]; var width = min + Math.floor(ROT.RNG.getUniform()*(max-min+1)); var min = options.roomHeight[0]; var max = options.roomHeight[1]; var height = min + Math.floor(ROT.RNG.getUniform()*(max-min+1)); var x1 = cx - Math.floor(ROT.RNG.getUniform()*width); var y1 = cy - Math.floor(ROT.RNG.getUniform()*height); var x2 = x1 + width - 1; var y2 = y1 + height - 1; return new this(x1, y1, x2, y2); } /** * Room of random size within a given dimensions */ ROT.Map.Feature.Room.createRandom = function(availWidth, availHeight, options) { var min = options.roomWidth[0]; var max = options.roomWidth[1]; var width = min + Math.floor(ROT.RNG.getUniform()*(max-min+1)); var min = options.roomHeight[0]; var max = options.roomHeight[1]; var height = min + Math.floor(ROT.RNG.getUniform()*(max-min+1)); var left = availWidth - width - 1; var top = availHeight - height - 1; var x1 = 1 + Math.floor(ROT.RNG.getUniform()*left); var y1 = 1 + Math.floor(ROT.RNG.getUniform()*top); var x2 = x1 + width - 1; var y2 = y1 + height - 1; return new this(x1, y1, x2, y2); } ROT.Map.Feature.Room.prototype.addDoor = function(x, y) { this._doors[x+","+y] = 1; } /** * @param {function} */ ROT.Map.Feature.Room.prototype.getDoors = function(callback) { for (var key in this._doors) { var parts = key.split(","); callback(parseInt(parts[0]), parseInt(parts[1])); } } ROT.Map.Feature.Room.prototype.clearDoors = function() { this._doors = {}; return this; } ROT.Map.Feature.Room.prototype.debug = function() { console.log("room", this._x1, this._y1, this._x2, this._y2); } ROT.Map.Feature.Room.prototype.isValid = function(isWallCallback, canBeDugCallback) { var left = this._x1-1; var right = this._x2+1; var top = this._y1-1; var bottom = this._y2+1; for (var x=left; x<=right; x++) { for (var y=top; y<=bottom; y++) { if (x == left || x == right || y == top || y == bottom) { if (!isWallCallback(x, y)) { return false; } } else { if (!canBeDugCallback(x, y)) { return false; } } } } return true; } /** * @param {function} digCallback Dig callback with a signature (x, y, value). Values: 0 = empty, 1 = wall, 2 = door. Multiple doors are allowed. */ ROT.Map.Feature.Room.prototype.create = function(digCallback) { var left = this._x1-1; var right = this._x2+1; var top = this._y1-1; var bottom = this._y2+1; var value = 0; for (var x=left; x<=right; x++) { for (var y=top; y<=bottom; y++) { if (x+","+y in this._doors) { value = 2; } else if (x == left || x == right || y == top || y == bottom) { value = 1; } else { value = 0; } digCallback(x, y, value); } } } ROT.Map.Feature.Room.prototype.getCenter = function() { return [Math.round((this._x1 + this._x2)/2), Math.round((this._y1 + this._y2)/2)]; } ROT.Map.Feature.Room.prototype.getLeft = function() { return this._x1; } ROT.Map.Feature.Room.prototype.getRight = function() { return this._x2; } ROT.Map.Feature.Room.prototype.getTop = function() { return this._y1; } ROT.Map.Feature.Room.prototype.getBottom = function() { return this._y2; } /** * @class Corridor * @augments ROT.Map.Feature * @param {int} startX * @param {int} startY * @param {int} endX * @param {int} endY */ ROT.Map.Feature.Corridor = function(startX, startY, endX, endY) { this._startX = startX; this._startY = startY; this._endX = endX; this._endY = endY; this._endsWithAWall = true; } ROT.Map.Feature.Corridor.extend(ROT.Map.Feature); ROT.Map.Feature.Corridor.createRandomAt = function(x, y, dx, dy, options) { var min = options.corridorLength[0]; var max = options.corridorLength[1]; var length = min + Math.floor(ROT.RNG.getUniform()*(max-min+1)); return new this(x, y, x + dx*length, y + dy*length); } ROT.Map.Feature.Corridor.prototype.debug = function() { console.log("corridor", this._startX, this._startY, this._endX, this._endY); } ROT.Map.Feature.Corridor.prototype.isValid = function(isWallCallback, canBeDugCallback){ var sx = this._startX; var sy = this._startY; var dx = this._endX-sx; var dy = this._endY-sy; var length = 1 + Math.max(Math.abs(dx), Math.abs(dy)); if (dx) { dx = dx/Math.abs(dx); } if (dy) { dy = dy/Math.abs(dy); } var nx = dy; var ny = -dx; var ok = true; for (var i=0; i