From 82980b80727b2ca70fe30b45bdd70244aec783d9 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Mon, 5 Jan 2026 03:53:47 +0300 Subject: [PATCH 1/8] Remove edict checks --- .../core/custom/constraintcore.lua | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua index 61b51d217c..1358b787b1 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua @@ -19,9 +19,7 @@ local maxHydraulic = CreateConVar( "wire_expression2_max_constraints_hydraulic", local maxPerEntity = CreateConVar( "wire_expression2_max_consttraints_per_entity", "0", cvFlags, nil, 0) local maxBallsocket = CreateConVar( "wire_expression2_max_constraints_ballsocket", "0", cvFlags, nil, 0) local maxAdvBallsocket = CreateConVar( "wire_expression2_max_constraints_ballsocket_adv", "0", cvFlags, nil, 0) - -local edictCutOff = CreateConVar( "wire_expression2_constraints_edict_cutoff", "0", cvFlags, "At what edict count will E2s be prevented from creating new rope-like constraints (0 turns the check off)", 0, 8192 ) -local shouldCleanup = CreateConVar( "Wire_expression2_constraints_cleanup", "0", cvFlags, "Whether or not Constraint Core should remove all constraints made by an E2 when it's deleted", 0, 1 ) +local shouldCleanup = CreateConVar( "wire_expression2_constraints_cleanup", "0", cvFlags, "Whether or not Constraint Core should remove all constraints made by an E2 when it's deleted", 0, 1 ) local playerCounts = WireLib.RegisterPlayerTable() @@ -165,17 +163,6 @@ local function checkCount(self, consType, ent1, ent2) return true end -local function checkEdicts(self) - local maxEdicts = edictCutOff:GetInt() - if maxEdicts == 0 then return true end - - if ents.GetEdictCount() >= maxEdicts then - return self:throw( "Global edict limit reached!", false ) - end - - return true -end - local function addUndo(self, consType, cons, rope) local data = self.data local ply = self.player @@ -357,7 +344,6 @@ end local function createHydraulic(self, index, ent1, ent2, v1, v2, width, bone1, bone2, constant, damping, rdamping, mat, stretch, color) if not checkEnts( self, ent1, ent2 ) then return end if not checkCount( self, "Hydraulic", ent1, ent2 ) then return end - if not checkEdicts( self ) then return end local constraints = setupEntConstraints( ent1 ) width = math.Clamp(width, 0, 50) @@ -442,7 +428,6 @@ end local function createRope(self, index, ent1, ent2, v1, v2, bone1, bone2, addlength, width, mat, rigid, color) if not checkEnts( self, ent1, ent2 ) then return end if not checkCount( self, "Rope", ent1, ent2 ) then return end - if not checkEdicts( self ) then return end local constraints = setupEntConstraints( ent1 ) local length = ( ent1:LocalToWorld( v1 ) - ent2:LocalToWorld( v2 ) ):Length() @@ -576,7 +561,6 @@ __e2setcost(30) local function createSlider(self, ent1, ent2, v1, v2, width, bone1, bone2, mat, color) if not checkEnts( self, ent1, ent2 ) then return end if not checkCount( self, "Slider", ent1, ent2 ) then return end - if not checkEdicts( self ) then return end if color then color = Color(color[1],color[2],color[3],255) From 48026dd3f0516708bead9f83cd80722487002774 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Mon, 5 Jan 2026 04:10:59 +0300 Subject: [PATCH 2/8] Remove per type checks --- .../core/custom/constraintcore.lua | 47 ++----------------- 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua index 1358b787b1..8178034d3c 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua @@ -7,19 +7,9 @@ local math_min = math.min local math_max = math.max local table_insert = table.insert -local cvFlags = {FCVAR_ARCHIVE} -local maxWeld = CreateConVar( "wire_expression2_max_constraints_weld", "0", cvFlags, nil, 0) -local maxRope = CreateConVar( "wire_expression2_max_constraints_rope", "0", cvFlags, nil, 0) -local maxAxis = CreateConVar( "wire_expression2_max_constraints_axis", "0", cvFlags, nil, 0) -local maxTotal = CreateConVar( "wire_expression2_max_constraints_total", "0", cvFlags, nil, 0) -local maxSlider = CreateConVar( "wire_expression2_max_constraints_slider", "0", cvFlags, nil, 0) -local maxElastic = CreateConVar( "wire_expression2_max_constraints_elastic", "0", cvFlags, nil, 0) -local maxNocollide = CreateConVar( "wire_expression2_max_constraints_nocollide", "0", cvFlags, nil, 0) -local maxHydraulic = CreateConVar( "wire_expression2_max_constraints_hydraulic", "0", cvFlags, nil, 0) -local maxPerEntity = CreateConVar( "wire_expression2_max_consttraints_per_entity", "0", cvFlags, nil, 0) -local maxBallsocket = CreateConVar( "wire_expression2_max_constraints_ballsocket", "0", cvFlags, nil, 0) -local maxAdvBallsocket = CreateConVar( "wire_expression2_max_constraints_ballsocket_adv", "0", cvFlags, nil, 0) -local shouldCleanup = CreateConVar( "wire_expression2_constraints_cleanup", "0", cvFlags, "Whether or not Constraint Core should remove all constraints made by an E2 when it's deleted", 0, 1 ) +local maxTotal = CreateConVar( "wire_expression2_max_constraints_total", "0", FCVAR_ARCHIVE, nil, 0) +local maxPerEntity = CreateConVar( "wire_expression2_max_consttraints_per_entity", "0", FCVAR_ARCHIVE, nil, 0) +local shouldCleanup = CreateConVar( "wire_expression2_constraints_cleanup", "0", FCVAR_ARCHIVE, "Whether or not Constraint Core should remove all constraints made by an E2 when it's deleted", 0, 1 ) local playerCounts = WireLib.RegisterPlayerTable() @@ -44,7 +34,6 @@ end local function setupCounts(holder) holder.allConstraints = holder.allConstraints or {} - holder.constraintCounts = holder.constraintCounts or {} holder.entityConstraints = holder.entityConstraints or {} holder.totalConstraints = holder.totalConstraints or 0 end @@ -72,19 +61,6 @@ e2function void enableConstraintUndo(state) self.data.constraintUndos = state ~= 0 end -local countLookup = { - Weld = maxWeld, - Rope = maxRope, - Axis = maxAxis, - Slider = maxSlider, - Elastic = maxElastic, - NoCollide = maxNocollide, - Hydraulic = maxHydraulic, - Ballsocket = maxBallsocket, - AdvBallsocket = maxAdvBallsocket, -} - - local function checkEnts(self, ent1, ent2) if not ent1 or not ent2 then return self:throw("Invalid entity!", false) end @@ -128,7 +104,6 @@ end local function checkCount(self, consType, ent1, ent2) local data = getCountHolder( self ) - local typeCounts = data.constraintCounts -- Total local totalLimit = maxTotal:GetInt() @@ -139,15 +114,6 @@ local function checkCount(self, consType, ent1, ent2) end end - -- Type - local typeLimit = countLookup[consType]:GetInt() - if typeLimit > 0 then - local typeCount = typeCounts[consType] or 0 - if typeCount >= typeLimit then - return self:throw( consType .. " limit reached!", false ) - end - end - -- Ents local entityLimit = maxPerEntity:GetInt() if entityLimit > 0 then @@ -183,15 +149,11 @@ end local function increment(self, consType, ent1, ent2, cons) local data = getCountHolder( self ) local entCounts = data.entityConstraints - local typeCounts = data.constraintCounts local totalCount = data.totalConstraints -- Total data.totalConstraints = totalCount + 1 - -- Type - typeCounts[consType] = ( typeCounts[consType] or 0 ) + 1 - -- Ents entCounts[ent1] = ( entCounts[ent1] or 0 ) + 1 entCounts[ent2] = ( entCounts[ent2] or 0 ) + 1 @@ -203,9 +165,6 @@ local function increment(self, consType, ent1, ent2, cons) -- Total data.totalConstraints = math_max( 0, data.totalConstraints - 1 ) - -- Type - typeCounts[consType] = math_max( 0, typeCounts[consType] - 1 ) - -- Ents entCounts[cons.Ent1] = math_max( 0, entCounts[cons.Ent1] - 1 ) entCounts[cons.Ent2] = math_max( 0, entCounts[cons.Ent2] - 1 ) From 9d2dffcad09937e4dfb327807bdeee86189b2a69 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Mon, 5 Jan 2026 05:00:11 +0300 Subject: [PATCH 3/8] Replace all count checks with CheckLimit --- .../core/custom/constraintcore.lua | 125 ++++++------------ 1 file changed, 44 insertions(+), 81 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua index 8178034d3c..bb805796e1 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua @@ -7,10 +7,7 @@ local math_min = math.min local math_max = math.max local table_insert = table.insert -local maxTotal = CreateConVar( "wire_expression2_max_constraints_total", "0", FCVAR_ARCHIVE, nil, 0) -local maxPerEntity = CreateConVar( "wire_expression2_max_consttraints_per_entity", "0", FCVAR_ARCHIVE, nil, 0) -local shouldCleanup = CreateConVar( "wire_expression2_constraints_cleanup", "0", FCVAR_ARCHIVE, "Whether or not Constraint Core should remove all constraints made by an E2 when it's deleted", 0, 1 ) - +local shouldCleanup = CreateConVar( "wire_expression2_constraints_cleanup", "0", FCVAR_ARCHIVE, "Whether or not Constraint Core should remove all constraints made by an E2 when it's deleted") local playerCounts = WireLib.RegisterPlayerTable() -- Returns the table being used to keep track of counts @@ -34,8 +31,6 @@ end local function setupCounts(holder) holder.allConstraints = holder.allConstraints or {} - holder.entityConstraints = holder.entityConstraints or {} - holder.totalConstraints = holder.totalConstraints or 0 end registerCallback("construct", function(self) @@ -66,15 +61,16 @@ local function checkEnts(self, ent1, ent2) if not ent1:IsWorld() then if not ent1:IsValid() then return self:throw("Invalid entity!", false) end + if ent1:IsPlayer() then return self:throw("Cannot constrain players!", false) end if not isOwner(self, ent1) then return self:throw("You are not the owner of the entity!", false) end end if not ent2:IsWorld() then if not ent2:IsValid() then return self:throw("Invalid target entity!", false) end + if ent2:IsPlayer() then return self:throw("Cannot constrain players!", false) end if not isOwner(self, ent2) then return self:throw("You are not the owner of the target entity!", false) end end - if ent1:IsPlayer() or ent2:IsPlayer() then return self:throw("Cannot constrain players!", false) end return true end @@ -102,84 +98,51 @@ local function setupEntConstraints(ent) return Ropes end -local function checkCount(self, consType, ent1, ent2) - local data = getCountHolder( self ) - - -- Total - local totalLimit = maxTotal:GetInt() - if totalLimit > 0 then - local totalCount = data.totalConstraints - if totalCount >= totalLimit then - return self:throw( "Total constraint limit reached!", false ) - end - end - - -- Ents - local entityLimit = maxPerEntity:GetInt() - if entityLimit > 0 then - local entCounts = data.entityConstraints +local function checkCount(self, rope) + local ply = self.player - local ent1Count = entCounts[ent1] or 0 - local ent2Count = entCounts[ent2] or 0 - if math_max( ent1Count, ent2Count ) >= entityLimit then - return self:throw( "Entity limit reached!", false ) - end + if not ply:CheckLimit(rope and "ropeconstraints" or "constraints") then + return false end return true end -local function addUndo(self, consType, cons, rope) - local data = self.data +local function addUndo(self, const_type, const, rope) local ply = self.player - local cleanupType = rope and "ropeconstraints" or "constraints" - - ply:AddCleanup( cleanupType, cons ) - if rope then ply:AddCleanup( cleanupType, rope ) end + local const_class = const:GetClass() - if not data.constraintUndos then return end - - undo.Create( "e2_" .. consType ) - undo.SetPlayer( ply ) - undo.AddEntity( cons ) - if rope then undo.AddEntity( rope ) end - undo.Finish() -end - -local function increment(self, consType, ent1, ent2, cons) - local data = getCountHolder( self ) - local entCounts = data.entityConstraints - local totalCount = data.totalConstraints - - -- Total - data.totalConstraints = totalCount + 1 - - -- Ents - entCounts[ent1] = ( entCounts[ent1] or 0 ) + 1 - entCounts[ent2] = ( entCounts[ent2] or 0 ) + 1 - - -- Decrement relevant counts - cons:CallOnRemove( "wire_expression2_constraints_" .. self.uid, function() - if not IsValid( self.entity ) then return end - - -- Total - data.totalConstraints = math_max( 0, data.totalConstraints - 1 ) + if const_class == "logic_collision_pair" then + ply:AddCleanup("nocollide", const) + ply:AddCount("constraints", const) + else + if const_class == "keyframe_rope" or rope then + ply:AddCount("ropeconstraints", const) + ply:AddCleanup("ropeconstraints", const) + if rope then ply:AddCleanup("ropeconstraints", rope) end + else + ply:AddCleanup("constraints", const) + end + end - -- Ents - entCounts[cons.Ent1] = math_max( 0, entCounts[cons.Ent1] - 1 ) - entCounts[cons.Ent2] = math_max( 0, entCounts[cons.Ent2] - 1 ) - end ) + if self.data.constraintUndos then + undo.Create("E2 " .. const_type) + undo.SetPlayer(ply) + undo.AddEntity(cons) + if rope then undo.AddEntity(rope) end + undo.Finish() + end end -local function postCreate(self, consType, ent1, ent2, cons, rope) - addUndo( self, consType, cons, rope ) - increment( self, consType, ent1, ent2, cons ) +local function postCreate(self, cons_type, cons, rope) + addUndo(self, cons_type, cons, rope) -- Don't bother tracking the constraints if we won't clean them up if not shouldCleanup:GetBool() then return end local data = getCountHolder( self ) table_insert( data.allConstraints, cons ) + if rope then table_insert( data.allConstraints, rope ) end end local function caps(text) @@ -197,7 +160,7 @@ __e2setcost(30) --- Creates an axis between and at vector positions local to each ent. e2function void axis(entity ent1, vector v1, entity ent2, vector v2) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "Axis", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.Axis(ent1, ent2, 0, 0, v1, v2, 0, 0, 0, 0) postCreate(self, "Axis", ent1, ent2, cons) @@ -206,7 +169,7 @@ end --- Creates an axis between and at vector positions local to each ent, with friction. e2function void axis(entity ent1, vector v1, entity ent2, vector v2, friction) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "Axis", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.Axis(ent1, ent2, 0, 0, v1, v2, 0, 0, friction, 0) postCreate(self, "Axis", ent1, ent2, cons) @@ -215,7 +178,7 @@ end --- Creates an axis between and at vector positions local to each ent, with friction and rotation axis. e2function void axis(entity ent1, vector v1, entity ent2, vector v2, friction, vector localaxis) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "Axis", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.Axis(ent1, ent2, 0, 0, v1, v2, 0, 0, friction, 0, localaxis) if not verifyConstraint(self, cons) then return end @@ -229,7 +192,7 @@ end --- Creates a ballsocket between and at , which is local to e2function void ballsocket(entity ent1, vector v, entity ent2) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "Ballsocket", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.Ballsocket(ent1, ent2, 0, 0, v, 0, 0, 0) if not verifyConstraint(self, cons) then return end @@ -240,7 +203,7 @@ end --- Creates a ballsocket between and at , which is local to , with friction e2function void ballsocket(entity ent1, vector v, entity ent2, friction) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "AdvBallsocket", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.AdvBallsocket(ent1, ent2, 0, 0, v, vector_origin, 0, 0, -180, -180, -180, 180, 180, 180, friction, friction, friction, 0, 0) if not verifyConstraint(self, cons) then return end @@ -251,7 +214,7 @@ end --- Creates an adv ballsocket between and at , which is local to , with many settings e2function void ballsocket(entity ent1, vector v, entity ent2, vector mins, vector maxs, vector frictions) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "AdvBallsocket", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.AdvBallsocket(ent1, ent2, 0, 0, v, vector_origin, 0, 0, mins[1], mins[2], mins[3], maxs[1], maxs[2], maxs[3], frictions[1], frictions[2], frictions[3], 0, 0) if not verifyConstraint(self, cons) then return end @@ -262,7 +225,7 @@ end --- Creates an adv ballsocket between and at , which is local to , with many settings e2function void ballsocket(entity ent1, vector v, entity ent2, vector mins, vector maxs, vector frictions, rotateonly) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "AdvBallsocket", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.AdvBallsocket(ent1, ent2, 0, 0, v, vector_origin, 0, 0, mins[1], mins[2], mins[3], maxs[1], maxs[2], maxs[3], frictions[1], frictions[2], frictions[3], rotateonly, 0) if not verifyConstraint(self, cons) then return end @@ -273,7 +236,7 @@ end --- Creates an angular weld (angles are fixed, position isn't) between and at , which is local to e2function void weldAng(entity ent1, vector v, entity ent2) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "AdvBallsocket", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.AdvBallsocket(ent1, ent2, 0, 0, v, vector_origin, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0) if not verifyConstraint(self, cons) then return end @@ -302,7 +265,7 @@ end -- == Hydraulic == local function createHydraulic(self, index, ent1, ent2, v1, v2, width, bone1, bone2, constant, damping, rdamping, mat, stretch, color) if not checkEnts( self, ent1, ent2 ) then return end - if not checkCount( self, "Hydraulic", ent1, ent2 ) then return end + if not checkCount( self, true ) then return end local constraints = setupEntConstraints( ent1 ) width = math.Clamp(width, 0, 50) @@ -386,7 +349,7 @@ end -- == Rope == local function createRope(self, index, ent1, ent2, v1, v2, bone1, bone2, addlength, width, mat, rigid, color) if not checkEnts( self, ent1, ent2 ) then return end - if not checkCount( self, "Rope", ent1, ent2 ) then return end + if not checkCount( self, true ) then return end local constraints = setupEntConstraints( ent1 ) local length = ( ent1:LocalToWorld( v1 ) - ent2:LocalToWorld( v2 ) ):Length() @@ -519,7 +482,7 @@ __e2setcost(30) -- == Sliders == local function createSlider(self, ent1, ent2, v1, v2, width, bone1, bone2, mat, color) if not checkEnts( self, ent1, ent2 ) then return end - if not checkCount( self, "Slider", ent1, ent2 ) then return end + if not checkCount( self, true ) then return end if color then color = Color(color[1],color[2],color[3],255) @@ -571,7 +534,7 @@ end -- == NoCollide == local function noCollideCreate(self, ent1, ent2, bone1, bone2) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "NoCollide", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.NoCollide(ent1, ent2, bone1 or 0, bone2 or 0) if not verifyConstraint(self, cons) then return end @@ -618,7 +581,7 @@ end -- == Welds == local function weldCreate(self, ent1, ent2, bone1, bone2, forcelimit, nocollide) if not checkEnts(self, ent1, ent2) then return end - if not checkCount(self, "Weld", ent1, ent2) then return end + if not checkCount(self, false) then return end local cons = constraint.Weld(ent1, ent2, bone1 or 0, bone2 or 0, forcelimit or 0, nocollide ~= 0) if not verifyConstraint(self, cons) then return end From a994e4f3a319d571b5308ca46e5bf8bc40551655 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Mon, 5 Jan 2026 05:22:19 +0300 Subject: [PATCH 4/8] Fixes --- .../core/custom/constraintcore.lua | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua index bb805796e1..007498d703 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua @@ -113,14 +113,15 @@ local function addUndo(self, const_type, const, rope) local const_class = const:GetClass() if const_class == "logic_collision_pair" then - ply:AddCleanup("nocollide", const) ply:AddCount("constraints", const) + ply:AddCleanup("nocollide", const) else if const_class == "keyframe_rope" or rope then ply:AddCount("ropeconstraints", const) ply:AddCleanup("ropeconstraints", const) if rope then ply:AddCleanup("ropeconstraints", rope) end else + ply:AddCount("constraints", const) ply:AddCleanup("constraints", const) end end @@ -128,20 +129,21 @@ local function addUndo(self, const_type, const, rope) if self.data.constraintUndos then undo.Create("E2 " .. const_type) undo.SetPlayer(ply) - undo.AddEntity(cons) + undo.AddEntity(const) + print(const) if rope then undo.AddEntity(rope) end undo.Finish() end end -local function postCreate(self, cons_type, cons, rope) - addUndo(self, cons_type, cons, rope) +local function postCreate(self, const_type, const, rope) + addUndo(self, const_type, const, rope) -- Don't bother tracking the constraints if we won't clean them up if not shouldCleanup:GetBool() then return end local data = getCountHolder( self ) - table_insert( data.allConstraints, cons ) + table_insert( data.allConstraints, const ) if rope then table_insert( data.allConstraints, rope ) end end @@ -163,7 +165,7 @@ e2function void axis(entity ent1, vector v1, entity ent2, vector v2) if not checkCount(self, false) then return end local cons = constraint.Axis(ent1, ent2, 0, 0, v1, v2, 0, 0, 0, 0) - postCreate(self, "Axis", ent1, ent2, cons) + postCreate(self, "Axis", cons) end --- Creates an axis between and at vector positions local to each ent, with friction. @@ -172,7 +174,7 @@ e2function void axis(entity ent1, vector v1, entity ent2, vector v2, friction) if not checkCount(self, false) then return end local cons = constraint.Axis(ent1, ent2, 0, 0, v1, v2, 0, 0, friction, 0) - postCreate(self, "Axis", ent1, ent2, cons) + postCreate(self, "Axis", cons) end --- Creates an axis between and at vector positions local to each ent, with friction and rotation axis. @@ -183,7 +185,7 @@ e2function void axis(entity ent1, vector v1, entity ent2, vector v2, friction, v local cons = constraint.Axis(ent1, ent2, 0, 0, v1, v2, 0, 0, friction, 0, localaxis) if not verifyConstraint(self, cons) then return end - postCreate(self, "Axis", ent1, ent2, cons) + postCreate(self, "Axis", cons) end @@ -197,7 +199,7 @@ e2function void ballsocket(entity ent1, vector v, entity ent2) local cons = constraint.Ballsocket(ent1, ent2, 0, 0, v, 0, 0, 0) if not verifyConstraint(self, cons) then return end - postCreate(self, "Ballsocket", ent1, ent2, cons) + postCreate(self, "Ballsocket", cons) end --- Creates a ballsocket between and at , which is local to , with friction @@ -208,7 +210,7 @@ e2function void ballsocket(entity ent1, vector v, entity ent2, friction) local cons = constraint.AdvBallsocket(ent1, ent2, 0, 0, v, vector_origin, 0, 0, -180, -180, -180, 180, 180, 180, friction, friction, friction, 0, 0) if not verifyConstraint(self, cons) then return end - postCreate(self, "AdvBallsocket", ent1, ent2, cons) + postCreate(self, "AdvBallsocket", cons) end --- Creates an adv ballsocket between and at , which is local to , with many settings @@ -219,7 +221,7 @@ e2function void ballsocket(entity ent1, vector v, entity ent2, vector mins, vect local cons = constraint.AdvBallsocket(ent1, ent2, 0, 0, v, vector_origin, 0, 0, mins[1], mins[2], mins[3], maxs[1], maxs[2], maxs[3], frictions[1], frictions[2], frictions[3], 0, 0) if not verifyConstraint(self, cons) then return end - postCreate(self, "AdvBallsocket", ent1, ent2, cons) + postCreate(self, "AdvBallsocket", cons) end --- Creates an adv ballsocket between and at , which is local to , with many settings @@ -230,7 +232,7 @@ e2function void ballsocket(entity ent1, vector v, entity ent2, vector mins, vect local cons = constraint.AdvBallsocket(ent1, ent2, 0, 0, v, vector_origin, 0, 0, mins[1], mins[2], mins[3], maxs[1], maxs[2], maxs[3], frictions[1], frictions[2], frictions[3], rotateonly, 0) if not verifyConstraint(self, cons) then return end - postCreate(self, "AdvBallsocket", ent1, ent2, cons) + postCreate(self, "AdvBallsocket", cons) end --- Creates an angular weld (angles are fixed, position isn't) between and at , which is local to @@ -241,7 +243,7 @@ e2function void weldAng(entity ent1, vector v, entity ent2) local cons = constraint.AdvBallsocket(ent1, ent2, 0, 0, v, vector_origin, 0, 0, 0, -0, 0, 0, 0, 0, 0, 0, 0, 1, 0) if not verifyConstraint(self, cons) then return end - postCreate(self, "AdvBallsocket", ent1, ent2, cons) + postCreate(self, "AdvBallsocket", cons) end @@ -284,7 +286,7 @@ local function createHydraulic(self, index, ent1, ent2, v1, v2, width, bone1, bo if not verifyConstraint( self, cons ) then return end constraints[index] = cons - postCreate( self, "Hydraulic", ent1, ent2, cons, rope ) + postCreate( self, "Hydraulic", cons, rope ) end e2function void hydraulic(index, entity ent, vector v1, bone bone, vector v2, width) @@ -365,7 +367,7 @@ local function createRope(self, index, ent1, ent2, v1, v2, bone1, bone2, addleng if not verifyConstraint( self, cons ) then return end constraints[index] = cons - postCreate( self, "Rope", ent1, ent2, cons, rope ) + postCreate( self, "Rope", cons, rope ) end e2function void rope(index, entity ent1, vector v1, entity ent2, vector v2, addlength, width, string mat, rigid, vector color ) @@ -491,7 +493,7 @@ local function createSlider(self, ent1, ent2, v1, v2, width, bone1, bone2, mat, local cons, rope = constraint.Slider( ent1, ent2, bone1 or 0, bone2 or 0, v1, v2, width or 1, mat ~= "" and mat or "cable/cable2", color ) if not verifyConstraint( self, cons ) then return end - postCreate(self, "Slider", ent1, ent2, cons, rope) + postCreate(self, "Slider", cons, rope) end e2function void slider(entity ent, vector v1, bone bone, vector v2) @@ -539,7 +541,7 @@ local function noCollideCreate(self, ent1, ent2, bone1, bone2) local cons = constraint.NoCollide(ent1, ent2, bone1 or 0, bone2 or 0) if not verifyConstraint(self, cons) then return end - postCreate(self, "NoCollide", ent1, ent2, cons) + postCreate(self, "NoCollide", cons) end e2function void entity:noCollide(entity target) @@ -586,7 +588,7 @@ local function weldCreate(self, ent1, ent2, bone1, bone2, forcelimit, nocollide) local cons = constraint.Weld(ent1, ent2, bone1 or 0, bone2 or 0, forcelimit or 0, nocollide ~= 0) if not verifyConstraint(self, cons) then return end - postCreate(self, "Weld", ent1, ent2, cons) + postCreate(self, "Weld", cons) end e2function void entity:weld(entity target) From 781e1779ab7def5f8c0b90b1e2a665073a315f92 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Mon, 5 Jan 2026 05:22:42 +0300 Subject: [PATCH 5/8] Disable nocollides on remove --- .../gmod_wire_expression2/core/custom/constraintcore.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua index 007498d703..c4f2c44a9d 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua @@ -538,7 +538,7 @@ local function noCollideCreate(self, ent1, ent2, bone1, bone2) if not checkEnts(self, ent1, ent2) then return end if not checkCount(self, false) then return end - local cons = constraint.NoCollide(ent1, ent2, bone1 or 0, bone2 or 0) + local cons = constraint.NoCollide(ent1, ent2, bone1 or 0, bone2 or 0, true) if not verifyConstraint(self, cons) then return end postCreate(self, "NoCollide", cons) From 4dd435034df266ec00eb79adb5d47b7bab73d7a6 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Mon, 5 Jan 2026 05:29:47 +0300 Subject: [PATCH 6/8] Make linter happy --- .../gmod_wire_expression2/core/custom/constraintcore.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua index c4f2c44a9d..1346559f79 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua @@ -4,7 +4,6 @@ local IsValid = IsValid local isValidBone = E2Lib.isValidBone local getBone = E2Lib.getBone local math_min = math.min -local math_max = math.max local table_insert = table.insert local shouldCleanup = CreateConVar( "wire_expression2_constraints_cleanup", "0", FCVAR_ARCHIVE, "Whether or not Constraint Core should remove all constraints made by an E2 when it's deleted") From d15496b1f9b7e9d243e5c78ba11ae905ab47f99f Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Mon, 5 Jan 2026 05:30:15 +0300 Subject: [PATCH 7/8] Minor change --- .../gmod_wire_expression2/core/custom/constraintcore.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua index 1346559f79..1dab368795 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua @@ -6,7 +6,7 @@ local getBone = E2Lib.getBone local math_min = math.min local table_insert = table.insert -local shouldCleanup = CreateConVar( "wire_expression2_constraints_cleanup", "0", FCVAR_ARCHIVE, "Whether or not Constraint Core should remove all constraints made by an E2 when it's deleted") +local shouldCleanup = CreateConVar("wire_expression2_constraints_cleanup", "0", FCVAR_ARCHIVE, "Whether or not Constraint Core should remove all constraints made by an E2 when it's deleted") local playerCounts = WireLib.RegisterPlayerTable() -- Returns the table being used to keep track of counts From af1ece1e7e6031f3978d32181bc7b62feb0fa6f4 Mon Sep 17 00:00:00 2001 From: Astralcircle <142503363+Astralcircle@users.noreply.github.com> Date: Tue, 6 Jan 2026 05:32:43 +0300 Subject: [PATCH 8/8] Forgot to remove that one debug print --- .../gmod_wire_expression2/core/custom/constraintcore.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua index 1dab368795..bd54a56246 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/constraintcore.lua @@ -129,7 +129,6 @@ local function addUndo(self, const_type, const, rope) undo.Create("E2 " .. const_type) undo.SetPlayer(ply) undo.AddEntity(const) - print(const) if rope then undo.AddEntity(rope) end undo.Finish() end