feat(rbxl): RegenerationScript no-op + реактивный Humanoid
8. RegenerationScript: эвристика по имени скрипта (regenerate*/
regenerationscript) → пропускается. У нас Anchored=True для импорта,
постройки не разрушаются, регенерация не нужна. Их работа дала бы
визуальные глитчи (model:remove + Clone каждые 2 мин).
9. BattleArmor: Humanoid.MaxHealth/Health/WalkSpeed/JumpPower теперь
реактивные (Object.defineProperty). При смене .MaxHealth=N шлёт
playerSet → player.maxHp обновляется → HUD HP-бар. BattleArmor
touch'нул → Humanoid.MaxHealth=20, Health=20 → игрок видит броню.
10. WinGui/FireButton: GUI-элементы из StarterGui приходят через
converter scene.gui[] и рендерятся стандартно. Если визуально не
идеально — это про GuiManager позиционирование, не специфично
для импорта.
11. AdminConsole: no-op, скрипт-заглушка, ничего не делает.
13. NotLinkedBlocker: слишком специфично (отмена урона через флаг
блока), пропускаю.
ROBLOX Battle итог: 9 механик реализованы (1-7, 12, 14), 2 решены
no-op (8, 11), 3 не критичны (10, 13). Карта должна играться.
This commit is contained in:
parent
913283ffa6
commit
932ef2bc20
@ -134,6 +134,13 @@ export class GameRuntime {
|
||||
// запуск немедленно крашит coroutine (WASM access out of bounds).
|
||||
const meta = parseRobloxLuaMeta(s.code);
|
||||
if (meta && meta.enabled === false) { rbxlSkipped++; continue; }
|
||||
// Пропускаем Regeneration-скрипты: у нас Anchored=True для
|
||||
// импорта, постройки не разрушаются, регенерация не нужна.
|
||||
// Их работа (model:remove + Clone) даст визуальные глитчи.
|
||||
const sname = String(s.name || '').toLowerCase();
|
||||
if (sname.startsWith('regenerate') || sname === 'regenerationscript') {
|
||||
rbxlSkipped++; continue;
|
||||
}
|
||||
const luaSource = unpackRobloxLuaCode(s.code);
|
||||
if (luaSource && luaSource.trim()) {
|
||||
// Эвристика Tool: если скрипт ссылается на Equipped/Activated
|
||||
@ -4258,6 +4265,12 @@ export class GameRuntime {
|
||||
try { player.walkSpeed = Number(payload.value) || player.walkSpeed; } catch (_) {}
|
||||
} else if (payload.prop === 'jumpPower') {
|
||||
try { player.jumpPower = Number(payload.value) || player.jumpPower; } catch (_) {}
|
||||
} else if (payload.prop === 'maxHealth') {
|
||||
try {
|
||||
const max = Math.max(1, Number(payload.value) || 100);
|
||||
player.maxHp = max;
|
||||
if (player.hp > max) player.hp = max;
|
||||
} catch (_) {}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -831,10 +831,31 @@ export function registerRobloxShim(lua, opts) {
|
||||
|
||||
const humanoid = newInstance('Humanoid', 'Humanoid');
|
||||
humanoid.Parent = character;
|
||||
humanoid.Health = 100;
|
||||
humanoid.MaxHealth = 100;
|
||||
humanoid.WalkSpeed = 16;
|
||||
humanoid.JumpPower = 50;
|
||||
let _hp = 100, _maxHp = 100, _ws = 16, _jp = 50;
|
||||
Object.defineProperty(humanoid, 'Health', {
|
||||
get() { return _hp; },
|
||||
set(v) {
|
||||
_hp = Math.max(0, Math.min(_maxHp, Number(v) || 0));
|
||||
try { humanoid.HealthChanged.Fire(_hp); } catch (_) {}
|
||||
send('playerSet', { prop: 'health', value: _hp });
|
||||
},
|
||||
});
|
||||
Object.defineProperty(humanoid, 'MaxHealth', {
|
||||
get() { return _maxHp; },
|
||||
set(v) {
|
||||
_maxHp = Math.max(1, Number(v) || 100);
|
||||
if (_hp > _maxHp) humanoid.Health = _maxHp;
|
||||
send('playerSet', { prop: 'maxHealth', value: _maxHp });
|
||||
},
|
||||
});
|
||||
Object.defineProperty(humanoid, 'WalkSpeed', {
|
||||
get() { return _ws; },
|
||||
set(v) { _ws = Number(v) || 16; send('playerSet', { prop: 'walkSpeed', value: _ws }); },
|
||||
});
|
||||
Object.defineProperty(humanoid, 'JumpPower', {
|
||||
get() { return _jp; },
|
||||
set(v) { _jp = Number(v) || 50; send('playerSet', { prop: 'jumpPower', value: _jp }); },
|
||||
});
|
||||
humanoid.Died = makeSignal();
|
||||
humanoid.HealthChanged = makeSignal();
|
||||
humanoid.Touched = makeSignal();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user