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

230 lines
6.4 KiB
C++

505
%{
#include "Entities/StdH/StdH.h"
%}
uses "Entities/Light";
uses "Entities/Bullet";
uses "Entities/PlayerWeapons";
uses "Engine/Classes/MovableEntity";
// input parameter for ghost buster ray
event EGhostBusterRay {
CEntityPointer penOwner, // entity which owns it
};
%{
#define HIT_DISTANCE 50.0f // ray hit distance
#define HIT_DAMAGE 15.0f // hit damage for every lerping bullet
void CGhostBusterRay_OnPrecache(CDLLEntityClass *pdec, INDEX iUser)
{
pdec->PrecacheClass(CLASS_BULLET);
pdec->PrecacheModel(MODEL_RAY);
pdec->PrecacheTexture(TEXTURE_RAY);
}
%}
class CGhostBusterRay : CMovableModelEntity {
name "GhostBusterRay";
thumbnail "";
features "ImplementsOnPrecache", "CanBePredictable";
properties:
1 CEntityPointer m_penOwner, // entity which owns it
2 BOOL m_bRender = FALSE, // do not render on startup
3 FLOAT3D m_vSrcOld = FLOAT3D(0.0f, 0.0f, 0.0f),
4 FLOAT3D m_vDstOld = FLOAT3D(0.0f, 0.0f, 0.0f),
5 FLOAT3D m_vSrc = FLOAT3D(0.0f, 0.0f, 0.0f),
6 FLOAT3D m_vDst = FLOAT3D(0.0f, 0.0f, 0.0f),
10 FLOAT3D m_iLastBulletPosition = FLOAT3D(32000.0f, 32000.0f, 32000.0f), // for lerping
11 CAnimObject m_aoLightAnim,
12 INDEX m_ctPasses = 0, // for lerping initialization
{
CLightSource m_lsLightSource;
CEntity *penBullet;
const CPlacement3D *pplSource;
}
components:
1 class CLASS_LIGHT "Classes\\Light.ecl",
2 class CLASS_BULLET "Classes\\Bullet.ecl",
// ********* RAY *********
10 model MODEL_RAY "Models\\Weapons\\GhostBuster\\Projectile\\Ray.mdl",
11 texture TEXTURE_RAY "Models\\Weapons\\GhostBuster\\Projectile\\Ray.tex",
functions:
// add to prediction any entities that this entity depends on
void AddDependentsToPrediction(void)
{
m_penOwner->AddToPrediction();
}
// render particles
void RenderParticles(void)
{
if (m_ctPasses<2) {
return;
}
FLOAT3D vLerpedSrc = Lerp(m_vSrcOld, m_vSrc, _pTimer->GetLerpFactor());
FLOAT3D vLerpedDst = Lerp(m_vDstOld, m_vDst, _pTimer->GetLerpFactor());
Particles_Ghostbuster(vLerpedSrc, vLerpedDst, 32, 1.0f);
};
/* Read from stream. */
void Read_t( CTStream *istr) // throw char *
{
CMovableModelEntity::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 = RGBToColor(134,238,255);
lsNew.ls_rFallOff = 10.0f;
lsNew.ls_rHotSpot = 1.0f;
lsNew.ls_plftLensFlare = NULL;
lsNew.ls_ubPolygonalMask = 0;
lsNew.ls_paoLightAnimation = &m_aoLightAnim;
m_lsLightSource.ls_penEntity = this;
m_lsLightSource.SetLightSource(lsNew);
};
/************************************************************
* DO MOVING *
************************************************************/
void DoMoving(void) {
en_plLastPlacement = GetPlacement(); // remember old placement for lerping
};
void PostMoving(void) {
if (!IsOfClass(m_penOwner, "Player Weapons")) { return; }
// from current owner position move away
CPlacement3D plSource;
((CPlayerWeapons&)*m_penOwner).GetGhostBusterSourcePlacement(plSource);
FLOAT3D vDirection, vDesired;
AnglesToDirectionVector(plSource.pl_OrientationAngle, vDirection);
vDesired = vDirection*HIT_DISTANCE;
vDesired = plSource.pl_PositionVector + vDesired;
// cast a ray to find if any brush is hit
CCastRay crRay( ((CPlayerWeapons&)*m_penOwner).m_penPlayer, plSource.pl_PositionVector, vDesired);
m_vSrcOld = m_vSrc;
m_vSrc = plSource.pl_PositionVector;
crRay.cr_bHitTranslucentPortals = FALSE;
crRay.cr_ttHitModels = CCastRay::TT_COLLISIONBOX;
GetWorld()->CastRay(crRay);
// if hit anything set new position
if (crRay.cr_penHit!=NULL) {
vDesired = crRay.cr_vHit;
}
vDesired -= vDirection/10.0f;
m_vDstOld = m_vDst;
m_vDst = vDesired;
// stretch model
FLOAT fStretch = (plSource.pl_PositionVector - vDesired).Length();
//GetModelObject()->mo_Stretch(3) = fStretch;
GetModelObject()->mo_Stretch(3) = 0.001f;
// set your new placement
CPlacement3D plSet;
plSet.pl_PositionVector = vDesired;
plSet.pl_OrientationAngle = plSource.pl_OrientationAngle;
SetPlacement(plSet);
m_ctPasses++;
};
/************************************************************
* FIRE FUNCTIONS *
************************************************************/
// prepare Bullet
void PrepareBullet(const CPlacement3D &plBullet) {
// create bullet
penBullet = CreateEntity(plBullet, CLASS_BULLET);
// init bullet
EBulletInit eInit;
eInit.penOwner = ((CPlayerWeapons&)*m_penOwner).m_penPlayer;
eInit.fDamage = HIT_DAMAGE;
penBullet->Initialize(eInit);
((CBullet&)*penBullet).m_EdtDamage = DMT_BULLET;
};
// fire
void Fire(const CPlacement3D &plSource) {
if (!IsOfClass(m_penOwner, "Player Weapons")) { return; }
// fire lerped bullets
PrepareBullet(plSource);
((CBullet&)*penBullet).CalcTarget(HIT_DISTANCE);
((CBullet&)*penBullet).m_fBulletSize = 0.5f;
((CBullet&)*penBullet).CalcJitterTarget(0.02f*HIT_DISTANCE);
((CBullet&)*penBullet).LaunchBullet(TRUE, FALSE, TRUE);
((CBullet&)*penBullet).DestroyBullet();
};
// destroy yourself
void DestroyGhostBusterRay(void) {
Destroy();
};
/************************************************************
* P R O C E D U R E S *
************************************************************/
procedures:
// --->>> MAIN
Main(EGhostBusterRay egbr) {
// store owner
ASSERT(egbr.penOwner!=NULL);
m_penOwner = egbr.penOwner;
// initialization
InitAsModel();
SetPhysicsFlags(EPF_MODEL_IMMATERIAL);
SetCollisionFlags(ECF_IMMATERIAL);
SetModel(MODEL_RAY);
SetModelMainTexture(TEXTURE_RAY);
try {
m_aoLightAnim.SetData_t(CTFILENAME("Animations\\GhostbusterLightning.ani"));
m_aoLightAnim.PlayAnim(0,AOF_LOOPING);
} catch (char *strError) {
CPrintF("%s", strError);
}
// setup light source
SetupLightSource();
// add to movers list
AddToMovers();
m_ctPasses = 0;
return;
}
};