mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
376 lines
10 KiB
Lua
376 lines
10 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/
|
|
--]]
|
|
|
|
local cam_IgnoreZ = cam.IgnoreZ
|
|
local vector_origin = vector_origin
|
|
local FrameTime = FrameTime
|
|
local angle_origin = Angle(0,0,0)
|
|
local WorldToLocal = WorldToLocal
|
|
|
|
local BUILDER, PART = pac.PartTemplate("base_drawable")
|
|
|
|
PART.ClassName = "particles"
|
|
PART.Group = 'effects'
|
|
PART.Icon = 'icon16/water.png'
|
|
|
|
BUILDER:StartStorableVars()
|
|
BUILDER:SetPropertyGroup("generic")
|
|
BUILDER:PropertyOrder("Name")
|
|
BUILDER:PropertyOrder("Hide")
|
|
BUILDER:PropertyOrder("ParentName")
|
|
BUILDER:GetSet("Follow", false)
|
|
BUILDER:GetSet("Additive", false)
|
|
BUILDER:GetSet("FireOnce", false)
|
|
BUILDER:GetSet("FireDelay", 0.2)
|
|
BUILDER:GetSet("NumberParticles", 1)
|
|
BUILDER:GetSet("PositionSpread", 0)
|
|
BUILDER:GetSet("PositionSpread2", Vector(0,0,0))
|
|
BUILDER:GetSet("DieTime", 3)
|
|
BUILDER:GetSet("StartSize", 2)
|
|
BUILDER:GetSet("EndSize", 20)
|
|
BUILDER:GetSet("StartLength", 0)
|
|
BUILDER:GetSet("EndLength", 0)
|
|
BUILDER:GetSet("ParticleAngle", Angle(0,0,0))
|
|
BUILDER:GetSet("AddFrametimeLife", false)
|
|
BUILDER:SetPropertyGroup("stick")
|
|
BUILDER:GetSet("AlignToSurface", true)
|
|
BUILDER:GetSet("StickToSurface", true)
|
|
BUILDER:GetSet("StickLifetime", 2)
|
|
BUILDER:GetSet("StickStartSize", 20)
|
|
BUILDER:GetSet("StickEndSize", 0)
|
|
BUILDER:GetSet("StickStartAlpha", 255)
|
|
BUILDER:GetSet("StickEndAlpha", 0)
|
|
BUILDER:SetPropertyGroup("appearance")
|
|
BUILDER:GetSet("Material", "effects/slime1")
|
|
BUILDER:GetSet("StartAlpha", 255)
|
|
BUILDER:GetSet("EndAlpha", 0)
|
|
BUILDER:GetSet("Translucent", true)
|
|
BUILDER:GetSet("Color2", Vector(255, 255, 255), {editor_panel = "color"})
|
|
BUILDER:GetSet("Color1", Vector(255, 255, 255), {editor_panel = "color"})
|
|
BUILDER:GetSet("RandomColor", false)
|
|
BUILDER:GetSet("Lighting", true)
|
|
BUILDER:GetSet("3D", false)
|
|
BUILDER:GetSet("DoubleSided", true)
|
|
BUILDER:GetSet("DrawManual", false)
|
|
BUILDER:SetPropertyGroup("rotation")
|
|
BUILDER:GetSet("ZeroAngle",true)
|
|
BUILDER:GetSet("RandomRollSpeed", 0)
|
|
BUILDER:GetSet("RollDelta", 0)
|
|
BUILDER:GetSet("ParticleAngleVelocity", Vector(50, 50, 50))
|
|
BUILDER:SetPropertyGroup("orientation")
|
|
BUILDER:SetPropertyGroup("movement")
|
|
BUILDER:GetSet("Velocity", 250)
|
|
BUILDER:GetSet("Spread", 0.1)
|
|
BUILDER:GetSet("AirResistance", 5)
|
|
BUILDER:GetSet("Bounce", 5)
|
|
BUILDER:GetSet("Gravity", Vector(0,0, -50))
|
|
BUILDER:GetSet("Collide", true)
|
|
BUILDER:GetSet("Sliding", true)
|
|
--BUILDER:GetSet("AddVelocityFromOwner", false)
|
|
BUILDER:GetSet("OwnerVelocityMultiplier", 0)
|
|
|
|
|
|
|
|
|
|
BUILDER:EndStorableVars()
|
|
|
|
function PART:GetNiceName()
|
|
return pac.PrettifyName(("/".. self:GetMaterial()):match(".+/(.+)")) or "error"
|
|
end
|
|
|
|
local function RemoveCallback(particle)
|
|
particle:SetLifeTime(0)
|
|
particle:SetDieTime(0)
|
|
|
|
particle:SetStartSize(0)
|
|
particle:SetEndSize(0)
|
|
|
|
particle:SetStartAlpha(0)
|
|
particle:SetEndAlpha(0)
|
|
end
|
|
|
|
local function SlideCallback(particle, hitpos, normal)
|
|
particle:SetBounce(1)
|
|
local vel = particle:GetVelocity()
|
|
vel.z = 0
|
|
particle:SetVelocity(vel)
|
|
particle:SetPos(hitpos + normal)
|
|
end
|
|
|
|
local function StickCallback(particle, hitpos, normal)
|
|
particle:SetAngleVelocity(Angle(0, 0, 0))
|
|
|
|
if particle.Align then
|
|
local ang = normal:Angle()
|
|
ang:RotateAroundAxis(normal, particle:GetAngles().y)
|
|
particle:SetAngles(ang)
|
|
end
|
|
|
|
if particle.Stick then
|
|
particle:SetVelocity(Vector(0, 0, 0))
|
|
particle:SetGravity(Vector(0, 0, 0))
|
|
end
|
|
|
|
particle:SetLifeTime(0)
|
|
particle:SetDieTime(particle.StickLifeTime or 0)
|
|
|
|
particle:SetStartSize(particle.StickStartSize or 0)
|
|
particle:SetEndSize(particle.StickEndSize or 0)
|
|
|
|
particle:SetStartAlpha(particle.StickStartAlpha or 0)
|
|
particle:SetEndAlpha(particle.StickEndAlpha or 0)
|
|
end
|
|
|
|
function PART:GetEmitter()
|
|
if not self.emitter then
|
|
self.NextShot = 0
|
|
self.Created = pac.RealTime + 0.1
|
|
self.emitter = ParticleEmitter(vector_origin, self:Get3D())
|
|
end
|
|
|
|
return self.emitter
|
|
end
|
|
|
|
function PART:SetDrawManual(b)
|
|
self.DrawManual = b
|
|
self:GetEmitter():SetNoDraw(b)
|
|
end
|
|
|
|
function PART:SetNumberParticles(num)
|
|
self.NumberParticles = math.Clamp(num, 0, 100)
|
|
end
|
|
|
|
function PART:Set3D(b)
|
|
self["3D"] = b
|
|
self.emitter = nil
|
|
end
|
|
|
|
function PART:OnShow(from_rendering)
|
|
self.CanKeepFiring = true
|
|
self.FirstShot = true
|
|
if not from_rendering then
|
|
self.NextShot = 0
|
|
local pos, ang = self:GetDrawPosition()
|
|
self:EmitParticles(self.Follow and vector_origin or pos, self.Follow and angle_origin or ang, ang)
|
|
end
|
|
end
|
|
|
|
function PART:OnDraw()
|
|
if not self.FireOnce then self.CanKeepFiring = true end
|
|
local pos, ang = self:GetDrawPosition()
|
|
local emitter = self:GetEmitter()
|
|
|
|
emitter:SetPos(pos)
|
|
if self.DrawManual or self.IgnoreZ or self.Follow or self.BlendMode ~= "" then
|
|
|
|
if not self.nodraw then
|
|
emitter:SetNoDraw(true)
|
|
self.nodraw = true
|
|
end
|
|
|
|
if self.Follow then
|
|
cam.Start3D(WorldToLocal(EyePos(), EyeAngles(), pos, ang))
|
|
if self.IgnoreZ then cam.IgnoreZ(true) end
|
|
emitter:Draw()
|
|
if self.IgnoreZ then cam.IgnoreZ(false) end
|
|
cam.End3D()
|
|
else
|
|
emitter:Draw()
|
|
end
|
|
else
|
|
if self.nodraw then
|
|
self:SetDrawManual(self:GetDrawManual())
|
|
self.nodraw = false
|
|
end
|
|
end
|
|
self:EmitParticles(self.Follow and vector_origin or pos, self.Follow and angle_origin or ang, ang)
|
|
end
|
|
|
|
function PART:SetAdditive(b)
|
|
self.Additive = b
|
|
|
|
self:SetMaterial(self:GetMaterial())
|
|
end
|
|
|
|
function PART:SetMaterial(var)
|
|
var = var or ""
|
|
|
|
if not pac.Handleurltex(self, var, function(mat)
|
|
mat:SetFloat("$alpha", 0.999)
|
|
mat:SetInt("$spriterendermode", self.Additive and 5 or 1)
|
|
self.Materialm = mat
|
|
self:CallRecursive("OnMaterialChanged")
|
|
end, "Sprite") then
|
|
if var == "" then
|
|
self.Materialm = nil
|
|
else
|
|
self.Materialm = pac.Material(var, self)
|
|
self:CallRecursive("OnMaterialChanged")
|
|
end
|
|
end
|
|
|
|
self.Material = var
|
|
end
|
|
|
|
function PART:EmitParticles(pos, ang, real_ang)
|
|
if self.FireOnce and not self.FirstShot then self.CanKeepFiring = false end
|
|
local emt = self:GetEmitter()
|
|
if not emt then return end
|
|
|
|
if self.NextShot < pac.RealTime and self.CanKeepFiring then
|
|
if self.Material == "" then return end
|
|
if self.Velocity == 500.01 then return end
|
|
|
|
local originalAng = ang
|
|
ang = ang:Forward()
|
|
|
|
local double = 1
|
|
if self.DoubleSided then
|
|
double = 2
|
|
end
|
|
|
|
for _ = 1, self.NumberParticles do
|
|
local mats = self.Material:Split(";")
|
|
if #mats > 1 then
|
|
self.Materialm = pac.Material(table.Random(mats), self)
|
|
self:CallRecursive("OnMaterialChanged")
|
|
end
|
|
local vec = Vector()
|
|
|
|
if self.Spread ~= 0 then
|
|
vec = Vector(
|
|
math.sin(math.Rand(0, 360)) * math.Rand(-self.Spread, self.Spread),
|
|
math.cos(math.Rand(0, 360)) * math.Rand(-self.Spread, self.Spread),
|
|
math.sin(math.random()) * math.Rand(-self.Spread, self.Spread)
|
|
)
|
|
end
|
|
|
|
local color
|
|
|
|
if self.RandomColor then
|
|
color =
|
|
{
|
|
math.random(math.min(self.Color1.r, self.Color2.r), math.max(self.Color1.r, self.Color2.r)),
|
|
math.random(math.min(self.Color1.g, self.Color2.g), math.max(self.Color1.g, self.Color2.g)),
|
|
math.random(math.min(self.Color1.b, self.Color2.b), math.max(self.Color1.b, self.Color2.b))
|
|
}
|
|
else
|
|
color = {self.Color1.r, self.Color1.g, self.Color1.b}
|
|
end
|
|
|
|
local roll = math.Rand(-self.RollDelta, self.RollDelta)
|
|
|
|
if self.PositionSpread ~= 0 then
|
|
pos = pos + Angle(math.Rand(-180, 180), math.Rand(-180, 180), math.Rand(-180, 180)):Forward() * self.PositionSpread
|
|
end
|
|
|
|
do
|
|
local vecAdd = Vector(
|
|
math.Rand(-self.PositionSpread2.x, self.PositionSpread2.x),
|
|
math.Rand(-self.PositionSpread2.x, self.PositionSpread2.y),
|
|
math.Rand(-self.PositionSpread2.z, self.PositionSpread2.z)
|
|
)
|
|
vecAdd:Rotate(originalAng)
|
|
pos = pos + vecAdd
|
|
end
|
|
|
|
for i = 1, double do
|
|
local particle = emt:Add(self.Materialm or self.Material, pos)
|
|
|
|
if double == 2 then
|
|
local ang_
|
|
if i == 1 then
|
|
ang_ = (ang * -1):Angle()
|
|
elseif i == 2 then
|
|
ang_ = ang:Angle()
|
|
end
|
|
|
|
particle:SetAngles(ang_)
|
|
else
|
|
particle:SetAngles(ang:Angle())
|
|
end
|
|
|
|
if self.OwnerVelocityMultiplier ~= 0 then
|
|
local owner = self:GetRootPart():GetOwner()
|
|
if owner:IsValid() then
|
|
vec = vec + (owner:GetVelocity() * self.OwnerVelocityMultiplier)
|
|
end
|
|
end
|
|
|
|
particle:SetVelocity((vec + ang) * self.Velocity)
|
|
particle:SetColor(unpack(color))
|
|
particle:SetColor(unpack(color))
|
|
|
|
local life = math.Clamp(self.DieTime, 0.0001, 50)
|
|
if self.AddFrametimeLife then
|
|
life = life + FrameTime()
|
|
end
|
|
particle:SetDieTime(life)
|
|
|
|
particle:SetStartAlpha(self.StartAlpha)
|
|
particle:SetEndAlpha(self.EndAlpha)
|
|
particle:SetStartSize(self.StartSize)
|
|
particle:SetEndSize(self.EndSize)
|
|
particle:SetStartLength(self.StartLength)
|
|
particle:SetEndLength(self.EndLength)
|
|
|
|
if self.RandomRollSpeed ~= 0 then
|
|
particle:SetRoll(self.RandomRollSpeed * 36)
|
|
end
|
|
|
|
if self.RollDelta ~= 0 then
|
|
particle:SetRollDelta(self.RollDelta + roll)
|
|
end
|
|
|
|
particle:SetAirResistance(self.AirResistance)
|
|
particle:SetBounce(self.Bounce)
|
|
particle:SetGravity(self.Gravity)
|
|
if self.ZeroAngle then particle:SetAngles(Angle(0,0,0))
|
|
else particle:SetAngles(particle:GetAngles() + self.ParticleAngle) end
|
|
particle:SetLighting(self.Lighting)
|
|
|
|
if not self.Follow then
|
|
particle:SetCollide(self.Collide)
|
|
end
|
|
|
|
if self.Sliding then
|
|
particle:SetCollideCallback(SlideCallback)
|
|
end
|
|
|
|
if self["3D"] then
|
|
if not self.Sliding then
|
|
if i == 1 then
|
|
particle:SetCollideCallback(RemoveCallback)
|
|
else
|
|
particle:SetCollideCallback(StickCallback)
|
|
end
|
|
end
|
|
|
|
particle:SetAngleVelocity(Angle(self.ParticleAngleVelocity.x, self.ParticleAngleVelocity.y, self.ParticleAngleVelocity.z))
|
|
|
|
particle.Align = self.Align
|
|
particle.Stick = self.Stick
|
|
particle.StickLifeTime = self.StickLifeTime
|
|
particle.StickStartSize = self.StickStartSize
|
|
particle.StickEndSize = self.StickEndSize
|
|
particle.StickStartAlpha = self.StickStartAlpha
|
|
particle.StickEndAlpha = self.StickEndAlpha
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
self.NextShot = pac.RealTime + self.FireDelay
|
|
end
|
|
self.FirstShot = false
|
|
end
|
|
|
|
BUILDER:Register()
|