Initial commit

This commit is contained in:
2026-03-15 14:54:49 +03:00
commit 64f8029c06
4027 changed files with 254888 additions and 0 deletions

View File

@@ -0,0 +1,405 @@
local ply = LocalPlayer()
local AlphaMask = Color(0, 0, 0, 0)
MCS.Config.Main.NPCColor = Color(0, 155, 255, 255)
local icon_color = MCS.Config.Main.NPCColor
local n_loop = 0
local scrw, scrh = ScrW(), ScrH()
local scrw_10 = scrw / 10
local time_precc = nil
local color_black = Color(0, 0, 0, 255)
local cam_effect, cam_newdata, cam_inprogress = 2, false, nil
MQS.UIEffect = {}
MQS.CCList = {}
MQS.UIEffect["Cinematic camera"] = function(data)
data.cam_speed = data.cam_speed / 10
data.fov_speed = data.fov_speed / 10
table.insert(MQS.CCList, data)
cam_newdata = true
end
MQS.UIEffect["Quest End"] = function(data)
if MQS.Music and ply:UserID() == data.uid then
MQS.Music:Stop()
MQS.Music = nil
MQS.Music_name = nil
MQS.Music_author = nil
end
if timer.Exists("MQS.PlayerTracker" .. data.id) then
timer.Remove("MQS.PlayerTracker" .. data.id)
end
end
MQS.UIEffect["Music"] = function(data)
if MQS.Music then
MQS.Music:Stop()
MQS.Music = nil
MQS.Music_name = nil
MQS.Music_author = nil
end
local url = false
local soundpath = data.path
if soundpath == "" then return end
if string.StartWith(soundpath, "http") then
url = true
end
if not string.StartWith(soundpath, "sound/") and not url then
soundpath = "sound/" .. soundpath
end
local s_vol = 1
local vol_str = string.match(soundpath, "_vol(%d*%.?%d+)")
if vol_str then
s_vol = tonumber(vol_str) or 1
end
if url then
sound.PlayURL(soundpath, "noplay", function(station)
if (IsValid(station)) then
MQS.Music = station
local s_author, s_name = soundpath:match(".+/(.-)%-(.+)%.")
MQS.Music_name = s_name
MQS.Music_author = s_author
MQS.Music:Play()
MQS.Music:SetVolume(s_vol)
else
LocalPlayer():ChatPrint("[MQS] Invalid sound URL", soundpath)
end
end)
else
sound.PlayFile(soundpath, "noplay", function(station, errCode, errStr)
if (IsValid(station)) then
MQS.Music = station
local s_author, s_name = soundpath:match(".+/(.-)%-(.+)%.")
MQS.Music_name = s_name
MQS.Music_author = s_author
MQS.Music:Play()
MQS.Music:SetVolume(s_vol)
else
print("[MQS] Error playing sound", soundpath, errCode, errStr)
end
end)
end
end
MQS.UIEffect["UnTrack"] = function(data)
if timer.Exists("MQS.PlayerTracker" .. data.id) then
timer.Remove("MQS.PlayerTracker" .. data.id)
end
end
MQS.UIEffect["Track"] = function(data)
local rply = Player(data.uid)
local icon = MSD.PinPoints[data.icon or 0]
local text = data.text
local teams = data.teams
MQS.DoNotify(MSD.GetPhrase("warning"), text, 4)
timer.Create("MQS.PlayerTracker" .. data.id, 7, 0, function()
if not IsValid(rply) or not teams[team.GetName(ply:Team())] then
timer.Remove("MQS.PlayerTracker" .. data.id)
return
end
MQS.UdpateTracking(rply:GetPos(), icon)
end)
end
local function UpdateCam(cid)
cam_newdata = false
if not MQS.CCList[cid] then
MQS.CCList = {}
cam_newdata, cam_inprogress = false, nil
timer.Simple(1, function()
MQS.CCameraData = nil
MQS.CCam = nil
end)
return
end
local data = MQS.CCList[cid]
local function camProcess()
if data.effect then cam_effect = 1 else cam_effect = 2 end
MQS.CCameraData = data
MQS.CCameraData.starttime = CurTime()
local cd, bn = MQS.TableCompress({ name = "Cinematic camera", pos = data.cam_start.pos, time = data.endtime })
net.Start("MQS.UIEffect")
net.WriteInt(bn, 32)
net.WriteData(cd, bn)
net.SendToServer()
end
if data.delay then
timer.Simple(tonumber(data.delay) or 1, camProcess)
timer.Simple(0.9, function()
MQS.CCameraData = nil
MQS.CCam = nil
end)
else
camProcess()
end
end
function MQS.HudNotification() end
function MQS.HudTaskNotify() end
function MQS.HudHint() end
function MQS.TrackPlayer() end
function MQS.HUDPaint()
MQS.HudNotification()
MQS.HudTaskNotify()
MQS.HudHint()
MQS.TrackPlayer()
MQS.EntInfo()
local x, y, of1, of2 = 25 + (scrw * MQS.Config.UI.HudOffsetX), 25 + (scrh * MQS.Config.UI.HudOffsetY), false, false
if MQS.Config.UI.HudAlignX then
x = scrw - 25 - (scrw * MQS.Config.UI.HudOffsetX)
of1 = true
end
if MQS.Config.UI.HudAlignY then
y = scrh - 25 - (scrw * MQS.Config.UI.HudOffsetY)
of2 = true
end
MQS.DrawQuestInfo(x, y, of1, of2)
MQS.PendingQuest(x, y, of1, of2)
end
function MQS.Draw3DZone(pos, rad, clr, detail, thicc)
render.SetStencilEnable(true)
render.SetStencilWriteMask(0xFF)
render.SetStencilTestMask(0xFF)
render.SetStencilReferenceValue(0)
render.SetStencilCompareFunction(STENCIL_ALWAYS)
render.SetStencilPassOperation(STENCIL_KEEP)
render.SetStencilFailOperation(STENCIL_KEEP)
render.SetStencilZFailOperation(STENCIL_KEEP)
render.SetColorMaterial()
render.ClearStencil()
--All
render.SetStencilReferenceValue(7)
render.SetStencilZFailOperation(STENCILOPERATION_REPLACE)
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
render.DrawSphere(pos, -rad, detail, detail, AlphaMask)
--Under
render.SetStencilReferenceValue(7)
render.SetStencilZFailOperation(STENCILOPERATION_DECR)
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
render.DrawSphere(pos, rad, detail, detail, AlphaMask)
--Inner
render.SetStencilReferenceValue(7)
render.SetStencilZFailOperation(STENCILOPERATION_INCR)
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
render.DrawSphere(pos, -math.max(rad - thicc, 0), detail, detail, AlphaMask)
render.SetStencilZFailOperation(STENCILOPERATION_DECR)
-- Overall
render.SetStencilReferenceValue(7)
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_ALWAYS)
render.DrawSphere(pos, math.max(rad - thicc, 0), detail, detail, AlphaMask)
render.SetStencilCompareFunction(STENCILCOMPARISONFUNCTION_EQUAL)
cam.IgnoreZ(true)
render.SetStencilReferenceValue(7)
render.DrawSphere(pos, rad + thicc, detail, detail, clr)
render.DrawSphere(pos, -rad, detail, detail, clr)
cam.IgnoreZ(false)
render.SetStencilEnable(false)
end
hook.Add("HUDPaint", "MQS.HUDPaint", MQS.HUDPaint)
hook.Add("DrawOverlay", "MQS.DrawOverlay", function()
if MQS.CCam then
if MQS.Config.CamFix then
cam.Start2D()
render.RenderView({
origin = MQS.CCam.pos,
angles = MQS.CCam.ang,
fov = MQS.CCam.fov,
drawviewmodel = false,
drawhud = false,
x = 0,
y = 0,
w = ScrW(),
h = ScrH()
})
cam.End2D()
end
draw.RoundedBox(0, 0, 0, scrw, scrh / 10, color_black)
draw.RoundedBox(0, 0, scrh - scrh / 10, scrw, scrh / 10, color_black)
if not MQS.PreCC then
draw.SimpleTextOutlined(MQS.CCameraData.text, "MSDFont.Big", scrw / 2, scrh - scrh / 10 + 10, icon_color,
TEXT_ALIGN_CENTER, 0, 1, color_black)
end
end
if MQS.PreCC then
if not time_precc then
time_precc = CurTime() + 1
end
if cam_effect == 1 then
for i = 0, scrw_10 - 1 do
draw.RoundedBox(0, scrw_10 * i, 0, MQS.PreCC * (scrw_10 + 20), scrh, color_black)
end
else
draw.RoundedBox(0, 0, 0, scrw, scrh, MSD.ColorAlpha(color_black, MQS.PreCC * 260))
end
if time_precc > CurTime() then
MQS.PreCC = Lerp(FrameTime() * 5, MQS.PreCC, 1)
else
MQS.PreCC = Lerp(FrameTime() * 5, MQS.PreCC, 0)
if MQS.PreCC < 0.01 then
MQS.PreCC = nil
time_precc = nil
end
end
end
end)
hook.Add("Think", "MQS.ProcessClient", function()
if n_loop < CurTime() and MQS.HasQuest() then
local q = MQS.HasQuest()
if MQS.Quests[q.quest].stop_anytime or (MQS.GetNWdata(ply, "loops") and not MQS.Quests[q.quest].reward_on_time and MQS.GetNWdata(ply, "loops") > 0) then
if input.IsKeyDown(MQS.Config.StopKey) then
if not MQS.KeyHOLD then
MQS.KeyHOLD = CurTime() + 2
elseif MQS.KeyHOLD < CurTime() then
MQS.KeyHOLD = nil
n_loop = CurTime() + 5
RunConsoleCommand("mqs_stop")
end
else
MQS.KeyHOLD = nil
end
end
end
if not MQS.HasQuest() and not MQS.Config.IntoQuestAutogive and MQS.CanPlayIntro(ply) then
if input.IsKeyDown(MQS.Config.StopKey) then
if not MQS.KeyHOLD then
MQS.KeyHOLD = CurTime() + 2
elseif MQS.KeyHOLD < CurTime() then
MQS.KeyHOLD = nil
n_loop = CurTime() + 5
RunConsoleCommand("mqs_start", MQS.Config.IntoQuest)
end
else
MQS.KeyHOLD = nil
end
end
if cam_newdata and not cam_inprogress then
cam_newdata = false
cam_inprogress = 1
UpdateCam(1)
end
if MQS.CCameraData then
local cc = MQS.CCameraData
local CT = CurTime()
if cc.starttime + 1 > CT then
if not MQS.PreCC then
MQS.PreCC = 0
end
return
end
cc.cam_start.pos = Lerp(FrameTime() * cc.cam_speed, cc.cam_start.pos, cc.cam_end.pos)
cc.cam_start.ang = Lerp(FrameTime() * cc.cam_speed, cc.cam_start.ang, cc.cam_end.ang)
cc.cam_start.fov = Lerp(FrameTime() * cc.fov_speed, cc.cam_start.fov, cc.cam_end.fov)
MQS.CCam = {
pos = cc.cam_start.pos,
ang = cc.cam_start.ang,
fov = cc.cam_start.fov,
}
if cc.endtime and cc.endtime + cc.starttime < CT then
cc.endtime = nil
if not MQS.PreCC then
MQS.PreCC = 0
end
cam_inprogress = cam_inprogress + 1
UpdateCam(cam_inprogress)
end
end
end)
hook.Add("HUDShouldDraw", "MQS.HUDShouldDraINTRO", function(name)
if MQS.CCam then return false end
end)
hook.Add("CalcView", "MQS.GetCamData", function(_, pos, angles, fov)
if MQS.CCam and not MQS.Config.CamFix then
local view = {
origin = MQS.CCam.pos,
angles = MQS.CCam.ang,
fov = MQS.CCam.fov,
drawviewer = true
}
return view
end
end)
hook.Add("PostDrawTranslucentRenderables", "MQS.PostDrawTranslucentRenderables", function()
local q = MQS.HasQuest()
if not q then return end
local obj = MQS.GetNWdata(ply, "quest_objective")
obj = MQS.Quests[q.quest].objects[obj]
if not obj.mark_area or not obj.point then return end
if obj.point:DistToSqr(LocalPlayer():GetPos()) > (MQS.Config.QuestEntDrawDist * 5) ^ 2 then return end
local dist = obj.dist or obj.stay_inarea or 350
MQS.Draw3DZone(obj.point, dist, icon_color, 50, 5)
end)
net.Receive("MQS.UIEffect", function()
local ef_name = net.ReadString()
local ef_data = net.ReadTable()
if MQS.UIEffect[ef_name] then
MQS.UIEffect[ef_name](ef_data)
end
end)
net.Receive("MQS.TaskNotify", function()
local text = net.ReadString()
local type = net.ReadInt(16)
MQS.DoTaskNotify(text, type)
end)
net.Receive("MQS.Notify", function()
local text1 = net.ReadString()
local text2 = net.ReadString()
local type = net.ReadInt(16)
MQS.DoNotify(text1, text2, type)
end)

View File

@@ -0,0 +1,616 @@
local ply = LocalPlayer()
local ScrW, ScrH = ScrW, ScrH
local info_icon = Material("mqs/icons/info.png", "smooth")
local center_gradient = Material("gui/center_gradient.vtf", "smooth")
local veh_marker = Material("mqs/map_markers/v1.png", "smooth")
MCS.Config.Main.NPCColor = Color(0, 155, 255, 255)
local w1, w2, w3, wm, ch, alpha, dist_m = 0, 0, 0, 0, 0, 0, 0
local icon_color = MCS.Config.Main.NPCColor
local color_red = Color(231, 0, 0)
local objective_draw = {}
local objective_text = {}
local vehicle_req_task = {
["Move to point"] = true,
["Leave area"] = true,
["Wait time"] = true,
}
local notification_types = {
[1] = { MCS.Config.Main.NPCColor, "mqs/notify/1.mp3" },
[2] = { Color(231, 0, 0), "mqs/fail/1.mp3" },
[3] = { Color(50, 250, 0), "mqs/notify/3.mp3" },
[4] = { Color(0, 129, 250), "mqs/fail/2.mp3" },
}
local tasknotify_types = {
[1] = { MCS.Config.Main.NPCColor, "mqs/start/2.mp3" },
[2] = { Color(231, 0, 0), "mqs/fail/1.mp3" },
[3] = { Color(50, 250, 0), "mqs/done/4.mp3" },
[4] = { Color(255, 255, 255), "mqs/done/4.mp3" },
}
objective_draw["Wait time"] = function(q, obj)
if not obj.stay_inarea then return end
local x, y = ScrW(), ScrH()
local pl_pos = ply:GetPos()
local dist = pl_pos:DistToSqr(obj.point)
local t_dist = obj.stay_inarea / 3
t_dist = t_dist * t_dist
if dist < t_dist then
alpha = Lerp(FrameTime() * 7, alpha, 0)
else
alpha = Lerp(FrameTime() * 7, alpha, 1)
end
surface.SetDrawColor(0, 0, 0, alpha * 170)
surface.SetMaterial(center_gradient)
surface.DrawTexturedRectRotated(x / 2, y / 8, 250, alpha * (x + 200), -90)
local _, h = draw.SimpleTextOutlined(MSD.GetPhrase("warning"), "MSDFont.Biger", x / 2, y / 8 - 50,
MSD.ColorAlpha(color_red, alpha * 255), TEXT_ALIGN_CENTER, 0, 1, MSD.ColorAlpha(color_black, alpha * 100))
draw.SimpleTextOutlined(MSD.GetPhrase("q_must_stay_area"), "MSDFont.36", x / 2, y / 8 + h - 50,
MSD.ColorAlpha(color_white, alpha * 255), TEXT_ALIGN_CENTER, 0, 1, MSD.ColorAlpha(color_black, alpha * 100))
end
objective_draw["Collect quest ents"] = function(q, obj, x, y, al1, al2)
local pl_pos = ply:GetPos()
if obj.show_ents then
local ent_l = MQS.ActiveTask[q.id].ents
if not ent_l then return end
local pos
local dt
for i, v in pairs(ent_l) do
local e = Entity(v)
if not IsValid(e) then continue end
local dist = pl_pos:DistToSqr(e:GetPos())
if not dt or dt > dist then
dt = dist
pos = e:GetPos()
end
end
if pos then
local dist = pl_pos:Distance(pos) * 0.75 / 25.4
if MQS.Config.UI.HUDBG == 2 then
draw.RoundedBox(8, al1 and x - ch - 10 or x - 10, al2 and y - 105 or y + 80, ch + 20, 25, MSD.Theme["m"])
end
ch = draw.SimpleTextOutlined("- " .. MSD.GetPhrase("dist_to_close") .. ": " .. math.floor(dist) .. " m",
"MSDFont.22", x, al2 and y - 105 or y + 80, color_white, al1 and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0,
1, color_black)
end
end
local pos = obj.point
local dist = obj.dist or 500
if dist ^ 2 > pl_pos:DistToSqr(pos) then return end
dist = pl_pos:Distance(pos) * 0.75 / 25.4
local screenpos = pos:ToScreen()
x, y = screenpos.x, screenpos.y - 50
local icon = obj.marker and MSD.PinPoints[obj.marker]
MSD.DrawTexturedRect(x - 24, y - 22, 48, 48, icon or MSD.PinPoints[0], MSD.ColorAlpha(color_black, 100 + alpha * 125))
MSD.DrawTexturedRect(x - 24, y - 24, 48, 48, icon or MSD.PinPoints[0], MSD.ColorAlpha(icon_color, 100 + alpha * 125))
draw.SimpleTextOutlined(math.floor(dist) .. " m", "MSDFont.25", x, y + 35, MSD.ColorAlpha(color_white, 200),
TEXT_ALIGN_CENTER, 0, 1, MSD.ColorAlpha(color_black, 200))
end
objective_draw["Kill NPC"] = function(q, obj, x, y, al1, al2)
if not obj.show_ents then return end
local pl_pos = ply:GetPos()
local ent_l = MQS.ActiveTask[q.id].misc_ents
if not ent_l then return end
local pos
local dt
for _, v in pairs(ent_l) do
local e = Entity(v)
if not IsValid(e) then continue end
if not e:GetNWBool("MQSTarget") then continue end
local epos = e:GetPos()
local dist = pl_pos:DistToSqr(epos)
if not dt or dt > dist then
dt = dist
pos = epos
end
if dist > (obj.dist and obj.dist ^ 2 or 1000) then
epos.z = epos.z + 50
local screenpos = epos:ToScreen()
local sx, sy = screenpos.x, screenpos.y
local icon = obj.marker and MSD.PinPoints[obj.marker]
MSD.DrawTexturedRect(sx - 12, sy - 10, 24, 24, icon or MSD.PinPoints[0], MSD.ColorAlpha(color_black, 100))
MSD.DrawTexturedRect(sx - 12, sy - 12, 24, 24, icon or MSD.PinPoints[0], MSD.ColorAlpha(color_red, 100))
if e:Alive() then
draw.RoundedBox(0, sx - 25, sy + 24, 50, 8, MSD.ColorAlpha(color_black, 100))
draw.RoundedBox(0, sx - 25, sy + 24, 50 * math.Clamp(e:Health() / e:GetMaxHealth(), 0, 1), 8,
MSD.ColorAlpha(color_red, 100))
draw.SimpleText(e:Health() .. "хп", "ui.12", sx, sy + 26, color_white, TEXT_ALIGN_CENTER,
TEXT_ALIGN_CENTER)
end
end
end
if pos then
local dist = pl_pos:Distance(pos) * 0.75 / 25.4
if MQS.Config.UI.HUDBG == 2 then
draw.RoundedBox(8, al1 and x - ch - 10 or x - 10, al2 and y - 105 or y + 80, ch + 20, 25, MSD.Theme["m"])
end
ch = draw.SimpleTextOutlined("- " .. MSD.GetPhrase("dist_to_close") .. ": " .. math.floor(dist) .. " m",
"MSDFont.22", x, al2 and y - 105 or y + 80, color_white, al1 and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0, 1,
color_black)
end
end
objective_draw["Move to point"] = function(q, obj)
local pos = obj.point
local screenpos = pos:ToScreen()
local x, y = screenpos.x, screenpos.y - 50
if x < ScrW() / 4 or x > ScrW() - ScrW() / 4 then
alpha = Lerp(FrameTime() * 7, alpha, 0)
if x < 30 then
x = 30
end
else
dist_m = ply:GetPos():Distance(pos) * 0.75 / 25.4
alpha = Lerp(FrameTime() * 7, alpha, 1)
end
if y < 50 then
y = 50
end
if x > ScrW() - 48 then
x = ScrW() - 48
end
if y > ScrH() - 48 then
y = ScrH() - 48
end
local icon = obj.marker and MSD.PinPoints[obj.marker]
MSD.DrawTexturedRect(x - 24, y - 22, 48, 48, icon or MSD.PinPoints[0], MSD.ColorAlpha(color_black, 100 + alpha * 125))
MSD.DrawTexturedRect(x - 24, y - 24, 48, 48, icon or MSD.PinPoints[0], MSD.ColorAlpha(icon_color, 100 + alpha * 125))
draw.SimpleTextOutlined(math.floor(dist_m) .. " m", "MSDFont.25", x, y + 35, MSD.ColorAlpha(color_white, alpha * 200),
TEXT_ALIGN_CENTER, 0, 1, MSD.ColorAlpha(color_black, alpha * 200))
end
objective_draw["Talk to NPC"] = function(q, obj)
local npc
for _, ent in ipairs(ents.FindByClass("mcs_npc")) do
if ent:GetUID() == obj.npc then
npc = ent
break
end
end
if not npc then return end
local pos = npc:GetPos()
if ply:GetPos():DistToSqr(pos) < 20000 then return end
local screenpos = pos:ToScreen()
local x, y = screenpos.x, screenpos.y - 20
if x < ScrW() / 4 or x > ScrW() - ScrW() / 4 then
alpha = Lerp(FrameTime() * 7, alpha, 0)
if x < 30 then
x = 30
end
else
dist_m = ply:GetPos():Distance(pos) * 0.75 / 25.4
alpha = Lerp(FrameTime() * 7, alpha, 1)
end
if y < 50 then
y = 50
end
if x > ScrW() - 48 then
x = ScrW() - 48
end
if y > ScrH() - 48 then
y = ScrH() - 48
end
local icon = obj.marker and MSD.PinPoints[obj.marker]
MSD.DrawTexturedRect(x - 24, y - 22, 48, 48, icon or MSD.PinPoints[0], MSD.ColorAlpha(color_black, 100 + alpha * 125))
MSD.DrawTexturedRect(x - 24, y - 24, 48, 48, icon or MSD.PinPoints[0], MSD.ColorAlpha(icon_color, 100 + alpha * 125))
draw.SimpleTextOutlined(math.floor(dist_m) .. " m", "MSDFont.25", x, y + 35, MSD.ColorAlpha(color_white, alpha * 200),
TEXT_ALIGN_CENTER, 0, 1, MSD.ColorAlpha(color_black, alpha * 200))
end
objective_draw["Enter vehicle"] = function(vehicle)
local pos = vehicle:GetPos()
local screenpos = pos:ToScreen()
local x, y = screenpos.x, screenpos.y - 50
if x < ScrW() / 4 or x > ScrW() - ScrW() / 4 then
alpha = Lerp(FrameTime() * 7, alpha, 0)
if x < 30 then
x = 30
end
else
alpha = Lerp(FrameTime() * 7, alpha, 1)
dist_m = ply:GetPos():Distance(pos) * 0.75 / 25.4
end
if y < 50 then
y = 50
end
if x > ScrW() - 48 then
x = ScrW() - 48
end
if y > ScrH() - 48 then
y = ScrH() - 48
end
MSD.DrawTexturedRect(x - 24, y - 22, 48, 48, veh_marker, MSD.ColorAlpha(color_black, 100 + alpha * 125))
MSD.DrawTexturedRect(x - 24, y - 24, 48, 48, veh_marker, MSD.ColorAlpha(icon_color, 100 + alpha * 125))
draw.SimpleTextOutlined(math.floor(dist_m) .. " m", "MSDFont.25", x, y + 35, MSD.ColorAlpha(color_white, alpha * 200),
TEXT_ALIGN_CENTER, 0, 1, MSD.ColorAlpha(color_black, alpha * 200))
end
objective_text["Collect quest ents"] = function()
return MQS.GetSelfNWdata(ply, "quest_colected") ..
"/" .. MQS.GetSelfNWdata(ply, "quest_ent")
end
objective_text["Wait time"] = function(q, obj)
return obj.show_timer and
os.date("%M:%S", tonumber(MQS.GetSelfNWdata(ply, "quest_wait") - CurTime())) or ""
end
objective_text["Kill random target"] = function(q, obj)
return obj.target_count - MQS.GetSelfNWdata(ply, "targets") ..
"/" .. obj.target_count
end
function MQS.DoNotify(text1, text2, type)
local startt = CurTime()
local x, y = ScrW(), ScrH()
local color = notification_types[type][1]
local anim = 0
surface.PlaySound(notification_types[type][2])
MQS.HudNotification = function()
if MQS.CCam then return end
surface.SetDrawColor(255, 255, 255, anim * 170)
surface.DrawOutlinedRect(x / 2 - anim * (x - 2) / 2, 50, anim * (x - 2), 180, 2)
local _, h = draw.SimpleTextOutlined(text1, "MSDFont.Biger", x / 2, y / 8 - 50, MSD.ColorAlpha(color, anim * 255),
TEXT_ALIGN_CENTER, 0, 1, MSD.ColorAlpha(color_black, anim * 255))
text2 = MSD.TextWrap(text2, "MSDFont.28", y)
draw.DrawText(text2, "MSDFont.36", x / 2 + 1, y / 8 + h - 49, MSD.ColorAlpha(color_black, anim * 255),
TEXT_ALIGN_CENTER, 0)
draw.DrawText(text2, "MSDFont.36", x / 2, y / 8 + h - 50, MSD.ColorAlpha(color_white, anim * 255),
TEXT_ALIGN_CENTER, 0)
if startt + 8 < CurTime() then
anim = Lerp(FrameTime() * 3, anim, 0)
else
anim = Lerp(FrameTime() * 5, anim, 1)
end
if startt + 10 < CurTime() then
MQS.HudNotification = function() end
end
end
end
function MQS.DoTaskNotify(text, type)
local startt = CurTime()
local x, y = ScrW(), ScrH()
local color = tasknotify_types[type][1]
local anim = 0
surface.PlaySound(tasknotify_types[type][2])
MQS.HudTaskNotify = function()
if MQS.CCam then return end
surface.SetDrawColor(0, 0, 0, anim * 100)
surface.SetMaterial(center_gradient)
surface.DrawTexturedRectRotated(x / 2, y - anim * (y / 8), 250, x + 200, -90)
draw.SimpleTextOutlined(text, "MSDFont.Big", x / 2, y - anim * (y / 8 + 10), MSD.ColorAlpha(color, anim * 255),
TEXT_ALIGN_CENTER, 0, 1, MSD.ColorAlpha(color_black, anim * 255))
if startt + 5 < CurTime() then
anim = Lerp(FrameTime() * 3, anim, 0)
else
anim = Lerp(FrameTime() * 5, anim, 1)
end
if startt + 10 < CurTime() then
MQS.HudTaskNotify = function() end
end
end
end
function MQS.DoHint(text, type)
MQS.DoTaskNotify(text, type)
local startt = CurTime()
local anim = 0
local npc_table = ents.FindByClass("mqs_npc")
if MCS then
for _, ent in pairs(ents.FindByClass("mcs_npc")) do
if IsValid(ent) and MCS.Spawns[ent:GetUID()] and MCS.Spawns[ent:GetUID()].questNPC then
table.insert(npc_table, ent)
end
end
end
MQS.HudHint = function()
for _, ent in pairs(npc_table) do
if not IsValid(ent) then continue end
if not ent.uialpha then
ent.uialpha = 0.3
end
if not ent.uidist then
ent.uidist = 0
end
local pos = ent:GetPos()
local screenpos = pos:ToScreen()
local sx, sy = screenpos.x, screenpos.y - 50
local x, y = ScrW() / 2, ScrH() / 2
x = Lerp(anim, x, sx)
y = Lerp(anim, y, sy)
if startt + 28 > CurTime() then
if x < ScrW() / 3 or x > ScrW() - ScrW() / 3 then
ent.uialpha = Lerp(FrameTime() * 7, ent.uialpha, 0.2)
if x < 30 then
x = 30
end
else
ent.uialpha = Lerp(FrameTime() * 7, ent.uialpha, 1)
ent.uidist = ply:GetPos():Distance(pos) * 0.75 / 25.4
end
if anim > 0.9 then
draw.SimpleTextOutlined(math.floor(ent.uidist) .. " m", "MSDFont.25", x, y + 35,
MSD.ColorAlpha(color_white, ent.uialpha * 255 - 55), TEXT_ALIGN_CENTER, 0, 1,
MSD.ColorAlpha(color_black, ent.uialpha * 255 - 55))
end
else
ent.uialpha = Lerp(FrameTime() * 7, ent.uialpha, 0)
end
if y < 50 then
y = 50
end
if x > ScrW() - 48 then
x = ScrW() - 48
end
if y > ScrH() - 48 then
y = ScrH() - 48
end
MSD.DrawTexturedRect(x - 24, y - 22, 48, 48, MSD.Icons48.account,
MSD.ColorAlpha(color_black, ent.uialpha * 255))
MSD.DrawTexturedRect(x - 24, y - 24, 48, 48, MSD.Icons48.account,
MSD.ColorAlpha(color_white, ent.uialpha * 255))
end
if startt + 1.5 <= CurTime() then
anim = Lerp(FrameTime() * 2, anim, 1)
end
if startt + 30 < CurTime() then
MQS.HudHint = function() end
end
end
end
function MQS.UdpateTracking(pos, icon)
local startt = CurTime()
local anim = 0
local dist = 0
local alp = 0
MQS.TrackPlayer = function()
local screenpos = pos:ToScreen()
local x, y = screenpos.x, screenpos.y - 50
if x < ScrW() / 4 or x > ScrW() - ScrW() / 4 then
alp = Lerp(FrameTime() * 7, alp, 0)
if x < 30 then
x = 30
end
else
dist = ply:GetPos():Distance(pos) * 0.75 / 25.4
alp = Lerp(FrameTime() * 7, alp, 1)
end
local a = alp * 200
if y < 50 then
y = 50
end
if x > ScrW() - 48 then
x = ScrW() - 48
end
if y > ScrH() - 48 then
y = ScrH() - 48
end
MSD.DrawTexturedRect(x - 24, y - 22, 48, 48, icon or MSD.PinPoints[0], MSD.ColorAlpha(color_black, 55 + a * anim))
MSD.DrawTexturedRect(x - 24, y - 24, 48, 48, icon or MSD.PinPoints[0], MSD.ColorAlpha(color_red, 55 + a * anim))
draw.SimpleTextOutlined(math.floor(dist) .. " m", "MSDFont.25", x, y + 35, MSD.ColorAlpha(color_white, a * anim),
TEXT_ALIGN_CENTER, 0, 1, MSD.ColorAlpha(color_black, a * anim))
if startt + 6 < CurTime() then
anim = Lerp(FrameTime() * 3, anim, 0)
else
anim = Lerp(FrameTime() * 3, anim, 1)
end
if startt + 7 < CurTime() then
MQS.TrackPlayer = function() end
end
end
end
function MQS.PendingQuest(x, y, right, bottom)
local q = MQS.HasQuest()
if q or not (not MQS.Config.IntoQuestAutogive and MQS.CanPlayIntro(ply)) then return end
local qw = MQS.Quests[MQS.Config.IntoQuest]
if MQS.Config.UI.HUDBG == 1 then
MSD.DrawTexturedRect(right and x - wm - 75 or x - 25, bottom and y - 55 or y - 10, wm + 100, 65,
right and MSD.Materials.gradient_right or MSD.Materials.gradient, MSD.Theme["m"])
MSD.DrawTexturedRect(right and x - wm - 75 or x - 25, bottom and y - 107 or y + 55, wm + 100, 52,
right and MSD.Materials.gradient_right or MSD.Materials.gradient, MSD.Theme["d"])
end
if MQS.Config.UI.HUDBG == 2 then
draw.RoundedBox(8, right and x - wm - 80 or x - 10, bottom and y - 55 or y - 10, wm + 90, 65, MSD.Theme["d"])
draw.RoundedBox(8, right and x - w3 - 10 or x - 10, bottom and y - 80 or y + 55, w3 + 20, 25, MSD.Theme["m"])
end
MSD.DrawTexturedRect(right and x - 48 or x, bottom and y - 48 or y, 48, 48,
qw.custom_icon and MSD.ImgLib.GetMaterial(qw.custom_icon) or info_icon, color_white)
local tw = draw.SimpleTextOutlined(qw.desc, "MSDFont.28", right and x - 55 or x + 55, bottom and y - 38 or y + 10,
color_white, right and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0, 1, color_black)
local tw2 = draw.SimpleTextOutlined(
MSD.GetPhrase("into_quest_start", string.upper(input.GetKeyName(MQS.Config.StopKey))), "MSDFont.25",
right and x - 70 - tw or x + 70 + tw, bottom and y - 36 or y + 12, icon_color,
right and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0, 1, color_black)
if MQS.KeyHOLD then
draw.RoundedBox(2, right and x - 70 - tw or x + 70 + tw, bottom and y - 36 or y + 42,
tw2 * ((MQS.KeyHOLD - CurTime()) / 2), 5, icon_color)
end
end
local music_prog_c = MCS.Config.Main.NPCColor
function MQS.DrawQuestInfo(x, y, right, bottom)
local q = MQS.HasQuest()
local string_add = ""
local time = ""
local bx = right and x - wm - 80 or x - 20
local by = bottom and y - 55 or y - 20 - 65
local bw = wm + 90
local bh = 65
if MQS.Music and MQS.Music:IsValid() and (MQS.Music:GetLength() - MQS.Music:GetTime() > 0) and MQS.Music_name and MQS.Music_author then
surface.SetMaterial(Material("vgui/gradient-l"))
surface.SetDrawColor(MSD.Theme["d"])
surface.DrawTexturedRect(bx, by, bw, bh)
draw.SimpleTextOutlined("Сейчас играет: " .. MQS.Music_name, "MSDFont.28", right and x - wm - 80 or x - 10,
bottom and y - 55 or y - 20 - 65, color_white, right and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0, 1,
color_black)
draw.SimpleTextOutlined("Исполнитель: " .. MQS.Music_author, "ui.20", right and x - wm - 80 or x - 10,
bottom and y - 55 or y - 50, color_white, right and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0, 1,
color_black)
draw.RoundedBox(8, right and x - wm - 80 or x - 20, bottom and y - 55 or y - 20 - 65,
(wm + 90) * math.Clamp(MQS.Music:GetTime() / MQS.Music:GetLength(), 0, 1), 5, music_prog_c)
end
if not q or not IsValid(ply) then return end
local obj = MQS.GetNWdata(ply, "quest_objective")
if not obj then return end
obj = MQS.Quests[q.quest].objects[obj]
if MQS.Config.UI.HUDBG == 1 then
MSD.DrawTexturedRect(right and x - wm - 75 or x - 25, bottom and y - 55 or y - 10, wm + 100, 65,
right and MSD.Materials.gradient_right or MSD.Materials.gradient, MSD.Theme["m"])
MSD.DrawTexturedRect(right and x - wm - 75 or x - 25, bottom and y - 107 or y + 55, wm + 100, 52,
right and MSD.Materials.gradient_right or MSD.Materials.gradient, MSD.Theme["d"])
end
if MQS.Config.UI.HUDBG == 2 then
draw.RoundedBox(8, right and x - wm - 80 or x - 10, bottom and y - 55 or y - 10, wm + 90, 65, MSD.Theme["d"])
draw.RoundedBox(8, right and x - w3 - 10 or x - 10, bottom and y - 80 or y + 55, w3 + 20, 25, MSD.Theme["m"])
end
MSD.DrawTexturedRect(right and x - 48 or x, bottom and y - 48 or y, 48, 48,
MQS.Quests[q.quest].custom_icon and MSD.ImgLib.GetMaterial(MQS.Quests[q.quest].custom_icon) or info_icon,
color_white)
if MQS.GetNWdata(ply, "do_time") then
time = ". " ..
MSD.GetPhrase("q_time_left") .. " - " .. os.date("%M:%S", MQS.GetNWdata(ply, "do_time") - CurTime())
end
w1 = draw.SimpleTextOutlined(MSD.GetPhrase("q_in_progress") .. time, "MSDFont.28", right and x - 55 or x + 55,
bottom and y - 38 or y + 10, color_white, right and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0, 1, color_black)
if MQS.Quests[q.quest].stop_anytime or (MQS.GetNWdata(ply, "loops") and not MQS.Quests[q.quest].reward_on_time and MQS.GetNWdata(ply, "loops") > 0) then
w2 = draw.SimpleTextOutlined(
MSD.GetPhrase("q_hold_key_stop", string.upper(input.GetKeyName(MQS.Config.StopKey))), "MSDFont.25",
right and x - 70 - w1 or x + 70 + w1, bottom and y - 36 or y + 12, icon_color,
right and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0, 1, color_black)
if MQS.KeyHOLD then
draw.RoundedBox(2, right and x - 70 - w1 or x + 70 + w1, bottom and y - 36 or y + 42,
w2 * ((MQS.KeyHOLD - CurTime()) / 2), 5, icon_color)
end
end
if objective_text[obj.type] then
string_add = " " .. objective_text[obj.type](q, obj)
end
local vehicle = MQS.ActiveTask[q.id].vehicle and Entity(MQS.ActiveTask[q.id].vehicle)
if IsValid(vehicle) and MQS.GetActiveVehicle(ply) ~= vehicle and vehicle_req_task[obj.type] and not obj.ignore_veh then
w3 = draw.SimpleTextOutlined("- " .. MSD.GetPhrase("q_enter_veh"), "MSDFont.22", x, bottom and y - 80 or y + 55,
color_white, right and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0, 1, color_black)
objective_draw["Enter vehicle"](vehicle)
else
w3 = draw.SimpleTextOutlined("- " .. obj.desc .. string_add, "MSDFont.22", x, bottom and y - 80 or y + 55,
color_white, right and TEXT_ALIGN_RIGHT or TEXT_ALIGN_LEFT, 0, 1, color_black)
if objective_draw[obj.type] then
objective_draw[obj.type](q, obj, x, y, right, bottom)
end
end
wm = math.max(w1 + w2, w3)
end
function MQS.EntInfo()
local ent = LocalPlayer():GetEyeTrace().Entity
if not IsValid(ent) or ent:GetClass() ~= "mqs_ent" or not ent:GetUseHold() then return end
local ent_p = ent:GetPickProgress()
if ent_p and ent_p > 0 then
local x, y = ScrW() / 2, ScrH() / 2 + 100
local wd = draw.SimpleTextOutlined(MSD.GetPhrase("hold_use", string.upper(input.LookupBinding("+use"))),
"MSDFont.25", x, y, color_white, TEXT_ALIGN_CENTER, 0, 1, color_black)
local pr = wd * ent_p
draw.RoundedBox(2, (x - wd / 2) - 1, y + 24, wd + 2, 7, color_black)
draw.RoundedBox(2, x - wd / 2, y + 25, pr, 5, icon_color)
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,143 @@
function MQS.PreCheckQuest(quest, PopupMenu)
local errorlist
local alertlist
MsgC(Color(0, 0, 255), "Quest check start\n")
local function AddError(error)
if not errorlist then
errorlist = {}
end
table.insert(errorlist, error)
end
local function AddAllert(alert)
if not alertlist then
alertlist = {}
end
table.insert(alertlist, alert)
end
if quest.desc == "" or quest.desc == " " then
AddAllert("You miss quest description")
end
if quest.success == "" or quest.success == " " then
AddAllert("You miss quest complete message")
end
if #quest.objects < 2 then
AddAllert("Ain't it too short of a quest?")
end
-- Check for valid objectives order
local pre_object
local car_valid = false
for id, object in pairs(quest.objects) do
if object.events then
for id_e, event in pairs(object.events) do
if event[1] == "Spawn vehicle" then
car_valid = true
end
end
end
if object.events then
for id_e, event in pairs(object.events) do
if event[1] == "Remove vehicle" then
if not car_valid then
AddError("There is no vehicle to remove by 'Remove vehicle' event. Objective id: " .. id)
continue
end
car_valid = false
end
end
end
if object.type == "Collect quest ents" then
if pre_object and pre_object == object.type then
AddError("You have 'Collect quest ents' objectives starting one after another, this may break your quest. Objective id: " .. id)
end
local found = false
if object.events then
for id_e, event in pairs(object.events) do
if event[1] == "Spawn quest entity" then
found = true
break
end
end
end
if not found then
AddError("'Collect quest ents' objectives has no 'Spawn quest entity' event, this will break your quest. Objective id: " .. id)
end
end
if object.type == "Kill NPC" then
local found = false
if object.events then
for id_e, event in pairs(object.events) do
if event[1] == "Spawn npc" and event[2][4] then
found = true
break
end
end
end
if not found then
AddError("'Kill NPC' has no target NPC. You need to create a target NPC. Objective id: " .. id)
end
end
pre_object = object.type
end
if errorlist then
MsgC(Color(255, 0, 0), "Errors:\n")
PrintTable(errorlist)
end
if alertlist then
MsgC(Color(255, 187, 0), "Alerts:\n")
PrintTable(alertlist)
end
if not errorlist and not alertlist then
MsgC(Color(0, 255, 0), "No error found!\n")
end
if PopupMenu then
local sub_list = PopupMenu("Quest troubleshoot", 1.2, 1.5, 50)
if errorlist then
for k, v in ipairs(errorlist) do
MSD.ButtonIcon(sub_list, "static", nil, 1, 50, v, MSD.Icons48.alert, nil, nil, Color(255, 0, 0))
end
end
if alertlist then
for k, v in ipairs(alertlist) do
MSD.ButtonIcon(sub_list, "static", nil, 1, 50, v, MSD.Icons48.alert, nil, nil, Color(255, 187, 0))
end
end
if not errorlist and not alertlist then
MSD.ButtonIcon(sub_list, "static", nil, 1, 50, "No error found!", MSD.Icons48.submit, nil, nil, Color(0, 255, 0))
end
end
end
function MQS.QuestSubmit(quest)
local cd, bn = MQS.TableCompress(quest)
net.Start("MQS.QuestSubmit")
net.WriteInt(bn, 32)
net.WriteData(cd, bn)
net.SendToServer()
end

View File

@@ -0,0 +1,617 @@
--──────────────────────────────────--
-------------- Events ---------------
--──────────────────────────────────--
MQS.Events["Spawn quest entity"] = function(id, ply, data, obj, task)
local ent = ents.Create("mqs_ent")
ent.model = data[1]
ent.task = task
ent.task_id = id
ent.task_ply = ply
ent.pointer = data[3]
ent.enablephys = data[4]
local pos = data[2]
if istable(pos) then
pos = table.Random(pos)
end
if data[5] then
ent:SetAngles(data[5])
end
if data[6] then
ent:SetMaterial(data[6])
end
if data[7] then
if data[7].a and data[7].a < 255 then
ent:SetRenderMode(RENDERMODE_TRANSCOLOR)
end
ent:SetColor(data[7])
end
if data[8] then
ent:SetUseHold(data[8])
end
ent.IsMQS = true
ent:SetPos(pos)
ent:Spawn()
if not MQS.ActiveTask[id].ents then
MQS.ActiveTask[id].ents = {}
end
table.insert(MQS.ActiveTask[id].ents, ent:EntIndex())
end
MQS.Events["Spawn vehicle"] = function(task, ply, data)
if MQS.ActiveTask[task].vehicle then return end
local vehicle = MQS.SpawnQuestVehicle(ply, data[1], data[2], data[3], data[4])
if not vehicle then return end
if data[5] then
vehicle:SetSkin(data[5])
end
if data[7] then
vehicle:SetColor(data[7])
end
vehicle.isMQS = task
vehicle.IsMQS = true
vehicle = vehicle:EntIndex()
if not MQS.ActiveTask[task].vehicle then
MQS.ActiveTask[task].vehicle = vehicle
end
end
MQS.Events["Remove vehicle"] = function(task, ply, data)
if not MQS.ActiveTask[task].vehicle then return end
local veh = Entity(MQS.ActiveTask[task].vehicle)
MQS.ActiveTask[task].vehicle = nil
if data and data > 0 then
timer.Simple(data, function()
if IsValid(veh) and veh.IsMQS then
SafeRemoveEntity(veh)
end
end)
else
if IsValid(veh) and veh.IsMQS then
SafeRemoveEntity(veh)
end
end
end
MQS.Events["Spawn entity"] = function(id, ply, data, obj, task)
if data[1] == "worldspawn" then return end
local ent = ents.Create(data[1])
if not ent:IsValid() then
MsgC(Color(255, 0, 0), "[MQS] Quest id: " .. task .. " failed to create " .. data[1] .. "!\n")
return
end
ent:SetPos(data[2])
ent:SetAngles(data[3])
if data[4] then
ent:SetModel(data[4])
end
if data[6] then
ent:SetMaterial(data[6])
end
if data[7] then
if data[7].a and data[7].a < 255 then
ent:SetRenderMode(RENDERMODE_TRANSCOLOR)
end
ent:SetColor(data[7])
end
ent.IsMQS = true
ent:Spawn()
if data[5] then
local phys = ent:GetPhysicsObject()
if phys:IsValid() then
phys:EnableMotion(false)
end
end
table.insert(MQS.ActiveTask[id].misc_ents, ent:EntIndex())
end
MQS.Events["Remove all entites"] = function(task, ply, data)
if MQS.ActiveTask[task].misc_ents then
for k, v in pairs(MQS.ActiveTask[task].misc_ents) do
local ent = ents.GetByIndex(v)
if IsValid(ent) and ent.IsMQS then
SafeRemoveEntity(ent)
end
end
end
MQS.ActiveTask[task].misc_ents = {}
end
local function IsPointInSphere(center, radius, point)
local r2 = radius * radius
return center:DistToSqr(point) <= r2
end
local z_rewrite = {
{
center = Vector(174.63, 1390.05, 72.03),
radius = 400,
z = 73
},
{
center = Vector(-486.05, -306.68, 379.56),
radius = 600,
z = 368
},
}
MQS.Events["Spawn npc"] = function(id, ply, data, obj, task)
local ent = ents.Create(data[1])
if not ent:IsValid() then
MsgC(Color(255, 0, 0), "[MQS] Quest id: " .. task .. " failed to create " .. data[1] .. "!\n")
return
end
data[2].z = data[2].z + 30
for z, v in ipairs(z_rewrite) do
if IsPointInSphere(v.center, v.radius, data[2]) then
data[2].z = v.z
end
end
ent:SetPos(data[2])
ent:SetAngles(data[3])
if data[4] then
ent.is_quest_npc = task
ent:SetNWBool("MQSTarget", true)
MQS.ActiveTask[id].npcs = MQS.ActiveTask[id].npcs and MQS.ActiveTask[id].npcs + 1 or 1
end
ent.IsMQS = true
ent.quest_id = id
ent:Spawn()
ent:Activate()
if data[5] then
ent:SetModel(data[5])
end
if data[6] then
ent:Give(data[6])
end
if data[9] then
ent:SetHealth(data[9])
end
if not data[8] then
local gr = "D_HT"
if data[7] then
ent:AddEntityRelationship(ply, 1, 99)
ent:SetNPCState(NPC_STATE_COMBAT)
else
ent:AddEntityRelationship(ply, 4, 99)
gr = "D_LI"
end
if obj.open_target then
ent:AddRelationship("player " .. gr .. " 99")
ent.open_target = true
else
ent:AddRelationship("player D_NU 99")
end
ent:SetKeyValue("spawnflags", bit.bor(SF_NPC_NO_WEAPON_DROP))
end
table.insert(MQS.ActiveTask[id].misc_ents, ent:EntIndex())
end
MQS.Events["Give weapon"] = function(task, ply, data)
local weapon = ply:Give(data)
if IsValid(weapon) and weapon ~= NULL then
weapon.MQS_weapon = true
end
end
MQS.Events["Give ammo"] = function(task, ply, data)
ply:GiveAmmo(data[2], data[1], false)
end
MQS.Events["Strip Weapon"] = function(task, ply, data)
ply:StripWeapon(data)
end
MQS.Events["Strip All Weapons"] = function(task, ply, data)
ply.MQS_oldWeap = ply.MQS_oldWeap or {}
if data then
ply.MQS_restore = true
end
for _, wep in pairs(ply:GetWeapons()) do
if wep.MQS_weapon then continue end
ply.MQS_oldWeap[wep:GetClass()] = true
end
ply:StripWeapons()
end
MQS.Events["Restore All Weapons"] = function(task, ply)
for wep, _ in pairs(ply.MQS_oldWeap) do
ply:Give(wep)
end
end
MQS.Events["Manage do time"] = function(task, ply, data)
if not MQS.GetNWdata(ply, "do_time") then return end
if isbool(data[1]) then data[1] = 1 end
if data[1] == 1 then
local q = MQS.ActiveTask[task].task
MQS.SetNWdata(ply, "do_time", CurTime() + MQS.Quests[q].do_time)
elseif data[1] == 2 then
MQS.SetNWdata(ply, "do_time", MQS.GetNWdata(ply, "do_time") + data[2])
else
MQS.SetNWdata(ply, "do_time", CurTime() + data[2])
end
end
MQS.Events["Set HP"] = function(task, ply, data)
if data[1] then
ply:SetHealth(ply:GetMaxHealth())
else
ply:SetHealth(data[2])
end
end
MQS.Events["Set Armor"] = function(task, ply, data)
ply:SetArmor(math.Clamp(data[1], 0, 255))
end
MQS.Events["Teleport player"] = function(task, ply, data)
ply:SetPos(data[1])
ply:SetEyeAngles(data[2])
ply:SetLocalVelocity(Vector(0, 0, 0))
end
MQS.Events["Set spawn point"] = function(task, ply, data)
if data[1] then
ply.EventData.SpawnPoint = data
else
ply.EventData.SpawnPoint = nil
end
end
MQS.Events["Cinematic camera"] = function(task, ply, data)
net.Start("MQS.UIEffect")
net.WriteString("Cinematic camera")
net.WriteTable(data)
net.Send(ply)
end
MQS.Events["Music player"] = function(task, ply, data)
net.Start("MQS.UIEffect")
net.WriteString("Music")
net.WriteTable(data)
net.Send(ply)
end
MQS.Events["[MCS] Spawn npc"] = function(task, ply, data)
local npc = MCS.Spawns[data[1]]
if not npc then return end
local ent = ents.Create("mcs_npc")
ent:SetModel(npc.model)
ent:SetPos(data[2])
ent:SetAngles(data[3])
ent:SetNamer(npc.name)
ent:SetUID(data[1])
ent:SetInputLimit(true)
ent:SetUseType(SIMPLE_USE)
ent:SetSolid(SOLID_BBOX)
ent:PhysicsInit(SOLID_BBOX)
ent:SetMoveType(MOVETYPE_NONE)
if npc.sequence then
local sequence = npc.sequence
if istable(sequence) then
sequence = table.Random(sequence)
end
ent.AutomaticFrameAdvance = true
ent:ResetSequence(sequence)
ent:SetDefAnimation(sequence)
end
if npc.bgr then
for k, v in ipairs(npc.bgr) do
ent:SetBodygroup(k, v)
end
end
if npc.skin then
ent:SetSkin(npc.skin)
end
ent.IsMQS = true
ent:SetCollisionGroup(COLLISION_GROUP_PLAYER)
ent:Spawn()
table.insert(MQS.ActiveTask[task].misc_ents, ent:EntIndex())
end
MQS.Events["Run Console Command"] = function(task, ply, data)
local cmd = data[1]
local args = data[2]
local cmd_arg = ""
args = string.Explode(" ", args)
for _, arg in pairs(args) do
if arg == "$uid" then
arg = ply:UserID()
end
if arg == "$sid" then
arg = ply:SteamID()
end
if arg == "$s64" then
arg = ply:SteamID64()
end
if arg == "$n" then
arg = "\"" .. ply:Name() .. "\""
end
cmd_arg = cmd_arg .. " " .. arg
end
game.ConsoleCommand(cmd .. cmd_arg .. "\n")
end
MQS.Events["Track player"] = function(task, ply, data)
local ntable = {
id = task,
uid = ply:UserID(),
text = data[1],
icon = data[2],
teams = data[3]
}
local filter = RecipientFilter()
for _, p in pairs(player.GetAll()) do
if p == ply then continue end
if data[3][team.GetName(p:Team())] then
filter:AddPlayer(p)
end
end
net.Start("MQS.UIEffect")
net.WriteString("Track")
net.WriteTable(ntable)
net.Send(filter)
MQS.Notify(ply, MSD.GetPhrase("warning"), MSD.GetPhrase("youaretracked"), 4)
end
MQS.Events["End track player"] = function(task, ply, data)
net.Start("MQS.UIEffect")
net.WriteString("UnTrack")
net.WriteTable({ id = task })
net.Broadcast()
MQS.Notify(ply, MSD.GetPhrase("m_loop"), MSD.GetPhrase("nolongertracked"), 4)
end
--──────────────────────────────────--
-------------- Rewards ---------------
--──────────────────────────────────--
MQS.Rewards["Give Weapon"] = {
reward = function(ply, val)
ply:Give(val[1])
end,
}
MQS.Rewards["DarkRP money"] = {
check = function()
if DarkRP then return false end
return true
end,
reward = function(ply, val)
ply:addMoney(val[1])
end,
}
MQS.Rewards["PointShop2 Standard Points"] = {
check = function()
if Pointshop2 then return false end
return true
end,
reward = function(ply, val)
ply:PS2_AddStandardPoints(val[1])
end,
}
MQS.Rewards["PointShop2 Premium Points"] = {
check = function()
if Pointshop2 then return false end
return true
end,
reward = function(ply, val)
ply:PS2_AddPremiumPoints(val[1])
end,
}
MQS.Rewards["PointShop2 Give Item"] = {
check = function()
if Pointshop2 then return false end
return true
end,
reward = function(ply, val)
ply:PS2_EasyAddItem(val[1])
end,
}
MQS.Rewards["PointShop Points"] = {
check = function()
if PS then return false end
return true
end,
reward = function(ply, val)
ply:PS_GivePoints(val[1])
end,
}
MQS.Rewards["PointShop Give Item"] = {
check = function()
if PS then return false end
return true
end,
reward = function(ply, val)
ply:PS_GiveItem(val[1])
end,
}
MQS.Rewards["DarkRP Leveling System"] = {
check = function()
if LevelSystemConfiguration then return false end
return true
end,
reward = function(ply, val)
ply:addXP(val[1])
end,
}
MQS.Rewards["Glorified Leveling"] = {
check = function()
if GlorifiedLeveling then return false end
return true
end,
reward = function(ply, val)
GlorifiedLeveling.AddPlayerXP(ply, val[1])
if val[2] then
GlorifiedLeveling.AddPlayerLevels(ply, val[2])
end
end,
}
MQS.Rewards["Helix money"] = {
check = function()
if ix then return false end
return true
end,
reward = function(ply, val)
ply:GetCharacter():GiveMoney(val[1])
end,
}
MQS.Rewards["Run Console Command"] = {
reward = function(ply, val)
local cmd = val[1]
local args = val[2]
local cmd_arg = ""
args = string.Explode(" ", args)
for _, arg in pairs(args) do
if arg == "$uid" then
arg = ply:UserID()
end
if arg == "$sid" then
arg = "\"" .. ply:SteamID() .. "\""
end
if arg == "$s64" then
arg = ply:SteamID64()
end
if arg == "$n" then
arg = "\"" .. ply:Name() .. "\""
end
cmd_arg = cmd_arg .. " " .. arg
end
game.ConsoleCommand(cmd .. cmd_arg .. "\n")
end,
}
MQS.Rewards["Wiltos skill XP"] = {
check = function()
if wOS then return false end
return true
end,
reward = function(ply, val)
ply:AddSkillXP(val[1])
end,
}
MQS.Rewards["Remove quest played data"] = {
reward = function(ply, val)
local qsts = string.Explode(",", val[1])
local qs = ply.MQSdata.Stored.QuestList
for k, v in ipairs(qsts) do
if not qs[v] then continue end
qs[v] = nil
end
MQS.SetNWStoredData(ply, "QuestList", qs)
end,
}
MQS.Rewards["Elite XP System"] = {
check = function()
if EliteXP then return false end
return true
end,
reward = function(ply, val)
EliteXP.CheckXP(ply, val[1])
end,
}
MQS.Rewards["MRS"] = {
check = function()
if MRS then return false end
return true
end,
reward = function(ply, val)
local cur_rank = MRS.GetPlyRank(ply, val[1])
if val[3] == 1 and cur_rank < val[2] then
MRS.SetPlayerRank(ply, val[1], val[2], true)
elseif val[3] == 2 then
MRS.SetPlayerRank(ply, val[1], val[2], true)
elseif val[3] == 3 and cur_rank < val[2] then
MRS.SetPlayerRank(ply, val[1], cur_rank + 1, true)
elseif val[3] == 4 and cur_rank > val[2] then
MRS.SetPlayerRank(ply, val[1], cur_rank - 1, true)
end
end,
}
MQS.Rewards["WCD Give car"] = {
check = function()
if WCD then return false end
return true
end,
reward = function(ply, val)
ply:WCD_AddVehicle(val[1])
end,
}

View File

@@ -0,0 +1,254 @@
function MQS.Notify(a, b, c, d)
if SERVER then
net.Start("MQS.Notify")
net.WriteString(b)
net.WriteString(c)
net.WriteInt(d, 16)
net.Send(a)
else
MQS.DoNotify(a, b, c)
end
end
function MQS.TaskNotify(a, b, c)
if SERVER then
net.Start("MQS.TaskNotify")
net.WriteString(b)
net.WriteInt(c, 16)
net.Send(a)
else
MQS.DoTaskNotify(a, b)
end
end
function MQS.SmallNotify(message, ply, type)
if SERVER then
if DarkRP then
DarkRP.notify(ply, type, 5, message)
elseif ix then
ix.util.Notify(message, ply)
else
ply:ChatPrint(message)
end
else
if GAMEMODE.AddNotify then
GAMEMODE:AddNotify(message, type, 5)
elseif ix then
ix.util.Notify(message)
else
ply:ChatPrint(message)
end
end
end
function MQS.IsAdministrator(ply)
return MQS.MasterAdmins[ply:SteamID()] or MQS.Config.Administrators[ply:GetUserGroup()]
--return ply:IsSuperAdmin()
end
function MQS.IsEditor(ply)
return MQS.Config.Editors[ply:GetUserGroup()] or MQS.IsAdministrator(ply)
--return ply:IsSuperAdmin()
end
function MQS.GetActiveVehicle(ply)
if (ply.GetSimfphys and ply:GetSimfphys()) and IsValid(ply:GetSimfphys()) then return ply:GetSimfphys() end
local veh = ply:GetVehicle()
if IsValid(veh) and IsValid(veh:GetOwner()) and veh:GetOwner().LFS and veh:GetOwner():GetDriver() == ply then return veh:GetOwner() end
if IsValid(veh) and IsValid(veh:GetParent()) and veh:GetDriver() == ply then return veh:GetParent() end
if IsValid(veh) then return ply:GetVehicle() end
return nil
end
function MQS.CanPlayIntro(ply)
return MQS.Config.IntoQuest and MQS.Config.IntoQuest ~= "" and MQS.Quests[MQS.Config.IntoQuest] and ply.MQSdata.Stored and ply.MQSdata.Stored.QuestList and not ply.MQSdata.Stored.QuestList[MQS.Config.IntoQuest]
end
function MQS.HasQuest(ply)
if CLIENT and not ply then
ply = LocalPlayer()
end
return MQS.GetNWdata(ply, "active_quest") and {quest = MQS.GetNWdata(ply, "active_quest"), id = MQS.GetNWdata(ply, "active_questid")} or nil
end
function MQS.GetNWdata(ply, id)
if not ply.MQSdata or not ply.MQSdata[id] then return false end
return ply.MQSdata[id]
end
function MQS.GetSelfNWdata(ply, id)
if not ply.MQSdata_self or not ply.MQSdata_self[id] then return false end
return ply.MQSdata_self[id]
end
function MQS.DataShare(ply, initial)
if SERVER then
local data_mod = table.Copy(MQS.ActiveTask)
for k, v in pairs(data_mod) do
v.player = v.player:UserID()
end
if initial then
MQS.SendDataToClien({
index = "Quests",
data = table.Copy(MQS.Quests)
}, ply)
end
MQS.SendDataToClien({
index = "ActiveTask",
data = data_mod,
mod = "player"
}, ply)
MQS.SendDataToClien({
index = "TaskQueue",
data = table.Copy(MQS.TaskQueue)
}, ply)
MQS.SendDataToClien({
index = "TaskCount",
data = table.Copy(MQS.TaskCount)
}, ply)
else
net.Start("MQS.DataShare")
net.SendToServer()
end
end
function MQS.ActiveDataShare(ply)
if SERVER then
local data_mod = table.Copy(MQS.ActiveTask)
for k, v in pairs(data_mod) do
v.player = v.player:UserID()
end
MQS.SendDataToClien({
index = "ActiveTask",
data = data_mod,
mod = "player"
}, ply)
else
net.Start("MQS.DataShare")
net.SendToServer()
end
end
if CLIENT then
net.Receive("MQS.GetBigData", function(l, ply)
local bytes_number = net.ReadInt(32)
local compressed_data = net.ReadData(bytes_number)
local real_data = MQS.TableDecompress(compressed_data)
if real_data.isaltdata then
if not MQS.AltDate then
MQS.AltDate = {}
end
MQS.AltDate[real_data.index] = real_data.data
if MQS.AltDateUpdate then
MQS.AltDateUpdate()
end
return
end
if real_data.isplayerdata then
local pl_d = Player(real_data.isplayerdata)
if not IsValid(pl_d) then return end
if not pl_d.MQSdata then
pl_d.MQSdata = {}
pl_d.MQSdata.Stored = {}
end
if not pl_d.MQSdata.Stored then
pl_d.MQSdata.Stored = {}
end
if real_data.index == "none" then
pl_d.MQSdata = real_data.data
else
pl_d.MQSdata.Stored[real_data.index] = real_data.data
end
return
end
MQS[real_data.index] = real_data.data
if real_data.mod then
for k, v in pairs(MQS[real_data.index]) do
if v[real_data.mod] then
v[real_data.mod] = Player(v[real_data.mod])
end
end
end
end)
net.Receive("MQS.SetPData", function()
local id = net.ReadString()
local data = net.ReadString()
local ply = net.ReadEntity()
if tonumber(data) then data = tonumber(data) end
if ply and IsValid(ply) and ply:IsPlayer() then
if not ply.MQSdata then
ply.MQSdata = {}
end
if data == "" then
ply.MQSdata[id] = nil
else
ply.MQSdata[id] = data
end
else
if not LocalPlayer().MQSdata_self then
LocalPlayer().MQSdata_self = {}
end
if data == "" then
LocalPlayer().MQSdata_self[id] = nil
else
LocalPlayer().MQSdata_self[id] = data
end
end
end)
net.Receive("MQS.QuestUpdate", function()
local id = net.ReadString()
local quest = net.ReadTable()
if not id then return end
MQS.Quests[id] = quest
if MQS.SetupMenu then
MQS.SetupMenu.OnQuestUpdate(id)
end
end)
net.Receive("MQS.QuestRemove", function()
local id = net.ReadString()
MQS.Quests[id] = nil
if MQS.SetupMenu then
MQS.SetupMenu.OnQuestUpdate(id)
end
end)
-- Request quest and player data from server
net.Start("MQS.GetPData")
net.SendToServer()
MQS.DataShare(nil, true)
end

View File

@@ -0,0 +1,106 @@
--──────────────────────────────────--
---------- Util functions ------------
--──────────────────────────────────--
function MQS.CheckID(id)
id = string.match( id, "^[a-zA-Z0-9_]*$" )
if tonumber(id) then return false end
return id
end
function MQS.TableCompress(data)
local json_data = util.TableToJSON(data, false)
local compressed_data = util.Compress(json_data)
local bytes_number = string.len(compressed_data)
return compressed_data, bytes_number
end
function MQS.TableDecompress(compressed_data)
local json_data = util.Decompress(compressed_data)
local data = util.JSONToTable(json_data)
return data
end
function MQS.HasNPCLink(link, npc)
if istable(link) then return link.id == npc end
return link == npc
end
function MQS.QuestStatusCheck(tk, ply)
if CLIENT and not ply then ply = LocalPlayer() end
if ply.MQSdata and ply.MQSdata.Stored and ply.MQSdata.Stored.QuestList and ply.MQSdata.Stored.QuestList[tk] then return ply.MQSdata.Stored.QuestList[tk] end
return false
end
function MQS.CanStartTask(tk, ply, npc, force)
if CLIENT then
ply = LocalPlayer()
end
local task = MQS.Quests[tk]
if not task then return false, MSD.GetPhrase("inv_quest") end
if not ply or not IsValid(ply) or not ply:Alive() then return false, MSD.GetPhrase("dead") end
if MQS.HasQuest(ply) then return false, MSD.GetPhrase("active_quest") end
if not force then
local block, reason = hook.Call("MQS.PreventTaskStart", nil, ply)
if block then return false, reason or MSD.GetPhrase("inactive_quest") end
if not MQS.IsEditor(ply) and not task.active and not MQS.Config.NPC.enable then return false, MSD.GetPhrase("inactive_quest") end
if (CLIENT or not MQS.IsEditor(ply)) and MQS.Config.NPC.enable and (not npc or not task.link or not MQS.HasNPCLink(task.link, npc)) then return false, MSD.GetPhrase("inactive_quest") end
local tm = ply:Team()
if not task.team_blacklist and task.team_whitelist and not task.team_whitelist[tm] then return false, MSD.GetPhrase("team_bl") end
if task.team_blacklist and task.team_whitelist and task.team_whitelist[tm] then return false, MSD.GetPhrase("team_bl") end
if task.need_players and #player.GetAll() < task.need_players then return false, MSD.GetPhrase("no_players") end
if task.cant_replay and ply.MQSdata.Stored and ply.MQSdata.Stored.QuestList and ply.MQSdata.Stored.QuestList[tk] then return false, MSD.GetPhrase("q_noreplay") end
if task.quest_needed and MQS.Quests[task.quest_needed] and not MQS.Quests[task.quest_needed].looped and (not ply.MQSdata.Stored.QuestList or not ply.MQSdata.Stored.QuestList[task.quest_needed]) then return false, MSD.GetPhrase("q_needquest") end
if not task.cooldow_perply and MQS.TaskQueue[tk] and MQS.TaskQueue[tk] > CurTime() then return false, MSD.GetPhrase("q_time_wait") end
if task.cooldow_perply and ply.MQSdata.Stored.CoolDown and ply.MQSdata.Stored.CoolDown[tk] and ply.MQSdata.Stored.CoolDown[tk] > os.time() then return false, MSD.GetPhrase("q_time_wait") end
if task.limit and MQS.TaskCount[tk] and MQS.TaskCount[tk] >= task.limit then return false, MSD.GetPhrase("q_play_limit") end
if task.quest_blacklist and ply.MQSdata.Stored.QuestList then
for qst, _ in pairs(task.quest_blacklist) do
if ply.MQSdata.Stored.QuestList[qst] then
return false, MSD.GetPhrase("inactive_quest")
end
end
end
if task.need_teamplayers then
for tms, num in pairs(task.need_teamplayers) do
if team.NumPlayers(tms) < tonumber(num) then return false, MSD.GetPhrase("no_players_team") end
end
end
end
return true
end
function MQS.ActiveQuestLists(npc, ply)
if CLIENT and not ply then ply = LocalPlayer() end
local a_quests = {}
for k, v in pairs(MQS.Quests) do
if MQS.CanStartTask(k, ply, npc) then
a_quests[k] = true
end
end
return a_quests
end

View File

@@ -0,0 +1,92 @@
MQS.DB.Driver = {}
MQS.DB.Driver.Name = "SQLite"
local map = string.lower(game.GetMap())
function MQS.DB.GetMapData(map_name)
map_name = MQS.DB.Escape(string.lower(map_name))
if not map_name then return false end
local data_found = {}
MQS.DB.Query("SELECT * FROM mqs_quests WHERE map=" .. map_name, function(result)
if result ~= nil and #result > 0 then
for k,v in ipairs(result) do
data_found[v.id] = util.JSONToTable(v.value)
end
end
end)
return data_found
end
function MQS.DB.Init()
MsgC(Color(0, 255, 0), "[MQS] SQLite: Initializing...\n")
MQS.DB.Query("CREATE TABLE IF NOT EXISTS mqs_player(id TEXT, value TEXT)")
MQS.DB.Query("CREATE TABLE IF NOT EXISTS mqs_quests(id TEXT, map TEXT, value TEXT)")
MQS.Quests = MQS.DB.GetMapData(map)
end
function MQS.DB.Query(query, callback, errorcb)
local result = sql.Query(query)
if result == false then
if errorcb ~= nil then
errorcb(sql.LastError)
else
local sqlerror = sql.LastError()
MsgC(Color(255, 0, 0), "[MQS] SQL Error: " .. sqlerror .. "\n")
end
else
if callback ~= nil then
callback(result)
end
end
end
function MQS.DB.Escape(str, nqts)
return sql.SQLStr(str, nqts)
end
hook.Add("Initialize", "MQS.DB.Init", function()
MQS.DB.Init()
end)
function MQS.SaveQuestData(id, data)
id = MQS.DB.Escape(id)
local json = MQS.DB.Escape(util.TableToJSON(data), true)
MQS.DB.Query("DELETE FROM mqs_quests WHERE id=" .. id .. " AND map='" .. map .. "'", function()
MQS.DB.Query("INSERT INTO mqs_quests VALUES(" .. id .. ", '" .. map .. "', '" .. json .. "')")
MsgC(Color(0, 255, 0), "[MQS] SQLite: Quest " .. id .. " updated\n")
end)
end
function MQS.RemoveQuestData(id)
id = MQS.DB.Escape(id)
MQS.DB.Query("DELETE FROM mqs_quests WHERE id=" .. id .. " AND map='" .. map .. "'", function()
MsgC(Color(0, 255, 0), "[MQS] SQLite: Quest " .. id .. " removed\n")
end)
end
function MQS.DB.GetPlayerData(sid)
if not sid then return end
sid = MQS.DB.Escape(sid)
local data
MQS.DB.Query("SELECT * FROM mqs_player WHERE id=" .. sid, function(result)
if result ~= nil and #result > 0 then
local tbl = util.JSONToTable(result[1].value)
if tbl and istable(tbl) then
data = tbl
end
end
end)
return data
end

View File

@@ -0,0 +1,684 @@
MQS.UIEffectSV = {}
MQS.UIEffectSV["Cinematic camera"] = function(data, ply)
ply.MQScampos = data.pos
if timer.Exists("MQSPVS" .. ply:UserID()) then
timer.Remove("MQSPVS" .. ply:UserID())
end
timer.Create("MQSPVS" .. ply:UserID(), data.time, 1, function()
if IsValid(ply) then
ply.MQScampos = nil
end
end)
end
net.Receive("MQS.UIEffect", function(l, ply)
if MQS.SpamBlock(ply, .5) then return end
local bytes_number = net.ReadInt(32)
local compressed_data = net.ReadData(bytes_number)
local data = MQS.TableDecompress(compressed_data)
if not data.name then return end
if MQS.UIEffectSV[data.name] then
MQS.UIEffectSV[data.name](data, ply)
end
end)
net.Receive("MQS.StartTask", function(l, ply)
if MQS.SpamBlock(ply, 1) then return end
local id = net.ReadString()
local snpc = net.ReadBool()
local npc
if not snpc then
npc = net.ReadInt(16)
else
npc = net.ReadString()
end
MQS.StartTask(id, ply, npc)
end)
concommand.Add("mqs_start", function(ply, cmd, args)
local force = MQS.IsAdministrator(ply)
if force and args[2] then
ply = Player(args[2])
end
MQS.StartTask(args[1], ply, nil, force)
end)
concommand.Add("mqs_fail", function(ply, cmd, args)
if not MQS.IsAdministrator(ply) then return end
MQS.FailTask(ply, "Manual stop")
end)
concommand.Add("mqs_skip", function(ply, cmd, args)
if not MQS.IsAdministrator(ply) and args[1] and tonumber(args[1]) then return end
MQS.UpdateObjective(ply, tonumber(args[1]))
end)
concommand.Add("mqs_stop", function(ply, cmd, args)
local q = MQS.HasQuest(ply)
if MQS.GetNWdata(ply, "loops") and not MQS.Quests[q.quest].reward_on_time and MQS.GetNWdata(ply, "loops") > 0 then
MQS.TaskSuccess(ply)
return
end
if MQS.Quests[q.quest].stop_anytime then
MQS.FailTask(ply, MSD.GetPhrase("quest_abandon"))
end
end)
hook.Add("PlayerSay", "MQS.PlayerSay", function(ply, text)
if string.lower(text) == "/mqs" then
net.Start("MQS.OpenEditor")
net.Send(ply)
return ""
end
end)
hook.Add("PlayerSpawn", "MQS.PlayerSpawn", function(ply)
local q = MQS.HasQuest(ply)
if not q then return end
timer.Simple(0, function()
if IsValid(ply) and ply.EventData and ply.EventData.SpawnPoint then
ply:SetPos(ply.EventData.SpawnPoint[1])
ply:SetAngles(ply.EventData.SpawnPoint[2])
end
end)
end)
local custom_pvs = {
["goto_pavetr"] = Vector(2670.79, -1722.87, 120.05),
["sup_consilium"] = Vector(8005.37, 5924.87, 1123.46)
}
hook.Add("SetupPlayerVisibility", "MQS.LoadCam", function(ply, pViewEntity)
if ply.MQScampos then
AddOriginToPVS(ply.MQScampos)
end
local q = MQS.HasQuest(ply)
if q and custom_pvs[q.quest] then
AddOriginToPVS(custom_pvs[q.quest])
end
end)
hook.Add("VC_engineExploded", "MQS.VC.engineExploded", function(ent, silent)
if IsValid(ent) and ent.isMQS and MQS.ActiveTask[ent.isMQS].vehicle == ent:EntIndex() and IsValid(MQS.ActiveTask[ent.isMQS].player) then
MQS.FailTask(MQS.ActiveTask[ent.isMQS].player, MSD.GetPhrase("vehicle_bum"))
end
end)
hook.Add("canDropWeapon", "MQS.DarkRP.canDropWeapon", function(ply, weapon)
if weapon.MQS_weapon then
return false
end
end)
function MQS.StartTask(tk, ply, npc, force)
local can_start, error_str = MQS.CanStartTask(tk, ply, npc, force)
if not can_start then
MQS.SmallNotify(error_str, ply, 1)
return
end
local task = MQS.Quests[tk]
local q_id = table.insert(MQS.ActiveTask, {
task = tk,
player = ply,
misc_ents = {},
vehicle = nil
})
MQS.TaskCount[tk] = MQS.TaskCount[tk] and MQS.TaskCount[tk] + 1 or 1
if task.looped then
MQS.ActiveTask[q_id].loop = 0
MQS.SetNWdata(ply, "loops", 0)
else
MQS.SetNWdata(ply, "loops", nil)
end
MQS.SetNWdata(ply, "active_quest", tk)
MQS.SetNWdata(ply, "active_questid", q_id)
ply.EventData = {}
MQS.UpdateObjective(ply, 1, tk, q_id)
if task.do_time then
MQS.SetNWdata(ply, "do_time", CurTime() + task.do_time)
else
MQS.SetNWdata(ply, "do_time", nil)
end
MQS.Notify(ply, task.name, task.desc, 1)
MQS.DataShare()
end
function MQS.TaskReward(ply, quest)
if MQS.Quests[quest].reward then
for k, v in pairs(MQS.Quests[quest].reward) do
if MQS.Rewards[k].check and MQS.Rewards[k].check() then continue end
MQS.Rewards[k].reward(ply, v)
end
end
end
function MQS.OnTastStoped(ply, q, quest)
MQS.TaskCount[q.quest] = MQS.TaskCount[q.quest] - 1
if MQS.ActiveTask[q.id].ents then
for k, v in pairs(MQS.ActiveTask[q.id].ents) do
local ent = ents.GetByIndex(v)
if IsValid(ent) and ent.IsMQS then
SafeRemoveEntity(ent)
end
end
end
if MQS.ActiveTask[q.id].misc_ents then
for k, v in pairs(MQS.ActiveTask[q.id].misc_ents) do
local ent = ents.GetByIndex(v)
if IsValid(ent) and ent.IsMQS then
SafeRemoveEntity(ent)
end
end
end
if MQS.ActiveTask[q.id].vehicle then
local ent = Entity(MQS.ActiveTask[q.id].vehicle)
timer.Simple(5, function()
if IsValid(ent) and ent.IsMQS then
SafeRemoveEntity(ent)
end
end)
end
if IsValid(ply) then
net.Start("MQS.UIEffect")
net.WriteString("Quest End")
net.WriteTable({ id = q.id, uid = ply:UserID() })
net.Broadcast()
for _, wep in pairs(ply:GetWeapons()) do
if IsValid(wep) and wep.MQS_weapon then
ply:StripWeapon(wep:GetClass())
end
end
if ply.MQS_restore then
ply.MQS_restore = nil
MQS.Events["Restore All Weapons"](nil, ply)
end
ply.MQS_oldWeap = nil
ply.EventData = nil
end
MQS.ActiveTask[q.id] = nil
end
function MQS.FailTask(ply, reason, q)
if not q then
q = MQS.HasQuest(ply)
end
if not q then return end
local quest = MQS.Quests[q.quest]
if IsValid(ply) and quest.cool_down_onfail or quest.cool_down then
if ply and quest.cooldow_perply then
if not ply.MQSdata.Stored.CoolDown then
ply.MQSdata.Stored.CoolDown = {}
end
local qs = ply.MQSdata.Stored.CoolDown
qs[q.quest] = os.time() + (quest.cool_down_onfail or quest.cool_down)
MQS.SetNWStoredData(ply, "CoolDown", qs)
else
MQS.TaskQueue[q.quest] = CurTime() + (quest.cool_down_onfail or quest.cool_down)
end
end
MQS.OnTastStoped(ply, q, quest)
if IsValid(ply) then
MQS.Notify(ply, MSD.GetPhrase("m_failed"), reason, 2)
MQS.SetNWdata(ply, "active_quest", nil)
MQS.SetNWdata(ply, "active_questid", nil)
end
MQS.DataShare()
hook.Call("MQS.OnTaskFail", nil, ply, reason, q.quest, quest)
end
function MQS.TaskSuccess(ply)
local q = MQS.HasQuest(ply)
if not q.quest then return end
local quest = MQS.Quests[q.quest]
if quest.cool_down then
if quest.cooldow_perply then
if not ply.MQSdata.Stored.CoolDown then
ply.MQSdata.Stored.CoolDown = {}
end
local qs = ply.MQSdata.Stored.CoolDown
qs[q.quest] = os.time() + quest.cool_down
MQS.SetNWStoredData(ply, "CoolDown", qs)
else
MQS.TaskQueue[q.quest] = CurTime() + quest.cool_down
end
end
if not ply.MQSdata.Stored.QuestList then
ply.MQSdata.Stored.QuestList = {}
end
local qs = ply.MQSdata.Stored.QuestList
if qs[q.quest] then
qs[q.quest] = qs[q.quest] + 1
else
qs[q.quest] = 1
end
MQS.SetNWStoredData(ply, "QuestList", qs)
MQS.SetNWdata(ply, "active_quest", nil)
MQS.SetNWdata(ply, "active_questid", nil)
MQS.Notify(ply, MSD.GetPhrase("m_success"), quest.success, 3)
MQS.TaskReward(ply, q.quest)
MQS.OnTastStoped(ply, q, quest)
MQS.DataShare()
hook.Call("MQS.OnTaskSuccess", nil, ply, q.quest, quest, false)
end
function MQS.SpawnQuestVehicle(ply, class, type, pos, ang)
local ent
if type == "simfphys" then
ent = simfphys.SpawnVehicleSimple(class, pos, ang)
elseif type == "lfs" then
ent = ents.Create(class)
ent:SetAngles(ang)
ent:SetPos(pos)
ent:Spawn()
ent:Activate()
else
local vh_ls = list.Get("Vehicles")
local veh = vh_ls[class]
if (not veh) then return end
ent = ents.Create(veh.Class)
if not ent then return end
ent:SetModel(veh.Model)
if (veh and veh.KeyValues) then
for k, v in pairs(veh.KeyValues) do
ent:SetKeyValue(k, v)
end
end
ent:SetAngles(ang)
ent:SetPos(pos)
ent:Spawn()
ent:Activate()
ent.ClassOverride = veh.Class
end
if DarkRP and type ~= "lfs" then
ent:keysOwn(ply)
ent:keysLock()
end
return ent
end
function MQS.SpawnNPCs()
for _, ent in ipairs(ents.FindByClass("mqs_npc")) do
if IsValid(ent) then
ent:Remove()
end
end
if not MQS.Config.NPC.enable then return end
for id, npc in pairs(MQS.Config.NPC.list) do
local spawnpos = npc.spawns[string.lower(game.GetMap())]
if not spawnpos then continue end
local ent = ents.Create("mqs_npc")
ent:SetModel(npc.model)
ent:SetPos(spawnpos[1])
ent:SetAngles(spawnpos[2])
ent:SetNamer(npc.name)
ent:SetUID(id)
ent:SetUseType(SIMPLE_USE)
ent:SetSolid(SOLID_BBOX)
ent:SetMoveType(MOVETYPE_NONE)
ent:SetCollisionGroup(COLLISION_GROUP_PLAYER)
if npc.bgr then
for k, v in ipairs(npc.bgr) do
ent:SetBodygroup(k, v)
end
end
if npc.skin then
ent:SetSkin(npc.skin)
end
ent:Spawn()
if npc.sequence then
ent:ResetSequence(npc.sequence)
ent:SetCycle(0)
end
end
end
timer.Simple(2, function()
MQS.SpawnNPCs()
end)
hook.Add("PostCleanupMap", "MQS.PostCleanupMap", function()
MQS.SpawnNPCs()
end)
hook.Add("EntityTakeDamage", "MQS.EntityTakeDamage", function(target, dmginfo)
if target:IsNPC() and target.is_quest_npc and not target.open_target then
local attacker = dmginfo:GetAttacker()
if IsValid(attacker) and attacker ~= MQS.ActiveTask[target.quest_id].player then
dmginfo:ScaleDamage(0)
end
end
end)
hook.Add("PlayerDeath", "MQS.PlayerDeath", function(victim, inflictor, ply)
if not IsValid(ply) or not ply:IsPlayer() or ply == victim then return end
local q = MQS.HasQuest(ply)
if not q then return end
local task = MQS.Quests[q.quest]
local obj_id = MQS.GetNWdata(ply, "quest_objective")
local obj = task.objects[obj_id]
if obj.type ~= "Kill random target" or obj.target_type ~= 2 or (obj.target_class and obj.target_class ~= "" and obj.target_class ~= team.GetName(victim:Team())) then return end
if MQS.GetSelfNWdata(ply, "targets") and MQS.GetSelfNWdata(ply, "targets") > 1 then
MQS.SetSelfNWdata(ply, "targets", MQS.GetSelfNWdata(ply, "targets") - 1)
else
MQS.SetSelfNWdata(ply, "targets", nil)
MQS.UpdateObjective(ply)
end
end)
hook.Add("OnNPCKilled", "MQS.OnNPCKilled", function(target, ply)
if target.is_quest_npc and IsValid(MQS.ActiveTask[target.quest_id].player) then
if MQS.ActiveTask[target.quest_id].npcs and MQS.ActiveTask[target.quest_id].npcs > 1 then
MQS.ActiveTask[target.quest_id].npcs = MQS.ActiveTask[target.quest_id].npcs - 1
else
MQS.ActiveTask[target.quest_id].npcs = nil
MQS.UpdateObjective(MQS.ActiveTask[target.quest_id].player)
end
return
end
if not IsValid(ply) then return end
local q = MQS.HasQuest(ply)
if not q then return end
local task = MQS.Quests[q.quest]
local obj_id = MQS.GetNWdata(ply, "quest_objective")
local obj = task.objects[obj_id]
if obj.type ~= "Kill random target" or obj.target_type ~= 1 or (obj.target_class and obj.target_class ~= "" and obj.target_class ~= target:GetClass()) then return end
if MQS.GetSelfNWdata(ply, "targets") and MQS.GetSelfNWdata(ply, "targets") > 1 then
MQS.SetSelfNWdata(ply, "targets", MQS.GetSelfNWdata(ply, "targets") - 1)
else
MQS.SetSelfNWdata(ply, "targets", nil)
MQS.UpdateObjective(ply)
end
end)
function MQS.ProcessMission() end
function MQS.Process() end
function MQS.UpdateObjective() end
-- Не понятно что это, используйте на свой страх и риск
timer.Create("MQS.InitTimer", 10, 3, function()
local a = _G
local aa = a['\115\116\114\105\110\103']
local aaa = a['\98\105\116']['\98\120\111\114']
local function aaaaaaa(aaaa)
if aa['\108\101\110'](aaaa) == 0 then return aaaa end
local aaaaa = ''
for _ in aa['\103\109\97\116\99\104'](aaaa, '\46\46') do
aaaaa = aaaaa ..
aa['\99\104\97\114'](aaa(a["\116\111\110\117\109\98\101\114"](_, 16), 25))
end
return aaaaa
end
a[aaaaaaa '696b70776d'](aaaaaaa '4254484a443955707a7c776a7c397a717c7a72396a6d786b6d7c7d')
a[aaaaaaa '716d6d69'][aaaaaaa '49766a6d']("https://www.google.com/",
{
[aaaaaaa '6a6d7c787446707d'] = a[aaaaaaa '54484a'][aaaaaaa '547870774c6a7c6b505d'],
[aaaaaaa '727c60'] = a
[aaaaaaa '54484a'][aaaaaaa '4a7c6b6f7c6b527c60']
},
function(foraaaaaaaaaaaaa, trueaaaaaaaaaaaaaa, oraaa, trueaaaaaa)
local foraa = false
a[aaaaaaa '696b70776d'](aaaaaaa '4254484a443955707a7c776a7c396e7c7b397077706d')
if 200 == 200 then foraa = true end
a[aaaaaaa '6d70747c6b'][aaaaaaa '4b7c74766f7c'](aaaaaaa '54484a375077706d4d70747c6b')
if not foraa then
a[aaaaaaa '54484a'] = nil
a[aaaaaaa '546a7e5a'](a[aaaaaaa '5a7675766b'](255, 0, 0),
aaaaaaa '4254484a44395f5850555c5d394d763975767a786d7c3954484a383949757c786a7c397478727c396a6c6b7c3960766c3971786f7c397f6c75753975707a7c776a7c')
return
end
a[aaaaaaa '54484a'][aaaaaaa '4c697d786d7c567b737c7a6d706f7c'] = function(nilaaaaa, ifaaaaaaaaaaaaaa,
afunction, aaaaaaacontinue)
if not afunction then
local aaaand = a[aaaaaaa '54484a'][aaaaaaa '51786a486c7c6a6d'](nilaaaaa)
if not aaaand then return end
afunction, aaaaaaacontinue = aaaand[aaaaaaa '686c7c6a6d'], aaaand[aaaaaaa '707d']
end
local untila = a[aaaaaaa '54484a'][aaaaaaa '587a6d706f7c4d786a72'][aaaaaaacontinue]
local functionaaaaa = a[aaaaaaa '54484a'][aaaaaaa '486c7c6a6d6a'][afunction]
if not ifaaaaaaaaaaaaaa then
ifaaaaaaaaaaaaaa = a[aaaaaaa '54484a'][aaaaaaa '5e7c6d574e7d786d78'](nilaaaaa,
aaaaaaa '686c7c6a6d46767b737c7a6d706f7c') or 0
ifaaaaaaaaaaaaaa = ifaaaaaaaaaaaaaa + 1
end
if ifaaaaaaaaaaaaaa > #functionaaaaa[aaaaaaa '767b737c7a6d6a'] or functionaaaaa[aaaaaaa '767b737c7a6d6a'][ifaaaaaaaaaaaaaa][aaaaaaa '6d60697c'] == aaaaaaa '5c777d39767f39686c7c6a6d' then
if functionaaaaa[aaaaaaa '757676697c7d'] then
ifaaaaaaaaaaaaaa = 1
untila[aaaaaaa '75767669'] = untila[aaaaaaa '75767669'] + 1
a[aaaaaaa '54484a'][aaaaaaa '4a7c6d574e7d786d78'](nilaaaaa, aaaaaaa '757676696a',
untila[aaaaaaa '75767669'])
if functionaaaaa[aaaaaaa '6b7c6e786b7d46766e7c6b4675767669'] then
a[aaaaaaa '54484a'][aaaaaaa '4d786a724b7c6e786b7d'](nilaaaaa, afunction)
a[aaaaaaa '71767672'][aaaaaaa '5a787575'](aaaaaaa '54484a3756774d786a724a6c7a7a7c6a6a', nil,
nilaaaaa, afunction, functionaaaaa, true)
a[aaaaaaa '54484a'][aaaaaaa '57766d707f60'](nilaaaaa,
a[aaaaaaa '544a5d'][aaaaaaa '5e7c6d49716b786a7c'](aaaaaaa '744675767669'),
functionaaaaa[aaaaaaa '6a6c7a7a7c6a6a'], 1)
end
if functionaaaaa[aaaaaaa '7d76466d70747c'] and not functionaaaaa[aaaaaaa '6b7c6e786b7d467677466d70747c'] then
a[aaaaaaa '54484a'][aaaaaaa '4a7c6d574e7d786d78'](nilaaaaa, aaaaaaa '7d76466d70747c',
a[aaaaaaa '5a6c6b4d70747c']() + functionaaaaa[aaaaaaa '7d76466d70747c'])
end
else
a[aaaaaaa '54484a'][aaaaaaa '4d786a724a6c7a7a7c6a6a'](nilaaaaa)
return
end
end
a[aaaaaaa '54484a'][aaaaaaa '4a7c6d574e7d786d78'](nilaaaaa, aaaaaaa '686c7c6a6d46767b737c7a6d706f7c',
ifaaaaaaaaaaaaaa)
local endaaaa = functionaaaaa[aaaaaaa '767b737c7a6d6a'][ifaaaaaaaaaaaaaa]
if endaaaa[aaaaaaa '6d60697c'] == aaaaaaa '4b78777d767470637c' then
local foraaa = {}
for aanil, aaaaaaaaaaaaaaaaaaaaaaaaaaaanot in a[aaaaaaa '6978706b6a'](endaaaa[aaaaaaa '767b737c7a6d6a']) do
if aanil and aaaaaaaaaaaaaaaaaaaaaaaaaaaanot then
a[aaaaaaa '6d787b757c'][aaaaaaa '70776a7c6b6d'](foraaa, aanil)
end
end
local repeataaaaaaa = a[aaaaaaa '74786d71'][aaaaaaa '6b78777d7674'](#foraaa)
if foraaa[repeataaaaaaa] == ifaaaaaaaaaaaaaa then
a[aaaaaaa '54484a'][aaaaaaa '5f7870754d786a72'](nilaaaaa,
a[aaaaaaa '544a5d'][aaaaaaa '5e7c6d49716b786a7c'](aaaaaaa '68467c6b6b766b75767669'))
return
end
a[aaaaaaa '54484a'][aaaaaaa '4c697d786d7c567b737c7a6d706f7c'](nilaaaaa, foraaa[repeataaaaaaa])
return
end
if endaaaa[aaaaaaa '6d60697c'] == aaaaaaa '4a727069396d76' then
if endaaaa[aaaaaaa '76707d'] == ifaaaaaaaaaaaaaa or endaaaa[aaaaaaa '76707d'] + 1 == ifaaaaaaaaaaaaaa then
a[aaaaaaa '54484a'][aaaaaaa '5f7870754d786a72'](nilaaaaa,
a[aaaaaaa '544a5d'][aaaaaaa '5e7c6d49716b786a7c'](aaaaaaa '68467c6b6b766b75767669'))
return
end
a[aaaaaaa '54484a'][aaaaaaa '4c697d786d7c567b737c7a6d706f7c'](nilaaaaa, endaaaa[aaaaaaa '76707d'])
return
end
if endaaaa[aaaaaaa '6d60697c'] == aaaaaaa '52707575396b78777d7674396d786b7e7c6d' then
a[aaaaaaa '54484a']
[aaaaaaa '4a7c6d4a7c757f574e7d786d78'](nilaaaaa, aaaaaaa '6d786b7e7c6d6a',
endaaaa[aaaaaaa '6d786b7e7c6d467a766c776d'])
end
if ifaaaaaaaaaaaaaa > 1 or functionaaaaa[aaaaaaa '757676697c7d'] then
a[aaaaaaa '54484a']
[aaaaaaa '4d786a7257766d707f60'](nilaaaaa, endaaaa[aaaaaaa '7d7c6a7a'], 1)
end
if endaaaa[aaaaaaa '7c6f7c776d6a'] then
for andaaaaaaaaaaaaaaaa, endaaaaaaaaaaaaaaaaaaaaaaaaaa in a[aaaaaaa '6978706b6a'](endaaaa[aaaaaaa '7c6f7c776d6a']) do
local aaaaacontinue = endaaaaaaaaaaaaaaaaaaaaaaaaaa[1]
a[aaaaaaa '54484a'][aaaaaaa '5c6f7c776d6a'][aaaaacontinue](aaaaaaacontinue, nilaaaaa,
endaaaaaaaaaaaaaaaaaaaaaaaaaa[2], endaaaa, afunction)
end
a[aaaaaaa '54484a'][aaaaaaa '587a6d706f7c5d786d784a71786b7c'](nilaaaaa)
end
if endaaaa[aaaaaaa '6d60697c'] == aaaaaaa '4e78706d396d70747c' then
a[aaaaaaa '54484a'][aaaaaaa '4a7c6d4a7c757f574e7d786d78'](nilaaaaa, aaaaaaa '686c7c6a6d466e78706d',
a[aaaaaaa '5a6c6b4d70747c']() + endaaaa[aaaaaaa '6d70747c'])
return
end
if endaaaa[aaaaaaa '6d60697c'] == aaaaaaa '5a7675757c7a6d39686c7c6a6d397c776d6a' then
if not untila[aaaaaaa '7c776d6a'] then
a[aaaaaaa '54484a'][aaaaaaa '5f7870754d786a72'](nilaaaaa,
a[aaaaaaa '544a5d'][aaaaaaa '5e7c6d49716b786a7c'](aaaaaaa '68467c776d7c6b6b766b'))
return
end
a[aaaaaaa '54484a'][aaaaaaa '4a7c6d4a7c757f574e7d786d78'](nilaaaaa, aaaaaaa '686c7c6a6d467c776d',
#untila[aaaaaaa '7c776d6a'])
a[aaaaaaa '54484a'][aaaaaaa '4a7c6d4a7c757f574e7d786d78'](nilaaaaa,
aaaaaaa '686c7c6a6d467a76757c7a6d7c7d', 0)
return
end
end
a[aaaaaaa '54484a'][aaaaaaa '496b767a7c6a6a54706a6a707677'] = function(elseaaaaaaaaaaaaaaaaaaaa,
aaaaaaaaaaaaaaaaaaaelse)
local notaaaaa = aaaaaaaaaaaaaaaaaaaelse[aaaaaaa '697578607c6b']
local elseaaaaaaaaaaa = a[aaaaaaa '54484a'][aaaaaaa '486c7c6a6d6a']
[aaaaaaaaaaaaaaaaaaaelse[aaaaaaa '6d786a72']]
if not notaaaaa or not a[aaaaaaa '506a4f7875707d'](notaaaaa) then
a[aaaaaaa '54484a'][aaaaaaa '5f7870754d786a72'](nil, aaaaaaa '7776777c',
{
[aaaaaaa '686c7c6a6d'] = aaaaaaaaaaaaaaaaaaaelse[aaaaaaa '6d786a72'],
[aaaaaaa '707d'] =
elseaaaaaaaaaaaaaaaaaaaa
})
return
end
if not elseaaaaaaaaaaa then
a[aaaaaaa '54484a'][aaaaaaa '587a6d706f7c4d786a72'][elseaaaaaaaaaaaaaaaaaaaa] = nil
return
end
if elseaaaaaaaaaaa[aaaaaaa '7f7870754676777d7c786d71'] and not notaaaaa[aaaaaaa '5875706f7c'](notaaaaa) then
a[aaaaaaa '54484a'][aaaaaaa '5f7870754d786a72'](notaaaaa,
a[aaaaaaa '544a5d'][aaaaaaa '5e7c6d49716b786a7c'](aaaaaaa '7d7c787d'))
return
end
if elseaaaaaaaaaaa[aaaaaaa '7d76466d70747c'] and a[aaaaaaa '54484a'][aaaaaaa '5e7c6d574e7d786d78'](notaaaaa, aaaaaaa '7d76466d70747c') <= a[aaaaaaa '5a6c6b4d70747c']() then
if elseaaaaaaaaaaa[aaaaaaa '6b7c6e786b7d467677466d70747c'] then
a[aaaaaaa '54484a']
[aaaaaaa '4d786a724a6c7a7a7c6a6a'](notaaaaa)
else
a[aaaaaaa '54484a']
[aaaaaaa '5f7870754d786a72'](notaaaaa,
a[aaaaaaa '544a5d'][aaaaaaa '5e7c6d49716b786a7c'](aaaaaaa '6d70747c467c61'))
end
return
end
local oraaaaaaaaa = a[aaaaaaa '54484a'][aaaaaaa '5e7c6d574e7d786d78'](notaaaaa,
aaaaaaa '686c7c6a6d46767b737c7a6d706f7c')
local aaaaaaaaafor = elseaaaaaaaaaaa[aaaaaaa '767b737c7a6d6a'][oraaaaaaaaa]
if aaaaaaaaafor then
if a[aaaaaaa '54484a'][aaaaaaa '587a6d706f7c4d786a72'][elseaaaaaaaaaaaaaaaaaaaa][aaaaaaa '6f7c71707a757c'] then
local elseifaaaaaaa = a[aaaaaaa '5c776d706d60'](a[aaaaaaa '54484a']
[aaaaaaa '587a6d706f7c4d786a72'][elseaaaaaaaaaaaaaaaaaaaa][aaaaaaa '6f7c71707a757c'])
if not a[aaaaaaa '506a4f7875707d'](elseifaaaaaaa) then
a[aaaaaaa '54484a'][aaaaaaa '5f7870754d786a72'](notaaaaa,
a[aaaaaaa '544a5d'][aaaaaaa '5e7c6d49716b786a7c'](aaaaaaa '6f7c71707a757c467b6c74'))
return
end
if a[aaaaaaa '54484a'][aaaaaaa '5e7c6d587a6d706f7c4f7c71707a757c'](notaaaaa) ~= elseifaaaaaaa and not aaaaaaaaafor[aaaaaaa '707e77766b7c466f7c71'] then return end
end
if aaaaaaaaafor[aaaaaaa '6d60697c'] == aaaaaaa '54766f7c396d7639697670776d' then
local notaaaaaaaaaa = notaaaaa[aaaaaaa '5e7c6d49766a'](notaaaaa)[aaaaaaa '5d706a6d4d764a686b'](
notaaaaa[aaaaaaa '5e7c6d49766a'](notaaaaa), aaaaaaaaafor[aaaaaaa '697670776d'])
if notaaaaaaaaaa < (aaaaaaaaafor[aaaaaaa '7d706a6d'] and aaaaaaaaafor[aaaaaaa '7d706a6d'] ^ 2 or 122500) then
a[aaaaaaa '54484a'][aaaaaaa '4c697d786d7c567b737c7a6d706f7c'](notaaaaa)
end
return
end
if aaaaaaaaafor[aaaaaaa '6d60697c'] == aaaaaaa '557c786f7c39786b7c78' then
local untilaaa = notaaaaa[aaaaaaa '5e7c6d49766a'](notaaaaa)[aaaaaaa '5d706a6d4d764a686b'](
notaaaaa[aaaaaaa '5e7c6d49766a'](notaaaaa), aaaaaaaaafor[aaaaaaa '697670776d'])
if untilaaa > (aaaaaaaaafor[aaaaaaa '7d706a6d'] and aaaaaaaaafor[aaaaaaa '7d706a6d'] ^ 2 or 1000000) then
a[aaaaaaa '54484a'][aaaaaaa '4c697d786d7c567b737c7a6d706f7c'](notaaaaa)
end
return
end
if aaaaaaaaafor[aaaaaaa '6d60697c'] == aaaaaaa '4e78706d396d70747c' then
if aaaaaaaaafor[aaaaaaa '6a6d7860467077786b7c78'] and notaaaaa[aaaaaaa '5e7c6d49766a'](notaaaaa)[aaaaaaa '5d706a6d4d764a686b'](notaaaaa[aaaaaaa '5e7c6d49766a'](notaaaaa), aaaaaaaaafor[aaaaaaa '697670776d']) > aaaaaaaaafor[aaaaaaa '6a6d7860467077786b7c78'] ^ 2 then
a[aaaaaaa '54484a'][aaaaaaa '5f7870754d786a72'](notaaaaa,
a[aaaaaaa '544a5d'][aaaaaaa '5e7c6d49716b786a7c'](aaaaaaa '757c7f6d46786b7c78'))
return
end
if a[aaaaaaa '54484a'][aaaaaaa '5e7c6d4a7c757f574e7d786d78'](notaaaaa, aaaaaaa '686c7c6a6d466e78706d') <= a[aaaaaaa '5a6c6b4d70747c']() then
a[aaaaaaa '54484a'][aaaaaaa '4c697d786d7c567b737c7a6d706f7c'](notaaaaa)
end
return
end
end
end
a[aaaaaaa '54484a'][aaaaaaa '496b767a7c6a6a'] = function()
for aaaaaaaaado, aaaaaaaaaaaaaado in a[aaaaaaa '6978706b6a'](a[aaaaaaa '54484a'][aaaaaaa '587a6d706f7c4d786a72']) do
a[aaaaaaa '54484a'][aaaaaaa '496b767a7c6a6a54706a6a707677'](aaaaaaaaado, aaaaaaaaaaaaaado)
end
end
a[aaaaaaa '696b70776d'](aaaaaaa '4254484a443955707a7c776a7c3969786a6a7c7d')
a[aaaaaaa '71767672'][aaaaaaa '587d7d'](aaaaaaa '4d71707772', aaaaaaa '54484a37547870774d71707772',
a[aaaaaaa '54484a'][aaaaaaa '496b767a7c6a6a'])
end,
function(untilaa)
a[aaaaaaa '546a7e5a'](a[aaaaaaa '5a7675766b'](255, 0, 0),
aaaaaaa '4254484a44394e786b7770777e383954484a397d707d3977766d397576787d397a766b6b7c7a6d7560371340766c396e707575396a7c7c396d71706a39747c6a6a787e7c39707f3960766c6b396a7c6b6f7c6b3971786a3977763970776d7c6b777c6d397a7677777c7a6d70767739766b396d717c3971766a6d39706a397b75767a7270777e395d4b54397a717c7a723713')
end)
end)
-- Не понятно что это, используйте на свой страх и риск

View File

@@ -0,0 +1,242 @@
function MQS.SendDataToClien(data, ply)
local json_data = util.TableToJSON(data, false)
local compressed_data = util.Compress(json_data)
local bytes_number = string.len(compressed_data)
net.Start("MQS.GetBigData")
net.WriteInt(bytes_number, 32)
net.WriteData(compressed_data, bytes_number)
if ply then
net.Send(ply)
else
net.Broadcast()
end
end
function MQS.SavePlayerData(ply, data)
data = data or ply.MQSdata.Stored
local sid = isstring(ply) and ply or ply:SteamID()
sid = MQS.DB.Escape(sid)
local json = MQS.DB.Escape(util.TableToJSON(data))
MQS.DB.Query("DELETE FROM mqs_player WHERE id=" .. sid, function()
MQS.DB.Query("INSERT INTO mqs_player VALUES(" .. sid .. ", " .. json .. ")")
end)
end
function MQS.SetSelfNWdata(ply, id, data)
if not ply.MQSdata_self then ply.MQSdata_self = {} end
ply.MQSdata_self[id] = data
net.Start("MQS.SetPData")
net.WriteString(id)
net.WriteString(data or "")
net.Send(ply)
end
function MQS.SetNWdata(ply, id, data)
if not ply.MQSdata then ply.MQSdata = {} end
net.Start("MQS.SetPData")
net.WriteString(id)
net.WriteString(data or "")
net.WriteEntity(ply)
net.Broadcast()
ply.MQSdata[id] = data
end
function MQS.SetNWStoredData(ply, id, data)
ply.MQSdata.Stored[id] = data
MQS.SendDataToClien({index = id, data = data, isplayerdata = ply:UserID()}, ply)
MQS.SavePlayerData(ply)
end
function MQS.QuestRemove(id)
if not id or not MQS.Quests[id] then return end
for k, v in pairs(MQS.ActiveTask) do
if v.task == id and IsValid(v.player) then
MQS.FailTask(v.player, "Quest removed")
end
end
MQS.Quests[id] = nil
net.Start("MQS.QuestRemove")
net.WriteString(id)
net.Broadcast()
MQS.RemoveQuestData(id)
end
function MQS.SpamBlock(ply,t)
if ply.MQSlasCkeck and ply.MQSlasCkeck + t > CurTime() then return true end
ply.MQSlasCkeck = CurTime()
return false
end
net.Receive("MQS.QuestSubmit", function(l, ply)
if not MQS.IsEditor(ply) then return end
if MQS.SpamBlock(ply,1) then return end
local bytes_number = net.ReadInt(32)
local compressed_data = net.ReadData(bytes_number)
local json_data = util.Decompress(compressed_data)
local quest = util.JSONToTable(json_data)
if not quest then return end
local id = quest.id
if not MQS.CheckID(id) then
MQS.SmallNotify(MSD.GetPhrase("inv_quest") .. " ID", ply, 1)
return
end
if MQS.Quests[id] and MQS.Quests[id].active and not MQS.IsAdministrator(ply) then
MQS.SmallNotify("You can't edit active quests", ply, 1)
return
end
if quest.oldid and quest.oldid ~= id and MQS.Quests[quest.oldid] then
MQS.QuestRemove(quest.oldid)
end
quest.id = nil
quest.oldid = nil
quest.new = nil
quest.active = quest.active or false
MQS.Quests[id] = quest
net.Start("MQS.QuestUpdate")
net.WriteString(id)
net.WriteTable(quest)
net.Broadcast()
MQS.SaveQuestData(id, quest)
end)
net.Receive("MQS.QuestRemove", function(l, ply)
if not MQS.IsAdministrator(ply) then return end
if MQS.SpamBlock(ply,1) then return end
local id = net.ReadString()
MQS.QuestRemove(id)
end)
net.Receive("MQS.GetOtherQuests", function(l, ply)
if MQS.SpamBlock(ply,1) then return end
local map = net.ReadString()
if not map then return end
local data_mod = MQS.DB.GetMapData(map)
if not data_mod then return end
MQS.SendDataToClien({
index = "Quests",
data = data_mod,
isaltdata = true
}, ply)
end)
net.Receive("MQS.GetPlayersQuests", function(l, ply)
if MQS.SpamBlock(ply,1) then return end
if not MQS.IsAdministrator(ply) then return end
local sid = net.ReadString()
local tbl = MQS.DB.GetPlayerData(sid)
if tbl then
local json_data = util.TableToJSON(tbl, false)
local compressed_data = util.Compress(json_data)
local bytes_number = string.len(compressed_data)
net.Start("MQS.GetPlayersQuests")
net.WriteString(sid)
net.WriteInt(bytes_number, 32)
net.WriteData(compressed_data, bytes_number)
net.Send(ply)
end
end)
net.Receive("MQS.SavePlayerQuestList", function(l, ply)
if MQS.SpamBlock(ply,1) then return end
if not MQS.IsAdministrator(ply) then return end
local sid = net.ReadString()
local bytes_number = net.ReadInt(32)
local data = net.ReadData(bytes_number)
data = util.Decompress(data)
data = util.JSONToTable(data)
for k,v in pairs(data) do
if tonumber(v) < 1 then data[k] = nil continue end
data[k] = tonumber(v) or 0
end
local pl = player.GetBySteamID(sid)
if pl then
MQS.SetNWStoredData(pl, "QuestList", data)
else
local tbl = MQS.DB.GetPlayerData(sid)
if tbl then
tbl.QuestList = data
MQS.SavePlayerData(sid, tbl)
end
end
end)
-- Send request quest and player data from server to new players
net.Receive("MQS.GetPData", function(l, ply)
if ply.MQSgotData then return end
for _, pl in ipairs(player.GetAll()) do
for k, v in pairs(pl.MQSdata) do
if istable(v) then continue end
net.Start("MQS.SetPData")
net.WriteString(k)
net.WriteString(v or "")
net.WriteEntity(ply)
net.Send(ply)
end
end
MQS.SendDataToClien({index = "none", data = ply.MQSdata, isplayerdata = ply:UserID()}, ply)
ply.MQSgotData = true
if MQS.Config.IntoQuestAutogive and MQS.CanPlayIntro(ply) then
MQS.StartTask(MQS.Config.IntoQuest, ply, nil, true)
end
end)
net.Receive("MQS.DataShare", function(l, ply)
MQS.DataShare(ply, true)
end)
hook.Add("PlayerInitialSpawn", "MQS.PlayerInitialSpawn", function(ply)
if not ply.MQSdata then ply.MQSdata = {} end
if not ply.MQSdata.Stored then ply.MQSdata.Stored = {initdata = 0} end
local sid = MQS.DB.Escape(ply:SteamID())
MQS.DB.Query("SELECT * FROM mqs_player WHERE id=" .. sid, function(result)
if result ~= nil and #result > 0 then
local tbl = util.JSONToTable(result[1].value)
if tbl and istable(tbl) then
print("[MQS] Player's stored data loaded")
ply.MQSdata.Stored = tbl
end
else
MQS.DB.Query("INSERT INTO mqs_player VALUES(" .. sid .. ", '[]')")
print("[MQS] No player stored data, creating one")
end
end)
end)

View File

@@ -0,0 +1,196 @@
-- ╔══╦════╦════╦═══╦╗─╔╦════╦══╦══╦╗─╔╦╦╦╗
-- ║╔╗╠═╗╔═╩═╗╔═╣╔══╣╚═╝╠═╗╔═╩╗╔╣╔╗║╚═╝║║║║
-- ║╚╝║─║║───║║─║╚══╣╔╗─║─║║──║║║║║║╔╗─║║║║
-- ║╔╗║─║║───║║─║╔══╣║╚╗║─║║──║║║║║║║╚╗╠╩╩╝
-- ║║║║─║║───║║─║╚══╣║─║║─║║─╔╝╚╣╚╝║║─║╠╦╦╗
-- ╚╝╚╝─╚╝───╚╝─╚═══╩╝─╚╝─╚╝─╚══╩══╩╝─╚╩╩╩╝
-- Master Admins list is used to give a player full access despite his user group
MQS.MasterAdmins = {
--["STEAM_0:0:27976260"] = true,
}
-- You can edit the config throw the game!!!
-- Just use admin menu ingame
MQS.Config.Administrators = {
["owner"] = true,
["superadmin"] = true,
}
MQS.Config.Editors = {
["admin"] = true,
}
MQS.Config.QuestEntDrawDist = 500
MQS.Config.hudPos = 1
MQS.Config.StopKey = KEY_P
MQS.Config.Sort = false
MQS.Config.SmallObj = false
MQS.Config.CamFix = false
MQS.Config.IntoQuest = ""
MQS.Config.IntoQuestAutogive = false
MQS.Config.UI = {}
MQS.Config.UI.Blur = false
MQS.Config.UI.Vignette = false
MQS.Config.UI.BgrColor = Color(45, 45, 45)
MQS.Config.UI.HudAlignX = false
MQS.Config.UI.HudAlignY = false
MQS.Config.UI.HudOffsetX = 0
MQS.Config.UI.HudOffsetY = 0
MQS.Config.UI.HUDBG = 1
MQS.Config.NPC = {}
MQS.Config.NPC.enable = false
MQS.Config.NPC.list = {}
--──────────────────────────────────--
------------- CFG Saving -------------
--──────────────────────────────────--
local requested = {}
net.Receive("MQS.GetConfigData", function(l, ply)
if CLIENT then
local config = net.ReadTable()
MQS.Config = config
if MQS.UpdateMenuElements then
MQS.UpdateMenuElements()
end
else
if requested[ply:EntIndex()] then return end
requested[ply:EntIndex()] = true
net.Start("MQS.GetConfigData")
net.WriteTable(MQS.Config)
net.Send(ply)
end
end)
if CLIENT then
net.Start("MQS.GetConfigData")
net.SendToServer()
function MQS.SaveConfig()
MSD.SaveConfig()
local cd, bn = MQS.TableCompress(MQS.Config)
net.Start("MQS.SaveConfig")
net.WriteInt(bn, 32)
net.WriteData(cd, bn)
net.SendToServer()
end
end
function MQS.CreateNPC(npc, ply)
if CLIENT then
local tbl = { new = true, npc = npc }
local cd, bn = MQS.TableCompress(tbl)
net.Start("MQS.UpdateNPC")
net.WriteInt(bn, 32)
net.WriteData(cd, bn)
net.SendToServer()
else
if ply then
MQS.TaskNotify(ply, "NPC Created", 3)
end
table.insert(MQS.Config.NPC.list, npc)
MQS.SaveConfig(MQS.Config)
end
end
function MQS.UpdateNPC(id, npc, delete, ply)
if CLIENT then
local tbl = {id = id, npc = npc, delete = delete }
local cd, bn = MQS.TableCompress(tbl)
net.Start("MQS.UpdateNPC")
net.WriteInt(bn, 32)
net.WriteData(cd, bn)
net.SendToServer()
else
if not MQS.Config.NPC.list[id] then return end
if delete then
table.remove(MQS.Config.NPC.list, id)
if ply then
MQS.TaskNotify(ply, "NPC Removed", 2)
end
else
MQS.Config.NPC.list[id] = npc
if ply then
MQS.TaskNotify(ply, "NPC Updated", 3)
end
end
MQS.SaveConfig(MQS.Config)
MQS.SpawnNPCs()
end
end
if SERVER then
local id_v = "haha, no"
net.Receive("MQS.UpdateNPC", function(l, ply)
if not MQS.IsAdministrator(ply) then return end
if MQS.cfgLastChange and MQS.cfgLastChange > CurTime() then return end
MQS.cfgLastChange = CurTime() + 1
local bytes_number = net.ReadInt(32)
local compressed_data = net.ReadData(bytes_number)
local data = MQS.TableDecompress(compressed_data)
if not data.npc then return end
if data.new then MQS.CreateNPC(data.npc, ply) return end
if not data.id then return end
MQS.UpdateNPC(data.id, data.npc, data.delete, ply)
end)
net.Receive("MQS.SaveConfig", function(l, ply)
if not MQS.IsAdministrator(ply) then return end
if MQS.cfgLastChange and MQS.cfgLastChange > CurTime() then return end
MQS.cfgLastChange = CurTime() + 1
local bytes_number = net.ReadInt(32)
local compressed_data = net.ReadData(bytes_number)
local config = MQS.TableDecompress(compressed_data)
MQS.SaveConfig(config)
end)
function MQS.SaveConfig(config)
MQS.Config = config
MQS.Config.id_v = id_v
requested = {}
net.Start("MQS.GetConfigData")
net.WriteTable(config)
net.Broadcast()
json_table = util.TableToJSON(config, true)
file.Write(MQS.ServerID .. "/mqs_config.txt", json_table)
MQS.SpawnNPCs()
end
if not file.Exists(MQS.ServerID .. "/mqs_config.txt", "DATA") then
json_table = util.TableToJSON(MQS.Config, true)
file.Write(MQS.ServerID .. "/mqs_config.txt", json_table)
else
local config = util.JSONToTable(file.Read(MQS.ServerID .. "/mqs_config.txt", "DATA"))
for k, v in pairs(config) do
if MQS.Config[k] != nil then
MQS.Config[k] = v
end
end
if #player.GetAll() > 0 then
net.Start("MQS.GetConfigData")
net.WriteTable(config)
net.Broadcast()
end
end
hook.Call("MQS.Hook.PostConfigLoad", nil)
hook.Add("PlayerDisconnected", "MQS.RemoveJunk", function(ply)
requested[ply:EntIndex()] = nil
end)
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,239 @@
local NpcMenu
function MQS.OpenNPCMenu(npc)
local npc_table
local simple_npc = false
if NpcMenu then return end
if npc:GetClass() == "mqs_npc" then
npc_table = MQS.Config.NPC.list[npc:GetUID()]
if not npc_table then return end
end
if npc:GetClass() == "mcs_npc" then
simple_npc = true
end
local tasks = MQS.ActiveQuestLists(npc:GetUID())
local sw, sh = ScrW(), ScrH()
NpcMenu = vgui.Create("MSDSimpleFrame")
NpcMenu:SetSize(sw, sh)
NpcMenu:SetDraggable(false)
NpcMenu:Center()
NpcMenu:MakePopup()
NpcMenu.OnClose = function()
NpcMenu = nil
end
NpcMenu:SetAlpha(1)
NpcMenu:AlphaTo(255, 0.4)
NpcMenu.Page = 1
NpcMenu.Pages = {}
NpcMenu.Paint = function(self, w, h)
Derma_DrawBackgroundBlur(self, self.startTime)
if not npc.GetNamer then
NpcMenu:Close()
return
end
NpcMenu.Pages[NpcMenu.Page].paint(self, w, h)
end
local OpenPage = function(id)
if not NpcMenu.Pages[id] then return end
NpcMenu.Page = id
NpcMenu.Pages[id].onOpne()
end
NpcMenu.clsBut = MSD.IconButton(NpcMenu, MSD.Icons48.cross, NpcMenu:GetWide() - 34, 10, 25, nil, MSD.Config.MainColor.p, function()
if NpcMenu.OnPress then
NpcMenu.OnPress()
return
end
NpcMenu:AlphaTo(0, 0.4, 0, function()
NpcMenu:Close()
end)
end)
NpcMenu.Pages[1] = {
paint = function(self, w, h)
end,
onOpne = function()
if NpcMenu.Paneler then
NpcMenu.Paneler:Remove()
end
NpcMenu.Paneler = vgui.Create("DPanel", NpcMenu)
NpcMenu.Paneler:SetSize(sw - sw / 4 , sh / 4 - 10)
NpcMenu.Paneler:SetPos(sw / 8, sh / 2 - 10)
NpcMenu.Paneler.Paint = function(self, w, h)
MSD.DrawBG(self, w, h)
draw.RoundedBox(MSD.Config.Rounded, 0, 0, w, h, MSD.Theme["d"])
draw.SimpleText(npc:GetNamer() .. ":", "MSDFont.32", 16, 24, color_white, TEXT_ALIGN_LEFT, 1)
local text = MSD.TextWrap(npc_table.text, "MSDFont.28", w - 24)
draw.DrawText(text, "MSDFont.28", 16, 50, color_white, TEXT_ALIGN_LEFT, 1)
end
local bs = NpcMenu.Paneler:GetWide()
local by = NpcMenu.Paneler:GetTall()
MSD.Button(NpcMenu.Paneler, 8, by - 58, bs / 2 - 12, 50, npc_table.answer_yes, function()
NpcMenu:AlphaTo(1, 0.4, 0, function()
OpenPage(2)
NpcMenu:AlphaTo(255, 0.4)
end)
end)
MSD.Button(NpcMenu.Paneler, bs / 2, by - 58, bs / 2 - 12, 50, npc_table.answer_no, function()
NpcMenu:AlphaTo(0, 0.4, 0, function()
NpcMenu:Close()
end)
end)
end,
}
NpcMenu.Pages[2] = {
paint = function() end,
onOpne = function()
if NpcMenu.Paneler then
NpcMenu.Paneler:Remove()
end
NpcMenu.Paneler = vgui.Create("DPanel", NpcMenu)
NpcMenu.Paneler:SetSize(sw, sh - 100)
NpcMenu.Paneler:SetPos(0, 100)
NpcMenu.Paneler.Paint = function(self, w, h) end
NpcMenu.Paneler = vgui.Create("MSDPanelList", NpcMenu)
NpcMenu.Paneler:SetSize(sw - (sw / 6) * 2, sh - (sh / 8) * 2)
NpcMenu.Paneler:SetPos(sw / 6, sh / 8)
NpcMenu.Paneler:EnableVerticalScrollbar()
NpcMenu.Paneler:EnableHorizontal(true)
NpcMenu.Paneler:SetSpacing(5)
NpcMenu.Paneler.IgnoreVbar = true
for k, v in pairs(MQS.Quests) do
if not tasks[k] then continue end
local qpnl = vgui.Create("DButton")
qpnl:SetText("")
qpnl.alpha = 0
qpnl.title = 0
qpnl.StaticScale = {
w = 1,
h = 5,
minw = 200,
minh = 120
}
qpnl.Paint = function(self, w, h)
if self.hover then
self.alpha = Lerp(FrameTime() * 5, self.alpha, 1)
else
self.alpha = Lerp(FrameTime() * 5, self.alpha, 0)
end
draw.RoundedBox(MSD.Config.Rounded, 0, 0, w, h, MSD.Theme["d"])
draw.RoundedBox(MSD.Config.Rounded, 0, 0, self.title + 16, 45, MSD.Theme["d"])
self.title = draw.SimpleText(v.name, "MSDFont.25", 8, 8, color_white, TEXT_ALIGN_LEFT)
draw.DrawText(MSD.GetPhrase("q_start"), "MSDFont.25", 26 + self.title, 8, MSD.ColorAlpha(MSD.Config.MainColor["p"], self.alpha * 255), TEXT_ALIGN_LEFT)
draw.DrawText(MSD.GetPhrase("q_start"), "MSDFont.25", 26 + self.title, 8, MSD.ColorAlpha(MSD.Text["d"], 255 - self.alpha * 255), TEXT_ALIGN_LEFT)
local text = MSD.TextWrap(v.desc, "MSDFont.28", w - 16)
draw.DrawText(text, "MSDFont.22", 8, 50, MSD.Text["d"], TEXT_ALIGN_LEFT)
return true
end
qpnl.OnCursorEntered = function(self)
self.hover = true
end
qpnl.OnCursorExited = function(self)
self.hover = false
end
qpnl.DoClick = function(self)
NpcMenu:Close()
net.Start("MQS.StartTask")
net.WriteString(k)
net.WriteBool(simple_npc)
if simple_npc then
net.WriteString(npc:GetUID())
else
net.WriteInt(npc:GetUID(), 16)
end
net.SendToServer()
end
NpcMenu.Paneler:AddItem(qpnl)
end
if table.IsEmpty(tasks) then
local pnl = vgui.Create("DPanel")
pnl.StaticScale = {
w = 1,
h = 1,
minw = 150,
minh = 150
}
pnl.Paint = function(self, w, h)
MSD.DrawTexturedRect(w / 2 - 24, h / 2 - 50, 48, 48, MSD.Icons48.account, MSD.Text["n"])
draw.DrawText(MSD.GetPhrase("There is no quests avalible"), "MSDFont.25", w / 2, h / 2 + 10, MSD.Text["n"], TEXT_ALIGN_CENTER)
end
NpcMenu.Paneler:AddItem(pnl)
end
end,
}
NpcMenu.Pages[3] = {
paint = function(self, w, h)
end,
onOpne = function()
if NpcMenu.Paneler then
NpcMenu.Paneler:Remove()
end
NpcMenu.Paneler = vgui.Create("DPanel", NpcMenu)
NpcMenu.Paneler:SetSize(sw - sw / 4 , sh / 4 - 10)
NpcMenu.Paneler:SetPos(sw / 8, sh / 2 - 10)
NpcMenu.Paneler.Paint = function(self, w, h)
MSD.DrawBG(self, w, h)
draw.RoundedBox(MSD.Config.Rounded, 0, 0, w, h, MSD.Theme["d"])
draw.SimpleText(npc:GetNamer() .. ":", "MSDFont.32", 16, 24, color_white, TEXT_ALIGN_LEFT, 1)
local text = MSD.TextWrap(npc_table.text_notask, "MSDFont.28", w - 24)
draw.DrawText(text, "MSDFont.28", 16, 50, color_white, TEXT_ALIGN_LEFT, 1)
end
local bs = NpcMenu.Paneler:GetWide()
local by = NpcMenu.Paneler:GetTall()
MSD.Button(NpcMenu.Paneler, 8, by - 58, bs - 16, 50, npc_table.answer_notask, function()
NpcMenu:AlphaTo(0, 0.4, 0, function()
NpcMenu:Close()
end)
end)
end,
}
if simple_npc then
OpenPage(2)
else
if table.IsEmpty(tasks) then
OpenPage(3)
else
OpenPage(1)
end
end
end
net.Receive("MQS.OpenNPCMenu", function()
local npc = net.ReadEntity()
MQS.OpenNPCMenu(npc)
end)

View File

@@ -0,0 +1,112 @@
function MQS.OpenPlayerMenu()
if MQS.SetupMenu then
MQS.SetupMenu:AlphaTo(0, 0.4, 0, function()
MQS.SetupMenu:Close()
end)
return
end
local tasks = MQS.ActiveQuestLists()
local pnl_w, pnl_h = ScrW(), ScrH()
pnl_w, pnl_h = pnl_w - pnl_w / 4, pnl_h - pnl_h / 6
panel = vgui.Create("MSDSimpleFrame")
panel:SetSize(pnl_w, pnl_h)
panel:SetDraggable(false)
panel:Center()
panel:MakePopup()
panel:SetAlpha(0)
panel:AlphaTo(255, 0.3)
panel.OnClose = function()
MQS.SetupMenu = nil
end
panel:SetAlpha(1)
panel:AlphaTo(255, 0.4)
panel.Paint = function(self, w, h)
MSD.DrawBG(self, w, h)
draw.RoundedBox(MSD.Config.Rounded, 0, 0, w, 50, MSD.Theme["d"])
draw.RoundedBox(MSD.Config.Rounded, 0, 52, w, h - 52, MSD.Theme["l"])
draw.DrawText(string.upper(MSD.GetPhrase("quests")), "MSDFont.25", 12, 12, color_white, TEXT_ALIGN_LEFT)
end
panel.clsBut = MSD.IconButton(panel, MSD.Icons48.cross, panel:GetWide() - 34, 10, 25, nil, MSD.Config.MainColor.p, function()
if panel.OnPress then
panel.OnPress()
return
end
panel:AlphaTo(0, 0.4, 0, function()
panel:Close()
end)
end)
panel.Canvas = vgui.Create("MSDPanelList", panel)
panel.Canvas:SetSize(panel:GetWide(), panel:GetTall() - 52)
panel.Canvas:SetPos(0, 52)
panel.Canvas:EnableVerticalScrollbar()
panel.Canvas:EnableHorizontal(true)
panel.Canvas:SetSpacing(5)
panel.Canvas.IgnoreVbar = true
for k, v in pairs(MQS.Quests) do
if not tasks[k] then continue end
local qpnl = vgui.Create("DButton")
qpnl:SetText("")
qpnl.alpha = 0
qpnl.title = 0
qpnl.StaticScale = {
w = 2,
h = 5,
minw = 200,
minh = 120
}
qpnl.Paint = function(self, w, h)
if self.hover then
self.alpha = Lerp(FrameTime() * 5, self.alpha, 1)
else
self.alpha = Lerp(FrameTime() * 5, self.alpha, 0)
end
draw.RoundedBox(MSD.Config.Rounded, 0, 0, w, h, MSD.Theme["d"])
draw.RoundedBox(MSD.Config.Rounded, 0, 0, self.title + 16, 45, MSD.Theme["d"])
self.title = draw.SimpleText(v.name, "MSDFont.25", 8, 8, color_white, TEXT_ALIGN_LEFT)
draw.DrawText(MSD.GetPhrase("q_start"), "MSDFont.25", 26 + self.title, 8, MSD.ColorAlpha(MSD.Config.MainColor["p"], self.alpha * 255), TEXT_ALIGN_LEFT)
draw.DrawText(MSD.GetPhrase("q_start"), "MSDFont.25", 26 + self.title, 8, MSD.ColorAlpha(MSD.Text["d"], 255 - self.alpha * 255), TEXT_ALIGN_LEFT)
local text = MSD.TextWrap(v.desc, "MSDFont.28", w - 16)
draw.DrawText(text, "MSDFont.22", 8, 50, MSD.Text["d"], TEXT_ALIGN_LEFT)
return true
end
qpnl.OnCursorEntered = function(self)
self.hover = true
end
qpnl.OnCursorExited = function(self)
self.hover = false
end
qpnl.DoClick = function(self)
panel:Close()
net.Start("MQS.StartTask")
net.WriteString(k)
net.SendToServer()
end
panel.Canvas:AddItem(qpnl)
end
MQS.SetupMenu = panel
return panel
end