Reduce the calls to util.IsValidModel() and use cached file checks (#55)

Changed: Use `IsModel` instead of pre-caching every frame
Changed: Use @SligWolf model validation
Added: Extra ghost entity piece before spawn
Added: Spawn flag for the valid model check
Replaced: Some `fileExists` calls on models with `IsModel`
Removed: Multiple checks and replaced them with `IsModel`
Removed: Pre-cache validation check on ghosts to be rendered correctly
Updated: Model check for SV/CL including deep model validation on spawn @Grocel
This commit is contained in:
Deyan Dobromirov 2024-03-24 17:32:02 +02:00 committed by GitHub
parent 3c39afa095
commit f42bdcfde3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 92 additions and 67 deletions

View File

@ -38,7 +38,6 @@ local tableRemove = table and table.remove
local tableEmpty = table and table.Empty
local tableInsert = table and table.insert
local utilAddNetworkString = util and util.AddNetworkString
local utilIsValidModel = util and util.IsValidModel
local vguiCreate = vgui and vgui.Create
local fileExists = file and file.Exists
local fileFind = file and file.Find
@ -85,7 +84,7 @@ local asmlib = trackasmlib; if(not asmlib) then -- Module present
------------ CONFIGURE ASMLIB ------------
asmlib.InitBase("track","assembly")
asmlib.SetOpVar("TOOL_VERSION","8.740")
asmlib.SetOpVar("TOOL_VERSION","8.741")
asmlib.SetIndexes("V" ,1,2,3)
asmlib.SetIndexes("A" ,1,2,3)
asmlib.SetIndexes("WV",1,2,3)
@ -683,7 +682,7 @@ if(CLIENT) then
local model = actTool:GetModel()
local ghcnt = actTool:GetGhostsDepth()
local atGho = asmlib.GetOpVar("ARRAY_GHOST")
if(utilIsValidModel(model)) then
if(asmlib.IsModel(model)) then
if(not (asmlib.HasGhosts() and ghcnt == atGho.Size and atGho.Slot == model)) then
if(not asmlib.MakeGhosts(ghcnt, model)) then
asmlib.LogInstance("Ghosting fail",sLog); return nil end
@ -1259,7 +1258,7 @@ if(CLIENT) then
actSpawn = asmlib.GetEntitySpawn(oPly,tgE,oTr.HitPos,trRec.Slot,trID,activrad,
spnflat,igntype, nextx, nexty, nextz, nextpic, nextyaw, nextrol)
if(actSpawn) then -- When spawn data is availabe draw adviser
if(utilIsValidModel(trRec.Slot)) then -- The model has valid pre-cache
if(asmlib.IsModel(trRec.Slot)) then -- The model has valid pre-cache
if(ghostcnt > 0) then -- The ghosting is enabled
if(not (hasghost and atGhosts.Size == 1 and trRec.Slot == atGhosts.Slot)) then
if(not asmlib.MakeGhosts(1, trRec.Slot)) then

View File

@ -74,6 +74,7 @@ local getmetatable = getmetatable
local setmetatable = setmetatable
local collectgarbage = collectgarbage
local LocalToWorld = LocalToWorld
local IsUselessModel = IsUselessModel
local SafeRemoveEntityDelayed = SafeRemoveEntityDelayed
local osClock = os and os.clock
local osDate = os and os.date
@ -86,6 +87,7 @@ local gameGetWorld = game and game.GetWorld
local utilTraceLine = util and util.TraceLine
local utilIsInWorld = util and util.IsInWorld
local utilIsValidModel = util and util.IsValidModel
local utilPrecacheModel = util and util.PrecacheModel
local utilGetPlayerTrace = util and util.GetPlayerTrace
local entsCreate = ents and ents.Create
local entsCreateClientProp = ents and ents.CreateClientProp
@ -164,13 +166,14 @@ local constraintCanConstrain = constraint and constraint.CanConstrain
local constraintAdvBallsocket = constraint and constraint.AdvBallsocket
local duplicatorStoreEntityModifier = duplicator and duplicator.StoreEntityModifier
---------------- CASHES SPACE --------------------
---------------- CACHES SPACE --------------------
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 = {} -- Used to allocate personal space for players
local libQTable = {} -- Used to allocate SQL table builder objects
local libModel = {} -- Used to store the the valid models status
module("trackasmlib")
@ -287,6 +290,41 @@ function IsOther(oEnt)
return false
end
-- Uses custom model check to remove the pre-caching overhead
libModel.Skip = {} -- Gerneral disabled models for spawning
libModel.Skip[""] = true -- Empty string
libModel.Skip["models/error.mdl"] = true
libModel.File = {} -- When the file is available
libModel.Deep = {} -- When the model is spawned
function IsModel(sModel, bDeep)
if(not IsHere(sModel)) then
LogInstance("Missing "..GetReport(sModel)); return false end
if(not IsString(sModel)) then
LogInstance("Mismatch "..GetReport(sModel)); return false end
if(libModel.Skip[sModel]) then
LogInstance("Skipped "..GetReport(sModel)); return false end
local vDeep = libModel.Deep[sModel] -- Read model validation status
if(SERVER and bDeep and IsHere(vDeep)) then return vDeep end -- Ganna spawn
local vFile = libModel.File[sModel] -- File current status
if(IsHere(vFile)) then -- File validation status is present
if(not vFile) then -- File is validated as invalid path
LogInstance("Invalid file "..GetReport(sModel)); return false end
else -- File validation status update
if(IsUselessModel(sModel)) then libModel.File[sModel] = false
LogInstance("File useless "..GetReport(sModel)); return false end
if(not fileExists(sModel, "GAME")) then libModel.File[sModel] = false
LogInstance("File missing "..GetReport(sModel)); return false end
vFile = true; libModel.File[sModel] = vFile -- The file validated
LogInstance("File >> "..GetReport3(vDeep, vFile, sModel))
end -- At this point file path is valid. Have to validate model
if(CLIENT or not bDeep) then return true else -- File is validated
utilPrecacheModel(sModel) vDeep = utilIsValidModel(sModel)
libModel.Deep[sModel] = vDeep; -- Store deep validation
LogInstance("Deep >> "..GetReport3(vDeep, vFile, sModel))
return vDeep -- Gonna spawn
end
end
-- Reports the type and actual value
function GetReport(vA) local sR = GetOpVar("FORM_VREPORT2")
return (sR and sR:format(type(vA), tostring(vA)) or "")
@ -409,7 +447,7 @@ end
------------------ LOGS ------------------------
local function GetLogID()
function GetLogID()
local nNum, fMax = GetOpVar("LOG_CURLOGS"), GetOpVar("LOG_FORMLID")
if(not (nNum and fMax)) then return "" end; return fMax:format(nNum)
end
@ -418,7 +456,7 @@ end
sMsg > Message being displayed
bCon > Force output in the console
]]
local function Log(vMsg, bCon)
function Log(vMsg, bCon)
local iMax = GetOpVar("LOG_MAXLOGS")
if(iMax <= 0) then return end
local sMsg = tostring(vMsg)
@ -441,7 +479,7 @@ end
sKey > SKIP / ONLY
Return: setting exist, message found
]]
local function IsLogFound(sMsg, sKey)
function IsLogFound(sMsg, sKey)
local sMsg = tostring(sMsg or "")
local sKey = tostring(sKey or "")
if(IsBlank(sKey)) then return nil end
@ -490,7 +528,7 @@ function LogInstance(vMsg, vSrc, bCon, iDbg, tDbg)
Log(sInst.." > "..sToolMD.." ["..sMoDB.."]"..sDbg.." "..sData, bCon)
end
local function LogCeption(tT,sS,tP)
function LogCeption(tT,sS,tP)
local vK, sS = "", tostring(sS or "Data")
if(not IsTable(tT)) then
LogInstance("{"..type(tT).."}["..sS.."] = <"..tostring(tT)..">",tP); return nil end
@ -1614,7 +1652,7 @@ function DoAction(sKey, ...)
return pcall(tAct.Act, tAct.Dat, ...)
end
local function AddLineListView(pnListView,frUsed,ivNdex)
function AddLineListView(pnListView,frUsed,ivNdex)
if(not IsHere(pnListView)) then
LogInstance("Missing panel"); return false end
if(not IsValid(pnListView)) then
@ -1742,7 +1780,7 @@ function SetDirectoryNode(pnBase, sName, sModel)
return pNode
end
local function PushSortValues(tTable,snCnt,nsValue,tData)
function PushSortValues(tTable,snCnt,nsValue,tData)
local iCnt, iInd = mathFloor(tonumber(snCnt) or 0), 1
if(not (tTable and IsTable(tTable) and (iCnt > 0))) then return 0 end
if(not tTable[iInd]) then
@ -2092,7 +2130,8 @@ end
* vPos > Custom position for the placeholder ( zero if none )
* aAng > Custom angles for the placeholder ( zero if none )
]]
local function MakeEntityNone(sModel, vPos, aAng) local eNone
function MakeEntityNone(sModel, vPos, aAng) local eNone
if(not IsModel(sModel)) then return nil end
if(SERVER) then eNone = entsCreate(GetOpVar("ENTITY_DEFCLASS"))
elseif(CLIENT) then eNone = entsCreateClientProp(sModel) end
if(not (eNone and eNone:IsValid())) then
@ -2190,10 +2229,8 @@ function DecodePOA(sStr)
end
function GetTransformOA(sModel, sKey)
if(not IsString(sModel)) then
if(not IsModel(sModel)) then
LogInstance("Model mismatch "..GetReport2(sModel, sKey)); return nil end
if(not fileExists(sModel, "GAME")) then
LogInstance("Model missing "..GetReport2(sModel, sKey)); return nil end
if(not IsString(sKey)) then
LogInstance("Key mismatch "..GetReport2(sModel, sKey)); return nil end
local ePiece = GetOpVar("ENTITY_TRANSFORMPOA")
@ -2274,7 +2311,7 @@ function RegisterPOA(stData, ivID, sP, sO, sA)
return tOffs
end
local function QuickSort(tD, iL, iH)
function QuickSort(tD, iL, iH)
if(not (iL and iH and (iL > 0) and (iL < iH))) then
LogInstance("Data dimensions mismatch"); return nil end
local iM = mathRandom(iH-iL-1)+iL-1
@ -2362,7 +2399,7 @@ end
------------------------- PLAYER -----------------------------------
local function GetPlayerSpot(pPly)
function GetPlayerSpot(pPly)
if(not IsPlayer(pPly)) then
LogInstance("Invalid "..GetReport(pPly)); return nil end
local stSpot = libPlayer[pPly]; if(not IsHere(stSpot)) then
@ -2371,7 +2408,7 @@ local function GetPlayerSpot(pPly)
end; return stSpot
end
local function SetCacheSpawn(stData)
function SetCacheSpawn(stData)
local stSpawn, iD = GetOpVar("STRUCT_SPAWN"), 1
while(stSpawn[iD]) do local tSec, iK = stSpawn[iD], 1
while(tSec[iK]) do local def = tSec[iK]
@ -2528,7 +2565,7 @@ end
-------------------------- BUILDSQL ------------------------------
local function CacheStmt(sHash,sStmt,...)
function CacheStmt(sHash,sStmt,...)
if(not IsHere(sHash)) then LogInstance("Missing hash"); return nil end
local sHash, tStore = tostring(sHash), GetOpVar("QUERY_STORE")
if(not IsHere(tStore)) then LogInstance("Missing storage"); return nil end
@ -3060,13 +3097,7 @@ end
--------------------------- PIECE QUERY -----------------------------
function CacheQueryPiece(sModel)
if(not IsHere(sModel)) then
LogInstance("Model does not exist"); return nil end
if(not IsString(sModel)) then
LogInstance("Model mismatch "..GetReport(sModel)); return nil end
if(IsBlank(sModel)) then
LogInstance("Model empty string"); return nil end
if(not utilIsValidModel(sModel)) then
if(not IsModel(sModel)) then
LogInstance("Model invalid <"..sModel..">"); return nil end
local makTab = GetBuilderNick("PIECES"); if(not IsHere(makTab)) then
LogInstance("Missing table builder"); return nil end
@ -3084,7 +3115,7 @@ function CacheQueryPiece(sModel)
local sMoDB = GetOpVar("MODE_DATABASE")
if(sMoDB == "SQL") then
local qModel = makTab:Match(sModel,1,true)
LogInstance("Model >> Pool <"..stringGetFileName(sModel)..">")
LogInstance("Save >> "..GetReport(sModel))
tCache[sModel] = {}; stData = tCache[sModel]; stData.Size = 0
local Q = CacheStmt(qsKey:format(sFunc, ""), nil, qModel)
if(not Q) then
@ -3097,7 +3128,7 @@ function CacheQueryPiece(sModel)
LogInstance("SQL exec error <"..sqlLastError()..">"); return nil end
if(not IsHere(qData) or IsEmpty(qData)) then
LogInstance("No data found <"..Q..">"); return nil end
local iCnt = 1; stData.Slot, stData.Size = sModel, 0
local iCnt = 1; stData.Slot, stData.Size = sModel, 0
stData.Type = qData[iCnt][makTab:GetColumnName(2)]
stData.Name = qData[iCnt][makTab:GetColumnName(3)]
stData.Unit = qData[iCnt][makTab:GetColumnName(8)]
@ -3115,13 +3146,7 @@ function CacheQueryPiece(sModel)
end
function CacheQueryAdditions(sModel)
if(not IsHere(sModel)) then
LogInstance("Model does not exist"); return nil end
if(not IsString(sModel)) then
LogInstance("Model mismatch "..GetReport(sModel)); return nil end
if(IsBlank(sModel)) then
LogInstance("Model empty string"); return nil end
if(not utilIsValidModel(sModel)) then
if(not IsModel(sModel)) then
LogInstance("Model invalid "..GetReport(sModel)); return nil end
local makTab = GetBuilderNick("ADDITIONS"); if(not IsHere(makTab)) then
LogInstance("Missing table builder"); return nil end
@ -3171,7 +3196,7 @@ end
* makTab > Table maker object
* sFunc > Export requestor ( CacheQueryPanel )
]]
local function ExportPanelDB(stPanel, bExp, makTab, sFunc)
function ExportPanelDB(stPanel, bExp, makTab, sFunc)
if(bExp) then
local sMiss = GetOpVar("MISS_NOAV")
local sExpo = GetOpVar("DIRPATH_EXP")
@ -3189,7 +3214,7 @@ local function ExportPanelDB(stPanel, bExp, makTab, sFunc)
local sN = vPanel[makTab:GetColumnName(3)]
if(not cT or cT ~= sT) then -- Category has been changed
F:Write("# Categorize [ "..sMoDB.." ]("..sT.."): "..tostring(WorkshopID(sT) or sMiss))
F:Write("\n"); cT = sT -- Cashe category name
F:Write("\n"); cT = sT -- Cache category name
end -- Otherwise just wite down the piece active point
F:Write("\""..sM.."\""..symSep.."\""..sT.."\""..symSep.."\""..sN.."\"")
F:Write("\n"); iCnt = iCnt + 1
@ -3789,7 +3814,7 @@ end
* makTab > Reference to additions table builder
* qList > The list to insert the found additions
]]--
local function SetAdditionsAR(sModel, makTab, qList)
function SetAdditionsAR(sModel, makTab, qList)
if(not IsHere(makTab)) then return end
local defTab = makTab:GetDefinition()
if(not IsHere(defTab)) then LogInstance("Table definition missing") end
@ -3835,7 +3860,7 @@ local function SetAdditionsAR(sModel, makTab, qList)
for iD = 1, #qData do qList[iE + iD] = qData[iD] end
end
local function ExportPiecesAR(fF,qData,sName,sInd,qList)
function ExportPiecesAR(fF,qData,sName,sInd,qList)
local dbNull = GetOpVar("MISS_NOSQL")
local keyBld, makAdd = GetOpVar("KEYQ_BUILDER")
local makTab = qData[keyBld]; if(not IsHere(makTab)) then
@ -4019,7 +4044,7 @@ end
----------------------------- SNAPPING ------------------------------
local function GetSurfaceAngle(oPly, vNorm)
function GetSurfaceAngle(oPly, vNorm)
local vF = oPly:GetAimVector()
local vR = vF:Cross(vNorm); vF:Set(vNorm:Cross(vR))
return vF:AngleEx(vNorm)
@ -4261,7 +4286,7 @@ end
* vR3 = {g h i}
* Returns a number: The 3x3 determinant value
]]--
local function DeterminantVector(vR1, vR2, vR3)
function DeterminantVector(vR1, vR2, vR3)
local a, b, c = vR1[cvX], vR1[cvY], vR1[cvZ]
local d, e, f = vR2[cvX], vR2[cvY], vR2[cvZ]
local g, h, i = vR3[cvX], vR3[cvY], vR3[cvZ]
@ -4289,7 +4314,7 @@ end
* x2 > Pillar intersection projection for second ray
* xx > Actual calculated pillar intersection point
]]--
local function IntersectRay(vO1, vD1, vO2, vD2)
function IntersectRay(vO1, vD1, vO2, vD2)
if(vD1:LengthSqr() == 0) then
LogInstance("First ray undefined"); return nil end
if(vD2:LengthSqr() == 0) then
@ -4307,7 +4332,7 @@ local function IntersectRay(vO1, vD1, vO2, vD2)
return f1, f2, x1, x2, xx
end
local function IntersectRayParallel(vO1, vD1, vO2, vD2)
function IntersectRayParallel(vO1, vD1, vO2, vD2)
if(vD1:LengthSqr() == 0) then
LogInstance("First ray undefined"); return nil end
if(vD2:LengthSqr() == 0) then
@ -4330,7 +4355,7 @@ function IntersectRayPair(vO1, vD1, vO2, vD2)
end; return f1, f2, x1, x2, xx
end
local function IntersectRayUpdate(stRay)
function IntersectRayUpdate(stRay)
if(not IsHere(stRay)) then
LogInstance("Ray invalid"); return nil end
local ryEnt = stRay.Ent
@ -4404,7 +4429,7 @@ function IntersectRayClear(oPly, sKey)
end
--[[
* This function intersects two already cashed rays
* This function intersects two already cached rays
* Used for generating
* sKey1 > First ray identifier
* sKey2 > Second ray identifier
@ -4464,9 +4489,7 @@ function AttachAdditions(ePiece)
LogInstance("ents.Create("..arRec[makTab:GetColumnName(3)]..")")
if(exItem and exItem:IsValid()) then
local adMod = tostring(arRec[makTab:GetColumnName(2)])
if(not fileExists(adMod, "GAME")) then
LogInstance("Missing attachment file "..adMod); return false end
if(not utilIsValidModel(adMod)) then
if(not IsModel(adMod, true)) then
LogInstance("Invalid attachment model "..adMod); return false end
exItem:SetModel(adMod) LogInstance("ENT:SetModel("..adMod..")")
local ofPos = arRec[makTab:GetColumnName(5)]; if(not IsString(ofPos)) then
@ -4517,7 +4540,7 @@ function AttachAdditions(ePiece)
end; LogInstance("Success"); return true
end
local function GetEntityOrTrace(oEnt)
function GetEntityOrTrace(oEnt)
if(oEnt and oEnt:IsValid()) then return oEnt end
local oPly = LocalPlayer(); if(not IsPlayer(oPly)) then
LogInstance("Player mismatch "..GetReport(oPly)); return nil end
@ -4632,6 +4655,8 @@ function MakePiece(pPly,sModel,vPos,aAng,nMass,sBgSkIDs,clColor,sMode)
LogInstance("Track limit reached"); return nil end
if(not pPly:CheckLimit("props")) then -- Check the props limit
LogInstance("Prop limit reached"); return nil end
if(not IsModel(sModel, true)) then
LogInstance("Model invalid"); return nil end
local stData = CacheQueryPiece(sModel) if(not IsHere(stData)) then
LogInstance("Record missing for <"..sModel..">"); return nil end
local aAng = Angle(aAng or GetOpVar("ANG_ZERO"))
@ -4771,7 +4796,7 @@ function ApplyPhysicalAnchor(ePiece,eBase,bWe,bNc,bNw,nFm)
LogInstance("Success"); return true, cnW, cnN, cnG
end
local function GetConstraintInfo(tC, iD)
function GetConstraintInfo(tC, iD)
local iD = mathFloor(tonumber(iD) or 0)
if(IsHere(tC) and IsTable(tC) and iD > 0) then
local eO, tO, iO = tC["Ent"..iD]
@ -4795,7 +4820,7 @@ local function GetConstraintInfo(tC, iD)
else LogInstance("Primary data missing "..GetReport(tC.Constraint)) end
end
local function GetRecordOver(oEnt, tI, vD)
function GetRecordOver(oEnt, tI, vD)
if(not (oEnt and oEnt:IsValid())) then return nil end
local tS, iD = {}, tonumber(vD)
tS.Ovr, tS.Ent = false, oEnt
@ -4807,11 +4832,11 @@ local function GetRecordOver(oEnt, tI, vD)
return tS -- Return the created item
end
local function SetRecordOver(tD, tS)
function SetRecordOver(tD, tS)
tD.Ovr, tD.ID, tD.Ent = true, tS.ID, tS.Ent
end
local function GetConstraintsEnt(oEnt)
function GetConstraintsEnt(oEnt)
if(not (oEnt and oEnt:IsValid())) then return nil end
local tO = {}; tO.Link = {}
tO.Base = GetRecordOver(oEnt)
@ -5017,7 +5042,7 @@ end
* color alpha channel have draw override. This is run
* for all the ghosted props to draw all of them correctly
]]
local function BlendGhost(self)
function BlendGhost(self)
local mar = self.marginRender
local num = renderGetBlend()
renderSetBlend(mar)
@ -5032,7 +5057,8 @@ end
* aAng > Angles for the entity, otherwise zero is used
* It must have been our imagination.
]]
local function MakeEntityGhost(sModel, vPos, aAng)
function MakeEntityGhost(sModel, vPos, aAng)
if(not IsModel(sModel)) then return nil end
local cPal = GetContainer("COLORS_LIST")
local eGho = entsCreateClientProp(sModel)
if(not (eGho and eGho:IsValid())) then eGho = nil
@ -5130,7 +5156,7 @@ end
* nA > Parametric constant curve factor [0 ; 1]
* Returns the value of the tangent
]]
local function GetCatmullRomCurveTangent(cS, cE, nT, nA)
function GetCatmullRomCurveTangent(cS, cE, nT, nA)
local nL, nM = cE:Distance(cS), GetOpVar("EPSILON_ZERO")
return ((((nL == 0) and nM or nL) ^ (tonumber(nA) or 0.5)) + nT)
end
@ -5143,7 +5169,7 @@ end
* nA > Parametric constant curve factor [0 ; 1]
* Returns a table containing the generated sequence
]]
local function GetCatmullRomCurveSegment(vP0, vP1, vP2, vP3, nN, nA)
function GetCatmullRomCurveSegment(vP0, vP1, vP2, vP3, nN, nA)
if(not IsVector(vP0)) then
LogInstance("Mismatch[0] "..GetReport(vP0)); return nil end
if(not IsVector(vP1)) then
@ -5177,7 +5203,7 @@ end
* nA > Parametric constant curve factor [0 ; 1]
* Returns a table containing the generated curve including the control points
]]
local function GetCatmullRomCurve(tV, nT, nA, tO)
function GetCatmullRomCurve(tV, nT, nA, tO)
if(not IsTable(tV)) then LogInstance("Vertices mismatch "..GetReport(tV)); return nil end
if(IsEmpty(tV)) then LogInstance("Vertices missing "..GetReport(tV)); return nil end
if(not (tV[1] and tV[2])) then LogInstance("Two vertices needed"); return nil end
@ -5205,7 +5231,7 @@ end
* nA > Parametric constant curve factor [0 ; 1]
* Returns a table containing the generated curve including the control points
]]
local function GetCatmullRomCurveDupe(tV, nT, nA, tO)
function GetCatmullRomCurveDupe(tV, nT, nA, tO)
if(not IsTable(tV)) then LogInstance("Vertices mismatch "..GetReport(tV)); return nil end
if(IsEmpty(tV)) then LogInstance("Vertices missing "..GetReport(tV)); return nil end
if(not (tV[1] and tV[2])) then LogInstance("Two vertices are needed"); return nil end
@ -5250,7 +5276,7 @@ end
* nR > Sphere radius number
* Returns the vector position of intersection
]]
local function IntersectLineSphere(vS, vE, vC, nR)
function IntersectLineSphere(vS, vE, vC, nR)
local nE = GetOpVar("EPSILON_ZERO")
local vD = Vector(vE); vD:Sub(vS)
local nA = vD:LengthSqr(); if(nA < nE) then
@ -5272,7 +5298,7 @@ end
* vE > Line end point vector
* Returns boolean if the condition is present
]]
local function IsAmongLine(vO, vS, vE)
function IsAmongLine(vO, vS, vE)
local nE = GetOpVar("EPSILON_ZERO")
local oS = Vector(vO); oS:Sub(vS)
local oE = Vector(vO); oE:Sub(vE)
@ -5295,7 +5321,7 @@ end
* vO > Search sphere location vector
* nD > Search sphere radius
]]
local function UpdateCurveNormUCS(oPly, vvS, vnS, vvE, vnE, vO, nD)
function UpdateCurveNormUCS(oPly, vvS, vnS, vvE, vnE, vO, nD)
if(not IsVector(vvS)) then
LogInstance("Start mismatch "..GetReport(vvS)); return nil end
if(not IsVector(vnS)) then
@ -5410,7 +5436,7 @@ end
* tV > A table of position vector vertices
* Returns the calculated recursive control sample
]]
local function GetBezierCurveVertex(cT, tV)
function GetBezierCurveVertex(cT, tV)
local tD, tP, nD = {}, {}, (#tV - 1)
for iD = 1, nD do
tD[iD] = Vector(tV[iD+1])

View File

@ -24,7 +24,6 @@ local netWriteAngle = net and net.WriteAngle
local netWriteEntity = net and net.WriteEntity
local netWriteVector = net and net.WriteVector
local vguiCreate = vgui and vgui.Create
local utilIsValidModel = util and util.IsValidModel
local stringUpper = string and string.upper
local mathAbs = math and math.abs
local mathMin = math and math.min
@ -34,7 +33,6 @@ local mathClamp = math and math.Clamp
local mathAtan2 = math and math.atan2
local mathRound = math and math.Round
local gameGetWorld = game and game.GetWorld
local fileExists = file and file.Exists
local tableInsert = table and table.insert
local tableRemove = table and table.remove
local tableEmpty = table and table.Empty
@ -1711,6 +1709,7 @@ function TOOL:UpdateGhost(oPly)
end
if(trRec) then
local ePiece = atGho[1]
if(not (ePiece and ePiece:IsValid())) then return end
local spnflat = self:GetSpawnFlat()
local igntype = self:GetIgnoreType()
local stackcnt = self:GetStackCount()
@ -1725,6 +1724,7 @@ function TOOL:UpdateGhost(oPly)
local vTemp, hdOffs = Vector(), asmlib.LocatePOA(stSpawn.HRec, pnextid)
if(not hdOffs) then return end -- Validated existent next point ID
for iNdex = 1, atGho.Size do ePiece = atGho[iNdex]
if(not (ePiece and ePiece:IsValid())) then return end
ePiece:SetPos(stSpawn.SPos); ePiece:SetAngles(stSpawn.SAng); ePiece:SetNoDraw(false)
vTemp:SetUnpacked(hdOffs.P[cvX], hdOffs.P[cvY], hdOffs.P[cvZ])
vTemp:Rotate(stSpawn.SAng); vTemp:Add(ePiece:GetPos())
@ -1773,7 +1773,7 @@ end
function TOOL:Think()
if(not asmlib.IsInit()) then return end
local model = self:GetModel()
if(utilIsValidModel(model)) then
if(asmlib.IsModel(model)) then
local workmode = self:GetWorkingMode()
if(CLIENT) then
local bO = asmlib.IsFlag("old_close_frame", asmlib.IsFlag("new_close_frame"))
@ -2317,7 +2317,7 @@ function TOOL.BuildCPanel(CPanel)
local sMod = vRec[makTab:GetColumnName(1)]
local sTyp = vRec[makTab:GetColumnName(2)]
local sNam = vRec[makTab:GetColumnName(3)]
if(fileExists(sMod, "GAME")) then
if(asmlib.IsModel(sMod)) then
if(not (asmlib.IsBlank(sTyp) or pTypes[sTyp])) then
local pRoot = pTree:AddNode(sTyp) -- No type folder made already
pRoot:SetTooltip(languageGetPhrase("tool."..gsToolNameL..".type"))