Merge branch 'master' into angle-snapping-fix

This commit is contained in:
vlazed 2024-08-20 16:38:50 -04:00 committed by GitHub
commit 3de388ee6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 347 additions and 101 deletions

View File

@ -1,3 +1,7 @@
-- load dconstants
include("ragdollmover/constants.lua")
AddCSLuaFile("ragdollmover/constants.lua")
-- load gizmos library
include("ragdollmover/rgm_gizmos.lua")
AddCSLuaFile("ragdollmover/rgm_gizmos.lua")
@ -9,6 +13,7 @@ AddCSLuaFile("ragdollmover/rgm_gizmos.lua")
module("rgm", package.seeall)
--[[ Line-Plane intersection, and return the result vector
I honestly cannot explain this at all. I just followed this tutorial:
http://www.wiremod.com/forum/expression-2-discussion-help/19008-line-plane-intersection-tutorial.html
@ -21,7 +26,7 @@ function IntersectRayWithPlane(planepoint, norm, line, linenormal)
return vec
end
local VECTOR_ONE = Vector(1, 1, 1)
local VECTOR_ONE = RGM_Constants.VECTOR_ONE
--Receives player eye position and eye angles.
--If cursor is visible, eye angles are based on cursor position.
@ -944,7 +949,9 @@ end
if CLIENT then
local COLOR_RGMGREEN = Color(0, 200, 0, 255)
local COLOR_RGMGREEN = RGM_Constants.COLOR_GREEN
local COLOR_RGMBLACK = RGM_Constants.COLOR_BLACK
local OUTLINE_WIDTH = RGM_Constants.OUTLINE_WIDTH
function DrawBoneName(ent, bone, name)
if not name then
@ -958,7 +965,7 @@ function DrawBoneName(ent, bone, name)
_pos = _pos:ToScreen()
local textpos = {x = _pos.x + 5, y = _pos.y - 5}
surface.DrawCircle(_pos.x, _pos.y, 3.5, COLOR_RGMGREEN)
draw.SimpleText(name, "Default", textpos.x, textpos.y, COLOR_RGMGREEN, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM)
draw.SimpleTextOutlined(name, "Default", textpos.x, textpos.y, COLOR_RGMGREEN, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM, OUTLINE_WIDTH, COLOR_RGMBLACK)
end
function DrawEntName(ent)
@ -978,7 +985,128 @@ function DrawEntName(ent)
pos = pos:ToScreen()
local textpos = {x = pos.x + 5, y = pos.y - 5}
surface.DrawCircle(pos.x, pos.y, 3.5, COLOR_RGMGREEN)
draw.SimpleText(name, "Default", textpos.x, textpos.y, COLOR_RGMGREEN, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM)
draw.SimpleTextOutlined(name, "Default", textpos.x, textpos.y, COLOR_RGMGREEN, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM, OUTLINE_WIDTH, COLOR_RGMBLACK)
end
local RGM_CIRCLE = {
{ x = -3, y = -3 },
{ x = 0, y = -4 },
{ x = 3, y = -3 },
{ x = 4, y = 0 },
{ x = 3, y = 3 },
{ x = 0, y = 4 },
{ x = -3, y = 3 },
{ x = -4, y = 0 }
}
function AdvBoneSelectRender(ent)
local mx, my = input.GetCursorPos() -- possible bug on mac https://wiki.facepunch.com/gmod/input.GetCursorPos
local selectedBones = {}
for i = 0, ent:GetBoneCount() do
local selected = false
local name = ent:GetBoneName(i)
if name == "__INVALIDBONE__" then continue end
local pos = ent:GetBonePosition(i)
pos = pos:ToScreen()
local dist = math.abs((mx - pos.x)^2 + (my - pos.y)^2)
local circ = table.Copy(RGM_CIRCLE)
for k, v in ipairs(circ) do
v.x = v.x + pos.x
v.y = v.y + pos.y
end
if dist < 576 then -- 24 pixels
surface.SetDrawColor(255, 255, 0, 255)
table.insert(selectedBones, name)
else
surface.SetDrawColor(0, 200, 0, 255)
end
draw.NoTexture()
surface.DrawPoly(circ)
end
for i = 1, #selectedBones do
local listItemPos = {x = mx + 5, y = my + i * 15}
draw.SimpleTextOutlined(selectedBones[i], "Default", listItemPos.x, listItemPos.y, COLOR_RGMGREEN, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM, OUTLINE_WIDTH, COLOR_RGMBLACK)
end
end
function AdvBoneSelectPick(ent)
local selected = {}
local mx, my = input.GetCursorPos()
cam.Start3D()
for i = 0, ent:GetBoneCount() do
if ent:GetBoneName(i) == "__INVALIDBONE__" then continue end
local pos = ent:GetBonePosition(i)
pos = pos:ToScreen()
local dist = math.abs((mx - pos.x)^2 + (my - pos.y)^2)
if dist < 576 then
table.insert(selected, i)
end
end
cam.End3D()
return selected
end
local COLOR_WHITE = Color(255, 255, 255, 255)
local COLOR_YELLOW = Color(255, 255, 0, 255)
local SelectedBone = nil
function AdvBoneSelectRadialRender(ent, bones)
local mx, my = input.GetCursorPos()
local midw, midh = ScrW()/2, ScrH()/2
local count = #bones
local angborder = (360 / count) / 2
for k, bone in ipairs(bones) do
local name = ent:GetBoneName(bone)
local thisang = (360 / count * (k - 1))
local thisrad = thisang / 180 * math.pi
local uix, uiy = (math.sin(thisrad) * 250), (math.cos(thisrad) * -250)
local color = COLOR_WHITE
uix, uiy = uix + midw, uiy + midh
local selangle = 360 - (math.deg(math.atan2(mx - midw, my - midh)) + 180) -- took this one from overhauled radial menu, which took some of the inspiration from wiremod
local diff = math.abs((thisang - selangle + 180) % 360 - 180)
local isselected = diff < angborder and true or false
local pos = ent:GetBonePosition(bone)
pos = pos:ToScreen()
local circ = table.Copy(RGM_CIRCLE)
for k, v in ipairs(circ) do
v.x = v.x + pos.x
v.y = v.y + pos.y
end
if isselected then
surface.SetDrawColor(255, 255, 0, 255)
color = COLOR_YELLOW
SelectedBone = bone
else
surface.SetDrawColor(0, 200, 0, 255)
end
draw.NoTexture()
surface.DrawPoly(circ)
surface.DrawCircle(uix, uiy, 3.5, color)
draw.SimpleTextOutlined(name, "Default", uix, uiy - 14, color, TEXT_ALIGN_CENTER, TEXT_ALIGN_BOTTOM, OUTLINE_WIDTH, COLOR_RGMBLACK)
end
end
function AdvBoneSelectRadialPick()
if not SelectedBone then return 0 end
return SelectedBone
end
function DrawBoneConnections(ent, bone)

View File

@ -1,8 +1,10 @@
include("shared.lua")
local VECTOR_FRONT = Vector(1, 0, 0)
local COLOR_RGMGREEN = Color(0, 200, 0, 255)
local VECTOR_FRONT = RGM_Constants.VECTOR_FRONT
local COLOR_RGMGREEN = RGM_Constants.COLOR_GREEN
local COLOR_RGMBLACK = RGM_Constants.COLOR_BLACK
local OUTLINE_WIDTH = RGM_Constants.OUTLINE_WIDTH
local ANGLE_ARROW_OFFSET = Angle(0, 90, 90)
local ANGLE_DISC = Angle(0, 90, 0)
@ -60,7 +62,7 @@ function ENT:DrawAngleText(axis, hitpos, startAngle)
local textAngle = mabs(mround((overnine - localized.y) * 100) / 100)
local textpos = hitpos:ToScreen()
draw.SimpleText(textAngle, "HudHintTextLarge", textpos.x + 5, textpos.y, COLOR_RGMGREEN, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM)
draw.SimpleTextOutlined(textAngle, "HudDefault", textpos.x + 5, textpos.y, COLOR_RGMGREEN, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM, OUTLINE_WIDTH, COLOR_RGMBLACK)
end
function ENT:Draw()

View File

@ -6,8 +6,8 @@ AddCSLuaFile("shared.lua")
ENT.DisableDuplicator = true
ENT.DoNotDuplicate = true
local VECTOR_ORIGIN = Vector(0, 0, 0)
local VECTOR_FRONT = Vector(1, 0, 0)
local VECTOR_ORIGIN = vector_origin
local VECTOR_FRONT = RGM_Constants.VECTOR_FRONT
local ANGLE_DISC = Angle(0, 90, 0)
local ANGLE_ARROW_OFFSET = Angle(0, 90, 90)

View File

@ -0,0 +1,10 @@
RGM_Constants = {
COLOR_GREEN = Color(0, 200, 0, 255),
COLOR_YELLOW = Color(255, 255, 0, 255),
COLOR_BLACK = Color(0, 0, 0, 255),
OUTLINE_WIDTH = 1,
VECTOR_ONE = Vector(1, 1, 1),
VECTOR_FRONT = Vector(1, 0, 0),
VECTOR_LEFT = Vector(0, 1, 0),
VECTOR_NEARZERO = Vector(0.01, 0.01, 0.01),
}

View File

@ -1,8 +1,8 @@
RGMGIZMOS = {}
local VECTOR_FRONT = Vector(1, 0, 0)
local VECTOR_SIDE = Vector(0, 1, 0)
local COLOR_YELLOW = Color(255, 255, 0, 255)
local VECTOR_FRONT = RGM_Constants.VECTOR_FRONT
local VECTOR_SIDE = RGM_Constants.VECTOR_LEFT
local COLOR_YELLOW = RGM_Constants.COLOR_YELLOW
----------------
-- BASE GIZMO --

View File

@ -53,9 +53,9 @@ local ENTSELECT_LOCKRESPONSE = 20
local BONE_FROZEN = 7
local BONE_UNFROZEN = 8
local VECTOR_FRONT = Vector(1, 0, 0)
local VECTOR_LEFT = Vector(0, 1, 0)
local VECTOR_SCALEDEF = Vector(1, 1, 1)
local VECTOR_FRONT = RGM_Constants.VECTOR_FRONT
local VECTOR_LEFT = RGM_Constants.VECTOR_LEFT
local VECTOR_SCALEDEF = RGM_Constants.VECTOR_ONE
local function rgmGetBone(pl, ent, bone)
--------------------------------------------------------- yeah this part is from locrotscale
@ -244,8 +244,8 @@ util.AddNetworkString("RAGDOLLMOVER")
ConstrainedAllowed = CreateConVar("sv_ragdollmover_allow_constrained_locking", 1, FCVAR_ARCHIVE + FCVAR_NOTIFY, "Allow usage of locking constrained entities to Ragdoll Mover's selected entity (Can be abused by attempting to move a lot of entities)", 0, 1)
local VECTOR_NEARZERO = Vector(0.01, 0.01, 0.01)
local VECTOR_ONE = Vector(1, 1, 1)
local VECTOR_NEARZERO = RGM_Constants.VECTOR_NEARZERO
local VECTOR_ONE = RGM_Constants.VECTOR_ONE
local function RecursiveFindIfParent(ent, lockbone, locktobone)
local parent = ent:GetBoneParent(locktobone)
@ -306,7 +306,7 @@ local NETFUNC = {
end
net.Start("RAGDOLLMOVER")
net.WriteUInt(6, 4)
net.WriteUInt(5, 4)
net.WriteUInt(#sendents, 13)
for _, ent in ipairs(sendents) do
net.WriteEntity(ent)
@ -352,7 +352,7 @@ local NETFUNC = {
if not next(ents) then return end
net.Start("RAGDOLLMOVER")
net.WriteUInt(13, 4)
net.WriteUInt(12, 4)
net.WriteBool(isphys)
net.WriteUInt(validcount, 13)
for i, ent in ipairs(ents) do
@ -414,7 +414,7 @@ local NETFUNC = {
if next(parented) then
net.Start("RAGDOLLMOVER")
net.WriteUInt(7, 4)
net.WriteUInt(6, 4)
net.WriteUInt(pcount, 13)
for ent, bones in pairs(parented) do
net.WriteEntity(ent)
@ -440,7 +440,7 @@ local NETFUNC = {
RAGDOLLMOVER.Sync(pl, "Entity", "Bone", "IsPhysBone")
net.Start("RAGDOLLMOVER")
net.WriteUInt(12, 4)
net.WriteUInt(11, 4)
net.WriteBool(RAGDOLLMOVER[pl].IsPhysBone)
net.WriteEntity(ent)
net.WriteUInt(RAGDOLLMOVER[pl].Bone, 10)
@ -488,7 +488,7 @@ local NETFUNC = {
local poslock, anglock, scllock = IsValid(RAGDOLLMOVER[pl].rgmPosLocks[ent][boneid]), IsValid(RAGDOLLMOVER[pl].rgmAngLocks[ent][boneid]), RAGDOLLMOVER[pl].rgmScaleLocks[ent][bone]
net.Start("RAGDOLLMOVER")
net.WriteUInt(8, 4)
net.WriteUInt(7, 4)
net.WriteEntity(ent)
net.WriteUInt(bone, 10)
net.WriteBool(poslock)
@ -516,14 +516,14 @@ local NETFUNC = {
physbone:EnableMotion(false)
physbone:Wake()
net.Start("RAGDOLLMOVER")
net.WriteUInt(15, 4)
net.WriteUInt(14, 4)
net.WriteUInt(BONE_FROZEN, 5)
net.Send(pl)
else
physbone:EnableMotion(true)
physbone:Wake()
net.Start("RAGDOLLMOVER")
net.WriteUInt(15, 4)
net.WriteUInt(14, 4)
net.WriteUInt(BONE_UNFROZEN, 5)
net.Send(pl)
end
@ -552,7 +552,7 @@ local NETFUNC = {
local err = samecheck and BONELOCK_FAILED_SAME or BONELOCK_FAILED_NOTPHYS
net.Start("RAGDOLLMOVER")
net.WriteUInt(15, 4)
net.WriteUInt(14, 4)
net.WriteUInt(err, 5)
net.Send(pl)
return
@ -568,13 +568,13 @@ local NETFUNC = {
RAGDOLLMOVER[pl].rgmAngLocks[lockent][bone] = nil
net.Start("RAGDOLLMOVER")
net.WriteUInt(9, 4)
net.WriteUInt(8, 4)
net.WriteEntity(lockent)
net.WriteUInt(lockedbone, 10)
net.Send(pl)
else
net.Start("RAGDOLLMOVER")
net.WriteUInt(15, 4)
net.WriteUInt(14, 4)
net.WriteUInt(BONELOCK_FAILED, 5)
net.Send(pl)
end
@ -585,13 +585,13 @@ local NETFUNC = {
RAGDOLLMOVER[pl].rgmAngLocks[lockent][lockedbone] = nil
net.Start("RAGDOLLMOVER")
net.WriteUInt(9, 4)
net.WriteUInt(8, 4)
net.WriteEntity(lockent)
net.WriteUInt(0, 10)
net.Send(pl)
else
net.Start("RAGDOLLMOVER")
net.WriteUInt(15, 4)
net.WriteUInt(14, 4)
net.WriteUInt(BONELOCK_FAILED, 5)
net.Send(pl)
end
@ -612,7 +612,7 @@ local NETFUNC = {
RAGDOLLMOVER[pl].rgmBoneLocks[ent][bone] = nil
net.Start("RAGDOLLMOVER")
net.WriteUInt(10, 4)
net.WriteUInt(9, 4)
net.WriteEntity(ent)
net.WriteUInt(unlockbone, 10)
net.Send(pl)
@ -628,7 +628,7 @@ local NETFUNC = {
local convar = ConstrainedAllowed:GetBool()
if not convar then
net.Start("RAGDOLLMOVER")
net.WriteUInt(15, 4)
net.WriteUInt(14, 4)
net.WriteUInt(ENTLOCK_FAILED_NOTALLOWED, 5)
net.Send(pl)
return
@ -642,7 +642,7 @@ local NETFUNC = {
if not ent.rgmPRenttoid then
if not rgm.BoneToPhysBone(ent, boneid) then
net.Start("RAGDOLLMOVER")
net.WriteUInt(15, 4)
net.WriteUInt(14, 4)
net.WriteUInt(ENTLOCK_FAILED_NONPHYS, 5)
net.Send(pl)
return
@ -657,7 +657,7 @@ local NETFUNC = {
RAGDOLLMOVER[pl].rgmEntLocks[lockent] = {id = physbone, ent = ent}
net.Start("RAGDOLLMOVER")
net.WriteUInt(11, 4)
net.WriteUInt(10, 4)
net.WriteBool(true)
net.WriteEntity(lockent)
net.Send(pl)
@ -672,7 +672,7 @@ local NETFUNC = {
RAGDOLLMOVER[pl].rgmEntLocks[lockent] = nil
net.Start("RAGDOLLMOVER")
net.WriteUInt(11, 4)
net.WriteUInt(10, 4)
net.WriteBool(false)
net.WriteEntity(lockent)
net.Send(pl)
@ -688,7 +688,7 @@ local NETFUNC = {
if tool:GetClientNumber("lockselected") ~= 0 then
net.Start("RAGDOLLMOVER")
net.WriteUInt(15, 4)
net.WriteUInt(14, 4)
net.WriteUInt(ENTSELECT_LOCKRESPONSE, 5)
net.Send(pl)
return
@ -734,7 +734,7 @@ local NETFUNC = {
if not resetlists then
net.Start("RAGDOLLMOVER")
net.WriteUInt(5, 4)
net.WriteUInt(4, 4)
net.WriteEntity(ent)
net.WriteUInt(#physchildren, 13)
@ -747,7 +747,7 @@ local NETFUNC = {
RAGDOLLMOVER[pl].PropRagdoll = ent.rgmPRidtoent and true or false
net.Start("RAGDOLLMOVER")
net.WriteUInt(3, 4)
net.WriteUInt(2, 4)
net.WriteBool(RAGDOLLMOVER[pl].PropRagdoll)
if RAGDOLLMOVER[pl].PropRagdoll then
local rgment = RAGDOLLMOVER[pl].Entity
@ -902,16 +902,22 @@ local NETFUNC = {
RAGDOLLMOVER[pl].GizmoOffset:Set(vector_origin)
net.Start("RAGDOLLMOVER")
net.WriteUInt(4, 4)
net.WriteUInt(3, 4)
net.WriteVector(RAGDOLLMOVER[pl].GizmoOffset)
net.Send(pl)
end,
function(len, pl) -- 14 - rgmOperationSwitch
local op = net.ReadUInt(2)
local tool = pl:GetTool("ragdollmover")
if not tool then return end
tool:SetOperation(1)
if op ~= 3 then
tool:SetOperation(op)
tool:SetStage(0)
else
tool:SetStage(1)
end
end,
function(len, pl) -- 15 - rgmSetGizmoToBone
@ -938,7 +944,7 @@ local NETFUNC = {
RAGDOLLMOVER[pl].GizmoOffset = vector
net.Start("RAGDOLLMOVER")
net.WriteUInt(4, 4)
net.WriteUInt(3, 4)
net.WriteVector(RAGDOLLMOVER[pl].GizmoOffset)
net.Send(pl)
end,
@ -960,12 +966,12 @@ local NETFUNC = {
end
net.Start("RAGDOLLMOVER")
net.WriteUInt(2, 4)
net.WriteUInt(1, 4)
net.Send(pl)
timer.Simple(0.1, function() -- ask client to get new bone position info in case if the parent bone was moved. put into timer as it takes a bit of time for position to update on client?
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 4)
net.WriteUInt(13, 4)
net.Send(pl)
end)
end,
@ -1001,12 +1007,12 @@ local NETFUNC = {
end
net.Start("RAGDOLLMOVER")
net.WriteUInt(2, 4)
net.WriteUInt(1, 4)
net.Send(pl)
timer.Simple(0.1, function() -- ask client to get new bone position info in case if the parent bone was moved. put into timer as it takes a bit of time for position to update on client?
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 4)
net.WriteUInt(13, 4)
net.Send(pl)
end)
end,
@ -1034,12 +1040,12 @@ local NETFUNC = {
end
net.Start("RAGDOLLMOVER")
net.WriteUInt(2, 4)
net.WriteUInt(1, 4)
net.Send(pl)
timer.Simple(0.1, function()
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 4)
net.WriteUInt(13, 4)
net.Send(pl)
end)
end,
@ -1066,12 +1072,12 @@ local NETFUNC = {
end
net.Start("RAGDOLLMOVER")
net.WriteUInt(2, 4)
net.WriteUInt(1, 4)
net.Send(pl)
timer.Simple(0.1, function()
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 4)
net.WriteUInt(13, 4)
net.Send(pl)
end)
end,
@ -1098,12 +1104,12 @@ local NETFUNC = {
end
net.Start("RAGDOLLMOVER")
net.WriteUInt(2, 4)
net.WriteUInt(1, 4)
net.Send(pl)
timer.Simple(0.1, function()
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 4)
net.WriteUInt(13, 4)
net.Send(pl)
end)
end,
@ -1130,12 +1136,12 @@ local NETFUNC = {
end
net.Start("RAGDOLLMOVER")
net.WriteUInt(2, 4)
net.WriteUInt(1, 4)
net.Send(pl)
timer.Simple(0.1, function()
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 4)
net.WriteUInt(13, 4)
net.Send(pl)
end)
end,
@ -1215,7 +1221,7 @@ local NETFUNC = {
end
net.Start("RAGDOLLMOVER")
net.WriteUInt(4, 4)
net.WriteUInt(3, 4)
net.WriteVector(RAGDOLLMOVER[pl].GizmoOffset)
net.Send(pl)
@ -1712,7 +1718,7 @@ hook.Add("EntityRemoved", "RGMDeselectEntity", function(ent)
RAGDOLLMOVER[pl].Entity = nil
RAGDOLLMOVER[pl].Axis.EntAdvMerged = false
net.Start("RAGDOLLMOVER")
net.WriteUInt(1, 4)
net.WriteUInt(0, 4)
net.Send(pl)
end
end
@ -1730,7 +1736,7 @@ concommand.Add("ragdollmover_resetroot", function(pl)
RAGDOLLMOVER.Sync(pl, "Bone", "IsPhysBone")
net.Start("RAGDOLLMOVER")
net.WriteUInt(12, 4)
net.WriteUInt(11, 4)
net.WriteBool(RAGDOLLMOVER[pl].IsPhysBone)
net.WriteEntity(RAGDOLLMOVER[pl].Entity)
net.WriteUInt(RAGDOLLMOVER[pl].Bone, 10)
@ -1773,13 +1779,14 @@ end
function TOOL:LeftClick()
local pl = self:GetOwner()
local eyepos, eyeang = rgm.EyePosAng(pl)
local op = self:GetOperation()
local tr = util.TraceLine({
start = eyepos,
endpos = eyepos + pl:GetAimVector() * 16384,
filter = { pl, pl:GetViewEntity() }
})
if self:GetOperation() == 1 then
if op == 1 then
if SERVER then
local axis, ent = RAGDOLLMOVER[pl].Axis, RAGDOLLMOVER[pl].Entity
@ -1802,7 +1809,7 @@ function TOOL:LeftClick()
elseif ent:GetClass() == "prop_ragdoll" then
ent = ent:GetPhysicsObjectNum(RAGDOLLMOVER[pl].PhysBone)
ogpos, ogang = ent:GetPos(), ent:GetAngles()
elseif ent:GetClass() == "prop_physics" then
elseif ent:GetPhysicsObjectCount() == 1 then
ent = ent:GetPhysicsObjectNum(0)
ogpos, ogang = ent:GetPos(), ent:GetAngles()
end
@ -1816,7 +1823,7 @@ function TOOL:LeftClick()
RAGDOLLMOVER[pl].GizmoOffset = offset
net.Start("RAGDOLLMOVER")
net.WriteUInt(4, 4)
net.WriteUInt(3, 4)
net.WriteVector(RAGDOLLMOVER[pl].GizmoOffset)
net.Send(pl)
end
@ -1829,6 +1836,7 @@ function TOOL:LeftClick()
if CLIENT then return false end
if RAGDOLLMOVER[pl].Moving then return false end
if op ~= 0 then return false end
local axis = RAGDOLLMOVER[pl].Axis
if not IsValid(axis) then
@ -1936,7 +1944,7 @@ function TOOL:LeftClick()
if entity ~= RAGDOLLMOVER[pl].Entity and self:GetClientNumber("lockselected") ~= 0 then
net.Start("RAGDOLLMOVER")
net.WriteUInt(15, 4)
net.WriteUInt(14, 4)
net.WriteUInt(ENTSELECT_LOCKRESPONSE, 5)
net.Send(pl)
return false
@ -1962,7 +1970,7 @@ function TOOL:LeftClick()
RAGDOLLMOVER[pl].PropRagdoll = entity.rgmPRidtoent and true or false
net.Start("RAGDOLLMOVER")
net.WriteUInt(3, 4)
net.WriteUInt(2, 4)
net.WriteBool(RAGDOLLMOVER[pl].PropRagdoll)
if RAGDOLLMOVER[pl].PropRagdoll then
local rgment = RAGDOLLMOVER[pl].Entity
@ -2031,7 +2039,7 @@ function TOOL:LeftClick()
RAGDOLLMOVER.Sync(pl, "Entity", "Bone", "IsPhysBone")
net.Start("RAGDOLLMOVER")
net.WriteUInt(12, 4)
net.WriteUInt(11, 4)
net.WriteBool(RAGDOLLMOVER[pl].IsPhysBone)
net.WriteEntity(RAGDOLLMOVER[pl].Entity)
net.WriteUInt(RAGDOLLMOVER[pl].Bone, 10)
@ -2044,15 +2052,16 @@ end
function TOOL:RightClick()
local pl = self:GetOwner()
local eyepos, eyeang = rgm.EyePosAng(pl)
local tr = util.TraceLine({
start = eyepos,
endpos = eyepos + pl:GetAimVector() * 16384,
filter = { pl, pl:GetViewEntity() }
})
if self:GetOperation() == 1 then
if SERVER then
local tr = util.TraceLine({
start = eyepos,
endpos = eyepos + pl:GetAimVector() * 16384,
filter = { pl, pl:GetViewEntity() }
})
local axis = RAGDOLLMOVER[pl].Axis
local ent, rgment = tr.Entity, RAGDOLLMOVER[pl].Entity
local offset
@ -2083,7 +2092,7 @@ function TOOL:RightClick()
elseif rgment:GetClass() == "prop_ragdoll" then
rgment = rgment:GetPhysicsObjectNum(RAGDOLLMOVER[pl].PhysBone)
ogpos, ogang = rgment:GetPos(), rgment:GetAngles()
elseif rgment:GetClass() == "prop_physics" then
elseif rgment:GetPhysicsObjectCount() == 1 then
rgment = rgment:GetPhysicsObjectNum(0)
ogpos, ogang = rgment:GetPos(), rgment:GetAngles()
end
@ -2097,7 +2106,7 @@ function TOOL:RightClick()
RAGDOLLMOVER[pl].GizmoOffset = offset
net.Start("RAGDOLLMOVER")
net.WriteUInt(4, 4)
net.WriteUInt(3, 4)
net.WriteVector(RAGDOLLMOVER[pl].GizmoOffset)
net.Send(pl)
end
@ -2121,9 +2130,6 @@ function TOOL:Reload()
return false
end
do
local pl
function TOOL:Think()
@ -2175,10 +2181,10 @@ if SERVER then
RAGDOLLMOVER[pl].Moving = false
RAGDOLLMOVER.Sync(pl, "Moving")
net.Start("RAGDOLLMOVER")
net.WriteUInt(2, 4)
net.WriteUInt(1, 4)
net.Send(pl)
net.Start("RAGDOLLMOVER")
net.WriteUInt(4, 4)
net.WriteUInt(3, 4)
net.WriteVector(RAGDOLLMOVER[pl].GizmoOffset)
net.Send(pl)
return
@ -2686,16 +2692,18 @@ end
end
end
if CLIENT then
TOOL.Information = {
{ name = "left_advselect", op = 2 },
{ name = "info_advselect", op = 2 },
{ name = "left_gizmomode", op = 1 },
{ name = "right_gizmomode", op = 1 },
{ name = "reload_gizmomode", op = 1 },
{ name = "left_default", op = 0 },
{ name = "info_default", op = 0 },
{ name = "info_defadvselect", op = 0 },
{ name = "reload_default", op = 0 },
}
@ -2719,6 +2727,25 @@ hook.Add("InitPostEntity", "rgmSetPlayer", function()
pl = LocalPlayer()
end)
hook.Add("KeyPress", "rgmSwitchSelectionMode", function(pl, key)
local tool = pl:GetTool()
if RAGDOLLMOVER[pl] and pl:GetActiveWeapon():GetClass() == "gmod_tool" and tool and tool.Mode == "ragdollmover" then
local op = tool:GetOperation()
local opset = 0
if key == IN_WALK then
if op ~= 2 and IsValid(RAGDOLLMOVER[pl].Entity) then opset = 2 end
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 5)
net.WriteUInt(opset, 2)
net.SendToServer()
if tool:GetStage() == 1 then gui.EnableScreenClicker(false) end
end
end
end)
cvars.AddChangeCallback("ragdollmover_localpos", function()
net.Start("RAGDOLLMOVER")
net.WriteUInt(26, 5)
@ -3297,6 +3324,7 @@ local function RGMGizmoMode()
if not RAGDOLLMOVER[pl] then return end
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 5)
net.WriteUInt(1, 2)
net.SendToServer()
end
@ -3525,7 +3553,7 @@ local function SetBoneNodes(bonepanel, sortedbones)
for k, v in ipairs(entdata) do
local text1 = ent:GetBoneName(v.id)
if nodes[ent].parent then
if nodes[ent].parent and not v.parent then
nodes[ent][v.id] = nodes[nodes[ent].parent][0]:AddNode(text1)
elseif v.parent then
nodes[ent][v.id] = nodes[ent][v.parent]:AddNode(text1)
@ -4355,7 +4383,7 @@ local function UpdateManipulationSliders(boneid, ent)
end
local NETFUNC = {
function(len) -- 1 - rgmDeselectEntity
function(len) -- 0 - rgmDeselectEntity
if IsValid(BonePanel) then BonePanel:Clear() end
if IsValid(EntPanel) then EntPanel:Clear() end
if IsValid(ConEntPanel) then ConEntPanel:Clear() end
@ -4368,11 +4396,11 @@ local NETFUNC = {
ScaleLocks = {}
end,
function(len) -- 2 - rgmUpdateSliders
function(len) -- 1 - rgmUpdateSliders
UpdateManipulationSliders(RAGDOLLMOVER[pl].Bone, RAGDOLLMOVER[pl].Entity)
end,
function(len) -- 3 - rgmUpdateLists
function(len) -- 2 - rgmUpdateLists
IsPropRagdoll = net.ReadBool()
ScaleLocks = {}
@ -4429,7 +4457,7 @@ local NETFUNC = {
end
end,
function(len) -- 4 - rgmUpdateGizmo
function(len) -- 3 - rgmUpdateGizmo
local vector = net.ReadVector()
if not IsValid(Gizmo1) then return end
Gizmo1:SetValue(vector.x)
@ -4437,7 +4465,7 @@ local NETFUNC = {
Gizmo3:SetValue(vector.z)
end,
function(len) -- 5 - rgmUpdateEntInfo
function(len) -- 4 - rgmUpdateEntInfo
local ent = net.ReadEntity()
local physchildren = {}
ScaleLocks = {}
@ -4465,7 +4493,7 @@ local NETFUNC = {
end
end,
function(len) -- 6 - rgmAskForPhysbonesResponse
function(len) -- 5 - rgmAskForPhysbonesResponse
local entcount = net.ReadUInt(13)
for j = 1, entcount do
local ent = net.ReadEntity()
@ -4504,7 +4532,7 @@ local NETFUNC = {
end
end,
function(len) -- 7 - rgmAskForParentedResponse
function(len) -- 6 - rgmAskForParentedResponse
local entcount = net.ReadUInt(13)
for i = 1, entcount do
@ -4523,7 +4551,7 @@ local NETFUNC = {
end
end,
function(len) -- 8 - rgmLockBoneResponse
function(len) -- 7 - rgmLockBoneResponse
local ent = net.ReadEntity()
local boneid = net.ReadUInt(10)
local poslock = net.ReadBool()
@ -4547,7 +4575,7 @@ local NETFUNC = {
end
end,
function(len) -- 9 - rgmLockToBoneResponse
function(len) -- 8 - rgmLockToBoneResponse
local ent = net.ReadEntity()
local lockbone = net.ReadUInt(10)
@ -4562,7 +4590,7 @@ local NETFUNC = {
end
end,
function(len) -- 10 - rgmUnlockToBoneResponse
function(len) -- 9 - rgmUnlockToBoneResponse
local ent = net.ReadEntity()
local unlockbone = net.ReadUInt(10)
@ -4573,7 +4601,7 @@ local NETFUNC = {
end
end,
function(len) -- 11 - rgmLockConstrainedResponse
function(len) -- 10 - rgmLockConstrainedResponse
local lock = net.ReadBool()
local lockent = net.ReadEntity()
@ -4588,7 +4616,7 @@ local NETFUNC = {
end
end,
function(len) -- 12 - rgmSelectBoneResponse
function(len) -- 11 - rgmSelectBoneResponse
local function SetVisiblePhysControls(bool)
local inverted = not bool
@ -4627,7 +4655,7 @@ local NETFUNC = {
rgmSendBonePos(pl, ent, boneid)
end,
function(len) -- 13 - rgmAskForNodeUpdatePhysicsResponse
function(len) -- 12 - rgmAskForNodeUpdatePhysicsResponse
local isphys = net.ReadBool()
local entcount = net.ReadUInt(13)
local physids, ents = {}
@ -4650,12 +4678,12 @@ local NETFUNC = {
UpdateBoneNodes(BonePanel, physids, isphys)
end,
function(len) -- 14 - rgmRequestBonePos
function(len) -- 13 - rgmRequestBonePos
if not RAGDOLLMOVER[pl] then return end
rgmSendBonePos(pl, RAGDOLLMOVER[pl].Entity, RAGDOLLMOVER[pl].Bone)
end,
function(len) -- 15 - rgmNotification
function(len) -- 14 - rgmNotification
local message = net.ReadUInt(5)
rgmDoNotification(message)
@ -4663,7 +4691,7 @@ local NETFUNC = {
}
net.Receive("RAGDOLLMOVER", function(len)
NETFUNC[net.ReadUInt(4)](len)
NETFUNC[net.ReadUInt(4) + 1](len)
end)
local material = CreateMaterial("rgmGizmoMaterial", "UnlitGeneric", {
@ -4676,6 +4704,67 @@ local material = CreateMaterial("rgmGizmoMaterial", "UnlitGeneric", {
["$nocull"] = 1,
})
local LastPressed = false
function TOOL:Think()
if RAGDOLLMOVER[pl] then
local op = self:GetOperation()
local nowpressed = input.IsMouseDown(MOUSE_LEFT)
if nowpressed and not LastPressed and op == 2 then -- left click is a predicted function, so leftclick wouldn't work in singleplayer since i need data from client
local ent = RAGDOLLMOVER[pl].Entity
if IsValid(ent) then
if self:GetStage() ~= 1 then
local selbones = rgm.AdvBoneSelectPick(ent)
if next(selbones) then
if #selbones == 1 then
net.Start("RAGDOLLMOVER")
net.WriteUInt(4, 5)
net.WriteEntity(ent)
net.WriteUInt(selbones[1], 10)
net.SendToServer()
timer.Simple(0.1, function()
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 5)
net.WriteUInt(0, 2)
net.SendToServer()
end)
else
RAGDOLLMOVER[pl].SelectedBones = selbones
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 5)
net.WriteUInt(3, 2)
net.SendToServer()
gui.EnableScreenClicker(true)
end
end
else
net.Start("RAGDOLLMOVER")
net.WriteUInt(4, 5)
net.WriteEntity(ent)
net.WriteUInt(rgm.AdvBoneSelectRadialPick(), 10)
net.SendToServer()
timer.Simple(0.1, function()
net.Start("RAGDOLLMOVER")
net.WriteUInt(14, 5)
net.WriteUInt(0, 2)
net.SendToServer()
end)
gui.EnableScreenClicker(false)
end
end
end
LastPressed = nowpressed
end
end
function TOOL:DrawHUD()
@ -4687,7 +4776,8 @@ function TOOL:DrawHUD()
local moving = RAGDOLLMOVER[pl].Moving or false
--We don't draw the axis if we don't have the axis entity or the target entity,
--or if we're not allowed to draw it.
if IsValid(ent) and IsValid(axis) and bone then
if not (self:GetOperation() == 2) and IsValid(ent) and IsValid(axis) and bone then
local scale = GizmoScale or 10
local width = GizmoWidth or 0.5
local moveaxis = axis[RGMGIZMOS.GizmoTable[RAGDOLLMOVER[pl].MoveAxis]]
@ -4727,7 +4817,13 @@ function TOOL:DrawHUD()
rgm.DrawSkeleton(ent)
end
if IsValid(HoveredEntBone) and EntityFilter(HoveredEntBone, self) and HoveredBone then
if self:GetOperation() == 2 and IsValid(ent) then
if self:GetStage() == 0 then
rgm.AdvBoneSelectRender(ent)
else
rgm.AdvBoneSelectRadialRender(ent, RAGDOLLMOVER[pl].SelectedBones)
end
elseif IsValid(HoveredEntBone) and EntityFilter(HoveredEntBone, self) and HoveredBone then
rgm.DrawBoneConnections(HoveredEntBone, HoveredBone)
rgm.DrawBoneName(HoveredEntBone, HoveredBone)
elseif IsValid(HoveredEnt) and EntityFilter(HoveredEnt, self) then

View File

@ -16,7 +16,7 @@ local function ClearPropRagdoll(ent)
if RAGDOLLMOVER[pl] and RAGDOLLMOVER[pl].Entity == ent then
RAGDOLLMOVER[pl].Entity = nil
net.Start("RAGDOLLMOVER")
net.WriteUInt(1, 4)
net.WriteUInt(0, 4)
net.Send(pl)
end
end
@ -189,7 +189,7 @@ net.Receive("RAGDOLLMOVER_PROPRAGDOLL", function(len, pl)
if filter[RAGDOLLMOVER[pl].Entity] then
RAGDOLLMOVER[pl].Entity = nil
net.Start("RAGDOLLMOVER")
net.WriteUInt(1, 4)
net.WriteUInt(0, 4)
net.Send(ply)
end
end
@ -938,9 +938,11 @@ function TOOL.BuildCPanel(CPanel)
end
local COLOR_RGMGREEN = Color(0, 200, 0, 255)
local VECTOR_FORWARD = Vector(1, 0, 0)
local VECTOR_LEFT = Vector(0, 1, 0)
local COLOR_RGMGREEN = RGM_Constants.COLOR_GREEN
local COLOR_RGMBLACK = RGM_Constants.COLOR_BLACK
local OUTLINE_WIDTH = RGM_Constants.OUTLINE_WIDTH
local VECTOR_FORWARD = RGM_Constants.VECTOR_FRONT
local VECTOR_LEFT = RGM_Constants.VECTOR_LEFT
function TOOL:DrawHUD()
@ -956,7 +958,7 @@ function TOOL:DrawHUD()
local textpos = { x = pos.x + 5, y = pos.y - 5 }
surface.DrawCircle(pos.x, pos.y, 3.5, COLOR_RGMGREEN)
if ent ~= HoveredEnt then
draw.SimpleText(node.id, "Default", textpos.x, textpos.y, COLOR_RGMGREEN, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM)
draw.SimpleTextOutlined(node.id, "Default", textpos.x, textpos.y, COLOR_RGMGREEN, TEXT_ALIGN_LEFT, TEXT_ALIGN_BOTTOM, OUTLINE_WIDTH, COLOR_RGMBLACK)
end
if not node.parent then continue end

View File

@ -4,12 +4,16 @@ tool.ragdollmover.desc=Allows advanced movement of ragdolls!
tool.ragdollmover.left_default=Select and move bones
tool.ragdollmover.info_default=Toggle between move/rotate/scale by using buttons that are set through tool's menu (Default: Middle and right mouse buttons)
tool.ragdollmover.info_defadvselect=Toggle advanced bone selection by pressing walk key
tool.ragdollmover.reload_default=Switch to the root bone of the ragdoll
tool.ragdollmover.left_gizmomode=Set offset to location you aim at
tool.ragdollmover.right_gizmomode=Set offset to coordinate center of the object you aim at
tool.ragdollmover.reload_gizmomode=Cancel set offset mode
tool.ragdollmover.left_advselect=Select any bone on the ragdoll!
tool.ragdollmover.info_advselect=Cancel selection mode by pressing walk key
tool.ragdollmover.gizmopanel=Gizmo
tool.ragdollmover.localpos=Local position gizmo
tool.ragdollmover.localang=Local angle gizmo
@ -42,7 +46,7 @@ tool.ragdollmover.unfreezetip=Unfreeze bones that were unfrozen before grabbing
tool.ragdollmover.disablefilter=Disable entity filter
tool.ragdollmover.disablefiltertip=Disable entity filter to select ANY entity. CAUTION - may be buggy
tool.ragdollmover.drawskeleton=Draw Skeleton
tool.ragdollmover.updaterate=Tool update rate
tool.ragdollmover.updaterate=Tool update interval
tool.ragdollmover.lockselected=Disable entity selection
tool.ragdollmover.snapenable=Enable angle snapping
tool.ragdollmover.snapamount=Angle snap amount

View File

@ -4,12 +4,16 @@ tool.ragdollmover.desc=Продвинутое позирование рэгдо
tool.ragdollmover.left_default=Выбрать и передвигать кости
tool.ragdollmover.info_default=Меняйте режим между передвижением/вращением/масштабированием через кнопки заданными в меню инструмента (По умолчанию: Средняя и правая кнопки мыши)
tool.ragdollmover.info_defadvselect=Включите продвинутый выбор костей нажатием кнопки ходьбы
tool.ragdollmover.reload_default=Выбрать корневую кость рэгдола
tool.ragdollmover.left_gizmomode=Задать сдвиг гизмо
tool.ragdollmover.right_gizmomode=Задать сдвиг гизмо в координатный центр объекта
tool.ragdollmover.reload_gizmomode=Отменить режим задания сдвига гизмо
tool.ragdollmover.left_advselect=Выберите любую кость на регдолле!
tool.ragdollmover.info_advselect=Отмените режим выбора нажатием на кнопку ходьбы
tool.ragdollmover.gizmopanel=Гизмо
tool.ragdollmover.localpos=Перемещение относительно кости
tool.ragdollmover.localang=Вращение относительно кости
@ -42,7 +46,7 @@ tool.ragdollmover.unfreezetip=Разморозить кости которые
tool.ragdollmover.disablefilter=Выключить фильтр энтитей
tool.ragdollmover.disablefiltertip=Позволяет выбрать ЛЮБУЮ энтити на карте. ВНИМАНИЕ - может вызывать баги
tool.ragdollmover.drawskeleton=Отображать скелет
tool.ragdollmover.updaterate=Частота обновлений
tool.ragdollmover.updaterate=Интервал обновлений
tool.ragdollmover.lockselected=Отключить выделение энтитей
tool.ragdollmover.snapenable=Включить пошаговый поворот
tool.ragdollmover.snapamount=Шаг поворота