From 5526191235e3f091a3e4ba46fa7ece417d108921 Mon Sep 17 00:00:00 2001 From: Deyan Dobromirov Date: Fri, 29 Sep 2017 18:03:16 +0300 Subject: [PATCH] Added: Dedicated player cache and caching player functions --- lua/autorun/gearassembly_init.lua | 43 ++-- lua/gearassembly/gearasmlib.lua | 235 ++++++++++-------- lua/weapons/gmod_tool/stools/gearassembly.lua | 27 +- 3 files changed, 172 insertions(+), 133 deletions(-) diff --git a/lua/autorun/gearassembly_init.lua b/lua/autorun/gearassembly_init.lua index 46da513..1be88e9 100644 --- a/lua/autorun/gearassembly_init.lua +++ b/lua/autorun/gearassembly_init.lua @@ -25,7 +25,7 @@ local asmlib = gearasmlib ------ CONFIGURE ASMLIB ------ asmlib.InitBase("gear","assembly") -asmlib.SetOpVar("TOOL_VERSION","5.188") +asmlib.SetOpVar("TOOL_VERSION","5.189") asmlib.SetIndexes("V",1,2,3) asmlib.SetIndexes("A",1,2,3) asmlib.SetIndexes("S",4,5,6,7) @@ -112,8 +112,15 @@ if(SERVER) then asmlib.SetAction("DUPE_PHYS_SETTINGS", function(oPly,oEnt,tData) -- Duplicator wrapper if(not asmlib.ApplyPhysicalSettings(oEnt,tData[1],tData[2],tData[3])) then - return asmlib.StatusLog(false,"DUPE_PHYS_SETTINGS: Failed to apply physical settings on "..tostring(oEnt)) end - return asmlib.StatusLog(true,"DUPE_PHYS_SETTINGS: Success") + return asmlib.StatusLog(nil,"DUPE_PHYS_SETTINGS: Failed to apply physical settings on "..tostring(oEnt)) end + return asmlib.StatusLog(nil,"DUPE_PHYS_SETTINGS: Success") + end) + + asmlib.SetAction("PLAYER_QUIT", + function(oPly) + if(not asmlib.ClearCachePly(oPly)) then + return asmlib.StatusLog(nil,"PLAYER_QUIT: Failed swiping stuff "..tostring(oPly)) end + return asmlib.StatusLog(nil,"PLAYER_QUIT: Success") end) end @@ -134,7 +141,7 @@ if(CLIENT) then asmlib.ConCommandPly(oPly,"rotpivh" , 0) asmlib.ConCommandPly(oPly,"deltarot" , 360) if(not devmode) then - return asmlib.StatusLog(true,"RESET_VARIABLES: Developer mode disabled") end + return asmlib.StatusLog(nil,"RESET_VARIABLES: Developer mode disabled") end asmlib.SetLogControl(asmlib.GetAsmVar("logsmax" , "INT"), asmlib.GetAsmVar("logfile" , "STR")) if(bgskids == "reset cvars") then -- Reset the limit also oPly:ConCommand("sbox_max"..asmlib.GetOpVar("CVAR_LIMITNAME").." 1500\n") @@ -181,22 +188,23 @@ if(CLIENT) then asmlib.RemoveDSV("PIECES",vPr) asmlib.LogInstance("RESET_VARIABLES: Match <"..vPr..">") end - else return asmlib.StatusLog(true,"RESET_VARIABLES: Command <"..bgskids.."> skipped") end - return asmlib.StatusLog(true,"RESET_VARIABLES: Success") + else return asmlib.StatusLog(nil,"RESET_VARIABLES: Command <"..bgskids.."> skipped") end + return asmlib.StatusLog(nil,"RESET_VARIABLES: Success") end) asmlib.SetAction("OPEN_FRAME", function(oPly,oCom,oArgs) local frUsed, nCount = asmlib.GetFrequentModels(oArgs[1]) if(not asmlib.IsExistent(frUsed)) then - return asmlib.StatusLog(false,"OPEN_FRAME: Failed to retrieve most frequent models ["..tostring(oArgs[1]).."]") + return asmlib.StatusLog(nil,"OPEN_FRAME: Failed to retrieve most frequent models ["..tostring(oArgs[1]).."]") end local defTable = asmlib.GetOpVar("DEFTABLE_PIECES") - if(not defTable) then return StatusLog(false,"OPEN_FRAME: Missing definition for table PIECES") end + if(not defTable) then + return StatusLog(nil,"OPEN_FRAME: Missing definition for table PIECES") end local pnFrame = vguiCreate("DFrame") if(not IsValid(pnFrame)) then pnFrame:Remove() - return asmlib.StatusLog(false,"OPEN_FRAME: Failed to create base frame") + return asmlib.StatusLog(nil,"OPEN_FRAME: Failed to create base frame") end local pnElements = asmlib.MakeContainer("FREQ_VGUI") pnElements:Insert(1,{Label = { "DButton" ,languageGetPhrase("tool."..gsToolNameL..".pn_export_lb") , languageGetPhrase("tool."..gsToolNameL..".pn_export")}}) @@ -220,7 +228,7 @@ if(CLIENT) then iNdex = iNdex + 1 end pnFrame:Remove(); collectgarbage() - return StatusLog(false,"OPEN_FRAME: Invalid panel created. Frame removed") + return StatusLog(nil,"OPEN_FRAME: Invalid panel created. Frame removed") end vItem.Panel:SetName(vItem.Label[2]) vItem.Panel:SetTooltip(vItem.Label[3]) @@ -314,12 +322,13 @@ if(CLIENT) then pnModelPanel:SetVisible(true) pnModelPanel.LayoutEntity = function(pnSelf, oEnt) if(pnSelf.bAnimated) then pnSelf:RunAnimation() end + local uiPly = LocalPlayer() local uiBox = asmlib.CacheBoxLayout(oEnt,40) if(not asmlib.IsExistent(uiBox)) then - return asmlib.StatusLog(false,"OPEN_FRAME: pnModelPanel.LayoutEntity: Box invalid") end - local stSpawn = asmlib.GetNormalSpawn(asmlib.GetOpVar("VEC_ZERO"),uiBox.Ang,oEnt:GetModel()) + return asmlib.StatusLog(nil,"OPEN_FRAME: pnModelPanel.LayoutEntity: Box invalid") end + local stSpawn = asmlib.GetNormalSpawn(uiPly,asmlib.GetOpVar("VEC_ZERO"),uiBox.Ang,oEnt:GetModel()) if(not stSpawn) then - return asmlib.StatusLog(false,"OPEN_FRAME: pnModelPanel.LayoutEntity: Spawn data fail") end + return asmlib.StatusLog(nil,"OPEN_FRAME: pnModelPanel.LayoutEntity: Spawn data fail") end asmlib.ApplySpawnFlat(oEnt, stSpawn, asmlib.GetOpVar("VEC_UP")) stSpawn.SPos:Set(uiBox.Cen) stSpawn.SPos:Rotate(stSpawn.SAng) @@ -347,7 +356,7 @@ if(CLIENT) then sField = tostring(sField or "") local sPattern = tostring(pnSelf:GetValue() or "") if(not asmlib.UpdateListView(pnListView,frUsed,nCount,sField,sPattern)) then - return asmlib.StatusLog(false,"OPEN_FRAME: TextEntry.OnEnter: Failed to update ListView {"..sName.."#"..sField.."#"..sPattern.."}") + return asmlib.StatusLog(nil,"OPEN_FRAME: TextEntry.OnEnter: Failed to update ListView {"..sName.."#"..sField.."#"..sPattern.."}") end end ------------ ListView -------------- @@ -382,17 +391,17 @@ if(CLIENT) then local uiEnt = pnModelPanel:GetEntity() local uiBox = asmlib.CacheBoxLayout(uiEnt,0,nRatio,nRatio-1) if(not asmlib.IsExistent(uiBox)) then - return asmlib.StatusLog(false,"OPEN_FRAME: ListView.OnRowSelected: Box invalid for <"..uiMod..">") end + return asmlib.StatusLog(nil,"OPEN_FRAME: ListView.OnRowSelected: Box invalid for <"..uiMod..">") end pnModelPanel:SetLookAt(uiBox.Eye); pnModelPanel:SetCamPos(uiBox.Cam) asmlib.ConCommandPly(oPly, "model" ,uiMod) end -- Copy the line model to the clipboard so it can be pasted with Ctrl+V pnListView.OnRowRightClick = function(pnSelf, nIndex, pnLine) SetClipboardText(pnLine:GetColumnText(5)) end if(not asmlib.UpdateListView(pnListView,frUsed,nCount)) then - asmlib.StatusLog(false,"OPEN_FRAME: ListView.OnRowSelected: Populate the list view failed") end + return asmlib.StatusLog(nil,"OPEN_FRAME: ListView.OnRowSelected: Populate the list view failed") end ------------ Show the completed panel -------------- pnFrame:SetVisible(true); pnFrame:Center() pnFrame:MakePopup() ; collectgarbage() - return asmlib.StatusLog(true,"OPEN_FRAME: Success") + return asmlib.StatusLog(nil,"OPEN_FRAME: Success") end) end diff --git a/lua/gearassembly/gearasmlib.lua b/lua/gearassembly/gearasmlib.lua index afddb04..cb3a3fe 100644 --- a/lua/gearassembly/gearasmlib.lua +++ b/lua/gearassembly/gearasmlib.lua @@ -144,6 +144,7 @@ local duplicatorStoreEntityModifier = duplicator and duplicator.StoreEntityModif local libCache = {} -- Used to cache stuff in a Pool local libAction = {} -- Used to attach external function to the lib local libOpVars = {} -- Used to Store operational Variable Values +local libPlayer = {} module( "gearasmlib" ) @@ -447,7 +448,6 @@ function InitBase(sName,sPurpose) SetOpVar("MODELNAM_FUNC",function(x) return " "..x:sub(2,2):upper() end) SetOpVar("QUERY_STORE", {}) SetOpVar("TABLE_BORDERS",{}) - SetOpVar("TABLE_PLAYER",{}) SetOpVar("TABLE_FREQUENT_MODELS",{}) SetOpVar("OOP_DEFAULTKEY","(!@<#_$|%^|&>*)DEFKEY(*>&|^%|$_#<@!)") SetOpVar("CVAR_LIMITNAME","asm"..GetOpVar("NAME_INIT").."s") @@ -456,30 +456,6 @@ function InitBase(sName,sPurpose) SetOpVar("HASH_QUERY_STORE",GetOpVar("TOOLNAME_PU").."QHASH_QUERY") SetOpVar("NAV_PIECE",{}) SetOpVar("NAV_PANEL",{}) - SetOpVar("STRUCT_SPAWN",{ - F = Vector(), -- Origin forward vector - R = Vector(), -- Origin right vector - U = Vector(), -- Origin up vector - OPos = Vector(), -- Origin position - OAng = Angle (), -- Origin angle - SPos = Vector(), -- Gear spawn position - SAng = Angle (), -- Gear spawn angle - DPos = Vector(), -- Domain position. Used for decomposition - DAng = Angle (), -- Domain angle. Used for constraints - --- Holder --- - HRec = 0, -- Pointer to the holder record - HPnt = Vector(), -- P - HMas = Vector(), -- O - HAng = Angle (), -- A - --- Traced --- - TRec = 0, -- Pointer to the trace record - TPnt = Vector(), -- P - TMas = Vector(), -- O - TAng = Angle (), -- A - --- Offsets --- - ANxt = Angle (), - PNxt = Vector() - }) return StatusPrint(true,"InitBase: Success") end @@ -1390,51 +1366,99 @@ end ------------------------- PLAYER ----------------------------------- +local function GetPlacePly(pPly) + if(not IsPlayer(pPly)) then + return StatusLog(nil,"GetPlacePly: Player <"..tostring(pPly)"> invalid") end + local plyPlace = libPlayer[pPly] + if(not IsExistent(plyPlace)) then + LogInstance("GetPlacePly: Cached <"..pPly:Nick()..">") + libPlayer[pPly] = {}; plyPlace = libPlayer[pPly] + end; return plyPlace +end + +local function CacheSpawnPly(pPly) + local plyPlace = GetPlacePly(pPly) + if(not IsExistent(plyPlace)) then + return StatusLog(nil,"CacheSpawnPly: Place missing") end + local plyData = plyPlace["SPAWN"] + if(not IsExistent(plyData)) then + LogInstance("CacheSpawnPly: Malloc <"..pPly:Nick()..">") + plyPlace["SPAWN"] = {}; plyData = plyPlace["SPAWN"] + plyData.F = Vector() -- Origin forward vector + plyData.R = Vector() -- Origin right vector + plyData.U = Vector() -- Origin up vector + plyData.OPos = Vector() -- Origin position + plyData.OAng = Angle () -- Origin angle + plyData.SPos = Vector() -- Gear spawn position + plyData.SAng = Angle () -- Gear spawn angle + plyData.DPos = Vector() -- Domain position. Used for decomposition + plyData.DAng = Angle () -- Domain angle. Used for constraints + --- Holder --- + plyData.HRec = 0 -- Pointer to the holder record + plyData.HPnt = Vector() -- P + plyData.HMas = Vector() -- O + plyData.HAng = Angle () -- A + --- Traced --- + plyData.TRec = 0 -- Pointer to the trace record + plyData.TPnt = Vector() -- P + plyData.TMas = Vector() -- O + plyData.TAng = Angle () -- A + --- Offsets --- + plyData.ANxt = Angle () + plyData.PNxt = Vector() + end; return plyData +end + +function ClearCachePly(pPly) + if(not IsPlayer(pPly)) then + return StatusLog(false,"ClearCachePly: Player <"..tostring(pPly)"> invalid") end + local plyPlace = libPlayer[pPly] + if(not IsExistent(plyPlace)) then + return StatusLog(true,"ClearCachePly: Clean") end + plyTable[pPly] = nil; collectgarbage(); return true +end + function GetDistanceHitPly(pPly, vHit) if(not IsPlayer(pPly)) then return StatusLog(nil,"GetDistanceHitPly: Player <"..tostring(pPly)"> invalid") end return (vHit - pPly:GetPos()):Length() end -function GetRadiusRatioPly(pPly, vHit, nMul) - if(not IsPlayer(pPly)) then - return StatusLog(nil,"GetRadiusRatioPly: Player <"..tostring(pPly)"> invalid") end - local plyTable = GetOpVar("TABLE_PLAYER") - local plyPlace = plyTable[pPly] +function CacheRadiusPly(pPly, vHit, nSca) + local plyPlace = GetPlacePly(pPly) if(not IsExistent(plyPlace)) then - plyTable[pPly] = {}; plyPlace = plyTable[pPly] end - local plyRadius = plyPlace["RADIUS"] - if(not IsExistent(plyPlace)) then - plyPlace["RADIUS"] = {}; plyRadius = plyPlace["RADIUS"] - plyRadius["MAR"] = (GetOpVar("GOLDEN_RATIO") * 1000), - plyRadius["LIM"] = ((GetOpVar("GOLDEN_RATIO") - 1) * 100) + return StatusLog(nil,"CacheRadiusPly: Place missing") end + local plyData = plyPlace["RADIUS"] + if(not IsExistent(plyData)) then + LogInstance("CacheRadiusPly: Malloc <"..pPly:Nick()..">") + plyPlace["RADIUS"] = {}; plyData = plyPlace["RADIUS"] + plyData["MAR"] = (GetOpVar("GOLDEN_RATIO") * 1000), + plyData["LIM"] = ((GetOpVar("GOLDEN_RATIO") - 1) * 100) end - local nMul = (tonumber(nMul) or 1) -- Disable scaling on missing + local nMul = (tonumber(nSca) or 1) -- Disable scaling on missing or outside nMul = ((nMul <= 1 and nMul >= 0) and nMul or 1) - local nMar, nLim = plyRadius["MAR"], plyRadius["LIM"] + local nMar, nLim = plyData["MAR"], plyData["LIM"] local nDst = GetDistanceHitPly(pPly, vHit) local nRad = ((nDst ~= 0) and mathClamp((nMar / nDst) * nMul, 1, nLim) or 0) return nRad, nDis end -function GetTracePly(pPly) - if(not IsPlayer(pPly)) then - return StatusLog(nil,"GetTracePly: Player <"..tostring(pPly)"> invalid") end - local plyTable = GetOpVar("TABLE_PLAYER") - local plyPlace, plyTime = plyTable[pPly], Time() +function CacheTracePly(pPly) + local plyPlace = GetPlacePly(pPly) if(not IsExistent(plyPlace)) then - plyTable[pPly] = {}; plyPlace = plyTable[pPly] end - local plyTrace = plyPlace["TRACE"] - if(not plyTrace) then -- Define trace delta margin - plyPlace["TRACE"] = {}; plyTrace = plyPlace["TRACE"] - plyTrace["TDM"] = 0.02 -- Trace delta time margin - plyTrace["NXT"] = plyTime + plyTrace["TDM"] -- Define next trace pending - plyTrace["DAT"] = utilTraceLine(utilGetPlayerTrace(pPly)) -- Make a trace + return StatusLog(nil,"CacheTracePly: Place missing") end + local plyData = plyPlace["TRACE"] + if(not IsExistent(plyData)) then -- Define trace delta margin + LogInstance("CacheTracePly: Malloc <"..pPly:Nick()..">") + plyPlace["TRACE"] = {}; plyData = plyPlace["TRACE"] + plyData["TDM"] = 0.02 -- Trace delta time margin + plyData["NXT"] = plyTime + plyData["TDM"] -- Define next trace pending + plyData["DAT"] = utilTraceLine(utilGetPlayerTrace(pPly)) -- Make a trace end -- Check the trace time margin interval - if(plyTime >= plyTrace["NXT"]) then - plyTrace["NXT"] = plyTime + plyTrace["TDM"] -- Next trace margin - plyTrace["DAT"] = utilTraceLine(utilGetPlayerTrace(pPly)) - end; return plyTrace["DAT"] + if(plyTime >= plyData["NXT"]) then + plyData["NXT"] = plyTime + plyData["TDM"] -- Next trace margin + plyData["DAT"] = utilTraceLine(utilGetPlayerTrace(pPly)) + end; return plyData["DAT"] end function ConCommandPly(pPly,sCvar,snValue) @@ -1477,57 +1501,55 @@ function UndoFinishPly(pPly,anyMessage) end function CachePressPly(pPly) - if(not IsPlayer(pPly)) then - return StatusLog(false,"CachePressPly: Player invalid <"..tostring(pPly)..">") end - local plyTable = GetOpVar("TABLE_PLAYER") - local plyPlace = plyTable[pPly] - if(plyPlace["CMD"]) then return true end -- Already cached + local plyPlace = GetPlacePly(pPly) if(not IsExistent(plyPlace)) then - plyTable[pPly] = {}; plyPlace = plyTable[pPly] end - local ucmdPressed = pPly:GetCurrentCommand() - if(not IsExistent(ucmdPressed)) then - return StatusLog(false,"CachePressPly: Obtained incorrectly") end - local plyPress = plyPlace["PRESS"] - if(not plyPress) then -- Define trace delta margin - plyPlace["PRESS"] = {}; plyPress = plyPlace["PRESS"] end - plyPress["CMD"] = ucmdPressed - return StatusLog(true,"CachePressPly: Cached <"..tostring(pPly)..">") + return StatusLog(false,"CachePressPly: Place missing") end + local plyData = plyPlace["PRESS"] + if(not IsExistent(plyData)) then -- Create predicate command + LogInstance("CachePressPly: Malloc <"..pPly:Nick()..">") + plyPlace["PRESS"] = {}; plyData = plyPlace["PRESS"] + plyData["CMD"] = pPly:GetCurrentCommand() + if(not IsExistent(plyData["CMD"])) then + return StatusLog(false,"CachePressPly: Command incorrect") end + end; return true end +-- https://wiki.garrysmod.com/page/CUserCmd/GetMouseWheel function GetMouseWheelPly(pPly) - if(not IsPlayer(pPly)) then --- https://wiki.garrysmod.com/page/CUserCmd/GetMouseWheel - return StatusLog(false,"DeltaMousePly: Player invalid <"..tostring(pPly)">") end - local plyPlace = GetOpVar("TABLE_PLAYER")[pPly] + local plyPlace = GetPlacePly(pPly) if(not IsExistent(plyPlace)) then - return StatusLog(false,"DeltaMousePly: Cache missing <"..pPly:Nick()..">") end - local plyPress = plyPlace["PRESS"] - local cmdPress = (plyPress and plyPress["CMD"]) + return StatusLog(0,"GetMouseWheelPly: Place missing") end + local plyData = plyPlace["PRESS"] + if(not IsExistent(plyData)) then + return StatusLog(0,"GetMouseWheelPly: Data missing <"..pPly:Nick()..">") end + local cmdPress = plyData["CMD"] + if(not IsExistent(cmdPress)) then + return StatusLog(0,"GetMouseWheelPly: Command missing <"..pPly:Nick()..">") end return (cmdPress and cmdPress:GetMouseWheel() or 0) end +-- https://wiki.garrysmod.com/page/CUserCmd/GetMouse(XY) function GetMouseVectorPly(pPly) - if(not IsPlayer(pPly)) then --- https://wiki.garrysmod.com/page/CUserCmd/GetMouse(XY) - return StatusLog(false,"GetMouseVectorPly: Player <"..tostring(pPly)"> not available") end - local plyPlace = GetOpVar("TABLE_PLAYER")[pPly] + local plyPlace = GetPlacePly(pPly) + if(not IsExistent(plyPlace)) then + return 0, StatusLog(0,"GetMouseVectorPly: Place missing") end + local plyData = plyPlace["PRESS"] + if(not IsExistent(plyData)) then + return 0, StatusLog(0,"GetMouseVectorPly: Data missing <"..pPly:Nick()..">") end + local cmdPress = plyData["CMD"] + if(not IsExistent(plyData)) then + return 0, StatusLog(0,"GetMouseVectorPly: Command missing <"..pPly:Nick()..">") end + return cmdPress:GetMouseX(), cmdPress:GetMouseY() +end + +-- https://wiki.garrysmod.com/page/Enums/IN +function CheckButtonPly(pPly, iInKey) + local plyPlace, iInKey = GetPlacePly(pPly), (tonumber(iInKey) or 0) if(not IsExistent(plyPlace)) then - return StatusLog(false,"GetMouseVectorPly: Cache missing <"..pPly:Nick()..">") end - local plyPress = plyPlace["PRESS"] - local cmdPress = (plyPress and plyPress["CMD"]) - local cmdX = (cmdPress and cmdPress:GetMouseX() or 0) - local cmdY = (cmdPress and cmdPress:GetMouseY() or 0) - return ucmdX, ucmdY -end - -function CheckButtonPly(pPly, ivInKey) - if(not IsPlayer(pPly)) then --- https://wiki.garrysmod.com/page/Enums/IN - return StatusLog(false,"CheckButtonPly: Player invalid <"..tostring(pPly)">") end - local iInKey = tonumber(ivInKey) - if(not IsExistent(iInKey)) then - return StatusLog(false,"CheckButtonPly: Input key {"..type(ivInKey)"}<"..tostring(ivInKey).."> invalid") end - local plyPlace = GetOpVar("TABLE_PLAYER")[pPly] - if(CLIENT or (not IsExistent(plyPlace))) then return pPly:KeyDown(iInKey) end - local plyPress = plyPlace["PRESS"] - local cmdPress = (plyPress and plyPress["CMD"]) + return StatusLog(false,"GetMouseVectorPly: Place missing") end + local plyData = plyPlace["PRESS"] + if(not IsExistent(plyData)) then return pPly:KeyDown(iInKey) end + local cmdPress = plyData["CMD"] if(not IsExistent(cmdPress)) then return pPly:KeyDown(iInKey) end return (bitBand(cmdPress:GetButtons(),iInKey) ~= 0) -- Read the cache end @@ -2717,21 +2739,25 @@ end --[[ * This function is the backbone of the tool for Trace.Normal * Calculates SPos, SAng based on the DB inserts and input parameters + * oPly --> The player who is making the spawn * ucsPos,ucsAng --> Origin position and angle of the snapping * hdModel --> Holder's piece model * enOrAngTr --> Position offset comes from trace origin angle F,R,U * ucsPos(X,Y,Z) --> Offset position * ucsAng(P,Y,R) --> Offset angle ]]-- -function GetNormalSpawn(ucsPos,ucsAng,hdModel,hdPivot,enOrAngTr,ucsPosX,ucsPosY,ucsPosZ,ucsAngP,ucsAngY,ucsAngR) +function GetNormalSpawn(oPly,ucsPos,ucsAng,hdModel,hdPivot,enOrAngTr,ucsPosX,ucsPosY,ucsPosZ,ucsAngP,ucsAngY,ucsAngR) local hdRec = CacheQueryPiece(hdModel) if(not IsExistent(hdRec)) then return StatusLog(nil,"GetNormalSpawn: Holder is not a piece <"..tostring(hdModel)..">") end if(not (IsExistent(hdRec.Kept) and (hdRec.Kept == 1))) then return StatusLog(nil,"GetNormalSpawn: Line count <"..tostring(hdRec.Kept).."> mismatch for <"..tostring(hdModel)..">") end local hdPOA = hdRec.Offs - if(not IsExistent(hdPOA)) then return StatusLog(nil,"GetNormalSpawn: Offsets missing <"..tostring(hdModel)..">") end - local stSpawn = GetOpVar("STRUCT_SPAWN") + if(not IsExistent(hdPOA)) then + return StatusLog(nil,"GetNormalSpawn: Offsets missing <"..tostring(hdModel)..">") end + local stSpawn = CacheSpawnPly(oPly) + if(not IsExistent(stSpawn)) then + return StatusLog(nil,"GetNormalSpawn: Cannot obtain spawn data") end stSpawn.HRec = hdRec if(ucsPos) then SetVector(stSpawn.OPos,ucsPos); SetVector(stSpawn.TMas, ucsPos) end if(ucsAng) then SetVector(stSpawn.OAng,ucsAng); SetVector(stSpawn.TAng, ucsAng) end @@ -2793,16 +2819,17 @@ end * Calculates SPos, SAng based on the DB inserts and input parameters * From the position and angle of the entity, the mass-center is calculated * and used as an origin to build the spawn parameters, + * oPly --> The player who makes the spawn * trEnt --> Trace.Entity * trPivot --> Trace pivot rotation * hdPivot --> Holder pivot rotation * hdModel --> The holder model - * enIgnTyp --> Ignore Gear Type - * enOrAngTr --> Apply offsets + * enIgnTyp --> Ignores the gearbox type when enabled + * enOrAngTr --> Position offset comes from trace origin angle F,R,U * ucsPos(X,Y,Z) --> Offset position * ucsAng(P,Y,R) --> Offset angle ]]-- -function GetEntitySpawn(trEnt,trPivot,hdPivot,hdModel,enIgnTyp,enOrAngTr, +function GetEntitySpawn(oPly,trEnt,trPivot,hdPivot,hdModel,enIgnTyp,enOrAngTr, ucsPosX,ucsPosY,ucsPosZ,ucsAngP,ucsAngY,ucsAngR) if(not (trEnt and trEnt:IsValid())) then return StatusLog(nil,"GetEntitySpawn: Entity origin invalid") end @@ -2822,7 +2849,9 @@ function GetEntitySpawn(trEnt,trPivot,hdPivot,hdModel,enIgnTyp,enOrAngTr, local trPos , trAng = trEnt:GetPos(), trEnt:GetAngles() local trPivot, hdPivot = (tonumber(trPivot) or 0), (tonumber(hdPivot ) or 0) local hdModel, enIgnTyp = tostring(hdModel or ""), (tonumber(enIgnTyp) or 0) - local stSpawn = GetOpVar("STRUCT_SPAWN") -- Get cached spawn + local stSpawn = CacheSpawnPly(oPly) -- Get cached spawn + if(not IsExistent(stSpawn)) then + return StatusLog(nil,"GetEntitySpawn: Cannot obtain spawn data") end stSpawn.HRec, stSpawn.TRec = hdRec, trRec -- Save records SetVector(stSpawn.TPnt,trPOA.P) -- Store data in objects SetVector(stSpawn.TMas,trPOA.O) @@ -2842,7 +2871,7 @@ local function GetEntityOrTrace(oEnt) local pPly = LocalPlayer() if(not IsPlayer(pPly)) then return StatusLog(nil,"GetEntityOrTrace: Player <"..type(pPly)"> missing") end - local stTrace = GetTracePly(pPly) + local stTrace = CacheTracePly(pPly) if(not IsExistent(stTrace)) then return StatusLog(nil,"GetEntityOrTrace: Trace missing") end if(not stTrace.Hit) then -- Boolean diff --git a/lua/weapons/gmod_tool/stools/gearassembly.lua b/lua/weapons/gmod_tool/stools/gearassembly.lua index 8b6a885..fd10b1e 100644 --- a/lua/weapons/gmod_tool/stools/gearassembly.lua +++ b/lua/weapons/gmod_tool/stools/gearassembly.lua @@ -86,6 +86,7 @@ end if(SERVER) then cleanupRegister(gsLimitName) + hookAdd("PlayerDisconnected", gsToolPrefL.."player_quit", asmlib.GetActionCode("PLAYER_QUIT"))) duplicatorRegisterEntityModifier(gsToolPrefL.."dupe_phys_set",asmlib.GetActionCode("DUPE_PHYS_SETTINGS")) end @@ -408,7 +409,7 @@ function TOOL:LeftClick(stTrace) if(not (eBase and eBase:IsValid()) and (trEnt and trEnt:IsValid())) then eBase = trEnt end local vPos, vAxis = stTrace.HitPos, Vector() local aAng = asmlib.GetNormalAngle(ply, stTrace) - local stSpawn = asmlib.GetNormalSpawn(vPos,aAng,model,rotpivh,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) + local stSpawn = asmlib.GetNormalSpawn(ply,vPos,aAng,model,rotpivh,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) if(not stSpawn) then return asmlib.StatusLog(false,self:GetStatus(stTrace,"TOOL:LeftClick(World): Normal spawn failed")) end local ePiece = asmlib.MakePiece(ply,model,stTrace.HitPos,ANG_ZERO,mass,bgskids,conPalette:Select("w"),bnderrmod) if(not ePiece) then return asmlib.StatusLog(false,self:GetStatus(stTrace,"TOOL:LeftClick(World): Making piece failed")) end @@ -455,7 +456,7 @@ function TOOL:LeftClick(stTrace) if(not hdRec) then return asmlib.StatusLog(false,self:GetStatus(stTrace,"TOOL:LeftClick(Prop): Holder model not a piece")) end -- Stacking when the mode is within borders and count is more than one if(asmlib.CheckButtonPly(ply,IN_SPEED) and count > 1 and stmode >= 1 and stmode <= SMode:GetSize()) then - local stSpawn = asmlib.GetEntitySpawn(trEnt,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) + local stSpawn = asmlib.GetEntitySpawn(ply,trEnt,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) if(not stSpawn) then return asmlib.StatusLog(false,self:GetStatus(stTrace,"TOOL:LeftClick(Stack): Failed to retrieve spawn data")) end local ePieceO, ePieceN = trEnt, nil local aIter , aStart = ePieceO:GetAngles(), ePieceO:GetAngles() @@ -471,11 +472,11 @@ function TOOL:LeftClick(stTrace) return asmlib.StatusLog(false,self:GetStatus(stTrace,"TOOL:LeftClick(Stack): Failed to apply physical anchor",ePiece)) end asmlib.UndoAddEntityPly(ePieceN) if(stmode == 1) then - stSpawn = asmlib.GetEntitySpawn(ePieceN,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) + stSpawn = asmlib.GetEntitySpawn(ply,ePieceN,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) elseif(stmode == 2) then aIter:RotateAroundAxis(stSpawn.TAng:Up(),-dRot) trEnt:SetAngles(aIter) - stSpawn = asmlib.GetEntitySpawn(trEnt,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) + stSpawn = asmlib.GetEntitySpawn(ply,trEnt,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) end if(not stSpawn) then -- Look both ways in a one way street :D asmlib.PrintNotifyPly(ply,"Cannot obtain spawn data!","ERROR") @@ -494,7 +495,7 @@ function TOOL:LeftClick(stTrace) return asmlib.StatusLog(true,"TOOL:LeftClick(Stack): Success") end -- Mesh holder gear to the trace one when stack count is one - local stSpawn = asmlib.GetEntitySpawn(trEnt,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) + local stSpawn = asmlib.GetEntitySpawn(ply,trEnt,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) if(stSpawn) then local ePiece = asmlib.MakePiece(ply,model,stSpawn.SPos,stSpawn.SAng,mass,bgskids,conPalette:Select("w"),bnderrmod) if(ePiece) then @@ -579,7 +580,7 @@ end function TOOL:UpdateGhost(ePiece, oPly) if(not (ePiece and ePiece:IsValid())) then return end - local stTrace = asmlib.GetTracePly(oPly) + local stTrace = asmlib.CacheTracePly(oPly) if(not stTrace) then return end local trEnt = stTrace.Entity ePiece:SetNoDraw(true) @@ -595,7 +596,7 @@ function TOOL:UpdateGhost(ePiece, oPly) local igntyp = self:GetIgnoreType() local nextx , nexty , nextz = self:GetPosOffsets() local nextpic, nextyaw, nextrol = self:GetAngOffsets() - local stSpawn = asmlib.GetEntitySpawn(trEnt,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) + local stSpawn = asmlib.GetEntitySpawn(oPly,trEnt,rotpivt,rotpivh,model,igntyp,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) if(not stSpawn) then return end ePiece:SetNoDraw(false) ePiece:SetAngles(stSpawn.SAng) @@ -608,7 +609,7 @@ function TOOL:UpdateGhost(ePiece, oPly) local nextpic, nextyaw, nextrol = self:GetAngOffsets() local vPos = stTrace.HitPos local aAng = asmlib.GetNormalAngle(oPly, stTrace) - local stSpawn = asmlib.GetNormalSpawn(vPos,aAng,model,rotpivh,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) + local stSpawn = asmlib.GetNormalSpawn(oPly,vPos,aAng,model,rotpivh,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) if(not stSpawn) then return end if(spnflat) then asmlib.ApplySpawnFlat(ePiece,stSpawn,stTrace.HitNormal) end ePiece:SetNoDraw(false); ePiece:SetAngles(stSpawn.SAng); ePiece:SetPos(stSpawn.SPos); return @@ -681,7 +682,7 @@ function TOOL:DrawHUD() asmlib.LogInstance("DrawHUD: Create screen") end; hudMonitor:SetColor() local oPly = LocalPlayer() - local stTrace = asmlib.GetTracePly(oPly) + local stTrace = asmlib.CacheTracePly(oPly) if(not stTrace) then return end if(not self:GetAdviser()) then return end local trEnt = stTrace.Entity @@ -691,11 +692,11 @@ function TOOL:DrawHUD() local rotpivt, rotpivh = self:GetRotatePivot() local nextx , nexty , nextz = self:GetPosOffsets() local nextpic, nextyaw, nextrol = self:GetAngOffsets() - local plyrad = asmlib.GetRadiusRatioPly(oPly, stTrace.HitPos, 1) + local plyrad = asmlib.CacheRadiusPly(oPly, stTrace.HitPos, 1) if(trEnt and trEnt:IsValid() and asmlib.CheckButtonPly(oPly,IN_SPEED)) then if(asmlib.IsOther(trEnt)) then return end local igntyp = self:GetIgnoreType() - local stSpawn = asmlib.GetEntitySpawn(trEnt,rotpivt,rotpivh,model,igntyp,trorang, + local stSpawn = asmlib.GetEntitySpawn(oPly,trEnt,rotpivt,rotpivh,model,igntyp,trorang, nextx,nexty,nextz,nextpic,nextyaw,nextrol) if(not stSpawn) then return end local Tp = trEnt:GetPos():ToScreen() @@ -714,7 +715,7 @@ function TOOL:DrawHUD() else local vPos = stTrace.HitPos local aAng = asmlib.GetNormalAngle(oPly, stTrace) - local stSpawn = asmlib.GetNormalSpawn(vPos,aAng,model,rotpivh,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) + local stSpawn = asmlib.GetNormalSpawn(oPly,vPos,aAng,model,rotpivh,trorang,nextx,nexty,nextz,nextpic,nextyaw,nextrol) if(not stSpawn) then return false end local Op = self:DrawUCS(hudMonitor, stSpawn.OPos, stSpawn.F:AngleEx(stSpawn.U), plyrad, "y", true) if(not spnflat) then @@ -763,7 +764,7 @@ function TOOL:DrawToolScreen(w, h) scrTool:SetTextEdge(0,0) local anInfo, anEnt = self:GetAnchor() local tInfo = stringExplode(gsSymRev,anInfo) - local stTrace = asmlib.GetTracePly(LocalPlayer()) + local stTrace = asmlib.CacheTracePly(LocalPlayer()) if(not stTrace) then scrTool:DrawText("Trace status: Invalid","r","SURF",{"Trebuchet24"}) scrTool:DrawTextAdd(" ["..(tInfo[1] or gsNoID).."]","an")