Last active
September 20, 2018 05:30
-
-
Save dhkatz/9e39ae18fd6c2969a785f07cc4db4053 to your computer and use it in GitHub Desktop.
Debug Door Attaching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CreateClientConVar("pd2_drill_debug", "0", true, false, "Draw Payday 2 Drill debug information.") | |
local doors = { ["prop_door_rotating"] = true, ["func_door"] = true, ["func_door_rotating"] = true } | |
hook.Add("PostDrawTranslucentRenderables", "DoorPos", function() | |
if not cvars.Bool("pd2_drill_debug") then return end | |
-- Find the drill we're working with | |
local drill = NULL | |
for _, e in ipairs(ents.FindInSphere(LocalPlayer():GetPos(), 500)) do | |
if e:GetClass() == "pd2_drill" then | |
drill = e | |
break | |
end | |
end | |
-- Get rid of all ghost drills no matter what | |
for _, e in ipairs(ents.FindByClass("pd2_drill")) do | |
if not IsValid(e) then continue end | |
if IsValid(e.Ghost) then e.Ghost:Remove() end | |
end | |
-- If we don't have a drill at this point return | |
if not IsValid(drill) or drill.Attached then return end | |
-- Find the door we're working with | |
local door = NULL | |
for _, e in ipairs(ents.FindInSphere(drill:GetPos(), 100)) do | |
if doors[e:GetClass()] then | |
door = e | |
break | |
end | |
end | |
-- If we don't have a door then make sure our ghost is cleaned up then return | |
if not IsValid(door) then if IsValid(drill.Ghost) then drill.Ghost:Remove() end return end | |
-- Unfortunately, there is no way to check if a door is open/closed on the client :/ | |
net.Start("PD2Drill.UpdateDoor") | |
net.WriteEntity(door) | |
net.SendToServer() | |
if not door.Closed then return end | |
-- Find the attachment point for the drill | |
local pos, b1, b2 = door:GetPos(), door:LookupBone("handle"), door:LookupBone("handle02") | |
if b1 or b2 then -- We have something to work with... | |
if b1 and b2 then -- Pick the closer one! | |
local p1, p2 = door:GetBonePosition(b1), door:GetBonePosition(b2) | |
local bone = p1:DistToSqr(drill:GetPos()) < p2:DistToSqr(drill:GetPos()) and b1 or b2 | |
pos = b1 == bone and p1 or p2 | |
else -- Pick whichever we have! | |
pos = b1 and door:GetBonePosition(b1) or door:GetBonePosition(b2) | |
end | |
end | |
-- Run a trace to see how the drill will be positioned | |
local trace = util.TraceLine({ | |
start = drill:GetPos(), | |
endpos = pos, | |
filter = function(e) | |
return e:EntIndex() == door:EntIndex() | |
end | |
}) | |
-- Determine best position and angle | |
local angle, p1, p2 = trace.HitNormal:Angle(), pos + Vector(10, 0, -11), pos + Vector(-10, 0, -11) | |
pos = drill:GetPos():DistToSqr(p1) < drill:GetPos():DistToSqr(p2) and p1 or p2 | |
-- Create the ghost if it's not valid | |
if not IsValid(drill.Ghost) then | |
drill.Ghost = ClientsideModel(drill:GetModel(), RENDERGROUP_BOTH) | |
drill.Ghost:SetSkin(drill:GetSkin()) | |
drill.Ghost:SetColor(Color(255, 255, 255, 150)) | |
drill.Ghost:SetRenderMode( RENDERMODE_TRANSALPHA ) | |
-- Be a good citizen and clean up the ghost if the drill gets removed! | |
drill:CallOnRemove("RemoveGhost", function(ent) | |
if IsValid(ent.Ghost) then ent.Ghost:Remove() end | |
end) | |
end | |
-- Actually position the ghost properly | |
drill:SetNoDraw(false) | |
drill.Ghost:SetPos(pos) | |
drill.Ghost:SetAngles(angle:Forward():Angle() + Angle(0, 180, 0)) | |
-- Draw some helpful debug lines | |
render.DrawLine( trace.HitPos, trace.HitPos + 8 * angle:Forward(), Color( 255, 0, 0 ), false ) | |
render.DrawLine( trace.HitPos, trace.HitPos + 8 * -angle:Right(), Color( 0, 255, 0 ), false ) | |
render.DrawLine( trace.HitPos, trace.HitPos + 8 * angle:Up(), Color( 0, 0, 255 ), false ) | |
render.DrawLine(drill:GetPos(), trace.HitPos, Color(255, 255, 255), false) | |
render.SetColorMaterial() | |
render.DrawSphere(pos, 1, 30, 30, Color(255, 255, 0)) | |
-- Calculate mass of door | |
local mass = 0 | |
if not IsValid(door:GetPhysicsObject()) then | |
local dims = door:OBBMaxs() - door:OBBMins() | |
mass = dims.x * dims.y * dims.z | |
else | |
mass = door:GetPhysicsObject():GetMass() | |
end | |
cam.Start2D() | |
-- Generate drill time based on door mass (maybe use thickness?) | |
draw.SimpleText("MASS: " .. mass .. "\nTIME: " .. math.ceil(-1 / 1237500000 * math.pow(mass, 2) + 199 / 495000 * mass - 305 / 99), "DermaDefault", ScrW() / 2, ScrH() / 2 - ScrH() / 4, Color(255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER) | |
cam.End2D() | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment