mirror of
https://github.com/JonnyBro/beatrun.git
synced 2025-01-30 11:37:27 +05:00
update!!11!
This commit is contained in:
parent
019aa24125
commit
636f78953f
11 changed files with 115 additions and 746 deletions
36
Courses client.md
Normal file
36
Courses client.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
"C:\Users\Jonny\Desktop\xd\lua\weapons\mg_base\modules\client\cl_spawnmenu.lua"
|
||||
|
||||
Courses client
|
||||
Beatrun_Apikey
|
||||
Beatrun_Domain
|
||||
|
||||
Viewpunch client
|
||||
Beatrun_ViewbobIntensity
|
||||
Beatrun_ViewbobStabilized
|
||||
|
||||
Courses client
|
||||
Beatrun_FastStart
|
||||
Beatrun_CPSave
|
||||
|
||||
Misc server
|
||||
Beatrun_AllowPropSpawn (Server)
|
||||
Beatrun_AllowOvedriveInMultiplayer (server)
|
||||
|
||||
Purist mode
|
||||
Beatrun_PuristMode (client)
|
||||
Beatrun_PuristModeForce (server)
|
||||
Beatrun_PuristWallrun (server)
|
||||
|
||||
Moves
|
||||
Beatrun_QuickturnGround (client)
|
||||
Beatrun_KickGlitch (server)
|
||||
Beatrun_QuakeJump (server)
|
||||
Beatrun_SideStep (server)
|
||||
Beatrun_MaxSpeed (server)
|
||||
Beatrun_Disarm (server)
|
||||
|
||||
Dive
|
||||
Beatrun_Totsugeki
|
||||
Beatrun_TotsugekiSpam
|
||||
Beatrun_TotsugekiHeading
|
||||
Beatrun_TotsugekiDir
|
14
README.md
14
README.md
|
@ -1,14 +1,15 @@
|
|||
# beatrun
|
||||
Modified beatrun's source code.<br><br>
|
||||
There are lua modules ([source](https://github.com/fluffy-servers/gmod-discord-rpc)), they are for Discord Rich Presence to work, if you want pure Lua just don't extract them, but your Level and Map will not be shown in your Discord status.<br>
|
||||
There are lua modules, they are for Discord Rich Presence to work, if you want pure Lua just don't extract them, but your Level and Map will not be shown in your Discord status.<br>
|
||||
This version of the beatrun works on any version of the game (Chromium or not).
|
||||
|
||||
[Old Kick Glitch Version](https://github.com/JonnyBro/beatrun/tree/old-kickglitch)
|
||||
|
||||
# Installation
|
||||
0. Delete `beatrun` folder in *addons* if you have it!
|
||||
1. Extract `beatrun` folder to *your_game_folder/garrysmod/addons*.
|
||||
2. Extract `lua` folder to *your_game_folder/garrysmod*.
|
||||
* `lua` folder constains modules for Discord Rich Presense to work. They are open source, visit [this](https://github.com/fluffy-servers/gmod-discord-rpc) link to see the source
|
||||
* `lua` folder constains modules for Discord Rich Presense to work. They are open source, visit [this](https://github.com/fluffy-servers/gmod-discord-rpc) to see the source.
|
||||
|
||||
## Changes added by me
|
||||
* [Custom online courses database](https://courses.beatrun.ru)! It's free 🤯!
|
||||
|
@ -26,10 +27,7 @@ This version of the beatrun works on any version of the game (Chromium or not).
|
|||
- [ ] Gamemodes menu
|
||||
|
||||
## Fixes and changes from previous version
|
||||
* Hacky fix for weapon damage.
|
||||
* Proper Kick Glitch (Like in original ME: https://www.youtube.com/watch?v=zK5y3NBUStc)
|
||||
* Grapple fixes. Now it moves with entity it attached to and other players can see it.
|
||||
* More reliable grappling.
|
||||
* You can now dive to your death =)
|
||||
|
||||
# All changes and fixes
|
||||
* Course saving works with compression and without.
|
||||
|
@ -39,3 +37,7 @@ This version of the beatrun works on any version of the game (Chromium or not).
|
|||
* Fixed DataTheft crash when touching data bank.
|
||||
* Fixed error when loading course.
|
||||
* Fixed collisions issues.
|
||||
* Fixed and tweaked player-player weapon damage.
|
||||
* Proper Kick Glitch (Like in original ME: https://www.youtube.com/watch?v=zK5y3NBUStc)
|
||||
* Grapple fixes. Now it moves with entity it attached to and other players can see it.
|
||||
* More reliable grappling.
|
||||
|
|
|
@ -18,7 +18,7 @@ local function FallCheck()
|
|||
if not IsValid(ply) then return end
|
||||
local speed = ply:GetVelocity().z
|
||||
|
||||
if not ply.FallStatic and speed <= -800 and ply:GetMoveType() ~= MOVETYPE_NOCLIP then
|
||||
if not ply.FallStatic and speed <= -800 and ply:GetMoveType() ~= MOVETYPE_NOCLIP and ply:GetDive() == false then
|
||||
ply:EmitSound("FallStatic")
|
||||
ply.FallStatic = true
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
hook.Add("AddToolMenuCategories", "Beatrun_Category", function()
|
||||
spawnmenu.AddToolCategory("Beatrun", "beatrun_category", "Beatrun Settings")
|
||||
end)
|
||||
|
||||
hook.Add("PopulateToolMenu", "CustomMenuSettings", function()
|
||||
spawnmenu.AddToolMenuOption("Utilities", "Beatrun Settings", "Custom_Menu", "#My Custom Menu", "", "", function(panel)
|
||||
panel:ClearControls()
|
||||
panel:NumSlider("Gravity", "sv_gravity", 0, 600)
|
||||
end)
|
||||
end)
|
|
@ -1,96 +0,0 @@
|
|||
local gamemodePanel = {
|
||||
w = 1200,
|
||||
h = 650,
|
||||
bgcolor = Color(32, 32, 32),
|
||||
outlinecolor = Color(54, 55, 56),
|
||||
alpha = 0.9,
|
||||
elements = {}
|
||||
}
|
||||
|
||||
gamemodePanel.x = 960 - gamemodePanel.w * 0.5
|
||||
gamemodePanel.y = 540 - gamemodePanel.h * 0.5
|
||||
|
||||
local function closeButton()
|
||||
AEUI:Clear()
|
||||
end
|
||||
|
||||
local function infectionButton()
|
||||
net.Start("Beatrun_ToggleGamemode")
|
||||
net.WriteString("infection")
|
||||
net.SendToServer()
|
||||
end
|
||||
|
||||
local function datatheftButton()
|
||||
net.Start("Beatrun_ToggleGamemode")
|
||||
net.WriteString("datatheft")
|
||||
net.SendToServer()
|
||||
end
|
||||
|
||||
-- local function createButton()
|
||||
-- net.Start("Beatrun_CreateLoadout")
|
||||
-- net.SendToServer()
|
||||
-- maxloadoutnum = maxloadoutnum + 1
|
||||
-- LocalPlayer():EmitSound("buttonclick.wav")
|
||||
-- end
|
||||
|
||||
local function isSA()
|
||||
return not LocalPlayer():IsSuperAdmin()
|
||||
end
|
||||
|
||||
AEUI:AddText(gamemodePanel, "Gamemodes Select", "AEUIVeryLarge", 20, 30)
|
||||
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)
|
||||
infectionbutton.greyed = isSA
|
||||
local datatheftbutton = AEUI:AddButton(gamemodePanel, "Toggle Data Theft", datatheftButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 450)
|
||||
datatheftbutton.greyed = isSA
|
||||
-- local loadoutbutton = AEUI:AddButton(gamemodePanel, "Create a new loadout", createButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 450)
|
||||
-- loadoutbutton.greyed = isSA
|
||||
-- local resetbutton = AEUI:AddButton(gamemodePanel, "Resets all loadouts", resetloadoutButton, "AEUILarge", gamemodePanel.w - 330, gamemodePanel.h - 550)
|
||||
-- resetbutton.greyed = isSA
|
||||
-- local leftloadout = AEUI:AddButton(gamemodePanel, " < ", leftButton, "AEUILarge", gamemodePanel.w - 225, gamemodePanel.h - 175)
|
||||
-- leftloadout.greyed = isSA
|
||||
-- local rightloadout = AEUI:AddButton(gamemodePanel, " > ", rightButton, "AEUILarge", gamemodePanel.w - 150, gamemodePanel.h - 175)
|
||||
-- rightloadout.greyed = isSA
|
||||
-- AEUI:AddText(gamemodePanel, "Change through loadouts", "AEUILarge", gamemodePanel.w - 360, gamemodePanel.h - 125)
|
||||
|
||||
local weaponsList = {
|
||||
w = 800,
|
||||
h = 450,
|
||||
x = 979.2 - gamemodePanel.w * 0.5,
|
||||
y = 648 - gamemodePanel.h * 0.5,
|
||||
bgcolor = Color(32, 32, 32),
|
||||
outlinecolor = Color(54, 55, 56),
|
||||
alpha = 0.9,
|
||||
elements = {}
|
||||
}
|
||||
|
||||
function OpenGMMenu(ply)
|
||||
AEUI:AddPanel(gamemodePanel)
|
||||
AEUI:AddPanel(weaponsList)
|
||||
|
||||
local loaded_weapons = {}
|
||||
|
||||
for i, _ in pairs(DATATHEFT_LOADOUTS) do
|
||||
for _, v in pairs(DATATHEFT_LOADOUTS[i]) do
|
||||
table.insert(loaded_weapons, v)
|
||||
end
|
||||
end
|
||||
|
||||
for _, v in pairs(weapons.GetList()) do
|
||||
if not string.find(v.ClassName:lower(), "base") then
|
||||
local weaponentry = AEUI:AddText(weaponsList, v.ClassName, "AEUILarge", 10, 40 * #weaponsList.elements)
|
||||
function weaponentry:onclick()
|
||||
LocalPlayer():EmitSound("buttonclick.wav")
|
||||
end
|
||||
weaponentry.greyed = isSA
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
hook.Add("InitPostEntity", "GMMenuCommand", function()
|
||||
concommand.Add("Beatrun_GamemodesMenu", OpenGMMenu)
|
||||
hook.Remove("InitPostEntity", "GMMenuCommand")
|
||||
end)
|
||||
|
||||
concommand.Add("Beatrun_GamemodesMenu", OpenGMMenu)
|
|
@ -1,490 +0,0 @@
|
|||
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
|
|
@ -1,122 +0,0 @@
|
|||
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.")
|
|
@ -0,0 +1,67 @@
|
|||
local function StartInfection()
|
||||
net.Start("Beatrun_ToggleGamemode")
|
||||
net.WriteString("infection")
|
||||
net.SendToServer()
|
||||
end
|
||||
|
||||
local function StartDataTheft()
|
||||
net.Start("Beatrun_ToggleGamemode")
|
||||
net.WriteString("datatheft")
|
||||
net.SendToServer()
|
||||
end
|
||||
|
||||
hook.Add("AddToolMenuCategories", "Beatrun_Category", function()
|
||||
spawnmenu.AddToolCategory("Beatrun", "Client", "Client")
|
||||
end)
|
||||
|
||||
hook.Add("PopulateToolMenu", "Beatrun_ToolMenu", function()
|
||||
--[[
|
||||
Beatrun_FOV
|
||||
|
||||
Beatrun_HUDXP
|
||||
Beatrun_HUDSway
|
||||
Beatrun_HUDDynamic
|
||||
Beatrun_HUDHidden
|
||||
Beatrun_HUDReticle
|
||||
|
||||
Beatrun_HUDTextColor
|
||||
Beatrun_HUDCornerColor
|
||||
Beatrun_HUDFloatingXPColor
|
||||
|
||||
Beatrun_MinimalVM
|
||||
Beatrun_Wind
|
||||
--]]
|
||||
spawnmenu.AddToolMenuOption("Beatrun", "Client", "beatrun_hud", "HUD", "", "", function(panel)
|
||||
panel:ClearControls()
|
||||
|
||||
panel:SetName("HUD Setttings")
|
||||
|
||||
panel:CheckBox("Show total XP near your nickname", "Beatrun_HUDXP")
|
||||
panel:CheckBox("Display HUD swaying", "Beatrun_HUDSway")
|
||||
panel:CheckBox("Hide HUD when moving", "Beatrun_HUDDynamic")
|
||||
panel:CheckBox("Display a dot in the center of the screen", "Beatrun_HUDReticle")
|
||||
|
||||
panel:NumSlider("FOV", "Beatrun_FOV", 90, 120, 0)
|
||||
panel:ControlHelp("You need to respawn after changing FOV!")
|
||||
|
||||
panel:NumSlider("Hide HUD", "Beatrun_HUDHidden", 0, 2, 0)
|
||||
panel:ControlHelp("0 - Shown\n1 - Gamemode only\n2 - Hidden")
|
||||
|
||||
local divider = vgui.Create("DHorizontalDivider")
|
||||
panel:AddItem(divider)
|
||||
|
||||
panel:Help("HUD Text Color")
|
||||
|
||||
local HudTextColor = vgui.Create("DColorMixer", Frame)
|
||||
HudTextColor:Dock(FILL)
|
||||
HudTextColor:SetPalette(true)
|
||||
HudTextColor:SetAlphaBar(true)
|
||||
HudTextColor:SetWangs(true)
|
||||
HudTextColor:SetColor(string.ToColor(GetConVar("Beatrun_HUDTextColor"):GetString()))
|
||||
function HudTextColor:ValueChanged(color)
|
||||
RunConsoleCommand("Beatrun_HUDTextColor", string.FromColor(col))
|
||||
end
|
||||
|
||||
panel:AddItem(HudTextColor)
|
||||
end)
|
||||
end)
|
|
@ -40,7 +40,7 @@ if SERVER then
|
|||
end
|
||||
|
||||
if CLIENT then
|
||||
CreateClientConVar("Beatrun_FOV", 90, true, true, "'Woah how are you moving this fast' and other hilarious jokes", 70, 175)
|
||||
CreateClientConVar("Beatrun_FOV", 90, true, true, "'Woah how are you moving this fast' and other hilarious jokes", 70, 120)
|
||||
CreateClientConVar("Beatrun_CPSave", 1, true, true, "Respawning during a course will go back to the last hit checkpoint", 0, 1)
|
||||
end
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ net.Receive("Beatrun_ToggleGamemode", function(_, ply)
|
|||
|
||||
if gm == "datatheft" then
|
||||
datatheft = not datatheft
|
||||
|
||||
if datatheft then
|
||||
Beatrun_StartDataTheft()
|
||||
else
|
||||
|
@ -15,6 +16,7 @@ net.Receive("Beatrun_ToggleGamemode", function(_, ply)
|
|||
end
|
||||
elseif gm == "infection" then
|
||||
infection = not infection
|
||||
|
||||
if infection then
|
||||
Beatrun_StartInfection()
|
||||
else
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
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