dobrograd-13-06-2022/garrysmod/addons/feature-wire/lua/entities/gmod_wire_explosive.lua
Jonny_Bro (Nikita) e4d5311906 first commit
2023-11-16 15:01:19 +05:00

274 lines
7.4 KiB
Lua

AddCSLuaFile()
DEFINE_BASECLASS( "base_wire_entity" )
ENT.PrintName = "Wire Explosive"
ENT.WireDebugName = "Explosive"
if CLIENT then return end -- No more client
local wire_explosive_delay = CreateConVar( "wire_explosive_delay", 0.2, FCVAR_ARCHIVE )
local wire_explosive_range = CreateConVar( "wire_explosive_range", 512, FCVAR_ARCHIVE )
function ENT:Initialize()
self:PhysicsInit( SOLID_VPHYSICS )
self:SetMoveType( MOVETYPE_VPHYSICS )
self:SetSolid( SOLID_VPHYSICS )
local phys = self:GetPhysicsObject()
if (phys:IsValid()) then
phys:Wake()
end
self.exploding = false
self.reloading = false
self.NormInfo = ""
self.count = 0
self.ExplodeTime = 0
self.ReloadTime = 0
self.CountTime = 0
self.Inputs = Wire_CreateInputs(self, { "Detonate", "ResetHealth" })
self:SetMaxHealth(100)
self:SetHealth(100)
self.Outputs = Wire_CreateOutputs(self, { "Health" })
end
function ENT:TriggerInput(iname, value)
if (iname == "Detonate") then
if ( !self.exploding && !self.reloading ) then
if ( math.abs(value) == self.key ) then
self:Trigger()
end
end
elseif (iname == "ResetHealth") then
self:ResetHealth()
end
end
function ENT:Setup( key, damage, delaytime, removeafter, radius, affectother, notaffected, delayreloadtime, maxhealth, bulletproof, explosionproof, fallproof, explodeatzero, resetatexplode, fireeffect, coloreffect, invisibleatzero )
self.key = key
self.Damage = math.Clamp( damage, 0, 1500 )
self.Delaytime = delaytime
self.Removeafter = removeafter
self.Radius = math.Clamp(radius, 1, wire_explosive_range:GetFloat())
self.Affectother = affectother
self.Notaffected = notaffected
self.Delayreloadtime = delayreloadtime
self.BulletProof = bulletproof
self.ExplosionProof = explosionproof
self.FallProof = fallproof
self.ExplodeAtZero = explodeatzero
self.ResetAtExplode = resetatexplode
self.FireEffect = fireeffect
self.ColorEffect = coloreffect
self.InvisibleAtZero = invisibleatzero
self:SetMaxHealth(maxhealth)
self:ResetHealth()
--[[
self:SetHealth(maxhealth)
Wire_TriggerOutput(self, "Health", maxhealth)
reset everthing back and try to stop exploding
self.exploding = false
self.reloading = false
self.count = 0
self:Extinguish()
if (self.ColorEffect) then self:SetColor(Color(255, 255, 255, 255)) end
]]
self.NormInfo = ""
if (self.Damage > 0) then self.NormInfo = self.NormInfo.."Damage: "..self.Damage end
if (self.Radius > 0 || self.Delaytime > 0) then self.NormInfo = self.NormInfo.."\n" end
if (self.Radius > 0 ) then self.NormInfo = self.NormInfo.." Rad: "..self.Radius end
if (self.Delaytime > 0) then self.NormInfo = self.NormInfo.." Delay: "..self.Delaytime end
self:ShowOutput()
local ttable = {
key = key,
damage = damage,
removeafter = removeafter,
delaytime = delaytime,
radius = radius,
affectother = affectother,
notaffected = notaffected,
delayreloadtime = delayreloadtime,
maxhealth = maxhealth,
bulletproof = bulletproof,
explosionproof = explosionproof,
fallproof = fallproof,
explodeatzero = explodeatzero,
resetatexplode = resetatexplode,
fireeffect = fireeffect,
coloreffect = coloreffect,
invisibleatzero = invisibleatzero
}
table.Merge( self:GetTable(), ttable )
end
function ENT:ResetHealth( )
self:SetHealth( self:GetMaxHealth() )
Wire_TriggerOutput(self, "Health", self:GetMaxHealth())
-- put the fires out and try to stop exploding
self.exploding = false
self.reloading = false
self.count = 0
self:Extinguish()
if (self.ColorEffect) then self:SetColor(Color(255, 255, 255, 255)) end
self:SetNoDraw( false )
self:ShowOutput()
end
function ENT:OnTakeDamage( dmginfo )
if ( dmginfo:GetInflictor():GetClass() == "gmod_wire_explosive" && !self.Affectother ) then return end
if ( !self.Notaffected ) then self:TakePhysicsDamage( dmginfo ) end
if (dmginfo:IsBulletDamage() && self.BulletProof) ||
(dmginfo:IsExplosionDamage() && self.ExplosionProof) ||
(dmginfo:IsFallDamage() && self.FallProof) then return end //fix fall damage, it doesn't happen
if (self:Health() > 0) then //don't need to beat a dead horse
local dammage = dmginfo:GetDamage()
local h = self:Health() - dammage
if (h < 0) then h = 0 end
self:SetHealth(h)
Wire_TriggerOutput(self, "Health", h)
self:ShowOutput()
if (self.ColorEffect) then
local c = h == 0 and 0 or 255 * (h / self:GetMaxHealth())
self:SetColor(Color(255, c, c, 255))
end
if (h == 0) then
if (self.ExplodeAtZero) then self:Trigger() end
end
end
end
-- Start exploding
function ENT:Trigger()
if ( self.Delaytime > 0 ) then
self.ExplodeTime = CurTime() + self.Delaytime
if (self.FireEffect) then self:Ignite((self.Delaytime + 3),0) end
end
self.exploding = true
// Force reset of counter
self.CountTime = 0
end
function ENT:Think()
BaseClass.Think(self)
if (self.exploding) then
if (self.ExplodeTime < CurTime()) then
self:Explode()
end
elseif (self.reloading) then
if (self.ReloadTime < CurTime()) then
self.reloading = false
if (self.ResetAtExplode) then
self:ResetHealth()
else
self:ShowOutput()
end
end
end
// Do count check to ensure that
// ShowOutput() is called every second
// when exploding or reloading
if ((self.CountTime or 0) < CurTime()) then
local temptime = 0
if (self.exploding) then
temptime = self.ExplodeTime
elseif (self.reloading) then
temptime = self.ReloadTime
end
if (temptime > 0) then
self.count = math.ceil(temptime - CurTime())
self:ShowOutput()
end
self.CountTime = CurTime() + 1
end
self:NextThink(CurTime() + 0.05)
return true
end
function ENT:Explode( )
if ( !self:IsValid() ) then return end
self:Extinguish()
if (!self.exploding) then return end //why are we exploding if we shouldn't be
local ply = self:GetPlayer() or self
if(not IsValid(ply)) then ply = self end;
if (self.InvisibleAtZero) then
self:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
self:SetNoDraw( true )
self:SetColor(Color(255, 255, 255, 0))
end
if ( self.Damage > 0 ) then
util.BlastDamage( self, ply, self:GetPos(), self.Radius, self.Damage )
end
local effectdata = EffectData()
effectdata:SetOrigin( self:GetPos() )
util.Effect( "Explosion", effectdata, true, true )
if ( self.Removeafter ) then
self:Remove()
return
end
self.exploding = false
self.reloading = true
self.ReloadTime = CurTime() + math.max(wire_explosive_delay:GetFloat(), self.Delayreloadtime)
// Force reset of counter
self.CountTime = 0
self:ShowOutput()
end
-- don't foreget to call this when changes happen
function ENT:ShowOutput( )
local txt = ""
if (self.reloading && self.Delayreloadtime > 0) then
txt = "Rearming... "..self.count
if (self.ColorEffect && !self.InvisibleAtZero) then
local c = 255 * ((self.Delayreloadtime - self.count) / self.Delayreloadtime)
self:SetColor(Color(255, c, c, 255))
end
if (self.InvisibleAtZero) then
self:SetNoDraw( false )
self:SetColor(Color(255, 255, 255, 255 * ((self.Delayreloadtime - self.count) / self.Delayreloadtime)))
self:SetRenderMode(RENDERMODE_TRANSALPHA)
end
elseif (self.exploding) then
txt = "Triggered... "..self.count
else
txt = self.NormInfo.."\nHealth: "..self:Health().."/"..self:GetMaxHealth()
end
self:SetOverlayText(txt)
end
duplicator.RegisterEntityClass( "gmod_wire_explosive", WireLib.MakeWireEnt, "Data", "key", "damage", "delaytime", "removeafter", "radius", "affectother", "notaffected", "delayreloadtime", "maxhealth", "bulletproof", "explosionproof", "fallproof", "explodeatzero", "resetatexplode", "fireeffect", "coloreffect", "invisibleatzero" )