Serious-Engine/Sources/EntitiesMP/ModelHolder3.es
2016-04-01 14:04:24 -04:00

765 lines
25 KiB
JavaScript

/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */
242
%{
#include "EntitiesMP/StdH/StdH.h"
#include "EntitiesMP/WorldSettingsController.h"
%}
uses "EntitiesMP/ModelDestruction";
uses "EntitiesMP/AnimationChanger";
uses "EntitiesMP/BloodSpray";
enum SkaCustomShadingType {
0 SCST_NONE "Automatic shading",
1 SCST_CONSTANT_SHADING "Constant shading",
2 SCST_FULL_CUSTOMIZED "Customized shading"
};
enum SkaShadowType {
0 SST_NONE "None",
1 SST_CLUSTER "Cluster shadows",
2 SST_POLYGONAL "Polygonal"
};
%{
// #define MIPRATIO 0.003125f //(2*tan(90/2))/640
%}
class CModelHolder3 : CRationalEntity {
name "ModelHolder3";
thumbnail "Thumbnails\\ModelHolder3.tbn";
features "HasName", "HasDescription";
properties:
1 CTFileName m_fnModel "Model file (.smc)" 'M' = CTFILENAME(""), //("Models\\Editor\\Axis.mdl"),
// 2 CTFileName m_fnTexture "Texture" 'T' =CTFILENAME("Models\\Editor\\Vector.tex"),
// 22 CTFileName m_fnReflection "Reflection" =CTString(""),
// 23 CTFileName m_fnSpecular "Specular" =CTString(""),
// 24 CTFileName m_fnBump "Bump" =CTString(""),
3 FLOAT m_fStretchAll "StretchAll" 'S' = 1.0f,
4 ANGLE3D m_vStretchXYZ "StretchXYZ" 'X' = FLOAT3D(1.0f, 1.0f, 1.0f),
// 4 FLOAT m_vStretchXYZ(1) "StretchX" 'X' = 1.0f,
// 5 FLOAT m_vStretchXYZ(2) "StretchY" 'Y' = 1.0f,
// 6 FLOAT m_vStretchXYZ(3) "StretchZ" 'Z' = 1.0f,
7 CTString m_strName "Name" 'N' ="",
12 CTString m_strDescription = "",
8 BOOL m_bColliding "Collision" 'L' = FALSE, // set if model is not immatierial
// 9 ANIMATION m_iModelAnimation "Model animation" = 0,
// 10 ANIMATION m_iTextureAnimation "Texture animation" = 0,
11 enum SkaShadowType m_stClusterShadows "Shadows" 'W' = SST_CLUSTER, // set if model uses cluster shadows
13 BOOL m_bBackground "Background" 'B' = FALSE, // set if model is rendered in background
21 BOOL m_bTargetable "Targetable" = FALSE, // st if model should be targetable
// parameters for custom shading of a model (overrides automatic shading calculation)
14 enum SkaCustomShadingType m_cstCustomShading "Shading mode" 'H' = SCST_NONE,
15 ANGLE3D m_aShadingDirection "Shade. Light direction" 'D' = ANGLE3D( AngleDeg(45.0f),AngleDeg(45.0f),AngleDeg(45.0f)),
16 COLOR m_colLight "Shade. Light color" 'O' = C_WHITE,
17 COLOR m_colAmbient "Shade. Ambient color" 'A' = C_BLACK,
// 18 CTFileName m_fnmLightAnimation "Light animation file" = CTString(""),
// 19 ANIMATION m_iLightAnimation "Light animation" = 0,
// 20 CAnimObject m_aoLightAnimation,
// 25 BOOL m_bAttachments "Attachments" = TRUE, // set if model should auto load attachments*/
26 BOOL m_bActive "Active" = TRUE,
// 31 FLOAT m_fMipAdd "Mip Add" = 0.0f,
// 32 FLOAT m_fMipMul "Mip Mul" = 1.0f,
//33 FLOAT m_fMipFadeDist "Mip Fade Dist" = 0.0f,
//34 FLOAT m_fMipFadeLen "Mip Fade Len" = 0.0f,
// 33 FLOAT m_fMipFadeDist = 0.0f,
// 34 FLOAT m_fMipFadeLen = 0.0f,
// 35 RANGE m_rMipFadeDistMetric "Mip Fade Dist (Metric)" = -1.0f,
// 36 FLOAT m_fMipFadeLenMetric "Mip Fade Len (Metric)" = -1.0f,
// random values variables
// 50 BOOL m_bRandomStretch "Apply RND stretch" = FALSE, // apply random stretch
// 52 FLOAT m_fStretchRndX "Stretch RND X (%)" = 0.2f, // random stretch width
// 51 FLOAT m_fStretchRndY "Stretch RND Y (%)" = 0.2f, // random stretch height
// 53 FLOAT m_fStretchRndZ "Stretch RND Z (%)" = 0.2f, // random stretch depth
// 54 FLOAT m_fStretchRndAll "Stretch RND All (%)" = 0.0f, // random stretch all
// 55 FLOAT3D m_fStretchRandom = FLOAT3D(1, 1, 1),
// destruction values
// 60 CEntityPointer m_penDestruction "Destruction" 'Q' COLOR(C_BLACK|0x20), // model destruction entity
// 61 FLOAT3D m_vDamage = FLOAT3D(0,0,0), // current damage impact
// 62 FLOAT m_tmLastDamage = -1000.0f,
// 63 CEntityPointer m_penDestroyTarget "Destruction Target" COLOR(C_WHITE|0xFF), // targeted when destroyed
// 64 CEntityPointer m_penLastDamager,
// 65 FLOAT m_tmSpraySpawned = 0.0f, // time when damage has been applied
// 66 FLOAT m_fSprayDamage = 0.0f, // total ammount of damage
// 67 CEntityPointer m_penSpray, // the blood spray
// 68 FLOAT m_fMaxDamageAmmount = 0.0f, // max ammount of damage recived in in last xxx ticks
70 FLOAT m_fClassificationStretch "Classification stretch" = 1.0f, // classification box multiplier
// 80 COLOR m_colBurning = COLOR(C_WHITE|CT_OPAQUE), // color applied when burning
// 90 enum DamageType m_dmtLastDamageType=DMT_CHAINSAW,
// 91 FLOAT m_fChainSawCutDamage "Chain saw cut dammage" 'C' = 300.0f,
// 93 INDEX m_iFirstRandomAnimation "First random animation" 'R' = -1,
100 FLOAT m_fMaxTessellationLevel "Max tessellation level" = 0.0f,
/*201 FLOAT m_tmFadeStart = -1.0f, // time when model starts fading
202 FLOAT m_tmFadeEnd = -1.0f, // time when model stops fading
203 INDEX m_iMinModelOpacity "Faded Min. Alpha" = 32,
205 FLOAT m_fFadeSpeed "Fadeout Speed" = 0.25f,
206 FLOAT m_fFadeEndWait "Fade end delay" = 0.1f,
207 BOOL m_bFadeChildren "Fade Children" = TRUE,
210 BOOL m_bFade "Fade" = TRUE,*/
/*{
CTFileName m_fnOldModel; // used for remembering last selected model (not saved at all)
}*/
components:
// 1 class CLASS_BLOOD_SPRAY "Classes\\BloodSpray.ecl",
functions:
// void Precache(void) {
// PrecacheClass(CLASS_BLOOD_SPRAY, 0);
// };
/* Fill in entity statistics - for AI purposes only */
BOOL FillEntityStatistics(EntityStats *pes)
{
//pes->es_strName = m_fnModel.FileName()+", "+m_fnTexture.FileName();
pes->es_strName = m_fnModel.FileName();
pes->es_ctCount = 1;
pes->es_ctAmmount = 1;
/*if (m_penDestruction!=NULL) {
pes->es_strName += " (destroyable)";
pes->es_fValue = GetDestruction()->m_fHealth;
pes->es_iScore = 0;
} else {*/
pes->es_fValue = 0;
pes->es_iScore = 0;
/*}*/
return TRUE;
}
// classification box multiplier
FLOAT3D GetClassificationBoxStretch(void)
{
return FLOAT3D( m_fClassificationStretch, m_fClassificationStretch, m_fClassificationStretch);
}
// maximum allowed tessellation level for this model (for Truform/N-Patches support)
FLOAT GetMaxTessellationLevel(void)
{
return m_fMaxTessellationLevel;
}
/* Receive damage */
void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType,
FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection)
{
// if not destroyable
/*if (m_penDestruction==NULL) {
// do nothing
return;
}
FLOAT fNewDamage = fDamageAmmount;
if( dmtType==DMT_BURNING)
{
UBYTE ubR, ubG, ubB, ubA;
ColorToRGBA(m_colBurning, ubR, ubG, ubB, ubA);
ubR=ClampDn(ubR-4, 32);
m_colBurning=RGBAToColor(ubR, ubR, ubR, ubA);
}
CModelDestruction *penDestruction = GetDestruction();
// adjust damage
fNewDamage *=DamageStrength(penDestruction->m_eibtBodyType, dmtType);
// if no damage
if (fNewDamage==0) {
// do nothing
return;
}
FLOAT fKickDamage = fNewDamage;
if( (dmtType == DMT_EXPLOSION) || (dmtType == DMT_IMPACT) || (dmtType == DMT_CANNONBALL_EXPLOSION) )
{
fKickDamage*=1.5f;
}
if (dmtType == DMT_CLOSERANGE) {
fKickDamage=0.0f;
}
if (dmtType == DMT_CHAINSAW) {
fKickDamage=0.0f;
}
if(dmtType == DMT_BULLET && penDestruction->m_eibtBodyType==EIBT_ROCK) {
fKickDamage=0.0f;
}
if( dmtType==DMT_BURNING)
{
fKickDamage=0.0f;
}
// get passed time since last damage
TIME tmNow = _pTimer->CurrentTick();
TIME tmDelta = tmNow-m_tmLastDamage;
m_tmLastDamage = tmNow;
// remember who damaged you
m_penLastDamager = penInflictor;
// fade damage out
if (tmDelta>=_pTimer->TickQuantum*3) {
m_vDamage=FLOAT3D(0,0,0);
}
// add new damage
FLOAT3D vDirectionFixed;
if (vDirection.ManhattanNorm()>0.5f) {
vDirectionFixed = vDirection;
} else {
vDirectionFixed = FLOAT3D(0,1,0);
}
FLOAT3D vDamageOld = m_vDamage;
m_vDamage += vDirectionFixed*fKickDamage;
// NOTE: we don't receive damage here, but handle death differently
if (m_vDamage.Length()>GetHealth()) {
if (!penDestruction->m_bRequireExplosion ||
dmtType==DMT_EXPLOSION || dmtType==DMT_CANNONBALL || dmtType==DMT_CANNONBALL_EXPLOSION)
{
EDeath eDeath; // we don't need any extra parameters
SendEvent(eDeath);
//remember last dammage type
m_dmtLastDamageType=dmtType;
}
}
if( m_fMaxDamageAmmount<fDamageAmmount) {
m_fMaxDamageAmmount = fDamageAmmount;
}
// if it has no spray, or if this damage overflows it
if( (dmtType!=DMT_BURNING) && (dmtType!=DMT_CHAINSAW) &&
(m_tmSpraySpawned<=_pTimer->CurrentTick()-_pTimer->TickQuantum*8 ||
m_fSprayDamage+fNewDamage>50.0f))
{
// spawn blood spray
CPlacement3D plSpray = CPlacement3D( vHitPoint, ANGLE3D(0, 0, 0));
m_penSpray = CreateEntity( plSpray, CLASS_BLOOD_SPRAY);
m_penSpray->SetParent( this);
ESpawnSpray eSpawnSpray;
// adjust spray power
if( m_fMaxDamageAmmount > 10.0f) {
eSpawnSpray.fDamagePower = 3.0f;
} else if(m_fSprayDamage+fNewDamage>50.0f) {
eSpawnSpray.fDamagePower = 2.0f;
} else {
eSpawnSpray.fDamagePower = 1.0f;
}
eSpawnSpray.sptType = penDestruction->m_sptType;
eSpawnSpray.fSizeMultiplier = penDestruction->m_fParticleSize;
// get your down vector (simulates gravity)
FLOAT3D vDn(-en_mRotation(1,2), -en_mRotation(2,2), -en_mRotation(3,2));
// setup direction of spray
FLOAT3D vHitPointRelative = vHitPoint - GetPlacement().pl_PositionVector;
FLOAT3D vReflectingNormal;
GetNormalComponent( vHitPointRelative, vDn, vReflectingNormal);
vReflectingNormal.Normalize();
FLOAT3D vProjectedComponent = vReflectingNormal*(vDirection%vReflectingNormal);
FLOAT3D vSpilDirection = vDirection-vProjectedComponent*2.0f-vDn*0.5f;
eSpawnSpray.vDirection = vSpilDirection;
eSpawnSpray.penOwner = this;
eSpawnSpray.colCentralColor=penDestruction->m_colParticles;
eSpawnSpray.colBurnColor=m_colBurning;
eSpawnSpray.fLaunchPower=penDestruction->m_fParticleLaunchPower;
// initialize spray
m_penSpray->Initialize( eSpawnSpray);
m_tmSpraySpawned = _pTimer->CurrentTick();
m_fSprayDamage = 0.0f;
m_fMaxDamageAmmount = 0.0f;
}
if( dmtType==DMT_CHAINSAW && m_fChainSawCutDamage>0)
{
m_fChainSawCutDamage-=fDamageAmmount;
if(m_fChainSawCutDamage<=0)
{
EDeath eDeath; // we don't need any extra parameters
SendEvent(eDeath);
//remember last dammage type
m_dmtLastDamageType=dmtType;
}
}
m_fSprayDamage+=fNewDamage;
*/
};
// Entity info
void *GetEntityInfo(void) {
/*CModelDestruction *pmd=GetDestruction();
if( pmd!=NULL)
{
return GetStdEntityInfo(pmd->m_eibtBodyType);
}*/
return CEntity::GetEntityInfo();
};
/* class CModelDestruction *GetDestruction(void)
{
ASSERT(m_penDestruction==NULL || IsOfClass(m_penDestruction, "ModelDestruction"));
return (CModelDestruction*)&*m_penDestruction;
}*/
BOOL IsTargetable(void) const
{
return m_bTargetable;
}
/* Get anim data for given animation property - return NULL for none. */
/* CAnimData *GetAnimData(SLONG slPropertyOffset)
{
if (slPropertyOffset==_offsetof(CModelHolder3, m_iModelAnimation)) {
return GetModelObject()->GetData();
} else if (slPropertyOffset==_offsetof(CModelHolder3, m_iTextureAnimation)) {
return GetModelObject()->mo_toTexture.GetData();
} else if (slPropertyOffset==_offsetof(CModelHolder3, m_iLightAnimation)) {
return m_aoLightAnimation.GetData();
} else {
return CEntity::GetAnimData(slPropertyOffset);
}
};*/
/* Adjust model mip factor if needed. */
/* void AdjustMipFactor(FLOAT &fMipFactor)
{
// if should fade last mip
if (m_fMipFadeDist>0) {
CModelObject *pmo = GetModelObject();
if(pmo==NULL) {
return;
}
// adjust for stretch
FLOAT fMipForFade = fMipFactor;
// if not visible
if (fMipForFade>m_fMipFadeDist) {
// set mip factor so that model is never rendered
fMipFactor = UpperLimit(0.0f);
return;
}
// adjust fading
FLOAT fFade = (m_fMipFadeDist-fMipForFade);
if (m_fMipFadeLen>0) {
fFade/=m_fMipFadeLen;
} else {
if (fFade>0) {
fFade = 1.0f;
}
}
fFade = Clamp(fFade, 0.0f, 1.0f);
// make it invisible
pmo->mo_colBlendColor = (pmo->mo_colBlendColor&~255)|UBYTE(255*fFade);
}
fMipFactor = fMipFactor*m_fMipMul+m_fMipAdd;
}*/
/* Adjust model shading parameters if needed. */
BOOL AdjustShadingParameters(FLOAT3D &vLightDirection, COLOR &colLight, COLOR &colAmbient)
{
switch(m_cstCustomShading)
{
case SCST_FULL_CUSTOMIZED:
{
// if there is color animation
/*if (m_aoLightAnimation.GetData()!=NULL) {
// get lerping info
SLONG colFrame0, colFrame1; FLOAT fRatio;
m_aoLightAnimation.GetFrame( colFrame0, colFrame1, fRatio);
UBYTE ubAnimR0, ubAnimG0, ubAnimB0;
UBYTE ubAnimR1, ubAnimG1, ubAnimB1;
ColorToRGB( colFrame0, ubAnimR0, ubAnimG0, ubAnimB0);
ColorToRGB( colFrame1, ubAnimR1, ubAnimG1, ubAnimB1);
// calculate current animation color
FLOAT fAnimR = NormByteToFloat( Lerp( ubAnimR0, ubAnimR1, fRatio));
FLOAT fAnimG = NormByteToFloat( Lerp( ubAnimG0, ubAnimG1, fRatio));
FLOAT fAnimB = NormByteToFloat( Lerp( ubAnimB0, ubAnimB1, fRatio));
// decompose constant colors
UBYTE ubLightR, ubLightG, ubLightB;
UBYTE ubAmbientR, ubAmbientG, ubAmbientB;
ColorToRGB( m_colLight, ubLightR, ubLightG, ubLightB);
ColorToRGB( m_colAmbient, ubAmbientR, ubAmbientG, ubAmbientB);
colLight = RGBToColor( ubLightR *fAnimR, ubLightG *fAnimG, ubLightB *fAnimB);
colAmbient = RGBToColor( ubAmbientR*fAnimR, ubAmbientG*fAnimG, ubAmbientB*fAnimB);
// if there is no color animation
} else {*/
colLight = m_colLight;
colAmbient = m_colAmbient;
//}
// obtain world settings controller
/*CWorldSettingsController *pwsc = GetWSC(this);
if( pwsc!=NULL && pwsc->m_bApplyShadingToModels)
{
// apply animating shading
COLOR colShade = GetWorld()->wo_atbTextureBlendings[9].tb_colMultiply;
colLight=MulColors(colLight, colShade);
colAmbient=MulColors(colAmbient, colShade);
}*/
AnglesToDirectionVector(m_aShadingDirection, vLightDirection);
vLightDirection = -vLightDirection;
break;
}
case SCST_CONSTANT_SHADING:
{
// combine colors with clamp
UBYTE lR,lG,lB,aR,aG,aB,rR,rG,rB;
ColorToRGB( colLight, lR, lG, lB);
ColorToRGB( colAmbient, aR, aG, aB);
colLight = 0;
rR = (UBYTE) Clamp( (ULONG)lR+aR, (ULONG)0, (ULONG)255);
rG = (UBYTE) Clamp( (ULONG)lG+aG, (ULONG)0, (ULONG)255);
rB = (UBYTE) Clamp( (ULONG)lB+aB, (ULONG)0, (ULONG)255);
colAmbient = RGBToColor( rR, rG, rB);
break;
}
case SCST_NONE:
{
// do nothing
break;
}
}
/* if(m_colBurning!=COLOR(C_WHITE|CT_OPAQUE))
{
colAmbient = MulColors( colAmbient, m_colBurning);
colLight = MulColors( colLight, m_colBurning);
return TRUE;
}*/
return m_stClusterShadows!=SST_NONE;
};
// apply mirror and stretch to the entity
void MirrorAndStretch(FLOAT fStretch, BOOL bMirrorX)
{
m_fStretchAll*=fStretch;
if (bMirrorX) {
m_vStretchXYZ(1)=-m_vStretchXYZ(1);
}
}
// Stretch model
void StretchModel(void) {
// stretch factors must not have extreme values
if (Abs(m_vStretchXYZ(1)) < 0.01f) { m_vStretchXYZ(1) = 0.01f; }
if (Abs(m_vStretchXYZ(2)) < 0.01f) { m_vStretchXYZ(2) = 0.01f; }
if (Abs(m_vStretchXYZ(3)) < 0.01f) { m_vStretchXYZ(3) = 0.01f; }
if (m_fStretchAll< 0.01f) { m_fStretchAll = 0.01f; }
if (Abs(m_vStretchXYZ(1)) >1000.0f) { m_vStretchXYZ(1) = 1000.0f*Sgn(m_vStretchXYZ(1)); }
if (Abs(m_vStretchXYZ(2)) >1000.0f) { m_vStretchXYZ(2) = 1000.0f*Sgn(m_vStretchXYZ(2)); }
if (Abs(m_vStretchXYZ(3)) >1000.0f) { m_vStretchXYZ(3) = 1000.0f*Sgn(m_vStretchXYZ(3)); }
if (m_fStretchAll>1000.0f) { m_fStretchAll = 1000.0f; }
/* if (m_bRandomStretch) {
m_bRandomStretch = FALSE;
// stretch
m_fStretchRndX = Clamp( m_fStretchRndX , 0.0f, 1.0f);
m_fStretchRndY = Clamp( m_fStretchRndY , 0.0f, 1.0f);
m_fStretchRndZ = Clamp( m_fStretchRndZ , 0.0f, 1.0f);
m_fStretchRndAll = Clamp( m_fStretchRndAll , 0.0f, 1.0f);
m_fStretchRandom(1) = (FRnd()*m_fStretchRndX*2 - m_fStretchRndX) + 1;
m_fStretchRandom(2) = (FRnd()*m_fStretchRndY*2 - m_fStretchRndY) + 1;
m_fStretchRandom(3) = (FRnd()*m_fStretchRndZ*2 - m_fStretchRndZ) + 1;
FLOAT fRNDAll = (FRnd()*m_fStretchRndAll*2 - m_fStretchRndAll) + 1;
m_fStretchRandom(1) *= fRNDAll;
m_fStretchRandom(2) *= fRNDAll;
m_fStretchRandom(3) *= fRNDAll;
}*/
GetModelInstance()->StretchModel( m_vStretchXYZ*m_fStretchAll );
ModelChangeNotify();
};
/* Init model holder*/
void InitModelHolder(void) {
// must not crash when model is removed
if (m_fnModel=="") {
m_fnModel=CTFILENAME("Models\\Editor\\Ska\\Axis.smc");
}
if (m_bActive) {
InitAsSkaModel();
} else {
InitAsSkaEditorModel();
}
BOOL bLoadOK = TRUE;
// try to load the model
try {
SetSkaModel_t(m_fnModel);
// if failed
} catch(char *strError) {
WarningMessage(TRANS("Cannot load ska model '%s':\n%s"), (const char *) m_fnModel, strError);
bLoadOK = FALSE;
// set colision info for default model
//SetSkaColisionInfo();
}
if (!bLoadOK) {
SetSkaModel(CTFILENAME("Models\\Editor\\Ska\\Axis.smc"));
}
/*try
{
GetModelObject()->mo_toTexture.SetData_t(m_fnTexture);
GetModelObject()->mo_toTexture.PlayAnim(m_iTextureAnimation, AOF_LOOPING);
GetModelObject()->mo_toReflection.SetData_t(m_fnReflection);
GetModelObject()->mo_toSpecular.SetData_t(m_fnSpecular);
GetModelObject()->mo_toBump.SetData_t(m_fnBump);
} catch (char *strError) {
WarningMessage(strError);
}*/
// set model stretch
StretchModel();
ModelChangeNotify();
if (m_bColliding&&m_bActive) {
SetPhysicsFlags(EPF_MODEL_FIXED);
SetCollisionFlags(ECF_MODEL_HOLDER);
} else {
SetPhysicsFlags(EPF_MODEL_IMMATERIAL);
SetCollisionFlags(ECF_IMMATERIAL);
}
switch(m_stClusterShadows) {
case SST_NONE:
{
SetFlags(GetFlags()&~ENF_CLUSTERSHADOWS);
//SetFlags(GetFlags()&~ENF_POLYGONALSHADOWS);
break;
}
case SST_CLUSTER:
{
SetFlags(GetFlags()|ENF_CLUSTERSHADOWS);
//SetFlags(GetFlags()&~ENF_POLYGONALSHADOWS);
break;
}
case SST_POLYGONAL:
{
//SetFlags(GetFlags()|ENF_POLYGONALSHADOWS);
SetFlags(GetFlags()&~ENF_CLUSTERSHADOWS);
break;
}
}
if (m_bBackground) {
SetFlags(GetFlags()|ENF_BACKGROUND);
} else {
SetFlags(GetFlags()&~ENF_BACKGROUND);
}
/* try {
m_aoLightAnimation.SetData_t(m_fnmLightAnimation);
} catch (char *strError) {
WarningMessage(TRANS("Cannot load '%s': %s"), (CTString&)m_fnmLightAnimation, strError);
m_fnmLightAnimation = "";
}
if (m_aoLightAnimation.GetData()!=NULL) {
m_aoLightAnimation.PlayAnim(m_iLightAnimation, AOF_LOOPING);
}
if (m_penDestruction==NULL) {
m_strDescription.PrintF("%s,%s undestroyable", (CTString&)m_fnModel.FileName(), (CTString&)m_fnTexture.FileName());
} else {
m_strDescription.PrintF("%s,%s -> %s", (CTString&)m_fnModel.FileName(), (CTString&)m_fnTexture.FileName(),
m_penDestruction->GetName());
}*/
/*m_iMinModelOpacity = Clamp(m_iMinModelOpacity, (INDEX)0, (INDEX)255);
m_fFadeEndWait = ClampDn(m_fFadeEndWait, 0.05f);
m_fFadeSpeed = ClampDn(m_fFadeSpeed, 0.05f);*/
m_strDescription.PrintF("%s", (const char *) m_fnModel.FileName());
return;
};
procedures:
Die()
{
// for each child of this entity
{FOREACHINLIST(CEntity, en_lnInParent, en_lhChildren, itenChild) {
// send it destruction event
itenChild->SendEvent(ERangeModelDestruction());
}}
/* // spawn debris
CModelDestruction *pmd=GetDestruction();
pmd->SpawnDebris(this);
// if there is another phase in destruction
CModelHolder3 *penNext = pmd->GetNextPhase();
if (penNext!=NULL) {
// copy it here
CEntity *penNew = GetWorld()->CopyEntityInWorld( *penNext, GetPlacement() );
penNew->GetModelObject()->StretchModel(GetModelObject()->mo_Stretch);
penNew->ModelChangeNotify();
((CModelHolder3 *)penNew)->m_colBurning=m_colBurning;
((CModelHolder3 *)penNew)->m_fChainSawCutDamage=m_fChainSawCutDamage;
if( pmd->m_iStartAnim!=-1)
{
penNew->GetModelObject()->PlayAnim(pmd->m_iStartAnim, 0);
}
// copy custom shading parameters
CModelHolder3 &mhNew=*((CModelHolder3 *)penNew);
mhNew.m_cstCustomShading=m_cstCustomShading;
mhNew.m_colLight=m_colLight;
mhNew.m_colAmbient=m_colAmbient;
mhNew.m_fMipFadeDist = m_fMipFadeDist;
mhNew.m_fMipFadeLen = m_fMipFadeLen;
mhNew.m_fMipAdd = m_fMipAdd;
mhNew.m_fMipMul = m_fMipMul;
// domino death for cannonball
if(m_dmtLastDamageType==DMT_CHAINSAW)
{
EDeath eDeath; // we don't need any extra parameters
mhNew.m_fChainSawCutDamage=0.0f;
mhNew.m_dmtLastDamageType=DMT_CHAINSAW;
penNew->SendEvent(eDeath);
}
}
// if there is a destruction target
if (m_penDestroyTarget!=NULL) {
// notify it
SendToTarget(m_penDestroyTarget, EET_TRIGGER, m_penLastDamager);
}*/
// destroy yourself
Destroy();
return;
}
Main()
{
// initialize the model
InitModelHolder();
/*if (m_fMipFadeLenMetric>m_rMipFadeDistMetric) { m_fMipFadeLenMetric = m_rMipFadeDistMetric; }
// convert metric factors to mip factors
if (m_rMipFadeDistMetric>0.0f) {
m_fMipFadeDist = Log2(m_rMipFadeDistMetric*1024.0f*MIPRATIO);
m_fMipFadeLen = Log2((m_rMipFadeDistMetric+m_fMipFadeLenMetric)*1024.0f*MIPRATIO) - m_fMipFadeDist;
} else {
m_fMipFadeDist = 0.0f;
m_fMipFadeLen = 0.0f;
}*/
// check your destruction pointer
/*if (m_penDestruction!=NULL && !IsOfClass(m_penDestruction, "ModelDestruction")) {
WarningMessage("Destruction '%s' is wrong class!", m_penDestruction->GetName());
m_penDestruction=NULL;
}*/
// wait forever
wait() {
// on the beginning
on(EBegin): {
// set your health
/*if (m_penDestruction!=NULL) {
SetHealth(GetDestruction()->m_fHealth);
}*/
resume;
}
// activate/deactivate shows/hides model
on (EActivate): {
SwitchToModel();
m_bActive = TRUE;
if (m_bColliding) {
SetPhysicsFlags(EPF_MODEL_FIXED);
SetCollisionFlags(ECF_MODEL_HOLDER);
}
resume;
}
on (EDeactivate): {
SwitchToEditorModel();
SetPhysicsFlags(EPF_MODEL_IMMATERIAL);
SetCollisionFlags(ECF_IMMATERIAL);
m_bActive = FALSE;
SetPhysicsFlags(EPF_MODEL_IMMATERIAL);
SetCollisionFlags(ECF_IMMATERIAL);
resume;
}
// when your parent is destroyed
on(ERangeModelDestruction): {
// for each child of this entity
{FOREACHINLIST(CEntity, en_lnInParent, en_lhChildren, itenChild) {
// send it destruction event
itenChild->SendEvent(ERangeModelDestruction());
}}
// destroy yourself
Destroy();
resume;
}
// when dead
on(EDeath): {
/*if (m_penDestruction!=NULL) {
jump Die();
}*/
resume;
}
/* on(EFade): {
if (_pTimer->CurrentTick()>m_tmFadeEnd) {
m_tmFadeStart = _pTimer->CurrentTick();
}
m_tmFadeEnd = _pTimer->CurrentTick() + m_fFadeSpeed + m_fFadeEndWait;
// perhaps fade all entities children
if (m_bFadeChildren) {
{FOREACHINLIST( CEntity, en_lnInParent, en_lhChildren, iten) {
iten->SendEvent(EFade());
}}
}
resume;
}*/
// when animation should be changed
/*on(EChangeAnim eChange): {
m_iModelAnimation = eChange.iModelAnim;
m_iTextureAnimation = eChange.iTextureAnim;
m_iLightAnimation = eChange.iLightAnim;
if (m_aoLightAnimation.GetData()!=NULL) {
m_aoLightAnimation.PlayAnim(m_iLightAnimation, eChange.bLightLoop?AOF_LOOPING:0);
}
if (GetModelObject()->GetData()!=NULL) {
GetModelObject()->PlayAnim(m_iModelAnimation, eChange.bModelLoop?AOF_LOOPING:0);
}
if (GetModelObject()->mo_toTexture.GetData()!=NULL) {
GetModelObject()->mo_toTexture.PlayAnim(m_iTextureAnimation, eChange.bTextureLoop?AOF_LOOPING:0);
}
resume;
}*/
otherwise(): {
resume;
}
};
}
};