1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Placing underground belts now removes belts and other (unneeded) tunnels inbetween

This commit is contained in:
tobspr
2020-06-16 13:19:53 +02:00
parent 90cb56292b
commit b8c3668d88
4 changed files with 150 additions and 7 deletions

View File

@@ -1,12 +1,17 @@
import { GameSystemWithFilter } from "../game_system_with_filter";
import { UndergroundBeltComponent, enumUndergroundBeltMode } from "../components/underground_belt";
import { Entity } from "../entity";
import { Loader } from "../../core/loader";
import { Math_max } from "../../core/builtins";
import { globalConfig } from "../../core/config";
import { enumDirection, enumDirectionToVector, enumDirectionToAngle } from "../../core/vector";
import { MapChunkView } from "../map_chunk_view";
import { DrawParameters } from "../../core/draw_parameters";
import { Loader } from "../../core/loader";
import {
enumDirection,
enumDirectionToAngle,
enumDirectionToVector,
Vector,
enumAngleToDirection,
enumInvertedDirections,
} from "../../core/vector";
import { enumUndergroundBeltMode, UndergroundBeltComponent } from "../components/underground_belt";
import { Entity } from "../entity";
import { GameSystemWithFilter } from "../game_system_with_filter";
export class UndergroundBeltSystem extends GameSystemWithFilter {
constructor(root) {
@@ -20,6 +25,8 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
"sprites/buildings/underground_belt_exit.png"
),
};
this.root.signals.entityManuallyPlaced.add(this.onEntityPlaced, this);
}
update() {
@@ -46,6 +53,135 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
}
}
/**
* Callback when an entity got placed, used to remove belts between underground belts
* @param {Entity} entity
*/
onEntityPlaced(entity) {
const undergroundComp = entity.components.UndergroundBelt;
if (undergroundComp && undergroundComp.mode === enumUndergroundBeltMode.receiver) {
const staticComp = entity.components.StaticMapEntity;
const tile = staticComp.origin;
const direction = enumAngleToDirection[staticComp.rotation];
const inverseDirection = enumInvertedDirections[direction];
const offset = enumDirectionToVector[inverseDirection];
let currentPos = tile.copy();
const tier = undergroundComp.tier;
const range = globalConfig.undergroundBeltMaxTilesByTier[tier];
// Search for the entrance which is furthes apart (this is why we can't reuse logic here)
let matchingEntrance = null;
for (let i = 0; i < range; ++i) {
currentPos.addInplace(offset);
const contents = this.root.map.getTileContent(currentPos);
if (!contents) {
continue;
}
const contentsUndergroundComp = contents.components.UndergroundBelt;
if (
contentsUndergroundComp &&
contentsUndergroundComp.tier === undergroundComp.tier &&
contentsUndergroundComp.mode === enumUndergroundBeltMode.sender
) {
matchingEntrance = {
entity: contents,
range: i,
};
}
}
if (!matchingEntrance) {
// Nothing found
return;
}
// Remove any belts between entrance and exit which have the same direction
currentPos = tile.copy();
for (let i = 0; i < matchingEntrance.range; ++i) {
currentPos.addInplace(offset);
const contents = this.root.map.getTileContent(currentPos);
if (!contents) {
continue;
}
const contentsStaticComp = contents.components.StaticMapEntity;
const contentsBeltComp = contents.components.Belt;
if (contentsBeltComp) {
// It's a belt
if (
contentsBeltComp.direction === enumDirection.top &&
enumAngleToDirection[contentsStaticComp.rotation] === direction
) {
// It's same rotation, drop it
this.root.logic.tryDeleteBuilding(contents);
}
}
}
// Remove any double tunnels, by checking the tile plus the tile above
currentPos = tile.copy().add(offset);
for (let i = 0; i < matchingEntrance.range - 1; ++i) {
const posBefore = currentPos.copy();
currentPos.addInplace(offset);
const entityBefore = this.root.map.getTileContent(posBefore);
const entityAfter = this.root.map.getTileContent(currentPos);
if (!entityBefore || !entityAfter) {
continue;
}
const undergroundBefore = entityBefore.components.UndergroundBelt;
const undergroundAfter = entityAfter.components.UndergroundBelt;
if (!undergroundBefore || !undergroundAfter) {
// Not an underground belt
continue;
}
if (
// Both same tier
undergroundBefore.tier !== undergroundAfter.tier ||
// And same tier as our original entity
undergroundBefore.tier !== undergroundComp.tier
) {
// Mismatching tier
continue;
}
if (
undergroundBefore.mode !== enumUndergroundBeltMode.sender ||
undergroundAfter.mode !== enumUndergroundBeltMode.receiver
) {
// Not the right mode
continue;
}
// Check rotations
const staticBefore = entityBefore.components.StaticMapEntity;
const staticAfter = entityAfter.components.StaticMapEntity;
if (
enumAngleToDirection[staticBefore.rotation] !== direction ||
enumAngleToDirection[staticAfter.rotation] !== direction
) {
// Wrong rotation
continue;
}
// All good, can remove
this.root.logic.tryDeleteBuilding(entityBefore);
this.root.logic.tryDeleteBuilding(entityAfter);
}
}
}
/**
*
* @param {Entity} entity