add sborka

This commit is contained in:
2026-03-31 10:27:04 +03:00
commit f5e5f56c84
2345 changed files with 382127 additions and 0 deletions

View File

@@ -0,0 +1,601 @@
AddCSLuaFile()
local ImpSnds = {}
ImpSnds[1] = "sw/bomb/impact_1.wav"
ImpSnds[2] = "sw/bomb/impact_2.wav"
ImpSnds[3] = "sw/bomb/impact_3.wav"
local WtrImpSnds = {}
WtrImpSnds[1] = "sw/bomb/impact_wtr_1.wav"
WtrImpSnds[2] = "sw/bomb/impact_wtr_2.wav"
WtrImpSnds[3] = "sw/bomb/impact_wtr_3.wav"
local DbrSnds = {}
DbrSnds[1] = "sw/bomb/debris_1.wav"
DbrSnds[2] = "sw/bomb/debris_2.wav"
DbrSnds[3] = "sw/bomb/debris_3.wav"
DbrSnds[4] = "sw/bomb/debris_4.wav"
local ExpSnds = {}
ExpSnds[1] = "sw/explosion/exp_tny_1.wav"
ExpSnds[2] = "sw/explosion/exp_tny_2.wav"
ExpSnds[3] = "sw/explosion/exp_tny_3.wav"
local FarExpSnds = {}
FarExpSnds[1] = "sw/explosion/exp_sml_dst_1.wav"
FarExpSnds[2] = "sw/explosion/exp_sml_dst_2.wav"
FarExpSnds[3] = "sw/explosion/exp_sml_dst_3.wav"
FarExpSnds[4] = "sw/explosion/exp_sml_dst_4.wav"
FarExpSnds[5] = "sw/explosion/exp_sml_dst_5.wav"
FarExpSnds[6] = "sw/explosion/exp_sml_dst_6.wav"
FarExpSnds[7] = "sw/explosion/exp_sml_dst_7.wav"
FarExpSnds[8] = "sw/explosion/exp_sml_dst_8.wav"
local DstExpSnds = {}
DstExpSnds[1] = "sw/explosion/exp_sml_far_1.wav"
DstExpSnds[2] = "sw/explosion/exp_sml_far_2.wav"
DstExpSnds[3] = "sw/explosion/exp_sml_far_3.wav"
DstExpSnds[4] = "sw/explosion/exp_sml_far_4.wav"
DstExpSnds[5] = "sw/explosion/exp_sml_far_5.wav"
DstExpSnds[6] = "sw/explosion/exp_sml_far_6.wav"
DstExpSnds[7] = "sw/explosion/exp_sml_far_7.wav"
DstExpSnds[8] = "sw/explosion/exp_sml_far_8.wav"
local WtrExpSnds = {}
WtrExpSnds[1] = "sw/explosion/exp_trp_1.wav"
WtrExpSnds[2] = "sw/explosion/exp_trp_2.wav"
WtrExpSnds[3] = "sw/explosion/exp_trp_3.wav"
--Main info
ENT.Type = "anim"
ENT.Spawnable = false
ENT.AdminSpawnable = false
ENT.AdminOnly = false
ENT.PrintName = "Bomb basescript V3"
ENT.Author = "Shermann Wolf"
ENT.Contact = "shermannwolf@gmail.com"
ENT.Category = "SW Bombs V3"
ENT.Editable = true
ENT.SWBombV3 = true
--Visual
ENT.Model = "models/sw/rus/bombs/ao25m1.mdl"
ENT.Effect = "ins_m203_explosion"
ENT.EffectAir = "ins_m203_explosion"
ENT.EffectWater = "ins_water_explosion"
ENT.Decal = "scorch_25kg"
ENT.AngEffect = true
--Sounds
ENT.ArmSound = "sw/bomb/arm.wav"
ENT.ImpactSound = table.Random(ImpSnds)
ENT.WaterImpactSound = table.Random(WtrImpSnds)
ENT.DebrisSound = table.Random(DbrSnds)
ENT.WhistleSound = "sw/bomb/whistle.wav"
ENT.ExplosionSound = table.Random(ExpSnds)
ENT.FarExplosionSound = table.Random(FarExpSnds)
ENT.DistExplosionSound = table.Random(DstExpSnds)
ENT.WaterExplosionSound = table.Random(WtrExpSnds)
ENT.WaterFarExplosionSound = nil
--Physics
ENT.TraceLength = 500
ENT.ImpactSpeed = 100
ENT.ImpactDepth = 25
ENT.Mass = 0
ENT.Durability = 10
ENT.DetonateHeight = 0
--Explosion
ENT.DamageType = DMG_BURN
ENT.ExplosionDamage = 10000
ENT.ExplosionRadius = 300
ENT.BlastRadius = 450
ENT.FragDamage = 25
ENT.FragRadius = 600
ENT.FragCount = 100
--Guidance
ENT.DiveHeight = 1000
ENT.Agility = 100
ENT.HaveGuidance = false
ENT.GuidanceActive = false
ENT.LaserGuided = false
ENT.LaserCode = "view"
function ENT:SetupDataTables()
self:NetworkVar("Bool",0,"Timed", {KeyName = "timed", Edit = { type = "Boolean", category = "Fuze"}})
self:NetworkVar("Int",1,"Timer", { KeyName = "timer", Edit = { type = "Int", min = 0, max = 120, category = "Fuze"} } )
self:NetworkVar("Bool",2,"AirDetonate", {KeyName = "airdetonate", Edit = { type = "Boolean", category = "Fuze"}})
self:NetworkVar("Int",3,"DetonateHeight", { KeyName = "detonateheight", Edit = { type = "Int", min = 0, max = 2000, category = "Fuze"} } )
end
if SERVER then
local angle_reg = Angle(0,0,0)
local angle_dif = Angle(-90,0,0)
local Normal = Vector(1,1,0)
local Normal2 = Vector(0.1,1,1)
local trlength = Vector(0,0,9000)
local angle_zero = Angle()
local angle_1 = Angle(-90,0,0)
function ENT:SpawnFunction( ply, tr, ClassName )
if not tr.Hit then return end
local ent = ents.Create( ClassName )
ent:SetPos( tr.HitPos + tr.HitNormal )
ent:SetAngles( Angle(0, ply:EyeAngles().y, 0 ) )
ent:Spawn()
ent:Activate()
ent.ImpactSound = table.Random(ImpSnds)
ent.WaterImpactSoundSound = table.Random(WtrImpSnds)
ent.DebrisSound = table.Random(DbrSnds)
ent.ExplosionSound = table.Random(ExpSnds)
ent.FarExplosionSound = table.Random(FarExpSnds)
ent.DistExplosionSound = table.Random(DstExpSnds)
ent.WaterExplosionSound = table.Random(WtrExpSnds)
return ent
end
function ENT:Initialize()
self:SetModel(self.Model)
self:SetSolid(SOLID_VPHYSICS)
self:PhysicsInit(SOLID_VPHYSICS)
self:SetCollisionGroup( COLLISION_GROUP_WORLD )
self:PhysWake()
local pObj = self:GetPhysicsObject()
pObj:SetMass( self.Mass )
pObj:EnableGravity( false )
pObj:EnableMotion( true )
pObj:EnableDrag( false )
self:StartMotionController()
self:PhysWake()
self.InGround = false
self.InEntity = false
self.Exploded = false
self.Armed = false
self.CurDurability = self.Durability
self.AirDetTicks = 0
self.FreefallTicks=0
self:OnSpawn()
end
function ENT:OnSpawn()
end
--Arming
function ENT:Use( activator, caller )
if !self.Exploded and !self.Armed then
self:EmitSound(self.ArmSound)
self.Armed = true
end
end
--Think
function ENT:Think()
self:NextThink(CurTime())
if self.Armed then
if self:GetAirDetonate() then
if IsValid(self) and (self:GetVelocity():Length() > self.ImpactSpeed) and not self:IsPlayerHolding() then
self.AirDetTicks = self.AirDetTicks + 1
if self.AirDetTicks >= 15 then
local tr = util.TraceLine({
start = self:LocalToWorld(self:OBBCenter()),
endpos = self:LocalToWorld(self:OBBCenter()) - Vector(0,0,self:GetDetonateHeight()),
filter = self,
})
if tr.Hit then
self.Exploded = true
self:Explode(self:GetPos())
end
end
end
end
if self.GuidanceActive then
self:LaserGuidance()
self:Guidance(self:GetPhysicsObject())
end
end
if self.InGround or self.InEntity then
if self:IsPlayerHolding() then
self.InGround = false
self.InEntity = false
end
end
self:OnTick()
return true
end
function ENT:OnTick()
end
--Flight physics
function ENT:PhysicsSimulate( phys, deltatime )
phys:Wake()
local ForceLinear, ForceAngle = phys:CalculateForceOffset( physenv.GetGravity(), phys:LocalToWorld( phys:GetMassCenter() + Vector(10,0,0) ) )
if self.WingsOpen then
ForceAngle = ForceAngle - phys:GetAngleVelocity() * 30
else
ForceAngle = ForceAngle - phys:GetAngleVelocity() * 5
if not self.GuidanceActive then
phys:AddAngleVelocity(Vector(self:GetVelocity():Length()*0.01,0,0))
end
end
return ForceAngle, ForceLinear, SIM_GLOBAL_ACCELERATION
end
--Guidance
function ENT:LaserGuidance()
if self.Armed and not (self.InGround or self.InEntity) then
if self.LaserGuided then
if IsValid(self.Launcher) then
local Parent = self.Launcher
local phys = self:GetPhysicsObject()
local ID = Parent:LookupAttachment( self.LaserCode )
local Attachment = Parent:GetAttachment( ID )
if Parent:GetAttachment( ID ) then
local TargetDir = Attachment.Ang:Forward()
local tr = util.TraceHull( {
start = Attachment.Pos,
endpos = (Attachment.Pos + TargetDir * 999999),
mins = Vector( -1, -1, -1 ),
maxs = Vector( 1, 1, 1 ),
filter = {self,Parent,Parent.wheel_C,Parent.wheel_R,Parent.wheel_L}
} )
self.target = tr.Entity
self.targetOffset = tr.Entity:WorldToLocal(tr.HitPos)
end
end
end
end
end
function ENT:Guidance(ph)
if self.target != NULL then
if IsValid(self.target) or self.target:GetClass() == "worldspawn" then
if not (self.InGround or self.Armed or self.InEntity) then return end
local pos = self:GetPos()
local vel = self:WorldToLocal(pos+ph:GetVelocity())*0.4
vel.x = 0
local target = self.target:LocalToWorld(self.targetOffset)
local v = self:WorldToLocal(target + Vector(0,0,math.Clamp((pos*Normal):Distance(target*Normal)/5 - 50,0,self.DiveHeight or 0))):GetNormal()
if isnumber(self.Agility) then
v.y = math.Clamp(v.y*10,-1,1)*self.Agility
v.z = math.Clamp(v.z*10,-1,1)*self.Agility
else
v.y = math.Clamp(v.y*10,-1,1)*10
v.z = math.Clamp(v.z*10,-1,1)*10
end
ph:AddAngleVelocity(
ph:GetAngleVelocity()*-0.4
+ Vector(math.Rand(-1,1), math.Rand(-1,1), math.Rand(-1,1))*5
+ Vector(0,-vel.z,vel.y)
+ Vector(0,-v.z,v.y)
)
ph:AddVelocity(self:GetForward()*10 - self:LocalToWorld(vel*Normal2) + pos)
end
end
end
--Taking damage
function ENT:OnTakeDamage(dmginfo)
if self.Exploded then return end
local inflictor = dmginfo:GetInflictor()
local attacker = dmginfo:GetAttacker()
if IsValid(inflictor) and (inflictor.IsGredBomb or inflictor.lvsProjectile or inflictor.SWBombV3 ) then return end
if IsValid(attacker) and (attacker.IsGredBomb or attacker.lvsProjectile or attacker.SWBombV3 ) then return end
self:TakePhysicsDamage(dmginfo)
self.CurDurability = self.CurDurability - dmginfo:GetDamage()
if self.Armed then
if self.CurDurability <= 0 then
self.Exploded = true
self:Explode(self:GetPos())
end
else
self:EmitSound(self.ArmSound)
self.Armed = true
end
end
--Explosion
function ENT:Explode(pos)
if !self.Exploded then return end
if !self.Armed then return end
pos = self:LocalToWorld(self:OBBCenter())
if(self:WaterLevel() >= 1) then
local tr = util.TraceLine({
start = pos,
endpos = pos + Vector(0,0,9000),
filter = self,
})
local tr2 = util.TraceLine({
start = tr.HitPos,
endpos = tr.HitPos - Vector(0,0,9000),
filter = self,
mask = MASK_WATER + CONTENTS_TRANSLUCENT,
})
if tr2.Hit then
ParticleEffect(self.EffectWater, tr2.HitPos,(self.AngEffect and angle_dif or angle_reg), nil)
end
else
local tr = util.TraceLine({
start = pos,
endpos = pos - Vector(0, 0, self.TraceLength),
filter = self,
})
if tr.HitWorld then
ParticleEffect(self.Effect,pos,(self.AngEffect and angle_dif or angle_reg),nil)
else
ParticleEffect(self.EffectAir,pos,(self.AngEffect and angle_dif or angle_reg),nil)
end
end
debugoverlay.Sphere(pos,self.ExplosionRadius,5,Color(255,0,0,100),false)
debugoverlay.Sphere(pos,self.BlastRadius,5,Color(200,150,0,100),false)
debugoverlay.Sphere(pos,self.FragRadius,5,Color(200,200,0,100),false)
--Deadly zone
if self.ExplosionRadius > 0 then
for k, v in pairs(ents.FindInSphere(pos,self.ExplosionRadius)) do
if v:IsValid() and not v.SWBombV3 then
local dmg = DamageInfo()
dmg:SetInflictor(self)
dmg:SetDamage(self.ExplosionDamage)
dmg:SetDamageType(self.DamageType)
dmg:SetAttacker((IsValid(self:GetCreator()) and self:GetCreator()) or self.Attacker or game.GetWorld())
v:TakeDamageInfo(dmg)
end
end
end
--Blast wave
if self.BlastRadius > 0 then
util.BlastDamage( self, ((IsValid(self:GetCreator()) and self:GetCreator()) or self.Attacker or game.GetWorld()), pos, self.BlastRadius,self.ExplosionDamage/2 )
self:BlastDoors(self, pos, 10)
end
--Frags
if self.FragCount > 0 then
self:Fragmentation(self,pos,10000,self.FragDamage,self.FragRadius,((IsValid(self:GetCreator()) and self:GetCreator()) or self.Attacker or game.GetWorld()))
end
swv3.CreateSound(pos,false,self.ExplosionSound,self.FarExplosionSound,self.DistExplosionSound)
timer.Simple(0,function()
if !IsValid(self) then return end
self:Remove()
end)
end
--Impact
function ENT:PhysicsCollide( data, physobj )
if self:GetVelocity():Length() >= self.ImpactSpeed then
local tr = util.TraceLine({
start = self:LocalToWorld(self:OBBCenter()),
endpos =self:LocalToWorld(self:OBBCenter())+self:GetAngles():Forward()*self.TraceLength,
filter = self,
})
if not (self.InGround or self.InEntity) then
if tr.Hit and tr.HitWorld and not tr.HitSky then
if self:WaterLevel() <= 0 then
self:EmitSound(self.ImpactSound)
self:EmitSound(self.DebrisSound)
else
self:EmitSound(self.WaterImpactSound)
end
self:SetPos(self:GetPos()+self:GetAngles():Forward()*(self.ImpactDepth))
self:SetAngles(self:GetAngles())
self:GetPhysicsObject():EnableMotion(false)
self.InGround = true
elseif tr.Hit and not tr.HitWorld and not tr.HitSky then
if IsValid(tr.Entity) then
if self:WaterLevel() <= 0 then
self:EmitSound(self.ImpactSound)
self:EmitSound(self.DebrisSound)
else
self:EmitSound(self.WaterImpactSound)
end
self:SetPos(self:GetPos()+self:GetAngles():Forward()*(self.ImpactDepth))
self:SetAngles(self:GetAngles())
self:SetParent(tr.Entity)
self.InEntity = true
end
end
end
if self.Armed then
if self:GetTimed() then
timer.Simple(self:GetTimer(),function()
if IsValid(self) then
self.Exploded = true
self:Explode(self:GetPos())
end
end)
else
self.Exploded = true
self:Explode(self:GetPos())
end
else
self:EmitSound(self.ArmSound)
self.Armed = true
end
end
end
--Door blasting
function ENT:IsDoor(ent)
local Class = ent:GetClass()
return (Class == "prop_door") or (Class == "prop_door_rotating") or (Class == "func_door") or (Class == "func_door_rotating")
end
function ENT:BlastDoors(blaster, pos, power, range, ignoreVisChecks)
for k, door in pairs(ents.FindInSphere(pos, 40 * power * (range or 1))) do
if self:IsDoor(door) then
local proceed = ignoreVisChecks
if not proceed then
local tr = util.QuickTrace(pos, door:LocalToWorld(door:OBBCenter()) - pos, blaster)
proceed = IsValid(tr.Entity) and (tr.Entity == door)
end
if proceed then
self:BlastDoor(door, (door:LocalToWorld(door:OBBCenter()) - pos):GetNormalized() * 1000)
end
end
if door:GetClass() == "func_breakable_surf" then
door:Fire("Break")
end
end
end
function ENT:BlastDoor(ent, vel)
local Moddel, Pozishun, Ayngul, Muteeriul, Skin = ent:GetModel(), ent:GetPos(), ent:GetAngles(), ent:GetMaterial(), ent:GetSkin()
sound.Play("Wood_Crate.Break", Pozishun, 60, 100)
sound.Play("Wood_Furniture.Break", Pozishun, 60, 100)
ent:Fire("unlock", "", 0)
ent:Fire("open", "", 0)
ent:SetNoDraw(true)
ent:SetNotSolid(true)
if Moddel and Pozishun and Ayngul then
local Replacement = ents.Create("prop_physics")
Replacement:SetModel(Moddel)
Replacement:SetPos(Pozishun + Vector(0, 0, 1))
Replacement:SetAngles(Ayngul)
if Muteeriul then
Replacement:SetMaterial(Muteeriul)
end
if Skin then
Replacement:SetSkin(Skin)
end
Replacement:SetModelScale(.9, 0)
Replacement:Spawn()
Replacement:Activate()
if vel then
Replacement:GetPhysicsObject():SetVelocity(vel)
timer.Simple(0, function()
if IsValid(Replacement) then
Replacement:GetPhysicsObject():ApplyForceCenter(vel * 100)
end
end)
end
timer.Simple(3, function()
if IsValid(Replacement) then
Replacement:SetCollisionGroup(COLLISION_GROUP_WEAPON)
end
end)
timer.Simple(30, function()
if IsValid(ent) then
ent:SetNotSolid(false)
ent:SetNoDraw(false)
end
if IsValid(Replacement) then
Replacement:Remove()
end
end)
end
end
--Frags
function ENT:Fragmentation(shooter, origin, fragNum, fragDmg, fragMaxDist, attacker, direction, spread, zReduction)
shooter = shooter or game.GetWorld()
zReduction = zReduction or 2
local Spred = Vector(0, 0, 0)
local BulletsFired, MaxBullets, disperseTime = 0, self.FragCount, .5
if fragNum >= 12000 then
disperseTime = 2
elseif fragNum >= 6000 then
disperseTime = 1
end
for i = 1, fragNum do
timer.Simple((i / fragNum) * disperseTime, function()
local Dir
if direction and spread then
Dir = Vector(direction.x, direction.y, direction.z)
Dir = Dir + VectorRand() * math.Rand(0, spread)
Dir:Normalize()
else
Dir = VectorRand()
end
if zReduction then
Dir.z = Dir.z / zReduction
Dir:Normalize()
end
local Tr = util.QuickTrace(origin, Dir * fragMaxDist, shooter)
if Tr.Hit and not Tr.HitSky and not Tr.HitWorld and (BulletsFired < MaxBullets) then
local LowFrag = (Tr.Entity.IsVehicle and Tr.Entity:IsVehicle()) or Tr.Entity.LFS or Tr.Entity.LVS or Tr.Entity.EZlowFragPlease
if (not LowFrag) or (LowFrag and math.random(1, 4) == 2) then
local firer = (IsValid(shooter) and shooter) or game.GetWorld()
firer:FireBullets({
Attacker = attacker,
Damage = fragDmg,
Force = fragDmg / 8,
Num = 1,
Src = origin,
Tracer = 0,
Dir = Dir,
Spread = Spred,
AmmoType = "Buckshot"
})
BulletsFired = BulletsFired + 1
end
end
end)
end
end
end
if CLIENT then
function ENT:Initialize()
self.snd = CreateSound(self, self.WhistleSound)
self.snd:SetSoundLevel( 110 )
self.snd:PlayEx(0,150)
end
function ENT:CalcDoppler()
local Ent = LocalPlayer()
local ViewEnt = Ent:GetViewEntity()
local sVel = self:GetVelocity()
local oVel = Ent:GetVelocity()
local SubVel = oVel - sVel
local SubPos = self:GetPos() - Ent:GetPos()
local DirPos = SubPos:GetNormalized()
local DirVel = SubVel:GetNormalized()
local A = math.acos( math.Clamp( DirVel:Dot( DirPos ) ,-1,1) )
return (1 + math.cos( A ) * SubVel:Length() / 13503.9)
end
function ENT:Think()
if self.snd then
self.snd:ChangePitch( 100 * self:CalcDoppler(), 1 )
self.snd:ChangeVolume(math.Clamp(-(self:GetVelocity().z + 1000) / 3000,0,1), 2)
end
end
function ENT:Draw()
self:DrawModel()
end
function ENT:SoundStop()
if self.snd then
self.snd:Stop()
end
end
function ENT:OnRemove()
self:SoundStop()
end
end