75 lines
3.4 KiB
TypeScript
75 lines
3.4 KiB
TypeScript
/** 从实际加载的关卡筛选介绍,不使用玩家进度或首次解锁关卡。 */
|
|
export function getLevelGameplay(config: any[], data: any): any[] {
|
|
const level = data.LEVEL_INFO && data.LEVEL_INFO[0] || {};
|
|
const blocks = (data.BLOCK_INFO && data.BLOCK_INFO[0] || []).slice();
|
|
const walls = data.WALL_INFO && data.WALL_INFO[0] || [];
|
|
const names = new Set<string>();
|
|
const add = (id: number) => names.add("daoju" + id);
|
|
|
|
// 生成区域里尚未出场的方块也属于本关;不扫描会随消除而变化的场景节点。
|
|
const gates = level.spawnGates || [];
|
|
if (gates.length) add(33);
|
|
gates.forEach(gate => (gate.spawnQueue || []).forEach(item => {
|
|
blocks.push(...(item.members || []));
|
|
}));
|
|
|
|
blocks.forEach(block => {
|
|
if (!block || block.block == null || Number(block.block) === 23) return;
|
|
const type = Number(block.type);
|
|
switch (type) {
|
|
case 1: case 10: add(block.colorChange != null ? 21 : 1); break;
|
|
case 2: case 3: case 12: case 13: add(4); break;
|
|
case 4: add(2); break;
|
|
case 5: add(3); break;
|
|
case 6: add(7); break;
|
|
case 7: case 8: add(Number(block.lockTime) > 0 ? 31 : 0); break;
|
|
case 9: case 19: add(Number(block.lockTime) > 0 ? 17 : 5); break;
|
|
case 11: add(11); break;
|
|
case 14: add(14); break;
|
|
case 16: add(16); break;
|
|
case 17: add(18); break;
|
|
case 20: add(25); break;
|
|
case 21: add(22); break;
|
|
case 22: add(28); break;
|
|
}
|
|
if (block.vertical || block.horizontal) add(0);
|
|
if (Number(block.color) === 11 || ((type === 1 || type === 10) && Number(block.stacking) === 11)) add(11);
|
|
if (block.colorArray != null) add(25);
|
|
if (block.lock != null) add(19); // 铁皮的开/合两种状态都需要介绍。
|
|
if (block.flowerSend || block.flowerReceive) add(24);
|
|
// 花盆接收块借用 floor 实现碰撞,它的盖板不可见,不额外展示快递盒。
|
|
if (block.floor && block.floorTime && !block.flowerReceive) {
|
|
add(block.floorMove === true ? 20 : block.floorMove === false && block.floorColor != null ? 29 : 12);
|
|
}
|
|
});
|
|
|
|
walls.forEach(wall => {
|
|
switch (Number(wall.special)) {
|
|
case 1: add(3); break;
|
|
case 2: add(6); break;
|
|
case 3: add(9); break;
|
|
case 4: case 5: add(10); break; // 果酱沿门移动。
|
|
case 6: add(14); break;
|
|
case 7: add(23); break; // 箭头挡板。
|
|
case 9: add(27); break; // 伸缩障碍杆。
|
|
case 10: case 11: add(26); break; // 带色挡板移动时覆盖其它门。
|
|
}
|
|
if (wall.colorArray) add(13);
|
|
if (wall.longAndShort) add(15);
|
|
if (wall.toggle) add(30);
|
|
});
|
|
(level.risefall || []).forEach(tile => {
|
|
if (Object.prototype.hasOwnProperty.call(tile, "vine")) {
|
|
if (Number(tile.vine) > 0) add(32);
|
|
} else add(tile.unLockFall ? 30 : 8);
|
|
});
|
|
|
|
// 沿用介绍的配置顺序,每种玩法只留一页,不因解锁关卡而漏掉实际出现的道具。
|
|
const seen = new Set<string>();
|
|
return (config || []).filter(entry => {
|
|
if (!names.has(entry.name) || seen.has(entry.name)) return false;
|
|
seen.add(entry.name);
|
|
return true;
|
|
});
|
|
}
|