From 123c8a21dbd6f304f2392efbb7f3101e93c8f7fd Mon Sep 17 00:00:00 2001 From: Twist Date: Fri, 18 Apr 2025 21:27:21 +0100 Subject: [PATCH 01/18] Fixed clip planes lagging behind when parented to a bone on a model part (#1391) Resolves last reported problem on issue #1341 --- lua/pac3/core/client/parts/bone.lua | 15 +++++++++------ lua/pac3/core/client/parts/clip.lua | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lua/pac3/core/client/parts/bone.lua b/lua/pac3/core/client/parts/bone.lua index e3414b447..29526e574 100644 --- a/lua/pac3/core/client/parts/bone.lua +++ b/lua/pac3/core/client/parts/bone.lua @@ -290,12 +290,12 @@ function PART:GetBonePosition() if not self.bone_index then return ent:GetPos(), ent:GetAngles() end local m = ent:GetBoneMatrix(self.bone_index) - if not m then return ent:GetPos(), ent:GetAngles() end - local pos = m:GetTranslation() - local ang = m:GetAngles() - - return pos, ang + if m then + return m:GetTranslation(), m:GetAngles() + else + return ent:GetPos(), ent:GetAngles() + end end function PART:GetBoneMatrix() @@ -306,12 +306,15 @@ BUILDER:Register() pac.AddHook("OnEntityCreated", "hide_mesh_no_crash", function(ent) local ply = ent:GetRagdollOwner() + if ply:IsPlayer() and ply.pac_inf_scale then for i = 0, ply:GetBoneCount() - 1 do local scale = ply:GetManipulateBoneScale(i) + if scale == inf_scale then - scale = Vector(0,0,0) + scale = vector_origin end + ply:ManipulateBoneScale(i, scale) end end diff --git a/lua/pac3/core/client/parts/clip.lua b/lua/pac3/core/client/parts/clip.lua index 7b40e4f0a..7dda463a2 100644 --- a/lua/pac3/core/client/parts/clip.lua +++ b/lua/pac3/core/client/parts/clip.lua @@ -40,6 +40,16 @@ do function PART:PreOnDraw() bclip = render_EnableClipping(true) + -- this fixes clip planes lagging behind when parented to a bone on a model part + local owner = self:GetParentOwner() + if owner:IsValid() and not owner.pac_clip_bonessetup and owner.PACPart then + -- in case there are multiple clips on one model part, only the first one needs to call SetupBones + self.pac_clip_owner = owner + owner.pac_clip_bonessetup = true + + pac.SetupBones(owner) + end + local pos, ang = LocalToWorld(self.Position + self.PositionOffset, self:CalcAngles(self.Angles + self.AngleOffset), self:GetBonePosition()) local normal = ang:Forward() @@ -49,6 +59,11 @@ do local render_PopCustomClipPlane = render.PopCustomClipPlane function PART:PostOnDraw() + if self.pac_clip_owner then + self.pac_clip_owner.pac_clip_bonessetup = nil + self.pac_clip_owner = nil + end + render_PopCustomClipPlane() render_EnableClipping(bclip) From 626cefbb63928f944cf9defe215742deb996f573 Mon Sep 17 00:00:00 2001 From: textstack <46581273+textstack@users.noreply.github.com> Date: Mon, 21 Apr 2025 01:42:51 -0400 Subject: [PATCH 02/18] is no draw and viewer steamid events --- lua/pac3/core/client/parts/event.lua | 39 +++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/lua/pac3/core/client/parts/event.lua b/lua/pac3/core/client/parts/event.lua index f7afde25a..14dce13b9 100644 --- a/lua/pac3/core/client/parts/event.lua +++ b/lua/pac3/core/client/parts/event.lua @@ -384,7 +384,6 @@ function PART:SetMultipleTargetParts(str) end self.ExtraHermites_Property = "MultipleTargetParts" end - end local function get_default(typ) @@ -2884,8 +2883,42 @@ PART.OldEvents = { end return true end, - } + }, + is_no_draw = { + operator_type = "none", + tutorial = "activates when the current entity is flagged with nodraw", + callback = function(self, ent) + return ent:GetNoDraw() + end, + }, + + viewer_steamid = { + operator_type = "string", preferred_operator = "equal", + tutorial = "activates when the local player has the steamID specified", + arguments = {{find = "string"}, {include_owner = "boolean"}}, + callback = function(self, ent, find, include_owner) + if include_owner then + find = find .. ";" .. self:GetOwner():SteamID() + end + + return self:StringOperator(pac.LocalPlayer:SteamID(), find) + end, + nice = function(self, ent, find, include_owner) + local count = #string.Split(find, ";") + + local idSumm + if count == 0 or find == "" then + idSumm = (include_owner and "owner id" or "\"\"") + elseif count == 1 then + idSumm = string.format("\"%s\"%s", find, include_owner and " + owner id" or "") + else + idSumm = string.format("1 of %d entries%s", count, include_owner and " + owner id" or "") + end + + return string.format("steamid: [%s %s]", self.Operator, idSumm) + end + }, } @@ -4732,7 +4765,7 @@ net.Receive("pac_update_healthbars", function(len) if cached_part then tbl[i][cached_part.UniqueID] = value end - + end end --PrintTable(tbl) From cfee8d2080533b9603e316f2654defea99485be6 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Fri, 25 Apr 2025 19:38:02 -0400 Subject: [PATCH 03/18] update the proxy expressions panel class now uses the auto-scrolling behavior quick setup option to clone model for layering small fix (prevents using properties without a getter when gathering the backup properties before opening bulk morph properties menu) --- .../editor/client/panels/extra_properties.lua | 33 ++++++++++++++++++- lua/pac3/editor/client/parts.lua | 13 +++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/lua/pac3/editor/client/panels/extra_properties.lua b/lua/pac3/editor/client/panels/extra_properties.lua index de6c5e955..66fd611cf 100644 --- a/lua/pac3/editor/client/panels/extra_properties.lua +++ b/lua/pac3/editor/client/panels/extra_properties.lua @@ -1257,7 +1257,10 @@ do -- script proxy pnl.Paint = function(...) if not self:IsValid() then pnl:Remove() return end local x, y = self:LocalToScreen() - y = math.Clamp(y,0,ScrH() - self:GetTall()) + local _,prop_y = pace.properties:LocalToScreen(0,0) + local overflow = y < prop_y or y > ScrH() - self:GetTall() + y = math.Clamp(y,prop_y,ScrH() - self:GetTall()) + pnl:SetPos(x + 5 + inset_x, y) surface.SetFont(pnl:GetFont()) local w = surface.GetTextSize(pnl:GetText()) + 6 @@ -1271,6 +1274,34 @@ do -- script proxy old(...) end + local skincolor = self:GetSkin().Colours.Category.Line.Button + local col = Color(skincolor.r,skincolor.g,skincolor.b, 255) + + pac.AddHook('PostRenderVGUI', hookID .. "2", function(code) + if not IsValid(self) or not IsValid(pnl) then pac.RemoveHook('Think', hookID .. "2") return end + local _,prop_y = pace.properties:LocalToScreen(0,0) + local x, y = self:LocalToScreen() + local overflow = y < prop_y or y > ScrH() - self:GetTall() + if overflow then + local str = "" + if y > ScrH() then + str = "↓↓" + else + str = "↑↑" + end + local container = self:GetParent() + y = math.Clamp(y,prop_y,ScrH() - self:GetTall()) + surface.SetFont(pnl:GetFont()) + local w2 = surface.GetTextSize(str .. " " .. self.CurrentKey .. " " .. str) + + surface.SetDrawColor(col) + surface.DrawRect(x - w2, y, w2, pnl:GetTall()) + surface.SetTextColor(self:GetSkin().Colours.Category.Line.Text) + surface.SetTextPos(x - w2, y) + surface.DrawText(str .. " " .. self.CurrentKey .. " " .. str) + end + end) + pace.BusyWithProperties = pnl end diff --git a/lua/pac3/editor/client/parts.lua b/lua/pac3/editor/client/parts.lua index 8d8dbd265..fc626b391 100644 --- a/lua/pac3/editor/client/parts.lua +++ b/lua/pac3/editor/client/parts.lua @@ -1955,7 +1955,9 @@ do -- menu parts_backup_properties_values[v] = {} for _,prop in pairs(v:GetProperties()) do if not excluded_properties[prop.key] then - parts_backup_properties_values[v][prop.key] = v["Get"..prop.key](v) + if v["Get"..prop.key] then + parts_backup_properties_values[v][prop.key] = v["Get"..prop.key](v) + end end end end @@ -3098,6 +3100,15 @@ function pace.AddQuickSetupsToPartMenu(menu, obj) end) end):SetIcon("icon16/text_align_center.png") + main:AddOption("clone model inside itself", function() + local copiable_properties = { + "Model", "Size", "Scale", "Alpha", "Material", "Materials", "NoLighting", "NoCulling", "Invert", "Skin", "IgnoreZ", "Translucent", "Brightness", "BlendMode" + } + local clone = obj:CreatePart("model2") + for i,v in ipairs(copiable_properties) do + clone:SetProperty(v, obj:GetProperty(v)) + end + end):SetIcon("icon16/shape_group.png") elseif obj.ClassName == "group" then main:AddOption("Assign to viewmodel", function() obj:SetParent() From 68412ef9c235d9a4c5d6001a65363cab2cd60d3a Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sat, 26 Apr 2025 17:54:36 -0400 Subject: [PATCH 04/18] entity's nicename states the model used if not edited --- lua/pac3/core/client/parts/model/entity.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lua/pac3/core/client/parts/model/entity.lua b/lua/pac3/core/client/parts/model/entity.lua index ef9294719..5697b44f4 100644 --- a/lua/pac3/core/client/parts/model/entity.lua +++ b/lua/pac3/core/client/parts/model/entity.lua @@ -69,6 +69,12 @@ function PART:GetNiceName() class_name = ent:GetClass() end + if str ~= "" then + return (str and str:gsub("%d", "") or "error") .. " " .. class_name .. " model" + elseif IsValid(self:GetOwner()) then + str = "[" .. string.GetFileFromFilename(string.StripExtension(self:GetOwner():GetModel())) .. "] " + return str .. class_name .. " model" + end return (str and str:gsub("%d", "") or "error") .. " " .. class_name .. " model" end From 36ca1c39d7c0e9a58f9c5b50f89bbd2874a91d63 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sat, 26 Apr 2025 23:48:04 -0400 Subject: [PATCH 05/18] improvements to camera swap set it as a doubleclick action (corresponds to the quick access option, view/unview camera) it saves the old view position (relative if using follow entity) so that when returning to editor view, we return to the same position --- lua/pac3/core/client/parts/camera.lua | 19 +++++++++++++++++++ lua/pac3/editor/client/view.lua | 14 +++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lua/pac3/core/client/parts/camera.lua b/lua/pac3/core/client/parts/camera.lua index 828c95690..51c7cf6f1 100644 --- a/lua/pac3/core/client/parts/camera.lua +++ b/lua/pac3/core/client/parts/camera.lua @@ -6,6 +6,8 @@ PART.ClassName = "camera" PART.Group = 'entity' PART.Icon = 'icon16/camera.png' +PART.ImplementsDoubleClickSpecified = true + BUILDER:StartStorableVars() BUILDER:GetSet("EyeAnglesLerp", 1) BUILDER:GetSet("DrawViewModel", false) @@ -75,6 +77,12 @@ function PART:CameraTakePriority(then_view) self.priority = true end) if then_view then + pace.old_ViewAngles = pace.ViewAngles + pace.old_ViewPos = pace.ViewPos + + --it should be relative if we use camera follow entity + pace.old_ViewPos_delta = pace.ViewPos - pace.GetViewEntity():GetPos() + timer.Simple(0.2, function() pace.CameraPartSwapView(true) end) end end @@ -351,6 +359,17 @@ function pac.HandleCameraPart(ply, pos, ang, fov, nearz, farz) --until we make reversible first person a thing, letting some non-drawable parts think, this is the best solution I could come up with end +function PART:OnDoubleClickSpecified() + if self ~= pac.active_camera then + self:CameraTakePriority(true) + else + pac.active_camera = nil + self.priority = false + self:RemoveSmallIcon() + pace.CameraPartSwapView() + end +end + function pac.HasRemainingCameraPart() pac.RebuildCameras() return table.Count(pac.LocalPlayer.pac_cameras) ~= 0 diff --git a/lua/pac3/editor/client/view.lua b/lua/pac3/editor/client/view.lua index 7b103ccd4..39d587831 100644 --- a/lua/pac3/editor/client/view.lua +++ b/lua/pac3/editor/client/view.lua @@ -768,7 +768,19 @@ function pace.EnableView(b) pac.AddHook("HUDShouldDraw", "editor", pace.HUDShouldDraw) pac.AddHook("PostRenderVGUI", "editor", pace.PostRenderVGUI) pace.Focused = true - pace.ResetView() + if pace.old_ViewAngles and pace.old_ViewPos and pace.old_ViewPos_delta then + if follow_entity:GetBool() then + pace.ViewPos = pace.old_ViewPos_delta + pace.GetViewEntity():GetPos() + else + pace.ViewPos = pace.old_ViewPos + end + pace.ViewAngles = pace.old_ViewAngles + pace.old_ViewAngles = nil + pace.old_ViewPos = nil + pace.old_ViewPos_delta = nil + else + pace.ResetView() + end else lastEntityPos = nil pac.RemoveHook("GUIMousePressed", "editor") From 21968119cfeace6cf21956f554020145e4090228 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sun, 27 Apr 2025 00:47:07 -0400 Subject: [PATCH 06/18] favourite materials support folder expansion --- lua/pac3/editor/client/panels/properties.lua | 21 +++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/lua/pac3/editor/client/panels/properties.lua b/lua/pac3/editor/client/panels/properties.lua index c57489c1a..54a0b6528 100644 --- a/lua/pac3/editor/client/panels/properties.lua +++ b/lua/pac3/editor/client/panels/properties.lua @@ -1747,7 +1747,26 @@ do -- base editable mat = string.gsub(mat, "^materials/", "") local mat_no_ext = string.StripExtension(mat) - if string.find(mat, "%[%d+,%d+%]") then --find the bracket notation + if string.sub(mat, 1, 7) == "folder:" then + local path = string.sub(mat, 8, #mat) + local menu3, pnl2 = menu2:AddSubMenu(string.GetFileFromFilename(path), function() + end) + pnl2:SetImage("icon16/folder.png") pnl2:SetTooltip(mat) + + local files = get_files_recursively(nil, path, {"vmt"}) + + for i,file in ipairs(files) do + mat_no_ext = string.sub(file,11,#file) --"materials/" + menu3:AddOption(string.StripExtension(file), function() + self:SetValue(mat_no_ext) + if self.CurrentKey == "Material" then + pace.current_part:SetMaterial(mat_no_ext) + elseif self.CurrentKey == "SpritePath" then + pace.current_part:SetSpritePath(mat_no_ext) + end + end):SetMaterial(mat_no_ext) + end + elseif string.find(mat, "%[%d+,%d+%]") then --find the bracket notation mat_no_ext = string.gsub(mat_no_ext, "%[%d+,%d+%]", "") pace.AddSubmenuWithBracketExpansion(menu2, function(str) str = str or "" From 7eaef714cb8eafb7a1aacca6f94d2f42da9051d2 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sun, 27 Apr 2025 00:52:14 -0400 Subject: [PATCH 07/18] tiny fix variable scope issue --- lua/pac3/editor/client/panels/properties.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lua/pac3/editor/client/panels/properties.lua b/lua/pac3/editor/client/panels/properties.lua index 54a0b6528..9d604c403 100644 --- a/lua/pac3/editor/client/panels/properties.lua +++ b/lua/pac3/editor/client/panels/properties.lua @@ -1756,8 +1756,8 @@ do -- base editable local files = get_files_recursively(nil, path, {"vmt"}) for i,file in ipairs(files) do - mat_no_ext = string.sub(file,11,#file) --"materials/" - menu3:AddOption(string.StripExtension(file), function() + local mat_no_ext = string.StripExtension(string.sub(file,11,#file)) --"materials/" + menu3:AddOption(mat_no_ext, function() self:SetValue(mat_no_ext) if self.CurrentKey == "Material" then pace.current_part:SetMaterial(mat_no_ext) From eeee167366511aa8685c8b8aa4e22ae5aa997191 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Mon, 28 Apr 2025 21:50:37 -0400 Subject: [PATCH 08/18] remove unused property --- lua/pac3/core/client/parts/hitscan.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/pac3/core/client/parts/hitscan.lua b/lua/pac3/core/client/parts/hitscan.lua index 111dc91f0..22540e9ce 100644 --- a/lua/pac3/core/client/parts/hitscan.lua +++ b/lua/pac3/core/client/parts/hitscan.lua @@ -14,7 +14,6 @@ PART.ImplementsDoubleClickSpecified = true BUILDER:StartStorableVars() :GetSet("ServerBullets", true, {description = "serverside bullets can do damage and exert a physical impact force"}) :SetPropertyGroup("bullet properties") - :GetSet("BulletImpact", false) :GetSet("Damage", 1, {editor_onchange = function (self,val) return math.floor(math.Clamp(val,0,268435455)) end}) :GetSet("Force",1000, {editor_onchange = function (self,val) return math.floor(math.Clamp(val,0,65535)) end}) :GetSet("AffectSelf", false, {description = "whether to allow to damage yourself"}) From ef0d9d6343a88730ec5be06dfa8e7e88525c58a3 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Fri, 9 May 2025 21:51:29 -0400 Subject: [PATCH 09/18] limit pac settings manager only allow change if requested cvar is from the table --- lua/pac3/editor/server/pac_settings_manager.lua | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lua/pac3/editor/server/pac_settings_manager.lua b/lua/pac3/editor/server/pac_settings_manager.lua index 900cd63bd..3868899ca 100644 --- a/lua/pac3/editor/server/pac_settings_manager.lua +++ b/lua/pac3/editor/server/pac_settings_manager.lua @@ -89,10 +89,14 @@ net.Receive("pac_send_sv_cvar", function(len,ply) local val = net.ReadString() if not cmd then return end - if GetConVar(cmd) then - GetConVar(cmd):SetString(val) + for i,v in ipairs(pac_server_cvars) do + if v[1] == cmd then + if GetConVar(cmd) then + GetConVar(cmd):SetString(val) + end + return + end end - end) net.Receive("pac_request_sv_cvars", function (len, ply) From 8ee4745a84444b0600333900787bfb89da4678e0 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Tue, 13 May 2025 21:31:53 -0400 Subject: [PATCH 10/18] make event operator force-fix less aggressive not equal is also a string operator, so don't replace it invert works slightly different from that as well --- lua/pac3/core/client/parts/event.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/pac3/core/client/parts/event.lua b/lua/pac3/core/client/parts/event.lua index 14dce13b9..d3faed68f 100644 --- a/lua/pac3/core/client/parts/event.lua +++ b/lua/pac3/core/client/parts/event.lua @@ -138,7 +138,7 @@ function PART:fix_event_operator() end elseif event_type == "string" then - if self.Operator ~= "find" and self.Operator ~= "find simple" and self.Operator ~= "equal" then + if self.Operator ~= "find" and self.Operator ~= "find simple" and self.Operator ~= "equal" and self.Operator ~= "not equal" then self.Operator = PART.Events[self.Event].preferred_operator --find simple self:SetInfo("The operator was automatically changed to work with this event type, which handles strings (text)") end From ba7253ba8a65f73bbb7764d23df5605a2275bd9c Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Fri, 16 May 2025 18:36:03 -0400 Subject: [PATCH 11/18] fix editor width initializing wrong --- lua/pac3/editor/client/panels/editor.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lua/pac3/editor/client/panels/editor.lua b/lua/pac3/editor/client/panels/editor.lua index 9cae0b1df..4821e2478 100644 --- a/lua/pac3/editor/client/panels/editor.lua +++ b/lua/pac3/editor/client/panels/editor.lua @@ -208,6 +208,8 @@ function PANEL:Init() if remember_width:GetBool() then self.init_w = math.max(self:GetCookieNumber("width"), 200) + else + self.init_w = 280 end if remember_divider:GetBool() then pace.vertical_div_height = self:GetCookieNumber("y_divider") From 35e902e5ca3dccf35c2bc39446799ec14ae6df56 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sat, 17 May 2025 16:32:41 -0400 Subject: [PATCH 12/18] bulk apply properties fixes sort alphabetically don't skip properties that have an editor friendly, it broke material parts and such don't do bulk select deselect if menu is active --- lua/pac3/editor/client/parts.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lua/pac3/editor/client/parts.lua b/lua/pac3/editor/client/parts.lua index fc626b391..44564e8ae 100644 --- a/lua/pac3/editor/client/parts.lua +++ b/lua/pac3/editor/client/parts.lua @@ -369,7 +369,7 @@ function pace.OnPartSelected(part, is_selecting) pace.delaybulkselect = pace.delaybulkselect or 0 --a time updated in shortcuts.lua to prevent common pac operations from triggering bulk selection local bulk_key_pressed = input.IsKeyDown(input.GetKeyCode(GetConVar("pac_bulk_select_key"):GetString())) - if (not bulk_key_pressed) and bulk_select_deselect:GetBool() then + if (not bulk_key_pressed) and bulk_select_deselect:GetBool() and not IsValid(pace.bulk_apply_properties_active) then if pace.last_mouse_code == MOUSE_LEFT then pace.ClearBulkList(true) end end @@ -1489,6 +1489,7 @@ do -- menu Panel:SetSize( 500, 600 ) Panel:Center() Panel:SetTitle("BULK SELECT PROPERTY EDIT - WARNING! EXPERIMENTAL FEATURE!") + pace.bulk_apply_properties_active = Panel Panel:MakePopup() surface.CreateFont("Font", { @@ -1543,7 +1544,7 @@ do -- menu end end end - if shared and not prop.udata.editor_friendly and basepart["Get" .. prop["key"]] ~= nil then + if shared and basepart["Get" .. prop["key"]] ~= nil then shared_properties[#shared_properties + 1] = prop["key"] elseif shared and prop.udata.editor_friendly and basepart["Get" .. prop["key"]] == nil then if not table.HasValue(shared_udata_properties, "event_udata_"..prop["key"]) then @@ -1575,6 +1576,7 @@ do -- menu for i,v in ipairs(shared_properties) do if excluded_vars[v] then table.remove(shared_properties,i) end end + table.sort(shared_properties) --populate panels for standard GetSet part properties for i,v in pairs(shared_properties) do From b3bd2614a4171c97cd9bbe95585f887beca350ff Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sat, 17 May 2025 18:54:48 -0400 Subject: [PATCH 13/18] replay custom animation when exiting animation editor except for gestures --- lua/pac3/editor/client/animation_timeline.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lua/pac3/editor/client/animation_timeline.lua b/lua/pac3/editor/client/animation_timeline.lua index 687feabb7..8ed9c3bc6 100644 --- a/lua/pac3/editor/client/animation_timeline.lua +++ b/lua/pac3/editor/client/animation_timeline.lua @@ -334,6 +334,7 @@ function timeline.Open(part) timeline.Stop() end +local editing_part pac.AddHook("pace_OnPartSelected", "pac3_timeline", function(part) if part.ClassName == "timeline_dummy_bone" then return end if part.ClassName == "custom_animation" then @@ -341,7 +342,17 @@ pac.AddHook("pace_OnPartSelected", "pac3_timeline", function(part) timeline.Close() end timeline.Open(part) + editing_part = part elseif timeline.editing then + if editing_part then + local part2 = editing_part + if part2.AnimationType ~= "gesture" and not part2:IsHidden() then + timer.Simple(0, function() + part2:OnHide() + part2:OnShow() + end) + end + end timeline.Close() end end) From f2877621911ee2bdbc7e4a59e3927557d955104d Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sat, 17 May 2025 19:10:29 -0400 Subject: [PATCH 14/18] fix asset browser sound playback for non-pac users --- lua/pac3/editor/client/asset_browser.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/pac3/editor/client/asset_browser.lua b/lua/pac3/editor/client/asset_browser.lua index fd8910a1e..a15110993 100644 --- a/lua/pac3/editor/client/asset_browser.lua +++ b/lua/pac3/editor/client/asset_browser.lua @@ -942,7 +942,7 @@ function pace.AssetBrowser(callback, browse_types_str, part_key) play:SetImage("icon16/control_stop.png") - local snd = CreateSound(pac.LocalPlayer, sound) + local snd = CreateSound(LocalPlayer(), sound) snd:Play() pace.asset_browser_snd = snd From b93fbcb0e6c431868c24b0bfabe914f627e5d670 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sat, 17 May 2025 19:25:17 -0400 Subject: [PATCH 15/18] editor fix if start with pac disabled, regain pac.LocalPlayer reference when opening editor --- lua/pac3/editor/client/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/pac3/editor/client/init.lua b/lua/pac3/editor/client/init.lua index 7de793b69..01630097d 100644 --- a/lua/pac3/editor/client/init.lua +++ b/lua/pac3/editor/client/init.lua @@ -93,6 +93,7 @@ local showInEditor = CreateConVar("pac_show_in_editor", "1", {FCVAR_ARCHIVE}, "S pace.pac_show_uniqueid = CreateConVar("pac_show_uniqueid", "0", {FCVAR_ARCHIVE}, "Show uniqueids of parts inside editor") function pace.OpenEditor() + if not pac.LocalPlayer then pac.LocalPlayer = LocalPlayer() end pace.CloseEditor() if hook.Run("PrePACEditorOpen", pac.LocalPlayer) == false then return end From 9cfddce48477d209c9b1bc3f5d0eb99364963f40 Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sat, 17 May 2025 20:55:20 -0400 Subject: [PATCH 16/18] disable nearest_life by default and define some sv convars despite its usefulness in wacky functional and combat pacmaking, by default we shall avoid aimbot and discovery of hidden players unless the setting is enabled I have an upcoming update to make it more configurable, but I intend to partially push this fragment to master first --- lua/pac3/core/client/base_movable.lua | 9 +++++++++ lua/pac3/core/server/init.lua | 8 ++++++++ lua/pac3/editor/client/spawnmenu.lua | 5 +++++ lua/pac3/editor/server/pac_settings_manager.lua | 6 ++++++ 4 files changed, 28 insertions(+) diff --git a/lua/pac3/core/client/base_movable.lua b/lua/pac3/core/client/base_movable.lua index aa81d9112..bfee81c6d 100644 --- a/lua/pac3/core/client/base_movable.lua +++ b/lua/pac3/core/client/base_movable.lua @@ -4,6 +4,12 @@ local Angle = Angle local NULL = NULL local Matrix = Matrix +local allow_NL = GetConVar("pac_sv_nearest_life") +local allow_NL_bone = GetConVar("pac_sv_nearest_life_allow_bones") +local NL_allow_sampling_anywhere = GetConVar("pac_sv_nearest_life_allow_sampling_from_parts") +local NL_allow_target_players = GetConVar("pac_sv_nearest_life_allow_targeting_players") +local NL_max_distance = GetConVar("pac_sv_nearest_life_max_distance") + local BUILDER, PART = pac.PartTemplate("base") PART.ClassName = "base_movable" @@ -209,6 +215,7 @@ function PART:CalcAngles(ang, wpos) end if pac.StringFind(self.AimPartName, "NEAREST_LIFE_YAW", true, true) then + if not allow_NL:GetBool() then self:SetWarning("nearest_life isn't allowed in this server\npac_sv_nearest_life") return ang or Angle(0,0,0) end local nearest_ent = get_nearest_ent(self) if not IsValid(nearest_ent) then return ang or Angle(0,0,0) end local ang = (nearest_ent:GetPos() - wpos):Angle() @@ -216,12 +223,14 @@ function PART:CalcAngles(ang, wpos) end if pac.StringFind(self.AimPartName, "NEAREST_LIFE_POS", true, true) then + if not allow_NL:GetBool() then self:SetWarning("nearest_life isn't allowed in this server\npac_sv_nearest_life") return ang or Angle(0,0,0) end local nearest_ent = get_nearest_ent(self) if not IsValid(nearest_ent) then return ang or Angle(0,0,0) end return self.Angles + (nearest_ent:GetPos() - wpos):Angle() end if pac.StringFind(self.AimPartName, "NEAREST_LIFE", true, true) then + if not allow_NL:GetBool() then self:SetWarning("nearest_life isn't allowed in this server\npac_sv_nearest_life") return ang or Angle(0,0,0) end local nearest_ent = get_nearest_ent(self) if not IsValid(nearest_ent) then return ang or Angle(0,0,0) end return self.Angles + ( nearest_ent:GetPos() + Vector(0,0,(nearest_ent:WorldSpaceCenter() - nearest_ent:GetPos()).z * 1.5) - wpos):Angle() diff --git a/lua/pac3/core/server/init.lua b/lua/pac3/core/server/init.lua index eac2c9fda..28f092079 100644 --- a/lua/pac3/core/server/init.lua +++ b/lua/pac3/core/server/init.lua @@ -10,6 +10,14 @@ CreateConVar("pac_allow_blood_color", "1", {FCVAR_NOTIFY}, "Allow to use custom CreateConVar("pac_allow_mdl", "1", CLIENT and {FCVAR_REPLICATED} or {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Allow to use custom MDLs") CreateConVar("pac_allow_mdl_entity", "1", CLIENT and {FCVAR_REPLICATED} or {FCVAR_ARCHIVE, FCVAR_REPLICATED}, "Allow to use custom MDLs as Entity") +local default = "0" +if game.SinglePlayer() then default = "1" end +CreateConVar("pac_sv_nearest_life", default, {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Enables nearest_life aimparts and bones, abusable for aimbot-type setups (which would already be possible with CS lua)") +CreateConVar("pac_sv_nearest_life_allow_sampling_from_parts", "1", {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Restricts nearest_life aimparts and bones search to the player itself to prevent sampling from arbitrary positions\n0=sampling can only start from the player itself") +CreateConVar("pac_sv_nearest_life_allow_bones", default, {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Restricts nearest_life bones, preventing placement on external entities' position") +CreateConVar("pac_sv_nearest_life_allow_targeting_players", "1", {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Restricts nearest_life aimparts and bones to forbid targeting players\n0=no target players") +CreateConVar("pac_sv_nearest_life_max_distance", "5000", {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Restricts the radius for nearest_life aimparts and bones") + include("util.lua") include("pac3/core/shared/init.lua") diff --git a/lua/pac3/editor/client/spawnmenu.lua b/lua/pac3/editor/client/spawnmenu.lua index 838809eba..8b67667e6 100644 --- a/lua/pac3/editor/client/spawnmenu.lua +++ b/lua/pac3/editor/client/spawnmenu.lua @@ -162,6 +162,11 @@ function pace.AdminSettingsMenu(self) self:CheckBox(L"Allow entity size modifier", "pac_modifier_size") self:CheckBox(L"Allow blood color modifier", "pac_allow_blood_color") self:NumSlider(L"Allow prop / other player outfits", "pac_sv_prop_outfits", 0, 2, 0) + self:CheckBox(L"Allow Nearest Life", "pac_sv_nearest_life") + self:CheckBox(L"Allow NL sampling anywhere", "pac_sv_nearest_life_bones") + self:CheckBox(L"Allow NL on bones", "pac_sv_nearest_life_bones") + self:CheckBox(L"Allow NL targeting players", "pac_sv_nearest_life_allow_targeting_players") + self:NumSlider(L"Max NL distance", "pac_sv_nearest_life_max_distance", 0, 20000, 0) self:Help(""):SetFont("DermaDefaultBold")--spacers self:Help(""):SetFont("DermaDefaultBold") diff --git a/lua/pac3/editor/server/pac_settings_manager.lua b/lua/pac3/editor/server/pac_settings_manager.lua index 3868899ca..290709b66 100644 --- a/lua/pac3/editor/server/pac_settings_manager.lua +++ b/lua/pac3/editor/server/pac_settings_manager.lua @@ -81,6 +81,12 @@ local pac_server_cvars = { {"pac_to_contraption_allow", "Allow PAC to contraption tool", "", -1, 0, 200}, {"pac_max_contraption_entities", "Entity limit for PAC to contraption", "", 0, 0, 200}, {"pac_restrictions", "restrict PAC editor camera movement", "", -1, 0, 200}, + + {"pac_sv_nearest_life", "Allow nearest life aimparts or bones", "", -1, 0, 200}, + {"pac_sv_nearest_life_allow_sampling_from_parts", "Allow NL sampling from anywhere", "", -1, 0, 200}, + {"pac_sv_nearest_life_allow_bones", "Allow NL usage on bones", "", -1, 0, 200}, + {"pac_sv_nearest_life_allow_targeting_players", "Allow NL targeting players", "", -1, 0, 200}, + {"pac_sv_nearest_life_max_distance", "Max NL distance", "", 0, 0, 20000}, } net.Receive("pac_send_sv_cvar", function(len,ply) From f0680ba8556fb061a4241ec9d1f4bda684d812fc Mon Sep 17 00:00:00 2001 From: pingu7867 Date: Sun, 18 May 2025 13:05:30 -0400 Subject: [PATCH 17/18] NL cvar fix copy them to the client realm --- lua/pac3/core/client/base_movable.lua | 12 +++++++----- lua/pac3/editor/client/settings.lua | 5 +++++ lua/pac3/editor/client/spawnmenu.lua | 15 +++++++++++++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lua/pac3/core/client/base_movable.lua b/lua/pac3/core/client/base_movable.lua index bfee81c6d..a00e1f1c6 100644 --- a/lua/pac3/core/client/base_movable.lua +++ b/lua/pac3/core/client/base_movable.lua @@ -4,11 +4,13 @@ local Angle = Angle local NULL = NULL local Matrix = Matrix -local allow_NL = GetConVar("pac_sv_nearest_life") -local allow_NL_bone = GetConVar("pac_sv_nearest_life_allow_bones") -local NL_allow_sampling_anywhere = GetConVar("pac_sv_nearest_life_allow_sampling_from_parts") -local NL_allow_target_players = GetConVar("pac_sv_nearest_life_allow_targeting_players") -local NL_max_distance = GetConVar("pac_sv_nearest_life_max_distance") +local default = "0" +if game.SinglePlayer() then default = "1" end +local allow_NL = CreateConVar("pac_sv_nearest_life", default, {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Enables nearest_life aimparts and bones, abusable for aimbot-type setups (which would already be possible with CS lua)") +local NL_allow_sampling_anywhere = CreateConVar("pac_sv_nearest_life_allow_sampling_from_parts", "1", {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Restricts nearest_life aimparts and bones search to the player itself to prevent sampling from arbitrary positions\n0=sampling can only start from the player itself") +local allow_NL_bone = CreateConVar("pac_sv_nearest_life_allow_bones", default, {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Restricts nearest_life bones, preventing placement on external entities' position") +local NL_allow_target_players = CreateConVar("pac_sv_nearest_life_allow_targeting_players", "1", {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Restricts nearest_life aimparts and bones to forbid targeting players\n0=no target players") +local NL_max_distance = CreateConVar("pac_sv_nearest_life_max_distance", "5000", {FCVAR_ARCHIVE, FCVAR_REPLICATED, FCVAR_NOTIFY}, "Restricts the radius for nearest_life aimparts and bones") local BUILDER, PART = pac.PartTemplate("base") diff --git a/lua/pac3/editor/client/settings.lua b/lua/pac3/editor/client/settings.lua index e2629afe2..12df1c152 100644 --- a/lua/pac3/editor/client/settings.lua +++ b/lua/pac3/editor/client/settings.lua @@ -93,6 +93,11 @@ local convar_params_misc = { {"pac_to_contraption_allow", "Allow PAC to contraption tool", "", -1, 0, 200}, {"pac_max_contraption_entities", "Entity limit for PAC to contraption", "", 0, 0, 200}, {"pac_restrictions", "restrict PAC editor camera movement", "", -1, 0, 200}, + {"pac_sv_nearest_life", "Allow nearest life aimparts or bones", "", -1, 0, 200}, + {"pac_sv_nearest_life_allow_sampling_from_parts", "Allow NL sampling from anywhere", "", -1, 0, 200}, + {"pac_sv_nearest_life_allow_bones", "Allow NL usage on bones", "", -1, 0, 200}, + {"pac_sv_nearest_life_allow_targeting_players", "Allow NL targeting players", "", -1, 0, 200}, + {"pac_sv_nearest_life_max_distance", "Max NL distance", "", 0, 0, 20000}, } pace = pace diff --git a/lua/pac3/editor/client/spawnmenu.lua b/lua/pac3/editor/client/spawnmenu.lua index 8b67667e6..993a4788a 100644 --- a/lua/pac3/editor/client/spawnmenu.lua +++ b/lua/pac3/editor/client/spawnmenu.lua @@ -142,6 +142,17 @@ function pace.ClientSettingsMenu(self) self:NumSlider(L"Particles max per emitter: ", "pac_limit_particles_per_emitter", 0, 10000, 0) end +local default = "0" +if game.SinglePlayer() then default = "1" end +CreateConVar("pac_sv_nearest_life", default, {FCVAR_REPLICATED}, "Enables nearest_life aimparts and bones, abusable for aimbot-type setups (which would already be possible with CS lua)") +CreateConVar("pac_sv_nearest_life_allow_sampling_from_parts", "1", {FCVAR_REPLICATED}, "Restricts nearest_life aimparts and bones search to the player itself to prevent sampling from arbitrary positions\n0=sampling can only start from the player itself") +CreateConVar("pac_sv_nearest_life_allow_bones", default, {FCVAR_REPLICATED}, "Restricts nearest_life bones, preventing placement on external entities' position") +CreateConVar("pac_sv_nearest_life_allow_targeting_players", "1", {FCVAR_REPLICATED}, "Restricts nearest_life aimparts and bones to forbid targeting players\n0=no target players") +CreateConVar("pac_sv_nearest_life_max_distance", "5000", {FCVAR_REPLICATED}, "Restricts the radius for nearest_life aimparts and bones") +CreateConVar("pac_submit_spam", "1", {FCVAR_REPLICATED}) +CreateConVar("pac_allow_blood_color", "1", {FCVAR_REPLICATED}) +CreateConVar("pac_sv_prop_outfits", "1", {FCVAR_REPLICATED}) + function pace.AdminSettingsMenu(self) if not LocalPlayer():IsAdmin() then return end if not IsValid(self) then return end @@ -163,8 +174,8 @@ function pace.AdminSettingsMenu(self) self:CheckBox(L"Allow blood color modifier", "pac_allow_blood_color") self:NumSlider(L"Allow prop / other player outfits", "pac_sv_prop_outfits", 0, 2, 0) self:CheckBox(L"Allow Nearest Life", "pac_sv_nearest_life") - self:CheckBox(L"Allow NL sampling anywhere", "pac_sv_nearest_life_bones") - self:CheckBox(L"Allow NL on bones", "pac_sv_nearest_life_bones") + self:CheckBox(L"Allow NL sampling anywhere", "pac_sv_nearest_life_allow_sampling_from_parts") + self:CheckBox(L"Allow NL on bones", "pac_sv_nearest_life_allow_bones") self:CheckBox(L"Allow NL targeting players", "pac_sv_nearest_life_allow_targeting_players") self:NumSlider(L"Max NL distance", "pac_sv_nearest_life_max_distance", 0, 20000, 0) self:Help(""):SetFont("DermaDefaultBold")--spacers From 12fa913c4c6ebde9ac800d21e76ead19a9621f6f Mon Sep 17 00:00:00 2001 From: thegrb93 Date: Wed, 21 May 2025 03:39:45 -0400 Subject: [PATCH 18/18] Blacklist crashing effect (#1413) --- lua/pac3/core/shared/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/pac3/core/shared/init.lua b/lua/pac3/core/shared/init.lua index 7f509860b..382905062 100644 --- a/lua/pac3/core/shared/init.lua +++ b/lua/pac3/core/shared/init.lua @@ -13,6 +13,7 @@ CreateConVar("pac_sv_draw_distance", 0, CLIENT and FCVAR_REPLICATED or bit.bor(F do local tohash = { -- Crash + 'eye_muzzle.pcf', -- E.Y.E: Divine Cybermancy effect that crashes gmod. https://github.com/CapsAdmin/pac3/issues/1410 'weapon_unusual_isotope.pcf', -- Invalid