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.

216 lines
5.4 KiB

/***
*
* 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);
}
}