mirror of
https://github.com/JonnyBro/beatrun.git
synced 2024-12-30 22:03:02 +05:00
update
This commit is contained in:
parent
d80ccc84ec
commit
c1568781ec
15 changed files with 699 additions and 77 deletions
|
@ -4,7 +4,7 @@ There are lua modules ([source](https://github.com/fluffy-servers/gmod-discord-r
|
||||||
This version of the beatrun works on any version of the game (Chromium or not).
|
This version of the beatrun works on any version of the game (Chromium or not).
|
||||||
|
|
||||||
## Changes added by me
|
## Changes added by me
|
||||||
* [Custom online courses service](https://courses.beatrun.ru)! It's free 🤯! DM @Jonny_Bro#4226 for an API key.
|
* [Custom online courses database](https://courses.beatrun.ru)! It's free 🤯!
|
||||||
* Allow Overdrive usage on the server - `Beatrun_AllowOvedriveInMultiplayer`.
|
* Allow Overdrive usage on the server - `Beatrun_AllowOvedriveInMultiplayer`.
|
||||||
* Change HUD's colors - `Beatrun_HUDTextColor`, `Beatrun_HUDCornerColor`, `Beatrun_HUDFloatingXPColor`.
|
* Change HUD's colors - `Beatrun_HUDTextColor`, `Beatrun_HUDCornerColor`, `Beatrun_HUDFloatingXPColor`.
|
||||||
* Discord Rich Presence (extract `lua` folder to `garrysmod`, along side with `addons` folder).
|
* Discord Rich Presence (extract `lua` folder to `garrysmod`, along side with `addons` folder).
|
||||||
|
@ -12,8 +12,10 @@ This version of the beatrun works on any version of the game (Chromium or not).
|
||||||
* Change max moving speed - `Beatrun_MaxSpeed`.
|
* Change max moving speed - `Beatrun_MaxSpeed`.
|
||||||
* Ability to remove ziplines that created with *Zipline Gun* - RMB.
|
* Ability to remove ziplines that created with *Zipline Gun* - RMB.
|
||||||
* Removed your SteamID from right corner, because I can.
|
* Removed your SteamID from right corner, because I can.
|
||||||
|
* Allow players to spawn props without admin rights - `Beatrun_AllowPropSpawn`.
|
||||||
|
|
||||||
## Fixes from previous version
|
## Fixes from previous version
|
||||||
* Database update because Cloudflare 🤡.
|
* Fixed player collision.
|
||||||
|
* Working on a new Gamemodes menu... (currently doesn't work at all).
|
||||||
|
|
||||||
### [All changes](https://github.com/JonnyBro/beatrun/blob/master/CHANGES.md)
|
### [All changes](https://github.com/JonnyBro/beatrun/blob/master/CHANGES.md)
|
|
@ -36,7 +36,6 @@ function ENT:Initialize()
|
||||||
end
|
end
|
||||||
|
|
||||||
hook.Add("ShouldCollide", "DataCubeCollisions", function(ent1, ent2)
|
hook.Add("ShouldCollide", "DataCubeCollisions", function(ent1, ent2)
|
||||||
-- If players are about to collide with each other, then they won't collide.
|
|
||||||
if ent1.DataCube and ent2.DataCube then return false end
|
if ent1.DataCube and ent2.DataCube then return false end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@ SWEP.DrawWeaponInfoBox = false
|
||||||
|
|
||||||
SWEP.HoldType = "fist"
|
SWEP.HoldType = "fist"
|
||||||
|
|
||||||
SWEP.Spawnable = false
|
SWEP.Spawnable = true
|
||||||
SWEP.AdminSpawnable = false
|
SWEP.AdminSpawnable = true
|
||||||
|
|
||||||
|
|
||||||
--[[Just don't draw the hands, we don't need 'em]]
|
--[[Just don't draw the hands, we don't need 'em]]
|
||||||
|
|
|
@ -9,51 +9,29 @@ local gamemodePanel = {
|
||||||
|
|
||||||
gamemodePanel.x = 960 - gamemodePanel.w * 0.5
|
gamemodePanel.x = 960 - gamemodePanel.w * 0.5
|
||||||
gamemodePanel.y = 540 - gamemodePanel.h * 0.5
|
gamemodePanel.y = 540 - gamemodePanel.h * 0.5
|
||||||
|
|
||||||
local function closeButton()
|
local function closeButton()
|
||||||
AEUI:Clear()
|
AEUI:Clear()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function infectionButton()
|
local function infectionButton()
|
||||||
net.Start("Beatrun_ToggleInfection")
|
net.Start("Beatrun_ToggleGamemode")
|
||||||
|
net.WriteString("infection")
|
||||||
net.SendToServer()
|
net.SendToServer()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function datatheftButton()
|
local function datatheftButton()
|
||||||
net.Start("Beatrun_ToggleDataTheft")
|
net.Start("Beatrun_ToggleGamemode")
|
||||||
|
net.WriteString("datatheft")
|
||||||
net.SendToServer()
|
net.SendToServer()
|
||||||
end
|
end
|
||||||
|
|
||||||
local loadoutnum = 1
|
-- local function createButton()
|
||||||
local maxloadoutnum = 1
|
-- net.Start("Beatrun_CreateLoadout")
|
||||||
|
-- net.SendToServer()
|
||||||
local function createButton()
|
-- maxloadoutnum = maxloadoutnum + 1
|
||||||
net.Start("Beatrun_CreateLoadout")
|
-- LocalPlayer():EmitSound("buttonclick.wav")
|
||||||
net.SendToServer()
|
-- end
|
||||||
maxloadoutnum = maxloadoutnum + 1
|
|
||||||
LocalPlayer():EmitSound("buttonclick.wav")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function resetloadoutButton()
|
|
||||||
net.Start("Beatrun_ResetLoadouts")
|
|
||||||
net.SendToServer()
|
|
||||||
loadoutnum = 1
|
|
||||||
maxloadoutnum = 1
|
|
||||||
LocalPlayer():EmitSound("buttonclick.wav")
|
|
||||||
end
|
|
||||||
|
|
||||||
local function leftButton()
|
|
||||||
if loadoutnum ~= 1 then
|
|
||||||
loadoutnum = loadoutnum - 1
|
|
||||||
LocalPlayer():EmitSound("buttonclick.wav")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function rightButton()
|
|
||||||
if loadoutnum ~= maxloadoutnum then
|
|
||||||
loadoutnum = loadoutnum + 1
|
|
||||||
LocalPlayer():EmitSound("buttonclick.wav")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function isSA()
|
local function isSA()
|
||||||
return not LocalPlayer():IsSuperAdmin()
|
return not LocalPlayer():IsSuperAdmin()
|
||||||
|
@ -63,17 +41,17 @@ AEUI:AddText(gamemodePanel, "Gamemodes Select", "AEUIVeryLarge", 20, 30)
|
||||||
AEUI:AddButton(gamemodePanel, " X ", closeButton, "AEUILarge", gamemodePanel.w - 47, 0)
|
AEUI:AddButton(gamemodePanel, " X ", closeButton, "AEUILarge", gamemodePanel.w - 47, 0)
|
||||||
|
|
||||||
local infectionbutton = AEUI:AddButton(gamemodePanel, "Toggle Infection", infectionButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 550)
|
local infectionbutton = AEUI:AddButton(gamemodePanel, "Toggle Infection", infectionButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 550)
|
||||||
infectionbutton.greyed = isSA()
|
infectionbutton.greyed = isSA
|
||||||
local datatheftbutton = AEUI:AddButton(gamemodePanel, "Toggle Data Theft", datatheftButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 450)
|
local datatheftbutton = AEUI:AddButton(gamemodePanel, "Toggle Data Theft", datatheftButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 450)
|
||||||
datatheftbutton.greyed = isSA()
|
datatheftbutton.greyed = isSA
|
||||||
-- local loadoutbutton = AEUI:AddButton(gamemodePanel, "Create a new loadout", createButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 450)
|
-- local loadoutbutton = AEUI:AddButton(gamemodePanel, "Create a new loadout", createButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 450)
|
||||||
-- loadoutbutton.greyed = isSA()
|
-- loadoutbutton.greyed = isSA
|
||||||
-- local resetbutton = AEUI:AddButton(gamemodePanel, "Resets all loadouts", resetloadoutButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 550)
|
-- local resetbutton = AEUI:AddButton(gamemodePanel, "Resets all loadouts", resetloadoutButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 550)
|
||||||
-- resetbutton.greyed = isSA()
|
-- resetbutton.greyed = isSA
|
||||||
-- local leftloadout = AEUI:AddButton(gamemodePanel, " < ", leftButton, "AEUILarge", gamemodePanel.w - 225, gamemodePanel.h - 175)
|
-- local leftloadout = AEUI:AddButton(gamemodePanel, " < ", leftButton, "AEUILarge", gamemodePanel.w - 225, gamemodePanel.h - 175)
|
||||||
-- leftloadout.greyed = isSA()
|
-- leftloadout.greyed = isSA
|
||||||
-- local rightloadout = AEUI:AddButton(gamemodePanel, " > ", rightButton, "AEUILarge", gamemodePanel.w - 150, gamemodePanel.h - 175)
|
-- local rightloadout = AEUI:AddButton(gamemodePanel, " > ", rightButton, "AEUILarge", gamemodePanel.w - 150, gamemodePanel.h - 175)
|
||||||
-- rightloadout.greyed = isSA()
|
-- rightloadout.greyed = isSA
|
||||||
-- AEUI:AddText(gamemodePanel, "Change through loadouts", "AEUILarge", gamemodePanel.w - 360, gamemodePanel.h - 125)
|
-- AEUI:AddText(gamemodePanel, "Change through loadouts", "AEUILarge", gamemodePanel.w - 360, gamemodePanel.h - 125)
|
||||||
|
|
||||||
local weaponsList = {
|
local weaponsList = {
|
||||||
|
@ -90,19 +68,22 @@ local weaponsList = {
|
||||||
function OpenGMMenu(ply)
|
function OpenGMMenu(ply)
|
||||||
AEUI:AddPanel(gamemodePanel)
|
AEUI:AddPanel(gamemodePanel)
|
||||||
AEUI:AddPanel(weaponsList)
|
AEUI:AddPanel(weaponsList)
|
||||||
|
|
||||||
local loaded_weapons = {}
|
local loaded_weapons = {}
|
||||||
|
|
||||||
for i, _ in pairs(DATATHEFT_LOADOUTS) do
|
for i, _ in pairs(DATATHEFT_LOADOUTS) do
|
||||||
for _, v in pairs(DATATHEFT_LOADOUTS[i]) do
|
for _, v in pairs(DATATHEFT_LOADOUTS[i]) do
|
||||||
table.insert(loaded_weapons, v)
|
table.insert(loaded_weapons, v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, v in pairs(weapons.GetList()) do
|
for _, v in pairs(weapons.GetList()) do
|
||||||
if not string.find(v.ClassName:lower(), "base") then
|
if not string.find(v.ClassName:lower(), "base") then
|
||||||
local weaponentry = AEUI:AddText(weaponsList, v.ClassName, "AEUILarge", 10, 40 * #weaponsList.elements)
|
local weaponentry = AEUI:AddText(weaponsList, v.ClassName, "AEUILarge", 10, 40 * #weaponsList.elements)
|
||||||
function weaponentry:onclick()
|
function weaponentry:onclick()
|
||||||
LocalPlayer():EmitSound("buttonclick.wav")
|
LocalPlayer():EmitSound("buttonclick.wav")
|
||||||
end
|
end
|
||||||
weaponentry.greyed = isSA()
|
weaponentry.greyed = isSA
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -0,0 +1,490 @@
|
||||||
|
function CLoadout:GetWeaponIcon(class)
|
||||||
|
if file.Exists("materials/entities/" .. class .. ".png", "GAME") then return "entities/" .. class .. ".png" end
|
||||||
|
if file.Exists("materials/vgui/entities/" .. class .. ".vtf", "GAME") then return "vgui/entities/" .. class end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:UpdateLists()
|
||||||
|
if IsValid(self.listAvailable) then
|
||||||
|
self:UpdateAvailableList()
|
||||||
|
end
|
||||||
|
|
||||||
|
if IsValid(self.listLoadoutItems) then
|
||||||
|
self:UpdateLoadoutList()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:CreateAvailableWeaponIcon(class)
|
||||||
|
local weapon = self.weaponRegistry[class]
|
||||||
|
|
||||||
|
if not weapon then return end
|
||||||
|
if self.categoryFilter and weapon.category ~= self.categoryFilter then return end
|
||||||
|
|
||||||
|
if self.filter ~= "" then
|
||||||
|
local foundClass = string.find(class, self.filter, 1, true)
|
||||||
|
local foundName = string.find(string.lower(weapon.name), self.filter, 1, true)
|
||||||
|
|
||||||
|
if not foundClass and not foundName then return end
|
||||||
|
end
|
||||||
|
|
||||||
|
local localPly = LocalPlayer()
|
||||||
|
|
||||||
|
local icon = self.listAvailable:Add("CLoadoutWeaponIcon")
|
||||||
|
icon:SetWeaponName(weapon.name)
|
||||||
|
icon:SetWeaponClass(class)
|
||||||
|
|
||||||
|
icon.DoClick = function()
|
||||||
|
if not localPly:IsAdmin() then
|
||||||
|
Derma_Message("You can't edit loadouts.", "Loadout editor", "OK")
|
||||||
|
else
|
||||||
|
self:AddWeapon(class)
|
||||||
|
self:UpdateLoadoutList()
|
||||||
|
icon:Remove()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
icon.OpenMenu = function()
|
||||||
|
local menu = DermaMenu()
|
||||||
|
|
||||||
|
menu:AddOption("Copy to clipboard", function()
|
||||||
|
SetClipboardText(class)
|
||||||
|
end)
|
||||||
|
|
||||||
|
menu:Open()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:UpdateAvailableList()
|
||||||
|
self.listAvailable:Clear()
|
||||||
|
|
||||||
|
local inLoadout = {}
|
||||||
|
|
||||||
|
for _, item in ipairs(DATATHEFT_LOADOUTS[self.loadoutIndex]) do
|
||||||
|
inLoadout[item[1]] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
for class, _ in SortedPairsByMemberValue(self.weaponRegistry, "name") do
|
||||||
|
if not inLoadout[class] then
|
||||||
|
self:CreateAvailableWeaponIcon(class)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.listAvailable:InvalidateLayout(true)
|
||||||
|
self.scrollAvailable:InvalidateLayout()
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:UpdateLoadoutList()
|
||||||
|
self.comboLoadouts._blockCallback = true
|
||||||
|
self.comboLoadouts:Clear()
|
||||||
|
|
||||||
|
for index, loadout in ipairs(DATATHEFT_LOADOUTS) do
|
||||||
|
self.comboLoadouts:AddChoice(tostring(index), nil, index == self.loadoutIndex)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.comboLoadouts._blockCallback = nil
|
||||||
|
self.listLoadoutItems:Clear()
|
||||||
|
|
||||||
|
local items = DATATHEFT_LOADOUTS[self.loadoutIndex]
|
||||||
|
|
||||||
|
for index, item in ipairs(items) do
|
||||||
|
local class = item[1]
|
||||||
|
local icon = self.listLoadoutItems:Add("CLoadoutWeaponIcon")
|
||||||
|
icon:SetWeaponClass(class)
|
||||||
|
icon._itemIndex = index
|
||||||
|
|
||||||
|
icon.DoClick = function()
|
||||||
|
self:RemoveWeapon(index)
|
||||||
|
self:CreateAvailableWeaponIcon(class)
|
||||||
|
icon:Remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
local regWeapon = self.weaponRegistry[class]
|
||||||
|
|
||||||
|
if not regWeapon then
|
||||||
|
if not self.hintedMissingWeapons then
|
||||||
|
self.hintedMissingWeapons = true
|
||||||
|
|
||||||
|
Derma_Message("This loadout has weapons that are currently unavailable.\nMake sure they are installed to use them.", "Missing weapons", "OK")
|
||||||
|
end
|
||||||
|
|
||||||
|
icon:SetWeaponName(class)
|
||||||
|
icon:SetMaterial("icon16/cancel.png")
|
||||||
|
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
icon:SetWeaponName(regWeapon.name)
|
||||||
|
|
||||||
|
if regWeapon.adminOnly then
|
||||||
|
icon:SetAdminOnly(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not regWeapon.noPrimary then
|
||||||
|
icon.Primary = item[2]
|
||||||
|
end
|
||||||
|
|
||||||
|
if not regWeapon.noSecondary then
|
||||||
|
icon.Secondary = item[3]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.labelCount:SetTextColor(#items > self:GetWeaponLimit() and Color(255, 50, 50) or color_white)
|
||||||
|
self.labelCount:SetText(string.format("%d/%d", #items, self:GetWeaponLimit()))
|
||||||
|
self.labelCount:SizeToContents()
|
||||||
|
|
||||||
|
self.listLoadoutItems:InvalidateLayout(true)
|
||||||
|
|
||||||
|
self.scrollLoadoutItems:InvalidateLayout()
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:ShowPanel()
|
||||||
|
if IsValid(self.frame) then
|
||||||
|
self.frame:Close()
|
||||||
|
self.frame = nil
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local frameW = math.max(ScrW() * 0.6, 820)
|
||||||
|
local frameH = math.max(ScrH() * 0.6, 500)
|
||||||
|
frameW = math.Clamp(frameW, 600, ScrW())
|
||||||
|
frameH = math.Clamp(frameH, 400, ScrH())
|
||||||
|
|
||||||
|
local frame = vgui.Create("DFrame")
|
||||||
|
frame:SetTitle("Click on any weapon to add/remove it from your loadout.")
|
||||||
|
frame:SetPos(0, 0)
|
||||||
|
frame:SetSize(frameW, frameH)
|
||||||
|
frame:SetSizable(true)
|
||||||
|
frame:SetDraggable(true)
|
||||||
|
frame:SetDeleteOnClose(true)
|
||||||
|
frame:SetScreenLock(true)
|
||||||
|
frame:SetMinWidth(600)
|
||||||
|
frame:SetMinHeight(400)
|
||||||
|
frame:Center()
|
||||||
|
frame:MakePopup()
|
||||||
|
|
||||||
|
self.frame = frame
|
||||||
|
|
||||||
|
frame._maximized = false
|
||||||
|
frame.btnMaxim:SetDisabled(false)
|
||||||
|
|
||||||
|
frame.btnClose.DoClick = function()
|
||||||
|
frame:Close()
|
||||||
|
end
|
||||||
|
|
||||||
|
frame.OnClose = function()
|
||||||
|
self:Apply()
|
||||||
|
end
|
||||||
|
|
||||||
|
local leftPanel = vgui.Create("DPanel", frame)
|
||||||
|
local rightPanel = vgui.Create("DPanel", frame)
|
||||||
|
|
||||||
|
local function PaintBackground(_, sw, sh)
|
||||||
|
surface.SetDrawColor(32, 32, 32, 255)
|
||||||
|
surface.DrawRect(0, 0, sw, sh)
|
||||||
|
end
|
||||||
|
|
||||||
|
leftPanel.Paint = PaintBackground
|
||||||
|
rightPanel.Paint = PaintBackground
|
||||||
|
|
||||||
|
local div = vgui.Create("DHorizontalDivider", frame)
|
||||||
|
div:Dock(FILL)
|
||||||
|
div:SetLeft(leftPanel)
|
||||||
|
div:SetRight(rightPanel)
|
||||||
|
div:SetDividerWidth(4)
|
||||||
|
div:SetLeftMin(200)
|
||||||
|
div:SetRightMin(200)
|
||||||
|
div:SetLeftWidth(frameW * 0.56)
|
||||||
|
|
||||||
|
frame.btnMaxim.DoClick = function()
|
||||||
|
if frame._maximized then
|
||||||
|
frame:SetSize(frame._oldDimensions[1], frame._oldDimensions[2])
|
||||||
|
frame:Center()
|
||||||
|
frame._maximized = false
|
||||||
|
frame._oldDimensions = nil
|
||||||
|
else
|
||||||
|
frame._maximized = true
|
||||||
|
|
||||||
|
frame._oldDimensions = {frame:GetWide(), frame:GetTall()}
|
||||||
|
|
||||||
|
frame:SetPos(0, 0)
|
||||||
|
frame:SetSize(ScrW(), ScrH())
|
||||||
|
end
|
||||||
|
|
||||||
|
frame:SetDraggable(not frame._maximized)
|
||||||
|
frame:SetSizable(not frame._maximized)
|
||||||
|
div:SetLeftWidth(frame:GetWide() * 0.56)
|
||||||
|
end
|
||||||
|
|
||||||
|
----- LEFT PANEL STUFF
|
||||||
|
self.comboCategory = vgui.Create("DComboBox", leftPanel)
|
||||||
|
self.comboCategory:SetFont("Trebuchet24")
|
||||||
|
self.comboCategory:SetSortItems(false)
|
||||||
|
self.comboCategory:SetTextColor(Color(150, 255, 150))
|
||||||
|
self.comboCategory:SetTall(30)
|
||||||
|
self.comboCategory:Dock(TOP)
|
||||||
|
self.comboCategory:DockMargin(2, 2, 2, 2)
|
||||||
|
self.comboCategory:AddChoice("Available weapons", nil, true)
|
||||||
|
|
||||||
|
for _, name in ipairs(self.categories) do
|
||||||
|
self.comboCategory:AddChoice(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.comboCategory.Paint = function(_, sw, sh)
|
||||||
|
surface.SetDrawColor(0, 0, 0, 240)
|
||||||
|
surface.DrawRect(0, 0, sw, sh)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.comboCategory.OnSelect = function(_, index)
|
||||||
|
index = tonumber(index) - 1
|
||||||
|
|
||||||
|
if index == 0 then
|
||||||
|
self.categoryFilter = nil
|
||||||
|
else
|
||||||
|
self.categoryFilter = self.categories[index]
|
||||||
|
end
|
||||||
|
|
||||||
|
self:UpdateLists()
|
||||||
|
end
|
||||||
|
|
||||||
|
local entrySearch = vgui.Create("DTextEntry", leftPanel)
|
||||||
|
entrySearch:SetFont("ChatFont")
|
||||||
|
entrySearch:SetMaximumCharCount(64)
|
||||||
|
entrySearch:SetTabbingDisabled(true)
|
||||||
|
entrySearch:SetPlaceholderText("Search...")
|
||||||
|
entrySearch:SetTall(38)
|
||||||
|
entrySearch:Dock(BOTTOM)
|
||||||
|
|
||||||
|
entrySearch.OnChange = function(s)
|
||||||
|
self.filter = string.lower(string.Trim(s:GetText()))
|
||||||
|
self:UpdateAvailableList()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- available weapons list
|
||||||
|
self.scrollAvailable = vgui.Create("DScrollPanel", leftPanel)
|
||||||
|
self.scrollAvailable:Dock(FILL)
|
||||||
|
|
||||||
|
self.listAvailable = vgui.Create("DIconLayout", self.scrollAvailable)
|
||||||
|
self.listAvailable:Dock(FILL)
|
||||||
|
self.listAvailable:DockMargin(0, 0, 0, 0)
|
||||||
|
self.listAvailable:SetSpaceX(4)
|
||||||
|
self.listAvailable:SetSpaceY(4)
|
||||||
|
|
||||||
|
----- RIGHT PANEL STUFF
|
||||||
|
local panelOptions = vgui.Create("DPanel", rightPanel)
|
||||||
|
panelOptions:SetTall(32)
|
||||||
|
panelOptions:Dock(TOP)
|
||||||
|
panelOptions:DockPadding(2, 2, 2, 2)
|
||||||
|
panelOptions:SetPaintBackground(false)
|
||||||
|
|
||||||
|
local buttonCopy = vgui.Create("DButton", panelOptions)
|
||||||
|
buttonCopy:SetText("")
|
||||||
|
buttonCopy:SetImage("icon16/brick_go.png")
|
||||||
|
buttonCopy:SetTooltip("Add weapons from your inventory")
|
||||||
|
buttonCopy:SetWide(24)
|
||||||
|
buttonCopy:Dock(RIGHT)
|
||||||
|
|
||||||
|
buttonCopy.DoClick = function()
|
||||||
|
Derma_Query("This will add all weapons that you're currently holding to this loadout. Continue?", "Add weapons from your inventory", "Yes", function()
|
||||||
|
self:AddInventoryWeapons()
|
||||||
|
end, "No")
|
||||||
|
end
|
||||||
|
|
||||||
|
local buttonRemove = vgui.Create("DButton", panelOptions)
|
||||||
|
buttonRemove:SetText("")
|
||||||
|
buttonRemove:SetImage("icon16/delete.png")
|
||||||
|
buttonRemove:SetTooltip("Delete loadout")
|
||||||
|
buttonRemove:SetWide(24)
|
||||||
|
buttonRemove:Dock(RIGHT)
|
||||||
|
|
||||||
|
buttonRemove.DoClick = function()
|
||||||
|
local loadoutName = DATATHEFT_LOADOUTS[self.loadoutIndex].name
|
||||||
|
local helpText = string.format("Are you sure you want to delete \"%s\"?", loadoutName)
|
||||||
|
|
||||||
|
Derma_Query(helpText, "Delete loadout", "Yes", function()
|
||||||
|
self:DeleteLoadout(self.loadoutIndex)
|
||||||
|
self:Save()
|
||||||
|
end, "No")
|
||||||
|
end
|
||||||
|
|
||||||
|
local buttonNew = vgui.Create("DButton", panelOptions)
|
||||||
|
buttonNew:SetText("")
|
||||||
|
buttonNew:SetImage("icon16/add.png")
|
||||||
|
buttonNew:SetTooltip("Create loadout")
|
||||||
|
buttonNew:SetWide(24)
|
||||||
|
buttonNew:Dock(RIGHT)
|
||||||
|
|
||||||
|
buttonNew.DoClick = function()
|
||||||
|
self.loadoutIndex = self:CreateLoadout(self.loadoutIndex + 1)
|
||||||
|
self:Save()
|
||||||
|
self:UpdateLists()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.comboLoadouts = vgui.Create("DComboBox", panelOptions)
|
||||||
|
self.comboLoadouts:SetFont("Trebuchet24")
|
||||||
|
self.comboLoadouts:SetSortItems(false)
|
||||||
|
self.comboLoadouts:Dock(FILL)
|
||||||
|
self.comboLoadouts:SetTextColor(Color(193, 202, 255))
|
||||||
|
|
||||||
|
self.comboLoadouts.Paint = function(_, sw, sh)
|
||||||
|
surface.SetDrawColor(0, 0, 0, 240)
|
||||||
|
surface.DrawRect(0, 0, sw, sh)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.comboLoadouts.OnSelect = function(s, index)
|
||||||
|
if s._blockCallback then return end
|
||||||
|
|
||||||
|
self.loadoutIndex = tonumber(index)
|
||||||
|
self.hintedMissingWeapons = nil
|
||||||
|
|
||||||
|
self:UpdateLists()
|
||||||
|
end
|
||||||
|
|
||||||
|
local panelToggle = vgui.Create("DPanel", rightPanel)
|
||||||
|
panelToggle:SetTall(52)
|
||||||
|
panelToggle:Dock(BOTTOM)
|
||||||
|
panelToggle:DockPadding(8, 8, 8, 8)
|
||||||
|
panelToggle._animState = self.enabled and 1 or 0
|
||||||
|
|
||||||
|
panelToggle.Paint = function(s, sw, sh)
|
||||||
|
s._animState = Lerp(FrameTime() * 10, s._animState, self.enabled and 1 or 0)
|
||||||
|
|
||||||
|
surface.SetDrawColor(50 + 50 * (1 - s._animState), 50 + 50 * s._animState, 50)
|
||||||
|
surface.DrawRect(0, 0, sw, sh)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.labelCount = vgui.Create("DLabel", panelToggle)
|
||||||
|
self.labelCount:SetText("0/0")
|
||||||
|
self.labelCount:Dock(RIGHT)
|
||||||
|
|
||||||
|
self.scrollLoadoutItems = vgui.Create("DScrollPanel", rightPanel)
|
||||||
|
self.scrollLoadoutItems:Dock(FILL)
|
||||||
|
self.listLoadoutItems = vgui.Create("DIconLayout", self.scrollLoadoutItems)
|
||||||
|
self.listLoadoutItems:Dock(FILL)
|
||||||
|
self.listLoadoutItems:DockMargin(0, 0, 0, 0)
|
||||||
|
self.listLoadoutItems:SetSpaceX(4)
|
||||||
|
self.listLoadoutItems:SetSpaceY(4)
|
||||||
|
|
||||||
|
self:UpdateLists()
|
||||||
|
end
|
||||||
|
|
||||||
|
if engine.ActiveGamemode() == "beatrun" then
|
||||||
|
list.Set("DesktopWindows", "CLoadoutDesktopIcon", {
|
||||||
|
title = "DataTheft loadouts editor",
|
||||||
|
icon = "entities/weapon_smg1.png",
|
||||||
|
init = function()
|
||||||
|
CLoadout:ShowPanel()
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local WeaponIcon = {}
|
||||||
|
|
||||||
|
local iconMaterials = {
|
||||||
|
ammo = Material("icon16/bullet_yellow.png")
|
||||||
|
}
|
||||||
|
|
||||||
|
AccessorFunc(WeaponIcon, "m_bAdminOnly", "AdminOnly")
|
||||||
|
AccessorFunc(WeaponIcon, "m_bFavorite", "Favorite")
|
||||||
|
|
||||||
|
function WeaponIcon:Init()
|
||||||
|
self:SetPaintBackground(false)
|
||||||
|
self:SetSize(140, 128)
|
||||||
|
self:SetText("")
|
||||||
|
self:SetDoubleClickingEnabled(false)
|
||||||
|
|
||||||
|
self.Image = self:Add("DImage")
|
||||||
|
self.Image:SetPos(0, 0)
|
||||||
|
self.Image:SetSize(128, 128)
|
||||||
|
self.Image:SetVisible(false)
|
||||||
|
self.Image:SetKeepAspect(false)
|
||||||
|
|
||||||
|
self.WeaponName = ""
|
||||||
|
self.WeaponClass = ""
|
||||||
|
self.Border = 0
|
||||||
|
self.TextColor = Color(255, 255, 255, 255)
|
||||||
|
self.TextOutlineColor = Color(0, 0, 0, 255)
|
||||||
|
end
|
||||||
|
|
||||||
|
function WeaponIcon:SetWeaponName(name)
|
||||||
|
self.WeaponName = name
|
||||||
|
end
|
||||||
|
|
||||||
|
function WeaponIcon:SetWeaponClass(class)
|
||||||
|
self.WeaponClass = class
|
||||||
|
local icon_path = CLoadout:GetWeaponIcon(class)
|
||||||
|
|
||||||
|
if icon_path then
|
||||||
|
self:SetMaterial(icon_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function WeaponIcon:SetMaterial(name)
|
||||||
|
self.m_MaterialName = name
|
||||||
|
local mat = Material(name)
|
||||||
|
|
||||||
|
if not mat or mat:IsError() then
|
||||||
|
name = name:Replace("entities/", "VGUI/entities/")
|
||||||
|
name = name:Replace(".png", "")
|
||||||
|
mat = Material(name)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not mat or mat:IsError() then return end
|
||||||
|
self.Image:SetMaterial(mat)
|
||||||
|
end
|
||||||
|
|
||||||
|
function WeaponIcon:DoClick()
|
||||||
|
end
|
||||||
|
|
||||||
|
function WeaponIcon:OpenMenu()
|
||||||
|
end
|
||||||
|
|
||||||
|
function WeaponIcon:PaintOver()
|
||||||
|
end
|
||||||
|
|
||||||
|
function WeaponIcon:Paint(w, h)
|
||||||
|
self.Border = self.Depressed and 8 or 0
|
||||||
|
render.PushFilterMag(TEXFILTER.ANISOTROPIC)
|
||||||
|
render.PushFilterMin(TEXFILTER.ANISOTROPIC)
|
||||||
|
|
||||||
|
self.Image:PaintAt(self.Border, self.Border, w - self.Border * 2, h - self.Border * 2)
|
||||||
|
render.PopFilterMin()
|
||||||
|
render.PopFilterMag()
|
||||||
|
|
||||||
|
if self:IsHovered() or self.Depressed or self:IsChildHovered() then
|
||||||
|
surface.SetDrawColor(255, 255, 255, 255)
|
||||||
|
else
|
||||||
|
surface.SetDrawColor(0, 0, 0, 255)
|
||||||
|
end
|
||||||
|
|
||||||
|
surface.DrawOutlinedRect(0, 0, w, h, 4)
|
||||||
|
local infoH = 20
|
||||||
|
local infoY = h - infoH - 4
|
||||||
|
|
||||||
|
surface.SetDrawColor(30, 30, 30, 240)
|
||||||
|
surface.DrawRect(4, infoY, w - 8, infoH)
|
||||||
|
draw.SimpleTextOutlined(self.WeaponName, "Default", 8, infoY + infoH * 0.5, self.TextColor, 0, 1, 1, self.TextOutlineColor)
|
||||||
|
surface.SetDrawColor(255, 255, 255, 255)
|
||||||
|
|
||||||
|
local str
|
||||||
|
|
||||||
|
if self.Primary then
|
||||||
|
if self.Secondary then
|
||||||
|
str = self.Primary .. "/" .. self.Secondary
|
||||||
|
else
|
||||||
|
str = self.Primary
|
||||||
|
end
|
||||||
|
elseif self.Secondary then
|
||||||
|
str = self.Secondary
|
||||||
|
end
|
||||||
|
|
||||||
|
if str then
|
||||||
|
surface.SetMaterial(iconMaterials.ammo)
|
||||||
|
surface.DrawTexturedRect(w - 18, infoY + 3, 16, 16)
|
||||||
|
|
||||||
|
draw.SimpleTextOutlined(str, "Default", w - 18, infoY + infoH * 0.5, self.TextColor, 2, 1, 1, self.TextOutlineColor)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
vgui.Register("CLoadoutWeaponIcon", WeaponIcon, "DButton")
|
||||||
|
end
|
122
beatrun/gamemodes/beatrun/gamemode/cl/off/Menu_Gamemodes_new.lua
Normal file
122
beatrun/gamemodes/beatrun/gamemode/cl/off/Menu_Gamemodes_new.lua
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
function CLoadout:InitRegistry()
|
||||||
|
local registry = {}
|
||||||
|
|
||||||
|
for _, v in pairs(list.Get("Weapon")) do
|
||||||
|
if not v.ClassName or not v.Spawnable then continue end
|
||||||
|
|
||||||
|
registry[v.ClassName] = {
|
||||||
|
name = (v.PrintName and v.PrintName ~= "") and v.PrintName or v.ClassName,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
self.weaponRegistry = registry
|
||||||
|
|
||||||
|
table.sort(self.categories)
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:CreateLoadout(items)
|
||||||
|
local loadout = {}
|
||||||
|
|
||||||
|
if istable(items) and table.IsSequential(items) then
|
||||||
|
for _, item in ipairs(items) do
|
||||||
|
loadout[#loadout + 1] = { item[1] }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return table.insert(DATATHEFT_LOADOUTS, loadout)
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:DeleteLoadout(index)
|
||||||
|
table.remove(DATATHEFT_LOADOUTS, index)
|
||||||
|
|
||||||
|
if #DATATHEFT_LOADOUTS == 0 then
|
||||||
|
self:CreateLoadout()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.loadoutIndex = #DATATHEFT_LOADOUTS
|
||||||
|
self:UpdateLists()
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:Apply()
|
||||||
|
local loadout = DATATHEFT_LOADOUTS[self.loadoutIndex]
|
||||||
|
|
||||||
|
loadout = util.Compress(util.TableToJSON(loadout))
|
||||||
|
|
||||||
|
if not loadut then
|
||||||
|
LocalPlayer():ChatPrint("Failed to compress the loadut!")
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
net.Start("Beatrun_UpdateLoadouts", false)
|
||||||
|
net.WriteData(loadout, #loadout)
|
||||||
|
net.SendToServer()
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:AddWeapon(class)
|
||||||
|
local items = DATATHEFT_LOADOUTS[self.loadoutIndex]
|
||||||
|
|
||||||
|
if #items < self:GetWeaponLimit() then
|
||||||
|
table.insert(items, { class })
|
||||||
|
else
|
||||||
|
Derma_Message("Your loadout is full!", "Loadout", "OK")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:AddInventoryWeapons()
|
||||||
|
local items = DATATHEFT_LOADOUTS[self.loadoutIndex]
|
||||||
|
|
||||||
|
local alreadyInLoadout = {}
|
||||||
|
|
||||||
|
for _, v in ipairs(items) do
|
||||||
|
alreadyInLoadout[v[1]] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
local weaponsList = LocalPlayer():GetWeapons()
|
||||||
|
|
||||||
|
for _, v in ipairs(weaponsList) do
|
||||||
|
local class = (v.GetClass and v:GetClass()) or v.ClassName
|
||||||
|
|
||||||
|
if not alreadyInLoadout[class] then
|
||||||
|
table.insert(DATATHEFT_LOADOUTS[self.loadoutIndex], { class })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:UpdateLists()
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:RemoveWeapon(index)
|
||||||
|
table.remove(DATATHEFT_LOADOUTS[self.loadoutIndex], index)
|
||||||
|
end
|
||||||
|
|
||||||
|
function CLoadout:Init()
|
||||||
|
self.filter = ""
|
||||||
|
|
||||||
|
self.loadoutIndex = 1
|
||||||
|
DATATHEFT_LOADOUTS = {}
|
||||||
|
|
||||||
|
if IsValid(self.frame) then
|
||||||
|
self.frame:Close()
|
||||||
|
self.frame = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
self:InitRegistry()
|
||||||
|
|
||||||
|
if #DATATHEFT_LOADOUTS == 0 then
|
||||||
|
self:CreateLoadout()
|
||||||
|
end
|
||||||
|
|
||||||
|
self:Apply()
|
||||||
|
end
|
||||||
|
|
||||||
|
hook.Add("InitPostEntity", "CLoadout_Initialize", function()
|
||||||
|
hook.Remove("InitPostEntity", "CLoadout_Initialize")
|
||||||
|
|
||||||
|
timer.Simple(1, function()
|
||||||
|
CLoadout:Init()
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
concommand.Add("Beatrun_GamemodesMenu", function()
|
||||||
|
CLoadout:ShowPanel()
|
||||||
|
end, nil, "Opens the loadout customization window.")
|
|
@ -301,7 +301,7 @@ hook.Add("SetupMove", "SpawnFreeze", function(ply, mv, cmd)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
hook.Add("ShouldCollide", "NoPlayerCollisions", function(ent1, ent2)
|
hook.Add("ShouldCollide", "NoPlayerCollisions", function(ent1, ent2)
|
||||||
if ent1:IsPlayer() and ent2.NoPlayerCollisions then
|
if ent1:IsPlayer() and (ent2:IsPlayer() or ent2.NoPlayerCollisions) then
|
||||||
if ent2.BRCollisionFunc then return ent2:BRCollisionFunc(ent1)
|
if ent2.BRCollisionFunc then return ent2:BRCollisionFunc(ent1)
|
||||||
else return false end
|
else return false end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,4 +2,8 @@ hook.Add("PlayerButtonDown", "CourseMenuBind", function(ply, button)
|
||||||
if (game.SinglePlayer() or CLIENT and IsFirstTimePredicted()) and button == KEY_F4 then
|
if (game.SinglePlayer() or CLIENT and IsFirstTimePredicted()) and button == KEY_F4 then
|
||||||
ply:ConCommand("Beatrun_CourseMenu")
|
ply:ConCommand("Beatrun_CourseMenu")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (game.SinglePlayer() or CLIENT and IsFirstTimePredicted()) and button == KEY_F3 then
|
||||||
|
ply:ConCommand("Beatrun_GamemodesMenu")
|
||||||
|
end
|
||||||
end)
|
end)
|
|
@ -1,5 +0,0 @@
|
||||||
hook.Add("PlayerButtonDown", "GMMenuBind", function(ply, button)
|
|
||||||
if (game.SinglePlayer() or CLIENT and IsFirstTimePredicted()) and button == KEY_F3 then
|
|
||||||
ply:ConCommand("Beatrun_GamemodesMenu")
|
|
||||||
end
|
|
||||||
end)
|
|
|
@ -1,12 +1,13 @@
|
||||||
if SERVER then
|
if SERVER then
|
||||||
local meta = FindMetaTable("Player")
|
local meta = FindMetaTable("Player")
|
||||||
|
local allowPropSpawn = CreateConVar("Beatrun_AllowPropSpawn", "0", {FCVAR_ARCHIVE}, "Allow players to spawn props and entities")
|
||||||
|
|
||||||
util.AddNetworkString("SPParkourEvent")
|
util.AddNetworkString("SPParkourEvent")
|
||||||
|
|
||||||
local spawn = {"PlayerGiveSWEP", "PlayerSpawnEffect", "PlayerSpawnNPC", "PlayerSpawnObject", "PlayerSpawnProp", "PlayerSpawnRagdoll", "PlayerSpawnSENT", "PlayerSpawnSWEP", "PlayerSpawnVehicle"}
|
local spawn = {"PlayerGiveSWEP", "PlayerSpawnEffect", "PlayerSpawnNPC", "PlayerSpawnObject", "PlayerSpawnProp", "PlayerSpawnRagdoll", "PlayerSpawnSENT", "PlayerSpawnSWEP", "PlayerSpawnVehicle"}
|
||||||
|
|
||||||
local function BlockSpawn(ply)
|
local function BlockSpawn(ply)
|
||||||
if not ply:IsSuperAdmin() then return false end
|
if not ply:IsAdmin() and not allowPropSpawn:GetBool() then return false end
|
||||||
end
|
end
|
||||||
|
|
||||||
for k, v in ipairs(spawn) do
|
for k, v in ipairs(spawn) do
|
||||||
|
@ -16,7 +17,7 @@ if SERVER then
|
||||||
hook.Add("IsSpawnpointSuitable", "NoSpawnFrag", function(ply) return true end)
|
hook.Add("IsSpawnpointSuitable", "NoSpawnFrag", function(ply) return true end)
|
||||||
|
|
||||||
hook.Add("AllowPlayerPickup", "AllowAdminsPickUp", function(ply, ent)
|
hook.Add("AllowPlayerPickup", "AllowAdminsPickUp", function(ply, ent)
|
||||||
if not ply:IsSuperAdmin() then return false end
|
if not ply:IsAdmin() and not allowPropSpawn:GetBool() then return false end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function meta:GTAB(minutes)
|
function meta:GTAB(minutes)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
local vmatrixmeta = FindMetaTable("VMatrix")
|
local vmatrixmeta = FindMetaTable("VMatrix")
|
||||||
local playermeta = FindMetaTable("Player")
|
local playermeta = FindMetaTable("Player")
|
||||||
|
|
||||||
|
CLoadout = {}
|
||||||
|
|
||||||
function CLIENT_IFTP()
|
function CLIENT_IFTP()
|
||||||
return CLIENT and IsFirstTimePredicted()
|
return CLIENT and IsFirstTimePredicted()
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
util.AddNetworkString("Beatrun_ToggleDataTheft")
|
|
||||||
util.AddNetworkString("Beatrun_ToggleInfection")
|
|
||||||
|
|
||||||
local datatheft, infection = false
|
|
||||||
|
|
||||||
net.Receive("Beatrun_ToggleDataTheft", function(_, ply)
|
|
||||||
datatheft = not datatheft
|
|
||||||
if datatheft then
|
|
||||||
Beatrun_StartDataTheft()
|
|
||||||
else
|
|
||||||
Beatrun_StopDataTheft()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
net.Receive("Beatrun_ToggleInfection", function(_, ply)
|
|
||||||
infection = not infection
|
|
||||||
if infection then
|
|
||||||
Beatrun_StartInfection()
|
|
||||||
else
|
|
||||||
Beatrun_StopInfection()
|
|
||||||
end
|
|
||||||
end)
|
|
28
beatrun/gamemodes/beatrun/gamemode/sv/off/Menu_Gamemodes.lua
Normal file
28
beatrun/gamemodes/beatrun/gamemode/sv/off/Menu_Gamemodes.lua
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
util.AddNetworkString("Beatrun_ToggleGamemode")
|
||||||
|
util.AddNetworkString("Beatrun_UpdateDataTheftLoadout")
|
||||||
|
|
||||||
|
local datatheft, infection = false
|
||||||
|
|
||||||
|
net.Receive("Beatrun_ToggleGamemode", function(_, ply)
|
||||||
|
local gm = net.ReadString()
|
||||||
|
|
||||||
|
if gm == "datatheft" then
|
||||||
|
datatheft = not datatheft
|
||||||
|
if datatheft then
|
||||||
|
Beatrun_StartDataTheft()
|
||||||
|
else
|
||||||
|
Beatrun_StopDataTheft()
|
||||||
|
end
|
||||||
|
elseif gm == "infection" then
|
||||||
|
infection = not infection
|
||||||
|
if infection then
|
||||||
|
Beatrun_StartInfection()
|
||||||
|
else
|
||||||
|
Beatrun_StopInfection()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
net.Receive("Beatrun_UpdateDataTheftLoadout", function(_, ply)
|
||||||
|
|
||||||
|
end)
|
|
@ -0,0 +1,20 @@
|
||||||
|
util.AddNetworkString("Beatrun_UpdateLoadouts")
|
||||||
|
|
||||||
|
local function IsAvailableForPlayer(ply)
|
||||||
|
return ply:IsAdmin()
|
||||||
|
end
|
||||||
|
|
||||||
|
net.Receive("Beatrun_UpdateLoadouts", function(len, ply)
|
||||||
|
local data = net.ReadData(len)
|
||||||
|
data = util.Decompress(data)
|
||||||
|
|
||||||
|
if not data or data == "" then return end
|
||||||
|
|
||||||
|
local loadout = util.JSONToTable(data)
|
||||||
|
|
||||||
|
if not loadout then return print("Failed to parse %s\"s loadout!", ply:Nick()) end
|
||||||
|
|
||||||
|
local canUse, reason = IsAvailableForPlayer(ply)
|
||||||
|
|
||||||
|
if not canUse then return ply:ChatPrint("[Loadout] " .. reason) end
|
||||||
|
end)
|
Loading…
Reference in a new issue