Serious-Engine/Sources/Entities/Flame.es
2016-04-08 00:11:36 +02:00

183 lines
4.6 KiB
C++

504
%{
#include "Entities/StdH/StdH.h"
%}
uses "Entities/Light";
// input parameter for flame
event EFlame {
CEntityPointer penOwner, // entity which owns it
CEntityPointer penAttach, // entity on which flame is attached (his parent)
};
%{
void CFlame_OnPrecache(CDLLEntityClass *pdec, INDEX iUser)
{
pdec->PrecacheModel(MODEL_FLAME);
pdec->PrecacheTexture(TEXTURE_FLAME);
pdec->PrecacheSound(SOUND_FLAME);
}
%}
class CFlame : CMovableModelEntity {
name "Flame";
thumbnail "";
features "ImplementsOnPrecache", "CanBePredictable";
properties:
1 CEntityPointer m_penOwner, // entity which owns it
2 CEntityPointer m_penAttach, // entity on which flame is attached (his parent)
5 BOOL m_bLoop = FALSE, // internal for loops
10 CSoundObject m_soEffect, // sound channel
{
CLightSource m_lsLightSource;
}
components:
1 class CLASS_LIGHT "Classes\\Light.ecl",
// ********* FLAME *********
10 model MODEL_FLAME "Models\\Effects\\Flame\\Flame.mdl",
//"Models\\Weapons\\Flamer\\Projectile\\Invisible.mdl",
11 texture TEXTURE_FLAME "Models\\Effects\\Flame\\Flame.tex",
12 sound SOUND_FLAME "Sounds\\Fire\\Fire4.wav",
functions:
// add to prediction any entities that this entity depends on
void AddDependentsToPrediction(void)
{
m_penOwner->AddToPrediction();
}
// postmoving
void PostMoving(void) {
CMovableModelEntity::PostMoving();
// if no air
CContentType &ctDn = GetWorld()->wo_actContentTypes[en_iDnContent];
// stop existing
if (!(ctDn.ct_ulFlags&CTF_BREATHABLE_LUNGS)) {
SendEvent(EEnd());
}
// never remove from list of movers
en_ulFlags &= ~ENF_INRENDERING;
// not moving in fact, only moving with its parent
en_plLastPlacement = en_plPlacement;
};
/* Read from stream. */
void Read_t( CTStream *istr) // throw char *
{
CRationalEntity::Read_t(istr);
SetupLightSource();
}
/* Get static light source information. */
CLightSource *GetLightSource(void)
{
if (!IsPredictor()) {
return &m_lsLightSource;
} else {
return NULL;
}
}
// Setup light source
void SetupLightSource(void)
{
// setup light source
CLightSource lsNew;
lsNew.ls_ulFlags = LSF_NONPERSISTENT|LSF_DYNAMIC;
lsNew.ls_colColor = C_dYELLOW;
lsNew.ls_rFallOff = 2.0f;
lsNew.ls_rHotSpot = 0.2f;
lsNew.ls_plftLensFlare = NULL;
lsNew.ls_ubPolygonalMask = 0;
lsNew.ls_paoLightAnimation = NULL;
m_lsLightSource.ls_penEntity = this;
m_lsLightSource.SetLightSource(lsNew);
}
/************************************************************
* P R O C E D U R E S *
************************************************************/
procedures:
// --->>> MAIN
Main(EFlame ef) {
// attach to parent (another entity)
ASSERT(ef.penOwner!=NULL);
ASSERT(ef.penAttach!=NULL);
m_penOwner = ef.penOwner;
m_penAttach = ef.penAttach;
SetParent(ef.penAttach);
// initialization
InitAsModel();
SetPhysicsFlags(EPF_MODEL_FLYING);
SetCollisionFlags(ECF_FLAME);
SetFlags(GetFlags() | ENF_SEETHROUGH);
// if parent is model
if (m_penAttach->GetRenderType()==CEntity::RT_MODEL) {
// stretch to its size
FLOATaabbox3D box;
m_penAttach->GetBoundingBox(box);
GetModelObject()->StretchModel(box.Size());
}
ModelChangeNotify();
SetModel(MODEL_FLAME);
SetModelMainTexture(TEXTURE_FLAME);
// play the burning sound
m_soEffect.Set3DParameters(5.0f, 1.0f, 1.0f, 1.0f);
PlaySound(m_soEffect, SOUND_FLAME, SOF_3D|SOF_LOOP);
// setup light source
SetupLightSource();
// must always be in movers, to find sector content type
AddToMovers();
// burning damage
SpawnReminder(this, 7.5f, 0);
m_bLoop = TRUE;
while(m_bLoop) {
wait(0.25f) {
// damage to parent
on (EBegin) : {
// if parent does not exist anymore
if (m_penAttach==NULL || (m_penAttach->GetFlags()&ENF_DELETED)) {
// stop existing
m_bLoop = FALSE;
stop;
}
// inflict damage to parent
m_penAttach->InflictDirectDamage(m_penAttach, m_penOwner, DMT_BURNING, 1.0f, FLOAT3D(0, 0, 0), -en_vGravityDir);
resume;
}
on (EFlame ef) : {
m_penOwner = ef.penOwner;
resume;
};
on (ETimer) : { stop; }
on (EReminder) : {
m_bLoop = FALSE;
stop;
}
on (EEnd) : {
m_bLoop = FALSE;
stop;
}
}
}
// cease to exist
Destroy();
return;
}
};