-- Made by Phoenixf129, hosted on Coderhire -- See license.txt for more info PSDrops = PSDrops or {} -- Are the below commands enabled? -- Due to the nature of the system, you may have to spam these commands before anyone gets anything :) -- I suggest you change the below commands to something unique. PSDrops.DebugEnabled = true PSDrops.DebugCommand = "ps_debugdrop" PSDrops.DebugCommand2 = "ps_debugdropme" PSDrops.DefaultItemColor = Color(0,255,0) -- Global sounds played to players when an item is found. PSDrops.AnnounceSound = "ambient/levels/canals/windchime2.wav" -- Sound that plays when the menu opens. PSDrops.MenuSound = "ambient/levels/canals/windchime2.wav" -- Theme Stuff PSDrops.WindowColor = Color(26, 30, 38, 100) --Main window color PSDrops.BannerColor = Color(26, 30, 38, 180) --Banner color, default is white PSDrops.CanvasColor = Color(255, 255, 255, 180) --Canvas color, default is white PSDrops.CanvasBorderColor = Color(0, 0, 0, 180) --Canvas color, default is white -- In minutes. -- The system will randomise a time between these to do initiate a drop sequence. PSDrops.DropTimeMin = 1 PSDrops.DropTimeMax = 15 -- Follow the below template, it should be self explanatory. PSDrops.PColors = { {minprice=35000, color = Color(150,50,255), rarity="Unusual"}, {minprice=10000, color = Color(0,0,255), rarity = "Rare"}, {minprice=5000, color = Color(255,0,0), rarity = "Special"}, {minprice=2000, color = Color(255,150,0), rarity = "Uncommon"}, {minprice=1000, color = Color(255,255,0), rarity = "Common"}, } -- Lower the number, higher the droprate. -- I prefer to keep them the same, but here's a free feature for you guys that want infinite drops for owner... PSDrops.DefaultDropRate = 30 PSDrops.DropRate = { ["owner"] = 30, ["devsuper"] = 30, ["superadmin"] = 30, ["admin"] = 30, ["moderator"] = 30, ["donator"] = 30, ["user"] = 30, } -- The way pointshop works, is the ID of the item, is it's lua filename. So if it's called craphat.lua, it's ID is craphat. -- Placing item ID's in here, will stop the system from dropping those item's at all. PSDrops.ItemBlackList = { "craphat", "craphat2", } -- Now supports tabs that are hidden from players from dropping items to them. -- Also now supports all of pointshops item/category restrictions thanks to HandsomeMatt! -- Due to this, the below Category Blacklist (Which is now fixed) may not apply to you any more :) -- Deprecated due to the system automatically blocking off item's if you've done it correctly in the first place. I.e. can't buy/see. -- Category blacklist. Check inside _category.lua and copy it's Name into here to blacklist any item's inside the category! -- Example: CATEGORY.Name = 'Hats' -- Add "Hats" below. Enjoy! PSDrops.CatBlackList = { "craphat", "craphat2", } -- Don't edit below here unless you know what you are doing. table.sort( PSDrops.PColors, function( a, b ) return a.minprice > b.minprice end ) if SERVER then AddCSLuaFile() util.AddNetworkString( "net_PSDropMenu" ) util.AddNetworkString( "net_PSDropChat" ) util.AddNetworkString( "net_PSUnBoxServer" ) util.AddNetworkString( "net_PSUnBoxClient" ) local nextCheck = 0 local meta = FindMetaTable("Player") function meta:ChooseRandPSDropItem() if not self.PSDropItems then self.PSDropItems = table.Copy(PS.Items) -- This should remove blacklisted entities from the table... for k, ITEM in pairs(self.PSDropItems) do local CATEGORY = PS:FindCategoryByName(ITEM.Category) local r, message = false, nil -- MY own custom tables if table.HasValue(PSDrops.ItemBlackList, ITEM.ID) then r = true end if table.HasValue(PSDrops.CatBlackList, CATEGORY.Name) then r = true end -- CanPlayerBuy support. If you can't buy it, you can't get it. if (type(ITEM.CanPlayerBuy) == "function") then r = not ITEM:CanPlayerBuy(self) elseif (type(ITEM.CanPlayerBuy) == "boolean") then r = not ITEM.CanPlayerBuy end -- Custom for my server. if ITEM.AdminOnly and not (self:IsMod() or self:IsAdmin()) then r = true end if ITEM.VIPOnly and not self:IsVIP() then r = true end -- See Category support. if CATEGORY.CanPlayerSee and not CATEGORY:CanPlayerSee(self) then r = true end -- Allowed usergroups support. if (ITEM.AllowedUserGroups and #ITEM.AllowedUserGroups > 0) and ( !table.HasValue(ITEM.AllowedUserGroups, self:PS_GetUsergroup() ) ) then r = true end if (CATEGORY.AllowedUserGroups and #CATEGORY.AllowedUserGroups > 0) and ( !table.HasValue(CATEGORY.AllowedUserGroups, self:PS_GetUsergroup() ) ) then r = true end -- And finally, remove it from the droptable! if r then self.PSDropItems[k] = nil end end end return table.Random(self.PSDropItems) end function PSDrops:DoThink(cmd, itemid, caller) local ITEM = PS.Items[itemid] if !cmd then if nextCheck > CurTime() then return end end for _, ply in pairs(player.GetAll()) do -- IF this has been called via debugdropme, then only drop for caller. if caller and caller:IsValid() then if ply != caller then continue end end if !caller then local dnum = PSDrops.DefaultDropRate for rank, rate in pairs(PSDrops.DropRate) do if ply:IsUserGroup(rank) then dnum = rate break end end if math.random(1, dnum) != math.Round(dnum/2) then continue end end if !ITEM then ITEM = ply:ChooseRandPSDropItem() end net.Start("net_PSDropMenu") net.WriteString(ITEM.ID) net.Send(ply) net.Start("net_PSDropChat") net.WriteEntity(ply) net.WriteString(ITEM.ID) net.Broadcast() print(ply:Nick().." found "..ITEM.Name) if not ply:PS_HasItem(ITEM.ID) then ply:PS_GiveItem(ITEM.ID) end end nextCheck = CurTime() + math.random( PSDrops.DropTimeMin * 60, PSDrops.DropTimeMax * 60 ) end hook.Add("Think", "PSDrops:DoThink", PSDrops.DoThink) -- A simple hacky method to make sure the debug command works, because i'm lazy. concommand.Add(PSDrops.DebugCommand, function(ply, cmd, args) if !PSDrops.DebugEnabled then return end PSDrops:DoThink(true, args[1]) end) concommand.Add(PSDrops.DebugCommand2, function(ply, cmd, args) if !PSDrops.DebugEnabled then return end PSDrops:DoThink(true, args[1], ply) end) -- Send unboxing! net.Receive("net_PSUnBoxServer", function() local ply = net.ReadEntity() local item_id = net.ReadString() print("Recieved net from "..ply:Nick()) net.Start("net_PSUnBoxClient") net.WriteEntity(ply) net.WriteString(item_id) net.Broadcast() end) else surface.CreateFont("PSDropsFont70", {font = "Bebas Neue", size= 70, weight = 400, antialias = true } ) --Font used for titles surface.CreateFont("PSDropsFont32", {font = "Bebas Neue", size= 32, weight = 400, antialias = true } ) --Font used for titles surface.CreateFont("PSDropsFont24", {font = "Bebas Neue", size= 24, weight = 400, antialias = true } ) --Font used for titles surface.CreateFont("PSDropsFont18", {font = "Bebas Neue", size= 18, weight = 400, antialias = true } ) --Font used for titles surface.CreateFont("PSDropsFont14", {font = "Bebas Neue", size= 14, weight = 400, antialias = true } ) --Font used for titles function PSDrops:Coloring(item) local itemColor = PSDrops.DefaultItemColor local rarity = "Common" for k, i in ipairs(PSDrops.PColors) do if item.Price >= i.minprice then itemColor = i.color rarity = i.rarity break end end return itemColor, rarity end net.Receive("net_PSDropMenu", function() local item_id = net.ReadString() PSDrops:Overlay(item_id) end) net.Receive("net_PSDropChat", function() local ply = net.ReadEntity() local item_id = net.ReadString() PSDrops:Chat(ply, item_id) end) net.Receive("net_PSUnboxClient", function() local ply = net.ReadEntity() local item_id = net.ReadString() PSDrops:ChatUnbox(ply, item_id) end) function PSDrops:Chat(ply, item_id) local item = PS.Items[item_id] local itemColor, rarity = PSDrops:Coloring(item) if ply:GetNWBool("NoAccount") then chat.AddText( Color(0,255,0), "[PSDrops] ", Color(255,255,255), ply:Nick().." would have found ", itemColor, item.Name, Color(255,255,255), " but he has no linked forum account!" ) else chat.AddText( Color(0,255,0), '[PSDrops] ', Color(255,255,255), ply:Nick().." has just found ", itemColor, rarity.." Crate", Color(255,255,255), "!" ) surface.PlaySound( PSDrops.AnnounceSound ) end end function PSDrops:ChatUnbox(ply, item_id) local item = PS.Items[item_id] local itemColor, rarity = PSDrops:Coloring(item) chat.AddText( Color(0,255,0), '[PSDrops] ', Color(255,255,255), ply:Nick().." has just unboxed ", itemColor, item.Name, Color(255,255,255), "!" ) end function PSDrops:Overlay(item_id) local item = PS.Items[item_id] local itemColor, rarity = PSDrops:Coloring(item) if IsValid(PSDropsOverlay) then PSDropsOverlay:Close() end surface.PlaySound("vo/coast/odessa/female01/nlo_cheer03.wav") local w, h = 170, 100 PSDropsOverlay = vgui.Create( "DFrame" ) PSDropsOverlay:SetSize( w, h ) PSDropsOverlay:SetPos(ScrW()-PSDropsOverlay:GetWide(), 200) PSDropsOverlay:SetDraggable( false ) PSDropsOverlay:ShowCloseButton( false ) PSDropsOverlay.btnMaxim:SetVisible( false ) PSDropsOverlay.btnMinim:SetVisible( false ) PSDropsOverlay:SetTitle( "" ) PSDropsOverlay.Paint = function() draw.RoundedBox( 8, 0, 0, w, h, Color(0,0,0,100) ) end PSDropsOverlay.DoClick = function() PSDrops:Menu(item_id) PSDropsOverlay:Close() end PSBoxModel = vgui.Create('DModelPanel', PSDropsOverlay) PSBoxModel:SetModel("models/items/item_item_crate.mdl") PSBoxModel:SetSize(100,100) local PrevMins, PrevMaxs = PSBoxModel.Entity:GetRenderBounds() PSBoxModel:SetCamPos(PrevMins:Distance(PrevMaxs) * Vector(0.6, 0.6, 0.6)) PSBoxModel:SetLookAt((PrevMaxs + PrevMins) / 2) PSBoxModel.DoClick = function() PSDrops:Menu(item_id) PSDropsOverlay:Close() end PSBoxModel:Center() PSDropOFound = vgui.Create("DLabel", PSDropsOverlay) PSDropOFound:SetText("Click here to unbox your item!") PSDropOFound:SetFont("PSDropsFont18") PSDropOFound:SetColor(itemColor) PSDropOFound:SizeToContents() PSDropOFound:SetPos(10,10) PSDropOFound.DoClick = function() PSDrops:Menu(item_id) PSDropsOverlay:Close() end -- And lets close it 60 seconds later if they don't click it for good measure. timer.Simple(60, function() if IsValid(PSDropsOverlay) then PSDropsOverlay:Close() end end) end function PSDrops:Menu(item_id) local item = PS.Items[item_id] local itemColor, rarity = PSDrops:Coloring(item) net.Start( "net_PSUnBoxServer" ) net.WriteEntity(LocalPlayer()) net.WriteString(item_id) net.SendToServer() if not LocalPlayer() then return end if LocalPlayer():GetNWBool("NoAccount") then return end surface.PlaySound( "physics/wood/wood_crate_break4.wav" ) if IsValid(PSDropsMainWindow) then PSDropsMainWindow:Close() end PSDropsMainWindow = vgui.Create( "DFrame" ) PSDropsMainWindow:SetSize( ScrW(), ScrH() ) PSDropsMainWindow:Center() PSDropsMainWindow:SetDraggable( false ) PSDropsMainWindow:ShowCloseButton( true ) PSDropsMainWindow.btnMaxim:SetVisible( false ) PSDropsMainWindow.btnMinim:SetVisible( false ) PSDropsMainWindow:SetTitle( "" ) PSDropsMainWindow:SetBackgroundBlur( true ) PSDropsMainWindow.Paint = PSDrops.PaintMainWindow PSDropsMainWindow:MakePopup() PSDropsCanvasBorder = vgui.Create('DPanel', PSDropsMainWindow) PSDropsCanvasBorder:SetPos(ScrW()/2-210, ScrH()/2-160) PSDropsCanvasBorder:SetSize(420,320) function PSDropsCanvasBorder:Paint(w,h) draw.RoundedBox(6,0,0,w,h,PSDrops.CanvasBorderColor) end PSDropsCanvas = vgui.Create('DPanel', PSDropsMainWindow) PSDropsCanvas:SetPos(ScrW()/2-200, ScrH()/2-150) PSDropsCanvas:SetSize(400,300) function PSDropsCanvas:Paint(w,h) draw.RoundedBox(6,0,0,w,h,PSDrops.CanvasColor) end PSDropCategory = vgui.Create("DLabel", PSDropsMainWindow) PSDropCategory:SetText("Category: "..item.Category) PSDropCategory:SetFont("PSDropsFont32") PSDropCategory:SizeToContents() PSDropCategory:Center() PSDropCategory:SetPos(ScrW()/2-(PSDropCategory:GetWide()/2), ScrH()/2+(PSDropsCanvas:GetTall()/2)) PSDropCategory:SetColor(color_white) PSDropItem = vgui.Create("DLabel", PSDropsMainWindow) PSDropItem:SetText(item.Name) PSDropItem:SetFont("PSDropsFont70") PSDropItem:SizeToContents() PSDropItem:Center() PSDropItem:SetPos(ScrW()/2-(PSDropItem:GetWide()/2), ScrH()/2-((PSDropItem:GetTall()/2)+110)) PSDropItem:SetColor(itemColor) if item.AdminOnly then PSDropAdminOnly = vgui.Create("DLabel", PSDropsMainWindow) PSDropAdminOnly:SetText("This Item is Admin Equippable only!") PSDropAdminOnly:SetFont("PSDropsFont70") PSDropAdminOnly:SizeToContents() PSDropAdminOnly:Center() PSDropAdminOnly:SetPos(ScrW()/2-(PSDropAdminOnly:GetWide()/2), ScrH()/2+(PSDropsCanvas:GetTall()/2)+80) PSDropAdminOnly:SetColor(color_white) end PSDropsItemBorder = vgui.Create('DPanel', PSDropsMainWindow) PSDropsItemBorder:SetPos(ScrW()/2-105, ScrH()/2-85) PSDropsItemBorder:SetSize(210,210) function PSDropsItemBorder:Paint(w,h) draw.RoundedBox(6,0,0,w,h,PSDrops.CanvasBorderColor) end local itemPanel = vgui.Create( 'DPointShopItem', PSDropsMainWindow ) itemPanel:SetData( item ) itemPanel:SetSize( 200, 200 ) itemPanel:SetPos( (ScrW()/2)-100, (ScrH()/2)-80 ) -- Let's overwrite this so we can add our own functionality. ALSO, when using original, it allows people to equip donator/Admin items for some stupid reason. itemPanel.DoClick = function() local points = PS.Config.CalculateBuyPrice(LocalPlayer(), item) if not LocalPlayer():PS_HasItem(item.ID) and not LocalPlayer():PS_HasPoints(points) then notification.AddLegacy("You don't have enough points for this!", NOTIFY_GENERIC, 5) end local menu = DermaMenu(item) if LocalPlayer():PS_HasItem(item.ID) then menu:AddOption('Sell', function() Derma_Query('Are you sure you want to sell ' .. item.Name .. '?', 'Sell Item', 'Yes', function() LocalPlayer():PS_SellItem(item.ID) end, 'No', function() end ) end) menu:AddSpacer() if LocalPlayer():PS_HasItemEquipped(item.ID) then menu:AddOption('Holster', function() LocalPlayer():PS_HolsterItem(item.ID) end) else if not item.AdminOnly or (item.AdminOnly and LocalPlayer():IsAdmin()) then menu:AddOption('Equip', function() LocalPlayer():PS_EquipItem(item.ID) end) else menu:AddOption('Equip', function() notification.AddLegacy("This Item is Admin Equippable only!", NOTIFY_GENERIC, 5) end) end end if LocalPlayer():PS_HasItemEquipped(item.ID) and item.Modify then menu:AddSpacer() menu:AddOption('Modify...', function() PS.Items[item.ID]:Modify(LocalPlayer().PS_Items[item.ID].Modifiers) end) end end menu:Open() end end function PSDrops.PaintMainWindow() //Paint window itself Derma_DrawBackgroundBlur(PSDropsMainWindow) surface.SetDrawColor(PSDrops.WindowColor) PSDrops.CurrentHeight = ScrH() surface.DrawRect(0, 50, ScrW(), PSDrops.CurrentHeight) //Banner heading surface.SetDrawColor( PSDrops.BannerColor ); surface.DrawRect( 0, 0, ScrW(), 75 ); draw.DrawText("Congratulations! You have found:", "PSDropsFont70", 10, 7, color_white, TEXT_ALIGN_LEFT) end end print("PSDrops:System Loaded (By Phoenixf129)!")