mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-25 03:40:26 +01:00
271 lines
7.3 KiB
C++
271 lines
7.3 KiB
C++
|
511
|
||
|
%{
|
||
|
#include "Entities/StdH/StdH.h"
|
||
|
%}
|
||
|
|
||
|
uses "Entities/BasicEffects";
|
||
|
uses "Entities/Light";
|
||
|
|
||
|
// input parameter for launching the projectile
|
||
|
event EDevilProjectile {
|
||
|
CEntityPointer penLauncher, // who launched it
|
||
|
CEntityPointer penTarget, // target entity
|
||
|
};
|
||
|
|
||
|
|
||
|
%{
|
||
|
#define FLY_TIME 15.0f
|
||
|
#define ROTATE_SPEED 200.0f
|
||
|
#define MOVING_SPEED 30.0f
|
||
|
#define MOVING_FREQUENCY 0.1f
|
||
|
%}
|
||
|
|
||
|
|
||
|
class CDevilProjectile : CMovableModelEntity {
|
||
|
name "Devil projectile";
|
||
|
thumbnail "";
|
||
|
|
||
|
properties:
|
||
|
1 CEntityPointer m_penLauncher, // who lanuched it
|
||
|
2 CEntityPointer m_penTarget, // target entity
|
||
|
|
||
|
10 FLOAT m_fIgnoreTime = 0.0f, // time when laucher will be ignored
|
||
|
11 FLOAT m_fStartTime = 0.0f, // start time when launched
|
||
|
12 FLOAT3D m_vDesiredAngle = FLOAT3D(0,0,0),
|
||
|
13 BOOL m_bFly = FALSE,
|
||
|
|
||
|
20 CSoundObject m_soEffect, // sound channel
|
||
|
|
||
|
{
|
||
|
CLightSource m_lsLightSource;
|
||
|
}
|
||
|
|
||
|
components:
|
||
|
1 class CLASS_BASIC_EFFECT "Classes\\BasicEffect.ecl",
|
||
|
2 class CLASS_LIGHT "Classes\\Light.ecl",
|
||
|
|
||
|
// ********* PLAYER ROCKET *********
|
||
|
10 model MODEL_FLARE "Models\\Enemies\\Devil\\Flare.mdl",
|
||
|
11 texture TEXTURE_FLARE "Models\\Enemies\\Devil\\12.tex",
|
||
|
|
||
|
|
||
|
functions:
|
||
|
/* Read from stream. */
|
||
|
void Read_t( CTStream *istr) // throw char *
|
||
|
{
|
||
|
CMovableModelEntity::Read_t(istr);
|
||
|
// setup light source
|
||
|
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_rHotSpot = 0.0f;
|
||
|
lsNew.ls_colColor = RGBToColor(0, 128, 128);
|
||
|
lsNew.ls_rFallOff = 5.0f;
|
||
|
lsNew.ls_plftLensFlare = NULL;
|
||
|
lsNew.ls_ubPolygonalMask = 0;
|
||
|
lsNew.ls_paoLightAnimation = NULL;
|
||
|
|
||
|
m_lsLightSource.ls_penEntity = this;
|
||
|
m_lsLightSource.SetLightSource(lsNew);
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* 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*MOVING_FREQUENCY) {
|
||
|
// start turning left
|
||
|
aRotation = -ROTATE_SPEED;
|
||
|
// if desired position is right
|
||
|
} else if (aWantedHeadingRelative > ROTATE_SPEED*MOVING_FREQUENCY) {
|
||
|
// start turning right
|
||
|
aRotation = +ROTATE_SPEED;
|
||
|
// if desired position is more-less ahead
|
||
|
} else {
|
||
|
aRotation = aWantedHeadingRelative/MOVING_FREQUENCY;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// calculate angle from position
|
||
|
void CalcAngleFromPosition() {
|
||
|
// target enemy body
|
||
|
FLOAT3D vTarget;
|
||
|
/* EntityInfo *peiTarget = (EntityInfo*) (m_penTarget->GetEntityInfo());
|
||
|
GetEntityInfoPosition(m_penTarget, peiTarget->vTargetCenter, vTarget);*/
|
||
|
vTarget = m_penTarget->GetPlacement().pl_PositionVector;
|
||
|
vTarget += FLOAT3D(m_penTarget->en_mRotation(1, 2),
|
||
|
m_penTarget->en_mRotation(2, 2),
|
||
|
m_penTarget->en_mRotation(3, 2)) * 2.0f;
|
||
|
|
||
|
// find relative orientation towards the desired position
|
||
|
m_vDesiredAngle = (vTarget - 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));
|
||
|
};
|
||
|
|
||
|
// fly move in direction
|
||
|
void FlyInDirection() {
|
||
|
RotateToAngle();
|
||
|
|
||
|
// target enemy body
|
||
|
FLOAT3D vTarget;
|
||
|
/* EntityInfo *peiTarget = (EntityInfo*) (m_penTarget->GetEntityInfo());
|
||
|
GetEntityInfoPosition(m_penTarget, peiTarget->vTargetCenter, vTarget);*/
|
||
|
vTarget = m_penTarget->GetPlacement().pl_PositionVector;
|
||
|
vTarget += FLOAT3D(m_penTarget->en_mRotation(1, 2),
|
||
|
m_penTarget->en_mRotation(2, 2),
|
||
|
m_penTarget->en_mRotation(3, 2)) * 2.0f;
|
||
|
|
||
|
// determine translation speed
|
||
|
FLOAT3D vTranslation = (vTarget - GetPlacement().pl_PositionVector) * !en_mRotation;
|
||
|
vTranslation(1) = 0.0f;
|
||
|
vTranslation.Normalize();
|
||
|
vTranslation *= MOVING_SPEED;
|
||
|
|
||
|
// start moving
|
||
|
SetDesiredTranslation(vTranslation);
|
||
|
};
|
||
|
|
||
|
// fly entity to desired position
|
||
|
void FlyToPosition() {
|
||
|
CalcAngleFromPosition();
|
||
|
FlyInDirection();
|
||
|
};
|
||
|
|
||
|
// 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));
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* C O M M O N F U N C T I O N S *
|
||
|
************************************************************/
|
||
|
void ProjectileTouch(CEntityPointer penHit) {
|
||
|
// direct damage
|
||
|
FLOAT3D vDirection;
|
||
|
AnglesToDirectionVector(GetPlacement().pl_OrientationAngle, vDirection);
|
||
|
InflictDirectDamage(penHit, m_penLauncher, DMT_PROJECTILE, 15.0f,
|
||
|
GetPlacement().pl_PositionVector, vDirection);
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
/************************************************************
|
||
|
* P R O C E D U R E S *
|
||
|
************************************************************/
|
||
|
procedures:
|
||
|
Fly(EVoid) {
|
||
|
// bounce loop
|
||
|
m_bFly = TRUE;
|
||
|
while(m_bFly && m_fStartTime+FLY_TIME > _pTimer->CurrentTick()) {
|
||
|
wait(0.1f) {
|
||
|
on (EBegin) : {
|
||
|
FlyToPosition();
|
||
|
resume;
|
||
|
}
|
||
|
on (EPass epass) : {
|
||
|
BOOL bHit;
|
||
|
// ignore launcher within 1 second
|
||
|
bHit = epass.penOther!=m_penLauncher || _pTimer->CurrentTick()>m_fIgnoreTime;
|
||
|
// ignore twister
|
||
|
bHit &= !IsOfClass(epass.penOther, "Twister");
|
||
|
if (bHit) {
|
||
|
ProjectileTouch(epass.penOther);
|
||
|
m_bFly = FALSE;
|
||
|
stop;
|
||
|
}
|
||
|
resume;
|
||
|
}
|
||
|
on (ETouch etouch) : {
|
||
|
// clear time limit for launcher
|
||
|
m_fIgnoreTime = 0.0f;
|
||
|
resume;
|
||
|
}
|
||
|
on (ETimer) : { stop; }
|
||
|
}
|
||
|
}
|
||
|
return EEnd();
|
||
|
};
|
||
|
|
||
|
// --->>> MAIN
|
||
|
Main(EDevilProjectile eLaunch) {
|
||
|
// remember the initial parameters
|
||
|
ASSERT(eLaunch.penLauncher!=NULL);
|
||
|
ASSERT(eLaunch.penTarget!=NULL);
|
||
|
m_penLauncher = eLaunch.penLauncher;
|
||
|
m_penTarget = eLaunch.penTarget;
|
||
|
|
||
|
// set appearance
|
||
|
InitAsModel();
|
||
|
SetPhysicsFlags(EPF_PROJECTILE_FLYING);
|
||
|
SetCollisionFlags(ECF_PROJECTILE_MAGIC);
|
||
|
SetModel(MODEL_FLARE);
|
||
|
SetModelMainTexture(TEXTURE_FLARE);
|
||
|
|
||
|
// setup light source
|
||
|
SetupLightSource();
|
||
|
|
||
|
// remember lauching time
|
||
|
m_fIgnoreTime = _pTimer->CurrentTick() + 1.0f;
|
||
|
|
||
|
// fly
|
||
|
m_fStartTime = _pTimer->CurrentTick();
|
||
|
autocall Fly() EEnd;
|
||
|
|
||
|
// cease to exist
|
||
|
Destroy();
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
};
|