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

381 lines
8.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()
SWEP.Category = "[LVS]"
SWEP.Spawnable = true
SWEP.AdminSpawnable = false
SWEP.ViewModel = "models/weapons/c_repairlvs.mdl"
SWEP.WorldModel = "models/weapons/w_repairlvs.mdl"
SWEP.UseHands = true
SWEP.HoldType = "slam"
SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = true
SWEP.Primary.Ammo = "none"
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "none"
SWEP.MaxRange = 250
function SWEP:SetupDataTables()
self:NetworkVar( "Float",0, "FlameTime" )
end
function SWEP:GetLVS()
local ply = self:GetOwner()
if not IsValid( ply ) then return NULL end
local ent = ply:GetEyeTrace().Entity
if not IsValid( ent ) then return NULL end
if ent.LVS then return ent end
if not ent.GetBase then return NULL end
ent = ent:GetBase()
if IsValid( ent ) and ent.LVS then return ent end
return NULL
end
function SWEP:FindClosest()
local lvsEnt = self:GetLVS()
if not IsValid( lvsEnt ) then return NULL end
local ply = self:GetOwner()
if ply:InVehicle() then return end
local ShootPos = ply:GetShootPos()
local AimVector = ply:GetAimVector()
local ClosestDist = self.MaxRange
local ClosestPiece = NULL
for _, entity in pairs( lvsEnt:GetChildren() ) do
if entity:GetClass() ~= "lvs_armor" then continue end
local boxOrigin = entity:GetPos()
local boxAngles = entity:GetAngles()
local boxMins = entity:GetMins()
local boxMaxs = entity:GetMaxs()
local HitPos, _, _ = util.IntersectRayWithOBB( ShootPos, AimVector * 1000, boxOrigin, boxAngles, boxMins, boxMaxs )
if isvector( HitPos ) then
local Dist = (ShootPos - HitPos):Length()
if Dist < ClosestDist then
ClosestDist = Dist
ClosestPiece = entity
end
end
end
return ClosestPiece
end
local function IsEngineMode( AimPos, Engine )
if not IsValid( Engine ) then return false end
if not isfunction( Engine.GetDoorHandler ) then return (AimPos - Engine:GetPos()):Length() < 25 end
local DoorHandler = Engine:GetDoorHandler()
if IsValid( DoorHandler ) then
if DoorHandler:IsOpen() then
return (AimPos - Engine:GetPos()):Length() < 50
end
return false
end
return (AimPos - Engine:GetPos()):Length() < 25
end
if CLIENT then
SWEP.PrintName = "Repair Torch"
SWEP.Author = "Blu-x92"
SWEP.Slot = 5
SWEP.SlotPos = 1
SWEP.Purpose = "Repair Broken Armor"
SWEP.Instructions = "Primary to Repair\nHold Secondary to switch to Armor Repair Mode"
SWEP.DrawWeaponInfoBox = true
SWEP.WepSelectIcon = surface.GetTextureID( "weapons/lvsrepair" )
local ColorSelect = Color(0,255,255,50)
local ColorText = Color(255,255,255,255)
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
function SWEP:DrawEffects( weapon, ply )
local ID = weapon:LookupAttachment( "muzzle" )
local Muzzle = weapon:GetAttachment( ID )
if not Muzzle then return end
local T = CurTime()
if self:GetFlameTime() < T or (self._NextFX1 or 0) > T then return end
self._NextFX1 = T + 0.02
local effectdata = EffectData()
effectdata:SetOrigin( Muzzle.Pos )
effectdata:SetAngles( Muzzle.Ang )
effectdata:SetScale( 0.5 )
util.Effect( "MuzzleEffect", effectdata, true, true )
if (self._NextFX2 or 0) > T then return end
self._NextFX2 = T + 0.06
local trace = ply:GetEyeTrace()
local ShootPos = ply:GetShootPos()
if (ShootPos - trace.HitPos):Length() > self.MaxRange then return end
local effectdata = EffectData()
effectdata:SetOrigin( trace.HitPos )
effectdata:SetNormal( trace.HitNormal * 0.15 )
util.Effect( "manhacksparks", effectdata, true, true )
local dlight = DynamicLight( self:EntIndex() )
if not dlight then return end
dlight.pos = (trace.HitPos + ShootPos) * 0.5
dlight.r = 206
dlight.g = 253
dlight.b = 255
dlight.brightness = 3
dlight.decay = 1000
dlight.size = 256
dlight.dietime = CurTime() + 0.1
end
function SWEP:PostDrawViewModel( vm, weapon, ply )
self:DrawEffects( vm, ply )
end
function SWEP:DrawWorldModel( flags )
self:DrawModel( flags )
self:DrawEffects( self, self:GetOwner() )
end
function SWEP:DrawHUD()
local ply = self:GetOwner()
if not IsValid( ply ) or not ply:KeyDown( IN_ATTACK2 ) then
local lvsEnt = self:GetLVS()
local Pos = ply:GetEyeTrace().HitPos
if IsValid( lvsEnt ) and (Pos - ply:GetShootPos()):Length() < self.MaxRange and not ply:InVehicle() then
if isfunction( lvsEnt.GetEngine ) then
local Engine = lvsEnt:GetEngine()
local AimPos = ply:GetEyeTrace().HitPos
local EngineMode = IsEngineMode( AimPos, Engine )
if IsValid( Engine ) and EngineMode then
DrawText( AimPos, "Engine\nHealth: "..math.Round(Engine:GetHP()).."/"..Engine:GetMaxHP(), ColorText )
else
DrawText( AimPos, "Frame\nHealth: "..math.Round(lvsEnt:GetHP()).."/"..lvsEnt:GetMaxHP(), ColorText )
end
else
DrawText( ply:GetEyeTrace().HitPos, "Frame\nHealth: "..math.Round(lvsEnt:GetHP()).."/"..lvsEnt:GetMaxHP(), ColorText )
end
end
return
end
local Target = self:FindClosest()
if IsValid( Target ) then
local boxOrigin = Target:GetPos()
local boxAngles = Target:GetAngles()
local boxMins = Target:GetMins()
local boxMaxs = Target:GetMaxs()
cam.Start3D()
render.SetColorMaterial()
render.DrawBox( boxOrigin, boxAngles, boxMins, boxMaxs, ColorSelect )
cam.End3D()
DrawText( Target:LocalToWorld( (boxMins + boxMaxs) * 0.5 ), (Target:GetIgnoreForce() / 100).."mm "..Target:GetLabel().."\nHealth: "..math.Round(Target:GetHP()).."/"..Target:GetMaxHP(), ColorText )
else
local Pos = ply:GetEyeTrace().HitPos
if IsValid( self:GetLVS() ) and (Pos - ply:GetShootPos()):Length() < self.MaxRange and not ply:InVehicle() then
DrawText( Pos, "No Armor", ColorText )
end
end
end
end
function SWEP:Initialize()
self:SetHoldType( self.HoldType )
end
function SWEP:PrimaryAttack()
local T = CurTime()
self:SetNextPrimaryFire( T + 0.15 )
self:SetFlameTime( T + 0.3 )
local EngineMode = false
local ArmorMode = true
local Target = self:FindClosest()
local ply = self:GetOwner()
if IsValid( ply ) and not ply:KeyDown( IN_ATTACK2 ) then
Target = self:GetLVS()
if isfunction( Target.GetEngine ) then
local Engine = Target:GetEngine()
local AimPos = ply:GetEyeTrace().HitPos
EngineMode = IsEngineMode( AimPos, Engine )
if IsValid( Engine ) and EngineMode then
Target = Engine
end
end
ArmorMode = false
end
if not IsValid( Target ) then
local ent = ply:GetEyeTrace().Entity
if IsValid( ent ) and (ent:GetPos() - ply:GetShootPos()):Length() < self.MaxRange and ent:GetClass() == "lvs_item_mine" then
if SERVER then timer.Simple(0, function() if not IsValid( ent ) then return end ent:Detonate() end ) end
end
return
end
local HP = Target:GetHP()
local MaxHP = Target:GetMaxHP()
if IsFirstTimePredicted() then
local trace = ply:GetEyeTrace()
if HP ~= MaxHP then
local effectdata = EffectData()
effectdata:SetOrigin( trace.HitPos )
effectdata:SetNormal( trace.HitNormal )
util.Effect( "stunstickimpact", effectdata, true, true )
end
end
if CLIENT then return end
Target:SetHP( math.min( HP + 7, MaxHP ) )
if EngineMode and Target:GetDestroyed() then
Target:SetDestroyed( false )
end
if not ArmorMode then return end
if Target:GetDestroyed() then Target:SetDestroyed( false ) end
if HP < MaxHP then return end
Target:OnRepaired()
end
function SWEP:SecondaryAttack()
end
function SWEP:Think()
local ply = self:GetOwner()
if not IsValid( ply ) then self:StopSND() return end
local PlaySound = self:GetFlameTime() >= CurTime() and (ply:GetShootPos() - ply:GetEyeTrace().HitPos):Length() < self.MaxRange
if PlaySound then
self:PlaySND()
else
self:StopSND()
end
end
function SWEP:StopSND()
if CLIENT then return end
if not self._snd then return end
self._snd:Stop()
self._snd = nil
end
function SWEP:PlaySND()
if CLIENT then return end
if self._snd then return end
local ply = self:GetOwner()
if not IsValid( ply ) then return end
self._snd = CreateSound( ply, "lvs/weldingtorch_loop.wav" )
self._snd:PlayEx(1, 70 )
end
function SWEP:OnRemove()
self:StopSND()
end
function SWEP:OnDrop()
self:StopSND()
end
function SWEP:Holster( wep )
self:StopSND()
return true
end