mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-12-27 07:54:51 +01:00
263 lines
6.9 KiB
Erlang
263 lines
6.9 KiB
Erlang
|
/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
|
||
|
|
||
|
607
|
||
|
%{
|
||
|
#include "StdH.h"
|
||
|
#include "EntitiesMP/BackgroundViewer.h"
|
||
|
#include "EntitiesMP/WorldSettingsController.h"
|
||
|
#include "EntitiesMP/Light.h"
|
||
|
%}
|
||
|
|
||
|
%{
|
||
|
struct ThunderInfo
|
||
|
{
|
||
|
INDEX ti_iSound;
|
||
|
FLOAT ti_fThunderStrikeDelay;
|
||
|
};
|
||
|
|
||
|
struct ThunderInfo _atiThunderSounds[3] =
|
||
|
{
|
||
|
{ SOUND_THUNDER1, 0.6f},
|
||
|
{ SOUND_THUNDER2, 0.0f},
|
||
|
{ SOUND_THUNDER3, 0.0f},
|
||
|
};
|
||
|
%}
|
||
|
|
||
|
class CLightning: CMovableModelEntity {
|
||
|
name "Lightning";
|
||
|
thumbnail "Thumbnails\\Lightning.tbn";
|
||
|
features "IsTargetable", "HasName";
|
||
|
|
||
|
properties:
|
||
|
1 CEntityPointer m_penTarget "Target" 'T' COLOR(C_BLUE|0xFF), // ptr to lightninig target
|
||
|
2 CEntityPointer m_penwsc, // ptr to world settings controller
|
||
|
3 CTString m_strName "Name" 'N' = "Lightning", // class name
|
||
|
4 FLOAT m_tmLightningStart = -1.0f, // lightning start time
|
||
|
5 CSoundObject m_soThunder, // sound channel
|
||
|
6 BOOL m_bBackground "Background" 'B' =FALSE,
|
||
|
7 CEntityPointer m_penLight "Light" 'L' COLOR(C_CYAN|0xFF), // ptr to light
|
||
|
8 ANIMATION m_iLightAnim "Light Animation" 'A' = 0,
|
||
|
9 INDEX m_iSoundPlaying = 0,
|
||
|
10 FLOAT m_fLightningPower "Lightning power" 'P' = 1.0f, // lightning's ligting power
|
||
|
11 FLOAT m_fSoundDelay "Sound delay" 'D' = 0.0f, // thunder's delay
|
||
|
|
||
|
components:
|
||
|
1 model MODEL_TELEPORT "Models\\Editor\\Teleport.mdl",
|
||
|
2 texture TEXTURE_TELEPORT "Models\\Editor\\BoundingBox.tex",
|
||
|
3 sound SOUND_THUNDER1 "Sounds\\Environment\\Thunders\\Thunder1.wav",
|
||
|
4 sound SOUND_THUNDER2 "Sounds\\Environment\\Thunders\\Thunder2.wav",
|
||
|
5 sound SOUND_THUNDER3 "Sounds\\Environment\\Thunders\\Thunder3.wav",
|
||
|
|
||
|
functions:
|
||
|
void Precache(void)
|
||
|
{
|
||
|
CMovableModelEntity::Precache();
|
||
|
PrecacheSound(SOUND_THUNDER1);
|
||
|
PrecacheSound(SOUND_THUNDER2);
|
||
|
PrecacheSound(SOUND_THUNDER3);
|
||
|
}
|
||
|
|
||
|
/* Get anim data for given animation property - return NULL for none. */
|
||
|
CAnimData *GetAnimData(SLONG slPropertyOffset)
|
||
|
{
|
||
|
if (m_penLight==NULL) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// if light entity
|
||
|
if (IsOfClass(m_penLight, "Light"))
|
||
|
{
|
||
|
CLight *penLight = (CLight*)&*m_penLight;
|
||
|
|
||
|
if (slPropertyOffset==offsetof(CLightning, m_iLightAnim))
|
||
|
{
|
||
|
return penLight->m_aoLightAnimation.GetData();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WarningMessage("Target '%s' is not of light class!", m_penLight->GetName());
|
||
|
}
|
||
|
return NULL;
|
||
|
};
|
||
|
|
||
|
void RenderParticles(void)
|
||
|
{
|
||
|
if( m_penTarget==NULL || m_tmLightningStart == -1) {return;};
|
||
|
|
||
|
TIME tmNow = _pTimer->GetLerpedCurrentTick();
|
||
|
// if lightning is traveling
|
||
|
if(
|
||
|
((tmNow-m_tmLightningStart) > 0.0f) &&
|
||
|
((tmNow-m_tmLightningStart) < 1.5f) )
|
||
|
{
|
||
|
// render lightning particles
|
||
|
FLOAT3D vSrc = GetPlacement().pl_PositionVector;
|
||
|
FLOAT3D vDst = m_penTarget->GetPlacement().pl_PositionVector;
|
||
|
Particles_Lightning( vSrc, vDst, m_tmLightningStart);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
procedures:
|
||
|
LightningStike()
|
||
|
{
|
||
|
// choose random sound
|
||
|
m_iSoundPlaying = 1+IRnd()%( ARRAYCOUNT(_atiThunderSounds)-1);
|
||
|
if( m_fSoundDelay != 0)
|
||
|
{
|
||
|
m_iSoundPlaying=0;
|
||
|
}
|
||
|
m_soThunder.SetVolume(1.5f*m_fLightningPower, 1.5f*m_fLightningPower);
|
||
|
m_soThunder.SetPitch(Lerp(0.9f, 1.2f, FRnd()));
|
||
|
|
||
|
if( m_fSoundDelay == 0.0f)
|
||
|
{
|
||
|
// play thunder !
|
||
|
PlaySound(m_soThunder, _atiThunderSounds[ m_iSoundPlaying].ti_iSound, 0);
|
||
|
}
|
||
|
|
||
|
// wait for sound to progress to lightning strike
|
||
|
if (_atiThunderSounds[ m_iSoundPlaying].ti_fThunderStrikeDelay>0.0f) {
|
||
|
autowait( _atiThunderSounds[ m_iSoundPlaying].ti_fThunderStrikeDelay);
|
||
|
}
|
||
|
|
||
|
// remember current time as lightning start time
|
||
|
TIME tmNow = _pTimer->CurrentTick();
|
||
|
m_tmLightningStart = tmNow;
|
||
|
// also in world settings controller
|
||
|
((CWorldSettingsController *)&*m_penwsc)->m_tmLightningStart = tmNow;
|
||
|
// set power of lightning
|
||
|
((CWorldSettingsController *)&*m_penwsc)->m_fLightningPower = m_fLightningPower;
|
||
|
|
||
|
// trigger light animation
|
||
|
if( m_penLight != NULL)
|
||
|
{
|
||
|
EChangeAnim eChange;
|
||
|
eChange.iLightAnim = m_iLightAnim;
|
||
|
eChange.bLightLoop = FALSE;
|
||
|
m_penLight->SendEvent(eChange);
|
||
|
}
|
||
|
|
||
|
if( m_fSoundDelay != 0.0f)
|
||
|
{
|
||
|
// wait given delay time
|
||
|
autowait( m_fSoundDelay);
|
||
|
// play thunder !
|
||
|
PlaySound(m_soThunder, _atiThunderSounds[ m_iSoundPlaying].ti_iSound, 0);
|
||
|
}
|
||
|
|
||
|
// wait until end of sound
|
||
|
wait( GetSoundLength(_atiThunderSounds[ m_iSoundPlaying].ti_iSound)-
|
||
|
_atiThunderSounds[ m_iSoundPlaying].ti_fThunderStrikeDelay)
|
||
|
{
|
||
|
on (ETimer) :
|
||
|
{
|
||
|
stop;
|
||
|
}
|
||
|
otherwise() :
|
||
|
{
|
||
|
resume;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
return EBegin();
|
||
|
}
|
||
|
|
||
|
Main(EVoid)
|
||
|
{
|
||
|
// set appearance
|
||
|
InitAsEditorModel();
|
||
|
SetPhysicsFlags(EPF_MODEL_IMMATERIAL);
|
||
|
SetCollisionFlags(ECF_IMMATERIAL);
|
||
|
|
||
|
// set appearance
|
||
|
SetModel(MODEL_TELEPORT);
|
||
|
SetModelMainTexture(TEXTURE_TELEPORT);
|
||
|
|
||
|
// see if it is lightning on background
|
||
|
if (m_bBackground)
|
||
|
{
|
||
|
SetFlags(GetFlags()|ENF_BACKGROUND);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetFlags(GetFlags()&~ENF_BACKGROUND);
|
||
|
}
|
||
|
|
||
|
// obtain bcg viewer entity
|
||
|
CBackgroundViewer *penBcgViewer = (CBackgroundViewer *) GetWorld()->GetBackgroundViewer();
|
||
|
if( penBcgViewer == NULL)
|
||
|
{
|
||
|
// don't do anything
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// obtain world settings controller
|
||
|
m_penwsc = penBcgViewer->m_penWorldSettingsController;
|
||
|
if( m_penwsc == NULL)
|
||
|
{
|
||
|
// don't do anything
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// must be world settings controller entity
|
||
|
if (!IsOfClass(m_penwsc, "WorldSettingsController"))
|
||
|
{
|
||
|
// don't do anything
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// lightning target must be marker
|
||
|
if( (m_penTarget == NULL) || (!IsOfClass(m_penTarget, "Marker")) )
|
||
|
{
|
||
|
if( m_penTarget != NULL)
|
||
|
{
|
||
|
WarningMessage("Target '%s' is not of Marker class!", m_penTarget->GetName());
|
||
|
}
|
||
|
// don't do anything
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// stretch model
|
||
|
FLOAT3D vDirection =
|
||
|
(m_penTarget->GetPlacement().pl_PositionVector-
|
||
|
GetPlacement().pl_PositionVector);
|
||
|
|
||
|
FLOAT3D vStretch = vDirection;
|
||
|
vStretch(1) = 1.0f;
|
||
|
vStretch(2) = 1.0f;
|
||
|
vStretch(3) = -vDirection.Length();
|
||
|
|
||
|
// set entity orientation
|
||
|
CPlacement3D pl = GetPlacement();
|
||
|
DirectionVectorToAngles(vDirection.Normalize(), pl.pl_OrientationAngle);
|
||
|
SetPlacement(pl);
|
||
|
|
||
|
GetModelObject()->StretchModel(vStretch);
|
||
|
ModelChangeNotify();
|
||
|
|
||
|
// correct power factor to fall under 0-1 boundaries
|
||
|
m_fLightningPower = Clamp( m_fLightningPower, 0.0f, 1.0f);
|
||
|
|
||
|
// spawn in world editor
|
||
|
autowait(0.1f);
|
||
|
|
||
|
while (TRUE)
|
||
|
{
|
||
|
wait()
|
||
|
{
|
||
|
on (EBegin) : { resume; }
|
||
|
on (ETrigger eTrigger) :
|
||
|
{
|
||
|
call LightningStike();
|
||
|
resume;
|
||
|
}
|
||
|
otherwise() :
|
||
|
{
|
||
|
resume;
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
};
|