feat: 50 игр на Lua + импорт Roblox для всех + поддержка Lua в плеере #39
@ -1763,30 +1763,21 @@ for i, e in ipairs(enemies) do
|
||||
end)
|
||||
end
|
||||
|
||||
-- Клик по сцене — бьём ближайшего врага в радиусе 4
|
||||
UserInputService.InputBegan:Connect(function(input, gp)
|
||||
if gp then return end
|
||||
if input.UserInputType ~= Enum.UserInputType.MouseButton1 then return end
|
||||
if won then return end
|
||||
local px = __rbxl_player_x()
|
||||
local pz = __rbxl_player_z()
|
||||
-- Клик по конкретному NPC (как в Тире — pick по 3D-объекту).
|
||||
-- BabylonScene выполняет raycast при ЛКМ и шлёт click с target=NPC.
|
||||
-- Регистрируем callback для каждого врага по его локальному ref.
|
||||
for _, e in ipairs(enemies) do
|
||||
if not e._dead and e.hp > 0 then
|
||||
local dx = e.x - px
|
||||
local dz = e.z - pz
|
||||
local dist = math.sqrt(dx*dx + dz*dz)
|
||||
if dist < 4 then
|
||||
e.hp = e.hp - 30
|
||||
if e.hp < 0 then e.hp = 0 end
|
||||
__rbxl_npc_damage(e.ref, 30)
|
||||
__rbxl_set_label(e.ref, e.name .. " HP: " .. e.hp, "#ff5555", 3)
|
||||
__rbxl_spawn_particles("sparks", e.x, 2, e.z, 0.4, 1)
|
||||
local enemy = e -- замыкание
|
||||
__rbxl_npc_on_click(enemy.ref, function()
|
||||
if enemy._dead or won then return end
|
||||
enemy.hp = enemy.hp - 30
|
||||
if enemy.hp < 0 then enemy.hp = 0 end
|
||||
__rbxl_npc_damage(enemy.ref, 30)
|
||||
__rbxl_set_label(enemy.ref, enemy.name .. " HP: " .. enemy.hp, "#ff5555", 3)
|
||||
__rbxl_spawn_particles("sparks", enemy.x, 2, enemy.z, 0.4, 1)
|
||||
hitSound:Play()
|
||||
break -- бьём только одного за клик
|
||||
end
|
||||
end
|
||||
end
|
||||
end)`,
|
||||
end)
|
||||
end`,
|
||||
},
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════
|
||||
|
||||
@ -3035,6 +3035,7 @@ export class BabylonScene {
|
||||
if (md.isBlock) {
|
||||
return { kind: 'block', ref: { x: md.gridX, y: md.gridY, z: md.gridZ } };
|
||||
}
|
||||
if (md.npcId != null) return { kind: 'npc', id: md.npcId };
|
||||
if (md.isModel) return { kind: 'model', id: md.instanceId };
|
||||
if (md.isPrimitive) return { kind: 'primitive', id: md.primitiveId };
|
||||
return null;
|
||||
|
||||
@ -1895,6 +1895,10 @@ export function registerRobloxShim(lua, opts) {
|
||||
global.set('__rbxl_npc_on_death', (ref, fn) => {
|
||||
if (typeof fn === 'function') _npcDeathCbs.set(String(ref || ''), fn);
|
||||
});
|
||||
const _npcClickCbs = new Map(); // localRef → fn
|
||||
global.set('__rbxl_npc_on_click', (ref, fn) => {
|
||||
if (typeof fn === 'function') _npcClickCbs.set(String(ref || ''), fn);
|
||||
});
|
||||
// Инвентарь invUI — паритет с JS game.inventory.add(itemId, count).
|
||||
// Сначала определяем итем (один раз), потом добавляем.
|
||||
const _localInventory = new Map();
|
||||
@ -2302,6 +2306,20 @@ export function registerRobloxShim(lua, opts) {
|
||||
try { equippedTool.Deactivated.Fire(); } catch (_) {}
|
||||
}
|
||||
// Mouse-события из плеера: клики, движение, клавиши при equipped Tool
|
||||
// BabylonScene шлёт глобальный 'click' при ЛКМ. Если в payload
|
||||
// target — это попадание по 3D-объекту. Для NPC фейерим cb.
|
||||
if (p.type === 'click' && p.target && p.target.kind === 'npc' && p.target.id != null) {
|
||||
const realRef = 'npc:' + p.target.id;
|
||||
let localRef = null;
|
||||
for (const [k, v] of _localToRealNpc.entries()) {
|
||||
if (v === realRef) { localRef = k; break; }
|
||||
}
|
||||
for (const [ref, fn] of _npcClickCbs.entries()) {
|
||||
if (ref === realRef || ref === localRef) {
|
||||
_pendingHandlerQueue.push({ fn, args: [] });
|
||||
}
|
||||
}
|
||||
}
|
||||
// BabylonScene шлёт глобальный 'click' при ЛКМ — это эквивалент
|
||||
// mouseButton1Down. Мапим в наши handler-ы.
|
||||
if (p.type === 'click' || p.type === 'mouseButton1Down') {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user