Serious-Engine/Sources/Entities/Debris.es
Daniel Gibson b64df456b6 Fix TFE warnings and lots of unused variable warnings
.. still, didn't look at unused variable warnings from *.es because
so many are generated.
2016-05-09 18:51:04 +02:00

277 lines
8.4 KiB
C++

602
%{
#include "Entities/StdH/StdH.h"
%}
uses "Entities/BasicEffects";
enum DebrisParticlesType {
0 DPT_NONE "", // no particles
1 DPT_BLOODTRAIL "", // blood
2 DPR_SMOKETRAIL "", // smoke
3 DPR_SPARKS "", // sparks (for robots)
4 DPR_FLYINGTRAIL "", // just flying object
};
// input parameter for spawning a debris
event ESpawnDebris {
EntityInfoBodyType Eeibt, // body type
CModelData *pmd, // model for this debris
FLOAT fSize, // stretch factor
CTextureData *ptd, // texture for this debris
CTextureData *ptdRefl, // reflection texture
CTextureData *ptdSpec, // specular texture
CTextureData *ptdBump, // bump texture
INDEX iModelAnim, // animation for debris model
enum DebrisParticlesType dptParticles, // particles type
enum BasicEffectType betStain, // stain left when touching brushes
COLOR colDebris, // multiply color for debris
};
%{
%}
class CDebris: CMovableModelEntity {
name "Debris";
thumbnail "";
properties:
1 enum DebrisParticlesType m_dptParticles = DPT_NONE, // type of particles
2 INDEX m_iBodyType = 0, // body type of this debris
3 BOOL m_bFade = FALSE, // fade debris
4 FLOAT m_fFadeStartTime = 0.0f, // fade start time
5 FLOAT m_fFadeTime = 0.0f, // fade time
6 FLOAT3D m_fLastStainHitPoint = FLOAT3D(0,0,0), // last stain hit point
7 enum BasicEffectType m_betStain = BET_NONE, // type of stain left
8 INDEX m_ctLeftStains = 0, // count of stains already left
9 FLOAT m_tmStarted = 0.0f, // time when spawned
components:
1 class CLASS_BASIC_EFFECT "Classes\\BasicEffect.ecl",
functions:
/* Entity info */
void *GetEntityInfo(void) {
return GetStdEntityInfo((EntityInfoBodyType)m_iBodyType);
};
/* Receive damage */
void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType,
FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection)
{
// cannot be damaged immediately after spawning
if ((_pTimer->CurrentTick()-m_tmStarted<1.0f)
||((dmtType==DMT_CANNONBALL_EXPLOSION) && (_pTimer->CurrentTick()-m_tmStarted<5.0f))) {
return;
}
CMovableModelEntity::ReceiveDamage(penInflictor, dmtType, fDamageAmmount, vHitPoint, vDirection);
};
/************************************************************
* FADE OUT *
************************************************************/
BOOL AdjustShadingParameters(FLOAT3D &vLightDirection, COLOR &colLight, COLOR &colAmbient)
{
if (m_bFade) {
FLOAT fTimeRemain = m_fFadeStartTime + m_fFadeTime - _pTimer->CurrentTick();
if (fTimeRemain < 0.0f) { fTimeRemain = 0.0f; }
COLOR colAlpha = GetModelObject()->mo_colBlendColor;
colAlpha = (colAlpha&0xffffff00) + (COLOR(fTimeRemain/m_fFadeTime*0xff)&0xff);
GetModelObject()->mo_colBlendColor = colAlpha;
}
return FALSE;
};
/************************************************************
* EFFECTS *
************************************************************/
// leave a stain where hit
void LeaveStain(void)
{
// if no stains
if (m_betStain==BET_NONE) {
// do nothing
return;
}
// don't allow too many stains to be left
if (m_ctLeftStains>5) {
return;
}
ESpawnEffect ese;
FLOAT3D vPoint;
FLOATplane3D plPlaneNormal;
FLOAT fDistanceToEdge;
// on plane
if (GetNearestPolygon(vPoint, plPlaneNormal, fDistanceToEdge)) {
// away from last hit point and near to polygon
if ((m_fLastStainHitPoint-vPoint).Length()>3.0f &&
(vPoint-GetPlacement().pl_PositionVector).Length()<3.5f) {
m_fLastStainHitPoint = vPoint;
// stain
ese.colMuliplier = C_WHITE|CT_OPAQUE;
ese.betType = m_betStain;
ese.vNormal = FLOAT3D(plPlaneNormal);
GetNormalComponent( en_vCurrentTranslationAbsolute, plPlaneNormal, ese.vDirection);
FLOAT fLength = ese.vDirection.Length() / 7.5f;
fLength = Clamp( fLength, 1.0f, 15.0f);
ese.vStretch = FLOAT3D( 1.0f, fLength*1.0f, 1.0f);
SpawnEffect(CPlacement3D(vPoint+ese.vNormal/50.0f*(FRnd()+0.5f), ANGLE3D(0, 0, 0)), ese);
m_ctLeftStains++;
}
}
};
// spawn effect
void SpawnEffect(const CPlacement3D &plEffect, const class ESpawnEffect &eSpawnEffect)
{
CEntityPointer penEffect = CreateEntity(plEffect, CLASS_BASIC_EFFECT);
penEffect->Initialize(eSpawnEffect);
};
// particles
void RenderParticles(void)
{
// if going too slow
if (en_vCurrentTranslationAbsolute.Length()<0.1f) {
// don't render particles
return;
}
switch(m_dptParticles) {
case DPT_BLOODTRAIL: {
Particles_BloodTrail( this);
} break;
case DPR_SMOKETRAIL: {
Particles_GrenadeTrail( this);
} break;
case DPR_SPARKS: {
Particles_ColoredStarsTrail( this);
} break;
case DPR_FLYINGTRAIL:{
//Particles_WhiteLineTrail( this);
Particles_BombTrail( this);
} break;
default: ASSERT(FALSE);
case DPT_NONE:
return;
}
};
// explode
void Explode(void)
{
// spawn explosion
CPlacement3D plExplosion = GetPlacement();
CEntityPointer penExplosion = CreateEntity(plExplosion, CLASS_BASIC_EFFECT);
ESpawnEffect eSpawnEffect;
eSpawnEffect.colMuliplier = C_WHITE|CT_OPAQUE;
eSpawnEffect.betType = BET_BOMB;
eSpawnEffect.vStretch = FLOAT3D(0.3f,0.3f,0.3f);
penExplosion->Initialize(eSpawnEffect);
}
/************************************************************
* MAIN *
************************************************************/
procedures:
Main(ESpawnDebris eSpawn)
{
InitAsModel();
SetPhysicsFlags(EPF_MODEL_BOUNCING|EPF_CANFADESPINNING);
SetCollisionFlags(ECF_DEBRIS);
SetFlags(GetFlags() | ENF_SEETHROUGH);
SetHealth(25.0f);
en_fBounceDampNormal = 0.15f;
en_fBounceDampParallel = 0.5f;
en_fJumpControlMultiplier = 0.0f;
// set density
if (eSpawn.Eeibt==EIBT_ICE) {
en_fDensity = 500.0f;
} else if (eSpawn.Eeibt==EIBT_WOOD) {
en_fDensity = 500.0f;
} else if (eSpawn.Eeibt==EIBT_FLESH) {
en_fDensity = 5000.0f;
en_fBounceDampNormal = 0.25f;
en_fBounceDampParallel = 0.75f;
} else if (TRUE) {
en_fDensity = 5000.0f;
}
// set appearance
m_dptParticles = eSpawn.dptParticles,
m_betStain = eSpawn.betStain;
m_iBodyType = (INDEX)eSpawn.Eeibt;
GetModelObject()->SetData(eSpawn.pmd);
GetModelObject()->mo_toTexture.SetData(eSpawn.ptd);
GetModelObject()->mo_toReflection.SetData(eSpawn.ptdRefl);
GetModelObject()->mo_toSpecular.SetData(eSpawn.ptdSpec);
GetModelObject()->mo_toBump.SetData(eSpawn.ptdBump);
GetModelObject()->PlayAnim(eSpawn.iModelAnim, AOF_LOOPING);
GetModelObject()->mo_Stretch = FLOAT3D( eSpawn.fSize, eSpawn.fSize, eSpawn.fSize);
// adjust color
GetModelObject()->mo_colBlendColor = eSpawn.colDebris|CT_OPAQUE;
ModelChangeNotify();
FLOATaabbox3D box;
GetBoundingBox(box);
FLOAT fEntitySize = box.Size().MaxNorm();
if (fEntitySize>0.5f) {
SetCollisionFlags(ECF_MODEL);
}
en_fCollisionSpeedLimit+=ClampDn(0.0f, fEntitySize*10.0f);
m_bFade = FALSE;
m_fLastStainHitPoint = FLOAT3D(32000.0f, 32000.0f, 32000.0f);
m_ctLeftStains = 0;
m_tmStarted = _pTimer->CurrentTick();
// wait some time
wait(FRnd()*2.0f + 3.0f) {
on (EBegin) : { resume; }
// if touched something
on (ETouch etouch) : {
// if it is brush
if (etouch.penOther->GetRenderType()==RT_BRUSH) {
// maybe leave stain
LeaveStain();
// if robot
if (m_iBodyType==EIBT_ROBOT) {
// explode
Explode();
SendEvent(EDeath());
resume;
}
}
resume;
}
on (EDeath) : { Destroy(); return; }
on (ETimer) : { stop; }
}
// fade away
SetCollisionFlags(ECF_DEBRIS);
m_fFadeStartTime = _pTimer->CurrentTick();
m_fFadeTime = 5.0f;
m_bFade = TRUE;
autowait(m_fFadeTime);
// cease to exist
Destroy();
return;
}
};