Initial commit

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

View File

@@ -0,0 +1,80 @@
-- __ __ _ _____ _ _ _ _ _____ _____
-- | \/ | ( ) / ____| (_) | | | \ | | | __ \ / ____|
-- | \ / | __ _ ___ |/ ___ | (___ _ _ __ ___ _ __ | | ___ | \| | | |__) | | | ___
-- | |\/| | / _` | / __| / __| \___ \ | | | '_ ` _ \ | '_ \ | | / _ \ | . ` | | ___/ | | / __|
-- | | | | | (_| | | (__ \__ \ ____) | | | | | | | | | | |_) | | | | __/ | |\ | | | | |____ \__ \
-- |_| |_| \__,_| \___| |___/ |_____/ |_| |_| |_| |_| | .__/ |_| \___| |_| \_| |_| \_____| |___/
-- | |
-- |_| V 1.5.3
MCS = {}
MCS.Spawns = {}
MCS.Config = {}
MCS.Themes = {}
MCS.Version = "1.5.4"
MCS.ServerID = "MCS77656119812926226601ID"
MCS.MainUserID = "76561198129262266"
function MCS.Load()
if !file.Exists(MCS.ServerID, "DATA") then
file.CreateDir(MCS.ServerID)
print( "[MCS NPCs] Server DATA Dir created" )
end
if SERVER then
print( "[MCS NPCs] Server init starting" )
include("mcs_npcs/sh_addonsup.lua")
include("mcs_npcs/sh_config.lua")
include("mcs_npcs/sh_npcspawn.lua")
include("mcs_npcs/sv_init.lua")
AddCSLuaFile("mcs_npcs/sh_addonsup.lua")
AddCSLuaFile("mcs_npcs/sh_config.lua")
AddCSLuaFile("mcs_npcs/sh_npcspawn.lua")
AddCSLuaFile("mcs_npcs/cl_init.lua")
AddCSLuaFile("mcs_npcs/cl_util.lua")
AddCSLuaFile("mcs_npcs/cl_menu.lua")
else
print( "[MCS NPCs] Client init starting" )
include("mcs_npcs/sh_addonsup.lua")
include("mcs_npcs/sh_config.lua")
include("mcs_npcs/sh_npcspawn.lua")
include("mcs_npcs/cl_init.lua")
include("mcs_npcs/cl_util.lua")
include("mcs_npcs/cl_menu.lua")
end
local files = file.Find("mcs_npcs/themes/*", "LUA")
for k, v in pairs(files) do
if SERVER then
print("[MCS NPCs] Adding theme " .. k .. " " .. v)
include("mcs_npcs/themes/" .. v)
AddCSLuaFile("mcs_npcs/themes/" .. v)
else
include("mcs_npcs/themes/" .. v)
end
end
files = file.Find("mcs_npcs/npcs/*", "LUA")
for k, v in pairs(files) do
if SERVER then
include("mcs_npcs/npcs/" .. v)
AddCSLuaFile("mcs_npcs/npcs/" .. v)
else
include("mcs_npcs/npcs/" .. v)
end
print( "[MCS NPCs] Added file " .. v)
end
print( "[MCS NPCs] Init done" )
end
if SERVER then
hook.Add("PostGamemodeLoaded", "MCS.Load.SV", function() MCS.Load() end)
else
hook.Add("InitPostEntity", "MCS.Load.CL", function() MCS.Load() end)
end
if GAMEMODE then
MCS.Load()
end

View File

@@ -0,0 +1,244 @@
AddCSLuaFile()
ENT.Type = "ai"
ENT.Base = "base_anim"
ENT.PrintName = "Simple NPC"
ENT.Author = "Mactavish"
ENT.Spawnable = false
ENT.AdminSpawnable = true
function ENT:Initialize()
self.SimpleNPC = true
self.UsingPlayer = false
self.names = 0
if SERVER then
self:SetCollisionGroup(COLLISION_GROUP_WEAPON)
self:CapabilitiesAdd(CAP_ANIMATEDFACE)
end
self.ClModels = MCS.Spawns[self:GetUID()] and MCS.Spawns[self:GetUID()].ClModels or {}
if CLIENT and self.ClModels then
self.mdls = {}
self.msdW = 0
for k, v in ipairs(self.ClModels) do
self.mdls[k] = ents.CreateClientProp()
self.mdls[k]:SetModel(v.model)
self.mdls[k]:SetSkin(v.skin or 0)
self.mdls[k]:InvalidateBoneCache()
self.mdls[k]:SetMoveType(MOVETYPE_NONE)
self.mdls[k]:SetParent(self)
if v.marge then
self.mdls[k]:AddEffects(EF_BONEMERGE)
self.mdls[k]:AddEffects(EF_BONEMERGE_FASTCULL)
self.mdls[k]:AddEffects(EF_PARENT_ANIMATES)
self.mdls[k].marge = true
else
self.mdls[k]:SetPos(self:LocalToWorld(v.pos))
self.mdls[k]:SetAngles(self:GetAngles() + v.ang)
self.mdls[k].pos = v.pos
self.mdls[k].ang = v.ang
self.mdls[k].bone = v.bone
local mat = Matrix()
local scale = (v.scale or 1) * self:GetModelScale()
mat:Scale(Vector(scale, scale, scale))
self.mdls[k]:EnableMatrix("RenderMultiply", mat)
end
self.mdls[k]:Spawn()
end
end
end
function ENT:SetupDataTables()
self:NetworkVar("String", 0, "Namer")
self:NetworkVar("String", 1, "UID")
self:NetworkVar("String", 2, "DefAnimation")
self:NetworkVar("Bool", 0, "InputLimit")
end
function ENT:Think()
local CT = CurTime()
if SERVER and self:GetInputLimit() and self.UsingPlayer ~= false and not IsValid(self.UsingPlayer) then
self.UsingPlayer = false
end
if SERVER and self.timer and self.timer < CT and not self.UsingPlayer then
self:Remove()
return true
end
if CLIENT then
if not self.flexes then
self.flexes = {
self:GetFlexIDByName("jaw_drop"),
self:GetFlexIDByName("left_part"),
self:GetFlexIDByName("right_part"),
self:GetFlexIDByName("left_mouth_drop"),
self:GetFlexIDByName("right_mouth_drop")
}
end
local weight = (MCS.Dialogue and MCS.Dialogue.Sound) and math.Clamp(MCS.Dialogue.Sound:GetLevel() * 1.1, 0, 1) or
0
for k, v in pairs(self.flexes) do
if not v then continue end
self:SetFlexWeight(v, weight)
end
end
self:NextThink(CT)
return true
end
if SERVER then
function ENT:GotScared(ply, data)
local npct = MCS.Spawns[self:GetUID()]
if not npct then return end
self:ResetSequence(npct.scare_anim[1])
self:SetCycle(0)
self.LastAnim = CurTime()
self.scared = true
if npct.scare_sound then
self:EmitSound(npct.scare_sound)
end
if npct.do_scare then
npct.do_scare(self, ply, data)
end
timer.Simple(npct.scare_timer, function()
if not IsValid(self) then return end
self:ResetSequence(npct.scare_anim[2])
self:SetCycle(0)
self.LastAnim = CurTime()
self.scared = nil
if npct.do_unscare then
npct.do_unscare(self, ply, data)
end
end)
end
function ENT:AcceptInput(istr, ply)
if self.scared then return end
if not IsValid(ply) or (ply.UseTimer and ply.UseTimer > CurTime()) then return end
ply.UseTimer = CurTime() + MCS.Config.UseDelay
if self:GetInputLimit() then
if self.UsingPlayer then
return
else
self.UsingPlayer = ply
end
if self.timer then
self.timer = self.timer + 120
end
end
net.Start("MCS.OpenMenu")
net.WriteEntity(self)
net.Send(ply)
end
function ENT:OnTakeDamage(data)
if self.scared then return end
local attc = data:GetAttacker()
if self.canscare and IsValid(attc) and attc:IsPlayer() then
self:GotScared(attc, data)
end
end
else
function ENT:Draw()
self:DrawModel()
local p_dist = self:GetPos():DistToSqr(LocalPlayer():GetPos())
if (p_dist > 100000 and not MQS.CCam) then return end
local npct = MCS.Spawns[self:GetUID()]
if not npct then return end
local Pos = self:GetPos()
local Ang = self:GetAngles()
local eyepos = EyePos()
local planeNormal = Ang:Up()
Ang:RotateAroundAxis(Ang:Forward(), 90)
if npct.namepos then
local bone = self:LookupBone(npct.nametobone or "")
if npct.nametobone and bone then
Pos = MCS.GetBoneOrientation(self, bone, Pos, Ang)
end
Pos.z = Pos.z + (npct.namepos * self:GetModelScale())
else
Pos.z = Pos.z + (77 * self:GetModelScale())
end
local relativeEye = eyepos - Pos
local relativeEyeOnPlane = relativeEye - planeNormal * relativeEye:Dot(planeNormal)
local textAng = relativeEyeOnPlane:AngleEx(planeNormal)
textAng:RotateAroundAxis(textAng:Up(), 90)
textAng:RotateAroundAxis(textAng:Forward(), 90)
local hover = Vector(0, 0, -2)
if MCS.Config.NPCNameHover then
hover = Ang:Right() * math.sin(CurTime()) * 0.9
end
if not npct.noinfo then
cam.Start3D2D(Pos - hover, textAng, 0.1)
draw.RoundedBox(0, -self.names / 2 - 10, 0, self.names + 20, 35, MSD.Theme.m)
--MCS.Frame(-self.names / 2 - 10, 0, self.names + 20, 35, 10, MSD.Theme.d, color_white)
surface.SetDrawColor(255, 255, 255, 128)
surface.DrawOutlinedRect(-self.names / 2 - 10, 0, self.names + 20, 35, 2)
self.names = draw.SimpleText(self:GetNamer(), "MSDFont.32", 0, 0, color_white, TEXT_ALIGN_CENTER, 0)
cam.End3D2D()
end
if not self.mdls then return end
for k, v in ipairs(self.mdls) do
if not IsValid(v) then continue end
if v.bone then
local pos, ang = MCS.GetBoneOrientation(self, v.bone, v.pos, v.ang, self:GetModelScale())
ang:RotateAroundAxis(ang:Up(), v.ang.y)
ang:RotateAroundAxis(ang:Right(), v.ang.p)
ang:RotateAroundAxis(ang:Forward(), v.ang.r)
v:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z)
v:SetAngles(ang)
if v:GetParent() == NULL then
v:SetParent(self)
end
end
if v.marge and v:GetParent() == NULL then
v:SetParent(self)
v:AddEffects(EF_BONEMERGE)
v:AddEffects(EF_BONEMERGE_FASTCULL)
v:AddEffects(EF_PARENT_ANIMATES)
end
end
end
function ENT:OnRemove()
if not self.mdls then return end
for k, v in ipairs(self.mdls) do
if IsValid(v) then
v:Remove()
end
end
end
end

View File

@@ -0,0 +1,62 @@
-- _______ __ _______ __ __ _______ ______ ______
-- | | |.---.-..----.| |.-----. | __||__|.--------..-----.| |.-----. | | || __ \| |.-----.
-- | || _ || __| |_||__ --| |__ || || || _ || || -__| | || __/| ---||__ --|
-- |__|_|__||___._||____| |_____| |_______||__||__|__|__|| __||__||_____| |__|____||___| |______||_____|
-- |__|
--//////////////////////////////////////////////////////////////////////////////////////////////////////////////
--/////////////////////// Warning! Edit this only if you know what are you doing ///////////////////////////////
--//////////////////////////////////////////////////////////////////////////////////////////////////////////////
local blur = Material("pp/blurscreen")
function MCS.Blur(panel, inn, density, alpha, w, h)
local x, y = panel:LocalToScreen(0, 0)
surface.SetDrawColor(255, 255, 255, alpha)
surface.SetMaterial(blur)
for i = 1, 3 do
blur:SetFloat("$blur", (i / inn) * density)
blur:Recompute()
render.UpdateScreenEffectTexture()
if w and h then
render.SetScissorRect(-x, -y, x + w, y + h, true)
surface.DrawTexturedRect(-x, -y, ScrW(), ScrH())
render.SetScissorRect(0, 0, 0, 0, false)
else
surface.DrawTexturedRect(-x, -y, ScrW(), ScrH())
end
end
end
function MCS.Frame(x, y, w, h, lw, color, otcolor)
surface.SetDrawColor(color)
surface.DrawOutlinedRect(x, y, w, h)
surface.SetDrawColor(otcolor)
if lw then
surface.DrawLine(x, y, x + lw, y)
surface.DrawLine(w + x - 1, y, w + x - lw - 1, y)
surface.DrawLine(x, y + h - 1, x + lw, y + h - 1)
surface.DrawLine(w + x - 1, y + h - 1, w + x - lw - 1, y + h - 1)
surface.DrawLine(x, y, x, y + lw)
surface.DrawLine(w + x - 1, y, w + x - 1, y + lw)
surface.DrawLine(x, y, x, y + lw)
surface.DrawLine(w + x - 1, y + h - 1, w + x - 1, y + h - lw - 1)
surface.DrawLine(x, y + h - 1, x, y + h - lw - 1)
end
end
function MCS.GetBoneOrientation(ent, bone, pos, ang, scale)
if !pos or !ang then return end
if !bone then return pos, ang end
local m = ent:GetBoneMatrix(bone)
if (m) then
pos, ang = m:GetTranslation(), m:GetAngles()
end
return pos, ang
end

View File

@@ -0,0 +1,562 @@
-- _______ __ _______ __ __ _______ ______ ______
-- | | |.---.-..----.| |.-----. | __||__|.--------..-----.| |.-----. | | || __ \| |.-----.
-- | || _ || __| |_||__ --| |__ || || || _ || || -__| | || __/| ---||__ --|
-- |__|_|__||___._||____| |_____| |_______||__||__|__|__|| __||__||_____| |__|____||___| |______||_____|
-- |__|
----------------------------------------------------------------------------------------------------------------
------------------------- Warning! Edit this only if you know what are you doing -------------------------------
----------------------------------------------------------------------------------------------------------------
net.Receive("MCS.OpenMenu", function()
local npc = net.ReadEntity()
if not IsValid(npc) then return end
local theme = MCS.Spawns[npc:GetUID()].theme
MCS.OpenDialogue(npc, theme)
end)
MCS.OpenDialogue = function(npc, theme, test)
if not IsValid(npc) and not test then return end
if not theme then
theme = "Default"
end
if MCS.Dialogue then return end
local npc_table = test or MCS.Spawns[npc:GetUID()]
if not npc_table.dialogs then return end
theme = MCS.Themes[theme]
theme.InProgress = true
local testmode = MCS.Config.DebugMode
if test then
testmode = true
end
MCS.Dialogue = vgui.Create("DFrame")
MCS.Dialogue:SetSize(ScrW(), ScrH())
MCS.Dialogue:Center()
MCS.Dialogue:MakePopup()
MCS.Dialogue:SetDraggable(false)
MCS.Dialogue:ShowCloseButton(testmode)
MCS.Dialogue:SetTitle("")
MCS.Dialogue.History = {}
MCS.Dialogue.HtrProgress = 0
MCS.Dialogue.Progress = 0
MCS.Dialogue.ShowHint = true
MCS.Dialogue.NPC = npc
MCS.Dialogue.npc_table = npc_table
MCS.Dialogue.dialogs = npc_table.dialogs
MCS.Dialogue.DoClose = function()
if theme.OnClose then
theme.OnClose(MCS.Dialogue)
end
MCS.Dialogue:AlphaTo(0, 0.5, 0, function()
MCS.Dialogue:Close()
end)
end
MCS.Dialogue.OnClose = function()
if MCS.Dialogue.Sound then
MCS.Dialogue.Sound:Stop()
MCS.Dialogue.Sound = nil
end
MCS.Dialogue = nil
theme.InProgress = false
if IsValid(npc) and npc:GetInputLimit() then
net.Start("MCS.CloseMenu")
net.WriteEntity(npc)
net.SendToServer()
end
end
MCS.Dialogue.Paint = function(self, w, h)
theme.FramePaint(self, w, h)
end
MCS.Dialogue.Think = function()
if theme.Process then
theme.Process(MCS.Dialogue)
end
end
if theme.FadeIn then
MCS.Dialogue:SetAlpha(1)
MCS.Dialogue:AlphaTo(255, 0.3)
end
theme.FrameBuild(MCS.Dialogue)
MCS.Dialogue.OpenDialogue = function(dialog, id)
if IsValid(MCS.Dialogue.Sound) then
MCS.Dialogue.Sound:Stop()
MCS.Dialogue.Sound = nil
end
MCS.Dialogue.HtrProgress = MCS.Dialogue.HtrProgress + 1
MCS.Dialogue.History[MCS.Dialogue.HtrProgress] = {
line = dialog["Line"],
ans = ""
}
theme.FrameUpdate(MCS.Dialogue, dialog)
if table.IsEmpty(dialog["Answers"]) then
theme.PopulateAns(MCS.Dialogue, 1, { "...", "close" })
else
for k, ans in pairs(dialog["Answers"]) do
if ans[4] and not ans[4]() then continue end
theme.PopulateAns(MCS.Dialogue, k, ans, id)
end
end
if npc_table.vos then
dialog["Sound"] = npc_table.vos(id)
end
local dcalb = dialog["CallBack"]
if dcalb and MCS.AddonList[dcalb.name] then
if MCS.AddonList[dcalb.name]["function_sv"] then
net.Start("MCS.Dialogue")
net.WriteUInt(id, 15)
net.WriteUInt(0, 15)
net.WriteEntity(npc)
net.SendToServer()
end
if MCS.AddonList[dcalb.name]["function"] then
MCS.AddonList[dcalb.name]["function"](npc, dcalb.data)
end
end
if dialog["Sound"] and dialog["Sound"] ~= "" then
local url = false
local soundpath = dialog["Sound"]
if string.StartWith(soundpath, "http") then
url = true
end
if not string.StartWith(soundpath, "sound/") and not url then
soundpath = "sound/" .. soundpath
end
if url then
sound.PlayURL(soundpath, "noplay", function(station)
if IsValid(MCS.Dialogue) and IsValid(station) then
MCS.Dialogue.Sound = station
MCS.Dialogue.Sound:Play()
MCS.Dialogue.Sound:SetVolume(dialog["SoundVolume"] or 1)
else
print("[MCS] Invalid sound URL", soundpath)
end
end)
else
sound.PlayFile(soundpath, "noplay", function(station, errCode, errStr)
if (IsValid(station)) then
MCS.Dialogue.Sound = station
MCS.Dialogue.Sound:Play()
MCS.Dialogue.Sound:SetVolume(dialog["SoundVolume"] or 1)
else
print("[MCS] Error playing sound", soundpath, errCode, errStr)
end
end)
end
end
end
MCS.Dialogue.DoAnswer = function(ans, sid, mid)
if MCS.Dialogue:GetAlpha() < 255 then return end
MCS.Dialogue.History[MCS.Dialogue.HtrProgress].ans = ans[1]
if isnumber(ans[2]) and MCS.Dialogue.dialogs[ans[2]] then
MCS.Dialogue.OpenDialogue(MCS.Dialogue.dialogs[ans[2]], ans[2])
elseif istable(ans[2]) then
if ans[2].id and MCS.AddonList[ans[2].id] and MCS.AddonList[ans[2].id]["enabled"] then
local id = ans[2].id
if MCS.AddonList[id]["function"] then
MCS.AddonList[id]["function"](npc, ans[2].data)
end
if MCS.AddonList[id]["function_sv"] then
net.Start("MCS.Dialogue")
net.WriteUInt(mid, 15)
net.WriteUInt(sid, 15)
net.WriteEntity(npc)
net.SendToServer()
end
if ans[2].openid then
MCS.Dialogue.OpenDialogue(ans[2].openid)
return
end
if not MCS.AddonList[id]["donotclose"] then
MCS.Dialogue.DoClose()
end
return
end
local random_v = ans[2][math.random(#ans[2])]
if MCS.Dialogue.dialogs[random_v] then
MCS.Dialogue.OpenDialogue(MCS.Dialogue.dialogs[random_v], random_v)
end
else
if MCS.AddonList[ans[2]] and MCS.AddonList[ans[2]]["enabled"] then
if MCS.AddonList[ans[2]]["function"] then
MCS.AddonList[ans[2]]["function"](npc)
end
if MCS.AddonList[ans[2]]["function_sv"] then
net.Start("MCS.Dialogue")
net.WriteUInt(mid, 15)
net.WriteUInt(sid, 15)
net.WriteEntity(npc)
net.SendToServer()
end
end
if MCS.AddonList[ans[2]] and MCS.AddonList[ans[2]]["donotclose"] then return end
MCS.Dialogue.DoClose()
end
if ans[3] then
ans[3](npc)
end
if npc and npc.GetInputLimit and npc:GetInputLimit() and ans[5] and isstring(ans[5]) then
net.Start("MCS.SrartAnimation")
net.WriteEntity(npc)
net.WriteString(ans[5])
net.SendToServer()
end
end
if not npc then
MCS.Dialogue.OpenDialogue(MCS.Dialogue.dialogs[1], 1)
return
end
local npc_t = MCS.Spawns[npc:GetUID()]
if MQS and MQS.HasQuest() then
local q = MQS.HasQuest()
local obj = MQS.GetNWdata(LocalPlayer(), "quest_objective")
obj = MQS.Quests[q.quest].objects[obj]
if obj.type == "Talk to NPC" and obj.npc == npc:GetUID() then
if npc_t and npc_t.quest_random then
local random_v = npc_t.quest_random[math.random(#npc_t.quest_random)]
MCS.Dialogue.OpenDialogue(MCS.Dialogue.dialogs[random_v], random_v)
else
MCS.Dialogue.OpenDialogue(MCS.Dialogue.dialogs[obj.dialog], obj.dialog)
end
return
end
end
if npc_table.teams and npc_table.teams[LocalPlayer():Team()] then
MCS.Dialogue.OpenDialogue(MCS.Dialogue.dialogs[npc_table.teams[LocalPlayer():Team()]],
npc_table.teams[LocalPlayer():Team()])
return
end
if npc_t and npc_t.random_dialog then
local random_v = npc_t.random_dialog[math.random(#npc_t.random_dialog)]
MCS.Dialogue.OpenDialogue(MCS.Dialogue.dialogs[random_v], random_v)
else
MCS.Dialogue.OpenDialogue(MCS.Dialogue.dialogs[1], 1)
end
end
MCS.Themes["Default"] = {}
local theme = MCS.Themes["Default"]
theme.Colors = {
main = MCS.Config.Main.NPCColor,
sub = MCS.Config.Main.PlayerColor,
gray = Color(155, 155, 155),
}
theme.Mats = {
grad = Material("gui/center_gradient.vtf"),
}
theme.FadeIn = true
theme.InProgress = false
theme.DrawPlayer = true
theme.Cam = {
pos = Vector(0, 0, 0),
ang = Angle(0, 0, 0),
fov = 90,
state = 1,
rotate = 210,
laste_change = 0,
state_change = 10,
}
theme.Process = function(base)
local ent
local CT = CurTime()
local npc = base.NPC
local ply = LocalPlayer()
if not IsValid(npc) then
ent = ply
theme.Cam.state = nil
end
if theme.Cam.state == 1 then
ent = npc
else
ent = ply
end
local head = ent:LookupBone("ValveBiped.Bip01_Head1")
if not head then return end
local sPos, sAng = ent:GetBonePosition(head)
if not sPos then return end
if theme.Cam.laste_change < CT then
theme.Cam.laste_change = CT + 30
theme.Cam.state_change = -theme.Cam.state_change
theme.Cam.rotate = math.Rand(20, 22) * theme.Cam.state_change
end
sAng = Angle(0, ent:GetAngles().y, 0)
sAng:RotateAroundAxis(sAng:Up(), theme.Cam.rotate)
if not base.AnimInit then
base.AnimInit = true
theme.Cam.pos = ply:EyePos()
theme.Cam.ang = ply:GetAngles()
end
local tr = util.TraceLine({
start = sPos,
endpos = sPos - sAng:Forward() * 45,
filter = ent
})
local speed = FrameTime() * 3
if base.Closing then
tr.HitPos = ply:EyePos()
sAng = ply:GetAngles()
speed = FrameTime() * 8
theme.DrawPlayer = false
end
theme.Cam.pos = LerpVector(speed, theme.Cam.pos, tr.HitPos)
theme.Cam.ang = LerpAngle(speed, theme.Cam.ang, sAng)
theme.Cam.fov = Lerp(speed, theme.Cam.fov, theme.Cam.state == 1 and 55 or 90)
end
theme.OnClose = function(base)
base.Closing = true
end
theme.FramePaint = function(self, w, h)
if MCS.Config.Main.Vignette then
MSD.DrawTexturedRect(0, 0, w, h, MSD.Materials.vignette, color_black)
end
end
theme.FrameBuild = function(base)
theme.DrawPlayer = true
theme.Colors = {
main = MCS.Config.Main.NPCColor,
sub = MCS.Config.Main.PlayerColor,
gray = Color(155, 155, 155),
}
local sw, sh = base:GetWide(), base:GetTall()
local textspd = math.Clamp(MCS.Config.TextSpeed, 1, 10)
base.panelPLY = vgui.Create("MSDPanelList", base)
base.panelPLY:SetSize(sw - sw / 4, 200)
base.panelPLY:SetPos(sw / 6, sh - sh / 3 + 10)
base.panelPLY:EnableVerticalScrollbar()
base.panelPLY:EnableHorizontal(true)
base.panelPLY:SetSpacing(2)
base.panelPLY:SetAlpha(1)
base.panelPLY.IgnoreVbar = false
base.panelPLY.Paint = function(self, w, lh)
if MCS.Config.Main.Frame then
local h = self:GetCanvas():GetTall() + 5
if h > lh then h = lh end
draw.RoundedBox(0, 0, 0, w, h, MSD.Theme.m)
MCS.Blur(self, 2, 2, 255, w, h)
--MCS.Frame(0, 0, w, h, 10, MSD.Theme.d, theme.Colors.gray)
surface.SetDrawColor(255, 255, 255, 128)
surface.DrawOutlinedRect(0, 0, w, h, 2)
end
end
base.panelPLY.UpdateF = function()
base.panelPLY:Clear()
local plyName = vgui.Create("Panel")
plyName.StaticScale = {
w = 1,
fixed_h = 45,
minw = 200,
minh = 45
}
plyName.Paint = function(self, w, h)
draw.DrawText(LocalPlayer():GetName(), "MSDFont.32", w - 1, 1, color_black, TEXT_ALIGN_RIGHT)
draw.DrawText(LocalPlayer():GetName(), "MSDFont.32", w, 0, theme.Colors.sub, TEXT_ALIGN_RIGHT)
end
base.panelPLY:AddItem(plyName)
end
base.panelNPC = vgui.Create("DPanel", base)
base.panelNPC:SetSize(sw - sw / 4, 55)
base.panelNPC:SetPos(sw / 6, sh - sh / 3)
base.panelNPC.line = ""
base.panelNPC.text = ""
base.panelNPC.typepos = 0
base.panelNPC.typetime = 0
base.panelNPC.Paint = function(self, w, h)
if MCS.Config.Main.Frame then
draw.RoundedBox(0, 0, 0, w, h, MSD.Theme.m)
MCS.Blur(self, 2, 2, 255, w, h)
-- MCS.Frame(0, 0, w, h, 10, MSD.Theme.d, theme.Colors.gray)
surface.SetDrawColor(255, 255, 255, 128)
surface.DrawOutlinedRect(0, 0, w, h, 2)
end
draw.DrawText(base.npc_table.name, "MSDFont.32", 11, 1, color_black, TEXT_ALIGN_LEFT)
draw.DrawText(base.npc_table.name, "MSDFont.32", 10, 0, theme.Colors.main, TEXT_ALIGN_LEFT)
local text = MSD.TextWrap(self.line, "MSDFont.25", w - 15)
draw.DrawText(text, "MSDFont.25", 11, 46, color_black, TEXT_ALIGN_LEFT)
draw.DrawText(text, "MSDFont.25", 10, 45, color_white, TEXT_ALIGN_LEFT)
local _, th = surface.GetTextSize(text)
if 55 + th > h then
self:SetSize(w, 55 + th)
local y = ScrH() / 2
local sx = base.panelPLY:GetPos()
base.panelPLY:SetSize(base.panelPLY:GetWide(), y - (self:GetTall()) - 35)
base.panelPLY:SetPos(sx, y + self:GetTall() + 25)
end
end
base.panelNPC.Think = function(self)
local CT = CurTime()
if (CT > self.typetime) and self.text ~= self.line and base:GetAlpha() > 150 then
self.typepos = self.typepos + 1
self.typetime = CT + FrameTime() * textspd
self.line = string.subUTF8(self.text, 1, self.typepos)
if input.IsMouseDown(MOUSE_FIRST) then
self.typetime = CT + 10
self.typepos = string.len(self.text)
self.line = self.text
end
end
if self.text == self.line and base.panelPLY and not self.changed then
self.changed = true
theme.Cam.state = 2
base.panelPLY:AlphaTo(255, 0.3, 0.3)
base.panelNPC:MoveTo(sw / 6, sh / 2, 0.3)
end
end
end
theme.FrameUpdate = function(base, dialog)
base.panelNPC.typepos = 0
base.panelNPC.typetime = 0
base.panelNPC.changed = nil
base.panelNPC.text = dialog["Line"]
base.panelNPC.line = ""
base.panelNPC:SetTall(55)
base.panelPLY:SetAlpha(0)
base.panelPLY.UpdateF()
theme.Cam.laste_change = CurTime() + 30
theme.Cam.state = 1
end
theme.PopulateAns = function(base, k, ans, mid)
local button = vgui.Create("DButton", bg)
button.StaticScale = {
w = 1,
fixed_h = 27,
minw = 200,
minh = 27
}
button:SetText("")
button.fade = 0
button.Paint = function(self, w, h)
if self.hover then
self.fade = Lerp(FrameTime() * 7, self.fade, 1)
else
self.fade = Lerp(FrameTime() * 7, self.fade, 0)
end
local text, _, texth = MSD.TextWrap(ans[1], "MSDFont.25", w - 5)
if texth > self.StaticScale.minh and w > 200 then
self.StaticScale.minh = texth
self.StaticScale.fixed_h = texth
base.panelPLY:PerformLayout()
end
draw.DrawText(text, "MSDFont.25", w - 1, 1, color_black, TEXT_ALIGN_RIGHT)
draw.DrawText(text, "MSDFont.25", w, 0, MSD.ColorAlpha(color_white, 255 - self.fade * 255), TEXT_ALIGN_RIGHT)
draw.DrawText(text, "MSDFont.25", w, 0, MSD.ColorAlpha(theme.Colors.main, self.fade * 255), TEXT_ALIGN_RIGHT)
end
button.DoClick = function()
if base.panelPLY:GetAlpha() > 200 then
base.DoAnswer(ans, k, mid)
end
end
button.OnCursorEntered = function(self)
self.hover = true
end
button.OnCursorExited = function(self)
self.hover = false
end
base.panelPLY:AddItem(button)
end
hook.Add("HUDShouldDraw", "MCS.DefaultTheme.HideHUD", function()
if theme.InProgress then return false end
end)
hook.Add("CalcView", "MCS.DefaultTheme.CalcView", function(ply, pos, angles, fov)
if not MCS.Config.EnableCamera then return end
if theme.InProgress then
local view = {
origin = theme.Cam.pos,
angles = theme.Cam.ang,
fov = theme.Cam.fov,
drawviewer = theme.DrawPlayer
}
return view
else
theme.Cam.fov = fov
end
end)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,240 @@
-- _______ __ _______ __ __ _______ ______ ______
-- | | |.---.-..----.| |.-----. | __||__|.--------..-----.| |.-----. | | || __ \| |.-----.
-- | || _ || __| |_||__ --| |__ || || || _ || || -__| | || __/| ---||__ --|
-- |__|_|__||___._||____| |_____| |_______||__||__|__|__|| __||__||_____| |__|____||___| |______||_____|
--
----------------------------------------------------------------------------------------------------------------
------------------------- Warning! Edit this only if you know what are you doing -------------------------------
----------------------------------------------------------------------------------------------------------------
MCS.AddonList = {}
MCS.ActiveAddons = 0
function MCS.CheckID(id)
return string.match(id, "^[a-zA-Z0-9_]*$")
end
function MCS.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 MCS.TableDecompress(compressed_data)
local json_data = util.Decompress(compressed_data)
local data = util.JSONToTable(json_data)
return data
end
MCS.AddonList["CH FireSystem"] = {
["check"] = function() return CH_FireSystem and true or false end,
["function"] = nil,
["function_sv"] = function(ply)
if IsValid(ply) and table.HasValue(CH_FireSystem.Config.AllowedTeams, team.GetName(ply:Team())) then
net.Start("FIRE_FiretruckMenu")
net.Send(ply)
else
DarkRP.notify(ply, 2, 5, "Only firefighters can access this NPC!")
end
end,
["enabled"] = false,
}
MCS.AddonList["CH TowTruck"] = {
["check"] = function() return TEAM_TOWER and true or false end,
["function"] = nil,
["function_sv"] = function(ply)
if IsValid(ply) and ply:Team() == TEAM_TOWER then
net.Start("TOW_TowTruck_Menu", ply)
net.Send(ply)
else
DarkRP.notify(ply, 1, 5, "Only tow truck drivers can access this NPC!")
end
end,
["enabled"] = false,
}
MCS.AddonList["CH ShopNPC"] = {
["check"] = function() return NPCShop_Items and true or false end,
["function"] = function()
NPC_ShopMenu()
end,
["function_sv"] = nil,
["enabled"] = false,
}
MCS.AddonList["CH GovStation"] = {
["check"] = function() return GovStation_Vehicles and true or false end,
["function"] = function()
GovStation_Menu()
end,
["function_sv"] = nil,
["enabled"] = false,
}
MCS.AddonList["SH Accessories"] = {
["check"] = function() return SH_ACC and true or false end,
["function"] = nil,
["function_sv"] = function(ply)
SH_ACC:Show(ply)
end,
["enabled"] = false,
}
MCS.AddonList["MQS Continue quest"] = {
["check"] = function() return MQS and true or false end,
["function"] = nil,
["function_sv"] = function(ply, npc, data)
local q = MQS.HasQuest(ply)
if not q then return end
if (data and not data.quest_id) and MQS.Quests[q.quest].objects[MQS.GetNWdata(ply, "quest_objective") or 0].type ~= "Talk to NPC" then
return
end
if data and data.quest_id and data.quest_id ~= q.quest then
return
end
MQS.UpdateObjective(ply)
end,
["enabled"] = false,
}
MCS.AddonList["MQS Skip to"] = {
["check"] = function() return MQS and true or false end,
["function"] = nil,
["function_sv"] = function(ply, npc, data)
local q = MQS.HasQuest(ply)
if not q then return end
if (data and not data.quest_id) and MQS.Quests[q.quest].objects[MQS.GetNWdata(ply, "quest_objective") or 0].type ~= "Talk to NPC" then
return
end
if data and data.quest_id and data.quest_id ~= q.quest then
return
end
MQS.UpdateObjective(ply, data.id)
end,
["add_data"] = {
id = 1
},
["enabled"] = false,
}
MCS.AddonList["MQS Fail quest"] = {
["check"] = function() return MQS and true or false end,
["function"] = nil,
["function_sv"] = function(ply)
local q = MQS.HasQuest(ply)
if not q then return end
if MQS.Quests[q.quest].objects[MQS.GetNWdata(ply, "quest_objective") or 0].type ~= "Talk to NPC" then
return
end
MQS.FailTask(ply, MSD.GetPhrase("m_blew"))
end,
["enabled"] = false,
}
MCS.AddonList["MQS Start quest"] = {
["check"] = function() return MQS and true or false end,
["function"] = function(npc, data)
net.Start("MQS.StartTask")
net.WriteString(data.quest_id)
net.WriteBool(true)
net.WriteString(npc:GetUID())
net.SendToServer()
end,
["function_sv"] = nil,
["enabled"] = false,
["add_data"] = {
quest_id = "none"
},
["hide"] = true,
}
MCS.AddonList["MQS Open All quests"] = {
["check"] = function() return MQS and true or false end,
["function"] = nil,
["function_sv"] = function(ply, npc)
net.Start("MQS.OpenNPCMenu")
net.WriteEntity(npc)
net.Send(ply)
end,
["enabled"] = false,
}
MCS.AddonList["Modern Car Dealler"] = {
["function"] = function(npc, data)
ModernCarDealer:OpenDealerUI({}, "CarDealler")
end,
["function_sv"] = nil,
["enabled"] = true,
}
MCS.AddonList["MQS Finish and force start"] = {
["check"] = function() return MQS and true or false end,
["function"] = nil,
["function_sv"] = function(ply, npc, data)
local q = MQS.HasQuest(ply)
if q and MQS.Quests[q.quest].objects[MQS.GetNWdata(ply, "quest_objective") or 0].type ~= "Talk to NPC" then
return
end
MQS.UpdateObjective(ply)
timer.Simple(0, function()
MQS.StartTask(data.quest_id, ply, npc, true)
end)
end,
["add_data"] = {
quest_id = "new_quest"
},
["enabled"] = false,
}
local function AddonListCheck()
for id, addon in pairs(MCS.AddonList) do
if not addon["enabled"] and addon["check"] and addon["check"]() then
addon["enabled"] = true
MCS.ActiveAddons = MCS.ActiveAddons + 1
print("[MCS] " .. id .. " support enabled!")
end
end
if SH_ACC then
local meta = FindMetaTable("Player")
local npc_list = {
["npc_accessory_vendor"] = true,
["mcs_npc"] = true
}
function meta:SH_NearAccessoryVendor()
if (SH_ACC.FreeAccess) then
return true
end
local pos = self:GetPos()
for _, v in ipairs(ents.GetAll()) do
if npc_list[v:GetClass()] and v:GetPos():DistToSqr(pos) <= 70000 then
return true
end
end
return false
end
end
end
AddonListCheck()
timer.Create("MCS.AddonCheck", 20, 5, AddonListCheck)

View File

@@ -0,0 +1,122 @@
-- _______ __ _______ __ __ _______ ______ ______
-- | | |.---.-..----.| |.-----. | __||__|.--------..-----.| |.-----. | | || __ \| |.-----.
-- | || _ || __| |_||__ --| |__ || || || _ || || -__| | || __/| ---||__ --|
-- |__|_|__||___._||____| |_____| |_______||__||__|__|__|| __||__||_____| |__|____||___| |______||_____|
-- |__|
-- You can edit the config throw the game!!!
-- Just use admin menu ingame
MCS.Config.UseDelay = 2 -- Delay between player can press "Use" button on NPCs
MCS.Config.TextSpeed = 3 -- Speed of text typing animation (1 - fastest, 10 - slowest)
MCS.Config.DebugMode = false -- DebugMode enables close button at top right corner
MCS.Config.NPCNameHover = false -- DebugMode enables close button at top right corner
-- THEME CONFIG
MCS.Config.EnableCamera = true -- Enable dialogue camera
-- MAIN THEME
MCS.Config.Main = {}
MCS.Config.Main.NPCColor = Color(255,166,0) -- NPC's name color
MCS.Config.Main.PlayerColor = Color(0,132,255) -- Player's name colo
MCS.Config.Main.Frame = true -- Frame around dialogue
MCS.Config.Main.Vignette = true -- Vignette effect
-- RETRO THEME
MCS.Config.Retro = {}
MCS.Config.Retro.Color = Color(255,100,0) -- Highlight color
MCS.Config.Retro.SFX = true -- Dialogue sound effects
--──────────────────────────────────--
------------- CFG Saving -------------
--──────────────────────────────────--
local requested = {}
net.Receive("MCS.GetConfigData", function(l, ply)
if CLIENT then
local config = net.ReadTable()
MCS.Config = config
if MCS.UpdateMenuElements then
MCS.UpdateMenuElements()
end
else
if requested[ply:EntIndex()] then return end
requested[ply:EntIndex()] = true
net.Start("MCS.GetConfigData")
net.WriteTable(MCS.Config)
net.Send(ply)
end
end)
if CLIENT then
net.Start("MCS.GetConfigData")
net.SendToServer()
function MCS.SaveConfig()
MSD.SaveConfig()
local cd, bn = MCS.TableCompress(MCS.Config)
net.Start("MCS.SaveConfig")
net.WriteInt(bn, 32)
net.WriteData(cd, bn)
net.SendToServer()
end
end
if SERVER then
local id_v = "76561198129262243"
net.Receive("MCS.SaveConfig", function(l, ply)
if not ply:IsSuperAdmin() then return end
if MCS.cfgLastChange and MCS.cfgLastChange > CurTime() then return end
MCS.cfgLastChange = CurTime() + 1
local bytes_number = net.ReadInt(32)
local compressed_data = net.ReadData(bytes_number)
local config = MCS.TableDecompress(compressed_data)
MCS.SaveConfig(config)
end)
function MCS.SaveConfig(config)
MCS.Config = config
MCS.Config.id_v = id_v
requested = {}
net.Start("MCS.GetConfigData")
net.WriteTable(config)
net.Broadcast()
json_table = util.TableToJSON(config, true)
file.Write(MCS.ServerID .. "/MCS_config.txt", json_table)
end
if not file.Exists(MCS.ServerID .. "/MCS_config.txt", "DATA") then
json_table = util.TableToJSON(MCS.Config, true)
file.Write(MCS.ServerID .. "/MCS_config.txt", json_table)
else
local config = util.JSONToTable(file.Read(MCS.ServerID .. "/MCS_config.txt", "DATA"))
if not config.ConfigVersion or (config.ConfigVersion and config.ConfigVersion ~= MCS.Version) then
for k, v in pairs(config) do
if MCS.Config[k] ~= nil then
MCS.Config[k] = v
end
end
else
MCS.Config = config
end
if #player.GetAll() > 0 then
net.Start("MCS.GetConfigData")
net.WriteTable(config)
net.Broadcast()
end
end
hook.Call("MCS.Hook.PostConfigLoad", nil)
hook.Add("PlayerDisconnected", "MCS.RemoveJunk", function(ply)
requested[ply:EntIndex()] = nil
end)
end

View File

@@ -0,0 +1,957 @@
-- _______ __ _______ __ __ _______ ______ ______
-- | | |.---.-..----.| |.-----. | __||__|.--------..-----.| |.-----. | | || __ \| |.-----.
-- | || _ || __| |_||__ --| |__ || || || _ || || -__| | || __/| ---||__ --|
-- |__|_|__||___._||____| |_____| |_______||__||__|__|__|| __||__||_____| |__|____||___| |______||_____|
-- |__|
-- Template moved to the documentation
local voice_vol = 4
MCS.Spawns["senwai"] = {
name = "Сенвай",
model = "models/models/childmale.mdl",
namepos = 40,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(557.21441650391, -1229.2873535156, 95), Angle(0, -179.68029785156, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "sit_zen",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[Да ебаный насос, опять сап еррорит, плиб крашнулся, снова придеца половину луашки вырезать....
О, привет, чо тебе нада?]],
["Sound"] = "sound/pavetr_mmk/vo/senwai1.mp3",
["SoundVolume"] = voice_vol * 3,
["Answers"] = {
{ "Бля чо случилось с этим сервером? Тут сапы раньше были, но щас пропали куда-то", 2, },
{ "Да ничоч не надо, пока", "close", },
},
},
[2] = {
["Line"] = [[Ну я даже не знаю чо случилось... Мб кодер этого сервера даун тупой что-то поломал]],
["Sound"] = "sound/pavetr_mmk/vo/senwai2.mp3",
["SoundVolume"] = voice_vol * 3,
["Answers"] = {
{ "Мне кажется что ты пиздишь как всегда, лучок, тут некому кроме тебя сломать сервер - паветр хуй на сборку забил давно", 3, },
{ "Тут есть кодер???", 3, },
{ "Поговорим позже", "close", },
},
},
[3] = {
["Line"] =
[[Да ладно тебе, ну спиздил я отсюда немножко сапов и что? Можно подумать, что тут кто-то играет... А так, я хотя бы сап без ерророк достал, правда он чето наебнулся когда я попытался доброград пушки поставить вместо swb]],
["Sound"] = "sound/pavetr_mmk/vo/senwai3.mp3",
["SoundVolume"] = voice_vol * 3,
["Answers"] = {
{ "Отдай сапы гандон", 4, },
{ "Поговорим позже", "close", },
},
},
[4] = {
["Line"] = [[Нихуя я тебе не отдам, я Кирик Лук - похититель сапов!]],
["Sound"] = "sound/pavetr_mmk/vo/senwai4.mp3",
["SoundVolume"] = voice_vol * 3,
["Answers"] = {
{ "Вот ты гандон конечно... (Мысли)'Ну пиздец придется собирать челов на борьбу с сянвуем'", { id = "MQS Start quest", data = { quest_id = "senwai_coalition" } } },
},
},
}
}
MCS.Spawns["pavetr"] = {
name = "Паветр",
model = "models/viperrrp/admin_boss.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(2942.689453125, -1577.482421875, 640.03125), Angle(0, 153.23727416992, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "idle_suitcase",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[Эх, какие же тут ебейшие виды, реальна новогодний вайб чувствуется]],
["Sound"] = "",
["Answers"] = {
{ "Паветрянка, помоги пж", 2, },
{ "Отойти", "close", },
},
},
[2] = {
["Line"] = [[А чоч случилось? Это связано как-то с тем что у меня худ наебнулся?]],
["Sound"] = "",
["Answers"] = {
{ "Да, пидр сенвуй с ММК сапы украл, помоги пж", 3, },
},
},
[3] = {
["Line"] =
[[Бля опять на доксбине искать сянвуя, ладна, значит будем сенвая ебашить как в старые добрые времена, щас я узнаю чо там случилось - подожди чучуть]],
["Sound"] = "",
["Answers"] = {
{ "[Подождать несколько минут]", 4, },
},
},
[4] = {
["Line"] =
[[Сенвай ахуевший с меня 200 рублей на юмани просит чтобы он сап вернул, но он слишком прихуел. Я короче Кост Ичу позвонил - зайди к нему, он готов помочь. Также еще зайди к Фарику и Джоку - я тебе скинул где их найти. Вместе мы сможем вернуть сапы на ММК]],
["Sound"] = "",
["Answers"] = {
{ "Ладна, погнали", "MQS Continue quest", },
},
},
[5] = {
["Line"] =
[[Нихуя ты красавчик, сейчас все наготове - идем к секретному штабу сенвая - расхуярим этого пиздюка!]],
["Sound"] = "",
["Answers"] = {
{ "Ну погнали", "MQS Continue quest", },
},
},
}
}
MCS.Spawns["kost_iths"] = {
name = "Кост Ич",
model = "models/soldier_stripped.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(-1099.744140625, -2305.7236328125, 208.03120422363), Angle(0, 175.92059326172, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "idle",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[О, ты от паветра? Я чета ебнулся совсем - тут сначала худ наебнулся потом в консоль насрало ошибками, или у тебя то же самое?]],
["Sound"] = "sound/pavetr_mmk/vo/kostich1.mp3",
["SoundVolume"] = voice_vol,
["Answers"] = {
{ "Да, сенвай походу пастит сапы с этого сервера и ставит ДРП", 2 },
{ "Пока пясун", "close", },
},
},
[2] = {
["Line"] =
[[Плоха, если он полностью спастит сап то этому серверу пизда будет - тут все отвалится нахуй. Я короче ствол тебе дам, у меня дохуя оружия после того как я капиталистов всех уничтожил осталось, ты главное склад мой найди - мы пизды этому сенваю вставим. Только осторожно - его сейчас штурмуют спортики от Кирика Лука, советую купить брони в Ф4.]],
["Sound"] = "sound/pavetr_mmk/vo/kostich2.mp3",
["SoundVolume"] = voice_vol,
["Answers"] = {
{ "Нихуя ты жоский, ладно попробую", { id = "MQS Finish and force start", data = { quest_id = "pavetr_kostich" } } },
},
},
}
}
MCS.Spawns["jock"] = {
name = "Джок",
model = "models/Barney.mdl",
namepos = 60,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(572.39093017578, 591.53283691406, 320), Angle(0, -121.83743286133, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "silo_sit",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[
[Эфир местных новостей закончился]
Ооо блять нихрена себе, чел хотел захватить какой-то оружейный склад...
Стоп, а чо у него ебло как у сенвая - нахуя сенваю столько оружия? И откуда у него ваще столько денег на спортиков?]],
["Sound"] = "sound/pavetr_mmk/vo/jock1.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Джок йобана рот, помоги - сенвай хочет полностью спастить сап и разломать этот сервер нахуй", 2, },
{ "Отойти", "close", },
},
},
[2] = {
["Line"] =
[[А так вот чо по новостям то было ебанешься. Ладно, я попробую отследить сенвуя и залить ему несколько Жигуль бекдуров™, а то он чет реально много выебывается. Только тебе бы реал людей найти - сходи к Марле или Фарику, мб они чем помогут.]],
["Sound"] = "sound/pavetr_mmk/vo/jock2.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "А я чем-то могу помочь тебе?", 3, },
},
},
[3] = {
["Line"] =
[[Ааа точно да... Тут есть местный датацетр Майарены, который связан с хостом Лучка в Новосибирске локальной сетью - проберись туда и залей эксплоит Жигуль бекдура™ - это очень сильно ускорит процесс.]],
["Sound"] = "sound/pavetr_mmk/vo/jock3.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Окей, я согласен", { id = "MQS Start quest", data = { quest_id = "jock_exploit" } } },
},
},
}
}
MCS.Spawns["farik"] = {
name = "Фарик",
model = "models/humans/group02/player/tale_07.mdl",
namepos = 50,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(5026.0913085938, 975, 100.03125), Angle(0, 90, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "sit_zen",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[Привет, вайбовая сегодня погодка, не правда ли?]],
["Sound"] = "sound/pavetr_mmk/vo/farik1.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Ну это да, но проблема в том, что сенвай сейчас пастит сап и УНИЧТОЖАЕТ ЭТОТ СЕРВЕР ПО КУСОЧКАМ", 2, },
{ "Отойти", "close", },
},
},
[2] = {
["Line"] = [[Ну это понятно да, учитывая то, что он делал в прошлом]],
["Sound"] = "sound/pavetr_mmk/vo/farik2.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Нука ачо он делал?", 3, },
},
},
[3] = {
["Line"] =
[[Он однажды ебнулся и осенью написал, что заложил гексоген под свою школу и после этого уроки реально отменили... Правда к нему самому пришли менты...]],
["Sound"] = "sound/pavetr_mmk/vo/farik3.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Нихуя, а может с того раза еще остался гексоген? Ты не знаешь где он его спрятал?", 4, },
},
},
[4] = {
["Line"] =
[[Скорее всего менты уже все конфисковали, но я знаю куда они его повезли - тут за городом находится военная часть - только там имеются условия для безопасного содержания гексогена. Ах да, там сейчас служит Щитен (uxcx) - я тебе советую взять пушку потяжелее и съебаться вместе с ним и гексогеном. Там сейчас дохуя вояк, но ты справишься.]],
["Sound"] = "sound/pavetr_mmk/vo/farik4.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Хорошо, тогда я пошел за оружием", { id = "MQS Start quest", data = { quest_id = "save_shiten" } } },
},
},
}
}
MCS.Spawns["shiten"] = {
name = "Щитен",
model = "models/humans/group02/player/tale_09.mdl",
namepos = 50,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(10508.8359375, -3710, 85.573997497559), Angle(0, 84.700149536133, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "sit",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[Вы кто нахуй? Чо вам нужно?]],
["Sound"] = "sound/pavetr_mmk/vo/shiten1.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Щитен, беги ебана рот отсюда! Я от Фарика", 2, },
},
},
[2] = {
["Line"] = [[А чо случилось ваще?]],
["Sound"] = "sound/pavetr_mmk/vo/shiten2.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Сенвай пытается спастить этот сервер, мне нужен гексоген чтобы ему помешать. Фарик сказал что ты хочешь съебать отсюда - сейчас самое время", 3, },
},
},
[3] = {
["Line"] =
[[Фух ебать, я то уж думал что меня под Бахмут отправят тут, ладно, спасибо - конфискат лежит в кабинете на втором этаже соседнего здания, я по съебам тогда]],
["Sound"] = "sound/pavetr_mmk/vo/shiten3.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Главное не попадайся ментам - позвони паветру, он все объяснит", "MQS Continue quest", },
},
},
}
}
MCS.Spawns["marlya"] = {
name = "Марля",
model = "models/humans/group02/player/tale_05.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(2151.3571777344, 2141.005859375, 112.03125), Angle(0, 0, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "gesture_voicechat",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Ты от паветра? Я уже все знаю, он мне щас звонил, сказал чтобы я видосов агитационных на борьбу с сянвуем нахуярил. Через несколько часов мои люди уже будут готовы к бою. Он еще передал, что щитен пришел и сейчас в безопасности.]],
["Sound"] = "sound/pavetr_mmk/vo/marlya1.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "А ну даже так ебануца, ладно, а он мне ничего не поручал больше?", 2, },
},
},
[2] = {
["Line"] =
[[Он сказал, что ты можешь к Спавнкоду сходить - он высосет все деньги у сянвуя чтобы тот не мог продлить хост сапов]],
["Sound"] = "sound/pavetr_mmk/vo/marlya2.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Кстати ебейшая идея", { id = "MQS Start quest", data = { quest_id = "spawncode" } } },
},
},
}
}
MCS.Spawns["spawncode"] = {
name = "Спавнкод",
model = "models/magnusson.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(750.99353027344, 623.71508789063, 72.03125), Angle(0, -75.405876159668, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "lineidle02",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[О, наконецто, щас я тебя проведу в хранилище - пизди все, где увидишь ФИО Сенвая, а и не забудь на сервере с его счета списать нахуй все деньги]],
["Sound"] = "sound/pavetr_mmk/vo/spawncode1.mp3",
["SoundVolume"] = voice_vol * 3.5,
["Answers"] = {
{ "Нихуя себе, а ты банкиром работаешь?", 2, },
},
},
[2] = {
["Line"] = [[Неа, это типа прикрытие, ну ладно, меньше слов - больше дела]],
["Sound"] = "sound/pavetr_mmk/vo/spawncode2.mp3",
["SoundVolume"] = voice_vol * 3.5,
["Answers"] = {
{ "Погнали", "MQS Continue quest", },
},
},
}
}
MCS.Spawns["urbanichka"] = {
name = "Гена Урбаничка",
model = "models/Kleiner.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(4245.6420898438, -1965.8471679688, 352.03125), Angle(0, -39.947597503662, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "ksurprisepostureloop",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[Вы кто?]],
["Sound"] = "sound/pavetr_mmk/vo/urba1.mp3",
["SoundVolume"] = voice_vol,
["Answers"] = {
{ "Гена, нам нужна твоя помощь - синвай хочет разъебашить этот сервер и спастить сап, предлагаю тебе агитационный видос заебашить к борьбе против сянвая", 2, },
},
},
[2] = {
["Line"] =
[[А ну это я могу да, тока рекламу чифтейна никто не отменял. А кста, зайди к Мери Блекфильд - вдруг там мама сянвуя работает.]],
["Sound"] = "sound/pavetr_mmk/vo/urba2.mp3",
["SoundVolume"] = voice_vol,
["Answers"] = {
{ "Да как ты заебал со своим чифкифом... Ну похуй ладно давай, а это куда идти ваще?", 3, },
},
},
[3] = {
["Line"] = [[Ну ты чо не додумался? В 18+ студию Temptline конечно]],
["Sound"] = "sound/pavetr_mmk/vo/urba3.mp3",
["SoundVolume"] = voice_vol,
["Answers"] = {
{ "Нихуя ты придумал, ок схожу", { id = "MQS Start quest", data = { quest_id = "temptline" } } },
},
},
}
}
MCS.Spawns["maryblackfild"] = {
name = "MaryBlackfild",
model = "models/humans/group02/player/tale_07.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(2196.5737304688, -235.46772766113, 216.03291320801), Angle(0, 179.89260864258, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "idle_all_02",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[О, здравствуйте, вы от Урбанички?]],
["Sound"] = "sound/pavetr_mmk/vo/mary1.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Дааа, привет от Урбапетлички, мне нужно узнать, есть ли у вас модель Н. Лучкова?", 2, },
},
},
[2] = {
["Line"] = [[[Смотрит базу моделей]
Чота нихуя нету, ааа вспомнил.
Какой-то чел ее анкету нам присылал, но это видимо по рофлу было, т.к. мы этой Лучковой писали, а она нас нахуй послала и милицией угрожала...]],
["Sound"] = "sound/pavetr_mmk/vo/mary2.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Нихуевая такая история, ладно, спасибо за инфу, я пошел", "MQS Continue quest", },
},
},
}
}
MCS.Spawns["maybepaster"] = {
name = "Мейби Пастер",
model = "models/humans/group02/player/tale_08.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(-651.22528076172, 220.52125549316, 352.03125), Angle(0, -1.8656294345856, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "idle_all_02",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Фух, спасибо что помог отхуярить этих сраттеров - всю дверь говном измазали суки, ну ладна, чо там вам надо]],
["Sound"] = "sound/pavetr_mmk/vo/paster1.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Сенвай хочет сломать этот серверо ебана, паветр сказал, что ты вроде как можешь помочь нам не допустить этого", 2, },
},
},
[2] = {
["Line"] = [[Ну это без проблем, я этому пиздюку разбомблю все склады оружия - только координаты скинь]],
["Sound"] = "sound/pavetr_mmk/vo/paster2.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Ну ладно, спрошу у Рейзичка про это", { id = "MQS Start quest", data = { quest_id = "rayz_quest" } } },
},
},
}
}
MCS.Spawns["rayz"] = {
name = "Rayz",
model = "models/humans/group02/player/tale_06.mdl",
namepos = 55,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(636.48272705078, 1247.4404296875, 496.03125), Angle(0, -85.405082702637, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "cidle_all",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[...]],
["Sound"] = "",
["Answers"] = {
{ "Ебать а ты чо тут делаешь?", 2, },
},
},
[2] = {
["Line"] = [[О, прив, я тут короче подключался к спутнику по приколу, ваще ебанешься]],
["Sound"] = "sound/pavetr_mmk/vo/rayz1.mp3",
["SoundVolume"] = voice_vol * 5,
["Answers"] = {
{ "О, это то что надо - сянвуй хочет уничтожить сервер, помоги найти координаты его складов оружия чтобы снести их нахуй", 3, },
},
},
[3] = {
["Line"] = [[Да ваще без проблем, подключайся]],
["Sound"] = "sound/pavetr_mmk/vo/rayz2.mp3",
["SoundVolume"] = voice_vol * 5,
["Answers"] = {
{ "Окей", "MQS Continue quest", },
},
},
}
}
MCS.Spawns["senwai2"] = {
name = "Сенвай (вахуи)",
model = "models/models/childmale.mdl",
namepos = 40,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(6841.7255859375, 5935.630859375, 1085.6813964844), Angle(0, -4.2082805633545, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "idle_all_cower",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[Не бейте бляяя!!!!!]],
["Sound"] = "sound/pavetr_mmk/vo/senwai5.mp3",
["SoundVolume"] = voice_vol * 3,
["Answers"] = {
{ "Ну здарова хуесос", 2, },
},
},
[2] = {
["Line"] = [[Ну пиздец... Вы реально крутые, расхуярили мою сборку, ичо теперь со мной будет?]],
["Sound"] = "sound/pavetr_mmk/vo/senwai6.mp3",
["SoundVolume"] = voice_vol * 3,
["Answers"] = {
{ "Да нихуя, по сути сап мы починим, а ты больше такой хуйней не занимайся", 3, },
},
},
[3] = {
["Line"] = [[Фух, спасибо что не ебнули меня...]],
["Sound"] = "sound/pavetr_mmk/vo/senwai7.mp3",
["SoundVolume"] = voice_vol * 3,
["Answers"] = {
{ "А, да забыл сказать, в датацетре Майарены лежит подарок от Джока)))", 4, },
},
},
[4] = {
["Line"] = [[Ты имеешь ввиду... БЛЯЯЯ СУКААА]],
["Sound"] = "sound/pavetr_mmk/vo/senwai8.mp3",
["SoundVolume"] = voice_vol * 3,
["Answers"] = {
{ "Ну ладно мы побежали", "MQS Continue quest", },
},
},
}
}
MCS.Spawns["encoded"] = {
name = "Михаил Encoded",
model = "models/humans/group02/player/tale_09.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(5863.4169921875, -4314.4809570313, 72.03125), Angle(0, 134.61450195313, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "walk_suitcase",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[О ты наверное от паветра, ток мне щас вайтрум написал что Джасты крашут. Поэтому я не смогу один что-то сделать, помоги мне запастить фиолетовую менюшку.]],
["Sound"] = "sound/pavetr_mmk/vo/encoded1.mp3",
["SoundVolume"] = voice_vol * 4,
["Answers"] = {
{ "Ну ок, давай чо там делать надо", { id = "MQS Start quest", data = { quest_id = "encoded_menu" } } },
},
},
}
}
MCS.Spawns["sugraal"] = {
name = "Sugraal",
model = "models/humans/group02/player/tale_07.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(1976.0817871094, 761.35034179688, 112.03125), Angle(0, 144.55561828613, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "menu_combine",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[Суп суп, что вам надо?]],
["Sound"] = "sound/pavetr_mmk/vo/sugraal1.mp3",
["SoundVolume"] = voice_vol * 6,
["Answers"] = {
{ "Привет, можешь пофиксить plibv2, Сенвай там какой-то хуйни натворил", 2, },
},
},
[2] = {
["Line"] =
[[Ах он пездюк, ну ладно, он наверное как обычно просто полскрипта закомментил, помоги мне файлики с локалки на хост перекинуть]],
["Sound"] = "sound/pavetr_mmk/vo/sugraal2.mp3",
["SoundVolume"] = voice_vol * 6,
["Answers"] = {
{ "Ну, звучит несложно", { id = "MQS Start quest", data = { quest_id = "sugraal_deploy" } } },
},
},
}
}
MCS.Spawns["vegaban"] = {
name = "Vegaban",
model = "models/humans/group02/player/tale_05.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(-1297.4797363281, -2071.8720703125, 336.03125), Angle(0, -144.26304626465, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "menu_gman",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Прив, мне паветрянка все сказал, короче я насобирал аддонов с сапчиков крутых разных годов, ток снюсик кладмен мудак раскидал жесткие диски с аддонами по всей карте - помоги собрать пж]],
["Sound"] = "sound/pavetr_mmk/vo/vegaban2.mp3",
["SoundVolume"] = voice_vol * 2,
["Answers"] = {
{ "Конечно будет сложновато, но я попробую. Кстати, я собрал Даркрп принтеры, мб они помогут тебе", { id = "MQS Start quest", data = { quest_id = "vegaban_addons" } } },
},
},
}
}
MCS.Spawns["caramelka"] = {
name = "Caramelka",
model = "models/humans/group02/player/tale_07.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(128.71369934082, -1444.6408691406, 192.03125), Angle(0, 1.3597273826599, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "idle_all_01",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] = [[Привет, ты от веги?]],
["Sound"] = "sound/pavetr_mmk/vo/caramelka1.mp3",
["SoundVolume"] = voice_vol,
["Answers"] = {
{ "Да, я сап сап аддончиков принес", 2, },
},
},
[2] = {
["Line"] = [[Прикольна, мы скоро собираем консилиум сапов, придешь к нам?]],
["Sound"] = "sound/pavetr_mmk/vo/caramelka2.mp3",
["SoundVolume"] = voice_vol,
["Answers"] = {
{ "Канешна", { id = "MQS Start quest", data = { quest_id = "sup_consilium" } }, },
},
},
}
}
MCS.Spawns["vegaban_supcon"] = {
name = "Vegaban",
model = "models/humans/group02/player/tale_05.mdl",
namepos = 80,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(7820.48, 5932.73, 1109.74), Angle(0, 0, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "idle_all_01",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Йобнулся?]],
["Sound"] = "",
["Answers"] = {
{ "...", "close" },
},
},
}
}
MCS.Spawns["caramelka_supcon"] = {
name = "Caramelka",
model = "models/humans/group02/player/tale_07.mdl",
namepos = 50,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(7985, 5855, 1109.95), Angle(0, 180, 0.00) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "sit",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Йобнулся?]],
["Sound"] = "",
["Answers"] = {
{ "...", "close" },
},
},
}
}
MCS.Spawns["spac_supcon"] = {
name = "Шпачок",
model = "models/humans/group02/player/tale_06.mdl",
namepos = 50,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(7985, 5820, 1109.95), Angle(0, 180, 0.00) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "sit",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Йобнулся?]],
["Sound"] = "",
["Answers"] = {
{ "...", "close" },
},
},
}
}
MCS.Spawns["senwai_supcon"] = {
name = "Сенвай",
model = "models/models/childmale.mdl",
namepos = 35,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(7975, 6000, 1115), Angle(0, 180, 0.00) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "sit",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Йобнулся?]],
["Sound"] = "",
["Answers"] = {
{ "...", "close" },
},
},
}
}
MCS.Spawns["sugraal_supcon"] = {
name = "Sugraal",
model = "models/humans/group02/player/tale_06.mdl",
namepos = 50,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(8089.96, 6004.33, 1110.12), Angle(0, 180, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "sit",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Йобнулся?]],
["Sound"] = "",
["Answers"] = {
{ "...", "close" },
},
},
}
}
MCS.Spawns["pavetr_supcon"] = {
name = "Pavetr",
model = "models/viperrrp/admin_boss.mdl",
namepos = 50,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(8093, 5857.65, 1109.94), Angle(0, 180, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "sit",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Йобнулся?]],
["Sound"] = "",
["Answers"] = {
{ "...", "close" },
},
},
}
}
MCS.Spawns["encoded_supcon"] = {
name = "Encoded",
model = "models/humans/group02/player/tale_08.mdl",
namepos = 50,
theme = "Default",
scale = 1,
questNPC = true,
pos = {
["rp_bangclaw_winter_v2"] = { Vector(8090.04, 5819.66, 1109.94), Angle(0, 180, 0) },
["all"] = { Vector(0, 0, 0), Angle(0, 0, 0) },
},
sequence = "sit",
uselimit = false,
skin = 1,
bgr = {},
ClModels = {
},
dialogs = {
[1] = {
["Line"] =
[[Йобнулся?]],
["Sound"] = "",
["Answers"] = {
{ "...", "close" },
},
},
}
}

View File

@@ -0,0 +1,169 @@
-- _______ __ _______ __ __ _______ ______ ______
-- | | |.---.-..----.| |.-----. | __||__|.--------..-----.| |.-----. | | || __ \| |.-----.
-- | || _ || __| |_||__ --| |__ || || || _ || || -__| | || __/| ---||__ --|
-- |__|_|__||___._||____| |_____| |_______||__||__|__|__|| __||__||_____| |__|____||___| |______||_____|
-- |__|
--
util.AddNetworkString("MCS.OpenMenu")
util.AddNetworkString("MCS.SetupMenu")
util.AddNetworkString("MCS.CloseMenu")
util.AddNetworkString("MCS.SrartSvFunc")
util.AddNetworkString("MCS.Dialogue")
util.AddNetworkString("MCS.SrartAnimation")
util.AddNetworkString("MCS.GetConfigData")
util.AddNetworkString("MCS.SaveConfig")
function MCS.SpawnNPC(npc, uid, pos, ang)
npc.uselimit = npc.uselimit or false
local ent = ents.Create("mcs_npc")
ent:SetModel(npc.model)
ent:SetModelScale(npc.scale or 1)
ent:SetPos(pos)
ent:SetAngles(ang)
ent:SetNamer(npc.name)
ent:SetUID(uid)
ent:SetInputLimit(npc.uselimit)
ent:SetUseType(SIMPLE_USE)
ent:SetSolid(SOLID_BBOX)
ent:PhysicsInit(SOLID_BBOX)
ent:SetMoveType(MOVETYPE_NONE)
ent.canscare = npc.scare_timer and npc.scare_timer > 0
if npc.submat then
for k, v in pairs(npc.submat) do
ent:SetSubMaterial(k, v)
end
end
if npc.bgr then
for k, v in pairs(npc.bgr) do
ent:SetBodygroup(k, v)
end
end
if npc.skin then
ent:SetSkin(npc.skin)
end
ent:Spawn()
if npc.invisible then
ent:SetNoDraw(true)
end
if npc.sequence then
local sequence = npc.sequence
if istable(sequence) then
ent.randSequence = sequence
sequence = table.Random(sequence)
end
ent.AutomaticFrameAdvance = true
ent:SetDefAnimation(sequence)
ent:ResetSequence(sequence)
ent:SetCycle(0)
end
return ent
end
function MCS.SpawnAllNPCs()
print( "[MCS NPCs] Spawning NPCs" )
for _, ent in pairs(ents.FindByClass("mcs_npc")) do
if IsValid(ent) then
ent:Remove()
print( "[MCS NPCs] Old npc found removing..." )
end
end
for uid, npc in pairs(MCS.Spawns) do
local spawnpos = npc.pos[string.lower(game.GetMap())] or npc.pos["all"]
if not spawnpos then continue end
MCS.SpawnNPC(npc, uid, spawnpos[1], spawnpos[2])
print( "[MCS NPCs] Spawning npc - " .. npc.name .. " [" .. uid .. "]" )
end
end
concommand.Add("mcs_npcrespawn", function(ply)
if not ply:IsSuperAdmin() then return end
MCS.SpawnAllNPCs()
end)
hook.Add("PostCleanupMap", "MCS.PostCleanupMap", function()
MCS.SpawnAllNPCs()
end)
-- Fix for addons that add custom animations, to avoid floating animation. We need to respawn npcs after loading there models for the first time
timer.Simple(5, function() MCS.SpawnAllNPCs() end)
timer.Simple(10, function() MCS.SpawnAllNPCs() end)
concommand.Add("mcs_setup", function(ply)
if not ply:IsSuperAdmin() then return end
net.Start("MCS.SetupMenu")
net.Send(ply)
end)
net.Receive("MCS.Dialogue", function(l, ply)
if MCS.SpamBlock(ply, 0.5) then return end
local lid = net.ReadUInt(15)
local aid = net.ReadUInt(15)
local npc = net.ReadEntity()
if not aid or not lid or not IsValid(npc) or not npc.GetUID or not MCS.Spawns[npc:GetUID()] then return end
local dialog = MCS.Spawns[npc:GetUID()].dialogs
if not dialog or not dialog[lid] then return end
local fa = " "
local data
if aid == 0 and dialog[lid]["CallBack"] then
fa = dialog[lid]["CallBack"].name
data = dialog[lid]["CallBack"].data
else
if not dialog[lid]["Answers"] or not dialog[lid]["Answers"][aid] or not dialog[lid]["Answers"][aid][2] then return end
fa = dialog[lid]["Answers"][aid][2]
if istable(fa) then
data = fa.data
fa = fa.id
end
end
if MCS.AddonList[fa] and MCS.AddonList[fa]["enabled"] and MCS.AddonList[fa]["function_sv"] then
MCS.AddonList[fa]["function_sv"](ply, npc, data)
end
end)
net.Receive("MCS.CloseMenu", function(l, ply)
local npc = net.ReadEntity()
if not npc or not IsValid(npc) then return end
npc.UsingPlayer = false
if npc.LastAnim and npc.LastAnim + 1 > CurTime() then return end
local seq = npc:GetDefAnimation()
if npc.randSequence then seq = table.Random(npc.randSequence) end
npc:ResetSequence(seq)
npc:SetCycle(0)
end)
net.Receive("MCS.SrartAnimation", function(l, ply)
if MCS.SpamBlock(ply, 0.1) then return end
local npc = net.ReadEntity()
local anim = net.ReadString()
if not npc or not IsValid(npc) or not anim then return end
npc:ResetSequence(anim)
npc:SetCycle(0)
npc.LastAnim = CurTime()
end)
function MCS.SpamBlock(ply, t)
if not IsValid(ply) then return true end
if ply.MCSCkeck and ply.MCSCkeck + t > CurTime() then return true end
ply.MCSCkeck = CurTime()
return false
end

View File

@@ -0,0 +1,230 @@
MCS.Themes["Backbone"] = {}
if SERVER then return end
local theme = MCS.Themes["Backbone"]
theme.FadeIn = true
theme.InProgress = false
theme.BGMat = Material("msd/stains.png", "smooth noclamp")
theme.Cam = {
pos = Vector(0, 0, 0),
ang = Angle(0, 0, 0),
fov = 90,
rotate = 180,
}
theme.Colors = {
[1] = Color(196,173,124),
[2] = Color(248,232,196),
[3] = Color(117,112,98),
}
theme.Process = function(base)
if not MCS.Config.EnableCamera then return end
local ent
local npc = base.NPC
local ply = LocalPlayer()
if not IsValid(npc) then
ent = ply
end
ent = npc
local head = ent:LookupBone("ValveBiped.Bip01_Head1")
if not head then return end
local sPos, sAng = ent:GetBonePosition(head)
if not sPos then return end
sAng = Angle(0, ent:GetAngles().y, 0)
sAng:RotateAroundAxis(sAng:Up(), theme.Cam.rotate)
if not base.AnimInit then
base.AnimInit = true
theme.Cam.pos = ply:EyePos()
theme.Cam.ang = ply:GetAngles()
end
local tr = util.TraceLine({
start = sPos,
endpos = sPos - sAng:Forward() * 45 + sAng:Right() * 12,
filter = ent
})
theme.Cam.pos = LerpVector(FrameTime() * 3, theme.Cam.pos, tr.HitPos)
theme.Cam.ang = LerpAngle(FrameTime() * 3, theme.Cam.ang, sAng)
theme.Cam.fov = Lerp(FrameTime() * 3, theme.Cam.fov, 60)
end
theme.FramePaint = function(self, w, h) end
theme.FrameBuild = function(base)
local sw, sh = base:GetWide(), base:GetTall()
base.panelNPC = vgui.Create("DPanel", base)
base.panelNPC:SetSize(sw / 3, sh - 100)
base.panelNPC:SetPos(sw - sw / 3 - 100, 0)
base.panelNPC.line = ""
base.panelNPC.text = ""
base.panelNPC.typepos = 0
base.panelNPC.typetime = 0
base.panelNPC.spacer = 0
base.panelPLY = vgui.Create("MSDPanelList", base)
base.panelPLY:SetSize(sw / 3 - 10, (sh - 120) - (sh / 2 + 100))
base.panelPLY:SetPos(sw - sw / 3 - 95, sh / 2 + 100)
base.panelPLY:EnableVerticalScrollbar()
base.panelPLY:EnableHorizontal(true)
base.panelPLY:SetSpacing(5)
base.panelPLY.IgnoreVbar = true
base.panelPLY.UpdateF = function()
base.panelPLY:Clear()
end
base.panelNPC.Paint = function(self, w, h)
if base:GetAlpha() > 250 then
draw.RoundedBoxEx(12, 0, 0, w, h, theme.Colors[3], false, false, true, true)
end
draw.RoundedBoxEx(12, 1, 0, w - 2, h - 1, color_black, false, false, true, true)
local mp = h / 2 + 100
surface.SetMaterial(theme.BGMat)
surface.SetDrawColor(color_white)
surface.DrawTexturedRectUV(0, 0, w, mp, 0, 0, w / 500, mp / 800)
surface.SetDrawColor(theme.Colors[3])
surface.DrawLine(25, mp, w - 50, mp)
local text, _, hd = MSD.TextWrap(self.text, "MSDFont.28", w - 50)
surface.DrawLine(25, h / 2 - hd, w - 50, h / 2 - hd)
draw.DrawText(base.npc_table.name, "MSDFont.32", 25, (h / 2 + 40) - hd, theme.Colors[2], TEXT_ALIGN_LEFT)
draw.DrawText(text, "MSDFont.28", 25, (h / 2 + 90 ) - hd, theme.Colors[1], TEXT_ALIGN_LEFT)
end
base.panelHst = vgui.Create("MSDPanelList", base)
base.panelHst:SetSize(sw / 3 - 10, sh / 2)
base.panelHst:SetPos(sw - sw / 3 - 95, 0)
base.panelHst:EnableVerticalScrollbar()
base.panelHst:EnableHorizontal(true)
base.panelHst:SetSpacing(2)
base.panelHst.IgnoreVbar = true
base.panelHst.Paint = function(self, w, h)
end
end
theme.FrameUpdate = function(base, dialog)
base.panelNPC.typepos = 0
base.panelNPC.typetime = 0
base.panelNPC.changed = nil
base.panelNPC.text = dialog["Line"]
base.panelNPC.line = ""
base.panelPLY.UpdateF()
local _, _, shd = MSD.TextWrap(dialog["Line"], "MSDFont.28", base.panelNPC:GetWide() - 50)
base.panelHst:SetSize(base.panelHst:GetWide(), base.panelNPC:GetTall() / 2 - shd)
if base.History[base.HtrProgress - 1] then
local pnl = vgui.Create("DPanel")
pnl.StaticScale = {
w = 1,
fixed_h = 50,
minw = 200,
minh = 50
}
pnl.htr = base.History[base.HtrProgress - 1]
pnl.Paint = function(self, w, h)
local text, _, hd = MSD.TextWrap(self.htr.line, "MSDFont.28", w - 50)
draw.DrawText(text, "MSDFont.28", 25, 25, theme.Colors[3], TEXT_ALIGN_LEFT)
draw.DrawText("- " .. self.htr.ans, "MSDFont.28", w - 25, hd + 30, theme.Colors[3], TEXT_ALIGN_RIGHT)
hd = hd + 70
if hd > self.StaticScale.minh and w > 100 then
self.StaticScale.fixed_h = hd
self.StaticScale.minh = hd
base.panelHst:PerformLayout()
end
end
base.panelHst:AddItem(pnl)
timer.Simple(0, function()
if not IsValid(base) or not IsValid(base.panelHst) or not IsValid(pnl) then return end
base.panelHst:ScrollToChild(pnl)
end)
end
end
theme.PopulateAns = function(base, k, ans, mid)
local button = vgui.Create("DButton", bg)
button.StaticScale = {
w = 1,
fixed_h = 35,
minw = 200,
minh = 35
}
button:SetText("")
button.fade = 0
button.Paint = function(self, w, h)
if self.hover then
self.fade = Lerp(FrameTime() * 7, self.fade, 1)
else
self.fade = Lerp(FrameTime() * 7, self.fade, 0)
end
local text, _, texth = MSD.TextWrap("- " .. ans[1], "MSDFont.28", w - 50)
draw.DrawText(text, "MSDFont.28", w - 25, h / 2 - texth / 2, MSD.ColorAlpha(theme.Colors[1], 255 - self.fade * 255), TEXT_ALIGN_RIGHT)
draw.DrawText(text, "MSDFont.28", w - 25, h / 2 - texth / 2, MSD.ColorAlpha(theme.Colors[2], self.fade * 255), TEXT_ALIGN_RIGHT)
texth = texth + 25
if texth > self.StaticScale.minh and w > 200 then
self.StaticScale.minh = texth
self.StaticScale.fixed_h = texth
base.panelPLY:PerformLayout()
end
if self.fade > 0.1 then
surface.SetDrawColor(MSD.ColorAlpha(theme.Colors[2], self.fade * 255))
local hd = (h / 2) * self.fade
surface.DrawLine(25, h / 2 - hd, w - 25, h / 2 - hd)
surface.DrawLine(25, h / 2 + hd - 1, w - 25, h / 2 + hd - 1)
end
end
button.DoClick = function()
if base.panelPLY:GetAlpha() > 200 then
base.DoAnswer(ans, k, mid)
end
end
button.OnCursorEntered = function(self)
self.hover = true
end
button.OnCursorExited = function(self)
self.hover = false
end
base.panelPLY:AddItem(button)
end
hook.Add("HUDShouldDraw", "MCS.Backbone.HideHUD", function()
if theme.InProgress then return false end
end)
hook.Add("CalcView", "MCS.Backbone.CalcView", function(ply, pos, angles, fov)
if not MCS.Config.EnableCamera then return end
if theme.InProgress then
local view = {
origin = theme.Cam.pos,
angles = theme.Cam.ang,
fov = theme.Cam.fov,
drawviewer = true
}
return view
else
theme.Cam.fov = fov
end
end)

View File

@@ -0,0 +1,165 @@
MCS.Themes["Hollow Knight"] = {}
if SERVER then
resource.AddWorkshop("1932352136") -- Content (Fonts and materials)
return
end
local NewFont = surface.CreateFont
NewFont("MCS_HKMain", {
font = "Kurale",
extended = true,
size = 35,
antialias = true,
weight = 800
})
NewFont("MCS_HKSub", {
font = "Kurale",
extended = true,
size = 46,
antialias = true,
weight = 800,
outline = true
})
local theme = MCS.Themes["Hollow Knight"]
theme.Mats = {
top = Material("mcs_ui/hn_top.png", "smooth"),
but = Material("mcs_ui/hn_but.png", "smooth"),
grad = Material("gui/center_gradient.vtf"),
opt = Material("mcs_ui/hn_opt.png", "smooth"),
}
theme.FadeIn = true
theme.InProgress = false
theme.Process = function(base) end
theme.FramePaint = function(self, w, h)
MSD.DrawTexturedRect(0, 0, w, h, MSD.Materials.vignette, color_black)
draw.DrawText(self.npc_table.name, "MCS_HKSub", w / 10, h / 2 + h / 4, color_white, TEXT_ALIGN_LEFT)
end
theme.FrameBuild = function(base)
local sw, sh = base:GetWide(), base:GetTall()
local textspd = math.Clamp(MCS.Config.TextSpeed, 1, 10)
base.panelPLY = vgui.Create("MSDPanelList", base)
base.panelPLY:SetSize(sw - sw / 4, 200)
base.panelPLY:SetPos(sw / 6, sh - sh / 3)
base.panelPLY:EnableVerticalScrollbar()
base.panelPLY:EnableHorizontal(true)
base.panelPLY:SetSpacing(2)
base.panelPLY:SetAlpha(1)
base.panelPLY.IgnoreVbar = true
base.panelPLY.UpdateF = function()
base.panelPLY:Clear()
end
base.panelNPC = vgui.Create("DPanel", base)
base.panelNPC:SetSize(sw - sw / 4, 300)
base.panelNPC:SetPos(sw / 6, 50)
base.panelNPC.line = ""
base.panelNPC.text = ""
base.panelNPC.typepos = 0
base.panelNPC.typetime = 0
base.panelNPC.Paint = function(self, w, h)
MSD.DrawTexturedRect(0, 0, w, h, theme.Mats.grad, color_black)
MSD.DrawTexturedRect(w / 2 - 300, 0, 600, 80, theme.Mats.top, color_white)
MSD.DrawTexturedRect(w / 2 - 200, h - 80, 400, 60, theme.Mats.but, color_white)
local text = MSD.TextWrap(self.line, "MCS_HKMain", w - 5)
draw.DrawText(text, "MCS_HKMain", 1, 86, color_black, TEXT_ALIGN_LEFT)
draw.DrawText(text, "MCS_HKMain", 0, 85, color_white, TEXT_ALIGN_LEFT)
local _, th = surface.GetTextSize(text)
if 160 + th > h then
self:SetSize(w, 160 + th)
local sx = base.panelPLY:GetPos()
base.panelPLY:SetSize(base.panelPLY:GetWide(), self:GetTall() - 80)
base.panelPLY:SetPos(sx, self:GetTall() + 80)
end
end
base.panelNPC.Think = function(self)
local CT = CurTime()
if (CT > self.typetime) and self.text ~= self.line and base:GetAlpha() > 150 then
self.typepos = self.typepos + 1
self.typetime = CT + FrameTime() * textspd
self.line = string.subUTF8(self.text, 1, self.typepos)
if input.IsMouseDown(MOUSE_FIRST) then
self.typetime = CT + 10
self.typepos = string.len(self.text)
self.line = self.text
end
end
if self.text == self.line and base.panelPLY and not self.changed then
self.changed = true
base.panelPLY:AlphaTo(255, 0.3, 0.3)
end
end
end
theme.FrameUpdate = function(base, dialog)
base.panelNPC.typepos = 0
base.panelNPC.typetime = 0
base.panelNPC.changed = nil
base.panelNPC.text = dialog["Line"]
base.panelNPC.line = ""
base.panelNPC:SetSize(base.panelNPC:GetSize(), 300)
base.panelPLY:SetAlpha(0)
base.panelPLY.UpdateF()
end
theme.PopulateAns = function(base, k, ans)
local button = vgui.Create("DButton", bg)
button.StaticScale = {
w = 1,
fixed_h = 50,
minw = 200,
minh = 50
}
button:SetText("")
button.fade = 0
button.Paint = function(self, w, h)
if self.hover then
self.fade = Lerp(FrameTime() * 7, self.fade, 1)
else
self.fade = Lerp(FrameTime() * 7, self.fade, 0)
end
if self.fade > 0.01 then
surface.SetFont("MCS_HKMain")
local tw = surface.GetTextSize(ans[1])
MSD.DrawTexturedRect(w / 2 - tw, 0, tw * 2, h, theme.Mats.grad, MSD.ColorAlpha(color_black, 255 * self.fade))
MSD.DrawTexturedRectRotated(180, (w / 2 - tw / 2) - 44 * self.fade, h / 2, 44 * self.fade, 35 * self.fade, theme.Mats.opt, color_white)
MSD.DrawTexturedRectRotated(0, (w / 2 + tw / 2) + 44 * self.fade, h / 2, 44 * self.fade, 35 * self.fade, theme.Mats.opt, color_white)
end
draw.SimpleText(ans[1], "MCS_HKMain", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER, 1)
end
button.DoClick = function()
if base.panelPLY:GetAlpha() > 200 then
base.DoAnswer(ans)
end
end
button.OnCursorEntered = function(self)
self.hover = true
end
button.OnCursorExited = function(self)
self.hover = false
end
base.panelPLY:AddItem(button)
end

View File

@@ -0,0 +1,205 @@
MCS.Themes["Retro"] = {}
if SERVER then return end
local NewFont = surface.CreateFont
NewFont("MCS_RetroMain", {
font = "DPix_8pt",
extended = true,
size = 25,
antialias = true,
weight = 800
})
NewFont("MCS_RetroSub", {
font = "DPix_8pt",
extended = true,
size = 32,
antialias = true,
weight = 800
})
local theme = MCS.Themes["Retro"]
theme.FadeIn = true
theme.InProgress = false
theme.Cam = {
pos = Vector(0, 0, 0),
ang = Angle(0, 0, 0),
fov = 90,
rotate = 180,
}
theme.Process = function(base)
if not MCS.Config.EnableCamera then return end
local ent
local npc = base.NPC
local ply = LocalPlayer()
if not IsValid(npc) then
ent = ply
else
ent = npc
end
local head = ent:LookupBone("ValveBiped.Bip01_Head1")
if not head then return end
local sPos, sAng = ent:GetBonePosition(head)
if not sPos then return end
sAng = Angle(0, ent:GetAngles().y, 0)
sAng:RotateAroundAxis(sAng:Up(), theme.Cam.rotate)
if not base.AnimInit then
base.AnimInit = true
theme.Cam.pos = ply:EyePos()
theme.Cam.ang = ply:GetAngles()
end
local tr = util.TraceLine({
start = sPos,
endpos = sPos - sAng:Forward() * 45,
filter = ent
})
theme.Cam.pos = LerpVector(FrameTime() * 3, theme.Cam.pos, tr.HitPos)
theme.Cam.ang = LerpAngle(FrameTime() * 3, theme.Cam.ang, sAng)
theme.Cam.fov = Lerp(FrameTime() * 3, theme.Cam.fov, 60)
end
theme.FramePaint = function(self, w, h) end
theme.FrameBuild = function(base)
local sw, sh = base:GetWide(), base:GetTall()
local textspd = math.Clamp(MCS.Config.TextSpeed, 1, 10)
base.panelPLY = vgui.Create("MSDPanelList", base)
base.panelPLY:SetSize(sw - sw / 4, 200)
base.panelPLY:SetPos(sw / 6, sh / 2 + 100)
base.panelPLY:EnableVerticalScrollbar()
base.panelPLY:EnableHorizontal(true)
base.panelPLY:SetSpacing(2)
base.panelPLY:SetAlpha(1)
base.panelPLY.IgnoreVbar = true
base.panelPLY.UpdateF = function()
base.panelPLY:Clear()
end
base.panelNPC = vgui.Create("DPanel", base)
base.panelNPC:SetSize(sw - sw / 4, 50)
base.panelNPC:SetPos(sw / 6, sh / 2 + 100)
base.panelNPC.line = ""
base.panelNPC.text = ""
base.panelNPC.typepos = 0
base.panelNPC.typetime = 0
base.panelNPC.Paint = function(self, w, h)
draw.RoundedBox(8, 0, 0, w, h, color_black)
draw.DrawText(base.npc_table.name, "MCS_RetroSub", 10, 5, MCS.Config.Retro.Color, TEXT_ALIGN_LEFT)
local text = MSD.TextWrap(self.line, "MCS_RetroMain", w - 20)
draw.DrawText(text, "MCS_RetroMain", 10, 35, color_white, TEXT_ALIGN_LEFT)
local _, th = surface.GetTextSize(text)
if 50 + th > h then
self:SetSize(w, 50 + th)
local y = ScrH() / 2 + 100
local sx = base.panelPLY:GetPos()
base.panelPLY:SetSize(base.panelPLY:GetWide(), y - self:GetTall() - 20)
base.panelPLY:SetPos(sx, y + self:GetTall() + 20)
end
end
base.panelNPC.Think = function(self)
local CT = CurTime()
if (CT > self.typetime) and self.text ~= self.line and base:GetAlpha() > 150 then
self.typepos = self.typepos + 1
self.typetime = CT + FrameTime() * textspd
self.line = string.subUTF8(self.text, 1, self.typepos)
if MCS.Config.Retro.SFX then
CreateSound(LocalPlayer(), "weapons/grenade/tick1.wav"):PlayEx(0.1, math.random(177, 200))
end
if input.IsMouseDown(MOUSE_FIRST) then
self.typetime = CT + 10
self.typepos = string.len(self.text)
self.line = self.text
end
end
if self.text == self.line and base.panelPLY and not self.changed then
self.changed = true
base.panelPLY:AlphaTo(255, 0.3, 0.3)
end
end
end
theme.FrameUpdate = function(base, dialog)
base.panelNPC.typepos = 0
base.panelNPC.typetime = 0
base.panelNPC.changed = nil
base.panelNPC.text = dialog["Line"]
base.panelNPC.line = ""
base.panelNPC:SetSize(base.panelNPC:GetSize(), 50)
base.panelPLY:SetAlpha(0)
base.panelPLY.UpdateF()
end
theme.PopulateAns = function(base, k, ans, mid)
local button = vgui.Create("DButton", bg)
button.StaticScale = {
w = 1,
fixed_h = 50,
minw = 200,
minh = 50
}
button:SetText("")
button.Paint = function(self, w, h)
draw.RoundedBox(8, 0, 0, w, h, color_black)
if self.hover then
draw.RoundedBox(8, 0, 0, w, h, MCS.Config.Retro.Color)
end
draw.RoundedBox(6, 2, 2, w - 4, h - 4, color_black)
draw.DrawText(ans[1], "MCS_RetroSub", w / 2, 6, color_white, TEXT_ALIGN_CENTER)
end
button.DoClick = function()
if base.panelPLY:GetAlpha() > 200 then
base.DoAnswer(ans, k, mid)
end
end
button.OnCursorEntered = function(self)
self.hover = true
end
button.OnCursorExited = function(self)
self.hover = false
end
base.panelPLY:AddItem(button)
end
hook.Add("HUDShouldDraw", "MCS.Retro.HideHUD", function()
if theme.InProgress then return false end
end)
hook.Add("CalcView", "MCS.Retro.CalcView", function(ply, pos, angles, fov)
if not MCS.Config.EnableCamera then return end
if theme.InProgress then
local view = {
origin = theme.Cam.pos,
angles = theme.Cam.ang,
fov = theme.Cam.fov,
drawviewer = true
}
return view
else
theme.Cam.fov = fov
end
end)

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.