feat: 50 игр на Lua + импорт Roblox для всех + поддержка Lua в плеере #39

Merged
min merged 215 commits from feat/lua-50-games-bundle into main 2026-06-09 21:59:25 +00:00
2 changed files with 26 additions and 11 deletions
Showing only changes of commit d6a874c8a0 - Show all commits

View File

@ -3271,7 +3271,30 @@ export class BabylonScene {
} }
if (!this.gameRuntime) return; if (!this.gameRuntime) return;
const pick = this._pickFromCenter(); // В pointer-lock (1-е лицо) курсор скрыт в центре — пикаем центром.
// В 3-м лице (свободный курсор) — пикаем по координатам клика.
const locked = (document.pointerLockElement === this.canvas);
let pick;
if (!locked && Number.isFinite(clickX) && Number.isFinite(clickY)) {
const pi = this.scene.pick(clickX, clickY, (mesh) => {
if (!mesh.isPickable) return false;
if (mesh === this._ghostMesh) return false;
if (mesh.name && mesh.name.startsWith('gridLine')) return false;
return true;
});
if (pi?.hit) {
let m = pi.pickedMesh;
if (m?.metadata?._isBlockProto && this.blockManager) {
const proxy = this.blockManager.findProxyByPickInfo(pi);
if (proxy) m = proxy;
}
pick = { mesh: m, point: pi.pickedPoint, pickInfo: pi };
} else {
pick = null;
}
} else {
pick = this._pickFromCenter();
}
const target = pick?.mesh ? this._meshToTarget(pick.mesh) : null; const target = pick?.mesh ? this._meshToTarget(pick.mesh) : null;
const point = pick?.point ? { x: pick.point.x, y: pick.point.y, z: pick.point.z } : null; const point = pick?.point ? { x: pick.point.x, y: pick.point.y, z: pick.point.z } : null;
// 1) Self-onClick — только если target есть // 1) Self-onClick — только если target есть

View File

@ -2173,27 +2173,19 @@ export function registerRobloxShim(lua, opts) {
if (!p) return; if (!p) return;
const id = p.primId ?? p.target; const id = p.primId ?? p.target;
const part = partById.get(Number(id)); const part = partById.get(Number(id));
if (p.kind === 'click') {
// eslint-disable-next-line no-console
console.warn('[shim fireTargetEvent click] primId=', id, 'part=', !!part);
}
if (!part) return; if (!part) return;
if (p.kind === 'touch' || p.kind === 'touched') { if (p.kind === 'touch' || p.kind === 'touched') {
part.Touched.Fire(hrp); part.Touched.Fire(hrp);
} else if (p.kind === 'untouch' || p.kind === 'untouched') { } else if (p.kind === 'untouch' || p.kind === 'untouched') {
part.TouchEnded.Fire(hrp); part.TouchEnded.Fire(hrp);
} else if (p.kind === 'click') { } else if (p.kind === 'click') {
// ClickDetector создаётся лениво — стрельба по 3D-объектам. // ClickDetector — стрельба по 3D-объектам.
// Фейерим без аргумента (передача объектов в Lua через wasmoon // Фейерим без аргумента (передача объектов в Lua через wasmoon
// может крашить с null.then). // может крашить с null.then).
try { try {
const cd = part._clickDetector; const cd = part._clickDetector;
// eslint-disable-next-line no-console
console.warn('[shim click]', 'partId=', id, 'cd=', !!cd, 'sig=', !!cd?.MouseClick, 'conns=', cd?.MouseClick?.connections?.length);
if (cd && cd.MouseClick) cd.MouseClick.Fire(); if (cd && cd.MouseClick) cd.MouseClick.Fire();
} catch (e) { } catch (_) {}
console.warn('[shim click err]', e?.message || e);
}
try { try {
if (part.Clicked) part.Clicked.Fire(); if (part.Clicked) part.Clicked.Fire();
} catch (_) {} } catch (_) {}