Initial commit
This commit is contained in:
405
addons/mc_quests/lua/mqs/core/cl_hooks.lua
Normal file
405
addons/mc_quests/lua/mqs/core/cl_hooks.lua
Normal 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)
|
||||
616
addons/mc_quests/lua/mqs/core/cl_hud.lua
Normal file
616
addons/mc_quests/lua/mqs/core/cl_hud.lua
Normal 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
|
||||
1310
addons/mc_quests/lua/mqs/core/cl_panels.lua
Normal file
1310
addons/mc_quests/lua/mqs/core/cl_panels.lua
Normal file
File diff suppressed because it is too large
Load Diff
143
addons/mc_quests/lua/mqs/core/cl_util.lua
Normal file
143
addons/mc_quests/lua/mqs/core/cl_util.lua
Normal 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
|
||||
617
addons/mc_quests/lua/mqs/core/sh_init.lua
Normal file
617
addons/mc_quests/lua/mqs/core/sh_init.lua
Normal 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,
|
||||
}
|
||||
254
addons/mc_quests/lua/mqs/core/sh_player.lua
Normal file
254
addons/mc_quests/lua/mqs/core/sh_player.lua
Normal 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
|
||||
106
addons/mc_quests/lua/mqs/core/sh_util.lua
Normal file
106
addons/mc_quests/lua/mqs/core/sh_util.lua
Normal 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
|
||||
92
addons/mc_quests/lua/mqs/core/sv_db.lua
Normal file
92
addons/mc_quests/lua/mqs/core/sv_db.lua
Normal 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
|
||||
684
addons/mc_quests/lua/mqs/core/sv_init.lua
Normal file
684
addons/mc_quests/lua/mqs/core/sv_init.lua
Normal 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)
|
||||
-- Не понятно что это, используйте на свой страх и риск
|
||||
242
addons/mc_quests/lua/mqs/core/sv_player.lua
Normal file
242
addons/mc_quests/lua/mqs/core/sv_player.lua
Normal 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)
|
||||
196
addons/mc_quests/lua/mqs/sh_config.lua
Normal file
196
addons/mc_quests/lua/mqs/sh_config.lua
Normal 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
|
||||
1824
addons/mc_quests/lua/mqs/ui/editor_panel.lua
Normal file
1824
addons/mc_quests/lua/mqs/ui/editor_panel.lua
Normal file
File diff suppressed because it is too large
Load Diff
239
addons/mc_quests/lua/mqs/ui/npc_menu.lua
Normal file
239
addons/mc_quests/lua/mqs/ui/npc_menu.lua
Normal 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)
|
||||
112
addons/mc_quests/lua/mqs/ui/user_panel.lua
Normal file
112
addons/mc_quests/lua/mqs/ui/user_panel.lua
Normal 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
|
||||
Reference in New Issue
Block a user