From 0eb15eca7e2ebc6c23e3495b4cfd5c7ba3aa31ad Mon Sep 17 00:00:00 2001 From: LengthenedGradient <109800352+LengthenedGradient@users.noreply.github.com> Date: Fri, 19 Jun 2026 00:26:05 -0400 Subject: [PATCH 1/5] Add parallelogram shape This may help in the construction of armor in other addons like ACF. Not much more complexity than a solid cube. --- lua/primitive/core/construct.lua | 42 +++++++++++++++++++++++++++++++ lua/primitive/entities/shapes.lua | 11 +++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lua/primitive/core/construct.lua b/lua/primitive/core/construct.lua index ce51e23..fc92910 100644 --- a/lua/primitive/core/construct.lua +++ b/lua/primitive/core/construct.lua @@ -2369,6 +2369,48 @@ registerType( "wedge_corner", function( param, data, threaded, physics ) end ) +-- PARALLELOGRAM +registerType( "parallelogram", function( param, data, threaded, physics ) + local dx = ( isvector( param.PrimSIZE ) and param.PrimSIZE[1] or 1 ) * 0.5 + local dy = ( isvector( param.PrimSIZE ) and param.PrimSIZE[2] or 1 ) * 0.5 + local dz = ( isvector( param.PrimSIZE ) and param.PrimSIZE[3] or 1 ) * 0.5 + + local slant = math_clamp( tonumber( param.PrimSLANT ) or 0, -89, 89 ) + local shift = math_tan( math_rad( slant ) ) * dz * 2 + + local model = simpleton.New() + local verts = model.verts + + -- Bottom face at z=-dz is unshifted; all horizontal offset goes to the top face. + -- The entity origin sits at the center of the bottom face. + model:PushXYZ( dx, dy, -dz ) -- 1 bottom y+ x+ + model:PushXYZ( dx, -dy, -dz ) -- 2 bottom y- x+ + model:PushXYZ( -dx, -dy, -dz ) -- 3 bottom y- x- + model:PushXYZ( -dx, dy, -dz ) -- 4 bottom y+ x- + model:PushXYZ( dx + shift, dy, dz ) -- 5 top y+ x+ + model:PushXYZ( dx + shift, -dy, dz ) -- 6 top y- x+ + model:PushXYZ( -dx + shift, -dy, dz ) -- 7 top y- x- + model:PushXYZ( -dx + shift, dy, dz ) -- 8 top y+ x- + + if CLIENT then + model:PushFace( 1, 2, 3, 4 ) -- bottom (-z) + model:PushFace( 5, 8, 7, 6 ) -- top (+z) + model:PushFace( 1, 4, 8, 5 ) -- y+ side + model:PushFace( 2, 6, 7, 3 ) -- y- side + model:PushFace( 2, 1, 5, 6 ) -- x+ side (slanted) + model:PushFace( 4, 3, 7, 8 ) -- x- side (slanted) + end + + if physics then + model.convexes = { verts } + end + + util_Transform( verts, param.PrimMESHROT, param.PrimMESHPOS, threaded ) + + return model +end ) + + -- AIRFOIL local function NACA4DIGIT( distr, points, chord, M, P, T, openEdge, ox, oy, oz ) ox = ox or 0 diff --git a/lua/primitive/entities/shapes.lua b/lua/primitive/entities/shapes.lua index 7340d6a..735f277 100644 --- a/lua/primitive/entities/shapes.lua +++ b/lua/primitive/entities/shapes.lua @@ -2,7 +2,7 @@ do local class = {} - local typen = { "cone", "cube", "cube_magic", "cube_hole", "cylinder", "dome", "plane", "pyramid", "sphere", "torus", "tube", "wedge", "wedge_corner" } + local typen = { "cone", "cube", "cube_magic", "cube_hole", "cylinder", "dome", "parallelogram", "plane", "pyramid", "sphere", "torus", "tube", "wedge", "wedge_corner" } local typek, defaults = {}, {} do @@ -18,6 +18,7 @@ do PrimNUMSEG = 16, PrimSIDES = 0, PrimSIZE = Vector( 48, 48, 48 ), + PrimSLANT = 0, PrimSUBDIV = 8, PrimTX = 0, PrimTY = 0, @@ -70,6 +71,12 @@ do PrimSUBDIV = 8, PrimTYPE = "dome", }, + parallelogram = { + PrimMESHSMOOTH = 0, + PrimSIZE = Vector( 48, 48, 48 ), + PrimSLANT = 0, + PrimTYPE = "parallelogram", + }, plane = { PrimMESHSMOOTH = 0, PrimSIZE = Vector( 48, 48, 48 ), @@ -163,6 +170,7 @@ do self:PrimitiveVar( "PrimDT", "Float", { category = "modify", title = "thickness", panel = "float", min = 1, max = 1000 }, true ) self:PrimitiveVar( "PrimTX", "Float", { category = "modify", title = "taper x", panel = "float", min = -1, max = 1 }, true ) self:PrimitiveVar( "PrimTY", "Float", { category = "modify", title = "taper y", panel = "float", min = -1, max = 1 }, true ) + self:PrimitiveVar( "PrimSLANT", "Float", { category = "modify", title = "slant angle", panel = "float", min = -80, max = 80 }, true ) self:PrimitiveVar( "PrimSUBDIV", "Int", { category = "modify", title = "subdivide", panel = "int", min = 1, max = 32 }, true ) self:PrimitiveVar( "PrimMAXSEG", "Int", { category = "modify", title = "max segments", panel = "int", min = 1, max = 32 }, true ) @@ -180,6 +188,7 @@ do { category = "shapes", entity = "primitive_shape", title = "cube_hole", command = "cube_hole 1 48" }, { category = "shapes", entity = "primitive_shape", title = "cylinder", command = "cylinder 1 48" }, { category = "shapes", entity = "primitive_shape", title = "dome", command = "dome 1 48" }, + { category = "shapes", entity = "primitive_shape", title = "parallelogram", command = "parallelogram 1 48" }, { category = "shapes", entity = "primitive_shape", title = "plane", command = "plane 1 48" }, { category = "shapes", entity = "primitive_shape", title = "pyramid", command = "pyramid 1 48" }, { category = "shapes", entity = "primitive_shape", title = "sphere", command = "sphere 1 48" }, From ad6aa8f2081bafe6bfba3607e9cacbb11fd46b05 Mon Sep 17 00:00:00 2001 From: LengthenedGradient <109800352+LengthenedGradient@users.noreply.github.com> Date: Fri, 19 Jun 2026 01:35:10 -0400 Subject: [PATCH 2/5] Add millimeter sizing option XYZ dimensions will be interpreted in terms of the provided unit (source units by default), but millimeters is now also an option. Minimum size will still be kept to 1u x 1u x 1u. --- lua/primitive/core/construct.lua | 8 ++++++++ lua/primitive/entities/shapes.lua | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lua/primitive/core/construct.lua b/lua/primitive/core/construct.lua index fc92910..a56b159 100644 --- a/lua/primitive/core/construct.lua +++ b/lua/primitive/core/construct.lua @@ -270,6 +270,14 @@ do either a function or a coroutine that will build the mesh --]] function addon.construct.get( name, param, threaded, physics ) + if param.PrimUNITS == "millimeters" then + param = table.Copy( param ) + if isvector( param.PrimSIZE ) then + local s = param.PrimSIZE * 0.03937 + param.PrimSIZE = Vector( math_max( s.x, 1 ), math_max( s.y, 1 ), math_max( s.z, 1 ) ) + end + if isnumber( param.PrimDT ) then param.PrimDT = math_max( param.PrimDT * 0.03937, 1 ) end + end return addon.construct.generate( construct_types[name], param, threaded, physics ) end end diff --git a/lua/primitive/entities/shapes.lua b/lua/primitive/entities/shapes.lua index 735f277..7085fb2 100644 --- a/lua/primitive/entities/shapes.lua +++ b/lua/primitive/entities/shapes.lua @@ -3,7 +3,7 @@ do local class = {} local typen = { "cone", "cube", "cube_magic", "cube_hole", "cylinder", "dome", "parallelogram", "plane", "pyramid", "sphere", "torus", "tube", "wedge", "wedge_corner" } - local typek, defaults = {}, {} + local typek, unitk, defaults = {}, { source = "source", millimeters = "millimeters" }, {} do for k, v in pairs( typen ) do @@ -22,6 +22,7 @@ do PrimSUBDIV = 8, PrimTX = 0, PrimTY = 0, + PrimUNITS = "source", }, cone = { PrimMAXSEG = 16, @@ -165,6 +166,7 @@ do function class:PrimitiveSetupDataTables() self:PrimitiveVar( "PrimTYPE", "String", { category = "modify", title = "type", panel = "combo", values = typek, icons = "primitive/icons/%s.png" }, true ) + self:PrimitiveVar( "PrimUNITS", "String", { global = true, category = "modify", title = "units", panel = "combo", values = unitk }, true ) self:PrimitiveVar( "PrimSIZE", "Vector", { category = "modify", title = "size", panel = "vector", min = Vector( 1, 1, 1 ), max = Vector( 1000, 1000, 1000 ) }, true ) self:PrimitiveVar( "PrimDT", "Float", { category = "modify", title = "thickness", panel = "float", min = 1, max = 1000 }, true ) @@ -383,6 +385,7 @@ do function class:PrimitiveSetupDataTables() self:PrimitiveVar( "PrimTYPE", "String", { category = "modify", title = "type", panel = "combo", values = typek, icons = "primitive/icons/%s.png" }, true ) + self:PrimitiveVar( "PrimUNITS", "String", { global = true, category = "modify", title = "units", panel = "combo", values = unitk }, true ) self:PrimitiveVar( "PrimSIZE", "Vector", { category = "modify", title = "size", panel = "vector", min = Vector( 1, 1, 1 ), max = Vector( 1000, 1000, 1000 ) }, true ) -- self:PrimitiveVar( "PrimDT", "Float", { category = "modify", title = "thickness", panel = "float", min = 1, max = 1000 }, true ) From 04484b0025fbf7ca06126e4b1a75b4ff215835eb Mon Sep 17 00:00:00 2001 From: LengthenedGradient <109800352+LengthenedGradient@users.noreply.github.com> Date: Fri, 19 Jun 2026 22:42:05 -0400 Subject: [PATCH 3/5] Fix parallelogram Icon and angle I tried, but primitives have helicopter bomb models. Just use cube icon for now. Slant angle replaced with overhang, which represents how much the top face is shifted horizontally, relative to the bottom face --- lua/primitive/core/construct.lua | 8 ++++---- lua/primitive/entities/shapes.lua | 2 +- materials/primitive/icons/parallelogram.png | Bin 0 -> 629 bytes 3 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 materials/primitive/icons/parallelogram.png diff --git a/lua/primitive/core/construct.lua b/lua/primitive/core/construct.lua index a56b159..701ab4f 100644 --- a/lua/primitive/core/construct.lua +++ b/lua/primitive/core/construct.lua @@ -12,8 +12,8 @@ local addon = Primitive local bit, math, util, table, isvector, WorldToLocal, LocalToWorld, Vector, Angle = bit, math, util, table, isvector, WorldToLocal, LocalToWorld, Vector, Angle -local math_abs, math_sin, math_cos, math_tan, math_asin, math_acos, math_atan, math_atan2, math_rad, math_deg, math_sqrt = - math.abs, math.sin, math.cos, math.tan, math.asin, math.acos, math.atan, math.atan2, math.rad, math.deg, math.sqrt +local math_abs, math_sin, math_cos, math_asin, math_acos, math_atan, math_atan2, math_rad, math_deg, math_sqrt = + math.abs, math.sin, math.cos, math.asin, math.acos, math.atan, math.atan2, math.rad, math.deg, math.sqrt local math_ceil, math_floor, math_round, math_min, math_max, math_clamp = math.ceil, math.floor, math.Round, math.min, math.max, math.Clamp @@ -277,6 +277,7 @@ do param.PrimSIZE = Vector( math_max( s.x, 1 ), math_max( s.y, 1 ), math_max( s.z, 1 ) ) end if isnumber( param.PrimDT ) then param.PrimDT = math_max( param.PrimDT * 0.03937, 1 ) end + if isnumber( param.PrimSLANT ) then param.PrimSLANT = param.PrimSLANT * 0.03937 end end return addon.construct.generate( construct_types[name], param, threaded, physics ) end @@ -2383,8 +2384,7 @@ registerType( "parallelogram", function( param, data, threaded, physics ) local dy = ( isvector( param.PrimSIZE ) and param.PrimSIZE[2] or 1 ) * 0.5 local dz = ( isvector( param.PrimSIZE ) and param.PrimSIZE[3] or 1 ) * 0.5 - local slant = math_clamp( tonumber( param.PrimSLANT ) or 0, -89, 89 ) - local shift = math_tan( math_rad( slant ) ) * dz * 2 + local shift = tonumber( param.PrimSLANT ) or 0 local model = simpleton.New() local verts = model.verts diff --git a/lua/primitive/entities/shapes.lua b/lua/primitive/entities/shapes.lua index 7085fb2..f1e3faa 100644 --- a/lua/primitive/entities/shapes.lua +++ b/lua/primitive/entities/shapes.lua @@ -172,7 +172,7 @@ do self:PrimitiveVar( "PrimDT", "Float", { category = "modify", title = "thickness", panel = "float", min = 1, max = 1000 }, true ) self:PrimitiveVar( "PrimTX", "Float", { category = "modify", title = "taper x", panel = "float", min = -1, max = 1 }, true ) self:PrimitiveVar( "PrimTY", "Float", { category = "modify", title = "taper y", panel = "float", min = -1, max = 1 }, true ) - self:PrimitiveVar( "PrimSLANT", "Float", { category = "modify", title = "slant angle", panel = "float", min = -80, max = 80 }, true ) + self:PrimitiveVar( "PrimSLANT", "Float", { category = "modify", title = "overhang", panel = "float", min = -1000, max = 1000 }, true ) self:PrimitiveVar( "PrimSUBDIV", "Int", { category = "modify", title = "subdivide", panel = "int", min = 1, max = 32 }, true ) self:PrimitiveVar( "PrimMAXSEG", "Int", { category = "modify", title = "max segments", panel = "int", min = 1, max = 32 }, true ) diff --git a/materials/primitive/icons/parallelogram.png b/materials/primitive/icons/parallelogram.png new file mode 100644 index 0000000000000000000000000000000000000000..ec67f53bf8ec4392425af7d33dd6c049cee2ba72 GIT binary patch literal 629 zcmV-*0*d{KP)R5%e;l0AzWQ51$}#;cAWs92@gVv8+P><>sGxI!QZA_^%3 z$v?2L2wS8`A^8Idq)@O(W#g2h2GRt!NSPwV7F%wy_<`S=_qn?x?t#m__uO-y^PV%~ zIx^RFox|b4@pvAMMwh$Y?ma$ZOsh~R+?~dSu`Y+u!hqp$Sc%1A&1f`wDX_oYZvU)S ztLtL17!XSwM$u=0!C;VEuh$JFen_X&F9fkco6W|V&1Uy{YsvS$R4P4$#k4;%#^dp; zNF?&n^Spwj`&7`~0`~hoS4VH$11X}VU-;Zkr(<%tTqT>$en}(}=jzucEfx!^+N4w} z<;3H03q;L)KL0nFOs*@H$`3D-$rw@JNZz?BJ1kYO5a0J5+CV|*f7&mkyx4BHjZwdr zj65nb7C{%lN#b(3vFj0t+HWpZIBy? P00000NkvXXu0mjf;3Oa> literal 0 HcmV?d00001 From ea4fa408fb89a333f9daae5d4563ed70a0b90d60 Mon Sep 17 00:00:00 2001 From: LengthenedGradient <109800352+LengthenedGradient@users.noreply.github.com> Date: Sat, 20 Jun 2026 00:31:44 -0400 Subject: [PATCH 4/5] Add hollow dome shape Maximum number of convexes is 32, no more than the most you can get on a tube. --- lua/primitive/core/construct.lua | 90 ++++++++++++++++++++++ lua/primitive/entities/shapes.lua | 10 ++- materials/primitive/icons/dome_hollow.png | Bin 0 -> 510 bytes 3 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 materials/primitive/icons/dome_hollow.png diff --git a/lua/primitive/core/construct.lua b/lua/primitive/core/construct.lua index 701ab4f..f413829 100644 --- a/lua/primitive/core/construct.lua +++ b/lua/primitive/core/construct.lua @@ -1927,6 +1927,96 @@ registerType( "dome", function( param, data, threaded, physics ) end, { canThread = true, domePlane = { pos = Vector(), normal = Vector( 0, 0, 1 ) } } ) +-- DOME_HOLLOW +-- Pushes interleaved outer+inner hemisphere verts into model over rings+1 latitude bands. +-- Each position v in ring r stores [outer, inner] consecutively; twoRing = 2*(sdiv+1) gives the same place on the next ring. +local function pushHollowRings( model, rings, sdiv, dx, dy, dz, idx, idy, idz ) + for r = 0, rings do + local t = math_pi * 0.5 * ( 1 - r / rings ) + local sinT, cosT = math_sin( t ), math_cos( t ) + for v = 0, sdiv do + local p = math_tau * v / sdiv + model:PushXYZ( -dx * math_cos( p ) * sinT, dy * math_sin( p ) * sinT, dz * cosT ) -- outer + model:PushXYZ( -idx * math_cos( p ) * sinT, idy * math_sin( p ) * sinT, idz * cosT ) -- inner + end + end +end + +registerType( "dome_hollow", function( param, data, threaded, physics ) + local subdiv = 2 * math_round( ( param.PrimSUBDIV or 8 ) / 2 ) + if subdiv < 4 then subdiv = 4 elseif subdiv > 32 then subdiv = 32 end + + local dx = ( isvector( param.PrimSIZE ) and param.PrimSIZE[1] or 1 ) * 0.5 + local dy = ( isvector( param.PrimSIZE ) and param.PrimSIZE[2] or 1 ) * 0.5 + local dz = ( isvector( param.PrimSIZE ) and param.PrimSIZE[3] or 1 ) * 0.5 + local dt = math_max( math_min( param.PrimDT or 1, dx - 1, dy - 1, dz - 1 ), 1 ) + + local idx = dx - dt + local idy = dy - dt + local idz = dz - dt + + local numRings = subdiv / 2 + local ringSize = subdiv + 1 -- verts per ring: subdiv segments need subdiv+1 verts to close the loop + local twoRing = ringSize * 2 -- stride per ring in interleaved layout + + local model = simpleton.New() + + if CLIENT then + pushHollowRings( model, numRings, subdiv, dx, dy, dz, idx, idy, idz ) + + -- Emit quad strips between adjacent rings. Each ring occupies twoRing slots, + -- so adding twoRing to an index moves to the same position one ring toward the apex. + for r = 1, numRings do + for v = 0, subdiv - 1 do + local a = 1 + ( r - 1 ) * twoRing + v * 2 -- bottom-left outer + local d = a + twoRing -- top-left outer + model:PushFace( d, d + 2, a + 2, a ) -- outer, outward normals + model:PushFace( a + 1, a + 3, d + 3, d + 1 ) -- inner, inward normals + end + end + + -- Close the open bottom edge with a ring of rim quads connecting outer equator to inner equator. + for v = 0, subdiv - 1 do + local ao = 1 + v * 2 + model:PushFace( ao, ao + 2, ao + 3, ao + 1 ) -- rim, downward normals + end + + util_Transform( model.verts, param.PrimMESHROT, param.PrimMESHPOS, threaded ) + end + + if physics then + -- Physics uses a lower subdivision cap to keep the convex count reasonable. + local physSubdiv = math_min( subdiv, 8 ) + local physRings = physSubdiv / 2 + local physRingSz = physSubdiv + 1 + local physTwoRing = physRingSz * 2 + local physModel = simpleton.New() + local physVerts = physModel.verts + + pushHollowRings( physModel, physRings, physSubdiv, dx, dy, dz, idx, idy, idz ) + + -- One convex per patch: four outer corners + four inner corners of each wall quad. + -- This approximates the hollow shell as a set of thin wedge-shaped convex hulls. + local convexes = {} + for r = 0, physRings - 1 do + for v = 0, physSubdiv - 1 do + local oa = 1 + r * physTwoRing + v * 2 -- bottom-left outer + local od = oa + physTwoRing -- top-left outer + convexes[#convexes + 1] = { + physVerts[oa], physVerts[oa + 2], physVerts[od], physVerts[od + 2], -- outer quad corners + physVerts[oa + 1], physVerts[oa + 3], physVerts[od + 1], physVerts[od + 3], -- inner quad corners + } + end + end + + model.convexes = convexes + util_Transform( physVerts, param.PrimMESHROT, param.PrimMESHPOS, threaded ) + end + + return model +end ) + + -- PLANE registerType( "plane", function( param, data, threaded, physics ) local dx = ( isvector( param.PrimSIZE ) and param.PrimSIZE[1] or 1 ) * 0.5 diff --git a/lua/primitive/entities/shapes.lua b/lua/primitive/entities/shapes.lua index f1e3faa..02c14ca 100644 --- a/lua/primitive/entities/shapes.lua +++ b/lua/primitive/entities/shapes.lua @@ -2,7 +2,7 @@ do local class = {} - local typen = { "cone", "cube", "cube_magic", "cube_hole", "cylinder", "dome", "parallelogram", "plane", "pyramid", "sphere", "torus", "tube", "wedge", "wedge_corner" } + local typen = { "cone", "cube", "cube_magic", "cube_hole", "cylinder", "dome", "dome_hollow", "parallelogram", "plane", "pyramid", "sphere", "torus", "tube", "wedge", "wedge_corner" } local typek, unitk, defaults = {}, { source = "source", millimeters = "millimeters" }, {} do @@ -72,6 +72,13 @@ do PrimSUBDIV = 8, PrimTYPE = "dome", }, + dome_hollow = { + PrimDT = 4, + PrimMESHSMOOTH = 65, + PrimSIZE = Vector( 48, 48, 48 ), + PrimSUBDIV = 8, + PrimTYPE = "dome_hollow", + }, parallelogram = { PrimMESHSMOOTH = 0, PrimSIZE = Vector( 48, 48, 48 ), @@ -190,6 +197,7 @@ do { category = "shapes", entity = "primitive_shape", title = "cube_hole", command = "cube_hole 1 48" }, { category = "shapes", entity = "primitive_shape", title = "cylinder", command = "cylinder 1 48" }, { category = "shapes", entity = "primitive_shape", title = "dome", command = "dome 1 48" }, + { category = "shapes", entity = "primitive_shape", title = "dome_hollow", command = "dome_hollow 1 48" }, { category = "shapes", entity = "primitive_shape", title = "parallelogram", command = "parallelogram 1 48" }, { category = "shapes", entity = "primitive_shape", title = "plane", command = "plane 1 48" }, { category = "shapes", entity = "primitive_shape", title = "pyramid", command = "pyramid 1 48" }, diff --git a/materials/primitive/icons/dome_hollow.png b/materials/primitive/icons/dome_hollow.png new file mode 100644 index 0000000000000000000000000000000000000000..42209f1a87470db491406d989f73e6a26e475e13 GIT binary patch literal 510 zcmVoV_Rovn-22o0&^b;_2+P zJ|g0h02n2gzSOp`Gj6wAv-~$VaUeR#=YVy$+pXksxti;`*I-G~G<};)CWBV1^(lBE z(FC%{7>40(sZ@G$9Oq`SSa`N=t86x_R;$%}6h)7XMq^+~JDf+i*Xy18zW-b-7O!ws zZ8jUNh$QssbUGZ5$9Ew4A_))LB8ic*^ZERxTrHQ&3Tjj)lhH&ZhSy}7asP-x5O|P! z0V0>zDVvLQ&+`;}obBF)yV~{y0422bdadOGr~y=l_t1`a;AeezI-TDk5VpK#v)N1l z2xqg|{`)wi^E%^vJ|E%0OS|1p$WC&tfC;@`uMa@*fY*P8$IIn1iQ||a!P&dVks-;5 z-;r3Foed6X{eIss6bcncKSRkk8Da6GTCGO1Eb-`XG)YJ#SD4de$;=%VCQx#ToYO=d zbI$1O{UH#5d5t~VDXH$616h*DndFQnRu}mB0aJY9apeiu_5c6?07*qoM6N<$f{wT8 AJOBUy literal 0 HcmV?d00001 From 2686f646e3eff191f6a0c15681a648bed38ee8fa Mon Sep 17 00:00:00 2001 From: LengthenedGradient <109800352+LengthenedGradient@users.noreply.github.com> Date: Sat, 20 Jun 2026 01:24:33 -0400 Subject: [PATCH 5/5] Satisfy GLuaTest Guard against invalid parameters --- lua/primitive/core/construct.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/primitive/core/construct.lua b/lua/primitive/core/construct.lua index f413829..222bf21 100644 --- a/lua/primitive/core/construct.lua +++ b/lua/primitive/core/construct.lua @@ -270,7 +270,7 @@ do either a function or a coroutine that will build the mesh --]] function addon.construct.get( name, param, threaded, physics ) - if param.PrimUNITS == "millimeters" then + if param and param.PrimUNITS == "millimeters" then param = table.Copy( param ) if isvector( param.PrimSIZE ) then local s = param.PrimSIZE * 0.03937