|
|
|
/***
|
|
|
|
*
|
|
|
|
* 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 BornThink ( void );
|
|
|
|
void EXPORT IdleThink ( void );
|
|
|
|
void EXPORT AmmoTouch ( CBaseEntity *pOther );
|
|
|
|
int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType );
|
|
|
|
|
|
|
|
int Save( CSave &save );
|
|
|
|
int Restore( CRestore &restore );
|
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
|
|
|
|
|
|
|
virtual int SizeForGrapple() { return GRAPPLE_FIXED; }
|
|
|
|
|
|
|
|
int m_iExplode;
|
|
|
|
BOOL borntime;
|
|
|
|
float m_flTimeSporeIdle;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
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 )
|
|
|
|
|
|
|
|
TYPEDESCRIPTION CSporeAmmo::m_SaveData[] =
|
|
|
|
{
|
|
|
|
DEFINE_FIELD( CSporeAmmo, m_flTimeSporeIdle, FIELD_TIME ),
|
|
|
|
DEFINE_FIELD( CSporeAmmo, borntime, FIELD_BOOLEAN ),
|
|
|
|
};
|
|
|
|
IMPLEMENT_SAVERESTORE( CSporeAmmo, CBaseEntity )
|
|
|
|
|
|
|
|
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.0;
|
|
|
|
pev->animtime = gpGlobals->time + 0.1;
|
|
|
|
|
|
|
|
pev->sequence = SPOREAMMO_IDLE1;
|
|
|
|
pev->body = 1;
|
|
|
|
|
|
|
|
Vector vecOrigin = pev->origin;
|
|
|
|
vecOrigin.z += 16;
|
|
|
|
UTIL_SetOrigin( pev, vecOrigin );
|
|
|
|
|
|
|
|
pev->angles.x -= 90;// :3
|
|
|
|
|
|
|
|
SetThink (&CSporeAmmo::IdleThink);
|
|
|
|
SetTouch (&CSporeAmmo::AmmoTouch);
|
|
|
|
|
|
|
|
m_flTimeSporeIdle = gpGlobals->time + 20;
|
|
|
|
pev->nextthink = gpGlobals->time + 0.1;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
// Override all damage
|
|
|
|
//=========================================================
|
|
|
|
int CSporeAmmo::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType )
|
|
|
|
{
|
|
|
|
if (!borntime) // rigth '!borntime' // blast in anytime 'borntime || !borntime'
|
|
|
|
{
|
|
|
|
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 );
|
|
|
|
|
|
|
|
UTIL_MakeVectors( vecLaunchDir );
|
|
|
|
CSporeGrenade::ShootTimed(pevAttacker, vecSrc, gpGlobals->v_forward * 800, false);
|
|
|
|
|
|
|
|
pev->framerate = 1.0;
|
|
|
|
pev->animtime = gpGlobals->time + 0.1;
|
|
|
|
pev->sequence = SPOREAMMO_SNATCHDOWN;
|
|
|
|
pev->body = 0;
|
|
|
|
borntime = 1;
|
|
|
|
m_flTimeSporeIdle = gpGlobals->time + 1;
|
|
|
|
SetThink (&CSporeAmmo::IdleThink);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=========================================================
|
|
|
|
// Thinking begin
|
|
|
|
//=========================================================
|
|
|
|
void CSporeAmmo :: BornThink ( void )
|
|
|
|
{
|
|
|
|
pev->nextthink = gpGlobals->time + 0.1;
|
|
|
|
|
|
|
|
if ( m_flTimeSporeIdle > gpGlobals->time )
|
|
|
|
return;
|
|
|
|
|
|
|
|
pev->sequence = SPOREAMMO_SPAWNDOWN;
|
|
|
|
pev->framerate = 1.0;
|
|
|
|
pev->animtime = gpGlobals->time + 0.1;
|
|
|
|
pev->body = 1;
|
|
|
|
borntime = 0;
|
|
|
|
SetThink (&CSporeAmmo::IdleThink);
|
|
|
|
|
|
|
|
m_flTimeSporeIdle = gpGlobals->time + 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSporeAmmo :: IdleThink ( void )
|
|
|
|
{
|
|
|
|
|
|
|
|
pev->nextthink = gpGlobals->time + 0.1;
|
|
|
|
if ( m_flTimeSporeIdle > gpGlobals->time )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (borntime)
|
|
|
|
{
|
|
|
|
pev->sequence = SPOREAMMO_IDLE;
|
|
|
|
|
|
|
|
m_flTimeSporeIdle = gpGlobals->time + 10;
|
|
|
|
SetThink(&CSporeAmmo::BornThink);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pev->sequence = SPOREAMMO_IDLE1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CSporeAmmo :: AmmoTouch ( CBaseEntity *pOther )
|
|
|
|
{
|
|
|
|
if ( !pOther->IsPlayer() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (borntime)
|
|
|
|
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->framerate = 1.0;
|
|
|
|
pev->animtime = gpGlobals->time + 0.1;
|
|
|
|
pev->sequence = SPOREAMMO_SNATCHDOWN;
|
|
|
|
pev->body = 0;
|
|
|
|
borntime = 1;
|
|
|
|
m_flTimeSporeIdle = gpGlobals->time + 1;
|
|
|
|
SetThink (&CSporeAmmo::IdleThink);
|
|
|
|
}
|
|
|
|
}
|