diff --git a/src/js/core/modal_dialog_forms.js b/src/js/core/modal_dialog_forms.js index 4d1c9f97..1ded9a8b 100644 --- a/src/js/core/modal_dialog_forms.js +++ b/src/js/core/modal_dialog_forms.js @@ -19,7 +19,7 @@ export class FormElement { abstract; } - focus(parent) {} + focus() {} isValid() { return true; diff --git a/src/js/core/polyfills.js b/src/js/core/polyfills.js index e5efca1d..145b4c82 100644 --- a/src/js/core/polyfills.js +++ b/src/js/core/polyfills.js @@ -72,6 +72,7 @@ function objectPolyfills() { } if (!Object.entries) { + // @ts-ignore Object.entries = function entries(O) { return reduce( keys(O), diff --git a/src/js/core/utils.js b/src/js/core/utils.js index 23368317..3d4e524c 100644 --- a/src/js/core/utils.js +++ b/src/js/core/utils.js @@ -405,8 +405,6 @@ export function findNiceValue(num) { return Math_round(niceValue * 100) / 100; } -window.fn = findNiceValue; - /** * Finds a nice integer value * @see findNiceValue diff --git a/src/js/game/belt_path.js b/src/js/game/belt_path.js index 0ab7299f..48d6a93e 100644 --- a/src/js/game/belt_path.js +++ b/src/js/game/belt_path.js @@ -14,6 +14,8 @@ const logger = createLogger("belt_path"); const _nextDistance = 0; const _item = 1; +const DEBUG = G_IS_DEV && false; + /** * Stores a path of belts, used for optimizing performance */ @@ -204,7 +206,7 @@ export class BeltPath { * @param {Entity} entity */ extendOnEnd(entity) { - logger.log("Extending belt path by entity at", entity.components.StaticMapEntity.origin); + DEBUG && logger.log("Extending belt path by entity at", entity.components.StaticMapEntity.origin); const beltComp = entity.components.Belt; @@ -212,7 +214,7 @@ export class BeltPath { const pendingItem = this.ejectorComp.takeSlotItem(0); if (pendingItem) { // Ok, so we have a pending item - logger.log("Taking pending item and putting it back on the path"); + DEBUG && logger.log("Taking pending item and putting it back on the path"); this.items.push([0, pendingItem]); } @@ -222,21 +224,22 @@ export class BeltPath { // Extend the path length const additionalLength = beltComp.getEffectiveLengthTiles(); this.totalLength += additionalLength; - logger.log(" Extended total length by", additionalLength, "to", this.totalLength); + DEBUG && logger.log(" Extended total length by", additionalLength, "to", this.totalLength); // If we have no item, just update the distance to the first item if (this.items.length === 0) { this.spacingToFirstItem = this.totalLength; - logger.log(" Extended spacing to first to", this.totalLength, "(= total length)"); + DEBUG && logger.log(" Extended spacing to first to", this.totalLength, "(= total length)"); } else { // Otherwise, update the next-distance of the last item const lastItem = this.items[this.items.length - 1]; - logger.log( - " Extended spacing of last item from", - lastItem[_nextDistance], - "to", - lastItem[_nextDistance] + additionalLength - ); + DEBUG && + logger.log( + " Extended spacing of last item from", + lastItem[_nextDistance], + "to", + lastItem[_nextDistance] + additionalLength + ); lastItem[_nextDistance] += additionalLength; } @@ -257,7 +260,7 @@ export class BeltPath { extendOnBeginning(entity) { const beltComp = entity.components.Belt; - logger.log("Extending the path on the beginning"); + DEBUG && logger.log("Extending the path on the beginning"); // All items on that belt are simply lost (for now) @@ -277,6 +280,24 @@ export class BeltPath { this.debug_checkIntegrity("extend-on-begin"); } + /** + * Returns if the given entity is the end entity of the path + * @param {Entity} entity + * @returns {boolean} + */ + isEndEntity(entity) { + return this.entityPath[this.entityPath.length - 1] === entity; + } + + /** + * Returns if the given entity is the start entity of the path + * @param {Entity} entity + * @returns {boolean} + */ + isStartEntity(entity) { + return this.entityPath[0] === entity; + } + /** * Splits this path at the given entity by removing it, and * returning the new secondary paht @@ -284,7 +305,7 @@ export class BeltPath { * @returns {BeltPath} */ deleteEntityOnPathSplitIntoTwo(entity) { - logger.log("Splitting path at entity", entity.components.StaticMapEntity.origin); + DEBUG && logger.log("Splitting path at entity", entity.components.StaticMapEntity.origin); // First, find where the current path ends const beltComp = entity.components.Belt; @@ -302,7 +323,7 @@ export class BeltPath { for (let i = 0; i < this.entityPath.length; ++i) { const otherEntity = this.entityPath[i]; if (otherEntity === entity) { - logger.log("Found entity at", i, "of length", firstPathLength); + DEBUG && logger.log("Found entity at", i, "of length", firstPathLength); break; } @@ -311,38 +332,41 @@ export class BeltPath { firstPathLength += otherEntity.components.Belt.getEffectiveLengthTiles(); } - logger.log( - "First path ends at", - firstPathLength, - "and entity", - firstPathEndEntity.components.StaticMapEntity.origin, - "and has", - firstPathEntityCount, - "entities" - ); + DEBUG && + logger.log( + "First path ends at", + firstPathLength, + "and entity", + firstPathEndEntity.components.StaticMapEntity.origin, + "and has", + firstPathEntityCount, + "entities" + ); // Compute length of second path const secondPathLength = this.totalLength - firstPathLength - entityLength; const secondPathStart = firstPathLength + entityLength; const secondEntities = this.entityPath.splice(firstPathEntityCount + 1); - logger.log( - "Second path starts at", - secondPathStart, - "and has a length of ", - secondPathLength, - "with", - secondEntities.length, - "entities" - ); + DEBUG && + logger.log( + "Second path starts at", + secondPathStart, + "and has a length of ", + secondPathLength, + "with", + secondEntities.length, + "entities" + ); // Remove the last item this.entityPath.pop(); - logger.log("Splitting", this.items.length, "items"); - logger.log( - "Old items are", - this.items.map(i => i[_nextDistance]) - ); + DEBUG && logger.log("Splitting", this.items.length, "items"); + DEBUG && + logger.log( + "Old items are", + this.items.map(i => i[_nextDistance]) + ); // Create second path const secondPath = new BeltPath(this.root, secondEntities); @@ -353,45 +377,48 @@ export class BeltPath { const item = this.items[i]; const distanceToNext = item[_nextDistance]; - logger.log(" Checking item at", itemPos, "with distance of", distanceToNext, "to next"); + DEBUG && logger.log(" Checking item at", itemPos, "with distance of", distanceToNext, "to next"); // Check if this item is past the first path if (itemPos >= firstPathLength) { // Remove it from the first path this.items.splice(i, 1); i -= 1; - logger.log(" Removed item from first path since its no longer contained @", itemPos); + DEBUG && + logger.log(" Removed item from first path since its no longer contained @", itemPos); // Check if its on the second path (otherwise its on the removed belt and simply lost) if (itemPos >= secondPathStart) { // Put item on second path secondPath.items.push([distanceToNext, item[_item]]); - logger.log( - " Put item to second path @", - itemPos, - "with distance to next =", - distanceToNext - ); + DEBUG && + logger.log( + " Put item to second path @", + itemPos, + "with distance to next =", + distanceToNext + ); // If it was the first item, adjust the distance to the first item if (secondPath.items.length === 1) { - logger.log(" Sinc it was the first, set sapcing of first to", itemPos); + DEBUG && logger.log(" Sinc it was the first, set sapcing of first to", itemPos); secondPath.spacingToFirstItem = itemPos - secondPathStart; } } else { - logger.log(" Item was on the removed belt, so its gone - forever!"); + DEBUG && logger.log(" Item was on the removed belt, so its gone - forever!"); } } else { // Seems this item is on the first path (so all good), so just make sure it doesn't // have a nextDistance which is bigger than the total path length const clampedDistanceToNext = Math_min(itemPos + distanceToNext, firstPathLength) - itemPos; if (clampedDistanceToNext < distanceToNext) { - logger.log( - "Correcting next distance (first path) from", - distanceToNext, - "to", - clampedDistanceToNext - ); + DEBUG && + logger.log( + "Correcting next distance (first path) from", + distanceToNext, + "to", + clampedDistanceToNext + ); item[_nextDistance] = clampedDistanceToNext; } } @@ -400,15 +427,17 @@ export class BeltPath { itemPos += distanceToNext; } - logger.log( - "New items are", - this.items.map(i => i[_nextDistance]) - ); + DEBUG && + logger.log( + "New items are", + this.items.map(i => i[_nextDistance]) + ); - logger.log( - "And second path items are", - secondPath.items.map(i => i[_nextDistance]) - ); + DEBUG && + logger.log( + "And second path items are", + secondPath.items.map(i => i[_nextDistance]) + ); // Adjust our total length this.totalLength = firstPathLength; @@ -433,25 +462,36 @@ export class BeltPath { * @param {Entity} entity */ deleteEntityOnEnd(entity) { - assert(this.entityPath[this.entityPath.length - 1] === entity, "Not the last entity actually"); + assert( + this.entityPath[this.entityPath.length - 1] === entity, + "Not actually the last entity (instead " + this.entityPath.indexOf(entity) + ")" + ); // Ok, first remove the entity const beltComp = entity.components.Belt; const beltLength = beltComp.getEffectiveLengthTiles(); - logger.log( - "Deleting last entity on path with length", - this.entityPath.length, - "(reducing", - this.totalLength, - " by", - beltLength, - ")" - ); + DEBUG && + logger.log( + "Deleting last entity on path with length", + this.entityPath.length, + "(reducing", + this.totalLength, + " by", + beltLength, + ")" + ); this.totalLength -= beltLength; this.entityPath.pop(); - logger.log(" New path has length of", this.totalLength, "with", this.entityPath.length, "entities"); + DEBUG && + logger.log( + " New path has length of", + this.totalLength, + "with", + this.entityPath.length, + "entities" + ); // This is just for sanity beltComp.assignedPath = null; @@ -465,20 +505,20 @@ export class BeltPath { let itemOffset = this.spacingToFirstItem; let lastItemOffset = itemOffset; - logger.log(" Adjusting", this.items.length, "items"); + DEBUG && logger.log(" Adjusting", this.items.length, "items"); for (let i = 0; i < this.items.length; ++i) { const item = this.items[i]; // Get rid of items past this path if (itemOffset >= this.totalLength) { - logger.log("Dropping item (current index=", i, ")"); + DEBUG && logger.log("Dropping item (current index=", i, ")"); this.items.splice(i, 1); i -= 1; continue; } - logger.log("Item", i, "is at", itemOffset, "with next offset", item[_nextDistance]); + DEBUG && logger.log("Item", i, "is at", itemOffset, "with next offset", item[_nextDistance]); lastItemOffset = itemOffset; itemOffset += item[_nextDistance]; } @@ -497,18 +537,19 @@ export class BeltPath { lastItemOffset ); - logger.log( - "Adjusted distance of last item: it is at", - lastItemOffset, - "so it has a distance of", - lastDistance, - "to the end (", - this.totalLength, - ")" - ); + DEBUG && + logger.log( + "Adjusted distance of last item: it is at", + lastItemOffset, + "so it has a distance of", + lastDistance, + "to the end (", + this.totalLength, + ")" + ); this.items[this.items.length - 1][_nextDistance] = lastDistance; } else { - logger.log(" Removed all items so we'll update spacing to total length"); + DEBUG && logger.log(" Removed all items so we'll update spacing to total length"); // We removed all items so update our spacing this.spacingToFirstItem = this.totalLength; @@ -528,25 +569,36 @@ export class BeltPath { * @param {Entity} entity */ deleteEntityOnStart(entity) { - assert(entity === this.entityPath[0], "Not actually the start entity"); + assert( + entity === this.entityPath[0], + "Not actually the start entity (instead " + this.entityPath.indexOf(entity) + ")" + ); // Ok, first remove the entity const beltComp = entity.components.Belt; const beltLength = beltComp.getEffectiveLengthTiles(); - logger.log( - "Deleting first entity on path with length", - this.entityPath.length, - "(reducing", - this.totalLength, - " by", - beltLength, - ")" - ); + DEBUG && + logger.log( + "Deleting first entity on path with length", + this.entityPath.length, + "(reducing", + this.totalLength, + " by", + beltLength, + ")" + ); this.totalLength -= beltLength; this.entityPath.shift(); - logger.log(" New path has length of", this.totalLength, "with", this.entityPath.length, "entities"); + DEBUG && + logger.log( + " New path has length of", + this.totalLength, + "with", + this.entityPath.length, + "entities" + ); // This is just for sanity beltComp.assignedPath = null; @@ -558,41 +610,45 @@ export class BeltPath { } else { // Simple case, we had no item on the beginning -> all good if (this.spacingToFirstItem >= beltLength) { - logger.log( - " No item on the first place, so we can just adjust the spacing (spacing=", - this.spacingToFirstItem, - ") removed =", - beltLength - ); + DEBUG && + logger.log( + " No item on the first place, so we can just adjust the spacing (spacing=", + this.spacingToFirstItem, + ") removed =", + beltLength + ); this.spacingToFirstItem -= beltLength; } else { // Welp, okay we need to drop all items which are < beltLength and adjust // the other item offsets as well - logger.log( - " We have at least one item in the beginning, drop those and adjust spacing (first item @", - this.spacingToFirstItem, - ") since we removed", - beltLength, - "length from path" - ); - logger.log( - " Items:", - this.items.map(i => i[_nextDistance]) - ); + DEBUG && + logger.log( + " We have at least one item in the beginning, drop those and adjust spacing (first item @", + this.spacingToFirstItem, + ") since we removed", + beltLength, + "length from path" + ); + DEBUG && + logger.log( + " Items:", + this.items.map(i => i[_nextDistance]) + ); // Find offset to first item let itemOffset = this.spacingToFirstItem; for (let i = 0; i < this.items.length; ++i) { const item = this.items[i]; if (itemOffset <= beltLength) { - logger.log( - " -> Dropping item with index", - i, - "at", - itemOffset, - "since it was on the removed belt" - ); + DEBUG && + logger.log( + " -> Dropping item with index", + i, + "at", + itemOffset, + "since it was on the removed belt" + ); // This item must be dropped this.items.splice(i, 1); i -= 1; @@ -605,13 +661,14 @@ export class BeltPath { } if (this.items.length > 0) { - logger.log( - " Offset of first non-dropped item was at:", - itemOffset, - "-> setting spacing to it (total length=", - this.totalLength, - ")" - ); + DEBUG && + logger.log( + " Offset of first non-dropped item was at:", + itemOffset, + "-> setting spacing to it (total length=", + this.totalLength, + ")" + ); this.spacingToFirstItem = itemOffset - beltLength; assert( @@ -619,7 +676,7 @@ export class BeltPath { "Invalid spacing after delete on start: " + this.spacingToFirstItem ); } else { - logger.log(" We dropped all items, simply set spacing to total length"); + DEBUG && logger.log(" We dropped all items, simply set spacing to total length"); // We dropped all items, simple one this.spacingToFirstItem = this.totalLength; } @@ -640,11 +697,11 @@ export class BeltPath { assert(otherPath !== this, "Circular path dependency"); const entities = otherPath.entityPath; - logger.log("Extending path by other path, starting to add entities"); + DEBUG && logger.log("Extending path by other path, starting to add entities"); const oldLength = this.totalLength; - logger.log(" Adding", entities.length, "new entities, current length =", this.totalLength); + DEBUG && logger.log(" Adding", entities.length, "new entities, current length =", this.totalLength); // First, append entities for (let i = 0; i < entities.length; ++i) { @@ -660,7 +717,13 @@ export class BeltPath { this.totalLength += additionalLength; } - logger.log(" Path is now", this.entityPath.length, "entities and has a length of", this.totalLength); + DEBUG && + logger.log( + " Path is now", + this.entityPath.length, + "entities and has a length of", + this.totalLength + ); // Update handles this.ejectorComp = this.entityPath[this.entityPath.length - 1].components.ItemEjector; @@ -670,21 +733,23 @@ export class BeltPath { if (this.items.length !== 0) { const lastItem = this.items[this.items.length - 1]; lastItem[_nextDistance] += otherPath.spacingToFirstItem; - logger.log(" Add distance to last item, effectively being", lastItem[_nextDistance], "now"); + DEBUG && + logger.log(" Add distance to last item, effectively being", lastItem[_nextDistance], "now"); } else { // Seems we have no items, update our first item distance this.spacingToFirstItem = oldLength + otherPath.spacingToFirstItem; - logger.log( - " We had no items, so our new spacing to first is old length (", - oldLength, - ") plus others spacing to first (", - otherPath.spacingToFirstItem, - ") =", - this.spacingToFirstItem - ); + DEBUG && + logger.log( + " We had no items, so our new spacing to first is old length (", + oldLength, + ") plus others spacing to first (", + otherPath.spacingToFirstItem, + ") =", + this.spacingToFirstItem + ); } - logger.log(" Pushing", otherPath.items.length, "items from other path"); + DEBUG && logger.log(" Pushing", otherPath.items.length, "items from other path"); // Aaand push the other paths items for (let i = 0; i < otherPath.items.length; ++i) { diff --git a/src/js/game/hud/parts/blueprint.js b/src/js/game/blueprint.js similarity index 85% rename from src/js/game/hud/parts/blueprint.js rename to src/js/game/blueprint.js index c53163d9..d923b2e1 100644 --- a/src/js/game/hud/parts/blueprint.js +++ b/src/js/game/blueprint.js @@ -1,13 +1,13 @@ -import { DrawParameters } from "../../../core/draw_parameters"; -import { Loader } from "../../../core/loader"; -import { createLogger } from "../../../core/logging"; -import { Vector } from "../../../core/vector"; -import { Entity } from "../../entity"; -import { GameRoot } from "../../root"; -import { findNiceIntegerValue } from "../../../core/utils"; -import { Math_pow } from "../../../core/builtins"; -import { blueprintShape } from "../../upgrades"; -import { globalConfig } from "../../../core/config"; +import { DrawParameters } from "../core/draw_parameters"; +import { Loader } from "../core/loader"; +import { createLogger } from "../core/logging"; +import { Vector } from "../core/vector"; +import { Entity } from "./entity"; +import { GameRoot } from "./root"; +import { findNiceIntegerValue } from "../core/utils"; +import { Math_pow } from "../core/builtins"; +import { blueprintShape } from "./upgrades"; +import { globalConfig } from "../core/config"; const logger = createLogger("blueprint"); @@ -176,7 +176,6 @@ export class Blueprint { tryPlace(root, tile) { return root.logic.performBulkOperation(() => { let anyPlaced = false; - const beltsToRegisterLater = []; for (let i = 0; i < this.entities.length; ++i) { let placeable = true; const entity = this.entities[i]; @@ -217,21 +216,10 @@ export class Blueprint { root.map.placeStaticEntity(clone); - // Registering a belt immediately triggers a recalculation of surrounding belt - // directions, which is no good when not all belts have been placed. To resolve - // this, only register belts after all entities have been placed. - if (!clone.components.Belt) { - root.entityMgr.registerEntity(clone); - } else { - beltsToRegisterLater.push(clone); - } + root.entityMgr.registerEntity(clone); anyPlaced = true; } } - - for (let i = 0; i < beltsToRegisterLater.length; i++) { - root.entityMgr.registerEntity(beltsToRegisterLater[i]); - } return anyPlaced; }); } diff --git a/src/js/game/hud/parts/blueprint_placer.js b/src/js/game/hud/parts/blueprint_placer.js index c98fbf2d..6b2af42e 100644 --- a/src/js/game/hud/parts/blueprint_placer.js +++ b/src/js/game/hud/parts/blueprint_placer.js @@ -9,7 +9,7 @@ import { KEYMAPPINGS } from "../../key_action_mapper"; import { blueprintShape } from "../../upgrades"; import { BaseHUDPart } from "../base_hud_part"; import { DynamicDomAttach } from "../dynamic_dom_attach"; -import { Blueprint } from "./blueprint"; +import { Blueprint } from "../../blueprint"; import { SOUNDS } from "../../../platform/sound"; export class HUDBlueprintPlacer extends BaseHUDPart { diff --git a/src/js/game/logic.js b/src/js/game/logic.js index 71c709dc..79caf38b 100644 --- a/src/js/game/logic.js +++ b/src/js/game/logic.js @@ -196,7 +196,7 @@ export class GameLogic { * @param {function} operation */ performBulkOperation(operation) { - logger.log("Running bulk operation ..."); + logger.warn("Running bulk operation ..."); assert(!this.root.bulkOperationRunning, "Can not run two bulk operations twice"); this.root.bulkOperationRunning = true; const now = performanceNow(); diff --git a/src/js/game/systems/belt.js b/src/js/game/systems/belt.js index ed4e4311..92de413b 100644 --- a/src/js/game/systems/belt.js +++ b/src/js/game/systems/belt.js @@ -146,38 +146,35 @@ export class BeltSystem extends GameSystemWithFilter { const assignedPath = entity.components.Belt.assignedPath; assert(assignedPath, "Entity has no belt path assigned"); + this.deleteEntityFromPath(assignedPath, entity); + this.verifyBeltPaths(); + } - // Find from and to entities - const fromEntity = this.findSupplyingEntity(entity); - const toEntity = this.findFollowUpEntity(entity); - - // Check if the belt had a previous belt - if (fromEntity) { - const fromPath = fromEntity.components.Belt.assignedPath; - - // Check if the entity had a followup - belt - if (toEntity) { - const toPath = toEntity.components.Belt.assignedPath; - assert(fromPath === toPath, "Invalid belt path layout (from path != to path)"); - - const newPath = fromPath.deleteEntityOnPathSplitIntoTwo(entity); - this.beltPaths.push(newPath); - } else { - fromPath.deleteEntityOnEnd(entity); - } - } else { - if (toEntity) { - // We need to remove the entity from the beginning of the other path - const toPath = toEntity.components.Belt.assignedPath; - toPath.deleteEntityOnStart(entity); - } else { - // This is a single entity path, easy to do - const path = entity.components.Belt.assignedPath; - fastArrayDeleteValue(this.beltPaths, path); - } + /** + * Attempts to delete the belt from its current path + * @param {BeltPath} path + * @param {Entity} entity + */ + deleteEntityFromPath(path, entity) { + if (path.entityPath.length === 1) { + // This is a single entity path, easy to do, simply erase whole path + fastArrayDeleteValue(this.beltPaths, path); + return; } - this.verifyBeltPaths(); + // Notice: Since there might be circular references, it is important to check + // which role the entity has + if (path.isStartEntity(entity)) { + // We tried to delete the start + path.deleteEntityOnStart(entity); + } else if (path.isEndEntity(entity)) { + // We tried to delete the end + path.deleteEntityOnEnd(entity); + } else { + // We tried to delete something inbetween + const newPath = path.deleteEntityOnPathSplitIntoTwo(entity); + this.beltPaths.push(newPath); + } } /** @@ -193,13 +190,9 @@ export class BeltSystem extends GameSystemWithFilter { return; } - console.log("ADD"); - const fromEntity = this.findSupplyingEntity(entity); const toEntity = this.findFollowUpEntity(entity); - console.log("From:", fromEntity, "to:", toEntity); - // Check if we can add the entity to the previous path if (fromEntity) { const fromPath = fromEntity.components.Belt.assignedPath; @@ -385,22 +378,15 @@ export class BeltSystem extends GameSystemWithFilter { */ computeBeltPaths() { const visitedUids = new Set(); - console.log("Computing belt paths"); - const debugEntity = e => e.components.StaticMapEntity.origin.toString(); - - // const stackToVisit = this.allEntities.slice(); const result = []; - const currentPath = null; - for (let i = 0; i < this.allEntities.length; ++i) { const entity = this.allEntities[i]; if (visitedUids.has(entity.uid)) { continue; } - // console.log("Starting at", debugEntity(entity)); // Mark entity as visited visitedUids.add(entity.uid); @@ -412,10 +398,9 @@ export class BeltSystem extends GameSystemWithFilter { // Find precedors let prevEntity = this.findSupplyingEntity(entity); while (prevEntity && --maxIter > 0) { - if (visitedUids.has(prevEntity)) { + if (visitedUids.has(prevEntity.uid)) { break; } - // console.log(" -> precedor: ", debugEntity(prevEntity)); path.unshift(prevEntity); visitedUids.add(prevEntity.uid); prevEntity = this.findSupplyingEntity(prevEntity); @@ -424,26 +409,17 @@ export class BeltSystem extends GameSystemWithFilter { // Find succedors let nextEntity = this.findFollowUpEntity(entity); while (nextEntity && --maxIter > 0) { - if (visitedUids.has(nextEntity)) { + if (visitedUids.has(nextEntity.uid)) { break; } - // console.log(" -> succedor: ", debugEntity(nextEntity)); path.push(nextEntity); visitedUids.add(nextEntity.uid); nextEntity = this.findFollowUpEntity(nextEntity); } - assert(maxIter !== 0, "Ran out of iterations"); - - // console.log( - // "Found path:", - // path.map(e => debugEntity(e)) - // ); - + assert(maxIter > 1, "Ran out of iterations"); result.push(new BeltPath(this.root, path)); - - // let prevEntity = this.findSupplyingEntity(srcEntity); } logger.log("Found", this.beltPaths.length, "belt paths");