Skip to content

Commit b0d629d

Browse files
committed
doubleclick actions
some actions for base_class: rename, expand/collapse, show/hide, write notes some are class-specific: hitscan shoot, sound play/stop, command execute, event invert... some are event-specific: timerx reset, command trigger, flashlight toggle you can revert to only the base_class actions or ignore the base_class actions and only trigger actions when a specific action exists for the part the options are in menu bar and node expander
1 parent a758913 commit b0d629d

File tree

13 files changed

+276
-2
lines changed

13 files changed

+276
-2
lines changed

lua/pac3/core/client/base_part.lua

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,135 @@ do -- scene graph
606606
end
607607
end
608608

609+
local pac_doubleclick_type = CreateClientConVar("pac_doubleclick_action", "expand", true, true, "What function should be run if you double-click on a part node.\n\nexpand : expand or collapse the node\nrename : rename the part\nnotes : write notes for the part\nshowhide : shows or hides the part\nspecific_only : only trigger class-specific actions, such as playing sounds, triggering hitscans, etc.\nnone : disable double-click actions")
610+
611+
function PART:OnDoubleClickBaseClass()
612+
pace.doubleclickfunc = pac_doubleclick_type:GetString()
613+
if pace.doubleclickfunc == "specific_only" then return end
614+
615+
pace.FlashNotification("double click action : " .. pace.doubleclickfunc)
616+
617+
if pace.doubleclickfunc == "expand" then
618+
if not self:HasChildren() then return end
619+
self:SetEditorExpand(not self:GetEditorExpand())
620+
pace.RefreshTree()
621+
elseif pace.doubleclickfunc == "rename" then
622+
local pnl = vgui.Create("DTextEntry")
623+
pnl:SetFont(pace.CurrentFont)
624+
pnl:SetDrawBackground(false)
625+
pnl:SetDrawBorder(false)
626+
pnl:SetText(self:GetName())
627+
pnl:SetKeyboardInputEnabled(true)
628+
pnl:RequestFocus()
629+
pnl:SelectAllOnFocus(true)
630+
631+
local hookID = tostring({})
632+
local textEntry = pnl
633+
local delay = os.clock() + 0.3
634+
635+
local old_name = self:GetName()
636+
637+
pac.AddHook('Think', hookID, function(code)
638+
if not IsValid(textEntry) then return pac.RemoveHook('Think', hookID) end
639+
if textEntry:IsHovered() then return end
640+
if delay > os.clock() then return end
641+
if not input.IsMouseDown(MOUSE_LEFT) and not input.IsKeyDown(KEY_ESCAPE) then return end
642+
pac.RemoveHook('Think', hookID)
643+
textEntry:Remove()
644+
pnl:OnEnter()
645+
end)
646+
647+
--local x,y = pnl:GetPos()
648+
--pnl:SetPos(x+3,y-4)
649+
--pnl:Dock(FILL)
650+
local x, y = self.pace_tree_node.Label:LocalToScreen()
651+
local inset_x = self.pace_tree_node.Label:GetTextInset()
652+
pnl:SetPos(x + inset_x, y)
653+
pnl:SetSize(self.pace_tree_node.Label:GetSize())
654+
pnl:SetWide(ScrW())
655+
pnl:MakePopup()
656+
657+
pnl.OnEnter = function()
658+
local input_text = pnl:GetText()
659+
pnl:Remove()
660+
if old_name == input_text then return end
661+
self:SetName(input_text)
662+
if self.pace_tree_node then
663+
if input_text ~= "" then
664+
self.pace_tree_node:SetText(input_text)
665+
else
666+
timer.Simple(0, function()
667+
self.pace_tree_node:SetText(self:GetName())
668+
end)
669+
end
670+
end
671+
pace.PopulateProperties(self)
672+
end
673+
674+
local old = pnl.Paint
675+
pnl.Paint = function(...)
676+
if not self:IsValid() then pnl:Remove() return end
677+
678+
surface.SetFont(pnl:GetFont())
679+
local w = surface.GetTextSize(pnl:GetText()) + 6
680+
681+
surface.DrawRect(0, 0, w, pnl:GetTall())
682+
surface.SetDrawColor(self.pace_tree_node:GetSkin().Colours.Properties.Border)
683+
surface.DrawOutlinedRect(0, 0, w, pnl:GetTall())
684+
685+
pnl:SetWide(w)
686+
687+
old(...)
688+
end
689+
elseif pace.doubleclickfunc == "notes" then
690+
if IsValid(pace.notes_pnl) then
691+
pace.notes_pnl:Remove()
692+
end
693+
local pnl = vgui.Create("DFrame")
694+
pace.notes_pnl = pnl
695+
local DText = vgui.Create("DTextEntry", pnl)
696+
local DButtonOK = vgui.Create("DButton", pnl)
697+
DText:SetMaximumCharCount(50000)
698+
699+
pnl:SetSize(1200,800)
700+
pnl:SetTitle("Long text with newline support for Notes.")
701+
pnl:Center()
702+
DButtonOK:SetText("OK")
703+
DButtonOK:SetSize(80,20)
704+
DButtonOK:SetPos(500, 775)
705+
DText:SetPos(5,25)
706+
DText:SetSize(1190,700)
707+
DText:SetMultiline(true)
708+
DText:SetContentAlignment(7)
709+
pnl:MakePopup()
710+
DText:RequestFocus()
711+
DText:SetText(self:GetNotes())
712+
713+
DButtonOK.DoClick = function()
714+
self:SetNotes(DText:GetText())
715+
pace.RefreshTree(true)
716+
pnl:Remove()
717+
end
718+
elseif pace.doubleclickfunc == "showhide" then
719+
self:SetHide(not self:GetHide())
720+
end
721+
end
722+
723+
local pac_doubleclick_specified = CreateClientConVar("pac_doubleclick_action_specified", "2", true, true, "Whether the base_part functions for double-click should be replaced by specific functions when available.\n\nset to 0 : only use base_class actions (expand, rename, notes, showhide)\nset to 1 : Use specific actions. most single-shot parts will trigger (sounds play, commands run, hitscans fire etc.), and events will invert\nset to 2 : When appropriate, some event types will have even more specific actions. command events trigger or toggle (depending on the time), is_flashlight_on will toggle the flashlight, timerx events will reset\n\nIf your selected base action is none, These won't trigger.\n\nIf you only want specific actions, you may select specific_only in the pac_doubleclick_action command if you only want specifics")
724+
function PART:OnDoubleClickSpecified()
725+
--override
726+
end
727+
728+
function PART:DoDoubleClick()
729+
pace.doubleclickfunc = pac_doubleclick_type:GetString()
730+
if pace.doubleclickfunc == "none" or pace.doubleclickfunc == "" then return end
731+
if pac_doubleclick_specified:GetInt() ~= 0 and self.ImplementsDoubleClickSpecified then
732+
pace.FlashNotification("double click action : class-specific")
733+
self:OnDoubleClickSpecified()
734+
else
735+
self:OnDoubleClickBaseClass()
736+
end
737+
end
609738
end
610739

611740
do -- hidden / events

lua/pac3/core/client/parts/command.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ PART.ClassName = "command"
55
PART.Group = "advanced"
66
PART.Icon = "icon16/application_xp_terminal.png"
77

8+
PART.ImplementsDoubleClickSpecified = true
9+
810
BUILDER:StartStorableVars()
911

1012
BUILDER:SetPropertyGroup("generic")
@@ -312,4 +314,6 @@ function PART:Execute(commandstring)
312314
end
313315
end
314316

317+
PART.OnDoubleClickSpecified = PART.Execute
318+
315319
BUILDER:Register()

lua/pac3/core/client/parts/damage_zone.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ PART.ClassName = "damage_zone"
66
PART.Group = "combat"
77
PART.Icon = "icon16/package.png"
88

9+
PART.ImplementsDoubleClickSpecified = true
10+
911
local renderhooks = {
1012
"PostDraw2DSkyBox",
1113
"PostDrawOpaqueRenderables",
@@ -682,6 +684,10 @@ function PART:OnShow()
682684
end
683685
end
684686

687+
function PART:OnDoubleClickSpecified()
688+
self:SendNetMessage()
689+
end
690+
685691
local dmgzone_requesting_corpses = {}
686692
function PART:SetAttachPartsToTargetEntity(b)
687693
self.AttachPartsToTargetEntity = b

lua/pac3/core/client/parts/event.lua

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ PART.ThinkTime = 0
1717
PART.AlwaysThink = true
1818
PART.Icon = 'icon16/clock.png'
1919

20+
PART.ImplementsDoubleClickSpecified = true
21+
2022
BUILDER:StartStorableVars()
2123
BUILDER:GetSet("Event", "", {enums = function(part)
2224
local output = {}
@@ -45,6 +47,36 @@ PART.Tutorials = {}
4547
local registered_command_event_series = {}
4648
local event_series_bounds = {}
4749

50+
function PART:OnDoubleClickSpecified()
51+
if GetConVar("pac_doubleclick_specified"):GetInt() == 1 then
52+
self:SetInvert(not self:GetInvert())
53+
pace.PopulateProperties(self)
54+
return
55+
end
56+
57+
if self.Event == "command" then
58+
local cmd, time, hide = self:GetParsedArgumentsForObject(self.Events.command)
59+
if time == 0 then --toggling mode
60+
pac.LocalPlayer.pac_command_events[cmd] = pac.LocalPlayer.pac_command_events[cmd] or {name = cmd, time = pac.RealTime, on = 0}
61+
----MORE PAC JANK?? SOMETIMES, THE 2 NOTATION DOESN'T CHANGE THE STATE YET
62+
if pac.LocalPlayer.pac_command_events[cmd].on == 1 then
63+
RunConsoleCommand("pac_event", cmd, "0")
64+
else
65+
RunConsoleCommand("pac_event", cmd, "1")
66+
end
67+
else
68+
RunConsoleCommand("pac_event", cmd)
69+
end
70+
elseif self.Event == "is_flashlight_on" then
71+
RunConsoleCommand("impulse", "100")
72+
elseif self.Event == "timerx" or self.Event == "timerx2" then
73+
self.time = nil
74+
else
75+
self:SetInvert(not self:GetInvert())
76+
pace.PopulateProperties(self)
77+
end
78+
end
79+
4880
function PART:register_command_event(str,b)
4981
local ply = self:GetPlayerOwner()
5082

@@ -3411,12 +3443,27 @@ function PART:GetParentEx()
34113443
return self:GetParent()
34123444
end
34133445

3446+
function PART:GetTargetingModePrefix()
3447+
local modes = {}
3448+
if self.AffectChildrenOnly then
3449+
table.insert(modes, "ACO")
3450+
end
3451+
if IsValid(self:GetDestinationPart()) then
3452+
table.insert(modes, "TP")
3453+
end
3454+
if self.MultiTargetPart then
3455+
table.insert(modes, "MTP")
3456+
end
3457+
if table.IsEmpty(modes) then return "" end
3458+
return "[" .. table.concat(modes, " ") .. "] "
3459+
end
3460+
34143461
function PART:GetNiceName()
34153462
local event_name = self:GetEvent()
34163463

34173464
if not PART.Events[event_name] then return "unknown event" end
34183465

3419-
return PART.Events[event_name]:GetNiceName(self, get_owner(self))
3466+
return self:GetTargetingModePrefix() .. PART.Events[event_name]:GetNiceName(self, get_owner(self))
34203467
end
34213468

34223469
local function is_hidden_by_something_else(part, ignored_part)

lua/pac3/core/client/parts/force.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ PART.Icon = "icon16/database_go.png"
77
PART.ManualDraw = true
88
PART.HandleModifiersManually = true
99

10+
PART.ImplementsDoubleClickSpecified = true
11+
1012
BUILDER:StartStorableVars()
1113
:SetPropertyGroup("AreaShape")
1214
:GetSet("HitboxMode", "Box", {enums = {
@@ -97,6 +99,10 @@ function PART:OnShow()
9799
self:Impulse(true)
98100
end
99101

102+
function PART:OnDoubleClickSpecified()
103+
self:Impulse(true)
104+
end
105+
100106
function PART:OnHide()
101107
pac.RemoveHook("PostDrawOpaqueRenderables", "pac_force_Draw"..self.UniqueID)
102108
self:Impulse(false)

lua/pac3/core/client/parts/hitscan.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ PART.ClassName = "hitscan"
99
PART.Group = "combat"
1010
PART.Icon = "icon16/user_gray.png"
1111

12+
PART.ImplementsDoubleClickSpecified = true
13+
1214
BUILDER:StartStorableVars()
1315
:GetSet("ServerBullets", true, {description = "serverside bullets can do damage and exert a physical impact force"})
1416
:SetPropertyGroup("bullet properties")
@@ -130,6 +132,10 @@ function PART:Shoot()
130132
end
131133
end
132134

135+
function PART:OnDoubleClickSpecified()
136+
self:Shoot()
137+
end
138+
133139

134140
--NOT THE ACTUAL DAMAGE TYPES. UNIQUE IDS TO COMPRESS NET MESSAGES
135141
local damage_ids = {

lua/pac3/core/client/parts/legacy/sound.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ PART.ThinkTime = 0
88
PART.Group = 'effects'
99
PART.Icon = 'icon16/sound.png'
1010

11+
PART.ImplementsDoubleClickSpecified = true
12+
1113
BUILDER:StartStorableVars()
1214
BUILDER:SetPropertyGroup("generic")
1315
BUILDER:GetSet("Sound", "")
@@ -329,6 +331,16 @@ function PART:StopSound(force_stop)
329331
end
330332
end
331333

334+
function PART:OnDoubleClickSpecified()
335+
if self.playing then
336+
self:StopSound(true)
337+
self.playing = false
338+
else
339+
self:PlaySound()
340+
self.playing = true
341+
end
342+
end
343+
332344
local channels =
333345
{
334346
CHAN_AUTO = 0,

lua/pac3/core/client/parts/lock.lua

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ PART.ClassName = "lock"
4040
PART.Group = "combat"
4141
PART.Icon = "icon16/lock.png"
4242

43+
PART.ImplementsDoubleClickSpecified = true
4344

4445
BUILDER:StartStorableVars()
4546
:SetPropertyGroup("Behaviour")
@@ -436,6 +437,12 @@ function PART:OnShow()
436437
end
437438
end
438439

440+
function PART:OnDoubleClickSpecified()
441+
if self.Mode ~= "Grab" then
442+
self:OnShow()
443+
end
444+
end
445+
439446
function PART:OnHide()
440447
pac.RemoveHook("PostDrawOpaqueRenderables", "pace_draw_lockpart_preview"..self.UniqueID)
441448
self.teleported = false

lua/pac3/core/client/parts/projectile.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ PART.ClassName = "projectile"
1818
PART.Group = {"advanced", "combat"}
1919
PART.Icon = "icon16/bomb.png"
2020

21+
PART.ImplementsDoubleClickSpecified = true
22+
2123
BUILDER:StartStorableVars()
2224
BUILDER:SetPropertyGroup("Firing")
2325
BUILDER:GetSet("Speed", 1)
@@ -446,6 +448,10 @@ function PART:Shoot(pos, ang, multi_projectile_count)
446448
end
447449
end
448450

451+
function PART:OnDoubleClickSpecified()
452+
self:Shoot()
453+
end
454+
449455
function PART:SetRadius(val)
450456
self.Radius = val
451457
local sv_dist = GetConVar("pac_sv_projectile_max_phys_radius"):GetInt()

lua/pac3/core/client/parts/sound.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ PART.ClassName = "sound2"
88
PART.Icon = 'icon16/music.png'
99
PART.Group = 'effects'
1010

11+
PART.ImplementsDoubleClickSpecified = true
1112

1213
BUILDER:StartStorableVars()
1314
BUILDER:SetPropertyGroup("generic")
@@ -359,6 +360,16 @@ function PART:OnShow(from_rendering)
359360
self.stopsound = false
360361
end
361362

363+
function PART:OnDoubleClickSpecified()
364+
if self.playing then
365+
self:StopSound(true)
366+
self.playing = false
367+
else
368+
self:PlaySound()
369+
self.playing = true
370+
end
371+
end
372+
362373
function PART:OnHide()
363374
self:StopSound()
364375
end

0 commit comments

Comments
 (0)