You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Assets/Engine/Scripts/Entities/Particle/ParticleEffect.lua

306 lines
9.2 KiB
Lua

----------------------------------------------------------------------------------------------------
--
-- Copyright (c) Contributors to the Open 3D Engine Project.
-- For complete copyright and license terms please see the LICENSE at the root of this distribution.
--
-- SPDX-License-Identifier: Apache-2.0 OR MIT
--
--
--
----------------------------------------------------------------------------------------------------
ParticleEffect = {
Properties = {
soclasses_SmartObjectClass = "",
ParticleEffect="",
Comment="",
bActive=1, -- Activate on startup
bPrime=1, -- Starts in equilibrium state, as if activated in past
Scale=1, -- Scale entire effect size.
SpeedScale=1, -- Scale particle emission speed
TimeScale=1, -- Scale emitter time evolution
CountScale=1, -- Scale particle counts.
bCountPerUnit=0, -- Multiply count by attachment extent
Strength=-1, -- Custom param control
esAttachType="", -- BoundingBox, Physics, Render
esAttachForm="", -- Vertices, Edges, Surface, Volume
PulsePeriod=0, -- Restart continually at this period.
NetworkSync=0, -- Do I want to be bound to the network?
bRegisterByBBox=0, -- Register In VisArea by BoundingBox, not by Position
Audio =
{
bEnableAudio=0, -- Toggles update of audio data.
audioRTPCRtpc="particlefx", -- The default audio RTPC name used.
}
},
Editor = {
Model="Editor/Objects/Particles.cgf",
Icon="Particles.bmp",
},
States = { "Active","Idle" },
Client = {},
Server = {},
};
Net.Expose {
Class = ParticleEffect,
ClientMethods = {
ClEvent_Spawn = { RELIABLE_ORDERED, POST_ATTACH },
ClEvent_Enable = { RELIABLE_ORDERED, POST_ATTACH },
ClEvent_Disable = { RELIABLE_ORDERED, POST_ATTACH },
ClEvent_Restart = { RELIABLE_ORDERED, POST_ATTACH },
ClEvent_Kill = { RELIABLE_ORDERED, POST_ATTACH },
},
ServerMethods = {
},
ServerProperties = {
},
};
-------------------------------------------------------
function ParticleEffect:OnSpawn()
if (not table.NetworkSync) then
self:SetFlags(ENTITY_FLAG_CLIENT_ONLY, 0);
end
end
-------------------------------------------------------
function ParticleEffect:OnLoad(table)
self:GotoState(""); -- forces execution of either "Idle" or "Active" state constructor
if (not table.nParticleSlot) then
if (self.nParticleSlot) then
self:DeleteParticleEmitter( self.nParticleSlot );
end
self:GotoState("Idle");
elseif (not self.nParticleSlot or self.nParticleSlot ~= table.nParticleSlot) then
if (self.nParticleSlot) then
self:DeleteParticleEmitter( self.nParticleSlot );
end
self:GotoState("Idle");
self.nParticleSlot = self:LoadParticleEffect( table.nParticleSlot, self.Properties.ParticleEffect, self.Properties );
self:GotoState("Active");
end
end
-------------------------------------------------------
function ParticleEffect:OnSave(table)
table.nParticleSlot = self.nParticleSlot;
end
-------------------------------------------------------
function ParticleEffect:OnPropertyChange()
if self.Properties.bActive ~= 0 then
self:GotoState( "" );
self:GotoState( "Active" );
else
self:GotoState( "Idle" );
end
end
-------------------------------------------------------
function ParticleEffect:OnReset()
self:GotoState( "Idle" );
if self.Properties.bActive ~= 0 then
self:GotoState( "Active" );
end
end
------------------------------------------------------------------------------------------------------
function ParticleEffect:Event_Enable()
self:GotoState( "Active" );
self:ActivateOutput( "Enable", true );
if CryAction.IsServer() and self.allClients then
self.allClients:ClEvent_Enable();
end
end
function ParticleEffect:Event_Disable()
self:GotoState( "Idle" );
self:ActivateOutput( "Disable", true );
if CryAction.IsServer() and self.allClients then
self.allClients:ClEvent_Disable();
end
end
function ParticleEffect:Event_Restart()
self:GotoState( "Idle" );
self:GotoState( "Active" );
self:ActivateOutput( "Restart", true );
if CryAction.IsServer() and self.allClients then
self.allClients:ClEvent_Restart();
end
end
function ParticleEffect:Event_Spawn()
self:GetDirectionVector(1, g_Vectors.temp_v2); -- 1=forward vector
Particle.SpawnEffect( self.Properties.ParticleEffect, self:GetPos(g_Vectors.temp_v1), g_Vectors.temp_v2, self.Properties.Scale );
self:ActivateOutput( "Spawn", true );
if CryAction.IsServer() and self.allClients then
self.allClients:ClEvent_Spawn();
end
end
function ParticleEffect:Event_Kill()
if (self.nParticleSlot) then
self:DeleteParticleEmitter(self.nParticleSlot);
end;
self:GotoState( "Idle" );
if CryAction.IsServer() and self.allClients then
self.allClients:ClEvent_Kill();
end
end
function ParticleEffect:Enable()
self:GotoState("Active");
if CryAction.IsServer() and self.allClients then
self.allClients:ClEvent_Enable();
end
end
function ParticleEffect:Disable()
self:GotoState("Idle");
if CryAction.IsServer() and self.allClients then
self.allClients:ClEvent_Disable();
end
end
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-- Active State
-------------------------------------------------------------------------------
ParticleEffect.Active =
{
OnBeginState = function( self )
if not self.nParticleSlot then
self.nParticleSlot = -1;
end
self.nParticleSlot = self:LoadParticleEffect( self.nParticleSlot, self.Properties.ParticleEffect, self.Properties );
end,
OnLeaveArea = function( self,entity,areaId )
self:GotoState( "Idle" );
end,
}
-------------------------------------------------------------------------------
-- Idle State
-------------------------------------------------------------------------------
ParticleEffect.Idle =
{
OnBeginState = function( self )
if self.nParticleSlot then
self:FreeSlot(self.nParticleSlot);
self.nParticleSlot = nil;
end
end,
OnEnterArea = function( self,entity,areaId )
self:GotoState( "Active" );
end,
}
-- !!! net and states stuff
function ParticleEffect:DefaultState(cs, state)
local default = self[state];
self[cs][state] = {
OnBeginState = default.OnBeginState,
OnEndState = default.OnEndState,
OnLeaveArea = default.OnLeaveArea,
OnEnterArea = default.OnEnterArea,
}
end
-------------------------------------------------------
ParticleEffect:DefaultState("Server", "Idle");
ParticleEffect:DefaultState("Server", "Active");
ParticleEffect:DefaultState("Client", "Idle");
ParticleEffect:DefaultState("Client", "Active");
-------------------------------------------------------
ParticleEffect.FlowEvents =
{
Inputs =
{
Disable = { ParticleEffect.Event_Disable, "bool" },
Enable = { ParticleEffect.Event_Enable, "bool" },
Restart = { ParticleEffect.Event_Restart, "bool" },
Spawn = { ParticleEffect.Event_Spawn, "bool" },
Kill = { ParticleEffect.Event_Kill, "bool" },
},
Outputs =
{
Disable = "bool",
Enable = "bool",
Restart = "bool",
Spawn = "bool",
},
}
-------------------------------------------------------
-- client functions
-------------------------------------------------------
-------------------------------------------------------
function ParticleEffect.Client:OnInit()
self:SetRegisterInSectors(1);
self.Properties.ParticleEffect = self:PreLoadParticleEffect( self.Properties.ParticleEffect );
self:SetUpdatePolicy(ENTITY_UPDATE_POT_VISIBLE);
--self:SetFlags(ENTITY_FLAG_CLIENT_ONLY, 0);
if (self.Properties.bActive ~= 0) then
self:GotoState( "Active" );
else
self:GotoState( "Idle" );
end
--self:NetPresent(nil);
end
-------------------------------------------------------
function ParticleEffect.Client:ClEvent_Spawn()
if( not CryAction.IsServer() ) then
self:Event_Spawn();
end
end
-------------------------------------------------------
function ParticleEffect.Client:ClEvent_Enable()
if( not CryAction.IsServer() ) then
self:Event_Enable();
end
end
-------------------------------------------------------
function ParticleEffect.Client:ClEvent_Disable()
if( not CryAction.IsServer() ) then
self:Event_Disable();
end
end
-------------------------------------------------------
function ParticleEffect.Client:ClEvent_Restart()
if( not CryAction.IsServer() ) then
self:Event_Restart();
end
end
-------------------------------------------------------
function ParticleEffect.Client:ClEvent_Kill()
if( not CryAction.IsServer() ) then
self:Event_Kill();
end
end