Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

191 lines
5.2 KiB

//=========== (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, Vector( 0, 0, 0), Vector(0, 0, 0));
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 );
}