|
|
|
//=========== (C) Copyright 1996-2002, Valve, L.L.C. All rights reserved. ===========
|
|
|
|
//
|
|
|
|
// The copyright to the contents herein is the property of Valve, L.L.C.
|
|
|
|
// The contents may be used and/or copied only with the written permission of
|
|
|
|
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
|
|
|
|
// the agreement/contract under which the contents have been supplied.
|
|
|
|
//
|
|
|
|
// Purpose: Quake rocket entity
|
|
|
|
//
|
|
|
|
// $Workfile: $
|
|
|
|
// $Date: $
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// $Log: $
|
|
|
|
//
|
|
|
|
// $NoKeywords: $
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include "extdll.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "cbase.h"
|
|
|
|
#include "weapons.h"
|
|
|
|
|
|
|
|
#define GRENADE_TRAIL 1
|
|
|
|
#define ROCKET_TRAIL 2
|
|
|
|
|
|
|
|
extern unsigned short g_sTrail;
|
|
|
|
extern unsigned short g_sExplosion;
|
|
|
|
|
|
|
|
LINK_ENTITY_TO_CLASS( quake_rocket, CQuakeRocket );
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
CQuakeRocket *CQuakeRocket::CreateRocket( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner )
|
|
|
|
{
|
|
|
|
CQuakeRocket *pRocket = GetClassPtr( (CQuakeRocket *)NULL );
|
|
|
|
|
|
|
|
UTIL_SetOrigin( pRocket->pev, vecOrigin );
|
|
|
|
SET_MODEL(ENT(pRocket->pev), "models/rocket.mdl");
|
|
|
|
pRocket->Spawn();
|
|
|
|
pRocket->pev->classname = MAKE_STRING("missile");
|
|
|
|
pRocket->pev->owner = pOwner->edict();
|
|
|
|
|
|
|
|
// Setup
|
|
|
|
pRocket->pev->movetype = MOVETYPE_FLYMISSILE;
|
|
|
|
pRocket->pev->solid = SOLID_BBOX;
|
|
|
|
|
|
|
|
// Velocity
|
|
|
|
pRocket->pev->velocity = vecAngles * 1000;
|
|
|
|
pRocket->pev->angles = UTIL_VecToAngles( vecAngles );
|
|
|
|
|
|
|
|
// Touch
|
|
|
|
pRocket->SetTouch( &CQuakeRocket::RocketTouch );
|
|
|
|
|
|
|
|
// Safety Remove
|
|
|
|
pRocket->pev->nextthink = gpGlobals->time + 5;
|
|
|
|
pRocket->SetThink( &CBaseEntity::SUB_Remove );
|
|
|
|
|
|
|
|
// Effects
|
|
|
|
// pRocket->pev->effects |= EF_LIGHT;
|
|
|
|
|
|
|
|
PLAYBACK_EVENT_FULL (FEV_GLOBAL, pRocket->edict(), g_sTrail, 0.0,
|
|
|
|
(float *)&pRocket->pev->origin, (float *)&pRocket->pev->angles, 0.7, 0.0, pRocket->entindex(), ROCKET_TRAIL, 0, 0);
|
|
|
|
|
|
|
|
return pRocket;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
CQuakeRocket *CQuakeRocket::CreateGrenade( Vector vecOrigin, Vector vecVelocity, CBaseEntity *pOwner )
|
|
|
|
{
|
|
|
|
CQuakeRocket *pRocket = GetClassPtr( (CQuakeRocket *)NULL );
|
|
|
|
|
|
|
|
UTIL_SetOrigin( pRocket->pev, vecOrigin );
|
|
|
|
SET_MODEL(ENT(pRocket->pev), "models/grenade.mdl");
|
|
|
|
pRocket->Spawn();
|
|
|
|
pRocket->pev->classname = MAKE_STRING("grenade");
|
|
|
|
pRocket->pev->owner = pOwner->edict();
|
|
|
|
|
|
|
|
// Setup
|
|
|
|
pRocket->pev->movetype = MOVETYPE_BOUNCE;
|
|
|
|
pRocket->pev->solid = SOLID_BBOX;
|
|
|
|
|
|
|
|
pRocket->pev->avelocity = Vector(300,300,300);
|
|
|
|
|
|
|
|
// Velocity
|
|
|
|
pRocket->pev->velocity = vecVelocity;
|
|
|
|
pRocket->pev->angles = UTIL_VecToAngles(vecVelocity);
|
|
|
|
pRocket->pev->friction = 0.5;
|
|
|
|
|
|
|
|
// Touch
|
|
|
|
pRocket->SetTouch( &CQuakeRocket::GrenadeTouch );
|
|
|
|
|
|
|
|
// set newmis duration
|
|
|
|
if ( gpGlobals->deathmatch == 4 )
|
|
|
|
{
|
|
|
|
pRocket->m_flAttackFinished = gpGlobals->time + 1.1; // What's this used for?
|
|
|
|
if (pOwner)
|
|
|
|
pOwner->TakeDamage( pOwner->pev, pOwner->pev, 10, DMG_GENERIC );
|
|
|
|
}
|
|
|
|
|
|
|
|
pRocket->pev->nextthink = gpGlobals->time + 2.5;
|
|
|
|
pRocket->SetThink( &CQuakeRocket::GrenadeExplode );
|
|
|
|
|
|
|
|
PLAYBACK_EVENT_FULL (FEV_GLOBAL, pRocket->edict(), g_sTrail, 0.0,
|
|
|
|
(float *)&g_vecZero, (float *)&g_vecZero, 0.7, 0.0, pRocket->entindex(), GRENADE_TRAIL, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
return pRocket;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
void CQuakeRocket::Spawn( void )
|
|
|
|
{
|
|
|
|
Precache();
|
|
|
|
|
|
|
|
UTIL_SetSize(pev, g_vecZero, g_vecZero );
|
|
|
|
UTIL_SetOrigin( pev, pev->origin );
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
void CQuakeRocket::Precache( void )
|
|
|
|
{
|
|
|
|
m_iTrail = PRECACHE_MODEL("sprites/smoke.spr");
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
void CQuakeRocket::RocketTouch ( CBaseEntity *pOther )
|
|
|
|
{
|
|
|
|
// Remove if we've hit skybrush
|
|
|
|
if ( UTIL_PointContents(pev->origin) == CONTENT_SKY )
|
|
|
|
{
|
|
|
|
UTIL_Remove( this );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do touch damage
|
|
|
|
float flDmg = RANDOM_FLOAT( 100, 120 );
|
|
|
|
CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner);
|
|
|
|
if (pOther->pev->health)
|
|
|
|
pOther->TakeDamage( pev, pOwner->pev, flDmg, DMG_BULLET );
|
|
|
|
|
|
|
|
// Don't do radius damage to the other, because all the damage was done in the impact
|
|
|
|
Q_RadiusDamage(this, pOwner, 120, pOther);
|
|
|
|
|
|
|
|
// Finish and remove
|
|
|
|
Explode();
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
void CQuakeRocket::GrenadeTouch( CBaseEntity *pOther )
|
|
|
|
{
|
|
|
|
if (pOther->pev->takedamage == DAMAGE_AIM)
|
|
|
|
{
|
|
|
|
GrenadeExplode();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pev->flags & FL_ONGROUND)
|
|
|
|
{
|
|
|
|
// add a bit of static friction
|
|
|
|
pev->velocity = pev->velocity * 0.75;
|
|
|
|
if (pev->velocity.Length() <= 20)
|
|
|
|
{
|
|
|
|
pev->avelocity = g_vecZero;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EMIT_SOUND(ENT(pev), CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM);
|
|
|
|
|
|
|
|
if (pev->velocity == g_vecZero)
|
|
|
|
pev->avelocity = g_vecZero;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
void CQuakeRocket::GrenadeExplode()
|
|
|
|
{
|
|
|
|
CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner);
|
|
|
|
Q_RadiusDamage(this, pOwner, 120, NULL);
|
|
|
|
|
|
|
|
// Finish and remove
|
|
|
|
Explode();
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
void CQuakeRocket::Explode()
|
|
|
|
{
|
|
|
|
//We use the angles field to send the rocket velocity.
|
|
|
|
PLAYBACK_EVENT_FULL( FEV_GLOBAL, edict(), g_sExplosion, 0.0, (float *)&pev->origin, (float *)&pev->velocity, 0.0, 0.0, 0, 0, 0, 0 );
|
|
|
|
|
|
|
|
UTIL_Remove( this );
|
|
|
|
}
|