mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-22 18:30:27 +01:00
291 lines
8.4 KiB
C++
291 lines
8.4 KiB
C++
|
507
|
||
|
%{
|
||
|
#include "Entities/StdH/StdH.h"
|
||
|
|
||
|
#define ECF_TWISTER ( \
|
||
|
((ECBI_BRUSH|ECBI_MODEL|ECBI_CORPSE|ECBI_ITEM|ECBI_PROJECTILE_MAGIC|ECBI_PROJECTILE_SOLID)<<ECB_TEST) |\
|
||
|
((ECBI_MODEL|ECBI_CORPSE|ECBI_ITEM|ECBI_PROJECTILE_MAGIC|ECBI_PROJECTILE_SOLID)<<ECB_PASS) |\
|
||
|
((ECBI_MODEL)<<ECB_IS))
|
||
|
#define EPF_TWISTER ( \
|
||
|
EPF_ONBLOCK_CLIMBORSLIDE|EPF_ORIENTEDBYGRAVITY|\
|
||
|
EPF_TRANSLATEDBYGRAVITY|EPF_MOVABLE)
|
||
|
%}
|
||
|
|
||
|
|
||
|
uses "Entities/Elemental";
|
||
|
|
||
|
|
||
|
enum TwisterSize {
|
||
|
0 TWS_SMALL "", // small twister
|
||
|
1 TWS_BIG "", // big twister
|
||
|
2 TWS_LARGE "", // large twister
|
||
|
};
|
||
|
|
||
|
|
||
|
// input parameter for twister
|
||
|
event ETwister {
|
||
|
CEntityPointer penOwner, // entity which owns it
|
||
|
enum TwisterSize EtsSize, // twister size
|
||
|
};
|
||
|
|
||
|
|
||
|
%{
|
||
|
static EntityInfo eiTwister = {
|
||
|
EIBT_AIR, 0.0f,
|
||
|
0.0f, 1.0f, 0.0f,
|
||
|
0.0f, 0.75f, 0.0f,
|
||
|
};
|
||
|
|
||
|
|
||
|
#define MOVE_FREQUENCY 0.1f
|
||
|
#define ROTATE_SPEED 10000.0f
|
||
|
#define MOVE_SPEED 7.5f
|
||
|
%}
|
||
|
|
||
|
class CTwister : CMovableModelEntity {
|
||
|
name "Twister";
|
||
|
thumbnail "";
|
||
|
|
||
|
properties:
|
||
|
1 CEntityPointer m_penOwner, // entity which owns it
|
||
|
2 enum TwisterSize m_EtsSize = TWS_SMALL, // size (type)
|
||
|
3 FLOAT3D m_vStartPosition = FLOAT3D(0,0,0), // start position
|
||
|
|
||
|
// internal -> do not use
|
||
|
10 FLOAT3D m_vDesiredPosition = FLOAT3D(0,0,0),
|
||
|
11 FLOAT3D m_vDesiredAngle = FLOAT3D(0,0,0),
|
||
|
12 FLOAT m_fStopTime = 0.0f,
|
||
|
13 FLOAT m_fActionRadius = 0.0f,
|
||
|
14 FLOAT m_fActionTime = 0.0f,
|
||
|
15 FLOAT m_fDiffMultiply = 0.0f,
|
||
|
16 FLOAT m_fUpMultiply = 0.0f,
|
||
|
20 BOOL m_bFadeOut = FALSE,
|
||
|
21 FLOAT m_fFadeStartTime = 0.0f,
|
||
|
22 FLOAT m_fFadeTime = 2.0f,
|
||
|
|
||
|
components:
|
||
|
// ********* TWISTER *********
|
||
|
10 model MODEL_TWISTER "Models\\Enemies\\Elementals\\Twister.mdl",
|
||
|
11 texture TEXTURE_TWISTER "Models\\Enemies\\Elementals\\AirMan01.tex",
|
||
|
|
||
|
functions:
|
||
|
/* Entity info */
|
||
|
void *GetEntityInfo(void) {
|
||
|
return &eiTwister;
|
||
|
};
|
||
|
|
||
|
/* Receive damage */
|
||
|
void ReceiveDamage(CEntity *penInflictor, enum DamageType dmtType,
|
||
|
FLOAT fDamageAmmount, const FLOAT3D &vHitPoint, const FLOAT3D &vDirection)
|
||
|
{
|
||
|
return;
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* FADE OUT *
|
||
|
************************************************************/
|
||
|
BOOL AdjustShadingParameters(FLOAT3D &vLightDirection, COLOR &colLight, COLOR &colAmbient) {
|
||
|
if (m_bFadeOut) {
|
||
|
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 CMovableModelEntity::AdjustShadingParameters(vLightDirection, colLight, colAmbient);
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* MOVING FUNCTIONS *
|
||
|
************************************************************/
|
||
|
// calculate rotation
|
||
|
void CalcHeadingRotation(ANGLE aWantedHeadingRelative, ANGLE &aRotation) {
|
||
|
// normalize it to [-180,+180] degrees
|
||
|
aWantedHeadingRelative = NormalizeAngle(aWantedHeadingRelative);
|
||
|
|
||
|
// if desired position is left
|
||
|
if (aWantedHeadingRelative < -ROTATE_SPEED*MOVE_FREQUENCY) {
|
||
|
// start turning left
|
||
|
aRotation = -ROTATE_SPEED;
|
||
|
// if desired position is right
|
||
|
} else if (aWantedHeadingRelative > ROTATE_SPEED*MOVE_FREQUENCY) {
|
||
|
// start turning right
|
||
|
aRotation = +ROTATE_SPEED;
|
||
|
// if desired position is more-less ahead
|
||
|
} else {
|
||
|
aRotation = aWantedHeadingRelative/MOVE_FREQUENCY;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// calculate angle from position
|
||
|
void CalcAngleFromPosition() {
|
||
|
// find relative orientation towards the desired position
|
||
|
m_vDesiredAngle = (m_vDesiredPosition - GetPlacement().pl_PositionVector).Normalize();
|
||
|
};
|
||
|
|
||
|
// rotate entity to desired angle
|
||
|
void RotateToAngle() {
|
||
|
// find relative heading towards the desired angle
|
||
|
ANGLE aRotation;
|
||
|
CalcHeadingRotation(GetRelativeHeading(m_vDesiredAngle), aRotation);
|
||
|
|
||
|
// start rotating
|
||
|
SetDesiredRotation(ANGLE3D(aRotation, 0, 0));
|
||
|
};
|
||
|
|
||
|
// move in direction
|
||
|
void MoveInDirection() {
|
||
|
RotateToAngle();
|
||
|
|
||
|
// determine translation speed
|
||
|
FLOAT3D vTranslation(0.0f, 0.0f, 0.0f);
|
||
|
vTranslation(3) = -MOVE_SPEED;
|
||
|
|
||
|
// start moving
|
||
|
SetDesiredTranslation(vTranslation);
|
||
|
};
|
||
|
|
||
|
// move entity to desired position
|
||
|
void MoveToPosition() {
|
||
|
CalcAngleFromPosition();
|
||
|
MoveInDirection();
|
||
|
};
|
||
|
|
||
|
// rotate entity to desired position
|
||
|
void RotateToPosition() {
|
||
|
CalcAngleFromPosition();
|
||
|
RotateToAngle();
|
||
|
};
|
||
|
|
||
|
// stop moving entity
|
||
|
void StopMoving() {
|
||
|
StopRotating();
|
||
|
StopTranslating();
|
||
|
};
|
||
|
|
||
|
// stop rotating entity
|
||
|
void StopRotating() {
|
||
|
SetDesiredRotation(ANGLE3D(0, 0, 0));
|
||
|
};
|
||
|
|
||
|
// stop translating
|
||
|
void StopTranslating() {
|
||
|
SetDesiredTranslation(FLOAT3D(0.0f, 0.0f, 0.0f));
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* ATTACK SPECIFIC *
|
||
|
************************************************************/
|
||
|
void SpinEntity(CEntity *pen) {
|
||
|
// don't spin air elemental and another twister
|
||
|
if (!(IsOfClass(pen, "Elemental") && ((CElemental&)*pen).m_EetType==ELT_AIR) &&
|
||
|
!(IsOfClass(pen, "Twister"))) {
|
||
|
if (pen->GetPhysicsFlags()&EPF_MOVABLE) {
|
||
|
// throw target away
|
||
|
FLOAT3D vSpeed;
|
||
|
vSpeed = FLOAT3D(en_mRotation(1, 2), en_mRotation(2, 2), en_mRotation(3, 2)) * m_fUpMultiply;
|
||
|
FLOAT3D vDiff = (pen->GetPlacement().pl_PositionVector - GetPlacement().pl_PositionVector).Normalize();
|
||
|
vSpeed += (vDiff*m_fDiffMultiply) * pen->en_mRotation;
|
||
|
// give absolute speed
|
||
|
((CMovableEntity&)*pen).en_vCurrentTranslationAbsolute = vSpeed;
|
||
|
((CMovableEntity&)*pen).en_aDesiredRotationRelative = ANGLE3D(180.0f, 0, 0);
|
||
|
// damage
|
||
|
FLOAT3D vDirection;
|
||
|
AnglesToDirectionVector(GetPlacement().pl_OrientationAngle, vDirection);
|
||
|
InflictDirectDamage(pen, m_penOwner, DMT_IMPACT, 0.1f, GetPlacement().pl_PositionVector, vDirection);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* P R O C E D U R E S *
|
||
|
************************************************************/
|
||
|
procedures:
|
||
|
// --->>> MAIN
|
||
|
Main(ETwister et) {
|
||
|
// remember the initial parameters
|
||
|
ASSERT(et.penOwner!=NULL);
|
||
|
m_penOwner = et.penOwner;
|
||
|
m_EtsSize = et.EtsSize;
|
||
|
|
||
|
// initialization
|
||
|
InitAsModel();
|
||
|
SetPhysicsFlags(EPF_TWISTER);
|
||
|
SetCollisionFlags(ECF_TWISTER);
|
||
|
SetFlags(GetFlags() | ENF_SEETHROUGH);
|
||
|
SetModel(MODEL_TWISTER);
|
||
|
SetModelMainTexture(TEXTURE_TWISTER);
|
||
|
|
||
|
// setup
|
||
|
switch(m_EtsSize) {
|
||
|
case TWS_SMALL:
|
||
|
m_fActionRadius = 10;
|
||
|
m_fActionTime = 10;
|
||
|
m_fUpMultiply = 5.0f;
|
||
|
m_fDiffMultiply = 1.0f;
|
||
|
break;
|
||
|
case TWS_BIG:
|
||
|
m_fActionRadius = 15;
|
||
|
m_fActionTime = 20;
|
||
|
m_fUpMultiply = 10.0f;
|
||
|
m_fDiffMultiply = 4.0f;
|
||
|
GetModelObject()->StretchModel(FLOAT3D(4.0f, 4.0f, 4.0f));
|
||
|
break;
|
||
|
case TWS_LARGE:
|
||
|
m_fActionRadius = 20;
|
||
|
m_fActionTime = 30;
|
||
|
m_fUpMultiply = 20.0f;
|
||
|
m_fDiffMultiply = 16.0f;
|
||
|
GetModelObject()->StretchModel(FLOAT3D(16.0f, 16.0f, 16.0f));
|
||
|
break;
|
||
|
}
|
||
|
ModelChangeNotify();
|
||
|
|
||
|
// start position
|
||
|
m_vStartPosition = GetPlacement().pl_PositionVector;
|
||
|
|
||
|
// move in range
|
||
|
m_fStopTime = _pTimer->CurrentTick() + 10.0f;
|
||
|
while(_pTimer->CurrentTick() < m_fStopTime) {
|
||
|
// new destination
|
||
|
FLOAT fR = FRnd()*10.0f;
|
||
|
FLOAT fA = FRnd()*360.0f;
|
||
|
m_vDesiredPosition = m_vStartPosition + FLOAT3D(CosFast(fA)*fR, 0, SinFast(fA)*fR);
|
||
|
while((m_vDesiredPosition - GetPlacement().pl_PositionVector).Length() > MOVE_SPEED*MOVE_FREQUENCY*2.0f &&
|
||
|
_pTimer->CurrentTick() < m_fStopTime) {
|
||
|
MoveToPosition();
|
||
|
wait(MOVE_FREQUENCY) {
|
||
|
on (EBegin) : { resume; }
|
||
|
on (ETimer) : { stop; }
|
||
|
on (EPass ep) : {
|
||
|
if (ep.penOther->GetRenderType()&RT_MODEL &&
|
||
|
ep.penOther->GetPhysicsFlags()&EPF_MOVABLE) {
|
||
|
SpinEntity(ep.penOther);
|
||
|
}
|
||
|
resume;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// fade out
|
||
|
m_fFadeStartTime = _pTimer->CurrentTick();
|
||
|
m_bFadeOut = TRUE;
|
||
|
m_fFadeTime = 2.0f;
|
||
|
autowait(m_fFadeTime);
|
||
|
|
||
|
// cease to exist
|
||
|
Destroy();
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
};
|