All pastes #974412 Raw Edit

Something

public text v1 · immutable
·published 2008-04-06 19:43 UTC
rendered paste body

local Entity = FindMetaTable( "Entity" )
Entity.OldFireBullets = Entity.OldFireBullets or Entity.FireBullets

local toFire = {}
function Entity:FireBullets( bullet )
	local copy = table.Copy( bullet )
	copy.Tracer = 0
	
	toFire[ self ] = toFire[ self ] or {}
	table.insert( toFire[ self ], copy )
end

local function Tick()
	local npcs = ents.FindByClass( "npc_*" )
	
	-- Loop through all bullets to fire.
	for ply, list in pairs( toFire ) do
		if ( #list > 0 ) then
		
			local reset = {}
			local ping = ply:Ping() / 1000
			
			for _, npc in pairs( npcs ) do
				local backTime = CurTime() - ping
				for _, info in ipairs( npc.Position or {} ) do
					if ( info[ 1 ] > backTime ) then
						reset[ npc ] = { npc:GetPos(), npc:GetAngles() }
						npc:SetPos( info[ 2 ] )
						npc:SetAngles( info[ 3 ] )
						break
					end
				end
			end
			
			-- Fire the bullets.
			for i, bullet in pairs( list ) do
				ply:OldFireBullets( bullet )
				list[ i ] = nil
			end
			
			-- Reset the NPCs positions.
			for npc, info in pairs( reset ) do
				npc:SetPos( info[ 1 ] )
				npc:SetAngles( info[ 2 ] )
			end
		end
		
		-- Saves time next tick by not having to loop through any more if there aren't any added.
		toFire[ ply ] = nil
	end			
	
	-- Save the NPCs positions.
	for _, npc in pairs( npcs ) do
		npc.Position = npc.Position or {}
		table.insert( npc.Position, 1, { CurTime(), npc:GetPos(), npc:GetAngles() } )
		npc.Position[ 100 ] = nil -- We only want to store a maximum of 100 entries.
	end
end
hook.Add( "Tick", "NPCLagCompensation.Tick", Tick )