Night Owl
7 years ago
19 changed files with 2147 additions and 2611 deletions
@ -0,0 +1,570 @@ |
|||||||
|
/***
|
||||||
|
* |
||||||
|
* Copyright (c) 1996-2002, 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. |
||||||
|
* |
||||||
|
****/ |
||||||
|
/*****************************************************
|
||||||
|
****************************************************** |
||||||
|
THREEWAVE CTF FLAG CODE |
||||||
|
****************************************************** |
||||||
|
*****************************************************/ |
||||||
|
|
||||||
|
#include "extdll.h" |
||||||
|
#include "util.h" |
||||||
|
#include "cbase.h" |
||||||
|
#include "player.h" |
||||||
|
#include "weapons.h" |
||||||
|
#include "gamerules.h" |
||||||
|
#include "items.h" |
||||||
|
#include "threewave_gamerules.h" |
||||||
|
#include "flags.h" |
||||||
|
|
||||||
|
unsigned short g_usCarried; |
||||||
|
unsigned short g_usFlagSpawn; |
||||||
|
enum Flag_Anims |
||||||
|
{ |
||||||
|
ON_GROUND = 0, |
||||||
|
NOT_CARRIED, |
||||||
|
CARRIED, |
||||||
|
WAVE_IDLE, |
||||||
|
FLAG_POSITION |
||||||
|
}; |
||||||
|
|
||||||
|
void CItemFlag::Spawn() |
||||||
|
{ |
||||||
|
Precache(); |
||||||
|
SET_MODEL( ENT( pev ), "models/flag.mdl" ); |
||||||
|
|
||||||
|
pev->movetype = MOVETYPE_TOSS; |
||||||
|
pev->solid = SOLID_TRIGGER; |
||||||
|
UTIL_SetOrigin( pev, pev->origin ); |
||||||
|
UTIL_SetSize( pev, Vector( -16, -16, 0 ), Vector( 16, 16, 16 ) ); |
||||||
|
|
||||||
|
SetThink( &CItemFlag::FlagThink ); |
||||||
|
SetTouch( &CItemFlag::FlagTouch ); |
||||||
|
|
||||||
|
pev->nextthink = gpGlobals->time + 0.3; |
||||||
|
|
||||||
|
//Set the Skin based on the team.
|
||||||
|
pev->skin = pev->team; |
||||||
|
|
||||||
|
Dropped = FALSE; |
||||||
|
m_flDroppedTime = 0.0; |
||||||
|
|
||||||
|
pev->sequence = NOT_CARRIED; |
||||||
|
pev->framerate = 1.0; |
||||||
|
|
||||||
|
// if( !DROP_TO_FLOOR( ENT( pev ) ) )
|
||||||
|
// ResetFlag( pev->team );
|
||||||
|
} |
||||||
|
|
||||||
|
void CItemFlag::FlagTouch( CBaseEntity *pToucher ) |
||||||
|
{ |
||||||
|
if( !pToucher ) |
||||||
|
return; |
||||||
|
|
||||||
|
if( !pToucher->IsPlayer() ) |
||||||
|
return; |
||||||
|
|
||||||
|
if( FBitSet( pev->effects, EF_NODRAW ) ) |
||||||
|
return; |
||||||
|
|
||||||
|
if( pToucher->pev->health <= 0 ) |
||||||
|
return; |
||||||
|
|
||||||
|
if( pToucher->pev->team == 0 ) |
||||||
|
return; |
||||||
|
|
||||||
|
CBasePlayer *pPlayer = (CBasePlayer *)pToucher; |
||||||
|
|
||||||
|
//Same team as the flag
|
||||||
|
if( pev->team == pToucher->pev->team ) |
||||||
|
{ |
||||||
|
//Flag is dropped, let's return it
|
||||||
|
if( Dropped ) |
||||||
|
{ |
||||||
|
Dropped = FALSE; |
||||||
|
|
||||||
|
pPlayer->AddPoints( TEAM_CAPTURE_RECOVERY_BONUS, TRUE ); |
||||||
|
|
||||||
|
if( pPlayer->pev->team == RED ) |
||||||
|
{ |
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Returned_Red_Flag\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
GetTeamName( pPlayer->pev->team ) ); |
||||||
|
|
||||||
|
if( ( (CThreeWave*)g_pGameRules )->iBlueFlagStatus == BLUE_FLAG_STOLEN ) |
||||||
|
{ |
||||||
|
for( int i = 1; i <= gpGlobals->maxClients; i++ ) |
||||||
|
{ |
||||||
|
CBasePlayer *pTeamMate = (CBasePlayer*)UTIL_PlayerByIndex( i ); |
||||||
|
|
||||||
|
if( pTeamMate ) |
||||||
|
{ |
||||||
|
if( pTeamMate->m_bHasFlag ) |
||||||
|
{ |
||||||
|
pTeamMate->pFlagReturner = pPlayer; |
||||||
|
pTeamMate->m_flFlagReturnTime = gpGlobals->time + TEAM_CAPTURE_RETURN_FLAG_ASSIST_TIMEOUT; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if( pPlayer->pev->team == BLUE ) |
||||||
|
{ |
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Returned_Blue_Flag\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
GetTeamName( pPlayer->pev->team ) ); |
||||||
|
|
||||||
|
if( ( (CThreeWave*)g_pGameRules )->iRedFlagStatus == RED_FLAG_STOLEN ) |
||||||
|
{ |
||||||
|
for( int i = 1; i <= gpGlobals->maxClients; i++ ) |
||||||
|
{ |
||||||
|
CBasePlayer *pTeamMate = (CBasePlayer*)UTIL_PlayerByIndex( i ); |
||||||
|
|
||||||
|
if( pTeamMate ) |
||||||
|
{ |
||||||
|
if( pTeamMate->m_bHasFlag ) |
||||||
|
{ |
||||||
|
pTeamMate->pFlagReturner = pPlayer; |
||||||
|
pTeamMate->m_flFlagReturnTime = gpGlobals->time + TEAM_CAPTURE_RETURN_FLAG_ASSIST_TIMEOUT; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//Back at home!
|
||||||
|
ResetFlag( pev->team ); |
||||||
|
|
||||||
|
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL ); |
||||||
|
if( pev->team == RED ) |
||||||
|
WRITE_BYTE( RED_FLAG_RETURNED_PLAYER ); |
||||||
|
else if( pev->team == BLUE ) |
||||||
|
WRITE_BYTE( BLUE_FLAG_RETURNED_PLAYER ); |
||||||
|
WRITE_STRING( STRING( pToucher->pev->netname ) ); |
||||||
|
MESSAGE_END(); |
||||||
|
|
||||||
|
// Remove this one
|
||||||
|
UTIL_Remove( this ); |
||||||
|
return; |
||||||
|
} |
||||||
|
// Not Dropped, means it's the one in our base
|
||||||
|
else |
||||||
|
{ |
||||||
|
// We have the enemy flag!
|
||||||
|
// Capture it!
|
||||||
|
if( pPlayer->m_bHasFlag ) |
||||||
|
{ |
||||||
|
if( pev->team == RED ) |
||||||
|
Capture( pPlayer, BLUE ); |
||||||
|
else if( pev->team == BLUE ) |
||||||
|
Capture( pPlayer, RED ); |
||||||
|
|
||||||
|
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, |
||||||
|
pPlayer->edict(), g_usCarried, 0, (float*)&g_vecZero, (float*)&g_vecZero, |
||||||
|
0.0, 0.0, pPlayer->entindex(), pPlayer->pev->team, 1, 0 ); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
if( Dropped ) |
||||||
|
{ |
||||||
|
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL ); |
||||||
|
if( pev->team == RED ) |
||||||
|
WRITE_BYTE( RED_FLAG_STOLEN ); |
||||||
|
else if( pev->team == BLUE ) |
||||||
|
WRITE_BYTE( BLUE_FLAG_STOLEN ); |
||||||
|
WRITE_STRING( STRING( pToucher->pev->netname ) ); |
||||||
|
MESSAGE_END(); |
||||||
|
|
||||||
|
pPlayer->m_bHasFlag = TRUE; |
||||||
|
|
||||||
|
CBaseEntity *pEnt = NULL; |
||||||
|
|
||||||
|
if( pev->team == RED ) |
||||||
|
{ |
||||||
|
pEnt = CBaseEntity::Create( "carried_flag_team1", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() ); |
||||||
|
|
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Picked_Up_Red_Flag\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
GetTeamName( pPlayer->pev->team ) ); |
||||||
|
} |
||||||
|
else if( pev->team == BLUE ) |
||||||
|
{ |
||||||
|
pEnt = CBaseEntity::Create( "carried_flag_team2", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() ); |
||||||
|
|
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Picked_Up_Blue_Flag\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
GetTeamName( pPlayer->pev->team ) ); |
||||||
|
} |
||||||
|
|
||||||
|
CCarriedFlag *pCarriedFlag = (CCarriedFlag *)pEnt; |
||||||
|
pCarriedFlag->Owner = pPlayer; |
||||||
|
|
||||||
|
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, |
||||||
|
pPlayer->edict(), g_usCarried, 0, (float*)&g_vecZero, (float*)&g_vecZero, |
||||||
|
0.0, 0.0, pPlayer->entindex(), pPlayer->pev->team, 0, 0 ); |
||||||
|
|
||||||
|
UTIL_Remove( this ); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
pev->effects |= EF_NODRAW; |
||||||
|
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL ); |
||||||
|
if( pev->team == RED ) |
||||||
|
WRITE_BYTE( RED_FLAG_STOLEN ); |
||||||
|
else if( pev->team == BLUE ) |
||||||
|
WRITE_BYTE( BLUE_FLAG_STOLEN ); |
||||||
|
WRITE_STRING( STRING( pToucher->pev->netname ) ); |
||||||
|
MESSAGE_END(); |
||||||
|
|
||||||
|
pPlayer->m_bHasFlag = TRUE; |
||||||
|
pPlayer->m_flCarrierPickupTime = gpGlobals->time + TEAM_CAPTURE_CARRIER_FLAG_SINCE_TIMEOUT; |
||||||
|
|
||||||
|
CBaseEntity *pEnt = NULL; |
||||||
|
|
||||||
|
if( pev->team == RED ) |
||||||
|
{ |
||||||
|
pEnt = CBaseEntity::Create( "carried_flag_team1", pev->origin, pev->angles, pPlayer->edict() ); |
||||||
|
|
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Stole_Red_Flag\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
GetTeamName( pPlayer->pev->team ) ); |
||||||
|
} |
||||||
|
else if( pev->team == BLUE ) |
||||||
|
{ |
||||||
|
pEnt = CBaseEntity::Create( "carried_flag_team2", pev->origin, pev->angles, pPlayer->edict() ); |
||||||
|
|
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Stole_Blue_Flag\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
GetTeamName( pPlayer->pev->team ) ); |
||||||
|
} |
||||||
|
|
||||||
|
CCarriedFlag *pCarriedFlag = (CCarriedFlag *)pEnt; |
||||||
|
pCarriedFlag->Owner = pPlayer; |
||||||
|
|
||||||
|
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, |
||||||
|
pPlayer->edict(), g_usCarried, 0, (float*)&g_vecZero, (float*)&g_vecZero, |
||||||
|
0.0, 0.0, pPlayer->entindex(), pPlayer->pev->team, 0, 0 ); |
||||||
|
} |
||||||
|
|
||||||
|
( (CThreeWave*)g_pGameRules )->m_flFlagStatusTime = gpGlobals->time + 0.1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void CItemFlag::Capture( CBasePlayer *pPlayer, int iTeam ) |
||||||
|
{ |
||||||
|
CBaseEntity *pFlag1 = NULL; |
||||||
|
|
||||||
|
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL ); |
||||||
|
if( iTeam == RED ) |
||||||
|
WRITE_BYTE( RED_FLAG_CAPTURED ); |
||||||
|
else if ( iTeam == BLUE ) |
||||||
|
WRITE_BYTE( BLUE_FLAG_CAPTURED ); |
||||||
|
WRITE_STRING( STRING( pPlayer->pev->netname ) ); |
||||||
|
MESSAGE_END(); |
||||||
|
|
||||||
|
if( pPlayer->pFlagCarrierKiller ) |
||||||
|
{ |
||||||
|
if( pPlayer->m_flFlagCarrierKillTime > gpGlobals->time ) |
||||||
|
{ |
||||||
|
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING( pPlayer->pFlagCarrierKiller->pev->netname ) ); |
||||||
|
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " gets an assist for fragging the flag carrier!\n" ); |
||||||
|
|
||||||
|
pPlayer->pFlagCarrierKiller->AddPoints( TEAM_CAPTURE_FRAG_CARRIER_ASSIST_BONUS, TRUE ); |
||||||
|
pPlayer->pFlagCarrierKiller = NULL; |
||||||
|
pPlayer->m_flFlagCarrierKillTime = 0.0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if( pPlayer->pFlagReturner ) |
||||||
|
{ |
||||||
|
if( pPlayer->m_flFlagReturnTime > gpGlobals->time ) |
||||||
|
{ |
||||||
|
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING( pPlayer->pFlagReturner->pev->netname ) ); |
||||||
|
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " gets an assist for returning his flag!\n"); |
||||||
|
|
||||||
|
pPlayer->pFlagReturner->AddPoints( TEAM_CAPTURE_RETURN_FLAG_ASSIST_BONUS, TRUE ); |
||||||
|
pPlayer->pFlagReturner = NULL; |
||||||
|
pPlayer->m_flFlagReturnTime = 0.0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if( iTeam != pPlayer->pev->team ) |
||||||
|
{ |
||||||
|
if( iTeam == RED ) |
||||||
|
{ |
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Captured_Red_Flag\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
GetTeamName( pPlayer->pev->team ) ); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Captured_Blue_Flag\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
GetTeamName( pPlayer->pev->team ) ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if( iTeam == RED ) |
||||||
|
{ |
||||||
|
( (CThreeWave *)g_pGameRules )->iBlueTeamScore++; |
||||||
|
|
||||||
|
while( ( pFlag1 = UTIL_FindEntityByClassname( pFlag1, "carried_flag_team1" ) ) != NULL ) |
||||||
|
{ |
||||||
|
if( pFlag1 ) |
||||||
|
UTIL_Remove( pFlag1 ); |
||||||
|
} |
||||||
|
} |
||||||
|
else if( iTeam == BLUE ) |
||||||
|
{ |
||||||
|
( (CThreeWave*)g_pGameRules )->iRedTeamScore++; |
||||||
|
|
||||||
|
while( ( pFlag1 = UTIL_FindEntityByClassname( pFlag1, "carried_flag_team2" ) ) != NULL ) |
||||||
|
{ |
||||||
|
if ( pFlag1 ) |
||||||
|
UTIL_Remove( pFlag1 ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
pPlayer->m_bHasFlag = FALSE; |
||||||
|
pPlayer->AddPoints( TEAM_CAPTURE_CAPTURE_BONUS, TRUE ); |
||||||
|
|
||||||
|
for( int i = 1; i <= gpGlobals->maxClients; i++ ) |
||||||
|
{ |
||||||
|
CBaseEntity *pTeamMate = UTIL_PlayerByIndex( i ); |
||||||
|
|
||||||
|
if( pTeamMate ) |
||||||
|
{ |
||||||
|
if( pTeamMate->pev->team == pPlayer->pev->team ) |
||||||
|
pTeamMate->AddPoints( TEAM_CAPTURE_TEAM_BONUS, TRUE ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
ResetFlag( iTeam ); |
||||||
|
} |
||||||
|
|
||||||
|
void CItemFlag::Materialize() |
||||||
|
{ |
||||||
|
if ( pev->effects & EF_NODRAW ) |
||||||
|
{ |
||||||
|
pev->effects &= ~EF_NODRAW; |
||||||
|
pev->effects |= EF_MUZZLEFLASH; |
||||||
|
} |
||||||
|
|
||||||
|
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, |
||||||
|
edict(), g_usFlagSpawn, 0, (float*)&g_vecZero, (float*)&g_vecZero, |
||||||
|
0.0, 0.0, pev->team, 0, 0, 0 ); |
||||||
|
|
||||||
|
Dropped = FALSE; |
||||||
|
|
||||||
|
SetTouch( &CItemFlag::FlagTouch ); |
||||||
|
SetThink( &CItemFlag::FlagThink ); |
||||||
|
} |
||||||
|
|
||||||
|
void CItemFlag::ResetFlag( int iTeam ) |
||||||
|
{ |
||||||
|
CBaseEntity *pFlag1 = NULL; |
||||||
|
|
||||||
|
if( iTeam == BLUE ) |
||||||
|
{ |
||||||
|
while( ( pFlag1 = UTIL_FindEntityByClassname( pFlag1, "item_flag_team2" ) ) != NULL ) |
||||||
|
{ |
||||||
|
CItemFlag *pFlag2 = (CItemFlag*)pFlag1; |
||||||
|
|
||||||
|
if( pFlag2->Dropped ) |
||||||
|
continue; |
||||||
|
|
||||||
|
if( pFlag2->pev->effects & EF_NODRAW ) |
||||||
|
pFlag2->Materialize(); |
||||||
|
} |
||||||
|
} |
||||||
|
else if( iTeam == RED ) |
||||||
|
{ |
||||||
|
while( ( pFlag1 = UTIL_FindEntityByClassname( pFlag1, "item_flag_team1" ) ) != NULL ) |
||||||
|
{ |
||||||
|
CItemFlag *pFlag2 = (CItemFlag*)pFlag1; |
||||||
|
|
||||||
|
if( pFlag2->Dropped ) |
||||||
|
continue; |
||||||
|
|
||||||
|
if( pFlag2->pev->effects & EF_NODRAW ) |
||||||
|
pFlag2->Materialize(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
( (CThreeWave*)g_pGameRules )->m_flFlagStatusTime = gpGlobals->time + 0.1; |
||||||
|
} |
||||||
|
|
||||||
|
void CItemFlag::FlagThink() |
||||||
|
{ |
||||||
|
if( Dropped ) |
||||||
|
{ |
||||||
|
if( m_flDroppedTime <= gpGlobals->time ) |
||||||
|
{ |
||||||
|
ResetFlag( pev->team ); |
||||||
|
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL ); |
||||||
|
if( pev->team == RED ) |
||||||
|
WRITE_BYTE( RED_FLAG_RETURNED ); |
||||||
|
else if( pev->team == BLUE ) |
||||||
|
WRITE_BYTE( BLUE_FLAG_RETURNED ); |
||||||
|
WRITE_STRING( "" ); |
||||||
|
MESSAGE_END(); |
||||||
|
|
||||||
|
UTIL_Remove( this ); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//Using 0.2 just in case we might lag the server.
|
||||||
|
pev->nextthink = gpGlobals->time + 0.2; |
||||||
|
} |
||||||
|
|
||||||
|
void CItemFlag::Precache() |
||||||
|
{ |
||||||
|
PRECACHE_MODEL( "models/flag.mdl" ); |
||||||
|
PRECACHE_SOUND( "ctf/flagcap.wav" ); |
||||||
|
PRECACHE_SOUND( "ctf/flagtk.wav" ); |
||||||
|
PRECACHE_SOUND( "ctf/flagret.wav" ); |
||||||
|
} |
||||||
|
|
||||||
|
class CItemFlagTeam1 : public CItemFlag |
||||||
|
{ |
||||||
|
void Spawn() |
||||||
|
{ |
||||||
|
pev->classname = MAKE_STRING( "item_flag_team1" ); |
||||||
|
pev->team = RED; |
||||||
|
CItemFlag::Spawn(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
class CItemFlagTeam2 : public CItemFlag |
||||||
|
{ |
||||||
|
void Spawn() |
||||||
|
{ |
||||||
|
pev->classname = MAKE_STRING( "item_flag_team2" ); |
||||||
|
pev->team = BLUE; |
||||||
|
CItemFlag::Spawn(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
LINK_ENTITY_TO_CLASS( item_flag_team1, CItemFlagTeam1 ) |
||||||
|
LINK_ENTITY_TO_CLASS( ctf_redflag, CItemFlagTeam1 ) |
||||||
|
LINK_ENTITY_TO_CLASS( item_flag_team2, CItemFlagTeam2 ) |
||||||
|
LINK_ENTITY_TO_CLASS( ctf_blueflag, CItemFlagTeam2 ) |
||||||
|
|
||||||
|
void CCarriedFlag::Spawn() |
||||||
|
{ |
||||||
|
Precache(); |
||||||
|
|
||||||
|
SET_MODEL( ENT( pev ), "models/flag.mdl" ); |
||||||
|
UTIL_SetOrigin( pev, pev->origin ); |
||||||
|
|
||||||
|
pev->movetype = MOVETYPE_NONE; |
||||||
|
pev->solid = SOLID_NOT; |
||||||
|
pev->effects |= EF_NODRAW; |
||||||
|
pev->sequence = WAVE_IDLE; |
||||||
|
pev->framerate = 1.0; |
||||||
|
|
||||||
|
/*
|
||||||
|
if( pev->team == RED ) |
||||||
|
pev->skin = 1; |
||||||
|
else if( pev->team == BLUE ) |
||||||
|
pev->skin = 2;*/ |
||||||
|
pev->skin = pev->team; |
||||||
|
|
||||||
|
m_iOwnerOldVel = 0; |
||||||
|
|
||||||
|
SetThink( &CCarriedFlag::FlagThink ); |
||||||
|
pev->nextthink = gpGlobals->time + 0.1; |
||||||
|
} |
||||||
|
|
||||||
|
void CCarriedFlag::Precache() |
||||||
|
{ |
||||||
|
PRECACHE_MODEL( "models/flag.mdl" ); |
||||||
|
} |
||||||
|
|
||||||
|
void CCarriedFlag::FlagThink() |
||||||
|
{ |
||||||
|
// Make it visible
|
||||||
|
pev->effects &= ~EF_NODRAW; |
||||||
|
|
||||||
|
// And let if follow
|
||||||
|
pev->aiment = ENT( Owner->pev ); |
||||||
|
pev->movetype = MOVETYPE_FOLLOW; |
||||||
|
|
||||||
|
// If owner is death or lost flag, remove
|
||||||
|
if( !Owner->IsAlive() || !Owner->m_bHasFlag ) |
||||||
|
UTIL_Remove( this ); |
||||||
|
else |
||||||
|
{ |
||||||
|
// If owners speed is low, go in idle mode
|
||||||
|
if( Owner->pev->velocity.Length() <= 75 && pev->sequence != WAVE_IDLE ) |
||||||
|
{ |
||||||
|
pev->sequence = WAVE_IDLE; |
||||||
|
} |
||||||
|
// Else let the flag go wild
|
||||||
|
else if( Owner->pev->velocity.Length() >= 75 && pev->sequence != CARRIED ) |
||||||
|
{ |
||||||
|
pev->sequence = CARRIED; |
||||||
|
} |
||||||
|
|
||||||
|
pev->frame += pev->framerate; |
||||||
|
|
||||||
|
if( pev->frame < 0.0 || pev->frame >= 256.0 ) |
||||||
|
{ |
||||||
|
pev->frame -= (int)( pev->frame / 256.0 ) * 256.0; |
||||||
|
} |
||||||
|
pev->nextthink = gpGlobals->time + 0.1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class CCarriedFlagTeam1 : public CCarriedFlag |
||||||
|
{ |
||||||
|
void Spawn() |
||||||
|
{ |
||||||
|
pev->team = RED; |
||||||
|
CCarriedFlag::Spawn(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
class CCarriedFlagTeam2 : public CCarriedFlag |
||||||
|
{ |
||||||
|
void Spawn() |
||||||
|
{ |
||||||
|
pev->team = BLUE; |
||||||
|
CCarriedFlag::Spawn(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
LINK_ENTITY_TO_CLASS( carried_flag_team1, CCarriedFlagTeam1 ) |
||||||
|
LINK_ENTITY_TO_CLASS( carried_flag_team2, CCarriedFlagTeam2 ) |
@ -0,0 +1,107 @@ |
|||||||
|
/***
|
||||||
|
* |
||||||
|
* Copyright (c) 1996-2002, 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. |
||||||
|
* |
||||||
|
****/ |
||||||
|
//=========================================================
|
||||||
|
// Flags
|
||||||
|
//=========================================================
|
||||||
|
#pragma once |
||||||
|
#ifndef FLAGS_H |
||||||
|
#define FLAGS_H |
||||||
|
|
||||||
|
#define STEAL_SOUND 1 |
||||||
|
#define CAPTURE_SOUND 2 |
||||||
|
#define RETURN_SOUND 3 |
||||||
|
|
||||||
|
#define RED_FLAG_STOLEN 1 |
||||||
|
#define BLUE_FLAG_STOLEN 2 |
||||||
|
#define RED_FLAG_CAPTURED 3 |
||||||
|
#define BLUE_FLAG_CAPTURED 4 |
||||||
|
#define RED_FLAG_RETURNED_PLAYER 5 |
||||||
|
#define BLUE_FLAG_RETURNED_PLAYER 6 |
||||||
|
#define RED_FLAG_RETURNED 7 |
||||||
|
#define BLUE_FLAG_RETURNED 8 |
||||||
|
#define RED_FLAG_LOST 9 |
||||||
|
#define BLUE_FLAG_LOST 10 |
||||||
|
|
||||||
|
#define RED_FLAG_STOLEN 1 |
||||||
|
#define BLUE_FLAG_STOLEN 2 |
||||||
|
#define RED_FLAG_DROPPED 3 |
||||||
|
#define BLUE_FLAG_DROPPED 4 |
||||||
|
#define RED_FLAG_ATBASE 5 |
||||||
|
#define BLUE_FLAG_ATBASE 6 |
||||||
|
|
||||||
|
// Standard Scoring
|
||||||
|
#define TEAM_CAPTURE_CAPTURE_BONUS 5 // what you get for capture
|
||||||
|
#define TEAM_CAPTURE_TEAM_BONUS 10 // what your team gets for capture
|
||||||
|
#define TEAM_CAPTURE_RECOVERY_BONUS 1 // what you get for recovery
|
||||||
|
#define TEAM_CAPTURE_FLAG_BONUS 0 // what you get for picking up enemy flag
|
||||||
|
#define TEAM_CAPTURE_FRAG_CARRIER_BONUS 2 // what you get for fragging a enemy flag carrier
|
||||||
|
#define TEAM_CAPTURE_FLAG_RETURN_TIME 40 // seconds until auto return
|
||||||
|
|
||||||
|
// bonuses
|
||||||
|
#define TEAM_CAPTURE_CARRIER_DANGER_PROTECT_BONUS 2 // bonus for fraggin someone
|
||||||
|
// who has recently hurt your flag carrier
|
||||||
|
#define TEAM_CAPTURE_CARRIER_PROTECT_BONUS 1 // bonus for fraggin someone while
|
||||||
|
// either you or your target are near your flag carrier
|
||||||
|
#define TEAM_CAPTURE_FLAG_DEFENSE_BONUS 1 // bonus for fraggin someone while
|
||||||
|
// either you or your target are near your flag
|
||||||
|
#define TEAM_CAPTURE_RETURN_FLAG_ASSIST_BONUS 1 // awarded for returning a flag that causes a
|
||||||
|
// capture to happen almost immediately
|
||||||
|
#define TEAM_CAPTURE_FRAG_CARRIER_ASSIST_BONUS 2 // award for fragging a flag carrier if a
|
||||||
|
// capture happens almost immediately
|
||||||
|
|
||||||
|
// Radius
|
||||||
|
#define TEAM_CAPTURE_TARGET_PROTECT_RADIUS 550 // the radius around an object being
|
||||||
|
// defended where a target will be worth extra frags
|
||||||
|
#define TEAM_CAPTURE_ATTACKER_PROTECT_RADIUS 550 // the radius around an object being
|
||||||
|
// defended where an attacker will get extra frags when making kills
|
||||||
|
|
||||||
|
// timeouts
|
||||||
|
#define TEAM_CAPTURE_CARRIER_DANGER_PROTECT_TIMEOUT 4 |
||||||
|
#define TEAM_CAPTURE_CARRIER_FLAG_SINCE_TIMEOUT 2 |
||||||
|
#define TEAM_CAPTURE_FRAG_CARRIER_ASSIST_TIMEOUT 6 |
||||||
|
#define TEAM_CAPTURE_RETURN_FLAG_ASSIST_TIMEOUT 4 |
||||||
|
|
||||||
|
extern const char *GetTeamName( int team ); |
||||||
|
|
||||||
|
class CItemFlag : public CBaseEntity |
||||||
|
{ |
||||||
|
public: |
||||||
|
void Spawn(); |
||||||
|
BOOL Dropped; |
||||||
|
float m_flDroppedTime; |
||||||
|
void EXPORT FlagThink(); |
||||||
|
|
||||||
|
private: |
||||||
|
void Precache(); |
||||||
|
void Capture( CBasePlayer *pPlayer, int iTeam ); |
||||||
|
void ResetFlag( int iTeam ); |
||||||
|
void Materialize(); |
||||||
|
void EXPORT FlagTouch( CBaseEntity *pOther ); |
||||||
|
// BOOL MyTouch( CBasePlayer *pPlayer );
|
||||||
|
}; |
||||||
|
|
||||||
|
class CCarriedFlag : public CBaseEntity |
||||||
|
{ |
||||||
|
public: |
||||||
|
void Spawn(); |
||||||
|
CBasePlayer *Owner; |
||||||
|
int m_iOwnerOldVel; |
||||||
|
|
||||||
|
private: |
||||||
|
void Precache(); |
||||||
|
void EXPORT FlagThink(); |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // FLAGS_H
|
@ -0,0 +1,351 @@ |
|||||||
|
/***
|
||||||
|
* |
||||||
|
* Copyright (c) 1996-2002, 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. |
||||||
|
* |
||||||
|
****/ |
||||||
|
/***********************************************
|
||||||
|
************************************************ |
||||||
|
GRAPPLE |
||||||
|
************************************************ |
||||||
|
***********************************************/ |
||||||
|
|
||||||
|
#include "extdll.h" |
||||||
|
#include "util.h" |
||||||
|
#include "cbase.h" |
||||||
|
#include "player.h" |
||||||
|
#include "weapons.h" |
||||||
|
#include "grapple.h" |
||||||
|
|
||||||
|
unsigned short g_usHook; |
||||||
|
unsigned short g_usCable; |
||||||
|
|
||||||
|
void CGrapple::Reset_Grapple() |
||||||
|
{ |
||||||
|
CBasePlayer *pOwner = (CBasePlayer *)CBaseEntity::Instance( pev->owner ); |
||||||
|
|
||||||
|
pOwner->m_bOn_Hook = FALSE; |
||||||
|
pOwner->m_bHook_Out = FALSE; |
||||||
|
|
||||||
|
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, |
||||||
|
pOwner->edict(), g_usCable, 0, (float*)&g_vecZero, (float*)&g_vecZero, |
||||||
|
0.0, 0.0, entindex(), pev->team, 1, 0 ); |
||||||
|
|
||||||
|
STOP_SOUND( edict(), CHAN_WEAPON, "weapons/grhang.wav" ); |
||||||
|
STOP_SOUND( pOwner->edict(), CHAN_WEAPON, "weapons/grfire.wav" ); |
||||||
|
STOP_SOUND( pOwner->edict(), CHAN_WEAPON, "weapons/grpull.wav" ); |
||||||
|
|
||||||
|
pOwner->m_ppHook = NULL; |
||||||
|
pev->enemy = NULL; |
||||||
|
|
||||||
|
UTIL_Remove( this ); |
||||||
|
} |
||||||
|
|
||||||
|
void CGrapple::GrappleTouch( CBaseEntity *pOther ) |
||||||
|
{ |
||||||
|
CBasePlayer *pOwner = (CBasePlayer *)CBaseEntity::Instance( pev->owner ); |
||||||
|
|
||||||
|
if( pOther == pOwner ) |
||||||
|
return; |
||||||
|
|
||||||
|
// DO NOT allow the grapple to hook to any projectiles, no matter WHAT!
|
||||||
|
// if you create new types of projectiles, make sure you use one of the
|
||||||
|
// classnames below or write code to exclude your new classname so
|
||||||
|
// grapples will not stick to them.
|
||||||
|
if( pOther->Classify() == CLASS_PROJECTILE ) |
||||||
|
return; |
||||||
|
|
||||||
|
if( pOther->IsPlayer() ) |
||||||
|
{ |
||||||
|
// glance off of teammates
|
||||||
|
if( pOther->pev->team == pOwner->pev->team ) |
||||||
|
return; |
||||||
|
|
||||||
|
// sound( self, CHAN_WEAPON, "player/axhit1.wav", 1, ATTN_NORM );
|
||||||
|
// TakeDamage( pOther->pev, pOwner->pev, 10, DMG_GENERIC );
|
||||||
|
|
||||||
|
// make hook invisible since we will be pulling directly
|
||||||
|
// towards the player the hook hit. Quakeworld makes it
|
||||||
|
// too quirky to try to match hook's velocity with that of
|
||||||
|
// the client that it hit.
|
||||||
|
// setmodel( self, "");
|
||||||
|
pev->velocity = g_vecZero; |
||||||
|
UTIL_SetOrigin( pev, pOther->pev->origin ); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
// sound( self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM );
|
||||||
|
|
||||||
|
// One point of damage inflicted upon impact. Subsequent
|
||||||
|
// damage will only be done to PLAYERS... this way secret
|
||||||
|
// doors and triggers will only be damaged once.
|
||||||
|
if( pOther->pev->takedamage ) |
||||||
|
TakeDamage( pOther->pev, pOwner->pev, 1, DMG_GENERIC ); |
||||||
|
|
||||||
|
pev->velocity = g_vecZero; |
||||||
|
EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "weapons/grhit.wav", 1, ATTN_NORM ); |
||||||
|
|
||||||
|
// No sparks underwater
|
||||||
|
if( pev->waterlevel == 0 ) |
||||||
|
UTIL_Sparks( pev->origin ); |
||||||
|
} |
||||||
|
|
||||||
|
// conveniently clears the sound channel of the CHAIN1 sound,
|
||||||
|
// which is a looping sample and would continue to play. Tink1 is
|
||||||
|
// the least offensive choice, ass NULL.WAV loops and clogs the
|
||||||
|
// channel with silence
|
||||||
|
// sound (self.owner, CHAN_NO_PHS_ADD+CHAN_WEAPON, "weapons/tink1.wav", 1, ATTN_NORM);
|
||||||
|
|
||||||
|
if( !( pOwner->pev->button & IN_ATTACK ) ) |
||||||
|
{ |
||||||
|
if( pOwner->m_bOn_Hook ) |
||||||
|
{ |
||||||
|
Reset_Grapple(); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if( pOwner->pev->flags & FL_ONGROUND ) |
||||||
|
{ |
||||||
|
pOwner->pev->flags &= ~FL_ONGROUND; |
||||||
|
// setorigin(self.owner,self.owner.origin + '0 0 1');
|
||||||
|
} |
||||||
|
|
||||||
|
pOwner->m_bOn_Hook = TRUE; |
||||||
|
|
||||||
|
// sound( self.owner, CHAN_WEAPON, "weapons/chain2.wav", 1, ATTN_NORM );
|
||||||
|
|
||||||
|
// CHAIN2 is a looping sample. Use LEFTY as a flag so that client.qc
|
||||||
|
// will know to only play the tink sound ONCE to clear the weapons
|
||||||
|
// sound channel. (Lefty is a leftover from AI.QC, so I reused it to
|
||||||
|
// avoid adding a field)
|
||||||
|
//self.owner.lefty = TRUE;
|
||||||
|
|
||||||
|
STOP_SOUND( pOwner->edict(), CHAN_WEAPON, "weapons/grfire.wav" ); |
||||||
|
|
||||||
|
pev->enemy = pOther->edict();// remember this guy!
|
||||||
|
SetThink( &CGrapple::Grapple_Track ); |
||||||
|
pev->nextthink = gpGlobals->time; |
||||||
|
m_flNextIdleTime = gpGlobals->time + 0.1; |
||||||
|
pev->solid = SOLID_NOT; |
||||||
|
SetTouch( NULL ); |
||||||
|
} |
||||||
|
|
||||||
|
bool CanSee( CBaseEntity *pEnemy, CBaseEntity *pOwner ) |
||||||
|
{ |
||||||
|
TraceResult tr; |
||||||
|
|
||||||
|
UTIL_TraceLine( pOwner->pev->origin, pEnemy->pev->origin, ignore_monsters, ENT( pOwner->pev ), &tr ); |
||||||
|
if( tr.flFraction == 1 ) |
||||||
|
return TRUE; |
||||||
|
|
||||||
|
UTIL_TraceLine( pOwner->pev->origin, pEnemy->pev->origin + Vector( 15, 15, 0 ), ignore_monsters, ENT( pOwner->pev ), &tr ); |
||||||
|
if( tr.flFraction == 1 ) |
||||||
|
return TRUE; |
||||||
|
|
||||||
|
UTIL_TraceLine( pOwner->pev->origin, pEnemy->pev->origin + Vector( -15, -15, 0 ), ignore_monsters, ENT( pOwner->pev ), &tr ); |
||||||
|
if( tr.flFraction == 1 ) |
||||||
|
return TRUE; |
||||||
|
|
||||||
|
UTIL_TraceLine( pOwner->pev->origin, pEnemy->pev->origin + Vector( -15, 15, 0 ), ignore_monsters, ENT( pOwner->pev ), &tr ); |
||||||
|
if( tr.flFraction == 1 ) |
||||||
|
return TRUE; |
||||||
|
|
||||||
|
UTIL_TraceLine( pOwner->pev->origin, pEnemy->pev->origin + Vector( 15, -15, 0 ), ignore_monsters, ENT( pOwner->pev ), &tr ); |
||||||
|
if( tr.flFraction == 1 ) |
||||||
|
return TRUE; |
||||||
|
|
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
void CGrapple::Grapple_Track() |
||||||
|
{ |
||||||
|
CBasePlayer *pOwner = (CBasePlayer*)CBaseEntity::Instance( pev->owner ); |
||||||
|
CBaseEntity *pEnemy = CBaseEntity::Instance( pev->enemy ); |
||||||
|
|
||||||
|
// Release dead targets
|
||||||
|
if( pEnemy->IsPlayer() && pEnemy->pev->health <= 0 ) |
||||||
|
Reset_Grapple(); |
||||||
|
|
||||||
|
// drop the hook if owner is dead or has released the button
|
||||||
|
if( !pOwner->m_bOn_Hook || pOwner->pev->health <= 0 ) |
||||||
|
{ |
||||||
|
Reset_Grapple(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if( !( pOwner->pev->button & IN_ATTACK ) ) |
||||||
|
{ |
||||||
|
if( pOwner->m_iQuakeWeapon == IT_EXTRA_WEAPON ) |
||||||
|
{ |
||||||
|
Reset_Grapple(); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// bring the pAiN!
|
||||||
|
if( pEnemy->IsPlayer() ) |
||||||
|
{ |
||||||
|
if( !CanSee( pEnemy, pOwner ) ) |
||||||
|
{ |
||||||
|
Reset_Grapple(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
// move the hook along with the player. It's invisible, but
|
||||||
|
// we need this to make the sound come from the right spot
|
||||||
|
UTIL_SetOrigin( pev, pEnemy->pev->origin ); |
||||||
|
|
||||||
|
// sound( self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM );
|
||||||
|
|
||||||
|
SpawnBlood( pEnemy->pev->origin, BLOOD_COLOR_RED, 1 ); |
||||||
|
( (CBasePlayer *)pEnemy )->TakeDamage( pev, pOwner->pev, 1, DMG_GENERIC ); |
||||||
|
} |
||||||
|
|
||||||
|
// If the hook is not attached to the player, constantly copy
|
||||||
|
// copy the target's velocity. Velocity copying DOES NOT work properly
|
||||||
|
// for a hooked client.
|
||||||
|
else |
||||||
|
pev->velocity = pEnemy->pev->velocity; |
||||||
|
|
||||||
|
pev->nextthink = gpGlobals->time + 0.1; |
||||||
|
} |
||||||
|
|
||||||
|
void CBasePlayer::Service_Grapple() |
||||||
|
{ |
||||||
|
Vector hook_dir; |
||||||
|
CBaseEntity *pEnemy = CBaseEntity::Instance( pev->enemy ); |
||||||
|
|
||||||
|
// drop the hook if player lets go of button
|
||||||
|
if( !( pev->button & IN_ATTACK ) ) |
||||||
|
{ |
||||||
|
if( m_iQuakeWeapon == IT_EXTRA_WEAPON ) |
||||||
|
{ |
||||||
|
m_ppHook->Reset_Grapple(); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if( m_ppHook->pev->enemy != NULL ) |
||||||
|
{ |
||||||
|
// If hooked to a player, track them directly!
|
||||||
|
if( pEnemy->IsPlayer() ) |
||||||
|
{ |
||||||
|
pEnemy = CBaseEntity::Instance( pev->enemy ); |
||||||
|
hook_dir = ( pEnemy->pev->origin - pev->origin ); |
||||||
|
} |
||||||
|
// else, track to hook
|
||||||
|
else |
||||||
|
hook_dir = ( m_ppHook->pev->origin - pev->origin ); |
||||||
|
|
||||||
|
pev->speed = 750; |
||||||
|
pev->velocity = ( hook_dir.Normalize() * pev->speed ); |
||||||
|
|
||||||
|
if( m_ppHook->m_flNextIdleTime <= gpGlobals->time && hook_dir.Length() <= 50 ) |
||||||
|
{ |
||||||
|
//No sparks underwater
|
||||||
|
if( m_ppHook->pev->waterlevel == 0 ) |
||||||
|
UTIL_Sparks( m_ppHook->pev->origin ); |
||||||
|
|
||||||
|
STOP_SOUND( edict(), CHAN_WEAPON, "weapons/grpull.wav" ); |
||||||
|
EMIT_SOUND( ENT( m_ppHook->pev ), CHAN_WEAPON, "weapons/grhang.wav", 1, ATTN_NORM ); |
||||||
|
|
||||||
|
m_ppHook->m_flNextIdleTime = gpGlobals->time + RANDOM_LONG( 1, 3 ); |
||||||
|
|
||||||
|
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, |
||||||
|
edict(), g_usCable, 0, (float *)&g_vecZero, (float *)&g_vecZero, |
||||||
|
0.0, 0.0, m_ppHook->entindex(), pev->team, 1, 0 ); |
||||||
|
} |
||||||
|
else if( m_ppHook->m_flNextIdleTime <= gpGlobals->time ) |
||||||
|
{ |
||||||
|
// No sparks underwater
|
||||||
|
if( m_ppHook->pev->waterlevel == 0 ) |
||||||
|
UTIL_Sparks( m_ppHook->pev->origin ); |
||||||
|
|
||||||
|
STOP_SOUND( edict(), CHAN_WEAPON, "weapons/grfire.wav" ); |
||||||
|
EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "weapons/grpull.wav", 1, ATTN_NORM ); |
||||||
|
m_ppHook->m_flNextIdleTime = gpGlobals->time + RANDOM_LONG( 1, 3 ); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void CGrapple::OnAirThink() |
||||||
|
{ |
||||||
|
TraceResult tr; |
||||||
|
|
||||||
|
CBaseEntity *pOwner = CBaseEntity::Instance( pev->owner ); |
||||||
|
|
||||||
|
if( !( pOwner->pev->button & IN_ATTACK ) ) |
||||||
|
{ |
||||||
|
Reset_Grapple(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
UTIL_TraceLine( pev->origin, pOwner->pev->origin, ignore_monsters, ENT( pev ), &tr ); |
||||||
|
|
||||||
|
if( tr.flFraction < 1.0 ) |
||||||
|
{ |
||||||
|
Reset_Grapple(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
pev->nextthink = gpGlobals->time + 0.5; |
||||||
|
} |
||||||
|
|
||||||
|
void CGrapple::Spawn() |
||||||
|
{ |
||||||
|
pev->movetype = MOVETYPE_FLYMISSILE; |
||||||
|
pev->solid = SOLID_BBOX; |
||||||
|
|
||||||
|
SET_MODEL( ENT( pev ),"models/hook.mdl" ); |
||||||
|
|
||||||
|
SetTouch( &CGrapple::GrappleTouch ); |
||||||
|
SetThink( &CGrapple::OnAirThink ); |
||||||
|
|
||||||
|
pev->nextthink = gpGlobals->time + 0.1; |
||||||
|
} |
||||||
|
|
||||||
|
LINK_ENTITY_TO_CLASS( hook, CGrapple ); |
||||||
|
|
||||||
|
void CBasePlayer::Throw_Grapple() |
||||||
|
{ |
||||||
|
if( m_bHook_Out ) |
||||||
|
return; |
||||||
|
|
||||||
|
CGrapple *pHookCBEnt = NULL; |
||||||
|
pHookCBEnt = (CGrapple*)CBaseEntity::Create( "hook", pev->origin, pev->angles, NULL ); |
||||||
|
|
||||||
|
if( pHookCBEnt ) |
||||||
|
{ |
||||||
|
m_ppHook = pHookCBEnt; |
||||||
|
|
||||||
|
m_ppHook->pev->owner = edict(); |
||||||
|
|
||||||
|
UTIL_MakeVectors( pev->v_angle ); |
||||||
|
|
||||||
|
UTIL_SetOrigin( m_ppHook->pev, pev->origin + gpGlobals->v_forward * 16 + Vector( 0, 0, 16 ) ); |
||||||
|
UTIL_SetSize( m_ppHook->pev, g_vecZero, g_vecZero ); |
||||||
|
|
||||||
|
EMIT_SOUND( ENT( pev ), CHAN_WEAPON, "weapons/grfire.wav", 1, ATTN_NORM ); |
||||||
|
|
||||||
|
// Make if fly forward
|
||||||
|
m_ppHook->pev->velocity = gpGlobals->v_forward * 1000; |
||||||
|
// And make the hook face forward too!
|
||||||
|
m_ppHook->pev->angles = UTIL_VecToAngles( gpGlobals->v_forward ); |
||||||
|
m_ppHook->pev->fixangle = TRUE; |
||||||
|
|
||||||
|
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, |
||||||
|
edict(), g_usCable, 0, (float*)&g_vecZero, (float*)&g_vecZero, |
||||||
|
0.0, 0.0, m_ppHook->entindex(), pev->team, 0, 0 ); |
||||||
|
|
||||||
|
m_bHook_Out = TRUE; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,32 @@ |
|||||||
|
/***
|
||||||
|
* |
||||||
|
* Copyright (c) 1996-2002, 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. |
||||||
|
* |
||||||
|
****/ |
||||||
|
#pragma once |
||||||
|
#ifndef GRAPPLE_H |
||||||
|
#define GRAPPLE_H |
||||||
|
class CGrapple : public CBaseEntity |
||||||
|
{ |
||||||
|
public: |
||||||
|
//Yes, I have no imagination so I use standard touch, spawn and think function names.
|
||||||
|
//Sue me! =P.
|
||||||
|
void Spawn(); |
||||||
|
int Classify() { return CLASS_PROJECTILE; }; |
||||||
|
void EXPORT OnAirThink(); |
||||||
|
void EXPORT GrappleTouch( CBaseEntity *pOther ); |
||||||
|
void Reset_Grapple(); |
||||||
|
void EXPORT Grapple_Track(); |
||||||
|
|
||||||
|
float m_flNextIdleTime; |
||||||
|
}; |
||||||
|
#endif // GRAPPLE_H
|
@ -0,0 +1,420 @@ |
|||||||
|
/***
|
||||||
|
* |
||||||
|
* Copyright (c) 1996-2002, 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. |
||||||
|
* |
||||||
|
****/ |
||||||
|
/*
|
||||||
|
*************************************** |
||||||
|
**************************************** |
||||||
|
RUNES |
||||||
|
**************************************** |
||||||
|
***************************************/ |
||||||
|
|
||||||
|
#include "extdll.h" |
||||||
|
#include "util.h" |
||||||
|
#include "cbase.h" |
||||||
|
#include "player.h" |
||||||
|
#include "weapons.h" |
||||||
|
#include "gamerules.h" |
||||||
|
#include "threewave_gamerules.h" |
||||||
|
#include "runes.h" |
||||||
|
|
||||||
|
extern bool g_bSpawnedRunes; |
||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
The Rune Game modes |
||||||
|
|
||||||
|
Rune 1 - Earth Magic |
||||||
|
resistance |
||||||
|
Rune 2 - Black Magic |
||||||
|
strength |
||||||
|
Rune 3 - Hell Magic |
||||||
|
haste |
||||||
|
Rune 4 - Elder Magic |
||||||
|
regeneration |
||||||
|
|
||||||
|
----------------------------------------------------------------------*/ |
||||||
|
|
||||||
|
BOOL IsRuneSpawnPointValid( CBaseEntity *pSpot ) |
||||||
|
{ |
||||||
|
CBaseEntity *ent = NULL; |
||||||
|
|
||||||
|
while( ( ent = UTIL_FindEntityInSphere( ent, pSpot->pev->origin, 128 ) ) != NULL ) |
||||||
|
{ |
||||||
|
//Try not to spawn it near other runes.
|
||||||
|
if( ent->Classify() == CLASS_RUNE ) |
||||||
|
return FALSE; |
||||||
|
} |
||||||
|
|
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
|
||||||
|
edict_t *RuneSelectSpawnPoint() |
||||||
|
{ |
||||||
|
CBaseEntity *pSpot = NULL; |
||||||
|
|
||||||
|
// Randomize the start spot
|
||||||
|
for( int i = RANDOM_LONG( 1, 5 ); i > 0; i-- ) |
||||||
|
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" ); |
||||||
|
if( !pSpot ) // skip over the null point
|
||||||
|
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" ); |
||||||
|
|
||||||
|
CBaseEntity *pFirstSpot = pSpot; |
||||||
|
|
||||||
|
do |
||||||
|
{ |
||||||
|
if( pSpot ) |
||||||
|
{ |
||||||
|
if( IsRuneSpawnPointValid( pSpot ) ) |
||||||
|
{ |
||||||
|
if( pSpot->pev->origin == g_vecZero ) |
||||||
|
{ |
||||||
|
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" ); |
||||||
|
continue; |
||||||
|
} |
||||||
|
// if so, go to pSpot
|
||||||
|
goto ReturnSpot; |
||||||
|
} |
||||||
|
} |
||||||
|
// increment pSpot
|
||||||
|
pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" ); |
||||||
|
} while ( pSpot != pFirstSpot ); // loop if we're not back to the start
|
||||||
|
|
||||||
|
// we haven't found a place to spawn yet, so kill any guy at the first spawn point and spawn there
|
||||||
|
if( pSpot ) |
||||||
|
goto ReturnSpot; |
||||||
|
|
||||||
|
// If startspot is set, (re)spawn there.
|
||||||
|
if( FStringNull( gpGlobals->startspot ) || !strlen( STRING( gpGlobals->startspot ) ) ) |
||||||
|
{ |
||||||
|
pSpot = UTIL_FindEntityByClassname( NULL, "info_player_start" ); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
pSpot = UTIL_FindEntityByTargetname( NULL, STRING( gpGlobals->startspot ) ); |
||||||
|
} |
||||||
|
|
||||||
|
ReturnSpot: |
||||||
|
if( !pSpot ) |
||||||
|
{ |
||||||
|
ALERT( at_error, "PutClientInServer: no info_player_start on level" ); |
||||||
|
return INDEXENT( 0 ); |
||||||
|
} |
||||||
|
return pSpot->edict(); |
||||||
|
} |
||||||
|
|
||||||
|
void VectorScale( const float *in, float scale, float *out ) |
||||||
|
{ |
||||||
|
out[0] = in[0] * scale; |
||||||
|
out[1] = in[1] * scale; |
||||||
|
out[2] = in[2] * scale; |
||||||
|
} |
||||||
|
|
||||||
|
void G_ProjectSource( vec3_t point, vec3_t distance, vec3_t forward, vec3_t right, vec3_t result ) |
||||||
|
{ |
||||||
|
result[0] = point[0] + forward[0] * distance[0] + right[0] * distance[1]; |
||||||
|
result[1] = point[1] + forward[1] * distance[0] + right[1] * distance[1]; |
||||||
|
result[2] = point[2] + forward[2] * distance[0] + right[2] * distance[1] + distance[2]; |
||||||
|
} |
||||||
|
|
||||||
|
#define VectorSet(v, x, y, z) (v[0]=(x), v[1]=(y), v[2]=(z)) |
||||||
|
|
||||||
|
void DropRune( CBasePlayer *pPlayer ) |
||||||
|
{ |
||||||
|
TraceResult tr; |
||||||
|
|
||||||
|
// do they even have a rune?
|
||||||
|
if( pPlayer->m_iRuneStatus == 0 ) |
||||||
|
return; |
||||||
|
|
||||||
|
// Make Sure there's enough room to drop the rune here
|
||||||
|
// This is so hacky ( the reason why we are doing this), and I hate it to death.
|
||||||
|
UTIL_MakeVectors( pPlayer->pev->v_angle ); |
||||||
|
Vector vecSrc = pPlayer->GetGunPosition( ); |
||||||
|
Vector vecEnd = vecSrc + gpGlobals->v_forward * 32; |
||||||
|
UTIL_TraceHull( vecSrc, vecEnd, dont_ignore_monsters, human_hull, ENT( pPlayer->pev ), &tr ); |
||||||
|
|
||||||
|
if( tr.flFraction != 1 ) |
||||||
|
{ |
||||||
|
ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "Not enough room to drop the rune here." ); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if( pPlayer->m_iRuneStatus ) |
||||||
|
{ |
||||||
|
CItemRune *pRune = (CItemRune*)CBaseEntity::Create( g_RuneEntityName[pPlayer->m_iRuneStatus], pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() ); |
||||||
|
|
||||||
|
if( pRune ) |
||||||
|
pRune->dropped = true; |
||||||
|
|
||||||
|
if( pPlayer->m_iRuneStatus == ITEM_RUNE3_FLAG ) |
||||||
|
g_engfuncs.pfnSetClientMaxspeed( ENT( pPlayer->pev ), PLAYER_MAX_SPEED ); // Reset Haste player speed to normal
|
||||||
|
|
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Dropped_%s\"\n", |
||||||
|
STRING(pPlayer->pev->netname), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
pPlayer->m_szTeamName, |
||||||
|
g_RuneName[pPlayer->m_iRuneStatus] ); |
||||||
|
pPlayer->m_iRuneStatus = 0; |
||||||
|
} |
||||||
|
|
||||||
|
MESSAGE_BEGIN( MSG_ONE, gmsgRuneStatus, NULL, pPlayer->pev ); |
||||||
|
WRITE_BYTE( pPlayer->m_iRuneStatus ); |
||||||
|
MESSAGE_END(); |
||||||
|
} |
||||||
|
|
||||||
|
void CItemRune::Spawn() |
||||||
|
{ |
||||||
|
m_bTouchable = FALSE; |
||||||
|
|
||||||
|
dropped = false; |
||||||
|
|
||||||
|
pev->movetype = MOVETYPE_TOSS; |
||||||
|
pev->solid = SOLID_TRIGGER; |
||||||
|
|
||||||
|
vec3_t forward, right, up; |
||||||
|
Vector vecAngles; |
||||||
|
|
||||||
|
UTIL_SetSize( pev, Vector( -15, -15, -15 ), Vector( 15, 15, 15 ) ); |
||||||
|
|
||||||
|
pev->angles.z = pev->angles.x = 0; |
||||||
|
pev->angles.y = RANDOM_LONG ( 0, 360 ); |
||||||
|
|
||||||
|
//If we got an owner, it means we are either dropping the flag or diying and letting it go.
|
||||||
|
if( pev->owner ) |
||||||
|
vecAngles = pev->owner->v.angles; |
||||||
|
else |
||||||
|
vecAngles = pev->angles; |
||||||
|
|
||||||
|
g_engfuncs.pfnAngleVectors( vecAngles, forward, right, up ); |
||||||
|
|
||||||
|
UTIL_SetOrigin( pev, pev->origin ); |
||||||
|
|
||||||
|
pev->velocity = ( forward * 400 ) + ( up * 200 ); |
||||||
|
|
||||||
|
if( pev->owner == NULL ) |
||||||
|
{ |
||||||
|
pev->origin.z += 16; |
||||||
|
pev->velocity.z = 300; |
||||||
|
} |
||||||
|
|
||||||
|
pev->owner = NULL; |
||||||
|
|
||||||
|
SetTouch( &CItemRune::RuneTouch ); |
||||||
|
|
||||||
|
pev->nextthink = gpGlobals->time + 1; // if no one touches it in two minutes,
|
||||||
|
// respawn it somewhere else, so inaccessible
|
||||||
|
// ones will come 'back'
|
||||||
|
SetThink( &CItemRune::MakeTouchable ); |
||||||
|
} |
||||||
|
|
||||||
|
void CItemRune::MakeTouchable() |
||||||
|
{ |
||||||
|
m_bTouchable = TRUE; |
||||||
|
pev->nextthink = gpGlobals->time + 120; // if no one touches it in two minutes,
|
||||||
|
// respawn it somewhere else, so inaccessible
|
||||||
|
// ones will come 'back'
|
||||||
|
SetThink( &CItemRune::RuneRespawn ); |
||||||
|
} |
||||||
|
|
||||||
|
void CItemRune::RuneTouch( CBaseEntity *pOther ) |
||||||
|
{ |
||||||
|
// No toucher?
|
||||||
|
if( !pOther ) |
||||||
|
return; |
||||||
|
|
||||||
|
// Not a player?
|
||||||
|
if( !pOther->IsPlayer() ) |
||||||
|
return; |
||||||
|
|
||||||
|
// DEAD?!
|
||||||
|
if( pOther->pev->health <= 0 ) |
||||||
|
return; |
||||||
|
|
||||||
|
// Spectating?
|
||||||
|
if( pOther->pev->movetype == MOVETYPE_NOCLIP ) |
||||||
|
return; |
||||||
|
|
||||||
|
CBasePlayer *pPlayer = (CBasePlayer*)pOther; |
||||||
|
|
||||||
|
// Only one per customer
|
||||||
|
if( pPlayer->m_iRuneStatus ) |
||||||
|
{ |
||||||
|
ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "You already have a rune!\n" ); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if( !m_bTouchable ) |
||||||
|
return; |
||||||
|
|
||||||
|
pPlayer->m_iRuneStatus = m_iRuneFlag; //Add me the rune flag
|
||||||
|
|
||||||
|
PrintTouchMessage( pPlayer ); |
||||||
|
|
||||||
|
EMIT_SOUND( ENT( pev ), CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM ); |
||||||
|
|
||||||
|
//Update my client side rune hud thingy.
|
||||||
|
MESSAGE_BEGIN( MSG_ONE, gmsgRuneStatus, NULL, pOther->pev ); |
||||||
|
WRITE_BYTE( pPlayer->m_iRuneStatus ); |
||||||
|
MESSAGE_END(); |
||||||
|
|
||||||
|
// And Remove this entity
|
||||||
|
UTIL_Remove( this ); |
||||||
|
} |
||||||
|
|
||||||
|
void CItemRune::RuneRespawn() |
||||||
|
{ |
||||||
|
edict_t *pentSpawnSpot; |
||||||
|
vec3_t vOrigin; |
||||||
|
|
||||||
|
pentSpawnSpot = RuneSelectSpawnPoint(); |
||||||
|
vOrigin = VARS( pentSpawnSpot )->origin; |
||||||
|
|
||||||
|
UTIL_SetOrigin( pev, vOrigin ); |
||||||
|
|
||||||
|
if( dropped ) |
||||||
|
PrintRespawnMessage(); |
||||||
|
|
||||||
|
Spawn(); |
||||||
|
} |
||||||
|
|
||||||
|
void CResistRune::PrintTouchMessage( CBasePlayer *pPlayer ) |
||||||
|
{ |
||||||
|
ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "You got the rune of Resistance!\n" ); |
||||||
|
|
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Found_ResistRune\"\n", |
||||||
|
STRING(pPlayer->pev->netname), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
pPlayer->m_szTeamName ); |
||||||
|
} |
||||||
|
|
||||||
|
void CResistRune::PrintRespawnMessage() |
||||||
|
{ |
||||||
|
UTIL_LogPrintf( "\"<-1><><>\" triggered \"Respawn_ResistRune\"\n" ); |
||||||
|
} |
||||||
|
|
||||||
|
void CResistRune::Spawn() |
||||||
|
{ |
||||||
|
SET_MODEL( ENT( pev ), "models/rune_resist.mdl" ); |
||||||
|
m_iRuneFlag = ITEM_RUNE1_FLAG; |
||||||
|
CItemRune::Spawn(); |
||||||
|
} |
||||||
|
|
||||||
|
LINK_ENTITY_TO_CLASS( item_rune1, CResistRune ); |
||||||
|
|
||||||
|
void CStrengthRune::PrintTouchMessage( CBasePlayer *pPlayer ) |
||||||
|
{ |
||||||
|
ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "You got the rune of Strength!\n" ); |
||||||
|
|
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Found_StrengthRune\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
pPlayer->m_szTeamName ); |
||||||
|
} |
||||||
|
|
||||||
|
void CStrengthRune::PrintRespawnMessage() |
||||||
|
{ |
||||||
|
UTIL_LogPrintf( "\"<-1><><>\" triggered \"Respawn_StrengthRune\"\n" ); |
||||||
|
} |
||||||
|
|
||||||
|
void CStrengthRune::Spawn() |
||||||
|
{ |
||||||
|
SET_MODEL( ENT( pev ), "models/rune_strength.mdl" ); |
||||||
|
m_iRuneFlag = ITEM_RUNE2_FLAG; |
||||||
|
CItemRune::Spawn(); |
||||||
|
} |
||||||
|
|
||||||
|
LINK_ENTITY_TO_CLASS( item_rune2, CStrengthRune ) |
||||||
|
|
||||||
|
void CHasteRune::PrintTouchMessage( CBasePlayer *pPlayer ) |
||||||
|
{ |
||||||
|
ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "You got the rune of Haste!\n" ); |
||||||
|
|
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Found_HasteRune\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
pPlayer->m_szTeamName ); |
||||||
|
|
||||||
|
g_engfuncs.pfnSetClientMaxspeed( ENT( pPlayer->pev ), ( PLAYER_MAX_SPEED * 1.25 ) ); // 25% more speed
|
||||||
|
} |
||||||
|
|
||||||
|
void CHasteRune::PrintRespawnMessage() |
||||||
|
{ |
||||||
|
UTIL_LogPrintf( "\"<-1><><>\" triggered triggered \"Respawn_HasteRune\"\n" ); |
||||||
|
} |
||||||
|
|
||||||
|
void CHasteRune::Spawn() |
||||||
|
{ |
||||||
|
SET_MODEL( ENT( pev ), "models/rune_haste.mdl" ); |
||||||
|
m_iRuneFlag = ITEM_RUNE3_FLAG; |
||||||
|
CItemRune::Spawn(); |
||||||
|
} |
||||||
|
|
||||||
|
LINK_ENTITY_TO_CLASS( item_rune3, CHasteRune ) |
||||||
|
|
||||||
|
void CRegenRune::PrintTouchMessage( CBasePlayer *pPlayer ) |
||||||
|
{ |
||||||
|
ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "You got the rune of Regeneration!\n" ); |
||||||
|
|
||||||
|
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Found_RegenRune\"\n", |
||||||
|
STRING( pPlayer->pev->netname ), |
||||||
|
GETPLAYERUSERID( pPlayer->edict() ), |
||||||
|
GETPLAYERAUTHID( pPlayer->edict() ), |
||||||
|
pPlayer->m_szTeamName ); |
||||||
|
} |
||||||
|
|
||||||
|
void CRegenRune::PrintRespawnMessage() |
||||||
|
{ |
||||||
|
UTIL_LogPrintf( "\"<-1><><>\" triggered triggered \"Respawn_RegenRune\"\n" ); |
||||||
|
} |
||||||
|
|
||||||
|
void CRegenRune::Spawn() |
||||||
|
{ |
||||||
|
SET_MODEL( ENT( pev ), "models/rune_regen.mdl" ); |
||||||
|
m_iRuneFlag = ITEM_RUNE4_FLAG; |
||||||
|
CItemRune::Spawn(); |
||||||
|
} |
||||||
|
|
||||||
|
LINK_ENTITY_TO_CLASS( item_rune4, CRegenRune ) |
||||||
|
|
||||||
|
/*
|
||||||
|
================ |
||||||
|
SpawnRunes |
||||||
|
spawn all the runes |
||||||
|
self is the entity that was created for us, we remove it |
||||||
|
================ |
||||||
|
*/ |
||||||
|
void SpawnRunes() |
||||||
|
{ |
||||||
|
if( g_bSpawnedRunes ) |
||||||
|
return; |
||||||
|
|
||||||
|
edict_t *pentSpawnSpot; |
||||||
|
|
||||||
|
pentSpawnSpot = RuneSelectSpawnPoint(); |
||||||
|
CBaseEntity::Create( "item_rune1", VARS(pentSpawnSpot)->origin, VARS( pentSpawnSpot )->angles, NULL ); |
||||||
|
|
||||||
|
pentSpawnSpot = RuneSelectSpawnPoint(); |
||||||
|
CBaseEntity::Create( "item_rune2", VARS(pentSpawnSpot)->origin, VARS( pentSpawnSpot )->angles, NULL ); |
||||||
|
|
||||||
|
pentSpawnSpot = RuneSelectSpawnPoint(); |
||||||
|
CBaseEntity::Create( "item_rune3", VARS(pentSpawnSpot)->origin, VARS( pentSpawnSpot )->angles, NULL ); |
||||||
|
|
||||||
|
pentSpawnSpot = RuneSelectSpawnPoint(); |
||||||
|
CBaseEntity::Create( "item_rune4", VARS(pentSpawnSpot)->origin, VARS( pentSpawnSpot )->angles, NULL ); |
||||||
|
|
||||||
|
g_bSpawnedRunes = TRUE; |
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
/***
|
||||||
|
* |
||||||
|
* Copyright (c) 1996-2002, 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. |
||||||
|
* |
||||||
|
****/ |
||||||
|
#pragma once |
||||||
|
#ifndef RUNES_H |
||||||
|
#define RUNES_H |
||||||
|
|
||||||
|
static const char *g_RuneEntityName[] = |
||||||
|
{ |
||||||
|
"", |
||||||
|
"item_rune1", |
||||||
|
"item_rune2", |
||||||
|
"item_rune3", |
||||||
|
"item_rune4" |
||||||
|
}; |
||||||
|
|
||||||
|
static const char *g_RuneName[] = |
||||||
|
{ |
||||||
|
"Unknown", |
||||||
|
"ResistRune", |
||||||
|
"StrengthRune", |
||||||
|
"HasteRune", |
||||||
|
"RegenRune" |
||||||
|
}; |
||||||
|
|
||||||
|
class CItemRune : public CBaseEntity |
||||||
|
{ |
||||||
|
private: |
||||||
|
void EXPORT RuneRespawn(); |
||||||
|
public: |
||||||
|
void EXPORT RuneTouch( CBaseEntity *pOther ); |
||||||
|
void Spawn(); |
||||||
|
int Classify() { return CLASS_RUNE; }; |
||||||
|
void EXPORT MakeTouchable(); |
||||||
|
virtual void PrintTouchMessage( CBasePlayer *pPlayer ){} |
||||||
|
virtual void PrintRespawnMessage(){} |
||||||
|
|
||||||
|
int m_iRuneFlag; |
||||||
|
bool m_bTouchable; |
||||||
|
bool dropped; |
||||||
|
}; |
||||||
|
|
||||||
|
class CResistRune : public CItemRune |
||||||
|
{ |
||||||
|
public: |
||||||
|
void Spawn(); |
||||||
|
void PrintTouchMessage( CBasePlayer *pPlayer ); |
||||||
|
void PrintRespawnMessage(); |
||||||
|
}; |
||||||
|
|
||||||
|
class CStrengthRune : public CItemRune |
||||||
|
{ |
||||||
|
public: |
||||||
|
void Spawn(); |
||||||
|
void PrintTouchMessage( CBasePlayer *pPlayer ); |
||||||
|
void PrintRespawnMessage(); |
||||||
|
}; |
||||||
|
|
||||||
|
class CHasteRune : public CItemRune |
||||||
|
{ |
||||||
|
public: |
||||||
|
void Spawn(); |
||||||
|
void PrintTouchMessage( CBasePlayer *pPlayer ); |
||||||
|
void PrintRespawnMessage(); |
||||||
|
}; |
||||||
|
|
||||||
|
class CRegenRune : public CItemRune |
||||||
|
{ |
||||||
|
public: |
||||||
|
void Spawn(); |
||||||
|
void PrintTouchMessage( CBasePlayer *pPlayer ); |
||||||
|
void PrintRespawnMessage(); |
||||||
|
}; |
||||||
|
#endif // RUNES_H
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue