From 3bc788514cc6e82adb34495b6d19609d9c0c526e Mon Sep 17 00:00:00 2001 From: penolakushari <45951611+penolakushari@users.noreply.github.com> Date: Sun, 4 Feb 2024 00:39:28 +0300 Subject: [PATCH] Fixed text entry in the precise nonphysics bone manipulation being called twice, fixed prop ragdoll gizmo offsets being applied to nonphysical bones of the props, added angle offset for prop ragdoll tool --- lua/entities/rgm_axis/init.lua | 8 +- lua/weapons/gmod_tool/stools/ragdollmover.lua | 18 ++- .../gmod_tool/stools/ragmover_propragdoll.lua | 107 ++++++++++++++++-- 3 files changed, 118 insertions(+), 15 deletions(-) diff --git a/lua/entities/rgm_axis/init.lua b/lua/entities/rgm_axis/init.lua index 3007a56..353777a 100644 --- a/lua/entities/rgm_axis/init.lua +++ b/lua/entities/rgm_axis/init.lua @@ -337,7 +337,7 @@ function ENT:Think() if not pl.rgm.Moving or not rotate then local entoffset = VECTOR_ORIGIN - if ent.rgmPRoffset then + if not scale and ent.rgmPRoffset and pl.rgm.IsPhysBone then entoffset = ent.rgmPRoffset end @@ -378,7 +378,11 @@ function ENT:Think() if not pl.rgm.Moving then -- Prevent whole thing from rotating when we do localized rotation - needed for proper angle reading if localstate or scale or (not pl.rgm.IsPhysBone and rotate) then -- Non phys bones don't go well with world coordinates. - self:SetAngles(ang or angle_zero) + local moveang = ang + if not scale and ent.rgmPRaoffset and pl.rgm.IsPhysBone then + _, moveang = LocalToWorld(vector_origin, ent.rgmPRaoffset, vector_origin, ang or angle_zero) + end + self:SetAngles(moveang) if not pl.rgm.IsPhysBone then local manipang = ent:GetManipulateBoneAngles(bone) self.DiscP:SetLocalAngles(Angle(0, 90 + manipang.y, 0)) -- Pitch follows Yaw angles diff --git a/lua/weapons/gmod_tool/stools/ragdollmover.lua b/lua/weapons/gmod_tool/stools/ragdollmover.lua index 32421ef..69325dc 100644 --- a/lua/weapons/gmod_tool/stools/ragdollmover.lua +++ b/lua/weapons/gmod_tool/stools/ragdollmover.lua @@ -2344,8 +2344,8 @@ local function CManipSlider(cpanel, text, mode, axis, min, max, dec, textentry) end function slider:OnValueChanged(value) - if ManipSliderUpdating or self.busy then return end - self.busy = true + if ManipSliderUpdating then return end + ManipSliderUpdating = true net.Start("rgmAdjustBone") net.WriteInt(mode, 3) net.WriteInt(axis, 3) @@ -2353,7 +2353,7 @@ local function CManipSlider(cpanel, text, mode, axis, min, max, dec, textentry) net.SendToServer() textentry:SetValue(round(textentry.Sliders[1]:GetValue(), 2) .. " " .. round(textentry.Sliders[2]:GetValue(), 2) .. " " .. round(textentry.Sliders[3]:GetValue(), 2)) - self.busy = false + ManipSliderUpdating = false end cpanel:AddItem(slider) @@ -2365,16 +2365,22 @@ local function CManipEntry(cpanel, mode) entry:SetValue("0 0 0") entry:SetUpdateOnType(true) entry.OnValueChange = function(self, value) - if ManipSliderUpdating or self.busy then return end - self.busy = true + if ManipSliderUpdating then return end + ManipSliderUpdating = true local values = string.Explode(" ", value) for i = 1, 3 do if values[i] and tonumber(values[i]) and IsValid(entry.Sliders[i]) then entry.Sliders[i]:SetValue(tonumber(values[i])) + + net.Start("rgmAdjustBone") + net.WriteInt(mode, 3) + net.WriteInt(i, 3) + net.WriteFloat(tonumber(values[i])) + net.SendToServer() end end - self.busy = false + ManipSliderUpdating = false end local textfocusold = entry.OnGetFocus diff --git a/lua/weapons/gmod_tool/stools/ragmover_propragdoll.lua b/lua/weapons/gmod_tool/stools/ragmover_propragdoll.lua index 74f7154..ba02934 100644 --- a/lua/weapons/gmod_tool/stools/ragmover_propragdoll.lua +++ b/lua/weapons/gmod_tool/stools/ragmover_propragdoll.lua @@ -54,6 +54,7 @@ duplicator.RegisterEntityModifier("Ragdoll Mover Prop Ragdoll", function(pl, ent ent.rgmPRidtoent = table.Copy(data.idtoent) ent.rgmPRparent = data.parent ent.rgmPRoffset = data.offset + ent.rgmPRaoffset = data.aoffset -- a stands for angle ent.rgmOldPostEntityPaste = ent.PostEntityPaste @@ -82,6 +83,7 @@ duplicator.RegisterEntityModifier("Ragdoll Mover Prop Ragdoll", function(pl, ent newdata.idtoent = table.Copy(ent.rgmPRidtoent) newdata.parent = ent.rgmPRparent newdata.offset = ent.rgmPRoffset + newdata.aoffset = ent.rgmPRaoffset duplicator.ClearEntityModifier(ent, "Ragdoll Mover Prop Ragdoll") duplicator.StoreEntityModifier(ent, "Ragdoll Mover Prop Ragdoll", newdata) @@ -123,6 +125,7 @@ net.Receive("rgmprApplySkeleton", function(len, pl) fail = true end ents[i].offset = net.ReadVector() + ents[i].aoffset = net.ReadAngle() end if fail or count > CVMaxPRBones:GetInt() then @@ -147,6 +150,7 @@ net.Receive("rgmprApplySkeleton", function(len, pl) ent.rgmPRenttoid = {} ent.rgmPRparent = data.parent ent.rgmPRoffset = data.offset + ent.rgmPRaoffset = data.aoffset for id, moredata in pairs(ents) do ent.rgmPRidtoent[moredata.id] = moredata.ent ent.rgmPRenttoid[moredata.ent] = moredata.id @@ -160,6 +164,7 @@ net.Receive("rgmprApplySkeleton", function(len, pl) end data.parent = ent.rgmPRparent data.offset = ent.rgmPRoffset + data.aoffset = ent.rgmPRaoffset duplicator.StoreEntityModifier(ent, "Ragdoll Mover Prop Ragdoll", data) end @@ -257,6 +262,8 @@ local ENT_SELECTED = 0 local ENT_CLEARED = 1 local PROP_NOT_IN_SET = 6 +local IsEditingSliders = false + local RGM_NOTIFY = { [ENT_SELECTED] = false, [ENT_CLEARED] = false, @@ -282,6 +289,7 @@ local function RGMCallApplySkeleton() net.WriteUInt(node.id, 13) net.WriteUInt(node.parent or 4100, 13) net.WriteVector(node.offset) + net.WriteAngle(node.aoffset) end net.SendToServer() end @@ -508,16 +516,43 @@ local function CSlider(cpanel, axis, text) local mround = math.Round sliderman.OnValueChanged = function(self, val) - if self.busy then return end - self.busy = true + if IsEditingSliders then return end + IsEditingSliders = true local node = PRUI.PRTree:GetSelectedItem() if not IsValid(node) then - self.busy = false + IsEditingSliders = false return end node.offset[axis] = val PRUI.PRTree.OffsetEntry:SetValue(mround(node.offset[1], 1) .. " " .. mround(node.offset[2], 1) .. " " .. mround(node.offset[3], 1)) - self.busy = false + IsEditingSliders = false + end + + cpanel:AddItem(sliderman) + return sliderman +end +local function CASlider(cpanel, axis, text) + local sliderman = vgui.Create("DNumSlider", cpanel) + sliderman:SetDark(true) + sliderman:SetText(text) + sliderman:SetDecimals(1) + sliderman:SetDefaultValue(0) + sliderman:SetMinMax(-360, 360) + sliderman:SetValue(0) + + local mround = math.Round + + sliderman.OnValueChanged = function(self, val) + if IsEditingSliders then return end + IsEditingSliders = true + local node = PRUI.PRTree:GetSelectedItem() + if not IsValid(node) then + IsEditingSliders = false + return + end + node.aoffset[axis] = val + PRUI.PRTree.AOffsetEntry:SetValue(mround(node.aoffset[1], 1) .. " " .. mround(node.aoffset[2], 1) .. " " .. mround(node.aoffset[3], 1)) + IsEditingSliders = false end cpanel:AddItem(sliderman) @@ -546,6 +581,7 @@ local function AddPRNode(parent, node) PRUI.PRTree.Nodes[id].ent = node.ent PRUI.PRTree.Nodes[id].id = id PRUI.PRTree.Nodes[id].offset = Vector(0, 0, 0) + PRUI.PRTree.Nodes[id].aoffset = Angle(0, 0, 0) PRUI.PRTree.Nodes[id].parent = parent.id or nil PRUI.PRTree.Nodes[id].depth = parent.depth and parent.depth + 1 or 1 PRUI.PRTree.Nodes[id]:Droppable("rgmPRMove") @@ -689,6 +725,10 @@ local function PropRagdollCreator(cpanel) PropRagdollUI.PRTree.Offsets[1]:SetValue(node.offset[1]) PropRagdollUI.PRTree.Offsets[2]:SetValue(node.offset[2]) PropRagdollUI.PRTree.Offsets[3]:SetValue(node.offset[3]) + + PropRagdollUI.PRTree.AOffsets[1]:SetValue(node.aoffset[1]) + PropRagdollUI.PRTree.AOffsets[2]:SetValue(node.aoffset[2]) + PropRagdollUI.PRTree.AOffsets[3]:SetValue(node.aoffset[3]) end AddHBar(PropRagdollUI.PRTree) @@ -699,16 +739,23 @@ local function PropRagdollCreator(cpanel) PropRagdollUI.PRTree.OffsetEntry:SetValue("0 0 0") PropRagdollUI.PRTree.OffsetEntry:SetUpdateOnType(true) PropRagdollUI.PRTree.OffsetEntry.OnValueChange = function(self, value) - if self.busy then return end - self.busy = true + if IsEditingSliders then return end + IsEditingSliders = true + local node = PropRagdollUI.PRTree:GetSelectedItem() + if not IsValid(node) then + IsEditingSliders = false + return + end + local values = string.Explode(" ", value) for i = 1, 3 do if values[i] and tonumber(values[i]) then PropRagdollUI.PRTree.Offsets[i]:SetValue(tonumber(values[i])) + node.offset[i] = tonumber(values[i]) end end - self.busy = false + IsEditingSliders = false end creatorpanel:AddItem(PropRagdollUI.PRTree.OffsetEntry) @@ -718,6 +765,36 @@ local function PropRagdollCreator(cpanel) PropRagdollUI.PRTree.Offsets[2] = CSlider(creatorpanel, 2, "Y") PropRagdollUI.PRTree.Offsets[3] = CSlider(creatorpanel, 3, "Z") + PropRagdollUI.PRTree.AOffsetEntry = vgui.Create("DTextEntry", creatorpanel) + PropRagdollUI.PRTree.AOffsetEntry:SetValue("0 0 0") + PropRagdollUI.PRTree.AOffsetEntry:SetUpdateOnType(true) + PropRagdollUI.PRTree.AOffsetEntry.OnValueChange = function(self, value) + if IsEditingSliders then return end + IsEditingSliders = true + local node = PropRagdollUI.PRTree:GetSelectedItem() + if not IsValid(node) then + IsEditingSliders = false + return + end + + local values = string.Explode(" ", value) + + for i = 1, 3 do + if values[i] and tonumber(values[i]) then + PropRagdollUI.PRTree.AOffsets[i]:SetValue(tonumber(values[i])) + node.aoffset[i] = tonumber(values[i]) + end + end + IsEditingSliders = false + end + creatorpanel:AddItem(PropRagdollUI.PRTree.AOffsetEntry) + + PropRagdollUI.PRTree.AOffsets = {} + + PropRagdollUI.PRTree.AOffsets[1] = CASlider(creatorpanel, 1, "#tool.ragdollmover.rot1") + PropRagdollUI.PRTree.AOffsets[2] = CASlider(creatorpanel, 2, "#tool.ragdollmover.rot2") + PropRagdollUI.PRTree.AOffsets[3] = CASlider(creatorpanel, 3, "#tool.ragdollmover.rot3") + local applybutt = vgui.Create("DButton", creatorpanel) applybutt:SetText("#tool.ragmover_propragdoll.apply") @@ -854,6 +931,7 @@ function TOOL:DrawHUD() if not IsValid(ent) then break end local pos = ent:GetPos() pos = LocalToWorld(node.offset, angle_zero, pos, ent:GetAngles()) + pos = pos:ToScreen() local textpos = { x = pos.x + 5, y = pos.y - 5 } @@ -883,7 +961,22 @@ function TOOL:DrawHUD() local ypos = LocalToWorld(VECTOR_LEFT * 50, angle_zero, pos, ang) local zpos = LocalToWorld(vector_up * 50, angle_zero, pos, ang) + _, ang = LocalToWorld(vector_origin, selnode.aoffset, vector_origin, ang) + local rxpos = LocalToWorld(VECTOR_FORWARD * 25, angle_zero, pos, ang) + local rypos = LocalToWorld(VECTOR_LEFT * 25, angle_zero, pos, ang) + local rzpos = LocalToWorld(vector_up * 25, angle_zero, pos, ang) + pos, xpos, ypos, zpos = pos:ToScreen(), xpos:ToScreen(), ypos:ToScreen(), zpos:ToScreen() + rxpos, rypos, rzpos = rxpos:ToScreen(), rypos:ToScreen(), rzpos:ToScreen() + + surface.SetDrawColor(175, 0, 0) + surface.DrawLine(pos.x, pos.y, rxpos.x, rxpos.y) + + surface.SetDrawColor(0, 175, 0) + surface.DrawLine(pos.x, pos.y, rypos.x, rypos.y) + + surface.SetDrawColor(0, 0, 175) + surface.DrawLine(pos.x, pos.y, rzpos.x, rzpos.y) surface.SetDrawColor(255, 0, 0) surface.DrawLine(pos.x, pos.y, xpos.x, xpos.y)