Files
2026-03-30 10:39:52 +03:00

144 lines
5.3 KiB
Lua

if game.SinglePlayer() then return end
-----------------------------------------------------------------------=#
if SERVER then
util.AddNetworkString("MultiplayerSoundFix_PlaySound")
local ENT = FindMetaTable("Entity")
if !MPSNDFIX_SOUND_PLAY then MPSNDFIX_SOUND_PLAY = sound.Play end
if !MPSNDFIX_EMITSOUND then MPSNDFIX_EMITSOUND = ENT.EmitSound end
-----------------------------------------------------------------------=#
timer.Create("MPSOUNDFIX_RESET_PLY_NET_MSG_COUNT", 1, 0, function()
for _, ply in ipairs(player.GetAll()) do
ply.MPSNDFIX_NETMSGS = 0
end
end)
-----------------------------------------------------------------------=#
-----------------------------------------------------------------------=#
local function posObscured( pos1, pos2 )
return util.TraceLine({
start = pos1,
endpos = pos2,
mask = MASK_NPCWORLDSTATIC,
}).Hit
end
-----------------------------------------------------------------------=#
-----------------------------------------------------------------------=#
local function sound_Net( name, pos, lvl, pitch, vol )
if lvl < 100 then return end
for _, ply in ipairs(player.GetAll()) do
if ply.MPSNDFIX_NETMSGS and ply.MPSNDFIX_NETMSGS >= 10 then continue end
local dist = ply:GetPos():DistToSqr(pos)
if dist < 1970^2 then continue end
if dist > 8000^2 && posObscured( ply:WorldSpaceCenter(), pos ) then continue end
net.Start("MultiplayerSoundFix_PlaySound")
net.WriteString(name)
net.WriteVector(pos)
net.WriteUInt(lvl, 10)
net.WriteUInt(pitch, 9)
net.WriteFloat(vol)
net.Send(ply)
ply.MPSNDFIX_NETMSGS = ply.MPSNDFIX_NETMSGS + 1
end
end
-----------------------------------------------------------------------=#
-----------------------------------------------------------------------=#
function sound:Play( pos, lvl, pitch, vol )
sound_Net( self, pos or Vector(), lvl or 100, pitch or 100, vol or 1 )
MPSNDFIX_SOUND_PLAY( self, pos, lvl, pitch, vol )
end
-----------------------------------------------------------------------=#
-----------------------------------------------------------------------=#
function ENT:EmitSound( name, lvl, pitch, vol, ... )
if !self.GetClass or self:GetClass() == "gmod_tool" then return end -- Weird entities that we just skip
sound_Net( name, self:WorldSpaceCenter(), lvl or 100, pitch or 100, vol or 1 )
MPSNDFIX_EMITSOUND( self, name, lvl, pitch, vol, ... )
end
-----------------------------------------------------------------------=#
end
-----------------------------------------------------------------------=#
if CLIENT then
net.Receive("MultiplayerSoundFix_PlaySound", function()
local name = net.ReadString()
local pos = net.ReadVector()
local lvl = net.ReadUInt(10)
local pitch = net.ReadUInt(9)
local vol = net.ReadFloat()
sound.Play(name, pos, lvl, pitch, vol)
end)
end
--PENETRATION-----------------------------------------------------------=#
local matEasyPen = {
[MAT_GLASS] = 0,
[MAT_WOOD] = 1,
[MAT_PLASTIC] = 1,
}
local function Penetration(ent, data)
if IsValid(ent) then
if ent.CurrentPenetrationPower >= 0 then
data.Damage = data.Damage/1.5
data.Callback = function(ent, tr, dmg)
data.Src = tr.HitPos+data.Dir*4
if matEasyPen[tr.MatType] then
ent.CurrentPenetrationPower = ent.CurrentPenetrationPower - matEasyPen[tr.MatType]
else
ent.CurrentPenetrationPower = ent.CurrentPenetrationPower - 2
end
if tr.Entity and (tr.Entity:IsPlayer() or tr.Entity:IsNPC()) then
ent.CurrentPenetrationPower = ent.CurrentPenetrationPower - 1
data.IgnoreEntity = tr.Entity
end
if ent.CurrentPenetrationPower >= 0 and not tr.HitSky then
Penetration(ent, data)
end
end
ent:FireBullets(data)
end
end
end
hook.Add("EntityFireBullets", "TDM_Penetration", function(ent, data)
if ent.PenetrationPower and ent.PenetrationPower > 0 then
if ent.CurrentPenetrationPower == ent.PenetrationPower then
data.Callback = function(ent, tr, dmg)
if tr.Entity and (tr.Entity:IsPlayer() or tr.Entity:IsNPC()) then
ent.CurrentPenetrationPower = ent.CurrentPenetrationPower - 1
data.IgnoreEntity = tr.Entity
end
if matEasyPen[tr.MatType] then
ent.CurrentPenetrationPower = ent.CurrentPenetrationPower - matEasyPen[tr.MatType]
else
ent.CurrentPenetrationPower = ent.CurrentPenetrationPower - 2
end
if ent.CurrentPenetrationPower >= 0 and not tr.HitSky then
data.Src = tr.HitPos+data.Dir*4
Penetration(ent, data)
end
end
return true
end
end
end)