diff --git a/lua/entities/gmod_wire_expression2/core/custom/prop2mesh.lua b/lua/entities/gmod_wire_expression2/core/custom/prop2mesh.lua index 15bddac..c38f851 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/prop2mesh.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/prop2mesh.lua @@ -449,6 +449,22 @@ e2function vector4 entity:p2mGetColor(index) local info = this.prop2mesh_controllers[index] return {info.col.r, info.col.g, info.col.b, info.col.a} end +e2function vector entity:p2mGetPos(index) + if not checkvalid(self, this, nil, index, nil) then + return {0,0,0} + end + local linkpos = this.prop2mesh_controllers[index].linkpos + if not linkpos then return {0,0,0} end + return {linkpos.x, linkpos.y, linkpos.z} +end +e2function angle entity:p2mGetAng(index) + if not checkvalid(self, this, nil, index, nil) then + return {0,0,0} + end + local linkang = this.prop2mesh_controllers[index].linkang + if not linkang then return {0,0,0} end + return {linkang.p, linkang.y, linkang.r} +end e2function string entity:p2mGetMaterial(index) if not checkvalid(self, this, nil, index, nil) then return "" diff --git a/lua/entities/sent_prop2mesh/cl_init.lua b/lua/entities/sent_prop2mesh/cl_init.lua index 6beea15..d2f229d 100644 --- a/lua/entities/sent_prop2mesh/cl_init.lua +++ b/lua/entities/sent_prop2mesh/cl_init.lua @@ -37,6 +37,7 @@ local Ent_SetColor = entMeta.SetColor local Ent_GetTable = entMeta.GetTable local Ent_DrawModel = entMeta.DrawModel local Ent_GetAngles = entMeta.GetAngles +local Ent_GetParent = entMeta.GetParent local Ent_SetParent = entMeta.SetParent local Ent_SetAngles = entMeta.SetAngles local Ent_SetMaterial = entMeta.SetMaterial @@ -396,6 +397,39 @@ local function drawMesh(self) return meshes and meshes.basic or empty end +local function refreshSetColor(infoEnt, col) + local isOpaque = col.a == 255 + + Ent_SetColor(infoEnt, col) + Ent_SetRenderMode(infoEnt, isOpaque and RENDERMODE_NORMAL or RENDERMODE_TRANSCOLOR) + infoEnt.RenderGroup = isOpaque and RENDERGROUP_OPAQUE or RENDERGROUP_BOTH +end + +local function refreshSetScale(infoEnt, scale) + if scale.x ~= 1 or scale.y ~= 1 or scale.z ~= 1 then + local matrix = Matrix() + matrix:SetScale(scale) + Ent_EnableMatrix(infoEnt, "RenderMultiply", matrix) + infoEnt.scale = scale + else + Ent_DisableMatrix(infoEnt, "RenderMultiply") + infoEnt.scale = nil + end +end + +local function refreshSetPosAng(infoEnt, info, p2mEnt) + local linkEnt = info.linkent + local parent = IsValid(linkEnt) and linkEnt or p2mEnt + local pos, ang = LocalToWorld(info.linkpos or vecZero, info.linkang or angZero, Ent_GetPos(parent), Ent_GetAngles(parent)) + + if parent ~= Ent_GetParent(infoEnt) then + Ent_SetParent(infoEnt, parent) + end + + Ent_SetPos(infoEnt, pos) + Ent_SetAngles(infoEnt, ang) +end + local function refresh(self, info) local infoEnt = info.ent @@ -411,33 +445,12 @@ local function refresh(self, info) info.ent = infoEnt end - local linkEnt = info.linkent - local parent = IsValid(linkEnt) and linkEnt or self - local pos, ang = LocalToWorld(info.linkpos or vecZero, info.linkang or angZero, Ent_GetPos(parent), Ent_GetAngles(parent)) - - Ent_SetParent(infoEnt, parent) - Ent_SetAngles(infoEnt, ang) - Ent_SetPos(infoEnt, pos) - local infoEntTable = Ent_GetTable(infoEnt) - local infoCol = info.col - local isOpaque = infoCol.a == 255 Ent_SetMaterial(infoEnt, info.mat) - Ent_SetColor(infoEnt, infoCol) - Ent_SetRenderMode(infoEnt, isOpaque and RENDERMODE_NORMAL or RENDERMODE_TRANSCOLOR) - infoEntTable.RenderGroup = isOpaque and RENDERGROUP_OPAQUE or RENDERGROUP_BOTH - - local infoScale = info.scale - if infoScale.x ~= 1 or infoScale.y ~= 1 or infoScale.z ~= 1 then - local matrix = Matrix() - matrix:SetScale(infoScale) - Ent_EnableMatrix(infoEnt, "RenderMultiply", matrix) - infoEnt.scale = info.scale - else - Ent_DisableMatrix(infoEnt, "RenderMultiply") - infoEnt.scale = nil - end + refreshSetColor(infoEnt, info.col) + refreshSetScale(infoEnt, info.scale) + refreshSetPosAng(infoEnt, info, self) local infoCrc = info.crc local infoUniqueID = info.uniqueID @@ -583,10 +596,72 @@ function ENT:GetDownloadProgress() end +local kvpass = {} +local function applyPropertyWithKVPass(ent, index, key, val) + local info = ent.prop2mesh_controllers[index] + if not info then return end + + local pass = kvpass[key] + + if pass then + pass(self, info, val) + val = info[key] -- Get the modified result + else + info[key] = val + end + + return val, info.ent +end + +function ENT:SetControllerCol(index, col) + local infoEnt + col, infoEnt = applyPropertyWithKVPass(self, index, "col", col) + if col == nil then return end + if not IsValid(infoEnt) then return end + + refreshSetColor(infoEnt, col) +end + +function ENT:SetControllerPos(index, linkpos) + local infoEnt + linkpos, infoEnt = applyPropertyWithKVPass(self, index, "linkpos", linkpos) + if linkpos == nil then return end + if not IsValid(infoEnt) then return end + + refreshSetPosAng(infoEnt, self.prop2mesh_controllers[index], self) +end + +function ENT:SetControllerAng(index, linkang) + local infoEnt + linkang, infoEnt = applyPropertyWithKVPass(self, index, "linkang", linkang) + if linkang == nil then return end + if not IsValid(infoEnt) then return end + + refreshSetPosAng(infoEnt, self.prop2mesh_controllers[index], self) +end + +function ENT:SetControllerMat(index, mat) + local infoEnt + mat, infoEnt = applyPropertyWithKVPass(self, index, "mat", mat) + if mat == nil then return end + if not IsValid(infoEnt) then return end + + Ent_SetMaterial(infoEnt, mat) +end + +function ENT:SetControllerScale(index, scale) + local infoEnt + scale, infoEnt = applyPropertyWithKVPass(self, index, "scale", scale) + if scale == nil then return end + if not IsValid(infoEnt) then return end + + refreshSetScale(infoEnt, scale) +end + + --[[ ]] -local kvpass = {} kvpass.crc = function(self, info, val) local crc = info.crc info.crc = val @@ -667,7 +742,8 @@ kvpass.mat = function(self, info, val) end kvpass.scale = function(self, info, val) - info.scale = Vector(unpack(val)) + if type(val) == "table" then val = Vector(unpack(val)) end + info.scale = val end kvpass.clips = function(self, info, val) diff --git a/lua/entities/sent_prop2mesh/init.lua b/lua/entities/sent_prop2mesh/init.lua index b4f5264..482c05f 100644 --- a/lua/entities/sent_prop2mesh/init.lua +++ b/lua/entities/sent_prop2mesh/init.lua @@ -438,6 +438,16 @@ function ENT:SetControllerLinkPos(index, val) end end +function ENT:GetControllerLinkPos(index) + local info = self.prop2mesh_controllers[index] + if not info then return end + + local linkpos = info.linkpos + if not linkpos then return Vector() end + + return Vector(linkpos.x, linkpos.y, linkpos.z) +end + function ENT:SetControllerLinkAng(index, val) local info = self.prop2mesh_controllers[index] if (info and isangle(val)) then @@ -453,6 +463,16 @@ function ENT:SetControllerLinkAng(index, val) end end +function ENT:GetControllerLinkAng(index) + local info = self.prop2mesh_controllers[index] + if not info then return end + + local linkang = info.linkang + if not linkang then return Angle() end + + return Angle(linkang.p, linkang.y, linkang.r) +end + function ENT:SetControllerName(index, val) local info = self.prop2mesh_controllers[index] if (info and isstring(val)) and (info.name ~= val) then diff --git a/lua/starfall/libs_cl/prop2mesh.lua b/lua/starfall/libs_cl/prop2mesh.lua index 63b919a..038d244 100644 --- a/lua/starfall/libs_cl/prop2mesh.lua +++ b/lua/starfall/libs_cl/prop2mesh.lua @@ -29,12 +29,33 @@ return function( instance ) local p2m_library = instance.Libraries.p2m local owrap, ounwrap = instance.WrapObject, instance.UnwrapObject local ents_methods, wrap, unwrap = instance.Types.Entity.Methods, instance.Types.Entity.Wrap, instance.Types.Entity.Unwrap - local ang_meta, aunwrap = instance.Types.Angle, instance.Types.Angle.Unwrap - local vec_meta, vunwrap = instance.Types.Vector, instance.Types.Vector.Unwrap + local ang_meta, awrap, aunwrap = instance.Types.Angle, instance.Types.Angle.Wrap, instance.Types.Angle.Unwrap + local vec_meta, vwrap, vunwrap = instance.Types.Vector, instance.Types.Vector.Wrap, instance.Types.Vector.Unwrap local col_meta, cwrap, cunwrap = instance.Types.Color, instance.Types.Color.Wrap, instance.Types.Color.Unwrap + local checkpermission = instance.player ~= SF.Superuser and SF.Permissions.check or function() end local recycle = prop2mesh.recycle + + local function getControllerInfo(ent, index) + CheckLuaType(index, TYPE_NUMBER) + + local controllers = ent.prop2mesh_controllers + if not controllers then + SF.Throw("This function is limited to sf controllers!", 3) + return false + end + + local info = controllers[index] + if not info then + SF.Throw(string.format("controller index %d does not exist on %s!", index, tostring(ent)), 3) + return false + end + + return info + end + + --- Manually sets controller info from a table clientside. It's important to note that this does not set the controller info serverside, so any modifications made to this P2M, dupe copying, etc. will not copy the inputted info -- @param number index index of controller -- @param table controllerData controller table to insert @@ -59,4 +80,103 @@ return function( instance ) prop2mesh.handleDownload(dataCRC, controllerDataComp) prop2mesh.refresh(ent, controller) end + + function ents_methods:p2mGetCount() + CheckType(self, ents_metatable) + local ent = unwrap(self) + local controllers = ent.prop2mesh_controllers + if not controllers then SF.Throw("This function is limited to sf controllers!", 2) end + + return #controllers + end + + function ents_methods:p2mSetColor(index, color) + CheckType(self, ents_metatable) + local ent = unwrap(self) + if not getControllerInfo(ent, index) then return end + checkpermission(instance, ent, "entities.setRenderProperty") + + ent:SetControllerCol(index, cunwrap(color)) + end + + function ents_methods:p2mGetColor(index) + CheckType(self, ents_metatable) + local ent = unwrap(self) + + return cwrap(getControllerInfo(ent, index).col) + end + + function ents_methods:p2mSetAlpha(index, alpha) + CheckType(self, ents_metatable) + CheckLuaType(alpha, TYPE_NUMBER) + local ent = unwrap(self) + local info = getControllerInfo(ent, index) + if not info then return end + checkpermission(instance, ent, "entities.setRenderProperty") + + info.col.a = alpha + ent:SetControllerCol(index, info.col) + end + + function ents_methods:p2mSetPos(index, pos) + CheckType(self, ents_metatable) + local ent = unwrap(self) + if not getControllerInfo(ent, index) then return end + checkpermission(instance, ent, "entities.setRenderProperty") + + ent:SetControllerPos(index, vunwrap(pos)) + end + + function ents_methods:p2mGetPos(index) + CheckType(self, ents_metatable) + local ent = unwrap(self) + local info = getControllerInfo(ent, index) + if not info then return end + + return vwrap(info.linkpos or Vector()) + end + + function ents_methods:p2mSetAng(index, ang) + CheckType(self, ents_metatable) + local ent = unwrap(self) + if not getControllerInfo(ent, index) then return end + checkpermission(instance, ent, "entities.setRenderProperty") + + ent:SetControllerAng(index, aunwrap(ang)) + end + + function ents_methods:p2mGetAng(index) + CheckType(self, ents_metatable) + local ent = unwrap(self) + local info = getControllerInfo(ent, index) + if not info then return end + + return awrap(info.linkang or Angle()) + end + + function ents_methods:p2mSetMaterial(index, mat) + CheckType(self, ents_metatable) + CheckLuaType(mat, TYPE_STRING) + local ent = unwrap(self) + if not getControllerInfo(ent, index) then return end + checkpermission(instance, ent, "entities.setRenderProperty") + + ent:SetControllerMat(index, mat) + end + + function ents_methods:p2mGetMaterial(index) + CheckType(self, ents_metatable) + local ent = unwrap(self) + + return getControllerInfo(ent, index).mat + end + + function ents_methods:p2mSetScale(index, scale) + CheckType(self, ents_metatable) + local ent = unwrap(self) + if not getControllerInfo(ent, index) then return end + checkpermission(instance, ent, "entities.setRenderProperty") + + ent:SetControllerScale(index, vunwrap(scale)) + end end diff --git a/lua/starfall/libs_sv/prop2mesh.lua b/lua/starfall/libs_sv/prop2mesh.lua index 2aaa202..bc4e77d 100644 --- a/lua/starfall/libs_sv/prop2mesh.lua +++ b/lua/starfall/libs_sv/prop2mesh.lua @@ -141,8 +141,8 @@ return function( instance ) local p2m_library = instance.Libraries.p2m local owrap, ounwrap = instance.WrapObject, instance.UnwrapObject local ents_methods, wrap, unwrap = instance.Types.Entity.Methods, instance.Types.Entity.Wrap, instance.Types.Entity.Unwrap - local ang_meta, aunwrap = instance.Types.Angle, instance.Types.Angle.Unwrap - local vec_meta, vunwrap = instance.Types.Vector, instance.Types.Vector.Unwrap + local ang_meta, awrap, aunwrap = instance.Types.Angle, instance.Types.Angle.Wrap, instance.Types.Angle.Unwrap + local vec_meta, vwrap, vunwrap = instance.Types.Vector, instance.Types.Vector.Wrap, instance.Types.Vector.Unwrap local col_meta, cwrap, cunwrap = instance.Types.Color, instance.Types.Color.Wrap, instance.Types.Color.Unwrap instance:AddHook( "initialize", function() @@ -386,6 +386,7 @@ return function( instance ) end --- Gets the number of prop2mesh controllers + -- @shared -- @return number count function ents_methods:p2mGetCount() CheckType( self, ents_metatable ) @@ -399,6 +400,7 @@ return function( instance ) end --- Gets the color of the controller + -- @shared -- @param number index -- @return Color the color function ents_methods:p2mGetColor( index ) @@ -414,7 +416,8 @@ return function( instance ) return cwrap( ent:GetControllerCol( index ) ) end - --- Sets the position of the controller + --- Sets the local position of the controller + -- @shared -- @param number index -- @param Vector position function ents_methods:p2mSetPos( index, pos ) @@ -429,7 +432,24 @@ return function( instance ) ent:SetControllerLinkPos( index, vunwrap( pos ) ) end - --- Sets the angle of the controller + --- Gets the local position of the controller + -- @shared + -- @param number index + -- @return Vector local position + function ents_methods:p2mGetPos( index ) + CheckType( self, ents_metatable ) + local ent = unwrap( self ) + + CheckLuaType( index, TYPE_NUMBER ) + if not checkValid( instance.player, ent, _POS, index, nil ) then + return + end + + return vwrap( ent:GetControllerLinkPos( index ) ) + end + + --- Sets the local angle of the controller + -- @shared -- @param number index -- @param Angle angle function ents_methods:p2mSetAng( index, ang ) @@ -444,7 +464,24 @@ return function( instance ) ent:SetControllerLinkAng( index, aunwrap( ang ) ) end + --- Gets the local angle of the controller + -- @shared + -- @param number index + -- @return Angle local angle + function ents_methods:p2mGetAng( index ) + CheckType( self, ents_metatable ) + local ent = unwrap( self ) + + CheckLuaType( index, TYPE_NUMBER ) + if not checkValid( instance.player, ent, _ANG, index, nil ) then + return + end + + return awrap( ent:GetControllerLinkAng( index ) ) + end + --- Sets the color of the controller + -- @shared -- @param number index -- @param Color color function ents_methods:p2mSetColor( index, color ) @@ -461,6 +498,7 @@ return function( instance ) end --- Sets the alpha of the controller + -- @shared -- @param number index -- @param number alpha function ents_methods:p2mSetAlpha( index, alpha ) @@ -479,6 +517,7 @@ return function( instance ) end --- Gets the material of the controller + -- @shared -- @param number index -- @return string material name function ents_methods:p2mGetMaterial( index ) @@ -495,6 +534,7 @@ return function( instance ) end --- Sets the material of the controller + -- @shared -- @param number index -- @param string mat material name function ents_methods:p2mSetMaterial( index, mat ) @@ -512,6 +552,7 @@ return function( instance ) end --- Sets the scale of the controller + -- @shared -- @param number index -- @param Vector scale function ents_methods:p2mSetScale( index, scale )