UNPKG

malwoden

Version:

![alt text](./coverage/badge-lines.svg) ![alt text](./coverage/badge-statements.svg) ![alt text](./coverage/badge-functions.svg) ![alt text](./coverage/badge-branches.svg)

233 lines 9.32 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.BSPDungeonBuilder = exports.BSPDungeonNode = void 0; var rand_1 = require("../rand"); var rect_1 = require("../struct/rect"); var builder_1 = require("./builder"); var util_1 = require("./util"); var BSPDungeonNode = /** @class */ (function (_super) { __extends(BSPDungeonNode, _super); function BSPDungeonNode(_a) { var v1 = _a.v1, v2 = _a.v2, rng = _a.rng; var _this = _super.call(this, v1, v2) || this; _this.leafMinWidth = 5; _this.leafMinHeight = 5; _this.rng = rng; return _this; } BSPDungeonNode.prototype.connectChildren = function () { }; BSPDungeonNode.prototype.getRandomSplitDir = function () { var splitDir = this.rng.nextBoolean() ? "vertical" : "horizontal"; if (this.width() > this.height() && this.width() / this.height() > 1.25) { splitDir = "horizontal"; } else if (this.height() > this.width() && this.height() / this.width() > 1.25) { splitDir = "vertical"; } return splitDir; }; BSPDungeonNode.prototype.split = function () { if (this.getRandomSplitDir() === "horizontal") { this.splitHorizontal(); } else { this.splitVertical(); } }; BSPDungeonNode.prototype.getChildren = function () { if (this.childA === undefined || this.childB === undefined) return []; else return [this.childA, this.childB]; }; BSPDungeonNode.prototype.isLeafNode = function () { return this.childA === undefined && this.childB === undefined; }; BSPDungeonNode.prototype.splitVertical = function () { if (this.isLeafNode() === false) { throw new Error("BSPDungeonNode already split!"); } var minH = this.leafMinHeight; var maxH = this.height() - this.leafMinHeight; if (maxH < minH) { return; } var h = this.rng.nextInt(minH, maxH); this.childA = new BSPDungeonNode({ v1: { x: this.v1.x, y: this.v1.y }, v2: { x: this.v2.x, y: this.v1.y + h - 1 }, rng: this.rng, }); this.childB = new BSPDungeonNode({ v1: { x: this.v1.x, y: this.v1.y + h }, v2: { x: this.v2.x, y: this.v2.y }, rng: this.rng, }); }; BSPDungeonNode.prototype.splitHorizontal = function () { if (this.isLeafNode() === false) { throw new Error("BSPDungeonNode already split!"); } var minW = this.leafMinWidth; var maxW = this.width() - this.leafMinWidth; if (maxW < minW) { return; } var w = this.rng.nextInt(minW, maxW); this.childA = new BSPDungeonNode({ v1: { x: this.v1.x, y: this.v1.y }, v2: { x: this.v1.x + w - 1, y: this.v2.y }, rng: this.rng, }); this.childB = new BSPDungeonNode({ v1: { x: this.v1.x + w, y: this.v1.y }, v2: { x: this.v2.x, y: this.v2.y }, rng: this.rng, }); }; return BSPDungeonNode; }(rect_1.Rect)); exports.BSPDungeonNode = BSPDungeonNode; /** * DungeonGenerator creates a number of rooms, and then works to connect * them. */ var BSPDungeonBuilder = /** @class */ (function (_super) { __extends(BSPDungeonBuilder, _super); function BSPDungeonBuilder(config) { var _a; var _this = _super.call(this, config) || this; _this.hallways = []; _this.rooms = []; _this.wallTile = config.wallTile; _this.floorTile = config.floorTile; _this.rng = (_a = config.rng) !== null && _a !== void 0 ? _a : new rand_1.AleaRNG(); _this.map.fill(_this.wallTile); _this.root = new BSPDungeonNode({ v1: { x: 0, y: 0 }, v2: { x: config.width - 1, y: config.height - 1 }, rng: _this.rng, }); return _this; } BSPDungeonBuilder.prototype.getLeafNodes = function () { var leafs = []; var horizon = [this.root]; while (horizon.length) { var node = horizon.pop(); if (node.isLeafNode()) { leafs.push(node); } horizon.push.apply(horizon, node.getChildren()); } return leafs; }; /** * Splits the dungeon n times. A count of 1 would divide the dungeon in two, * count of 2 divides it in 4, etc. * @param count - number */ BSPDungeonBuilder.prototype.splitByCount = function (count) { for (var i = 0; i < count; i++) { var leafs = this.getLeafNodes(); for (var _i = 0, leafs_1 = leafs; _i < leafs_1.length; _i++) { var l = leafs_1[_i]; l.split(); } } }; /** * Creates rooms given the current BSP Tree. Use the 'split' method first to generate areas, then * call createRooms to generate rooms within those areas * * @param options - Options to create the rooms * @param options.minWidth - The minimum width of a generated room. * @param options.minHeight - The minimum height of a generated room. * @param options.maxWidth - The maximum width of a generated room. Will never be wider than the BSP area. * @param options.maxHeight - The maximum height of a generated room. Will never be taller than the BSP area. * @param options.padding - Can pad the area to ensure rooms aren't against the boundaries. Default 0. */ BSPDungeonBuilder.prototype.createRooms = function (options) { var _a, _b, _c; var minWidth = options.minWidth, minHeight = options.minHeight; var padding = (_a = options.padding) !== null && _a !== void 0 ? _a : 0; var leafs = this.getLeafNodes(); for (var _i = 0, leafs_2 = leafs; _i < leafs_2.length; _i++) { var area = leafs_2[_i]; var areaWidth = area.width() - padding * 2; var areaHeight = area.height() - padding * 2; var maxWidth = Math.min((_b = options.maxWidth) !== null && _b !== void 0 ? _b : areaWidth, areaWidth); var maxHeight = Math.min((_c = options.maxHeight) !== null && _c !== void 0 ? _c : areaHeight, areaHeight); if (maxWidth < minWidth || maxHeight < minHeight) continue; var w = this.rng.nextInt(minWidth, maxWidth); var h = this.rng.nextInt(minHeight, maxHeight); var pv1 = { x: area.v1.x + padding, y: area.v1.y + padding }; var pv2 = { x: area.v2.x - padding, y: area.v2.y - padding }; var randX = this.rng.nextInt(pv1.x, pv2.x - w + 1); var randY = this.rng.nextInt(pv1.y, pv2.y - h + 1); var room = rect_1.Rect.FromWidthHeight({ x: randX, y: randY }, w, h); this.carveRoom(room); this.rooms.push(room); } }; BSPDungeonBuilder.prototype.carveRoom = function (room) { for (var x = room.v1.x; x <= room.v2.x; x++) { for (var y = room.v1.y; y <= room.v2.y; y++) { this.map.set({ x: x, y: y }, this.floorTile); } } }; /** * Gets all rooms created. These will each belong to a leaf node of the BSP Tree. * @returns Rect[] - A list of all rooms */ BSPDungeonBuilder.prototype.getRooms = function () { return this.rooms; }; /** * Creates simple right angle hallways between existing rooms. * @returns BSPDungeon - Can be used for method chaining. */ BSPDungeonBuilder.prototype.createSimpleHallways = function () { this.hallways = []; var shuffledRooms = this.rng.shuffle(this.rooms); var connectedRooms = []; while (shuffledRooms.length) { var nextRoom = shuffledRooms.pop(); // if not the first room, connect it in if (connectedRooms.length) { var roomToConnect = connectedRooms[connectedRooms.length - 1]; var hallway = util_1.getSimpleHallwayFromRooms(nextRoom, roomToConnect); this.hallways.push(hallway); } connectedRooms.push(nextRoom); } }; /** * Returns a list of all hallways * @returns Vector2[][] - The hallways */ BSPDungeonBuilder.prototype.getHallways = function () { return this.hallways; }; return BSPDungeonBuilder; }(builder_1.Builder)); exports.BSPDungeonBuilder = BSPDungeonBuilder; //# sourceMappingURL=bsp-dungeon-builder.js.map