// ---------------------------------------------------------------
// BubbleMod
//
// AUTHOR
// Tyler Lund <halflife@bubblemod.org>
//
// LICENSE
//
// Permission is granted to anyone to use this software for
// any purpose on any computer system, and to redistribute it
// in any way, subject to the following restrictions:
//
// 1. The author is not responsible for the consequences of
// use of this software, no matter how awful, even if they
// arise from defects in it.
// 2. The origin of this software must not be misrepresented,
// either by explicit claim or by omission.
// 3. Altered versions must be plainly marked as such, and
// must not be misrepresented (by explicit claim or
// omission) as being the original software.
// 3a. It would be nice if I got a copy of your improved
// version sent to halflife@bubblemod.org.
// 4. This notice must not be removed or altered.
//
// ---------------------------------------------------------------
# include "extdll.h"
# include "util.h"
# include "cbase.h"
# include "weapons.h"
# include "player.h"
# include "skill.h"
# include "items.h"
# include "gamerules.h"
# include "BMOD_rune.h"
# include "BMOD_messaging.h"
# include "BMOD_player.h"
# define RUNE_MODEL "models / w_oxygen.mdl"
extern DLL_GLOBAL BOOL g_runes_learn ;
extern cvar_t bm_runemask ;
void CRune : : Spawn ( void )
{
Precache ( ) ;
// SET_MODEL(ENT(pev), RUNE_MODEL);
pev - > movetype = MOVETYPE_BOUNCE ;
pev - > solid = SOLID_TRIGGER ;
pev - > classname = MAKE_STRING ( " rune " ) ;
pev - > renderfx | = kRenderFxGlowShell ;
pev - > rendercolor = m_vRuneColor ;
pev - > renderamt = 50 ;
m_randomize = FALSE ;
UTIL_SetOrigin ( pev , pev - > origin ) ;
UTIL_SetSize ( pev , Vector ( - 16 , - 16 , 0 ) , Vector ( 16 , 16 , 16 ) ) ;
SetTouch ( & CRune : : RuneTouch ) ;
pev - > effects | = EF_NODRAW ;
SetThink ( & CRune : : Materialize ) ;
pev - > nextthink = gpGlobals - > time + RANDOM_FLOAT ( .5 , 2 ) ;
if ( DROP_TO_FLOOR ( ENT ( pev ) ) = = 0 )
{
ALERT ( at_error , " Item %s fell out of level at %f,%f,%f " , STRING ( pev - > classname ) , pev - > origin . x , pev - > origin . y , pev - > origin . z ) ;
UTIL_Remove ( this ) ;
return ;
}
}
void CRune : : RuneTouch ( CBaseEntity * pOther )
{
// if it's not a player, just bounce
if ( ! pOther - > IsPlayer ( ) )
{
if ( ! pev - > velocity )
return ;
TraceResult tr ;
UTIL_TraceLine ( pev - > origin , pev - > origin - Vector ( 0 , 0 , 10 ) , ignore_monsters , edict ( ) , & tr ) ;
if ( tr . flFraction < 1.0 )
{
// add a bit of static friction
pev - > velocity = pev - > velocity * 0.5 ;
}
return ;
}
CBasePlayer * pPlayer = ( CBasePlayer * ) pOther ;
if ( ! pPlayer - > BMOD_IsASpawn ( ) & & MyTouch ( pPlayer ) )
{
pPlayer - > pev - > rendermode = kRenderNormal ;
pPlayer - > pev - > renderfx = kRenderFxGlowShell ;
pPlayer - > pev - > rendercolor = m_vRuneColor ;
pPlayer - > pev - > renderamt = 10 ; // glow shell distance from entity
SetTouch ( NULL ) ;
Respawn ( ) ;
}
}
CBaseEntity * CRune : : Respawn ( void )
{
pev - > effects | = EF_NODRAW ;
if ( m_randomize )
SetThink ( & CRune : : MaterializeRandom ) ;
else
SetThink ( & CRune : : Materialize ) ;
return this ;
}
void CRune : : MaterializeRandom ( void )
{
// Make sure at least one rune type is allowed
if ( ! ( ( int ) bm_runemask . value & 63 ) )
{
UTIL_Remove ( this ) ;
return ;
}
CBaseEntity * NewRune = NULL ;
int rand = 1 ;
for ( int i = 0 ; i < RANDOM_LONG ( 3 , 10 ) ; i + + )
{
do {
rand * = 2 ;
if ( rand > 63 )
rand = 1 ;
} while ( ! ( rand & ( int ) bm_runemask . value ) ) ;
}
if ( rand = = RUNE_CROWBAR )
NewRune = CBaseEntity : : Create ( " item_CrowbarRune " , pev - > origin , Vector ( 0 , 0 , 0 ) , NULL ) ;
else if ( rand = = RUNE_GRENADE )
NewRune = CBaseEntity : : Create ( " item_GrenadeRune " , pev - > origin , Vector ( 0 , 0 , 0 ) , NULL ) ;
else if ( rand = = RUNE_357 )
NewRune = CBaseEntity : : Create ( " item_357Rune " , pev - > origin , Vector ( 0 , 0 , 0 ) , NULL ) ;
else if ( rand = = RUNE_HEALTH )
NewRune = CBaseEntity : : Create ( " item_HealthRune " , pev - > origin , Vector ( 0 , 0 , 0 ) , NULL ) ;
else if ( rand = = RUNE_BATTERY )
NewRune = CBaseEntity : : Create ( " item_BatteryRune " , pev - > origin , Vector ( 0 , 0 , 0 ) , NULL ) ;
else if ( rand = = RUNE_SHOTGUN )
NewRune = CBaseEntity : : Create ( " item_ShotgunRune " , pev - > origin , Vector ( 0 , 0 , 0 ) , NULL ) ;
( ( CRune * ) NewRune ) - > m_randomize = TRUE ;
UTIL_Remove ( this ) ;
}
void CRune : : Materialize ( void )
{
// Pool of random spawn points.
static Vector spawnPoints [ 200 ] ;
// Populate the random spawn point pool.
if ( ! g_runes_learn ) {
g_runes_learn = TRUE ;
CBaseEntity * pSpot = NULL ;
for ( int i = 0 ; i < 200 ; i + + ) {
do
pSpot = UTIL_FindEntityInSphere ( pSpot , Vector ( 0 , 0 , 0 ) , 4096 ) ;
while ( pSpot = = NULL | |
! (
! strcmp ( STRING ( pSpot - > pev - > classname ) , " info_player_deathmatch " ) |
! strncmp ( STRING ( pSpot - > pev - > classname ) , " weapon_ " , 7 ) |
! strncmp ( STRING ( pSpot - > pev - > classname ) , " ammo_ " , 5 )
) ) ;
spawnPoints [ i ] = pSpot - > pev - > origin ;
}
}
if ( pev - > effects & EF_NODRAW )
{
pev - > angles . x = 0 ;
pev - > angles . z = 0 ;
pev - > origin = spawnPoints [ RANDOM_LONG ( 0 , 199 ) ] ;
pev - > velocity . x = RANDOM_FLOAT ( .5 , 2 ) ;
if ( RANDOM_LONG ( 0 , 1 ) )
pev - > velocity . x = pev - > velocity . x * - 1 ;
pev - > velocity . y = RANDOM_FLOAT ( .5 , 2 ) ;
if ( RANDOM_LONG ( 0 , 1 ) )
pev - > velocity . y = pev - > velocity . y * - 1 ;
pev - > velocity . z = RANDOM_FLOAT ( .5 , 2 ) ;
pev - > avelocity . y = RANDOM_FLOAT ( 0 , 100 ) ;
pev - > velocity = pev - > velocity . Normalize ( ) * 300 ;
// changing from invisible state to visible.
EMIT_SOUND_DYN ( ENT ( pev ) , CHAN_WEAPON , " items/suitchargeok1.wav " , 1 , ATTN_NORM , 0 , 150 ) ;
pev - > effects & = ~ EF_NODRAW ;
pev - > effects | = EF_MUZZLEFLASH ;
SetTouch ( & CRune : : RuneTouch ) ;
}
// EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "buttons/blip2.wav", 1, ATTN_NORM, 0, 150 );
pev - > nextthink = gpGlobals - > time + 2 ;
}
void CRune : : Precache ( void )
{
PRECACHE_MODEL ( RUNE_MODEL ) ;
PRECACHE_SOUND ( " buttons/blip2.wav " ) ;
}
LINK_ENTITY_TO_CLASS ( item_rune , CRune ) ;
////////////////////////////////////////////////
// Crowbar rune
////////////////////////////////////////////////
# define CROWBARRUNE_MODEL "models / w_crowbar.mdl"
class CCrowbarRune : public CRune
{
void Spawn ( void )
{
m_vRuneColor = Vector ( 255 , 20 , 20 ) ;
SET_MODEL ( ENT ( pev ) , CROWBARRUNE_MODEL ) ;
CRune : : Spawn ( ) ;
}
void Precache ( void )
{
PRECACHE_MODEL ( CROWBARRUNE_MODEL ) ;
}
BOOL MyTouch ( CBasePlayer * pPlayer )
{
// One rune at a time folks.
if ( ! pPlayer - > m_RuneFlags )
{
float time = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_cbar_t " ) ) ;
float respawn = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_cbar_r " ) ) ;
//RuneMsg( pPlayer, MSG_RUNE_CROWBAR, m_vRuneColor, time - .5);
PrintMessage ( pPlayer , BMOD_CHAN_RUNE , m_vRuneColor , Vector ( .1 , time - .5 , .1 ) , " SUPER CROWBAR \n Increased crowbar damage / infinite throws. " ) ;
EMIT_SOUND ( pPlayer - > edict ( ) , CHAN_ITEM , " items/gunpickup2.wav " , 1 , ATTN_NORM ) ;
pPlayer - > m_RuneFlags = RUNE_CROWBAR ;
pPlayer - > m_RuneTime = gpGlobals - > time + time ;
pev - > nextthink = gpGlobals - > time + respawn ;
return TRUE ;
}
else
return FALSE ;
}
} ;
LINK_ENTITY_TO_CLASS ( item_CrowbarRune , CCrowbarRune ) ;
////////////////////////////////////////////////
// Grenade rune
////////////////////////////////////////////////
# define GRENADERUNE_MODEL "models / w_grenade.mdl"
class CGrenadeRune : public CRune
{
void Spawn ( void )
{
m_vRuneColor = Vector ( 255 , 128 , 0 ) ;
SET_MODEL ( ENT ( pev ) , GRENADERUNE_MODEL ) ;
CRune : : Spawn ( ) ;
}
void Precache ( void )
{
PRECACHE_MODEL ( GRENADERUNE_MODEL ) ;
}
BOOL MyTouch ( CBasePlayer * pPlayer )
{
// One rune at a time folks.
if ( ! pPlayer - > m_RuneFlags )
{
float time = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_gren_t " ) ) ;
float respawn = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_gren_r " ) ) ;
PrintMessage ( pPlayer , BMOD_CHAN_RUNE , m_vRuneColor , Vector ( .1 , time - .5 , .1 ) , " MEGA GRENADE \n Increased hand grenade damage. " ) ;
EMIT_SOUND ( pPlayer - > edict ( ) , CHAN_ITEM , " items/gunpickup2.wav " , 1 , ATTN_NORM ) ;
pPlayer - > m_RuneFlags = RUNE_GRENADE ;
pPlayer - > m_RuneTime = gpGlobals - > time + time ;
pev - > nextthink = gpGlobals - > time + respawn ;
return TRUE ;
}
else
return FALSE ;
}
} ;
LINK_ENTITY_TO_CLASS ( item_GrenadeRune , CGrenadeRune ) ;
////////////////////////////////////////////////
// Health rune
////////////////////////////////////////////////
# define HEALTHRUNE_MODEL "models / w_medkit.mdl"
class CHealthRune : public CRune
{
void Spawn ( void )
{
m_vRuneColor = Vector ( 20 , 255 , 20 ) ;
SET_MODEL ( ENT ( pev ) , HEALTHRUNE_MODEL ) ;
CRune : : Spawn ( ) ;
}
void Precache ( void )
{
PRECACHE_MODEL ( HEALTHRUNE_MODEL ) ;
}
BOOL MyTouch ( CBasePlayer * pPlayer )
{
// One rune at a time folks.
if ( ! pPlayer - > m_RuneFlags )
{
float time = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_health_t " ) ) ;
float respawn = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_health_r " ) ) ;
PrintMessage ( pPlayer , BMOD_CHAN_RUNE , m_vRuneColor , Vector ( .1 , time - .5 , .1 ) , " DOUBLE HEALTH PICKUPS \n Med packs / machines give 2X health. Fast Heal on Bubble Gun. " ) ;
EMIT_SOUND ( pPlayer - > edict ( ) , CHAN_ITEM , " items/gunpickup2.wav " , 1 , ATTN_NORM ) ;
pPlayer - > m_RuneFlags = RUNE_HEALTH ;
pPlayer - > m_RuneTime = gpGlobals - > time + time ;
pev - > nextthink = gpGlobals - > time + respawn ;
return TRUE ;
}
else
return FALSE ;
}
} ;
LINK_ENTITY_TO_CLASS ( item_HealthRune , CHealthRune ) ;
////////////////////////////////////////////////
// Battery rune
////////////////////////////////////////////////
# define BATTERYRUNE_MODEL "models / w_battery.mdl"
class CBatteryRune : public CRune
{
void Spawn ( void )
{
m_vRuneColor = Vector ( 0 , 255 , 255 ) ;
SET_MODEL ( ENT ( pev ) , BATTERYRUNE_MODEL ) ;
CRune : : Spawn ( ) ;
}
void Precache ( void )
{
PRECACHE_MODEL ( BATTERYRUNE_MODEL ) ;
}
BOOL MyTouch ( CBasePlayer * pPlayer )
{
// One rune at a time folks.
if ( ! pPlayer - > m_RuneFlags )
{
float time = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_armor_t " ) ) ;
float respawn = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_armor_r " ) ) ;
PrintMessage ( pPlayer , BMOD_CHAN_RUNE , m_vRuneColor , Vector ( .1 , time - .5 , .1 ) , " DOUBLE ARMOR PICKUPS \n Armor batteries / machines give 2X armor. Bubble Gun gives armor. " ) ;
EMIT_SOUND ( pPlayer - > edict ( ) , CHAN_ITEM , " items/gunpickup2.wav " , 1 , ATTN_NORM ) ;
pPlayer - > m_RuneFlags = RUNE_BATTERY ;
pPlayer - > m_RuneTime = gpGlobals - > time + time ;
pev - > nextthink = gpGlobals - > time + respawn ;
return TRUE ;
}
else
return FALSE ;
}
} ;
LINK_ENTITY_TO_CLASS ( item_BatteryRune , CBatteryRune ) ;
////////////////////////////////////////////////
// 357 rune
////////////////////////////////////////////////
# define _357RUNE_MODEL "models / w_357.mdl"
class C357Rune : public CRune
{
void Spawn ( void )
{
m_vRuneColor = Vector ( 250 , 20 , 250 ) ;
SET_MODEL ( ENT ( pev ) , _357RUNE_MODEL ) ;
CRune : : Spawn ( ) ;
}
void Precache ( void )
{
PRECACHE_MODEL ( _357RUNE_MODEL ) ;
}
BOOL MyTouch ( CBasePlayer * pPlayer )
{
// One rune at a time folks.
if ( ! pPlayer - > m_RuneFlags )
{
float time = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_357_t " ) ) ;
float respawn = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_357_r " ) ) ;
PrintMessage ( pPlayer , BMOD_CHAN_RUNE , m_vRuneColor , Vector ( .1 , time - .5 , .1 ) , " SUPER MAGNUM \n Increased magnum damage. " ) ;
EMIT_SOUND ( pPlayer - > edict ( ) , CHAN_ITEM , " items/gunpickup2.wav " , 1 , ATTN_NORM ) ;
pPlayer - > m_RuneFlags = RUNE_357 ;
pPlayer - > m_RuneTime = gpGlobals - > time + time ;
pev - > nextthink = gpGlobals - > time + respawn ;
return TRUE ;
}
else
return FALSE ;
}
} ;
LINK_ENTITY_TO_CLASS ( item_357Rune , C357Rune ) ;
////////////////////////////////////////////////
// Shotgun rune
////////////////////////////////////////////////
# define SHOTGUNRUNE_MODEL "models / w_shotgun.mdl"
class CShotgunRune : public CRune
{
void Spawn ( void )
{
m_vRuneColor = Vector ( 20 , 20 , 255 ) ;
SET_MODEL ( ENT ( pev ) , SHOTGUNRUNE_MODEL ) ;
CRune : : Spawn ( ) ;
}
void Precache ( void )
{
PRECACHE_MODEL ( SHOTGUNRUNE_MODEL ) ;
}
BOOL MyTouch ( CBasePlayer * pPlayer )
{
// One rune at a time folks.
if ( ! pPlayer - > m_RuneFlags )
{
float time = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_shotty_t " ) ) ;
float respawn = max ( 1 , CVAR_GET_FLOAT ( " bm_rune_shotty_r " ) ) ;
PrintMessage ( pPlayer , BMOD_CHAN_RUNE , m_vRuneColor , Vector ( .1 , time - .5 , .1 ) , " SUPER SHOTGUN \n Increased shotgun speed / fast reload. " ) ;
EMIT_SOUND ( pPlayer - > edict ( ) , CHAN_ITEM , " items/gunpickup2.wav " , 1 , ATTN_NORM ) ;
pPlayer - > m_RuneFlags = RUNE_SHOTGUN ;
pPlayer - > m_RuneTime = gpGlobals - > time + time ;
pev - > nextthink = gpGlobals - > time + respawn ;
return TRUE ;
}
else
return FALSE ;
}
} ;
LINK_ENTITY_TO_CLASS ( item_ShotgunRune , CShotgunRune ) ;