656 lines
14 KiB
C++
656 lines
14 KiB
C++
//-----------------------------------------------------------------------------
|
|
//
|
|
// $Logfile:: /Quake 2 Engine/Sin/code/game/powerups.cpp $
|
|
// $Revision:: 24 $
|
|
// $Author:: Aldie $
|
|
// $Date:: 3/24/99 4:30p $
|
|
//
|
|
// Copyright (C) 1998 by Ritual Entertainment, Inc.
|
|
// All rights reserved.
|
|
//
|
|
// This source is may not be distributed and/or modified without
|
|
// expressly written permission by Ritual Entertainment, Inc.
|
|
//
|
|
// $Log:: /Quake 2 Engine/Sin/code/game/powerups.cpp $
|
|
//
|
|
// 24 3/24/99 4:30p Aldie
|
|
// tried to bullet proof certain crash bugs
|
|
//
|
|
// 23 11/13/98 2:36a Aldie
|
|
// Added a fixdeadbodies for mutagen
|
|
//
|
|
// 22 11/09/98 1:47a Aldie
|
|
// Change tesselate stuff for mutagen
|
|
//
|
|
// 21 11/08/98 5:12p Markd
|
|
// Added mutant hands to precache of mutagen as well
|
|
//
|
|
// 20 11/07/98 9:32p Markd
|
|
// pre-cached manumit_pl in mutagen constructor
|
|
//
|
|
// 19 10/22/98 2:44a Aldie
|
|
// Reduced POWERUP_TIME to 30
|
|
//
|
|
// 18 10/20/98 8:05p Aldie
|
|
// Made oxygen autopickup and use.
|
|
//
|
|
// 17 10/19/98 11:50p Aldie
|
|
// Added yellow dynamic light to adrenaline
|
|
//
|
|
// 16 10/19/98 12:05a Jimdose
|
|
// made all code use fast checks for inheritance (no text lookups when
|
|
// possible)
|
|
// isSubclassOf no longer requires ::_classinfo()
|
|
// moved ScubaGear from keys.cpp
|
|
//
|
|
// 15 10/16/98 10:53p Aldie
|
|
// Remove mutagen after using
|
|
//
|
|
// 14 10/13/98 2:29p Aldie
|
|
// Check for owners on Powedown
|
|
//
|
|
// 13 10/12/98 3:49p Aldie
|
|
// Oxygen requires scubagear
|
|
//
|
|
// 12 10/11/98 8:58p Aldie
|
|
// Moved savemodel and saveskin to sentient
|
|
//
|
|
// 11 10/11/98 12:03a Aldie
|
|
// Adrenaline effects
|
|
//
|
|
// 10 10/06/98 9:17p Aldie
|
|
// Fixed some bugs with models and skins
|
|
//
|
|
// 9 10/06/98 3:06p Aldie
|
|
// Fix adrenaline function
|
|
//
|
|
// 8 10/01/98 7:57p Aldie
|
|
// Consolidated the cprintf
|
|
//
|
|
// 7 9/28/98 4:17p Aldie
|
|
// Added oxygen powerup
|
|
//
|
|
// 6 9/26/98 4:45p Aldie
|
|
// Added mutant mode
|
|
//
|
|
// 5 9/25/98 2:59p Aldie
|
|
// Added medkit
|
|
//
|
|
// 4 9/05/98 12:12p Aldie
|
|
// Added checks to see if powerups were active
|
|
//
|
|
// 3 8/31/98 5:44p Aldie
|
|
// Added cloak
|
|
//
|
|
// 2 8/27/98 2:30p Aldie
|
|
// Adrenaline
|
|
//
|
|
// DESCRIPTION:
|
|
// Miscellaneous powerups
|
|
|
|
#include "powerups.h"
|
|
#include "specialfx.h"
|
|
#include "player.h"
|
|
|
|
#define POWERUP_TIME 30
|
|
|
|
CLASS_DECLARATION( InventoryItem, ScubaGear, "inventory_scubagear" )
|
|
|
|
ResponseDef ScubaGear::Responses[] =
|
|
{
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
ScubaGear::ScubaGear
|
|
(
|
|
)
|
|
{
|
|
setModel( "scubagear.def" );
|
|
}
|
|
|
|
CLASS_DECLARATION( InventoryItem, Adrenaline, "powerup_adrenaline" );
|
|
|
|
Event EV_Adrenaline_Powerdown( "adrenaline_powerdown" );
|
|
|
|
ResponseDef Adrenaline::Responses[] =
|
|
{
|
|
{ &EV_Adrenaline_Powerdown, ( Response )Adrenaline::Powerdown },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
Adrenaline::Adrenaline
|
|
(
|
|
)
|
|
|
|
{
|
|
setModel( "adren.def" );
|
|
Set( 1 );
|
|
setRespawnTime( 180 + G_Random( 60 ) );
|
|
}
|
|
|
|
void Adrenaline::Powerdown
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
if ( !owner )
|
|
{
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
owner->flags &= ~FL_ADRENALINE;
|
|
owner->edict->s.renderfx &= ~RF_DLIGHT;
|
|
owner->edict->s.color_r = 0;
|
|
owner->edict->s.color_g = 0;
|
|
owner->edict->s.color_b = 0;
|
|
owner->edict->s.radius = 0;
|
|
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
}
|
|
|
|
void Adrenaline::Use
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
str realname;
|
|
Event *event;
|
|
|
|
if ( !owner )
|
|
{
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
if ( owner->PowerupActive() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Make sure there is one available
|
|
assert( amount );
|
|
amount--;
|
|
if (amount <= 0)
|
|
{
|
|
owner->RemoveItem( this );
|
|
}
|
|
|
|
PostEvent( EV_Adrenaline_Powerdown, POWERUP_TIME );
|
|
|
|
owner->flags |= FL_ADRENALINE;
|
|
|
|
event = new Event( "poweruptimer" );
|
|
event->AddInteger( POWERUP_TIME );
|
|
event->AddInteger( P_ADRENALINE );
|
|
owner->edict->s.renderfx |= RF_DLIGHT;
|
|
owner->edict->s.color_r = 1;
|
|
owner->edict->s.color_g = 1;
|
|
owner->edict->s.color_b = 0;
|
|
owner->edict->s.radius = 120;
|
|
owner->ProcessEvent ( event );
|
|
|
|
realname = GetRandomAlias( "snd_activate" );
|
|
|
|
if ( realname.length() )
|
|
owner->sound( realname, 1, CHAN_ITEM, ATTN_NORM );
|
|
}
|
|
|
|
CLASS_DECLARATION( InventoryItem, Cloak, "powerups_cloak" );
|
|
|
|
Event EV_Cloak_Powerdown( "Cloak_powerdown" );
|
|
|
|
ResponseDef Cloak::Responses[] =
|
|
{
|
|
{ &EV_Cloak_Powerdown, ( Response )Cloak::Powerdown },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
|
|
Cloak::Cloak
|
|
(
|
|
)
|
|
|
|
{
|
|
setModel( "cloak.def" );
|
|
Set( 1 );
|
|
setRespawnTime( 180 + G_Random( 60 ) );
|
|
}
|
|
|
|
void Cloak::Powerdown
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
if ( !owner )
|
|
{
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
if ( owner->flags & FL_CLOAK )
|
|
{
|
|
str realname;
|
|
|
|
owner->flags &= ~FL_CLOAK;
|
|
realname = GetRandomAlias( "snd_deactivate" );
|
|
if ( realname.length() )
|
|
owner->sound( realname, 1, CHAN_ITEM, ATTN_NORM );
|
|
owner->edict->s.renderfx &= ~RF_DLIGHT;
|
|
owner->edict->s.color_r = 0;
|
|
owner->edict->s.color_g = 0;
|
|
owner->edict->s.color_b = 0;
|
|
owner->edict->s.radius = 0;
|
|
}
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
}
|
|
|
|
void Cloak::Use
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
str realname;
|
|
Event *event;
|
|
|
|
if ( !owner )
|
|
{
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
if ( owner->PowerupActive() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Make sure there is one available
|
|
assert( amount );
|
|
amount--;
|
|
if (amount <= 0)
|
|
{
|
|
owner->RemoveItem( this );
|
|
}
|
|
|
|
PostEvent( EV_Cloak_Powerdown, POWERUP_TIME );
|
|
|
|
owner->flags |= FL_CLOAK;
|
|
owner->edict->s.renderfx |= RF_DLIGHT;
|
|
owner->edict->s.color_r = 1;
|
|
owner->edict->s.color_g = 1;
|
|
owner->edict->s.color_b = 1;
|
|
owner->edict->s.radius = -120;
|
|
|
|
event = new Event( "poweruptimer" );
|
|
event->AddInteger( POWERUP_TIME );
|
|
event->AddInteger( P_CLOAK );
|
|
owner->ProcessEvent ( event );
|
|
|
|
realname = GetRandomAlias( "snd_activate" );
|
|
|
|
if ( realname.length() )
|
|
owner->sound( realname, 1, CHAN_ITEM, ATTN_NORM );
|
|
}
|
|
|
|
CLASS_DECLARATION( InventoryItem, Mutagen, "powerups_mutagen" );
|
|
|
|
Event EV_Mutagen_Powerdown( "mutagen_powerdown" );
|
|
|
|
ResponseDef Mutagen::Responses[] =
|
|
{
|
|
{ &EV_Mutagen_Powerdown, ( Response )Mutagen::Powerdown },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
Mutagen::Mutagen
|
|
(
|
|
)
|
|
|
|
{
|
|
modelIndex( "manumit_pl.def" );
|
|
modelIndex( "view_mutanthands.def" );
|
|
setModel( "u4vial.def" );
|
|
Set( 1 );
|
|
setRespawnTime( 180 + G_Random( 60 ) );
|
|
}
|
|
|
|
void Mutagen::Powerdown
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
str realname;
|
|
|
|
if ( !owner )
|
|
{
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
owner->flags &= ~FL_MUTANT;
|
|
realname = GetRandomAlias( "snd_deactivate" );
|
|
|
|
if ( realname.length() )
|
|
owner->sound( realname, 1, CHAN_ITEM, ATTN_NORM );
|
|
|
|
if ( owner->isClient() )
|
|
{
|
|
int playernum = owner->edict-g_edicts-1;
|
|
|
|
owner->setModel( owner->savemodel );
|
|
owner->RandomAnimate( "idle", NULL );
|
|
|
|
strcpy( owner->client->pers.model, owner->savemodel.c_str() );
|
|
strcpy( owner->client->pers.skin, owner->saveskin.c_str() );
|
|
|
|
// combine name, skin and model into a configstring
|
|
gi.configstring (CS_PLAYERSKINS+playernum, va("%s\\%s\\%s",
|
|
owner->client->pers.netname,
|
|
owner->client->pers.model,
|
|
owner->client->pers.skin));
|
|
}
|
|
|
|
owner->takeWeapon( "MutantHands" );
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
}
|
|
|
|
void Mutagen::Use
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
str realname;
|
|
Event *event;
|
|
Weapon *mutanthands;
|
|
|
|
if ( !owner )
|
|
{
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
if ( owner->PowerupActive() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Make sure there is one available
|
|
assert( amount );
|
|
amount--;
|
|
|
|
if (amount <= 0)
|
|
{
|
|
owner->RemoveItem( this );
|
|
}
|
|
|
|
PostEvent( EV_Mutagen_Powerdown, POWERUP_TIME );
|
|
owner->flags |= FL_MUTANT;
|
|
|
|
//Set the timer
|
|
event = new Event( "poweruptimer" );
|
|
event->AddInteger( POWERUP_TIME );
|
|
event->AddInteger( P_MUTAGEN );
|
|
owner->ProcessEvent ( event );
|
|
|
|
TesselateModel(owner,
|
|
1,
|
|
1000,
|
|
Vector( "0 0 1" ),
|
|
50,
|
|
0.1f,
|
|
owner->tess_thickness,
|
|
vec3_origin
|
|
);
|
|
|
|
owner->savemodel = COM_SkipPath(owner->model.c_str());
|
|
owner->saveskin = COM_SkipPath(owner->client->pers.skin);
|
|
|
|
owner->setModel( "manumit_pl.def" );
|
|
owner->RandomAnimate( "idle", NULL );
|
|
|
|
if ( owner->isClient() )
|
|
{
|
|
int playernum = owner->edict-g_edicts-1;
|
|
|
|
strcpy( owner->client->pers.model, "manumit_pl.def" );
|
|
strcpy( owner->client->pers.skin, "manu_base.tga" );
|
|
// combine name, skin and model into a configstring
|
|
gi.configstring (CS_PLAYERSKINS+playernum,
|
|
va("%s\\%s\\%s",
|
|
owner->client->pers.netname,
|
|
owner->client->pers.model,
|
|
owner->client->pers.skin)
|
|
);
|
|
|
|
FixDeadBodiesForPlayer( owner->edict );
|
|
}
|
|
|
|
// Give the mutanthands weapon. - Force it.
|
|
mutanthands = owner->giveWeapon( "MutantHands" );
|
|
owner->ForceChangeWeapon( mutanthands );
|
|
|
|
realname = GetRandomAlias( "snd_activate" );
|
|
|
|
if ( realname.length() )
|
|
owner->sound( realname, 1, CHAN_ITEM, ATTN_NORM );
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/*SINED misc_medkit (1.0 0.2 0.2)
|
|
Heals whoever uses it to their max health.
|
|
/*****************************************************************************/
|
|
CLASS_DECLARATION( Entity, Medkit, "misc_medkit" );
|
|
|
|
ResponseDef Medkit::Responses[] =
|
|
{
|
|
{ &EV_Use, ( Response )Medkit::Use },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
Medkit::Medkit
|
|
(
|
|
)
|
|
|
|
{
|
|
setSolidType( SOLID_BSP );
|
|
setMoveType( MOVETYPE_NONE );
|
|
showModel();
|
|
}
|
|
|
|
void Medkit::Use
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Entity *other;
|
|
str realname;
|
|
|
|
other = ev->GetEntity( 1 );
|
|
if ( other && other->health < other->max_health )
|
|
{
|
|
other->health = other->max_health;
|
|
realname = GetRandomAlias( "snd_activate" );
|
|
|
|
if ( realname.length() )
|
|
other->sound( realname, 1, CHAN_ITEM, ATTN_NORM );
|
|
}
|
|
}
|
|
|
|
CLASS_DECLARATION( InventoryItem, Oxygen, "powerups_oxygen" );
|
|
|
|
Event EV_Oxygen_Powerdown( "oxygen_powerdown" );
|
|
|
|
ResponseDef Oxygen::Responses[] =
|
|
{
|
|
{ &EV_Oxygen_Powerdown, ( Response )Oxygen::Powerdown },
|
|
{ &EV_Item_Pickup, ( Response )Oxygen::Pickup },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
Oxygen::Oxygen
|
|
(
|
|
)
|
|
|
|
{
|
|
setModel( "oxygen.def" );
|
|
Set( 1 );
|
|
setRespawnTime( 180 + G_Random( 60 ) );
|
|
}
|
|
|
|
void Oxygen::Powerdown
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
if ( !owner )
|
|
{
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
if ( owner->flags & FL_OXYGEN )
|
|
{
|
|
str realname;
|
|
|
|
owner->flags &= ~FL_OXYGEN;
|
|
realname = GetRandomAlias( "snd_deactivate" );
|
|
if ( realname.length() )
|
|
owner->sound( realname, 1, CHAN_ITEM, ATTN_NORM );
|
|
}
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
}
|
|
|
|
void Oxygen::Pickup
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
Entity *other;
|
|
Sentient *sen;
|
|
Item *item;
|
|
|
|
other = ev->GetEntity( 1 );
|
|
|
|
if ( !other )
|
|
{
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
sen = ( Sentient * )other;
|
|
|
|
// Single player must have the scuba gear to use oxygen
|
|
if ( !deathmatch->value && !sen->FindItem( "ScubaGear" ) )
|
|
{
|
|
Item *item;
|
|
|
|
item = ( Item * )new ScubaGear;
|
|
item->CancelEventsOfType( EV_Item_DropToFloor );
|
|
item->CancelEventsOfType( EV_Remove );
|
|
item->ProcessPendingEvents();
|
|
|
|
gi.centerprintf( other->edict, "jcx yv 20 string \"You need this item to use Oxygen:\" jcx yv -20 icon %d", item->GetIconIndex() );
|
|
delete item;
|
|
|
|
return;
|
|
}
|
|
|
|
if ( !ItemPickup( sen ) )
|
|
return;
|
|
|
|
if ( sen->isSubclassOf( Player ) )
|
|
{
|
|
Player *player = ( Player * )sen;
|
|
|
|
player->GiveOxygen( 60 );
|
|
}
|
|
|
|
item = sen->FindItem( getClassname() );
|
|
if ( item )
|
|
{
|
|
CancelPendingEvents();
|
|
item->PostEvent( EV_Remove, 0 );
|
|
}
|
|
}
|
|
|
|
void Oxygen::Use
|
|
(
|
|
Event *ev
|
|
)
|
|
|
|
{
|
|
str realname;
|
|
Event *event;
|
|
|
|
if ( !owner )
|
|
{
|
|
CancelPendingEvents();
|
|
PostEvent( EV_Remove, 0 );
|
|
return;
|
|
}
|
|
|
|
// Single player must have the scuba gear to use oxygen
|
|
if ( !deathmatch->value && !owner->FindItem( "ScubaGear" ) )
|
|
{
|
|
Item *item;
|
|
|
|
item = ( Item * )new ScubaGear;
|
|
item->CancelEventsOfType( EV_Item_DropToFloor );
|
|
item->CancelEventsOfType( EV_Remove );
|
|
item->ProcessPendingEvents();
|
|
|
|
gi.centerprintf( owner->edict, "jcx yv 20 string \"You need this item to use Oxygen:\" jcx yv -20 icon %d", item->GetIconIndex() );
|
|
delete item;
|
|
|
|
return;
|
|
}
|
|
|
|
if ( owner->PowerupActive() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Make sure there is one available
|
|
assert( amount );
|
|
amount--;
|
|
if (amount <= 0)
|
|
{
|
|
owner->RemoveItem( this );
|
|
}
|
|
|
|
PostEvent( EV_Oxygen_Powerdown, 60 );
|
|
|
|
owner->flags |= FL_OXYGEN;
|
|
|
|
event = new Event( "poweruptimer" );
|
|
event->AddInteger( 60 );
|
|
event->AddInteger( P_OXYGEN );
|
|
owner->ProcessEvent ( event );
|
|
|
|
realname = GetRandomAlias( "snd_activate" );
|
|
|
|
if ( realname.length() )
|
|
owner->sound( realname, 1, CHAN_ITEM, ATTN_NORM );
|
|
}
|