75 lines
3.8 KiB
TypeScript
75 lines
3.8 KiB
TypeScript
import { reshape, refreshLinks } from "./RainbowCut";
|
|
import { RAINBOW_SHAPES } from "./RainbowRules";
|
|
import { RocketCut } from "./RocketRules";
|
|
|
|
/** 不调用消除入口:不推进机关、计数、彩虹能量,也不生成替代方块。 */
|
|
export function applyRocketCut(map: any, block: any, cut: RocketCut): void {
|
|
const origin = block.rocketOrigin || block.node.uuid;
|
|
const x = block.posX, y = block.posY;
|
|
if (!cut.fragments.length) {
|
|
block.allBlocks.forEach(p => {
|
|
const cell = map.mapBlocksWall[x + p.x][y + p.y].getComponent("MapBlock");
|
|
if (cell.block_Id === block.node.uuid) { cell.block_Id = ""; cell.nowColor = -1; }
|
|
});
|
|
map.blocks.splice(map.blocks.indexOf(block.node), 1);
|
|
block.node.active = false;
|
|
block.node.removeFromParent();
|
|
block.node.destroy();
|
|
} else {
|
|
const first = cut.fragments[0];
|
|
const upper = block.type === 1 && block.block_Info.node?.getComponent("Block");
|
|
const template = cc.instantiate(map.Block_Array[first.shape]);
|
|
const floors = block.node.children.filter(node => node.getComponent("Floor")).map(node => ({
|
|
node, x: Math.round((node.x + 65) / 120), y: Math.round((node.y - 60) / 120),
|
|
time: node.getComponent("Floor").time
|
|
}));
|
|
// 只有普通块及其普通地板/问号覆盖允许分裂,因此没有钥匙等附件归属转移。
|
|
const info = cut.fragments.length > 1 ? JSON.parse(JSON.stringify(block.block_Info)) : null;
|
|
if (info) {
|
|
const question = block.node.getChildByName("question");
|
|
if (question) info.questionTime = question.getComponent("Question").time;
|
|
floors.forEach(floor => {
|
|
if (!RAINBOW_SHAPES[first.shape].some(p => p.x + first.offset.x === floor.x && p.y + first.offset.y === floor.y)) {
|
|
floor.node.active = false;
|
|
floor.node.removeFromParent();
|
|
floor.node.destroy();
|
|
}
|
|
});
|
|
}
|
|
if (upper) { upper.posX = x; upper.posY = y; }
|
|
reshape(map, block, first, template, false);
|
|
block.rocketOrigin = origin;
|
|
if (upper) {
|
|
reshape(map, upper, first, template, true);
|
|
const offset = upper.getStackingPos();
|
|
upper.node.setPosition(block.node.x + offset.x, block.node.y + offset.y);
|
|
upper.stacking = cc.v2(offset.x, offset.y);
|
|
upper.startPos = upper.node.position.clone();
|
|
}
|
|
template.destroy();
|
|
for (const fragment of cut.fragments.slice(1)) {
|
|
const node = cc.instantiate(map.Block_Array[fragment.shape]);
|
|
const cell = map.mapBlocksWall[x + fragment.offset.x][y + fragment.offset.y];
|
|
node.parent = map.node;
|
|
node.setPosition(cell.x + 65, cell.y - 60);
|
|
const ids = map.blocks.map(n => Number(n.getComponent("Block").blockId) || 0);
|
|
const extra = node.getComponent("Block");
|
|
extra.init({ ...info, id: Math.max(0, ...ids) + 1, block: fragment.shape,
|
|
position: { x: node.x, y: node.y } }, null, null, null, null);
|
|
extra.rocketOrigin = origin;
|
|
node.children.forEach(child => {
|
|
const floor = child.getComponent("Floor");
|
|
if (!floor) return;
|
|
const px = Math.round((child.x + 65) / 120), py = Math.round((child.y - 60) / 120);
|
|
const old = floors.find(p => p.x === px + fragment.offset.x && p.y === py + fragment.offset.y);
|
|
floor.init(old.time, extra.posX + px, extra.posY + py);
|
|
});
|
|
map.blocks.push(node);
|
|
extra.cmupdate();
|
|
}
|
|
refreshLinks(map, upper ? [block, upper] : [block]);
|
|
block.cmupdate();
|
|
}
|
|
map.blockNum = map.blocks.length;
|
|
}
|