I Need Help with Modifying the DarkRP Notifications
9 replies, posted
Basically I want to make my own DarkRP Notifications (e.g. "Payday! You received $45!").
What I tried so far works fine if there is only one notification but as soon as there is more than one it bugs out.
I spent about 8 hours trying to make it work properly but now I got no more ideas and I hope some of you can help me.
[video]https://youtu.be/vsrvmw0snxE[/video]
I apologize for the messy code but I hope it is not too hard to read. :smile:
[CODE]/*---------------------------------------------------------------------------
Display notifications
---------------------------------------------------------------------------*/
NotifyText={}
panelNoti={}
local function DisplayNotify(msg)
local txt = msg:ReadString()
table.insert(NotifyText,txt)
PrintTable(NotifyText) -- debug
for k,v in pairs(NotifyText) do
if CLIENT then
panelNotiTex= v
panelNotiLen = string.len(panelNotiTex)*5+50
--print(panelNotiLen) -- debug
panelNoti = vgui.Create( "DPanel")
panelNoti:SetSize(panelNotiLen,60)
panelNoti:SetPos(30,30)
function panelNoti:Paint(w,h)
if IsValid(panelNoti) then
--panelNoti:Remove()
--hook.Remove( "Think", "ProgBar1" )
--panelNoti:Remove()
--table.remove(NotifyText,k)
panelNoti:SetPos(30,k*30)
end -- if IsValid(panelNoti)
surface.SetDrawColor(255,255,55)
surface.DrawRect(30,30,panelNotiLen,60)
surface.SetTextColor(255,0,0)
surface.SetTextPos(40,35)
surface.DrawText(panelNotiTex)
end -- function panelNoti:Paint
timer.Create( "panelNotiTime", 3, 1, function ()
for k,v in pairs(NotifyText) do
if IsValid(panelNoti) then panelNoti:Remove() end
table.remove(NotifyText,k)
table.remove(NotifyText,k-1)
if IsValid(panelNotiB) then panelNotiB:Remove() end
if not IsValid(panelNotiB) then hook.Remove( "Think", "ProgBar1" ) end
end--for k,v (line 429)
end) --timer.Create( "panelNotiTime"...
if timer.TimeLeft( "panelNotiTime" ) > 0 and IsValid(panelNoti) and panelNoti:IsVisible() then
function ProgBar1 ()
NotProg = timer.TimeLeft( "panelNotiTime" )/3
local panelNotiB = vgui.Create( "DProgress",panelNoti )
panelNotiB:SetPos( 30, 55 )
panelNotiB:SetSize(panelNotiLen,5)
panelNotiB:SetFraction( NotProg )
panelNotiB:SetParent(panelNoti)
function panelNotiB:Paint(w,h)
surface.SetDrawColor(255,0,0)
surface.DrawRect(0,0,NotProg*panelNotiLen,h)
end --function panelNotiB:Paint(w,h)
end --function ProgBar1 ()
hook.Add("Think", "ProgBar1", ProgBar1)
end -- if timer.TimeLeft( "panelNotiTime" )
end -- if client
end -- for k,v (line 389)
surface.PlaySound("buttons/lightswitch2.wav")
-- Log to client console
MsgC(Color(255, 20, 20, 255), "[DarkRP] ", Color(200, 200, 200, 255), txt, "\n")
end --function DisplayNotify(msg)
usermessage.Hook("_Notify", DisplayNotify)
[/CODE]
*Bump*
Don't use timers. When you create a timer with the same name, the previous timers with that name stop working.
[QUOTE=Neat-Nit;50117699]Don't use timers. When you create a timer with the same name, the previous timers with that name stop working.[/QUOTE]
How am I supposed to do it instead?
Here is a good example: [url]https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/includes/modules/notification.lua#L88-L131[/url]
[QUOTE=Neat-Nit;50117772]Here is a good example: [url]https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/includes/modules/notification.lua#L88-L131[/url][/QUOTE]
Thanks. I decided to use that example to modify all notifications first.
But I need some help with the progress bars (time left) which I want to add to every notification.
I managed to add a progress bar to every notification but if there are multiple notifications on the screen, all progress bars are using the time of the last notification that appeared.
The part I edited starts at "function Progbar2()"
[CODE]
surface.CreateFont( "GModNotify", {
font = "marlett",
size = 19,
weight = 1000
} )
NOTIFY_GENERIC = 0
NOTIFY_ERROR = 1
NOTIFY_UNDO = 2
NOTIFY_HINT = 3
NOTIFY_CLEANUP = 4
module( "notification", package.seeall )
local NoticeMaterial = {}
NoticeMaterial[ NOTIFY_GENERIC ] = Material( "vgui/notices/generic" )
NoticeMaterial[ NOTIFY_ERROR ] = Material( "vgui/notices/error" )
NoticeMaterial[ NOTIFY_UNDO ] = Material( "vgui/notices/undo" )
NoticeMaterial[ NOTIFY_HINT ] = Material( "vgui/notices/hint" )
NoticeMaterial[ NOTIFY_CLEANUP ] = Material( "vgui/notices/cleanup" )
local Notices = {}
function AddProgress( uid, text )
if ( IsValid( Notices[ uid ] ) ) then
Notices[ uid ].StartTime = SysTime()
Notices[ uid ].Length = 1000000
Notices[ uid ]:SetText( text )
Notices[ uid ]:SetProgress()
return
end
local parent = nil
if ( GetOverlayPanel ) then parent = GetOverlayPanel() end
local Panel = vgui.Create( "NoticePanel", parent )
Panel.StartTime = SysTime()
Panel.Length = 1000000
Panel.VelX = -5
Panel.VelY = 0
Panel.fx = ScrW() + 200
Panel.fy = ScrH()
Panel:SetAlpha( 255 )
Panel:SetText( text )
Panel:SetPos( Panel.fx, Panel.fy )
Panel:SetProgress()
Notices[ uid ] = Panel
end
function Kill( uid )
if ( !IsValid( Notices[ uid ] ) ) then return end
Notices[ uid ].StartTime = SysTime()
Notices[ uid ].Length = 0.8
end
function AddLegacy( text, type, length )
local parent = nil
if ( GetOverlayPanel ) then parent = GetOverlayPanel() end
local Panel = vgui.Create( "NoticePanel", parent )
Panel.StartTime = SysTime()
Panel.Length = length
Panel.VelX = -5
Panel.VelY = 0
Panel.fx = ScrW() + 200
Panel.fy = ScrH()
Panel:SetAlpha( 255 )
Panel:SetText( text )
Panel:SetLegacyType( type )
Panel:SetPos( Panel.fx, Panel.fy )
table.insert( Notices, Panel )
text123 = text
end
-- This is ugly because it's ripped straight from the old notice system
local function UpdateNotice( i, Panel, Count )
local x = Panel.fx
local y = Panel.fy
local w = Panel:GetWide() + 16
local h = Panel:GetTall() + 16
local ideal_y = ScrH() - ( Count - i ) * ( h - 12 ) - 150
local ideal_x = ScrW() - w - 20
local timeleft = Panel.StartTime - ( SysTime() - Panel.Length )
-- Cartoon style about to go thing
if ( timeleft < 0.7 ) then
ideal_x = ideal_x - 50
end
-- Gone!
if ( timeleft < 0.2 ) then
ideal_x = ideal_x + w * 2
end
local spd = FrameTime() * 15
y = y + Panel.VelY * spd
x = x + Panel.VelX * spd
local dist = ideal_y - y
Panel.VelY = Panel.VelY + dist * spd * 1
if ( math.abs( dist ) < 2 && math.abs( Panel.VelY ) < 0.1 ) then Panel.VelY = 0 end
dist = ideal_x - x
Panel.VelX = Panel.VelX + dist * spd * 1
if ( math.abs( dist ) < 2 && math.abs( Panel.VelX ) < 0.1 ) then Panel.VelX = 0 end
-- Friction.. kind of FPS independant.
Panel.VelX = Panel.VelX * ( 0.95 - FrameTime() * 8 )
Panel.VelY = Panel.VelY * ( 0.95 - FrameTime() * 8 )
Panel.fx = x
Panel.fy = y
Panel:SetPos( Panel.fx, Panel.fy )
for k, Panel in pairs( Notices ) do
local timeleft = Panel.StartTime - ( SysTime() - Panel.Length )
PanelProgBleft = timeleft
end
local function Update()
if ( !Notices ) then return end
local i = 0
local Count = table.Count( Notices )
for key, Panel in pairs( Notices ) do
i = i + 1
UpdateNotice( i, Panel, Count )
end
for k, Panel in pairs( Notices ) do
if ( !IsValid( Panel ) || Panel:KillSelf() ) then Notices[ k ] = nil end
end
end
hook.Add( "Think", "NotificationThink", Update )
local PANEL = {}
--[[---------------------------------------------------------
Name: Init
-----------------------------------------------------------]]
function PANEL:Init()
self:DockPadding( 3, 3, 3, 3 )
self.Label = vgui.Create( "DLabel", self )
self.Label:Dock( FILL )
self.Label:SetFont( "GModNotify" )
self.Label:SetTextColor( Color( 255, 255, 255, 255 ) )
self.Label:SetExpensiveShadow( 1, Color( 0, 0, 0, 200 ) )
self.Label:SetContentAlignment( 5 )
self:SetBackgroundColor( Color( 20, 20, 20, 255 * 0.9 ) )
function self:Paint(w,h)
surface.SetDrawColor(75,75,75,255*0.9)
surface.DrawRect(0,0,w,h)
surface.SetDrawColor(0,100,255,255*0.9)
surface.DrawRect(0,0,40,50)
function Progbar2()
local panelNotiB = vgui.Create( "DProgress",self)
panelNotiB:SetPos( 0, 0 )
panelNotiB:SetSize(PanelProgBleft*5,10) --PanelProgBleft=TimeLeft
panelNotiB:SetFraction( 0.75 )
panelNotiB:SetParent(self)
function panelNotiB:Paint(w,h)
surface.SetDrawColor(255,0,0)
surface.DrawRect(0,0,PanelProgBleft*5,h)
--print("Test") -- debug
end
print(PanelProgBleft) --debug
end
hook.Add("Think", "Progbar2", Progbar2)
end
end
function PANEL:SetText( txt )
self.Label:SetText( txt )
self:SizeToContents()
end
function PANEL:SizeToContents()
self.Label:SizeToContents()
local width = self.Label:GetWide()
if ( IsValid( self.Image ) ) then
width = width + 32 + 8
end
width = width + 20
self:SetWidth( width )
self:SetHeight( 32 + 6 )
self:InvalidateLayout()
end
function PANEL:SetLegacyType( t )
self.Image = vgui.Create( "DImageButton", self )
self.Image:SetMaterial( NoticeMaterial[ t ] )
self.Image:SetSize( 32, 32 )
self.Image:Dock( LEFT )
self.Image:DockMargin( 0, 0, 8, 0 )
self.Image.DoClick = function()
self.StartTime = 0
end
self:SizeToContents()
end
function PANEL:SetProgress()
-- Quick and dirty, just how I like it.
self.Paint = function( s, w, h )
self.BaseClass.Paint( self, w, h )
surface.SetDrawColor( 100, 0, 0, 150 )
surface.DrawRect( 4, self:GetTall() - 10, self:GetWide() - 8, 5 )
surface.SetDrawColor( 0, 0, 50, 255 )
surface.DrawRect( 5, self:GetTall() - 9, self:GetWide() - 10, 3 )
local w = self:GetWide() * 0.25
local x = math.fmod( SysTime() * 200, self:GetWide() + w ) - w
if ( x + w > self:GetWide() - 11 ) then w = ( self:GetWide() - 11 ) - x end
if ( x < 0 ) then w = w + x; x = 0 end
surface.SetDrawColor( 0, 0, 255, 255 )
surface.DrawRect( 5 + x, self:GetTall() - 9, w, 3 )
end
end
function PANEL:KillSelf()
if ( self.StartTime + self.Length < SysTime() ) then
self:Remove()
return true
end
return false
end
vgui.Register( "NoticePanel", PANEL, "DPanel" )
[/CODE]
*bump*
I have no idea what you're doing. Do YOU know what you're doing? I don't think you know what you're doing.
[QUOTE=Neat-Nit;50148001]I have no idea what you're doing. Do YOU know what you're doing? I don't think you know what you're doing.[/QUOTE]
I know what I want to do and I try my best to do it but I'm new to lua so I test everything that comes to my mind.
I basically saw that video: [url]https://www.youtube.com/watch?v=MG6cyXrY1KY[/url]
And want to make something similar. Thats all.
Take a closer look at the code I linked to (default gmod code). It also has a progress bar which works correctly.
Sorry, you need to Log In to post a reply to this thread.