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
Showing only changes of commit 598b91bd9e - Show all commits

View File

@ -394,7 +394,8 @@ function newInstance(className, name) {
GetPropertyChangedSignal: m.GetPropertyChangedSignal, GetPropertyChangedSignal: m.GetPropertyChangedSignal,
}; };
// Proxy: для unknown свойств возвращаем stub чтобы скрипты не падали. // Proxy: для unknown свойств возвращаем stub чтобы скрипты не падали.
return new Proxy(target, { let proxyRef;
proxyRef = new Proxy(target, {
get(t, prop) { get(t, prop) {
// Существующее свойство всегда возвращаем как есть (включая методы) // Существующее свойство всегда возвращаем как есть (включая методы)
if (Object.prototype.hasOwnProperty.call(t, prop) || prop in t) { if (Object.prototype.hasOwnProperty.call(t, prop) || prop in t) {
@ -417,6 +418,27 @@ function newInstance(className, name) {
return stub; return stub;
}, },
set(t, prop, value) { set(t, prop, value) {
// Авто-управление иерархией при `inst.Parent = X`:
// 1) удаляем себя из Children старого Parent
// 2) пушим в Children нового Parent
// 3) фейерим ChildAdded/ChildRemoved
if (prop === 'Parent') {
const oldP = t.Parent;
if (oldP && oldP.Children) {
const i = oldP.Children.indexOf(proxyRef);
if (i >= 0) {
oldP.Children.splice(i, 1);
try { oldP.ChildRemoved && oldP.ChildRemoved.Fire(proxyRef); } catch (_) {}
}
}
t[prop] = value;
if (value && value.Children && value.Children.indexOf(proxyRef) < 0) {
value.Children.push(proxyRef);
try { value.ChildAdded && value.ChildAdded.Fire(proxyRef); } catch (_) {}
}
try { t.AncestryChanged && t.AncestryChanged.Fire(proxyRef, value); } catch (_) {}
return true;
}
t[prop] = value; t[prop] = value;
return true; return true;
}, },
@ -426,6 +448,7 @@ function newInstance(className, name) {
return true; return true;
}, },
}); });
return proxyRef;
} }
/** /**