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

237 lines
6.8 KiB
Lua

AddCSLuaFile()
DEFINE_BASECLASS( "base_wire_entity" )
ENT.PrintName = "Wire Balloon Deployer"
ENT.Author = "LuaPinapple"
ENT.Contact = "evilpineapple@cox.net"
ENT.Purpose = "It Deploys Balloons."
ENT.Instructions = "Use wire."
ENT.Category = "Wiremod"
ENT.Spawnable = true
ENT.AdminOnly = false
ENT.WireDebugName = "Balloon Deployer"
cleanup.Register("wire_deployers")
if CLIENT then
language.Add( "Cleanup_wire_deployers", "Balloon Deployers" )
language.Add( "Cleaned_wire_deployers", "Cleaned up Balloon Deployers" )
language.Add( "SBoxLimit_wire_deployers", "You have hit the Balloon Deployers limit!" )
return -- No more client
end
local material = "cable/rope"
local BalloonTypes =
{
Model("models/MaxOfS2D/balloon_classic.mdl"),
Model("models/balloons/balloon_classicheart.mdl"),
Model("models/balloons/balloon_dog.mdl"),
Model("models/balloons/balloon_star.mdl")
}
CreateConVar('sbox_maxwire_deployers', 2)
local DmgFilter
local function CreateDamageFilter()
if IsValid(DmgFilter) then return end
DmgFilter = ents.Create("filter_activator_name")
DmgFilter:SetKeyValue("targetname", "DmgFilter")
DmgFilter:SetKeyValue("negated", "1")
DmgFilter:Spawn()
end
hook.Add("InitPostEntity", "CreateDamageFilter", CreateDamageFilter)
local function MakeBalloonSpawner(pl, Data)
if IsValid(pl) and not pl:CheckLimit("wire_deployers") then return nil end
if Data.Model and not WireLib.CanModel(pl, Data.Model, Data.Skin) then return false end
local ent = ents.Create("sent_deployableballoons")
if not ent:IsValid() then return end
duplicator.DoGeneric(ent, Data)
ent:SetPlayer(pl)
ent:Spawn()
ent:Activate()
duplicator.DoGenericPhysics(ent, pl, Data)
if IsValid(pl) then
pl:AddCount("wire_deployers", ent)
pl:AddCleanup("wire_deployers", ent)
end
return ent
end
duplicator.RegisterEntityClass("sent_deployableballoons", MakeBalloonSpawner, "Data")
scripted_ents.Alias("gmod_iballoon", "gmod_balloon")
--Moves old "Lenght" input to new "Length" input for older dupes
WireLib.AddInputAlias( "Lenght", "Length" )
function ENT:SpawnFunction( ply, tr )
if (not tr.Hit) then return end
local SpawnPos = tr.HitPos+tr.HitNormal*16
local ent = MakeBalloonSpawner(ply, {Pos=SpawnPos})
return ent
end
function ENT:Initialize()
self:SetModel("models/props_junk/PropaneCanister001a.mdl")
self:PhysicsInit(SOLID_VPHYSICS)
self:SetMoveType( MOVETYPE_VPHYSICS )
self:SetSolid(SOLID_VPHYSICS)
self.Deployed = 0
self.Balloon = nil
self.Constraints = {}
self.force = 500
self.weld = false
self.popable = true
self.rl = 64
if WireAddon then
self.Inputs = Wire_CreateInputs(self,{ "Force", "Length", "Weld?", "Popable?", "BalloonType", "Deploy" })
self.Outputs=WireLib.CreateSpecialOutputs(self, { "Deployed", "BalloonEntity" }, {"NORMAL","ENTITY" })
Wire_TriggerOutput(self,"Deployed", self.Deployed)
--Wire_TriggerOutput(self,"Force", self.force)
end
local phys = self:GetPhysicsObject()
if(phys:IsValid()) then
phys:SetMass(250)
phys:Wake()
end
self:UpdateOverlay()
end
function ENT:TriggerInput(key,value)
if (key == "Deploy") then
if value ~= 0 then
if self.Deployed == 0 then
self:DeployBalloons()
self.Deployed = 1
end
Wire_TriggerOutput(self, "Deployed", self.Deployed)
else
if self.Deployed ~= 0 then
self:RetractBalloons()
self.Deployed = 0
end
Wire_TriggerOutput(self, "Deployed", self.Deployed)
end
elseif (key == "Force") then
self.force = value
if self.Deployed ~= 0 then
self.Balloon:SetForce(value)
end
elseif (key == "Length") then
self.rl = value
elseif (key == "Weld?") then
self.weld = value ~= 0
elseif (key == "Popable?") then
self.popable = value ~= 0
self:UpdatePopable()
elseif (key == "BalloonType") then
self.balloonType=value+1 --To correct for 1 based indexing
end
self:UpdateOverlay()
end
local balloon_registry = {}
hook.Add("EntityRemoved", "balloon_deployer", function(ent)
local deployer = balloon_registry[ent]
if IsValid(deployer) and deployer.TriggerInput then
deployer.Deployed = 0
deployer:TriggerInput("Deploy", 0)
end
end)
function ENT:UpdatePopable()
local balloon = self.Balloon
if balloon ~= nil and balloon:IsValid() then
if not self.popable then
balloon:Fire("setdamagefilter", "DmgFilter", 0);
else
balloon:Fire("setdamagefilter", "", 0);
end
end
end
function ENT:DeployBalloons()
local balloon
balloon = ents.Create("gmod_balloon") --normal balloon
local model = BalloonTypes[self.balloonType]
if(model==nil) then
model = BalloonTypes[1]
end
balloon:SetModel(model)
balloon:Spawn()
balloon:SetColor(Color(math.random(0,255), math.random(0,255), math.random(0,255), 255))
balloon:SetForce(self.force)
balloon:SetMaterial("models/balloon/balloon")
balloon:SetPlayer(self:GetPlayer())
duplicator.DoGeneric(balloon,{Pos = self:GetPos() + (self:GetUp()*25)})
duplicator.DoGenericPhysics(balloon,pl,{Pos = Pos})
local balloonPos = balloon:GetPos() -- the origin the balloon is at the bottom
local hitEntity = self
local hitPos = self:LocalToWorld(Vector(0, 0, self:OBBMaxs().z)) -- the top of the spawner
-- We trace from the balloon to us, and if there's anything in the way, we
-- attach a constraint to that instead - that way, the balloon spawner can
-- be hidden underneath a plate which magically gets balloons attached to it.
local balloonToSpawner = (hitPos - balloonPos):GetNormalized() * 250
local trace = util.QuickTrace(balloon:GetPos(), balloonToSpawner, balloon)
if constraint.CanConstrain(trace.Entity, trace.PhysicsBone) then
local phys = trace.Entity:GetPhysicsObjectNum(trace.PhysicsBone)
if IsValid(phys) then
hitEntity = trace.Entity
hitPos = trace.HitPos
end
end
if self.weld then
local constraint = constraint.Weld( balloon, hitEntity, 0, trace.PhysicsBone, 0)
balloon:DeleteOnRemove(constraint)
else
balloonPos = balloon:WorldToLocal(balloonPos)
hitPos = hitEntity:WorldToLocal(hitPos)
local constraint, rope = constraint.Rope(
balloon, hitEntity, 0, trace.PhysicsBone, balloonPos, hitPos,
0, self.rl, 0, 1.5, material, false)
if constraint then
balloon:DeleteOnRemove(constraint)
balloon:DeleteOnRemove(rope)
end
end
self:DeleteOnRemove(balloon)
self.Balloon = balloon
self:UpdatePopable()
balloon_registry[balloon] = self
Wire_TriggerOutput(self, "BalloonEntity", self.Balloon)
end
function ENT:OnRemove()
if self.Balloon then
balloon_registry[self.Balloon] = nil
end
Wire_Remove(self)
end
function ENT:RetractBalloons()
if self.Balloon:IsValid() then
local c = self.Balloon:GetColor()
local effectdata = EffectData()
effectdata:SetOrigin( self.Balloon:GetPos() )
effectdata:SetStart( Vector(c.r,c.g,c.b) )
util.Effect( "balloon_pop", effectdata )
self.Balloon:Remove()
else
self.Balloon = nil
end
end
function ENT:UpdateOverlay()
self:SetOverlayText( "Deployed = " .. ((self.Deployed ~= 0) and "yes" or "no") )
end