local StartTime = SysTime() if SERVER then AddCSLuaFile("includes/circles/circles.lua") end local function FileIsEmpty( filename ) if file.Size( filename, "LUA" ) <= 1 then -- this is suspicous local data = file.Read( filename, "LUA" ) if data and string.len( data ) <= 1 then -- confirm its empty print("[LVS] - refusing to load '"..filename.."'! File is Empty!" ) return true end end return false end for _, filename in pairs( file.Find("lvs_framework/autorun/*.lua", "LUA") ) do if FileIsEmpty( "lvs_framework/autorun/"..filename ) then continue end if string.StartWith( filename, "sv_") then -- sv_ prefix only load serverside if SERVER then include("lvs_framework/autorun/"..filename) end continue end if string.StartWith( filename, "cl_") then -- cl_ prefix only load clientside if SERVER then AddCSLuaFile("lvs_framework/autorun/"..filename) else include("lvs_framework/autorun/"..filename) end continue end -- everything else is shared if SERVER then AddCSLuaFile("lvs_framework/autorun/"..filename) end include("lvs_framework/autorun/"..filename) end hook.Run( "LVS:Initialize" ) print("[LVS] - initialized ["..math.Round((SysTime() - StartTime) * 1000,2).."ms]") if CLIENT then hook.Add( "InitPostEntity", "!!!lvscheckupdates", function() timer.Simple(20, function() LVS.CheckUpdates() local convar = GetConVar( "no_error_hitboxes" ) if not convar then return end convar:SetBool( false ) end) end ) return end resource.AddWorkshop("2912816023") local ValveWierdBlastDamageClass = { ["npc_strider"] = true, -- takes 70 damage for each blast damage as constant value ... ["npc_combinegunship"] = true, -- takes 44 damage as constant value ... ["func_breakable_surf"] = true, -- this entity dont care about anything that isnt a trace attack or blast damage } function LVS:BlastDamage( pos, forward, attacker, inflictor, damage, damagetype, radius, force ) local dmginfo = DamageInfo() dmginfo:SetAttacker( attacker ) dmginfo:SetInflictor( inflictor ) dmginfo:SetDamage( damage ) dmginfo:SetDamageType( damagetype == DMG_BLAST and DMG_SONIC or damagetype ) if damagetype ~= DMG_BLAST then dmginfo:SetDamagePosition( pos ) dmginfo:SetDamageForce( forward * force ) util.BlastDamageInfo( dmginfo, pos, radius ) return end util.BlastDamageInfo( dmginfo, pos, radius ) local FragmentAngle = 10 local NumFragments = 16 local NumFragmentsMissed = 0 local RegisteredHits = {} local trace = util.TraceLine( { start = pos, endpos = pos - forward * radius, filter = { attacker, inflictor }, } ) local startpos = trace.HitPos for i = 1, NumFragments do local ang = forward:Angle() + Angle( math.random(-FragmentAngle,FragmentAngle), math.random(-FragmentAngle,FragmentAngle), 0 ) local dir = ang:Forward() local endpos = pos + dir * radius local trace = util.TraceLine( { start = startpos, endpos = endpos, filter = { attacker, inflictor }, } ) debugoverlay.Line( startpos, trace.HitPos, 10, Color( 255, 0, 0, 255 ), true ) if not trace.Hit then NumFragmentsMissed = NumFragmentsMissed + 1 continue end if not IsValid( trace.Entity ) then continue end if not RegisteredHits[ trace.Entity ] then RegisteredHits[ trace.Entity ] = {} end table.insert( RegisteredHits[ trace.Entity ], { origin = trace.HitPos, force = forward * force, } ) end local Hull = Vector(10,10,10) for _, ent in ipairs( ents.FindInSphere( pos, radius ) ) do if not ent.LVS or ent == inflictor or ent == attacker then continue end local trace = util.TraceHull( { start = pos, endpos = ent:LocalToWorld( ent:OBBCenter() ), mins = -Hull, maxs = Hull, whitelist = true, ignoreworld = true, filter = ent, } ) debugoverlay.Line( pos, trace.HitPos, 10, Color( 255, 0, 0, 255 ), true ) NumFragments = NumFragments + 1 if not RegisteredHits[ ent ] then RegisteredHits[ ent ] = {} end table.insert( RegisteredHits[ ent ], { origin = trace.HitPos, force = forward * force, } ) end if NumFragmentsMissed == NumFragments then return end local DamageBoost = NumFragments / ( NumFragments - NumFragmentsMissed ) for ent, data in pairs( RegisteredHits ) do local NumHits = #data local AverageOrigin = vector_origin local AverageForce = vector_origin for _, HitData in pairs( data ) do AverageOrigin = AverageOrigin + HitData.origin AverageForce = AverageForce + HitData.force end AverageOrigin = AverageOrigin / NumHits AverageForce = AverageForce / NumHits local TotalDamage = ( ( NumHits * DamageBoost ) / NumFragments ) * damage --debugoverlay.Cross( AverageOrigin, 50, 10, Color( 255, 0, 255 ) ) -- hack if ValveWierdBlastDamageClass[ ent:GetClass() ] then util.BlastDamage( inflictor, attacker, pos, radius, damage ) continue end local dmginfo = DamageInfo() dmginfo:SetAttacker( attacker ) dmginfo:SetInflictor( inflictor ) dmginfo:SetDamage( TotalDamage ) dmginfo:SetDamageForce( AverageForce ) dmginfo:SetDamagePosition( AverageOrigin ) dmginfo:SetDamageType( DMG_BLAST ) ent:TakeDamageInfo( dmginfo ) end end function LVS:FixVelocity() local tbl = physenv.GetPerformanceSettings() if tbl.MaxVelocity < 4000 then local OldVel = tbl.MaxVelocity tbl.MaxVelocity = 4000 physenv.SetPerformanceSettings(tbl) print("[LVS] Low MaxVelocity detected! Increasing! "..OldVel.." => 4000") end if tbl.MaxAngularVelocity < 7272 then local OldAngVel = tbl.MaxAngularVelocity tbl.MaxAngularVelocity = 7272 physenv.SetPerformanceSettings(tbl) print("[LVS] Low MaxAngularVelocity detected! Increasing! "..OldAngVel.." => 7272") end end hook.Add( "InitPostEntity", "!!!lvscheckupdates", function() timer.Simple(20, function() LVS.CheckUpdates() end) end )