|
|
|
/***
|
|
|
|
*
|
|
|
|
* Copyright (c) 1996-2001, Valve LLC. All rights reserved.
|
|
|
|
*
|
|
|
|
* This product contains software technology licensed from Id
|
|
|
|
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
|
|
|
|
* All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use, distribution, and modification of this source code and/or resulting
|
|
|
|
* object code is restricted to non-commercial enhancements to products from
|
|
|
|
* Valve LLC. All other use, distribution, or modification is prohibited
|
|
|
|
* without written permission from Valve LLC.
|
|
|
|
*
|
|
|
|
****/
|
|
|
|
|
|
|
|
#include "extdll.h"
|
|
|
|
#include "util.h"
|
|
|
|
#include "cbase.h"
|
|
|
|
#include "monsters.h"
|
|
|
|
#include "weapons.h"
|
|
|
|
#include "nodes.h"
|
|
|
|
#include "player.h"
|
|
|
|
#include "gamerules.h"
|
|
|
|
#include "sporegrenade.h"
|
|
|
|
|
|
|
|
class CSporeAmmo : public CBaseEntity
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void Spawn( void );
|
|
|
|
void Precache( void );
|
|
|
|
void EXPORT IdleThink ( void );
|
|
|
|
void EXPORT AmmoTouch ( CBaseEntity *pOther );
|
|
|
|
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
|
|
|
|
|
|
|
|
virtual int SizeForGrapple() { return GRAPPLE_FIXED; }
|
|
|
|
|
|
|
|
int m_iExplode;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
SPOREAMMO_IDLE = 0,
|
|
|
|
SPOREAMMO_SPAWNUP,
|
|
|
|
SPOREAMMO_SNATCHUP,
|
|
|
|
SPOREAMMO_SPAWNDOWN,
|
|
|
|
SPOREAMMO_SNATCHDOWN,
|
|
|
|
SPOREAMMO_IDLE1,
|
|
|
|
SPOREAMMO_IDLE2,
|
|
|
|
} SPOREAMMO;
|
|
|
|
|
|
|
|
LINK_ENTITY_TO_CLASS( ammo_spore, CSporeAmmo )
|
|
|
|
|
|
|
|
void CSporeAmmo :: Precache( void )
|
|
|
|
{
|
|
|
|
PRECACHE_MODEL("models/spore_ammo.mdl");
|
|
|
|
m_iExplode = PRECACHE_MODEL ("sprites/spore_exp_c_01.spr");
|
|
|
|
PRECACHE_SOUND("weapons/spore_ammo.wav");
|
|
|
|
UTIL_PrecacheOther ( "spore" );
|
|
|
|
}
|
|
|
|
//=========================================================
|
|
|
|
// Spawn
|
|
|
|
//=========================================================
|
|
|
|
void CSporeAmmo :: Spawn( void )
|
|
|
|
{
|
|
|
|
Precache( );
|
|
|
|
SET_MODEL(ENT(pev), "models/spore_ammo.mdl");
|
|
|
|
UTIL_SetSize(pev, Vector( -16, -16, -16 ), Vector( 16, 16, 16 ));
|
|
|
|
pev->takedamage = DAMAGE_YES;
|
|
|
|
pev->solid = SOLID_BBOX;
|
|
|
|
pev->movetype = MOVETYPE_NONE;
|
|
|
|
pev->framerate = 1.0f;
|
|
|
|
pev->health = 1.0f;
|
|
|
|
pev->animtime = gpGlobals->time;
|
|
|
|
|
|
|
|
pev->sequence = SPOREAMMO_SPAWNDOWN;
|
|
|
|
pev->body = 1;
|
|
|
|
|
|
|
|
pev->origin.z += 16;
|
|
|
|
UTIL_SetOrigin( pev, pev->origin );
|
|
|
|
|
|
|
|
pev->angles.x -= 90;// :3
|
|
|
|
|
|
|
|
SetThink (&CSporeAmmo::IdleThink);
|
|
|
|
SetTouch (&CSporeAmmo::AmmoTouch);
|
|
|
|
|
|
|
|
pev->nextthink = gpGlobals->time + 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
// Override all damage
|
|
|
|
//=========================================================
|
|
|
|
int CSporeAmmo::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
|
|
|
|
{
|
|
|
|
if (pev->body != 0)
|
|
|
|
{
|
|
|
|
Vector vecSrc = pev->origin + gpGlobals->v_forward * -32;
|
|
|
|
|
|
|
|
MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
|
|
|
|
WRITE_BYTE( TE_EXPLOSION ); // This makes a dynamic light and the explosion sprites/sound
|
|
|
|
WRITE_COORD( vecSrc.x ); // Send to PAS because of the sound
|
|
|
|
WRITE_COORD( vecSrc.y );
|
|
|
|
WRITE_COORD( vecSrc.z );
|
|
|
|
WRITE_SHORT( m_iExplode );
|
|
|
|
WRITE_BYTE( 25 ); // scale * 10
|
|
|
|
WRITE_BYTE( 12 ); // framerate
|
|
|
|
WRITE_BYTE( TE_EXPLFLAG_NOSOUND );
|
|
|
|
MESSAGE_END();
|
|
|
|
|
|
|
|
|
|
|
|
//ALERT( at_console, "angles %f %f %f\n", pev->angles.x, pev->angles.y, pev->angles.z );
|
|
|
|
|
|
|
|
Vector angles = pev->angles;
|
|
|
|
angles.x -= 90;
|
|
|
|
angles.y += 180;
|
|
|
|
|
|
|
|
Vector vecLaunchDir = angles;
|
|
|
|
|
|
|
|
vecLaunchDir.x += RANDOM_FLOAT( -20, 20 );
|
|
|
|
vecLaunchDir.y += RANDOM_FLOAT( -20, 20 );
|
|
|
|
vecLaunchDir.z += RANDOM_FLOAT( -20, 20 );
|
|
|
|
|
|
|
|
CSpore* pSpore = CSpore::CreateSpore(pev->origin, vecLaunchDir, this, CSpore::GRENADE, false, true);
|
|
|
|
UTIL_MakeVectors( vecLaunchDir );
|
|
|
|
pSpore->pev->velocity = gpGlobals->v_forward * 800;
|
|
|
|
|
|
|
|
pev->frame = 0;
|
|
|
|
pev->animtime = gpGlobals->time + 0.1;
|
|
|
|
pev->sequence = SPOREAMMO_SNATCHDOWN;
|
|
|
|
pev->body = 0;
|
|
|
|
pev->nextthink = gpGlobals->time + 0.66f;
|
|
|
|
SetThink (&CSporeAmmo::IdleThink);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSporeAmmo :: IdleThink ( void )
|
|
|
|
{
|
|
|
|
switch (pev->sequence)
|
|
|
|
{
|
|
|
|
case SPOREAMMO_SPAWNDOWN:
|
|
|
|
{
|
|
|
|
pev->sequence = SPOREAMMO_IDLE1;
|
|
|
|
pev->animtime = gpGlobals->time;
|
|
|
|
pev->frame = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SPOREAMMO_SNATCHDOWN:
|
|
|
|
{
|
|
|
|
pev->sequence = SPOREAMMO_IDLE;
|
|
|
|
pev->animtime = gpGlobals->time;
|
|
|
|
pev->frame = 0;
|
|
|
|
pev->nextthink = gpGlobals->time + 10.0f;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case SPOREAMMO_IDLE:
|
|
|
|
{
|
|
|
|
pev->body = 1;
|
|
|
|
pev->sequence = SPOREAMMO_SPAWNDOWN;
|
|
|
|
pev->animtime = gpGlobals->time;
|
|
|
|
pev->frame = 0;
|
|
|
|
pev->nextthink = gpGlobals->time + 4.0f;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSporeAmmo :: AmmoTouch ( CBaseEntity *pOther )
|
|
|
|
{
|
|
|
|
if ( !pOther->IsPlayer() || pev->body == 0 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
int bResult = (pOther->GiveAmmo( AMMO_SPORE_GIVE, "spores", SPORE_MAX_CARRY ) != -1);
|
|
|
|
if (bResult)
|
|
|
|
{
|
|
|
|
EMIT_SOUND(ENT(pev), CHAN_ITEM, "weapons/spore_ammo.wav", 1, ATTN_NORM);
|
|
|
|
|
|
|
|
pev->frame = 0;
|
|
|
|
pev->animtime = gpGlobals->time;
|
|
|
|
pev->sequence = SPOREAMMO_SNATCHDOWN;
|
|
|
|
pev->body = 0;
|
|
|
|
pev->nextthink = gpGlobals->time + 0.66f;
|
|
|
|
}
|
|
|
|
}
|