mirror of
https://github.com/ptitSeb/Serious-Engine
synced 2024-11-22 10:20:26 +01:00
230 lines
6.4 KiB
C++
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;
|
|
}
|
|
};
|