/** 从实际加载的关卡筛选介绍,不使用玩家进度或首次解锁关卡。 */ 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(); 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(); return (config || []).filter(entry => { if (!names.has(entry.name) || seen.has(entry.name)) return false; seen.add(entry.name); return true; }); }