激光门完毕
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type MapController from "./Map";
|
||||
import type Wall from "./Wall";
|
||||
import type Block from "./Block";
|
||||
import { LQCollide } from "./lq_collide_system/lq_collide";
|
||||
import { LQCollideSystem } from "./lq_collide_system/lq_collide_system";
|
||||
import { LQCollideShape } from "./lq_base/data/lq_const";
|
||||
@@ -173,23 +174,64 @@ export default class LaserSystem {
|
||||
}
|
||||
}
|
||||
|
||||
private collectColliders(): { shape: LaserCollider; wall: cc.Node }[] {
|
||||
const result: { shape: LaserCollider; wall: cc.Node }[] = [];
|
||||
/** Prediction only: movable blockers may clear; actual reception still uses every solid. */
|
||||
getPotentialExitIds(): Set<string> {
|
||||
const fixed = this.collectColliders().filter(item => !this.canMoveBlocker(item.block));
|
||||
const result = new Set<string>();
|
||||
for (const group of this.groups) {
|
||||
const obstacles = fixed.filter(item => item.wall !== group.emitter.node.parent
|
||||
&& item.wall !== group.receiver.node.parent).map(item => item.shape);
|
||||
// Scan to the receiver, including blockers hidden behind the visible beam's first hit.
|
||||
if (!nearestLaserHit(group.source.getBeamOrigin(), group.target.getBeamOrigin(), obstacles)) {
|
||||
result.add(group.config.id);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private canMoveBlocker(block: Block, visited = new Set<Block>()): boolean {
|
||||
if (!block || block.over || visited.has(block)) return false;
|
||||
visited.add(block);
|
||||
const info = block.block_Info || {};
|
||||
// Exit locks, question blocks and petal covers do not prevent dragging.
|
||||
// Temporary input locks during spawning/opening also need no elimination to clear.
|
||||
const hasAxis = (block.type !== 8 && info.vertical == null)
|
||||
|| (block.type !== 7 && info.horizontal == null);
|
||||
if ([3, 4, 10, 12].indexOf(block.type) < 0
|
||||
&& (!info.floor || info.floorMove === true) && hasAxis) return true;
|
||||
|
||||
const drivers: cc.Node[] = [];
|
||||
if (block.type === 10 && info.node) drivers.push(info.node);
|
||||
if (info.floor && info.floorMove === true) drivers.push(...(block.teamBlocks || []));
|
||||
// Adhesive followers can move even when they cannot be dragged directly.
|
||||
for (const node of this.map.node.children) {
|
||||
const driver = node.getComponent("Block") as Block;
|
||||
if (driver && driver.type === 9 && driver.block_Info && driver.block_Info.node === block.node) {
|
||||
drivers.push(node);
|
||||
}
|
||||
}
|
||||
return drivers.some(node => cc.isValid(node, true) && node.activeInHierarchy
|
||||
&& this.canMoveBlocker(node.getComponent("Block"), visited));
|
||||
}
|
||||
|
||||
private collectColliders(): { shape: LaserCollider; wall: cc.Node; block: Block }[] {
|
||||
const result: { shape: LaserCollider; wall: cc.Node; block: Block }[] = [];
|
||||
for (const collider of LQCollideSystem.collide_arr) {
|
||||
const node = collider.node;
|
||||
if (!cc.isValid(node, true) || !node.activeInHierarchy || !collider.is_enable
|
||||
|| !collider.enabled || collider.data_string === "-1" || collider.data_string === "-2") continue;
|
||||
if (node.name === "rise" && this.map.riseFallBlock.indexOf(node.parent) >= 0) continue;
|
||||
let ancestor = node, wall: cc.Node = null, transparent = false;
|
||||
let ancestor = node, wall: cc.Node = null, owner: Block = null, transparent = false;
|
||||
while (ancestor && ancestor !== this.map.node) {
|
||||
const block = ancestor.getComponent("Block");
|
||||
const block = ancestor.getComponent("Block") as Block;
|
||||
if (block && !owner) owner = block;
|
||||
if (block && (block.type === 22 || block.over)) transparent = true;
|
||||
if (ancestor.getChildByName("wall") && ancestor.getChildByName("wall").getComponent("Wall")) wall = ancestor;
|
||||
ancestor = ancestor.parent;
|
||||
}
|
||||
if (ancestor !== this.map.node || transparent) continue;
|
||||
const shape = this.colliderShape(collider);
|
||||
if (shape) result.push({ shape, wall });
|
||||
if (shape) result.push({ shape, wall, block: owner });
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user