diff --git a/src/community/docsGamesBuildersLua.js b/src/community/docsGamesBuildersLua.js index e2503c8..c759168 100644 --- a/src/community/docsGamesBuildersLua.js +++ b/src/community/docsGamesBuildersLua.js @@ -1059,60 +1059,30 @@ pickupSound.SoundId = "pickup"; pickupSound.Volume = 0.8 local winSound = Instance.new("Sound", workspace) winSound.SoundId = "win"; winSound.Volume = 1 --- Спавним "торговца" — фигурка из 3 кубов за прилавком на (0, ?, 5) --- Прилавок на x=0, z=3, sz=1.5 → задняя часть z=3.75. Ставим торговца на z=5. --- Туловище -__rbxl_spawn_part({ - type = "cube", name = "ТорговецТело", - x = 0, y = 2.0, z = 5, - sx = 1.2, sy = 1.6, sz = 0.6, - color = "#3b82f6", anchored = true, canCollide = false, -}) --- Голова -__rbxl_spawn_part({ - type = "sphere", name = "ТорговецГолова", - x = 0, y = 3.2, z = 5, - sx = 0.8, sy = 0.8, sz = 0.8, - color = "#fcd9b6", anchored = true, canCollide = false, -}) --- Шляпа -__rbxl_spawn_part({ - type = "cylinder", name = "ТорговецШляпа", - x = 0, y = 3.8, z = 5, - sx = 1.0, sy = 0.3, sz = 1.0, - color = "#7a4a26", anchored = true, canCollide = false, -}) +-- Спавним NPC-торговца за прилавком (паритет с JS spawnNpc) +local traderRef = __rbxl_spawn_npc("character-a", 0, 1, 5, "Торговец Боб", 100, 0) --- Простой "инвентарь" в HUD: ключ -local screenGui = Instance.new("ScreenGui", player.PlayerGui) -local invLabel = Instance.new("TextLabel", screenGui) -invLabel.Size = UDim2.new(0, 220, 0, 40) -invLabel.Position = UDim2.new(1, -240, 0, 20) -invLabel.BackgroundColor3 = Color3.fromRGB(0, 0, 0) -invLabel.BackgroundTransparency = 0.4 -invLabel.TextColor3 = Color3.fromRGB(255, 215, 0) -invLabel.TextScaled = true -invLabel.Font = Enum.Font.SourceSansBold -invLabel.Text = "Ключа нет" +-- Определяем итем "Ключ" в инвентаре и показываем hotbar +__rbxl_inventory_define("key", "Ключ", "#ffd700") -- Игрок заговорил с торговцем local talkEvent = getEvent("TalkTrader") talkEvent.Event:Connect(function() if hasKey then - __rbxl_show_text("Торговец: Иди к двери, ключ у тебя!", 3) + __rbxl_npc_say(traderRef, "Иди к двери, ключ у тебя!", 3) return end hasKey = true - invLabel.Text = "У тебя есть Ключ" - invLabel.TextColor3 = Color3.fromRGB(100, 255, 100) - __rbxl_show_text("Торговец: Привет! Вот тебе ключ от двери. Удачи!", 4) + __rbxl_npc_say(traderRef, "Привет! Вот тебе ключ от двери. Удачи!", 4) + __rbxl_inventory_add("key", 1) + __rbxl_show_text("Ты получил Ключ!", 2) pickupSound:Play() end) -- Игрок пытается открыть дверь local openEvent = getEvent("OpenDoor") openEvent.Event:Connect(function() - if not hasKey then + if not __rbxl_inventory_has("key") then __rbxl_show_text("Дверь заперта. Нужен ключ от торговца.", 2) return end diff --git a/src/editor/engine/lua/RobloxShim.js b/src/editor/engine/lua/RobloxShim.js index e85c597..e148a77 100644 --- a/src/editor/engine/lua/RobloxShim.js +++ b/src/editor/engine/lua/RobloxShim.js @@ -1816,6 +1816,65 @@ export function registerRobloxShim(lua, opts) { color: color || '#ffffff', }); }); + // Спавн NPC — паритет с JS game.scene.spawnNpc(modelType, opts). + // Возвращает локальный ref (строку 'npc_lua_N'), который можно передавать + // в __rbxl_npc_say(ref, text, duration). + let _nextNpcRef = 0; + global.set('__rbxl_spawn_npc', (modelType, x, y, z, name, hp, speed) => { + const ref = 'npc_lua_' + (_nextNpcRef++); + send('npc.spawn', { + modelType: String(modelType || 'character-a'), + ref, + x: +x || 0, y: +y || 0, z: +z || 0, + name: name ? String(name) : undefined, + hp: hp != null ? +hp : undefined, + speed: speed != null ? +speed : undefined, + }); + return ref; + }); + global.set('__rbxl_npc_say', (ref, text, duration) => { + send('npc.say', { + ref: String(ref || ''), + text: String(text || ''), + duration: +duration || 3, + }); + }); + // Инвентарь invUI — паритет с JS game.inventory.add(itemId, count). + // Сначала определяем итем (один раз), потом добавляем. + const _localInventory = new Map(); + const _definedItems = new Set(); + global.set('__rbxl_inventory_define', (itemId, name, color) => { + const id = String(itemId || ''); + if (!id || _definedItems.has(id)) return; + _definedItems.add(id); + send('items.define', { + def: { + id, + name: name ? String(name) : id, + color: color || '#ffd700', + stack: 99, + }, + }); + }); + global.set('__rbxl_inventory_add', (itemId, count) => { + const id = String(itemId || ''); + if (!id) return; + const c = Number(count) || 1; + _localInventory.set(id, (_localInventory.get(id) || 0) + c); + send('inv2.add', { itemId: id, count: c }); + }); + global.set('__rbxl_inventory_has', (itemId) => { + return (_localInventory.get(String(itemId || '')) || 0) > 0; + }); + global.set('__rbxl_inventory_remove', (itemId, count) => { + const id = String(itemId || ''); + const c = Number(count) || 1; + const cur = _localInventory.get(id) || 0; + const newCount = Math.max(0, cur - c); + if (newCount === 0) _localInventory.delete(id); + else _localInventory.set(id, newCount); + send('inv2.remove', { itemId: id, count: c }); + }); // Подброс игрока — паритет с JS game.player.boostJump(strength). // 1.0 = обычный прыжок, 3.0 = втрое выше, и т.д. global.set('__rbxl_boost_jump', (strength) => {