Files
wnsrc/lua/entities/lvs_armor.lua
lifestorm 9c918c46e5 Upload
2024-08-04 23:12:27 +03:00

240 lines
5.8 KiB
Lua

--[[
| 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/
--]]
AddCSLuaFile()
ENT.Type = "anim"
ENT.DoNotDuplicate = true
ENT.RenderGroup = RENDERGROUP_BOTH
function ENT:SetupDataTables()
self:NetworkVar( "Entity",0, "Base" )
self:NetworkVar( "Float",0, "HP" )
self:NetworkVar( "Float",1, "MaxHP" )
self:NetworkVar( "Float",2, "IgnoreForce" )
self:NetworkVar( "Vector",0, "Mins" )
self:NetworkVar( "Vector",1, "Maxs" )
self:NetworkVar( "Bool",0, "Destroyed" )
self:NetworkVar( "String",0, "Label" )
if SERVER then
self:SetMaxHP( 100 )
self:SetHP( 100 )
self:SetLabel( "Armor Plate" )
end
end
if SERVER then
function ENT:Initialize()
self:SetMoveType( MOVETYPE_NONE )
self:SetSolid( SOLID_NONE )
self:DrawShadow( false )
end
function ENT:Think()
return false
end
function ENT:OnHealthChanged( dmginfo, old, new )
if old == new then return end
end
function ENT:OnRepaired()
end
function ENT:OnDestroyed( dmginfo )
end
function ENT:OnTakeDamage( dmginfo )
end
function ENT:TakeTransmittedDamage( dmginfo )
local Force = dmginfo:GetDamageForce()
local Damage = dmginfo:GetDamage()
local DamageForce = Force:Length()
local CurHealth = self:GetHP()
local pos = dmginfo:GetDamagePosition()
local dir = Force:GetNormalized()
local trace = util.TraceLine( {
start = pos - dir * 20,
endpos = pos + dir * 20,
} )
local DotHitNormal = math.Clamp( trace.HitNormal:Dot( dir ) ,-1,1)
local Armor = self:GetIgnoreForce()
local ArmorEffective = Armor / math.abs( DotHitNormal )
if math.abs( DotHitNormal ) > 0.9 then
ArmorEffective = Armor
end
local DisableBounce = false
local Inflictor = dmginfo:GetInflictor()
if IsValid( Inflictor ) then
if Inflictor.DisableBallistics or Inflictor:IsNPC() or Inflictor:IsNextBot() then
DisableBounce = true
end
end
if DamageForce <= ArmorEffective then
local T = CurTime()
if trace.Entity ~= self:GetBase() then
self._NextBounce = T + 1
return false
end
local Ax = math.acos( DotHitNormal )
local HitAngle = 90 - (180 - math.deg( Ax ))
if HitAngle > 20 then
local effectdata = EffectData()
effectdata:SetOrigin( trace.HitPos )
effectdata:SetNormal( -dir )
util.Effect( "manhacksparks", effectdata, true, true )
self._NextBounce = T + 1
return false
end
local NewDir = dir - trace.HitNormal * math.cos( Ax ) * 2
if (self._NextBounce or 0) > T or DisableBounce then
local effectdata = EffectData()
effectdata:SetOrigin( trace.HitPos )
effectdata:SetNormal( NewDir:GetNormalized() * 0.25 )
util.Effect( "manhacksparks", effectdata, true, true )
return false
end
self._NextBounce = T + 1
local hit_decal = ents.Create( "lvs_armor_bounce" )
hit_decal:SetPos( trace.HitPos )
hit_decal:SetAngles( NewDir:Angle() )
hit_decal:Spawn()
hit_decal:Activate()
hit_decal:EmitSound("lvs/armor_rico"..math.random(1,6)..".wav", 95, 100, math.min( dmginfo:GetDamage() / 1000, 1 ) )
local PhysObj = hit_decal:GetPhysicsObject()
if not IsValid( PhysObj ) then return false end
PhysObj:EnableDrag( false )
PhysObj:SetVelocityInstantaneous( NewDir * 2000 + Vector(0,0,250) )
PhysObj:SetAngleVelocityInstantaneous( VectorRand() * 250 )
return false
end
local NewHealth = math.Clamp( CurHealth - Damage, 0, self:GetMaxHP() )
self:OnHealthChanged( dmginfo, CurHealth, NewHealth )
self:SetHP( NewHealth )
local hit_decal = ents.Create( "lvs_armor_penetrate" )
hit_decal:SetPos( trace.HitPos )
hit_decal:SetAngles( trace.HitNormal:Angle() + Angle(90,0,0) )
hit_decal:Spawn()
hit_decal:Activate()
hit_decal:SetParent( trace.Entity )
if not self:GetDestroyed() then
self:SetDestroyed( true )
self:OnDestroyed( dmginfo )
end
return true
end
return
end
function ENT:Initialize()
end
function ENT:OnRemove()
end
function ENT:Think()
end
function ENT:Draw()
end
local function DrawText( pos, text, col )
cam.Start2D()
local data2D = pos:ToScreen()
if not data2D.visible then return end
local font = "TargetIDSmall"
local x = data2D.x
local y = data2D.y
draw.DrawText( text, font, x + 1, y + 1, Color( 0, 0, 0, 120 ), TEXT_ALIGN_CENTER )
draw.DrawText( text, font, x + 2, y + 2, Color( 0, 0, 0, 50 ), TEXT_ALIGN_CENTER )
draw.DrawText( text, font, x, y, col or color_white, TEXT_ALIGN_CENTER )
cam.End2D()
end
local LVS = LVS
local BoxMat = Material("models/wireframe")
local ColorSelect = Color(0,127,255,150)
local ColorNormal = Color(50,50,50,150)
local ColorTransBlack = Color(0,0,0,150)
local OutlineThickness = Vector(0.5,0.5,0.5)
local ColorText = Color(255,0,0,255)
function ENT:DrawTranslucent()
if not LVS.DeveloperEnabled then return end
local ply = LocalPlayer()
if not IsValid( ply ) or ply:InVehicle() or not ply:KeyDown( IN_SPEED ) then return end
local boxOrigin = self:GetPos()
local boxAngles = self:GetAngles()
local boxMins = self:GetMins()
local boxMaxs = self:GetMaxs()
local HitPos, _, _ = util.IntersectRayWithOBB( ply:GetShootPos(), ply:GetAimVector() * 1000, boxOrigin, boxAngles, boxMins, boxMaxs )
local InRange = isvector( HitPos )
local Col = InRange and ColorSelect or ColorNormal
render.SetColorMaterial()
render.DrawBox( boxOrigin, boxAngles, boxMins, boxMaxs, Col )
render.DrawBox( boxOrigin, boxAngles, boxMaxs + OutlineThickness, boxMins - OutlineThickness, ColorTransBlack )
local boxCenter = (self:LocalToWorld( boxMins ) + self:LocalToWorld( boxMaxs )) * 0.5
if not InRange then return end
DrawText( boxCenter, "Armor: "..(self:GetIgnoreForce() / 100).."mm\nHealth:"..self:GetHP().."/"..self:GetMaxHP(), ColorText )
end