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.
445 lines
13 KiB
445 lines
13 KiB
8 years ago
|
// ---------------------------------------------------------------
|
||
|
// 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(RuneTouch);
|
||
|
|
||
|
pev->effects |= EF_NODRAW;
|
||
|
SetThink ( 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 ( MaterializeRandom );
|
||
|
else
|
||
|
SetThink ( 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( 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\nIncreased 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\nIncreased 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\nMed 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\nArmor 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\nIncreased 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\nIncreased 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 );
|