This commit is contained in:
lifestorm
2024-08-04 23:54:45 +03:00
parent 0e770b2b49
commit df294d03aa
7526 changed files with 4011945 additions and 15 deletions

View File

@@ -0,0 +1,250 @@
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ENT._pdsParts = {}
ENT.PDSDamageVelocity = 100
ENT.PDSDamageMultiplier = 0.05
function ENT:ClearPDS()
if not istable( self._pdsParts ) then return end
table.Empty( self._pdsParts )
end
function ENT:PDSHealthValueChanged( name, old, new)
if new == old then return end
if not self:IsInitialized() or not istable( self._pdsParts ) or new ~= self:GetMaxHP() then return end
for _, part in pairs( self._pdsParts ) do
part:SetStage( 0 )
if not part._group or not part._subgroup then continue end
self:SetBodygroup( part._group, part._subgroup )
part._group = nil
part._subgroup = nil
end
end
local function DamagePart( ent, part, speed )
if not speed then
speed = 0
end
local stage = part:GetStage() + 1
part:SetStage( stage )
local data = part:GetStageData()
if isfunction( data.Callback ) then
data:Callback( ent, part, speed )
end
if istable( data.bodygroup ) then
for group, subgroup in pairs( data.bodygroup ) do
if not part._group or not part._subgroup then
part._group = group
part._subgroup = ent:GetBodygroup( group )
end
ent:SetBodygroup( group, subgroup )
end
end
if isstring( data.sound ) then
ent:EmitSound( data.sound, 75, 100, math.min(0.1 + speed / 700,1) )
end
if isstring( data.effect ) then
local effectdata = EffectData()
effectdata:SetOrigin( ent:LocalToWorld( part.pos ) )
util.Effect( data.effect, effectdata, true, true )
end
if not istable( data.gib ) or not data.gib.mdl then return end
timer.Simple(0, function()
if not IsValid( ent ) then return end
local InvAttach = isstring( data.gib.target )
local pos
local ang
if InvAttach then
pos = vector_origin
ang = angle_zero
else
if isvector( data.gib.pos ) and isangle( data.gib.ang ) then
pos = ent:LocalToWorld( data.gib.pos )
ang = ent:LocalToWorldAngles( data.gib.ang )
end
end
local gib = ents.Create( "prop_physics" )
gib:SetModel( data.gib.mdl )
gib:SetPos( pos )
gib:SetAngles( ang )
gib:Spawn()
gib:Activate()
gib:SetCollisionGroup( COLLISION_GROUP_DEBRIS )
gib:SetSkin( ent:GetSkin() )
if InvAttach then
local att = gib:GetAttachment( gib:LookupAttachment( data.gib.target ) )
if att then
local newpos = ent:LocalToWorld( -att.Pos )
local newang = ent:LocalToWorldAngles( -att.Ang )
gib:SetPos( newpos )
gib:SetAngles( newang )
end
end
gib:SetOwner( ent )
gib:SetColor( ent:GetColor() )
gib:SetRenderMode( RENDERMODE_TRANSALPHA )
ent:DeleteOnRemove( gib )
ent:TransferCPPI( gib )
timer.Simple( 59.5, function()
if not IsValid( gib ) then return end
gib:SetRenderFX( kRenderFxFadeFast )
end)
timer.Simple( 60, function()
if not IsValid( gib ) then return end
gib:Remove()
end)
local PhysObj = gib:GetPhysicsObject()
if not IsValid( PhysObj ) then return end
PhysObj:SetVelocityInstantaneous( ent:GetVelocity() + Vector(0,0,250) )
PhysObj:AddAngleVelocity( VectorRand() * 500 )
end)
end
function ENT:AddPDS( data )
if not data then return end
if self._pdsPartsID then
self._pdsPartsID = self._pdsPartsID + 1
else
self._pdsPartsID = 1
end
data.pos = data.pos or Vector(0,0,0)
data.ang = data.ang or Angle(0,0,0)
data.mins = data.mins or Vector(-1,-1,-1)
data.maxs = data.maxs or Vector(1,1,1)
data.stages = data.stages or {}
data.GetStage = function( self )
if not self._curstage then
self._curstage = 0
end
return self._curstage
end
data.SetStage = function( self, stage )
self._curstage = stage
end
data.GetStageData = function( self, stage )
return self.stages[ self:GetStage() ] or {}
end
debugoverlay.BoxAngles( self:LocalToWorld( data.pos ), data.mins, data.maxs, self:LocalToWorldAngles( data.ang ), 8, Color( 50, 50, 0, 150 ) )
self._pdsParts[ self._pdsPartsID ] = data
if data.allow_damage then
local id = self._pdsPartsID
self:AddDS( {
pos = data.pos,
ang = data.ang,
mins = data.mins,
maxs = data.maxs,
Callback = function( tbl, ent, dmginfo )
if not IsValid( ent ) then return end
local part = ent._pdsParts[ id ]
if not part then return end
DamagePart( ent, part, 1000 )
end
} )
end
end
function ENT:FindPDS( PosToCheck, RadiusAdd )
if not isnumber( RadiusAdd ) then
RadiusAdd = 1
end
local Parts = {}
debugoverlay.Cross( PosToCheck, 50, 4, Color( 255, 255, 0 ) )
for index, part in ipairs( self._pdsParts ) do
local mins = part.mins
local maxs = part.maxs
local pos = self:LocalToWorld( part.pos )
local ang = self:LocalToWorldAngles( part.ang )
local dir = (pos - PosToCheck):GetNormalized()
local HitPos, HitNormal, Fraction = util.IntersectRayWithOBB( PosToCheck, dir * RadiusAdd, pos, ang, mins, maxs )
if HitPos then
table.insert( Parts, part )
end
end
for _, closestPart in ipairs( Parts ) do
local mins = closestPart.mins
local maxs = closestPart.maxs
local pos = self:LocalToWorld( closestPart.pos )
local ang = self:LocalToWorldAngles( closestPart.ang )
debugoverlay.BoxAngles( pos, mins, maxs, ang, 1, Color( 255, 255, 0, 150 ) )
end
return Parts
end
function ENT:CalcPDS( physdata )
local VelDif = math.abs( physdata.OurOldVelocity:Length() - physdata.OurNewVelocity:Length() )
if VelDif < self.PDSDamageVelocity then return end
local parts = self:FindPDS( physdata.HitPos, (VelDif - self.PDSDamageVelocity) * self.PDSDamageMultiplier )
if #parts == 0 then return end
local HP = self:GetHP()
local MaxHP = self:GetMaxHP()
if HP == MaxHP then
self:SetHP( math.max( MaxHP - 0.1, 1 ) )
end
for _, part in pairs( parts ) do
DamagePart( self, part, VelDif )
end
end