mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-18 14:13:46 +03:00
Upload
This commit is contained in:
227
lua/pac3/core/client/parts/effect.lua
Normal file
227
lua/pac3/core/client/parts/effect.lua
Normal file
@@ -0,0 +1,227 @@
|
||||
--[[
|
||||
| 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/
|
||||
--]]
|
||||
|
||||
local CurTime = CurTime
|
||||
local ParticleEffect = ParticleEffect
|
||||
|
||||
local BUILDER, PART = pac.PartTemplate("base_drawable")
|
||||
|
||||
PART.ClassName = "effect"
|
||||
PART.Groups = {'effects', 'model', 'entity'}
|
||||
PART.Icon = 'icon16/wand.png'
|
||||
|
||||
BUILDER:StartStorableVars()
|
||||
BUILDER:GetSet("Effect", "default", {enums = function() return pac.particle_list end})
|
||||
BUILDER:GetSet("Loop", true)
|
||||
BUILDER:GetSet("Follow", true)
|
||||
BUILDER:GetSet("Rate", 1, {editor_sensitivity = 0.1})
|
||||
BUILDER:GetSet("UseParticleTracer", false)
|
||||
|
||||
BUILDER:GetSetPart("PointA")
|
||||
BUILDER:GetSetPart("PointB")
|
||||
BUILDER:GetSetPart("PointC")
|
||||
BUILDER:GetSetPart("PointD")
|
||||
|
||||
BUILDER:EndStorableVars()
|
||||
|
||||
BUILDER:RemoveProperty("Translucent")
|
||||
PART.Translucent = false -- otherwise OnDraw won't be called
|
||||
|
||||
local BaseClass_GetOwner = PART.GetOwner
|
||||
|
||||
function PART:GetNiceName()
|
||||
return pac.PrettifyName(self:GetEffect())
|
||||
end
|
||||
|
||||
function PART:Initialize()
|
||||
self:SetEffect(self.Effect)
|
||||
|
||||
if not pac.particle_list then
|
||||
local found = {}
|
||||
|
||||
for file_name in pairs(pac_loaded_particle_effects) do
|
||||
local ok, err = pcall(function()
|
||||
local data = file.Read("particles/"..file_name, "GAME", "b")
|
||||
if data then
|
||||
for str in data:gmatch("\3%c([%a_]+)%c") do
|
||||
if #str > 1 then
|
||||
found[str] = str
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if not ok then
|
||||
local msg = "unable to parse particle file " .. file_name .. ": " .. err
|
||||
self:SetError(msg)
|
||||
pac.Message(Color(255, 50, 50), msg)
|
||||
end
|
||||
end
|
||||
|
||||
pac.particle_list = found
|
||||
end
|
||||
end
|
||||
|
||||
PART.last_spew = 0
|
||||
|
||||
if not pac_loaded_particle_effects then
|
||||
pac_loaded_particle_effects = {}
|
||||
|
||||
for _, file_name in pairs(file.Find("particles/*.pcf", "GAME")) do
|
||||
if not pac_loaded_particle_effects[file_name] and not pac.BlacklistedParticleSystems[file_name:lower()] then
|
||||
game.AddParticles("particles/" .. file_name)
|
||||
end
|
||||
|
||||
pac_loaded_particle_effects[file_name] = true
|
||||
end
|
||||
end
|
||||
|
||||
local already = {}
|
||||
local alreadyServer = {}
|
||||
local function pac_request_precache(name)
|
||||
if already[name] then return end
|
||||
already[name] = true
|
||||
PrecacheParticleSystem(name)
|
||||
net.Start("pac_request_precache")
|
||||
net.WriteString(name)
|
||||
net.SendToServer()
|
||||
end
|
||||
|
||||
function PART:SetEffect(name)
|
||||
self.waitingForServer = true
|
||||
self.Effect = name
|
||||
self.Ready = alreadyServer[name] or false
|
||||
|
||||
if not alreadyServer[name] then
|
||||
pac_request_precache(name)
|
||||
else
|
||||
self.waitingForServer = false
|
||||
end
|
||||
end
|
||||
|
||||
pac.AddHook("pac_EffectPrecached", "pac_Effects", function(name)
|
||||
if alreadyServer[name] then return end
|
||||
alreadyServer[name] = true
|
||||
pac.dprint("effect %q precached!", name)
|
||||
pac.CallRecursiveOnAllParts("OnEffectPrecached", name)
|
||||
end)
|
||||
|
||||
function PART:OnEffectPrecached(name)
|
||||
if self.Effect == name then
|
||||
self.Ready = true
|
||||
self.waitingForServer = false
|
||||
end
|
||||
end
|
||||
|
||||
function PART:OnDraw()
|
||||
if not self.Ready then
|
||||
if not self.waitingForServer then
|
||||
self:SetEffect(self.Effect)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local ent = self:GetOwner()
|
||||
|
||||
if ent:IsValid() and self.Loop then
|
||||
local time = CurTime()
|
||||
if self.last_spew < time then
|
||||
local pos, ang = self:GetDrawPosition()
|
||||
|
||||
ent:StopParticles()
|
||||
ent:StopParticleEmission()
|
||||
self:Emit(pos, ang)
|
||||
self.last_spew = time + math.max(self.Rate, 0.1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PART:OnHide()
|
||||
local ent = self:GetOwner()
|
||||
|
||||
if ent:IsValid() then
|
||||
ent:StopParticles()
|
||||
ent:StopParticleEmission()
|
||||
end
|
||||
end
|
||||
|
||||
function PART:OnShow(from_rendering)
|
||||
if from_rendering then
|
||||
self:Emit(self:GetDrawPosition())
|
||||
end
|
||||
end
|
||||
|
||||
function PART:Emit(pos, ang)
|
||||
local ent = self:GetOwner()
|
||||
|
||||
if ent:IsValid() then
|
||||
if not self.Effect then
|
||||
ent:StopParticles()
|
||||
ent:StopParticleEmission()
|
||||
return
|
||||
end
|
||||
|
||||
if self.UseParticleTracer and self.PointA:IsValid() then
|
||||
local ent2 = self.PointA.Entity and self.PointA.Entity or self.PointA:GetOwner()
|
||||
|
||||
util.ParticleTracerEx(
|
||||
self.Effect,
|
||||
ent:GetPos(),
|
||||
ent2:GetPos(),
|
||||
true,
|
||||
ent:EntIndex(),
|
||||
0
|
||||
)
|
||||
return
|
||||
end
|
||||
|
||||
if self.PointA:IsValid() then
|
||||
local points = {}
|
||||
|
||||
table.insert(points, {
|
||||
entity = self.PointA.Entity and self.PointA.Entity or self.PointA:GetOwner(),
|
||||
attachtype = PATTACH_ABSORIGIN_FOLLOW,
|
||||
})
|
||||
|
||||
if self.PointB:IsValid() then
|
||||
table.insert(points, {
|
||||
entity = self.PointB.Entity and self.PointB.Entity or self.PointB:GetOwner(),
|
||||
attachtype = PATTACH_ABSORIGIN_FOLLOW,
|
||||
})
|
||||
end
|
||||
|
||||
if self.PointC:IsValid() then
|
||||
table.insert(points, {
|
||||
entity = self.PointC.Entity and self.PointC.Entity or self.PointC:GetOwner(),
|
||||
attachtype = PATTACH_ABSORIGIN_FOLLOW,
|
||||
})
|
||||
end
|
||||
|
||||
if self.PointD:IsValid() then
|
||||
table.insert(points, {
|
||||
entity = self.PointD.Entity and self.PointD.Entity or self.PointD:GetOwner(),
|
||||
attachtype = PATTACH_ABSORIGIN_FOLLOW,
|
||||
})
|
||||
end
|
||||
|
||||
ent:CreateParticleEffect(self.Effect, points)
|
||||
elseif self.Follow then
|
||||
ent:StopParticles()
|
||||
ent:StopParticleEmission()
|
||||
CreateParticleSystem(ent, self.Effect, PATTACH_ABSORIGIN_FOLLOW, 0)
|
||||
else
|
||||
ent:StopParticles()
|
||||
ent:StopParticleEmission()
|
||||
ParticleEffect(self.Effect, pos, ang, ent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
BUILDER:Register()
|
||||
Reference in New Issue
Block a user