Initial commit
This commit is contained in:
175
lua/includes/modules/widget.lua
Normal file
175
lua/includes/modules/widget.lua
Normal file
@@ -0,0 +1,175 @@
|
||||
|
||||
|
||||
--
|
||||
-- Widgets are like gui controls in the 3D world(!!!)
|
||||
--
|
||||
|
||||
widgets = {}
|
||||
local widgetEntities = {}
|
||||
|
||||
--
|
||||
-- Holds the currently hovered widget
|
||||
--
|
||||
widgets.Hovered = nil
|
||||
widgets.HoveredPos = vector_origin
|
||||
|
||||
--
|
||||
-- Holds the current pressed widget
|
||||
--
|
||||
widgets.Pressed = nil
|
||||
|
||||
local tr = {}
|
||||
local trace = {
|
||||
output = tr,
|
||||
filter = widgetEntities,
|
||||
whitelist = true,
|
||||
}
|
||||
|
||||
local function UpdateHovered( pl )
|
||||
|
||||
if ( !IsValid( pl ) ) then return end
|
||||
|
||||
if ( !pl:Alive() ) then
|
||||
pl:SetHoveredWidget( NULL )
|
||||
return
|
||||
end
|
||||
|
||||
local eyePos = pl:EyePos()
|
||||
local aimVector = pl:GetAimVector()
|
||||
aimVector:Mul( 256 )
|
||||
aimVector:Add( eyePos )
|
||||
|
||||
trace.start = eyePos
|
||||
trace.endpos = aimVector
|
||||
|
||||
-- debugoverlay.Line( trace.start, trace.endpos, 0.5 )
|
||||
|
||||
widgets.Tracing = true
|
||||
util.TraceLine( trace )
|
||||
widgets.Tracing = false
|
||||
|
||||
if ( !IsValid( tr.Entity ) || tr.Entity:IsWorld() ) then
|
||||
pl:SetHoveredWidget( NULL )
|
||||
return
|
||||
end
|
||||
|
||||
-- debugoverlay.Cross( tr.HitPos, 1, 60 )
|
||||
|
||||
pl:SetHoveredWidget( tr.Entity )
|
||||
pl.WidgetHitPos = tr.HitPos
|
||||
|
||||
return tr.Entity
|
||||
|
||||
end
|
||||
|
||||
local function UpdateButton( pl, mv, btn, mousebutton, hvr, prs )
|
||||
|
||||
local now = mv:KeyDown( btn )
|
||||
local was = mv:KeyWasDown( btn )
|
||||
|
||||
if ( now && !was && IsValid( hvr ) ) then
|
||||
hvr:OnPress( pl, mousebutton, mv )
|
||||
end
|
||||
|
||||
if ( !now && was && IsValid( prs ) ) then
|
||||
prs:OnRelease( pl, mousebutton, mv )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--
|
||||
-- The idea here is to have exactly the same
|
||||
-- behaviour on the client as the server.
|
||||
--
|
||||
function widgets.PlayerTick( pl, mv )
|
||||
|
||||
local hvr = UpdateHovered( pl )
|
||||
local prs = pl:GetPressedWidget()
|
||||
|
||||
UpdateButton( pl, mv, IN_ATTACK, 1, hvr, prs )
|
||||
UpdateButton( pl, mv, IN_ATTACK2, 2, hvr, prs )
|
||||
|
||||
if ( IsValid( prs ) ) then
|
||||
prs:PressedThinkInternal( pl, mv )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
---
|
||||
--- Render the widgets!
|
||||
---
|
||||
|
||||
-- Function stub for backwards compatibility
|
||||
function widgets.RenderMe( ent )
|
||||
-- We do this solely for backwards compatibility
|
||||
ent._WantsWidgetRender = true
|
||||
end
|
||||
|
||||
local function RenderWidgets()
|
||||
|
||||
local prs = LocalPlayer():GetPressedWidget()
|
||||
local prsValid = IsValid( prs )
|
||||
|
||||
cam.Start3D( EyePos(), EyeAngles() )
|
||||
|
||||
for _, v in ipairs( widgetEntities ) do
|
||||
|
||||
--
|
||||
-- The pressed widget gets to decide what should draw
|
||||
--
|
||||
if ( prsValid && !prs:PressedShouldDraw( v ) ) then continue end
|
||||
if ( !v._WantsWidgetRender ) then continue end
|
||||
|
||||
v:OverlayRender()
|
||||
v._WantsWidgetRender = nil
|
||||
|
||||
end
|
||||
|
||||
cam.End3D()
|
||||
|
||||
end
|
||||
|
||||
hook.Add( "OnEntityCreated", "CreateWidgets", function( ent )
|
||||
|
||||
timer.Simple( 0.001, function()
|
||||
|
||||
if ( !ent:IsWidget() ) then return end
|
||||
|
||||
table.insert( widgetEntities, ent )
|
||||
hook.Add( "PlayerTick", "TickWidgets", widgets.PlayerTick )
|
||||
|
||||
if ( CLIENT ) then
|
||||
hook.Add( "PostDrawEffects", "RenderWidgets", RenderWidgets )
|
||||
end
|
||||
|
||||
end )
|
||||
|
||||
end )
|
||||
|
||||
hook.Add( "EntityRemoved", "RemoveWidgets", function( ent )
|
||||
|
||||
if ( !ent:IsWidget() ) then return end
|
||||
|
||||
for k, v in next, widgetEntities do
|
||||
if ( v == ent ) then
|
||||
table.remove( widgetEntities, k )
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if ( #widgetEntities == 0 ) then
|
||||
hook.Remove( "PlayerTick", "TickWidgets" )
|
||||
|
||||
if ( CLIENT ) then
|
||||
hook.Remove( "PostDrawEffects", "RenderWidgets" )
|
||||
end
|
||||
end
|
||||
|
||||
end )
|
||||
|
||||
local ENTITY = FindMetaTable( "Entity" )
|
||||
|
||||
function ENTITY:IsWidget()
|
||||
return self.Widget
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user