diff --git a/src/community/docsGamesBuildersLua.js b/src/community/docsGamesBuildersLua.js index 259533c..84cfddd 100644 --- a/src/community/docsGamesBuildersLua.js +++ b/src/community/docsGamesBuildersLua.js @@ -2607,26 +2607,129 @@ end)`; // ИГРА 30 — «Квесты» // ═══════════════════════════════════════════════════════════════ 'quest-tasks': { - g30_main: `-- === ИГРА «КВЕСТЫ» (Lua) === + g30_main: `-- === ИГРА «КВЕСТ С ЗАДАНИЯМИ» — главный скрипт (Lua) === ${SNIPPET_BROADCAST} -local quests = { - { name = "Собери 5 ягод", goal = 5, current = 0 }, - { name = "Победи врага", goal = 1, current = 0 }, - { name = "Дойди до башни", goal = 1, current = 0 }, -} +local stage = 0 -- 0=не начат, 1=собрать монетку, 2=дойти до флага, 3=вернуться, 4=готово -print("Квесты:") -for i, q in ipairs(quests) do print(" " .. i .. ". " .. q.name) end +local function setObjective(text, color) + __rbxl_hud_set("objective", "ЦЕЛЬ: " .. text, 50, 8, color or "#ffe066", 24) +end +setObjective("подойди к квестодателю и нажми E") -local ev = getEvent("QuestProgress") -ev.Event:Connect(function(idx, amount) - quests[idx].current = quests[idx].current + (amount or 1) - local q = quests[idx] - print(q.name .. ": " .. q.current .. "/" .. q.goal) - if q.current >= q.goal then - print("Квест выполнен: " .. q.name) +-- Спавним NPC рядом с тумбой (NPC = квестодатель) +local npcRef = __rbxl_spawn_npc("character-a", 1.5, 1, 2, "Старейшина", 100, 0) + +local coinSound = Instance.new("Sound", workspace) +coinSound.SoundId = "coin"; coinSound.Volume = 0.7 +local pickupSound = Instance.new("Sound", workspace) +pickupSound.SoundId = "pickup"; pickupSound.Volume = 0.7 +local winSound = Instance.new("Sound", workspace) +winSound.SoundId = "win"; winSound.Volume = 1 + +-- Поговорить с NPC +local talkEvent = getEvent("Talk") +talkEvent.Event:Connect(function() + if stage == 0 then + stage = 1 + __rbxl_npc_say(npcRef, "Задание 1: найди жёлтую монетку!", 4) + setObjective("собери жёлтую монетку (слева)") + elseif stage == 3 then + stage = 4 + __rbxl_npc_say(npcRef, "Молодец! Квест выполнен!", 4) + __rbxl_hud_set("objective", "КВЕСТ ПРОЙДЕН!", 50, 8, "#22dd55", 26) + __rbxl_show_text("Победа! Квест пройден!", 5) + winSound:Play() + local px = __rbxl_player_x() + local py = __rbxl_player_y() + local pz = __rbxl_player_z() + __rbxl_spawn_particles("confetti", px, py + 3, pz, 3, 3) + elseif stage == 4 then + __rbxl_npc_say(npcRef, "Спасибо, герой!", 3) + elseif stage == 1 then + __rbxl_npc_say(npcRef, "Ты ещё не собрал монетку!", 3) + elseif stage == 2 then + __rbxl_npc_say(npcRef, "Сначала дойди до синего флага!", 3) end +end) + +-- Монетка собрана +local coinEvent = getEvent("CoinDone") +coinEvent.Event:Connect(function() + if stage ~= 1 then return end + stage = 2 + coinSound:Play() + __rbxl_npc_say(npcRef, "Отлично! Теперь дойди до синего флага.", 4) + __rbxl_show_text("Монетка собрана!", 2) + setObjective("дойди до синего флага (справа)") +end) + +-- Флаг достигнут +local flagEvent = getEvent("FlagDone") +flagEvent.Event:Connect(function() + if stage ~= 2 then return end + stage = 3 + pickupSound:Play() + __rbxl_show_text("Флаг найден!", 2) + setObjective("вернись к квестодателю и нажми E") +end)`, + g30_npc: `-- === Скрипт квестодателя (Lua) === +local UserInputService = game:GetService("UserInputService") +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local RunService = game:GetService("RunService") +local part = script.Parent +local hintVisible = false + +RunService.Heartbeat:Connect(function() + local px = __rbxl_player_x() + local pz = __rbxl_player_z() + local dx = part.Position.X - px + local dz = part.Position.Z - pz + local dist = math.sqrt(dx*dx + dz*dz) + local near = dist <= 4 + if near ~= hintVisible then + hintVisible = near + if near then + __rbxl_hud_set("g30_npc_hint", "[E] Поговорить", 50, 75, "#ffe44a", 20) + else + __rbxl_hud_set("g30_npc_hint", nil) + end + end +end) + +UserInputService.InputBegan:Connect(function(input, gp) + if gp then return end + if not hintVisible then return end + if input.KeyCode ~= Enum.KeyCode.E then return end + local ev = ReplicatedStorage:FindFirstChild("Talk") + if ev then ev:Fire() end +end)`, + g30_coin: `-- === Скрипт квест-монетки (Lua) === +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local part = script.Parent +local taken = false + +part.Touched:Connect(function(hit) + if taken then return end + local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") + if not h then return end + taken = true + local ev = ReplicatedStorage:FindFirstChild("CoinDone") + if ev then ev:Fire() end + part:Destroy() +end)`, + g30_flag: `-- === Скрипт квест-флага (Lua) === +local ReplicatedStorage = game:GetService("ReplicatedStorage") +local part = script.Parent +local fired = false + +part.Touched:Connect(function(hit) + if fired then return end + local h = hit.Parent and hit.Parent:FindFirstChild("Humanoid") + if not h then return end + fired = true + local ev = ReplicatedStorage:FindFirstChild("FlagDone") + if ev then ev:Fire() end end)`, }, diff --git a/src/community/docsLessons.jsx b/src/community/docsLessons.jsx index fea3530..80ff32e 100644 --- a/src/community/docsLessons.jsx +++ b/src/community/docsLessons.jsx @@ -4019,7 +4019,7 @@ game.self.onTouch(() => { продаёт ключ, открывает дверь.

- {`// === ИГРА «МАГАЗИН» — главный скрипт === + {`// === ИГРА «МАГАЗИН» — главный скрипт === let coins = 0; const PRICE = 5; // ключ стоит 5 монет @@ -4070,7 +4070,7 @@ game.onMessage('win', () => { const p = game.player.position; game.scene.spawnParticles('confetti', { x: p.x, y: p.y + 3, z: p.z }, { duration: 3, count: 3 }); -});`} +});`}

Каждый объект магазина — монетка, прилавок, дверь, финиш — работает в своей «песочнице» и не видит переменные @@ -4100,23 +4100,23 @@ game.onMessage('win', () => {

Шаг 3. Скрипт монетки

- {`// === Скрипт монетки === + {`// === Скрипт монетки === game.self.onTouch(() => { game.broadcast('coin'); game.self.delete(); -});`} +});`}

Шаг 4. Скрипт прилавка и двери

- {`// === Скрипт прилавка === + {`// === Скрипт прилавка === game.self.onInteract(() => { game.broadcast('buy'); -}, { text: 'Купить ключ (5 монет)', distance: 4 });`} +}, { text: 'Купить ключ (5 монет)', distance: 4 });`} - {`// === Скрипт двери === + {`// === Скрипт двери === game.self.onInteract(() => { game.broadcast('open-door'); -}, { text: 'Открыть дверь', distance: 4 });`} +}, { text: 'Открыть дверь', distance: 4 });`}

И прилавок, и дверь — это объекты с взаимодействием по E. Подошёл к прилавку и нажал