2145 lines
72 KiB
Lua
2145 lines
72 KiB
Lua
local base_url = "http://dev.pavetr.ru/server/senwai-mmk/posters/"
|
||
|
||
local agits = {
|
||
{
|
||
pos = Vector(2351.97, -62, 160),
|
||
ang = Angle(0, 180, 90),
|
||
url = base_url .. "soup.png",
|
||
width = 500,
|
||
height = 400,
|
||
scale = 0.1,
|
||
show = "m"
|
||
},
|
||
{
|
||
pos = Vector(2270, -62, 160),
|
||
ang = Angle(0, 180, 90),
|
||
url = base_url .. "whatissup.png",
|
||
width = 500,
|
||
height = 400,
|
||
scale = 0.1,
|
||
show = "u"
|
||
},
|
||
{
|
||
pos = Vector(-626.13, -965, 160),
|
||
ang = Angle(0, 0, 90),
|
||
url = base_url .. "supforpidor.png",
|
||
width = 400,
|
||
height = 500,
|
||
scale = 0.1,
|
||
show = "m"
|
||
},
|
||
{
|
||
pos = Vector(2661.47, -1540, 160),
|
||
ang = Angle(0, 180, 90),
|
||
url = base_url .. "senwaidox.png",
|
||
width = 500,
|
||
height = 400,
|
||
scale = 0.1,
|
||
show = "u"
|
||
},
|
||
{
|
||
pos = Vector(89.12, 380, 160),
|
||
ang = Angle(0, 0, 90),
|
||
url = base_url .. "wantsup.png",
|
||
width = 500,
|
||
height = 650,
|
||
scale = 0.1,
|
||
show = "m"
|
||
},
|
||
{
|
||
pos = Vector(5470, 1340, 160),
|
||
ang = Angle(0, -90, 90),
|
||
url = base_url .. "7733sup.png",
|
||
width = 500,
|
||
height = 500,
|
||
scale = 0.1,
|
||
show = "u"
|
||
},
|
||
{
|
||
pos = Vector(1580.32, 2175, 245),
|
||
ang = Angle(0, 0, 90),
|
||
url = base_url .. "jockddos.png",
|
||
width = 500,
|
||
height = 550,
|
||
scale = 0.1,
|
||
show = "m"
|
||
},
|
||
{
|
||
pos = Vector(4300, -4157, 160),
|
||
ang = Angle(0, 180, 90),
|
||
url = base_url .. "10sup.png",
|
||
width = 500,
|
||
height = 500,
|
||
scale = 0.1,
|
||
show = "u"
|
||
},
|
||
{
|
||
pos = Vector(7885, 5905, 1145),
|
||
ang = Angle(0, 90, 90),
|
||
url = base_url .. "sup.png",
|
||
width = 500,
|
||
height = 500,
|
||
scale = 0.1,
|
||
},
|
||
{
|
||
pos = Vector(3776.82, 382, 160),
|
||
ang = Angle(0, 0, 90),
|
||
url = base_url .. "gafich.png",
|
||
width = 550,
|
||
height = 500,
|
||
scale = 0.1,
|
||
},
|
||
{
|
||
pos = Vector(644, -1280, 160),
|
||
ang = Angle(0, 90, 90),
|
||
url = base_url .. "skipper.png",
|
||
width = 700,
|
||
height = 500,
|
||
scale = 0.1,
|
||
},
|
||
{
|
||
pos = Vector(-1035, -2280, 180),
|
||
ang = Angle(0, 90 + 40, 90),
|
||
url = base_url .. "snegiri.png",
|
||
width = 1500,
|
||
height = 800,
|
||
scale = 0.1,
|
||
},
|
||
}
|
||
local u_cnt = 0
|
||
local m_cnt = 0
|
||
for z, v in ipairs(agits) do
|
||
if v.show == "m" then
|
||
m_cnt = m_cnt + 1
|
||
elseif v.show == "u" then
|
||
u_cnt = u_cnt + 1
|
||
end
|
||
end
|
||
|
||
local cur_params
|
||
local save = "kostich_saves.dat"
|
||
|
||
timer.Create("removeRagdolls", 3, 0, function() game.RemoveRagdolls() end)
|
||
|
||
local function save_settings()
|
||
file.Write(save, util.Base64Encode(util.TableToJSON(cur_params)))
|
||
end
|
||
|
||
local def_cfg = {
|
||
hud = "kostich",
|
||
tab = "kostich",
|
||
cmenu = "kostich",
|
||
selector = "kostich",
|
||
posters = "",
|
||
plib = true
|
||
}
|
||
|
||
local function load_settings()
|
||
if file.Exists(save, "DATA") then
|
||
cur_params = util.JSONToTable(util.Base64Decode(file.Read(save, "DATA")))
|
||
for z, v in ipairs(def_cfg) do
|
||
if not cur_params[z] then
|
||
cur_params[z] = v
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if not file.Exists(save, "DATA") then
|
||
cur_params = def_cfg
|
||
save_settings()
|
||
else
|
||
load_settings()
|
||
end
|
||
|
||
gameevent.Listen("client_disconnect")
|
||
hook.Add("client_disconnect", "kostich.saveOnExit", function(data)
|
||
save_settings()
|
||
end)
|
||
|
||
kostich = kostich or {}
|
||
function kostich.getValue(key)
|
||
return cur_params[key]
|
||
end
|
||
|
||
local red = Color(255, 0, 0)
|
||
|
||
-- 5.5 sec
|
||
function kostich.ss1()
|
||
surface.PlaySound("ambient/levels/labs/electric_explosion1.wav")
|
||
LocalPlayer():ScreenFade(SCREENFADE.IN, Color(0, 0, 0, 255), 0.3, 0)
|
||
timer.Simple(0.3, function()
|
||
cur_params["hud"] = "drp"
|
||
save_settings()
|
||
chat.AddText(red, "[ИВЕНТ] ", color_white, "Ваш худ от сапа исчез и заменился на даркрпшный")
|
||
end)
|
||
|
||
timer.Simple(0.5, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player1.mp3")
|
||
chat.AddText(color_white, "- Блять, что за хуйня!? Куда худ пропал")
|
||
timer.Simple(2.5, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player2.mp3")
|
||
chat.AddText(color_white, "- Я даже хз кто это мог сделать, а хотя...")
|
||
timer.Simple(2.5, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player3.mp3")
|
||
chat.AddText(color_white, "- Точно! Надо у сенвая спросить, он пиздюк еще тот")
|
||
end)
|
||
end)
|
||
end)
|
||
end
|
||
|
||
-- 8.5 sec
|
||
function kostich.ss2()
|
||
surface.PlaySound("ambient/levels/labs/electric_explosion1.wav")
|
||
LocalPlayer():ScreenFade(SCREENFADE.IN, Color(0, 0, 0, 255), 0.3, 0)
|
||
timer.Simple(0.3, function()
|
||
cur_params["plib"] = false
|
||
save_settings()
|
||
chat.AddText(red, "[ИВЕНТ] ", color_white, "У вас отъебнуло plibv2")
|
||
LocalPlayer():ScreenFade(SCREENFADE.IN, Color(0, 0, 0, 255), 0.3, 0)
|
||
end)
|
||
|
||
timer.Simple(1, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player4.mp3")
|
||
chat.AddText(color_white, "- Сука что на этот раз")
|
||
timer.Create("plib_emit_errors", 0.2, 5, function()
|
||
ErrorNoHalt("У вас наебнулся plib_v2")
|
||
end)
|
||
timer.Simple(1.5, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player5.mp3")
|
||
chat.AddText(color_white, "- Ебаный рот какие-то ошибки сука")
|
||
timer.Simple(2, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player6.mp3")
|
||
chat.AddText(color_white, "- Чооо plib2, пиздец сенвай так всю сборку расхуярит")
|
||
timer.Simple(4, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player7.mp3")
|
||
chat.AddText(color_white, "- Надо быстрее к паветру идти")
|
||
end)
|
||
end)
|
||
end)
|
||
end)
|
||
end
|
||
|
||
-- 2 sec
|
||
function kostich.myarena_ddosed()
|
||
surface.PlaySound("ambient/levels/labs/electric_explosion1.wav")
|
||
LocalPlayer():ScreenFade(SCREENFADE.IN, Color(0, 0, 0, 255), 0.3, 0)
|
||
timer.Simple(0.3, function()
|
||
surface.PlaySound("ambient/explosions/explode_8.wav")
|
||
chat.AddText(red, "[ИВЕНТ] ", color_white, "В датацентре что-то взорвалось")
|
||
LocalPlayer():ScreenFade(SCREENFADE.IN, Color(0, 0, 0, 255), 0.3, 0)
|
||
end)
|
||
|
||
timer.Simple(0.5, function()
|
||
surface.PlaySound("plats/elevbell1.wav")
|
||
chat.AddText(color_white, "Filip Bozhenko: Ку мне Васты крашат, я хз чем")
|
||
timer.Simple(0.5, function()
|
||
surface.PlaySound("plats/elevbell1.wav")
|
||
chat.AddText(color_white, "whiteroom: Ку мне Джасты крашат, я хз чем")
|
||
timer.Simple(0.5, function()
|
||
surface.PlaySound("plats/elevbell1.wav")
|
||
chat.AddText(color_white, "senwai: Босс Инферно не дудось пж")
|
||
timer.Simple(0.5, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player8.mp3")
|
||
chat.AddText(color_white, "- Пиздец там все разнесло конечно")
|
||
end)
|
||
end)
|
||
end)
|
||
end)
|
||
end
|
||
|
||
function kostich.hacker_game()
|
||
local stat
|
||
sound.PlayFile("sound/pavetr_mmk/music/Pavetr-Give_Talon.mp3", "noplay", function(station, errCode, errStr)
|
||
if IsValid(station) then
|
||
station:Play()
|
||
station:SetVolume(2)
|
||
stat = station
|
||
else
|
||
print("Error playing sound!", errCode, errStr)
|
||
end
|
||
end)
|
||
local ply = LocalPlayer()
|
||
local rows, cols = 6, 9
|
||
local cellSize = 64
|
||
local spacing = 4
|
||
|
||
local win = vgui.Create("DFrame")
|
||
win:SetTitle("Жигуль бекдур™ Loader")
|
||
win:SetSize(ScrW(), ScrH())
|
||
win:Center()
|
||
win:MakePopup()
|
||
win:SetDraggable(false)
|
||
win:ShowCloseButton(true)
|
||
local col1 = Color(20, 20, 25, 255)
|
||
local col2 = Color(0, 150, 255)
|
||
|
||
local drops = {}
|
||
local next_char_change = 0
|
||
local char_cache = {}
|
||
for i = 33, 126 do table.insert(char_cache, string.char(i)) end
|
||
|
||
win.OnClose = function()
|
||
if IsValid(stat) then
|
||
stat:Stop()
|
||
end
|
||
end
|
||
|
||
win.Paint = function(s, w, h)
|
||
draw.RoundedBox(0, 0, 0, w, h, col1 or Color(0, 0, 0, 240))
|
||
|
||
local fontSize = 18
|
||
local columns = math.floor(w / fontSize)
|
||
|
||
if #drops == 0 then
|
||
for i = 1, columns do
|
||
drops[i] = {
|
||
y = math.random(-h, 0),
|
||
speed = math.random(10, 30),
|
||
text = {}
|
||
}
|
||
for j = 1, 15 do drops[i].text[j] = table.Random(char_cache) end
|
||
end
|
||
end
|
||
|
||
surface.SetFont("ui.18")
|
||
|
||
local time = RealTime()
|
||
local do_change = false
|
||
if time > next_char_change then
|
||
do_change = true
|
||
next_char_change = time + 0.05
|
||
end
|
||
|
||
for i = 1, columns do
|
||
local drop = drops[i]
|
||
|
||
for j = 1, 12 do
|
||
local charY = drop.y - (j * fontSize)
|
||
|
||
if charY < h + fontSize and charY > -fontSize then
|
||
local alpha = 255 - (j * 20)
|
||
if alpha > 0 then
|
||
if j == 1 then
|
||
surface.SetTextColor(200, 255, 200, alpha)
|
||
else
|
||
surface.SetTextColor(0, 255, 0, alpha)
|
||
end
|
||
|
||
surface.SetTextPos((i - 1) * fontSize, charY)
|
||
|
||
if do_change and math.random() > 0.9 then
|
||
drop.text[j] = table.Random(char_cache)
|
||
end
|
||
|
||
surface.DrawText(drop.text[j] or "0")
|
||
end
|
||
end
|
||
end
|
||
|
||
drop.y = drop.y + (drop.speed * FrameTime() * 10)
|
||
|
||
if drop.y > h + 200 then
|
||
drop.y = -fontSize * 2
|
||
drop.speed = math.random(10, 35)
|
||
end
|
||
end
|
||
draw.RoundedBox(0, 0, 0, w, 24, col2 or Color(50, 50, 50))
|
||
draw.SimpleText("Если вы закроете окно, пропишите play_hacker в консоль чтобы начать игру снова", "ui.20", 12, 36,
|
||
color_white)
|
||
end
|
||
|
||
local grid = {}
|
||
local visited = {}
|
||
local stack = {}
|
||
|
||
for y = 1, rows do
|
||
grid[y] = {}
|
||
for x = 1, cols do
|
||
grid[y][x] = {
|
||
type = 0,
|
||
rot = 0,
|
||
powered = false,
|
||
neighbors = { top = false, right = false, bottom = false, left = false }
|
||
}
|
||
end
|
||
end
|
||
|
||
local current = { x = 1, y = 1 }
|
||
visited[1] = { [1] = true }
|
||
table.insert(stack, current)
|
||
|
||
while #stack > 0 do
|
||
local neighbors = {}
|
||
local dirs = {
|
||
{ dx = 0, dy = -1, name = "top", op = "bottom" },
|
||
{ dx = 1, dy = 0, name = "right", op = "left" },
|
||
{ dx = 0, dy = 1, name = "bottom", op = "top" },
|
||
{ dx = -1, dy = 0, name = "left", op = "right" }
|
||
}
|
||
|
||
for _, d in ipairs(dirs) do
|
||
local nx, ny = current.x + d.dx, current.y + d.dy
|
||
if nx > 0 and nx <= cols and ny > 0 and ny <= rows then
|
||
visited[ny] = visited[ny] or {}
|
||
if not visited[ny][nx] then
|
||
table.insert(neighbors, { x = nx, y = ny, dir = d.name, op = d.op })
|
||
end
|
||
end
|
||
end
|
||
|
||
if #neighbors > 0 then
|
||
local nextCell = neighbors[math.random(#neighbors)]
|
||
grid[current.y][current.x].neighbors[nextCell.dir] = true
|
||
grid[nextCell.y][nextCell.x].neighbors[nextCell.op] = true
|
||
current = { x = nextCell.x, y = nextCell.y }
|
||
visited[current.y][current.x] = true
|
||
table.insert(stack, current)
|
||
else
|
||
current = table.remove(stack)
|
||
end
|
||
end
|
||
|
||
for y = 1, rows do
|
||
for x = 1, cols do
|
||
local cell = grid[y][x]
|
||
local c = 0
|
||
if cell.neighbors.top then c = c + 1 end
|
||
if cell.neighbors.right then c = c + 2 end
|
||
if cell.neighbors.bottom then c = c + 4 end
|
||
if cell.neighbors.left then c = c + 8 end
|
||
|
||
if c == 5 or c == 10 then
|
||
cell.type = 1
|
||
elseif c == 3 or c == 6 or c == 9 or c == 12 then
|
||
cell.type = 2
|
||
elseif c == 7 or c == 11 or c == 13 or c == 14 then
|
||
cell.type = 3
|
||
elseif c == 15 then
|
||
cell.type = 4
|
||
else
|
||
cell.type = 1
|
||
end
|
||
|
||
cell.rot = math.random(0, 3)
|
||
end
|
||
end
|
||
|
||
local function GetConnections(type, rot)
|
||
local conns = { false, false, false, false }
|
||
if type == 1 then
|
||
conns = { true, false, true, false }
|
||
elseif type == 2 then
|
||
conns = { true, true, false, false }
|
||
elseif type == 3 then
|
||
conns = { true, true, true, false }
|
||
elseif type == 4 then
|
||
conns = { true, true, true, true }
|
||
end
|
||
|
||
local rotated = {}
|
||
for i = 1, 4 do
|
||
local index = (i - 1 - rot) % 4 + 1
|
||
rotated[i] = conns[index]
|
||
end
|
||
return rotated
|
||
end
|
||
|
||
local function UpdatePower()
|
||
for y = 1, rows do
|
||
for x = 1, cols do
|
||
grid[y][x].powered = false
|
||
end
|
||
end
|
||
|
||
local q = { { x = 1, y = 1 } }
|
||
grid[1][1].powered = true
|
||
|
||
local head = 1
|
||
while head <= #q do
|
||
local curr = q[head]
|
||
head = head + 1
|
||
local cx, cy = curr.x, curr.y
|
||
local cell = grid[cy][cx]
|
||
local conns = GetConnections(cell.type, cell.rot)
|
||
|
||
local dirs = {
|
||
{ dx = 0, dy = -1, idx = 1, opp = 3 },
|
||
{ dx = 1, dy = 0, idx = 2, opp = 4 },
|
||
{ dx = 0, dy = 1, idx = 3, opp = 1 },
|
||
{ dx = -1, dy = 0, idx = 4, opp = 2 }
|
||
}
|
||
|
||
for _, d in ipairs(dirs) do
|
||
if conns[d.idx] then
|
||
local nx, ny = cx + d.dx, cy + d.dy
|
||
if nx > 0 and nx <= cols and ny > 0 and ny <= rows then
|
||
local neighbor = grid[ny][nx]
|
||
local nConns = GetConnections(neighbor.type, neighbor.rot)
|
||
if nConns[d.opp] and not neighbor.powered then
|
||
neighbor.powered = true
|
||
table.insert(q, { x = nx, y = ny })
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
if grid[rows][cols].powered then
|
||
chat.AddText(Color(0, 255, 0), "[ЖИГУЛЬ] ", Color(255, 255, 255),
|
||
"Успех! Файл `bruhdecomp.exe` загружен на сервер Senwai-VDS.")
|
||
surface.PlaySound("buttons/button14.wav")
|
||
RunConsoleCommand("success_hacking")
|
||
win:Close()
|
||
end
|
||
end
|
||
|
||
local container = vgui.Create("DGrid", win)
|
||
container:SetSize(cols * cellSize + 20, rows * cellSize + 50)
|
||
container:SetCols(cols)
|
||
container:SetColWide(cellSize)
|
||
container:SetRowHeight(cellSize)
|
||
container:Center()
|
||
|
||
|
||
for y = 1, rows do
|
||
for x = 1, cols do
|
||
local btn = vgui.Create("DButton")
|
||
btn:SetText("")
|
||
btn:SetSize(cellSize, cellSize)
|
||
|
||
btn.DoClick = function()
|
||
grid[y][x].rot = (grid[y][x].rot + 1) % 4
|
||
surface.PlaySound("common/wpn_select.wav")
|
||
UpdatePower()
|
||
end
|
||
|
||
btn.Paint = function(s, w, h)
|
||
local cell = grid[y][x]
|
||
local isPowered = cell.powered
|
||
local col = isPowered and Color(0, 255, 100) or Color(50, 50, 60)
|
||
if x == 1 and y == 1 then col = Color(0, 150, 255) end
|
||
if x == cols and y == rows then col = isPowered and Color(0, 255, 0) or Color(255, 50, 50) end
|
||
|
||
draw.RoundedBox(0, 0, 0, w, h, Color(30, 30, 35))
|
||
|
||
local cx, cy = w / 2, h / 2
|
||
local thick = 8
|
||
local conns = GetConnections(cell.type, cell.rot)
|
||
|
||
surface.SetDrawColor(col)
|
||
if conns[1] then surface.DrawRect(cx - thick / 2, 0, thick, cy) end
|
||
if conns[2] then surface.DrawRect(cx, cy - thick / 2, cx, thick) end
|
||
if conns[3] then surface.DrawRect(cx - thick / 2, cy, thick, cy) end
|
||
if conns[4] then surface.DrawRect(0, cy - thick / 2, cx, thick) end
|
||
|
||
surface.DrawRect(cx - thick, cy - thick, thick * 2, thick * 2)
|
||
end
|
||
|
||
container:AddItem(btn)
|
||
end
|
||
end
|
||
|
||
UpdatePower()
|
||
end
|
||
|
||
function kostich.bank_game()
|
||
local stat
|
||
|
||
sound.PlayFile("sound/pavetr_mmk/music/Senwai-Avtoritet.mp3", "noplay", function(station, errCode, errStr)
|
||
if IsValid(station) then
|
||
station:Play()
|
||
station:SetVolume(1)
|
||
stat = station
|
||
end
|
||
end)
|
||
|
||
local ply = LocalPlayer()
|
||
|
||
-- Настройки окна
|
||
local win = vgui.Create("DFrame")
|
||
win:SetTitle("SENWAI_OS v3.0 // BANK_SECURITY_BREACH")
|
||
win:SetSize(ScrW(), ScrH())
|
||
win:Center()
|
||
win:MakePopup()
|
||
win:SetDraggable(false)
|
||
win:ShowCloseButton(true)
|
||
|
||
-- Цвета (в стиле твоего примера)
|
||
local col_bg = Color(20, 20, 25, 255)
|
||
local col_accent = Color(0, 150, 255)
|
||
local col_accent_dim = Color(0, 150, 255, 50)
|
||
local col_text = Color(200, 255, 200)
|
||
local col_highlight = Color(255, 200, 50) -- Цвет для активной строки/столбца
|
||
|
||
-- == ФОНОВАЯ АНИМАЦИЯ (МАТРИЦА) ==
|
||
local drops = {}
|
||
local char_cache = {}
|
||
for i = 33, 126 do table.insert(char_cache, string.char(i)) end
|
||
|
||
win.OnClose = function()
|
||
if IsValid(stat) then stat:Stop() end
|
||
end
|
||
|
||
win.Paint = function(s, w, h)
|
||
-- Отрисовка фона
|
||
draw.RoundedBox(0, 0, 0, w, h, col_bg)
|
||
|
||
-- Логика дождя символов (из твоего кода)
|
||
local fontSize = 18
|
||
surface.SetFont("ui.18")
|
||
local columns = math.floor(w / fontSize)
|
||
|
||
if #drops == 0 then
|
||
for i = 1, columns do
|
||
drops[i] = {
|
||
y = math.random(-h, 0),
|
||
speed = math.random(10, 30),
|
||
text = {}
|
||
}
|
||
for j = 1, 15 do drops[i].text[j] = table.Random(char_cache) end
|
||
end
|
||
end
|
||
|
||
for i = 1, columns do
|
||
local drop = drops[i]
|
||
for j = 1, 12 do
|
||
local charY = drop.y - (j * fontSize)
|
||
if charY < h + fontSize and charY > -fontSize then
|
||
local alpha = 100 - (j * 5) -- Сделал чуть тусклее, чтобы не мешало игре
|
||
if alpha > 0 then
|
||
surface.SetTextColor(0, 150, 255, alpha) -- Синий оттенок для кибер-стиля
|
||
surface.SetTextPos((i - 1) * fontSize, charY)
|
||
if math.random() > 0.95 then drop.text[j] = table.Random(char_cache) end
|
||
surface.DrawText(drop.text[j] or "0")
|
||
end
|
||
end
|
||
end
|
||
drop.y = drop.y + (drop.speed * FrameTime() * 10)
|
||
if drop.y > h + 200 then
|
||
drop.y = -fontSize * 2
|
||
drop.speed = math.random(10, 35)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- == ЛОГИКА ИГРЫ ==
|
||
local gridSize = 6 -- Размер сетки 6x6
|
||
local hexValues = { "1C", "BD", "55", "E9", "7A", "FF" }
|
||
local gridData = {}
|
||
local requiredSequence = {}
|
||
local playerSequence = {}
|
||
|
||
local timerStart = CurTime()
|
||
local timeLimit = 45 -- Секунд на взлом
|
||
local isGameOver = false
|
||
|
||
-- Состояние курсора:
|
||
-- axis: "row" (горизонтально) или "col" (вертикально)
|
||
-- index: номер текущей строки или столбца
|
||
local activeState = { axis = "row", index = 1 }
|
||
|
||
-- Генерация уровня так, чтобы он был проходим
|
||
local function GenerateLevel()
|
||
-- 1. Создаем пустую сетку
|
||
for y = 1, gridSize do
|
||
gridData[y] = {}
|
||
for x = 1, gridSize do
|
||
gridData[y][x] = { val = table.Random(hexValues), used = false }
|
||
end
|
||
end
|
||
|
||
-- 2. Генерируем гарантированно правильный путь (4 шага)
|
||
local pathLength = 4
|
||
local cx, cy = math.random(1, gridSize), 1 -- Начинаем всегда с первой строки
|
||
local pathAxis = "row" -- Первый ход выбирается из строки
|
||
|
||
-- Записываем первый шаг
|
||
gridData[cy][cx].val = table.Random(hexValues)
|
||
table.insert(requiredSequence, gridData[cy][cx].val)
|
||
|
||
-- Симуляция следующих шагов
|
||
local simX, simY = cx, cy
|
||
local simAxis = "col" -- После выбора в строке, следующий выбор в столбце
|
||
|
||
for i = 2, pathLength do
|
||
local nextVal = table.Random(hexValues)
|
||
|
||
if simAxis == "col" then
|
||
-- Выбираем новую строку в том же столбце
|
||
local newY = math.random(1, gridSize)
|
||
while newY == simY do newY = math.random(1, gridSize) end
|
||
simY = newY
|
||
else
|
||
-- Выбираем новый столбец в той же строке
|
||
local newX = math.random(1, gridSize)
|
||
while newX == simX do newX = math.random(1, gridSize) end
|
||
simX = newX
|
||
end
|
||
|
||
gridData[simY][simX].val = nextVal
|
||
table.insert(requiredSequence, nextVal)
|
||
|
||
-- Инвертируем ось для следующего шага
|
||
simAxis = (simAxis == "row") and "col" or "row"
|
||
end
|
||
|
||
-- Заполняем остальные ячейки случайным мусором (уже сделано в шаге 1, но перезапишем путь)
|
||
-- Путь уже записан в сетку, так что всё ок.
|
||
end
|
||
|
||
GenerateLevel()
|
||
|
||
-- == ИНТЕРФЕЙС ИГРЫ ==
|
||
|
||
local mainPanel = vgui.Create("DPanel", win)
|
||
mainPanel:SetSize(800, 600)
|
||
mainPanel:Center()
|
||
mainPanel.Paint = function(s, w, h)
|
||
-- Рамка вокруг игровой зоны
|
||
surface.SetDrawColor(col_accent)
|
||
surface.DrawOutlinedRect(0, 0, w, h, 2)
|
||
draw.RoundedBox(0, 0, 0, w, h, Color(10, 10, 15, 240))
|
||
end
|
||
|
||
-- Верхняя панель: Таймер и Цель
|
||
local infoPanel = vgui.Create("DPanel", mainPanel)
|
||
infoPanel:SetPos(20, 20)
|
||
infoPanel:SetSize(760, 100)
|
||
infoPanel.Paint = function(s, w, h)
|
||
if isGameOver then return end
|
||
|
||
-- Таймер / Полоса обнаружения
|
||
local timeLeft = math.max(0, timeLimit - (CurTime() - timerStart))
|
||
local pct = timeLeft / timeLimit
|
||
|
||
draw.SimpleText("ОБНАРУЖЕНИЕ ВТОРЖЕНИЯ:", "DermaDefaultBold", 0, 0, Color(255, 50, 50))
|
||
draw.RoundedBox(0, 0, 20, w, 20, Color(50, 0, 0))
|
||
draw.RoundedBox(0, 0, 20, w * (1 - pct), 20, Color(255, 0, 0)) -- Красная полоса растет
|
||
|
||
if timeLeft <= 0 then
|
||
isGameOver = true
|
||
surface.PlaySound("buttons/button10.wav")
|
||
chat.AddText(Color(255, 0, 0), "[ВЗЛОМ] ", Color(255, 255, 255), "Время истекло! Система заблокирована.")
|
||
win:Close()
|
||
kostich.bank_game()
|
||
end
|
||
|
||
-- Отображение необходимой последовательности
|
||
draw.SimpleText("ТРЕБУЕМЫЙ БУФЕР:", "DermaDefaultBold", 0, 50, col_accent)
|
||
for i, code in ipairs(requiredSequence) do
|
||
local col = Color(100, 100, 100)
|
||
-- Если этот код уже собран
|
||
if i <= #playerSequence then
|
||
col = Color(0, 255, 0)
|
||
-- Если это следующий код
|
||
elseif i == #playerSequence + 1 then
|
||
col = Color(255, 255, 255)
|
||
end
|
||
|
||
draw.SimpleText(code, "DermaLarge", 150 + (i * 60), 45, col)
|
||
end
|
||
end
|
||
|
||
-- Сетка кнопок
|
||
local gridBaseX, gridBaseY = 150, 150
|
||
local cellSize = 60
|
||
local gap = 10
|
||
|
||
for y = 1, gridSize do
|
||
for x = 1, gridSize do
|
||
local btn = vgui.Create("DButton", mainPanel)
|
||
btn:SetPos(gridBaseX + (x - 1) * (cellSize + gap), gridBaseY + (y - 1) * (cellSize + gap))
|
||
btn:SetSize(cellSize, cellSize)
|
||
btn:SetText(gridData[y][x].val)
|
||
btn:SetFont("DermaLarge")
|
||
btn:SetColor(col_text)
|
||
|
||
btn.Paint = function(s, w, h)
|
||
local isHovered = s:IsHovered()
|
||
local cell = gridData[y][x]
|
||
|
||
-- Логика подсветки доступности
|
||
local isActive = false
|
||
if not isGameOver and not cell.used then
|
||
if activeState.axis == "row" and activeState.index == y then isActive = true end
|
||
if activeState.axis == "col" and activeState.index == x then isActive = true end
|
||
end
|
||
|
||
-- Отрисовка фона кнопки
|
||
local drawCol = Color(40, 40, 45)
|
||
if cell.used then
|
||
drawCol = Color(20, 20, 20) -- Уже нажата
|
||
s:SetColor(Color(50, 50, 50))
|
||
elseif isActive then
|
||
drawCol = Color(60, 60, 70)
|
||
if isHovered then drawCol = col_accent end -- Подсветка при наведении
|
||
-- Рисуем линию-подсветку через всю строку/столбец (визуальный эффект)
|
||
else
|
||
s:SetColor(Color(100, 100, 100, 50)) -- Неактивные тусклые
|
||
end
|
||
|
||
draw.RoundedBox(4, 0, 0, w, h, drawCol)
|
||
|
||
-- Рамка для активной оси
|
||
if isActive and not isHovered then
|
||
surface.SetDrawColor(col_accent_dim)
|
||
surface.DrawOutlinedRect(0, 0, w, h)
|
||
end
|
||
end
|
||
|
||
btn.DoClick = function()
|
||
if isGameOver then return end
|
||
local cell = gridData[y][x]
|
||
|
||
-- Проверка валидности хода
|
||
local isValidMove = false
|
||
if not cell.used then
|
||
if activeState.axis == "row" and activeState.index == y then isValidMove = true end
|
||
if activeState.axis == "col" and activeState.index == x then isValidMove = true end
|
||
end
|
||
|
||
if not isValidMove then
|
||
surface.PlaySound("buttons/button10.wav") -- Звук ошибки
|
||
return
|
||
end
|
||
|
||
-- Логика хода
|
||
|
||
cell.used = true
|
||
table.insert(playerSequence, cell.val)
|
||
|
||
-- Проверка правильности
|
||
local currentStep = #playerSequence
|
||
if playerSequence[currentStep] ~= requiredSequence[currentStep] then
|
||
-- ОШИБКА! Сброс прогресса (немного упростим - сбросим только последние ходы или просто проигрыш)
|
||
-- Хардкорный вариант: ошибка сбрасывает часть буфера
|
||
surface.PlaySound("buttons/button8.wav")
|
||
playerSequence = {} -- Полный сброс буфера игрока при ошибке
|
||
-- Опционально: уменьшить время таймера при ошибке
|
||
timeLimit = timeLimit - 5
|
||
else
|
||
surface.PlaySound("buttons/button3.wav")
|
||
end
|
||
|
||
-- Смена оси
|
||
if activeState.axis == "row" then
|
||
activeState.axis = "col"
|
||
activeState.index = x
|
||
else
|
||
activeState.axis = "row"
|
||
activeState.index = y
|
||
end
|
||
|
||
-- Проверка победы
|
||
if #playerSequence == #requiredSequence then
|
||
isGameOver = true
|
||
surface.PlaySound("buttons/button14.wav")
|
||
chat.AddText(Color(0, 255, 0), "[SenwaiOS] ", Color(255, 255, 255),
|
||
"Эксплоит установлен! Деньги переводятся...")
|
||
net.Start("pavetr.done_bank")
|
||
net.SendToServer()
|
||
win:Close()
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
-- Декоративные линии для понимания оси
|
||
local overlay = vgui.Create("DPanel", mainPanel)
|
||
overlay:SetSize(800, 600)
|
||
overlay:SetMouseInputEnabled(false) -- Чтобы кликать сквозь
|
||
overlay.Paint = function(s, w, h)
|
||
if isGameOver then return end
|
||
|
||
local startX, startY = gridBaseX, gridBaseY
|
||
local fullSize = (cellSize + gap) * gridSize
|
||
|
||
surface.SetDrawColor(Color(255, 200, 0, 30)) -- Желтая подсветка текущей линии
|
||
|
||
if activeState.axis == "row" then
|
||
local yPos = startY + (activeState.index - 1) * (cellSize + gap)
|
||
draw.RoundedBox(0, startX - 10, yPos - 5, fullSize, cellSize + 10, Color(0, 150, 255, 20))
|
||
else
|
||
local xPos = startX + (activeState.index - 1) * (cellSize + gap)
|
||
draw.RoundedBox(0, xPos - 5, startY - 10, cellSize + 10, fullSize, Color(0, 150, 255, 20))
|
||
end
|
||
end
|
||
end
|
||
|
||
function kostich.satellite_game()
|
||
local stat
|
||
sound.PlayFile("sound/music/hl2_song6.mp3", "noplay", function(station, errCode, errStr)
|
||
if IsValid(station) then
|
||
station:Play()
|
||
station:SetVolume(0.5)
|
||
stat = station
|
||
else
|
||
print("Error playing sound!", errCode, errStr)
|
||
end
|
||
end)
|
||
|
||
local ply = LocalPlayer()
|
||
|
||
local rows, cols = 8, 8
|
||
local cellSize = 50
|
||
local warehouseCount = 8
|
||
|
||
local win = vgui.Create("DFrame")
|
||
win:SetTitle("SATELLITE-GPS: Target Locator v2.0")
|
||
win:SetSize(ScrW(), ScrH())
|
||
win:Center()
|
||
win:MakePopup()
|
||
win:SetDraggable(false)
|
||
win:ShowCloseButton(true)
|
||
|
||
local colBG = Color(10, 15, 20, 250)
|
||
local colGrid = Color(0, 150, 255)
|
||
local colHidden = Color(30, 35, 40)
|
||
local colScanned = Color(50, 50, 55)
|
||
local colTarget = Color(255, 50, 50)
|
||
local colText = Color(100, 255, 100)
|
||
|
||
local drops = {}
|
||
local next_char_change = 0
|
||
local char_cache = {}
|
||
for i = 33, 126 do table.insert(char_cache, string.char(i)) end
|
||
|
||
win.OnClose = function()
|
||
if IsValid(stat) then stat:Stop() end
|
||
end
|
||
|
||
win.Paint = function(s, w, h)
|
||
draw.RoundedBox(0, 0, 0, w, h, colBG)
|
||
|
||
local fontSize = 18
|
||
local columns = math.floor(w / fontSize)
|
||
if #drops == 0 then
|
||
for i = 1, columns do
|
||
drops[i] = { y = math.random(-h, 0), speed = math.random(10, 30), text = {} }
|
||
for j = 1, 15 do drops[i].text[j] = table.Random(char_cache) end
|
||
end
|
||
end
|
||
|
||
surface.SetFont("DermaDefault")
|
||
local time = RealTime()
|
||
local do_change = false
|
||
if time > next_char_change then
|
||
do_change = true
|
||
next_char_change = time + 0.05
|
||
end
|
||
|
||
for i = 1, columns do
|
||
local drop = drops[i]
|
||
for j = 1, 12 do
|
||
local charY = drop.y - (j * fontSize)
|
||
if charY < h + fontSize and charY > -fontSize then
|
||
local alpha = 100 - (j * 8)
|
||
if alpha > 0 then
|
||
surface.SetTextColor(0, 255, 0, alpha)
|
||
surface.SetTextPos((i - 1) * fontSize, charY)
|
||
if do_change and math.random() > 0.9 then drop.text[j] = table.Random(char_cache) end
|
||
surface.DrawText(drop.text[j] or "0")
|
||
end
|
||
end
|
||
end
|
||
drop.y = drop.y + (drop.speed * FrameTime() * 10)
|
||
if drop.y > h + 200 then
|
||
drop.y = -fontSize * 2
|
||
drop.speed = math.random(10, 35)
|
||
end
|
||
end
|
||
|
||
draw.SimpleText("ЗАДАЧА: ОБНАРУЖИТЬ СКЛАДЫ (" .. warehouseCount .. " шт)", "DermaLarge", w / 2, 50,
|
||
Color(255, 200, 0), TEXT_ALIGN_CENTER)
|
||
draw.SimpleText("Клик по сектору для сканирования. Цифры указывают количество целей рядом.", "DermaDefault", w /
|
||
2, 85, color_white, TEXT_ALIGN_CENTER)
|
||
end
|
||
|
||
local grid = {}
|
||
local foundCount = 0
|
||
local isGameOver = false
|
||
|
||
for y = 1, rows do
|
||
grid[y] = {}
|
||
for x = 1, cols do
|
||
grid[y][x] = {
|
||
isTarget = false,
|
||
revealed = false,
|
||
neighborCount = 0
|
||
}
|
||
end
|
||
end
|
||
|
||
local placed = 0
|
||
while placed < warehouseCount do
|
||
local rx, ry = math.random(1, cols), math.random(1, rows)
|
||
if not grid[ry][rx].isTarget then
|
||
grid[ry][rx].isTarget = true
|
||
placed = placed + 1
|
||
end
|
||
end
|
||
|
||
for y = 1, rows do
|
||
for x = 1, cols do
|
||
if not grid[y][x].isTarget then
|
||
local count = 0
|
||
for dy = -1, 1 do
|
||
for dx = -1, 1 do
|
||
local ny, nx = y + dy, x + dx
|
||
if ny >= 1 and ny <= rows and nx >= 1 and nx <= cols then
|
||
if grid[ny][nx].isTarget then count = count + 1 end
|
||
end
|
||
end
|
||
end
|
||
grid[y][x].neighborCount = count
|
||
end
|
||
end
|
||
end
|
||
|
||
local container = vgui.Create("DGrid", win)
|
||
container:SetSize(cols * cellSize + 20, rows * cellSize + 20)
|
||
container:SetCols(cols)
|
||
container:SetColWide(cellSize)
|
||
container:SetRowHeight(cellSize)
|
||
container:Center()
|
||
|
||
for y = 1, rows do
|
||
for x = 1, cols do
|
||
local btn = vgui.Create("DButton")
|
||
btn:SetText("")
|
||
btn:SetSize(cellSize, cellSize)
|
||
|
||
btn.Paint = function(s, w, h)
|
||
local cell = grid[y][x]
|
||
|
||
surface.SetDrawColor(0, 0, 0, 200)
|
||
surface.DrawOutlinedRect(0, 0, w, h)
|
||
|
||
if not cell.revealed then
|
||
draw.RoundedBox(0, 1, 1, w - 2, h - 2, colHidden)
|
||
surface.SetDrawColor(0, 50, 100, 100)
|
||
if math.random() > 0.99 then
|
||
surface.SetDrawColor(100, 255, 255, 150)
|
||
end
|
||
surface.DrawOutlinedRect(2, 2, w - 4, h - 4)
|
||
else
|
||
if cell.isTarget then
|
||
draw.RoundedBox(0, 1, 1, w - 2, h - 2, colTarget)
|
||
draw.SimpleText("TARGET", "DermaDefault", w / 2, h / 2, color_black, TEXT_ALIGN_CENTER,
|
||
TEXT_ALIGN_CENTER)
|
||
else
|
||
draw.RoundedBox(0, 1, 1, w - 2, h - 2, colScanned)
|
||
if cell.neighborCount > 0 then
|
||
local intense = math.min(255, cell.neighborCount * 50)
|
||
draw.SimpleText(cell.neighborCount, "DermaLarge", w / 2, h / 2,
|
||
Color(255, 255 - intense, 255 - intense), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||
end
|
||
end
|
||
end
|
||
|
||
if s:IsHovered() and not cell.revealed then
|
||
surface.SetDrawColor(255, 255, 255, 30)
|
||
surface.DrawRect(0, 0, w, h)
|
||
end
|
||
end
|
||
|
||
btn.DoClick = function()
|
||
local cell = grid[y][x]
|
||
if cell.revealed or isGameOver then return end
|
||
|
||
cell.revealed = true
|
||
|
||
if cell.isTarget then
|
||
surface.PlaySound("buttons/blip1.wav")
|
||
foundCount = foundCount + 1
|
||
|
||
if foundCount >= warehouseCount then
|
||
isGameOver = true
|
||
chat.AddText(Color(0, 255, 0), "[СПУТНИК] ", Color(255, 255, 255),
|
||
"Все цели обнаружены. Координаты отправлены.")
|
||
surface.PlaySound("buttons/button14.wav")
|
||
RunConsoleCommand("success_sat")
|
||
win:Close()
|
||
end
|
||
else
|
||
surface.PlaySound("buttons/lightswitch2.wav")
|
||
end
|
||
end
|
||
|
||
container:AddItem(btn)
|
||
end
|
||
end
|
||
end
|
||
|
||
-- 2.5 sec
|
||
function kostich.boom()
|
||
surface.PlaySound("ambient/explosions/explode_3.wav")
|
||
LocalPlayer():ScreenFade(SCREENFADE.IN, Color(0, 0, 0, 255), 0.3, 0)
|
||
timer.Simple(0.3, function()
|
||
surface.PlaySound("ambient/explosions/explode_2.wav")
|
||
chat.AddText(red, "[ИВЕНТ] ", color_white, "Слышны взрывы")
|
||
end)
|
||
|
||
timer.Simple(2, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player9.mp3")
|
||
chat.AddText(color_white, "- Это еще че за хуйня")
|
||
timer.Simple(1, function()
|
||
surface.PlaySound("npc/overwatch/radiovoice/off2.wav")
|
||
chat.AddText(color_white, "[Рация] Это Мейби Пастер бомбит склады сенвая")
|
||
timer.Simple(2, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player10.mp3")
|
||
chat.AddText(color_white, "- Аа нихуя себе")
|
||
timer.Simple(2, function()
|
||
surface.PlaySound("pavetr_mmk/vo/player11.mp3")
|
||
chat.AddText(color_white, "- Надо быстрее нападать пока они не опомнились")
|
||
end)
|
||
end)
|
||
end)
|
||
end)
|
||
end
|
||
|
||
concommand.Add("play_hacker", function()
|
||
kostich.hacker_game()
|
||
end)
|
||
|
||
concommand.Add("play_gps", function()
|
||
kostich.satellite_game()
|
||
end)
|
||
|
||
function kostich.addMarlyaPosters()
|
||
local posters = kostich.getValue("posters")
|
||
if not string.find(posters:lower(), "m") then
|
||
cur_params["posters"] = cur_params["posters"] .. "m"
|
||
end
|
||
chat.AddText(Color(0, 255, 0), "[ПОСТЕРЫ] ", Color(255, 255, 255),
|
||
"На карте появились постеры Марли (" .. m_cnt .. "шт.)")
|
||
save_settings()
|
||
end
|
||
|
||
function kostich.addGenaPosters()
|
||
local posters = kostich.getValue("posters")
|
||
if not string.find(posters:lower(), "u") then
|
||
cur_params["posters"] = cur_params["posters"] .. "u"
|
||
end
|
||
chat.AddText(Color(0, 255, 0), "[ПОСТЕРЫ] ", Color(255, 255, 255),
|
||
"На карте появились постеры Урбанички (" .. u_cnt .. "шт.)")
|
||
save_settings()
|
||
end
|
||
|
||
function kostich.myarena()
|
||
timer.Create("fx_myarena", 1, 6, function()
|
||
surface.PlaySound("ambient/explosions/explode_3.wav")
|
||
local pos = Vector(2727.877686, -1700.273682, 109.490601)
|
||
local effectdata = EffectData()
|
||
effectdata:SetOrigin(pos)
|
||
effectdata:SetMagnitude(2)
|
||
effectdata:SetScale(1)
|
||
effectdata:SetRadius(5)
|
||
util.Effect("HelicopterMegaBomb", effectdata)
|
||
end)
|
||
end
|
||
|
||
concommand.Add("fx_test", function()
|
||
kostich.myarena()
|
||
end)
|
||
|
||
if not file.Exists("mmk_img", "DATA") then
|
||
file.CreateDir("mmk_img")
|
||
end
|
||
|
||
local MatCache = {}
|
||
local DownloadQueue = {}
|
||
|
||
local function GetPosterMat(url)
|
||
if MatCache[url] then return MatCache[url] end
|
||
|
||
local crc = util.CRC(url)
|
||
local path = "mmk_img/" .. crc .. ".png"
|
||
|
||
if file.Exists(path, "DATA") then
|
||
local mat = Material("../data/" .. path, "noclamp smooth")
|
||
MatCache[url] = mat
|
||
return mat
|
||
end
|
||
|
||
if not DownloadQueue[url] then
|
||
DownloadQueue[url] = true
|
||
|
||
http.Fetch(url, function(body, len, headers, code)
|
||
if code ~= 200 then return end
|
||
|
||
file.Write(path, body)
|
||
|
||
DownloadQueue[url] = nil
|
||
end, function(err)
|
||
print("[Poster Error] Failed to load: " .. url)
|
||
print(err)
|
||
DownloadQueue[url] = nil
|
||
end)
|
||
end
|
||
|
||
return nil
|
||
end
|
||
|
||
local peekDist = 400 * 400
|
||
hook.Add("PostDrawTranslucentRenderables", "DrawPostersMMK", function(bDepth, bSkybox)
|
||
if bSkybox then return end
|
||
|
||
for _, data in ipairs(agits) do
|
||
if (not data.show or string.find(kostich.getValue("posters"):lower(), data.show) and (data.pos:DistToSqr(LocalPlayer():GetPos()) <= peekDist) or MQS.CCam) then
|
||
local mat = GetPosterMat(data.url)
|
||
local scale = data.scale or 0.1
|
||
|
||
cam.Start3D2D(data.pos, data.ang, scale)
|
||
|
||
if mat then
|
||
surface.SetDrawColor(255, 255, 255, 255)
|
||
surface.SetMaterial(mat)
|
||
surface.DrawTexturedRect(0, 0, data.width, data.height)
|
||
else
|
||
surface.SetDrawColor(30, 30, 30, 200)
|
||
surface.DrawRect(0, 0, data.width, data.height)
|
||
|
||
draw.SimpleText("Загрузка...", "DermaLarge", data.width / 2, data.height / 2, color_white,
|
||
TEXT_ALIGN_CENTER,
|
||
TEXT_ALIGN_CENTER)
|
||
end
|
||
|
||
cam.End3D2D()
|
||
end
|
||
end
|
||
end)
|
||
|
||
|
||
concommand.Add("p_getpos", function()
|
||
local ply = LocalPlayer()
|
||
if not IsValid(ply) then return end
|
||
|
||
local pos = ply:GetPos()
|
||
local code = string.format("Vector(%.2f, %.2f, %.2f)", pos.x, pos.y, pos.z)
|
||
|
||
SetClipboardText(code)
|
||
chat.AddText(Color(100, 255, 100), "[Cpy] ", color_white, "Позиция скопирована: ", Color(200, 200, 0), code)
|
||
end)
|
||
|
||
concommand.Add("p_getang", function()
|
||
local ply = LocalPlayer()
|
||
if not IsValid(ply) then return end
|
||
|
||
local ang = ply:EyeAngles()
|
||
|
||
local code = string.format("Angle(%.2f, %.2f, %.2f)", ang.p, ang.y, ang.r)
|
||
|
||
SetClipboardText(code)
|
||
chat.AddText(Color(100, 255, 100), "[Cpy] ", color_white, "Угол скопирован: ", Color(200, 200, 0), code)
|
||
end)
|
||
|
||
-- function kostich.menu_pasting()
|
||
-- local stat
|
||
-- sound.PlayFile("sound/ambient/machines/combine_terminal_loop1.wav", "noplay", function(station, errCode, errStr)
|
||
-- if IsValid(station) then
|
||
-- station:Play()
|
||
-- station:SetVolume(0.3)
|
||
-- stat = station
|
||
-- end
|
||
-- end)
|
||
|
||
-- local code_lines = {
|
||
-- {
|
||
-- correct = 2,
|
||
-- variants = {
|
||
-- "local frame = vgui.Destroy('DFrame')",
|
||
-- "local frame = vgui.Create('DFrame')",
|
||
-- "dim frame as new Window()",
|
||
-- "function frame:Create()"
|
||
-- }
|
||
-- },
|
||
-- {
|
||
-- correct = 1,
|
||
-- variants = {
|
||
-- "frame:SetSize(500, 400)",
|
||
-- "frame.width = 500; frame.height = 400",
|
||
-- "frame:Resize_Window(500, 400)",
|
||
-- "SetSize(frame, 500, 400)"
|
||
-- }
|
||
-- },
|
||
-- {
|
||
-- correct = 3,
|
||
-- variants = {
|
||
-- "frame.center()",
|
||
-- "frame:Align('center')",
|
||
-- "frame:Center()",
|
||
-- "util.Center(frame)"
|
||
-- }
|
||
-- },
|
||
-- {
|
||
-- correct = 2,
|
||
-- variants = {
|
||
-- "frame:ShowCloseButton(false)",
|
||
-- "frame:MakePopup()",
|
||
-- "frame:EnableMouse()",
|
||
-- "input.EnableCursor()"
|
||
-- }
|
||
-- },
|
||
-- {
|
||
-- correct = 4,
|
||
-- variants = {
|
||
-- "paint(function(w,h) end)",
|
||
-- "frame.Paint = new function()",
|
||
-- "hook.Add('Paint', frame)",
|
||
-- "frame.Paint = function(s, w, h)"
|
||
-- }
|
||
-- },
|
||
-- {
|
||
-- correct = 1,
|
||
-- variants = {
|
||
-- " draw.RoundedBox(0, 0, 0, w, h, Color(40, 0, 60))",
|
||
-- " surface.DrawRect(red, 0, 0, w, h)",
|
||
-- " draw.Box(0, 0, w, h, purple)",
|
||
-- " render.Clear(40, 0, 60)"
|
||
-- }
|
||
-- },
|
||
-- {
|
||
-- correct = 3,
|
||
-- variants = {
|
||
-- "end function",
|
||
-- "return true",
|
||
-- "end",
|
||
-- "}"
|
||
-- }
|
||
-- }
|
||
-- }
|
||
|
||
-- for k, v in ipairs(code_lines) do
|
||
-- v.current = math.random(1, #v.variants)
|
||
-- if v.current == v.correct then
|
||
-- v.current = (v.current % #v.variants) + 1
|
||
-- end
|
||
-- end
|
||
|
||
-- local win = vgui.Create("DFrame")
|
||
-- win:SetTitle("VSCode - purple_menu.lua [READ ONLY - CLICK TO PATCH]")
|
||
-- win:SetSize(ScrW(), ScrH())
|
||
-- win:Center()
|
||
-- win:MakePopup()
|
||
-- win:ShowCloseButton(true)
|
||
-- win:SetDraggable(false)
|
||
|
||
-- local colBG = Color(30, 30, 35)
|
||
-- local colSidebar = Color(25, 25, 30)
|
||
-- local colLineNum = Color(100, 100, 120)
|
||
-- local colHighlight = Color(45, 40, 50)
|
||
|
||
-- local colFunc = Color(200, 100, 255)
|
||
-- local colStr = Color(150, 255, 150)
|
||
-- local colErr = Color(255, 100, 100)
|
||
-- local colNorm = Color(220, 220, 220)
|
||
|
||
-- local lineHeight = 40
|
||
-- local startY = 100
|
||
-- local isWin = false
|
||
|
||
-- win.OnClose = function()
|
||
-- if IsValid(stat) then stat:Stop() end
|
||
-- end
|
||
|
||
-- local consoleStatus = "ERROR: Syntax error in line 1..."
|
||
-- local consoleCol = colErr
|
||
|
||
-- local function CheckWin()
|
||
-- local errors = 0
|
||
-- local firstErrorLine = -1
|
||
|
||
-- for k, v in ipairs(code_lines) do
|
||
-- if v.current ~= v.correct then
|
||
-- errors = errors + 1
|
||
-- if firstErrorLine == -1 then firstErrorLine = k end
|
||
-- end
|
||
-- end
|
||
|
||
-- if errors == 0 then
|
||
-- isWin = true
|
||
-- consoleStatus = "SUCCESS: 0 Errors, 0 Warnings. Compiling..."
|
||
-- consoleCol = Color(0, 255, 0)
|
||
-- surface.PlaySound("buttons/button14.wav")
|
||
|
||
-- timer.Simple(1.5, function()
|
||
-- if IsValid(win) then
|
||
-- surface.PlaySound("ambient/levels/labs/electric_explosion1.wav")
|
||
-- LocalPlayer():ScreenFade(SCREENFADE.IN, Color(0, 0, 0, 255), 0.3, 0)
|
||
-- timer.Simple(0.3, function()
|
||
-- cur_params["hud"] = "kostich"
|
||
-- save_settings()
|
||
-- chat.AddText(red, "[ИВЕНТ] ", color_white, "В сборку вернулся худ от сапа")
|
||
-- end)
|
||
-- RunConsoleCommand("success_menu")
|
||
-- win:Close()
|
||
-- end
|
||
-- end)
|
||
-- else
|
||
-- consoleStatus = "COMPILER ERROR: Unexpected symbol near line " .. firstErrorLine
|
||
-- consoleCol = colErr
|
||
-- end
|
||
-- end
|
||
|
||
-- win.Paint = function(s, w, h)
|
||
-- draw.RoundedBox(0, 0, 0, w, h, colBG)
|
||
|
||
-- draw.RoundedBox(0, 0, 0, 60, h, colSidebar)
|
||
|
||
-- draw.SimpleText("LUA DEBUGGER", "DermaLarge", 80, 20, Color(200, 100, 255))
|
||
-- draw.SimpleText("Нажмите на строку с ошибкой, чтобы исправить код.", "DermaDefault", 80, 55, Color(150, 150, 150))
|
||
|
||
-- draw.RoundedBox(0, 0, h - 40, w, 40, Color(20, 20, 20))
|
||
-- draw.SimpleText("> " .. consoleStatus, "DermaDefaultBold", 10, h - 28, consoleCol)
|
||
-- end
|
||
|
||
-- for i, lineData in ipairs(code_lines) do
|
||
-- local btn = vgui.Create("DButton", win)
|
||
-- btn:SetPos(60, startY + (i - 1) * lineHeight)
|
||
-- btn:SetSize(win:GetWide() - 60, lineHeight)
|
||
-- btn:SetText("")
|
||
|
||
-- btn.Paint = function(s, w, h)
|
||
-- if s:IsHovered() and not isWin then
|
||
-- draw.RoundedBox(0, 0, 0, w, h, colHighlight)
|
||
-- end
|
||
|
||
-- local text = lineData.variants[lineData.current]
|
||
-- local isCorrect = (lineData.current == lineData.correct)
|
||
|
||
-- local txtCol = colNorm
|
||
-- if isWin then
|
||
-- txtCol = Color(100, 255, 100)
|
||
-- elseif isCorrect then
|
||
-- txtCol = colFunc
|
||
-- else
|
||
-- txtCol = Color(255, 100, 100)
|
||
-- end
|
||
|
||
-- draw.SimpleText(text, "DermaLarge", 20, h / 2, txtCol, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
|
||
|
||
-- surface.SetTextColor(colLineNum)
|
||
-- surface.SetFont("DermaLarge")
|
||
-- surface.SetTextPos(-40, h / 2 - 10)
|
||
-- surface.DrawText(tostring(i))
|
||
-- end
|
||
|
||
-- btn.DoClick = function()
|
||
-- if isWin then return end
|
||
|
||
-- lineData.current = lineData.current + 1
|
||
-- if lineData.current > #lineData.variants then
|
||
-- lineData.current = 1
|
||
-- end
|
||
|
||
-- surface.PlaySound("buttons/lightswitch2.wav")
|
||
-- CheckWin()
|
||
-- end
|
||
-- end
|
||
|
||
-- CheckWin()
|
||
-- end
|
||
|
||
function kostich.deploy_game()
|
||
local music
|
||
sound.PlayFile("sound/pavetr_mmk/music/Sugraal&Pavetr-Sup_Paster.mp3", "noplay", function(station, err, str)
|
||
if IsValid(station) then
|
||
station:Play()
|
||
station:SetVolume(1.5)
|
||
music = station
|
||
end
|
||
end)
|
||
|
||
local function RestartGame()
|
||
surface.PlaySound("buttons/button10.wav")
|
||
chat.AddText(Color(255, 50, 50), "[SFTP] ", color_white,
|
||
"ОШИБКА: Вам афродетка сервак ебет хеппи мил бекдуром! Экстренное отключение...")
|
||
|
||
local owner = vgui.GetWorldPanel()
|
||
for _, child in ipairs(owner:GetChildren()) do
|
||
if child.IsDeployGame then child:Close() end
|
||
end
|
||
|
||
timer.Simple(1.5, function() kostich.deploy_game() end)
|
||
end
|
||
|
||
local files = {
|
||
{ name = "init.lua", type = "lua", size = "12 KB", bad = false },
|
||
{ name = "cl_init.lua", type = "lua", size = "24 KB", bad = false },
|
||
{ name = "shared.lua", type = "lua", size = "5 KB", bad = false },
|
||
{ name = "sv_db.lua", type = "lua", size = "8 KB", bad = false },
|
||
{ name = "config.lua", type = "lua", size = "2 KB", bad = false },
|
||
{ name = "brush_decompile.exe", type = "exe", size = "5 MB", bad = true },
|
||
{ name = "happy_meal_backdoor.dll", type = "dll", size = "1 MB", bad = true },
|
||
{ name = "utils.lua", type = "lua", size = "4 KB", bad = false },
|
||
}
|
||
|
||
local needed = 0
|
||
for _, f in ipairs(files) do if not f.bad then needed = needed + 1 end end
|
||
local current = 0
|
||
|
||
local win = vgui.Create("DFrame")
|
||
win:SetTitle("WinSCP")
|
||
win:SetSize(900, 600)
|
||
win:Center()
|
||
win:MakePopup()
|
||
win.IsDeployGame = true
|
||
win:ShowCloseButton(true)
|
||
|
||
win.Paint = function(s, w, h)
|
||
draw.RoundedBox(0, 0, 0, w, h, Color(30, 30, 35))
|
||
draw.RoundedBox(0, 0, 0, w, 25, Color(60, 0, 90))
|
||
draw.RoundedBox(0, 0, h - 30, w, 30, Color(20, 20, 20))
|
||
draw.SimpleText("PENDING: " .. (needed - current) .. " files", "DermaDefault", 10, h - 22, Color(150, 150, 150))
|
||
end
|
||
|
||
win.OnClose = function()
|
||
if IsValid(music) then
|
||
music:Stop()
|
||
end
|
||
end
|
||
|
||
local function CreatePanel(parent, title, x, colHeader)
|
||
local p = vgui.Create("DPanel", parent)
|
||
p:SetPos(x, 40)
|
||
p:SetSize(440, 520)
|
||
p.Paint = function(s, w, h)
|
||
draw.RoundedBox(0, 0, 0, w, h, Color(40, 40, 45))
|
||
draw.RoundedBox(0, 0, 0, w, 30, colHeader)
|
||
draw.SimpleText(title, "DermaDefaultBold", 10, 8, color_white)
|
||
end
|
||
|
||
local scroll = vgui.Create("DScrollPanel", p)
|
||
scroll:Dock(FILL)
|
||
scroll:DockMargin(5, 35, 5, 5)
|
||
|
||
local layout = vgui.Create("DIconLayout", scroll)
|
||
layout:Dock(FILL)
|
||
layout:SetSpaceY(5)
|
||
|
||
return layout
|
||
end
|
||
|
||
local leftLayout = CreatePanel(win, "LOCAL DISK (Click to Upload)", 5, Color(70, 70, 80))
|
||
local rightLayout = CreatePanel(win, "REMOTE SERVER", 455, Color(0, 100, 50))
|
||
|
||
for _, f in ipairs(files) do
|
||
local btn = leftLayout:Add("DButton")
|
||
btn:SetSize(420, 40)
|
||
btn:SetText("")
|
||
|
||
btn.IsUploading = false
|
||
btn.Progress = 0
|
||
btn.UploadSpeed = 0
|
||
btn.IsUploaded = false
|
||
|
||
btn.DoClick = function(s)
|
||
if s.IsUploaded or s.IsUploading then return end
|
||
|
||
if f.bad then
|
||
RestartGame()
|
||
return
|
||
end
|
||
|
||
surface.PlaySound("buttons/button17.wav")
|
||
s.IsUploading = true
|
||
s.StartTime = CurTime()
|
||
s.Duration = math.Rand(0.5, 1.5)
|
||
end
|
||
|
||
btn.Think = function(s)
|
||
if s.IsUploading then
|
||
local fraction = (CurTime() - s.StartTime) / s.Duration
|
||
s.Progress = math.Clamp(fraction, 0, 1)
|
||
|
||
if fraction >= 1 then
|
||
s.IsUploading = false
|
||
s.IsUploaded = true
|
||
|
||
s:SetParent(rightLayout)
|
||
s:Dock(TOP)
|
||
leftLayout:InvalidateLayout()
|
||
rightLayout:InvalidateLayout()
|
||
|
||
surface.PlaySound("buttons/combine_button7.wav")
|
||
|
||
current = current + 1
|
||
|
||
if current >= needed then
|
||
surface.PlaySound("buttons/button14.wav")
|
||
chat.AddText(Color(0, 255, 0), "[SFTP] ", color_white, "ПЛИБ ЗАЛИТ!")
|
||
surface.PlaySound("ambient/levels/labs/electric_explosion1.wav")
|
||
LocalPlayer():ScreenFade(SCREENFADE.IN, Color(0, 0, 0, 255), 0.3, 0)
|
||
timer.Simple(0.3, function()
|
||
cur_params["plib"] = true
|
||
save_settings()
|
||
chat.AddText(red, "[ИВЕНТ] ", color_white, "В сборку вернулся plib")
|
||
end)
|
||
RunConsoleCommand("success_plib")
|
||
win:Close()
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
btn.Paint = function(s, w, h)
|
||
local col = Color(60, 60, 65)
|
||
if s.IsUploaded then col = Color(30, 60, 30) end
|
||
draw.RoundedBox(4, 0, 0, w, h, col)
|
||
|
||
if s.IsUploading then
|
||
draw.RoundedBox(4, 0, 0, w * s.Progress, h, Color(0, 200, 255, 50))
|
||
draw.RoundedBox(0, 0, h - 2, w * s.Progress, 2, Color(0, 255, 255))
|
||
end
|
||
|
||
local iconCol = Color(100, 200, 255)
|
||
if f.bad then iconCol = Color(255, 100, 100) end
|
||
draw.RoundedBox(0, 10, 10, 20, 20, iconCol)
|
||
|
||
draw.SimpleText(f.name, "DermaDefaultBold", 40, 12, color_white)
|
||
|
||
if s.IsUploading then
|
||
local pct = math.Round(s.Progress * 100)
|
||
draw.SimpleText(pct .. "%", "DermaDefaultBold", w - 50, 12, Color(0, 255, 255))
|
||
elseif s.IsUploaded then
|
||
draw.SimpleText("OK", "DermaDefaultBold", w - 40, 12, Color(100, 255, 100))
|
||
else
|
||
draw.SimpleText(f.size, "DermaDefault", w - 50, 12, Color(150, 150, 150))
|
||
if s:IsHovered() then
|
||
draw.SimpleText("UPLOAD", "DermaDefaultBold", w - 110, 12, Color(0, 255, 255))
|
||
end
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
function kostich.titles()
|
||
local credits = {
|
||
{ type = "gap", val = 100 },
|
||
{ type = "header", val = "МЕРТВАЯ МАМА КОСТ ИЧА РП" },
|
||
{ type = "text", val = "Ивент 'Сенвай украл сапы'" },
|
||
{ type = "gap", val = 50 },
|
||
|
||
{ type = "header", val = "РАЗРАБОТЧИКИ" },
|
||
{ type = "text", val = "Pavetr" },
|
||
{ type = "text", val = "Encoded - мини-игра про менюшки" },
|
||
{ type = "text", val = "MacTavish - пиздец забагованные McQuests+SimpleNPCs" },
|
||
{ type = "gap", val = 30 },
|
||
|
||
{ type = "header", val = "САУНД ДИЗАЙНЕРЫ" },
|
||
{ type = "text", val = "Marlya" },
|
||
{ type = "text", val = "Pavetr" },
|
||
{ type = "gap", val = 30 },
|
||
|
||
{ type = "header", val = "ОЗВУЧКА" },
|
||
{ type = "text", val = "Encoded" },
|
||
{ type = "text", val = "Spawncode" },
|
||
{ type = "text", val = "Caramelka" },
|
||
{ type = "text", val = "Rayz" },
|
||
{ type = "text", val = "Applio RVC - Urbanichka, Кост Ич" },
|
||
{ type = "text", val = "ElevenLabs - Остальные голоса" },
|
||
{ type = "gap", val = 30 },
|
||
|
||
{ type = "header", val = "ИВЕНТ ПОСВЯЩАЕТСЯ" },
|
||
{ type = "text", val = "Shiten (uxcx) - его недавно забрали в ВСРФ" },
|
||
{ type = "text", val = "Senwai" },
|
||
{ type = "text", val = "Vegaban" },
|
||
{ type = "text", val = "Sugraal" },
|
||
{ type = "text", val = "Кост Ич (aka @PIXO1166)" },
|
||
{ type = "gap", val = 30 },
|
||
|
||
{ type = "image", val = base_url .. "gmod.png", height = 300 },
|
||
{ type = "text", val = "Powered by Garry's Mod" },
|
||
{ type = "gap", val = 60 },
|
||
|
||
{ type = "header", val = "ОТДЕЛЬНАЯ БЛАГОДАРНОСТЬ" },
|
||
{ type = "text", val = "Jock" },
|
||
{ type = "text", val = "Inferno" },
|
||
{ type = "text", val = "Spawncode" },
|
||
{ type = "text", val = "Spac3e" },
|
||
{ type = "gap", val = 30 },
|
||
|
||
{ type = "header", val = "ВЫРАЖАЮ БЛАГОДАРНОСТЬ ВСЕМ" },
|
||
{ type = "text", val = "упомянутым в сюжетке персонажам" },
|
||
|
||
{ type = "gap", val = 30 },
|
||
{ type = "header", val = "СПАСИБО ЗА ИГРУ" },
|
||
{ type = "text", val = "Заходите на pavetr.ru/ds чтобы не пропустить подобные ивенты" },
|
||
{ type = "gap", val = ScrH() * 0.4 },
|
||
|
||
{ type = "image", val = base_url .. "senwai_out.png", height = 300 },
|
||
{ type = "gap", val = 30 }
|
||
}
|
||
|
||
local music
|
||
sound.PlayFile("sound/pavetr_mmk/music/Marlya-My_Kirik_Luk.mp3", "noplay", function(station, err, str)
|
||
if IsValid(station) then
|
||
station:Play()
|
||
station:SetVolume(3)
|
||
music = station
|
||
end
|
||
end)
|
||
|
||
local pnl = vgui.Create("DPanel")
|
||
pnl:SetSize(ScrW(), ScrH())
|
||
pnl:MakePopup()
|
||
pnl:SetKeyboardInputEnabled(true)
|
||
|
||
pnl.OnKeyCodePressed = function() end
|
||
gui.EnableScreenClicker(true)
|
||
|
||
local scrollY = ScrH()
|
||
local contentHeight = 0
|
||
local baseSpeed = 50
|
||
local fastSpeed = 400
|
||
local currentSpeed = baseSpeed
|
||
|
||
local container = vgui.Create("DPanel", pnl)
|
||
container:SetWide(ScrW() * 0.6)
|
||
container:SetPos(ScrW() * 0.2, scrollY)
|
||
container.Paint = function() end
|
||
|
||
local yCursor = 0
|
||
for _, item in ipairs(credits) do
|
||
if item.type == "header" then
|
||
local lbl = vgui.Create("DLabel", container)
|
||
lbl:SetFont("ui.40")
|
||
lbl:SetText(item.val)
|
||
lbl:SetTextColor(Color(0, 255, 255))
|
||
lbl:SizeToContents()
|
||
lbl:SetPos((container:GetWide() - lbl:GetWide()) / 2, yCursor)
|
||
yCursor = yCursor + 50
|
||
elseif item.type == "text" then
|
||
local lbl = vgui.Create("DLabel", container)
|
||
lbl:SetFont("ui.30")
|
||
lbl:SetText(item.val)
|
||
lbl:SetTextColor(Color(200, 200, 200))
|
||
lbl:SizeToContents()
|
||
lbl:SetPos((container:GetWide() - lbl:GetWide()) / 2, yCursor)
|
||
yCursor = yCursor + 30
|
||
elseif item.type == "image" then
|
||
local img = vgui.Create("DHTML", container)
|
||
local h = item.height or 200
|
||
local w = h * 1.77
|
||
img:SetSize(w, h)
|
||
img:SetPos((container:GetWide() - w) / 2, yCursor)
|
||
img:SetHTML([[<body style="margin:0;padding:0;overflow:hidden;background:transparent;"><img src="]] ..
|
||
item.val .. [[" style="width:100%;height:100%;object-fit:contain;"></body>]])
|
||
img:SetMouseInputEnabled(false)
|
||
yCursor = yCursor + h + 20
|
||
elseif item.type == "gap" then
|
||
yCursor = yCursor + item.val
|
||
end
|
||
end
|
||
|
||
container:SetTall(yCursor)
|
||
contentHeight = yCursor
|
||
|
||
pnl.Paint = function(s, w, h)
|
||
surface.SetDrawColor(0, 0, 0, 255)
|
||
surface.DrawRect(0, 0, w, h)
|
||
|
||
if math.random() > 0.95 then
|
||
surface.SetDrawColor(255, 0, 0, 5)
|
||
surface.DrawRect(0, math.random(0, h), w, 2)
|
||
end
|
||
|
||
local targetSpeed = baseSpeed
|
||
if input.IsKeyDown(KEY_SPACE) or input.IsMouseDown(MOUSE_LEFT) then
|
||
targetSpeed = fastSpeed
|
||
draw.SimpleText(">>", "DermaLarge", w - 50, h - 50,
|
||
Color(255, 50, 50, math.abs(math.sin(CurTime() * 10) * 255)))
|
||
end
|
||
|
||
currentSpeed = Lerp(FrameTime() * 5, currentSpeed, targetSpeed)
|
||
scrollY = scrollY - (currentSpeed * FrameTime())
|
||
container:SetPos(ScrW() * 0.2, scrollY)
|
||
|
||
if scrollY + contentHeight < 0 then
|
||
if IsValid(music) then
|
||
music:Stop()
|
||
end
|
||
|
||
s:Remove()
|
||
gui.EnableScreenClicker(false)
|
||
chat.AddText(Color(0, 255, 0), "Спасибо за прохождение сюжетки ММК РП!")
|
||
end
|
||
end
|
||
end
|
||
|
||
-- Miha Cheater
|
||
do
|
||
local createFont = surface.CreateFont
|
||
|
||
createFont('quest.title', {
|
||
font = 'Roboto Medium',
|
||
size = 24,
|
||
weight = 500
|
||
})
|
||
end
|
||
|
||
local function mat(name)
|
||
return Material('eui_quest/' .. name .. '.png')
|
||
end
|
||
|
||
local ELEMENTS = {
|
||
{
|
||
icon = mat('Frame 1169754813'),
|
||
size = { 1497, 877 },
|
||
pos = { 98, 249 },
|
||
correctPos = { 500, 250 },
|
||
mul = 4,
|
||
placed = false,
|
||
},
|
||
{
|
||
icon = mat('Group 37086'),
|
||
size = { 369, 155 },
|
||
pos = { 120, 259 },
|
||
correctPos = { 800, 250 },
|
||
placed = false,
|
||
},
|
||
{
|
||
icon = mat('Frame 1169754810'),
|
||
size = { 701, 70 },
|
||
pos = { 540, 319 },
|
||
correctPos = { 1100, 300 },
|
||
placed = false,
|
||
},
|
||
{
|
||
icon = mat('Bar'),
|
||
size = { 738, 367 },
|
||
pos = { 230, 450 },
|
||
correctPos = { 600, 450 },
|
||
placed = false,
|
||
},
|
||
{
|
||
icon = mat('Frame 1169754811'),
|
||
size = { 46, 352 },
|
||
pos = { 140, 450 },
|
||
correctPos = { 750, 500 },
|
||
placed = false,
|
||
},
|
||
{
|
||
icon = mat('Button'),
|
||
size = { 435, 206 },
|
||
pos = { 230, 810 },
|
||
correctPos = { 900, 750 },
|
||
placed = false,
|
||
},
|
||
{
|
||
icon = mat('Frame 1169754812'),
|
||
size = { 727, 744 },
|
||
pos = { 930, 300 },
|
||
correctPos = { 1050, 350 },
|
||
placed = false,
|
||
},
|
||
{
|
||
icon = mat('CLOSE'),
|
||
size = { 120, 50 },
|
||
pos = { 1350, 329 },
|
||
correctPos = { 1200, 350 },
|
||
placed = false,
|
||
},
|
||
}
|
||
|
||
local backgroundColor = Color(15, 11, 19)
|
||
local secondaryColor = Color(30, 24, 37)
|
||
local accentColor = Color(59, 32, 59)
|
||
|
||
local RNDX = RNDX
|
||
local rect = RNDX.Draw
|
||
local BOX_ROUNDED = 16
|
||
|
||
local PANEL = {}
|
||
|
||
function PANEL:Init()
|
||
self.startTime = CurTime()
|
||
sound.PlayFile("sound/pavetr_mmk/music/Pavetr-Chelyabinskii_Central_vol2.mp3", "noplay", function(station, err, str)
|
||
if IsValid(station) then
|
||
station:Play()
|
||
station:SetVolume(3)
|
||
self.music = station
|
||
end
|
||
end)
|
||
|
||
|
||
self:AddHeader()
|
||
self:AddContainer()
|
||
self:AddElements()
|
||
self:AddZones()
|
||
end
|
||
|
||
function PANEL:AddHeader()
|
||
local header = self:Add('Panel')
|
||
header:Dock(TOP)
|
||
header:SetTall(64)
|
||
|
||
function header:Paint(w, h)
|
||
rect(BOX_ROUNDED, 0, 0, w, h, secondaryColor, RNDX.NO_BL + RNDX.NO_BR)
|
||
end
|
||
|
||
local title = header:Add('DLabel')
|
||
title:Dock(LEFT)
|
||
title:DockMargin(10, 0, 0, 0)
|
||
title:SetText('PURPLE QUEST')
|
||
-- title:SetContentAlignment(5)
|
||
title:SetFont('quest.title')
|
||
title:SizeToContentsX()
|
||
|
||
local close = header:Add('DButton')
|
||
close:Dock(RIGHT)
|
||
close:DockMargin(0, 10, 10, 10)
|
||
close:SetText('')
|
||
close:SetWide(44)
|
||
|
||
close.scale = 1
|
||
|
||
function close:Paint(w, h)
|
||
local matrix = Matrix()
|
||
|
||
local x, y = self:LocalToScreen(w / 2, h / 2)
|
||
local center = Vector(x, y)
|
||
|
||
local isHovered = self:IsHovered()
|
||
self.scale = Lerp(FrameTime() * 8, self.scale, isHovered and 1.05 or 1)
|
||
|
||
matrix:Translate(center)
|
||
matrix:Scale(Vector(1, 1, 0) * self.scale)
|
||
matrix:Translate(-center)
|
||
|
||
cam.PushModelMatrix(matrix)
|
||
rect(BOX_ROUNDED / 2, 0, 0, w, h, accentColor)
|
||
draw.SimpleText('✕', 'quest.title', w / 2, h / 2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
|
||
cam.PopModelMatrix()
|
||
end
|
||
|
||
local frame = self
|
||
function close:DoClick()
|
||
if frame.music then
|
||
frame.music:Stop()
|
||
end
|
||
frame:Remove()
|
||
end
|
||
end
|
||
|
||
function PANEL:AddContainer()
|
||
local container = self:Add('Panel')
|
||
container:Dock(FILL)
|
||
|
||
self.container = container
|
||
end
|
||
|
||
function PANEL:AddElements()
|
||
local container = self.container
|
||
|
||
local side = container:Add('DScrollPanel')
|
||
side:Dock(LEFT)
|
||
side:DockPadding(10, 0, 0, 0)
|
||
side:SetWide(460)
|
||
side.VBar:SetHideButtons(true)
|
||
side.VBar.Paint = nil
|
||
side.VBar.btnGrip.Paint = nil
|
||
|
||
function side:Paint(w, h)
|
||
rect(BOX_ROUNDED, 0, 0, w, h, secondaryColor, RNDX.NO_TL + RNDX.NO_TR + RNDX.NO_BR)
|
||
end
|
||
|
||
for i, currentElement in RandomPairs(ELEMENTS) do
|
||
local size = currentElement.size
|
||
local mul = currentElement.mul or 2
|
||
|
||
local sizeW, sizeH = size[1] / mul, size[2] / mul
|
||
|
||
local element = side:Add('DPanel')
|
||
element:Dock(TOP)
|
||
element:DockMargin(0, 0, 0, 8)
|
||
element:SetTall(sizeH)
|
||
element:Droppable('purple-menu')
|
||
element:SetCursor('hand')
|
||
|
||
element.i = i
|
||
element.scale = 1
|
||
|
||
function element:Paint(w, h)
|
||
local matrix = Matrix()
|
||
|
||
local x, y = self:LocalToScreen(w / 2, h / 2)
|
||
local center = Vector(x, y)
|
||
|
||
local isHovered = self:IsHovered()
|
||
self.scale = Lerp(FrameTime() * 8, self.scale, isHovered and 1.05 or 1)
|
||
|
||
matrix:Translate(center)
|
||
matrix:Scale(Vector(1, 1, 0) * self.scale)
|
||
matrix:Translate(-center)
|
||
|
||
cam.PushModelMatrix(matrix)
|
||
surface.SetMaterial(currentElement.icon)
|
||
surface.SetDrawColor(255, 255, 255, 255)
|
||
surface.DrawTexturedRect(w / 2 - sizeW / 2, 0, sizeW, sizeH)
|
||
cam.PopModelMatrix()
|
||
end
|
||
end
|
||
end
|
||
|
||
function PANEL:AddZones()
|
||
local fr = self
|
||
local list = self.container:Add('Panel')
|
||
list:Dock(FILL)
|
||
list:DockMargin(10, 10, 0, 0)
|
||
|
||
local currentElements = 1
|
||
|
||
local zonePanles = {}
|
||
|
||
for i = 1, 8 do
|
||
local element = ELEMENTS[i]
|
||
|
||
local icon = element.icon
|
||
|
||
local size = element.size
|
||
local sizeW, sizeH = size[1] / 2, size[2] / 2
|
||
|
||
local pos = element.pos
|
||
local posX, posY = pos[1] / 2, pos[2] / 2
|
||
|
||
local zone = list:Add('DPanel')
|
||
zone:SetSize(sizeW, sizeH)
|
||
zone:SetPos(posX, posY)
|
||
|
||
if i ~= 1 then
|
||
zone:SetVisible(false)
|
||
end
|
||
|
||
zone.startTime = CurTime()
|
||
|
||
function zone:Paint(w, h)
|
||
local matrix = Matrix()
|
||
|
||
local startTime = self.startTime
|
||
|
||
local timeElapsed = (CurTime() - startTime) * 4
|
||
local value = math.sin(timeElapsed) * 0.5 + 0.5
|
||
local currentAlpha = Lerp(value, 0.5, 1)
|
||
|
||
local mul = self.placed and 1 or currentAlpha
|
||
|
||
cam.PushModelMatrix(matrix)
|
||
surface.SetMaterial(icon)
|
||
surface.SetDrawColor(255 * mul, 255 * mul, 255 * mul, self.placed and 255 or 50)
|
||
surface.DrawTexturedRect(w / 2 - sizeW / 2, 0, sizeW, sizeH)
|
||
cam.PopModelMatrix()
|
||
end
|
||
|
||
zone:Receiver('purple-menu', function(self, panels, dropped)
|
||
if not dropped then return end
|
||
|
||
local firstPanel = panels[1]
|
||
|
||
if firstPanel.i == i and not self.placed and currentElements == firstPanel.i then
|
||
self.placed = true
|
||
|
||
currentElements = currentElements + 1
|
||
|
||
local nextPanel = zonePanles[currentElements]
|
||
if nextPanel then
|
||
nextPanel:SetVisible(true)
|
||
end
|
||
|
||
if currentElements == (#ELEMENTS + 1) then
|
||
if fr.music then
|
||
fr.music:Stop()
|
||
end
|
||
surface.PlaySound("ambient/levels/labs/electric_explosion1.wav")
|
||
LocalPlayer():ScreenFade(SCREENFADE.IN, Color(0, 0, 0, 255), 0.3, 0)
|
||
timer.Simple(0.3, function()
|
||
cur_params["hud"] = "kostich"
|
||
save_settings()
|
||
chat.AddText(red, "[ИВЕНТ] ", color_white, "В сборку вернулся худ от сапа")
|
||
end)
|
||
RunConsoleCommand("success_menu")
|
||
fr:Remove()
|
||
end
|
||
end
|
||
end)
|
||
|
||
zonePanles[i] = zone
|
||
end
|
||
end
|
||
|
||
do
|
||
local colorAlpha = ColorAlpha(accentColor, 255)
|
||
|
||
function PANEL:Paint(w, h)
|
||
local startTime = self.startTime
|
||
|
||
local timeElapsed = CurTime() - startTime
|
||
local value = math.sin(timeElapsed) * 0.5 + 0.5
|
||
local currentAlpha = Lerp(value, 0.5, 1)
|
||
|
||
colorAlpha = ColorAlpha(colorAlpha, 255 * currentAlpha)
|
||
|
||
RNDX().Rect(0, 0, w, h)
|
||
:Color(colorAlpha)
|
||
:Shadow(20, 20)
|
||
:Rad(BOX_ROUNDED)
|
||
:Draw()
|
||
|
||
rect(BOX_ROUNDED, 0, 0, w, h, backgroundColor)
|
||
end
|
||
end
|
||
|
||
vgui.Register('quest.purpleMenu', PANEL, 'EditablePanel')
|
||
|
||
function kostich.menu_pasting()
|
||
local menu = vgui.Create('quest.purpleMenu')
|
||
menu:SetSize(1300, 800)
|
||
menu:Center()
|
||
menu:MakePopup()
|
||
end
|
||
|
||
concommand.Add("play_menu", function()
|
||
kostich.menu_pasting()
|
||
end)
|
||
|
||
concommand.Add("play_plib", function()
|
||
kostich.deploy_game()
|
||
end)
|
||
|
||
concommand.Add("play_bank", function()
|
||
kostich.bank_game()
|
||
end)
|
||
|
||
concommand.Add("show_titles", function()
|
||
kostich.titles()
|
||
end)
|
||
|
||
|
||
local vol = 4
|
||
net.Receive("pavetr.sendSound", function(_, ply)
|
||
local snd = net.ReadString()
|
||
sound.PlayFile(snd, "noplay", function(station, errCode, errStr)
|
||
if (IsValid(station)) then
|
||
station:Play()
|
||
station:SetVolume(vol)
|
||
else
|
||
print("[QuestSay] Error playing sound", snd, errCode, errStr)
|
||
end
|
||
end)
|
||
end)
|
||
|
||
local highlight = Color(0, 155, 255)
|
||
local delay = 60 * 5
|
||
local msgs = {
|
||
{ highlight, "[MMK] ", color_white, "Правила и информация о персонажах находятся в ", highlight, "F4->Вики" },
|
||
{ highlight, "[MMK] ", color_white, "Нет озвучки или музыки? Скачайте контент по инструкции в ", highlight, "F4->Вики" },
|
||
{ highlight, "[MMK] ", color_white, "Заходите на ", highlight, "pavetr.ru/ds ", color_white, "чтобы не пропустить новые ивенты" },
|
||
{ highlight, "[MMK] ", color_white, "Вы можете покупать хилки и броню в ", highlight, "F4->Магазин" },
|
||
}
|
||
timer.Create("chat_msg", delay, 0, function()
|
||
local msg = msgs[math.random(#msgs)]
|
||
chat.AddText(unpack(msg))
|
||
end)
|