diff --git a/dmc/cl_dll/CTF_FlagStatus.cpp b/dmc/cl_dll/CTF_FlagStatus.cpp deleted file mode 100644 index b11adcf..0000000 --- a/dmc/cl_dll/CTF_FlagStatus.cpp +++ /dev/null @@ -1,246 +0,0 @@ -#ifdef THREEWAVE - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "entity_types.h" -#include "usercmd.h" -#include "pm_defs.h" -#include "pm_materials.h" -#include "ref_params.h" -#include -#include "vgui_viewport.h" -#include "vgui_ScorePanel.h" - -#define RED_FLAG_STOLE 1 -#define BLUE_FLAG_STOLE 2 -#define RED_FLAG_LOST 3 -#define BLUE_FLAG_LOST 4 -#define RED_FLAG_ATBASE 5 -#define BLUE_FLAG_ATBASE 6 - -#define ITEM_RUNE1_FLAG 1 -#define ITEM_RUNE2_FLAG 2 -#define ITEM_RUNE3_FLAG 3 -#define ITEM_RUNE4_FLAG 4 - -DECLARE_MESSAGE(m_FlagStat, FlagStat) -DECLARE_MESSAGE(m_FlagStat, RuneStat) -DECLARE_MESSAGE(m_FlagStat, FlagCarrier) - -int CHudFlagStatus::Init(void) -{ - HOOK_MESSAGE( FlagStat ); - HOOK_MESSAGE( RuneStat ); - HOOK_MESSAGE( FlagCarrier ); - - m_iFlags |= HUD_ACTIVE; - - gHUD.AddHudElem(this); - - Reset(); - - return 1; -}; - -int CHudFlagStatus::VidInit(void) -{ - m_iBlueAtBaseIndex = gHUD.GetSpriteIndex( "blue_atbase" ); - m_iBlueLostIndex = gHUD.GetSpriteIndex( "blue_lost" ); - m_iBlueStolenIndex = gHUD.GetSpriteIndex( "blue_stolen" ); - - m_iRedAtBaseIndex = gHUD.GetSpriteIndex( "red_atbase" ); - m_iRedLostIndex = gHUD.GetSpriteIndex( "red_lost" ); - m_iRedStolenIndex = gHUD.GetSpriteIndex( "red_stolen" ); - - m_iRune1Index = gHUD.GetSpriteIndex( "rune1" ); - m_iRune2Index = gHUD.GetSpriteIndex( "rune2" ); - m_iRune3Index = gHUD.GetSpriteIndex( "rune3" ); - m_iRune4Index = gHUD.GetSpriteIndex( "rune4" ); - - m_hBlueAtBase = gHUD.GetSprite( m_iBlueAtBaseIndex ); - m_hBlueLost = gHUD.GetSprite( m_iBlueLostIndex ); - m_hBlueStolen = gHUD.GetSprite( m_iBlueStolenIndex ); - - m_hRedAtBase = gHUD.GetSprite( m_iRedAtBaseIndex ); - m_hRedLost = gHUD.GetSprite( m_iRedLostIndex ); - m_hRedStolen = gHUD.GetSprite( m_iRedStolenIndex ); - - m_hRune1 = gHUD.GetSprite( m_iRune1Index ); - m_hRune2 = gHUD.GetSprite( m_iRune2Index ); - m_hRune3 = gHUD.GetSprite( m_iRune3Index ); - m_hRune4 = gHUD.GetSprite( m_iRune4Index ); - - // Load sprites here - m_iBlueFlagIndex = gHUD.GetSpriteIndex( "b_flag_c" ); - m_iRedFlagIndex = gHUD.GetSpriteIndex( "r_flag_c" ); - - m_hBlueFlag = gHUD.GetSprite( m_iBlueFlagIndex ); - m_hRedFlag = gHUD.GetSprite( m_iRedFlagIndex ); - - return 1; -} - -void CHudFlagStatus :: Reset( void ) -{ - return; -} - - -int CHudFlagStatus ::Draw(float flTime ) -{ - - if ( !iDrawStatus ) - return 1; - - int x, y; - int r,g,b; - - r = g = b = 255; - - x = 20; - y = ( ScreenHeight - gHUD.m_iFontHeight ) - ( gHUD.m_iFontHeight / 2 ) - 40; - - - switch ( iBlueFlagStatus ) - { - case BLUE_FLAG_STOLE: - SPR_Set( m_hBlueStolen, r, g, b ); - SPR_DrawHoles( 1, x, y, NULL ); - break; - case BLUE_FLAG_LOST: - SPR_Set( m_hBlueLost, r, g, b ); - SPR_DrawHoles( 1, x, y, NULL ); - break; - case BLUE_FLAG_ATBASE: - SPR_Set( m_hBlueAtBase, r, g, b ); - SPR_DrawHoles( 1, x, y, NULL ); - break; - } - - x = 50; - - if ( iBlueTeamScore < 10) - { - x += 3; - gHUD.DrawHudNumber( x, y + 4, DHN_DRAWZERO, iBlueTeamScore, 255, 255, 255 ); - } - else if ( iBlueTeamScore >= 10 && iBlueTeamScore < 100 ) - gHUD.DrawHudNumber( x, y + 4, DHN_2DIGITS | DHN_DRAWZERO, iBlueTeamScore, 255, 255, 255 ); - - x = 20; - y = ( ScreenHeight - gHUD.m_iFontHeight ) - ( gHUD.m_iFontHeight / 2 ) - 75; - - switch ( iRedFlagStatus ) - { - case RED_FLAG_STOLE: - SPR_Set( m_hRedStolen, r, g, b ); - SPR_DrawHoles( 1, x, y, NULL ); - break; - case RED_FLAG_LOST: - SPR_Set( m_hRedLost, r, g, b ); - SPR_DrawHoles( 1, x, y, NULL ); - break; - case RED_FLAG_ATBASE: - SPR_Set( m_hRedAtBase, r, g, b ); - SPR_DrawHoles( 1, x, y, NULL ); - break; - } - - x = 50; - if ( iRedTeamScore < 10) - { - x += 3; - gHUD.DrawHudNumber( x, y + 4, DHN_DRAWZERO, iRedTeamScore, 255, 255, 255 ); - } - else if ( iBlueTeamScore >= 10 && iBlueTeamScore < 100 ) - gHUD.DrawHudNumber( x, y + 4, DHN_2DIGITS | DHN_DRAWZERO, iRedTeamScore, 255, 255, 255 ); - - x = 20; - y = ( ScreenHeight - gHUD.m_iFontHeight ) - ( gHUD.m_iFontHeight / 2 ) - 110; - - switch ( m_iRuneStat ) - { - case ITEM_RUNE1_FLAG: - SPR_Set( m_hRune1, r, g, b ); - SPR_Draw( 1, x, y, NULL ); - break; - - case ITEM_RUNE2_FLAG: - SPR_Set( m_hRune2, r, g, b ); - SPR_Draw( 1, x, y, NULL ); - break; - - case ITEM_RUNE3_FLAG: - SPR_Set( m_hRune3, r, g, b ); - SPR_Draw( 1, x, y, NULL ); - break; - - case ITEM_RUNE4_FLAG: - SPR_Set( m_hRune4, r, g, b ); - SPR_Draw( 1, x, y, NULL ); - break; - } - - return 1; -} - -int CHudFlagStatus::MsgFunc_FlagStat(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - iDrawStatus = READ_BYTE(); - iRedFlagStatus = READ_BYTE(); - iBlueFlagStatus = READ_BYTE(); - - iRedTeamScore = READ_BYTE(); - iBlueTeamScore = READ_BYTE(); - - return 1; -} - -int CHudFlagStatus::MsgFunc_RuneStat(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - m_iRuneStat = READ_BYTE(); - - return 1; -} - -int CHudFlagStatus::MsgFunc_FlagCarrier(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - int index = READ_BYTE(); - - bool bRedFlag = false; - bool bBlueFlag = false; - - g_PlayerExtraInfo[ index ].iHasFlag = READ_BYTE(); - - for ( int i = 1; i < MAX_PLAYERS + 1; i++ ) - { - if ( g_PlayerExtraInfo[ i ].iHasFlag ) - { - if ( g_PlayerExtraInfo[ i ].teamnumber == 1 ) - bRedFlag = true; - else if ( g_PlayerExtraInfo[ i ].teamnumber == 2 ) - bBlueFlag = true; - } - } - - if ( !bRedFlag ) - gViewPort->m_pScoreBoard->m_pImages[ 5 ]->setVisible( false ); - if ( !bBlueFlag ) - gViewPort->m_pScoreBoard->m_pImages[ 4 ]->setVisible( false ); - - return 1; -} - - -#endif \ No newline at end of file diff --git a/dmc/cl_dll/CTF_HudMessage.cpp b/dmc/cl_dll/CTF_HudMessage.cpp deleted file mode 100644 index c7d640f..0000000 --- a/dmc/cl_dll/CTF_HudMessage.cpp +++ /dev/null @@ -1,184 +0,0 @@ -#ifdef THREEWAVE - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "entity_types.h" -#include "usercmd.h" -#include "pm_defs.h" -#include "pm_materials.h" -#include "ref_params.h" -#include - - -#define MAX_BONUS 10 - -#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_HUD 9 -#define BLUE_FLAG_LOST_HUD 10 - - - -char *sBonusStrings[] = -{ - "", - "\\w stole the \\rRED\\w Flag!", - "\\w stole the \\bBLUE\\w Flag!", - "\\w captured the \\rRED\\w Flag", - "\\w captured the \\bBLUE\\w Flag", - "\\w returned the \\rRED\\w Flag", - "\\w returned the \\bBLUE\\w Flag", - "\\wThe \\rRED\\w Flag has Returned", - "\\wThe \\bBLUE\\w Flag has Returned", - "\\w lost the \\rRED\\w Flag!", - "\\w lost the \\bBLUE\\w Flag!", -}; - -DECLARE_MESSAGE(m_Bonus, Bonus) - -struct bonus_info_t -{ - int iSlot; - int iType; - bool bActive; - float flBonusTime; - char sPlayerName[64]; -}; - -bonus_info_t g_PlayerBonus[MAX_BONUS+1]; - -int CHudBonus::Init(void) -{ - HOOK_MESSAGE( Bonus ); - - m_iFlags |= HUD_ACTIVE; - - gHUD.AddHudElem(this); - - Reset(); - - return 1; -}; - -int CHudBonus::VidInit(void) -{ - return 1; -} - -void CHudBonus :: Reset( void ) -{ - m_iFlags |= HUD_ACTIVE; - - for ( int reset = 0; reset < MAX_BONUS; reset++) - { - g_PlayerBonus[ reset ].flBonusTime = 0.0; - g_PlayerBonus[ reset ].iSlot = 0; - g_PlayerBonus[ reset ].iType = 0; - g_PlayerBonus[ reset ].bActive = false; - m_bUsedSlot[ reset ] = false; - strcpy ( g_PlayerBonus[ reset ].sPlayerName, "" ); - } -} - -int CHudBonus ::Draw(float flTime ) -{ - for (int index = 1; index < MAX_BONUS + 1; index++) - { - //Just activated - if ( g_PlayerBonus[ index ].bActive && !g_PlayerBonus[ index ].flBonusTime ) - { - g_PlayerBonus[ index ].flBonusTime = flTime + 5.0; - - for ( int i = 1; i < MAX_BONUS + 1; i++ ) - { - if ( m_bUsedSlot[ i ] == false ) //found one thats not used - { - m_bUsedSlot[ i ] = true; //use it! - g_PlayerBonus[ index ].iSlot = i; - break; - } - } - } - - if ( g_PlayerBonus[ index ].flBonusTime > flTime ) - { - int YPos; - int iMod = gHUD.ReturnStringPixelLength( "\\w\\r\\w" ); - - YPos = ( ( ScreenHeight - gHUD.m_iFontHeight ) - ( gHUD.m_iFontHeight / 2 ) + 3 ) - ( 30 * g_PlayerBonus[ index ].iSlot ); - - int XPos = 75; - - char szText[256]; - - strcpy ( szText, g_PlayerBonus[ index ].sPlayerName ); - strcat ( szText, sBonusStrings[ g_PlayerBonus[ index ].iType ] ); - - if ( gHUD.m_FlagStat.iBlueTeamScore >= 10 ) - gHUD.DrawHudStringCTF( XPos + 20, YPos, 640, szText, 255, 255, 255 ); - else - gHUD.DrawHudStringCTF( XPos , YPos, 320, szText, 255, 255, 255 ); - - } - - if ( g_PlayerBonus[ index ].flBonusTime < flTime ) - { - g_PlayerBonus[ index ].bActive = false; - m_bUsedSlot[ g_PlayerBonus[ index ].iSlot ] = false; - g_PlayerBonus[ index ].iSlot = 0; - strcpy ( g_PlayerBonus[ index ].sPlayerName, "" ); - } - } - - return 1; -} - -int CHudBonus::MsgFunc_Bonus(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - for ( int index = 1; index < MAX_BONUS + 1; index++) - { - //Find wich one is not used - if ( g_PlayerBonus[ index ].bActive == false ) - break; //Not using this one?, then we shall use this. - } - - g_PlayerBonus[ index ].bActive = true; - g_PlayerBonus[ index ].flBonusTime = 0.0; - g_PlayerBonus[ index ].iType = READ_BYTE(); - strcpy ( g_PlayerBonus[ index ].sPlayerName, READ_STRING() ); - - switch ( g_PlayerBonus[ index ].iType ) - { - case RED_FLAG_STOLEN: - case BLUE_FLAG_STOLEN: - PlaySound( "ctf/flagtk.wav", 1 ); - break; - case RED_FLAG_CAPTURED: - case BLUE_FLAG_CAPTURED: - PlaySound( "ctf/flagcap.wav", 1 ); - break; - case RED_FLAG_RETURNED_PLAYER: - case BLUE_FLAG_RETURNED_PLAYER: - case RED_FLAG_RETURNED: - case BLUE_FLAG_RETURNED: - PlaySound( "ctf/flagret.wav", 1 ); - break; - } - - return 1; -} - -#endif \ No newline at end of file diff --git a/dmc/cl_dll/DMC_BSPFile.h b/dmc/cl_dll/DMC_BSPFile.h deleted file mode 100644 index a6bf4a6..0000000 --- a/dmc/cl_dll/DMC_BSPFile.h +++ /dev/null @@ -1,48 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( DMC_BSPFILE_H ) -#define DMC_BSPFILE_H -#ifdef _WIN32 -#pragma once -#endif - -// MINI-version of BSPFILE.H to support DeathMatch Classic's entity lump extraction stuff. - -#define BSPVERSION 30 - -typedef struct -{ - int fileofs, filelen; -} lump_t; - -#define LUMP_ENTITIES 0 -#define LUMP_PLANES 1 -#define LUMP_TEXTURES 2 -#define LUMP_VERTEXES 3 -#define LUMP_VISIBILITY 4 -#define LUMP_NODES 5 -#define LUMP_TEXINFO 6 -#define LUMP_FACES 7 -#define LUMP_LIGHTING 8 -#define LUMP_CLIPNODES 9 -#define LUMP_LEAFS 10 -#define LUMP_MARKSURFACES 11 -#define LUMP_EDGES 12 -#define LUMP_SURFEDGES 13 -#define LUMP_MODELS 14 - -#define HEADER_LUMPS 15 - -typedef struct -{ - int version; - lump_t lumps[HEADER_LUMPS]; -} dheader_t; - - -#endif // DMC_BSPFILE_H \ No newline at end of file diff --git a/dmc/cl_dll/DMC_Teleporters.cpp b/dmc/cl_dll/DMC_Teleporters.cpp deleted file mode 100644 index 9eee920..0000000 --- a/dmc/cl_dll/DMC_Teleporters.cpp +++ /dev/null @@ -1,520 +0,0 @@ -//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "extdll.h" -#include "entity_state.h" -#include "pm_defs.h" -#include "pm_shared.h" -#include "pm_movevars.h" -#include "hud_iface.h" -#include "com_model.h" -#include "event_api.h" -#include "com_weapons.h" -#include "event_flags.h" -#include "DMC_BSPFile.h" -#include "cl_util.h" - -#include "FileSystem.h" - -extern IFileSystem *g_pFileSystem; - -extern playermove_t *pmove; -extern int g_runfuncs; - -// Don't support more than MAX_TELE teleporters ( map still can load tho ) -#define MAX_TELES 256 - -extern Vector g_vecTeleMins[ MAX_TELES ]; -extern Vector g_vecTeleMaxs[ MAX_TELES ]; -extern int g_iTeleNum; -extern int g_iUser1; -extern bool g_bLoadedTeles; -vec3_t vecTempAngles; -bool bChangeAngles; - - -// We only care about two kinds of entities for now: Teleporters and their targets -// FIXME: After loading, store a pointer from teleporter to target instead of looking up all the time. -typedef enum -{ - // Entity is a teleporter - DMC_TELE = 0, - // Entity is a target - DMC_TARGET -} dmc_teletype_t; - -typedef struct -{ - // Type of entity - dmc_teletype_t type; - - // Classname - char classname[ 32 ]; - - // What this entity targets - char target[ 32 ]; - - // If entity is a target, the name tag it uses - char targetname[ 32 ]; - - // Orientation of the teleporter - float angles[3]; - - // Target origin - float origin[3]; - - // Bounding box of the teleporter - float absmin[3]; - float absmax[3]; - -} dmc_tele_t; - -// Teleporter/Target entity database -static dmc_tele_t s_teles[ MAX_TELES ]; -static int s_num_teles = 0; - -// We'll use this for playing the teleporting sounds locally. -static unsigned short s_usTeleport; - -/* -============================== -Dmc_SetKeyValue - -Fill in key/values fro the teleporter -============================== -*/ -void Dmc_SetKeyValue( dmc_tele_t *pTele, const char *key, const char *value ) -{ - float x, y, z; - - if ( !stricmp( key, "classname" ) ) - { - strcpy( pTele->classname, value ); - } - else if ( !stricmp( key, "target" ) ) - { - strcpy( pTele->target, value ); - } - else if ( !stricmp( key, "targetname" ) ) - { - strcpy( pTele->targetname, value ); - } - else if ( !stricmp( key, "angles" ) ) - { - if ( sscanf( value, "%f %f %f", &x, &y, &z ) == 3 ) - { - pTele->angles[ 0 ] = x ; - pTele->angles[ 1 ] = y; - pTele->angles[ 2 ] = z; - } - } - else if ( !stricmp( key, "origin" ) ) - { - if ( sscanf( value, "%f %f %f", &x, &y, &z ) == 3 ) - { - pTele->origin[ 0 ] = x; - pTele->origin[ 1 ] = y; - pTele->origin[ 2 ] = z; - } - } -} - -/* -============================== -Dmc_ParseTeleporter - -Evaluate Key/Value pairs for the entity -============================== -*/ -char *Dmc_ParseTeleporter( char *buffer, dmc_tele_t *pTele, int *error ) -{ - char key[256]; - char token[ 1024 ]; - int n; - - memset( pTele, 0, sizeof( *pTele ) ); - - while (1) - { - // Parse key - buffer = gEngfuncs.COM_ParseFile ( buffer, token ); - if ( token[0] == '}' ) - break; - - // Ran out of input buffer? - if ( !buffer ) - { - *error = 1; - break; - } - - // Store off the key - strcpy ( key, token ); - - // Fix heynames with trailing spaces - n = strlen( key ); - while (n && key[n-1] == ' ') - { - key[n-1] = 0; - n--; - } - - // Parse value - buffer = gEngfuncs.COM_ParseFile ( buffer, token ); - - // Ran out of buffer? - if (!buffer) - { - *error = 1; - break; - } - - // Hit the end instead of a value? - if ( token[0] == '}' ) - { - *error = 1; - break; - } - - if ( token[0] == '}' && token[1] == '(' ) - int k = 0; - - // Assign k/v pair - Dmc_SetKeyValue( pTele, key, token ); - } - - // Return what's left in the stream - return buffer; -} - -/* -============================== -Dmc_ProcessEnts - -Parse through entity lump looking for teleporters or targets -============================== -*/ -void Dmc_ProcessEnts( char *buffer ) -{ - char token[ 1024 ]; - dmc_tele_t *pTele = NULL; - int error = 0; - - // parse entities from entity lump of .bsp file - while ( 1 ) - { - // parse the opening brace - buffer = gEngfuncs.COM_ParseFile ( buffer, token ); - if (!buffer) - break; - - // Didn't find opening brace? - if ( token[0] != '{' ) - { - gEngfuncs.Con_Printf ("Dmc_ProcessEnts: found %s when expecting {\n", token ); - return; - } - - // Assume we're filling in this tele - pTele = &s_teles[ s_num_teles ]; - - // Fill in data - buffer = Dmc_ParseTeleporter( buffer, pTele, &error ); - - // Check for errors and abort if any - if ( error ) - { - gEngfuncs.Con_Printf ("Dmc_ProcessEnts: error parsing entities\n" ); - return; - } - - // Check classname - if ( stricmp( pTele->classname, "trigger_teleport" ) && stricmp( pTele->classname, "info_teleport_destination" ) ) - continue; - - // Set type based on classname - if ( !stricmp( pTele->classname, "trigger_teleport" ) ) - { - pTele->type = DMC_TELE; - } - else - { - pTele->type = DMC_TARGET; - } - - // If we got to here, we're using the entity - s_num_teles++; - - // No more room... - if ( s_num_teles >= MAX_TELES ) - break; - } -} - -/* -============================== -Dmc_LoadEntityLump - -Open the .bsp and read in the entity lump -============================== -*/ -char *Dmc_LoadEntityLump( const char *filename ) -{ - FileHandle_t fp; - int i; - dheader_t header; - int size; - lump_t *curLump; - char *buffer = NULL; - - fp = g_pFileSystem->Open( filename, "rb" ); - if ( !fp ) - return NULL; - - // Read in the .bsp header - if ( g_pFileSystem->Read(&header, sizeof(dheader_t), fp) != sizeof(dheader_t) ) - { - gEngfuncs.Con_Printf("Dmc_LoadEntityLump: Could not read BSP header for map [%s].\n", filename); - g_pFileSystem->Close(fp); - return NULL; - } - - // Check the version - i = header.version; - if ( i != 29 && i != 30) - { - g_pFileSystem->Close(fp); - gEngfuncs.Con_Printf("Dmc_LoadEntityLump: Map [%s] has incorrect BSP version (%i should be %i).\n", filename, i, BSPVERSION); - return NULL; - } - - // Get entity lump - curLump = &header.lumps[ LUMP_ENTITIES ]; - // and entity lump size - size = curLump->filelen; - - // Jump to it - g_pFileSystem->Seek( fp, curLump->fileofs, FILESYSTEM_SEEK_HEAD ); - - // Allocate sufficient memmory - buffer = (char *)malloc( size + 1 ); - if ( !buffer ) - { - g_pFileSystem->Close(fp); - gEngfuncs.Con_Printf("Dmc_LoadEntityLump: Couldn't allocate %i bytes\n", size + 1 ); - return NULL; - } - - // Read in the entity lump - g_pFileSystem->Read( buffer, size, fp ); - - // Terminate the string - buffer[ size ] = '\0'; - - if ( fp ) - { - g_pFileSystem->Close(fp); - } - - return buffer; -} - -/* -============================== -Dmc_LoadTeleporters - -Load in the .bsp file and process the entities -============================== -*/ -void Dmc_LoadTeleporters( const char *map ) -{ - char *buffer = NULL; - char filename[ 256 ]; - - sprintf( filename, "%s", map ); - - // TODO: Fix Slashes? - - // Reset count - s_num_teles = 0; - - // Load entity lump - buffer = Dmc_LoadEntityLump( filename ); - if ( !buffer ) - return; - - // Process buffer and extract teleporters/targets - Dmc_ProcessEnts( buffer ); - - // Discard buffer - free( buffer ); -} - -/* -============================== -Dmc_FindTarget - -Search entity list for target matching "name" -============================== -*/ -dmc_tele_t *Dmc_FindTarget( const char *name, int numtele, dmc_tele_t *pTeles ) -{ - int i; - dmc_tele_t *target; - - // Find the target - for ( i = 0; i < numtele; i++ ) - { - target = &pTeles[ i ]; - - if ( !target ) - continue; - - if ( stricmp( target->targetname, name ) ) - continue; - - return target; - } - - return NULL; -} - -/* -============================== -Dmc_TeleporterTouched - -Imparts the desired velocity to the player -after touching a teleporter. -============================== -*/ -void Dmc_TeleporterTouched( int numtele, dmc_tele_t *pTeles, dmc_tele_t *pTele, struct local_state_s *player ) -{ - int i; - dmc_tele_t *target; - pmtrace_t tr; - float flGravity = pmove->movevars->gravity; - - vec3_t forward, up, right; - - float zero[ 3 ] = { 0.0, 0.0, 0.0 }; - - // Find the target - target = Dmc_FindTarget( pTele->target, numtele, pTeles ); - - for ( i = 0; i < 3; i++ ) - player->playerstate.origin[ i ] = target->origin[ i ]; - - player->playerstate.origin[ 2 ] += 27; - - AngleVectors( target->angles, forward, right, up ); - player->client.velocity = forward * 300; - - // Play sound if appropriate - if ( s_usTeleport && g_runfuncs ) - { - //Adrian - This is a little hack to make the player face - //the destination angles as soon as we step out. - //Check view.cpp for the rest. - for ( i = 0; i < 3; i++ ) - vecTempAngles[ i ] = target->angles[ i ]; - - bChangeAngles = true; - - gEngfuncs.pfnPlaybackEvent( FEV_NOTHOST, NULL, s_usTeleport, 0.0, target->origin, zero, 0.0, 0.0, 0, 0, 0, 0 ); - } -} - -/* -============================== -Dmc_TouchTeleporters - -See if player is touching a teleporter ( not that kind of touching! ). -============================== -*/ -void Dmc_TouchTeleporters ( struct local_state_s *player, dmc_tele_t *pTeles, int numtele ) -{ - int i, j; - dmc_tele_t *pTele; - float absmin[3], absmax[3]; - float pmins[ 3 ] = { 13, 13, 24 }; - float pmaxs[ 3 ] = { 13, 13, 32 }; - vec3_t LengthVector; - int iTeleNum = 0; - - - // Determine player's bbox - for ( j = 0; j < 3; j++ ) - { - absmin[ j ] = player->playerstate.origin[ j ] - pmins[ j ]; - absmax[ j ] = player->playerstate.origin[ j ] + pmaxs[ j ]; - } - - for ( i = 0; i < numtele; i++ ) - { - pTele = &pTeles[ i ]; - if ( !pTele ) - continue; - - if ( pTele->type != DMC_TELE ) - continue; - - //Adrian - Load all the teleporter Mins and Max size. - //This comes via an event when the player connects. - if ( !g_bLoadedTeles ) - { - for ( int j = 0; j < 3; j++ ) - { - pTele->absmin[ j ] = g_vecTeleMins[ iTeleNum ][ j ] - 1.0; - pTele->absmax[ j ] = g_vecTeleMaxs[ iTeleNum ][ j ] + 1.0; - } - iTeleNum++; - - //Done going thru all the teleporters - if ( iTeleNum == g_iTeleNum ) - g_bLoadedTeles = true; - } - - if ( absmin[0] > pTele->absmax[0] - || absmin[1] > pTele->absmax[1] - || absmin[2] > pTele->absmax[2] - || absmax[0] < pTele->absmin[0] - || absmax[1] < pTele->absmin[1] - || absmax[2] < pTele->absmin[2] ) - continue; - - Dmc_TeleporterTouched( numtele, pTeles, pTele, player ); - - break; - } -} - -/* -============================== -Dmc_CheckTeleporters - -Load data if needed, otherwise just run checks on player's final position to see if teleporter needs -to impart velocity on the player. -============================== -*/ -void Dmc_CheckTeleporters( struct local_state_s *from, struct local_state_s *to ) -{ - static char current_level[ 128 ]; - - // See if we've changed to a new map - if ( stricmp( current_level, gEngfuncs.pfnGetLevelName() ) ) - { - strcpy( current_level, gEngfuncs.pfnGetLevelName() ); - Dmc_LoadTeleporters( current_level ); - - // Grab sound event - s_usTeleport = gEngfuncs.pfnPrecacheEvent( 1, "events/teleport.sc" ); - } - - // Run test, only if we're not a spectator - if ( g_iUser1 == OBS_NONE ) - Dmc_TouchTeleporters( to, s_teles, s_num_teles ); -} diff --git a/dmc/cl_dll/DMC_Teleporters.h b/dmc/cl_dll/DMC_Teleporters.h deleted file mode 100644 index e14a3c7..0000000 --- a/dmc/cl_dll/DMC_Teleporters.h +++ /dev/null @@ -1,16 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( DMC_TELEPORTERS_H ) -#define DMC_TELEPORTERS_H -#ifdef _WIN32 -#pragma once -#endif - -void Dmc_CheckTeleporters( struct local_state_s *from, struct local_state_s *to ); - -#endif // DMC_TELEPORTERS_H \ No newline at end of file diff --git a/dmc/cl_dll/Exports.h b/dmc/cl_dll/Exports.h deleted file mode 100644 index e47dcc7..0000000 --- a/dmc/cl_dll/Exports.h +++ /dev/null @@ -1,112 +0,0 @@ -#include "Platform.h" - -extern "C" -{ - // From hl_weapons - void DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ); - - // From cdll_int - int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ); - int DLLEXPORT HUD_VidInit( void ); - void DLLEXPORT HUD_Init( void ); - int DLLEXPORT HUD_Redraw( float flTime, int intermission ); - int DLLEXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime ); - void DLLEXPORT HUD_Reset ( void ); - void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ); - void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ); - char DLLEXPORT HUD_PlayerMoveTexture( char *name ); - int DLLEXPORT HUD_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); - int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ); - void DLLEXPORT HUD_Frame( double time ); - void DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking); - void DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf ); - void DLLEXPORT HUD_ChatInputPosition( int *x, int *y ); - - // From demo - void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer ); - - // From entity - int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void DLLEXPORT HUD_CreateEntities( void ); - void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); - void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); - void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); - void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd ); - void DLLEXPORT HUD_TempEntUpdate( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( struct cl_entity_s *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) ); - struct cl_entity_s DLLEXPORT *HUD_GetUserEntity( int index ); - - // From in_camera - void DLLEXPORT CAM_Think( void ); - int DLLEXPORT CL_IsThirdPerson( void ); - void DLLEXPORT CL_CameraOffset( float *ofs ); - - // From input - struct kbutton_s DLLEXPORT *KB_Find( const char *name ); - void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ); - void DLLEXPORT HUD_Shutdown( void ); - int DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding ); - - // From inputw32 - void DLLEXPORT IN_ActivateMouse( void ); - void DLLEXPORT IN_DeactivateMouse( void ); - void DLLEXPORT IN_MouseEvent (int mstate); - void DLLEXPORT IN_Accumulate (void); - void DLLEXPORT IN_ClearStates (void); - - // From tri - void DLLEXPORT HUD_DrawNormalTriangles( void ); - void DLLEXPORT HUD_DrawTransparentTriangles( void ); - - // From view - void DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams ); - - // From GameStudioModelRenderer - int DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio ); -} - -/* -extern cldll_func_dst_t *g_pcldstAddrs; - -// Macros for the client receiving calls from the engine -#define RecClInitialize(a, b) (g_pcldstAddrs->pInitFunc(&a, &b)) -#define RecClHudInit() (g_pcldstAddrs->pHudInitFunc()) -#define RecClHudVidInit() (g_pcldstAddrs->pHudVidInitFunc()) -#define RecClHudRedraw(a, b) (g_pcldstAddrs->pHudRedrawFunc(&a, &b)) -#define RecClHudUpdateClientData(a, b) (g_pcldstAddrs->pHudUpdateClientDataFunc(&a, &b)) -#define RecClHudReset() (g_pcldstAddrs->pHudResetFunc()) -#define RecClClientMove(a, b) (g_pcldstAddrs->pClientMove(&a, &b)) -#define RecClClientMoveInit(a) (g_pcldstAddrs->pClientMoveInit(&a)) -#define RecClClientTextureType(a) (g_pcldstAddrs->pClientTextureType(&a)) -#define RecClIN_ActivateMouse() (g_pcldstAddrs->pIN_ActivateMouse()) -#define RecClIN_DeactivateMouse() (g_pcldstAddrs->pIN_DeactivateMouse()) -#define RecClIN_MouseEvent(a) (g_pcldstAddrs->pIN_MouseEvent(&a)) -#define RecClIN_ClearStates() (g_pcldstAddrs->pIN_ClearStates()) -#define RecClIN_Accumulate() (g_pcldstAddrs->pIN_Accumulate()) -#define RecClCL_CreateMove(a, b, c) (g_pcldstAddrs->pCL_CreateMove(&a, &b, &c)) -#define RecClCL_IsThirdPerson() (g_pcldstAddrs->pCL_IsThirdPerson()) -#define RecClCL_GetCameraOffsets(a) (g_pcldstAddrs->pCL_GetCameraOffsets(&a)) -#define RecClFindKey(a) (g_pcldstAddrs->pFindKey(&a)) -#define RecClCamThink() (g_pcldstAddrs->pCamThink()) -#define RecClCalcRefdef(a) (g_pcldstAddrs->pCalcRefdef(&a)) -#define RecClAddEntity(a, b, c) (g_pcldstAddrs->pAddEntity(&a, &b, &c)) -#define RecClCreateEntities() (g_pcldstAddrs->pCreateEntities()) -#define RecClDrawNormalTriangles() (g_pcldstAddrs->pDrawNormalTriangles()) -#define RecClDrawTransparentTriangles() (g_pcldstAddrs->pDrawTransparentTriangles()) -#define RecClStudioEvent(a, b) (g_pcldstAddrs->pStudioEvent(&a, &b)) -#define RecClPostRunCmd(a, b, c, d, e, f) (g_pcldstAddrs->pPostRunCmd(&a, &b, &c, &d, &e, &f)) -#define RecClShutdown() (g_pcldstAddrs->pShutdown()) -#define RecClTxferLocalOverrides(a, b) (g_pcldstAddrs->pTxferLocalOverrides(&a, &b)) -#define RecClProcessPlayerState(a, b) (g_pcldstAddrs->pProcessPlayerState(&a, &b)) -#define RecClTxferPredictionData(a, b, c, d, e, f) (g_pcldstAddrs->pTxferPredictionData(&a, &b, &c, &d, &e, &f)) -#define RecClReadDemoBuffer(a, b) (g_pcldstAddrs->pReadDemoBuffer(&a, &b)) -#define RecClConnectionlessPacket(a, b, c, d) (g_pcldstAddrs->pConnectionlessPacket(&a, &b, &c, &d)) -#define RecClGetHullBounds(a, b, c) (g_pcldstAddrs->pGetHullBounds(&a, &b, &c)) -#define RecClHudFrame(a) (g_pcldstAddrs->pHudFrame(&a)) -#define RecClKeyEvent(a, b, c) (g_pcldstAddrs->pKeyEvent(&a, &b, &c)) -#define RecClTempEntUpdate(a, b, c, d, e, f, g) (g_pcldstAddrs->pTempEntUpdate(&a, &b, &c, &d, &e, &f, &g)) -#define RecClGetUserEntity(a) (g_pcldstAddrs->pGetUserEntity(&a)) -#define RecClVoiceStatus(a, b) (g_pcldstAddrs->pVoiceStatus(&a, &b)) -#define RecClDirectorMessage(a, b) (g_pcldstAddrs->pDirectorMessage(&a, &b)) -#define RecClStudioInterface(a, b, c) (g_pcldstAddrs->pStudioInterface(&a, &b, &c)) -#define RecClChatInputPosition(a, b) (g_pcldstAddrs->pChatInputPosition(&a, &b)) -*/ \ No newline at end of file diff --git a/dmc/cl_dll/GameStudioModelRenderer.cpp b/dmc/cl_dll/GameStudioModelRenderer.cpp deleted file mode 100644 index 1d9d307..0000000 --- a/dmc/cl_dll/GameStudioModelRenderer.cpp +++ /dev/null @@ -1,119 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "com_model.h" -#include "studio.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "dlight.h" -#include "triangleapi.h" - -#include -#include -#include -#include - -#include "studio_util.h" -#include "r_studioint.h" - -#include "StudioModelRenderer.h" -#include "GameStudioModelRenderer.h" - -// -// Override the StudioModelRender virtual member functions here to implement custom bone -// setup, blending, etc. -// - -// Global engine <-> studio model rendering code interface -extern engine_studio_api_t IEngineStudio; - -// The renderer object, created on the stack. -CGameStudioModelRenderer g_StudioRenderer; - -/* -==================== -CGameStudioModelRenderer - -==================== -*/ -CGameStudioModelRenderer::CGameStudioModelRenderer( void ) -{ -} - -//////////////////////////////////// -// Hooks to class implementation -//////////////////////////////////// - -/* -==================== -R_StudioDrawPlayer - -==================== -*/ -int R_StudioDrawPlayer( int flags, entity_state_t *pplayer ) -{ - return g_StudioRenderer.StudioDrawPlayer( flags, pplayer ); -} - -/* -==================== -R_StudioDrawModel - -==================== -*/ -int R_StudioDrawModel( int flags ) -{ - return g_StudioRenderer.StudioDrawModel( flags ); -} - -/* -==================== -R_StudioInit - -==================== -*/ -void R_StudioInit( void ) -{ - g_StudioRenderer.Init(); -} - -// The simple drawing interface we'll pass back to the engine -r_studio_interface_t studio = -{ - STUDIO_INTERFACE_VERSION, - R_StudioDrawModel, - R_StudioDrawPlayer, -}; - -/* -==================== -HUD_GetStudioModelInterface - -Export this function for the engine to use the studio renderer class to render objects. -==================== -*/ -extern "C" int DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio ) -{ - if ( version != STUDIO_INTERFACE_VERSION ) - return 0; - - // Point the engine to our callbacks - *ppinterface = &studio; - - // Copy in engine helper functions - memcpy( &IEngineStudio, pstudio, sizeof( IEngineStudio ) ); - - // Initialize local variables, etc. - R_StudioInit(); - - // Success - return 1; -} diff --git a/dmc/cl_dll/GameStudioModelRenderer.h b/dmc/cl_dll/GameStudioModelRenderer.h deleted file mode 100644 index 7d06f70..0000000 --- a/dmc/cl_dll/GameStudioModelRenderer.h +++ /dev/null @@ -1,26 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( GAMESTUDIOMODELRENDERER_H ) -#define GAMESTUDIOMODELRENDERER_H -#if defined( _WIN32 ) -#pragma once -#endif - -/* -==================== -CGameStudioModelRenderer - -==================== -*/ -class CGameStudioModelRenderer : public CStudioModelRenderer -{ -public: - CGameStudioModelRenderer( void ); -}; - -#endif // GAMESTUDIOMODELRENDERER_H \ No newline at end of file diff --git a/dmc/cl_dll/MOTD.cpp b/dmc/cl_dll/MOTD.cpp deleted file mode 100644 index e0e3490..0000000 --- a/dmc/cl_dll/MOTD.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// MOTD.cpp -// -// for displaying a server-sent message of the day -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -DECLARE_MESSAGE( m_MOTD, MOTD ); - -int CHudMOTD::MOTD_DISPLAY_TIME; - -int CHudMOTD :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( MOTD ); - - CVAR_CREATE( "motd_display_time", "15", 0 ); - - m_iFlags &= ~HUD_ACTIVE; // start out inactive - m_szMOTD[0] = 0; - - return 1; -} - -int CHudMOTD :: VidInit( void ) -{ - // Load sprites here - - return 1; -} - -void CHudMOTD :: Reset( void ) -{ - m_iFlags &= ~HUD_ACTIVE; // start out inactive - m_szMOTD[0] = 0; - m_iLines = 0; - m_flActiveRemaining = 0; -} - -#define LINE_HEIGHT 13 - -int CHudMOTD :: Draw( float fTime ) -{ - static float sfLastTime; - float fElapsed; - - // Draw MOTD line-by-line - if ( m_flActiveRemaining <= 0.0 ) - { - // finished with MOTD, disable it - m_szMOTD[0] = 0; - m_iLines = 0; - m_iFlags &= ~HUD_ACTIVE; - m_flActiveRemaining = 0.0; - return 1; - } - - fElapsed = gHUD.m_flTime - sfLastTime; - - // Don't let time go negative ( level transition? ) - fElapsed = V_max( 0.0, fElapsed ); - // Don't let time go hugely positive ( first connection to active server ? ) - fElapsed = V_min( 1.0, fElapsed ); - - // Remember last timestamp - sfLastTime = gHUD.m_flTime; - - // Remove a bit of time - m_flActiveRemaining -= fElapsed; - - // find the top of where the MOTD should be drawn, so the whole thing is centered in the screen - int ypos = V_max(((ScreenHeight - (m_iLines * LINE_HEIGHT)) / 2) - 40, 30 ); // shift it up slightly - char *ch = m_szMOTD; - while ( *ch ) - { - int line_length = 0; // count the length of the current line - for ( char *next_line = ch; *next_line != '\n' && *next_line != 0; next_line++ ) - line_length += gHUD.m_scrinfo.charWidths[ *next_line ]; - char *top = next_line; - if ( *top == '\n' ) - *top = 0; - else - top = NULL; - - // find where to start drawing the line - int xpos = (ScreenWidth - line_length) / 2; - - gHUD.DrawHudString( xpos, ypos, ScreenWidth, ch, 255, 180, 0 ); - - ypos += LINE_HEIGHT; - - if ( top ) // restore - *top = '\n'; - ch = next_line; - if ( *ch == '\n' ) - ch++; - - if ( ypos > (ScreenHeight - 20) ) - break; // don't let it draw too low - } - - return 1; -} - -int CHudMOTD :: MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf ) -{ - if ( m_iFlags & HUD_ACTIVE ) - { - Reset(); // clear the current MOTD in prep for this one - } - - BEGIN_READ( pbuf, iSize ); - - int is_finished = READ_BYTE(); - strcat( m_szMOTD, READ_STRING() ); - - if ( is_finished ) - { - m_iFlags |= HUD_ACTIVE; - - MOTD_DISPLAY_TIME = V_max( 10, CVAR_GET_FLOAT( "motd_display_time" ) ); - - m_flActiveRemaining = MOTD_DISPLAY_TIME; - - for ( char *sz = m_szMOTD; *sz != 0; sz++ ) // count the number of lines in the MOTD - { - if ( *sz == '\n' ) - m_iLines++; - } - } - - return 1; -} - diff --git a/dmc/cl_dll/StudioModelRenderer.cpp b/dmc/cl_dll/StudioModelRenderer.cpp deleted file mode 100644 index 6095566..0000000 --- a/dmc/cl_dll/StudioModelRenderer.cpp +++ /dev/null @@ -1,1723 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// studio_model.cpp -// routines for setting up to draw 3DStudio models - -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "com_model.h" -#include "studio.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "dlight.h" -#include "triangleapi.h" - -#include -#include -#include -#include - -#include "studio_util.h" -#include "r_studioint.h" - -#include "StudioModelRenderer.h" -#include "GameStudioModelRenderer.h" - -// Global engine <-> studio model rendering code interface -engine_studio_api_t IEngineStudio; - -///////////////////// -// Implementation of CStudioModelRenderer.h - -/* -==================== -Init - -==================== -*/ -void CStudioModelRenderer::Init( void ) -{ - // Set up some variables shared with engine - m_pCvarHiModels = IEngineStudio.GetCvar( "cl_himodels" ); - m_pCvarDeveloper = IEngineStudio.GetCvar( "developer" ); - m_pCvarDrawEntities = IEngineStudio.GetCvar( "r_drawentities" ); - - m_pChromeSprite = IEngineStudio.GetChromeSprite(); - - IEngineStudio.GetModelCounters( &m_pStudioModelCount, &m_pModelsDrawn ); - - // Get pointers to engine data structures - m_pbonetransform = (float (*)[MAXSTUDIOBONES][3][4])IEngineStudio.StudioGetBoneTransform(); - m_plighttransform = (float (*)[MAXSTUDIOBONES][3][4])IEngineStudio.StudioGetLightTransform(); - m_paliastransform = (float (*)[3][4])IEngineStudio.StudioGetAliasTransform(); - m_protationmatrix = (float (*)[3][4])IEngineStudio.StudioGetRotationMatrix(); -} - -/* -==================== -CStudioModelRenderer - -==================== -*/ -CStudioModelRenderer::CStudioModelRenderer( void ) -{ - m_fDoInterp = 1; - m_fGaitEstimation = 1; - m_pCurrentEntity = NULL; - m_pCvarHiModels = NULL; - m_pCvarDeveloper = NULL; - m_pCvarDrawEntities = NULL; - m_pChromeSprite = NULL; - m_pStudioModelCount = NULL; - m_pModelsDrawn = NULL; - m_protationmatrix = NULL; - m_paliastransform = NULL; - m_pbonetransform = NULL; - m_plighttransform = NULL; - m_pStudioHeader = NULL; - m_pBodyPart = NULL; - m_pSubModel = NULL; - m_pPlayerInfo = NULL; - m_pRenderModel = NULL; -} - -/* -==================== -~CStudioModelRenderer - -==================== -*/ -CStudioModelRenderer::~CStudioModelRenderer( void ) -{ -} - -/* -==================== -StudioCalcBoneAdj - -==================== -*/ -void CStudioModelRenderer::StudioCalcBoneAdj( float dadt, float *adj, const byte *pcontroller1, const byte *pcontroller2, byte mouthopen ) -{ - int i, j; - float value; - mstudiobonecontroller_t *pbonecontroller; - - pbonecontroller = (mstudiobonecontroller_t *)((byte *)m_pStudioHeader + m_pStudioHeader->bonecontrollerindex); - - for (j = 0; j < m_pStudioHeader->numbonecontrollers; j++) - { - i = pbonecontroller[j].index; - if (i <= 3) - { - // check for 360% wrapping - if (pbonecontroller[j].type & STUDIO_RLOOP) - { - if (abs(pcontroller1[i] - pcontroller2[i]) > 128) - { - int a, b; - a = (pcontroller1[j] + 128) % 256; - b = (pcontroller2[j] + 128) % 256; - value = ((a * dadt) + (b * (1 - dadt)) - 128) * (360.0/256.0) + pbonecontroller[j].start; - } - else - { - value = ((pcontroller1[i] * dadt + (pcontroller2[i]) * (1.0 - dadt))) * (360.0/256.0) + pbonecontroller[j].start; - } - } - else - { - value = (pcontroller1[i] * dadt + pcontroller2[i] * (1.0 - dadt)) / 255.0; - if (value < 0) value = 0; - if (value > 1.0) value = 1.0; - value = (1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end; - } - // Con_DPrintf( "%d %d %f : %f\n", m_pCurrentEntity->curstate.controller[j], m_pCurrentEntity->latched.prevcontroller[j], value, dadt ); - } - else - { - value = mouthopen / 64.0; - if (value > 1.0) value = 1.0; - value = (1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end; - // Con_DPrintf("%d %f\n", mouthopen, value ); - } - switch(pbonecontroller[j].type & STUDIO_TYPES) - { - case STUDIO_XR: - case STUDIO_YR: - case STUDIO_ZR: - adj[j] = value * (M_PI / 180.0); - break; - case STUDIO_X: - case STUDIO_Y: - case STUDIO_Z: - adj[j] = value; - break; - } - } -} - - -/* -==================== -StudioCalcBoneQuaterion - -==================== -*/ -void CStudioModelRenderer::StudioCalcBoneQuaterion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *q ) -{ - int j, k; - vec4_t q1, q2; - vec3_t angle1, angle2; - mstudioanimvalue_t *panimvalue; - - for (j = 0; j < 3; j++) - { - if (panim->offset[j+3] == 0) - { - angle2[j] = angle1[j] = pbone->value[j+3]; // default; - } - else - { - panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]); - k = frame; - // DEBUG - if (panimvalue->num.total < panimvalue->num.valid) - k = 0; - while (panimvalue->num.total <= k) - { - k -= panimvalue->num.total; - panimvalue += panimvalue->num.valid + 1; - // DEBUG - if (panimvalue->num.total < panimvalue->num.valid) - k = 0; - } - // Bah, missing blend! - if (panimvalue->num.valid > k) - { - angle1[j] = panimvalue[k+1].value; - - if (panimvalue->num.valid > k + 1) - { - angle2[j] = panimvalue[k+2].value; - } - else - { - if (panimvalue->num.total > k + 1) - angle2[j] = angle1[j]; - else - angle2[j] = panimvalue[panimvalue->num.valid+2].value; - } - } - else - { - angle1[j] = panimvalue[panimvalue->num.valid].value; - if (panimvalue->num.total > k + 1) - { - angle2[j] = angle1[j]; - } - else - { - angle2[j] = panimvalue[panimvalue->num.valid + 2].value; - } - } - angle1[j] = pbone->value[j+3] + angle1[j] * pbone->scale[j+3]; - angle2[j] = pbone->value[j+3] + angle2[j] * pbone->scale[j+3]; - } - - if (pbone->bonecontroller[j+3] != -1) - { - angle1[j] += adj[pbone->bonecontroller[j+3]]; - angle2[j] += adj[pbone->bonecontroller[j+3]]; - } - } - - if (!VectorCompare( angle1, angle2 )) - { - AngleQuaternion( angle1, q1 ); - AngleQuaternion( angle2, q2 ); - QuaternionSlerp( q1, q2, s, q ); - } - else - { - AngleQuaternion( angle1, q ); - } -} - -/* -==================== -StudioCalcBonePosition - -==================== -*/ -void CStudioModelRenderer::StudioCalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *pos ) -{ - int j, k; - mstudioanimvalue_t *panimvalue; - - for (j = 0; j < 3; j++) - { - pos[j] = pbone->value[j]; // default; - if (panim->offset[j] != 0) - { - panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]); - /* - if (i == 0 && j == 0) - Con_DPrintf("%d %d:%d %f\n", frame, panimvalue->num.valid, panimvalue->num.total, s ); - */ - - k = frame; - // DEBUG - if (panimvalue->num.total < panimvalue->num.valid) - k = 0; - // find span of values that includes the frame we want - while (panimvalue->num.total <= k) - { - k -= panimvalue->num.total; - panimvalue += panimvalue->num.valid + 1; - // DEBUG - if (panimvalue->num.total < panimvalue->num.valid) - k = 0; - } - // if we're inside the span - if (panimvalue->num.valid > k) - { - // and there's more data in the span - if (panimvalue->num.valid > k + 1) - { - pos[j] += (panimvalue[k+1].value * (1.0 - s) + s * panimvalue[k+2].value) * pbone->scale[j]; - } - else - { - pos[j] += panimvalue[k+1].value * pbone->scale[j]; - } - } - else - { - // are we at the end of the repeating values section and there's another section with data? - if (panimvalue->num.total <= k + 1) - { - pos[j] += (panimvalue[panimvalue->num.valid].value * (1.0 - s) + s * panimvalue[panimvalue->num.valid + 2].value) * pbone->scale[j]; - } - else - { - pos[j] += panimvalue[panimvalue->num.valid].value * pbone->scale[j]; - } - } - } - if ( pbone->bonecontroller[j] != -1 && adj ) - { - pos[j] += adj[pbone->bonecontroller[j]]; - } - } -} - -/* -==================== -StudioSlerpBones - -==================== -*/ -void CStudioModelRenderer::StudioSlerpBones( vec4_t q1[], float pos1[][3], vec4_t q2[], float pos2[][3], float s ) -{ - int i; - vec4_t q3; - float s1; - - if (s < 0) s = 0; - else if (s > 1.0) s = 1.0; - - s1 = 1.0 - s; - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - QuaternionSlerp( q1[i], q2[i], s, q3 ); - q1[i][0] = q3[0]; - q1[i][1] = q3[1]; - q1[i][2] = q3[2]; - q1[i][3] = q3[3]; - pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s; - pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s; - pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s; - } -} - -/* -==================== -StudioGetAnim - -==================== -*/ -mstudioanim_t *CStudioModelRenderer::StudioGetAnim( model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc ) -{ - mstudioseqgroup_t *pseqgroup; - cache_user_t *paSequences; - - pseqgroup = (mstudioseqgroup_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqgroupindex) + pseqdesc->seqgroup; - - if (pseqdesc->seqgroup == 0) - { - return (mstudioanim_t *)((byte *)m_pStudioHeader + pseqdesc->animindex); - } - - paSequences = (cache_user_t *)m_pSubModel->submodels; - - if (paSequences == NULL) - { - paSequences = (cache_user_t *)IEngineStudio.Mem_Calloc( 16, sizeof( cache_user_t ) ); // UNDONE: leak! - m_pSubModel->submodels = (dmodel_t *)paSequences; - } - - if (!IEngineStudio.Cache_Check( (struct cache_user_s *)&(paSequences[pseqdesc->seqgroup]))) - { - gEngfuncs.Con_DPrintf("loading %s\n", pseqgroup->name ); - IEngineStudio.LoadCacheFile( pseqgroup->name, (struct cache_user_s *)&paSequences[pseqdesc->seqgroup] ); - } - return (mstudioanim_t *)((byte *)paSequences[pseqdesc->seqgroup].data + pseqdesc->animindex); -} - -/* -==================== -StudioPlayerBlend - -==================== -*/ -void CStudioModelRenderer::StudioPlayerBlend( mstudioseqdesc_t *pseqdesc, int *pBlend, float *pPitch ) -{ - // calc up/down pointing - *pBlend = (*pPitch * 3); - if (*pBlend < pseqdesc->blendstart[0]) - { - *pPitch -= pseqdesc->blendstart[0] / 3.0; - *pBlend = 0; - } - else if (*pBlend > pseqdesc->blendend[0]) - { - *pPitch -= pseqdesc->blendend[0] / 3.0; - *pBlend = 255; - } - else - { - if (pseqdesc->blendend[0] - pseqdesc->blendstart[0] < 0.1) // catch qc error - *pBlend = 127; - else - *pBlend = 255 * (*pBlend - pseqdesc->blendstart[0]) / (pseqdesc->blendend[0] - pseqdesc->blendstart[0]); - *pPitch = 0; - } -} - -/* -==================== -StudioSetUpTransform - -==================== -*/ -void CStudioModelRenderer::StudioSetUpTransform (int trivial_accept) -{ - int i; - vec3_t angles; - vec3_t modelpos; - - - VectorCopy( m_pCurrentEntity->origin, modelpos ); - -// TODO: should really be stored with the entity instead of being reconstructed -// TODO: should use a look-up table -// TODO: could cache lazily, stored in the entity - angles[ROLL] = m_pCurrentEntity->curstate.angles[ROLL]; - angles[PITCH] = m_pCurrentEntity->curstate.angles[PITCH]; - angles[YAW] = m_pCurrentEntity->curstate.angles[YAW]; - - //Adrian - Have the model rotate ( weapon world models, powerups and armor. ) - //Yeah, we're too lazy to animate them!. - if ( strstr( m_pCurrentEntity->model->name, "g_" ) || strstr( m_pCurrentEntity->model->name, "pow_" ) || strstr( m_pCurrentEntity->model->name, "armour" ) ) - { - float timemod; - - timemod = fmod( gEngfuncs.GetClientTime(), 2.0f ); - - m_pCurrentEntity->angles[0] = 0; - m_pCurrentEntity->angles[YAW] = timemod * 180.0 - 90.0; - m_pCurrentEntity->angles[2] = 0; - - VectorCopy( m_pCurrentEntity->angles, m_pCurrentEntity->curstate.angles ); - } - - //Con_DPrintf("Angles %4.2f prev %4.2f for %i\n", angles[PITCH], m_pCurrentEntity->index); - //Con_DPrintf("movetype %d %d\n", m_pCurrentEntity->movetype, m_pCurrentEntity->aiment ); - if (m_pCurrentEntity->curstate.movetype == MOVETYPE_STEP) - { - float f = 0; - float d; - - // don't do it if the goalstarttime hasn't updated in a while. - - // NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit - // was increased to 1.0 s., which is 2x the max lag we are accounting for. - - if ( ( m_clTime < m_pCurrentEntity->curstate.animtime + 1.0f ) && - ( m_pCurrentEntity->curstate.animtime != m_pCurrentEntity->latched.prevanimtime ) ) - { - f = (m_clTime - m_pCurrentEntity->curstate.animtime) / (m_pCurrentEntity->curstate.animtime - m_pCurrentEntity->latched.prevanimtime); - //Con_DPrintf("%4.2f %.2f %.2f\n", f, m_pCurrentEntity->curstate.animtime, m_clTime); - } - - if (m_fDoInterp) - { - // ugly hack to interpolate angle, position. current is reached 0.1 seconds after being set - f = f - 1.0; - } - else - { - f = 0; - } - - for (i = 0; i < 3; i++) - { - modelpos[i] += (m_pCurrentEntity->origin[i] - m_pCurrentEntity->latched.prevorigin[i]) * f; - } - - // NOTE: Because multiplayer lag can be relatively large, we don't want to cap - // f at 1.5 anymore. - //if (f > -1.0 && f < 1.5) {} - -// gEngfuncs.Con_DPrintf("%.0f %.0f\n",m_pCurrentEntity->angles[0][YAW], m_pCurrentEntity->angles[1][YAW] ); - for (i = 0; i < 3; i++) - { - float ang1, ang2; - - ang1 = m_pCurrentEntity->angles[i]; - ang2 = m_pCurrentEntity->latched.prevangles[i]; - - d = ang1 - ang2; - if (d > 180) - { - d -= 360; - } - else if (d < -180) - { - d += 360; - } - - angles[i] += d * f; - } - //Con_DPrintf("%.3f \n", f ); - } - else if ( m_pCurrentEntity->curstate.movetype != MOVETYPE_NONE ) - { - VectorCopy( m_pCurrentEntity->angles, angles ); - } - - //Con_DPrintf("%.0f %0.f %0.f\n", modelpos[0], modelpos[1], modelpos[2] ); -// gEngfuncs.Con_DPrintf("%.0f %0.f %0.f\n", angles[0], angles[1], angles[2] ); - - - angles[PITCH] = -angles[PITCH]; - AngleMatrix (angles, (*m_protationmatrix)); - - if ( !IEngineStudio.IsHardware() ) - { - static float viewmatrix[3][4]; - - VectorCopy (m_vRight, viewmatrix[0]); - VectorCopy (m_vUp, viewmatrix[1]); - VectorInverse (viewmatrix[1]); - VectorCopy (m_vNormal, viewmatrix[2]); - - (*m_protationmatrix)[0][3] = modelpos[0] - m_vRenderOrigin[0]; - (*m_protationmatrix)[1][3] = modelpos[1] - m_vRenderOrigin[1]; - (*m_protationmatrix)[2][3] = modelpos[2] - m_vRenderOrigin[2]; - - ConcatTransforms (viewmatrix, (*m_protationmatrix), (*m_paliastransform)); - - // do the scaling up of x and y to screen coordinates as part of the transform - // for the unclipped case (it would mess up clipping in the clipped case). - // Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y - // correspondingly so the projected x and y come out right - // FIXME: make this work for clipped case too? - if (trivial_accept) - { - for (i=0 ; i<4 ; i++) - { - (*m_paliastransform)[0][i] *= m_fSoftwareXScale * - (1.0 / (ZISCALE * 0x10000)); - (*m_paliastransform)[1][i] *= m_fSoftwareYScale * - (1.0 / (ZISCALE * 0x10000)); - (*m_paliastransform)[2][i] *= 1.0 / (ZISCALE * 0x10000); - - } - } - } - - (*m_protationmatrix)[0][3] = modelpos[0]; - (*m_protationmatrix)[1][3] = modelpos[1]; - (*m_protationmatrix)[2][3] = modelpos[2]; -} - - -/* -==================== -StudioEstimateInterpolant - -==================== -*/ -float CStudioModelRenderer::StudioEstimateInterpolant( void ) -{ - float dadt = 1.0; - - if ( m_fDoInterp && ( m_pCurrentEntity->curstate.animtime >= m_pCurrentEntity->latched.prevanimtime + 0.01 ) ) - { - dadt = (m_clTime - m_pCurrentEntity->curstate.animtime) / 0.1; - if (dadt > 2.0) - { - dadt = 2.0; - } - } - return dadt; -} - -/* -==================== -StudioCalcRotations - -==================== -*/ -void CStudioModelRenderer::StudioCalcRotations ( float pos[][3], vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f ) -{ - int i; - int frame; - mstudiobone_t *pbone; - - float s; - float adj[MAXSTUDIOCONTROLLERS]; - float dadt; - - if (f > pseqdesc->numframes - 1) - { - f = 0; // bah, fix this bug with changing sequences too fast - } - // BUG ( somewhere else ) but this code should validate this data. - // This could cause a crash if the frame # is negative, so we'll go ahead - // and clamp it here - else if ( f < -0.01 ) - { - f = -0.01; - } - - frame = (int)f; - - // Con_DPrintf("%d %.4f %.4f %.4f %.4f %d\n", m_pCurrentEntity->curstate.sequence, m_clTime, m_pCurrentEntity->animtime, m_pCurrentEntity->frame, f, frame ); - - // Con_DPrintf( "%f %f %f\n", m_pCurrentEntity->angles[ROLL], m_pCurrentEntity->angles[PITCH], m_pCurrentEntity->angles[YAW] ); - - // Con_DPrintf("frame %d %d\n", frame1, frame2 ); - - - dadt = StudioEstimateInterpolant( ); - s = (f - frame); - - // add in programtic controllers - pbone = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); - - StudioCalcBoneAdj( dadt, adj, m_pCurrentEntity->curstate.controller, m_pCurrentEntity->latched.prevcontroller, m_pCurrentEntity->mouth.mouthopen ); - - for (i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++) - { - StudioCalcBoneQuaterion( frame, s, pbone, panim, adj, q[i] ); - - StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] ); - // if (0 && i == 0) - // Con_DPrintf("%d %d %d %d\n", m_pCurrentEntity->curstate.sequence, frame, j, k ); - } - - if (pseqdesc->motiontype & STUDIO_X) - { - pos[pseqdesc->motionbone][0] = 0.0; - } - if (pseqdesc->motiontype & STUDIO_Y) - { - pos[pseqdesc->motionbone][1] = 0.0; - } - if (pseqdesc->motiontype & STUDIO_Z) - { - pos[pseqdesc->motionbone][2] = 0.0; - } - - s = 0 * ((1.0 - (f - (int)(f))) / (pseqdesc->numframes)) * m_pCurrentEntity->curstate.framerate; - - if (pseqdesc->motiontype & STUDIO_LX) - { - pos[pseqdesc->motionbone][0] += s * pseqdesc->linearmovement[0]; - } - if (pseqdesc->motiontype & STUDIO_LY) - { - pos[pseqdesc->motionbone][1] += s * pseqdesc->linearmovement[1]; - } - if (pseqdesc->motiontype & STUDIO_LZ) - { - pos[pseqdesc->motionbone][2] += s * pseqdesc->linearmovement[2]; - } -} - -/* -==================== -Studio_FxTransform - -==================== -*/ -void CStudioModelRenderer::StudioFxTransform( cl_entity_t *ent, float transform[3][4] ) -{ - - switch( ent->curstate.renderfx ) - { - case kRenderFxDistort: - case kRenderFxHologram: - if ( gEngfuncs.pfnRandomLong(0,49) == 0 ) - { - int axis = gEngfuncs.pfnRandomLong(0,1); - if ( axis == 1 ) // Choose between x & z - axis = 2; - VectorScale( transform[axis], gEngfuncs.pfnRandomFloat(1,1.484), transform[axis] ); - } - else if ( gEngfuncs.pfnRandomLong(0,49) == 0 ) - { - float offset; - int axis = gEngfuncs.pfnRandomLong(0,1); - if ( axis == 1 ) // Choose between x & z - axis = 2; - offset = gEngfuncs.pfnRandomFloat(-10,10); - transform[gEngfuncs.pfnRandomLong(0,2)][3] += offset; - } - break; - case kRenderFxExplode: - { - float scale; - - scale = 1.0 + ( m_clTime - ent->curstate.animtime) * 10.0; - if ( scale > 2 ) // Don't blow up more than 200% - scale = 2; - transform[0][1] *= scale; - transform[1][1] *= scale; - transform[2][1] *= scale; - } - break; - - } -} - -/* -==================== -StudioEstimateFrame - -==================== -*/ -float CStudioModelRenderer::StudioEstimateFrame( mstudioseqdesc_t *pseqdesc ) -{ - double dfdt, f; - - if ( m_fDoInterp ) - { - if ( m_clTime < m_pCurrentEntity->curstate.animtime ) - { - dfdt = 0; - } - else - { - dfdt = (m_clTime - m_pCurrentEntity->curstate.animtime) * m_pCurrentEntity->curstate.framerate * pseqdesc->fps; - - } - } - else - { - dfdt = 0; - } - - if (pseqdesc->numframes <= 1) - { - f = 0; - } - else - { - f = (m_pCurrentEntity->curstate.frame * (pseqdesc->numframes - 1)) / 256.0; - } - - f += dfdt; - - if (pseqdesc->flags & STUDIO_LOOPING) - { - if (pseqdesc->numframes > 1) - { - f -= (int)(f / (pseqdesc->numframes - 1)) * (pseqdesc->numframes - 1); - } - if (f < 0) - { - f += (pseqdesc->numframes - 1); - } - } - else - { - if (f >= pseqdesc->numframes - 1.001) - { - f = pseqdesc->numframes - 1.001; - } - if (f < 0.0) - { - f = 0.0; - } - } - return f; -} - -/* -==================== -StudioSetupBones - -==================== -*/ -void CStudioModelRenderer::StudioSetupBones ( void ) -{ - int i; - double f; - - mstudiobone_t *pbones; - mstudioseqdesc_t *pseqdesc; - mstudioanim_t *panim; - - static float pos[MAXSTUDIOBONES][3]; - static vec4_t q[MAXSTUDIOBONES]; - float bonematrix[3][4]; - - static float pos2[MAXSTUDIOBONES][3]; - static vec4_t q2[MAXSTUDIOBONES]; - static float pos3[MAXSTUDIOBONES][3]; - static vec4_t q3[MAXSTUDIOBONES]; - static float pos4[MAXSTUDIOBONES][3]; - static vec4_t q4[MAXSTUDIOBONES]; - - if (m_pCurrentEntity->curstate.sequence >= m_pStudioHeader->numseq) - { - m_pCurrentEntity->curstate.sequence = 0; - } - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; - - f = StudioEstimateFrame( pseqdesc ); - - if (m_pCurrentEntity->latched.prevframe > f) - { - //Con_DPrintf("%f %f\n", m_pCurrentEntity->prevframe, f ); - } - - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - StudioCalcRotations( pos, q, pseqdesc, panim, f ); - - if (pseqdesc->numblends > 1) - { - float s; - float dadt; - - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos2, q2, pseqdesc, panim, f ); - - dadt = StudioEstimateInterpolant(); - s = (m_pCurrentEntity->curstate.blending[0] * dadt + m_pCurrentEntity->latched.prevblending[0] * (1.0 - dadt)) / 255.0; - - StudioSlerpBones( q, pos, q2, pos2, s ); - - if (pseqdesc->numblends == 4) - { - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos3, q3, pseqdesc, panim, f ); - - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos4, q4, pseqdesc, panim, f ); - - s = (m_pCurrentEntity->curstate.blending[0] * dadt + m_pCurrentEntity->latched.prevblending[0] * (1.0 - dadt)) / 255.0; - StudioSlerpBones( q3, pos3, q4, pos4, s ); - - s = (m_pCurrentEntity->curstate.blending[1] * dadt + m_pCurrentEntity->latched.prevblending[1] * (1.0 - dadt)) / 255.0; - StudioSlerpBones( q, pos, q3, pos3, s ); - } - } - - if (m_fDoInterp && - m_pCurrentEntity->latched.sequencetime && - ( m_pCurrentEntity->latched.sequencetime + 0.2 > m_clTime ) && - ( m_pCurrentEntity->latched.prevsequence < m_pStudioHeader->numseq )) - { - // blend from last sequence - static float pos1b[MAXSTUDIOBONES][3]; - static vec4_t q1b[MAXSTUDIOBONES]; - float s; - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->latched.prevsequence; - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - // clip prevframe - StudioCalcRotations( pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - if (pseqdesc->numblends > 1) - { - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos2, q2, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - s = (m_pCurrentEntity->latched.prevseqblending[0]) / 255.0; - StudioSlerpBones( q1b, pos1b, q2, pos2, s ); - - if (pseqdesc->numblends == 4) - { - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos3, q3, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos4, q4, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - s = (m_pCurrentEntity->latched.prevseqblending[0]) / 255.0; - StudioSlerpBones( q3, pos3, q4, pos4, s ); - - s = (m_pCurrentEntity->latched.prevseqblending[1]) / 255.0; - StudioSlerpBones( q1b, pos1b, q3, pos3, s ); - } - } - - s = 1.0 - (m_clTime - m_pCurrentEntity->latched.sequencetime) / 0.2; - StudioSlerpBones( q, pos, q1b, pos1b, s ); - } - else - { - //Con_DPrintf("prevframe = %4.2f\n", f); - m_pCurrentEntity->latched.prevframe = f; - } - - pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); - - // calc gait animation - if (m_pPlayerInfo && m_pPlayerInfo->gaitsequence != 0) - { - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pPlayerInfo->gaitsequence; - - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - StudioCalcRotations( pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe ); - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - if (strcmp( pbones[i].name, "Bip01 Spine") == 0) - break; - memcpy( pos[i], pos2[i], sizeof( pos[i] )); - memcpy( q[i], q2[i], sizeof( q[i] )); - } - } - - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - QuaternionMatrix( q[i], bonematrix ); - - bonematrix[0][3] = pos[i][0]; - bonematrix[1][3] = pos[i][1]; - bonematrix[2][3] = pos[i][2]; - - if (pbones[i].parent == -1) - { - - //Adrian - Scale the player's model height down - //NOTE: This is only relative for a few models, - //some other models might need a different number. - if ( m_pCurrentEntity->player ) - bonematrix[2][2] *= 0.89; // (2,2) is Z component - - if ( IEngineStudio.IsHardware() ) - { - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - } - else - { - ConcatTransforms ((*m_paliastransform), bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - } - - // Apply client-side effects to the transformation matrix - StudioFxTransform( m_pCurrentEntity, (*m_pbonetransform)[i] ); - } - else - { - ConcatTransforms ((*m_pbonetransform)[pbones[i].parent], bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_plighttransform)[pbones[i].parent], bonematrix, (*m_plighttransform)[i]); - } - } - -} - - -/* -==================== -StudioSaveBones - -==================== -*/ -void CStudioModelRenderer::StudioSaveBones( void ) -{ - int i; - - mstudiobone_t *pbones; - pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); - - m_nCachedBones = m_pStudioHeader->numbones; - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - strcpy( m_nCachedBoneNames[i], pbones[i].name ); - MatrixCopy( (*m_pbonetransform)[i], m_rgCachedBoneTransform[i] ); - MatrixCopy( (*m_plighttransform)[i], m_rgCachedLightTransform[i] ); - } -} - - -/* -==================== -StudioMergeBones - -==================== -*/ -void CStudioModelRenderer::StudioMergeBones ( model_t *m_pSubModel ) -{ - int i, j; - double f; - int do_hunt = true; - - mstudiobone_t *pbones; - mstudioseqdesc_t *pseqdesc; - mstudioanim_t *panim; - - static float pos[MAXSTUDIOBONES][3]; - float bonematrix[3][4]; - static vec4_t q[MAXSTUDIOBONES]; - - if (m_pCurrentEntity->curstate.sequence >= m_pStudioHeader->numseq) - { - m_pCurrentEntity->curstate.sequence = 0; - } - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; - - f = StudioEstimateFrame( pseqdesc ); - - if (m_pCurrentEntity->latched.prevframe > f) - { - //Con_DPrintf("%f %f\n", m_pCurrentEntity->prevframe, f ); - } - - panim = StudioGetAnim( m_pSubModel, pseqdesc ); - StudioCalcRotations( pos, q, pseqdesc, panim, f ); - - pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); - - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - for (j = 0; j < m_nCachedBones; j++) - { - if (stricmp(pbones[i].name, m_nCachedBoneNames[j]) == 0) - { - MatrixCopy( m_rgCachedBoneTransform[j], (*m_pbonetransform)[i] ); - MatrixCopy( m_rgCachedLightTransform[j], (*m_plighttransform)[i] ); - break; - } - } - if (j >= m_nCachedBones) - { - QuaternionMatrix( q[i], bonematrix ); - - bonematrix[0][3] = pos[i][0]; - bonematrix[1][3] = pos[i][1]; - bonematrix[2][3] = pos[i][2]; - - if (pbones[i].parent == -1) - { - if ( IEngineStudio.IsHardware() ) - { - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - //MatrixCopy( (*m_pbonetransform)[i], (*m_plighttransform)[i] ); - } - else - { - ConcatTransforms ((*m_paliastransform), bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - } - - // Apply client-side effects to the transformation matrix - StudioFxTransform( m_pCurrentEntity, (*m_pbonetransform)[i] ); - } - else - { - ConcatTransforms ((*m_pbonetransform)[pbones[i].parent], bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_plighttransform)[pbones[i].parent], bonematrix, (*m_plighttransform)[i]); - } - } - } -} - -/* -==================== -StudioDrawModel - -==================== -*/ -int CStudioModelRenderer::StudioDrawModel( int flags ) -{ - alight_t lighting; - vec3_t dir; - - m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); - IEngineStudio.GetTimes( &m_nFrameCount, &m_clTime, &m_clOldTime ); - IEngineStudio.GetViewInfo( m_vRenderOrigin, m_vUp, m_vRight, m_vNormal ); - IEngineStudio.GetAliasScale( &m_fSoftwareXScale, &m_fSoftwareYScale ); - - if (m_pCurrentEntity->curstate.renderfx == kRenderFxDeadPlayer) - { - entity_state_t deadplayer; - - int result; - int save_interp; - - if (m_pCurrentEntity->curstate.renderamt <= 0 || m_pCurrentEntity->curstate.renderamt > gEngfuncs.GetMaxClients() ) - return 0; - - // get copy of player - deadplayer = *(IEngineStudio.GetPlayerState( m_pCurrentEntity->curstate.renderamt - 1 )); //cl.frames[cl.parsecount & CL_UPDATE_MASK].playerstate[m_pCurrentEntity->curstate.renderamt-1]; - - // clear weapon, movement state - deadplayer.number = m_pCurrentEntity->curstate.renderamt; - deadplayer.weaponmodel = 0; - deadplayer.gaitsequence = 0; - - deadplayer.movetype = MOVETYPE_NONE; - VectorCopy( m_pCurrentEntity->curstate.angles, deadplayer.angles ); - VectorCopy( m_pCurrentEntity->curstate.origin, deadplayer.origin ); - - save_interp = m_fDoInterp; - m_fDoInterp = 0; - - // draw as though it were a player - result = StudioDrawPlayer( flags, &deadplayer ); - - m_fDoInterp = save_interp; - return result; - } - - m_pRenderModel = m_pCurrentEntity->model; - m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (m_pRenderModel); - IEngineStudio.StudioSetHeader( m_pStudioHeader ); - IEngineStudio.SetRenderModel( m_pRenderModel ); - - StudioSetUpTransform( 0 ); - - if (flags & STUDIO_RENDER) - { - // see if the bounding box lets us trivially reject, also sets - if (!IEngineStudio.StudioCheckBBox ()) - return 0; - - (*m_pModelsDrawn)++; - (*m_pStudioModelCount)++; // render data cache cookie - - if (m_pStudioHeader->numbodyparts == 0) - return 1; - } - - if (m_pCurrentEntity->curstate.movetype == MOVETYPE_FOLLOW) - { - StudioMergeBones( m_pRenderModel ); - } - else - { - StudioSetupBones( ); - } - - StudioSaveBones( ); - - if (flags & STUDIO_EVENTS) - { - StudioCalcAttachments( ); - IEngineStudio.StudioClientEvents( ); - // copy attachments into global entity array - if ( m_pCurrentEntity->index > 0 ) - { - cl_entity_t *ent = gEngfuncs.GetEntityByIndex( m_pCurrentEntity->index ); - - memcpy( ent->attachment, m_pCurrentEntity->attachment, sizeof( vec3_t ) * 4 ); - } - } - - if (flags & STUDIO_RENDER) - { - lighting.plightvec = dir; - IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting ); - - IEngineStudio.StudioEntityLight( &lighting ); - - //Scale the spike model lighting by a factor of 30 ( H4X!! ) - if ( strstr ( m_pCurrentEntity->model->name, "spike.mdl" ) ) - lighting.ambientlight *= 30; - - // model and frame independant - IEngineStudio.StudioSetupLighting (&lighting); - - // get remap colors - m_nTopColor = m_pCurrentEntity->curstate.colormap & 0xFF; - m_nBottomColor = (m_pCurrentEntity->curstate.colormap & 0xFF00) >> 8; - - IEngineStudio.StudioSetRemapColors( m_nTopColor, m_nBottomColor ); - - StudioRenderModel( ); - } - - return 1; -} - -/* -==================== -StudioEstimateGait - -==================== -*/ -void CStudioModelRenderer::StudioEstimateGait( entity_state_t *pplayer ) -{ - float dt; - vec3_t est_velocity; - - dt = (m_clTime - m_clOldTime); - if (dt < 0) - dt = 0; - else if (dt > 1.0) - dt = 1; - - if (dt == 0 || m_pPlayerInfo->renderframe == m_nFrameCount) - { - m_flGaitMovement = 0; - return; - } - - // VectorAdd( pplayer->velocity, pplayer->prediction_error, est_velocity ); - if ( m_fGaitEstimation ) - { - VectorSubtract( m_pCurrentEntity->origin, m_pPlayerInfo->prevgaitorigin, est_velocity ); - VectorCopy( m_pCurrentEntity->origin, m_pPlayerInfo->prevgaitorigin ); - m_flGaitMovement = Length( est_velocity ); - if (dt <= 0 || m_flGaitMovement / dt < 5) - { - m_flGaitMovement = 0; - est_velocity[0] = 0; - est_velocity[1] = 0; - } - } - else - { - VectorCopy( pplayer->velocity, est_velocity ); - m_flGaitMovement = Length( est_velocity ) * dt; - } - - if (est_velocity[1] == 0 && est_velocity[0] == 0) - { - float flYawDiff = m_pCurrentEntity->angles[YAW] - m_pPlayerInfo->gaityaw; - flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360; - if (flYawDiff > 180) - flYawDiff -= 360; - if (flYawDiff < -180) - flYawDiff += 360; - - if (dt < 0.25) - flYawDiff *= dt * 4; - else - flYawDiff *= dt; - - m_pPlayerInfo->gaityaw += flYawDiff; - m_pPlayerInfo->gaityaw = m_pPlayerInfo->gaityaw - (int)(m_pPlayerInfo->gaityaw / 360) * 360; - - m_flGaitMovement = 0; - } - else - { - m_pPlayerInfo->gaityaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI); - if (m_pPlayerInfo->gaityaw > 180) - m_pPlayerInfo->gaityaw = 180; - if (m_pPlayerInfo->gaityaw < -180) - m_pPlayerInfo->gaityaw = -180; - } - -} - -/* -==================== -StudioProcessGait - -==================== -*/ -void CStudioModelRenderer::StudioProcessGait( entity_state_t *pplayer ) -{ - mstudioseqdesc_t *pseqdesc; - float dt; - int iBlend; - float flYaw; // view direction relative to movement - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; - - StudioPlayerBlend( pseqdesc, &iBlend, &m_pCurrentEntity->angles[PITCH] ); - - m_pCurrentEntity->latched.prevangles[PITCH] = m_pCurrentEntity->angles[PITCH]; - m_pCurrentEntity->curstate.blending[0] = iBlend; - m_pCurrentEntity->latched.prevblending[0] = m_pCurrentEntity->curstate.blending[0]; - m_pCurrentEntity->latched.prevseqblending[0] = m_pCurrentEntity->curstate.blending[0]; - - // Con_DPrintf("%f %d\n", m_pCurrentEntity->angles[PITCH], m_pCurrentEntity->blending[0] ); - - dt = (m_clTime - m_clOldTime); - if (dt < 0) - dt = 0; - else if (dt > 1.0) - dt = 1; - - StudioEstimateGait( pplayer ); - - // Con_DPrintf("%f %f\n", m_pCurrentEntity->angles[YAW], m_pPlayerInfo->gaityaw ); - - // calc side to side turning - flYaw = m_pCurrentEntity->angles[YAW] - m_pPlayerInfo->gaityaw; - flYaw = flYaw - (int)(flYaw / 360) * 360; - if (flYaw < -180) - flYaw = flYaw + 360; - if (flYaw > 180) - flYaw = flYaw - 360; - - if (flYaw > 120) - { - m_pPlayerInfo->gaityaw = m_pPlayerInfo->gaityaw - 180; - m_flGaitMovement = -m_flGaitMovement; - flYaw = flYaw - 180; - } - else if (flYaw < -120) - { - m_pPlayerInfo->gaityaw = m_pPlayerInfo->gaityaw + 180; - m_flGaitMovement = -m_flGaitMovement; - flYaw = flYaw + 180; - } - - // adjust torso - m_pCurrentEntity->curstate.controller[0] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); - m_pCurrentEntity->curstate.controller[1] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); - m_pCurrentEntity->curstate.controller[2] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); - m_pCurrentEntity->curstate.controller[3] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); - m_pCurrentEntity->latched.prevcontroller[0] = m_pCurrentEntity->curstate.controller[0]; - m_pCurrentEntity->latched.prevcontroller[1] = m_pCurrentEntity->curstate.controller[1]; - m_pCurrentEntity->latched.prevcontroller[2] = m_pCurrentEntity->curstate.controller[2]; - m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; - - m_pCurrentEntity->angles[YAW] = m_pPlayerInfo->gaityaw; - if (m_pCurrentEntity->angles[YAW] < -0) - m_pCurrentEntity->angles[YAW] += 360; - m_pCurrentEntity->latched.prevangles[YAW] = m_pCurrentEntity->angles[YAW]; - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + pplayer->gaitsequence; - - // calc gait frame - if (pseqdesc->linearmovement[0] > 0) - { - m_pPlayerInfo->gaitframe += (m_flGaitMovement / pseqdesc->linearmovement[0]) * pseqdesc->numframes; - } - else - { - m_pPlayerInfo->gaitframe += pseqdesc->fps * dt; - } - - // do modulo - m_pPlayerInfo->gaitframe = m_pPlayerInfo->gaitframe - (int)(m_pPlayerInfo->gaitframe / pseqdesc->numframes) * pseqdesc->numframes; - if (m_pPlayerInfo->gaitframe < 0) - m_pPlayerInfo->gaitframe += pseqdesc->numframes; -} - -/* -==================== -StudioDrawPlayer - -==================== -*/ -int CStudioModelRenderer::StudioDrawPlayer( int flags, entity_state_t *pplayer ) -{ - alight_t lighting; - vec3_t dir; - - m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); - IEngineStudio.GetTimes( &m_nFrameCount, &m_clTime, &m_clOldTime ); - IEngineStudio.GetViewInfo( m_vRenderOrigin, m_vUp, m_vRight, m_vNormal ); - IEngineStudio.GetAliasScale( &m_fSoftwareXScale, &m_fSoftwareYScale ); - - // Con_DPrintf("DrawPlayer %d\n", m_pCurrentEntity->blending[0] ); - - // Con_DPrintf("DrawPlayer %d %d (%d)\n", m_nFrameCount, pplayer->player_index, m_pCurrentEntity->curstate.sequence ); - - // Con_DPrintf("Player %.2f %.2f %.2f\n", pplayer->velocity[0], pplayer->velocity[1], pplayer->velocity[2] ); - - m_nPlayerIndex = pplayer->number - 1; - - if (m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients()) - return 0; - - m_pRenderModel = IEngineStudio.SetupPlayerModel( m_nPlayerIndex ); - if (m_pRenderModel == NULL) - return 0; - - m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (m_pRenderModel); - IEngineStudio.StudioSetHeader( m_pStudioHeader ); - IEngineStudio.SetRenderModel( m_pRenderModel ); - - if (pplayer->gaitsequence) - { - vec3_t orig_angles; - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - - VectorCopy( m_pCurrentEntity->angles, orig_angles ); - - StudioProcessGait( pplayer ); - - m_pPlayerInfo->gaitsequence = pplayer->gaitsequence; - m_pPlayerInfo = NULL; - - StudioSetUpTransform( 0 ); - VectorCopy( orig_angles, m_pCurrentEntity->angles ); - } - else - { - m_pCurrentEntity->curstate.controller[0] = 127; - m_pCurrentEntity->curstate.controller[1] = 127; - m_pCurrentEntity->curstate.controller[2] = 127; - m_pCurrentEntity->curstate.controller[3] = 127; - m_pCurrentEntity->latched.prevcontroller[0] = m_pCurrentEntity->curstate.controller[0]; - m_pCurrentEntity->latched.prevcontroller[1] = m_pCurrentEntity->curstate.controller[1]; - m_pCurrentEntity->latched.prevcontroller[2] = m_pCurrentEntity->curstate.controller[2]; - m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; - - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - m_pPlayerInfo->gaitsequence = 0; - - StudioSetUpTransform( 0 ); - } - - if (flags & STUDIO_RENDER) - { - // see if the bounding box lets us trivially reject, also sets - if (!IEngineStudio.StudioCheckBBox ()) - return 0; - - (*m_pModelsDrawn)++; - (*m_pStudioModelCount)++; // render data cache cookie - - if (m_pStudioHeader->numbodyparts == 0) - return 1; - } - - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - StudioSetupBones( ); - - StudioSaveBones( ); - m_pPlayerInfo->renderframe = m_nFrameCount; - - m_pPlayerInfo = NULL; - - if (flags & STUDIO_EVENTS) - { - StudioCalcAttachments( ); - IEngineStudio.StudioClientEvents( ); - // copy attachments into global entity array - if ( m_pCurrentEntity->index > 0 ) - { - cl_entity_t *ent = gEngfuncs.GetEntityByIndex( m_pCurrentEntity->index ); - - memcpy( ent->attachment, m_pCurrentEntity->attachment, sizeof( vec3_t ) * 4 ); - } - } - - if (flags & STUDIO_RENDER) - { - if (m_pCvarHiModels->value && m_pRenderModel != m_pCurrentEntity->model ) - { - // show highest resolution multiplayer model - m_pCurrentEntity->curstate.body = 255; - } - - if (!(m_pCvarDeveloper->value == 0 && gEngfuncs.GetMaxClients() == 1 ) && ( m_pRenderModel == m_pCurrentEntity->model ) ) - { - m_pCurrentEntity->curstate.body = 1; // force helmet - } - - lighting.plightvec = dir; - IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting ); - - IEngineStudio.StudioEntityLight( &lighting ); - - //Scale player model lighting by a factor of 100 ( H4X!! ) - lighting.ambientlight *= 100; - - // model and frame independant - IEngineStudio.StudioSetupLighting (&lighting); - - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - - // get remap colors - m_nTopColor = m_pPlayerInfo->topcolor; - if (m_nTopColor < 0) - m_nTopColor = 0; - if (m_nTopColor > 360) - m_nTopColor = 360; - m_nBottomColor = m_pPlayerInfo->bottomcolor; - if (m_nBottomColor < 0) - m_nBottomColor = 0; - if (m_nBottomColor > 360) - m_nBottomColor = 360; - - IEngineStudio.StudioSetRemapColors( m_nTopColor, m_nBottomColor ); - - StudioRenderModel( ); - m_pPlayerInfo = NULL; - - if ( pplayer->weaponmodel ) - { - cl_entity_t saveent = *m_pCurrentEntity; - - model_t *pweaponmodel = IEngineStudio.GetModelByIndex( pplayer->weaponmodel ); - - m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (pweaponmodel); - IEngineStudio.StudioSetHeader( m_pStudioHeader ); - - //Animate p_ model. - if ( strstr ( pweaponmodel->name, "p_nail2.mdl" ) ) - { - if ( m_pCurrentEntity->curstate.sequence == 50 ) - m_pCurrentEntity->curstate.sequence = 1; - else - m_pCurrentEntity->curstate.sequence = 0; - - StudioSetupBones( ); - } - else if ( strstr ( pweaponmodel->name, "p_rock.mdl" ) ) - { - if ( m_pCurrentEntity->curstate.sequence == 46 ) - m_pCurrentEntity->curstate.sequence = 1; - else - m_pCurrentEntity->curstate.sequence = 0; - - StudioSetupBones( ); - } - - StudioMergeBones( pweaponmodel); - - IEngineStudio.StudioSetupLighting (&lighting); - - StudioRenderModel( ); - - StudioCalcAttachments( ); - - *m_pCurrentEntity = saveent; - } - } - - return 1; -} - -/* -==================== -StudioCalcAttachments - -==================== -*/ -void CStudioModelRenderer::StudioCalcAttachments( void ) -{ - int i; - mstudioattachment_t *pattachment; - - if ( m_pStudioHeader->numattachments > 4 ) - { - gEngfuncs.Con_DPrintf( "Too many attachments on %s\n", m_pCurrentEntity->model->name ); - exit( -1 ); - } - - // calculate attachment points - pattachment = (mstudioattachment_t *)((byte *)m_pStudioHeader + m_pStudioHeader->attachmentindex); - for (i = 0; i < m_pStudioHeader->numattachments; i++) - { - VectorTransform( pattachment[i].org, (*m_plighttransform)[pattachment[i].bone], m_pCurrentEntity->attachment[i] ); - } -} - -/* -==================== -StudioRenderModel - -==================== -*/ -void CStudioModelRenderer::StudioRenderModel( void ) -{ - IEngineStudio.SetChromeOrigin(); - IEngineStudio.SetForceFaceFlags( 0 ); - - if ( m_pCurrentEntity->curstate.renderfx == kRenderFxGlowShell ) - { - if ( strstr ( m_pCurrentEntity->model->name, "v_" ) ) - { - if ( m_pCurrentEntity->curstate.renderamt != 5 ) - { - m_pCurrentEntity->curstate.renderfx = kRenderFxNone; - StudioRenderFinal( ); - } - } - else - { - if ( m_pCurrentEntity->curstate.renderamt != 5 && m_pCurrentEntity->curstate.rendermode != kRenderTransColor ) - { - m_pCurrentEntity->curstate.renderfx = kRenderFxNone; - StudioRenderFinal( ); - } - } - - if ( !IEngineStudio.IsHardware() ) - { - gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); - } - - IEngineStudio.SetForceFaceFlags( STUDIO_NF_CHROME ); - - gEngfuncs.pTriAPI->SpriteTexture( m_pChromeSprite, 0 ); - m_pCurrentEntity->curstate.renderfx = kRenderFxGlowShell; - - StudioRenderFinal( ); - if ( !IEngineStudio.IsHardware() ) - { - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); - } - - } - else - { - StudioRenderFinal( ); - } -} - -/* -==================== -StudioRenderFinal_Software - -==================== -*/ -void CStudioModelRenderer::StudioRenderFinal_Software( void ) -{ - int i; - - // Note, rendermode set here has effect in SW - IEngineStudio.SetupRenderer( 0 ); - - if (m_pCvarDrawEntities->value == 2) - { - IEngineStudio.StudioDrawBones( ); - } - else if (m_pCvarDrawEntities->value == 3) - { - IEngineStudio.StudioDrawHulls( ); - } - else - { - for (i=0 ; i < m_pStudioHeader->numbodyparts ; i++) - { - IEngineStudio.StudioSetupModel( i, (void **)&m_pBodyPart, (void **)&m_pSubModel ); - IEngineStudio.StudioDrawPoints( ); - } - } - - if (m_pCvarDrawEntities->value == 4) - { - gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); - IEngineStudio.StudioDrawHulls( ); - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); - } - - if (m_pCvarDrawEntities->value == 5) - { - IEngineStudio.StudioDrawAbsBBox( ); - } - - IEngineStudio.RestoreRenderer(); -} - -/* -==================== -StudioRenderFinal_Hardware - -==================== -*/ -void CStudioModelRenderer::StudioRenderFinal_Hardware( void ) -{ - int i; - int rendermode; - - rendermode = IEngineStudio.GetForceFaceFlags() ? kRenderTransAdd : m_pCurrentEntity->curstate.rendermode; - IEngineStudio.SetupRenderer( rendermode ); - - if (m_pCvarDrawEntities->value == 2) - { - IEngineStudio.StudioDrawBones(); - } - else if (m_pCvarDrawEntities->value == 3) - { - IEngineStudio.StudioDrawHulls(); - } - else - { - for (i=0 ; i < m_pStudioHeader->numbodyparts ; i++) - { - IEngineStudio.StudioSetupModel( i, (void **)&m_pBodyPart, (void **)&m_pSubModel ); - - if (m_fDoInterp) - { - // interpolation messes up bounding boxes. - m_pCurrentEntity->trivial_accept = 0; - } - - IEngineStudio.GL_SetRenderMode( rendermode ); - IEngineStudio.StudioDrawPoints(); - IEngineStudio.GL_StudioDrawShadow(); - } - } - - if ( m_pCvarDrawEntities->value == 4 ) - { - gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); - IEngineStudio.StudioDrawHulls( ); - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); - } - - IEngineStudio.RestoreRenderer(); -} - -/* -==================== -StudioRenderFinal - -==================== -*/ -void CStudioModelRenderer::StudioRenderFinal(void) -{ - if ( IEngineStudio.IsHardware() ) - { - StudioRenderFinal_Hardware(); - } - else - { - StudioRenderFinal_Software(); - } -} - diff --git a/dmc/cl_dll/StudioModelRenderer.h b/dmc/cl_dll/StudioModelRenderer.h deleted file mode 100644 index 8f1427f..0000000 --- a/dmc/cl_dll/StudioModelRenderer.h +++ /dev/null @@ -1,189 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined ( STUDIOMODELRENDERER_H ) -#define STUDIOMODELRENDERER_H -#if defined( _WIN32 ) -#pragma once -#endif - -/* -==================== -CStudioModelRenderer - -==================== -*/ -class CStudioModelRenderer -{ -public: - // Construction/Destruction - CStudioModelRenderer( void ); - virtual ~CStudioModelRenderer( void ); - - // Initialization - virtual void Init( void ); - -public: - // Public Interfaces - virtual int StudioDrawModel ( int flags ); - virtual int StudioDrawPlayer ( int flags, struct entity_state_s *pplayer ); - -public: - // Local interfaces - // - - // Look up animation data for sequence - virtual mstudioanim_t *StudioGetAnim ( model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc ); - - // Interpolate model position and angles and set up matrices - virtual void StudioSetUpTransform (int trivial_accept); - - // Set up model bone positions - virtual void StudioSetupBones ( void ); - - // Find final attachment points - virtual void StudioCalcAttachments ( void ); - - // Save bone matrices and names - virtual void StudioSaveBones( void ); - - // Merge cached bones with current bones for model - virtual void StudioMergeBones ( model_t *m_pSubModel ); - - // Determine interpolation fraction - virtual float StudioEstimateInterpolant( void ); - - // Determine current frame for rendering - virtual float StudioEstimateFrame ( mstudioseqdesc_t *pseqdesc ); - - // Apply special effects to transform matrix - virtual void StudioFxTransform( cl_entity_t *ent, float transform[3][4] ); - - // Spherical interpolation of bones - virtual void StudioSlerpBones ( vec4_t q1[], float pos1[][3], vec4_t q2[], float pos2[][3], float s ); - - // Compute bone adjustments ( bone controllers ) - virtual void StudioCalcBoneAdj ( float dadt, float *adj, const byte *pcontroller1, const byte *pcontroller2, byte mouthopen ); - - // Get bone quaternions - virtual void StudioCalcBoneQuaterion ( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *q ); - - // Get bone positions - virtual void StudioCalcBonePosition ( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *pos ); - - // Compute rotations - virtual void StudioCalcRotations ( float pos[][3], vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f ); - - // Send bones and verts to renderer - virtual void StudioRenderModel ( void ); - - // Finalize rendering - virtual void StudioRenderFinal (void); - - // GL&D3D vs. Software renderer finishing functions - virtual void StudioRenderFinal_Software ( void ); - virtual void StudioRenderFinal_Hardware ( void ); - - // Player specific data - // Determine pitch and blending amounts for players - virtual void StudioPlayerBlend ( mstudioseqdesc_t *pseqdesc, int *pBlend, float *pPitch ); - - // Estimate gait frame for player - virtual void StudioEstimateGait ( entity_state_t *pplayer ); - - // Process movement of player - virtual void StudioProcessGait ( entity_state_t *pplayer ); - -public: - - // Client clock - double m_clTime; - // Old Client clock - double m_clOldTime; - - // Do interpolation? - int m_fDoInterp; - // Do gait estimation? - int m_fGaitEstimation; - - // Current render frame # - int m_nFrameCount; - - // Cvars that studio model code needs to reference - // - // Use high quality models? - cvar_t *m_pCvarHiModels; - // Developer debug output desired? - cvar_t *m_pCvarDeveloper; - // Draw entities bone hit boxes, etc? - cvar_t *m_pCvarDrawEntities; - - // The entity which we are currently rendering. - cl_entity_t *m_pCurrentEntity; - - // The model for the entity being rendered - model_t *m_pRenderModel; - - // Player info for current player, if drawing a player - player_info_t *m_pPlayerInfo; - - // The index of the player being drawn - int m_nPlayerIndex; - - // The player's gait movement - float m_flGaitMovement; - - // Pointer to header block for studio model data - studiohdr_t *m_pStudioHeader; - - // Pointers to current body part and submodel - mstudiobodyparts_t *m_pBodyPart; - mstudiomodel_t *m_pSubModel; - - // Palette substition for top and bottom of model - int m_nTopColor; - int m_nBottomColor; - - // - // Sprite model used for drawing studio model chrome - model_t *m_pChromeSprite; - - // Caching - // Number of bones in bone cache - int m_nCachedBones; - // Names of cached bones - char m_nCachedBoneNames[ MAXSTUDIOBONES ][ 32 ]; - // Cached bone & light transformation matrices - float m_rgCachedBoneTransform [ MAXSTUDIOBONES ][ 3 ][ 4 ]; - float m_rgCachedLightTransform[ MAXSTUDIOBONES ][ 3 ][ 4 ]; - - // Software renderer scale factors - float m_fSoftwareXScale, m_fSoftwareYScale; - - // Current view vectors and render origin - float m_vUp[ 3 ]; - float m_vRight[ 3 ]; - float m_vNormal[ 3 ]; - - float m_vRenderOrigin[ 3 ]; - - // Model render counters ( from engine ) - int *m_pStudioModelCount; - int *m_pModelsDrawn; - - // Matrices - // Model to world transformation - float (*m_protationmatrix)[ 3 ][ 4 ]; - // Model to view transformation - float (*m_paliastransform)[ 3 ][ 4 ]; - - // Concatenated bone and light transforms - float (*m_pbonetransform) [ MAXSTUDIOBONES ][ 3 ][ 4 ]; - float (*m_plighttransform)[ MAXSTUDIOBONES ][ 3 ][ 4 ]; -}; - -#endif // STUDIOMODELRENDERER_H \ No newline at end of file diff --git a/dmc/cl_dll/ammo.cpp b/dmc/cl_dll/ammo.cpp deleted file mode 100644 index 78af18d..0000000 --- a/dmc/cl_dll/ammo.cpp +++ /dev/null @@ -1,1131 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// Ammo.cpp -// -// implementation of CHudAmmo class -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -#include "ammohistory.h" - -WEAPON *gpActiveSel; // NULL means off, 1 means just the menu bar, otherwise - // this points to the active weapon menu item -WEAPON *gpLastSel; // Last weapon menu selection - -client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes, int iCount); - -WeaponsResource gWR; - -int g_weaponselect = 0; - -void WeaponsResource :: LoadAllWeaponSprites( void ) -{ - for (int i = 0; i < MAX_WEAPONS; i++) - { - if ( rgWeapons[i].iId ) - LoadWeaponSprites( &rgWeapons[i] ); - } -} - -int WeaponsResource :: CountAmmo( int iId ) -{ - if ( iId < 0 ) - return 0; - - //Fixes some crashes. - if ( iId > MAX_AMMO_TYPES ) - return 0; - - return riAmmo[iId]; -} - -int WeaponsResource :: HasAmmo( WEAPON *p ) -{ - if ( !p ) - return FALSE; - - // weapons with no max ammo can always be selected - if ( p->iMax1 == -1 ) - return TRUE; - - return (p->iAmmoType == -1) || p->iClip > 0 || CountAmmo(p->iAmmoType) - || CountAmmo(p->iAmmo2Type) || ( p->iFlags & WEAPON_FLAGS_SELECTONEMPTY ); -} - - -void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon ) -{ - int i, iRes; - - if (ScreenWidth < 640) - iRes = 320; - else - iRes = 640; - - char sz[128]; - - if ( !pWeapon ) - return; - - memset( &pWeapon->rcActive, 0, sizeof(wrect_t) ); - memset( &pWeapon->rcInactive, 0, sizeof(wrect_t) ); - memset( &pWeapon->rcAmmo, 0, sizeof(wrect_t) ); - memset( &pWeapon->rcAmmo2, 0, sizeof(wrect_t) ); - pWeapon->hInactive = 0; - pWeapon->hActive = 0; - pWeapon->hAmmo = 0; - pWeapon->hAmmo2 = 0; - - sprintf(sz, "sprites/%s.txt", pWeapon->szName); - client_sprite_t *pList = SPR_GetList(sz, &i); - - if (!pList) - return; - - client_sprite_t *p; - - p = GetSpriteList( pList, "crosshair", iRes, i ); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hCrosshair = SPR_Load(sz); - pWeapon->rcCrosshair = p->rc; - } - else - pWeapon->hCrosshair = NULL; - - p = GetSpriteList(pList, "autoaim", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hAutoaim = SPR_Load(sz); - pWeapon->rcAutoaim = p->rc; - } - else - pWeapon->hAutoaim = 0; - - p = GetSpriteList( pList, "zoom", iRes, i ); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hZoomedCrosshair = SPR_Load(sz); - pWeapon->rcZoomedCrosshair = p->rc; - } - else - { - pWeapon->hZoomedCrosshair = pWeapon->hCrosshair; //default to non-zoomed crosshair - pWeapon->rcZoomedCrosshair = pWeapon->rcCrosshair; - } - - p = GetSpriteList(pList, "zoom_autoaim", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hZoomedAutoaim = SPR_Load(sz); - pWeapon->rcZoomedAutoaim = p->rc; - } - else - { - pWeapon->hZoomedAutoaim = pWeapon->hZoomedCrosshair; //default to zoomed crosshair - pWeapon->rcZoomedAutoaim = pWeapon->rcZoomedCrosshair; - } - - p = GetSpriteList(pList, "weapon", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hInactive = SPR_Load(sz); - pWeapon->rcInactive = p->rc; - - gHR.iHistoryGap = V_max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top ); - } - else - pWeapon->hInactive = 0; - - p = GetSpriteList(pList, "weapon_s", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hActive = SPR_Load(sz); - pWeapon->rcActive = p->rc; - } - else - pWeapon->hActive = 0; - - p = GetSpriteList(pList, "ammo", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hAmmo = SPR_Load(sz); - pWeapon->rcAmmo = p->rc; - - gHR.iHistoryGap = V_max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top ); - } - else - pWeapon->hAmmo = 0; - - p = GetSpriteList(pList, "ammo2", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hAmmo2 = SPR_Load(sz); - pWeapon->rcAmmo2 = p->rc; - - gHR.iHistoryGap = V_max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top ); - } - else - pWeapon->hAmmo2 = 0; - -} - -// Returns the first weapon for a given slot. -WEAPON *WeaponsResource :: GetFirstPos( int iSlot ) -{ - WEAPON *pret = NULL; - - for (int i = 0; i < MAX_WEAPON_POSITIONS; i++) - { - if ( rgSlots[iSlot][i] && HasAmmo( rgSlots[iSlot][i] ) ) - { - pret = rgSlots[iSlot][i]; - break; - } - } - - return pret; -} - - -WEAPON* WeaponsResource :: GetNextActivePos( int iSlot, int iSlotPos ) -{ - if ( iSlotPos >= MAX_WEAPON_POSITIONS || iSlot >= MAX_WEAPON_SLOTS ) - return NULL; - - WEAPON *p = gWR.rgSlots[ iSlot ][ iSlotPos+1 ]; - - if ( !p || !gWR.HasAmmo(p) ) - return GetNextActivePos( iSlot, iSlotPos + 1 ); - - return p; -} - - -int giBucketHeight, giBucketWidth, giABHeight, giABWidth; // Ammo Bar width and height - -HSPRITE ghsprBuckets; // Sprite for top row of weapons menu - -DECLARE_MESSAGE(m_Ammo, CurWeapon ); // Current weapon and clip -DECLARE_MESSAGE(m_Ammo, WeaponList); // new weapon type -DECLARE_MESSAGE(m_Ammo, AmmoX); // update known ammo type's count -DECLARE_MESSAGE(m_Ammo, AmmoPickup); // flashes an ammo pickup record -DECLARE_MESSAGE(m_Ammo, WeapPickup); // flashes a weapon pickup record -DECLARE_MESSAGE(m_Ammo, HideWeapon); // hides the weapon, ammo, and crosshair displays temporarily -DECLARE_MESSAGE(m_Ammo, ItemPickup); - -DECLARE_COMMAND(m_Ammo, Slot1); -DECLARE_COMMAND(m_Ammo, Slot2); -DECLARE_COMMAND(m_Ammo, Slot3); -DECLARE_COMMAND(m_Ammo, Slot4); -DECLARE_COMMAND(m_Ammo, Slot5); -DECLARE_COMMAND(m_Ammo, Slot6); -DECLARE_COMMAND(m_Ammo, Slot7); -DECLARE_COMMAND(m_Ammo, Slot8); -DECLARE_COMMAND(m_Ammo, Slot9); -DECLARE_COMMAND(m_Ammo, Slot10); -DECLARE_COMMAND(m_Ammo, Close); -DECLARE_COMMAND(m_Ammo, NextWeapon); -DECLARE_COMMAND(m_Ammo, PrevWeapon); - -// width of ammo fonts -#define AMMO_SMALL_WIDTH 10 -#define AMMO_LARGE_WIDTH 20 - -#define HISTORY_DRAW_TIME "5" - -int CHudAmmo::Init(void) -{ - gHUD.AddHudElem(this); - - HOOK_MESSAGE(CurWeapon); - HOOK_MESSAGE(WeaponList); - HOOK_MESSAGE(AmmoPickup); - HOOK_MESSAGE(WeapPickup); - HOOK_MESSAGE(ItemPickup); - HOOK_MESSAGE(HideWeapon); - HOOK_MESSAGE(AmmoX); - - HOOK_COMMAND("slot1", Slot1); - HOOK_COMMAND("slot2", Slot2); - HOOK_COMMAND("slot3", Slot3); - HOOK_COMMAND("slot4", Slot4); - HOOK_COMMAND("slot5", Slot5); - HOOK_COMMAND("slot6", Slot6); - HOOK_COMMAND("slot7", Slot7); - HOOK_COMMAND("slot8", Slot8); - HOOK_COMMAND("slot9", Slot9); - HOOK_COMMAND("slot10", Slot10); - HOOK_COMMAND("cancelselect", Close); - HOOK_COMMAND("invnext", NextWeapon); - HOOK_COMMAND("invprev", PrevWeapon); - - Reset(); - - CVAR_CREATE( "hud_drawhistory_time", HISTORY_DRAW_TIME, 0 ); - CVAR_CREATE( "hud_fastswitch", "0", FCVAR_ARCHIVE ); // controls whether or not weapons can be selected in one keypress - - m_iFlags |= HUD_ACTIVE; //!!! - - gWR.Init(); - gHR.Init(); - - return 1; -}; - -void CHudAmmo::Reset(void) -{ - m_fFade = 0; - m_iFlags |= HUD_ACTIVE; //!!! - - gpActiveSel = NULL; - gHUD.m_iHideHUDDisplay = 0; - - gWR.Reset(); - gHR.Reset(); - - // VidInit(); - -} - -int CHudAmmo::VidInit(void) -{ - // Load sprites for buckets (top row of weapon menu) - m_HUD_bucket0 = gHUD.GetSpriteIndex( "bucket1" ); - m_HUD_selection = gHUD.GetSpriteIndex( "selection" ); - - ghsprBuckets = gHUD.GetSprite(m_HUD_bucket0); - giBucketWidth = gHUD.GetSpriteRect(m_HUD_bucket0).right - gHUD.GetSpriteRect(m_HUD_bucket0).left; - giBucketHeight = gHUD.GetSpriteRect(m_HUD_bucket0).bottom - gHUD.GetSpriteRect(m_HUD_bucket0).top; - - gHR.iHistoryGap = V_max( gHR.iHistoryGap, gHUD.GetSpriteRect(m_HUD_bucket0).bottom - gHUD.GetSpriteRect(m_HUD_bucket0).top); - - // If we've already loaded weapons, let's get new sprites - gWR.LoadAllWeaponSprites(); - - if (ScreenWidth >= 640) - { - giABWidth = 20; - giABHeight = 4; - } - else - { - giABWidth = 10; - giABHeight = 2; - } - - return 1; -} - -// -// Think: -// Used for selection of weapon menu item. -// -void CHudAmmo::Think(void) -{ - if ( gHUD.m_fPlayerDead ) - return; - - if ( gHUD.m_iWeaponBits != gWR.iOldWeaponBits ) - { - gWR.iOldWeaponBits = gHUD.m_iWeaponBits; - - for (int i = MAX_WEAPONS-1; i > 0; i-- ) - { - WEAPON *p = gWR.GetWeapon(i); - - if ( p ) - { - if ( gHUD.m_iWeaponBits & p->iId ) - gWR.PickupWeapon( p ); - else - gWR.DropWeapon( p ); - } - } - } - - if (!gpActiveSel) - return; - - // has the player selected one? - if (gHUD.m_iKeyBits & IN_ATTACK) - { - if (gpActiveSel != (WEAPON *)1) - { - //ServerCmd(gpActiveSel->szName); - g_weaponselect = gpActiveSel->iSlot; - } - - gpLastSel = gpActiveSel; - gpActiveSel = NULL; - gHUD.m_iKeyBits &= ~IN_ATTACK; - - PlaySound("common/wpn_select.wav", 1); - } - -} - -// -// Helper function to return a Ammo pointer from id -// - -HSPRITE* WeaponsResource :: GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect ) -{ - for ( int i = 0; i < MAX_WEAPONS; i++ ) - { - if ( rgWeapons[i].iAmmoType == iAmmoId ) - { - rect = rgWeapons[i].rcAmmo; - return &rgWeapons[i].hAmmo; - } - else if ( rgWeapons[i].iAmmo2Type == iAmmoId ) - { - rect = rgWeapons[i].rcAmmo2; - return &rgWeapons[i].hAmmo2; - } - } - - return NULL; -} - -void WeaponsResource :: SelectSlot( int iSlot, int fAdvance, int iDirection ) -{ - if ( gHUD.m_Menu.m_fMenuDisplayed && (fAdvance == FALSE) && (iDirection == 1) ) - { // menu is overriding slot use commands - gHUD.m_Menu.SelectMenuItem( iSlot ); - return; - } - - if ( iSlot > MAX_WEAPON_SLOTS ) - return; - - if ( gHUD.m_fPlayerDead || gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) - return; - - WEAPON *p = NULL; - bool fastSwitch = CVAR_GET_FLOAT( "hud_fastswitch" ) != 0; - - if ( (gpActiveSel == NULL) || (gpActiveSel == (WEAPON *)1) || (iSlot != gpActiveSel->iSlot) ) - { - PlaySound( "common/wpn_hudon.wav", 1 ); - p = GetFirstPos( iSlot ); - - if ( p && fastSwitch ) // check for fast weapon switch mode - { - // if fast weapon switch is on, then weapons can be selected in a single keypress - // but only if there is only one item in the bucket - WEAPON *p2 = GetNextActivePos( p->iSlot, p->iSlotPos ); - if ( !p2 ) - { // only one active item in bucket, so change directly to weapon - //ServerCmd( p->szName ); - g_weaponselect = iSlot; - return; - } - } - } - else - { - PlaySound("common/wpn_moveselect.wav", 1); - if ( gpActiveSel ) - p = GetNextActivePos( gpActiveSel->iSlot, gpActiveSel->iSlotPos ); - if ( !p ) - p = GetFirstPos( iSlot ); - } - - - if ( !p ) // no selection found - { - // just display the weapon list, unless fastswitch is on just ignore it - if ( !fastSwitch ) - gpActiveSel = (WEAPON *)1; - else - gpActiveSel = NULL; - } - else - gpActiveSel = p; -} - -//------------------------------------------------------------------------ -// Message Handlers -//------------------------------------------------------------------------ - -// -// AmmoX -- Update the count of a known type of ammo -// -int CHudAmmo::MsgFunc_AmmoX(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - int iIndex = READ_BYTE(); - int iCount = READ_BYTE(); - - gWR.SetAmmo( iIndex, abs(iCount) ); - - return 1; -} - -int CHudAmmo::MsgFunc_AmmoPickup( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - int iIndex = READ_BYTE(); - int iCount = READ_BYTE(); - - // Add ammo to the history - gHR.AddToHistory( HISTSLOT_AMMO, iIndex, abs(iCount) ); - - return 1; -} - -int CHudAmmo::MsgFunc_WeapPickup( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - int iIndex = READ_BYTE(); - - // Add the weapon to the history - gHR.AddToHistory( HISTSLOT_WEAP, iIndex ); - - return 1; -} - -int CHudAmmo::MsgFunc_ItemPickup( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - const char *szName = READ_STRING(); - - // Add the weapon to the history - gHR.AddToHistory( HISTSLOT_ITEM, szName ); - - return 1; -} - - -int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - gHUD.m_iHideHUDDisplay = READ_BYTE(); - - if ( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) - { - static wrect_t nullrc; - gpActiveSel = NULL; - SetCrosshair( 0, nullrc, 0, 0, 0 ); - } - - return 1; -} - -// -// CurWeapon: Update hud state with the current weapon and clip count. Ammo -// counts are updated with AmmoX. Server assures that the Weapon ammo type -// numbers match a real ammo type. -// -int CHudAmmo::MsgFunc_CurWeapon(const char *pszName, int iSize, void *pbuf ) -{ - static wrect_t nullrc; - int fOnTarget = FALSE; - - - BEGIN_READ( pbuf, iSize ); - - int iState = READ_BYTE(); - int iId = READ_BYTE(); - int iClip = READ_CHAR(); - - // detect if we're also on target - if ( iState > 1 ) - { - fOnTarget = TRUE; - } - - if ( iId < 1 ) - { - SetCrosshair(0, nullrc, 0, 0, 0); - return 0; - } - - // Is player dead??? - if ((iId == -1) && (iClip == -1)) - { - gHUD.m_fPlayerDead = TRUE; - gpActiveSel = NULL; - return 1; - } - gHUD.m_fPlayerDead = FALSE; - - WEAPON *pWeapon = gWR.GetWeapon( iId ); - - if ( !pWeapon ) - return 0; - - if ( iClip < -1 ) - pWeapon->iClip = abs(iClip); - else - pWeapon->iClip = iClip; - - - if ( iState == 0 ) // we're not the current weapon, so update no more - return 1; - - m_pWeapon = pWeapon; - - m_fFade = 200.0f; //!!! - m_iFlags |= HUD_ACTIVE; - - return 1; -} - -// -// WeaponList -- Tells the hud about a new weapon type. -// -int CHudAmmo::MsgFunc_WeaponList(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - WEAPON Weapon; - - strcpy( Weapon.szName, READ_STRING() ); - Weapon.iAmmoType = (int)READ_CHAR(); - - Weapon.iMax1 = READ_BYTE(); - if (Weapon.iMax1 == 255) - Weapon.iMax1 = -1; - - Weapon.iAmmo2Type = READ_BYTE(); - Weapon.iMax2 = READ_BYTE(); - if (Weapon.iMax2 == 255) - Weapon.iMax2 = -1; - - Weapon.iSlot = READ_BYTE(); - Weapon.iSlotPos = READ_BYTE(); - Weapon.iId = READ_LONG(); - - Weapon.iFlags = READ_BYTE(); - - Weapon.iClip = 0; - - gWR.AddWeapon( &Weapon ); - - return 1; - -} - -//------------------------------------------------------------------------ -// Command Handlers -//------------------------------------------------------------------------ - -void CHudAmmo::UserCmd_Slot1(void) -{ - gWR.SelectSlot(1, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot2(void) -{ - gWR.SelectSlot(2, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot3(void) -{ - gWR.SelectSlot(3, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot4(void) -{ - gWR.SelectSlot(4, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot5(void) -{ - gWR.SelectSlot(5, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot6(void) -{ - gWR.SelectSlot(6, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot7(void) -{ - gWR.SelectSlot(7, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot8(void) -{ - gWR.SelectSlot(8, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot9(void) -{ - gWR.SelectSlot(9, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot10(void) -{ - gWR.SelectSlot(10, FALSE, 1); -} - -void CHudAmmo::UserCmd_Close(void) -{ - if (gpActiveSel) - { - gpLastSel = gpActiveSel; - gpActiveSel = NULL; - PlaySound("common/wpn_hudoff.wav", 1); - } - else - ClientCmd("escape"); -} - - -// Selects the next item in the weapon menu -void CHudAmmo::UserCmd_NextWeapon(void) -{ - if ( gHUD.m_fPlayerDead || (gHUD.m_iHideHUDDisplay & (HIDEHUD_WEAPONS | HIDEHUD_ALL)) ) - return; - - if ( !gpActiveSel || gpActiveSel == (WEAPON*)1 ) - gpActiveSel = m_pWeapon; - - int pos = 0; - int slot = 0; - if ( gpActiveSel ) - { - pos = gpActiveSel->iSlotPos + 1; - slot = gpActiveSel->iSlot; - } - - for ( int loop = 0; loop <= 1; loop++ ) - { - for ( ; slot < MAX_WEAPON_SLOTS + 1; slot++ ) - { - for ( ; pos < MAX_WEAPON_POSITIONS; pos++ ) - { - WEAPON *wsp = gWR.GetWeaponSlot( slot, pos ); - - if ( wsp && gWR.HasAmmo(wsp) ) - { - gpActiveSel = wsp; - return; - } - } - - pos = 0; - } - - slot = 0; // start looking from the first slot again - } - - gpActiveSel = NULL; -} - -// Selects the previous item in the menu -void CHudAmmo::UserCmd_PrevWeapon(void) -{ - if ( gHUD.m_fPlayerDead || (gHUD.m_iHideHUDDisplay & (HIDEHUD_WEAPONS | HIDEHUD_ALL)) ) - return; - - if ( !gpActiveSel || gpActiveSel == (WEAPON*)1 ) - gpActiveSel = m_pWeapon; - - int pos = MAX_WEAPON_POSITIONS-1; - int slot = MAX_WEAPON_SLOTS; - if ( gpActiveSel ) - { - pos = gpActiveSel->iSlotPos - 1; - slot = gpActiveSel->iSlot; - } - - for ( int loop = 0; loop <= 1; loop++ ) - { - for ( ; slot >= 0; slot-- ) - { - for ( ; pos >= 0; pos-- ) - { - WEAPON *wsp = gWR.GetWeaponSlot( slot, pos ); - - if ( wsp && gWR.HasAmmo(wsp) ) - { - gpActiveSel = wsp; - return; - } - } - - pos = MAX_WEAPON_POSITIONS-1; - } - - slot = MAX_WEAPON_SLOTS; - } - - gpActiveSel = NULL; -} - - - -//------------------------------------------------------------------------- -// Drawing code -//------------------------------------------------------------------------- - -int CHudAmmo::Draw(float flTime) -{ - int a, x, y, r, g, b; - int AmmoWidth; - - int iCrossX; - int iCrossY; - int iCrossLength; - char *chCrossHair = "+"; // Heh - - /*if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) )) - return 1;*/ - - if ( (gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL )) ) - return 1; - - // Draw Weapon Menu - DrawWList(flTime); - - // Draw ammo pickup history - gHR.DrawAmmoHistory( flTime ); - - if (!(m_iFlags & HUD_ACTIVE)) - return 0; - - if (!m_pWeapon) - return 0; - - WEAPON *pw = m_pWeapon; // shorthand - - // SPR_Draw Ammo - if ((pw->iAmmoType < 0) && (pw->iAmmo2Type < 0)) - return 0; - - - int iFlags = DHN_DRAWZERO; // draw 0 values - - AmmoWidth = gHUD.GetSpriteRect(gHUD.m_HUD_number_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).left; - - a = (int) V_max( MIN_ALPHA, m_fFade ); - - if (m_fFade > 0) - m_fFade -= (gHUD.m_flTimeDelta * 20); - - UnpackRGB(r,g,b, RGB_YELLOWISH); - - ScaleColors(r, g, b, a ); - - // Does this weapon have a clip? - y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight/2; - - /******************* DRAW CROSSHAIR *********************/ - iCrossLength = gHUD.m_scrinfo.charWidths[ *chCrossHair ]; - iCrossY = ScreenHeight / 2 - gHUD.m_scrinfo.iCharHeight / 2; - iCrossX = ScreenWidth / 2 - iCrossLength / 2; - - gHUD.DrawHudString( iCrossX, iCrossY, iCrossX + 50, chCrossHair, 170, 170, 170 ); - /******************* DRAW CROSSHAIR *********************/ - - // Does weapon have any ammo at all? - if (m_pWeapon->iAmmoType > 0) - { - int iIconWidth = m_pWeapon->rcAmmo.right - m_pWeapon->rcAmmo.left; - - if (pw->iClip >= 0) - { - x = ScreenWidth - (8 * AmmoWidth) - iIconWidth; - - UnpackRGB(r,g,b, RGB_YELLOWISH); - // GL Seems to need this - ScaleColors( r, g, b, a ); - m_iNumberXPosition = x = gHUD.DrawHudNumber(x, y, iFlags | DHN_3DIGITS, gWR.CountAmmo(pw->iAmmoType), r, g, b); - } - - // Draw the ammo Icon - int iOffset = (m_pWeapon->rcAmmo.bottom - m_pWeapon->rcAmmo.top)/8; - SPR_Set(m_pWeapon->hAmmo, r, g, b); - SPR_DrawAdditive(0, x, y - iOffset, &m_pWeapon->rcAmmo); - - m_iXPosition = x; - } - - return 1; -} - - -// -// Draws the ammo bar on the hud -// -int DrawBar(int x, int y, int width, int height, float f) -{ - int r, g, b; - - if (f < 0) - f = 0; - if (f > 1) - f = 1; - - if (f) - { - int w = f * width; - - // Always show at least one pixel if we have ammo. - if (w <= 0) - w = 1; - UnpackRGB(r, g, b, RGB_GREENISH); - FillRGBA(x, y, w, height, r, g, b, 255); - x += w; - width -= w; - } - - UnpackRGB(r, g, b, RGB_YELLOWISH); - - FillRGBA(x, y, width, height, r, g, b, 128); - - return (x + width); -} - - - -void DrawAmmoBar(WEAPON *p, int x, int y, int width, int height) -{ - if ( !p ) - return; - - if (p->iAmmoType != -1) - { - if (!gWR.CountAmmo(p->iAmmoType)) - return; - - float f = (float)gWR.CountAmmo(p->iAmmoType)/(float)p->iMax1; - - x = DrawBar(x, y, width, height, f); - } -} - - - - -// -// Draw Weapon Menu -// -int CHudAmmo::DrawWList(float flTime) -{ - int r,g,b,x,y,a,i; - - if ( !gpActiveSel ) - return 0; - - int iActiveSlot; - - if ( gpActiveSel == (WEAPON *)1 ) - iActiveSlot = -1; // current slot has no weapons - else - iActiveSlot = gpActiveSel->iSlot; - - x = 10; //!!! - y = 10; //!!! - - - // Ensure that there are available choices in the active slot - if ( iActiveSlot > 0 ) - { - if ( !gWR.GetFirstPos( iActiveSlot ) ) - { - gpActiveSel = (WEAPON *)1; - iActiveSlot = -1; - } - } - - // Draw top line - for ( i = 0; i < MAX_WEAPON_SLOTS; i++ ) - { - int iWidth; - - UnpackRGB(r,g,b, RGB_YELLOWISH); - - if ( iActiveSlot == i ) - a = 255; - else - a = 192; - - ScaleColors(r, g, b, 255); - SPR_Set(gHUD.GetSprite(m_HUD_bucket0 + i), r, g, b ); - - // make active slot wide enough to accomodate gun pictures - if ( i == iActiveSlot ) - { - WEAPON *p = gWR.GetFirstPos(iActiveSlot); - - if ( p ) - iWidth = p->rcActive.right - p->rcActive.left; - } - else - iWidth = giBucketWidth; - - if ( i == iActiveSlot ) - SPR_DrawAdditive(0, x + 104, y, &gHUD.GetSpriteRect(m_HUD_bucket0 + i)); - else - SPR_DrawAdditive(0, x, y, &gHUD.GetSpriteRect(m_HUD_bucket0 + i)); - - x += iWidth + 5; - } - - - a = 128; //!!! - x = 10; - - // Draw all of the buckets - for (i = 1; i < MAX_WEAPON_SLOTS + 1; i++) - { - y = giBucketHeight + 10; - - // If this is the active slot, draw the bigger pictures, - // otherwise just draw boxes - if ( i == iActiveSlot ) - { - WEAPON *p = gWR.GetFirstPos( i ); - int iWidth = giBucketWidth; - if ( p ) - iWidth = p->rcActive.right - p->rcActive.left; - - for ( int iPos = 0; iPos < MAX_WEAPON_POSITIONS; iPos++ ) - { - p = gWR.GetWeaponSlot( i, iPos ); - - if ( !p || !p->iId ) - continue; - - UnpackRGB( r,g,b, RGB_YELLOWISH ); - - // if active, then we must have ammo. - - if ( gpActiveSel == p ) - { - if ( gWR.HasAmmo(p) ) - ScaleColors(r, g, b, 192); - else - { - UnpackRGB(r,g,b, RGB_REDISH); - ScaleColors(r, g, b, 128); - } - - SPR_Set(p->hActive, r, g, b ); - SPR_DrawAdditive(0, x, y, &p->rcActive); - } - else - { - // Draw Weapon if Red if no ammo - - if ( gWR.HasAmmo(p) ) - ScaleColors(r, g, b, 192); - else - { - UnpackRGB(r,g,b, RGB_REDISH); - ScaleColors(r, g, b, 128); - } - - SPR_Set( p->hInactive, r, g, b ); - SPR_DrawAdditive( 0, x, y, &p->rcInactive ); - } - - // Draw Ammo Bar - - DrawAmmoBar(p, x + giABWidth/2, y, giABWidth, giABHeight); - - y += p->rcActive.bottom - p->rcActive.top + 5; - } - - x += iWidth + 5; - - } - else - { - // Draw Row of weapons. - - UnpackRGB(r,g,b, RGB_YELLOWISH); - - for ( int iPos = 0; iPos < MAX_WEAPON_POSITIONS; iPos++ ) - { - WEAPON *p = gWR.GetWeaponSlot( i, iPos ); - - if ( !p || !p->iId ) - continue; - - if ( gWR.HasAmmo(p) ) - { - UnpackRGB(r,g,b, RGB_YELLOWISH); - a = 128; - } - else - { - UnpackRGB(r,g,b, RGB_REDISH); - a = 96; - } - - FillRGBA( x, y, giBucketWidth, giBucketHeight, r, g, b, a ); - - y += giBucketHeight + 5; - } - - x += giBucketWidth + 5; - } - } - - return 1; - -} - - -/* ================================= - GetSpriteList - -Finds and returns the matching -sprite name 'psz' and resolution 'iRes' -in the given sprite list 'pList' -iCount is the number of items in the pList -================================= */ -client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes, int iCount) -{ - if (!pList) - return NULL; - - int i = iCount; - client_sprite_t *p = pList; - - while(i--) - { - if ((!strcmp(psz, p->szName)) && (p->iRes == iRes)) - return p; - p++; - } - - return NULL; -} - - diff --git a/dmc/cl_dll/ammo.h b/dmc/cl_dll/ammo.h deleted file mode 100644 index 5e44065..0000000 --- a/dmc/cl_dll/ammo.h +++ /dev/null @@ -1,62 +0,0 @@ -/*** -* -* 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. -* -****/ - -#ifndef __AMMO_H__ -#define __AMMO_H__ - -#define MAX_WEAPON_NAME 128 - - -#define WEAPON_FLAGS_SELECTONEMPTY 1 - -#define WEAPON_IS_ONTARGET 0x40 - -struct WEAPON -{ - char szName[MAX_WEAPON_NAME]; - int iAmmoType; - int iAmmo2Type; - int iMax1; - int iMax2; - int iSlot; - int iSlotPos; - int iFlags; - int iId; - int iClip; - - int iCount; // # of itesm in plist - - HSPRITE hActive; - wrect_t rcActive; - HSPRITE hInactive; - wrect_t rcInactive; - HSPRITE hAmmo; - wrect_t rcAmmo; - HSPRITE hAmmo2; - wrect_t rcAmmo2; - HSPRITE hCrosshair; - wrect_t rcCrosshair; - HSPRITE hAutoaim; - wrect_t rcAutoaim; - HSPRITE hZoomedCrosshair; - wrect_t rcZoomedCrosshair; - HSPRITE hZoomedAutoaim; - wrect_t rcZoomedAutoaim; -}; - -typedef int AMMO; - - -#endif \ No newline at end of file diff --git a/dmc/cl_dll/ammo_secondary.cpp b/dmc/cl_dll/ammo_secondary.cpp deleted file mode 100644 index 52b1bdf..0000000 --- a/dmc/cl_dll/ammo_secondary.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// ammo_secondary.cpp -// -// implementation of CHudAmmoSecondary class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE( m_AmmoSecondary, SecAmmoVal ); -DECLARE_MESSAGE( m_AmmoSecondary, SecAmmoIcon ); - -int CHudAmmoSecondary :: Init( void ) -{ - HOOK_MESSAGE( SecAmmoVal ); - HOOK_MESSAGE( SecAmmoIcon ); - - gHUD.AddHudElem(this); - m_HUD_ammoicon = 0; - - for ( int i = 0; i < MAX_SEC_AMMO_VALUES; i++ ) - m_iAmmoAmounts[i] = -1; // -1 means don't draw this value - - Reset(); - - return 1; -} - -void CHudAmmoSecondary :: Reset( void ) -{ - m_fFade = 0; -} - -int CHudAmmoSecondary :: VidInit( void ) -{ - return 1; -} - -int CHudAmmoSecondary :: Draw(float flTime) -{ - if ( (gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL )) ) - return 1; - - // draw secondary ammo icons above normal ammo readout - int a, x, y, r, g, b, AmmoWidth; - UnpackRGB( r, g, b, RGB_YELLOWISH ); - a = (int) V_max( MIN_ALPHA, m_fFade ); - if (m_fFade > 0) - m_fFade -= (gHUD.m_flTimeDelta * 20); // slowly lower alpha to fade out icons - ScaleColors( r, g, b, a ); - - AmmoWidth = gHUD.GetSpriteRect(gHUD.m_HUD_number_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).left; - - y = ScreenHeight - (gHUD.m_iFontHeight*4); // this is one font height higher than the weapon ammo values - x = ScreenWidth - AmmoWidth; - - if ( m_HUD_ammoicon ) - { - // Draw the ammo icon - x -= (gHUD.GetSpriteRect(m_HUD_ammoicon).right - gHUD.GetSpriteRect(m_HUD_ammoicon).left); - y -= (gHUD.GetSpriteRect(m_HUD_ammoicon).top - gHUD.GetSpriteRect(m_HUD_ammoicon).bottom); - - SPR_Set( gHUD.GetSprite(m_HUD_ammoicon), r, g, b ); - SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(m_HUD_ammoicon) ); - } - else - { // move the cursor by the '0' char instead, since we don't have an icon to work with - x -= AmmoWidth; - y -= (gHUD.GetSpriteRect(gHUD.m_HUD_number_0).top - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).bottom); - } - - // draw the ammo counts, in reverse order, from right to left - for ( int i = MAX_SEC_AMMO_VALUES-1; i >= 0; i-- ) - { - if ( m_iAmmoAmounts[i] < 0 ) - continue; // negative ammo amounts imply that they shouldn't be drawn - - // half a char gap between the ammo number and the previous pic - x -= (AmmoWidth / 2); - - // draw the number, right-aligned - x -= (gHUD.GetNumWidth( m_iAmmoAmounts[i], DHN_DRAWZERO ) * AmmoWidth); - gHUD.DrawHudNumber( x, y, DHN_DRAWZERO, m_iAmmoAmounts[i], r, g, b ); - - if ( i != 0 ) - { - // draw the divider bar - x -= (AmmoWidth / 2); - FillRGBA(x, y, (AmmoWidth/10), gHUD.m_iFontHeight, r, g, b, a); - } - } - - return 1; -} - -// Message handler for Secondary Ammo Value -// accepts one value: -// string: sprite name -int CHudAmmoSecondary :: MsgFunc_SecAmmoIcon( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - m_HUD_ammoicon = gHUD.GetSpriteIndex( READ_STRING() ); - - return 1; -} - -// Message handler for Secondary Ammo Icon -// Sets an ammo value -// takes two values: -// byte: ammo index -// byte: ammo value -int CHudAmmoSecondary :: MsgFunc_SecAmmoVal( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int index = READ_BYTE(); - if ( index < 0 || index >= MAX_SEC_AMMO_VALUES ) - return 1; - - m_iAmmoAmounts[index] = READ_BYTE(); - m_iFlags |= HUD_ACTIVE; - - // check to see if there is anything left to draw - int count = 0; - for ( int i = 0; i < MAX_SEC_AMMO_VALUES; i++ ) - { - count += V_max( 0, m_iAmmoAmounts[i] ); - } - - if ( count == 0 ) - { // the ammo fields are all empty, so turn off this hud area - m_iFlags &= ~HUD_ACTIVE; - return 1; - } - - // make the icons light up - m_fFade = 200.0f; - - return 1; -} - - diff --git a/dmc/cl_dll/ammohistory.cpp b/dmc/cl_dll/ammohistory.cpp deleted file mode 100644 index 8668fd4..0000000 --- a/dmc/cl_dll/ammohistory.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// ammohistory.cpp -// - - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -#include "ammohistory.h" - -HistoryResource gHR; - -#define AMMO_PICKUP_GAP (gHR.iHistoryGap+5) -#define AMMO_PICKUP_PICK_HEIGHT (32 + (gHR.iHistoryGap * 2)) -#define AMMO_PICKUP_HEIGHT_MAX (ScreenHeight - 100) - -#define MAX_ITEM_NAME 32 -int HISTORY_DRAW_TIME = 5; - -// keep a list of items -struct ITEM_INFO -{ - char szName[MAX_ITEM_NAME]; - HSPRITE spr; - wrect_t rect; -}; - -void HistoryResource :: AddToHistory( int iType, int iId, int iCount ) -{ - if ( iType == HISTSLOT_AMMO && !iCount ) - return; // no amount, so don't add - - if ( (((AMMO_PICKUP_GAP * iCurrentHistorySlot) + AMMO_PICKUP_PICK_HEIGHT) > AMMO_PICKUP_HEIGHT_MAX) || (iCurrentHistorySlot >= MAX_HISTORY) ) - { // the pic would have to be drawn too high - // so start from the bottom - iCurrentHistorySlot = 0; - } - - HIST_ITEM *freeslot = &rgAmmoHistory[iCurrentHistorySlot++]; // default to just writing to the first slot - HISTORY_DRAW_TIME = CVAR_GET_FLOAT( "hud_drawhistory_time" ); - - freeslot->type = iType; - freeslot->iId = iId; - freeslot->iCount = iCount; - freeslot->DisplayTime = gHUD.m_flTime + HISTORY_DRAW_TIME; -} - -void HistoryResource :: AddToHistory( int iType, const char *szName, int iCount ) -{ - if ( iType != HISTSLOT_ITEM ) - return; - - if ( (((AMMO_PICKUP_GAP * iCurrentHistorySlot) + AMMO_PICKUP_PICK_HEIGHT) > AMMO_PICKUP_HEIGHT_MAX) || (iCurrentHistorySlot >= MAX_HISTORY) ) - { // the pic would have to be drawn too high - // so start from the bottom - iCurrentHistorySlot = 0; - } - - HIST_ITEM *freeslot = &rgAmmoHistory[iCurrentHistorySlot++]; // default to just writing to the first slot - - // I am really unhappy with all the code in this file - - int i = gHUD.GetSpriteIndex( szName ); - if ( i == -1 ) - return; // unknown sprite name, don't add it to history - - freeslot->iId = i; - freeslot->type = iType; - freeslot->iCount = iCount; - - HISTORY_DRAW_TIME = CVAR_GET_FLOAT( "hud_drawhistory_time" ); - freeslot->DisplayTime = gHUD.m_flTime + HISTORY_DRAW_TIME; -} - - -void HistoryResource :: CheckClearHistory( void ) -{ - for ( int i = 0; i < MAX_HISTORY; i++ ) - { - if ( rgAmmoHistory[i].type ) - return; - } - - iCurrentHistorySlot = 0; -} - -// -// Draw Ammo pickup history -// -int HistoryResource :: DrawAmmoHistory( float flTime ) -{ - for ( int i = 0; i < MAX_HISTORY; i++ ) - { - if ( rgAmmoHistory[i].type ) - { - rgAmmoHistory[i].DisplayTime = V_min( rgAmmoHistory[i].DisplayTime, gHUD.m_flTime + HISTORY_DRAW_TIME ); - - if ( rgAmmoHistory[i].DisplayTime <= flTime ) - { // pic drawing time has expired - memset( &rgAmmoHistory[i], 0, sizeof(HIST_ITEM) ); - CheckClearHistory(); - } - else if ( rgAmmoHistory[i].type == HISTSLOT_AMMO ) - { - wrect_t rcPic; - HSPRITE *spr = gWR.GetAmmoPicFromWeapon( rgAmmoHistory[i].iId, rcPic ); - - int r, g, b; - UnpackRGB(r,g,b, RGB_YELLOWISH); - float scale = (rgAmmoHistory[i].DisplayTime - flTime) * 80; - ScaleColors(r, g, b, V_min(scale, 255) ); - - // Draw the pic - int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth - 24; - if ( spr && *spr ) // weapon isn't loaded yet so just don't draw the pic - { // the dll has to make sure it has sent info the weapons you need - SPR_Set( *spr, r, g, b ); - SPR_DrawAdditive( 0, xpos, ypos, &rcPic ); - } - - // Draw the number - gHUD.DrawHudNumberString( xpos - 10, ypos, xpos - 100, rgAmmoHistory[i].iCount, r, g, b ); - } - else if ( rgAmmoHistory[i].type == HISTSLOT_WEAP ) - { - WEAPON *weap = gWR.GetWeapon( rgAmmoHistory[i].iId ); - - if ( !weap ) - return 1; // we don't know about the weapon yet, so don't draw anything - - int r, g, b; - UnpackRGB(r,g,b, RGB_YELLOWISH); - - if ( !gWR.HasAmmo( weap ) ) - UnpackRGB(r,g,b, RGB_REDISH); // if the weapon doesn't have ammo, display it as red - - float scale = (rgAmmoHistory[i].DisplayTime - flTime) * 80; - ScaleColors(r, g, b, V_min(scale, 255) ); - - int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth - (weap->rcInactive.right - weap->rcInactive.left); - SPR_Set( weap->hInactive, r, g, b ); - SPR_DrawAdditive( 0, xpos, ypos, &weap->rcInactive ); - } - else if ( rgAmmoHistory[i].type == HISTSLOT_ITEM ) - { - int r, g, b; - - if ( !rgAmmoHistory[i].iId ) - continue; // sprite not loaded - - wrect_t rect = gHUD.GetSpriteRect( rgAmmoHistory[i].iId ); - - UnpackRGB(r,g,b, RGB_YELLOWISH); - float scale = (rgAmmoHistory[i].DisplayTime - flTime) * 80; - ScaleColors(r, g, b, V_min(scale, 255) ); - - int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth - (rect.right - rect.left) - 10; - - SPR_Set( gHUD.GetSprite( rgAmmoHistory[i].iId ), r, g, b ); - SPR_DrawAdditive( 0, xpos, ypos, &rect ); - } - } - } - - - return 1; -} - - diff --git a/dmc/cl_dll/ammohistory.h b/dmc/cl_dll/ammohistory.h deleted file mode 100644 index 5da8921..0000000 --- a/dmc/cl_dll/ammohistory.h +++ /dev/null @@ -1,144 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// ammohistory.h -// - -// this is the max number of items in each bucket -#define MAX_WEAPON_POSITIONS 1 - -class WeaponsResource -{ -private: - // Information about weapons & ammo - WEAPON rgWeapons[MAX_WEAPONS]; // Weapons Array - - // counts of weapons * ammo - WEAPON* rgSlots[MAX_WEAPON_SLOTS+1][MAX_WEAPON_POSITIONS+1]; // The slots currently in use by weapons. The value is a pointer to the weapon; if it's NULL, no weapon is there - int riAmmo[MAX_AMMO_TYPES]; // count of each ammo type - -public: - void Init( void ) - { - memset( rgWeapons, 0, sizeof rgWeapons ); - Reset(); - } - - void Reset( void ) - { - iOldWeaponBits = 0; - memset( rgSlots, 0, sizeof rgSlots ); - memset( riAmmo, 0, sizeof riAmmo ); - } - -///// WEAPON ///// - int iOldWeaponBits; - - WEAPON *GetWeapon( int iId ) { return &rgWeapons[iId]; } - void AddWeapon( WEAPON *wp ) - { - rgWeapons[ wp->iId ] = *wp; - LoadWeaponSprites( &rgWeapons[ wp->iId ] ); - } - - void PickupWeapon( WEAPON *wp ) - { - rgSlots[ wp->iSlot ][ 0 ] = wp; - } - - void DropWeapon( WEAPON *wp ) - { - rgSlots[ wp->iSlot ][ 0 ] = NULL; - } - - void DropAllWeapons( void ) - { - for ( int i = 0; i < MAX_WEAPONS; i++ ) - { - if ( rgWeapons[i].iId ) - DropWeapon( &rgWeapons[i] ); - } - } - - WEAPON* GetWeaponSlot( int slot, int pos ) { return rgSlots[slot][pos]; } - - void LoadWeaponSprites( WEAPON* wp ); - void LoadAllWeaponSprites( void ); - WEAPON* GetFirstPos( int iSlot ); - void SelectSlot( int iSlot, int fAdvance, int iDirection ); - WEAPON* GetNextActivePos( int iSlot, int iSlotPos ); - - int HasAmmo( WEAPON *p ); - -///// AMMO ///// - AMMO GetAmmo( int iId ) { return iId; } - - void SetAmmo( int iId, int iCount ) { riAmmo[ iId ] = iCount; } - - int CountAmmo( int iId ); - - HSPRITE* GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect ); - -}; - -extern WeaponsResource gWR; - - -#define MAX_HISTORY 12 -enum { - HISTSLOT_EMPTY, - HISTSLOT_AMMO, - HISTSLOT_WEAP, - HISTSLOT_ITEM, -}; - -class HistoryResource -{ -private: - struct HIST_ITEM { - int type; - float DisplayTime; // the time at which this item should be removed from the history - int iCount; - int iId; - }; - - HIST_ITEM rgAmmoHistory[MAX_HISTORY]; - -public: - - void Init( void ) - { - Reset(); - } - - void Reset( void ) - { - memset( rgAmmoHistory, 0, sizeof rgAmmoHistory ); - } - - int iHistoryGap; - int iCurrentHistorySlot; - - void AddToHistory( int iType, int iId, int iCount = 0 ); - void AddToHistory( int iType, const char *szName, int iCount = 0 ); - - void CheckClearHistory( void ); - int DrawAmmoHistory( float flTime ); -}; - -extern HistoryResource gHR; - - - diff --git a/dmc/cl_dll/battery.cpp b/dmc/cl_dll/battery.cpp deleted file mode 100644 index eb8e985..0000000 --- a/dmc/cl_dll/battery.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// battery.cpp -// -// implementation of CHudBattery class -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -DECLARE_MESSAGE(m_Battery, Battery) - -int CHudBattery::Init(void) -{ - m_iBat = 0; - m_fFade = 0; - m_iFlags = 0; - - HOOK_MESSAGE(Battery); - - gHUD.AddHudElem(this); - - return 1; -}; - - -int CHudBattery::VidInit(void) -{ - int HUD_suit_empty = gHUD.GetSpriteIndex( "suit_empty" ); - int HUD_suit_full = gHUD.GetSpriteIndex( "suit_full" ); - - m_hSprite1 = m_hSprite2 = 0; // delaying get sprite handles until we know the sprites are loaded - m_prc1 = &gHUD.GetSpriteRect( HUD_suit_empty ); - m_prc2 = &gHUD.GetSpriteRect( HUD_suit_full ); - m_iHeight = m_prc2->bottom - m_prc1->top; - m_fFade = 0; - return 1; -}; - -int CHudBattery:: MsgFunc_Battery(const char *pszName, int iSize, void *pbuf ) -{ - m_iFlags |= HUD_ACTIVE; - - - BEGIN_READ( pbuf, iSize ); - int x = READ_SHORT(); - - if (x != m_iBat) - { - m_fFade = FADE_TIME; - m_iBat = x; - } - - return 1; -} - - -int CHudBattery::Draw(float flTime) -{ - if ( gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH ) - return 1; - - int r, g, b, x, y, a; - wrect_t rc; - - rc = *m_prc2; - rc.top += m_iHeight * ((float)(100-(V_min(100,m_iBat))) * 0.01); // battery can go from 0 to 100 so * 0.01 goes from 0 to 1 - - UnpackRGB(r,g,b, RGB_YELLOWISH); - - // Has health changed? Flash the health # - if (m_fFade) - { - if (m_fFade > FADE_TIME) - m_fFade = FADE_TIME; - - m_fFade -= (gHUD.m_flTimeDelta * 20); - if (m_fFade <= 0) - { - a = 128; - m_fFade = 0; - } - - // Fade the health number back to dim - - a = MIN_ALPHA + (m_fFade/FADE_TIME) * 128; - - } - else - a = MIN_ALPHA; - - ScaleColors(r, g, b, a ); - - int iOffset = (m_prc1->bottom - m_prc1->top)/6; - - y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight / 2; - x = ScreenWidth/5; - - // make sure we have the right sprite handles - if ( !m_hSprite1 ) - m_hSprite1 = gHUD.GetSprite( gHUD.GetSpriteIndex( "suit_empty" ) ); - if ( !m_hSprite2 ) - m_hSprite2 = gHUD.GetSprite( gHUD.GetSpriteIndex( "suit_full" ) ); - - SPR_Set(m_hSprite1, r, g, b ); - SPR_DrawAdditive( 0, x, y - iOffset, m_prc1); - - if (rc.bottom > rc.top) - { - SPR_Set(m_hSprite2, r, g, b ); - SPR_DrawAdditive( 0, x, y - iOffset + (rc.top - m_prc2->top), &rc); - } - - x += (m_prc1->right - m_prc1->left); - x = gHUD.DrawHudNumber(x, y, DHN_3DIGITS | DHN_DRAWZERO, m_iBat, r, g, b); - - return 1; -} \ No newline at end of file diff --git a/dmc/cl_dll/camera.h b/dmc/cl_dll/camera.h deleted file mode 100644 index 08c8792..0000000 --- a/dmc/cl_dll/camera.h +++ /dev/null @@ -1,24 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// Camera.h -- defines and such for a 3rd person camera -// NOTE: must include quakedef.h first - -#ifndef _CAMERA_H_ -#define _CAMERA_H_ - -// pitch, yaw, dist -extern vec3_t cam_ofs; -// Using third person camera -extern int cam_thirdperson; - -void CAM_Init( void ); -void CAM_ClearStates( void ); -void CAM_StartMouseMove(void); -void CAM_EndMouseMove(void); - -#endif // _CAMERA_H_ diff --git a/dmc/cl_dll/cdll_int.cpp b/dmc/cl_dll/cdll_int.cpp deleted file mode 100644 index 579d61c..0000000 --- a/dmc/cl_dll/cdll_int.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// -// cdll_int.c -// -// this implementation handles the linking of the engine to the DLL -// - -#include "hud.h" -#include "cl_util.h" -#include -#include "netadr.h" -#include "vgui_int.h" -#include "voice_status.h" - -#include "FileSystem.h" - -#include "interface.h" -#include "vgui_SchemeManager.h" - -#include "Platform.h" - -CSysModule *g_pFileSystemModule = NULL; -IFileSystem *g_pFileSystem = NULL; - -CSysModule *g_hTrackerModule = NULL; - -cl_enginefunc_t gEngfuncs; -CHud gHUD; -TeamFortressViewport *gViewPort = NULL; - -#include "pm_shared.h" - -#include "hud_servers.h" - -void InitInput (void); -void EV_HookEvents( void ); -void IN_Commands( void ); - -/* -========================== - Initialize - -Called when the DLL is first loaded. -========================== -*/ -extern "C" -{ -int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ); -int DLLEXPORT HUD_VidInit( void ); -int DLLEXPORT HUD_Init( void ); -int DLLEXPORT HUD_Redraw( float flTime, int intermission ); -int DLLEXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime ); -int DLLEXPORT HUD_Reset ( void ); -void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ); -void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ); -char DLLEXPORT HUD_PlayerMoveTexture( char *name ); -int DLLEXPORT HUD_ConnectionlessPacket( struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); -int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ); -void DLLEXPORT HUD_Frame( double time ); -void DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ); -void DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking); -void DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf ); -} - -/* -================================ -HUD_GetHullBounds - - Engine calls this to enumerate player collision hulls, for prediction. Return 0 if the hullnumber doesn't exist. -================================ -*/ -int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ) -{ - int iret = 0; - - switch ( hullnumber ) - { - case 0: // Normal player - mins = Vector(-16, -16, -32); - maxs = Vector(16, 16, 32); - iret = 1; - break; - case 1: // Crouched player - mins = Vector(-16, -16, -32); - maxs = Vector(16, 16, 32); - iret = 1; - break; - case 2: // Point based hull - mins = Vector( 0, 0, 0 ); - maxs = Vector( 0, 0, 0 ); - iret = 1; - break; - } - - return iret; -} - -/* -================================ -HUD_ConnectionlessPacket - - Return 1 if the packet is valid. Set response_buffer_size if you want to send a response packet. Incoming, it holds the max - size of the response_buffer, so you must zero it out if you choose not to respond. -================================ -*/ -int DLLEXPORT HUD_ConnectionlessPacket( struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ) -{ - // Parse stuff from args - int max_buffer_size = *response_buffer_size; - - // Zero it out since we aren't going to respond. - // If we wanted to response, we'd write data into response_buffer - *response_buffer_size = 0; - - // Since we don't listen for anything here, just respond that it's a bogus message - // If we didn't reject the message, we'd return 1 for success instead. - return 0; -} - -void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ) -{ - PM_Init( ppmove ); -} - -char DLLEXPORT HUD_PlayerMoveTexture( char *name ) -{ - return PM_FindTextureType( name ); -} - -void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ) -{ - PM_Move( ppmove, server ); -} - -int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ) -{ - gEngfuncs = *pEnginefuncs; - - //!!! mwh UNDONE We need to think about our versioning strategy. Do we want to try to be compatible - // with previous versions, especially when we're only 'bonus' functionality? Should it be the engine - // that decides if the DLL is compliant? - - if (iVersion != CLDLL_INTERFACE_VERSION) - return 0; - - memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t)); - - EV_HookEvents(); - - // Determine which filesystem to use. -#if defined ( _WIN32 ) - char *szFsModule = "filesystem_stdio.dll"; -#elif defined(OSX) - char *szFsModule = "filesystem_stdio.dylib"; -#elif defined(LINUX) - char *szFsModule = "filesystem_stdio.so"; -#else -#error -#endif - - - char szFSDir[MAX_PATH]; - szFSDir[0] = 0; - if ( gEngfuncs.COM_ExpandFilename( szFsModule, szFSDir, sizeof( szFSDir ) ) == FALSE ) - { - return false; - } - - // Get filesystem interface. - g_pFileSystemModule = Sys_LoadModule( szFSDir ); - assert( g_pFileSystemModule ); - if( !g_pFileSystemModule ) - { - return false; - } - - CreateInterfaceFn fileSystemFactory = Sys_GetFactory( g_pFileSystemModule ); - if( !fileSystemFactory ) - { - return false; - } - - g_pFileSystem = ( IFileSystem * )fileSystemFactory( FILESYSTEM_INTERFACE_VERSION, NULL ); - assert( g_pFileSystem ); - if( !g_pFileSystem ) - { - return false; - } - - return 1; -} - - -/* -========================== - HUD_VidInit - -Called when the game initializes -and whenever the vid_mode is changed -so the HUD can reinitialize itself. -========================== -*/ - -int DLLEXPORT HUD_VidInit( void ) -{ - gHUD.VidInit(); - - VGui_Startup(); - - return 1; -} - -/* -========================== - HUD_Init - -Called whenever the client connects -to a server. Reinitializes all -the hud variables. -========================== -*/ - -int DLLEXPORT HUD_Init( void ) -{ - InitInput(); - gHUD.Init(); - Scheme_Init(); - - return 1; -} - - -/* -========================== - HUD_Redraw - -called every screen frame to -redraw the HUD. -=========================== -*/ - -int DLLEXPORT HUD_Redraw( float time, int intermission ) -{ - gHUD.Redraw( time, intermission ); - - return 1; -} - - -/* -========================== - HUD_UpdateClientData - -called every time shared client -dll/engine data gets changed, -and gives the cdll a chance -to modify the data. - -returns 1 if anything has been changed, 0 otherwise. -========================== -*/ - -int DLLEXPORT HUD_UpdateClientData(client_data_t *pcldata, float flTime ) -{ - return gHUD.UpdateClientData(pcldata, flTime ); -} - -/* -========================== - HUD_Reset - -Called at start and end of demos to restore to "non"HUD state. -========================== -*/ - -int DLLEXPORT HUD_Reset( void ) -{ - gHUD.VidInit(); - return 1; -} - -/* -========================== -HUD_Frame - -Called by engine every frame that client .dll is loaded -========================== -*/ - -void DLLEXPORT HUD_Frame( double time ) -{ - IN_Commands(); - - ServersThink( time ); - - GetClientVoiceMgr()->Frame(time); -} - - -/* -========================== -HUD_VoiceStatus - -Called when a player starts or stops talking. -========================== -*/ - -void DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking) -{ - GetClientVoiceMgr()->UpdateSpeakerStatus(entindex, bTalking); -} - -/* -========================== -HUD_DirectorMessage - -Called when a director event message was received -========================== -*/ - -void DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf ) -{ - gHUD.m_Spectator.DirectorMessage( iSize, pbuf ); -} diff --git a/dmc/cl_dll/cl_dll.dsp b/dmc/cl_dll/cl_dll.dsp deleted file mode 100644 index d64a514..0000000 --- a/dmc/cl_dll/cl_dll.dsp +++ /dev/null @@ -1,598 +0,0 @@ -# Microsoft Developer Studio Project File - Name="cl_dll" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=cl_dll - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "cl_dll.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "cl_dll.mak" CFG="cl_dll - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "cl_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "cl_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$/GoldSrc/dmc/cl_dlls", STQCAAAA" -# PROP Scc_LocalPath "." -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "cl_dll - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir ".\Release" -# PROP BASE Intermediate_Dir ".\Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\Release" -# PROP Intermediate_Dir ".\Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\utils\common" /I "..\..\public" /I "..\engine" /I "..\common" /I "..\utils\vgui\include" /I "..\dlls" /I "..\..\engine" /I "..\..\common" /I "..\pm_shared" /I "..\..\utils\vgui\include" /I "." /I "..\..\game_shared" /I "..\..\external" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "CLIENT_DLL" /D "DMC_BUILD" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ..\..\utils\vgui\lib\win32_vc6\vgui.lib wsock32.lib ..\..\lib\public\sdl2.lib /nologo /subsystem:windows /dll /map /debug /machine:I386 /out:".\Release\client.dll" -# Begin Custom Build - Copying to cl_dlls -InputDir=.\Release -ProjDir=. -InputPath=.\Release\client.dll -SOURCE="$(InputPath)" - -BuildCmds= \ - call ..\..\filecopy.bat $(InputPath) $(ProjDir)\..\..\..\game\mod\cl_dlls\client.dll \ - call ..\..\filecopy.bat $(InputDir)\client.pdb $(ProjDir)\..\..\..\game\mod\cl_dlls\client.pdb \ - - -"..\..\..\game\mod\cl_dlls\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) - -"..\..\..\game\mod\cl_dlls\client.pdb" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) -# End Custom Build - -!ELSEIF "$(CFG)" == "cl_dll - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir ".\Debug" -# PROP BASE Intermediate_Dir ".\Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\Debug" -# PROP Intermediate_Dir ".\Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MTd /W3 /GX /ZI /Od /I "..\..\public" /I "..\engine" /I "..\common" /I "..\utils\vgui\include" /I "..\dlls" /I "..\..\engine" /I "..\..\common" /I "..\pm_shared" /I "..\..\utils\vgui\include" /I "." /I "..\..\game_shared" /I "..\..\external" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "CLIENT_DLL" /D "DMC_BUILD" /FR /Fp".\Release/cl_dll.pch" /YX /Fo".\Release/" /Fd".\Release/" /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ..\..\utils\vgui\lib\win32_vc6\vgui.lib wsock32.lib ..\..\lib\public\sdl2.lib /nologo /subsystem:windows /dll /profile /map /debug /machine:I386 /out:".\Debug\client.dll" -# Begin Custom Build - Copying to cl_dlls -InputDir=.\Debug -ProjDir=. -InputPath=.\Debug\client.dll -SOURCE="$(InputPath)" - -BuildCmds= \ - call ..\..\filecopy.bat $(InputPath) $(ProjDir)\..\..\..\game\mod\cl_dlls\client.dll \ - call ..\..\filecopy.bat $(InputDir)\client.pdb $(ProjDir)\..\..\..\game\mod\cl_dlls\client.pdb \ - - -"..\..\..\game\mod\cl_dlls\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) - -"..\..\..\game\mod\cl_dlls\client.pdb" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) -# End Custom Build - -!ENDIF - -# Begin Target - -# Name "cl_dll - Win32 Release" -# Name "cl_dll - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90" -# Begin Group "quake" - -# PROP Default_Filter "*.cpp" -# Begin Source File - -SOURCE=.\CTF_FlagStatus.cpp -# End Source File -# Begin Source File - -SOURCE=.\CTF_HudMessage.cpp -# End Source File -# Begin Source File - -SOURCE=.\DMC_Teleporters.cpp -# End Source File -# Begin Source File - -SOURCE=.\ev_hldm.cpp -# End Source File -# Begin Source File - -SOURCE=.\quake\quake_baseentity.cpp -# End Source File -# Begin Source File - -SOURCE=.\quake\quake_events.cpp -# End Source File -# Begin Source File - -SOURCE=..\dlls\quake_gun.cpp -# End Source File -# Begin Source File - -SOURCE=.\quake\quake_objects.cpp -# End Source File -# Begin Source File - -SOURCE=.\quake\quake_weapons.cpp -# End Source File -# Begin Source File - -SOURCE=..\dlls\quake_weapons_all.cpp -# End Source File -# Begin Source File - -SOURCE=.\studio_util.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_SpectatorPanel.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=.\ammo.cpp -# End Source File -# Begin Source File - -SOURCE=.\ammo_secondary.cpp -# End Source File -# Begin Source File - -SOURCE=.\ammohistory.cpp -# End Source File -# Begin Source File - -SOURCE=.\battery.cpp -# End Source File -# Begin Source File - -SOURCE=.\cdll_int.cpp -# End Source File -# Begin Source File - -SOURCE=.\com_weapons.cpp -# End Source File -# Begin Source File - -SOURCE=.\death.cpp -# End Source File -# Begin Source File - -SOURCE=.\demo.cpp -# End Source File -# Begin Source File - -SOURCE=.\entity.cpp -# End Source File -# Begin Source File - -SOURCE=.\ev_common.cpp -# End Source File -# Begin Source File - -SOURCE=.\events.cpp -# End Source File -# Begin Source File - -SOURCE=.\GameStudioModelRenderer.cpp -# End Source File -# Begin Source File - -SOURCE=.\geiger.cpp -# End Source File -# Begin Source File - -SOURCE=.\health.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud_msg.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud_redraw.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud_servers.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud_spectator.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud_update.cpp -# End Source File -# Begin Source File - -SOURCE=.\in_camera.cpp -# End Source File -# Begin Source File - -SOURCE=.\input.cpp -# End Source File -# Begin Source File - -SOURCE=.\inputw32.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\public\interface.cpp -# End Source File -# Begin Source File - -SOURCE=.\menu.cpp -# End Source File -# Begin Source File - -SOURCE=.\message.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\common\parsemsg.cpp -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_debug.c -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_math.c -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_shared.c -# End Source File -# Begin Source File - -SOURCE=.\saytext.cpp -# End Source File -# Begin Source File - -SOURCE=.\scoreboard.cpp -# PROP Exclude_From_Build 1 -# End Source File -# Begin Source File - -SOURCE=.\status_icons.cpp -# End Source File -# Begin Source File - -SOURCE=.\statusbar.cpp -# End Source File -# Begin Source File - -SOURCE=.\StudioModelRenderer.cpp -# End Source File -# Begin Source File - -SOURCE=.\text_message.cpp -# End Source File -# Begin Source File - -SOURCE=.\train.cpp -# End Source File -# Begin Source File - -SOURCE=.\tri.cpp -# End Source File -# Begin Source File - -SOURCE=.\util.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_checkbutton2.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_grid.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_helpers.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_int.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_listbox.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_loadtga.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_ScorePanel.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_scrollbar2.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_ServerBrowser.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_slider2.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_viewport.cpp -# End Source File -# Begin Source File - -SOURCE=.\view.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\voice_banmgr.cpp -# End Source File -# Begin Source File - -SOURCE=.\voice_status.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" -# Begin Source File - -SOURCE=.\ammo.h -# End Source File -# Begin Source File - -SOURCE=.\ammohistory.h -# End Source File -# Begin Source File - -SOURCE=.\camera.h -# End Source File -# Begin Source File - -SOURCE=.\cl_dll.h -# End Source File -# Begin Source File - -SOURCE=.\cl_util.h -# End Source File -# Begin Source File - -SOURCE=.\com_weapons.h -# End Source File -# Begin Source File - -SOURCE=.\demo.h -# End Source File -# Begin Source File - -SOURCE=.\DMC_BSPFile.h -# End Source File -# Begin Source File - -SOURCE=.\DMC_Teleporters.h -# End Source File -# Begin Source File - -SOURCE=.\ev_hldm.h -# End Source File -# Begin Source File - -SOURCE=.\eventscripts.h -# End Source File -# Begin Source File - -SOURCE=.\GameStudioModelRenderer.h -# End Source File -# Begin Source File - -SOURCE=.\health.h -# End Source File -# Begin Source File - -SOURCE=.\hud.h -# End Source File -# Begin Source File - -SOURCE=.\hud_iface.h -# End Source File -# Begin Source File - -SOURCE=.\hud_servers.h -# End Source File -# Begin Source File - -SOURCE=.\hud_servers_priv.h -# End Source File -# Begin Source File - -SOURCE=.\hud_spectator.h -# End Source File -# Begin Source File - -SOURCE=.\in_defs.h -# End Source File -# Begin Source File - -SOURCE=.\kbutton.h -# End Source File -# Begin Source File - -SOURCE=..\..\common\parsemsg.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_debug.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_defs.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_info.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_materials.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_movevars.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_shared.h -# End Source File -# Begin Source File - -SOURCE=..\dlls\quake_gun.h -# End Source File -# Begin Source File - -SOURCE=.\StudioModelRenderer.h -# End Source File -# Begin Source File - -SOURCE=.\util.h -# End Source File -# Begin Source File - -SOURCE=.\util_vector.h -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_checkbutton2.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_ControlConfigPanel.h -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_grid.h -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_helpers.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_int.h -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_listbox.h -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_loadtga.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_SchemeManager.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_ScorePanel.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_ServerBrowser.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_SpectatorPanel.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_viewport.h -# End Source File -# Begin Source File - -SOURCE=.\view.h -# End Source File -# Begin Source File - -SOURCE=.\voice_status.h -# End Source File -# Begin Source File - -SOURCE=.\wrect.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" -# End Group -# Begin Source File - -SOURCE=.\vgui_CustomObjects.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_MOTDWindow.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_SchemeManager.cpp -# End Source File -# End Target -# End Project diff --git a/dmc/cl_dll/cl_dll.h b/dmc/cl_dll/cl_dll.h deleted file mode 100644 index ca15f58..0000000 --- a/dmc/cl_dll/cl_dll.h +++ /dev/null @@ -1,40 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// cl_dll.h -// - -// 4-23-98 JOHN - -// -// This DLL is linked by the client when they first initialize. -// This DLL is responsible for the following tasks: -// - Loading the HUD graphics upon initialization -// - Drawing the HUD graphics every frame -// - Handling the custum HUD-update packets -// - -#include "Platform.h" - -typedef unsigned char byte; -typedef unsigned short word; -typedef float vec_t; -typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf); - -#include "util_vector.h" -#include "../engine/cdll_int.h" -#include "../dlls/cdll_dll.h" - -extern cl_enginefunc_t gEngfuncs; diff --git a/dmc/cl_dll/cl_util.h b/dmc/cl_dll/cl_util.h deleted file mode 100644 index d67ebbe..0000000 --- a/dmc/cl_dll/cl_util.h +++ /dev/null @@ -1,188 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// cl_util.h -// - -#include "cvardef.h" - -#include "Platform.h" - - -// Macros to hook function calls into the HUD object -#define HOOK_MESSAGE(x) gEngfuncs.pfnHookUserMsg(#x, __MsgFunc_##x ); - -#define DECLARE_MESSAGE(y, x) int __MsgFunc_##x(const char *pszName, int iSize, void *pbuf) \ - { \ - return gHUD.y.MsgFunc_##x(pszName, iSize, pbuf ); \ - } - - -#define HOOK_COMMAND(x, y) gEngfuncs.pfnAddCommand( x, __CmdFunc_##y ); -#define DECLARE_COMMAND(y, x) void __CmdFunc_##x( void ) \ - { \ - gHUD.y.UserCmd_##x( ); \ - } - -inline float CVAR_GET_FLOAT( const char *x ) { return gEngfuncs.pfnGetCvarFloat( (char*)x ); } -inline char* CVAR_GET_STRING( const char *x ) { return gEngfuncs.pfnGetCvarString( (char*)x ); } -inline struct cvar_s *CVAR_CREATE( const char *cv, const char *val, const int flags ) { return gEngfuncs.pfnRegisterVariable( (char*)cv, (char*)val, flags ); } - -#define SPR_Load (*gEngfuncs.pfnSPR_Load) -#define SPR_Set (*gEngfuncs.pfnSPR_Set) -#define SPR_Frames (*gEngfuncs.pfnSPR_Frames) -#define SPR_GetList (*gEngfuncs.pfnSPR_GetList) - -// SPR_Draw draws a the current sprite as solid -#define SPR_Draw (*gEngfuncs.pfnSPR_Draw) -// SPR_DrawHoles draws the current sprites, with color index255 not drawn (transparent) -#define SPR_DrawHoles (*gEngfuncs.pfnSPR_DrawHoles) -// SPR_DrawAdditive adds the sprites RGB values to the background (additive transulency) -#define SPR_DrawAdditive (*gEngfuncs.pfnSPR_DrawAdditive) - -// SPR_EnableScissor sets a clipping rect for HUD sprites. (0,0) is the top-left hand corner of the screen. -#define SPR_EnableScissor (*gEngfuncs.pfnSPR_EnableScissor) -// SPR_DisableScissor disables the clipping rect -#define SPR_DisableScissor (*gEngfuncs.pfnSPR_DisableScissor) -// -#define FillRGBA (*gEngfuncs.pfnFillRGBA) - - -// ScreenHeight returns the height of the screen, in pixels -#define ScreenHeight (gHUD.m_scrinfo.iHeight) -// ScreenWidth returns the width of the screen, in pixels -#define ScreenWidth (gHUD.m_scrinfo.iWidth) - -// Use this to set any co-ords in 640x480 space -#define XRES(x) ((int)(float(x) * ((float)ScreenWidth / 640.0f) + 0.5f)) -#define YRES(y) ((int)(float(y) * ((float)ScreenHeight / 480.0f) + 0.5f)) - -// use this to project world coordinates to screen coordinates -#define XPROJECT(x) ( (1.0f+(x))*ScreenWidth*0.5f ) -#define YPROJECT(y) ( (1.0f-(y))*ScreenHeight*0.5f ) - -#define GetScreenInfo (*gEngfuncs.pfnGetScreenInfo) -#define ServerCmd (*gEngfuncs.pfnServerCmd) -#define ClientCmd (*gEngfuncs.pfnClientCmd) -#define SetCrosshair (*gEngfuncs.pfnSetCrosshair) -#define AngleVectors (*gEngfuncs.pfnAngleVectors) - - -// Gets the height & width of a sprite, at the specified frame -inline int SPR_Height( HSPRITE x, int f ) { return gEngfuncs.pfnSPR_Height(x, f); } -inline int SPR_Width( HSPRITE x, int f ) { return gEngfuncs.pfnSPR_Width(x, f); } - -inline client_textmessage_t *TextMessageGet( const char *pName ) { return gEngfuncs.pfnTextMessageGet( pName ); } -inline int TextMessageDrawChar( int x, int y, int number, int r, int g, int b ) -{ - return gEngfuncs.pfnDrawCharacter( x, y, number, r, g, b ); -} - -inline int DrawConsoleString( int x, int y, const char *string ) -{ - return gEngfuncs.pfnDrawConsoleString( x, y, (char*) string ); -} - -inline void GetConsoleStringSize( const char *string, int *width, int *height ) -{ - gEngfuncs.pfnDrawConsoleStringLen( string, width, height ); -} - -inline int ConsoleStringLen( const char *string ) -{ - int _width, _height; - GetConsoleStringSize( string, &_width, &_height ); - return _width; -} - -inline void ConsolePrint( const char *string ) -{ - gEngfuncs.pfnConsolePrint( string ); -} - -inline void CenterPrint( const char *string ) -{ - gEngfuncs.pfnCenterPrint( string ); -} - - -inline char *safe_strcpy( char *dst, const char *src, int len_dst) -{ - if( len_dst <= 0 ) - { - return NULL; // this is bad - } - - strncpy(dst,src,len_dst); - dst[ len_dst - 1 ] = '\0'; - - return dst; -} - -inline int safe_sprintf( char *dst, int len_dst, const char *format, ...) -{ - if( len_dst <= 0 ) - { - return -1; // this is bad - } - - va_list v; - - va_start(v, format); - - _vsnprintf(dst,len_dst,format,v); - - va_end(v); - - dst[ len_dst - 1 ] = '\0'; - - return 0; -} - -// returns the players name of entity no. -#define GetPlayerInfo (*gEngfuncs.pfnGetPlayerInfo) - -// sound functions -inline void PlaySound( char *szSound, float vol ) { gEngfuncs.pfnPlaySoundByName( szSound, vol ); } -inline void PlaySound( int iSound, float vol ) { gEngfuncs.pfnPlaySoundByIndex( iSound, vol ); } - -void ScaleColors( int &r, int &g, int &b, int a ); - -#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) -#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];} -#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];} -#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];} -#define VectorClear(a) { a[0]=0.0;a[1]=0.0;a[2]=0.0;} -float Length(const float *v); -void VectorMA (const float *veca, float scale, const float *vecb, float *vecc); -void VectorScale (const float *in, float scale, float *out); -float VectorNormalize (float *v); -void VectorInverse ( float *v ); - -extern vec3_t vec3_origin; - -// disable 'possible loss of data converting float to int' warning message -#pragma warning( disable: 4244 ) -// disable 'truncation from 'const double' to 'float' warning message -#pragma warning( disable: 4305 ) - -inline void UnpackRGB(int &r, int &g, int &b, unsigned long ulRGB)\ -{\ - r = (ulRGB & 0xFF0000) >>16;\ - g = (ulRGB & 0xFF00) >> 8;\ - b = ulRGB & 0xFF;\ -} - -HSPRITE LoadSprite(const char *pszName); diff --git a/dmc/cl_dll/com_model.h b/dmc/cl_dll/com_model.h deleted file mode 100644 index 2711599..0000000 --- a/dmc/cl_dll/com_model.h +++ /dev/null @@ -1,359 +0,0 @@ -/*** -* -* 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. -* -****/ - -// com_model.h -#if !defined( COM_MODEL_H ) -#define COM_MODEL_H -#if defined( _WIN32 ) -#pragma once -#endif - -#define STUDIO_RENDER 1 -#define STUDIO_EVENTS 2 - -#define MAX_CLIENTS 32 -#define MAX_EDICTS 900 - -#define MAX_MODEL_NAME 64 -#define MAX_MAP_HULLS 4 -#define MIPLEVELS 4 -#define NUM_AMBIENTS 4 // automatic ambient sounds -#define MAXLIGHTMAPS 4 -#define PLANE_ANYZ 5 - -#define ALIAS_Z_CLIP_PLANE 5 - -// flags in finalvert_t.flags -#define ALIAS_LEFT_CLIP 0x0001 -#define ALIAS_TOP_CLIP 0x0002 -#define ALIAS_RIGHT_CLIP 0x0004 -#define ALIAS_BOTTOM_CLIP 0x0008 -#define ALIAS_Z_CLIP 0x0010 -#define ALIAS_ONSEAM 0x0020 -#define ALIAS_XY_CLIP_MASK 0x000F - -#define ZISCALE ((float)0x8000) - -#define CACHE_SIZE 32 // used to align key data structures - -typedef enum -{ - mod_brush, - mod_sprite, - mod_alias, - mod_studio -} modtype_t; - -// must match definition in modelgen.h -#ifndef SYNCTYPE_T -#define SYNCTYPE_T - -typedef enum -{ - ST_SYNC=0, - ST_RAND -} synctype_t; - -#endif - -typedef struct -{ - float mins[3], maxs[3]; - float origin[3]; - int headnode[MAX_MAP_HULLS]; - int visleafs; // not including the solid leaf 0 - int firstface, numfaces; -} dmodel_t; - -// plane_t structure -typedef struct mplane_s -{ - vec3_t normal; // surface normal - float dist; // closest appoach to origin - byte type; // for texture axis selection and fast side tests - byte signbits; // signx + signy<<1 + signz<<1 - byte pad[2]; -} mplane_t; - -typedef struct -{ - vec3_t position; -} mvertex_t; - -typedef struct -{ - unsigned short v[2]; - unsigned int cachededgeoffset; -} medge_t; - -typedef struct texture_s -{ - char name[16]; - unsigned width, height; - int anim_total; // total tenths in sequence ( 0 = no) - int anim_min, anim_max; // time for this frame min <=time< max - struct texture_s *anim_next; // in the animation sequence - struct texture_s *alternate_anims; // bmodels in frame 1 use these - unsigned offsets[MIPLEVELS]; // four mip maps stored - unsigned paloffset; -} texture_t; - -typedef struct -{ - float vecs[2][4]; // [s/t] unit vectors in world space. - // [i][3] is the s/t offset relative to the origin. - // s or t = dot(3Dpoint,vecs[i])+vecs[i][3] - float mipadjust; // ?? mipmap limits for very small surfaces - texture_t *texture; - int flags; // sky or slime, no lightmap or 256 subdivision -} mtexinfo_t; - -typedef struct mnode_s -{ -// common with leaf - int contents; // 0, to differentiate from leafs - int visframe; // node needs to be traversed if current - - short minmaxs[6]; // for bounding box culling - - struct mnode_s *parent; - -// node specific - mplane_t *plane; - struct mnode_s *children[2]; - - unsigned short firstsurface; - unsigned short numsurfaces; -} mnode_t; - -typedef struct msurface_s msurface_t; -typedef struct decal_s decal_t; - -// JAY: Compress this as much as possible -struct decal_s -{ - decal_t *pnext; // linked list for each surface - msurface_t *psurface; // Surface id for persistence / unlinking - short dx; // Offsets into surface texture (in texture coordinates, so we don't need floats) - short dy; - short texture; // Decal texture - byte scale; // Pixel scale - byte flags; // Decal flags - - short entityIndex; // Entity this is attached to -}; - -typedef struct mleaf_s -{ -// common with node - int contents; // wil be a negative contents number - int visframe; // node needs to be traversed if current - - short minmaxs[6]; // for bounding box culling - - struct mnode_s *parent; - -// leaf specific - byte *compressed_vis; - struct efrag_s *efrags; - - msurface_t **firstmarksurface; - int nummarksurfaces; - int key; // BSP sequence number for leaf's contents - byte ambient_sound_level[NUM_AMBIENTS]; -} mleaf_t; - -struct msurface_s -{ - int visframe; // should be drawn when node is crossed - - int dlightframe; // last frame the surface was checked by an animated light - int dlightbits; // dynamically generated. Indicates if the surface illumination - // is modified by an animated light. - - mplane_t *plane; // pointer to shared plane - int flags; // see SURF_ #defines - - int firstedge; // look up in model->surfedges[], negative numbers - int numedges; // are backwards edges - -// surface generation data - struct surfcache_s *cachespots[MIPLEVELS]; - - short texturemins[2]; // smallest s/t position on the surface. - short extents[2]; // ?? s/t texture size, 1..256 for all non-sky surfaces - - mtexinfo_t *texinfo; - -// lighting info - byte styles[MAXLIGHTMAPS]; // index into d_lightstylevalue[] for animated lights - // no one surface can be effected by more than 4 - // animated lights. - color24 *samples; - - decal_t *pdecals; -}; - -typedef struct -{ - int planenum; - short children[2]; // negative numbers are contents -} dclipnode_t; - -typedef struct hull_s -{ - dclipnode_t *clipnodes; - mplane_t *planes; - int firstclipnode; - int lastclipnode; - vec3_t clip_mins; - vec3_t clip_maxs; -} hull_t; - -#if !defined( CACHE_USER ) && !defined( QUAKEDEF_H ) -#define CACHE_USER -typedef struct cache_user_s -{ - void *data; -} cache_user_t; -#endif - -typedef struct model_s -{ - char name[ MAX_MODEL_NAME ]; - qboolean needload; // bmodels and sprites don't cache normally - - modtype_t type; - int numframes; - synctype_t synctype; - - int flags; - -// -// volume occupied by the model -// - vec3_t mins, maxs; - float radius; - -// -// brush model -// - int firstmodelsurface, nummodelsurfaces; - - int numsubmodels; - dmodel_t *submodels; - - int numplanes; - mplane_t *planes; - - int numleafs; // number of visible leafs, not counting 0 - struct mleaf_s *leafs; - - int numvertexes; - mvertex_t *vertexes; - - int numedges; - medge_t *edges; - - int numnodes; - mnode_t *nodes; - - int numtexinfo; - mtexinfo_t *texinfo; - - int numsurfaces; - msurface_t *surfaces; - - int numsurfedges; - int *surfedges; - - int numclipnodes; - dclipnode_t *clipnodes; - - int nummarksurfaces; - msurface_t **marksurfaces; - - hull_t hulls[MAX_MAP_HULLS]; - - int numtextures; - texture_t **textures; - - byte *visdata; - - color24 *lightdata; - - char *entities; - -// -// additional model data -// - cache_user_t cache; // only access through Mod_Extradata - -} model_t; - -typedef vec_t vec4_t[4]; - -typedef struct alight_s -{ - int ambientlight; // clip at 128 - int shadelight; // clip at 192 - ambientlight - vec3_t color; - float *plightvec; -} alight_t; - -typedef struct auxvert_s -{ - float fv[3]; // viewspace x, y -} auxvert_t; - -#include "custom.h" - -#define MAX_INFO_STRING 256 -#define MAX_SCOREBOARDNAME 32 -typedef struct player_info_s -{ - // User id on server - int userid; - - // User info string - char userinfo[ MAX_INFO_STRING ]; - - // Name - char name[ MAX_SCOREBOARDNAME ]; - - // Spectator or not, unused - int spectator; - - int ping; - int packet_loss; - - // skin information - char model[MAX_QPATH]; - int topcolor; - int bottomcolor; - - // last frame rendered - int renderframe; - - // Gait frame estimation - int gaitsequence; - float gaitframe; - float gaityaw; - vec3_t prevgaitorigin; - - customization_t customdata; -} player_info_t; - -#endif // #define COM_MODEL_H diff --git a/dmc/cl_dll/com_weapons.cpp b/dmc/cl_dll/com_weapons.cpp deleted file mode 100644 index f204c41..0000000 --- a/dmc/cl_dll/com_weapons.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/*** -* -* 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. -* -****/ - -// Com_Weapons.cpp -// Shared weapons common/shared functions -#include -#include "hud.h" -#include "cl_util.h" -#include "com_weapons.h" - -#include "const.h" -#include "entity_state.h" -#include "r_efx.h" - -// g_runfuncs is true if this is the first time we've "predicated" a particular movement/firing -// command. If it is 1, then we should play events/sounds etc., otherwise, we just will be -// updating state info, but not firing events -int g_runfuncs = 0; - -// During our weapon prediction processing, we'll need to reference some data that is part of -// the final state passed into the postthink functionality. We'll set this pointer and then -// reset it to NULL as appropriate -struct local_state_s *g_finalstate = NULL; - -/* -==================== -COM_Log - -Log debug messages to file ( appends ) -==================== -*/ -void COM_Log( char *pszFile, char *fmt, ...) -{ - va_list argptr; - char string[1024]; - FILE *fp; - char *pfilename; - - if ( !pszFile ) - { - pfilename = "c:\\hllog.txt"; - } - else - { - pfilename = pszFile; - } - - va_start (argptr,fmt); - vsprintf (string, fmt,argptr); - va_end (argptr); - - fp = fopen( pfilename, "a+t"); - if (fp) - { - fprintf(fp, "%s", string); - fclose(fp); - } -} - -// remember the current animation for the view model, in case we get out of sync with -// server. -static int g_currentanim; - -/* -===================== -HUD_SendWeaponAnim - -Change weapon model animation -===================== -*/ -void HUD_SendWeaponAnim( int iAnim, int body, int force ) -{ - // Don't actually change it. - if ( !g_runfuncs && !force ) - return; - - g_currentanim = iAnim; - - // Tell animation system new info - gEngfuncs.pfnWeaponAnim( iAnim, body ); -} - -/* -===================== -HUD_GetWeaponAnim - -Retrieve current predicted weapon animation -===================== -*/ -int HUD_GetWeaponAnim( void ) -{ - return g_currentanim; -} - -/* -===================== -HUD_PlaySound - -Play a sound, if we are seeing this command for the first time -===================== -*/ -void HUD_PlaySound( char *sound, float volume ) -{ - if ( !g_runfuncs || !g_finalstate ) - return; - - gEngfuncs.pfnPlaySoundByNameAtLocation( sound, volume, (float *)&g_finalstate->playerstate.origin ); -} - -/* -===================== -HUD_PlaybackEvent - -Directly queue up an event on the client -===================== -*/ -void HUD_PlaybackEvent( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, - float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) -{ - vec3_t org; - vec3_t ang; - - if ( !g_runfuncs || !g_finalstate ) - return; - - // Weapon prediction events are assumed to occur at the player's origin - org = g_finalstate->playerstate.origin; - ang = v_angles; - gEngfuncs.pfnPlaybackEvent( flags, pInvoker, eventindex, delay, (float *)&org, (float *)&ang, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2 ); -} - -/* -===================== -HUD_SetMaxSpeed - -===================== -*/ -void HUD_SetMaxSpeed( const edict_t *ed, float speed ) -{ -} - - -/* -===================== -UTIL_WeaponTimeBase - -Always 0.0 on client, even if not predicting weapons ( won't get called - in that case ) -===================== -*/ -float UTIL_WeaponTimeBase( void ) -{ - return 0.0; -} - -static unsigned int glSeed = 0; - -unsigned int seed_table[ 256 ] = -{ - 28985, 27138, 26457, 9451, 17764, 10909, 28790, 8716, 6361, 4853, 17798, 21977, 19643, 20662, 10834, 20103, - 27067, 28634, 18623, 25849, 8576, 26234, 23887, 18228, 32587, 4836, 3306, 1811, 3035, 24559, 18399, 315, - 26766, 907, 24102, 12370, 9674, 2972, 10472, 16492, 22683, 11529, 27968, 30406, 13213, 2319, 23620, 16823, - 10013, 23772, 21567, 1251, 19579, 20313, 18241, 30130, 8402, 20807, 27354, 7169, 21211, 17293, 5410, 19223, - 10255, 22480, 27388, 9946, 15628, 24389, 17308, 2370, 9530, 31683, 25927, 23567, 11694, 26397, 32602, 15031, - 18255, 17582, 1422, 28835, 23607, 12597, 20602, 10138, 5212, 1252, 10074, 23166, 19823, 31667, 5902, 24630, - 18948, 14330, 14950, 8939, 23540, 21311, 22428, 22391, 3583, 29004, 30498, 18714, 4278, 2437, 22430, 3439, - 28313, 23161, 25396, 13471, 19324, 15287, 2563, 18901, 13103, 16867, 9714, 14322, 15197, 26889, 19372, 26241, - 31925, 14640, 11497, 8941, 10056, 6451, 28656, 10737, 13874, 17356, 8281, 25937, 1661, 4850, 7448, 12744, - 21826, 5477, 10167, 16705, 26897, 8839, 30947, 27978, 27283, 24685, 32298, 3525, 12398, 28726, 9475, 10208, - 617, 13467, 22287, 2376, 6097, 26312, 2974, 9114, 21787, 28010, 4725, 15387, 3274, 10762, 31695, 17320, - 18324, 12441, 16801, 27376, 22464, 7500, 5666, 18144, 15314, 31914, 31627, 6495, 5226, 31203, 2331, 4668, - 12650, 18275, 351, 7268, 31319, 30119, 7600, 2905, 13826, 11343, 13053, 15583, 30055, 31093, 5067, 761, - 9685, 11070, 21369, 27155, 3663, 26542, 20169, 12161, 15411, 30401, 7580, 31784, 8985, 29367, 20989, 14203, - 29694, 21167, 10337, 1706, 28578, 887, 3373, 19477, 14382, 675, 7033, 15111, 26138, 12252, 30996, 21409, - 25678, 18555, 13256, 23316, 22407, 16727, 991, 9236, 5373, 29402, 6117, 15241, 27715, 19291, 19888, 19847 -}; - -unsigned int U_Random( void ) -{ - glSeed *= 69069; - glSeed += seed_table[ glSeed & 0xff ]; - - return ( ++glSeed & 0x0fffffff ); -} - -void U_Srand( unsigned int seed ) -{ - glSeed = seed_table[ seed & 0xff ]; -} - -/* -===================== -UTIL_SharedRandomLong -===================== -*/ -int UTIL_SharedRandomLong( unsigned int seed, int low, int high ) -{ - - unsigned int range; - - U_Srand( (int)seed + low + high ); - - range = high - low + 1; - if ( !(range - 1) ) - { - return low; - } - else - { - int offset; - int rnum; - - rnum = U_Random(); - - offset = rnum % range; - - return (low + offset); - } -} - -/* -===================== -UTIL_SharedRandomFloat -===================== -*/ -float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ) -{ - // - unsigned int range; - - U_Srand( (int)seed + *(int *)&low + *(int *)&high ); - - U_Random(); - U_Random(); - - range = high - low; - if ( !range ) - { - return low; - } - else - { - int tensixrand; - float offset; - - tensixrand = U_Random() & 65535; - - offset = (float)tensixrand / 65536.0; - - return (low + offset * range ); - } -} - -/* -====================== -stub_* - -stub functions for such things as precaching. So we don't have to modify weapons code that - is compiled into both game and client .dlls. -====================== -*/ -int stub_PrecacheModel ( const char* s ) { return 0; } -int stub_PrecacheSound ( const char* s ) { return 0; } -unsigned short stub_PrecacheEvent ( int type, const char *s ) { return 0; } -const char *stub_NameForFunction ( uint32 function ) { return "func"; } -void stub_SetModel ( edict_t *e, const char *m ) {} diff --git a/dmc/cl_dll/com_weapons.h b/dmc/cl_dll/com_weapons.h deleted file mode 100644 index 7e92bb4..0000000 --- a/dmc/cl_dll/com_weapons.h +++ /dev/null @@ -1,48 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// com_weapons.h -// Shared weapons common function prototypes -#if !defined( COM_WEAPONSH ) -#define COM_WEAPONSH -#ifdef _WIN32 -#pragma once -#endif - -#include "hud_iface.h" - -extern "C" -{ - void DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ); -} - -void COM_Log( char *pszFile, char *fmt, ...); -int CL_IsDead( void ); - -float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ); -int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); - -int HUD_GetWeaponAnim( void ); -void HUD_SendWeaponAnim( int iAnim, int body, int force ); -void HUD_PlaySound( char *sound, float volume ); -void HUD_PlaybackEvent( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); -void HUD_SetMaxSpeed( const struct edict_s *ed, float speed ); -int stub_PrecacheModel( const char* s ); -int stub_PrecacheSound( const char* s ); -unsigned short stub_PrecacheEvent( int type, const char *s ); -const char *stub_NameForFunction ( uint32 function ); -void stub_SetModel ( struct edict_s *e, const char *m ); - - -extern cvar_t *cl_lw; - -extern int g_runfuncs; -extern vec3_t v_angles; -extern float g_lastFOV; -extern struct local_state_s *g_finalstate; - -#endif \ No newline at end of file diff --git a/dmc/cl_dll/death.cpp b/dmc/cl_dll/death.cpp deleted file mode 100644 index a2564f1..0000000 --- a/dmc/cl_dll/death.cpp +++ /dev/null @@ -1,293 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// death notice -// -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -#include "vgui_viewport.h" - -DECLARE_MESSAGE( m_DeathNotice, DeathMsg ); - -struct DeathNoticeItem { - char szKiller[MAX_PLAYER_NAME_LENGTH*2]; - char szVictim[MAX_PLAYER_NAME_LENGTH*2]; - int iId; // the index number of the associated sprite - int iSuicide; - int iTeamKill; - float flDisplayTime; - float *KillerColor; - float *VictimColor; -}; - -#define MAX_DEATHNOTICES 4 -static int DEATHNOTICE_DISPLAY_TIME = 6; - -#define DEATHNOTICE_TOP 32 - -DeathNoticeItem rgDeathNoticeList[ MAX_DEATHNOTICES + 1 ]; - -extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; -extern hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; - -float g_ColorBlue[3] = { 0.6, 0.8, 1.0 }; -float g_ColorRed[3] = { 1.0, 0.25, 0.25 }; -float g_ColorGreen[3] = { 0.6, 1.0, 0.6 }; -float g_ColorYellow[3] = { 1.0, 0.7, 0.0 }; -float g_ColorYellowish[3] = { 1.0, 0.625, 0.0 }; - -float *GetClientColor( int clientIndex ) -{ - const char *teamName = g_PlayerExtraInfo[ clientIndex].teamname; - - if ( !teamName || *teamName == 0 ) - return g_ColorYellowish; - - if ( !stricmp( "blue", teamName ) ) - return g_ColorBlue; - else if ( !stricmp( "red", teamName ) ) - return g_ColorRed; - else if ( !stricmp( "green", teamName ) ) - return g_ColorGreen; - else if ( !stricmp( "yellow", teamName ) ) - return g_ColorYellow; - - return g_ColorYellowish; -} - -int GetTeamIndex( int clientIndex ) -{ - const char *teamName = g_PlayerExtraInfo[ clientIndex].teamname; - - if ( !teamName || *teamName == 0 ) - return NULL; - - if ( !stricmp( "red", teamName ) ) - return 1; - else if ( !stricmp( "blue", teamName ) ) - return 2; - - return 0; -} - -int CHudDeathNotice :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( DeathMsg ); - - CVAR_CREATE( "hud_deathnotice_time", "6", 0 ); - - return 1; -} - - -void CHudDeathNotice :: InitHUDData( void ) -{ - memset( rgDeathNoticeList, 0, sizeof(rgDeathNoticeList) ); -} - - -int CHudDeathNotice :: VidInit( void ) -{ - m_HUD_d_skull = gHUD.GetSpriteIndex( "d_skull" ); - - return 1; -} - -int CHudDeathNotice :: Draw( float flTime ) -{ - int x, y, r, g, b; - - for ( int i = 0; i < MAX_DEATHNOTICES; i++ ) - { - if ( rgDeathNoticeList[i].iId == 0 ) - break; // we've gone through them all - - if ( rgDeathNoticeList[i].flDisplayTime < flTime ) - { // display time has expired - // remove the current item from the list - memmove( &rgDeathNoticeList[i], &rgDeathNoticeList[i+1], sizeof(DeathNoticeItem) * (MAX_DEATHNOTICES - i) ); - i--; // continue on the next item; stop the counter getting incremented - continue; - } - - rgDeathNoticeList[i].flDisplayTime = V_min( rgDeathNoticeList[i].flDisplayTime, gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME ); - - // Draw the death notice - y = YRES(DEATHNOTICE_TOP) + 2 + (20 * i); //!!! - - int id = (rgDeathNoticeList[i].iId == -1) ? m_HUD_d_skull : rgDeathNoticeList[i].iId; - x = ScreenWidth - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left); - - if ( !rgDeathNoticeList[i].iSuicide ) - { - x -= (5 + ConsoleStringLen( rgDeathNoticeList[i].szKiller ) ); - - // Draw killers name - if ( rgDeathNoticeList[i].KillerColor ) - gEngfuncs.pfnDrawSetTextColor( rgDeathNoticeList[i].KillerColor[0], rgDeathNoticeList[i].KillerColor[1], rgDeathNoticeList[i].KillerColor[2] ); - x = 5 + DrawConsoleString( x, y, rgDeathNoticeList[i].szKiller ); - } - - r = 255; g = 80; b = 0; - if ( rgDeathNoticeList[i].iTeamKill ) - { - r = 10; g = 240; b = 10; // display it in sickly green - } - - // Draw death weapon - SPR_Set( gHUD.GetSprite(id), r, g, b ); - SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(id) ); - - x += (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left); - - // Draw victims name - if ( rgDeathNoticeList[i].VictimColor ) - gEngfuncs.pfnDrawSetTextColor( rgDeathNoticeList[i].VictimColor[0], rgDeathNoticeList[i].VictimColor[1], rgDeathNoticeList[i].VictimColor[2] ); - x = DrawConsoleString( x, y, rgDeathNoticeList[i].szVictim ); - } - - return 1; -} - - -// This message handler may be better off elsewhere -int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbuf ) -{ - m_iFlags |= HUD_ACTIVE; - - BEGIN_READ( pbuf, iSize ); - - int killer = READ_BYTE(); - int victim = READ_BYTE(); - - char killedwith[32]; - strcpy( killedwith, "d_" ); - strncat( killedwith, READ_STRING(), 32 ); - - if (gViewPort) - gViewPort->DeathMsg( killer, victim ); - - gHUD.m_Spectator.DeathMessage(victim); - int i; - for ( i = 0; i < MAX_DEATHNOTICES; i++ ) - { - if ( rgDeathNoticeList[i].iId == 0 ) - break; - } - if ( i == MAX_DEATHNOTICES ) - { // move the rest of the list forward to make room for this item - memmove( rgDeathNoticeList, rgDeathNoticeList+1, sizeof(DeathNoticeItem) * MAX_DEATHNOTICES ); - i = MAX_DEATHNOTICES - 1; - } - - //gHUD.m_Scoreboard.GetAllPlayersInfo(); - - if (gViewPort) - gViewPort->GetAllPlayersInfo(); - - char *killer_name = g_PlayerInfoList[ killer ].name; - char *victim_name = g_PlayerInfoList[ victim ].name; - if ( !killer_name ) - { - killer_name = ""; - rgDeathNoticeList[i].szKiller[0] = 0; - } - else - { - rgDeathNoticeList[i].KillerColor = GetClientColor( killer ); - strncpy( rgDeathNoticeList[i].szKiller, killer_name, MAX_PLAYER_NAME_LENGTH ); - rgDeathNoticeList[i].szKiller[MAX_PLAYER_NAME_LENGTH-1] = 0; - } - - if ( !victim_name ) - { - victim_name = ""; - rgDeathNoticeList[i].szVictim[0] = 0; - } - else - { - rgDeathNoticeList[i].VictimColor = GetClientColor( victim ); - strncpy( rgDeathNoticeList[i].szVictim, victim_name, MAX_PLAYER_NAME_LENGTH ); - rgDeathNoticeList[i].szVictim[MAX_PLAYER_NAME_LENGTH-1] = 0; - } - - if ( killer == victim || killer == 0 ) - rgDeathNoticeList[i].iSuicide = TRUE; - - if ( !strcmp( killedwith, "d_teammate" ) ) - rgDeathNoticeList[i].iTeamKill = TRUE; - - // Find the sprite in the list - int spr = gHUD.GetSpriteIndex( killedwith ); - - rgDeathNoticeList[i].iId = spr; - - DEATHNOTICE_DISPLAY_TIME = CVAR_GET_FLOAT( "hud_deathnotice_time" ); - rgDeathNoticeList[i].flDisplayTime = gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME; - - // record the death notice in the console - if ( rgDeathNoticeList[i].iSuicide ) - { - ConsolePrint( rgDeathNoticeList[i].szVictim ); - - if ( !strcmp( killedwith, "d_world" ) ) - { - ConsolePrint( " died" ); - } - else - { - ConsolePrint( " killed self" ); - } - } - else if ( rgDeathNoticeList[i].iTeamKill ) - { - ConsolePrint( rgDeathNoticeList[i].szKiller ); - ConsolePrint( " killed his teammate " ); - ConsolePrint( rgDeathNoticeList[i].szVictim ); - } - else - { - ConsolePrint( rgDeathNoticeList[i].szKiller ); - ConsolePrint( " killed " ); - ConsolePrint( rgDeathNoticeList[i].szVictim ); - } - - if ( killedwith && *killedwith && (*killedwith > 13 ) && strcmp( killedwith, "d_world" ) && !rgDeathNoticeList[i].iTeamKill ) - { - ConsolePrint( " with " ); - - // replace the code names with the 'real' names - if ( !strcmp( killedwith+2, "egon" ) ) - strcpy( killedwith, "d_gluon gun" ); - if ( !strcmp( killedwith+2, "gauss" ) ) - strcpy( killedwith, "d_tau cannon" ); - - ConsolePrint( killedwith+2 ); // skip over the "d_" part - } - - ConsolePrint( "\n" ); - - return 1; -} - - - diff --git a/dmc/cl_dll/demo.cpp b/dmc/cl_dll/demo.cpp deleted file mode 100644 index f003077..0000000 --- a/dmc/cl_dll/demo.cpp +++ /dev/null @@ -1,61 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "hud.h" -#include "cl_util.h" -#include "demo.h" -#include "demo_api.h" -#include - -extern "C" -{ - void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer ); -} - -/* -===================== -Demo_WriteBuffer - -Write some data to the demo stream -===================== -*/ -void Demo_WriteBuffer( int type, int size, unsigned char *buffer ) -{ - int pos = 0; - unsigned char buf[ 32 * 1024 ]; - *( int * )&buf[pos] = type; - pos+=sizeof( int ); - - memcpy( &buf[pos], buffer, size ); - - // Write full buffer out - gEngfuncs.pDemoAPI->WriteBuffer( size + sizeof( int ), buf ); -} - -/* -===================== -Demo_ReadBuffer - -Engine wants us to parse some data from the demo stream -===================== -*/ -void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer ) -{ - int type; - int i = 0; - - type = *( int * )buffer; - i += sizeof( int ); - switch ( type ) - { - case TYPE_USER: - break; - default: - gEngfuncs.Con_DPrintf( "Unknown demo buffer type, skipping.\n" ); - break; - } -} \ No newline at end of file diff --git a/dmc/cl_dll/demo.h b/dmc/cl_dll/demo.h deleted file mode 100644 index a220327..0000000 --- a/dmc/cl_dll/demo.h +++ /dev/null @@ -1,20 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( DEMOH ) -#define DEMOH -#pragma once - -// Types of demo messages we can write/parse -enum -{ - TYPE_USER = 0, -}; - -void Demo_WriteBuffer( int type, int size, unsigned char *buffer ); - -#endif \ No newline at end of file diff --git a/dmc/cl_dll/entity.cpp b/dmc/cl_dll/entity.cpp deleted file mode 100644 index 598bbc9..0000000 --- a/dmc/cl_dll/entity.cpp +++ /dev/null @@ -1,860 +0,0 @@ -/**** -* -* -* 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. -* -****/ -// Client side entity management functions -#include - -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "entity_types.h" -#include "studio_event.h" // def. of mstudioevent_t -#include "r_efx.h" -#include "usercmd.h" -#include "event_api.h" -#include "pm_defs.h" -#include "pm_shared.h" -#include "pmtrace.h" -#include "voice_status.h" - -void Game_AddObjects( void ); - - -extern vec3_t v_origin; - -extern "C" -{ - int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void DLLEXPORT HUD_CreateEntities( void ); - void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); - void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); - void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); - void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd ); - void DLLEXPORT HUD_TempEntUpdate( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( struct cl_entity_s *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) ); - struct cl_entity_s DLLEXPORT *HUD_GetUserEntity( int index ); -} - -/* -======================== -HUD_AddEntity - Return 0 to filter entity from visible list for rendering -======================== -*/ -int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ) -{ - switch ( type ) - { - case ET_NORMAL: - case ET_PLAYER: - case ET_BEAM: - case ET_TEMPENTITY: - case ET_FRAGMENTED: - default: - break; - } - - // each frame every entity passes this function, so the overview hooks it to filter the overview entities - // in spectator mode: - // each frame every entity passes this function, so the overview hooks - // it to filter the overview entities - - if ( g_iUser1 ) - { - gHUD.m_Spectator.AddOverviewEntity( type, ent, modelname ); - - if ( ( g_iUser1 == OBS_IN_EYE || gHUD.m_Spectator.m_pip->value == INSET_IN_EYE ) && - ent->index == g_iUser2 ) - return 0; // don't draw the player we are following in eye - - } - return 1; -} - -/* -========================= -HUD_TxferLocalOverrides - -The server sends us our origin with extra precision as part of the clientdata structure, not during the normal -playerstate update in entity_state_t. In order for these overrides to eventually get to the appropriate playerstate -structure, we need to copy them into the state structure at this point. -========================= -*/ -void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ) -{ - VectorCopy( client->origin, state->origin ); - - // Observer - state->iuser1 = client->iuser1; - state->iuser2 = client->iuser2; -} - -/* -========================= -HUD_ProcessPlayerState - -We have received entity_state_t for this player over the network. We need to copy appropriate fields to the -playerstate structure -========================= -*/ -void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ) -{ - // Copy in network data - VectorCopy( src->origin, dst->origin ); - VectorCopy( src->angles, dst->angles ); - - VectorCopy( src->velocity, dst->velocity ); - - dst->frame = src->frame; - dst->modelindex = src->modelindex; - dst->skin = src->skin; - dst->effects = src->effects; - dst->weaponmodel = src->weaponmodel; - dst->movetype = src->movetype; - dst->sequence = src->sequence; - dst->animtime = src->animtime; - - dst->solid = src->solid; - - dst->rendermode = src->rendermode; - dst->renderamt = src->renderamt; - dst->rendercolor.r = src->rendercolor.r; - dst->rendercolor.g = src->rendercolor.g; - dst->rendercolor.b = src->rendercolor.b; - dst->renderfx = src->renderfx; - - dst->framerate = src->framerate; - dst->body = src->body; - - memcpy( &dst->controller[0], &src->controller[0], 4 * sizeof( byte ) ); - memcpy( &dst->blending[0], &src->blending[0], 2 * sizeof( byte ) ); - - VectorCopy( src->basevelocity, dst->basevelocity ); - - dst->friction = src->friction; - dst->gravity = src->gravity; - dst->gaitsequence = src->gaitsequence; - dst->spectator = src->spectator; - dst->usehull = src->usehull; - dst->playerclass = src->playerclass; - dst->team = src->team; - dst->colormap = src->colormap; - // Save off some data so other areas of the Client DLL can get to it - cl_entity_t *player = gEngfuncs.GetLocalPlayer(); // Get the local player's index - if ( dst->number == player->index ) - { - g_iUser1 = src->iuser1; - g_iUser2 = src->iuser2; - g_iUser3 = src->iuser3; - } -} - -/* -========================= -HUD_TxferPredictionData - -Because we can predict an arbitrary number of frames before the server responds with an update, we need to be able to copy client side prediction data in - from the state that the server ack'd receiving, which can be anywhere along the predicted frame path ( i.e., we could predict 20 frames into the future and the server ack's - up through 10 of those frames, so we need to copy persistent client-side only state from the 10th predicted frame to the slot the server - update is occupying. -========================= -*/ -void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd ) -{ - ps->oldbuttons = pps->oldbuttons; - ps->flFallVelocity = pps->flFallVelocity; - ps->iStepLeft = pps->iStepLeft; - ps->playerclass = pps->playerclass; - - pcd->viewmodel = ppcd->viewmodel; - pcd->m_iId = ppcd->m_iId; - pcd->ammo_shells = ppcd->ammo_shells; - pcd->ammo_nails = ppcd->ammo_nails; - pcd->ammo_cells = ppcd->ammo_cells; - pcd->ammo_rockets = ppcd->ammo_rockets; - pcd->m_flNextAttack = ppcd->m_flNextAttack; - pcd->fov = ppcd->fov; - pcd->weaponanim = ppcd->weaponanim; - pcd->tfstate = ppcd->tfstate; - pcd->maxspeed = ppcd->maxspeed; - - pcd->deadflag = ppcd->deadflag; - - // Observer - pcd->iuser1 = ppcd->iuser1; - pcd->iuser2 = ppcd->iuser2; - - if ( gEngfuncs.IsSpectateOnly() ) - { - // in specator mode we tell the engine who we want to spectate and how - // iuser3 is not used for duck prevention (since the spectator can't duck at all) - pcd->iuser1 = g_iUser1; // observer mode - pcd->iuser2 = g_iUser2; // first target - pcd->iuser3 = g_iUser3; // second target - } - // m_iQuakeItems - pcd->iuser3 = ppcd->iuser3; - // m_iQuakeWeapon # - pcd->fuser1 = ppcd->fuser1; - // m_iNailIndex - pcd->fuser2 = ppcd->fuser2; - // m_iRuneStatus - pcd->fuser3 = ppcd->fuser3; - - memcpy( wd, pwd, 32 * sizeof( weapon_data_t ) ); -} - -/* -//#define TEST_IT -#if defined( TEST_IT ) - -cl_entity_t mymodel[9]; - -void MoveModel( void ) -{ - cl_entity_t *player; - int i, j; - int modelindex; - struct model_s *mod; - - // Load it up with some bogus data - player = gEngfuncs.GetLocalPlayer(); - if ( !player ) - return; - - mod = gEngfuncs.CL_LoadModel( "models/sentry3.mdl", &modelindex ); - for ( i = 0; i < 3; i++ ) - { - for ( j = 0; j < 3; j++ ) - { - // Don't draw over ourself... - if ( ( i == 1 ) && ( j == 1 ) ) - continue; - - mymodel[ i * 3 + j ] = *player; - - mymodel[ i * 3 + j ].player = 0; - - mymodel[ i * 3 + j ].model = mod; - mymodel[ i * 3 + j ].curstate.modelindex = modelindex; - - // Move it out a bit - mymodel[ i * 3 + j ].origin[0] = player->origin[0] + 50 * ( 1 - i ); - mymodel[ i * 3 + j ].origin[1] = player->origin[1] + 50 * ( 1 - j ); - - gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, &mymodel[i*3+j] ); - } - } - -} - -#endif - -//#define TRACE_TEST -#if defined( TRACE_TEST ) - -extern int hitent; - -cl_entity_t hit; - -void TraceModel( void ) -{ - cl_entity_t *ent; - - if ( hitent <= 0 ) - return; - - // Load it up with some bogus data - ent = gEngfuncs.GetEntityByIndex( hitent ); - if ( !ent ) - return; - - hit = *ent; - //hit.curstate.rendermode = kRenderTransTexture; - //hit.curstate.renderfx = kRenderFxGlowShell; - //hit.curstate.renderamt = 100; - - hit.origin[2] += 40; - - gEngfuncs.CL_CreateVisibleEntity( ET_NORMAL, &hit ); -} - -#endif -*/ - -/* -void ParticleCallback( struct particle_s *particle, float frametime ) -{ - int i; - - for ( i = 0; i < 3; i++ ) - { - particle->org[ i ] += particle->vel[ i ] * frametime; - } -} - -void Particles( void ) -{ - static float lasttime; - float curtime; - - curtime = gEngfuncs.GetClientTime(); - - if ( ( curtime - lasttime ) < 10.0 ) - return; - - lasttime = curtime; - - // Create a few particles - particle_t *p; - int i, j; - - for ( i = 0; i < 100; i++ ) - { - p = gEngfuncs.pEfxAPI->R_AllocParticle( ParticleCallback ); - if ( !p ) - break; - - for ( j = 0; j < 3; j++ ) - { - p->org[ j ] = v_origin[ j ]; - p->vel[ j ] = gEngfuncs.pfnRandomFloat( -100.0, 100.0 ); - } - - p->color = gEngfuncs.pfnRandomLong( 0, 255 ); - gEngfuncs.pEfxAPI->R_GetPackedColor( &p->packedColor, p->color ); - - // p->die is set to current time so all you have to do is add an additional time to it - p->die += 5.0; - } -} -*/ - -/* -void TempEntCallback ( struct tempent_s *ent, float frametime, float currenttime ) -{ - int i; - - for ( i = 0; i < 3; i++ ) - { - ent->entity.curstate.origin[ i ] += ent->entity.baseline.origin[ i ] * frametime; - } -} - -void TempEnts( void ) -{ - static float lasttime; - float curtime; - - curtime = gEngfuncs.GetClientTime(); - - if ( ( curtime - lasttime ) < 10.0 ) - return; - - lasttime = curtime; - - TEMPENTITY *p; - int i, j; - struct model_s *mod; - vec3_t origin; - int index; - - mod = gEngfuncs.CL_LoadModel( "sprites/laserdot.spr", &index ); - - for ( i = 0; i < 100; i++ ) - { - for ( j = 0; j < 3; j++ ) - { - origin[ j ] = v_origin[ j ]; - if ( j != 2 ) - { - origin[ j ] += 75; - } - } - - p = gEngfuncs.pEfxAPI->CL_TentEntAllocCustom( (float *)&origin, mod, 0, TempEntCallback ); - if ( !p ) - break; - - for ( j = 0; j < 3; j++ ) - { - p->entity.curstate.origin[ j ] = origin[ j ]; - - // Store velocity in baseline origin - p->entity.baseline.origin[ j ] = gEngfuncs.pfnRandomFloat( -100, 100 ); - } - - // p->die is set to current time so all you have to do is add an additional time to it - p->die += 10.0; - } -} -*/ - -/* -========================= -HUD_CreateEntities - -Gives us a chance to add additional entities to the render this frame -========================= -*/ -void DLLEXPORT HUD_CreateEntities( void ) -{ - // e.g., create a persistent cl_entity_t somewhere. - // Load an appropriate model into it ( gEngfuncs.CL_LoadModel ) - // Call gEngfuncs.CL_CreateVisibleEntity to add it to the visedicts list -/* -#if defined( TEST_IT ) - MoveModel(); -#endif - -#if defined( TRACE_TEST ) - TraceModel(); -#endif -*/ -/* - Particles(); -*/ -/* - TempEnts(); -*/ - // Add in any game specific objects - Game_AddObjects(); - - GetClientVoiceMgr()->CreateEntities(); -} - -/* -========================= -HUD_StudioEvent - -The entity's studio model description indicated an event was -fired during this frame, handle the event by it's tag ( e.g., muzzleflash, sound ) -========================= -*/ -void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ) -{ - switch( event->event ) - { - case 5001: - gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[0], atoi( event->options) ); - break; - case 5011: - gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[1], atoi( event->options) ); - break; - case 5021: - gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[2], atoi( event->options) ); - break; - case 5031: - gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[3], atoi( event->options) ); - break; - case 5002: - gEngfuncs.pEfxAPI->R_SparkEffect( (float *)&entity->attachment[0], atoi( event->options), -100, 100 ); - break; - // Client side sound - case 5004: - gEngfuncs.pfnPlaySoundByNameAtLocation( (char *)event->options, 1.0, (float *)&entity->attachment[0] ); - break; - default: - break; - } -} - -/* -================= -CL_UpdateTEnts - -Simulation and cleanup of temporary entities -================= -*/ -void DLLEXPORT HUD_TempEntUpdate ( - double frametime, // Simulation time - double client_time, // Absolute time on client - double cl_gravity, // True gravity on client - TEMPENTITY **ppTempEntFree, // List of freed temporary ents - TEMPENTITY **ppTempEntActive, // List - int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), - void ( *Callback_TempEntPlaySound )( TEMPENTITY *pTemp, float damp ) ) -{ - static int gTempEntFrame = 0; - int i; - TEMPENTITY *pTemp, *pnext, *pprev; - float freq, gravity, gravitySlow, life, fastFreq; - - // Nothing to simulate - if ( !*ppTempEntActive ) - return; - - // in order to have tents collide with players, we have to run the player prediction code so - // that the client has the player list. We run this code once when we detect any COLLIDEALL - // tent, then set this BOOL to true so the code doesn't get run again if there's more than - // one COLLIDEALL ent for this update. (often are). - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( -1 ); - - // !!!BUGBUG -- This needs to be time based - gTempEntFrame = (gTempEntFrame+1) & 31; - - pTemp = *ppTempEntActive; - - // !!! Don't simulate while paused.... This is sort of a hack, revisit. - if ( frametime <= 0 ) - { - while ( pTemp ) - { - if ( !(pTemp->flags & FTENT_NOMODEL ) ) - { - Callback_AddVisibleEntity( &pTemp->entity ); - } - pTemp = pTemp->next; - } - goto finish; - } - - pprev = NULL; - freq = client_time * 0.01; - fastFreq = client_time * 5.5; - gravity = -frametime * cl_gravity; - gravitySlow = gravity * 0.5; - - while ( pTemp ) - { - int active; - - active = 1; - - life = pTemp->die - client_time; - pnext = pTemp->next; - if ( life < 0 ) - { - if ( pTemp->flags & FTENT_FADEOUT ) - { - if (pTemp->entity.curstate.rendermode == kRenderNormal) - pTemp->entity.curstate.rendermode = kRenderTransTexture; - pTemp->entity.curstate.renderamt = pTemp->entity.baseline.renderamt * ( 1 + life * pTemp->fadeSpeed ); - if ( pTemp->entity.curstate.renderamt <= 0 ) - active = 0; - - } - else - active = 0; - } - if ( !active ) // Kill it - { - pTemp->next = *ppTempEntFree; - *ppTempEntFree = pTemp; - if ( !pprev ) // Deleting at head of list - *ppTempEntActive = pnext; - else - pprev->next = pnext; - } - else - { - pprev = pTemp; - - VectorCopy( pTemp->entity.origin, pTemp->entity.prevstate.origin ); - - if ( pTemp->flags & FTENT_SPARKSHOWER ) - { - // Adjust speed if it's time - // Scale is next think time - if ( client_time > pTemp->entity.baseline.scale ) - { - // Show Sparks - gEngfuncs.pEfxAPI->R_SparkEffect( pTemp->entity.origin, 8, -200, 200 ); - - // Reduce life - pTemp->entity.baseline.framerate -= 0.1; - - if ( pTemp->entity.baseline.framerate <= 0.0 ) - { - pTemp->die = client_time; - } - else - { - // So it will die no matter what - pTemp->die = client_time + 0.5; - - // Next think - pTemp->entity.baseline.scale = client_time + 0.1; - } - } - } - else if ( pTemp->flags & FTENT_PLYRATTACHMENT ) - { - cl_entity_t *pClient; - - pClient = gEngfuncs.GetEntityByIndex( pTemp->clientIndex ); - - VectorAdd( pClient->origin, pTemp->tentOffset, pTemp->entity.origin ); - } - else if ( pTemp->flags & FTENT_SINEWAVE ) - { - pTemp->x += pTemp->entity.baseline.origin[0] * frametime; - pTemp->y += pTemp->entity.baseline.origin[1] * frametime; - - pTemp->entity.origin[0] = pTemp->x + sin( pTemp->entity.baseline.origin[2] + client_time * pTemp->entity.prevstate.frame ) * (10*pTemp->entity.curstate.framerate); - pTemp->entity.origin[1] = pTemp->y + sin( pTemp->entity.baseline.origin[2] + fastFreq + 0.7 ) * (8*pTemp->entity.curstate.framerate); - pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime; - } - else if ( pTemp->flags & FTENT_SPIRAL ) - { - float s, c; - s = sin( pTemp->entity.baseline.origin[2] + fastFreq ); - c = cos( pTemp->entity.baseline.origin[2] + fastFreq ); - - pTemp->entity.origin[0] += pTemp->entity.baseline.origin[0] * frametime + 8 * sin( client_time * 20 + (int)pTemp ); - pTemp->entity.origin[1] += pTemp->entity.baseline.origin[1] * frametime + 4 * sin( client_time * 30 + (int)pTemp ); - pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime; - } - else - { - for ( i = 0; i < 3; i++ ) - pTemp->entity.origin[i] += pTemp->entity.baseline.origin[i] * frametime; - } - - if ( pTemp->flags & FTENT_SPRANIMATE ) - { - pTemp->entity.curstate.frame += frametime * pTemp->entity.curstate.framerate; - if ( pTemp->entity.curstate.frame >= pTemp->frameMax ) - { - pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame); - - if ( !(pTemp->flags & FTENT_SPRANIMATELOOP) ) - { - // this animating sprite isn't set to loop, so destroy it. - pTemp->die = client_time; - pTemp = pnext; - continue; - } - } - } - else if ( pTemp->flags & FTENT_SPRCYCLE ) - { - pTemp->entity.curstate.frame += frametime * 10; - if ( pTemp->entity.curstate.frame >= pTemp->frameMax ) - { - pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame); - } - } -// Experiment -#if 0 - if ( pTemp->flags & FTENT_SCALE ) - pTemp->entity.curstate.framerate += 20.0 * (frametime / pTemp->entity.curstate.framerate); -#endif - - if ( pTemp->flags & FTENT_ROTATE ) - { - pTemp->entity.angles[0] += pTemp->entity.baseline.angles[0] * frametime; - pTemp->entity.angles[1] += pTemp->entity.baseline.angles[1] * frametime; - pTemp->entity.angles[2] += pTemp->entity.baseline.angles[2] * frametime; - - VectorCopy( pTemp->entity.angles, pTemp->entity.latched.prevangles ); - } - - if ( pTemp->flags & (FTENT_COLLIDEALL | FTENT_COLLIDEWORLD) ) - { - vec3_t traceNormal; - float traceFraction = 1; - - if ( pTemp->flags & FTENT_COLLIDEALL ) - { - pmtrace_t pmtrace; - physent_t *pe; - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - - gEngfuncs.pEventAPI->EV_PlayerTrace( pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX, -1, &pmtrace ); - - - if ( pmtrace.fraction != 1 ) - { - pe = gEngfuncs.pEventAPI->EV_GetPhysent( pmtrace.ent ); - - if ( !pmtrace.ent || ( pe->info != pTemp->clientIndex ) ) - { - traceFraction = pmtrace.fraction; - VectorCopy( pmtrace.plane.normal, traceNormal ); - - if ( pTemp->hitcallback ) - { - (*pTemp->hitcallback)( pTemp, &pmtrace ); - } - } - } - } - else if ( pTemp->flags & FTENT_COLLIDEWORLD ) - { - pmtrace_t pmtrace; - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - - gEngfuncs.pEventAPI->EV_PlayerTrace( pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX | PM_WORLD_ONLY, -1, &pmtrace ); - - if ( pmtrace.fraction != 1 ) - { - traceFraction = pmtrace.fraction; - VectorCopy( pmtrace.plane.normal, traceNormal ); - - if ( pTemp->flags & FTENT_SPARKSHOWER ) - { - // Chop spark speeds a bit more - // - VectorScale( pTemp->entity.baseline.origin, 0.6, pTemp->entity.baseline.origin ); - - if ( Length( pTemp->entity.baseline.origin ) < 10 ) - { - pTemp->entity.baseline.framerate = 0.0; - } - } - - if ( pTemp->hitcallback ) - { - (*pTemp->hitcallback)( pTemp, &pmtrace ); - } - } - } - - if ( traceFraction != 1 ) // Decent collision now, and damping works - { - float proj, damp; - - // Place at contact point - VectorMA( pTemp->entity.prevstate.origin, traceFraction*frametime, pTemp->entity.baseline.origin, pTemp->entity.origin ); - // Damp velocity - damp = pTemp->bounceFactor; - if ( pTemp->flags & (FTENT_GRAVITY|FTENT_SLOWGRAVITY) ) - { - damp *= 0.5; - if ( traceNormal[2] > 0.9 ) // Hit floor? - { - if ( pTemp->entity.baseline.origin[2] <= 0 && pTemp->entity.baseline.origin[2] >= gravity*3 ) - { - damp = 0; // Stop - pTemp->flags &= ~(FTENT_ROTATE|FTENT_GRAVITY|FTENT_SLOWGRAVITY|FTENT_COLLIDEWORLD|FTENT_SMOKETRAIL); - pTemp->entity.angles[0] = 0; - pTemp->entity.angles[2] = 0; - } - } - } - - if (pTemp->hitSound) - { - Callback_TempEntPlaySound(pTemp, damp); - } - - if (pTemp->flags & FTENT_COLLIDEKILL) - { - // die on impact - pTemp->flags &= ~FTENT_FADEOUT; - pTemp->die = client_time; - } - else - { - // Reflect velocity - if ( damp != 0 ) - { - proj = DotProduct( pTemp->entity.baseline.origin, traceNormal ); - VectorMA( pTemp->entity.baseline.origin, -proj*2, traceNormal, pTemp->entity.baseline.origin ); - // Reflect rotation (fake) - - pTemp->entity.angles[1] = -pTemp->entity.angles[1]; - } - - if ( damp != 1 ) - { - - VectorScale( pTemp->entity.baseline.origin, damp, pTemp->entity.baseline.origin ); - VectorScale( pTemp->entity.angles, 0.9, pTemp->entity.angles ); - } - } - } - } - - - if ( (pTemp->flags & FTENT_FLICKER) && gTempEntFrame == pTemp->entity.curstate.effects ) - { - dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight (0); - VectorCopy (pTemp->entity.origin, dl->origin); - dl->radius = 60; - dl->color.r = 255; - dl->color.g = 120; - dl->color.b = 0; - dl->die = client_time + 0.01; - } - - if ( pTemp->flags & FTENT_SMOKETRAIL ) - { - if ( pTemp->entity.baseline.sequence == 69 ) // Little smoke - gEngfuncs.pEfxAPI->R_RocketTrail ( pTemp->entity.prevstate.origin, pTemp->entity.origin, 1 ); - else if ( pTemp->entity.baseline.sequence == 70 ) // Rocket Powered smoke ( heh? ) - gEngfuncs.pEfxAPI->R_RocketTrail ( pTemp->entity.prevstate.origin, pTemp->entity.origin, 0 ); - else - gEngfuncs.pEfxAPI->R_RocketTrail ( pTemp->entity.prevstate.origin, pTemp->entity.origin, 2 ); - } - - - if ( pTemp->flags & FTENT_GRAVITY ) - pTemp->entity.baseline.origin[2] += gravity; - else if ( pTemp->flags & FTENT_SLOWGRAVITY ) - pTemp->entity.baseline.origin[2] += gravitySlow; - - if ( pTemp->flags & FTENT_CLIENTCUSTOM ) - { - if ( pTemp->callback ) - { - ( *pTemp->callback )( pTemp, frametime, client_time ); - } - } - - // Cull to PVS (not frustum cull, just PVS) - if ( !(pTemp->flags & FTENT_NOMODEL ) ) - { - if ( !Callback_AddVisibleEntity( &pTemp->entity ) ) - { - if ( !(pTemp->flags & FTENT_PERSIST) ) - { - pTemp->die = client_time; // If we can't draw it this frame, just dump it. - pTemp->flags &= ~FTENT_FADEOUT; // Don't fade out, just die - } - } - } - } - pTemp = pnext; - } - -finish: - // Restore state info - gEngfuncs.pEventAPI->EV_PopPMStates(); -} - -/* -================= -HUD_GetUserEntity - -If you specify negative numbers for beam start and end point entities, then - the engine will call back into this function requesting a pointer to a cl_entity_t - object that describes the entity to attach the beam onto. - -Indices must start at 1, not zero. -================= -*/ -cl_entity_t DLLEXPORT *HUD_GetUserEntity( int index ) -{ -return NULL; -} diff --git a/dmc/cl_dll/ev_common.cpp b/dmc/cl_dll/ev_common.cpp deleted file mode 100644 index 9138409..0000000 --- a/dmc/cl_dll/ev_common.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/*** -* -* 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. -* -****/ -// shared event functions -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" - -#include "r_efx.h" - -#include "eventscripts.h" -#include "event_api.h" - -/* -================= -GetEntity - -Return's the requested cl_entity_t -================= -*/ -struct cl_entity_s *GetEntity( int idx ) -{ - return gEngfuncs.GetEntityByIndex( idx ); -} - -/* -================= -GetViewEntity - -Return's the current weapon/view model -================= -*/ -struct cl_entity_s *GetViewEntity( void ) -{ - return gEngfuncs.GetViewModel(); -} - -/* -================= -EV_CreateTracer - -Creates a tracer effect -================= -*/ -void EV_CreateTracer( float *start, float *end ) -{ - gEngfuncs.pEfxAPI->R_TracerEffect( start, end ); -} - -/* -================= -EV_IsPlayer - -Is the entity's index in the player range? -================= -*/ -qboolean EV_IsPlayer( int idx ) -{ - if ( idx >= 1 && idx <= gEngfuncs.GetMaxClients() ) - return true; - - return false; -} - -/* -================= -EV_IsLocal - -Is the entity == the local player -================= -*/ -qboolean EV_IsLocal( int idx ) -{ - return gEngfuncs.pEventAPI->EV_IsLocal( idx - 1 ) ? true : false; -} - -/* -================= -EV_GetGunPosition - -Figure out the height of the gun -================= -*/ -void EV_GetGunPosition( event_args_t *args, float *pos, float *origin ) -{ - int idx; - vec3_t view_ofs; - - idx = args->entindex; - - VectorClear( view_ofs ); - view_ofs[2] = DEFAULT_VIEWHEIGHT; - - if ( EV_IsPlayer( idx ) ) - { - if ( EV_IsLocal( idx ) ) - { - // Grab predicted result for local player - gEngfuncs.pEventAPI->EV_LocalPlayerViewheight( view_ofs ); - } - else if ( args->ducking == 1 ) - { - view_ofs[2] = VEC_DUCK_VIEW; - } - } - - VectorAdd( origin, view_ofs, pos ); -} - -/* -================= -EV_EjectBrass - -Bullet shell casings -================= -*/ -void EV_EjectBrass( float *origin, float *velocity, float rotation, int model, int soundtype ) -{ - vec3_t endpos; - VectorClear( endpos ); - endpos[1] = rotation; - gEngfuncs.pEfxAPI->R_TempModel( origin, velocity, endpos, 2.5, model, soundtype ); -} - -/* -================= -EV_GetDefaultShellInfo - -Determine where to eject shells from -================= -*/ -void EV_GetDefaultShellInfo( event_args_t *args, float *origin, float *velocity, float *ShellVelocity, float *ShellOrigin, float *forward, float *right, float *up, float forwardScale, float upScale, float rightScale ) -{ - int i; - vec3_t view_ofs; - float fR, fU; - - int idx; - - idx = args->entindex; - - VectorClear( view_ofs ); - view_ofs[2] = DEFAULT_VIEWHEIGHT; - - if ( EV_IsPlayer( idx ) ) - { - if ( EV_IsLocal( idx ) ) - { - gEngfuncs.pEventAPI->EV_LocalPlayerViewheight( view_ofs ); - } - else if ( args->ducking == 1 ) - { - view_ofs[2] = VEC_DUCK_VIEW; - } - } - - fR = gEngfuncs.pfnRandomFloat( 50, 70 ); - fU = gEngfuncs.pfnRandomFloat( 100, 150 ); - - for ( i = 0; i < 3; i++ ) - { - ShellVelocity[i] = velocity[i] + right[i] * fR + up[i] * fU + forward[i] * 25; - ShellOrigin[i] = origin[i] + view_ofs[i] + up[i] * upScale + forward[i] * forwardScale + right[i] * rightScale; - } -} - -/* -================= -EV_MuzzleFlash - -Flag weapon/view model for muzzle flash -================= -*/ -void EV_MuzzleFlash( void ) -{ - // Add muzzle flash to current weapon model - cl_entity_t *ent = GetViewEntity(); - if ( !ent ) - { - return; - } - - // Or in the muzzle flash - ent->curstate.effects |= EF_MUZZLEFLASH; -} \ No newline at end of file diff --git a/dmc/cl_dll/ev_hldm.cpp b/dmc/cl_dll/ev_hldm.cpp deleted file mode 100644 index 2d6cccb..0000000 --- a/dmc/cl_dll/ev_hldm.cpp +++ /dev/null @@ -1,1544 +0,0 @@ -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "entity_types.h" -#include "usercmd.h" -#include "pm_defs.h" -#include "pm_materials.h" - -#include "eventscripts.h" -#include "ev_hldm.h" - -#include "r_efx.h" -#include "event_api.h" -#include "event_args.h" -#include "in_defs.h" - -#include - -// QUAKECLASSIC -#define Q_SMALL_PUNCHANGLE_KICK -2 -#define Q_BIG_PUNCHANGLE_KICK -4 - -char PM_FindTextureType( char *name ); - -void V_PunchAxis( int axis, float punch ); -extern vec3_t v_origin; - -extern "C" -{ - -// HLDM -void EV_FireShotGunSingle( struct event_args_s *args ); -void EV_FireShotGunDouble( struct event_args_s *args ); -void EV_FireAxe( struct event_args_s *args ); -void EV_FireAxeSwing( struct event_args_s *args ); -void EV_FireRocket( struct event_args_s *args ); -void EV_FireLightning( struct event_args_s *args ); -void EV_FireSpike( struct event_args_s *args ); -void EV_FireSuperSpike( struct event_args_s *args ); -void EV_FireGrenade( struct event_args_s *args ); -void EV_Gibbed( event_args_t *args ); -void EV_Teleport( event_args_t *args ); -void EV_Trail( event_args_t *args ); -void EV_Explosion( event_args_t *args ); - -void EV_PlayerPowerup( struct event_args_s *args ); - -void EV_DMC_DoorGoUp( struct event_args_s *args ); -void EV_DMC_DoorGoDown( struct event_args_s *args ); -void EV_DMC_DoorHitTop( struct event_args_s *args ); -void EV_DMC_DoorHitBottom( struct event_args_s *args ); - -#ifdef THREEWAVE - void EV_Hook( event_args_t *args ); - void EV_Cable( struct event_args_s *args ); - void EV_FollowCarrier( struct event_args_s *args ); - void EV_FlagSpawn( struct event_args_s *args ); -#endif - - -void EV_TrainPitchAdjust( struct event_args_s *args ); -} - -#define VECTOR_CONE_1DEGREES Vector( 0.00873, 0.00873, 0.00873 ) -#define VECTOR_CONE_2DEGREES Vector( 0.01745, 0.01745, 0.01745 ) -#define VECTOR_CONE_3DEGREES Vector( 0.02618, 0.02618, 0.02618 ) -#define VECTOR_CONE_4DEGREES Vector( 0.03490, 0.03490, 0.03490 ) -#define VECTOR_CONE_5DEGREES Vector( 0.04362, 0.04362, 0.04362 ) -#define VECTOR_CONE_6DEGREES Vector( 0.05234, 0.05234, 0.05234 ) -#define VECTOR_CONE_7DEGREES Vector( 0.06105, 0.06105, 0.06105 ) -#define VECTOR_CONE_8DEGREES Vector( 0.06976, 0.06976, 0.06976 ) -#define VECTOR_CONE_9DEGREES Vector( 0.07846, 0.07846, 0.07846 ) -#define VECTOR_CONE_10DEGREES Vector( 0.08716, 0.08716, 0.08716 ) -#define VECTOR_CONE_15DEGREES Vector( 0.13053, 0.13053, 0.13053 ) -#define VECTOR_CONE_20DEGREES Vector( 0.17365, 0.17365, 0.17365 ) - -// play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the -// original traceline endpoints used by the attacker, iBulletType is the type of bullet that hit the texture. -// returns volume of strike instrument (crowbar) to play -float EV_HLDM_PlayTextureSound( int idx, pmtrace_t *ptr, float *vecSrc, float *vecEnd, int iBulletType ) -{ - // hit the world, try to play sound based on texture material type - char chTextureType = CHAR_TEX_CONCRETE; - float fvol; - float fvolbar; - char *rgsz[4]; - int cnt; - float fattn = ATTN_NORM; - int entity; - char *pTextureName; - char texname[ 64 ]; - char szbuffer[ 64 ]; - - entity = gEngfuncs.pEventAPI->EV_IndexFromTrace( ptr ); - - // FIXME check if playtexture sounds movevar is set - // - - chTextureType = 0; - - // Player - if ( entity >= 1 && entity <= gEngfuncs.GetMaxClients() ) - { - // hit body - chTextureType = CHAR_TEX_FLESH; - } - else if ( entity == 0 ) - { - // get texture from entity or world (world is ent(0)) - pTextureName = (char *)gEngfuncs.pEventAPI->EV_TraceTexture( ptr->ent, vecSrc, vecEnd ); - - if ( pTextureName ) - { - strcpy( texname, pTextureName ); - pTextureName = texname; - - // strip leading '-0' or '+0~' or '{' or '!' - if (*pTextureName == '-' || *pTextureName == '+') - { - pTextureName += 2; - } - - if (*pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ') - { - pTextureName++; - } - - // '}}' - strcpy( szbuffer, pTextureName ); - szbuffer[ CBTEXTURENAMEMAX - 1 ] = 0; - - // get texture type - chTextureType = PM_FindTextureType( szbuffer ); - } - } - - switch (chTextureType) - { - default: - case CHAR_TEX_CONCRETE: fvol = 0.9; fvolbar = 0.6; - rgsz[0] = "player/pl_step1.wav"; - rgsz[1] = "player/pl_step2.wav"; - cnt = 2; - break; - case CHAR_TEX_METAL: fvol = 0.9; fvolbar = 0.3; - rgsz[0] = "player/pl_metal1.wav"; - rgsz[1] = "player/pl_metal2.wav"; - cnt = 2; - break; - case CHAR_TEX_DIRT: fvol = 0.9; fvolbar = 0.1; - rgsz[0] = "player/pl_dirt1.wav"; - rgsz[1] = "player/pl_dirt2.wav"; - rgsz[2] = "player/pl_dirt3.wav"; - cnt = 3; - break; - case CHAR_TEX_VENT: fvol = 0.5; fvolbar = 0.3; - rgsz[0] = "player/pl_duct1.wav"; - rgsz[1] = "player/pl_duct1.wav"; - cnt = 2; - break; - case CHAR_TEX_GRATE: fvol = 0.9; fvolbar = 0.5; - rgsz[0] = "player/pl_grate1.wav"; - rgsz[1] = "player/pl_grate4.wav"; - cnt = 2; - break; - case CHAR_TEX_TILE: fvol = 0.8; fvolbar = 0.2; - rgsz[0] = "player/pl_tile1.wav"; - rgsz[1] = "player/pl_tile3.wav"; - rgsz[2] = "player/pl_tile2.wav"; - rgsz[3] = "player/pl_tile4.wav"; - cnt = 4; - break; - case CHAR_TEX_SLOSH: fvol = 0.9; fvolbar = 0.0; - rgsz[0] = "player/pl_slosh1.wav"; - rgsz[1] = "player/pl_slosh3.wav"; - rgsz[2] = "player/pl_slosh2.wav"; - rgsz[3] = "player/pl_slosh4.wav"; - cnt = 4; - break; - case CHAR_TEX_WOOD: fvol = 0.9; fvolbar = 0.2; - rgsz[0] = "debris/wood1.wav"; - rgsz[1] = "debris/wood2.wav"; - rgsz[2] = "debris/wood3.wav"; - cnt = 3; - break; - case CHAR_TEX_GLASS: - case CHAR_TEX_COMPUTER: - fvol = 0.8; fvolbar = 0.2; - rgsz[0] = "debris/glass1.wav"; - rgsz[1] = "debris/glass2.wav"; - rgsz[2] = "debris/glass3.wav"; - cnt = 3; - break; - case CHAR_TEX_FLESH: - if (iBulletType == BULLET_PLAYER_CROWBAR) - return 0.0; // crowbar already makes this sound - fvol = 1.0; fvolbar = 0.2; - rgsz[0] = "weapons/bullet_hit1.wav"; - rgsz[1] = "weapons/bullet_hit2.wav"; - fattn = 1.0; - cnt = 2; - break; - } - - // play material hit sound - gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, rgsz[gEngfuncs.pfnRandomLong(0,cnt-1)], fvol, fattn, 0, 96 + gEngfuncs.pfnRandomLong(0,0xf) ); - return fvolbar; -} - -//CheckPVS see if playerIndex is in same PVS as localplayer -bool CheckPVS( int playerIndex ) -{ - //returns true if the player is in the same PVS - cl_entity_t *localPlayer = gEngfuncs.GetLocalPlayer(); - cl_entity_t *player; - - player = gEngfuncs.GetEntityByIndex( playerIndex ); - - if( !player || !localPlayer ) - return false; - - if ( player == localPlayer ) - return true; - - if( player->curstate.messagenum < localPlayer->curstate.messagenum ) - return false; - - return true; -} - - -char *EV_HLDM_RocketDamageDecal( void ) -{ - static char decalname[ 32 ]; - int idx; - - idx = gEngfuncs.pfnRandomLong( 1, 3 ); - sprintf( decalname, "{scorch%i", idx ); - return decalname; -} - -char *EV_HLDM_DamageDecal( void ) -{ - static char decalname[ 32 ]; - int idx; - - idx = gEngfuncs.pfnRandomLong( 0, 4 ); - sprintf( decalname, "{shot%i", idx + 1 ); - return decalname; -} - - -char *EV_Lightning_DamageDecal( void ) -{ - int idx; - static char decalname[ 32 ]; - //sprintf( decalname, "{smscorch1"); - - idx = gEngfuncs.pfnRandomLong( 0, 2 ); - sprintf( decalname, "{smscorch%i", idx + 1 ); - - return decalname; -} - -char *EV_Quake_DamageDecalClub( void ) -{ - static char decalname[ 32 ]; - int idx; - - idx = gEngfuncs.pfnRandomLong( 0, 4 ); - sprintf( decalname, "{shot%i", idx + 1 ); - return decalname; -} - -void EV_Quake_GunshotDecalTrace( pmtrace_t *pTrace, char *decalName ) -{ - int iRand; - physent_t *pe; - - gEngfuncs.pEfxAPI->R_BulletImpactParticles( pTrace->endpos ); - - iRand = gEngfuncs.pfnRandomLong(0,0x7FFF); - if ( iRand < (0x7fff/2) )// not every bullet makes a sound. - { - switch( iRand % 5) - { - case 0: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric2.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 2: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric3.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric4.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 4: gEngfuncs.pEventAPI->EV_PlaySound( -1, pTrace->endpos, 0, "weapons/ric5.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - } - } - - pe = gEngfuncs.pEventAPI->EV_GetPhysent( pTrace->ent ); - - // Only decal brush models such as the world etc. - if ( decalName && decalName[0] && pe && ( pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP ) ) - { - if ( CVAR_GET_FLOAT( "r_decals" ) ) - { - gEngfuncs.pEfxAPI->R_DecalShoot( - gEngfuncs.pEfxAPI->Draw_DecalIndex( gEngfuncs.pEfxAPI->Draw_DecalIndexFromName( decalName ) ), - gEngfuncs.pEventAPI->EV_IndexFromTrace( pTrace ), 0, pTrace->endpos, 0 ); - } - } -} - - -void EV_Quake_DecalTrace( pmtrace_t *pTrace, char *decalName ) -{ - physent_t *pe; - - pe = gEngfuncs.pEventAPI->EV_GetPhysent( pTrace->ent ); - - // Only decal brush models such as the world etc. - if ( decalName && decalName[0] && pe && ( pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP ) ) - { - if ( CVAR_GET_FLOAT( "r_decals" ) ) - { - gEngfuncs.pEfxAPI->R_DecalShoot( - gEngfuncs.pEfxAPI->Draw_DecalIndex( gEngfuncs.pEfxAPI->Draw_DecalIndexFromName( decalName ) ), - gEngfuncs.pEventAPI->EV_IndexFromTrace( pTrace ), 0, pTrace->endpos, 0 ); - } - } -} - -void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType ) -{ - physent_t *pe; - - pe = gEngfuncs.pEventAPI->EV_GetPhysent( pTrace->ent ); - - if ( pe && pe->solid == SOLID_BSP ) - { - switch( iBulletType ) - { - case BULLET_PLAYER_CROWBAR: - EV_Quake_DecalTrace( pTrace, EV_Quake_DamageDecalClub() ); - break; - - case BULLET_PLAYER_9MM: - case BULLET_MONSTER_9MM: - case BULLET_PLAYER_MP5: - case BULLET_MONSTER_MP5: - case BULLET_PLAYER_BUCKSHOT: - case BULLET_PLAYER_357: - default: - // smoke and decal - EV_Quake_GunshotDecalTrace( pTrace, EV_HLDM_DamageDecal() ); - break; - } - } -} - -void EV_Quake_PlayQuadSound ( int idx, float *origin, int iFlag ) -{ - if ( iFlag == 3 ) - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "rune/rune22.wav", 1, ATTN_NORM, 0, PITCH_NORM); - else if ( iFlag == 2 ) - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "rune/rune2.wav", 1, ATTN_NORM, 0, PITCH_NORM); - else if ( iFlag == 4 ) - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "rune/rune3.wav", 1, ATTN_NORM, 0, PITCH_NORM); - else if ( iFlag == 1 ) - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_ITEM, "items/damage3.wav", 1, ATTN_NORM, 0, PITCH_NORM); -} - -/* -================ -FireBullets - -Go to the trouble of combining multiple pellets into a single damage call. -================ -*/ -void EV_Quake_FireBullets( int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, float *vecSpread ) -{ - int i; - pmtrace_t tr; - int iShot; - vec3_t vecRight, vecUp; - - VectorCopy( right, vecRight ); - VectorCopy( up, vecUp ); - - for ( iShot = 1; iShot <= cShots; iShot++ ) - { - vec3_t vecDir, vecEnd; - - // get circular gaussian spread - vec3_t spread; - do { - spread[0] = gEngfuncs.pfnRandomFloat(-1.0,1.0) + gEngfuncs.pfnRandomFloat(-1.0,1.0); - spread[1] = gEngfuncs.pfnRandomFloat(-1.0,1.0) + gEngfuncs.pfnRandomFloat(-1.0,1.0); - spread[2] = spread[0] * spread[0] + spread[1] *spread[1]; - } while (spread[2] > 1); - - for ( i = 0 ; i < 3; i++ ) - { - vecDir[i] = vecDirShooting[i] + spread[ 0 ] * vecSpread[ 0 ] * vecRight[ i ] + spread[ 1 ] * vecSpread[ 1 ] * up [ i ]; - vecEnd[i] = vecSrc[ i ] + 2048.0 * vecDir[ i ]; - } - - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 ); - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr ); - - int iBulletType = BULLET_PLAYER_BUCKSHOT; - - // do damage, paint decals - if ( tr.fraction != 1.0 ) - { - switch(iBulletType) - { - default: - case BULLET_PLAYER_9MM: - EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); - EV_HLDM_DecalGunshot( &tr, iBulletType ); - break; - case BULLET_PLAYER_MP5: - EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); - EV_HLDM_DecalGunshot( &tr, iBulletType ); - break; - case BULLET_PLAYER_BUCKSHOT: - EV_HLDM_DecalGunshot( &tr, iBulletType ); - break; - case BULLET_PLAYER_357: - EV_HLDM_PlayTextureSound( idx, &tr, vecSrc, vecEnd, iBulletType ); - EV_HLDM_DecalGunshot( &tr, iBulletType ); - break; - } - } - - gEngfuncs.pEventAPI->EV_PopPMStates(); - } -} - -void EV_FireShotGunDouble( event_args_t *args ) -{ - int idx; - vec3_t origin; - vec3_t angles; - vec3_t velocity; - - int i; - vec3_t vecSrc, vecAiming; - vec3_t vecSpread; - vec3_t up, right, forward; - float flSpread = 0.01; - - idx = args->entindex; - VectorCopy( args->origin, origin ); - VectorCopy( args->angles, angles ); - VectorCopy( args->velocity, velocity ); - - AngleVectors( angles, forward, right, up ); - - EV_Quake_PlayQuadSound( idx, origin, args->iparam1 ); - - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/shotgn2.wav", 1.0, ATTN_NORM, 0, 100 ); - - EV_GetGunPosition( args, vecSrc, origin ); - VectorCopy( forward, vecAiming ); - - for ( i = 0; i < 3; i++ ) - { - vecSpread[0] = 0.04; - vecSpread[1] = 0.04; - vecSpread[2] = 0.00; - } - - EV_Quake_FireBullets( idx, forward, right, up, 14, vecSrc, vecAiming, vecSpread ); - - if ( EV_IsLocal( idx ) ) - { - V_PunchAxis( 0, Q_BIG_PUNCHANGLE_KICK ); - } -} - -void EV_FireShotGunSingle( event_args_t *args ) -{ - int idx; - vec3_t origin; - vec3_t angles; - vec3_t velocity; - - int i; - vec3_t vecSrc, vecAiming; - vec3_t vecSpread; - vec3_t up, right, forward; - float flSpread = 0.01; - - idx = args->entindex; - VectorCopy( args->origin, origin ); - VectorCopy( args->angles, angles ); - VectorCopy( args->velocity, velocity ); - - AngleVectors( angles, forward, right, up ); - - EV_Quake_PlayQuadSound( idx, origin, args->iparam1 ); - - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/guncock.wav", 1.0, ATTN_NORM, 0, 100 ); - - EV_GetGunPosition( args, vecSrc, origin ); - VectorCopy( forward, vecAiming ); - - for ( i = 0; i < 3; i++ ) - { - vecSpread[0] = 0.04; - vecSpread[1] = 0.04; - vecSpread[2] = 0.00; - } - - EV_Quake_FireBullets( idx, forward, right, up, 6, vecSrc, vecAiming, vecSpread ); - - if ( EV_IsLocal( idx ) ) - { - V_PunchAxis( 0, Q_SMALL_PUNCHANGLE_KICK ); - } -} - -enum soundtypes_e -{ - SOUND_MISS, - SOUND_HIT_BODY, - SOUND_HIT_WALL, -}; - -void EV_Quake_PlayAxeSound( int idx, float *origin, int iSoundType ) -{ - switch ( iSoundType ) - { - case SOUND_HIT_BODY: - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "player/axhitbod.wav", 1, ATTN_NORM, 0, PITCH_NORM); - break; - - case SOUND_HIT_WALL: - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM, 0, PITCH_NORM); - break; - - default: - break; - } -} - - -void EV_FireAxe( event_args_t *args ) -{ - int ent; - - int fDidHit = 0; - int m_bHullHit = 1; - - vec3_t vecSrc, vecEnd; - vec3_t up, right, forward; - pmtrace_t tr; - - int idx; - vec3_t origin; - vec3_t angles; - vec3_t velocity; - - idx = args->entindex; - VectorCopy( args->origin, origin ); - VectorCopy( args->angles, angles ); - VectorCopy( args->velocity, velocity ); - - AngleVectors( angles, forward, right, up ); - - EV_GetGunPosition( args, vecSrc, origin ); - - VectorMA( vecSrc, 64, forward, vecEnd ); - - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 ); - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_NORMAL, -1, &tr ); - - if ( tr.fraction < 1.0 ) - { - ent = gEngfuncs.pEventAPI->EV_IndexFromTrace( &tr ); - - if ( !EV_IsPlayer( ent ) ) - { - EV_Quake_PlayAxeSound( idx, origin, SOUND_HIT_WALL ); - EV_HLDM_DecalGunshot( &tr, BULLET_PLAYER_CROWBAR ); - } - - EV_Quake_PlayQuadSound( idx, origin, args->iparam1 ); - } - - gEngfuncs.pEventAPI->EV_PopPMStates(); - -} - -void EV_FireAxeSwing( event_args_t *args ) -{ - int idx; - vec3_t origin; - - idx = args->entindex; - VectorCopy( args->origin, origin ); - - EV_Quake_PlayQuadSound( idx, origin, args->iparam1 ); - - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/ax1.wav", 1.0, ATTN_NORM, 0, 100 ); -} - - -#ifdef THREEWAVE - -void EV_Hook( event_args_t *args ) -{ - return; -} - -void EV_Cable( event_args_t *args ) -{ - int idx, attached, team, modelIndex; - - float r, g, b; - - idx = args->entindex; - attached = args->iparam1; - team = args->iparam2; - - modelIndex = gEngfuncs.pEventAPI->EV_FindModelIndex( "sprites/smoke.spr" ); - - if ( !modelIndex ) - return; - - if ( team == 1 ) - { - r = 500; - g = 0; - b = 0; - } - else if ( team == 2 ) - { - r = 0; - g = 0; - b = 500; - } - - if ( args->bparam1 == 1) - gEngfuncs.pEfxAPI->R_BeamKill ( attached ); - else - gEngfuncs.pEfxAPI->R_BeamEnts ( idx, attached, modelIndex, 9999, 1, 0.001, 0.8, 0.0, 0.0, 0.0, r, g, b ); -} - -void EV_GenericParticleCallback( struct particle_s *particle, float frametime ) -{ - int i; - - for ( i = 0; i < 3; i++ ) - { - particle->org[ i ] += particle->vel[ i ] * frametime; - } -} - -void EV_TrailCallback ( struct tempent_s *ent, float frametime, float currenttime ) -{ - - //If the Player is not on our PVS, then go back - if ( !CheckPVS( ent->clientIndex ) ) - return; - - dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight ( 0 ); - - cl_entity_t *player = gEngfuncs.GetEntityByIndex( ent->clientIndex ); - - if ( !player ) - return; - - VectorCopy ( player->origin, dl->origin ); - - dl->radius = 240; - dl->die = gEngfuncs.GetClientTime() + 0.001; //Kill it right away - - if ( ent->entity.baseline.movetype == 2 ) - { - dl->color.r = 240; - dl->color.g = 25; - dl->color.b = 25; - } - else - { - dl->color.r = 25; - dl->color.g = 25; - dl->color.b = 240; - } - - //I know what you are thinking and yes, this was the only place I could find on where to put the timer - //Hacky; Yes, Works; Yes!. - if ( ent->entity.baseline.animtime > gEngfuncs.GetClientTime() ) - return; - - for ( int i = 0; i < 4; i++ ) - { - particle_t *bPart = gEngfuncs.pEfxAPI->R_AllocParticle (EV_GenericParticleCallback); - - if ( bPart ) - { - VectorCopy ( ent->entity.origin, bPart->org); - bPart->org[0] += gEngfuncs.pfnRandomFloat (-2, 2); - bPart->org[1] += gEngfuncs.pfnRandomFloat (-2, 2); - bPart->org[2] += gEngfuncs.pfnRandomFloat (-2, 2); - bPart->vel[0] = gEngfuncs.pfnRandomFloat (-50, 50); - bPart->vel[1] = gEngfuncs.pfnRandomFloat (-50, 50); - bPart->vel[2] = gEngfuncs.pfnRandomFloat (75, 80); - - //Check team and color the particle correctly - if ( ent->entity.baseline.movetype == 2 ) - bPart->color = 70; - else - bPart->color = 43; - - bPart->type = pt_slowgrav; - bPart->die = gEngfuncs.GetClientTime() + 0.5; - } - } - - ent->entity.baseline.animtime = gEngfuncs.GetClientTime() + 0.3; -} - - -void EV_FollowCarrier (event_args_t *args) -{ - int iEntIndex = args->iparam1; - int iTeam = args->iparam2; - float r,g,b; - - int modelIndex; - char *model = "sprites/smoke.spr"; - - modelIndex = gEngfuncs.pEventAPI->EV_FindModelIndex ( model ); - - if ( iTeam == 2 ) - { - r = 500; - g = 0; - b = 0; - } - else if ( iTeam == 1 ) - { - r = 0; - g = 0; - b = 500; - } - - if ( args->bparam1 == 1) - gEngfuncs.pEfxAPI->R_KillAttachedTents ( iEntIndex ); - else - { - TEMPENTITY *pTrailSpawner = NULL; - pTrailSpawner = gEngfuncs.pEfxAPI->R_TempModel ( args->origin, args->velocity, args->angles, 9999, modelIndex, TE_BOUNCE_NULL ); - - if ( pTrailSpawner != NULL) - { - pTrailSpawner->flags |= ( FTENT_PLYRATTACHMENT | FTENT_PERSIST | FTENT_NOMODEL | FTENT_CLIENTCUSTOM ); - pTrailSpawner->clientIndex = iEntIndex; - - pTrailSpawner->entity.baseline.movetype = iTeam; // Hack to store the team number on this temp ent. - pTrailSpawner->entity.baseline.animtime = gEngfuncs.GetClientTime() + 0.3; - pTrailSpawner->callback = EV_TrailCallback; - } - } -} - -void EV_FlagSpawn (event_args_t *args) -{ - vec3_t origin; - VectorCopy( args->origin, origin ); - - gEngfuncs.pEfxAPI->R_Implosion ( origin, 50, 20, 0.5 ); - - for ( int i = 0; i < 20; i++ ) - { - particle_t *bPart = gEngfuncs.pEfxAPI->R_AllocParticle ( EV_GenericParticleCallback ); - - if ( bPart ) - { - VectorCopy ( args->origin, bPart->org); - bPart->org[0] += gEngfuncs.pfnRandomFloat (-4, 4); - bPart->org[1] += gEngfuncs.pfnRandomFloat (-4, 4); - bPart->org[2] += gEngfuncs.pfnRandomFloat (-4, 4); - bPart->vel[0] = gEngfuncs.pfnRandomFloat (-50, 50); - bPart->vel[1] = gEngfuncs.pfnRandomFloat (-50, 50); - bPart->vel[2] = gEngfuncs.pfnRandomFloat (250, 350); - - //Check team and color the particle correctly - if ( args->iparam1 == 1 ) - bPart->color = 70; - else - bPart->color = 43; - - bPart->type = pt_grav; - bPart->die = gEngfuncs.GetClientTime() + 3; - } - } -} - -#endif - - -void EV_PowerupCallback ( struct tempent_s *ent, float frametime, float currenttime ) -{ - //If the Player is not on our PVS, then go back - if ( !CheckPVS( ent->clientIndex ) ) - return; - - dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight ( 0 ); - - cl_entity_t *player = gEngfuncs.GetEntityByIndex( ent->clientIndex ); - - if ( !player ) - return; - - VectorCopy ( player->origin, dl->origin ); - - dl->radius = 270; - dl->dark = true; - dl->die = gEngfuncs.GetClientTime() + 0.001; //Kill it right away - - if ( ent->entity.baseline.iuser2 == 1 ) - { - if ( ent->entity.baseline.iuser1 == 1 ) - { - dl->color.r = 255; - dl->color.g = 128; - dl->color.b = 128; - } - else - { - dl->color.r = 0; - dl->color.g = 75; - dl->color.b = 255; - } - } - else if ( ent->entity.baseline.iuser2 == 2 ) - { - if ( ent->entity.baseline.iuser1 == 1 ) - { - dl->color.r = 255; - dl->color.g = 128; - dl->color.b = 0; - } - else if ( ent->entity.baseline.iuser1 == 2 ) - { - dl->color.r = 0; - dl->color.g = 128; - dl->color.b = 250; - } - else - { - dl->color.r = 255; - dl->color.g = 75; - dl->color.b = 0; - } - } - else if ( ent->entity.baseline.iuser2 == 3 ) - { - dl->color.r = 255; - dl->color.g = 125; - dl->color.b = 255; - } -} - - -void EV_PlayerPowerup (event_args_t *args) -{ - int iEntIndex = args->iparam1; - int iTeam = args->iparam2; - int iPowerUp = (int)args->fparam1; - - int modelIndex; - char *model = "sprites/smoke.spr"; - - modelIndex = gEngfuncs.pEventAPI->EV_FindModelIndex ( model ); - - if ( args->bparam1 == 1) - gEngfuncs.pEfxAPI->R_KillAttachedTents ( iEntIndex ); - - if ( iPowerUp ) - { - TEMPENTITY *pTrailSpawner = NULL; - pTrailSpawner = gEngfuncs.pEfxAPI->R_TempModel ( args->origin, args->velocity, args->angles, 9999, modelIndex, TE_BOUNCE_NULL ); - - if ( pTrailSpawner != NULL) - { - pTrailSpawner->flags |= ( FTENT_PLYRATTACHMENT | FTENT_PERSIST | FTENT_NOMODEL | FTENT_CLIENTCUSTOM ); - pTrailSpawner->clientIndex = iEntIndex; - - pTrailSpawner->entity.baseline.iuser1 = iTeam; - pTrailSpawner->entity.baseline.iuser2 = iPowerUp; - - pTrailSpawner->callback = EV_PowerupCallback; - } - } -} - -float g_flLightTime; -BEAM *pBeam; - -void EV_FireLightning( event_args_t *args ) -{ - int idx; - vec3_t origin, endorigin; - vec3_t angles; - vec3_t vecEnd; - vec3_t up, right, forward; - int iShutDown; - - cl_entity_t *player; - - pmtrace_t tr; - int modelIndex; - - bool bSound = false; - - idx = args->entindex; - VectorCopy( args->origin, origin ); - VectorCopy( args->angles, angles ); - bSound = args->bparam1 ? true : false; - iShutDown = args->iparam2; - - modelIndex = gEngfuncs.pEventAPI->EV_FindModelIndex( "sprites/laserbeam.spr" ); - - // Load it up with some bogus data - player = gEngfuncs.GetLocalPlayer(); - - AngleVectors( angles, forward, right, up ); - - if ( EV_IsLocal( idx ) ) - { - if ( g_flLightTime <= gEngfuncs.GetClientTime() ) - { - gEngfuncs.pfnWeaponAnim( 1, 0 ); - g_flLightTime = gEngfuncs.GetClientTime() + 0.5; - } - - V_PunchAxis( 0, Q_SMALL_PUNCHANGLE_KICK ); - - cl_entity_t *player = gEngfuncs.GetViewModel(); - origin = player->attachment[0]; - } - else - { - origin = origin + Vector( 0, 0, 16 ); - } - - - if ( bSound ) - { - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/lhit.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); - EV_Quake_PlayQuadSound( idx, origin, args->iparam1 ); - } - - if ( iShutDown == 0 && EV_IsLocal( idx ) && pBeam == NULL ) - { - vec3_t vecSrc, vecEnd, origin, angles, forward, right, up; - pmtrace_t tr; - - cl_entity_t *pl = gEngfuncs.GetEntityByIndex( idx ); - - if ( pl ) - { - VectorCopy( gHUD.m_vecAngles, angles ); - - AngleVectors( angles, forward, right, up ); - - EV_GetGunPosition( args, vecSrc, pl->origin ); - - VectorMA( vecSrc, 2048, forward, vecEnd ); - - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 ); - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr ); - - gEngfuncs.pEventAPI->EV_PopPMStates(); - - pBeam = gEngfuncs.pEfxAPI->R_BeamEntPoint ( idx | 0x1000, tr.endpos, modelIndex, 99999, 5.0, 0.15, 2.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0 ); - } - } - else if ( iShutDown == 1 ) - { - if ( EV_IsLocal( idx ) ) - { - if ( pBeam ) - { - pBeam->die = 0.0; - pBeam = NULL; - } - } - } -} - - -void EV_FireRocket( event_args_t *args ) -{ - int idx; - vec3_t origin; - - idx = args->entindex; - VectorCopy( args->origin, origin ); - - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/sgun1.wav", 1.0, ATTN_NORM, 0, 100 ); - - EV_Quake_PlayQuadSound( idx, origin, args->iparam1 ); - - if ( EV_IsLocal( idx ) ) - { - V_PunchAxis( 0, Q_SMALL_PUNCHANGLE_KICK ); - } -} - -void EV_FireGrenade( event_args_t *args ) -{ - int idx; - vec3_t origin; - - idx = args->entindex; - VectorCopy( args->origin, origin ); - - EV_Quake_PlayQuadSound( idx, origin, args->iparam1 ); - - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/grenade.wav", 1.0, ATTN_NORM, 0, 100 ); - - if ( EV_IsLocal( idx ) ) - { - V_PunchAxis( 0, Q_SMALL_PUNCHANGLE_KICK ); - } -} - -void EV_Quake_NailTouch( struct tempent_s *ent, pmtrace_t *ptr ) -{ - char decalname[ 32 ]; - int idx; - physent_t *pe; - - pe = gEngfuncs.pEventAPI->EV_GetPhysent( ptr->ent ); - if ( pe && ( pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP ) ) - { - decalname[ 0 ] = '\0'; - idx = gEngfuncs.pfnRandomLong( 0, 4 ); - sprintf( decalname, "{shot%i", idx + 1 ); - EV_Quake_GunshotDecalTrace( ptr, decalname ); - } -} - -void EV_Quake_ClientProjectile( float *vecOrigin, float *vecVelocity, short sModelIndex, int iOwnerIndex, int iLife, void (*hitcallback)( struct tempent_s *ent, pmtrace_t *ptr ) ) -{ - gEngfuncs.pEfxAPI->R_Projectile( vecOrigin, vecVelocity, sModelIndex, iLife, iOwnerIndex, hitcallback ); -} - -void EV_FireSpike( event_args_t *args ) -{ - int idx; - vec3_t origin; - vec3_t angles; - vec3_t up, right, forward; - vec3_t vecVelocity; - float offset = args->bparam1 ? 2.0 : -2.0; - - int shell; - - // gEngfuncs.Con_NPrintf( 22, "offset %f", offset ); - - idx = args->entindex; - VectorCopy( args->origin, origin ); - VectorCopy( args->angles, angles ); - - shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/spike.mdl" ); - AngleVectors( angles, forward, right, up ); - - EV_Quake_PlayQuadSound( idx, origin, args->iparam1 ); - - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/rocket1i.wav", 1.0, ATTN_NORM, 0, 100 ); - - // make nails - VectorScale( forward, 1000, vecVelocity ); - EV_Quake_ClientProjectile( origin + Vector(0,0,10) + (right * offset), vecVelocity, (short)shell, idx, 6, EV_Quake_NailTouch ); - - if ( EV_IsLocal( idx ) ) - { - V_PunchAxis( 0, Q_SMALL_PUNCHANGLE_KICK ); - } -} - -void EV_FireSuperSpike( event_args_t *args ) -{ - int idx; - vec3_t origin; - vec3_t angles; - vec3_t up, right, forward; - vec3_t vecVelocity; - - int shell; - - idx = args->entindex; - VectorCopy( args->origin, origin ); - VectorCopy( args->angles, angles ); - - shell = gEngfuncs.pEventAPI->EV_FindModelIndex( "models/spike.mdl" ); - AngleVectors( angles, forward, right, up ); - - EV_Quake_PlayQuadSound( idx, origin, args->iparam1 ); - - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/spike2.wav", 1.0, ATTN_NORM, 0, 100 ); - - // make nails - VectorScale( forward, 1000, vecVelocity ); - EV_Quake_ClientProjectile( origin + Vector(0,0,16), vecVelocity, (short)shell, idx, 6, EV_Quake_NailTouch ); - - if ( EV_IsLocal( idx ) ) - { - V_PunchAxis( 0, Q_SMALL_PUNCHANGLE_KICK ); - } -} - -#define SND_CHANGE_PITCH (1<<7) - -void EV_TrainPitchAdjust( event_args_t *args ) -{ - int idx; - vec3_t origin; - - unsigned short us_params; - int noise; - float m_flVolume; - int pitch; - int stop; - - char sz[ 256 ]; - - idx = args->entindex; - - VectorCopy( args->origin, origin ); - - us_params = (unsigned short)args->iparam1; - stop = args->bparam1; - - m_flVolume = (float)(us_params & 0x003f)/40.0; - noise = (int)(((us_params) >> 12 ) & 0x0007); - pitch = (int)( 10.0 * (float)( ( us_params >> 6 ) & 0x003f ) ); - - switch ( noise ) - { - case 1: strcpy( sz, "plats/ttrain1.wav"); break; - case 2: strcpy( sz, "plats/ttrain2.wav"); break; - case 3: strcpy( sz, "plats/ttrain3.wav"); break; - case 4: strcpy( sz, "plats/ttrain4.wav"); break; - case 5: strcpy( sz, "plats/ttrain6.wav"); break; - case 6: strcpy( sz, "plats/ttrain7.wav"); break; - default: - // no sound - strcpy( sz, "" ); - return; - } - - if ( stop ) - { - gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, sz ); - } - else - { - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, sz, m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, pitch ); - } -} - -char *DMC_BloodDecal (void) -{ - static char blooddecal[ 32 ]; - int idx; - - idx = gEngfuncs.pfnRandomLong( 0, 5 ); - - sprintf( blooddecal, "{blood%i", idx + 1 ); - - return blooddecal; -} - -void DMC_DecalTrace( pmtrace_t *pTrace, char *decalName ) -{ - physent_t *pe; - - pe = gEngfuncs.pEventAPI->EV_GetPhysent( pTrace->ent ); - - // Only decal brush models such as the world etc. - if ( decalName && decalName[0] && pe && ( pe->solid == SOLID_BSP || pe->movetype == MOVETYPE_PUSHSTEP ) ) - { - if ( CVAR_GET_FLOAT( "r_decals" ) ) - { - gEngfuncs.pEfxAPI->R_DecalShoot( - gEngfuncs.pEfxAPI->Draw_DecalIndex( gEngfuncs.pEfxAPI->Draw_DecalIndexFromName( decalName ) ), - gEngfuncs.pEventAPI->EV_IndexFromTrace( pTrace ), 0, pTrace->endpos, 0 ); - } - } -} - -void EV_GibTouch ( struct tempent_s *ent, struct pmtrace_s *ptr ) -{ - DMC_DecalTrace (ptr, DMC_BloodDecal()); - - // 1 in 5 chance of squishy sound - if (gEngfuncs.pfnRandomLong(0, 4) > 0) - return; - - switch (gEngfuncs.pfnRandomLong(0, 5)) - { - case 0 : gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, "debris/flesh1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 1 : gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, "debris/flesh2.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 2 : gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, "debris/flesh3.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 3 : gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, "debris/flesh5.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 4 : gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, "debris/flesh6.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 5 : gEngfuncs.pEventAPI->EV_PlaySound( 0, ptr->endpos, CHAN_STATIC, "debris/flesh7.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - } -} - -void EV_GibParticleCallback( struct particle_s *particle, float frametime ) -{ - int i; - - for ( i = 0; i < 3; i++ ) - { - particle->org[ i ] += particle->vel[ i ] * frametime; - } -} - -void EV_Gibbed (event_args_t *args) -{ - - vec3_t origin, velocity, angles, rotate; - int modelindex, i; - TEMPENTITY *pGib = NULL; - int gibs = 5; - char *model1 = "models/gib_1.mdl"; - char *model2 = "models/gib_2.mdl"; - char *model3 = "models/gib_3.mdl"; - - VectorCopy( args->origin, origin ); - - gEngfuncs.pEventAPI->EV_PlaySound( 0, origin, CHAN_STATIC, "player/gib.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); - - rotate[0] = gEngfuncs.pfnRandomLong (-100, 100); - rotate[1] = gEngfuncs.pfnRandomLong (-100, 100); - rotate[2] = gEngfuncs.pfnRandomLong (-100, 100); - - for (i = 0; i < gibs; i++) - { - switch ( gEngfuncs.pfnRandomLong( 1, 3 ) ) - { - case 1: modelindex = gEngfuncs.pEventAPI->EV_FindModelIndex ( model1 ); break; - case 2: modelindex = gEngfuncs.pEventAPI->EV_FindModelIndex ( model2 ); break; - case 3: modelindex = gEngfuncs.pEventAPI->EV_FindModelIndex ( model3 ); break; - //Just in case - default: modelindex = gEngfuncs.pEventAPI->EV_FindModelIndex ( model1 ); break; - } - - if (!modelindex) - return; - - VectorCopy( args->angles, angles ); - - VectorScale( angles, -1.0, angles ); - - angles[0] += gEngfuncs.pfnRandomFloat ( -0.30, 0.30 ); - angles[1] += gEngfuncs.pfnRandomFloat ( -0.30, 0.30 ); - angles[2] += gEngfuncs.pfnRandomFloat ( -0.30, 0.30 ); - - VectorScale ( angles, gEngfuncs.pfnRandomFloat( 500, 1200 ), velocity ); - velocity[2] += 600; - - pGib = gEngfuncs.pEfxAPI->R_TempModel (origin, velocity, rotate, 15, modelindex, TE_BOUNCE_NULL); - - if (pGib != NULL) - { - pGib->flags |= (FTENT_COLLIDEWORLD | FTENT_ROTATE | FTENT_FADEOUT | FTENT_CLIENTCUSTOM | FTENT_SMOKETRAIL); - pGib->hitcallback = EV_GibTouch; - - } - } -} - -//Spawns the teleport effect. -void EV_Teleport ( event_args_t *args ) -{ - vec3_t vecOrg; - - VectorCopy( args->origin, vecOrg ); - - switch (gEngfuncs.pfnRandomLong(0, 4)) - { - case 0 : gEngfuncs.pEventAPI->EV_PlaySound( 0, vecOrg, CHAN_STATIC, "misc/r_tele1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 1 : gEngfuncs.pEventAPI->EV_PlaySound( 0, vecOrg, CHAN_STATIC, "misc/r_tele2.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 2 : gEngfuncs.pEventAPI->EV_PlaySound( 0, vecOrg, CHAN_STATIC, "misc/r_tele3.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 3 : gEngfuncs.pEventAPI->EV_PlaySound( 0, vecOrg, CHAN_STATIC, "misc/r_tele4.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - case 4 : gEngfuncs.pEventAPI->EV_PlaySound( 0, vecOrg, CHAN_STATIC, "misc/r_tele5.wav", 1.0, ATTN_NORM, 0, PITCH_NORM ); break; - } - - gEngfuncs.pEfxAPI->R_TeleportSplash( vecOrg ); -} - -int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3}; - -void EV_RocketTrailCallback ( struct tempent_s *ent, float frametime, float currenttime ) -{ - if ( currenttime < ent->entity.baseline.fuser1 ) - return; - - if ( ent->entity.origin == ent->entity.attachment[0] ) - ent->die = gEngfuncs.GetClientTime(); - else - VectorCopy ( ent->entity.origin, ent->entity.attachment[0] ); - - //Make the Rocket light up. ( And only rockets, no Grenades ). - if ( ent->entity.baseline.sequence == 70 ) - { - dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight ( 0 ); - VectorCopy ( ent->entity.origin, dl->origin ); - - dl->radius = 160; - dl->dark = true; - dl->die = gEngfuncs.GetClientTime() + 0.001; //Kill it right away - - dl->color.r = 255; - dl->color.g = 255; - dl->color.b = 255; - } -} - -#define GRENADE_TRAIL 1 -#define ROCKET_TRAIL 2 - -void EV_Trail (event_args_t *args) -{ - int iEntIndex = args->iparam1; - TEMPENTITY *pTrailSpawner = NULL; - - pTrailSpawner = gEngfuncs.pEfxAPI->CL_TempEntAllocNoModel ( args->origin ); - - if ( pTrailSpawner != NULL) - { - pTrailSpawner->flags |= ( FTENT_PLYRATTACHMENT | FTENT_COLLIDEKILL | FTENT_CLIENTCUSTOM | FTENT_SMOKETRAIL | FTENT_COLLIDEWORLD ); - pTrailSpawner->callback = EV_RocketTrailCallback; - pTrailSpawner->clientIndex = iEntIndex; - - if ( args->iparam2 == GRENADE_TRAIL ) - pTrailSpawner->entity.baseline.sequence = 69; - else if ( args->iparam2 == ROCKET_TRAIL ) - pTrailSpawner->entity.baseline.sequence = 70; - - pTrailSpawner->die = gEngfuncs.GetClientTime() + 10; // Just in case - pTrailSpawner->entity.baseline.fuser1 = gEngfuncs.GetClientTime() + 0.5; // Don't try to die till 500ms ahead - } -} - -void EV_Explosion (event_args_t *args) -{ - vec3_t origin, scorch_origin, velocity, forward, right, up; - int modelIndex; - char *model = "sprites/zerogxplode.spr"; - modelIndex = gEngfuncs.pEventAPI->EV_FindModelIndex (model); - pmtrace_t tr; - - //Make decals and Explosions - //Might not work for grenades. - VectorCopy( args->origin, origin ); - VectorCopy( args->angles, velocity ); //Velocity - - scorch_origin = origin - velocity.Normalize() * 32; - - gEngfuncs.pEfxAPI->R_Explosion( origin, modelIndex, 2.5, 15, TE_EXPLFLAG_NONE ); - gEngfuncs.pEfxAPI->R_ParticleExplosion2( origin , 111, 8 ); - - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - gEngfuncs.pEventAPI->EV_PushPMStates(); - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( -1 ); - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( scorch_origin, scorch_origin + velocity.Normalize() * 64, PM_STUDIO_BOX | PM_WORLD_ONLY , -1, &tr ); - - gEngfuncs.pEventAPI->EV_PopPMStates(); - - - DMC_DecalTrace( &tr, EV_HLDM_RocketDamageDecal() ); - -} - -#define EV_DMC_MOVE_SOUND 0 -#define EV_DMC_STOP_SOUND 1 -char *EV_DMC_LookupDoorSound( int type, int index ) -{ - static char sound[ 128 ]; - int idx; - - // Assume the worst - strcpy( sound, "common/null.wav"); - - if ( type == EV_DMC_MOVE_SOUND ) - { - idx = ( index >> 8 ) & 0xff; - - switch (idx) - { - case 0: - strcpy( sound, "common/null.wav"); - break; - case 1: - strcpy( sound, "doors/doormove1.wav"); - break; - case 2: - strcpy( sound, "doors/doormove2.wav"); - break; - case 3: - strcpy( sound, "doors/doormove3.wav"); - break; - case 4: - strcpy( sound, "doors/doormove4.wav"); - break; - case 5: - strcpy( sound, "doors/doormove5.wav"); - break; - case 6: - strcpy( sound, "doors/doormove6.wav"); - break; - case 7: - strcpy( sound, "doors/doormove7.wav"); - break; - case 8: - strcpy( sound, "doors/doormove8.wav"); - break; - case 9: - strcpy( sound, "doors/doormove9.wav"); - break; - case 10: - strcpy( sound, "doors/doormove10.wav"); - break; - default: - strcpy( sound, "common/null.wav"); - break; - } - } - else if ( type == EV_DMC_STOP_SOUND ) - { - idx = ( index & 0xff ); - - // set the door's 'reached destination' stop sound - switch ( idx ) - { - case 0: - strcpy( sound, "common/null.wav"); - break; - case 1: - strcpy( sound, "doors/doorstop1.wav"); - break; - case 2: - strcpy( sound, "doors/doorstop2.wav"); - break; - case 3: - strcpy( sound, "doors/doorstop3.wav"); - break; - case 4: - strcpy( sound, "doors/doorstop4.wav"); - break; - case 5: - strcpy( sound, "doors/doorstop5.wav"); - break; - case 6: - strcpy( sound, "doors/doorstop6.wav"); - break; - case 7: - strcpy( sound, "doors/doorstop7.wav"); - break; - case 8: - strcpy( sound, "doors/doorstop8.wav"); - break; - default: - strcpy( sound, "common/null.wav"); - break; - } - } - return sound; -} - -void EV_DMC_DoorGoUp( event_args_t *args ) -{ - int idx = -1; - int soundindex = args->iparam1; - - gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, EV_DMC_LookupDoorSound( EV_DMC_MOVE_SOUND, soundindex )); - gEngfuncs.pEventAPI->EV_PlaySound( idx, args->origin, CHAN_STATIC, EV_DMC_LookupDoorSound( EV_DMC_MOVE_SOUND, soundindex ), 1.0, ATTN_NORM, 0, PITCH_NORM ); -} - -void EV_DMC_DoorGoDown( event_args_t *args ) -{ - int idx = -1; - int soundindex = args->iparam1; - - gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, EV_DMC_LookupDoorSound( EV_DMC_MOVE_SOUND, soundindex )); - gEngfuncs.pEventAPI->EV_PlaySound( idx, args->origin, CHAN_STATIC, EV_DMC_LookupDoorSound( EV_DMC_MOVE_SOUND, soundindex ), 1.0, ATTN_NORM, 0, PITCH_NORM ); -} - -void EV_DMC_DoorHitTop( event_args_t *args ) -{ - int idx = -1; - int soundindex = args->iparam1; - - gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, EV_DMC_LookupDoorSound( EV_DMC_MOVE_SOUND, soundindex )); - gEngfuncs.pEventAPI->EV_PlaySound( idx, args->origin, CHAN_STATIC, EV_DMC_LookupDoorSound( EV_DMC_STOP_SOUND, soundindex ), 1.0, ATTN_NORM, 0, PITCH_NORM ); -} - -void EV_DMC_DoorHitBottom( event_args_t *args ) -{ - int idx = -1; - int soundindex = args->iparam1; - - gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, EV_DMC_LookupDoorSound( EV_DMC_MOVE_SOUND, soundindex )); - gEngfuncs.pEventAPI->EV_PlaySound( idx, args->origin, CHAN_STATIC, EV_DMC_LookupDoorSound( EV_DMC_STOP_SOUND, soundindex ), 1.0, ATTN_NORM, 0, PITCH_NORM ); -} - - diff --git a/dmc/cl_dll/ev_hldm.h b/dmc/cl_dll/ev_hldm.h deleted file mode 100644 index 2c5e4ce..0000000 --- a/dmc/cl_dll/ev_hldm.h +++ /dev/null @@ -1,96 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined ( EV_HLDMH ) -#define EV_HLDMH - -// bullet types -typedef enum -{ - BULLET_NONE = 0, - BULLET_PLAYER_9MM, // glock - BULLET_PLAYER_MP5, // mp5 - BULLET_PLAYER_357, // python - BULLET_PLAYER_BUCKSHOT, // shotgun - BULLET_PLAYER_CROWBAR, // crowbar swipe - - BULLET_MONSTER_9MM, - BULLET_MONSTER_MP5, - BULLET_MONSTER_12MM, -} Bullet; - -enum glock_e { - GLOCK_IDLE1 = 0, - GLOCK_IDLE2, - GLOCK_IDLE3, - GLOCK_SHOOT, - GLOCK_SHOOT_EMPTY, - GLOCK_RELOAD, - GLOCK_RELOAD_NOT_EMPTY, - GLOCK_DRAW, - GLOCK_HOLSTER, - GLOCK_ADD_SILENCER -}; - -enum shotgun_e { - SHOTGUN_IDLE = 0, - SHOTGUN_FIRE, - SHOTGUN_FIRE2, - SHOTGUN_RELOAD, - SHOTGUN_PUMP, - SHOTGUN_START_RELOAD, - SHOTGUN_DRAW, - SHOTGUN_HOLSTER, - SHOTGUN_IDLE4, - SHOTGUN_IDLE_DEEP -}; - -enum mp5_e -{ - MP5_LONGIDLE = 0, - MP5_IDLE1, - MP5_LAUNCH, - MP5_RELOAD, - MP5_DEPLOY, - MP5_FIRE1, - MP5_FIRE2, - MP5_FIRE3, -}; - -enum python_e { - PYTHON_IDLE1 = 0, - PYTHON_FIDGET, - PYTHON_FIRE1, - PYTHON_RELOAD, - PYTHON_HOLSTER, - PYTHON_DRAW, - PYTHON_IDLE2, - PYTHON_IDLE3 -}; - -#define GAUSS_PRIMARY_CHARGE_VOLUME 256// how loud gauss is while charging -#define GAUSS_PRIMARY_FIRE_VOLUME 450// how loud gauss is when discharged - -enum gauss_e { - GAUSS_IDLE = 0, - GAUSS_IDLE2, - GAUSS_FIDGET, - GAUSS_SPINUP, - GAUSS_SPIN, - GAUSS_FIRE, - GAUSS_FIRE2, - GAUSS_HOLSTER, - GAUSS_DRAW -}; - -int EV_HLDM_DamageDecal( int entity, int bitsDamageType ); -void EV_HLDM_GunshotDecalTrace( pmtrace_t *pTrace, char *decalName ); -void EV_HLDM_DecalGunshot( pmtrace_t *pTrace, int iBulletType ); -int EV_HLDM_CheckTracer( int idx, float *vecSrc, float *end, float *forward, float *right, int iBulletType, int iTracerFreq, int *tracerCount ); -void EV_HLDM_FireBullets( int idx, float *forward, float *right, float *up, int cShots, float *vecSrc, float *vecDirShooting, float *vecSpread, float flDistance, int iBulletType, int iTracerFreq, int *tracerCount ); - -#endif // EV_HLDMH \ No newline at end of file diff --git a/dmc/cl_dll/events.cpp b/dmc/cl_dll/events.cpp deleted file mode 100644 index a170888..0000000 --- a/dmc/cl_dll/events.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "hud.h" -#include "cl_util.h" - -void Game_HookEvents( void ); - -/* -=================== -EV_HookEvents - -See if game specific code wants to hook any events. -=================== -*/ -void EV_HookEvents( void ) -{ - Game_HookEvents(); -} diff --git a/dmc/cl_dll/eventscripts.h b/dmc/cl_dll/eventscripts.h deleted file mode 100644 index 5611729..0000000 --- a/dmc/cl_dll/eventscripts.h +++ /dev/null @@ -1,73 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// eventscripts.h -#if !defined ( EVENTSCRIPTSH ) -#define EVENTSCRIPTSH - -// defaults for clientinfo messages -#define DEFAULT_VIEWHEIGHT 22 -#define VEC_DUCK_VIEW 12 - -#define FTENT_FADEOUT 0x00000080 - -#define DMG_GENERIC 0 // generic damage was done -#define DMG_CRUSH (1 << 0) // crushed by falling or moving object -#define DMG_BULLET (1 << 1) // shot -#define DMG_SLASH (1 << 2) // cut, clawed, stabbed -#define DMG_BURN (1 << 3) // heat burned -#define DMG_FREEZE (1 << 4) // frozen -#define DMG_FALL (1 << 5) // fell too far -#define DMG_BLAST (1 << 6) // explosive blast damage -#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt -#define DMG_SHOCK (1 << 8) // electric shock -#define DMG_SONIC (1 << 9) // sound pulse shockwave -#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam -#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death -#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death. - -// time-based damage -//mask off TF-specific stuff too -#define DMG_TIMEBASED (~(0xff003fff)) // mask for time-based damage - -#define DMG_DROWN (1 << 14) // Drowning -#define DMG_FIRSTTIMEBASED DMG_DROWN - -#define DMG_PARALYZE (1 << 15) // slows affected creature down -#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad -#define DMG_POISON (1 << 17) // blood poisioning -#define DMG_RADIATION (1 << 18) // radiation exposure -#define DMG_DROWNRECOVER (1 << 19) // drowning recovery -#define DMG_ACID (1 << 20) // toxic chemicals or acid burns -#define DMG_SLOWBURN (1 << 21) // in an oven -#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer -#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar) - -//TF ADDITIONS -#define DMG_IGNITE (1 << 24) // Players hit by this begin to burn -#define DMG_RADIUS_MAX (1 << 25) // Radius damage with this flag doesn't decrease over distance -#define DMG_RADIUS_QUAKE (1 << 26) // Radius damage is done like Quake. 1/2 damage at 1/2 radius. -#define DMG_IGNOREARMOR (1 << 27) // Damage ignores target's armor -#define DMG_AIMED (1 << 28) // Does Hit location damage -#define DMG_WALLPIERCING (1 << 29) // Blast Damages ents through walls - -#define DMG_CALTROP (1<<30) -#define DMG_HALLUC (1<<31) - -// Some of these are HL/TFC specific? -void EV_EjectBrass( float *origin, float *velocity, float rotation, int model, int soundtype ); -void EV_GetGunPosition( struct event_args_s *args, float *pos, float *origin ); -void EV_GetDefaultShellInfo( struct event_args_s *args, float *origin, float *velocity, float *ShellVelocity, float *ShellOrigin, float *forward, float *right, float *up, float forwardScale, float upScale, float rightScale ); -qboolean EV_IsLocal( int idx ); -qboolean EV_IsPlayer( int idx ); -void EV_CreateTracer( float *start, float *end ); - -struct cl_entity_s *GetEntity( int idx ); -struct cl_entity_s *GetViewEntity( void ); -void EV_MuzzleFlash( void ); - -#endif // EVENTSCRIPTSH diff --git a/dmc/cl_dll/flashlight.cpp b/dmc/cl_dll/flashlight.cpp deleted file mode 100644 index 8578334..0000000 --- a/dmc/cl_dll/flashlight.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// flashlight.cpp -// -// implementation of CHudFlashlight class -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - - - -DECLARE_MESSAGE(m_Flash, FlashBat) -DECLARE_MESSAGE(m_Flash, Flashlight) - -#define BAT_NAME "sprites/%d_Flashlight.spr" - -int CHudFlashlight::Init(void) -{ - m_fFade = 0; - m_fOn = 0; - - HOOK_MESSAGE(Flashlight); - HOOK_MESSAGE(FlashBat); - - m_iFlags |= HUD_ACTIVE; - - gHUD.AddHudElem(this); - - return 1; -}; - -void CHudFlashlight::Reset(void) -{ - m_fFade = 0; - m_fOn = 0; -} - -int CHudFlashlight::VidInit(void) -{ - int HUD_flash_empty = gHUD.GetSpriteIndex( "flash_empty" ); - int HUD_flash_full = gHUD.GetSpriteIndex( "flash_full" ); - int HUD_flash_beam = gHUD.GetSpriteIndex( "flash_beam" ); - - m_hSprite1 = gHUD.GetSprite(HUD_flash_empty); - m_hSprite2 = gHUD.GetSprite(HUD_flash_full); - m_hBeam = gHUD.GetSprite(HUD_flash_beam); - m_prc1 = &gHUD.GetSpriteRect(HUD_flash_empty); - m_prc2 = &gHUD.GetSpriteRect(HUD_flash_full); - m_prcBeam = &gHUD.GetSpriteRect(HUD_flash_beam); - m_iWidth = m_prc2->right - m_prc2->left; - - return 1; -}; - -int CHudFlashlight:: MsgFunc_FlashBat(const char *pszName, int iSize, void *pbuf ) -{ - - - BEGIN_READ( pbuf, iSize ); - int x = READ_BYTE(); - m_iBat = x; - m_flBat = ((float)x)/100.0; - - return 1; -} - -int CHudFlashlight:: MsgFunc_Flashlight(const char *pszName, int iSize, void *pbuf ) -{ - - BEGIN_READ( pbuf, iSize ); - m_fOn = READ_BYTE(); - int x = READ_BYTE(); - m_iBat = x; - m_flBat = ((float)x)/100.0; - - return 1; -} - -int CHudFlashlight::Draw(float flTime) -{ - if ( gHUD.m_iHideHUDDisplay & ( HIDEHUD_FLASHLIGHT | HIDEHUD_ALL ) ) - return 1; - - int r, g, b, x, y, a; - wrect_t rc; - - if (m_fOn) - a = 225; - else - a = MIN_ALPHA; - - if (m_flBat < 0.20) - UnpackRGB(r,g,b, RGB_REDISH); - else - UnpackRGB(r,g,b, RGB_YELLOWISH); - - ScaleColors(r, g, b, a); - - y = (m_prc1->bottom - m_prc2->top)/2; - x = ScreenWidth - m_iWidth - m_iWidth/2 ; - - // Draw the flashlight casing - SPR_Set(m_hSprite1, r, g, b ); - SPR_DrawAdditive( 0, x, y, m_prc1); - - if ( m_fOn ) - { // draw the flashlight beam - x = ScreenWidth - m_iWidth/2; - - SPR_Set( m_hBeam, r, g, b ); - SPR_DrawAdditive( 0, x, y, m_prcBeam ); - } - - // draw the flashlight energy level - x = ScreenWidth - m_iWidth - m_iWidth/2 ; - int iOffset = m_iWidth * (1.0 - m_flBat); - if (iOffset < m_iWidth) - { - rc = *m_prc2; - rc.left += iOffset; - - SPR_Set(m_hSprite2, r, g, b ); - SPR_DrawAdditive( 0, x + iOffset, y, &rc); - } - - - return 1; -} \ No newline at end of file diff --git a/dmc/cl_dll/geiger.cpp b/dmc/cl_dll/geiger.cpp deleted file mode 100644 index 9944267..0000000 --- a/dmc/cl_dll/geiger.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// Geiger.cpp -// -// implementation of CHudAmmo class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include - -#include "parsemsg.h" - -DECLARE_MESSAGE(m_Geiger, Geiger ) - -int CHudGeiger::Init(void) -{ - HOOK_MESSAGE( Geiger ); - - m_iGeigerRange = 0; - m_iFlags = 0; - - gHUD.AddHudElem(this); - - srand( (unsigned)time( NULL ) ); - - return 1; -}; - -int CHudGeiger::VidInit(void) -{ - return 1; -}; - -int CHudGeiger::MsgFunc_Geiger(const char *pszName, int iSize, void *pbuf) -{ - - BEGIN_READ( pbuf, iSize ); - - // update geiger data - m_iGeigerRange = READ_BYTE(); - m_iGeigerRange = m_iGeigerRange << 2; - - m_iFlags |= HUD_ACTIVE; - - return 1; -} - -int CHudGeiger::Draw (float flTime) -{ - int pct; - float flvol; - int rg[3]; - int i; - - if (m_iGeigerRange <= 800 && m_iGeigerRange > 0) - { - // peicewise linear is better than continuous formula for this - if (m_iGeigerRange > 600) - { - pct = 2; - flvol = 0.4; //Con_Printf ( "range > 600\n"); - rg[0] = 1; - rg[1] = 1; - i = 2; - } - else if (m_iGeigerRange > 500) - { - pct = 4; - flvol = 0.5; //Con_Printf ( "range > 500\n"); - rg[0] = 1; - rg[1] = 2; - i = 2; - } - else if (m_iGeigerRange > 400) - { - pct = 8; - flvol = 0.6; //Con_Printf ( "range > 400\n"); - rg[0] = 1; - rg[1] = 2; - rg[2] = 3; - i = 3; - } - else if (m_iGeigerRange > 300) - { - pct = 8; - flvol = 0.7; //Con_Printf ( "range > 300\n"); - rg[0] = 2; - rg[1] = 3; - rg[2] = 4; - i = 3; - } - else if (m_iGeigerRange > 200) - { - pct = 28; - flvol = 0.78; //Con_Printf ( "range > 200\n"); - rg[0] = 2; - rg[1] = 3; - rg[2] = 4; - i = 3; - } - else if (m_iGeigerRange > 150) - { - pct = 40; - flvol = 0.80; //Con_Printf ( "range > 150\n"); - rg[0] = 3; - rg[1] = 4; - rg[2] = 5; - i = 3; - } - else if (m_iGeigerRange > 100) - { - pct = 60; - flvol = 0.85; //Con_Printf ( "range > 100\n"); - rg[0] = 3; - rg[1] = 4; - rg[2] = 5; - i = 3; - } - else if (m_iGeigerRange > 75) - { - pct = 80; - flvol = 0.9; //Con_Printf ( "range > 75\n"); - //gflGeigerDelay = cl.time + GEIGERDELAY * 0.75; - rg[0] = 4; - rg[1] = 5; - rg[2] = 6; - i = 3; - } - else if (m_iGeigerRange > 50) - { - pct = 90; - flvol = 0.95; //Con_Printf ( "range > 50\n"); - rg[0] = 5; - rg[1] = 6; - i = 2; - } - else - { - pct = 95; - flvol = 1.0; //Con_Printf ( "range < 50\n"); - rg[0] = 5; - rg[1] = 6; - i = 2; - } - - flvol = (flvol * ((rand() & 127)) / 255) + 0.25; // UTIL_RandomFloat(0.25, 0.5); - - if ((rand() & 127) < pct || (rand() & 127) < pct) - { - //S_StartDynamicSound (-1, 0, rgsfx[rand() % i], r_origin, flvol, 1.0, 0, 100); - char sz[256]; - - int j = rand() & 1; - if (i > 2) - j += rand() & 1; - - sprintf(sz, "player/geiger%d.wav", j + 1); - PlaySound(sz, flvol); - - } - } - - return 1; -} diff --git a/dmc/cl_dll/health.cpp b/dmc/cl_dll/health.cpp deleted file mode 100644 index 2989a4a..0000000 --- a/dmc/cl_dll/health.cpp +++ /dev/null @@ -1,476 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// Health.cpp -// -// implementation of CHudHealth class -// - -#include "stdio.h" -#include "stdlib.h" -#include "math.h" - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" -#include - - -DECLARE_MESSAGE(m_Health, Health ) -DECLARE_MESSAGE(m_Health, Damage ) - -#define PAIN_NAME "sprites/%d_pain.spr" -#define DAMAGE_NAME "sprites/%d_dmg.spr" - -int giDmgHeight, giDmgWidth; - -int giDmgFlags[NUM_DMG_TYPES] = -{ - DMG_POISON, - DMG_ACID, - DMG_FREEZE|DMG_SLOWFREEZE, - DMG_DROWN, - DMG_BURN|DMG_SLOWBURN, - DMG_NERVEGAS, - DMG_RADIATION, - DMG_SHOCK, - DMG_CALTROP, - DMG_TRANQ, - DMG_CONCUSS, - DMG_HALLUC -}; - -int CHudHealth::Init(void) -{ - HOOK_MESSAGE(Health); - HOOK_MESSAGE(Damage); - m_iHealth = 100; - m_fFade = 0; - m_iFlags = 0; - m_bitsDamage = 0; - m_fAttackFront = m_fAttackRear = m_fAttackRight = m_fAttackLeft = 0; - giDmgHeight = 0; - giDmgWidth = 0; - - memset(m_dmg, 0, sizeof(DAMAGE_IMAGE) * NUM_DMG_TYPES); - - - gHUD.AddHudElem(this); - return 1; -} - -void CHudHealth::Reset( void ) -{ - // make sure the pain compass is cleared when the player respawns - m_fAttackFront = m_fAttackRear = m_fAttackRight = m_fAttackLeft = 0; - - - // force all the flashing damage icons to expire - m_bitsDamage = 0; - for ( int i = 0; i < NUM_DMG_TYPES; i++ ) - { - m_dmg[i].fExpire = 0; - } -} - -int CHudHealth::VidInit(void) -{ - m_hSprite = 0; - - m_HUD_dmg_bio = gHUD.GetSpriteIndex( "dmg_bio" ) + 1; - m_HUD_cross = gHUD.GetSpriteIndex( "cross" ); - - giDmgHeight = gHUD.GetSpriteRect(m_HUD_dmg_bio).right - gHUD.GetSpriteRect(m_HUD_dmg_bio).left; - giDmgWidth = gHUD.GetSpriteRect(m_HUD_dmg_bio).bottom - gHUD.GetSpriteRect(m_HUD_dmg_bio).top; - return 1; -} - -int CHudHealth:: MsgFunc_Health(const char *pszName, int iSize, void *pbuf ) -{ - // TODO: update local health data - BEGIN_READ( pbuf, iSize ); - int x = READ_BYTE(); - - m_iFlags |= HUD_ACTIVE; - - // Only update the fade if we've changed health - if (x != m_iHealth) - { - m_fFade = FADE_TIME; - m_iHealth = x; - } - - return 1; -} - - -int CHudHealth:: MsgFunc_Damage(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int armor = READ_BYTE(); // armor - int damageTaken = READ_BYTE(); // health - long bitsDamage = READ_LONG(); // damage bits - - vec3_t vecFrom; - - for ( int i = 0 ; i < 3 ; i++) - vecFrom[i] = READ_COORD(); - - UpdateTiles(gHUD.m_flTime, bitsDamage); - - // Actually took damage? - if ( damageTaken > 0 || armor > 0 ) - CalcDamageDirection(vecFrom); - - return 1; -} - - -// Returns back a color from the -// Green <-> Yellow <-> Red ramp -void CHudHealth::GetPainColor( int &r, int &g, int &b ) -{ - int iHealth = m_iHealth; - - if (iHealth > 25) - iHealth -= 25; - else if ( iHealth < 0 ) - iHealth = 0; -#if 0 - g = iHealth * 255 / 100; - r = 255 - g; - b = 0; -#else - if (m_iHealth > 25) - { - UnpackRGB(r,g,b, RGB_YELLOWISH); - } - else - { - r = 250; - g = 0; - b = 0; - } -#endif -} - -int CHudHealth::Draw(float flTime) -{ - int r, g, b; - int a = 0, x, y; - int HealthWidth; - -// if (m_iHealth <= 0) -// return 1; - - if ( gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH ) - return 1; - - if ( !m_hSprite ) - m_hSprite = LoadSprite(PAIN_NAME); - - // Has health changed? Flash the health # - if (m_fFade) - { - m_fFade -= (gHUD.m_flTimeDelta * 20); - if (m_fFade <= 0) - { - a = MIN_ALPHA; - m_fFade = 0; - } - - // Fade the health number back to dim - - a = MIN_ALPHA + (m_fFade/FADE_TIME) * 128; - - } - else - a = MIN_ALPHA; - - // If health is getting low, make it bright red - if (m_iHealth <= 15) - a = 255; - - GetPainColor( r, g, b ); - ScaleColors(r, g, b, a ); - - // Only draw health if we have the suit. - { - HealthWidth = gHUD.GetSpriteRect(gHUD.m_HUD_number_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).left; - int CrossWidth = gHUD.GetSpriteRect(m_HUD_cross).right - gHUD.GetSpriteRect(m_HUD_cross).left; - - y = ScreenHeight - gHUD.m_iFontHeight - gHUD.m_iFontHeight / 2; - x = CrossWidth /2; - - SPR_Set(gHUD.GetSprite(m_HUD_cross), r, g, b); - SPR_DrawAdditive(0, x, y, &gHUD.GetSpriteRect(m_HUD_cross)); - - x = CrossWidth + HealthWidth / 2; - - x = gHUD.DrawHudNumber(x, y, DHN_3DIGITS | DHN_DRAWZERO, m_iHealth, r, g, b); - - x += HealthWidth/2; - - int iHeight = gHUD.m_iFontHeight; - int iWidth = HealthWidth/10; - FillRGBA(x, y, iWidth, iHeight, 255, 160, 0, a); - } - - DrawDamage(flTime); - return DrawPain(flTime); -} - -void CHudHealth::CalcDamageDirection(vec3_t vecFrom) -{ - vec3_t forward, right, up; - float side, front; - vec3_t vecOrigin, vecAngles; - - if (!vecFrom[0] && !vecFrom[1] && !vecFrom[2]) - { - m_fAttackFront = m_fAttackRear = m_fAttackRight = m_fAttackLeft = 0; - return; - } - - - memcpy(vecOrigin, gHUD.m_vecOrigin, sizeof(vec3_t)); - memcpy(vecAngles, gHUD.m_vecAngles, sizeof(vec3_t)); - - - VectorSubtract (vecFrom, vecOrigin, vecFrom); - - float flDistToTarget = vecFrom.Length(); - - vecFrom = vecFrom.Normalize(); - AngleVectors (vecAngles, forward, right, up); - - front = DotProduct (vecFrom, right); - side = DotProduct (vecFrom, forward); - - if (flDistToTarget <= 50) - { - m_fAttackFront = m_fAttackRear = m_fAttackRight = m_fAttackLeft = 1; - } - else - { - if (side > 0) - { - if (side > 0.3) - m_fAttackFront = V_max(m_fAttackFront, side); - } - else - { - float f = fabs(side); - if (f > 0.3) - m_fAttackRear = V_max(m_fAttackRear, f); - } - - if (front > 0) - { - if (front > 0.3) - m_fAttackRight = V_max(m_fAttackRight, front); - } - else - { - float f = fabs(front); - if (f > 0.3) - m_fAttackLeft = V_max(m_fAttackLeft, f); - } - } -} - -int CHudHealth::DrawPain(float flTime) -{ - if (!(m_fAttackFront || m_fAttackRear || m_fAttackLeft || m_fAttackRight)) - return 1; - - int r, g, b; - int x, y, a, shade; - - // TODO: get the shift value of the health - a = 255; // max brightness until then - - float fFade = gHUD.m_flTimeDelta * 2; - - // SPR_Draw top - if (m_fAttackFront > 0.4) - { - GetPainColor(r,g,b); - shade = a * V_max( m_fAttackFront, 0.5 ); - ScaleColors(r, g, b, shade); - SPR_Set(m_hSprite, r, g, b ); - - x = ScreenWidth/2 - SPR_Width(m_hSprite, 0)/2; - y = ScreenHeight/2 - SPR_Height(m_hSprite,0) * 3; - SPR_DrawAdditive(0, x, y, NULL); - m_fAttackFront = V_max( 0, m_fAttackFront - fFade ); - } else - m_fAttackFront = 0; - - if (m_fAttackRight > 0.4) - { - GetPainColor(r,g,b); - shade = a * V_max( m_fAttackRight, 0.5 ); - ScaleColors(r, g, b, shade); - SPR_Set(m_hSprite, r, g, b ); - - x = ScreenWidth/2 + SPR_Width(m_hSprite, 1) * 2; - y = ScreenHeight/2 - SPR_Height(m_hSprite,1)/2; - SPR_DrawAdditive(1, x, y, NULL); - m_fAttackRight = V_max( 0, m_fAttackRight - fFade ); - } else - m_fAttackRight = 0; - - if (m_fAttackRear > 0.4) - { - GetPainColor(r,g,b); - shade = a * V_max( m_fAttackRear, 0.5 ); - ScaleColors(r, g, b, shade); - SPR_Set(m_hSprite, r, g, b ); - - x = ScreenWidth/2 - SPR_Width(m_hSprite, 2)/2; - y = ScreenHeight/2 + SPR_Height(m_hSprite,2) * 2; - SPR_DrawAdditive(2, x, y, NULL); - m_fAttackRear = V_max( 0, m_fAttackRear - fFade ); - } else - m_fAttackRear = 0; - - if (m_fAttackLeft > 0.4) - { - GetPainColor(r,g,b); - shade = a * V_max( m_fAttackLeft, 0.5 ); - ScaleColors(r, g, b, shade); - SPR_Set(m_hSprite, r, g, b ); - - x = ScreenWidth/2 - SPR_Width(m_hSprite, 3) * 3; - y = ScreenHeight/2 - SPR_Height(m_hSprite,3)/2; - SPR_DrawAdditive(3, x, y, NULL); - - m_fAttackLeft = V_max( 0, m_fAttackLeft - fFade ); - } else - m_fAttackLeft = 0; - - return 1; -} - -int CHudHealth::DrawDamage(float flTime) -{ - int r, g, b, a; - DAMAGE_IMAGE *pdmg; - - if (!m_bitsDamage) - return 1; - - UnpackRGB(r,g,b, RGB_YELLOWISH); - - a = (int)( fabs(sin(flTime*2)) * 256.0); - - ScaleColors(r, g, b, a); - - // Draw all the items - int i; - for (i = 0; i < NUM_DMG_TYPES; i++) - { - if (m_bitsDamage & giDmgFlags[i]) - { - pdmg = &m_dmg[i]; - SPR_Set(gHUD.GetSprite(m_HUD_dmg_bio + i), r, g, b ); - SPR_DrawAdditive(0, pdmg->x, pdmg->y, &gHUD.GetSpriteRect(m_HUD_dmg_bio + i)); - } - } - - - // check for bits that should be expired - for ( i = 0; i < NUM_DMG_TYPES; i++ ) - { - DAMAGE_IMAGE *pdmg = &m_dmg[i]; - - if ( m_bitsDamage & giDmgFlags[i] ) - { - pdmg->fExpire = V_min( flTime + DMG_IMAGE_LIFE, pdmg->fExpire ); - - if ( pdmg->fExpire <= flTime // when the time has expired - && a < 40 ) // and the flash is at the low point of the cycle - { - pdmg->fExpire = 0; - - int y = pdmg->y; - pdmg->x = pdmg->y = 0; - - // move everyone above down - for (int j = 0; j < NUM_DMG_TYPES; j++) - { - pdmg = &m_dmg[j]; - if ((pdmg->y) && (pdmg->y < y)) - pdmg->y += giDmgHeight; - - } - - m_bitsDamage &= ~giDmgFlags[i]; // clear the bits - } - } - } - - return 1; -} - - -void CHudHealth::UpdateTiles(float flTime, long bitsDamage) -{ - DAMAGE_IMAGE *pdmg; - - // Which types are new? - long bitsOn = ~m_bitsDamage & bitsDamage; - - for (int i = 0; i < NUM_DMG_TYPES; i++) - { - pdmg = &m_dmg[i]; - - // Is this one already on? - if (m_bitsDamage & giDmgFlags[i]) - { - pdmg->fExpire = flTime + DMG_IMAGE_LIFE; // extend the duration - if (!pdmg->fBaseline) - pdmg->fBaseline = flTime; - } - - // Are we just turning it on? - if (bitsOn & giDmgFlags[i]) - { - // put this one at the bottom - pdmg->x = giDmgWidth/8; - pdmg->y = ScreenHeight - giDmgHeight * 2; - pdmg->fExpire=flTime + DMG_IMAGE_LIFE; - - // move everyone else up - for (int j = 0; j < NUM_DMG_TYPES; j++) - { - if (j == i) - continue; - - pdmg = &m_dmg[j]; - if (pdmg->y) - pdmg->y -= giDmgHeight; - - } - pdmg = &m_dmg[i]; - } - } - - // damage bits are only turned on here; they are turned off when the draw time has expired (in DrawDamage()) - m_bitsDamage |= bitsDamage; -} - diff --git a/dmc/cl_dll/health.h b/dmc/cl_dll/health.h deleted file mode 100644 index 5120103..0000000 --- a/dmc/cl_dll/health.h +++ /dev/null @@ -1,130 +0,0 @@ -/*** -* -* 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. -* -****/ - -#define DMG_IMAGE_LIFE 2 // seconds that image is up - -#define DMG_IMAGE_POISON 0 -#define DMG_IMAGE_ACID 1 -#define DMG_IMAGE_COLD 2 -#define DMG_IMAGE_DROWN 3 -#define DMG_IMAGE_BURN 4 -#define DMG_IMAGE_NERVE 5 -#define DMG_IMAGE_RAD 6 -#define DMG_IMAGE_SHOCK 7 -//tf defines -#define DMG_IMAGE_CALTROP 8 -#define DMG_IMAGE_TRANQ 9 -#define DMG_IMAGE_CONCUSS 10 -#define DMG_IMAGE_HALLUC 11 -#define NUM_DMG_TYPES 12 -// instant damage - -#define DMG_GENERIC 0 // generic damage was done -#define DMG_CRUSH (1 << 0) // crushed by falling or moving object -#define DMG_BULLET (1 << 1) // shot -#define DMG_SLASH (1 << 2) // cut, clawed, stabbed -#define DMG_BURN (1 << 3) // heat burned -#define DMG_FREEZE (1 << 4) // frozen -#define DMG_FALL (1 << 5) // fell too far -#define DMG_BLAST (1 << 6) // explosive blast damage -#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt -#define DMG_SHOCK (1 << 8) // electric shock -#define DMG_SONIC (1 << 9) // sound pulse shockwave -#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam -#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death -#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death. - - -// time-based damage -//mask off TF-specific stuff too -#define DMG_TIMEBASED (~(0xff003fff)) // mask for time-based damage - - -#define DMG_DROWN (1 << 14) // Drowning -#define DMG_FIRSTTIMEBASED DMG_DROWN - -#define DMG_PARALYZE (1 << 15) // slows affected creature down -#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad -#define DMG_POISON (1 << 17) // blood poisioning -#define DMG_RADIATION (1 << 18) // radiation exposure -#define DMG_DROWNRECOVER (1 << 19) // drowning recovery -#define DMG_ACID (1 << 20) // toxic chemicals or acid burns -#define DMG_SLOWBURN (1 << 21) // in an oven -#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer -#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar) - -//TF ADDITIONS -#define DMG_IGNITE (1 << 24) // Players hit by this begin to burn -#define DMG_RADIUS_MAX (1 << 25) // Radius damage with this flag doesn't decrease over distance -#define DMG_RADIUS_QUAKE (1 << 26) // Radius damage is done like Quake. 1/2 damage at 1/2 radius. -#define DMG_IGNOREARMOR (1 << 27) // Damage ignores target's armor -#define DMG_AIMED (1 << 28) // Does Hit location damage -#define DMG_WALLPIERCING (1 << 29) // Blast Damages ents through walls - -#define DMG_CALTROP (1<<30) -#define DMG_HALLUC (1<<31) - -// TF Healing Additions for TakeHealth -#define DMG_IGNORE_MAXHEALTH DMG_IGNITE -// TF Redefines since we never use the originals -#define DMG_NAIL DMG_SLASH -#define DMG_NOT_SELF DMG_FREEZE - - -#define DMG_TRANQ DMG_MORTAR -#define DMG_CONCUSS DMG_SONIC - - - -typedef struct -{ - float fExpire; - float fBaseline; - int x, y; -} DAMAGE_IMAGE; - -// -//----------------------------------------------------- -// -class CHudHealth: public CHudBase -{ -public: - virtual int Init( void ); - virtual int VidInit( void ); - virtual int Draw(float fTime); - virtual void Reset( void ); - int MsgFunc_Health(const char *pszName, int iSize, void *pbuf); - int MsgFunc_Damage(const char *pszName, int iSize, void *pbuf); - int m_iHealth; - int m_HUD_dmg_bio; - int m_HUD_cross; - - void GetPainColor( int &r, int &g, int &b ); - float m_fFade; - -private: - HSPRITE m_hSprite; - HSPRITE m_hDamage; - - DAMAGE_IMAGE m_dmg[NUM_DMG_TYPES]; - int m_bitsDamage; - - - int DrawPain(float fTime); - int DrawDamage(float fTime); - float m_fAttackFront, m_fAttackRear, m_fAttackLeft, m_fAttackRight; - void CalcDamageDirection(vec3_t vecFrom); - void UpdateTiles(float fTime, long bits); -}; diff --git a/dmc/cl_dll/hud.cpp b/dmc/cl_dll/hud.cpp deleted file mode 100644 index 65fa852..0000000 --- a/dmc/cl_dll/hud.cpp +++ /dev/null @@ -1,594 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// hud.cpp -// -// implementation of CHud class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" -#include "hud_servers.h" -#include "vgui_viewport.h" -#include "demo.h" -#include "demo_api.h" -#include "voice_status.h" -#include "vgui_ScorePanel.h" - - -class CDMCVoiceStatusHelper : public IVoiceStatusHelper -{ -public: - virtual void GetPlayerTextColor(int entindex, int color[3]) - { - color[0] = color[1] = color[2] = 255; - - if( entindex >= 0 && entindex < sizeof(g_PlayerExtraInfo)/sizeof(g_PlayerExtraInfo[0]) ) - { - int iTeam = g_PlayerExtraInfo[entindex].teamnumber; - - if( iTeam >= 0 && iTeam < sizeof(iTeamColors)/sizeof(iTeamColors[0]) ) - { - color[0] = iTeamColors[iTeam][0]; - color[1] = iTeamColors[iTeam][1]; - color[2] = iTeamColors[iTeam][2]; - } - } - } - - virtual void UpdateCursorState() - { - gViewPort->UpdateCursorState(); - } - - virtual int GetAckIconHeight() - { - return ScreenHeight - gHUD.m_iFontHeight*2 - 6; - } - - virtual bool CanShowSpeakerLabels() - { - if( gViewPort && gViewPort->m_pScoreBoard ) - return !gViewPort->m_pScoreBoard->isVisible(); - else - return false; - } -}; -static CDMCVoiceStatusHelper g_VoiceStatusHelper; - - - -extern client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes, int iCount); - -extern cvar_t *sensitivity; -cvar_t *cl_lw = NULL; -cvar_t *cl_autowepswitch; -cvar_t *cl_rollspeed; -cvar_t *cl_rollangle; -cvar_t *cl_fov; - -void ShutdownInput (void); - -void __CmdFunc_ToggleServerBrowser( void ) -{ - if ( gViewPort ) - { - gViewPort->ToggleServerBrowser(); - } -} - -//DECLARE_MESSAGE(m_Logo, Logo) -int __MsgFunc_Logo(const char *pszName, int iSize, void *pbuf) -{ - return gHUD.MsgFunc_Logo(pszName, iSize, pbuf ); -} - -//DECLARE_MESSAGE(m_Logo, Logo) -int __MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf) -{ - return gHUD.MsgFunc_ResetHUD(pszName, iSize, pbuf ); -} - -int __MsgFunc_InitHUD(const char *pszName, int iSize, void *pbuf) -{ - gHUD.MsgFunc_InitHUD( pszName, iSize, pbuf ); - return 1; -} - -int __MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf) -{ - return gHUD.MsgFunc_SetFOV( pszName, iSize, pbuf ); -} - -int __MsgFunc_Concuss(const char *pszName, int iSize, void *pbuf) -{ - return gHUD.MsgFunc_Concuss( pszName, iSize, pbuf ); -} - -int __MsgFunc_GameMode(const char *pszName, int iSize, void *pbuf ) -{ - return gHUD.MsgFunc_GameMode( pszName, iSize, pbuf ); -} - -int __MsgFunc_MOTD(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_MOTD( pszName, iSize, pbuf ); - return 0; -} - -int __MsgFunc_ServerName(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_ServerName( pszName, iSize, pbuf ); - return 0; -} - -// QUAKECLASSIC -int __MsgFunc_QItems(const char *pszName, int iSize, void *pbuf) -{ - return gHUD.MsgFunc_QItems( pszName, iSize, pbuf ); -} - -int __MsgFunc_ScoreInfo(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_ScoreInfo( pszName, iSize, pbuf ); - return 0; -} - -int __MsgFunc_TeamInfo(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_TeamInfo( pszName, iSize, pbuf ); - return 0; -} - -void __CmdFunc_OpenCommandMenu(void) -{ - if ( gViewPort ) - { - gViewPort->ShowCommandMenu( gViewPort->m_StandardMenu ); - } -} - -void __CmdFunc_CloseCommandMenu(void) -{ - if ( gViewPort ) - { - gViewPort->InputSignalHideCommandMenu(); - } -} - -void __CmdFunc_ForceCloseCommandMenu( void ) -{ - if ( gViewPort ) - { - gViewPort->HideCommandMenu(); - } -} - -// This is called every time the DLL is loaded -void CHud :: Init( void ) -{ - HOOK_MESSAGE( Logo ); - HOOK_MESSAGE( ResetHUD ); - HOOK_MESSAGE( GameMode ); - HOOK_MESSAGE( InitHUD ); - HOOK_MESSAGE( SetFOV ); - HOOK_MESSAGE( Concuss ); - - HOOK_MESSAGE( MOTD ); - HOOK_MESSAGE( ServerName ); - - HOOK_COMMAND( "togglebrowser", ToggleServerBrowser ); - - HOOK_COMMAND( "+commandmenu", OpenCommandMenu ); - HOOK_COMMAND( "-commandmenu", CloseCommandMenu ); - HOOK_COMMAND( "ForceCloseCommandMenu", ForceCloseCommandMenu ); - - // QUAKECLASSIC - HOOK_MESSAGE( QItems ); - HOOK_MESSAGE( ScoreInfo ); - //HOOK_MESSAGE( TeamScore ); - HOOK_MESSAGE( TeamInfo ); - - m_iLogo = 0; - m_iFOV = 0; - - CVAR_CREATE( "zoom_sensitivity_ratio", "1.2", 0 ); - default_fov = CVAR_CREATE( "default_fov", "90", 0 ); - cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); - m_pCvarStealMouse = CVAR_CREATE( "hud_capturemouse", "1", FCVAR_ARCHIVE ); - m_pCvarDraw = CVAR_CREATE( "hud_draw", "1", FCVAR_ARCHIVE ); - /************************ CLIENT CVAR DEFINITIONS ************************/ - cl_autowepswitch = gEngfuncs.pfnRegisterVariable ( "cl_autowepswitch", "2", FCVAR_USERINFO|FCVAR_ARCHIVE ); - cl_rollangle = gEngfuncs.pfnRegisterVariable ( "cl_rollangle", "0.65", FCVAR_CLIENTDLL|FCVAR_ARCHIVE ); - cl_rollspeed = gEngfuncs.pfnRegisterVariable ( "cl_rollspeed", "300", FCVAR_CLIENTDLL|FCVAR_ARCHIVE ); - cl_fov = gEngfuncs.pfnRegisterVariable ( "cl_fov", "90", FCVAR_USERINFO|FCVAR_ARCHIVE ); - /************************ CLIENT CVAR DEFINITIONS ************************/ - - m_pSpriteList = NULL; - - // Clear any old HUD list - if ( m_pHudList ) - { - HUDLIST *pList; - while ( m_pHudList ) - { - pList = m_pHudList; - m_pHudList = m_pHudList->pNext; - free( pList ); - } - m_pHudList = NULL; - } - - // In case we get messages before the first update -- time will be valid - m_flTime = 1.0; - - m_Ammo.Init(); - m_Health.Init(); - m_SayText.Init(); - m_Spectator.Init(); - m_Geiger.Init(); - m_Train.Init(); - m_Battery.Init(); - m_Message.Init(); -// m_Scoreboard.Init(); -// m_MOTD.Init(); - m_StatusBar.Init(); - m_DeathNotice.Init(); - m_AmmoSecondary.Init(); - m_TextMessage.Init(); - m_StatusIcons.Init(); - - GetClientVoiceMgr()->Init(&g_VoiceStatusHelper, (vgui::Panel**)&gViewPort); - - - m_Menu.Init(); - - ServersInit(); - - MsgFunc_ResetHUD(0, 0, NULL ); -} - -CHud::CHud() : m_iSpriteCount(0), m_pHudList(NULL) -{ -} - -// CHud destructor -// cleans up memory allocated for m_rg* arrays -CHud :: ~CHud() -{ - delete [] m_rghSprites; - delete [] m_rgrcRects; - delete [] m_rgszSpriteNames; - - if ( m_pHudList ) - { - HUDLIST *pList; - while ( m_pHudList ) - { - pList = m_pHudList; - m_pHudList = m_pHudList->pNext; - free( pList ); - } - m_pHudList = NULL; - } - - ServersShutdown(); -} - -// GetSpriteIndex() -// searches through the sprite list loaded from hud.txt for a name matching SpriteName -// returns an index into the gHUD.m_rghSprites[] array -// returns 0 if sprite not found -int CHud :: GetSpriteIndex( const char *SpriteName ) -{ - // look through the loaded sprite name list for SpriteName - for ( int i = 0; i < m_iSpriteCount; i++ ) - { - if ( strncmp( SpriteName, m_rgszSpriteNames + (i * MAX_SPRITE_NAME_LENGTH), MAX_SPRITE_NAME_LENGTH ) == 0 ) - return i; - } - - return -1; // invalid sprite -} - -void CHud :: VidInit( void ) -{ - m_scrinfo.iSize = sizeof(m_scrinfo); - GetScreenInfo(&m_scrinfo); - - // ---------- - // Load Sprites - // --------- -// m_hsprFont = LoadSprite("sprites/%d_font.spr"); - - m_hsprLogo = 0; - m_hsprCursor = 0; - - if (ScreenWidth < 640) - m_iRes = 320; - else - m_iRes = 640; - - // Only load this once - if ( !m_pSpriteList ) - { - // we need to load the hud.txt, and all sprites within - m_pSpriteList = SPR_GetList("sprites/hud.txt", &m_iSpriteCountAllRes); - - if (m_pSpriteList) - { - // count the number of sprites of the appropriate res - m_iSpriteCount = 0; - client_sprite_t *p = m_pSpriteList; - int j; - for ( j = 0; j < m_iSpriteCountAllRes; j++ ) - { - if ( p->iRes == m_iRes ) - m_iSpriteCount++; - p++; - } - - // allocated memory for sprite handle arrays - m_rghSprites = new HSPRITE[m_iSpriteCount]; - m_rgrcRects = new wrect_t[m_iSpriteCount]; - m_rgszSpriteNames = new char[m_iSpriteCount * MAX_SPRITE_NAME_LENGTH]; - - p = m_pSpriteList; - int index = 0; - for ( j = 0; j < m_iSpriteCountAllRes; j++ ) - { - if ( p->iRes == m_iRes ) - { - char sz[256]; - sprintf(sz, "sprites/%s.spr", p->szSprite); - m_rghSprites[index] = SPR_Load(sz); - m_rgrcRects[index] = p->rc; - strncpy( &m_rgszSpriteNames[index * MAX_SPRITE_NAME_LENGTH], p->szName, MAX_SPRITE_NAME_LENGTH ); - - index++; - } - - p++; - } - } - } - else - { - // we have already have loaded the sprite reference from hud.txt, but - // we need to make sure all the sprites have been loaded (we've gone through a transition, or loaded a save game) - client_sprite_t *p = m_pSpriteList; - int index = 0; - for ( int j = 0; j < m_iSpriteCountAllRes; j++ ) - { - if ( p->iRes == m_iRes ) - { - char sz[256]; - sprintf( sz, "sprites/%s.spr", p->szSprite ); - m_rghSprites[index] = SPR_Load(sz); - index++; - } - - p++; - } - } - - // assumption: number_1, number_2, etc, are all listed and loaded sequentially - m_HUD_number_0 = GetSpriteIndex( "number_0" ); - - m_iFontHeight = m_rgrcRects[m_HUD_number_0].bottom - m_rgrcRects[m_HUD_number_0].top; - - m_Ammo.VidInit(); - m_Health.VidInit(); - m_Spectator.VidInit(); - m_Geiger.VidInit(); - m_Train.VidInit(); - m_Battery.VidInit(); - m_Message.VidInit(); -// m_Scoreboard.VidInit(); -// m_MOTD.VidInit(); - m_StatusBar.VidInit(); - m_DeathNotice.VidInit(); - m_SayText.VidInit(); - m_Menu.VidInit(); - m_AmmoSecondary.VidInit(); - m_TextMessage.VidInit(); - m_StatusIcons.VidInit(); - - GetClientVoiceMgr()->VidInit(); -} - -int CHud::MsgFunc_Logo(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - // update Train data - m_iLogo = READ_BYTE(); - - return 1; -} - -float g_lastFOV = 0.0; - -/* -============ -COM_FileBase -============ -*/ -// Extracts the base name of a file (no path, no extension, assumes '/' as path separator) -void COM_FileBase ( const char *in, char *out) -{ - int len, start, end; - - len = strlen( in ); - - // scan backward for '.' - end = len - 1; - while ( end && in[end] != '.' && in[end] != '/' && in[end] != '\\' ) - end--; - - if ( in[end] != '.' ) // no '.', copy to end - end = len-1; - else - end--; // Found ',', copy to left of '.' - - - // Scan backward for '/' - start = len-1; - while ( start >= 0 && in[start] != '/' && in[start] != '\\' ) - start--; - - if ( in[start] != '/' && in[start] != '\\' ) - start = 0; - else - start++; - - // Length of new sting - len = end - start + 1; - - // Copy partial string - strncpy( out, &in[start], len ); - // Terminate it - out[len] = 0; -} - -/* -================= -HUD_IsGame - -================= -*/ -int HUD_IsGame( const char *game ) -{ - const char *gamedir; - char gd[ 1024 ]; - - gamedir = gEngfuncs.pfnGetGameDirectory(); - if ( gamedir && gamedir[0] ) - { - COM_FileBase( gamedir, gd ); - if ( !stricmp( gd, game ) ) - return 1; - } - return 0; -} - -/* -===================== -HUD_GetFOV - -Returns last FOV -===================== -*/ -float HUD_GetFOV( void ) -{ - /* - if ( gEngfuncs.pDemoAPI->IsRecording() ) - { - // Write it - int i = 0; - unsigned char buf[ 100 ]; - - // Active - *( float * )&buf[ i ] = g_lastFOV; - i += sizeof( float ); - - Demo_WriteBuffer( TYPE_ZOOM, i, buf ); - } - - if ( gEngfuncs.pDemoAPI->IsPlayingback() ) - { - g_lastFOV = g_demozoom; - } - */ - return g_lastFOV; -} - -int CHud::MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - int newfov = READ_BYTE(); - int def_fov = CVAR_GET_FLOAT( "default_fov" ); - - if ( newfov == 0 ) - { - m_iFOV = def_fov; - } - else - { - m_iFOV = newfov; - } - - // the clients fov is actually set in the client data update section of the hud - - // Set a new sensitivity - if ( m_iFOV == def_fov ) - { - // reset to saved sensitivity - m_flMouseSensitivity = 0; - } - else - { - // set a new sensitivity that is proportional to the change from the FOV default - m_flMouseSensitivity = sensitivity->value * ((float)newfov / (float)def_fov) * CVAR_GET_FLOAT("zoom_sensitivity_ratio"); - } - - return 1; -} - - -void CHud::AddHudElem(CHudBase *phudelem) -{ - HUDLIST *pdl, *ptemp; - -//phudelem->Think(); - - if (!phudelem) - return; - - pdl = (HUDLIST *)malloc(sizeof(HUDLIST)); - if (!pdl) - return; - - memset(pdl, 0, sizeof(HUDLIST)); - pdl->p = phudelem; - - if (!m_pHudList) - { - m_pHudList = pdl; - return; - } - - ptemp = m_pHudList; - - while (ptemp->pNext) - ptemp = ptemp->pNext; - - ptemp->pNext = pdl; -} - -float CHud::GetSensitivity( void ) -{ - return m_flMouseSensitivity; -} - - diff --git a/dmc/cl_dll/hud.h b/dmc/cl_dll/hud.h deleted file mode 100644 index dd74d36..0000000 --- a/dmc/cl_dll/hud.h +++ /dev/null @@ -1,659 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// hud.h -// -// class CHud declaration -// -// CHud handles the message, calculation, and drawing the HUD -// - - -#define RGB_YELLOWISH 0x00FFA000 //255,160,0 -#define RGB_REDISH 0x00FF1010 //255,160,0 -#define RGB_GREENISH 0x0000A000 //0,160,0 -#define RGB_NORMAL 0x00FFFFFF // 255,255,255 - -#include "wrect.h" - -#include "cl_dll.h" -#include "ammo.h" - -#define DHN_DRAWZERO 1 -#define DHN_2DIGITS 2 -#define DHN_3DIGITS 4 -#define MIN_ALPHA 100 - -#define HUDELEM_ACTIVE 1 - -typedef struct { - int x, y; -} POSITION; - -typedef struct { - unsigned char r,g,b,a; -} RGBA; -typedef struct cvar_s cvar_t; - - -#define HUD_ACTIVE 1 -#define HUD_INTERMISSION 2 - -#define MAX_PLAYER_NAME_LENGTH 32 - -#define MAX_MOTD_LENGTH 1024 - -#ifndef _WIN32 -#define _cdecl -#endif - -enum -{ - MAX_PLAYERS = 64, - MAX_TEAMS = 64, - MAX_TEAM_NAME = 16, -}; - -struct extra_player_info_t -{ - short frags; - short deaths; - short teamnumber; - char teamname[MAX_TEAM_NAME]; -}; - -struct team_info_t -{ - char name[MAX_TEAM_NAME]; - short frags; - short deaths; - short ping; - short packetloss; - short ownteam; - short players; - int already_drawn; - int scores_overriden; - int teamnumber; -}; - -extern hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine -extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll -extern team_info_t g_TeamInfo[MAX_TEAMS+1]; - -// -//----------------------------------------------------- -// -class CHudBase -{ -public: - POSITION m_pos; - int m_type; - int m_iFlags; // active, moving, - virtual int Init( void ) {return 0;} - virtual int VidInit( void ) {return 0;} - virtual int Draw(float flTime) {return 0;} - virtual void Think(void) {return;} - virtual void Reset(void) {return;} - virtual void InitHUDData( void ) {} // called every time a server is connected to - -}; - -struct HUDLIST { - CHudBase *p; - HUDLIST *pNext; -}; - - -#include "hud_spectator.h" -// -//----------------------------------------------------- -// -class CHudAmmo: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - void Think(void); - void Reset(void); - int DrawWList(float flTime); - int DrawFastList(float flTime); - float m_flFastListTime; - int MsgFunc_CurWeapon(const char *pszName, int iSize, void *pbuf); - int MsgFunc_WeaponList(const char *pszName, int iSize, void *pbuf); - int MsgFunc_AmmoX(const char *pszName, int iSize, void *pbuf); - int MsgFunc_AmmoPickup( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_WeapPickup( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_ItemPickup( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ); - - void _cdecl UserCmd_Slot1( void ); - void _cdecl UserCmd_Slot2( void ); - void _cdecl UserCmd_Slot3( void ); - void _cdecl UserCmd_Slot4( void ); - void _cdecl UserCmd_Slot5( void ); - void _cdecl UserCmd_Slot6( void ); - void _cdecl UserCmd_Slot7( void ); - void _cdecl UserCmd_Slot8( void ); - void _cdecl UserCmd_Slot9( void ); - void _cdecl UserCmd_Slot10( void ); - void _cdecl UserCmd_Close( void ); - void _cdecl UserCmd_NextWeapon( void ); - void _cdecl UserCmd_PrevWeapon( void ); - - int m_iXPosition; - int m_iNumberXPosition; - HSPRITE m_sprAmmoSprite; - int m_HUD_Ammo; - wrect_t *m_prc1; - -private: - float m_fFade; - RGBA m_rgba; - WEAPON *m_pWeapon; - int m_HUD_bucket0; - int m_HUD_selection; - - -}; - -// -//----------------------------------------------------- -// - -class CHudAmmoSecondary: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - void Reset( void ); - int Draw(float flTime); - - int MsgFunc_SecAmmoVal( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_SecAmmoIcon( const char *pszName, int iSize, void *pbuf ); - -private: - enum { - MAX_SEC_AMMO_VALUES = 4 - }; - - int m_HUD_ammoicon; // sprite indices - int m_iAmmoAmounts[MAX_SEC_AMMO_VALUES]; - float m_fFade; -}; - - -#include "health.h" - - -#define FADE_TIME 100 - -// -//----------------------------------------------------- -// -class CHudGeiger: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - int MsgFunc_Geiger(const char *pszName, int iSize, void *pbuf); - -private: - int m_iGeigerRange; - -}; - -// -//----------------------------------------------------- -// -class CHudTrain: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - int MsgFunc_Train(const char *pszName, int iSize, void *pbuf); - -private: - HSPRITE m_hSprite; - int m_iPos; - -}; -// -//----------------------------------------------------- -// -// REMOVED: Vgui has replaced this. -// -// -//----------------------------------------------------- -/* -class CHudMOTD : public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw( float flTime ); - void Reset( void ); - - int MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf ); - -protected: - static int MOTD_DISPLAY_TIME; - char m_szMOTD[ MAX_MOTD_LENGTH ]; - float m_flActiveRemaining; - int m_iLines; -}; -*/ -// -//----------------------------------------------------- -// -class CHudStatusBar : public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw( float flTime ); - void Reset( void ); - void ParseStatusString( int line_num ); - - int MsgFunc_StatusText( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_StatusValue( const char *pszName, int iSize, void *pbuf ); - -protected: - enum { - MAX_STATUSTEXT_LENGTH = 128, - MAX_STATUSBAR_VALUES = 8, - MAX_STATUSBAR_LINES = 2, - }; - - HSPRITE m_hArmor; - HSPRITE m_hHealth; - int m_iArmorSpriteIndex; - int m_iHealthSpriteIndex; - - - char m_szStatusText[MAX_STATUSBAR_LINES][MAX_STATUSTEXT_LENGTH]; // a text string describing how the status bar is to be drawn - char m_szStatusBar[MAX_STATUSBAR_LINES][MAX_STATUSTEXT_LENGTH]; // the constructed bar that is drawn - int m_iStatusValues[MAX_STATUSBAR_VALUES]; // an array of values for use in the status bar - - char m_szName[MAX_STATUSBAR_LINES][MAX_STATUSTEXT_LENGTH]; - char m_szHealth[MAX_STATUSBAR_LINES][MAX_STATUSTEXT_LENGTH]; - char m_szArmor[MAX_STATUSBAR_LINES][MAX_STATUSTEXT_LENGTH]; - - int m_iTeamMate[MAX_STATUSBAR_LINES]; - - int m_bReparseString; // set to TRUE whenever the m_szStatusBar needs to be recalculated -}; - -// -//----------------------------------------------------- -// - -/*class CHudScoreboard: public CHudBase -{ -public: - int Init( void ); - void InitHUDData( void ); - int VidInit( void ); - int Draw( float flTime ); - int DrawPlayers( int xoffset, float listslot, int nameoffset = 0, char *team = NULL ); // returns the ypos where it finishes drawing - void UserCmd_ShowScores( void ); - void UserCmd_HideScores( void ); - int MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf ); - void DeathMsg( int killer, int victim ); - - - - int m_iNumTeams; - - int m_iLastKilledBy; - int m_fLastKillTime; - int m_iPlayerNum; - int m_iShowscoresHeld; - - void GetAllPlayersInfo( void ); - - - -}; - -*/ - -// -//----------------------------------------------------- -// -class CHudDeathNotice : public CHudBase -{ -public: - int Init( void ); - void InitHUDData( void ); - int VidInit( void ); - int Draw( float flTime ); - int MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbuf ); - -private: - int m_HUD_d_skull; // sprite index of skull icon - - char szText[256][4]; -}; - -// -//----------------------------------------------------- -// -class CHudMenu : public CHudBase -{ -public: - int Init( void ); - void InitHUDData( void ); - int VidInit( void ); - void Reset( void ); - int Draw( float flTime ); - int MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf ); - - void SelectMenuItem( int menu_item ); - - int m_fMenuDisplayed; - int m_bitsValidSlots; - float m_flShutoffTime; - int m_fWaitingForMore; -}; - -// -//----------------------------------------------------- -// -class CHudSayText : public CHudBase -{ -public: - int Init( void ); - void InitHUDData( void ); - int VidInit( void ); - int Draw( float flTime ); - int MsgFunc_SayText( const char *pszName, int iSize, void *pbuf ); - void SayTextPrint( const char *pszBuf, int iBufSize, int clientIndex = -1 ); - void EnsureTextFitsInOneLineAndWrapIfHaveTo( int line ); - - struct cvar_s * m_HUD_saytext; - struct cvar_s * m_HUD_saytext_time; -}; - -// -//----------------------------------------------------- -// -class CHudBattery: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - int MsgFunc_Battery(const char *pszName, int iSize, void *pbuf ); - -private: - HSPRITE m_hSprite1; - HSPRITE m_hSprite2; - wrect_t *m_prc1; - wrect_t *m_prc2; - int m_iBat; - float m_fFade; - int m_iHeight; // width of the battery innards -}; - - -// -//----------------------------------------------------- -// -const int maxHUDMessages = 16; -struct message_parms_t -{ - client_textmessage_t *pMessage; - float time; - int x, y; - int totalWidth, totalHeight; - int width; - int lines; - int lineLength; - int length; - int r, g, b; - int text; - int fadeBlend; - float charTime; - float fadeTime; -}; - -// -//----------------------------------------------------- -// - -class CHudTextMessage: public CHudBase -{ -public: - int Init( void ); - static char *LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size ); - static char *BufferedLocaliseTextString( const char *msg ); - char *LookupString( const char *msg_name, int *msg_dest = NULL ); - int MsgFunc_TextMsg(const char *pszName, int iSize, void *pbuf); -}; - -// -//----------------------------------------------------- -// - -class CHudMessage: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - int MsgFunc_HudText(const char *pszName, int iSize, void *pbuf); - int MsgFunc_GameTitle(const char *pszName, int iSize, void *pbuf); - - float FadeBlend( float fadein, float fadeout, float hold, float localTime ); - int XPosition( float x, int width, int lineWidth ); - int YPosition( float y, int height ); - - void MessageAdd( const char *pName, float time ); - void MessageAdd(client_textmessage_t * newMessage ); - void MessageDrawScan( client_textmessage_t *pMessage, float time ); - void MessageScanStart( void ); - void MessageScanNextChar( void ); - void Reset( void ); - -private: - client_textmessage_t *m_pMessages[maxHUDMessages]; - float m_startTime[maxHUDMessages]; - message_parms_t m_parms; - float m_gameTitleTime; - client_textmessage_t *m_pGameTitle; - - int m_HUD_title_life; - int m_HUD_title_half; -}; - -// -//----------------------------------------------------- -// -#define MAX_SPRITE_NAME_LENGTH 24 - -class CHudStatusIcons: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - void Reset( void ); - int Draw(float flTime); - int MsgFunc_StatusIcon(const char *pszName, int iSize, void *pbuf); - - enum { - MAX_ICONSPRITENAME_LENGTH = MAX_SPRITE_NAME_LENGTH, - MAX_ICONSPRITES = 4, - }; - - - //had to make these public so CHud could access them (to enable concussion icon) - //could use a friend declaration instead... - void EnableIcon( char *pszIconName, unsigned char red, unsigned char green, unsigned char blue ); - void DisableIcon( char *pszIconName ); - -private: - - typedef struct - { - char szSpriteName[MAX_ICONSPRITENAME_LENGTH]; - HSPRITE spr; - wrect_t rc; - unsigned char r, g, b; - } icon_sprite_t; - - icon_sprite_t m_IconList[MAX_ICONSPRITES]; - -}; - - -// -//----------------------------------------------------- -// -class CVoiceStatus; -typedef struct cvar_s cvar_t; - -class CHud -{ -private: - HUDLIST *m_pHudList; - HSPRITE m_hsprLogo; - int m_iLogo; - client_sprite_t *m_pSpriteList; - int m_iSpriteCount; - int m_iSpriteCountAllRes; - float m_flMouseSensitivity; - int m_iConcussionEffect; - -public: - - HSPRITE m_hsprCursor; - float m_flTime; // the current client time - float m_fOldTime; // the time at which the HUD was last redrawn - double m_flTimeDelta; // the difference between flTime and fOldTime - Vector m_vecOrigin; - Vector m_vecAngles; - int m_iKeyBits; - int m_iHideHUDDisplay; - int m_iFOV; - int m_Teamplay; - int m_iRes; - cvar_t *m_pCvarStealMouse; - cvar_t *m_pCvarDraw; - - // QUAKECLASSIC - int m_iQuakeItems; - - int m_iFontHeight; - int DrawHudNumber(int x, int y, int iFlags, int iNumber, int r, int g, int b ); - int DrawHudString(int x, int y, int iMaxX, char *szString, int r, int g, int b ); - - int DrawHudStringCTF(int x, int y, int iMaxX, char *szString, int r, int g, int b ); - - int ReturnStringPixelLength ( char *Hihi ); - - int DrawHudStringReverse( int xpos, int ypos, int iMinX, char *szString, int r, int g, int b ); - int DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r, int g, int b ); - int GetNumWidth(int iNumber, int iFlags); - -private: - // the memory for these arrays are allocated in the first call to CHud::VidInit(), when the hud.txt and associated sprites are loaded. - // freed in ~CHud() - HSPRITE *m_rghSprites; /*[HUD_SPRITE_COUNT]*/ // the sprites loaded from hud.txt - wrect_t *m_rgrcRects; /*[HUD_SPRITE_COUNT]*/ - char *m_rgszSpriteNames; /*[HUD_SPRITE_COUNT][MAX_SPRITE_NAME_LENGTH]*/ - - struct cvar_s *default_fov; -public: - HSPRITE GetSprite( int index ) - { - return (index < 0) ? 0 : m_rghSprites[index]; - } - - wrect_t& GetSpriteRect( int index ) - { - return m_rgrcRects[index]; - } - - - int GetSpriteIndex( const char *SpriteName ); // gets a sprite index, for use in the m_rghSprites[] array - - CHudAmmo m_Ammo; - CHudHealth m_Health; - CHudSpectator m_Spectator; - CHudGeiger m_Geiger; - CHudBattery m_Battery; - CHudTrain m_Train; - CHudMessage m_Message; -// CHudScoreboard m_Scoreboard; -// CHudMOTD m_MOTD; - CHudStatusBar m_StatusBar; - CHudDeathNotice m_DeathNotice; - CHudSayText m_SayText; - CHudMenu m_Menu; - CHudAmmoSecondary m_AmmoSecondary; - CHudTextMessage m_TextMessage; - CHudStatusIcons m_StatusIcons; - - void Init( void ); - void VidInit( void ); - void Think(void); - int Redraw( float flTime, int intermission ); - int UpdateClientData( client_data_t *cdata, float time ); - - CHud(); - ~CHud(); // destructor, frees allocated memory - - // user messages - int _cdecl MsgFunc_Damage(const char *pszName, int iSize, void *pbuf ); - int _cdecl MsgFunc_GameMode(const char *pszName, int iSize, void *pbuf ); - int _cdecl MsgFunc_Logo(const char *pszName, int iSize, void *pbuf); - int _cdecl MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf); - void _cdecl MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf ); - int _cdecl MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf); - int _cdecl MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf ); - - // QUAKECLASSIC - int _cdecl MsgFunc_QItems( const char *pszName, int iSize, void *pbuf ); - - // Screen information - SCREENINFO m_scrinfo; - - int m_iWeaponBits; - int m_fPlayerDead; - int m_iIntermission; - - // sprite indexes - int m_HUD_number_0; - - - void AddHudElem(CHudBase *p); - - float GetSensitivity(); -}; - -class TeamFortressViewport; - -extern CHud gHUD; -extern TeamFortressViewport *gViewPort; - -extern int g_iUser1; -extern int g_iUser2; -extern int g_iUser3; - diff --git a/dmc/cl_dll/hud_iface.h b/dmc/cl_dll/hud_iface.h deleted file mode 100644 index 152ba35..0000000 --- a/dmc/cl_dll/hud_iface.h +++ /dev/null @@ -1,19 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( HUD_IFACEH ) -#define HUD_IFACEH -#pragma once - -#include "Platform.h" - -typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf); -#include "wrect.h" -#include "../engine/cdll_int.h" -extern cl_enginefunc_t gEngfuncs; - -#endif \ No newline at end of file diff --git a/dmc/cl_dll/hud_msg.cpp b/dmc/cl_dll/hud_msg.cpp deleted file mode 100644 index 1be43ea..0000000 --- a/dmc/cl_dll/hud_msg.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// hud_msg.cpp -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -extern float g_flLightTime; - -#define MAX_TELES 256 -Vector g_vecTeleMins[ MAX_TELES ]; -Vector g_vecTeleMaxs[ MAX_TELES ]; -int g_iTeleNum; -bool g_bLoadedTeles; - -float g_iFogColor[3]; -float g_iStartDist; -float g_iEndDist; - -/// USER-DEFINED SERVER MESSAGE HANDLERS - -int CHud :: MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf ) -{ - ASSERT( iSize == 0 ); - - // clear all hud data - HUDLIST *pList = m_pHudList; - - while ( pList ) - { - if ( pList->p ) - pList->p->Reset(); - pList = pList->pNext; - } - - // reset sensitivity - m_flMouseSensitivity = 0; - - // reset concussion effect - m_iConcussionEffect = 0; - - g_flLightTime = 0.0; - - return 1; -} - -void CHud :: MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf ) -{ - g_iTeleNum = 0; - g_bLoadedTeles = false; - int i; - - //Clear all the teleporters - for ( i = 0; i < MAX_TELES; i++ ) - { - g_vecTeleMins[ i ].x = 0.0; - g_vecTeleMins[ i ].y = 0.0; - g_vecTeleMins[ i ].z = 0.0; - - g_vecTeleMaxs[ i ].x = 0.0; - g_vecTeleMaxs[ i ].y = 0.0; - g_vecTeleMaxs[ i ].z = 0.0; - } - - /***** FOG CLEARING JIBBA JABBA *****/ - for ( i = 0; i < 3; i++ ) - g_iFogColor[ i ] = 0.0; - - g_iStartDist = 0.0; - g_iEndDist = 0.0; - /***** FOG CLEARING JIBBA JABBA *****/ - - // prepare all hud data - HUDLIST *pList = m_pHudList; - - while (pList) - { - if ( pList->p ) - pList->p->InitHUDData(); - pList = pList->pNext; - } - - BEGIN_READ( pbuf, iSize ); - g_iTeleNum = READ_BYTE(); - - for ( i = 0; i < g_iTeleNum; i++ ) - { - g_vecTeleMins[ i ].x = READ_COORD(); - g_vecTeleMins[ i ].y = READ_COORD(); - g_vecTeleMins[ i ].z = READ_COORD(); - g_vecTeleMaxs[ i ].x = READ_COORD(); - g_vecTeleMaxs[ i ].y = READ_COORD(); - g_vecTeleMaxs[ i ].z = READ_COORD(); - } - - for ( i = 0; i < 3; i++ ) - g_iFogColor[ i ] = READ_SHORT(); // Should just get a byte. - - //If they both are 0, it means no fog for this level. - g_iStartDist = READ_SHORT(); - g_iEndDist = READ_SHORT(); -} - - -int CHud :: MsgFunc_GameMode(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - m_Teamplay = READ_BYTE(); - - return 1; -} - - -int CHud :: MsgFunc_Damage(const char *pszName, int iSize, void *pbuf ) -{ - int armor, blood; - Vector from; - int i; - float count; - - BEGIN_READ( pbuf, iSize ); - armor = READ_BYTE(); - blood = READ_BYTE(); - - for (i=0 ; i<3 ; i++) - from[i] = READ_COORD(); - - count = (blood * 0.5) + (armor * 0.5); - - if (count < 10) - count = 10; - - // TODO: kick viewangles, show damage visually - - return 1; -} - -int CHud :: MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - m_iConcussionEffect = READ_BYTE(); - if (m_iConcussionEffect) - this->m_StatusIcons.EnableIcon("dmg_concuss",255,160,0); - else - this->m_StatusIcons.DisableIcon("dmg_concuss"); - return 1; -} - -// QUAKECLASSIC -int CHud :: MsgFunc_QItems(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - m_iQuakeItems = READ_LONG(); - - return 1; -} \ No newline at end of file diff --git a/dmc/cl_dll/hud_redraw.cpp b/dmc/cl_dll/hud_redraw.cpp deleted file mode 100644 index fb2555e..0000000 --- a/dmc/cl_dll/hud_redraw.cpp +++ /dev/null @@ -1,447 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// hud_redraw.cpp -// -#include -#include "hud.h" -#include "cl_util.h" -#include -#include "vgui_viewport.h" - -extern int g_iVisibleMouse; - -#define MAX_LOGO_FRAMES 56 - -int grgLogoFrame[MAX_LOGO_FRAMES] = -{ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 12, 11, 10, 9, 8, 14, 15, - 16, 17, 18, 19, 20, 20, 20, 20, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 29, 29, 29, 29, 29, 28, 27, 26, 25, 24, 30, 31 -}; - - -// Think -void CHud::Think(void) -{ - m_scrinfo.iSize = sizeof(m_scrinfo); - GetScreenInfo(&m_scrinfo); - - HUDLIST *pList = m_pHudList; - while (pList) - { - if (pList->p->m_iFlags & HUD_ACTIVE) - pList->p->Think(); - pList = pList->pNext; - } - - // think about default fov - if ( m_iFOV == 0 ) - { // only let players adjust up in fov, and only if they are not overriden by something else - m_iFOV = V_max( default_fov->value, 90 ); - } - - -} - -// Redraw -// step through the local data, placing the appropriate graphics & text as appropriate -// returns 1 if they've changed, 0 otherwise -int CHud :: Redraw( float flTime, int intermission ) -{ - m_fOldTime = m_flTime; // save time of previous redraw - m_flTime = flTime; - m_flTimeDelta = (double)m_flTime - m_fOldTime; - static float m_flShotTime = 0; - - // Clock was reset, reset delta - if ( m_flTimeDelta < 0 ) - m_flTimeDelta = 0; - - // Bring up the scoreboard during intermission - if (gViewPort) - { - if ( m_iIntermission && !intermission ) - { - // Have to do this here so the scoreboard goes away - m_iIntermission = intermission; - gViewPort->HideCommandMenu(); - gViewPort->HideScoreBoard(); - gViewPort->UpdateSpectatorPanel(); - } - else if ( !m_iIntermission && intermission ) - { - m_iIntermission = intermission; - gViewPort->HideCommandMenu(); - gViewPort->HideVGUIMenu(); - gViewPort->ShowScoreBoard(); - gViewPort->UpdateSpectatorPanel(); - - // Take a screenshot if the client's got the cvar set - if ( CVAR_GET_FLOAT( "hud_takesshots" ) != 0 ) - m_flShotTime = flTime + 1.0; // Take a screenshot in a second - } - } - - if (m_flShotTime && m_flShotTime < flTime) - { - gEngfuncs.pfnClientCmd("snapshot\n"); - m_flShotTime = 0; - } - // if no redrawing is necessary - // return 0; - - // draw all registered HUD elements - if ( m_pCvarDraw->value ) - { - HUDLIST *pList = m_pHudList; - - while (pList) - { - if ( !intermission ) - { - if ((pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL)) - pList->p->Draw(flTime); - } - else - { // it's an intermission, so only draw hud elements that are set to draw during intermissions - if ( pList->p->m_iFlags & HUD_INTERMISSION ) - pList->p->Draw( flTime ); - } - - pList = pList->pNext; - } - } - - // are we in demo mode? do we need to draw the logo in the top corner? - if (m_iLogo) - { - int x, y, i; - - if (m_hsprLogo == 0) - m_hsprLogo = LoadSprite("sprites/%d_logo.spr"); - - SPR_Set(m_hsprLogo, 250, 250, 250 ); - - x = SPR_Width(m_hsprLogo, 0); - x = ScreenWidth - x; - y = SPR_Height(m_hsprLogo, 0)/2; - - // Draw the logo at 20 fps - int iFrame = (int)(flTime * 20) % MAX_LOGO_FRAMES; - i = grgLogoFrame[iFrame] - 1; - - SPR_DrawAdditive(i, x, y, NULL); - } - - - return 1; -} - -void ScaleColors( int &r, int &g, int &b, int a ) -{ - float x = (float)a / 255; - r = (int)(r * x); - g = (int)(g * x); - b = (int)(b * x); -} - - - -/* -=========================== -int ReturnStringPixelLength ( char *Hihi ) - -Returns a integer representing the length of the string passed -=========================== -*/ -int CHud :: ReturnStringPixelLength ( char *Hihi ) -{ - int iNameLength = 0; - - int strleng = ( strlen( Hihi ) ); - - for ( int har = 0; har < strleng; har++) - iNameLength += gHUD.m_scrinfo.charWidths[ Hihi[har] ]; - - return iNameLength; -} - -int LastColor; - -int CHud :: DrawHudStringCTF(int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b ) -{ - int WantColor = 0; - int Color = 0; - - // draw the string until we hit the null character or a newline character - for ( ; *szIt != 0 && *szIt != '\n'; szIt++ ) - { - int next;// = xpos + gHUD.m_scrinfo.charWidths[ *szIt ]; // variable-width fonts look cool - - /* if ( next > iMaxX ) - return xpos;*/ - - - if (*szIt == '\\') - { - if (Color > 0) - Color = 0; - - WantColor = 1; - - } - - if (WantColor == 1 && *szIt == 'w') - { - Color = 1; - LastColor = Color; - } - - - if (WantColor == 1 && *szIt == 'g') - { - Color = 2; - LastColor = Color; - } - - - - if (WantColor == 1 && *szIt == 'b') - { - Color = 3; - LastColor = Color; - } - - - if (WantColor == 1 && *szIt == 'r') - { - Color = 4; - LastColor = Color; - } - - - - if (WantColor == 1 && *szIt == 'y') - { - Color = 5; - LastColor = Color; - } - - - - if (WantColor == 1 && *szIt == 'q') - { - Color = 6; - LastColor = Color; - } - - - - if (Color == 0 && WantColor == 0) - { - if (LastColor == 1) - TextMessageDrawChar( xpos, ypos, *szIt, 255, 255, 255 ); - if (LastColor == 2) - TextMessageDrawChar( xpos, ypos, *szIt, 0, 79, 0); - if (LastColor == 3) - TextMessageDrawChar( xpos, ypos, *szIt, 0, 0, 200); - if (LastColor == 4) - TextMessageDrawChar( xpos, ypos, *szIt, 200, 0, 0 ); - if (LastColor == 5) - TextMessageDrawChar( xpos, ypos, *szIt, 198, 221, 66 ); - if (LastColor == 6) - TextMessageDrawChar( xpos, ypos, *szIt, 136, 136, 136 ); - - else if (LastColor == 0) - TextMessageDrawChar( xpos, ypos, *szIt, r, g, b ); - - next = xpos + gHUD.m_scrinfo.charWidths[ *szIt ]; - } - - else if (Color > 0 && WantColor == 0 ) - { - if (Color == 1) - TextMessageDrawChar( xpos, ypos, *szIt, 255, 255, 255 ); - if (Color == 2) - TextMessageDrawChar( xpos, ypos, *szIt, 0, 79, 0); - if (Color == 3) - TextMessageDrawChar( xpos, ypos, *szIt, 0, 0, 200); - if (Color == 4) - TextMessageDrawChar( xpos, ypos, *szIt, 200, 0, 0 ); - if (Color == 5) - TextMessageDrawChar( xpos, ypos, *szIt, 198, 221, 66 ); - if (Color == 6) - TextMessageDrawChar( xpos, ypos, *szIt, 136, 136, 136 ); - - next = xpos + gHUD.m_scrinfo.charWidths[ *szIt ]; - } - - else if (Color > 0 && WantColor == 1) - { - //next = xpos + (gHUD.m_scrinfo.charWidths[ *szIt ] * 2); // variable-width fonts look cool - WantColor = 0; - } - - - xpos = next; - } - - return xpos; -} - - -int CHud :: DrawHudString(int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b ) -{ - // draw the string until we hit the null character or a newline character - for ( ; *szIt != 0 && *szIt != '\n'; szIt++ ) - { - int next = xpos + gHUD.m_scrinfo.charWidths[ *szIt ]; // variable-width fonts look cool - if ( next > iMaxX ) - return xpos; - - TextMessageDrawChar( xpos, ypos, *szIt, r, g, b ); - xpos = next; - } - - return xpos; -} - -int CHud :: DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r, int g, int b ) -{ - char szString[32]; - sprintf( szString, "%d", iNumber ); - return DrawHudStringReverse( xpos, ypos, iMinX, szString, r, g, b ); - -} - -// draws a string from right to left (right-aligned) -int CHud :: DrawHudStringReverse( int xpos, int ypos, int iMinX, char *szString, int r, int g, int b ) -{ - // find the end of the string - char *szIt; - for ( szIt = szString; *szIt != 0; szIt++ ) - { // we should count the length? - } - - // iterate throug the string in reverse - for ( szIt--; szIt != (szString-1); szIt-- ) - { - int next = xpos - gHUD.m_scrinfo.charWidths[ *szIt ]; // variable-width fonts look cool - if ( next < iMinX ) - return xpos; - xpos = next; - - TextMessageDrawChar( xpos, ypos, *szIt, r, g, b ); - } - - return xpos; -} - -int CHud :: DrawHudNumber( int x, int y, int iFlags, int iNumber, int r, int g, int b) -{ - int iWidth = GetSpriteRect(m_HUD_number_0).right - GetSpriteRect(m_HUD_number_0).left; - int k; - - if (iNumber > 0) - { - // SPR_Draw 100's - if (iNumber >= 100) - { - k = iNumber/100; - SPR_Set(GetSprite(m_HUD_number_0 + k), r, g, b ); - SPR_DrawAdditive( 0, x, y, &GetSpriteRect(m_HUD_number_0 + k)); - x += iWidth; - } - else if (iFlags & (DHN_3DIGITS)) - { - //SPR_DrawAdditive( 0, x, y, &rc ); - x += iWidth; - } - - // SPR_Draw 10's - if (iNumber >= 10) - { - k = (iNumber % 100)/10; - SPR_Set(GetSprite(m_HUD_number_0 + k), r, g, b ); - SPR_DrawAdditive( 0, x, y, &GetSpriteRect(m_HUD_number_0 + k)); - x += iWidth; - } - else if (iFlags & (DHN_3DIGITS | DHN_2DIGITS)) - { - //SPR_DrawAdditive( 0, x, y, &rc ); - x += iWidth; - } - - // SPR_Draw ones - k = iNumber % 10; - SPR_Set(GetSprite(m_HUD_number_0 + k), r, g, b ); - SPR_DrawAdditive(0, x, y, &GetSpriteRect(m_HUD_number_0 + k)); - x += iWidth; - } - else if (iFlags & DHN_DRAWZERO) - { - SPR_Set(GetSprite(m_HUD_number_0), r, g, b ); - - // SPR_Draw 100's - if (iFlags & (DHN_3DIGITS)) - { - //SPR_DrawAdditive( 0, x, y, &rc ); - x += iWidth; - } - - if (iFlags & (DHN_3DIGITS | DHN_2DIGITS)) - { - //SPR_DrawAdditive( 0, x, y, &rc ); - x += iWidth; - } - - // SPR_Draw ones - - SPR_DrawAdditive( 0, x, y, &GetSpriteRect(m_HUD_number_0)); - x += iWidth; - } - - return x; -} - - -int CHud::GetNumWidth( int iNumber, int iFlags ) -{ - if (iFlags & (DHN_3DIGITS)) - return 3; - - if (iFlags & (DHN_2DIGITS)) - return 2; - - if (iNumber <= 0) - { - if (iFlags & (DHN_DRAWZERO)) - return 1; - else - return 0; - } - - if (iNumber < 10) - return 1; - - if (iNumber < 100) - return 2; - - return 3; - -} - - diff --git a/dmc/cl_dll/hud_servers.cpp b/dmc/cl_dll/hud_servers.cpp deleted file mode 100644 index 06138ae..0000000 --- a/dmc/cl_dll/hud_servers.cpp +++ /dev/null @@ -1,1256 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// hud_servers.cpp -#include "hud.h" -#include "cl_util.h" -#include "hud_servers_priv.h" -#include "hud_servers.h" -#include "net_api.h" -#include -#ifdef _WIN32 -#include "winsani_in.h" -#include -#include "winsani_out.h" -#else -#define __cdecl -#include -#endif - -static int context_id; - -// Default master server address in case we can't read any from valvecomm.lst file -#define VALVE_MASTER_ADDRESS "half-life.east.won.net" -#define PORT_MASTER 27010 -#define PORT_SERVER 27015 - -// File where we really should look for master servers -#define MASTER_PARSE_FILE "valvecomm.lst" - -#define MAX_QUERIES 20 - -#define NET_API gEngfuncs.pNetAPI - -static CHudServers *g_pServers = NULL; - -/* -=================== -ListResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK ListResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->ListResponse( response ); - } -} - -/* -=================== -ServerResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK ServerResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->ServerResponse( response ); - } -} - -/* -=================== -PingResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK PingResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->PingResponse( response ); - } -} - -/* -=================== -RulesResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK RulesResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->RulesResponse( response ); - } -} -/* -=================== -PlayersResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK PlayersResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->PlayersResponse( response ); - } -} -/* -=================== -ListResponse - -=================== -*/ -void CHudServers::ListResponse( struct net_response_s *response ) -{ - request_t *list; - request_t *p; - int c = 0; - - if ( !( response->error == NET_SUCCESS ) ) - return; - - if ( response->type != NETAPI_REQUEST_SERVERLIST ) - return; - - if ( response->response ) - { - list = ( request_t * ) response->response; - while ( list ) - { - c++; - - //if ( c < 40 ) - { - // Copy from parsed stuff - p = new request_t; - p->context = -1; - p->remote_address = list->remote_address; - p->next = m_pServerList; - m_pServerList = p; - } - - // Move on - list = list->next; - } - } - - gEngfuncs.Con_Printf( "got list\n" ); - - m_nQuerying = 1; - m_nActiveQueries = 0; -} - -/* -=================== -ServerResponse - -=================== -*/ -void CHudServers::ServerResponse( struct net_response_s *response ) -{ - char *szresponse; - request_t *p; - server_t *browser; - int len; - char sz[ 32 ]; - - // Remove from active list - p = FindRequest( response->context, m_pActiveList ); - if ( p ) - { - static int first = 0; - - RemoveServerFromList( &m_pActiveList, p ); - m_nActiveQueries--; - - if ( !first ) - { - gEngfuncs.Con_Printf( "recv first %f\n", gEngfuncs.GetClientTime() ); - first = 1; - } - } - - - if ( response->error != NET_SUCCESS ) - return; - - switch ( response->type ) - { - case NETAPI_REQUEST_DETAILS: - if ( response->response ) - { - szresponse = (char *)response->response; - len = strlen( szresponse ) + 100 + 1; - sprintf( sz, "%i", (int)( 1000.0 * response->ping ) ); - - browser = new server_t; - browser->remote_address = response->remote_address; - browser->info = new char[ len ]; - browser->ping = (int)( 1000.0 * response->ping ); - strcpy( browser->info, szresponse ); - - NET_API->SetValueForKey( browser->info, "address", gEngfuncs.pNetAPI->AdrToString( &response->remote_address ), len ); - NET_API->SetValueForKey( browser->info, "ping", sz, len ); - - AddServer( &m_pServers, browser ); - } - break; - default: - break; - } -} - -/* -=================== -PingResponse - -=================== -*/ -void CHudServers::PingResponse( struct net_response_s *response ) -{ - char sz[ 32 ]; - - if ( response->error != NET_SUCCESS ) - return; - - switch ( response->type ) - { - case NETAPI_REQUEST_PING: - sprintf( sz, "%.2f", 1000.0 * response->ping ); - - gEngfuncs.Con_Printf( "ping == %s\n", sz ); - break; - default: - break; - } -} - -/* -=================== -RulesResponse - -=================== -*/ -void CHudServers::RulesResponse( struct net_response_s *response ) -{ - char *szresponse; - - if ( response->error != NET_SUCCESS ) - return; - - switch ( response->type ) - { - case NETAPI_REQUEST_RULES: - if ( response->response ) - { - szresponse = (char *)response->response; - - gEngfuncs.Con_Printf( "rules %s\n", szresponse ); - } - break; - default: - break; - } -} - -/* -=================== -PlayersResponse - -=================== -*/ -void CHudServers::PlayersResponse( struct net_response_s *response ) -{ - char *szresponse; - - if ( response->error != NET_SUCCESS ) - return; - - switch ( response->type ) - { - case NETAPI_REQUEST_PLAYERS: - if ( response->response ) - { - szresponse = (char *)response->response; - - gEngfuncs.Con_Printf( "players %s\n", szresponse ); - } - break; - default: - break; - } -} - -/* -=================== -CompareServers - -Return 1 if p1 is "less than" p2, 0 otherwise -=================== -*/ -int CHudServers::CompareServers( server_t *p1, server_t *p2 ) -{ - const char *n1, *n2; - - if ( p1->ping < p2->ping ) - return 1; - - if ( p1->ping == p2->ping ) - { - // Pings equal, sort by second key: hostname - if ( p1->info && p2->info ) - { - n1 = NET_API->ValueForKey( p1->info, "hostname" ); - n2 = NET_API->ValueForKey( p2->info, "hostname" ); - - if ( n1 && n2 ) - { - if ( stricmp( n1, n2 ) < 0 ) - return 1; - } - } - } - - return 0; -} - -/* -=================== -AddServer - -=================== -*/ -void CHudServers::AddServer( server_t **ppList, server_t *p ) -{ -server_t *list; - - if ( !ppList || ! p ) - return; - - m_nServerCount++; - - // What sort key? Ping? - list = *ppList; - - // Head of list? - if ( !list ) - { - p->next = NULL; - *ppList = p; - return; - } - - // Put on head of list - if ( CompareServers( p, list ) ) - { - p->next = *ppList; - *ppList = p; - } - else - { - while ( list->next ) - { - // Insert before list next - if ( CompareServers( p, list->next ) ) - { - p->next = list->next->next; - list->next = p; - return; - } - - list = list->next; - } - - // Just add at end - p->next = NULL; - list->next = p; - } -} - -/* -=================== -Think - -=================== -*/ -void CHudServers::Think( double time ) -{ - m_fElapsed += time; - - if ( !m_nRequesting ) - return; - - if ( !m_nQuerying ) - return; - - QueryThink(); - - if ( ServerListSize() > 0 ) - return; - - m_dStarted = 0.0; - m_nRequesting = 0; - m_nDone = 0; - m_nQuerying = 0; - m_nActiveQueries = 0; -} - -/* -=================== -QueryThink - -=================== -*/ -void CHudServers::QueryThink( void ) -{ - request_t *p; - - if ( !m_nRequesting || m_nDone ) - return; - - if ( !m_nQuerying ) - return; - - if ( m_nActiveQueries > MAX_QUERIES ) - return; - - // Nothing left - if ( !m_pServerList ) - return; - - while ( 1 ) - { - static int first = 0; - p = m_pServerList; - - // No more in list? - if ( !p ) - break; - - // Move to next - m_pServerList = m_pServerList->next; - - // Setup context_id - p->context = context_id; - - // Make sure networking system has started. - // NET_API->InitNetworking(); - - if ( !first ) - { - gEngfuncs.Con_Printf( "send first %f\n", gEngfuncs.GetClientTime() ); - first = 1; - } - - // Start up query on this one - NET_API->SendRequest( context_id++, NETAPI_REQUEST_DETAILS, 0, 2.0, &p->remote_address, ::ServerResponse ); - - // Increment active list - m_nActiveQueries++; - - // Add to active list - p->next = m_pActiveList; - m_pActiveList = p; - - // Too many active? - if ( m_nActiveQueries > MAX_QUERIES ) - break; - } -} - -/* -================== -ServerListSize - -# of servers in active query and in pending to be queried lists -================== -*/ -int CHudServers::ServerListSize( void ) -{ - int c = 0; - request_t *p; - - p = m_pServerList; - while ( p ) - { - c++; - p = p->next; - } - - p = m_pActiveList; - while ( p ) - { - c++; - p = p->next; - } - - return c; -} - -/* -=================== -FindRequest - -Look up a request by context id -=================== -*/ -CHudServers::request_t *CHudServers::FindRequest( int context, request_t *pList ) -{ - request_t *p; - p = pList; - while ( p ) - { - if ( context == p->context ) - return p; - - p = p->next; - } - return NULL; -} - -/* -=================== -RemoveServerFromList - -Remote, but don't delete, item from *ppList -=================== -*/ -void CHudServers::RemoveServerFromList( request_t **ppList, request_t *item ) -{ - request_t *p, *n; - request_t *newlist = NULL; - - if ( !ppList ) - return; - - p = *ppList; - while ( p ) - { - n = p->next; - if ( p != item ) - { - p->next = newlist; - newlist = p; - } - p = n; - } - *ppList = newlist; -} - -/* -=================== -ClearRequestList - -=================== -*/ -void CHudServers::ClearRequestList( request_t **ppList ) -{ - request_t *p, *n; - - if ( !ppList ) - return; - - p = *ppList; - while ( p ) - { - n = p->next; - delete p; - p = n; - } - *ppList = NULL; -} - -/* -=================== -ClearServerList - -=================== -*/ -void CHudServers::ClearServerList( server_t **ppList ) -{ - server_t *p, *n; - - if ( !ppList ) - return; - - p = *ppList; - while ( p ) - { - n = p->next; - delete[] p->info; - delete p; - p = n; - } - *ppList = NULL; -} - -int CompareField( CHudServers::server_t *p1, CHudServers::server_t *p2, const char *fieldname, int iSortOrder ) -{ - const char *sz1, *sz2; - float fv1, fv2; - - sz1 = NET_API->ValueForKey( p1->info, fieldname ); - sz2 = NET_API->ValueForKey( p2->info, fieldname ); - - fv1 = atof( sz1 ); - fv2 = atof( sz2 ); - - if ( fv1 && fv2 ) - { - if ( fv1 > fv2 ) - return iSortOrder; - else if ( fv1 < fv2 ) - return -iSortOrder; - else - return 0; - } - - // String compare - return stricmp( sz1, sz2 ); -} - -int ServerListCompareFunc( CHudServers::server_t *p1, CHudServers::server_t *p2, const char *fieldname ) -{ - if (!p1 || !p2) // No meaningful comparison - return 0; - - int iSortOrder = 1; - - int retval = 0; - - retval = CompareField( p1, p2, fieldname, iSortOrder ); - - return retval; -} - -static char g_fieldname[ 256 ]; -int __cdecl FnServerCompare(const void *elem1, const void *elem2 ) -{ - CHudServers::server_t *list1, *list2; - - list1 = *(CHudServers::server_t **)elem1; - list2 = *(CHudServers::server_t **)elem2; - - return ServerListCompareFunc( list1, list2, g_fieldname ); -} - -void CHudServers::SortServers( const char *fieldname ) -{ - server_t *p; - // Create a list - if ( !m_pServers ) - return; - - strcpy( g_fieldname, fieldname ); - - int i; - int c = 0; - - p = m_pServers; - while ( p ) - { - c++; - p = p->next; - } - - server_t **pSortArray; - - pSortArray = new server_t *[ c ]; - memset( pSortArray, 0, c * sizeof( server_t * ) ); - - // Now copy the list into the pSortArray: - p = m_pServers; - i = 0; - while ( p ) - { - pSortArray[ i++ ] = p; - p = p->next; - } - - // Now do that actual sorting. - size_t nCount = c; - size_t nSize = sizeof( server_t * ); - - qsort( - pSortArray, - (size_t)nCount, - (size_t)nSize, - FnServerCompare - ); - - // Now rebuild the list. - m_pServers = pSortArray[0]; - for ( i = 0; i < c - 1; i++ ) - { - pSortArray[ i ]->next = pSortArray[ i + 1 ]; - } - pSortArray[ c - 1 ]->next = NULL; - - // Clean Up. - delete[] pSortArray; -} - -/* -=================== -GetServer - -Return particular server -=================== -*/ -CHudServers::server_t *CHudServers::GetServer( int server ) -{ - int c = 0; - server_t *p; - - p = m_pServers; - while ( p ) - { - if ( c == server ) - return p; - - c++; - p = p->next; - } - return NULL; -} - -/* -=================== -GetServerInfo - -Return info ( key/value ) string for particular server -=================== -*/ -char *CHudServers::GetServerInfo( int server ) -{ - server_t *p = GetServer( server ); - if ( p ) - { - return p->info; - } - return NULL; -} - -/* -=================== -CancelRequest - -Kill all pending requests in engine -=================== -*/ -void CHudServers::CancelRequest( void ) -{ - m_nRequesting = 0; - m_nQuerying = 0; - m_nDone = 1; - - NET_API->CancelAllRequests(); -} - -/* -================== -LoadMasterAddresses - -Loads the master server addresses from file and into the passed in array -================== -*/ -int CHudServers::LoadMasterAddresses( int maxservers, int *count, netadr_t *padr ) -{ - int i; - char szMaster[ 256 ]; - char szMasterFile[256]; - char *pbuffer = NULL; - char *pstart = NULL ; - netadr_t adr; - char szAdr[64]; - int nPort; - int nCount = 0; - bool bIgnore; - int nDefaultPort; - - // Assume default master and master file - strcpy( szMaster, VALVE_MASTER_ADDRESS ); // IP:PORT string - strcpy( szMasterFile, MASTER_PARSE_FILE ); - - // See if there is a command line override - i = gEngfuncs.CheckParm( "-comm", &pstart ); - if ( i && pstart ) - { - strcpy (szMasterFile, pstart ); - } - - // Read them in from proper file - pbuffer = (char *)gEngfuncs.COM_LoadFile( szMasterFile, 5, NULL ); // Use malloc - if ( !pbuffer ) - { - goto finish_master; - } - - pstart = pbuffer; - - while ( nCount < maxservers ) - { - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - - if ( strlen(m_szToken) <= 0) - break; - - bIgnore = true; - - if ( !stricmp( m_szToken, "Master" ) ) - { - nDefaultPort = PORT_MASTER; - bIgnore = FALSE; - } - - // Now parse all addresses between { } - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - if ( strlen(m_szToken) <= 0 ) - break; - - if ( stricmp ( m_szToken, "{" ) ) - break; - - // Parse addresses until we get to "}" - while ( nCount < maxservers ) - { - char base[256]; - - // Now parse all addresses between { } - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - - if (strlen(m_szToken) <= 0) - break; - - if ( !stricmp ( m_szToken, "}" ) ) - break; - - sprintf( base, "%s", m_szToken ); - - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - - if (strlen(m_szToken) <= 0) - break; - - if ( stricmp( m_szToken, ":" ) ) - break; - - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - - if (strlen(m_szToken) <= 0) - break; - - nPort = atoi ( m_szToken ); - if ( !nPort ) - nPort = nDefaultPort; - - sprintf( szAdr, "%s:%i", base, nPort ); - - // Can we resolve it any better - if ( !NET_API->StringToAdr( szAdr, &adr ) ) - bIgnore = true; - - if ( !bIgnore ) - { - padr[ nCount++ ] = adr; - } - } - } - -finish_master: - if ( !nCount ) - { - sprintf( szMaster, VALVE_MASTER_ADDRESS ); // IP:PORT string - - // Convert to netadr_t - if ( NET_API->StringToAdr ( szMaster, &adr ) ) - { - - padr[ nCount++ ] = adr; - } - } - - *count = nCount; - - if ( pbuffer ) - { - gEngfuncs.COM_FreeFile( pbuffer ); - } - - return ( nCount > 0 ) ? 1 : 0; -} - -/* -=================== -RequestList - -Request list of game servers from master -=================== -*/ -void CHudServers::RequestList( void ) -{ - m_nRequesting = 1; - m_nDone = 0; - m_dStarted = m_fElapsed; - - int count = 0; - netadr_t adr; - - if ( !LoadMasterAddresses( 1, &count, &adr ) ) - { - gEngfuncs.Con_DPrintf( "SendRequest: Unable to read master server addresses\n" ); - return; - } - - ClearRequestList( &m_pActiveList ); - ClearRequestList( &m_pServerList ); - ClearServerList( &m_pServers ); - - m_nServerCount = 0; - - // Make sure networking system has started. - NET_API->InitNetworking(); - - // Kill off left overs if any - NET_API->CancelAllRequests(); - - // Request Server List from master - NET_API->SendRequest( context_id++, NETAPI_REQUEST_SERVERLIST, 0, 5.0, &adr, ::ListResponse ); -} - -void CHudServers::RequestBroadcastList( int clearpending ) -{ - m_nRequesting = 1; - m_nDone = 0; - m_dStarted = m_fElapsed; - - netadr_t adr; - memset( &adr, 0, sizeof( adr ) ); - - if ( clearpending ) - { - ClearRequestList( &m_pActiveList ); - ClearRequestList( &m_pServerList ); - ClearServerList( &m_pServers ); - - m_nServerCount = 0; - } - - // Make sure to byte swap server if necessary ( using "host" to "net" conversion - adr.port = htons( PORT_SERVER ); - - // Make sure networking system has started. - NET_API->InitNetworking(); - - if ( clearpending ) - { - // Kill off left overs if any - NET_API->CancelAllRequests(); - } - - adr.type = NA_BROADCAST; - - // Request Servers from LAN via IP - NET_API->SendRequest( context_id++, NETAPI_REQUEST_DETAILS, FNETAPI_MULTIPLE_RESPONSE, 5.0, &adr, ::ServerResponse ); - - adr.type = NA_BROADCAST_IPX; - - // Request Servers from LAN via IPX ( if supported ) - NET_API->SendRequest( context_id++, NETAPI_REQUEST_DETAILS, FNETAPI_MULTIPLE_RESPONSE, 5.0, &adr, ::ServerResponse ); -} - -void CHudServers::ServerPing( int server ) -{ - server_t *p; - - p = GetServer( server ); - if ( !p ) - return; - - // Make sure networking system has started. - NET_API->InitNetworking(); - - // Request Server List from master - NET_API->SendRequest( context_id++, NETAPI_REQUEST_PING, 0, 5.0, &p->remote_address, ::PingResponse ); -} - -void CHudServers::ServerRules( int server ) -{ - server_t *p; - - p = GetServer( server ); - if ( !p ) - return; - - // Make sure networking system has started. - NET_API->InitNetworking(); - - // Request Server List from master - NET_API->SendRequest( context_id++, NETAPI_REQUEST_RULES, 0, 5.0, &p->remote_address, ::RulesResponse ); -} - -void CHudServers::ServerPlayers( int server ) -{ - server_t *p; - - p = GetServer( server ); - if ( !p ) - return; - - // Make sure networking system has started. - NET_API->InitNetworking(); - - // Request Server List from master - NET_API->SendRequest( context_id++, NETAPI_REQUEST_PLAYERS, 0, 5.0, &p->remote_address, ::PlayersResponse ); -} - -int CHudServers::isQuerying() -{ - return m_nRequesting ? 1 : 0; -} - - -/* -=================== -GetServerCount - -Return number of servers in browser list -=================== -*/ -int CHudServers::GetServerCount( void ) -{ - return m_nServerCount; -} - -/* -=================== -CHudServers - -=================== -*/ -CHudServers::CHudServers( void ) -{ - m_nRequesting = 0; - m_dStarted = 0.0; - m_nDone = 0; - m_pServerList = NULL; - m_pServers = NULL; - m_pActiveList = NULL; - m_nQuerying = 0; - m_nActiveQueries = 0; - - m_fElapsed = 0.0; - - - m_pPingRequest = NULL; - m_pRulesRequest = NULL; - m_pPlayersRequest = NULL; -} - -/* -=================== -~CHudServers - -=================== -*/ -CHudServers::~CHudServers( void ) -{ - ClearRequestList( &m_pActiveList ); - ClearRequestList( &m_pServerList ); - ClearServerList( &m_pServers ); - - m_nServerCount = 0; - - if ( m_pPingRequest ) - { - delete m_pPingRequest; - m_pPingRequest = NULL; - - } - - if ( m_pRulesRequest ) - { - delete m_pRulesRequest; - m_pRulesRequest = NULL; - } - - if ( m_pPlayersRequest ) - { - delete m_pPlayersRequest; - m_pPlayersRequest = NULL; - } -} - -/////////////////////////////// -// -// PUBLIC APIs -// -/////////////////////////////// - -/* -=================== -ServersGetCount - -=================== -*/ -int ServersGetCount( void ) -{ - if ( g_pServers ) - { - return g_pServers->GetServerCount(); - } - return 0; -} - -int ServersIsQuerying( void ) -{ - if ( g_pServers ) - { - return g_pServers->isQuerying(); - } - return 0; -} - -/* -=================== -ServersGetInfo - -=================== -*/ -const char *ServersGetInfo( int server ) -{ - if ( g_pServers ) - { - return g_pServers->GetServerInfo( server ); - } - - return NULL; -} - -void SortServers( const char *fieldname ) -{ - if ( g_pServers ) - { - g_pServers->SortServers( fieldname ); - } -} - -/* -=================== -ServersShutdown - -=================== -*/ -void ServersShutdown( void ) -{ - if ( g_pServers ) - { - delete g_pServers; - g_pServers = NULL; - } -} - -/* -=================== -ServersInit - -=================== -*/ -void ServersInit( void ) -{ - // Kill any previous instance - ServersShutdown(); - - g_pServers = new CHudServers(); -} - -/* -=================== -ServersThink - -=================== -*/ -void ServersThink( double time ) -{ - if ( g_pServers ) - { - g_pServers->Think( time ); - } -} - -/* -=================== -ServersCancel - -=================== -*/ -void ServersCancel( void ) -{ - if ( g_pServers ) - { - g_pServers->CancelRequest(); - } -} - -// Requests -/* -=================== -ServersList - -=================== -*/ -void ServersList( void ) -{ - if ( g_pServers ) - { - g_pServers->RequestList(); - } -} - -void BroadcastServersList( int clearpending ) -{ - if ( g_pServers ) - { - g_pServers->RequestBroadcastList( clearpending ); - } -} - -void ServerPing( int server ) -{ - if ( g_pServers ) - { - g_pServers->ServerPing( server ); - } -} - -void ServerRules( int server ) -{ - if ( g_pServers ) - { - g_pServers->ServerRules( server ); - } -} - -void ServerPlayers( int server ) -{ - if ( g_pServers ) - { - g_pServers->ServerPlayers( server ); - } -} diff --git a/dmc/cl_dll/hud_servers.h b/dmc/cl_dll/hud_servers.h deleted file mode 100644 index 01e9442..0000000 --- a/dmc/cl_dll/hud_servers.h +++ /dev/null @@ -1,41 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( HUD_SERVERSH ) -#define HUD_SERVERSH -#pragma once - -#define NET_CALLBACK /* */ - -// Dispatchers -void NET_CALLBACK ListResponse( struct net_response_s *response ); -void NET_CALLBACK ServerResponse( struct net_response_s *response ); -void NET_CALLBACK PingResponse( struct net_response_s *response ); -void NET_CALLBACK RulesResponse( struct net_response_s *response ); -void NET_CALLBACK PlayersResponse( struct net_response_s *response ); - -void ServersInit( void ); -void ServersShutdown( void ); -void ServersThink( double time ); -void ServersCancel( void ); - -// Get list and get server info from each -void ServersList( void ); - -// Query for IP / IPX LAN servers -void BroadcastServersList( int clearpending ); - -void ServerPing( int server ); -void ServerRules( int server ); -void ServerPlayers( int server ); - -int ServersGetCount( void ); -const char *ServersGetInfo( int server ); -int ServersIsQuerying( void ); -void SortServers( const char *fieldname ); - -#endif // HUD_SERVERSH \ No newline at end of file diff --git a/dmc/cl_dll/hud_servers_priv.h b/dmc/cl_dll/hud_servers_priv.h deleted file mode 100644 index 73692f4..0000000 --- a/dmc/cl_dll/hud_servers_priv.h +++ /dev/null @@ -1,98 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( HUD_SERVERS_PRIVH ) -#define HUD_SERVERS_PRIVH -#pragma once - -#include "netadr.h" - -class CHudServers -{ -public: - typedef struct request_s - { - struct request_s *next; - netadr_t remote_address; - int context; - } request_t; - - typedef struct server_s - { - struct server_s *next; - netadr_t remote_address; - char *info; - int ping; - } server_t; - - CHudServers(); - ~CHudServers(); - - void Think( double time ); - void QueryThink( void ); - int isQuerying( void ); - - int LoadMasterAddresses( int maxservers, int *count, netadr_t *padr ); - - void RequestList( void ); - void RequestBroadcastList( int clearpending ); - - void ServerPing( int server ); - void ServerRules( int server ); - void ServerPlayers( int server ); - - void CancelRequest( void ); - - int CompareServers( server_t *p1, server_t *p2 ); - - void ClearServerList( server_t **ppList ); - void ClearRequestList( request_t **ppList ); - - void AddServer( server_t **ppList, server_t *p ); - - void RemoveServerFromList( request_t **ppList, request_t *item ); - - request_t *FindRequest( int context, request_t *pList ); - - int ServerListSize( void ); - char *GetServerInfo( int server ); - int GetServerCount( void ); - void SortServers( const char *fieldname ); - - void ListResponse( struct net_response_s *response ); - void ServerResponse( struct net_response_s *response ); - void PingResponse( struct net_response_s *response ); - void RulesResponse( struct net_response_s *response ); - void PlayersResponse( struct net_response_s *response ); -private: - - server_t *GetServer( int server ); - - // - char m_szToken[ 1024 ]; - int m_nRequesting; - int m_nDone; - - double m_dStarted; - - request_t *m_pServerList; - request_t *m_pActiveList; - - server_t *m_pServers; - - int m_nServerCount; - - int m_nActiveQueries; - int m_nQuerying; - double m_fElapsed; - - request_t *m_pPingRequest; - request_t *m_pRulesRequest; - request_t *m_pPlayersRequest; -}; - -#endif // HUD_SERVERS_PRIVH \ No newline at end of file diff --git a/dmc/cl_dll/hud_spectator.cpp b/dmc/cl_dll/hud_spectator.cpp deleted file mode 100644 index 0766708..0000000 --- a/dmc/cl_dll/hud_spectator.cpp +++ /dev/null @@ -1,1576 +0,0 @@ -//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "hud.h" -#include "cl_util.h" -#include "cl_entity.h" -#include "triangleapi.h" -#include "vgui_viewport.h" -#include "vgui_SpectatorPanel.h" -#include "hltv.h" - -#include "pm_shared.h" -#include "pm_defs.h" -#include "pmtrace.h" -#include "parsemsg.h" -#include "entity_types.h" - -// these are included for the math functions -#include "com_model.h" -#include "demo_api.h" -#include "studio_util.h" - -#pragma warning(disable: 4244) - -extern int iJumpSpectator; -extern float vJumpOrigin[3]; -extern float vJumpAngles[3]; - - -extern void V_GetInEyePos(int entity, float * origin, float * angles ); -extern void V_ResetChaseCam(); -extern void V_GetChasePos(int target, float * cl_angles, float * origin, float * angles); -extern void VectorAngles( const float *forward, float *angles ); -void NormalizeAngles( float *angles ); -extern float * GetClientColor( int clientIndex ); - -extern vec3_t v_origin; // last view origin -extern vec3_t v_angles; // last view angle -extern vec3_t v_cl_angles; // last client/mouse angle -extern vec3_t v_sim_org; // last sim origin - -void SpectatorMode(void) -{ - - - if ( gEngfuncs.Cmd_Argc() <= 1 ) - { - gEngfuncs.Con_Printf( "usage: spec_mode
[]\n" ); - return; - } - - // SetModes() will decide if command is executed on server or local - if ( gEngfuncs.Cmd_Argc() == 2 ) - gHUD.m_Spectator.SetModes( atoi( gEngfuncs.Cmd_Argv(1) ), -1 ); - else if ( gEngfuncs.Cmd_Argc() == 3 ) - gHUD.m_Spectator.SetModes( atoi( gEngfuncs.Cmd_Argv(1) ), atoi( gEngfuncs.Cmd_Argv(2) ) ); -} - -void SpectatorSpray(void) -{ - vec3_t forward; - char string[128]; - - if ( !gEngfuncs.IsSpectateOnly() ) - return; - - AngleVectors(v_angles,forward,NULL,NULL); - VectorScale(forward, 128, forward); - VectorAdd(forward, v_origin, forward); - pmtrace_t * trace = gEngfuncs.PM_TraceLine( v_origin, forward, PM_TRACELINE_PHYSENTSONLY, 2, -1 ); - if ( trace->fraction != 1.0 ) - { - sprintf(string, "drc_spray %.2f %.2f %.2f %i", - trace->endpos[0], trace->endpos[1], trace->endpos[2], trace->ent ); - gEngfuncs.pfnServerCmd(string); - } - -} -void SpectatorHelp(void) -{ - if ( gViewPort ) - { - gViewPort->ShowVGUIMenu( MENU_SPECHELP ); - } - else - { - char *text = CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help_Text" ); - - if ( text ) - { - while ( *text ) - { - if ( *text != 13 ) - gEngfuncs.Con_Printf( "%c", *text ); - text++; - } - } - } -} - -void SpectatorMenu( void ) -{ - if ( gEngfuncs.Cmd_Argc() <= 1 ) - { - gEngfuncs.Con_Printf( "usage: spec_menu <0|1>\n" ); - return; - } - - gViewPort->m_pSpectatorPanel->ShowMenu( atoi( gEngfuncs.Cmd_Argv(1))!=0 ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int CHudSpectator::Init() -{ - gHUD.AddHudElem(this); - - m_iFlags |= HUD_ACTIVE; - m_flNextObserverInput = 0.0f; - m_zoomDelta = 0.0f; - m_moveDelta = 0.0f; - m_chatEnabled = (gHUD.m_SayText.m_HUD_saytext->value!=0); - iJumpSpectator = 0; - - memset( &m_OverviewData, 0, sizeof(m_OverviewData)); - memset( &m_OverviewEntities, 0, sizeof(m_OverviewEntities)); - m_lastPrimaryObject = m_lastSecondaryObject = 0; - - gEngfuncs.pfnAddCommand ("spec_mode", SpectatorMode ); - gEngfuncs.pfnAddCommand ("spec_decal", SpectatorSpray ); - gEngfuncs.pfnAddCommand ("spec_help", SpectatorHelp ); - gEngfuncs.pfnAddCommand ("spec_menu", SpectatorMenu ); - - m_drawnames = gEngfuncs.pfnRegisterVariable("spec_drawnames","1",0); - m_drawcone = gEngfuncs.pfnRegisterVariable("spec_drawcone","1",0); - m_drawstatus = gEngfuncs.pfnRegisterVariable("spec_drawstatus","1",0); - m_autoDirector = gEngfuncs.pfnRegisterVariable("spec_autodirector","1",0); - m_pip = gEngfuncs.pfnRegisterVariable("spec_pip","1",0); - - - if ( !m_drawnames || !m_drawcone || !m_drawstatus || !m_autoDirector || !m_pip) - { - gEngfuncs.Con_Printf("ERROR! Couldn't register all spectator variables.\n"); - return 0; - } - - return 1; -} - - -//----------------------------------------------------------------------------- -// UTIL_StringToVector originally from ..\dlls\util.cpp, slightly changed -//----------------------------------------------------------------------------- - -void UTIL_StringToVector( float * pVector, const char *pString ) -{ - char *pstr, *pfront, tempString[128]; - int j; - - strcpy( tempString, pString ); - pstr = pfront = tempString; - - for ( j = 0; j < 3; j++ ) - { - pVector[j] = atof( pfront ); - - while ( *pstr && *pstr != ' ' ) - pstr++; - if (!*pstr) - break; - pstr++; - pfront = pstr; - } - - if (j < 2) - { - for (j = j+1;j < 3; j++) - pVector[j] = 0; - } -} - -int UTIL_FindEntityInMap(char * name, float * origin, float * angle) -{ - int n,found = 0; - char keyname[256]; - char token[1024]; - - cl_entity_t * pEnt = gEngfuncs.GetEntityByIndex( 0 ); // get world model - - if ( !pEnt ) return 0; - - if ( !pEnt->model ) return 0; - - char * data = pEnt->model->entities; - - while (data) - { - data = gEngfuncs.COM_ParseFile(data, token); - - if ( (token[0] == '}') || (token[0]==0) ) - break; - - if (!data) - { - gEngfuncs.Con_DPrintf("UTIL_FindEntityInMap: EOF without closing brace\n"); - return 0; - } - - if (token[0] != '{') - { - gEngfuncs.Con_DPrintf("UTIL_FindEntityInMap: expected {\n"); - return 0; - } - - // we parse the first { now parse entities properties - - while ( 1 ) - { - // parse key - data = gEngfuncs.COM_ParseFile(data, token); - if (token[0] == '}') - break; // finish parsing this entity - - if (!data) - { - gEngfuncs.Con_DPrintf("UTIL_FindEntityInMap: EOF without closing brace\n"); - return 0; - }; - - strcpy (keyname, token); - - // another hack to fix keynames with trailing spaces - n = strlen(keyname); - while (n && keyname[n-1] == ' ') - { - keyname[n-1] = 0; - n--; - } - - // parse value - data = gEngfuncs.COM_ParseFile(data, token); - if (!data) - { - gEngfuncs.Con_DPrintf("UTIL_FindEntityInMap: EOF without closing brace\n"); - return 0; - }; - - if (token[0] == '}') - { - gEngfuncs.Con_DPrintf("UTIL_FindEntityInMap: closing brace without data"); - return 0; - } - - if (!strcmp(keyname,"classname")) - { - if (!strcmp(token, name )) - { - found = 1; // thats our entity - } - }; - - if( !strcmp( keyname, "angle" ) ) - { - float y = atof( token ); - - if (y >= 0) - { - angle[0] = 0.0f; - angle[1] = y; - } - else if ((int)y == -1) - { - angle[0] = -90.0f; - angle[1] = 0.0f;; - } - else - { - angle[0] = 90.0f; - angle[1] = 0.0f; - } - - angle[2] = 0.0f; - } - - if( !strcmp( keyname, "angles" ) ) - { - UTIL_StringToVector(angle, token); - } - - if (!strcmp(keyname,"origin")) - { - UTIL_StringToVector(origin, token); - - }; - - } // while (1) - - if (found) - return 1; - - } - - return 0; // we search all entities, but didn't found the correct - -} - -//----------------------------------------------------------------------------- -// SetSpectatorStartPosition(): -// Get valid map position and 'beam' spectator to this position -//----------------------------------------------------------------------------- - -void CHudSpectator::SetSpectatorStartPosition() -{ - VectorCopy(vec3_origin, m_cameraOrigin); - VectorCopy(vec3_origin, m_cameraAngles); - - - // search for info_player start - if (!UTIL_FindEntityInMap( "trigger_camera", m_cameraOrigin, m_cameraAngles ) ) - { - if (!UTIL_FindEntityInMap( "info_player_start", m_cameraOrigin, m_cameraAngles ) ) - gEngfuncs.Con_Printf("Couldn't find spectator spawn point.\n"); - // uh, we didn't find anything - } - - VectorCopy(m_cameraOrigin, vJumpOrigin); - VectorCopy(m_cameraAngles, vJumpAngles); - - iJumpSpectator = 1; -} - -//----------------------------------------------------------------------------- -// Purpose: Loads new icons -//----------------------------------------------------------------------------- -int CHudSpectator::VidInit() -{ - m_hsprPlayer = SPR_Load("sprites/iplayer.spr"); - m_hsprPlayerBlue = SPR_Load("sprites/iplayerblue.spr"); - m_hsprPlayerRed = SPR_Load("sprites/iplayerred.spr"); - m_hsprPlayerDead = SPR_Load("sprites/iplayerdead.spr"); - m_hsprUnkownMap = SPR_Load("sprites/tile.spr"); - m_hsprBeam = SPR_Load("sprites/laserbeam.spr"); - m_hsprCamera = SPR_Load("sprites/camera.spr"); - m_hCrosshair = SPR_Load("sprites/crosshairs.spr"); - - return 1; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : flTime - -// intermission - -//----------------------------------------------------------------------------- -int CHudSpectator::Draw(float flTime) -{ - int lx; - - char string[256]; - float * color; - - // draw only in spectator mode - if ( !g_iUser1 ) - return 1; - - // if user pressed zoom, aplly changes - if ( (m_zoomDelta != 0.0f) && (g_iUser1 != OBS_ROAMING) ) - { - m_mapZoom += m_zoomDelta; - - if ( m_mapZoom > 3.0f ) - m_mapZoom = 3.0f; - - if ( m_mapZoom < 0.5f ) - m_mapZoom = 0.5f; - } - - // if user moves in map mode, change map origin - if ( (m_moveDelta != 0.0f) && (g_iUser1 != OBS_ROAMING) ) - { - vec3_t right; - AngleVectors(v_angles, NULL, right, NULL); - VectorNormalize(right); - VectorScale(right, m_moveDelta, right ); - - VectorAdd( m_mapOrigin, right, m_mapOrigin ) - - } - - // Only draw the icon names only if map mode is in Main Mode - if ( g_iUser1 < OBS_MAP_FREE ) - return 1; - - if ( !m_drawnames->value ) - return 1; - - // make sure we have player info - gViewPort->GetAllPlayersInfo(); - - - // loop through all the players and draw additional infos to their sprites on the map - for (int i = 0; i < MAX_PLAYERS; i++) - { - - if ( m_vPlayerPos[i][2]<0 ) // marked as invisible ? - continue; - - // check if name would be in inset window - if ( m_pip->value != INSET_OFF ) - { - if ( m_vPlayerPos[i][0] > XRES( m_OverviewData.insetWindowX ) && - m_vPlayerPos[i][1] > YRES( m_OverviewData.insetWindowY ) && - m_vPlayerPos[i][0] < XRES( m_OverviewData.insetWindowX + m_OverviewData.insetWindowWidth ) && - m_vPlayerPos[i][1] < YRES( m_OverviewData.insetWindowY + m_OverviewData.insetWindowHeight) - ) continue; - } - - color = GetClientColor( i+1 ); - - // draw the players name and health underneath - sprintf(string, "%s", g_PlayerInfoList[i+1].name ); - - lx = strlen(string)*3; // 3 is avg. character length :) - - gEngfuncs.pfnDrawSetTextColor( color[0], color[1], color[2] ); - DrawConsoleString( m_vPlayerPos[i][0]-lx,m_vPlayerPos[i][1], string); - - } - - return 1; -} - - -void CHudSpectator::DirectorMessage( int iSize, void *pbuf ) -{ - float value; - char * string; - - BEGIN_READ( pbuf, iSize ); - - int cmd = READ_BYTE(); - - switch ( cmd ) // director command byte - { - case DRC_CMD_START : - // now we have to do some things clientside, since the proxy doesn't know our mod - - // fake a InitHUD message - gHUD.MsgFunc_InitHUD(NULL,0, NULL); - - break; - - case DRC_CMD_EVENT : - m_lastPrimaryObject = READ_WORD(); - m_lastSecondaryObject = READ_WORD(); - m_iObserverFlags = READ_LONG(); - - if ( m_autoDirector->value ) - { - if ( (g_iUser2 != m_lastPrimaryObject) || (g_iUser3 != m_lastSecondaryObject) ) - V_ResetChaseCam(); - - g_iUser2 = m_lastPrimaryObject; - g_iUser3 = m_lastSecondaryObject; - } - - // gEngfuncs.Con_Printf("Director Camera: %i %i\n", firstObject, secondObject); - break; - - case DRC_CMD_MODE : - if ( m_autoDirector->value ) - { - SetModes( READ_BYTE(), -1 ); - } - break; - - case DRC_CMD_CAMERA : - if ( m_autoDirector->value ) - { - vJumpOrigin[0] = READ_COORD(); // position - vJumpOrigin[1] = READ_COORD(); - vJumpOrigin[2] = READ_COORD(); - - vJumpAngles[0] = READ_COORD(); // view angle - vJumpAngles[1] = READ_COORD(); - vJumpAngles[0] = READ_COORD(); - - iJumpSpectator = 1; - } - break; - - case DRC_CMD_MESSAGE: - { - client_textmessage_t * msg = &m_HUDMessages[m_lastHudMessage]; - - msg->effect = READ_BYTE(); // effect - - UnpackRGB( (int&)msg->r1, (int&)msg->g1, (int&)msg->b2, READ_LONG() ); // color - msg->r2 = msg->r1; - msg->g2 = msg->g1; - msg->b2 = msg->b1; - msg->a2 = msg->a1 = 0xFF; // not transparent - - msg->x = READ_FLOAT(); // x pos - msg->y = READ_FLOAT(); // y pos - - msg->fadein = READ_FLOAT(); // fadein - msg->fadeout = READ_FLOAT(); // fadeout - msg->holdtime = READ_FLOAT(); // holdtime - msg->fxtime = READ_FLOAT(); // fxtime; - - strncpy( m_HUDMessageText[m_lastHudMessage], READ_STRING(), 128 ); - m_HUDMessageText[m_lastHudMessage][127]=0; // text - - msg->pMessage = m_HUDMessageText[m_lastHudMessage]; - msg->pName = "HUD_MESSAGE"; - - gHUD.m_Message.MessageAdd( msg ); - - m_lastHudMessage++; - m_lastHudMessage %= MAX_SPEC_HUD_MESSAGES; - - } - - break; - - case DRC_CMD_SOUND : - string = READ_STRING(); - value = READ_FLOAT(); - - // gEngfuncs.Con_Printf("DRC_CMD_FX_SOUND: %s %.2f\n", string, value ); - PlaySound( string, value ); - - break; - case DRC_CMD_TIMESCALE : - value = READ_FLOAT(); - break; - - - -/* case DRC_CMD_STATUS: - READ_LONG(); // total number of spectator slots - m_iSpectatorNumber = READ_LONG(); // total number of spectator - READ_WORD(); // total number of relay proxies - - gViewPort->UpdateSpectatorPanel(); - break; - - case DRC_CMD_BANNER: - // gEngfuncs.Con_DPrintf("GUI: Banner %s\n",READ_STRING() ); // name of banner tga eg gfx/temp/7454562234563475.tga - gViewPort->m_pSpectatorPanel->m_TopBanner->LoadImage( READ_STRING() ); - gViewPort->UpdateSpectatorPanel(); - break; - case DRC_CMD_FADE: - { - screenfade_t sf; - - sf.fader = 255; - sf.fadeg = 0; - sf.fadeb = 0; - sf.fadealpha = 128; - sf.fadeFlags = FFADE_STAYOUT | FFADE_OUT; - - // gHUD.m_flTime = cl.time - - stream->ReadFloat(); // duration - sf.stream->ReadFloat(); // holdTime - sf.fadeFlags = READ_SHORT(); // flags - stream->ReadLong(); // color RGB - - CallEnghudSetScreenFade( &sf ); - } - break; -*/ - - case DRC_CMD_STUFFTEXT: - ClientCmd( READ_STRING() ); - break; - - default : gEngfuncs.Con_DPrintf("CHudSpectator::DirectorMessage: unknown command %i.\n", cmd ); - } -} - -void CHudSpectator::FindNextPlayer(bool bReverse) -{ - // MOD AUTHORS: Modify the logic of this function if you want to restrict the observer to watching - // only a subset of the players. e.g. Make it check the target's team. - - int iStart; - cl_entity_t * pEnt = NULL; - - // if we are NOT in HLTV mode, spectator targets are set on server - if ( !gEngfuncs.IsSpectateOnly() ) - { - char cmdstring[32]; - // forward command to server - sprintf(cmdstring,"follownext %i",bReverse?1:0); - gEngfuncs.pfnServerCmd(cmdstring); - return; - } - - if ( g_iUser2 ) - iStart = g_iUser2; - else - iStart = 1; - - g_iUser2 = 0; - - int iCurrent = iStart; - - int iDir = bReverse ? -1 : 1; - - // make sure we have player info - gViewPort->GetAllPlayersInfo(); - - - do - { - iCurrent += iDir; - - // Loop through the clients - if (iCurrent > MAX_PLAYERS) - iCurrent = 1; - if (iCurrent < 1) - iCurrent = MAX_PLAYERS; - - pEnt = gEngfuncs.GetEntityByIndex( iCurrent ); - - if ( !IsActivePlayer( pEnt ) ) - continue; - - // MOD AUTHORS: Add checks on target here. - - g_iUser2 = iCurrent; - break; - - } while ( iCurrent != iStart ); - - // Did we find a target? - if ( !g_iUser2 ) - { - gEngfuncs.Con_DPrintf( "No observer targets.\n" ); - // take save camera position - VectorCopy(m_cameraOrigin, vJumpOrigin); - VectorCopy(m_cameraAngles, vJumpAngles); - } - else - { - // use new entity position for roaming - VectorCopy ( pEnt->origin, vJumpOrigin ); - VectorCopy ( pEnt->angles, vJumpAngles ); - } - iJumpSpectator = 1; -} - -void CHudSpectator::HandleButtonsDown( int ButtonPressed ) -{ - double time = gEngfuncs.GetClientTime(); - - int newMainMode = -1; - int newInsetMode = m_pip->value; - - // gEngfuncs.Con_Printf(" HandleButtons:%i\n", ButtonPressed ); - if ( !gViewPort ) - return; - - if ( !g_iUser1 ) - return; // dont do anything if not in spectator mode - - // don't handle buttons during normal demo playback - if ( gEngfuncs.pDemoAPI->IsPlayingback() && !gEngfuncs.IsSpectateOnly() ) - return; - // Slow down mouse clicks. - if ( m_flNextObserverInput > time ) - return; - - // enable spectator screen - if ( ButtonPressed & IN_DUCK ) - gViewPort->m_pSpectatorPanel->ShowMenu(!gViewPort->m_pSpectatorPanel->m_menuVisible); - - // 'Use' changes inset window mode - if ( ButtonPressed & IN_USE ) - { - newInsetMode = ToggleInset(true); - } - - // if not in HLTV mode, buttons are handled server side - if ( gEngfuncs.IsSpectateOnly() ) - { - // changing target or chase mode not in overviewmode without inset window - - // Jump changes main window modes - if ( ButtonPressed & IN_JUMP ) - { - if ( g_iUser1 == OBS_CHASE_LOCKED ) - newMainMode = OBS_CHASE_FREE; - - else if ( g_iUser1 == OBS_CHASE_FREE ) - newMainMode = OBS_IN_EYE; - - else if ( g_iUser1 == OBS_IN_EYE ) - newMainMode = OBS_ROAMING; - - else if ( g_iUser1 == OBS_ROAMING ) - newMainMode = OBS_MAP_FREE; - - else if ( g_iUser1 == OBS_MAP_FREE ) - newMainMode = OBS_MAP_CHASE; - - else - newMainMode = OBS_CHASE_FREE; // don't use OBS_CHASE_LOCKED anymore - } - - // Attack moves to the next player - if ( ButtonPressed & (IN_ATTACK | IN_ATTACK2) ) - { - FindNextPlayer( (ButtonPressed & IN_ATTACK2) ? true:false ); - - if ( g_iUser1 == OBS_ROAMING ) - { - gEngfuncs.SetViewAngles( vJumpAngles ); - iJumpSpectator = 1; - - } - // lease directed mode if player want to see another player - m_autoDirector->value = 0.0f; - } - } - - SetModes(newMainMode, newInsetMode); - - if ( ButtonPressed & IN_FORWARD ) - m_zoomDelta = 0.01f; - - if ( ButtonPressed & IN_BACK ) - m_zoomDelta = -0.01f; - - if ( ButtonPressed & IN_MOVELEFT ) - m_moveDelta = -12.0f; - - if ( ButtonPressed & IN_MOVERIGHT ) - m_moveDelta = 12.0f; - - m_flNextObserverInput = time + 0.2; -} - -void CHudSpectator::HandleButtonsUp( int ButtonPressed ) -{ - if ( !gViewPort ) - return; - - if ( !gViewPort->m_pSpectatorPanel->isVisible() ) - return; // dont do anything if not in spectator mode - - if ( ButtonPressed & (IN_FORWARD | IN_BACK) ) - m_zoomDelta = 0.0f; - - if ( ButtonPressed & (IN_MOVELEFT | IN_MOVERIGHT) ) - m_moveDelta = 0.0f; -} -void CHudSpectator::SetModes(int iNewMainMode, int iNewInsetMode) -{ - static wrect_t crosshairRect; - - // if value == -1 keep old value - if ( iNewMainMode == -1 ) - iNewMainMode = g_iUser1; - - if ( iNewInsetMode == -1 ) - iNewInsetMode = m_pip->value; - - // inset mode is handled only clients side - m_pip->value = iNewInsetMode; - - if ( iNewMainMode < OBS_CHASE_LOCKED || iNewMainMode > OBS_MAP_CHASE ) - { - gEngfuncs.Con_Printf("Invalid spectator mode.\n"); - return; - } - - // main modes ettings will override inset window settings - if ( iNewMainMode != g_iUser1 ) - { - // if we are NOT in HLTV mode, main spectator mode is set on server - if ( !gEngfuncs.IsSpectateOnly() ) - { - char cmdstring[32]; - // forward command to server - sprintf(cmdstring,"specmode %i",iNewMainMode ); - gEngfuncs.pfnServerCmd(cmdstring); - return; - } - - if ( !g_iUser2 ) // make sure we have a target - { - // choose last Director object if still available - if ( IsActivePlayer( gEngfuncs.GetEntityByIndex( m_lastPrimaryObject ) ) ) - { - g_iUser2 = m_lastPrimaryObject; - g_iUser3 = m_lastSecondaryObject; - } - else - FindNextPlayer(false); // find any target - } - - switch ( iNewMainMode ) - { - case OBS_CHASE_LOCKED: g_iUser1 = OBS_CHASE_LOCKED; - break; - - case OBS_CHASE_FREE : g_iUser1 = OBS_CHASE_FREE; - break; - - case OBS_ROAMING : // jump to current vJumpOrigin/angle - g_iUser1 = OBS_ROAMING; - V_GetChasePos( g_iUser2, v_cl_angles, vJumpOrigin, vJumpAngles ); - gEngfuncs.SetViewAngles( vJumpAngles ); - iJumpSpectator = 1; - break; - - case OBS_IN_EYE : g_iUser1 = OBS_IN_EYE; - break; - - case OBS_MAP_FREE : g_iUser1 = OBS_MAP_FREE; - // reset user values - m_mapZoom = m_OverviewData.zoom; - m_mapOrigin = m_OverviewData.origin; - break; - - case OBS_MAP_CHASE : g_iUser1 = OBS_MAP_CHASE; - // reset user values - m_mapZoom = m_OverviewData.zoom; - m_mapOrigin = m_OverviewData.origin; - break; - } - - // enable or disable crosshair - if ( (g_iUser1 == OBS_IN_EYE) || (g_iUser1 == OBS_ROAMING) ) - { - crosshairRect.left = 24; - crosshairRect.top = 0; - crosshairRect.right = 48; - crosshairRect.bottom = 24; - - SetCrosshair( m_hCrosshair, crosshairRect, 255, 255, 255 ); - } - else - { - memset( &crosshairRect,0,sizeof(crosshairRect) ); - SetCrosshair( 0, crosshairRect, 0, 0, 0 ); - } - - char string[128]; - sprintf(string, "#Spec_Mode%d", g_iUser1 ); - sprintf(string, "%c%s", HUD_PRINTCENTER, CHudTextMessage::BufferedLocaliseTextString( string )); - gHUD.m_TextMessage.MsgFunc_TextMsg(NULL, strlen(string)+1, string ); - } - - gViewPort->UpdateSpectatorPanel(); - -} - -bool CHudSpectator::IsActivePlayer(cl_entity_t * ent) -{ - return ( ent && - ent->player && - ent->curstate.solid != SOLID_NOT && - ent != gEngfuncs.GetLocalPlayer() && - g_PlayerInfoList[ent->index].name != NULL - ); -} - - -bool CHudSpectator::ParseOverviewFile( ) -{ - char filename[255]; - char levelname[255]; - char token[1024]; - float height; - - char *pfile = NULL; - - memset( &m_OverviewData, 0, sizeof(m_OverviewData)); - - // fill in standrd values - m_OverviewData.insetWindowX = 4; // upper left corner - m_OverviewData.insetWindowY = 4; - m_OverviewData.insetWindowHeight = 180; - m_OverviewData.insetWindowWidth = 240; - m_OverviewData.origin[0] = 0.0f; - m_OverviewData.origin[1] = 0.0f; - m_OverviewData.origin[2] = 0.0f; - m_OverviewData.zoom = 1.0f; - m_OverviewData.layers = 0; - m_OverviewData.layersHeights[0] = 0.0f; - strcpy( m_OverviewData.map, gEngfuncs.pfnGetLevelName() ); - - if ( strlen( m_OverviewData.map ) == 0 ) - return false; // not active yet - - strcpy(levelname, m_OverviewData.map + 5); - levelname[strlen(levelname)-4] = 0; - - sprintf(filename, "overviews/%s.txt", levelname ); - - pfile = (char *)gEngfuncs.COM_LoadFile( filename, 5, NULL); - - if (!pfile) - { - gEngfuncs.Con_Printf("Couldn't open file %s. Using default values for overiew mode.\n", filename ); - return false; - } - - - while (true) - { - pfile = gEngfuncs.COM_ParseFile(pfile, token); - - if (!pfile) - break; - - if ( !stricmp( token, "global" ) ) - { - // parse the global data - pfile = gEngfuncs.COM_ParseFile(pfile, token); - if ( stricmp( token, "{" ) ) - { - gEngfuncs.Con_Printf("Error parsing overview file %s. (expected { )\n", filename ); - return false; - } - - pfile = gEngfuncs.COM_ParseFile(pfile,token); - - while (stricmp( token, "}") ) - { - if ( !stricmp( token, "zoom" ) ) - { - pfile = gEngfuncs.COM_ParseFile(pfile,token); - m_OverviewData.zoom = atof( token ); - } - else if ( !stricmp( token, "origin" ) ) - { - pfile = gEngfuncs.COM_ParseFile(pfile, token); - m_OverviewData.origin[0] = atof( token ); - pfile = gEngfuncs.COM_ParseFile(pfile,token); - m_OverviewData.origin[1] = atof( token ); - pfile = gEngfuncs.COM_ParseFile(pfile, token); - m_OverviewData.origin[2] = atof( token ); - } - else if ( !stricmp( token, "rotated" ) ) - { - pfile = gEngfuncs.COM_ParseFile(pfile,token); - m_OverviewData.rotated = atoi( token ); - } - else if ( !stricmp( token, "inset" ) ) - { - pfile = gEngfuncs.COM_ParseFile(pfile,token); - m_OverviewData.insetWindowX = atof( token ); - pfile = gEngfuncs.COM_ParseFile(pfile,token); - m_OverviewData.insetWindowY = atof( token ); - pfile = gEngfuncs.COM_ParseFile(pfile,token); - m_OverviewData.insetWindowWidth = atof( token ); - pfile = gEngfuncs.COM_ParseFile(pfile,token); - m_OverviewData.insetWindowHeight = atof( token ); - - } - else - { - gEngfuncs.Con_Printf("Error parsing overview file %s. (%s unkown)\n", filename, token ); - return false; - } - - pfile = gEngfuncs.COM_ParseFile(pfile,token); // parse next token - - } - } - else if ( !stricmp( token, "layer" ) ) - { - // parse a layer data - - if ( m_OverviewData.layers == OVERVIEW_MAX_LAYERS ) - { - gEngfuncs.Con_Printf("Error parsing overview file %s. ( too many layers )\n", filename ); - return false; - } - - pfile = gEngfuncs.COM_ParseFile(pfile,token); - - - if ( stricmp( token, "{" ) ) - { - gEngfuncs.Con_Printf("Error parsing overview file %s. (expected { )\n", filename ); - return false; - } - - pfile = gEngfuncs.COM_ParseFile(pfile,token); - - while (stricmp( token, "}") ) - { - if ( !stricmp( token, "image" ) ) - { - pfile = gEngfuncs.COM_ParseFile(pfile,token); - strcpy(m_OverviewData.layersImages[ m_OverviewData.layers ], token); - - - } - else if ( !stricmp( token, "height" ) ) - { - pfile = gEngfuncs.COM_ParseFile(pfile,token); - height = atof(token); - m_OverviewData.layersHeights[ m_OverviewData.layers ] = height; - } - else - { - gEngfuncs.Con_Printf("Error parsing overview file %s. (%s unkown)\n", filename, token ); - return false; - } - - pfile = gEngfuncs.COM_ParseFile(pfile,token); // parse next token - } - - m_OverviewData.layers++; - - } - } - - gEngfuncs.COM_FreeFile( pfile ); - - m_mapZoom = m_OverviewData.zoom; - m_mapOrigin = m_OverviewData.origin; - - return true; - -} - -void CHudSpectator::LoadMapSprites() -{ - // right now only support for one map layer - if (m_OverviewData.layers > 0 ) - { - m_MapSprite = gEngfuncs.LoadMapSprite( m_OverviewData.layersImages[0] ); - } - else - m_MapSprite = NULL; // the standard "unkown map" sprite will be used instead -} - -void CHudSpectator::DrawOverviewLayer() -{ - float screenaspect, xs, ys, xStep, yStep, x,y,z; - int ix,iy,i,xTiles,yTiles,frame; - - qboolean hasMapImage = m_MapSprite?TRUE:FALSE; - model_t * dummySprite = (struct model_s *)gEngfuncs.GetSpritePointer( m_hsprUnkownMap); - - if ( hasMapImage) - { - i = m_MapSprite->numframes / (4*3); - i = sqrt((float)i); - xTiles = i*4; - yTiles = i*3; - } - else - { - xTiles = 8; - yTiles = 6; - } - - - screenaspect = 4.0f/3.0f; - - - xs = m_OverviewData.origin[0]; - ys = m_OverviewData.origin[1]; - z = ( 90.0f - v_angles[0] ) / 90.0f; - z *= m_OverviewData.layersHeights[0]; // gOverviewData.z_min - 32; - - // i = r_overviewTexture + ( layer*OVERVIEW_X_TILES*OVERVIEW_Y_TILES ); - - gEngfuncs.pTriAPI->RenderMode( kRenderTransTexture ); - gEngfuncs.pTriAPI->CullFace( TRI_NONE ); - gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 1.0 ); - - frame = 0; - - - // rotated view ? - if ( m_OverviewData.rotated ) - { - xStep = (2*4096.0f / m_OverviewData.zoom ) / xTiles; - yStep = -(2*4096.0f / (m_OverviewData.zoom* screenaspect) ) / yTiles; - - y = ys + (4096.0f / (m_OverviewData.zoom * screenaspect)); - - for (iy = 0; iy < yTiles; iy++) - { - x = xs - (4096.0f / (m_OverviewData.zoom)); - - for (ix = 0; ix < xTiles; ix++) - { - if (hasMapImage) - gEngfuncs.pTriAPI->SpriteTexture( m_MapSprite, frame ); - else - gEngfuncs.pTriAPI->SpriteTexture( dummySprite, 0 ); - - gEngfuncs.pTriAPI->Begin( TRI_QUADS ); - gEngfuncs.pTriAPI->TexCoord2f( 0, 0 ); - gEngfuncs.pTriAPI->Vertex3f (x, y, z); - - gEngfuncs.pTriAPI->TexCoord2f( 1, 0 ); - gEngfuncs.pTriAPI->Vertex3f (x+xStep ,y, z); - - gEngfuncs.pTriAPI->TexCoord2f( 1, 1 ); - gEngfuncs.pTriAPI->Vertex3f (x+xStep, y+yStep, z); - - gEngfuncs.pTriAPI->TexCoord2f( 0, 1 ); - gEngfuncs.pTriAPI->Vertex3f (x, y+yStep, z); - gEngfuncs.pTriAPI->End(); - - frame++; - x+= xStep; - } - - y+=yStep; - } - } - else - { - xStep = -(2*4096.0f / m_OverviewData.zoom ) / xTiles; - yStep = -(2*4096.0f / (m_OverviewData.zoom* screenaspect) ) / yTiles; - - - x = xs + (4096.0f / (m_OverviewData.zoom * screenaspect )); - - - - for (ix = 0; ix < yTiles; ix++) - { - - y = ys + (4096.0f / (m_OverviewData.zoom)); - - for (iy = 0; iy < xTiles; iy++) - { - if (hasMapImage) - gEngfuncs.pTriAPI->SpriteTexture( m_MapSprite, frame ); - else - gEngfuncs.pTriAPI->SpriteTexture( dummySprite, 0 ); - - gEngfuncs.pTriAPI->Begin( TRI_QUADS ); - gEngfuncs.pTriAPI->TexCoord2f( 0, 0 ); - gEngfuncs.pTriAPI->Vertex3f (x, y, z); - - gEngfuncs.pTriAPI->TexCoord2f( 0, 1 ); - gEngfuncs.pTriAPI->Vertex3f (x+xStep ,y, z); - - gEngfuncs.pTriAPI->TexCoord2f( 1, 1 ); - gEngfuncs.pTriAPI->Vertex3f (x+xStep, y+yStep, z); - - gEngfuncs.pTriAPI->TexCoord2f( 1, 0 ); - gEngfuncs.pTriAPI->Vertex3f (x, y+yStep, z); - gEngfuncs.pTriAPI->End(); - - frame++; - - y+=yStep; - } - - x+= xStep; - - } - } -} - -void CHudSpectator::DrawOverviewEntities() -{ - int i,ir,ig,ib; - struct model_s *hSpriteModel; - vec3_t origin, angles, point, forward, right, left, up, world, screen, offset; - float x,y,z, r,g,b, sizeScale = 4.0f; - cl_entity_t * ent; - float rmatrix[3][4]; // transformation matrix - - float zScale = (90.0f - v_angles[0] ) / 90.0f; - - - z = m_OverviewData.layersHeights[0] * zScale; - // get yellow/brown HUD color - UnpackRGB(ir,ig,ib, RGB_YELLOWISH); - r = (float)ir/255.0f; - g = (float)ig/255.0f; - b = (float)ib/255.0f; - - gEngfuncs.pTriAPI->CullFace( TRI_NONE ); - - for (i=0; i < MAX_PLAYERS; i++ ) - m_vPlayerPos[i][2] = -1; // mark as invisible - - // draw all players - for (i=0 ; i < MAX_OVERVIEW_ENTITIES ; i++) - { - if ( !m_OverviewEntities[i].hSprite ) - continue; - - hSpriteModel = (struct model_s *)gEngfuncs.GetSpritePointer( m_OverviewEntities[i].hSprite ); - ent = m_OverviewEntities[i].entity; - - gEngfuncs.pTriAPI->SpriteTexture( hSpriteModel, 0 ); - gEngfuncs.pTriAPI->RenderMode( kRenderTransTexture ); - - // see R_DrawSpriteModel - // draws players sprite - - AngleVectors(ent->angles, right, up, NULL ); - - VectorCopy(ent->origin,origin); - - gEngfuncs.pTriAPI->Begin( TRI_QUADS ); - - gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 1.0 ); - - gEngfuncs.pTriAPI->TexCoord2f (1, 0); - VectorMA (origin, 16.0f * sizeScale, up, point); - VectorMA (point, 16.0f * sizeScale, right, point); - point[2] *= zScale; - gEngfuncs.pTriAPI->Vertex3fv (point); - - gEngfuncs.pTriAPI->TexCoord2f (0, 0); - - VectorMA (origin, 16.0f * sizeScale, up, point); - VectorMA (point, -16.0f * sizeScale, right, point); - point[2] *= zScale; - gEngfuncs.pTriAPI->Vertex3fv (point); - - gEngfuncs.pTriAPI->TexCoord2f (0,1); - VectorMA (origin, -16.0f * sizeScale, up, point); - VectorMA (point, -16.0f * sizeScale, right, point); - point[2] *= zScale; - gEngfuncs.pTriAPI->Vertex3fv (point); - - gEngfuncs.pTriAPI->TexCoord2f (1,1); - VectorMA (origin, -16.0f * sizeScale, up, point); - VectorMA (point, 16.0f * sizeScale, right, point); - point[2] *= zScale; - gEngfuncs.pTriAPI->Vertex3fv (point); - - gEngfuncs.pTriAPI->End (); - - - if ( !ent->player) - continue; - // draw line under player icons - origin[2] *= zScale; - - gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); - - hSpriteModel = (struct model_s *)gEngfuncs.GetSpritePointer( m_hsprBeam ); - gEngfuncs.pTriAPI->SpriteTexture( hSpriteModel, 0 ); - - gEngfuncs.pTriAPI->Color4f(r, g, b, 0.3); - - gEngfuncs.pTriAPI->Begin ( TRI_QUADS ); - gEngfuncs.pTriAPI->TexCoord2f (1, 0); - gEngfuncs.pTriAPI->Vertex3f (origin[0]+4, origin[1]+4, origin[2]-zScale); - gEngfuncs.pTriAPI->TexCoord2f (0, 0); - gEngfuncs.pTriAPI->Vertex3f (origin[0]-4, origin[1]-4, origin[2]-zScale); - gEngfuncs.pTriAPI->TexCoord2f (0, 1); - gEngfuncs.pTriAPI->Vertex3f (origin[0]-4, origin[1]-4,z); - gEngfuncs.pTriAPI->TexCoord2f (1, 1); - gEngfuncs.pTriAPI->Vertex3f (origin[0]+4, origin[1]+4,z); - gEngfuncs.pTriAPI->End (); - - gEngfuncs.pTriAPI->Begin ( TRI_QUADS ); - gEngfuncs.pTriAPI->TexCoord2f (1, 0); - gEngfuncs.pTriAPI->Vertex3f (origin[0]-4, origin[1]+4, origin[2]-zScale); - gEngfuncs.pTriAPI->TexCoord2f (0, 0); - gEngfuncs.pTriAPI->Vertex3f (origin[0]+4, origin[1]-4, origin[2]-zScale); - gEngfuncs.pTriAPI->TexCoord2f (0, 1); - gEngfuncs.pTriAPI->Vertex3f (origin[0]+4, origin[1]-4,z); - gEngfuncs.pTriAPI->TexCoord2f (1, 1); - gEngfuncs.pTriAPI->Vertex3f (origin[0]-4, origin[1]+4,z); - gEngfuncs.pTriAPI->End (); - - // calculate screen position for name and infromation in hud::draw() - if ( gEngfuncs.pTriAPI->WorldToScreen(origin,screen) ) - continue; // object is behind viewer - - screen[0] = XPROJECT(screen[0]); - screen[1] = YPROJECT(screen[1]); - screen[2] = 0.0f; - - // calculate some offset under the icon - origin[0]+=32.0f; - origin[1]+=32.0f; - - gEngfuncs.pTriAPI->WorldToScreen(origin,offset); - - offset[0] = XPROJECT(offset[0]); - offset[1] = YPROJECT(offset[1]); - offset[2] = 0.0f; - - VectorSubtract(offset, screen, offset ); - - int playerNum = ent->index - 1; - - m_vPlayerPos[playerNum][0] = screen[0]; - m_vPlayerPos[playerNum][1] = screen[1] + Length(offset); - m_vPlayerPos[playerNum][2] = 1; // mark player as visible - } - - if ( !m_pip->value || !m_drawcone->value ) - return; - - // get current camera position and angle - - if ( m_pip->value == INSET_IN_EYE || g_iUser1 == OBS_IN_EYE ) - { - V_GetInEyePos( g_iUser2, origin, angles ); - } - else if ( m_pip->value == INSET_CHASE_FREE || g_iUser1 == OBS_CHASE_FREE ) - { - V_GetChasePos( g_iUser2, v_cl_angles, origin, angles ); - } - else if ( g_iUser1 == OBS_ROAMING ) - { - VectorCopy( v_sim_org, origin ); - VectorCopy( v_cl_angles, angles ); - } - else - V_GetChasePos( g_iUser2, NULL, origin, angles ); - - // draw camera sprite - - x = origin[0]; - y = origin[1]; - z = origin[2]; - - angles[0] = 0; // always show horizontal camera sprite - - hSpriteModel = (struct model_s *)gEngfuncs.GetSpritePointer( m_hsprCamera ); - gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); - gEngfuncs.pTriAPI->SpriteTexture( hSpriteModel, 0 ); - - gEngfuncs.pTriAPI->Color4f( r, g, b, 1.0 ); - - AngleVectors(angles, forward, NULL, NULL ); - VectorScale (forward, 512.0f, forward); - - offset[0] = 0.0f; - offset[1] = 45.0f; - offset[2] = 0.0f; - - AngleMatrix(offset, rmatrix ); - VectorTransform(forward, rmatrix , right ); - - offset[1]= -45.0f; - AngleMatrix(offset, rmatrix ); - VectorTransform(forward, rmatrix , left ); - - gEngfuncs.pTriAPI->Begin (TRI_TRIANGLES); - gEngfuncs.pTriAPI->TexCoord2f( 0, 0 ); - gEngfuncs.pTriAPI->Vertex3f (x+right[0], y+right[1], (z+right[2]) * zScale); - - gEngfuncs.pTriAPI->TexCoord2f( 0, 1 ); - gEngfuncs.pTriAPI->Vertex3f (x, y, z * zScale); - - gEngfuncs.pTriAPI->TexCoord2f( 1, 1 ); - gEngfuncs.pTriAPI->Vertex3f (x+left[0], y+left[1], (z+left[2]) * zScale); - gEngfuncs.pTriAPI->End (); - -} - - -void CHudSpectator::DrawOverview() -{ - // draw only in sepctator mode - if ( !g_iUser1 ) - return; - - // Only draw the overview if Map Mode is selected for this view - if ( m_iDrawCycle == 0 && ( (g_iUser1 != OBS_MAP_FREE) && (g_iUser1 != OBS_MAP_CHASE) ) ) - return; - - if ( m_iDrawCycle == 1 && m_pip->value < INSET_MAP_FREE ) - return; - - DrawOverviewLayer(); - DrawOverviewEntities(); - CheckOverviewEntities(); -} -void CHudSpectator::CheckOverviewEntities() -{ - double time = gEngfuncs.GetClientTime(); - - // removes old entities from list - for ( int i = 0; i< MAX_OVERVIEW_ENTITIES; i++ ) - { - // remove entity from list if it is too old - if ( m_OverviewEntities[i].killTime < time ) - { - memset( &m_OverviewEntities[i], 0, sizeof (overviewEntity_t) ); - } - } -} - -bool CHudSpectator::AddOverviewEntity( int type, struct cl_entity_s *ent, const char *modelname) -{ - HSPRITE hSprite = 0; - double duration = -1.0f; // duration -1 means show it only this frame; - - if ( !ent ) - return false; - - if ( type == ET_PLAYER ) - { - if ( ent->curstate.solid != SOLID_NOT) - { - switch ( g_PlayerExtraInfo[ent->index].teamnumber ) - { - // blue and red teams are swapped in CS and TFC - case 1 : hSprite = m_hsprPlayerBlue; break; - case 2 : hSprite = m_hsprPlayerRed; break; - default : hSprite = m_hsprPlayer; break; - } - } - else - return false; // it's an spectator - } - else if (type == ET_NORMAL) - { - return false; - } - else - return false; - - return AddOverviewEntityToList(hSprite, ent, gEngfuncs.GetClientTime() + duration ); -} - -void CHudSpectator::DeathMessage(int victim) -{ - // find out where the victim is - cl_entity_t *pl = gEngfuncs.GetEntityByIndex(victim); - - if (pl && pl->player) - AddOverviewEntityToList(m_hsprPlayerDead, pl, gEngfuncs.GetClientTime() + 2.0f ); -} - -bool CHudSpectator::AddOverviewEntityToList(HSPRITE sprite, cl_entity_t *ent, double killTime) -{ - for ( int i = 0; i< MAX_OVERVIEW_ENTITIES; i++ ) - { - // find empty entity slot - if ( m_OverviewEntities[i].entity == NULL) - { - m_OverviewEntities[i].entity = ent; - m_OverviewEntities[i].hSprite = sprite; - m_OverviewEntities[i].killTime = killTime; - return true; - } - } - - return false; // maximum overview entities reached -} -void CHudSpectator::CheckSettings() -{ - // disallow same inset mode as main mode: - - if ( ( g_iUser1 < OBS_MAP_FREE ) && ( m_pip->value == INSET_CHASE_FREE || m_pip->value == INSET_IN_EYE ) ) - { - // otherwise both would show in World picures - m_pip->value = INSET_MAP_FREE; - } - - if ( ( g_iUser1 >= OBS_MAP_FREE ) && ( m_pip->value >= INSET_MAP_FREE ) ) - { - // both would show map views - m_pip->value = INSET_CHASE_FREE; - } - - // disble in intermission screen - if ( gHUD.m_iIntermission ) - m_pip->value = INSET_OFF; - - // check chat mode - if ( m_chatEnabled != (gHUD.m_SayText.m_HUD_saytext->value!=0) ) - { - // hud_saytext changed - m_chatEnabled = (gHUD.m_SayText.m_HUD_saytext->value!=0); - - if ( gEngfuncs.IsSpectateOnly() ) - { - // tell proxy our new chat mode - char chatcmd[32]; - sprintf(chatcmd, "ignoremsg %i", m_chatEnabled?0:1 ); - gEngfuncs.pfnServerCmd(chatcmd); - } - } - - - // draw small border around inset view, adjust upper black bar - gViewPort->m_pSpectatorPanel->EnableInsetView( m_pip->value != INSET_OFF ); -} - -int CHudSpectator::ToggleInset(bool allowOff) -{ - int newInsetMode = m_pip->value + 1; - - if ( g_iUser1 < OBS_MAP_FREE ) - { - if ( newInsetMode > INSET_MAP_CHASE ) - { - if (allowOff) - newInsetMode = INSET_OFF; - else - newInsetMode = INSET_MAP_FREE; - } - - if ( newInsetMode == INSET_CHASE_FREE ) - newInsetMode = INSET_MAP_FREE; - } - else - { - if ( newInsetMode > INSET_IN_EYE ) - { - if (allowOff) - newInsetMode = INSET_OFF; - else - newInsetMode = INSET_CHASE_FREE; - } - } - - return newInsetMode; -} -void CHudSpectator::Reset() -{ - // Reset HUD - if ( strcmp( m_OverviewData.map, gEngfuncs.pfnGetLevelName() ) ) - { - // update level overview if level changed - ParseOverviewFile(); - LoadMapSprites(); - SetSpectatorStartPosition(); - } - - memset( &m_OverviewEntities, 0, sizeof(m_OverviewEntities)); -} - -void CHudSpectator::InitHUDData() -{ - m_lastPrimaryObject = m_lastSecondaryObject = 0; - m_flNextObserverInput = 0.0f; - m_lastHudMessage = 0; - m_iSpectatorNumber = 0; - iJumpSpectator = 0; - g_iUser1 = g_iUser2 = 0; - - memset( &m_OverviewData, 0, sizeof(m_OverviewData)); - memset( &m_OverviewEntities, 0, sizeof(m_OverviewEntities)); - - if ( gEngfuncs.IsSpectateOnly() || gEngfuncs.pDemoAPI->IsPlayingback() ) - m_autoDirector->value = 1.0f; - else - m_autoDirector->value = 0.0f; - - SetModes( OBS_CHASE_FREE, INSET_OFF ); - - g_iUser2 = 0; // fake not target until first camera command - - // reset HUD FOV - gHUD.m_iFOV = CVAR_GET_FLOAT("default_fov"); - Reset(); - SetSpectatorStartPosition(); -} - diff --git a/dmc/cl_dll/hud_spectator.h b/dmc/cl_dll/hud_spectator.h deleted file mode 100644 index ca57ea8..0000000 --- a/dmc/cl_dll/hud_spectator.h +++ /dev/null @@ -1,129 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef SPECTATOR_H -#define SPECTATOR_H -#pragma once - -#include "cl_entity.h" - - - -#define INSET_OFF 0 -#define INSET_CHASE_FREE 1 -#define INSET_IN_EYE 2 -#define INSET_MAP_FREE 3 -#define INSET_MAP_CHASE 4 - -#define MAX_SPEC_HUD_MESSAGES 8 - - - -#define OVERVIEW_TILE_SIZE 128 // don't change this -#define OVERVIEW_MAX_LAYERS 1 - -//----------------------------------------------------------------------------- -// Purpose: Handles the drawing of the spectator stuff (camera & top-down map and all the things on it ) -//----------------------------------------------------------------------------- - -typedef struct overviewInfo_s { - char map[64]; // cl.levelname or empty - vec3_t origin; // center of map - float zoom; // zoom of map images - int layers; // how may layers do we have - float layersHeights[OVERVIEW_MAX_LAYERS]; - char layersImages[OVERVIEW_MAX_LAYERS][255]; - qboolean rotated; // are map images rotated (90 degrees) ? - - int insetWindowX; - int insetWindowY; - int insetWindowHeight; - int insetWindowWidth; -} overviewInfo_t; - -typedef struct overviewEntity_s { - - HSPRITE hSprite; - struct cl_entity_s * entity; - double killTime; -} overviewEntity_t; - -#define MAX_OVERVIEW_ENTITIES 128 - -class CHudSpectator : public CHudBase -{ -public: - void Reset(); - int ToggleInset(bool allowOff); - void CheckSettings(); - void InitHUDData( void ); - bool AddOverviewEntityToList( HSPRITE sprite, cl_entity_t * ent, double killTime); - void DeathMessage(int victim); - bool AddOverviewEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void CheckOverviewEntities(); - void DrawOverview(); - void DrawOverviewEntities(); - void GetMapPosition( float * returnvec ); - void DrawOverviewLayer(); - void LoadMapSprites(); - bool ParseOverviewFile(); - bool IsActivePlayer(cl_entity_t * ent); - void SetModes(int iMainMode, int iInsetMode); - void HandleButtonsDown(int ButtonPressed); - void HandleButtonsUp(int ButtonPressed); - void FindNextPlayer( bool bReverse ); - void DirectorMessage( int iSize, void *pbuf ); - void SetSpectatorStartPosition(); - int Init(); - int VidInit(); - - int Draw(float flTime); - - int m_iDrawCycle; - client_textmessage_t m_HUDMessages[MAX_SPEC_HUD_MESSAGES]; - char m_HUDMessageText[MAX_SPEC_HUD_MESSAGES][128]; - int m_lastHudMessage; - overviewInfo_t m_OverviewData; - overviewEntity_t m_OverviewEntities[MAX_OVERVIEW_ENTITIES]; - int m_iObserverFlags; - int m_iSpectatorNumber; - - float m_mapZoom; // zoom the user currently uses - vec3_t m_mapOrigin; // origin where user rotates around - cvar_t * m_drawnames; - cvar_t * m_drawcone; - cvar_t * m_drawstatus; - cvar_t * m_autoDirector; - cvar_t * m_pip; - - - qboolean m_chatEnabled; - - vec3_t m_cameraOrigin; // a help camera - vec3_t m_cameraAngles; // and it's angles - - -private: - vec3_t m_vPlayerPos[MAX_PLAYERS]; - HSPRITE m_hsprPlayerBlue; - HSPRITE m_hsprPlayerRed; - HSPRITE m_hsprPlayer; - HSPRITE m_hsprCamera; - HSPRITE m_hsprPlayerDead; - HSPRITE m_hsprViewcone; - HSPRITE m_hsprUnkownMap; - HSPRITE m_hsprBeam; - HSPRITE m_hCrosshair; - struct model_s * m_MapSprite; // each layer image is saved in one sprite, where each tile is a sprite frame - float m_flNextObserverInput; - float m_zoomDelta; - float m_moveDelta; - int m_lastPrimaryObject; - int m_lastSecondaryObject; -}; - -#endif // SPECTATOR_H diff --git a/dmc/cl_dll/hud_update.cpp b/dmc/cl_dll/hud_update.cpp deleted file mode 100644 index 7f2b2b8..0000000 --- a/dmc/cl_dll/hud_update.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// hud_update.cpp -// - -#include -#include "hud.h" -#include "cl_util.h" -#include -#include - -int CL_ButtonBits( int ); -void CL_ResetButtonBits( int bits ); - -extern float v_idlescale; -float in_fov; -extern void HUD_SetCmdBits( int bits ); -int iCarriedWeapons; - -int CHud::UpdateClientData(client_data_t *cdata, float time) -{ - memcpy(m_vecOrigin, cdata->origin, sizeof(vec3_t)); - memcpy(m_vecAngles, cdata->viewangles, sizeof(vec3_t)); - - m_iKeyBits = CL_ButtonBits( 0 ); - m_iWeaponBits = cdata->iWeaponBits; - - in_fov = cdata->fov; - - Think(); - - cdata->fov = m_iFOV; - - v_idlescale = m_iConcussionEffect; - - CL_ResetButtonBits( m_iKeyBits ); - - // return 1 if in anything in the client_data struct has been changed, 0 otherwise - return 1; -} - - - diff --git a/dmc/cl_dll/in_camera.cpp b/dmc/cl_dll/in_camera.cpp deleted file mode 100644 index 11dafd5..0000000 --- a/dmc/cl_dll/in_camera.cpp +++ /dev/null @@ -1,628 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" - -#include "SDL2/SDL_mouse.h" -#include "port.h" - -float CL_KeyState (kbutton_t *key); - -extern "C" -{ - void DLLEXPORT CAM_Think( void ); - int DLLEXPORT CL_IsThirdPerson( void ); - void DLLEXPORT CL_CameraOffset( float *ofs ); -} - -extern cl_enginefunc_t gEngfuncs; - -//-------------------------------------------------- Constants - -#define CAM_DIST_DELTA 1.0 -#define CAM_ANGLE_DELTA 2.5 -#define CAM_ANGLE_SPEED 2.5 -#define CAM_MIN_DIST 30.0 -#define CAM_ANGLE_MOVE .5 -#define MAX_ANGLE_DIFF 10.0 -#define PITCH_MAX 90.0 -#define PITCH_MIN 0 -#define YAW_MAX 135.0 -#define YAW_MIN -135.0 - -enum ECAM_Command -{ - CAM_COMMAND_NONE = 0, - CAM_COMMAND_TOTHIRDPERSON = 1, - CAM_COMMAND_TOFIRSTPERSON = 2 -}; - -//-------------------------------------------------- Global Variables - -cvar_t *cam_command; -cvar_t *cam_snapto; -cvar_t *cam_idealyaw; -cvar_t *cam_idealpitch; -cvar_t *cam_idealdist; -cvar_t *cam_contain; - -cvar_t *c_maxpitch; -cvar_t *c_minpitch; -cvar_t *c_maxyaw; -cvar_t *c_minyaw; -cvar_t *c_maxdistance; -cvar_t *c_mindistance; - -// pitch, yaw, dist -vec3_t cam_ofs; - - -// In third person -int cam_thirdperson; -int cam_mousemove; //true if we are moving the cam with the mouse, False if not -int iMouseInUse=0; -int cam_distancemove; -extern int mouse_x, mouse_y; //used to determine what the current x and y values are -int cam_old_mouse_x, cam_old_mouse_y; //holds the last ticks mouse movement -POINT cam_mouse; -//-------------------------------------------------- Local Variables - -static kbutton_t cam_pitchup, cam_pitchdown, cam_yawleft, cam_yawright; -static kbutton_t cam_in, cam_out, cam_move; - -//-------------------------------------------------- Prototypes - -void CAM_ToThirdPerson(void); -void CAM_ToFirstPerson(void); -void CAM_StartDistance(void); -void CAM_EndDistance(void); - -void SDL_GetCursorPos( POINT *p ) -{ - SDL_GetMouseState( (int *)&p->x, (int *)&p->y ); -} - -void SDL_SetCursorPos( const int x, const int y ) -{ -} - - -//-------------------------------------------------- Local Functions - -float MoveToward( float cur, float goal, float maxspeed ) -{ - if( cur != goal ) - { - if( fabs( cur - goal ) > 180.0 ) - { - if( cur < goal ) - cur += 360.0; - else - cur -= 360.0; - } - - if( cur < goal ) - { - if( cur < goal - 1.0 ) - cur += ( goal - cur ) / 4.0; - else - cur = goal; - } - else - { - if( cur > goal + 1.0 ) - cur -= ( cur - goal ) / 4.0; - else - cur = goal; - } - } - - - // bring cur back into range - if( cur < 0 ) - cur += 360.0; - else if( cur >= 360 ) - cur -= 360; - - return cur; -} - - -//-------------------------------------------------- Gobal Functions - -typedef struct -{ - vec3_t boxmins, boxmaxs;// enclose the test object along entire move - float *mins, *maxs; // size of the moving object - vec3_t mins2, maxs2; // size when clipping against mosnters - float *start, *end; - trace_t trace; - int type; - edict_t *passedict; - qboolean monsterclip; -} moveclip_t; - -extern trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end); - -void DLLEXPORT CAM_Think( void ) -{ - vec3_t origin; - vec3_t ext, pnt, camForward, camRight, camUp; - moveclip_t clip; - float dist; - vec3_t camAngles; - float flSensitivity; -#ifdef LATER - int i; -#endif - vec3_t viewangles; - - switch( (int) cam_command->value ) - { - case CAM_COMMAND_TOTHIRDPERSON: - CAM_ToThirdPerson(); - break; - - case CAM_COMMAND_TOFIRSTPERSON: - CAM_ToFirstPerson(); - break; - - case CAM_COMMAND_NONE: - default: - break; - } - - if( !cam_thirdperson ) - return; - -#ifdef LATER - if ( cam_contain->value ) - { - gEngfuncs.GetClientOrigin( origin ); - ext[0] = ext[1] = ext[2] = 0.0; - } -#endif - - camAngles[ PITCH ] = cam_idealpitch->value; - camAngles[ YAW ] = cam_idealyaw->value; - dist = cam_idealdist->value; - // - //movement of the camera with the mouse - // - if (cam_mousemove) - { - //get windows cursor position - SDL_GetCursorPos (&cam_mouse); - //check for X delta values and adjust accordingly - //eventually adjust YAW based on amount of movement - //don't do any movement of the cam using YAW/PITCH if we are zooming in/out the camera - if (!cam_distancemove) - { - - //keep the camera within certain limits around the player (ie avoid certain bad viewing angles) - if (cam_mouse.x>gEngfuncs.GetWindowCenterX()) - { - //if ((camAngles[YAW]>=225.0)||(camAngles[YAW]<135.0)) - if (camAngles[YAW]value) - { - camAngles[ YAW ] += (CAM_ANGLE_MOVE)*((cam_mouse.x-gEngfuncs.GetWindowCenterX())/2); - } - if (camAngles[YAW]>c_maxyaw->value) - { - - camAngles[YAW]=c_maxyaw->value; - } - } - else if (cam_mouse.x225.0)) - if (camAngles[YAW]>c_minyaw->value) - { - camAngles[ YAW ] -= (CAM_ANGLE_MOVE)* ((gEngfuncs.GetWindowCenterX()-cam_mouse.x)/2); - - } - if (camAngles[YAW]value) - { - camAngles[YAW]=c_minyaw->value; - - } - } - - //check for y delta values and adjust accordingly - //eventually adjust PITCH based on amount of movement - //also make sure camera is within bounds - if (cam_mouse.y>gEngfuncs.GetWindowCenterY()) - { - if(camAngles[PITCH]value) - { - camAngles[PITCH] +=(CAM_ANGLE_MOVE)* ((cam_mouse.y-gEngfuncs.GetWindowCenterY())/2); - } - if (camAngles[PITCH]>c_maxpitch->value) - { - camAngles[PITCH]=c_maxpitch->value; - } - } - else if (cam_mouse.yc_minpitch->value) - { - camAngles[PITCH] -= (CAM_ANGLE_MOVE)*((gEngfuncs.GetWindowCenterY()-cam_mouse.y)/2); - } - if (camAngles[PITCH]value) - { - camAngles[PITCH]=c_minpitch->value; - } - } - - //set old mouse coordinates to current mouse coordinates - //since we are done with the mouse - - if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 ) - { - cam_old_mouse_x=cam_mouse.x*flSensitivity; - cam_old_mouse_y=cam_mouse.y*flSensitivity; - } - else - { - cam_old_mouse_x=cam_mouse.x; - cam_old_mouse_y=cam_mouse.y; - } - SDL_SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); - } - } - - //Nathan code here - if( CL_KeyState( &cam_pitchup ) ) - camAngles[ PITCH ] += CAM_ANGLE_DELTA; - else if( CL_KeyState( &cam_pitchdown ) ) - camAngles[ PITCH ] -= CAM_ANGLE_DELTA; - - if( CL_KeyState( &cam_yawleft ) ) - camAngles[ YAW ] -= CAM_ANGLE_DELTA; - else if( CL_KeyState( &cam_yawright ) ) - camAngles[ YAW ] += CAM_ANGLE_DELTA; - - if( CL_KeyState( &cam_in ) ) - { - dist -= CAM_DIST_DELTA; - if( dist < CAM_MIN_DIST ) - { - // If we go back into first person, reset the angle - camAngles[ PITCH ] = 0; - camAngles[ YAW ] = 0; - dist = CAM_MIN_DIST; - } - - } - else if( CL_KeyState( &cam_out ) ) - dist += CAM_DIST_DELTA; - - if (cam_distancemove) - { - if (cam_mouse.y>gEngfuncs.GetWindowCenterY()) - { - if(distvalue) - { - dist +=CAM_DIST_DELTA * ((cam_mouse.y-gEngfuncs.GetWindowCenterY())/2); - } - if (dist>c_maxdistance->value) - { - dist=c_maxdistance->value; - } - } - else if (cam_mouse.yc_mindistance->value) - { - dist -= (CAM_DIST_DELTA)*((gEngfuncs.GetWindowCenterY()-cam_mouse.y)/2); - } - if (distvalue) - { - dist=c_mindistance->value; - } - } - //set old mouse coordinates to current mouse coordinates - //since we are done with the mouse - cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity(); - cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity(); - SDL_SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); - } -#ifdef LATER - if( cam_contain->value ) - { - // check new ideal - VectorCopy( origin, pnt ); - AngleVectors( camAngles, camForward, camRight, camUp ); - for (i=0 ; i<3 ; i++) - pnt[i] += -dist*camForward[i]; - - // check line from r_refdef.vieworg to pnt - memset ( &clip, 0, sizeof ( moveclip_t ) ); - clip.trace = SV_ClipMoveToEntity( sv.edicts, r_refdef.vieworg, ext, ext, pnt ); - if( clip.trace.fraction == 1.0 ) - { - // update ideal - cam_idealpitch->value = camAngles[ PITCH ]; - cam_idealyaw->value = camAngles[ YAW ]; - cam_idealdist->value = dist; - } - } - else -#endif - { - // update ideal - cam_idealpitch->value = camAngles[ PITCH ]; - cam_idealyaw->value = camAngles[ YAW ]; - cam_idealdist->value = dist; - } - - // Move towards ideal - VectorCopy( cam_ofs, camAngles ); - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - if( cam_snapto->value ) - { - camAngles[ YAW ] = cam_idealyaw->value + viewangles[ YAW ]; - camAngles[ PITCH ] = cam_idealpitch->value + viewangles[ PITCH ]; - camAngles[ 2 ] = cam_idealdist->value; - } - else - { - if( camAngles[ YAW ] - viewangles[ YAW ] != cam_idealyaw->value ) - camAngles[ YAW ] = MoveToward( camAngles[ YAW ], cam_idealyaw->value + viewangles[ YAW ], CAM_ANGLE_SPEED ); - - if( camAngles[ PITCH ] - viewangles[ PITCH ] != cam_idealpitch->value ) - camAngles[ PITCH ] = MoveToward( camAngles[ PITCH ], cam_idealpitch->value + viewangles[ PITCH ], CAM_ANGLE_SPEED ); - - if( fabs( camAngles[ 2 ] - cam_idealdist->value ) < 2.0 ) - camAngles[ 2 ] = cam_idealdist->value; - else - camAngles[ 2 ] += ( cam_idealdist->value - camAngles[ 2 ] ) / 4.0; - } -#ifdef LATER - if( cam_contain->value ) - { - // Test new position - dist = camAngles[ ROLL ]; - camAngles[ ROLL ] = 0; - - VectorCopy( origin, pnt ); - AngleVectors( camAngles, camForward, camRight, camUp ); - for (i=0 ; i<3 ; i++) - pnt[i] += -dist*camForward[i]; - - // check line from r_refdef.vieworg to pnt - memset ( &clip, 0, sizeof ( moveclip_t ) ); - ext[0] = ext[1] = ext[2] = 0.0; - clip.trace = SV_ClipMoveToEntity( sv.edicts, r_refdef.vieworg, ext, ext, pnt ); - if( clip.trace.fraction != 1.0 ) - return; - } -#endif - cam_ofs[ 0 ] = camAngles[ 0 ]; - cam_ofs[ 1 ] = camAngles[ 1 ]; - cam_ofs[ 2 ] = dist; -} - -extern void KeyDown (kbutton_t *b); // HACK -extern void KeyUp (kbutton_t *b); // HACK - -void CAM_PitchUpDown(void) { KeyDown( &cam_pitchup ); } -void CAM_PitchUpUp(void) { KeyUp( &cam_pitchup ); } -void CAM_PitchDownDown(void) { KeyDown( &cam_pitchdown ); } -void CAM_PitchDownUp(void) { KeyUp( &cam_pitchdown ); } -void CAM_YawLeftDown(void) { KeyDown( &cam_yawleft ); } -void CAM_YawLeftUp(void) { KeyUp( &cam_yawleft ); } -void CAM_YawRightDown(void) { KeyDown( &cam_yawright ); } -void CAM_YawRightUp(void) { KeyUp( &cam_yawright ); } -void CAM_InDown(void) { KeyDown( &cam_in ); } -void CAM_InUp(void) { KeyUp( &cam_in ); } -void CAM_OutDown(void) { KeyDown( &cam_out ); } -void CAM_OutUp(void) { KeyUp( &cam_out ); } - -void CAM_ToThirdPerson(void) -{ - //Only allow cam_command if we are running a debug version of the client.dll -#ifndef _DEBUG - return; -#endif - - vec3_t viewangles; - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - if( !cam_thirdperson ) - { - cam_thirdperson = 1; - - cam_ofs[ YAW ] = viewangles[ YAW ]; - cam_ofs[ PITCH ] = viewangles[ PITCH ]; - cam_ofs[ 2 ] = CAM_MIN_DIST; - } - - gEngfuncs.Cvar_SetValue( "cam_command", 0 ); -} - -void CAM_ToFirstPerson(void) -{ - cam_thirdperson = 0; - - gEngfuncs.Cvar_SetValue( "cam_command", 0 ); -} - -void CAM_ToggleSnapto( void ) -{ - cam_snapto->value = !cam_snapto->value; -} - -void CAM_Init( void ) -{ - gEngfuncs.pfnAddCommand( "+campitchup", CAM_PitchUpDown ); - gEngfuncs.pfnAddCommand( "-campitchup", CAM_PitchUpUp ); - gEngfuncs.pfnAddCommand( "+campitchdown", CAM_PitchDownDown ); - gEngfuncs.pfnAddCommand( "-campitchdown", CAM_PitchDownUp ); - gEngfuncs.pfnAddCommand( "+camyawleft", CAM_YawLeftDown ); - gEngfuncs.pfnAddCommand( "-camyawleft", CAM_YawLeftUp ); - gEngfuncs.pfnAddCommand( "+camyawright", CAM_YawRightDown ); - gEngfuncs.pfnAddCommand( "-camyawright", CAM_YawRightUp ); - gEngfuncs.pfnAddCommand( "+camin", CAM_InDown ); - gEngfuncs.pfnAddCommand( "-camin", CAM_InUp ); - gEngfuncs.pfnAddCommand( "+camout", CAM_OutDown ); - gEngfuncs.pfnAddCommand( "-camout", CAM_OutUp ); - gEngfuncs.pfnAddCommand( "thirdperson", CAM_ToThirdPerson ); - gEngfuncs.pfnAddCommand( "firstperson", CAM_ToFirstPerson ); - gEngfuncs.pfnAddCommand( "+cammousemove",CAM_StartMouseMove); - gEngfuncs.pfnAddCommand( "-cammousemove",CAM_EndMouseMove); - gEngfuncs.pfnAddCommand( "+camdistance", CAM_StartDistance ); - gEngfuncs.pfnAddCommand( "-camdistance", CAM_EndDistance ); - gEngfuncs.pfnAddCommand( "snapto", CAM_ToggleSnapto ); - - cam_command = gEngfuncs.pfnRegisterVariable ( "cam_command", "0", 0 ); // tells camera to go to thirdperson - cam_snapto = gEngfuncs.pfnRegisterVariable ( "cam_snapto", "0", 0 ); // snap to thirdperson view - cam_idealyaw = gEngfuncs.pfnRegisterVariable ( "cam_idealyaw", "90", 0 ); // thirdperson yaw - cam_idealpitch = gEngfuncs.pfnRegisterVariable ( "cam_idealpitch", "0", 0 ); // thirperson pitch - cam_idealdist = gEngfuncs.pfnRegisterVariable ( "cam_idealdist", "64", 0 ); // thirdperson distance - cam_contain = gEngfuncs.pfnRegisterVariable ( "cam_contain", "0", 0 ); // contain camera to world - - c_maxpitch = gEngfuncs.pfnRegisterVariable ( "c_maxpitch", "90.0", 0 ); - c_minpitch = gEngfuncs.pfnRegisterVariable ( "c_minpitch", "0.0", 0 ); - c_maxyaw = gEngfuncs.pfnRegisterVariable ( "c_maxyaw", "135.0", 0 ); - c_minyaw = gEngfuncs.pfnRegisterVariable ( "c_minyaw", "-135.0", 0 ); - c_maxdistance = gEngfuncs.pfnRegisterVariable ( "c_maxdistance", "200.0", 0 ); - c_mindistance = gEngfuncs.pfnRegisterVariable ( "c_mindistance", "30.0", 0 ); -} - -void CAM_ClearStates( void ) -{ - vec3_t viewangles; - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - cam_pitchup.state = 0; - cam_pitchdown.state = 0; - cam_yawleft.state = 0; - cam_yawright.state = 0; - cam_in.state = 0; - cam_out.state = 0; - - cam_thirdperson = 0; - cam_command->value = 0; - cam_mousemove=0; - - cam_snapto->value = 0; - cam_distancemove = 0; - - cam_ofs[ 0 ] = 0.0; - cam_ofs[ 1 ] = 0.0; - cam_ofs[ 2 ] = CAM_MIN_DIST; - - cam_idealpitch->value = viewangles[ PITCH ]; - cam_idealyaw->value = viewangles[ YAW ]; - cam_idealdist->value = CAM_MIN_DIST; -} - -void CAM_StartMouseMove(void) -{ - float flSensitivity; - - //only move the cam with mouse if we are in third person. - if (cam_thirdperson) - { - //set appropriate flags and initialize the old mouse position - //variables for mouse camera movement - if (!cam_mousemove) - { - cam_mousemove=1; - iMouseInUse=1; - SDL_GetCursorPos (&cam_mouse); - - if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 ) - { - cam_old_mouse_x=cam_mouse.x*flSensitivity; - cam_old_mouse_y=cam_mouse.y*flSensitivity; - } - else - { - cam_old_mouse_x=cam_mouse.x; - cam_old_mouse_y=cam_mouse.y; - } - } - } - //we are not in 3rd person view..therefore do not allow camera movement - else - { - cam_mousemove=0; - iMouseInUse=0; - } -} - -//the key has been released for camera movement -//tell the engine that mouse camera movement is off -void CAM_EndMouseMove(void) -{ - cam_mousemove=0; - iMouseInUse=0; -} - - -//---------------------------------------------------------- -//routines to start the process of moving the cam in or out -//using the mouse -//---------------------------------------------------------- -void CAM_StartDistance(void) -{ - //only move the cam with mouse if we are in third person. - if (cam_thirdperson) - { - //set appropriate flags and initialize the old mouse position - //variables for mouse camera movement - if (!cam_distancemove) - { - cam_distancemove=1; - cam_mousemove=1; - iMouseInUse=1; - SDL_GetCursorPos (&cam_mouse); - cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity(); - cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity(); - } - } - //we are not in 3rd person view..therefore do not allow camera movement - else - { - cam_distancemove=0; - cam_mousemove=0; - iMouseInUse=0; - } -} - -//the key has been released for camera movement -//tell the engine that mouse camera movement is off -void CAM_EndDistance(void) -{ - cam_distancemove=0; - cam_mousemove=0; - iMouseInUse=0; -} - -int DLLEXPORT CL_IsThirdPerson( void ) -{ - return cam_thirdperson ? 1 : 0; -} - -void DLLEXPORT CL_CameraOffset( float *ofs ) -{ - VectorCopy( cam_ofs, ofs ); -} diff --git a/dmc/cl_dll/in_defs.h b/dmc/cl_dll/in_defs.h deleted file mode 100644 index dac97c9..0000000 --- a/dmc/cl_dll/in_defs.h +++ /dev/null @@ -1,19 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( IN_DEFSH ) -#define IN_DEFSH -#pragma once - -// up / down -#define PITCH 0 -// left / right -#define YAW 1 -// fall over -#define ROLL 2 - -#endif \ No newline at end of file diff --git a/dmc/cl_dll/input.cpp b/dmc/cl_dll/input.cpp deleted file mode 100644 index ac2cbdc..0000000 --- a/dmc/cl_dll/input.cpp +++ /dev/null @@ -1,1039 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// cl.input.c -- builds an intended movement command to send to the server - -//xxxxxx Move bob and pitch drifting code here and other stuff from view if needed - -// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All -// rights reserved. -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -extern "C" -{ -#include "kbutton.h" -} -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "view.h" -#include -#include -#include "vgui_viewport.h" -#include "voice_status.h" - -extern "C" -{ - struct kbutton_s DLLEXPORT *KB_Find( const char *name ); - void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ); - void DLLEXPORT HUD_Shutdown( void ); - int DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding ); -} - -extern int g_weaponselect; -extern cl_enginefunc_t gEngfuncs; - -// Defined in pm_math.c -float anglemod( float a ); - -void IN_Init (void); -void IN_Move ( float frametime, usercmd_t *cmd); -void IN_Shutdown( void ); -void V_Init( void ); -int CL_ButtonBits( int ); - -// xxx need client dll function to get and clear impuse -extern cvar_t *in_joystick; - -int in_impulse = 0; -int in_cancel = 0; - -cvar_t *m_pitch; -cvar_t *m_yaw; -cvar_t *m_forward; -cvar_t *m_side; - -cvar_t *lookstrafe; -cvar_t *lookspring; -cvar_t *cl_pitchup; -cvar_t *cl_pitchdown; -cvar_t *cl_upspeed; -cvar_t *cl_forwardspeed; -cvar_t *cl_backspeed; -cvar_t *cl_sidespeed; -cvar_t *cl_movespeedkey; -cvar_t *cl_yawspeed; -cvar_t *cl_pitchspeed; -cvar_t *cl_anglespeedkey; -cvar_t *cl_vsmoothing; -/* -=============================================================================== - -KEY BUTTONS - -Continuous button event tracking is complicated by the fact that two different -input sources (say, mouse button 1 and the control key) can both press the -same button, but the button should only be released when both of the -pressing key have been released. - -When a key event issues a button command (+forward, +attack, etc), it appends -its key number as a parameter to the command so it can be matched up with -the release. - -state bit 0 is the current state of the key -state bit 1 is edge triggered on the up to down transition -state bit 2 is edge triggered on the down to up transition - -=============================================================================== -*/ - - -kbutton_t in_mlook; -kbutton_t in_klook; -kbutton_t in_jlook; -kbutton_t in_left; -kbutton_t in_right; -kbutton_t in_forward; -kbutton_t in_back; -kbutton_t in_lookup; -kbutton_t in_lookdown; -kbutton_t in_moveleft; -kbutton_t in_moveright; -kbutton_t in_strafe; -kbutton_t in_speed; -kbutton_t in_use; -kbutton_t in_jump; -kbutton_t in_attack; -kbutton_t in_attack2; -kbutton_t in_up; -kbutton_t in_down; -kbutton_t in_duck; -kbutton_t in_reload; -kbutton_t in_alt1; -kbutton_t in_score; -kbutton_t in_break; -kbutton_t in_graph; // Display the netgraph - -typedef struct kblist_s -{ - struct kblist_s *next; - kbutton_t *pkey; - char name[32]; -} kblist_t; - -kblist_t *g_kbkeys = NULL; - -/* -============ -KB_ConvertString - -Removes references to +use and replaces them with the keyname in the output string. If - a binding is unfound, then the original text is retained. -NOTE: Only works for text with +word in it. -============ -*/ -int KB_ConvertString( char *in, char **ppout ) -{ - char sz[ 4096 ]; - char binding[ 64 ]; - char *p; - char *pOut; - char *pEnd; - const char *pBinding; - - if ( !ppout ) - return 0; - - *ppout = NULL; - p = in; - pOut = sz; - while ( *p ) - { - if ( *p == '+' ) - { - pEnd = binding; - while ( *p && ( isalnum( *p ) || ( pEnd == binding ) ) && ( ( pEnd - binding ) < 63 ) ) - { - *pEnd++ = *p++; - } - - *pEnd = '\0'; - - pBinding = NULL; - if ( strlen( binding + 1 ) > 0 ) - { - // See if there is a binding for binding? - pBinding = gEngfuncs.Key_LookupBinding( binding + 1 ); - } - - if ( pBinding ) - { - *pOut++ = '['; - pEnd = (char *)pBinding; - } - else - { - pEnd = binding; - } - - while ( *pEnd ) - { - *pOut++ = *pEnd++; - } - - if ( pBinding ) - { - *pOut++ = ']'; - } - } - else - { - *pOut++ = *p++; - } - } - - *pOut = '\0'; - - pOut = ( char * )malloc( strlen( sz ) + 1 ); - strcpy( pOut, sz ); - *ppout = pOut; - - return 1; -} - -/* -============ -KB_Find - -Allows the engine to get a kbutton_t directly ( so it can check +mlook state, etc ) for saving out to .cfg files -============ -*/ -struct kbutton_s DLLEXPORT *KB_Find( const char *name ) -{ - kblist_t *p; - p = g_kbkeys; - while ( p ) - { - if ( !stricmp( name, p->name ) ) - return p->pkey; - - p = p->next; - } - return NULL; -} - -/* -============ -KB_Add - -Add a kbutton_t * to the list of pointers the engine can retrieve via KB_Find -============ -*/ -void KB_Add( const char *name, kbutton_t *pkb ) -{ - kblist_t *p; - kbutton_t *kb; - - kb = KB_Find( name ); - - if ( kb ) - return; - - p = ( kblist_t * )malloc( sizeof( kblist_t ) ); - memset( p, 0, sizeof( *p ) ); - - strcpy( p->name, name ); - p->pkey = pkb; - - p->next = g_kbkeys; - g_kbkeys = p; -} - -/* -============ -KB_Init - -Add kbutton_t definitions that the engine can query if needed -============ -*/ -void KB_Init( void ) -{ - g_kbkeys = NULL; - - KB_Add( "in_graph", &in_graph ); - KB_Add( "in_mlook", &in_mlook ); - KB_Add( "in_jlook", &in_jlook ); -} - -/* -============ -KB_Shutdown - -Clear kblist -============ -*/ -void KB_Shutdown( void ) -{ - kblist_t *p, *n; - p = g_kbkeys; - while ( p ) - { - n = p->next; - free( p ); - p = n; - } - g_kbkeys = NULL; -} - -/* -============ -KeyDown -============ -*/ -void KeyDown (kbutton_t *b) -{ - int k; - char *c; - - c = gEngfuncs.Cmd_Argv(1); - if (c[0]) - k = atoi(c); - else - k = -1; // typed manually at the console for continuous down - - if (k == b->down[0] || k == b->down[1]) - return; // repeating key - - if (!b->down[0]) - b->down[0] = k; - else if (!b->down[1]) - b->down[1] = k; - else - { - gEngfuncs.Con_DPrintf ("Three keys down for a button '%c' '%c' '%c'!\n", b->down[0], b->down[1], c); - return; - } - - if (b->state & 1) - return; // still down - b->state |= 1 + 2; // down + impulse down -} - -/* -============ -KeyUp -============ -*/ -void KeyUp (kbutton_t *b) -{ - int k; - char *c; - - c = gEngfuncs.Cmd_Argv(1); - if (c[0]) - k = atoi(c); - else - { // typed manually at the console, assume for unsticking, so clear all - b->down[0] = b->down[1] = 0; - b->state = 4; // impulse up - return; - } - - if (b->down[0] == k) - b->down[0] = 0; - else if (b->down[1] == k) - b->down[1] = 0; - else - return; // key up without coresponding down (menu pass through) - if (b->down[0] || b->down[1]) - { - //Con_Printf ("Keys down for button: '%c' '%c' '%c' (%d,%d,%d)!\n", b->down[0], b->down[1], c, b->down[0], b->down[1], c); - return; // some other key is still holding it down - } - - if (!(b->state & 1)) - return; // still up (this should not happen) - - b->state &= ~1; // now up - b->state |= 4; // impulse up -} - -/* -============ -HUD_Key_Event - -Return 1 to allow engine to process the key, otherwise, act on it as needed -============ -*/ -int DLLEXPORT HUD_Key_Event( int down, int keynum, const char *pszCurrentBinding ) -{ - if (gViewPort) - { - return gViewPort->KeyInput(down, keynum, pszCurrentBinding); - } - - return 1; -} - -void IN_BreakDown( void ) { KeyDown( &in_break );}; -void IN_BreakUp( void ) { KeyUp( &in_break ); }; -void IN_KLookDown (void) {KeyDown(&in_klook);} -void IN_KLookUp (void) {KeyUp(&in_klook);} -void IN_JLookDown (void) {KeyDown(&in_jlook);} -void IN_JLookUp (void) {KeyUp(&in_jlook);} -void IN_MLookDown (void) {KeyDown(&in_mlook);} -void IN_UpDown(void) {KeyDown(&in_up);} -void IN_UpUp(void) {KeyUp(&in_up);} -void IN_DownDown(void) {KeyDown(&in_down);} -void IN_DownUp(void) {KeyUp(&in_down);} -void IN_LeftDown(void) {KeyDown(&in_left);} -void IN_LeftUp(void) {KeyUp(&in_left);} -void IN_RightDown(void) {KeyDown(&in_right);} -void IN_RightUp(void) {KeyUp(&in_right);} - -void IN_ForwardDown(void) -{ - KeyDown(&in_forward); - gHUD.m_Spectator.HandleButtonsDown( IN_FORWARD ); -} - -void IN_ForwardUp(void) -{ - KeyUp(&in_forward); - gHUD.m_Spectator.HandleButtonsUp( IN_FORWARD ); -} - -void IN_BackDown(void) -{ - KeyDown(&in_back); - gHUD.m_Spectator.HandleButtonsDown( IN_BACK ); -} - -void IN_BackUp(void) -{ - KeyUp(&in_back); - gHUD.m_Spectator.HandleButtonsUp( IN_BACK ); -} -void IN_LookupDown(void) {KeyDown(&in_lookup);} -void IN_LookupUp(void) {KeyUp(&in_lookup);} -void IN_LookdownDown(void) {KeyDown(&in_lookdown);} -void IN_LookdownUp(void) {KeyUp(&in_lookdown);} -void IN_MoveleftDown(void) -{ - KeyDown(&in_moveleft); - gHUD.m_Spectator.HandleButtonsDown( IN_MOVELEFT ); -} - -void IN_MoveleftUp(void) -{ - KeyUp(&in_moveleft); - gHUD.m_Spectator.HandleButtonsUp( IN_MOVELEFT ); -} - -void IN_MoverightDown(void) -{ - KeyDown(&in_moveright); - gHUD.m_Spectator.HandleButtonsDown( IN_MOVERIGHT ); -} - -void IN_MoverightUp(void) -{ - KeyUp(&in_moveright); - gHUD.m_Spectator.HandleButtonsUp( IN_MOVERIGHT ); -} -void IN_SpeedDown(void) {KeyDown(&in_speed);} -void IN_SpeedUp(void) {KeyUp(&in_speed);} -void IN_StrafeDown(void) {KeyDown(&in_strafe);} -void IN_StrafeUp(void) {KeyUp(&in_strafe);} - -void IN_Attack2Down(void) -{ - KeyDown(&in_attack2); - gHUD.m_Spectator.HandleButtonsDown( IN_ATTACK2 ); -} - -void IN_Attack2Up(void) {KeyUp(&in_attack2);} -void IN_UseDown (void) -{ - KeyDown(&in_use); - gHUD.m_Spectator.HandleButtonsDown( IN_USE ); -} -void IN_UseUp (void) {KeyUp(&in_use);} - -void IN_JumpDown (void) -{ - KeyDown(&in_jump); - gHUD.m_Spectator.HandleButtonsDown( IN_JUMP ); -} -void IN_JumpUp (void) {KeyUp(&in_jump);} - -void IN_DuckDown(void) -{ - KeyDown(&in_duck); - gHUD.m_Spectator.HandleButtonsDown( IN_DUCK ); -} -void IN_DuckUp(void) {KeyUp(&in_duck);} -void IN_ReloadDown(void) {KeyDown(&in_reload);} -void IN_ReloadUp(void) {KeyUp(&in_reload);} -void IN_Alt1Down(void) {KeyDown(&in_alt1);} -void IN_Alt1Up(void) {KeyUp(&in_alt1);} -void IN_GraphDown(void) {KeyDown(&in_graph);} -void IN_GraphUp(void) {KeyUp(&in_graph);} - -void IN_AttackDown(void) -{ - KeyDown( &in_attack ); - gHUD.m_Spectator.HandleButtonsDown( IN_ATTACK ); -} - -void IN_AttackUp(void) -{ - KeyUp( &in_attack ); - in_cancel = 0; -} - -// Special handling -void IN_Cancel(void) -{ - in_cancel = 1; -} - -void IN_Impulse (void) -{ - in_impulse = atoi( gEngfuncs.Cmd_Argv(1) ); -} - -void IN_ScoreDown(void) -{ - KeyDown(&in_score); - - if ( gViewPort ) - { - gViewPort->ShowScoreBoard(); - } -} - -void IN_ScoreUp(void) -{ - KeyUp(&in_score); - - if ( gViewPort ) - { - gViewPort->HideScoreBoard(); - } -} - -void IN_MLookUp (void) -{ - KeyUp( &in_mlook ); - if ( !( in_mlook.state & 1 ) && lookspring->value ) - { - V_StartPitchDrift(); - } -} - -/* -=============== -CL_KeyState - -Returns 0.25 if a key was pressed and released during the frame, -0.5 if it was pressed and held -0 if held then released, and -1.0 if held for the entire time -=============== -*/ -float CL_KeyState (kbutton_t *key) -{ - float val = 0.0; - int impulsedown, impulseup, down; - - impulsedown = key->state & 2; - impulseup = key->state & 4; - down = key->state & 1; - - if ( impulsedown && !impulseup ) - { - // pressed and held this frame? - val = down ? 0.5 : 0.0; - } - - if ( impulseup && !impulsedown ) - { - // released this frame? - val = down ? 0.0 : 0.0; - } - - if ( !impulsedown && !impulseup ) - { - // held the entire frame? - val = down ? 1.0 : 0.0; - } - - if ( impulsedown && impulseup ) - { - if ( down ) - { - // released and re-pressed this frame - val = 0.75; - } - else - { - // pressed and released this frame - val = 0.25; - } - } - - // clear impulses - key->state &= 1; - return val; -} - -/* -================ -CL_AdjustAngles - -Moves the local angle positions -================ -*/ -void CL_AdjustAngles ( float frametime, float *viewangles ) -{ - float speed; - float up, down; - - if (in_speed.state & 1) - { - speed = frametime * cl_anglespeedkey->value; - } - else - { - speed = frametime; - } - - if (!(in_strafe.state & 1)) - { - viewangles[YAW] -= speed*cl_yawspeed->value*CL_KeyState (&in_right); - viewangles[YAW] += speed*cl_yawspeed->value*CL_KeyState (&in_left); - viewangles[YAW] = anglemod(viewangles[YAW]); - } - if (in_klook.state & 1) - { - V_StopPitchDrift (); - viewangles[PITCH] -= speed*cl_pitchspeed->value * CL_KeyState (&in_forward); - viewangles[PITCH] += speed*cl_pitchspeed->value * CL_KeyState (&in_back); - } - - up = CL_KeyState (&in_lookup); - down = CL_KeyState(&in_lookdown); - - viewangles[PITCH] -= speed*cl_pitchspeed->value * up; - viewangles[PITCH] += speed*cl_pitchspeed->value * down; - - if (up || down) - V_StopPitchDrift (); - - if (viewangles[PITCH] > cl_pitchdown->value) - viewangles[PITCH] = cl_pitchdown->value; - if (viewangles[PITCH] < -cl_pitchup->value) - viewangles[PITCH] = -cl_pitchup->value; - - if (viewangles[ROLL] > 50) - viewangles[ROLL] = 50; - if (viewangles[ROLL] < -50) - viewangles[ROLL] = -50; -} - -/* -================ -CL_CreateMove - -Send the intended movement message to the server -if active == 1 then we are 1) not playing back demos ( where our commands are ignored ) and -2 ) we have finished signing on to server -================ -*/ -void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ) -{ - float spd; - vec3_t viewangles; - static vec3_t oldangles; - - if ( active ) - { - //memset( viewangles, 0, sizeof( vec3_t ) ); - //viewangles[ 0 ] = viewangles[ 1 ] = viewangles[ 2 ] = 0.0; - gEngfuncs.GetViewAngles( (float *)viewangles ); - - CL_AdjustAngles ( frametime, viewangles ); - - memset (cmd, 0, sizeof(*cmd)); - - gEngfuncs.SetViewAngles( (float *)viewangles ); - - if ( in_strafe.state & 1 ) - { - cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_right); - cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_left); - } - - cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_moveright); - cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_moveleft); - - cmd->upmove += cl_upspeed->value * CL_KeyState (&in_up); - cmd->upmove -= cl_upspeed->value * CL_KeyState (&in_down); - - if ( !(in_klook.state & 1 ) ) - { - cmd->forwardmove += cl_forwardspeed->value * CL_KeyState (&in_forward); - cmd->forwardmove -= cl_backspeed->value * CL_KeyState (&in_back); - } - - // adjust for speed key - if ( in_speed.state & 1 ) - { - cmd->forwardmove *= cl_movespeedkey->value; - cmd->sidemove *= cl_movespeedkey->value; - cmd->upmove *= cl_movespeedkey->value; - } - - // clip to maxspeed - spd = gEngfuncs.GetClientMaxspeed(); - if ( spd != 0.0 ) - { - // scale the 3 speeds so that the total velocity is not > cl.maxspeed - float fmov = sqrt( (cmd->forwardmove*cmd->forwardmove) + (cmd->sidemove*cmd->sidemove) + (cmd->upmove*cmd->upmove) ); - - if ( fmov > spd ) - { - float fratio = spd / fmov; - cmd->forwardmove *= fratio; - cmd->sidemove *= fratio; - cmd->upmove *= fratio; - } - } - - // Allow mice and other controllers to add their inputs - IN_Move ( frametime, cmd ); - } - - cmd->impulse = in_impulse; - in_impulse = 0; - - cmd->weaponselect = g_weaponselect; - g_weaponselect = 0; - - // - // set button and flag bits - // - cmd->buttons = CL_ButtonBits( 1 ); - - // If they're in a modal dialog, ignore the attack button. - if(GetClientVoiceMgr()->IsInSquelchMode()) - cmd->buttons &= ~IN_ATTACK; - - // Using joystick? - if ( in_joystick->value ) - { - if ( cmd->forwardmove > 0 ) - { - cmd->buttons |= IN_FORWARD; - } - else if ( cmd->forwardmove < 0 ) - { - cmd->buttons |= IN_BACK; - } - } - - gEngfuncs.GetViewAngles( (float *)viewangles ); - // Set current view angles. - - if ( gHUD.m_Health.m_iHealth > 0 ) - { - VectorCopy( viewangles, cmd->viewangles ); - VectorCopy( viewangles, oldangles ); - } - else - { - VectorCopy( oldangles, cmd->viewangles ); - } -} - -/* -============ -CL_IsDead - -Returns 1 if health is <= 0 -============ -*/ -int CL_IsDead( void ) -{ - return ( gHUD.m_Health.m_iHealth <= 0 ) ? 1 : 0; -} - -/* -============ -CL_ButtonBits - -Returns appropriate button info for keyboard and mouse state -Set bResetState to 1 to clear old state info -============ -*/ -int CL_ButtonBits( int bResetState ) -{ - int bits = 0; - - if ( in_attack.state & 3 ) - { - bits |= IN_ATTACK; - } - - if (in_duck.state & 3) - { - bits |= IN_DUCK; - } - - if (in_jump.state & 3) - { - bits |= IN_JUMP; - } - - if ( in_forward.state & 3 ) - { - bits |= IN_FORWARD; - } - - if (in_back.state & 3) - { - bits |= IN_BACK; - } - - if (in_use.state & 3) - { - bits |= IN_USE; - } - - if (in_cancel) - { - bits |= IN_CANCEL; - } - - if ( in_left.state & 3 ) - { - bits |= IN_LEFT; - } - - if (in_right.state & 3) - { - bits |= IN_RIGHT; - } - - if ( in_moveleft.state & 3 ) - { - bits |= IN_MOVELEFT; - } - - if (in_moveright.state & 3) - { - bits |= IN_MOVERIGHT; - } - - if (in_attack2.state & 3) - { - bits |= IN_ATTACK2; - } - - if (in_reload.state & 3) - { - bits |= IN_RELOAD; - } - - if (in_alt1.state & 3) - { - bits |= IN_ALT1; - } - - if ( in_score.state & 3 ) - { - bits |= IN_SCORE; - } - - // Dead or in intermission? Shore scoreboard, too - if ( CL_IsDead() || gHUD.m_iIntermission ) - { - bits |= IN_SCORE; - } - - if ( bResetState ) - { - in_attack.state &= ~2; - in_duck.state &= ~2; - in_jump.state &= ~2; - in_forward.state &= ~2; - in_back.state &= ~2; - in_use.state &= ~2; - in_left.state &= ~2; - in_right.state &= ~2; - in_moveleft.state &= ~2; - in_moveright.state &= ~2; - in_attack2.state &= ~2; - in_reload.state &= ~2; - in_alt1.state &= ~2; - in_score.state &= ~2; - } - - return bits; -} - -/* -============ -CL_ResetButtonBits - -============ -*/ -void CL_ResetButtonBits( int bits ) -{ - int bitsNew = CL_ButtonBits( 0 ) ^ bits; - - // Has the attack button been changed - if ( bitsNew & IN_ATTACK ) - { - // Was it pressed? or let go? - if ( bits & IN_ATTACK ) - { - KeyDown( &in_attack ); - } - else - { - // totally clear state - in_attack.state &= ~7; - } - } -} - -/* -============ -InitInput -============ -*/ -void InitInput (void) -{ - gEngfuncs.pfnAddCommand ("+moveup",IN_UpDown); - gEngfuncs.pfnAddCommand ("-moveup",IN_UpUp); - gEngfuncs.pfnAddCommand ("+movedown",IN_DownDown); - gEngfuncs.pfnAddCommand ("-movedown",IN_DownUp); - gEngfuncs.pfnAddCommand ("+left",IN_LeftDown); - gEngfuncs.pfnAddCommand ("-left",IN_LeftUp); - gEngfuncs.pfnAddCommand ("+right",IN_RightDown); - gEngfuncs.pfnAddCommand ("-right",IN_RightUp); - gEngfuncs.pfnAddCommand ("+forward",IN_ForwardDown); - gEngfuncs.pfnAddCommand ("-forward",IN_ForwardUp); - gEngfuncs.pfnAddCommand ("+back",IN_BackDown); - gEngfuncs.pfnAddCommand ("-back",IN_BackUp); - gEngfuncs.pfnAddCommand ("+lookup", IN_LookupDown); - gEngfuncs.pfnAddCommand ("-lookup", IN_LookupUp); - gEngfuncs.pfnAddCommand ("+lookdown", IN_LookdownDown); - gEngfuncs.pfnAddCommand ("-lookdown", IN_LookdownUp); - gEngfuncs.pfnAddCommand ("+strafe", IN_StrafeDown); - gEngfuncs.pfnAddCommand ("-strafe", IN_StrafeUp); - gEngfuncs.pfnAddCommand ("+moveleft", IN_MoveleftDown); - gEngfuncs.pfnAddCommand ("-moveleft", IN_MoveleftUp); - gEngfuncs.pfnAddCommand ("+moveright", IN_MoverightDown); - gEngfuncs.pfnAddCommand ("-moveright", IN_MoverightUp); - gEngfuncs.pfnAddCommand ("+speed", IN_SpeedDown); - gEngfuncs.pfnAddCommand ("-speed", IN_SpeedUp); - gEngfuncs.pfnAddCommand ("+attack", IN_AttackDown); - gEngfuncs.pfnAddCommand ("-attack", IN_AttackUp); - gEngfuncs.pfnAddCommand ("+attack2", IN_Attack2Down); - gEngfuncs.pfnAddCommand ("-attack2", IN_Attack2Up); - gEngfuncs.pfnAddCommand ("+use", IN_UseDown); - gEngfuncs.pfnAddCommand ("-use", IN_UseUp); - gEngfuncs.pfnAddCommand ("+jump", IN_JumpDown); - gEngfuncs.pfnAddCommand ("-jump", IN_JumpUp); - gEngfuncs.pfnAddCommand ("impulse", IN_Impulse); - gEngfuncs.pfnAddCommand ("+klook", IN_KLookDown); - gEngfuncs.pfnAddCommand ("-klook", IN_KLookUp); - gEngfuncs.pfnAddCommand ("+mlook", IN_MLookDown); - gEngfuncs.pfnAddCommand ("-mlook", IN_MLookUp); - gEngfuncs.pfnAddCommand ("+jlook", IN_JLookDown); - gEngfuncs.pfnAddCommand ("-jlook", IN_JLookUp); - gEngfuncs.pfnAddCommand ("+duck", IN_DuckDown); - gEngfuncs.pfnAddCommand ("-duck", IN_DuckUp); - gEngfuncs.pfnAddCommand ("+reload", IN_ReloadDown); - gEngfuncs.pfnAddCommand ("-reload", IN_ReloadUp); - gEngfuncs.pfnAddCommand ("+alt1", IN_Alt1Down); - gEngfuncs.pfnAddCommand ("-alt1", IN_Alt1Up); - gEngfuncs.pfnAddCommand ("+score", IN_ScoreDown); - gEngfuncs.pfnAddCommand ("-score", IN_ScoreUp); - gEngfuncs.pfnAddCommand ("+showscores", IN_ScoreDown); - gEngfuncs.pfnAddCommand ("-showscores", IN_ScoreUp); - gEngfuncs.pfnAddCommand ("+graph", IN_GraphDown); - gEngfuncs.pfnAddCommand ("-graph", IN_GraphUp); - gEngfuncs.pfnAddCommand ("+break",IN_BreakDown); - gEngfuncs.pfnAddCommand ("-break",IN_BreakUp); - - lookstrafe = gEngfuncs.pfnRegisterVariable ( "lookstrafe", "0", FCVAR_ARCHIVE ); - lookspring = gEngfuncs.pfnRegisterVariable ( "lookspring", "0", FCVAR_ARCHIVE ); - cl_anglespeedkey = gEngfuncs.pfnRegisterVariable ( "cl_anglespeedkey", "0.67", 0 ); - cl_yawspeed = gEngfuncs.pfnRegisterVariable ( "cl_yawspeed", "210", 0 ); - cl_pitchspeed = gEngfuncs.pfnRegisterVariable ( "cl_pitchspeed", "225", 0 ); - cl_upspeed = gEngfuncs.pfnRegisterVariable ( "cl_upspeed", "320", 0 ); - cl_forwardspeed = gEngfuncs.pfnRegisterVariable ( "cl_forwardspeed", "400", FCVAR_ARCHIVE ); - cl_backspeed = gEngfuncs.pfnRegisterVariable ( "cl_backspeed", "400", FCVAR_ARCHIVE ); - cl_sidespeed = gEngfuncs.pfnRegisterVariable ( "cl_sidespeed", "400", 0 ); - cl_movespeedkey = gEngfuncs.pfnRegisterVariable ( "cl_movespeedkey", "0.3", 0 ); - cl_pitchup = gEngfuncs.pfnRegisterVariable ( "cl_pitchup", "89", 0 ); - cl_pitchdown = gEngfuncs.pfnRegisterVariable ( "cl_pitchdown", "89", 0 ); - - cl_vsmoothing = gEngfuncs.pfnRegisterVariable ( "cl_vsmoothing", "0.05", FCVAR_ARCHIVE ); - - m_pitch = gEngfuncs.pfnRegisterVariable ( "m_pitch","0.022", FCVAR_ARCHIVE ); - m_yaw = gEngfuncs.pfnRegisterVariable ( "m_yaw","0.022", FCVAR_ARCHIVE ); - m_forward = gEngfuncs.pfnRegisterVariable ( "m_forward","1", FCVAR_ARCHIVE ); - m_side = gEngfuncs.pfnRegisterVariable ( "m_side","0.8", FCVAR_ARCHIVE ); - - // Initialize third person camera controls. - CAM_Init(); - // Initialize inputs - IN_Init(); - // Initialize keyboard - KB_Init(); - // Initialize view system - V_Init(); -} - -/* -============ -ShutdownInput -============ -*/ -void ShutdownInput (void) -{ - IN_Shutdown(); - KB_Shutdown(); -} - -#include "interface.h" - -void DLLEXPORT HUD_Shutdown( void ) -{ - ShutdownInput(); - - extern CSysModule *g_hTrackerModule; - if (g_hTrackerModule) - { - Sys_UnloadModule(g_hTrackerModule); - } - - extern CSysModule *g_pFileSystemModule; - if (g_pFileSystemModule) - { - Sys_UnloadModule(g_pFileSystemModule); - } - -} diff --git a/dmc/cl_dll/inputw32.cpp b/dmc/cl_dll/inputw32.cpp deleted file mode 100644 index cf90512..0000000 --- a/dmc/cl_dll/inputw32.cpp +++ /dev/null @@ -1,942 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// in_win.c -- windows 95 mouse and joystick code -// 02/21/97 JCB Added extended DirectInput code to support external controllers. - -#include "port.h" -#include -#include - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "../public/keydefs.h" -#include "view.h" -#include "Exports.h" -/*#ifdef _WIN32 -#define DLLEXPORT EXPORT -#else -#define DLLEXPORT __attribute__ ((visibility("default"))) -#endif*/ - -#define MOUSE_BUTTON_COUNT 5 - -// Set this to 1 to show mouse cursor. Experimental -int g_iVisibleMouse = 0; - -extern cl_enginefunc_t gEngfuncs; - -extern int iMouseInUse; - -extern kbutton_t in_strafe; -extern kbutton_t in_mlook; -extern kbutton_t in_speed; -extern kbutton_t in_jlook; - -extern cvar_t *m_pitch; -extern cvar_t *m_yaw; -extern cvar_t *m_forward; -extern cvar_t *m_side; - -extern cvar_t *lookstrafe; -extern cvar_t *lookspring; -extern cvar_t *cl_pitchdown; -extern cvar_t *cl_pitchup; -extern cvar_t *cl_yawspeed; -extern cvar_t *cl_sidespeed; -extern cvar_t *cl_forwardspeed; -extern cvar_t *cl_pitchspeed; -extern cvar_t *cl_movespeedkey; - -// mouse variables -cvar_t *m_filter; -cvar_t *sensitivity; - -// Custom mouse acceleration (0 disable, 1 to enable, 2 enable with separate yaw/pitch rescale) -static cvar_t *m_customaccel; -//Formula: mousesensitivity = ( rawmousedelta^m_customaccel_exponent ) * m_customaccel_scale + sensitivity -// If mode is 2, then x and y sensitivity are scaled by m_pitch and m_yaw respectively. -// Custom mouse acceleration value. -static cvar_t *m_customaccel_scale; -//Max mouse move scale factor, 0 for no limit -static cvar_t *m_customaccel_max; -//Mouse move is raised to this power before being scaled by scale factor -static cvar_t *m_customaccel_exponent; - -int mouse_buttons; -int mouse_oldbuttonstate; -POINT current_pos; -int old_mouse_x, old_mouse_y, mx_accum, my_accum; -float mouse_x, mouse_y; - -static int restore_spi; -static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; -static int mouseactive; -int mouseinitialized; -static int mouseparmsvalid; -static int mouseshowtoggle = 1; - -// joystick defines and variables -// where should defines be moved? -#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick -#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball -#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V -#define JOY_AXIS_X 0 -#define JOY_AXIS_Y 1 -#define JOY_AXIS_Z 2 -#define JOY_AXIS_R 3 -#define JOY_AXIS_U 4 -#define JOY_AXIS_V 5 - -enum _ControlList -{ - AxisNada = 0, - AxisForward, - AxisLook, - AxisSide, - AxisTurn -}; - - -DWORD dwAxisMap[ JOY_MAX_AXES ]; -DWORD dwControlMap[ JOY_MAX_AXES ]; -DWORD pdwRawValue[ JOY_MAX_AXES ]; -DWORD joy_oldbuttonstate, joy_oldpovstate; - -int joy_id; -DWORD joy_flags; -DWORD joy_numbuttons; - -SDL_GameController *s_pJoystick = NULL; - -// none of these cvars are saved over a session -// this means that advanced controller configuration needs to be executed -// each time. this avoids any problems with getting back to a default usage -// or when changing from one controller to another. this way at least something -// works. -cvar_t *in_joystick; -cvar_t *joy_name; -cvar_t *joy_advanced; -cvar_t *joy_advaxisx; -cvar_t *joy_advaxisy; -cvar_t *joy_advaxisz; -cvar_t *joy_advaxisr; -cvar_t *joy_advaxisu; -cvar_t *joy_advaxisv; -cvar_t *joy_forwardthreshold; -cvar_t *joy_sidethreshold; -cvar_t *joy_pitchthreshold; -cvar_t *joy_yawthreshold; -cvar_t *joy_forwardsensitivity; -cvar_t *joy_sidesensitivity; -cvar_t *joy_pitchsensitivity; -cvar_t *joy_yawsensitivity; -cvar_t *joy_wwhack1; -cvar_t *joy_wwhack2; - -int joy_avail, joy_advancedinit, joy_haspov; - -/* -=========== -Force_CenterView_f -=========== -*/ -void Force_CenterView_f (void) -{ - vec3_t viewangles; - - if (!iMouseInUse) - { - gEngfuncs.GetViewAngles( (float *)viewangles ); - viewangles[PITCH] = 0; - gEngfuncs.SetViewAngles( (float *)viewangles ); - } -} - -/* -=========== -IN_ActivateMouse -=========== -*/ -void DLLEXPORT IN_ActivateMouse (void) -{ - if (mouseinitialized) - { -#ifdef _WIN32 - if (mouseparmsvalid) - restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); -#endif - mouseactive = 1; - } -} - -/* -=========== -IN_DeactivateMouse -=========== -*/ -void DLLEXPORT IN_DeactivateMouse (void) -{ - if (mouseinitialized) - { -#ifdef _WIN32 - if (restore_spi) - SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); -#endif - - mouseactive = 0; - } -} - -/* -=========== -IN_StartupMouse -=========== -*/ -void IN_StartupMouse (void) -{ - if ( gEngfuncs.CheckParm ("-nomouse", NULL ) ) - return; - - mouseinitialized = 1; -#ifdef _WIN32 - mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); - - if (mouseparmsvalid) - { - if ( gEngfuncs.CheckParm ("-noforcemspd", NULL ) ) - newmouseparms[2] = originalmouseparms[2]; - - if ( gEngfuncs.CheckParm ("-noforcemaccel", NULL ) ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - } - - if ( gEngfuncs.CheckParm ("-noforcemparms", NULL ) ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - newmouseparms[2] = originalmouseparms[2]; - } - } -#endif - - mouse_buttons = MOUSE_BUTTON_COUNT; -} - -/* -=========== -IN_Shutdown -=========== -*/ -void IN_Shutdown (void) -{ - IN_DeactivateMouse (); -} - -/* -=========== -IN_GetMousePos - -Ask for mouse position from engine -=========== -*/ -void IN_GetMousePos( int *mx, int *my ) -{ - gEngfuncs.GetMousePosition( mx, my ); -} - -/* -=========== -IN_ResetMouse - -FIXME: Call through to engine? -=========== -*/ -void IN_ResetMouse( void ) -{ -} - -/* -=========== -IN_MouseEvent -=========== -*/ -void DLLEXPORT IN_MouseEvent (int mstate) -{ - int i; - - if ( iMouseInUse || g_iVisibleMouse ) - return; - - // perform button actions - for (i=0 ; ivalue; - - // Using special accleration values - if ( m_customaccel->value != 0 ) - { - float raw_mouse_movement_distance = sqrt( mx * mx + my * my ); - float acceleration_scale = m_customaccel_scale->value; - float accelerated_sensitivity_max = m_customaccel_max->value; - float accelerated_sensitivity_exponent = m_customaccel_exponent->value; - float accelerated_sensitivity = ( (float)pow( raw_mouse_movement_distance, accelerated_sensitivity_exponent ) * acceleration_scale + mouse_senstivity ); - - if ( accelerated_sensitivity_max > 0.0001f && - accelerated_sensitivity > accelerated_sensitivity_max ) - { - accelerated_sensitivity = accelerated_sensitivity_max; - } - - *x *= accelerated_sensitivity; - *y *= accelerated_sensitivity; - - // Further re-scale by yaw and pitch magnitude if user requests alternate mode 2 - // This means that they will need to up their value for m_customaccel_scale greatly (>40x) since m_pitch/yaw default - // to 0.022 - if ( m_customaccel->value == 2 ) - { - *x *= m_yaw->value; - *y *= m_pitch->value; - } - } - else - { - // Just apply the default - *x *= mouse_senstivity; - *y *= mouse_senstivity; - } -} - -/* -=========== -IN_MouseMove -=========== -*/ -void IN_MouseMove ( float frametime, usercmd_t *cmd) -{ - int mx, my; - vec3_t viewangles; - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - if ( in_mlook.state & 1) - { - V_StopPitchDrift (); - } - - //jjb - this disbles normal mouse control if the user is trying to - // move the camera, or if the mouse cursor is visible or if we're in intermission - if ( !iMouseInUse && !gHUD.m_iIntermission && !g_iVisibleMouse ) - { - int deltaX, deltaY; - SDL_GetRelativeMouseState( &deltaX, &deltaY ); - current_pos.x = deltaX; - current_pos.y = deltaY; - mx = deltaX + mx_accum; - my = deltaY + my_accum; - - mx_accum = 0; - my_accum = 0; - - if (m_filter->value) - { - mouse_x = (mx + old_mouse_x) * 0.5; - mouse_y = (my + old_mouse_y) * 0.5; - } - else - { - mouse_x = mx; - mouse_y = my; - } - - old_mouse_x = mx; - old_mouse_y = my; - - // Apply custom mouse scaling/acceleration - IN_ScaleMouse( &mouse_x, &mouse_y ); - - // add mouse X/Y movement to cmd - if ( (in_strafe.state & 1) || (lookstrafe->value && (in_mlook.state & 1) )) - cmd->sidemove += m_side->value * mouse_x; - else - viewangles[YAW] -= m_yaw->value * mouse_x; - - if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) - { - viewangles[PITCH] += m_pitch->value * mouse_y; - if (viewangles[PITCH] > cl_pitchdown->value) - viewangles[PITCH] = cl_pitchdown->value; - if (viewangles[PITCH] < -cl_pitchup->value) - viewangles[PITCH] = -cl_pitchup->value; - } - else - { - if ((in_strafe.state & 1) && gEngfuncs.IsNoClipping() ) - { - cmd->upmove -= m_forward->value * mouse_y; - } - else - { - cmd->forwardmove -= m_forward->value * mouse_y; - } - } - - // if the mouse has moved, force it to the center, so there's room to move - if ( mx || my ) - { - IN_ResetMouse(); - } - } - - gEngfuncs.SetViewAngles( (float *)viewangles ); - -/* -//#define TRACE_TEST -#if defined( TRACE_TEST ) - { - int mx, my; - void V_Move( int mx, int my ); - IN_GetMousePos( &mx, &my ); - V_Move( mx, my ); - } -#endif -*/ -} - -/* -=========== -IN_Accumulate -=========== -*/ -void DLLEXPORT IN_Accumulate (void) -{ - //only accumulate mouse if we are not moving the camera with the mouse - if ( !iMouseInUse && !g_iVisibleMouse) - { - if (mouseactive) - { - int deltaX, deltaY; - SDL_GetRelativeMouseState( &deltaX, &deltaY ); - mx_accum += deltaX; - my_accum += deltaY; - // force the mouse to the center, so there's room to move - IN_ResetMouse(); - - } - } - -} - -/* -=================== -IN_ClearStates -=================== -*/ -void DLLEXPORT IN_ClearStates (void) -{ - if ( !mouseactive ) - return; - - mx_accum = 0; - my_accum = 0; - mouse_oldbuttonstate = 0; -} - -/* -=============== -IN_StartupJoystick -=============== -*/ -void IN_StartupJoystick (void) -{ - // abort startup if user requests no joystick - if ( gEngfuncs.CheckParm ("-nojoy", NULL ) ) - return; - - // assume no joystick - joy_avail = 0; - - int nJoysticks = SDL_NumJoysticks(); - if ( nJoysticks > 0 ) - { - for ( int i = 0; i < nJoysticks; i++ ) - { - if ( SDL_IsGameController( i ) ) - { - s_pJoystick = SDL_GameControllerOpen( i ); - if ( s_pJoystick ) - { - //save the joystick's number of buttons and POV status - joy_numbuttons = SDL_CONTROLLER_BUTTON_MAX; - joy_haspov = 0; - - // old button and POV states default to no buttons pressed - joy_oldbuttonstate = joy_oldpovstate = 0; - - // mark the joystick as available and advanced initialization not completed - // this is needed as cvars are not available during initialization - gEngfuncs.Con_Printf ("joystick found\n\n", SDL_GameControllerName(s_pJoystick)); - joy_avail = 1; - joy_advancedinit = 0; - break; - } - - } - } - } - else - { - gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); - } -} - -int RawValuePointer (int axis) -{ - switch (axis) - { - default: - case JOY_AXIS_X: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX ); - case JOY_AXIS_Y: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY ); - case JOY_AXIS_Z: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX ); - case JOY_AXIS_R: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY ); - - } -} - -/* -=========== -Joy_AdvancedUpdate_f -=========== -*/ -void Joy_AdvancedUpdate_f (void) -{ - - // called once by IN_ReadJoystick and by user whenever an update is needed - // cvars are now available - int i; - DWORD dwTemp; - - // initialize all the maps - for (i = 0; i < JOY_MAX_AXES; i++) - { - dwAxisMap[i] = AxisNada; - dwControlMap[i] = JOY_ABSOLUTE_AXIS; - pdwRawValue[i] = RawValuePointer(i); - } - - if( joy_advanced->value == 0.0) - { - // default joystick initialization - // 2 axes only with joystick control - dwAxisMap[JOY_AXIS_X] = AxisTurn; - // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS; - dwAxisMap[JOY_AXIS_Y] = AxisForward; - // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS; - } - else - { - if ( strcmp ( joy_name->string, "joystick") != 0 ) - { - // notify user of advanced controller - gEngfuncs.Con_Printf ("\n%s configured\n\n", joy_name->string); - } - - // advanced initialization here - // data supplied by user via joy_axisn cvars - dwTemp = (DWORD) joy_advaxisx->value; - dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisy->value; - dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisz->value; - dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisr->value; - dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisu->value; - dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisv->value; - dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; - } -} - - -/* -=========== -IN_Commands -=========== -*/ -void IN_Commands (void) -{ - int i, key_index; - - if (!joy_avail) - { - return; - } - - DWORD buttonstate, povstate; - - // loop through the joystick buttons - // key a joystick event or auxillary event for higher number buttons for each state change - buttonstate = 0; - for ( i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) - { - if ( SDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i ) ) - { - buttonstate |= 1<value) - { - return; - } - - // collect the joystick data, if possible - if (IN_ReadJoystick () != 1) - { - return; - } - - if (in_speed.state & 1) - speed = cl_movespeedkey->value; - else - speed = 1; - - aspeed = speed * frametime; - - // loop through the axes - for (i = 0; i < JOY_MAX_AXES; i++) - { - // get the floating point zero-centered, potentially-inverted data for the current axis - fAxisValue = (float) pdwRawValue[i]; - // move centerpoint to zero - fAxisValue -= 32768.0; - - if (joy_wwhack2->value != 0.0) - { - if (dwAxisMap[i] == AxisTurn) - { - // this is a special formula for the Logitech WingMan Warrior - // y=ax^b; where a = 300 and b = 1.3 - // also x values are in increments of 800 (so this is factored out) - // then bounds check result to level out excessively high spin rates - fTemp = 300.0 * pow( fabs(fAxisValue) / 800.0, 1.3); - if (fTemp > 14000.0) - fTemp = 14000.0; - // restore direction information - fAxisValue = (fAxisValue > 0.0) ? fTemp : -fTemp; - } - } - - // convert range from -32768..32767 to -1..1 - fAxisValue /= 32768.0; - - switch (dwAxisMap[i]) - { - case AxisForward: - if ((joy_advanced->value == 0.0) && (in_jlook.state & 1)) - { - // user wants forward control to become look control - if (fabs(fAxisValue) > joy_pitchthreshold->value) - { - // if mouse invert is on, invert the joystick pitch value - // only absolute control support here (joy_advanced is 0) - if (m_pitch->value < 0.0) - { - viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; - } - else - { - viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; - } - V_StopPitchDrift(); - } - else - { - // no pitch movement - // disable pitch return-to-center unless requested by user - // *** this code can be removed when the lookspring bug is fixed - // *** the bug always has the lookspring feature on - if(lookspring->value == 0.0) - { - V_StopPitchDrift(); - } - } - } - else - { - // user wants forward control to be forward control - if (fabs(fAxisValue) > joy_forwardthreshold->value) - { - cmd->forwardmove += (fAxisValue * joy_forwardsensitivity->value) * speed * cl_forwardspeed->value; - } - } - break; - - case AxisSide: - if (fabs(fAxisValue) > joy_sidethreshold->value) - { - cmd->sidemove += (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; - } - break; - - case AxisTurn: - if ((in_strafe.state & 1) || (lookstrafe->value && (in_jlook.state & 1))) - { - // user wants turn control to become side control - if (fabs(fAxisValue) > joy_sidethreshold->value) - { - cmd->sidemove -= (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; - } - } - else - { - // user wants turn control to be turn control - if (fabs(fAxisValue) > joy_yawthreshold->value) - { - if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) - { - viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * aspeed * cl_yawspeed->value; - } - else - { - viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * speed * 180.0; - } - - } - } - break; - - case AxisLook: - if (in_jlook.state & 1) - { - if (fabs(fAxisValue) > joy_pitchthreshold->value) - { - // pitch movement detected and pitch movement desired by user - if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) - { - viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; - } - else - { - viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * speed * 180.0; - } - V_StopPitchDrift(); - } - else - { - // no pitch movement - // disable pitch return-to-center unless requested by user - // *** this code can be removed when the lookspring bug is fixed - // *** the bug always has the lookspring feature on - if( lookspring->value == 0.0 ) - { - V_StopPitchDrift(); - } - } - } - break; - - default: - break; - } - } - - // bounds check pitch - if (viewangles[PITCH] > cl_pitchdown->value) - viewangles[PITCH] = cl_pitchdown->value; - if (viewangles[PITCH] < -cl_pitchup->value) - viewangles[PITCH] = -cl_pitchup->value; - - gEngfuncs.SetViewAngles( (float *)viewangles ); -} - -/* -=========== -IN_Move -=========== -*/ -void IN_Move ( float frametime, usercmd_t *cmd) -{ - if ( !iMouseInUse && mouseactive ) - { - IN_MouseMove ( frametime, cmd); - } - - IN_JoyMove ( frametime, cmd); -} - -/* -=========== -IN_Init -=========== -*/ -void IN_Init (void) -{ - m_filter = gEngfuncs.pfnRegisterVariable ( "m_filter","0", FCVAR_ARCHIVE ); - sensitivity = gEngfuncs.pfnRegisterVariable ( "sensitivity","3", FCVAR_ARCHIVE ); // user mouse sensitivity setting. - - in_joystick = gEngfuncs.pfnRegisterVariable ( "joystick","0", FCVAR_ARCHIVE ); - joy_name = gEngfuncs.pfnRegisterVariable ( "joyname", "joystick", 0 ); - joy_advanced = gEngfuncs.pfnRegisterVariable ( "joyadvanced", "0", 0 ); - joy_advaxisx = gEngfuncs.pfnRegisterVariable ( "joyadvaxisx", "0", 0 ); - joy_advaxisy = gEngfuncs.pfnRegisterVariable ( "joyadvaxisy", "0", 0 ); - joy_advaxisz = gEngfuncs.pfnRegisterVariable ( "joyadvaxisz", "0", 0 ); - joy_advaxisr = gEngfuncs.pfnRegisterVariable ( "joyadvaxisr", "0", 0 ); - joy_advaxisu = gEngfuncs.pfnRegisterVariable ( "joyadvaxisu", "0", 0 ); - joy_advaxisv = gEngfuncs.pfnRegisterVariable ( "joyadvaxisv", "0", 0 ); - joy_forwardthreshold = gEngfuncs.pfnRegisterVariable ( "joyforwardthreshold", "0.15", 0 ); - joy_sidethreshold = gEngfuncs.pfnRegisterVariable ( "joysidethreshold", "0.15", 0 ); - joy_pitchthreshold = gEngfuncs.pfnRegisterVariable ( "joypitchthreshold", "0.15", 0 ); - joy_yawthreshold = gEngfuncs.pfnRegisterVariable ( "joyyawthreshold", "0.15", 0 ); - joy_forwardsensitivity = gEngfuncs.pfnRegisterVariable ( "joyforwardsensitivity", "-1.0", 0 ); - joy_sidesensitivity = gEngfuncs.pfnRegisterVariable ( "joysidesensitivity", "-1.0", 0 ); - joy_pitchsensitivity = gEngfuncs.pfnRegisterVariable ( "joypitchsensitivity", "1.0", 0 ); - joy_yawsensitivity = gEngfuncs.pfnRegisterVariable ( "joyyawsensitivity", "-1.0", 0 ); - joy_wwhack1 = gEngfuncs.pfnRegisterVariable ( "joywwhack1", "0.0", 0 ); - joy_wwhack2 = gEngfuncs.pfnRegisterVariable ( "joywwhack2", "0.0", 0 ); - - m_customaccel = gEngfuncs.pfnRegisterVariable ( "m_customaccel", "0", FCVAR_ARCHIVE ); - m_customaccel_scale = gEngfuncs.pfnRegisterVariable ( "m_customaccel_scale", "0.04", FCVAR_ARCHIVE ); - m_customaccel_max = gEngfuncs.pfnRegisterVariable ( "m_customaccel_max", "0", FCVAR_ARCHIVE ); - m_customaccel_exponent = gEngfuncs.pfnRegisterVariable ( "m_customaccel_exponent", "1", FCVAR_ARCHIVE ); - - gEngfuncs.pfnAddCommand ("force_centerview", Force_CenterView_f); - gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); - - IN_StartupMouse (); - IN_StartupJoystick (); -} diff --git a/dmc/cl_dll/kbutton.h b/dmc/cl_dll/kbutton.h deleted file mode 100644 index 23cd8ac..0000000 --- a/dmc/cl_dll/kbutton.h +++ /dev/null @@ -1,18 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( KBUTTONH ) -#define KBUTTONH -#pragma once - -typedef struct kbutton_s -{ - int down[2]; // key nums holding it down - int state; // low bit is down state -} kbutton_t; - -#endif // !KBUTTONH \ No newline at end of file diff --git a/dmc/cl_dll/menu.cpp b/dmc/cl_dll/menu.cpp deleted file mode 100644 index 4f2be25..0000000 --- a/dmc/cl_dll/menu.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// menu.cpp -// -// generic menu handler -// -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include -#include "vgui_viewport.h" - -#define MAX_MENU_STRING 512 -char g_szMenuString[MAX_MENU_STRING]; -char g_szPrelocalisedMenuString[MAX_MENU_STRING]; - -int KB_ConvertString( char *in, char **ppout ); - -DECLARE_MESSAGE( m_Menu, ShowMenu ); - -int CHudMenu :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( ShowMenu ); - - InitHUDData(); - - return 1; -} - -void CHudMenu :: InitHUDData( void ) -{ - m_fMenuDisplayed = 0; - m_bitsValidSlots = 0; - Reset(); -} - -void CHudMenu :: Reset( void ) -{ - g_szPrelocalisedMenuString[0] = 0; - m_fWaitingForMore = FALSE; -} - -int CHudMenu :: VidInit( void ) -{ - return 1; -} - - -/*================================= - ParseEscapeToken - - Interprets the given escape token (backslash followed by a letter). The - first character of the token must be a backslash. The second character - specifies the operation to perform: - - \w : White text (this is the default) - \d : Dim (gray) text - \y : Yellow text - \r : Red text - \R : Right-align (just for the remainder of the current line) -=================================*/ - -static int menu_r, menu_g, menu_b, menu_x, menu_ralign; - -static inline const char* ParseEscapeToken( const char* token ) -{ - if ( *token != '\\' ) - return token; - - token++; - - switch ( *token ) - { - case '\0': - return token; - - case 'w': - menu_r = 255; - menu_g = 255; - menu_b = 255; - break; - - case 'd': - menu_r = 100; - menu_g = 100; - menu_b = 100; - break; - - case 'y': - menu_r = 255; - menu_g = 210; - menu_b = 64; - break; - - case 'r': - menu_r = 210; - menu_g = 24; - menu_b = 0; - break; - - case 'R': - menu_x = ScreenWidth/2; - menu_ralign = TRUE; - break; - } - - return ++token; -} - - -int CHudMenu :: Draw( float flTime ) -{ - // check for if menu is set to disappear - if ( m_flShutoffTime > 0 ) - { - if ( m_flShutoffTime <= gHUD.m_flTime ) - { // times up, shutoff - m_fMenuDisplayed = 0; - m_iFlags &= ~HUD_ACTIVE; - return 1; - } - } - - // don't draw the menu if the scoreboard is being shown - if ( gViewPort && gViewPort->IsScoreBoardVisible() ) - return 1; - - // draw the menu, along the left-hand side of the screen - - // count the number of newlines - int nlc = 0; - int i; - for ( i = 0; i < MAX_MENU_STRING && g_szMenuString[i] != '\0'; i++ ) - { - if ( g_szMenuString[i] == '\n' ) - nlc++; - } - - // center it - int y = (ScreenHeight/2) - ((nlc/2)*12) - 40; // make sure it is above the say text - - menu_r = 255; - menu_g = 255; - menu_b = 255; - menu_x = 20; - menu_ralign = FALSE; - - const char* sptr = g_szMenuString; - - while ( *sptr != '\0' ) - { - if ( *sptr == '\\' ) - { - sptr = ParseEscapeToken( sptr ); - } - else if ( *sptr == '\n' ) - { - menu_ralign = FALSE; - menu_x = 20; - y += (12); - - sptr++; - } - else - { - char menubuf[ 80 ]; - const char *ptr = sptr; - while ( *sptr != '\0' && *sptr != '\n' && *sptr != '\\') - { - sptr++; - } - strncpy( menubuf, ptr, V_min( ( sptr - ptr), (int)sizeof( menubuf ) )); - menubuf[ V_min( ( sptr - ptr), (int)(sizeof( menubuf )-1) ) ] = '\0'; - - if ( menu_ralign ) - { - // IMPORTANT: Right-to-left rendered text does not parse escape tokens! - menu_x = gHUD.DrawHudStringReverse( menu_x, y, 0, menubuf, menu_r, menu_g, menu_b ); - } - else - { - menu_x = gHUD.DrawHudString( menu_x, y, 320, menubuf, menu_r, menu_g, menu_b ); - } - } - } - - return 1; -} - -// selects an item from the menu -void CHudMenu :: SelectMenuItem( int menu_item ) -{ - // if menu_item is in a valid slot, send a menuselect command to the server - if ( (menu_item > 0) && (m_bitsValidSlots & (1 << (menu_item-1))) ) - { - char szbuf[32]; - sprintf( szbuf, "menuselect %d\n", menu_item ); - ClientCmd( szbuf ); - - // remove the menu - m_fMenuDisplayed = 0; - m_iFlags &= ~HUD_ACTIVE; - } -} - - -// Message handler for ShowMenu message -// takes four values: -// short: a bitfield of keys that are valid input -// char : the duration, in seconds, the menu should stay up. -1 means is stays until something is chosen. -// byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, FALSE if it's the last string -// string: menu string to display -// if this message is never received, then scores will simply be the combined totals of the players. -int CHudMenu :: MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf ) -{ - char *temp = NULL; - - BEGIN_READ( pbuf, iSize ); - - m_bitsValidSlots = READ_SHORT(); - int DisplayTime = READ_CHAR(); - int NeedMore = READ_BYTE(); - - if ( DisplayTime > 0 ) - m_flShutoffTime = DisplayTime + gHUD.m_flTime; - else - m_flShutoffTime = -1; - - if ( m_bitsValidSlots ) - { - if ( !m_fWaitingForMore ) // this is the start of a new menu - { - strncpy( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING ); - } - else - { // append to the current menu string - strncat( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING - strlen(g_szPrelocalisedMenuString) ); - } - g_szPrelocalisedMenuString[MAX_MENU_STRING-1] = 0; // ensure null termination (strncat/strncpy does not) - - if ( !NeedMore ) - { // we have the whole string, so we can localise it now - strcpy( g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString( g_szPrelocalisedMenuString ) ); - - // Swap in characters - if ( KB_ConvertString( g_szMenuString, &temp ) ) - { - strcpy( g_szMenuString, temp ); - free( temp ); - } - } - - m_fMenuDisplayed = 1; - m_iFlags |= HUD_ACTIVE; - } - else - { - m_fMenuDisplayed = 0; // no valid slots means that the menu should be turned off - m_iFlags &= ~HUD_ACTIVE; - } - - m_fWaitingForMore = NeedMore; - - return 1; -} diff --git a/dmc/cl_dll/message.cpp b/dmc/cl_dll/message.cpp deleted file mode 100644 index b4d8118..0000000 --- a/dmc/cl_dll/message.cpp +++ /dev/null @@ -1,481 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// -// Message.cpp -// -// implementation of CHudMessage class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE( m_Message, HudText ) -DECLARE_MESSAGE( m_Message, GameTitle ) - - -int CHudMessage::Init(void) -{ - HOOK_MESSAGE( HudText ); - HOOK_MESSAGE( GameTitle ); - - gHUD.AddHudElem(this); - - Reset(); - - return 1; -}; - -int CHudMessage::VidInit( void ) -{ - m_HUD_title_half = gHUD.GetSpriteIndex( "title_half" ); - m_HUD_title_life = gHUD.GetSpriteIndex( "title_life" ); - - return 1; -}; - - -void CHudMessage::Reset( void ) -{ - memset( m_pMessages, 0, sizeof( m_pMessages[0] ) * maxHUDMessages ); - memset( m_startTime, 0, sizeof( m_startTime[0] ) * maxHUDMessages ); - - m_gameTitleTime = 0; - m_pGameTitle = NULL; -} - - -float CHudMessage::FadeBlend( float fadein, float fadeout, float hold, float localTime ) -{ - float fadeTime = fadein + hold; - float fadeBlend; - - if ( localTime < 0 ) - return 0; - - if ( localTime < fadein ) - { - fadeBlend = 1 - ((fadein - localTime) / fadein); - } - else if ( localTime > fadeTime ) - { - if ( fadeout > 0 ) - fadeBlend = 1 - ((localTime - fadeTime) / fadeout); - else - fadeBlend = 0; - } - else - fadeBlend = 1; - - return fadeBlend; -} - - -int CHudMessage::XPosition( float x, int width, int totalWidth ) -{ - int xPos; - - if ( x == -1 ) - { - xPos = (ScreenWidth - width) / 2; - } - else - { - if ( x < 0 ) - xPos = (1.0 + x) * ScreenWidth - totalWidth; // Alight right - else - xPos = x * ScreenWidth; - } - - if ( xPos + width > ScreenWidth ) - xPos = ScreenWidth - width; - else if ( xPos < 0 ) - xPos = 0; - - return xPos; -} - - -int CHudMessage::YPosition( float y, int height ) -{ - int yPos; - - if ( y == -1 ) // Centered? - yPos = (ScreenHeight - height) * 0.5; - else - { - // Alight bottom? - if ( y < 0 ) - yPos = (1.0 + y) * ScreenHeight - height; // Alight bottom - else // align top - yPos = y * ScreenHeight; - } - - if ( yPos + height > ScreenHeight ) - yPos = ScreenHeight - height; - else if ( yPos < 0 ) - yPos = 0; - - return yPos; -} - - -void CHudMessage::MessageScanNextChar( void ) -{ - int srcRed, srcGreen, srcBlue, destRed, destGreen, destBlue; - int blend; - - srcRed = m_parms.pMessage->r1; - srcGreen = m_parms.pMessage->g1; - srcBlue = m_parms.pMessage->b1; - blend = 0; // Pure source - destRed = destGreen = destBlue = 0; - - switch( m_parms.pMessage->effect ) - { - // Fade-in / Fade-out - case 0: - case 1: - blend = m_parms.fadeBlend; - break; - - case 2: - m_parms.charTime += m_parms.pMessage->fadein; - if ( m_parms.charTime > m_parms.time ) - { - srcRed = srcGreen = srcBlue = 0; - blend = 0; // pure source - } - else - { - float deltaTime = m_parms.time - m_parms.charTime; - - if ( m_parms.time > m_parms.fadeTime ) - { - blend = m_parms.fadeBlend; - } - else if ( deltaTime > m_parms.pMessage->fxtime ) - blend = 0; // pure dest - else - { - destRed = m_parms.pMessage->r2; - destGreen = m_parms.pMessage->g2; - destBlue = m_parms.pMessage->b2; - blend = 255 - (deltaTime * (1.0/m_parms.pMessage->fxtime) * 255.0 + 0.5); - } - } - break; - } - if ( blend > 255 ) - blend = 255; - else if ( blend < 0 ) - blend = 0; - - m_parms.r = ((srcRed * (255-blend)) + (destRed * blend)) >> 8; - m_parms.g = ((srcGreen * (255-blend)) + (destGreen * blend)) >> 8; - m_parms.b = ((srcBlue * (255-blend)) + (destBlue * blend)) >> 8; - - if ( m_parms.pMessage->effect == 1 && m_parms.charTime != 0 ) - { - if ( m_parms.x >= 0 && m_parms.y >= 0 && (m_parms.x + gHUD.m_scrinfo.charWidths[ m_parms.text ]) <= ScreenWidth ) - TextMessageDrawChar( m_parms.x, m_parms.y, m_parms.text, m_parms.pMessage->r2, m_parms.pMessage->g2, m_parms.pMessage->b2 ); - } -} - - -void CHudMessage::MessageScanStart( void ) -{ - switch( m_parms.pMessage->effect ) - { - // Fade-in / out with flicker - case 1: - case 0: - m_parms.fadeTime = m_parms.pMessage->fadein + m_parms.pMessage->holdtime; - - - if ( m_parms.time < m_parms.pMessage->fadein ) - { - m_parms.fadeBlend = ((m_parms.pMessage->fadein - m_parms.time) * (1.0/m_parms.pMessage->fadein) * 255); - } - else if ( m_parms.time > m_parms.fadeTime ) - { - if ( m_parms.pMessage->fadeout > 0 ) - m_parms.fadeBlend = (((m_parms.time - m_parms.fadeTime) / m_parms.pMessage->fadeout) * 255); - else - m_parms.fadeBlend = 255; // Pure dest (off) - } - else - m_parms.fadeBlend = 0; // Pure source (on) - m_parms.charTime = 0; - - if ( m_parms.pMessage->effect == 1 && (rand()%100) < 10 ) - m_parms.charTime = 1; - break; - - case 2: - m_parms.fadeTime = (m_parms.pMessage->fadein * m_parms.length) + m_parms.pMessage->holdtime; - - if ( m_parms.time > m_parms.fadeTime && m_parms.pMessage->fadeout > 0 ) - m_parms.fadeBlend = (((m_parms.time - m_parms.fadeTime) / m_parms.pMessage->fadeout) * 255); - else - m_parms.fadeBlend = 0; - break; - } -} - - -void CHudMessage::MessageDrawScan( client_textmessage_t *pMessage, float time ) -{ - int i, j, length, width; - const char *pText; - unsigned char line[80]; - - pText = pMessage->pMessage; - // Count lines - m_parms.lines = 1; - m_parms.time = time; - m_parms.pMessage = pMessage; - length = 0; - width = 0; - m_parms.totalWidth = 0; - while ( *pText ) - { - if ( *pText == '\n' ) - { - m_parms.lines++; - if ( width > m_parms.totalWidth ) - m_parms.totalWidth = width; - width = 0; - } - else - width += gHUD.m_scrinfo.charWidths[*pText]; - pText++; - length++; - } - m_parms.length = length; - m_parms.totalHeight = (m_parms.lines * gHUD.m_scrinfo.iCharHeight); - - - m_parms.y = YPosition( pMessage->y, m_parms.totalHeight ); - pText = pMessage->pMessage; - - m_parms.charTime = 0; - - MessageScanStart(); - - for ( i = 0; i < m_parms.lines; i++ ) - { - m_parms.lineLength = 0; - m_parms.width = 0; - while ( *pText && *pText != '\n' ) - { - unsigned char c = *pText; - line[m_parms.lineLength] = c; - m_parms.width += gHUD.m_scrinfo.charWidths[c]; - m_parms.lineLength++; - pText++; - } - pText++; // Skip LF - line[m_parms.lineLength] = 0; - - m_parms.x = XPosition( pMessage->x, m_parms.width, m_parms.totalWidth ); - - for ( j = 0; j < m_parms.lineLength; j++ ) - { - m_parms.text = line[j]; - int next = m_parms.x + gHUD.m_scrinfo.charWidths[ m_parms.text ]; - MessageScanNextChar(); - - if ( m_parms.x >= 0 && m_parms.y >= 0 && next <= ScreenWidth ) - TextMessageDrawChar( m_parms.x, m_parms.y, m_parms.text, m_parms.r, m_parms.g, m_parms.b ); - m_parms.x = next; - } - - m_parms.y += gHUD.m_scrinfo.iCharHeight; - } -} - - -int CHudMessage::Draw( float fTime ) -{ - int i, drawn; - client_textmessage_t *pMessage; - float endTime; - - drawn = 0; - - if ( m_gameTitleTime > 0 ) - { - float localTime = gHUD.m_flTime - m_gameTitleTime; - float brightness; - - // Maybe timer isn't set yet - if ( m_gameTitleTime > gHUD.m_flTime ) - m_gameTitleTime = gHUD.m_flTime; - - if ( localTime > (m_pGameTitle->fadein + m_pGameTitle->holdtime + m_pGameTitle->fadeout) ) - m_gameTitleTime = 0; - else - { - brightness = FadeBlend( m_pGameTitle->fadein, m_pGameTitle->fadeout, m_pGameTitle->holdtime, localTime ); - - int halfWidth = gHUD.GetSpriteRect(m_HUD_title_half).right - gHUD.GetSpriteRect(m_HUD_title_half).left; - int fullWidth = halfWidth + gHUD.GetSpriteRect(m_HUD_title_life).right - gHUD.GetSpriteRect(m_HUD_title_life).left; - int fullHeight = gHUD.GetSpriteRect(m_HUD_title_half).bottom - gHUD.GetSpriteRect(m_HUD_title_half).top; - - int x = XPosition( m_pGameTitle->x, fullWidth, fullWidth ); - int y = YPosition( m_pGameTitle->y, fullHeight ); - - - SPR_Set( gHUD.GetSprite(m_HUD_title_half), brightness * m_pGameTitle->r1, brightness * m_pGameTitle->g1, brightness * m_pGameTitle->b1 ); - SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(m_HUD_title_half) ); - - SPR_Set( gHUD.GetSprite(m_HUD_title_life), brightness * m_pGameTitle->r1, brightness * m_pGameTitle->g1, brightness * m_pGameTitle->b1 ); - SPR_DrawAdditive( 0, x + halfWidth, y, &gHUD.GetSpriteRect(m_HUD_title_life) ); - - drawn = 1; - } - } - // Fixup level transitions - for ( i = 0; i < maxHUDMessages; i++ ) - { - // Assume m_parms.time contains last time - if ( m_pMessages[i] ) - { - pMessage = m_pMessages[i]; - if ( m_startTime[i] > gHUD.m_flTime ) - m_startTime[i] = gHUD.m_flTime + m_parms.time - m_startTime[i] + 0.2; // Server takes 0.2 seconds to spawn, adjust for this - } - } - - for ( i = 0; i < maxHUDMessages; i++ ) - { - if ( m_pMessages[i] ) - { - pMessage = m_pMessages[i]; - - // This is when the message is over - switch( pMessage->effect ) - { - case 0: - case 1: - endTime = m_startTime[i] + pMessage->fadein + pMessage->fadeout + pMessage->holdtime; - break; - - // Fade in is per character in scanning messages - case 2: - endTime = m_startTime[i] + (pMessage->fadein * strlen( pMessage->pMessage )) + pMessage->fadeout + pMessage->holdtime; - break; - } - - if ( fTime <= endTime ) - { - float messageTime = fTime - m_startTime[i]; - - // Draw the message - // effect 0 is fade in/fade out - // effect 1 is flickery credits - // effect 2 is write out (training room) - MessageDrawScan( pMessage, messageTime ); - - drawn++; - } - else - { - // The message is over - m_pMessages[i] = NULL; - } - } - } - - // Remember the time -- to fix up level transitions - m_parms.time = gHUD.m_flTime; - // Don't call until we get another message - if ( !drawn ) - m_iFlags &= ~HUD_ACTIVE; - - return 1; -} - - -void CHudMessage::MessageAdd( const char *pName, float time ) -{ - int i; - - for ( i = 0; i < maxHUDMessages; i++ ) - { - if ( !m_pMessages[i] ) - { - m_pMessages[i] = TextMessageGet( pName ); - m_startTime[i] = time; - return; - } - } -} - - -int CHudMessage::MsgFunc_HudText( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - char *pString = READ_STRING(); - - MessageAdd( pString, gHUD.m_flTime ); - // Remember the time -- to fix up level transitions - m_parms.time = gHUD.m_flTime; - - // Turn on drawing - if ( !(m_iFlags & HUD_ACTIVE) ) - m_iFlags |= HUD_ACTIVE; - - return 1; -} - - -int CHudMessage::MsgFunc_GameTitle( const char *pszName, int iSize, void *pbuf ) -{ - m_pGameTitle = TextMessageGet( "GAMETITLE" ); - if ( m_pGameTitle != NULL ) - { - m_gameTitleTime = gHUD.m_flTime; - - // Turn on drawing - if ( !(m_iFlags & HUD_ACTIVE) ) - m_iFlags |= HUD_ACTIVE; - } - - return 1; -} -void CHudMessage::MessageAdd(client_textmessage_t * newMessage ) -{ - m_parms.time = gHUD.m_flTime; - - // Turn on drawing - if ( !(m_iFlags & HUD_ACTIVE) ) - m_iFlags |= HUD_ACTIVE; - - for ( int i = 0; i < maxHUDMessages; i++ ) - { - if ( !m_pMessages[i] ) - { - m_pMessages[i] = newMessage; - m_startTime[i] = gHUD.m_flTime; - return; - } - } - -} diff --git a/dmc/cl_dll/quake/quake_baseentity.cpp b/dmc/cl_dll/quake/quake_baseentity.cpp deleted file mode 100644 index fb0d394..0000000 --- a/dmc/cl_dll/quake/quake_baseentity.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/*** -* -* 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. -* -****/ - -/* -========================== -This file contains "stubs" of class member implementations so that we can predict certain - weapons client side. From time to time you might find that you need to implement part of the - these functions. If so, cut it from here, paste it in hl_weapons.cpp or somewhere else and - add in the functionality you need. -========================== -*/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "nodes.h" - -// Globals used by game logic -const Vector g_vecZero = Vector( 0, 0, 0 ); -int gmsgWeapPickup = 0; -enginefuncs_t g_engfuncs; -globalvars_t *gpGlobals; - -short g_sModelIndexLaser; - -ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS]; - -void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int flags, int pitch) { } - -// CBaseEntity Stubs -int CBaseEntity :: TakeHealth( float flHealth, int bitsDamageType ) { return 1; } -int CBaseEntity :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) { return 1; } -CBaseEntity *CBaseEntity::GetNextTarget( void ) { return NULL; } -int CBaseEntity::Save( CSave &save ) { return 1; } -int CBaseEntity::Restore( CRestore &restore ) { return 1; } -void CBaseEntity::SetObjectCollisionBox( void ) { } -int CBaseEntity :: Intersects( CBaseEntity *pOther ) { return 0; } -void CBaseEntity :: MakeDormant( void ) { } -int CBaseEntity :: IsDormant( void ) { return 0; } -BOOL CBaseEntity :: IsInWorld( void ) { return TRUE; } -int CBaseEntity::ShouldToggle( USE_TYPE useType, BOOL currentState ) { return 0; } -int CBaseEntity :: DamageDecal( int bitsDamageType ) { return -1; } -CBaseEntity * CBaseEntity::Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) { return NULL; } -void CBaseEntity::SUB_Remove( void ) { } - -// CBaseDelay Stubs -void CBaseDelay :: KeyValue( struct KeyValueData_s * ) { } -int CBaseDelay::Restore( class CRestore & ) { return 1; } -int CBaseDelay::Save( class CSave & ) { return 1; } - -// CBaseAnimating Stubs -int CBaseAnimating::Restore( class CRestore & ) { return 1; } -int CBaseAnimating::Save( class CSave & ) { return 1; } - -// DEBUG Stubs -edict_t *DBG_EntOfVars( const entvars_t *pev ) { return NULL; } -void DBG_AssertFunction(BOOL fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage) { } - -// UTIL_* Stubs -void UTIL_PrecacheOther( const char *szClassname ) { } -void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ) { } -void UTIL_DecalTrace( TraceResult *pTrace, int decalNumber ) { } -void UTIL_GunshotDecalTrace( TraceResult *pTrace, int decalNumber ) { } -void UTIL_MakeVectors( const Vector &vecAngles ) { } -BOOL UTIL_IsValidEntity( edict_t *pent ) { return TRUE; } -void UTIL_SetOrigin( entvars_t *, const Vector &org ) { } -BOOL UTIL_GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) { return TRUE; } -void UTIL_LogPrintf(char *,...) { } -void UTIL_ClientPrintAll( int,char const *,char const *,char const *,char const *,char const *) { } -void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) { } - -// CBaseToggle Stubs -int CBaseToggle::Restore( class CRestore & ) { return 1; } -int CBaseToggle::Save( class CSave & ) { return 1; } -void CBaseToggle :: KeyValue( struct KeyValueData_s * ) { } - -// CGrenade Stubs -void CGrenade::BounceSound( void ) { } -void CGrenade::Explode( Vector, Vector ) { } -void CGrenade::Explode( TraceResult *, int ) { } -void CGrenade::Killed( entvars_t *, int ) { } -void CGrenade::Spawn( void ) { } - -CBaseEntity* CBaseMonster :: CheckTraceHullAttack( float flDist, int iDamage, int iDmgType ) { return NULL; } -void CBaseMonster :: Eat ( float flFullDuration ) { } -BOOL CBaseMonster :: FShouldEat ( void ) { return TRUE; } -void CBaseMonster :: BarnacleVictimBitten ( entvars_t *pevBarnacle ) { } -void CBaseMonster :: BarnacleVictimReleased ( void ) { } -void CBaseMonster :: Listen ( void ) { } -float CBaseMonster :: FLSoundVolume ( CSound *pSound ) { return 0.0; } -BOOL CBaseMonster :: FValidateHintType ( short sHint ) { return FALSE; } -void CBaseMonster :: Look ( int iDistance ) { } -int CBaseMonster :: ISoundMask ( void ) { return 0; } -CSound* CBaseMonster :: PBestSound ( void ) { return NULL; } -CSound* CBaseMonster :: PBestScent ( void ) { return NULL; } -float CBaseAnimating :: StudioFrameAdvance ( float flInterval ) { return 0.0; } -void CBaseMonster :: MonsterThink ( void ) { } -void CBaseMonster :: MonsterUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { } -int CBaseMonster :: IgnoreConditions ( void ) { return 0; } -void CBaseMonster :: RouteClear ( void ) { } -void CBaseMonster :: RouteNew ( void ) { } -BOOL CBaseMonster :: FRouteClear ( void ) { return FALSE; } -BOOL CBaseMonster :: FRefreshRoute ( void ) { return 0; } -BOOL CBaseMonster::MoveToEnemy( Activity movementAct, float waitTime ) { return FALSE; } -BOOL CBaseMonster::MoveToLocation( Activity movementAct, float waitTime, const Vector &goal ) { return FALSE; } -BOOL CBaseMonster::MoveToTarget( Activity movementAct, float waitTime ) { return FALSE; } -BOOL CBaseMonster::MoveToNode( Activity movementAct, float waitTime, const Vector &goal ) { return FALSE; } -int ShouldSimplify( int routeType ) { return TRUE; } -void CBaseMonster :: RouteSimplify( CBaseEntity *pTargetEnt ) { } -BOOL CBaseMonster :: FBecomeProne ( void ) { return TRUE; } -BOOL CBaseMonster :: CheckRangeAttack1 ( float flDot, float flDist ) { return FALSE; } -BOOL CBaseMonster :: CheckRangeAttack2 ( float flDot, float flDist ) { return FALSE; } -BOOL CBaseMonster :: CheckMeleeAttack1 ( float flDot, float flDist ) { return FALSE; } -BOOL CBaseMonster :: CheckMeleeAttack2 ( float flDot, float flDist ) { return FALSE; } -void CBaseMonster :: CheckAttacks ( CBaseEntity *pTarget, float flDist ) { } -BOOL CBaseMonster :: FCanCheckAttacks ( void ) { return FALSE; } -int CBaseMonster :: CheckEnemy ( CBaseEntity *pEnemy ) { return 0; } -void CBaseMonster :: PushEnemy( CBaseEntity *pEnemy, Vector &vecLastKnownPos ) { } -BOOL CBaseMonster :: PopEnemy( ) { return FALSE; } -void CBaseMonster :: SetActivity ( Activity NewActivity ) { } -void CBaseMonster :: SetSequenceByName ( char *szSequence ) { } -int CBaseMonster :: CheckLocalMove ( const Vector &vecStart, const Vector &vecEnd, CBaseEntity *pTarget, float *pflDist ) { return 0; } -float CBaseMonster :: OpenDoorAndWait( entvars_t *pevDoor ) { return 0.0; } -void CBaseMonster :: AdvanceRoute ( float distance ) { } -int CBaseMonster :: RouteClassify( int iMoveFlag ) { return 0; } -BOOL CBaseMonster :: BuildRoute ( const Vector &vecGoal, int iMoveFlag, CBaseEntity *pTarget ) { return FALSE; } -void CBaseMonster :: InsertWaypoint ( Vector vecLocation, int afMoveFlags ) { } -BOOL CBaseMonster :: FTriangulate ( const Vector &vecStart , const Vector &vecEnd, float flDist, CBaseEntity *pTargetEnt, Vector *pApex ) { return FALSE; } -void CBaseMonster :: Move ( float flInterval ) { } -BOOL CBaseMonster:: ShouldAdvanceRoute( float flWaypointDist ) { return FALSE; } -void CBaseMonster::MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval ) { } -void CBaseMonster :: MonsterInit ( void ) { } -void CBaseMonster :: MonsterInitThink ( void ) { } -void CBaseMonster :: StartMonster ( void ) { } -void CBaseMonster :: MovementComplete( void ) { } -int CBaseMonster::TaskIsRunning( void ) { return 0; } -int CBaseMonster::IRelationship ( CBaseEntity *pTarget ) { return 0; } -BOOL CBaseMonster :: FindCover ( Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist ) { return FALSE; } -BOOL CBaseMonster :: BuildNearestRoute ( Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist ) { return FALSE; } -CBaseEntity *CBaseMonster :: BestVisibleEnemy ( void ) { return NULL; } -BOOL CBaseMonster :: FInViewCone ( CBaseEntity *pEntity ) { return FALSE; } -BOOL CBaseMonster :: FInViewCone ( Vector *pOrigin ) { return FALSE; } -BOOL CBaseEntity :: FVisible ( CBaseEntity *pEntity ) { return FALSE; } -BOOL CBaseEntity :: FVisible ( const Vector &vecOrigin ) { return FALSE; } -void CBaseMonster :: MakeIdealYaw( Vector vecTarget ) { } -float CBaseMonster::FlYawDiff ( void ) { return 0.0; } -float CBaseMonster::ChangeYaw ( int yawSpeed ) { return 0; } -float CBaseMonster::VecToYaw ( Vector vecDir ) { return 0.0; } -int CBaseAnimating :: LookupActivity ( int activity ) { return 0; } -int CBaseAnimating :: LookupActivityHeaviest ( int activity ) { return 0; } -void CBaseMonster :: SetEyePosition ( void ) { } -int CBaseAnimating :: LookupSequence ( const char *label ) { return 0; } -void CBaseAnimating :: ResetSequenceInfo ( ) { } -BOOL CBaseAnimating :: GetSequenceFlags( ) { return FALSE; } -void CBaseAnimating :: DispatchAnimEvents ( float flInterval ) { } -void CBaseMonster :: HandleAnimEvent( MonsterEvent_t *pEvent ) { } -float CBaseAnimating :: SetBoneController ( int iController, float flValue ) { return 0.0; } -void CBaseAnimating :: InitBoneControllers ( void ) { } -float CBaseAnimating :: SetBlending ( int iBlender, float flValue ) { return 0; } -void CBaseAnimating :: GetBonePosition ( int iBone, Vector &origin, Vector &angles ) { } -void CBaseAnimating :: GetAttachment ( int iAttachment, Vector &origin, Vector &angles ) { } -int CBaseAnimating :: FindTransition( int iEndingSequence, int iGoalSequence, int *piDir ) { return -1; } -void CBaseAnimating :: GetAutomovement( Vector &origin, Vector &angles, float flInterval ) { } -void CBaseAnimating :: SetBodygroup( int iGroup, int iValue ) { } -int CBaseAnimating :: GetBodygroup( int iGroup ) { return 0; } -Vector CBaseMonster :: GetGunPosition( void ) { return g_vecZero; } -void CBaseEntity::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { } -void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker ) { } -void CBaseEntity :: TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ) { } -void CBaseMonster :: MakeDamageBloodDecal ( int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir ) { } -BOOL CBaseMonster :: FGetNodeRoute ( Vector vecDest ) { return TRUE; } -int CBaseMonster :: FindHintNode ( void ) { return NO_NODE; } -void CBaseMonster::ReportAIState( void ) { } -void CBaseMonster :: KeyValue( KeyValueData *pkvd ) { } -BOOL CBaseMonster :: FCheckAITrigger ( void ) { return FALSE; } -int CBaseMonster :: CanPlaySequence( BOOL fDisregardMonsterState, int interruptLevel ) { return FALSE; } -BOOL CBaseMonster :: FindLateralCover ( const Vector &vecThreat, const Vector &vecViewOffset ) { return FALSE; } -Vector CBaseMonster :: ShootAtEnemy( const Vector &shootOrigin ) { return g_vecZero; } -BOOL CBaseMonster :: FacingIdeal( void ) { return FALSE; } -BOOL CBaseMonster :: FCanActiveIdle ( void ) { return FALSE; } -void CBaseMonster::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ) { } -void CBaseMonster::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ) { } -void CBaseMonster::SentenceStop( void ) { } -void CBaseMonster::CorpseFallThink( void ) { } -void CBaseMonster :: MonsterInitDead( void ) { } -BOOL CBaseMonster :: BBoxFlat ( void ) { return TRUE; } -BOOL CBaseMonster :: GetEnemy ( void ) { return FALSE; } -void CBaseMonster :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { } -CBaseEntity* CBaseMonster :: DropItem ( char *pszItemName, const Vector &vecPos, const Vector &vecAng ) { return NULL; } -BOOL CBaseMonster :: ShouldFadeOnDeath( void ) { return FALSE; } -void CBaseMonster :: RadiusDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) { } -void CBaseMonster :: RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) { } -void CBaseMonster::FadeMonster( void ) { } -void CBaseMonster :: GibMonster( void ) { } -BOOL CBaseMonster :: HasHumanGibs( void ) { return FALSE; } -BOOL CBaseMonster :: HasAlienGibs( void ) { return FALSE; } -Activity CBaseMonster :: GetDeathActivity ( void ) { return ACT_DIE_HEADSHOT; } -MONSTERSTATE CBaseMonster :: GetIdealState ( void ) { return MONSTERSTATE_ALERT; } -Schedule_t* CBaseMonster :: GetScheduleOfType ( int Type ) { return NULL; } -Schedule_t *CBaseMonster :: GetSchedule ( void ) { return NULL; } -void CBaseMonster :: RunTask ( Task_t *pTask ) { } -void CBaseMonster :: StartTask ( Task_t *pTask ) { } -Schedule_t *CBaseMonster::ScheduleFromName( const char *pName ) { return NULL;} -void CBaseMonster::BecomeDead( void ) {} -void CBaseMonster :: RunAI ( void ) {} -void CBaseMonster :: Killed( entvars_t *pevAttacker, int iGib ) {} -int CBaseMonster :: TakeHealth (float flHealth, int bitsDamageType) { return 0; } -int CBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { return 0; } -int CBaseMonster::Restore( class CRestore & ) { return 1; } -int CBaseMonster::Save( class CSave & ) { return 1; } - -int TrainSpeed(int iSpeed, int iMax) { return 0; } -void CBasePlayer::CheckAmmo(void) { } -void CBasePlayer :: DeathSound( void ) { } -int CBasePlayer :: TakeHealth( float flHealth, int bitsDamageType ) { return 0; } -void CBasePlayer :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { } -int CBasePlayer :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { return 0; } -void CBasePlayer::RemoveAllItems( BOOL removeSuit ) { } -void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim ) { } -void CBasePlayer::WaterMove() { } -BOOL CBasePlayer::IsOnLadder( void ) { return FALSE; } -void CBasePlayer::PlayerDeathThink(void) { } -void CBasePlayer::StartDeathCam( void ) { } -void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) { } -void CBasePlayer::PlayerUse ( void ) { } -void CBasePlayer::Jump() { } -void CBasePlayer::Duck( ) { } -int CBasePlayer::Classify ( void ) { return 0; } -void CBasePlayer :: PlayStepSound(int step, float fvol) { } -void CBasePlayer :: UpdateStepSound( void ) { } -void CBasePlayer::PreThink(void) { } -void CBasePlayer::CheckTimeBasedDamage() { } -void CBasePlayer :: UpdateGeigerCounter( void ) { } -void CBasePlayer::CheckSuitUpdate() { } -void CBasePlayer::SetSuitUpdate(char *name, int fgroup, int iNoRepeatTime) { } -void CBasePlayer::PostThink() { } -int CBasePlayer::Save( CSave &save ) { return 0; } -void CBasePlayer::RenewItems(void) { } -int CBasePlayer::Restore( CRestore &restore ) { return 0; } -void CBasePlayer::SelectNextItem( int iItem ) { } -BOOL CBasePlayer::HasWeapons( void ) { return FALSE; } -void CBasePlayer::SelectPrevItem( int iItem ) { } -CBaseEntity *FindEntityForward( CBaseEntity *pMe ) { return NULL; } -BOOL CBasePlayer :: FlashlightIsOn( void ) { return FALSE; } -void CBasePlayer :: FlashlightTurnOn( void ) { } -void CBasePlayer :: FlashlightTurnOff( void ) { } -void CBasePlayer :: ForceClientDllUpdate( void ) { } -void CBasePlayer::ImpulseCommands( ) { } -void CBasePlayer::CheatImpulseCommands( int iImpulse ) { } -int CBasePlayer::AddPlayerItem( CBasePlayerItem *pItem ) { return FALSE; } -int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem ) { return FALSE; } -void CBasePlayer::ItemPreFrame() { } -void CBasePlayer::ItemPostFrame() { } -int CBasePlayer::AmmoInventory( int iAmmoIndex ) { return -1; } -int CBasePlayer::GetAmmoIndex(const char *psz) { return -1; } -void CBasePlayer::SendAmmoUpdate(void) { } -void CBasePlayer :: UpdateClientData( void ) { } -BOOL CBasePlayer :: FBecomeProne ( void ) { return TRUE; } -void CBasePlayer :: BarnacleVictimBitten ( entvars_t *pevBarnacle ) { } -void CBasePlayer :: BarnacleVictimReleased ( void ) { } -int CBasePlayer :: Illumination( void ) { return 0; } -void CBasePlayer :: EnableControl(BOOL fControl) { } -Vector CBasePlayer :: GetAutoaimVector( float flDelta ) { return g_vecZero; } -Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta ) { return g_vecZero; } -void CBasePlayer :: ResetAutoaim( ) { } -void CBasePlayer :: SetCustomDecalFrames( int nFrames ) { } -int CBasePlayer :: GetCustomDecalFrames( void ) { return -1; } -void CBasePlayer::DropPlayerItem ( char *pszItemName ) { } -BOOL CBasePlayer::HasPlayerItem( CBasePlayerItem *pCheckItem ) { return FALSE; } -BOOL CBasePlayer :: SwitchWeapon( CBasePlayerItem *pWeapon ) { return FALSE; } -Vector CBasePlayer :: GetGunPosition( void ) { return g_vecZero; } -const char *CBasePlayer::TeamID( void ) { return ""; } -int CBasePlayer :: GiveAmmo( int iCount, char *szName, int iMax ) { return 0; } -void CBasePlayer::AddPoints( int score, BOOL bAllowNegativeScore ) { } -void CBasePlayer::AddPointsToTeam( int score, BOOL bAllowNegativeScore ) { } - -void ClearMultiDamage(void) { } -void ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker ) { } -void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType) { } -void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage) { } -int DamageDecal( CBaseEntity *pEntity, int bitsDamageType ) { return 0; } -void DecalGunshot( TraceResult *pTrace, int iBulletType ) { } -void EjectBrass ( const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype ) { } -void AddAmmoNameToAmmoRegistry( const char *szAmmoname ) { } -int CBasePlayerItem::Restore( class CRestore & ) { return 1; } -int CBasePlayerItem::Save( class CSave & ) { return 1; } -int CBasePlayerWeapon::Restore( class CRestore & ) { return 1; } -int CBasePlayerWeapon::Save( class CSave & ) { return 1; } -void CBasePlayerItem :: SetObjectCollisionBox( void ) { } -void CBasePlayerItem :: FallInit( void ) { } -void CBasePlayerItem::FallThink ( void ) { } -void CBasePlayerItem::Materialize( void ) { } -void CBasePlayerItem::AttemptToMaterialize( void ) { } -void CBasePlayerItem :: CheckRespawn ( void ) { } -CBaseEntity* CBasePlayerItem::Respawn( void ) { return NULL; } -void CBasePlayerItem::DefaultTouch( CBaseEntity *pOther ) { } -void CBasePlayerItem::DestroyItem( void ) { } -int CBasePlayerItem::AddToPlayer( CBasePlayer *pPlayer ) { return TRUE; } -void CBasePlayerItem::Drop( void ) { } -void CBasePlayerItem::Kill( void ) { } -void CBasePlayerItem::Holster( int skiplocal ) { } -void CBasePlayerItem::AttachToPlayer ( CBasePlayer *pPlayer ) { } -int CBasePlayerWeapon::AddDuplicate( CBasePlayerItem *pOriginal ) { return 0; } -int CBasePlayerWeapon::AddToPlayer( CBasePlayer *pPlayer ) { return FALSE; } -int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer ) { return 0; } -BOOL CBasePlayerWeapon :: AddPrimaryAmmo( int iCount, char *szName, int iMaxClip, int iMaxCarry ) { return TRUE; } -BOOL CBasePlayerWeapon :: AddSecondaryAmmo( int iCount, char *szName, int iMax ) { return TRUE; } -BOOL CBasePlayerWeapon :: IsUseable( void ) { return TRUE; } -int CBasePlayerWeapon::PrimaryAmmoIndex( void ) { return -1; } -int CBasePlayerWeapon::SecondaryAmmoIndex( void ) { return -1; } -void CBasePlayerAmmo::Spawn( void ) { } -CBaseEntity* CBasePlayerAmmo::Respawn( void ) { return this; } -void CBasePlayerAmmo::Materialize( void ) { } -void CBasePlayerAmmo :: DefaultTouch( CBaseEntity *pOther ) { } -int CBasePlayerWeapon::ExtractAmmo( CBasePlayerWeapon *pWeapon ) { return 0; } -int CBasePlayerWeapon::ExtractClipAmmo( CBasePlayerWeapon *pWeapon ) { return 0; } -void CBasePlayerWeapon::RetireWeapon( void ) { } \ No newline at end of file diff --git a/dmc/cl_dll/quake/quake_events.cpp b/dmc/cl_dll/quake/quake_events.cpp deleted file mode 100644 index 6925bbf..0000000 --- a/dmc/cl_dll/quake/quake_events.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "../hud.h" -#include "../cl_util.h" -#include "event_api.h" - -extern "C" -{ -// Deathmatch Classic -void EV_FireShotGunSingle( struct event_args_s *args ); -void EV_FireShotGunDouble( struct event_args_s *args ); -void EV_FireAxe( struct event_args_s *args ); -void EV_FireAxeSwing( struct event_args_s *args ); -void EV_FireRocket( struct event_args_s *args ); -void EV_FireLightning( struct event_args_s *args ); -void EV_FireSpike( struct event_args_s *args ); -void EV_FireSuperSpike( struct event_args_s *args ); -void EV_FireGrenade( struct event_args_s *args ); -void EV_Gibbed (struct event_args_s *args ); -void EV_Teleport (struct event_args_s *args ); -void EV_Trail (struct event_args_s *args ); -void EV_Explosion (struct event_args_s *args ); -void EV_PlayerPowerup ( struct event_args_s *args ); - -void EV_DMC_DoorGoUp( struct event_args_s *args ); -void EV_DMC_DoorGoDown( struct event_args_s *args ); -void EV_DMC_DoorHitTop( struct event_args_s *args ); -void EV_DMC_DoorHitBottom( struct event_args_s *args ); - -// HLDM -void EV_TrainPitchAdjust( struct event_args_s *args ); -} - -/* -====================== -Game_HookEvents - -Associate script file name with callback functions. Callback's must be extern "C" so - the engine doesn't get confused about name mangling stuff. Note that the format is - always the same. Of course, a clever mod team could actually embed parameters, behavior - into the actual .sc files and create a .sc file parser and hook their functionality through - that.. i.e., a scripting system. - -That was what we were going to do, but we ran out of time...oh well. -====================== -*/ -void Game_HookEvents( void ) -{ - gEngfuncs.pfnHookEvent( "events/shotgun1.sc", EV_FireShotGunSingle ); - gEngfuncs.pfnHookEvent( "events/shotgun2.sc", EV_FireShotGunDouble ); - gEngfuncs.pfnHookEvent( "events/axe.sc", EV_FireAxe ); - gEngfuncs.pfnHookEvent( "events/axeswing.sc", EV_FireAxeSwing ); - gEngfuncs.pfnHookEvent( "events/rocket.sc", EV_FireRocket ); - gEngfuncs.pfnHookEvent( "events/lightning.sc", EV_FireLightning ); - gEngfuncs.pfnHookEvent( "events/grenade.sc", EV_FireGrenade ); - gEngfuncs.pfnHookEvent( "events/spike.sc", EV_FireSpike ); - gEngfuncs.pfnHookEvent( "events/superspike.sc", EV_FireSuperSpike ); - gEngfuncs.pfnHookEvent( "events/gibs.sc", EV_Gibbed ); - gEngfuncs.pfnHookEvent( "events/teleport.sc", EV_Teleport ); - gEngfuncs.pfnHookEvent( "events/trail.sc", EV_Trail ); - gEngfuncs.pfnHookEvent( "events/explosion.sc", EV_Explosion ); - - gEngfuncs.pfnHookEvent( "events/powerup.sc", EV_PlayerPowerup ); - - gEngfuncs.pfnHookEvent( "events/door/doorgoup.sc", EV_DMC_DoorGoUp ); - gEngfuncs.pfnHookEvent( "events/door/doorgodown.sc", EV_DMC_DoorGoDown ); - gEngfuncs.pfnHookEvent( "events/door/doorhittop.sc", EV_DMC_DoorHitTop ); - gEngfuncs.pfnHookEvent( "events/door/doorhitbottom.sc", EV_DMC_DoorHitBottom ); - - gEngfuncs.pfnHookEvent( "events/train.sc", EV_TrainPitchAdjust ); -} diff --git a/dmc/cl_dll/quake/quake_objects.cpp b/dmc/cl_dll/quake/quake_objects.cpp deleted file mode 100644 index 68c0a82..0000000 --- a/dmc/cl_dll/quake/quake_objects.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "../hud.h" -#include "../cl_util.h" -#include "../demo.h" - -#include "demo_api.h" -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" - -#include "pm_defs.h" -#include "event_api.h" -#include "entity_types.h" -#include "r_efx.h" - - -extern BEAM *pBeam; -void HUD_GetLastOrg( float *org ); - -void UpdateBeams ( void ) -{ - vec3_t forward, vecSrc, vecEnd, origin, angles, right, up; - vec3_t view_ofs; - pmtrace_t tr; - cl_entity_t *pthisplayer = gEngfuncs.GetLocalPlayer(); - int idx = pthisplayer->index; - - // Get our exact viewangles from engine - gEngfuncs.GetViewAngles( (float *)angles ); - - // Determine our last predicted origin - HUD_GetLastOrg( (float *)&origin ); - - AngleVectors( angles, forward, right, up ); - - VectorCopy( origin, vecSrc ); - - VectorMA( vecSrc, 2048, forward, vecEnd ); - - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( idx - 1 ); - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - gEngfuncs.pEventAPI->EV_PlayerTrace( vecSrc, vecEnd, PM_STUDIO_BOX, -1, &tr ); - - gEngfuncs.pEventAPI->EV_PopPMStates(); - - pBeam->target = tr.endpos; - pBeam->die = gEngfuncs.GetClientTime() + 0.1; // We keep it alive just a little bit forward in the future, just in case. -} - -/* -===================== -Game_AddObjects - -Add game specific, client-side objects here -===================== -*/ -void Game_AddObjects( void ) -{ - if ( pBeam ) - UpdateBeams(); -} \ No newline at end of file diff --git a/dmc/cl_dll/quake/quake_weapons.cpp b/dmc/cl_dll/quake/quake_weapons.cpp deleted file mode 100644 index c8952b6..0000000 --- a/dmc/cl_dll/quake/quake_weapons.cpp +++ /dev/null @@ -1,988 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "weapons.h" -#include "nodes.h" -#include "player.h" - -#include "usercmd.h" -#include "entity_state.h" -#include "demo_api.h" -#include "pm_defs.h" -#include "event_api.h" -#include "r_efx.h" - -#include "../hud_iface.h" -#include "../com_weapons.h" -#include "../demo.h" - -#include "quake_gun.h" -#include "../DMC_Teleporters.h" - -extern globalvars_t *gpGlobals; - -// Pool of client side entities/entvars_t -static entvars_t ev[ 32 ]; -static int num_ents = 0; - -// The entity we'll use to represent the local client -static CBasePlayer player; - -// Local version of game .dll global variables ( time, etc. ) -static globalvars_t Globals; - -static CBasePlayerWeapon *g_pWpns[ 32 ]; -extern int iCarriedWeapons; -int g_iWaterLevel; -// HLDM Weapon placeholder entities. -CQuakeGun g_QuakeGun; - -extern BEAM *pBeam; -/* -====================== -AlertMessage - -Print debug messages to console -====================== -*/ -void AlertMessage( ALERT_TYPE atype, const char *szFmt, ... ) -{ - va_list argptr; - static char string[1024]; - - va_start (argptr, szFmt); - vsprintf (string, szFmt,argptr); - va_end (argptr); - - gEngfuncs.Con_Printf( "cl: " ); - gEngfuncs.Con_Printf( string ); -} - -/* -===================== -HUD_PrepEntity - -Links the raw entity to an entvars_s holder. If a player is passed in as the owner, then -we set up the m_pPlayer field. -===================== -*/ -void HUD_PrepEntity( CBaseEntity *pEntity, CBasePlayer *pWeaponOwner ) -{ - memset( &ev[ num_ents ], 0, sizeof( entvars_t ) ); - pEntity->pev = &ev[ num_ents++ ]; - - pEntity->Precache(); - pEntity->Spawn(); - - if ( pWeaponOwner ) - { - ItemInfo info; - - ((CBasePlayerWeapon *)pEntity)->m_pPlayer = pWeaponOwner; - - ((CBasePlayerWeapon *)pEntity)->GetItemInfo( &info ); - - g_pWpns[ info.iId ] = (CBasePlayerWeapon *)pEntity; - } -} - -CQuakeRocket *CQuakeRocket::CreateRocket( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner ) -{ - return NULL; -} - -CQuakeRocket *CQuakeRocket::CreateGrenade( Vector vecOrigin, Vector vecVelocity, CBaseEntity *pOwner ) -{ - return NULL; -} - -CQuakeNail *CQuakeNail::CreateSuperNail( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner ) -{ - return NULL; -} - -CQuakeNail *CQuakeNail::CreateNail( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner ) -{ - return NULL; -} - -void CBasePlayer :: Precache( void ) -{ - m_usShotgunSingle = PRECACHE_EVENT( 1, "events/shotgun1.sc" ); - m_usShotgunDouble = PRECACHE_EVENT( 1, "events/shotgun2.sc" ); - m_usAxe = PRECACHE_EVENT( 1, "events/axe.sc" ); - m_usAxeSwing = PRECACHE_EVENT( 1, "events/axeswing.sc" ); - m_usRocket = PRECACHE_EVENT( 1, "events/rocket.sc" ); - m_usGrenade = PRECACHE_EVENT( 1, "events/grenade.sc" ); - m_usLightning = PRECACHE_EVENT( 1, "events/lightning.sc" ); - m_usSpike = PRECACHE_EVENT( 1, "events/spike.sc" ); - m_usSuperSpike = PRECACHE_EVENT( 1, "events/superspike.sc" ); -} - -/* -===================== -CBaseEntity :: Killed - -If weapons code "kills" an entity, just set its effects to EF_NODRAW -===================== -*/ -void CBaseEntity :: Killed( entvars_t *pevAttacker, int iGib ) -{ - pev->effects |= EF_NODRAW; -} - -/* -===================== -CBasePlayerWeapon :: DefaultReload -===================== -*/ -BOOL CBasePlayerWeapon :: DefaultReload( int iClipSize, int iAnim, float fDelay ) -{ - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + fDelay; - - //!!UNDONE -- reload sound goes here !!! - SendWeaponAnim( iAnim ); - - m_fInReload = TRUE; - - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3; - return TRUE; -} - -/* -===================== -CBasePlayerWeapon :: CanDeploy -===================== -*/ -BOOL CBasePlayerWeapon :: CanDeploy( void ) -{ - BOOL bHasAmmo = 0; - - if ( !pszAmmo1() ) - { - // this weapon doesn't use ammo, can always deploy. - return TRUE; - } - - if ( pszAmmo1() ) - { - bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0); - } - if ( pszAmmo2() ) - { - bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] != 0); - } - if (m_iClip > 0) - { - bHasAmmo |= 1; - } - if (!bHasAmmo) - { - return FALSE; - } - - return TRUE; -} - -/* -===================== -CBasePlayerWeapon :: DefaultDeploy - -===================== -*/ -BOOL CBasePlayerWeapon :: DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal ) -{ - if ( !CanDeploy() ) - return FALSE; - - gEngfuncs.CL_LoadModel( szViewModel, &m_pPlayer->pev->viewmodel ); - - SendWeaponAnim( iAnim ); - - m_bPlayedIdleAnim = FALSE; - - m_pPlayer->m_flNextAttack = 0.5; - m_flTimeWeaponIdle = 1.0; - return TRUE; -} - -/* -===================== -CBasePlayerWeapon :: PlayEmptySound - -===================== -*/ -BOOL CBasePlayerWeapon :: PlayEmptySound( void ) -{ - if (m_iPlayEmptySound) - { - HUD_PlaySound( "weapons/357_cock1.wav", 0.8 ); - m_iPlayEmptySound = 0; - return 0; - } - return 0; -} - -/* -===================== -CBasePlayerWeapon :: ResetEmptySound - -===================== -*/ -void CBasePlayerWeapon :: ResetEmptySound( void ) -{ - m_iPlayEmptySound = 1; -} - -/* -===================== -CBasePlayerWeapon::Holster - -Put away weapon -===================== -*/ -void CBasePlayerWeapon::Holster( int skiplocal /* = 0 */ ) -{ - m_fInReload = FALSE; // cancel any reload in progress. - m_pPlayer->pev->viewmodel = 0; -} - -/* -===================== -CBasePlayerWeapon::SendWeaponAnim - -Animate weapon model -===================== -*/ -void CBasePlayerWeapon::SendWeaponAnim( int iAnim, int skiplocal ) -{ - m_pPlayer->pev->weaponanim = iAnim; - - int body = 0; - - HUD_SendWeaponAnim( iAnim, body, 0 ); -} - -/* -===================== -CBasePlayerWeapon::ItemPostFrame - -Handles weapon firing, reloading, etc. -===================== -*/ -void CBasePlayerWeapon::ItemPostFrame( void ) -{ - if ((m_fInReload) && (m_pPlayer->m_flNextAttack <= 0.0)) - { -#if 0 // FIXME, need ammo on client to make this work right - // complete the reload. - int j = V_min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); - - // Add them to the clip - m_iClip += j; - m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j; -#else - m_iClip += 10; -#endif - m_fInReload = FALSE; - } - - if ((m_pPlayer->pev->button & IN_ATTACK2) && (m_flNextSecondaryAttack <= 0.0)) - { - if ( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] ) - { - m_fFireOnEmpty = TRUE; - } - - SecondaryAttack(); - m_pPlayer->pev->button &= ~IN_ATTACK2; - } - else if ((m_pPlayer->pev->button & IN_ATTACK) && (m_flNextPrimaryAttack <= 0.0)) - { - if ( (m_iClip == 0 && pszAmmo1()) || (iMaxClip() == -1 && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] ) ) - { - m_fFireOnEmpty = TRUE; - } - - PrimaryAttack(); - } - else if ( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload ) - { - // reload when reload is pressed, or if no buttons are down and weapon is empty. - Reload(); - } - else if ( !(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2) ) ) - { - // no fire buttons down - - m_fFireOnEmpty = FALSE; - - if ( !m_bPlayedIdleAnim ) - { - m_bPlayedIdleAnim = TRUE; - - if ( m_pPlayer->m_iQuakeWeapon == IT_LIGHTNING ) - PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_pPlayer->m_usLightning, 0, (float *)&m_pPlayer->pev->origin, (float *)&m_pPlayer->pev->angles, 0.0, 0.0, 0, 1, 0, 0 ); - } - - WeaponIdle( ); - return; - } - - // catch all - if ( ShouldWeaponIdle() ) - { - WeaponIdle(); - } -} - -/* -===================== -CBasePlayer::SelectItem - - Switch weapons -===================== -*/ -void CBasePlayer::SelectItem(const char *pstr) -{ - if (!pstr) - return; - - CBasePlayerItem *pItem = NULL; - - if (!pItem) - return; - - - if (pItem == m_pActiveItem) - return; - - if (m_pActiveItem) - m_pActiveItem->Holster( ); - - m_pLastItem = m_pActiveItem; - m_pActiveItem = pItem; - - if (m_pActiveItem) - { - m_pActiveItem->Deploy( ); - } -} - -/* -===================== -CBasePlayer::SelectLastItem - -===================== -*/ -void CBasePlayer::SelectLastItem(void) -{ - if (!m_pLastItem) - { - return; - } - - if ( m_pActiveItem && !m_pActiveItem->CanHolster() ) - { - return; - } - - if (m_pActiveItem) - m_pActiveItem->Holster( ); - - CBasePlayerItem *pTemp = m_pActiveItem; - m_pActiveItem = m_pLastItem; - m_pLastItem = pTemp; - m_pActiveItem->Deploy( ); -} - -/* -===================== -CBasePlayer::Killed - -===================== -*/ -void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib ) -{ - if ( m_iQuakeWeapon == IT_LIGHTNING ) - { - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usLightning, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, 0, 1, 0, 0 ); - } - - // Holster weapon immediately, to allow it to cleanup - if (m_pActiveItem) - m_pActiveItem->Holster( ); -} - -/* -===================== -CBasePlayer::Spawn - -===================== -*/ -void CBasePlayer::Spawn( void ) -{ - if (m_pActiveItem) - m_pActiveItem->Deploy( ); -} - -BOOL CQuakeGun::Deploy( ) -{ - gEngfuncs.CL_LoadModel( "models/v_axe.mdl", &m_pPlayer->pev->viewmodel ); - strcpy( m_pPlayer->m_szAnimExtention, "onehanded" ); - return TRUE; -} - -int HUD_GetModelIndex( char *modelname ) -{ - int retval = 0; - gEngfuncs.CL_LoadModel( modelname, &retval ); - return retval; -} - -/* -===================== -UTIL_TraceLine - -Don't actually trace, but act like the trace didn't hit anything. -===================== -*/ -void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr ) -{ - memset( ptr, 0, sizeof( *ptr ) ); - ptr->flFraction = 1.0; -} - -/* -===================== -UTIL_ParticleBox - -For debugging, draw a box around a player made out of particles -===================== -*/ -void UTIL_ParticleBox( CBasePlayer *player, float *mins, float *maxs, float life, unsigned char r, unsigned char g, unsigned char b ) -{ - int i; - vec3_t mmin, mmax; - - for ( i = 0; i < 3; i++ ) - { - mmin[ i ] = player->pev->origin[ i ] + mins[ i ]; - mmax[ i ] = player->pev->origin[ i ] + maxs[ i ]; - } - - gEngfuncs.pEfxAPI->R_ParticleBox( (float *)&mmin, (float *)&mmax, 5.0, 0, 255, 0 ); -} - -/* -===================== -UTIL_ParticleBoxes - -For debugging, draw boxes for other collidable players -===================== -*/ -void UTIL_ParticleBoxes( void ) -{ - int idx; - physent_t *pe; - cl_entity_t *player; - vec3_t mins, maxs; - - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - player = gEngfuncs.GetLocalPlayer(); - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( player->index - 1 ); - - for ( idx = 1; idx < 100; idx++ ) - { - pe = gEngfuncs.pEventAPI->EV_GetPhysent( idx ); - if ( !pe ) - break; - - if ( pe->info >= 1 && pe->info <= gEngfuncs.GetMaxClients() ) - { - mins = pe->origin + pe->mins; - maxs = pe->origin + pe->maxs; - - gEngfuncs.pEfxAPI->R_ParticleBox( (float *)&mins, (float *)&maxs, 0, 0, 255, 2.0 ); - } - } - - gEngfuncs.pEventAPI->EV_PopPMStates(); -} - -/* -===================== -UTIL_ParticleLine - -For debugging, draw a line made out of particles -===================== -*/ -void UTIL_ParticleLine( CBasePlayer *player, float *start, float *end, float life, unsigned char r, unsigned char g, unsigned char b ) -{ - gEngfuncs.pEfxAPI->R_ParticleLine( start, end, r, g, b, life ); -} - -/* -===================== -CBasePlayerWeapon::PrintState - -For debugging, print out state variables to log file -===================== -*/ -void CBasePlayerWeapon::PrintState( void ) -{ - COM_Log( "c:\\hl.log", "%.4f ", gpGlobals->time ); - COM_Log( "c:\\hl.log", "%.4f ", m_pPlayer->m_flNextAttack ); - COM_Log( "c:\\hl.log", "%.4f ", m_flNextPrimaryAttack ); - COM_Log( "c:\\hl.log", "%.4f ", m_flTimeWeaponIdle - gpGlobals->time); - COM_Log( "c:\\hl.log", "%i ", m_iClip ); -} - -vec3_t previousorigin; - -/* -===================== -HUD_GetLastOrg - -Retruns the last position that we stored for egon beam endpoint. -===================== -*/ -void HUD_GetLastOrg( float *org ) -{ - int i; - - // Return last origin - for ( i = 0; i < 3; i++ ) - { - org[i] = previousorigin[i]; - } -} - -/* -===================== -HUD_SetLastOrg - -Remember our exact predicted origin so we can draw the egon to the right position. -===================== -*/ -void HUD_SetLastOrg( void ) -{ - int i; - - // Offset final origin by view_offset - for ( i = 0; i < 3; i++ ) - { - previousorigin[i] = g_finalstate->playerstate.origin[i] + g_finalstate->client.view_ofs[ i ]; - } -} - -/* -===================== -HUD_InitClientWeapons - -Set up weapons, player and functions needed to run weapons code client-side. -===================== -*/ -void HUD_InitClientWeapons( void ) -{ - static int initialized = 0; - if ( initialized ) - return; - - initialized = 1; - - // Set up pointer ( dummy object ) - gpGlobals = &Globals; - - // Fill in current time ( probably not needed ) - gpGlobals->time = gEngfuncs.GetClientTime(); - - // Fake functions - g_engfuncs.pfnPrecacheModel = stub_PrecacheModel; - g_engfuncs.pfnPrecacheSound = stub_PrecacheSound; - g_engfuncs.pfnPrecacheEvent = stub_PrecacheEvent; - g_engfuncs.pfnNameForFunction = stub_NameForFunction; - g_engfuncs.pfnSetModel = stub_SetModel; - g_engfuncs.pfnSetClientMaxspeed = HUD_SetMaxSpeed; - - // Handled locally - g_engfuncs.pfnPlaybackEvent = HUD_PlaybackEvent; - g_engfuncs.pfnAlertMessage = AlertMessage; - - // Pass through to engine - g_engfuncs.pfnPrecacheEvent = gEngfuncs.pfnPrecacheEvent; - g_engfuncs.pfnRandomFloat = gEngfuncs.pfnRandomFloat; - g_engfuncs.pfnRandomLong = gEngfuncs.pfnRandomLong; - - // Allocate a slot for the local player - HUD_PrepEntity( &player , NULL ); - - // Allocate slot(s) for each weapon that we are going to be predicting - HUD_PrepEntity( &g_QuakeGun , &player ); -} - -int Quake_NumForWeaponItem( int quakeitem ) -{ - int retval = 1; - switch ( quakeitem ) - { - default: - case IT_AXE: - retval = 1; - break; - case IT_SHOTGUN: - retval = 2; - break; - case IT_SUPER_SHOTGUN: - retval = 3; - break; - case IT_NAILGUN: - retval = 4; - break; - case IT_SUPER_NAILGUN: - retval = 5; - break; - case IT_GRENADE_LAUNCHER: - retval = 6; - break; - case IT_ROCKET_LAUNCHER: - retval = 7; - break; - - case IT_LIGHTNING: - retval = 8; - break; - } - - return retval; -} - -/* -===================== -HUD_WeaponsPostThink - -Run Weapon firing code on client -===================== -*/ -void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cmd, double time, unsigned int random_seed ) -{ - int i; - int buttonsChanged; - CBasePlayerWeapon *pWeapon = NULL; - CBasePlayerWeapon *pCurrent; - weapon_data_t nulldata, *pfrom, *pto; - static int lasthealth; - - memset( &nulldata, 0, sizeof( nulldata ) ); - - HUD_InitClientWeapons(); - - // Get current clock - gpGlobals->time = time; - - // Fill in data based on selected weapon - // FIXME, make this a method in each weapon? where you pass in an entity_state_t *? - switch ( from->client.m_iId ) - { - case WEAPON_GLOCK: - pWeapon = &g_QuakeGun; - break; - } - - // Store pointer to our destination entity_state_t so we can get our origin, etc. from it - // for setting up events on the client - g_finalstate = to; - - // If we are running events/etc. go ahead and see if we - // managed to die between last frame and this one - // If so, run the appropriate player killed or spawn function - if ( g_runfuncs ) - { - if ( to->client.health <= 0 && lasthealth > 0 ) - { - player.Killed( NULL, 0 ); - } - else if ( to->client.health > 0 && lasthealth <= 0 ) - { - player.Spawn(); - } - - lasthealth = to->client.health; - } - - // We are not predicting the current weapon, just bow out here. - if ( !pWeapon ) - return; - - gpGlobals->deathmatch = from->client.iuser4; - - for ( i = 0; i < 32; i++ ) - { - pCurrent = g_pWpns[ i ]; - if ( !pCurrent ) - { - continue; - } - - pfrom = &from->weapondata[ i ]; - - pCurrent->m_fInReload = pfrom->m_fInReload; - pCurrent->m_iClip = pfrom->m_iClip; - pCurrent->m_flNextPrimaryAttack = pfrom->m_flNextPrimaryAttack; - pCurrent->m_flNextSecondaryAttack = pfrom->m_flNextSecondaryAttack; - pCurrent->m_flTimeWeaponIdle = pfrom->m_flTimeWeaponIdle; - } - - // For random weapon events, use this seed to seed random # generator - player.random_seed = random_seed; - - // Get old buttons from previous state. - player.m_afButtonLast = from->playerstate.oldbuttons; - - // Which buttsons chave changed - buttonsChanged = (player.m_afButtonLast ^ cmd->buttons); // These buttons have changed this frame - - // Debounced button codes for pressed/released - // The changed ones still down are "pressed" - player.m_afButtonPressed = buttonsChanged & cmd->buttons; - // The ones not down are "released" - player.m_afButtonReleased = buttonsChanged & (~cmd->buttons); - - // Set player variables that weapons code might check/alter - player.pev->button = cmd->buttons; - - player.pev->velocity = from->client.velocity; - player.pev->flags = from->client.flags; - - player.pev->deadflag = from->client.deadflag; - g_iWaterLevel = player.pev->waterlevel = from->client.waterlevel; - player.pev->maxspeed = from->client.maxspeed; - player.pev->fov = from->client.fov; - player.pev->weaponanim = from->client.weaponanim; - player.pev->viewmodel = from->client.viewmodel; - player.m_flNextAttack = from->client.m_flNextAttack; - player.m_iQuakeWeapon = (int)from->client.fuser1; - iCarriedWeapons = player.m_iQuakeItems = from->client.iuser3; - - player.m_iAmmoShells = from->client.ammo_shells; - player.m_iAmmoCells = from->client.ammo_cells; - player.m_iAmmoRockets = from->client.ammo_rockets; - player.m_iAmmoNails = from->client.ammo_nails; - - player.m_iNailOffset = (int)from->client.fuser2 != 0.0 ? 4.0 : -4.0; - - - - // REally useful for debugging prediction -/* if ( player.m_iQuakeWeapon > 0 ) - { - gEngfuncs.Con_NPrintf( 9, "got qw %i", player.m_iQuakeWeapon ); - char items[33]; - for ( int i = 0; i < 32; i++ ) - { - if ( player.m_iQuakeItems & (1<viewmodel ); - gEngfuncs.Con_NPrintf( 16, "dm == %i", gpGlobals->deathmatch ); - }*/ - - - // Point to current weapon object - if ( from->client.m_iId ) - { - player.m_pActiveItem = g_pWpns[ from->client.m_iId ]; - } - - // Set ammo, but don't change anim - player.W_SetCurrentAmmo( 0 ); - - - - // Don't go firing anything if we have died. - // Or if we don't have a weapon model deployed - if ( ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) && !CL_IsDead() ) // && player.pev->viewmodel ) - { - if ( player.m_flNextAttack <= 0 ) - { - pWeapon->ItemPostFrame(); - } - } - - // Assume that we are not going to switch weapons - to->client.m_iId = from->client.m_iId; - - // Now see if we issued a changeweapon command ( and we're not dead ) - if ( cmd->weaponselect && ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) ) - { - // Switched to a different weapon? - if ( Quake_NumForWeaponItem( player.m_iQuakeWeapon ) != cmd->weaponselect ) - { - player.W_ChangeWeapon( cmd->weaponselect ); - } - } - - if ( player.m_iQuakeWeapon != IT_LIGHTNING && pBeam != NULL ) - { - pBeam->die = 0.0; - pBeam = NULL; - } - // Copy in results of predcition code - - to->client.viewmodel = player.pev->viewmodel; - to->client.fov = player.pev->fov; - to->client.weaponanim = player.pev->weaponanim; - to->client.m_flNextAttack = player.m_flNextAttack; - to->client.maxspeed = player.pev->maxspeed; - to->client.iuser3 = player.m_iQuakeItems; - to->client.fuser1 = (float)player.m_iQuakeWeapon; - to->client.fuser2 = (float)player.m_iNailOffset > 0.0 ? 1.0 : 0.0; - - to->client.ammo_shells = player.m_iAmmoShells; - to->client.ammo_cells = player.m_iAmmoCells; - to->client.ammo_rockets = player.m_iAmmoRockets; - to->client.ammo_nails = player.m_iAmmoNails; - - // Make sure that weapon animation matches what the game .dll is telling us - // over the wire ( fixes some animation glitches ) - if ( g_runfuncs && ( HUD_GetWeaponAnim() != to->client.weaponanim ) ) - { - int body = 2; - // Force a fixed anim down to viewmodel - HUD_SendWeaponAnim( to->client.weaponanim, body, 1 ); - } - - for ( i = 0; i < 32; i++ ) - { - pCurrent = g_pWpns[ i ]; - - pto = &to->weapondata[ i ]; - - if ( !pCurrent ) - { - memset( pto, 0, sizeof( weapon_data_t ) ); - continue; - } - - pto->m_fInReload = pCurrent->m_fInReload; - pto->m_iClip = pCurrent->m_iClip; - pto->m_flNextPrimaryAttack = pCurrent->m_flNextPrimaryAttack; - pto->m_flNextSecondaryAttack = pCurrent->m_flNextSecondaryAttack; - pto->m_flTimeWeaponIdle = pCurrent->m_flTimeWeaponIdle; - - // Decrement weapon counters, server does this at same time ( during post think, after doing everything else ) - pto->m_flNextReload -= cmd->msec / 1000.0; - pto->m_fNextAimBonus -= cmd->msec / 1000.0; - pto->m_flNextPrimaryAttack -= cmd->msec / 1000.0; - pto->m_flNextSecondaryAttack -= cmd->msec / 1000.0; - pto->m_flTimeWeaponIdle -= cmd->msec / 1000.0; - - if ( pto->m_flPumpTime != -9999 ) - { - pto->m_flPumpTime -= cmd->msec / 1000.0; - if ( pto->m_flPumpTime < -0.001 ) - pto->m_flPumpTime = -0.001; - } - - if ( pto->m_fNextAimBonus < -1.0 ) - { - pto->m_fNextAimBonus = -1.0; - } - - if ( pto->m_flNextPrimaryAttack < -1.0 ) - { - pto->m_flNextPrimaryAttack = -1.0; - } - - if ( pto->m_flNextSecondaryAttack < -0.001 ) - { - pto->m_flNextSecondaryAttack = -0.001; - } - - if ( pto->m_flTimeWeaponIdle < -0.001 ) - { - pto->m_flTimeWeaponIdle = -0.001; - } - - if ( pto->m_flNextReload < -0.001 ) - { - pto->m_flNextReload = -0.001; - } - } - - // m_flNextAttack is now part of the weapons, but is part of the player instead - to->client.m_flNextAttack -= cmd->msec / 1000.0; - if ( to->client.m_flNextAttack < -0.001 ) - { - to->client.m_flNextAttack = -0.001; - } - - // Store off the last position from the predicted state. - HUD_SetLastOrg(); - // Wipe it so we can't use it after this frame - g_finalstate = NULL; -} - -/* -===================== -HUD_PostRunCmd - -Client calls this during prediction, after it has moved the player and updated any info changed into to-> -time is the current client clock based on prediction -cmd is the command that caused the movement, etc -runfuncs is 1 if this is the first time we've predicted this command. If so, sounds and effects should play, otherwise, they should -be ignored -===================== -*/ -void DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ) -{ - g_runfuncs = runfuncs; - - // Only run post think stuff for glock for the sample - // implementation - if ( cl_lw && cl_lw->value ) - { - HUD_WeaponsPostThink( from, to, cmd, time, random_seed ); - } - else - { - to->client.fov = g_lastFOV; - } - - Dmc_CheckTeleporters( from, to ); // See if we stepped on a jump pad - - // All games can use FOV state - g_lastFOV = to->client.fov; -} diff --git a/dmc/cl_dll/readme.txt b/dmc/cl_dll/readme.txt deleted file mode 100644 index 249205c..0000000 --- a/dmc/cl_dll/readme.txt +++ /dev/null @@ -1,107 +0,0 @@ - client dll readme.txt -------------------------- - -This file details the structure of the half-life client dll, and -how it communicates with the half-life game engine. - - -Engine callback functions: - -Drawing functions: - HSPRITE SPR_Load( char *picname ); - Loads a sprite into memory, and returns a handle to it. - - int SPR_Frames( HSPRITE sprite ); - Returns the number of frames stored in the specified sprite. - - int SPR_Height( HSPRITE x, int frame ) - Returns the height, in pixels, of a sprite at the specified frame. - Returns 0 is the frame number or the sprite handle is invalid. - - int SPR_Width( HSPRITE x, int f ) - Returns the width, in pixels, of a sprite at the specified frame. - Returns 0 is the frame number or the sprite handle is invalid. - - int SPR_Set( HSPRITE sprite, int r, int g, int b ); - Prepares a sprite about to be drawn. RBG color values are applied to the sprite at this time. - - - void SPR_Draw( int frame, int x, int y ); - Precondition: SPR_Set has already been called for a sprite. - Draws the currently active sprite to the screen, at position (x,y), where (0,0) is - the top left-hand corner of the screen. - - - void SPR_DrawHoles( int frame, int x, int y ); - Precondition: SPR_Set has already been called for a sprite. - Draws the currently active sprite to the screen. Color index #255 is treated as transparent. - - void SPR_DrawAdditive( int frame, int x, int y ); - Precondition: SPR_Set has already been called for a sprite. - Draws the currently active sprite to the screen, adding it's color values to the background. - - void SPR_EnableScissor( int x, int y, int width, int height ); - Creates a clipping rectangle. No pixels will be drawn outside the specified area. Will - stay in effect until either the next frame, or SPR_DisableScissor is called. - - void SPR_DisableScissor( void ); - Disables the effect of an SPR_EnableScissor call. - - int IsHighRes( void ); - returns 1 if the res mode is 640x480 or higher; 0 otherwise. - - int ScreenWidth( void ); - returns the screen width, in pixels. - - int ScreenHeight( void ); - returns the screen height, in pixels. - -// Sound functions - void PlaySound( char *szSound, int volume ) - plays the sound 'szSound' at the specified volume. Loads the sound if it hasn't been cached. - If it can't find the sound, it displays an error message and plays no sound. - - void PlaySound( int iSound, int volume ) - Precondition: iSound has been precached. - Plays the sound, from the precache list. - - -// Communication functions - void SendClientCmd( char *szCmdString ); - sends a command to the server, just as if the client had typed the szCmdString at the console. - - char *GetPlayerName( int entity_number ); - returns a pointer to a string, that contains the name of the specified client. - Returns NULL if the entity_number is not a client. - - - DECLARE_MESSAGE(), HOOK_MESSAGE() - These two macros bind the message sending between the entity DLL and the client DLL to - the CHud object. - - HOOK_MESSAGE( message_name ) - This is used inside CHud::Init(). It calls into the engine to hook that message - from the incoming message stream. - Precondition: There must be a function of name UserMsg_message_name declared - for CHud. Eg, CHud::UserMsg_Health() must be declared if you want to - use HOOK_MESSAGE( Health ); - - DECLARE_MESSAGE( message_name ) - For each HOOK_MESSAGE you must have an equivalent DECLARE_MESSAGE. This creates - a function which passes the hooked messages into the CHud object. - - - HOOK_COMMAND(), DECLARE_COMMAND() - These two functions declare and hook console commands into the client dll. - - HOOK_COMMAND( char *command, command_name ) - Whenever the user types the 'command' at the console, the function 'command_name' - will be called. - Precondition: There must be a function of the name UserCmd_command_name declared - for CHud. Eg, CHud::UserMsg_ShowScores() must be declared if you want to - use HOOK_COMMAND( "+showscores", ShowScores ); - - DECLARE_COMMAND( command_name ) - For each HOOK_COMMAND you must have an equivelant DECLARE_COMMAND. This creates - a function which passes the hooked commands into the CHud object. - diff --git a/dmc/cl_dll/saytext.cpp b/dmc/cl_dll/saytext.cpp deleted file mode 100644 index 679809f..0000000 --- a/dmc/cl_dll/saytext.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// saytext.cpp -// -// implementation of CHudSayText class -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -extern float *GetClientColor( int clientIndex ); -extern hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; - -#define MAX_LINES 5 -#define MAX_CHARS_PER_LINE 256 /* it can be less than this, depending on char size */ - -// allow 20 pixels on either side of the text -#define MAX_LINE_WIDTH ( ScreenWidth - 40 ) -#define LINE_START 10 -static float SCROLL_SPEED = 5; - -static char g_szLineBuffer[ MAX_LINES + 1 ][ MAX_CHARS_PER_LINE ]; -static float *g_pflNameColors[ MAX_LINES + 1 ]; -static int g_iNameLengths[ MAX_LINES + 1 ]; -static float flScrollTime = 0; // the time at which the lines next scroll up - -static int Y_START = 0; -static int line_height = 0; - -DECLARE_MESSAGE( m_SayText, SayText ); - -int CHudSayText :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( SayText ); - - InitHUDData(); - - m_HUD_saytext = gEngfuncs.pfnRegisterVariable( "hud_saytext", "1", 0 ); - m_HUD_saytext_time = gEngfuncs.pfnRegisterVariable( "hud_saytext_time", "5", 0 ); - - return 1; -} - - -void CHudSayText :: InitHUDData( void ) -{ - memset( g_szLineBuffer, 0, sizeof g_szLineBuffer ); - memset( g_pflNameColors, 0, sizeof g_pflNameColors ); - memset( g_iNameLengths, 0, sizeof g_iNameLengths ); - - m_iFlags |= HUD_INTERMISSION; // is always drawn during an intermission -} - -int CHudSayText :: VidInit( void ) -{ - return 1; -} - - -int ScrollTextUp( void ) -{ - ConsolePrint( g_szLineBuffer[0] ); // move the first line into the console buffer - g_szLineBuffer[MAX_LINES][0] = 0; - memmove( g_szLineBuffer[0], g_szLineBuffer[1], sizeof(g_szLineBuffer) - sizeof(g_szLineBuffer[0]) ); // overwrite the first line - memmove( &g_pflNameColors[0], &g_pflNameColors[1], sizeof(g_pflNameColors) - sizeof(g_pflNameColors[0]) ); - memmove( &g_iNameLengths[0], &g_iNameLengths[1], sizeof(g_iNameLengths) - sizeof(g_iNameLengths[0]) ); - g_szLineBuffer[MAX_LINES-1][0] = 0; - - if ( g_szLineBuffer[0][0] == ' ' ) // also scroll up following lines - { - g_szLineBuffer[0][0] = 2; - return 1 + ScrollTextUp(); - } - - return 1; -} - -int CHudSayText :: Draw( float flTime ) -{ - int y = Y_START; - - // make sure the scrolltime is within reasonable bounds, to guard against the clock being reset - flScrollTime = V_min( flScrollTime, flTime + m_HUD_saytext_time->value ); - - // make sure the scrolltime is within reasonable bounds, to guard against the clock being reset - flScrollTime = V_min( flScrollTime, flTime + m_HUD_saytext_time->value ); - - if ( flScrollTime <= flTime ) - { - if ( *g_szLineBuffer[0] ) - { - flScrollTime = flTime + m_HUD_saytext_time->value; - // push the console up - ScrollTextUp(); - } - else - { // buffer is empty, just disable drawing of this section - m_iFlags &= ~HUD_ACTIVE; - } - } - - for ( int i = 0; i < MAX_LINES; i++ ) - { - if ( *g_szLineBuffer[i] ) - { - if ( *g_szLineBuffer[i] == 2 && g_pflNameColors[i] ) - { - // it's a saytext string - static char buf[MAX_PLAYER_NAME_LENGTH+32]; - - // draw the first x characters in the player color - strncpy( buf, g_szLineBuffer[i], V_min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+32) ); - buf[ V_min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+31) ] = 0; - gEngfuncs.pfnDrawSetTextColor( g_pflNameColors[i][0], g_pflNameColors[i][1], g_pflNameColors[i][2] ); - - int x = DrawConsoleString( LINE_START, y, buf ); - - // color is reset after each string draw - DrawConsoleString( x, y, g_szLineBuffer[i] + g_iNameLengths[i] ); - } - else - { - // normal draw - DrawConsoleString( LINE_START, y, g_szLineBuffer[i] ); - } - } - - y += line_height; - } - - - return 1; -} - -int CHudSayText :: MsgFunc_SayText( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int client_index = READ_BYTE(); // the client who spoke the message - SayTextPrint( READ_STRING(), iSize - 1, client_index ); - - return 1; -} - -void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIndex ) -{ - // find an empty string slot - int i; - for ( i = 0; i < MAX_LINES; i++ ) - { - if ( ! *g_szLineBuffer[i] ) - break; - } - if ( i == MAX_LINES ) - { - // force scroll buffer up - ScrollTextUp(); - i = MAX_LINES - 1; - } - - g_iNameLengths[i] = 0; - g_pflNameColors[i] = NULL; - - // if it's a say message, search for the players name in the string - if ( *pszBuf == 2 && clientIndex > 0 ) - { - GetPlayerInfo( clientIndex, &g_PlayerInfoList[clientIndex] ); - const char *pName = g_PlayerInfoList[clientIndex].name; - - if ( pName ) - { - const char *nameInString = strstr( pszBuf, pName ); - - if ( nameInString ) - { - g_iNameLengths[i] = strlen( pName ) + (nameInString - pszBuf); - g_pflNameColors[i] = GetClientColor( clientIndex ); - } - } - } - - strncpy( g_szLineBuffer[i], pszBuf, V_max(iBufSize -1, MAX_CHARS_PER_LINE-1) ); - - // make sure the text fits in one line - EnsureTextFitsInOneLineAndWrapIfHaveTo( i ); - - // Set scroll time - if ( i == 0 ) - { - flScrollTime = gHUD.m_flTime + m_HUD_saytext_time->value; - } - - m_iFlags |= HUD_ACTIVE; - PlaySound( "misc/talk.wav", 1 ); - - if ( ScreenHeight >= 480 ) - Y_START = ScreenHeight - 138; - else - Y_START = ScreenHeight - 70; - Y_START -= (line_height * (MAX_LINES+1)); - -} - -void CHudSayText :: EnsureTextFitsInOneLineAndWrapIfHaveTo( int line ) -{ - int line_width = 0; - GetConsoleStringSize( g_szLineBuffer[line], &line_width, &line_height ); - - if ( (line_width + LINE_START) > MAX_LINE_WIDTH ) - { // string is too long to fit on line - // scan the string until we find what word is too long, and wrap the end of the sentence after the word - int length = LINE_START; - int tmp_len = 0; - char *last_break = NULL; - for ( char *x = g_szLineBuffer[line]; *x != 0; x++ ) - { - // check for a color change, if so skip past it - if ( x[0] == '/' && x[1] == '(' ) - { - x += 2; - // skip forward until past mode specifier - while ( *x != 0 && *x != ')' ) - x++; - - if ( *x != 0 ) - x++; - - if ( *x == 0 ) - break; - } - - char buf[2]; - buf[1] = 0; - - if ( *x == ' ' && x != g_szLineBuffer[line] ) // store each line break, except for the very first character - last_break = x; - - buf[0] = *x; // get the length of the current character - GetConsoleStringSize( buf, &tmp_len, &line_height ); - length += tmp_len; - - if ( length > MAX_LINE_WIDTH ) - { // needs to be broken up - if ( !last_break ) - last_break = x-1; - - x = last_break; - - // find an empty string slot - int j; - do - { - for ( j = 0; j < MAX_LINES; j++ ) - { - if ( ! *g_szLineBuffer[j] ) - break; - } - if ( j == MAX_LINES ) - { - // need to make more room to display text, scroll stuff up then fix the pointers - int linesmoved = ScrollTextUp(); - line -= linesmoved; - last_break = last_break - (sizeof(g_szLineBuffer[0]) * linesmoved); - } - } - while ( j == MAX_LINES ); - - // copy remaining string into next buffer, making sure it starts with a space character - if ( (char)*last_break == (char)' ' ) - { - int linelen = strlen(g_szLineBuffer[j]); - int remaininglen = strlen(last_break); - - if ( (linelen - remaininglen) <= MAX_CHARS_PER_LINE ) - strcat( g_szLineBuffer[j], last_break ); - } - else - { - if ( (strlen(g_szLineBuffer[j]) - strlen(last_break) - 2) < MAX_CHARS_PER_LINE ) - { - strcat( g_szLineBuffer[j], " " ); - strcat( g_szLineBuffer[j], last_break ); - } - } - - *last_break = 0; // cut off the last string - - EnsureTextFitsInOneLineAndWrapIfHaveTo( j ); - break; - } - } - } -} diff --git a/dmc/cl_dll/scoreboard.cpp b/dmc/cl_dll/scoreboard.cpp deleted file mode 100644 index a032bbe..0000000 --- a/dmc/cl_dll/scoreboard.cpp +++ /dev/null @@ -1,527 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// Scoreboard.cpp -// -// implementation of CHudScoreboard class -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -DECLARE_COMMAND( m_Scoreboard, ShowScores ); -DECLARE_COMMAND( m_Scoreboard, HideScores ); - -DECLARE_MESSAGE( m_Scoreboard, ScoreInfo ); -DECLARE_MESSAGE( m_Scoreboard, TeamInfo ); -DECLARE_MESSAGE( m_Scoreboard, TeamScore ); - - -int CHudScoreboard :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( ScoreInfo ); - HOOK_MESSAGE( TeamScore ); - HOOK_MESSAGE( TeamInfo ); - - InitHUDData(); - - return 1; -} - - -int CHudScoreboard :: VidInit( void ) -{ - - return 1; -} - -void CHudScoreboard :: InitHUDData( void ) -{ - memset( g_PlayerExtraInfo, 0, sizeof g_PlayerExtraInfo ); - m_iLastKilledBy = 0; - m_fLastKillTime = 0; - m_iPlayerNum = 0; - m_iNumTeams = 0; - - memset( m_TeamInfo, 0, sizeof m_TeamInfo ); - - m_iFlags &= ~HUD_ACTIVE; // starts out inactive - - m_iFlags |= HUD_INTERMISSION; // is always drawn during an intermission -} - -/* The scoreboard -We have a minimum width of 1-320 - we could have the field widths scale with it? -*/ - -// X positions -// relative to the side of the scoreboard -#define NAME_RANGE_MIN 20 -#define NAME_RANGE_MAX 145 -#define KILLS_RANGE_MIN 130 -#define KILLS_RANGE_MAX 170 -#define DIVIDER_POS 180 -#define DEATHS_RANGE_MIN 185 -#define DEATHS_RANGE_MAX 210 -#define PING_RANGE_MIN 245 -#define PING_RANGE_MAX 295 - -#define SCOREBOARD_WIDTH 320 - - -// Y positions -#define ROW_GAP 13 -#define ROW_RANGE_MIN 15 -#define ROW_RANGE_MAX ( ScreenHeight - 50 ) - -int CHudScoreboard :: Draw( float fTime ) -{ - if ( !m_iShowscoresHeld && gHUD.m_Health.m_iHealth > 0 && !gHUD.m_iIntermission ) - return 1; - - - GetAllPlayersInfo(); - - // just sort the list on the fly - // list is sorted first by frags, then by deaths - float list_slot = 0; - int xpos_rel = (ScreenWidth - SCOREBOARD_WIDTH) / 2; - - // print the heading line - int ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP); - int xpos = NAME_RANGE_MIN + xpos_rel; - - if ( !gHUD.m_Teamplay ) - gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Player", 255, 140, 0 ); - else - gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, "Teams", 255, 140, 0 ); - - gHUD.DrawHudStringReverse( KILLS_RANGE_MAX + xpos_rel, ypos, 0, "kills", 255, 140, 0 ); - gHUD.DrawHudString( DIVIDER_POS + xpos_rel, ypos, ScreenWidth, "/", 255, 140, 0 ); - gHUD.DrawHudString( DEATHS_RANGE_MIN + xpos_rel + 5, ypos, ScreenWidth, "deaths", 255, 140, 0 ); - gHUD.DrawHudString( PING_RANGE_MAX + xpos_rel - 35, ypos, ScreenWidth, "latency", 255, 140, 0 ); - - list_slot += 1.2; - ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP); - xpos = NAME_RANGE_MIN + xpos_rel; - FillRGBA( xpos - 5, ypos, PING_RANGE_MAX - 5, 1, 255, 140, 0, 255); // draw the seperator line - - list_slot += 0.8; - - if ( !gHUD.m_Teamplay ) - { - // it's not teamplay, so just draw a simple player list - DrawPlayers( xpos_rel, list_slot ); - return 1; - } - - // clear out team scores - for ( int i = 1; i <= m_iNumTeams; i++ ) - { - if ( !m_TeamInfo[i].scores_overriden ) - m_TeamInfo[i].frags = m_TeamInfo[i].deaths = 0; - m_TeamInfo[i].ping = m_TeamInfo[i].packetloss = 0; - } - - // recalc the team scores, then draw them - for ( i = 1; i < MAX_PLAYERS; i++ ) - { - if ( m_PlayerInfoList[i].name == NULL ) - continue; // empty player slot, skip - - if ( m_PlayerExtraInfo[i].teamname[0] == 0 ) - continue; // skip over players who are not in a team - - // find what team this player is in - for ( int j = 1; j <= m_iNumTeams; j++ ) - { - if ( !stricmp( m_PlayerExtraInfo[i].teamname, m_TeamInfo[j].name ) ) - break; - } - if ( j > m_iNumTeams ) // player is not in a team, skip to the next guy - continue; - - if ( !m_TeamInfo[j].scores_overriden ) - { - m_TeamInfo[j].frags += m_PlayerExtraInfo[i].frags; - m_TeamInfo[j].deaths += m_PlayerExtraInfo[i].deaths; - } - - m_TeamInfo[j].ping += m_PlayerInfoList[i].ping; - m_TeamInfo[j].packetloss += m_PlayerInfoList[i].packetloss; - - if ( m_PlayerInfoList[i].thisplayer ) - m_TeamInfo[j].ownteam = TRUE; - else - m_TeamInfo[j].ownteam = FALSE; - } - - // find team ping/packetloss averages - for ( i = 1; i <= m_iNumTeams; i++ ) - { - m_TeamInfo[i].already_drawn = FALSE; - - if ( m_TeamInfo[i].players > 0 ) - { - m_TeamInfo[i].ping /= m_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping - m_TeamInfo[i].packetloss /= m_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping - } - } - - // Draw the teams - while ( 1 ) - { - int highest_frags = -99999; int lowest_deaths = 99999; - int best_team = 0; - - for ( i = 1; i <= m_iNumTeams; i++ ) - { - if ( m_TeamInfo[i].players < 0 ) - continue; - - if ( !m_TeamInfo[i].already_drawn && m_TeamInfo[i].frags >= highest_frags ) - { - if ( m_TeamInfo[i].frags > highest_frags || m_TeamInfo[i].deaths < lowest_deaths ) - { - best_team = i; - lowest_deaths = m_TeamInfo[i].deaths; - highest_frags = m_TeamInfo[i].frags; - } - } - } - - // draw the best team on the scoreboard - if ( !best_team ) - break; - - // draw out the best team - team_info_t *team_info = &m_TeamInfo[best_team]; - - ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP); - - // check we haven't drawn too far down - if ( ypos > ROW_RANGE_MAX ) // don't draw to close to the lower border - break; - - xpos = NAME_RANGE_MIN + xpos_rel; - int r = 255, g = 225, b = 55; // draw the stuff kinda yellowish - - if ( team_info->ownteam ) // if it is their team, draw the background different color - { - // overlay the background in blue, then draw the score text over it - FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, PING_RANGE_MAX - 5, ROW_GAP, 0, 0, 255, 70 ); - } - - // draw their name (left to right) - gHUD.DrawHudString( xpos, ypos, NAME_RANGE_MAX + xpos_rel, team_info->name, r, g, b ); - - // draw kills (right to left) - xpos = KILLS_RANGE_MAX + xpos_rel; - gHUD.DrawHudNumberString( xpos, ypos, KILLS_RANGE_MIN + xpos_rel, team_info->frags, r, g, b ); - - // draw divider - xpos = DIVIDER_POS + xpos_rel; - gHUD.DrawHudString( xpos, ypos, xpos + 20, "/", r, g, b ); - - // draw deaths - xpos = DEATHS_RANGE_MAX + xpos_rel; - gHUD.DrawHudNumberString( xpos, ypos, DEATHS_RANGE_MIN + xpos_rel, team_info->deaths, r, g, b ); - - // draw ping - // draw ping & packetloss - static char buf[64]; - sprintf( buf, "%d", team_info->ping ); - xpos = ((PING_RANGE_MAX - PING_RANGE_MIN) / 2) + PING_RANGE_MIN + xpos_rel + 25; - UnpackRGB( r, g, b, RGB_YELLOWISH ); - gHUD.DrawHudStringReverse( xpos, ypos, xpos - 50, buf, r, g, b ); - - /* Packetloss removed on Kelly 'shipping nazi' Bailey's orders - sprintf( buf, " %d", team_info->packetloss ); - gHUD.DrawHudString( xpos, ypos, xpos+50, buf, r, g, b ); - */ - - team_info->already_drawn = TRUE; // set the already_drawn to be TRUE, so this team won't get drawn again - list_slot++; - - // draw all the players that belong to this team, indented slightly - list_slot = DrawPlayers( xpos_rel, list_slot, 10, team_info->name ); - } - - // draw all the players who are not in a team - list_slot += 0.5; - DrawPlayers( xpos_rel, list_slot, 0, "" ); - - return 1; -} - -// returns the ypos where it finishes drawing -int CHudScoreboard :: DrawPlayers( int xpos_rel, float list_slot, int nameoffset, char *team ) -{ - // draw the players, in order, and restricted to team if set - while ( 1 ) - { - // Find the top ranking player - int highest_frags = -99999; int lowest_deaths = 99999; - int best_player = 0; - - for ( int i = 1; i < MAX_PLAYERS; i++ ) - { - if ( m_PlayerInfoList[i].name && m_PlayerExtraInfo[i].frags >= highest_frags ) - { - if ( !(team && stricmp(m_PlayerExtraInfo[i].teamname, team)) ) // make sure it is the specified team - { - extra_player_info_t *pl_info = &m_PlayerExtraInfo[i]; - if ( pl_info->frags > highest_frags || pl_info->deaths < lowest_deaths ) - { - best_player = i; - lowest_deaths = pl_info->deaths; - highest_frags = pl_info->frags; - - } - } - } - } - - if ( !best_player ) - break; - - // draw out the best player - hud_player_info_t *pl_info = &m_PlayerInfoList[best_player]; - - int ypos = ROW_RANGE_MIN + (list_slot * ROW_GAP); - - // check we haven't drawn too far down - if ( ypos > ROW_RANGE_MAX ) // don't draw to close to the lower border - break; - - int xpos = NAME_RANGE_MIN + xpos_rel; - int r = 255, g = 255, b = 255; - if ( best_player == m_iLastKilledBy && m_fLastKillTime && m_fLastKillTime > gHUD.m_flTime ) - { - if ( pl_info->thisplayer ) - { // green is the suicide color? i wish this could do grey... - FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, PING_RANGE_MAX - 5, ROW_GAP, 80, 155, 0, 70 ); - } - else - { // Highlight the killers name - overlay the background in red, then draw the score text over it - FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, PING_RANGE_MAX - 5, ROW_GAP, 255, 0, 0, ((float)15 * (float)(m_fLastKillTime - gHUD.m_flTime)) ); - } - } - else if ( pl_info->thisplayer ) // if it is their name, draw it a different color - { - // overlay the background in blue, then draw the score text over it - FillRGBA( NAME_RANGE_MIN + xpos_rel - 5, ypos, PING_RANGE_MAX - 5, ROW_GAP, 0, 0, 255, 70 ); - } - - // draw their name (left to right) - gHUD.DrawHudString( xpos + nameoffset, ypos, NAME_RANGE_MAX + xpos_rel, pl_info->name, r, g, b ); - - // draw kills (right to left) - xpos = KILLS_RANGE_MAX + xpos_rel; - gHUD.DrawHudNumberString( xpos, ypos, KILLS_RANGE_MIN + xpos_rel, m_PlayerExtraInfo[best_player].frags, r, g, b ); - - // draw divider - xpos = DIVIDER_POS + xpos_rel; - gHUD.DrawHudString( xpos, ypos, xpos + 20, "/", r, g, b ); - - // draw deaths - xpos = DEATHS_RANGE_MAX + xpos_rel; - gHUD.DrawHudNumberString( xpos, ypos, DEATHS_RANGE_MIN + xpos_rel, m_PlayerExtraInfo[best_player].deaths, r, g, b ); - - // draw ping & packetloss - static char buf[64]; - sprintf( buf, "%d", m_PlayerInfoList[best_player].ping ); - xpos = ((PING_RANGE_MAX - PING_RANGE_MIN) / 2) + PING_RANGE_MIN + xpos_rel + 25; - gHUD.DrawHudStringReverse( xpos, ypos, xpos - 50, buf, r, g, b ); - - /* Packetloss removed on Kelly 'shipping nazi' Bailey's orders - if ( m_PlayerInfoList[best_player].packetloss >= 63 ) - { - UnpackRGB( r, g, b, RGB_REDISH ); - sprintf( buf, " !!!!" ); - } - else - { - sprintf( buf, " %d", m_PlayerInfoList[best_player].packetloss ); - } - - gHUD.DrawHudString( xpos, ypos, xpos+50, buf, r, g, b ); - */ - - pl_info->name = NULL; // set the name to be NULL, so this client won't get drawn again - list_slot++; - } - - return list_slot; -} - - -void CHudScoreboard :: GetAllPlayersInfo( void ) -{ - for ( int i = 1; i < MAX_PLAYERS; i++ ) - { - GetPlayerInfo( i, &m_PlayerInfoList[i] ); - - if ( m_PlayerInfoList[i].thisplayer ) - m_iPlayerNum = i; // !!!HACK: this should be initialized elsewhere... maybe gotten from the engine - } -} - -int CHudScoreboard :: MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf ) -{ - m_iFlags |= HUD_ACTIVE; - - BEGIN_READ( pbuf, iSize ); - short cl = READ_BYTE(); - short frags = READ_SHORT(); - short deaths = READ_SHORT(); - - if ( cl > 0 && cl <= MAX_PLAYERS ) - { - m_PlayerExtraInfo[cl].frags = frags; - m_PlayerExtraInfo[cl].deaths = deaths; - } - - return 1; -} - -// Message handler for TeamInfo message -// accepts two values: -// byte: client number -// string: client team name -int CHudScoreboard :: MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - short cl = READ_BYTE(); - - if ( cl > 0 && cl <= MAX_PLAYERS ) - { // set the players team - strncpy( m_PlayerExtraInfo[cl].teamname, READ_STRING(), MAX_TEAM_NAME ); - } - - // rebuild the list of teams - - // clear out player counts from teams - for ( int i = 1; i <= m_iNumTeams; i++ ) - { - m_TeamInfo[i].players = 0; - } - - // rebuild the team list - GetAllPlayersInfo(); - m_iNumTeams = 0; - for ( i = 1; i < MAX_PLAYERS; i++ ) - { - if ( m_PlayerInfoList[i].name == NULL ) - continue; - - if ( m_PlayerExtraInfo[i].teamname[0] == 0 ) - continue; // skip over players who are not in a team - - // is this player in an existing team? - for ( int j = 1; j <= m_iNumTeams; j++ ) - { - if ( m_TeamInfo[j].name[0] == '\0' ) - break; - - if ( !stricmp( m_PlayerExtraInfo[i].teamname, m_TeamInfo[j].name ) ) - break; - } - - if ( j > m_iNumTeams ) - { // they aren't in a listed team, so make a new one - // search through for an empty team slot - for ( int j = 1; j <= m_iNumTeams; j++ ) - { - if ( m_TeamInfo[j].name[0] == '\0' ) - break; - } - m_iNumTeams = V_max( j, m_iNumTeams ); - - strncpy( m_TeamInfo[j].name, m_PlayerExtraInfo[i].teamname, MAX_TEAM_NAME ); - m_TeamInfo[j].players = 0; - } - - m_TeamInfo[j].players++; - } - - // clear out any empty teams - for ( i = 1; i <= m_iNumTeams; i++ ) - { - if ( m_TeamInfo[i].players < 1 ) - memset( &m_TeamInfo[i], 0, sizeof(team_info_t) ); - } - - return 1; -} - -// Message handler for TeamScore message -// accepts three values: -// string: team name -// short: teams kills -// short: teams deaths -// if this message is never received, then scores will simply be the combined totals of the players. -int CHudScoreboard :: MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - char *TeamName = READ_STRING(); - - // find the team matching the name - for ( int i = 1; i <= m_iNumTeams; i++ ) - { - if ( !stricmp( TeamName, m_TeamInfo[i].name ) ) - break; - } - if ( i > m_iNumTeams ) - return 1; - - // use this new score data instead of combined player scores - m_TeamInfo[i].scores_overriden = TRUE; - m_TeamInfo[i].frags = READ_SHORT(); - m_TeamInfo[i].deaths = READ_SHORT(); - - return 1; -} - -void CHudScoreboard :: DeathMsg( int killer, int victim ) -{ - // if we were the one killed, or the world killed us, set the scoreboard to indicate suicide - if ( victim == m_iPlayerNum || killer == 0 ) - { - m_iLastKilledBy = killer ? killer : m_iPlayerNum; - m_fLastKillTime = gHUD.m_flTime + 10; // display who we were killed by for 10 seconds - - if ( killer == m_iPlayerNum ) - m_iLastKilledBy = m_iPlayerNum; - } -} - - - -void CHudScoreboard :: UserCmd_ShowScores( void ) -{ - m_iShowscoresHeld = TRUE; -} - -void CHudScoreboard :: UserCmd_HideScores( void ) -{ - m_iShowscoresHeld = FALSE; -} diff --git a/dmc/cl_dll/status_icons.cpp b/dmc/cl_dll/status_icons.cpp deleted file mode 100644 index 8733dcc..0000000 --- a/dmc/cl_dll/status_icons.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// status_icons.cpp -// -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE( m_StatusIcons, StatusIcon ); - -int CHudStatusIcons::Init( void ) -{ - HOOK_MESSAGE( StatusIcon ); - - gHUD.AddHudElem( this ); - - Reset(); - - return 1; -} - -int CHudStatusIcons::VidInit( void ) -{ - - return 1; -} - -void CHudStatusIcons::Reset( void ) -{ - memset( m_IconList, 0, sizeof m_IconList ); - m_iFlags &= ~HUD_ACTIVE; -} - -// Draw status icons along the left-hand side of the screen -int CHudStatusIcons::Draw( float flTime ) -{ - // find starting position to draw from, along right-hand side of screen - int x = 5; - int y = ScreenHeight / 2; - - // loop through icon list, and draw any valid icons drawing up from the middle of screen - for ( int i = 0; i < MAX_ICONSPRITES; i++ ) - { - if ( m_IconList[i].spr ) - { - y -= ( m_IconList[i].rc.bottom - m_IconList[i].rc.top ) + 5; - - SPR_Set( m_IconList[i].spr, m_IconList[i].r, m_IconList[i].g, m_IconList[i].b ); - SPR_DrawAdditive( 0, x, y, &m_IconList[i].rc ); - } - } - - return 1; -} - -// Message handler for StatusIcon message -// accepts five values: -// byte : TRUE = ENABLE icon, FALSE = DISABLE icon -// string : the sprite name to display -// byte : red -// byte : green -// byte : blue -int CHudStatusIcons::MsgFunc_StatusIcon( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int ShouldEnable = READ_BYTE(); - char *pszIconName = READ_STRING(); - if ( ShouldEnable ) - { - int r = READ_BYTE(); - int g = READ_BYTE(); - int b = READ_BYTE(); - EnableIcon( pszIconName, r, g, b ); - m_iFlags |= HUD_ACTIVE; - } - else - { - DisableIcon( pszIconName ); - } - - return 1; -} - -// add the icon to the icon list, and set it's drawing color -void CHudStatusIcons::EnableIcon( char *pszIconName, unsigned char red, unsigned char green, unsigned char blue ) -{ - // check to see if the sprite is in the current list - int i; - for ( i = 0; i < MAX_ICONSPRITES; i++ ) - { - if ( !stricmp( m_IconList[i].szSpriteName, pszIconName ) ) - break; - } - - if ( i == MAX_ICONSPRITES ) - { - // icon not in list, so find an empty slot to add to - for ( i = 0; i < MAX_ICONSPRITES; i++ ) - { - if ( !m_IconList[i].spr ) - break; - } - } - - // if we've run out of space in the list, overwrite the first icon - if ( i == MAX_ICONSPRITES ) - { - i = 0; - } - - // Load the sprite and add it to the list - // the sprite must be listed in hud.txt - int spr_index = gHUD.GetSpriteIndex( pszIconName ); - m_IconList[i].spr = gHUD.GetSprite( spr_index ); - m_IconList[i].rc = gHUD.GetSpriteRect( spr_index ); - m_IconList[i].r = red; - m_IconList[i].g = green; - m_IconList[i].b = blue; - strcpy( m_IconList[i].szSpriteName, pszIconName ); -} - -void CHudStatusIcons::DisableIcon( char *pszIconName ) -{ - // find the sprite is in the current list - for ( int i = 0; i < MAX_ICONSPRITES; i++ ) - { - if ( !stricmp( m_IconList[i].szSpriteName, pszIconName ) ) - { - // clear the item from the list - memset( &m_IconList[i], 0, sizeof(icon_sprite_t) ); - return; - } - } -} diff --git a/dmc/cl_dll/statusbar.cpp b/dmc/cl_dll/statusbar.cpp deleted file mode 100644 index 43ef061..0000000 --- a/dmc/cl_dll/statusbar.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// statusbar.cpp -// -// generic text status bar, set by game dll -// runs across bottom of screen -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -DECLARE_MESSAGE( m_StatusBar, StatusText ); -DECLARE_MESSAGE( m_StatusBar, StatusValue ); - -#define STATUSBAR_ID_LINE 1 - -extern int GetTeamIndex( int clientIndex ); -int g_iNameColors; - -int CHudStatusBar :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( StatusText ); - HOOK_MESSAGE( StatusValue ); - - Reset(); - - return 1; -} - -int CHudStatusBar :: VidInit( void ) -{ - // Load sprites here - m_iArmorSpriteIndex = gHUD.GetSpriteIndex( "armor_bar" ); - m_hArmor = gHUD.GetSprite( m_iArmorSpriteIndex ); - - m_iHealthSpriteIndex = gHUD.GetSpriteIndex( "health_bar" ); - m_hHealth = gHUD.GetSprite( m_iHealthSpriteIndex ); - - return 1; -} - -void CHudStatusBar :: Reset( void ) -{ - m_iFlags &= ~HUD_ACTIVE; // start out inactive - for ( int i = 0; i < MAX_STATUSBAR_LINES; i++ ) - m_szStatusText[i][0] = 0; - memset( m_iStatusValues, 0, sizeof m_iStatusValues ); - - m_iStatusValues[0] = 1; // 0 is the special index, which always returns true -} - -void CHudStatusBar :: ParseStatusString( int line_num ) -{ - int indexval; - - indexval = m_iStatusValues[ 1 ]; - - GetPlayerInfo( indexval, &g_PlayerInfoList[indexval] ); - - if ( g_PlayerInfoList[indexval].name != NULL ) - { - strncpy( m_szName[line_num], g_PlayerInfoList[indexval].name, MAX_PLAYER_NAME_LENGTH ); - } - else - { - strncpy( m_szName[line_num], "******", MAX_PLAYER_NAME_LENGTH ); - } - - g_iNameColors = GetTeamIndex( indexval ); - - indexval = m_iStatusValues[ 2 ]; - sprintf( m_szHealth[ line_num ], ":%d", indexval ); - - indexval = m_iStatusValues[ 3 ]; - sprintf( m_szArmor[ line_num ], ":%d", indexval ); - - m_iTeamMate[ line_num ] = m_iStatusValues[ 5 ]; -} - -int CHudStatusBar :: Draw( float fTime ) -{ - int r , g, b, a, name_r, name_g, name_b; - - if ( m_bReparseString ) - { - for ( int i = 0; i < MAX_STATUSBAR_LINES; i++ ) - ParseStatusString( i ); - m_bReparseString = FALSE; - } - - //Not Watching anyone - if ( m_iStatusValues[ 1 ] == 0 ) - { - m_iFlags &= ~HUD_ACTIVE; - return 1; - } - - // Draw the status bar lines - for ( int i = 0; i < MAX_STATUSBAR_LINES; i++ ) - { - int TextHeight = 0; - int TotalTextWidth = 0; - - //Ugly way to get - if ( m_iTeamMate[i] ) - { - TotalTextWidth += gHUD.ReturnStringPixelLength ( m_szName[i] ); - TotalTextWidth += gHUD.ReturnStringPixelLength ( m_szHealth[i] ); - TotalTextWidth += gHUD.ReturnStringPixelLength ( m_szArmor[i] ); - TotalTextWidth += 48; - TextHeight = gHUD.m_scrinfo.iCharHeight; - } - else - TotalTextWidth += gHUD.ReturnStringPixelLength ( m_szName[i] ); - - TextHeight = gHUD.m_scrinfo.iCharHeight; - - if ( g_iNameColors == 1 ) - { - name_r = 255; - name_g = 50; - name_b = 50; - } - else if ( g_iNameColors == 2 ) - { - name_r = 50; - name_g = 50; - name_b = 255; - } - else - name_r = name_g = name_b = 255; - - int Y_START; - if ( ScreenHeight >= 480 ) - Y_START = ScreenHeight - 55; - else - Y_START = ScreenHeight - 45; - - int x = gHUD.m_Ammo.m_iNumberXPosition; - int y = Y_START; // = ( ScreenHeight / 2 ) + ( TextHeight * 3 ); - - int x_offset; - a = 200; - - UnpackRGB( r, g, b, RGB_NORMAL); - ScaleColors( r, g, b, a ); - ScaleColors( name_r, name_g, name_b, 125 ); - - //Draw the name First - gHUD.DrawHudString( x, y, 1024, m_szName[i], name_r, name_g, name_b ); - - if ( !m_iTeamMate[i] ) - continue; - - //Get the length in pixels for the name - x_offset = gHUD.ReturnStringPixelLength ( m_szName[i] ); - - //Add the offset - x += ( x_offset + 8 ); - - //Now draw the Sprite for the health - SPR_Set( m_hHealth, r, g, b ); - SPR_DrawHoles( 0, x , y, &gHUD.GetSpriteRect( m_iHealthSpriteIndex ) ); - - //Add the sprite width size - x += 16; - - //Draw the health value ( x + offset for the name lenght + width of the sprite ) - gHUD.DrawHudString( x, y, 1024, m_szHealth[i], name_r, name_g, name_b ); - - //Get the length in pixels for the health - x_offset = gHUD.ReturnStringPixelLength ( m_szHealth[i] ); - - //Add the offset - x += ( x_offset + 8 ); - - //Now draw the Sprite for the Armor - SPR_Set( m_hArmor, r, g, b ); - SPR_DrawHoles( 0, x, y, &gHUD.GetSpriteRect( m_iArmorSpriteIndex ) ); - - x += 16; - - //Draw the armor value ( x + offset for the name lenght + width of the sprite ) - gHUD.DrawHudString( x, y, 1024, m_szArmor[i], name_r, name_g, name_b ); - } - - return 1; -} - -// Message handler for StatusText message -// accepts two values: -// byte: line number of status bar text -// string: status bar text -// this string describes how the status bar should be drawn -// a semi-regular expression: -// ( slotnum ([a..z] [%pX] [%iX])*)* -// where slotnum is an index into the Value table (see below) -// if slotnum is 0, the string is always drawn -// if StatusValue[slotnum] != 0, the following string is drawn, upto the next newline - otherwise the text is skipped upto next newline -// %pX, where X is an integer, will substitute a player name here, getting the player index from StatusValue[X] -// %iX, where X is an integer, will substitute a number here, getting the number from StatusValue[X] -int CHudStatusBar :: MsgFunc_StatusText( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int line = READ_BYTE(); - - if ( line < 0 || line >= MAX_STATUSBAR_LINES ) - return 1; - - strncpy( m_szStatusText[line], READ_STRING(), MAX_STATUSTEXT_LENGTH ); - m_szStatusText[line][MAX_STATUSTEXT_LENGTH-1] = 0; // ensure it's null terminated ( strncpy() won't null terminate if read string too long) - - if ( m_szStatusText[0] == 0 ) - m_iFlags &= ~HUD_ACTIVE; - else - m_iFlags |= HUD_ACTIVE; // we have status text, so turn on the status bar - - m_bReparseString = TRUE; - - return 1; -} - -// Message handler for StatusText message -// accepts two values: -// byte: index into the status value array -// short: value to store -int CHudStatusBar :: MsgFunc_StatusValue( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int index = READ_BYTE(); - if ( index < 1 || index >= MAX_STATUSBAR_VALUES ) - return 1; // index out of range - - m_iStatusValues[index] = READ_SHORT(); - - m_iFlags |= HUD_ACTIVE; - - m_bReparseString = TRUE; - - return 1; -} \ No newline at end of file diff --git a/dmc/cl_dll/studio_util.cpp b/dmc/cl_dll/studio_util.cpp deleted file mode 100644 index 1358ea0..0000000 --- a/dmc/cl_dll/studio_util.cpp +++ /dev/null @@ -1,138 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "com_model.h" -#include "studio_util.h" - -// angles index are not the same as ROLL, PITCH, YAW - -/* -==================== -AngleQuaternion - -==================== -*/ -void AngleQuaternion( float *angles, vec4_t quaternion ) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - // FIXME: rescale the inputs to 1/2 angle - angle = angles[2] * 0.5; - sy = sin(angle); - cy = cos(angle); - angle = angles[1] * 0.5; - sp = sin(angle); - cp = cos(angle); - angle = angles[0] * 0.5; - sr = sin(angle); - cr = cos(angle); - - quaternion[0] = sr*cp*cy-cr*sp*sy; // X - quaternion[1] = cr*sp*cy+sr*cp*sy; // Y - quaternion[2] = cr*cp*sy-sr*sp*cy; // Z - quaternion[3] = cr*cp*cy+sr*sp*sy; // W -} - -/* -==================== -QuaternionSlerp - -==================== -*/ -void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt ) -{ - int i; - float omega, cosom, sinom, sclp, sclq; - - // decide if one of the quaternions is backwards - float a = 0; - float b = 0; - - for (i = 0; i < 4; i++) - { - a += (p[i]-q[i])*(p[i]-q[i]); - b += (p[i]+q[i])*(p[i]+q[i]); - } - if (a > b) - { - for (i = 0; i < 4; i++) - { - q[i] = -q[i]; - } - } - - cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3]; - - if ((1.0 + cosom) > 0.000001) - { - if ((1.0 - cosom) > 0.000001) - { - omega = acos( cosom ); - sinom = sin( omega ); - sclp = sin( (1.0 - t)*omega) / sinom; - sclq = sin( t*omega ) / sinom; - } - else - { - sclp = 1.0 - t; - sclq = t; - } - for (i = 0; i < 4; i++) { - qt[i] = sclp * p[i] + sclq * q[i]; - } - } - else - { - qt[0] = -q[1]; - qt[1] = q[0]; - qt[2] = -q[3]; - qt[3] = q[2]; - sclp = sin( (1.0 - t) * (0.5 * M_PI)); - sclq = sin( t * (0.5 * M_PI)); - for (i = 0; i < 3; i++) - { - qt[i] = sclp * p[i] + sclq * qt[i]; - } - } -} - -/* -==================== -QuaternionMatrix - -==================== -*/ -void QuaternionMatrix( vec4_t quaternion, float (*matrix)[4] ) -{ - matrix[0][0] = 1.0 - 2.0 * quaternion[1] * quaternion[1] - 2.0 * quaternion[2] * quaternion[2]; - matrix[1][0] = 2.0 * quaternion[0] * quaternion[1] + 2.0 * quaternion[3] * quaternion[2]; - matrix[2][0] = 2.0 * quaternion[0] * quaternion[2] - 2.0 * quaternion[3] * quaternion[1]; - - matrix[0][1] = 2.0 * quaternion[0] * quaternion[1] - 2.0 * quaternion[3] * quaternion[2]; - matrix[1][1] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[2] * quaternion[2]; - matrix[2][1] = 2.0 * quaternion[1] * quaternion[2] + 2.0 * quaternion[3] * quaternion[0]; - - matrix[0][2] = 2.0 * quaternion[0] * quaternion[2] + 2.0 * quaternion[3] * quaternion[1]; - matrix[1][2] = 2.0 * quaternion[1] * quaternion[2] - 2.0 * quaternion[3] * quaternion[0]; - matrix[2][2] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[1] * quaternion[1]; -} - -/* -==================== -MatrixCopy - -==================== -*/ -void MatrixCopy( float in[3][4], float out[3][4] ) -{ - memcpy( out, in, sizeof( float ) * 3 * 4 ); -} \ No newline at end of file diff --git a/dmc/cl_dll/studio_util.h b/dmc/cl_dll/studio_util.h deleted file mode 100644 index aa8dcf6..0000000 --- a/dmc/cl_dll/studio_util.h +++ /dev/null @@ -1,40 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( STUDIO_UTIL_H ) -#define STUDIO_UTIL_H -#if defined( WIN32 ) -#pragma once -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -#ifndef PITCH -// MOVEMENT INFO -// up / down -#define PITCH 0 -// left / right -#define YAW 1 -// fall over -#define ROLL 2 -#endif - -#define FDotProduct( a, b ) (fabs((a[0])*(b[0])) + fabs((a[1])*(b[1])) + fabs((a[2])*(b[2]))) - -void AngleMatrix (const float *angles, float (*matrix)[4] ); -int VectorCompare (const float *v1, const float *v2); -void CrossProduct (const float *v1, const float *v2, float *cross); -void VectorTransform (const float *in1, float in2[3][4], float *out); -void ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]); -void MatrixCopy( float in[3][4], float out[3][4] ); -void QuaternionMatrix( vec4_t quaternion, float (*matrix)[4] ); -void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt ); -void AngleQuaternion( float *angles, vec4_t quaternion ); - -#endif // STUDIO_UTIL_H \ No newline at end of file diff --git a/dmc/cl_dll/text_message.cpp b/dmc/cl_dll/text_message.cpp deleted file mode 100644 index 721c245..0000000 --- a/dmc/cl_dll/text_message.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// text_message.cpp -// -// implementation of CHudTextMessage class -// -// this class routes messages through titles.txt for localisation -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE( m_TextMessage, TextMsg ); - -int CHudTextMessage::Init(void) -{ - HOOK_MESSAGE( TextMsg ); - - gHUD.AddHudElem( this ); - - Reset(); - - return 1; -}; - -// Searches through the string for any msg names (indicated by a '#') -// any found are looked up in titles.txt and the new message substituted -// the new value is pushed into dst_buffer -char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size ) -{ - char *dst = dst_buffer; - for ( char *src = (char*)msg; *src != 0 && buffer_size > 0; buffer_size-- ) - { - if ( *src == '#' ) - { - // cut msg name out of string - static char word_buf[255]; - char *wdst = word_buf, *word_start = src; - for ( ++src ; (*src >= 'A' && *src <= 'z') || (*src >= '0' && *src <= '9'); wdst++, src++ ) - { - *wdst = *src; - } - *wdst = 0; - - // lookup msg name in titles.txt - client_textmessage_t *clmsg = TextMessageGet( word_buf ); - if ( !clmsg || !(clmsg->pMessage) ) - { - src = word_start; - *dst = *src; - dst++, src++; - continue; - } - - // copy string into message over the msg name - for ( char *wsrc = (char*)clmsg->pMessage; *wsrc != 0; wsrc++, dst++ ) - { - *dst = *wsrc; - } - *dst = 0; - } - else - { - *dst = *src; - dst++, src++; - *dst = 0; - } - } - - dst_buffer[buffer_size-1] = 0; // ensure null termination - return dst_buffer; -} - -// As above, but with a local static buffer -char *CHudTextMessage::BufferedLocaliseTextString( const char *msg ) -{ - static char dst_buffer[1024]; - return LocaliseTextString( msg, dst_buffer, 1024 ); -} - -// Simplified version of LocaliseTextString; assumes string is only one word -char *CHudTextMessage::LookupString( const char *msg, int *msg_dest ) -{ - if ( !msg ) - return ""; - - // '#' character indicates this is a reference to a string in titles.txt, and not the string itself - if ( msg[0] == '#' ) - { - // this is a message name, so look up the real message - client_textmessage_t *clmsg = TextMessageGet( msg+1 ); - - if ( !clmsg || !(clmsg->pMessage) ) - return (char*)msg; // lookup failed, so return the original string - - if ( msg_dest ) - { - // check to see if titles.txt info overrides msg destination - // if clmsg->effect is less than 0, then clmsg->effect holds -1 * message_destination - if ( clmsg->effect < 0 ) // - *msg_dest = -clmsg->effect; - } - - return (char*)clmsg->pMessage; - } - else - { // nothing special about this message, so just return the same string - return (char*)msg; - } -} - -void StripEndNewlineFromString( char *str ) -{ - int s = strlen( str ) - 1; - if ( str[s] == '\n' || str[s] == '\r' ) - str[s] = 0; -} - -// converts all '\r' characters to '\n', so that the engine can deal with the properly -// returns a pointer to str -char* ConvertCRtoNL( char *str ) -{ - for ( char *ch = str; *ch != 0; ch++ ) - if ( *ch == '\r' ) - *ch = '\n'; - return str; -} - -// Message handler for text messages -// displays a string, looking them up from the titles.txt file, which can be localised -// parameters: -// byte: message direction ( HUD_PRINTCONSOLE, HUD_PRINTNOTIFY, HUD_PRINTCENTER, HUD_PRINTTALK ) -// string: message -// optional parameters: -// string: message parameter 1 -// string: message parameter 2 -// string: message parameter 3 -// string: message parameter 4 -// any string that starts with the character '#' is a message name, and is used to look up the real message in titles.txt -// the next (optional) one to four strings are parameters for that string (which can also be message names if they begin with '#') -int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int msg_dest = READ_BYTE(); - -#define MSG_BUF_SIZE 128 - static char szBuf[6][MSG_BUF_SIZE]; - char *msg_text = LookupString( READ_STRING(), &msg_dest ); - msg_text = safe_strcpy( szBuf[0], msg_text, MSG_BUF_SIZE ); - - // keep reading strings and using C format strings for subsituting the strings into the localised text string - char *sstr1 = LookupString( READ_STRING() ); - sstr1 = safe_strcpy( szBuf[1], sstr1 , MSG_BUF_SIZE ); - StripEndNewlineFromString( sstr1 ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines - char *sstr2 = LookupString( READ_STRING() ); - sstr2 = safe_strcpy( szBuf[2], sstr2 , MSG_BUF_SIZE ); - StripEndNewlineFromString( sstr2 ); - char *sstr3 = LookupString( READ_STRING() ); - sstr3 = safe_strcpy( szBuf[3], sstr3 , MSG_BUF_SIZE ); - StripEndNewlineFromString( sstr3 ); - char *sstr4 = LookupString( READ_STRING() ); - sstr4 = safe_strcpy( szBuf[4], sstr4 , MSG_BUF_SIZE ); - StripEndNewlineFromString( sstr4 ); - char *psz = szBuf[5]; - - switch ( msg_dest ) - { - case HUD_PRINTCENTER: - safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); - CenterPrint( ConvertCRtoNL( psz ) ); - break; - - case HUD_PRINTNOTIFY: - psz[0] = 1; // mark this message to go into the notify buffer - safe_sprintf( psz+1, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); - ConsolePrint( ConvertCRtoNL( psz ) ); - break; - - case HUD_PRINTTALK: - safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); - gHUD.m_SayText.SayTextPrint( ConvertCRtoNL( psz ), 128 ); - break; - - case HUD_PRINTCONSOLE: - safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); - ConsolePrint( ConvertCRtoNL( psz ) ); - break; - } - - return 1; -} diff --git a/dmc/cl_dll/train.cpp b/dmc/cl_dll/train.cpp deleted file mode 100644 index 0286c68..0000000 --- a/dmc/cl_dll/train.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// Train.cpp -// -// implementation of CHudAmmo class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE(m_Train, Train ) - - -int CHudTrain::Init(void) -{ - HOOK_MESSAGE( Train ); - - m_iPos = 0; - m_iFlags = 0; - gHUD.AddHudElem(this); - - return 1; -}; - -int CHudTrain::VidInit(void) -{ - m_hSprite = 0; - - return 1; -}; - -int CHudTrain::Draw(float fTime) -{ - if ( !m_hSprite ) - m_hSprite = LoadSprite("sprites/%d_train.spr"); - - if (m_iPos) - { - int r, g, b, x, y; - - UnpackRGB(r,g,b, RGB_YELLOWISH); - SPR_Set(m_hSprite, r, g, b ); - - // This should show up to the right and part way up the armor number - y = ScreenHeight - SPR_Height(m_hSprite,0) - gHUD.m_iFontHeight; - x = ScreenWidth/3 + SPR_Width(m_hSprite,0)/4; - - SPR_DrawAdditive( m_iPos - 1, x, y, NULL); - - } - - return 1; -} - - -int CHudTrain::MsgFunc_Train(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - // update Train data - m_iPos = READ_BYTE(); - - if (m_iPos) - m_iFlags |= HUD_ACTIVE; - else - m_iFlags &= ~HUD_ACTIVE; - - return 1; -} diff --git a/dmc/cl_dll/tri.cpp b/dmc/cl_dll/tri.cpp deleted file mode 100644 index 7746bd1..0000000 --- a/dmc/cl_dll/tri.cpp +++ /dev/null @@ -1,129 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// Triangle rendering, if any - -#include "hud.h" -#include "cl_util.h" - -// Triangle rendering apis are in gEngfuncs.pTriAPI - -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "triangleapi.h" - -extern "C" -{ - void DLLEXPORT HUD_DrawNormalTriangles( void ); - void DLLEXPORT HUD_DrawTransparentTriangles( void ); -}; - -extern float g_iFogColor[3]; -extern float g_iStartDist; -extern float g_iEndDist; -extern int g_iWaterLevel; - -//#define TEST_IT -#if defined( TEST_IT ) - -/* -================= -Draw_Triangles - -Example routine. Draws a sprite offset from the player origin. -================= -*/ -void Draw_Triangles( void ) -{ - cl_entity_t *player; - vec3_t org; - - // Load it up with some bogus data - player = gEngfuncs.GetLocalPlayer(); - if ( !player ) - return; - - org = player->origin; - - org.x += 50; - org.y += 50; - - if (gHUD.m_hsprCursor == 0) - { - char sz[256]; - sprintf( sz, "sprites/cursor.spr" ); - gHUD.m_hsprCursor = SPR_Load( sz ); - } - - if ( !gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *)gEngfuncs.GetSpritePointer( gHUD.m_hsprCursor ), 0 )) - { - return; - } - - // Create a triangle, sigh - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); - gEngfuncs.pTriAPI->CullFace( TRI_NONE ); - gEngfuncs.pTriAPI->Begin( TRI_QUADS ); - // Overload p->color with index into tracer palette, p->packedColor with brightness - gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 1.0 ); - // UNDONE: This gouraud shading causes tracers to disappear on some cards (permedia2) - gEngfuncs.pTriAPI->Brightness( 1 ); - gEngfuncs.pTriAPI->TexCoord2f( 0, 0 ); - gEngfuncs.pTriAPI->Vertex3f( org.x, org.y, org.z ); - - gEngfuncs.pTriAPI->Brightness( 1 ); - gEngfuncs.pTriAPI->TexCoord2f( 0, 1 ); - gEngfuncs.pTriAPI->Vertex3f( org.x, org.y + 50, org.z ); - - gEngfuncs.pTriAPI->Brightness( 1 ); - gEngfuncs.pTriAPI->TexCoord2f( 1, 1 ); - gEngfuncs.pTriAPI->Vertex3f( org.x + 50, org.y + 50, org.z ); - - gEngfuncs.pTriAPI->Brightness( 1 ); - gEngfuncs.pTriAPI->TexCoord2f( 1, 0 ); - gEngfuncs.pTriAPI->Vertex3f( org.x + 50, org.y, org.z ); - - gEngfuncs.pTriAPI->End(); - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); -} - -#endif - -//Render fog ( duh ). -void RenderFog ( void ) -{ - //Not in water and we want fog. - bool bFog = g_iWaterLevel < 2 && g_iStartDist >= 0 && g_iEndDist >= 0; - gEngfuncs.pTriAPI->Fog ( g_iFogColor, g_iStartDist, g_iEndDist, bFog ); -} - - -/* -================= -HUD_DrawNormalTriangles - -Non-transparent triangles-- add them here -================= -*/ -void DLLEXPORT HUD_DrawNormalTriangles( void ) -{ - gHUD.m_Spectator.DrawOverview(); -} - -/* -================= -HUD_DrawTransparentTriangles - -Render any triangles with transparent rendermode needs here -================= -*/ -void DLLEXPORT HUD_DrawTransparentTriangles( void ) -{ - - RenderFog(); -} diff --git a/dmc/cl_dll/util.cpp b/dmc/cl_dll/util.cpp deleted file mode 100644 index 1bbfce2..0000000 --- a/dmc/cl_dll/util.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// util.cpp -// -// implementation of class-less helper functions -// - -#include -#include -#include - -#include "hud.h" -#include "cl_util.h" -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -vec3_t vec3_origin( 0, 0, 0 ); - -HSPRITE LoadSprite(const char *pszName) -{ - int i; - char sz[256]; - - if (ScreenWidth < 640) - i = 320; - else - i = 640; - - sprintf(sz, pszName, i); - - return SPR_Load(sz); -} - diff --git a/dmc/cl_dll/util.h b/dmc/cl_dll/util.h deleted file mode 100644 index 706d694..0000000 --- a/dmc/cl_dll/util.h +++ /dev/null @@ -1,148 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// util.h -// - -#include "cvardef.h" - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -// Macros to hook function calls into the HUD object -#define HOOK_MESSAGE(x) gEngfuncs.pfnHookUserMsg(#x, __MsgFunc_##x ); - -#define DECLARE_MESSAGE(y, x) int __MsgFunc_##x(const char *pszName, int iSize, void *pbuf) \ - { \ - return gHUD.##y.MsgFunc_##x(pszName, iSize, pbuf ); \ - } - - -#define HOOK_COMMAND(x, y) gEngfuncs.pfnAddCommand( x, __CmdFunc_##y ); -#define DECLARE_COMMAND(y, x) void __CmdFunc_##x( void ) \ - { \ - gHUD.##y.UserCmd_##x( ); \ - } - -inline float CVAR_GET_FLOAT( const char *x ) { return gEngfuncs.pfnGetCvarFloat( (char*)x ); } -inline char* CVAR_GET_STRING( const char *x ) { return gEngfuncs.pfnGetCvarString( (char*)x ); } -inline struct cvar_s *CVAR_CREATE( const char *cv, const char *val, const int flags ) { return gEngfuncs.pfnRegisterVariable( (char*)cv, (char*)val, flags ); } - -#define SPR_Load (*gEngfuncs.pfnSPR_Load) -#define SPR_Set (*gEngfuncs.pfnSPR_Set) -#define SPR_Frames (*gEngfuncs.pfnSPR_Frames) -#define SPR_GetList (*gEngfuncs.pfnSPR_GetList) - -// SPR_Draw draws a the current sprite as solid -#define SPR_Draw (*gEngfuncs.pfnSPR_Draw) -// SPR_DrawHoles draws the current sprites, with color index255 not drawn (transparent) -#define SPR_DrawHoles (*gEngfuncs.pfnSPR_DrawHoles) -// SPR_DrawAdditive adds the sprites RGB values to the background (additive transulency) -#define SPR_DrawAdditive (*gEngfuncs.pfnSPR_DrawAdditive) - -// SPR_EnableScissor sets a clipping rect for HUD sprites. (0,0) is the top-left hand corner of the screen. -#define SPR_EnableScissor (*gEngfuncs.pfnSPR_EnableScissor) -// SPR_DisableScissor disables the clipping rect -#define SPR_DisableScissor (*gEngfuncs.pfnSPR_DisableScissor) -// -#define FillRGBA (*gEngfuncs.pfnFillRGBA) - - -// ScreenHeight returns the height of the screen, in pixels -#define ScreenHeight (gHUD.m_scrinfo.iHeight) -// ScreenWidth returns the width of the screen, in pixels -#define ScreenWidth (gHUD.m_scrinfo.iWidth) - -#define GetScreenInfo (*gEngfuncs.pfnGetScreenInfo) -#define ServerCmd (*gEngfuncs.pfnServerCmd) -#define ClientCmd (*gEngfuncs.pfnClientCmd) -#define SetCrosshair (*gEngfuncs.pfnSetCrosshair) -#define AngleVectors (*gEngfuncs.pfnAngleVectors) - - -// Gets the height & width of a sprite, at the specified frame -inline int SPR_Height( HSPRITE x, int f ) { return gEngfuncs.pfnSPR_Height(x, f); } -inline int SPR_Width( HSPRITE x, int f ) { return gEngfuncs.pfnSPR_Width(x, f); } - -inline client_textmessage_t *TextMessageGet( const char *pName ) { return gEngfuncs.pfnTextMessageGet( pName ); } -inline int TextMessageDrawChar( int x, int y, int number, int r, int g, int b ) -{ - return gEngfuncs.pfnDrawCharacter( x, y, number, r, g, b ); -} - -inline int DrawConsoleString( int x, int y, const char *string ) -{ - return gEngfuncs.pfnDrawConsoleString( x, y, (char*) string ); -} - -inline void GetConsoleStringSize( const char *string, int *width, int *height ) -{ - gEngfuncs.pfnDrawConsoleStringLen( string, width, height ); -} - -inline int ConsoleStringLen( const char *string ) -{ - int _width, _height; - GetConsoleStringSize( string, &_width, &_height ); - return _width; -} - -inline void ConsolePrint( const char *string ) -{ - gEngfuncs.pfnConsolePrint( string ); -} - -inline void CenterPrint( const char *string ) -{ - gEngfuncs.pfnCenterPrint( string ); -} - -// returns the players name of entity no. -#define GetPlayerInfo (*gEngfuncs.pfnGetPlayerInfo) - -// sound functions -inline void PlaySound( char *szSound, float vol ) { gEngfuncs.pfnPlaySoundByName( szSound, vol ); } -inline void PlaySound( int iSound, float vol ) { gEngfuncs.pfnPlaySoundByIndex( iSound, vol ); } - -void ScaleColors( int &r, int &g, int &b, int a ); - -#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) -#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];} -#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];} -#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];} -#define VectorClear(a) { a[0]=0.0;a[1]=0.0;a[2]=0.0;} -float Length(const float *v); -void VectorMA (const float *veca, float scale, const float *vecb, float *vecc); -void VectorScale (const float *in, float scale, float *out); -float VectorNormalize (float *v); -void VectorInverse ( float *v ); - -extern vec3_t vec3_origin; - -// disable 'possible loss of data converting float to int' warning message -#pragma warning( disable: 4244 ) -// disable 'truncation from 'const double' to 'float' warning message -#pragma warning( disable: 4305 ) - -inline void UnpackRGB(int &r, int &g, int &b, unsigned long ulRGB)\ -{\ - r = (ulRGB & 0xFF0000) >>16;\ - g = (ulRGB & 0xFF00) >> 8;\ - b = ulRGB & 0xFF;\ -} - -HSPRITE LoadSprite(const char *pszName); diff --git a/dmc/cl_dll/util_vector.h b/dmc/cl_dll/util_vector.h deleted file mode 100644 index fdac17c..0000000 --- a/dmc/cl_dll/util_vector.h +++ /dev/null @@ -1,121 +0,0 @@ -/*** -* -* 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. -* -****/ -// Vector.h -// A subset of the extdll.h in the project HL Entity DLL -// - -// Misc C-runtime library headers -#include "stdio.h" -#include "stdlib.h" -#include "math.h" - -// Header file containing definition of globalvars_t and entvars_t -typedef unsigned int func_t; // -typedef unsigned int string_t; // from engine's pr_comp.h; -typedef float vec_t; // needed before including progdefs.h - -//========================================================= -// 2DVector - used for many pathfinding and many other -// operations that are treated as planar rather than 3d. -//========================================================= -class Vector2D -{ -public: - inline Vector2D(void) { } - inline Vector2D(float X, float Y) { x = X; y = Y; } - inline Vector2D operator+(const Vector2D& v) const { return Vector2D(x+v.x, y+v.y); } - inline Vector2D operator-(const Vector2D& v) const { return Vector2D(x-v.x, y-v.y); } - inline Vector2D operator*(float fl) const { return Vector2D(x*fl, y*fl); } - inline Vector2D operator/(float fl) const { return Vector2D(x/fl, y/fl); } - - inline float Length(void) const { return (float)sqrt(x*x + y*y ); } - - inline Vector2D Normalize ( void ) const - { - Vector2D vec2; - - float flLen = Length(); - if ( flLen == 0 ) - { - return Vector2D( (float)0, (float)0 ); - } - else - { - flLen = 1 / flLen; - return Vector2D( x * flLen, y * flLen ); - } - } - - vec_t x, y; -}; - -inline float DotProduct(const Vector2D& a, const Vector2D& b) { return( a.x*b.x + a.y*b.y ); } -inline Vector2D operator*(float fl, const Vector2D& v) { return v * fl; } - -//========================================================= -// 3D Vector -//========================================================= -class Vector // same data-layout as engine's vec3_t, -{ // which is a vec_t[3] -public: - // Construction/destruction - inline Vector(void) { } - inline Vector(float X, float Y, float Z) { x = X; y = Y; z = Z; } - inline Vector(double X, double Y, double Z) { x = (float)X; y = (float)Y; z = (float)Z; } - inline Vector(int X, int Y, int Z) { x = (float)X; y = (float)Y; z = (float)Z; } - inline Vector(const Vector& v) { x = v.x; y = v.y; z = v.z; } - inline Vector(float rgfl[3]) { x = rgfl[0]; y = rgfl[1]; z = rgfl[2]; } - - // Operators - inline Vector operator-(void) const { return Vector(-x,-y,-z); } - inline int operator==(const Vector& v) const { return x==v.x && y==v.y && z==v.z; } - inline int operator!=(const Vector& v) const { return !(*this==v); } - inline Vector operator+(const Vector& v) const { return Vector(x+v.x, y+v.y, z+v.z); } - inline Vector operator-(const Vector& v) const { return Vector(x-v.x, y-v.y, z-v.z); } - inline Vector operator*(float fl) const { return Vector(x*fl, y*fl, z*fl); } - inline Vector operator/(float fl) const { return Vector(x/fl, y/fl, z/fl); } - - // Methods - inline void CopyToArray(float* rgfl) const { rgfl[0] = x, rgfl[1] = y, rgfl[2] = z; } - inline float Length(void) const { return (float)sqrt(x*x + y*y + z*z); } - operator float *() { return &x; } // Vectors will now automatically convert to float * when needed - operator const float *() const { return &x; } // Vectors will now automatically convert to float * when needed - inline Vector Normalize(void) const - { - float flLen = Length(); - if (flLen == 0) return Vector(0,0,1); // ???? - flLen = 1 / flLen; - return Vector(x * flLen, y * flLen, z * flLen); - } - - inline Vector2D Make2D ( void ) const - { - Vector2D Vec2; - - Vec2.x = x; - Vec2.y = y; - - return Vec2; - } - inline float Length2D(void) const { return (float)sqrt(x*x + y*y); } - - // Members - vec_t x, y, z; -}; -inline Vector operator*(float fl, const Vector& v) { return v * fl; } -inline float DotProduct(const Vector& a, const Vector& b) { return(a.x*b.x+a.y*b.y+a.z*b.z); } -inline Vector CrossProduct(const Vector& a, const Vector& b) { return Vector( a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x ); } - -#define vec3_t Vector diff --git a/dmc/cl_dll/vgui_ControlConfigPanel.h b/dmc/cl_dll/vgui_ControlConfigPanel.h deleted file mode 100644 index 4c413a0..0000000 --- a/dmc/cl_dll/vgui_ControlConfigPanel.h +++ /dev/null @@ -1,47 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef CONTROLCONFIGPANEL_H -#define CONTROLCONFIGPANEL_H - -#include -#include - -namespace vgui -{ -class HeaderPanel; -class TablePanel; -class ScrollPanel; -class InputStream; -class Label; -} - -class ControlConfigPanel : public vgui::Panel -{ -private: - vgui::HeaderPanel* _headerPanel; - vgui::TablePanel* _tablePanel; - vgui::ScrollPanel* _scrollPanel; - vgui::Dar _cvarDar; - vgui::Dar _descDar; - vgui::Label* _actionLabel; - vgui::Label* _keyButtonLabel; - vgui::Label* _alternateLabel; -public: - ControlConfigPanel(int x,int y,int wide,int tall); -public: - void AddCVar(const char* cvar,const char* desc); - void AddCVarFromInputStream(vgui::InputStream* is); - int GetCVarCount(); - void GetCVar(int index,char* cvar,int cvarLen,char* desc,int descLen); - void GetCVarBind(const char* cvar,char* bind,int bindLen,char* bindAlt,int bindAltLen); - void SetCVarBind(const char* cvar,const char* bind,const char* bindAlt); -}; - - - -#endif \ No newline at end of file diff --git a/dmc/cl_dll/vgui_CustomObjects.cpp b/dmc/cl_dll/vgui_CustomObjects.cpp deleted file mode 100644 index 9a6beb1..0000000 --- a/dmc/cl_dll/vgui_CustomObjects.cpp +++ /dev/null @@ -1,428 +0,0 @@ -//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Contains implementation of various VGUI-derived objects -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "VGUI_Font.h" - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "parsemsg.h" - -#include "vgui_int.h" -#include "vgui_viewport.h" -#include "vgui_ServerBrowser.h" -#include "VGUI_BitmapTGA.h" - - -// Arrow filenames -char *sArrowFilenames[] = -{ - "arrowup", - "arrowdn", - "arrowlt", - "arrowrt", -}; - - -//----------------------------------------------------------------------------- -// Purpose: Loads a .tga file and returns a pointer to the VGUI tga object -//----------------------------------------------------------------------------- -BitmapTGA *LoadTGA( const char* pImageName ) -{ - BitmapTGA *pTGA; - - char sz[256]; - sprintf(sz, "%%d_%s", pImageName); - - // Load the Image - FileInputStream* fis = new FileInputStream( GetVGUITGAName(sz), false ); - pTGA = new BitmapTGA(fis,true); - fis->close(); - - return pTGA; -} - -//=========================================================== -// All TFC Hud buttons are derived from this one. -CommandButton::CommandButton( const char* text,int x,int y,int wide,int tall, bool bNoHighlight) : Button("",x,y,wide,tall) -{ - m_iPlayerClass = 0; - m_bNoHighlight = bNoHighlight; - Init(); - setText( text ); -} - -CommandButton::CommandButton( int iPlayerClass, const char* text,int x,int y,int wide,int tall) : Button("",x,y,wide,tall) -{ - m_iPlayerClass = iPlayerClass; - m_bNoHighlight = false; - Init(); - setText( text ); -} - -void CommandButton::Init( void ) -{ - m_pSubMenu = NULL; - m_pSubLabel = NULL; - m_pParentMenu = NULL; - - // Set text color to orange - setFgColor(Scheme::sc_primary1); - - // left align - setContentAlignment( vgui::Label::a_west ); - - // Add the Highlight signal - if (!m_bNoHighlight) - addInputSignal( new CHandler_CommandButtonHighlight(this) ); - - // not bound to any button yet - m_cBoundKey = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: Prepends the button text with the current bound key -// if no bound key, then a clear space ' ' instead -//----------------------------------------------------------------------------- -void CommandButton::RecalculateText( void ) -{ - char szBuf[128]; - - if ( m_cBoundKey != 0 ) - { - if ( m_cBoundKey == (char)255 ) - { - strcpy( szBuf, m_sMainText ); - } - else - { - sprintf( szBuf, " %c %s", m_cBoundKey, m_sMainText ); - } - szBuf[MAX_BUTTON_SIZE-1] = 0; - } - else - { - // just draw a space if no key bound - sprintf( szBuf, " %s", m_sMainText ); - szBuf[MAX_BUTTON_SIZE-1] = 0; - } - - Button::setText( szBuf ); -} - -void CommandButton::setText( const char *text ) -{ - strncpy( m_sMainText, text, MAX_BUTTON_SIZE ); - m_sMainText[MAX_BUTTON_SIZE-1] = 0; - - RecalculateText(); -} - -void CommandButton::setBoundKey( char boundKey ) -{ - m_cBoundKey = boundKey; - RecalculateText(); -} - -char CommandButton::getBoundKey( void ) -{ - return m_cBoundKey; -} - -void CommandButton::AddSubMenu( CCommandMenu *pNewMenu ) -{ - m_pSubMenu = pNewMenu; - - // Prevent this button from being pushed - setMouseClickEnabled( MOUSE_LEFT, false ); -} - -void CommandButton::UpdateSubMenus( int iAdjustment ) -{ - if ( m_pSubMenu ) - m_pSubMenu->RecalculatePositions( iAdjustment ); -} - -void CommandButton::paint() -{ - // Make the sub label paint the same as the button - if ( m_pSubLabel ) - { - if ( isSelected() ) - m_pSubLabel->PushDown(); - else - m_pSubLabel->PushUp(); - } - - // draw armed button text in white - if ( isArmed() ) - { - setFgColor( Scheme::sc_secondary2 ); - } - else - { - setFgColor( Scheme::sc_primary1 ); - } - - Button::paint(); -} - -void CommandButton::paintBackground() -{ - if ( isArmed() ) - { - // Orange highlight background - drawSetColor( Scheme::sc_primary2 ); - drawFilledRect(0,0,_size[0],_size[1]); - } - - // Orange Border - drawSetColor( Scheme::sc_secondary1 ); - drawOutlinedRect(0,0,_size[0],_size[1]); -} - -//----------------------------------------------------------------------------- -// Purpose: Highlights the current button, and all it's parent menus -//----------------------------------------------------------------------------- -void CommandButton::cursorEntered( void ) -{ - // unarm all the other buttons in this menu - CCommandMenu *containingMenu = getParentMenu(); - if ( containingMenu ) - { - containingMenu->ClearButtonsOfArmedState(); - - // make all our higher buttons armed - CCommandMenu *pCParent = containingMenu->GetParentMenu(); - if ( pCParent ) - { - CommandButton *pParentButton = pCParent->FindButtonWithSubmenu( containingMenu ); - - pParentButton->cursorEntered(); - } - } - - // arm ourselves - setArmed( true ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CommandButton::cursorExited( void ) -{ - // only clear ourselves if we have do not have a containing menu - // only stay armed if we have a sub menu - // the buttons only unarm themselves when another button is armed instead - if ( !getParentMenu() || !GetSubMenu() ) - { - setArmed( false ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Returns the command menu that the button is part of, if any -// Output : CCommandMenu * -//----------------------------------------------------------------------------- -CCommandMenu *CommandButton::getParentMenu( void ) -{ - return m_pParentMenu; -} - -//----------------------------------------------------------------------------- -// Purpose: Sets the menu that contains this button -// Input : *pParentMenu - -//----------------------------------------------------------------------------- -void CommandButton::setParentMenu( CCommandMenu *pParentMenu ) -{ - m_pParentMenu = pParentMenu; -} - - -//=========================================================== -int ClassButton::IsNotValid() -{ - return false; -} - -//=========================================================== -// Button with Class image beneath it -CImageLabel::CImageLabel( const char* pImageName,int x,int y ) : Label( "", x,y ) -{ - setContentFitted(true); - m_pTGA = LoadTGA(pImageName); - setImage( m_pTGA ); -} - -CImageLabel::CImageLabel( const char* pImageName,int x,int y,int wide,int tall ) : Label( "", x,y,wide,tall ) -{ - setContentFitted(true); - m_pTGA = LoadTGA(pImageName); - setImage( m_pTGA ); -} - -//=========================================================== -// Image size -int CImageLabel::getImageWide( void ) -{ - int iXSize, iYSize; - m_pTGA->getSize( iXSize, iYSize ); - return iXSize; -} - -int CImageLabel::getImageTall( void ) -{ - int iXSize, iYSize; - m_pTGA->getSize( iXSize, iYSize ); - return iYSize; -} - -//=========================================================== -// Various overloaded paint functions for Custom VGUI objects -void CCommandMenu::paintBackground() -{ - // Transparent black background - drawSetColor(Scheme::sc_primary3); - drawFilledRect(0,0,_size[0],_size[1]); -} - -//================================================================================= -// CUSTOM SCROLLPANEL -//================================================================================= -CTFScrollButton::CTFScrollButton(int iArrow, const char* text,int x,int y,int wide,int tall) : CommandButton(text,x,y,wide,tall) -{ - // Set text color to orange - setFgColor(Scheme::sc_primary1); - - // Load in the arrow - m_pTGA = LoadTGA( sArrowFilenames[iArrow] ); - setImage( m_pTGA ); - - // Highlight signal - InputSignal *pISignal = new CHandler_CommandButtonHighlight(this); - addInputSignal(pISignal); -} - -void CTFScrollButton::paint( void ) -{ - // draw armed button text in white - if ( isArmed() ) - { - m_pTGA->setColor( Color(255,255,255, 0) ); - } - else - { - m_pTGA->setColor( Color(255,255,255, 128) ); - } - - m_pTGA->doPaint(this); -} - -void CTFScrollButton::paintBackground( void ) -{ -/* - if ( isArmed() ) - { - // Orange highlight background - drawSetColor( Scheme::sc_primary2 ); - drawFilledRect(0,0,_size[0],_size[1]); - } - - // Orange Border - drawSetColor( Scheme::sc_secondary1 ); - drawOutlinedRect(0,0,_size[0]-1,_size[1]); -*/ -} - -void CTFSlider::paintBackground( void ) -{ - int wide,tall,nobx,noby; - getPaintSize(wide,tall); - getNobPos(nobx,noby); - - // Border - drawSetColor( Scheme::sc_secondary1 ); - drawOutlinedRect( 0,0,wide,tall ); - - if( isVertical() ) - { - // Nob Fill - drawSetColor( Scheme::sc_primary2 ); - drawFilledRect( 0,nobx,wide,noby ); - - // Nob Outline - drawSetColor( Scheme::sc_primary1 ); - drawOutlinedRect( 0,nobx,wide,noby ); - } - else - { - // Nob Fill - drawSetColor( Scheme::sc_primary2 ); - drawFilledRect( nobx,0,noby,tall ); - - // Nob Outline - drawSetColor( Scheme::sc_primary1 ); - drawOutlinedRect( nobx,0,noby,tall ); - } -} - -CTFScrollPanel::CTFScrollPanel(int x,int y,int wide,int tall) : ScrollPanel(x,y,wide,tall) -{ - ScrollBar *pScrollBar = getVerticalScrollBar(); - pScrollBar->setButton( new CTFScrollButton( ARROW_UP, "", 0,0,16,16 ), 0 ); - pScrollBar->setButton( new CTFScrollButton( ARROW_DOWN, "", 0,0,16,16 ), 1 ); - pScrollBar->setSlider( new CTFSlider(0,wide-1,wide,(tall-(wide*2))+2,true) ); - pScrollBar->setPaintBorderEnabled(false); - pScrollBar->setPaintBackgroundEnabled(false); - pScrollBar->setPaintEnabled(false); - - pScrollBar = getHorizontalScrollBar(); - pScrollBar->setButton( new CTFScrollButton( ARROW_LEFT, "", 0,0,16,16 ), 0 ); - pScrollBar->setButton( new CTFScrollButton( ARROW_RIGHT, "", 0,0,16,16 ), 1 ); - pScrollBar->setSlider( new CTFSlider(tall,0,wide-(tall*2),tall,false) ); - pScrollBar->setPaintBorderEnabled(false); - pScrollBar->setPaintBackgroundEnabled(false); - pScrollBar->setPaintEnabled(false); -} - - -//================================================================================= -// CUSTOM HANDLERS -//================================================================================= -void CHandler_MenuButtonOver::cursorEntered(Panel *panel) -{ - if ( gViewPort && m_pMenuPanel ) - { - m_pMenuPanel->SetActiveInfo( m_iButton ); - } -} - -void CMenuHandler_StringCommandClassSelect::actionPerformed(Panel* panel) -{ - CMenuHandler_StringCommand::actionPerformed( panel ); - - bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0; - -} - diff --git a/dmc/cl_dll/vgui_MOTDWindow.cpp b/dmc/cl_dll/vgui_MOTDWindow.cpp deleted file mode 100644 index 66d09b4..0000000 --- a/dmc/cl_dll/vgui_MOTDWindow.cpp +++ /dev/null @@ -1,153 +0,0 @@ -//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "VGUI_Font.h" -#include "VGUI_ScrollPanel.h" -#include "VGUI_TextImage.h" - -#include - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "const.h" - -#include "vgui_int.h" -#include "vgui_viewport.h" -#include "vgui_ServerBrowser.h" - -#define MOTD_TITLE_X XRES(16) -#define MOTD_TITLE_Y YRES(16) - -#define MOTD_WINDOW_X XRES(112) -#define MOTD_WINDOW_Y YRES(80) -#define MOTD_WINDOW_SIZE_X XRES(424) -#define MOTD_WINDOW_SIZE_Y YRES(312) - -//----------------------------------------------------------------------------- -// Purpose: Displays the MOTD and basic server information -//----------------------------------------------------------------------------- -class CMessageWindowPanel : public CMenuPanel -{ -public: - CMessageWindowPanel( const char *szMOTD, const char *szTitle, int iShadeFullScreen, int iRemoveMe, int x, int y, int wide, int tall ); - -private: - CTransparentPanel *m_pBackgroundPanel; - -}; - -//----------------------------------------------------------------------------- -// Purpose: Creates a new CMessageWindowPanel -// Output : CMenuPanel - interface to the panel -//----------------------------------------------------------------------------- -CMenuPanel *CMessageWindowPanel_Create( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall ) -{ - return new CMessageWindowPanel( szMOTD, szTitle, iShadeFullscreen, iRemoveMe, x, y, wide, tall ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructs a message panel -//----------------------------------------------------------------------------- -CMessageWindowPanel::CMessageWindowPanel( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall ) : CMenuPanel( iShadeFullscreen ? 100 : 255, iRemoveMe, x, y, wide, tall ) -{ - // Get the scheme used for the Titles - CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); - - // schemes - SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" ); - SchemeHandle_t hMOTDText = pSchemes->getSchemeHandle( "Briefing Text" ); - - // color schemes - int r, g, b, a; - - // Create the window - m_pBackgroundPanel = new CTransparentPanel( iShadeFullscreen ? 255 : 100, MOTD_WINDOW_X, MOTD_WINDOW_Y, MOTD_WINDOW_SIZE_X, MOTD_WINDOW_SIZE_Y ); - m_pBackgroundPanel->setParent( this ); - m_pBackgroundPanel->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0)) ); - m_pBackgroundPanel->setVisible( true ); - - int iXSize,iYSize,iXPos,iYPos; - m_pBackgroundPanel->getPos( iXPos,iYPos ); - m_pBackgroundPanel->getSize( iXSize,iYSize ); - - // Create the title - Label *pLabel = new Label( "", iXPos + MOTD_TITLE_X, iYPos + MOTD_TITLE_Y ); - pLabel->setParent( this ); - pLabel->setFont( pSchemes->getFont(hTitleScheme) ); - pLabel->setFont( Scheme::sf_primary1 ); - - pSchemes->getFgColor( hTitleScheme, r, g, b, a ); - pLabel->setFgColor( r, g, b, a ); - pLabel->setFgColor( Scheme::sc_primary1 ); - pSchemes->getBgColor( hTitleScheme, r, g, b, a ); - pLabel->setBgColor( r, g, b, a ); - pLabel->setContentAlignment( vgui::Label::a_west ); - pLabel->setText(szTitle); - - // Create the Scroll panel - ScrollPanel *pScrollPanel = new CTFScrollPanel( iXPos + XRES(16), iYPos + MOTD_TITLE_Y*2 + YRES(16), iXSize - XRES(32), iYSize - (YRES(48) + BUTTON_SIZE_Y*2) ); - pScrollPanel->setParent(this); - //force the scrollbars on so clientClip will take them in account after the validate - pScrollPanel->setScrollBarAutoVisible(false, false); - pScrollPanel->setScrollBarVisible(true, true); - pScrollPanel->validate(); - - // Create the text panel - TextPanel *pText = new TextPanel( "", 0,0, 64,64); - pText->setParent( pScrollPanel->getClient() ); - - // get the font and colors from the scheme - pText->setFont( pSchemes->getFont(hMOTDText) ); - pSchemes->getFgColor( hMOTDText, r, g, b, a ); - pText->setFgColor( r, g, b, a ); - pSchemes->getBgColor( hMOTDText, r, g, b, a ); - pText->setBgColor( r, g, b, a ); - pText->setText(szMOTD); - - // Get the total size of the MOTD text and resize the text panel - int iScrollSizeX, iScrollSizeY; - - // First, set the size so that the client's wdith is correct at least because the - // width is critical for getting the "wrapped" size right. - // You'll see a horizontal scroll bar if there is a single word that won't wrap in the - // specified width. - pText->getTextImage()->setSize(pScrollPanel->getClientClip()->getWide(), pScrollPanel->getClientClip()->getTall()); - pText->getTextImage()->getTextSizeWrapped( iScrollSizeX, iScrollSizeY ); - - // Now resize the textpanel to fit the scrolled size - pText->setSize( iScrollSizeX , iScrollSizeY ); - - //turn the scrollbars back into automode - pScrollPanel->setScrollBarAutoVisible(true, true); - pScrollPanel->setScrollBarVisible(false, false); - - pScrollPanel->validate(); - - CommandButton *pButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_OK" ), iXPos + XRES(16), iYPos + iYSize - YRES(16) - BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_TextWindow(HIDE_TEXTWINDOW)); - pButton->setParent(this); - -} - - - - - - diff --git a/dmc/cl_dll/vgui_SchemeManager.cpp b/dmc/cl_dll/vgui_SchemeManager.cpp deleted file mode 100644 index dddd268..0000000 --- a/dmc/cl_dll/vgui_SchemeManager.cpp +++ /dev/null @@ -1,556 +0,0 @@ -//=========== (C) Copyright 1996-2002 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "hud.h" -#include "vgui_SchemeManager.h" -#include "cvardef.h" - -#include - - -cvar_t *g_CV_BitmapFonts; - - -void Scheme_Init() -{ - g_CV_BitmapFonts = gEngfuncs.pfnRegisterVariable("bitmapfonts", "1", 0); -} - - - -//----------------------------------------------------------------------------- -// Purpose: Scheme managers data container -//----------------------------------------------------------------------------- -class CSchemeManager::CScheme -{ -public: - enum { - SCHEME_NAME_LENGTH = 32, - FONT_NAME_LENGTH = 48, - FONT_FILENAME_LENGTH = 64, - }; - - // name - char schemeName[SCHEME_NAME_LENGTH]; - - // font - char fontName[FONT_NAME_LENGTH]; - - int fontSize; - int fontWeight; - - vgui::Font *font; - int ownFontPointer; // true if the font is ours to delete - - // scheme - byte fgColor[4]; - byte bgColor[4]; - byte armedFgColor[4]; - byte armedBgColor[4]; - byte mousedownFgColor[4]; - byte mousedownBgColor[4]; - byte borderColor[4]; - - // construction/destruction - CScheme(); - ~CScheme(); -}; - -CSchemeManager::CScheme::CScheme() -{ - schemeName[0] = 0; - fontName[0] = 0; - fontSize = 0; - fontWeight = 0; - font = NULL; - ownFontPointer = false; -} - -CSchemeManager::CScheme::~CScheme() -{ - // only delete our font pointer if we own it - if ( ownFontPointer ) - { - delete font; - } -} - -//----------------------------------------------------------------------------- -// Purpose: resolution information -// !! needs to be shared out -//----------------------------------------------------------------------------- -static int g_ResArray[] = -{ - 320, - 400, - 512, - 640, - 800, - 1024, - 1152, - 1280, - 1600 -}; -static int g_NumReses = sizeof(g_ResArray) / sizeof(int); - -static byte *LoadFileByResolution( const char *filePrefix, int xRes, const char *filePostfix ) -{ - // find our resolution in the res array - int resNum = g_NumReses - 1; - while ( g_ResArray[resNum] > xRes ) - { - resNum--; - - if ( resNum < 0 ) - return NULL; - } - - // try open the file - byte *pFile = NULL; - while ( 1 ) - { - - // try load - char fname[256]; - sprintf( fname, "%s%d%s", filePrefix, g_ResArray[resNum], filePostfix ); - pFile = gEngfuncs.COM_LoadFile( fname, 5, NULL ); - - if ( pFile ) - break; - - if ( resNum == 0 ) - return NULL; - - resNum--; - }; - - return pFile; -} - -static void ParseRGBAFromString( byte colorArray[4], const char *colorVector ) -{ - int r, g, b, a; - sscanf( colorVector, "%d %d %d %d", &r, &g, &b, &a ); - colorArray[0] = r; - colorArray[1] = g; - colorArray[2] = b; - colorArray[3] = a; -} - -//----------------------------------------------------------------------------- -// Purpose: initializes the scheme manager -// loading the scheme files for the current resolution -// Input : xRes - -// yRes - dimensions of output window -//----------------------------------------------------------------------------- -CSchemeManager::CSchemeManager( int xRes, int yRes ) -{ - // basic setup - m_pSchemeList = NULL; - m_iNumSchemes = 0; - - // find the closest matching scheme file to our resolution - char token[1024]; - char *pFile = (char*)LoadFileByResolution( "", xRes, "_textscheme.txt" ); - m_xRes = xRes; - - char *pFileStart = pFile; - - byte *pFontData; - int fontFileLength; - char fontFilename[512]; - - // - // Read the scheme descriptions from the text file, into a temporary array - // format is simply: - // = - // - // a of "SchemeName" signals a new scheme is being described - // - - const static int numTmpSchemes = 64; - static CScheme tmpSchemes[numTmpSchemes]; - memset( tmpSchemes, 0, sizeof(tmpSchemes) ); - int currentScheme = -1; - CScheme *pScheme = NULL; - - if ( !pFile ) - { - gEngfuncs.Con_DPrintf( "Unable to find *_textscheme.txt\n"); - goto buildDefaultFont; - } - - // record what has been entered so we can create defaults from the different values - bool hasFgColor, hasBgColor, hasArmedFgColor, hasArmedBgColor, hasMouseDownFgColor, hasMouseDownBgColor; - - pFile = gEngfuncs.COM_ParseFile( pFile, token ); - while ( strlen(token) > 0 && (currentScheme < numTmpSchemes) ) - { - // get the paramName name - static const int tokenSize = 64; - char paramName[tokenSize], paramValue[tokenSize]; - - strncpy( paramName, token, tokenSize ); - paramName[tokenSize-1] = 0; // ensure null termination - - // get the '=' character - pFile = gEngfuncs.COM_ParseFile( pFile, token ); - if ( stricmp( token, "=" ) ) - { - if ( currentScheme < 0 ) - { - gEngfuncs.Con_Printf( "error parsing font scheme text file at file start - expected '=', found '%s''\n", token ); - } - else - { - gEngfuncs.Con_Printf( "error parsing font scheme text file at scheme '%s' - expected '=', found '%s''\n", tmpSchemes[currentScheme].schemeName, token ); - } - break; - } - - // get paramValue - pFile = gEngfuncs.COM_ParseFile( pFile, token ); - strncpy( paramValue, token, tokenSize ); - paramValue[tokenSize-1] = 0; // ensure null termination - - // is this a new scheme? - if ( !stricmp(paramName, "SchemeName") ) - { - // setup the defaults for the current scheme - if ( pScheme ) - { - // foreground color defaults (normal -> armed -> mouse down) - if ( !hasFgColor ) - { - pScheme->fgColor[0] = pScheme->fgColor[1] = pScheme->fgColor[2] = pScheme->fgColor[3] = 255; - } - if ( !hasArmedFgColor ) - { - memcpy( pScheme->armedFgColor, pScheme->fgColor, sizeof(pScheme->armedFgColor) ); - } - if ( !hasMouseDownFgColor ) - { - memcpy( pScheme->mousedownFgColor, pScheme->armedFgColor, sizeof(pScheme->mousedownFgColor) ); - } - - // background color (normal -> armed -> mouse down) - if ( !hasBgColor ) - { - pScheme->bgColor[0] = pScheme->bgColor[1] = pScheme->bgColor[2] = pScheme->bgColor[3] = 0; - } - if ( !hasArmedBgColor ) - { - memcpy( pScheme->armedBgColor, pScheme->bgColor, sizeof(pScheme->armedBgColor) ); - } - if ( !hasMouseDownBgColor ) - { - memcpy( pScheme->mousedownBgColor, pScheme->armedBgColor, sizeof(pScheme->mousedownBgColor) ); - } - - // font size - if ( !pScheme->fontSize ) - { - pScheme->fontSize = 17; - } - if ( !pScheme->fontName[0] ) - { - strcpy( pScheme->fontName, "Arial" ); - } - } - - // create the new scheme - currentScheme++; - pScheme = &tmpSchemes[currentScheme]; - hasFgColor = hasBgColor = hasArmedFgColor = hasArmedBgColor = hasMouseDownFgColor = hasMouseDownBgColor = false; - - strncpy( pScheme->schemeName, paramValue, CScheme::SCHEME_NAME_LENGTH ); - pScheme->schemeName[CScheme::SCHEME_NAME_LENGTH-1] = '\0'; // ensure null termination of string - } - - if ( !pScheme ) - { - gEngfuncs.Con_Printf( "font scheme text file MUST start with a 'SchemeName'\n"); - break; - } - - // pull the data out into the scheme - if ( !stricmp(paramName, "FontName") ) - { - strncpy( pScheme->fontName, paramValue, CScheme::FONT_NAME_LENGTH ); - pScheme->fontName[CScheme::FONT_NAME_LENGTH-1] = 0; - } - else if ( !stricmp(paramName, "FontSize") ) - { - pScheme->fontSize = atoi( paramValue ); - } - else if ( !stricmp(paramName, "FontWeight") ) - { - pScheme->fontWeight = atoi( paramValue ); - } - else if ( !stricmp(paramName, "FgColor") ) - { - ParseRGBAFromString( pScheme->fgColor, paramValue ); - hasFgColor = true; - } - else if ( !stricmp(paramName, "BgColor") ) - { - ParseRGBAFromString( pScheme->bgColor, paramValue ); - hasBgColor = true; - } - else if ( !stricmp(paramName, "FgColorArmed") ) - { - ParseRGBAFromString( pScheme->armedFgColor, paramValue ); - hasArmedFgColor = true; - } - else if ( !stricmp(paramName, "BgColorArmed") ) - { - ParseRGBAFromString( pScheme->armedBgColor, paramValue ); - hasArmedBgColor = true; - } - else if ( !stricmp(paramName, "FgColorMousedown") ) - { - ParseRGBAFromString( pScheme->mousedownFgColor, paramValue ); - hasMouseDownFgColor = true; - } - else if ( !stricmp(paramName, "BgColorMousedown") ) - { - ParseRGBAFromString( pScheme->mousedownBgColor, paramValue ); - hasMouseDownBgColor = true; - } - else if ( !stricmp(paramName, "BorderColor") ) - { - ParseRGBAFromString( pScheme->borderColor, paramValue ); - hasMouseDownBgColor = true; - } - - // get the new token last, so we now if the loop needs to be continued or not - pFile = gEngfuncs.COM_ParseFile( pFile, token ); - } - - // free the file - gEngfuncs.COM_FreeFile( pFileStart ); - - -buildDefaultFont: - - // make sure we have at least 1 valid font - if ( currentScheme < 0 ) - { - currentScheme = 0; - strcpy( tmpSchemes[0].schemeName, "Default Scheme" ); - strcpy( tmpSchemes[0].fontName, "Arial" ); - tmpSchemes[0].fontSize = 0; - tmpSchemes[0].fgColor[0] = tmpSchemes[0].fgColor[1] = tmpSchemes[0].fgColor[2] = tmpSchemes[0].fgColor[3] = 255; - tmpSchemes[0].armedFgColor[0] = tmpSchemes[0].armedFgColor[1] = tmpSchemes[0].armedFgColor[2] = tmpSchemes[0].armedFgColor[3] = 255; - tmpSchemes[0].mousedownFgColor[0] = tmpSchemes[0].mousedownFgColor[1] = tmpSchemes[0].mousedownFgColor[2] = tmpSchemes[0].mousedownFgColor[3] = 255; - } - - // we have the full list of schemes in the tmpSchemes array - // now allocate the correct sized list - m_iNumSchemes = currentScheme + 1; // 0-based index - m_pSchemeList = new CScheme[ m_iNumSchemes ]; - - // copy in the data - memcpy( m_pSchemeList, tmpSchemes, sizeof(CScheme) * m_iNumSchemes ); - - // create the fonts - for ( int i = 0; i < m_iNumSchemes; i++ ) - { - m_pSchemeList[i].font = NULL; - - // see if the current font values exist in a previously loaded font - for ( int j = 0; j < i; j++ ) - { - // check if the font name, size, and weight are the same - if ( !stricmp(m_pSchemeList[i].fontName, m_pSchemeList[j].fontName) - && m_pSchemeList[i].fontSize == m_pSchemeList[j].fontSize - && m_pSchemeList[i].fontWeight == m_pSchemeList[j].fontWeight ) - { - // copy the pointer, but mark i as not owning it - m_pSchemeList[i].font = m_pSchemeList[j].font; - m_pSchemeList[i].ownFontPointer = false; - } - } - - // if we haven't found the font already, load it ourselves - if ( !m_pSchemeList[i].font ) - { - fontFileLength = -1; - pFontData = NULL; - - if(g_CV_BitmapFonts && g_CV_BitmapFonts->value) - { - int fontRes = 640; - if ( m_xRes >= 1600 ) - fontRes = 1600; - else if ( m_xRes >= 1280 ) - fontRes = 1280; - else if ( m_xRes >= 1152 ) - fontRes = 1152; - else if ( m_xRes >= 1024 ) - fontRes = 1024; - else if ( m_xRes >= 800 ) - fontRes = 800; - - sprintf(fontFilename, "gfx\\vgui\\fonts\\%d_%s.tga", fontRes, m_pSchemeList[i].schemeName); - pFontData = gEngfuncs.COM_LoadFile( fontFilename, 5, &fontFileLength ); - if(!pFontData) - gEngfuncs.Con_Printf("Missing bitmap font: %s\n", fontFilename); - } - - m_pSchemeList[i].font = new vgui::Font( - m_pSchemeList[i].fontName, - pFontData, - fontFileLength, - m_pSchemeList[i].fontSize, - 0, - 0, - m_pSchemeList[i].fontWeight, - false, - false, - false, - false); - - m_pSchemeList[i].ownFontPointer = true; - } - - // fix up alpha values; VGUI uses 1-A (A=0 being solid, A=255 transparent) - m_pSchemeList[i].fgColor[3] = 255 - m_pSchemeList[i].fgColor[3]; - m_pSchemeList[i].bgColor[3] = 255 - m_pSchemeList[i].bgColor[3]; - m_pSchemeList[i].armedFgColor[3] = 255 - m_pSchemeList[i].armedFgColor[3]; - m_pSchemeList[i].armedBgColor[3] = 255 - m_pSchemeList[i].armedBgColor[3]; - m_pSchemeList[i].mousedownFgColor[3] = 255 - m_pSchemeList[i].mousedownFgColor[3]; - m_pSchemeList[i].mousedownBgColor[3] = 255 - m_pSchemeList[i].mousedownBgColor[3]; - } -} - -//----------------------------------------------------------------------------- -// Purpose: frees all the memory used by the scheme manager -//----------------------------------------------------------------------------- -CSchemeManager::~CSchemeManager() -{ - delete [] m_pSchemeList; - m_iNumSchemes = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: Finds a scheme in the list, by name -// Input : char *schemeName - string name of the scheme -// Output : SchemeHandle_t handle to the scheme -//----------------------------------------------------------------------------- -SchemeHandle_t CSchemeManager::getSchemeHandle( const char *schemeName ) -{ - // iterate through the list - for ( int i = 0; i < m_iNumSchemes; i++ ) - { - if ( !stricmp(schemeName, m_pSchemeList[i].schemeName) ) - return i; - } - - return 0; -} - -//----------------------------------------------------------------------------- -// Purpose: always returns a valid scheme handle -// Input : schemeHandle - -// Output : CScheme -//----------------------------------------------------------------------------- -CSchemeManager::CScheme *CSchemeManager::getSafeScheme( SchemeHandle_t schemeHandle ) -{ - if ( schemeHandle < m_iNumSchemes ) - return m_pSchemeList + schemeHandle; - - return m_pSchemeList; -} - - -//----------------------------------------------------------------------------- -// Purpose: Returns the schemes pointer to a font -// Input : schemeHandle - -// Output : vgui::Font -//----------------------------------------------------------------------------- -vgui::Font *CSchemeManager::getFont( SchemeHandle_t schemeHandle ) -{ - return getSafeScheme( schemeHandle )->font; -} - -void CSchemeManager::getFgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->fgColor[0]; - g = pScheme->fgColor[1]; - b = pScheme->fgColor[2]; - a = pScheme->fgColor[3]; -} - -void CSchemeManager::getBgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->bgColor[0]; - g = pScheme->bgColor[1]; - b = pScheme->bgColor[2]; - a = pScheme->bgColor[3]; -} - -void CSchemeManager::getFgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->armedFgColor[0]; - g = pScheme->armedFgColor[1]; - b = pScheme->armedFgColor[2]; - a = pScheme->armedFgColor[3]; -} - -void CSchemeManager::getBgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->armedBgColor[0]; - g = pScheme->armedBgColor[1]; - b = pScheme->armedBgColor[2]; - a = pScheme->armedBgColor[3]; -} - -void CSchemeManager::getFgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->mousedownFgColor[0]; - g = pScheme->mousedownFgColor[1]; - b = pScheme->mousedownFgColor[2]; - a = pScheme->mousedownFgColor[3]; -} - -void CSchemeManager::getBgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->mousedownBgColor[0]; - g = pScheme->mousedownBgColor[1]; - b = pScheme->mousedownBgColor[2]; - a = pScheme->mousedownBgColor[3]; -} - -void CSchemeManager::getBorderColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->borderColor[0]; - g = pScheme->borderColor[1]; - b = pScheme->borderColor[2]; - a = pScheme->borderColor[3]; -} - - - diff --git a/dmc/cl_dll/vgui_SchemeManager.h b/dmc/cl_dll/vgui_SchemeManager.h deleted file mode 100644 index 0e7d99a..0000000 --- a/dmc/cl_dll/vgui_SchemeManager.h +++ /dev/null @@ -1,52 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include - -// handle to an individual scheme -typedef int SchemeHandle_t; - -// Register console variables, etc.. -void Scheme_Init(); - - -//----------------------------------------------------------------------------- -// Purpose: Handles the loading of text scheme description from disk -// supports different font/color/size schemes at different resolutions -//----------------------------------------------------------------------------- -class CSchemeManager -{ -public: - // initialization - CSchemeManager( int xRes, int yRes ); - virtual ~CSchemeManager(); - - // scheme handling - SchemeHandle_t getSchemeHandle( const char *schemeName ); - - // getting info from schemes - vgui::Font *getFont( SchemeHandle_t schemeHandle ); - void getFgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getBgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getFgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getBgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getFgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getBgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getBorderColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - -private: - class CScheme; - CScheme *m_pSchemeList; - int m_iNumSchemes; - - // Resolution we were initted at. - int m_xRes; - - CScheme *getSafeScheme( SchemeHandle_t schemeHandle ); -}; - - diff --git a/dmc/cl_dll/vgui_ScorePanel.cpp b/dmc/cl_dll/vgui_ScorePanel.cpp deleted file mode 100644 index c372496..0000000 --- a/dmc/cl_dll/vgui_ScorePanel.cpp +++ /dev/null @@ -1,1031 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: VGUI scoreboard -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - - -#include - -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "vgui_viewport.h" -#include "vgui_ScorePanel.h" -#include "voice_status.h" -#include "vgui_helpers.h" -#include "vgui_loadtga.h" - -extern int g_iTeamNumber; - -hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine -extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll -team_info_t g_TeamInfo[MAX_TEAMS+1]; -int g_IsSpectator[MAX_PLAYERS+1]; - -// Scoreboard dimensions -#define SBOARD_TITLE_SIZE_Y YRES(22) - -#define X_BORDER XRES(4) - -// Column sizes -class SBColumnInfo -{ -public: - char *m_pTitle; // If null, ignore, if starts with #, it's localized, otherwise use the string directly. - int m_Width; // Based on 640 width. Scaled to fit other resolutions. - Label::Alignment m_Alignment; -}; - -// grid size is marked out for 640x480 screen - -SBColumnInfo g_ColumnInfo[NUM_COLUMNS] = -{ - {NULL, 24, Label::a_east}, // tracker column - {NULL, 140, Label::a_west}, // name - {"#SCORE", 80, Label::a_east}, - {"#DEATHS", 46, Label::a_east}, - {"#LATENCY", 46, Label::a_east}, - {"#VOICE", 40, Label::a_east}, - {NULL, 2, Label::a_east}, // blank column to take up the slack -}; - - -#define TEAM_NO 0 -#define TEAM_YES 1 -#define TEAM_SPECTATORS 2 -#define TEAM_BLANK 3 - - -//----------------------------------------------------------------------------- -// ScorePanel::HitTestPanel. -//----------------------------------------------------------------------------- - -void ScorePanel::HitTestPanel::internalMousePressed(MouseCode code) -{ - for(int i=0;i<_inputSignalDar.getCount();i++) - { - _inputSignalDar[i]->mousePressed(code,this); - } -} - - - -//----------------------------------------------------------------------------- -// Purpose: Create the ScoreBoard panel -//----------------------------------------------------------------------------- -ScorePanel::ScorePanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall) -{ - CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); - SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle("Scoreboard Title Text"); - SchemeHandle_t hSmallScheme = pSchemes->getSchemeHandle("Scoreboard Small Text"); - Font *tfont = pSchemes->getFont(hTitleScheme); - Font *smallfont = pSchemes->getFont(hSmallScheme); - - setBgColor(0, 0, 0, 96); - m_pCurrentHighlightLabel = NULL; - m_iHighlightRow = -1; - - // Initialize the top title. - m_TitleLabel.setFont(tfont); - m_TitleLabel.setText(""); - m_TitleLabel.setBgColor( 0, 0, 0, 255 ); - m_TitleLabel.setFgColor( Scheme::sc_primary1 ); - m_TitleLabel.setContentAlignment( vgui::Label::a_west ); - - LineBorder *border = new LineBorder(Color(60, 60, 60, 128)); - setBorder(border); - setPaintBorderEnabled(true); - - int xpos = g_ColumnInfo[0].m_Width + 3; - if (ScreenWidth >= 640) - { - // only expand column size for res greater than 640 - xpos = XRES(xpos); - } - m_TitleLabel.setBounds(xpos, 4, wide, SBOARD_TITLE_SIZE_Y); - m_TitleLabel.setContentFitted(false); - m_TitleLabel.setParent(this); - - // Setup the header (labels like "name", "class", etc..). - m_HeaderGrid.SetDimensions(NUM_COLUMNS, 1); - m_HeaderGrid.SetSpacing(0, 0); - - for(int i=0; i < NUM_COLUMNS; i++) - { - if (g_ColumnInfo[i].m_pTitle && g_ColumnInfo[i].m_pTitle[0] == '#') - m_HeaderLabels[i].setText(CHudTextMessage::BufferedLocaliseTextString(g_ColumnInfo[i].m_pTitle)); - else if(g_ColumnInfo[i].m_pTitle) - m_HeaderLabels[i].setText(g_ColumnInfo[i].m_pTitle); - - int xwide = g_ColumnInfo[i].m_Width; - if (ScreenWidth >= 640) - { - xwide = XRES(xwide); - } - else if (ScreenWidth == 400) - { - // hack to make 400x300 resolution scoreboard fit - if (i == 1) - { - // reduces size of player name cell - xwide -= 28; - } - else if (i == 0) - { - // tracker icon cell - xwide -= 8; - } - } - - m_HeaderGrid.SetColumnWidth(i, xwide); - m_HeaderGrid.SetEntry(i, 0, &m_HeaderLabels[i]); - - m_HeaderLabels[i].setBgColor(0,0,0,255); - m_HeaderLabels[i].setFgColor(Scheme::sc_primary1); - m_HeaderLabels[i].setFont(smallfont); - m_HeaderLabels[i].setContentAlignment(g_ColumnInfo[i].m_Alignment); - - int yres = 12; - if (ScreenHeight >= 480) - { - yres = YRES(yres); - } - m_HeaderLabels[i].setSize(50, yres); - } - - // Set the width of the last column to be the remaining space. - int ex, ey, ew, eh; - m_HeaderGrid.GetEntryBox(NUM_COLUMNS - 2, 0, ex, ey, ew, eh); - m_HeaderGrid.SetColumnWidth(NUM_COLUMNS - 1, (wide - X_BORDER) - (ex + ew)); - - m_HeaderGrid.AutoSetRowHeights(); - m_HeaderGrid.setBounds(X_BORDER, SBOARD_TITLE_SIZE_Y, wide - X_BORDER*2, m_HeaderGrid.GetRowHeight(0)); - m_HeaderGrid.setParent(this); - m_HeaderGrid.setBgColor(0,0,0,255); - - - // Now setup the listbox with the actual player data in it. - int headerX, headerY, headerWidth, headerHeight; - m_HeaderGrid.getBounds(headerX, headerY, headerWidth, headerHeight); - m_PlayerList.setBounds(headerX, headerY+headerHeight, headerWidth, tall - headerY - headerHeight - 6); - m_PlayerList.setBgColor(0,0,0,255); - m_PlayerList.setParent(this); - - for(int row=0; row < NUM_ROWS; row++) - { - CGrid *pGridRow = &m_PlayerGrids[row]; - - pGridRow->SetDimensions(NUM_COLUMNS, 1); - - for(int col=0; col < NUM_COLUMNS; col++) - { - m_PlayerEntries[col][row].setContentFitted(false); - m_PlayerEntries[col][row].setRow(row); - m_PlayerEntries[col][row].addInputSignal(this); - pGridRow->SetEntry(col, 0, &m_PlayerEntries[col][row]); - } - - pGridRow->setBgColor(0,0,0,255); - pGridRow->SetSpacing(0, 0); - pGridRow->CopyColumnWidths(&m_HeaderGrid); - pGridRow->AutoSetRowHeights(); - pGridRow->setSize(PanelWidth(pGridRow), pGridRow->CalcDrawHeight()); - pGridRow->RepositionContents(); - - m_PlayerList.AddItem(pGridRow); - } - - - // Add the hit test panel. It is invisible and traps mouse clicks so we can go into squelch mode. - m_HitTestPanel.setBgColor(0,0,0,255); - m_HitTestPanel.setParent(this); - m_HitTestPanel.setBounds(0, 0, wide, tall); - m_HitTestPanel.addInputSignal(this); - - Initialize(); -} - - -//----------------------------------------------------------------------------- -// Purpose: Called each time a new level is started. -//----------------------------------------------------------------------------- -void ScorePanel::Initialize( void ) -{ - // Clear out scoreboard data - m_iLastKilledBy = 0; - m_fLastKillTime = 0; - m_iPlayerNum = 0; - m_iNumTeams = 0; - memset( g_PlayerExtraInfo, 0, sizeof g_PlayerExtraInfo ); - memset( g_TeamInfo, 0, sizeof g_TeamInfo ); -} - - -bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] ) -{ - return !!gEngfuncs.GetPlayerUniqueID( iPlayer, playerID ); -} - -//----------------------------------------------------------------------------- -// Purpose: Recalculate the internal scoreboard data -//----------------------------------------------------------------------------- -void ScorePanel::Update() -{ - int i; - - // Set the title - if (gViewPort->m_szServerName) - { - char sz[MAX_SERVERNAME_LENGTH + 16]; - sprintf(sz, "%s", gViewPort->m_szServerName ); - m_TitleLabel.setText(sz); - } - - m_iRows = 0; - gViewPort->GetAllPlayersInfo(); - - // Clear out sorts - for (i = 0; i < NUM_ROWS; i++) - { - m_iSortedRows[i] = 0; - m_iIsATeam[i] = TEAM_NO; - } - for (i = 0; i < MAX_PLAYERS; i++) - { - m_bHasBeenSorted[i] = false; - } - - // If it's not teamplay, sort all the players. Otherwise, sort the teams. - if ( !gHUD.m_Teamplay ) - SortPlayers( 0, NULL ); - else - SortTeams(); - - // set scrollbar range - m_PlayerList.SetScrollRange(m_iRows); - - FillGrid(); -} - -//----------------------------------------------------------------------------- -// Purpose: Sort all the teams -//----------------------------------------------------------------------------- -void ScorePanel::SortTeams() -{ - // clear out team scores - int i; - for ( i = 1; i <= m_iNumTeams; i++ ) - { - if ( !g_TeamInfo[i].scores_overriden ) - g_TeamInfo[i].frags = g_TeamInfo[i].deaths = 0; - g_TeamInfo[i].ping = g_TeamInfo[i].packetloss = 0; - } - - // recalc the team scores, then draw them - for ( i = 1; i < MAX_PLAYERS; i++ ) - { - if ( g_PlayerInfoList[i].name == NULL ) - continue; // empty player slot, skip - - if ( g_PlayerExtraInfo[i].teamname[0] == 0 ) - continue; // skip over players who are not in a team - - // find what team this player is in - int j; - for ( j = 1; j <= m_iNumTeams; j++ ) - { - if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) ) - break; - } - if ( j > m_iNumTeams ) // player is not in a team, skip to the next guy - continue; - - if ( !g_TeamInfo[j].scores_overriden ) - { - g_TeamInfo[j].frags += g_PlayerExtraInfo[i].frags; - g_TeamInfo[j].deaths += g_PlayerExtraInfo[i].deaths; - } - - g_TeamInfo[j].ping += g_PlayerInfoList[i].ping; - g_TeamInfo[j].packetloss += g_PlayerInfoList[i].packetloss; - - if ( g_PlayerInfoList[i].thisplayer ) - g_TeamInfo[j].ownteam = TRUE; - else - g_TeamInfo[j].ownteam = FALSE; - - // Set the team's number (used for team colors) - g_TeamInfo[j].teamnumber = g_PlayerExtraInfo[i].teamnumber; - } - - // find team ping/packetloss averages - for ( i = 1; i <= m_iNumTeams; i++ ) - { - g_TeamInfo[i].already_drawn = FALSE; - - if ( g_TeamInfo[i].players > 0 ) - { - g_TeamInfo[i].ping /= g_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping - g_TeamInfo[i].packetloss /= g_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping - } - } - - // Draw the teams - while ( 1 ) - { - int highest_frags = -99999; int lowest_deaths = 99999; - int best_team = 0; - - for ( i = 1; i <= m_iNumTeams; i++ ) - { - if ( g_TeamInfo[i].players < 1 ) - continue; - - if ( !g_TeamInfo[i].already_drawn && g_TeamInfo[i].frags >= highest_frags ) - { - if ( g_TeamInfo[i].frags > highest_frags || g_TeamInfo[i].deaths < lowest_deaths ) - { - best_team = i; - lowest_deaths = g_TeamInfo[i].deaths; - highest_frags = g_TeamInfo[i].frags; - } - } - } - - // draw the best team on the scoreboard - if ( !best_team ) - break; - - // Put this team in the sorted list - m_iSortedRows[ m_iRows ] = best_team; - m_iIsATeam[ m_iRows ] = TEAM_YES; - g_TeamInfo[best_team].already_drawn = TRUE; // set the already_drawn to be TRUE, so this team won't get sorted again - m_iRows++; - - // Now sort all the players on this team - SortPlayers( 0, g_TeamInfo[best_team].name ); - } - - // Add all the players who aren't in a team yet into spectators - SortPlayers( TEAM_SPECTATORS, NULL ); -} - -//----------------------------------------------------------------------------- -// Purpose: Sort a list of players -//----------------------------------------------------------------------------- -void ScorePanel::SortPlayers( int iTeam, char *team ) -{ - bool bCreatedTeam = false; - - // draw the players, in order, and restricted to team if set - while ( 1 ) - { - // Find the top ranking player - int highest_frags = -99999; int lowest_deaths = 99999; - int best_player; - best_player = 0; - - for ( int i = 1; i < MAX_PLAYERS; i++ ) - { - if ( m_bHasBeenSorted[i] == false && g_PlayerInfoList[i].name && g_PlayerExtraInfo[i].frags >= highest_frags ) - { - cl_entity_t *ent = gEngfuncs.GetEntityByIndex( i ); - - if ( ent && !(team && stricmp(g_PlayerExtraInfo[i].teamname, team)) ) - { - extra_player_info_t *pl_info = &g_PlayerExtraInfo[i]; - if ( pl_info->frags > highest_frags || pl_info->deaths < lowest_deaths ) - { - best_player = i; - lowest_deaths = pl_info->deaths; - highest_frags = pl_info->frags; - } - } - } - } - - if ( !best_player ) - break; - - // If we haven't created the Team yet, do it first - if (!bCreatedTeam && iTeam) - { - m_iIsATeam[ m_iRows ] = iTeam; - m_iRows++; - - bCreatedTeam = true; - } - - // Put this player in the sorted list - m_iSortedRows[ m_iRows ] = best_player; - m_bHasBeenSorted[ best_player ] = true; - m_iRows++; - } - - if (team) - { - m_iIsATeam[m_iRows++] = TEAM_BLANK; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Recalculate the existing teams in the match -//----------------------------------------------------------------------------- -void ScorePanel::RebuildTeams() -{ - // clear out player counts from teams - int i; - for ( i = 1; i <= m_iNumTeams; i++ ) - { - g_TeamInfo[i].players = 0; - } - - // rebuild the team list - gViewPort->GetAllPlayersInfo(); - m_iNumTeams = 0; - for ( i = 1; i < MAX_PLAYERS; i++ ) - { - if ( g_PlayerInfoList[i].name == NULL ) - continue; - - if ( g_PlayerExtraInfo[i].teamname[0] == 0 ) - continue; // skip over players who are not in a team - - // is this player in an existing team? - int j; - for ( j = 1; j <= m_iNumTeams; j++ ) - { - if ( g_TeamInfo[j].name[0] == '\0' ) - break; - - if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) ) - break; - } - - if ( j > m_iNumTeams ) - { // they aren't in a listed team, so make a new one - // search through for an empty team slot - for ( int j = 1; j <= m_iNumTeams; j++ ) - { - if ( g_TeamInfo[j].name[0] == '\0' ) - break; - } - m_iNumTeams = V_max( j, m_iNumTeams ); - - strncpy( g_TeamInfo[j].name, g_PlayerExtraInfo[i].teamname, MAX_TEAM_NAME ); - g_TeamInfo[j].players = 0; - } - - g_TeamInfo[j].players++; - } - - // clear out any empty teams - for ( i = 1; i <= m_iNumTeams; i++ ) - { - if ( g_TeamInfo[i].players < 1 ) - memset( &g_TeamInfo[i], 0, sizeof(team_info_t) ); - } - - // Update the scoreboard - Update(); -} - - -void ScorePanel::FillGrid() -{ - CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); - SchemeHandle_t hScheme = pSchemes->getSchemeHandle("Scoreboard Text"); - SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle("Scoreboard Title Text"); - SchemeHandle_t hSmallScheme = pSchemes->getSchemeHandle("Scoreboard Small Text"); - - Font *sfont = pSchemes->getFont(hScheme); - Font *tfont = pSchemes->getFont(hTitleScheme); - Font *smallfont = pSchemes->getFont(hSmallScheme); - - // update highlight position - int x, y; - getApp()->getCursorPos( x, y ); - screenToLocal( x, y ); - cursorMoved( x, y, this ); - - // remove highlight row if we're not in squelch mode - if (!GetClientVoiceMgr()->IsInSquelchMode()) - { - m_iHighlightRow = -1; - } - - bool bNextRowIsGap = false; - - int row; - for(row=0; row < NUM_ROWS; row++) - { - CGrid *pGridRow = &m_PlayerGrids[row]; - pGridRow->SetRowUnderline(0, false, 0, 0, 0, 0, 0); - - if(row >= m_iRows) - { - for(int col=0; col < NUM_COLUMNS; col++) - m_PlayerEntries[col][row].setVisible(false); - - continue; - } - - bool bRowIsGap = false; - if (bNextRowIsGap) - { - bNextRowIsGap = false; - bRowIsGap = true; - } - - for(int col=0; col < NUM_COLUMNS; col++) - { - CLabelHeader *pLabel = &m_PlayerEntries[col][row]; - - pLabel->setVisible(true); - pLabel->setText2(""); - pLabel->setImage(NULL); - pLabel->setFont(sfont); - pLabel->setTextOffset(0, 0); - - int rowheight = 13; - if (ScreenHeight > 480) - { - rowheight = YRES(rowheight); - } - else - { - // more tweaking, make sure icons fit at low res - rowheight = 15; - } - pLabel->setSize(pLabel->getWide(), rowheight); - pLabel->setBgColor(0, 0, 0, 255); - - char sz[128]; - hud_player_info_t *pl_info = NULL; - team_info_t *team_info = NULL; - - if (m_iIsATeam[row] == TEAM_BLANK) - { - pLabel->setText(" "); - continue; - } - else if ( m_iIsATeam[row] == TEAM_YES ) - { - // Get the team's data - team_info = &g_TeamInfo[ m_iSortedRows[row] ]; - - // team color text for team names - pLabel->setFgColor( iTeamColors[team_info->teamnumber][0], iTeamColors[team_info->teamnumber][1], iTeamColors[team_info->teamnumber][2], 0 ); - - // different height for team header rows - rowheight = 20; - if (ScreenHeight >= 480) - { - rowheight = YRES(rowheight); - } - pLabel->setSize(pLabel->getWide(), rowheight); - pLabel->setFont(tfont); - - pGridRow->SetRowUnderline(0, true, YRES(3), iTeamColors[team_info->teamnumber][0], iTeamColors[team_info->teamnumber][1], iTeamColors[team_info->teamnumber][2], 0); - } - else if ( m_iIsATeam[row] == TEAM_SPECTATORS ) - { - // grey text for spectators - pLabel->setFgColor(100, 100, 100, 0); - - // different height for team header rows - rowheight = 20; - if (ScreenHeight >= 480) - { - rowheight = YRES(rowheight); - } - pLabel->setSize(pLabel->getWide(), rowheight); - pLabel->setFont(tfont); - - pGridRow->SetRowUnderline(0, true, YRES(3), 100, 100, 100, 0); - } - else - { - // team color text for player names - pLabel->setFgColor( iTeamColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][0], iTeamColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][1], iTeamColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][2], 0 ); - - // Get the player's data - pl_info = &g_PlayerInfoList[ m_iSortedRows[row] ]; - - // Set background color - if ( pl_info->thisplayer ) // if it is their name, draw it a different color - { - // Highlight this player - pLabel->setFgColor(Scheme::sc_white); - pLabel->setBgColor( iTeamColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][0], iTeamColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][1], iTeamColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber ][2], 196 ); - } - else if ( m_iSortedRows[row] == m_iLastKilledBy && m_fLastKillTime && m_fLastKillTime > gHUD.m_flTime ) - { - // Killer's name - pLabel->setBgColor( 255,0,0, 255 - ((float)15 * (float)(m_fLastKillTime - gHUD.m_flTime)) ); - } - } - - // Align - if (col == COLUMN_NAME) - { - pLabel->setContentAlignment( vgui::Label::a_west ); - } - else if (col == COLUMN_TRACKER) - { - pLabel->setContentAlignment( vgui::Label::a_center ); - } - else - { - pLabel->setContentAlignment( vgui::Label::a_east ); - } - - // Fill out with the correct data - strcpy(sz, ""); - if ( m_iIsATeam[row] ) - { - char sz2[128]; - - switch (col) - { - case COLUMN_NAME: - if ( m_iIsATeam[row] == TEAM_SPECTATORS ) - { - sprintf( sz2, CHudTextMessage::BufferedLocaliseTextString( "#Spectators" ) ); - } - else - { - sprintf( sz2, CHudTextMessage::BufferedLocaliseTextString( team_info->name ) ); - } - - strcpy(sz, sz2); - - // Append the number of players - if ( m_iIsATeam[row] == TEAM_YES ) - { - if (team_info->players == 1) - { - sprintf(sz2, "(%d %s)", team_info->players, CHudTextMessage::BufferedLocaliseTextString( "#Player" ) ); - } - else - { - sprintf(sz2, "(%d %s)", team_info->players, CHudTextMessage::BufferedLocaliseTextString( "#Player_plural" ) ); - } - - pLabel->setText2(sz2); - pLabel->setFont2(smallfont); - } - break; - case COLUMN_VOICE: - break; - case COLUMN_KILLS: - if ( m_iIsATeam[row] == TEAM_YES ) - sprintf(sz, "%d", team_info->frags ); - break; - case COLUMN_DEATHS: - if ( m_iIsATeam[row] == TEAM_YES ) - sprintf(sz, "%d", team_info->deaths ); - break; - case COLUMN_LATENCY: - if ( m_iIsATeam[row] == TEAM_YES ) - sprintf(sz, "%d", team_info->ping ); - break; - default: - break; - } - } - else - { - bool bShowClass = false; - - switch (col) - { - case COLUMN_NAME: - sprintf(sz, "%s ", pl_info->name); - break; - case COLUMN_VOICE: - sz[0] = 0; - GetClientVoiceMgr()->UpdateSpeakerImage(pLabel, m_iSortedRows[row]); - break; - case COLUMN_KILLS: - sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].frags ); - break; - case COLUMN_DEATHS: - sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].deaths ); - break; - case COLUMN_LATENCY: - sprintf(sz, "%d", g_PlayerInfoList[ m_iSortedRows[row] ].ping ); - break; - default: - break; - } - } - - pLabel->setText(sz); - } - } - - for(row=0; row < NUM_ROWS; row++) - { - CGrid *pGridRow = &m_PlayerGrids[row]; - - pGridRow->AutoSetRowHeights(); - pGridRow->setSize(PanelWidth(pGridRow), pGridRow->CalcDrawHeight()); - pGridRow->RepositionContents(); - } - - // hack, for the thing to resize - m_PlayerList.getSize(x, y); - m_PlayerList.setSize(x, y); -} - - -//----------------------------------------------------------------------------- -// Purpose: Setup highlights for player names in scoreboard -//----------------------------------------------------------------------------- -void ScorePanel::DeathMsg( int killer, int victim ) -{ - // if we were the one killed, or the world killed us, set the scoreboard to indicate suicide - if ( victim == m_iPlayerNum || killer == 0 ) - { - m_iLastKilledBy = killer ? killer : m_iPlayerNum; - m_fLastKillTime = gHUD.m_flTime + 10; // display who we were killed by for 10 seconds - - if ( killer == m_iPlayerNum ) - m_iLastKilledBy = m_iPlayerNum; - } -} - - -void ScorePanel::Open( void ) -{ - RebuildTeams(); - setVisible(true); - m_HitTestPanel.setVisible(true); -} - - -void ScorePanel::mousePressed(MouseCode code, Panel* panel) -{ - if(gHUD.m_iIntermission) - return; - - if (!GetClientVoiceMgr()->IsInSquelchMode()) - { - GetClientVoiceMgr()->StartSquelchMode(); - m_HitTestPanel.setVisible(false); - } - else if (m_iHighlightRow >= 0) - { - // mouse has been pressed, toggle mute state - int iPlayer = m_iSortedRows[m_iHighlightRow]; - if (iPlayer > 0) - { - // print text message - hud_player_info_t *pl_info = &g_PlayerInfoList[iPlayer]; - - if (pl_info && pl_info->name && pl_info->name[0]) - { - char string[256]; - if (GetClientVoiceMgr()->IsPlayerBlocked(iPlayer)) - { - char string1[1024]; - - // remove mute - GetClientVoiceMgr()->SetPlayerBlockedState(iPlayer, false); - - sprintf( string1, CHudTextMessage::BufferedLocaliseTextString( "#Unmuted" ), pl_info->name ); - sprintf( string, "%c** %s\n", HUD_PRINTTALK, string1 ); - - gHUD.m_TextMessage.MsgFunc_TextMsg(NULL, strlen(string)+1, string ); - } - else - { - char string1[1024]; - char string2[1024]; - - // mute the player - GetClientVoiceMgr()->SetPlayerBlockedState(iPlayer, true); - - sprintf( string1, CHudTextMessage::BufferedLocaliseTextString( "#Muted" ), pl_info->name ); - sprintf( string2, CHudTextMessage::BufferedLocaliseTextString( "#No_longer_hear_that_player" ) ); - sprintf( string, "%c** %s %s\n", HUD_PRINTTALK, string1, string2 ); - - gHUD.m_TextMessage.MsgFunc_TextMsg(NULL, strlen(string)+1, string ); - } - } - } - } -} - - -void ScorePanel::cursorMoved(int x, int y, Panel *panel) -{ - // Translate from local coordinates to screen coordinates. - panel->localToScreen( x, y ); - - if (GetClientVoiceMgr()->IsInSquelchMode()) - { - // look for which cell the mouse is currently over - for (int i = 0; i < NUM_ROWS; i++) - { - int row, col; - if (m_PlayerGrids[i].getCellAtPoint(x, y, row, col)) - { - MouseOverCell(i, col); - return; - } - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Handles mouse movement over a cell -// Input : row - -// col - -//----------------------------------------------------------------------------- -void ScorePanel::MouseOverCell(int row, int col) -{ - CLabelHeader *label = &m_PlayerEntries[col][row]; - - // clear the previously highlighted label - if (m_pCurrentHighlightLabel != label) - { - m_pCurrentHighlightLabel = NULL; - m_iHighlightRow = -1; - } - if (!label) - return; - - // don't act on teams - if (m_iIsATeam[row] != TEAM_NO) - return; - - // don't act on disconnected players or ourselves - hud_player_info_t *pl_info = &g_PlayerInfoList[ m_iSortedRows[row] ]; - if (!pl_info->name || !pl_info->name[0]) - return; - - if (pl_info->thisplayer && !gEngfuncs.IsSpectateOnly() ) - return; - - // setup the new highlight - m_pCurrentHighlightLabel = label; - m_iHighlightRow = row; -} - -//----------------------------------------------------------------------------- -// Purpose: Label paint functions - take into account current highligh status -//----------------------------------------------------------------------------- -void CLabelHeader::paintBackground() -{ - Color oldBg; - getBgColor(oldBg); - - if (gViewPort->m_pScoreBoard->m_iHighlightRow == _row) - { - setBgColor(134, 91, 19, 0); - } - - Panel::paintBackground(); - - setBgColor(oldBg); -} - - -//----------------------------------------------------------------------------- -// Purpose: Label paint functions - take into account current highligh status -//----------------------------------------------------------------------------- -void CLabelHeader::paint() -{ - Color oldFg; - getFgColor(oldFg); - - if (gViewPort->m_pScoreBoard->m_iHighlightRow == _row) - { - setFgColor(255, 255, 255, 0); - } - - // draw text - int x, y, iwide, itall; - getTextSize(iwide, itall); - calcAlignment(iwide, itall, x, y); - _dualImage->setPos(x, y); - - int x1, y1; - _dualImage->GetImage(1)->getPos(x1, y1); - _dualImage->GetImage(1)->setPos(_gap, y1); - - _dualImage->doPaint(this); - - // get size of the panel and the image - if (_image) - { - _image->getSize(iwide, itall); - calcAlignment(iwide, itall, x, y); - _image->setPos(x, y); - _image->doPaint(this); - } - - setFgColor(oldFg[0], oldFg[1], oldFg[2], oldFg[3]); -} - - -void CLabelHeader::calcAlignment(int iwide, int itall, int &x, int &y) -{ - // calculate alignment ourselves, since vgui is so broken - int wide, tall; - getSize(wide, tall); - - x = 0, y = 0; - - // align left/right - switch (_contentAlignment) - { - // left - case Label::a_northwest: - case Label::a_west: - case Label::a_southwest: - { - x = 0; - break; - } - - // center - case Label::a_north: - case Label::a_center: - case Label::a_south: - { - x = (wide - iwide) / 2; - break; - } - - // right - case Label::a_northeast: - case Label::a_east: - case Label::a_southeast: - { - x = wide - iwide; - break; - } - } - - // top/down - switch (_contentAlignment) - { - // top - case Label::a_northwest: - case Label::a_north: - case Label::a_northeast: - { - y = 0; - break; - } - - // center - case Label::a_west: - case Label::a_center: - case Label::a_east: - { - y = (tall - itall) / 2; - break; - } - - // south - case Label::a_southwest: - case Label::a_south: - case Label::a_southeast: - { - y = tall - itall; - break; - } - } - -// don't clip to Y -// if (y < 0) -// { -// y = 0; -// } - if (x < 0) - { - x = 0; - } - - x += _offset[0]; - y += _offset[1]; -} diff --git a/dmc/cl_dll/vgui_ScorePanel.h b/dmc/cl_dll/vgui_ScorePanel.h deleted file mode 100644 index c7befe9..0000000 --- a/dmc/cl_dll/vgui_ScorePanel.h +++ /dev/null @@ -1,314 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef SCOREPANEL_H -#define SCOREPANEL_H - -#include -#include -#include -#include -#include -#include -#include "vgui_listbox.h" - -#include - -#define MAX_SCORES 10 -#define MAX_SCOREBOARD_TEAMS 5 - -// Scoreboard cells -#define COLUMN_TRACKER 0 -#define COLUMN_NAME 1 -#define COLUMN_KILLS 2 -#define COLUMN_DEATHS 3 -#define COLUMN_LATENCY 4 -#define COLUMN_VOICE 5 -#define COLUMN_BLANK 6 -#define NUM_COLUMNS 7 - -#define NUM_ROWS (MAX_PLAYERS + (MAX_SCOREBOARD_TEAMS * 2)) - -using namespace vgui; - -class CTextImage2 : public Image -{ -public: - CTextImage2() - { - _image[0] = new TextImage(""); - _image[1] = new TextImage(""); - } - - ~CTextImage2() - { - delete _image[0]; - delete _image[1]; - } - - TextImage *GetImage(int image) - { - return _image[image]; - } - - void getSize(int &wide, int &tall) - { - int w1, w2, t1, t2; - _image[0]->getTextSize(w1, t1); - _image[1]->getTextSize(w2, t2); - - wide = w1 + w2; - tall = V_max(t1, t2); - setSize(wide, tall); - } - - void doPaint(Panel *panel) - { - _image[0]->doPaint(panel); - _image[1]->doPaint(panel); - } - - void setPos(int x, int y) - { - _image[0]->setPos(x, y); - - int swide, stall; - _image[0]->getSize(swide, stall); - - int wide, tall; - _image[1]->getSize(wide, tall); - _image[1]->setPos(x + wide, y + (stall * 0.9) - tall); - } - - void setColor(Color color) - { - _image[0]->setColor(color); - } - - void setColor2(Color color) - { - _image[1]->setColor(color); - } - -private: - TextImage *_image[2]; - -}; - -//----------------------------------------------------------------------------- -// Purpose: Custom label for cells in the Scoreboard's Table Header -//----------------------------------------------------------------------------- -class CLabelHeader : public Label -{ -public: - CLabelHeader() : Label("") - { - _dualImage = new CTextImage2(); - _dualImage->setColor2(Color(255, 170, 0, 0)); - _row = -2; - _useFgColorAsImageColor = true; - _offset[0] = 0; - _offset[1] = 0; - } - - ~CLabelHeader() - { - delete _dualImage; - } - - void setRow(int row) - { - _row = row; - } - - void setFgColorAsImageColor(bool state) - { - _useFgColorAsImageColor = state; - } - - virtual void setText(int textBufferLen, const char* text) - { - _dualImage->GetImage(0)->setText(text); - - // calculate the text size - Font *font = _dualImage->GetImage(0)->getFont(); - _gap = 0; - for (const char *ch = text; *ch != 0; ch++) - { - int a, b, c; - font->getCharABCwide(*ch, a, b, c); - _gap += (a + b + c); - } - - _gap += XRES(5); - } - - virtual void setText(const char* text) - { - // strip any non-alnum characters from the end - char buf[512]; - strcpy(buf, text); - - int len = strlen(buf); - while (len && isspace(buf[--len])) - { - buf[len] = 0; - } - - CLabelHeader::setText(0, buf); - } - - void setText2(const char *text) - { - _dualImage->GetImage(1)->setText(text); - } - - void getTextSize(int &wide, int &tall) - { - _dualImage->getSize(wide, tall); - } - - void setFgColor(int r,int g,int b,int a) - { - Label::setFgColor(r,g,b,a); - Color color(r,g,b,a); - _dualImage->setColor(color); - _dualImage->setColor2(color); - if (_image && _useFgColorAsImageColor) - { - _image->setColor(color); - } - repaint(); - } - - void setFgColor(Scheme::SchemeColor sc) - { - Label::setFgColor(sc); - _dualImage->setColor(sc); - } - - void setFont(Font *font) - { - _dualImage->GetImage(0)->setFont(font); - } - - void setFont2(Font *font) - { - _dualImage->GetImage(1)->setFont(font); - } - - // this adjust the absolute position of the text after alignment is calculated - void setTextOffset(int x, int y) - { - _offset[0] = x; - _offset[1] = y; - } - - void paint(); - void paintBackground(); - void calcAlignment(int iwide, int itall, int &x, int &y); - -private: - CTextImage2 *_dualImage; - int _row; - int _gap; - int _offset[2]; - bool _useFgColorAsImageColor; -}; - -class ScoreTablePanel; - -#include "vgui_grid.h" -#include "vgui_defaultinputsignal.h" - -//----------------------------------------------------------------------------- -// Purpose: Scoreboard back panel -//----------------------------------------------------------------------------- -class ScorePanel : public Panel, public vgui::CDefaultInputSignal -{ -private: - // Default panel implementation doesn't forward mouse messages when there is no cursor and we need them. - class HitTestPanel : public Panel - { - public: - virtual void internalMousePressed(MouseCode code); - }; - - -private: - - Label m_TitleLabel; - - // Here is how these controls are arranged hierarchically. - // m_HeaderGrid - // m_HeaderLabels - - // m_PlayerGridScroll - // m_PlayerGrid - // m_PlayerEntries - - CGrid m_HeaderGrid; - CLabelHeader m_HeaderLabels[NUM_COLUMNS]; // Labels above the - CLabelHeader *m_pCurrentHighlightLabel; - int m_iHighlightRow; - - vgui::CListBox m_PlayerList; - CGrid m_PlayerGrids[NUM_ROWS]; // The grid with player and team info. - CLabelHeader m_PlayerEntries[NUM_COLUMNS][NUM_ROWS]; // Labels for the grid entries. - - ScorePanel::HitTestPanel m_HitTestPanel; - - CLabelHeader* GetPlayerEntry(int x, int y) {return &m_PlayerEntries[x][y];} - -public: - - int m_iNumTeams; - int m_iPlayerNum; - int m_iShowscoresHeld; - - int m_iRows; - int m_iSortedRows[NUM_ROWS]; - int m_iIsATeam[NUM_ROWS]; - bool m_bHasBeenSorted[MAX_PLAYERS]; - int m_iLastKilledBy; - int m_fLastKillTime; - - CImageLabel *m_pImages[ 7 ]; - - -public: - - ScorePanel(int x,int y,int wide,int tall); - - void Update( void ); - - void SortTeams( void ); - void SortPlayers( int iTeam, char *team ); - void RebuildTeams( void ); - - void FillGrid(); - - void DeathMsg( int killer, int victim ); - - void Initialize( void ); - - void Open( void ); - - void MouseOverCell(int row, int col); - - -// InputSignal overrides. -public: - - virtual void mousePressed(MouseCode code, Panel* panel); - virtual void cursorMoved(int x, int y, Panel *panel); - - friend class CLabelHeader; -}; - -#endif - diff --git a/dmc/cl_dll/vgui_ServerBrowser.cpp b/dmc/cl_dll/vgui_ServerBrowser.cpp deleted file mode 100644 index 428d0c4..0000000 --- a/dmc/cl_dll/vgui_ServerBrowser.cpp +++ /dev/null @@ -1,623 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include -#include -#include -#include -#include -#include - -#include "hud.h" -#include "cl_util.h" -#include "hud_servers.h" -#include "net_api.h" - -#include "vgui_viewport.h" -#include "vgui_ServerBrowser.h" - -using namespace vgui; - -namespace -{ - -#define MAX_SB_ROWS 24 - -#define NUM_COLUMNS 5 - -#define HEADER_SIZE_Y YRES(18) - -// Column sizes -#define CSIZE_ADDRESS XRES(200) -#define CSIZE_SERVER XRES(400) -#define CSIZE_MAP XRES(500) -#define CSIZE_CURRENT XRES(570) -#define CSIZE_PING XRES(640) - -#define CELL_HEIGHT YRES(15) - -class ServerBrowserTablePanel; - -class CBrowser_InputSignal : public InputSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; -public: - CBrowser_InputSignal( ServerBrowserTablePanel *pBrowser ) - { - m_pBrowser = pBrowser; - } - - virtual void cursorMoved(int x,int y,Panel* panel) {}; - virtual void cursorEntered(Panel* panel){}; - virtual void cursorExited(Panel* Panel) {}; - - virtual void mousePressed(MouseCode code,Panel* panel); - - virtual void mouseDoublePressed(MouseCode code,Panel* panel); - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -class ServerBrowserTablePanel : public TablePanel -{ -private: - Label *m_pLabel; - int m_nMouseOverRow; - -public: - - ServerBrowserTablePanel( int x,int y,int wide,int tall,int columnCount) : TablePanel( x,y,wide,tall,columnCount) - { - m_pLabel = new Label( "", 0, 0 /*,wide, tall*/ ); - - m_nMouseOverRow = 0; - } - -public: - void setMouseOverRow( int row ) - { - m_nMouseOverRow = row; - } - - void DoSort( char *sortkey ) - { - // Request server list and refresh servers... - SortServers( sortkey ); - } - - void DoRefresh( void ) - { - // Request server list and refresh servers... - ServersList(); - BroadcastServersList( 0 ); - } - - void DoBroadcastRefresh( void ) - { - // Request server list and refresh servers... - BroadcastServersList( 1 ); - } - - void DoStop( void ) - { - // Stop requesting - ServersCancel(); - } - - void DoCancel( void ) - { - ClientCmd( "togglebrowser\n" ); - } - - void DoConnect( void ) - { - const char *info; - const char *address; - char sz[ 256 ]; - - info = ServersGetInfo( m_nMouseOverRow ); - if ( !info ) - return; - - address = gEngfuncs.pNetAPI->ValueForKey( info, "address" ); - //gEngfuncs.Con_Printf( "Connecting to %s\n", address ); - - sprintf( sz, "connect %s\n", address ); - - ClientCmd( sz ); - - DoCancel(); - } - - void DoPing( void ) - { - ServerPing( 0 ); - ServerRules( 0 ); - ServerPlayers( 0 ); - } - - virtual int getRowCount() - { - int rowcount; - int height, width; - - getSize( width, height ); - - // Space for buttons - height -= YRES(20); - height = V_max( 0, height ); - - rowcount = height / CELL_HEIGHT; - - return rowcount; - } - - virtual int getCellTall(int row) - { - return CELL_HEIGHT - 2; - } - - virtual Panel* getCellRenderer(int column,int row,bool columnSelected,bool rowSelected,bool cellSelected) - { - const char *info; - const char *val, *val2; - char sz[ 32 ]; - - info = ServersGetInfo( row ); - - if ( row == m_nMouseOverRow ) - { - m_pLabel->setFgColor( 200, 240, 63, 100 ); - } - else - { - m_pLabel->setFgColor( 255, 255, 255, 0 ); - } - m_pLabel->setBgColor( 0, 0, 0, 200 ); - m_pLabel->setContentAlignment( vgui::Label::a_west ); - m_pLabel->setFont( Scheme::sf_primary2 ); - - if ( info ) - { - // Fill out with the correct data - switch ( column ) - { - case 0: - val = gEngfuncs.pNetAPI->ValueForKey( info, "address" ); - if ( val ) - { - strncpy( sz, val, 31 ); - sz[ 31 ] = '\0'; - // Server Name; - m_pLabel->setText( sz ); - } - break; - case 1: - val = gEngfuncs.pNetAPI->ValueForKey( info, "hostname" ); - if ( val ) - { - strncpy( sz, val, 31 ); - sz[ 31 ] = '\0'; - // Server Map; - m_pLabel->setText( sz ); - } - break; - case 2: - val = gEngfuncs.pNetAPI->ValueForKey( info, "map" ); - if ( val ) - { - strncpy( sz, val, 31 ); - sz[ 31 ] = '\0'; - // Server Name; - m_pLabel->setText( sz ); - } - break; - case 3: - val = gEngfuncs.pNetAPI->ValueForKey( info, "current" ); - val2 = gEngfuncs.pNetAPI->ValueForKey( info, "max" ); - if ( val && val2 ) - { - sprintf( sz, "%s/%s", val, val2 ); - sz[ 31 ] = '\0'; - // Server Map; - m_pLabel->setText( sz ); - } - break; - case 4: - val = gEngfuncs.pNetAPI->ValueForKey( info, "ping" ); - if ( val ) - { - strncpy( sz, val, 31 ); - sz[ 31 ] = '\0'; - // Server Name; - m_pLabel->setText( sz ); - } - break; - default: - break; - } - } - else - { - if ( !row && !column ) - { - if ( ServersIsQuerying() ) - { - m_pLabel->setText( "Waiting for servers to respond..." ); - } - else - { - m_pLabel->setText( "Press 'Refresh' to search for servers..." ); - } - } - else - { - m_pLabel->setText( "" ); - } - } - - return m_pLabel; - } - - virtual Panel* startCellEditing(int column,int row) - { - return null; - } - -}; - -class ConnectHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - ConnectHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoConnect(); - } -}; - -class RefreshHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - RefreshHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoRefresh(); - } -}; - -class BroadcastRefreshHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - BroadcastRefreshHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoBroadcastRefresh(); - } -}; - -class StopHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - StopHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoStop(); - } -}; - -class CancelHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - CancelHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoCancel(); - } -}; - -class PingHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - PingHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoPing(); - } -}; - -class SortHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - SortHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoSort( "map" ); - } -}; - -} - -class LabelSortInputHandler : public InputSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - char m_szSortKey[ 64 ]; - -public: - LabelSortInputHandler( ServerBrowserTablePanel *pBrowser, char *name ) - { - m_pBrowser = pBrowser; - strcpy( m_szSortKey, name ); - } - - virtual void cursorMoved(int x,int y,Panel* panel) {}; - virtual void cursorEntered(Panel* panel){}; - virtual void cursorExited(Panel* Panel) {}; - - virtual void mousePressed(MouseCode code,Panel* panel) - { - m_pBrowser->DoSort( m_szSortKey ); - } - - virtual void mouseDoublePressed(MouseCode code,Panel* panel) - { - m_pBrowser->DoSort( m_szSortKey ); - } - - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -class CSBLabel : public Label -{ - -private: - char m_szSortKey[ 64 ]; - ServerBrowserTablePanel *m_pBrowser; - -public: - CSBLabel( char *name, char *sortkey ) : Label( name ) - { - m_pBrowser = NULL; - - strcpy( m_szSortKey, sortkey ); - - int label_bg_r = 120, - label_bg_g = 75, - label_bg_b = 32, - label_bg_a = 200; - - int label_fg_r = 255, - label_fg_g = 0, - label_fg_b = 0, - label_fg_a = 0; - - setContentAlignment( vgui::Label::a_west ); - setFgColor( label_fg_r, label_fg_g, label_fg_b, label_fg_a ); - setBgColor( label_bg_r, label_bg_g, label_bg_b, label_bg_a ); - setFont( Scheme::sf_primary2 ); - - } - - void setTable( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - - addInputSignal( new LabelSortInputHandler( (ServerBrowserTablePanel * )m_pBrowser, m_szSortKey ) ); - } -}; - -ServerBrowser::ServerBrowser(int x,int y,int wide,int tall) : CTransparentPanel( 100, x,y,wide,tall ) -{ - int i; - - _headerPanel = new HeaderPanel(0,0,wide,HEADER_SIZE_Y); - _headerPanel->setParent(this); - _headerPanel->setFgColor( 100,100,100, 100 ); - _headerPanel->setBgColor( 0, 0, 0, 100 ); - - CSBLabel *pLabel[5]; - - pLabel[0] = new CSBLabel( "Address", "address" ); - pLabel[1] = new CSBLabel( "Server", "hostname" ); - pLabel[2] = new CSBLabel( "Map", "map" ); - pLabel[3] = new CSBLabel( "Current", "current" ); - pLabel[4] = new CSBLabel( "Latency", "ping" ); - - for ( i = 0; i < 5; i++ ) - { - _headerPanel->addSectionPanel( pLabel[i] ); - } - - // _headerPanel->setFont( Scheme::sf_primary1 ); - - _headerPanel->setSliderPos( 0, CSIZE_ADDRESS ); - _headerPanel->setSliderPos( 1, CSIZE_SERVER ); - _headerPanel->setSliderPos( 2, CSIZE_MAP ); - _headerPanel->setSliderPos( 3, CSIZE_CURRENT ); - _headerPanel->setSliderPos( 4, CSIZE_PING ); - - _tablePanel = new ServerBrowserTablePanel( 0, HEADER_SIZE_Y, wide, tall - HEADER_SIZE_Y, NUM_COLUMNS ); - _tablePanel->setParent(this); - _tablePanel->setHeaderPanel(_headerPanel); - _tablePanel->setFgColor( 100,100,100, 100 ); - _tablePanel->setBgColor( 0, 0, 0, 100 ); - - _tablePanel->addInputSignal( new CBrowser_InputSignal( (ServerBrowserTablePanel *)_tablePanel ) ); - - for ( i = 0; i < 5; i++ ) - { - pLabel[i]->setTable( (ServerBrowserTablePanel * )_tablePanel ); - } - - int bw = 80, bh = 15; - int by = tall - HEADER_SIZE_Y; - - int btnx = 10; - - _connectButton = new CommandButton( "Connect", btnx, by, bw, bh ); - _connectButton->setParent( this ); - _connectButton->addActionSignal( new ConnectHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - btnx += bw; - - _refreshButton = new CommandButton( "Refresh", btnx, by, bw, bh ); - _refreshButton->setParent( this ); - _refreshButton->addActionSignal( new RefreshHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - /* - btnx += bw; - - _broadcastRefreshButton = new CommandButton( "LAN", btnx, by, bw, bh ); - _broadcastRefreshButton->setParent( this ); - _broadcastRefreshButton->addActionSignal( new BroadcastRefreshHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - */ - - btnx += bw; - - _stopButton = new CommandButton( "Stop", btnx, by, bw, bh ); - _stopButton->setParent( this ); - _stopButton->addActionSignal( new StopHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - /* - btnx += bw; - - _pingButton = new CommandButton( "Test", btnx, by, bw, bh ); - _pingButton->setParent( this ); - _pingButton->addActionSignal( new PingHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - btnx += bw; - - _sortButton = new CommandButton( "Sort", btnx, by, bw, bh ); - _sortButton->setParent( this ); - _sortButton->addActionSignal( new SortHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - */ - - btnx += bw; - - _cancelButton = new CommandButton( "Close", btnx, by, bw, bh ); - _cancelButton->setParent( this ); - _cancelButton->addActionSignal( new CancelHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - setPaintBorderEnabled(false); - setPaintBackgroundEnabled(false); - setPaintEnabled(false); - -} - -void ServerBrowser::setSize(int wide,int tall) -{ - Panel::setSize(wide,tall); - - _headerPanel->setBounds(0,0,wide,HEADER_SIZE_Y); - _tablePanel->setBounds(0,HEADER_SIZE_Y,wide,tall - HEADER_SIZE_Y); - - _connectButton->setBounds( 5, tall - HEADER_SIZE_Y, 75, 15 ); - _refreshButton->setBounds( 85, tall - HEADER_SIZE_Y, 75, 15 ); - /* - _broadcastRefreshButton->setBounds( 165, tall - HEADER_SIZE_Y, 75, 15 ); - */ - _stopButton->setBounds( 165, tall - HEADER_SIZE_Y, 75, 15 ); - /* - _pingButton->setBounds( 325, tall - HEADER_SIZE_Y, 75, 15 ); - */ - _cancelButton->setBounds( 245, tall - HEADER_SIZE_Y, 75, 15 ); -} - -void CBrowser_InputSignal::mousePressed(MouseCode code,Panel* panel) -{ - int x, y; - int therow = 2; - - if ( code != MOUSE_LEFT ) - return; - - panel->getApp()->getCursorPos(x,y); - panel->screenToLocal( x, y ); - - therow = y / CELL_HEIGHT; - - // Figure out which row it's on - m_pBrowser->setMouseOverRow( therow ); -} - -void CBrowser_InputSignal::mouseDoublePressed(MouseCode code,Panel* panel) -{ - int x, y; - int therow = 2; - - if ( code != MOUSE_LEFT ) - return; - - panel->getApp()->getCursorPos(x,y); - panel->screenToLocal( x, y ); - - therow = y / CELL_HEIGHT; - - // Figure out which row it's on - m_pBrowser->setMouseOverRow( therow ); - m_pBrowser->DoConnect(); -} diff --git a/dmc/cl_dll/vgui_ServerBrowser.h b/dmc/cl_dll/vgui_ServerBrowser.h deleted file mode 100644 index 01f5693..0000000 --- a/dmc/cl_dll/vgui_ServerBrowser.h +++ /dev/null @@ -1,50 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef ServerBrowser_H -#define ServerBrowser_H - -#include - -namespace vgui -{ -class Button; -class TablePanel; -class HeaderPanel; -} - -class CTransparentPanel; -class CommandButton; - -// Scoreboard positions -#define SB_X_INDENT (20 * ((float)ScreenHeight / 640)) -#define SB_Y_INDENT (20 * ((float)ScreenHeight / 480)) - -class ServerBrowser : public CTransparentPanel -{ -private: - HeaderPanel * _headerPanel; - TablePanel* _tablePanel; - - CommandButton* _connectButton; - CommandButton* _refreshButton; - CommandButton* _broadcastRefreshButton; - CommandButton* _stopButton; - CommandButton* _sortButton; - CommandButton* _cancelButton; - - CommandButton* _pingButton; - -public: - ServerBrowser(int x,int y,int wide,int tall); -public: - virtual void setSize(int wide,int tall); -}; - - - -#endif diff --git a/dmc/cl_dll/vgui_SpectatorPanel.cpp b/dmc/cl_dll/vgui_SpectatorPanel.cpp deleted file mode 100644 index e3a85d6..0000000 --- a/dmc/cl_dll/vgui_SpectatorPanel.cpp +++ /dev/null @@ -1,204 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// vgui_SpectatorPanel.cpp: implementation of the SpectatorPanel class. -// -////////////////////////////////////////////////////////////////////// - -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "pm_shared.h" -#include "vgui_viewport.h" -#include "vgui_SpectatorPanel.h" - - - -////////////////////////////////////////////////////////////////////// -// Construction/Destruction -////////////////////////////////////////////////////////////////////// - -SpectatorPanel::SpectatorPanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall) -{ -} - -SpectatorPanel::~SpectatorPanel() -{ - -} - -void SpectatorPanel::ActionSignal(int cmd) -{ - switch (cmd) - { - case SPECTATOR_PANEL_CMD_NONE : break; - - case SPECTATOR_PANEL_CMD_OPTIONS : gViewPort->ShowCommandMenu( gViewPort->m_SpectatorMenu ); - break; - - case SPECTATOR_PANEL_CMD_NEXTPLAYER : gHUD.m_Spectator.FindNextPlayer(true); - break; - - case SPECTATOR_PANEL_CMD_PREVPLAYER : gHUD.m_Spectator.FindNextPlayer(false); - break; - - case SPECTATOR_PANEL_CMD_HIDEMENU : ShowMenu(false); - break; - - - - case SPECTATOR_PANEL_CMD_TOGGLE_INSET : gHUD.m_Spectator.SetModes( -1, - gHUD.m_Spectator.ToggleInset(false) ); - break; - - - default : gEngfuncs.Con_DPrintf("Unknown SpectatorPanel ActionSingal %i.\n",cmd); break; - } - -} - - -void SpectatorPanel::Initialize() -{ - int x,y,wide,tall; - - getBounds(x,y,wide,tall); - - CSchemeManager * pSchemes = gViewPort->GetSchemeManager(); - - SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" ); - - m_TopBorder = new CTransparentPanel(64, 0, 0, ScreenWidth, YRES(32)); - m_TopBorder->setParent(this); - - m_BottomBorder = new CTransparentPanel(64, 0, ScreenHeight - YRES(32), ScreenWidth, YRES(32)); - m_BottomBorder->setParent(this); - - setPaintBackgroundEnabled(false); - - // Initialize the bottom title. - m_BottomMainLabel = new Label( "Spectator Bottom", XRES(6+64+6+24+6), YRES(4), XRES(428), YRES(24) ); - m_BottomMainLabel->setParent(m_BottomBorder); - m_BottomMainLabel->setFont( pSchemes->getFont( hTitleScheme ) ); - m_BottomMainLabel->setPaintBackgroundEnabled(false); - m_BottomMainLabel->setFgColor( Scheme::sc_primary1 ); - m_BottomMainLabel->setContentAlignment( vgui::Label::a_center ); - - LineBorder * border = new LineBorder(1, Scheme::sc_secondary1); - m_BottomMainLabel->setBorder(border); - m_BottomMainLabel->setPaintBorderEnabled(true); - - // Initialize the top title. - m_TopMainLabel = new Label( "Spectator Top", 0, 0, wide, YRES(32) ); - m_TopMainLabel->setParent(m_TopBorder); - m_TopMainLabel->setFont( pSchemes->getFont( hTitleScheme ) ); - m_TopMainLabel->setPaintBackgroundEnabled(false); - m_TopMainLabel->setFgColor( Scheme::sc_primary1 ); - m_TopMainLabel->setContentAlignment( vgui::Label::a_center ); - - // Initialize command buttons. - m_OptionButton = new CommandButton("Options", XRES(6), YRES(6), XRES(64), YRES(20) ); - m_OptionButton->setParent( m_BottomBorder ); - m_OptionButton->setContentAlignment( vgui::Label::a_center ); - m_OptionButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name - m_OptionButton->addActionSignal( new CSpectatorHandler_Command(this,SPECTATOR_PANEL_CMD_OPTIONS) ); - - m_PrevPlayerButton= new CommandButton("<<", XRES(6+64+6), YRES(6), XRES(24), YRES(20) ); - m_PrevPlayerButton->setParent( m_BottomBorder ); - m_PrevPlayerButton->setContentAlignment( vgui::Label::a_center ); - m_PrevPlayerButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name - m_PrevPlayerButton->addActionSignal( new CSpectatorHandler_Command(this,SPECTATOR_PANEL_CMD_PREVPLAYER) ); - - m_NextPlayerButton= new CommandButton(">>", XRES(640-6-64-6-24), YRES(6), XRES(24), YRES(20) ); - m_NextPlayerButton->setParent( m_BottomBorder ); - m_NextPlayerButton->setContentAlignment( vgui::Label::a_center ); - m_NextPlayerButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name - m_NextPlayerButton->addActionSignal( new CSpectatorHandler_Command(this,SPECTATOR_PANEL_CMD_NEXTPLAYER) ); - - m_HideButton = new CommandButton("Hide", XRES(640-6-64), YRES(6), XRES(64), YRES(20) ); - m_HideButton->setParent( m_BottomBorder ); - m_HideButton->setContentAlignment( vgui::Label::a_center ); - m_HideButton->setBoundKey( (char)255 ); // special no bound to avoid leading spaces in name - m_HideButton->addActionSignal( new CSpectatorHandler_Command(this,SPECTATOR_PANEL_CMD_HIDEMENU) ); - - - m_InsetViewButton = new CommandButton("", XRES(2), YRES(2), XRES(240), YRES(180) ); - m_InsetViewButton->setParent( this ); - m_InsetViewButton->addActionSignal( new CSpectatorHandler_Command(this,SPECTATOR_PANEL_CMD_TOGGLE_INSET) ); - - - m_menuVisible = false; - m_HideButton->setVisible(false); - m_OptionButton->setVisible(false); - m_NextPlayerButton->setVisible(false); - m_PrevPlayerButton->setVisible(false); - m_BottomMainLabel->setPaintBorderEnabled(false); - m_TopMainLabel->setVisible(false); - -} - -void SpectatorPanel::ShowMenu(bool isVisible) -{ - m_HideButton->setVisible(isVisible); - m_OptionButton->setVisible(isVisible); - m_NextPlayerButton->setVisible(isVisible); - m_PrevPlayerButton->setVisible(isVisible); - m_BottomMainLabel->setPaintBorderEnabled(isVisible); - m_TopMainLabel->setVisible(isVisible); - - if ( !isVisible ) - { - gViewPort->HideCommandMenu(); - - // if switching from visible menu to invisible menu, show help text - if ( m_menuVisible && this->isVisible() ) - { - char string[ 64 ]; - - _snprintf( string, sizeof( string ) - 1, "%c%s", HUD_PRINTCENTER, CHudTextMessage::BufferedLocaliseTextString( "#Spec_Duck" ) ); - string[ sizeof( string ) - 1 ] = '\0'; - - gHUD.m_TextMessage.MsgFunc_TextMsg( NULL, strlen( string ) + 1, string ); - } - } - - m_menuVisible = isVisible; - - gViewPort->UpdateCursorState(); -} - -void SpectatorPanel::EnableInsetView(bool isEnabled) -{ - int x = gHUD.m_Spectator.m_OverviewData.insetWindowX; - int y = gHUD.m_Spectator.m_OverviewData.insetWindowY; - int wide = gHUD.m_Spectator.m_OverviewData.insetWindowWidth; - int tall = gHUD.m_Spectator.m_OverviewData.insetWindowHeight; - - if ( isEnabled ) - { - // short black bar to see full inset - m_TopBorder->setBounds( XRES(x+wide+2), 0, XRES(640 - (x+wide+2) ), YRES(32) ); - - m_TopMainLabel->setBounds( 0, 0, XRES(640 - (x+wide+2)), YRES(32) ); - - m_InsetViewButton->setBounds( XRES( x ), YRES( y ), - XRES( wide ), YRES( tall ) ); - m_InsetViewButton->setVisible(true); - } - else - { - // full black bar, no inset border - m_TopBorder->setBounds( 0, 0, ScreenWidth, YRES(32) ); - m_TopMainLabel->setBounds( 0, 0, ScreenWidth, YRES(32) ); - m_InsetViewButton->setVisible(false); - } -} - - - diff --git a/dmc/cl_dll/vgui_SpectatorPanel.h b/dmc/cl_dll/vgui_SpectatorPanel.h deleted file mode 100644 index ee1f712..0000000 --- a/dmc/cl_dll/vgui_SpectatorPanel.h +++ /dev/null @@ -1,93 +0,0 @@ - -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// vgui_SpectatorPanel.h: interface for the SpectatorPanel class. -// -////////////////////////////////////////////////////////////////////// - -#ifndef SPECTATORPANEL_H -#define SPECTATORPANEL_H - -#include -#include -#include - -using namespace vgui; - -#define SPECTATOR_PANEL_CMD_NONE 0 - -#define SPECTATOR_PANEL_CMD_OPTIONS 1 -#define SPECTATOR_PANEL_CMD_PREVPLAYER 2 -#define SPECTATOR_PANEL_CMD_NEXTPLAYER 3 -#define SPECTATOR_PANEL_CMD_HIDEMENU 4 -#define SPECTATOR_PANEL_CMD_TOGGLE_INSET 5 - - -class SpectatorPanel : public Panel //, public vgui::CDefaultInputSignal -{ - -public: - SpectatorPanel(int x,int y,int wide,int tall); - virtual ~SpectatorPanel(); - - void ActionSignal(int cmd); - - // InputSignal overrides. -public: - void Initialize(); - - - - -public: - - void EnableInsetView(bool isEnabled); - void ShowMenu(bool isVisible); - - - CommandButton * m_OptionButton; - CommandButton * m_HideButton; - CommandButton * m_PrevPlayerButton; - CommandButton * m_NextPlayerButton; - - CTransparentPanel * m_TopBorder; - CTransparentPanel * m_BottomBorder; - - CommandButton * m_InsetViewButton; - - Label * m_TopMainLabel; - Label * m_BottomMainLabel; - - - bool m_menuVisible; -}; - - - -class CSpectatorHandler_Command : public ActionSignal -{ - -private: - SpectatorPanel * m_pFather; - int m_cmd; - -public: - CSpectatorHandler_Command( SpectatorPanel * panel, int cmd ) - { - m_pFather = panel; - m_cmd = cmd; - } - - virtual void actionPerformed( Panel * panel ) - { - m_pFather->ActionSignal(m_cmd); - } -}; - - -#endif // !defined SPECTATORPANEL_H diff --git a/dmc/cl_dll/vgui_int.cpp b/dmc/cl_dll/vgui_int.cpp deleted file mode 100644 index 0f4b9e5..0000000 --- a/dmc/cl_dll/vgui_int.cpp +++ /dev/null @@ -1,128 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include"vgui_int.h" -#include -#include -#include -#include -#include -#include -#include -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "vgui_viewport.h" -#include "vgui_ControlConfigPanel.h" - -namespace -{ - -class TexturePanel : public Panel , public ActionSignal -{ -private: - int _bindIndex; - TextEntry* _textEntry; -public: - TexturePanel() : Panel(0,0,256,276) - { - _bindIndex=2700; - _textEntry=new TextEntry("2700",0,0,128,20); - _textEntry->setParent(this); - _textEntry->addActionSignal(this); - } -public: - virtual bool isWithin(int x,int y) - { - return _textEntry->isWithin(x,y); - } -public: - virtual void actionPerformed(Panel* panel) - { - char buf[256]; - _textEntry->getText(0,buf,256); - sscanf(buf,"%d",&_bindIndex); - } -protected: - virtual void paintBackground() - { - Panel::paintBackground(); - - int wide,tall; - getPaintSize(wide,tall); - - drawSetColor(0,0,255,0); - drawSetTexture(_bindIndex); - drawTexturedRect(0,19,257,257); - } - -}; - -} - -using namespace vgui; - -void VGui_ViewportPaintBackground(int extents[4]) -{ - gEngfuncs.VGui_ViewportPaintBackground(extents); -} - -void* VGui_GetPanel() -{ - return (Panel*)gEngfuncs.VGui_GetPanel(); -} - -void VGui_Startup() -{ - Panel* root=(Panel*)VGui_GetPanel(); - root->setBgColor(128,128,0,0); - //root->setNonPainted(false); - //root->setBorder(new LineBorder()); - root->setLayout(new BorderLayout(0)); - - - //root->getSurfaceBase()->setEmulatedCursorVisible(true); - - if (gViewPort != NULL) - { -// root->removeChild(gViewPort); - - // free the memory -// delete gViewPort; -// gViewPort = NULL; - - gViewPort->Initialize(); - } - else - { - gViewPort = new TeamFortressViewport(0,0,root->getWide(),root->getTall()); - gViewPort->setParent(root); - } - - /* - TexturePanel* texturePanel=new TexturePanel(); - texturePanel->setParent(gViewPort); - */ - -} - -void VGui_Shutdown() -{ - delete gViewPort; - gViewPort = NULL; -} - - - - - diff --git a/dmc/cl_dll/vgui_int.h b/dmc/cl_dll/vgui_int.h deleted file mode 100644 index 6510853..0000000 --- a/dmc/cl_dll/vgui_int.h +++ /dev/null @@ -1,21 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef VGUI_INT_H -#define VGUI_INT_H - -extern "C" -{ -void VGui_Startup(); -void VGui_Shutdown(); - -//Only safe to call from inside subclass of Panel::paintBackground -void VGui_ViewportPaintBackground(int extents[4]); -} - - -#endif \ No newline at end of file diff --git a/dmc/cl_dll/vgui_viewport.cpp b/dmc/cl_dll/vgui_viewport.cpp deleted file mode 100644 index a7c8746..0000000 --- a/dmc/cl_dll/vgui_viewport.cpp +++ /dev/null @@ -1,1983 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Client DLL VGUI Viewport -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "pm_shared.h" -#include "parsemsg.h" -#include "keydefs.h" -#include "demo.h" -#include "demo_api.h" - -#include "vgui_int.h" -#include "vgui_viewport.h" -#include "vgui_ServerBrowser.h" -#include "vgui_ScorePanel.h" -#include "vgui_SpectatorPanel.h" -#include "voice_status.h" - -extern int g_iVisibleMouse; -class CCommandMenu; -int g_iPlayerClass; -int g_iTeamNumber; -int g_iUser1 = 0; -int g_iUser2 = 0; -int g_iUser3 = 0; - -// Scoreboard positions -#define SBOARD_INDENT_X XRES(104) -#define SBOARD_INDENT_Y YRES(40) - -// low-res scoreboard indents -#define SBOARD_INDENT_X_512 30 -#define SBOARD_INDENT_Y_512 30 - -#define SBOARD_INDENT_X_400 0 -#define SBOARD_INDENT_Y_400 20 - - - -void IN_ResetMouse( void ); -extern CMenuPanel* CMessageWindowPanel_Create( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall ); -extern float * GetClientColor( int clientIndex ); - -using namespace vgui; - -// Team Colors -int iTeamColors[5][3] = -{ - { 255, 170, 0 }, // HL Orange - { 66, 115, 247 }, - { 220, 51, 38 }, - { 240, 135, 0 }, - { 115, 240, 115 }, -}; - -// Used for Class specific buttons -char *sTFClasses[] = -{ - "", - "SCOUT", - "SNIPER", - "SOLDIER", - "DEMOMAN", - "MEDIC", - "HWGUY", - "PYRO", - "SPY", - "ENGINEER", - "CIVILIAN", -}; - -char *sLocalisedClasses[] = -{ - "#Civilian", - "#Scout", - "#Sniper", - "#Soldier", - "#Demoman", - "#Medic", - "#HWGuy", - "#Pyro", - "#Spy", - "#Engineer", - "#Random", - "#Civilian", -}; - -char *sTFClassSelection[] = -{ - "civilian", - "scout", - "sniper", - "soldier", - "demoman", - "medic", - "hwguy", - "pyro", - "spy", - "engineer", - "randompc", - "civilian", -}; - - -// Get the name of TGA file, based on GameDir -char* GetVGUITGAName(const char *pszName) -{ - int i; - char sz[256]; - static char gd[256]; - const char *gamedir; - - if (ScreenWidth < 640) - i = 320; - else - i = 640; - sprintf(sz, pszName, i); - - gamedir = gEngfuncs.pfnGetGameDirectory(); - sprintf(gd, "%s/gfx/vgui/%s.tga",gamedir,sz); - - return gd; -} - -//================================================================ -// COMMAND MENU -//================================================================ -void CCommandMenu::AddButton( CommandButton *pButton ) -{ - if (m_iButtons >= MAX_BUTTONS) - return; - - m_aButtons[m_iButtons] = pButton; - m_iButtons++; - pButton->setParent( this ); - pButton->setFont( Scheme::sf_primary3 ); - - // give the button a default key binding - if ( m_iButtons < 10 ) - { - pButton->setBoundKey( m_iButtons + '0' ); - } - else if ( m_iButtons == 10 ) - { - pButton->setBoundKey( '0' ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Tries to find a button that has a key bound to the input, and -// presses the button if found -// Input : keyNum - the character number of the input key -// Output : Returns true if the command menu should close, false otherwise -//----------------------------------------------------------------------------- -bool CCommandMenu::KeyInput( int keyNum ) -{ - // loop through all our buttons looking for one bound to keyNum - for ( int i = 0; i < m_iButtons; i++ ) - { - if ( !m_aButtons[i]->IsNotValid() ) - { - if ( m_aButtons[i]->getBoundKey() == keyNum ) - { - // hit the button - if ( m_aButtons[i]->GetSubMenu() ) - { - // open the sub menu - gViewPort->SetCurrentCommandMenu( m_aButtons[i]->GetSubMenu() ); - return false; - } - else - { - // run the bound command - m_aButtons[i]->fireActionSignal(); - return true; - } - } - } - } - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: clears the current menus buttons of any armed (highlighted) -// state, and all their sub buttons -//----------------------------------------------------------------------------- -void CCommandMenu::ClearButtonsOfArmedState( void ) -{ - for ( int i = 0; i < GetNumButtons(); i++ ) - { - m_aButtons[i]->setArmed( false ); - - if ( m_aButtons[i]->GetSubMenu() ) - { - m_aButtons[i]->GetSubMenu()->ClearButtonsOfArmedState(); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pSubMenu - -// Output : CommandButton -//----------------------------------------------------------------------------- -CommandButton *CCommandMenu::FindButtonWithSubmenu( CCommandMenu *pSubMenu ) -{ - for ( int i = 0; i < GetNumButtons(); i++ ) - { - if ( m_aButtons[i]->GetSubMenu() == pSubMenu ) - return m_aButtons[i]; - } - - return NULL; -} - -// Recalculate the visible buttons -bool CCommandMenu::RecalculateVisibles( int iYOffset, bool bHideAll ) -{ - int i, iCurrentY = 0; - int iVisibleButtons = 0; - - // Cycle through all the buttons in this menu, and see which will be visible - for (i = 0; i < m_iButtons; i++) - { - int iClass = m_aButtons[i]->GetPlayerClass(); - - if ( (iClass && iClass != g_iPlayerClass ) || ( m_aButtons[i]->IsNotValid() ) || bHideAll ) - { - m_aButtons[i]->setVisible( false ); - if ( m_aButtons[i]->GetSubMenu() != NULL ) - { - (m_aButtons[i]->GetSubMenu())->RecalculateVisibles( 0, true ); - } - } - else - { - // If it's got a submenu, force it to check visibilities - if ( m_aButtons[i]->GetSubMenu() != NULL ) - { - if ( !(m_aButtons[i]->GetSubMenu())->RecalculateVisibles( 0 , false ) ) - { - // The submenu had no visible buttons, so don't display this button - m_aButtons[i]->setVisible( false ); - continue; - } - } - - m_aButtons[i]->setVisible( true ); - iVisibleButtons++; - } - } - - // Set Size - setSize( _size[0], (iVisibleButtons * (BUTTON_SIZE_Y-1)) + 1 ); - - if ( iYOffset ) - { - m_iYOffset = iYOffset; - } - - for (i = 0; i < m_iButtons; i++) - { - if ( m_aButtons[i]->isVisible() ) - { - if ( m_aButtons[i]->GetSubMenu() != NULL ) - (m_aButtons[i]->GetSubMenu())->RecalculateVisibles( iCurrentY + m_iYOffset, false ); - - - // Make sure it's at the right Y position - // m_aButtons[i]->getPos( iXPos, iYPos ); - - if ( m_iDirection ) - { - m_aButtons[i]->setPos( 0, (iVisibleButtons-1) * (BUTTON_SIZE_Y-1) - iCurrentY ); - } - else - { - m_aButtons[i]->setPos( 0, iCurrentY ); - } - - iCurrentY += (BUTTON_SIZE_Y-1); - } - } - - return iVisibleButtons?true:false; -} - -// Make sure all submenus can fit on the screen -void CCommandMenu::RecalculatePositions( int iYOffset ) -{ - int iTop; - int iAdjust = 0; - - m_iYOffset+= iYOffset; - - if ( m_iDirection ) - iTop = ScreenHeight - (m_iYOffset + _size[1] ); - else - iTop = m_iYOffset; - - if ( iTop < 0 ) - iTop = 0; - - // Calculate if this is going to fit onscreen, and shuffle it up if it won't - int iBottom = iTop + _size[1]; - - if ( iBottom > ScreenHeight ) - { - // Move in increments of button sizes - while (iAdjust < (iBottom - ScreenHeight)) - { - iAdjust += BUTTON_SIZE_Y - 1; - } - - iTop -= iAdjust; - - // Make sure it doesn't move off the top of the screen (the menu's too big to fit it all) - if ( iTop < 0 ) - { - iAdjust -= (0 - iTop); - iTop = 0; - } - } - - setPos( _pos[0], iTop ); - - // We need to force all menus below this one to update their positions now, because they - // might have submenus riding off buttons in this menu that have just shifted. - for (int i = 0; i < m_iButtons; i++) - m_aButtons[i]->UpdateSubMenus( iAdjust ); -} - - -// Make this menu and all menus above it in the chain visible -void CCommandMenu::MakeVisible( CCommandMenu *pChildMenu ) -{ -/* - // Push down the button leading to the child menu - for (int i = 0; i < m_iButtons; i++) - { - if ( (pChildMenu != NULL) && (m_aButtons[i]->GetSubMenu() == pChildMenu) ) - { - m_aButtons[i]->setArmed( true ); - } - else - { - m_aButtons[i]->setArmed( false ); - } - } -*/ - - setVisible(true); - if (m_pParentMenu) - m_pParentMenu->MakeVisible( this ); -} - -//================================================================ -// CreateSubMenu -CCommandMenu *TeamFortressViewport::CreateSubMenu( CommandButton *pButton, CCommandMenu *pParentMenu, int iOffsetY ) -{ - int iXPos = 0; - int iYPos = 0; - int iWide = CMENU_SIZE_X; - int iTall = 0; - int iDirection = 0; - - if (pParentMenu) - { - iXPos = m_pCurrentCommandMenu->GetXOffset() + (CMENU_SIZE_X - 1); - iYPos = m_pCurrentCommandMenu->GetYOffset() + iOffsetY; - iDirection = pParentMenu->GetDirection(); - } - - CCommandMenu *pMenu = new CCommandMenu(pParentMenu, iDirection, iXPos, iYPos, iWide, iTall ); - pMenu->setParent(this); - pButton->AddSubMenu( pMenu ); - pButton->setFont( Scheme::sf_primary3 ); - - // Create the Submenu-open signal - InputSignal *pISignal = new CMenuHandler_PopupSubMenuInput(pButton, pMenu); - pButton->addInputSignal(pISignal); - - // Put a > to show it's a submenu - CImageLabel *pLabel = new CImageLabel( "arrow", CMENU_SIZE_X - SUBMENU_SIZE_X, SUBMENU_SIZE_Y ); - pLabel->setParent(pButton); - pLabel->addInputSignal(pISignal); - - // Reposition - pLabel->getPos( iXPos, iYPos ); - pLabel->setPos( CMENU_SIZE_X - pLabel->getImageWide(), (BUTTON_SIZE_Y - pLabel->getImageTall()) / 2 ); - - // Create the mouse off signal for the Label too - if (!pButton->m_bNoHighlight) - pLabel->addInputSignal( new CHandler_CommandButtonHighlight(pButton) ); - - return pMenu; -} - -//----------------------------------------------------------------------------- -// Purpose: Makes sure the memory allocated for TeamFortressViewport is nulled out -// Input : stAllocateBlock - -// Output : void * -//----------------------------------------------------------------------------- -void *TeamFortressViewport::operator new( size_t stAllocateBlock ) -{ -// void *mem = Panel::operator new( stAllocateBlock ); - void *mem = ::operator new( stAllocateBlock ); - memset( mem, 0, stAllocateBlock ); - return mem; -} - -//----------------------------------------------------------------------------- -// Purpose: InputSignal handler for the main viewport -//----------------------------------------------------------------------------- -class CViewPortInputHandler : public InputSignal -{ -public: - bool bPressed; - - CViewPortInputHandler() - { - } - - virtual void cursorMoved(int x,int y,Panel* panel) {} - virtual void cursorEntered(Panel* panel) {} - virtual void cursorExited(Panel* panel) {} - virtual void mousePressed(MouseCode code,Panel* panel) - { - if ( code != MOUSE_LEFT ) - { - // send a message to close the command menu - // this needs to be a message, since a direct call screws the timing - gEngfuncs.pfnClientCmd( "ForceCloseCommandMenu\n" ); - } - } - virtual void mouseReleased(MouseCode code,Panel* panel) - { - } - - virtual void mouseDoublePressed(MouseCode code,Panel* panel) {} - virtual void mouseWheeled(int delta,Panel* panel) {} - virtual void keyPressed(KeyCode code,Panel* panel) {} - virtual void keyTyped(KeyCode code,Panel* panel) {} - virtual void keyReleased(KeyCode code,Panel* panel) {} - virtual void keyFocusTicked(Panel* panel) {} -}; - - -//================================================================ -TeamFortressViewport::TeamFortressViewport(int x,int y,int wide,int tall) : Panel(x,y,wide,tall), m_SchemeManager(wide,tall) -{ - gViewPort = this; - m_iInitialized = false; -// m_pTeamMenu = NULL; -// m_pClassMenu = NULL; - m_pScoreBoard = NULL; - m_pSpectatorPanel = NULL; - m_pCurrentMenu = NULL; - m_pCurrentCommandMenu = NULL; - - CVAR_CREATE( "hud_classautokill", "1", FCVAR_ARCHIVE ); // controls whether or not to suicide immediately on TF class switch - CVAR_CREATE( "hud_takesshots", "0", FCVAR_ARCHIVE ); // controls whether or not to automatically take screenshots at the end of a round - - Initialize(); - addInputSignal( new CViewPortInputHandler ); - - int r, g, b, a; - - Scheme* pScheme = App::getInstance()->getScheme(); - - // primary text color - // Get the colors - //!! two different types of scheme here, need to integrate - SchemeHandle_t hPrimaryScheme = m_SchemeManager.getSchemeHandle( "Primary Button Text" ); - { - // font - pScheme->setFont( Scheme::sf_primary1, m_SchemeManager.getFont(hPrimaryScheme) ); - - // text color - m_SchemeManager.getFgColor( hPrimaryScheme, r, g, b, a ); - pScheme->setColor(Scheme::sc_primary1, r, g, b, a ); // sc_primary1 is non-transparent orange - - // background color (transparent black) - m_SchemeManager.getBgColor( hPrimaryScheme, r, g, b, a ); - pScheme->setColor(Scheme::sc_primary3, r, g, b, a ); - - // armed foreground color - m_SchemeManager.getFgArmedColor( hPrimaryScheme, r, g, b, a ); - pScheme->setColor(Scheme::sc_secondary2, r, g, b, a ); - - // armed background color - m_SchemeManager.getBgArmedColor( hPrimaryScheme, r, g, b, a ); - pScheme->setColor(Scheme::sc_primary2, r, g, b, a ); - - //!! need to get this color from scheme file - // used for orange borders around buttons - m_SchemeManager.getBorderColor( hPrimaryScheme, r, g, b, a ); - // pScheme->setColor(Scheme::sc_secondary1, r, g, b, a ); - pScheme->setColor(Scheme::sc_secondary1, 255*0.7, 170*0.7, 0, 0); - } - - // Change the second primary font (used in the scoreboard) - SchemeHandle_t hScoreboardScheme = m_SchemeManager.getSchemeHandle( "Scoreboard Text" ); - { - pScheme->setFont(Scheme::sf_primary2, m_SchemeManager.getFont(hScoreboardScheme) ); - } - - // Change the third primary font (used in command menu) - SchemeHandle_t hCommandMenuScheme = m_SchemeManager.getSchemeHandle( "CommandMenu Text" ); - { - pScheme->setFont(Scheme::sf_primary3, m_SchemeManager.getFont(hCommandMenuScheme) ); - } - - App::getInstance()->setScheme(pScheme); - - // VGUI MENUS - CreateTeamMenu(); - CreateClassMenu(); - CreateSpectatorMenu(); - CreateScoreBoard(); - // Init command menus - m_iNumMenus = 0; - m_iCurrentTeamNumber = m_iUser1 = m_iUser2 = 0; - m_StandardMenu = CreateCommandMenu("commandmenu.txt", 0, CMENU_TOP); - m_SpectatorMenu = CreateCommandMenu("spectatormenu.txt", 1, YRES(32) ); // above bottom bar - - CreateServerBrowser(); - -} - -//----------------------------------------------------------------------------- -// Purpose: Called everytime a new level is started. Viewport clears out it's data. -//----------------------------------------------------------------------------- -void TeamFortressViewport::Initialize( void ) -{ - // Force each menu to Initialize -/* if (m_pTeamMenu) - { - m_pTeamMenu->Initialize(); - } - if (m_pClassMenu) - { - m_pClassMenu->Initialize(); - }*/ - if (m_pScoreBoard) - { - m_pScoreBoard->Initialize(); - HideScoreBoard(); - } - if (m_pSpectatorPanel) - { - // Spectator menu doesn't need initializing - m_pSpectatorPanel->setVisible( false ); - } - - // Make sure all menus are hidden - HideVGUIMenu(); - HideCommandMenu(); - - // Clear out some data - m_iGotAllMOTD = true; - m_iRandomPC = false; - m_flScoreBoardLastUpdated = 0; - - // reset player info - g_iPlayerClass = 0; - g_iTeamNumber = 0; - - strcpy(m_sMapName, ""); - strcpy(m_szServerName, ""); - for (int i = 0; i < 5; i++) - { - m_iValidClasses[i] = 0; - strcpy(m_sTeamNames[i], ""); - } - - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_none) ); -} - -class CException; -//----------------------------------------------------------------------------- -// Purpose: Read the Command Menu structure from the txt file and create the menu. -// Returns Index of menu in m_pCommandMenus -//----------------------------------------------------------------------------- -int TeamFortressViewport::CreateCommandMenu( char * menuFile, int direction, int yOffset ) -{ - // COMMAND MENU - // Create the root of this new Command Menu - - int newIndex = m_iNumMenus; - - m_pCommandMenus[newIndex] = new CCommandMenu(NULL, direction, 0, yOffset, CMENU_SIZE_X, 300); // This will be resized once we know how many items are in it - m_pCommandMenus[newIndex]->setParent(this); - m_pCommandMenus[newIndex]->setVisible(false); - - m_iNumMenus++; - - // Read Command Menu from the txt file - char token[1024]; - char *pfile = (char*)gEngfuncs.COM_LoadFile( menuFile, 5, NULL); - if (!pfile) - { - gEngfuncs.Con_DPrintf( "Unable to open %s\n", menuFile); - SetCurrentCommandMenu( NULL ); - return newIndex; - } - -#ifdef _WIN32 -try -{ -#endif - // First, read in the localisation strings - - // Detpack strings - gHUD.m_TextMessage.LocaliseTextString( "#DetpackSet_For5Seconds", m_sDetpackStrings[0], MAX_BUTTON_SIZE ); - gHUD.m_TextMessage.LocaliseTextString( "#DetpackSet_For20Seconds", m_sDetpackStrings[1], MAX_BUTTON_SIZE ); - gHUD.m_TextMessage.LocaliseTextString( "#DetpackSet_For50Seconds", m_sDetpackStrings[2], MAX_BUTTON_SIZE ); - - // Now start parsing the menu structure - m_pCurrentCommandMenu = m_pCommandMenus[newIndex]; - char szLastButtonText[32] = "file start"; - pfile = gEngfuncs.COM_ParseFile(pfile, token); - while ( ( strlen ( token ) > 0 ) && ( m_iNumMenus < MAX_MENUS ) ) - { - // Keep looping until we hit the end of this menu - while ( token[0] != '}' && ( strlen( token ) > 0 ) ) - { - char cText[32] = ""; - char cBoundKey[32] = ""; - char cCustom[32] = ""; - static const int cCommandLength = 128; - char cCommand[cCommandLength] = ""; - char szMap[MAX_MAPNAME] = ""; - int iPlayerClass = 0; - int iCustom = false; - int iTeamOnly = -1; - int iToggle = 0; - int iButtonY; - bool bGetExtraToken = true; - CommandButton *pButton = NULL; - - // We should never be here without a Command Menu - if (!m_pCurrentCommandMenu) - { - gEngfuncs.Con_Printf("Error in %s file after '%s'.\n",menuFile, szLastButtonText ); - m_iInitialized = false; - return newIndex; - } - - // token should already be the bound key, or the custom name - strncpy( cCustom, token, 32 ); - cCustom[31] = '\0'; - - // See if it's a custom button - if (!strcmp(cCustom, "CUSTOM") ) - { - iCustom = true; - - // Get the next token - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } - // See if it's a map - else if (!strcmp(cCustom, "MAP") ) - { - // Get the mapname - pfile = gEngfuncs.COM_ParseFile(pfile, token); - strncpy( szMap, token, MAX_MAPNAME ); - szMap[MAX_MAPNAME-1] = '\0'; - - // Get the next token - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } - else if ( !strncmp(cCustom, "TEAM", 4) ) // TEAM1, TEAM2, TEAM3, TEAM4 - { - // make it a team only button - iTeamOnly = atoi( cCustom + 4 ); - - // Get the next token - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } - else if ( !strncmp(cCustom, "TOGGLE", 6) ) - { - iToggle = true; - // Get the next token - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } - - // Get the button bound key - strncpy( cBoundKey, token, 32 ); - cText[31] = '\0'; - - // Get the button text - pfile = gEngfuncs.COM_ParseFile(pfile, token); - strncpy( cText, token, 32 ); - cText[31] = '\0'; - - // save off the last button text we've come across (for error reporting) - strcpy( szLastButtonText, cText ); - - // Get the button command - pfile = gEngfuncs.COM_ParseFile(pfile, token); - strncpy( cCommand, token, cCommandLength ); - cCommand[cCommandLength - 1] = '\0'; - - iButtonY = (BUTTON_SIZE_Y-1) * m_pCurrentCommandMenu->GetNumButtons(); - - // Custom button handling - if ( iCustom ) - { - pButton = CreateCustomButton( cText, cCommand, iButtonY ); - - // Get the next token to see if we're a menu - pfile = gEngfuncs.COM_ParseFile(pfile, token); - - if ( token[0] == '{' ) - { - strcpy( cCommand, token ); - } - else - { - bGetExtraToken = false; - } - } - else if ( szMap[0] != '\0' ) - { - // create a map button - pButton = new MapButton(szMap, cText, 0, iButtonY, CMENU_SIZE_X, BUTTON_SIZE_Y); - } - else if ( iTeamOnly != -1) - { - // button that only shows up if the player is on team iTeamOnly - pButton = new TeamOnlyCommandButton( iTeamOnly, cText, 0, iButtonY, CMENU_SIZE_X, BUTTON_SIZE_Y ); - } - else if ( iToggle ) - { - pButton = new ToggleCommandButton( cCommand, cText,0, iButtonY, CMENU_SIZE_X, BUTTON_SIZE_Y ); - } - else - { - // normal button - pButton = new CommandButton( iPlayerClass, cText, 0, iButtonY, CMENU_SIZE_X, BUTTON_SIZE_Y ); - } - - // add the button into the command menu - if ( pButton ) - { - m_pCurrentCommandMenu->AddButton( pButton ); - pButton->setBoundKey( cBoundKey[0] ); - pButton->setParentMenu( m_pCurrentCommandMenu ); - - // Override font in CommandMenu - pButton->setFont( Scheme::sf_primary3 ); - } - - // Find out if it's a submenu or a button we're dealing with - if ( cCommand[0] == '{' ) - { - if ( m_iNumMenus >= MAX_MENUS ) - { - gEngfuncs.Con_Printf( "Too many menus in %s past '%s'\n",menuFile, szLastButtonText ); - } - else - { - // Create the menu - m_pCommandMenus[m_iNumMenus] = CreateSubMenu(pButton, m_pCurrentCommandMenu, iButtonY ); - m_pCurrentCommandMenu = m_pCommandMenus[m_iNumMenus]; - m_iNumMenus++; - } - } - else if ( !iCustom ) - { - // Create the button and attach it to the current menu - if ( iToggle ) - pButton->addActionSignal(new CMenuHandler_ToggleCvar(cCommand)); - else - pButton->addActionSignal(new CMenuHandler_StringCommand(cCommand)); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - - // Get the next token - if ( bGetExtraToken ) - { - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } - } - - // Move back up a menu - m_pCurrentCommandMenu = m_pCurrentCommandMenu->GetParentMenu(); - - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } -#ifdef _WIN32 -} -catch( CException *e ) -{ - e; - //e->Delete(); - e = NULL; - m_iInitialized = false; - return newIndex; -} -#endif - SetCurrentMenu( NULL ); - SetCurrentCommandMenu( NULL ); - gEngfuncs.COM_FreeFile( pfile ); - - m_iInitialized = true; - return newIndex; -} - -//----------------------------------------------------------------------------- -// Purpose: Creates all the class choices under a spy's disguise menus, and -// maps a command to them -// Output : CCommandMenu -//----------------------------------------------------------------------------- - -CCommandMenu *TeamFortressViewport::CreateDisguiseSubmenu( CommandButton *pButton, CCommandMenu *pParentMenu, const char *commandText, int iYOffset ) -{ - // create the submenu, under which the class choices will be listed - CCommandMenu *pMenu = CreateSubMenu( pButton, pParentMenu, iYOffset ); - m_pCommandMenus[m_iNumMenus] = pMenu; - m_iNumMenus++; - - return pMenu; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pButtonText - -// *pButtonName - -// Output : CommandButton -//----------------------------------------------------------------------------- -CommandButton *TeamFortressViewport::CreateCustomButton( char *pButtonText, char *pButtonName, int iYOffset ) -{ - CommandButton *pButton = NULL; - CCommandMenu *pMenu = NULL; - - // ChangeTeam - if ( !strcmp( pButtonName, "!CHANGETEAM" ) ) - { - // ChangeTeam Submenu - pButton = new CommandButton(pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - - // Create the submenu - pMenu = CreateSubMenu(pButton, m_pCurrentCommandMenu, iYOffset ); - m_pCommandMenus[m_iNumMenus] = pMenu; - m_iNumMenus++; - - // ChangeTeam buttons - for (int i = 0; i < 4; i++) - { - char sz[256]; - sprintf(sz, "jointeam %d", i+1); - m_pTeamButtons[i] = new TeamButton(i+1, "teamname", 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - m_pTeamButtons[i]->addActionSignal(new CMenuHandler_StringCommandWatch( sz )); - pMenu->AddButton( m_pTeamButtons[i] ); - } - - // Auto Assign button - m_pTeamButtons[4] = new TeamButton(5, gHUD.m_TextMessage.BufferedLocaliseTextString( "#Team_AutoAssign" ), 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - m_pTeamButtons[4]->addActionSignal(new CMenuHandler_StringCommand( "jointeam 5" )); - pMenu->AddButton( m_pTeamButtons[4] ); - - // Spectate button - m_pTeamButtons[5] = new SpectateButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_Spectate" ), 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y, false); - m_pTeamButtons[5]->addActionSignal(new CMenuHandler_StringCommand( "spectate" )); - pMenu->AddButton( m_pTeamButtons[5] ); - } - - else if ( !strcmp( pButtonName, "!MAPBRIEFING" ) ) - { - pButton = new CommandButton(pButtonText, 0, BUTTON_SIZE_Y * m_pCurrentCommandMenu->GetNumButtons(), CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_TextWindow(MENU_MAPBRIEFING)); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - - else if ( !strcmp( pButtonName, "!SERVERINFO" ) ) - { - pButton = new ClassButton(0, pButtonText, 0, BUTTON_SIZE_Y * m_pCurrentCommandMenu->GetNumButtons(), CMENU_SIZE_X, BUTTON_SIZE_Y, false); - pButton->addActionSignal(new CMenuHandler_TextWindow(MENU_INTRO)); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - - return pButton; -} - -void TeamFortressViewport::ToggleServerBrowser() -{ - if (!m_iInitialized) - return; - - if ( !m_pServerBrowser ) - return; - - if ( m_pServerBrowser->isVisible() ) - { - m_pServerBrowser->setVisible( false ); - } - else - { - m_pServerBrowser->setVisible( true ); - } - - UpdateCursorState(); -} - -//======================================================================= -//======================================================================= -void TeamFortressViewport::ShowCommandMenu(int menuIndex) -{ - if (!m_iInitialized) - return; - - //Already have a menu open. - if ( m_pCurrentMenu ) - return; - - // is the command menu open? - if ( m_pCurrentCommandMenu == m_pCommandMenus[menuIndex] ) - { - HideCommandMenu(); - return; - } - - // Not visible while in intermission - if ( gHUD.m_iIntermission ) - return; - - // Recalculate visible menus - UpdateCommandMenu( menuIndex ); - HideVGUIMenu(); - - SetCurrentCommandMenu( m_pCommandMenus[menuIndex] ); - m_flMenuOpenTime = gHUD.m_flTime; - UpdateCursorState(); - - // get command menu parameters - for ( int i = 2; i < gEngfuncs.Cmd_Argc(); i++ ) - { - const char *param = gEngfuncs.Cmd_Argv( i - 1 ); - if ( param ) - { - if ( m_pCurrentCommandMenu->KeyInput(param[0]) ) - { - // kill the menu open time, since the key input is final - HideCommandMenu(); - } - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Handles the key input of "-commandmenu" -// Input : -//----------------------------------------------------------------------------- -void TeamFortressViewport::InputSignalHideCommandMenu() -{ - if (!m_iInitialized) - return; - - // if they've just tapped the command menu key, leave it open - if ( (m_flMenuOpenTime + 0.3) > gHUD.m_flTime ) - return; - - HideCommandMenu(); -} - -//----------------------------------------------------------------------------- -// Purpose: Hides the command menu -//----------------------------------------------------------------------------- -void TeamFortressViewport::HideCommandMenu() -{ - if (!m_iInitialized) - return; - - if ( m_pCommandMenus[m_StandardMenu] ) - { - m_pCommandMenus[m_StandardMenu]->ClearButtonsOfArmedState(); - } - - if ( m_pCommandMenus[m_SpectatorMenu] ) - { - m_pCommandMenus[m_SpectatorMenu]->ClearButtonsOfArmedState(); - } - - m_flMenuOpenTime = 0.0f; - SetCurrentCommandMenu( NULL ); - UpdateCursorState(); -} - -//----------------------------------------------------------------------------- -// Purpose: Bring up the scoreboard -//----------------------------------------------------------------------------- -void TeamFortressViewport::ShowScoreBoard( void ) -{ - if (m_pScoreBoard) - { - // No Scoreboard in single-player - if ( gEngfuncs.GetMaxClients() > 1 ) - { - m_pScoreBoard->Open(); - UpdateCursorState(); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Returns true if the scoreboard is up -//----------------------------------------------------------------------------- -bool TeamFortressViewport::IsScoreBoardVisible( void ) -{ - if (m_pScoreBoard) - return m_pScoreBoard->isVisible(); - - return false; -} - - -//----------------------------------------------------------------------------- -// Purpose: Hide the scoreboard -//----------------------------------------------------------------------------- -void TeamFortressViewport::HideScoreBoard( void ) -{ - // Prevent removal of scoreboard during intermission - if ( gHUD.m_iIntermission ) - return; - - if (m_pScoreBoard) - { - m_pScoreBoard->setVisible(false); - - GetClientVoiceMgr()->StopSquelchMode(); - - UpdateCursorState(); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Activate's the player special ability -// called when the player hits their "special" key -//----------------------------------------------------------------------------- -void TeamFortressViewport::InputPlayerSpecial( void ) -{ - if (!m_iInitialized) - return; -} - -// Set the submenu of the Command Menu -void TeamFortressViewport::SetCurrentCommandMenu( CCommandMenu *pNewMenu ) -{ - for (int i = 0; i < m_iNumMenus; i++) - m_pCommandMenus[i]->setVisible(false); - - m_pCurrentCommandMenu = pNewMenu; - - if (m_pCurrentCommandMenu) - m_pCurrentCommandMenu->MakeVisible( NULL ); -} - -void TeamFortressViewport::UpdateCommandMenu(int menuIndex) -{ - m_pCommandMenus[menuIndex]->RecalculateVisibles( 0, false ); - m_pCommandMenus[menuIndex]->RecalculatePositions( 0 ); -} - -void TeamFortressViewport::UpdateSpectatorPanel() -{ - m_iUser1 = g_iUser1; - m_iUser2 = g_iUser2; - - if (!m_pSpectatorPanel) - return; - - // check if spectator combinations are still valid - gHUD.m_Spectator.CheckSettings(); - - if ( g_iUser1 && gHUD.m_pCvarDraw->value && !gHUD.m_iIntermission) // don't draw in dev_overview mode - { - char bottomText[128]; - char helpString2[128]; - char tempString[128]; - char * name; - int player = 0; - - if ( !m_pSpectatorPanel->isVisible() ) - { - m_pSpectatorPanel->setVisible( true ); // show spectator panel, but - m_pSpectatorPanel->ShowMenu( false ); // dsiable all menus/buttons - - _snprintf( tempString, sizeof( tempString ) - 1, "%c%s", HUD_PRINTCENTER, CHudTextMessage::BufferedLocaliseTextString( "#Spec_Duck" ) ); - tempString[ sizeof( tempString ) - 1 ] = '\0'; - - gHUD.m_TextMessage.MsgFunc_TextMsg( NULL, strlen( tempString ) + 1, tempString ); - } - - sprintf(bottomText,"#Spec_Mode%d", g_iUser1 ); - sprintf(helpString2,"#Spec_Mode%d", g_iUser1 ); - - if ( gEngfuncs.IsSpectateOnly() ) - strcat(helpString2, " - HLTV"); - - // check if we're locked onto a target, show the player's name - if ( (g_iUser2 > 0) && (g_iUser2 <= gEngfuncs.GetMaxClients()) && (g_iUser1 != OBS_ROAMING) ) - { - player = g_iUser2; - } - - // special case in free map and inset off, don't show names - if ( (g_iUser1 == OBS_MAP_FREE) && !gHUD.m_Spectator.m_pip->value ) - name = NULL; - else - name = g_PlayerInfoList[player].name; - - // create player & health string - if ( player && name ) - { - strcpy( bottomText, name ); - } - - // in first person mode colorize player names - if ( (g_iUser1 == OBS_IN_EYE) && player ) - { - float * color = GetClientColor( player ); - int r = color[0]*255; - int g = color[1]*255; - int b = color[2]*255; - - // set team color, a bit transparent - m_pSpectatorPanel->m_BottomMainLabel->setFgColor(r,g,b,0); - } - else - { // restore GUI color - m_pSpectatorPanel->m_BottomMainLabel->setFgColor( Scheme::sc_primary1 ); - } - - // add sting auto if we are in auto directed mode - if ( gHUD.m_Spectator.m_autoDirector->value ) - { - char tempString[128]; - sprintf(tempString, "#Spec_Auto %s", helpString2); - strcpy( helpString2, tempString ); - } - - m_pSpectatorPanel->m_BottomMainLabel->setText( CHudTextMessage::BufferedLocaliseTextString( bottomText ) ); - m_pSpectatorPanel->m_TopMainLabel->setText( CHudTextMessage::BufferedLocaliseTextString( helpString2 ) ); - - } - else - { - m_pSpectatorPanel->setVisible( false ); - m_pSpectatorPanel->ShowMenu( false ); // dsiable all menus/buttons - } -} - -//====================================================================== -void TeamFortressViewport::CreateScoreBoard( void ) -{ - int xdent = SBOARD_INDENT_X, ydent = SBOARD_INDENT_Y; - if (ScreenWidth == 512) - { - xdent = SBOARD_INDENT_X_512; - ydent = SBOARD_INDENT_Y_512; - } - else if (ScreenWidth == 400) - { - xdent = SBOARD_INDENT_X_400; - ydent = SBOARD_INDENT_Y_400; - } - m_pScoreBoard = new ScorePanel(xdent, ydent, ScreenWidth - (xdent * 2), ScreenHeight - (ydent * 2)); - m_pScoreBoard->setParent(this); - m_pScoreBoard->setVisible(false); -} - -void TeamFortressViewport::CreateServerBrowser( void ) -{ - m_pServerBrowser = new ServerBrowser( 0, 0, ScreenWidth, ScreenHeight ); - m_pServerBrowser->setParent(this); - m_pServerBrowser->setVisible(false); -} - - -//====================================================================== -// Set the VGUI Menu -void TeamFortressViewport::SetCurrentMenu( CMenuPanel *pMenu ) -{ - m_pCurrentMenu = pMenu; - if ( m_pCurrentMenu ) - { - // Don't open menus in demo playback - if ( gEngfuncs.pDemoAPI->IsPlayingback() ) - return; - - m_pCurrentMenu->Open(); - } -} - -//================================================================ -// Text Window -CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow ) -{ - char sz[256]; - char *cText; - char *pfile = NULL; - static const int MAX_TITLE_LENGTH = 32; - char cTitle[MAX_TITLE_LENGTH]; - - if ( iTextToShow == SHOW_MOTD ) - { - if (!m_szServerName || !m_szServerName[0]) - strcpy( cTitle, "Half-Life" ); - else - strncpy( cTitle, m_szServerName, MAX_TITLE_LENGTH ); - cTitle[MAX_TITLE_LENGTH-1] = 0; - cText = m_szMOTD; - } - else if ( iTextToShow == SHOW_MAPBRIEFING ) - { - // Get the current mapname, and open it's map briefing text - if (m_sMapName && m_sMapName[0]) - { - strcpy( sz, "maps/"); - strcat( sz, m_sMapName ); - strcat( sz, ".txt" ); - } - else - { - const char *level = gEngfuncs.pfnGetLevelName(); - if (!level) - return NULL; - - strcpy( sz, level ); - char *ch = strchr( sz, '.' ); - *ch = '\0'; - strcat( sz, ".txt" ); - - // pull out the map name - strcpy( m_sMapName, level ); - ch = strchr( m_sMapName, '.' ); - if ( ch ) - { - *ch = 0; - } - - ch = strchr( m_sMapName, '/' ); - if ( ch ) - { - // move the string back over the '/' - memmove( m_sMapName, ch+1, strlen(ch)+1 ); - } - } - - pfile = (char*)gEngfuncs.COM_LoadFile( sz, 5, NULL ); - - if (!pfile) - return NULL; - - cText = pfile; - - strncpy( cTitle, m_sMapName, MAX_TITLE_LENGTH ); - cTitle[MAX_TITLE_LENGTH-1] = 0; - } - else if ( iTextToShow == SHOW_SPECHELP ) - { - CHudTextMessage::LocaliseTextString( "#Spec_Help_Title", cTitle, MAX_TITLE_LENGTH ); - cTitle[MAX_TITLE_LENGTH-1] = 0; - - char *pfile = CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help_Text" ); - if ( pfile ) - { - cText = pfile; - } - } - else - return NULL; - - // if we're in the game (ie. have selected a class), flag the menu to be only grayed in the dialog box, instead of full screen - CMenuPanel *pMOTDPanel = CMessageWindowPanel_Create( cText, cTitle, g_iPlayerClass == 11, false, 0, 0, ScreenWidth, ScreenHeight ); - pMOTDPanel->setParent( this ); - - if ( pfile ) - gEngfuncs.COM_FreeFile( pfile ); - - return pMOTDPanel; -} - -//================================================================ -// VGUI Menus -void TeamFortressViewport::ShowVGUIMenu( int iMenu ) -{ - CMenuPanel *pNewMenu = NULL; - - // Don't open menus in demo playback - if ( gEngfuncs.pDemoAPI->IsPlayingback() ) - return; - - // Don't create one if it's already in the list - if (m_pCurrentMenu) - { - CMenuPanel *pMenu = m_pCurrentMenu; - while (pMenu != NULL) - { - if (pMenu->GetMenuID() == iMenu) - return; - pMenu = pMenu->GetNextMenu(); - } - } - - switch ( iMenu ) - { - case MENU_TEAM: - pNewMenu = ShowTeamMenu(); - break; - - // Map Briefing removed now that it appears in the team menu - case MENU_MAPBRIEFING: - pNewMenu = CreateTextWindow( SHOW_MAPBRIEFING ); - break; - - case MENU_INTRO: - pNewMenu = CreateTextWindow( SHOW_MOTD ); - break; - - case MENU_CLASSHELP: - pNewMenu = CreateTextWindow( SHOW_CLASSDESC ); - break; - - case MENU_SPECHELP: - pNewMenu = CreateTextWindow( SHOW_SPECHELP ); - break; - case MENU_CLASS: - pNewMenu = ShowClassMenu(); - break; - - default: - break; - } - - if (!pNewMenu) - return; - - // Close the Command Menu if it's open - HideCommandMenu(); - - pNewMenu->SetMenuID( iMenu ); - pNewMenu->SetActive( true ); - pNewMenu->setParent(this); - - // See if another menu is visible, and if so, cache this one for display once the other one's finished - if (m_pCurrentMenu) - { - m_pCurrentMenu->SetNextMenu( pNewMenu ); - } - else - { - m_pCurrentMenu = pNewMenu; - m_pCurrentMenu->Open(); - UpdateCursorState(); - } -} - -// Removes all VGUI Menu's onscreen -void TeamFortressViewport::HideVGUIMenu() -{ - while (m_pCurrentMenu) - { - HideTopMenu(); - } -} - -// Remove the top VGUI menu, and bring up the next one -void TeamFortressViewport::HideTopMenu() -{ - if (m_pCurrentMenu) - { - // Close the top one - m_pCurrentMenu->Close(); - - // Bring up the next one - gViewPort->SetCurrentMenu( m_pCurrentMenu->GetNextMenu() ); - } - - UpdateCursorState(); -} - -// Return TRUE if the HUD's allowed to print text messages -bool TeamFortressViewport::AllowedToPrintText( void ) -{ - // Prevent text messages when fullscreen menus are up - if ( m_pCurrentMenu && g_iPlayerClass == 0 ) - { - int iId = m_pCurrentMenu->GetMenuID(); - if ( iId == MENU_TEAM || iId == MENU_CLASS || iId == MENU_INTRO || iId == MENU_CLASSHELP ) - return FALSE; - } - - return TRUE; -} - -//====================================================================================== -// TEAM MENU -//====================================================================================== -// Bring up the Team selection Menu -CMenuPanel* TeamFortressViewport::ShowTeamMenu() -{ - // Don't open menus in demo playback - if ( gEngfuncs.pDemoAPI->IsPlayingback() ) - return NULL; - -// m_pTeamMenu->Reset(); -// return m_pTeamMenu; - - return NULL; -} - -void TeamFortressViewport::CreateTeamMenu() -{ - // Create the panel -/* m_pTeamMenu = new CTeamMenuPanel(100, false, 0, 0, ScreenWidth, ScreenHeight); - m_pTeamMenu->setParent( this ); - m_pTeamMenu->setVisible( false );*/ -} - -//====================================================================================== -// CLASS MENU -//====================================================================================== -// Bring up the Class selection Menu -CMenuPanel* TeamFortressViewport::ShowClassMenu() -{ - // Don't open menus in demo playback - if ( gEngfuncs.pDemoAPI->IsPlayingback() ) - return NULL; - -// m_pClassMenu->Reset(); -// return m_pClassMenu; - - return NULL; -} - -void TeamFortressViewport::CreateClassMenu() -{ - // Create the panel -/* m_pClassMenu = new CClassMenuPanel(100, false, 0, 0, ScreenWidth, ScreenHeight); - m_pClassMenu->setParent(this); - m_pClassMenu->setVisible( false );*/ -} - -//====================================================================================== -// SPECTATOR MENU -//====================================================================================== -// Spectator "Menu" explaining the Spectator buttons -void TeamFortressViewport::CreateSpectatorMenu() -{ - // Create the Panel - m_pSpectatorPanel = new SpectatorPanel(0, 0, ScreenWidth, ScreenHeight); - m_pSpectatorPanel->setParent(this); - m_pSpectatorPanel->setVisible(false); - m_pSpectatorPanel->Initialize(); -} - -//====================================================================================== -// UPDATE HUD SECTIONS -//====================================================================================== -// We've got an update on player info -// Recalculate any menus that use it. -void TeamFortressViewport::UpdateOnPlayerInfo() -{ -/* if (m_pTeamMenu) - m_pTeamMenu->Update(); - if (m_pClassMenu) - m_pClassMenu->Update();*/ - if (m_pScoreBoard) - m_pScoreBoard->Update(); -} - -void TeamFortressViewport::UpdateCursorState() -{ - // Need cursor if any VGUI window is up - if ( m_pSpectatorPanel->m_menuVisible || m_pCurrentMenu || m_pServerBrowser->isVisible() || GetClientVoiceMgr()->IsInSquelchMode() ) - { - g_iVisibleMouse = true; - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_arrow) ); - return; - } - else if ( m_pCurrentCommandMenu ) - { - // commandmenu doesn't have cursor if hud_capturemouse is turned off - if ( gHUD.m_pCvarStealMouse->value != 0.0f ) - { - g_iVisibleMouse = true; - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_arrow) ); - return; - } - } - - IN_ResetMouse(); - g_iVisibleMouse = false; - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_none) ); -} - -void TeamFortressViewport::UpdateHighlights() -{ - if (m_pCurrentCommandMenu) - m_pCurrentCommandMenu->MakeVisible( NULL ); -} - -void TeamFortressViewport::GetAllPlayersInfo( void ) -{ - for ( int i = 1; i < MAX_PLAYERS; i++ ) - { - GetPlayerInfo( i, &g_PlayerInfoList[i] ); - - if ( g_PlayerInfoList[i].thisplayer ) - m_pScoreBoard->m_iPlayerNum = i; // !!!HACK: this should be initialized elsewhere... maybe gotten from the engine - } -} - -void TeamFortressViewport::paintBackground() -{ - int wide, tall; - getParent()->getSize( wide, tall ); - setSize( wide, tall ); - - // See if the command menu is visible and needs recalculating due to some external change -/* if ( g_iTeamNumber != m_iCurrentTeamNumber ) - { - UpdateCommandMenu(); - - if ( m_pClassMenu ) - { - m_pClassMenu->Update(); - } - - m_iCurrentTeamNumber = g_iTeamNumber; - } - - if ( g_iPlayerClass != m_iCurrentPlayerClass ) - { - UpdateCommandMenu(); - - m_iCurrentPlayerClass = g_iPlayerClass; - } */ - - // See if the Spectator Menu needs to be update - if ( g_iUser1 != m_iUser1 || g_iUser2 != m_iUser2 ) - { - UpdateSpectatorPanel(); - } - - // Update the Scoreboard, if it's visible - if ( m_pScoreBoard->isVisible() && (m_flScoreBoardLastUpdated < gHUD.m_flTime) ) - { - m_pScoreBoard->Update(); - m_flScoreBoardLastUpdated = gHUD.m_flTime + 0.5; - } - - int extents[4]; - getAbsExtents(extents[0],extents[1],extents[2],extents[3]); - VGui_ViewportPaintBackground(extents); -} - -//================================================================ -// Input Handler for Drag N Drop panels -void CDragNDropHandler::cursorMoved(int x,int y,Panel* panel) -{ - if(m_bDragging) - { - App::getInstance()->getCursorPos(x,y); - m_pPanel->setPos(m_iaDragOrgPos[0]+(x-m_iaDragStart[0]),m_iaDragOrgPos[1]+(y-m_iaDragStart[1])); - - if(m_pPanel->getParent()!=null) - { - m_pPanel->getParent()->repaint(); - } - } -} - -void CDragNDropHandler::mousePressed(MouseCode code,Panel* panel) -{ - int x,y; - App::getInstance()->getCursorPos(x,y); - m_bDragging=true; - m_iaDragStart[0]=x; - m_iaDragStart[1]=y; - m_pPanel->getPos(m_iaDragOrgPos[0],m_iaDragOrgPos[1]); - App::getInstance()->setMouseCapture(panel); - - m_pPanel->setDragged(m_bDragging); - m_pPanel->requestFocus(); -} - -void CDragNDropHandler::mouseReleased(MouseCode code,Panel* panel) -{ - m_bDragging=false; - m_pPanel->setDragged(m_bDragging); - App::getInstance()->setMouseCapture(null); -} - -//================================================================ -// Number Key Input -bool TeamFortressViewport::SlotInput( int iSlot ) -{ - // If there's a menu up, give it the input - if ( m_pCurrentMenu ) - return m_pCurrentMenu->SlotInput( iSlot ); - - return FALSE; -} - -// Direct Key Input -int TeamFortressViewport::KeyInput( int down, int keynum, const char *pszCurrentBinding ) -{ - // Enter gets out of Spectator Mode by bringing up the Team Menu - if (m_iUser1 && gEngfuncs.Con_IsVisible() == false ) - { - if ( down && (keynum == K_ENTER || keynum == K_KP_ENTER) ) - ShowVGUIMenu( MENU_TEAM ); - } - - // Open Text Window? - if (m_pCurrentMenu && gEngfuncs.Con_IsVisible() == false) - { - int iMenuID = m_pCurrentMenu->GetMenuID(); - - // Get number keys as Input for Team/Class menus - if (iMenuID == MENU_TEAM || iMenuID == MENU_CLASS) - { - // Escape gets you out of Team/Class menus if the Cancel button is visible - if ( keynum == K_ESCAPE ) - { - if ( (iMenuID == MENU_TEAM && g_iTeamNumber) || (iMenuID == MENU_CLASS && g_iPlayerClass) ) - { - HideTopMenu(); - return 0; - } - } - - for (int i = '0'; i <= '9'; i++) - { - if ( down && (keynum == i) ) - { - SlotInput( i - '0' ); - return 0; - } - } - } - - // Grab enter keys to close TextWindows - if ( down && (keynum == K_ENTER || keynum == K_KP_ENTER || keynum == K_SPACE || keynum == K_ESCAPE) ) - { - if ( iMenuID == MENU_MAPBRIEFING || iMenuID == MENU_INTRO || iMenuID == MENU_CLASSHELP ) - { - HideTopMenu(); - return 0; - } - } - - // Grab jump key on Team Menu as autoassign - if ( pszCurrentBinding && down && !strcmp(pszCurrentBinding, "+jump") ) - { - if (iMenuID == MENU_TEAM) - { -// m_pTeamMenu->SlotInput(5); - return 0; - } - } - - } - - // if we're in a command menu, try hit one of it's buttons - if ( down && m_pCurrentCommandMenu ) - { - // Escape hides the command menu - if ( keynum == K_ESCAPE ) - { - HideCommandMenu(); - return 0; - } - - // only trap the number keys - if ( keynum >= '0' && keynum <= '9' ) - { - if ( m_pCurrentCommandMenu->KeyInput(keynum) ) - { - // a final command has been issued, so close the command menu - HideCommandMenu(); - } - - return 0; - } - } - - return 1; -} - -//================================================================ -// Message Handlers -int TeamFortressViewport::MsgFunc_ValClass(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - for (int i = 0; i < 5; i++) - m_iValidClasses[i] = READ_SHORT(); - - // Force the menu to update - UpdateCommandMenu( m_StandardMenu ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_TeamNames(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iNumberOfTeams = READ_BYTE(); - - for (int i = 0; i < m_iNumberOfTeams; i++) - { - int teamNum = i + 1; - - gHUD.m_TextMessage.LocaliseTextString( READ_STRING(), m_sTeamNames[teamNum], MAX_TEAMNAME_SIZE ); - - // Set the team name buttons - if (m_pTeamButtons[i]) - m_pTeamButtons[i]->setText( m_sTeamNames[teamNum] ); - - // Set the disguise buttons - if (m_pDisguiseButtons[i]) - m_pDisguiseButtons[i]->setText( m_sTeamNames[teamNum] ); - } - - // Update the Team Menu -// if (m_pTeamMenu) -// m_pTeamMenu->Update(); - - return 1; -} - -int TeamFortressViewport::MsgFunc_Feign(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iIsFeigning = READ_BYTE(); - - // Force the menu to update - UpdateCommandMenu( m_StandardMenu ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_Detpack(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iIsSettingDetpack = READ_BYTE(); - - // Force the menu to update - UpdateCommandMenu( m_StandardMenu ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_VGUIMenu(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int iMenu = READ_BYTE(); - - // Map briefing includes the name of the map (because it's sent down before the client knows what map it is) - if (iMenu == MENU_MAPBRIEFING) - { - strncpy( m_sMapName, READ_STRING(), sizeof(m_sMapName) ); - m_sMapName[ sizeof(m_sMapName) - 1 ] = '\0'; - } - - // Bring up the menu6 - ShowVGUIMenu( iMenu ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf ) -{ - if (m_iGotAllMOTD) - m_szMOTD[0] = 0; - - BEGIN_READ( pbuf, iSize ); - - m_iGotAllMOTD = READ_BYTE(); - int roomInArray = sizeof(m_szMOTD) - strlen(m_szMOTD) - 1; - - strncat( m_szMOTD, READ_STRING(), roomInArray >= 0 ? roomInArray : 0 ); - m_szMOTD[ sizeof(m_szMOTD)-1 ] = '\0'; - - if ( m_iGotAllMOTD ) - { - ShowVGUIMenu( MENU_INTRO ); - } - - return 1; -} - -int TeamFortressViewport::MsgFunc_BuildSt( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iBuildState = READ_BYTE(); - - // Force the menu to update - UpdateCommandMenu( m_StandardMenu ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_RandomPC( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iRandomPC = READ_BYTE(); - - return 1; -} - -int TeamFortressViewport::MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - strncpy( m_szServerName, READ_STRING(), MAX_SERVERNAME_LENGTH ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - short cl = READ_BYTE(); - short frags = READ_SHORT(); - short deaths = READ_SHORT(); - short teamnumber = READ_SHORT(); - - if ( cl > 0 && cl <= MAX_PLAYERS ) - { - g_PlayerExtraInfo[cl].frags = frags; - g_PlayerExtraInfo[cl].deaths = deaths; - g_PlayerExtraInfo[cl].teamnumber = teamnumber; - - UpdateOnPlayerInfo(); - } - - return 1; -} - -// Message handler for TeamScore message -// accepts three values: -// string: team name -// short: teams kills -// short: teams deaths -// if this message is never received, then scores will simply be the combined totals of the players. -int TeamFortressViewport::MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - char *TeamName = READ_STRING(); - - // find the team matching the name - int i; - for ( i = 1; i <= m_pScoreBoard->m_iNumTeams; i++ ) - { - if ( !stricmp( TeamName, g_TeamInfo[i].name ) ) - break; - } - - if ( i > m_pScoreBoard->m_iNumTeams ) - return 1; - - // use this new score data instead of combined player scoresw - g_TeamInfo[i].scores_overriden = TRUE; - g_TeamInfo[i].frags = READ_SHORT(); - g_TeamInfo[i].deaths = READ_SHORT(); - - return 1; -} - -// Message handler for TeamInfo message -// accepts two values: -// byte: client number -// string: client team name -int TeamFortressViewport::MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf ) -{ - if (!m_pScoreBoard) - return 1; - - BEGIN_READ( pbuf, iSize ); - short cl = READ_BYTE(); - - if ( cl > 0 && cl <= MAX_PLAYERS ) - { - // set the players team - strncpy( g_PlayerExtraInfo[cl].teamname, READ_STRING(), MAX_TEAM_NAME ); - } - - // rebuild the list of teams - m_pScoreBoard->RebuildTeams(); - - return 1; -} - -void TeamFortressViewport::DeathMsg( int killer, int victim ) -{ - m_pScoreBoard->DeathMsg(killer,victim); -} - -int TeamFortressViewport::MsgFunc_Spectator( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - -/* short cl = READ_BYTE(); - if ( cl > 0 && cl <= MAX_PLAYERS ) - { - g_IsSpectator[cl] = READ_BYTE(); - }*/ - - return 1; -} - -int TeamFortressViewport::MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iAllowSpectators = READ_BYTE(); - - // Force the menu to update - UpdateCommandMenu( m_StandardMenu ); - - // If the team menu is up, update it too -// if (m_pTeamMenu) -// m_pTeamMenu->Update(); - - return 1; -} - diff --git a/dmc/cl_dll/vgui_viewport.h b/dmc/cl_dll/vgui_viewport.h deleted file mode 100644 index 1fcd156..0000000 --- a/dmc/cl_dll/vgui_viewport.h +++ /dev/null @@ -1,1331 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef TEAMFORTRESSVIEWPORT_H -#define TEAMFORTRESSVIEWPORT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// custom scheme handling -#include "vgui_SchemeManager.h" - -#define PC_LASTCLASS 12 - -#define MENU_DEFAULT 1 -#define MENU_TEAM 2 -#define MENU_CLASS 3 -#define MENU_MAPBRIEFING 4 -#define MENU_INTRO 5 -#define MENU_CLASSHELP 6 -#define MENU_CLASSHELP2 7 -#define MENU_REPEATHELP 8 -#define MENU_SPECHELP 9 - - -using namespace vgui; - -class Cursor; -class ScorePanel; -class SpectatorPanel; -class CCommandMenu; -class CommandLabel; -class CommandButton; -class BuildButton; -class ClassButton; -class CMenuPanel; -class ServerBrowser; -class DragNDropPanel; -class CTransparentPanel; -//class CClassMenuPanel; -//class CTeamMenuPanel; - -char* GetVGUITGAName(const char *pszName); -BitmapTGA *LoadTGA( const char* pImageName ); -void ScaleColors( int &r, int &g, int &b, int a ); -extern char *sTFClassSelection[]; -extern int sTFValidClassInts[]; -extern char *sLocalisedClasses[]; -extern int iTeamColors[5][3]; - -#define MAX_SERVERNAME_LENGTH 32 - - -// Command Menu positions -#define MAX_MENUS 40 -#define MAX_BUTTONS 100 - -#define BUTTON_SIZE_Y YRES(30) -#define CMENU_SIZE_X XRES(160) - -#define SUBMENU_SIZE_X (CMENU_SIZE_X / 8) -#define SUBMENU_SIZE_Y (BUTTON_SIZE_Y / 6) - -#define CMENU_TOP (BUTTON_SIZE_Y * 4) - -#define MAX_TEAMNAME_SIZE 64 -#define MAX_BUTTON_SIZE 32 - -// Map Briefing Window -#define MAPBRIEF_INDENT 30 - -// Team Menu -#define TMENU_INDENT_X (30 * ((float)ScreenHeight / 640)) -#define TMENU_HEADER 100 -#define TMENU_SIZE_X (ScreenWidth - (TMENU_INDENT_X * 2)) -#define TMENU_SIZE_Y (TMENU_HEADER + BUTTON_SIZE_Y * 7) -#define TMENU_PLAYER_INDENT (((float)TMENU_SIZE_X / 3) * 2) -#define TMENU_INDENT_Y (((float)ScreenHeight - TMENU_SIZE_Y) / 2) - -// Class Menu -#define CLMENU_INDENT_X (30 * ((float)ScreenHeight / 640)) -#define CLMENU_HEADER 100 -#define CLMENU_SIZE_X (ScreenWidth - (CLMENU_INDENT_X * 2)) -#define CLMENU_SIZE_Y (CLMENU_HEADER + BUTTON_SIZE_Y * 11) -#define CLMENU_PLAYER_INDENT (((float)CLMENU_SIZE_X / 3) * 2) -#define CLMENU_INDENT_Y (((float)ScreenHeight - CLMENU_SIZE_Y) / 2) - -// Arrows -enum -{ - ARROW_UP, - ARROW_DOWN, - ARROW_LEFT, - ARROW_RIGHT, -}; - -//============================================================================== -// VIEWPORT PIECES -//============================================================ -// Wrapper for an Image Label without a background -class CImageLabel : public Label -{ -public: - BitmapTGA *m_pTGA; - -public: - CImageLabel( const char* pImageName,int x,int y ); - CImageLabel( const char* pImageName,int x,int y,int wide,int tall ); - - virtual int getImageTall(); - virtual int getImageWide(); - - virtual void paintBackground() - { - // Do nothing, so the background's left transparent. - } -}; - -// Command Label -// Overridden label so we can darken it when submenus open -class CommandLabel : public Label -{ -private: - int m_iState; - -public: - CommandLabel(const char* text,int x,int y,int wide,int tall) : Label(text,x,y,wide,tall) - { - m_iState = false; - } - - void PushUp() - { - m_iState = false; - repaint(); - } - - void PushDown() - { - m_iState = true; - repaint(); - } -}; - -//============================================================ -// Command Buttons -class CommandButton : public Button -{ -private: - int m_iPlayerClass; - - // Submenus under this button - CCommandMenu *m_pSubMenu; - CCommandMenu *m_pParentMenu; - CommandLabel *m_pSubLabel; - - char m_sMainText[MAX_BUTTON_SIZE]; - char m_cBoundKey; - - SchemeHandle_t m_hTextScheme; - - void RecalculateText( void ); - -public: - bool m_bNoHighlight; - -public: - // Constructors - CommandButton( const char* text,int x,int y,int wide,int tall, bool bNoHighlight = false); - CommandButton( int iPlayerClass, const char* text,int x,int y,int wide,int tall); - - void Init( void ); - - // Menu Handling - void AddSubMenu( CCommandMenu *pNewMenu ); - void AddSubLabel( CommandLabel *pSubLabel ) - { - m_pSubLabel = pSubLabel; - } - - virtual int IsNotValid( void ) - { - return false; - } - - void UpdateSubMenus( int iAdjustment ); - int GetPlayerClass() { return m_iPlayerClass; }; - CCommandMenu *GetSubMenu() { return m_pSubMenu; }; - - CCommandMenu *getParentMenu( void ); - void setParentMenu( CCommandMenu *pParentMenu ); - - // Overloaded vgui functions - virtual void paint(); - virtual void setText( const char *text ); - virtual void paintBackground(); - - void cursorEntered( void ); - void cursorExited( void ); - - void setBoundKey( char boundKey ); - char getBoundKey( void ); -}; - -//============================================================ -// Command Menus -class CCommandMenu : public Panel -{ -private: - CCommandMenu *m_pParentMenu; - int m_iXOffset; - int m_iYOffset; - - // Buttons in this menu - CommandButton *m_aButtons[ MAX_BUTTONS ]; - int m_iButtons; - - // opens menu from top to bottom (0 = default), or from bottom to top (1)? - int m_iDirection; -public: - CCommandMenu( CCommandMenu *pParentMenu, int x,int y,int wide,int tall ) : Panel(x,y,wide,tall) - { - m_pParentMenu = pParentMenu; - m_iXOffset = x; - m_iYOffset = y; - m_iButtons = 0; - m_iDirection = 0; - } - - CCommandMenu( CCommandMenu *pParentMenu, int direction, int x,int y,int wide,int tall ) : Panel(x,y,wide,tall) - { - m_pParentMenu = pParentMenu; - m_iXOffset = x; - m_iYOffset = y; - m_iButtons = 0; - m_iDirection = direction; - } - - void AddButton( CommandButton *pButton ); - bool RecalculateVisibles( int iNewYPos, bool bHideAll ); - void RecalculatePositions( int iYOffset ); - void MakeVisible( CCommandMenu *pChildMenu ); - - CCommandMenu *GetParentMenu() { return m_pParentMenu; }; - int GetXOffset() { return m_iXOffset; }; - int GetYOffset() { return m_iYOffset; }; - int GetDirection() { return m_iDirection; }; - int GetNumButtons() { return m_iButtons; }; - CommandButton *FindButtonWithSubmenu( CCommandMenu *pSubMenu ); - - void ClearButtonsOfArmedState( void ); - - - bool KeyInput( int keyNum ); - - virtual void paintBackground(); -}; - -//============================================================================== -class TeamFortressViewport : public Panel -{ -private: - vgui::Cursor* _cursorNone; - vgui::Cursor* _cursorArrow; - - int m_iInitialized; - - CCommandMenu *m_pCommandMenus[ MAX_MENUS ]; - CCommandMenu *m_pCurrentCommandMenu; - float m_flMenuOpenTime; - float m_flScoreBoardLastUpdated; - int m_iNumMenus; - int m_iCurrentTeamNumber; - int m_iCurrentPlayerClass; - int m_iUser1; - int m_iUser2; - - // VGUI Menus - void CreateTeamMenu( void ); - CMenuPanel* ShowTeamMenu( void ); - void CreateClassMenu( void ); - CMenuPanel* ShowClassMenu( void ); - void CreateSpectatorMenu( void ); - - // Scheme handler - CSchemeManager m_SchemeManager; - - // MOTD - int m_iGotAllMOTD; - char m_szMOTD[ MAX_MOTD_LENGTH ]; - - // Command Menu Team buttons - CommandButton *m_pTeamButtons[6]; - CommandButton *m_pDisguiseButtons[5]; - BuildButton *m_pBuildButtons[3]; - BuildButton *m_pBuildActiveButtons[3]; - - // Server Browser - ServerBrowser *m_pServerBrowser; - - int m_iAllowSpectators; - - // Data for specific sections of the Command Menu - int m_iValidClasses[5]; - int m_iIsFeigning; - int m_iIsSettingDetpack; - int m_iNumberOfTeams; - int m_iBuildState; - int m_iRandomPC; - char m_sTeamNames[5][MAX_TEAMNAME_SIZE]; - - // Localisation strings - char m_sDetpackStrings[3][MAX_BUTTON_SIZE]; - - char m_sMapName[64]; -public: - TeamFortressViewport(int x,int y,int wide,int tall); - void Initialize( void ); - - int CreateCommandMenu( char * menuFile, int direction, int yOffset ); - void CreateScoreBoard( void ); - void CreateServerBrowser( void ); - CommandButton * CreateCustomButton( char *pButtonText, char * pButtonName, int iYOffset ); - CCommandMenu * CreateDisguiseSubmenu( CommandButton *pButton, CCommandMenu *pParentMenu, const char *commandText, int iYOffset ); - - void UpdateCursorState( void ); - void UpdateCommandMenu(int menuIndex); - void UpdateOnPlayerInfo( void ); - void UpdateHighlights( void ); - void UpdateSpectatorPanel( void ); - - int KeyInput( int down, int keynum, const char *pszCurrentBinding ); - void InputPlayerSpecial( void ); - void GetAllPlayersInfo( void ); - void DeathMsg( int killer, int victim ); - - void ShowCommandMenu(int menuIndex); - void InputSignalHideCommandMenu( void ); - void HideCommandMenu( void ); - void SetCurrentCommandMenu( CCommandMenu *pNewMenu ); - void SetCurrentMenu( CMenuPanel *pMenu ); - - void ShowScoreBoard( void ); - void HideScoreBoard( void ); - bool IsScoreBoardVisible( void ); - - bool AllowedToPrintText( void ); - - void ShowVGUIMenu( int iMenu ); - void HideVGUIMenu( void ); - void HideTopMenu( void ); - - void ToggleServerBrowser( void ); - - CMenuPanel* CreateTextWindow( int iTextToShow ); - - CCommandMenu *CreateSubMenu( CommandButton *pButton, CCommandMenu *pParentMenu, int iYOffset ); - - // Data Handlers - int GetValidClasses(int iTeam) { return m_iValidClasses[iTeam]; }; - int GetNumberOfTeams() { return m_iNumberOfTeams; }; - int GetIsFeigning() { return m_iIsFeigning; }; - int GetIsSettingDetpack() { return m_iIsSettingDetpack; }; - int GetBuildState() { return m_iBuildState; }; - int IsRandomPC() { return m_iRandomPC; }; - char *GetTeamName( int iTeam ) { return m_sTeamNames[iTeam]; }; - int GetAllowSpectators() { return m_iAllowSpectators; }; - - // Message Handlers - int MsgFunc_ValClass(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_TeamNames(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_Feign(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_Detpack(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_VGUIMenu(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_BuildSt( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_RandomPC( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_Spectator( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf ); - - // Input - bool SlotInput( int iSlot ); - - virtual void paintBackground(); - - CSchemeManager *GetSchemeManager( void ) { return &m_SchemeManager; } - - void *operator new( size_t stAllocateBlock ); - -public: - // VGUI Menus - CMenuPanel *m_pCurrentMenu; - int m_SpectatorMenu; // indexs in m_pCommandMenus - int m_StandardMenu; -// CTeamMenuPanel *m_pTeamMenu; -// CClassMenuPanel *m_pClassMenu; - ScorePanel *m_pScoreBoard; - SpectatorPanel *m_pSpectatorPanel; - char m_szServerName[ MAX_SERVERNAME_LENGTH ]; -}; - -//============================================================ -// Command Menu Button Handlers -#define MAX_COMMAND_SIZE 256 - -class CMenuHandler_StringCommand : public ActionSignal -{ -protected: - char m_pszCommand[MAX_COMMAND_SIZE]; - int m_iCloseVGUIMenu; -public: - CMenuHandler_StringCommand( char *pszCommand ) - { - strncpy( m_pszCommand, pszCommand, MAX_COMMAND_SIZE); - m_pszCommand[MAX_COMMAND_SIZE-1] = '\0'; - m_iCloseVGUIMenu = false; - } - - CMenuHandler_StringCommand( char *pszCommand, int iClose ) - { - strncpy( m_pszCommand, pszCommand, MAX_COMMAND_SIZE); - m_pszCommand[MAX_COMMAND_SIZE-1] = '\0'; - m_iCloseVGUIMenu = true; - } - - virtual void actionPerformed(Panel* panel) - { - gEngfuncs.pfnClientCmd(m_pszCommand); - - if (m_iCloseVGUIMenu) - gViewPort->HideTopMenu(); - else - gViewPort->HideCommandMenu(); - } -}; - -// This works the same as CMenuHandler_StringCommand, except it watches the string command -// for specific commands, and modifies client vars based upon them. -class CMenuHandler_StringCommandWatch : public CMenuHandler_StringCommand -{ -private: -public: - CMenuHandler_StringCommandWatch( char *pszCommand ) : CMenuHandler_StringCommand( pszCommand ) - { - } - - CMenuHandler_StringCommandWatch( char *pszCommand, int iClose ) : CMenuHandler_StringCommand( pszCommand, iClose ) - { - } - - virtual void actionPerformed(Panel* panel) - { - CMenuHandler_StringCommand::actionPerformed( panel ); - - // Try to guess the player's new team (it'll be corrected if it's wrong) - /* if ( !strcmp( m_pszCommand, "jointeam 1" ) ) - g_iTeamNumber = 1; - else if ( !strcmp( m_pszCommand, "jointeam 2" ) ) - g_iTeamNumber = 2; - else if ( !strcmp( m_pszCommand, "jointeam 3" ) ) - g_iTeamNumber = 3; - else if ( !strcmp( m_pszCommand, "jointeam 4" ) ) - g_iTeamNumber = 4;*/ - } -}; - -// Used instead of CMenuHandler_StringCommand for Class Selection buttons. -// Checks the state of hud_classautokill and kills the player if set -class CMenuHandler_StringCommandClassSelect : public CMenuHandler_StringCommand -{ -private: -public: - CMenuHandler_StringCommandClassSelect( char *pszCommand ) : CMenuHandler_StringCommand( pszCommand ) - { - } - - CMenuHandler_StringCommandClassSelect( char *pszCommand, int iClose ) : CMenuHandler_StringCommand( pszCommand, iClose ) - { - } - - virtual void actionPerformed(Panel* panel); -}; - -class CMenuHandler_PopupSubMenuInput : public InputSignal -{ -private: - CCommandMenu *m_pSubMenu; - Button *m_pButton; -public: - CMenuHandler_PopupSubMenuInput( Button *pButton, CCommandMenu *pSubMenu ) - { - m_pSubMenu = pSubMenu; - m_pButton = pButton; - } - - virtual void cursorMoved(int x,int y,Panel* panel) - { - //gViewPort->SetCurrentCommandMenu( m_pSubMenu ); - } - - virtual void cursorEntered(Panel* panel) - { - gViewPort->SetCurrentCommandMenu( m_pSubMenu ); - - if (m_pButton) - m_pButton->setArmed(true); - }; - virtual void cursorExited(Panel* Panel) {}; - virtual void mousePressed(MouseCode code,Panel* panel) {}; - virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}; - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -class CMenuHandler_LabelInput : public InputSignal -{ -private: - ActionSignal *m_pActionSignal; -public: - CMenuHandler_LabelInput( ActionSignal *pSignal ) - { - m_pActionSignal = pSignal; - } - - virtual void mousePressed(MouseCode code,Panel* panel) - { - m_pActionSignal->actionPerformed( panel ); - } - - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void cursorEntered(Panel* panel) {}; - virtual void cursorExited(Panel* Panel) {}; - virtual void cursorMoved(int x,int y,Panel* panel) {}; - virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -#define HIDE_TEXTWINDOW 0 -#define SHOW_MAPBRIEFING 1 -#define SHOW_CLASSDESC 2 -#define SHOW_MOTD 3 -#define SHOW_SPECHELP 4 - -class CMenuHandler_TextWindow : public ActionSignal -{ -private: - int m_iState; -public: - CMenuHandler_TextWindow( int iState ) - { - m_iState = iState; - } - - virtual void actionPerformed(Panel* panel) - { - if (m_iState == HIDE_TEXTWINDOW) - { - gViewPort->HideTopMenu(); - } - else - { - gViewPort->HideCommandMenu(); - gViewPort->ShowVGUIMenu( m_iState ); - } - } -}; - -class CMenuHandler_ToggleCvar : public ActionSignal -{ -private: - struct cvar_s * m_cvar; - -public: - CMenuHandler_ToggleCvar( char * cvarname ) - { - m_cvar = gEngfuncs.pfnGetCvarPointer( cvarname ); - } - - virtual void actionPerformed(Panel* panel) - { - if ( m_cvar->value ) - m_cvar->value = 0.0f; - else - m_cvar->value = 1.0f; - - gViewPort->UpdateSpectatorPanel(); - } - - -}; -class CDragNDropHandler : public InputSignal -{ -private: - DragNDropPanel* m_pPanel; - bool m_bDragging; - int m_iaDragOrgPos[2]; - int m_iaDragStart[2]; - -public: - CDragNDropHandler(DragNDropPanel* pPanel) - { - m_pPanel = pPanel; - m_bDragging = false; - } - - void cursorMoved(int x,int y,Panel* panel); - void mousePressed(MouseCode code,Panel* panel); - void mouseReleased(MouseCode code,Panel* panel); - - void mouseDoublePressed(MouseCode code,Panel* panel) {}; - void cursorEntered(Panel* panel) {}; - void cursorExited(Panel* panel) {}; - void mouseWheeled(int delta,Panel* panel) {}; - void keyPressed(KeyCode code,Panel* panel) {}; - void keyTyped(KeyCode code,Panel* panel) {}; - void keyReleased(KeyCode code,Panel* panel) {}; - void keyFocusTicked(Panel* panel) {}; -}; - -class CHandler_MenuButtonOver : public InputSignal -{ -private: - int m_iButton; - CMenuPanel *m_pMenuPanel; -public: - CHandler_MenuButtonOver( CMenuPanel *pPanel, int iButton ) - { - m_iButton = iButton; - m_pMenuPanel = pPanel; - } - - void cursorEntered(Panel *panel); - - void cursorMoved(int x,int y,Panel* panel) {}; - void mousePressed(MouseCode code,Panel* panel) {}; - void mouseReleased(MouseCode code,Panel* panel) {}; - void mouseDoublePressed(MouseCode code,Panel* panel) {}; - void cursorExited(Panel* panel) {}; - void mouseWheeled(int delta,Panel* panel) {}; - void keyPressed(KeyCode code,Panel* panel) {}; - void keyTyped(KeyCode code,Panel* panel) {}; - void keyReleased(KeyCode code,Panel* panel) {}; - void keyFocusTicked(Panel* panel) {}; -}; - -class CHandler_ButtonHighlight : public InputSignal -{ -private: - Button *m_pButton; -public: - CHandler_ButtonHighlight( Button *pButton ) - { - m_pButton = pButton; - } - - virtual void cursorEntered(Panel* panel) - { - m_pButton->setArmed(true); - }; - virtual void cursorExited(Panel* Panel) - { - m_pButton->setArmed(false); - }; - virtual void mousePressed(MouseCode code,Panel* panel) {}; - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void cursorMoved(int x,int y,Panel* panel) {}; - virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -//----------------------------------------------------------------------------- -// Purpose: Special handler for highlighting of command menu buttons -//----------------------------------------------------------------------------- -class CHandler_CommandButtonHighlight : public CHandler_ButtonHighlight -{ -private: - CommandButton *m_pCommandButton; -public: - CHandler_CommandButtonHighlight( CommandButton *pButton ) : CHandler_ButtonHighlight( pButton ) - { - m_pCommandButton = pButton; - } - - virtual void cursorEntered( Panel *panel ) - { - m_pCommandButton->cursorEntered(); - } - - virtual void cursorExited( Panel *panel ) - { - m_pCommandButton->cursorExited(); - } -}; - - -//================================================================ -// Overidden Command Buttons for special visibilities -class ClassButton : public CommandButton -{ -protected: - int m_iPlayerClass; - -public: - ClassButton( int iClass, const char* text,int x,int y,int wide,int tall, bool bNoHighlight ) : CommandButton( text,x,y,wide,tall, bNoHighlight) - { - m_iPlayerClass = iClass; - } - - virtual int IsNotValid(); -}; - -class TeamButton : public CommandButton -{ -private: - int m_iTeamNumber; -public: - TeamButton( int iTeam, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - m_iTeamNumber = iTeam; - } - - virtual int IsNotValid() - { - int iTeams = gViewPort->GetNumberOfTeams(); - // Never valid if there's only 1 team - if (iTeams == 1) - return true; - - // Auto Team's always visible - if (m_iTeamNumber == 5) - return false; - -// if (iTeams >= m_iTeamNumber && m_iTeamNumber != g_iTeamNumber) -// return false; - - return true; - } -}; - -class FeignButton : public CommandButton -{ -private: - int m_iFeignState; -public: - FeignButton( int iState, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - m_iFeignState = iState; - } - - virtual int IsNotValid() - { - return true; - } -}; - -class SpectateButton : public CommandButton -{ -public: - SpectateButton( const char* text,int x,int y,int wide,int tall, bool bNoHighlight ) : CommandButton( text,x,y,wide,tall, bNoHighlight) - { - } - - virtual int IsNotValid() - { - // Only visible if the server allows it - if ( gViewPort->GetAllowSpectators() != 0 ) - return false; - - return true; - } -}; - -#define DISGUISE_TEAM1 (1<<0) -#define DISGUISE_TEAM2 (1<<1) -#define DISGUISE_TEAM3 (1<<2) -#define DISGUISE_TEAM4 (1<<3) - -class DisguiseButton : public CommandButton -{ -private: - int m_iValidTeamsBits; - int m_iThisTeam; -public: - DisguiseButton( int iValidTeamNumsBits, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall,false ) - { - m_iValidTeamsBits = iValidTeamNumsBits; - } - - virtual int IsNotValid() - { - // if it's not tied to a specific team, then always show (for spies) - if ( !m_iValidTeamsBits ) - return false; - - // if we're tied to a team make sure we can change to that team - int iTmp = 1 << (gViewPort->GetNumberOfTeams() - 1); - if ( m_iValidTeamsBits & iTmp ) - return false; - - return true; - } -}; - -class DetpackButton : public CommandButton -{ -private: - int m_iDetpackState; -public: - DetpackButton( int iState, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - m_iDetpackState = iState; - } - - virtual int IsNotValid() - { - return true; - } -}; - -extern int iBuildingCosts[]; -#define BUILDSTATE_HASBUILDING (1<<0) // Data is building ID (1 = Dispenser, 2 = Sentry) -#define BUILDSTATE_BUILDING (1<<1) -#define BUILDSTATE_BASE (1<<2) -#define BUILDSTATE_CANBUILD (1<<3) // Data is building ID (0 = Dispenser, 1 = Sentry) - -class BuildButton : public CommandButton -{ -private: - int m_iBuildState; - int m_iBuildData; - -public: - enum Buildings - { - DISPENSER = 0, - SENTRYGUN = 1, - }; - - BuildButton( int iState, int iData, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - m_iBuildState = iState; - m_iBuildData = iData; - } - - virtual int IsNotValid() - { - return true; - } -}; - -#define MAX_MAPNAME 256 - -class MapButton : public CommandButton -{ -private: - char m_szMapName[ MAX_MAPNAME ]; - -public: - MapButton( const char *pMapName, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - sprintf( m_szMapName, "maps/%s.bsp", pMapName ); - } - - virtual int IsNotValid() - { - const char *level = gEngfuncs.pfnGetLevelName(); - if (!level) - return true; - - // Does it match the current map name? - if ( strcmp(m_szMapName, level) ) - return true; - - return false; - } -}; - -//----------------------------------------------------------------------------- -// Purpose: CommandButton which is only displayed if the player is on team X -//----------------------------------------------------------------------------- -class TeamOnlyCommandButton : public CommandButton -{ -private: - int m_iTeamNum; - -public: - TeamOnlyCommandButton( int iTeamNum, const char* text,int x,int y,int wide,int tall ) : - CommandButton( text, x, y, wide, tall ), m_iTeamNum(iTeamNum) {} - - virtual int IsNotValid() - { -/* if ( g_iTeamNumber != m_iTeamNum ) - return true;*/ - - return CommandButton::IsNotValid(); - } -}; - -//----------------------------------------------------------------------------- -// Purpose: CommandButton which is only displayed if the player is on team X -//----------------------------------------------------------------------------- -class ToggleCommandButton : public CommandButton, public InputSignal -{ -private: - struct cvar_s * m_cvar; - CImageLabel * pLabelOn; - CImageLabel * pLabelOff; - - -public: - ToggleCommandButton( const char* cvarname, const char* text,int x,int y,int wide,int tall ) : - CommandButton( text, x, y, wide, tall ) - { - m_cvar = gEngfuncs.pfnGetCvarPointer( cvarname ); - - // Put a > to show it's a submenu - pLabelOn = new CImageLabel( "checked", 0, 0 ); - pLabelOn->setParent(this); - pLabelOn->addInputSignal(this); - - pLabelOff = new CImageLabel( "unchecked", 0, 0 ); - pLabelOff->setParent(this); - pLabelOff->setEnabled(true); - pLabelOff->addInputSignal(this); - - int textwide, texttall; - getTextSize( textwide, texttall); - - // Reposition - pLabelOn->setPos( textwide, (tall - pLabelOn->getTall()) / 2 ); - - pLabelOff->setPos( textwide, (tall - pLabelOff->getTall()) / 2 ); - - // Set text color to orange - setFgColor(Scheme::sc_primary1); - } - - virtual void cursorEntered(Panel* panel) - { - CommandButton::cursorEntered(); - } - - virtual void cursorExited(Panel* panel) - { - CommandButton::cursorExited(); - } - - virtual void mousePressed(MouseCode code,Panel* panel) - { - doClick(); - }; - - virtual void cursorMoved(int x,int y,Panel* panel) {}; - - virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}; - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; - - virtual void paint( void ) - { - if ( !m_cvar ) - { - pLabelOff->setVisible(false); - pLabelOn->setVisible(false); - } - else if ( m_cvar->value ) - { - pLabelOff->setVisible(false); - pLabelOn->setVisible(true); - } - else - { - pLabelOff->setVisible(true); - pLabelOn->setVisible(false); - } - - CommandButton::paint(); - - } -}; -//============================================================ -// Panel that can be dragged around -class DragNDropPanel : public Panel -{ -private: - bool m_bBeingDragged; - LineBorder *m_pBorder; -public: - DragNDropPanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall) - { - m_bBeingDragged = false; - - // Create the Drag Handler - addInputSignal( new CDragNDropHandler(this) ); - - // Create the border (for dragging) - m_pBorder = new LineBorder(); - } - - virtual void setDragged( bool bState ) - { - m_bBeingDragged = bState; - - if (m_bBeingDragged) - setBorder(m_pBorder); - else - setBorder(NULL); - } -}; - -//================================================================ -// Panel that draws itself with a transparent black background -class CTransparentPanel : public Panel -{ -private: - int m_iTransparency; -public: - CTransparentPanel(int iTrans, int x,int y,int wide,int tall) : Panel(x,y,wide,tall) - { - m_iTransparency = iTrans; - } - - virtual void paintBackground() - { - if (m_iTransparency) - { - // Transparent black background - drawSetColor( 0,0,0, m_iTransparency ); - drawFilledRect(0,0,_size[0],_size[1]); - } - } -}; - -//================================================================ -// Menu Panel that supports buffering of menus -class CMenuPanel : public CTransparentPanel -{ -private: - CMenuPanel *m_pNextMenu; - int m_iMenuID; - int m_iRemoveMe; - int m_iIsActive; - float m_flOpenTime; -public: - CMenuPanel(int iRemoveMe, int x,int y,int wide,int tall) : CTransparentPanel(100, x,y,wide,tall) - { - Reset(); - m_iRemoveMe = iRemoveMe; - } - - CMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide,int tall) : CTransparentPanel(iTrans, x,y,wide,tall) - { - Reset(); - m_iRemoveMe = iRemoveMe; - } - - virtual void Reset( void ) - { - m_pNextMenu = NULL; - m_iIsActive = false; - m_flOpenTime = 0; - } - - void SetNextMenu( CMenuPanel *pNextPanel ) - { - if (m_pNextMenu) - m_pNextMenu->SetNextMenu( pNextPanel ); - else - m_pNextMenu = pNextPanel; - } - - void SetMenuID( int iID ) - { - m_iMenuID = iID; - } - - void SetActive( int iState ) - { - m_iIsActive = iState; - } - - virtual void Open( void ) - { - setVisible( true ); - - // Note the open time, so we can delay input for a bit - m_flOpenTime = gHUD.m_flTime; - } - - virtual void Close( void ) - { - setVisible( false ); - m_iIsActive = false; - - if ( m_iMenuID == MENU_INTRO ) - { - gEngfuncs.pfnClientCmd( "_firstspawn\n" ); - } - - if ( m_iRemoveMe ) - gViewPort->removeChild( this ); - - // This MenuPanel has now been deleted. Don't append code here. - } - - int ShouldBeRemoved() { return m_iRemoveMe; }; - CMenuPanel* GetNextMenu() { return m_pNextMenu; }; - int GetMenuID() { return m_iMenuID; }; - int IsActive() { return m_iIsActive; }; - float GetOpenTime() { return m_flOpenTime; }; - - // Numeric input - virtual bool SlotInput( int iSlot ) { return false; }; - virtual void SetActiveInfo( int iInput ) {}; -}; - -//================================================================ -// Custom drawn scroll bars -class CTFScrollButton : public CommandButton -{ -private: - BitmapTGA *m_pTGA; - -public: - CTFScrollButton(int iArrow, const char* text,int x,int y,int wide,int tall); - - virtual void paint( void ); - virtual void paintBackground( void ); -}; - -// Custom drawn slider bar -class CTFSlider : public Slider -{ -public: - CTFSlider(int x,int y,int wide,int tall,bool vertical) : Slider(x,y,wide,tall,vertical) - { - }; - - virtual void paintBackground( void ); -}; - -// Custom drawn scrollpanel -class CTFScrollPanel : public ScrollPanel -{ -public: - CTFScrollPanel(int x,int y,int wide,int tall); -}; - -//================================================================ -// Menu Panels that take key input -//============================================================ -/*class CClassMenuPanel : public CMenuPanel -{ -private: - CTransparentPanel *m_pClassInfoPanel[PC_LASTCLASS]; - Label *m_pPlayers[PC_LASTCLASS]; - ClassButton *m_pButtons[PC_LASTCLASS]; - CommandButton *m_pCancelButton; - ScrollPanel *m_pScrollPanel; - - CImageLabel *m_pClassImages[MAX_TEAMS][PC_LASTCLASS]; - - int m_iCurrentInfo; - - enum { STRLENMAX_PLAYERSONTEAM = 128 }; - char m_sPlayersOnTeamString[STRLENMAX_PLAYERSONTEAM]; - -public: - CClassMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide,int tall); - - virtual bool SlotInput( int iSlot ); - virtual void Open( void ); - virtual void Update( void ); - virtual void SetActiveInfo( int iInput ); - virtual void Initialize( void ); - - virtual void Reset( void ) - { - CMenuPanel::Reset(); - m_iCurrentInfo = 0; - } -};*/ -/* -class CTeamMenuPanel : public CMenuPanel -{ -public: - ScrollPanel *m_pScrollPanel; - CTransparentPanel *m_pTeamWindow; - Label *m_pMapTitle; - TextPanel *m_pBriefing; - TextPanel *m_pTeamInfoPanel[6]; - CommandButton *m_pButtons[6]; - bool m_bUpdatedMapName; - CommandButton *m_pCancelButton; - CommandButton *m_pSpectateButton; - - int m_iCurrentInfo; - -public: - CTeamMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide,int tall); - - virtual bool SlotInput( int iSlot ); - virtual void Open( void ); - virtual void Update( void ); - virtual void SetActiveInfo( int iInput ); - virtual void paintBackground( void ); - - virtual void Initialize( void ); - - virtual void Reset( void ) - { - CMenuPanel::Reset(); - m_iCurrentInfo = 0; - } -}; -*/ -//========================================================= -// Specific Menus to handle old HUD sections -class CHealthPanel : public DragNDropPanel -{ -private: - BitmapTGA *m_pHealthTGA; - Label *m_pHealthLabel; -public: - CHealthPanel(int x,int y,int wide,int tall) : DragNDropPanel(x,y,wide,tall) - { - // Load the Health icon - FileInputStream* fis = new FileInputStream( GetVGUITGAName("%d_hud_health"), false); - m_pHealthTGA = new BitmapTGA(fis,true); - fis->close(); - - // Create the Health Label - int iXSize,iYSize; - m_pHealthTGA->getSize(iXSize,iYSize); - m_pHealthLabel = new Label("",0,0,iXSize,iYSize); - m_pHealthLabel->setImage(m_pHealthTGA); - m_pHealthLabel->setParent(this); - - // Set panel dimension - // Shouldn't be needed once Billy's fized setImage not recalculating the size - //setSize( iXSize + 100, gHUD.m_iFontHeight + 10 ); - //m_pHealthLabel->setPos( 10, (getTall() - iYSize) / 2 ); - } - - virtual void paintBackground() - { - } - - void paint() - { - // Get the paint color - int r,g,b,a; - // Has health changed? Flash the health # - if (gHUD.m_Health.m_fFade) - { - gHUD.m_Health.m_fFade -= (gHUD.m_flTimeDelta * 20); - if (gHUD.m_Health.m_fFade <= 0) - { - a = MIN_ALPHA; - gHUD.m_Health.m_fFade = 0; - } - - // Fade the health number back to dim - a = MIN_ALPHA + (gHUD.m_Health.m_fFade/FADE_TIME) * 128; - } - else - a = MIN_ALPHA; - - gHUD.m_Health.GetPainColor( r, g, b ); - ScaleColors(r, g, b, a ); - - // If health is getting low, make it bright red - if (gHUD.m_Health.m_iHealth <= 15) - a = 255; - - int iXSize,iYSize, iXPos, iYPos; - m_pHealthTGA->getSize(iXSize,iYSize); - m_pHealthTGA->getPos(iXPos, iYPos); - - // Paint the player's health - int x = gHUD.DrawHudNumber( iXPos + iXSize + 5, iYPos + 5, DHN_3DIGITS | DHN_DRAWZERO, gHUD.m_Health.m_iHealth, r, g, b); - - // Draw the vertical line - int HealthWidth = gHUD.GetSpriteRect(gHUD.m_HUD_number_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).left; - x += HealthWidth / 2; - FillRGBA(x, iYPos + 5, HealthWidth / 10, gHUD.m_iFontHeight, 255, 160, 0, a); - } -}; - -#endif diff --git a/dmc/cl_dll/view.cpp b/dmc/cl_dll/view.cpp deleted file mode 100644 index a5546b8..0000000 --- a/dmc/cl_dll/view.cpp +++ /dev/null @@ -1,1678 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// view/refresh setup functions - -#include -#include "hud.h" -#include "cl_util.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" - -#include "entity_state.h" -#include "cl_entity.h" -#include "ref_params.h" -#include "in_defs.h" // PITCH YAW ROLL -#include "pm_movevars.h" -#include "pm_shared.h" -#include "pm_defs.h" -#include "event_api.h" -#include "pmtrace.h" -#include "hltv.h" - - -// QUAKECLASSIC -extern int iMouseInUse; -extern vec3_t vecTempAngles; -extern bool bChangeAngles; - - -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -extern "C" -{ - int CL_IsThirdPerson( void ); - void CL_CameraOffset( float *ofs ); - - void DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams ); - - void PM_ParticleLine( float *start, float *end, int pcolor, float life, float vert); - int PM_GetInfo( int ent ); -} - -void InterpolateAngles( float * start, float * end, float * output, float frac ); -void NormalizeAngles( float * angles ); -float Distance( const float * v1, const float * v2 ); -float AngleBetweenVectors( const float * v1, const float * v2 ); - -extern float vJumpOrigin[ 3 ]; -extern float vJumpAngles[ 3 ]; - -#include "r_studioint.h" -#include "com_model.h" - -extern engine_studio_api_t IEngineStudio; - -void V_DropPunchAngle ( float frametime, float *ev_punchangle ); -void VectorAngles( const float *forward, float *angles ); - -/* -The view is allowed to move slightly from it's true position for bobbing, -but if it exceeds 8 pixels linear distance (spherical, not box), the list of -entities sent from the server may not include everything in the pvs, especially -when crossing a water boudnary. -*/ - -extern cvar_t *cl_forwardspeed; -extern cvar_t *chase_active; -extern cvar_t *cl_vsmoothing; - -vec3_t v_origin, v_angles, v_cl_angles, v_sim_org, v_lastAngles; -float v_frametime, v_lastDistance; - -vec3_t ev_punchangle; - -cvar_t *scr_ofsx; -cvar_t *scr_ofsy; -cvar_t *scr_ofsz; - -cvar_t *v_centermove; -cvar_t *v_centerspeed; - -cvar_t *cl_bobcycle; -cvar_t *cl_bob; -cvar_t *cl_bobup; -cvar_t *cl_waterdist; -cvar_t *cl_chasedist; - -// These cvars are not registered (so users can't cheat), so set the ->value field directly -// Register these cvars in V_Init() if needed for easy tweaking -cvar_t v_iyaw_cycle = {"v_iyaw_cycle", "2", 0, 2}; -cvar_t v_iroll_cycle = {"v_iroll_cycle", "0.5", 0, 0.5}; -cvar_t v_ipitch_cycle = {"v_ipitch_cycle", "1", 0, 1}; -cvar_t v_iyaw_level = {"v_iyaw_level", "0.3", 0, 0.3}; -cvar_t v_iroll_level = {"v_iroll_level", "0.1", 0, 0.1}; -cvar_t v_ipitch_level = {"v_ipitch_level", "0.3", 0, 0.3}; - -float v_idlescale; // used by TFC for concussion grenade effect - -/* -//============================================================================= -void V_NormalizeAngles( float *angles ) -{ - int i; - // Normalize angles - for ( i = 0; i < 3; i++ ) - { - if ( angles[i] > 180.0 ) - { - angles[i] -= 360.0; - } - else if ( angles[i] < -180.0 ) - { - angles[i] += 360.0; - } - } -} - -/* -=================== -V_InterpolateAngles - -Interpolate Euler angles. -FIXME: Use Quaternions to avoid discontinuities -Frac is 0.0 to 1.0 ( i.e., should probably be clamped, but doesn't have to be ) -=================== - -void V_InterpolateAngles( float *start, float *end, float *output, float frac ) -{ - int i; - float ang1, ang2; - float d; - - V_NormalizeAngles( start ); - V_NormalizeAngles( end ); - - for ( i = 0 ; i < 3 ; i++ ) - { - ang1 = start[i]; - ang2 = end[i]; - - d = ang2 - ang1; - if ( d > 180 ) - { - d -= 360; - } - else if ( d < -180 ) - { - d += 360; - } - - output[i] = ang1 + d * frac; - } - - V_NormalizeAngles( output ); -} */ - - -// Quakeworld bob code, this fixes jitters in the mutliplayer since the clock (pparams->time) isn't quite linear -float V_CalcBob ( struct ref_params_s *pparams ) -{ - static double bobtime; - static float bob; - float cycle; - static float lasttime; - vec3_t vel; - - - if ( pparams->onground == -1 || - pparams->time == lasttime ) - { - // just use old value - return bob; - } - - lasttime = pparams->time; - - bobtime += pparams->frametime; - cycle = bobtime - (int)( bobtime / cl_bobcycle->value ) * cl_bobcycle->value; - cycle /= cl_bobcycle->value; - - if ( cycle < cl_bobup->value ) - { - cycle = M_PI * cycle / cl_bobup->value; - } - else - { - cycle = M_PI + M_PI * ( cycle - cl_bobup->value )/( 1.0 - cl_bobup->value ); - } - - // bob is proportional to simulated velocity in the xy plane - // (don't count Z, or jumping messes it up) - VectorCopy( pparams->simvel, vel ); - vel[2] = 0; - - bob = sqrt( vel[0] * vel[0] + vel[1] * vel[1] ) * cl_bob->value; - bob = bob * 0.3 + bob * 0.7 * sin(cycle); - bob = V_min( bob, 4 ); - bob = V_max( bob, -7 ); - return bob; - -} - -/* -=============== -V_CalcRoll -Used by view and sv_user -=============== -*/ -float V_CalcRoll (vec3_t angles, vec3_t velocity, float rollangle, float rollspeed ) -{ - float sign; - float side; - float value; - vec3_t forward, right, up; - - AngleVectors ( angles, forward, right, up ); - - side = DotProduct (velocity, right); - sign = side < 0 ? -1 : 1; - side = fabs( side ); - - value = rollangle; - if (side < rollspeed) - { - side = side * value / rollspeed; - } - else - { - side = value; - } - return side * sign; -} - - -typedef struct pitchdrift_s -{ - float pitchvel; - int nodrift; - float driftmove; - double laststop; -} pitchdrift_t; - -static pitchdrift_t pd; - -void V_StartPitchDrift( void ) -{ - if ( pd.laststop == gEngfuncs.GetClientTime() ) - { - return; // something else is keeping it from drifting - } - - if ( pd.nodrift || !pd.pitchvel ) - { - pd.pitchvel = v_centerspeed->value; - pd.nodrift = 0; - pd.driftmove = 0; - } -} - -void V_StopPitchDrift ( void ) -{ - pd.laststop = gEngfuncs.GetClientTime(); - pd.nodrift = 1; - pd.pitchvel = 0; -} - -/* -=============== -V_DriftPitch - -Moves the client pitch angle towards idealpitch sent by the server. - -If the user is adjusting pitch manually, either with lookup/lookdown, -mlook and mouse, or klook and keyboard, pitch drifting is constantly stopped. -=============== -*/ -#include "kbutton.h" -extern kbutton_t in_mlook; - -void V_DriftPitch ( struct ref_params_s *pparams ) -{ - float delta, move; - - if ( ( in_mlook.state & 1) || gEngfuncs.IsNoClipping() || !pparams->onground || pparams->demoplayback || pparams->spectator ) - { - pd.driftmove = 0; - pd.pitchvel = 0; - return; - } - - // don't count small mouse motion - if (pd.nodrift) - { - if ( fabs( pparams->cmd->forwardmove ) < cl_forwardspeed->value ) - pd.driftmove = 0; - else - pd.driftmove += pparams->frametime; - - if ( pd.driftmove > v_centermove->value) - { - V_StartPitchDrift (); - } - return; - } - - delta = pparams->idealpitch - pparams->cl_viewangles[PITCH]; - - if (!delta) - { - pd.pitchvel = 0; - return; - } - - move = pparams->frametime * pd.pitchvel; - pd.pitchvel += pparams->frametime * v_centerspeed->value; - -//Con_Printf ("move: %f (%f)\n", move, pparams->frametime); - - if (delta > 0) - { - if (move > delta) - { - pd.pitchvel = 0; - move = delta; - } - pparams->cl_viewangles[PITCH] += move; - } - else if (delta < 0) - { - if (move > -delta) - { - pd.pitchvel = 0; - move = -delta; - } - pparams->cl_viewangles[PITCH] -= move; - } -} - -/* -============================================================================== - VIEW RENDERING -============================================================================== -*/ - -/* -================== -V_CalcGunAngle -================== -*/ -void V_CalcGunAngle ( struct ref_params_s *pparams ) -{ - cl_entity_t *viewent; - - viewent = gEngfuncs.GetViewModel(); - if ( !viewent ) - return; - - viewent->angles[YAW] = pparams->viewangles[YAW] + pparams->crosshairangle[YAW]; - viewent->angles[PITCH] = -pparams->viewangles[PITCH] + pparams->crosshairangle[PITCH] * 0.25; - viewent->angles[ROLL] -= v_idlescale * sin(pparams->time*v_iroll_cycle.value) * v_iroll_level.value; - - // don't apply all of the v_ipitch to prevent normally unseen parts of viewmodel from coming into view. - viewent->angles[PITCH] -= v_idlescale * sin(pparams->time*v_ipitch_cycle.value) * (v_ipitch_level.value * 0.5); - viewent->angles[YAW] -= v_idlescale * sin(pparams->time*v_iyaw_cycle.value) * v_iyaw_level.value; - - VectorCopy( viewent->angles, viewent->curstate.angles ); - VectorCopy( viewent->angles, viewent->latched.prevangles ); -} - -/* -============== -V_AddIdle - -Idle swaying -============== -*/ -void V_AddIdle ( struct ref_params_s *pparams ) -{ - pparams->viewangles[ROLL] += v_idlescale * sin(pparams->time*v_iroll_cycle.value) * v_iroll_level.value; - pparams->viewangles[PITCH] += v_idlescale * sin(pparams->time*v_ipitch_cycle.value) * v_ipitch_level.value; - pparams->viewangles[YAW] += v_idlescale * sin(pparams->time*v_iyaw_cycle.value) * v_iyaw_level.value; -} - - -extern cvar_t *cl_rollspeed; -extern cvar_t *cl_rollangle; -/* -============== -V_CalcViewRoll - -Roll is induced by movement and damage -============== -*/ -void V_CalcViewRoll ( struct ref_params_s *pparams ) -{ - cl_entity_t *viewentity; - - viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); - if ( !viewentity ) - return; - - //Roll the angles when strafing Quake style! - pparams->viewangles[ROLL] = V_CalcRoll (pparams->viewangles, pparams->simvel, cl_rollangle->value, cl_rollspeed->value ) * 4; - - if ( pparams->health <= 0 && ( pparams->viewheight[2] != 0 ) ) - { - // only roll the view if the player is dead and the viewheight[2] is nonzero - // this is so deadcam in multiplayer will work. - pparams->viewangles[ROLL] = 80; // dead view angle - return; - } -} - - -/* -================== -V_CalcIntermissionRefdef - -================== -*/ -void V_CalcIntermissionRefdef ( struct ref_params_s *pparams ) -{ - cl_entity_t *ent, *view; - float old; - -// don't allow cheats in multiplayer - if ( pparams->maxclients > 1 ) - { - scr_ofsx->value = 0.0; - scr_ofsy->value = 0.0; - scr_ofsz->value = 0.0; - } - - // ent is the player model ( visible when out of body ) - ent = gEngfuncs.GetLocalPlayer(); - - // view is the weapon model (only visible from inside body ) - view = gEngfuncs.GetViewModel(); - - VectorCopy ( pparams->simorg, pparams->vieworg ); - VectorCopy ( pparams->cl_viewangles, pparams->viewangles ); - - view->model = NULL; - - // allways idle in intermission - old = v_idlescale; - v_idlescale = 1; - - V_AddIdle ( pparams ); - - if ( gEngfuncs.IsSpectateOnly() ) - { - // in HLTV we must go to 'intermission' position by ourself - VectorCopy( gHUD.m_Spectator.m_cameraOrigin, pparams->vieworg ); - VectorCopy( gHUD.m_Spectator.m_cameraAngles, pparams->viewangles ); - } - v_idlescale = old; - - v_cl_angles = pparams->cl_viewangles; - v_origin = pparams->vieworg; - v_angles = pparams->viewangles; -} - -#define ORIGIN_BACKUP 64 -#define ORIGIN_MASK ( ORIGIN_BACKUP - 1 ) - -typedef struct -{ - float Origins[ ORIGIN_BACKUP ][3]; - float OriginTime[ ORIGIN_BACKUP ]; - - float Angles[ ORIGIN_BACKUP ][3]; - float AngleTime[ ORIGIN_BACKUP ]; - - int CurrentOrigin; - int CurrentAngle; -} viewinterp_t; - -/* -================== -V_CalcRefdef - -================== -*/ -void V_CalcNormalRefdef ( struct ref_params_s *pparams ) -{ - cl_entity_t *ent, *view; - int i; - vec3_t angles; - float bob, waterOffset; - static viewinterp_t ViewInterp; - - static float oldz = 0; - static float lasttime; - - static float lastang[3]; - vec3_t angdelta; - - vec3_t camAngles, camForward, camRight, camUp; - cl_entity_t *pwater; - - //Force angle change - if ( bChangeAngles == true ) - { - pparams->cl_viewangles[PITCH] = vecTempAngles[PITCH]; - pparams->cl_viewangles[YAW] = vecTempAngles[YAW]; - pparams->cl_viewangles[ROLL] = vecTempAngles[ROLL]; - - vecTempAngles = Vector ( 0, 0, 0 ); - bChangeAngles = false; - } - - // don't allow cheats in multiplayer - if ( pparams->maxclients > 1 ) - { - gEngfuncs.Cvar_SetValue ("scr_ofsx", 0); - gEngfuncs.Cvar_SetValue ("scr_ofsy", 0); - gEngfuncs.Cvar_SetValue ("scr_ofsz", 0); - } - - V_DriftPitch ( pparams ); - - // ent is the player model ( visible when out of body ) - ent = gEngfuncs.GetLocalPlayer(); - - // view is the weapon model (only visible from inside body ) - view = gEngfuncs.GetViewModel(); - - // transform the view offset by the model's matrix to get the offset from - // model origin for the view - bob = V_CalcBob ( pparams ); - - // refresh position - VectorCopy ( pparams->simorg, pparams->vieworg ); - pparams->vieworg[2] += ( bob ); - VectorAdd( pparams->vieworg, pparams->viewheight, pparams->vieworg ); - - VectorCopy ( pparams->cl_viewangles, pparams->viewangles ); - - gEngfuncs.V_CalcShake(); - gEngfuncs.V_ApplyShake( pparams->vieworg, pparams->viewangles, 1.0 ); - - // never let view origin sit exactly on a node line, because a water plane can - // dissapear when viewed with the eye exactly on it. - // FIXME, we send origin at 1/128 now, change this? - // the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis - - pparams->vieworg[0] += 1.0/32; - pparams->vieworg[1] += 1.0/32; - pparams->vieworg[2] += 1.0/32; - - // Check for problems around water, move the viewer artificially if necessary - // -- this prevents drawing errors in GL due to waves - - waterOffset = 0; - if ( pparams->waterlevel >= 2 ) - { - int i, contents, waterDist, waterEntity; - vec3_t point; - waterDist = cl_waterdist->value; - - if ( pparams->hardware ) - { - waterEntity = gEngfuncs.PM_WaterEntity( pparams->simorg ); - if ( waterEntity >= 0 && waterEntity < pparams->max_entities ) - { - pwater = gEngfuncs.GetEntityByIndex( waterEntity ); - if ( pwater && ( pwater->model != NULL ) ) - { - waterDist += ( pwater->curstate.scale * 16 ); // Add in wave height - } - } - } - else - { - waterEntity = 0; // Don't need this in software - } - - VectorCopy( pparams->vieworg, point ); - - // Eyes are above water, make sure we're above the waves - if ( pparams->waterlevel == 2 ) - { - point[2] -= waterDist; - for ( i = 0; i < waterDist; i++ ) - { - contents = gEngfuncs.PM_PointContents( point, NULL ); - if ( contents > CONTENTS_WATER ) - break; - point[2] += 1; - } - waterOffset = (point[2] + waterDist) - pparams->vieworg[2]; - } - else - { - // eyes are under water. Make sure we're far enough under - point[2] += waterDist; - - for ( i = 0; i < waterDist; i++ ) - { - contents = gEngfuncs.PM_PointContents( point, NULL ); - if ( contents <= CONTENTS_WATER ) - break; - point[2] -= 1; - } - waterOffset = (point[2] - waterDist) - pparams->vieworg[2]; - } - } - - pparams->vieworg[2] += waterOffset; - - V_CalcViewRoll ( pparams ); - - V_AddIdle ( pparams ); - - // offsets - VectorCopy( pparams->cl_viewangles, angles ); - - AngleVectors ( angles, pparams->forward, pparams->right, pparams->up ); - - for ( i=0 ; i<3 ; i++ ) - { - pparams->vieworg[i] += scr_ofsx->value*pparams->forward[i] + scr_ofsy->value*pparams->right[i] + scr_ofsz->value*pparams->up[i]; - } - - // Treating cam_ofs[2] as the distance - if( CL_IsThirdPerson() ) - { - vec3_t ofs; - - ofs[0] = ofs[1] = ofs[2] = 0.0; - - CL_CameraOffset( (float *)&ofs ); - - VectorCopy( ofs, camAngles ); - camAngles[ ROLL ] = 0; - - AngleVectors( camAngles, camForward, camRight, camUp ); - - for ( i = 0; i < 3; i++ ) - { - pparams->vieworg[ i ] += -ofs[2] * camForward[ i ]; - } - } - - // Give gun our viewangles - VectorCopy ( pparams->cl_viewangles, view->angles ); - - // set up gun position - V_CalcGunAngle ( pparams ); - - // Use predicted origin as view origin. - VectorCopy ( pparams->simorg, view->origin ); - view->origin[2] += ( waterOffset ); - VectorAdd( view->origin, pparams->viewheight, view->origin ); - - // Let the viewmodel shake at about 10% of the amplitude - gEngfuncs.V_ApplyShake( view->origin, view->angles, 0.9 ); - - for ( i = 0; i < 3; i++ ) - { - view->origin[ i ] += bob * 0.4 * pparams->forward[ i ]; - } - view->origin[2] += bob; - - // throw in a little tilt. - view->angles[YAW] -= bob * 0.5; - view->angles[ROLL] -= bob * 1; - view->angles[PITCH] -= bob * 0.3; - - // pushing the view origin down off of the same X/Z plane as the ent's origin will give the - // gun a very nice 'shifting' effect when the player looks up/down. If there is a problem - // with view model distortion, this may be a cause. (SJB). - view->origin[2] -= 1; - - // fudge position around to keep amount of weapon visible - // roughly equal with different FOV - if (pparams->viewsize == 110) - { - view->origin[2] += 1; - } - else if (pparams->viewsize == 100) - { - view->origin[2] += 2; - } - else if (pparams->viewsize == 90) - { - view->origin[2] += 1; - } - else if (pparams->viewsize == 80) - { - view->origin[2] += 0.5; - } - - // Add in the punchangle, if any - VectorAdd ( pparams->viewangles, pparams->punchangle, pparams->viewangles ); - - // Include client side punch, too - VectorAdd ( pparams->viewangles, (float *)&ev_punchangle, pparams->viewangles); - - V_DropPunchAngle ( pparams->frametime, (float *)&ev_punchangle ); - - // smooth out stair step ups -#if 1 - if ( !pparams->smoothing && pparams->onground && pparams->simorg[2] - oldz > 0) - { - float steptime; - - steptime = pparams->time - lasttime; - if (steptime < 0) - //FIXME I_Error ("steptime < 0"); - steptime = 0; - - oldz += steptime * 150; - if (oldz > pparams->simorg[2]) - oldz = pparams->simorg[2]; - if (pparams->simorg[2] - oldz > 18) - oldz = pparams->simorg[2]- 18; - pparams->vieworg[2] += oldz - pparams->simorg[2]; - view->origin[2] += oldz - pparams->simorg[2]; - } - else - { - oldz = pparams->simorg[2]; - } -#endif - - { - static float lastorg[3]; - vec3_t delta; - - VectorSubtract( pparams->simorg, lastorg, delta ); - - if ( Length( delta ) != 0.0 ) - { - VectorCopy( pparams->simorg, ViewInterp.Origins[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] ); - ViewInterp.OriginTime[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] = pparams->time; - ViewInterp.CurrentOrigin++; - - VectorCopy( pparams->simorg, lastorg ); - } - } - - // Smooth out whole view in multiplayer when on trains, lifts - if ( cl_vsmoothing && cl_vsmoothing->value && - ( pparams->smoothing && ( pparams->maxclients > 1 ) ) ) - { - int foundidx; - int i; - float t; - - if ( cl_vsmoothing->value < 0.0 ) - { - gEngfuncs.Cvar_SetValue( "cl_vsmoothing", 0.0 ); - } - - t = pparams->time - cl_vsmoothing->value; - - for ( i = 1; i < ORIGIN_MASK; i++ ) - { - foundidx = ViewInterp.CurrentOrigin - 1 - i; - if ( ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] <= t ) - break; - } - - if ( i < ORIGIN_MASK && ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] != 0.0 ) - { - // Interpolate - vec3_t delta; - double frac; - double dt; - vec3_t neworg; - - dt = ViewInterp.OriginTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ]; - if ( dt > 0.0 ) - { - frac = ( t - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK] ) / dt; - frac = V_min( 1.0, frac ); - VectorSubtract( ViewInterp.Origins[ ( foundidx + 1 ) & ORIGIN_MASK ], ViewInterp.Origins[ foundidx & ORIGIN_MASK ], delta ); - VectorMA( ViewInterp.Origins[ foundidx & ORIGIN_MASK ], frac, delta, neworg ); - - VectorSubtract( neworg, pparams->simorg, delta ); - - VectorAdd( pparams->simorg, delta, pparams->simorg ); - VectorAdd( pparams->vieworg, delta, pparams->vieworg ); - VectorAdd( view->origin, delta, view->origin ); - } - } - } - - // Store off v_angles before munging for third person - v_angles = pparams->viewangles; - v_cl_angles = pparams->cl_viewangles; - - if ( CL_IsThirdPerson() ) - { - VectorCopy( camAngles, pparams->viewangles); - } - - // override all previous settings if the viewent isn't the client - if ( pparams->viewentity > pparams->maxclients ) - { - cl_entity_t *viewentity; - viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); - if ( viewentity ) - { - VectorCopy( viewentity->origin, pparams->vieworg ); - VectorCopy( viewentity->angles, pparams->viewangles ); - - // Store off overridden viewangles - v_angles = pparams->viewangles; - } - } - - lasttime = pparams->time; - - v_origin = pparams->vieworg; -} -void V_SmoothInterpolateAngles( float * startAngle, float * endAngle, float * finalAngle, float degreesPerSec ) -{ - float frac,d; - - NormalizeAngles( startAngle ); - NormalizeAngles( endAngle ); - - for ( int i = 0 ; i < 3 ; i++ ) - { - d = endAngle[i] - startAngle[i]; - - if ( d > 180.0f ) - { - d -= 360.0f; - } - else if ( d < -180.0f ) - { - d += 360.0f; - } - - float absd = fabs(d); - - if ( absd > 0.1f ) - { - frac = (degreesPerSec * v_frametime ) / absd; - - if ( absd < 45.0f ) - frac*= absd / 45.0f; // slow down last 45 degrees - - if ( frac > 1.0f ) - { - finalAngle[i] = endAngle[i]; - } - else - { - finalAngle[i] = startAngle[i] + d * frac; - } - } - else - { - finalAngle[i] = endAngle[i]; - } - - } - - NormalizeAngles( finalAngle ); -} - -// Get the origin of the Observer based around the target's position and angles -void V_GetChaseOrigin( float * angles, float * origin, float distance, qboolean worldOnly, float * returnvec ) -{ - int tracefinished = false; - vec3_t vecEnd; - vec3_t forward; - vec3_t vecStart; - pmtrace_t * trace; - - // Trace back from the target using the player's view angles - AngleVectors(angles, forward, NULL, NULL); - - VectorScale(forward,-1,forward); - - VectorCopy( origin, vecStart ); - - VectorMA(vecStart, distance , forward, vecEnd); - - while (!tracefinished) - { - - trace = gEngfuncs.PM_TraceLine( vecStart, vecEnd, PM_TRACELINE_PHYSENTSONLY, 2, -1 ); - - if ( trace->ent <= 0 || !worldOnly) - { - tracefinished = true; - } - else - { - if( Distance(trace->endpos, vecEnd ) > 1.0f ) - { - VectorAdd( trace->endpos, forward, vecStart); - } - else - { - tracefinished = true; - } - } - } - - // gEngfuncs.Con_Printf("Trace loop %i\n", trace->ent ); - - VectorMA( trace->endpos, 4, trace->plane.normal, returnvec ); - - v_lastDistance = Distance(trace->endpos, origin); // real distance without offset -} - -void V_GetDirectedChasePosition(cl_entity_t * ent1, cl_entity_t * ent2,float * angle, float * origin) -{ - float newAngle[3]; float newOrigin[3]; float tempVec[3]; - - int flags = gHUD.m_Spectator.m_iObserverFlags; - - qboolean deadPlayer = ent1->player && (ent1->curstate.solid == SOLID_NOT); - - float dfactor = ( flags & DRC_FLAG_DRAMATIC )? -1.0f : 1.0f; - - if ( ent1->player && (ent1->curstate.solid == SOLID_NOT) ) - dfactor = 1.5f; // zoom away if player dies - - float distance = 112.0f + ( 16.0f * dfactor ); // get close if dramatic; - - // go away in final scenes - if (flags & DRC_FLAG_FINAL ) - distance*=2.0f; - - // let v_lastDistance float smoothly away - v_lastDistance+= v_frametime * 24.0f; // move unit per seconds back - - if ( distance > v_lastDistance ) - distance = v_lastDistance; - - - VectorCopy(ent1->origin, newOrigin); - - if ( ent1->player ) - { - if ( deadPlayer ) - newOrigin[2]+= 2; //laying on ground - else - newOrigin[2]+= 28; // head level of living player - - } - else - newOrigin[2]+= 8; // object, tricky, must be above bomb in CS - - if ( ( ent2 == (cl_entity_t*)0xFFFFFFFF ) || deadPlayer ) // we have no second target or player just died - { - // we have no second target, choose view direction based on - // show front of primary target - VectorCopy(ent1->angles, newAngle); - newAngle[1]+= 180.0f; - - newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic - - // if final scene (bomb), show from real high pos - if ( flags & DRC_FLAG_FINAL ) - newAngle[0] = 22.5f; - - // choose side of object/player - if ( flags & DRC_FLAG_SIDE ) - newAngle[1]+=22.5f; - else - newAngle[1]-=22.5f; - - // if ( AngleBetweenVectors( tempVec, newAngle ) > 1.0f ) - V_SmoothInterpolateAngles( v_lastAngles, newAngle, angle, 120.0f ); - - // HACK, if player is dead don't clip against his dead body, can't check this - V_GetChaseOrigin( angle, newOrigin, distance, deadPlayer, origin ); - - } - else if ( ent2 ) - { - // get new angle towards second target - VectorSubtract( ent2->origin, ent1->origin, newAngle ); - - VectorAngles( newAngle, newAngle ); - newAngle[0] = -newAngle[0]; - - // set angle diffrent in Dramtaic scenes - newAngle[0]+= 12.5f * dfactor; // lower angle if dramatic - - if ( flags & DRC_FLAG_SIDE ) - newAngle[1]+=22.5f; - else - newAngle[1]-=22.5f; - - V_GetChaseOrigin( newAngle, newOrigin, distance, false, origin ); - - origin[2]+= 16.0f*( 1.0f - (v_lastDistance / distance) ); - - // calculate angle to second target - VectorSubtract( ent2->origin, origin, tempVec ); - VectorAngles( tempVec, tempVec ); - tempVec[0] = -tempVec[0]; - - // take middle between two viewangles - InterpolateAngles( newAngle, tempVec, angle, 0.5f); - - } - else - { - // second target disappeard somehow (dead) - // keep last good viewangle - V_GetChaseOrigin( angle, newOrigin, distance, false, origin ); - } - - VectorCopy(angle, v_lastAngles); -} - -void V_GetChasePos(int target, float * cl_angles, float * origin, float * angles) -{ - if ( !target) - { - // just copy a save in-map position - VectorCopy ( vJumpAngles, angles ); - VectorCopy ( vJumpOrigin, origin ); - return; - }; - - cl_entity_t * ent = gEngfuncs.GetEntityByIndex( target ); - - if (!ent) return; - - - if ( gHUD.m_Spectator.m_autoDirector->value ) - { - if ( g_iUser3 ) - V_GetDirectedChasePosition( ent, gEngfuncs.GetEntityByIndex( g_iUser3 ), - angles, origin ); - else - V_GetDirectedChasePosition( ent, ( cl_entity_t*)0xFFFFFFFF, - angles, origin ); - } - else - { - if ( cl_angles == NULL ) // no mouse angles given, use entity angles ( locked mode ) - { - VectorCopy ( ent->angles, angles); - angles[0]*=-1; - } - else - VectorCopy ( cl_angles, angles); - - - VectorCopy ( ent->origin, origin); - - origin[2]+= 28; // DEFAULT_VIEWHEIGHT - some offset - - V_GetChaseOrigin( angles, origin, cl_chasedist->value, false, origin ); - } -} - -void V_ResetChaseCam() -{ - v_lastDistance = 4096.0f; -} - - -void V_GetInEyePos(int target, float * origin, float * angles ) -{ - if ( !target) - { - // just copy a save in-map position - VectorCopy ( vJumpAngles, angles ); - VectorCopy ( vJumpOrigin, origin ); - return; - }; - - - cl_entity_t * ent = gEngfuncs.GetEntityByIndex( target ); - - if ( !ent ) - return; - - VectorCopy ( ent->origin, origin ); - VectorCopy ( ent->angles, angles ); - - angles[0]*=-M_PI; - - if ( ent->curstate.solid == SOLID_NOT ) - { - angles[ROLL] = 80; // dead view angle - origin[2]+= -8 ; // PM_DEAD_VIEWHEIGHT - } - else if (ent->curstate.usehull == 1 ) - origin[2]+= 12; // VEC_DUCK_VIEW; - else - // exacty eye position can't be caluculated since it depends on - // client values like cl_bobcycle, this offset matches the default values - origin[2]+= 28; // DEFAULT_VIEWHEIGHT -} - -void V_GetMapFreePosition( float * cl_angles, float * origin, float * angles ) -{ - vec3_t forward; - vec3_t zScaledTarget; - - VectorCopy(cl_angles, angles); - - // modify angles since we don't wanna see map's bottom - angles[0] = 51.25f + 38.75f*(angles[0]/90.0f); - - zScaledTarget[0] = gHUD.m_Spectator.m_mapOrigin[0]; - zScaledTarget[1] = gHUD.m_Spectator.m_mapOrigin[1]; - zScaledTarget[2] = gHUD.m_Spectator.m_mapOrigin[2] * (( 90.0f - angles[0] ) / 90.0f ); - - - AngleVectors(angles, forward, NULL, NULL); - - VectorNormalize(forward); - - VectorMA(zScaledTarget, -( 4096.0f / gHUD.m_Spectator.m_mapZoom ), forward , origin); -} - -void V_GetMapChasePosition(int target, float * cl_angles, float * origin, float * angles) -{ - vec3_t forward; - - if ( target ) - { - cl_entity_t * ent = gEngfuncs.GetEntityByIndex( target ); - - if ( gHUD.m_Spectator.m_autoDirector->value ) - { - // this is done to get the angles made by director mode - V_GetChasePos(target, cl_angles, origin, angles); - VectorCopy(ent->origin, origin); - - // keep fix chase angle horizontal - angles[0] = 45.0f; - } - else - { - VectorCopy(cl_angles, angles); - VectorCopy(ent->origin, origin); - - // modify angles since we don't wanna see map's bottom - angles[0] = 51.25f + 38.75f*(angles[0]/90.0f); - } - } - else - { - // keep out roaming position, but modify angles - VectorCopy(cl_angles, angles); - angles[0] = 51.25f + 38.75f*(angles[0]/90.0f); - } - - origin[2] *= (( 90.0f - angles[0] ) / 90.0f ); - angles[2] = 0.0f; // don't roll angle (if chased player is dead) - - AngleVectors(angles, forward, NULL, NULL); - - VectorNormalize(forward); - - VectorMA(origin, -1536, forward, origin); -} - -int V_FindViewModelByWeaponModel(int weaponindex) -{ - - static char * modelmap[][2] = { - -#ifdef THREEWAVE - // { "models/p_grapple.mdl", "models/v_grapple.mdl" }, -#endif - - { "models/p_crowbar.mdl", "models/v_crowbar.mdl" }, - { "models/p_shot.mdl", "models/v_shot.mdl" }, - { "models/p_shot2.mdl", "models/v_shot2.mdl" }, - { "models/p_nail.mdl", "models/v_nail.mdl" }, - { "models/p_nail2.mdl", "models/v_nail2.mdl" }, - { "models/p_rock.mdl", "models/v_rock.mdl" }, - { "models/p_rock2.mdl", "models/v_rock2.mdl" }, - { "models/p_light.mdl", "models/v_light.mdl" }, - { NULL, NULL } }; - - struct model_s * weaponModel = IEngineStudio.GetModelByIndex( weaponindex ); - - if ( weaponModel ) - { - int len = strlen( weaponModel->name ); - int i = 0; - - while ( *modelmap[i] != NULL ) - { - if ( !strnicmp( weaponModel->name, modelmap[i][0], len ) ) - { - return gEngfuncs.pEventAPI->EV_FindModelIndex( modelmap[i][1] ); - } - i++; - } - - return 0; - } - else - return 0; - -} - - -/* -================== -V_CalcSpectatorRefdef - -================== -*/ -void V_CalcSpectatorRefdef ( struct ref_params_s * pparams ) -{ - - vec3_t angles; - static viewinterp_t ViewInterp; - static float bob = 0.0f; - static vec3_t velocity ( 0.0f, 0.0f, 0.0f); - - static int lastWeaponModelIndex = 0; - static int lastViewModelIndex = 0; - - cl_entity_t * ent = gEngfuncs.GetEntityByIndex( g_iUser2 ); - cl_entity_t * gunModel = gEngfuncs.GetViewModel(); - static float lasttime; - - static float lastang[3]; - static float lastorg[3]; - - vec3_t delta; - pparams->onlyClientDraw = false; - - // refresh position - VectorCopy ( pparams->simorg, v_sim_org ); - - // get old values - VectorCopy ( pparams->cl_viewangles, v_cl_angles ); - VectorCopy ( pparams->viewangles, v_angles ); - VectorCopy ( pparams->vieworg, v_origin ); - v_frametime = pparams->frametime; - - if ( pparams->nextView == 0 ) - { - // first renderer cycle, full screen - - switch ( g_iUser1 ) - { - case OBS_CHASE_LOCKED: V_GetChasePos( g_iUser2, NULL, v_origin, v_angles ); - break; - - case OBS_CHASE_FREE: V_GetChasePos( g_iUser2, v_cl_angles, v_origin, v_angles ); - break; - - case OBS_ROAMING : VectorCopy (v_cl_angles, v_angles); - VectorCopy (v_sim_org, v_origin); - break; - - case OBS_IN_EYE : V_GetInEyePos( g_iUser2, v_origin, v_angles ); - break; - - case OBS_MAP_FREE : pparams->onlyClientDraw = true; - V_GetMapFreePosition( v_cl_angles, v_origin, v_angles ); - break; - - case OBS_MAP_CHASE : pparams->onlyClientDraw = true; - V_GetMapChasePosition( g_iUser2, v_cl_angles, v_origin, v_angles ); - break; - } - - if ( gHUD.m_Spectator.m_pip->value ) - pparams->nextView = 1; // force a second renderer view - - gHUD.m_Spectator.m_iDrawCycle = 0; - - } - else - { - // second renderer cycle, inset window - - // set inset parameters - pparams->viewport[0] = XRES(gHUD.m_Spectator.m_OverviewData.insetWindowX); // change viewport to inset window - pparams->viewport[1] = YRES(gHUD.m_Spectator.m_OverviewData.insetWindowY); - pparams->viewport[2] = XRES(gHUD.m_Spectator.m_OverviewData.insetWindowWidth); - pparams->viewport[3] = YRES(gHUD.m_Spectator.m_OverviewData.insetWindowHeight); - pparams->nextView = 0; // on further view - pparams->onlyClientDraw = false; - - // override some settings in certain modes - switch ( (int)gHUD.m_Spectator.m_pip->value ) - { - case INSET_CHASE_FREE : V_GetChasePos( g_iUser2, v_cl_angles, v_origin, v_angles ); - break; - - case INSET_IN_EYE : V_GetInEyePos( g_iUser2, v_origin, v_angles ); - break; - - case INSET_MAP_FREE : pparams->onlyClientDraw = true; - V_GetMapFreePosition( v_cl_angles, v_origin, v_angles ); - break; - - case INSET_MAP_CHASE : pparams->onlyClientDraw = true; - - if ( g_iUser1 == OBS_ROAMING ) - V_GetMapChasePosition( 0, v_cl_angles, v_origin, v_angles ); - else - V_GetMapChasePosition( g_iUser2, v_cl_angles, v_origin, v_angles ); - - break; - } - - gHUD.m_Spectator.m_iDrawCycle = 1; - } - - - // do the smoothing only once per frame, not in roaming or map mode - if ( (gHUD.m_Spectator.m_iDrawCycle == 0) && (g_iUser1 == OBS_IN_EYE) ) - { - // smooth angles - - VectorSubtract( v_angles, lastang, delta ); - if ( Length( delta ) != 0.0f ) - { - VectorCopy( v_angles, ViewInterp.Angles[ ViewInterp.CurrentAngle & ORIGIN_MASK ] ); - ViewInterp.AngleTime[ ViewInterp.CurrentAngle & ORIGIN_MASK ] = pparams->time; - ViewInterp.CurrentAngle++; - VectorCopy( v_angles, lastang ); - } - - if ( cl_vsmoothing && cl_vsmoothing->value ) - { - int foundidx; - int i; - float t; - - t = pparams->time - cl_vsmoothing->value; - - for ( i = 1; i < ORIGIN_MASK; i++ ) - { - foundidx = ViewInterp.CurrentAngle - 1 - i; - if ( ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ] <= t ) - break; - } - - if ( i < ORIGIN_MASK && ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ] != 0.0 ) - { - // Interpolate - double dt; - float da; - vec3_t v1,v2; - - AngleVectors( ViewInterp.Angles[ foundidx & ORIGIN_MASK ], v1, NULL, NULL ); - AngleVectors( ViewInterp.Angles[ (foundidx + 1) & ORIGIN_MASK ], v2, NULL, NULL ); - da = AngleBetweenVectors( v1, v2 ); - - dt = ViewInterp.AngleTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ]; - - if ( dt > 0.0 && ( da < 22.5f) ) - { - double frac; - - frac = ( t - ViewInterp.AngleTime[ foundidx & ORIGIN_MASK] ) / dt; - frac = V_min( 1.0, frac ); - - // interpolate angles - InterpolateAngles( ViewInterp.Angles[ foundidx & ORIGIN_MASK ], ViewInterp.Angles[ (foundidx + 1) & ORIGIN_MASK ], v_angles, frac ); - } - } - } - - // smooth origin - - VectorSubtract( v_origin, lastorg, delta ); - - if ( Length( delta ) != 0.0 ) - { - VectorCopy( v_origin, ViewInterp.Origins[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] ); - ViewInterp.OriginTime[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] = pparams->time; - ViewInterp.CurrentOrigin++; - - VectorCopy( v_origin, lastorg ); - } - - // don't smooth in roaming (already smoothd), - if ( cl_vsmoothing && cl_vsmoothing->value ) - { - int foundidx; - int i; - float t; - - t = pparams->time - cl_vsmoothing->value; - - for ( i = 1; i < ORIGIN_MASK; i++ ) - { - foundidx = ViewInterp.CurrentOrigin - 1 - i; - if ( ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] <= t ) - break; - } - - if ( i < ORIGIN_MASK && ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] != 0.0 ) - { - // Interpolate - vec3_t delta; - double frac; - double dt; - vec3_t neworg; - - dt = ViewInterp.OriginTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ]; - if ( dt > 0.0 ) - { - frac = ( t - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK] ) / dt; - frac = V_min( 1.0, frac ); - VectorSubtract( ViewInterp.Origins[ ( foundidx + 1 ) & ORIGIN_MASK ], ViewInterp.Origins[ foundidx & ORIGIN_MASK ], delta ); - VectorMA( ViewInterp.Origins[ foundidx & ORIGIN_MASK ], frac, delta, neworg ); - - // Dont interpolate large changes - if ( Length( delta ) < 64 ) - { - VectorCopy( neworg, v_origin ); - } - } - } - } - } - - // Hack in weapon model: - - - if ( (g_iUser1 == OBS_IN_EYE || gHUD.m_Spectator.m_pip->value == INSET_IN_EYE) - && ent && g_iUser2 ) - { - // get position for weapon model - VectorCopy( v_origin, gunModel->origin); - VectorCopy( v_angles, gunModel->angles); - - // add idle tremble - gunModel->angles[PITCH]*=-1; - - // calculate player velocity - float timeDiff = ent->curstate.msg_time - ent->prevstate.msg_time; - - if ( timeDiff > 0 ) - { - vec3_t distance; - VectorSubtract(ent->prevstate.origin, ent->curstate.origin, distance); - VectorScale(distance, 1/timeDiff, distance ); - - velocity[0] = velocity[0]*0.66f + distance[0]*0.33f; - velocity[1] = velocity[1]*0.66f + distance[1]*0.33f; - velocity[2] = velocity[2]*0.66f + distance[2]*0.33f; - - VectorCopy(velocity, pparams->simvel); - pparams->onground = 1; - - bob = V_CalcBob( pparams ); - } - - vec3_t forward; - AngleVectors(v_angles, forward, NULL, NULL ); - - for ( int i = 0; i < 3; i++ ) - { - gunModel->origin[ i ] += bob * 0.4 * forward[ i ]; - } - - // throw in a little tilt. - gunModel->angles[YAW] -= bob * 0.5; - gunModel->angles[ROLL] -= bob * 1; - gunModel->angles[PITCH] -= bob * 0.3; - - VectorCopy( gunModel->angles, gunModel->curstate.angles ); - VectorCopy( gunModel->angles, gunModel->latched.prevangles ); - - if ( lastWeaponModelIndex != ent->curstate.weaponmodel ) - { - // weapon model changed - - lastWeaponModelIndex = ent->curstate.weaponmodel; - lastViewModelIndex = V_FindViewModelByWeaponModel( lastWeaponModelIndex ); - if ( lastViewModelIndex ) - { - gEngfuncs.pfnWeaponAnim(0,0); // reset weapon animation - } - else - { - // model not found - gunModel->model = NULL; // disable weaopn model - lastWeaponModelIndex = lastViewModelIndex = 0; - } - } - - if ( lastViewModelIndex ) - { - gunModel->model = IEngineStudio.GetModelByIndex( lastViewModelIndex ); - gunModel->curstate.modelindex = lastViewModelIndex; - gunModel->curstate.frame = 0; - gunModel->curstate.colormap = 0; - gunModel->index = g_iUser2; - } - else - { - gunModel->model = NULL; // disable weaopn model - } - } - else - { - gunModel->model = NULL; // disable weaopn model - lastWeaponModelIndex = lastViewModelIndex = 0; - } - - lasttime = pparams->time; - - // write back new values into pparams - - VectorCopy ( v_angles, pparams->viewangles ) - VectorCopy ( v_origin, pparams->vieworg ); - -} - -void DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams ) -{ - // intermission / finale rendering - if ( pparams->intermission ) - { - V_CalcIntermissionRefdef ( pparams ); - } - else if ( pparams->spectator || g_iUser1 ) // g_iUser true if in spectator mode - { - V_CalcSpectatorRefdef ( pparams ); - } - else if ( !pparams->paused ) - { - V_CalcNormalRefdef ( pparams ); - } -} - -/* -============= -V_DropPunchAngle - -============= -*/ -void V_DropPunchAngle ( float frametime, float *ev_punchangle ) -{ - float len; - - len = VectorNormalize ( ev_punchangle ); - len -= (10.0 + len * 0.5) * frametime; - len = V_max( len, 0.0 ); - VectorScale ( ev_punchangle, len, ev_punchangle ); -} - -/* -============= -V_PunchAxis - -Client side punch effect -============= -*/ -void V_PunchAxis( int axis, float punch ) -{ - ev_punchangle[ axis ] = punch; -} - -/* -============= -V_Init -============= -*/ -void V_Init (void) -{ - gEngfuncs.pfnAddCommand ("centerview", V_StartPitchDrift ); - - scr_ofsx = gEngfuncs.pfnRegisterVariable( "scr_ofsx","0", 0 ); - scr_ofsy = gEngfuncs.pfnRegisterVariable( "scr_ofsy","0", 0 ); - scr_ofsz = gEngfuncs.pfnRegisterVariable( "scr_ofsz","0", 0 ); - - v_centermove = gEngfuncs.pfnRegisterVariable( "v_centermove", "0.15", 0 ); - v_centerspeed = gEngfuncs.pfnRegisterVariable( "v_centerspeed","500", 0 ); - - cl_bobcycle = gEngfuncs.pfnRegisterVariable( "cl_bobcycle","0.8", 0 );// best default for my experimental gun wag (sjb) - cl_bob = gEngfuncs.pfnRegisterVariable( "cl_bob","0.01", 0 );// best default for my experimental gun wag (sjb) - cl_bobup = gEngfuncs.pfnRegisterVariable( "cl_bobup","0.5", 0 ); - cl_waterdist = gEngfuncs.pfnRegisterVariable( "cl_waterdist","4", 0 ); - cl_chasedist = gEngfuncs.pfnRegisterVariable( "cl_chasedist","112", 0 ); -} - - -//#define TRACE_TEST -#if defined( TRACE_TEST ) - -extern float in_fov; -/* -==================== -CalcFov -==================== -*/ -float CalcFov (float fov_x, float width, float height) -{ - float a; - float x; - - if (fov_x < 1 || fov_x > 179) - fov_x = 90; // error, set to 90 - - x = width/tan(fov_x/360*M_PI); - - a = atan (height/x); - - a = a*360/M_PI; - - return a; -} - -int hitent = -1; - -void V_Move( int mx, int my ) -{ - float fov; - float fx, fy; - float dx, dy; - float c_x, c_y; - float dX, dY; - vec3_t forward, up, right; - vec3_t newangles; - - vec3_t farpoint; - pmtrace_t tr; - - fov = CalcFov( in_fov, (float)ScreenWidth, (float)ScreenHeight ); - - c_x = (float)ScreenWidth / 2.0; - c_y = (float)ScreenHeight / 2.0; - - dx = (float)mx - c_x; - dy = (float)my - c_y; - - // Proportion we moved in each direction - fx = dx / c_x; - fy = dy / c_y; - - dX = fx * in_fov / 2.0 ; - dY = fy * fov / 2.0; - - newangles = v_angles; - - newangles[ YAW ] -= dX; - newangles[ PITCH ] += dY; - - // Now rotate v_forward around that point - AngleVectors ( newangles, forward, right, up ); - - farpoint = v_origin + 8192 * forward; - - // Trace - tr = *(gEngfuncs.PM_TraceLine( (float *)&v_origin, (float *)&farpoint, PM_TRACELINE_PHYSENTSONLY, 2 /*point sized hull*/, -1 )); - - if ( tr.fraction != 1.0 && tr.ent != 0 ) - { - hitent = PM_GetInfo( tr.ent ); - PM_ParticleLine( (float *)&v_origin, (float *)&tr.endpos, 5, 1.0, 0.0 ); - } - else - { - hitent = -1; - } -} - -#endif diff --git a/dmc/cl_dll/view.h b/dmc/cl_dll/view.h deleted file mode 100644 index 1afbe38..0000000 --- a/dmc/cl_dll/view.h +++ /dev/null @@ -1,15 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined ( VIEWH ) -#define VIEWH -#pragma once - -void V_StartPitchDrift( void ); -void V_StopPitchDrift( void ); - -#endif // !VIEWH \ No newline at end of file diff --git a/dmc/cl_dll/voice_status.cpp b/dmc/cl_dll/voice_status.cpp deleted file mode 100644 index 0b09684..0000000 --- a/dmc/cl_dll/voice_status.cpp +++ /dev/null @@ -1,885 +0,0 @@ -//========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// There are hud.h's coming out of the woodwork so this ensures that we get the right one. -#if defined(THREEWAVE) || defined(DMC_BUILD) - #include "../dmc/cl_dll/hud.h" -#elif defined(CSTRIKE) - #include "../cstrike/cl_dll/hud.h" -#elif defined(DOD) - #include "../dod/cl_dll/hud.h" -#else - #include "hud.h" -#endif - -#include "cl_util.h" -#include -#include -#include -#include "parsemsg.h" -#include "hud_servers.h" -#include "demo.h" -#include "demo_api.h" -#include "voice_status.h" -#include "r_efx.h" -#include "entity_types.h" -#include "VGUI_ActionSignal.h" -#include "VGUI_Scheme.h" -#include "VGUI_TextImage.h" -#include "vgui_loadtga.h" -#include "vgui_helpers.h" -#include "VGUI_MouseCode.h" - - - -using namespace vgui; - - -extern int cam_thirdperson; - - -#define VOICE_MODEL_INTERVAL 0.3 -#define SCOREBOARD_BLINK_FREQUENCY 0.3 // How often to blink the scoreboard icons. -#define SQUELCHOSCILLATE_PER_SECOND 2.0f - - -extern BitmapTGA *LoadTGA( const char* pImageName ); - - - -// ---------------------------------------------------------------------- // -// The voice manager for the client. -// ---------------------------------------------------------------------- // -CVoiceStatus g_VoiceStatus; - -CVoiceStatus* GetClientVoiceMgr() -{ - return &g_VoiceStatus; -} - - - -// ---------------------------------------------------------------------- // -// CVoiceStatus. -// ---------------------------------------------------------------------- // - -static CVoiceStatus *g_pInternalVoiceStatus = NULL; - -int __MsgFunc_VoiceMask(const char *pszName, int iSize, void *pbuf) -{ - if(g_pInternalVoiceStatus) - g_pInternalVoiceStatus->HandleVoiceMaskMsg(iSize, pbuf); - - return 1; -} - -int __MsgFunc_ReqState(const char *pszName, int iSize, void *pbuf) -{ - if(g_pInternalVoiceStatus) - g_pInternalVoiceStatus->HandleReqStateMsg(iSize, pbuf); - - return 1; -} - - -int g_BannedPlayerPrintCount; -void ForEachBannedPlayer(char id[16]) -{ - char str[256]; - sprintf(str, "Ban %d: %2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x\n", - g_BannedPlayerPrintCount++, - id[0], id[1], id[2], id[3], - id[4], id[5], id[6], id[7], - id[8], id[9], id[10], id[11], - id[12], id[13], id[14], id[15] - ); -#ifdef _WIN32 - strupr(str); -#endif - gEngfuncs.pfnConsolePrint(str); -} - - -void ShowBannedCallback() -{ - if(g_pInternalVoiceStatus) - { - g_BannedPlayerPrintCount = 0; - gEngfuncs.pfnConsolePrint("------- BANNED PLAYERS -------\n"); - g_pInternalVoiceStatus->m_BanMgr.ForEachBannedPlayer(ForEachBannedPlayer); - gEngfuncs.pfnConsolePrint("------------------------------\n"); - } -} - - -// ---------------------------------------------------------------------- // -// CVoiceStatus. -// ---------------------------------------------------------------------- // - -CVoiceStatus::CVoiceStatus() -{ - m_bBanMgrInitialized = false; - m_LastUpdateServerState = 0; - - m_pSpeakerLabelIcon = NULL; - m_pScoreboardNeverSpoken = NULL; - m_pScoreboardNotSpeaking = NULL; - m_pScoreboardSpeaking = NULL; - m_pScoreboardSpeaking2 = NULL; - m_pScoreboardSquelch = NULL; - m_pScoreboardBanned = NULL; - - m_pLocalBitmap = NULL; - m_pAckBitmap = NULL; - - m_bTalking = m_bServerAcked = false; - - memset(m_pBanButtons, 0, sizeof(m_pBanButtons)); - - m_pParentPanel = NULL; - - m_bServerModEnable = -1; - - m_pchGameDir = NULL; -} - - -CVoiceStatus::~CVoiceStatus() -{ - g_pInternalVoiceStatus = NULL; - - for(int i=0; i < MAX_VOICE_SPEAKERS; i++) - { - delete m_Labels[i].m_pLabel; - m_Labels[i].m_pLabel = NULL; - - delete m_Labels[i].m_pIcon; - m_Labels[i].m_pIcon = NULL; - - delete m_Labels[i].m_pBackground; - m_Labels[i].m_pBackground = NULL; - } - - delete m_pLocalLabel; - m_pLocalLabel = NULL; - - FreeBitmaps(); - - if(m_pchGameDir) - { - if(m_bBanMgrInitialized) - { - m_BanMgr.SaveState(m_pchGameDir); - } - - free(m_pchGameDir); - } -} - - -int CVoiceStatus::Init( - IVoiceStatusHelper *pHelper, - Panel **pParentPanel) -{ - // Setup the voice_modenable cvar. - gEngfuncs.pfnRegisterVariable("voice_modenable", "1", FCVAR_ARCHIVE); - - gEngfuncs.pfnRegisterVariable("voice_clientdebug", "0", 0); - - gEngfuncs.pfnAddCommand("voice_showbanned", ShowBannedCallback); - - if(gEngfuncs.pfnGetGameDirectory()) - { - m_BanMgr.Init(gEngfuncs.pfnGetGameDirectory()); - m_bBanMgrInitialized = true; - } - - assert(!g_pInternalVoiceStatus); - g_pInternalVoiceStatus = this; - - m_BlinkTimer = 0; - m_VoiceHeadModel = NULL; - memset(m_Labels, 0, sizeof(m_Labels)); - - for(int i=0; i < MAX_VOICE_SPEAKERS; i++) - { - CVoiceLabel *pLabel = &m_Labels[i]; - - pLabel->m_pBackground = new Label(""); - - if(pLabel->m_pLabel = new Label("")) - { - pLabel->m_pLabel->setVisible( true ); - pLabel->m_pLabel->setFont( Scheme::sf_primary2 ); - pLabel->m_pLabel->setTextAlignment( Label::a_east ); - pLabel->m_pLabel->setContentAlignment( Label::a_east ); - pLabel->m_pLabel->setParent( pLabel->m_pBackground ); - } - - if( pLabel->m_pIcon = new ImagePanel( NULL ) ) - { - pLabel->m_pIcon->setVisible( true ); - pLabel->m_pIcon->setParent( pLabel->m_pBackground ); - } - - pLabel->m_clientindex = -1; - } - - m_pLocalLabel = new ImagePanel(NULL); - - m_bInSquelchMode = false; - - m_pHelper = pHelper; - m_pParentPanel = pParentPanel; - gHUD.AddHudElem(this); - m_iFlags = HUD_ACTIVE; - HOOK_MESSAGE(VoiceMask); - HOOK_MESSAGE(ReqState); - - // Cache the game directory for use when we shut down - const char *pchGameDirT = gEngfuncs.pfnGetGameDirectory(); - m_pchGameDir = (char *)malloc(strlen(pchGameDirT) + 1); - strcpy(m_pchGameDir, pchGameDirT); - - return 1; -} - - -int CVoiceStatus::VidInit() -{ - FreeBitmaps(); - - - if( m_pLocalBitmap = vgui_LoadTGA("gfx/vgui/icntlk_pl.tga") ) - { - m_pLocalBitmap->setColor(Color(255,255,255,135)); - } - - if( m_pAckBitmap = vgui_LoadTGA("gfx/vgui/icntlk_sv.tga") ) - { - m_pAckBitmap->setColor(Color(255,255,255,135)); // Give just a tiny bit of translucency so software draws correctly. - } - - m_pLocalLabel->setImage( m_pLocalBitmap ); - m_pLocalLabel->setVisible( false ); - - - if( m_pSpeakerLabelIcon = vgui_LoadTGANoInvertAlpha("gfx/vgui/speaker4.tga" ) ) - m_pSpeakerLabelIcon->setColor( Color(255,255,255,1) ); // Give just a tiny bit of translucency so software draws correctly. - - if (m_pScoreboardNeverSpoken = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker1.tga")) - m_pScoreboardNeverSpoken->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardNotSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker2.tga")) - m_pScoreboardNotSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker3.tga")) - m_pScoreboardSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardSpeaking2 = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker4.tga")) - m_pScoreboardSpeaking2->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardSquelch = vgui_LoadTGA("gfx/vgui/icntlk_squelch.tga")) - m_pScoreboardSquelch->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardBanned = vgui_LoadTGA("gfx/vgui/640_voiceblocked.tga")) - m_pScoreboardBanned->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - // Figure out the voice head model height. - m_VoiceHeadModelHeight = 45; - char *pFile = (char *)gEngfuncs.COM_LoadFile("scripts/voicemodel.txt", 5, NULL); - if(pFile) - { - char token[4096]; - gEngfuncs.COM_ParseFile(pFile, token); - if(token[0] >= '0' && token[0] <= '9') - { - m_VoiceHeadModelHeight = (float)atof(token); - } - - gEngfuncs.COM_FreeFile(pFile); - } - - m_VoiceHeadModel = gEngfuncs.pfnSPR_Load("sprites/voiceicon.spr"); - return TRUE; -} - - -void CVoiceStatus::Frame(double frametime) -{ - // check server banned players once per second - if(gEngfuncs.GetClientTime() - m_LastUpdateServerState > 1) - { - UpdateServerState(false); - } - - m_BlinkTimer += frametime; - - // Update speaker labels. - if( m_pHelper->CanShowSpeakerLabels() ) - { - for( int i=0; i < MAX_VOICE_SPEAKERS; i++ ) - m_Labels[i].m_pBackground->setVisible( m_Labels[i].m_clientindex != -1 ); - } - else - { - for( int i=0; i < MAX_VOICE_SPEAKERS; i++ ) - m_Labels[i].m_pBackground->setVisible( false ); - } - - for(int i=0; i < VOICE_MAX_PLAYERS; i++) - UpdateBanButton(i); -} - - -void CVoiceStatus::CreateEntities() -{ - if(!m_VoiceHeadModel) - return; - - cl_entity_t *localPlayer = gEngfuncs.GetLocalPlayer(); - - int iOutModel = 0; - for(int i=0; i < VOICE_MAX_PLAYERS; i++) - { - if(!m_VoicePlayers[i]) - continue; - - cl_entity_s *pClient = gEngfuncs.GetEntityByIndex(i+1); - - // Don't show an icon if the player is not in our PVS. - if(!pClient || pClient->curstate.messagenum < localPlayer->curstate.messagenum) - continue; - - // Don't show an icon for dead or spectating players (ie: invisible entities). - if(pClient->curstate.effects & EF_NODRAW) - continue; - - // Don't show an icon for the local player unless we're in thirdperson mode. - if(pClient == localPlayer && !cam_thirdperson) - continue; - - cl_entity_s *pEnt = &m_VoiceHeadModels[iOutModel]; - ++iOutModel; - - memset(pEnt, 0, sizeof(*pEnt)); - - pEnt->curstate.rendermode = kRenderTransAdd; - pEnt->curstate.renderamt = 255; - pEnt->baseline.renderamt = 255; - pEnt->curstate.renderfx = kRenderFxNoDissipation; - pEnt->curstate.framerate = 1; - pEnt->curstate.frame = 0; - pEnt->model = (struct model_s*)gEngfuncs.GetSpritePointer(m_VoiceHeadModel); - pEnt->angles[0] = pEnt->angles[1] = pEnt->angles[2] = 0; - pEnt->curstate.scale = 0.5f; - - pEnt->origin[0] = pEnt->origin[1] = 0; - pEnt->origin[2] = 45; - - VectorAdd(pEnt->origin, pClient->origin, pEnt->origin); - - // Tell the engine. - gEngfuncs.CL_CreateVisibleEntity(ET_NORMAL, pEnt); - } -} - - -void CVoiceStatus::UpdateSpeakerStatus( int entindex, qboolean bTalking ) -{ - cvar_t *pVoiceLoopback = NULL; - - if ( !m_pParentPanel || !*m_pParentPanel ) - { - return; - } - - if ( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) ) - { - char msg[256]; - _snprintf( msg, sizeof( msg ), "CVoiceStatus::UpdateSpeakerStatus: ent %d talking = %d\n", entindex, bTalking ); - gEngfuncs.pfnConsolePrint( msg ); - } - - int iLocalPlayerIndex = gEngfuncs.GetLocalPlayer()->index; - - // Is it the local player talking? - if ( entindex == -1 ) - { - m_bTalking = !!bTalking; - if( bTalking ) - { - // Enable voice for them automatically if they try to talk. - gEngfuncs.pfnClientCmd( "voice_modenable 1" ); - } - - // now set the player index to the correct index for the local player - // this will allow us to have the local player's icon flash in the scoreboard - entindex = iLocalPlayerIndex; - - pVoiceLoopback = gEngfuncs.pfnGetCvarPointer( "voice_loopback" ); - } - else if ( entindex == -2 ) - { - m_bServerAcked = !!bTalking; - } - - if ( entindex >= 0 && entindex <= VOICE_MAX_PLAYERS ) - { - int iClient = entindex - 1; - if ( iClient < 0 ) - { - return; - } - - CVoiceLabel *pLabel = FindVoiceLabel( iClient ); - if ( bTalking ) - { - m_VoicePlayers[iClient] = true; - m_VoiceEnabledPlayers[iClient] = true; - - // If we don't have a label for this guy yet, then create one. - if ( !pLabel ) - { - // if this isn't the local player (unless they have voice_loopback on) - if ( ( entindex != iLocalPlayerIndex ) || ( pVoiceLoopback && pVoiceLoopback->value ) ) - { - if ( pLabel = GetFreeVoiceLabel() ) - { - // Get the name from the engine. - hud_player_info_t info; - memset( &info, 0, sizeof( info ) ); - GetPlayerInfo( entindex, &info ); - - char paddedName[512]; - _snprintf( paddedName, sizeof( paddedName ), "%s ", info.name ); - - int color[3]; - m_pHelper->GetPlayerTextColor( entindex, color ); - - if ( pLabel->m_pBackground ) - { - pLabel->m_pBackground->setBgColor( color[0], color[1], color[2], 135 ); - pLabel->m_pBackground->setParent( *m_pParentPanel ); - pLabel->m_pBackground->setVisible( m_pHelper->CanShowSpeakerLabels() ); - } - - if ( pLabel->m_pLabel ) - { - pLabel->m_pLabel->setFgColor( 255, 255, 255, 0 ); - pLabel->m_pLabel->setBgColor( 0, 0, 0, 255 ); - pLabel->m_pLabel->setText( paddedName ); - } - - pLabel->m_clientindex = iClient; - } - } - } - } - else - { - m_VoicePlayers[iClient] = false; - - // If we have a label for this guy, kill it. - if ( pLabel ) - { - pLabel->m_pBackground->setVisible( false ); - pLabel->m_clientindex = -1; - } - } - } - - RepositionLabels(); -} - - -void CVoiceStatus::UpdateServerState(bool bForce) -{ - // Can't do anything when we're not in a level. - char const *pLevelName = gEngfuncs.pfnGetLevelName(); - if( pLevelName[0] == 0 ) - { - if( gEngfuncs.pfnGetCvarFloat("voice_clientdebug") ) - { - gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: pLevelName[0]==0\n" ); - } - - return; - } - - int bCVarModEnable = !!gEngfuncs.pfnGetCvarFloat("voice_modenable"); - if(bForce || m_bServerModEnable != bCVarModEnable) - { - m_bServerModEnable = bCVarModEnable; - - char str[256]; - _snprintf(str, sizeof(str), "VModEnable %d", m_bServerModEnable); - ServerCmd(str); - - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - char msg[256]; - sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str); - gEngfuncs.pfnConsolePrint(msg); - } - } - - char str[2048]; - sprintf(str, "vban"); - bool bChange = false; - - for(unsigned long dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++) - { - unsigned long serverBanMask = 0; - unsigned long banMask = 0; - for(unsigned long i=0; i < 32; i++) - { - char playerID[16]; - if(!gEngfuncs.GetPlayerUniqueID(i+1, playerID)) - continue; - - if(m_BanMgr.GetPlayerBan(playerID)) - banMask |= 1 << i; - - if(m_ServerBannedPlayers[dw*32 + i]) - serverBanMask |= 1 << i; - } - - if(serverBanMask != banMask) - bChange = true; - - // Ok, the server needs to be updated. - char numStr[512]; - sprintf(numStr, " %x", banMask); - strcat(str, numStr); - } - - if(bChange || bForce) - { - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - char msg[256]; - sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str); - gEngfuncs.pfnConsolePrint(msg); - } - - gEngfuncs.pfnServerCmdUnreliable(str); // Tell the server.. - } - else - { - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: no change\n" ); - } - } - - m_LastUpdateServerState = gEngfuncs.GetClientTime(); -} - -void CVoiceStatus::UpdateSpeakerImage(Label *pLabel, int iPlayer) -{ - m_pBanButtons[iPlayer-1] = pLabel; - UpdateBanButton(iPlayer-1); -} - -void CVoiceStatus::UpdateBanButton(int iClient) -{ - Label *pPanel = m_pBanButtons[iClient]; - - if (!pPanel) - return; - - char playerID[16]; - extern bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] ); - if(!HACK_GetPlayerUniqueID(iClient+1, playerID)) - return; - - // Figure out if it's blinking or not. - bool bBlink = fmod(m_BlinkTimer, SCOREBOARD_BLINK_FREQUENCY*2) < SCOREBOARD_BLINK_FREQUENCY; - bool bTalking = !!m_VoicePlayers[iClient]; - bool bBanned = m_BanMgr.GetPlayerBan(playerID); - bool bNeverSpoken = !m_VoiceEnabledPlayers[iClient]; - - // Get the appropriate image to display on the panel. - if (bBanned) - { - pPanel->setImage(m_pScoreboardBanned); - } - else if (bTalking) - { - if (bBlink) - { - pPanel->setImage(m_pScoreboardSpeaking2); - } - else - { - pPanel->setImage(m_pScoreboardSpeaking); - } - pPanel->setFgColor(255, 170, 0, 1); - } - else if (bNeverSpoken) - { - pPanel->setImage(m_pScoreboardNeverSpoken); - pPanel->setFgColor(100, 100, 100, 1); - } - else - { - pPanel->setImage(m_pScoreboardNotSpeaking); - } -} - - -void CVoiceStatus::HandleVoiceMaskMsg(int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - unsigned long dw; - for(dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++) - { - m_AudiblePlayers.SetDWord(dw, (unsigned long)READ_LONG()); - m_ServerBannedPlayers.SetDWord(dw, (unsigned long)READ_LONG()); - - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - char str[256]; - gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleVoiceMaskMsg\n"); - - sprintf(str, " - m_AudiblePlayers[%d] = %lu\n", dw, m_AudiblePlayers.GetDWord(dw)); - gEngfuncs.pfnConsolePrint(str); - - sprintf(str, " - m_ServerBannedPlayers[%d] = %lu\n", dw, m_ServerBannedPlayers.GetDWord(dw)); - gEngfuncs.pfnConsolePrint(str); - } - } - - m_bServerModEnable = READ_BYTE(); -} - -void CVoiceStatus::HandleReqStateMsg(int iSize, void *pbuf) -{ - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleReqStateMsg\n"); - } - - UpdateServerState(true); -} - -void CVoiceStatus::StartSquelchMode() -{ - if(m_bInSquelchMode) - return; - - m_bInSquelchMode = true; - m_pHelper->UpdateCursorState(); -} - -void CVoiceStatus::StopSquelchMode() -{ - m_bInSquelchMode = false; - m_pHelper->UpdateCursorState(); -} - -bool CVoiceStatus::IsInSquelchMode() -{ - return m_bInSquelchMode; -} - -CVoiceLabel* CVoiceStatus::FindVoiceLabel(int clientindex) -{ - for(int i=0; i < MAX_VOICE_SPEAKERS; i++) - { - if(m_Labels[i].m_clientindex == clientindex) - return &m_Labels[i]; - } - - return NULL; -} - - -CVoiceLabel* CVoiceStatus::GetFreeVoiceLabel() -{ - return FindVoiceLabel(-1); -} - - -void CVoiceStatus::RepositionLabels() -{ - // find starting position to draw from, along right-hand side of screen - int y = ScreenHeight / 2; - - int iconWide = 8, iconTall = 8; - if( m_pSpeakerLabelIcon ) - { - m_pSpeakerLabelIcon->getSize( iconWide, iconTall ); - } - - // Reposition active labels. - for(int i = 0; i < MAX_VOICE_SPEAKERS; i++) - { - CVoiceLabel *pLabel = &m_Labels[i]; - - if( pLabel->m_clientindex == -1 || !pLabel->m_pLabel ) - { - if( pLabel->m_pBackground ) - pLabel->m_pBackground->setVisible( false ); - - continue; - } - - int textWide, textTall; - pLabel->m_pLabel->getContentSize( textWide, textTall ); - - // Don't let it stretch too far across their screen. - if( textWide > (ScreenWidth*2)/3 ) - textWide = (ScreenWidth*2)/3; - - // Setup the background label to fit everything in. - int border = 2; - int bgWide = textWide + iconWide + border*3; - int bgTall = V_max( textTall, iconTall ) + border*2; - pLabel->m_pBackground->setBounds( ScreenWidth - bgWide - 8, y, bgWide, bgTall ); - - // Put the text at the left. - pLabel->m_pLabel->setBounds( border, (bgTall - textTall) / 2, textWide, textTall ); - - // Put the icon at the right. - int iconLeft = border + textWide + border; - int iconTop = (bgTall - iconTall) / 2; - if( pLabel->m_pIcon ) - { - pLabel->m_pIcon->setImage( m_pSpeakerLabelIcon ); - pLabel->m_pIcon->setBounds( iconLeft, iconTop, iconWide, iconTall ); - } - - y += bgTall + 2; - } - - if( m_pLocalBitmap && m_pAckBitmap && m_pLocalLabel && (m_bTalking || m_bServerAcked) ) - { - m_pLocalLabel->setParent(*m_pParentPanel); - m_pLocalLabel->setVisible( true ); - - if( m_bServerAcked && !!gEngfuncs.pfnGetCvarFloat("voice_clientdebug") ) - m_pLocalLabel->setImage( m_pAckBitmap ); - else - m_pLocalLabel->setImage( m_pLocalBitmap ); - - int sizeX, sizeY; - m_pLocalBitmap->getSize(sizeX, sizeY); - - int local_xPos = ScreenWidth - sizeX - 10; - int local_yPos = m_pHelper->GetAckIconHeight() - sizeY; - - m_pLocalLabel->setPos( local_xPos, local_yPos ); - } - else - { - m_pLocalLabel->setVisible( false ); - } -} - - -void CVoiceStatus::FreeBitmaps() -{ - // Delete all the images we have loaded. - delete m_pLocalBitmap; - m_pLocalBitmap = NULL; - - delete m_pAckBitmap; - m_pAckBitmap = NULL; - - delete m_pSpeakerLabelIcon; - m_pSpeakerLabelIcon = NULL; - - delete m_pScoreboardNeverSpoken; - m_pScoreboardNeverSpoken = NULL; - - delete m_pScoreboardNotSpeaking; - m_pScoreboardNotSpeaking = NULL; - - delete m_pScoreboardSpeaking; - m_pScoreboardSpeaking = NULL; - - delete m_pScoreboardSpeaking2; - m_pScoreboardSpeaking2 = NULL; - - delete m_pScoreboardSquelch; - m_pScoreboardSquelch = NULL; - - delete m_pScoreboardBanned; - m_pScoreboardBanned = NULL; - - // Clear references to the images in panels. - for(int i=0; i < VOICE_MAX_PLAYERS; i++) - { - if (m_pBanButtons[i]) - { - m_pBanButtons[i]->setImage(NULL); - } - } - - if(m_pLocalLabel) - m_pLocalLabel->setImage(NULL); -} - -//----------------------------------------------------------------------------- -// Purpose: returns true if the target client has been banned -// Input : playerID - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool CVoiceStatus::IsPlayerBlocked(int iPlayer) -{ - char playerID[16]; - if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID)) - return false; - - return m_BanMgr.GetPlayerBan(playerID); -} - -//----------------------------------------------------------------------------- -// Purpose: returns true if the player can't hear the other client due to game rules (eg. the other team) -// Input : playerID - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool CVoiceStatus::IsPlayerAudible(int iPlayer) -{ - return !!m_AudiblePlayers[iPlayer-1]; -} - -//----------------------------------------------------------------------------- -// Purpose: blocks/unblocks the target client from being heard -// Input : playerID - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -void CVoiceStatus::SetPlayerBlockedState(int iPlayer, bool blocked) -{ - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 1\n" ); - } - - char playerID[16]; - if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID)) - return; - - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 2\n" ); - } - - // Squelch or (try to) unsquelch this player. - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - char str[256]; - sprintf(str, "CVoiceStatus::SetPlayerBlockedState: setting player %d ban to %d\n", iPlayer, !m_BanMgr.GetPlayerBan(playerID)); - gEngfuncs.pfnConsolePrint(str); - } - - m_BanMgr.SetPlayerBan( playerID, blocked ); - UpdateServerState(false); -} diff --git a/dmc/cl_dll/voice_status.h b/dmc/cl_dll/voice_status.h deleted file mode 100644 index 8edf58c..0000000 --- a/dmc/cl_dll/voice_status.h +++ /dev/null @@ -1,228 +0,0 @@ -//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef VOICE_STATUS_H -#define VOICE_STATUS_H -#pragma once - - -#include "VGUI_Label.h" -#include "VGUI_LineBorder.h" -#include "VGUI_ImagePanel.h" -#include "VGUI_BitmapTGA.h" -#include "VGUI_InputSignal.h" -#include "VGUI_Button.h" -#include "voice_common.h" -#include "cl_entity.h" -#include "voice_banmgr.h" -#include "vgui_checkbutton2.h" -#include "vgui_defaultinputsignal.h" - - -class CVoiceStatus; - - -class CVoiceLabel -{ -public: - vgui::Label *m_pLabel; - vgui::Label *m_pBackground; - vgui::ImagePanel *m_pIcon; // Voice icon next to player name. - int m_clientindex; // Client index of the speaker. -1 if this label isn't being used. -}; - - -// This is provided by each mod to access data that may not be the same across mods. -class IVoiceStatusHelper -{ -public: - virtual ~IVoiceStatusHelper() {} - - // Get RGB color for voice status text about this player. - virtual void GetPlayerTextColor(int entindex, int color[3]) = 0; - - // Force it to update the cursor state. - virtual void UpdateCursorState() = 0; - - // Return the height above the bottom that the voice ack icons should be drawn at. - virtual int GetAckIconHeight() = 0; - - // Return true if the voice manager is allowed to show speaker labels - // (mods usually return false when the scoreboard is up). - virtual bool CanShowSpeakerLabels() = 0; -}; - -//----------------------------------------------------------------------------- -// Purpose: Holds a color for the shared image -//----------------------------------------------------------------------------- -class VoiceImagePanel : public vgui::ImagePanel -{ - virtual void paintBackground() - { - if (_image!=null) - { - vgui::Color col; - getFgColor(col); - _image->setColor(col); - _image->doPaint(this); - } - } -}; - - -class CVoiceStatus : public CHudBase, public vgui::CDefaultInputSignal -{ -public: - CVoiceStatus(); - virtual ~CVoiceStatus(); - -// CHudBase overrides. -public: - - // Initialize the cl_dll's voice manager. - virtual int Init( - IVoiceStatusHelper *m_pHelper, - vgui::Panel **pParentPanel); - - // ackPosition is the bottom position of where CVoiceStatus will draw the voice acknowledgement labels. - virtual int VidInit(); - - -public: - - // Call from HUD_Frame each frame. - void Frame(double frametime); - - // Called when a player starts or stops talking. - // entindex is -1 to represent the local client talking (before the data comes back from the server). - // When the server acknowledges that the local client is talking, then entindex will be gEngfuncs.GetLocalPlayer(). - // entindex is -2 to represent the local client's voice being acked by the server. - void UpdateSpeakerStatus(int entindex, qboolean bTalking); - - // sets the correct image in the label for the player - void UpdateSpeakerImage(vgui::Label *pLabel, int iPlayer); - - // Call from the HUD_CreateEntities function so it can add sprites above player heads. - void CreateEntities(); - - // Called when the server registers a change to who this client can hear. - void HandleVoiceMaskMsg(int iSize, void *pbuf); - - // The server sends this message initially to tell the client to send their state. - void HandleReqStateMsg(int iSize, void *pbuf); - - -// Squelch mode functions. -public: - - // When you enter squelch mode, pass in - void StartSquelchMode(); - void StopSquelchMode(); - bool IsInSquelchMode(); - - // returns true if the target client has been banned - // playerIndex is of range 1..maxplayers - bool IsPlayerBlocked(int iPlayerIndex); - - // returns false if the player can't hear the other client due to game rules (eg. the other team) - bool IsPlayerAudible(int iPlayerIndex); - - // blocks the target client from being heard - void SetPlayerBlockedState(int iPlayerIndex, bool blocked); - -public: - - CVoiceLabel* FindVoiceLabel(int clientindex); // Find a CVoiceLabel representing the specified speaker. - // Returns NULL if none. - // entindex can be -1 if you want a currently-unused voice label. - CVoiceLabel* GetFreeVoiceLabel(); // Get an unused voice label. Returns NULL if none. - - void RepositionLabels(); - - void FreeBitmaps(); - - void UpdateServerState(bool bForce); - - // Update the button artwork to reflect the client's current state. - void UpdateBanButton(int iClient); - - -public: - - enum {MAX_VOICE_SPEAKERS=7}; - - float m_LastUpdateServerState; // Last time we called this function. - int m_bServerModEnable; // What we've sent to the server about our "voice_modenable" cvar. - - vgui::Panel **m_pParentPanel; - CPlayerBitVec m_VoicePlayers; // Who is currently talking. Indexed by client index. - - // This is the gamerules-defined list of players that you can hear. It is based on what teams people are on - // and is totally separate from the ban list. Indexed by client index. - CPlayerBitVec m_AudiblePlayers; - - // Players who have spoken at least once in the game so far - CPlayerBitVec m_VoiceEnabledPlayers; - - // This is who the server THINKS we have banned (it can become incorrect when a new player arrives on the server). - // It is checked periodically, and the server is told to squelch or unsquelch the appropriate players. - CPlayerBitVec m_ServerBannedPlayers; - - cl_entity_s m_VoiceHeadModels[VOICE_MAX_PLAYERS]; // These aren't necessarily in the order of players. They are just - // a place for it to put data in during CreateEntities. - - IVoiceStatusHelper *m_pHelper; // Each mod provides an implementation of this. - - - // Scoreboard icons. - double m_BlinkTimer; // Blink scoreboard icons.. - vgui::BitmapTGA *m_pScoreboardNeverSpoken; - vgui::BitmapTGA *m_pScoreboardNotSpeaking; - vgui::BitmapTGA *m_pScoreboardSpeaking; - vgui::BitmapTGA *m_pScoreboardSpeaking2; - vgui::BitmapTGA *m_pScoreboardSquelch; - vgui::BitmapTGA *m_pScoreboardBanned; - - vgui::Label *m_pBanButtons[VOICE_MAX_PLAYERS]; // scoreboard buttons. - - // Squelch mode stuff. - bool m_bInSquelchMode; - - HSPRITE m_VoiceHeadModel; // Voice head model (goes above players who are speaking). - float m_VoiceHeadModelHeight; // Height above their head to place the model. - - vgui::Image *m_pSpeakerLabelIcon; // Icon next to speaker labels. - - // Lower-right icons telling when the local player is talking.. - vgui::BitmapTGA *m_pLocalBitmap; // Represents the local client talking. - vgui::BitmapTGA *m_pAckBitmap; // Represents the server ack'ing the client talking. - vgui::ImagePanel *m_pLocalLabel; // Represents the local client talking. - - bool m_bTalking; // Set to true when the client thinks it's talking. - bool m_bServerAcked; // Set to true when the server knows the client is talking. - -public: - - CVoiceBanMgr m_BanMgr; // Tracks which users we have squelched and don't want to hear. - -public: - - bool m_bBanMgrInitialized; - - // Labels telling who is speaking. - CVoiceLabel m_Labels[MAX_VOICE_SPEAKERS]; - - // Cache the game directory for use when we shut down - char * m_pchGameDir; -}; - - -// Get the (global) voice manager. -CVoiceStatus* GetClientVoiceMgr(); - - -#endif // VOICE_STATUS_H diff --git a/dmc/cl_dll/wrect.h b/dmc/cl_dll/wrect.h deleted file mode 100644 index a3494ae..0000000 --- a/dmc/cl_dll/wrect.h +++ /dev/null @@ -1,16 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( WRECTH ) -#define WRECTH - -typedef struct rect_s -{ - int left, right, top, bottom; -} wrect_t; - -#endif \ No newline at end of file diff --git a/dmc/dlls/Makefile b/dmc/dlls/Makefile deleted file mode 100644 index e383cda..0000000 --- a/dmc/dlls/Makefile +++ /dev/null @@ -1,126 +0,0 @@ -# -# Half-Life DMC SDK 2.3 dmc_i386.so Makefile for x86 Linux -# -# October 2002 by Leon Hartwig (hartwig@valvesoftware.com) -# - -DLLNAME=dmc - -ARCH=i386 - -#make sure this is the correct compiler for your system -CC=gcc - -DLL_SRCDIR=. -ENGINE_SRCDIR=../../engine -COMMON_SRCDIR=../../common -PM_SHARED_SRCDIR=../pm_shared -GAME_SHARED_SRCDIR=../../game_shared - -DLL_OBJDIR=$(DLL_SRCDIR)/obj -PM_SHARED_OBJDIR=$(DLL_OBJDIR)/pm_shared -GAME_SHARED_OBJDIR=$(DLL_OBJDIR)/game_shared - -BASE_CFLAGS= -Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -D_vsnprintf=vsnprintf\ - -DCLIENT_WEAPONS - -#safe optimization -CFLAGS=$(BASE_CFLAGS) -w -m486 -O1 - -#full optimization -#CFLAGS=$(BASE_CFLAGS) -w -O1 -m486 -ffast-math -funroll-loops \ - -fomit-frame-pointer -fexpensive-optimizations \ - -malign-loops=2 -malign-jumps=2 -malign-functions=2 - -#use these when debugging -#CFLAGS=$(BASE_CFLAGS) -g - -INCLUDEDIRS=-I. -I$(ENGINE_SRCDIR) -I$(COMMON_SRCDIR) -I$(PM_SHARED_SRCDIR) -I$(GAME_SHARED_SRCDIR) - -LDFLAGS= - -SHLIBEXT=so -SHLIBCFLAGS=-fPIC -SHLIBLDFLAGS=-shared - -DO_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) $(INCLUDEDIRS) -o $@ -c $< - -############################################################################# -# SETUP AND BUILD -# GAME -############################################################################# - -$(DLL_OBJDIR)/%.o: $(DLL_SRCDIR)/%.cpp - $(DO_CC) - -$(GAME_SHARED_OBJDIR)/%.o: $(GAME_SHARED_SRCDIR)/%.cpp - $(DO_CC) - -$(PM_SHARED_OBJDIR)/%.o: $(PM_SHARED_SRCDIR)/%.c - $(DO_CC) - -OBJ = \ - $(DLL_OBJDIR)/animating.o \ - $(DLL_OBJDIR)/animation.o \ - $(DLL_OBJDIR)/bmodels.o \ - $(DLL_OBJDIR)/buttons.o \ - $(DLL_OBJDIR)/cbase.o \ - $(DLL_OBJDIR)/client.o \ - $(DLL_OBJDIR)/combat.o \ - $(DLL_OBJDIR)/doors.o \ - $(DLL_OBJDIR)/effects.o \ - $(DLL_OBJDIR)/explode.o \ - $(DLL_OBJDIR)/func_break.o \ - $(DLL_OBJDIR)/game.o \ - $(DLL_OBJDIR)/gamerules.o \ - $(DLL_OBJDIR)/globals.o \ - $(DLL_OBJDIR)/h_ai.o \ - $(DLL_OBJDIR)/h_export.o \ - $(DLL_OBJDIR)/lights.o \ - $(DLL_OBJDIR)/maprules.o \ - $(DLL_OBJDIR)/monsters.o \ - $(DLL_OBJDIR)/monsterstate.o \ - $(DLL_OBJDIR)/multiplay_gamerules.o \ - $(DLL_OBJDIR)/nodes.o \ - $(DLL_OBJDIR)/observer.o \ - $(DLL_OBJDIR)/pathcorner.o \ - $(DLL_OBJDIR)/plane.o \ - $(DLL_OBJDIR)/plats.o \ - $(DLL_OBJDIR)/player.o \ - $(DLL_OBJDIR)/quake_gun.o \ - $(DLL_OBJDIR)/quake_items.o \ - $(DLL_OBJDIR)/quake_nail.o \ - $(DLL_OBJDIR)/quake_player.o \ - $(DLL_OBJDIR)/quake_rocket.o \ - $(DLL_OBJDIR)/quake_weapons_all.o \ - $(DLL_OBJDIR)/schedule.o \ - $(DLL_OBJDIR)/singleplay_gamerules.o \ - $(DLL_OBJDIR)/skill.o \ - $(DLL_OBJDIR)/sound.o \ - $(DLL_OBJDIR)/spectator.o \ - $(DLL_OBJDIR)/subs.o \ - $(DLL_OBJDIR)/teamplay_gamerules.o \ - $(DLL_OBJDIR)/triggers.o \ - $(DLL_OBJDIR)/util.o \ - $(DLL_OBJDIR)/weapons.o \ - $(DLL_OBJDIR)/world.o \ - $(PM_SHARED_OBJDIR)/pm_shared.o \ - $(PM_SHARED_OBJDIR)/pm_math.o \ - $(PM_SHARED_OBJDIR)/pm_debug.o \ - $(GAME_SHARED_OBJDIR)/voice_gamemgr.o - -$(DLLNAME)_$(ARCH).$(SHLIBEXT) : neat $(OBJ) - $(CC) $(CFLAGS) $(SHLIBLDFLAGS) $(LDFLAGS) -o $@ $(OBJ) - -neat: - -mkdir $(DLL_OBJDIR) - -mkdir $(GAME_SHARED_OBJDIR) - -mkdir $(PM_SHARED_OBJDIR) -clean: - -rm -f $(OBJ) - -rm -f $(DLLNAME)_$(ARCH).$(SHLIBEXT) -spotless: clean - -rm -r $(GAME_SHARED_OBJDIR) - -rm -r $(PM_SHARED_OBJDIR) - -rm -r $(DLL_OBJDIR) - diff --git a/dmc/dlls/activity.h b/dmc/dlls/activity.h deleted file mode 100644 index 6fd3a18..0000000 --- a/dmc/dlls/activity.h +++ /dev/null @@ -1,109 +0,0 @@ -/*** -* -* 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. -* -****/ - -#ifndef ACTIVITY_H -#define ACTIVITY_H - - -typedef enum { - ACT_RESET = 0, // Set m_Activity to this invalid value to force a reset to m_IdealActivity - ACT_IDLE = 1, - ACT_GUARD, - ACT_WALK, - ACT_RUN, - ACT_FLY, // Fly (and flap if appropriate) - ACT_SWIM, - ACT_HOP, // vertical jump - ACT_LEAP, // long forward jump - ACT_FALL, - ACT_LAND, - ACT_STRAFE_LEFT, - ACT_STRAFE_RIGHT, - ACT_ROLL_LEFT, // tuck and roll, left - ACT_ROLL_RIGHT, // tuck and roll, right - ACT_TURN_LEFT, // turn quickly left (stationary) - ACT_TURN_RIGHT, // turn quickly right (stationary) - ACT_CROUCH, // the act of crouching down from a standing position - ACT_CROUCHIDLE, // holding body in crouched position (loops) - ACT_STAND, // the act of standing from a crouched position - ACT_USE, - ACT_SIGNAL1, - ACT_SIGNAL2, - ACT_SIGNAL3, - ACT_TWITCH, - ACT_COWER, - ACT_SMALL_FLINCH, - ACT_BIG_FLINCH, - ACT_RANGE_ATTACK1, - ACT_RANGE_ATTACK2, - ACT_MELEE_ATTACK1, - ACT_MELEE_ATTACK2, - ACT_RELOAD, - ACT_ARM, // pull out gun, for instance - ACT_DISARM, // reholster gun - ACT_EAT, // monster chowing on a large food item (loop) - ACT_DIESIMPLE, - ACT_DIEBACKWARD, - ACT_DIEFORWARD, - ACT_DIEVIOLENT, - ACT_BARNACLE_HIT, // barnacle tongue hits a monster - ACT_BARNACLE_PULL, // barnacle is lifting the monster ( loop ) - ACT_BARNACLE_CHOMP, // barnacle latches on to the monster - ACT_BARNACLE_CHEW, // barnacle is holding the monster in its mouth ( loop ) - ACT_SLEEP, - ACT_INSPECT_FLOOR, // for active idles, look at something on or near the floor - ACT_INSPECT_WALL, // for active idles, look at something directly ahead of you ( doesn't HAVE to be a wall or on a wall ) - ACT_IDLE_ANGRY, // alternate idle animation in which the monster is clearly agitated. (loop) - ACT_WALK_HURT, // limp (loop) - ACT_RUN_HURT, // limp (loop) - ACT_HOVER, // Idle while in flight - ACT_GLIDE, // Fly (don't flap) - ACT_FLY_LEFT, // Turn left in flight - ACT_FLY_RIGHT, // Turn right in flight - ACT_DETECT_SCENT, // this means the monster smells a scent carried by the air - ACT_SNIFF, // this is the act of actually sniffing an item in front of the monster - ACT_BITE, // some large monsters can eat small things in one bite. This plays one time, EAT loops. - ACT_THREAT_DISPLAY, // without attacking, monster demonstrates that it is angry. (Yell, stick out chest, etc ) - ACT_FEAR_DISPLAY, // monster just saw something that it is afraid of - ACT_EXCITED, // for some reason, monster is excited. Sees something he really likes to eat, or whatever. - ACT_SPECIAL_ATTACK1, // very monster specific special attacks. - ACT_SPECIAL_ATTACK2, - ACT_COMBAT_IDLE, // agitated idle. - ACT_WALK_SCARED, - ACT_RUN_SCARED, - ACT_VICTORY_DANCE, // killed a player, do a victory dance. - ACT_DIE_HEADSHOT, // die, hit in head. - ACT_DIE_CHESTSHOT, // die, hit in chest - ACT_DIE_GUTSHOT, // die, hit in gut - ACT_DIE_BACKSHOT, // die, hit in back - ACT_FLINCH_HEAD, - ACT_FLINCH_CHEST, - ACT_FLINCH_STOMACH, - ACT_FLINCH_LEFTARM, - ACT_FLINCH_RIGHTARM, - ACT_FLINCH_LEFTLEG, - ACT_FLINCH_RIGHTLEG, -} Activity; - - -typedef struct { - int type; - char *name; -} activity_map_t; - -extern activity_map_t activity_map[]; - - -#endif //ACTIVITY_H diff --git a/dmc/dlls/activitymap.h b/dmc/dlls/activitymap.h deleted file mode 100644 index 92cadae..0000000 --- a/dmc/dlls/activitymap.h +++ /dev/null @@ -1,97 +0,0 @@ -/*** -* -* 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. -* -****/ - -#define _A( a ) { a, #a } - -activity_map_t activity_map[] = -{ -_A( ACT_IDLE ), -_A( ACT_GUARD ), -_A( ACT_WALK ), -_A( ACT_RUN ), -_A( ACT_FLY ), -_A( ACT_SWIM ), -_A( ACT_HOP ), -_A( ACT_LEAP ), -_A( ACT_FALL ), -_A( ACT_LAND ), -_A( ACT_STRAFE_LEFT ), -_A( ACT_STRAFE_RIGHT ), -_A( ACT_ROLL_LEFT ), -_A( ACT_ROLL_RIGHT ), -_A( ACT_TURN_LEFT ), -_A( ACT_TURN_RIGHT ), -_A( ACT_CROUCH ), -_A( ACT_CROUCHIDLE ), -_A( ACT_STAND ), -_A( ACT_USE ), -_A( ACT_SIGNAL1 ), -_A( ACT_SIGNAL2 ), -_A( ACT_SIGNAL3 ), -_A( ACT_TWITCH ), -_A( ACT_COWER ), -_A( ACT_SMALL_FLINCH ), -_A( ACT_BIG_FLINCH ), -_A( ACT_RANGE_ATTACK1 ), -_A( ACT_RANGE_ATTACK2 ), -_A( ACT_MELEE_ATTACK1 ), -_A( ACT_MELEE_ATTACK2 ), -_A( ACT_RELOAD ), -_A( ACT_ARM ), -_A( ACT_DISARM ), -_A( ACT_EAT ), -_A( ACT_DIESIMPLE ), -_A( ACT_DIEBACKWARD ), -_A( ACT_DIEFORWARD ), -_A( ACT_DIEVIOLENT ), -_A( ACT_BARNACLE_HIT ), -_A( ACT_BARNACLE_PULL ), -_A( ACT_BARNACLE_CHOMP ), -_A( ACT_BARNACLE_CHEW ), -_A( ACT_SLEEP ), -_A( ACT_INSPECT_FLOOR ), -_A( ACT_INSPECT_WALL ), -_A( ACT_IDLE_ANGRY ), -_A( ACT_WALK_HURT ), -_A( ACT_RUN_HURT ), -_A( ACT_HOVER ), -_A( ACT_GLIDE ), -_A( ACT_FLY_LEFT ), -_A( ACT_FLY_RIGHT ), -_A( ACT_DETECT_SCENT ), -_A( ACT_SNIFF ), -_A( ACT_BITE ), -_A( ACT_THREAT_DISPLAY ), -_A( ACT_FEAR_DISPLAY ), -_A( ACT_EXCITED ), -_A( ACT_SPECIAL_ATTACK1 ), -_A( ACT_SPECIAL_ATTACK2 ), -_A( ACT_COMBAT_IDLE ), -_A( ACT_WALK_SCARED ), -_A( ACT_RUN_SCARED ), -_A( ACT_VICTORY_DANCE ), -_A( ACT_DIE_HEADSHOT ), -_A( ACT_DIE_CHESTSHOT ), -_A( ACT_DIE_GUTSHOT ), -_A( ACT_DIE_BACKSHOT ), -_A( ACT_FLINCH_HEAD ), -_A( ACT_FLINCH_CHEST ), -_A( ACT_FLINCH_STOMACH ), -_A( ACT_FLINCH_LEFTARM ), -_A( ACT_FLINCH_RIGHTARM ), -_A( ACT_FLINCH_LEFTLEG ), -_A( ACT_FLINCH_RIGHTLEG ), -0, NULL -}; diff --git a/dmc/dlls/animating.cpp b/dmc/dlls/animating.cpp deleted file mode 100644 index 2da7536..0000000 --- a/dmc/dlls/animating.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== monsters.cpp ======================================================== - - Monster-related utility code - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "animation.h" -#include "saverestore.h" - -TYPEDESCRIPTION CBaseAnimating::m_SaveData[] = -{ - DEFINE_FIELD( CBaseMonster, m_flFrameRate, FIELD_FLOAT ), - DEFINE_FIELD( CBaseMonster, m_flGroundSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CBaseMonster, m_flLastEventCheck, FIELD_TIME ), - DEFINE_FIELD( CBaseMonster, m_fSequenceFinished, FIELD_BOOLEAN ), - DEFINE_FIELD( CBaseMonster, m_fSequenceLoops, FIELD_BOOLEAN ), -}; - -IMPLEMENT_SAVERESTORE( CBaseAnimating, CBaseDelay ); - - -//========================================================= -// StudioFrameAdvance - advance the animation frame up to the current time -// if an flInterval is passed in, only advance animation that number of seconds -//========================================================= -float CBaseAnimating :: StudioFrameAdvance ( float flInterval ) -{ - if (flInterval == 0.0) - { - flInterval = (gpGlobals->time - pev->animtime); - if (flInterval <= 0.001) - { - pev->animtime = gpGlobals->time; - return 0.0; - } - } - if (! pev->animtime) - flInterval = 0.0; - - pev->frame += flInterval * m_flFrameRate * pev->framerate; - pev->animtime = gpGlobals->time; - - if (pev->frame < 0.0 || pev->frame >= 256.0) - { - if (m_fSequenceLoops) - pev->frame -= (int)(pev->frame / 256.0) * 256.0; - else - pev->frame = (pev->frame < 0.0) ? 0 : 255; - m_fSequenceFinished = TRUE; // just in case it wasn't caught in GetEvents - } - - return flInterval; -} - -//========================================================= -// LookupActivity -//========================================================= -int CBaseAnimating :: LookupActivity ( int activity ) -{ - ASSERT( activity != 0 ); - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::LookupActivity( pmodel, pev, activity ); -} - -//========================================================= -// LookupActivityHeaviest -// -// Get activity with highest 'weight' -// -//========================================================= -int CBaseAnimating :: LookupActivityHeaviest ( int activity ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::LookupActivityHeaviest( pmodel, pev, activity ); -} - -//========================================================= -//========================================================= -int CBaseAnimating :: LookupSequence ( const char *label ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::LookupSequence( pmodel, label ); -} - - -//========================================================= -//========================================================= -void CBaseAnimating :: ResetSequenceInfo ( ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - GetSequenceInfo( pmodel, pev, &m_flFrameRate, &m_flGroundSpeed ); - m_fSequenceLoops = ((GetSequenceFlags() & STUDIO_LOOPING) != 0); - pev->animtime = gpGlobals->time; - pev->framerate = 1.0; - m_fSequenceFinished = FALSE; - m_flLastEventCheck = gpGlobals->time; -} - - - -//========================================================= -//========================================================= -BOOL CBaseAnimating :: GetSequenceFlags( ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::GetSequenceFlags( pmodel, pev ); -} - -//========================================================= -// DispatchAnimEvents -//========================================================= -void CBaseAnimating :: DispatchAnimEvents ( float flInterval ) -{ - MonsterEvent_t event; - - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - if ( !pmodel ) - { - ALERT( at_aiconsole, "Gibbed monster is thinking!\n" ); - return; - } - - // FIXME: I have to do this or some events get missed, and this is probably causing the problem below - flInterval = 0.1; - - // FIX: this still sometimes hits events twice - float flStart = pev->frame + (m_flLastEventCheck - pev->animtime) * m_flFrameRate * pev->framerate; - float flEnd = pev->frame + flInterval * m_flFrameRate * pev->framerate; - m_flLastEventCheck = pev->animtime + flInterval; - - m_fSequenceFinished = FALSE; - if (flEnd >= 256 || flEnd <= 0.0) - m_fSequenceFinished = TRUE; - - int index = 0; - - while ( (index = GetAnimationEvent( pmodel, pev, &event, flStart, flEnd, index ) ) != 0 ) - { - HandleAnimEvent( &event ); - } -} - - -//========================================================= -//========================================================= -float CBaseAnimating :: SetBoneController ( int iController, float flValue ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return SetController( pmodel, pev, iController, flValue ); -} - -//========================================================= -//========================================================= -void CBaseAnimating :: InitBoneControllers ( void ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - SetController( pmodel, pev, 0, 0.0 ); - SetController( pmodel, pev, 1, 0.0 ); - SetController( pmodel, pev, 2, 0.0 ); - SetController( pmodel, pev, 3, 0.0 ); -} - -//========================================================= -//========================================================= -float CBaseAnimating :: SetBlending ( int iBlender, float flValue ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::SetBlending( pmodel, pev, iBlender, flValue ); -} - -//========================================================= -//========================================================= -void CBaseAnimating :: GetBonePosition ( int iBone, Vector &origin, Vector &angles ) -{ - GET_BONE_POSITION( ENT(pev), iBone, origin, angles ); -} - -//========================================================= -//========================================================= -void CBaseAnimating :: GetAttachment ( int iAttachment, Vector &origin, Vector &angles ) -{ - GET_ATTACHMENT( ENT(pev), iAttachment, origin, angles ); -} - -//========================================================= -//========================================================= -int CBaseAnimating :: FindTransition( int iEndingSequence, int iGoalSequence, int *piDir ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - if (piDir == NULL) - { - int iDir; - int sequence = ::FindTransition( pmodel, iEndingSequence, iGoalSequence, &iDir ); - if (iDir != 1) - return -1; - else - return sequence; - } - - return ::FindTransition( pmodel, iEndingSequence, iGoalSequence, piDir ); -} - -//========================================================= -//========================================================= -void CBaseAnimating :: GetAutomovement( Vector &origin, Vector &angles, float flInterval ) -{ - -} - -void CBaseAnimating :: SetBodygroup( int iGroup, int iValue ) -{ - ::SetBodygroup( GET_MODEL_PTR( ENT(pev) ), pev, iGroup, iValue ); -} - -int CBaseAnimating :: GetBodygroup( int iGroup ) -{ - return ::GetBodygroup( GET_MODEL_PTR( ENT(pev) ), pev, iGroup ); -} - - -int CBaseAnimating :: ExtractBbox( int sequence, float *mins, float *maxs ) -{ - return ::ExtractBbox( GET_MODEL_PTR( ENT(pev) ), sequence, mins, maxs ); -} - -//========================================================= -//========================================================= - -void CBaseAnimating :: SetSequenceBox( void ) -{ - Vector mins, maxs; - - // Get sequence bbox - if ( ExtractBbox( pev->sequence, mins, maxs ) ) - { - // expand box for rotation - // find min / max for rotations - float yaw = pev->angles.y * (M_PI / 180.0); - - Vector xvector, yvector; - xvector.x = cos(yaw); - xvector.y = sin(yaw); - yvector.x = -sin(yaw); - yvector.y = cos(yaw); - Vector bounds[2]; - - bounds[0] = mins; - bounds[1] = maxs; - - Vector rmin( 9999, 9999, 9999 ); - Vector rmax( -9999, -9999, -9999 ); - Vector base, transformed; - - for (int i = 0; i <= 1; i++ ) - { - base.x = bounds[i].x; - for ( int j = 0; j <= 1; j++ ) - { - base.y = bounds[j].y; - for ( int k = 0; k <= 1; k++ ) - { - base.z = bounds[k].z; - - // transform the point - transformed.x = xvector.x*base.x + yvector.x*base.y; - transformed.y = xvector.y*base.x + yvector.y*base.y; - transformed.z = base.z; - - for ( int l = 0; l < 3; l++ ) - { - if (transformed[l] < rmin[l]) - rmin[l] = transformed[l]; - if (transformed[l] > rmax[l]) - rmax[l] = transformed[l]; - } - } - } - } - rmin.z = 0; - rmax.z = rmin.z + 1; - UTIL_SetSize( pev, rmin, rmax ); - } -} - diff --git a/dmc/dlls/animation.cpp b/dmc/dlls/animation.cpp deleted file mode 100644 index cff609e..0000000 --- a/dmc/dlls/animation.cpp +++ /dev/null @@ -1,524 +0,0 @@ -/*** -* -* 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. -* -****/ - -#include "Platform.h" - -// hack into header files that we can ship -typedef int qboolean; -typedef unsigned char byte; -#include "../utils/common/mathlib.h" -#include "const.h" - -#include "progdefs.h" -#include "edict.h" -#include "eiface.h" - -#include "studio.h" - -#include "../engine/studio.h" - -#ifndef ACTIVITY_H -#include "activity.h" -#endif - -#include "activitymap.h" - -#ifndef ANIMATION_H -#include "animation.h" -#endif - -#ifndef SCRIPTEVENT_H -#include "scriptevent.h" -#endif - -#ifndef ENGINECALLBACK_H -#include "enginecallback.h" -#endif - -extern globalvars_t *gpGlobals; - -#pragma warning( disable : 4244 ) - - - -int ExtractBbox( void *pmodel, int sequence, float *mins, float *maxs ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return 0; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - mins[0] = pseqdesc[ sequence ].bbmin[0]; - mins[1] = pseqdesc[ sequence ].bbmin[1]; - mins[2] = pseqdesc[ sequence ].bbmin[2]; - - maxs[0] = pseqdesc[ sequence ].bbmax[0]; - maxs[1] = pseqdesc[ sequence ].bbmax[1]; - maxs[2] = pseqdesc[ sequence ].bbmax[2]; - - return 1; -} - - -int LookupActivity( void *pmodel, entvars_t *pev, int activity ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return 0; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - int weighttotal = 0; - int seq = ACTIVITY_NOT_AVAILABLE; - for (int i = 0; i < pstudiohdr->numseq; i++) - { - if (pseqdesc[i].activity == activity) - { - weighttotal += pseqdesc[i].actweight; - if (!weighttotal || RANDOM_LONG(0,weighttotal-1) < pseqdesc[i].actweight) - seq = i; - } - } - - return seq; -} - - -int LookupActivityHeaviest( void *pmodel, entvars_t *pev, int activity ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr ) - return 0; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - int weight = 0; - int seq = ACTIVITY_NOT_AVAILABLE; - for (int i = 0; i < pstudiohdr->numseq; i++) - { - if (pseqdesc[i].activity == activity) - { - if ( pseqdesc[i].actweight > weight ) - { - weight = pseqdesc[i].actweight; - seq = i; - } - } - } - - return seq; -} - -void GetEyePosition ( void *pmodel, float *vecEyePosition ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - - if ( !pstudiohdr ) - { - ALERT ( at_console, "GetEyePosition() Can't get pstudiohdr ptr!\n" ); - return; - } - - VectorCopy ( pstudiohdr->eyeposition, vecEyePosition ); -} - -int LookupSequence( void *pmodel, const char *label ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return 0; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - for (int i = 0; i < pstudiohdr->numseq; i++) - { - if (stricmp( pseqdesc[i].label, label ) == 0) - return i; - } - - return -1; -} - - -int IsSoundEvent( int eventNumber ) -{ - if ( eventNumber == SCRIPT_EVENT_SOUND || eventNumber == SCRIPT_EVENT_SOUND_VOICE ) - return 1; - return 0; -} - - -void SequencePrecache( void *pmodel, const char *pSequenceName ) -{ - int index = LookupSequence( pmodel, pSequenceName ); - if ( index >= 0 ) - { - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr || index >= pstudiohdr->numseq ) - return; - - mstudioseqdesc_t *pseqdesc; - mstudioevent_t *pevent; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + index; - pevent = (mstudioevent_t *)((byte *)pstudiohdr + pseqdesc->eventindex); - - for (int i = 0; i < pseqdesc->numevents; i++) - { - // Don't send client-side events to the server AI - if ( pevent[i].event >= EVENT_CLIENT ) - continue; - - // UNDONE: Add a callback to check to see if a sound is precached yet and don't allocate a copy - // of it's name if it is. - if ( IsSoundEvent( pevent[i].event ) ) - { - if ( !strlen(pevent[i].options) ) - { - ALERT( at_error, "Bad sound event %d in sequence %s :: %s (sound is \"%s\")\n", pevent[i].event, pstudiohdr->name, pSequenceName, pevent[i].options ); - } - - PRECACHE_SOUND( (char *)(gpGlobals->pStringBase + ALLOC_STRING(pevent[i].options) ) ); - } - } - } -} - - - -void GetSequenceInfo( void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return; - - mstudioseqdesc_t *pseqdesc; - - if (pev->sequence >= pstudiohdr->numseq) - { - *pflFrameRate = 0.0; - *pflGroundSpeed = 0.0; - return; - } - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - if (pseqdesc->numframes > 1) - { - *pflFrameRate = 256 * pseqdesc->fps / (pseqdesc->numframes - 1); - *pflGroundSpeed = sqrt( pseqdesc->linearmovement[0]*pseqdesc->linearmovement[0]+ pseqdesc->linearmovement[1]*pseqdesc->linearmovement[1]+ pseqdesc->linearmovement[2]*pseqdesc->linearmovement[2] ); - *pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1); - } - else - { - *pflFrameRate = 256.0; - *pflGroundSpeed = 0.0; - } -} - - -int GetSequenceFlags( void *pmodel, entvars_t *pev ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr || pev->sequence >= pstudiohdr->numseq ) - return 0; - - mstudioseqdesc_t *pseqdesc; - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - return pseqdesc->flags; -} - - -int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEvent, float flStart, float flEnd, int index ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr || pev->sequence >= pstudiohdr->numseq || !pMonsterEvent ) - return 0; - - int events = 0; - - mstudioseqdesc_t *pseqdesc; - mstudioevent_t *pevent; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - pevent = (mstudioevent_t *)((byte *)pstudiohdr + pseqdesc->eventindex); - - if (pseqdesc->numevents == 0 || index > pseqdesc->numevents ) - return 0; - - if (pseqdesc->numframes > 1) - { - flStart *= (pseqdesc->numframes - 1) / 256.0; - flEnd *= (pseqdesc->numframes - 1) / 256.0; - } - else - { - flStart = 0; - flEnd = 1.0; - } - - for (; index < pseqdesc->numevents; index++) - { - // Don't send client-side events to the server AI - if ( pevent[index].event >= EVENT_CLIENT ) - continue; - - if ( (pevent[index].frame >= flStart && pevent[index].frame < flEnd) || - ((pseqdesc->flags & STUDIO_LOOPING) && flEnd >= pseqdesc->numframes - 1 && pevent[index].frame < flEnd - pseqdesc->numframes + 1) ) - { - pMonsterEvent->event = pevent[index].event; - pMonsterEvent->options = pevent[index].options; - return index + 1; - } - } - return 0; -} - -float SetController( void *pmodel, entvars_t *pev, int iController, float flValue ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return flValue; - - mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)pstudiohdr + pstudiohdr->bonecontrollerindex); - - // find first controller that matches the index - int i; - for ( i = 0; i < pstudiohdr->numbonecontrollers; i++, pbonecontroller++) - { - if (pbonecontroller->index == iController) - break; - } - if (i >= pstudiohdr->numbonecontrollers) - return flValue; - - // wrap 0..360 if it's a rotational controller - - if (pbonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR)) - { - // ugly hack, invert value if end < start - if (pbonecontroller->end < pbonecontroller->start) - flValue = -flValue; - - // does the controller not wrap? - if (pbonecontroller->start + 359.0 >= pbonecontroller->end) - { - if (flValue > ((pbonecontroller->start + pbonecontroller->end) / 2.0) + 180) - flValue = flValue - 360; - if (flValue < ((pbonecontroller->start + pbonecontroller->end) / 2.0) - 180) - flValue = flValue + 360; - } - else - { - if (flValue > 360) - flValue = flValue - (int)(flValue / 360.0) * 360.0; - else if (flValue < 0) - flValue = flValue + (int)((flValue / -360.0) + 1) * 360.0; - } - } - - int setting = 255 * (flValue - pbonecontroller->start) / (pbonecontroller->end - pbonecontroller->start); - - if (setting < 0) setting = 0; - if (setting > 255) setting = 255; - pev->controller[iController] = setting; - - return setting * (1.0 / 255.0) * (pbonecontroller->end - pbonecontroller->start) + pbonecontroller->start; -} - - -float SetBlending( void *pmodel, entvars_t *pev, int iBlender, float flValue ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return flValue; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - if (pseqdesc->blendtype[iBlender] == 0) - return flValue; - - if (pseqdesc->blendtype[iBlender] & (STUDIO_XR | STUDIO_YR | STUDIO_ZR)) - { - // ugly hack, invert value if end < start - if (pseqdesc->blendend[iBlender] < pseqdesc->blendstart[iBlender]) - flValue = -flValue; - - // does the controller not wrap? - if (pseqdesc->blendstart[iBlender] + 359.0 >= pseqdesc->blendend[iBlender]) - { - if (flValue > ((pseqdesc->blendstart[iBlender] + pseqdesc->blendend[iBlender]) / 2.0) + 180) - flValue = flValue - 360; - if (flValue < ((pseqdesc->blendstart[iBlender] + pseqdesc->blendend[iBlender]) / 2.0) - 180) - flValue = flValue + 360; - } - } - - int setting = 255 * (flValue - pseqdesc->blendstart[iBlender]) / (pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender]); - - if (setting < 0) setting = 0; - if (setting > 255) setting = 255; - - pev->blending[iBlender] = setting; - - return setting * (1.0 / 255.0) * (pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender]) + pseqdesc->blendstart[iBlender]; -} - - - - -int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return iGoalAnim; - - mstudioseqdesc_t *pseqdesc; - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - // bail if we're going to or from a node 0 - if (pseqdesc[iEndingAnim].entrynode == 0 || pseqdesc[iGoalAnim].entrynode == 0) - { - return iGoalAnim; - } - - int iEndNode; - - // ALERT( at_console, "from %d to %d: ", pEndNode->iEndNode, pGoalNode->iStartNode ); - - if (*piDir > 0) - { - iEndNode = pseqdesc[iEndingAnim].exitnode; - } - else - { - iEndNode = pseqdesc[iEndingAnim].entrynode; - } - - if (iEndNode == pseqdesc[iGoalAnim].entrynode) - { - *piDir = 1; - return iGoalAnim; - } - - byte *pTransition = ((byte *)pstudiohdr + pstudiohdr->transitionindex); - - int iInternNode = pTransition[(iEndNode-1)*pstudiohdr->numtransitions + (pseqdesc[iGoalAnim].entrynode-1)]; - - if (iInternNode == 0) - return iGoalAnim; - - int i; - - // look for someone going - for (i = 0; i < pstudiohdr->numseq; i++) - { - if (pseqdesc[i].entrynode == iEndNode && pseqdesc[i].exitnode == iInternNode) - { - *piDir = 1; - return i; - } - if (pseqdesc[i].nodeflags) - { - if (pseqdesc[i].exitnode == iEndNode && pseqdesc[i].entrynode == iInternNode) - { - *piDir = -1; - return i; - } - } - } - - ALERT( at_console, "error in transition graph" ); - return iGoalAnim; -} - -void SetBodygroup( void *pmodel, entvars_t *pev, int iGroup, int iValue ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return; - - if (iGroup > pstudiohdr->numbodyparts) - return; - - mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + iGroup; - - if (iValue >= pbodypart->nummodels) - return; - - int iCurrent = (pev->body / pbodypart->base) % pbodypart->nummodels; - - pev->body = (pev->body - (iCurrent * pbodypart->base) + (iValue * pbodypart->base)); -} - - -int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return 0; - - if (iGroup > pstudiohdr->numbodyparts) - return 0; - - mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + iGroup; - - if (pbodypart->nummodels <= 1) - return 0; - - int iCurrent = (pev->body / pbodypart->base) % pbodypart->nummodels; - - return iCurrent; -} diff --git a/dmc/dlls/animation.h b/dmc/dlls/animation.h deleted file mode 100644 index 174bd71..0000000 --- a/dmc/dlls/animation.h +++ /dev/null @@ -1,47 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef ANIMATION_H -#define ANIMATION_H - -#define ACTIVITY_NOT_AVAILABLE -1 - -#ifndef MONSTEREVENT_H -#include "monsterevent.h" -#endif - -extern int IsSoundEvent( int eventNumber ); - -int LookupActivity( void *pmodel, entvars_t *pev, int activity ); -int LookupActivityHeaviest( void *pmodel, entvars_t *pev, int activity ); -int LookupSequence( void *pmodel, const char *label ); -void GetSequenceInfo( void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed ); -int GetSequenceFlags( void *pmodel, entvars_t *pev ); -int LookupAnimationEvents( void *pmodel, entvars_t *pev, float flStart, float flEnd ); -float SetController( void *pmodel, entvars_t *pev, int iController, float flValue ); -float SetBlending( void *pmodel, entvars_t *pev, int iBlender, float flValue ); -void GetEyePosition( void *pmodel, float *vecEyePosition ); -void SequencePrecache( void *pmodel, const char *pSequenceName ); -int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir ); -void SetBodygroup( void *pmodel, entvars_t *pev, int iGroup, int iValue ); -int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup ); - -int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEvent, float flStart, float flEnd, int index ); -int ExtractBbox( void *pmodel, int sequence, float *mins, float *maxs ); - -// From /engine/studio.h -#define STUDIO_LOOPING 0x0001 - - -#endif //ANIMATION_H diff --git a/dmc/dlls/basemonster.h b/dmc/dlls/basemonster.h deleted file mode 100644 index 190965d..0000000 --- a/dmc/dlls/basemonster.h +++ /dev/null @@ -1,339 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ - -#ifndef BASEMONSTER_H -#define BASEMONSTER_H - -// -// generic Monster -// -class CBaseMonster : public CBaseToggle -{ -private: - int m_afConditions; - -public: - typedef enum - { - SCRIPT_PLAYING = 0, // Playing the sequence - SCRIPT_WAIT, // Waiting on everyone in the script to be ready - SCRIPT_CLEANUP, // Cancelling the script / cleaning up - SCRIPT_WALK_TO_MARK, - SCRIPT_RUN_TO_MARK, - } SCRIPTSTATE; - - - - // these fields have been added in the process of reworking the state machine. (sjb) - EHANDLE m_hEnemy; // the entity that the monster is fighting. - EHANDLE m_hTargetEnt; // the entity that the monster is trying to reach - EHANDLE m_hOldEnemy[ MAX_OLD_ENEMIES ]; - Vector m_vecOldEnemy[ MAX_OLD_ENEMIES ]; - - float m_flFieldOfView;// width of monster's field of view ( dot product ) - float m_flWaitFinished;// if we're told to wait, this is the time that the wait will be over. - float m_flMoveWaitFinished; - - Activity m_Activity;// what the monster is doing (animation) - Activity m_IdealActivity;// monster should switch to this activity - - int m_LastHitGroup; // the last body region that took damage - - MONSTERSTATE m_MonsterState;// monster's current state - MONSTERSTATE m_IdealMonsterState;// monster should change to this state - - int m_iTaskStatus; - Schedule_t *m_pSchedule; - int m_iScheduleIndex; - - WayPoint_t m_Route[ ROUTE_SIZE ]; // Positions of movement - int m_movementGoal; // Goal that defines route - int m_iRouteIndex; // index into m_Route[] - float m_moveWaitTime; // How long I should wait for something to move - - Vector m_vecMoveGoal; // kept around for node graph moves, so we know our ultimate goal - Activity m_movementActivity; // When moving, set this activity - - int m_iAudibleList; // first index of a linked list of sounds that the monster can hear. - int m_afSoundTypes; - - Vector m_vecLastPosition;// monster sometimes wants to return to where it started after an operation. - - int m_iHintNode; // this is the hint node that the monster is moving towards or performing active idle on. - - int m_afMemory; - - int m_iMaxHealth;// keeps track of monster's maximum health value (for re-healing, etc) - - Vector m_vecEnemyLKP;// last known position of enemy. (enemy's origin) - - int m_cAmmoLoaded; // how much ammo is in the weapon (used to trigger reload anim sequences) - - int m_afCapability;// tells us what a monster can/can't do. - - float m_flNextAttack; // cannot attack again until this time - - int m_bitsDamageType; // what types of damage has monster (player) taken - BYTE m_rgbTimeBasedDamage[CDMG_TIMEBASED]; - - int m_lastDamageAmount;// how much damage did monster (player) last take - // time based damage counters, decr. 1 per 2 seconds - int m_bloodColor; // color of blood particless - - int m_failSchedule; // Schedule type to choose if current schedule fails - - float m_flHungryTime;// set this is a future time to stop the monster from eating for a while. - - float m_flDistTooFar; // if enemy farther away than this, bits_COND_ENEMY_TOOFAR set in CheckEnemy - float m_flDistLook; // distance monster sees (Default 2048) - - int m_iTriggerCondition;// for scripted AI, this is the condition that will cause the activation of the monster's TriggerTarget - string_t m_iszTriggerTarget;// name of target that should be fired. - - Vector m_HackedGunPos; // HACK until we can query end of gun - -// Scripted sequence Info - SCRIPTSTATE m_scriptState; // internal cinematic state - CCineMonster *m_pCine; - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - void KeyValue( KeyValueData *pkvd ); - -// monster use function - void EXPORT MonsterUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT CorpseUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -// overrideable Monster member functions - - virtual int BloodColor( void ) { return m_bloodColor; } - - virtual CBaseMonster *MyMonsterPointer( void ) { return this; } - virtual void Look ( int iDistance );// basic sight function for monsters - virtual void RunAI ( void );// core ai function! - void Listen ( void ); - - virtual BOOL IsAlive( void ) { return (pev->deadflag != DEAD_DEAD); } - virtual BOOL ShouldFadeOnDeath( void ); - -// Basic Monster AI functions - virtual float ChangeYaw ( int speed ); - float VecToYaw( Vector vecDir ); - float FlYawDiff ( void ); - - float DamageForce( float damage ); - -// stuff written for new state machine - virtual void MonsterThink( void ); - void EXPORT CallMonsterThink( void ) { this->MonsterThink(); } - virtual int IRelationship ( CBaseEntity *pTarget ); - virtual void MonsterInit ( void ); - virtual void MonsterInitDead( void ); // Call after animation/pose is set up - virtual void BecomeDead( void ); - void EXPORT CorpseFallThink( void ); - - void EXPORT MonsterInitThink ( void ); - virtual void StartMonster ( void ); - virtual CBaseEntity* BestVisibleEnemy ( void );// finds best visible enemy for attack - virtual BOOL FInViewCone ( CBaseEntity *pEntity );// see if pEntity is in monster's view cone - virtual BOOL FInViewCone ( Vector *pOrigin );// see if given location is in monster's view cone - virtual void HandleAnimEvent( MonsterEvent_t *pEvent ); - - virtual int CheckLocalMove ( const Vector &vecStart, const Vector &vecEnd, CBaseEntity *pTarget, float *pflDist );// check validity of a straight move through space - virtual void Move( float flInterval = 0.1 ); - virtual void MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval ); - virtual BOOL ShouldAdvanceRoute( float flWaypointDist ); - - virtual Activity GetStoppedActivity( void ) { return ACT_IDLE; } - virtual void Stop( void ) { m_IdealActivity = GetStoppedActivity(); } - - // This will stop animation until you call ResetSequenceInfo() at some point in the future - inline void StopAnimation( void ) { pev->framerate = 0; } - - // these functions will survey conditions and set appropriate conditions bits for attack types. - virtual BOOL CheckRangeAttack1( float flDot, float flDist ); - virtual BOOL CheckRangeAttack2( float flDot, float flDist ); - virtual BOOL CheckMeleeAttack1( float flDot, float flDist ); - virtual BOOL CheckMeleeAttack2( float flDot, float flDist ); - - BOOL FHaveSchedule( void ); - BOOL FScheduleValid ( void ); - void ClearSchedule( void ); - BOOL FScheduleDone ( void ); - void ChangeSchedule ( Schedule_t *pNewSchedule ); - void NextScheduledTask ( void ); - Schedule_t *ScheduleInList( const char *pName, Schedule_t **pList, int listCount ); - - virtual Schedule_t *ScheduleFromName( const char *pName ); - static Schedule_t *m_scheduleList[]; - - void MaintainSchedule ( void ); - virtual void StartTask ( Task_t *pTask ); - virtual void RunTask ( Task_t *pTask ); - virtual Schedule_t *GetScheduleOfType( int Type ); - virtual Schedule_t *GetSchedule( void ); - virtual void ScheduleChange( void ) {} - // virtual int CanPlaySequence( void ) { return ((m_pCine == NULL) && (m_MonsterState == MONSTERSTATE_NONE || m_MonsterState == MONSTERSTATE_IDLE || m_IdealMonsterState == MONSTERSTATE_IDLE)); } - virtual int CanPlaySequence( BOOL fDisregardState, int interruptLevel ); - virtual int CanPlaySentence( BOOL fDisregardState ) { return IsAlive(); } - virtual void PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ); - virtual void PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ); - - virtual void SentenceStop( void ); - - Task_t *GetTask ( void ); - virtual MONSTERSTATE GetIdealState ( void ); - virtual void SetActivity ( Activity NewActivity ); - void SetSequenceByName ( char *szSequence ); - void SetState ( MONSTERSTATE State ); - virtual void ReportAIState( void ); - - void CheckAttacks ( CBaseEntity *pTarget, float flDist ); - virtual int CheckEnemy ( CBaseEntity *pEnemy ); - void PushEnemy( CBaseEntity *pEnemy, Vector &vecLastKnownPos ); - BOOL PopEnemy( void ); - - BOOL FGetNodeRoute ( Vector vecDest ); - - inline void TaskComplete( void ) { if ( !HasConditions(bits_COND_TASK_FAILED) ) m_iTaskStatus = TASKSTATUS_COMPLETE; } - void MovementComplete( void ); - inline void TaskFail( void ) { SetConditions(bits_COND_TASK_FAILED); } - inline void TaskBegin( void ) { m_iTaskStatus = TASKSTATUS_RUNNING; } - int TaskIsRunning( void ); - inline int TaskIsComplete( void ) { return (m_iTaskStatus == TASKSTATUS_COMPLETE); } - inline int MovementIsComplete( void ) { return (m_movementGoal == MOVEGOAL_NONE); } - - int IScheduleFlags ( void ); - BOOL FRefreshRoute( void ); - BOOL FRouteClear ( void ); - void RouteSimplify( CBaseEntity *pTargetEnt ); - void AdvanceRoute ( float distance ); - virtual BOOL FTriangulate ( const Vector &vecStart , const Vector &vecEnd, float flDist, CBaseEntity *pTargetEnt, Vector *pApex ); - void MakeIdealYaw( Vector vecTarget ); - virtual void SetYawSpeed ( void ) { return; };// allows different yaw_speeds for each activity - BOOL BuildRoute ( const Vector &vecGoal, int iMoveFlag, CBaseEntity *pTarget ); - virtual BOOL BuildNearestRoute ( Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist ); - int RouteClassify( int iMoveFlag ); - void InsertWaypoint ( Vector vecLocation, int afMoveFlags ); - - BOOL FindLateralCover ( const Vector &vecThreat, const Vector &vecViewOffset ); - virtual BOOL FindCover ( Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist ); - virtual BOOL FValidateCover ( const Vector &vecCoverLocation ) { return TRUE; }; - virtual float CoverRadius( void ) { return 784; } // Default cover radius - - virtual BOOL FCanCheckAttacks ( void ); - virtual void CheckAmmo( void ) { return; }; - virtual int IgnoreConditions ( void ); - - inline void SetConditions( int iConditions ) { m_afConditions |= iConditions; } - inline void ClearConditions( int iConditions ) { m_afConditions &= ~iConditions; } - inline BOOL HasConditions( int iConditions ) { if ( m_afConditions & iConditions ) return TRUE; return FALSE; } - inline BOOL HasAllConditions( int iConditions ) { if ( (m_afConditions & iConditions) == iConditions ) return TRUE; return FALSE; } - - virtual BOOL FValidateHintType( short sHint ); - int FindHintNode ( void ); - virtual BOOL FCanActiveIdle ( void ); - void SetTurnActivity ( void ); - float FLSoundVolume ( CSound *pSound ); - - BOOL MoveToNode( Activity movementAct, float waitTime, const Vector &goal ); - BOOL MoveToTarget( Activity movementAct, float waitTime ); - BOOL MoveToLocation( Activity movementAct, float waitTime, const Vector &goal ); - BOOL MoveToEnemy( Activity movementAct, float waitTime ); - - // Returns the time when the door will be open - float OpenDoorAndWait( entvars_t *pevDoor ); - - virtual int ISoundMask( void ); - virtual CSound* PBestSound ( void ); - virtual CSound* PBestScent ( void ); - virtual float HearingSensitivity( void ) { return 1.0; }; - - BOOL FBecomeProne ( void ); - virtual void BarnacleVictimBitten( entvars_t *pevBarnacle ); - virtual void BarnacleVictimReleased( void ); - - void SetEyePosition ( void ); - - BOOL FShouldEat( void );// see if a monster is 'hungry' - void Eat ( float flFullDuration );// make the monster 'full' for a while. - - CBaseEntity *CheckTraceHullAttack( float flDist, int iDamage, int iDmgType ); - BOOL FacingIdeal( void ); - - BOOL FCheckAITrigger( void );// checks and, if necessary, fires the monster's trigger target. - BOOL NoFriendlyFire( void ); - - BOOL BBoxFlat( void ); - - // PrescheduleThink - virtual void PrescheduleThink( void ) { return; }; - - BOOL GetEnemy ( void ); - void MakeDamageBloodDecal ( int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir ); - void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); - - // combat functions - float UpdateTarget ( entvars_t *pevTarget ); - virtual Activity GetDeathActivity ( void ); - Activity GetSmallFlinchActivity( void ); - virtual void Killed( entvars_t *pevAttacker, int iGib ); - virtual void GibMonster( void ); - BOOL ShouldGibMonster( int iGib ); - void CallGibMonster( void ); - virtual BOOL HasHumanGibs( void ); - virtual BOOL HasAlienGibs( void ); - virtual void FadeMonster( void ); // Called instead of GibMonster() when gibs are disabled - - Vector ShootAtEnemy( const Vector &shootOrigin ); - virtual Vector BodyTarget( const Vector &posSrc ) { return Center( ) * 0.75 + EyePosition() * 0.25; }; // position to shoot at - - virtual Vector GetGunPosition( void ); - - virtual int TakeHealth( float flHealth, int bitsDamageType ); - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType); - int DeadTakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); - - void RadiusDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ); - void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ); - virtual int IsMoving( void ) { return m_movementGoal != MOVEGOAL_NONE; } - - void RouteClear( void ); - void RouteNew( void ); - - virtual void DeathSound ( void ) { return; }; - virtual void AlertSound ( void ) { return; }; - virtual void IdleSound ( void ) { return; }; - virtual void PainSound ( void ) { return; }; - - virtual void StopFollowing( BOOL clearSchedule ) {} - - inline void Remember( int iMemory ) { m_afMemory |= iMemory; } - inline void Forget( int iMemory ) { m_afMemory &= ~iMemory; } - inline BOOL HasMemory( int iMemory ) { if ( m_afMemory & iMemory ) return TRUE; return FALSE; } - inline BOOL HasAllMemories( int iMemory ) { if ( (m_afMemory & iMemory) == iMemory ) return TRUE; return FALSE; } - - BOOL ExitScriptedSequence( ); - BOOL CineCleanup( ); - - CBaseEntity* DropItem ( char *pszItemName, const Vector &vecPos, const Vector &vecAng );// drop an item. -}; - - - -#endif // BASEMONSTER_H diff --git a/dmc/dlls/bmodels.cpp b/dmc/dlls/bmodels.cpp deleted file mode 100644 index 8016d35..0000000 --- a/dmc/dlls/bmodels.cpp +++ /dev/null @@ -1,958 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== bmodels.cpp ======================================================== - - spawn, think, and use functions for entities that use brush models - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "doors.h" - -extern DLL_GLOBAL Vector g_vecAttackDir; - -#define SF_BRUSH_ACCDCC 16// brush should accelerate and decelerate when toggled -#define SF_BRUSH_HURT 32// rotating brush that inflicts pain based on rotation speed -#define SF_ROTATING_NOT_SOLID 64 // some special rotating objects are not solid. - -// covering cheesy noise1, noise2, & noise3 fields so they make more sense (for rotating fans) -#define noiseStart noise1 -#define noiseStop noise2 -#define noiseRunning noise3 - -#define SF_PENDULUM_SWING 2 // spawnflag that makes a pendulum a rope swing. -// -// BModelOrigin - calculates origin of a bmodel from absmin/size because all bmodel origins are 0 0 0 -// -Vector VecBModelOrigin( entvars_t* pevBModel ) -{ - return pevBModel->absmin + ( pevBModel->size * 0.5 ); -} - -// =================== FUNC_WALL ============================================== - -/*QUAKED func_wall (0 .5 .8) ? -This is just a solid wall if not inhibited -*/ -class CFuncWall : public CBaseEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - // Bmodels don't go across transitions - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } -}; - -LINK_ENTITY_TO_CLASS( func_wall, CFuncWall ); - -void CFuncWall :: Spawn( void ) -{ - pev->angles = g_vecZero; - pev->movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything - pev->solid = SOLID_BSP; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - // If it can't move/go away, it's really part of the world - pev->flags |= FL_WORLDBRUSH; -} - - -void CFuncWall :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( ShouldToggle( useType, (int)(pev->frame)) ) - pev->frame = 1 - pev->frame; -} - - -#define SF_WALL_START_OFF 0x0001 - -class CFuncWallToggle : public CFuncWall -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void TurnOff( void ); - void TurnOn( void ); - BOOL IsOn( void ); -}; - -LINK_ENTITY_TO_CLASS( func_wall_toggle, CFuncWallToggle ); - -void CFuncWallToggle :: Spawn( void ) -{ - CFuncWall::Spawn(); - if ( pev->spawnflags & SF_WALL_START_OFF ) - TurnOff(); -} - - -void CFuncWallToggle :: TurnOff( void ) -{ - pev->solid = SOLID_NOT; - pev->effects |= EF_NODRAW; - UTIL_SetOrigin( pev, pev->origin ); -} - - -void CFuncWallToggle :: TurnOn( void ) -{ - pev->solid = SOLID_BSP; - pev->effects &= ~EF_NODRAW; - UTIL_SetOrigin( pev, pev->origin ); -} - - -BOOL CFuncWallToggle :: IsOn( void ) -{ - if ( pev->solid == SOLID_NOT ) - return FALSE; - return TRUE; -} - - -void CFuncWallToggle :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int status = IsOn(); - - if ( ShouldToggle( useType, status ) ) - { - if ( status ) - TurnOff(); - else - TurnOn(); - } -} - - -#define SF_CONVEYOR_VISUAL 0x0001 -#define SF_CONVEYOR_NOTSOLID 0x0002 - -class CFuncConveyor : public CFuncWall -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void UpdateSpeed( float speed ); -}; - -LINK_ENTITY_TO_CLASS( func_conveyor, CFuncConveyor ); -void CFuncConveyor :: Spawn( void ) -{ - SetMovedir( pev ); - CFuncWall::Spawn(); - - if ( !(pev->spawnflags & SF_CONVEYOR_VISUAL) ) - SetBits( pev->flags, FL_CONVEYOR ); - - // HACKHACK - This is to allow for some special effects - if ( pev->spawnflags & SF_CONVEYOR_NOTSOLID ) - { - pev->solid = SOLID_NOT; - pev->skin = 0; // Don't want the engine thinking we've got special contents on this brush - } - - if ( pev->speed == 0 ) - pev->speed = 100; - - UpdateSpeed( pev->speed ); -} - - -// HACKHACK -- This is ugly, but encode the speed in the rendercolor to avoid adding more data to the network stream -void CFuncConveyor :: UpdateSpeed( float speed ) -{ - // Encode it as an integer with 4 fractional bits - int speedCode = (int)(fabs(speed) * 16.0); - - if ( speed < 0 ) - pev->rendercolor.x = 1; - else - pev->rendercolor.x = 0; - - pev->rendercolor.y = (speedCode >> 8); - pev->rendercolor.z = (speedCode & 0xFF); -} - - -void CFuncConveyor :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - pev->speed = -pev->speed; - UpdateSpeed( pev->speed ); -} - - - -// =================== FUNC_ILLUSIONARY ============================================== - - -/*QUAKED func_illusionary (0 .5 .8) ? -A simple entity that looks solid but lets you walk through it. -*/ -class CFuncIllusionary : public CBaseToggle -{ -public: - void Spawn( void ); - void EXPORT SloshTouch( CBaseEntity *pOther ); - void KeyValue( KeyValueData *pkvd ); - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } -}; - -LINK_ENTITY_TO_CLASS( func_illusionary, CFuncIllusionary ); - -void CFuncIllusionary :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "skin"))//skin is used for content type - { - pev->skin = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -void CFuncIllusionary :: Spawn( void ) -{ - pev->angles = g_vecZero; - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_NOT;// always solid_not - SET_MODEL( ENT(pev), STRING(pev->model) ); - - // I'd rather eat the network bandwidth of this than figure out how to save/restore - // these entities after they have been moved to the client, or respawn them ala Quake - // Perhaps we can do this in deathmatch only. - // MAKE_STATIC(ENT(pev)); -} - - -// ------------------------------------------------------------------------------- -// -// Monster only clip brush -// -// This brush will be solid for any entity who has the FL_MONSTERCLIP flag set -// in pev->flags -// -// otherwise it will be invisible and not solid. This can be used to keep -// specific monsters out of certain areas -// -// ------------------------------------------------------------------------------- -class CFuncMonsterClip : public CFuncWall -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) {} // Clear out func_wall's use function -}; - -LINK_ENTITY_TO_CLASS( func_monsterclip, CFuncMonsterClip ); - -void CFuncMonsterClip::Spawn( void ) -{ - CFuncWall::Spawn(); - if ( CVAR_GET_FLOAT("showtriggers") == 0 ) - pev->effects = EF_NODRAW; - pev->flags |= FL_MONSTERCLIP; -} - - -// =================== FUNC_ROTATING ============================================== -class CFuncRotating : public CBaseEntity -{ -public: - // basic functions - void Spawn( void ); - void Precache( void ); - void EXPORT SpinUp ( void ); - void EXPORT SpinDown ( void ); - void KeyValue( KeyValueData* pkvd); - void EXPORT HurtTouch ( CBaseEntity *pOther ); - void EXPORT RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT Rotate( void ); - void RampPitchVol (int fUp ); - void Blocked( CBaseEntity *pOther ); - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - float m_flFanFriction; - float m_flAttenuation; - float m_flVolume; - float m_pitch; - int m_sounds; -}; - -TYPEDESCRIPTION CFuncRotating::m_SaveData[] = -{ - DEFINE_FIELD( CFuncRotating, m_flFanFriction, FIELD_FLOAT ), - DEFINE_FIELD( CFuncRotating, m_flAttenuation, FIELD_FLOAT ), - DEFINE_FIELD( CFuncRotating, m_flVolume, FIELD_FLOAT ), - DEFINE_FIELD( CFuncRotating, m_pitch, FIELD_FLOAT ), - DEFINE_FIELD( CFuncRotating, m_sounds, FIELD_INTEGER ) -}; - -IMPLEMENT_SAVERESTORE( CFuncRotating, CBaseEntity ); - - -LINK_ENTITY_TO_CLASS( func_rotating, CFuncRotating ); - -void CFuncRotating :: KeyValue( KeyValueData* pkvd) -{ - if (FStrEq(pkvd->szKeyName, "fanfriction")) - { - m_flFanFriction = atof(pkvd->szValue)/100; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "Volume")) - { - m_flVolume = atof(pkvd->szValue)/10.0; - - if (m_flVolume > 1.0) - m_flVolume = 1.0; - if (m_flVolume < 0.0) - m_flVolume = 0.0; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spawnorigin")) - { - Vector tmp; - UTIL_StringToVector( (float *)tmp, pkvd->szValue ); - if ( tmp != g_vecZero ) - pev->origin = tmp; - } - else if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -/*QUAKED func_rotating (0 .5 .8) ? START_ON REVERSE X_AXIS Y_AXIS -You need to have an origin brush as part of this entity. The -center of that brush will be -the point around which it is rotated. It will rotate around the Z -axis by default. You can -check either the X_AXIS or Y_AXIS box to change that. - -"speed" determines how fast it moves; default value is 100. -"dmg" damage to inflict when blocked (2 default) - -REVERSE will cause the it to rotate in the opposite direction. -*/ - - -void CFuncRotating :: Spawn( ) -{ - // set final pitch. Must not be PITCH_NORM, since we - // plan on pitch shifting later. - - m_pitch = PITCH_NORM - 1; - - // maintain compatibility with previous maps - if (m_flVolume == 0.0) - m_flVolume = 1.0; - - // if the designer didn't set a sound attenuation, default to one. - m_flAttenuation = ATTN_NORM; - - if ( FBitSet ( pev->spawnflags, SF_BRUSH_ROTATE_SMALLRADIUS) ) - { - m_flAttenuation = ATTN_IDLE; - } - else if ( FBitSet ( pev->spawnflags, SF_BRUSH_ROTATE_MEDIUMRADIUS) ) - { - m_flAttenuation = ATTN_STATIC; - } - else if ( FBitSet ( pev->spawnflags, SF_BRUSH_ROTATE_LARGERADIUS) ) - { - m_flAttenuation = ATTN_NORM; - } - - // prevent divide by zero if level designer forgets friction! - if ( m_flFanFriction == 0 ) - { - m_flFanFriction = 1; - } - - if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_Z_AXIS) ) - pev->movedir = Vector(0,0,1); - else if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_X_AXIS) ) - pev->movedir = Vector(1,0,0); - else - pev->movedir = Vector(0,1,0); // y-axis - - // check for reverse rotation - if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_BACKWARDS) ) - pev->movedir = pev->movedir * -1; - - // some rotating objects like fake volumetric lights will not be solid. - if ( FBitSet(pev->spawnflags, SF_ROTATING_NOT_SOLID) ) - { - pev->solid = SOLID_NOT; - pev->skin = CONTENTS_EMPTY; - pev->movetype = MOVETYPE_PUSH; - } - else - { - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - } - - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - SetUse( &CFuncRotating::RotatingUse ); - // did level designer forget to assign speed? - if (pev->speed <= 0) - pev->speed = 0; - - // Removed this per level designers request. -- JAY - // if (pev->dmg == 0) - // pev->dmg = 2; - - // instant-use brush? - if ( FBitSet( pev->spawnflags, SF_BRUSH_ROTATE_INSTANT) ) - { - SetThink( &CFuncRotating::SUB_CallUseToggle ); - pev->nextthink = pev->ltime + 1.5; // leave a magic delay for client to start up - } - // can this brush inflict pain? - if ( FBitSet (pev->spawnflags, SF_BRUSH_HURT) ) - { - SetTouch( &CFuncRotating::HurtTouch ); - } - - Precache( ); -} - - -void CFuncRotating :: Precache( void ) -{ - char* szSoundFile = (char*) STRING(pev->message); - - // set up fan sounds - - if (!FStringNull( pev->message ) && strlen( szSoundFile ) > 0) - { - // if a path is set for a wave, use it - - PRECACHE_SOUND(szSoundFile); - - pev->noiseRunning = ALLOC_STRING(szSoundFile); - } else - { - // otherwise use preset sound - switch (m_sounds) - { - case 1: - PRECACHE_SOUND ("fans/fan1.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan1.wav"); - break; - case 2: - PRECACHE_SOUND ("fans/fan2.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan2.wav"); - break; - case 3: - PRECACHE_SOUND ("fans/fan3.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan3.wav"); - break; - case 4: - PRECACHE_SOUND ("fans/fan4.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan4.wav"); - break; - case 5: - PRECACHE_SOUND ("fans/fan5.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan5.wav"); - break; - - case 0: - default: - if (!FStringNull( pev->message ) && strlen( szSoundFile ) > 0) - { - PRECACHE_SOUND(szSoundFile); - - pev->noiseRunning = ALLOC_STRING(szSoundFile); - break; - } else - { - pev->noiseRunning = ALLOC_STRING("common/null.wav"); - break; - } - } - } - - if (pev->avelocity != g_vecZero ) - { - // if fan was spinning, and we went through transition or save/restore, - // make sure we restart the sound. 1.5 sec delay is magic number. KDB - - SetThink ( &CFuncRotating::SpinUp ); - pev->nextthink = pev->ltime + 1.5; - } -} - - - -// -// Touch - will hurt others based on how fast the brush is spinning -// -void CFuncRotating :: HurtTouch ( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - // we can't hurt this thing, so we're not concerned with it - if ( !pevOther->takedamage ) - return; - - // calculate damage based on rotation speed - pev->dmg = pev->avelocity.Length() / 10; - - pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH); - - pevOther->velocity = (pevOther->origin - VecBModelOrigin(pev) ).Normalize() * pev->dmg; -} - -// -// RampPitchVol - ramp pitch and volume up to final values, based on difference -// between how fast we're going vs how fast we plan to go -// -#define FANPITCHMIN 30 -#define FANPITCHMAX 100 - -void CFuncRotating :: RampPitchVol (int fUp) -{ - - Vector vecAVel = pev->avelocity; - vec_t vecCur; - vec_t vecFinal; - float fpct; - float fvol; - float fpitch; - int pitch; - - // get current angular velocity - - vecCur = fabs(vecAVel.x != 0 ? vecAVel.x : (vecAVel.y != 0 ? vecAVel.y : vecAVel.z)); - - // get target angular velocity - - vecFinal = (pev->movedir.x != 0 ? pev->movedir.x : (pev->movedir.y != 0 ? pev->movedir.y : pev->movedir.z)); - vecFinal *= pev->speed; - vecFinal = fabs(vecFinal); - - // calc volume and pitch as % of final vol and pitch - - fpct = vecCur / vecFinal; -// if (fUp) -// fvol = m_flVolume * (0.5 + fpct/2.0); // spinup volume ramps up from 50% max vol -// else - fvol = m_flVolume * fpct; // slowdown volume ramps down to 0 - - fpitch = FANPITCHMIN + (FANPITCHMAX - FANPITCHMIN) * fpct; - - pitch = (int) fpitch; - if (pitch == PITCH_NORM) - pitch = PITCH_NORM-1; - - // change the fan's vol and pitch - - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), - fvol, m_flAttenuation, SND_CHANGE_PITCH | SND_CHANGE_VOL, pitch); - -} - -// -// SpinUp - accelerates a non-moving func_rotating up to it's speed -// -void CFuncRotating :: SpinUp( void ) -{ - Vector vecAVel;//rotational velocity - - pev->nextthink = pev->ltime + 0.1; - pev->avelocity = pev->avelocity + ( pev->movedir * ( pev->speed * m_flFanFriction ) ); - - vecAVel = pev->avelocity;// cache entity's rotational velocity - - // if we've met or exceeded target speed, set target speed and stop thinking - if ( fabs(vecAVel.x) >= fabs(pev->movedir.x * pev->speed) && - fabs(vecAVel.y) >= fabs(pev->movedir.y * pev->speed) && - fabs(vecAVel.z) >= fabs(pev->movedir.z * pev->speed) ) - { - pev->avelocity = pev->movedir * pev->speed;// set speed in case we overshot - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), - m_flVolume, m_flAttenuation, SND_CHANGE_PITCH | SND_CHANGE_VOL, FANPITCHMAX); - - SetThink( &CFuncRotating::Rotate ); - Rotate(); - } - else - { - RampPitchVol(TRUE); - } -} - -// -// SpinDown - decelerates a moving func_rotating to a standstill. -// -void CFuncRotating :: SpinDown( void ) -{ - Vector vecAVel;//rotational velocity - vec_t vecdir; - - pev->nextthink = pev->ltime + 0.1; - - pev->avelocity = pev->avelocity - ( pev->movedir * ( pev->speed * m_flFanFriction ) );//spin down slower than spinup - - vecAVel = pev->avelocity;// cache entity's rotational velocity - - if (pev->movedir.x != 0) - vecdir = pev->movedir.x; - else if (pev->movedir.y != 0) - vecdir = pev->movedir.y; - else - vecdir = pev->movedir.z; - - // if we've met or exceeded target speed, set target speed and stop thinking - // (note: must check for movedir > 0 or < 0) - if (((vecdir > 0) && (vecAVel.x <= 0 && vecAVel.y <= 0 && vecAVel.z <= 0)) || - ((vecdir < 0) && (vecAVel.x >= 0 && vecAVel.y >= 0 && vecAVel.z >= 0))) - { - pev->avelocity = g_vecZero;// set speed in case we overshot - - // stop sound, we're done - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning /* Stop */), - 0, 0, SND_STOP, m_pitch); - - SetThink( &CFuncRotating::Rotate ); - Rotate(); - } - else - { - RampPitchVol(FALSE); - } -} - -void CFuncRotating :: Rotate( void ) -{ - pev->nextthink = pev->ltime + 10; -} - -//========================================================= -// Rotating Use - when a rotating brush is triggered -//========================================================= -void CFuncRotating :: RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // is this a brush that should accelerate and decelerate when turned on/off (fan)? - if ( FBitSet ( pev->spawnflags, SF_BRUSH_ACCDCC ) ) - { - // fan is spinning, so stop it. - if ( pev->avelocity != g_vecZero ) - { - SetThink ( &CFuncRotating::SpinDown ); - //EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStop), - // m_flVolume, m_flAttenuation, 0, m_pitch); - - pev->nextthink = pev->ltime + 0.1; - } - else// fan is not moving, so start it - { - SetThink ( &CFuncRotating::SpinUp ); - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), - 0.01, m_flAttenuation, 0, FANPITCHMIN); - - pev->nextthink = pev->ltime + 0.1; - } - } - else if ( !FBitSet ( pev->spawnflags, SF_BRUSH_ACCDCC ) )//this is a normal start/stop brush. - { - if ( pev->avelocity != g_vecZero ) - { - // play stopping sound here - SetThink ( &CFuncRotating::SpinDown ); - - // EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStop), - // m_flVolume, m_flAttenuation, 0, m_pitch); - - pev->nextthink = pev->ltime + 0.1; - // pev->avelocity = g_vecZero; - } - else - { - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), - m_flVolume, m_flAttenuation, 0, FANPITCHMAX); - pev->avelocity = pev->movedir * pev->speed; - - SetThink( &CFuncRotating::Rotate ); - Rotate(); - } - } -} - - -// -// RotatingBlocked - An entity has blocked the brush -// -void CFuncRotating :: Blocked( CBaseEntity *pOther ) - -{ - pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH); -} - - - - - - -//#endif - - -class CPendulum : public CBaseEntity -{ -public: - void Spawn ( void ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT Swing( void ); - void EXPORT PendulumUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT Stop( void ); - void Touch( CBaseEntity *pOther ); - void EXPORT RopeTouch ( CBaseEntity *pOther );// this touch func makes the pendulum a rope - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - void Blocked( CBaseEntity *pOther ); - - static TYPEDESCRIPTION m_SaveData[]; - - float m_accel; // Acceleration - float m_distance; // - float m_time; - float m_damp; - float m_maxSpeed; - float m_dampSpeed; - vec3_t m_center; - vec3_t m_start; -}; - -LINK_ENTITY_TO_CLASS( func_pendulum, CPendulum ); - -TYPEDESCRIPTION CPendulum::m_SaveData[] = -{ - DEFINE_FIELD( CPendulum, m_accel, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_distance, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_time, FIELD_TIME ), - DEFINE_FIELD( CPendulum, m_damp, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_maxSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_dampSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_center, FIELD_VECTOR ), - DEFINE_FIELD( CPendulum, m_start, FIELD_VECTOR ), -}; - -IMPLEMENT_SAVERESTORE( CPendulum, CBaseEntity ); - - - -void CPendulum :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "distance")) - { - m_distance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "damp")) - { - m_damp = atof(pkvd->szValue) * 0.001; - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -void CPendulum :: Spawn( void ) -{ - // set the axis of rotation - CBaseToggle :: AxisDir( pev ); - - if ( FBitSet (pev->spawnflags, SF_DOOR_PASSABLE) ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - if ( m_distance == 0 ) - return; - - if (pev->speed == 0) - pev->speed = 100; - - m_accel = (pev->speed * pev->speed) / (2 * fabs(m_distance)); // Calculate constant acceleration from speed and distance - m_maxSpeed = pev->speed; - m_start = pev->angles; - m_center = pev->angles + (m_distance * 0.5) * pev->movedir; - - if ( FBitSet( pev->spawnflags, SF_BRUSH_ROTATE_INSTANT) ) - { - SetThink( &CPendulum::SUB_CallUseToggle ); - pev->nextthink = gpGlobals->time + 0.1; - } - pev->speed = 0; - SetUse( &CPendulum::PendulumUse ); - - if ( FBitSet( pev->spawnflags, SF_PENDULUM_SWING ) ) - { - SetTouch ( &CPendulum::RopeTouch ); - } -} - - -void CPendulum :: PendulumUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->speed ) // Pendulum is moving, stop it and auto-return if necessary - { - if ( FBitSet( pev->spawnflags, SF_PENDULUM_AUTO_RETURN ) ) - { - float delta; - - delta = CBaseToggle :: AxisDelta( pev->spawnflags, pev->angles, m_start ); - - pev->avelocity = m_maxSpeed * pev->movedir; - pev->nextthink = pev->ltime + (delta / m_maxSpeed); - SetThink( &CPendulum::Stop ); - } - else - { - pev->speed = 0; // Dead stop - SetThink( NULL ); - pev->avelocity = g_vecZero; - } - } - else - { - pev->nextthink = pev->ltime + 0.1; // Start the pendulum moving - m_time = gpGlobals->time; // Save time to calculate dt - SetThink( &CPendulum::Swing ); - m_dampSpeed = m_maxSpeed; - } -} - - -void CPendulum :: Stop( void ) -{ - pev->angles = m_start; - pev->speed = 0; - SetThink( NULL ); - pev->avelocity = g_vecZero; -} - - -void CPendulum::Blocked( CBaseEntity *pOther ) -{ - m_time = gpGlobals->time; -} - - -void CPendulum :: Swing( void ) -{ - float delta, dt; - - delta = CBaseToggle :: AxisDelta( pev->spawnflags, pev->angles, m_center ); - dt = gpGlobals->time - m_time; // How much time has passed? - m_time = gpGlobals->time; // Remember the last time called - - if ( delta > 0 && m_accel > 0 ) - pev->speed -= m_accel * dt; // Integrate velocity - else - pev->speed += m_accel * dt; - - if ( pev->speed > m_maxSpeed ) - pev->speed = m_maxSpeed; - else if ( pev->speed < -m_maxSpeed ) - pev->speed = -m_maxSpeed; - // scale the destdelta vector by the time spent traveling to get velocity - pev->avelocity = pev->speed * pev->movedir; - - // Call this again - pev->nextthink = pev->ltime + 0.1; - - if ( m_damp ) - { - m_dampSpeed -= m_damp * m_dampSpeed * dt; - if ( m_dampSpeed < 30.0 ) - { - pev->angles = m_center; - pev->speed = 0; - SetThink( NULL ); - pev->avelocity = g_vecZero; - } - else if ( pev->speed > m_dampSpeed ) - pev->speed = m_dampSpeed; - else if ( pev->speed < -m_dampSpeed ) - pev->speed = -m_dampSpeed; - - } -} - - -void CPendulum :: Touch ( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - if ( pev->dmg <= 0 ) - return; - - // we can't hurt this thing, so we're not concerned with it - if ( !pevOther->takedamage ) - return; - - // calculate damage based on rotation speed - float damage = pev->dmg * pev->speed * 0.01; - - if ( damage < 0 ) - damage = -damage; - - pOther->TakeDamage( pev, pev, damage, DMG_CRUSH ); - - pevOther->velocity = (pevOther->origin - VecBModelOrigin(pev) ).Normalize() * damage; -} - -void CPendulum :: RopeTouch ( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - if ( !pOther->IsPlayer() ) - {// not a player! - ALERT ( at_console, "Not a client\n" ); - return; - } - - if ( ENT(pevOther) == pev->enemy ) - {// this player already on the rope. - return; - } - - pev->enemy = pOther->edict(); - pevOther->velocity = g_vecZero; - pevOther->movetype = MOVETYPE_NONE; -} - - diff --git a/dmc/dlls/buttons.cpp b/dmc/dlls/buttons.cpp deleted file mode 100644 index 5ea927d..0000000 --- a/dmc/dlls/buttons.cpp +++ /dev/null @@ -1,1279 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== buttons.cpp ======================================================== - - button-related code - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "doors.h" - -#if !defined ( _WIN32 ) -#include // memset()))) -#endif - -#define SF_BUTTON_DONTMOVE 1 -#define SF_ROTBUTTON_NOTSOLID 1 -#define SF_BUTTON_TOGGLE 32 // button stays pushed until reactivated -#define SF_BUTTON_SPARK_IF_OFF 64 // button sparks in OFF state -#define SF_BUTTON_TOUCH_ONLY 256 // button only fires as a result of USE key. - -#define SF_GLOBAL_SET 1 // Set global state to initial state on spawn - -class CEnvGlobal : public CPointEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - string_t m_globalstate; - int m_triggermode; - int m_initialstate; -}; - -TYPEDESCRIPTION CEnvGlobal::m_SaveData[] = -{ - DEFINE_FIELD( CEnvGlobal, m_globalstate, FIELD_STRING ), - DEFINE_FIELD( CEnvGlobal, m_triggermode, FIELD_INTEGER ), - DEFINE_FIELD( CEnvGlobal, m_initialstate, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CEnvGlobal, CBaseEntity ); - -LINK_ENTITY_TO_CLASS( env_global, CEnvGlobal ); - -void CEnvGlobal::KeyValue( KeyValueData *pkvd ) -{ - pkvd->fHandled = TRUE; - - if ( FStrEq(pkvd->szKeyName, "globalstate") ) // State name - m_globalstate = ALLOC_STRING( pkvd->szValue ); - else if ( FStrEq(pkvd->szKeyName, "triggermode") ) - m_triggermode = atoi( pkvd->szValue ); - else if ( FStrEq(pkvd->szKeyName, "initialstate") ) - m_initialstate = atoi( pkvd->szValue ); - else - CPointEntity::KeyValue( pkvd ); -} - -void CEnvGlobal::Spawn( void ) -{ - if ( !m_globalstate ) - { - REMOVE_ENTITY( ENT(pev) ); - return; - } - if ( FBitSet( pev->spawnflags, SF_GLOBAL_SET ) ) - { - if ( !gGlobalState.EntityInTable( m_globalstate ) ) - gGlobalState.EntityAdd( m_globalstate, gpGlobals->mapname, (GLOBALESTATE)m_initialstate ); - } -} - - -void CEnvGlobal::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - GLOBALESTATE oldState = gGlobalState.EntityGetState( m_globalstate ); - GLOBALESTATE newState; - - switch( m_triggermode ) - { - case 0: - newState = GLOBAL_OFF; - break; - - case 1: - newState = GLOBAL_ON; - break; - - case 2: - newState = GLOBAL_DEAD; - break; - - default: - case 3: - if ( oldState == GLOBAL_ON ) - newState = GLOBAL_OFF; - else if ( oldState == GLOBAL_OFF ) - newState = GLOBAL_ON; - else - newState = oldState; - } - - if ( gGlobalState.EntityInTable( m_globalstate ) ) - gGlobalState.EntitySetState( m_globalstate, newState ); - else - gGlobalState.EntityAdd( m_globalstate, gpGlobals->mapname, newState ); -} - - - -TYPEDESCRIPTION CMultiSource::m_SaveData[] = -{ - //!!!BUGBUG FIX - DEFINE_ARRAY( CMultiSource, m_rgEntities, FIELD_EHANDLE, MS_MAX_TARGETS ), - DEFINE_ARRAY( CMultiSource, m_rgTriggered, FIELD_INTEGER, MS_MAX_TARGETS ), - DEFINE_FIELD( CMultiSource, m_iTotal, FIELD_INTEGER ), - DEFINE_FIELD( CMultiSource, m_globalstate, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CMultiSource, CBaseEntity ); - -LINK_ENTITY_TO_CLASS( multisource, CMultiSource ); -// -// Cache user-entity-field values until spawn is called. -// - -void CMultiSource::KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "style") || - FStrEq(pkvd->szKeyName, "height") || - FStrEq(pkvd->szKeyName, "killtarget") || - FStrEq(pkvd->szKeyName, "value1") || - FStrEq(pkvd->szKeyName, "value2") || - FStrEq(pkvd->szKeyName, "value3")) - pkvd->fHandled = TRUE; - else if ( FStrEq(pkvd->szKeyName, "globalstate") ) - { - m_globalstate = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -#define SF_MULTI_INIT 1 - -void CMultiSource::Spawn() -{ - // set up think for later registration - - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->nextthink = gpGlobals->time + 0.1; - pev->spawnflags |= SF_MULTI_INIT; // Until it's initialized - SetThink(&CMultiSource::Register); -} - -void CMultiSource::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int i = 0; - - // Find the entity in our list - while (i < m_iTotal) - if ( m_rgEntities[i++] == pCaller ) - break; - - // if we didn't find it, report error and leave - if (i > m_iTotal) - { - ALERT(at_console, "MultiSrc:Used by non member %s.\n", STRING(pCaller->pev->classname)); - return; - } - - // CONSIDER: a Use input to the multisource always toggles. Could check useType for ON/OFF/TOGGLE - - m_rgTriggered[i-1] ^= 1; - - // - if ( IsTriggered( pActivator ) ) - { - ALERT( at_aiconsole, "Multisource %s enabled (%d inputs)\n", STRING(pev->targetname), m_iTotal ); - USE_TYPE useType = USE_TOGGLE; - if ( m_globalstate ) - useType = USE_ON; - SUB_UseTargets( NULL, useType, 0 ); - } -} - - -BOOL CMultiSource::IsTriggered( CBaseEntity * ) -{ - // Is everything triggered? - int i = 0; - - // Still initializing? - if ( pev->spawnflags & SF_MULTI_INIT ) - return 0; - - while (i < m_iTotal) - { - if (m_rgTriggered[i] == 0) - break; - i++; - } - - if (i == m_iTotal) - { - if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON ) - return 1; - } - - return 0; -} - -void CMultiSource::Register(void) -{ - edict_t *pentTarget = NULL; - - m_iTotal = 0; - memset( m_rgEntities, 0, MS_MAX_TARGETS * sizeof(EHANDLE) ); - - SetThink(&CMultiSource::SUB_DoNothing); - - // search for all entities which target this multisource (pev->targetname) - - pentTarget = FIND_ENTITY_BY_STRING(NULL, "target", STRING(pev->targetname)); - - while (!FNullEnt(pentTarget) && (m_iTotal < MS_MAX_TARGETS)) - { - CBaseEntity *pTarget = CBaseEntity::Instance(pentTarget); - if ( pTarget ) - m_rgEntities[m_iTotal++] = pTarget; - - pentTarget = FIND_ENTITY_BY_STRING( pentTarget, "target", STRING(pev->targetname)); - } - - pentTarget = FIND_ENTITY_BY_STRING(NULL, "classname", "multi_manager"); - while (!FNullEnt(pentTarget) && (m_iTotal < MS_MAX_TARGETS)) - { - CBaseEntity *pTarget = CBaseEntity::Instance(pentTarget); - if ( pTarget && pTarget->HasTarget(pev->targetname) ) - m_rgEntities[m_iTotal++] = pTarget; - - pentTarget = FIND_ENTITY_BY_STRING( pentTarget, "classname", "multi_manager" ); - } - - pev->spawnflags &= ~SF_MULTI_INIT; -} - -// CBaseButton -TYPEDESCRIPTION CBaseButton::m_SaveData[] = -{ - DEFINE_FIELD( CBaseButton, m_fStayPushed, FIELD_BOOLEAN ), - DEFINE_FIELD( CBaseButton, m_fRotating, FIELD_BOOLEAN ), - - DEFINE_FIELD( CBaseButton, m_sounds, FIELD_INTEGER ), - DEFINE_FIELD( CBaseButton, m_bLockedSound, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseButton, m_bLockedSentence, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseButton, m_bUnlockedSound, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseButton, m_bUnlockedSentence, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseButton, m_strChangeTarget, FIELD_STRING ), -// DEFINE_FIELD( CBaseButton, m_ls, FIELD_??? ), // This is restored in Precache() -}; - - -IMPLEMENT_SAVERESTORE( CBaseButton, CBaseToggle ); - -void CBaseButton::Precache( void ) -{ - char *pszSound; - - if ( FBitSet ( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ) )// this button should spark in OFF state - { - PRECACHE_SOUND ("buttons/spark1.wav"); - PRECACHE_SOUND ("buttons/spark2.wav"); - PRECACHE_SOUND ("buttons/spark3.wav"); - PRECACHE_SOUND ("buttons/spark4.wav"); - PRECACHE_SOUND ("buttons/spark5.wav"); - PRECACHE_SOUND ("buttons/spark6.wav"); - } - - // get door button sounds, for doors which require buttons to open - - if (m_bLockedSound) - { - pszSound = ButtonSound( (int)m_bLockedSound ); - PRECACHE_SOUND(pszSound); - m_ls.sLockedSound = ALLOC_STRING(pszSound); - } - - if (m_bUnlockedSound) - { - pszSound = ButtonSound( (int)m_bUnlockedSound ); - PRECACHE_SOUND(pszSound); - m_ls.sUnlockedSound = ALLOC_STRING(pszSound); - } - - // get sentence group names, for doors which are directly 'touched' to open - - switch (m_bLockedSentence) - { - case 1: m_ls.sLockedSentence = MAKE_STRING("NA"); break; // access denied - case 2: m_ls.sLockedSentence = MAKE_STRING("ND"); break; // security lockout - case 3: m_ls.sLockedSentence = MAKE_STRING("NF"); break; // blast door - case 4: m_ls.sLockedSentence = MAKE_STRING("NFIRE"); break; // fire door - case 5: m_ls.sLockedSentence = MAKE_STRING("NCHEM"); break; // chemical door - case 6: m_ls.sLockedSentence = MAKE_STRING("NRAD"); break; // radiation door - case 7: m_ls.sLockedSentence = MAKE_STRING("NCON"); break; // gen containment - case 8: m_ls.sLockedSentence = MAKE_STRING("NH"); break; // maintenance door - case 9: m_ls.sLockedSentence = MAKE_STRING("NG"); break; // broken door - - default: m_ls.sLockedSentence = 0; break; - } - - switch (m_bUnlockedSentence) - { - case 1: m_ls.sUnlockedSentence = MAKE_STRING("EA"); break; // access granted - case 2: m_ls.sUnlockedSentence = MAKE_STRING("ED"); break; // security door - case 3: m_ls.sUnlockedSentence = MAKE_STRING("EF"); break; // blast door - case 4: m_ls.sUnlockedSentence = MAKE_STRING("EFIRE"); break; // fire door - case 5: m_ls.sUnlockedSentence = MAKE_STRING("ECHEM"); break; // chemical door - case 6: m_ls.sUnlockedSentence = MAKE_STRING("ERAD"); break; // radiation door - case 7: m_ls.sUnlockedSentence = MAKE_STRING("ECON"); break; // gen containment - case 8: m_ls.sUnlockedSentence = MAKE_STRING("EH"); break; // maintenance door - - default: m_ls.sUnlockedSentence = 0; break; - } -} - -// -// Cache user-entity-field values until spawn is called. -// - -void CBaseButton::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "changetarget")) - { - m_strChangeTarget = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "locked_sound")) - { - m_bLockedSound = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "locked_sentence")) - { - m_bLockedSentence = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "unlocked_sound")) - { - m_bUnlockedSound = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "unlocked_sentence")) - { - m_bUnlockedSentence = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -// -// ButtonShot -// -int CBaseButton::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - BUTTON_CODE code = ButtonResponseToTouch(); - - if ( code == BUTTON_NOTHING ) - return 0; - // Temporarily disable the touch function, until movement is finished. - SetTouch( NULL ); - - m_hActivator = CBaseEntity::Instance( pevAttacker ); - if ( m_hActivator == NULL ) - return 0; - - if ( code == BUTTON_RETURN ) - { - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - - // Toggle buttons fire when they get back to their "home" position - if ( !(pev->spawnflags & SF_BUTTON_TOGGLE) ) - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); - ButtonReturn(); - } - else // code == BUTTON_ACTIVATE - ButtonActivate( ); - - return 0; -} - -/*QUAKED func_button (0 .5 .8) ? -When a button is touched, it moves some distance in the direction of it's angle, -triggers all of it's targets, waits some time, then returns to it's original position -where it can be triggered again. - -"angle" determines the opening direction -"target" all entities with a matching targetname will be used -"speed" override the default 40 speed -"wait" override the default 1 second wait (-1 = never return) -"lip" override the default 4 pixel lip remaining at end of move -"health" if set, the button must be killed instead of touched -"sounds" -0) steam metal -1) wooden clunk -2) metallic click -3) in-out -*/ -LINK_ENTITY_TO_CLASS( func_button, CBaseButton ); - - -void CBaseButton::Spawn( ) -{ - char *pszSound; - - //---------------------------------------------------- - //determine sounds for buttons - //a sound of 0 should not make a sound - //---------------------------------------------------- - pszSound = ButtonSound( m_sounds ); - PRECACHE_SOUND(pszSound); - pev->noise = ALLOC_STRING(pszSound); - - Precache(); - - if ( FBitSet ( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ) )// this button should spark in OFF state - { - SetThink ( &CBaseButton::ButtonSpark ); - pev->nextthink = gpGlobals->time + 0.5;// no hurry, make sure everything else spawns - } - - SetMovedir(pev); - - pev->movetype = MOVETYPE_PUSH; - pev->solid = SOLID_BSP; - SET_MODEL(ENT(pev), STRING(pev->model)); - - if (pev->speed == 0) - pev->speed = 40; - - if (pev->health > 0) - { - pev->takedamage = DAMAGE_YES; - } - - if (m_flWait == 0) - m_flWait = 1; - if (m_flLip == 0) - m_flLip = 4; - - m_toggle_state = TS_AT_BOTTOM; - m_vecPosition1 = pev->origin; - // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big - m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs( pev->movedir.x * (pev->size.x-2) ) + fabs( pev->movedir.y * (pev->size.y-2) ) + fabs( pev->movedir.z * (pev->size.z-2) ) - m_flLip)); - - - // Is this a non-moving button? - if ( ((m_vecPosition2 - m_vecPosition1).Length() < 1) || (pev->spawnflags & SF_BUTTON_DONTMOVE) ) - m_vecPosition2 = m_vecPosition1; - - m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE); - m_fRotating = FALSE; - - // if the button is flagged for USE button activation only, take away it's touch function and add a use function - - if ( FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) ) // touchable button - { - SetTouch( &CBaseButton::ButtonTouch ); - } - else - { - SetTouch ( NULL ); - SetUse ( &CBaseButton::ButtonUse ); - } -} - - -// Button sound table. -// Also used by CBaseDoor to get 'touched' door lock/unlock sounds - -char *ButtonSound( int sound ) -{ - char *pszSound; - - switch ( sound ) - { - case 0: pszSound = "common/null.wav"; break; - case 1: pszSound = "buttons/button1.wav"; break; - case 2: pszSound = "buttons/button2.wav"; break; - case 3: pszSound = "buttons/button3.wav"; break; - case 4: pszSound = "buttons/button4.wav"; break; - case 5: pszSound = "buttons/button5.wav"; break; - case 6: pszSound = "buttons/button6.wav"; break; - case 7: pszSound = "buttons/button7.wav"; break; - case 8: pszSound = "buttons/button8.wav"; break; - case 9: pszSound = "buttons/button9.wav"; break; - case 10: pszSound = "buttons/button10.wav"; break; - case 11: pszSound = "buttons/button11.wav"; break; - case 12: pszSound = "buttons/latchlocked1.wav"; break; - case 13: pszSound = "buttons/latchunlocked1.wav"; break; - case 14: pszSound = "buttons/lightswitch2.wav";break; - -// next 6 slots reserved for any additional sliding button sounds we may add - - case 21: pszSound = "buttons/lever1.wav"; break; - case 22: pszSound = "buttons/lever2.wav"; break; - case 23: pszSound = "buttons/lever3.wav"; break; - case 24: pszSound = "buttons/lever4.wav"; break; - case 25: pszSound = "buttons/lever5.wav"; break; - - default:pszSound = "buttons/button9.wav"; break; - } - - return pszSound; -} - -// -// Makes flagged buttons spark when turned off -// - -void DoSpark(entvars_t *pev, const Vector &location ) -{ - Vector tmp = location + pev->size * 0.5; - UTIL_Sparks( tmp ); - - float flVolume = RANDOM_FLOAT ( 0.25 , 0.75 ) * 0.4;//random volume range - switch ( (int)(RANDOM_FLOAT(0,1) * 6) ) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark1.wav", flVolume, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark2.wav", flVolume, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark3.wav", flVolume, ATTN_NORM); break; - case 3: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark4.wav", flVolume, ATTN_NORM); break; - case 4: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM); break; - case 5: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM); break; - } -} - -void CBaseButton::ButtonSpark ( void ) -{ - SetThink ( &CBaseButton::ButtonSpark ); - pev->nextthink = gpGlobals->time + ( 0.1 + RANDOM_FLOAT ( 0, 1.5 ) );// spark again at random interval - - DoSpark( pev, pev->mins ); -} - - -// -// Button's Use function -// -void CBaseButton::ButtonUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // Ignore touches if button is moving, or pushed-in and waiting to auto-come-out. - // UNDONE: Should this use ButtonResponseToTouch() too? - if (m_toggle_state == TS_GOING_UP || m_toggle_state == TS_GOING_DOWN ) - return; - - m_hActivator = pActivator; - if ( m_toggle_state == TS_AT_TOP) - { - if (!m_fStayPushed && FBitSet(pev->spawnflags, SF_BUTTON_TOGGLE)) - { - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - - //SUB_UseTargets( m_eoActivator ); - ButtonReturn(); - } - } - else - ButtonActivate( ); -} - - -CBaseButton::BUTTON_CODE CBaseButton::ButtonResponseToTouch( void ) -{ - // Ignore touches if button is moving, or pushed-in and waiting to auto-come-out. - if (m_toggle_state == TS_GOING_UP || - m_toggle_state == TS_GOING_DOWN || - (m_toggle_state == TS_AT_TOP && !m_fStayPushed && !FBitSet(pev->spawnflags, SF_BUTTON_TOGGLE) ) ) - return BUTTON_NOTHING; - - if (m_toggle_state == TS_AT_TOP) - { - if((FBitSet(pev->spawnflags, SF_BUTTON_TOGGLE) ) && !m_fStayPushed) - { - return BUTTON_RETURN; - } - } - else - return BUTTON_ACTIVATE; - - return BUTTON_NOTHING; -} - - -// -// Touching a button simply "activates" it. -// -void CBaseButton:: ButtonTouch( CBaseEntity *pOther ) -{ - // Ignore touches by anything but players - if (!FClassnameIs(pOther->pev, "player")) - return; - - m_hActivator = pOther; - - BUTTON_CODE code = ButtonResponseToTouch(); - - if ( code == BUTTON_NOTHING ) - return; - - if (!UTIL_IsMasterTriggered(m_sMaster, pOther)) - { - // play button locked sound - PlayLockSounds(pev, &m_ls, TRUE, TRUE); - return; - } - - // Temporarily disable the touch function, until movement is finished. - SetTouch( NULL ); - - if ( code == BUTTON_RETURN ) - { - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); - ButtonReturn(); - } - else // code == BUTTON_ACTIVATE - ButtonActivate( ); -} - -// -// Starts the button moving "in/up". -// -void CBaseButton::ButtonActivate( ) -{ - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - - if (!UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) - { - // button is locked, play locked sound - PlayLockSounds(pev, &m_ls, TRUE, TRUE); - return; - } - else - { - // button is unlocked, play unlocked sound - PlayLockSounds(pev, &m_ls, FALSE, TRUE); - } - - ASSERT(m_toggle_state == TS_AT_BOTTOM); - m_toggle_state = TS_GOING_UP; - - SetMoveDone( &CBaseButton::TriggerAndWait ); - if (!m_fRotating) - LinearMove( m_vecPosition2, pev->speed); - else - AngularMove( m_vecAngle2, pev->speed); -} - -// -// Button has reached the "in/up" position. Activate its "targets", and pause before "popping out". -// -void CBaseButton::TriggerAndWait( void ) -{ - ASSERT(m_toggle_state == TS_GOING_UP); - - if (!UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) - return; - - m_toggle_state = TS_AT_TOP; - - // If button automatically comes back out, start it moving out. - // Else re-instate touch method - if (m_fStayPushed || FBitSet ( pev->spawnflags, SF_BUTTON_TOGGLE ) ) - { - if ( !FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) ) // this button only works if USED, not touched! - { - // ALL buttons are now use only - SetTouch ( NULL ); - } - else - SetTouch( &CBaseButton::ButtonTouch ); - } - else - { - pev->nextthink = pev->ltime + m_flWait; - SetThink( &CBaseButton::ButtonReturn ); - } - - pev->frame = 1; // use alternate textures - - - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); -} - - -// -// Starts the button moving "out/down". -// -void CBaseButton::ButtonReturn( void ) -{ - ASSERT(m_toggle_state == TS_AT_TOP); - m_toggle_state = TS_GOING_DOWN; - - SetMoveDone( &CBaseButton::ButtonBackHome ); - if (!m_fRotating) - LinearMove( m_vecPosition1, pev->speed); - else - AngularMove( m_vecAngle1, pev->speed); - - pev->frame = 0; // use normal textures -} - - -// -// Button has returned to start state. Quiesce it. -// -void CBaseButton::ButtonBackHome( void ) -{ - ASSERT(m_toggle_state == TS_GOING_DOWN); - m_toggle_state = TS_AT_BOTTOM; - - if ( FBitSet(pev->spawnflags, SF_BUTTON_TOGGLE) ) - { - //EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); - } - - - if (!FStringNull(pev->target)) - { - edict_t* pentTarget = NULL; - for (;;) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target)); - - if (FNullEnt(pentTarget)) - break; - - if (!FClassnameIs(pentTarget, "multisource")) - continue; - CBaseEntity *pTarget = CBaseEntity::Instance( pentTarget ); - - if ( pTarget ) - pTarget->Use( m_hActivator, this, USE_TOGGLE, 0 ); - } - } - -// Re-instate touch method, movement cycle is complete. - if ( !FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) ) // this button only works if USED, not touched! - { - // All buttons are now use only - SetTouch ( NULL ); - } - else - SetTouch( &CBaseButton::ButtonTouch ); - -// reset think for a sparking button - if ( FBitSet ( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ) ) - { - SetThink ( &CBaseButton::ButtonSpark ); - pev->nextthink = gpGlobals->time + 0.5;// no hurry. - } -} - - - -// -// Rotating button (aka "lever") -// -class CRotButton : public CBaseButton -{ -public: - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( func_rot_button, CRotButton ); - -void CRotButton::Spawn( void ) -{ - char *pszSound; - //---------------------------------------------------- - //determine sounds for buttons - //a sound of 0 should not make a sound - //---------------------------------------------------- - pszSound = ButtonSound( m_sounds ); - PRECACHE_SOUND(pszSound); - pev->noise = ALLOC_STRING(pszSound); - - // set the axis of rotation - CBaseToggle::AxisDir( pev ); - - // check for clockwise rotation - if ( FBitSet (pev->spawnflags, SF_DOOR_ROTATE_BACKWARDS) ) - pev->movedir = pev->movedir * -1; - - pev->movetype = MOVETYPE_PUSH; - - if ( pev->spawnflags & SF_ROTBUTTON_NOTSOLID ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - - SET_MODEL(ENT(pev), STRING(pev->model)); - - if (pev->speed == 0) - pev->speed = 40; - - if (m_flWait == 0) - m_flWait = 1; - - if (pev->health > 0) - { - pev->takedamage = DAMAGE_YES; - } - - m_toggle_state = TS_AT_BOTTOM; - m_vecAngle1 = pev->angles; - m_vecAngle2 = pev->angles + pev->movedir * m_flMoveDistance; - ASSERTSZ(m_vecAngle1 != m_vecAngle2, "rotating button start/end positions are equal"); - - m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE); - m_fRotating = TRUE; - - // if the button is flagged for USE button activation only, take away it's touch function and add a use function - if ( !FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) ) - { - SetTouch ( NULL ); - SetUse ( &CRotButton::ButtonUse ); - } - else // touchable button - SetTouch( &CRotButton::ButtonTouch ); - - //SetTouch( ButtonTouch ); -} - - -// Make this button behave like a door (HACKHACK) -// This will disable use and make the button solid -// rotating buttons were made SOLID_NOT by default since their were some -// collision problems with them... -#define SF_MOMENTARY_DOOR 0x0001 - -class CMomentaryRotButton : public CBaseToggle -{ -public: - void Spawn ( void ); - void KeyValue( KeyValueData *pkvd ); - virtual int ObjectCaps( void ) - { - int flags = CBaseToggle :: ObjectCaps() & (~FCAP_ACROSS_TRANSITION); - if ( pev->spawnflags & SF_MOMENTARY_DOOR ) - return flags; - return flags | FCAP_CONTINUOUS_USE; - } - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT Off( void ); - void EXPORT Return( void ); - void UpdateSelf( float value ); - void UpdateSelfReturn( float value ); - void UpdateAllButtons( float value, int start ); - - void PlaySound( void ); - void UpdateTarget( float value ); - - static CMomentaryRotButton *Instance( edict_t *pent ) { return (CMomentaryRotButton *)GET_PRIVATE(pent);}; - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - int m_lastUsed; - int m_direction; - float m_returnSpeed; - vec3_t m_start; - vec3_t m_end; - int m_sounds; -}; -TYPEDESCRIPTION CMomentaryRotButton::m_SaveData[] = -{ - DEFINE_FIELD( CMomentaryRotButton, m_lastUsed, FIELD_INTEGER ), - DEFINE_FIELD( CMomentaryRotButton, m_direction, FIELD_INTEGER ), - DEFINE_FIELD( CMomentaryRotButton, m_returnSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CMomentaryRotButton, m_start, FIELD_VECTOR ), - DEFINE_FIELD( CMomentaryRotButton, m_end, FIELD_VECTOR ), - DEFINE_FIELD( CMomentaryRotButton, m_sounds, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CMomentaryRotButton, CBaseToggle ); - -LINK_ENTITY_TO_CLASS( momentary_rot_button, CMomentaryRotButton ); - -void CMomentaryRotButton::Spawn( void ) -{ - CBaseToggle::AxisDir( pev ); - - if ( pev->speed == 0 ) - pev->speed = 100; - - if ( m_flMoveDistance < 0 ) - { - m_start = pev->angles + pev->movedir * m_flMoveDistance; - m_end = pev->angles; - m_direction = 1; // This will toggle to -1 on the first use() - m_flMoveDistance = -m_flMoveDistance; - } - else - { - m_start = pev->angles; - m_end = pev->angles + pev->movedir * m_flMoveDistance; - m_direction = -1; // This will toggle to +1 on the first use() - } - - if ( pev->spawnflags & SF_MOMENTARY_DOOR ) - pev->solid = SOLID_BSP; - else - pev->solid = SOLID_NOT; - - pev->movetype = MOVETYPE_PUSH; - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - char *pszSound = ButtonSound( m_sounds ); - PRECACHE_SOUND(pszSound); - pev->noise = ALLOC_STRING(pszSound); - m_lastUsed = 0; -} - -void CMomentaryRotButton::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "returnspeed")) - { - m_returnSpeed = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -void CMomentaryRotButton::PlaySound( void ) -{ - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); -} - -// BUGBUG: This design causes a latentcy. When the button is retriggered, the first impulse -// will send the target in the wrong direction because the parameter is calculated based on the -// current, not future position. -void CMomentaryRotButton::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - pev->ideal_yaw = CBaseToggle::AxisDelta( pev->spawnflags, pev->angles, m_start ) / m_flMoveDistance; - - UpdateAllButtons( pev->ideal_yaw, 1 ); - UpdateTarget( pev->ideal_yaw ); -} - -void CMomentaryRotButton::UpdateAllButtons( float value, int start ) -{ - // Update all rot buttons attached to the same target - edict_t *pentTarget = NULL; - for (;;) - { - - pentTarget = FIND_ENTITY_BY_STRING(pentTarget, "target", STRING(pev->target)); - if (FNullEnt(pentTarget)) - break; - - if ( FClassnameIs( VARS(pentTarget), "momentary_rot_button" ) ) - { - CMomentaryRotButton *pEntity = CMomentaryRotButton::Instance(pentTarget); - if ( pEntity ) - { - if ( start ) - pEntity->UpdateSelf( value ); - else - pEntity->UpdateSelfReturn( value ); - } - } - } -} - -void CMomentaryRotButton::UpdateSelf( float value ) -{ - BOOL fplaysound = FALSE; - - if ( !m_lastUsed ) - { - fplaysound = TRUE; - m_direction = -m_direction; - } - m_lastUsed = 1; - - pev->nextthink = pev->ltime + 0.1; - if ( m_direction > 0 && value >= 1.0 ) - { - pev->avelocity = g_vecZero; - pev->angles = m_end; - return; - } - else if ( m_direction < 0 && value <= 0 ) - { - pev->avelocity = g_vecZero; - pev->angles = m_start; - return; - } - - if (fplaysound) - PlaySound(); - - // HACKHACK -- If we're going slow, we'll get multiple player packets per frame, bump nexthink on each one to avoid stalling - if ( pev->nextthink < pev->ltime ) - pev->nextthink = pev->ltime + 0.1; - else - pev->nextthink += 0.1; - - pev->avelocity = (m_direction * pev->speed) * pev->movedir; - SetThink( &CMomentaryRotButton::Off ); -} - -void CMomentaryRotButton::UpdateTarget( float value ) -{ - if (!FStringNull(pev->target)) - { - edict_t* pentTarget = NULL; - for (;;) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target)); - if (FNullEnt(pentTarget)) - break; - CBaseEntity *pEntity = CBaseEntity::Instance(pentTarget); - if ( pEntity ) - { - pEntity->Use( this, this, USE_SET, value ); - } - } - } -} - -void CMomentaryRotButton::Off( void ) -{ - pev->avelocity = g_vecZero; - m_lastUsed = 0; - if ( FBitSet( pev->spawnflags, SF_PENDULUM_AUTO_RETURN ) && m_returnSpeed > 0 ) - { - SetThink( &CMomentaryRotButton::Return ); - pev->nextthink = pev->ltime + 0.1; - m_direction = -1; - } - else - SetThink( NULL ); -} - -void CMomentaryRotButton::Return( void ) -{ - float value = CBaseToggle::AxisDelta( pev->spawnflags, pev->angles, m_start ) / m_flMoveDistance; - - UpdateAllButtons( value, 0 ); // This will end up calling UpdateSelfReturn() n times, but it still works right - if ( value > 0 ) - UpdateTarget( value ); -} - - -void CMomentaryRotButton::UpdateSelfReturn( float value ) -{ - if ( value <= 0 ) - { - pev->avelocity = g_vecZero; - pev->angles = m_start; - pev->nextthink = -1; - SetThink( NULL ); - } - else - { - pev->avelocity = -m_returnSpeed * pev->movedir; - pev->nextthink = pev->ltime + 0.1; - } -} - - -//---------------------------------------------------------------- -// Spark -//---------------------------------------------------------------- - -class CEnvSpark : public CBaseEntity -{ -public: - void Spawn(void); - void Precache(void); - void EXPORT SparkThink(void); - void EXPORT SparkStart(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT SparkStop(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue(KeyValueData *pkvd); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - float m_flDelay; -}; - - -TYPEDESCRIPTION CEnvSpark::m_SaveData[] = -{ - DEFINE_FIELD( CEnvSpark, m_flDelay, FIELD_FLOAT), -}; - -IMPLEMENT_SAVERESTORE( CEnvSpark, CBaseEntity ); - -LINK_ENTITY_TO_CLASS(env_spark, CEnvSpark); -LINK_ENTITY_TO_CLASS(env_debris, CEnvSpark); - -void CEnvSpark::Spawn(void) -{ - SetThink( NULL ); - SetUse( NULL ); - - if (FBitSet(pev->spawnflags, 32)) // Use for on/off - { - if (FBitSet(pev->spawnflags, 64)) // Start on - { - SetThink(&CEnvSpark::SparkThink); // start sparking - SetUse(&CEnvSpark::SparkStop); // set up +USE to stop sparking - } - else - SetUse(&CEnvSpark::SparkStart); - } - else - SetThink(&CEnvSpark::SparkThink); - - pev->nextthink = gpGlobals->time + ( 0.1 + RANDOM_FLOAT ( 0, 1.5 ) ); - - if (m_flDelay <= 0) - m_flDelay = 1.5; - - Precache( ); -} - - -void CEnvSpark::Precache(void) -{ - PRECACHE_SOUND( "buttons/spark1.wav" ); - PRECACHE_SOUND( "buttons/spark2.wav" ); - PRECACHE_SOUND( "buttons/spark3.wav" ); - PRECACHE_SOUND( "buttons/spark4.wav" ); - PRECACHE_SOUND( "buttons/spark5.wav" ); - PRECACHE_SOUND( "buttons/spark6.wav" ); -} - -void CEnvSpark::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "MaxDelay")) - { - m_flDelay = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "style") || - FStrEq(pkvd->szKeyName, "height") || - FStrEq(pkvd->szKeyName, "killtarget") || - FStrEq(pkvd->szKeyName, "value1") || - FStrEq(pkvd->szKeyName, "value2") || - FStrEq(pkvd->szKeyName, "value3")) - pkvd->fHandled = TRUE; - else - CBaseEntity::KeyValue( pkvd ); -} - -void EXPORT CEnvSpark::SparkThink(void) -{ - pev->nextthink = gpGlobals->time + 0.1 + RANDOM_FLOAT (0, m_flDelay); - DoSpark( pev, pev->origin ); -} - -void EXPORT CEnvSpark::SparkStart(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetUse(&CEnvSpark::SparkStop); - SetThink(&CEnvSpark::SparkThink); - pev->nextthink = gpGlobals->time + (0.1 + RANDOM_FLOAT ( 0, m_flDelay)); -} - -void EXPORT CEnvSpark::SparkStop(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetUse(&CEnvSpark::SparkStart); - SetThink(NULL); -} - -#define SF_BTARGET_USE 0x0001 -#define SF_BTARGET_ON 0x0002 - -class CButtonTarget : public CBaseEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - int ObjectCaps( void ); - -}; - -LINK_ENTITY_TO_CLASS( button_target, CButtonTarget ); - -void CButtonTarget::Spawn( void ) -{ - pev->movetype = MOVETYPE_PUSH; - pev->solid = SOLID_BSP; - SET_MODEL(ENT(pev), STRING(pev->model)); - pev->takedamage = DAMAGE_YES; - - if ( FBitSet( pev->spawnflags, SF_BTARGET_ON ) ) - pev->frame = 1; -} - -void CButtonTarget::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, (int)pev->frame ) ) - return; - pev->frame = 1-pev->frame; - if ( pev->frame ) - SUB_UseTargets( pActivator, USE_ON, 0 ); - else - SUB_UseTargets( pActivator, USE_OFF, 0 ); -} - - -int CButtonTarget :: ObjectCaps( void ) -{ - int caps = CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; - - if ( FBitSet(pev->spawnflags, SF_BTARGET_USE) ) - return caps | FCAP_IMPULSE_USE; - else - return caps; -} - - -int CButtonTarget::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - Use( Instance(pevAttacker), this, USE_TOGGLE, 0 ); - - return 1; -} diff --git a/dmc/dlls/cbase.cpp b/dmc/dlls/cbase.cpp deleted file mode 100644 index fc276c5..0000000 --- a/dmc/dlls/cbase.cpp +++ /dev/null @@ -1,767 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "client.h" -#include "decals.h" -#include "gamerules.h" -#include "game.h" - -void PM_Move ( struct playermove_s *ppmove, int server ); -void PM_Init ( struct playermove_s *ppmove ); -char PM_FindTextureType( char *name ); - -void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd ); - -extern Vector VecBModelOrigin( entvars_t* pevBModel ); -extern DLL_GLOBAL Vector g_vecAttackDir; -extern DLL_GLOBAL int g_iSkillLevel; - -static DLL_FUNCTIONS gFunctionTable = -{ - GameDLLInit, //pfnGameInit - DispatchSpawn, //pfnSpawn - DispatchThink, //pfnThink - DispatchUse, //pfnUse - DispatchTouch, //pfnTouch - DispatchBlocked, //pfnBlocked - DispatchKeyValue, //pfnKeyValue - DispatchSave, //pfnSave - DispatchRestore, //pfnRestore - DispatchObjectCollsionBox, //pfnAbsBox - - SaveWriteFields, //pfnSaveWriteFields - SaveReadFields, //pfnSaveReadFields - - SaveGlobalState, //pfnSaveGlobalState - RestoreGlobalState, //pfnRestoreGlobalState - ResetGlobalState, //pfnResetGlobalState - - ClientConnect, //pfnClientConnect - ClientDisconnect, //pfnClientDisconnect - ClientKill, //pfnClientKill - ClientPutInServer, //pfnClientPutInServer - ClientCommand, //pfnClientCommand - ClientUserInfoChanged, //pfnClientUserInfoChanged - ServerActivate, //pfnServerActivate - ServerDeactivate, //pfnServerDeactivate - - PlayerPreThink, //pfnPlayerPreThink - PlayerPostThink, //pfnPlayerPostThink - - StartFrame, //pfnStartFrame - ParmsNewLevel, //pfnParmsNewLevel - ParmsChangeLevel, //pfnParmsChangeLevel - - GetGameDescription, //pfnGetGameDescription Returns string describing current .dll game. - PlayerCustomization, //pfnPlayerCustomization Notifies .dll of new customization for player. - - SpectatorConnect, //pfnSpectatorConnect Called when spectator joins server - SpectatorDisconnect, //pfnSpectatorDisconnect Called when spectator leaves the server - SpectatorThink, //pfnSpectatorThink Called when spectator sends a command packet (usercmd_t) - - Sys_Error, //pfnSys_Error Called when engine has encountered an error - - PM_Move, //pfnPM_Move - PM_Init, //pfnPM_Init Server version of player movement initialization - PM_FindTextureType, //pfnPM_FindTextureType - - SetupVisibility, //pfnSetupVisibility Set up PVS and PAS for networking for this client - UpdateClientData, //pfnUpdateClientData Set up data sent only to specific client - AddToFullPack, //pfnAddToFullPack - CreateBaseline, //pfnCreateBaseline Tweak entity baseline for network encoding, allows setup of player baselines, too. - RegisterEncoders, //pfnRegisterEncoders Callbacks for network encoding - GetWeaponData, //pfnGetWeaponData - CmdStart, //pfnCmdStart - CmdEnd, //pfnCmdEnd - ConnectionlessPacket, //pfnConnectionlessPacket - GetHullBounds, //pfnGetHullBounds - CreateInstancedBaselines, //pfnCreateInstancedBaselines - InconsistentFile, //pfnInconsistentFile - AllowLagCompensation, //pfnAllowLagCompensation -}; - -static void SetObjectCollisionBox( entvars_t *pev ); - -int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ) -{ - if ( !pFunctionTable || interfaceVersion != INTERFACE_VERSION ) - { - return FALSE; - } - - memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) ); - return TRUE; -} - -int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ) -{ - if ( !pFunctionTable || *interfaceVersion != INTERFACE_VERSION ) - { - // Tell engine what version we had, so it can figure out who is out of date. - *interfaceVersion = INTERFACE_VERSION; - return FALSE; - } - - memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) ); - return TRUE; -} - - -int DispatchSpawn( edict_t *pent ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - - if (pEntity) - { - // Initialize these or entities who don't link to the world won't have anything in here - pEntity->pev->absmin = pEntity->pev->origin - Vector(1,1,1); - pEntity->pev->absmax = pEntity->pev->origin + Vector(1,1,1); - - pEntity->Spawn(); - - // Try to get the pointer again, in case the spawn function deleted the entity. - // UNDONE: Spawn() should really return a code to ask that the entity be deleted, but - // that would touch too much code for me to do that right now. - pEntity = (CBaseEntity *)GET_PRIVATE(pent); - - if ( pEntity ) - { - if ( g_pGameRules && !g_pGameRules->IsAllowedToSpawn( pEntity ) ) - return -1; // return that this entity should be deleted - if ( pEntity->pev->flags & FL_KILLME ) - return -1; - } - - - // Handle global stuff here - if ( pEntity && pEntity->pev->globalname ) - { - const globalentity_t *pGlobal = gGlobalState.EntityFromTable( pEntity->pev->globalname ); - if ( pGlobal ) - { - // Already dead? delete - if ( pGlobal->state == GLOBAL_DEAD ) - return -1; - else if ( !FStrEq( STRING(gpGlobals->mapname), pGlobal->levelName ) ) - pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive - // In this level & not dead, continue on as normal - } - else - { - // Spawned entities default to 'On' - gGlobalState.EntityAdd( pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON ); -// ALERT( at_console, "Added global entity %s (%s)\n", STRING(pEntity->pev->classname), STRING(pEntity->pev->globalname) ); - } - } - - } - - return 0; -} - -void DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd ) -{ - if ( !pkvd || !pentKeyvalue ) - return; - - EntvarsKeyvalue( VARS(pentKeyvalue), pkvd ); - - // If the key was an entity variable, or there's no class set yet, don't look for the object, it may - // not exist yet. - if ( pkvd->fHandled || pkvd->szClassName == NULL ) - return; - - // Get the actualy entity object - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentKeyvalue); - - if ( !pEntity ) - return; - - pEntity->KeyValue( pkvd ); -} - - -// HACKHACK -- this is a hack to keep the node graph entity from "touching" things (like triggers) -// while it builds the graph -BOOL gTouchDisabled = FALSE; -void DispatchTouch( edict_t *pentTouched, edict_t *pentOther ) -{ - if ( gTouchDisabled ) - return; - - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentTouched); - CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE( pentOther ); - - if ( pEntity && pOther && ! ((pEntity->pev->flags | pOther->pev->flags) & FL_KILLME) ) - pEntity->Touch( pOther ); -} - - -void DispatchUse( edict_t *pentUsed, edict_t *pentOther ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentUsed); - CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther); - - if (pEntity && !(pEntity->pev->flags & FL_KILLME) ) - pEntity->Use( pOther, pOther, USE_TOGGLE, 0 ); -} - -void DispatchThink( edict_t *pent ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - if (pEntity) - { - if ( FBitSet( pEntity->pev->flags, FL_DORMANT ) ) - ALERT( at_error, "Dormant entity %s is thinking!!\n", STRING(pEntity->pev->classname) ); - - pEntity->Think(); - } -} - -void DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE( pentBlocked ); - CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE( pentOther ); - - if (pEntity) - pEntity->Blocked( pOther ); -} - -void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - - if ( pEntity && pSaveData ) - { - ENTITYTABLE *pTable = &pSaveData->pTable[ pSaveData->currentIndex ]; - - if ( pTable->pent != pent ) - ALERT( at_error, "ENTITY TABLE OR INDEX IS WRONG!!!!\n" ); - - if ( pEntity->ObjectCaps() & FCAP_DONT_SAVE ) - return; - - // These don't use ltime & nextthink as times really, but we'll fudge around it. - if ( pEntity->pev->movetype == MOVETYPE_PUSH ) - { - float delta = pEntity->pev->nextthink - pEntity->pev->ltime; - pEntity->pev->ltime = gpGlobals->time; - pEntity->pev->nextthink = pEntity->pev->ltime + delta; - } - - pTable->location = pSaveData->size; // Remember entity position for file I/O - pTable->classname = pEntity->pev->classname; // Remember entity class for respawn - - CSave saveHelper( pSaveData ); - pEntity->Save( saveHelper ); - - pTable->size = pSaveData->size - pTable->location; // Size of entity block is data size written to block - } -} - - -// Find the matching global entity. Spit out an error if the designer made entities of -// different classes with the same global name -CBaseEntity *FindGlobalEntity( string_t classname, string_t globalname ) -{ - edict_t *pent = FIND_ENTITY_BY_STRING( NULL, "globalname", STRING(globalname) ); - CBaseEntity *pReturn = CBaseEntity::Instance( pent ); - if ( pReturn ) - { - if ( !FClassnameIs( pReturn->pev, STRING(classname) ) ) - { - ALERT( at_console, "Global entity found %s, wrong class %s\n", STRING(globalname), STRING(pReturn->pev->classname) ); - pReturn = NULL; - } - } - - return pReturn; -} - - -int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - - if ( pEntity && pSaveData ) - { - entvars_t tmpVars; - Vector oldOffset; - - CRestore restoreHelper( pSaveData ); - if ( globalEntity ) - { - CRestore tmpRestore( pSaveData ); - tmpRestore.PrecacheMode( 0 ); - tmpRestore.ReadEntVars( "ENTVARS", &tmpVars ); - - // HACKHACK - reset the save pointers, we're going to restore for real this time - pSaveData->size = pSaveData->pTable[pSaveData->currentIndex].location; - pSaveData->pCurrentData = pSaveData->pBaseData + pSaveData->size; - // ------------------- - - - const globalentity_t *pGlobal = gGlobalState.EntityFromTable( tmpVars.globalname ); - - // Don't overlay any instance of the global that isn't the latest - // pSaveData->szCurrentMapName is the level this entity is coming from - // pGlobla->levelName is the last level the global entity was active in. - // If they aren't the same, then this global update is out of date. - if ( !FStrEq( pSaveData->szCurrentMapName, pGlobal->levelName ) ) - return 0; - - // Compute the new global offset - oldOffset = pSaveData->vecLandmarkOffset; - CBaseEntity *pNewEntity = FindGlobalEntity( tmpVars.classname, tmpVars.globalname ); - if ( pNewEntity ) - { -// ALERT( at_console, "Overlay %s with %s\n", STRING(pNewEntity->pev->classname), STRING(tmpVars.classname) ); - // Tell the restore code we're overlaying a global entity from another level - restoreHelper.SetGlobalMode( 1 ); // Don't overwrite global fields - pSaveData->vecLandmarkOffset = (pSaveData->vecLandmarkOffset - pNewEntity->pev->mins) + tmpVars.mins; - pEntity = pNewEntity;// we're going to restore this data OVER the old entity - pent = ENT( pEntity->pev ); - // Update the global table to say that the global definition of this entity should come from this level - gGlobalState.EntityUpdate( pEntity->pev->globalname, gpGlobals->mapname ); - } - else - { - // This entity will be freed automatically by the engine. If we don't do a restore on a matching entity (below) - // or call EntityUpdate() to move it to this level, we haven't changed global state at all. - return 0; - } - - } - - if ( pEntity->ObjectCaps() & FCAP_MUST_SPAWN ) - { - pEntity->Restore( restoreHelper ); - pEntity->Spawn(); - } - else - { - pEntity->Restore( restoreHelper ); - pEntity->Precache( ); - } - - // Again, could be deleted, get the pointer again. - pEntity = (CBaseEntity *)GET_PRIVATE(pent); - -#if 0 - if ( pEntity && pEntity->pev->globalname && globalEntity ) - { - ALERT( at_console, "Global %s is %s\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->model) ); - } -#endif - - // Is this an overriding global entity (coming over the transition), or one restoring in a level - if ( globalEntity ) - { -// ALERT( at_console, "After: %f %f %f %s\n", pEntity->pev->origin.x, pEntity->pev->origin.y, pEntity->pev->origin.z, STRING(pEntity->pev->model) ); - pSaveData->vecLandmarkOffset = oldOffset; - if ( pEntity ) - { - UTIL_SetOrigin( pEntity->pev, pEntity->pev->origin ); - pEntity->OverrideReset(); - } - } - else if ( pEntity && pEntity->pev->globalname ) - { - const globalentity_t *pGlobal = gGlobalState.EntityFromTable( pEntity->pev->globalname ); - if ( pGlobal ) - { - // Already dead? delete - if ( pGlobal->state == GLOBAL_DEAD ) - return -1; - else if ( !FStrEq( STRING(gpGlobals->mapname), pGlobal->levelName ) ) - { - pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive - } - // In this level & not dead, continue on as normal - } - else - { - ALERT( at_error, "Global Entity %s (%s) not in table!!!\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->classname) ); - // Spawned entities default to 'On' - gGlobalState.EntityAdd( pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON ); - } - } - } - return 0; -} - - -void DispatchObjectCollsionBox( edict_t *pent ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - if (pEntity) - { - pEntity->SetObjectCollisionBox(); - } - else - SetObjectCollisionBox( &pent->v ); -} - - -void SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ) -{ - CSave saveHelper( pSaveData ); - saveHelper.WriteFields( pname, pBaseData, pFields, fieldCount ); -} - - -void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ) -{ - CRestore restoreHelper( pSaveData ); - restoreHelper.ReadFields( pname, pBaseData, pFields, fieldCount ); -} - - -edict_t * EHANDLE::Get( void ) -{ - if (m_pent) - { - if (m_pent->serialnumber == m_serialnumber) - return m_pent; - else - return NULL; - } - return NULL; -}; - -edict_t * EHANDLE::Set( edict_t *pent ) -{ - m_pent = pent; - if (pent) - m_serialnumber = m_pent->serialnumber; - return pent; -}; - - -EHANDLE :: operator CBaseEntity *() -{ - return (CBaseEntity *)GET_PRIVATE( Get( ) ); -}; - - -CBaseEntity * EHANDLE :: operator = (CBaseEntity *pEntity) -{ - if (pEntity) - { - m_pent = ENT( pEntity->pev ); - if (m_pent) - m_serialnumber = m_pent->serialnumber; - } - else - { - m_pent = NULL; - m_serialnumber = 0; - } - return pEntity; -} - -EHANDLE :: operator int () -{ - return Get() != NULL; -} - -CBaseEntity * EHANDLE :: operator -> () -{ - return (CBaseEntity *)GET_PRIVATE( Get( ) ); -} - - -// give health -int CBaseEntity :: TakeHealth( float flHealth, int bitsDamageType ) -{ - if (!pev->takedamage) - return 0; - -// heal - if ( pev->health >= pev->max_health ) - return 0; - - pev->health += flHealth; - - if (pev->health > pev->max_health) - pev->health = pev->max_health; - - return 1; -} - -// inflict damage on this entity. bitsDamageType indicates type of damage inflicted, ie: DMG_CRUSH - -int CBaseEntity :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - Vector vecTemp; - - if (!pev->takedamage) - return 0; - - // UNDONE: some entity types may be immune or resistant to some bitsDamageType - - // if Attacker == Inflictor, the attack was a melee or other instant-hit attack. - // (that is, no actual entity projectile was involved in the attack so use the shooter's origin). - if ( pevAttacker == pevInflictor ) - { - vecTemp = pevAttacker->origin - ( VecBModelOrigin(pev) ); - } - else - // an actual missile was involved. - { - vecTemp = pevInflictor->origin - ( VecBModelOrigin(pev) ); - } - -// this global is still used for glass and other non-monster killables, along with decals. - g_vecAttackDir = vecTemp.Normalize(); - -// save damage based on the target's armor level - -// figure momentum add (don't let hurt brushes or other triggers move player) - if ((!FNullEnt(pevInflictor)) && (pev->movetype == MOVETYPE_WALK || pev->movetype == MOVETYPE_STEP) && (pevAttacker->solid != SOLID_TRIGGER) ) - { - Vector vecDir = pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5; - vecDir = vecDir.Normalize(); - - float flForce = flDamage * ((32 * 32 * 72.0) / (pev->size.x * pev->size.y * pev->size.z)) * 5; - - if (flForce > 1000.0) - flForce = 1000.0; - pev->velocity = pev->velocity + vecDir * flForce; - } - -// do the damage - pev->health -= flDamage; - if (pev->health <= 0) - { - Killed( pevAttacker, GIB_NORMAL ); - return 0; - } - - return 1; -} - - -void CBaseEntity :: Killed( entvars_t *pevAttacker, int iGib ) -{ - pev->takedamage = DAMAGE_NO; - pev->deadflag = DEAD_DEAD; - UTIL_Remove( this ); -} - - -CBaseEntity *CBaseEntity::GetNextTarget( void ) -{ - if ( FStringNull( pev->target ) ) - return NULL; - edict_t *pTarget = FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(pev->target) ); - if ( FNullEnt(pTarget) ) - return NULL; - - return Instance( pTarget ); -} - -// Global Savedata for Delay -TYPEDESCRIPTION CBaseEntity::m_SaveData[] = -{ - DEFINE_FIELD( CBaseEntity, m_pGoalEnt, FIELD_CLASSPTR ), - - DEFINE_FIELD( CBaseEntity, m_pfnThink, FIELD_FUNCTION ), // UNDONE: Build table of these!!! - DEFINE_FIELD( CBaseEntity, m_pfnTouch, FIELD_FUNCTION ), - DEFINE_FIELD( CBaseEntity, m_pfnUse, FIELD_FUNCTION ), - DEFINE_FIELD( CBaseEntity, m_pfnBlocked, FIELD_FUNCTION ), -}; - - -int CBaseEntity::Save( CSave &save ) -{ - if ( save.WriteEntVars( "ENTVARS", pev ) ) - return save.WriteFields( "BASE", this, m_SaveData, ARRAYSIZE(m_SaveData) ); - - return 0; -} - -int CBaseEntity::Restore( CRestore &restore ) -{ - int status; - - status = restore.ReadEntVars( "ENTVARS", pev ); - if ( status ) - status = restore.ReadFields( "BASE", this, m_SaveData, ARRAYSIZE(m_SaveData) ); - - if ( pev->modelindex != 0 && !FStringNull(pev->model) ) - { - Vector mins, maxs; - mins = pev->mins; // Set model is about to destroy these - maxs = pev->maxs; - - - PRECACHE_MODEL( (char *)STRING(pev->model) ); - SET_MODEL(ENT(pev), STRING(pev->model)); - UTIL_SetSize(pev, mins, maxs); // Reset them - } - - return status; -} - - -// Initialize absmin & absmax to the appropriate box -void SetObjectCollisionBox( entvars_t *pev ) -{ - if ( (pev->solid == SOLID_BSP) && - (pev->angles.x || pev->angles.y|| pev->angles.z) ) - { // expand for rotation - float max, v; - int i; - - max = 0; - for (i=0 ; i<3 ; i++) - { - v = fabs( pev->mins[i]); - if (v > max) - max = v; - v = fabs( pev->maxs[i]); - if (v > max) - max = v; - } - for (i=0 ; i<3 ; i++) - { - pev->absmin[i] = pev->origin[i] - max; - pev->absmax[i] = pev->origin[i] + max; - } - } - else - { - pev->absmin = pev->origin + pev->mins; - pev->absmax = pev->origin + pev->maxs; - } - - pev->absmin.x -= 1; - pev->absmin.y -= 1; - pev->absmin.z -= 1; - pev->absmax.x += 1; - pev->absmax.y += 1; - pev->absmax.z += 1; -} - - -void CBaseEntity::SetObjectCollisionBox( void ) -{ - ::SetObjectCollisionBox( pev ); -} - - -int CBaseEntity :: Intersects( CBaseEntity *pOther ) -{ - if ( pOther->pev->absmin.x > pev->absmax.x || - pOther->pev->absmin.y > pev->absmax.y || - pOther->pev->absmin.z > pev->absmax.z || - pOther->pev->absmax.x < pev->absmin.x || - pOther->pev->absmax.y < pev->absmin.y || - pOther->pev->absmax.z < pev->absmin.z ) - return 0; - return 1; -} - -void CBaseEntity :: MakeDormant( void ) -{ - SetBits( pev->flags, FL_DORMANT ); - - // Don't touch - pev->solid = SOLID_NOT; - // Don't move - pev->movetype = MOVETYPE_NONE; - // Don't draw - SetBits( pev->effects, EF_NODRAW ); - // Don't think - pev->nextthink = 0; - // Relink - UTIL_SetOrigin( pev, pev->origin ); -} - -int CBaseEntity :: IsDormant( void ) -{ - return FBitSet( pev->flags, FL_DORMANT ); -} - -BOOL CBaseEntity :: IsInWorld( void ) -{ - // position - if (pev->origin.x >= 4096) return FALSE; - if (pev->origin.y >= 4096) return FALSE; - if (pev->origin.z >= 4096) return FALSE; - if (pev->origin.x <= -4096) return FALSE; - if (pev->origin.y <= -4096) return FALSE; - if (pev->origin.z <= -4096) return FALSE; - // speed - if (pev->velocity.x >= 2000) return FALSE; - if (pev->velocity.y >= 2000) return FALSE; - if (pev->velocity.z >= 2000) return FALSE; - if (pev->velocity.x <= -2000) return FALSE; - if (pev->velocity.y <= -2000) return FALSE; - if (pev->velocity.z <= -2000) return FALSE; - - return TRUE; -} - -int CBaseEntity::ShouldToggle( USE_TYPE useType, BOOL currentState ) -{ - if ( useType != USE_TOGGLE && useType != USE_SET ) - { - if ( (currentState && useType == USE_ON) || (!currentState && useType == USE_OFF) ) - return 0; - } - return 1; -} - - -int CBaseEntity :: DamageDecal( int bitsDamageType ) -{ - if ( pev->rendermode == kRenderTransAlpha ) - return -1; - - if ( pev->rendermode != kRenderNormal ) - return DECAL_BPROOF1; - - return DECAL_GUNSHOT1 + RANDOM_LONG(0,4); -} - - - -// NOTE: szName must be a pointer to constant memory, e.g. "monster_class" because the entity -// will keep a pointer to it after this call. -CBaseEntity * CBaseEntity::Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) -{ - edict_t *pent; - CBaseEntity *pEntity; - - pent = CREATE_NAMED_ENTITY( MAKE_STRING( szName )); - if ( FNullEnt( pent ) ) - { - ALERT ( at_console, "NULL Ent in Create!\n" ); - return NULL; - } - pEntity = Instance( pent ); - pEntity->pev->owner = pentOwner; - pEntity->pev->origin = vecOrigin; - pEntity->pev->angles = vecAngles; - DispatchSpawn( pEntity->edict() ); - return pEntity; -} - - diff --git a/dmc/dlls/cbase.h b/dmc/dlls/cbase.h deleted file mode 100644 index df35c94..0000000 --- a/dmc/dlls/cbase.h +++ /dev/null @@ -1,800 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -Class Hierachy - -CBaseEntity - CBaseDelay - CBaseToggle - CBaseItem - CBaseMonster - CBaseCycler - CBasePlayer - CBaseGroup -*/ - -#define MAX_PATH_SIZE 10 // max number of nodes available for a path. - -// These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions) -#define FCAP_CUSTOMSAVE 0x00000001 -#define FCAP_ACROSS_TRANSITION 0x00000002 // should transfer between transitions -#define FCAP_MUST_SPAWN 0x00000004 // Spawn after restore -#define FCAP_DONT_SAVE 0x80000000 // Don't save this -#define FCAP_IMPULSE_USE 0x00000008 // can be used by the player -#define FCAP_CONTINUOUS_USE 0x00000010 // can be used by the player -#define FCAP_ONOFF_USE 0x00000020 // can be used by the player -#define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains) -#define FCAP_MASTER 0x00000080 // Can be used to "master" other entities (like multisource) - -// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!! -#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions - -#include "archtypes.h" // DAL -#include "saverestore.h" -#include "schedule.h" - -#ifndef MONSTEREVENT_H -#include "monsterevent.h" -#endif - -#include "Platform.h" - -// C functions for external declarations that call the appropriate C++ methods - -#define EXPORT DLLEXPORT - -extern "C" DLLEXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); -extern "C" DLLEXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); - -extern int DispatchSpawn( edict_t *pent ); -extern void DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd ); -extern void DispatchTouch( edict_t *pentTouched, edict_t *pentOther ); -extern void DispatchUse( edict_t *pentUsed, edict_t *pentOther ); -extern void DispatchThink( edict_t *pent ); -extern void DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther ); -extern void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData ); -extern int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity ); -extern void DispatchObjectCollsionBox( edict_t *pent ); -extern void SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); -extern void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); -extern void SaveGlobalState( SAVERESTOREDATA *pSaveData ); -extern void RestoreGlobalState( SAVERESTOREDATA *pSaveData ); -extern void ResetGlobalState( void ); - -typedef enum { USE_OFF = 0, USE_ON = 1, USE_SET = 2, USE_TOGGLE = 3 } USE_TYPE; - -extern void FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -typedef void (CBaseEntity::*BASEPTR)(void); -typedef void (CBaseEntity::*ENTITYFUNCPTR)(CBaseEntity *pOther ); -typedef void (CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -// For CLASSIFY -#define CLASS_NONE 0 -#define CLASS_MACHINE 1 -#define CLASS_PLAYER 2 -#define CLASS_HUMAN_PASSIVE 3 -#define CLASS_HUMAN_MILITARY 4 -#define CLASS_ALIEN_MILITARY 5 -#define CLASS_ALIEN_PASSIVE 6 -#define CLASS_ALIEN_MONSTER 7 -#define CLASS_ALIEN_PREY 8 -#define CLASS_ALIEN_PREDATOR 9 -#define CLASS_INSECT 10 -#define CLASS_PLAYER_ALLY 11 -#define CLASS_PLAYER_BIOWEAPON 12 // hornets and snarks.launched by players -#define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks.launched by the alien menace -#define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures. - -class CBaseEntity; -class CBaseMonster; -class CBasePlayerItem; -class CSquadMonster; - - -#define SF_NORESPAWN ( 1 << 30 )// !!!set this bit on guns and stuff that should never respawn. - -// -// EHANDLE. Safe way to point to CBaseEntities who may die between frames -// -class EHANDLE -{ -private: - edict_t *m_pent; - int m_serialnumber; -public: - edict_t *Get( void ); - edict_t *Set( edict_t *pent ); - - operator int (); - - operator CBaseEntity *(); - - CBaseEntity * operator = (CBaseEntity *pEntity); - CBaseEntity * operator ->(); -}; - - -// -// Base Entity. All entity types derive from this -// -class CBaseEntity -{ -public: - // Constructor. Set engine to use C/C++ callback functions - // pointers to engine data - entvars_t *pev; // Don't need to save/restore this pointer, the engine resets it - - // path corners - CBaseEntity *m_pGoalEnt;// path corner we are heading towards - CBaseEntity *m_pLink;// used for temporary link-list operations. - - // initialization functions - virtual void Spawn( void ) { return; } - virtual void Precache( void ) { return; } - virtual void KeyValue( KeyValueData* pkvd) { pkvd->fHandled = FALSE; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - virtual int ObjectCaps( void ) { return FCAP_ACROSS_TRANSITION; } - virtual void Activate( void ) {} - - // Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box) - virtual void SetObjectCollisionBox( void ); - -// Classify - returns the type of group (i.e, "houndeye", or "human military" so that monsters with different classnames -// still realize that they are teammates. (overridden for monsters that form groups) - virtual int Classify ( void ) { return CLASS_NONE; }; - virtual void DeathNotice ( entvars_t *pevChild ) {}// monster maker children use this to tell the monster maker that they have died. - - - static TYPEDESCRIPTION m_SaveData[]; - - virtual void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - virtual int TakeHealth( float flHealth, int bitsDamageType ); - virtual void Killed( entvars_t *pevAttacker, int iGib ); - virtual int BloodColor( void ) { return DONT_BLEED; } - virtual void TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); - virtual BOOL IsTriggered( CBaseEntity *pActivator ) {return TRUE;} - virtual CBaseMonster *MyMonsterPointer( void ) { return NULL;} - virtual CSquadMonster *MySquadMonsterPointer( void ) { return NULL;} - virtual int GetToggleState( void ) { return TS_AT_TOP; } - virtual void AddPoints( int score, BOOL bAllowNegativeScore ) {} - virtual void AddPointsToTeam( int score, BOOL bAllowNegativeScore ) {} - virtual BOOL AddPlayerItem( CBasePlayerItem *pItem ) { return 0; } - virtual BOOL RemovePlayerItem( CBasePlayerItem *pItem ) { return 0; } - virtual int GiveAmmo( int iAmount, char *szName, int iMax ) { return -1; }; - virtual float GetDelay( void ) { return 0; } - virtual int IsMoving( void ) { return pev->velocity != g_vecZero; } - virtual void OverrideReset( void ) {} - virtual int DamageDecal( int bitsDamageType ); - // This is ONLY used by the node graph to test movement through a door - virtual void SetToggleState( int state ) {} - virtual void StartSneaking( void ) {} - virtual void StopSneaking( void ) {} - virtual BOOL OnControls( entvars_t *pev ) { return FALSE; } - virtual BOOL IsSneaking( void ) { return FALSE; } - virtual BOOL IsAlive( void ) { return (pev->deadflag == DEAD_NO) && pev->health > 0; } - virtual BOOL IsBSPModel( void ) { return pev->solid == SOLID_BSP || pev->movetype == MOVETYPE_PUSHSTEP; } - virtual BOOL ReflectGauss( void ) { return ( IsBSPModel() && !pev->takedamage ); } - virtual BOOL HasTarget( string_t targetname ) { return FStrEq(STRING(targetname), STRING(pev->targetname) ); } - virtual BOOL IsInWorld( void ); - virtual BOOL IsPlayer( void ) { return FALSE; } - virtual BOOL IsNetClient( void ) { return FALSE; } - virtual const char *TeamID( void ) { return ""; } - - -// virtual void SetActivator( CBaseEntity *pActivator ) {} - virtual CBaseEntity *GetNextTarget( void ); - - // fundamental callbacks - void (CBaseEntity ::*m_pfnThink)(void); - void (CBaseEntity ::*m_pfnTouch)( CBaseEntity *pOther ); - void (CBaseEntity ::*m_pfnUse)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void (CBaseEntity ::*m_pfnBlocked)( CBaseEntity *pOther ); - - virtual void Think( void ) { if (m_pfnThink) (this->*m_pfnThink)(); }; - virtual void Touch( CBaseEntity *pOther ) { if (m_pfnTouch) (this->*m_pfnTouch)( pOther ); }; - virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) - { - if (m_pfnUse) - (this->*m_pfnUse)( pActivator, pCaller, useType, value ); - } - virtual void Blocked( CBaseEntity *pOther ) { if (m_pfnBlocked) (this->*m_pfnBlocked)( pOther ); }; - - // allow engine to allocate instance data - void *operator new( size_t stAllocateBlock, entvars_t *pev ) - { - return (void *)ALLOC_PRIVATE(ENT(pev), stAllocateBlock); - }; - - // don't use this. -#if _MSC_VER >= 1200 // only build this code if MSVC++ 6.0 or higher - void operator delete(void *pMem, entvars_t *pev) - { - pev->flags |= FL_KILLME; - }; -#endif - - void UpdateOnRemove( void ); - - // common member functions - void EXPORT SUB_Remove( void ); - void EXPORT SUB_DoNothing( void ); - void EXPORT SUB_StartFadeOut ( void ); - void EXPORT SUB_FadeOut ( void ); - void EXPORT SUB_CallUseToggle( void ) { this->Use( this, this, USE_TOGGLE, 0 ); } - int ShouldToggle( USE_TYPE useType, BOOL currentState ); - void FireBullets( ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = NULL ); - - virtual CBaseEntity *Respawn( void ) { return NULL; } - - void SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ); - // Do the bounding boxes of these two intersect? - int Intersects( CBaseEntity *pOther ); - void MakeDormant( void ); - int IsDormant( void ); - BOOL IsLockedByMaster( void ) { return FALSE; } - - static CBaseEntity *Instance( edict_t *pent ) - { - if ( !pent ) - pent = ENT(0); - CBaseEntity *pEnt = (CBaseEntity *)GET_PRIVATE(pent); - return pEnt; - } - - static CBaseEntity *Instance( entvars_t *pev ) { return Instance( ENT( pev ) ); } - static CBaseEntity *Instance( int eoffset) { return Instance( ENT( eoffset) ); } - - CBaseMonster *GetMonsterPointer( entvars_t *pevMonster ) - { - CBaseEntity *pEntity = Instance( pevMonster ); - if ( pEntity ) - return pEntity->MyMonsterPointer(); - return NULL; - } - CBaseMonster *GetMonsterPointer( edict_t *pentMonster ) - { - CBaseEntity *pEntity = Instance( pentMonster ); - if ( pEntity ) - return pEntity->MyMonsterPointer(); - return NULL; - } - - - // Ugly code to lookup all functions to make sure they are exported when set. -#ifdef _DEBUG - void FunctionCheck( void *pFunction, char *name ) - { -#ifdef _WIN32 - if (pFunction && !NAME_FOR_FUNCTION((uint32)pFunction) ) - ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING(pev->classname), name, pFunction ); -#endif // _WIN32 - } - - BASEPTR ThinkSet( BASEPTR func, char *name ) - { - m_pfnThink = func; - FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnThink)))), name ); - return func; - } - ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name ) - { - m_pfnTouch = func; - FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnTouch)))), name ); - return func; - } - USEPTR UseSet( USEPTR func, char *name ) - { - m_pfnUse = func; - FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnUse)))), name ); - return func; - } - ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name ) - { - m_pfnBlocked = func; - FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnBlocked)))), name ); - return func; - } - -#endif - - - // virtual functions used by a few classes - - // used by monsters that are created by the MonsterMaker - virtual void UpdateOwner( void ) { return; }; - - - // - static CBaseEntity *Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner = NULL ); - - virtual BOOL FBecomeProne( void ) {return FALSE;}; - edict_t *edict() { return ENT( pev ); }; - EOFFSET eoffset( ) { return OFFSET( pev ); }; - int entindex( ) { return ENTINDEX( edict() ); }; - - virtual Vector Center( ) { return (pev->absmax + pev->absmin) * 0.5; }; // center point of entity - virtual Vector EyePosition( ) { return pev->origin + pev->view_ofs; }; // position of eyes - virtual Vector EarPosition( ) { return pev->origin + pev->view_ofs; }; // position of ears - virtual Vector BodyTarget( const Vector &posSrc ) { return Center( ); }; // position to shoot at - - virtual int Illumination( ) { return GETENTITYILLUM( ENT( pev ) ); }; - - virtual BOOL FVisible ( CBaseEntity *pEntity ); - virtual BOOL FVisible ( const Vector &vecOrigin ); - - - // QUAKECLASSIC - BOOL m_bAxHitMe; - void Spawn_Telefog( Vector vecOrg, CBaseEntity *pOther ); - Vector m_vecTeleAngles; -}; - - - -// Ugly technique to override base member functions -// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a -// member function of a base class. static_cast is a sleezy way around that problem. - -#ifdef _DEBUG - -#define SetThink( a ) ThinkSet( static_cast (a), #a ) -#define SetTouch( a ) TouchSet( static_cast (a), #a ) -#define SetUse( a ) UseSet( static_cast (a), #a ) -#define SetBlocked( a ) BlockedSet( static_cast (a), #a ) - -#else - -#define SetThink( a ) m_pfnThink = static_cast (a) -#define SetTouch( a ) m_pfnTouch = static_cast (a) -#define SetUse( a ) m_pfnUse = static_cast (a) -#define SetBlocked( a ) m_pfnBlocked = static_cast (a) - -#endif - - -class CPointEntity : public CBaseEntity -{ -public: - void Spawn( void ); - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } -private: -}; - - -typedef struct locksounds // sounds that doors and buttons make when locked/unlocked -{ - string_t sLockedSound; // sound a door makes when it's locked - string_t sLockedSentence; // sentence group played when door is locked - string_t sUnlockedSound; // sound a door makes when it's unlocked - string_t sUnlockedSentence; // sentence group played when door is unlocked - - int iLockedSentence; // which sentence in sentence group to play next - int iUnlockedSentence; // which sentence in sentence group to play next - - float flwaitSound; // time delay between playing consecutive 'locked/unlocked' sounds - float flwaitSentence; // time delay between playing consecutive sentences - BYTE bEOFLocked; // true if hit end of list of locked sentences - BYTE bEOFUnlocked; // true if hit end of list of unlocked sentences -} locksound_t; - -void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton); - -// -// MultiSouce -// - -#define MAX_MULTI_TARGETS 16 // maximum number of targets a single multi_manager entity may be assigned. -#define MS_MAX_TARGETS 32 - -class CMultiSource : public CPointEntity -{ -public: - void Spawn( ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - int ObjectCaps( void ) { return (CPointEntity::ObjectCaps() | FCAP_MASTER); } - BOOL IsTriggered( CBaseEntity *pActivator ); - void EXPORT Register( void ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - EHANDLE m_rgEntities[MS_MAX_TARGETS]; - int m_rgTriggered[MS_MAX_TARGETS]; - - int m_iTotal; - string_t m_globalstate; -}; - - -// -// generic Delay entity. -// -class CBaseDelay : public CBaseEntity -{ -public: - float m_flDelay; - int m_iszKillTarget; - - virtual void KeyValue( KeyValueData* pkvd); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - // common member functions - void SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ); - void EXPORT DelayThink( void ); -}; - - -class CBaseAnimating : public CBaseDelay -{ -public: - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - // Basic Monster Animation functions - float StudioFrameAdvance( float flInterval = 0.0 ); // accumulate animation frame time from last time called until now - int GetSequenceFlags( void ); - int LookupActivity ( int activity ); - int LookupActivityHeaviest ( int activity ); - int LookupSequence ( const char *label ); - void ResetSequenceInfo ( ); - void DispatchAnimEvents ( float flFutureInterval = 0.1 ); // Handle events that have happend since last time called up until X seconds into the future - virtual void HandleAnimEvent( MonsterEvent_t *pEvent ) { return; }; - float SetBoneController ( int iController, float flValue ); - void InitBoneControllers ( void ); - float SetBlending ( int iBlender, float flValue ); - void GetBonePosition ( int iBone, Vector &origin, Vector &angles ); - void GetAutomovement( Vector &origin, Vector &angles, float flInterval = 0.1 ); - int FindTransition( int iEndingSequence, int iGoalSequence, int *piDir ); - void GetAttachment ( int iAttachment, Vector &origin, Vector &angles ); - void SetBodygroup( int iGroup, int iValue ); - int GetBodygroup( int iGroup ); - int ExtractBbox( int sequence, float *mins, float *maxs ); - void SetSequenceBox( void ); - - // animation needs - float m_flFrameRate; // computed FPS for current sequence - float m_flGroundSpeed; // computed linear movement rate for current sequence - float m_flLastEventCheck; // last time the event list was checked - BOOL m_fSequenceFinished;// flag set when StudioAdvanceFrame moves across a frame boundry - BOOL m_fSequenceLoops; // true if the sequence loops -}; - - -// -// generic Toggle entity. -// -#define SF_ITEM_USE_ONLY 256 // ITEM_USE_ONLY = BUTTON_USE_ONLY = DOOR_USE_ONLY!!! - -class CBaseToggle : public CBaseAnimating -{ -public: - void KeyValue( KeyValueData *pkvd ); - - TOGGLE_STATE m_toggle_state; - float m_flActivateFinished;//like attack_finished, but for doors - float m_flMoveDistance;// how far a door should slide or rotate - float m_flWait; - float m_flLip; - float m_flTWidth;// for plats - float m_flTLength;// for plats - - Vector m_vecPosition1; - Vector m_vecPosition2; - Vector m_vecAngle1; - Vector m_vecAngle2; - - int m_cTriggersLeft; // trigger_counter only, # of activations remaining - float m_flHeight; - EHANDLE m_hActivator; - void (CBaseToggle::*m_pfnCallWhenMoveDone)(void); - Vector m_vecFinalDest; - Vector m_vecFinalAngle; - - int m_bitsDamageInflict; // DMG_ damage type that the door or tigger does - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - virtual int GetToggleState( void ) { return m_toggle_state; } - virtual float GetDelay( void ) { return m_flWait; } - - // common member functions - void LinearMove( Vector vecDest, float flSpeed ); - void EXPORT LinearMoveDone( void ); - void AngularMove( Vector vecDestAngle, float flSpeed ); - void EXPORT AngularMoveDone( void ); - BOOL IsLockedByMaster( void ); - - static float AxisValue( int flags, const Vector &angles ); - static void AxisDir( entvars_t *pev ); - static float AxisDelta( int flags, const Vector &angle1, const Vector &angle2 ); - - string_t m_sMaster; // If this button has a master switch, this is the targetname. - // A master switch must be of the multisource type. If all - // of the switches in the multisource have been triggered, then - // the button will be allowed to operate. Otherwise, it will be - // deactivated. -}; -#define SetMoveDone( a ) m_pfnCallWhenMoveDone = static_cast (a) - - -// people gib if their health is <= this at the time of death -#define GIB_HEALTH_VALUE -30 - -#define ROUTE_SIZE 8 // how many waypoints a monster can store at one time -#define MAX_OLD_ENEMIES 4 // how many old enemies to remember - -#define bits_CAP_DUCK ( 1 << 0 )// crouch -#define bits_CAP_JUMP ( 1 << 1 )// jump/leap -#define bits_CAP_STRAFE ( 1 << 2 )// strafe ( walk/run sideways) -#define bits_CAP_SQUAD ( 1 << 3 )// can form squads -#define bits_CAP_SWIM ( 1 << 4 )// proficiently navigate in water -#define bits_CAP_CLIMB ( 1 << 5 )// climb ladders/ropes -#define bits_CAP_USE ( 1 << 6 )// open doors/push buttons/pull levers -#define bits_CAP_HEAR ( 1 << 7 )// can hear forced sounds -#define bits_CAP_AUTO_DOORS ( 1 << 8 )// can trigger auto doors -#define bits_CAP_OPEN_DOORS ( 1 << 9 )// can open manual doors -#define bits_CAP_TURN_HEAD ( 1 << 10)// can turn head, always bone controller 0 - -#define bits_CAP_RANGE_ATTACK1 ( 1 << 11)// can do a range attack 1 -#define bits_CAP_RANGE_ATTACK2 ( 1 << 12)// can do a range attack 2 -#define bits_CAP_MELEE_ATTACK1 ( 1 << 13)// can do a melee attack 1 -#define bits_CAP_MELEE_ATTACK2 ( 1 << 14)// can do a melee attack 2 - -#define bits_CAP_FLY ( 1 << 15)// can fly, move all around - -#define bits_CAP_DOORS_GROUP (bits_CAP_USE | bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS) - -// used by suit voice to indicate damage sustained and repaired type to player - -// instant damage - -#define DMG_GENERIC 0 // generic damage was done -#define DMG_CRUSH (1 << 0) // crushed by falling or moving object -#define DMG_BULLET (1 << 1) // shot -#define DMG_SLASH (1 << 2) // cut, clawed, stabbed -#define DMG_BURN (1 << 3) // heat burned -#define DMG_FREEZE (1 << 4) // frozen -#define DMG_FALL (1 << 5) // fell too far -#define DMG_BLAST (1 << 6) // explosive blast damage -#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt -#define DMG_SHOCK (1 << 8) // electric shock -#define DMG_SONIC (1 << 9) // sound pulse shockwave -#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam -#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death -#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death. -#define DMG_DROWN (1 << 14) // Drowning -// time-based damage -#define DMG_TIMEBASED (~(0x3fff)) // mask for time-based damage - -#define DMG_PARALYZE (1 << 15) // slows affected creature down -#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad -#define DMG_POISON (1 << 17) // blood poisioning -#define DMG_RADIATION (1 << 18) // radiation exposure -#define DMG_DROWNRECOVER (1 << 19) // drowning recovery -#define DMG_ACID (1 << 20) // toxic chemicals or acid burns -#define DMG_SLOWBURN (1 << 21) // in an oven -#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer -#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar) - -#define DMG_IGNORE_MAXHEALTH (1<< 24) // Used by TakeHealth only. Ignores the player's max health when healing. - -// these are the damage types that are allowed to gib corpses -#define DMG_GIB_CORPSE ( DMG_CRUSH | DMG_FALL | DMG_BLAST | DMG_SONIC | DMG_CLUB ) - -// these are the damage types that have client hud art -#define DMG_SHOWNHUD (DMG_POISON | DMG_ACID | DMG_FREEZE | DMG_SLOWFREEZE | DMG_DROWN | DMG_BURN | DMG_SLOWBURN | DMG_NERVEGAS | DMG_RADIATION | DMG_SHOCK) - -// NOTE: tweak these values based on gameplay feedback: - -#define PARALYZE_DURATION 2 // number of 2 second intervals to take damage -#define PARALYZE_DAMAGE 1.0 // damage to take each 2 second interval - -#define NERVEGAS_DURATION 2 -#define NERVEGAS_DAMAGE 5.0 - -#define POISON_DURATION 5 -#define POISON_DAMAGE 2.0 - -#define RADIATION_DURATION 2 -#define RADIATION_DAMAGE 1.0 - -#define ACID_DURATION 2 -#define ACID_DAMAGE 5.0 - -#define SLOWBURN_DURATION 2 -#define SLOWBURN_DAMAGE 1.0 - -#define SLOWFREEZE_DURATION 2 -#define SLOWFREEZE_DAMAGE 1.0 - - -#define itbd_Paralyze 0 -#define itbd_NerveGas 1 -#define itbd_Poison 2 -#define itbd_Radiation 3 -#define itbd_DrownRecover 4 -#define itbd_Acid 5 -#define itbd_SlowBurn 6 -#define itbd_SlowFreeze 7 -#define CDMG_TIMEBASED 8 - -// when calling KILLED(), a value that governs gib behavior is expected to be -// one of these three values -#define GIB_NORMAL 0// gib if entity was overkilled -#define GIB_NEVER 1// never gib, no matter how much death damage is done ( freezing, etc ) -#define GIB_ALWAYS 2// always gib ( Houndeye Shock, Barnacle Bite ) - -class CBaseMonster; -class CCineMonster; -class CSound; - -#include "basemonster.h" - - -char *ButtonSound( int sound ); // get string of button sound number - - -// -// Generic Button -// -class CBaseButton : public CBaseToggle -{ -public: - void Spawn( void ); - virtual void Precache( void ); - void RotSpawn( void ); - virtual void KeyValue( KeyValueData* pkvd); - - void ButtonActivate( ); - void SparkSoundCache( void ); - - void EXPORT ButtonShot( void ); - void EXPORT ButtonTouch( CBaseEntity *pOther ); - void EXPORT ButtonSpark ( void ); - void EXPORT TriggerAndWait( void ); - void EXPORT ButtonReturn( void ); - void EXPORT ButtonBackHome( void ); - void EXPORT ButtonUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - enum BUTTON_CODE { BUTTON_NOTHING, BUTTON_ACTIVATE, BUTTON_RETURN }; - BUTTON_CODE ButtonResponseToTouch( void ); - - static TYPEDESCRIPTION m_SaveData[]; - // Buttons that don't take damage can be IMPULSE used - virtual int ObjectCaps( void ) { return (CBaseToggle:: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | (pev->takedamage?0:FCAP_IMPULSE_USE); } - - BOOL m_fStayPushed; // button stays pushed in until touched again? - BOOL m_fRotating; // a rotating button? default is a sliding button. - - string_t m_strChangeTarget; // if this field is not null, this is an index into the engine string array. - // when this button is touched, it's target entity's TARGET field will be set - // to the button's ChangeTarget. This allows you to make a func_train switch paths, etc. - - locksound_t m_ls; // door lock sounds - - BYTE m_bLockedSound; // ordinals from entity selection - BYTE m_bLockedSentence; - BYTE m_bUnlockedSound; - BYTE m_bUnlockedSentence; - int m_sounds; -}; - -// -// Weapons -// - -#define BAD_WEAPON 0x00007FFF - -// -// Converts a entvars_t * to a class pointer -// It will allocate the class and entity if necessary -// -template T * GetClassPtr( T *a ) -{ - entvars_t *pev = (entvars_t *)a; - - // allocate entity if necessary - if (pev == NULL) - pev = VARS(CREATE_ENTITY()); - - // get the private data - a = (T *)GET_PRIVATE(ENT(pev)); - - if (a == NULL) - { - // allocate private data - a = new(pev) T; - a->pev = pev; - } - return a; -} - - -/* -bit_PUSHBRUSH_DATA | bit_TOGGLE_DATA -bit_MONSTER_DATA -bit_DELAY_DATA -bit_TOGGLE_DATA | bit_DELAY_DATA | bit_MONSTER_DATA -bit_PLAYER_DATA | bit_MONSTER_DATA -bit_MONSTER_DATA | CYCLER_DATA -bit_LIGHT_DATA -path_corner_data -bit_MONSTER_DATA | wildcard_data -bit_MONSTER_DATA | bit_GROUP_DATA -boid_flock_data -boid_data -CYCLER_DATA -bit_ITEM_DATA -bit_ITEM_DATA | func_hud_data -bit_TOGGLE_DATA | bit_ITEM_DATA -EOFFSET -env_sound_data -env_sound_data -push_trigger_data -*/ - -#define TRACER_FREQ 4 // Tracers fire every 4 bullets - -typedef struct _SelAmmo -{ - BYTE Ammo1Type; - BYTE Ammo1; - BYTE Ammo2Type; - BYTE Ammo2; -} SelAmmo; - - -// this moved here from world.cpp, to allow classes to be derived from it -//======================= -// CWorld -// -// This spawns first when each level begins. -//======================= -class CWorld : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); -}; - -class CClientFog : public CBaseEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - - float m_iStartDist; - float m_iEndDist; -}; - -// QUAKECLASSIC -extern char *g_szDeathType; diff --git a/dmc/dlls/cdll_dll.h b/dmc/dlls/cdll_dll.h deleted file mode 100644 index 65279fc..0000000 --- a/dmc/dlls/cdll_dll.h +++ /dev/null @@ -1,46 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// cdll_dll.h - -// this file is included by both the game-dll and the client-dll, - -#ifndef CDLL_DLL_H -#define CDLL_DLL_H - -#define MAX_WEAPONS 257 // ??? - -#define MAX_WEAPON_SLOTS 9 // hud item selection slots -#define MAX_ITEM_TYPES 6 // hud item selection slots - -#define MAX_ITEMS 5 // hard coded item types - -#define HIDEHUD_WEAPONS ( 1<<0 ) -#define HIDEHUD_FLASHLIGHT ( 1<<1 ) -#define HIDEHUD_ALL ( 1<<2 ) -#define HIDEHUD_HEALTH ( 1<<3 ) - -#define MAX_AMMO_TYPES 32 // ??? -#define MAX_AMMO_SLOTS 32 // not really slots - -#define HUD_PRINTNOTIFY 1 -#define HUD_PRINTCONSOLE 2 -#define HUD_PRINTTALK 3 -#define HUD_PRINTCENTER 4 - - -#define WEAPON_SUIT 31 - -#endif diff --git a/dmc/dlls/client.cpp b/dmc/dlls/client.cpp deleted file mode 100644 index 0b0760d..0000000 --- a/dmc/dlls/client.cpp +++ /dev/null @@ -1,1817 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// Robin, 4-22-98: Moved set_suicide_frame() here from player.cpp to allow us to -// have one without a hardcoded player.mdl in tf_client.cpp - -/* - -===== client.cpp ======================================================== - - client/server game specific stuff - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "player.h" -#include "spectator.h" -#include "client.h" -#include "gamerules.h" -#include "customentity.h" -#include "weapons.h" -#include "weaponinfo.h" -#include "usercmd.h" -#include "netadr.h" - -#if !defined ( _WIN32 ) -#include // isspace,isprint -#endif - -extern DLL_GLOBAL ULONG g_ulModelIndexPlayer; -extern DLL_GLOBAL BOOL g_fGameOver; -extern DLL_GLOBAL int g_iSkillLevel; -extern DLL_GLOBAL ULONG g_ulFrameCount; - -#if defined( THREEWAVE ) -char* GetTeamName( int team ); -#endif - -extern bool g_bHaveMOTD; - -extern void CopyToBodyQue(entvars_t* pev); -extern int giPrecacheGrunt; -extern int gmsgSayText; - -extern unsigned short g_sGibbed; -extern unsigned short g_sTeleport; -extern unsigned short g_sTrail; -extern unsigned short g_sExplosion; -extern unsigned short g_usPowerUp; - -#ifdef THREEWAVE -extern unsigned short g_usHook; -extern unsigned short g_usCable; -extern unsigned short g_usCarried; -extern unsigned short g_usFlagSpawn; -#endif - -void LinkUserMessages( void ); - -/* - * used by kill command and disconnect command - * ROBIN: Moved here from player.cpp, to allow multiple player models - */ -void set_suicide_frame(entvars_t* pev) -{ - if (!FStrEq(STRING(pev->model), "models/player.mdl")) - return; // allready gibbed - -// pev->frame = $deatha11; - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_TOSS; - pev->deadflag = DEAD_DEAD; - pev->nextthink = -1; -} - - -/* -=========== -ClientConnect - -called when a player connects to a server -============ -*/ -BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) -{ - return g_pGameRules->ClientConnected( pEntity, pszName, pszAddress, szRejectReason ); - -// a client connecting during an intermission can cause problems -// if (intermission_running) -// ExitIntermission (); - -} - - -/* -=========== -ClientDisconnect - -called when a player disconnects from a server - -GLOBALS ASSUMED SET: g_fGameOver -============ -*/ -void ClientDisconnect( edict_t *pEntity ) -{ - if (g_fGameOver) - return; - - char text[256]; - sprintf( text, "- %s has left the game\n", STRING(pEntity->v.netname) ); - MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); - WRITE_BYTE( ENTINDEX(pEntity) ); - WRITE_STRING( text ); - MESSAGE_END(); - - // since the edict doesn't get deleted, fix it so it doesn't interfere. - pEntity->v.takedamage = DAMAGE_NO;// don't attract autoaim - pEntity->v.solid = SOLID_NOT;// nonsolid - UTIL_SetOrigin ( &pEntity->v, pEntity->v.origin ); - - g_pGameRules->ClientDisconnected( pEntity ); -} - - -// called by ClientKill and DeadThink -void respawn(entvars_t* pev, BOOL fCopyCorpse) -{ - if (gpGlobals->coop || gpGlobals->deathmatch) - { - if ( fCopyCorpse ) - { - // make a copy of the dead body for appearances sake - CopyToBodyQue(pev); - } - - // respawn player - GetClassPtr( (CBasePlayer *)pev)->Spawn( ); - } - else - { // restart the entire server - SERVER_COMMAND("reload\n"); - } -} - -/* -============ -ClientKill - -Player entered the suicide command - -GLOBALS ASSUMED SET: g_ulModelIndexPlayer -============ -*/ -void ClientKill( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - - CBasePlayer *pl = (CBasePlayer*) CBasePlayer::Instance( pev ); - - if ( pl->m_fNextSuicideTime > gpGlobals->time ) - return; // prevent suiciding too ofter - - pl->m_fNextSuicideTime = gpGlobals->time + 1; // don't let them suicide for 5 seconds after suiciding - - // have the player kill themself - pev->health = 0; - pl->Killed( pev, GIB_ALWAYS ); - -// pev->modelindex = g_ulModelIndexPlayer; -// pev->frags -= 2; // extra penalty -// respawn( pev ); -} - -/* -=========== -ClientPutInServer - -called each time a player is spawned -============ -*/ -void ClientPutInServer( edict_t *pEntity ) -{ - CBasePlayer *pPlayer; - - entvars_t *pev = &pEntity->v; - - pPlayer = GetClassPtr((CBasePlayer *)pev); - pPlayer->SetCustomDecalFrames(-1); // Assume none; - - pPlayer->m_bHadFirstSpawn = false; - - // Allocate a CBasePlayer for pev, and call spawn - pPlayer->Spawn(); - - // Reset interpolation during first frame - pPlayer->pev->effects |= EF_NOINTERP; -} - - -#include "threewave_gamerules.h" - -//// HOST_SAY -// String comes in as -// say blah blah blah -// or as -// blah blah blah -// -void Host_Say( edict_t *pEntity, int teamonly ) -{ - CBasePlayer *client; - int j; - char *p; - char text[128]; - char szTemp[256]; - const char *cpSay = "say"; - const char *cpSayTeam = "say_team"; - const char *pcmd = CMD_ARGV(0); - - // We can get a raw string now, without the "say " prepended - if ( CMD_ARGC() == 0 ) - return; - - if ( !stricmp( pcmd, cpSay) || !stricmp( pcmd, cpSayTeam ) ) - { - if ( CMD_ARGC() >= 2 ) - { - p = (char *)CMD_ARGS(); - } - else - { - // say with a blank message, nothing to do - return; - } - } - else // Raw text, need to prepend argv[0] - { - if ( CMD_ARGC() >= 2 ) - { - sprintf( szTemp, "%s %s", ( char * )pcmd, (char *)CMD_ARGS() ); - } - else - { - // Just a one word command, use the first word...sigh - sprintf( szTemp, "%s", ( char * )pcmd ); - } - p = szTemp; - } - -// remove quotes if present - if (*p == '"') - { - p++; - p[strlen(p)-1] = 0; - } - -// make sure the text has content - char *pc; - for ( pc = p; pc != NULL && *pc != 0; pc++ ) - { - if ( isprint( *pc ) && !isspace( *pc ) ) - { - pc = NULL; // we've found an alphanumeric character, so text is valid - break; - } - } - if ( pc != NULL ) - return; // no character found, so say nothing - -// turn on color set 2 (color on, no sound) - if ( teamonly ) - sprintf( text, "%c(TEAM) %s: ", 2, STRING( pEntity->v.netname ) ); - else - sprintf( text, "%c%s: ", 2, STRING( pEntity->v.netname ) ); - - j = sizeof(text) - 2 - strlen(text); // -2 for /n and null terminator - if ( (int)strlen(p) > j ) - p[j] = 0; - - strcat( text, p ); - strcat( text, "\n" ); - - entvars_t *pev = &pEntity->v; - CBasePlayer* player = GetClassPtr((CBasePlayer *)pev); - - // loop through all players - // Start with the first player. - // This may return the world in single player if the client types something between levels or during spawn - // so check it, or it will infinite loop - - client = NULL; - while ( ((client = (CBasePlayer*)UTIL_FindEntityByClassname( client, "player" )) != NULL) && (!FNullEnt(client->edict())) ) - { - if ( !client->pev ) - continue; - - if ( client->edict() == pEntity ) - continue; - - if ( !(client->IsNetClient()) ) // Not a client ? (should never be true) - continue; - - // can the receiver hear the sender? or has he muted him? -#ifdef THREEWAVE - if ( ((CThreeWave *)g_pGameRules)->m_VoiceGameMgr.PlayerHasBlockedPlayer( client, player ) ) -#else - if ( ((CHalfLifeMultiplay *)g_pGameRules)->m_VoiceGameMgr.PlayerHasBlockedPlayer( client, player ) ) -#endif - continue; - - if ( teamonly && g_pGameRules->PlayerRelationship(client, CBaseEntity::Instance(pEntity)) != GR_TEAMMATE ) - continue; - - MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, client->pev ); - WRITE_BYTE( ENTINDEX(pEntity) ); - WRITE_STRING( text ); - MESSAGE_END(); - - } - - // print to the sending client - MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, &pEntity->v ); - WRITE_BYTE( ENTINDEX(pEntity) ); - WRITE_STRING( text ); - MESSAGE_END(); - - // echo to server console - g_engfuncs.pfnServerPrint( text ); - - char * temp; - if ( teamonly ) - temp = "say_team"; - else - temp = "say"; - -#if !defined( THREEWAVE ) - - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" %s \"%s\"\n", - STRING( pEntity->v.netname ), - GETPLAYERUSERID( pEntity ), - GETPLAYERAUTHID( pEntity ), - GETPLAYERUSERID( pEntity ), - temp, - p ); -#else - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" %s \"%s\"\n", - STRING( pEntity->v.netname ), - GETPLAYERUSERID( pEntity ), - GETPLAYERAUTHID( pEntity ), - GetTeamName( pEntity->v.team ), - temp, - p ); -#endif -} - - -/* -=========== -ClientCommand -called each time a player uses a "cmd" command -============ -*/ -extern float g_flWeaponCheat; - -// Use CMD_ARGV, CMD_ARGV, and CMD_ARGC to get pointers the character string command. -void ClientCommand( edict_t *pEntity ) -{ - const char *pcmd = CMD_ARGV(0); - - // Is the client spawned yet? - if ( !pEntity->pvPrivateData ) - return; - - entvars_t *pev = &pEntity->v; - - if ( FStrEq(pcmd, "say" ) ) - { - Host_Say( pEntity, 0 ); - } - else if ( FStrEq(pcmd, "say_team" ) ) - { - Host_Say( pEntity, 1 ); - } - else if ( FStrEq(pcmd, "fullupdate" ) ) - { - GetClassPtr((CBasePlayer *)pev)->ForceClientDllUpdate(); - } - else if ( FStrEq(pcmd, "give" ) ) - { - if ( g_flWeaponCheat != 0.0) - { - int iszItem = ALLOC_STRING( CMD_ARGV(1) ); // Make a copy of the classname - GetClassPtr((CBasePlayer *)pev)->GiveNamedItem( STRING(iszItem) ); - } - } - else if ( FStrEq(pcmd, "_firstspawn" ) ) - { - CBasePlayer * pPlayer = GetClassPtr((CBasePlayer *)pev); - - if ( pPlayer->m_bHadFirstSpawn == false && g_bHaveMOTD ) - { - pPlayer->m_bHadFirstSpawn = true; -#ifndef THREEWAVE - pPlayer->Spawn(); -#endif - - } - - - - } - - // QUAKECLASSIC - // Some commands removed: Drop Use Weapon - // Some added: qweapon -/* else if ( FStrEq(pcmd, "qweapon" ) ) - { - if ( CMD_ARGC() > 1 ) - { - GetClassPtr((CBasePlayer *)pev)->W_ChangeWeapon( atoi( CMD_ARGV(1) ) ); - } - }*/ - else if ( FStrEq(pcmd, "spectate" ) ) - { - CBasePlayer * pPlayer = GetClassPtr((CBasePlayer *)pev); - - if ( pPlayer->pev->flags & FL_PROXY ) - { - edict_t *pentSpawnSpot = g_pGameRules->GetPlayerSpawnSpot( pPlayer ); - pPlayer->StartObserver( pev->origin, VARS(pentSpawnSpot)->angles); - } - } - else if (FStrEq(pcmd, "lastinv" )) - { - GetClassPtr((CBasePlayer *)pev)->SelectLastItem(); - } - else if ( g_pGameRules->ClientCommand( GetClassPtr((CBasePlayer *)pev), pcmd ) ) - { - // MenuSelect returns true only if the command is properly handled, so don't print a warning - } - else if ( FStrEq( pcmd, "specmode" ) ) // new spectator mode - { - CBasePlayer * pPlayer = GetClassPtr((CBasePlayer *)pev); - if ( pPlayer->IsObserver() ) - pPlayer->Observer_SetMode( atoi( CMD_ARGV(1) ) ); - } - else if ( FStrEq( pcmd, "follownext" ) ) // follow next player - { - CBasePlayer * pPlayer = GetClassPtr((CBasePlayer *)pev); - if ( pPlayer->IsObserver() ) - pPlayer->Observer_FindNextPlayer(); - } - else - { - // tell the user they entered an unknown command - ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, UTIL_VarArgs( "Unknown command: %s\n", pcmd ) ); - } -} - - -/* -======================== -ClientUserInfoChanged - -called after the player changes -userinfo - gives dll a chance to modify it before -it gets sent into the rest of the engine. -======================== -*/ -void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ) -{ - // Is the client spawned yet? - if ( !pEntity->pvPrivateData ) - return; - - // msg everyone if someone changes their name, and it isn't the first time (changing no name to current name) - if ( pEntity->v.netname && STRING(pEntity->v.netname)[0] != 0 && !FStrEq( STRING(pEntity->v.netname), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" )) ) - { - char text[256]; - sprintf( text, "* %s changed name to %s\n", STRING(pEntity->v.netname), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); - MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); - WRITE_BYTE( ENTINDEX(pEntity) ); - WRITE_STRING( text ); - MESSAGE_END(); - -#if !defined( THREEWAVE ) - - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" changed name to \"%s\"\n", - STRING( pEntity->v.netname ), - GETPLAYERUSERID( pEntity ), - GETPLAYERAUTHID( pEntity ), - GETPLAYERUSERID( pEntity ), - g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); -#else - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" changed name to \"%s\"\n", - STRING( pEntity->v.netname ), - GETPLAYERUSERID( pEntity ), - GETPLAYERAUTHID( pEntity ), - GetTeamName( pEntity->v.team ), - g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); -#endif - } - - // QUAKECLASSIC - // Weapon switching behaviour - ((CBasePlayer*)pEntity)->m_iWeaponSwitch = 8; - char *st = g_engfuncs.pfnInfoKeyValue( infobuffer, "w_switch" ); - if (st && st[0]) - { - ((CBasePlayer*)pEntity)->m_iWeaponSwitch = atoi(st); - } - ((CBasePlayer*)pEntity)->m_iBackpackSwitch = 8; - st = g_engfuncs.pfnInfoKeyValue( infobuffer, "b_switch" ); - if (st && st[0]) - { - ((CBasePlayer*)pEntity)->m_iBackpackSwitch = atoi(st); - } - - g_pGameRules->ClientUserInfoChanged( GetClassPtr((CBasePlayer *)&pEntity->v), infobuffer ); - -} - -static int g_serveractive = 0; - -void ServerDeactivate( void ) -{ - // It's possible that the engine will call this function more times than is necessary - // Therefore, only run it one time for each call to ServerActivate - if ( g_serveractive != 1 ) - { - return; - } - - g_serveractive = 0; - - // Peform any shutdown operations here... - // -} - -void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) -{ - int i; - CBaseEntity *pClass; - - // Every call to ServerActivate should be matched by a call to ServerDeactivate - g_serveractive = 1; - - // Clients have not been initialized yet - for ( i = 0; i < edictCount; i++ ) - { - if ( pEdictList[i].free ) - continue; - - // Clients aren't necessarily initialized until ClientPutInServer() - if ( i < clientMax || !pEdictList[i].pvPrivateData ) - continue; - - pClass = CBaseEntity::Instance( &pEdictList[i] ); - // Activate this entity if it's got a class & isn't dormant - if ( pClass && !(pClass->pev->flags & FL_DORMANT) ) - { - pClass->Activate(); - } - else - { - ALERT( at_console, "Can't instance %s\n", STRING(pEdictList[i].v.classname) ); - } - } - - // Link user messages here to make sure first client can get them... - LinkUserMessages(); -} - - -/* -================ -PlayerPreThink - -Called every frame before physics are run -================ -*/ -void PlayerPreThink( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->PreThink( ); -} - -/* -================ -PlayerPostThink - -Called every frame after physics are run -================ -*/ -void PlayerPostThink( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->PostThink( ); -} - - - -void ParmsNewLevel( void ) -{ -} - - -void ParmsChangeLevel( void ) -{ - // retrieve the pointer to the save data - SAVERESTOREDATA *pSaveData = (SAVERESTOREDATA *)gpGlobals->pSaveData; - - if ( pSaveData ) - pSaveData->connectionCount = BuildChangeList( pSaveData->levelList, MAX_LEVEL_CONNECTIONS ); -} - - -// -// GLOBALS ASSUMED SET: g_ulFrameCount -// -void StartFrame( void ) -{ - if ( g_pGameRules ) - g_pGameRules->Think(); - - if ( g_fGameOver ) - return; - - gpGlobals->teamplay = CVAR_GET_FLOAT("teamplay"); - g_iSkillLevel = CVAR_GET_FLOAT("skill"); - g_ulFrameCount++; -} - - -void ClientPrecache( void ) -{ - // setup precaches always needed - PRECACHE_SOUND("player/sprayer.wav"); // spray paint sound for PreAlpha - - // PRECACHE_SOUND("player/pl_jumpland2.wav"); // UNDONE: play 2x step sound - - PRECACHE_SOUND("player/pl_fallpain2.wav"); - PRECACHE_SOUND("player/pl_fallpain3.wav"); - - PRECACHE_SOUND("player/pl_step1.wav"); // walk on concrete - PRECACHE_SOUND("player/pl_step2.wav"); - PRECACHE_SOUND("player/pl_step3.wav"); - PRECACHE_SOUND("player/pl_step4.wav"); - - PRECACHE_SOUND("common/npc_step1.wav"); // NPC walk on concrete - PRECACHE_SOUND("common/npc_step2.wav"); - PRECACHE_SOUND("common/npc_step3.wav"); - PRECACHE_SOUND("common/npc_step4.wav"); - - PRECACHE_SOUND("player/pl_metal1.wav"); // walk on metal - PRECACHE_SOUND("player/pl_metal2.wav"); - PRECACHE_SOUND("player/pl_metal3.wav"); - PRECACHE_SOUND("player/pl_metal4.wav"); - - PRECACHE_SOUND("player/pl_dirt1.wav"); // walk on dirt - PRECACHE_SOUND("player/pl_dirt2.wav"); - PRECACHE_SOUND("player/pl_dirt3.wav"); - PRECACHE_SOUND("player/pl_dirt4.wav"); - - PRECACHE_SOUND("player/pl_duct1.wav"); // walk in duct - PRECACHE_SOUND("player/pl_duct2.wav"); - PRECACHE_SOUND("player/pl_duct3.wav"); - PRECACHE_SOUND("player/pl_duct4.wav"); - - PRECACHE_SOUND("player/pl_grate1.wav"); // walk on grate - PRECACHE_SOUND("player/pl_grate2.wav"); - PRECACHE_SOUND("player/pl_grate3.wav"); - PRECACHE_SOUND("player/pl_grate4.wav"); - - PRECACHE_SOUND("player/pl_slosh1.wav"); // walk in shallow water - PRECACHE_SOUND("player/pl_slosh2.wav"); - PRECACHE_SOUND("player/pl_slosh3.wav"); - PRECACHE_SOUND("player/pl_slosh4.wav"); - - PRECACHE_SOUND("player/pl_tile1.wav"); // walk on tile - PRECACHE_SOUND("player/pl_tile2.wav"); - PRECACHE_SOUND("player/pl_tile3.wav"); - PRECACHE_SOUND("player/pl_tile4.wav"); - PRECACHE_SOUND("player/pl_tile5.wav"); - - PRECACHE_SOUND("player/pl_swim1.wav"); // breathe bubbles - PRECACHE_SOUND("player/pl_swim2.wav"); - PRECACHE_SOUND("player/pl_swim3.wav"); - PRECACHE_SOUND("player/pl_swim4.wav"); - - PRECACHE_SOUND("player/pl_ladder1.wav"); // climb ladder rung - PRECACHE_SOUND("player/pl_ladder2.wav"); - PRECACHE_SOUND("player/pl_ladder3.wav"); - PRECACHE_SOUND("player/pl_ladder4.wav"); - - PRECACHE_SOUND("player/pl_wade1.wav"); // wade in water - PRECACHE_SOUND("player/pl_wade2.wav"); - PRECACHE_SOUND("player/pl_wade3.wav"); - PRECACHE_SOUND("player/pl_wade4.wav"); - - PRECACHE_SOUND("debris/wood1.wav"); // hit wood texture - PRECACHE_SOUND("debris/wood2.wav"); - PRECACHE_SOUND("debris/wood3.wav"); - - PRECACHE_SOUND("plats/train_use1.wav"); // use a train - - PRECACHE_SOUND("buttons/spark5.wav"); // hit computer texture - PRECACHE_SOUND("buttons/spark6.wav"); - PRECACHE_SOUND("debris/glass1.wav"); - PRECACHE_SOUND("debris/glass2.wav"); - PRECACHE_SOUND("debris/glass3.wav"); - - PRECACHE_SOUND( SOUND_FLASHLIGHT_ON ); - PRECACHE_SOUND( SOUND_FLASHLIGHT_OFF ); - -// player gib sounds - PRECACHE_SOUND("common/bodysplat.wav"); - -// player pain sounds - PRECACHE_SOUND("player/pain1.wav"); - PRECACHE_SOUND("player/pain2.wav"); - PRECACHE_SOUND("player/pain3.wav"); - PRECACHE_SOUND("player/pain4.wav"); - PRECACHE_SOUND("player/pain5.wav"); - PRECACHE_SOUND("player/pain6.wav"); - PRECACHE_SOUND("player/drown1.wav"); - PRECACHE_SOUND("player/drown2.wav"); - PRECACHE_SOUND("player/lburn1.wav"); - PRECACHE_SOUND("player/lburn2.wav"); - PRECACHE_SOUND("player/death1.wav"); - PRECACHE_SOUND("player/death2.wav"); - PRECACHE_SOUND("player/death3.wav"); - PRECACHE_SOUND("player/death4.wav"); - PRECACHE_SOUND("player/death5.wav"); - - PRECACHE_SOUND("player/h2odeath.wav"); - - PRECACHE_MODEL("models/player.mdl"); - - // hud sounds - - PRECACHE_SOUND("common/wpn_hudoff.wav"); - PRECACHE_SOUND("common/wpn_hudon.wav"); - PRECACHE_SOUND("common/wpn_moveselect.wav"); - PRECACHE_SOUND("common/wpn_select.wav"); - PRECACHE_SOUND("common/wpn_denyselect.wav"); - - PRECACHE_SOUND("player/gib.wav"); - - PRECACHE_MODEL("models/gib_1.mdl"); - PRECACHE_MODEL("models/gib_2.mdl"); - PRECACHE_MODEL("models/gib_3.mdl"); - - PRECACHE_SOUND("player/plyrjmp8.wav"); - -#ifdef THREEWAVE - - PRECACHE_MODEL("models/rune_resist.mdl"); - PRECACHE_MODEL("models/rune_haste.mdl"); - PRECACHE_MODEL("models/rune_regen.mdl"); - PRECACHE_MODEL("models/rune_strength.mdl"); - - PRECACHE_SOUND("rune/rune1.wav"); - PRECACHE_SOUND("rune/rune2.wav"); - PRECACHE_SOUND("rune/rune22.wav"); // Quad + Strength Rune. - PRECACHE_SOUND("rune/rune3.wav"); - PRECACHE_SOUND("rune/rune4.wav"); - - PRECACHE_MODEL("models/hook.mdl"); - - PRECACHE_MODEL("sprites/rope.spr"); - - PRECACHE_SOUND("weapons/grfire.wav"); - PRECACHE_SOUND("weapons/grhang.wav"); - PRECACHE_SOUND("weapons/grhit.wav"); - PRECACHE_SOUND("weapons/grpull.wav"); - PRECACHE_SOUND("weapons/grreset.wav"); - - g_usHook = PRECACHE_EVENT( 1, "events/hook.sc" ); - g_usCable = PRECACHE_EVENT( 1, "events/cable.sc" ); - g_usCarried = PRECACHE_EVENT( 1, "events/follow.sc" ); - g_usFlagSpawn = PRECACHE_EVENT( 1, "events/flagspawn.sc" ); - -#endif - - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/p_crowbar.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/p_light.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/p_nail.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/p_nail2.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/p_rock.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/p_rock2.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/p_shot.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/p_shot2.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/spike.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/rocket.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/grenade.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/backpack.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/backpack.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/armor_g.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/armor_r.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/armor_y.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/armor_y.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/b_nail0.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/b_nail1.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/g_light.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/g_nail.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/g_nail2.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/g_rock.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/g_rock2.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/g_shot2.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/pow_invis.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/pow_quad.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/pow_invuln.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/suit.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/w_battery.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/w_batteryl.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/w_medkit.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/w_medkitl.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/w_medkits.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/w_rpgammo.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/w_rpgammo_big.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/w_shotbox.mdl"); - ENGINE_FORCE_UNMODIFIED(force_exactfile, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ),"models/w_shotbox_big.mdl"); - - g_sGibbed = PRECACHE_EVENT( 1, "events/gibs.sc" ); - g_sTeleport = PRECACHE_EVENT( 1, "events/teleport.sc" ); - g_sTrail = PRECACHE_EVENT( 1, "events/trail.sc" ); - g_sExplosion = PRECACHE_EVENT( 1, "events/explosion.sc" ); - g_usPowerUp = PRECACHE_EVENT( 1, "events/powerup.sc" ); - - if (giPrecacheGrunt) - UTIL_PrecacheOther("monster_human_grunt"); -} - -/* -================ -Sys_Error - -Engine is going to shut down, allows setting a breakpoint in game .dll to catch that occasion -================ -*/ -void Sys_Error( const char *error_string ) -{ - // Default case, do nothing. MOD AUTHORS: Add code ( e.g., _asm { int 3 }; here to cause a breakpoint for debugging your game .dlls -} - -/* -=============== -const char *GetGameDescription() - -Returns the descriptive name of this .dll. E.g., Half-Life, or Team Fortress 2 -=============== -*/ -const char *GetGameDescription() -{ - if ( g_pGameRules ) // this function may be called before the world has spawned, and the game rules initialized - return g_pGameRules->GetGameDescription(); - else - return "DMC"; -} - -/* -================ -PlayerCustomization - -A new player customization has been registered on the server -UNDONE: This only sets the # of frames of the spray can logo -animation right now. -================ -*/ -void PlayerCustomization( edict_t *pEntity, customization_t *pCust ) -{ - entvars_t *pev = &pEntity->v; - CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity); - - if (!pPlayer) - { - ALERT(at_console, "PlayerCustomization: Couldn't get player!\n"); - return; - } - - if (!pCust) - { - ALERT(at_console, "PlayerCustomization: NULL customization!\n"); - return; - } - - switch (pCust->resource.type) - { - case t_decal: - pPlayer->SetCustomDecalFrames(pCust->nUserData2); // Second int is max # of frames. - break; - case t_sound: - case t_skin: - case t_model: - // Ignore for now. - break; - default: - ALERT(at_console, "PlayerCustomization: Unknown customization type!\n"); - break; - } -} - -/* -================ -SpectatorConnect - -A spectator has joined the game -================ -*/ -void SpectatorConnect( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->SpectatorConnect( ); -} - -/* -================ -SpectatorConnect - -A spectator has left the game -================ -*/ -void SpectatorDisconnect( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->SpectatorDisconnect( ); -} - -/* -================ -SpectatorConnect - -A spectator has sent a usercmd -================ -*/ -void SpectatorThink( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->SpectatorThink( ); -} - -//////////////////////////////////////////////////////// -// PAS and PVS routines for client messaging -// - -/* -================ -SetupVisibility - -A client can have a separate "view entity" indicating that his/her view should depend on the origin of that -view entity. If that's the case, then pViewEntity will be non-NULL and will be used. Otherwise, the current -entity's origin is used. Either is offset by the view_ofs to get the eye position. - -From the eye position, we set up the PAS and PVS to use for filtering network messages to the client. At this point, we could - override the actual PAS or PVS values, or use a different origin. - -NOTE: Do not cache the values of pas and pvs, as they depend on reusable memory in the engine, they are only good for this one frame -================ -*/ -void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas ) -{ - Vector org; - edict_t *pView = pClient; - - // Find the client's PVS - if ( pViewEntity ) - { - pView = pViewEntity; - } - - if ( pClient->v.flags & FL_PROXY ) - { - *pvs = NULL; // the spectator proxy sees - *pas = NULL; // and hears everything - return; - } - org = pView->v.origin + pView->v.view_ofs; - if ( pView->v.flags & FL_DUCKING ) - { - org = org + ( VEC_HULL_MIN - VEC_DUCK_HULL_MIN ); - } - - *pvs = ENGINE_SET_PVS ( (float *)&org ); - *pas = ENGINE_SET_PAS ( (float *)&org ); -} - -#include "entity_state.h" - -/* -AddToFullPack - -Return 1 if the entity state has been filled in for the ent and the entity will be propagated to the client, 0 otherwise - -state is the server maintained copy of the state info that is transmitted to the client -a MOD could alter values copied into state to send the "host" a different look for a particular entity update, etc. -e and ent are the entity that is being added to the update, if 1 is returned -host is the player's edict of the player whom we are sending the update to -player is 1 if the ent/e is a player and 0 otherwise -pSet is either the PAS or PVS that we previous set up. We can use it to ask the engine to filter the entity against the PAS or PVS. -we could also use the pas/ pvs that we set in SetupVisibility, if we wanted to. Caching the value is valid in that case, but still only for the current frame -*/ -int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ) -{ - int i; - - // don't send if flagged for NODRAW and it's not the host getting the message - if ( ( ent->v.effects & EF_NODRAW ) && - ( ent != host ) ) - return 0; - - // Ignore ents without valid / visible models - if ( !ent->v.modelindex || !STRING( ent->v.model ) ) - return 0; - - // Don't send spectators to other players - if ( ( ent->v.flags & FL_SPECTATOR ) && ( ent != host ) ) - { - return 0; - } - - // Ignore if not the host and not touching a PVS/PAS leaf - // If pSet is NULL, then the test will always succeed and the entity will be added to the update - if ( ent != host ) - { - //We still want to show all ents for a quick period ( max 700ms of lag ) for when we predict teleporters - //if we don't do this, the entities on the other side wont show until the real origin comes thru and reaches - //the new PVS/PAS. - if ( !ENGINE_CHECK_VISIBILITY( (const struct edict_s *)ent, pSet ) && ent->v.fuser4 < gpGlobals->time ) - { - return 0; - } - } - - - // Don't send entity to local client if the client says it's predicting the entity itself. - if ( ent->v.flags & FL_SKIPLOCALHOST ) - { - if ( ( hostflags & 1 ) && ( ent->v.owner == host ) ) - return 0; - } - - if ( host->v.groupinfo ) - { - UTIL_SetGroupTrace( host->v.groupinfo, GROUP_OP_AND ); - - // Should always be set, of course - if ( ent->v.groupinfo ) - { - if ( g_groupop == GROUP_OP_AND ) - { - if ( !(ent->v.groupinfo & host->v.groupinfo ) ) - return 0; - } - else if ( g_groupop == GROUP_OP_NAND ) - { - if ( ent->v.groupinfo & host->v.groupinfo ) - return 0; - } - } - - UTIL_UnsetGroupTrace(); - } - - memset( state, 0, sizeof( *state ) ); - - // Assign index so we can track this entity from frame to frame and - // delta from it. - state->number = e; - state->entityType = ENTITY_NORMAL; - - // Flag custom entities. - if ( ent->v.flags & FL_CUSTOMENTITY ) - { - state->entityType = ENTITY_BEAM; - } - - // - // Copy state data - // - - // Round animtime to nearest millisecond - state->animtime = (int)(1000.0 * ent->v.animtime ) / 1000.0; - - memcpy( state->origin, ent->v.origin, 3 * sizeof( float ) ); - memcpy( state->angles, ent->v.angles, 3 * sizeof( float ) ); - memcpy( state->mins, ent->v.mins, 3 * sizeof( float ) ); - memcpy( state->maxs, ent->v.maxs, 3 * sizeof( float ) ); - - memcpy( state->startpos, ent->v.startpos, 3 * sizeof( float ) ); - memcpy( state->endpos, ent->v.endpos, 3 * sizeof( float ) ); - - state->impacttime = ent->v.impacttime; - state->starttime = ent->v.starttime; - - state->modelindex = ent->v.modelindex; - - state->frame = ent->v.frame; - state->skin = ent->v.skin; - state->effects = ent->v.effects; - - // This non-player entity is being moved by the game .dll and not the physics simulation system - // make sure that we interpolate it's position on the client if it moves - if ( !player && - ent->v.animtime && - ent->v.velocity[ 0 ] == 0 && - ent->v.velocity[ 1 ] == 0 && - ent->v.velocity[ 2 ] == 0 ) - { - state->eflags |= EFLAG_SLERP; - } - - state->scale = ent->v.scale; - state->solid = ent->v.solid; - state->colormap = ent->v.colormap; - state->movetype = ent->v.movetype; - state->sequence = ent->v.sequence; - state->framerate = ent->v.framerate; - state->body = ent->v.body; - - for (i = 0; i < 4; i++) - { - state->controller[i] = ent->v.controller[i]; - } - - for (i = 0; i < 2; i++) - { - state->blending[i] = ent->v.blending[i]; - } - - state->rendermode = ent->v.rendermode; - state->renderamt = ent->v.renderamt; - state->renderfx = ent->v.renderfx; - state->rendercolor.r = ent->v.rendercolor[0]; - state->rendercolor.g = ent->v.rendercolor[1]; - state->rendercolor.b = ent->v.rendercolor[2]; - - state->aiment = 0; - if ( ent->v.aiment ) - { - state->aiment = ENTINDEX( ent->v.aiment ); - } - - state->owner = 0; - if ( ent->v.owner ) - { - int owner = ENTINDEX( ent->v.owner ); - - // Only care if owned by a player - if ( owner >= 1 && owner <= gpGlobals->maxClients ) - { - state->owner = owner; - } - } - // Special stuff for players only - if ( player ) - { - memcpy( state->basevelocity, ent->v.basevelocity, 3 * sizeof( float ) ); - - state->weaponmodel = MODEL_INDEX( STRING( ent->v.weaponmodel ) ); - state->gaitsequence = ent->v.gaitsequence; - state->spectator = ent->v.flags & FL_SPECTATOR; - state->friction = ent->v.friction; - - state->gravity = ent->v.gravity; -// state->team = ent->v.team; -// state->playerclass = ent->v.playerclass; - state->usehull = ( ent->v.flags & FL_DUCKING ) ? 1 : 0; - state->health = ent->v.health; - } - - return 1; -} - -// defaults for clientinfo messages -#define DEFAULT_VIEWHEIGHT 28 - -/* -=================== -CreateBaseline - -Creates baselines used for network encoding, especially for player data since players are not spawned until connect time. -=================== -*/ -void CreateBaseline( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs ) -{ - baseline->origin = entity->v.origin; - baseline->angles = entity->v.angles; - baseline->frame = entity->v.frame; - baseline->skin = (short)entity->v.skin; - - // render information - baseline->rendermode = (byte)entity->v.rendermode; - baseline->renderamt = (byte)entity->v.renderamt; - baseline->rendercolor.r = (byte)entity->v.rendercolor[0]; - baseline->rendercolor.g = (byte)entity->v.rendercolor[1]; - baseline->rendercolor.b = (byte)entity->v.rendercolor[2]; - baseline->renderfx = (byte)entity->v.renderfx; - - if ( player ) - { - baseline->mins = player_mins; - baseline->maxs = player_maxs; - - baseline->colormap = eindex; - baseline->modelindex = playermodelindex; - baseline->friction = 1.0; - baseline->movetype = MOVETYPE_WALK; - - baseline->scale = entity->v.scale; - baseline->solid = SOLID_SLIDEBOX; - baseline->framerate = 1.0; - baseline->gravity = 1.0; - - } - else - { - baseline->mins = entity->v.mins; - baseline->maxs = entity->v.maxs; - - baseline->colormap = 0; - baseline->modelindex = entity->v.modelindex;//SV_ModelIndex(pr_strings + entity->v.model); - baseline->movetype = entity->v.movetype; - - baseline->scale = entity->v.scale; - baseline->solid = entity->v.solid; - baseline->framerate = entity->v.framerate; - baseline->gravity = entity->v.gravity; - } -} - -typedef struct -{ - char name[32]; - int field; -} entity_field_alias_t; - -#define FIELD_ORIGIN0 0 -#define FIELD_ORIGIN1 1 -#define FIELD_ORIGIN2 2 -#define FIELD_ANGLES0 3 -#define FIELD_ANGLES1 4 -#define FIELD_ANGLES2 5 - -static entity_field_alias_t entity_field_alias[]= -{ - { "origin[0]", 0 }, - { "origin[1]", 0 }, - { "origin[2]", 0 }, - { "angles[0]", 0 }, - { "angles[1]", 0 }, - { "angles[2]", 0 }, -}; - -void Entity_FieldInit( struct delta_s *pFields ) -{ - entity_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN0 ].name ); - entity_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN1 ].name ); - entity_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN2 ].name ); - entity_field_alias[ FIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES0 ].name ); - entity_field_alias[ FIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES1 ].name ); - entity_field_alias[ FIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES2 ].name ); -} - -/* -================== -Entity_Encode - -Callback for sending entity_state_t info over network. -FIXME: Move to script -================== -*/ -void Entity_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) -{ - entity_state_t *f, *t; - - int localplayer = 0; - static int initialized = 0; - - if ( !initialized ) - { - Entity_FieldInit( pFields ); - initialized = 1; - } - - f = (entity_state_t *)from; - t = (entity_state_t *)to; - - // Never send origin to local player, it's sent with more resolution in clientdata_t structure - localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); - if ( localplayer ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } - - if ( ( t->impacttime != 0 ) && ( t->starttime != 0 ) ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ANGLES0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ANGLES1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ANGLES2 ].field ); - } - - if ( ( t->movetype == MOVETYPE_FOLLOW ) && - ( t->aiment != 0 ) ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } - else if ( t->aiment != f->aiment ) - { - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } -} - -static entity_field_alias_t player_field_alias[]= -{ - { "origin[0]", 0 }, - { "origin[1]", 0 }, - { "origin[2]", 0 }, -}; - -void Player_FieldInit( struct delta_s *pFields ) -{ - player_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN0 ].name ); - player_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN1 ].name ); - player_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN2 ].name ); -} - -/* -================== -Player_Encode - -Callback for sending entity_state_t for players info over network. -================== -*/ -void Player_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) -{ - entity_state_t *f, *t; - int localplayer = 0; - static int initialized = 0; - - if ( !initialized ) - { - Player_FieldInit( pFields ); - initialized = 1; - } - - f = (entity_state_t *)from; - t = (entity_state_t *)to; - - // Never send origin to local player, it's sent with more resolution in clientdata_t structure - localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); - if ( localplayer ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } - - if ( ( t->movetype == MOVETYPE_FOLLOW ) && - ( t->aiment != 0 ) ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } - else if ( t->aiment != f->aiment ) - { - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } -} - -#define CUSTOMFIELD_ORIGIN0 0 -#define CUSTOMFIELD_ORIGIN1 1 -#define CUSTOMFIELD_ORIGIN2 2 -#define CUSTOMFIELD_ANGLES0 3 -#define CUSTOMFIELD_ANGLES1 4 -#define CUSTOMFIELD_ANGLES2 5 -#define CUSTOMFIELD_SKIN 6 -#define CUSTOMFIELD_SEQUENCE 7 -#define CUSTOMFIELD_ANIMTIME 8 - -entity_field_alias_t custom_entity_field_alias[]= -{ - { "origin[0]", 0 }, - { "origin[1]", 0 }, - { "origin[2]", 0 }, - { "angles[0]", 0 }, - { "angles[1]", 0 }, - { "angles[2]", 0 }, - { "skin", 0 }, - { "sequence", 0 }, - { "animtime", 0 }, -}; - -void Custom_Entity_FieldInit( struct delta_s *pFields ) -{ - custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].name ); - custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].name ); -} - -/* -================== -Custom_Encode - -Callback for sending entity_state_t info ( for custom entities ) over network. -FIXME: Move to script -================== -*/ -void Custom_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) -{ - entity_state_t *f, *t; - int beamType; - static int initialized = 0; - - if ( !initialized ) - { - Custom_Entity_FieldInit( pFields ); - initialized = 1; - } - - f = (entity_state_t *)from; - t = (entity_state_t *)to; - - beamType = t->rendermode & 0x0f; - - if ( beamType != BEAM_POINTS && beamType != BEAM_ENTPOINT ) - { - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field ); - } - - if ( beamType != BEAM_POINTS ) - { - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field ); - } - - if ( beamType != BEAM_ENTS && beamType != BEAM_ENTPOINT ) - { - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field ); - } - - // animtime is compared by rounding first - // see if we really shouldn't actually send it - if ( (int)f->animtime == (int)t->animtime ) - { - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field ); - } -} - -/* -================= -RegisterEncoders - -Allows game .dll to override network encoding of certain types of entities and tweak values, etc. -================= -*/ -void RegisterEncoders( void ) -{ - DELTA_ADDENCODER( "Entity_Encode", Entity_Encode ); - DELTA_ADDENCODER( "Custom_Encode", Custom_Encode ); - DELTA_ADDENCODER( "Player_Encode", Player_Encode ); -} - -int GetWeaponData( struct edict_s *player, struct weapon_data_s *info ) -{ - int i; - weapon_data_t *item; - entvars_t *pev = &player->v; - CBasePlayer *pl = ( CBasePlayer *) CBasePlayer::Instance( pev ); - CBasePlayerWeapon *gun; - - ItemInfo II; - - memset( info, 0, 32 * sizeof( weapon_data_t ) ); - - if ( !pl ) - return 1; - - // go through all of the weapons and make a list of the ones to pack - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - if ( pl->m_rgpPlayerItems[ i ] ) - { - // there's a weapon here. Should I pack it? - CBasePlayerItem *pPlayerItem = pl->m_rgpPlayerItems[ i ]; - - while ( pPlayerItem ) - { - gun = (CBasePlayerWeapon *)pPlayerItem->GetWeaponPtr(); - if ( gun && gun->UseDecrement() ) - { - // Get The ID. - memset( &II, 0, sizeof( II ) ); - gun->GetItemInfo( &II ); - - if ( II.iId >= 0 && II.iId < 32 ) - { - item = &info[ II.iId ]; - - item->m_iId = II.iId; - item->m_iClip = gun->m_iClip; - - item->m_flTimeWeaponIdle = V_max( gun->m_flTimeWeaponIdle, -0.001 ); - item->m_flNextPrimaryAttack = V_max( gun->m_flNextPrimaryAttack, -0.001 ); - item->m_flNextSecondaryAttack = V_max( gun->m_flNextSecondaryAttack, -0.001 ); - item->m_fInReload = gun->m_fInReload; - } - } - pPlayerItem = pPlayerItem->m_pNext; - } - } - } - return 1; -} - -/* -================= -UpdateClientData - -Data sent to current client only -engine sets cd to 0 before calling. -================= -*/ -void UpdateClientData ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ) -{ - cd->flags = ent->v.flags; - cd->health = ent->v.health; - - cd->viewmodel = MODEL_INDEX( STRING( ent->v.viewmodel ) ); - cd->waterlevel = ent->v.waterlevel; - cd->watertype = ent->v.watertype; - //cd->weapons = ent->v.weapons; - - // Vectors - cd->origin = ent->v.origin; - cd->velocity = ent->v.velocity; - cd->view_ofs = ent->v.view_ofs; - cd->punchangle = ent->v.punchangle; - - cd->bInDuck = ent->v.bInDuck; - cd->flTimeStepSound = ent->v.flTimeStepSound; - cd->flDuckTime = ent->v.flDuckTime; - cd->flSwimTime = ent->v.flSwimTime; - cd->waterjumptime = ent->v.teleport_time; - - strcpy( cd->physinfo, ENGINE_GETPHYSINFO( ent ) ); - - cd->maxspeed = ent->v.maxspeed; - cd->fov = ent->v.fov; - cd->weaponanim = ent->v.weaponanim; - - cd->pushmsec = ent->v.pushmsec; - - // Observer - cd->iuser1 = ent->v.iuser1; - cd->iuser2 = ent->v.iuser2; - cd->iuser3 = ent->v.iuser3; - - if ( sendweapons ) - { - entvars_t *pev = (entvars_t *)&ent->v; - CBasePlayer *pl = ( CBasePlayer *) CBasePlayer::Instance( pev ); - - if ( pl ) - { - cd->m_flNextAttack = pl->m_flNextAttack; - cd->weapons = pl->m_iQuakeItems; - - if ( pl->m_pActiveItem ) - { - CBasePlayerWeapon *gun; - gun = (CBasePlayerWeapon *)pl->m_pActiveItem->GetWeaponPtr(); - if ( gun && gun->UseDecrement() ) - { - ItemInfo II; - memset( &II, 0, sizeof( II ) ); - gun->GetItemInfo( &II ); - - cd->m_iId = II.iId; - } - } - - cd->fuser1 = (float)pl->m_iQuakeWeapon; - cd->iuser4 = gpGlobals->deathmatch; - cd->fuser2 = pl->m_iNailOffset > 0 ? 1.0 : 0.0; -#ifdef THREEWAVE - cd->fuser3 = (float)pl->m_iRuneStatus; -#endif - - cd->iuser3 = pl->m_iQuakeItems; - - cd->ammo_shells = pl->m_iAmmoShells; - cd->ammo_nails = pl->m_iAmmoNails; - cd->ammo_cells = pl->m_iAmmoCells; - cd->ammo_rockets = pl->m_iAmmoRockets; - } - } -} - -/* -================= -CmdStart - -We're about to run this usercmd for the specified player. We can set up groupinfo and masking here, etc. -This is the time to examine the usercmd for anything extra. This call happens even if think does not. -================= -*/ -void CmdStart( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed ) -{ - entvars_t *pev = (entvars_t *)&player->v; - CBasePlayer *pl = ( CBasePlayer *) CBasePlayer::Instance( pev ); - - if( !pl ) - return; - - if ( cmd->weaponselect != 0 ) - { - usercmd_t *c = (usercmd_t *)cmd; - pl->W_ChangeWeapon( c->weaponselect ); - c->weaponselect = 0; - } - - if ( pl->pev->groupinfo != 0 ) - { - UTIL_SetGroupTrace( pl->pev->groupinfo, GROUP_OP_AND ); - } - - pl->random_seed = random_seed; -} - -/* -================= -CmdEnd - -Each cmdstart is exactly matched with a cmd end, clean up any group trace flags, etc. here -================= -*/ -void CmdEnd ( const edict_t *player ) -{ - entvars_t *pev = (entvars_t *)&player->v; - CBasePlayer *pl = ( CBasePlayer *) CBasePlayer::Instance( pev ); - - if( !pl ) - return; - if ( pl->pev->groupinfo != 0 ) - { - UTIL_UnsetGroupTrace(); - } -} - -/* -================================ -ConnectionlessPacket - - Return 1 if the packet is valid. Set response_buffer_size if you want to send a response packet. Incoming, it holds the max - size of the response_buffer, so you must zero it out if you choose not to respond. -================================ -*/ -int ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ) -{ - // Parse stuff from args - int max_buffer_size = *response_buffer_size; - - // Zero it out since we aren't going to respond. - // If we wanted to response, we'd write data into response_buffer - *response_buffer_size = 0; - - // Since we don't listen for anything here, just respond that it's a bogus message - // If we didn't reject the message, we'd return 1 for success instead. - return 0; -} - -/* -================================ -GetHullBounds - - Engine calls this to enumerate player collision hulls, for prediction. Return 0 if the hullnumber doesn't exist. -================================ -*/ -int GetHullBounds( int hullnumber, float *mins, float *maxs ) -{ - int iret = 0; - - switch ( hullnumber ) - { - case 0: // Normal player - mins = Vector(-16, -16, -32); - maxs = Vector(16, 16, 32); - iret = 1; - break; - case 1: // Crouched player - mins = Vector(-16, -16, -32); - maxs = Vector(16, 16, 32); - iret = 1; - break; - case 2: // Point based hull - mins = Vector( 0, 0, 0 ); - maxs = Vector( 0, 0, 0 ); - iret = 1; - break; - } - - return iret; -} - -/* -================================ -CreateInstancedBaselines - -Create pseudo-baselines for items that aren't placed in the map at spawn time, but which are likely -to be created during play ( e.g., grenades, ammo packs, projectiles, corpses, etc. ) -================================ -*/ -void CreateInstancedBaselines ( void ) -{ - int iret = 0; - entity_state_t state; - - memset( &state, 0, sizeof( state ) ); - - // Create any additional baselines here for things like grendates, etc. - // iret = ENGINE_INSTANCE_BASELINE( pc->pev->classname, &state ); - - // Destroy objects. - //UTIL_Remove( pc ); -} - -/* -================================ -InconsistentFile - -One of the ENGINE_FORCE_UNMODIFIED files failed the consistency check for the specified player - Return 0 to allow the client to continue, 1 to force immediate disconnection ( with an optional disconnect message of up to 256 characters ) -================================ -*/ -int InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message ) -{ - // Server doesn't care? - if ( CVAR_GET_FLOAT( "mp_consistency" ) != 1 ) - return 0; - - // Default behavior is to kick the player - sprintf( disconnect_message, "Server is enforcing file consistency for %s\n", filename ); - - // Kick now with specified disconnect message. - return 1; -} - -/* -================================ -AllowLagCompensation - - The game .dll should return 1 if lag compensation should be allowed ( could also just set - the sv_unlag cvar. - Most games right now should return 0, until client-side weapon prediction code is written - and tested for them ( note you can predict weapons, but not do lag compensation, too, - if you want. -================================ -*/ -int AllowLagCompensation( void ) -{ - return 0; -} - diff --git a/dmc/dlls/client.h b/dmc/dlls/client.h deleted file mode 100644 index 1e66cc8..0000000 --- a/dmc/dlls/client.h +++ /dev/null @@ -1,65 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef CLIENT_H -#define CLIENT_H - -extern void respawn( entvars_t* pev, BOOL fCopyCorpse ); -extern BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); -extern void ClientDisconnect( edict_t *pEntity ); -extern void ClientKill( edict_t *pEntity ); -extern void ClientPutInServer( edict_t *pEntity ); -extern void ClientCommand( edict_t *pEntity ); -extern void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ); -extern void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ); -extern void ServerDeactivate( void ); -extern void StartFrame( void ); -extern void PlayerPostThink( edict_t *pEntity ); -extern void PlayerPreThink( edict_t *pEntity ); -extern void ParmsNewLevel( void ); -extern void ParmsChangeLevel( void ); - -extern void ClientPrecache( void ); - -extern const char *GetGameDescription( void ); -extern void PlayerCustomization( edict_t *pEntity, customization_t *pCust ); - -extern void SpectatorConnect ( edict_t *pEntity ); -extern void SpectatorDisconnect ( edict_t *pEntity ); -extern void SpectatorThink ( edict_t *pEntity ); - -extern void Sys_Error( const char *error_string ); - -extern void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas ); -extern void UpdateClientData ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ); -extern int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ); -extern void CreateBaseline( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs ); -extern void RegisterEncoders( void ); - -extern int GetWeaponData( struct edict_s *player, struct weapon_data_s *info ); - -extern void CmdStart( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed ); -extern void CmdEnd ( const edict_t *player ); - -extern int ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); - -extern int GetHullBounds( int hullnumber, float *mins, float *maxs ); - -extern void CreateInstancedBaselines ( void ); - -extern int InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message ); - -extern int AllowLagCompensation( void ); - -#endif // CLIENT_H diff --git a/dmc/dlls/combat.cpp b/dmc/dlls/combat.cpp deleted file mode 100644 index 82f5862..0000000 --- a/dmc/dlls/combat.cpp +++ /dev/null @@ -1,1099 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== combat.cpp ======================================================== - - functions dealing with damage infliction & death - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "soundent.h" -#include "decals.h" -#include "animation.h" -#include "weapons.h" -#include "func_break.h" -#include "player.h" - -extern DLL_GLOBAL Vector g_vecAttackDir; -extern DLL_GLOBAL int g_iSkillLevel; - -extern Vector VecBModelOrigin( entvars_t* pevBModel ); -extern entvars_t *g_pevLastInflictor; - -unsigned short g_sGibbed; -unsigned short g_sTeleport; -unsigned short g_sTrail; -unsigned short g_sExplosion; -unsigned short g_usPowerUp; - -#define GERMAN_GIB_COUNT 4 -#define HUMAN_GIB_COUNT 6 -#define ALIEN_GIB_COUNT 4 - - -// HACKHACK -- The gib velocity equations don't work -void CGib :: LimitVelocity( void ) -{ - float length = pev->velocity.Length(); - - // ceiling at 1500. The gib velocity equation is not bounded properly. Rather than tune it - // in 3 separate places again, I'll just limit it here. - if ( length > 1500.0 ) - pev->velocity = pev->velocity.Normalize() * 1500; // This should really be sv_maxvelocity * 0.75 or something -} - - -void CGib :: SpawnStickyGibs( entvars_t *pevVictim, Vector vecOrigin, int cGibs ) -{ - int i; - - if ( g_Language == LANGUAGE_GERMAN ) - { - // no sticky gibs in germany right now! - return; - } - - for ( i = 0 ; i < cGibs ; i++ ) - { - CGib *pGib = GetClassPtr( (CGib *)NULL ); - - pGib->Spawn( "models/stickygib.mdl" ); - pGib->pev->body = RANDOM_LONG(0,2); - - if ( pevVictim ) - { - pGib->pev->origin.x = vecOrigin.x + RANDOM_FLOAT( -3, 3 ); - pGib->pev->origin.y = vecOrigin.y + RANDOM_FLOAT( -3, 3 ); - pGib->pev->origin.z = vecOrigin.z + RANDOM_FLOAT( -3, 3 ); - - /* - pGib->pev->origin.x = pevVictim->absmin.x + pevVictim->size.x * (RANDOM_FLOAT ( 0 , 1 ) ); - pGib->pev->origin.y = pevVictim->absmin.y + pevVictim->size.y * (RANDOM_FLOAT ( 0 , 1 ) ); - pGib->pev->origin.z = pevVictim->absmin.z + pevVictim->size.z * (RANDOM_FLOAT ( 0 , 1 ) ); - */ - - // make the gib fly away from the attack vector - pGib->pev->velocity = g_vecAttackDir * -1; - - // mix in some noise - pGib->pev->velocity.x += RANDOM_FLOAT ( -0.15, 0.15 ); - pGib->pev->velocity.y += RANDOM_FLOAT ( -0.15, 0.15 ); - pGib->pev->velocity.z += RANDOM_FLOAT ( -0.15, 0.15 ); - - pGib->pev->velocity = pGib->pev->velocity * 900; - - pGib->pev->avelocity.x = RANDOM_FLOAT ( 250, 400 ); - pGib->pev->avelocity.y = RANDOM_FLOAT ( 250, 400 ); - - // copy owner's blood color - pGib->m_bloodColor = (CBaseEntity::Instance(pevVictim))->BloodColor(); - - if ( pevVictim->health > -50) - { - pGib->pev->velocity = pGib->pev->velocity * 0.7; - } - else if ( pevVictim->health > -200) - { - pGib->pev->velocity = pGib->pev->velocity * 2; - } - else - { - pGib->pev->velocity = pGib->pev->velocity * 4; - } - - - pGib->pev->movetype = MOVETYPE_TOSS; - pGib->pev->solid = SOLID_BBOX; - UTIL_SetSize ( pGib->pev, Vector ( 0, 0 ,0 ), Vector ( 0, 0, 0 ) ); - pGib->SetTouch ( &CGib::StickyGibTouch ); - pGib->SetThink (NULL); - } - pGib->LimitVelocity(); - } -} - -void CGib :: SpawnHeadGib( entvars_t *pevVictim ) -{ - CGib *pGib = GetClassPtr( (CGib *)NULL ); - - if ( g_Language == LANGUAGE_GERMAN ) - { - pGib->Spawn( "models/germangibs.mdl" );// throw one head - pGib->pev->body = 0; - } - else - { - pGib->Spawn( "models/hgibs.mdl" );// throw one head - pGib->pev->body = 0; - } - - if ( pevVictim ) - { - pGib->pev->origin = pevVictim->origin + pevVictim->view_ofs; - - edict_t *pentPlayer = FIND_CLIENT_IN_PVS( pGib->edict() ); - - if ( RANDOM_LONG ( 0, 100 ) <= 5 && pentPlayer ) - { - // 5% chance head will be thrown at player's face. - entvars_t *pevPlayer; - - pevPlayer = VARS( pentPlayer ); - pGib->pev->velocity = ( ( pevPlayer->origin + pevPlayer->view_ofs ) - pGib->pev->origin ).Normalize() * 300; - pGib->pev->velocity.z += 100; - } - else - { - pGib->pev->velocity = Vector (RANDOM_FLOAT(-100,100), RANDOM_FLOAT(-100,100), RANDOM_FLOAT(200,300)); - } - - - pGib->pev->avelocity.x = RANDOM_FLOAT ( 100, 200 ); - pGib->pev->avelocity.y = RANDOM_FLOAT ( 100, 300 ); - - // copy owner's blood color - pGib->m_bloodColor = (CBaseEntity::Instance(pevVictim))->BloodColor(); - - if ( pevVictim->health > -50) - { - pGib->pev->velocity = pGib->pev->velocity * 0.7; - } - else if ( pevVictim->health > -200) - { - pGib->pev->velocity = pGib->pev->velocity * 2; - } - else - { - pGib->pev->velocity = pGib->pev->velocity * 4; - } - } - pGib->LimitVelocity(); -} - -void CGib :: SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int human ) -{ - int cSplat; - - for ( cSplat = 0 ; cSplat < cGibs ; cSplat++ ) - { - CGib *pGib = GetClassPtr( (CGib *)NULL ); - - if ( g_Language == LANGUAGE_GERMAN ) - { - pGib->Spawn( "models/germangibs.mdl" ); - pGib->pev->body = RANDOM_LONG(0,GERMAN_GIB_COUNT-1); - } - else - { - if ( human ) - { - // human pieces - pGib->Spawn( "models/hgibs.mdl" ); - pGib->pev->body = RANDOM_LONG(1,HUMAN_GIB_COUNT-1);// start at one to avoid throwing random amounts of skulls (0th gib) - } - else - { - // aliens - pGib->Spawn( "models/agibs.mdl" ); - pGib->pev->body = RANDOM_LONG(0,ALIEN_GIB_COUNT-1); - } - } - - if ( pevVictim ) - { - // spawn the gib somewhere in the monster's bounding volume - pGib->pev->origin.x = pevVictim->absmin.x + pevVictim->size.x * (RANDOM_FLOAT ( 0 , 1 ) ); - pGib->pev->origin.y = pevVictim->absmin.y + pevVictim->size.y * (RANDOM_FLOAT ( 0 , 1 ) ); - pGib->pev->origin.z = pevVictim->absmin.z + pevVictim->size.z * (RANDOM_FLOAT ( 0 , 1 ) ) + 1; // absmin.z is in the floor because the engine subtracts 1 to enlarge the box - - // make the gib fly away from the attack vector - pGib->pev->velocity = g_vecAttackDir * -1; - - // mix in some noise - pGib->pev->velocity.x += RANDOM_FLOAT ( -0.25, 0.25 ); - pGib->pev->velocity.y += RANDOM_FLOAT ( -0.25, 0.25 ); - pGib->pev->velocity.z += RANDOM_FLOAT ( -0.25, 0.25 ); - - pGib->pev->velocity = pGib->pev->velocity * RANDOM_FLOAT ( 300, 400 ); - - pGib->pev->avelocity.x = RANDOM_FLOAT ( 100, 200 ); - pGib->pev->avelocity.y = RANDOM_FLOAT ( 100, 300 ); - - // copy owner's blood color - pGib->m_bloodColor = (CBaseEntity::Instance(pevVictim))->BloodColor(); - - if ( pevVictim->health > -50) - { - pGib->pev->velocity = pGib->pev->velocity * 0.7; - } - else if ( pevVictim->health > -200) - { - pGib->pev->velocity = pGib->pev->velocity * 2; - } - else - { - pGib->pev->velocity = pGib->pev->velocity * 4; - } - - pGib->pev->solid = SOLID_BBOX; - UTIL_SetSize ( pGib->pev, Vector( 0 , 0 , 0 ), Vector ( 0, 0, 0 ) ); - } - pGib->LimitVelocity(); - } -} - -//========================================================= -// WaitTillLand - in order to emit their meaty scent from -// the proper location, gibs should wait until they stop -// bouncing to emit their scent. That's what this function -// does. -//========================================================= -void CGib :: WaitTillLand ( void ) -{ - if (!IsInWorld()) - { - UTIL_Remove( this ); - return; - } - - if ( pev->velocity == g_vecZero ) - { - SetThink (&CGib::SUB_StartFadeOut); - pev->nextthink = gpGlobals->time + m_lifeTime; - } - else - { - // wait and check again in another half second. - pev->nextthink = gpGlobals->time + 0.5; - } -} - -// -// Gib bounces on the ground or wall, sponges some blood down, too! -// -void CGib :: BounceGibTouch ( CBaseEntity *pOther ) -{ - Vector vecSpot; - TraceResult tr; - - //if ( RANDOM_LONG(0,1) ) - // return;// don't bleed everytime - - if (pev->flags & FL_ONGROUND) - { - pev->velocity = pev->velocity * 0.9; - pev->angles.x = 0; - pev->angles.z = 0; - pev->avelocity.x = 0; - pev->avelocity.z = 0; - } - else - { - if ( g_Language != LANGUAGE_GERMAN && m_cBloodDecals > 0 && m_bloodColor != DONT_BLEED ) - { - vecSpot = pev->origin + Vector ( 0 , 0 , 8 );//move up a bit, and trace down. - UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -24 ), ignore_monsters, ENT(pev), & tr); - - UTIL_BloodDecalTrace( &tr, m_bloodColor ); - - m_cBloodDecals--; - } - - if ( m_material != matNone && RANDOM_LONG(0,2) == 0 ) - { - float volume; - float zvel = fabs(pev->velocity.z); - - volume = 0.8 * V_min(1.0, ((float)zvel) / 450.0); - - CBreakable::MaterialSoundRandom( edict(), (Materials)m_material, volume ); - } - } -} - -// -// Sticky gib puts blood on the wall and stays put. -// -void CGib :: StickyGibTouch ( CBaseEntity *pOther ) -{ - Vector vecSpot; - TraceResult tr; - - SetThink ( &CGib::SUB_Remove ); - pev->nextthink = gpGlobals->time + 10; - - if ( !FClassnameIs( pOther->pev, "worldspawn" ) ) - { - pev->nextthink = gpGlobals->time; - return; - } - - UTIL_TraceLine ( pev->origin, pev->origin + pev->velocity * 32, ignore_monsters, ENT(pev), & tr); - - UTIL_BloodDecalTrace( &tr, m_bloodColor ); - - pev->velocity = tr.vecPlaneNormal * -1; - pev->angles = UTIL_VecToAngles ( pev->velocity ); - pev->velocity = g_vecZero; - pev->avelocity = g_vecZero; - pev->movetype = MOVETYPE_NONE; -} - -//========================================================= -// GibMonster - create some gore and get rid of a monster's -// model. -//========================================================= -void CBaseMonster :: GibMonster( void ) -{ - TraceResult tr; - BOOL gibbed = FALSE; - - EMIT_SOUND(ENT(pev), CHAN_WEAPON, "common/bodysplat.wav", 1, ATTN_NORM); - - if ( CVAR_GET_FLOAT("violence_hgibs") != 0 ) // Only the player will ever get here - { - if ( IsPlayer() ) - { - PLAYBACK_EVENT_FULL ( FEV_GLOBAL, edict(), - g_sGibbed, 0.0, (float *)&pev->origin, (float *)&g_vecAttackDir, 0.0, 0.0, 0, 0, 0, 0); - } - - /*CGib::SpawnHeadGib( pev ); - CGib::SpawnRandomGibs( pev, 4, 1 ); // throw some human gibs.*/ - } - gibbed = TRUE; -} - -//========================================================= -// GetDeathActivity - determines the best type of death -// anim to play. -//========================================================= -Activity CBaseMonster :: GetDeathActivity ( void ) -{ - Activity deathActivity; - BOOL fTriedDirection; - float flDot; - TraceResult tr; - Vector vecSrc; - - if ( pev->deadflag != DEAD_NO ) - { - // don't run this while dying. - return m_IdealActivity; - } - - vecSrc = Center(); - - fTriedDirection = FALSE; - deathActivity = ACT_DIESIMPLE;// in case we can't find any special deaths to do. - - UTIL_MakeVectors ( pev->angles ); - flDot = DotProduct ( gpGlobals->v_forward, g_vecAttackDir * -1 ); - - switch ( m_LastHitGroup ) - { - // try to pick a region-specific death. - case HITGROUP_HEAD: - deathActivity = ACT_DIE_HEADSHOT; - break; - - case HITGROUP_STOMACH: - deathActivity = ACT_DIE_GUTSHOT; - break; - - case HITGROUP_GENERIC: - // try to pick a death based on attack direction - fTriedDirection = TRUE; - - if ( flDot > 0.3 ) - { - deathActivity = ACT_DIEFORWARD; - } - else if ( flDot <= -0.3 ) - { - deathActivity = ACT_DIEBACKWARD; - } - break; - - default: - // try to pick a death based on attack direction - fTriedDirection = TRUE; - - if ( flDot > 0.3 ) - { - deathActivity = ACT_DIEFORWARD; - } - else if ( flDot <= -0.3 ) - { - deathActivity = ACT_DIEBACKWARD; - } - break; - } - - - // can we perform the prescribed death? - if ( LookupActivity ( deathActivity ) == ACTIVITY_NOT_AVAILABLE ) - { - // no! did we fail to perform a directional death? - if ( fTriedDirection ) - { - // if yes, we're out of options. Go simple. - deathActivity = ACT_DIESIMPLE; - } - else - { - // cannot perform the ideal region-specific death, so try a direction. - if ( flDot > 0.3 ) - { - deathActivity = ACT_DIEFORWARD; - } - else if ( flDot <= -0.3 ) - { - deathActivity = ACT_DIEBACKWARD; - } - } - } - - if ( LookupActivity ( deathActivity ) == ACTIVITY_NOT_AVAILABLE ) - { - // if we're still invalid, simple is our only option. - deathActivity = ACT_DIESIMPLE; - } - - if ( deathActivity == ACT_DIEFORWARD ) - { - // make sure there's room to fall forward - UTIL_TraceHull ( vecSrc, vecSrc + gpGlobals->v_forward * 64, dont_ignore_monsters, head_hull, edict(), &tr ); - - if ( tr.flFraction != 1.0 ) - { - deathActivity = ACT_DIESIMPLE; - } - } - - if ( deathActivity == ACT_DIEBACKWARD ) - { - // make sure there's room to fall backward - UTIL_TraceHull ( vecSrc, vecSrc - gpGlobals->v_forward * 64, dont_ignore_monsters, head_hull, edict(), &tr ); - - if ( tr.flFraction != 1.0 ) - { - deathActivity = ACT_DIESIMPLE; - } - } - - return deathActivity; -} - -//========================================================= -// GetSmallFlinchActivity - determines the best type of flinch -// anim to play. -//========================================================= -Activity CBaseMonster :: GetSmallFlinchActivity ( void ) -{ - Activity flinchActivity; - BOOL fTriedDirection; - float flDot; - - fTriedDirection = FALSE; - UTIL_MakeVectors ( pev->angles ); - flDot = DotProduct ( gpGlobals->v_forward, g_vecAttackDir * -1 ); - - switch ( m_LastHitGroup ) - { - // pick a region-specific flinch - case HITGROUP_HEAD: - flinchActivity = ACT_FLINCH_HEAD; - break; - case HITGROUP_STOMACH: - flinchActivity = ACT_FLINCH_STOMACH; - break; - case HITGROUP_LEFTARM: - flinchActivity = ACT_FLINCH_LEFTARM; - break; - case HITGROUP_RIGHTARM: - flinchActivity = ACT_FLINCH_RIGHTARM; - break; - case HITGROUP_LEFTLEG: - flinchActivity = ACT_FLINCH_LEFTLEG; - break; - case HITGROUP_RIGHTLEG: - flinchActivity = ACT_FLINCH_RIGHTLEG; - break; - case HITGROUP_GENERIC: - default: - // just get a generic flinch. - flinchActivity = ACT_SMALL_FLINCH; - break; - } - - - // do we have a sequence for the ideal activity? - if ( LookupActivity ( flinchActivity ) == ACTIVITY_NOT_AVAILABLE ) - { - flinchActivity = ACT_SMALL_FLINCH; - } - - return flinchActivity; -} - - -BOOL CBaseMonster::ShouldGibMonster( int iGib ) -{ - if ( ( iGib == GIB_NORMAL && pev->health < GIB_HEALTH_VALUE ) || ( iGib == GIB_ALWAYS ) ) - return TRUE; - - return FALSE; -} - - -void CBaseMonster::CallGibMonster( void ) -{ - BOOL fade = FALSE; - - if ( HasHumanGibs() ) - { - if ( CVAR_GET_FLOAT("violence_hgibs") == 0 ) - fade = TRUE; - } - else if ( HasAlienGibs() ) - { - if ( CVAR_GET_FLOAT("violence_agibs") == 0 ) - fade = TRUE; - } - - pev->takedamage = DAMAGE_NO; - pev->solid = SOLID_NOT;// do something with the body. while monster blows up - - if ( fade ) - { - FadeMonster(); - } - else - { - pev->effects = EF_NODRAW; // make the model invisible. - GibMonster(); - } - - pev->deadflag = DEAD_DEAD; - FCheckAITrigger(); - - // don't let the status bar glitch for players.with <0 health. - if (pev->health < -99) - { - pev->health = 0; - } - - if ( ShouldFadeOnDeath() && !fade ) - UTIL_Remove(this); -} - -// -// fade out - slowly fades a entity out, then removes it. -// -// DON'T USE ME FOR GIBS AND STUFF IN MULTIPLAYER! -// SET A FUTURE THINK AND A RENDERMODE!! -void CBaseEntity :: SUB_StartFadeOut ( void ) -{ - if (pev->rendermode == kRenderNormal) - { - pev->renderamt = 255; - pev->rendermode = kRenderTransTexture; - } - - pev->solid = SOLID_NOT; - pev->avelocity = g_vecZero; - - pev->nextthink = gpGlobals->time + 0.1; - SetThink ( &CBaseEntity::SUB_FadeOut ); -} - -void CBaseEntity :: SUB_FadeOut ( void ) -{ - if ( pev->renderamt > 7 ) - { - pev->renderamt -= 7; - pev->nextthink = gpGlobals->time + 0.1; - } - else - { - pev->renderamt = 0; - pev->nextthink = gpGlobals->time + 0.2; - SetThink ( &CBaseEntity::SUB_Remove ); - } -} - -// -// Throw a chunk -// -void CGib :: Spawn( const char *szGibModel ) -{ - pev->movetype = MOVETYPE_BOUNCE; - pev->friction = 0.55; // deading the bounce a bit - - // sometimes an entity inherits the edict from a former piece of glass, - // and will spawn using the same render FX or rendermode! bad! - pev->renderamt = 255; - pev->rendermode = kRenderNormal; - pev->renderfx = kRenderFxNone; - pev->solid = SOLID_SLIDEBOX;/// hopefully this will fix the VELOCITY TOO LOW crap - pev->classname = MAKE_STRING("gib"); - - SET_MODEL(ENT(pev), szGibModel); - UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0)); - - pev->nextthink = gpGlobals->time + 4; - m_lifeTime = 25; - SetThink ( &CGib::WaitTillLand ); - SetTouch ( &CGib::BounceGibTouch ); - - m_material = matNone; - m_cBloodDecals = 5;// how many blood decals this gib can place (1 per bounce until none remain). -} - -/* -============ -TakeDamage - -The damage is coming from inflictor, but get mad at attacker -This should be the only function that ever reduces health. -bitsDamageType indicates the type of damage sustained, ie: DMG_SHOCK - -Time-based damage: only occurs while the monster is within the trigger_hurt. -When a monster is poisoned via an arrow etc it takes all the poison damage at once. - - - -GLOBALS ASSUMED SET: g_iSkillLevel -============ -*/ -int CBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) -{ - float flTake; - Vector vecDir; - - if (!pev->takedamage) - return 0; - - if ( !IsAlive() ) - { - return DeadTakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); - } - - if ( pev->deadflag == DEAD_NO ) - { - // no pain sound during death animation. - PainSound();// "Ouch!" - } - - //!!!LATER - make armor consideration here! - flTake = flDamage; - - // set damage type sustained - m_bitsDamageType |= bitsDamageType; - - // grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit). - vecDir = Vector( 0, 0, 0 ); - if (!FNullEnt( pevInflictor )) - { - CBaseEntity *pInflictor = CBaseEntity :: Instance( pevInflictor ); - if (pInflictor) - { - vecDir = ( pInflictor->Center() - Vector ( 0, 0, 10 ) - Center() ).Normalize(); - vecDir = g_vecAttackDir = vecDir.Normalize(); - } - } - - // add to the damage total for clients, which will be sent as a single - // message at the end of the frame - // todo: remove after combining shotgun blasts? - if ( IsPlayer() ) - { - if ( pevInflictor ) - pev->dmg_inflictor = ENT(pevInflictor); - - pev->dmg_take += flTake; - - // check for godmode or invincibility - if ( pev->flags & FL_GODMODE ) - { - return 0; - } - } - - // if this is a player, move him around! - if ( ( !FNullEnt( pevInflictor ) ) && (pev->movetype == MOVETYPE_WALK) && (!pevAttacker || pevAttacker->solid != SOLID_TRIGGER) ) - { - pev->velocity = pev->velocity + vecDir * -DamageForce( flDamage ); - } - - // do the damage - pev->health -= flTake; - - // HACKHACK Don't kill monsters in a script. Let them break their scripts first - if ( m_MonsterState == MONSTERSTATE_SCRIPT ) - { - SetConditions( bits_COND_LIGHT_DAMAGE ); - return 0; - } - - if ( pev->health <= 0 ) - { - g_pevLastInflictor = pevInflictor; - - if ( bitsDamageType & DMG_ALWAYSGIB ) - { - Killed( pevAttacker, GIB_ALWAYS ); - } - else if ( bitsDamageType & DMG_NEVERGIB ) - { - Killed( pevAttacker, GIB_NEVER ); - } - else - { - Killed( pevAttacker, GIB_NORMAL ); - } - - g_pevLastInflictor = NULL; - - return 0; - } - - // react to the damage (get mad) - if ( (pev->flags & FL_MONSTER) && !FNullEnt(pevAttacker) ) - { - if ( pevAttacker->flags & (FL_MONSTER | FL_CLIENT) ) - {// only if the attack was a monster or client! - - // enemy's last known position is somewhere down the vector that the attack came from. - if (pevInflictor) - { - if (m_hEnemy == NULL || pevInflictor == m_hEnemy->pev || !HasConditions(bits_COND_SEE_ENEMY)) - { - m_vecEnemyLKP = pevInflictor->origin; - } - } - else - { - m_vecEnemyLKP = pev->origin + ( g_vecAttackDir * 64 ); - } - - MakeIdealYaw( m_vecEnemyLKP ); - - // add pain to the conditions - // !!!HACKHACK - fudged for now. Do we want to have a virtual function to determine what is light and - // heavy damage per monster class? - if ( flDamage > 0 ) - { - SetConditions(bits_COND_LIGHT_DAMAGE); - } - - if ( flDamage >= 20 ) - { - SetConditions(bits_COND_HEAVY_DAMAGE); - } - } - } - - return 1; -} - -//========================================================= -// DeadTakeDamage - takedamage function called when a monster's -// corpse is damaged. -//========================================================= -int CBaseMonster :: DeadTakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) -{ - Vector vecDir; - - // grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit). - vecDir = Vector( 0, 0, 0 ); - if (!FNullEnt( pevInflictor )) - { - CBaseEntity *pInflictor = CBaseEntity :: Instance( pevInflictor ); - if (pInflictor) - { - vecDir = ( pInflictor->Center() - Vector ( 0, 0, 10 ) - Center() ).Normalize(); - vecDir = g_vecAttackDir = vecDir.Normalize(); - } - } - -#if 0// turn this back on when the bounding box issues are resolved. - - pev->flags &= ~FL_ONGROUND; - pev->origin.z += 1; - - // let the damage scoot the corpse around a bit. - if ( !FNullEnt(pevInflictor) && (pevAttacker->solid != SOLID_TRIGGER) ) - { - pev->velocity = pev->velocity + vecDir * -DamageForce( flDamage ); - } - -#endif - - // kill the corpse if enough damage was done to destroy the corpse and the damage is of a type that is allowed to destroy the corpse. - if ( bitsDamageType & DMG_GIB_CORPSE ) - { - if ( pev->health <= flDamage ) - { - pev->health = -50; - Killed( pevAttacker, GIB_ALWAYS ); - return 0; - } - // Accumulate corpse gibbing damage, so you can gib with multiple hits - pev->health -= flDamage * 0.1; - } - - return 1; -} - - -float CBaseMonster :: DamageForce( float damage ) -{ - float force = damage * ((32 * 32 * 72.0) / (pev->size.x * pev->size.y * pev->size.z)) * 5; - - if ( force > 1000.0) - { - force = 1000.0; - } - - return force; -} - -// -// RadiusDamage - this entity is exploding, or otherwise needs to inflict damage upon entities within a certain range. -// -// only damage ents that can clearly be seen by the explosion! - - -void RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType ) -{ - CBaseEntity *pEntity = NULL; - TraceResult tr; - float flAdjustedDamage, falloff; - Vector vecSpot; - - if ( flRadius ) - falloff = flDamage / flRadius; - else - falloff = 1.0; - - int bInWater = (UTIL_PointContents ( vecSrc ) == CONTENTS_WATER); - - vecSrc.z += 1;// in case grenade is lying on the ground - - if ( !pevAttacker ) - pevAttacker = pevInflictor; - - // iterate on all entities in the vicinity. - while ((pEntity = UTIL_FindEntityInSphere( pEntity, vecSrc, flRadius )) != NULL) - { - if ( pEntity->pev->takedamage != DAMAGE_NO ) - { - // UNDONE: this should check a damage mask, not an ignore - if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore ) - {// houndeyes don't hurt other houndeyes with their attack - continue; - } - - // blast's don't tavel into or out of water - if (bInWater && pEntity->pev->waterlevel == 0) - continue; - if (!bInWater && pEntity->pev->waterlevel == 3) - continue; - - vecSpot = pEntity->BodyTarget( vecSrc ); - - UTIL_TraceLine ( vecSrc, vecSpot, dont_ignore_monsters, ENT(pevInflictor), &tr ); - - if ( tr.flFraction == 1.0 || tr.pHit == pEntity->edict() ) - {// the explosion can 'see' this entity, so hurt them! - if (tr.fStartSolid) - { - // if we're stuck inside them, fixup the position and distance - tr.vecEndPos = vecSrc; - tr.flFraction = 0.0; - } - - // decrease damage for an ent that's farther from the bomb. - flAdjustedDamage = ( vecSrc - tr.vecEndPos ).Length() * falloff; - flAdjustedDamage = flDamage - flAdjustedDamage; - - if ( flAdjustedDamage < 0 ) - { - flAdjustedDamage = 0; - } - - // ALERT( at_console, "hit %s\n", STRING( pEntity->pev->classname ) ); - if (tr.flFraction != 1.0) - { - ClearMultiDamage( ); - pEntity->TraceAttack( pevInflictor, flAdjustedDamage, (tr.vecEndPos - vecSrc).Normalize( ), &tr, bitsDamageType ); - ApplyMultiDamage( pevInflictor, pevAttacker ); - } - else - { - pEntity->TakeDamage ( pevInflictor, pevAttacker, flAdjustedDamage, bitsDamageType ); - } - } - } - } -} - - -void CBaseMonster :: RadiusDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) -{ - ::RadiusDamage( pev->origin, pevInflictor, pevAttacker, flDamage, flDamage * 2.5, iClassIgnore, bitsDamageType ); -} - - -void CBaseMonster :: RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) -{ - ::RadiusDamage( vecSrc, pevInflictor, pevAttacker, flDamage, flDamage * 2.5, iClassIgnore, bitsDamageType ); -} - -/* -//========================================================= -// TraceAttack -//========================================================= -void CBaseMonster::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) -{ - Vector vecOrigin = ptr->vecEndPos - vecDir * 4; - - ALERT ( at_console, "%d\n", ptr->iHitgroup ); - - - if ( pev->takedamage ) - { - AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType ); - - int blood = BloodColor(); - - if ( blood != DONT_BLEED ) - { - SpawnBlood(vecOrigin, blood, flDamage);// a little surface blood. - } - } -} -*/ - -void CBaseEntity :: TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ) -{ - if (BloodColor() == DONT_BLEED) - return; - - if (flDamage == 0) - return; - - if (! (bitsDamageType & (DMG_CRUSH | DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB | DMG_MORTAR))) - return; - - // make blood decal on the wall! - TraceResult Bloodtr; - Vector vecTraceDir; - float flNoise; - int cCount; - int i; - - if (flDamage < 10) - { - flNoise = 0.1; - cCount = 1; - } - else if (flDamage < 25) - { - flNoise = 0.2; - cCount = 2; - } - else - { - flNoise = 0.3; - cCount = 4; - } - - for ( i = 0 ; i < cCount ; i++ ) - { - vecTraceDir = vecDir * -1;// trace in the opposite direction the shot came from (the direction the shot is going) - - vecTraceDir.x += RANDOM_FLOAT( -flNoise, flNoise ); - vecTraceDir.y += RANDOM_FLOAT( -flNoise, flNoise ); - vecTraceDir.z += RANDOM_FLOAT( -flNoise, flNoise ); - - UTIL_TraceLine( ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * -172, ignore_monsters, ENT(pev), &Bloodtr); - - if ( Bloodtr.flFraction != 1.0 ) - { - UTIL_BloodDecalTrace( &Bloodtr, BloodColor() ); - } - } -} - -//========================================================= -//========================================================= -void CBaseMonster :: MakeDamageBloodDecal ( int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir ) -{ - // make blood decal on the wall! - TraceResult Bloodtr; - Vector vecTraceDir; - int i; - - if ( !IsAlive() ) - { - // dealing with a dead monster. - if ( pev->max_health <= 0 ) - { - // no blood decal for a monster that has already decalled its limit. - return; - } - else - { - pev->max_health--; - } - } - - for ( i = 0 ; i < cCount ; i++ ) - { - vecTraceDir = vecDir; - - vecTraceDir.x += RANDOM_FLOAT( -flNoise, flNoise ); - vecTraceDir.y += RANDOM_FLOAT( -flNoise, flNoise ); - vecTraceDir.z += RANDOM_FLOAT( -flNoise, flNoise ); - - UTIL_TraceLine( ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * 172, ignore_monsters, ENT(pev), &Bloodtr); - -/* - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_SHOWLINE); - WRITE_COORD( ptr->vecEndPos.x ); - WRITE_COORD( ptr->vecEndPos.y ); - WRITE_COORD( ptr->vecEndPos.z ); - - WRITE_COORD( Bloodtr.vecEndPos.x ); - WRITE_COORD( Bloodtr.vecEndPos.y ); - WRITE_COORD( Bloodtr.vecEndPos.z ); - MESSAGE_END(); -*/ - - if ( Bloodtr.flFraction != 1.0 ) - { - UTIL_BloodDecalTrace( &Bloodtr, BloodColor() ); - } - } -} diff --git a/dmc/dlls/decals.h b/dmc/dlls/decals.h deleted file mode 100644 index 95fa44f..0000000 --- a/dmc/dlls/decals.h +++ /dev/null @@ -1,75 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef DECALS_H -#define DECALS_H - -// -// Dynamic Decals -// -enum decal_e -{ - DECAL_GUNSHOT1 = 0, - DECAL_GUNSHOT2, - DECAL_GUNSHOT3, - DECAL_GUNSHOT4, - DECAL_GUNSHOT5, - DECAL_LAMBDA1, - DECAL_LAMBDA2, - DECAL_LAMBDA3, - DECAL_LAMBDA4, - DECAL_LAMBDA5, - DECAL_LAMBDA6, - DECAL_SCORCH1, - DECAL_SCORCH2, - DECAL_BLOOD1, - DECAL_BLOOD2, - DECAL_BLOOD3, - DECAL_BLOOD4, - DECAL_BLOOD5, - DECAL_BLOOD6, - DECAL_YBLOOD1, - DECAL_YBLOOD2, - DECAL_YBLOOD3, - DECAL_YBLOOD4, - DECAL_YBLOOD5, - DECAL_YBLOOD6, - DECAL_GLASSBREAK1, - DECAL_GLASSBREAK2, - DECAL_GLASSBREAK3, - DECAL_BIGSHOT1, - DECAL_BIGSHOT2, - DECAL_BIGSHOT3, - DECAL_BIGSHOT4, - DECAL_BIGSHOT5, - DECAL_SPIT1, - DECAL_SPIT2, - DECAL_BPROOF1, // Bulletproof glass decal - DECAL_GARGSTOMP1, // Gargantua stomp crack - DECAL_SMALLSCORCH1, // Small scorch mark - DECAL_SMALLSCORCH2, // Small scorch mark - DECAL_SMALLSCORCH3, // Small scorch mark - DECAL_MOMMABIRTH, // Big momma birth splatter - DECAL_MOMMASPLAT, -}; - -typedef struct -{ - char *name; - int index; -} DLL_DECALLIST; - -extern DLL_DECALLIST gDecals[]; - -#endif // DECALS_H diff --git a/dmc/dlls/defaultai.cpp b/dmc/dlls/defaultai.cpp deleted file mode 100644 index 2b23124..0000000 --- a/dmc/dlls/defaultai.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -//========================================================= -// Default behaviors. -//========================================================= -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "schedule.h" -#include "defaultai.h" -#include "nodes.h" -#include "scripted.h" - -Schedule_t *CBaseMonster::m_scheduleList[] = -{ -}; - -Schedule_t *CBaseMonster::ScheduleFromName( const char *pName ) -{ - return ScheduleInList( pName, m_scheduleList, ARRAYSIZE(m_scheduleList) ); -} - - -Schedule_t *CBaseMonster :: ScheduleInList( const char *pName, Schedule_t **pList, int listCount ) -{ - int i; - - if ( !pName ) - { - ALERT( at_console, "%s set to unnamed schedule!\n", STRING(pev->classname) ); - return NULL; - } - - - for ( i = 0; i < listCount; i++ ) - { - if ( !pList[i]->pName ) - { - ALERT( at_console, "Unnamed schedule!\n" ); - continue; - } - if ( stricmp( pName, pList[i]->pName ) == 0 ) - return pList[i]; - } - return NULL; -} - -//========================================================= -// GetScheduleOfType - returns a pointer to one of the -// monster's available schedules of the indicated type. -//========================================================= -Schedule_t* CBaseMonster :: GetScheduleOfType ( int Type ) -{ -// ALERT ( at_console, "Sched Type:%d\n", Type ); - switch ( Type ) - { - // This is the schedule for scripted sequences AND scripted AI - case SCHED_AISCRIPT: - { - ASSERT( m_pCine != NULL ); - if ( !m_pCine ) - { - ALERT( at_aiconsole, "Script failed for %s\n", STRING(pev->classname) ); - CineCleanup(); - return GetScheduleOfType( SCHED_IDLE_STAND ); - } -// else -// ALERT( at_aiconsole, "Starting script %s for %s\n", STRING( m_pCine->m_iszPlay ), STRING(pev->classname) ); - - switch ( m_pCine->m_fMoveTo ) - { - case 0: - case 4: - return slWaitScript; - case 1: - return slWalkToScript; - case 2: - return slRunToScript; - case 5: - return slFaceScript; - } - break; - } - case SCHED_IDLE_STAND: - { - if ( RANDOM_LONG(0,14) == 0 && FCanActiveIdle() ) - { - return &slActiveIdle[ 0 ]; - } - - return &slIdleStand[ 0 ]; - } - case SCHED_IDLE_WALK: - { - return &slIdleWalk[ 0 ]; - } - case SCHED_WAIT_TRIGGER: - { - return &slIdleTrigger[ 0 ]; - } - case SCHED_WAKE_ANGRY: - { - return &slWakeAngry[ 0 ]; - } - case SCHED_ALERT_FACE: - { - return &slAlertFace[ 0 ]; - } - case SCHED_ALERT_STAND: - { - return &slAlertStand[ 0 ]; - } - case SCHED_COMBAT_STAND: - { - return &slCombatStand[ 0 ]; - } - case SCHED_COMBAT_FACE: - { - return &slCombatFace[ 0 ]; - } - case SCHED_CHASE_ENEMY: - { - return &slChaseEnemy[ 0 ]; - } - case SCHED_CHASE_ENEMY_FAILED: - { - return &slFail[ 0 ]; - } - case SCHED_SMALL_FLINCH: - { - return &slSmallFlinch[ 0 ]; - } - case SCHED_ALERT_SMALL_FLINCH: - { - return &slAlertSmallFlinch[ 0 ]; - } - case SCHED_RELOAD: - { - return &slReload[ 0 ]; - } - case SCHED_ARM_WEAPON: - { - return &slArmWeapon[ 0 ]; - } - case SCHED_STANDOFF: - { - return &slStandoff[ 0 ]; - } - case SCHED_RANGE_ATTACK1: - { - return &slRangeAttack1[ 0 ]; - } - case SCHED_RANGE_ATTACK2: - { - return &slRangeAttack2[ 0 ]; - } - case SCHED_MELEE_ATTACK1: - { - return &slPrimaryMeleeAttack[ 0 ]; - } - case SCHED_MELEE_ATTACK2: - { - return &slSecondaryMeleeAttack[ 0 ]; - } - case SCHED_SPECIAL_ATTACK1: - { - return &slSpecialAttack1[ 0 ]; - } - case SCHED_SPECIAL_ATTACK2: - { - return &slSpecialAttack2[ 0 ]; - } - case SCHED_TAKE_COVER_FROM_BEST_SOUND: - { - return &slTakeCoverFromBestSound[ 0 ]; - } - case SCHED_TAKE_COVER_FROM_ENEMY: - { - return &slTakeCoverFromEnemy[ 0 ]; - } - case SCHED_COWER: - { - return &slCower[ 0 ]; - } - case SCHED_AMBUSH: - { - return &slAmbush[ 0 ]; - } - case SCHED_BARNACLE_VICTIM_GRAB: - { - return &slBarnacleVictimGrab[ 0 ]; - } - case SCHED_BARNACLE_VICTIM_CHOMP: - { - return &slBarnacleVictimChomp[ 0 ]; - } - case SCHED_INVESTIGATE_SOUND: - { - return &slInvestigateSound[ 0 ]; - } - case SCHED_DIE: - { - return &slDie[ 0 ]; - } - case SCHED_TAKE_COVER_FROM_ORIGIN: - { - return &slTakeCoverFromOrigin[ 0 ]; - } - case SCHED_VICTORY_DANCE: - { - return &slVictoryDance[ 0 ]; - } - case SCHED_FAIL: - { - return slFail; - } - default: - { - ALERT ( at_console, "GetScheduleOfType()\nNo CASE for Schedule Type %d!\n", Type ); - - return &slIdleStand[ 0 ]; - break; - } - } - - return NULL; -} diff --git a/dmc/dlls/defaultai.h b/dmc/dlls/defaultai.h deleted file mode 100644 index 652d108..0000000 --- a/dmc/dlls/defaultai.h +++ /dev/null @@ -1,98 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -#ifndef DEFAULTAI_H -#define DEFAULTAI_H - -//========================================================= -// Failed -//========================================================= -extern Schedule_t slFail[]; - -//========================================================= -// Idle Schedules -//========================================================= -extern Schedule_t slIdleStand[]; -extern Schedule_t slIdleTrigger[]; -extern Schedule_t slIdleWalk[]; - -//========================================================= -// Wake Schedules -//========================================================= -extern Schedule_t slWakeAngry[]; - -//========================================================= -// AlertTurn Schedules -//========================================================= -extern Schedule_t slAlertFace[]; - -//========================================================= -// AlertIdle Schedules -//========================================================= -extern Schedule_t slAlertStand[]; - -//========================================================= -// CombatIdle Schedule -//========================================================= -extern Schedule_t slCombatStand[]; - -//========================================================= -// CombatFace Schedule -//========================================================= -extern Schedule_t slCombatFace[]; - -//========================================================= -// reload schedule -//========================================================= -extern Schedule_t slReload[]; - -//========================================================= -// Attack Schedules -//========================================================= - -extern Schedule_t slRangeAttack1[]; -extern Schedule_t slRangeAttack2[]; - -extern Schedule_t slTakeCoverFromBestSound[]; - -// primary melee attack -extern Schedule_t slMeleeAttack[]; - -// Chase enemy schedule -extern Schedule_t slChaseEnemy[]; - -//========================================================= -// small flinch, used when a relatively minor bit of damage -// is inflicted. -//========================================================= -extern Schedule_t slSmallFlinch[]; - -//========================================================= -// Die! -//========================================================= -extern Schedule_t slDie[]; - -//========================================================= -// Universal Error Schedule -//========================================================= -extern Schedule_t slError[]; - -//========================================================= -// Scripted sequences -//========================================================= -extern Schedule_t slWalkToScript[]; -extern Schedule_t slRunToScript[]; -extern Schedule_t slWaitScript[]; - -#endif // DEFAULTAI_H diff --git a/dmc/dlls/dmc.def b/dmc/dlls/dmc.def deleted file mode 100644 index b455ca1..0000000 --- a/dmc/dlls/dmc.def +++ /dev/null @@ -1,5 +0,0 @@ -LIBRARY dmc -EXPORTS - GiveFnptrsToDll @1 -SECTIONS - .data READ WRITE diff --git a/dmc/dlls/dmcgl.def b/dmc/dlls/dmcgl.def deleted file mode 100644 index a02b87c..0000000 --- a/dmc/dlls/dmcgl.def +++ /dev/null @@ -1,15 +0,0 @@ -LIBRARY dmcgl -EXPORTS - GiveFnptrsToDll @1 - GetEntityInterfaces @2 - SetChangeParms @3 - SetNewParms @4 - ClientKill @5 - PutClientInServer @6 - PlayerPreThink @7 - PlayerPostThink @8 - ClientConnect @9 - ClientDisconnect @10 - StartFrame @11 -SECTIONS - .data READ WRITE diff --git a/dmc/dlls/doors.cpp b/dmc/dlls/doors.cpp deleted file mode 100644 index 9de01f2..0000000 --- a/dmc/dlls/doors.cpp +++ /dev/null @@ -1,1099 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== doors.cpp ======================================================== - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "doors.h" - - -extern void SetMovedir(entvars_t* ev); - -#define noiseMoving noise1 -#define noiseArrived noise2 - -class CBaseDoor : public CBaseToggle -{ -public: - void Spawn( void ); - void Precache( void ); - virtual void KeyValue( KeyValueData *pkvd ); - virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual void Blocked( CBaseEntity *pOther ); - - - virtual int ObjectCaps( void ) - { - if (pev->spawnflags & SF_ITEM_USE_ONLY) - return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE; - else - return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); - }; - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - virtual void SetToggleState( int state ); - - // used to selectivly override defaults - void EXPORT DoorTouch( CBaseEntity *pOther ); - - // local functions - int DoorActivate( ); - void EXPORT DoorGoUp( void ); - void EXPORT DoorGoDown( void ); - void EXPORT DoorHitTop( void ); - void EXPORT DoorHitBottom( void ); - - BYTE m_bHealthValue;// some doors are medi-kit doors, they give players health - - BYTE m_bMoveSnd; // sound a door makes while moving - BYTE m_bStopSnd; // sound a door makes when it stops - - locksound_t m_ls; // door lock sounds - - BYTE m_bLockedSound; // ordinals from entity selection - BYTE m_bLockedSentence; - BYTE m_bUnlockedSound; - BYTE m_bUnlockedSentence; - float m_fNextSoundPlay; - bool m_bIsReopening; // If the bIsReopening flag is set, the door's not fully shut, but it still wants to reopen - // because a player's standing in it's field. - bool m_bStoppedOpenSound; // TRUE once the original opening sound has been stopped - -private: - unsigned short m_usDoorGoUp; - unsigned short m_usDoorGoDown; - unsigned short m_usDoorHitTop; - unsigned short m_usDoorHitBottom; -}; - - -TYPEDESCRIPTION CBaseDoor::m_SaveData[] = -{ - DEFINE_FIELD( CBaseDoor, m_bHealthValue, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bMoveSnd, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bStopSnd, FIELD_CHARACTER ), - - DEFINE_FIELD( CBaseDoor, m_bLockedSound, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bLockedSentence, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bUnlockedSound, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bUnlockedSentence, FIELD_CHARACTER ), - -}; - -IMPLEMENT_SAVERESTORE( CBaseDoor, CBaseToggle ); - - -#define DOOR_SENTENCEWAIT 6 -#define DOOR_SOUNDWAIT 3 -#define BUTTON_SOUNDWAIT 0.5 - -// play door or button locked or unlocked sounds. -// pass in pointer to valid locksound struct. -// if flocked is true, play 'door is locked' sound, -// otherwise play 'door is unlocked' sound -// NOTE: this routine is shared by doors and buttons - -void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton) -{ - // LOCKED SOUND - - // CONSIDER: consolidate the locksound_t struct (all entries are duplicates for lock/unlock) - // CONSIDER: and condense this code. - float flsoundwait; - - if (fbutton) - flsoundwait = BUTTON_SOUNDWAIT; - else - flsoundwait = DOOR_SOUNDWAIT; - - if (flocked) - { - int fplaysound = (pls->sLockedSound && gpGlobals->time > pls->flwaitSound); - int fplaysentence = (pls->sLockedSentence && !pls->bEOFLocked && gpGlobals->time > pls->flwaitSentence); - float fvol; - - if (fplaysound && fplaysentence) - fvol = 0.25; - else - fvol = 1.0; - - // if there is a locked sound, and we've debounced, play sound - if (fplaysound) - { - // play 'door locked' sound - EMIT_SOUND(ENT(pev), CHAN_ITEM, (char*)STRING(pls->sLockedSound), fvol, ATTN_NORM); - pls->flwaitSound = gpGlobals->time + flsoundwait; - } - - // if there is a sentence, we've not played all in list, and we've debounced, play sound - if (fplaysentence) - { - // play next 'door locked' sentence in group - int iprev = pls->iLockedSentence; - - pls->iLockedSentence = SENTENCEG_PlaySequentialSz(ENT(pev), STRING(pls->sLockedSentence), - 0.85, ATTN_NORM, 0, 100, pls->iLockedSentence, FALSE); - pls->iUnlockedSentence = 0; - - // make sure we don't keep calling last sentence in list - pls->bEOFLocked = (iprev == pls->iLockedSentence); - - pls->flwaitSentence = gpGlobals->time + DOOR_SENTENCEWAIT; - } - } - else - { - // UNLOCKED SOUND - - int fplaysound = (pls->sUnlockedSound && gpGlobals->time > pls->flwaitSound); - int fplaysentence = (pls->sUnlockedSentence && !pls->bEOFUnlocked && gpGlobals->time > pls->flwaitSentence); - float fvol; - - // if playing both sentence and sound, lower sound volume so we hear sentence - if (fplaysound && fplaysentence) - fvol = 0.25; - else - fvol = 1.0; - - // play 'door unlocked' sound if set - if (fplaysound) - { - EMIT_SOUND(ENT(pev), CHAN_ITEM, (char*)STRING(pls->sUnlockedSound), fvol, ATTN_NORM); - pls->flwaitSound = gpGlobals->time + flsoundwait; - } - - // play next 'door unlocked' sentence in group - if (fplaysentence) - { - int iprev = pls->iUnlockedSentence; - - pls->iUnlockedSentence = SENTENCEG_PlaySequentialSz(ENT(pev), STRING(pls->sUnlockedSentence), - 0.85, ATTN_NORM, 0, 100, pls->iUnlockedSentence, FALSE); - pls->iLockedSentence = 0; - - // make sure we don't keep calling last sentence in list - pls->bEOFUnlocked = (iprev == pls->iUnlockedSentence); - pls->flwaitSentence = gpGlobals->time + DOOR_SENTENCEWAIT; - } - } -} - -// -// Cache user-entity-field values until spawn is called. -// - -void CBaseDoor::KeyValue( KeyValueData *pkvd ) -{ - - if (FStrEq(pkvd->szKeyName, "skin"))//skin is used for content type - { - pev->skin = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "movesnd")) - { - m_bMoveSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "stopsnd")) - { - m_bStopSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "healthvalue")) - { - m_bHealthValue = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "locked_sound")) - { - m_bLockedSound = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "locked_sentence")) - { - m_bLockedSentence = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "unlocked_sound")) - { - m_bUnlockedSound = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "unlocked_sentence")) - { - m_bUnlockedSentence = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "WaveHeight")) - { - pev->scale = atof(pkvd->szValue) * (1.0/8.0); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK TOGGLE -if two doors touch, they are assumed to be connected and operate as a unit. - -TOGGLE causes the door to wait in both the start and end states for a trigger event. - -START_OPEN causes the door to move to its destination when spawned, and operate in reverse. -It is used to temporarily or permanently close off an area when triggered (not usefull for -touch or takedamage doors). - -"angle" determines the opening direction -"targetname" if set, no touch field will be spawned and a remote button or trigger - field activates the door. -"health" if set, door must be shot open -"speed" movement speed (100 default) -"wait" wait before returning (3 default, -1 = never return) -"lip" lip remaining at end of move (8 default) -"dmg" damage to inflict when blocked (2 default) -"sounds" -0) no sound -1) stone -2) base -3) stone chain -4) screechy metal -*/ - -LINK_ENTITY_TO_CLASS( func_door, CBaseDoor ); -// -// func_water - same as a door. -// -LINK_ENTITY_TO_CLASS( func_water, CBaseDoor ); - - -void CBaseDoor::Spawn( ) -{ - Precache(); - SetMovedir (pev); - - if ( pev->skin == 0 ) - {//normal door - if ( FBitSet (pev->spawnflags, SF_DOOR_PASSABLE) ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - } - else - {// special contents - pev->solid = SOLID_NOT; - SetBits( pev->spawnflags, SF_DOOR_SILENT ); // water is silent for now - } - - pev->movetype = MOVETYPE_PUSH; - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - if (pev->speed == 0) - pev->speed = 100; - - m_vecPosition1 = pev->origin; - // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big - m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs( pev->movedir.x * (pev->size.x-2) ) + fabs( pev->movedir.y * (pev->size.y-2) ) + fabs( pev->movedir.z * (pev->size.z-2) ) - m_flLip)); - ASSERTSZ(m_vecPosition1 != m_vecPosition2, "door start/end positions are equal"); - if ( FBitSet (pev->spawnflags, SF_DOOR_START_OPEN) ) - { // swap pos1 and pos2, put door at pos2 - UTIL_SetOrigin(pev, m_vecPosition2); - m_vecPosition2 = m_vecPosition1; - m_vecPosition1 = pev->origin; - } - - m_toggle_state = TS_AT_BOTTOM; - - m_fNextSoundPlay = 0; - m_bIsReopening = false; - m_bStoppedOpenSound = false; - // if the door is flagged for USE button activation only, use NULL touch function - if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ) - { - SetTouch ( NULL ); - } - else // touchable button - SetTouch( &CBaseDoor::DoorTouch ); -} - - -void CBaseDoor :: SetToggleState( int state ) -{ - if ( state == TS_AT_TOP ) - UTIL_SetOrigin( pev, m_vecPosition2 ); - else - UTIL_SetOrigin( pev, m_vecPosition1 ); -} - - -void CBaseDoor::Precache( void ) -{ - char *pszSound; - -// set the door's "in-motion" sound - switch (m_bMoveSnd) - { - case 0: - pev->noiseMoving = ALLOC_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("doors/doormove1.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove1.wav"); - break; - case 2: - PRECACHE_SOUND ("doors/doormove2.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove2.wav"); - break; - case 3: - PRECACHE_SOUND ("doors/doormove3.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove3.wav"); - break; - case 4: - PRECACHE_SOUND ("doors/doormove4.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove4.wav"); - break; - case 5: - PRECACHE_SOUND ("doors/doormove5.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove5.wav"); - break; - case 6: - PRECACHE_SOUND ("doors/doormove6.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove6.wav"); - break; - case 7: - PRECACHE_SOUND ("doors/doormove7.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove7.wav"); - break; - case 8: - PRECACHE_SOUND ("doors/doormove8.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove8.wav"); - break; - case 9: - PRECACHE_SOUND ("doors/doormove9.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove9.wav"); - break; - case 10: - PRECACHE_SOUND ("doors/doormove10.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove10.wav"); - break; - default: - pev->noiseMoving = ALLOC_STRING("common/null.wav"); - break; - } - -// set the door's 'reached destination' stop sound - switch (m_bStopSnd) - { - case 0: - pev->noiseArrived = ALLOC_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("doors/doorstop1.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop1.wav"); - break; - case 2: - PRECACHE_SOUND ("doors/doorstop2.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop2.wav"); - break; - case 3: - PRECACHE_SOUND ("doors/doorstop3.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop3.wav"); - break; - case 4: - PRECACHE_SOUND ("doors/doorstop4.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop4.wav"); - break; - case 5: - PRECACHE_SOUND ("doors/doorstop5.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop5.wav"); - break; - case 6: - PRECACHE_SOUND ("doors/doorstop6.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop6.wav"); - break; - case 7: - PRECACHE_SOUND ("doors/doorstop7.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop7.wav"); - break; - case 8: - PRECACHE_SOUND ("doors/doorstop8.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop8.wav"); - break; - default: - pev->noiseArrived = ALLOC_STRING("common/null.wav"); - break; - } - - // get door button sounds, for doors which are directly 'touched' to open - - if (m_bLockedSound) - { - pszSound = ButtonSound( (int)m_bLockedSound ); - PRECACHE_SOUND(pszSound); - m_ls.sLockedSound = ALLOC_STRING(pszSound); - } - - if (m_bUnlockedSound) - { - pszSound = ButtonSound( (int)m_bUnlockedSound ); - PRECACHE_SOUND(pszSound); - m_ls.sUnlockedSound = ALLOC_STRING(pszSound); - } - - // get sentence group names, for doors which are directly 'touched' to open - - switch (m_bLockedSentence) - { - case 1: m_ls.sLockedSentence = ALLOC_STRING("NA"); break; // access denied - case 2: m_ls.sLockedSentence = ALLOC_STRING("ND"); break; // security lockout - case 3: m_ls.sLockedSentence = ALLOC_STRING("NF"); break; // blast door - case 4: m_ls.sLockedSentence = ALLOC_STRING("NFIRE"); break; // fire door - case 5: m_ls.sLockedSentence = ALLOC_STRING("NCHEM"); break; // chemical door - case 6: m_ls.sLockedSentence = ALLOC_STRING("NRAD"); break; // radiation door - case 7: m_ls.sLockedSentence = ALLOC_STRING("NCON"); break; // gen containment - case 8: m_ls.sLockedSentence = ALLOC_STRING("NH"); break; // maintenance door - case 9: m_ls.sLockedSentence = ALLOC_STRING("NG"); break; // broken door - - default: m_ls.sLockedSentence = 0; break; - } - - switch (m_bUnlockedSentence) - { - case 1: m_ls.sUnlockedSentence = ALLOC_STRING("EA"); break; // access granted - case 2: m_ls.sUnlockedSentence = ALLOC_STRING("ED"); break; // security door - case 3: m_ls.sUnlockedSentence = ALLOC_STRING("EF"); break; // blast door - case 4: m_ls.sUnlockedSentence = ALLOC_STRING("EFIRE"); break; // fire door - case 5: m_ls.sUnlockedSentence = ALLOC_STRING("ECHEM"); break; // chemical door - case 6: m_ls.sUnlockedSentence = ALLOC_STRING("ERAD"); break; // radiation door - case 7: m_ls.sUnlockedSentence = ALLOC_STRING("ECON"); break; // gen containment - case 8: m_ls.sUnlockedSentence = ALLOC_STRING("EH"); break; // maintenance door - - default: m_ls.sUnlockedSentence = 0; break; - } - m_usDoorGoUp = PRECACHE_EVENT( 1, "events/door/doorgoup.sc" ); - m_usDoorGoDown = PRECACHE_EVENT( 1, "events/door/doorgodown.sc" ); - m_usDoorHitTop = PRECACHE_EVENT( 1, "events/door/doorhittop.sc" ); - m_usDoorHitBottom = PRECACHE_EVENT( 1, "events/door/doorhitbottom.sc" ); -} - -// -// Doors not tied to anything (e.g. button, another door) can be touched, to make them activate. -// -void CBaseDoor::DoorTouch( CBaseEntity *pOther ) -{ - entvars_t* pevToucher = pOther->pev; - - // Ignore touches by anything but players - if (!FClassnameIs(pevToucher, "player")) - return; - - // If door has master, and it's not ready to trigger, - // play 'locked' sound - - if (m_sMaster && !UTIL_IsMasterTriggered(m_sMaster, pOther)) - PlayLockSounds(pev, &m_ls, TRUE, FALSE); - - // If door is somebody's target, then touching does nothing. - // You have to activate the owner (e.g. button). - - if (!FStringNull(pev->targetname)) - { - // play locked sound - PlayLockSounds(pev, &m_ls, TRUE, FALSE); - return; - } - - m_hActivator = pOther;// remember who activated the door - - if (DoorActivate( )) - SetTouch( NULL ); // Temporarily disable the touch function, until movement is finished. -} - - -// -// Used by SUB_UseTargets, when a door is the target of a button. -// -void CBaseDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - m_hActivator = pActivator; - // if not ready to be used, ignore "use" command. - if (m_toggle_state == TS_AT_BOTTOM || FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN) && m_toggle_state == TS_AT_TOP) - DoorActivate(); -} - -// -// Causes the door to "do its thing", i.e. start moving, and cascade activation. -// -int CBaseDoor::DoorActivate( ) -{ - if (!UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) - return 0; - - if (FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN) && m_toggle_state == TS_AT_TOP) - {// door should close - DoorGoDown(); - } - else - {// door should open - - if ( m_hActivator != NULL && m_hActivator->IsPlayer() ) - {// give health if player opened the door (medikit) - // VARS( m_eoActivator )->health += m_bHealthValue; - - m_hActivator->TakeHealth( m_bHealthValue, DMG_GENERIC ); - - } - - // play door unlock sounds - if (!m_bIsReopening) - { - PlayLockSounds(pev, &m_ls, FALSE, FALSE); - } - DoorGoUp(); - } - - return 1; -} - -extern Vector VecBModelOrigin( entvars_t* pevBModel ); - -// -// Starts the door going to its "up" position (simply ToggleData->vecPosition2). -// -void CBaseDoor::DoorGoUp( void ) -{ - entvars_t *pevActivator; - - // It could be going-down, if blocked. - ASSERT( m_bIsReopening == true || (m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN) ); - - // emit door moving and stop sounds on CHAN_STATIC so that the multicast doesn't - // filter them out and leave a client stuck with looping door sounds! - if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) && m_bIsReopening == false ) - { - // don't play sounds too often - if ( m_fNextSoundPlay < gpGlobals->time ) - { - Vector vecCenter( Center() ); - float *pCenter = (float *)&vecCenter; - PLAYBACK_EVENT_FULL( FEV_RELIABLE, NULL, m_usDoorGoUp, 0.0, pCenter, (float *)&g_vecZero, 0.0, 0.0, ( m_bMoveSnd << 8 ) | ( m_bStopSnd & 0xff ), 0, 0, 0 ); -#if defined ( OLD_SOUNDS ) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) ); - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM); -#endif - } - } - - m_toggle_state = TS_GOING_UP; - - SetMoveDone( &CBaseDoor::DoorHitTop ); - if ( FClassnameIs(pev, "func_door_rotating")) // !!! BUGBUG Triggered doors don't work with this yet - { - float sign = 1.0; - - if ( m_hActivator != NULL ) - { - pevActivator = m_hActivator->pev; - - if ( !FBitSet( pev->spawnflags, SF_DOOR_ONEWAY ) && pev->movedir.y ) // Y axis rotation, move away from the player - { - Vector vec = pevActivator->origin - pev->origin; - Vector angles = pevActivator->angles; - angles.x = 0; - angles.z = 0; - UTIL_MakeVectors (angles); - // Vector vnext = (pevToucher->origin + (pevToucher->velocity * 10)) - pev->origin; - UTIL_MakeVectors ( pevActivator->angles ); - Vector vnext = (pevActivator->origin + (gpGlobals->v_forward * 10)) - pev->origin; - if ( (vec.x*vnext.y - vec.y*vnext.x) < 0 ) - sign = -1.0; - } - } - AngularMove(m_vecAngle2*sign, pev->speed); - } - else - LinearMove(m_vecPosition2, pev->speed); -} - - -// -// The door has reached the "up" position. Either go back down, or wait for another activation. -// -void CBaseDoor::DoorHitTop( void ) -{ - if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) - { - // don't play sounds too often - if ( (( m_fNextSoundPlay < gpGlobals->time ) && !m_bIsReopening) || (!m_bStoppedOpenSound) ) - { - m_bStoppedOpenSound = true; - - Vector vecCenter( Center() ); - float *pCenter = (float *)&vecCenter; - - PLAYBACK_EVENT_FULL( FEV_RELIABLE, NULL, m_usDoorHitTop, 0.0, pCenter, (float *)&g_vecZero, 0.0, 0.0, ( m_bMoveSnd << 8 ) | ( m_bStopSnd & 0xff ), 0, 0, 0 ); -#if defined ( OLD_SOUNDS ) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) ); - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseArrived), 1, ATTN_NORM); -#endif - } - } - - ASSERT(m_toggle_state == TS_GOING_UP); - m_toggle_state = TS_AT_TOP; - m_bIsReopening = false; - - // toggle-doors don't come down automatically, they wait for refire. - if (FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN)) - { - // Re-instate touch method, movement is complete - if ( !FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ) - SetTouch( &CBaseDoor::DoorTouch ); - } - else - { - // In flWait seconds, DoorGoDown will fire, unless wait is -1, then door stays open - pev->nextthink = pev->ltime + m_flWait; - SetThink( &CBaseDoor::DoorGoDown ); - - if ( m_flWait == -1 ) - { - pev->nextthink = -1; - } - } - - // Fire the close target (if startopen is set, then "top" is closed) - netname is the close target - if ( pev->netname && (pev->spawnflags & SF_DOOR_START_OPEN) ) - FireTargets( STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0 ); - - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished -} - - -// -// Starts the door going to its "down" position (simply ToggleData->vecPosition1). -// -void CBaseDoor::DoorGoDown( void ) -{ - if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) - { - // don't play sounds too often - if ( m_fNextSoundPlay < gpGlobals->time ) - { - Vector vecCenter( Center() ); - float *pCenter = (float *)&vecCenter; - - PLAYBACK_EVENT_FULL( FEV_RELIABLE, NULL, m_usDoorGoDown, 0.0, pCenter, (float *)&g_vecZero, 0.0, 0.0, ( m_bMoveSnd << 8 ) | ( m_bStopSnd & 0xff ), 0, 0, 0 ); -#if defined ( OLD_SOUNDS ) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) ); - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM); -#endif - } - } - -#ifdef DOOR_ASSERT - ASSERT(m_toggle_state == TS_AT_TOP); -#endif // DOOR_ASSERT - m_toggle_state = TS_GOING_DOWN; - - SetMoveDone( &CBaseDoor::DoorHitBottom ); - if ( FClassnameIs(pev, "func_door_rotating"))//rotating door - AngularMove( m_vecAngle1, pev->speed); - else - LinearMove( m_vecPosition1, pev->speed); -} - -// -// The door has reached the "down" position. Back to quiescence. -// -void CBaseDoor::DoorHitBottom( void ) -{ - if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) - { - // don't play sounds too often - if ( m_fNextSoundPlay < gpGlobals->time ) - { - Vector vecCenter( Center() ); - float *pCenter = (float *)&vecCenter; - PLAYBACK_EVENT_FULL( FEV_RELIABLE, NULL, m_usDoorHitBottom, 0.0, pCenter, (float *)&g_vecZero, 0.0, 0.0, ( m_bMoveSnd << 8 ) | ( m_bStopSnd & 0xff ), 0, 0, 0 ); -#if defined ( OLD_SOUNDS ) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) ); - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseArrived), 1, ATTN_NORM); -#endif - } - } - - ASSERT(m_toggle_state == TS_GOING_DOWN); - m_toggle_state = TS_AT_BOTTOM; - - // Re-instate touch method, cycle is complete - if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ) - {// use only door - SetTouch ( NULL ); - } - else // touchable door - SetTouch( &CBaseDoor::DoorTouch ); - - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished - - // Fire the close target (if startopen is set, then "top" is closed) - netname is the close target - if ( pev->netname && !(pev->spawnflags & SF_DOOR_START_OPEN) ) - FireTargets( STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0 ); -} - -void CBaseDoor::Blocked( CBaseEntity *pOther ) -{ - edict_t *pentTarget = NULL; - CBaseDoor *pDoor = NULL; - - - // Hurt the blocker a little. - if ( pev->dmg ) - pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH ); - - // if a door has a negative wait, it would never come back if blocked, - // so let it just squash the object to death real fast - - if (m_flWait >= 0) - { - if (m_toggle_state == TS_GOING_DOWN) - { - DoorGoUp(); - } - else - { - DoorGoDown(); - } - } - - // Don't play blocked sounds too often - if ( m_fNextSoundPlay <= gpGlobals->time ) - { - m_fNextSoundPlay = gpGlobals->time + 0.3; - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) ); - } - - // Block all door pieces with the same targetname here. - if ( !FStringNull ( pev->targetname ) ) - { - for (;;) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->targetname)); - - if ( VARS( pentTarget ) != pev ) - { - if (FNullEnt(pentTarget)) - break; - - if ( FClassnameIs ( pentTarget, "func_door" ) || FClassnameIs ( pentTarget, "func_door_rotating" ) ) - { - - pDoor = GetClassPtr( (CBaseDoor *) VARS(pentTarget) ); - - if ( pDoor->m_flWait >= 0) - { - if (pDoor->pev->velocity == pev->velocity && pDoor->pev->avelocity == pev->velocity) - { - // this is the most hacked, evil, bastardized thing I've ever seen. kjb - if ( FClassnameIs ( pentTarget, "func_door" ) ) - {// set origin to realign normal doors - pDoor->pev->origin = pev->origin; - pDoor->pev->velocity = g_vecZero;// stop! - } - else - {// set angles to realign rotating doors - pDoor->pev->angles = pev->angles; - pDoor->pev->avelocity = g_vecZero; - } - } - - if ( pDoor->m_toggle_state == TS_GOING_DOWN) - pDoor->DoorGoUp(); - else - pDoor->DoorGoDown(); - } - } - } - } - } -} - - -/*QUAKED FuncRotDoorSpawn (0 .5 .8) ? START_OPEN REVERSE -DOOR_DONT_LINK TOGGLE X_AXIS Y_AXIS -if two doors touch, they are assumed to be connected and operate as -a unit. - -TOGGLE causes the door to wait in both the start and end states for -a trigger event. - -START_OPEN causes the door to move to its destination when spawned, -and operate in reverse. It is used to temporarily or permanently -close off an area when triggered (not usefull for touch or -takedamage doors). - -You need to have an origin brush as part of this entity. The -center of that brush will be -the point around which it is rotated. It will rotate around the Z -axis by default. You can -check either the X_AXIS or Y_AXIS box to change that. - -"distance" is how many degrees the door will be rotated. -"speed" determines how fast the door moves; default value is 100. - -REVERSE will cause the door to rotate in the opposite direction. - -"angle" determines the opening direction -"targetname" if set, no touch field will be spawned and a remote -button or trigger field activates the door. -"health" if set, door must be shot open -"speed" movement speed (100 default) -"wait" wait before returning (3 default, -1 = never return) -"dmg" damage to inflict when blocked (2 default) -"sounds" -0) no sound -1) stone -2) base -3) stone chain -4) screechy metal -*/ -class CRotDoor : public CBaseDoor -{ -public: - void Spawn( void ); - virtual void SetToggleState( int state ); -}; - -LINK_ENTITY_TO_CLASS( func_door_rotating, CRotDoor ); - - -void CRotDoor::Spawn( void ) -{ - Precache(); - // set the axis of rotation - CBaseToggle::AxisDir( pev ); - - // check for clockwise rotation - if ( FBitSet (pev->spawnflags, SF_DOOR_ROTATE_BACKWARDS) ) - pev->movedir = pev->movedir * -1; - - //m_flWait = 2; who the hell did this? (sjb) - m_vecAngle1 = pev->angles; - m_vecAngle2 = pev->angles + pev->movedir * m_flMoveDistance; - - ASSERTSZ(m_vecAngle1 != m_vecAngle2, "rotating door start/end positions are equal"); - - if ( FBitSet (pev->spawnflags, SF_DOOR_PASSABLE) ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - - pev->movetype = MOVETYPE_PUSH; - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - if (pev->speed == 0) - pev->speed = 100; - -// DOOR_START_OPEN is to allow an entity to be lighted in the closed position -// but spawn in the open position - if ( FBitSet (pev->spawnflags, SF_DOOR_START_OPEN) ) - { // swap pos1 and pos2, put door at pos2, invert movement direction - pev->angles = m_vecAngle2; - Vector vecSav = m_vecAngle1; - m_vecAngle2 = m_vecAngle1; - m_vecAngle1 = vecSav; - pev->movedir = pev->movedir * -1; - } - - m_toggle_state = TS_AT_BOTTOM; - - if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ) - { - SetTouch ( NULL ); - } - else // touchable button - SetTouch( &CRotDoor::DoorTouch ); -} - - -void CRotDoor :: SetToggleState( int state ) -{ - if ( state == TS_AT_TOP ) - pev->angles = m_vecAngle2; - else - pev->angles = m_vecAngle1; - - UTIL_SetOrigin( pev, pev->origin ); -} - - -class CMomentaryDoor : public CBaseToggle -{ -public: - void Spawn( void ); - void Precache( void ); - - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual int ObjectCaps( void ) { return CBaseToggle :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - BYTE m_bMoveSnd; // sound a door makes while moving -}; - -LINK_ENTITY_TO_CLASS( momentary_door, CMomentaryDoor ); - -TYPEDESCRIPTION CMomentaryDoor::m_SaveData[] = -{ - DEFINE_FIELD( CMomentaryDoor, m_bMoveSnd, FIELD_CHARACTER ), -}; - -IMPLEMENT_SAVERESTORE( CMomentaryDoor, CBaseToggle ); - -void CMomentaryDoor::Spawn( void ) -{ - SetMovedir (pev); - - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - if (pev->speed == 0) - pev->speed = 100; - if (pev->dmg == 0) - pev->dmg = 2; - - m_vecPosition1 = pev->origin; - // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big - m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs( pev->movedir.x * (pev->size.x-2) ) + fabs( pev->movedir.y * (pev->size.y-2) ) + fabs( pev->movedir.z * (pev->size.z-2) ) - m_flLip)); - ASSERTSZ(m_vecPosition1 != m_vecPosition2, "door start/end positions are equal"); - - if ( FBitSet (pev->spawnflags, SF_DOOR_START_OPEN) ) - { // swap pos1 and pos2, put door at pos2 - UTIL_SetOrigin(pev, m_vecPosition2); - m_vecPosition2 = m_vecPosition1; - m_vecPosition1 = pev->origin; - } - SetTouch( NULL ); - - Precache(); -} - -void CMomentaryDoor::Precache( void ) -{ - -// set the door's "in-motion" sound - switch (m_bMoveSnd) - { - case 0: - pev->noiseMoving = ALLOC_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("doors/doormove1.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove1.wav"); - break; - case 2: - PRECACHE_SOUND ("doors/doormove2.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove2.wav"); - break; - case 3: - PRECACHE_SOUND ("doors/doormove3.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove3.wav"); - break; - case 4: - PRECACHE_SOUND ("doors/doormove4.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove4.wav"); - break; - case 5: - PRECACHE_SOUND ("doors/doormove5.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove5.wav"); - break; - case 6: - PRECACHE_SOUND ("doors/doormove6.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove6.wav"); - break; - case 7: - PRECACHE_SOUND ("doors/doormove7.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove7.wav"); - break; - case 8: - PRECACHE_SOUND ("doors/doormove8.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove8.wav"); - break; - default: - pev->noiseMoving = ALLOC_STRING("common/null.wav"); - break; - } -} - -void CMomentaryDoor::KeyValue( KeyValueData *pkvd ) -{ - - if (FStrEq(pkvd->szKeyName, "movesnd")) - { - m_bMoveSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "stopsnd")) - { -// m_bStopSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "healthvalue")) - { -// m_bHealthValue = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -void CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( useType != USE_SET ) // Momentary buttons will pass down a float in here - return; - - if ( value > 1.0 ) - value = 1.0; - Vector move = m_vecPosition1 + (value * (m_vecPosition2 - m_vecPosition1)); - - Vector delta = move - pev->origin; - float speed = delta.Length() * 10; - - if ( speed != 0 ) - { - // This entity only thinks when it moves, so if it's thinking, it's in the process of moving - // play the sound when it starts moving - if ( pev->nextthink < pev->ltime || pev->nextthink == 0 ) - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM); - - LinearMove( move, speed ); - } - -} diff --git a/dmc/dlls/doors.h b/dmc/dlls/doors.h deleted file mode 100644 index 8008861..0000000 --- a/dmc/dlls/doors.h +++ /dev/null @@ -1,33 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef DOORS_H -#define DOORS_H - -// doors -#define SF_DOOR_ROTATE_Y 0 -#define SF_DOOR_START_OPEN 1 -#define SF_DOOR_ROTATE_BACKWARDS 2 -#define SF_DOOR_PASSABLE 8 -#define SF_DOOR_ONEWAY 16 -#define SF_DOOR_NO_AUTO_RETURN 32 -#define SF_DOOR_ROTATE_Z 64 -#define SF_DOOR_ROTATE_X 128 -#define SF_DOOR_USE_ONLY 256 // door must be opened by player's use button. -#define SF_DOOR_NOMONSTERS 512 // Monster can't open -#define SF_DOOR_SILENT 0x80000000 - - - -#endif //DOORS_H diff --git a/dmc/dlls/effects.cpp b/dmc/dlls/effects.cpp deleted file mode 100644 index 535125b..0000000 --- a/dmc/dlls/effects.cpp +++ /dev/null @@ -1,2268 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "customentity.h" -#include "effects.h" -#include "weapons.h" -#include "decals.h" -#include "func_break.h" -#include "shake.h" - -#define SF_GIBSHOOTER_REPEATABLE 1 // allows a gibshooter to be refired - -#define SF_FUNNEL_REVERSE 1 // funnel effect repels particles instead of attracting them. - - -// Lightning target, just alias landmark -LINK_ENTITY_TO_CLASS( info_target, CPointEntity ); - - -class CBubbling : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - - void EXPORT FizzThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - virtual int ObjectCaps( void ) { return CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - static TYPEDESCRIPTION m_SaveData[]; - - int m_density; - int m_frequency; - int m_bubbleModel; - int m_state; -}; - -LINK_ENTITY_TO_CLASS( env_bubbles, CBubbling ); - -TYPEDESCRIPTION CBubbling::m_SaveData[] = -{ - DEFINE_FIELD( CBubbling, m_density, FIELD_INTEGER ), - DEFINE_FIELD( CBubbling, m_frequency, FIELD_INTEGER ), - DEFINE_FIELD( CBubbling, m_state, FIELD_INTEGER ), - // Let spawn restore this! - // DEFINE_FIELD( CBubbling, m_bubbleModel, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CBubbling, CBaseEntity ); - - -#define SF_BUBBLES_STARTOFF 0x0001 - -void CBubbling::Spawn( void ) -{ - Precache( ); - SET_MODEL( ENT(pev), STRING(pev->model) ); // Set size - - pev->solid = SOLID_NOT; // Remove model & collisions - pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on - pev->rendermode = kRenderTransTexture; - int speed = pev->speed > 0 ? pev->speed : -pev->speed; - - // HACKHACK!!! - Speed in rendercolor - pev->rendercolor.x = speed >> 8; - pev->rendercolor.y = speed & 255; - pev->rendercolor.z = (pev->speed < 0) ? 1 : 0; - - - if ( !(pev->spawnflags & SF_BUBBLES_STARTOFF) ) - { - SetThink( &CBubbling::FizzThink ); - pev->nextthink = gpGlobals->time + 2.0; - m_state = 1; - } - else - m_state = 0; -} - -void CBubbling::Precache( void ) -{ - m_bubbleModel = PRECACHE_MODEL("sprites/bubble.spr"); // Precache bubble sprite -} - - -void CBubbling::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( ShouldToggle( useType, m_state ) ) - m_state = !m_state; - - if ( m_state ) - { - SetThink( & CBubbling::FizzThink ); - pev->nextthink = gpGlobals->time + 0.1; - } - else - { - SetThink( NULL ); - pev->nextthink = 0; - } -} - - -void CBubbling::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "density")) - { - m_density = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "frequency")) - { - m_frequency = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "current")) - { - pev->speed = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -void CBubbling::FizzThink( void ) -{ - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, VecBModelOrigin(pev) ); - WRITE_BYTE( TE_FIZZ ); - WRITE_SHORT( (short)ENTINDEX( edict() ) ); - WRITE_SHORT( (short)m_bubbleModel ); - WRITE_BYTE( m_density ); - MESSAGE_END(); - - if ( m_frequency > 19 ) - pev->nextthink = gpGlobals->time + 0.5; - else - pev->nextthink = gpGlobals->time + 2.5 - (0.1 * m_frequency); -} - -// -------------------------------------------------- -// -// Beams -// -// -------------------------------------------------- - -LINK_ENTITY_TO_CLASS( beam, CBeam ); - -void CBeam::Spawn( void ) -{ - pev->solid = SOLID_NOT; // Remove model & collisions - Precache( ); -} - -void CBeam::Precache( void ) -{ - if ( pev->owner ) - SetStartEntity( ENTINDEX( pev->owner ) ); - if ( pev->aiment ) - SetEndEntity( ENTINDEX( pev->aiment ) ); -} - -void CBeam::SetStartEntity( int entityIndex ) -{ - pev->sequence = (entityIndex & 0x0FFF) | ((pev->sequence&0xF000)<<12); - pev->owner = g_engfuncs.pfnPEntityOfEntIndex( entityIndex ); -} - -void CBeam::SetEndEntity( int entityIndex ) -{ - pev->skin = (entityIndex & 0x0FFF) | ((pev->skin&0xF000)<<12); - pev->aiment = g_engfuncs.pfnPEntityOfEntIndex( entityIndex ); -} - - -// These don't take attachments into account -const Vector &CBeam::GetStartPos( void ) -{ - if ( GetType() == BEAM_ENTS ) - { - edict_t *pent = g_engfuncs.pfnPEntityOfEntIndex( GetStartEntity() ); - return pent->v.origin; - } - return pev->origin; -} - - -const Vector &CBeam::GetEndPos( void ) -{ - int type = GetType(); - if ( type == BEAM_POINTS || type == BEAM_HOSE ) - { - return pev->angles; - } - - edict_t *pent = g_engfuncs.pfnPEntityOfEntIndex( GetEndEntity() ); - if ( pent ) - return pent->v.origin; - return pev->angles; -} - - -CBeam *CBeam::BeamCreate( const char *pSpriteName, int width ) -{ - // Create a new entity with CBeam private data - CBeam *pBeam = GetClassPtr( (CBeam *)NULL ); - pBeam->pev->classname = MAKE_STRING("beam"); - - pBeam->BeamInit( pSpriteName, width ); - - return pBeam; -} - - -void CBeam::BeamInit( const char *pSpriteName, int width ) -{ - pev->flags |= FL_CUSTOMENTITY; - SetColor( 255, 255, 255 ); - SetBrightness( 255 ); - SetNoise( 0 ); - SetFrame( 0 ); - SetScrollRate( 0 ); - pev->model = MAKE_STRING( pSpriteName ); - SetTexture( PRECACHE_MODEL( (char *)pSpriteName ) ); - SetWidth( width ); - pev->skin = 0; - pev->sequence = 0; - pev->rendermode = 0; -} - - -void CBeam::PointsInit( const Vector &start, const Vector &end ) -{ - SetType( BEAM_POINTS ); - SetStartPos( start ); - SetEndPos( end ); - SetStartAttachment( 0 ); - SetEndAttachment( 0 ); - RelinkBeam(); -} - - -void CBeam::HoseInit( const Vector &start, const Vector &direction ) -{ - SetType( BEAM_HOSE ); - SetStartPos( start ); - SetEndPos( direction ); - SetStartAttachment( 0 ); - SetEndAttachment( 0 ); - RelinkBeam(); -} - - -void CBeam::PointEntInit( const Vector &start, int endIndex ) -{ - SetType( BEAM_ENTPOINT ); - SetStartPos( start ); - SetEndEntity( endIndex ); - SetStartAttachment( 0 ); - SetEndAttachment( 0 ); - RelinkBeam(); -} - -void CBeam::EntsInit( int startIndex, int endIndex ) -{ - SetType( BEAM_ENTS ); - SetStartEntity( startIndex ); - SetEndEntity( endIndex ); - SetStartAttachment( 0 ); - SetEndAttachment( 0 ); - RelinkBeam(); -} - - -void CBeam::RelinkBeam( void ) -{ - const Vector &startPos = GetStartPos(), &endPos = GetEndPos(); - - pev->mins.x = V_min( startPos.x, endPos.x ); - pev->mins.y = V_min( startPos.y, endPos.y ); - pev->mins.z = V_min( startPos.z, endPos.z ); - pev->maxs.x = V_max( startPos.x, endPos.x ); - pev->maxs.y = V_max( startPos.y, endPos.y ); - pev->maxs.z = V_max( startPos.z, endPos.z ); - pev->mins = pev->mins - pev->origin; - pev->maxs = pev->maxs - pev->origin; - - UTIL_SetSize( pev, pev->mins, pev->maxs ); - UTIL_SetOrigin( pev, pev->origin ); -} - -#if 0 -void CBeam::SetObjectCollisionBox( void ) -{ - const Vector &startPos = GetStartPos(), &endPos = GetEndPos(); - - pev->absmin.x = V_min( startPos.x, endPos.x ); - pev->absmin.y = V_min( startPos.y, endPos.y ); - pev->absmin.z = V_min( startPos.z, endPos.z ); - pev->absmax.x = V_max( startPos.x, endPos.x ); - pev->absmax.y = V_max( startPos.y, endPos.y ); - pev->absmax.z = V_max( startPos.z, endPos.z ); -} -#endif - - -void CBeam::TriggerTouch( CBaseEntity *pOther ) -{ - if ( pOther->pev->flags & (FL_CLIENT | FL_MONSTER) ) - { - if ( pev->owner ) - { - CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner); - pOwner->Use( pOther, this, USE_TOGGLE, 0 ); - } - ALERT( at_console, "Firing targets!!!\n" ); - } -} - - -CBaseEntity *CBeam::RandomTargetname( const char *szName ) -{ - int total = 0; - - CBaseEntity *pEntity = NULL; - CBaseEntity *pNewEntity = NULL; - while ((pNewEntity = UTIL_FindEntityByTargetname( pNewEntity, szName )) != NULL) - { - total++; - if (RANDOM_LONG(0,total-1) < 1) - pEntity = pNewEntity; - } - return pEntity; -} - - -void CBeam::DoSparks( const Vector &start, const Vector &end ) -{ - if ( pev->spawnflags & (SF_BEAM_SPARKSTART|SF_BEAM_SPARKEND) ) - { - if ( pev->spawnflags & SF_BEAM_SPARKSTART ) - { - UTIL_Sparks( start ); - } - if ( pev->spawnflags & SF_BEAM_SPARKEND ) - { - UTIL_Sparks( end ); - } - } -} - - -class CLightning : public CBeam -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - void Activate( void ); - - void EXPORT StrikeThink( void ); - void EXPORT DamageThink( void ); - void RandomArea( void ); - void RandomPoint( Vector &vecSrc ); - void Zap( const Vector &vecSrc, const Vector &vecDest ); - void EXPORT StrikeUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - inline BOOL ServerSide( void ) - { - if ( m_life == 0 && !(pev->spawnflags & SF_BEAM_RING) ) - return TRUE; - return FALSE; - } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - void BeamUpdateVars( void ); - - int m_active; - int m_iszStartEntity; - int m_iszEndEntity; - float m_life; - int m_boltWidth; - int m_noiseAmplitude; - int m_brightness; - int m_speed; - float m_restrike; - int m_spriteTexture; - int m_iszSpriteName; - int m_frameStart; - - float m_radius; -}; - -LINK_ENTITY_TO_CLASS( env_lightning, CLightning ); -LINK_ENTITY_TO_CLASS( env_beam, CLightning ); - -// UNDONE: Jay -- This is only a test -#if _DEBUG -class CTripBeam : public CLightning -{ - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS( trip_beam, CTripBeam ); - -void CTripBeam::Spawn( void ) -{ - CLightning::Spawn(); - SetTouch( &CTripBeam::TriggerTouch ); - pev->solid = SOLID_TRIGGER; - RelinkBeam(); -} -#endif - - - -TYPEDESCRIPTION CLightning::m_SaveData[] = -{ - DEFINE_FIELD( CLightning, m_active, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_iszStartEntity, FIELD_STRING ), - DEFINE_FIELD( CLightning, m_iszEndEntity, FIELD_STRING ), - DEFINE_FIELD( CLightning, m_life, FIELD_FLOAT ), - DEFINE_FIELD( CLightning, m_boltWidth, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_noiseAmplitude, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_brightness, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_speed, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_restrike, FIELD_FLOAT ), - DEFINE_FIELD( CLightning, m_spriteTexture, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_iszSpriteName, FIELD_STRING ), - DEFINE_FIELD( CLightning, m_frameStart, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_radius, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CLightning, CBeam ); - - -void CLightning::Spawn( void ) -{ - if ( FStringNull( m_iszSpriteName ) ) - { - SetThink( &CLightning::SUB_Remove ); - return; - } - pev->solid = SOLID_NOT; // Remove model & collisions - Precache( ); - - pev->dmgtime = gpGlobals->time; - - if ( ServerSide() ) - { - SetThink( NULL ); - if ( pev->dmg > 0 ) - { - SetThink( &CLightning::DamageThink ); - pev->nextthink = gpGlobals->time + 0.1; - } - if ( pev->targetname ) - { - if ( !(pev->spawnflags & SF_BEAM_STARTON) ) - { - pev->effects = EF_NODRAW; - m_active = 0; - pev->nextthink = 0; - } - else - m_active = 1; - - SetUse( &CLightning::ToggleUse ); - } - } - else - { - m_active = 0; - if ( !FStringNull(pev->targetname) ) - { - SetUse( &CLightning::StrikeUse ); - } - if ( FStringNull(pev->targetname) || FBitSet(pev->spawnflags, SF_BEAM_STARTON) ) - { - SetThink( &CLightning::StrikeThink ); - pev->nextthink = gpGlobals->time + 1.0; - } - } -} - -void CLightning::Precache( void ) -{ - m_spriteTexture = PRECACHE_MODEL( (char *)STRING(m_iszSpriteName) ); - CBeam::Precache(); -} - - -void CLightning::Activate( void ) -{ - if ( ServerSide() ) - BeamUpdateVars(); -} - - -void CLightning::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "LightningStart")) - { - m_iszStartEntity = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "LightningEnd")) - { - m_iszEndEntity = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "life")) - { - m_life = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "BoltWidth")) - { - m_boltWidth = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "NoiseAmplitude")) - { - m_noiseAmplitude = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "TextureScroll")) - { - m_speed = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "StrikeTime")) - { - m_restrike = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "texture")) - { - m_iszSpriteName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "framestart")) - { - m_frameStart = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "Radius")) - { - m_radius = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "damage")) - { - pev->dmg = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBeam::KeyValue( pkvd ); -} - - -void CLightning::ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, m_active ) ) - return; - if ( m_active ) - { - m_active = 0; - pev->effects |= EF_NODRAW; - pev->nextthink = 0; - } - else - { - m_active = 1; - pev->effects &= ~EF_NODRAW; - DoSparks( GetStartPos(), GetEndPos() ); - if ( pev->dmg > 0 ) - { - pev->nextthink = gpGlobals->time; - pev->dmgtime = gpGlobals->time; - } - } -} - - -void CLightning::StrikeUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, m_active ) ) - return; - - if ( m_active ) - { - m_active = 0; - SetThink( NULL ); - } - else - { - SetThink( &CLightning::StrikeThink ); - pev->nextthink = gpGlobals->time + 0.1; - } - - if ( !FBitSet( pev->spawnflags, SF_BEAM_TOGGLE ) ) - SetUse( NULL ); -} - - -int IsPointEntity( CBaseEntity *pEnt ) -{ - if ( !pEnt->pev->modelindex ) - return 1; - if ( FClassnameIs( pEnt->pev, "info_target" ) || FClassnameIs( pEnt->pev, "info_landmark" ) || FClassnameIs( pEnt->pev, "path_corner" ) ) - return 1; - - return 0; -} - - -void CLightning::StrikeThink( void ) -{ - if ( m_life != 0 ) - { - if ( pev->spawnflags & SF_BEAM_RANDOM ) - pev->nextthink = gpGlobals->time + m_life + RANDOM_FLOAT( 0, m_restrike ); - else - pev->nextthink = gpGlobals->time + m_life + m_restrike; - } - m_active = 1; - - if (FStringNull(m_iszEndEntity)) - { - if (FStringNull(m_iszStartEntity)) - { - RandomArea( ); - } - else - { - CBaseEntity *pStart = RandomTargetname( STRING(m_iszStartEntity) ); - if (pStart != NULL) - RandomPoint( pStart->pev->origin ); - else - ALERT( at_console, "env_beam: unknown entity \"%s\"\n", STRING(m_iszStartEntity) ); - } - return; - } - - CBaseEntity *pStart = RandomTargetname( STRING(m_iszStartEntity) ); - CBaseEntity *pEnd = RandomTargetname( STRING(m_iszEndEntity) ); - - if ( pStart != NULL && pEnd != NULL ) - { - if ( IsPointEntity( pStart ) || IsPointEntity( pEnd ) ) - { - if ( pev->spawnflags & SF_BEAM_RING) - { - // don't work - return; - } - } - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - if ( IsPointEntity( pStart ) || IsPointEntity( pEnd ) ) - { - if ( !IsPointEntity( pEnd ) ) // One point entity must be in pEnd - { - CBaseEntity *pTemp; - pTemp = pStart; - pStart = pEnd; - pEnd = pTemp; - } - if ( !IsPointEntity( pStart ) ) // One sided - { - WRITE_BYTE( TE_BEAMENTPOINT ); - WRITE_SHORT( pStart->entindex() ); - WRITE_COORD( pEnd->pev->origin.x); - WRITE_COORD( pEnd->pev->origin.y); - WRITE_COORD( pEnd->pev->origin.z); - } - else - { - WRITE_BYTE( TE_BEAMPOINTS); - WRITE_COORD( pStart->pev->origin.x); - WRITE_COORD( pStart->pev->origin.y); - WRITE_COORD( pStart->pev->origin.z); - WRITE_COORD( pEnd->pev->origin.x); - WRITE_COORD( pEnd->pev->origin.y); - WRITE_COORD( pEnd->pev->origin.z); - } - - - } - else - { - if ( pev->spawnflags & SF_BEAM_RING) - WRITE_BYTE( TE_BEAMRING ); - else - WRITE_BYTE( TE_BEAMENTS ); - WRITE_SHORT( pStart->entindex() ); - WRITE_SHORT( pEnd->entindex() ); - } - - WRITE_SHORT( m_spriteTexture ); - WRITE_BYTE( m_frameStart ); // framestart - WRITE_BYTE( (int)pev->framerate); // framerate - WRITE_BYTE( (int)(m_life*10.0) ); // life - WRITE_BYTE( m_boltWidth ); // width - WRITE_BYTE( m_noiseAmplitude ); // noise - WRITE_BYTE( (int)pev->rendercolor.x ); // r, g, b - WRITE_BYTE( (int)pev->rendercolor.y ); // r, g, b - WRITE_BYTE( (int)pev->rendercolor.z ); // r, g, b - WRITE_BYTE( pev->renderamt ); // brightness - WRITE_BYTE( m_speed ); // speed - MESSAGE_END(); - DoSparks( pStart->pev->origin, pEnd->pev->origin ); - if ( pev->dmg > 0 ) - { - TraceResult tr; - UTIL_TraceLine( pStart->pev->origin, pEnd->pev->origin, dont_ignore_monsters, NULL, &tr ); - BeamDamageInstant( &tr, pev->dmg ); - } - } -} - - -void CBeam::BeamDamage( TraceResult *ptr ) -{ - RelinkBeam(); - if ( ptr->flFraction != 1.0 && ptr->pHit != NULL ) - { - CBaseEntity *pHit = CBaseEntity::Instance(ptr->pHit); - if ( pHit ) - { - ClearMultiDamage(); - pHit->TraceAttack( pev, pev->dmg * (gpGlobals->time - pev->dmgtime), (ptr->vecEndPos - pev->origin).Normalize(), ptr, DMG_ENERGYBEAM ); - ApplyMultiDamage( pev, pev ); - if ( pev->spawnflags & SF_BEAM_DECALS ) - { - if ( pHit->IsBSPModel() ) - UTIL_DecalTrace( ptr, DECAL_BIGSHOT1 + RANDOM_LONG(0,4) ); - } - } - } - pev->dmgtime = gpGlobals->time; -} - - -void CLightning::DamageThink( void ) -{ - pev->nextthink = gpGlobals->time + 0.1; - TraceResult tr; - UTIL_TraceLine( GetStartPos(), GetEndPos(), dont_ignore_monsters, NULL, &tr ); - BeamDamage( &tr ); -} - - - -void CLightning::Zap( const Vector &vecSrc, const Vector &vecDest ) -{ -#if 1 - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_BEAMPOINTS); - WRITE_COORD(vecSrc.x); - WRITE_COORD(vecSrc.y); - WRITE_COORD(vecSrc.z); - WRITE_COORD(vecDest.x); - WRITE_COORD(vecDest.y); - WRITE_COORD(vecDest.z); - WRITE_SHORT( m_spriteTexture ); - WRITE_BYTE( m_frameStart ); // framestart - WRITE_BYTE( (int)pev->framerate); // framerate - WRITE_BYTE( (int)(m_life*10.0) ); // life - WRITE_BYTE( m_boltWidth ); // width - WRITE_BYTE( m_noiseAmplitude ); // noise - WRITE_BYTE( (int)pev->rendercolor.x ); // r, g, b - WRITE_BYTE( (int)pev->rendercolor.y ); // r, g, b - WRITE_BYTE( (int)pev->rendercolor.z ); // r, g, b - WRITE_BYTE( pev->renderamt ); // brightness - WRITE_BYTE( m_speed ); // speed - MESSAGE_END(); -#else - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE(TE_LIGHTNING); - WRITE_COORD(vecSrc.x); - WRITE_COORD(vecSrc.y); - WRITE_COORD(vecSrc.z); - WRITE_COORD(vecDest.x); - WRITE_COORD(vecDest.y); - WRITE_COORD(vecDest.z); - WRITE_BYTE(10); - WRITE_BYTE(50); - WRITE_BYTE(40); - WRITE_SHORT(m_spriteTexture); - MESSAGE_END(); -#endif - DoSparks( vecSrc, vecDest ); -} - -void CLightning::RandomArea( void ) -{ - int iLoops = 0; - - for (iLoops = 0; iLoops < 10; iLoops++) - { - Vector vecSrc = pev->origin; - - Vector vecDir1 = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) ); - vecDir1 = vecDir1.Normalize(); - TraceResult tr1; - UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, ignore_monsters, ENT(pev), &tr1 ); - - if (tr1.flFraction == 1.0) - continue; - - Vector vecDir2; - do { - vecDir2 = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) ); - } while (DotProduct(vecDir1, vecDir2 ) > 0); - vecDir2 = vecDir2.Normalize(); - TraceResult tr2; - UTIL_TraceLine( vecSrc, vecSrc + vecDir2 * m_radius, ignore_monsters, ENT(pev), &tr2 ); - - if (tr2.flFraction == 1.0) - continue; - - if ((tr1.vecEndPos - tr2.vecEndPos).Length() < m_radius * 0.1) - continue; - - UTIL_TraceLine( tr1.vecEndPos, tr2.vecEndPos, ignore_monsters, ENT(pev), &tr2 ); - - if (tr2.flFraction != 1.0) - continue; - - Zap( tr1.vecEndPos, tr2.vecEndPos ); - - break; - } -} - - -void CLightning::RandomPoint( Vector &vecSrc ) -{ - int iLoops = 0; - - for (iLoops = 0; iLoops < 10; iLoops++) - { - Vector vecDir1 = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) ); - vecDir1 = vecDir1.Normalize(); - TraceResult tr1; - UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, ignore_monsters, ENT(pev), &tr1 ); - - if ((tr1.vecEndPos - vecSrc).Length() < m_radius * 0.1) - continue; - - if (tr1.flFraction == 1.0) - continue; - - Zap( vecSrc, tr1.vecEndPos ); - break; - } -} - - - -void CLightning::BeamUpdateVars( void ) -{ - int beamType; - int pointStart, pointEnd; - - edict_t *pStart = FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(m_iszStartEntity) ); - edict_t *pEnd = FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(m_iszEndEntity) ); - pointStart = IsPointEntity( CBaseEntity::Instance(pStart) ); - pointEnd = IsPointEntity( CBaseEntity::Instance(pEnd) ); - - pev->skin = 0; - pev->sequence = 0; - pev->rendermode = 0; - pev->flags |= FL_CUSTOMENTITY; - pev->model = m_iszSpriteName; - SetTexture( m_spriteTexture ); - - beamType = BEAM_ENTS; - if ( pointStart || pointEnd ) - { - if ( !pointStart ) // One point entity must be in pStart - { - edict_t *pTemp; - // Swap start & end - pTemp = pStart; - pStart = pEnd; - pEnd = pTemp; - int swap = pointStart; - pointStart = pointEnd; - pointEnd = swap; - } - if ( !pointEnd ) - beamType = BEAM_ENTPOINT; - else - beamType = BEAM_POINTS; - } - - SetType( beamType ); - if ( beamType == BEAM_POINTS || beamType == BEAM_ENTPOINT || beamType == BEAM_HOSE ) - { - SetStartPos( pStart->v.origin ); - if ( beamType == BEAM_POINTS || beamType == BEAM_HOSE ) - SetEndPos( pEnd->v.origin ); - else - SetEndEntity( ENTINDEX(pEnd) ); - } - else - { - SetStartEntity( ENTINDEX(pStart) ); - SetEndEntity( ENTINDEX(pEnd) ); - } - - RelinkBeam(); - - SetWidth( m_boltWidth ); - SetNoise( m_noiseAmplitude ); - SetFrame( m_frameStart ); - SetScrollRate( m_speed ); - if ( pev->spawnflags & SF_BEAM_SHADEIN ) - SetFlags( BEAM_FSHADEIN ); - else if ( pev->spawnflags & SF_BEAM_SHADEOUT ) - SetFlags( BEAM_FSHADEOUT ); -} - - -LINK_ENTITY_TO_CLASS( env_laser, CLaser ); - -TYPEDESCRIPTION CLaser::m_SaveData[] = -{ - DEFINE_FIELD( CLaser, m_pSprite, FIELD_CLASSPTR ), - DEFINE_FIELD( CLaser, m_iszSpriteName, FIELD_STRING ), - DEFINE_FIELD( CLaser, m_firePosition, FIELD_POSITION_VECTOR ), -}; - -IMPLEMENT_SAVERESTORE( CLaser, CBeam ); - -void CLaser::Spawn( void ) -{ - if ( FStringNull( pev->model ) ) - { - SetThink( &CLaser::SUB_Remove ); - return; - } - pev->solid = SOLID_NOT; // Remove model & collisions - Precache( ); - - SetThink( &CLaser::StrikeThink ); - pev->flags |= FL_CUSTOMENTITY; - - PointsInit( pev->origin, pev->origin ); - - if ( !m_pSprite && m_iszSpriteName ) - m_pSprite = CSprite::SpriteCreate( STRING(m_iszSpriteName), pev->origin, TRUE ); - else - m_pSprite = NULL; - - if ( m_pSprite ) - m_pSprite->SetTransparency( kRenderGlow, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, pev->renderamt, pev->renderfx ); - - if ( pev->targetname && !(pev->spawnflags & SF_BEAM_STARTON) ) - TurnOff(); - else - TurnOn(); -} - -void CLaser::Precache( void ) -{ - pev->modelindex = PRECACHE_MODEL( (char *)STRING(pev->model) ); - if ( m_iszSpriteName ) - PRECACHE_MODEL( (char *)STRING(m_iszSpriteName) ); -} - - -void CLaser::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "LaserTarget")) - { - pev->message = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "width")) - { - SetWidth( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "NoiseAmplitude")) - { - SetNoise( atoi(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "TextureScroll")) - { - SetScrollRate( atoi(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "texture")) - { - pev->model = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "EndSprite")) - { - m_iszSpriteName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "framestart")) - { - pev->frame = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "damage")) - { - pev->dmg = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBeam::KeyValue( pkvd ); -} - - -int CLaser::IsOn( void ) -{ - if (pev->effects & EF_NODRAW) - return 0; - return 1; -} - - -void CLaser::TurnOff( void ) -{ - pev->effects |= EF_NODRAW; - pev->nextthink = 0; - if ( m_pSprite ) - m_pSprite->TurnOff(); -} - - -void CLaser::TurnOn( void ) -{ - pev->effects &= ~EF_NODRAW; - if ( m_pSprite ) - m_pSprite->TurnOn(); - pev->dmgtime = gpGlobals->time; - pev->nextthink = gpGlobals->time; -} - - -void CLaser::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int active = IsOn(); - - if ( !ShouldToggle( useType, active ) ) - return; - if ( active ) - { - TurnOff(); - } - else - { - TurnOn(); - } -} - - -void CLaser::FireAtPoint( TraceResult &tr ) -{ - SetEndPos( tr.vecEndPos ); - if ( m_pSprite ) - UTIL_SetOrigin( m_pSprite->pev, tr.vecEndPos ); - - BeamDamage( &tr ); - DoSparks( GetStartPos(), tr.vecEndPos ); -} - -void CLaser::StrikeThink( void ) -{ - CBaseEntity *pEnd = RandomTargetname( STRING(pev->message) ); - - if ( pEnd ) - m_firePosition = pEnd->pev->origin; - - TraceResult tr; - - UTIL_TraceLine( pev->origin, m_firePosition, dont_ignore_monsters, NULL, &tr ); - FireAtPoint( tr ); - pev->nextthink = gpGlobals->time + 0.1; -} - - - -class CGlow : public CPointEntity -{ -public: - void Spawn( void ); - void Think( void ); - void Animate( float frames ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - float m_lastTime; - float m_maxFrame; -}; - -LINK_ENTITY_TO_CLASS( env_glow, CGlow ); - -TYPEDESCRIPTION CGlow::m_SaveData[] = -{ - DEFINE_FIELD( CGlow, m_lastTime, FIELD_TIME ), - DEFINE_FIELD( CGlow, m_maxFrame, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CGlow, CPointEntity ); - -void CGlow::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; - - PRECACHE_MODEL( (char *)STRING(pev->model) ); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1; - if ( m_maxFrame > 1.0 && pev->framerate != 0 ) - pev->nextthink = gpGlobals->time + 0.1; - - m_lastTime = gpGlobals->time; -} - - -void CGlow::Think( void ) -{ - Animate( pev->framerate * (gpGlobals->time - m_lastTime) ); - - pev->nextthink = gpGlobals->time + 0.1; - m_lastTime = gpGlobals->time; -} - - -void CGlow::Animate( float frames ) -{ - if ( m_maxFrame > 0 ) - pev->frame = fmod( pev->frame + frames, m_maxFrame ); -} - - -LINK_ENTITY_TO_CLASS( env_sprite, CSprite ); - -TYPEDESCRIPTION CSprite::m_SaveData[] = -{ - DEFINE_FIELD( CSprite, m_lastTime, FIELD_TIME ), - DEFINE_FIELD( CSprite, m_maxFrame, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CSprite, CPointEntity ); - -void CSprite::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; - - Precache(); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1; - if ( pev->targetname && !(pev->spawnflags & SF_SPRITE_STARTON) ) - TurnOff(); - else - TurnOn(); - - // Worldcraft only sets y rotation, copy to Z - if ( pev->angles.y != 0 && pev->angles.z == 0 ) - { - pev->angles.z = pev->angles.y; - pev->angles.y = 0; - } -} - - -void CSprite::Precache( void ) -{ - PRECACHE_MODEL( (char *)STRING(pev->model) ); - - // Reset attachment after save/restore - if ( pev->aiment ) - SetAttachment( pev->aiment, pev->body ); - else - { - // Clear attachment - pev->skin = 0; - pev->body = 0; - } -} - - -void CSprite::SpriteInit( const char *pSpriteName, const Vector &origin ) -{ - pev->model = MAKE_STRING(pSpriteName); - pev->origin = origin; - Spawn(); -} - -CSprite *CSprite::SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate ) -{ - CSprite *pSprite = GetClassPtr( (CSprite *)NULL ); - pSprite->SpriteInit( pSpriteName, origin ); - pSprite->pev->classname = MAKE_STRING("env_sprite"); - pSprite->pev->solid = SOLID_NOT; - pSprite->pev->movetype = MOVETYPE_NOCLIP; - if ( animate ) - pSprite->TurnOn(); - - return pSprite; -} - - -void CSprite::AnimateThink( void ) -{ - Animate( pev->framerate * (gpGlobals->time - m_lastTime) ); - - pev->nextthink = gpGlobals->time + 0.1; - m_lastTime = gpGlobals->time; -} - -void CSprite::AnimateUntilDead( void ) -{ - if ( gpGlobals->time > pev->dmgtime ) - UTIL_Remove(this); - else - { - AnimateThink(); - pev->nextthink = gpGlobals->time; - } -} - -void CSprite::Expand( float scaleSpeed, float fadeSpeed ) -{ - pev->speed = scaleSpeed; - pev->health = fadeSpeed; - SetThink( &CSprite::ExpandThink ); - - pev->nextthink = gpGlobals->time; - m_lastTime = gpGlobals->time; -} - - -void CSprite::ExpandThink( void ) -{ - float frametime = gpGlobals->time - m_lastTime; - pev->scale += pev->speed * frametime; - pev->renderamt -= pev->health * frametime; - if ( pev->renderamt <= 0 ) - { - pev->renderamt = 0; - UTIL_Remove( this ); - } - else - { - pev->nextthink = gpGlobals->time + 0.1; - m_lastTime = gpGlobals->time; - } -} - - -void CSprite::Animate( float frames ) -{ - pev->frame += frames; - if ( pev->frame > m_maxFrame ) - { - if ( pev->spawnflags & SF_SPRITE_ONCE ) - { - TurnOff(); - } - else - { - if ( m_maxFrame > 0 ) - pev->frame = fmod( pev->frame, m_maxFrame ); - } - } -} - - -void CSprite::TurnOff( void ) -{ - pev->effects = EF_NODRAW; - pev->nextthink = 0; -} - - -void CSprite::TurnOn( void ) -{ - pev->effects = 0; - if ( (pev->framerate && m_maxFrame > 1.0) || (pev->spawnflags & SF_SPRITE_ONCE) ) - { - SetThink( &CSprite::AnimateThink ); - pev->nextthink = gpGlobals->time; - m_lastTime = gpGlobals->time; - } - pev->frame = 0; -} - - -void CSprite::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int on = pev->effects != EF_NODRAW; - if ( ShouldToggle( useType, on ) ) - { - if ( on ) - { - TurnOff(); - } - else - { - TurnOn(); - } - } -} - - -class CGibShooter : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT ShootThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual CGib *CreateGib( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - int m_iGibs; - int m_iGibCapacity; - int m_iGibMaterial; - int m_iGibModelIndex; - float m_flGibVelocity; - float m_flVariance; - float m_flGibLife; -}; - -TYPEDESCRIPTION CGibShooter::m_SaveData[] = -{ - DEFINE_FIELD( CGibShooter, m_iGibs, FIELD_INTEGER ), - DEFINE_FIELD( CGibShooter, m_iGibCapacity, FIELD_INTEGER ), - DEFINE_FIELD( CGibShooter, m_iGibMaterial, FIELD_INTEGER ), - DEFINE_FIELD( CGibShooter, m_iGibModelIndex, FIELD_INTEGER ), - DEFINE_FIELD( CGibShooter, m_flGibVelocity, FIELD_FLOAT ), - DEFINE_FIELD( CGibShooter, m_flVariance, FIELD_FLOAT ), - DEFINE_FIELD( CGibShooter, m_flGibLife, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CGibShooter, CBaseDelay ); -LINK_ENTITY_TO_CLASS( gibshooter, CGibShooter ); - - -void CGibShooter :: Precache ( void ) -{ - if ( g_Language == LANGUAGE_GERMAN ) - { - m_iGibModelIndex = PRECACHE_MODEL ("models/germanygibs.mdl"); - } - else - { - m_iGibModelIndex = PRECACHE_MODEL ("models/hgibs.mdl"); - } -} - - -void CGibShooter::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "m_iGibs")) - { - m_iGibs = m_iGibCapacity = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_flVelocity")) - { - m_flGibVelocity = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_flVariance")) - { - m_flVariance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_flGibLife")) - { - m_flGibLife = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - { - CBaseDelay::KeyValue( pkvd ); - } -} - -void CGibShooter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetThink( &CGibShooter::ShootThink ); - pev->nextthink = gpGlobals->time; -} - -void CGibShooter::Spawn( void ) -{ - Precache(); - - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; - - if ( m_flDelay == 0 ) - { - m_flDelay = 0.1; - } - - if ( m_flGibLife == 0 ) - { - m_flGibLife = 25; - } - - SetMovedir ( pev ); - pev->body = MODEL_FRAMES( m_iGibModelIndex ); -} - - -CGib *CGibShooter :: CreateGib ( void ) -{ - if ( CVAR_GET_FLOAT("violence_hgibs") == 0 ) - return NULL; - - CGib *pGib = GetClassPtr( (CGib *)NULL ); - pGib->Spawn( "models/hgibs.mdl" ); - pGib->m_bloodColor = BLOOD_COLOR_RED; - - if ( pev->body <= 1 ) - { - ALERT ( at_aiconsole, "GibShooter Body is <= 1!\n" ); - } - - pGib->pev->body = RANDOM_LONG ( 1, pev->body - 1 );// avoid throwing random amounts of the 0th gib. (skull). - - return pGib; -} - - -void CGibShooter :: ShootThink ( void ) -{ - pev->nextthink = gpGlobals->time + m_flDelay; - - Vector vecShootDir; - - vecShootDir = pev->movedir; - - vecShootDir = vecShootDir + gpGlobals->v_right * RANDOM_FLOAT( -1, 1) * m_flVariance;; - vecShootDir = vecShootDir + gpGlobals->v_forward * RANDOM_FLOAT( -1, 1) * m_flVariance;; - vecShootDir = vecShootDir + gpGlobals->v_up * RANDOM_FLOAT( -1, 1) * m_flVariance;; - - vecShootDir = vecShootDir.Normalize(); - CGib *pGib = CreateGib(); - - if ( pGib ) - { - pGib->pev->origin = pev->origin; - pGib->pev->velocity = vecShootDir * m_flGibVelocity; - - pGib->pev->avelocity.x = RANDOM_FLOAT ( 100, 200 ); - pGib->pev->avelocity.y = RANDOM_FLOAT ( 100, 300 ); - - float thinkTime = pGib->pev->nextthink - gpGlobals->time; - - pGib->m_lifeTime = (m_flGibLife * RANDOM_FLOAT( 0.95, 1.05 )); // +/- 5% - if ( pGib->m_lifeTime < thinkTime ) - { - pGib->pev->nextthink = gpGlobals->time + pGib->m_lifeTime; - pGib->m_lifeTime = 0; - } - - } - - if ( --m_iGibs <= 0 ) - { - if ( pev->spawnflags & SF_GIBSHOOTER_REPEATABLE ) - { - m_iGibs = m_iGibCapacity; - SetThink ( NULL ); - pev->nextthink = gpGlobals->time; - } - else - { - SetThink ( &CGibShooter::SUB_Remove ); - pev->nextthink = gpGlobals->time; - } - } -} - - -class CEnvShooter : public CGibShooter -{ - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - - CGib *CreateGib( void ); -}; - -LINK_ENTITY_TO_CLASS( env_shooter, CEnvShooter ); - -void CEnvShooter :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "shootmodel")) - { - pev->model = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "shootsounds")) - { - int iNoise = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - switch( iNoise ) - { - case 0: - m_iGibMaterial = matGlass; - break; - case 1: - m_iGibMaterial = matWood; - break; - case 2: - m_iGibMaterial = matMetal; - break; - case 3: - m_iGibMaterial = matFlesh; - break; - case 4: - m_iGibMaterial = matRocks; - break; - - default: - case -1: - m_iGibMaterial = matNone; - break; - } - } - else - { - CGibShooter::KeyValue( pkvd ); - } -} - - -void CEnvShooter :: Precache ( void ) -{ - m_iGibModelIndex = PRECACHE_MODEL( (char *)STRING(pev->model) ); - CBreakable::MaterialSoundPrecache( (Materials)m_iGibMaterial ); -} - - -CGib *CEnvShooter :: CreateGib ( void ) -{ - CGib *pGib = GetClassPtr( (CGib *)NULL ); - - pGib->Spawn( STRING(pev->model) ); - - int bodyPart = 0; - - if ( pev->body > 1 ) - bodyPart = RANDOM_LONG( 0, pev->body-1 ); - - pGib->pev->body = bodyPart; - pGib->m_bloodColor = DONT_BLEED; - pGib->m_material = m_iGibMaterial; - - pGib->pev->rendermode = pev->rendermode; - pGib->pev->renderamt = pev->renderamt; - pGib->pev->rendercolor = pev->rendercolor; - pGib->pev->renderfx = pev->renderfx; - pGib->pev->scale = pev->scale; - pGib->pev->skin = pev->skin; - - return pGib; -} - - - - -class CTestEffect : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - // void KeyValue( KeyValueData *pkvd ); - void EXPORT TestThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - int m_iLoop; - int m_iBeam; - CBeam *m_pBeam[24]; - float m_flBeamTime[24]; - float m_flStartTime; -}; - - -LINK_ENTITY_TO_CLASS( test_effect, CTestEffect ); - -void CTestEffect::Spawn( void ) -{ - Precache( ); -} - -void CTestEffect::Precache( void ) -{ - PRECACHE_MODEL( "sprites/lgtning.spr" ); -} - -void CTestEffect::TestThink( void ) -{ - int i; - float t = (gpGlobals->time - m_flStartTime); - - if (m_iBeam < 24) - { - CBeam *pbeam = CBeam::BeamCreate( "sprites/lgtning.spr", 100 ); - - TraceResult tr; - - Vector vecSrc = pev->origin; - Vector vecDir = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) ); - vecDir = vecDir.Normalize(); - UTIL_TraceLine( vecSrc, vecSrc + vecDir * 128, ignore_monsters, ENT(pev), &tr); - - pbeam->PointsInit( vecSrc, tr.vecEndPos ); - // pbeam->SetColor( 80, 100, 255 ); - pbeam->SetColor( 255, 180, 100 ); - pbeam->SetWidth( 100 ); - pbeam->SetScrollRate( 12 ); - - m_flBeamTime[m_iBeam] = gpGlobals->time; - m_pBeam[m_iBeam] = pbeam; - m_iBeam++; - -#if 0 - Vector vecMid = (vecSrc + tr.vecEndPos) * 0.5; - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE(TE_DLIGHT); - WRITE_COORD(vecMid.x); // X - WRITE_COORD(vecMid.y); // Y - WRITE_COORD(vecMid.z); // Z - WRITE_BYTE( 20 ); // radius * 0.1 - WRITE_BYTE( 255 ); // r - WRITE_BYTE( 180 ); // g - WRITE_BYTE( 100 ); // b - WRITE_BYTE( 20 ); // time * 10 - WRITE_BYTE( 0 ); // decay * 0.1 - MESSAGE_END( ); -#endif - } - - if (t < 3.0) - { - for (i = 0; i < m_iBeam; i++) - { - t = (gpGlobals->time - m_flBeamTime[i]) / ( 3 + m_flStartTime - m_flBeamTime[i]); - m_pBeam[i]->SetBrightness( 255 * t ); - // m_pBeam[i]->SetScrollRate( 20 * t ); - } - pev->nextthink = gpGlobals->time + 0.1; - } - else - { - for (i = 0; i < m_iBeam; i++) - { - UTIL_Remove( m_pBeam[i] ); - } - m_flStartTime = gpGlobals->time; - m_iBeam = 0; - // pev->nextthink = gpGlobals->time; - SetThink( NULL ); - } -} - - -void CTestEffect::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetThink( &CTestEffect::TestThink ); - pev->nextthink = gpGlobals->time + 0.1; - m_flStartTime = gpGlobals->time; -} - - - -// Blood effects -class CBlood : public CPointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - inline int Color( void ) { return pev->impulse; } - inline float BloodAmount( void ) { return pev->dmg; } - - inline void SetColor( int color ) { pev->impulse = color; } - inline void SetBloodAmount( float amount ) { pev->dmg = amount; } - - Vector Direction( void ); - Vector BloodPosition( CBaseEntity *pActivator ); - -private: -}; - -LINK_ENTITY_TO_CLASS( env_blood, CBlood ); - - - -#define SF_BLOOD_RANDOM 0x0001 -#define SF_BLOOD_STREAM 0x0002 -#define SF_BLOOD_PLAYER 0x0004 -#define SF_BLOOD_DECAL 0x0008 - -void CBlood::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; - SetMovedir( pev ); -} - - -void CBlood::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "color")) - { - int color = atoi(pkvd->szValue); - switch( color ) - { - case 1: - SetColor( BLOOD_COLOR_YELLOW ); - break; - default: - SetColor( BLOOD_COLOR_RED ); - break; - } - - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "amount")) - { - SetBloodAmount( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -Vector CBlood::Direction( void ) -{ - if ( pev->spawnflags & SF_BLOOD_RANDOM ) - return UTIL_RandomBloodVector(); - - return pev->movedir; -} - - -Vector CBlood::BloodPosition( CBaseEntity *pActivator ) -{ - if ( pev->spawnflags & SF_BLOOD_PLAYER ) - { - edict_t *pPlayer; - - if ( pActivator && pActivator->IsPlayer() ) - { - pPlayer = pActivator->edict(); - } - else - pPlayer = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - if ( pPlayer ) - return (pPlayer->v.origin + pPlayer->v.view_ofs) + Vector( RANDOM_FLOAT(-10,10), RANDOM_FLOAT(-10,10), RANDOM_FLOAT(-10,10) ); - } - - return pev->origin; -} - - -void CBlood::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->spawnflags & SF_BLOOD_STREAM ) - UTIL_BloodStream( BloodPosition(pActivator), Direction(), Color(), BloodAmount() ); - else - UTIL_BloodDrips( BloodPosition(pActivator), Direction(), Color(), BloodAmount() ); - - if ( pev->spawnflags & SF_BLOOD_DECAL ) - { - Vector forward = Direction(); - Vector start = BloodPosition( pActivator ); - TraceResult tr; - - UTIL_TraceLine( start, start + forward * BloodAmount() * 2, ignore_monsters, NULL, &tr ); - if ( tr.flFraction != 1.0 ) - UTIL_BloodDecalTrace( &tr, Color() ); - } -} - - - -// Screen shake -class CShake : public CPointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - inline float Amplitude( void ) { return pev->scale; } - inline float Frequency( void ) { return pev->dmg_save; } - inline float Duration( void ) { return pev->dmg_take; } - inline float Radius( void ) { return pev->dmg; } - - inline void SetAmplitude( float amplitude ) { pev->scale = amplitude; } - inline void SetFrequency( float frequency ) { pev->dmg_save = frequency; } - inline void SetDuration( float duration ) { pev->dmg_take = duration; } - inline void SetRadius( float radius ) { pev->dmg = radius; } -private: -}; - -LINK_ENTITY_TO_CLASS( env_shake, CShake ); - -// pev->scale is amplitude -// pev->dmg_save is frequency -// pev->dmg_take is duration -// pev->dmg is radius -// radius of 0 means all players -// NOTE: UTIL_ScreenShake() will only shake players who are on the ground - -#define SF_SHAKE_EVERYONE 0x0001 // Don't check radius -// UNDONE: These don't work yet -#define SF_SHAKE_DISRUPT 0x0002 // Disrupt controls -#define SF_SHAKE_INAIR 0x0004 // Shake players in air - -void CShake::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; - - if ( pev->spawnflags & SF_SHAKE_EVERYONE ) - pev->dmg = 0; -} - - -void CShake::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "amplitude")) - { - SetAmplitude( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "frequency")) - { - SetFrequency( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "duration")) - { - SetDuration( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "radius")) - { - SetRadius( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -void CShake::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - UTIL_ScreenShake( pev->origin, Amplitude(), Frequency(), Duration(), Radius() ); -} - - -class CFade : public CPointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - inline float Duration( void ) { return pev->dmg_take; } - inline float HoldTime( void ) { return pev->dmg_save; } - - inline void SetDuration( float duration ) { pev->dmg_take = duration; } - inline void SetHoldTime( float hold ) { pev->dmg_save = hold; } -private: -}; - -LINK_ENTITY_TO_CLASS( env_fade, CFade ); - -// pev->dmg_take is duration -// pev->dmg_save is hold duration -#define SF_FADE_IN 0x0001 // Fade in, not out -#define SF_FADE_MODULATE 0x0002 // Modulate, don't blend -#define SF_FADE_ONLYONE 0x0004 - -void CFade::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; -} - - -void CFade::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "duration")) - { - SetDuration( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "holdtime")) - { - SetHoldTime( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -void CFade::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int fadeFlags = 0; - - if ( !(pev->spawnflags & SF_FADE_IN) ) - fadeFlags |= FFADE_OUT; - - if ( pev->spawnflags & SF_FADE_MODULATE ) - fadeFlags |= FFADE_MODULATE; - - if ( pev->spawnflags & SF_FADE_ONLYONE ) - { - if ( pActivator->IsNetClient() ) - { - UTIL_ScreenFade( pActivator, pev->rendercolor, Duration(), HoldTime(), pev->renderamt, fadeFlags ); - } - } - else - { - UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), pev->renderamt, fadeFlags ); - } - SUB_UseTargets( this, USE_TOGGLE, 0 ); -} - - -class CMessage : public CPointEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); -private: -}; - -LINK_ENTITY_TO_CLASS( env_message, CMessage ); - - -void CMessage::Spawn( void ) -{ - Precache(); - - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - - switch( pev->impulse ) - { - case 1: // Medium radius - pev->speed = ATTN_STATIC; - break; - - case 2: // Large radius - pev->speed = ATTN_NORM; - break; - - case 3: //EVERYWHERE - pev->speed = ATTN_NONE; - break; - - default: - case 0: // Small radius - pev->speed = ATTN_IDLE; - break; - } - pev->impulse = 0; - - // No volume, use normal - if ( pev->scale <= 0 ) - pev->scale = 1.0; -} - - -void CMessage::Precache( void ) -{ - if ( pev->noise ) - PRECACHE_SOUND( (char *)STRING(pev->noise) ); -} - -void CMessage::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "messagesound")) - { - pev->noise = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "messagevolume")) - { - pev->scale = atof(pkvd->szValue) * 0.1; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "messageattenuation")) - { - pev->impulse = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -void CMessage::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - CBaseEntity *pPlayer = NULL; - - if ( pev->spawnflags & SF_MESSAGE_ALL ) - UTIL_ShowMessageAll( STRING(pev->message) ); - else - { - if ( pActivator && pActivator->IsPlayer() ) - pPlayer = pActivator; - else - { - pPlayer = CBaseEntity::Instance( g_engfuncs.pfnPEntityOfEntIndex( 1 ) ); - } - if ( pPlayer ) - UTIL_ShowMessage( STRING(pev->message), pPlayer ); - } - if ( pev->noise ) - { - EMIT_SOUND( edict(), CHAN_BODY, STRING(pev->noise), pev->scale, pev->speed ); - } - if ( pev->spawnflags & SF_MESSAGE_ONCE ) - UTIL_Remove( this ); - - SUB_UseTargets( this, USE_TOGGLE, 0 ); -} - - - -//========================================================= -// FunnelEffect -//========================================================= -class CEnvFunnel : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - int m_iSprite; // Don't save, precache -}; - -void CEnvFunnel :: Precache ( void ) -{ - m_iSprite = PRECACHE_MODEL ( "sprites/flare6.spr" ); -} - -LINK_ENTITY_TO_CLASS( env_funnel, CEnvFunnel ); - -void CEnvFunnel::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_LARGEFUNNEL ); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( m_iSprite ); - - if ( pev->spawnflags & SF_FUNNEL_REVERSE )// funnel flows in reverse? - { - WRITE_SHORT( 1 ); - } - else - { - WRITE_SHORT( 0 ); - } - - - MESSAGE_END(); - - SetThink( &CEnvFunnel::SUB_Remove ); - pev->nextthink = gpGlobals->time; -} - -void CEnvFunnel::Spawn( void ) -{ - Precache(); - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; -} - -//========================================================= -// Beverage Dispenser -// overloaded pev->frags, is now a flag for whether or not a can is stuck in the dispenser. -// overloaded pev->health, is now how many cans remain in the machine. -//========================================================= -class CEnvBeverage : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); -}; - -void CEnvBeverage :: Precache ( void ) -{ - PRECACHE_MODEL( "models/can.mdl" ); - PRECACHE_SOUND( "weapons/g_bounce3.wav" ); -} - -LINK_ENTITY_TO_CLASS( env_beverage, CEnvBeverage ); - -void CEnvBeverage::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->frags != 0 || pev->health <= 0 ) - { - // no more cans while one is waiting in the dispenser, or if I'm out of cans. - return; - } - - CBaseEntity *pCan = CBaseEntity::Create( "item_sodacan", pev->origin, pev->angles, edict() ); - - if ( pev->skin == 6 ) - { - // random - pCan->pev->skin = RANDOM_LONG( 0, 5 ); - } - else - { - pCan->pev->skin = pev->skin; - } - - pev->frags = 1; - pev->health--; - - //SetThink (SUB_Remove); - //pev->nextthink = gpGlobals->time; -} - -void CEnvBeverage::Spawn( void ) -{ - Precache(); - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; - pev->frags = 0; - - if ( pev->health == 0 ) - { - pev->health = 10; - } -} - -//========================================================= -// Soda can -//========================================================= -class CItemSoda : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void EXPORT CanThink ( void ); - void EXPORT CanTouch ( CBaseEntity *pOther ); -}; - -void CItemSoda :: Precache ( void ) -{ -} - -LINK_ENTITY_TO_CLASS( item_sodacan, CItemSoda ); - -void CItemSoda::Spawn( void ) -{ - Precache(); - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_TOSS; - - SET_MODEL ( ENT(pev), "models/can.mdl" ); - UTIL_SetSize ( pev, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ) ); - - SetThink (&CItemSoda::CanThink); - pev->nextthink = gpGlobals->time + 0.5; -} - -void CItemSoda::CanThink ( void ) -{ - EMIT_SOUND (ENT(pev), CHAN_WEAPON, "weapons/g_bounce3.wav", 1, ATTN_NORM ); - - pev->solid = SOLID_TRIGGER; - UTIL_SetSize ( pev, Vector ( -8, -8, 0 ), Vector ( 8, 8, 8 ) ); - SetThink ( NULL ); - SetTouch ( &CItemSoda::CanTouch ); -} - -void CItemSoda::CanTouch ( CBaseEntity *pOther ) -{ - if ( !pOther->IsPlayer() ) - { - return; - } - - // spoit sound here - - pOther->TakeHealth( 1, DMG_GENERIC );// a bit of health. - - if ( !FNullEnt( pev->owner ) ) - { - // tell the machine the can was taken - pev->owner->v.frags = 0; - } - - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = EF_NODRAW; - SetTouch ( NULL ); - SetThink ( &CItemSoda::SUB_Remove ); - pev->nextthink = gpGlobals->time; -} diff --git a/dmc/dlls/effects.h b/dmc/dlls/effects.h deleted file mode 100644 index f93a9d8..0000000 --- a/dmc/dlls/effects.h +++ /dev/null @@ -1,209 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef EFFECTS_H -#define EFFECTS_H - -#define SF_BEAM_STARTON 0x0001 -#define SF_BEAM_TOGGLE 0x0002 -#define SF_BEAM_RANDOM 0x0004 -#define SF_BEAM_RING 0x0008 -#define SF_BEAM_SPARKSTART 0x0010 -#define SF_BEAM_SPARKEND 0x0020 -#define SF_BEAM_DECALS 0x0040 -#define SF_BEAM_SHADEIN 0x0080 -#define SF_BEAM_SHADEOUT 0x0100 -#define SF_BEAM_TEMPORARY 0x8000 - -#define SF_SPRITE_STARTON 0x0001 -#define SF_SPRITE_ONCE 0x0002 -#define SF_SPRITE_TEMPORARY 0x8000 - -class CSprite : public CPointEntity -{ -public: - void Spawn( void ); - void Precache( void ); - - int ObjectCaps( void ) - { - int flags = 0; - if ( pev->spawnflags & SF_SPRITE_TEMPORARY ) - flags = FCAP_DONT_SAVE; - return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | flags; - } - void EXPORT AnimateThink( void ); - void EXPORT ExpandThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void Animate( float frames ); - void Expand( float scaleSpeed, float fadeSpeed ); - void SpriteInit( const char *pSpriteName, const Vector &origin ); - - inline void SetAttachment( edict_t *pEntity, int attachment ) - { - if ( pEntity ) - { - pev->skin = ENTINDEX(pEntity); - pev->body = attachment; - pev->aiment = pEntity; - pev->movetype = MOVETYPE_FOLLOW; - } - } - void TurnOff( void ); - void TurnOn( void ); - inline float Frames( void ) { return m_maxFrame; } - inline void SetTransparency( int rendermode, int r, int g, int b, int a, int fx ) - { - pev->rendermode = rendermode; - pev->rendercolor.x = r; - pev->rendercolor.y = g; - pev->rendercolor.z = b; - pev->renderamt = a; - pev->renderfx = fx; - } - inline void SetTexture( int spriteIndex ) { pev->modelindex = spriteIndex; } - inline void SetScale( float scale ) { pev->scale = scale; } - inline void SetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; } - inline void SetBrightness( int brightness ) { pev->renderamt = brightness; } - - inline void AnimateAndDie( float framerate ) - { - SetThink(&CSprite::AnimateUntilDead); - pev->framerate = framerate; - pev->dmgtime = gpGlobals->time + (m_maxFrame / framerate); - pev->nextthink = gpGlobals->time; - } - - void EXPORT AnimateUntilDead( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - static CSprite *SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate ); - -private: - - float m_lastTime; - float m_maxFrame; -}; - - -class CBeam : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - int ObjectCaps( void ) - { - int flags = 0; - if ( pev->spawnflags & SF_BEAM_TEMPORARY ) - flags = FCAP_DONT_SAVE; - return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | flags; - } - - void EXPORT TriggerTouch( CBaseEntity *pOther ); - - // These functions are here to show the way beams are encoded as entities. - // Encoding beams as entities simplifies their management in the client/server architecture - inline void SetType( int type ) { pev->rendermode = (pev->rendermode & 0xF0) | (type&0x0F); } - inline void SetFlags( int flags ) { pev->rendermode = (pev->rendermode & 0x0F) | (flags&0xF0); } - inline void SetStartPos( const Vector& pos ) { pev->origin = pos; } - inline void SetEndPos( const Vector& pos ) { pev->angles = pos; } - void SetStartEntity( int entityIndex ); - void SetEndEntity( int entityIndex ); - - inline void SetStartAttachment( int attachment ) { pev->sequence = (pev->sequence & 0x0FFF) | ((attachment&0xF)<<12); } - inline void SetEndAttachment( int attachment ) { pev->skin = (pev->skin & 0x0FFF) | ((attachment&0xF)<<12); } - - inline void SetTexture( int spriteIndex ) { pev->modelindex = spriteIndex; } - inline void SetWidth( int width ) { pev->scale = width; } - inline void SetNoise( int amplitude ) { pev->body = amplitude; } - inline void SetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; } - inline void SetBrightness( int brightness ) { pev->renderamt = brightness; } - inline void SetFrame( float frame ) { pev->frame = frame; } - inline void SetScrollRate( int speed ) { pev->animtime = speed; } - - inline int GetType( void ) { return pev->rendermode & 0x0F; } - inline int GetFlags( void ) { return pev->rendermode & 0xF0; } - inline int GetStartEntity( void ) { return pev->sequence & 0xFFF; } - inline int GetEndEntity( void ) { return pev->skin & 0xFFF; } - - const Vector &GetStartPos( void ); - const Vector &GetEndPos( void ); - - Vector Center( void ) { return (GetStartPos() + GetEndPos()) * 0.5; }; // center point of beam - - inline int GetTexture( void ) { return pev->modelindex; } - inline int GetWidth( void ) { return pev->scale; } - inline int GetNoise( void ) { return pev->body; } - // inline void GetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; } - inline int GetBrightness( void ) { return pev->renderamt; } - inline int GetFrame( void ) { return pev->frame; } - inline int GetScrollRate( void ) { return pev->animtime; } - - // Call after you change start/end positions - void RelinkBeam( void ); -// void SetObjectCollisionBox( void ); - - void DoSparks( const Vector &start, const Vector &end ); - CBaseEntity *RandomTargetname( const char *szName ); - void BeamDamage( TraceResult *ptr ); - // Init after BeamCreate() - void BeamInit( const char *pSpriteName, int width ); - void PointsInit( const Vector &start, const Vector &end ); - void PointEntInit( const Vector &start, int endIndex ); - void EntsInit( int startIndex, int endIndex ); - void HoseInit( const Vector &start, const Vector &direction ); - - static CBeam *BeamCreate( const char *pSpriteName, int width ); - - inline void LiveForTime( float time ) { SetThink(&CBeam::SUB_Remove); pev->nextthink = gpGlobals->time + time; } - inline void BeamDamageInstant( TraceResult *ptr, float damage ) - { - pev->dmg = damage; - pev->dmgtime = gpGlobals->time - 1; - BeamDamage(ptr); - } -}; - - -#define SF_MESSAGE_ONCE 0x0001 // Fade in, not out -#define SF_MESSAGE_ALL 0x0002 // Send to all clients - - -class CLaser : public CBeam -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - - void TurnOn( void ); - void TurnOff( void ); - int IsOn( void ); - - void FireAtPoint( TraceResult &point ); - - void EXPORT StrikeThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - CSprite *m_pSprite; - int m_iszSpriteName; - Vector m_firePosition; -}; - -#endif //EFFECTS_H diff --git a/dmc/dlls/enginecallback.h b/dmc/dlls/enginecallback.h deleted file mode 100644 index 28f3141..0000000 --- a/dmc/dlls/enginecallback.h +++ /dev/null @@ -1,159 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef ENGINECALLBACK_H -#define ENGINECALLBACK_H -#pragma once - -#include "event_flags.h" - -// Must be provided by user of this code -extern enginefuncs_t g_engfuncs; - -// The actual engine callbacks -#define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId) -#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) -#define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel) -#define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound) -#define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric) -#define SET_MODEL (*g_engfuncs.pfnSetModel) -#define MODEL_INDEX (*g_engfuncs.pfnModelIndex) -#define MODEL_FRAMES (*g_engfuncs.pfnModelFrames) -#define SET_SIZE (*g_engfuncs.pfnSetSize) -#define CHANGE_LEVEL (*g_engfuncs.pfnChangeLevel) -#define GET_SPAWN_PARMS (*g_engfuncs.pfnGetSpawnParms) -#define SAVE_SPAWN_PARMS (*g_engfuncs.pfnSaveSpawnParms) -#define VEC_TO_YAW (*g_engfuncs.pfnVecToYaw) -#define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles) -#define MOVE_TO_ORIGIN (*g_engfuncs.pfnMoveToOrigin) -#define oldCHANGE_YAW (*g_engfuncs.pfnChangeYaw) -#define CHANGE_PITCH (*g_engfuncs.pfnChangePitch) -#define MAKE_VECTORS (*g_engfuncs.pfnMakeVectors) -#define CREATE_ENTITY (*g_engfuncs.pfnCreateEntity) -#define REMOVE_ENTITY (*g_engfuncs.pfnRemoveEntity) -#define CREATE_NAMED_ENTITY (*g_engfuncs.pfnCreateNamedEntity) -#define MAKE_STATIC (*g_engfuncs.pfnMakeStatic) -#define ENT_IS_ON_FLOOR (*g_engfuncs.pfnEntIsOnFloor) -#define DROP_TO_FLOOR (*g_engfuncs.pfnDropToFloor) -#define WALK_MOVE (*g_engfuncs.pfnWalkMove) -#define SET_ORIGIN (*g_engfuncs.pfnSetOrigin) -#define EMIT_SOUND_DYN2 (*g_engfuncs.pfnEmitSound) -#define BUILD_SOUND_MSG (*g_engfuncs.pfnBuildSoundMsg) -#define TRACE_LINE (*g_engfuncs.pfnTraceLine) -#define TRACE_TOSS (*g_engfuncs.pfnTraceToss) -#define TRACE_MONSTER_HULL (*g_engfuncs.pfnTraceMonsterHull) -#define TRACE_HULL (*g_engfuncs.pfnTraceHull) -#define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector) -#define SERVER_COMMAND (*g_engfuncs.pfnServerCommand) -#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute) -#define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand) -#define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect) -#define LIGHT_STYLE (*g_engfuncs.pfnLightStyle) -#define DECAL_INDEX (*g_engfuncs.pfnDecalIndex) -#define POINT_CONTENTS (*g_engfuncs.pfnPointContents) -#define CRC32_INIT (*g_engfuncs.pfnCRC32_Init) -#define CRC32_PROCESS_BUFFER (*g_engfuncs.pfnCRC32_ProcessBuffer) -#define CRC32_PROCESS_BYTE (*g_engfuncs.pfnCRC32_ProcessByte) -#define CRC32_FINAL (*g_engfuncs.pfnCRC32_Final) -#define RANDOM_LONG (*g_engfuncs.pfnRandomLong) -#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat) - -inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin = NULL, edict_t *ed = NULL ) { - (*g_engfuncs.pfnMessageBegin)(msg_dest, msg_type, pOrigin, ed); -} -#define MESSAGE_END (*g_engfuncs.pfnMessageEnd) -#define WRITE_BYTE (*g_engfuncs.pfnWriteByte) -#define WRITE_CHAR (*g_engfuncs.pfnWriteChar) -#define WRITE_SHORT (*g_engfuncs.pfnWriteShort) -#define WRITE_LONG (*g_engfuncs.pfnWriteLong) -#define WRITE_ANGLE (*g_engfuncs.pfnWriteAngle) -#define WRITE_COORD (*g_engfuncs.pfnWriteCoord) -#define WRITE_STRING (*g_engfuncs.pfnWriteString) -#define WRITE_ENTITY (*g_engfuncs.pfnWriteEntity) -#define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister) -#define CVAR_GET_FLOAT (*g_engfuncs.pfnCVarGetFloat) -#define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString) -#define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat) -#define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString) -#define ALERT (*g_engfuncs.pfnAlertMessage) -#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf) -#define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData) -inline void *GET_PRIVATE( edict_t *pent ) -{ - if ( pent ) - return pent->pvPrivateData; - return NULL; -} - -#define FREE_PRIVATE (*g_engfuncs.pfnFreeEntPrivateData) -//#define STRING (*g_engfuncs.pfnSzFromIndex) -#define ALLOC_STRING (*g_engfuncs.pfnAllocString) -#define FIND_ENTITY_BY_STRING (*g_engfuncs.pfnFindEntityByString) -#define GETENTITYILLUM (*g_engfuncs.pfnGetEntityIllum) -#define FIND_ENTITY_IN_SPHERE (*g_engfuncs.pfnFindEntityInSphere) -#define FIND_CLIENT_IN_PVS (*g_engfuncs.pfnFindClientInPVS) -#define EMIT_AMBIENT_SOUND (*g_engfuncs.pfnEmitAmbientSound) -#define GET_MODEL_PTR (*g_engfuncs.pfnGetModelPtr) -#define REG_USER_MSG (*g_engfuncs.pfnRegUserMsg) -#define GET_BONE_POSITION (*g_engfuncs.pfnGetBonePosition) -#define FUNCTION_FROM_NAME (*g_engfuncs.pfnFunctionFromName) -#define NAME_FOR_FUNCTION (*g_engfuncs.pfnNameForFunction) -#define TRACE_TEXTURE (*g_engfuncs.pfnTraceTexture) -#define CLIENT_PRINTF (*g_engfuncs.pfnClientPrintf) -#define CMD_ARGS (*g_engfuncs.pfnCmd_Args) -#define CMD_ARGC (*g_engfuncs.pfnCmd_Argc) -#define CMD_ARGV (*g_engfuncs.pfnCmd_Argv) -#define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment) -#define SET_VIEW (*g_engfuncs.pfnSetView) -#define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle) -#define LOAD_FILE_FOR_ME (*g_engfuncs.pfnLoadFileForMe) -#define FREE_FILE (*g_engfuncs.pfnFreeFile) -#define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime) -#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir) -#define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid) -#define NUMBER_OF_ENTITIES (*g_engfuncs.pfnNumberOfEntities) -#define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer) - -#define CVAR_GET_POINTER (*g_engfuncs.pfnCVarGetPointer) - -#define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent) -#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent) - -#define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS) -#define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS) - -#define ENGINE_CHECK_VISIBILITY (*g_engfuncs.pfnCheckVisibility) - -#define DELTA_SET ( *g_engfuncs.pfnDeltaSetField ) -#define DELTA_UNSET ( *g_engfuncs.pfnDeltaUnsetField ) -#define DELTA_ADDENCODER ( *g_engfuncs.pfnDeltaAddEncoder ) -#define ENGINE_CURRENT_PLAYER ( *g_engfuncs.pfnGetCurrentPlayer ) - -#define ENGINE_CANSKIP ( *g_engfuncs.pfnCanSkipPlayer ) - -#define DELTA_FINDFIELD ( *g_engfuncs.pfnDeltaFindField ) -#define DELTA_SETBYINDEX ( *g_engfuncs.pfnDeltaSetFieldByIndex ) -#define DELTA_UNSETBYINDEX ( *g_engfuncs.pfnDeltaUnsetFieldByIndex ) - -#define ENGINE_GETPHYSINFO ( *g_engfuncs.pfnGetPhysicsInfoString ) - -#define ENGINE_SETGROUPMASK ( *g_engfuncs.pfnSetGroupMask ) - -#define ENGINE_INSTANCE_BASELINE ( *g_engfuncs.pfnCreateInstancedBaseline ) - -#define ENGINE_FORCE_UNMODIFIED ( *g_engfuncs.pfnForceUnmodified ) - -#define PLAYER_CNX_STATS ( *g_engfuncs.pfnGetPlayerStats ) - -#endif //ENGINECALLBACK_H diff --git a/dmc/dlls/explode.cpp b/dmc/dlls/explode.cpp deleted file mode 100644 index 4e5f1c1..0000000 --- a/dmc/dlls/explode.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== explode.cpp ======================================================== - - Explosion-related code - -*/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "decals.h" -#include "explode.h" - -// Spark Shower -class CShower : public CBaseEntity -{ - void Spawn( void ); - void Think( void ); - void Touch( CBaseEntity *pOther ); - int ObjectCaps( void ) { return FCAP_DONT_SAVE; } -}; - -LINK_ENTITY_TO_CLASS( spark_shower, CShower ); - -void CShower::Spawn( void ) -{ - pev->velocity = RANDOM_FLOAT( 200, 300 ) * pev->angles; - pev->velocity.x += RANDOM_FLOAT(-100.f,100.f); - pev->velocity.y += RANDOM_FLOAT(-100.f,100.f); - if ( pev->velocity.z >= 0 ) - pev->velocity.z += 200; - else - pev->velocity.z -= 200; - pev->movetype = MOVETYPE_BOUNCE; - pev->gravity = 0.5; - pev->nextthink = gpGlobals->time + 0.1; - pev->solid = SOLID_NOT; - SET_MODEL( edict(), "models/grenade.mdl"); // Need a model, just use the grenade, we don't draw it anyway - UTIL_SetSize(pev, g_vecZero, g_vecZero ); - pev->effects |= EF_NODRAW; - pev->speed = RANDOM_FLOAT( 0.5, 1.5 ); - - pev->angles = g_vecZero; -} - - -void CShower::Think( void ) -{ - UTIL_Sparks( pev->origin ); - - pev->speed -= 0.1; - if ( pev->speed > 0 ) - pev->nextthink = gpGlobals->time + 0.1; - else - UTIL_Remove( this ); - pev->flags &= ~FL_ONGROUND; -} - -void CShower::Touch( CBaseEntity *pOther ) -{ - if ( pev->flags & FL_ONGROUND ) - pev->velocity = pev->velocity * 0.1; - else - pev->velocity = pev->velocity * 0.6; - - if ( (pev->velocity.x*pev->velocity.x+pev->velocity.y*pev->velocity.y) < 10.0 ) - pev->speed = 0; -} - -class CEnvExplosion : public CBaseMonster -{ -public: - void Spawn( ); - void EXPORT Smoke ( void ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - int m_iMagnitude;// how large is the fireball? how much damage? - int m_spriteScale; // what's the exact fireball sprite scale? -}; - -TYPEDESCRIPTION CEnvExplosion::m_SaveData[] = -{ - DEFINE_FIELD( CEnvExplosion, m_iMagnitude, FIELD_INTEGER ), - DEFINE_FIELD( CEnvExplosion, m_spriteScale, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CEnvExplosion, CBaseMonster ); -LINK_ENTITY_TO_CLASS( env_explosion, CEnvExplosion ); - -void CEnvExplosion::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "iMagnitude")) - { - m_iMagnitude = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -void CEnvExplosion::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; - - pev->movetype = MOVETYPE_NONE; - /* - if ( m_iMagnitude > 250 ) - { - m_iMagnitude = 250; - } - */ - - float flSpriteScale; - flSpriteScale = ( m_iMagnitude - 50) * 0.6; - - /* - if ( flSpriteScale > 50 ) - { - flSpriteScale = 50; - } - */ - if ( flSpriteScale < 10 ) - { - flSpriteScale = 10; - } - - m_spriteScale = (int)flSpriteScale; -} - -void CEnvExplosion::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - TraceResult tr; - - pev->model = iStringNull;//invisible - pev->solid = SOLID_NOT;// intangible - - Vector vecSpot;// trace starts here! - - vecSpot = pev->origin + Vector ( 0 , 0 , 8 ); - - UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -40 ), ignore_monsters, ENT(pev), & tr); - - // Pull out of the wall a bit - if ( tr.flFraction != 1.0 ) - { - pev->origin = tr.vecEndPos + (tr.vecPlaneNormal * (m_iMagnitude - 24) * 0.6); - } - else - { - pev->origin = pev->origin; - } - - // draw decal - if (! ( pev->spawnflags & SF_ENVEXPLOSION_NODECAL)) - { - if ( RANDOM_FLOAT( 0 , 1 ) < 0.5 ) - { - UTIL_DecalTrace( &tr, DECAL_SCORCH1 ); - } - else - { - UTIL_DecalTrace( &tr, DECAL_SCORCH2 ); - } - } - - // draw fireball - if ( !( pev->spawnflags & SF_ENVEXPLOSION_NOFIREBALL ) ) - { - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); - WRITE_BYTE( TE_EXPLOSION); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( g_sModelIndexFireball ); - WRITE_BYTE( (BYTE)m_spriteScale ); // scale * 10 - WRITE_BYTE( 15 ); // framerate - WRITE_BYTE( TE_EXPLFLAG_NONE ); - MESSAGE_END(); - } - else - { - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); - WRITE_BYTE( TE_EXPLOSION); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( g_sModelIndexFireball ); - WRITE_BYTE( 0 ); // no sprite - WRITE_BYTE( 15 ); // framerate - WRITE_BYTE( TE_EXPLFLAG_NONE ); - MESSAGE_END(); - } - - // do damage - if ( !( pev->spawnflags & SF_ENVEXPLOSION_NODAMAGE ) ) - { - RadiusDamage ( pev, pev, m_iMagnitude, CLASS_NONE, DMG_BLAST ); - } - - SetThink( &CEnvExplosion::Smoke ); - pev->nextthink = gpGlobals->time + 0.3; - - // draw sparks - if ( !( pev->spawnflags & SF_ENVEXPLOSION_NOSPARKS ) ) - { - int sparkCount = RANDOM_LONG(0,3); - - for ( int i = 0; i < sparkCount; i++ ) - { - Create( "spark_shower", pev->origin, tr.vecPlaneNormal, NULL ); - } - } -} - -void CEnvExplosion::Smoke( void ) -{ - if ( !( pev->spawnflags & SF_ENVEXPLOSION_NOSMOKE ) ) - { - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); - WRITE_BYTE( TE_SMOKE ); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( g_sModelIndexSmoke ); - WRITE_BYTE( (BYTE)m_spriteScale ); // scale * 10 - WRITE_BYTE( 12 ); // framerate - MESSAGE_END(); - } - - if ( !(pev->spawnflags & SF_ENVEXPLOSION_REPEATABLE) ) - { - UTIL_Remove( this ); - } -} - - -// HACKHACK -- create one of these and fake a keyvalue to get the right explosion setup -void ExplosionCreate( const Vector ¢er, const Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage ) -{ - KeyValueData kvd; - char buf[128]; - - CBaseEntity *pExplosion = CBaseEntity::Create( "env_explosion", center, angles, pOwner ); - sprintf( buf, "%3d", magnitude ); - kvd.szKeyName = "iMagnitude"; - kvd.szValue = buf; - pExplosion->KeyValue( &kvd ); - if ( !doDamage ) - pExplosion->pev->spawnflags |= SF_ENVEXPLOSION_NODAMAGE; - - pExplosion->Spawn(); - pExplosion->Use( NULL, NULL, USE_TOGGLE, 0 ); -} diff --git a/dmc/dlls/explode.h b/dmc/dlls/explode.h deleted file mode 100644 index 3feb011..0000000 --- a/dmc/dlls/explode.h +++ /dev/null @@ -1,32 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef EXPLODE_H -#define EXPLODE_H - - -#define SF_ENVEXPLOSION_NODAMAGE ( 1 << 0 ) // when set, ENV_EXPLOSION will not actually inflict damage -#define SF_ENVEXPLOSION_REPEATABLE ( 1 << 1 ) // can this entity be refired? -#define SF_ENVEXPLOSION_NOFIREBALL ( 1 << 2 ) // don't draw the fireball -#define SF_ENVEXPLOSION_NOSMOKE ( 1 << 3 ) // don't draw the smoke -#define SF_ENVEXPLOSION_NODECAL ( 1 << 4 ) // don't make a scorch mark -#define SF_ENVEXPLOSION_NOSPARKS ( 1 << 5 ) // don't make a scorch mark - -extern DLL_GLOBAL short g_sModelIndexFireball; -extern DLL_GLOBAL short g_sModelIndexSmoke; - - -extern void ExplosionCreate( const Vector ¢er, const Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage ); - -#endif //EXPLODE_H diff --git a/dmc/dlls/extdll.h b/dmc/dlls/extdll.h deleted file mode 100644 index eddd955..0000000 --- a/dmc/dlls/extdll.h +++ /dev/null @@ -1,48 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef EXTDLL_H -#define EXTDLL_H - -#include "archtypes.h" // DAL - -// -// Global header file for extension DLLs -// - -#include "Platform.h" - -// Header file containing definition of globalvars_t and entvars_t -typedef unsigned int func_t; // -typedef unsigned int string_t; // from engine's pr_comp.h; -typedef float vec_t; // needed before including progdefs.h - -// Vector class -#include "vector.h" - -// Defining it as a (bogus) struct helps enforce type-checking -#define vec3_t Vector - -// Shared engine/DLL constants -#include "const.h" -#include "progdefs.h" -#include "edict.h" - -// Shared header describing protocol between engine and DLLs -#include "eiface.h" - -// Shared header between the client DLL and the game DLLs -#include "cdll_dll.h" - -#endif //EXTDLL_H diff --git a/dmc/dlls/func_break.cpp b/dmc/dlls/func_break.cpp deleted file mode 100644 index 9ee9f69..0000000 --- a/dmc/dlls/func_break.cpp +++ /dev/null @@ -1,998 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== bmodels.cpp ======================================================== - - spawn, think, and use functions for entities that use brush models - -*/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "func_break.h" -#include "decals.h" -#include "explode.h" - -extern DLL_GLOBAL Vector g_vecAttackDir; - -// =================== FUNC_Breakable ============================================== - -// Just add more items to the bottom of this array and they will automagically be supported -// This is done instead of just a classname in the FGD so we can control which entities can -// be spawned, and still remain fairly flexible -const char *CBreakable::pSpawnObjects[] = -{ - NULL, // 0 - "item_battery", // 1 - "item_healthkit", // 2 - "weapon_9mmhandgun",// 3 - "ammo_9mmclip", // 4 - "weapon_9mmAR", // 5 - "ammo_9mmAR", // 6 - "ammo_ARgrenades", // 7 - "weapon_shotgun", // 8 - "ammo_buckshot", // 9 - "weapon_crossbow", // 10 - "ammo_crossbow", // 11 - "weapon_357", // 12 - "ammo_357", // 13 - "weapon_rpg", // 14 - "ammo_rpgclip", // 15 - "ammo_gaussclip", // 16 - "weapon_handgrenade",// 17 - "weapon_tripmine", // 18 - "weapon_satchel", // 19 - "weapon_snark", // 20 - "weapon_hornetgun", // 21 -}; - -void CBreakable::KeyValue( KeyValueData* pkvd ) -{ - // UNDONE_WC: explicitly ignoring these fields, but they shouldn't be in the map file! - if (FStrEq(pkvd->szKeyName, "explosion")) - { - if (!stricmp(pkvd->szValue, "directed")) - m_Explosion = expDirected; - else if (!stricmp(pkvd->szValue, "random")) - m_Explosion = expRandom; - else - m_Explosion = expRandom; - - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "material")) - { - int i = atoi( pkvd->szValue); - - // 0:glass, 1:metal, 2:flesh, 3:wood - - if ((i < 0) || (i >= matLastMaterial)) - m_Material = matWood; - else - m_Material = (Materials)i; - - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "deadmodel")) - { - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "shards")) - { -// m_iShards = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "gibmodel") ) - { - m_iszGibModel = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spawnobject") ) - { - int object = atoi( pkvd->szValue ); - if ( object > 0 && object < ARRAYSIZE(pSpawnObjects) ) - m_iszSpawnObject = MAKE_STRING( pSpawnObjects[object] ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "explodemagnitude") ) - { - ExplosionSetMagnitude( atoi( pkvd->szValue ) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "lip") ) - pkvd->fHandled = TRUE; - else - CBaseDelay::KeyValue( pkvd ); -} - - -// -// func_breakable - bmodel that breaks into pieces after taking damage -// -LINK_ENTITY_TO_CLASS( func_breakable, CBreakable ); -TYPEDESCRIPTION CBreakable::m_SaveData[] = -{ - DEFINE_FIELD( CBreakable, m_Material, FIELD_INTEGER ), - DEFINE_FIELD( CBreakable, m_Explosion, FIELD_INTEGER ), - -// Don't need to save/restore these because we precache after restore -// DEFINE_FIELD( CBreakable, m_idShard, FIELD_INTEGER ), - - DEFINE_FIELD( CBreakable, m_angle, FIELD_FLOAT ), - DEFINE_FIELD( CBreakable, m_iszGibModel, FIELD_STRING ), - DEFINE_FIELD( CBreakable, m_iszSpawnObject, FIELD_STRING ), - - // Explosion magnitude is stored in pev->impulse -}; - -IMPLEMENT_SAVERESTORE( CBreakable, CBaseEntity ); - -void CBreakable::Spawn( void ) -{ - Precache( ); - - if ( FBitSet( pev->spawnflags, SF_BREAK_TRIGGER_ONLY ) ) - pev->takedamage = DAMAGE_NO; - else - pev->takedamage = DAMAGE_YES; - - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - m_angle = pev->angles.y; - pev->angles.y = 0; - - - SET_MODEL(ENT(pev), STRING(pev->model) );//set size and link into world. - - SetTouch( &CBreakable::BreakTouch ); - if ( FBitSet( pev->spawnflags, SF_BREAK_TRIGGER_ONLY ) ) // Only break on trigger - SetTouch( NULL ); - - // Flag unbreakable glass as "worldbrush" so it will block ALL tracelines - if ( !IsBreakable() && pev->rendermode != kRenderNormal ) - pev->flags |= FL_WORLDBRUSH; -} - - -const char *CBreakable::pSoundsWood[] = -{ - "debris/wood1.wav", - "debris/wood2.wav", - "debris/wood3.wav", -}; - -const char *CBreakable::pSoundsFlesh[] = -{ - "debris/flesh1.wav", - "debris/flesh2.wav", - "debris/flesh3.wav", - "debris/flesh5.wav", - "debris/flesh6.wav", - "debris/flesh7.wav", -}; - -const char *CBreakable::pSoundsMetal[] = -{ - "debris/metal1.wav", - "debris/metal2.wav", - "debris/metal3.wav", -}; - -const char *CBreakable::pSoundsConcrete[] = -{ - "debris/concrete1.wav", - "debris/concrete2.wav", - "debris/concrete3.wav", -}; - - -const char *CBreakable::pSoundsGlass[] = -{ - "debris/glass1.wav", - "debris/glass2.wav", - "debris/glass3.wav", -}; - -const char **CBreakable::MaterialSoundList( Materials precacheMaterial, int &soundCount ) -{ - const char **pSoundList = NULL; - - switch ( precacheMaterial ) - { - case matWood: - pSoundList = pSoundsWood; - soundCount = ARRAYSIZE(pSoundsWood); - break; - case matFlesh: - pSoundList = pSoundsFlesh; - soundCount = ARRAYSIZE(pSoundsFlesh); - break; - case matComputer: - case matUnbreakableGlass: - case matGlass: - pSoundList = pSoundsGlass; - soundCount = ARRAYSIZE(pSoundsGlass); - break; - - case matMetal: - pSoundList = pSoundsMetal; - soundCount = ARRAYSIZE(pSoundsMetal); - break; - - case matCinderBlock: - case matRocks: - pSoundList = pSoundsConcrete; - soundCount = ARRAYSIZE(pSoundsConcrete); - break; - - - case matCeilingTile: - case matNone: - default: - soundCount = 0; - break; - } - - return pSoundList; -} - -void CBreakable::MaterialSoundPrecache( Materials precacheMaterial ) -{ - const char **pSoundList; - int i, soundCount = 0; - - pSoundList = MaterialSoundList( precacheMaterial, soundCount ); - - for ( i = 0; i < soundCount; i++ ) - { - PRECACHE_SOUND( (char *)pSoundList[i] ); - } -} - -void CBreakable::MaterialSoundRandom( edict_t *pEdict, Materials soundMaterial, float volume ) -{ - const char **pSoundList; - int soundCount = 0; - - pSoundList = MaterialSoundList( soundMaterial, soundCount ); - - if ( soundCount ) - EMIT_SOUND( pEdict, CHAN_BODY, pSoundList[ RANDOM_LONG(0,soundCount-1) ], volume, 1.0 ); -} - - -void CBreakable::Precache( void ) -{ - const char *pGibName; - - switch (m_Material) - { - case matWood: - pGibName = "models/woodgibs.mdl"; - - PRECACHE_SOUND("debris/bustcrate1.wav"); - PRECACHE_SOUND("debris/bustcrate2.wav"); - break; - case matFlesh: - pGibName = "models/fleshgibs.mdl"; - - PRECACHE_SOUND("debris/bustflesh1.wav"); - PRECACHE_SOUND("debris/bustflesh2.wav"); - break; - case matComputer: - PRECACHE_SOUND("buttons/spark5.wav"); - PRECACHE_SOUND("buttons/spark6.wav"); - pGibName = "models/computergibs.mdl"; - - PRECACHE_SOUND("debris/bustmetal1.wav"); - PRECACHE_SOUND("debris/bustmetal2.wav"); - break; - - case matUnbreakableGlass: - case matGlass: - pGibName = "models/glassgibs.mdl"; - - PRECACHE_SOUND("debris/bustglass1.wav"); - PRECACHE_SOUND("debris/bustglass2.wav"); - break; - case matMetal: - pGibName = "models/metalplategibs.mdl"; - - PRECACHE_SOUND("debris/bustmetal1.wav"); - PRECACHE_SOUND("debris/bustmetal2.wav"); - break; - case matCinderBlock: - pGibName = "models/cindergibs.mdl"; - - PRECACHE_SOUND("debris/bustconcrete1.wav"); - PRECACHE_SOUND("debris/bustconcrete2.wav"); - break; - case matRocks: - pGibName = "models/rockgibs.mdl"; - - PRECACHE_SOUND("debris/bustconcrete1.wav"); - PRECACHE_SOUND("debris/bustconcrete2.wav"); - break; - case matCeilingTile: - pGibName = "models/ceilinggibs.mdl"; - - PRECACHE_SOUND ("debris/bustceiling.wav"); - break; - } - MaterialSoundPrecache( m_Material ); - if ( m_iszGibModel ) - pGibName = STRING(m_iszGibModel); - - m_idShard = PRECACHE_MODEL( (char *)pGibName ); - - // Precache the spawn item's data - if ( m_iszSpawnObject ) - UTIL_PrecacheOther( (char *)STRING( m_iszSpawnObject ) ); -} - -// play shard sound when func_breakable takes damage. -// the more damage, the louder the shard sound. - - -void CBreakable::DamageSound( void ) -{ - int pitch; - float fvol; - char *rgpsz[6]; - int i; - int material = m_Material; - -// if (RANDOM_LONG(0,1)) -// return; - - if (RANDOM_LONG(0,2)) - pitch = PITCH_NORM; - else - pitch = 95 + RANDOM_LONG(0,34); - - fvol = RANDOM_FLOAT(0.75, 1.0); - - if (material == matComputer && RANDOM_LONG(0,1)) - material = matMetal; - - switch (material) - { - case matComputer: - case matGlass: - case matUnbreakableGlass: - rgpsz[0] = "debris/glass1.wav"; - rgpsz[1] = "debris/glass2.wav"; - rgpsz[2] = "debris/glass3.wav"; - i = 3; - break; - - case matWood: - rgpsz[0] = "debris/wood1.wav"; - rgpsz[1] = "debris/wood2.wav"; - rgpsz[2] = "debris/wood3.wav"; - i = 3; - break; - - case matMetal: - rgpsz[0] = "debris/metal1.wav"; - rgpsz[1] = "debris/metal3.wav"; - rgpsz[2] = "debris/metal2.wav"; - i = 2; - break; - - case matFlesh: - rgpsz[0] = "debris/flesh1.wav"; - rgpsz[1] = "debris/flesh2.wav"; - rgpsz[2] = "debris/flesh3.wav"; - rgpsz[3] = "debris/flesh5.wav"; - rgpsz[4] = "debris/flesh6.wav"; - rgpsz[5] = "debris/flesh7.wav"; - i = 6; - break; - - case matRocks: - case matCinderBlock: - rgpsz[0] = "debris/concrete1.wav"; - rgpsz[1] = "debris/concrete2.wav"; - rgpsz[2] = "debris/concrete3.wav"; - i = 3; - break; - - case matCeilingTile: - // UNDONE: no ceiling tile shard sound yet - i = 0; - break; - } - - if (i) - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, rgpsz[RANDOM_LONG(0,i-1)], fvol, ATTN_NORM, 0, pitch); -} - -void CBreakable::BreakTouch( CBaseEntity *pOther ) -{ - float flDamage; - entvars_t* pevToucher = pOther->pev; - - // only players can break these right now - if ( !pOther->IsPlayer() || !IsBreakable() ) - { - return; - } - - if ( FBitSet ( pev->spawnflags, SF_BREAK_TOUCH ) ) - {// can be broken when run into - flDamage = pevToucher->velocity.Length() * 0.01; - - if (flDamage >= pev->health) - { - SetTouch( NULL ); - TakeDamage(pevToucher, pevToucher, flDamage, DMG_CRUSH); - - // do a little damage to player if we broke glass or computer - pOther->TakeDamage( pev, pev, flDamage/4, DMG_SLASH ); - } - } - - if ( FBitSet ( pev->spawnflags, SF_BREAK_PRESSURE ) && pevToucher->absmin.z >= pev->maxs.z - 2 ) - {// can be broken when stood upon - - // play creaking sound here. - DamageSound(); - - SetThink ( &CBreakable::Die ); - SetTouch( NULL ); - - if ( m_flDelay == 0 ) - {// !!!BUGBUG - why doesn't zero delay work? - m_flDelay = 0.1; - } - - pev->nextthink = pev->ltime + m_flDelay; - - } - -} - - -// -// Smash the our breakable object -// - -// Break when triggered -void CBreakable::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( IsBreakable() ) - { - pev->angles.y = m_angle; - UTIL_MakeVectors(pev->angles); - g_vecAttackDir = gpGlobals->v_forward; - - Die(); - } -} - - -void CBreakable::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ) -{ - // random spark if this is a 'computer' object - if (RANDOM_LONG(0,1) ) - { - switch( m_Material ) - { - case matComputer: - { - UTIL_Sparks( ptr->vecEndPos ); - - float flVolume = RANDOM_FLOAT ( 0.7 , 1.0 );//random volume range - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM); break; - } - } - break; - - case matUnbreakableGlass: - UTIL_Ricochet( ptr->vecEndPos, RANDOM_FLOAT(0.5,1.5) ); - break; - } - } - - CBaseDelay::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType ); -} - -//========================================================= -// Special takedamage for func_breakable. Allows us to make -// exceptions that are breakable-specific -// bitsDamageType indicates the type of damage sustained ie: DMG_CRUSH -//========================================================= -int CBreakable :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - Vector vecTemp; - - // if Attacker == Inflictor, the attack was a melee or other instant-hit attack. - // (that is, no actual entity projectile was involved in the attack so use the shooter's origin). - if ( pevAttacker == pevInflictor ) - { - vecTemp = pevInflictor->origin - ( pev->absmin + ( pev->size * 0.5 ) ); - - // if a client hit the breakable with a crowbar, and breakable is crowbar-sensitive, break it now. - if ( FBitSet ( pevAttacker->flags, FL_CLIENT ) && - FBitSet ( pev->spawnflags, SF_BREAK_CROWBAR ) && (bitsDamageType & DMG_CLUB)) - flDamage = pev->health; - } - else - // an actual missile was involved. - { - vecTemp = pevInflictor->origin - ( pev->absmin + ( pev->size * 0.5 ) ); - } - - if (!IsBreakable()) - return 0; - - // Breakables take double damage from the crowbar - if ( bitsDamageType & DMG_CLUB ) - flDamage *= 2; - - // Boxes / glass / etc. don't take much poison damage, just the impact of the dart - consider that 10% - if ( bitsDamageType & DMG_POISON ) - flDamage *= 0.1; - -// this global is still used for glass and other non-monster killables, along with decals. - g_vecAttackDir = vecTemp.Normalize(); - -// do the damage - pev->health -= flDamage; - if (pev->health <= 0) - { - Killed( pevAttacker, GIB_NORMAL ); - Die(); - return 0; - } - - // Make a shard noise each time func breakable is hit. - // Don't play shard noise if cbreakable actually died. - - DamageSound(); - - return 1; -} - - -void CBreakable::Die( void ) -{ - Vector vecSpot;// shard origin - Vector vecVelocity;// shard velocity - CBaseEntity *pEntity = NULL; - char cFlag = 0; - int pitch; - float fvol; - - pitch = 95 + RANDOM_LONG(0,29); - - if (pitch > 97 && pitch < 103) - pitch = 100; - - // The more negative pev->health, the louder - // the sound should be. - - fvol = RANDOM_FLOAT(0.85, 1.0) + ( fabs(pev->health) / 100.0); - - if (fvol > 1.0) - fvol = 1.0; - - - switch (m_Material) - { - case matGlass: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_GLASS; - break; - - case matWood: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_WOOD; - break; - - case matComputer: - case matMetal: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_METAL; - break; - - case matFlesh: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_FLESH; - break; - - case matRocks: - case matCinderBlock: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_CONCRETE; - break; - - case matCeilingTile: - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustceiling.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - - - if (m_Explosion == expDirected) - vecVelocity = g_vecAttackDir * 200; - else - { - vecVelocity.x = 0; - vecVelocity.y = 0; - vecVelocity.z = 0; - } - - vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot ); - WRITE_BYTE( TE_BREAKMODEL); - - // position - WRITE_COORD( vecSpot.x ); - WRITE_COORD( vecSpot.y ); - WRITE_COORD( vecSpot.z ); - - // size - WRITE_COORD( pev->size.x); - WRITE_COORD( pev->size.y); - WRITE_COORD( pev->size.z); - - // velocity - WRITE_COORD( vecVelocity.x ); - WRITE_COORD( vecVelocity.y ); - WRITE_COORD( vecVelocity.z ); - - // randomization - WRITE_BYTE( 10 ); - - // Model - WRITE_SHORT( m_idShard ); //model id# - - // # of shards - WRITE_BYTE( 0 ); // let client decide - - // duration - WRITE_BYTE( 25 );// 2.5 seconds - - // flags - WRITE_BYTE( cFlag ); - MESSAGE_END(); - - float size = pev->size.x; - if ( size < pev->size.y ) - size = pev->size.y; - if ( size < pev->size.z ) - size = pev->size.z; - - // !!! HACK This should work! - // Build a box above the entity that looks like an 8 pixel high sheet - Vector mins = pev->absmin; - Vector maxs = pev->absmax; - mins.z = pev->absmax.z; - maxs.z += 8; - - // BUGBUG -- can only find 256 entities on a breakable -- should be enough - CBaseEntity *pList[256]; - int count = UTIL_EntitiesInBox( pList, 256, mins, maxs, FL_ONGROUND ); - if ( count ) - { - for ( int i = 0; i < count; i++ ) - { - ClearBits( pList[i]->pev->flags, FL_ONGROUND ); - pList[i]->pev->groundentity = NULL; - } - } - - // Don't fire something that could fire myself - pev->targetname = 0; - - pev->solid = SOLID_NOT; - // Fire targets on break - SUB_UseTargets( NULL, USE_TOGGLE, 0 ); - - SetThink( &CBreakable::SUB_Remove ); - pev->nextthink = pev->ltime + 0.1; - if ( m_iszSpawnObject ) - CBaseEntity::Create( (char *)STRING(m_iszSpawnObject), VecBModelOrigin(pev), pev->angles, edict() ); - - - if ( Explodable() ) - { - ExplosionCreate( Center(), pev->angles, edict(), ExplosionMagnitude(), TRUE ); - } -} - - - -BOOL CBreakable :: IsBreakable( void ) -{ - return m_Material != matUnbreakableGlass; -} - - -int CBreakable :: DamageDecal( int bitsDamageType ) -{ - if ( m_Material == matGlass ) - return DECAL_GLASSBREAK1 + RANDOM_LONG(0,2); - - if ( m_Material == matUnbreakableGlass ) - return DECAL_BPROOF1; - - return CBaseEntity::DamageDecal( bitsDamageType ); -} - - -class CPushable : public CBreakable -{ -public: - void Spawn ( void ); - void Precache( void ); - void Touch ( CBaseEntity *pOther ); - void Move( CBaseEntity *pMover, int push ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT StopSound( void ); -// virtual void SetActivator( CBaseEntity *pActivator ) { m_pPusher = pActivator; } - - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_CONTINUOUS_USE; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - inline float MaxSpeed( void ) { return m_maxSpeed; } - - // breakables use an overridden takedamage - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - - static TYPEDESCRIPTION m_SaveData[]; - - static char *m_soundNames[3]; - int m_lastSound; // no need to save/restore, just keeps the same sound from playing twice in a row - float m_maxSpeed; - float m_soundTime; -}; - -TYPEDESCRIPTION CPushable::m_SaveData[] = -{ - DEFINE_FIELD( CPushable, m_maxSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CPushable, m_soundTime, FIELD_TIME ), -}; - -IMPLEMENT_SAVERESTORE( CPushable, CBreakable ); - -LINK_ENTITY_TO_CLASS( func_pushable, CPushable ); - -char *CPushable :: m_soundNames[3] = { "debris/pushbox1.wav", "debris/pushbox2.wav", "debris/pushbox3.wav" }; - - -void CPushable :: Spawn( void ) -{ - if ( pev->spawnflags & SF_PUSH_BREAKABLE ) - CBreakable::Spawn(); - else - Precache( ); - - pev->movetype = MOVETYPE_PUSHSTEP; - pev->solid = SOLID_BBOX; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - if ( pev->friction > 399 ) - pev->friction = 399; - - m_maxSpeed = 400 - pev->friction; - SetBits( pev->flags, FL_FLOAT ); - pev->friction = 0; - - pev->origin.z += 1; // Pick up off of the floor - UTIL_SetOrigin( pev, pev->origin ); - - // Multiply by area of the box's cross-section (assume 1000 units^3 standard volume) - pev->skin = ( pev->skin * (pev->maxs.x - pev->mins.x) * (pev->maxs.y - pev->mins.y) ) * 0.0005; - m_soundTime = 0; -} - - -void CPushable :: Precache( void ) -{ - for ( int i = 0; i < 3; i++ ) - PRECACHE_SOUND( m_soundNames[i] ); - - if ( pev->spawnflags & SF_PUSH_BREAKABLE ) - CBreakable::Precache( ); -} - - -void CPushable :: KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "size") ) - { - int bbox = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - - switch( bbox ) - { - case 0: // Point - UTIL_SetSize(pev, Vector(-8, -8, -8), Vector(8, 8, 8)); - break; - - case 2: // Big Hull!?!? !!!BUGBUG Figure out what this hull really is - UTIL_SetSize(pev, VEC_DUCK_HULL_MIN*2, VEC_DUCK_HULL_MAX*2); - break; - - case 3: // Player duck - UTIL_SetSize(pev, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX); - break; - - default: - case 1: // Player - UTIL_SetSize(pev, VEC_HULL_MIN, VEC_HULL_MAX); - break; - } - - } - else if ( FStrEq(pkvd->szKeyName, "buoyancy") ) - { - pev->skin = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBreakable::KeyValue( pkvd ); -} - - -// Pull the func_pushable -void CPushable :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !pActivator || !pActivator->IsPlayer() ) - { - if ( pev->spawnflags & SF_PUSH_BREAKABLE ) - this->CBreakable::Use( pActivator, pCaller, useType, value ); - return; - } - - if ( pActivator->pev->velocity != g_vecZero ) - Move( pActivator, 0 ); -} - - -void CPushable :: Touch( CBaseEntity *pOther ) -{ - if ( FClassnameIs( pOther->pev, "worldspawn" ) ) - return; - - Move( pOther, 1 ); -} - - -void CPushable :: Move( CBaseEntity *pOther, int push ) -{ - entvars_t* pevToucher = pOther->pev; - int playerTouch = 0; - - // Is entity standing on this pushable ? - if ( FBitSet(pevToucher->flags,FL_ONGROUND) && pevToucher->groundentity && VARS(pevToucher->groundentity) == pev ) - { - // Only push if floating - if ( pev->waterlevel > 0 ) - pev->velocity.z += pevToucher->velocity.z * 0.1; - - return; - } - - - if ( pOther->IsPlayer() ) - { - if ( push && !(pevToucher->button & (IN_FORWARD|IN_USE)) ) // Don't push unless the player is pushing forward and NOT use (pull) - return; - playerTouch = 1; - } - - float factor; - - if ( playerTouch ) - { - if ( !(pevToucher->flags & FL_ONGROUND) ) // Don't push away from jumping/falling players unless in water - { - if ( pev->waterlevel < 1 ) - return; - else - factor = 0.1; - } - else - factor = 1; - } - else - factor = 0.25; - - pev->velocity.x += pevToucher->velocity.x * factor; - pev->velocity.y += pevToucher->velocity.y * factor; - - float length = sqrt( pev->velocity.x * pev->velocity.x + pev->velocity.y * pev->velocity.y ); - if ( push && (length > MaxSpeed()) ) - { - pev->velocity.x = (pev->velocity.x * MaxSpeed() / length ); - pev->velocity.y = (pev->velocity.y * MaxSpeed() / length ); - } - if ( playerTouch ) - { - pevToucher->velocity.x = pev->velocity.x; - pevToucher->velocity.y = pev->velocity.y; - if ( (gpGlobals->time - m_soundTime) > 0.7 ) - { - m_soundTime = gpGlobals->time; - if ( length > 0 && FBitSet(pev->flags,FL_ONGROUND) ) - { - m_lastSound = RANDOM_LONG(0,2); - EMIT_SOUND(ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound], 0.5, ATTN_NORM); - // SetThink( StopSound ); - // pev->nextthink = pev->ltime + 0.1; - } - else - STOP_SOUND( ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound] ); - } - } -} - -#if 0 -void CPushable::StopSound( void ) -{ - Vector dist = pev->oldorigin - pev->origin; - if ( dist.Length() <= 0 ) - STOP_SOUND( ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound] ); -} -#endif - -int CPushable::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - if ( pev->spawnflags & SF_PUSH_BREAKABLE ) - return CBreakable::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); - - return 1; -} - diff --git a/dmc/dlls/func_break.h b/dmc/dlls/func_break.h deleted file mode 100644 index 9bb281d..0000000 --- a/dmc/dlls/func_break.h +++ /dev/null @@ -1,74 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef FUNC_BREAK_H -#define FUNC_BREAK_H - -typedef enum { expRandom, expDirected} Explosions; -typedef enum { matGlass = 0, matWood, matMetal, matFlesh, matCinderBlock, matCeilingTile, matComputer, matUnbreakableGlass, matRocks, matNone, matLastMaterial } Materials; - -#define NUM_SHARDS 6 // this many shards spawned when breakable objects break; - -class CBreakable : public CBaseDelay -{ -public: - // basic functions - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData* pkvd); - void EXPORT BreakTouch( CBaseEntity *pOther ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void DamageSound( void ); - - // breakables use an overridden takedamage - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - // To spark when hit - void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); - - BOOL IsBreakable( void ); - BOOL SparkWhenHit( void ); - - int DamageDecal( int bitsDamageType ); - - void EXPORT Die( void ); - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - inline BOOL Explodable( void ) { return ExplosionMagnitude() > 0; } - inline int ExplosionMagnitude( void ) { return pev->impulse; } - inline void ExplosionSetMagnitude( int magnitude ) { pev->impulse = magnitude; } - - static void MaterialSoundPrecache( Materials precacheMaterial ); - static void MaterialSoundRandom( edict_t *pEdict, Materials soundMaterial, float volume ); - static const char **MaterialSoundList( Materials precacheMaterial, int &soundCount ); - - static const char *pSoundsWood[]; - static const char *pSoundsFlesh[]; - static const char *pSoundsGlass[]; - static const char *pSoundsMetal[]; - static const char *pSoundsConcrete[]; - static const char *pSpawnObjects[]; - - static TYPEDESCRIPTION m_SaveData[]; - - Materials m_Material; - Explosions m_Explosion; - int m_idShard; - float m_angle; - int m_iszGibModel; - int m_iszSpawnObject; -}; - -#endif // FUNC_BREAK_H diff --git a/dmc/dlls/func_tank.cpp b/dmc/dlls/func_tank.cpp deleted file mode 100644 index 2076285..0000000 --- a/dmc/dlls/func_tank.cpp +++ /dev/null @@ -1,1039 +0,0 @@ -/*** -* -* Copyright (c) 1996-2001, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "effects.h" -#include "weapons.h" -#include "explode.h" - -#include "player.h" - - -#define SF_TANK_ACTIVE 0x0001 -#define SF_TANK_PLAYER 0x0002 -#define SF_TANK_HUMANS 0x0004 -#define SF_TANK_ALIENS 0x0008 -#define SF_TANK_LINEOFSIGHT 0x0010 -#define SF_TANK_CANCONTROL 0x0020 -#define SF_TANK_SOUNDON 0x8000 - -enum TANKBULLET -{ - TANK_BULLET_NONE = 0, - TANK_BULLET_9MM = 1, - TANK_BULLET_MP5 = 2, - TANK_BULLET_12MM = 3, -}; - -// Custom damage -// env_laser (duration is 0.5 rate of fire) -// rockets -// explosion? - -class CFuncTank : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void Think( void ); - void TrackTarget( void ); - - virtual void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); - virtual Vector UpdateTargetPosition( CBaseEntity *pTarget ) - { - return pTarget->BodyTarget( pev->origin ); - } - - void StartRotSound( void ); - void StopRotSound( void ); - - // Bmodels don't go across transitions - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - inline BOOL IsActive( void ) { return (pev->spawnflags & SF_TANK_ACTIVE)?TRUE:FALSE; } - inline void TankActivate( void ) { pev->spawnflags |= SF_TANK_ACTIVE; pev->nextthink = pev->ltime + 0.1; m_fireLast = 0; } - inline void TankDeactivate( void ) { pev->spawnflags &= ~SF_TANK_ACTIVE; m_fireLast = 0; StopRotSound(); } - inline BOOL CanFire( void ) { return (gpGlobals->time - m_lastSightTime) < m_persist; } - BOOL InRange( float range ); - - // Acquire a target. pPlayer is a player in the PVS - edict_t *FindTarget( edict_t *pPlayer ); - - void TankTrace( const Vector &vecStart, const Vector &vecForward, const Vector &vecSpread, TraceResult &tr ); - - Vector BarrelPosition( void ) - { - Vector forward, right, up; - UTIL_MakeVectorsPrivate( pev->angles, forward, right, up ); - return pev->origin + (forward * m_barrelPos.x) + (right * m_barrelPos.y) + (up * m_barrelPos.z); - } - - void AdjustAnglesForBarrel( Vector &angles, float distance ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - BOOL OnControls( entvars_t *pevTest ); - BOOL StartControl( CBasePlayer* pController ); - void StopControl( void ); - void ControllerPostFrame( void ); - - -protected: - CBasePlayer* m_pController; - float m_flNextAttack; - Vector m_vecControllerUsePos; - - float m_yawCenter; // "Center" yaw - float m_yawRate; // Max turn rate to track targets - float m_yawRange; // Range of turning motion (one-sided: 30 is +/- 30 degress from center) - // Zero is full rotation - float m_yawTolerance; // Tolerance angle - - float m_pitchCenter; // "Center" pitch - float m_pitchRate; // Max turn rate on pitch - float m_pitchRange; // Range of pitch motion as above - float m_pitchTolerance; // Tolerance angle - - float m_fireLast; // Last time I fired - float m_fireRate; // How many rounds/second - float m_lastSightTime;// Last time I saw target - float m_persist; // Persistence of firing (how long do I shoot when I can't see) - float m_minRange; // Minimum range to aim/track - float m_maxRange; // Max range to aim/track - - Vector m_barrelPos; // Length of the freakin barrel - float m_spriteScale; // Scale of any sprites we shoot - int m_iszSpriteSmoke; - int m_iszSpriteFlash; - TANKBULLET m_bulletType; // Bullet type - int m_iBulletDamage; // 0 means use Bullet type's default damage - - Vector m_sightOrigin; // Last sight of target - int m_spread; // firing spread - int m_iszMaster; // Master entity (game_team_master or multisource) -}; - - -TYPEDESCRIPTION CFuncTank::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTank, m_yawCenter, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_yawRate, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_yawRange, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_yawTolerance, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_pitchCenter, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_pitchRate, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_pitchRange, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_pitchTolerance, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_fireLast, FIELD_TIME ), - DEFINE_FIELD( CFuncTank, m_fireRate, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_lastSightTime, FIELD_TIME ), - DEFINE_FIELD( CFuncTank, m_persist, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_minRange, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_maxRange, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_barrelPos, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTank, m_spriteScale, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_iszSpriteSmoke, FIELD_STRING ), - DEFINE_FIELD( CFuncTank, m_iszSpriteFlash, FIELD_STRING ), - DEFINE_FIELD( CFuncTank, m_bulletType, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTank, m_sightOrigin, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTank, m_spread, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTank, m_pController, FIELD_CLASSPTR ), - DEFINE_FIELD( CFuncTank, m_vecControllerUsePos, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTank, m_flNextAttack, FIELD_TIME ), - DEFINE_FIELD( CFuncTank, m_iBulletDamage, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTank, m_iszMaster, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTank, CBaseEntity ); - -static Vector gTankSpread[] = -{ - Vector( 0, 0, 0 ), // perfect - Vector( 0.025, 0.025, 0.025 ), // small cone - Vector( 0.05, 0.05, 0.05 ), // medium cone - Vector( 0.1, 0.1, 0.1 ), // large cone - Vector( 0.25, 0.25, 0.25 ), // extra-large cone -}; -#define MAX_FIRING_SPREADS ARRAYSIZE(gTankSpread) - - -void CFuncTank :: Spawn( void ) -{ - Precache(); - - pev->movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything - pev->solid = SOLID_BSP; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - m_yawCenter = pev->angles.y; - m_pitchCenter = pev->angles.x; - - if ( IsActive() ) - pev->nextthink = pev->ltime + 1.0; - - m_sightOrigin = BarrelPosition(); // Point at the end of the barrel - - if ( m_fireRate <= 0 ) - m_fireRate = 1; - if ( m_spread > MAX_FIRING_SPREADS ) - m_spread = 0; - - pev->oldorigin = pev->origin; -} - - -void CFuncTank :: Precache( void ) -{ - if ( m_iszSpriteSmoke ) - PRECACHE_MODEL( (char *)STRING(m_iszSpriteSmoke) ); - if ( m_iszSpriteFlash ) - PRECACHE_MODEL( (char *)STRING(m_iszSpriteFlash) ); - - if ( pev->noise ) - PRECACHE_SOUND( (char *)STRING(pev->noise) ); -} - - -void CFuncTank :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "yawrate")) - { - m_yawRate = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "yawrange")) - { - m_yawRange = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "yawtolerance")) - { - m_yawTolerance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pitchrange")) - { - m_pitchRange = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pitchrate")) - { - m_pitchRate = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pitchtolerance")) - { - m_pitchTolerance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "firerate")) - { - m_fireRate = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "barrel")) - { - m_barrelPos.x = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "barrely")) - { - m_barrelPos.y = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "barrelz")) - { - m_barrelPos.z = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spritescale")) - { - m_spriteScale = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spritesmoke")) - { - m_iszSpriteSmoke = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spriteflash")) - { - m_iszSpriteFlash = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "rotatesound")) - { - pev->noise = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "persistence")) - { - m_persist = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "bullet")) - { - m_bulletType = (TANKBULLET)atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "bullet_damage" )) - { - m_iBulletDamage = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "firespread")) - { - m_spread = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "minRange")) - { - m_minRange = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "maxRange")) - { - m_maxRange = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "master")) - { - m_iszMaster = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -////////////// START NEW STUFF ////////////// - -//================================================================================== -// TANK CONTROLLING -BOOL CFuncTank :: OnControls( entvars_t *pevTest ) -{ - if ( !(pev->spawnflags & SF_TANK_CANCONTROL) ) - return FALSE; - - Vector offset = pevTest->origin - pev->origin; - - if ( (m_vecControllerUsePos - pevTest->origin).Length() < 30 ) - return TRUE; - - return FALSE; -} - -BOOL CFuncTank :: StartControl( CBasePlayer *pController ) -{ - if ( m_pController != NULL ) - return FALSE; - - // Team only or disabled? - if ( m_iszMaster ) - { - if ( !UTIL_IsMasterTriggered( m_iszMaster, pController ) ) - return FALSE; - } - - ALERT( at_console, "using TANK!\n"); - - m_pController = pController; - if ( m_pController->m_pActiveItem ) - { - m_pController->m_pActiveItem->Holster(); - m_pController->pev->weaponmodel = 0; - m_pController->pev->viewmodel = 0; - - } - - m_pController->m_iHideHUD |= HIDEHUD_WEAPONS; - m_vecControllerUsePos = m_pController->pev->origin; - - pev->nextthink = pev->ltime + 0.1; - - return TRUE; -} - -void CFuncTank :: StopControl() -{ - // TODO: bring back the controllers current weapon - if ( !m_pController ) - return; - - if ( m_pController->m_pActiveItem ) - m_pController->m_pActiveItem->Deploy(); - - ALERT( at_console, "stopped using TANK\n"); - - m_pController->m_iHideHUD &= ~HIDEHUD_WEAPONS; - - pev->nextthink = 0; - m_pController = NULL; - - if ( IsActive() ) - pev->nextthink = pev->ltime + 1.0; -} - -// Called each frame by the player's ItemPostFrame -void CFuncTank :: ControllerPostFrame( void ) -{ - ASSERT(m_pController != NULL); - - if ( gpGlobals->time < m_flNextAttack ) - return; - - if ( m_pController->pev->button & IN_ATTACK ) - { - Vector vecForward; - UTIL_MakeVectorsPrivate( pev->angles, vecForward, NULL, NULL ); - - m_fireLast = gpGlobals->time - (1/m_fireRate) - 0.01; // to make sure the gun doesn't fire too many bullets - - Fire( BarrelPosition(), vecForward, m_pController->pev ); - - // HACKHACK -- make some noise (that the AI can hear) - if ( m_pController && m_pController->IsPlayer() ) - ((CBasePlayer *)m_pController)->m_iWeaponVolume = LOUD_GUN_VOLUME; - - m_flNextAttack = gpGlobals->time + (1/m_fireRate); - } -} -////////////// END NEW STUFF ////////////// - - -void CFuncTank :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->spawnflags & SF_TANK_CANCONTROL ) - { // player controlled turret - - if ( pActivator->Classify() != CLASS_PLAYER ) - return; - - if ( value == 2 && useType == USE_SET ) - { - ControllerPostFrame(); - } - else if ( !m_pController && useType != USE_OFF ) - { - ((CBasePlayer*)pActivator)->m_pTank = this; - StartControl( (CBasePlayer*)pActivator ); - } - else - { - StopControl(); - } - } - else - { - if ( !ShouldToggle( useType, IsActive() ) ) - return; - - if ( IsActive() ) - TankDeactivate(); - else - TankActivate(); - } -} - - -edict_t *CFuncTank :: FindTarget( edict_t *pPlayer ) -{ - return pPlayer; -} - - - -BOOL CFuncTank :: InRange( float range ) -{ - if ( range < m_minRange ) - return FALSE; - if ( m_maxRange > 0 && range > m_maxRange ) - return FALSE; - - return TRUE; -} - - -void CFuncTank :: Think( void ) -{ - pev->avelocity = g_vecZero; - TrackTarget(); - - if ( fabs(pev->avelocity.x) > 1 || fabs(pev->avelocity.y) > 1 ) - StartRotSound(); - else - StopRotSound(); -} - -void CFuncTank::TrackTarget( void ) -{ - TraceResult tr; - edict_t *pPlayer = FIND_CLIENT_IN_PVS( edict() ); - BOOL updateTime = FALSE, lineOfSight; - Vector angles, direction, targetPosition, barrelEnd; - edict_t *pTarget; - - // Get a position to aim for - if (m_pController) - { - // Tanks attempt to mirror the player's angles - angles = m_pController->pev->v_angle; - angles[0] = 0 - angles[0]; - pev->nextthink = pev->ltime + 0.05; - } - else - { - if ( IsActive() ) - pev->nextthink = pev->ltime + 0.1; - else - return; - - if ( FNullEnt( pPlayer ) ) - { - if ( IsActive() ) - pev->nextthink = pev->ltime + 2; // Wait 2 secs - return; - } - pTarget = FindTarget( pPlayer ); - if ( !pTarget ) - return; - - // Calculate angle needed to aim at target - barrelEnd = BarrelPosition(); - targetPosition = pTarget->v.origin + pTarget->v.view_ofs; - float range = (targetPosition - barrelEnd).Length(); - - if ( !InRange( range ) ) - return; - - UTIL_TraceLine( barrelEnd, targetPosition, dont_ignore_monsters, edict(), &tr ); - - lineOfSight = FALSE; - // No line of sight, don't track - if ( tr.flFraction == 1.0 || tr.pHit == pTarget ) - { - lineOfSight = TRUE; - - CBaseEntity *pInstance = CBaseEntity::Instance(pTarget); - if ( InRange( range ) && pInstance && pInstance->IsAlive() ) - { - updateTime = TRUE; - m_sightOrigin = UpdateTargetPosition( pInstance ); - } - } - - // Track sight origin - -// !!! I'm not sure what i changed - direction = m_sightOrigin - pev->origin; -// direction = m_sightOrigin - barrelEnd; - angles = UTIL_VecToAngles( direction ); - - // Calculate the additional rotation to point the end of the barrel at the target (not the gun's center) - AdjustAnglesForBarrel( angles, direction.Length() ); - } - - angles.x = -angles.x; - - // Force the angles to be relative to the center position - angles.y = m_yawCenter + UTIL_AngleDistance( angles.y, m_yawCenter ); - angles.x = m_pitchCenter + UTIL_AngleDistance( angles.x, m_pitchCenter ); - - // Limit against range in y - if ( angles.y > m_yawCenter + m_yawRange ) - { - angles.y = m_yawCenter + m_yawRange; - updateTime = FALSE; // Don't update if you saw the player, but out of range - } - else if ( angles.y < (m_yawCenter - m_yawRange) ) - { - angles.y = (m_yawCenter - m_yawRange); - updateTime = FALSE; // Don't update if you saw the player, but out of range - } - - if ( updateTime ) - m_lastSightTime = gpGlobals->time; - - // Move toward target at rate or less - float distY = UTIL_AngleDistance( angles.y, pev->angles.y ); - pev->avelocity.y = distY * 10; - if ( pev->avelocity.y > m_yawRate ) - pev->avelocity.y = m_yawRate; - else if ( pev->avelocity.y < -m_yawRate ) - pev->avelocity.y = -m_yawRate; - - // Limit against range in x - if ( angles.x > m_pitchCenter + m_pitchRange ) - angles.x = m_pitchCenter + m_pitchRange; - else if ( angles.x < m_pitchCenter - m_pitchRange ) - angles.x = m_pitchCenter - m_pitchRange; - - // Move toward target at rate or less - float distX = UTIL_AngleDistance( angles.x, pev->angles.x ); - pev->avelocity.x = distX * 10; - - if ( pev->avelocity.x > m_pitchRate ) - pev->avelocity.x = m_pitchRate; - else if ( pev->avelocity.x < -m_pitchRate ) - pev->avelocity.x = -m_pitchRate; - - if ( m_pController ) - return; - - if ( CanFire() && ( (fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (pev->spawnflags & SF_TANK_LINEOFSIGHT) ) ) - { - BOOL fire = FALSE; - Vector forward; - UTIL_MakeVectorsPrivate( pev->angles, forward, NULL, NULL ); - - if ( pev->spawnflags & SF_TANK_LINEOFSIGHT ) - { - float length = direction.Length(); - UTIL_TraceLine( barrelEnd, barrelEnd + forward * length, dont_ignore_monsters, edict(), &tr ); - if ( tr.pHit == pTarget ) - fire = TRUE; - } - else - fire = TRUE; - - if ( fire ) - { - Fire( BarrelPosition(), forward, pev ); - } - else - m_fireLast = 0; - } - else - m_fireLast = 0; -} - - -// If barrel is offset, add in additional rotation -void CFuncTank::AdjustAnglesForBarrel( Vector &angles, float distance ) -{ - float r2, d2; - - - if ( m_barrelPos.y != 0 || m_barrelPos.z != 0 ) - { - distance -= m_barrelPos.z; - d2 = distance * distance; - if ( m_barrelPos.y ) - { - r2 = m_barrelPos.y * m_barrelPos.y; - angles.y += (180.0 / M_PI) * atan2( m_barrelPos.y, sqrt( d2 - r2 ) ); - } - if ( m_barrelPos.z ) - { - r2 = m_barrelPos.z * m_barrelPos.z; - angles.x += (180.0 / M_PI) * atan2( -m_barrelPos.z, sqrt( d2 - r2 ) ); - } - } -} - - -// Fire targets and spawn sprites -void CFuncTank::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - if ( m_fireLast != 0 ) - { - if ( m_iszSpriteSmoke ) - { - CSprite *pSprite = CSprite::SpriteCreate( STRING(m_iszSpriteSmoke), barrelEnd, TRUE ); - pSprite->AnimateAndDie( RANDOM_FLOAT( 15.0, 20.0 ) ); - pSprite->SetTransparency( kRenderTransAlpha, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, 255, kRenderFxNone ); - pSprite->pev->velocity.z = RANDOM_FLOAT(40, 80); - pSprite->SetScale( m_spriteScale ); - } - if ( m_iszSpriteFlash ) - { - CSprite *pSprite = CSprite::SpriteCreate( STRING(m_iszSpriteFlash), barrelEnd, TRUE ); - pSprite->AnimateAndDie( 60 ); - pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); - pSprite->SetScale( m_spriteScale ); - - // Hack Hack, make it stick around for at least 100 ms. - pSprite->pev->nextthink += 0.1; - } - SUB_UseTargets( this, USE_TOGGLE, 0 ); - } - m_fireLast = gpGlobals->time; -} - - -void CFuncTank::TankTrace( const Vector &vecStart, const Vector &vecForward, const Vector &vecSpread, TraceResult &tr ) -{ - // get circular gaussian spread - float x, y, z; - do { - x = RANDOM_FLOAT(-0.5,0.5) + RANDOM_FLOAT(-0.5,0.5); - y = RANDOM_FLOAT(-0.5,0.5) + RANDOM_FLOAT(-0.5,0.5); - z = x*x+y*y; - } while (z > 1); - Vector vecDir = vecForward + - x * vecSpread.x * gpGlobals->v_right + - y * vecSpread.y * gpGlobals->v_up; - Vector vecEnd; - - vecEnd = vecStart + vecDir * 4096; - UTIL_TraceLine( vecStart, vecEnd, dont_ignore_monsters, edict(), &tr ); -} - - -void CFuncTank::StartRotSound( void ) -{ - if ( !pev->noise || (pev->spawnflags & SF_TANK_SOUNDON) ) - return; - pev->spawnflags |= SF_TANK_SOUNDON; - EMIT_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noise), 0.85, ATTN_NORM); -} - - -void CFuncTank::StopRotSound( void ) -{ - if ( pev->spawnflags & SF_TANK_SOUNDON ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noise) ); - pev->spawnflags &= ~SF_TANK_SOUNDON; -} - -class CFuncTankGun : public CFuncTank -{ -public: - void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); -}; -LINK_ENTITY_TO_CLASS( func_tank, CFuncTankGun ); - -void CFuncTankGun::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - int i; - - if ( m_fireLast != 0 ) - { - // FireBullets needs gpGlobals->v_up, etc. - UTIL_MakeAimVectors(pev->angles); - - int bulletCount = (gpGlobals->time - m_fireLast) * m_fireRate; - if ( bulletCount > 0 ) - { - for ( i = 0; i < bulletCount; i++ ) - { - switch( m_bulletType ) - { - case TANK_BULLET_9MM: - FireBullets( 1, barrelEnd, forward, gTankSpread[m_spread], 4096, BULLET_MONSTER_9MM, 1, m_iBulletDamage, pevAttacker ); - break; - - case TANK_BULLET_MP5: - FireBullets( 1, barrelEnd, forward, gTankSpread[m_spread], 4096, BULLET_MONSTER_MP5, 1, m_iBulletDamage, pevAttacker ); - break; - - case TANK_BULLET_12MM: - FireBullets( 1, barrelEnd, forward, gTankSpread[m_spread], 4096, BULLET_MONSTER_12MM, 1, m_iBulletDamage, pevAttacker ); - break; - - default: - case TANK_BULLET_NONE: - break; - } - } - CFuncTank::Fire( barrelEnd, forward, pevAttacker ); - } - } - else - CFuncTank::Fire( barrelEnd, forward, pevAttacker ); -} - - - -class CFuncTankLaser : public CFuncTank -{ -public: - void Activate( void ); - void KeyValue( KeyValueData *pkvd ); - void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); - void Think( void ); - CLaser *GetLaser( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - -private: - CLaser *m_pLaser; - float m_laserTime; -}; -LINK_ENTITY_TO_CLASS( func_tanklaser, CFuncTankLaser ); - -TYPEDESCRIPTION CFuncTankLaser::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTankLaser, m_pLaser, FIELD_CLASSPTR ), - DEFINE_FIELD( CFuncTankLaser, m_laserTime, FIELD_TIME ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTankLaser, CFuncTank ); - -void CFuncTankLaser::Activate( void ) -{ - if ( !GetLaser() ) - { - UTIL_Remove(this); - ALERT( at_error, "Laser tank with no env_laser!\n" ); - } - else - { - m_pLaser->TurnOff(); - } -} - - -void CFuncTankLaser::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "laserentity")) - { - pev->message = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CFuncTank::KeyValue( pkvd ); -} - - -CLaser *CFuncTankLaser::GetLaser( void ) -{ - if ( m_pLaser ) - return m_pLaser; - - edict_t *pentLaser; - - pentLaser = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->message) ); - while ( !FNullEnt( pentLaser ) ) - { - // Found the landmark - if ( FClassnameIs( pentLaser, "env_laser" ) ) - { - m_pLaser = (CLaser *)CBaseEntity::Instance(pentLaser); - break; - } - else - pentLaser = FIND_ENTITY_BY_TARGETNAME( pentLaser, STRING(pev->message) ); - } - - return m_pLaser; -} - - -void CFuncTankLaser::Think( void ) -{ - if ( m_pLaser && (gpGlobals->time > m_laserTime) ) - m_pLaser->TurnOff(); - - CFuncTank::Think(); -} - - -void CFuncTankLaser::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - int i; - TraceResult tr; - - if ( m_fireLast != 0 && GetLaser() ) - { - // TankTrace needs gpGlobals->v_up, etc. - UTIL_MakeAimVectors(pev->angles); - - int bulletCount = (gpGlobals->time - m_fireLast) * m_fireRate; - if ( bulletCount ) - { - for ( i = 0; i < bulletCount; i++ ) - { - m_pLaser->pev->origin = barrelEnd; - TankTrace( barrelEnd, forward, gTankSpread[m_spread], tr ); - - m_laserTime = gpGlobals->time; - m_pLaser->TurnOn(); - m_pLaser->pev->dmgtime = gpGlobals->time - 1.0; - m_pLaser->FireAtPoint( tr ); - m_pLaser->pev->nextthink = 0; - } - CFuncTank::Fire( barrelEnd, forward, pev ); - } - } - else - { - CFuncTank::Fire( barrelEnd, forward, pev ); - } -} - -class CFuncTankRocket : public CFuncTank -{ -public: - void Precache( void ); - void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); -}; -LINK_ENTITY_TO_CLASS( func_tankrocket, CFuncTankRocket ); - -void CFuncTankRocket::Precache( void ) -{ - UTIL_PrecacheOther( "rpg_rocket" ); - CFuncTank::Precache(); -} - - - -void CFuncTankRocket::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - int i; - - if ( m_fireLast != 0 ) - { - int bulletCount = (gpGlobals->time - m_fireLast) * m_fireRate; - if ( bulletCount > 0 ) - { - for ( i = 0; i < bulletCount; i++ ) - { - CBaseEntity *pRocket = CBaseEntity::Create( "rpg_rocket", barrelEnd, pev->angles, edict() ); - } - CFuncTank::Fire( barrelEnd, forward, pev ); - } - } - else - CFuncTank::Fire( barrelEnd, forward, pev ); -} - - -class CFuncTankMortar : public CFuncTank -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); -}; -LINK_ENTITY_TO_CLASS( func_tankmortar, CFuncTankMortar ); - - -void CFuncTankMortar::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "iMagnitude")) - { - pev->impulse = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CFuncTank::KeyValue( pkvd ); -} - - -void CFuncTankMortar::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - if ( m_fireLast != 0 ) - { - int bulletCount = (gpGlobals->time - m_fireLast) * m_fireRate; - // Only create 1 explosion - if ( bulletCount > 0 ) - { - TraceResult tr; - - // TankTrace needs gpGlobals->v_up, etc. - UTIL_MakeAimVectors(pev->angles); - - TankTrace( barrelEnd, forward, gTankSpread[m_spread], tr ); - - ExplosionCreate( tr.vecEndPos, pev->angles, edict(), pev->impulse, TRUE ); - - CFuncTank::Fire( barrelEnd, forward, pev ); - } - } - else - CFuncTank::Fire( barrelEnd, forward, pev ); -} - - - -//============================================================================ -// FUNC TANK CONTROLS -//============================================================================ -class CFuncTankControls : public CBaseEntity -{ -public: - virtual int ObjectCaps( void ); - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void Think( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - CFuncTank *m_pTank; -}; -LINK_ENTITY_TO_CLASS( func_tankcontrols, CFuncTankControls ); - -TYPEDESCRIPTION CFuncTankControls::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTankControls, m_pTank, FIELD_CLASSPTR ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTankControls, CBaseEntity ); - -int CFuncTankControls :: ObjectCaps( void ) -{ - return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE; -} - - -void CFuncTankControls :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ // pass the Use command onto the controls - if ( m_pTank ) - m_pTank->Use( pActivator, pCaller, useType, value ); - - ASSERT( m_pTank != NULL ); // if this fails, most likely means save/restore hasn't worked properly -} - - -void CFuncTankControls :: Think( void ) -{ - edict_t *pTarget = NULL; - - do - { - pTarget = FIND_ENTITY_BY_TARGETNAME( pTarget, STRING(pev->target) ); - } while ( !FNullEnt(pTarget) && strncmp( STRING(pTarget->v.classname), "func_tank", 9 ) ); - - if ( FNullEnt( pTarget ) ) - { - ALERT( at_console, "No tank %s\n", STRING(pev->target) ); - return; - } - - m_pTank = (CFuncTank*)Instance(pTarget); -} - -void CFuncTankControls::Spawn( void ) -{ - pev->solid = SOLID_TRIGGER; - pev->movetype = MOVETYPE_NONE; - pev->effects |= EF_NODRAW; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - UTIL_SetSize( pev, pev->mins, pev->maxs ); - UTIL_SetOrigin( pev, pev->origin ); - - pev->nextthink = gpGlobals->time + 0.3; // After all the func_tank's have spawned - - CBaseEntity::Spawn(); -} diff --git a/dmc/dlls/game.cpp b/dmc/dlls/game.cpp deleted file mode 100644 index e514815..0000000 --- a/dmc/dlls/game.cpp +++ /dev/null @@ -1,892 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "extdll.h" -#include "eiface.h" -#include "util.h" -#include "game.h" - -// QUAKECLASSIC -cvar_t rj = {"rj", "0"}; - -cvar_t displaysoundlist = {"displaysoundlist","0"}; - -// multiplayer server rules -cvar_t fragsleft = {"mp_fragsleft","0", FCVAR_SERVER | FCVAR_UNLOGGED }; // Don't spam console/log files/users with this changing -cvar_t timeleft = {"mp_timeleft","0" , FCVAR_SERVER | FCVAR_UNLOGGED }; // " " - -// multiplayer server rules -cvar_t teamplay = {"mp_teamplay","0", FCVAR_SERVER }; - -cvar_t fraglimit = {"mp_fraglimit","0", FCVAR_SERVER }; -cvar_t timelimit = {"mp_timelimit","0", FCVAR_SERVER }; -cvar_t friendlyfire= {"mp_friendlyfire","0", FCVAR_SERVER }; -cvar_t falldamage = {"mp_falldamage","0", FCVAR_SERVER }; -cvar_t weaponstay = {"mp_weaponstay","1", FCVAR_SERVER }; -cvar_t forcerespawn= {"mp_forcerespawn","1", FCVAR_SERVER }; -cvar_t flashlight = {"mp_flashlight","0", FCVAR_SERVER }; -cvar_t aimcrosshair= {"mp_autocrosshair","1", FCVAR_SERVER }; -cvar_t decalfrequency = {"decalfrequency","30", FCVAR_SERVER }; -cvar_t teamlist = {"mp_teamlist","hgrunt;scientist", FCVAR_SERVER }; -cvar_t teamoverride = {"mp_teamoverride","1" }; -cvar_t defaultteam = {"mp_defaultteam","0" }; -cvar_t allowmonsters={"mp_allowmonsters","0", FCVAR_SERVER }; - -cvar_t mp_chattime = {"mp_chattime","10", FCVAR_SERVER }; - -cvar_t *g_psv_gravity = NULL; -cvar_t *g_psv_aim = NULL; -cvar_t *g_footsteps = NULL; - -//CVARS FOR SKILL LEVEL SETTINGS -// Agrunt -cvar_t sk_agrunt_health1 = {"sk_agrunt_health1","0"}; -cvar_t sk_agrunt_health2 = {"sk_agrunt_health2","0"}; -cvar_t sk_agrunt_health3 = {"sk_agrunt_health3","0"}; - -cvar_t sk_agrunt_dmg_punch1 = {"sk_agrunt_dmg_punch1","0"}; -cvar_t sk_agrunt_dmg_punch2 = {"sk_agrunt_dmg_punch2","0"}; -cvar_t sk_agrunt_dmg_punch3 = {"sk_agrunt_dmg_punch3","0"}; - -// Apache -cvar_t sk_apache_health1 = {"sk_apache_health1","0"}; -cvar_t sk_apache_health2 = {"sk_apache_health2","0"}; -cvar_t sk_apache_health3 = {"sk_apache_health3","0"}; - -// Barney -cvar_t sk_barney_health1 = {"sk_barney_health1","0"}; -cvar_t sk_barney_health2 = {"sk_barney_health2","0"}; -cvar_t sk_barney_health3 = {"sk_barney_health3","0"}; - -// Bullsquid -cvar_t sk_bullsquid_health1 = {"sk_bullsquid_health1","0"}; -cvar_t sk_bullsquid_health2 = {"sk_bullsquid_health2","0"}; -cvar_t sk_bullsquid_health3 = {"sk_bullsquid_health3","0"}; - -cvar_t sk_bullsquid_dmg_bite1 = {"sk_bullsquid_dmg_bite1","0"}; -cvar_t sk_bullsquid_dmg_bite2 = {"sk_bullsquid_dmg_bite2","0"}; -cvar_t sk_bullsquid_dmg_bite3 = {"sk_bullsquid_dmg_bite3","0"}; - -cvar_t sk_bullsquid_dmg_whip1 = {"sk_bullsquid_dmg_whip1","0"}; -cvar_t sk_bullsquid_dmg_whip2 = {"sk_bullsquid_dmg_whip2","0"}; -cvar_t sk_bullsquid_dmg_whip3 = {"sk_bullsquid_dmg_whip3","0"}; - -cvar_t sk_bullsquid_dmg_spit1 = {"sk_bullsquid_dmg_spit1","0"}; -cvar_t sk_bullsquid_dmg_spit2 = {"sk_bullsquid_dmg_spit2","0"}; -cvar_t sk_bullsquid_dmg_spit3 = {"sk_bullsquid_dmg_spit3","0"}; - - -// Big Momma -cvar_t sk_bigmomma_health_factor1 = {"sk_bigmomma_health_factor1","1.0"}; -cvar_t sk_bigmomma_health_factor2 = {"sk_bigmomma_health_factor2","1.0"}; -cvar_t sk_bigmomma_health_factor3 = {"sk_bigmomma_health_factor3","1.0"}; - -cvar_t sk_bigmomma_dmg_slash1 = {"sk_bigmomma_dmg_slash1","50"}; -cvar_t sk_bigmomma_dmg_slash2 = {"sk_bigmomma_dmg_slash2","50"}; -cvar_t sk_bigmomma_dmg_slash3 = {"sk_bigmomma_dmg_slash3","50"}; - -cvar_t sk_bigmomma_dmg_blast1 = {"sk_bigmomma_dmg_blast1","100"}; -cvar_t sk_bigmomma_dmg_blast2 = {"sk_bigmomma_dmg_blast2","100"}; -cvar_t sk_bigmomma_dmg_blast3 = {"sk_bigmomma_dmg_blast3","100"}; - -cvar_t sk_bigmomma_radius_blast1 = {"sk_bigmomma_radius_blast1","250"}; -cvar_t sk_bigmomma_radius_blast2 = {"sk_bigmomma_radius_blast2","250"}; -cvar_t sk_bigmomma_radius_blast3 = {"sk_bigmomma_radius_blast3","250"}; - -// Gargantua -cvar_t sk_gargantua_health1 = {"sk_gargantua_health1","0"}; -cvar_t sk_gargantua_health2 = {"sk_gargantua_health2","0"}; -cvar_t sk_gargantua_health3 = {"sk_gargantua_health3","0"}; - -cvar_t sk_gargantua_dmg_slash1 = {"sk_gargantua_dmg_slash1","0"}; -cvar_t sk_gargantua_dmg_slash2 = {"sk_gargantua_dmg_slash2","0"}; -cvar_t sk_gargantua_dmg_slash3 = {"sk_gargantua_dmg_slash3","0"}; - -cvar_t sk_gargantua_dmg_fire1 = {"sk_gargantua_dmg_fire1","0"}; -cvar_t sk_gargantua_dmg_fire2 = {"sk_gargantua_dmg_fire2","0"}; -cvar_t sk_gargantua_dmg_fire3 = {"sk_gargantua_dmg_fire3","0"}; - -cvar_t sk_gargantua_dmg_stomp1 = {"sk_gargantua_dmg_stomp1","0"}; -cvar_t sk_gargantua_dmg_stomp2 = {"sk_gargantua_dmg_stomp2","0"}; -cvar_t sk_gargantua_dmg_stomp3 = {"sk_gargantua_dmg_stomp3","0"}; - - -// Hassassin -cvar_t sk_hassassin_health1 = {"sk_hassassin_health1","0"}; -cvar_t sk_hassassin_health2 = {"sk_hassassin_health2","0"}; -cvar_t sk_hassassin_health3 = {"sk_hassassin_health3","0"}; - - -// Headcrab -cvar_t sk_headcrab_health1 = {"sk_headcrab_health1","0"}; -cvar_t sk_headcrab_health2 = {"sk_headcrab_health2","0"}; -cvar_t sk_headcrab_health3 = {"sk_headcrab_health3","0"}; - -cvar_t sk_headcrab_dmg_bite1 = {"sk_headcrab_dmg_bite1","0"}; -cvar_t sk_headcrab_dmg_bite2 = {"sk_headcrab_dmg_bite2","0"}; -cvar_t sk_headcrab_dmg_bite3 = {"sk_headcrab_dmg_bite3","0"}; - - -// Hgrunt -cvar_t sk_hgrunt_health1 = {"sk_hgrunt_health1","0"}; -cvar_t sk_hgrunt_health2 = {"sk_hgrunt_health2","0"}; -cvar_t sk_hgrunt_health3 = {"sk_hgrunt_health3","0"}; - -cvar_t sk_hgrunt_kick1 = {"sk_hgrunt_kick1","0"}; -cvar_t sk_hgrunt_kick2 = {"sk_hgrunt_kick2","0"}; -cvar_t sk_hgrunt_kick3 = {"sk_hgrunt_kick3","0"}; - -cvar_t sk_hgrunt_pellets1 = {"sk_hgrunt_pellets1","0"}; -cvar_t sk_hgrunt_pellets2 = {"sk_hgrunt_pellets2","0"}; -cvar_t sk_hgrunt_pellets3 = {"sk_hgrunt_pellets3","0"}; - -cvar_t sk_hgrunt_gspeed1 = {"sk_hgrunt_gspeed1","0"}; -cvar_t sk_hgrunt_gspeed2 = {"sk_hgrunt_gspeed2","0"}; -cvar_t sk_hgrunt_gspeed3 = {"sk_hgrunt_gspeed3","0"}; - -// Houndeye -cvar_t sk_houndeye_health1 = {"sk_houndeye_health1","0"}; -cvar_t sk_houndeye_health2 = {"sk_houndeye_health2","0"}; -cvar_t sk_houndeye_health3 = {"sk_houndeye_health3","0"}; - -cvar_t sk_houndeye_dmg_blast1 = {"sk_houndeye_dmg_blast1","0"}; -cvar_t sk_houndeye_dmg_blast2 = {"sk_houndeye_dmg_blast2","0"}; -cvar_t sk_houndeye_dmg_blast3 = {"sk_houndeye_dmg_blast3","0"}; - - -// ISlave -cvar_t sk_islave_health1 = {"sk_islave_health1","0"}; -cvar_t sk_islave_health2 = {"sk_islave_health2","0"}; -cvar_t sk_islave_health3 = {"sk_islave_health3","0"}; - -cvar_t sk_islave_dmg_claw1 = {"sk_islave_dmg_claw1","0"}; -cvar_t sk_islave_dmg_claw2 = {"sk_islave_dmg_claw2","0"}; -cvar_t sk_islave_dmg_claw3 = {"sk_islave_dmg_claw3","0"}; - -cvar_t sk_islave_dmg_clawrake1 = {"sk_islave_dmg_clawrake1","0"}; -cvar_t sk_islave_dmg_clawrake2 = {"sk_islave_dmg_clawrake2","0"}; -cvar_t sk_islave_dmg_clawrake3 = {"sk_islave_dmg_clawrake3","0"}; - -cvar_t sk_islave_dmg_zap1 = {"sk_islave_dmg_zap1","0"}; -cvar_t sk_islave_dmg_zap2 = {"sk_islave_dmg_zap2","0"}; -cvar_t sk_islave_dmg_zap3 = {"sk_islave_dmg_zap3","0"}; - - -// Icthyosaur -cvar_t sk_ichthyosaur_health1 = {"sk_ichthyosaur_health1","0"}; -cvar_t sk_ichthyosaur_health2 = {"sk_ichthyosaur_health2","0"}; -cvar_t sk_ichthyosaur_health3 = {"sk_ichthyosaur_health3","0"}; - -cvar_t sk_ichthyosaur_shake1 = {"sk_ichthyosaur_shake1","0"}; -cvar_t sk_ichthyosaur_shake2 = {"sk_ichthyosaur_shake2","0"}; -cvar_t sk_ichthyosaur_shake3 = {"sk_ichthyosaur_shake3","0"}; - - -// Leech -cvar_t sk_leech_health1 = {"sk_leech_health1","0"}; -cvar_t sk_leech_health2 = {"sk_leech_health2","0"}; -cvar_t sk_leech_health3 = {"sk_leech_health3","0"}; - -cvar_t sk_leech_dmg_bite1 = {"sk_leech_dmg_bite1","0"}; -cvar_t sk_leech_dmg_bite2 = {"sk_leech_dmg_bite2","0"}; -cvar_t sk_leech_dmg_bite3 = {"sk_leech_dmg_bite3","0"}; - -// Controller -cvar_t sk_controller_health1 = {"sk_controller_health1","0"}; -cvar_t sk_controller_health2 = {"sk_controller_health2","0"}; -cvar_t sk_controller_health3 = {"sk_controller_health3","0"}; - -cvar_t sk_controller_dmgzap1 = {"sk_controller_dmgzap1","0"}; -cvar_t sk_controller_dmgzap2 = {"sk_controller_dmgzap2","0"}; -cvar_t sk_controller_dmgzap3 = {"sk_controller_dmgzap3","0"}; - -cvar_t sk_controller_speedball1 = {"sk_controller_speedball1","0"}; -cvar_t sk_controller_speedball2 = {"sk_controller_speedball2","0"}; -cvar_t sk_controller_speedball3 = {"sk_controller_speedball3","0"}; - -cvar_t sk_controller_dmgball1 = {"sk_controller_dmgball1","0"}; -cvar_t sk_controller_dmgball2 = {"sk_controller_dmgball2","0"}; -cvar_t sk_controller_dmgball3 = {"sk_controller_dmgball3","0"}; - -// Nihilanth -cvar_t sk_nihilanth_health1 = {"sk_nihilanth_health1","0"}; -cvar_t sk_nihilanth_health2 = {"sk_nihilanth_health2","0"}; -cvar_t sk_nihilanth_health3 = {"sk_nihilanth_health3","0"}; - -cvar_t sk_nihilanth_zap1 = {"sk_nihilanth_zap1","0"}; -cvar_t sk_nihilanth_zap2 = {"sk_nihilanth_zap2","0"}; -cvar_t sk_nihilanth_zap3 = {"sk_nihilanth_zap3","0"}; - -// Scientist -cvar_t sk_scientist_health1 = {"sk_scientist_health1","0"}; -cvar_t sk_scientist_health2 = {"sk_scientist_health2","0"}; -cvar_t sk_scientist_health3 = {"sk_scientist_health3","0"}; - - -// Snark -cvar_t sk_snark_health1 = {"sk_snark_health1","0"}; -cvar_t sk_snark_health2 = {"sk_snark_health2","0"}; -cvar_t sk_snark_health3 = {"sk_snark_health3","0"}; - -cvar_t sk_snark_dmg_bite1 = {"sk_snark_dmg_bite1","0"}; -cvar_t sk_snark_dmg_bite2 = {"sk_snark_dmg_bite2","0"}; -cvar_t sk_snark_dmg_bite3 = {"sk_snark_dmg_bite3","0"}; - -cvar_t sk_snark_dmg_pop1 = {"sk_snark_dmg_pop1","0"}; -cvar_t sk_snark_dmg_pop2 = {"sk_snark_dmg_pop2","0"}; -cvar_t sk_snark_dmg_pop3 = {"sk_snark_dmg_pop3","0"}; - - - -// Zombie -cvar_t sk_zombie_health1 = {"sk_zombie_health1","0"}; -cvar_t sk_zombie_health2 = {"sk_zombie_health2","0"}; -cvar_t sk_zombie_health3 = {"sk_zombie_health3","0"}; - -cvar_t sk_zombie_dmg_one_slash1 = {"sk_zombie_dmg_one_slash1","0"}; -cvar_t sk_zombie_dmg_one_slash2 = {"sk_zombie_dmg_one_slash2","0"}; -cvar_t sk_zombie_dmg_one_slash3 = {"sk_zombie_dmg_one_slash3","0"}; - -cvar_t sk_zombie_dmg_both_slash1 = {"sk_zombie_dmg_both_slash1","0"}; -cvar_t sk_zombie_dmg_both_slash2 = {"sk_zombie_dmg_both_slash2","0"}; -cvar_t sk_zombie_dmg_both_slash3 = {"sk_zombie_dmg_both_slash3","0"}; - - -//Turret -cvar_t sk_turret_health1 = {"sk_turret_health1","0"}; -cvar_t sk_turret_health2 = {"sk_turret_health2","0"}; -cvar_t sk_turret_health3 = {"sk_turret_health3","0"}; - - -// MiniTurret -cvar_t sk_miniturret_health1 = {"sk_miniturret_health1","0"}; -cvar_t sk_miniturret_health2 = {"sk_miniturret_health2","0"}; -cvar_t sk_miniturret_health3 = {"sk_miniturret_health3","0"}; - - -// Sentry Turret -cvar_t sk_sentry_health1 = {"sk_sentry_health1","0"}; -cvar_t sk_sentry_health2 = {"sk_sentry_health2","0"}; -cvar_t sk_sentry_health3 = {"sk_sentry_health3","0"}; - - -// PLAYER WEAPONS - -// Crowbar whack -cvar_t sk_plr_crowbar1 = {"sk_plr_crowbar1","0"}; -cvar_t sk_plr_crowbar2 = {"sk_plr_crowbar2","0"}; -cvar_t sk_plr_crowbar3 = {"sk_plr_crowbar3","0"}; - -// Glock Round -cvar_t sk_plr_9mm_bullet1 = {"sk_plr_9mm_bullet1","0"}; -cvar_t sk_plr_9mm_bullet2 = {"sk_plr_9mm_bullet2","0"}; -cvar_t sk_plr_9mm_bullet3 = {"sk_plr_9mm_bullet3","0"}; - -// 357 Round -cvar_t sk_plr_357_bullet1 = {"sk_plr_357_bullet1","0"}; -cvar_t sk_plr_357_bullet2 = {"sk_plr_357_bullet2","0"}; -cvar_t sk_plr_357_bullet3 = {"sk_plr_357_bullet3","0"}; - -// MP5 Round -cvar_t sk_plr_9mmAR_bullet1 = {"sk_plr_9mmAR_bullet1","0"}; -cvar_t sk_plr_9mmAR_bullet2 = {"sk_plr_9mmAR_bullet2","0"}; -cvar_t sk_plr_9mmAR_bullet3 = {"sk_plr_9mmAR_bullet3","0"}; - - -// M203 grenade -cvar_t sk_plr_9mmAR_grenade1 = {"sk_plr_9mmAR_grenade1","0"}; -cvar_t sk_plr_9mmAR_grenade2 = {"sk_plr_9mmAR_grenade2","0"}; -cvar_t sk_plr_9mmAR_grenade3 = {"sk_plr_9mmAR_grenade3","0"}; - - -// Shotgun buckshot -cvar_t sk_plr_buckshot1 = {"sk_plr_buckshot1","0"}; -cvar_t sk_plr_buckshot2 = {"sk_plr_buckshot2","0"}; -cvar_t sk_plr_buckshot3 = {"sk_plr_buckshot3","0"}; - - -// Crossbow -cvar_t sk_plr_xbow_bolt_client1 = {"sk_plr_xbow_bolt_client1","0"}; -cvar_t sk_plr_xbow_bolt_client2 = {"sk_plr_xbow_bolt_client2","0"}; -cvar_t sk_plr_xbow_bolt_client3 = {"sk_plr_xbow_bolt_client3","0"}; - -cvar_t sk_plr_xbow_bolt_monster1 = {"sk_plr_xbow_bolt_monster1","0"}; -cvar_t sk_plr_xbow_bolt_monster2 = {"sk_plr_xbow_bolt_monster2","0"}; -cvar_t sk_plr_xbow_bolt_monster3 = {"sk_plr_xbow_bolt_monster3","0"}; - - -// RPG -cvar_t sk_plr_rpg1 = {"sk_plr_rpg1","0"}; -cvar_t sk_plr_rpg2 = {"sk_plr_rpg2","0"}; -cvar_t sk_plr_rpg3 = {"sk_plr_rpg3","0"}; - - -// Zero Point Generator -cvar_t sk_plr_gauss1 = {"sk_plr_gauss1","0"}; -cvar_t sk_plr_gauss2 = {"sk_plr_gauss2","0"}; -cvar_t sk_plr_gauss3 = {"sk_plr_gauss3","0"}; - - -// Tau Cannon -cvar_t sk_plr_egon_narrow1 = {"sk_plr_egon_narrow1","0"}; -cvar_t sk_plr_egon_narrow2 = {"sk_plr_egon_narrow2","0"}; -cvar_t sk_plr_egon_narrow3 = {"sk_plr_egon_narrow3","0"}; - -cvar_t sk_plr_egon_wide1 = {"sk_plr_egon_wide1","0"}; -cvar_t sk_plr_egon_wide2 = {"sk_plr_egon_wide2","0"}; -cvar_t sk_plr_egon_wide3 = {"sk_plr_egon_wide3","0"}; - - -// Hand Grendade -cvar_t sk_plr_hand_grenade1 = {"sk_plr_hand_grenade1","0"}; -cvar_t sk_plr_hand_grenade2 = {"sk_plr_hand_grenade2","0"}; -cvar_t sk_plr_hand_grenade3 = {"sk_plr_hand_grenade3","0"}; - - -// Satchel Charge -cvar_t sk_plr_satchel1 = {"sk_plr_satchel1","0"}; -cvar_t sk_plr_satchel2 = {"sk_plr_satchel2","0"}; -cvar_t sk_plr_satchel3 = {"sk_plr_satchel3","0"}; - - -// Tripmine -cvar_t sk_plr_tripmine1 = {"sk_plr_tripmine1","0"}; -cvar_t sk_plr_tripmine2 = {"sk_plr_tripmine2","0"}; -cvar_t sk_plr_tripmine3 = {"sk_plr_tripmine3","0"}; - - -// WORLD WEAPONS -cvar_t sk_12mm_bullet1 = {"sk_12mm_bullet1","0"}; -cvar_t sk_12mm_bullet2 = {"sk_12mm_bullet2","0"}; -cvar_t sk_12mm_bullet3 = {"sk_12mm_bullet3","0"}; - -cvar_t sk_9mmAR_bullet1 = {"sk_9mmAR_bullet1","0"}; -cvar_t sk_9mmAR_bullet2 = {"sk_9mmAR_bullet2","0"}; -cvar_t sk_9mmAR_bullet3 = {"sk_9mmAR_bullet3","0"}; - -cvar_t sk_9mm_bullet1 = {"sk_9mm_bullet1","0"}; -cvar_t sk_9mm_bullet2 = {"sk_9mm_bullet2","0"}; -cvar_t sk_9mm_bullet3 = {"sk_9mm_bullet3","0"}; - - -// HORNET -cvar_t sk_hornet_dmg1 = {"sk_hornet_dmg1","0"}; -cvar_t sk_hornet_dmg2 = {"sk_hornet_dmg2","0"}; -cvar_t sk_hornet_dmg3 = {"sk_hornet_dmg3","0"}; - -// HEALTH/CHARGE -cvar_t sk_suitcharger1 = { "sk_suitcharger1","0" }; -cvar_t sk_suitcharger2 = { "sk_suitcharger2","0" }; -cvar_t sk_suitcharger3 = { "sk_suitcharger3","0" }; - -cvar_t sk_battery1 = { "sk_battery1","0" }; -cvar_t sk_battery2 = { "sk_battery2","0" }; -cvar_t sk_battery3 = { "sk_battery3","0" }; - -cvar_t sk_healthcharger1 = { "sk_healthcharger1","0" }; -cvar_t sk_healthcharger2 = { "sk_healthcharger2","0" }; -cvar_t sk_healthcharger3 = { "sk_healthcharger3","0" }; - -cvar_t sk_healthkit1 = { "sk_healthkit1","0" }; -cvar_t sk_healthkit2 = { "sk_healthkit2","0" }; -cvar_t sk_healthkit3 = { "sk_healthkit3","0" }; - -cvar_t sk_scientist_heal1 = { "sk_scientist_heal1","0" }; -cvar_t sk_scientist_heal2 = { "sk_scientist_heal2","0" }; -cvar_t sk_scientist_heal3 = { "sk_scientist_heal3","0" }; - - -// monster damage adjusters -cvar_t sk_monster_head1 = { "sk_monster_head1","2" }; -cvar_t sk_monster_head2 = { "sk_monster_head2","2" }; -cvar_t sk_monster_head3 = { "sk_monster_head3","2" }; - -cvar_t sk_monster_chest1 = { "sk_monster_chest1","1" }; -cvar_t sk_monster_chest2 = { "sk_monster_chest2","1" }; -cvar_t sk_monster_chest3 = { "sk_monster_chest3","1" }; - -cvar_t sk_monster_stomach1 = { "sk_monster_stomach1","1" }; -cvar_t sk_monster_stomach2 = { "sk_monster_stomach2","1" }; -cvar_t sk_monster_stomach3 = { "sk_monster_stomach3","1" }; - -cvar_t sk_monster_arm1 = { "sk_monster_arm1","1" }; -cvar_t sk_monster_arm2 = { "sk_monster_arm2","1" }; -cvar_t sk_monster_arm3 = { "sk_monster_arm3","1" }; - -cvar_t sk_monster_leg1 = { "sk_monster_leg1","1" }; -cvar_t sk_monster_leg2 = { "sk_monster_leg2","1" }; -cvar_t sk_monster_leg3 = { "sk_monster_leg3","1" }; - -// player damage adjusters -cvar_t sk_player_head1 = { "sk_player_head1","2" }; -cvar_t sk_player_head2 = { "sk_player_head2","2" }; -cvar_t sk_player_head3 = { "sk_player_head3","2" }; - -cvar_t sk_player_chest1 = { "sk_player_chest1","1" }; -cvar_t sk_player_chest2 = { "sk_player_chest2","1" }; -cvar_t sk_player_chest3 = { "sk_player_chest3","1" }; - -cvar_t sk_player_stomach1 = { "sk_player_stomach1","1" }; -cvar_t sk_player_stomach2 = { "sk_player_stomach2","1" }; -cvar_t sk_player_stomach3 = { "sk_player_stomach3","1" }; - -cvar_t sk_player_arm1 = { "sk_player_arm1","1" }; -cvar_t sk_player_arm2 = { "sk_player_arm2","1" }; -cvar_t sk_player_arm3 = { "sk_player_arm3","1" }; - -cvar_t sk_player_leg1 = { "sk_player_leg1","1" }; -cvar_t sk_player_leg2 = { "sk_player_leg2","1" }; -cvar_t sk_player_leg3 = { "sk_player_leg3","1" }; - -// END Cvars for Skill Level settings - -// Register your console variables here -// This gets called one time when the game is initialied -void GameDLLInit( void ) -{ - // Register cvars here: - g_psv_gravity = CVAR_GET_POINTER( "sv_gravity" ); - g_psv_aim = CVAR_GET_POINTER( "sv_aim" ); - g_footsteps = CVAR_GET_POINTER( "mp_footsteps" ); - - // QUAKECLASSIC - CVAR_REGISTER (&rj); - - CVAR_REGISTER (&displaysoundlist); - - CVAR_REGISTER (&teamplay); - CVAR_REGISTER (&fraglimit); - CVAR_REGISTER (&timelimit); - - CVAR_REGISTER (&fragsleft); - CVAR_REGISTER (&timeleft); - - CVAR_REGISTER (&friendlyfire); - CVAR_REGISTER (&falldamage); - CVAR_REGISTER (&weaponstay); - CVAR_REGISTER (&forcerespawn); - CVAR_REGISTER (&flashlight); - CVAR_REGISTER (&aimcrosshair); - CVAR_REGISTER (&decalfrequency); - CVAR_REGISTER (&teamlist); - CVAR_REGISTER (&teamoverride); - CVAR_REGISTER (&defaultteam); - CVAR_REGISTER (&allowmonsters); - - CVAR_REGISTER (&mp_chattime); - -// REGISTER CVARS FOR SKILL LEVEL STUFF - // Agrunt - CVAR_REGISTER ( &sk_agrunt_health1 );// {"sk_agrunt_health1","0"}; - CVAR_REGISTER ( &sk_agrunt_health2 );// {"sk_agrunt_health2","0"}; - CVAR_REGISTER ( &sk_agrunt_health3 );// {"sk_agrunt_health3","0"}; - - CVAR_REGISTER ( &sk_agrunt_dmg_punch1 );// {"sk_agrunt_dmg_punch1","0"}; - CVAR_REGISTER ( &sk_agrunt_dmg_punch2 );// {"sk_agrunt_dmg_punch2","0"}; - CVAR_REGISTER ( &sk_agrunt_dmg_punch3 );// {"sk_agrunt_dmg_punch3","0"}; - - // Apache - CVAR_REGISTER ( &sk_apache_health1 );// {"sk_apache_health1","0"}; - CVAR_REGISTER ( &sk_apache_health2 );// {"sk_apache_health2","0"}; - CVAR_REGISTER ( &sk_apache_health3 );// {"sk_apache_health3","0"}; - - // Barney - CVAR_REGISTER ( &sk_barney_health1 );// {"sk_barney_health1","0"}; - CVAR_REGISTER ( &sk_barney_health2 );// {"sk_barney_health2","0"}; - CVAR_REGISTER ( &sk_barney_health3 );// {"sk_barney_health3","0"}; - - // Bullsquid - CVAR_REGISTER ( &sk_bullsquid_health1 );// {"sk_bullsquid_health1","0"}; - CVAR_REGISTER ( &sk_bullsquid_health2 );// {"sk_bullsquid_health2","0"}; - CVAR_REGISTER ( &sk_bullsquid_health3 );// {"sk_bullsquid_health3","0"}; - - CVAR_REGISTER ( &sk_bullsquid_dmg_bite1 );// {"sk_bullsquid_dmg_bite1","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_bite2 );// {"sk_bullsquid_dmg_bite2","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_bite3 );// {"sk_bullsquid_dmg_bite3","0"}; - - CVAR_REGISTER ( &sk_bullsquid_dmg_whip1 );// {"sk_bullsquid_dmg_whip1","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_whip2 );// {"sk_bullsquid_dmg_whip2","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_whip3 );// {"sk_bullsquid_dmg_whip3","0"}; - - CVAR_REGISTER ( &sk_bullsquid_dmg_spit1 );// {"sk_bullsquid_dmg_spit1","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_spit2 );// {"sk_bullsquid_dmg_spit2","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_spit3 );// {"sk_bullsquid_dmg_spit3","0"}; - - - CVAR_REGISTER ( &sk_bigmomma_health_factor1 );// {"sk_bigmomma_health_factor1","1.0"}; - CVAR_REGISTER ( &sk_bigmomma_health_factor2 );// {"sk_bigmomma_health_factor2","1.0"}; - CVAR_REGISTER ( &sk_bigmomma_health_factor3 );// {"sk_bigmomma_health_factor3","1.0"}; - - CVAR_REGISTER ( &sk_bigmomma_dmg_slash1 );// {"sk_bigmomma_dmg_slash1","50"}; - CVAR_REGISTER ( &sk_bigmomma_dmg_slash2 );// {"sk_bigmomma_dmg_slash2","50"}; - CVAR_REGISTER ( &sk_bigmomma_dmg_slash3 );// {"sk_bigmomma_dmg_slash3","50"}; - - CVAR_REGISTER ( &sk_bigmomma_dmg_blast1 );// {"sk_bigmomma_dmg_blast1","100"}; - CVAR_REGISTER ( &sk_bigmomma_dmg_blast2 );// {"sk_bigmomma_dmg_blast2","100"}; - CVAR_REGISTER ( &sk_bigmomma_dmg_blast3 );// {"sk_bigmomma_dmg_blast3","100"}; - - CVAR_REGISTER ( &sk_bigmomma_radius_blast1 );// {"sk_bigmomma_radius_blast1","250"}; - CVAR_REGISTER ( &sk_bigmomma_radius_blast2 );// {"sk_bigmomma_radius_blast2","250"}; - CVAR_REGISTER ( &sk_bigmomma_radius_blast3 );// {"sk_bigmomma_radius_blast3","250"}; - - // Gargantua - CVAR_REGISTER ( &sk_gargantua_health1 );// {"sk_gargantua_health1","0"}; - CVAR_REGISTER ( &sk_gargantua_health2 );// {"sk_gargantua_health2","0"}; - CVAR_REGISTER ( &sk_gargantua_health3 );// {"sk_gargantua_health3","0"}; - - CVAR_REGISTER ( &sk_gargantua_dmg_slash1 );// {"sk_gargantua_dmg_slash1","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_slash2 );// {"sk_gargantua_dmg_slash2","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_slash3 );// {"sk_gargantua_dmg_slash3","0"}; - - CVAR_REGISTER ( &sk_gargantua_dmg_fire1 );// {"sk_gargantua_dmg_fire1","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_fire2 );// {"sk_gargantua_dmg_fire2","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_fire3 );// {"sk_gargantua_dmg_fire3","0"}; - - CVAR_REGISTER ( &sk_gargantua_dmg_stomp1 );// {"sk_gargantua_dmg_stomp1","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_stomp2 );// {"sk_gargantua_dmg_stomp2","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_stomp3 );// {"sk_gargantua_dmg_stomp3","0"}; - - - // Hassassin - CVAR_REGISTER ( &sk_hassassin_health1 );// {"sk_hassassin_health1","0"}; - CVAR_REGISTER ( &sk_hassassin_health2 );// {"sk_hassassin_health2","0"}; - CVAR_REGISTER ( &sk_hassassin_health3 );// {"sk_hassassin_health3","0"}; - - - // Headcrab - CVAR_REGISTER ( &sk_headcrab_health1 );// {"sk_headcrab_health1","0"}; - CVAR_REGISTER ( &sk_headcrab_health2 );// {"sk_headcrab_health2","0"}; - CVAR_REGISTER ( &sk_headcrab_health3 );// {"sk_headcrab_health3","0"}; - - CVAR_REGISTER ( &sk_headcrab_dmg_bite1 );// {"sk_headcrab_dmg_bite1","0"}; - CVAR_REGISTER ( &sk_headcrab_dmg_bite2 );// {"sk_headcrab_dmg_bite2","0"}; - CVAR_REGISTER ( &sk_headcrab_dmg_bite3 );// {"sk_headcrab_dmg_bite3","0"}; - - - // Hgrunt - CVAR_REGISTER ( &sk_hgrunt_health1 );// {"sk_hgrunt_health1","0"}; - CVAR_REGISTER ( &sk_hgrunt_health2 );// {"sk_hgrunt_health2","0"}; - CVAR_REGISTER ( &sk_hgrunt_health3 );// {"sk_hgrunt_health3","0"}; - - CVAR_REGISTER ( &sk_hgrunt_kick1 );// {"sk_hgrunt_kick1","0"}; - CVAR_REGISTER ( &sk_hgrunt_kick2 );// {"sk_hgrunt_kick2","0"}; - CVAR_REGISTER ( &sk_hgrunt_kick3 );// {"sk_hgrunt_kick3","0"}; - - CVAR_REGISTER ( &sk_hgrunt_pellets1 ); - CVAR_REGISTER ( &sk_hgrunt_pellets2 ); - CVAR_REGISTER ( &sk_hgrunt_pellets3 ); - - CVAR_REGISTER ( &sk_hgrunt_gspeed1 ); - CVAR_REGISTER ( &sk_hgrunt_gspeed2 ); - CVAR_REGISTER ( &sk_hgrunt_gspeed3 ); - - // Houndeye - CVAR_REGISTER ( &sk_houndeye_health1 );// {"sk_houndeye_health1","0"}; - CVAR_REGISTER ( &sk_houndeye_health2 );// {"sk_houndeye_health2","0"}; - CVAR_REGISTER ( &sk_houndeye_health3 );// {"sk_houndeye_health3","0"}; - - CVAR_REGISTER ( &sk_houndeye_dmg_blast1 );// {"sk_houndeye_dmg_blast1","0"}; - CVAR_REGISTER ( &sk_houndeye_dmg_blast2 );// {"sk_houndeye_dmg_blast2","0"}; - CVAR_REGISTER ( &sk_houndeye_dmg_blast3 );// {"sk_houndeye_dmg_blast3","0"}; - - - // ISlave - CVAR_REGISTER ( &sk_islave_health1 );// {"sk_islave_health1","0"}; - CVAR_REGISTER ( &sk_islave_health2 );// {"sk_islave_health2","0"}; - CVAR_REGISTER ( &sk_islave_health3 );// {"sk_islave_health3","0"}; - - CVAR_REGISTER ( &sk_islave_dmg_claw1 );// {"sk_islave_dmg_claw1","0"}; - CVAR_REGISTER ( &sk_islave_dmg_claw2 );// {"sk_islave_dmg_claw2","0"}; - CVAR_REGISTER ( &sk_islave_dmg_claw3 );// {"sk_islave_dmg_claw3","0"}; - - CVAR_REGISTER ( &sk_islave_dmg_clawrake1 );// {"sk_islave_dmg_clawrake1","0"}; - CVAR_REGISTER ( &sk_islave_dmg_clawrake2 );// {"sk_islave_dmg_clawrake2","0"}; - CVAR_REGISTER ( &sk_islave_dmg_clawrake3 );// {"sk_islave_dmg_clawrake3","0"}; - - CVAR_REGISTER ( &sk_islave_dmg_zap1 );// {"sk_islave_dmg_zap1","0"}; - CVAR_REGISTER ( &sk_islave_dmg_zap2 );// {"sk_islave_dmg_zap2","0"}; - CVAR_REGISTER ( &sk_islave_dmg_zap3 );// {"sk_islave_dmg_zap3","0"}; - - - // Icthyosaur - CVAR_REGISTER ( &sk_ichthyosaur_health1 );// {"sk_ichthyosaur_health1","0"}; - CVAR_REGISTER ( &sk_ichthyosaur_health2 );// {"sk_ichthyosaur_health2","0"}; - CVAR_REGISTER ( &sk_ichthyosaur_health3 );// {"sk_ichthyosaur_health3","0"}; - - CVAR_REGISTER ( &sk_ichthyosaur_shake1 );// {"sk_ichthyosaur_health3","0"}; - CVAR_REGISTER ( &sk_ichthyosaur_shake2 );// {"sk_ichthyosaur_health3","0"}; - CVAR_REGISTER ( &sk_ichthyosaur_shake3 );// {"sk_ichthyosaur_health3","0"}; - - - - // Leech - CVAR_REGISTER ( &sk_leech_health1 );// {"sk_leech_health1","0"}; - CVAR_REGISTER ( &sk_leech_health2 );// {"sk_leech_health2","0"}; - CVAR_REGISTER ( &sk_leech_health3 );// {"sk_leech_health3","0"}; - - CVAR_REGISTER ( &sk_leech_dmg_bite1 );// {"sk_leech_dmg_bite1","0"}; - CVAR_REGISTER ( &sk_leech_dmg_bite2 );// {"sk_leech_dmg_bite2","0"}; - CVAR_REGISTER ( &sk_leech_dmg_bite3 );// {"sk_leech_dmg_bite3","0"}; - - - // Controller - CVAR_REGISTER ( &sk_controller_health1 ); - CVAR_REGISTER ( &sk_controller_health2 ); - CVAR_REGISTER ( &sk_controller_health3 ); - - CVAR_REGISTER ( &sk_controller_dmgzap1 ); - CVAR_REGISTER ( &sk_controller_dmgzap2 ); - CVAR_REGISTER ( &sk_controller_dmgzap3 ); - - CVAR_REGISTER ( &sk_controller_speedball1 ); - CVAR_REGISTER ( &sk_controller_speedball2 ); - CVAR_REGISTER ( &sk_controller_speedball3 ); - - CVAR_REGISTER ( &sk_controller_dmgball1 ); - CVAR_REGISTER ( &sk_controller_dmgball2 ); - CVAR_REGISTER ( &sk_controller_dmgball3 ); - - // Nihilanth - CVAR_REGISTER ( &sk_nihilanth_health1 );// {"sk_nihilanth_health1","0"}; - CVAR_REGISTER ( &sk_nihilanth_health2 );// {"sk_nihilanth_health2","0"}; - CVAR_REGISTER ( &sk_nihilanth_health3 );// {"sk_nihilanth_health3","0"}; - - CVAR_REGISTER ( &sk_nihilanth_zap1 ); - CVAR_REGISTER ( &sk_nihilanth_zap2 ); - CVAR_REGISTER ( &sk_nihilanth_zap3 ); - - // Scientist - CVAR_REGISTER ( &sk_scientist_health1 );// {"sk_scientist_health1","0"}; - CVAR_REGISTER ( &sk_scientist_health2 );// {"sk_scientist_health2","0"}; - CVAR_REGISTER ( &sk_scientist_health3 );// {"sk_scientist_health3","0"}; - - - // Snark - CVAR_REGISTER ( &sk_snark_health1 );// {"sk_snark_health1","0"}; - CVAR_REGISTER ( &sk_snark_health2 );// {"sk_snark_health2","0"}; - CVAR_REGISTER ( &sk_snark_health3 );// {"sk_snark_health3","0"}; - - CVAR_REGISTER ( &sk_snark_dmg_bite1 );// {"sk_snark_dmg_bite1","0"}; - CVAR_REGISTER ( &sk_snark_dmg_bite2 );// {"sk_snark_dmg_bite2","0"}; - CVAR_REGISTER ( &sk_snark_dmg_bite3 );// {"sk_snark_dmg_bite3","0"}; - - CVAR_REGISTER ( &sk_snark_dmg_pop1 );// {"sk_snark_dmg_pop1","0"}; - CVAR_REGISTER ( &sk_snark_dmg_pop2 );// {"sk_snark_dmg_pop2","0"}; - CVAR_REGISTER ( &sk_snark_dmg_pop3 );// {"sk_snark_dmg_pop3","0"}; - - - - // Zombie - CVAR_REGISTER ( &sk_zombie_health1 );// {"sk_zombie_health1","0"}; - CVAR_REGISTER ( &sk_zombie_health2 );// {"sk_zombie_health3","0"}; - CVAR_REGISTER ( &sk_zombie_health3 );// {"sk_zombie_health3","0"}; - - CVAR_REGISTER ( &sk_zombie_dmg_one_slash1 );// {"sk_zombie_dmg_one_slash1","0"}; - CVAR_REGISTER ( &sk_zombie_dmg_one_slash2 );// {"sk_zombie_dmg_one_slash2","0"}; - CVAR_REGISTER ( &sk_zombie_dmg_one_slash3 );// {"sk_zombie_dmg_one_slash3","0"}; - - CVAR_REGISTER ( &sk_zombie_dmg_both_slash1 );// {"sk_zombie_dmg_both_slash1","0"}; - CVAR_REGISTER ( &sk_zombie_dmg_both_slash2 );// {"sk_zombie_dmg_both_slash2","0"}; - CVAR_REGISTER ( &sk_zombie_dmg_both_slash3 );// {"sk_zombie_dmg_both_slash3","0"}; - - - //Turret - CVAR_REGISTER ( &sk_turret_health1 );// {"sk_turret_health1","0"}; - CVAR_REGISTER ( &sk_turret_health2 );// {"sk_turret_health2","0"}; - CVAR_REGISTER ( &sk_turret_health3 );// {"sk_turret_health3","0"}; - - - // MiniTurret - CVAR_REGISTER ( &sk_miniturret_health1 );// {"sk_miniturret_health1","0"}; - CVAR_REGISTER ( &sk_miniturret_health2 );// {"sk_miniturret_health2","0"}; - CVAR_REGISTER ( &sk_miniturret_health3 );// {"sk_miniturret_health3","0"}; - - - // Sentry Turret - CVAR_REGISTER ( &sk_sentry_health1 );// {"sk_sentry_health1","0"}; - CVAR_REGISTER ( &sk_sentry_health2 );// {"sk_sentry_health2","0"}; - CVAR_REGISTER ( &sk_sentry_health3 );// {"sk_sentry_health3","0"}; - - - // PLAYER WEAPONS - - // Crowbar whack - CVAR_REGISTER ( &sk_plr_crowbar1 );// {"sk_plr_crowbar1","0"}; - CVAR_REGISTER ( &sk_plr_crowbar2 );// {"sk_plr_crowbar2","0"}; - CVAR_REGISTER ( &sk_plr_crowbar3 );// {"sk_plr_crowbar3","0"}; - - // Glock Round - CVAR_REGISTER ( &sk_plr_9mm_bullet1 );// {"sk_plr_9mm_bullet1","0"}; - CVAR_REGISTER ( &sk_plr_9mm_bullet2 );// {"sk_plr_9mm_bullet2","0"}; - CVAR_REGISTER ( &sk_plr_9mm_bullet3 );// {"sk_plr_9mm_bullet3","0"}; - - // 357 Round - CVAR_REGISTER ( &sk_plr_357_bullet1 );// {"sk_plr_357_bullet1","0"}; - CVAR_REGISTER ( &sk_plr_357_bullet2 );// {"sk_plr_357_bullet2","0"}; - CVAR_REGISTER ( &sk_plr_357_bullet3 );// {"sk_plr_357_bullet3","0"}; - - // MP5 Round - CVAR_REGISTER ( &sk_plr_9mmAR_bullet1 );// {"sk_plr_9mmAR_bullet1","0"}; - CVAR_REGISTER ( &sk_plr_9mmAR_bullet2 );// {"sk_plr_9mmAR_bullet2","0"}; - CVAR_REGISTER ( &sk_plr_9mmAR_bullet3 );// {"sk_plr_9mmAR_bullet3","0"}; - - - // M203 grenade - CVAR_REGISTER ( &sk_plr_9mmAR_grenade1 );// {"sk_plr_9mmAR_grenade1","0"}; - CVAR_REGISTER ( &sk_plr_9mmAR_grenade2 );// {"sk_plr_9mmAR_grenade2","0"}; - CVAR_REGISTER ( &sk_plr_9mmAR_grenade3 );// {"sk_plr_9mmAR_grenade3","0"}; - - - // Shotgun buckshot - CVAR_REGISTER ( &sk_plr_buckshot1 );// {"sk_plr_buckshot1","0"}; - CVAR_REGISTER ( &sk_plr_buckshot2 );// {"sk_plr_buckshot2","0"}; - CVAR_REGISTER ( &sk_plr_buckshot3 );// {"sk_plr_buckshot3","0"}; - - - // Crossbow - CVAR_REGISTER ( &sk_plr_xbow_bolt_monster1 );// {"sk_plr_xbow_bolt1","0"}; - CVAR_REGISTER ( &sk_plr_xbow_bolt_monster2 );// {"sk_plr_xbow_bolt2","0"}; - CVAR_REGISTER ( &sk_plr_xbow_bolt_monster3 );// {"sk_plr_xbow_bolt3","0"}; - - CVAR_REGISTER ( &sk_plr_xbow_bolt_client1 );// {"sk_plr_xbow_bolt1","0"}; - CVAR_REGISTER ( &sk_plr_xbow_bolt_client2 );// {"sk_plr_xbow_bolt2","0"}; - CVAR_REGISTER ( &sk_plr_xbow_bolt_client3 );// {"sk_plr_xbow_bolt3","0"}; - - - // RPG - CVAR_REGISTER ( &sk_plr_rpg1 );// {"sk_plr_rpg1","0"}; - CVAR_REGISTER ( &sk_plr_rpg2 );// {"sk_plr_rpg2","0"}; - CVAR_REGISTER ( &sk_plr_rpg3 );// {"sk_plr_rpg3","0"}; - - - // Gauss Gun - CVAR_REGISTER ( &sk_plr_gauss1 );// {"sk_plr_gauss1","0"}; - CVAR_REGISTER ( &sk_plr_gauss2 );// {"sk_plr_gauss2","0"}; - CVAR_REGISTER ( &sk_plr_gauss3 );// {"sk_plr_gauss3","0"}; - - - // Egon Gun - CVAR_REGISTER ( &sk_plr_egon_narrow1 );// {"sk_plr_egon_narrow1","0"}; - CVAR_REGISTER ( &sk_plr_egon_narrow2 );// {"sk_plr_egon_narrow2","0"}; - CVAR_REGISTER ( &sk_plr_egon_narrow3 );// {"sk_plr_egon_narrow3","0"}; - - CVAR_REGISTER ( &sk_plr_egon_wide1 );// {"sk_plr_egon_wide1","0"}; - CVAR_REGISTER ( &sk_plr_egon_wide2 );// {"sk_plr_egon_wide2","0"}; - CVAR_REGISTER ( &sk_plr_egon_wide3 );// {"sk_plr_egon_wide3","0"}; - - - // Hand Grendade - CVAR_REGISTER ( &sk_plr_hand_grenade1 );// {"sk_plr_hand_grenade1","0"}; - CVAR_REGISTER ( &sk_plr_hand_grenade2 );// {"sk_plr_hand_grenade2","0"}; - CVAR_REGISTER ( &sk_plr_hand_grenade3 );// {"sk_plr_hand_grenade3","0"}; - - - // Satchel Charge - CVAR_REGISTER ( &sk_plr_satchel1 );// {"sk_plr_satchel1","0"}; - CVAR_REGISTER ( &sk_plr_satchel2 );// {"sk_plr_satchel2","0"}; - CVAR_REGISTER ( &sk_plr_satchel3 );// {"sk_plr_satchel3","0"}; - - - // Tripmine - CVAR_REGISTER ( &sk_plr_tripmine1 );// {"sk_plr_tripmine1","0"}; - CVAR_REGISTER ( &sk_plr_tripmine2 );// {"sk_plr_tripmine2","0"}; - CVAR_REGISTER ( &sk_plr_tripmine3 );// {"sk_plr_tripmine3","0"}; - - - // WORLD WEAPONS - CVAR_REGISTER ( &sk_12mm_bullet1 );// {"sk_12mm_bullet1","0"}; - CVAR_REGISTER ( &sk_12mm_bullet2 );// {"sk_12mm_bullet2","0"}; - CVAR_REGISTER ( &sk_12mm_bullet3 );// {"sk_12mm_bullet3","0"}; - - CVAR_REGISTER ( &sk_9mmAR_bullet1 );// {"sk_9mm_bullet1","0"}; - CVAR_REGISTER ( &sk_9mmAR_bullet2 );// {"sk_9mm_bullet1","0"}; - CVAR_REGISTER ( &sk_9mmAR_bullet3 );// {"sk_9mm_bullet1","0"}; - - CVAR_REGISTER ( &sk_9mm_bullet1 );// {"sk_9mm_bullet1","0"}; - CVAR_REGISTER ( &sk_9mm_bullet2 );// {"sk_9mm_bullet2","0"}; - CVAR_REGISTER ( &sk_9mm_bullet3 );// {"sk_9mm_bullet3","0"}; - - - // HORNET - CVAR_REGISTER ( &sk_hornet_dmg1 );// {"sk_hornet_dmg1","0"}; - CVAR_REGISTER ( &sk_hornet_dmg2 );// {"sk_hornet_dmg2","0"}; - CVAR_REGISTER ( &sk_hornet_dmg3 );// {"sk_hornet_dmg3","0"}; - - // HEALTH/SUIT CHARGE DISTRIBUTION - CVAR_REGISTER ( &sk_suitcharger1 ); - CVAR_REGISTER ( &sk_suitcharger2 ); - CVAR_REGISTER ( &sk_suitcharger3 ); - - CVAR_REGISTER ( &sk_battery1 ); - CVAR_REGISTER ( &sk_battery2 ); - CVAR_REGISTER ( &sk_battery3 ); - - CVAR_REGISTER ( &sk_healthcharger1 ); - CVAR_REGISTER ( &sk_healthcharger2 ); - CVAR_REGISTER ( &sk_healthcharger3 ); - - CVAR_REGISTER ( &sk_healthkit1 ); - CVAR_REGISTER ( &sk_healthkit2 ); - CVAR_REGISTER ( &sk_healthkit3 ); - - CVAR_REGISTER ( &sk_scientist_heal1 ); - CVAR_REGISTER ( &sk_scientist_heal2 ); - CVAR_REGISTER ( &sk_scientist_heal3 ); - -// monster damage adjusters - CVAR_REGISTER ( &sk_monster_head1 ); - CVAR_REGISTER ( &sk_monster_head2 ); - CVAR_REGISTER ( &sk_monster_head3 ); - - CVAR_REGISTER ( &sk_monster_chest1 ); - CVAR_REGISTER ( &sk_monster_chest2 ); - CVAR_REGISTER ( &sk_monster_chest3 ); - - CVAR_REGISTER ( &sk_monster_stomach1 ); - CVAR_REGISTER ( &sk_monster_stomach2 ); - CVAR_REGISTER ( &sk_monster_stomach3 ); - - CVAR_REGISTER ( &sk_monster_arm1 ); - CVAR_REGISTER ( &sk_monster_arm2 ); - CVAR_REGISTER ( &sk_monster_arm3 ); - - CVAR_REGISTER ( &sk_monster_leg1 ); - CVAR_REGISTER ( &sk_monster_leg2 ); - CVAR_REGISTER ( &sk_monster_leg3 ); - -// player damage adjusters - CVAR_REGISTER ( &sk_player_head1 ); - CVAR_REGISTER ( &sk_player_head2 ); - CVAR_REGISTER ( &sk_player_head3 ); - - CVAR_REGISTER ( &sk_player_chest1 ); - CVAR_REGISTER ( &sk_player_chest2 ); - CVAR_REGISTER ( &sk_player_chest3 ); - - CVAR_REGISTER ( &sk_player_stomach1 ); - CVAR_REGISTER ( &sk_player_stomach2 ); - CVAR_REGISTER ( &sk_player_stomach3 ); - - CVAR_REGISTER ( &sk_player_arm1 ); - CVAR_REGISTER ( &sk_player_arm2 ); - CVAR_REGISTER ( &sk_player_arm3 ); - - CVAR_REGISTER ( &sk_player_leg1 ); - CVAR_REGISTER ( &sk_player_leg2 ); - CVAR_REGISTER ( &sk_player_leg3 ); -// END REGISTER CVARS FOR SKILL LEVEL STUFF - - SERVER_COMMAND( "exec skill.cfg\n" ); -} - diff --git a/dmc/dlls/game.h b/dmc/dlls/game.h deleted file mode 100644 index e61c3f3..0000000 --- a/dmc/dlls/game.h +++ /dev/null @@ -1,46 +0,0 @@ -/*** -* -* 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. -* -****/ - -#ifndef GAME_H -#define GAME_H - -extern void GameDLLInit( void ); - - -extern cvar_t displaysoundlist; -extern cvar_t mapcyclefile; -extern cvar_t servercfgfile; -extern cvar_t lservercfgfile; - -// multiplayer server rules -extern cvar_t fraglimit; -extern cvar_t timelimit; -extern cvar_t friendlyfir; -extern cvar_t falldamage; -extern cvar_t weaponstay; -extern cvar_t forcerespaw; -extern cvar_t flashlight; -extern cvar_t aimcrosshair; -extern cvar_t decalfrequency; -extern cvar_t teamlist; -extern cvar_t teamoverride; -extern cvar_t defaultteam; - -// Engine Cvars -extern cvar_t *g_psv_gravity; -extern cvar_t *g_psv_aim; -extern cvar_t *g_footsteps; - -#endif // GAME_H diff --git a/dmc/dlls/gamerules.cpp b/dmc/dlls/gamerules.cpp deleted file mode 100644 index c5da3fc..0000000 --- a/dmc/dlls/gamerules.cpp +++ /dev/null @@ -1,179 +0,0 @@ -/*** -* -* 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. -* -****/ -//========================================================= -// GameRules.cpp -//========================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "teamplay_gamerules.h" - -extern Vector g_vecTeleMins[ MAX_TELES ]; -extern Vector g_vecTeleMaxs[ MAX_TELES ]; -extern int g_iTeleNum; - -#include "skill.h" - -extern edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ); - -DLL_GLOBAL CGameRules* g_pGameRules = NULL; -extern DLL_GLOBAL BOOL g_fGameOver; -extern int gmsgDeathMsg; // client dll messages -extern int gmsgScoreInfo; -extern int gmsgMOTD; - -//========================================================= -//========================================================= -BOOL CGameRules::CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int iMaxCarry ) -{ - int iAmmoIndex; - - if ( pszAmmoName ) - { - iAmmoIndex = pPlayer->GetAmmoIndex( pszAmmoName ); - - if ( iAmmoIndex > -1 ) - { - if ( pPlayer->AmmoInventory( iAmmoIndex ) < iMaxCarry ) - { - // player has room for more of this type of ammo - return TRUE; - } - } - } - - return FALSE; -} - -//========================================================= -//========================================================= -edict_t *CGameRules :: GetPlayerSpawnSpot( CBasePlayer *pPlayer ) -{ - edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer ); - - pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1); - pPlayer->pev->v_angle = g_vecZero; - pPlayer->pev->velocity = g_vecZero; - pPlayer->pev->angles = VARS(pentSpawnSpot)->angles; - pPlayer->pev->punchangle = g_vecZero; - pPlayer->pev->fixangle = TRUE; - - return pentSpawnSpot; -} - -//========================================================= -//========================================================= -BOOL CGameRules::CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ - if ( pWeapon->pszAmmo1() ) - { - if ( !CanHaveAmmo( pPlayer, pWeapon->pszAmmo1(), pWeapon->iMaxAmmo1() ) ) - { - // we can't carry anymore ammo for this gun. We can only - // have the gun if we aren't already carrying one of this type - if ( pPlayer->HasPlayerItem( pWeapon ) ) - { - return FALSE; - } - } - } - else - { - // weapon doesn't use ammo, don't take another if you already have it. - if ( pPlayer->HasPlayerItem( pWeapon ) ) - { - return FALSE; - } - } - - // note: will fall through to here if GetItemInfo doesn't fill the struct! - return TRUE; -} - -//========================================================= -// load the SkillData struct with the proper values based on the skill level. -//========================================================= -void CGameRules::RefreshSkillData ( void ) -{ - int iSkill; - - iSkill = (int)CVAR_GET_FLOAT("skill"); - - if ( iSkill < 1 ) - { - iSkill = 1; - } - else if ( iSkill > 3 ) - { - iSkill = 3; - } - - gSkillData.iSkillLevel = iSkill; -} - -//========================================================= -// instantiate the proper game rules object -//========================================================= - -CGameRules *InstallGameRules( void ) -{ - SERVER_COMMAND( "exec game.cfg\n" ); - SERVER_EXECUTE( ); - - //Clear all the teleporters - for ( int i = 0; i < MAX_TELES; i++ ) - { - g_vecTeleMins[ i ].x = 0.0; - g_vecTeleMins[ i ].y = 0.0; - g_vecTeleMins[ i ].z = 0.0; - - g_vecTeleMaxs[ i ].x = 0.0; - g_vecTeleMaxs[ i ].y = 0.0; - g_vecTeleMaxs[ i ].z = 0.0; - } - - g_iTeleNum = 0; - - if ( !gpGlobals->deathmatch ) - { - // generic half-life - return new CHalfLifeRules; - } - else - { - if ( CVAR_GET_FLOAT( "mp_teamplay" ) > 0 ) - { - // teamplay - return new CHalfLifeTeamplay; - } - if ((int)gpGlobals->deathmatch == 1) - { - // vanilla deathmatch - return new CHalfLifeMultiplay; - } - else - { - // vanilla deathmatch?? - return new CHalfLifeMultiplay; - } - } -} - - - diff --git a/dmc/dlls/gamerules.h b/dmc/dlls/gamerules.h deleted file mode 100644 index 7886df4..0000000 --- a/dmc/dlls/gamerules.h +++ /dev/null @@ -1,370 +0,0 @@ -/*** -* -* 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. -* -****/ -//========================================================= -// GameRules -//========================================================= - -//#include "weapons.h" -//#include "items.h" -class CBasePlayerItem; -class CBasePlayer; -class CItem; -class CBasePlayerAmmo; - -// weapon respawning return codes -enum -{ - GR_NONE = 0, - - GR_WEAPON_RESPAWN_YES, - GR_WEAPON_RESPAWN_NO, - - GR_AMMO_RESPAWN_YES, - GR_AMMO_RESPAWN_NO, - - GR_ITEM_RESPAWN_YES, - GR_ITEM_RESPAWN_NO, - - GR_PLR_DROP_GUN_ALL, - GR_PLR_DROP_GUN_ACTIVE, - GR_PLR_DROP_GUN_NO, - - GR_PLR_DROP_AMMO_ALL, - GR_PLR_DROP_AMMO_ACTIVE, - GR_PLR_DROP_AMMO_NO, -}; - -// Player relationship return codes -enum -{ - GR_NOTTEAMMATE = 0, - GR_TEAMMATE, - GR_ENEMY, - GR_ALLY, - GR_NEUTRAL, -}; - -class CGameRules -{ -public: - virtual void RefreshSkillData( void );// fill skill data struct with proper values - virtual void Think( void ) = 0;// GR_Think - runs every server frame, should handle any timer tasks, periodic events, etc. - virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ) = 0; // Can this item spawn (eg monsters don't spawn in deathmatch). - - virtual BOOL FAllowFlashlight( void ) = 0;// Are players allowed to switch on their flashlight? - virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) = 0;// should the player switch to this weapon? - virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) = 0;// I can't use this weapon anymore, get me the next best one. - -// Functions to verify the single/multiplayer status of a game - virtual BOOL IsMultiplayer( void ) = 0;// is this a multiplayer game? (either coop or deathmatch) - virtual BOOL IsDeathmatch( void ) = 0;//is this a deathmatch game? - virtual BOOL IsTeamplay( void ) { return FALSE; };// is this deathmatch game being played with team rules? - virtual BOOL IsCoOp( void ) = 0;// is this a coop game? - virtual const char *GetGameDescription( void ) { return "DMC"; } // this is the game name that gets seen in the server browser - -// Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) = 0;// a client just connected to the server (player hasn't spawned yet) - virtual void InitHUD( CBasePlayer *pl ) = 0; // the client dll is ready for updating - virtual void ClientDisconnected( edict_t *pClient ) = 0;// a client just disconnected from the server - virtual void UpdateGameMode( CBasePlayer *pPlayer ) {} // the client needs to be informed of the current game mode - -// Client damage rules - virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ) = 0;// this client just hit the ground after a fall. How much damage? - virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) {return TRUE;};// can this player take damage from this attacker? - virtual BOOL ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) { return TRUE; } - -// Client spawn/respawn control - virtual void PlayerSpawn( CBasePlayer *pPlayer ) = 0;// called by CBasePlayer::Spawn just before releasing player into the game - virtual void PlayerThink( CBasePlayer *pPlayer ) = 0; // called by CBasePlayer::PreThink every frame, before physics are run and after keys are accepted - virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ) = 0;// is this player allowed to respawn now? - virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ) = 0;// When in the future will this player be able to spawn? - virtual edict_t *GetPlayerSpawnSpot( CBasePlayer *pPlayer );// Place this player on their spawnspot and face them the proper direction. - - virtual BOOL AllowAutoTargetCrosshair( void ) { return TRUE; }; - virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) { return FALSE; }; // handles the user commands; returns TRUE if command handled properly - virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) {} // the player has changed userinfo; can change it now - -// Client kills/scoring - virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) = 0;// how many points do I award whoever kills this player? - virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) = 0;// Called each time a player dies - virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor )= 0;// Call this from within a GameRules class to report an obituary. -// Weapon retrieval - virtual BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon );// The player is touching an CBasePlayerItem, do I give it to him? - virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) = 0;// Called each time a player picks up a weapon from the ground - -// Weapon spawn/respawn control - virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon ) = 0;// should this weapon respawn? - virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon ) = 0;// when may this weapon respawn? - virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon ) = 0; // can i respawn now, and if not, when should i try again? - virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ) = 0;// where in the world should this weapon respawn? - -// Item retrieval - virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ) = 0;// is this player allowed to take this item? - virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ) = 0;// call each time a player picks up an item (battery, healthkit, longjump) - -// Item spawn/respawn control - virtual int ItemShouldRespawn( CItem *pItem ) = 0;// Should this item respawn? - virtual float FlItemRespawnTime( CItem *pItem ) = 0;// when may this item respawn? - virtual Vector VecItemRespawnSpot( CItem *pItem ) = 0;// where in the world should this item respawn? - -// Ammo retrieval - virtual BOOL CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int iMaxCarry );// can this player take more of this ammo? - virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ) = 0;// called each time a player picks up some ammo in the world - -// Ammo spawn/respawn control - virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ) = 0;// should this ammo item respawn? - virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ) = 0;// when should this ammo item respawn? - virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ) = 0;// where in the world should this ammo item respawn? - // by default, everything spawns - -// Healthcharger respawn control - virtual float FlHealthChargerRechargeTime( void ) = 0;// how long until a depleted HealthCharger recharges itself? - virtual float FlHEVChargerRechargeTime( void ) { return 0; }// how long until a depleted HealthCharger recharges itself? - -// What happens to a dead player's weapons - virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ) = 0;// what do I do with a player's weapons when he's killed? - -// What happens to a dead player's ammo - virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ) = 0;// Do I drop ammo when the player dies? How much? - -// Teamplay stuff - virtual const char *GetTeamID( CBaseEntity *pEntity ) = 0;// what team is this entity on? - virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) = 0;// What is the player's relationship with this entity? - virtual int GetTeamIndex( const char *pTeamName ) { return -1; } - virtual const char *GetIndexedTeamName( int teamIndex ) { return ""; } - virtual BOOL IsValidTeam( const char *pTeamName ) { return TRUE; } - virtual void ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ) {} - virtual const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer ) { return ""; } - -// Sounds - virtual BOOL PlayTextureSounds( void ) { return TRUE; } - virtual BOOL PlayFootstepSounds( CBasePlayer *pl, float fvol ) { return TRUE; } - -// Monsters - virtual BOOL FAllowMonsters( void ) = 0;//are monsters allowed - - // Immediately end a multiplayer game - virtual void EndMultiplayerGame( void ) {} -}; - -extern CGameRules *InstallGameRules( void ); - - -//========================================================= -// CHalfLifeRules - rules for the single player Half-Life -// game. -//========================================================= -class CHalfLifeRules : public CGameRules -{ -public: - CHalfLifeRules ( void ); - -// GR_Think - virtual void Think( void ); - virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ); - virtual BOOL FAllowFlashlight( void ) { return TRUE; }; - - virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); - virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ); - -// Functions to verify the single/multiplayer status of a game - virtual BOOL IsMultiplayer( void ); - virtual BOOL IsDeathmatch( void ); - virtual BOOL IsCoOp( void ); - -// Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); - virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating - virtual void ClientDisconnected( edict_t *pClient ); - -// Client damage rules - virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ); - -// Client spawn/respawn control - virtual void PlayerSpawn( CBasePlayer *pPlayer ); - virtual void PlayerThink( CBasePlayer *pPlayer ); - virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ); - virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ); - - virtual BOOL AllowAutoTargetCrosshair( void ); - -// Client kills/scoring - virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); - virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - -// Weapon retrieval - virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); - -// Weapon spawn/respawn control - virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon ); - virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon ); - virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon ); - virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ); - -// Item retrieval - virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ); - virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ); - -// Item spawn/respawn control - virtual int ItemShouldRespawn( CItem *pItem ); - virtual float FlItemRespawnTime( CItem *pItem ); - virtual Vector VecItemRespawnSpot( CItem *pItem ); - -// Ammo retrieval - virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ); - -// Ammo spawn/respawn control - virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ); - virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ); - virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ); - -// Healthcharger respawn control - virtual float FlHealthChargerRechargeTime( void ); - -// What happens to a dead player's weapons - virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ); - -// What happens to a dead player's ammo - virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ); - -// Monsters - virtual BOOL FAllowMonsters( void ); - -// Teamplay stuff - virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";}; - virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); -}; - - -#include "voice_gamemgr.h" - -//========================================================= -// CHalfLifeMultiplay - rules for the basic half life multiplayer -// competition -//========================================================= -class CHalfLifeMultiplay : public CGameRules -{ -public: - CHalfLifeMultiplay(); - - virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ); - -// GR_Think - virtual void Think( void ); - virtual void RefreshSkillData( void ); - virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ); - virtual BOOL FAllowFlashlight( void ); - - virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); - virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ); - -// Functions to verify the single/multiplayer status of a game - virtual BOOL IsMultiplayer( void ); - virtual BOOL IsDeathmatch( void ); - virtual BOOL IsCoOp( void ); - -// Client connection/disconnection - // If ClientConnected returns FALSE, the connection is rejected and the user is provided the reason specified in - // svRejectReason - // Only the client's name and remote address are provided to the dll for verification. - virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); - virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating - virtual void ClientDisconnected( edict_t *pClient ); - virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode - -// Client damage rules - virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ); - virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ); - -// Client spawn/respawn control - virtual void PlayerSpawn( CBasePlayer *pPlayer ); - virtual void PlayerThink( CBasePlayer *pPlayer ); - virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ); - virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ); - virtual edict_t *GetPlayerSpawnSpot( CBasePlayer *pPlayer ); - - virtual BOOL AllowAutoTargetCrosshair( void ); - -// Client kills/scoring - virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); - virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - -// Weapon retrieval - virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); - virtual BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon );// The player is touching an CBasePlayerItem, do I give it to him? - -// Weapon spawn/respawn control - virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon ); - virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon ); - virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon ); - virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ); - -// Item retrieval - virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ); - virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ); - -// Item spawn/respawn control - virtual int ItemShouldRespawn( CItem *pItem ); - virtual float FlItemRespawnTime( CItem *pItem ); - virtual Vector VecItemRespawnSpot( CItem *pItem ); - -// Ammo retrieval - virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ); - -// Ammo spawn/respawn control - virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ); - virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ); - virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ); - -// Healthcharger respawn control - virtual float FlHealthChargerRechargeTime( void ); - virtual float FlHEVChargerRechargeTime( void ); - -// What happens to a dead player's weapons - virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ); - -// What happens to a dead player's ammo - virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ); - -// Teamplay stuff - virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";} - virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); - - virtual BOOL PlayTextureSounds( void ) { return FALSE; } - virtual BOOL PlayFootstepSounds( CBasePlayer *pl, float fvol ); - -// Monsters - virtual BOOL FAllowMonsters( void ); - - // Immediately end a multiplayer game - virtual void EndMultiplayerGame( void ) { GoToIntermission(); } - - CVoiceGameMgr m_VoiceGameMgr; - -protected: - virtual void ChangeLevel( void ); - virtual void GoToIntermission( void ); - float m_flIntermissionEndTime; - float m_flIntermissionStartTime; - BOOL m_iEndIntermissionButtonHit; - void SendMOTDToClient( edict_t *client ); - - float m_flGameEndTime; - virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ); -}; - -extern DLL_GLOBAL CGameRules* g_pGameRules; diff --git a/dmc/dlls/globals.cpp b/dmc/dlls/globals.cpp deleted file mode 100644 index ef657c2..0000000 --- a/dmc/dlls/globals.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== globals.cpp ======================================================== - - DLL-wide global variable definitions. - They're all defined here, for convenient centralization. - Source files that need them should "extern ..." declare each - variable, to better document what globals they care about. - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "soundent.h" - -DLL_GLOBAL ULONG g_ulFrameCount; -DLL_GLOBAL ULONG g_ulModelIndexEyes; -DLL_GLOBAL ULONG g_ulModelIndexPlayer; -DLL_GLOBAL Vector g_vecAttackDir; -DLL_GLOBAL int g_iSkillLevel; -DLL_GLOBAL int gDisplayTitle; -DLL_GLOBAL BOOL g_fGameOver; -DLL_GLOBAL const Vector g_vecZero = Vector(0,0,0); -DLL_GLOBAL int g_Language; diff --git a/dmc/dlls/h_ai.cpp b/dmc/dlls/h_ai.cpp deleted file mode 100644 index 7eabdf8..0000000 --- a/dmc/dlls/h_ai.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - - h_ai.cpp - halflife specific ai code - -*/ - - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" - -#define NUM_LATERAL_CHECKS 13 // how many checks are made on each side of a monster looking for lateral cover -#define NUM_LATERAL_LOS_CHECKS 6 // how many checks are made on each side of a monster looking for lateral cover - -//float flRandom = RANDOM_FLOAT(0,1); - -DLL_GLOBAL BOOL g_fDrawLines = FALSE; - -//========================================================= -// -// AI UTILITY FUNCTIONS -// -// !!!UNDONE - move CBaseMonster functions to monsters.cpp -//========================================================= - -//========================================================= -// FBoxVisible - a more accurate ( and slower ) version -// of FVisible. -// -// !!!UNDONE - make this CBaseMonster? -//========================================================= -BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize ) -{ - // don't look through water - if ((pevLooker->waterlevel != 3 && pevTarget->waterlevel == 3) - || (pevLooker->waterlevel == 3 && pevTarget->waterlevel == 0)) - return FALSE; - - TraceResult tr; - Vector vecLookerOrigin = pevLooker->origin + pevLooker->view_ofs;//look through the monster's 'eyes' - for (int i = 0; i < 5; i++) - { - Vector vecTarget = pevTarget->origin; - vecTarget.x += RANDOM_FLOAT( pevTarget->mins.x + flSize, pevTarget->maxs.x - flSize); - vecTarget.y += RANDOM_FLOAT( pevTarget->mins.y + flSize, pevTarget->maxs.y - flSize); - vecTarget.z += RANDOM_FLOAT( pevTarget->mins.z + flSize, pevTarget->maxs.z - flSize); - - UTIL_TraceLine(vecLookerOrigin, vecTarget, ignore_monsters, ignore_glass, ENT(pevLooker)/*pentIgnore*/, &tr); - - if (tr.flFraction == 1.0) - { - vecTargetOrigin = vecTarget; - return TRUE;// line of sight is valid. - } - } - return FALSE;// Line of sight is not established -} - -// -// VecCheckToss - returns the velocity at which an object should be lobbed from vecspot1 to land near vecspot2. -// returns g_vecZero if toss is not feasible. -// -Vector VecCheckToss ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj ) -{ - TraceResult tr; - Vector vecMidPoint;// halfway point between Spot1 and Spot2 - Vector vecApex;// highest point - Vector vecScale; - Vector vecGrenadeVel; - Vector vecTemp; - float flGravity = CVAR_GET_FLOAT( "sv_gravity" ) * flGravityAdj; - - if (vecSpot2.z - vecSpot1.z > 500) - { - // to high, fail - return g_vecZero; - } - - UTIL_MakeVectors (pev->angles); - - // toss a little bit to the left or right, not right down on the enemy's bean (head). - vecSpot2 = vecSpot2 + gpGlobals->v_right * ( RANDOM_FLOAT(-8,8) + RANDOM_FLOAT(-16,16) ); - vecSpot2 = vecSpot2 + gpGlobals->v_forward * ( RANDOM_FLOAT(-8,8) + RANDOM_FLOAT(-16,16) ); - - // calculate the midpoint and apex of the 'triangle' - // UNDONE: normalize any Z position differences between spot1 and spot2 so that triangle is always RIGHT - - // How much time does it take to get there? - - // get a rough idea of how high it can be thrown - vecMidPoint = vecSpot1 + (vecSpot2 - vecSpot1) * 0.5; - UTIL_TraceLine(vecMidPoint, vecMidPoint + Vector(0,0,500), ignore_monsters, ENT(pev), &tr); - vecMidPoint = tr.vecEndPos; - // (subtract 15 so the grenade doesn't hit the ceiling) - vecMidPoint.z -= 15; - - if (vecMidPoint.z < vecSpot1.z || vecMidPoint.z < vecSpot2.z) - { - // to not enough space, fail - return g_vecZero; - } - - // How high should the grenade travel to reach the apex - float distance1 = (vecMidPoint.z - vecSpot1.z); - float distance2 = (vecMidPoint.z - vecSpot2.z); - - // How long will it take for the grenade to travel this distance - float time1 = sqrt( distance1 / (0.5 * flGravity) ); - float time2 = sqrt( distance2 / (0.5 * flGravity) ); - - if (time1 < 0.1) - { - // too close - return g_vecZero; - } - - // how hard to throw sideways to get there in time. - vecGrenadeVel = (vecSpot2 - vecSpot1) / (time1 + time2); - // how hard upwards to reach the apex at the right time. - vecGrenadeVel.z = flGravity * time1; - - // find the apex - vecApex = vecSpot1 + vecGrenadeVel * time1; - vecApex.z = vecMidPoint.z; - - UTIL_TraceLine(vecSpot1, vecApex, dont_ignore_monsters, ENT(pev), &tr); - if (tr.flFraction != 1.0) - { - // fail! - return g_vecZero; - } - - // UNDONE: either ignore monsters or change it to not care if we hit our enemy - UTIL_TraceLine(vecSpot2, vecApex, ignore_monsters, ENT(pev), &tr); - if (tr.flFraction != 1.0) - { - // fail! - return g_vecZero; - } - - return vecGrenadeVel; -} - - -// -// VecCheckThrow - returns the velocity vector at which an object should be thrown from vecspot1 to hit vecspot2. -// returns g_vecZero if throw is not feasible. -// -Vector VecCheckThrow ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj ) -{ - float flGravity = CVAR_GET_FLOAT( "sv_gravity" ) * flGravityAdj; - - Vector vecGrenadeVel = (vecSpot2 - vecSpot1); - - // throw at a constant time - float time = vecGrenadeVel.Length( ) / flSpeed; - vecGrenadeVel = vecGrenadeVel * (1.0 / time); - - // adjust upward toss to compensate for gravity loss - vecGrenadeVel.z += flGravity * time * 0.5; - - Vector vecApex = vecSpot1 + (vecSpot2 - vecSpot1) * 0.5; - vecApex.z += 0.5 * flGravity * (time * 0.5) * (time * 0.5); - - TraceResult tr; - UTIL_TraceLine(vecSpot1, vecApex, dont_ignore_monsters, ENT(pev), &tr); - if (tr.flFraction != 1.0) - { - // fail! - return g_vecZero; - } - - UTIL_TraceLine(vecSpot2, vecApex, ignore_monsters, ENT(pev), &tr); - if (tr.flFraction != 1.0) - { - // fail! - return g_vecZero; - } - - return vecGrenadeVel; -} - - diff --git a/dmc/dlls/h_export.cpp b/dmc/dlls/h_export.cpp deleted file mode 100644 index 85a54da..0000000 --- a/dmc/dlls/h_export.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== h_export.cpp ======================================================== - - Entity classes exported by Halflife. - -*/ - -#include "extdll.h" -#include "util.h" - -#include "cbase.h" -#undef DLLEXPORT - -#ifdef _WIN32 -#define DLLEXPORT __stdcall -#else -#define DLLEXPORT __attribute__ ((visibility("default"))) -#endif - -// Holds engine functionality callbacks -enginefuncs_t g_engfuncs; -globalvars_t *gpGlobals; - - -#ifdef _WIN32 - -// Required DLL entry point -BOOL WINAPI DllMain( - HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - if (fdwReason == DLL_PROCESS_ATTACH) - { - } - else if (fdwReason == DLL_PROCESS_DETACH) - { - } - return TRUE; -} -#endif - -extern "C" void DLLEXPORT GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) -{ - memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t)); - gpGlobals = pGlobals; -} - diff --git a/dmc/dlls/hl.def b/dmc/dlls/hl.def deleted file mode 100644 index b4211ab..0000000 --- a/dmc/dlls/hl.def +++ /dev/null @@ -1,5 +0,0 @@ -LIBRARY hl -EXPORTS - GiveFnptrsToDll @1 -SECTIONS - .data READ WRITE diff --git a/dmc/dlls/hl.dsp b/dmc/dlls/hl.dsp deleted file mode 100644 index e261503..0000000 --- a/dmc/dlls/hl.dsp +++ /dev/null @@ -1,509 +0,0 @@ -# Microsoft Developer Studio Project File - Name="hl" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=hl - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "hl.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "hl.mak" CFG="hl - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "hl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "hl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$/GoldSrc/dmc/dlls", TTQCAAAA" -# PROP Scc_LocalPath "." -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "hl - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir ".\Release" -# PROP BASE Intermediate_Dir ".\Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\Releasehl" -# PROP Intermediate_Dir ".\Releasehl" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /G5 /MT /W3 /Zi /O2 /I "..\engine" /I "..\common" /I "..\..\public" /I "." /I "..\..\game_shared" /I "..\dlls" /I "..\..\engine" /I "..\..\common" /I "..\pm_shared" /I "..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "QUIVER" /D "VOXEL" /D "QUAKE2" /D "VALVE_DLL" /Fr /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /debug /machine:I386 /def:".\hl.def" /out:".\Releasehl/dmc.dll" -# SUBTRACT LINK32 /profile -# Begin Custom Build - Copying... -InputDir=.\Releasehl -ProjDir=. -InputPath=.\Releasehl\dmc.dll -InputName=dmc -SOURCE="$(InputPath)" - -BuildCmds= \ - call ..\..\filecopy.bat $(InputPath) $(ProjDir)\..\..\..\game\mod\dlls\$(InputName).dll \ - call ..\..\filecopy.bat $(InputDir)\$(InputName).pdb $(ProjDir)\..\..\..\game\mod\dlls\$(InputName).pdb \ - - -"$(ProjDir)\..\..\..\game\mod\dlls\$(InputName).dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) - -"$(ProjDir)\..\..\..\game\mod\dlls\$(InputName).pdb" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) -# End Custom Build - -!ELSEIF "$(CFG)" == "hl - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir ".\hl___Win" -# PROP BASE Intermediate_Dir ".\hl___Win" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\debughl" -# PROP Intermediate_Dir ".\debughl" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /G5 /MTd /W3 /Gm /ZI /Od /I "..\public" /I "." /I "..\..\game_shared" /I "..\dlls" /I "..\..\engine" /I "..\..\common" /I "..\pm_shared" /I "..\\" /I "..\..\public" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "QUIVER" /D "VOXEL" /D "QUAKE2" /D "VALVE_DLL" /FR /YX /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /i "..\engine" /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 user32.lib advapi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /def:".\hl.def" /implib:".\Debug\hl.lib" -# SUBTRACT LINK32 /profile -# Begin Custom Build - Copying... -ProjDir=. -InputPath=.\debughl\hl.dll -InputName=hl -SOURCE="$(InputPath)" - -"$(ProjDir)\..\..\..\game\mod\dlls\$(InputName).dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - call ..\..\filecopy.bat $(InputPath) $(ProjDir)\..\..\..\game\mod\dlls\$(InputName).dll - -# End Custom Build - -!ENDIF - -# Begin Target - -# Name "hl - Win32 Release" -# Name "hl - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90" -# Begin Group "Shared Weapons" - -# PROP Default_Filter "*.cpp" -# Begin Source File - -SOURCE=.\quake_gun.cpp -# End Source File -# Begin Source File - -SOURCE=.\quake_weapons_all.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=.\animating.cpp -# End Source File -# Begin Source File - -SOURCE=.\animation.cpp -# End Source File -# Begin Source File - -SOURCE=.\bmodels.cpp -# End Source File -# Begin Source File - -SOURCE=.\buttons.cpp -# End Source File -# Begin Source File - -SOURCE=.\cbase.cpp -# End Source File -# Begin Source File - -SOURCE=.\client.cpp -# End Source File -# Begin Source File - -SOURCE=.\combat.cpp -# End Source File -# Begin Source File - -SOURCE=.\doors.cpp -# End Source File -# Begin Source File - -SOURCE=.\effects.cpp -# End Source File -# Begin Source File - -SOURCE=.\explode.cpp -# End Source File -# Begin Source File - -SOURCE=.\func_break.cpp -# End Source File -# Begin Source File - -SOURCE=.\func_tank.cpp -# End Source File -# Begin Source File - -SOURCE=.\game.cpp -# End Source File -# Begin Source File - -SOURCE=.\gamerules.cpp -# End Source File -# Begin Source File - -SOURCE=.\globals.cpp -# End Source File -# Begin Source File - -SOURCE=.\h_ai.cpp -# End Source File -# Begin Source File - -SOURCE=.\h_export.cpp -# End Source File -# Begin Source File - -SOURCE=.\lights.cpp -# End Source File -# Begin Source File - -SOURCE=.\maprules.cpp -# End Source File -# Begin Source File - -SOURCE=.\monsters.cpp -# End Source File -# Begin Source File - -SOURCE=.\monsterstate.cpp -# End Source File -# Begin Source File - -SOURCE=.\multiplay_gamerules.cpp -# End Source File -# Begin Source File - -SOURCE=.\nodes.cpp -# End Source File -# Begin Source File - -SOURCE=.\observer.cpp -# End Source File -# Begin Source File - -SOURCE=.\pathcorner.cpp -# End Source File -# Begin Source File - -SOURCE=.\plane.cpp -# End Source File -# Begin Source File - -SOURCE=.\plats.cpp -# End Source File -# Begin Source File - -SOURCE=.\player.cpp -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_debug.c -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_math.c -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_shared.c -# End Source File -# Begin Source File - -SOURCE=.\quake_items.cpp -# End Source File -# Begin Source File - -SOURCE=.\quake_nail.cpp -# End Source File -# Begin Source File - -SOURCE=.\quake_player.cpp -# End Source File -# Begin Source File - -SOURCE=.\quake_rocket.cpp -# End Source File -# Begin Source File - -SOURCE=.\schedule.cpp -# End Source File -# Begin Source File - -SOURCE=.\singleplay_gamerules.cpp -# End Source File -# Begin Source File - -SOURCE=.\skill.cpp -# End Source File -# Begin Source File - -SOURCE=.\sound.cpp -# End Source File -# Begin Source File - -SOURCE=.\spectator.cpp -# End Source File -# Begin Source File - -SOURCE=.\subs.cpp -# End Source File -# Begin Source File - -SOURCE=.\teamplay_gamerules.cpp -# End Source File -# Begin Source File - -SOURCE=.\threewave_gamerules.cpp -# End Source File -# Begin Source File - -SOURCE=.\triggers.cpp -# End Source File -# Begin Source File - -SOURCE=.\util.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\voice_gamemgr.cpp -# End Source File -# Begin Source File - -SOURCE=.\weapons.cpp -# End Source File -# Begin Source File - -SOURCE=.\world.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" -# Begin Source File - -SOURCE=.\activity.h -# End Source File -# Begin Source File - -SOURCE=.\activitymap.h -# End Source File -# Begin Source File - -SOURCE=.\animation.h -# End Source File -# Begin Source File - -SOURCE=.\basemonster.h -# End Source File -# Begin Source File - -SOURCE=.\cbase.h -# End Source File -# Begin Source File - -SOURCE=.\cdll_dll.h -# End Source File -# Begin Source File - -SOURCE=.\client.h -# End Source File -# Begin Source File - -SOURCE=.\decals.h -# End Source File -# Begin Source File - -SOURCE=.\defaultai.h -# End Source File -# Begin Source File - -SOURCE=.\doors.h -# End Source File -# Begin Source File - -SOURCE=.\effects.h -# End Source File -# Begin Source File - -SOURCE=.\enginecallback.h -# End Source File -# Begin Source File - -SOURCE=.\explode.h -# End Source File -# Begin Source File - -SOURCE=.\extdll.h -# End Source File -# Begin Source File - -SOURCE=.\func_break.h -# End Source File -# Begin Source File - -SOURCE=.\gamerules.h -# End Source File -# Begin Source File - -SOURCE=.\items.h -# End Source File -# Begin Source File - -SOURCE=.\monsterevent.h -# End Source File -# Begin Source File - -SOURCE=.\monsters.h -# End Source File -# Begin Source File - -SOURCE=.\nodes.h -# End Source File -# Begin Source File - -SOURCE=.\plane.h -# End Source File -# Begin Source File - -SOURCE=.\player.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_debug.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_defs.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_info.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_materials.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_movevars.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_shared.h -# End Source File -# Begin Source File - -SOURCE=.\quake_gun.h -# End Source File -# Begin Source File - -SOURCE=.\saverestore.h -# End Source File -# Begin Source File - -SOURCE=.\schedule.h -# End Source File -# Begin Source File - -SOURCE=.\scripted.h -# End Source File -# Begin Source File - -SOURCE=.\scriptevent.h -# End Source File -# Begin Source File - -SOURCE=.\skill.h -# End Source File -# Begin Source File - -SOURCE=.\soundent.h -# End Source File -# Begin Source File - -SOURCE=.\spectator.h -# End Source File -# Begin Source File - -SOURCE=.\teamplay_gamerules.h -# End Source File -# Begin Source File - -SOURCE=.\threewave_gamerules.h -# End Source File -# Begin Source File - -SOURCE=.\trains.h -# End Source File -# Begin Source File - -SOURCE=.\util.h -# End Source File -# Begin Source File - -SOURCE=.\vector.h -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\voice_gamemgr.h -# End Source File -# Begin Source File - -SOURCE=.\weapons.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/dmc/dlls/hlgl.def b/dmc/dlls/hlgl.def deleted file mode 100644 index b94aa63..0000000 --- a/dmc/dlls/hlgl.def +++ /dev/null @@ -1,15 +0,0 @@ -LIBRARY hlgl -EXPORTS - GiveFnptrsToDll @1 - GetEntityInterfaces @2 - SetChangeParms @3 - SetNewParms @4 - ClientKill @5 - PutClientInServer @6 - PlayerPreThink @7 - PlayerPostThink @8 - ClientConnect @9 - ClientDisconnect @10 - StartFrame @11 -SECTIONS - .data READ WRITE diff --git a/dmc/dlls/items.cpp b/dmc/dlls/items.cpp deleted file mode 100644 index c0b7914..0000000 --- a/dmc/dlls/items.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== items.cpp ======================================================== - - functions governing the selection/use of weapons for players - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "weapons.h" -#include "player.h" -#include "skill.h" -#include "items.h" -#include "gamerules.h" - -extern int gmsgItemPickup; - -class CWorldItem : public CBaseEntity -{ -public: - void KeyValue(KeyValueData *pkvd ); - void Spawn( void ); - int m_iType; -}; - -LINK_ENTITY_TO_CLASS(world_items, CWorldItem); - -void CWorldItem::KeyValue(KeyValueData *pkvd) -{ - if (FStrEq(pkvd->szKeyName, "type")) - { - m_iType = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -void CWorldItem::Spawn( void ) -{ - CBaseEntity *pEntity = NULL; - - switch (m_iType) - { - case 44: // ITEM_BATTERY: - pEntity = CBaseEntity::Create( "item_battery", pev->origin, pev->angles ); - break; - case 42: // ITEM_ANTIDOTE: - pEntity = CBaseEntity::Create( "item_antidote", pev->origin, pev->angles ); - break; - case 43: // ITEM_SECURITY: - pEntity = CBaseEntity::Create( "item_security", pev->origin, pev->angles ); - break; - case 45: // ITEM_SUIT: - pEntity = CBaseEntity::Create( "item_suit", pev->origin, pev->angles ); - break; - } - - if (!pEntity) - { - ALERT( at_console, "unable to create world_item %d\n", m_iType ); - } - else - { - pEntity->pev->target = pev->target; - pEntity->pev->targetname = pev->targetname; - pEntity->pev->spawnflags = pev->spawnflags; - } - - REMOVE_ENTITY(edict()); -} - - -void CItem::Spawn( void ) -{ - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - UTIL_SetOrigin( pev, pev->origin ); - UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16)); - SetTouch(ItemTouch); - - 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; - } -} - -extern int gEvilImpulse101; - -void CItem::ItemTouch( CBaseEntity *pOther ) -{ - // if it's not a player, ignore - if ( !pOther->IsPlayer() ) - { - return; - } - - CBasePlayer *pPlayer = (CBasePlayer *)pOther; - - // ok, a player is touching this item, but can he have it? - if ( !g_pGameRules->CanHaveItem( pPlayer, this ) ) - { - // no? Ignore the touch. - return; - } - - if (MyTouch( pPlayer )) - { - SUB_UseTargets( pOther, USE_TOGGLE, 0 ); - SetTouch( NULL ); - - // player grabbed the item. - g_pGameRules->PlayerGotItem( pPlayer, this ); - if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES ) - { - Respawn(); - } - else - { - UTIL_Remove( this ); - } - } - else if (gEvilImpulse101) - { - UTIL_Remove( this ); - } -} - -CBaseEntity* CItem::Respawn( void ) -{ - SetTouch( NULL ); - pev->effects |= EF_NODRAW; - - UTIL_SetOrigin( pev, g_pGameRules->VecItemRespawnSpot( this ) );// blip to whereever you should respawn. - - SetThink ( Materialize ); - pev->nextthink = g_pGameRules->FlItemRespawnTime( this ); - return this; -} - -void CItem::Materialize( void ) -{ - if ( pev->effects & EF_NODRAW ) - { - // 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( ItemTouch ); -} - -#define SF_SUIT_SHORTLOGON 0x0001 - -class CItemSuit : public CItem -{ - void Spawn( void ) - { - Precache( ); - SET_MODEL(ENT(pev), "models/w_suit.mdl"); - CItem::Spawn( ); - } - void Precache( void ) - { - PRECACHE_MODEL ("models/w_suit.mdl"); - } - BOOL MyTouch( CBasePlayer *pPlayer ) - { - if ( pPlayer->pev->weapons & (1<spawnflags & SF_SUIT_SHORTLOGON ) - EMIT_SOUND_SUIT(pPlayer->edict(), "!HEV_A0"); // short version of suit logon, - else - EMIT_SOUND_SUIT(pPlayer->edict(), "!HEV_AAx"); // long version of suit logon - - pPlayer->pev->weapons |= (1<pev->armorvalue < MAX_NORMAL_BATTERY) && - (pPlayer->pev->weapons & (1<pev->armorvalue += gSkillData.batteryCapacity; - pPlayer->pev->armorvalue = V_min(pPlayer->pev->armorvalue, MAX_NORMAL_BATTERY); - - EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); - - MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); - WRITE_STRING( STRING(pev->classname) ); - MESSAGE_END(); - - - // Suit reports new power level - // For some reason this wasn't working in release build -- round it. - pct = (int)( (float)(pPlayer->pev->armorvalue * 100.0) * (1.0/MAX_NORMAL_BATTERY) + 0.5); - pct = (pct / 5); - if (pct > 0) - pct--; - - sprintf( szcharge,"!HEV_%1dP", pct ); - - //EMIT_SOUND_SUIT(ENT(pev), szcharge); - pPlayer->SetSuitUpdate(szcharge, FALSE, SUIT_NEXT_IN_30SEC); - return TRUE; - } - return FALSE; - } -}; - -LINK_ENTITY_TO_CLASS(item_battery, CItemBattery); - - -class CItemAntidote : public CItem -{ - void Spawn( void ) - { - Precache( ); - SET_MODEL(ENT(pev), "models/w_antidote.mdl"); - CItem::Spawn( ); - } - void Precache( void ) - { - PRECACHE_MODEL ("models/w_antidote.mdl"); - } - BOOL MyTouch( CBasePlayer *pPlayer ) - { - pPlayer->SetSuitUpdate("!HEV_DET4", FALSE, SUIT_NEXT_IN_1MIN); - - pPlayer->m_rgItems[ITEM_ANTIDOTE] += 1; - return TRUE; - } -}; - -LINK_ENTITY_TO_CLASS(item_antidote, CItemAntidote); - - -class CItemSecurity : public CItem -{ - void Spawn( void ) - { - Precache( ); - SET_MODEL(ENT(pev), "models/w_security.mdl"); - CItem::Spawn( ); - } - void Precache( void ) - { - PRECACHE_MODEL ("models/w_security.mdl"); - } - BOOL MyTouch( CBasePlayer *pPlayer ) - { - pPlayer->m_rgItems[ITEM_SECURITY] += 1; - return TRUE; - } -}; - -LINK_ENTITY_TO_CLASS(item_security, CItemSecurity); - -class CItemLongJump : public CItem -{ - void Spawn( void ) - { - Precache( ); - SET_MODEL(ENT(pev), "models/w_longjump.mdl"); - CItem::Spawn( ); - } - void Precache( void ) - { - PRECACHE_MODEL ("models/w_longjump.mdl"); - } - BOOL MyTouch( CBasePlayer *pPlayer ) - { - if ( pPlayer->m_fLongJump ) - { - return FALSE; - } - - if ( ( pPlayer->pev->weapons & (1<m_fLongJump = TRUE;// player now has longjump module - - g_engfuncs.pfnSetPhysicsKeyValue( pPlayer->edict(), "slj", "1" ); - - MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); - WRITE_STRING( STRING(pev->classname) ); - MESSAGE_END(); - - EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A1" ); // Play the longjump sound UNDONE: Kelly? correct sound? - return TRUE; - } - return FALSE; - } -}; - -LINK_ENTITY_TO_CLASS( item_longjump, CItemLongJump ); diff --git a/dmc/dlls/items.h b/dmc/dlls/items.h deleted file mode 100644 index e985296..0000000 --- a/dmc/dlls/items.h +++ /dev/null @@ -1,29 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef ITEMS_H -#define ITEMS_H - - -class CItem : public CBaseEntity -{ -public: - void Spawn( void ); - CBaseEntity* Respawn( void ); - void EXPORT ItemTouch( CBaseEntity *pOther ); - void EXPORT Materialize( void ); - virtual BOOL MyTouch( CBasePlayer *pPlayer ) { return FALSE; }; -}; - -#endif // ITEMS_H diff --git a/dmc/dlls/lights.cpp b/dmc/dlls/lights.cpp deleted file mode 100644 index 312aa30..0000000 --- a/dmc/dlls/lights.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== lights.cpp ======================================================== - - spawn and think functions for editor-placed lights - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" - - - -class CLight : public CPointEntity -{ -public: - virtual void KeyValue( KeyValueData* pkvd ); - virtual void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - int m_iStyle; - int m_iszPattern; -}; -LINK_ENTITY_TO_CLASS( light, CLight ); - -TYPEDESCRIPTION CLight::m_SaveData[] = -{ - DEFINE_FIELD( CLight, m_iStyle, FIELD_INTEGER ), - DEFINE_FIELD( CLight, m_iszPattern, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CLight, CPointEntity ); - - -// -// Cache user-entity-field values until spawn is called. -// -void CLight :: KeyValue( KeyValueData* pkvd) -{ - if (FStrEq(pkvd->szKeyName, "style")) - { - m_iStyle = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pitch")) - { - pev->angles.x = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pattern")) - { - m_iszPattern = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - { - CPointEntity::KeyValue( pkvd ); - } -} - -/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) LIGHT_START_OFF -Non-displayed light. -Default light value is 300 -Default style is 0 -If targeted, it will toggle between on or off. -*/ - -void CLight :: Spawn( void ) -{ - if (FStringNull(pev->targetname)) - { // inert light - REMOVE_ENTITY(ENT(pev)); - return; - } - - if (m_iStyle >= 32) - { -// CHANGE_METHOD(ENT(pev), em_use, light_use); - if (FBitSet(pev->spawnflags, SF_LIGHT_START_OFF)) - LIGHT_STYLE(m_iStyle, "a"); - else if (m_iszPattern) - LIGHT_STYLE(m_iStyle, (char *)STRING( m_iszPattern )); - else - LIGHT_STYLE(m_iStyle, "m"); - } -} - - -void CLight :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if (m_iStyle >= 32) - { - if ( !ShouldToggle( useType, !FBitSet(pev->spawnflags, SF_LIGHT_START_OFF) ) ) - return; - - if (FBitSet(pev->spawnflags, SF_LIGHT_START_OFF)) - { - if (m_iszPattern) - LIGHT_STYLE(m_iStyle, (char *)STRING( m_iszPattern )); - else - LIGHT_STYLE(m_iStyle, "m"); - ClearBits(pev->spawnflags, SF_LIGHT_START_OFF); - } - else - { - LIGHT_STYLE(m_iStyle, "a"); - SetBits(pev->spawnflags, SF_LIGHT_START_OFF); - } - } -} - -// -// shut up spawn functions for new spotlights -// -LINK_ENTITY_TO_CLASS( light_spot, CLight ); - - -class CEnvLight : public CLight -{ -public: - void KeyValue( KeyValueData* pkvd ); - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( light_environment, CEnvLight ); - -void CEnvLight::KeyValue( KeyValueData* pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "_light")) - { - int r, g, b, v, j; - char szColor[64]; - j = sscanf( pkvd->szValue, "%d %d %d %d\n", &r, &g, &b, &v ); - if (j == 1) - { - g = b = r; - } - else if (j == 4) - { - r = r * (v / 255.0); - g = g * (v / 255.0); - b = b * (v / 255.0); - } - - // simulate qrad direct, ambient,and gamma adjustments, as well as engine scaling - r = pow( r / 114.0, 0.6 ) * 264; - g = pow( g / 114.0, 0.6 ) * 264; - b = pow( b / 114.0, 0.6 ) * 264; - - pkvd->fHandled = TRUE; - sprintf( szColor, "%d", r ); - CVAR_SET_STRING( "sv_skycolor_r", szColor ); - sprintf( szColor, "%d", g ); - CVAR_SET_STRING( "sv_skycolor_g", szColor ); - sprintf( szColor, "%d", b ); - CVAR_SET_STRING( "sv_skycolor_b", szColor ); - } - else - { - CLight::KeyValue( pkvd ); - } -} - - -void CEnvLight :: Spawn( void ) -{ - char szVector[64]; - UTIL_MakeAimVectors( pev->angles ); - - sprintf( szVector, "%f", gpGlobals->v_forward.x ); - CVAR_SET_STRING( "sv_skyvec_x", szVector ); - sprintf( szVector, "%f", gpGlobals->v_forward.y ); - CVAR_SET_STRING( "sv_skyvec_y", szVector ); - sprintf( szVector, "%f", gpGlobals->v_forward.z ); - CVAR_SET_STRING( "sv_skyvec_z", szVector ); - - CLight::Spawn( ); -} diff --git a/dmc/dlls/maprules.cpp b/dmc/dlls/maprules.cpp deleted file mode 100644 index 45882bd..0000000 --- a/dmc/dlls/maprules.cpp +++ /dev/null @@ -1,918 +0,0 @@ -/*** -* -* 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. -* -****/ - -// ------------------------------------------- -// -// maprules.cpp -// -// This module contains entities for implementing/changing game -// rules dynamically within each map (.BSP) -// -// ------------------------------------------- - -#include "extdll.h" -#include "eiface.h" -#include "util.h" -#include "gamerules.h" -#include "maprules.h" -#include "cbase.h" -#include "player.h" - -class CRuleEntity : public CBaseEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - void SetMaster( int iszMaster ) { m_iszMaster = iszMaster; } - -protected: - BOOL CanFireForActivator( CBaseEntity *pActivator ); - -private: - string_t m_iszMaster; -}; - -TYPEDESCRIPTION CRuleEntity::m_SaveData[] = -{ - DEFINE_FIELD( CRuleEntity, m_iszMaster, FIELD_STRING), -}; - -IMPLEMENT_SAVERESTORE( CRuleEntity, CBaseEntity ); - - -void CRuleEntity::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = EF_NODRAW; -} - - -void CRuleEntity::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "master")) - { - SetMaster( ALLOC_STRING(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -BOOL CRuleEntity::CanFireForActivator( CBaseEntity *pActivator ) -{ - if ( m_iszMaster ) - { - if ( UTIL_IsMasterTriggered( m_iszMaster, pActivator ) ) - return TRUE; - else - return FALSE; - } - - return TRUE; -} - -// -// CRulePointEntity -- base class for all rule "point" entities (not brushes) -// -class CRulePointEntity : public CRuleEntity -{ -public: - void Spawn( void ); -}; - -void CRulePointEntity::Spawn( void ) -{ - CRuleEntity::Spawn(); - pev->frame = 0; - pev->model = 0; -} - -// -// CRuleBrushEntity -- base class for all rule "brush" entities (not brushes) -// Default behavior is to set up like a trigger, invisible, but keep the model for volume testing -// -class CRuleBrushEntity : public CRuleEntity -{ -public: - void Spawn( void ); - -private: -}; - -void CRuleBrushEntity::Spawn( void ) -{ - SET_MODEL( edict(), STRING(pev->model) ); - CRuleEntity::Spawn(); -} - - -// CGameScore / game_score -- award points to player / team -// Points +/- total -// Flag: Allow negative scores SF_SCORE_NEGATIVE -// Flag: Award points to team in teamplay SF_SCORE_TEAM - -#define SF_SCORE_NEGATIVE 0x0001 -#define SF_SCORE_TEAM 0x0002 - -class CGameScore : public CRulePointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - inline int Points( void ) { return pev->frags; } - inline BOOL AllowNegativeScore( void ) { return pev->spawnflags & SF_SCORE_NEGATIVE; } - inline BOOL AwardToTeam( void ) { return pev->spawnflags & SF_SCORE_TEAM; } - - inline void SetPoints( int points ) { pev->frags = points; } - -private: -}; - -LINK_ENTITY_TO_CLASS( game_score, CGameScore ); - - -void CGameScore::Spawn( void ) -{ - CRulePointEntity::Spawn(); -} - - -void CGameScore::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "points")) - { - SetPoints( atoi(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CRulePointEntity::KeyValue( pkvd ); -} - - - -void CGameScore::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - // Only players can use this - if ( pActivator->IsPlayer() ) - { - if ( AwardToTeam() ) - { - pActivator->AddPointsToTeam( Points(), AllowNegativeScore() ); - } - else - { - pActivator->AddPoints( Points(), AllowNegativeScore() ); - } - } -} - - -// CGameEnd / game_end -- Ends the game in MP - -class CGameEnd : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); -private: -}; - -LINK_ENTITY_TO_CLASS( game_end, CGameEnd ); - - -void CGameEnd::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - g_pGameRules->EndMultiplayerGame(); -} - - -// -// CGameText / game_text -- NON-Localized HUD Message (use env_message to display a titles.txt message) -// Flag: All players SF_ENVTEXT_ALLPLAYERS -// - - -#define SF_ENVTEXT_ALLPLAYERS 0x0001 - - -class CGameText : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - inline BOOL MessageToAll( void ) { return (pev->spawnflags & SF_ENVTEXT_ALLPLAYERS); } - inline void MessageSet( const char *pMessage ) { pev->message = ALLOC_STRING(pMessage); } - inline const char *MessageGet( void ) { return STRING(pev->message); } - -private: - - hudtextparms_t m_textParms; -}; - -LINK_ENTITY_TO_CLASS( game_text, CGameText ); - -// Save parms as a block. Will break save/restore if the structure changes, but this entity didn't ship with Half-Life, so -// it can't impact saved Half-Life games. -TYPEDESCRIPTION CGameText::m_SaveData[] = -{ - DEFINE_ARRAY( CGameText, m_textParms, FIELD_CHARACTER, sizeof(hudtextparms_t) ), -}; - -IMPLEMENT_SAVERESTORE( CGameText, CRulePointEntity ); - - -void CGameText::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "channel")) - { - m_textParms.channel = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "x")) - { - m_textParms.x = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "y")) - { - m_textParms.y = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "effect")) - { - m_textParms.effect = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "color")) - { - int color[4]; - UTIL_StringToIntArray( color, 4, pkvd->szValue ); - m_textParms.r1 = color[0]; - m_textParms.g1 = color[1]; - m_textParms.b1 = color[2]; - m_textParms.a1 = color[3]; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "color2")) - { - int color[4]; - UTIL_StringToIntArray( color, 4, pkvd->szValue ); - m_textParms.r2 = color[0]; - m_textParms.g2 = color[1]; - m_textParms.b2 = color[2]; - m_textParms.a2 = color[3]; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "fadein")) - { - m_textParms.fadeinTime = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "fadeout")) - { - m_textParms.fadeoutTime = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "holdtime")) - { - m_textParms.holdTime = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "fxtime")) - { - m_textParms.fxTime = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CRulePointEntity::KeyValue( pkvd ); -} - - -void CGameText::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( MessageToAll() ) - { - UTIL_HudMessageAll( m_textParms, MessageGet() ); - } - else - { - if ( pActivator->IsNetClient() ) - { - UTIL_HudMessage( pActivator, m_textParms, MessageGet() ); - } - } -} - - -// -// CGameTeamMaster / game_team_master -- "Masters" like multisource, but based on the team of the activator -// Only allows mastered entity to fire if the team matches my team -// -// team index (pulled from server team list "mp_teamlist" -// Flag: Remove on Fire -// Flag: Any team until set? -- Any team can use this until the team is set (otherwise no teams can use it) -// - -#define SF_TEAMMASTER_FIREONCE 0x0001 -#define SF_TEAMMASTER_ANYTEAM 0x0002 - -class CGameTeamMaster : public CRulePointEntity -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - int ObjectCaps( void ) { return CRulePointEntity:: ObjectCaps() | FCAP_MASTER; } - - BOOL IsTriggered( CBaseEntity *pActivator ); - const char *TeamID( void ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_TEAMMASTER_FIREONCE) ? TRUE : FALSE; } - inline BOOL AnyTeam( void ) { return (pev->spawnflags & SF_TEAMMASTER_ANYTEAM) ? TRUE : FALSE; } - -private: - BOOL TeamMatch( CBaseEntity *pActivator ); - - int m_teamIndex; - USE_TYPE triggerType; -}; - -LINK_ENTITY_TO_CLASS( game_team_master, CGameTeamMaster ); - -void CGameTeamMaster::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "teamindex")) - { - m_teamIndex = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "triggerstate")) - { - int type = atoi( pkvd->szValue ); - switch( type ) - { - case 0: - triggerType = USE_OFF; - break; - case 2: - triggerType = USE_TOGGLE; - break; - default: - triggerType = USE_ON; - break; - } - pkvd->fHandled = TRUE; - } - else - CRulePointEntity::KeyValue( pkvd ); -} - - -void CGameTeamMaster::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( useType == USE_SET ) - { - if ( value < 0 ) - { - m_teamIndex = -1; - } - else - { - m_teamIndex = g_pGameRules->GetTeamIndex( pActivator->TeamID() ); - } - return; - } - - if ( TeamMatch( pActivator ) ) - { - SUB_UseTargets( pActivator, triggerType, value ); - if ( RemoveOnFire() ) - UTIL_Remove( this ); - } -} - - -BOOL CGameTeamMaster::IsTriggered( CBaseEntity *pActivator ) -{ - return TeamMatch( pActivator ); -} - - -const char *CGameTeamMaster::TeamID( void ) -{ - if ( m_teamIndex < 0 ) // Currently set to "no team" - return ""; - - return g_pGameRules->GetIndexedTeamName( m_teamIndex ); // UNDONE: Fill this in with the team from the "teamlist" -} - - -BOOL CGameTeamMaster::TeamMatch( CBaseEntity *pActivator ) -{ - if ( m_teamIndex < 0 && AnyTeam() ) - return TRUE; - - if ( !pActivator ) - return FALSE; - - return UTIL_TeamsMatch( pActivator->TeamID(), TeamID() ); -} - - -// -// CGameTeamSet / game_team_set -- Changes the team of the entity it targets to the activator's team -// Flag: Fire once -// Flag: Clear team -- Sets the team to "NONE" instead of activator - -#define SF_TEAMSET_FIREONCE 0x0001 -#define SF_TEAMSET_CLEARTEAM 0x0002 - -class CGameTeamSet : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_TEAMSET_FIREONCE) ? TRUE : FALSE; } - inline BOOL ShouldClearTeam( void ) { return (pev->spawnflags & SF_TEAMSET_CLEARTEAM) ? TRUE : FALSE; } - -private: -}; - -LINK_ENTITY_TO_CLASS( game_team_set, CGameTeamSet ); - - -void CGameTeamSet::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( ShouldClearTeam() ) - { - SUB_UseTargets( pActivator, USE_SET, -1 ); - } - else - { - SUB_UseTargets( pActivator, USE_SET, 0 ); - } - - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } -} - - -// -// CGamePlayerZone / game_player_zone -- players in the zone fire my target when I'm fired -// -// Needs master? -class CGamePlayerZone : public CRuleBrushEntity -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - -private: - string_t m_iszInTarget; - string_t m_iszOutTarget; - string_t m_iszInCount; - string_t m_iszOutCount; -}; - -LINK_ENTITY_TO_CLASS( game_zone_player, CGamePlayerZone ); -TYPEDESCRIPTION CGamePlayerZone::m_SaveData[] = -{ - DEFINE_FIELD( CGamePlayerZone, m_iszInTarget, FIELD_STRING ), - DEFINE_FIELD( CGamePlayerZone, m_iszOutTarget, FIELD_STRING ), - DEFINE_FIELD( CGamePlayerZone, m_iszInCount, FIELD_STRING ), - DEFINE_FIELD( CGamePlayerZone, m_iszOutCount, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CGamePlayerZone, CRuleBrushEntity ); - -void CGamePlayerZone::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "intarget")) - { - m_iszInTarget = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "outtarget")) - { - m_iszOutTarget = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "incount")) - { - m_iszInCount = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "outcount")) - { - m_iszOutCount = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CRuleBrushEntity::KeyValue( pkvd ); -} - -void CGamePlayerZone::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int playersInCount = 0; - int playersOutCount = 0; - - if ( !CanFireForActivator( pActivator ) ) - return; - - CBaseEntity *pPlayer = NULL; - - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - pPlayer = UTIL_PlayerByIndex( i ); - if ( pPlayer ) - { - TraceResult trace; - int hullNumber; - - hullNumber = human_hull; - if ( pPlayer->pev->flags & FL_DUCKING ) - { - hullNumber = head_hull; - } - - UTIL_TraceModel( pPlayer->pev->origin, pPlayer->pev->origin, hullNumber, edict(), &trace ); - - if ( trace.fStartSolid ) - { - playersInCount++; - if ( m_iszInTarget ) - { - FireTargets( STRING(m_iszInTarget), pPlayer, pActivator, useType, value ); - } - } - else - { - playersOutCount++; - if ( m_iszOutTarget ) - { - FireTargets( STRING(m_iszOutTarget), pPlayer, pActivator, useType, value ); - } - } - } - } - - if ( m_iszInCount ) - { - FireTargets( STRING(m_iszInCount), pActivator, this, USE_SET, playersInCount ); - } - - if ( m_iszOutCount ) - { - FireTargets( STRING(m_iszOutCount), pActivator, this, USE_SET, playersOutCount ); - } -} - - - -// -// CGamePlayerHurt / game_player_hurt -- Damages the player who fires it -// Flag: Fire once - -#define SF_PKILL_FIREONCE 0x0001 -class CGamePlayerHurt : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_PKILL_FIREONCE) ? TRUE : FALSE; } - -private: -}; - -LINK_ENTITY_TO_CLASS( game_player_hurt, CGamePlayerHurt ); - - -void CGamePlayerHurt::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( pActivator->IsPlayer() ) - { - if ( pev->dmg < 0 ) - pActivator->TakeHealth( -pev->dmg, DMG_GENERIC ); - else - pActivator->TakeDamage( pev, pev, pev->dmg, DMG_GENERIC ); - } - - SUB_UseTargets( pActivator, useType, value ); - - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } -} - - - -// -// CGameCounter / game_counter -- Counts events and fires target -// Flag: Fire once -// Flag: Reset on Fire - -#define SF_GAMECOUNT_FIREONCE 0x0001 -#define SF_GAMECOUNT_RESET 0x0002 - -class CGameCounter : public CRulePointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_GAMECOUNT_FIREONCE) ? TRUE : FALSE; } - inline BOOL ResetOnFire( void ) { return (pev->spawnflags & SF_GAMECOUNT_RESET) ? TRUE : FALSE; } - - inline void CountUp( void ) { pev->frags++; } - inline void CountDown( void ) { pev->frags--; } - inline void ResetCount( void ) { pev->frags = pev->dmg; } - inline int CountValue( void ) { return pev->frags; } - inline int LimitValue( void ) { return pev->health; } - - inline BOOL HitLimit( void ) { return CountValue() == LimitValue(); } - -private: - - inline void SetCountValue( int value ) { pev->frags = value; } - inline void SetInitialValue( int value ) { pev->dmg = value; } -}; - -LINK_ENTITY_TO_CLASS( game_counter, CGameCounter ); - -void CGameCounter::Spawn( void ) -{ - // Save off the initial count - SetInitialValue( CountValue() ); - CRulePointEntity::Spawn(); -} - - -void CGameCounter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - switch( useType ) - { - case USE_ON: - case USE_TOGGLE: - CountUp(); - break; - - case USE_OFF: - CountDown(); - break; - - case USE_SET: - SetCountValue( (int)value ); - break; - } - - if ( HitLimit() ) - { - SUB_UseTargets( pActivator, USE_TOGGLE, 0 ); - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } - - if ( ResetOnFire() ) - { - ResetCount(); - } - } -} - - - -// -// CGameCounterSet / game_counter_set -- Sets the counter's value -// Flag: Fire once - -#define SF_GAMECOUNTSET_FIREONCE 0x0001 - -class CGameCounterSet : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_GAMECOUNTSET_FIREONCE) ? TRUE : FALSE; } - -private: -}; - -LINK_ENTITY_TO_CLASS( game_counter_set, CGameCounterSet ); - - -void CGameCounterSet::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - SUB_UseTargets( pActivator, USE_SET, pev->frags ); - - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } -} - - -// -// CGamePlayerEquip / game_playerequip -- Sets the default player equipment -// Flag: USE Only - -#define SF_PLAYEREQUIP_USEONLY 0x0001 -#define MAX_EQUIP 32 - -class CGamePlayerEquip : public CRulePointEntity -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Touch( CBaseEntity *pOther ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - inline BOOL UseOnly( void ) { return (pev->spawnflags & SF_PLAYEREQUIP_USEONLY) ? TRUE : FALSE; } - -private: - - void EquipPlayer( CBaseEntity *pPlayer ); - - string_t m_weaponNames[MAX_EQUIP]; - int m_weaponCount[MAX_EQUIP]; -}; - -LINK_ENTITY_TO_CLASS( game_player_equip, CGamePlayerEquip ); - - -void CGamePlayerEquip::KeyValue( KeyValueData *pkvd ) -{ - CRulePointEntity::KeyValue( pkvd ); - - if ( !pkvd->fHandled ) - { - for ( int i = 0; i < MAX_EQUIP; i++ ) - { - if ( !m_weaponNames[i] ) - { - char tmp[128]; - - UTIL_StripToken( pkvd->szKeyName, tmp ); - - m_weaponNames[i] = ALLOC_STRING(tmp); - m_weaponCount[i] = atoi(pkvd->szValue); - m_weaponCount[i] = V_max(1,m_weaponCount[i]); - pkvd->fHandled = TRUE; - break; - } - } - } -} - - -void CGamePlayerEquip::Touch( CBaseEntity *pOther ) -{ - if ( !CanFireForActivator( pOther ) ) - return; - - if ( UseOnly() ) - return; - - EquipPlayer( pOther ); -} - -void CGamePlayerEquip::EquipPlayer( CBaseEntity *pEntity ) -{ - CBasePlayer *pPlayer = NULL; - - if ( pEntity->IsPlayer() ) - { - pPlayer = (CBasePlayer *)pEntity; - } - - if ( !pPlayer ) - return; - - for ( int i = 0; i < MAX_EQUIP; i++ ) - { - if ( !m_weaponNames[i] ) - break; - for ( int j = 0; j < m_weaponCount[i]; j++ ) - { - pPlayer->GiveNamedItem( STRING(m_weaponNames[i]) ); - } - } -} - - -void CGamePlayerEquip::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - EquipPlayer( pActivator ); -} - - -// -// CGamePlayerTeam / game_player_team -- Changes the team of the player who fired it -// Flag: Fire once -// Flag: Kill Player -// Flag: Gib Player - -#define SF_PTEAM_FIREONCE 0x0001 -#define SF_PTEAM_KILL 0x0002 -#define SF_PTEAM_GIB 0x0004 - -class CGamePlayerTeam : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -private: - - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_PTEAM_FIREONCE) ? TRUE : FALSE; } - inline BOOL ShouldKillPlayer( void ) { return (pev->spawnflags & SF_PTEAM_KILL) ? TRUE : FALSE; } - inline BOOL ShouldGibPlayer( void ) { return (pev->spawnflags & SF_PTEAM_GIB) ? TRUE : FALSE; } - - const char *TargetTeamName( const char *pszTargetName ); -}; - -LINK_ENTITY_TO_CLASS( game_player_team, CGamePlayerTeam ); - - -const char *CGamePlayerTeam::TargetTeamName( const char *pszTargetName ) -{ - CBaseEntity *pTeamEntity = NULL; - - while ((pTeamEntity = UTIL_FindEntityByTargetname( pTeamEntity, pszTargetName )) != NULL) - { - if ( FClassnameIs( pTeamEntity->pev, "game_team_master" ) ) - return pTeamEntity->TeamID(); - } - - return NULL; -} - - -void CGamePlayerTeam::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( pActivator->IsPlayer() ) - { - const char *pszTargetTeam = TargetTeamName( STRING(pev->target) ); - if ( pszTargetTeam ) - { - CBasePlayer *pPlayer = (CBasePlayer *)pActivator; - g_pGameRules->ChangePlayerTeam( pPlayer, pszTargetTeam, ShouldKillPlayer(), ShouldGibPlayer() ); - } - } - - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } -} - - diff --git a/dmc/dlls/maprules.h b/dmc/dlls/maprules.h deleted file mode 100644 index 3772094..0000000 --- a/dmc/dlls/maprules.h +++ /dev/null @@ -1,22 +0,0 @@ -/*** -* -* 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. -* -****/ - -#ifndef MAPRULES_H -#define MAPRULES_H - - - -#endif // MAPRULES_H - diff --git a/dmc/dlls/monsterevent.h b/dmc/dlls/monsterevent.h deleted file mode 100644 index 46c5624..0000000 --- a/dmc/dlls/monsterevent.h +++ /dev/null @@ -1,34 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef MONSTEREVENT_H -#define MONSTEREVENT_H - -typedef struct -{ - int event; - char *options; -} MonsterEvent_t; - -#define EVENT_SPECIFIC 0 -#define EVENT_SCRIPTED 1000 -#define EVENT_SHARED 2000 -#define EVENT_CLIENT 5000 - -#define MONSTER_EVENT_BODYDROP_LIGHT 2001 -#define MONSTER_EVENT_BODYDROP_HEAVY 2002 - -#define MONSTER_EVENT_SWISHSOUND 2010 - -#endif // MONSTEREVENT_H diff --git a/dmc/dlls/monsters.cpp b/dmc/dlls/monsters.cpp deleted file mode 100644 index f2ff0b4..0000000 --- a/dmc/dlls/monsters.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -/* - -===== monsters.cpp ======================================================== - - Monster-related utility code - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "nodes.h" -#include "monsters.h" - -CBaseEntity* CBaseMonster :: CheckTraceHullAttack( float flDist, int iDamage, int iDmgType ) { return NULL; } -void CBaseMonster :: Eat ( float flFullDuration ) { } -BOOL CBaseMonster :: FShouldEat ( void ) { return TRUE; } -void CBaseMonster :: BarnacleVictimBitten ( entvars_t *pevBarnacle ) { } -void CBaseMonster :: BarnacleVictimReleased ( void ) { } -void CBaseMonster :: Listen ( void ) { } -float CBaseMonster :: FLSoundVolume ( CSound *pSound ) { return 0.0; } -BOOL CBaseMonster :: FValidateHintType ( short sHint ) { return FALSE; } -void CBaseMonster :: Look ( int iDistance ) { } -int CBaseMonster :: ISoundMask ( void ) { return 0; } -CSound* CBaseMonster :: PBestSound ( void ) { return NULL; } -CSound* CBaseMonster :: PBestScent ( void ) { return NULL; } -void CBaseMonster :: MonsterThink ( void ) { } -void CBaseMonster :: MonsterUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { } -int CBaseMonster :: IgnoreConditions ( void ) { return 0; } -void CBaseMonster :: RouteClear ( void ) { } -void CBaseMonster :: RouteNew ( void ) { } -BOOL CBaseMonster :: FRouteClear ( void ) { return FALSE; } -BOOL CBaseMonster :: FRefreshRoute ( void ) { return 0; } -BOOL CBaseMonster::MoveToEnemy( Activity movementAct, float waitTime ) { return FALSE; } -BOOL CBaseMonster::MoveToLocation( Activity movementAct, float waitTime, const Vector &goal ) { return FALSE; } -BOOL CBaseMonster::MoveToTarget( Activity movementAct, float waitTime ) { return FALSE; } -BOOL CBaseMonster::MoveToNode( Activity movementAct, float waitTime, const Vector &goal ) { return FALSE; } -int ShouldSimplify( int routeType ) { return TRUE; } -void CBaseMonster :: RouteSimplify( CBaseEntity *pTargetEnt ) { } -BOOL CBaseMonster :: FBecomeProne ( void ) { return TRUE; } -BOOL CBaseMonster :: CheckRangeAttack1 ( float flDot, float flDist ) { return FALSE; } -BOOL CBaseMonster :: CheckRangeAttack2 ( float flDot, float flDist ) { return FALSE; } -BOOL CBaseMonster :: CheckMeleeAttack1 ( float flDot, float flDist ) { return FALSE; } -BOOL CBaseMonster :: CheckMeleeAttack2 ( float flDot, float flDist ) { return FALSE; } -void CBaseMonster :: CheckAttacks ( CBaseEntity *pTarget, float flDist ) { } -BOOL CBaseMonster :: FCanCheckAttacks ( void ) { return FALSE; } -int CBaseMonster :: CheckEnemy ( CBaseEntity *pEnemy ) { return 0; } -void CBaseMonster :: PushEnemy( CBaseEntity *pEnemy, Vector &vecLastKnownPos ) { } -BOOL CBaseMonster :: PopEnemy( ) { return FALSE; } -void CBaseMonster :: SetActivity ( Activity NewActivity ) { } -void CBaseMonster :: SetSequenceByName ( char *szSequence ) { } -int CBaseMonster :: CheckLocalMove ( const Vector &vecStart, const Vector &vecEnd, CBaseEntity *pTarget, float *pflDist ) { return 0; } -float CBaseMonster :: OpenDoorAndWait( entvars_t *pevDoor ) { return 0.0; } -void CBaseMonster :: AdvanceRoute ( float distance ) { } -int CBaseMonster :: RouteClassify( int iMoveFlag ) { return 0; } -BOOL CBaseMonster :: BuildRoute ( const Vector &vecGoal, int iMoveFlag, CBaseEntity *pTarget ) { return FALSE; } -void CBaseMonster :: InsertWaypoint ( Vector vecLocation, int afMoveFlags ) { } -BOOL CBaseMonster :: FTriangulate ( const Vector &vecStart , const Vector &vecEnd, float flDist, CBaseEntity *pTargetEnt, Vector *pApex ) { return FALSE; } -void CBaseMonster :: Move ( float flInterval ) { } -BOOL CBaseMonster:: ShouldAdvanceRoute( float flWaypointDist ) { return FALSE; } -void CBaseMonster::MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval ) { } -void CBaseMonster :: MonsterInit ( void ) { } -void CBaseMonster :: MonsterInitThink ( void ) { } -void CBaseMonster :: StartMonster ( void ) { } -void CBaseMonster :: MovementComplete( void ) { } -int CBaseMonster::TaskIsRunning( void ) { return 0; } -int CBaseMonster::IRelationship ( CBaseEntity *pTarget ) { return 0; } -BOOL CBaseMonster :: FindCover ( Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist ) { return FALSE; } -BOOL CBaseMonster :: BuildNearestRoute ( Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist ) { return FALSE; } -CBaseEntity *CBaseMonster :: BestVisibleEnemy ( void ) { return NULL; } -BOOL CBaseMonster :: FInViewCone ( CBaseEntity *pEntity ) { return FALSE; } -BOOL CBaseMonster :: FInViewCone ( Vector *pOrigin ) { return FALSE; } -BOOL CBaseEntity :: FVisible ( CBaseEntity *pEntity ) { return FALSE; } -BOOL CBaseEntity :: FVisible ( const Vector &vecOrigin ) { return FALSE; } -void CBaseMonster :: MakeIdealYaw( Vector vecTarget ) { } -float CBaseMonster::FlYawDiff ( void ) { return 0.0; } -float CBaseMonster::ChangeYaw ( int yawSpeed ) { return 0; } -float CBaseMonster::VecToYaw ( Vector vecDir ) { return 0.0; } -void CBaseMonster :: SetEyePosition ( void ) { } -void CBaseMonster :: HandleAnimEvent( MonsterEvent_t *pEvent ) { } -Vector CBaseMonster :: GetGunPosition( void ) { return g_vecZero; } -void CBaseEntity::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { } -void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker ) { } -BOOL CBaseMonster :: FGetNodeRoute ( Vector vecDest ) { return TRUE; } -int CBaseMonster :: FindHintNode ( void ) { return NO_NODE; } -void CBaseMonster::ReportAIState( void ) { } -void CBaseMonster :: KeyValue( KeyValueData *pkvd ) { } -BOOL CBaseMonster :: FCheckAITrigger ( void ) { return FALSE; } -int CBaseMonster :: CanPlaySequence( BOOL fDisregardMonsterState, int interruptLevel ) { return FALSE; } -BOOL CBaseMonster :: FindLateralCover ( const Vector &vecThreat, const Vector &vecViewOffset ) { return FALSE; } -Vector CBaseMonster :: ShootAtEnemy( const Vector &shootOrigin ) { return g_vecZero; } -BOOL CBaseMonster :: FacingIdeal( void ) { return FALSE; } -BOOL CBaseMonster :: FCanActiveIdle ( void ) { return FALSE; } -void CBaseMonster::PlaySentence( const char *pszSentence, float duration, float volume, float attenuation ) { } -void CBaseMonster::PlayScriptedSentence( const char *pszSentence, float duration, float volume, float attenuation, BOOL bConcurrent, CBaseEntity *pListener ) { } -void CBaseMonster::SentenceStop( void ) { } -void CBaseMonster::CorpseFallThink( void ) { } -void CBaseMonster :: MonsterInitDead( void ) { } -BOOL CBaseMonster :: BBoxFlat ( void ) { return TRUE; } -BOOL CBaseMonster :: GetEnemy ( void ) { return FALSE; } -void CBaseMonster :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { } -CBaseEntity* CBaseMonster :: DropItem ( char *pszItemName, const Vector &vecPos, const Vector &vecAng ) { return NULL; } -BOOL CBaseMonster :: ShouldFadeOnDeath( void ) { return FALSE; } -void CBaseMonster::FadeMonster( void ) { } -BOOL CBaseMonster :: HasHumanGibs( void ) { return TRUE; } -BOOL CBaseMonster :: HasAlienGibs( void ) { return FALSE; } -MONSTERSTATE CBaseMonster :: GetIdealState ( void ) { return MONSTERSTATE_ALERT; } -Schedule_t* CBaseMonster :: GetScheduleOfType ( int Type ) { return NULL; } -Schedule_t *CBaseMonster :: GetSchedule ( void ) { return NULL; } -void CBaseMonster :: RunTask ( Task_t *pTask ) { } -void CBaseMonster :: StartTask ( Task_t *pTask ) { } -Schedule_t *CBaseMonster::ScheduleFromName( const char *pName ) { return NULL;} -void CBaseMonster::BecomeDead( void ) {} -void CBaseMonster :: RunAI ( void ) {} -void CBaseMonster :: Killed( entvars_t *pevAttacker, int iGib ) {} -int CBaseMonster :: TakeHealth (float flHealth, int bitsDamageType) { return 0; } -int CBaseMonster::Restore( class CRestore & ) { return 1; } -int CBaseMonster::Save( class CSave & ) { return 1; } - - diff --git a/dmc/dlls/monsters.h b/dmc/dlls/monsters.h deleted file mode 100644 index f7f1a03..0000000 --- a/dmc/dlls/monsters.h +++ /dev/null @@ -1,183 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -#ifndef MONSTERS_H -#include "skill.h" -#define MONSTERS_H - -/* - -===== monsters.h ======================================================== - - Header file for monster-related utility code - -*/ - -// CHECKLOCALMOVE result types -#define LOCALMOVE_INVALID 0 // move is not possible -#define LOCALMOVE_INVALID_DONT_TRIANGULATE 1 // move is not possible, don't try to triangulate -#define LOCALMOVE_VALID 2 // move is possible - -// Hit Group standards -#define HITGROUP_GENERIC 0 -#define HITGROUP_HEAD 1 -#define HITGROUP_CHEST 2 -#define HITGROUP_STOMACH 3 -#define HITGROUP_LEFTARM 4 -#define HITGROUP_RIGHTARM 5 -#define HITGROUP_LEFTLEG 6 -#define HITGROUP_RIGHTLEG 7 - - -// Monster Spawnflags -#define SF_MONSTER_WAIT_TILL_SEEN 1// spawnflag that makes monsters wait until player can see them before attacking. -#define SF_MONSTER_GAG 2 // no idle noises from this monster -#define SF_MONSTER_HITMONSTERCLIP 4 -// 8 -#define SF_MONSTER_PRISONER 16 // monster won't attack anyone, no one will attacke him. -// 32 -// 64 -#define SF_MONSTER_WAIT_FOR_SCRIPT 128 //spawnflag that makes monsters wait to check for attacking until the script is done or they've been attacked -#define SF_MONSTER_PREDISASTER 256 //this is a predisaster scientist or barney. Influences how they speak. -#define SF_MONSTER_FADECORPSE 512 // Fade out corpse after death -#define SF_MONSTER_FALL_TO_GROUND 0x80000000 - -// specialty spawnflags -#define SF_MONSTER_TURRET_AUTOACTIVATE 32 -#define SF_MONSTER_TURRET_STARTINACTIVE 64 -#define SF_MONSTER_WAIT_UNTIL_PROVOKED 64 // don't attack the player unless provoked - - - -// MoveToOrigin stuff -#define MOVE_START_TURN_DIST 64 // when this far away from moveGoal, start turning to face next goal -#define MOVE_STUCK_DIST 32 // if a monster can't step this far, it is stuck. - - -// MoveToOrigin stuff -#define MOVE_NORMAL 0// normal move in the direction monster is facing -#define MOVE_STRAFE 1// moves in direction specified, no matter which way monster is facing - -// spawn flags 256 and above are already taken by the engine -extern void UTIL_MoveToOrigin( edict_t* pent, const Vector &vecGoal, float flDist, int iMoveType ); - -Vector VecCheckToss ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj = 1.0 ); -Vector VecCheckThrow ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj = 1.0 ); -extern DLL_GLOBAL Vector g_vecAttackDir; -extern DLL_GLOBAL CONSTANT float g_flMeleeRange; -extern DLL_GLOBAL CONSTANT float g_flMediumRange; -extern DLL_GLOBAL CONSTANT float g_flLongRange; -extern void EjectBrass (const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype ); -extern void ExplodeModel( const Vector &vecOrigin, float speed, int model, int count ); - -BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget ); -BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize = 0.0 ); - -// monster to monster relationship types -#define R_AL -2 // (ALLY) pals. Good alternative to R_NO when applicable. -#define R_FR -1// (FEAR)will run -#define R_NO 0// (NO RELATIONSHIP) disregard -#define R_DL 1// (DISLIKE) will attack -#define R_HT 2// (HATE)will attack this character instead of any visible DISLIKEd characters -#define R_NM 3// (NEMESIS) A monster Will ALWAYS attack its nemsis, no matter what - - -// these bits represent the monster's memory -#define MEMORY_CLEAR 0 -#define bits_MEMORY_PROVOKED ( 1 << 0 )// right now only used for houndeyes. -#define bits_MEMORY_INCOVER ( 1 << 1 )// monster knows it is in a covered position. -#define bits_MEMORY_SUSPICIOUS ( 1 << 2 )// Ally is suspicious of the player, and will move to provoked more easily -#define bits_MEMORY_PATH_FINISHED ( 1 << 3 )// Finished monster path (just used by big momma for now) -#define bits_MEMORY_ON_PATH ( 1 << 4 )// Moving on a path -#define bits_MEMORY_MOVE_FAILED ( 1 << 5 )// Movement has already failed -#define bits_MEMORY_FLINCHED ( 1 << 6 )// Has already flinched -#define bits_MEMORY_KILLED ( 1 << 7 )// HACKHACK -- remember that I've already called my Killed() -#define bits_MEMORY_CUSTOM4 ( 1 << 28 ) // Monster-specific memory -#define bits_MEMORY_CUSTOM3 ( 1 << 29 ) // Monster-specific memory -#define bits_MEMORY_CUSTOM2 ( 1 << 30 ) // Monster-specific memory -#define bits_MEMORY_CUSTOM1 ( 1 << 31 ) // Monster-specific memory - -// trigger conditions for scripted AI -// these MUST match the CHOICES interface in halflife.fgd for the base monster -enum -{ - AITRIGGER_NONE = 0, - AITRIGGER_SEEPLAYER_ANGRY_AT_PLAYER, - AITRIGGER_TAKEDAMAGE, - AITRIGGER_HALFHEALTH, - AITRIGGER_DEATH, - AITRIGGER_SQUADMEMBERDIE, - AITRIGGER_SQUADLEADERDIE, - AITRIGGER_HEARWORLD, - AITRIGGER_HEARPLAYER, - AITRIGGER_HEARCOMBAT, - AITRIGGER_SEEPLAYER_UNCONDITIONAL, - AITRIGGER_SEEPLAYER_NOT_IN_COMBAT, -}; -/* - 0 : "No Trigger" - 1 : "See Player" - 2 : "Take Damage" - 3 : "50% Health Remaining" - 4 : "Death" - 5 : "Squad Member Dead" - 6 : "Squad Leader Dead" - 7 : "Hear World" - 8 : "Hear Player" - 9 : "Hear Combat" -*/ - -// -// A gib is a chunk of a body, or a piece of wood/metal/rocks/etc. -// -class CGib : public CBaseEntity -{ -public: - void Spawn( const char *szGibModel ); - void EXPORT BounceGibTouch ( CBaseEntity *pOther ); - void EXPORT StickyGibTouch ( CBaseEntity *pOther ); - void EXPORT WaitTillLand( void ); - void LimitVelocity( void ); - - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; } - static void SpawnHeadGib( entvars_t *pevVictim ); - static void SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int human ); - static void SpawnStickyGibs( entvars_t *pevVictim, Vector vecOrigin, int cGibs ); - - int m_bloodColor; - int m_cBloodDecals; - int m_material; - float m_lifeTime; -}; - - -#define CUSTOM_SCHEDULES\ - virtual Schedule_t *ScheduleFromName( const char *pName );\ - static Schedule_t *m_scheduleList[]; - -#define DEFINE_CUSTOM_SCHEDULES(derivedClass)\ - Schedule_t *derivedClass::m_scheduleList[] = - -#define IMPLEMENT_CUSTOM_SCHEDULES(derivedClass, baseClass)\ - Schedule_t *derivedClass::ScheduleFromName( const char *pName )\ - {\ - Schedule_t *pSchedule = ScheduleInList( pName, m_scheduleList, ARRAYSIZE(m_scheduleList) );\ - if ( !pSchedule )\ - return baseClass::ScheduleFromName(pName);\ - return pSchedule;\ - } - - - -#endif //MONSTERS_H diff --git a/dmc/dlls/monsterstate.cpp b/dmc/dlls/monsterstate.cpp deleted file mode 100644 index ddc0e70..0000000 --- a/dmc/dlls/monsterstate.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -//========================================================= -// monsterstate.cpp - base class monster functions for -// controlling core AI. -//========================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "nodes.h" -#include "monsters.h" -#include "animation.h" -#include "saverestore.h" - -void CBaseMonster :: SetState ( MONSTERSTATE State ) { }; diff --git a/dmc/dlls/multiplay_gamerules.cpp b/dmc/dlls/multiplay_gamerules.cpp deleted file mode 100644 index 5add9b1..0000000 --- a/dmc/dlls/multiplay_gamerules.cpp +++ /dev/null @@ -1,1672 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// -// teamplay_gamerules.cpp -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "skill.h" -#include "game.h" -#include "items.h" -#include "hltv.h" - -#if !defined ( _WIN32 ) -#include -#endif - -#define INTERMISSION_TIME 60 - -#if defined( THREEWAVE ) -char* GetTeamName( int team ); -#endif - -class CDMCGameMgrHelper : public IVoiceGameMgrHelper -{ -public: - virtual bool CanPlayerHearPlayer(CBasePlayer *pPlayer1, CBasePlayer *pPlayer2) - { - return true; - } -}; -static CDMCGameMgrHelper g_GameMgrHelper; - -bool g_bHaveMOTD; - -extern DLL_GLOBAL CGameRules *g_pGameRules; -extern DLL_GLOBAL BOOL g_fGameOver; -extern int gmsgDeathMsg; // client dll messages -extern int gmsgScoreInfo; -extern int gmsgMOTD; -extern int gmsgServerName; - -#define ITEM_RESPAWN_TIME 30 -#define WEAPON_RESPAWN_TIME 20 -#define AMMO_RESPAWN_TIME 20 - -char *g_szDeathType; - -//********************************************************* -// Rules for the half-life multiplayer game. -//********************************************************* - -CHalfLifeMultiplay :: CHalfLifeMultiplay() -{ - m_VoiceGameMgr.Init(&g_GameMgrHelper, gpGlobals->maxClients); - int length; - - char * pFileList = (char*)LOAD_FILE_FOR_ME( "motd.txt", &length ); - - if ( pFileList ) - g_bHaveMOTD = true; - else - g_bHaveMOTD = false; - - RefreshSkillData(); - m_flIntermissionEndTime = 0; - m_flGameEndTime = 0.0; - - // 11/8/98 - // Modified by YWB: Server .cfg file is now a cvar, so that - // server ops can run multiple game servers, with different server .cfg files, - // from a single installed directory. - // Mapcyclefile is already a cvar. - - // 3/31/99 - // Added lservercfg file cvar, since listen and dedicated servers should not - // share a single config file. (sjb) - if ( IS_DEDICATED_SERVER() ) - { - // dedicated server - char *servercfgfile = (char *)CVAR_GET_STRING( "servercfgfile" ); - - if ( servercfgfile && servercfgfile[0] ) - { - char szCommand[256]; - - ALERT( at_console, "Executing dedicated server config file\n" ); - sprintf( szCommand, "exec %s\n", servercfgfile ); - SERVER_COMMAND( szCommand ); - } - } - else - { - // listen server - char *lservercfgfile = (char *)CVAR_GET_STRING( "lservercfgfile" ); - - if ( lservercfgfile && lservercfgfile[0] ) - { - char szCommand[256]; - - ALERT( at_console, "Executing listen server config file\n" ); - sprintf( szCommand, "exec %s\n", lservercfgfile ); - SERVER_COMMAND( szCommand ); - } - } -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay::RefreshSkillData( void ) -{ -// load all default values - CGameRules::RefreshSkillData(); - -// override some values for multiplay. - - // suitcharger - gSkillData.suitchargerCapacity = 30; - - // Crowbar whack - gSkillData.plrDmgCrowbar = 25; - - // Glock Round - gSkillData.plrDmg9MM = 12; - - // 357 Round - gSkillData.plrDmg357 = 40; - - // MP5 Round - gSkillData.plrDmgMP5 = 12; - - // M203 grenade - gSkillData.plrDmgM203Grenade = 100; - - // Shotgun buckshot - gSkillData.plrDmgBuckshot = 20;// fewer pellets in deathmatch - - // Crossbow - gSkillData.plrDmgCrossbowClient = 20; - - // RPG - gSkillData.plrDmgRPG = 120; - - // Egon - gSkillData.plrDmgEgonWide = 20; - gSkillData.plrDmgEgonNarrow = 10; - - // Hand Grendade - gSkillData.plrDmgHandGrenade = 100; - - // Satchel Charge - gSkillData.plrDmgSatchel = 120; - - // Tripmine - gSkillData.plrDmgTripmine = 150; - - // hornet - gSkillData.plrDmgHornet = 10; -} - -// longest the intermission can last, in seconds -#define MAX_INTERMISSION_TIME 120 - -BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) -{ - if(m_VoiceGameMgr.ClientCommand(pPlayer, pcmd)) - return TRUE; - - return CGameRules::ClientCommand(pPlayer, pcmd); -} - -extern cvar_t mp_chattime; - -extern cvar_t timeleft, fragsleft; -//========================================================= -//========================================================= -void CHalfLifeMultiplay :: Think ( void ) -{ - m_VoiceGameMgr.Update(gpGlobals->frametime); - - ///// Check game rules ///// - static int last_frags; - static int last_time; - - int frags_remaining = 0; - int time_remaining = 0; - - if ( g_fGameOver ) // someone else quit the game already - { - // bounds check - int time = (int)CVAR_GET_FLOAT( "mp_chattime" ); - if ( time < 1 ) - CVAR_SET_STRING( "mp_chattime", "1" ); - else if ( time > INTERMISSION_TIME ) - CVAR_SET_STRING( "mp_chattime", UTIL_dtos1( INTERMISSION_TIME ) ); - - m_flIntermissionEndTime = m_flIntermissionStartTime + mp_chattime.value; - - // check to see if we should change levels now - if ( m_flIntermissionEndTime < gpGlobals->time ) - { - if ( m_iEndIntermissionButtonHit // check that someone has pressed a key, or the max intermission time is over - || ( ( m_flIntermissionStartTime + INTERMISSION_TIME ) < gpGlobals->time) ) - ChangeLevel(); // intermission is over - } - - return; - } - - if ( m_flGameEndTime != 0.0 && m_flGameEndTime <= gpGlobals->time ) - { - GoToIntermission(); - m_flGameEndTime = 0.0; - return; - } - - float flTimeLimit = timelimit.value * 60; - float flFragLimit = fraglimit.value; - - time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0); - - if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit && m_flGameEndTime == 0.0 ) - { - GoToIntermission(); - return; - } - - if ( flFragLimit && m_flGameEndTime == 0.0 ) - { - int bestfrags = 9999; - int remain; - - // check if any player is over the frag limit - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - - if ( pPlayer && pPlayer->pev->frags >= flFragLimit ) - { - m_flGameEndTime = gpGlobals->time + 1.5; - return; - } - - - if ( pPlayer ) - { - remain = flFragLimit - pPlayer->pev->frags; - if ( remain < bestfrags ) - { - bestfrags = remain; - } - } - - } - frags_remaining = bestfrags; - } - - // Updates when frags change - if ( frags_remaining != last_frags ) - { - g_engfuncs.pfnCvar_DirectSet( &fragsleft, UTIL_VarArgs( "%i", frags_remaining ) ); - } - - // Updates once per second - if ( timeleft.value != last_time ) - { - g_engfuncs.pfnCvar_DirectSet( &timeleft, UTIL_VarArgs( "%i", time_remaining ) ); - } - - last_frags = frags_remaining; - last_time = time_remaining; -} - - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::IsMultiplayer( void ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::IsDeathmatch( void ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::IsCoOp( void ) -{ - return gpGlobals->coop; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ - if ( !pWeapon->CanDeploy() ) - { - // that weapon can't deploy anyway. - return FALSE; - } - - if ( !pPlayer->m_pActiveItem ) - { - // player doesn't have an active item! - return TRUE; - } - - if ( !pPlayer->m_pActiveItem->CanHolster() ) - { - // can't put away the active item. - return FALSE; - } - - if ( pWeapon->iWeight() > pPlayer->m_pActiveItem->iWeight() ) - { - return TRUE; - } - - return FALSE; -} - -BOOL CHalfLifeMultiplay :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) -{ - - CBasePlayerItem *pCheck; - CBasePlayerItem *pBest;// this will be used in the event that we don't find a weapon in the same category. - int iBestWeight; - int i; - - iBestWeight = -1;// no weapon lower than -1 can be autoswitched to - pBest = NULL; - - if ( !pCurrentWeapon->CanHolster() ) - { - // can't put this gun away right now, so can't switch. - return FALSE; - } - - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - pCheck = pPlayer->m_rgpPlayerItems[ i ]; - - while ( pCheck ) - { - if ( pCheck->iWeight() > -1 && pCheck->iWeight() == pCurrentWeapon->iWeight() && pCheck != pCurrentWeapon ) - { - // this weapon is from the same category. - if ( pCheck->CanDeploy() ) - { - if ( pPlayer->SwitchWeapon( pCheck ) ) - { - return TRUE; - } - } - } - else if ( pCheck->iWeight() > iBestWeight && pCheck != pCurrentWeapon )// don't reselect the weapon we're trying to get rid of - { - //ALERT ( at_console, "Considering %s\n", STRING( pCheck->pev->classname ) ); - // we keep updating the 'best' weapon just in case we can't find a weapon of the same weight - // that the player was using. This will end up leaving the player with his heaviest-weighted - // weapon. - if ( pCheck->CanDeploy() ) - { - // if this weapon is useable, flag it as the best - iBestWeight = pCheck->iWeight(); - pBest = pCheck; - } - } - - pCheck = pCheck->m_pNext; - } - } - - // if we make it here, we've checked all the weapons and found no useable - // weapon in the same catagory as the current weapon. - - // if pBest is null, we didn't find ANYTHING. Shouldn't be possible- should always - // at least get the crowbar, but ya never know. - if ( !pBest ) - { - return FALSE; - } - - pPlayer->SwitchWeapon( pBest ); - - return TRUE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) -{ - m_VoiceGameMgr.ClientConnected(pEntity); - return TRUE; -} - -extern int gmsgSayText; -extern int gmsgGameMode; - -void CHalfLifeMultiplay :: UpdateGameMode( CBasePlayer *pPlayer ) -{ - MESSAGE_BEGIN( MSG_ONE, gmsgGameMode, NULL, pPlayer->edict() ); - WRITE_BYTE( 0 ); // game mode none - MESSAGE_END(); -} - -void CHalfLifeMultiplay :: InitHUD( CBasePlayer *pl ) -{ - // notify other clients of player joining the game - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, UTIL_VarArgs( "%s has joined the game\n", - ( pl->pev->netname && STRING(pl->pev->netname)[0] != 0 ) ? STRING(pl->pev->netname) : "unconnected" ) ); - -#if !defined( THREEWAVE ) - - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" entered the game\n", - STRING( pl->pev->netname ), - GETPLAYERUSERID( pl->edict() ), - GETPLAYERAUTHID( pl->edict() ), - GETPLAYERUSERID( pl->edict() ) ); -#else - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" entered the game\n", - STRING( pl->pev->netname ), - GETPLAYERUSERID( pl->edict() ), - GETPLAYERAUTHID( pl->edict() ), - GetTeamName( pl->pev->team ) ); -#endif - - UpdateGameMode( pl ); - - // sending just one score makes the hud scoreboard active; otherwise - // it is just disabled for single play - MESSAGE_BEGIN( MSG_ONE, gmsgScoreInfo, NULL, pl->edict() ); - WRITE_BYTE( ENTINDEX(pl->edict()) ); - WRITE_SHORT( 0 ); - WRITE_SHORT( 0 ); - WRITE_SHORT( 0 ); - MESSAGE_END(); - - SendMOTDToClient( pl->edict() ); - - // loop through all active players and send their score info to the new client - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - // FIXME: Probably don't need to cast this just to read m_iDeaths - CBasePlayer *plr = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if ( plr ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgScoreInfo, NULL, pl->edict() ); - WRITE_BYTE( i ); // client number - WRITE_SHORT( plr->pev->frags ); - WRITE_SHORT( plr->m_iDeaths ); - WRITE_SHORT( plr->pev->team ); - MESSAGE_END(); - } - } - - if ( g_fGameOver ) - { - MESSAGE_BEGIN( MSG_ONE, SVC_INTERMISSION, NULL, pl->edict() ); - MESSAGE_END(); - } -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay :: ClientDisconnected( edict_t *pClient ) -{ - if ( pClient ) - { - CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance( pClient ); - - if ( pPlayer ) - { - FireTargets( "game_playerleave", pPlayer, pPlayer, USE_TOGGLE, 0 ); - -#if !defined( THREEWAVE ) - - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" disconnected\n", - STRING( pPlayer->pev->netname ), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - GETPLAYERUSERID( pPlayer->edict() ) ); -#else - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" disconnected\n", - STRING( pPlayer->pev->netname ), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - GetTeamName( pPlayer->pev->team ) ); -#endif - - pPlayer->RemoveAllItems( TRUE );// destroy all of the players weapons and items - } - } -} - -//========================================================= -//========================================================= -float CHalfLifeMultiplay :: FlPlayerFallDamage( CBasePlayer *pPlayer ) -{ - int iFallDamage = (int)CVAR_GET_FLOAT("mp_falldamage"); - - switch ( iFallDamage ) - { - case 1://progressive - pPlayer->m_flFallVelocity -= PLAYER_MAX_SAFE_FALL_SPEED; - return pPlayer->m_flFallVelocity * DAMAGE_FOR_FALL_SPEED; - break; - default: - case 0:// fixed - return 5; - break; - } -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay :: PlayerThink( CBasePlayer *pPlayer ) -{ - if ( g_fGameOver ) - { - // check for button presses - if ( pPlayer->m_afButtonPressed & ( IN_DUCK | IN_ATTACK | IN_ATTACK2 | IN_USE | IN_JUMP ) ) - m_iEndIntermissionButtonHit = TRUE; - - // clear attack/use commands from player - pPlayer->m_afButtonPressed = 0; - pPlayer->pev->button = 0; - pPlayer->m_afButtonReleased = 0; - } -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay :: PlayerSpawn( CBasePlayer *pPlayer ) -{ - BOOL addDefault; - CBaseEntity *pWeaponEntity = NULL; - - pPlayer->pev->weapons |= (1<Touch( pPlayer ); - addDefault = FALSE; - } - - if ( addDefault ) - { - // Start with init ammoload - pPlayer->m_iAmmoShells = 25; - - // Start with shotgun and axe - pPlayer->GiveNamedItem( "weapon_quakegun" ); - pPlayer->m_iQuakeItems |= (IT_SHOTGUN | IT_AXE); - pPlayer->m_iQuakeWeapon = pPlayer->W_BestWeapon(); - pPlayer->W_SetCurrentAmmo(); - } -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay :: FPlayerCanRespawn( CBasePlayer *pPlayer ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -float CHalfLifeMultiplay :: FlPlayerSpawnTime( CBasePlayer *pPlayer ) -{ - return gpGlobals->time;//now! -} - -BOOL CHalfLifeMultiplay :: AllowAutoTargetCrosshair( void ) -{ - return ( CVAR_GET_FLOAT( "mp_autocrosshair" ) != 0 ); -} - -//========================================================= -// IPointsForKill - how many points awarded to anyone -// that kills this player? -//========================================================= -int CHalfLifeMultiplay :: IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) -{ - return 1; -} - -void CHalfLifeMultiplay::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) -{ - pPlayer->m_iFOV = atoi( g_engfuncs.pfnInfoKeyValue( infobuffer, "cl_fov" ) ); - pPlayer->m_iAutoWepSwitch = atoi( g_engfuncs.pfnInfoKeyValue( infobuffer, "cl_autowepswitch" ) ); -} - -//========================================================= -// PlayerKilled - someone/something killed this player -//========================================================= -void CHalfLifeMultiplay :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ - DeathNotice( pVictim, pKiller, pInflictor ); - - pVictim->m_iDeaths += 1; - - - FireTargets( "game_playerdie", pVictim, pVictim, USE_TOGGLE, 0 ); - CBasePlayer *peKiller = NULL; - CBaseEntity *ktmp = CBaseEntity::Instance( pKiller ); - if ( ktmp && (ktmp->Classify() == CLASS_PLAYER) ) - peKiller = (CBasePlayer*)ktmp; - - if ( pVictim->pev == pKiller ) - { // killed self - pKiller->frags -= 1; - } - else if ( ktmp && ktmp->IsPlayer() ) - { - // if a player dies in a deathmatch game and the killer is a client, award the killer some points - pKiller->frags += IPointsForKill( peKiller, pVictim ); - - FireTargets( "game_playerkill", ktmp, ktmp, USE_TOGGLE, 0 ); - } - else - { // killed by the world - pVictim->pev->frags -= 1; - } - - // update the scores - // killed scores - MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); - WRITE_SHORT( pVictim->pev->frags ); - WRITE_SHORT( pVictim->m_iDeaths ); - WRITE_SHORT( pVictim->pev->team ); - MESSAGE_END(); - - // killers score, if it's a player - CBaseEntity *ep = CBaseEntity::Instance( pKiller ); - if ( ep && ep->Classify() == CLASS_PLAYER ) - { - CBasePlayer *PK = (CBasePlayer*)ep; - - MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); - WRITE_BYTE( ENTINDEX(PK->edict()) ); - WRITE_SHORT( PK->pev->frags ); - WRITE_SHORT( PK->m_iDeaths ); - WRITE_SHORT( PK->pev->team ); - MESSAGE_END(); - - // let the killer paint another decal as soon as he'd like. - PK->m_flNextDecalTime = gpGlobals->time; - } -} - -//========================================================= -// Deathnotice. -//========================================================= -void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ) -{ - // Work out what killed the player, and send a message to all clients about it - CBaseEntity *Killer = CBaseEntity::Instance( pKiller ); - - const char *killer_weapon_name = "world"; // by default, the player is killed by the world - int killer_index = 0; - - // Hack to fix name change - char *tau = "tau_cannon"; - char *gluon = "gluon gun"; - - // QUAKECLASSIC - // Might have overridden - if (g_szDeathType) - { - killer_weapon_name = g_szDeathType; - } - else - { - if ( pKiller->flags & FL_CLIENT ) - { - killer_index = ENTINDEX(ENT(pKiller)); - - if ( pevInflictor ) - { - if ( pevInflictor == pKiller ) - { - // If the inflictor is the killer, then it must be their current weapon doing the damage - CBasePlayer *pPlayer = (CBasePlayer*)CBaseEntity::Instance( pKiller ); - - switch( pPlayer->m_iQuakeWeapon ) - { - case IT_AXE: killer_weapon_name = "weapon_axe"; break; - case IT_SHOTGUN: killer_weapon_name = "weapon_shotgun"; break; - case IT_SUPER_SHOTGUN: killer_weapon_name = "weapon_doubleshotgun"; break; - case IT_NAILGUN: killer_weapon_name = "weapon_nailgun"; break; - case IT_SUPER_NAILGUN: killer_weapon_name = "weapon_supernail"; break; - case IT_GRENADE_LAUNCHER: killer_weapon_name = "weapon_grenadel"; break; - case IT_ROCKET_LAUNCHER: killer_weapon_name = "weapon_rocketl"; break; - case IT_LIGHTNING: killer_weapon_name = "weapon_lightning"; break; - - default: - killer_weapon_name = "Empty"; - } - - } - else - { - killer_weapon_name = STRING( pevInflictor->classname ); // it's just that easy - } - } - } - else - { - killer_weapon_name = STRING( pevInflictor->classname ); - } - - // strip the monster_* or weapon_* from the inflictor's classname - if ( strncmp( killer_weapon_name, "weapon_", 7 ) == 0 ) - killer_weapon_name += 7; - else if ( strncmp( killer_weapon_name, "monster_", 8 ) == 0 ) - killer_weapon_name += 8; - else if ( strncmp( killer_weapon_name, "func_", 5 ) == 0 ) - killer_weapon_name += 5; - } - - MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); - WRITE_BYTE( killer_index ); // the killer - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim - WRITE_STRING( killer_weapon_name ); // what they were killed by (should this be a string?) - MESSAGE_END(); - - // replace the code names with the 'real' names - if ( !strcmp( killer_weapon_name, "egon" ) ) - killer_weapon_name = gluon; - else if ( !strcmp( killer_weapon_name, "gauss" ) ) - killer_weapon_name = tau; - - if ( pVictim->pev == pKiller ) - { - // killed self -#if !defined( THREEWAVE ) - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"%s\"\n", - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GETPLAYERUSERID( pVictim->edict() ), - killer_weapon_name ); -#else - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\"\n", - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GetTeamName( pVictim->pev->team ), - killer_weapon_name ); -#endif - } - else if ( pKiller->flags & FL_CLIENT ) - { -#if !defined( THREEWAVE ) - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" killed \"%s<%i><%s><%i>\" with \"%s\"\n", - STRING( pKiller->netname ), - GETPLAYERUSERID( ENT(pKiller) ), - GETPLAYERAUTHID( ENT(pKiller) ), - GETPLAYERUSERID( ENT(pKiller) ), - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GETPLAYERUSERID( pVictim->edict() ), - killer_weapon_name ); -#else - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" killed \"%s<%i><%s><%s>\" with \"%s\"\n", - STRING( pKiller->netname ), - GETPLAYERUSERID( ENT(pKiller) ), - GETPLAYERAUTHID( ENT(pKiller) ), - GetTeamName( pKiller->team ), - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GetTeamName( pVictim->pev->team ), - killer_weapon_name ); -#endif - } - else - { - // killed by the world -#if !defined( THREEWAVE ) - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"%s\" (world)\n", - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GETPLAYERUSERID( pVictim->edict() ), - killer_weapon_name ); -#else - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" committed suicide with \"%s\" (world)\n", - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GetTeamName( pVictim->pev->team ), - killer_weapon_name ); -#endif - } - - g_szDeathType = NULL; - - // HLTV event msg - MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR ); - WRITE_BYTE ( 9 ); // command length in bytes - WRITE_BYTE ( DRC_CMD_EVENT ); // player killed - WRITE_SHORT( ENTINDEX(pVictim->edict()) ); // index number of primary entity - if (pevInflictor) - WRITE_SHORT( ENTINDEX(ENT(pevInflictor)) ); // index number of secondary entity - else - WRITE_SHORT( ENTINDEX(ENT(pKiller)) ); // index number of secondary entity - WRITE_LONG( 7 | DRC_FLAG_DRAMATIC); // eventflags (priority and flags) - MESSAGE_END(); - -// Print a standard message - // TODO: make this go direct to console - return; // just remove for now - -} - -//========================================================= -// PlayerGotWeapon - player has grabbed a weapon that was -// sitting in the world -//========================================================= -void CHalfLifeMultiplay :: PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ -} - -//========================================================= -// FlWeaponRespawnTime - what is the time in the future -// at which this weapon may spawn? -//========================================================= -float CHalfLifeMultiplay :: FlWeaponRespawnTime( CBasePlayerItem *pWeapon ) -{ - if ( CVAR_GET_FLOAT("mp_weaponstay") > 0 ) - { - // make sure it's only certain weapons - if ( !(pWeapon->iFlags() & ITEM_FLAG_LIMITINWORLD) ) - { - return gpGlobals->time + 0; // weapon respawns almost instantly - } - } - - return gpGlobals->time + WEAPON_RESPAWN_TIME; -} - -// when we are within this close to running out of entities, items -// marked with the ITEM_FLAG_LIMITINWORLD will delay their respawn -#define ENTITY_INTOLERANCE 100 - -//========================================================= -// FlWeaponRespawnTime - Returns 0 if the weapon can respawn -// now, otherwise it returns the time at which it can try -// to spawn again. -//========================================================= -float CHalfLifeMultiplay :: FlWeaponTryRespawn( CBasePlayerItem *pWeapon ) -{ - if ( pWeapon && pWeapon->m_iId && (pWeapon->iFlags() & ITEM_FLAG_LIMITINWORLD) ) - { - if ( NUMBER_OF_ENTITIES() < (gpGlobals->maxEntities - ENTITY_INTOLERANCE) ) - return 0; - - // we're past the entity tolerance level, so delay the respawn - return FlWeaponRespawnTime( pWeapon ); - } - - return 0; -} - -//========================================================= -// VecWeaponRespawnSpot - where should this weapon spawn? -// Some game variations may choose to randomize spawn locations -//========================================================= -Vector CHalfLifeMultiplay :: VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ) -{ - return pWeapon->pev->origin; -} - -//========================================================= -// WeaponShouldRespawn - any conditions inhibiting the -// respawning of this weapon? -//========================================================= -int CHalfLifeMultiplay :: WeaponShouldRespawn( CBasePlayerItem *pWeapon ) -{ - if ( pWeapon->pev->spawnflags & SF_NORESPAWN ) - { - return GR_WEAPON_RESPAWN_NO; - } - - return GR_WEAPON_RESPAWN_YES; -} - -//========================================================= -// CanHaveWeapon - returns FALSE if the player is not allowed -// to pick up this weapon -//========================================================= -BOOL CHalfLifeMultiplay::CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pItem ) -{ - if ( CVAR_GET_FLOAT("mp_weaponstay") > 0 ) - { - if ( pItem->iFlags() & ITEM_FLAG_LIMITINWORLD ) - return CGameRules::CanHavePlayerItem( pPlayer, pItem ); - - // check if the player already has this weapon - for ( int i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - CBasePlayerItem *it = pPlayer->m_rgpPlayerItems[i]; - - while ( it != NULL ) - { - if ( it->m_iId == pItem->m_iId ) - { - return FALSE; - } - - it = it->m_pNext; - } - } - } - - return CGameRules::CanHavePlayerItem( pPlayer, pItem ); -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay::PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ) -{ -} - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::ItemShouldRespawn( CItem *pItem ) -{ - if ( pItem->pev->spawnflags & SF_NORESPAWN ) - { - return GR_ITEM_RESPAWN_NO; - } - - return GR_ITEM_RESPAWN_YES; -} - - -//========================================================= -// At what time in the future may this Item respawn? -//========================================================= -float CHalfLifeMultiplay::FlItemRespawnTime( CItem *pItem ) -{ - return gpGlobals->time + ITEM_RESPAWN_TIME; -} - -//========================================================= -// Where should this item respawn? -// Some game variations may choose to randomize spawn locations -//========================================================= -Vector CHalfLifeMultiplay::VecItemRespawnSpot( CItem *pItem ) -{ - return pItem->pev->origin; -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay::PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ) -{ -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::IsAllowedToSpawn( CBaseEntity *pEntity ) -{ -// if ( pEntity->pev->flags & FL_MONSTER ) -// return FALSE; - - return TRUE; -} - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ) -{ - if ( pAmmo->pev->spawnflags & SF_NORESPAWN ) - { - return GR_AMMO_RESPAWN_NO; - } - - return GR_AMMO_RESPAWN_YES; -} - -//========================================================= -//========================================================= -float CHalfLifeMultiplay::FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ) -{ - return gpGlobals->time + AMMO_RESPAWN_TIME; -} - -//========================================================= -//========================================================= -Vector CHalfLifeMultiplay::VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ) -{ - return pAmmo->pev->origin; -} - -//========================================================= -//========================================================= -float CHalfLifeMultiplay::FlHealthChargerRechargeTime( void ) -{ - return 60; -} - - -float CHalfLifeMultiplay::FlHEVChargerRechargeTime( void ) -{ - return 30; -} - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::DeadPlayerWeapons( CBasePlayer *pPlayer ) -{ - return GR_PLR_DROP_GUN_ACTIVE; -} - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::DeadPlayerAmmo( CBasePlayer *pPlayer ) -{ - return GR_PLR_DROP_AMMO_ACTIVE; -} - -edict_t *CHalfLifeMultiplay::GetPlayerSpawnSpot( CBasePlayer *pPlayer ) -{ - edict_t *pentSpawnSpot = CGameRules::GetPlayerSpawnSpot( pPlayer ); - if ( IsMultiplayer() && pentSpawnSpot->v.target ) - { - FireTargets( STRING(pentSpawnSpot->v.target), pPlayer, pPlayer, USE_TOGGLE, 0 ); - } - - return pentSpawnSpot; -} - - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) -{ - // half life deathmatch has only enemies - return GR_NOTTEAMMATE; -} - -BOOL CHalfLifeMultiplay :: PlayFootstepSounds( CBasePlayer *pl, float fvol ) -{ - return FALSE; - - if ( g_footsteps && g_footsteps->value == 0 ) - return FALSE; - - if ( pl->IsOnLadder() || pl->pev->velocity.Length2D() > 220 ) - return TRUE; // only make step sounds in multiplayer if the player is moving fast enough - - return FALSE; -} - -BOOL CHalfLifeMultiplay :: FAllowFlashlight( void ) -{ - return CVAR_GET_FLOAT( "mp_flashlight" ) != 0; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay :: FAllowMonsters( void ) -{ - return ( CVAR_GET_FLOAT( "mp_allowmonsters" ) != 0 ); -} - -//========================================================= -//======== CHalfLifeMultiplay private functions =========== - -void CHalfLifeMultiplay :: GoToIntermission( void ) -{ - if ( g_fGameOver ) - return; // intermission has already been triggered, so ignore. - - MESSAGE_BEGIN(MSG_ALL, SVC_INTERMISSION); - MESSAGE_END(); - - // bounds check - int time = (int)CVAR_GET_FLOAT( "mp_chattime" ); - if ( time < 1 ) - CVAR_SET_STRING( "mp_chattime", "1" ); - else if ( time > INTERMISSION_TIME ) - CVAR_SET_STRING( "mp_chattime", UTIL_dtos1( INTERMISSION_TIME ) ); - - m_flIntermissionEndTime = gpGlobals->time + ( (int)mp_chattime.value ); - m_flIntermissionStartTime = gpGlobals->time; - - g_fGameOver = TRUE; - m_iEndIntermissionButtonHit = FALSE; -} - -#define MAX_RULE_BUFFER 1024 - -typedef struct mapcycle_item_s -{ - struct mapcycle_item_s *next; - - char mapname[ 32 ]; - int minplayers, maxplayers; - char rulebuffer[ MAX_RULE_BUFFER ]; -} mapcycle_item_t; - -typedef struct mapcycle_s -{ - struct mapcycle_item_s *items; - struct mapcycle_item_s *next_item; -} mapcycle_t; - -/* -============== -DestroyMapCycle - -Clean up memory used by mapcycle when switching it -============== -*/ -void DestroyMapCycle( mapcycle_t *cycle ) -{ - mapcycle_item_t *p, *n, *start; - p = cycle->items; - if ( p ) - { - start = p; - p = p->next; - while ( p != start ) - { - n = p->next; - delete p; - p = n; - } - - delete cycle->items; - } - cycle->items = NULL; - cycle->next_item = NULL; -} - -static char com_token[ 1500 ]; - -/* -============== -COM_Parse - -Parse a token out of a string -============== -*/ -char *COM_Parse (char *data) -{ - int c; - int len; - - len = 0; - com_token[0] = 0; - - if (!data) - return NULL; - -// skip whitespace -skipwhite: - while ( (c = *data) <= ' ') - { - if (c == 0) - return NULL; // end of file; - data++; - } - -// skip // comments - if (c=='/' && data[1] == '/') - { - while (*data && *data != '\n') - data++; - goto skipwhite; - } - - -// handle quoted strings specially - if (c == '\"') - { - data++; - while (1) - { - c = *data++; - if (c=='\"' || !c) - { - com_token[len] = 0; - return data; - } - com_token[len] = c; - len++; - } - } - -// parse single characters - if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' ) - { - com_token[len] = c; - len++; - com_token[len] = 0; - return data+1; - } - -// parse a regular word - do - { - com_token[len] = c; - data++; - len++; - c = *data; - if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' ) - break; - } while (c>32); - - com_token[len] = 0; - return data; -} - -/* -============== -COM_TokenWaiting - -Returns 1 if additional data is waiting to be processed on this line -============== -*/ -int COM_TokenWaiting( char *buffer ) -{ - char *p; - - p = buffer; - while ( *p && *p!='\n') - { - if ( !isspace( *p ) || isalnum( *p ) ) - return 1; - - p++; - } - - return 0; -} - -/* -============== -ReloadMapCycleFile - -Parses mapcycle.txt file into mapcycle_t structure -============== -*/ -int ReloadMapCycleFile( char *filename, mapcycle_t *cycle ) -{ - char szBuffer[ MAX_RULE_BUFFER ]; - char szMap[ 32 ]; - int length; - char *pFileList; - char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( filename, &length ); - int hasbuffer; - mapcycle_item_s *item, *newlist = NULL, *next; - - if ( pFileList && length ) - { - // the first map name in the file becomes the default - while ( 1 ) - { - hasbuffer = 0; - memset( szBuffer, 0, MAX_RULE_BUFFER ); - - - pFileList = COM_Parse( pFileList ); - if ( strlen( com_token ) <= 0 ) - - - break; - - strcpy( szMap, com_token ); - - // Any more tokens on this line? - if ( COM_TokenWaiting( pFileList ) ) - { - pFileList = COM_Parse( pFileList ); - if ( strlen( com_token ) > 0 ) - { - hasbuffer = 1; - strcpy( szBuffer, com_token ); - } - } - - // Check map - if ( IS_MAP_VALID( szMap ) ) - { - // Create entry - char *s; - - item = new mapcycle_item_s; - - strcpy( item->mapname, szMap ); - - item->minplayers = 0; - item->maxplayers = 0; - - memset( item->rulebuffer, 0, MAX_RULE_BUFFER ); - - if ( hasbuffer ) - { - s = g_engfuncs.pfnInfoKeyValue( szBuffer, "minplayers" ); - if ( s && s[0] ) - { - item->minplayers = atoi( s ); - item->minplayers = V_max( item->minplayers, 0 ); - item->minplayers = V_min( item->minplayers, gpGlobals->maxClients ); - } - s = g_engfuncs.pfnInfoKeyValue( szBuffer, "maxplayers" ); - if ( s && s[0] ) - { - item->maxplayers = atoi( s ); - item->maxplayers = V_max( item->maxplayers, 0 ); - item->maxplayers = V_min( item->maxplayers, gpGlobals->maxClients ); - } - - // Remove keys - // - g_engfuncs.pfnInfo_RemoveKey( szBuffer, "minplayers" ); - g_engfuncs.pfnInfo_RemoveKey( szBuffer, "maxplayers" ); - - strcpy( item->rulebuffer, szBuffer ); - } - - item->next = cycle->items; - cycle->items = item; - } - else - { - ALERT( at_console, "Skipping %s from mapcycle, not a valid map\n", szMap ); - } - - - } - - FREE_FILE( aFileList ); - } - - // Fixup circular list pointer - item = cycle->items; - - // Reverse it to get original order - while ( item ) - { - next = item->next; - item->next = newlist; - newlist = item; - item = next; - } - cycle->items = newlist; - item = cycle->items; - - // Didn't parse anything - if ( !item ) - { - return 0; - } - - while ( item->next ) - { - item = item->next; - } - item->next = cycle->items; - - cycle->next_item = item->next; - - return 1; -} - -/* -============== -CountPlayers - -Determine the current # of active players on the server for map cycling logic -============== -*/ -int CountPlayers( void ) -{ - int num = 0; - - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pEnt = UTIL_PlayerByIndex( i ); - - if ( pEnt ) - { - num = num + 1; - } - } - - return num; -} - -/* -============== -ExtractCommandString - -Parse commands/key value pairs to issue right after map xxx command is issued on server - level transition -============== -*/ -void ExtractCommandString( char *s, char *szCommand ) -{ - // Now make rules happen - char pkey[512]; - char value[512]; // use two buffers so compares - // work without stomping on each other - char *o; - - if ( *s == '\\' ) - s++; - - while (1) - { - o = pkey; - while ( *s != '\\' ) - { - if ( !*s ) - return; - *o++ = *s++; - } - *o = 0; - s++; - - o = value; - - while (*s != '\\' && *s) - { - if (!*s) - return; - *o++ = *s++; - } - *o = 0; - - strcat( szCommand, pkey ); - if ( strlen( value ) > 0 ) - { - strcat( szCommand, " " ); - strcat( szCommand, value ); - } - strcat( szCommand, "\n" ); - - if (!*s) - return; - s++; - } -} - -/* -============== -ChangeLevel - -Server is changing to a new level, check mapcycle.txt for map name and setup info -============== -*/ -void CHalfLifeMultiplay :: ChangeLevel( void ) -{ - static char szPreviousMapCycleFile[ 256 ]; - static mapcycle_t mapcycle; - - char szNextMap[32]; - char szFirstMapInList[32]; - char szCommands[ 1500 ]; - char szRules[ 1500 ]; - int minplayers = 0, maxplayers = 0; - strcpy( szFirstMapInList, "hldm1" ); // the absolute default level is hldm1 - - int curplayers; - BOOL do_cycle = TRUE; - - // find the map to change to - char *mapcfile = (char*)CVAR_GET_STRING( "mapcyclefile" ); - ASSERT( mapcfile != NULL ); - - szCommands[ 0 ] = '\0'; - szRules[ 0 ] = '\0'; - - curplayers = CountPlayers(); - - // Has the map cycle filename changed? - if ( stricmp( mapcfile, szPreviousMapCycleFile ) ) - { - strcpy( szPreviousMapCycleFile, mapcfile ); - - DestroyMapCycle( &mapcycle ); - - if ( !ReloadMapCycleFile( mapcfile, &mapcycle ) || ( !mapcycle.items ) ) - { - ALERT( at_console, "Unable to load map cycle file %s\n", mapcfile ); - do_cycle = FALSE; - } - } - - if ( do_cycle && mapcycle.items ) - { - BOOL keeplooking = FALSE; - BOOL found = FALSE; - mapcycle_item_s *item; - - // Assume current map - strcpy( szNextMap, STRING(gpGlobals->mapname) ); - strcpy( szFirstMapInList, STRING(gpGlobals->mapname) ); - - // Traverse list - for ( item = mapcycle.next_item; item->next != mapcycle.next_item; item = item->next ) - { - keeplooking = FALSE; - - ASSERT( item != NULL ); - - if ( item->minplayers != 0 ) - { - if ( curplayers >= item->minplayers ) - { - found = TRUE; - minplayers = item->minplayers; - } - else - { - keeplooking = TRUE; - } - } - - if ( item->maxplayers != 0 ) - { - if ( curplayers <= item->maxplayers ) - { - found = TRUE; - maxplayers = item->maxplayers; - } - else - { - keeplooking = TRUE; - } - } - - if ( keeplooking ) - continue; - - found = TRUE; - break; - } - - if ( !found ) - { - item = mapcycle.next_item; - } - - // Increment next item pointer - mapcycle.next_item = item->next; - - // Perform logic on current item - strcpy( szNextMap, item->mapname ); - - ExtractCommandString( item->rulebuffer, szCommands ); - strcpy( szRules, item->rulebuffer ); - } - - if ( !IS_MAP_VALID(szNextMap) ) - { - strcpy( szNextMap, szFirstMapInList ); - } - - g_fGameOver = TRUE; - - ALERT( at_console, "CHANGE LEVEL: %s\n", szNextMap ); - if ( minplayers || maxplayers ) - { - ALERT( at_console, "PLAYER COUNT: min %i max %i current %i\n", minplayers, maxplayers, curplayers ); - } - if ( strlen( szRules ) > 0 ) - { - ALERT( at_console, "RULES: %s\n", szRules ); - } - - CHANGE_LEVEL( szNextMap, NULL ); - if ( strlen( szCommands ) > 0 ) - { - SERVER_COMMAND( szCommands ); - } -} - -#define MAX_MOTD_CHUNK 60 -#define MAX_MOTD_LENGTH (MAX_MOTD_CHUNK * 4) - -void CHalfLifeMultiplay :: SendMOTDToClient( edict_t *client ) -{ - // read from the MOTD.txt file - int length, char_count = 0; - char *pFileList; - char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( "motd.txt", &length ); - - // send the server name - MESSAGE_BEGIN( MSG_ONE, gmsgServerName, NULL, client ); - WRITE_STRING( CVAR_GET_STRING("hostname") ); - MESSAGE_END(); - - // Send the message of the day - // read it chunk-by-chunk, and send it in parts - - while ( pFileList && *pFileList && char_count < MAX_MOTD_LENGTH ) - { - char chunk[MAX_MOTD_CHUNK+1]; - - if ( strlen( pFileList ) < MAX_MOTD_CHUNK ) - { - strcpy( chunk, pFileList ); - } - else - { - strncpy( chunk, pFileList, MAX_MOTD_CHUNK ); - chunk[MAX_MOTD_CHUNK] = 0; // strncpy doesn't always append the null terminator - } - - char_count += strlen( chunk ); - if ( char_count < MAX_MOTD_LENGTH ) - pFileList = aFileList + char_count; - else - *pFileList = 0; - - MESSAGE_BEGIN( MSG_ONE, gmsgMOTD, NULL, client ); - WRITE_BYTE( *pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come - WRITE_STRING( chunk ); - MESSAGE_END(); - } - - FREE_FILE( aFileList ); -} - - diff --git a/dmc/dlls/nodes.cpp b/dmc/dlls/nodes.cpp deleted file mode 100644 index 7825c8a..0000000 --- a/dmc/dlls/nodes.cpp +++ /dev/null @@ -1,3654 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -//========================================================= -// nodes.cpp - AI node tree stuff. -//========================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "nodes.h" -#include "animation.h" -#include "doors.h" - -#ifndef _WIN32 -#include -#include -#include -#define CreateDirectory(p, n) mkdir(p, 0777) -#endif // _WIN32 - -#define HULL_STEP_SIZE 16// how far the test hull moves on each step -#define NODE_HEIGHT 8 // how high to lift nodes off the ground after we drop them all (make stair/ramp mapping easier) - -// to help eliminate node clutter by level designers, this is used to cap how many other nodes -// any given node is allowed to 'see' in the first stage of graph creation "LinkVisibleNodes()". -#define MAX_NODE_INITIAL_LINKS 128 -#define MAX_NODES 1024 - -extern DLL_GLOBAL edict_t *g_pBodyQueueHead; - -Vector VecBModelOrigin( entvars_t* pevBModel ); - -CGraph WorldGraph; - -LINK_ENTITY_TO_CLASS( info_node, CNodeEnt ); -LINK_ENTITY_TO_CLASS( info_node_air, CNodeEnt ); - -//========================================================= -// CGraph - InitGraph - prepares the graph for use. Frees any -// memory currently in use by the world graph, NULLs -// all pointers, and zeros the node count. -//========================================================= -void CGraph :: InitGraph( void) -{ - - // Make the graph unavailable - // - m_fGraphPresent = FALSE; - m_fGraphPointersSet = FALSE; - m_fRoutingComplete = FALSE; - - // Free the link pool - // - if ( m_pLinkPool ) - { - free ( m_pLinkPool ); - m_pLinkPool = NULL; - } - - // Free the node info - // - if ( m_pNodes ) - { - free ( m_pNodes ); - m_pNodes = NULL; - } - - if ( m_di ) - { - free ( m_di ); - m_di = NULL; - } - - // Free the routing info. - // - if ( m_pRouteInfo ) - { - free ( m_pRouteInfo ); - m_pRouteInfo = NULL; - } - - if (m_pHashLinks) - { - free(m_pHashLinks); - m_pHashLinks = NULL; - } - - // Zero node and link counts - // - m_cNodes = 0; - m_cLinks = 0; - m_nRouteInfo = 0; - - m_iLastActiveIdleSearch = 0; - m_iLastCoverSearch = 0; -} - -//========================================================= -// CGraph - AllocNodes - temporary function that mallocs a -// reasonable number of nodes so we can build the path which -// will be saved to disk. -//========================================================= -int CGraph :: AllocNodes ( void ) -{ -// malloc all of the nodes - WorldGraph.m_pNodes = (CNode *)calloc ( sizeof ( CNode ), MAX_NODES ); - -// could not malloc space for all the nodes! - if ( !WorldGraph.m_pNodes ) - { - ALERT ( at_aiconsole, "**ERROR**\nCouldn't malloc %d nodes!\n", WorldGraph.m_cNodes ); - return FALSE; - } - - return TRUE; -} - -//========================================================= -// CGraph - LinkEntForLink - sometimes the ent that blocks -// a path is a usable door, in which case the monster just -// needs to face the door and fire it. In other cases, the -// monster needs to operate a button or lever to get the -// door to open. This function will return a pointer to the -// button if the monster needs to hit a button to open the -// door, or returns a pointer to the door if the monster -// need only use the door. -// -// pNode is the node the monster will be standing on when it -// will need to stop and trigger the ent. -//========================================================= -entvars_t* CGraph :: LinkEntForLink ( CLink *pLink, CNode *pNode ) -{ - edict_t *pentSearch; - edict_t *pentTrigger; - entvars_t *pevTrigger; - entvars_t *pevLinkEnt; - TraceResult tr; - - pevLinkEnt = pLink->m_pLinkEnt; - if ( !pevLinkEnt ) - return NULL; - - pentSearch = NULL;// start search at the top of the ent list. - - if ( FClassnameIs ( pevLinkEnt, "func_door" ) || FClassnameIs ( pevLinkEnt, "func_door_rotating" ) ) - { - - ///!!!UNDONE - check for TOGGLE or STAY open doors here. If a door is in the way, and is - // TOGGLE or STAY OPEN, even monsters that can't open doors can go that way. - - if ( ( pevLinkEnt->spawnflags & SF_DOOR_USE_ONLY ) ) - {// door is use only, so the door is all the monster has to worry about - return pevLinkEnt; - } - - while ( 1 ) - { - pentTrigger = FIND_ENTITY_BY_TARGET ( pentSearch, STRING( pevLinkEnt->targetname ) );// find the button or trigger - - if ( FNullEnt( pentTrigger ) ) - {// no trigger found - - // right now this is a problem among auto-open doors, or any door that opens through the use - // of a trigger brush. Trigger brushes have no models, and don't show up in searches. Just allow - // monsters to open these sorts of doors for now. - return pevLinkEnt; - } - - pentSearch = pentTrigger; - pevTrigger = VARS( pentTrigger ); - - if ( FClassnameIs(pevTrigger, "func_button") || FClassnameIs(pevTrigger, "func_rot_button" ) ) - {// only buttons are handled right now. - - // trace from the node to the trigger, make sure it's one we can see from the node. - // !!!HACKHACK Use bodyqueue here cause there are no ents we really wish to ignore! - UTIL_TraceLine ( pNode->m_vecOrigin, VecBModelOrigin( pevTrigger ), ignore_monsters, g_pBodyQueueHead, &tr ); - - - if ( VARS(tr.pHit) == pevTrigger ) - {// good to go! - return VARS( tr.pHit ); - } - } - } - } - else - { - ALERT ( at_aiconsole, "Unsupported PathEnt:\n'%s'\n", STRING ( pevLinkEnt->classname ) ); - return NULL; - } -} - -//========================================================= -// CGraph - HandleLinkEnt - a brush ent is between two -// nodes that would otherwise be able to see each other. -// Given the monster's capability, determine whether -// or not the monster can go this way. -//========================================================= -int CGraph :: HandleLinkEnt ( int iNode, entvars_t *pevLinkEnt, int afCapMask, NODEQUERY queryType ) -{ - edict_t *pentWorld; - CBaseEntity *pDoor; - TraceResult tr; - - if ( !m_fGraphPresent || !m_fGraphPointersSet ) - {// protect us in the case that the node graph isn't available - ALERT ( at_aiconsole, "Graph not ready!\n" ); - return FALSE; - } - - if ( FNullEnt ( pevLinkEnt ) ) - { - ALERT ( at_aiconsole, "dead path ent!\n" ); - return TRUE; - } - pentWorld = NULL; - -// func_door - if ( FClassnameIs( pevLinkEnt, "func_door" ) || FClassnameIs( pevLinkEnt, "func_door_rotating" ) ) - {// ent is a door. - - pDoor = ( CBaseEntity::Instance( pevLinkEnt ) ); - - if ( ( pevLinkEnt->spawnflags & SF_DOOR_USE_ONLY ) ) - {// door is use only. - - if ( ( afCapMask & bits_CAP_OPEN_DOORS ) ) - {// let monster right through if he can open doors - return TRUE; - } - else - { - // monster should try for it if the door is open and looks as if it will stay that way - if ( pDoor->GetToggleState()== TS_AT_TOP && ( pevLinkEnt->spawnflags & SF_DOOR_NO_AUTO_RETURN ) ) - { - return TRUE; - } - - return FALSE; - } - } - else - {// door must be opened with a button or trigger field. - - // monster should try for it if the door is open and looks as if it will stay that way - if ( pDoor->GetToggleState() == TS_AT_TOP && ( pevLinkEnt->spawnflags & SF_DOOR_NO_AUTO_RETURN ) ) - { - return TRUE; - } - if ( ( afCapMask & bits_CAP_OPEN_DOORS ) ) - { - if ( !( pevLinkEnt->spawnflags & SF_DOOR_NOMONSTERS ) || queryType == NODEGRAPH_STATIC ) - return TRUE; - } - - return FALSE; - } - } -// func_breakable - else if ( FClassnameIs( pevLinkEnt, "func_breakable" ) && queryType == NODEGRAPH_STATIC ) - { - return TRUE; - } - else - { - ALERT ( at_aiconsole, "Unhandled Ent in Path %s\n", STRING( pevLinkEnt->classname ) ); - return FALSE; - } - - return FALSE; -} - -#if 0 -//========================================================= -// FindNearestLink - finds the connection (line) nearest -// the given point. Returns FALSE if fails, or TRUE if it -// has stuffed the index into the nearest link pool connection -// into the passed int pointer, and a BOOL telling whether or -// not the point is along the line into the passed BOOL pointer. -//========================================================= -int CGraph :: FindNearestLink ( const Vector &vecTestPoint, int *piNearestLink, BOOL *pfAlongLine ) -{ - int i, j;// loops - - int iNearestLink;// index into the link pool, this is the nearest node at any time. - float flMinDist;// the distance of of the nearest case so far - float flDistToLine;// the distance of the current test case - - BOOL fCurrentAlongLine; - BOOL fSuccess; - - //float flConstant;// line constant - Vector vecSpot1, vecSpot2; - Vector2D vec2Spot1, vec2Spot2, vec2TestPoint; - Vector2D vec2Normal;// line normal - Vector2D vec2Line; - - TraceResult tr; - - iNearestLink = -1;// prepare for failure - fSuccess = FALSE; - - flMinDist = 9999;// anything will be closer than this - -// go through all of the nodes, and each node's connections - int cSkip = 0;// how many links proper pairing allowed us to skip - int cChecked = 0;// how many links were checked - - for ( i = 0 ; i < m_cNodes ; i++ ) - { - vecSpot1 = m_pNodes[ i ].m_vecOrigin; - - if ( m_pNodes[ i ].m_cNumLinks <= 0 ) - {// this shouldn't happen! - ALERT ( at_aiconsole, "**Node %d has no links\n", i ); - continue; - } - - for ( j = 0 ; j < m_pNodes[ i ].m_cNumLinks ; j++ ) - { - /* - !!!This optimization only works when the node graph consists of properly linked pairs. - if ( INodeLink ( i, j ) <= i ) - { - // since we're going through the nodes in order, don't check - // any connections whose second node is lower in the list - // than the node we're currently working with. This eliminates - // redundant checks. - cSkip++; - continue; - } - */ - - vecSpot2 = PNodeLink ( i, j )->m_vecOrigin; - - // these values need a little attention now and then, or sometimes ramps cause trouble. - if ( fabs ( vecSpot1.z - vecTestPoint.z ) > 48 && fabs ( vecSpot2.z - vecTestPoint.z ) > 48 ) - { - // if both endpoints of the line are 32 units or more above or below the monster, - // the monster won't be able to get to them, so we do a bit of trivial rejection here. - // this may change if monsters are allowed to jump down. - // - // !!!LATER: some kind of clever X/Y hashing should be used here, too - continue; - } - -// now we have two endpoints for a line segment that we've not already checked. -// since all lines that make it this far are within -/+ 32 units of the test point's -// Z Plane, we can get away with doing the point->line check in 2d. - - cChecked++; - - vec2Spot1 = vecSpot1.Make2D(); - vec2Spot2 = vecSpot2.Make2D(); - vec2TestPoint = vecTestPoint.Make2D(); - - // get the line normal. - vec2Line = ( vec2Spot1 - vec2Spot2 ).Normalize(); - vec2Normal.x = -vec2Line.y; - vec2Normal.y = vec2Line.x; - - if ( DotProduct ( vec2Line, ( vec2TestPoint - vec2Spot1 ) ) > 0 ) - {// point outside of line - flDistToLine = ( vec2TestPoint - vec2Spot1 ).Length(); - fCurrentAlongLine = FALSE; - } - else if ( DotProduct ( vec2Line, ( vec2TestPoint - vec2Spot2 ) ) < 0 ) - {// point outside of line - flDistToLine = ( vec2TestPoint - vec2Spot2 ).Length(); - fCurrentAlongLine = FALSE; - } - else - {// point inside line - flDistToLine = fabs( DotProduct ( vec2TestPoint - vec2Spot2, vec2Normal ) ); - fCurrentAlongLine = TRUE; - } - - if ( flDistToLine < flMinDist ) - {// just found a line nearer than any other so far - - UTIL_TraceLine ( vecTestPoint, SourceNode( i, j ).m_vecOrigin, ignore_monsters, g_pBodyQueueHead, &tr ); - - if ( tr.flFraction != 1.0 ) - {// crap. can't see the first node of this link, try to see the other - - UTIL_TraceLine ( vecTestPoint, DestNode( i, j ).m_vecOrigin, ignore_monsters, g_pBodyQueueHead, &tr ); - if ( tr.flFraction != 1.0 ) - {// can't use this link, cause can't see either node! - continue; - } - - } - - fSuccess = TRUE;// we know there will be something to return. - flMinDist = flDistToLine; - iNearestLink = m_pNodes [ i ].m_iFirstLink + j; - *piNearestLink = m_pNodes[ i ].m_iFirstLink + j; - *pfAlongLine = fCurrentAlongLine; - } - } - } - -/* - if ( fSuccess ) - { - WRITE_BYTE(MSG_BROADCAST, SVC_TEMPENTITY); - WRITE_BYTE(MSG_BROADCAST, TE_SHOWLINE); - - WRITE_COORD(MSG_BROADCAST, m_pNodes[ m_pLinkPool[ iNearestLink ].m_iSrcNode ].m_vecOrigin.x ); - WRITE_COORD(MSG_BROADCAST, m_pNodes[ m_pLinkPool[ iNearestLink ].m_iSrcNode ].m_vecOrigin.y ); - WRITE_COORD(MSG_BROADCAST, m_pNodes[ m_pLinkPool[ iNearestLink ].m_iSrcNode ].m_vecOrigin.z + NODE_HEIGHT); - - WRITE_COORD(MSG_BROADCAST, m_pNodes[ m_pLinkPool[ iNearestLink ].m_iDestNode ].m_vecOrigin.x ); - WRITE_COORD(MSG_BROADCAST, m_pNodes[ m_pLinkPool[ iNearestLink ].m_iDestNode ].m_vecOrigin.y ); - WRITE_COORD(MSG_BROADCAST, m_pNodes[ m_pLinkPool[ iNearestLink ].m_iDestNode ].m_vecOrigin.z + NODE_HEIGHT); - } -*/ - - ALERT ( at_aiconsole, "%d Checked\n", cChecked ); - return fSuccess; -} - -#endif - -int CGraph::HullIndex( const CBaseEntity *pEntity ) -{ - if ( pEntity->pev->movetype == MOVETYPE_FLY) - return NODE_FLY_HULL; - - if ( pEntity->pev->mins == Vector( -12, -12, 0 ) ) - return NODE_SMALL_HULL; - else if ( pEntity->pev->mins == VEC_HUMAN_HULL_MIN ) - return NODE_HUMAN_HULL; - else if ( pEntity->pev->mins == Vector ( -32, -32, 0 ) ) - return NODE_LARGE_HULL; - -// ALERT ( at_aiconsole, "Unknown Hull Mins!\n" ); - return NODE_HUMAN_HULL; -} - - -int CGraph::NodeType( const CBaseEntity *pEntity ) -{ - if ( pEntity->pev->movetype == MOVETYPE_FLY) - { - if (pEntity->pev->waterlevel != 0) - { - return bits_NODE_WATER; - } - else - { - return bits_NODE_AIR; - } - } - return bits_NODE_LAND; -} - - -// Sum up graph weights on the path from iStart to iDest to determine path length -float CGraph::PathLength( int iStart, int iDest, int iHull, int afCapMask ) -{ - float distance = 0; - int iNext; - - int iMaxLoop = m_cNodes; - - int iCurrentNode = iStart; - int iCap = CapIndex( afCapMask ); - - while (iCurrentNode != iDest) - { - if (iMaxLoop-- <= 0) - { - ALERT( at_console, "Route Failure\n" ); - return 0; - } - - iNext = NextNodeInRoute( iCurrentNode, iDest, iHull, iCap ); - if (iCurrentNode == iNext) - { - //ALERT(at_aiconsole, "SVD: Can't get there from here..\n"); - return 0; - } - - int iLink; - HashSearch(iCurrentNode, iNext, iLink); - if (iLink < 0) - { - ALERT(at_console, "HashLinks is broken from %d to %d.\n", iCurrentNode, iDest); - return 0; - } - CLink &link = Link(iLink); - distance += link.m_flWeight; - - iCurrentNode = iNext; - } - - return distance; -} - - -// Parse the routing table at iCurrentNode for the next node on the shortest path to iDest -int CGraph::NextNodeInRoute( int iCurrentNode, int iDest, int iHull, int iCap ) -{ - int iNext = iCurrentNode; - int nCount = iDest+1; - char *pRoute = m_pRouteInfo + m_pNodes[ iCurrentNode ].m_pNextBestNode[iHull][iCap]; - - // Until we decode the next best node - // - while (nCount > 0) - { - char ch = *pRoute++; - //ALERT(at_aiconsole, "C(%d)", ch); - if (ch < 0) - { - // Sequence phrase - // - ch = -ch; - if (nCount <= ch) - { - iNext = iDest; - nCount = 0; - //ALERT(at_aiconsole, "SEQ: iNext/iDest=%d\n", iNext); - } - else - { - //ALERT(at_aiconsole, "SEQ: nCount + ch (%d + %d)\n", nCount, ch); - nCount = nCount - ch; - } - } - else - { - //ALERT(at_aiconsole, "C(%d)", *pRoute); - - // Repeat phrase - // - if (nCount <= ch+1) - { - iNext = iCurrentNode + *pRoute; - if (iNext >= m_cNodes) iNext -= m_cNodes; - else if (iNext < 0) iNext += m_cNodes; - nCount = 0; - //ALERT(at_aiconsole, "REP: iNext=%d\n", iNext); - } - else - { - //ALERT(at_aiconsole, "REP: nCount - ch+1 (%d - %d+1)\n", nCount, ch); - nCount = nCount - ch - 1; - } - pRoute++; - } - } - - return iNext; -} - - -//========================================================= -// CGraph - FindShortestPath -// -// accepts a capability mask (afCapMask), and will only -// find a path usable by a monster with those capabilities -// returns the number of nodes copied into supplied array -//========================================================= -int CGraph :: FindShortestPath ( int *piPath, int iStart, int iDest, int iHull, int afCapMask) -{ - int iVisitNode; - int iCurrentNode; - int iNumPathNodes; - int iHullMask; - - if ( !m_fGraphPresent || !m_fGraphPointersSet ) - {// protect us in the case that the node graph isn't available or built - ALERT ( at_aiconsole, "Graph not ready!\n" ); - return FALSE; - } - - if ( iStart < 0 || iStart > m_cNodes ) - {// The start node is bad? - ALERT ( at_aiconsole, "Can't build a path, iStart is %d!\n", iStart ); - return FALSE; - } - - if (iStart == iDest) - { - piPath[0] = iStart; - piPath[1] = iDest; - return 2; - } - - // Is routing information present. - // - if (m_fRoutingComplete) - { - int iCap = CapIndex( afCapMask ); - - iNumPathNodes = 0; - piPath[iNumPathNodes++] = iStart; - iCurrentNode = iStart; - int iNext; - - //ALERT(at_aiconsole, "GOAL: %d to %d\n", iStart, iDest); - - // Until we arrive at the destination - // - while (iCurrentNode != iDest) - { - iNext = NextNodeInRoute( iCurrentNode, iDest, iHull, iCap ); - if (iCurrentNode == iNext) - { - //ALERT(at_aiconsole, "SVD: Can't get there from here..\n"); - return 0; - break; - } - if (iNumPathNodes >= MAX_PATH_SIZE) - { - //ALERT(at_aiconsole, "SVD: Don't return the entire path.\n"); - break; - } - piPath[iNumPathNodes++] = iNext; - iCurrentNode = iNext; - } - //ALERT( at_aiconsole, "SVD: Path with %d nodes.\n", iNumPathNodes); - } - else - { - CQueuePriority queue; - - switch( iHull ) - { - case NODE_SMALL_HULL: - iHullMask = bits_LINK_SMALL_HULL; - break; - case NODE_HUMAN_HULL: - iHullMask = bits_LINK_HUMAN_HULL; - break; - case NODE_LARGE_HULL: - iHullMask = bits_LINK_LARGE_HULL; - break; - case NODE_FLY_HULL: - iHullMask = bits_LINK_FLY_HULL; - break; - } - - // Mark all the nodes as unvisited. - // - int i; - for ( i = 0; i < m_cNodes; i++) - { - m_pNodes[ i ].m_flClosestSoFar = -1.0; - } - - m_pNodes[ iStart ].m_flClosestSoFar = 0.0; - m_pNodes[ iStart ].m_iPreviousNode = iStart;// tag this as the origin node - queue.Insert( iStart, 0.0 );// insert start node - - while ( !queue.Empty() ) - { - // now pull a node out of the queue - float flCurrentDistance; - iCurrentNode = queue.Remove(flCurrentDistance); - - // For straight-line weights, the following Shortcut works. For arbitrary weights, - // it doesn't. - // - if (iCurrentNode == iDest) break; - - CNode *pCurrentNode = &m_pNodes[ iCurrentNode ]; - - for ( i = 0 ; i < pCurrentNode->m_cNumLinks ; i++ ) - {// run through all of this node's neighbors - - iVisitNode = INodeLink ( iCurrentNode, i ); - if ( ( m_pLinkPool[ m_pNodes[ iCurrentNode ].m_iFirstLink + i ].m_afLinkInfo & iHullMask ) != iHullMask ) - {// monster is too large to walk this connection - //ALERT ( at_aiconsole, "fat ass %d/%d\n",m_pLinkPool[ m_pNodes[ iCurrentNode ].m_iFirstLink + i ].m_afLinkInfo, iMonsterHull ); - continue; - } - // check the connection from the current node to the node we're about to mark visited and push into the queue - if ( m_pLinkPool[ m_pNodes[ iCurrentNode ].m_iFirstLink + i ].m_pLinkEnt != NULL ) - {// there's a brush ent in the way! Don't mark this node or put it into the queue unless the monster can negotiate it - - if ( !HandleLinkEnt ( iCurrentNode, m_pLinkPool[ m_pNodes[ iCurrentNode ].m_iFirstLink + i ].m_pLinkEnt, afCapMask, NODEGRAPH_STATIC ) ) - {// monster should not try to go this way. - continue; - } - } - float flOurDistance = flCurrentDistance + m_pLinkPool[ m_pNodes[ iCurrentNode ].m_iFirstLink + i].m_flWeight; - if ( m_pNodes[ iVisitNode ].m_flClosestSoFar < -0.5 - || flOurDistance < m_pNodes[ iVisitNode ].m_flClosestSoFar - 0.001 ) - { - m_pNodes[iVisitNode].m_flClosestSoFar = flOurDistance; - m_pNodes[iVisitNode].m_iPreviousNode = iCurrentNode; - - queue.Insert ( iVisitNode, flOurDistance ); - } - } - } - if ( m_pNodes[iDest].m_flClosestSoFar < -0.5 ) - {// Destination is unreachable, no path found. - return 0; - } - - // the queue is not empty - - // now we must walk backwards through the m_iPreviousNode field, and count how many connections there are in the path - iCurrentNode = iDest; - iNumPathNodes = 1;// count the dest - - while ( iCurrentNode != iStart ) - { - iNumPathNodes++; - iCurrentNode = m_pNodes[ iCurrentNode ].m_iPreviousNode; - } - - iCurrentNode = iDest; - for ( i = iNumPathNodes - 1 ; i >= 0 ; i-- ) - { - piPath[ i ] = iCurrentNode; - iCurrentNode = m_pNodes [ iCurrentNode ].m_iPreviousNode; - } - } - -#if 0 - - if (m_fRoutingComplete) - { - // This will draw the entire path that was generated for the monster. - - for ( int i = 0 ; i < iNumPathNodes - 1 ; i++ ) - { - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_SHOWLINE); - - WRITE_COORD( m_pNodes[ piPath[ i ] ].m_vecOrigin.x ); - WRITE_COORD( m_pNodes[ piPath[ i ] ].m_vecOrigin.y ); - WRITE_COORD( m_pNodes[ piPath[ i ] ].m_vecOrigin.z + NODE_HEIGHT ); - - WRITE_COORD( m_pNodes[ piPath[ i + 1 ] ].m_vecOrigin.x ); - WRITE_COORD( m_pNodes[ piPath[ i + 1 ] ].m_vecOrigin.y ); - WRITE_COORD( m_pNodes[ piPath[ i + 1 ] ].m_vecOrigin.z + NODE_HEIGHT ); - MESSAGE_END(); - } - } - -#endif -#if 0 // MAZE map - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_SHOWLINE); - - WRITE_COORD( m_pNodes[ 4 ].m_vecOrigin.x ); - WRITE_COORD( m_pNodes[ 4 ].m_vecOrigin.y ); - WRITE_COORD( m_pNodes[ 4 ].m_vecOrigin.z + NODE_HEIGHT ); - - WRITE_COORD( m_pNodes[ 9 ].m_vecOrigin.x ); - WRITE_COORD( m_pNodes[ 9 ].m_vecOrigin.y ); - WRITE_COORD( m_pNodes[ 9 ].m_vecOrigin.z + NODE_HEIGHT ); - MESSAGE_END(); -#endif - - return iNumPathNodes; -} - -inline ULONG Hash(void *p, int len) -{ - CRC32_t ulCrc; - CRC32_INIT(&ulCrc); - CRC32_PROCESS_BUFFER(&ulCrc, p, len); - return CRC32_FINAL(ulCrc); -} - -void inline CalcBounds(int &Lower, int &Upper, int Goal, int Best) -{ - int Temp = 2*Goal - Best; - if (Best > Goal) - { - Lower = V_max(0, Temp); - Upper = Best; - } - else - { - Upper = V_min(255, Temp); - Lower = Best; - } -} - -// Convert from [-8192,8192] to [0, 255] -// -inline int CALC_RANGE(int x, int lower, int upper) -{ - return NUM_RANGES*(x-lower)/((upper-lower+1)); -} - - -void inline UpdateRange(int &minValue, int &maxValue, int Goal, int Best) -{ - int Lower, Upper; - CalcBounds(Lower, Upper, Goal, Best); - if (Upper < maxValue) maxValue = Upper; - if (minValue < Lower) minValue = Lower; -} - -void CGraph :: CheckNode(Vector vecOrigin, int iNode) -{ - // Have we already seen this point before?. - // - if (m_di[iNode].m_CheckedEvent == m_CheckedCounter) return; - m_di[iNode].m_CheckedEvent = m_CheckedCounter; - - float flDist = ( vecOrigin - m_pNodes[ iNode ].m_vecOriginPeek ).Length(); - - if ( flDist < m_flShortest ) - { - TraceResult tr; - - // make sure that vecOrigin can trace to this node! - UTIL_TraceLine ( vecOrigin, m_pNodes[ iNode ].m_vecOriginPeek, ignore_monsters, 0, &tr ); - - if ( tr.flFraction == 1.0 ) - { - m_iNearest = iNode; - m_flShortest = flDist; - - UpdateRange(m_minX, m_maxX, CALC_RANGE(vecOrigin.x, m_RegionMin[0], m_RegionMax[0]), m_pNodes[iNode].m_Region[0]); - UpdateRange(m_minY, m_maxY, CALC_RANGE(vecOrigin.y, m_RegionMin[1], m_RegionMax[1]), m_pNodes[iNode].m_Region[1]); - UpdateRange(m_minZ, m_maxZ, CALC_RANGE(vecOrigin.z, m_RegionMin[2], m_RegionMax[2]), m_pNodes[iNode].m_Region[2]); - - // From maxCircle, calculate maximum bounds box. All points must be - // simultaneously inside all bounds of the box. - // - m_minBoxX = CALC_RANGE(vecOrigin.x - flDist, m_RegionMin[0], m_RegionMax[0]); - m_maxBoxX = CALC_RANGE(vecOrigin.x + flDist, m_RegionMin[0], m_RegionMax[0]); - m_minBoxY = CALC_RANGE(vecOrigin.y - flDist, m_RegionMin[1], m_RegionMax[1]); - m_maxBoxY = CALC_RANGE(vecOrigin.y + flDist, m_RegionMin[1], m_RegionMax[1]); - m_minBoxZ = CALC_RANGE(vecOrigin.z - flDist, m_RegionMin[2], m_RegionMax[2]); - m_maxBoxZ = CALC_RANGE(vecOrigin.z + flDist, m_RegionMin[2], m_RegionMax[2]); - } - } -} - -//========================================================= -// CGraph - FindNearestNode - returns the index of the node nearest -// the given vector -1 is failure (couldn't find a valid -// near node ) -//========================================================= -int CGraph :: FindNearestNode ( const Vector &vecOrigin, CBaseEntity *pEntity ) -{ - return FindNearestNode( vecOrigin, NodeType( pEntity ) ); -} - -int CGraph :: FindNearestNode ( const Vector &vecOrigin, int afNodeTypes ) -{ - int i; - TraceResult tr; - - if ( !m_fGraphPresent || !m_fGraphPointersSet ) - {// protect us in the case that the node graph isn't available - ALERT ( at_aiconsole, "Graph not ready!\n" ); - return -1; - } - - // Check with the cache - // - ULONG iHash = (CACHE_SIZE-1) & Hash((void *)(const float *)vecOrigin, sizeof(vecOrigin)); - if (m_Cache[iHash].v == vecOrigin) - { - //ALERT(at_aiconsole, "Cache Hit.\n"); - return m_Cache[iHash].n; - } - else - { - //ALERT(at_aiconsole, "Cache Miss.\n"); - } - - // Mark all points as unchecked. - // - m_CheckedCounter++; - if (m_CheckedCounter == 0) - { - for (int i = 0; i < m_cNodes; i++) - { - m_di[i].m_CheckedEvent = 0; - } - m_CheckedCounter++; - } - - m_iNearest = -1; - m_flShortest = 999999.0; // just a big number. - - // If we can find a visible point, then let CalcBounds set the limits, but if - // we have no visible point at all to start with, then don't restrict the limits. - // -#if 1 - m_minX = 0; m_maxX = 255; - m_minY = 0; m_maxY = 255; - m_minZ = 0; m_maxZ = 255; - m_minBoxX = 0; m_maxBoxX = 255; - m_minBoxY = 0; m_maxBoxY = 255; - m_minBoxZ = 0; m_maxBoxZ = 255; -#else - m_minBoxX = CALC_RANGE(vecOrigin.x - flDist, m_RegionMin[0], m_RegionMax[0]); - m_maxBoxX = CALC_RANGE(vecOrigin.x + flDist, m_RegionMin[0], m_RegionMax[0]); - m_minBoxY = CALC_RANGE(vecOrigin.y - flDist, m_RegionMin[1], m_RegionMax[1]); - m_maxBoxY = CALC_RANGE(vecOrigin.y + flDist, m_RegionMin[1], m_RegionMax[1]); - m_minBoxZ = CALC_RANGE(vecOrigin.z - flDist, m_RegionMin[2], m_RegionMax[2]); - m_maxBoxZ = CALC_RANGE(vecOrigin.z + flDist, m_RegionMin[2], m_RegionMax[2]) - CalcBounds(m_minX, m_maxX, CALC_RANGE(vecOrigin.x, m_RegionMin[0], m_RegionMax[0]), m_pNodes[m_iNearest].m_Region[0]); - CalcBounds(m_minY, m_maxY, CALC_RANGE(vecOrigin.y, m_RegionMin[1], m_RegionMax[1]), m_pNodes[m_iNearest].m_Region[1]); - CalcBounds(m_minZ, m_maxZ, CALC_RANGE(vecOrigin.z, m_RegionMin[2], m_RegionMax[2]), m_pNodes[m_iNearest].m_Region[2]); -#endif - - int halfX = (m_minX+m_maxX)/2; - int halfY = (m_minY+m_maxY)/2; - int halfZ = (m_minZ+m_maxZ)/2; - - int j; - - for (i = halfX; i >= m_minX; i--) - { - for (j = m_RangeStart[0][i]; j <= m_RangeEnd[0][i]; j++) - { - if (!(m_pNodes[m_di[j].m_SortedBy[0]].m_afNodeInfo & afNodeTypes)) continue; - - int rgY = m_pNodes[m_di[j].m_SortedBy[0]].m_Region[1]; - if (rgY > m_maxBoxY) break; - if (rgY < m_minBoxY) continue; - - int rgZ = m_pNodes[m_di[j].m_SortedBy[0]].m_Region[2]; - if (rgZ < m_minBoxZ) continue; - if (rgZ > m_maxBoxZ) continue; - CheckNode(vecOrigin, m_di[j].m_SortedBy[0]); - } - } - - for (i = V_max(m_minY,halfY+1); i <= m_maxY; i++) - { - for (j = m_RangeStart[1][i]; j <= m_RangeEnd[1][i]; j++) - { - if (!(m_pNodes[m_di[j].m_SortedBy[1]].m_afNodeInfo & afNodeTypes)) continue; - - int rgZ = m_pNodes[m_di[j].m_SortedBy[1]].m_Region[2]; - if (rgZ > m_maxBoxZ) break; - if (rgZ < m_minBoxZ) continue; - int rgX = m_pNodes[m_di[j].m_SortedBy[1]].m_Region[0]; - if (rgX < m_minBoxX) continue; - if (rgX > m_maxBoxX) continue; - CheckNode(vecOrigin, m_di[j].m_SortedBy[1]); - } - } - - for (i = V_min(m_maxZ,halfZ); i >= m_minZ; i--) - { - for (j = m_RangeStart[2][i]; j <= m_RangeEnd[2][i]; j++) - { - if (!(m_pNodes[m_di[j].m_SortedBy[2]].m_afNodeInfo & afNodeTypes)) continue; - - int rgX = m_pNodes[m_di[j].m_SortedBy[2]].m_Region[0]; - if (rgX > m_maxBoxX) break; - if (rgX < m_minBoxX) continue; - int rgY = m_pNodes[m_di[j].m_SortedBy[2]].m_Region[1]; - if (rgY < m_minBoxY) continue; - if (rgY > m_maxBoxY) continue; - CheckNode(vecOrigin, m_di[j].m_SortedBy[2]); - } - } - - for (i = V_max(m_minX,halfX+1); i <= m_maxX; i++) - { - for (j = m_RangeStart[0][i]; j <= m_RangeEnd[0][i]; j++) - { - if (!(m_pNodes[m_di[j].m_SortedBy[0]].m_afNodeInfo & afNodeTypes)) continue; - - int rgY = m_pNodes[m_di[j].m_SortedBy[0]].m_Region[1]; - if (rgY > m_maxBoxY) break; - if (rgY < m_minBoxY) continue; - - int rgZ = m_pNodes[m_di[j].m_SortedBy[0]].m_Region[2]; - if (rgZ < m_minBoxZ) continue; - if (rgZ > m_maxBoxZ) continue; - CheckNode(vecOrigin, m_di[j].m_SortedBy[0]); - } - } - - for (i = V_min(m_maxY,halfY); i >= m_minY; i--) - { - for (j = m_RangeStart[1][i]; j <= m_RangeEnd[1][i]; j++) - { - if (!(m_pNodes[m_di[j].m_SortedBy[1]].m_afNodeInfo & afNodeTypes)) continue; - - int rgZ = m_pNodes[m_di[j].m_SortedBy[1]].m_Region[2]; - if (rgZ > m_maxBoxZ) break; - if (rgZ < m_minBoxZ) continue; - int rgX = m_pNodes[m_di[j].m_SortedBy[1]].m_Region[0]; - if (rgX < m_minBoxX) continue; - if (rgX > m_maxBoxX) continue; - CheckNode(vecOrigin, m_di[j].m_SortedBy[1]); - } - } - - for (i = V_max(m_minZ,halfZ+1); i <= m_maxZ; i++) - { - for (j = m_RangeStart[2][i]; j <= m_RangeEnd[2][i]; j++) - { - if (!(m_pNodes[m_di[j].m_SortedBy[2]].m_afNodeInfo & afNodeTypes)) continue; - - int rgX = m_pNodes[m_di[j].m_SortedBy[2]].m_Region[0]; - if (rgX > m_maxBoxX) break; - if (rgX < m_minBoxX) continue; - int rgY = m_pNodes[m_di[j].m_SortedBy[2]].m_Region[1]; - if (rgY < m_minBoxY) continue; - if (rgY > m_maxBoxY) continue; - CheckNode(vecOrigin, m_di[j].m_SortedBy[2]); - } - } - -#if 0 - // Verify our answers. - // - int iNearestCheck = -1; - m_flShortest = 8192;// find nodes within this radius - - for ( i = 0 ; i < m_cNodes ; i++ ) - { - float flDist = ( vecOrigin - m_pNodes[ i ].m_vecOriginPeek ).Length(); - - if ( flDist < m_flShortest ) - { - // make sure that vecOrigin can trace to this node! - UTIL_TraceLine ( vecOrigin, m_pNodes[ i ].m_vecOriginPeek, ignore_monsters, 0, &tr ); - - if ( tr.flFraction == 1.0 ) - { - iNearestCheck = i; - m_flShortest = flDist; - } - } - } - - if (iNearestCheck != m_iNearest) - { - ALERT( at_aiconsole, "NOT closest %d(%f,%f,%f) %d(%f,%f,%f).\n", - iNearestCheck, - m_pNodes[iNearestCheck].m_vecOriginPeek.x, - m_pNodes[iNearestCheck].m_vecOriginPeek.y, - m_pNodes[iNearestCheck].m_vecOriginPeek.z, - m_iNearest, - (m_iNearest == -1?0.0:m_pNodes[m_iNearest].m_vecOriginPeek.x), - (m_iNearest == -1?0.0:m_pNodes[m_iNearest].m_vecOriginPeek.y), - (m_iNearest == -1?0.0:m_pNodes[m_iNearest].m_vecOriginPeek.z)); - } - if (m_iNearest == -1) - { - ALERT(at_aiconsole, "All that work for nothing.\n"); - } -#endif - m_Cache[iHash].v = vecOrigin; - m_Cache[iHash].n = m_iNearest; - return m_iNearest; -} - -//========================================================= -// CGraph - ShowNodeConnections - draws a line from the given node -// to all connected nodes -//========================================================= -void CGraph :: ShowNodeConnections ( int iNode ) -{ - Vector vecSpot; - CNode *pNode; - CNode *pLinkNode; - int i; - - if ( !m_fGraphPresent || !m_fGraphPointersSet ) - {// protect us in the case that the node graph isn't available or built - ALERT ( at_aiconsole, "Graph not ready!\n" ); - return; - } - - if ( iNode < 0 ) - { - ALERT( at_aiconsole, "Can't show connections for node %d\n", iNode ); - return; - } - - pNode = &m_pNodes[ iNode ]; - - UTIL_ParticleEffect( pNode->m_vecOrigin, g_vecZero, 255, 20 );// show node position - - if ( pNode->m_cNumLinks <= 0 ) - {// no connections! - ALERT ( at_aiconsole, "**No Connections!\n" ); - } - - for ( i = 0 ; i < pNode->m_cNumLinks ; i++ ) - { - - pLinkNode = &Node( NodeLink( iNode, i).m_iDestNode ); - vecSpot = pLinkNode->m_vecOrigin; - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_SHOWLINE); - - WRITE_COORD( m_pNodes[ iNode ].m_vecOrigin.x ); - WRITE_COORD( m_pNodes[ iNode ].m_vecOrigin.y ); - WRITE_COORD( m_pNodes[ iNode ].m_vecOrigin.z + NODE_HEIGHT ); - - WRITE_COORD( vecSpot.x ); - WRITE_COORD( vecSpot.y ); - WRITE_COORD( vecSpot.z + NODE_HEIGHT ); - MESSAGE_END(); - - } -} - -//========================================================= -// CGraph - LinkVisibleNodes - the first, most basic -// function of node graph creation, this connects every -// node to every other node that it can see. Expects a -// pointer to an empty connection pool and a file pointer -// to write progress to. Returns the total number of initial -// links. -// -// If there's a problem with this process, the index -// of the offending node will be written to piBadNode -//========================================================= -int CGraph :: LinkVisibleNodes ( CLink *pLinkPool, FILE *file, int *piBadNode ) -{ - int i,j,z; - edict_t *pTraceEnt; - int cTotalLinks, cLinksThisNode, cMaxInitialLinks; - TraceResult tr; - - // !!!BUGBUG - this function returns 0 if there is a problem in the middle of connecting the graph - // it also returns 0 if none of the nodes in a level can see each other. piBadNode is ALWAYS read - // by BuildNodeGraph() if this function returns a 0, so make sure that it doesn't get some random - // number back. - *piBadNode = 0; - - - if ( m_cNodes <= 0 ) - { - ALERT ( at_aiconsole, "No Nodes!\n" ); - return FALSE; - } - - // if the file pointer is bad, don't blow up, just don't write the - // file. - if ( !file ) - { - ALERT ( at_aiconsole, "**LinkVisibleNodes:\ncan't write to file." ); - } - else - { - fprintf ( file, "----------------------------------------------------------------------------\n" ); - fprintf ( file, "LinkVisibleNodes - Initial Connections\n" ); - fprintf ( file, "----------------------------------------------------------------------------\n" ); - } - - cTotalLinks = 0;// start with no connections - - // to keep track of the maximum number of initial links any node had so far. - // this lets us keep an eye on MAX_NODE_INITIAL_LINKS to ensure that we are - // being generous enough. - cMaxInitialLinks = 0; - - for ( i = 0 ; i < m_cNodes ; i++ ) - { - cLinksThisNode = 0;// reset this count for each node. - - if ( file ) - { - fprintf ( file, "Node #%4d:\n\n", i ); - } - - for ( z = 0 ; z < MAX_NODE_INITIAL_LINKS ; z++ ) - {// clear out the important fields in the link pool for this node - pLinkPool [ cTotalLinks + z ].m_iSrcNode = i;// so each link knows which node it originates from - pLinkPool [ cTotalLinks + z ].m_iDestNode = 0; - pLinkPool [ cTotalLinks + z ].m_pLinkEnt = NULL; - } - - m_pNodes [ i ].m_iFirstLink = cTotalLinks; - - // now build a list of every other node that this node can see - for ( j = 0 ; j < m_cNodes ; j++ ) - { - if ( j == i ) - {// don't connect to self! - continue; - } - -#if 0 - - if ( (m_pNodes[ i ].m_afNodeInfo & bits_NODE_WATER) != (m_pNodes[ j ].m_afNodeInfo & bits_NODE_WATER) ) - { - // don't connect water nodes to air nodes or land nodes. It just wouldn't be prudent at this juncture. - continue; - } -#else - if ( (m_pNodes[ i ].m_afNodeInfo & bits_NODE_GROUP_REALM) != (m_pNodes[ j ].m_afNodeInfo & bits_NODE_GROUP_REALM) ) - { - // don't connect air nodes to water nodes to land nodes. It just wouldn't be prudent at this juncture. - continue; - } -#endif - - tr.pHit = NULL;// clear every time so we don't get stuck with last trace's hit ent - pTraceEnt = 0; - - UTIL_TraceLine ( m_pNodes[ i ].m_vecOrigin, - m_pNodes[ j ].m_vecOrigin, - ignore_monsters, - g_pBodyQueueHead,//!!!HACKHACK no real ent to supply here, using a global we don't care about - &tr ); - - - if ( tr.fStartSolid ) - continue; - - if ( tr.flFraction != 1.0 ) - {// trace hit a brush ent, trace backwards to make sure that this ent is the only thing in the way. - - pTraceEnt = tr.pHit;// store the ent that the trace hit, for comparison - - UTIL_TraceLine ( m_pNodes[ j ].m_vecOrigin, - m_pNodes[ i ].m_vecOrigin, - ignore_monsters, - g_pBodyQueueHead,//!!!HACKHACK no real ent to supply here, using a global we don't care about - &tr ); - - -// there is a solid_bsp ent in the way of these two nodes, so we must record several things about in order to keep -// track of it in the pathfinding code, as well as through save and restore of the node graph. ANY data that is manipulated -// as part of the process of adding a LINKENT to a connection here must also be done in CGraph::SetGraphPointers, where reloaded -// graphs are prepared for use. - if ( tr.pHit == pTraceEnt && !FClassnameIs( tr.pHit, "worldspawn" ) ) - { - // get a pointer - pLinkPool [ cTotalLinks ].m_pLinkEnt = VARS( tr.pHit ); - - // record the modelname, so that we can save/load node trees - memcpy( pLinkPool [ cTotalLinks ].m_szLinkEntModelname, STRING( VARS(tr.pHit)->model ), 4 ); - - // set the flag for this ent that indicates that it is attached to the world graph - // if this ent is removed from the world, it must also be removed from the connections - // that it formerly blocked. - if ( !FBitSet( VARS( tr.pHit )->flags, FL_GRAPHED ) ) - { - VARS( tr.pHit )->flags += FL_GRAPHED; - } - } - else - {// even if the ent wasn't there, these nodes couldn't be connected. Skip. - continue; - } - } - - if ( file ) - { - fprintf ( file, "%4d", j ); - - if ( !FNullEnt( pLinkPool[ cTotalLinks ].m_pLinkEnt ) ) - {// record info about the ent in the way, if any. - fprintf ( file, " Entity on connection: %s, name: %s Model: %s", STRING( VARS( pTraceEnt )->classname ), STRING ( VARS( pTraceEnt )->targetname ), STRING ( VARS(tr.pHit)->model ) ); - } - - fprintf ( file, "\n" ); - } - - pLinkPool [ cTotalLinks ].m_iDestNode = j; - cLinksThisNode++; - cTotalLinks++; - - // If we hit this, either a level designer is placing too many nodes in the same area, or - // we need to allow for a larger initial link pool. - if ( cLinksThisNode == MAX_NODE_INITIAL_LINKS ) - { - ALERT ( at_aiconsole, "**LinkVisibleNodes:\nNode %d has NodeLinks > MAX_NODE_INITIAL_LINKS", i ); - fprintf ( file, "** NODE %d HAS NodeLinks > MAX_NODE_INITIAL_LINKS **\n", i ); - *piBadNode = i; - return FALSE; - } - else if ( cTotalLinks > MAX_NODE_INITIAL_LINKS * m_cNodes ) - {// this is paranoia - ALERT ( at_aiconsole, "**LinkVisibleNodes:\nTotalLinks > MAX_NODE_INITIAL_LINKS * NUMNODES" ); - *piBadNode = i; - return FALSE; - } - - if ( cLinksThisNode == 0 ) - { - fprintf ( file, "**NO INITIAL LINKS**\n" ); - } - - // record the connection info in the link pool - WorldGraph.m_pNodes [ i ].m_cNumLinks = cLinksThisNode; - - // keep track of the most initial links ANY node had, so we can figure out - // if we have a large enough default link pool - if ( cLinksThisNode > cMaxInitialLinks ) - { - cMaxInitialLinks = cLinksThisNode; - } - } - - - if ( file ) - { - fprintf ( file, "----------------------------------------------------------------------------\n" ); - } - } - - fprintf ( file, "\n%4d Total Initial Connections - %4d Maximum connections for a single node.\n", cTotalLinks, cMaxInitialLinks ); - fprintf ( file, "----------------------------------------------------------------------------\n\n\n" ); - - return cTotalLinks; -} - -//========================================================= -// CGraph - RejectInlineLinks - expects a pointer to a link -// pool, and a pointer to and already-open file ( if you -// want status reports written to disk ). RETURNS the number -// of connections that were rejected -//========================================================= -int CGraph :: RejectInlineLinks ( CLink *pLinkPool, FILE *file ) -{ - int i,j,k; - - int cRejectedLinks; - - BOOL fRestartLoop;// have to restart the J loop if we eliminate a link. - - CNode *pSrcNode; - CNode *pCheckNode;// the node we are testing for (one of pSrcNode's connections) - CNode *pTestNode;// the node we are checking against ( also one of pSrcNode's connections) - - float flDistToTestNode, flDistToCheckNode; - - Vector2D vec2DirToTestNode, vec2DirToCheckNode; - - if ( file ) - { - fprintf ( file, "----------------------------------------------------------------------------\n" ); - fprintf ( file, "InLine Rejection:\n" ); - fprintf ( file, "----------------------------------------------------------------------------\n" ); - } - - cRejectedLinks = 0; - - for ( i = 0 ; i < m_cNodes ; i++ ) - { - pSrcNode = &m_pNodes[ i ]; - - if ( file ) - { - fprintf ( file, "Node %3d:\n", i ); - } - - for ( j = 0 ; j < pSrcNode->m_cNumLinks ; j++ ) - { - pCheckNode = &m_pNodes[ pLinkPool[ pSrcNode->m_iFirstLink + j ].m_iDestNode ]; - - vec2DirToCheckNode = ( pCheckNode->m_vecOrigin - pSrcNode->m_vecOrigin ).Make2D(); - flDistToCheckNode = vec2DirToCheckNode.Length(); - vec2DirToCheckNode = vec2DirToCheckNode.Normalize(); - - pLinkPool[ pSrcNode->m_iFirstLink + j ].m_flWeight = flDistToCheckNode; - - fRestartLoop = FALSE; - for ( k = 0 ; k < pSrcNode->m_cNumLinks && !fRestartLoop ; k++ ) - { - if ( k == j ) - {// don't check against same node - continue; - } - - pTestNode = &m_pNodes [ pLinkPool[ pSrcNode->m_iFirstLink + k ].m_iDestNode ]; - - vec2DirToTestNode = ( pTestNode->m_vecOrigin - pSrcNode->m_vecOrigin ).Make2D(); - - flDistToTestNode = vec2DirToTestNode.Length(); - vec2DirToTestNode = vec2DirToTestNode.Normalize(); - - if ( DotProduct ( vec2DirToCheckNode, vec2DirToTestNode ) >= 0.998 ) - { - // there's a chance that TestNode intersects the line to CheckNode. If so, we should disconnect the link to CheckNode. - if ( flDistToTestNode < flDistToCheckNode ) - { - if ( file ) - { - fprintf ( file, "REJECTED NODE %3d through Node %3d, Dot = %8f\n", pLinkPool[ pSrcNode->m_iFirstLink + j ].m_iDestNode, pLinkPool[ pSrcNode->m_iFirstLink + k ].m_iDestNode, DotProduct ( vec2DirToCheckNode, vec2DirToTestNode ) ); - } - - pLinkPool[ pSrcNode->m_iFirstLink + j ] = pLinkPool[ pSrcNode->m_iFirstLink + ( pSrcNode->m_cNumLinks - 1 ) ]; - pSrcNode->m_cNumLinks--; - j--; - - cRejectedLinks++;// keeping track of how many links are cut, so that we can return that value. - - fRestartLoop = TRUE; - } - } - } - } - - if ( file ) - { - fprintf ( file, "----------------------------------------------------------------------------\n\n" ); - } - } - - return cRejectedLinks; -} - -//========================================================= -// TestHull is a modelless clip hull that verifies reachable -// nodes by walking from every node to each of it's connections -//========================================================= -class CTestHull : public CBaseMonster -{ - -public: - void Spawn( entvars_t *pevMasterNode ); - virtual int ObjectCaps( void ) { return CBaseMonster :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - void EXPORT CallBuildNodeGraph ( void ); - void BuildNodeGraph ( void ); - void EXPORT ShowBadNode ( void ); - void EXPORT DropDelay ( void ); - void EXPORT PathFind ( void ); - - Vector vecBadNodeOrigin; -}; - -LINK_ENTITY_TO_CLASS( testhull, CTestHull ); - -//========================================================= -// CTestHull::Spawn -//========================================================= -void CTestHull :: Spawn( entvars_t *pevMasterNode ) -{ - SET_MODEL(ENT(pev), "models/player.mdl"); - UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX); - - pev->solid = SOLID_SLIDEBOX; - pev->movetype = MOVETYPE_STEP; - pev->effects = 0; - pev->health = 50; - pev->yaw_speed = 8; - - if ( WorldGraph.m_fGraphPresent ) - {// graph loaded from disk, so we don't need the test hull - SetThink ( &CTestHull::SUB_Remove ); - pev->nextthink = gpGlobals->time; - } - else - { - SetThink ( &CTestHull::DropDelay ); - pev->nextthink = gpGlobals->time + 1; - } - - // Make this invisible - // UNDONE: Shouldn't we just use EF_NODRAW? This doesn't need to go to the client. - pev->rendermode = kRenderTransTexture; - pev->renderamt = 0; -} - -//========================================================= -// TestHull::DropDelay - spawns TestHull on top of -// the 0th node and drops it to the ground. -//========================================================= -void CTestHull::DropDelay ( void ) -{ -// UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding..." ); - - UTIL_SetOrigin ( VARS(pev), WorldGraph.m_pNodes[ 0 ].m_vecOrigin ); - - SetThink ( &CTestHull::CallBuildNodeGraph ); - - pev->nextthink = gpGlobals->time + 1; -} - -//========================================================= -// nodes start out as ents in the world. As they are spawned, -// the node info is recorded then the ents are discarded. -//========================================================= -void CNodeEnt :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "hinttype")) - { - m_sHintType = (short)atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - - if (FStrEq(pkvd->szKeyName, "activity")) - { - m_sHintActivity = (short)atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -//========================================================= -//========================================================= -void CNodeEnt :: Spawn( void ) -{ - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_NOT;// always solid_not - - if ( WorldGraph.m_fGraphPresent ) - {// graph loaded from disk, so discard all these node ents as soon as they spawn - REMOVE_ENTITY( edict() ); - return; - } - - if ( WorldGraph.m_cNodes == 0 ) - {// this is the first node to spawn, spawn the test hull entity that builds and walks the node tree - CTestHull *pHull = GetClassPtr((CTestHull *)NULL); - pHull->Spawn( pev ); - } - - if ( WorldGraph.m_cNodes >= MAX_NODES ) - { - ALERT ( at_aiconsole, "cNodes > MAX_NODES\n" ); - return; - } - - WorldGraph.m_pNodes[ WorldGraph.m_cNodes ].m_vecOriginPeek = - WorldGraph.m_pNodes[ WorldGraph.m_cNodes ].m_vecOrigin = pev->origin; - WorldGraph.m_pNodes[ WorldGraph.m_cNodes ].m_flHintYaw = pev->angles.y; - WorldGraph.m_pNodes[ WorldGraph.m_cNodes ].m_sHintType = m_sHintType; - WorldGraph.m_pNodes[ WorldGraph.m_cNodes ].m_sHintActivity = m_sHintActivity; - - if (FClassnameIs( pev, "info_node_air" )) - WorldGraph.m_pNodes[ WorldGraph.m_cNodes ].m_afNodeInfo = bits_NODE_AIR; - else - WorldGraph.m_pNodes[ WorldGraph.m_cNodes ].m_afNodeInfo = 0; - - WorldGraph.m_cNodes++; - - REMOVE_ENTITY( edict() ); -} - -//========================================================= -// CTestHull - ShowBadNode - makes a bad node fizzle. When -// there's a problem with node graph generation, the test -// hull will be placed up the bad node's location and will generate -// particles -//========================================================= -void CTestHull :: ShowBadNode( void ) -{ - pev->movetype = MOVETYPE_FLY; - pev->angles.y = pev->angles.y + 4; - - UTIL_MakeVectors ( pev->angles ); - - UTIL_ParticleEffect ( pev->origin, g_vecZero, 255, 25 ); - UTIL_ParticleEffect ( pev->origin + gpGlobals->v_forward * 64, g_vecZero, 255, 25 ); - UTIL_ParticleEffect ( pev->origin - gpGlobals->v_forward * 64, g_vecZero, 255, 25 ); - UTIL_ParticleEffect ( pev->origin + gpGlobals->v_right * 64, g_vecZero, 255, 25 ); - UTIL_ParticleEffect ( pev->origin - gpGlobals->v_right * 64, g_vecZero, 255, 25 ); - - pev->nextthink = gpGlobals->time + 0.1; -} - -extern BOOL gTouchDisabled; -void CTestHull::CallBuildNodeGraph( void ) -{ - // TOUCH HACK -- Don't allow this entity to call anyone's "touch" function - gTouchDisabled = TRUE; - BuildNodeGraph(); - gTouchDisabled = FALSE; - // Undo TOUCH HACK -} - -//========================================================= -// BuildNodeGraph - think function called by the empty walk -// hull that is spawned by the first node to spawn. This -// function links all nodes that can see each other, then -// eliminates all inline links, then uses a monster-sized -// hull that walks between each node and each of its links -// to ensure that a monster can actually fit through the space -//========================================================= -void CTestHull :: BuildNodeGraph( void ) -{ - TraceResult tr; - FILE *file; - - char szNrpFilename [MAX_PATH];// text node report filename - - CLink *pTempPool; // temporary link pool - - CNode *pSrcNode;// node we're currently working with - CNode *pDestNode;// the other node in comparison operations - - BOOL fSkipRemainingHulls;//if smallest hull can't fit, don't check any others - BOOL fPairsValid;// are all links in the graph evenly paired? - - int i, j, hull; - - int iBadNode;// this is the node that caused graph generation to fail - - int cMaxInitialLinks = 0; - int cMaxValidLinks = 0; - - int iPoolIndex = 0; - int cPoolLinks;// number of links in the pool. - - Vector vecDirToCheckNode; - Vector vecDirToTestNode; - Vector vecStepCheckDir; - Vector vecTraceSpot; - Vector vecSpot; - - Vector2D vec2DirToCheckNode; - Vector2D vec2DirToTestNode; - Vector2D vec2StepCheckDir; - Vector2D vec2TraceSpot; - Vector2D vec2Spot; - - float flYaw;// use this stuff to walk the hull between nodes - float flDist; - int step; - - SetThink ( &CTestHull::SUB_Remove );// no matter what happens, the hull gets rid of itself. - pev->nextthink = gpGlobals->time; - -// malloc a swollen temporary connection pool that we trim down after we know exactly how many connections there are. - pTempPool = (CLink *)calloc ( sizeof ( CLink ) , ( WorldGraph.m_cNodes * MAX_NODE_INITIAL_LINKS ) ); - if ( !pTempPool ) - { - ALERT ( at_aiconsole, "**Could not malloc TempPool!\n" ); - return; - } - - - // make sure directories have been made - GET_GAME_DIR( szNrpFilename ); - strcat( szNrpFilename, "/maps" ); - CreateDirectory( szNrpFilename, NULL ); - strcat( szNrpFilename, "/graphs" ); - CreateDirectory( szNrpFilename, NULL ); - - strcat( szNrpFilename, "/" ); - strcat( szNrpFilename, STRING( gpGlobals->mapname ) ); - strcat( szNrpFilename, ".nrp" ); - - file = fopen ( szNrpFilename, "w+" ); - - if ( !file ) - {// file error - ALERT ( at_aiconsole, "Couldn't create %s!\n", szNrpFilename ); - - if ( pTempPool ) - { - free ( pTempPool ); - } - - return; - } - - fprintf( file, "Node Graph Report for map: %s.bsp\n", STRING(gpGlobals->mapname) ); - fprintf ( file, "%d Total Nodes\n\n", WorldGraph.m_cNodes ); - - for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) - {// print all node numbers and their locations to the file. - WorldGraph.m_pNodes[ i ].m_cNumLinks = 0; - WorldGraph.m_pNodes[ i ].m_iFirstLink = 0; - memset(WorldGraph.m_pNodes[ i ].m_pNextBestNode, 0, sizeof(WorldGraph.m_pNodes[ i ].m_pNextBestNode)); - - fprintf ( file, "Node# %4d\n", i ); - fprintf ( file, "Location %4d,%4d,%4d\n",(int)WorldGraph.m_pNodes[ i ].m_vecOrigin.x, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.y, (int)WorldGraph.m_pNodes[ i ].m_vecOrigin.z ); - fprintf ( file, "HintType: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintType ); - fprintf ( file, "HintActivity: %4d\n", WorldGraph.m_pNodes[ i ].m_sHintActivity ); - fprintf ( file, "HintYaw: %4f\n", WorldGraph.m_pNodes[ i ].m_flHintYaw ); - fprintf ( file, "-------------------------------------------------------------------------------\n" ); - } - fprintf ( file, "\n\n" ); - - - // Automatically recognize WATER nodes and drop the LAND nodes to the floor. - // - for ( i = 0; i < WorldGraph.m_cNodes; i++) - { - if (WorldGraph.m_pNodes[ i ].m_afNodeInfo & bits_NODE_AIR) - { - // do nothing - } - else if (UTIL_PointContents(WorldGraph.m_pNodes[ i ].m_vecOrigin) == CONTENTS_WATER) - { - WorldGraph.m_pNodes[ i ].m_afNodeInfo |= bits_NODE_WATER; - } - else - { - WorldGraph.m_pNodes[ i ].m_afNodeInfo |= bits_NODE_LAND; - - // trace to the ground, then pop up 8 units and place node there to make it - // easier for them to connect (think stairs, chairs, and bumps in the floor). - // After the routing is done, push them back down. - // - TraceResult tr; - - UTIL_TraceLine ( WorldGraph.m_pNodes[i].m_vecOrigin, - WorldGraph.m_pNodes[i].m_vecOrigin - Vector ( 0, 0, 384 ), - ignore_monsters, - g_pBodyQueueHead,//!!!HACKHACK no real ent to supply here, using a global we don't care about - &tr ); - - // This trace is ONLY used if we hit an entity flagged with FL_WORLDBRUSH - TraceResult trEnt; - UTIL_TraceLine ( WorldGraph.m_pNodes[i].m_vecOrigin, - WorldGraph.m_pNodes[i].m_vecOrigin - Vector ( 0, 0, 384 ), - dont_ignore_monsters, - g_pBodyQueueHead,//!!!HACKHACK no real ent to supply here, using a global we don't care about - &trEnt ); - - - // Did we hit something closer than the floor? - if ( trEnt.flFraction < tr.flFraction ) - { - // If it was a world brush entity, copy the node location - if ( trEnt.pHit && (trEnt.pHit->v.flags & FL_WORLDBRUSH) ) - tr.vecEndPos = trEnt.vecEndPos; - } - - WorldGraph.m_pNodes[i].m_vecOriginPeek.z = - WorldGraph.m_pNodes[i].m_vecOrigin.z = tr.vecEndPos.z + NODE_HEIGHT; - } - } - - cPoolLinks = WorldGraph.LinkVisibleNodes( pTempPool, file, &iBadNode ); - - if ( !cPoolLinks ) - { - ALERT ( at_aiconsole, "**ConnectVisibleNodes FAILED!\n" ); - - SetThink ( &CTestHull::ShowBadNode );// send the hull off to show the offending node. - //pev->solid = SOLID_NOT; - pev->origin = WorldGraph.m_pNodes[ iBadNode ].m_vecOrigin; - - if ( pTempPool ) - { - free ( pTempPool ); - } - - if ( file ) - {// close the file - fclose ( file ); - } - - return; - } - -// send the walkhull to all of this node's connections now. We'll do this here since -// so much of it relies on being able to control the test hull. - fprintf ( file, "----------------------------------------------------------------------------\n" ); - fprintf ( file, "Walk Rejection:\n"); - - for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) - { - pSrcNode = &WorldGraph.m_pNodes[ i ]; - - fprintf ( file, "-------------------------------------------------------------------------------\n"); - fprintf ( file, "Node %4d:\n\n", i ); - - for ( j = 0 ; j < pSrcNode->m_cNumLinks ; j++ ) - { - // assume that all hulls can walk this link, then eliminate the ones that can't. - pTempPool [ pSrcNode->m_iFirstLink + j ].m_afLinkInfo = bits_LINK_SMALL_HULL | bits_LINK_HUMAN_HULL | bits_LINK_LARGE_HULL | bits_LINK_FLY_HULL; - - - // do a check for each hull size. - - // if we can't fit a tiny hull through a connection, no other hulls with fit either, so we - // should just fall out of the loop. Do so by setting the SkipRemainingHulls flag. - fSkipRemainingHulls = FALSE; - for ( hull = 0 ; hull < MAX_NODE_HULLS; hull++ ) - { - if (fSkipRemainingHulls && (hull == NODE_HUMAN_HULL || hull == NODE_LARGE_HULL)) // skip the remaining walk hulls - continue; - - switch ( hull ) - { - case NODE_SMALL_HULL: - UTIL_SetSize(pev, Vector(-12, -12, 0), Vector(12, 12, 24)); - break; - case NODE_HUMAN_HULL: - UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX ); - break; - case NODE_LARGE_HULL: - UTIL_SetSize(pev, Vector(-32, -32, 0), Vector(32, 32, 64)); - break; - case NODE_FLY_HULL: - UTIL_SetSize(pev, Vector(-32, -32, 0), Vector(32, 32, 64)); - // UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0)); - break; - } - - UTIL_SetOrigin ( pev, pSrcNode->m_vecOrigin );// place the hull on the node - - if ( !FBitSet ( pev->flags, FL_ONGROUND ) ) - { - ALERT ( at_aiconsole, "OFFGROUND!\n" ); - } - - // now build a yaw that points to the dest node, and get the distance. - if ( j < 0 ) - { - ALERT ( at_aiconsole, "**** j = %d ****\n", j ); - if ( pTempPool ) - { - free ( pTempPool ); - } - - if ( file ) - {// close the file - fclose ( file ); - } - return; - } - - pDestNode = &WorldGraph.m_pNodes [ pTempPool[ pSrcNode->m_iFirstLink + j ].m_iDestNode ]; - - vecSpot = pDestNode->m_vecOrigin; - //vecSpot.z = pev->origin.z; - - if (hull < NODE_FLY_HULL) - { - int SaveFlags = pev->flags; - int MoveMode = WALKMOVE_WORLDONLY; - if (pSrcNode->m_afNodeInfo & bits_NODE_WATER) - { - pev->flags |= FL_SWIM; - MoveMode = WALKMOVE_NORMAL; - } - - flYaw = UTIL_VecToYaw ( pDestNode->m_vecOrigin - pev->origin ); - - flDist = ( vecSpot - pev->origin ).Length2D(); - - int fWalkFailed = FALSE; - - // in this loop we take tiny steps from the current node to the nodes that it links to, one at a time. - // pev->angles.y = flYaw; - for ( step = 0 ; step < flDist && !fWalkFailed ; step += HULL_STEP_SIZE ) - { - float stepSize = HULL_STEP_SIZE; - - if ( (step + stepSize) >= (flDist-1) ) - stepSize = (flDist - step) - 1; - - if ( !WALK_MOVE( ENT(pev), flYaw, stepSize, MoveMode ) ) - {// can't take the next step - - fWalkFailed = TRUE; - break; - } - } - - if (!fWalkFailed && (pev->origin - vecSpot).Length() > 64) - { - // ALERT( at_console, "bogus walk\n"); - // we thought we - fWalkFailed = TRUE; - } - - if (fWalkFailed) - { - - //pTempPool[ pSrcNode->m_iFirstLink + j ] = pTempPool [ pSrcNode->m_iFirstLink + ( pSrcNode->m_cNumLinks - 1 ) ]; - - // now me must eliminate the hull that couldn't walk this connection - switch ( hull ) - { - case NODE_SMALL_HULL: // if this hull can't fit, nothing can, so drop the connection - fprintf ( file, "NODE_SMALL_HULL step %d\n", step ); - pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~(bits_LINK_SMALL_HULL | bits_LINK_HUMAN_HULL | bits_LINK_LARGE_HULL); - fSkipRemainingHulls = TRUE;// don't bother checking larger hulls - break; - case NODE_HUMAN_HULL: - fprintf ( file, "NODE_HUMAN_HULL step %d\n", step ); - pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~(bits_LINK_HUMAN_HULL | bits_LINK_LARGE_HULL); - fSkipRemainingHulls = TRUE;// don't bother checking larger hulls - break; - case NODE_LARGE_HULL: - fprintf ( file, "NODE_LARGE_HULL step %d\n", step ); - pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~bits_LINK_LARGE_HULL; - break; - } - } - pev->flags = SaveFlags; - } - else - { - TraceResult tr; - - UTIL_TraceHull( pSrcNode->m_vecOrigin + Vector( 0, 0, 32 ), pDestNode->m_vecOriginPeek + Vector( 0, 0, 32 ), ignore_monsters, large_hull, ENT( pev ), &tr ); - if (tr.fStartSolid || tr.flFraction < 1.0) - { - pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo &= ~bits_LINK_FLY_HULL; - } - } - } - - if (pTempPool[ pSrcNode->m_iFirstLink + j ].m_afLinkInfo == 0) - { - fprintf ( file, "Rejected Node %3d - Unreachable by ", pTempPool [ pSrcNode->m_iFirstLink + j ].m_iDestNode ); - pTempPool[ pSrcNode->m_iFirstLink + j ] = pTempPool [ pSrcNode->m_iFirstLink + ( pSrcNode->m_cNumLinks - 1 ) ]; - fprintf ( file, "Any Hull\n" ); - - pSrcNode->m_cNumLinks--; - cPoolLinks--;// we just removed a link, so decrement the total number of links in the pool. - j--; - } - - } - } - fprintf ( file, "-------------------------------------------------------------------------------\n\n\n"); - - cPoolLinks -= WorldGraph.RejectInlineLinks ( pTempPool, file ); - -// now malloc a pool just large enough to hold the links that are actually used - WorldGraph.m_pLinkPool = (CLink *) calloc ( sizeof ( CLink ), cPoolLinks ); - - if ( !WorldGraph.m_pLinkPool ) - {// couldn't make the link pool! - ALERT ( at_aiconsole, "Couldn't malloc LinkPool!\n" ); - if ( pTempPool ) - { - free ( pTempPool ); - } - if ( file ) - {// close the file - fclose ( file ); - } - - return; - } - WorldGraph.m_cLinks = cPoolLinks; - -//copy only the used portions of the TempPool into the graph's link pool - int iFinalPoolIndex = 0; - int iOldFirstLink; - - for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) - { - iOldFirstLink = WorldGraph.m_pNodes[ i ].m_iFirstLink;// store this, because we have to re-assign it before entering the copy loop - - WorldGraph.m_pNodes[ i ].m_iFirstLink = iFinalPoolIndex; - - for ( j = 0 ; j < WorldGraph.m_pNodes[ i ].m_cNumLinks ; j++ ) - { - WorldGraph.m_pLinkPool[ iFinalPoolIndex++ ] = pTempPool[ iOldFirstLink + j ]; - } - } - - - // Node sorting numbers linked nodes close to each other - // - WorldGraph.SortNodes(); - - // This is used for HashSearch - // - WorldGraph.BuildLinkLookups(); - - fPairsValid = TRUE; // assume that the connection pairs are all valid to start - - fprintf ( file, "\n\n-------------------------------------------------------------------------------\n"); - fprintf ( file, "Link Pairings:\n"); - -// link integrity check. The idea here is that if Node A links to Node B, node B should -// link to node A. If not, we have a situation that prevents us from using a basic -// optimization in the FindNearestLink function. - for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) - { - for ( j = 0 ; j < WorldGraph.m_pNodes[ i ].m_cNumLinks ; j++ ) - { - int iLink; - WorldGraph.HashSearch(WorldGraph.INodeLink(i,j), i, iLink); - if (iLink < 0) - { - fPairsValid = FALSE;// unmatched link pair. - fprintf ( file, "WARNING: Node %3d does not connect back to Node %3d\n", WorldGraph.INodeLink(i, j), i); - } - } - } - - // !!!LATER - if all connections are properly paired, when can enable an optimization in the pathfinding code - // (in the find nearest line function) - if ( fPairsValid ) - { - fprintf ( file, "\nAll Connections are Paired!\n"); - } - - fprintf ( file, "-------------------------------------------------------------------------------\n"); - fprintf ( file, "\n\n-------------------------------------------------------------------------------\n"); - fprintf ( file, "Total Number of Connections in Pool: %d\n", cPoolLinks ); - fprintf ( file, "-------------------------------------------------------------------------------\n"); - fprintf ( file, "Connection Pool: %d bytes\n", sizeof ( CLink ) * cPoolLinks ); - fprintf ( file, "-------------------------------------------------------------------------------\n"); - - - ALERT ( at_aiconsole, "%d Nodes, %d Connections\n", WorldGraph.m_cNodes, cPoolLinks ); - - // This is used for FindNearestNode - // - WorldGraph.BuildRegionTables(); - - - // Push all of the LAND nodes down to the ground now. Leave the water and air nodes alone. - // - for ( i = 0 ; i < WorldGraph.m_cNodes ; i++ ) - { - if ((WorldGraph.m_pNodes[ i ].m_afNodeInfo & bits_NODE_LAND)) - { - WorldGraph.m_pNodes[ i ].m_vecOrigin.z -= NODE_HEIGHT; - } - } - - - if ( pTempPool ) - {// free the temp pool - free ( pTempPool ); - } - - if ( file ) - { - fclose ( file ); - } - - // We now have some graphing capabilities. - // - WorldGraph.m_fGraphPresent = TRUE;//graph is in memory. - WorldGraph.m_fGraphPointersSet = TRUE;// since the graph was generated, the pointers are ready - WorldGraph.m_fRoutingComplete = FALSE; // Optimal routes aren't computed, yet. - - // Compute and compress the routing information. - // - WorldGraph.ComputeStaticRoutingTables(); - -// save the node graph for this level - WorldGraph.FSaveGraph( (char *)STRING( gpGlobals->mapname ) ); - ALERT( at_console, "Done.\n"); -} - - -//========================================================= -// returns a hardcoded path. -//========================================================= -void CTestHull :: PathFind ( void ) -{ - int iPath[ 50 ]; - int iPathSize; - int i; - CNode *pNode, *pNextNode; - - if ( !WorldGraph.m_fGraphPresent || !WorldGraph.m_fGraphPointersSet ) - {// protect us in the case that the node graph isn't available - ALERT ( at_aiconsole, "Graph not ready!\n" ); - return; - } - - iPathSize = WorldGraph.FindShortestPath ( iPath, 0, 19, 0, 0 ); // UNDONE use hull constant - - if ( !iPathSize ) - { - ALERT ( at_aiconsole, "No Path!\n" ); - return; - } - - ALERT ( at_aiconsole, "%d\n", iPathSize ); - - pNode = &WorldGraph.m_pNodes[ iPath [ 0 ] ]; - - for ( i = 0 ; i < iPathSize - 1 ; i++ ) - { - - pNextNode = &WorldGraph.m_pNodes[ iPath [ i + 1 ] ]; - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_SHOWLINE); - - WRITE_COORD( pNode->m_vecOrigin.x ); - WRITE_COORD( pNode->m_vecOrigin.y ); - WRITE_COORD( pNode->m_vecOrigin.z + NODE_HEIGHT ); - - WRITE_COORD( pNextNode->m_vecOrigin.x); - WRITE_COORD( pNextNode->m_vecOrigin.y); - WRITE_COORD( pNextNode->m_vecOrigin.z + NODE_HEIGHT); - MESSAGE_END(); - - pNode = pNextNode; - } - -} - - -//========================================================= -// CStack Constructor -//========================================================= -CStack :: CStack( void ) -{ - m_level = 0; -} - -//========================================================= -// pushes a value onto the stack -//========================================================= -void CStack :: Push( int value ) -{ - if ( m_level >= MAX_STACK_NODES ) - { - printf("Error!\n"); - return; - } - m_stack[m_level] = value; - m_level++; -} - -//========================================================= -// pops a value off of the stack -//========================================================= -int CStack :: Pop( void ) -{ - if ( m_level <= 0 ) - return -1; - - m_level--; - return m_stack[ m_level ]; -} - -//========================================================= -// returns the value on the top of the stack -//========================================================= -int CStack :: Top ( void ) -{ - return m_stack[ m_level - 1 ]; -} - -//========================================================= -// copies every element on the stack into an array LIFO -//========================================================= -void CStack :: CopyToArray ( int *piArray ) -{ - int i; - - for ( i = 0 ; i < m_level ; i++ ) - { - piArray[ i ] = m_stack[ i ]; - } -} - -//========================================================= -// CQueue constructor -//========================================================= -CQueue :: CQueue( void ) -{ - m_cSize = 0; - m_head = 0; - m_tail = -1; -} - -//========================================================= -// inserts a value into the queue -//========================================================= -void CQueue :: Insert ( int iValue, float fPriority ) -{ - - if ( Full() ) - { - printf ( "Queue is full!\n" ); - return; - } - - m_tail++; - - if ( m_tail == MAX_STACK_NODES ) - {//wrap around - m_tail = 0; - } - - m_queue[ m_tail ].Id = iValue; - m_queue[ m_tail ].Priority = fPriority; - m_cSize++; -} - -//========================================================= -// removes a value from the queue (FIFO) -//========================================================= -int CQueue :: Remove ( float &fPriority ) -{ - if ( m_head == MAX_STACK_NODES ) - {// wrap - m_head = 0; - } - - m_cSize--; - fPriority = m_queue[ m_head ].Priority; - return m_queue[ m_head++ ].Id; -} - -//========================================================= -// CQueue constructor -//========================================================= -CQueuePriority :: CQueuePriority( void ) -{ - m_cSize = 0; -} - -//========================================================= -// inserts a value into the priority queue -//========================================================= -void CQueuePriority :: Insert( int iValue, float fPriority ) -{ - - if ( Full() ) - { - printf ( "Queue is full!\n" ); - return; - } - - m_heap[ m_cSize ].Priority = fPriority; - m_heap[ m_cSize ].Id = iValue; - m_cSize++; - Heap_SiftUp(); -} - -//========================================================= -// removes the smallest item from the priority queue -// -//========================================================= -int CQueuePriority :: Remove( float &fPriority ) -{ - int iReturn = m_heap[ 0 ].Id; - fPriority = m_heap[ 0 ].Priority; - - m_cSize--; - - m_heap[ 0 ] = m_heap[ m_cSize ]; - - Heap_SiftDown(0); - return iReturn; -} - -#define HEAP_LEFT_CHILD(x) (2*(x)+1) -#define HEAP_RIGHT_CHILD(x) (2*(x)+2) -#define HEAP_PARENT(x) (((x)-1)/2) - -void CQueuePriority::Heap_SiftDown(int iSubRoot) -{ - int parent = iSubRoot; - int child = HEAP_LEFT_CHILD(parent); - - struct tag_HEAP_NODE Ref = m_heap[ parent ]; - - while (child < m_cSize) - { - int rightchild = HEAP_RIGHT_CHILD(parent); - if (rightchild < m_cSize) - { - if ( m_heap[ rightchild ].Priority < m_heap[ child ].Priority ) - { - child = rightchild; - } - } - if ( Ref.Priority <= m_heap[ child ].Priority ) - break; - - m_heap[ parent ] = m_heap[ child ]; - parent = child; - child = HEAP_LEFT_CHILD(parent); - } - m_heap[ parent ] = Ref; -} - -void CQueuePriority::Heap_SiftUp(void) -{ - int child = m_cSize-1; - while (child) - { - int parent = HEAP_PARENT(child); - if ( m_heap[ parent ].Priority <= m_heap[ child ].Priority ) - break; - - struct tag_HEAP_NODE Tmp; - Tmp = m_heap[ child ]; - m_heap[ child ] = m_heap[ parent ]; - m_heap[ parent ] = Tmp; - - child = parent; - } -} - -//========================================================= -// CGraph - FLoadGraph - attempts to load a node graph from disk. -// if the current level is maps/snar.bsp, maps/graphs/snar.nod -// will be loaded. If file cannot be loaded, the node tree -// will be created and saved to disk. -//========================================================= -int CGraph :: FLoadGraph ( char *szMapName ) -{ - char szFilename[MAX_PATH]; - int iVersion; - int length; - byte *aMemFile; - byte *pMemFile; - - // make sure the directories have been made - char szDirName[MAX_PATH]; - GET_GAME_DIR( szDirName ); - strcat( szDirName, "/maps" ); - CreateDirectory( szDirName, NULL ); - strcat( szDirName, "/graphs" ); - CreateDirectory( szDirName, NULL ); - - strcpy ( szFilename, "maps/graphs/" ); - strcat ( szFilename, szMapName ); - strcat( szFilename, ".nod" ); - - pMemFile = aMemFile = LOAD_FILE_FOR_ME(szFilename, &length); - - if ( !aMemFile ) - { - return FALSE; - } - else - { - // Read the graph version number - // - length -= sizeof(int); - if (length < 0) goto ShortFile; - memcpy(&iVersion, pMemFile, sizeof(int)); - pMemFile += sizeof(int); - - if ( iVersion != GRAPH_VERSION ) - { - // This file was written by a different build of the dll! - // - ALERT ( at_aiconsole, "**ERROR** Graph version is %d, expected %d\n",iVersion, GRAPH_VERSION ); - goto ShortFile; - } - - // Read the graph class - // - length -= sizeof(CGraph); - if (length < 0) goto ShortFile; - memcpy(this, pMemFile, sizeof(CGraph)); - pMemFile += sizeof(CGraph); - - // Set the pointers to zero, just in case we run out of memory. - // - m_pNodes = NULL; - m_pLinkPool = NULL; - m_di = NULL; - m_pRouteInfo = NULL; - m_pHashLinks = NULL; - - - // Malloc for the nodes - // - m_pNodes = ( CNode * )calloc ( sizeof ( CNode ), m_cNodes ); - - if ( !m_pNodes ) - { - ALERT ( at_aiconsole, "**ERROR**\nCouldn't malloc %d nodes!\n", m_cNodes ); - goto NoMemory; - } - - // Read in all the nodes - // - length -= sizeof(CNode) * m_cNodes; - if (length < 0) goto ShortFile; - memcpy(m_pNodes, pMemFile, sizeof(CNode)*m_cNodes); - pMemFile += sizeof(CNode) * m_cNodes; - - - // Malloc for the link pool - // - m_pLinkPool = ( CLink * )calloc ( sizeof ( CLink ), m_cLinks ); - - if ( !m_pLinkPool ) - { - ALERT ( at_aiconsole, "**ERROR**\nCouldn't malloc %d link!\n", m_cLinks ); - goto NoMemory; - } - - // Read in all the links - // - length -= sizeof(CLink)*m_cLinks; - if (length < 0) goto ShortFile; - memcpy(m_pLinkPool, pMemFile, sizeof(CLink)*m_cLinks); - pMemFile += sizeof(CLink)*m_cLinks; - - // Malloc for the sorting info. - // - m_di = (DIST_INFO *)calloc( sizeof(DIST_INFO), m_cNodes ); - if ( !m_di ) - { - ALERT ( at_aiconsole, "***ERROR**\nCouldn't malloc %d entries sorting nodes!\n", m_cNodes ); - goto NoMemory; - } - - // Read it in. - // - length -= sizeof(DIST_INFO)*m_cNodes; - if (length < 0) goto ShortFile; - memcpy(m_di, pMemFile, sizeof(DIST_INFO)*m_cNodes); - pMemFile += sizeof(DIST_INFO)*m_cNodes; - - // Malloc for the routing info. - // - m_fRoutingComplete = FALSE; - m_pRouteInfo = (char *)calloc( sizeof(char), m_nRouteInfo ); - if ( !m_pRouteInfo ) - { - ALERT ( at_aiconsole, "***ERROR**\nCounldn't malloc %d route bytes!\n", m_nRouteInfo ); - goto NoMemory; - } - m_CheckedCounter = 0; - for (int i = 0; i < m_cNodes; i++) - { - m_di[i].m_CheckedEvent = 0; - } - - // Read in the route information. - // - length -= sizeof(char)*m_nRouteInfo; - if (length < 0) goto ShortFile; - memcpy(m_pRouteInfo, pMemFile, sizeof(char)*m_nRouteInfo); - pMemFile += sizeof(char)*m_nRouteInfo; - m_fRoutingComplete = TRUE;; - - // malloc for the hash links - // - m_pHashLinks = (short *)calloc(sizeof(short), m_nHashLinks); - if (!m_pHashLinks) - { - ALERT ( at_aiconsole, "***ERROR**\nCounldn't malloc %d hash link bytes!\n", m_nHashLinks ); - goto NoMemory; - } - - // Read in the hash link information - // - length -= sizeof(short)*m_nHashLinks; - if (length < 0) goto ShortFile; - memcpy(m_pHashLinks, pMemFile, sizeof(short)*m_nHashLinks); - pMemFile += sizeof(short)*m_nHashLinks; - - // Set the graph present flag, clear the pointers set flag - // - m_fGraphPresent = TRUE; - m_fGraphPointersSet = FALSE; - - FREE_FILE(aMemFile); - - if (length != 0) - { - ALERT ( at_aiconsole, "***WARNING***:Node graph was longer than expected by %d bytes.!\n", length); - } - - return TRUE; - } - -ShortFile: -NoMemory: - FREE_FILE(aMemFile); - return FALSE; -} - -//========================================================= -// CGraph - FSaveGraph - It's not rocket science. -// this WILL overwrite existing files. -//========================================================= -int CGraph :: FSaveGraph ( char *szMapName ) -{ - - int iVersion = GRAPH_VERSION; - char szFilename[MAX_PATH]; - FILE *file; - - if ( !m_fGraphPresent || !m_fGraphPointersSet ) - {// protect us in the case that the node graph isn't available or built - ALERT ( at_aiconsole, "Graph not ready!\n" ); - return FALSE; - } - - // make sure directories have been made - GET_GAME_DIR( szFilename ); - strcat( szFilename, "/maps" ); - CreateDirectory( szFilename, NULL ); - strcat( szFilename, "/graphs" ); - CreateDirectory( szFilename, NULL ); - - strcat( szFilename, "/" ); - strcat( szFilename, szMapName ); - strcat( szFilename, ".nod" ); - - file = fopen ( szFilename, "wb" ); - - ALERT ( at_aiconsole, "Created: %s\n", szFilename ); - - if ( !file ) - {// couldn't create - ALERT ( at_aiconsole, "Couldn't Create: %s\n", szFilename ); - return FALSE; - } - else - { - // write the version - fwrite ( &iVersion, sizeof ( int ), 1, file ); - - // write the CGraph class - fwrite ( this, sizeof ( CGraph ), 1, file ); - - // write the nodes - fwrite ( m_pNodes, sizeof ( CNode ), m_cNodes, file ); - - // write the links - fwrite ( m_pLinkPool, sizeof ( CLink ), m_cLinks, file ); - - fwrite ( m_di, sizeof(DIST_INFO), m_cNodes, file ); - - // Write the route info. - // - if ( m_pRouteInfo && m_nRouteInfo ) - { - fwrite ( m_pRouteInfo, sizeof( char ), m_nRouteInfo, file ); - } - - if (m_pHashLinks && m_nHashLinks) - { - fwrite(m_pHashLinks, sizeof(short), m_nHashLinks, file); - } - fclose ( file ); - return TRUE; - } -} - -//========================================================= -// CGraph - FSetGraphPointers - Takes the modelnames of -// all of the brush ents that block connections in the node -// graph and resolves them into pointers to those entities. -// this is done after loading the graph from disk, whereupon -// the pointers are not valid. -//========================================================= -int CGraph :: FSetGraphPointers ( void ) -{ - int i; - edict_t *pentLinkEnt; - - for ( i = 0 ; i < m_cLinks ; i++ ) - {// go through all of the links - - if ( m_pLinkPool[ i ].m_pLinkEnt != NULL ) - { - char name[5]; - // when graphs are saved, any valid pointers are will be non-zero, signifying that we should - // reset those pointers upon reloading. Any pointers that were NULL when the graph was saved - // will be NULL when reloaded, and will ignored by this function. - - // m_szLinkEntModelname is not necessarily NULL terminated (so we can store it in a more alignment-friendly 4 bytes) - memcpy( name, m_pLinkPool[ i ].m_szLinkEntModelname, 4 ); - name[4] = 0; - pentLinkEnt = FIND_ENTITY_BY_STRING( NULL, "model", name ); - - if ( FNullEnt ( pentLinkEnt ) ) - { - // the ent isn't around anymore? Either there is a major problem, or it was removed from the world - // ( like a func_breakable that's been destroyed or something ). Make sure that LinkEnt is null. - ALERT ( at_aiconsole, "**Could not find model %s\n", name ); - m_pLinkPool[ i ].m_pLinkEnt = NULL; - } - else - { - m_pLinkPool[ i ].m_pLinkEnt = VARS( pentLinkEnt ); - - if ( !FBitSet( m_pLinkPool[ i ].m_pLinkEnt->flags, FL_GRAPHED ) ) - { - m_pLinkPool[ i ].m_pLinkEnt->flags += FL_GRAPHED; - } - } - } - } - - // the pointers are now set. - m_fGraphPointersSet = TRUE; - return TRUE; -} - -//========================================================= -// CGraph - CheckNODFile - this function checks the date of -// the BSP file that was just loaded and the date of the a -// ssociated .NOD file. If the NOD file is not present, or -// is older than the BSP file, we rebuild it. -// -// returns FALSE if the .NOD file doesn't qualify and needs -// to be rebuilt. -// -// !!!BUGBUG - the file times we get back are 20 hours ahead! -// since this happens consistantly, we can still correctly -// determine which of the 2 files is newer. This needs fixed, -// though. ( I now suspect that we are getting GMT back from -// these functions and must compensate for local time ) (sjb) -//========================================================= -int CGraph :: CheckNODFile ( char *szMapName ) -{ - int retValue; - - char szBspFilename[MAX_PATH]; - char szGraphFilename[MAX_PATH]; - - - strcpy ( szBspFilename, "maps/" ); - strcat ( szBspFilename, szMapName ); - strcat ( szBspFilename, ".bsp" ); - - strcpy ( szGraphFilename, "maps/graphs/" ); - strcat ( szGraphFilename, szMapName ); - strcat ( szGraphFilename, ".nod" ); - - retValue = TRUE; - - int iCompare; - if (COMPARE_FILE_TIME(szBspFilename, szGraphFilename, &iCompare)) - { - if ( iCompare > 0 ) - {// BSP file is newer. - ALERT ( at_aiconsole, ".NOD File will be updated\n\n" ); - retValue = FALSE; - } - } - else - { - retValue = FALSE; - } - - return retValue; -} - -#define ENTRY_STATE_EMPTY -1 - -struct tagNodePair -{ - short iSrc; - short iDest; -}; - -void CGraph::HashInsert(int iSrcNode, int iDestNode, int iKey) -{ - struct tagNodePair np; - - np.iSrc = iSrcNode; - np.iDest = iDestNode; - CRC32_t dwHash; - CRC32_INIT(&dwHash); - CRC32_PROCESS_BUFFER(&dwHash, &np, sizeof(np)); - dwHash = CRC32_FINAL(dwHash); - - int di = m_HashPrimes[dwHash&15]; - int i = (dwHash >> 4) % m_nHashLinks; - while (m_pHashLinks[i] != ENTRY_STATE_EMPTY) - { - i += di; - if (i >= m_nHashLinks) i -= m_nHashLinks; - } - m_pHashLinks[i] = iKey; -} - -void CGraph::HashSearch(int iSrcNode, int iDestNode, int &iKey) -{ - struct tagNodePair np; - - np.iSrc = iSrcNode; - np.iDest = iDestNode; - CRC32_t dwHash; - CRC32_INIT(&dwHash); - CRC32_PROCESS_BUFFER(&dwHash, &np, sizeof(np)); - dwHash = CRC32_FINAL(dwHash); - - int di = m_HashPrimes[dwHash&15]; - int i = (dwHash >> 4) % m_nHashLinks; - while (m_pHashLinks[i] != ENTRY_STATE_EMPTY) - { - CLink &link = Link(m_pHashLinks[i]); - if (iSrcNode == link.m_iSrcNode && iDestNode == link.m_iDestNode) - { - break; - } - else - { - i += di; - if (i >= m_nHashLinks) i -= m_nHashLinks; - } - } - iKey = m_pHashLinks[i]; -} - -#define NUMBER_OF_PRIMES 177 - -int Primes[NUMBER_OF_PRIMES] = -{ 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, -71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, -157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, -241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, -347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, -439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, -547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, -643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, -751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, -859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, -977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 0 }; - -void CGraph::HashChoosePrimes(int TableSize) -{ - int LargestPrime = TableSize/2; - if (LargestPrime > Primes[NUMBER_OF_PRIMES-2]) - { - LargestPrime = Primes[NUMBER_OF_PRIMES-2]; - } - int Spacing = LargestPrime/16; - - // Pick a set primes that are evenly spaced from (0 to LargestPrime) - // We divide this interval into 16 equal sized zones. We want to find - // one prime number that best represents that zone. - // - int iPrime,iZone; - for (iZone = 1, iPrime = 0; iPrime < 16; iZone += Spacing) - { - // Search for a prime number that is less than the target zone - // number given by iZone. - // - int Lower = Primes[0]; - for (int jPrime = 0; Primes[jPrime] != 0; jPrime++) - { - if (jPrime != 0 && TableSize % Primes[jPrime] == 0) continue; - int Upper = Primes[jPrime]; - if (Lower <= iZone && iZone <= Upper) - { - // Choose the closest lower prime number. - // - if (iZone - Lower <= Upper - iZone) - { - m_HashPrimes[iPrime++] = Lower; - } - else - { - m_HashPrimes[iPrime++] = Upper; - } - break; - } - Lower = Upper; - } - } - - // Alternate negative and positive numbers - // - for (iPrime = 0; iPrime < 16; iPrime += 2) - { - m_HashPrimes[iPrime] = TableSize-m_HashPrimes[iPrime]; - } - - // Shuffle the set of primes to reduce correlation with bits in - // hash key. - // - for (iPrime = 0; iPrime < 16-1; iPrime++) - { - int Pick = RANDOM_LONG(0, 15-iPrime); - int Temp = m_HashPrimes[Pick]; - m_HashPrimes[Pick] = m_HashPrimes[15-iPrime]; - m_HashPrimes[15-iPrime] = Temp; - } -} - -// Renumber nodes so that nodes that link together are together. -// -#define UNNUMBERED_NODE -1 -void CGraph::SortNodes(void) -{ - // We are using m_iPreviousNode to be the new node number. - // After assigning new node numbers to everything, we move - // things and patchup the links. - // - int iNodeCnt = 0; - int i; - m_pNodes[0].m_iPreviousNode = iNodeCnt++; - - for (i = 1; i < m_cNodes; i++) - { - m_pNodes[i].m_iPreviousNode = UNNUMBERED_NODE; - } - - for (i = 0; i < m_cNodes; i++) - { - // Run through all of this node's neighbors - // - for (int j = 0 ; j < m_pNodes[i].m_cNumLinks; j++ ) - { - int iDestNode = INodeLink(i, j); - if (m_pNodes[iDestNode].m_iPreviousNode == UNNUMBERED_NODE) - { - m_pNodes[iDestNode].m_iPreviousNode = iNodeCnt++; - } - } - } - - // Assign remaining node numbers to unlinked nodes. - // - for (i = 0; i < m_cNodes; i++) - { - if (m_pNodes[i].m_iPreviousNode == UNNUMBERED_NODE) - { - m_pNodes[i].m_iPreviousNode = iNodeCnt++; - } - } - - // Alter links to reflect new node numbers. - // - for (i = 0; i < m_cLinks; i++) - { - m_pLinkPool[i].m_iSrcNode = m_pNodes[m_pLinkPool[i].m_iSrcNode].m_iPreviousNode; - m_pLinkPool[i].m_iDestNode = m_pNodes[m_pLinkPool[i].m_iDestNode].m_iPreviousNode; - } - - // Rearrange nodes to reflect new node numbering. - // - for (i = 0; i < m_cNodes; i++) - { - while (m_pNodes[i].m_iPreviousNode != i) - { - // Move current node off to where it should be, and bring - // that other node back into the current slot. - // - int iDestNode = m_pNodes[i].m_iPreviousNode; - CNode TempNode = m_pNodes[iDestNode]; - m_pNodes[iDestNode] = m_pNodes[i]; - m_pNodes[i] = TempNode; - } - } -} - -void CGraph::BuildLinkLookups(void) -{ - m_nHashLinks = 3*m_cLinks/2 + 3; - - HashChoosePrimes(m_nHashLinks); - m_pHashLinks = (short *)calloc(sizeof(short), m_nHashLinks); - if (!m_pHashLinks) - { - ALERT(at_aiconsole, "Couldn't allocated Link Lookup Table.\n"); - return; - } - int i; - for (i = 0; i < m_nHashLinks; i++) - { - m_pHashLinks[i] = ENTRY_STATE_EMPTY; - } - - for (i = 0; i < m_cLinks; i++) - { - CLink &link = Link(i); - HashInsert(link.m_iSrcNode, link.m_iDestNode, i); - } -#if 0 - for (i = 0; i < m_cLinks; i++) - { - CLink &link = Link(i); - int iKey; - HashSearch(link.m_iSrcNode, link.m_iDestNode, iKey); - if (iKey != i) - { - ALERT(at_aiconsole, "HashLinks don't match (%d versus %d)\n", i, iKey); - } - } -#endif -} - -void CGraph::BuildRegionTables(void) -{ - if (m_di) free(m_di); - - // Go ahead and setup for range searching the nodes for FindNearestNodes - // - m_di = (DIST_INFO *)calloc(sizeof(DIST_INFO), m_cNodes); - if (!m_di) - { - ALERT(at_aiconsole, "Couldn't allocated node ordering array.\n"); - return; - } - - // Calculate regions for all the nodes. - // - // - int i; - for (i = 0; i < 3; i++) - { - m_RegionMin[i] = 999999999.0; // just a big number out there; - m_RegionMax[i] = -999999999.0; // just a big number out there; - } - for (i = 0; i < m_cNodes; i++) - { - if (m_pNodes[i].m_vecOrigin.x < m_RegionMin[0]) - m_RegionMin[0] = m_pNodes[i].m_vecOrigin.x; - if (m_pNodes[i].m_vecOrigin.y < m_RegionMin[1]) - m_RegionMin[1] = m_pNodes[i].m_vecOrigin.y; - if (m_pNodes[i].m_vecOrigin.z < m_RegionMin[2]) - m_RegionMin[2] = m_pNodes[i].m_vecOrigin.z; - - if (m_pNodes[i].m_vecOrigin.x > m_RegionMax[0]) - m_RegionMax[0] = m_pNodes[i].m_vecOrigin.x; - if (m_pNodes[i].m_vecOrigin.y > m_RegionMax[1]) - m_RegionMax[1] = m_pNodes[i].m_vecOrigin.y; - if (m_pNodes[i].m_vecOrigin.z > m_RegionMax[2]) - m_RegionMax[2] = m_pNodes[i].m_vecOrigin.z; - } - for (i = 0; i < m_cNodes; i++) - { - m_pNodes[i].m_Region[0] = CALC_RANGE(m_pNodes[i].m_vecOrigin.x, m_RegionMin[0], m_RegionMax[0]); - m_pNodes[i].m_Region[1] = CALC_RANGE(m_pNodes[i].m_vecOrigin.y, m_RegionMin[1], m_RegionMax[1]); - m_pNodes[i].m_Region[2] = CALC_RANGE(m_pNodes[i].m_vecOrigin.z, m_RegionMin[2], m_RegionMax[2]); - } - - for (i = 0; i < 3; i++) - { - int j; - for (j = 0; j < NUM_RANGES; j++) - { - m_RangeStart[i][j] = 255; - m_RangeEnd[i][j] = 0; - } - for (j = 0; j < m_cNodes; j++) - { - m_di[j].m_SortedBy[i] = j; - } - - for (j = 0; j < m_cNodes - 1; j++) - { - int jNode = m_di[j].m_SortedBy[i]; - int jCodeX = m_pNodes[jNode].m_Region[0]; - int jCodeY = m_pNodes[jNode].m_Region[1]; - int jCodeZ = m_pNodes[jNode].m_Region[2]; - int jCode; - switch (i) - { - case 0: - jCode = (jCodeX << 16) + (jCodeY << 8) + jCodeZ; - break; - case 1: - jCode = (jCodeY << 16) + (jCodeZ << 8) + jCodeX; - break; - case 2: - jCode = (jCodeZ << 16) + (jCodeX << 8) + jCodeY; - break; - } - - for (int k = j+1; k < m_cNodes; k++) - { - int kNode = m_di[k].m_SortedBy[i]; - int kCodeX = m_pNodes[kNode].m_Region[0]; - int kCodeY = m_pNodes[kNode].m_Region[1]; - int kCodeZ = m_pNodes[kNode].m_Region[2]; - int kCode; - switch (i) - { - case 0: - kCode = (kCodeX << 16) + (kCodeY << 8) + kCodeZ; - break; - case 1: - kCode = (kCodeY << 16) + (kCodeZ << 8) + kCodeX; - break; - case 2: - kCode = (kCodeZ << 16) + (kCodeX << 8) + kCodeY; - break; - } - - if (kCode < jCode) - { - // Swap j and k entries. - // - int Tmp = m_di[j].m_SortedBy[i]; - m_di[j].m_SortedBy[i] = m_di[k].m_SortedBy[i]; - m_di[k].m_SortedBy[i] = Tmp; - } - } - } - } - - // Generate lookup tables. - // - for (i = 0; i < m_cNodes; i++) - { - int CodeX = m_pNodes[m_di[i].m_SortedBy[0]].m_Region[0]; - int CodeY = m_pNodes[m_di[i].m_SortedBy[1]].m_Region[1]; - int CodeZ = m_pNodes[m_di[i].m_SortedBy[2]].m_Region[2]; - - if (i < m_RangeStart[0][CodeX]) - { - m_RangeStart[0][CodeX] = i; - } - if (i < m_RangeStart[1][CodeY]) - { - m_RangeStart[1][CodeY] = i; - } - if (i < m_RangeStart[2][CodeZ]) - { - m_RangeStart[2][CodeZ] = i; - } - if (m_RangeEnd[0][CodeX] < i) - { - m_RangeEnd[0][CodeX] = i; - } - if (m_RangeEnd[1][CodeY] < i) - { - m_RangeEnd[1][CodeY] = i; - } - if (m_RangeEnd[2][CodeZ] < i) - { - m_RangeEnd[2][CodeZ] = i; - } - } - - // Initialize the cache. - // - memset(m_Cache, 0, sizeof(m_Cache)); -} - -void CGraph :: ComputeStaticRoutingTables( void ) -{ - int nRoutes = m_cNodes*m_cNodes; -#define FROM_TO(x,y) ((x)*m_cNodes+(y)) - short *Routes = new short[nRoutes]; - - int *pMyPath = new int[m_cNodes]; - unsigned short *BestNextNodes = new unsigned short[m_cNodes]; - char *pRoute = new char[m_cNodes*2]; - - - if (Routes && pMyPath && BestNextNodes && pRoute) - { - int nTotalCompressedSize = 0; - for (int iHull = 0; iHull < MAX_NODE_HULLS; iHull++) - { - for (int iCap = 0; iCap < 2; iCap++) - { - int iCapMask; - switch (iCap) - { - case 0: - iCapMask = 0; - break; - - case 1: - iCapMask = bits_CAP_OPEN_DOORS | bits_CAP_AUTO_DOORS | bits_CAP_USE; - break; - } - - - // Initialize Routing table to uncalculated. - // - int iFrom; - for (iFrom = 0; iFrom < m_cNodes; iFrom++) - { - for (int iTo = 0; iTo < m_cNodes; iTo++) - { - Routes[FROM_TO(iFrom, iTo)] = -1; - } - } - - for (iFrom = 0; iFrom < m_cNodes; iFrom++) - { - for (int iTo = m_cNodes-1; iTo >= 0; iTo--) - { - if (Routes[FROM_TO(iFrom, iTo)] != -1) continue; - - int cPathSize = FindShortestPath(pMyPath, iFrom, iTo, iHull, iCapMask); - - // Use the computed path to update the routing table. - // - if (cPathSize > 1) - { - for (int iNode = 0; iNode < cPathSize-1; iNode++) - { - int iStart = pMyPath[iNode]; - int iNext = pMyPath[iNode+1]; - for (int iNode1 = iNode+1; iNode1 < cPathSize; iNode1++) - { - int iEnd = pMyPath[iNode1]; - Routes[FROM_TO(iStart, iEnd)] = iNext; - } - } -#if 0 - // Well, at first glance, this should work, but actually it's safer - // to be told explictly that you can take a series of node in a - // particular direction. Some links don't appear to have links in - // the opposite direction. - // - for (iNode = cPathSize-1; iNode >= 1; iNode--) - { - int iStart = pMyPath[iNode]; - int iNext = pMyPath[iNode-1]; - for (int iNode1 = iNode-1; iNode1 >= 0; iNode1--) - { - int iEnd = pMyPath[iNode1]; - Routes[FROM_TO(iStart, iEnd)] = iNext; - } - } -#endif - } - else - { - Routes[FROM_TO(iFrom, iTo)] = iFrom; - Routes[FROM_TO(iTo, iFrom)] = iTo; - } - } - } - - for (iFrom = 0; iFrom < m_cNodes; iFrom++) - { - for (int iTo = 0; iTo < m_cNodes; iTo++) - { - BestNextNodes[iTo] = Routes[FROM_TO(iFrom, iTo)]; - } - - // Compress this node's routing table. - // - int iLastNode = 9999999; // just really big. - int cSequence = 0; - int cRepeats = 0; - int CompressedSize = 0; - char *p = pRoute; - for (int i = 0; i < m_cNodes; i++) - { - BOOL CanRepeat = ((BestNextNodes[i] == iLastNode) && cRepeats < 127); - BOOL CanSequence = (BestNextNodes[i] == i && cSequence < 128); - - if (cRepeats) - { - if (CanRepeat) - { - cRepeats++; - } - else - { - // Emit the repeat phrase. - // - CompressedSize += 2; // (count-1, iLastNode-i) - *p++ = cRepeats - 1; - int a = iLastNode - iFrom; - int b = iLastNode - iFrom + m_cNodes; - int c = iLastNode - iFrom - m_cNodes; - if (-128 <= a && a <= 127) - { - *p++ = a; - } - else if (-128 <= b && b <= 127) - { - *p++ = b; - } - else if (-128 <= c && c <= 127) - { - *p++ = c; - } - else - { - ALERT( at_aiconsole, "Nodes need sorting (%d,%d)!\n", iLastNode, iFrom); - } - cRepeats = 0; - - if (CanSequence) - { - // Start a sequence. - // - cSequence++; - } - else - { - // Start another repeat. - // - cRepeats++; - } - } - } - else if (cSequence) - { - if (CanSequence) - { - cSequence++; - } - else - { - // It may be advantageous to combine - // a single-entry sequence phrase with the - // next repeat phrase. - // - if (cSequence == 1 && CanRepeat) - { - // Combine with repeat phrase. - // - cRepeats = 2; - cSequence = 0; - } - else - { - // Emit the sequence phrase. - // - CompressedSize += 1; // (-count) - *p++ = -cSequence; - cSequence = 0; - - // Start a repeat sequence. - // - cRepeats++; - } - } - } - else - { - if (CanSequence) - { - // Start a sequence phrase. - // - cSequence++; - } - else - { - // Start a repeat sequence. - // - cRepeats++; - } - } - iLastNode = BestNextNodes[i]; - } - if (cRepeats) - { - // Emit the repeat phrase. - // - CompressedSize += 2; - *p++ = cRepeats - 1; -#if 0 - iLastNode = iFrom + *pRoute; - if (iLastNode >= m_cNodes) iLastNode -= m_cNodes; - else if (iLastNode < 0) iLastNode += m_cNodes; -#endif - int a = iLastNode - iFrom; - int b = iLastNode - iFrom + m_cNodes; - int c = iLastNode - iFrom - m_cNodes; - if (-128 <= a && a <= 127) - { - *p++ = a; - } - else if (-128 <= b && b <= 127) - { - *p++ = b; - } - else if (-128 <= c && c <= 127) - { - *p++ = c; - } - else - { - ALERT( at_aiconsole, "Nodes need sorting (%d,%d)!\n", iLastNode, iFrom); - } - } - if (cSequence) - { - // Emit the Sequence phrase. - // - CompressedSize += 1; - *p++ = -cSequence; - } - - // Go find a place to store this thing and point to it. - // - int nRoute = p - pRoute; - if (m_pRouteInfo) - { - int i; - for (i = 0; i < m_nRouteInfo - nRoute; i++) - { - if (memcmp(m_pRouteInfo + i, pRoute, nRoute) == 0) - { - break; - } - } - if (i < m_nRouteInfo - nRoute) - { - m_pNodes[ iFrom ].m_pNextBestNode[iHull][iCap] = i; - } - else - { - char *Tmp = (char *)calloc(sizeof(char), (m_nRouteInfo + nRoute)); - memcpy(Tmp, m_pRouteInfo, m_nRouteInfo); - free(m_pRouteInfo); - m_pRouteInfo = Tmp; - memcpy(m_pRouteInfo + m_nRouteInfo, pRoute, nRoute); - m_pNodes[ iFrom ].m_pNextBestNode[iHull][iCap] = m_nRouteInfo; - m_nRouteInfo += nRoute; - nTotalCompressedSize += CompressedSize; - } - } - else - { - m_nRouteInfo = nRoute; - m_pRouteInfo = (char *)calloc(sizeof(char), nRoute); - memcpy(m_pRouteInfo, pRoute, nRoute); - m_pNodes[ iFrom ].m_pNextBestNode[iHull][iCap] = 0; - nTotalCompressedSize += CompressedSize; - } - } - } - } - ALERT( at_aiconsole, "Size of Routes = %d\n", nTotalCompressedSize); - } - if (Routes) delete Routes; - if (BestNextNodes) delete BestNextNodes; - if (pRoute) delete pRoute; - if (pMyPath) delete pMyPath; - Routes = 0; - BestNextNodes = 0; - pRoute = 0; - pMyPath = 0; - -#if 0 - TestRoutingTables(); -#endif - m_fRoutingComplete = TRUE; -} - -// Test those routing tables. Doesn't really work, yet. -// -void CGraph :: TestRoutingTables( void ) -{ - int *pMyPath = new int[m_cNodes]; - int *pMyPath2 = new int[m_cNodes]; - if (pMyPath && pMyPath2) - { - for (int iHull = 0; iHull < MAX_NODE_HULLS; iHull++) - { - for (int iCap = 0; iCap < 2; iCap++) - { - int iCapMask; - switch (iCap) - { - case 0: - iCapMask = 0; - break; - - case 1: - iCapMask = bits_CAP_OPEN_DOORS | bits_CAP_AUTO_DOORS | bits_CAP_USE; - break; - } - - for (int iFrom = 0; iFrom < m_cNodes; iFrom++) - { - for (int iTo = 0; iTo < m_cNodes; iTo++) - { - m_fRoutingComplete = FALSE; - int cPathSize1 = FindShortestPath(pMyPath, iFrom, iTo, iHull, iCapMask); - m_fRoutingComplete = TRUE; - int cPathSize2 = FindShortestPath(pMyPath2, iFrom, iTo, iHull, iCapMask); - - // Unless we can look at the entire path, we can verify that it's correct. - // - if (cPathSize2 == MAX_PATH_SIZE) continue; - - // Compare distances. - // -#if 1 - float flDistance1 = 0.0; - int i; - for (i = 0; i < cPathSize1-1; i++) - { - // Find the link from pMyPath[i] to pMyPath[i+1] - // - if (pMyPath[i] == pMyPath[i+1]) continue; - int iVisitNode; - BOOL bFound = FALSE; - for (int iLink = 0; iLink < m_pNodes[pMyPath[i]].m_cNumLinks; iLink++) - { - iVisitNode = INodeLink ( pMyPath[i], iLink ); - if (iVisitNode == pMyPath[i+1]) - { - flDistance1 += m_pLinkPool[ m_pNodes[ pMyPath[i] ].m_iFirstLink + iLink].m_flWeight; - bFound = TRUE; - break; - } - } - if (!bFound) - { - ALERT(at_aiconsole, "No link.\n"); - } - } - - float flDistance2 = 0.0; - for (i = 0; i < cPathSize2-1; i++) - { - // Find the link from pMyPath2[i] to pMyPath2[i+1] - // - if (pMyPath2[i] == pMyPath2[i+1]) continue; - int iVisitNode; - BOOL bFound = FALSE; - for (int iLink = 0; iLink < m_pNodes[pMyPath2[i]].m_cNumLinks; iLink++) - { - iVisitNode = INodeLink ( pMyPath2[i], iLink ); - if (iVisitNode == pMyPath2[i+1]) - { - flDistance2 += m_pLinkPool[ m_pNodes[ pMyPath2[i] ].m_iFirstLink + iLink].m_flWeight; - bFound = TRUE; - break; - } - } - if (!bFound) - { - ALERT(at_aiconsole, "No link.\n"); - } - } - if (fabs(flDistance1 - flDistance2) > 0.10) - { -#else - if (cPathSize1 != cPathSize2 || memcmp(pMyPath, pMyPath2, sizeof(int)*cPathSize1) != 0) - { -#endif - ALERT(at_aiconsole, "Routing is inconsistent!!!\n"); - ALERT(at_aiconsole, "(%d to %d |%d/%d)1:", iFrom, iTo, iHull, iCap); - for (int i = 0; i < cPathSize1; i++) - { - ALERT(at_aiconsole, "%d ", pMyPath[i]); - } - ALERT(at_aiconsole, "\n(%d to %d |%d/%d)2:", iFrom, iTo, iHull, iCap); - for (i = 0; i < cPathSize2; i++) - { - ALERT(at_aiconsole, "%d ", pMyPath2[i]); - } - ALERT(at_aiconsole, "\n"); - m_fRoutingComplete = FALSE; - cPathSize1 = FindShortestPath(pMyPath, iFrom, iTo, iHull, iCapMask); - m_fRoutingComplete = TRUE; - cPathSize2 = FindShortestPath(pMyPath2, iFrom, iTo, iHull, iCapMask); - goto EnoughSaid; - } - } - } - } - } - } - -EnoughSaid: - - if (pMyPath) delete pMyPath; - if (pMyPath2) delete pMyPath2; - pMyPath = 0; - pMyPath2 = 0; -} - - - - - - - - - -//========================================================= -// CNodeViewer - Draws a graph of the shorted path from all nodes -// to current location (typically the player). It then draws -// as many connects as it can per frame, trying not to overflow the buffer -//========================================================= -class CNodeViewer : public CBaseEntity -{ -public: - void Spawn( void ); - - int m_iBaseNode; - int m_iDraw; - int m_nVisited; - int m_aFrom[128]; - int m_aTo[128]; - int m_iHull; - int m_afNodeType; - Vector m_vecColor; - - void FindNodeConnections( int iNode ); - void AddNode( int iFrom, int iTo ); - void EXPORT DrawThink( void ); - -}; -LINK_ENTITY_TO_CLASS( node_viewer, CNodeViewer ); -LINK_ENTITY_TO_CLASS( node_viewer_human, CNodeViewer ); -LINK_ENTITY_TO_CLASS( node_viewer_fly, CNodeViewer ); -LINK_ENTITY_TO_CLASS( node_viewer_large, CNodeViewer ); - -void CNodeViewer::Spawn( ) -{ - if ( !WorldGraph.m_fGraphPresent || !WorldGraph.m_fGraphPointersSet ) - {// protect us in the case that the node graph isn't available or built - ALERT ( at_console, "Graph not ready!\n" ); - UTIL_Remove( this ); - return; - } - - - if (FClassnameIs( pev, "node_viewer_fly")) - { - m_iHull = NODE_FLY_HULL; - m_afNodeType = bits_NODE_AIR; - m_vecColor = Vector( 160, 100, 255 ); - } - else if (FClassnameIs( pev, "node_viewer_large")) - { - m_iHull = NODE_LARGE_HULL; - m_afNodeType = bits_NODE_LAND | bits_NODE_WATER; - m_vecColor = Vector( 100, 255, 160 ); - } - else - { - m_iHull = NODE_HUMAN_HULL; - m_afNodeType = bits_NODE_LAND | bits_NODE_WATER; - m_vecColor = Vector( 255, 160, 100 ); - } - - - m_iBaseNode = WorldGraph.FindNearestNode ( pev->origin, m_afNodeType ); - - if ( m_iBaseNode < 0 ) - { - ALERT( at_console, "No nearby node\n" ); - return; - } - - m_nVisited = 0; - - ALERT( at_aiconsole, "basenode %d\n", m_iBaseNode ); - - if (WorldGraph.m_cNodes < 128) - { - for (int i = 0; i < WorldGraph.m_cNodes; i++) - { - AddNode( i, WorldGraph.NextNodeInRoute( i, m_iBaseNode, m_iHull, 0 )); - } - } - else - { - // do a depth traversal - FindNodeConnections( m_iBaseNode ); - - int start = 0; - int end; - do { - end = m_nVisited; - // ALERT( at_console, "%d :", m_nVisited ); - for (end = m_nVisited; start < end; start++) - { - FindNodeConnections( m_aFrom[start] ); - FindNodeConnections( m_aTo[start] ); - } - } while (end != m_nVisited); - } - - ALERT( at_aiconsole, "%d nodes\n", m_nVisited ); - - m_iDraw = 0; - SetThink( &CNodeViewer::DrawThink ); - pev->nextthink = gpGlobals->time; -} - - -void CNodeViewer :: FindNodeConnections ( int iNode ) -{ - AddNode( iNode, WorldGraph.NextNodeInRoute( iNode, m_iBaseNode, m_iHull, 0 )); - for ( int i = 0 ; i < WorldGraph.m_pNodes[ iNode ].m_cNumLinks ; i++ ) - { - CLink *pToLink = &WorldGraph.NodeLink( iNode, i); - AddNode( pToLink->m_iDestNode, WorldGraph.NextNodeInRoute( pToLink->m_iDestNode, m_iBaseNode, m_iHull, 0 )); - } -} - -void CNodeViewer::AddNode( int iFrom, int iTo ) -{ - if (m_nVisited >= 128) - { - return; - } - else - { - if (iFrom == iTo) - return; - - for (int i = 0; i < m_nVisited; i++) - { - if (m_aFrom[i] == iFrom && m_aTo[i] == iTo) - return; - if (m_aFrom[i] == iTo && m_aTo[i] == iFrom) - return; - } - m_aFrom[m_nVisited] = iFrom; - m_aTo[m_nVisited] = iTo; - m_nVisited++; - } -} - - -void CNodeViewer :: DrawThink( void ) -{ - pev->nextthink = gpGlobals->time; - - for (int i = 0; i < 10; i++) - { - if (m_iDraw == m_nVisited) - { - UTIL_Remove( this ); - return; - } - - extern short g_sModelIndexLaser; - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_BEAMPOINTS ); - WRITE_COORD( WorldGraph.m_pNodes[ m_aFrom[m_iDraw] ].m_vecOrigin.x ); - WRITE_COORD( WorldGraph.m_pNodes[ m_aFrom[m_iDraw] ].m_vecOrigin.y ); - WRITE_COORD( WorldGraph.m_pNodes[ m_aFrom[m_iDraw] ].m_vecOrigin.z + NODE_HEIGHT ); - - WRITE_COORD( WorldGraph.m_pNodes[ m_aTo[m_iDraw] ].m_vecOrigin.x ); - WRITE_COORD( WorldGraph.m_pNodes[ m_aTo[m_iDraw] ].m_vecOrigin.y ); - WRITE_COORD( WorldGraph.m_pNodes[ m_aTo[m_iDraw] ].m_vecOrigin.z + NODE_HEIGHT ); - WRITE_SHORT( g_sModelIndexLaser ); - WRITE_BYTE( 0 ); // framerate - WRITE_BYTE( 0 ); // framerate - WRITE_BYTE( 250 ); // life - WRITE_BYTE( 40 ); // width - WRITE_BYTE( 0 ); // noise - WRITE_BYTE( m_vecColor.x ); // r, g, b - WRITE_BYTE( m_vecColor.y ); // r, g, b - WRITE_BYTE( m_vecColor.z ); // r, g, b - WRITE_BYTE( 128 ); // brightness - WRITE_BYTE( 0 ); // speed - MESSAGE_END(); - - m_iDraw++; - } -} - - diff --git a/dmc/dlls/nodes.h b/dmc/dlls/nodes.h deleted file mode 100644 index 269fe42..0000000 --- a/dmc/dlls/nodes.h +++ /dev/null @@ -1,374 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -//========================================================= -// nodes.h -//========================================================= - -//========================================================= -// DEFINE -//========================================================= -#define MAX_STACK_NODES 100 -#define NO_NODE -1 -#define MAX_NODE_HULLS 4 - -#define bits_NODE_LAND ( 1 << 0 ) // Land node, so nudge if necessary. -#define bits_NODE_AIR ( 1 << 1 ) // Air node, don't nudge. -#define bits_NODE_WATER ( 1 << 2 ) // Water node, don't nudge. -#define bits_NODE_GROUP_REALM (bits_NODE_LAND | bits_NODE_AIR | bits_NODE_WATER) - -//========================================================= -// Instance of a node. -//========================================================= -class CNode -{ -public: - Vector m_vecOrigin;// location of this node in space - Vector m_vecOriginPeek; // location of this node (LAND nodes are NODE_HEIGHT higher). - BYTE m_Region[3]; // Which of 256 regions do each of the coordinate belong? - int m_afNodeInfo;// bits that tell us more about this location - - int m_cNumLinks; // how many links this node has - int m_iFirstLink;// index of this node's first link in the link pool. - - // Where to start looking in the compressed routing table (offset into m_pRouteInfo). - // (4 hull sizes -- smallest to largest + fly/swim), and secondly, door capability. - // - int m_pNextBestNode[MAX_NODE_HULLS][2]; - - // Used in finding the shortest path. m_fClosestSoFar is -1 if not visited. - // Then it is the distance to the source. If another path uses this node - // and has a closer distance, then m_iPreviousNode is also updated. - // - float m_flClosestSoFar; // Used in finding the shortest path. - int m_iPreviousNode; - - short m_sHintType;// there is something interesting in the world at this node's position - short m_sHintActivity;// there is something interesting in the world at this node's position - float m_flHintYaw;// monster on this node should face this yaw to face the hint. -}; - -//========================================================= -// CLink - A link between 2 nodes -//========================================================= -#define bits_LINK_SMALL_HULL ( 1 << 0 )// headcrab box can fit through this connection -#define bits_LINK_HUMAN_HULL ( 1 << 1 )// player box can fit through this connection -#define bits_LINK_LARGE_HULL ( 1 << 2 )// big box can fit through this connection -#define bits_LINK_FLY_HULL ( 1 << 3 )// a flying big box can fit through this connection -#define bits_LINK_DISABLED ( 1 << 4 )// link is not valid when the set - -#define NODE_SMALL_HULL 0 -#define NODE_HUMAN_HULL 1 -#define NODE_LARGE_HULL 2 -#define NODE_FLY_HULL 3 - -class CLink -{ -public: - int m_iSrcNode;// the node that 'owns' this link ( keeps us from having to make reverse lookups ) - int m_iDestNode;// the node on the other end of the link. - - entvars_t *m_pLinkEnt;// the entity that blocks this connection (doors, etc) - - // m_szLinkEntModelname is not necessarily NULL terminated (so we can store it in a more alignment-friendly 4 bytes) - char m_szLinkEntModelname[ 4 ];// the unique name of the brush model that blocks the connection (this is kept for save/restore) - - int m_afLinkInfo;// information about this link - float m_flWeight;// length of the link line segment -}; - - -typedef struct -{ - int m_SortedBy[3]; - int m_CheckedEvent; -} DIST_INFO; - -typedef struct -{ - Vector v; - short n; // Nearest node or -1 if no node found. -} CACHE_ENTRY; - -//========================================================= -// CGraph -//========================================================= -#define GRAPH_VERSION (int)16// !!!increment this whever graph/node/link classes change, to obsolesce older disk files. -class CGraph -{ -public: - -// the graph has two flags, and should not be accessed unless both flags are TRUE! - BOOL m_fGraphPresent;// is the graph in memory? - BOOL m_fGraphPointersSet;// are the entity pointers for the graph all set? - BOOL m_fRoutingComplete; // are the optimal routes computed, yet? - - CNode *m_pNodes;// pointer to the memory block that contains all node info - CLink *m_pLinkPool;// big list of all node connections - char *m_pRouteInfo; // compressed routing information the nodes use. - - int m_cNodes;// total number of nodes - int m_cLinks;// total number of links - int m_nRouteInfo; // size of m_pRouteInfo in bytes. - - // Tables for making nearest node lookup faster. SortedBy provided nodes in a - // order of a particular coordinate. Instead of doing a binary search, RangeStart - // and RangeEnd let you get to the part of SortedBy that you are interested in. - // - // Once you have a point of interest, the only way you'll find a closer point is - // if at least one of the coordinates is closer than the ones you have now. So we - // search each range. After the search is exhausted, we know we have the closest - // node. - // -#define CACHE_SIZE 128 -#define NUM_RANGES 256 - DIST_INFO *m_di; // This is m_cNodes long, but the entries don't correspond to CNode entries. - int m_RangeStart[3][NUM_RANGES]; - int m_RangeEnd[3][NUM_RANGES]; - float m_flShortest; - int m_iNearest; - int m_minX, m_minY, m_minZ, m_maxX, m_maxY, m_maxZ; - int m_minBoxX, m_minBoxY, m_minBoxZ, m_maxBoxX, m_maxBoxY, m_maxBoxZ; - int m_CheckedCounter; - float m_RegionMin[3], m_RegionMax[3]; // The range of nodes. - CACHE_ENTRY m_Cache[CACHE_SIZE]; - - - int m_HashPrimes[16]; - short *m_pHashLinks; - int m_nHashLinks; - - - // kinda sleazy. In order to allow variety in active idles for monster groups in a room with more than one node, - // we keep track of the last node we searched from and store it here. Subsequent searches by other monsters will pick - // up where the last search stopped. - int m_iLastActiveIdleSearch; - - // another such system used to track the search for cover nodes, helps greatly with two monsters trying to get to the same node. - int m_iLastCoverSearch; - - // functions to create the graph - int LinkVisibleNodes ( CLink *pLinkPool, FILE *file, int *piBadNode ); - int RejectInlineLinks ( CLink *pLinkPool, FILE *file ); - int FindShortestPath ( int *piPath, int iStart, int iDest, int iHull, int afCapMask); - int FindNearestNode ( const Vector &vecOrigin, CBaseEntity *pEntity ); - int FindNearestNode ( const Vector &vecOrigin, int afNodeTypes ); - //int FindNearestLink ( const Vector &vecTestPoint, int *piNearestLink, BOOL *pfAlongLine ); - float PathLength( int iStart, int iDest, int iHull, int afCapMask ); - int NextNodeInRoute( int iCurrentNode, int iDest, int iHull, int iCap ); - - enum NODEQUERY { NODEGRAPH_DYNAMIC, NODEGRAPH_STATIC }; - // A static query means we're asking about the possiblity of handling this entity at ANY time - // A dynamic query means we're asking about it RIGHT NOW. So we should query the current state - int HandleLinkEnt ( int iNode, entvars_t *pevLinkEnt, int afCapMask, NODEQUERY queryType ); - entvars_t* LinkEntForLink ( CLink *pLink, CNode *pNode ); - void ShowNodeConnections ( int iNode ); - void InitGraph( void ); - int AllocNodes ( void ); - - int CheckNODFile(char *szMapName); - int FLoadGraph(char *szMapName); - int FSaveGraph(char *szMapName); - int FSetGraphPointers(void); - void CheckNode(Vector vecOrigin, int iNode); - - void BuildRegionTables(void); - void ComputeStaticRoutingTables(void); - void TestRoutingTables(void); - - void HashInsert(int iSrcNode, int iDestNode, int iKey); - void HashSearch(int iSrcNode, int iDestNode, int &iKey); - void HashChoosePrimes(int TableSize); - void BuildLinkLookups(void); - - void SortNodes(void); - - int HullIndex( const CBaseEntity *pEntity ); // what hull the monster uses - int NodeType( const CBaseEntity *pEntity ); // what node type the monster uses - inline int CapIndex( int afCapMask ) - { - if (afCapMask & (bits_CAP_OPEN_DOORS | bits_CAP_AUTO_DOORS | bits_CAP_USE)) - return 1; - return 0; - } - - - inline CNode &Node( int i ) - { -#ifdef _DEBUG - if ( !m_pNodes || i < 0 || i > m_cNodes ) - ALERT( at_error, "Bad Node!\n" ); -#endif - return m_pNodes[i]; - } - - inline CLink &Link( int i ) - { -#ifdef _DEBUG - if ( !m_pLinkPool || i < 0 || i > m_cLinks ) - ALERT( at_error, "Bad link!\n" ); -#endif - return m_pLinkPool[i]; - } - - inline CLink &NodeLink( int iNode, int iLink ) - { - return Link( Node( iNode ).m_iFirstLink + iLink ); - } - - inline CLink &NodeLink( const CNode &node, int iLink ) - { - return Link( node.m_iFirstLink + iLink ); - } - - inline int INodeLink ( int iNode, int iLink ) - { - return NodeLink( iNode, iLink ).m_iDestNode; - } - -#if 0 - inline CNode &SourceNode( int iNode, int iLink ) - { - return Node( NodeLink( iNode, iLink ).m_iSrcNode ); - } - - inline CNode &DestNode( int iNode, int iLink ) - { - return Node( NodeLink( iNode, iLink ).m_iDestNode ); - } - - inline CNode *PNodeLink ( int iNode, int iLink ) - { - return &DestNode( iNode, iLink ); - } -#endif -}; - -//========================================================= -// Nodes start out as ents in the level. The node graph -// is built, then these ents are discarded. -//========================================================= -class CNodeEnt : public CBaseEntity -{ - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - short m_sHintType; - short m_sHintActivity; -}; - - -//========================================================= -// CStack - last in, first out. -//========================================================= -class CStack -{ -public: - CStack( void ); - void Push( int value ); - int Pop( void ); - int Top( void ); - int Empty( void ) { return m_level==0; } - int Size( void ) { return m_level; } - void CopyToArray ( int *piArray ); - -private: - int m_stack[ MAX_STACK_NODES ]; - int m_level; -}; - - -//========================================================= -// CQueue - first in, first out. -//========================================================= -class CQueue -{ -public: - - CQueue( void );// constructor - inline int Full ( void ) { return ( m_cSize == MAX_STACK_NODES ); } - inline int Empty ( void ) { return ( m_cSize == 0 ); } - //inline int Tail ( void ) { return ( m_queue[ m_tail ] ); } - inline int Size ( void ) { return ( m_cSize ); } - void Insert( int, float ); - int Remove( float & ); - -private: - int m_cSize; - struct tag_QUEUE_NODE - { - int Id; - float Priority; - } m_queue[ MAX_STACK_NODES ]; - int m_head; - int m_tail; -}; - -//========================================================= -// CQueuePriority - Priority queue (smallest item out first). -// -//========================================================= -class CQueuePriority -{ -public: - - CQueuePriority( void );// constructor - inline int Full ( void ) { return ( m_cSize == MAX_STACK_NODES ); } - inline int Empty ( void ) { return ( m_cSize == 0 ); } - //inline int Tail ( float & ) { return ( m_queue[ m_tail ].Id ); } - inline int Size ( void ) { return ( m_cSize ); } - void Insert( int, float ); - int Remove( float &); - -private: - int m_cSize; - struct tag_HEAP_NODE - { - int Id; - float Priority; - } m_heap[ MAX_STACK_NODES ]; - void Heap_SiftDown(int); - void Heap_SiftUp(void); - -}; - -//========================================================= -// hints - these MUST coincide with the HINTS listed under -// info_node in the FGD file! -//========================================================= -enum -{ - HINT_NONE = 0, - HINT_WORLD_DOOR, - HINT_WORLD_WINDOW, - HINT_WORLD_BUTTON, - HINT_WORLD_MACHINERY, - HINT_WORLD_LEDGE, - HINT_WORLD_LIGHT_SOURCE, - HINT_WORLD_HEAT_SOURCE, - HINT_WORLD_BLINKING_LIGHT, - HINT_WORLD_BRIGHT_COLORS, - HINT_WORLD_HUMAN_BLOOD, - HINT_WORLD_ALIEN_BLOOD, - - HINT_TACTICAL_EXIT = 100, - HINT_TACTICAL_VANTAGE, - HINT_TACTICAL_AMBUSH, - - HINT_STUKA_PERCH = 300, - HINT_STUKA_LANDING, -}; - -extern CGraph WorldGraph; diff --git a/dmc/dlls/observer.cpp b/dmc/dlls/observer.cpp deleted file mode 100644 index 2fe0ee2..0000000 --- a/dmc/dlls/observer.cpp +++ /dev/null @@ -1,142 +0,0 @@ -//=========== (C) Copyright 1996-2002, Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Functionality for the observer chase camera -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "pm_shared.h" - -// Find the next client in the game for this player to spectate -void CBasePlayer::Observer_FindNextPlayer() -{ - // MOD AUTHORS: Modify the logic of this function if you want to restrict the observer to watching - // only a subset of the players. e.g. Make it check the target's team. - - CBaseEntity *client = m_hObserverTarget; - while ( (client = (CBaseEntity*)UTIL_FindEntityByClassname( client, "player" )) != m_hObserverTarget ) - { - if ( !client ) - continue; - if ( !client->pev ) - continue; - if ( client == this ) - continue; - - // Add checks on target here. - - m_hObserverTarget = client; - break; - } - - // Did we find a target? - if ( m_hObserverTarget ) - { - // Store the target in pev so the physics DLL can get to it - if (pev->iuser1 != OBS_ROAMING) - pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); - // Move to the target - UTIL_SetOrigin( pev, m_hObserverTarget->pev->origin ); - - ALERT( at_console, "Now Tracking %s\n", STRING( m_hObserverTarget->pev->classname ) ); - } - else - { - ALERT( at_console, "No observer targets.\n" ); - } -} - -// Handle buttons in observer mode -void CBasePlayer::Observer_HandleButtons() -{ - // Slow down mouse clicks - if ( m_flNextObserverInput > gpGlobals->time ) - return; - - // Jump changes from modes: Chase to Roaming - if ( m_afButtonPressed & IN_JUMP ) - { - if ( pev->iuser1 == OBS_CHASE_LOCKED ) - Observer_SetMode( OBS_CHASE_FREE ); - - else if ( pev->iuser1 == OBS_CHASE_FREE ) - Observer_SetMode( OBS_ROAMING ); - - else if ( pev->iuser1 == OBS_ROAMING ) - Observer_SetMode( OBS_IN_EYE ); - - else if ( pev->iuser1 == OBS_IN_EYE ) - Observer_SetMode( OBS_MAP_FREE ); - - else if ( pev->iuser1 == OBS_MAP_FREE ) - Observer_SetMode( OBS_MAP_CHASE ); - - else - Observer_SetMode( OBS_CHASE_FREE ); // don't use OBS_CHASE_LOCKED anymore - - m_flNextObserverInput = gpGlobals->time + 0.2; - } - - // Attack moves to the next player - if ( m_afButtonPressed & IN_ATTACK ) - { - Observer_FindNextPlayer(); - - m_flNextObserverInput = gpGlobals->time + 0.2; - } - -} - -// Attempt to change the observer mode -void CBasePlayer::Observer_SetMode( int iMode ) -{ - // Just abort if we're changing to the mode we're already in - if ( iMode == pev->iuser1 ) - return; - - // is valid mode ? - if ( iMode < OBS_CHASE_LOCKED || iMode > OBS_MAP_CHASE ) - iMode = OBS_IN_EYE; // now it is - - // if we are not roaming, we need a valid target to track - if ( (iMode != OBS_ROAMING) && (m_hObserverTarget == NULL) ) - { - Observer_FindNextPlayer(); - - // if we didn't find a valid target switch to roaming - if (m_hObserverTarget == NULL) - { - ClientPrint( pev, HUD_PRINTCENTER, "#Spec_NoTarget" ); - iMode = OBS_ROAMING; - } - } - - // set spectator mode - pev->iuser1 = iMode; - - // set target if not roaming - if (iMode == OBS_ROAMING) - pev->iuser2 = 0; - else - pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); - - // print spepctaor mode on client screen - - char modemsg[16]; - sprintf(modemsg,"#Spec_Mode%i", iMode); - ClientPrint( pev, HUD_PRINTCENTER, modemsg ); -} diff --git a/dmc/dlls/pathcorner.cpp b/dmc/dlls/pathcorner.cpp deleted file mode 100644 index b2c1e3f..0000000 --- a/dmc/dlls/pathcorner.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// ========================== PATH_CORNER =========================== -// - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "trains.h" -#include "saverestore.h" - -class CPathCorner : public CPointEntity -{ -public: - void Spawn( ); - void KeyValue( KeyValueData* pkvd ); - float GetDelay( void ) { return m_flWait; } -// void Touch( CBaseEntity *pOther ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - float m_flWait; -}; - -LINK_ENTITY_TO_CLASS( path_corner, CPathCorner ); - -// Global Savedata for Delay -TYPEDESCRIPTION CPathCorner::m_SaveData[] = -{ - DEFINE_FIELD( CPathCorner, m_flWait, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CPathCorner, CPointEntity ); - -// -// Cache user-entity-field values until spawn is called. -// -void CPathCorner :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -void CPathCorner :: Spawn( ) -{ - ASSERTSZ(!FStringNull(pev->targetname), "path_corner without a targetname"); -} - -#if 0 -void CPathCorner :: Touch( CBaseEntity *pOther ) -{ - entvars_t* pevToucher = pOther->pev; - - if ( FBitSet ( pevToucher->flags, FL_MONSTER ) ) - {// monsters don't navigate path corners based on touch anymore - return; - } - - // If OTHER isn't explicitly looking for this path_corner, bail out - if ( pOther->m_pGoalEnt != this ) - { - return; - } - - // If OTHER has an enemy, this touch is incidental, ignore - if ( !FNullEnt(pevToucher->enemy) ) - { - return; // fighting, not following a path - } - - // UNDONE: support non-zero flWait - /* - if (m_flWait != 0) - ALERT(at_warning, "Non-zero path-cornder waits NYI"); - */ - - // Find the next "stop" on the path, make it the goal of the "toucher". - if (FStringNull(pev->target)) - { - ALERT(at_warning, "PathCornerTouch: no next stop specified"); - } - - pOther->m_pGoalEnt = CBaseEntity::Instance( FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(pev->target) ) ); - - // If "next spot" was not found (does not exist - level design error) - if ( !pOther->m_pGoalEnt ) - { - ALERT(at_console, "PathCornerTouch--%s couldn't find next stop in path: %s", STRING(pev->classname), STRING(pev->target)); - return; - } - - // Turn towards the next stop in the path. - pevToucher->ideal_yaw = UTIL_VecToYaw ( pOther->m_pGoalEnt->pev->origin - pevToucher->origin ); -} -#endif - - - -TYPEDESCRIPTION CPathTrack::m_SaveData[] = -{ - DEFINE_FIELD( CPathTrack, m_length, FIELD_FLOAT ), - DEFINE_FIELD( CPathTrack, m_pnext, FIELD_CLASSPTR ), - DEFINE_FIELD( CPathTrack, m_paltpath, FIELD_CLASSPTR ), - DEFINE_FIELD( CPathTrack, m_pprevious, FIELD_CLASSPTR ), - DEFINE_FIELD( CPathTrack, m_altName, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CPathTrack, CBaseEntity ); -LINK_ENTITY_TO_CLASS( path_track, CPathTrack ); - -// -// Cache user-entity-field values until spawn is called. -// -void CPathTrack :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "altpath")) - { - m_altName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -void CPathTrack :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int on; - - // Use toggles between two paths - if ( m_paltpath ) - { - on = !FBitSet( pev->spawnflags, SF_PATH_ALTERNATE ); - if ( ShouldToggle( useType, on ) ) - { - if ( on ) - SetBits( pev->spawnflags, SF_PATH_ALTERNATE ); - else - ClearBits( pev->spawnflags, SF_PATH_ALTERNATE ); - } - } - else // Use toggles between enabled/disabled - { - on = !FBitSet( pev->spawnflags, SF_PATH_DISABLED ); - - if ( ShouldToggle( useType, on ) ) - { - if ( on ) - SetBits( pev->spawnflags, SF_PATH_DISABLED ); - else - ClearBits( pev->spawnflags, SF_PATH_DISABLED ); - } - } -} - - -void CPathTrack :: Link( void ) -{ - edict_t *pentTarget; - - if ( !FStringNull(pev->target) ) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->target) ); - if ( !FNullEnt(pentTarget) ) - { - m_pnext = CPathTrack::Instance( pentTarget ); - - if ( m_pnext ) // If no next pointer, this is the end of a path - { - m_pnext->SetPrevious( this ); - } - } - else - ALERT( at_console, "Dead end link %s\n", STRING(pev->target) ); - } - - // Find "alternate" path - if ( m_altName ) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_altName) ); - if ( !FNullEnt(pentTarget) ) - { - m_paltpath = CPathTrack::Instance( pentTarget ); - - if ( m_paltpath ) // If no next pointer, this is the end of a path - { - m_paltpath->SetPrevious( this ); - } - } - } -} - - -void CPathTrack :: Spawn( void ) -{ - pev->solid = SOLID_TRIGGER; - UTIL_SetSize(pev, Vector(-8, -8, -8), Vector(8, 8, 8)); - - m_pnext = NULL; - m_pprevious = NULL; -// DEBUGGING CODE -#if PATH_SPARKLE_DEBUG - SetThink( Sparkle ); - pev->nextthink = gpGlobals->time + 0.5; -#endif -} - - -void CPathTrack::Activate( void ) -{ - if ( !FStringNull( pev->targetname ) ) // Link to next, and back-link - Link(); -} - -CPathTrack *CPathTrack :: ValidPath( CPathTrack *ppath, int testFlag ) -{ - if ( !ppath ) - return NULL; - - if ( testFlag && FBitSet( ppath->pev->spawnflags, SF_PATH_DISABLED ) ) - return NULL; - - return ppath; -} - - -void CPathTrack :: Project( CPathTrack *pstart, CPathTrack *pend, Vector *origin, float dist ) -{ - if ( pstart && pend ) - { - Vector dir = (pend->pev->origin - pstart->pev->origin); - dir = dir.Normalize(); - *origin = pend->pev->origin + dir * dist; - } -} - -CPathTrack *CPathTrack::GetNext( void ) -{ - if ( m_paltpath && FBitSet( pev->spawnflags, SF_PATH_ALTERNATE ) && !FBitSet( pev->spawnflags, SF_PATH_ALTREVERSE ) ) - return m_paltpath; - - return m_pnext; -} - - - -CPathTrack *CPathTrack::GetPrevious( void ) -{ - if ( m_paltpath && FBitSet( pev->spawnflags, SF_PATH_ALTERNATE ) && FBitSet( pev->spawnflags, SF_PATH_ALTREVERSE ) ) - return m_paltpath; - - return m_pprevious; -} - - - -void CPathTrack::SetPrevious( CPathTrack *pprev ) -{ - // Only set previous if this isn't my alternate path - if ( pprev && !FStrEq( STRING(pprev->pev->targetname), STRING(m_altName) ) ) - m_pprevious = pprev; -} - - -// Assumes this is ALWAYS enabled -CPathTrack *CPathTrack :: LookAhead( Vector *origin, float dist, int move ) -{ - CPathTrack *pcurrent; - float originalDist = dist; - - pcurrent = this; - Vector currentPos = *origin; - - if ( dist < 0 ) // Travelling backwards through path - { - dist = -dist; - while ( dist > 0 ) - { - Vector dir = pcurrent->pev->origin - currentPos; - float length = dir.Length(); - if ( !length ) - { - if ( !ValidPath(pcurrent->GetPrevious(), move) ) // If there is no previous node, or it's disabled, return now. - { - if ( !move ) - Project( pcurrent->GetNext(), pcurrent, origin, dist ); - return NULL; - } - pcurrent = pcurrent->GetPrevious(); - } - else if ( length > dist ) // enough left in this path to move - { - *origin = currentPos + (dir * (dist / length)); - return pcurrent; - } - else - { - dist -= length; - currentPos = pcurrent->pev->origin; - *origin = currentPos; - if ( !ValidPath(pcurrent->GetPrevious(), move) ) // If there is no previous node, or it's disabled, return now. - return NULL; - - pcurrent = pcurrent->GetPrevious(); - } - } - *origin = currentPos; - return pcurrent; - } - else - { - while ( dist > 0 ) - { - if ( !ValidPath(pcurrent->GetNext(), move) ) // If there is no next node, or it's disabled, return now. - { - if ( !move ) - Project( pcurrent->GetPrevious(), pcurrent, origin, dist ); - return NULL; - } - Vector dir = pcurrent->GetNext()->pev->origin - currentPos; - float length = dir.Length(); - if ( !length && !ValidPath( pcurrent->GetNext()->GetNext(), move ) ) - { - if ( dist == originalDist ) // HACK -- up against a dead end - return NULL; - return pcurrent; - } - if ( length > dist ) // enough left in this path to move - { - *origin = currentPos + (dir * (dist / length)); - return pcurrent; - } - else - { - dist -= length; - currentPos = pcurrent->GetNext()->pev->origin; - pcurrent = pcurrent->GetNext(); - *origin = currentPos; - } - } - *origin = currentPos; - } - - return pcurrent; -} - - -// Assumes this is ALWAYS enabled -CPathTrack *CPathTrack :: Nearest( Vector origin ) -{ - int deadCount; - float minDist, dist; - Vector delta; - CPathTrack *ppath, *pnearest; - - - delta = origin - pev->origin; - delta.z = 0; - minDist = delta.Length(); - pnearest = this; - ppath = GetNext(); - - // Hey, I could use the old 2 racing pointers solution to this, but I'm lazy :) - deadCount = 0; - while ( ppath && ppath != this ) - { - deadCount++; - if ( deadCount > 9999 ) - { - ALERT( at_error, "Bad sequence of path_tracks from %s", STRING(pev->targetname) ); - return NULL; - } - delta = origin - ppath->pev->origin; - delta.z = 0; - dist = delta.Length(); - if ( dist < minDist ) - { - minDist = dist; - pnearest = ppath; - } - ppath = ppath->GetNext(); - } - return pnearest; -} - - -CPathTrack *CPathTrack::Instance( edict_t *pent ) -{ - if ( FClassnameIs( pent, "path_track" ) ) - return (CPathTrack *)GET_PRIVATE(pent); - return NULL; -} - - - // DEBUGGING CODE -#if PATH_SPARKLE_DEBUG -void CPathTrack :: Sparkle( void ) -{ - - pev->nextthink = gpGlobals->time + 0.2; - if ( FBitSet( pev->spawnflags, SF_PATH_DISABLED ) ) - UTIL_ParticleEffect(pev->origin, Vector(0,0,100), 210, 10); - else - UTIL_ParticleEffect(pev->origin, Vector(0,0,100), 84, 10); -} -#endif - diff --git a/dmc/dlls/plane.cpp b/dmc/dlls/plane.cpp deleted file mode 100644 index 39a91c3..0000000 --- a/dmc/dlls/plane.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "extdll.h" -#include "plane.h" - -//========================================================= -// Plane -//========================================================= -CPlane :: CPlane ( void ) -{ - m_fInitialized = FALSE; -} - -//========================================================= -// InitializePlane - Takes a normal for the plane and a -// point on the plane and -//========================================================= -void CPlane :: InitializePlane ( const Vector &vecNormal, const Vector &vecPoint ) -{ - m_vecNormal = vecNormal; - m_flDist = DotProduct ( m_vecNormal, vecPoint ); - m_fInitialized = TRUE; -} - - -//========================================================= -// PointInFront - determines whether the given vector is -// in front of the plane. -//========================================================= -BOOL CPlane :: PointInFront ( const Vector &vecPoint ) -{ - float flFace; - - if ( !m_fInitialized ) - { - return FALSE; - } - - flFace = DotProduct ( m_vecNormal, vecPoint ) - m_flDist; - - if ( flFace >= 0 ) - { - return TRUE; - } - - return FALSE; -} - diff --git a/dmc/dlls/plane.h b/dmc/dlls/plane.h deleted file mode 100644 index af70f1c..0000000 --- a/dmc/dlls/plane.h +++ /dev/null @@ -1,43 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef PLANE_H -#define PLANE_H - -//========================================================= -// Plane -//========================================================= -class CPlane -{ -public: - CPlane ( void ); - - //========================================================= - // InitializePlane - Takes a normal for the plane and a - // point on the plane and - //========================================================= - void InitializePlane ( const Vector &vecNormal, const Vector &vecPoint ); - - //========================================================= - // PointInFront - determines whether the given vector is - // in front of the plane. - //========================================================= - BOOL PointInFront ( const Vector &vecPoint ); - - Vector m_vecNormal; - float m_flDist; - BOOL m_fInitialized; -}; - -#endif // PLANE_H diff --git a/dmc/dlls/plats.cpp b/dmc/dlls/plats.cpp deleted file mode 100644 index dd439b9..0000000 --- a/dmc/dlls/plats.cpp +++ /dev/null @@ -1,2285 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== plats.cpp ======================================================== - - spawn, think, and touch functions for trains, etc - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "trains.h" -#include "saverestore.h" - -static void PlatSpawnInsideTrigger(entvars_t* pevPlatform); - -#define SF_PLAT_TOGGLE 0x0001 - -class CBasePlatTrain : public CBaseToggle -{ -public: - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - void KeyValue( KeyValueData* pkvd); - void Precache( void ); - - // This is done to fix spawn flag collisions between this class and a derived class - virtual BOOL IsTogglePlat( void ) { return (pev->spawnflags & SF_PLAT_TOGGLE) ? TRUE : FALSE; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - BYTE m_bMoveSnd; // sound a plat makes while moving - BYTE m_bStopSnd; // sound a plat makes when it stops - float m_volume; // Sound volume -}; - -TYPEDESCRIPTION CBasePlatTrain::m_SaveData[] = -{ - DEFINE_FIELD( CBasePlatTrain, m_bMoveSnd, FIELD_CHARACTER ), - DEFINE_FIELD( CBasePlatTrain, m_bStopSnd, FIELD_CHARACTER ), - DEFINE_FIELD( CBasePlatTrain, m_volume, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CBasePlatTrain, CBaseToggle ); - -void CBasePlatTrain :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "lip")) - { - m_flLip = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "height")) - { - m_flHeight = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "rotation")) - { - m_vecFinalAngle.x = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "movesnd")) - { - m_bMoveSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "stopsnd")) - { - m_bStopSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "volume")) - { - m_volume = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -#define noiseMoving noise -#define noiseArrived noise1 - -void CBasePlatTrain::Precache( void ) -{ -// set the plat's "in-motion" sound - switch (m_bMoveSnd) - { - case 0: - pev->noiseMoving = MAKE_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("plats/bigmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/bigmove1.wav"); - break; - case 2: - PRECACHE_SOUND ("plats/bigmove2.wav"); - pev->noiseMoving = MAKE_STRING("plats/bigmove2.wav"); - break; - case 3: - PRECACHE_SOUND ("plats/elevmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/elevmove1.wav"); - break; - case 4: - PRECACHE_SOUND ("plats/elevmove2.wav"); - pev->noiseMoving = MAKE_STRING("plats/elevmove2.wav"); - break; - case 5: - PRECACHE_SOUND ("plats/elevmove3.wav"); - pev->noiseMoving = MAKE_STRING("plats/elevmove3.wav"); - break; - case 6: - PRECACHE_SOUND ("plats/freightmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/freightmove1.wav"); - break; - case 7: - PRECACHE_SOUND ("plats/freightmove2.wav"); - pev->noiseMoving = MAKE_STRING("plats/freightmove2.wav"); - break; - case 8: - PRECACHE_SOUND ("plats/heavymove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/heavymove1.wav"); - break; - case 9: - PRECACHE_SOUND ("plats/rackmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/rackmove1.wav"); - break; - case 10: - PRECACHE_SOUND ("plats/railmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/railmove1.wav"); - break; - case 11: - PRECACHE_SOUND ("plats/squeekmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/squeekmove1.wav"); - break; - case 12: - PRECACHE_SOUND ("plats/talkmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/talkmove1.wav"); - break; - case 13: - PRECACHE_SOUND ("plats/talkmove2.wav"); - pev->noiseMoving = MAKE_STRING("plats/talkmove2.wav"); - break; - default: - pev->noiseMoving = MAKE_STRING("common/null.wav"); - break; - } - -// set the plat's 'reached destination' stop sound - switch (m_bStopSnd) - { - case 0: - pev->noiseArrived = MAKE_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("plats/bigstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/bigstop1.wav"); - break; - case 2: - PRECACHE_SOUND ("plats/bigstop2.wav"); - pev->noiseArrived = MAKE_STRING("plats/bigstop2.wav"); - break; - case 3: - PRECACHE_SOUND ("plats/freightstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/freightstop1.wav"); - break; - case 4: - PRECACHE_SOUND ("plats/heavystop2.wav"); - pev->noiseArrived = MAKE_STRING("plats/heavystop2.wav"); - break; - case 5: - PRECACHE_SOUND ("plats/rackstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/rackstop1.wav"); - break; - case 6: - PRECACHE_SOUND ("plats/railstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/railstop1.wav"); - break; - case 7: - PRECACHE_SOUND ("plats/squeekstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/squeekstop1.wav"); - break; - case 8: - PRECACHE_SOUND ("plats/talkstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/talkstop1.wav"); - break; - - default: - pev->noiseArrived = MAKE_STRING("common/null.wav"); - break; - } -} - -// -//====================== PLAT code ==================================================== -// - - -#define noiseMovement noise -#define noiseStopMoving noise1 - -class CFuncPlat : public CBasePlatTrain -{ -public: - void Spawn( void ); - void Precache( void ); - void Setup( void ); - - virtual void Blocked( CBaseEntity *pOther ); - - - void EXPORT PlatUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - void EXPORT CallGoDown( void ) { GoDown(); } - void EXPORT CallHitTop( void ) { HitTop(); } - void EXPORT CallHitBottom( void ) { HitBottom(); } - - virtual void GoUp( void ); - virtual void GoDown( void ); - virtual void HitTop( void ); - virtual void HitBottom( void ); -}; -LINK_ENTITY_TO_CLASS( func_plat, CFuncPlat ); - - -// UNDONE: Need to save this!!! It needs class & linkage -class CPlatTrigger : public CBaseEntity -{ -public: - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; } - void SpawnInsideTrigger( CFuncPlat *pPlatform ); - void Touch( CBaseEntity *pOther ); - CFuncPlat *m_pPlatform; -}; - - - -/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER -speed default 150 - -Plats are always drawn in the extended position, so they will light correctly. - -If the plat is the target of another trigger or button, it will start out disabled in -the extended position until it is trigger, when it will lower and become a normal plat. - -If the "height" key is set, that will determine the amount the plat moves, instead of -being implicitly determined by the model's height. - -Set "sounds" to one of the following: -1) base fast -2) chain slow -*/ - -void CFuncPlat :: Setup( void ) -{ - //pev->noiseMovement = MAKE_STRING("plats/platmove1.wav"); - //pev->noiseStopMoving = MAKE_STRING("plats/platstop1.wav"); - - if (m_flTLength == 0) - m_flTLength = 80; - if (m_flTWidth == 0) - m_flTWidth = 10; - - pev->angles = g_vecZero; - - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - UTIL_SetOrigin(pev, pev->origin); // set size and link into world - UTIL_SetSize(pev, pev->mins, pev->maxs); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - // vecPosition1 is the top position, vecPosition2 is the bottom - m_vecPosition1 = pev->origin; - m_vecPosition2 = pev->origin; - if (m_flHeight != 0) - m_vecPosition2.z = pev->origin.z - m_flHeight; - else - m_vecPosition2.z = pev->origin.z - pev->size.z + 8; - if (pev->speed == 0) - pev->speed = 150; - - if ( m_volume == 0 ) - m_volume = 0.85; -} - - -void CFuncPlat :: Precache( ) -{ - CBasePlatTrain::Precache(); - //PRECACHE_SOUND("plats/platmove1.wav"); - //PRECACHE_SOUND("plats/platstop1.wav"); - if ( !IsTogglePlat() ) - PlatSpawnInsideTrigger( pev ); // the "start moving" trigger -} - - -void CFuncPlat :: Spawn( ) -{ - Setup(); - - Precache(); - - // If this platform is the target of some button, it starts at the TOP position, - // and is brought down by that button. Otherwise, it starts at BOTTOM. - if ( !FStringNull(pev->targetname) ) - { - UTIL_SetOrigin (pev, m_vecPosition1); - m_toggle_state = TS_AT_TOP; - SetUse( &CFuncPlat::PlatUse ); - } - else - { - UTIL_SetOrigin (pev, m_vecPosition2); - m_toggle_state = TS_AT_BOTTOM; - } -} - - - -static void PlatSpawnInsideTrigger(entvars_t* pevPlatform) -{ - GetClassPtr( (CPlatTrigger *)NULL)->SpawnInsideTrigger( GetClassPtr( (CFuncPlat *)pevPlatform ) ); -} - - -// -// Create a trigger entity for a platform. -// -void CPlatTrigger :: SpawnInsideTrigger( CFuncPlat *pPlatform ) -{ - m_pPlatform = pPlatform; - // Create trigger entity, "point" it at the owning platform, give it a touch method - pev->solid = SOLID_TRIGGER; - pev->movetype = MOVETYPE_NONE; - pev->origin = pPlatform->pev->origin; - - // Establish the trigger field's size - Vector vecTMin = m_pPlatform->pev->mins + Vector ( 25 , 25 , 0 ); - Vector vecTMax = m_pPlatform->pev->maxs + Vector ( 25 , 25 , 8 ); - vecTMin.z = vecTMax.z - ( m_pPlatform->m_vecPosition1.z - m_pPlatform->m_vecPosition2.z + 8 ); - if (m_pPlatform->pev->size.x <= 50) - { - vecTMin.x = (m_pPlatform->pev->mins.x + m_pPlatform->pev->maxs.x) / 2; - vecTMax.x = vecTMin.x + 1; - } - if (m_pPlatform->pev->size.y <= 50) - { - vecTMin.y = (m_pPlatform->pev->mins.y + m_pPlatform->pev->maxs.y) / 2; - vecTMax.y = vecTMin.y + 1; - } - UTIL_SetSize ( pev, vecTMin, vecTMax ); -} - - -// -// When the platform's trigger field is touched, the platform ??? -// -void CPlatTrigger :: Touch( CBaseEntity *pOther ) -{ - // Ignore touches by non-players - entvars_t* pevToucher = pOther->pev; - if ( !FClassnameIs (pevToucher, "player") ) - return; - - // Ignore touches by corpses - if (!pOther->IsAlive()) - return; - - // Make linked platform go up/down. - if (m_pPlatform->m_toggle_state == TS_AT_BOTTOM) - m_pPlatform->GoUp(); - else if (m_pPlatform->m_toggle_state == TS_AT_TOP) - m_pPlatform->pev->nextthink = m_pPlatform->pev->ltime + 1;// delay going down -} - - -// -// Used by SUB_UseTargets, when a platform is the target of a button. -// Start bringing platform down. -// -void CFuncPlat :: PlatUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( IsTogglePlat() ) - { - // Top is off, bottom is on - BOOL on = (m_toggle_state == TS_AT_BOTTOM) ? TRUE : FALSE; - - if ( !ShouldToggle( useType, on ) ) - return; - - if (m_toggle_state == TS_AT_TOP) - GoDown(); - else if ( m_toggle_state == TS_AT_BOTTOM ) - GoUp(); - } - else - { - SetUse( NULL ); - - if (m_toggle_state == TS_AT_TOP) - GoDown(); - } -} - - -// -// Platform is at top, now starts moving down. -// -void CFuncPlat :: GoDown( void ) -{ - if(pev->noiseMovement) - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement), m_volume, ATTN_NORM); - - ASSERT(m_toggle_state == TS_AT_TOP || m_toggle_state == TS_GOING_UP); - m_toggle_state = TS_GOING_DOWN; - SetMoveDone(&CFuncPlat::CallHitBottom); - LinearMove(m_vecPosition2, pev->speed); -} - - -// -// Platform has hit bottom. Stops and waits forever. -// -void CFuncPlat :: HitBottom( void ) -{ - if(pev->noiseMovement) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement)); - - if (pev->noiseStopMoving) - EMIT_SOUND(ENT(pev), CHAN_WEAPON, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - - ASSERT(m_toggle_state == TS_GOING_DOWN); - m_toggle_state = TS_AT_BOTTOM; -} - - -// -// Platform is at bottom, now starts moving up -// -void CFuncPlat :: GoUp( void ) -{ - if (pev->noiseMovement) - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement), m_volume, ATTN_NORM); - - ASSERT(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN); - m_toggle_state = TS_GOING_UP; - SetMoveDone(&CFuncPlat::CallHitTop); - LinearMove(m_vecPosition1, pev->speed); -} - - -// -// Platform has hit top. Pauses, then starts back down again. -// -void CFuncPlat :: HitTop( void ) -{ - if(pev->noiseMovement) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement)); - - if (pev->noiseStopMoving) - EMIT_SOUND(ENT(pev), CHAN_WEAPON, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - - ASSERT(m_toggle_state == TS_GOING_UP); - m_toggle_state = TS_AT_TOP; - - if ( !IsTogglePlat() ) - { - // After a delay, the platform will automatically start going down again. - SetThink( &CFuncPlat::CallGoDown ); - pev->nextthink = pev->ltime + 3; - } -} - - -void CFuncPlat :: Blocked( CBaseEntity *pOther ) -{ - ALERT( at_aiconsole, "%s Blocked by %s\n", STRING(pev->classname), STRING(pOther->pev->classname) ); - // Hurt the blocker a little - pOther->TakeDamage(pev, pev, 1, DMG_CRUSH); - - if(pev->noiseMovement) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement)); - - // Send the platform back where it came from - ASSERT(m_toggle_state == TS_GOING_UP || m_toggle_state == TS_GOING_DOWN); - if (m_toggle_state == TS_GOING_UP) - GoDown(); - else if (m_toggle_state == TS_GOING_DOWN) - GoUp (); -} - - -class CFuncPlatRot : public CFuncPlat -{ -public: - void Spawn( void ); - void SetupRotation( void ); - - virtual void GoUp( void ); - virtual void GoDown( void ); - virtual void HitTop( void ); - virtual void HitBottom( void ); - - void RotMove( Vector &destAngle, float time ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - Vector m_end, m_start; -}; -LINK_ENTITY_TO_CLASS( func_platrot, CFuncPlatRot ); -TYPEDESCRIPTION CFuncPlatRot::m_SaveData[] = -{ - DEFINE_FIELD( CFuncPlatRot, m_end, FIELD_VECTOR ), - DEFINE_FIELD( CFuncPlatRot, m_start, FIELD_VECTOR ), -}; - -IMPLEMENT_SAVERESTORE( CFuncPlatRot, CFuncPlat ); - - -void CFuncPlatRot :: SetupRotation( void ) -{ - if ( m_vecFinalAngle.x != 0 ) // This plat rotates too! - { - CBaseToggle :: AxisDir( pev ); - m_start = pev->angles; - m_end = pev->angles + pev->movedir * m_vecFinalAngle.x; - } - else - { - m_start = g_vecZero; - m_end = g_vecZero; - } - if ( !FStringNull(pev->targetname) ) // Start at top - { - pev->angles = m_end; - } -} - - -void CFuncPlatRot :: Spawn( void ) -{ - CFuncPlat :: Spawn(); - SetupRotation(); -} - -void CFuncPlatRot :: GoDown( void ) -{ - CFuncPlat :: GoDown(); - RotMove( m_start, pev->nextthink - pev->ltime ); -} - - -// -// Platform has hit bottom. Stops and waits forever. -// -void CFuncPlatRot :: HitBottom( void ) -{ - CFuncPlat :: HitBottom(); - pev->avelocity = g_vecZero; - pev->angles = m_start; -} - - -// -// Platform is at bottom, now starts moving up -// -void CFuncPlatRot :: GoUp( void ) -{ - CFuncPlat :: GoUp(); - RotMove( m_end, pev->nextthink - pev->ltime ); -} - - -// -// Platform has hit top. Pauses, then starts back down again. -// -void CFuncPlatRot :: HitTop( void ) -{ - CFuncPlat :: HitTop(); - pev->avelocity = g_vecZero; - pev->angles = m_end; -} - - -void CFuncPlatRot :: RotMove( Vector &destAngle, float time ) -{ - // set destdelta to the vector needed to move - Vector vecDestDelta = destAngle - pev->angles; - - // Travel time is so short, we're practically there already; so make it so. - if ( time >= 0.1) - pev->avelocity = vecDestDelta / time; - else - { - pev->avelocity = vecDestDelta; - pev->nextthink = pev->ltime + 1; - } -} - - -// -//====================== TRAIN code ================================================== -// - -class CFuncTrain : public CBasePlatTrain -{ -public: - void Spawn( void ); - void Precache( void ); - void Activate( void ); - void OverrideReset( void ); - - void Blocked( CBaseEntity *pOther ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - - void EXPORT Wait( void ); - void EXPORT Next( void ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - entvars_t *m_pevCurrentTarget; - int m_sounds; - BOOL m_activated; -}; - -LINK_ENTITY_TO_CLASS( func_train, CFuncTrain ); -TYPEDESCRIPTION CFuncTrain::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTrain, m_sounds, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTrain, m_pevCurrentTarget, FIELD_EVARS ), - DEFINE_FIELD( CFuncTrain, m_activated, FIELD_BOOLEAN ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTrain, CBasePlatTrain ); - - -void CFuncTrain :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBasePlatTrain::KeyValue( pkvd ); -} - - -void CFuncTrain :: Blocked( CBaseEntity *pOther ) - -{ - if ( gpGlobals->time < m_flActivateFinished) - return; - - m_flActivateFinished = gpGlobals->time + 0.5; - - pOther->TakeDamage(pev, pev, pev->dmg, DMG_CRUSH); -} - - -void CFuncTrain :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->spawnflags & SF_TRAIN_WAIT_RETRIGGER ) - { - // Move toward my target - pev->spawnflags &= ~SF_TRAIN_WAIT_RETRIGGER; - Next(); - } - else - { - pev->spawnflags |= SF_TRAIN_WAIT_RETRIGGER; - // Pop back to last target if it's available - if ( pev->enemy ) - pev->target = pev->enemy->v.targetname; - pev->nextthink = 0; - pev->velocity = g_vecZero; - if ( pev->noiseStopMoving ) - EMIT_SOUND (ENT(pev), CHAN_VOICE, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - } -} - - -void CFuncTrain :: Wait( void ) -{ - // Fire the pass target if there is one - if ( m_pevCurrentTarget->message ) - { - FireTargets( STRING(m_pevCurrentTarget->message), this, this, USE_TOGGLE, 0 ); - if ( FBitSet( m_pevCurrentTarget->spawnflags, SF_CORNER_FIREONCE ) ) - m_pevCurrentTarget->message = 0; - } - - // need pointer to LAST target. - if ( FBitSet (m_pevCurrentTarget->spawnflags , SF_TRAIN_WAIT_RETRIGGER ) || ( pev->spawnflags & SF_TRAIN_WAIT_RETRIGGER ) ) - { - pev->spawnflags |= SF_TRAIN_WAIT_RETRIGGER; - // clear the sound channel. - if ( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noiseMovement) ); - if ( pev->noiseStopMoving ) - EMIT_SOUND (ENT(pev), CHAN_VOICE, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - pev->nextthink = 0; - return; - } - - // ALERT ( at_console, "%f\n", m_flWait ); - - if (m_flWait != 0) - {// -1 wait will wait forever! - pev->nextthink = pev->ltime + m_flWait; - if ( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noiseMovement) ); - if ( pev->noiseStopMoving ) - EMIT_SOUND (ENT(pev), CHAN_VOICE, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - SetThink( &CFuncTrain::Next ); - } - else - { - Next();// do it RIGHT now! - } -} - - -// -// Train next - path corner needs to change to next target -// -void CFuncTrain :: Next( void ) -{ - CBaseEntity *pTarg; - - - // now find our next target - pTarg = GetNextTarget(); - - if ( !pTarg ) - { - if ( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noiseMovement) ); - // Play stop sound - if ( pev->noiseStopMoving ) - EMIT_SOUND (ENT(pev), CHAN_VOICE, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - return; - } - - // Save last target in case we need to find it again - pev->message = pev->target; - - pev->target = pTarg->pev->target; - m_flWait = pTarg->GetDelay(); - - if ( m_pevCurrentTarget && m_pevCurrentTarget->speed != 0 ) - {// don't copy speed from target if it is 0 (uninitialized) - pev->speed = m_pevCurrentTarget->speed; - ALERT( at_aiconsole, "Train %s speed to %4.2f\n", STRING(pev->targetname), pev->speed ); - } - m_pevCurrentTarget = pTarg->pev;// keep track of this since path corners change our target for us. - - pev->enemy = pTarg->edict();//hack - - if(FBitSet(m_pevCurrentTarget->spawnflags, SF_CORNER_TELEPORT)) - { - // Path corner has indicated a teleport to the next corner. - SetBits(pev->effects, EF_NOINTERP); - UTIL_SetOrigin(pev, pTarg->pev->origin - (pev->mins + pev->maxs)* 0.5); - Wait(); // Get on with doing the next path corner. - } - else - { - // Normal linear move. - - // CHANGED this from CHAN_VOICE to CHAN_STATIC around OEM beta time because trains should - // use CHAN_STATIC for their movement sounds to prevent sound field problems. - // this is not a hack or temporary fix, this is how things should be. (sjb). - if ( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noiseMovement) ); - if ( pev->noiseMovement ) - EMIT_SOUND (ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement), m_volume, ATTN_NORM); - ClearBits(pev->effects, EF_NOINTERP); - SetMoveDone( &CFuncTrain::Wait ); - LinearMove (pTarg->pev->origin - (pev->mins + pev->maxs)* 0.5, pev->speed); - } -} - - -void CFuncTrain :: Activate( void ) -{ - // Not yet active, so teleport to first target - if ( !m_activated ) - { - m_activated = TRUE; - entvars_t *pevTarg = VARS( FIND_ENTITY_BY_TARGETNAME (NULL, STRING(pev->target) ) ); - - pev->target = pevTarg->target; - m_pevCurrentTarget = pevTarg;// keep track of this since path corners change our target for us. - - UTIL_SetOrigin (pev, pevTarg->origin - (pev->mins + pev->maxs) * 0.5 ); - - if ( FStringNull(pev->targetname) ) - { // not triggered, so start immediately - pev->nextthink = pev->ltime + 0.1; - SetThink( &CFuncTrain::Next ); - } - else - pev->spawnflags |= SF_TRAIN_WAIT_RETRIGGER; - } -} - -/*QUAKED func_train (0 .5 .8) ? -Trains are moving platforms that players can ride. -The targets origin specifies the min point of the train at each corner. -The train spawns at the first target it is pointing at. -If the train is the target of a button or trigger, it will not begin moving until activated. -speed default 100 -dmg default 2 -sounds -1) ratchet metal -*/ - -void CFuncTrain :: Spawn( void ) -{ - Precache(); - if (pev->speed == 0) - pev->speed = 100; - - if ( FStringNull(pev->target) ) - ALERT(at_console, "FuncTrain with no target"); - - if (pev->dmg == 0) - pev->dmg = 2; - - pev->movetype = MOVETYPE_PUSH; - - if ( FBitSet (pev->spawnflags, SF_TRACKTRAIN_PASSABLE) ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - - SET_MODEL( ENT(pev), STRING(pev->model) ); - UTIL_SetSize (pev, pev->mins, pev->maxs); - UTIL_SetOrigin(pev, pev->origin); - - m_activated = FALSE; - - if ( m_volume == 0 ) - m_volume = 0.85; -} - - -void CFuncTrain::Precache( void ) -{ - CBasePlatTrain::Precache(); - -#if 0 // obsolete - // otherwise use preset sound - switch (m_sounds) - { - case 0: - pev->noise = 0; - pev->noise1 = 0; - break; - - case 1: - PRECACHE_SOUND ("plats/train2.wav"); - PRECACHE_SOUND ("plats/train1.wav"); - pev->noise = MAKE_STRING("plats/train2.wav"); - pev->noise1 = MAKE_STRING("plats/train1.wav"); - break; - - case 2: - PRECACHE_SOUND ("plats/platmove1.wav"); - PRECACHE_SOUND ("plats/platstop1.wav"); - pev->noise = MAKE_STRING("plats/platstop1.wav"); - pev->noise1 = MAKE_STRING("plats/platmove1.wav"); - break; - } -#endif -} - - -void CFuncTrain::OverrideReset( void ) -{ - CBaseEntity *pTarg; - - // Are we moving? - if ( pev->velocity != g_vecZero && pev->nextthink != 0 ) - { - pev->target = pev->message; - // now find our next target - pTarg = GetNextTarget(); - if ( !pTarg ) - { - pev->nextthink = 0; - pev->velocity = g_vecZero; - } - else // Keep moving for 0.1 secs, then find path_corner again and restart - { - SetThink( &CFuncTrain::Next ); - pev->nextthink = pev->ltime + 0.1; - } - } -} - - - - -// --------------------------------------------------------------------- -// -// Track Train -// -// --------------------------------------------------------------------- - -TYPEDESCRIPTION CFuncTrackTrain::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTrackTrain, m_ppath, FIELD_CLASSPTR ), - DEFINE_FIELD( CFuncTrackTrain, m_length, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_height, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_speed, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_dir, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_startSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_controlMins, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTrackTrain, m_controlMaxs, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTrackTrain, m_sounds, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTrackTrain, m_flVolume, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_flBank, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_oldSpeed, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTrackTrain, CBaseEntity ); -LINK_ENTITY_TO_CLASS( func_tracktrain, CFuncTrackTrain ); - -void CFuncTrackTrain :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "wheels")) - { - m_length = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "height")) - { - m_height = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "startspeed")) - { - m_startSpeed = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "volume")) - { - m_flVolume = (float) (atoi(pkvd->szValue)); - m_flVolume *= 0.1; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "bank")) - { - m_flBank = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -void CFuncTrackTrain :: NextThink( float thinkTime, BOOL alwaysThink ) -{ - if ( alwaysThink ) - pev->flags |= FL_ALWAYSTHINK; - else - pev->flags &= ~FL_ALWAYSTHINK; - - pev->nextthink = thinkTime; -} - - -void CFuncTrackTrain :: Blocked( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - // Blocker is on-ground on the train - if ( FBitSet( pevOther->flags, FL_ONGROUND ) && VARS(pevOther->groundentity) == pev ) - { - float deltaSpeed = fabs(pev->speed); - if ( deltaSpeed > 50 ) - deltaSpeed = 50; - if ( !pevOther->velocity.z ) - pevOther->velocity.z += deltaSpeed; - return; - } - else - pevOther->velocity = (pevOther->origin - pev->origin ).Normalize() * pev->dmg; - - ALERT( at_aiconsole, "TRAIN(%s): Blocked by %s (dmg:%.2f)\n", STRING(pev->targetname), STRING(pOther->pev->classname), pev->dmg ); - if ( pev->dmg <= 0 ) - return; - // we can't hurt this thing, so we're not concerned with it - pOther->TakeDamage(pev, pev, pev->dmg, DMG_CRUSH); -} - - -void CFuncTrackTrain :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( useType != USE_SET ) - { - if ( !ShouldToggle( useType, (pev->speed != 0) ) ) - return; - - if ( pev->speed == 0 ) - { - pev->speed = m_speed * m_dir; - - Next(); - } - else - { - pev->speed = 0; - pev->velocity = g_vecZero; - pev->avelocity = g_vecZero; - StopSound(); - SetThink( NULL ); - } - } - else - { - float delta = value; - - delta = ((int)(pev->speed * 4) / (int)m_speed)*0.25 + 0.25 * delta; - if ( delta > 1 ) - delta = 1; - else if ( delta < -1 ) - delta = -1; - if ( pev->spawnflags & SF_TRACKTRAIN_FORWARDONLY ) - { - if ( delta < 0 ) - delta = 0; - } - pev->speed = m_speed * delta; - Next(); - ALERT( at_aiconsole, "TRAIN(%s), speed to %.2f\n", STRING(pev->targetname), pev->speed ); - } -} - - -static float Fix( float angle ) -{ - while ( angle < 0 ) - angle += 360; - while ( angle > 360 ) - angle -= 360; - - return angle; -} - - -static void FixupAngles( Vector &v ) -{ - v.x = Fix( v.x ); - v.y = Fix( v.y ); - v.z = Fix( v.z ); -} - -#define TRAIN_STARTPITCH 60 -#define TRAIN_MAXPITCH 200 -#define TRAIN_MAXSPEED 1000 // approx max speed for sound pitch calculation - -void CFuncTrackTrain :: StopSound( void ) -{ - // if sound playing, stop it - if (m_soundPlaying && pev->noise) - { - unsigned short us_encode; - unsigned short us_sound = ( ( unsigned short )( m_sounds ) & 0x0007 ) << 12; - - us_encode = us_sound; - - PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, - (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 1, 0 ); - - /* - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noise)); - */ - EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "plats/ttrain_brake1.wav", m_flVolume, ATTN_NORM, 0, 100); - } - - m_soundPlaying = 0; -} - -// update pitch based on speed, start sound if not playing -// NOTE: when train goes through transition, m_soundPlaying should go to 0, -// which will cause the looped sound to restart. - -void CFuncTrackTrain :: UpdateSound( void ) -{ - float flpitch; - - if (!pev->noise) - return; - - flpitch = TRAIN_STARTPITCH + ( fabs(pev->speed) * (TRAIN_MAXPITCH - TRAIN_STARTPITCH) / TRAIN_MAXSPEED); - - if (!m_soundPlaying) - { - // play startup sound for train - EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "plats/ttrain_start1.wav", m_flVolume, ATTN_NORM, 0, 100); - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noise), m_flVolume, ATTN_NORM, 0, (int) flpitch); - m_soundPlaying = 1; - } - else - { -/* - // update pitch - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noise), m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, (int) flpitch); -*/ - // volume 0.0 - 1.0 - 6 bits - // m_sounds 3 bits - // flpitch = 6 bits - // 15 bits total - - unsigned short us_encode; - unsigned short us_sound = ( ( unsigned short )( m_sounds ) & 0x0007 ) << 12; - unsigned short us_pitch = ( ( unsigned short )( flpitch / 10.0 ) & 0x003f ) << 6; - unsigned short us_volume = ( ( unsigned short )( m_flVolume * 40.0 ) & 0x003f ); - - us_encode = us_sound | us_pitch | us_volume; - - PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, - (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 0, 0 ); - } -} - - -void CFuncTrackTrain :: Next( void ) -{ - float time = 0.5; - - if ( !pev->speed ) - { - ALERT( at_aiconsole, "TRAIN(%s): Speed is 0\n", STRING(pev->targetname) ); - StopSound(); - return; - } - -// if ( !m_ppath ) -// m_ppath = CPathTrack::Instance(FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->target) )); - if ( !m_ppath ) - { - ALERT( at_aiconsole, "TRAIN(%s): Lost path\n", STRING(pev->targetname) ); - StopSound(); - return; - } - - UpdateSound(); - - Vector nextPos = pev->origin; - - nextPos.z -= m_height; - CPathTrack *pnext = m_ppath->LookAhead( &nextPos, pev->speed * 0.1, 1 ); - nextPos.z += m_height; - - pev->velocity = (nextPos - pev->origin) * 10; - Vector nextFront = pev->origin; - - nextFront.z -= m_height; - if ( m_length > 0 ) - m_ppath->LookAhead( &nextFront, m_length, 0 ); - else - m_ppath->LookAhead( &nextFront, 100, 0 ); - nextFront.z += m_height; - - Vector delta = nextFront - pev->origin; - Vector angles = UTIL_VecToAngles( delta ); - // The train actually points west - angles.y += 180; - - // !!! All of this crap has to be done to make the angles not wrap around, revisit this. - FixupAngles( angles ); - FixupAngles( pev->angles ); - - if ( !pnext || (delta.x == 0 && delta.y == 0) ) - angles = pev->angles; - - float vy, vx; - if ( !(pev->spawnflags & SF_TRACKTRAIN_NOPITCH) ) - vx = UTIL_AngleDistance( angles.x, pev->angles.x ); - else - vx = 0; - vy = UTIL_AngleDistance( angles.y, pev->angles.y ); - - pev->avelocity.y = vy * 10; - pev->avelocity.x = vx * 10; - - if ( m_flBank != 0 ) - { - if ( pev->avelocity.y < -5 ) - pev->avelocity.z = UTIL_AngleDistance( UTIL_ApproachAngle( -m_flBank, pev->angles.z, m_flBank*2 ), pev->angles.z); - else if ( pev->avelocity.y > 5 ) - pev->avelocity.z = UTIL_AngleDistance( UTIL_ApproachAngle( m_flBank, pev->angles.z, m_flBank*2 ), pev->angles.z); - else - pev->avelocity.z = UTIL_AngleDistance( UTIL_ApproachAngle( 0, pev->angles.z, m_flBank*4 ), pev->angles.z) * 4; - } - - if ( pnext ) - { - if ( pnext != m_ppath ) - { - CPathTrack *pFire; - if ( pev->speed >= 0 ) - pFire = pnext; - else - pFire = m_ppath; - - m_ppath = pnext; - // Fire the pass target if there is one - if ( pFire->pev->message ) - { - FireTargets( STRING(pFire->pev->message), this, this, USE_TOGGLE, 0 ); - if ( FBitSet( pFire->pev->spawnflags, SF_PATH_FIREONCE ) ) - pFire->pev->message = 0; - } - - if ( pFire->pev->spawnflags & SF_PATH_DISABLE_TRAIN ) - pev->spawnflags |= SF_TRACKTRAIN_NOCONTROL; - - // Don't override speed if under user control - if ( pev->spawnflags & SF_TRACKTRAIN_NOCONTROL ) - { - if ( pFire->pev->speed != 0 ) - {// don't copy speed from target if it is 0 (uninitialized) - pev->speed = pFire->pev->speed; - ALERT( at_aiconsole, "TrackTrain %s speed to %4.2f\n", STRING(pev->targetname), pev->speed ); - } - } - - } - SetThink( &CFuncTrackTrain::Next ); - NextThink( pev->ltime + time, TRUE ); - } - else // end of path, stop - { - StopSound(); - pev->velocity = (nextPos - pev->origin); - pev->avelocity = g_vecZero; - float distance = pev->velocity.Length(); - m_oldSpeed = pev->speed; - - - pev->speed = 0; - - // Move to the dead end - - // Are we there yet? - if ( distance > 0 ) - { - // no, how long to get there? - time = distance / m_oldSpeed; - pev->velocity = pev->velocity * (m_oldSpeed / distance); - SetThink( &CFuncTrackTrain::DeadEnd ); - NextThink( pev->ltime + time, FALSE ); - } - else - { - DeadEnd(); - } - } -} - - -void CFuncTrackTrain::DeadEnd( void ) -{ - // Fire the dead-end target if there is one - CPathTrack *pTrack, *pNext; - - pTrack = m_ppath; - - ALERT( at_aiconsole, "TRAIN(%s): Dead end ", STRING(pev->targetname) ); - // Find the dead end path node - // HACKHACK -- This is bugly, but the train can actually stop moving at a different node depending on it's speed - // so we have to traverse the list to it's end. - if ( pTrack ) - { - if ( m_oldSpeed < 0 ) - { - do - { - pNext = pTrack->ValidPath( pTrack->GetPrevious(), TRUE ); - if ( pNext ) - pTrack = pNext; - } while ( pNext ); - } - else - { - do - { - pNext = pTrack->ValidPath( pTrack->GetNext(), TRUE ); - if ( pNext ) - pTrack = pNext; - } while ( pNext ); - } - } - - pev->velocity = g_vecZero; - pev->avelocity = g_vecZero; - if ( pTrack ) - { - ALERT( at_aiconsole, "at %s\n", STRING(pTrack->pev->targetname) ); - if ( pTrack->pev->netname ) - FireTargets( STRING(pTrack->pev->netname), this, this, USE_TOGGLE, 0 ); - } - else - ALERT( at_aiconsole, "\n" ); -} - - -void CFuncTrackTrain :: SetControls( entvars_t *pevControls ) -{ - Vector offset = pevControls->origin - pev->oldorigin; - - m_controlMins = pevControls->mins + offset; - m_controlMaxs = pevControls->maxs + offset; -} - - -BOOL CFuncTrackTrain :: OnControls( entvars_t *pevTest ) -{ - Vector offset = pevTest->origin - pev->origin; - - if ( pev->spawnflags & SF_TRACKTRAIN_NOCONTROL ) - return FALSE; - - // Transform offset into local coordinates - UTIL_MakeVectors( pev->angles ); - Vector local; - local.x = DotProduct( offset, gpGlobals->v_forward ); - local.y = -DotProduct( offset, gpGlobals->v_right ); - local.z = DotProduct( offset, gpGlobals->v_up ); - - if ( local.x >= m_controlMins.x && local.y >= m_controlMins.y && local.z >= m_controlMins.z && - local.x <= m_controlMaxs.x && local.y <= m_controlMaxs.y && local.z <= m_controlMaxs.z ) - return TRUE; - - return FALSE; -} - - -void CFuncTrackTrain :: Find( void ) -{ - m_ppath = CPathTrack::Instance(FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->target) )); - if ( !m_ppath ) - return; - - entvars_t *pevTarget = m_ppath->pev; - if ( !FClassnameIs( pevTarget, "path_track" ) ) - { - ALERT( at_error, "func_track_train must be on a path of path_track\n" ); - m_ppath = NULL; - return; - } - - Vector nextPos = pevTarget->origin; - nextPos.z += m_height; - - Vector look = nextPos; - look.z -= m_height; - m_ppath->LookAhead( &look, m_length, 0 ); - look.z += m_height; - - pev->angles = UTIL_VecToAngles( look - nextPos ); - // The train actually points west - pev->angles.y += 180; - - if ( pev->spawnflags & SF_TRACKTRAIN_NOPITCH ) - pev->angles.x = 0; - UTIL_SetOrigin( pev, nextPos ); - NextThink( pev->ltime + 0.1, FALSE ); - SetThink( &CFuncTrackTrain::Next ); - pev->speed = m_startSpeed; - - UpdateSound(); -} - - -void CFuncTrackTrain :: NearestPath( void ) -{ - CBaseEntity *pTrack = NULL; - CBaseEntity *pNearest = NULL; - float dist, closest; - - closest = 1024; - - while ((pTrack = UTIL_FindEntityInSphere( pTrack, pev->origin, 1024 )) != NULL) - { - // filter out non-tracks - if ( !(pTrack->pev->flags & (FL_CLIENT|FL_MONSTER)) && FClassnameIs( pTrack->pev, "path_track" ) ) - { - dist = (pev->origin - pTrack->pev->origin).Length(); - if ( dist < closest ) - { - closest = dist; - pNearest = pTrack; - } - } - } - - if ( !pNearest ) - { - ALERT( at_console, "Can't find a nearby track !!!\n" ); - SetThink(NULL); - return; - } - - ALERT( at_aiconsole, "TRAIN: %s, Nearest track is %s\n", STRING(pev->targetname), STRING(pNearest->pev->targetname) ); - // If I'm closer to the next path_track on this path, then it's my real path - pTrack = ((CPathTrack *)pNearest)->GetNext(); - if ( pTrack ) - { - if ( (pev->origin - pTrack->pev->origin).Length() < (pev->origin - pNearest->pev->origin).Length() ) - pNearest = pTrack; - } - - m_ppath = (CPathTrack *)pNearest; - - if ( pev->speed != 0 ) - { - NextThink( pev->ltime + 0.1, FALSE ); - SetThink( &CFuncTrackTrain::Next ); - } -} - - -void CFuncTrackTrain::OverrideReset( void ) -{ - NextThink( pev->ltime + 0.1, FALSE ); - SetThink( &CFuncTrackTrain::NearestPath ); -} - - -CFuncTrackTrain *CFuncTrackTrain::Instance( edict_t *pent ) -{ - if ( FClassnameIs( pent, "func_tracktrain" ) ) - return (CFuncTrackTrain *)GET_PRIVATE(pent); - return NULL; -} - -/*QUAKED func_train (0 .5 .8) ? -Trains are moving platforms that players can ride. -The targets origin specifies the min point of the train at each corner. -The train spawns at the first target it is pointing at. -If the train is the target of a button or trigger, it will not begin moving until activated. -speed default 100 -dmg default 2 -sounds -1) ratchet metal -*/ - -void CFuncTrackTrain :: Spawn( void ) -{ - if ( pev->speed == 0 ) - m_speed = 100; - else - m_speed = pev->speed; - - pev->speed = 0; - pev->velocity = g_vecZero; - pev->avelocity = g_vecZero; - pev->impulse = m_speed; - - m_dir = 1; - - if ( FStringNull(pev->target) ) - ALERT( at_console, "FuncTrain with no target" ); - - if ( pev->spawnflags & SF_TRACKTRAIN_PASSABLE ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - SET_MODEL( ENT(pev), STRING(pev->model) ); - - UTIL_SetSize( pev, pev->mins, pev->maxs ); - UTIL_SetOrigin( pev, pev->origin ); - - // Cache off placed origin for train controls - pev->oldorigin = pev->origin; - - m_controlMins = pev->mins; - m_controlMaxs = pev->maxs; - m_controlMaxs.z += 72; -// start trains on the next frame, to make sure their targets have had -// a chance to spawn/activate - NextThink( pev->ltime + 0.1, FALSE ); - SetThink( &CFuncTrackTrain::Find ); - Precache(); -} - -void CFuncTrackTrain :: Precache( void ) -{ - if (m_flVolume == 0.0) - m_flVolume = 1.0; - - switch (m_sounds) - { - default: - // no sound - pev->noise = 0; - break; - case 1: PRECACHE_SOUND("plats/ttrain1.wav"); pev->noise = MAKE_STRING("plats/ttrain1.wav");break; - case 2: PRECACHE_SOUND("plats/ttrain2.wav"); pev->noise = MAKE_STRING("plats/ttrain2.wav");break; - case 3: PRECACHE_SOUND("plats/ttrain3.wav"); pev->noise = MAKE_STRING("plats/ttrain3.wav");break; - case 4: PRECACHE_SOUND("plats/ttrain4.wav"); pev->noise = MAKE_STRING("plats/ttrain4.wav");break; - case 5: PRECACHE_SOUND("plats/ttrain6.wav"); pev->noise = MAKE_STRING("plats/ttrain6.wav");break; - case 6: PRECACHE_SOUND("plats/ttrain7.wav"); pev->noise = MAKE_STRING("plats/ttrain7.wav");break; - } - - PRECACHE_SOUND("plats/ttrain_brake1.wav"); - PRECACHE_SOUND("plats/ttrain_start1.wav"); - - m_usAdjustPitch = PRECACHE_EVENT( 1, "events/train.sc" ); -} - -// This class defines the volume of space that the player must stand in to control the train -class CFuncTrainControls : public CBaseEntity -{ -public: - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - void Spawn( void ); - void EXPORT Find( void ); -}; -LINK_ENTITY_TO_CLASS( func_traincontrols, CFuncTrainControls ); - - -void CFuncTrainControls :: Find( void ) -{ - edict_t *pTarget = NULL; - - do - { - pTarget = FIND_ENTITY_BY_TARGETNAME( pTarget, STRING(pev->target) ); - } while ( !FNullEnt(pTarget) && !FClassnameIs(pTarget, "func_tracktrain") ); - - if ( FNullEnt( pTarget ) ) - { - ALERT( at_console, "No train %s\n", STRING(pev->target) ); - return; - } - - CFuncTrackTrain *ptrain = CFuncTrackTrain::Instance(pTarget); - ptrain->SetControls( pev ); - UTIL_Remove( this ); -} - - -void CFuncTrainControls :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - UTIL_SetSize( pev, pev->mins, pev->maxs ); - UTIL_SetOrigin( pev, pev->origin ); - - SetThink(&CFuncTrainControls::Find ); - pev->nextthink = gpGlobals->time; -} - - - -// ---------------------------------------------------------------------------- -// -// Track changer / Train elevator -// -// ---------------------------------------------------------------------------- - -#define SF_TRACK_ACTIVATETRAIN 0x00000001 -#define SF_TRACK_RELINK 0x00000002 -#define SF_TRACK_ROTMOVE 0x00000004 -#define SF_TRACK_STARTBOTTOM 0x00000008 -#define SF_TRACK_DONT_MOVE 0x00000010 - -// -// This entity is a rotating/moving platform that will carry a train to a new track. -// It must be larger in X-Y planar area than the train, since it must contain the -// train within these dimensions in order to operate when the train is near it. -// - -typedef enum { TRAIN_SAFE, TRAIN_BLOCKING, TRAIN_FOLLOWING } TRAIN_CODE; - -class CFuncTrackChange : public CFuncPlatRot -{ -public: - void Spawn( void ); - void Precache( void ); - -// virtual void Blocked( void ); - virtual void EXPORT GoUp( void ); - virtual void EXPORT GoDown( void ); - - void KeyValue( KeyValueData* pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT Find( void ); - TRAIN_CODE EvaluateTrain( CPathTrack *pcurrent ); - void UpdateTrain( Vector &dest ); - virtual void HitBottom( void ); - virtual void HitTop( void ); - void Touch( CBaseEntity *pOther ); - virtual void UpdateAutoTargets( int toggleState ); - virtual BOOL IsTogglePlat( void ) { return TRUE; } - - void DisableUse( void ) { m_use = 0; } - void EnableUse( void ) { m_use = 1; } - int UseEnabled( void ) { return m_use; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - virtual void OverrideReset( void ); - - - CPathTrack *m_trackTop; - CPathTrack *m_trackBottom; - - CFuncTrackTrain *m_train; - - int m_trackTopName; - int m_trackBottomName; - int m_trainName; - TRAIN_CODE m_code; - int m_targetState; - int m_use; -}; -LINK_ENTITY_TO_CLASS( func_trackchange, CFuncTrackChange ); - -TYPEDESCRIPTION CFuncTrackChange::m_SaveData[] = -{ - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trackTop, FIELD_CLASSPTR ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trackBottom, FIELD_CLASSPTR ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_train, FIELD_CLASSPTR ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trackTopName, FIELD_STRING ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trackBottomName, FIELD_STRING ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trainName, FIELD_STRING ), - DEFINE_FIELD( CFuncTrackChange, m_code, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTrackChange, m_targetState, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTrackChange, m_use, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTrackChange, CFuncPlatRot ); - -void CFuncTrackChange :: Spawn( void ) -{ - Setup(); - if ( FBitSet( pev->spawnflags, SF_TRACK_DONT_MOVE ) ) - m_vecPosition2.z = pev->origin.z; - - SetupRotation(); - - if ( FBitSet( pev->spawnflags, SF_TRACK_STARTBOTTOM ) ) - { - UTIL_SetOrigin (pev, m_vecPosition2); - m_toggle_state = TS_AT_BOTTOM; - pev->angles = m_start; - m_targetState = TS_AT_TOP; - } - else - { - UTIL_SetOrigin (pev, m_vecPosition1); - m_toggle_state = TS_AT_TOP; - pev->angles = m_end; - m_targetState = TS_AT_BOTTOM; - } - - EnableUse(); - pev->nextthink = pev->ltime + 2.0; - SetThink( &CFuncTrackChange::Find ); - Precache(); -} - -void CFuncTrackChange :: Precache( void ) -{ - // Can't trigger sound - PRECACHE_SOUND( "buttons/button11.wav" ); - - CFuncPlatRot::Precache(); -} - - -// UNDONE: Filter touches before re-evaluating the train. -void CFuncTrackChange :: Touch( CBaseEntity *pOther ) -{ -#if 0 - TRAIN_CODE code; - entvars_t *pevToucher = pOther->pev; -#endif -} - - - -void CFuncTrackChange :: KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "train") ) - { - m_trainName = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "toptrack") ) - { - m_trackTopName = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "bottomtrack") ) - { - m_trackBottomName = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - { - CFuncPlatRot::KeyValue( pkvd ); // Pass up to base class - } -} - - -void CFuncTrackChange::OverrideReset( void ) -{ - pev->nextthink = pev->ltime + 1.0; - SetThink( &CFuncTrackChange::Find ); -} - -void CFuncTrackChange :: Find( void ) -{ - // Find track entities - edict_t *target; - - target = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trackTopName) ); - if ( !FNullEnt(target) ) - { - m_trackTop = CPathTrack::Instance( target ); - target = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trackBottomName) ); - if ( !FNullEnt(target) ) - { - m_trackBottom = CPathTrack::Instance( target ); - target = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trainName) ); - if ( !FNullEnt(target) ) - { - m_train = CFuncTrackTrain::Instance( FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trainName) ) ); - if ( !m_train ) - { - ALERT( at_error, "Can't find train for track change! %s\n", STRING(m_trainName) ); - return; - } - Vector center = (pev->absmin + pev->absmax) * 0.5; - m_trackBottom = m_trackBottom->Nearest( center ); - m_trackTop = m_trackTop->Nearest( center ); - UpdateAutoTargets( m_toggle_state ); - SetThink( NULL ); - return; - } - else - { - ALERT( at_error, "Can't find train for track change! %s\n", STRING(m_trainName) ); - target = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trainName) ); - } - } - else - ALERT( at_error, "Can't find bottom track for track change! %s\n", STRING(m_trackBottomName) ); - } - else - ALERT( at_error, "Can't find top track for track change! %s\n", STRING(m_trackTopName) ); -} - - - -TRAIN_CODE CFuncTrackChange :: EvaluateTrain( CPathTrack *pcurrent ) -{ - // Go ahead and work, we don't have anything to switch, so just be an elevator - if ( !pcurrent || !m_train ) - return TRAIN_SAFE; - - if ( m_train->m_ppath == pcurrent || (pcurrent->m_pprevious && m_train->m_ppath == pcurrent->m_pprevious) || - (pcurrent->m_pnext && m_train->m_ppath == pcurrent->m_pnext) ) - { - if ( m_train->pev->speed != 0 ) - return TRAIN_BLOCKING; - - Vector dist = pev->origin - m_train->pev->origin; - float length = dist.Length2D(); - if ( length < m_train->m_length ) // Empirically determined close distance - return TRAIN_FOLLOWING; - else if ( length > (150 + m_train->m_length) ) - return TRAIN_SAFE; - - return TRAIN_BLOCKING; - } - - return TRAIN_SAFE; -} - - -void CFuncTrackChange :: UpdateTrain( Vector &dest ) -{ - float time = (pev->nextthink - pev->ltime); - - m_train->pev->velocity = pev->velocity; - m_train->pev->avelocity = pev->avelocity; - m_train->NextThink( m_train->pev->ltime + time, FALSE ); - - // Attempt at getting the train to rotate properly around the origin of the trackchange - if ( time <= 0 ) - return; - - Vector offset = m_train->pev->origin - pev->origin; - Vector delta = dest - pev->angles; - // Transform offset into local coordinates - UTIL_MakeInvVectors( delta, gpGlobals ); - Vector local; - local.x = DotProduct( offset, gpGlobals->v_forward ); - local.y = DotProduct( offset, gpGlobals->v_right ); - local.z = DotProduct( offset, gpGlobals->v_up ); - - local = local - offset; - m_train->pev->velocity = pev->velocity + (local * (1.0/time)); -} - -void CFuncTrackChange :: GoDown( void ) -{ - if ( m_code == TRAIN_BLOCKING ) - return; - - // HitBottom may get called during CFuncPlat::GoDown(), so set up for that - // before you call GoDown() - - UpdateAutoTargets( TS_GOING_DOWN ); - // If ROTMOVE, move & rotate - if ( FBitSet( pev->spawnflags, SF_TRACK_DONT_MOVE ) ) - { - SetMoveDone( &CFuncTrackChange::CallHitBottom ); - m_toggle_state = TS_GOING_DOWN; - AngularMove( m_start, pev->speed ); - } - else - { - CFuncPlat :: GoDown(); - SetMoveDone( &CFuncTrackChange::CallHitBottom ); - RotMove( m_start, pev->nextthink - pev->ltime ); - } - // Otherwise, rotate first, move second - - // If the train is moving with the platform, update it - if ( m_code == TRAIN_FOLLOWING ) - { - UpdateTrain( m_start ); - m_train->m_ppath = NULL; - } -} - - -// -// Platform is at bottom, now starts moving up -// -void CFuncTrackChange :: GoUp( void ) -{ - if ( m_code == TRAIN_BLOCKING ) - return; - - // HitTop may get called during CFuncPlat::GoUp(), so set up for that - // before you call GoUp(); - - UpdateAutoTargets( TS_GOING_UP ); - if ( FBitSet( pev->spawnflags, SF_TRACK_DONT_MOVE ) ) - { - m_toggle_state = TS_GOING_UP; - SetMoveDone( &CFuncTrackChange::CallHitTop ); - AngularMove( m_end, pev->speed ); - } - else - { - // If ROTMOVE, move & rotate - CFuncPlat :: GoUp(); - SetMoveDone( &CFuncTrackChange::CallHitTop ); - RotMove( m_end, pev->nextthink - pev->ltime ); - } - - // Otherwise, move first, rotate second - - // If the train is moving with the platform, update it - if ( m_code == TRAIN_FOLLOWING ) - { - UpdateTrain( m_end ); - m_train->m_ppath = NULL; - } -} - - -// Normal track change -void CFuncTrackChange :: UpdateAutoTargets( int toggleState ) -{ - if ( !m_trackTop || !m_trackBottom ) - return; - - if ( toggleState == TS_AT_TOP ) - ClearBits( m_trackTop->pev->spawnflags, SF_PATH_DISABLED ); - else - SetBits( m_trackTop->pev->spawnflags, SF_PATH_DISABLED ); - - if ( toggleState == TS_AT_BOTTOM ) - ClearBits( m_trackBottom->pev->spawnflags, SF_PATH_DISABLED ); - else - SetBits( m_trackBottom->pev->spawnflags, SF_PATH_DISABLED ); -} - - -void CFuncTrackChange :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( m_toggle_state != TS_AT_TOP && m_toggle_state != TS_AT_BOTTOM ) - return; - - // If train is in "safe" area, but not on the elevator, play alarm sound - if ( m_toggle_state == TS_AT_TOP ) - m_code = EvaluateTrain( m_trackTop ); - else if ( m_toggle_state == TS_AT_BOTTOM ) - m_code = EvaluateTrain( m_trackBottom ); - else - m_code = TRAIN_BLOCKING; - if ( m_code == TRAIN_BLOCKING ) - { - // Play alarm and return - EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/button11.wav", 1, ATTN_NORM); - return; - } - - // Otherwise, it's safe to move - // If at top, go down - // at bottom, go up - - DisableUse(); - if (m_toggle_state == TS_AT_TOP) - GoDown(); - else - GoUp(); -} - - -// -// Platform has hit bottom. Stops and waits forever. -// -void CFuncTrackChange :: HitBottom( void ) -{ - CFuncPlatRot :: HitBottom(); - if ( m_code == TRAIN_FOLLOWING ) - { -// UpdateTrain(); - m_train->SetTrack( m_trackBottom ); - } - SetThink( NULL ); - pev->nextthink = -1; - - UpdateAutoTargets( m_toggle_state ); - - EnableUse(); -} - - -// -// Platform has hit bottom. Stops and waits forever. -// -void CFuncTrackChange :: HitTop( void ) -{ - CFuncPlatRot :: HitTop(); - if ( m_code == TRAIN_FOLLOWING ) - { -// UpdateTrain(); - m_train->SetTrack( m_trackTop ); - } - - // Don't let the plat go back down - SetThink( NULL ); - pev->nextthink = -1; - UpdateAutoTargets( m_toggle_state ); - EnableUse(); -} - - - -class CFuncTrackAuto : public CFuncTrackChange -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual void UpdateAutoTargets( int toggleState ); -}; - -LINK_ENTITY_TO_CLASS( func_trackautochange, CFuncTrackAuto ); - -// Auto track change -void CFuncTrackAuto :: UpdateAutoTargets( int toggleState ) -{ - CPathTrack *pTarget, *pNextTarget; - - if ( !m_trackTop || !m_trackBottom ) - return; - - if ( m_targetState == TS_AT_TOP ) - { - pTarget = m_trackTop->GetNext(); - pNextTarget = m_trackBottom->GetNext(); - } - else - { - pTarget = m_trackBottom->GetNext(); - pNextTarget = m_trackTop->GetNext(); - } - if ( pTarget ) - { - ClearBits( pTarget->pev->spawnflags, SF_PATH_DISABLED ); - if ( m_code == TRAIN_FOLLOWING && m_train && m_train->pev->speed == 0 ) - m_train->Use( this, this, USE_ON, 0 ); - } - - if ( pNextTarget ) - SetBits( pNextTarget->pev->spawnflags, SF_PATH_DISABLED ); - -} - - -void CFuncTrackAuto :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - CPathTrack *pTarget; - - if ( !UseEnabled() ) - return; - - if ( m_toggle_state == TS_AT_TOP ) - pTarget = m_trackTop; - else if ( m_toggle_state == TS_AT_BOTTOM ) - pTarget = m_trackBottom; - else - pTarget = NULL; - - if ( FClassnameIs( pActivator->pev, "func_tracktrain" ) ) - { - m_code = EvaluateTrain( pTarget ); - // Safe to fire? - if ( m_code == TRAIN_FOLLOWING && m_toggle_state != m_targetState ) - { - DisableUse(); - if (m_toggle_state == TS_AT_TOP) - GoDown(); - else - GoUp(); - } - } - else - { - if ( pTarget ) - pTarget = pTarget->GetNext(); - if ( pTarget && m_train->m_ppath != pTarget && ShouldToggle( useType, m_targetState ) ) - { - if ( m_targetState == TS_AT_TOP ) - m_targetState = TS_AT_BOTTOM; - else - m_targetState = TS_AT_TOP; - } - - UpdateAutoTargets( m_targetState ); - } -} - - -// ---------------------------------------------------------- -// -// -// pev->speed is the travel speed -// pev->health is current health -// pev->max_health is the amount to reset to each time it starts - -#define FGUNTARGET_START_ON 0x0001 - -class CGunTarget : public CBaseMonster -{ -public: - void Spawn( void ); - void Activate( void ); - void EXPORT Next( void ); - void EXPORT Start( void ); - void EXPORT Wait( void ); - void Stop( void ); - - int BloodColor( void ) { return DONT_BLEED; } - int Classify( void ) { return CLASS_MACHINE; } - int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - Vector BodyTarget( const Vector &posSrc ) { return pev->origin; } - - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - BOOL m_on; -}; - - -LINK_ENTITY_TO_CLASS( func_guntarget, CGunTarget ); - -TYPEDESCRIPTION CGunTarget::m_SaveData[] = -{ - DEFINE_FIELD( CGunTarget, m_on, FIELD_BOOLEAN ), -}; - -IMPLEMENT_SAVERESTORE( CGunTarget, CBaseMonster ); - - -void CGunTarget::Spawn( void ) -{ - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - if ( pev->speed == 0 ) - pev->speed = 100; - - // Don't take damage until "on" - pev->takedamage = DAMAGE_NO; - pev->flags |= FL_MONSTER; - - m_on = FALSE; - pev->max_health = pev->health; - - if ( pev->spawnflags & FGUNTARGET_START_ON ) - { - SetThink( &CGunTarget::Start ); - pev->nextthink = pev->ltime + 0.3; - } -} - - -void CGunTarget::Activate( void ) -{ - CBaseEntity *pTarg; - - // now find our next target - pTarg = GetNextTarget(); - if ( pTarg ) - { - m_hTargetEnt = pTarg; - UTIL_SetOrigin( pev, pTarg->pev->origin - (pev->mins + pev->maxs) * 0.5 ); - } -} - - -void CGunTarget::Start( void ) -{ - Use( this, this, USE_ON, 0 ); -} - - -void CGunTarget::Next( void ) -{ - SetThink( NULL ); - - m_hTargetEnt = GetNextTarget(); - CBaseEntity *pTarget = m_hTargetEnt; - - if ( !pTarget ) - { - Stop(); - return; - } - SetMoveDone( &CGunTarget::Wait ); - LinearMove( pTarget->pev->origin - (pev->mins + pev->maxs) * 0.5, pev->speed ); -} - - -void CGunTarget::Wait( void ) -{ - CBaseEntity *pTarget = m_hTargetEnt; - - if ( !pTarget ) - { - Stop(); - return; - } - - // Fire the pass target if there is one - if ( pTarget->pev->message ) - { - FireTargets( STRING(pTarget->pev->message), this, this, USE_TOGGLE, 0 ); - if ( FBitSet( pTarget->pev->spawnflags, SF_CORNER_FIREONCE ) ) - pTarget->pev->message = 0; - } - - m_flWait = pTarget->GetDelay(); - - pev->target = pTarget->pev->target; - SetThink( &CGunTarget::Next ); - if (m_flWait != 0) - {// -1 wait will wait forever! - pev->nextthink = pev->ltime + m_flWait; - } - else - { - Next();// do it RIGHT now! - } -} - - -void CGunTarget::Stop( void ) -{ - pev->velocity = g_vecZero; - pev->nextthink = 0; - pev->takedamage = DAMAGE_NO; -} - - -int CGunTarget::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) -{ - if ( pev->health > 0 ) - { - pev->health -= flDamage; - if ( pev->health <= 0 ) - { - pev->health = 0; - Stop(); - if ( pev->message ) - FireTargets( STRING(pev->message), this, this, USE_TOGGLE, 0 ); - } - } - return 0; -} - - -void CGunTarget::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, m_on ) ) - return; - - if ( m_on ) - { - Stop(); - } - else - { - pev->takedamage = DAMAGE_AIM; - m_hTargetEnt = GetNextTarget(); - if ( m_hTargetEnt == NULL ) - return; - pev->health = pev->max_health; - Next(); - } -} - - - diff --git a/dmc/dlls/player.cpp b/dmc/dlls/player.cpp deleted file mode 100644 index 8ca2cae..0000000 --- a/dmc/dlls/player.cpp +++ /dev/null @@ -1,4887 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== player.cpp ======================================================== - - functions dealing with the player - -*/ - -#include "extdll.h" -#include "util.h" - -#include "cbase.h" -#include "player.h" -#include "trains.h" -#include "nodes.h" -#include "weapons.h" -#include "monsters.h" -#include "../engine/shake.h" -#include "decals.h" -#include "gamerules.h" -#include "quake_gun.h" - -// #define DUCKFIX - -extern bool g_bHaveMOTD; -#include "pm_shared.h" -#include "hltv.h" - -extern DLL_GLOBAL ULONG g_ulModelIndexPlayer; -extern DLL_GLOBAL BOOL g_fGameOver; -extern DLL_GLOBAL BOOL g_fDrawLines; -extern unsigned short g_sTeleport; -extern unsigned short g_usPowerUp; - -Vector g_vecTeleMins[ MAX_TELES ]; -Vector g_vecTeleMaxs[ MAX_TELES ]; -int g_iTeleNum; - -int gEvilImpulse101; -extern DLL_GLOBAL int g_iSkillLevel, gDisplayTitle; -BOOL gInitHUD = TRUE; - -extern void CopyToBodyQue(entvars_t* pev); -extern void respawn(entvars_t *pev, BOOL fCopyCorpse); -extern Vector VecBModelOrigin(entvars_t *pevBModel ); - -extern edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ); - -int MapTextureTypeStepType(char chTextureType); - -void AddAmmoNameToAmmoRegistry( const char *szAmmoname ); - -// the world node graph -extern CGraph WorldGraph; - -#define PLAYER_WALLJUMP_SPEED 300 // how fast we can spring off walls -#define PLAYER_LONGJUMP_SPEED 350 // how fast we longjump - -#define TRAIN_ACTIVE 0x80 -#define TRAIN_NEW 0xc0 -#define TRAIN_OFF 0x00 -#define TRAIN_NEUTRAL 0x01 -#define TRAIN_SLOW 0x02 -#define TRAIN_MEDIUM 0x03 -#define TRAIN_FAST 0x04 -#define TRAIN_BACK 0x05 - -#define FLASH_DRAIN_TIME 1.2 //100 units/3 minutes -#define FLASH_CHARGE_TIME 0.2 // 100 units/20 seconds (seconds per unit) - - -//#define PLAYER_MAX_SAFE_FALL_DIST 20// falling any farther than this many feet will inflict damage -//#define PLAYER_FATAL_FALL_DIST 60// 100% damage inflicted if player falls this many feet -//#define DAMAGE_PER_UNIT_FALLEN (float)( 100 ) / ( ( PLAYER_FATAL_FALL_DIST - PLAYER_MAX_SAFE_FALL_DIST ) * 12 ) -//#define MAX_SAFE_FALL_UNITS ( PLAYER_MAX_SAFE_FALL_DIST * 12 ) - -// Global Savedata for player -TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] = -{ - DEFINE_FIELD( CBasePlayer, m_flFlashLightTime, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_iFlashBattery, FIELD_INTEGER ), - - DEFINE_FIELD( CBasePlayer, m_afButtonLast, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_afButtonPressed, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_afButtonReleased, FIELD_INTEGER ), - - DEFINE_ARRAY( CBasePlayer, m_rgItems, FIELD_INTEGER, MAX_ITEMS ), - DEFINE_FIELD( CBasePlayer, m_afPhysicsFlags, FIELD_INTEGER ), - - DEFINE_FIELD( CBasePlayer, m_flTimeStepSound, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_flTimeWeaponIdle, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_flSwimTime, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_flDuckTime, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_flWallJumpTime, FIELD_TIME ), - - DEFINE_FIELD( CBasePlayer, m_flSuitUpdate, FIELD_TIME ), - DEFINE_ARRAY( CBasePlayer, m_rgSuitPlayList, FIELD_INTEGER, CSUITPLAYLIST ), - DEFINE_FIELD( CBasePlayer, m_iSuitPlayNext, FIELD_INTEGER ), - DEFINE_ARRAY( CBasePlayer, m_rgiSuitNoRepeat, FIELD_INTEGER, CSUITNOREPEAT ), - DEFINE_ARRAY( CBasePlayer, m_rgflSuitNoRepeatTime, FIELD_TIME, CSUITNOREPEAT ), - DEFINE_FIELD( CBasePlayer, m_lastDamageAmount, FIELD_INTEGER ), - - DEFINE_ARRAY( CBasePlayer, m_rgpPlayerItems, FIELD_CLASSPTR, MAX_ITEM_TYPES ), - DEFINE_FIELD( CBasePlayer, m_pActiveItem, FIELD_CLASSPTR ), - DEFINE_FIELD( CBasePlayer, m_pLastItem, FIELD_CLASSPTR ), - - DEFINE_ARRAY( CBasePlayer, m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ), - DEFINE_FIELD( CBasePlayer, m_idrowndmg, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_idrownrestored, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_tSneaking, FIELD_TIME ), - - DEFINE_FIELD( CBasePlayer, m_iTrain, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_bitsHUDDamage, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_flFallVelocity, FIELD_FLOAT ), - DEFINE_FIELD( CBasePlayer, m_iTargetVolume, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_iWeaponVolume, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_iExtraSoundTypes, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_iWeaponFlash, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_fLongJump, FIELD_BOOLEAN ), - DEFINE_FIELD( CBasePlayer, m_fInitHUD, FIELD_BOOLEAN ), - DEFINE_FIELD( CBasePlayer, m_tbdPrev, FIELD_TIME ), - - DEFINE_FIELD( CBasePlayer, m_pTank, FIELD_EHANDLE ), - DEFINE_FIELD( CBasePlayer, m_iHideHUD, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_iFOV, FIELD_INTEGER ), - - //DEFINE_FIELD( CBasePlayer, m_fDeadTime, FIELD_FLOAT ), // only used in multiplayer games - //DEFINE_FIELD( CBasePlayer, m_fGameHUDInitialized, FIELD_INTEGER ), // only used in multiplayer games - //DEFINE_FIELD( CBasePlayer, m_flStopExtraSoundTime, FIELD_TIME ), - //DEFINE_FIELD( CBasePlayer, m_fKnownItem, FIELD_INTEGER ), // reset to zero on load - //DEFINE_FIELD( CBasePlayer, m_iPlayerSound, FIELD_INTEGER ), // Don't restore, set in Precache() - //DEFINE_FIELD( CBasePlayer, m_pentSndLast, FIELD_EDICT ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_flSndRoomtype, FIELD_FLOAT ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_flSndRange, FIELD_FLOAT ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_fNewAmmo, FIELD_INTEGER ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_flgeigerRange, FIELD_FLOAT ), // Don't restore, reset in Precache() - //DEFINE_FIELD( CBasePlayer, m_flgeigerDelay, FIELD_FLOAT ), // Don't restore, reset in Precache() - //DEFINE_FIELD( CBasePlayer, m_igeigerRangePrev, FIELD_FLOAT ), // Don't restore, reset in Precache() - //DEFINE_FIELD( CBasePlayer, m_iStepLeft, FIELD_INTEGER ), // Don't need to restore - //DEFINE_ARRAY( CBasePlayer, m_szTextureName, FIELD_CHARACTER, CBTEXTURENAMEMAX ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_chTextureType, FIELD_CHARACTER ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_fNoPlayerSound, FIELD_BOOLEAN ), // Don't need to restore, debug - //DEFINE_FIELD( CBasePlayer, m_iUpdateTime, FIELD_INTEGER ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_iClientHealth, FIELD_INTEGER ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_iClientBattery, FIELD_INTEGER ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_iClientHideHUD, FIELD_INTEGER ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_fWeapon, FIELD_BOOLEAN ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_nCustomSprayFrames, FIELD_INTEGER ), // Don't restore, depends on server message after spawning and only matters in multiplayer - //DEFINE_FIELD( CBasePlayer, m_vecAutoAim, FIELD_VECTOR ), // Don't save/restore - this is recomputed - //DEFINE_ARRAY( CBasePlayer, m_rgAmmoLast, FIELD_INTEGER, MAX_AMMO_SLOTS ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_fOnTarget, FIELD_BOOLEAN ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_nCustomSprayFrames, FIELD_INTEGER ), // Don't need to restore - -}; - - -int giPrecacheGrunt = 0; -int gmsgShake = 0; -int gmsgFade = 0; -int gmsgSelAmmo = 0; -int gmsgFlashlight = 0; -int gmsgFlashBattery = 0; -int gmsgResetHUD = 0; -int gmsgInitHUD = 0; -int gmsgShowGameTitle = 0; -int gmsgCurWeapon = 0; -int gmsgHealth = 0; -int gmsgDamage = 0; -int gmsgBattery = 0; -int gmsgTrain = 0; -int gmsgLogo = 0; -int gmsgWeaponList = 0; -int gmsgAmmoX = 0; -int gmsgHudText = 0; -int gmsgDeathMsg = 0; -int gmsgScoreInfo = 0; -int gmsgTeamInfo = 0; -int gmsgTeamScore = 0; -int gmsgGameMode = 0; -int gmsgMOTD = 0; -int gmsgServerName = 0; -int gmsgAmmoPickup = 0; -int gmsgWeapPickup = 0; -int gmsgItemPickup = 0; -int gmsgHideWeapon = 0; -int gmsgSetCurWeap = 0; -int gmsgSayText = 0; -int gmsgTextMsg = 0; -int gmsgSetFOV = 0; -int gmsgShowMenu = 0; -int gmsgGeigerRange = 0; - -// QUAKECLASSIC -int gmsgQItems = 0; -int gmsgStatusText = 0; -int gmsgStatusValue = 0; - -void LinkUserMessages( void ) -{ - // Already taken care of? - if ( gmsgSelAmmo ) - { - return; - } - - gmsgSelAmmo = REG_USER_MSG("SelAmmo", sizeof(SelAmmo)); - gmsgCurWeapon = REG_USER_MSG("CurWeapon", 3); - gmsgGeigerRange = REG_USER_MSG("Geiger", 1); - gmsgFlashlight = REG_USER_MSG("Flashlight", 2); - gmsgFlashBattery = REG_USER_MSG("FlashBat", 1); - gmsgHealth = REG_USER_MSG( "Health", 1 ); - gmsgDamage = REG_USER_MSG( "Damage", 12 ); - gmsgBattery = REG_USER_MSG( "Battery", 2); - gmsgTrain = REG_USER_MSG( "Train", 1); - gmsgHudText = REG_USER_MSG( "HudText", -1 ); - gmsgSayText = REG_USER_MSG( "SayText", -1 ); - gmsgTextMsg = REG_USER_MSG( "TextMsg", -1 ); - gmsgWeaponList = REG_USER_MSG("WeaponList", -1); - gmsgResetHUD = REG_USER_MSG("ResetHUD", 1); // called every respawn - gmsgInitHUD = REG_USER_MSG("InitHUD", -1 ); // called every time a new player joins the server - gmsgShowGameTitle = REG_USER_MSG("GameTitle", 1); - gmsgDeathMsg = REG_USER_MSG( "DeathMsg", -1 ); - gmsgScoreInfo = REG_USER_MSG( "ScoreInfo", 7 ); - gmsgTeamInfo = REG_USER_MSG( "TeamInfo", -1 ); // sets the name of a player's team - gmsgTeamScore = REG_USER_MSG( "TeamScore", -1 ); // sets the score of a team on the scoreboard - gmsgGameMode = REG_USER_MSG( "GameMode", 1 ); - gmsgMOTD = REG_USER_MSG( "MOTD", -1 ); - gmsgServerName = REG_USER_MSG( "ServerName", -1 ); - gmsgAmmoPickup = REG_USER_MSG( "AmmoPickup", 2 ); - gmsgWeapPickup = REG_USER_MSG( "WeapPickup", 1 ); - gmsgItemPickup = REG_USER_MSG( "ItemPickup", -1 ); - gmsgHideWeapon = REG_USER_MSG( "HideWeapon", 1 ); - gmsgSetFOV = REG_USER_MSG( "SetFOV", 1 ); - gmsgShowMenu = REG_USER_MSG( "ShowMenu", -1 ); - gmsgShake = REG_USER_MSG("ScreenShake", sizeof(ScreenShake)); - gmsgFade = REG_USER_MSG("ScreenFade", sizeof(ScreenFade)); - gmsgAmmoX = REG_USER_MSG("AmmoX", 2); - - gmsgQItems = REG_USER_MSG( "QItems", 4 ); - - gmsgStatusText = REG_USER_MSG("StatusText", -1); - gmsgStatusValue = REG_USER_MSG("StatusValue", 3); -} - -LINK_ENTITY_TO_CLASS( player, CBasePlayer ); - - -// QUAKECLASSIC: Play pain sounds -void CBasePlayer :: Pain( CBaseEntity *pAttacker ) -{ - if (pev->health < 0) - return; - - if ( FClassnameIs( pAttacker->pev, "teledeath" ) ) - { - EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/teledth1.wav", 1, ATTN_NORM ); - return; - } - - // water pain sounds - if (pev->watertype == CONTENT_WATER && pev->waterlevel == 3) - { - UTIL_Bubbles( pev->mins, pev->maxs, 3 ); - if ( RANDOM_FLOAT(0,1) > 0.5 ) - EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/drown1.wav", 1, ATTN_NORM ); - else - EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/drown2.wav", 1, ATTN_NORM ); - return; - } - - // slime pain sounds - if (pev->watertype == CONTENT_SLIME) - { - if ( RANDOM_FLOAT(0,1) > 0.5 ) - EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM ); - else - EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM ); - return; - } - - // lava pain sounds - if (pev->watertype == CONTENT_LAVA) - { - if ( RANDOM_FLOAT(0,1) > 0.5 ) - EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/lburn1.wav", 1, ATTN_NORM ); - else - EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/lburn2.wav", 1, ATTN_NORM ); - return; - } - - // don't make multiple pain sounds right after each other - if (m_flPainSoundFinished > gpGlobals->time) - { - m_bAxHitMe = 0; - return; - } - m_flPainSoundFinished = gpGlobals->time + 0.5; - - // ax pain sound - if (m_bAxHitMe == 1) - { - m_bAxHitMe = 0; - EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/axhitbod.wav", 1, ATTN_NORM ); - return; - } - - // play random sound - switch ( (int)(RANDOM_FLOAT(0,1) * 6) ) - { - case 0: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/pain1.wav", 1, ATTN_NORM ); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/pain2.wav", 1, ATTN_NORM ); break; - case 2: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/pain3.wav", 1, ATTN_NORM ); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/pain4.wav", 1, ATTN_NORM ); break; - case 4: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/pain5.wav", 1, ATTN_NORM ); break; - case 5: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/pain6.wav", 1, ATTN_NORM ); break; - } -} - -// QUAKECLASSIC: Play a random death sound -void CBasePlayer :: DeathSound( void ) -{ - // water death sounds - if (pev->waterlevel == 3) - { - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NONE); - return; - } - - // play random sound - switch ( (int)(RANDOM_FLOAT(0,1) * 5) ) - { - case 0: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/death1.wav", 1, ATTN_NORM ); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/death2.wav", 1, ATTN_NORM ); break; - case 2: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/death3.wav", 1, ATTN_NORM ); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/death4.wav", 1, ATTN_NORM ); break; - case 4: EMIT_SOUND( ENT(pev), CHAN_VOICE, "player/death5.wav", 1, ATTN_NORM ); break; - } -} - -/* - * - */ -Vector VecVelocityForDamage(float flDamage) -{ - Vector vec(RANDOM_FLOAT(-100,100), RANDOM_FLOAT(-100,100), RANDOM_FLOAT(200,300)); - - if (flDamage > -50) - vec = vec * 0.7; - else if (flDamage > -200) - vec = vec * 2; - else - vec = vec * 10; - - return vec; -} - -#if 0 /* -static void ThrowGib(entvars_t *pev, char *szGibModel, float flDamage) -{ - edict_t *pentNew = CREATE_ENTITY(); - entvars_t *pevNew = VARS(pentNew); - - pevNew->origin = pev->origin; - SET_MODEL(ENT(pevNew), szGibModel); - UTIL_SetSize(pevNew, g_vecZero, g_vecZero); - - pevNew->velocity = VecVelocityForDamage(flDamage); - pevNew->movetype = MOVETYPE_BOUNCE; - pevNew->solid = SOLID_NOT; - pevNew->avelocity.x = RANDOM_FLOAT(0,600); - pevNew->avelocity.y = RANDOM_FLOAT(0,600); - pevNew->avelocity.z = RANDOM_FLOAT(0,600); - CHANGE_METHOD(ENT(pevNew), em_think, SUB_Remove); - pevNew->ltime = gpGlobals->time; - pevNew->nextthink = gpGlobals->time + RANDOM_FLOAT(10,20); - pevNew->frame = 0; - pevNew->flags = 0; -} - - -static void ThrowHead(entvars_t *pev, char *szGibModel, floatflDamage) -{ - SET_MODEL(ENT(pev), szGibModel); - pev->frame = 0; - pev->nextthink = -1; - pev->movetype = MOVETYPE_BOUNCE; - pev->takedamage = DAMAGE_NO; - pev->solid = SOLID_NOT; - pev->view_ofs = Vector(0,0,8); - UTIL_SetSize(pev, Vector(-16,-16,0), Vector(16,16,56)); - pev->velocity = VecVelocityForDamage(flDamage); - pev->avelocity = RANDOM_FLOAT(-1,1) * Vector(0,600,0); - pev->origin.z -= 24; - ClearBits(pev->flags, FL_ONGROUND); -} - - -*/ -#endif - -int TrainSpeed(int iSpeed, int iMax) -{ - float fSpeed, fMax; - int iRet = 0; - - fMax = (float)iMax; - fSpeed = iSpeed; - - fSpeed = fSpeed/fMax; - - if (iSpeed < 0) - iRet = TRAIN_BACK; - else if (iSpeed == 0) - iRet = TRAIN_NEUTRAL; - else if (fSpeed < 0.33) - iRet = TRAIN_SLOW; - else if (fSpeed < 0.66) - iRet = TRAIN_MEDIUM; - else - iRet = TRAIN_FAST; - - return iRet; -} - - -// override takehealth -// bitsDamageType indicates type of damage healed. - -int CBasePlayer :: TakeHealth( float flHealth, int bitsDamageType ) -{ - // QUAKECLASSIC - if (pev->health <= 0) - return 0; - if ( !(bitsDamageType & DMG_IGNORE_MAXHEALTH) && (pev->health >= pev->max_health) ) - return 0; - int iHealAmount = ceil(flHealth); - - pev->health += iHealAmount; - if ( !(bitsDamageType & DMG_IGNORE_MAXHEALTH) && (pev->health >= pev->max_health) ) - pev->health = pev->max_health; - - if (pev->health > 250) - pev->health = 250; - return 1; -} - -Vector CBasePlayer :: GetGunPosition( ) -{ -// UTIL_MakeVectors(pev->v_angle); -// m_HackedGunPos = pev->view_ofs; - Vector origin; - - origin = pev->origin + pev->view_ofs; - return origin; -} - -//========================================================= -// TraceAttack -//========================================================= -void CBasePlayer :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) -{ - if ( pev->takedamage ) - { - SpawnBlood(ptr->vecEndPos, BloodColor(), flDamage);// a little surface blood. - TraceBleed( flDamage, vecDir, ptr, bitsDamageType ); - AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType ); - } -} - -void CBasePlayer::RemoveAllItems( BOOL removeSuit ) -{ - if (m_pActiveItem) - { - ResetAutoaim( ); - m_pActiveItem->Holster( ); - m_pActiveItem = NULL; - } - - m_pLastItem = NULL; - - int i; - CBasePlayerItem *pPendingItem; - for (i = 0; i < MAX_ITEM_TYPES; i++) - { - m_pActiveItem = m_rgpPlayerItems[i]; - while (m_pActiveItem) - { - pPendingItem = m_pActiveItem->m_pNext; - m_pActiveItem->Drop( ); - m_pActiveItem = pPendingItem; - } - m_rgpPlayerItems[i] = NULL; - } - m_pActiveItem = NULL; - - pev->viewmodel = 0; - pev->weaponmodel = 0; - - if ( removeSuit ) - pev->weapons = 0; - else - pev->weapons &= ~WEAPON_ALLWEAPONS; - - for ( i = 0; i < MAX_AMMO_SLOTS;i++) - m_rgAmmo[i] = 0; - - UpdateClientData(); - // send Selected Weapon Message to our client - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); - WRITE_BYTE(0); - WRITE_BYTE(0); - WRITE_BYTE(0); - MESSAGE_END(); -} - -/* - * GLOBALS ASSUMED SET: g_ulModelIndexPlayer - * - * ENTITY_METHOD(PlayerDie) - */ -entvars_t *g_pevLastInflictor; // Set in combat.cpp. Used to pass the damage inflictor for death messages. - // Better solution: Add as parameter to all Killed() functions. - -void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib ) -{ - g_pGameRules->PlayerKilled( this, pevAttacker, g_pevLastInflictor ); - - if ( m_pTank != NULL ) - { - m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - } - - - //Remove all powerups and powerup timers - m_flInvincibleFinished = m_flRadsuitFinished = m_flInvisibleFinished = m_flSuperDamageFinished = 0.0; - PowerUpThink(); - - SetAnimation( PLAYER_DIE ); - - m_iRespawnFrames = 0; - - pev->modelindex = g_ulModelIndexPlayer; // don't use eyes - - pev->deadflag = DEAD_DYING; - pev->movetype = MOVETYPE_TOSS; - ClearBits(pev->flags, FL_ONGROUND); - - if ( m_iQuakeWeapon == IT_LIGHTNING ) - { - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usLightning, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, 0, 1, 0, 0 ); - - if ( m_pActiveItem ) - ((CQuakeGun*)m_pActiveItem)->DestroyEffect(); - } - - if (pev->velocity.z < 10) - pev->velocity.z += RANDOM_FLOAT(0,300); - - // clear out the suit message cache so we don't keep chattering - SetSuitUpdate(NULL, FALSE, 0); - - // send "health" update message to zero - m_iClientHealth = 0; - MESSAGE_BEGIN( MSG_ONE, gmsgHealth, NULL, pev ); - WRITE_BYTE( m_iClientHealth ); - MESSAGE_END(); - - // Tell Ammo Hud that the player is dead - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); - WRITE_BYTE(0); - WRITE_BYTE(0XFF); - WRITE_BYTE(0xFF); - MESSAGE_END(); - - - // UNDONE: Put this in, but add FFADE_PERMANENT and make fade time 8.8 instead of 4.12 - // UTIL_ScreenFade( edict(), Vector(128,0,0), 6, 15, 255, FFADE_OUT | FFADE_MODULATE ); - - //Quake Player always gibs - if ( pev->health < -40 ) - { - pev->solid = SOLID_NOT; - - GibMonster(); // This clears pev->model - pev->effects |= EF_NODRAW; - return; - } - - DeathSound(); - - pev->angles.x = 0; - pev->angles.z = 0; - - SetThink(&CBasePlayer::PlayerDeathThink); - pev->nextthink = gpGlobals->time + 0.1; -} - - -// Set the activity based on an event or current state -void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim ) -{ - int animDesired; - float speed; - char szAnim[64]; - - speed = pev->velocity.Length2D(); - - if (pev->flags & FL_FROZEN) - { - speed = 0; - playerAnim = PLAYER_IDLE; - } - - switch (playerAnim) - { - case PLAYER_JUMP: - m_IdealActivity = ACT_HOP; - break; - - case PLAYER_SUPERJUMP: - m_IdealActivity = ACT_LEAP; - break; - - case PLAYER_DIE: - m_IdealActivity = ACT_DIESIMPLE; - m_IdealActivity = GetDeathActivity( ); - break; - - case PLAYER_ATTACK1: - switch( m_Activity ) - { - case ACT_HOVER: - case ACT_SWIM: - case ACT_HOP: - case ACT_LEAP: - case ACT_DIESIMPLE: - m_IdealActivity = m_Activity; - break; - default: - m_IdealActivity = ACT_RANGE_ATTACK1; - break; - } - break; - case PLAYER_IDLE: - case PLAYER_WALK: - if ( !FBitSet( pev->flags, FL_ONGROUND ) && (m_Activity == ACT_HOP || m_Activity == ACT_LEAP) ) // Still jumping - { - m_IdealActivity = m_Activity; - } - else if ( pev->waterlevel > 1 ) - { - if ( speed == 0 ) - m_IdealActivity = ACT_HOVER; - else - m_IdealActivity = ACT_SWIM; - } - else - { - m_IdealActivity = ACT_WALK; - } - break; - } - - switch (m_IdealActivity) - { - case ACT_HOVER: - case ACT_LEAP: - case ACT_SWIM: - case ACT_HOP: - case ACT_DIESIMPLE: - default: - if ( m_Activity == m_IdealActivity) - return; - m_Activity = m_IdealActivity; - - animDesired = LookupActivity( m_Activity ); - // Already using the desired animation? - if (pev->sequence == animDesired) - return; - - pev->gaitsequence = 0; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - - case ACT_RANGE_ATTACK1: - if ( FBitSet( pev->flags, FL_DUCKING ) ) // crouching - strcpy( szAnim, "crouch_shoot_" ); - else - strcpy( szAnim, "ref_shoot_" ); - strcat( szAnim, m_szAnimExtention ); - animDesired = LookupSequence( szAnim ); - if (animDesired == -1) - animDesired = 0; - - if ( pev->sequence != animDesired || !m_fSequenceLoops ) - { - pev->frame = 0; - } - - if (!m_fSequenceLoops) - { - pev->effects |= EF_NOINTERP; - } - - m_Activity = m_IdealActivity; - - pev->sequence = animDesired; - ResetSequenceInfo( ); - break; - - case ACT_WALK: - if (m_Activity != ACT_RANGE_ATTACK1 || m_fSequenceFinished) - { - if ( FBitSet( pev->flags, FL_DUCKING ) ) // crouching - strcpy( szAnim, "crouch_aim_" ); - else - strcpy( szAnim, "ref_aim_" ); - strcat( szAnim, m_szAnimExtention ); - animDesired = LookupSequence( szAnim ); - if (animDesired == -1) - animDesired = 0; - m_Activity = ACT_WALK; - } - else - { - animDesired = pev->sequence; - } - } - - if ( FBitSet( pev->flags, FL_DUCKING ) ) - { - if ( speed == 0) - { - pev->gaitsequence = LookupActivity( ACT_CROUCHIDLE ); - // pev->gaitsequence = LookupActivity( ACT_CROUCH ); - } - else - { - pev->gaitsequence = LookupActivity( ACT_CROUCH ); - } - } - else if ( speed > 220 ) - { - pev->gaitsequence = LookupActivity( ACT_RUN ); - } - else if (speed > 0) - { - pev->gaitsequence = LookupActivity( ACT_WALK ); - } - else - { - // pev->gaitsequence = LookupActivity( ACT_WALK ); - pev->gaitsequence = LookupSequence( "deep_idle" ); - } - - - // Already using the desired animation? - if (pev->sequence == animDesired) - return; - - //ALERT( at_console, "Set animation to %d\n", animDesired ); - // Reset to first frame of desired animation - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); -} - - -/* -=========== -WaterMove -============ -*/ -#define AIRTIME 12 // lung full of air lasts this many seconds - -void CBasePlayer::WaterMove() -{ - int air; - - if (pev->movetype == MOVETYPE_NOCLIP) - return; - - if (pev->health < 0) - return; - - // waterlevel 0 - not in water - // waterlevel 1 - feet in water - // waterlevel 2 - waist in water - // waterlevel 3 - head in water - - if (pev->waterlevel != 3) - { - // not underwater - - // play 'up for air' sound - if (pev->air_finished < gpGlobals->time) - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade1.wav", 1, ATTN_NORM); - else if (pev->air_finished < gpGlobals->time + 9) - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade2.wav", 1, ATTN_NORM); - - pev->air_finished = gpGlobals->time + AIRTIME; - pev->dmg = 2; - - // if we took drowning damage, give it back slowly - if (m_idrowndmg > m_idrownrestored) - { - // set drowning damage bit. hack - dmg_drownrecover actually - // makes the time based damage code 'give back' health over time. - // make sure counter is cleared so we start count correctly. - - // NOTE: this actually causes the count to continue restarting - // until all drowning damage is healed. - - m_bitsDamageType &= ~DMG_DROWN; - - /* m_bitsDamageType |= DMG_DROWNRECOVER; - - m_rgbTimeBasedDamage[itbd_DrownRecover] = 0;*/ - } - - } - else - { // fully under water - // stop restoring damage while underwater - m_bitsDamageType &= ~DMG_DROWNRECOVER; - m_rgbTimeBasedDamage[itbd_DrownRecover] = 0; - - if (pev->air_finished < gpGlobals->time) // drown! - { - if (pev->pain_finished < gpGlobals->time) - { - // take drowning damage - pev->dmg += 1; - if (pev->dmg > 5) - pev->dmg = 5; - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), pev->dmg, DMG_DROWN); - pev->pain_finished = gpGlobals->time + 1; - - // track drowning damage, give it back when - // player finally takes a breath - - m_idrowndmg += pev->dmg; - } - } - else - { - m_bitsDamageType &= ~DMG_DROWN; - } - } - - if (!pev->waterlevel) - { - if (FBitSet(pev->flags, FL_INWATER)) - { -#if 0 - // play leave water sound - switch (RANDOM_LONG(0,3)) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade2.wav", 1, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade3.wav", 1, ATTN_NORM); break; - case 3: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade4.wav", 1, ATTN_NORM); break; - } -#endif - - ClearBits(pev->flags, FL_INWATER); - } - return; - } - - // make bubbles - - air = (int)(pev->air_finished - gpGlobals->time); - if (!RANDOM_LONG(0,0x1f) && RANDOM_LONG(0,AIRTIME-1) >= air) - { - switch (RANDOM_LONG(0,3)) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_swim1.wav", 0.8, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_swim2.wav", 0.8, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_swim3.wav", 0.8, ATTN_NORM); break; - case 3: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_swim4.wav", 0.8, ATTN_NORM); break; - } - } - - if (pev->watertype == CONTENT_LAVA) // do damage - { - if (pev->dmgtime < gpGlobals->time) - { - if ( m_iQuakeItems & IT_SUIT ) - pev->dmgtime = gpGlobals->time + 1.0; - else - pev->dmgtime = gpGlobals->time + 0.2; - - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), 10 * pev->waterlevel, DMG_BURN ); - } - } - else if (pev->watertype == CONTENT_SLIME) // do damage - { - if (pev->dmgtime < gpGlobals->time) - { - pev->dmgtime = gpGlobals->time + 1.0; - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), 4 * pev->waterlevel, DMG_ACID ); - } - } - - if (!FBitSet(pev->flags, FL_INWATER)) - { -#if 0 - // player enter water sound - if (pev->watertype == CONTENT_WATER) - { - switch (RANDOM_LONG(0,3)) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade2.wav", 1, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade3.wav", 1, ATTN_NORM); break; - case 3: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade4.wav", 1, ATTN_NORM); break; - } - } -#endif - - SetBits(pev->flags, FL_INWATER); - pev->dmgtime = 0; - } - - if (!FBitSet(pev->flags, FL_WATERJUMP)) - pev->velocity = pev->velocity - 0.8 * pev->waterlevel * gpGlobals->frametime * pev->velocity; -} - - -// TRUE if the player is attached to a ladder -BOOL CBasePlayer::IsOnLadder( void ) -{ - return (pev->movetype == MOVETYPE_FLY); -} - -void CBasePlayer::PlayerDeathThink(void) -{ - float flForward; - - if (FBitSet(pev->flags, FL_ONGROUND)) - { - flForward = pev->velocity.Length() - 20; - if (flForward <= 0) - pev->velocity = g_vecZero; - else - pev->velocity = flForward * pev->velocity.Normalize(); - } - - if ( m_iQuakeWeapon ) - { - DropBackpack(); - } - - if (pev->modelindex && (!m_fSequenceFinished) && (pev->deadflag == DEAD_DYING)) - { - StudioFrameAdvance( ); - - m_iRespawnFrames++; // Note, these aren't necessarily real "frames", so behavior is dependent on # of client movement commands - if ( m_iRespawnFrames < 120 ) // Animations should be no longer than this - return; - } - - if (m_fSequenceFinished == 0) - { - StudioFrameAdvance(); - return; - } - - if (pev->deadflag == DEAD_DYING) - pev->deadflag = DEAD_DEAD; - - StopAnimation(); - - - pev->effects |= EF_NOINTERP; - pev->framerate = 0.0; - - BOOL fAnyButtonDown = (pev->button & ~IN_SCORE ); - - // wait for all buttons released - if (pev->deadflag == DEAD_DEAD) - { - if (fAnyButtonDown) - return; - - if ( g_pGameRules->FPlayerCanRespawn( this ) ) - { - m_fDeadTime = gpGlobals->time; - pev->deadflag = DEAD_RESPAWNABLE; - } - - return; - } - -// if the player has been dead for one second longer than allowed by forcerespawn, -// forcerespawn isn't on. Send the player off to an intermission camera until they -// choose to respawn. -/* if ( g_pGameRules->IsMultiplayer() && ( gpGlobals->time > (m_fDeadTime + 6) ) && !(m_afPhysicsFlags & PFLAG_OBSERVER) ) - { - // go to dead camera. - StartDeathCam(); - }*/ - -// wait for any button down, or mp_forcerespawn is set and the respawn time is up - if (!fAnyButtonDown - && !( g_pGameRules->IsMultiplayer() && CVAR_GET_FLOAT("mp_forcerespawn") > 0 && (gpGlobals->time > (m_fDeadTime + 5))) ) - return; - - pev->button = 0; - m_iRespawnFrames = 0; - - - - //ALERT(at_console, "Respawn\n"); - - respawn(pev, !(m_afPhysicsFlags & PFLAG_OBSERVER) );// don't copy a corpse if we're in deathcam. - pev->nextthink = -1; -} - -//========================================================= -// StartDeathCam - find an intermission spot and send the -// player off into observer mode -//========================================================= -void CBasePlayer::StartDeathCam( void ) -{ - edict_t *pSpot, *pNewSpot; - int iRand; - - if ( pev->view_ofs == g_vecZero ) - { - // don't accept subsequent attempts to StartDeathCam() - return; - } - - pSpot = FIND_ENTITY_BY_CLASSNAME( NULL, "info_intermission"); - - if ( !FNullEnt( pSpot ) ) - { - // at least one intermission spot in the world. - iRand = RANDOM_LONG( 0, 3 ); - - while ( iRand > 0 ) - { - pNewSpot = FIND_ENTITY_BY_CLASSNAME( pSpot, "info_intermission"); - - if ( pNewSpot ) - { - pSpot = pNewSpot; - } - - iRand--; - } - - CopyToBodyQue( pev ); - StartObserver( pSpot->v.origin, pSpot->v.v_angle ); - } - else - { - // no intermission spot. Push them up in the air, looking down at their corpse - TraceResult tr; - CopyToBodyQue( pev ); - UTIL_TraceLine( pev->origin, pev->origin + Vector( 0, 0, 128 ), ignore_monsters, edict(), &tr ); - StartObserver( tr.vecEndPos, UTIL_VecToAngles( tr.vecEndPos - pev->origin ) ); - return; - } -} - -void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) -{ - m_iHideHUD |= (HIDEHUD_HEALTH | HIDEHUD_WEAPONS); - m_afPhysicsFlags |= PFLAG_OBSERVER; - - pev->effects = EF_NODRAW; - pev->view_ofs = g_vecZero; - pev->angles = pev->v_angle = vecViewAngle; - pev->fixangle = TRUE; - pev->solid = SOLID_NOT; - pev->takedamage = DAMAGE_NO; - pev->movetype = MOVETYPE_NONE; - UTIL_SetOrigin( pev, vecPosition ); - - ClearBits( m_afPhysicsFlags, PFLAG_DUCKING ); - ClearBits( pev->flags, FL_DUCKING ); - // pev->flags = FL_CLIENT | FL_SPECTATOR; // Should we set Spectator flag? Or is it reserver for people connecting with spectator 1? - pev->deadflag = DEAD_RESPAWNABLE; - - // Tell the physics code that this player's now in observer mode - Observer_SetMode(OBS_CHASE_LOCKED); - m_flNextObserverInput = 0; -} - -// -// PlayerUse - handles USE keypress -// -#define PLAYER_SEARCH_RADIUS (float)64 - -void CBasePlayer::PlayerUse ( void ) -{ - // Was use pressed or released? - if ( ! ((pev->button | m_afButtonPressed | m_afButtonReleased) & IN_USE) ) - return; - - // Hit Use on a train? - if ( m_afButtonPressed & IN_USE ) - { - if ( m_pTank != NULL ) - { - // Stop controlling the tank - // TODO: Send HUD Update - m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - return; - } - else - { - if ( m_afPhysicsFlags & PFLAG_ONTRAIN ) - { - m_afPhysicsFlags &= ~PFLAG_ONTRAIN; - m_iTrain = TRAIN_NEW|TRAIN_OFF; - return; - } - else - { // Start controlling the train! - CBaseEntity *pTrain = CBaseEntity::Instance( pev->groundentity ); - - if ( pTrain && !(pev->button & IN_JUMP) && FBitSet(pev->flags, FL_ONGROUND) && (pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) && pTrain->OnControls(pev) ) - { - m_afPhysicsFlags |= PFLAG_ONTRAIN; - m_iTrain = TrainSpeed(pTrain->pev->speed, pTrain->pev->impulse); - m_iTrain |= TRAIN_NEW; - EMIT_SOUND( ENT(pev), CHAN_ITEM, "plats/train_use1.wav", 0.8, ATTN_NORM); - return; - } - } - } - } - - CBaseEntity *pObject = NULL; - CBaseEntity *pClosest = NULL; - Vector vecLOS; - float flMaxDot = VIEW_FIELD_NARROW; - float flDot; - - UTIL_MakeVectors ( pev->v_angle );// so we know which way we are facing - - while ((pObject = UTIL_FindEntityInSphere( pObject, pev->origin, PLAYER_SEARCH_RADIUS )) != NULL) - { - - if (pObject->ObjectCaps() & (FCAP_IMPULSE_USE | FCAP_CONTINUOUS_USE | FCAP_ONOFF_USE)) - { - // !!!PERFORMANCE- should this check be done on a per case basis AFTER we've determined that - // this object is actually usable? This dot is being done for every object within PLAYER_SEARCH_RADIUS - // when player hits the use key. How many objects can be in that area, anyway? (sjb) - vecLOS = (VecBModelOrigin( pObject->pev ) - (pev->origin + pev->view_ofs)); - - // This essentially moves the origin of the target to the corner nearest the player to test to see - // if it's "hull" is in the view cone - vecLOS = UTIL_ClampVectorToBox( vecLOS, pObject->pev->size * 0.5 ); - - flDot = DotProduct (vecLOS , gpGlobals->v_forward); - if (flDot > flMaxDot ) - {// only if the item is in front of the user - pClosest = pObject; - flMaxDot = flDot; -// ALERT( at_console, "%s : %f\n", STRING( pObject->pev->classname ), flDot ); - } -// ALERT( at_console, "%s : %f\n", STRING( pObject->pev->classname ), flDot ); - } - } - pObject = pClosest; - - // Found an object - if (pObject ) - { - //!!!UNDONE: traceline here to prevent USEing buttons through walls - int caps = pObject->ObjectCaps(); - - if ( m_afButtonPressed & IN_USE ) - EMIT_SOUND( ENT(pev), CHAN_ITEM, "common/wpn_select.wav", 0.4, ATTN_NORM); - - if ( ( (pev->button & IN_USE) && (caps & FCAP_CONTINUOUS_USE) ) || - ( (m_afButtonPressed & IN_USE) && (caps & (FCAP_IMPULSE_USE|FCAP_ONOFF_USE)) ) ) - { - if ( caps & FCAP_CONTINUOUS_USE ) - m_afPhysicsFlags |= PFLAG_USING; - - pObject->Use( this, this, USE_SET, 1 ); - } - // UNDONE: Send different USE codes for ON/OFF. Cache last ONOFF_USE object to send 'off' if you turn away - else if ( (m_afButtonReleased & IN_USE) && (pObject->ObjectCaps() & FCAP_ONOFF_USE) ) // BUGBUG This is an "off" use - { - pObject->Use( this, this, USE_SET, 0 ); - } - } - else - { - if ( m_afButtonPressed & IN_USE ) - EMIT_SOUND( ENT(pev), CHAN_ITEM, "common/wpn_denyselect.wav", 0.4, ATTN_NORM); - } -} - - - -void CBasePlayer::Jump() -{ - Vector vecWallCheckDir;// direction we're tracing a line to find a wall when walljumping - Vector vecAdjustedVelocity; - Vector vecSpot; - TraceResult tr; - - if (FBitSet(pev->flags, FL_WATERJUMP)) - return; - - if (pev->waterlevel >= 2) - { - return; - } - - // jump velocity is sqrt( height * gravity * 2) - - // If this isn't the first frame pressing the jump button, break out. - if ( !FBitSet( m_afButtonPressed, IN_JUMP ) ) - return; // don't pogo stick - - if ( !(pev->flags & FL_ONGROUND) || !pev->groundentity ) - { - return; - } - -// many features in this function use v_forward, so makevectors now. - UTIL_MakeVectors (pev->angles); - - SetAnimation( PLAYER_JUMP ); - - if ( FBitSet(pev->flags, FL_DUCKING ) || FBitSet(m_afPhysicsFlags, PFLAG_DUCKING) ) - { - if ( m_fLongJump && (pev->button & IN_DUCK) && gpGlobals->time - m_flDuckTime < 1 && pev->velocity.Length() > 50 ) - {// If jump pressed within a second of duck while moving, long jump! - SetAnimation( PLAYER_SUPERJUMP ); - } - } - - // If you're standing on a conveyor, add it's velocity to yours (for momentum) - entvars_t *pevGround = VARS(pev->groundentity); - if ( pevGround && (pevGround->flags & FL_CONVEYOR) ) - { - pev->velocity = pev->velocity + pev->basevelocity; - } -} - - - -// This is a glorious hack to find free space when you've crouched into some solid space -// Our crouching collisions do not work correctly for some reason and this is easier -// than fixing the problem :( -void FixPlayerCrouchStuck( edict_t *pPlayer ) -{ - TraceResult trace; - - // Move up as many as 18 pixels if the player is stuck. - for ( int i = 0; i < 18; i++ ) - { - UTIL_TraceHull( pPlayer->v.origin, pPlayer->v.origin, dont_ignore_monsters, head_hull, pPlayer, &trace ); - if ( trace.fStartSolid ) - pPlayer->v.origin.z ++; - else - break; - } -} - -void CBasePlayer::Duck( ) -{ - if (pev->button & IN_DUCK) - { - SetAnimation( PLAYER_WALK ); - } -} - -// -// ID's player as such. -// -int CBasePlayer::Classify ( void ) -{ - return CLASS_PLAYER; -} - - -void CBasePlayer::AddPoints( int score, BOOL bAllowNegativeScore ) -{ - // Positive score always adds - if ( score < 0 ) - { - if ( !bAllowNegativeScore ) - { - if ( pev->frags < 0 ) // Can't go more negative - return; - - if ( -score > pev->frags ) // Will this go negative? - { - score = -pev->frags; // Sum will be 0 - } - } - } - - pev->frags += score; - - MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); - WRITE_BYTE( ENTINDEX(edict()) ); - WRITE_SHORT( pev->frags ); - WRITE_SHORT( m_iDeaths ); - WRITE_SHORT( pev->team ); - MESSAGE_END(); -} - - -void CBasePlayer::AddPointsToTeam( int score, BOOL bAllowNegativeScore ) -{ - int index = entindex(); - - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - - if ( pPlayer && i != index ) - { - if ( g_pGameRules->PlayerRelationship( this, pPlayer ) == GR_TEAMMATE ) - { - pPlayer->AddPoints( score, bAllowNegativeScore ); - } - } - } -} - -#if 0 -void CBasePlayer::CheckWeapon(void) -{ - // play a weapon idle anim if it's time! - if ( gpGlobals->time > m_flTimeWeaponIdle ) - { - WeaponIdle ( ); - } -} -#endif - - -// play a footstep if it's time - this will eventually be frame-based. not time based. - -#define STEP_CONCRETE 0 // default step sound -#define STEP_METAL 1 // metal floor -#define STEP_DIRT 2 // dirt, sand, rock -#define STEP_VENT 3 // ventillation duct -#define STEP_GRATE 4 // metal grating -#define STEP_TILE 5 // floor tiles -#define STEP_SLOSH 6 // shallow liquid puddle -#define STEP_WADE 7 // wading in liquid -#define STEP_LADDER 8 // climbing ladder - -// Play correct step sound for material we're on or in - -void CBasePlayer :: PlayStepSound(int step, float fvol) -{ - return; - - static int iSkipStep = 0; - - if ( !g_pGameRules->PlayFootstepSounds( this, fvol ) ) - return; - - // irand - 0,1 for right foot, 2,3 for left foot - // used to alternate left and right foot - int irand = RANDOM_LONG(0,1) + (m_iStepLeft * 2); - - m_iStepLeft = !m_iStepLeft; - - switch (step) - { - default: - case STEP_CONCRETE: - switch (irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_step1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_step3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_step2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_step4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_METAL: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_metal1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_metal3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_metal2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_metal4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_DIRT: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_dirt1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_dirt3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_dirt2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_dirt4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_VENT: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_duct1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_duct3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_duct2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_duct4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_GRATE: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_grate1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_grate3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_grate2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_grate4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_TILE: - if (!RANDOM_LONG(0,4)) - irand = 4; - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile4.wav", fvol, ATTN_NORM); break; - case 4: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile5.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_SLOSH: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_slosh1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_slosh3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_slosh2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_slosh4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_WADE: - if ( iSkipStep == 0 ) - { - iSkipStep++; - break; - } - - if ( iSkipStep++ == 3 ) - { - iSkipStep = 0; - } - - switch (irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_wade1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_wade2.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_wade3.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_wade4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_LADDER: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_ladder1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_ladder3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_ladder2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_ladder4.wav", fvol, ATTN_NORM); break; - } - break; - } -} - -// Simple mapping from texture type character to step type - -int MapTextureTypeStepType(char chTextureType) -{ -switch (chTextureType) - { - default: - case CHAR_TEX_CONCRETE: return STEP_CONCRETE; - case CHAR_TEX_METAL: return STEP_METAL; - case CHAR_TEX_DIRT: return STEP_DIRT; - case CHAR_TEX_VENT: return STEP_VENT; - case CHAR_TEX_GRATE: return STEP_GRATE; - case CHAR_TEX_TILE: return STEP_TILE; - case CHAR_TEX_SLOSH: return STEP_SLOSH; - } -} - -// Play left or right footstep based on material player is on or in - -void CBasePlayer :: UpdateStepSound( void ) -{ - int fWalking; - float fvol; - char szbuffer[64]; - const char *pTextureName; - Vector start, end; - float rgfl1[3]; - float rgfl2[3]; - Vector knee; - Vector feet; - Vector center; - float height; - float speed; - float velrun; - float velwalk; - float flduck; - int fLadder; - int step; - - if (gpGlobals->time <= m_flTimeStepSound) - return; - - if (pev->flags & FL_FROZEN) - return; - - speed = pev->velocity.Length(); - - // determine if we are on a ladder - fLadder = IsOnLadder(); - - // UNDONE: need defined numbers for run, walk, crouch, crouch run velocities!!!! - if (FBitSet(pev->flags, FL_DUCKING) || fLadder) - { - velwalk = 60; // These constants should be based on cl_movespeedkey * cl_forwardspeed somehow - velrun = 80; // UNDONE: Move walking to server - flduck = 0.1; - } - else - { - velwalk = 120; - velrun = 210; - flduck = 0.0; - } - - // ALERT (at_console, "vel: %f\n", vecVel.Length()); - - // if we're on a ladder or on the ground, and we're moving fast enough, - // play step sound. Also, if m_flTimeStepSound is zero, get the new - // sound right away - we just started moving in new level. - - if ((fLadder || FBitSet (pev->flags, FL_ONGROUND)) && pev->velocity != g_vecZero - && (speed >= velwalk || !m_flTimeStepSound)) - { - SetAnimation( PLAYER_WALK ); - - fWalking = speed < velrun; - - center = knee = feet = (pev->absmin + pev->absmax) * 0.5; - height = pev->absmax.z - pev->absmin.z; - - knee.z = pev->absmin.z + height * 0.2; - feet.z = pev->absmin.z; - - // find out what we're stepping in or on... - if (fLadder) - { - step = STEP_LADDER; - fvol = 0.35; - m_flTimeStepSound = gpGlobals->time + 0.35; - } - else if ( UTIL_PointContents ( knee ) == CONTENTS_WATER ) - { - step = STEP_WADE; - fvol = 0.65; - m_flTimeStepSound = gpGlobals->time + 0.6; - } - else if (UTIL_PointContents ( feet ) == CONTENTS_WATER ) - { - step = STEP_SLOSH; - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - } - else - { - // find texture under player, if different from current texture, - // get material type - - start = end = center; // center point of player BB - start.z = end.z = pev->absmin.z; // copy zmin - start.z += 4.0; // extend start up - end.z -= 24.0; // extend end down - - start.CopyToArray(rgfl1); - end.CopyToArray(rgfl2); - - pTextureName = TRACE_TEXTURE( ENT( pev->groundentity), rgfl1, rgfl2 ); - if ( pTextureName ) - { - // strip leading '-0' or '{' or '!' - if (*pTextureName == '-') - pTextureName += 2; - if (*pTextureName == '{' || *pTextureName == '!') - pTextureName++; - - if (_strnicmp(pTextureName, m_szTextureName, CBTEXTURENAMEMAX-1)) - { - // current texture is different from texture player is on... - // set current texture - strcpy(szbuffer, pTextureName); - szbuffer[CBTEXTURENAMEMAX - 1] = 0; - strcpy(m_szTextureName, szbuffer); - - // ALERT ( at_aiconsole, "texture: %s\n", m_szTextureName ); - - // get texture type - m_chTextureType = TEXTURETYPE_Find(m_szTextureName); - } - } - - step = MapTextureTypeStepType(m_chTextureType); - - switch (m_chTextureType) - { - default: - case CHAR_TEX_CONCRETE: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_METAL: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_DIRT: - fvol = fWalking ? 0.25 : 0.55; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_VENT: - fvol = fWalking ? 0.4 : 0.7; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_GRATE: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_TILE: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_SLOSH: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - } - } - - m_flTimeStepSound += flduck; // slower step time if ducking - - // play the sound - - // 35% volume if ducking - if ( pev->flags & FL_DUCKING ) - fvol *= 0.35; - } -} - -void CBasePlayer::PowerUpThink(void) -{ - int iPowerUp = 0; - bool bUpdate = FALSE; - - //Quad time ran out - if ( m_iQuakeItems & IT_QUAD && m_flSuperDamageFinished < gpGlobals->time ) - { - //Clear the glowing shell effect - pev->renderfx = kRenderFxNone; - //Reset quad timer - m_flSuperDamageFinished = 0.0; - m_bPlayedQuadSound = FALSE; - - //Remove the powerup - m_iQuakeItems &= ~IT_QUAD; - - //We have other powerups, choose the one with more time remaining - if ( m_iQuakeItems & IT_INVISIBILITY || m_iQuakeItems & IT_INVULNERABILITY ) - { - if ( m_iQuakeItems & IT_INVULNERABILITY ) - { - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 255, 128, 0 ); // RGB - pev->renderamt = 100; // Shell size - - iPowerUp = 2; - } - - if ( m_iQuakeItems & IT_INVISIBILITY ) - { - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 128, 128, 128 ); // RGB - pev->renderamt = 5; // Shell size - } - } - - bUpdate = TRUE; - } - - if ( m_iQuakeItems & IT_QUAD && m_flSuperDamageFinished <= gpGlobals->time + 3 && !m_bPlayedQuadSound ) - { - ClientPrint(pev, HUD_PRINTNOTIFY, "#Quad_Damage_Off" ); - EMIT_SOUND( ENT(pev), CHAN_ITEM, "items/damage2.wav", 1, ATTN_NORM ); - - m_bPlayedQuadSound = TRUE; - } - - //Env Suit time ran out - if ( m_iQuakeItems & IT_SUIT && m_flRadsuitFinished < gpGlobals->time ) - { - m_flRadsuitFinished = 0.0; - m_bPlayedEnvSound = FALSE; - - //Remove the powerup - m_iQuakeItems &= ~IT_SUIT; - - //We have other powerups, choose the one with more time remaining - if ( m_iQuakeItems & IT_QUAD || m_iQuakeItems & IT_INVULNERABILITY ) - { - - if ( m_iQuakeItems & IT_INVULNERABILITY && m_iQuakeItems & IT_QUAD ) - { - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 255, 125, 255 ); // RGB - pev->renderamt = 100; // Shell size - } - - else if ( m_flSuperDamageFinished > m_flInvincibleFinished ) - { - pev->renderfx = kRenderFxNone; - pev->rendermode = kRenderNormal; - pev->renderamt = 255; - - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 128, 128, 255 ); // RGB - pev->renderamt = 100; // Shell size - } - else - { - pev->renderfx = kRenderFxNone; - pev->rendermode = kRenderNormal; - pev->renderamt = 255; - - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 255, 128, 0 ); // RGB - pev->renderamt = 100; // Shell size - } - } - else //Clear the invisi screen effect - { - pev->renderfx = kRenderFxNone; - pev->rendermode = kRenderNormal; - pev->renderamt = 255; - } - } - - if ( m_iQuakeItems & IT_SUIT && m_flRadsuitFinished <= gpGlobals->time + 3 && !m_bPlayedEnvSound ) - { - ClientPrint(pev, HUD_PRINTNOTIFY, "#BioSuit_Off" ); - EMIT_SOUND( ENT(pev), CHAN_ITEM, "items/suit2.wav", 1, ATTN_NORM ); - - m_bPlayedEnvSound = TRUE; - - } - - //Invisibility time ran out - if ( m_iQuakeItems & IT_INVISIBILITY && m_flInvisibleFinished < gpGlobals->time ) - { - //Reset the invi timer - m_flInvisibleFinished = 0.0; - m_bPlayedProtectSound = FALSE; - - //Remove the powerup - m_iQuakeItems &= ~IT_INVISIBILITY; - - pev->renderfx = kRenderFxNone; - pev->rendermode = kRenderNormal; - pev->renderamt = 255; - - //We have other powerups, choose the one with more time remaining - if ( m_iQuakeItems & IT_QUAD || m_iQuakeItems & IT_INVULNERABILITY ) - { - if ( m_iQuakeItems & IT_QUAD && m_iQuakeItems & IT_INVULNERABILITY ) - { - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 255, 125, 255 ); // RGB - pev->renderamt = 100; // Shell size - - } - - else if ( m_flSuperDamageFinished > m_flInvincibleFinished ) - { - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 128, 128, 255 ); // RGB - pev->renderamt = 100; // Shell size - } - else - { - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 255, 128, 0 ); // RGB - pev->renderamt = 100; // Shell size - } - } - else //Clear the invisi screen effect - { - pev->renderfx = kRenderFxNone; - pev->rendermode = kRenderNormal; - pev->renderamt = 255; - } - - //Forces our view model to re-appear - W_SetCurrentAmmo(); - - } - - if ( m_iQuakeItems & IT_INVISIBILITY && m_flInvisibleFinished <= gpGlobals->time + 3 && !m_bPlayedInvSound ) - { - ClientPrint(pev, HUD_PRINTNOTIFY, "#Ring_Shadows_Off" ); - EMIT_SOUND( ENT(pev), CHAN_ITEM, "items/inv2.wav", 1, ATTN_NORM ); - - m_bPlayedInvSound = TRUE; - - } - - //666 time ran out - if ( m_iQuakeItems & IT_INVULNERABILITY && m_flInvincibleFinished < gpGlobals->time ) - { - //Clear the glowing shell effect - pev->renderfx = kRenderFxNone; - //Reset 666 timer - m_flInvincibleFinished = 0.0; - m_bPlayedProtectSound = FALSE; - - //Remove the powerup - m_iQuakeItems &= ~IT_INVULNERABILITY; - - //We have other powerups, choose the one with more time remaining - if ( m_iQuakeItems & IT_QUAD || m_iQuakeItems & IT_INVISIBILITY ) - { - if ( m_flSuperDamageFinished > m_flInvisibleFinished ) - { - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 128, 128, 255 ); // RGB - pev->renderamt = 100; // Shell size - - iPowerUp = 1; - } - else - { - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 128, 128, 128 ); // RGB - pev->renderamt = 5; // Shell size - } - } - - bUpdate = TRUE; - } - - if ( m_iQuakeItems & IT_INVULNERABILITY && m_flInvincibleFinished <= gpGlobals->time + 3 && !m_bPlayedProtectSound ) - { - ClientPrint(pev, HUD_PRINTNOTIFY, "#Protection_Off" ); - EMIT_SOUND( ENT(pev), CHAN_ITEM, "items/protect2.wav", 1, ATTN_NORM ); - - m_bPlayedProtectSound = TRUE; - } - - if ( bUpdate ) - { - W_SetCurrentAmmo(); - - PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, - edict(), g_usPowerUp, 0, (float *)&g_vecZero, (float *)&g_vecZero, - (float)iPowerUp, 0.0, entindex(), pev->team, 1, 0 ); - } - -} - - -#define CLIMB_SHAKE_FREQUENCY 22 // how many frames in between screen shakes when climbing -#define MAX_CLIMB_SPEED 200 // fastest vertical climbing speed possible -#define CLIMB_SPEED_DEC 15 // climbing deceleration rate -#define CLIMB_PUNCH_X -7 // how far to 'punch' client X axis when climbing -#define CLIMB_PUNCH_Z 7 // how far to 'punch' client Z axis when climbing - -void CBasePlayer::PreThink(void) -{ - int buttonsChanged = (m_afButtonLast ^ pev->button); // These buttons have changed this frame - - // Debounced button codes for pressed/released - // UNDONE: Do we need auto-repeat? - m_afButtonPressed = buttonsChanged & pev->button; // The changed ones still down are "pressed" - m_afButtonReleased = buttonsChanged & (~pev->button); // The ones not down are "released" - - g_pGameRules->PlayerThink( this ); - - if ( g_fGameOver ) - return; // intermission or finale - - UTIL_MakeVectors(pev->v_angle); // is this still used? - - ItemPreFrame( ); - WaterMove(); - - if ( g_pGameRules && g_pGameRules->FAllowFlashlight() ) - m_iHideHUD &= ~HIDEHUD_FLASHLIGHT; - else - m_iHideHUD |= HIDEHUD_FLASHLIGHT; - - - // JOHN: checks if new client data (for HUD and view control) needs to be sent to the client - UpdateClientData(); - - CheckTimeBasedDamage(); - - CheckSuitUpdate(); - - // Observer Button Handling - if ( pev->iuser1 != 0 ) - { - Observer_HandleButtons(); - return; - } - - //Run Powerup think (removes powerups over time, etc) - PowerUpThink(); - - // Dead think only if they're not an observer - if (pev->deadflag >= DEAD_DYING) - { - PlayerDeathThink(); - return; - } - - // So the correct flags get sent to client asap. - // - if ( m_afPhysicsFlags & PFLAG_ONTRAIN ) - pev->flags |= FL_ONTRAIN; - else - pev->flags &= ~FL_ONTRAIN; - - // Train speed control - if ( m_afPhysicsFlags & PFLAG_ONTRAIN ) - { - CBaseEntity *pTrain = CBaseEntity::Instance( pev->groundentity ); - float vel; - - if ( !pTrain ) - { - TraceResult trainTrace; - // Maybe this is on the other side of a level transition - UTIL_TraceLine( pev->origin, pev->origin + Vector(0,0,-38), ignore_monsters, ENT(pev), &trainTrace ); - - // HACKHACK - Just look for the func_tracktrain classname - if ( trainTrace.flFraction != 1.0 && trainTrace.pHit ) - pTrain = CBaseEntity::Instance( trainTrace.pHit ); - - - if ( !pTrain || !(pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) || !pTrain->OnControls(pev) ) - { - //ALERT( at_error, "In train mode with no train!\n" ); - m_afPhysicsFlags &= ~PFLAG_ONTRAIN; - m_iTrain = TRAIN_NEW|TRAIN_OFF; - return; - } - } - else if ( !FBitSet( pev->flags, FL_ONGROUND ) || FBitSet( pTrain->pev->spawnflags, SF_TRACKTRAIN_NOCONTROL ) || (pev->button & (IN_MOVELEFT|IN_MOVERIGHT) ) ) - { - // Turn off the train if you jump, strafe, or the train controls go dead - m_afPhysicsFlags &= ~PFLAG_ONTRAIN; - m_iTrain = TRAIN_NEW|TRAIN_OFF; - return; - } - - pev->velocity = g_vecZero; - vel = 0; - if ( m_afButtonPressed & IN_FORWARD ) - { - vel = 1; - pTrain->Use( this, this, USE_SET, (float)vel ); - } - else if ( m_afButtonPressed & IN_BACK ) - { - vel = -1; - pTrain->Use( this, this, USE_SET, (float)vel ); - } - - if (vel) - { - m_iTrain = TrainSpeed(pTrain->pev->speed, pTrain->pev->impulse); - m_iTrain |= TRAIN_ACTIVE|TRAIN_NEW; - } - - } else if (m_iTrain & TRAIN_ACTIVE) - m_iTrain = TRAIN_NEW; // turn off train - - if (pev->button & IN_JUMP) - { - // If on a ladder, jump off the ladder - // else Jump - Jump(); - } - - // QUAKECLASSIC - // Duck removed - - // play a footstep if it's time - this will eventually be frame-based. not time based. - UpdateStepSound(); - - if ( !FBitSet ( pev->flags, FL_ONGROUND ) ) - { - m_flFallVelocity = -pev->velocity.z; - } - - // StudioFrameAdvance( );//!!!HACKHACK!!! Can't be hit by traceline when not animating? - - // Clear out ladder pointer - m_hEnemy = NULL; - - if ( m_afPhysicsFlags & PFLAG_ONBARNACLE ) - { - pev->velocity = g_vecZero; - } -} -/* Time based Damage works as follows: - 1) There are several types of timebased damage: - - #define DMG_PARALYZE (1 << 14) // slows affected creature down - #define DMG_NERVEGAS (1 << 15) // nerve toxins, very bad - #define DMG_POISON (1 << 16) // blood poisioning - #define DMG_RADIATION (1 << 17) // radiation exposure - #define DMG_DROWNRECOVER (1 << 18) // drown recovery - #define DMG_ACID (1 << 19) // toxic chemicals or acid burns - #define DMG_SLOWBURN (1 << 20) // in an oven - #define DMG_SLOWFREEZE (1 << 21) // in a subzero freezer - - 2) A new hit inflicting tbd restarts the tbd counter - each monster has an 8bit counter, - per damage type. The counter is decremented every second, so the maximum time - an effect will last is 255/60 = 4.25 minutes. Of course, staying within the radius - of a damaging effect like fire, nervegas, radiation will continually reset the counter to max. - - 3) Every second that a tbd counter is running, the player takes damage. The damage - is determined by the type of tdb. - Paralyze - 1/2 movement rate, 30 second duration. - Nervegas - 5 points per second, 16 second duration = 80 points max dose. - Poison - 2 points per second, 25 second duration = 50 points max dose. - Radiation - 1 point per second, 50 second duration = 50 points max dose. - Drown - 5 points per second, 2 second duration. - Acid/Chemical - 5 points per second, 10 second duration = 50 points max. - Burn - 10 points per second, 2 second duration. - Freeze - 3 points per second, 10 second duration = 30 points max. - - 4) Certain actions or countermeasures counteract the damaging effects of tbds: - - Armor/Heater/Cooler - Chemical(acid),burn, freeze all do damage to armor power, then to body - - recharged by suit recharger - Air In Lungs - drowning damage is done to air in lungs first, then to body - - recharged by poking head out of water - - 10 seconds if swiming fast - Air In SCUBA - drowning damage is done to air in tanks first, then to body - - 2 minutes in tanks. Need new tank once empty. - Radiation Syringe - Each syringe full provides protection vs one radiation dosage - Antitoxin Syringe - Each syringe full provides protection vs one poisoning (nervegas or poison). - Health kit - Immediate stop to acid/chemical, fire or freeze damage. - Radiation Shower - Immediate stop to radiation damage, acid/chemical or fire damage. - - -*/ - -// If player is taking time based damage, continue doing damage to player - -// this simulates the effect of being poisoned, gassed, dosed with radiation etc - -// anything that continues to do damage even after the initial contact stops. -// Update all time based damage counters, and shut off any that are done. - -// The m_bitsDamageType bit MUST be set if any damage is to be taken. -// This routine will detect the initial on value of the m_bitsDamageType -// and init the appropriate counter. Only processes damage every second. - -//#define PARALYZE_DURATION 30 // number of 2 second intervals to take damage -//#define PARALYZE_DAMAGE 0.0 // damage to take each 2 second interval - -//#define NERVEGAS_DURATION 16 -//#define NERVEGAS_DAMAGE 5.0 - -//#define POISON_DURATION 25 -//#define POISON_DAMAGE 2.0 - -//#define RADIATION_DURATION 50 -//#define RADIATION_DAMAGE 1.0 - -//#define ACID_DURATION 10 -//#define ACID_DAMAGE 5.0 - -//#define SLOWBURN_DURATION 2 -//#define SLOWBURN_DAMAGE 1.0 - -//#define SLOWFREEZE_DURATION 1.0 -//#define SLOWFREEZE_DAMAGE 3.0 - -/* */ - - -void CBasePlayer::CheckTimeBasedDamage() -{ - int i; - BYTE bDuration = 0; - - static float gtbdPrev = 0.0; - - if (!(m_bitsDamageType & DMG_TIMEBASED)) - return; - - // only check for time based damage approx. every 2 seconds - if ( fabs(gpGlobals->time - m_tbdPrev) < 2.0) - return; - - m_tbdPrev = gpGlobals->time; - - for (i = 0; i < CDMG_TIMEBASED; i++) - { - // make sure bit is set for damage type - if (m_bitsDamageType & (DMG_PARALYZE << i)) - { - switch (i) - { - case itbd_Paralyze: - // UNDONE - flag movement as half-speed - bDuration = PARALYZE_DURATION; - break; - case itbd_NerveGas: -// TakeDamage(pev, pev, NERVEGAS_DAMAGE, DMG_GENERIC); - bDuration = NERVEGAS_DURATION; - break; - case itbd_Poison: - TakeDamage(pev, pev, POISON_DAMAGE, DMG_GENERIC); - bDuration = POISON_DURATION; - break; - case itbd_Radiation: -// TakeDamage(pev, pev, RADIATION_DAMAGE, DMG_GENERIC); - bDuration = RADIATION_DURATION; - break; - case itbd_DrownRecover: - // NOTE: this hack is actually used to RESTORE health - // after the player has been drowning and finally takes a breath - if (m_idrowndmg > m_idrownrestored) - { - int idif = V_min(m_idrowndmg - m_idrownrestored, 10); - - TakeHealth(idif, DMG_GENERIC); - m_idrownrestored += idif; - } - bDuration = 4; // get up to 5*10 = 50 points back - break; - case itbd_Acid: -// TakeDamage(pev, pev, ACID_DAMAGE, DMG_GENERIC); - bDuration = ACID_DURATION; - break; - case itbd_SlowBurn: -// TakeDamage(pev, pev, SLOWBURN_DAMAGE, DMG_GENERIC); - bDuration = SLOWBURN_DURATION; - break; - case itbd_SlowFreeze: -// TakeDamage(pev, pev, SLOWFREEZE_DAMAGE, DMG_GENERIC); - bDuration = SLOWFREEZE_DURATION; - break; - default: - bDuration = 0; - } - - if (m_rgbTimeBasedDamage[i]) - { - // use up an antitoxin on poison or nervegas after a few seconds of damage - if (((i == itbd_NerveGas) && (m_rgbTimeBasedDamage[i] < NERVEGAS_DURATION)) || - ((i == itbd_Poison) && (m_rgbTimeBasedDamage[i] < POISON_DURATION))) - { - if (m_rgItems[ITEM_ANTIDOTE]) - { - m_rgbTimeBasedDamage[i] = 0; - m_rgItems[ITEM_ANTIDOTE]--; - SetSuitUpdate("!HEV_HEAL4", FALSE, SUIT_REPEAT_OK); - } - } - - - // decrement damage duration, detect when done. - if (!m_rgbTimeBasedDamage[i] || --m_rgbTimeBasedDamage[i] == 0) - { - m_rgbTimeBasedDamage[i] = 0; - // if we're done, clear damage bits - m_bitsDamageType &= ~(DMG_PARALYZE << i); - } - } - else - // first time taking this damage type - init damage duration - m_rgbTimeBasedDamage[i] = bDuration; - } - } -} - -/* -THE POWER SUIT - -The Suit provides 3 main functions: Protection, Notification and Augmentation. -Some functions are automatic, some require power. -The player gets the suit shortly after getting off the train in C1A0 and it stays -with him for the entire game. - -Protection - - Heat/Cold - When the player enters a hot/cold area, the heating/cooling indicator on the suit - will come on and the battery will drain while the player stays in the area. - After the battery is dead, the player starts to take damage. - This feature is built into the suit and is automatically engaged. - Radiation Syringe - This will cause the player to be immune from the effects of radiation for N seconds. Single use item. - Anti-Toxin Syringe - This will cure the player from being poisoned. Single use item. - Health - Small (1st aid kits, food, etc.) - Large (boxes on walls) - Armor - The armor works using energy to create a protective field that deflects a - percentage of damage projectile and explosive attacks. After the armor has been deployed, - it will attempt to recharge itself to full capacity with the energy reserves from the battery. - It takes the armor N seconds to fully charge. - -Notification (via the HUD) - -x Health -x Ammo -x Automatic Health Care - Notifies the player when automatic healing has been engaged. -x Geiger counter - Classic Geiger counter sound and status bar at top of HUD - alerts player to dangerous levels of radiation. This is not visible when radiation levels are normal. -x Poison - Armor - Displays the current level of armor. - -Augmentation - - Reanimation (w/adrenaline) - Causes the player to come back to life after he has been dead for 3 seconds. - Will not work if player was gibbed. Single use. - Long Jump - Used by hitting the ??? key(s). Caused the player to further than normal. - SCUBA - Used automatically after picked up and after player enters the water. - Works for N seconds. Single use. - -Things powered by the battery - - Armor - Uses N watts for every M units of damage. - Heat/Cool - Uses N watts for every second in hot/cold area. - Long Jump - Uses N watts for every jump. - Alien Cloak - Uses N watts for each use. Each use lasts M seconds. - Alien Shield - Augments armor. Reduces Armor drain by one half - -*/ - -// if in range of radiation source, ping geiger counter - -#define GEIGERDELAY 0.25 - -void CBasePlayer :: UpdateGeigerCounter( void ) -{ - BYTE range; - - // delay per update ie: don't flood net with these msgs - if (gpGlobals->time < m_flgeigerDelay) - return; - - m_flgeigerDelay = gpGlobals->time + GEIGERDELAY; - - // send range to radition source to client - - range = (BYTE) (m_flgeigerRange / 4); - - if (range != m_igeigerRangePrev) - { - m_igeigerRangePrev = range; - - MESSAGE_BEGIN( MSG_ONE, gmsgGeigerRange, NULL, pev ); - WRITE_BYTE( range ); - MESSAGE_END(); - } - - // reset counter and semaphore - if (!RANDOM_LONG(0,3)) - m_flgeigerRange = 1000; - -} - -/* -================ -CheckSuitUpdate - -Play suit update if it's time -================ -*/ - -#define SUITUPDATETIME 3.5 -#define SUITFIRSTUPDATETIME 0.1 - -void CBasePlayer::CheckSuitUpdate() -{ - int i; - int isentence = 0; - int isearch = m_iSuitPlayNext; - - // Ignore suit updates if no suit - if ( !(pev->weapons & (1<IsMultiplayer() ) - { - // don't bother updating HEV voice in multiplayer. - return; - } - - if ( gpGlobals->time >= m_flSuitUpdate && m_flSuitUpdate > 0) - { - // play a sentence off of the end of the queue - for (i = 0; i < CSUITPLAYLIST; i++) - { - if (isentence = m_rgSuitPlayList[isearch]) - break; - - if (++isearch == CSUITPLAYLIST) - isearch = 0; - } - - if (isentence) - { - m_rgSuitPlayList[isearch] = 0; - if (isentence > 0) - { - // play sentence number - - char sentence[CBSENTENCENAME_MAX+1]; - strcpy(sentence, "!"); - strcat(sentence, gszallsentencenames[isentence]); - EMIT_SOUND_SUIT(ENT(pev), sentence); - } - else - { - // play sentence group - EMIT_GROUPID_SUIT(ENT(pev), -isentence); - } - m_flSuitUpdate = gpGlobals->time + SUITUPDATETIME; - } - else - // queue is empty, don't check - m_flSuitUpdate = 0; - } -} - -// add sentence to suit playlist queue. if fgroup is true, then -// name is a sentence group (HEV_AA), otherwise name is a specific -// sentence name ie: !HEV_AA0. If iNoRepeat is specified in -// seconds, then we won't repeat playback of this word or sentence -// for at least that number of seconds. - -void CBasePlayer::SetSuitUpdate(char *name, int fgroup, int iNoRepeatTime) -{ - int i; - int isentence; - int iempty = -1; - - - // Ignore suit updates if no suit - if ( !(pev->weapons & (1<IsMultiplayer() ) - { - // due to static channel design, etc. We don't play HEV sounds in multiplayer right now. - return; - } - - // if name == NULL, then clear out the queue - - if (!name) - { - for (i = 0; i < CSUITPLAYLIST; i++) - m_rgSuitPlayList[i] = 0; - return; - } - // get sentence or group number - if (!fgroup) - { - isentence = SENTENCEG_Lookup(name, NULL); - if (isentence < 0) - return; - } - else - // mark group number as negative - isentence = -SENTENCEG_GetIndex(name); - - // check norepeat list - this list lets us cancel - // the playback of words or sentences that have already - // been played within a certain time. - - for (i = 0; i < CSUITNOREPEAT; i++) - { - if (isentence == m_rgiSuitNoRepeat[i]) - { - // this sentence or group is already in - // the norepeat list - - if (m_rgflSuitNoRepeatTime[i] < gpGlobals->time) - { - // norepeat time has expired, clear it out - m_rgiSuitNoRepeat[i] = 0; - m_rgflSuitNoRepeatTime[i] = 0.0; - iempty = i; - break; - } - else - { - // don't play, still marked as norepeat - return; - } - } - // keep track of empty slot - if (!m_rgiSuitNoRepeat[i]) - iempty = i; - } - - // sentence is not in norepeat list, save if norepeat time was given - - if (iNoRepeatTime) - { - if (iempty < 0) - iempty = RANDOM_LONG(0, CSUITNOREPEAT-1); // pick random slot to take over - m_rgiSuitNoRepeat[iempty] = isentence; - m_rgflSuitNoRepeatTime[iempty] = iNoRepeatTime + gpGlobals->time; - } - - // find empty spot in queue, or overwrite last spot - - m_rgSuitPlayList[m_iSuitPlayNext++] = isentence; - if (m_iSuitPlayNext == CSUITPLAYLIST) - m_iSuitPlayNext = 0; - - if (m_flSuitUpdate <= gpGlobals->time) - { - if (m_flSuitUpdate == 0) - // play queue is empty, don't delay too long before playback - m_flSuitUpdate = gpGlobals->time + SUITFIRSTUPDATETIME; - else - m_flSuitUpdate = gpGlobals->time + SUITUPDATETIME; - } - -} - -/* -================ -CheckPowerups - -Check for turning off powerups - -GLOBALS ASSUMED SET: g_ulModelIndexPlayer -================ -*/ - static void -CheckPowerups(entvars_t *pev) -{ - if (pev->health <= 0) - return; - - pev->modelindex = g_ulModelIndexPlayer; // don't use eyes -} - -void CBasePlayer::PostThink() -{ - if ( g_fGameOver ) - goto pt_end; // intermission or finale - - if (!IsAlive()) - goto pt_end; - - // Handle Tank controlling - if ( m_pTank != NULL ) - { // if they've moved too far from the gun, or selected a weapon, unuse the gun - if ( m_pTank->OnControls( pev ) && !pev->weaponmodel ) - { - m_pTank->Use( this, this, USE_SET, 2 ); // try fire the gun - } - else - { // they've moved off the platform - m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - } - } - -// do weapon stuff - ItemPostFrame( ); - -// check to see if player landed hard enough to make a sound -// falling farther than half of the maximum safe distance, but not as far a max safe distance will -// play a bootscrape sound, and no damage will be inflicted. Fallling a distance shorter than half -// of maximum safe distance will make no sound. Falling farther than max safe distance will play a -// fallpain sound, and damage will be inflicted based on how far the player fell - - if ( (FBitSet(pev->flags, FL_ONGROUND)) && (pev->health > 0) && m_flFallVelocity >= PLAYER_FALL_PUNCH_THRESHHOLD ) - { - float fvol = 0.5; - - // ALERT ( at_console, "%f\n", m_flFallVelocity ); - - if (pev->watertype == CONTENT_WATER) - { - // Did he hit the world or a non-moving entity? - // BUG - this happens all the time in water, especially when - // BUG - water has current force - // if ( !pev->groundentity || VARS(pev->groundentity)->velocity.z == 0 ) - // EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM); - } - else if ( m_flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED ) - {// after this point, we start doing damage - float flFallDamage = g_pGameRules->FlPlayerFallDamage( this ); - - if ( flFallDamage > pev->health ) - {//splat - // note: play on item channel because we play footstep landing on body channel - EMIT_SOUND(ENT(pev), CHAN_ITEM, "common/bodysplat.wav", 1, ATTN_NORM); - } - - if ( flFallDamage > 0 ) - { - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), flFallDamage, DMG_FALL ); - pev->punchangle.x = 0; - } - - fvol = 1.0; - } - else if ( m_flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED / 2 ) - { - // EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_jumpland2.wav", 1, ATTN_NORM); - fvol = 0.85; - } - else if ( m_flFallVelocity < PLAYER_MIN_BOUNCE_SPEED ) - { - fvol = 0; - } - - if ( fvol > 0.0 ) - { - // get current texture under player right away - m_flTimeStepSound = 0; - UpdateStepSound(); - } - - if ( IsAlive() ) - { - SetAnimation( PLAYER_WALK ); - } - } - - if (FBitSet(pev->flags, FL_ONGROUND)) - { - //if (m_flFallVelocity > 64 && !g_pGameRules->IsMultiplayer()) - // TODO Make noise - m_flFallVelocity = 0; - } - - // select the proper animation for the player character - if ( IsAlive() ) - { - if (!pev->velocity.x && !pev->velocity.y) - SetAnimation( PLAYER_IDLE ); - else if ((pev->velocity.x || pev->velocity.y) && (FBitSet(pev->flags, FL_ONGROUND))) - SetAnimation( PLAYER_WALK ); - else if (pev->waterlevel > 1) - SetAnimation( PLAYER_WALK ); - } - - StudioFrameAdvance( ); - CheckPowerups(pev); - -pt_end: - // Decay timers on weapons - // go through all of the weapons and make a list of the ones to pack - for ( int i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - if ( m_rgpPlayerItems[ i ] ) - { - CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[ i ]; - - while ( pPlayerItem ) - { - CBasePlayerWeapon *gun; - - gun = (CBasePlayerWeapon *)pPlayerItem->GetWeaponPtr(); - - if ( gun && gun->UseDecrement() ) - { - gun->m_flNextPrimaryAttack = V_max( gun->m_flNextPrimaryAttack - gpGlobals->frametime, -1.0 ); - gun->m_flNextSecondaryAttack = V_max( gun->m_flNextSecondaryAttack - gpGlobals->frametime, -0.001 ); - - if ( gun->m_flTimeWeaponIdle != 1000 ) - { - gun->m_flTimeWeaponIdle = V_max( gun->m_flTimeWeaponIdle - gpGlobals->frametime, -0.001 ); - } - } - - pPlayerItem = pPlayerItem->m_pNext; - } - } - } - - m_flNextAttack -= gpGlobals->frametime; - if ( m_flNextAttack < -0.001 ) - m_flNextAttack = -0.001; - - // Track button info so we can detect 'pressed' and 'released' buttons next frame - m_afButtonLast = pev->button; -} - -BOOL IsSpawnPointValid( CBaseEntity *pPlayer, CBaseEntity *pSpot ) -{ - CBaseEntity *ent = NULL; - - if ( !pSpot->IsTriggered( pPlayer ) ) - { - return FALSE; - } - - while ( (ent = UTIL_FindEntityInSphere( ent, pSpot->pev->origin, 96 )) != NULL ) - { - // if ent is a client, don't spawn on 'em - if ( ent->pev->flags & FL_CLIENT ) - return FALSE; - } - - return TRUE; -} - -DLL_GLOBAL CBaseEntity *g_pLastSpawn; -inline int FNullEnt( CBaseEntity *ent ) { return (ent == NULL) || FNullEnt( ent->edict() ); } - -/* -============ -EntSelectSpawnPoint - -Returns the entity to spawn at - -USES AND SETS GLOBAL g_pLastSpawn -============ -*/ -edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ) -{ - CBaseEntity *pSpot; - edict_t *player; - - player = pPlayer->edict(); - -// choose a info_player_deathmatch point - if (g_pGameRules->IsCoOp()) - { - pSpot = UTIL_FindEntityByClassname( g_pLastSpawn, "info_player_coop"); - if ( !FNullEnt(pSpot) ) - goto ReturnSpot; - pSpot = UTIL_FindEntityByClassname( g_pLastSpawn, "info_player_start"); - if ( !FNullEnt(pSpot) ) - goto ReturnSpot; - } - else if ( g_pGameRules->IsDeathmatch() ) - { - pSpot = g_pLastSpawn; - // Randomize the start spot - for ( int i = RANDOM_LONG(1,5); i > 0; i-- ) - pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" ); - if ( FNullEnt( pSpot ) ) // skip over the null point - pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" ); - - CBaseEntity *pFirstSpot = pSpot; - - do - { - if ( pSpot ) - { - // check if pSpot is valid - if ( IsSpawnPointValid( pPlayer, pSpot ) ) - { - if ( pSpot->pev->origin == Vector( 0, 0, 0 ) ) - { - 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 ( !FNullEnt( pSpot ) ) - { - CBaseEntity *ent = NULL; - while ( (ent = UTIL_FindEntityInSphere( ent, pSpot->pev->origin, 128 )) != NULL ) - { - // if ent is a client, kill em (unless they are ourselves) - if ( ent->IsPlayer() && !(ent->edict() == player) ) - ent->TakeDamage( VARS(INDEXENT(0)), VARS(INDEXENT(0)), 300, DMG_GENERIC ); - } - goto ReturnSpot; - } - } - - // If startspot is set, (re)spawn there. - if ( FStringNull( gpGlobals->startspot ) || !strlen(STRING(gpGlobals->startspot))) - { - pSpot = UTIL_FindEntityByClassname(NULL, "info_player_start"); - if ( !FNullEnt(pSpot) ) - goto ReturnSpot; - } - else - { - pSpot = UTIL_FindEntityByTargetname( NULL, STRING(gpGlobals->startspot) ); - if ( !FNullEnt(pSpot) ) - goto ReturnSpot; - } - -ReturnSpot: - if ( FNullEnt( pSpot ) ) - { - ALERT(at_error, "PutClientInServer: no info_player_start on level"); - return INDEXENT(0); - } - - g_pLastSpawn = pSpot; - return pSpot->edict(); -} - -void CBasePlayer::Spawn( void ) -{ - pev->classname = MAKE_STRING("player"); - pev->health = 100; - pev->armorvalue = 0; - pev->takedamage = DAMAGE_AIM; - pev->solid = SOLID_SLIDEBOX; - pev->movetype = MOVETYPE_WALK; - pev->max_health = pev->health; - pev->flags &= FL_PROXY; // keep proxy flag sey by engine - pev->flags |= FL_CLIENT; - pev->air_finished = gpGlobals->time + 12; - pev->dmg = 2; // initial water damage - pev->effects = 0; - pev->deadflag = DEAD_NO; - pev->dmg_take = 0; - pev->dmg_save = 0; - pev->friction = 1.0; - pev->gravity = 1.0; - m_bitsHUDDamage = -1; - m_bitsDamageType = 0; - m_afPhysicsFlags = 0; - m_fLongJump = FALSE;// no longjump module. - - g_engfuncs.pfnSetPhysicsKeyValue( edict(), "slj", "0" ); - g_engfuncs.pfnSetPhysicsKeyValue( edict(), "hl", "1" ); - - - m_flNextDecalTime = 0;// let this player decal as soon as he spawns. - - m_flgeigerDelay = gpGlobals->time + 2.0; // wait a few seconds until user-defined message registrations - // are recieved by all clients - - m_flTimeStepSound = 0; - m_iStepLeft = 0; - m_flFieldOfView = 0.5;// some monsters use this to determine whether or not the player is looking at them. - - m_bloodColor = BLOOD_COLOR_RED; - m_flNextAttack = UTIL_WeaponTimeBase(); - StartSneaking(); - - m_iFlashBattery = 99; - m_flFlashLightTime = 1; // force first message - -// dont let uninitialized value here hurt the player - m_flFallVelocity = 0; - - //g_pGameRules->SetDefaultPlayerTeam( this ); - g_pGameRules->GetPlayerSpawnSpot( this ); - - SET_MODEL(ENT(pev), "models/player.mdl"); - g_ulModelIndexPlayer = pev->modelindex; - pev->sequence = LookupActivity( ACT_IDLE ); - - UTIL_SetSize(pev, VEC_HULL_MIN, VEC_HULL_MAX); - - pev->view_ofs = VEC_VIEW; - Precache(); - m_HackedGunPos = Vector( 0, 32, 0 ); - - m_fNoPlayerSound = FALSE;// normal sound behavior. - - m_pLastItem = NULL; - m_fInitHUD = TRUE; - m_iClientHideHUD = -1; // force this to be recalculated - m_fWeapon = FALSE; - m_pClientActiveItem = NULL; - m_iClientBattery = -1; - - m_flLightningTime = 0.0; - - InitStatusBar(); - m_iQuakeItems = 0; - - // reset all ammo values to 0 - for ( int i = 0; i < MAX_AMMO_SLOTS; i++ ) - { - m_rgAmmo[i] = 0; - m_rgAmmoLast[i] = 0; // client ammo values also have to be reset (the death hud clear messages does on the client side) - } - - m_lastx = m_lasty = 0; - - if ( !m_bHadFirstSpawn && g_bHaveMOTD ) - { - pev->effects |= EF_NODRAW; - pev->solid = SOLID_NOT; - pev->takedamage = DAMAGE_NO; - pev->movetype = MOVETYPE_NONE; - - g_engfuncs.pfnSetClientMaxspeed( ENT( pev ), 1 ); - m_iHideHUD |= HIDEHUD_WEAPONS | HIDEHUD_FLASHLIGHT | HIDEHUD_HEALTH; - } - else - { - g_engfuncs.pfnSetClientMaxspeed( ENT( pev ), PLAYER_MAX_SPEED ); - m_iHideHUD &= ~( HIDEHUD_WEAPONS | HIDEHUD_HEALTH ); - - pev->effects &= ~EF_NODRAW; - - g_pGameRules->PlayerSpawn( this ); - - PLAYBACK_EVENT_FULL ( FEV_GLOBAL, edict(), g_sTeleport, 0.0, (float *)&pev->origin, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0); - - m_fKnownItem = false; - } - - -} - - -void CBasePlayer :: Precache( void ) -{ - // in the event that the player JUST spawned, and the level node graph - // was loaded, fix all of the node graph pointers before the game starts. - - // !!!BUGBUG - now that we have multiplayer, this needs to be moved! - if ( WorldGraph.m_fGraphPresent && !WorldGraph.m_fGraphPointersSet ) - { - if ( !WorldGraph.FSetGraphPointers() ) - { - ALERT ( at_console, "**Graph pointers were not set!\n"); - } - else - { - ALERT ( at_console, "**Graph Pointers Set!\n" ); - } - } - - // SOUNDS / MODELS ARE PRECACHED in ClientPrecache() (game specific) - // because they need to precache before any clients have connected - m_usShotgunSingle = PRECACHE_EVENT( 1, "events/shotgun1.sc" ); - m_usShotgunDouble = PRECACHE_EVENT( 1, "events/shotgun2.sc" ); - m_usAxe = PRECACHE_EVENT( 1, "events/axe.sc" ); - m_usAxeSwing = PRECACHE_EVENT( 1, "events/axeswing.sc" ); - m_usRocket = PRECACHE_EVENT( 1, "events/rocket.sc" ); - m_usGrenade = PRECACHE_EVENT( 1, "events/grenade.sc" ); - m_usLightning = PRECACHE_EVENT( 1, "events/lightning.sc" ); - m_usSpike = PRECACHE_EVENT( 1, "events/spike.sc" ); - m_usSuperSpike = PRECACHE_EVENT( 1, "events/superspike.sc" ); - - - // init geiger counter vars during spawn and each time - // we cross a level transition - - m_flgeigerRange = 1000; - m_igeigerRangePrev = 1000; - - m_bitsDamageType = 0; - m_bitsHUDDamage = -1; - - m_iClientBattery = -1; - - m_iTrain = TRAIN_NEW; - - // Make sure any necessary user messages have been registered - LinkUserMessages(); - - m_iUpdateTime = 5; // won't update for 1/2 a second - - if ( gInitHUD ) - m_fInitHUD = TRUE; -} - - -int CBasePlayer::Save( CSave &save ) -{ - if ( !CBaseMonster::Save(save) ) - return 0; - - return save.WriteFields( "PLAYER", this, m_playerSaveData, ARRAYSIZE(m_playerSaveData) ); -} - - -// -// Marks everything as new so the player will resend this to the hud. -// -void CBasePlayer::RenewItems(void) -{ - -} - - -int CBasePlayer::Restore( CRestore &restore ) -{ - if ( !CBaseMonster::Restore(restore) ) - return 0; - - int status = restore.ReadFields( "PLAYER", this, m_playerSaveData, ARRAYSIZE(m_playerSaveData) ); - - SAVERESTOREDATA *pSaveData = (SAVERESTOREDATA *)gpGlobals->pSaveData; - // landmark isn't present. - if ( !pSaveData->fUseLandmark ) - { - ALERT( at_console, "No Landmark:%s\n", pSaveData->szLandmarkName ); - - // default to normal spawn - edict_t* pentSpawnSpot = EntSelectSpawnPoint( this ); - pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1); - pev->angles = VARS(pentSpawnSpot)->angles; - } - pev->v_angle.z = 0; // Clear out roll - pev->angles = pev->v_angle; - - pev->fixangle = TRUE; // turn this way immediately - -// Copied from spawn() for now - m_bloodColor = BLOOD_COLOR_RED; - - g_ulModelIndexPlayer = pev->modelindex; - -/* if ( FBitSet(pev->flags, FL_DUCKING) ) - { - // Use the crouch HACK - // FixPlayerCrouchStuck( edict() ); - UTIL_SetSize(pev, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX); - } - else - { - UTIL_SetSize(pev, VEC_HULL_MIN, VEC_HULL_MAX); - }*/ - - RenewItems(); - - return status; -} - - - -void CBasePlayer::SelectNextItem( int iItem ) -{ - CBasePlayerItem *pItem; - - pItem = m_rgpPlayerItems[ iItem ]; - - if (!pItem) - return; - - if (pItem == m_pActiveItem) - { - // select the next one in the chain - pItem = m_pActiveItem->m_pNext; - if (! pItem) - { - return; - } - - CBasePlayerItem *pLast; - pLast = pItem; - while (pLast->m_pNext) - pLast = pLast->m_pNext; - - // relink chain - pLast->m_pNext = m_pActiveItem; - m_pActiveItem->m_pNext = NULL; - m_rgpPlayerItems[ iItem ] = pItem; - } - - ResetAutoaim( ); - - // FIX, this needs to queue them up and delay - if (m_pActiveItem) - { - m_pActiveItem->Holster( ); - } - - m_pActiveItem = pItem; - - if (m_pActiveItem) - { - m_pActiveItem->Deploy( ); - m_pActiveItem->UpdateItemInfo( ); - } -} - -void CBasePlayer::SelectItem(const char *pstr) -{ - if (!pstr) - return; - - CBasePlayerItem *pItem = NULL; - - for (int i = 0; i < MAX_ITEM_TYPES; i++) - { - if (m_rgpPlayerItems[i]) - { - pItem = m_rgpPlayerItems[i]; - - while (pItem) - { - if (FClassnameIs(pItem->pev, pstr)) - break; - pItem = pItem->m_pNext; - } - } - - if (pItem) - break; - } - - if (!pItem) - return; - - - if (pItem == m_pActiveItem) - return; - - ResetAutoaim( ); - - // FIX, this needs to queue them up and delay - if (m_pActiveItem) - m_pActiveItem->Holster( ); - - m_pLastItem = m_pActiveItem; - m_pActiveItem = pItem; - - if (m_pActiveItem) - { - m_pActiveItem->Deploy( ); - m_pActiveItem->UpdateItemInfo( ); - } -} - - -void CBasePlayer::SelectLastItem(void) -{ - if (!m_pLastItem) - { - return; - } - - if ( m_pActiveItem && !m_pActiveItem->CanHolster() ) - { - return; - } - - ResetAutoaim( ); - - // FIX, this needs to queue them up and delay - if (m_pActiveItem) - m_pActiveItem->Holster( ); - - CBasePlayerItem *pTemp = m_pActiveItem; - m_pActiveItem = m_pLastItem; - m_pLastItem = pTemp; - m_pActiveItem->Deploy( ); - m_pActiveItem->UpdateItemInfo( ); -} - -//============================================== -// HasWeapons - do I have any weapons at all? -//============================================== -BOOL CBasePlayer::HasWeapons( void ) -{ - int i; - - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - if ( m_rgpPlayerItems[ i ] ) - { - return TRUE; - } - } - - return FALSE; -} - -void CBasePlayer::SelectPrevItem( int iItem ) -{ -} - - -const char *CBasePlayer::TeamID( void ) -{ - if ( pev == NULL ) // Not fully connected yet - return ""; - - // return their team name - return m_szTeamName; -} - - -//============================================== -// !!!UNDONE:ultra temporary SprayCan entity to apply -// decal frame at a time. For PreAlpha CD -//============================================== -class CSprayCan : public CBaseEntity -{ -public: - void Spawn ( entvars_t *pevOwner ); - void Think( void ); - - virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; } -}; - -void CSprayCan::Spawn ( entvars_t *pevOwner ) -{ - pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->v_angle; - pev->owner = ENT(pevOwner); - pev->frame = 0; - - pev->nextthink = gpGlobals->time + 0.1; - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/sprayer.wav", 1, ATTN_NORM); -} - -void CSprayCan::Think( void ) -{ - TraceResult tr; - int playernum; - int nFrames; - CBasePlayer *pPlayer; - - pPlayer = (CBasePlayer *)GET_PRIVATE(pev->owner); - - if (pPlayer) - nFrames = pPlayer->GetCustomDecalFrames(); - else - nFrames = -1; - - playernum = ENTINDEX(pev->owner); - - // ALERT(at_console, "Spray by player %i, %i of %i\n", playernum, (int)(pev->frame + 1), nFrames); - - UTIL_MakeVectors(pev->angles); - UTIL_TraceLine ( pev->origin, pev->origin + gpGlobals->v_forward * 128, ignore_monsters, pev->owner, & tr); - - // No customization present. - if (nFrames == -1) - { - UTIL_DecalTrace( &tr, DECAL_LAMBDA6 ); - UTIL_Remove( this ); - } - else - { - UTIL_PlayerDecalTrace( &tr, playernum, pev->frame, TRUE ); - // Just painted last custom frame. - if ( pev->frame++ >= (nFrames - 1)) - UTIL_Remove( this ); - } - - pev->nextthink = gpGlobals->time + 0.1; -} - -class CBloodSplat : public CBaseEntity -{ -public: - void Spawn ( entvars_t *pevOwner ); - void Spray ( void ); -}; - -void CBloodSplat::Spawn ( entvars_t *pevOwner ) -{ - pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->v_angle; - pev->owner = ENT(pevOwner); - - SetThink ( &CBloodSplat::Spray ); - pev->nextthink = gpGlobals->time + 0.1; -} - -void CBloodSplat::Spray ( void ) -{ - TraceResult tr; - - if ( g_Language != LANGUAGE_GERMAN ) - { - UTIL_MakeVectors(pev->angles); - UTIL_TraceLine ( pev->origin, pev->origin + gpGlobals->v_forward * 128, ignore_monsters, pev->owner, & tr); - - UTIL_BloodDecalTrace( &tr, BLOOD_COLOR_RED ); - } - SetThink ( &CBloodSplat::SUB_Remove ); - pev->nextthink = gpGlobals->time + 0.1; -} - -//============================================== - - - -void CBasePlayer::GiveNamedItem( const char *pszName ) -{ - edict_t *pent; - - int istr = MAKE_STRING(pszName); - - pent = CREATE_NAMED_ENTITY(istr); - if ( FNullEnt( pent ) ) - { - ALERT ( at_console, "NULL Ent in GiveNamedItem!\n" ); - return; - } - VARS( pent )->origin = pev->origin; - pent->v.spawnflags |= SF_NORESPAWN; - - DispatchSpawn( pent ); - DispatchTouch( pent, ENT( pev ) ); -} - - - -CBaseEntity *FindEntityForward( CBaseEntity *pMe ) -{ - TraceResult tr; - - UTIL_MakeVectors(pMe->pev->v_angle); - UTIL_TraceLine(pMe->pev->origin + pMe->pev->view_ofs,pMe->pev->origin + pMe->pev->view_ofs + gpGlobals->v_forward * 8192,dont_ignore_monsters, pMe->edict(), &tr ); - if ( tr.flFraction != 1.0 && !FNullEnt( tr.pHit) ) - { - CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit ); - return pHit; - } - return NULL; -} - - -BOOL CBasePlayer :: FlashlightIsOn( void ) -{ - return FBitSet(pev->effects, EF_DIMLIGHT); -} - - -void CBasePlayer :: FlashlightTurnOn( void ) -{ - if ( !g_pGameRules->FAllowFlashlight() ) - { - return; - } - - if ( (pev->weapons & (1<effects, EF_DIMLIGHT); - MESSAGE_BEGIN( MSG_ONE, gmsgFlashlight, NULL, pev ); - WRITE_BYTE(1); - WRITE_BYTE(m_iFlashBattery); - MESSAGE_END(); - - m_flFlashLightTime = FLASH_DRAIN_TIME + gpGlobals->time; - - } -} - - -void CBasePlayer :: FlashlightTurnOff( void ) -{ - EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, SOUND_FLASHLIGHT_OFF, 1.0, ATTN_NORM, 0, PITCH_NORM ); - ClearBits(pev->effects, EF_DIMLIGHT); - MESSAGE_BEGIN( MSG_ONE, gmsgFlashlight, NULL, pev ); - WRITE_BYTE(0); - WRITE_BYTE(m_iFlashBattery); - MESSAGE_END(); - - m_flFlashLightTime = FLASH_CHARGE_TIME + gpGlobals->time; - -} - -/* -=============== -ForceClientDllUpdate - -When recording a demo, we need to have the server tell us the entire client state -so that the client side .dll can behave correctly. -Reset stuff so that the state is transmitted. -=============== -*/ -void CBasePlayer :: ForceClientDllUpdate( void ) -{ - m_iClientHealth = -1; - m_iClientBattery = -1; - m_iClientQuakeItems = -1; - m_iClientQuakeWeapon = -1; - m_iTrain |= TRAIN_NEW; // Force new train message. - m_fWeapon = FALSE; // Force weapon send - m_fKnownItem = FALSE; // Force weaponinit messages. - m_fInitHUD = TRUE; // Force HUD gmsgResetHUD message - - // Now force all the necessary messages - // to be sent. - UpdateClientData(); -} - -/* -============ -ImpulseCommands -============ -*/ -extern float g_flWeaponCheat; - -void CBasePlayer::ImpulseCommands( ) -{ - TraceResult tr;// UNDONE: kill me! This is temporary for PreAlpha CDs - - // Handle use events - PlayerUse(); - - int iImpulse = (int)pev->impulse; - - // QUAKECLASSIC - // Handle weapon switches first -/* if (iImpulse >= 1 && iImpulse <= 8) - { - W_ChangeWeapon( iImpulse ); - } - else - {*/ - switch (iImpulse) - { - - // QUAKECLASSIC - case 10: - W_CycleWeaponCommand(); - break; - case 12: - W_CycleWeaponReverseCommand(); - break; - - case 99: - { - - int iOn; - - if (!gmsgLogo) - { - iOn = 1; - gmsgLogo = REG_USER_MSG("Logo", 1); - } - else - { - iOn = 0; - } - - ASSERT( gmsgLogo > 0 ); - // send "health" update message - MESSAGE_BEGIN( MSG_ONE, gmsgLogo, NULL, pev ); - WRITE_BYTE(iOn); - MESSAGE_END(); - - if(!iOn) - gmsgLogo = 0; - break; - } - /* case 100: - // temporary flashlight for level designers - if ( FlashlightIsOn() ) - { - FlashlightTurnOff(); - } - else - { - FlashlightTurnOn(); - } - break;*/ - - case 201:// paint decal - - if ( gpGlobals->time < m_flNextDecalTime ) - { - // too early! - break; - } - - UTIL_MakeVectors(pev->v_angle); - UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr); - - if ( tr.flFraction != 1.0 ) - {// line hit something, so paint a decal - m_flNextDecalTime = gpGlobals->time + CVAR_GET_FLOAT("decalfrequency"); - CSprayCan *pCan = GetClassPtr((CSprayCan *)NULL); - pCan->Spawn( pev ); - } - - break; - - default: - // check all of the cheat impulse commands now - CheatImpulseCommands( iImpulse ); - break; - } - //} - - pev->impulse = 0; -} - -//========================================================= -//========================================================= -void CBasePlayer::CheatImpulseCommands( int iImpulse ) -{ -#if !defined( HLDEMO_BUILD ) - if ( g_flWeaponCheat == 0.0 ) - { - return; - } - - CBaseEntity *pEntity; - TraceResult tr; - - switch ( iImpulse ) - { - case 76: - { - if (!giPrecacheGrunt) - { - giPrecacheGrunt = 1; - ALERT(at_console, "You must now restart to use Grunt-o-matic.\n"); - } - else - { - UTIL_MakeVectors( Vector( 0, pev->v_angle.y, 0 ) ); - Create("monster_human_grunt", pev->origin + gpGlobals->v_forward * 128, pev->angles); - } - break; - } - - - case 101: - gEvilImpulse101 = TRUE; - m_iAmmoNails = 200; - m_iAmmoShells = 100; - m_iAmmoRockets = 100; - m_iAmmoCells = 100; - m_iQuakeItems |= IT_NAILGUN | IT_SUPER_NAILGUN | IT_SUPER_SHOTGUN | IT_ROCKET_LAUNCHER | IT_GRENADE_LAUNCHER | IT_LIGHTNING; - CheckAmmo(); - W_SetCurrentAmmo(); - gEvilImpulse101 = FALSE; - break; - - case 102: - // Gibbage!!! - CGib::SpawnRandomGibs( pev, 1, 1 ); - break; - - case 103: - // What the hell are you doing? - pEntity = FindEntityForward( this ); - if ( pEntity ) - { - CBaseMonster *pMonster = pEntity->MyMonsterPointer(); - if ( pMonster ) - pMonster->ReportAIState(); - } - break; - - case 104: - // Dump all of the global state varaibles (and global entity names) - gGlobalState.DumpGlobals(); - break; - - case 105:// player makes no sound for monsters to hear. - { - if ( m_fNoPlayerSound ) - { - ALERT ( at_console, "Player is audible\n" ); - m_fNoPlayerSound = FALSE; - } - else - { - ALERT ( at_console, "Player is silent\n" ); - m_fNoPlayerSound = TRUE; - } - break; - } - - case 106: - // Give me the classname and targetname of this entity. - pEntity = FindEntityForward( this ); - if ( pEntity ) - { - ALERT ( at_console, "Classname: %s", STRING( pEntity->pev->classname ) ); - - if ( !FStringNull ( pEntity->pev->targetname ) ) - { - ALERT ( at_console, " - Targetname: %s\n", STRING( pEntity->pev->targetname ) ); - } - else - { - ALERT ( at_console, " - TargetName: No Targetname\n" ); - } - - ALERT ( at_console, "Model: %s\n", STRING( pEntity->pev->model ) ); - if ( pEntity->pev->globalname ) - ALERT ( at_console, "Globalname: %s\n", STRING( pEntity->pev->globalname ) ); - } - break; - - case 107: - { - TraceResult tr; - - edict_t *pWorld = g_engfuncs.pfnPEntityOfEntIndex( 0 ); - - Vector start = pev->origin + pev->view_ofs; - Vector end = start + gpGlobals->v_forward * 1024; - UTIL_TraceLine( start, end, ignore_monsters, edict(), &tr ); - if ( tr.pHit ) - pWorld = tr.pHit; - const char *pTextureName = TRACE_TEXTURE( pWorld, start, end ); - if ( pTextureName ) - ALERT( at_console, "Texture: %s\n", pTextureName ); - } - break; - case 195:// show shortest paths for entire level to nearest node - { - Create("node_viewer_fly", pev->origin, pev->angles); - } - break; - case 196:// show shortest paths for entire level to nearest node - { - Create("node_viewer_large", pev->origin, pev->angles); - } - break; - case 197:// show shortest paths for entire level to nearest node - { - Create("node_viewer_human", pev->origin, pev->angles); - } - break; - case 199:// show nearest node and all connections - { - ALERT ( at_console, "%d\n", WorldGraph.FindNearestNode ( pev->origin, bits_NODE_GROUP_REALM ) ); - WorldGraph.ShowNodeConnections ( WorldGraph.FindNearestNode ( pev->origin, bits_NODE_GROUP_REALM ) ); - } - break; - case 202:// Random blood splatter - UTIL_MakeVectors(pev->v_angle); - UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr); - - if ( tr.flFraction != 1.0 ) - {// line hit something, so paint a decal - CBloodSplat *pBlood = GetClassPtr((CBloodSplat *)NULL); - pBlood->Spawn( pev ); - } - break; - case 203:// remove creature. - pEntity = FindEntityForward( this ); - if ( pEntity ) - { - if ( pEntity->pev->takedamage ) - pEntity->SetThink(&CBaseEntity::SUB_Remove); - } - break; - } -#endif // HLDEMO_BUILD -} - -// -// Add a weapon to the player (Item == Weapon == Selectable Object) -// -int CBasePlayer::AddPlayerItem( CBasePlayerItem *pItem ) -{ - CBasePlayerItem *pInsert; - - pInsert = m_rgpPlayerItems[pItem->iItemSlot()]; - - while (pInsert) - { - if (FClassnameIs( pInsert->pev, STRING( pItem->pev->classname) )) - { - if (pItem->AddDuplicate( pInsert )) - { - g_pGameRules->PlayerGotWeapon ( this, pItem ); - pItem->CheckRespawn(); - - // ugly hack to update clip w/o an update clip message - pInsert->UpdateItemInfo( ); - if (m_pActiveItem) - m_pActiveItem->UpdateItemInfo( ); - - pItem->Kill( ); - } - else if (gEvilImpulse101) - { - // FIXME: remove anyway for deathmatch testing - pItem->Kill( ); - } - return FALSE; - } - pInsert = pInsert->m_pNext; - } - - - if (pItem->AddToPlayer( this )) - { - g_pGameRules->PlayerGotWeapon ( this, pItem ); - pItem->CheckRespawn(); - - pItem->m_pNext = m_rgpPlayerItems[pItem->iItemSlot()]; - m_rgpPlayerItems[pItem->iItemSlot()] = pItem; - - // should we switch to this item? - if ( g_pGameRules->FShouldSwitchWeapon( this, pItem ) ) - { - SwitchWeapon( pItem ); - } - - return TRUE; - } - else if (gEvilImpulse101) - { - // FIXME: remove anyway for deathmatch testing - pItem->Kill( ); - } - return FALSE; -} - - - -int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem ) -{ - if (m_pActiveItem == pItem) - { - ResetAutoaim( ); - pItem->Holster( ); - pItem->pev->nextthink = 0;// crowbar may be trying to swing again, etc. - pItem->SetThink( NULL ); - m_pActiveItem = NULL; - pev->viewmodel = 0; - pev->weaponmodel = 0; - } - else if ( m_pLastItem == pItem ) - m_pLastItem = NULL; - - CBasePlayerItem *pPrev = m_rgpPlayerItems[pItem->iItemSlot()]; - - if (pPrev == pItem) - { - m_rgpPlayerItems[pItem->iItemSlot()] = pItem->m_pNext; - return TRUE; - } - else - { - while (pPrev && pPrev->m_pNext != pItem) - { - pPrev = pPrev->m_pNext; - } - if (pPrev) - { - pPrev->m_pNext = pItem->m_pNext; - return TRUE; - } - } - return FALSE; -} - - -// -// Returns the unique ID for the ammo, or -1 if error -// -int CBasePlayer :: GiveAmmo( int iCount, char *szName, int iMax ) -{ - if ( !szName ) - { - // no ammo. - return -1; - } - - if ( !g_pGameRules->CanHaveAmmo( this, szName, iMax ) ) - { - // game rules say I can't have any more of this ammo type. - return -1; - } - - int i = 0; - - i = GetAmmoIndex( szName ); - - if ( i < 0 || i >= MAX_AMMO_SLOTS ) - return -1; - - int iAdd = V_min( iCount, iMax - m_rgAmmo[i] ); - if ( iAdd < 1 ) - return i; - - m_rgAmmo[ i ] += iAdd; - - - if ( gmsgAmmoPickup ) // make sure the ammo messages have been linked first - { - // Send the message that ammo has been picked up - MESSAGE_BEGIN( MSG_ONE, gmsgAmmoPickup, NULL, pev ); - WRITE_BYTE( GetAmmoIndex(szName) ); // ammo ID - WRITE_BYTE( iAdd ); // amount - MESSAGE_END(); - } - - return i; -} - - -/* -============ -ItemPreFrame - -Called every frame by the player PreThink -============ -*/ -void CBasePlayer::ItemPreFrame() -{ - if ( m_flNextAttack > 0 ) - { - return; - } - - if (!m_pActiveItem) - return; - - m_pActiveItem->ItemPreFrame( ); -} - - -/* -============ -ItemPostFrame - -Called every frame by the player PostThink -============ -*/ -void CBasePlayer::ItemPostFrame() -{ - static int fInSelect = FALSE; - - // check if the player is using a tank - if ( m_pTank != NULL ) - return; - - // HACKHACK: To make the axe fire 0.3 sec after fire is pressed - // See if the axe should fire now - if (m_flAxeFire && m_flAxeFire <= gpGlobals->time) - { - m_flAxeFire = 0; - W_FireAxe(); - } - - if ( m_flNextAttack > 0 ) - { - return; - } - - ImpulseCommands(); - - if (!m_pActiveItem) - return; - - m_pActiveItem->ItemPostFrame( ); -} - -int CBasePlayer::AmmoInventory( int iAmmoIndex ) -{ - if (iAmmoIndex == -1) - { - return -1; - } - - return m_rgAmmo[ iAmmoIndex ]; -} - -int CBasePlayer::GetAmmoIndex(const char *psz) -{ - int i; - - if (!psz) - return -1; - - for (i = 1; i < MAX_AMMO_SLOTS; i++) - { - if ( !CBasePlayerItem::AmmoInfoArray[i].pszName ) - continue; - - if (stricmp( psz, CBasePlayerItem::AmmoInfoArray[i].pszName ) == 0) - return i; - } - - return -1; -} - -// Called from UpdateClientData -// makes sure the client has all the necessary ammo info, if values have changed -void CBasePlayer::SendAmmoUpdate(void) -{ - for (int i=0; i < MAX_AMMO_SLOTS;i++) - { - if (m_rgAmmo[i] != m_rgAmmoLast[i]) - { - m_rgAmmoLast[i] = m_rgAmmo[i]; - - ASSERT( m_rgAmmo[i] >= 0 ); - ASSERT( m_rgAmmo[i] < 255 ); - - // send "Ammo" update message - MESSAGE_BEGIN( MSG_ONE, gmsgAmmoX, NULL, pev ); - WRITE_BYTE( i ); - WRITE_BYTE( V_max( V_min( m_rgAmmo[i], 254 ), 0 ) ); // clamp the value to one byte - MESSAGE_END(); - } - } -} - -/* -========================================================= - UpdateClientData - -resends any changed player HUD info to the client. -Called every frame by PlayerPreThink -Also called at start of demo recording and playback by -ForceClientDllUpdate to ensure the demo gets messages -reflecting all of the HUD state info. -========================================================= -*/ -void CBasePlayer :: UpdateClientData( void ) -{ - if (m_fInitHUD) - { - m_fInitHUD = FALSE; - gInitHUD = FALSE; - - MESSAGE_BEGIN( MSG_ONE, gmsgResetHUD, NULL, pev ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - - if ( !m_fGameHUDInitialized ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgInitHUD, NULL, pev ); - WRITE_BYTE ( g_iTeleNum ); - for ( int i = 0; i < g_iTeleNum; i++ ) - { - WRITE_COORD( g_vecTeleMins[ i ].x ); - WRITE_COORD( g_vecTeleMins[ i ].y ); - WRITE_COORD( g_vecTeleMins[ i ].z ); - - WRITE_COORD( g_vecTeleMaxs[ i ].x ); - WRITE_COORD( g_vecTeleMaxs[ i ].y ); - WRITE_COORD( g_vecTeleMaxs[ i ].z ); - } - - CBaseEntity *pEntity = NULL; - pEntity = UTIL_FindEntityByClassname( pEntity, "env_fog" ); - - if ( pEntity ) - { - ALERT( at_console, "Map has fog!\n" ); - CClientFog *pFog = (CClientFog *)pEntity; - - //Send as bytes?. - WRITE_SHORT ( pFog->pev->rendercolor.x ); - WRITE_SHORT ( pFog->pev->rendercolor.y ); - WRITE_SHORT ( pFog->pev->rendercolor.z ); - WRITE_SHORT ( pFog->m_iStartDist ); - WRITE_SHORT ( pFog->m_iEndDist ); - } - else - ALERT( at_console, "Map doesn't have any fog!\n" ); - - - MESSAGE_END(); - - g_pGameRules->InitHUD( this ); - m_fGameHUDInitialized = TRUE; - if ( g_pGameRules->IsMultiplayer() ) - { - FireTargets( "game_playerjoin", this, this, USE_TOGGLE, 0 ); - } - } - FireTargets( "game_playerspawn", this, this, USE_TOGGLE, 0 ); - } - - if ( m_iHideHUD != m_iClientHideHUD ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgHideWeapon, NULL, pev ); - WRITE_BYTE( m_iHideHUD ); - MESSAGE_END(); - - m_iClientHideHUD = m_iHideHUD; - } - - if ( m_iFOV != m_iClientFOV ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev ); - WRITE_BYTE( m_iFOV ); - MESSAGE_END(); - - // cache FOV change at end of function, so weapon updates can see that FOV has changed - } - - // HACKHACK -- send the message to display the game title - if (gDisplayTitle) - { - MESSAGE_BEGIN( MSG_ONE, gmsgShowGameTitle, NULL, pev ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - gDisplayTitle = 0; - } - - if (pev->health != m_iClientHealth) - { -#define clamp( val, min, max ) ( ((val) > (max)) ? (max) : ( ((val) < (min)) ? (min) : (val) ) ) - int iHealth = clamp( pev->health, 0, 255 ); // make sure that no negative health values are sent - if ( pev->health > 0.0f && pev->health <= 1.0f ) - iHealth = 1; - - // send "health" update message - MESSAGE_BEGIN( MSG_ONE, gmsgHealth, NULL, pev ); - WRITE_BYTE( iHealth ); - MESSAGE_END(); - - m_iClientHealth = pev->health; - } - - // QUAKECLASSIC - // Send down the state of the QuakeItems - if ( m_iQuakeItems != m_iClientQuakeItems ) - { - // send "items" update message - MESSAGE_BEGIN( MSG_ONE, gmsgQItems, NULL, pev ); - WRITE_LONG( m_iQuakeItems ); - MESSAGE_END(); - - m_iClientQuakeItems = m_iQuakeItems; - } - - if (pev->armorvalue != m_iClientBattery) - { - m_iClientBattery = pev->armorvalue; - - ASSERT( gmsgBattery > 0 ); - // send "health" update message - MESSAGE_BEGIN( MSG_ONE, gmsgBattery, NULL, pev ); - WRITE_SHORT( (int)pev->armorvalue); - MESSAGE_END(); - } - - if (pev->dmg_take || pev->dmg_save || m_bitsHUDDamage != m_bitsDamageType) - { - // Comes from inside me if not set - Vector damageOrigin = pev->origin; - // send "damage" message - // causes screen to flash, and pain compass to show direction of damage - edict_t *other = pev->dmg_inflictor; - if ( other && UTIL_IsValidEntity(other) ) - { - CBaseEntity *pEntity = CBaseEntity::Instance(other); - if ( pEntity ) - damageOrigin = pEntity->Center(); - } - - // only send down damage type that have hud art - int visibleDamageBits = m_bitsDamageType & DMG_SHOWNHUD; - - MESSAGE_BEGIN( MSG_ONE, gmsgDamage, NULL, pev ); - WRITE_BYTE( pev->dmg_save ); - WRITE_BYTE( pev->dmg_take ); - WRITE_LONG( visibleDamageBits ); - WRITE_COORD( damageOrigin.x ); - WRITE_COORD( damageOrigin.y ); - WRITE_COORD( damageOrigin.z ); - MESSAGE_END(); - - pev->dmg_take = 0; - pev->dmg_save = 0; - m_bitsHUDDamage = m_bitsDamageType; - - // Clear off non-time-based damage indicators - m_bitsDamageType &= DMG_TIMEBASED; - } - - // Update Status Bar - if ( m_flNextSBarUpdateTime < gpGlobals->time ) - { - UpdateStatusBar(); - m_flNextSBarUpdateTime = gpGlobals->time + 0.2; - } - - if (m_iTrain & TRAIN_NEW) - { - ASSERT( gmsgTrain > 0 ); - // send "health" update message - MESSAGE_BEGIN( MSG_ONE, gmsgTrain, NULL, pev ); - WRITE_BYTE(m_iTrain & 0xF); - MESSAGE_END(); - - m_iTrain &= ~TRAIN_NEW; - } - - int iShellIndex = GetAmmoIndex("shells"); - int iNailIndex = GetAmmoIndex("nails"); - int iRocketIndex = GetAmmoIndex("rockets"); - int iCellIndex = GetAmmoIndex("cells"); - - // - // New Weapon? - // - if (!m_fKnownItem) - { - m_fKnownItem = TRUE; - - // WeaponInit Message - // byte = # of weapons - // - // for each weapon: - // byte name str length (not including null) - // bytes... name - // byte Ammo Type - // byte Ammo2 Type - // byte bucket - // byte bucket pos - // byte flags - // ???? Icons - - // Send ALL the weapon info now - // QUAKECLASSIC - // Tell the client about the Quake weapons - for (int i = 1; i < 10; i++) - { - const char *pszName; - int iAmmoIndex; - int iMaxAmmo = 0; - int iCurrentAmmo = 0; - int iBit = 0; - - switch( i ) - { - case 1: iBit = IT_AXE; break; - case 2: iBit = IT_SHOTGUN; break; - case 3: iBit = IT_SUPER_SHOTGUN; break; - case 4: iBit = IT_NAILGUN; break; - case 5: iBit = IT_SUPER_NAILGUN; break; - case 6: iBit = IT_GRENADE_LAUNCHER; break; - case 7: iBit = IT_ROCKET_LAUNCHER; break; - case 8: iBit = IT_LIGHTNING; break; - case 9: iBit = IT_EXTRA_WEAPON; break; - - default: - pszName = "Empty"; - } - - if ( ! ( m_iQuakeItems & iBit ) ) - continue; - - switch( i ) - { - case 1: pszName = "weapon_axe"; iAmmoIndex = -1; iBit |= IT_AXE; break; - case 2: pszName = "weapon_shotgun"; iAmmoIndex = iShellIndex; iBit |= IT_SHOTGUN; iCurrentAmmo = m_iAmmoShells ; iMaxAmmo = 100; break; - case 3: pszName = "weapon_doubleshotgun"; iAmmoIndex = iShellIndex; iBit |= IT_SUPER_SHOTGUN; iCurrentAmmo = m_iAmmoShells ; iMaxAmmo = 100; break; - case 4: pszName = "weapon_nailgun"; iAmmoIndex = iNailIndex; iBit |= IT_NAILGUN; iCurrentAmmo = m_iAmmoNails; iMaxAmmo = 200; break; - case 5: pszName = "weapon_supernail"; iAmmoIndex = iNailIndex; iBit |= IT_SUPER_NAILGUN; iCurrentAmmo = m_iAmmoNails; iMaxAmmo = 200; break; - case 6: pszName = "weapon_grenadel"; iAmmoIndex = iRocketIndex; iBit |= IT_GRENADE_LAUNCHER; iCurrentAmmo = m_iAmmoRockets; iMaxAmmo = 100; break; - case 7: pszName = "weapon_rocketl"; iAmmoIndex = iRocketIndex; iBit |= IT_ROCKET_LAUNCHER; iCurrentAmmo = m_iAmmoRockets; iMaxAmmo = 100; break; - case 8: pszName = "weapon_lightning"; iAmmoIndex = iCellIndex; iBit |= IT_LIGHTNING; iCurrentAmmo = m_iAmmoCells; iMaxAmmo = 100; break; - case 9: pszName = "weapon_grapple"; iAmmoIndex = -1; iBit |= IT_EXTRA_WEAPON; break; - - default: - pszName = "Empty"; - } - - MESSAGE_BEGIN( MSG_ONE, gmsgWeaponList, NULL, pev ); - WRITE_STRING(pszName); // string weapon name - WRITE_BYTE(iAmmoIndex); // byte Ammo Type - WRITE_BYTE( iMaxAmmo ); // byte Max Ammo 1 - WRITE_BYTE( -1 ); // byte Ammo2 Type - WRITE_BYTE( iCurrentAmmo ); // byte Max Ammo 2 - WRITE_BYTE( i ); // byte bucket - WRITE_BYTE( 0 ); // byte bucket pos - WRITE_LONG( iBit ); // byte id (bit index into pev->weapons) - - if ( i == 1 || i == 9 ) - WRITE_BYTE( 1 ); // We can select this one on empty - else - WRITE_BYTE( 0 ); // Can't select it when empty. - - MESSAGE_END(); - } - } - - - // QUAKECLASSIC - // HACKHACK: Make the HL ammo types equal the Quake ammo - m_rgAmmo[ iShellIndex ] = m_iAmmoShells; - m_rgAmmo[ iNailIndex ] = m_iAmmoNails; - m_rgAmmo[ iRocketIndex ] = m_iAmmoRockets; - m_rgAmmo[ iCellIndex ] = m_iAmmoCells; - SendAmmoUpdate(); - - // Update all the items - for ( int i = 0; i < MAX_ITEM_TYPES; i++ ) - { - if ( m_rgpPlayerItems[i] ) // each item updates it's successors - m_rgpPlayerItems[i]->UpdateClientData( this ); - } - - // Cache and client weapon change - m_pClientActiveItem = m_pActiveItem; - m_iClientFOV = m_iFOV; - - // QUAKECLASSIC - m_iClientQuakeWeapon = m_iQuakeWeapon; -} - - -//========================================================= -// FBecomeProne - Overridden for the player to set the proper -// physics flags when a barnacle grabs player. -//========================================================= -BOOL CBasePlayer :: FBecomeProne ( void ) -{ - m_afPhysicsFlags |= PFLAG_ONBARNACLE; - return TRUE; -} - -//========================================================= -// BarnacleVictimBitten - bad name for a function that is called -// by Barnacle victims when the barnacle pulls their head -// into its mouth. For the player, just die. -//========================================================= -void CBasePlayer :: BarnacleVictimBitten ( entvars_t *pevBarnacle ) -{ - TakeDamage ( pevBarnacle, pevBarnacle, pev->health + pev->armorvalue, DMG_SLASH | DMG_ALWAYSGIB ); -} - -//========================================================= -// BarnacleVictimReleased - overridden for player who has -// physics flags concerns. -//========================================================= -void CBasePlayer :: BarnacleVictimReleased ( void ) -{ - m_afPhysicsFlags &= ~PFLAG_ONBARNACLE; -} - - -//========================================================= -// Illumination -// return player light level plus virtual muzzle flash -//========================================================= -int CBasePlayer :: Illumination( void ) -{ - int iIllum = CBaseEntity::Illumination( ); - - iIllum += m_iWeaponFlash; - if (iIllum > 255) - return 255; - return iIllum; -} - - -void CBasePlayer :: EnableControl(BOOL fControl) -{ - if (!fControl) - pev->flags |= FL_FROZEN; - else - pev->flags &= ~FL_FROZEN; - -} - - -#define DOT_1DEGREE 0.9998476951564 -#define DOT_2DEGREE 0.9993908270191 -#define DOT_3DEGREE 0.9986295347546 -#define DOT_4DEGREE 0.9975640502598 -#define DOT_5DEGREE 0.9961946980917 -#define DOT_6DEGREE 0.9945218953683 -#define DOT_7DEGREE 0.9925461516413 -#define DOT_8DEGREE 0.9902680687416 -#define DOT_9DEGREE 0.9876883405951 -#define DOT_10DEGREE 0.9848077530122 -#define DOT_15DEGREE 0.9659258262891 -#define DOT_20DEGREE 0.9396926207859 -#define DOT_25DEGREE 0.9063077870367 - -//========================================================= -// Autoaim -// set crosshair position to point to enemey -//========================================================= -Vector CBasePlayer :: GetAutoaimVector( float flDelta ) -{ - if (g_iSkillLevel == SKILL_HARD) - { - UTIL_MakeVectors( pev->v_angle + pev->punchangle ); - return gpGlobals->v_forward; - } - - Vector vecSrc = GetGunPosition( ); - float flDist = 8192; - - // always use non-sticky autoaim - // UNDONE: use sever variable to chose! - if (1 || g_iSkillLevel == SKILL_MEDIUM) - { - m_vecAutoAim = Vector( 0, 0, 0 ); - // flDelta *= 0.5; - } - - BOOL m_fOldTargeting = m_fOnTarget; - Vector angles = AutoaimDeflection(vecSrc, flDist, flDelta ); - - // update ontarget if changed - if ( !g_pGameRules->AllowAutoTargetCrosshair() ) - m_fOnTarget = 0; - else if (m_fOldTargeting != m_fOnTarget) - { - m_pActiveItem->UpdateItemInfo( ); - } - - if (angles.x > 180) - angles.x -= 360; - if (angles.x < -180) - angles.x += 360; - if (angles.y > 180) - angles.y -= 360; - if (angles.y < -180) - angles.y += 360; - - if (angles.x > 25) - angles.x = 25; - if (angles.x < -25) - angles.x = -25; - if (angles.y > 12) - angles.y = 12; - if (angles.y < -12) - angles.y = -12; - - - // always use non-sticky autoaim - // UNDONE: use sever variable to chose! - if (0 || g_iSkillLevel == SKILL_EASY) - { - m_vecAutoAim = m_vecAutoAim * 0.67 + angles * 0.33; - } - else - { - m_vecAutoAim = angles * 0.9; - } - - // m_vecAutoAim = m_vecAutoAim * 0.99; - - // Don't send across network if sv_aim is 0 - if ( CVAR_GET_FLOAT( "sv_aim" ) != 0 ) - { - if ( m_vecAutoAim.x != m_lastx || - m_vecAutoAim.y != m_lasty ) - { - SET_CROSSHAIRANGLE( edict(), -m_vecAutoAim.x, m_vecAutoAim.y ); - - m_lastx = m_vecAutoAim.x; - m_lasty = m_vecAutoAim.y; - } - } - - // ALERT( at_console, "%f %f\n", angles.x, angles.y ); - - UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); - return gpGlobals->v_forward; -} - - -Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta ) -{ - edict_t *pEdict = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - CBaseEntity *pEntity; - float bestdot; - Vector bestdir; - edict_t *bestent; - TraceResult tr; - - if ( CVAR_GET_FLOAT("sv_aim") == 0 ) - { - m_fOnTarget = FALSE; - return g_vecZero; - } - - UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); - - // try all possible entities - bestdir = gpGlobals->v_forward; - bestdot = flDelta; // +- 10 degrees - bestent = NULL; - - m_fOnTarget = FALSE; - - UTIL_TraceLine( vecSrc, vecSrc + bestdir * flDist, dont_ignore_monsters, edict(), &tr ); - - - if ( tr.pHit && tr.pHit->v.takedamage != DAMAGE_NO) - { - // don't look through water - if (!((pev->waterlevel != 3 && tr.pHit->v.waterlevel == 3) - || (pev->waterlevel == 3 && tr.pHit->v.waterlevel == 0))) - { - if (tr.pHit->v.takedamage == DAMAGE_AIM) - m_fOnTarget = TRUE; - - return m_vecAutoAim; - } - } - - for ( int i = 1; i < gpGlobals->maxEntities; i++, pEdict++ ) - { - Vector center; - Vector dir; - float dot; - - if ( pEdict->free ) // Not in use - continue; - - if (pEdict->v.takedamage != DAMAGE_AIM) - continue; - if (pEdict == edict()) - continue; -// if (pev->team > 0 && pEdict->v.team == pev->team) -// continue; // don't aim at teammate - if ( !g_pGameRules->ShouldAutoAim( this, pEdict ) ) - continue; - - pEntity = Instance( pEdict ); - if (pEntity == NULL) - continue; - - if (!pEntity->IsAlive()) - continue; - - // don't look through water - if ((pev->waterlevel != 3 && pEntity->pev->waterlevel == 3) - || (pev->waterlevel == 3 && pEntity->pev->waterlevel == 0)) - continue; - - center = pEntity->BodyTarget( vecSrc ); - - dir = (center - vecSrc).Normalize( ); - - // make sure it's in front of the player - if (DotProduct (dir, gpGlobals->v_forward ) < 0) - continue; - - dot = fabs( DotProduct (dir, gpGlobals->v_right ) ) - + fabs( DotProduct (dir, gpGlobals->v_up ) ) * 0.5; - - // tweek for distance - dot *= 1.0 + 0.2 * ((center - vecSrc).Length() / flDist); - - if (dot > bestdot) - continue; // to far to turn - - UTIL_TraceLine( vecSrc, center, dont_ignore_monsters, edict(), &tr ); - if (tr.flFraction != 1.0 && tr.pHit != pEdict) - { - // ALERT( at_console, "hit %s, can't see %s\n", STRING( tr.pHit->v.classname ), STRING( pEdict->v.classname ) ); - continue; - } - - // don't shoot at friends - if (IRelationship( pEntity ) < 0) - { - if ( !pEntity->IsPlayer() && !g_pGameRules->IsDeathmatch()) - // ALERT( at_console, "friend\n"); - continue; - } - - // can shoot at this one - bestdot = dot; - bestent = pEdict; - bestdir = dir; - } - - if (bestent) - { - bestdir = UTIL_VecToAngles (bestdir); - bestdir.x = -bestdir.x; - bestdir = bestdir - pev->v_angle - pev->punchangle; - - if (bestent->v.takedamage == DAMAGE_AIM) - m_fOnTarget = TRUE; - - return bestdir; - } - - return Vector( 0, 0, 0 ); -} - - -void CBasePlayer :: ResetAutoaim( ) -{ - if (m_vecAutoAim.x != 0 || m_vecAutoAim.y != 0) - { - m_vecAutoAim = Vector( 0, 0, 0 ); - SET_CROSSHAIRANGLE( edict(), 0, 0 ); - } - m_fOnTarget = FALSE; -} - -/* -============= -SetCustomDecalFrames - - UNDONE: Determine real frame limit, 8 is a placeholder. - Note: -1 means no custom frames present. -============= -*/ -void CBasePlayer :: SetCustomDecalFrames( int nFrames ) -{ - if (nFrames > 0 && - nFrames < 8) - m_nCustomSprayFrames = nFrames; - else - m_nCustomSprayFrames = -1; -} - -/* -============= -GetCustomDecalFrames - - Returns the # of custom frames this player's custom clan logo contains. -============= -*/ -int CBasePlayer :: GetCustomDecalFrames( void ) -{ - return m_nCustomSprayFrames; -} - - -//========================================================= -// DropPlayerItem - drop the named item, or if no name, -// the active item. -//========================================================= -void CBasePlayer::DropPlayerItem ( char *pszItemName ) -{ - if ( !g_pGameRules->IsMultiplayer() || (CVAR_GET_FLOAT("mp_weaponstay") > 0) ) - { - // no dropping in single player. - return; - } - - if ( !strlen( pszItemName ) ) - { - // if this string has no length, the client didn't type a name! - // assume player wants to drop the active item. - // make the string null to make future operations in this function easier - pszItemName = NULL; - } - - CBasePlayerItem *pWeapon; - int i; - - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - pWeapon = m_rgpPlayerItems[ i ]; - - while ( pWeapon ) - { - if ( pszItemName ) - { - // try to match by name. - if ( !strcmp( pszItemName, STRING( pWeapon->pev->classname ) ) ) - { - // match! - break; - } - } - else - { - // trying to drop active item - if ( pWeapon == m_pActiveItem ) - { - // active item! - break; - } - } - - pWeapon = pWeapon->m_pNext; - } - - - // if we land here with a valid pWeapon pointer, that's because we found the - // item we want to drop and hit a BREAK; pWeapon is the item. - if ( pWeapon ) - { - g_pGameRules->GetNextBestWeapon( this, pWeapon ); - - UTIL_MakeVectors ( pev->angles ); - - pev->weapons &= ~(1<m_iId);// take item off hud - - CWeaponBox *pWeaponBox = (CWeaponBox *)CBaseEntity::Create( "weaponbox", pev->origin + gpGlobals->v_forward * 10, pev->angles, edict() ); - pWeaponBox->pev->angles.x = 0; - pWeaponBox->pev->angles.z = 0; - pWeaponBox->PackWeapon( pWeapon ); - pWeaponBox->pev->velocity = gpGlobals->v_forward * 300 + gpGlobals->v_forward * 100; - - // drop half of the ammo for this weapon. - int iAmmoIndex; - - iAmmoIndex = GetAmmoIndex ( pWeapon->pszAmmo1() ); // ??? - - if ( iAmmoIndex != -1 ) - { - // this weapon weapon uses ammo, so pack an appropriate amount. - if ( pWeapon->iFlags() & ITEM_FLAG_EXHAUSTIBLE ) - { - // pack up all the ammo, this weapon is its own ammo type - pWeaponBox->PackAmmo( MAKE_STRING(pWeapon->pszAmmo1()), m_rgAmmo[ iAmmoIndex ] ); - m_rgAmmo[ iAmmoIndex ] = 0; - - } - else - { - // pack half of the ammo - pWeaponBox->PackAmmo( MAKE_STRING(pWeapon->pszAmmo1()), m_rgAmmo[ iAmmoIndex ] / 2 ); - m_rgAmmo[ iAmmoIndex ] /= 2; - } - - } - - return;// we're done, so stop searching with the FOR loop. - } - } -} - -//========================================================= -// HasPlayerItem Does the player already have this item? -//========================================================= -BOOL CBasePlayer::HasPlayerItem( CBasePlayerItem *pCheckItem ) -{ - CBasePlayerItem *pItem = m_rgpPlayerItems[pCheckItem->iItemSlot()]; - - while (pItem) - { - if (FClassnameIs( pItem->pev, STRING( pCheckItem->pev->classname) )) - { - return TRUE; - } - pItem = pItem->m_pNext; - } - - return FALSE; -} - -//========================================================= -// HasNamedPlayerItem Does the player already have this item? -//========================================================= -BOOL CBasePlayer::HasNamedPlayerItem( const char *pszItemName ) -{ - CBasePlayerItem *pItem; - int i; - - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - pItem = m_rgpPlayerItems[ i ]; - - while (pItem) - { - if ( !strcmp( pszItemName, STRING( pItem->pev->classname ) ) ) - { - return TRUE; - } - pItem = pItem->m_pNext; - } - } - - return FALSE; -} - -//========================================================= -// -//========================================================= -BOOL CBasePlayer :: SwitchWeapon( CBasePlayerItem *pWeapon ) -{ - if ( !pWeapon->CanDeploy() ) - { - return FALSE; - } - - ResetAutoaim( ); - - if (m_pActiveItem) - { - m_pActiveItem->Holster( ); - } - - m_pActiveItem = pWeapon; - pWeapon->Deploy( ); - - return TRUE; -} - -//========================================================= -// Dead HEV suit prop -//========================================================= -class CDeadHEV : public CBaseMonster -{ -public: - void Spawn( void ); - int Classify ( void ) { return CLASS_HUMAN_MILITARY; } - - void KeyValue( KeyValueData *pkvd ); - - int m_iPose;// which sequence to display -- temporary, don't need to save - static char *m_szPoses[4]; -}; - -char *CDeadHEV::m_szPoses[] = { "deadback", "deadsitting", "deadstomach", "deadtable" }; - -void CDeadHEV::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "pose")) - { - m_iPose = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseMonster::KeyValue( pkvd ); -} - -LINK_ENTITY_TO_CLASS( monster_hevsuit_dead, CDeadHEV ); - -//========================================================= -// ********** DeadHEV SPAWN ********** -//========================================================= -void CDeadHEV :: Spawn( void ) -{ - PRECACHE_MODEL("models/player.mdl"); - SET_MODEL(ENT(pev), "models/player.mdl"); - - pev->effects = 0; - pev->yaw_speed = 8; - pev->sequence = 0; - pev->body = 1; - m_bloodColor = BLOOD_COLOR_RED; - - pev->sequence = LookupSequence( m_szPoses[m_iPose] ); - - if (pev->sequence == -1) - { - ALERT ( at_console, "Dead hevsuit with bad pose\n" ); - pev->sequence = 0; - pev->effects = EF_BRIGHTFIELD; - } - - // Corpses have less health - pev->health = 8; - - MonsterInitDead(); -} - - -class CStripWeapons : public CPointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -private: -}; - -LINK_ENTITY_TO_CLASS( player_weaponstrip, CStripWeapons ); - -void CStripWeapons :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - CBasePlayer *pPlayer = NULL; - - if ( pActivator && pActivator->IsPlayer() ) - { - pPlayer = (CBasePlayer *)pActivator; - } - else if ( !g_pGameRules->IsDeathmatch() ) - { - pPlayer = (CBasePlayer *)CBaseEntity::Instance( g_engfuncs.pfnPEntityOfEntIndex( 1 ) ); - } - - if ( pPlayer ) - pPlayer->RemoveAllItems( FALSE ); -} - - -class CRevertSaved : public CPointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT MessageThink( void ); - void EXPORT LoadThink( void ); - void KeyValue( KeyValueData *pkvd ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - inline float Duration( void ) { return pev->dmg_take; } - inline float HoldTime( void ) { return pev->dmg_save; } - inline float MessageTime( void ) { return m_messageTime; } - inline float LoadTime( void ) { return m_loadTime; } - - inline void SetDuration( float duration ) { pev->dmg_take = duration; } - inline void SetHoldTime( float hold ) { pev->dmg_save = hold; } - inline void SetMessageTime( float time ) { m_messageTime = time; } - inline void SetLoadTime( float time ) { m_loadTime = time; } - -private: - float m_messageTime; - float m_loadTime; -}; - -LINK_ENTITY_TO_CLASS( player_loadsaved, CRevertSaved ); - -TYPEDESCRIPTION CRevertSaved::m_SaveData[] = -{ - DEFINE_FIELD( CRevertSaved, m_messageTime, FIELD_FLOAT ), // These are not actual times, but durations, so save as floats - DEFINE_FIELD( CRevertSaved, m_loadTime, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CRevertSaved, CPointEntity ); - -void CRevertSaved :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "duration")) - { - SetDuration( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "holdtime")) - { - SetHoldTime( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "messagetime")) - { - SetMessageTime( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "loadtime")) - { - SetLoadTime( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -void CRevertSaved :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), pev->renderamt, FFADE_OUT ); - pev->nextthink = gpGlobals->time + MessageTime(); - SetThink( &CRevertSaved::MessageThink ); -} - - -void CRevertSaved :: MessageThink( void ) -{ - UTIL_ShowMessageAll( STRING(pev->message) ); - float nextThink = LoadTime() - MessageTime(); - if ( nextThink > 0 ) - { - pev->nextthink = gpGlobals->time + nextThink; - SetThink( &CRevertSaved::LoadThink ); - } - else - LoadThink(); -} - - -void CRevertSaved :: LoadThink( void ) -{ - if ( !gpGlobals->deathmatch ) - { - SERVER_COMMAND("reload\n"); - } -} - - -//========================================================= -// Multiplayer intermission spots. -//========================================================= -class CInfoIntermission:public CPointEntity -{ - void Spawn( void ); - void Think( void ); -}; - -void CInfoIntermission::Spawn( void ) -{ - UTIL_SetOrigin( pev, pev->origin ); - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; - pev->v_angle = g_vecZero; - - pev->nextthink = gpGlobals->time + 2;// let targets spawn! - -} - -void CInfoIntermission::Think ( void ) -{ - edict_t *pTarget; - - // find my target - pTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->target) ); - - if ( !FNullEnt(pTarget) ) - { - pev->v_angle = UTIL_VecToAngles( (pTarget->v.origin - pev->origin).Normalize() ); - pev->v_angle.x = -pev->v_angle.x; - } -} - -LINK_ENTITY_TO_CLASS( info_intermission, CInfoIntermission ); - diff --git a/dmc/dlls/player.h b/dmc/dlls/player.h deleted file mode 100644 index a9be420..0000000 --- a/dmc/dlls/player.h +++ /dev/null @@ -1,497 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -#ifndef PLAYER_H -#define PLAYER_H - -#define PLAYER_FATAL_FALL_SPEED 1024// approx 60 feet -#define PLAYER_MAX_SAFE_FALL_SPEED 580// approx 20 feet -#define DAMAGE_FOR_FALL_SPEED (float) 100 / ( PLAYER_FATAL_FALL_SPEED - PLAYER_MAX_SAFE_FALL_SPEED )// damage per unit per second. -#define PLAYER_MIN_BOUNCE_SPEED 200 -#define PLAYER_FALL_PUNCH_THRESHHOLD (float)350 // won't punch player's screen/make scrape noise unless player falling at least this fast. - -// -// Player PHYSICS FLAGS bits -// -#define PFLAG_ONLADDER ( 1<<0 ) -#define PFLAG_ONSWING ( 1<<0 ) -#define PFLAG_ONTRAIN ( 1<<1 ) -#define PFLAG_ONBARNACLE ( 1<<2 ) -#define PFLAG_DUCKING ( 1<<3 ) // In the process of ducking, but totally squatted yet -#define PFLAG_USING ( 1<<4 ) // Using a continuous entity -#define PFLAG_OBSERVER ( 1<<5 ) // player is locked in stationary cam mode. Spectators can move, observers can't. - -// -// generic player -// -//----------------------------------------------------- -//This is Half-Life player entity -//----------------------------------------------------- -#define CSUITPLAYLIST 4 // max of 4 suit sentences queued up at any time - -#define SUIT_GROUP TRUE -#define SUIT_SENTENCE FALSE - -#define SUIT_REPEAT_OK 0 -#define SUIT_NEXT_IN_30SEC 30 -#define SUIT_NEXT_IN_1MIN 60 -#define SUIT_NEXT_IN_5MIN 300 -#define SUIT_NEXT_IN_10MIN 600 -#define SUIT_NEXT_IN_30MIN 1800 -#define SUIT_NEXT_IN_1HOUR 3600 - -#define CSUITNOREPEAT 32 - -#define SOUND_FLASHLIGHT_ON "items/flashlight1.wav" -#define SOUND_FLASHLIGHT_OFF "items/flashlight1.wav" - -#define TEAM_NAME_LENGTH 16 - -typedef enum -{ - PLAYER_IDLE, - PLAYER_WALK, - PLAYER_JUMP, - PLAYER_SUPERJUMP, - PLAYER_DIE, - PLAYER_ATTACK1, -} PLAYER_ANIM; - -#ifdef THREEWAVE -enum Player_Menu { - Team_Menu, - Team_Menu_IG, -}; -#endif - -#define MAX_ID_RANGE 2048 -#define SBAR_STRING_SIZE 128 -enum sbar_data -{ -SBAR_ID_TARGETNAME = 1, -SBAR_ID_TARGETHEALTH, -SBAR_ID_TARGETARMOR, -SBAR_ID_TARGETRUNE, -SBAR_ID_TARGETTEAM, -SBAR_END, -}; - -#define PLAYER_MAX_SPEED 300 - -class CBasePlayer : public CBaseMonster -{ -public: - int random_seed; // See that is shared between client & server for shared weapons code - - int m_iPlayerSound;// the index of the sound list slot reserved for this player - int m_iTargetVolume;// ideal sound volume. - int m_iWeaponVolume;// how loud the player's weapon is right now. - int m_iExtraSoundTypes;// additional classification for this weapon's sound - int m_iWeaponFlash;// brightness of the weapon flash - float m_flStopExtraSoundTime; - - float m_flFlashLightTime; // Time until next battery draw/Recharge - int m_iFlashBattery; // Flashlight Battery Draw - - int m_afButtonLast; - int m_afButtonPressed; - int m_afButtonReleased; - - edict_t *m_pentSndLast; // last sound entity to modify player room type - float m_flSndRoomtype; // last roomtype set by sound entity - float m_flSndRange; // dist from player to sound entity - - float m_flFallVelocity; - - int m_rgItems[MAX_ITEMS]; - int m_fKnownItem; // True when a new item needs to be added - int m_fNewAmmo; // True when a new item has been added - - unsigned int m_afPhysicsFlags; // physics flags - set when 'normal' physics should be revisited or overriden - float m_fNextSuicideTime; // the time after which the player can next use the suicide command - - -// these are time-sensitive things that we keep track of - float m_flTimeStepSound; // when the last stepping sound was made - float m_flTimeWeaponIdle; // when to play another weapon idle animation. - float m_flSwimTime; // how long player has been underwater - float m_flDuckTime; // how long we've been ducking - float m_flWallJumpTime; // how long until next walljump - - float m_flSuitUpdate; // when to play next suit update - int m_rgSuitPlayList[CSUITPLAYLIST];// next sentencenum to play for suit update - int m_iSuitPlayNext; // next sentence slot for queue storage; - int m_rgiSuitNoRepeat[CSUITNOREPEAT]; // suit sentence no repeat list - float m_rgflSuitNoRepeatTime[CSUITNOREPEAT]; // how long to wait before allowing repeat - int m_lastDamageAmount; // Last damage taken - float m_tbdPrev; // Time-based damage timer - - float m_flgeigerRange; // range to nearest radiation source - float m_flgeigerDelay; // delay per update of range msg to client - int m_igeigerRangePrev; - int m_iStepLeft; // alternate left/right foot stepping sound - char m_szTextureName[CBTEXTURENAMEMAX]; // current texture name we're standing on - char m_chTextureType; // current texture type - - int m_idrowndmg; // track drowning damage taken - int m_idrownrestored; // track drowning damage restored - - int m_bitsHUDDamage; // Damage bits for the current fame. These get sent to - // the hude via the DAMAGE message - BOOL m_fInitHUD; // True when deferred HUD restart msg needs to be sent - BOOL m_fGameHUDInitialized; - int m_iTrain; // Train control position - BOOL m_fWeapon; // Set this to FALSE to force a reset of the current weapon HUD info - - EHANDLE m_pTank; // the tank which the player is currently controlling, NULL if no tank - float m_fDeadTime; // the time at which the player died (used in PlayerDeathThink()) - - BOOL m_fNoPlayerSound; // a debugging feature. Player makes no sound if this is true. - BOOL m_fLongJump; // does this player have the longjump module? - - float m_tSneaking; - int m_iUpdateTime; // stores the number of frame ticks before sending HUD update messages - int m_iClientHealth; // the health currently known by the client. If this changes, send a new - int m_iClientBattery; // the Battery currently known by the client. If this changes, send a new - int m_iHideHUD; // the players hud weapon info is to be hidden - int m_iClientHideHUD; - int m_iFOV; // field of view - int m_iClientFOV; // client's known FOV - // usable player items - CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES]; - CBasePlayerItem *m_pActiveItem; - CBasePlayerItem *m_pClientActiveItem; // client version of the active item - CBasePlayerItem *m_pLastItem; - // shared ammo slots - int m_rgAmmo[MAX_AMMO_SLOTS]; - int m_rgAmmoLast[MAX_AMMO_SLOTS]; - - Vector m_vecAutoAim; - BOOL m_fOnTarget; - int m_iDeaths; - float m_iRespawnFrames; // used in PlayerDeathThink() to make sure players can always respawn - - int m_lastx, m_lasty; // These are the previous update's crosshair angles, DON"T SAVE/RESTORE - - int m_nCustomSprayFrames;// Custom clan logo frames for this player - float m_flNextDecalTime;// next time this player can spray a decal - - char m_szTeamName[TEAM_NAME_LENGTH]; - - virtual void Spawn( void ); - -// virtual void Think( void ); - virtual void Jump( void ); - virtual void Duck( void ); - virtual void PreThink( void ); - virtual void PostThink( void ); - virtual Vector GetGunPosition( void ); - virtual int TakeHealth( float flHealth, int bitsDamageType ); - virtual void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType); - virtual void Killed( entvars_t *pevAttacker, int iGib ); - virtual Vector BodyTarget( const Vector &posSrc ) { return Center( ) + pev->view_ofs * RANDOM_FLOAT( 0.5, 1.1 ); }; // position to shoot at - virtual void StartSneaking( void ) { m_tSneaking = gpGlobals->time - 1; } - virtual void StopSneaking( void ) { m_tSneaking = gpGlobals->time + 30; } - virtual BOOL IsSneaking( void ) { return m_tSneaking <= gpGlobals->time; } - virtual BOOL IsAlive( void ) { return (pev->deadflag == DEAD_NO) && pev->health > 0; } - virtual BOOL ShouldFadeOnDeath( void ) { return FALSE; } - virtual BOOL IsPlayer( void ) { return TRUE; } // Spectators should return FALSE for this, they aren't "players" as far as game logic is concerned - - virtual BOOL IsNetClient( void ) { return TRUE; } // Bots should return FALSE for this, they can't receive NET messages - // Spectators should return TRUE for this - virtual const char *TeamID( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - void RenewItems(void); - void RemoveAllItems( BOOL removeSuit ); - BOOL SwitchWeapon( CBasePlayerItem *pWeapon ); - - // JOHN: sends custom messages if player HUD data has changed (eg health, ammo) - virtual void UpdateClientData( void ); - - static TYPEDESCRIPTION m_playerSaveData[]; - - // Player is moved across the transition by other means - virtual int ObjectCaps( void ) { return CBaseMonster :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual void Precache( void ); - BOOL IsOnLadder( void ); - BOOL FlashlightIsOn( void ); - void FlashlightTurnOn( void ); - void FlashlightTurnOff( void ); - - void DeathSound ( void ); - - int Classify ( void ); - void SetAnimation( PLAYER_ANIM playerAnim ); - void SetWeaponAnimType( const char *szExtention ); - char m_szAnimExtention[32]; - - // custom player functions - virtual void ImpulseCommands( void ); - void CheatImpulseCommands( int iImpulse ); - - void StartDeathCam( void ); - void StartObserver( Vector vecPosition, Vector vecViewAngle ); - - void AddPoints( int score, BOOL bAllowNegativeScore ); - void AddPointsToTeam( int score, BOOL bAllowNegativeScore ); - BOOL AddPlayerItem( CBasePlayerItem *pItem ); - BOOL RemovePlayerItem( CBasePlayerItem *pItem ); - void DropPlayerItem ( char *pszItemName ); - BOOL HasPlayerItem( CBasePlayerItem *pCheckItem ); - BOOL HasNamedPlayerItem( const char *pszItemName ); - BOOL HasWeapons( void );// do I have ANY weapons? - void SelectPrevItem( int iItem ); - void SelectNextItem( int iItem ); - void SelectLastItem(void); - void SelectItem(const char *pstr); - void ItemPreFrame( void ); - void ItemPostFrame( void ); - void GiveNamedItem( const char *szName ); - void EnableControl(BOOL fControl); - - int GiveAmmo( int iAmount, char *szName, int iMax ); - void SendAmmoUpdate(void); - - void WaterMove( void ); - void EXPORT PlayerDeathThink( void ); - void PlayerUse( void ); - - void CheckSuitUpdate(); - void SetSuitUpdate(char *name, int fgroup, int iNoRepeat); - void UpdateGeigerCounter( void ); - void CheckTimeBasedDamage( void ); - void UpdateStepSound( void ); - void PlayStepSound(int step, float fvol); - - BOOL FBecomeProne ( void ); - void BarnacleVictimBitten ( entvars_t *pevBarnacle ); - void BarnacleVictimReleased ( void ); - static int GetAmmoIndex(const char *psz); - int AmmoInventory( int iAmmoIndex ); - int Illumination( void ); - - void ResetAutoaim( void ); - Vector GetAutoaimVector( float flDelta ); - Vector AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta ); - - void ForceClientDllUpdate( void ); // Forces all client .dll specific data to be resent to client. - - void DeathMessage( entvars_t *pevKiller ); - - void SetCustomDecalFrames( int nFrames ); - int GetCustomDecalFrames( void ); - - // Observer camera - void Observer_FindNextPlayer(); - void Observer_HandleButtons(); - void Observer_SetMode( int iMode ); - EHANDLE m_hObserverTarget; - float m_flNextObserverInput; - int IsObserver() { return pev->iuser1; }; - - - // QUAKECLASSIC - // Player - void Pain( CBaseEntity *pAttacker ); - float m_flPainSoundFinished; - - BOOL m_bHadFirstSpawn; // used to handle the MOTD - - // Weapon selection - int W_BestWeapon( void ); - void W_SetCurrentAmmo( int sendanim = 1 ); - BOOL W_CheckNoAmmo( void ); - void W_ChangeWeapon( int iWeaponNumber ); - void W_CycleWeaponCommand( void ); - void W_CycleWeaponReverseCommand( void ); - - // Weapon functionality - void Q_FireBullets(int iShots, Vector vecDir, Vector vecSpread); - void LightningDamage( Vector p1, Vector p2, CBaseEntity *pAttacker, float flDamage,Vector vecDir); - - // Weapons - void W_Attack( int iQuadSound ); - void W_FireAxe( void ); - void W_FireShotgun( int QuadSound ); - void W_FireSuperShotgun( int QuadSound ); - void W_FireRocket( int QuadSound ); - void W_FireLightning( int QuadSound ); - void W_FireGrenade( int QuadSound ); - void W_FireSuperSpikes( int QuadSound ); - void W_FireSpikes( int QuadSound ); - - // Ammunition - void CheckAmmo( void ); - int *m_pCurrentAmmo; // Always points to one of the four ammo counts below - int m_iAmmoRockets; - int m_iAmmoCells; - int m_iAmmoShells; - int m_iAmmoNails; - - // Backpacks - void DropBackpack( void ); - - // Weapons - void Deathmatch_Weapon(int iOldWeapon, int iNewWeapon); - int m_iQuakeWeapon; - int m_iClientQuakeWeapon; // The last status of the m_iQuakeWeapon sent to the client. - int m_iQuakeItems; - int m_iClientQuakeItems; // The last status of the m_iQuakeItems sent to the client. - int m_iWeaponSwitch; - int m_iBackpackSwitch; - int m_iAutoWepSwitch; - - // Weapon Data - float m_flAxeFire; - float m_flLightningTime; - int m_iNailOffset; - float m_flNextQuadSound; - - // Powerups - float m_flSuperDamageFinished; - float m_flInvincibleFinished; - float m_flInvisibleFinished; - float m_flRadsuitFinished; - void PowerUpThink( void ); //Checks powerup timers and hadles their effects - char m_chOldModel[64]; //Save the player's model here - bool m_bPlayedQuadSound; - bool m_bPlayedEnvSound; - bool m_bPlayedInvSound; - bool m_bPlayedProtectSound; - - BOOL m_bLostInvincSound; - BOOL m_bLostInvisSound; - BOOL m_bLostSuperSound; - BOOL m_bLostRadSound; - float m_fInvincSound; - float m_fSuperSound; - - void InitStatusBar( void ); - void UpdateStatusBar( void ); - int m_izSBarState[ SBAR_END ]; - float m_flNextSBarUpdateTime; - float m_flStatusBarDisappearDelay; - char m_SbarString0[ SBAR_STRING_SIZE ]; - char m_SbarString1[ SBAR_STRING_SIZE ]; - - unsigned short m_usShotgunSingle; - unsigned short m_usShotgunDouble; - unsigned short m_usAxe; - unsigned short m_usAxeSwing; - unsigned short m_usRocket; - unsigned short m_usGrenade; - unsigned short m_usLightning; - unsigned short m_usSpike; - unsigned short m_usSuperSpike; - - -#ifdef THREEWAVE - int m_bHasFlag; - void ShowMenu ( int bitsValidSlots, int nDisplayTime, BOOL fNeedMore, char *pszText ); - int m_iMenu; - - float m_flNextTeamChange; - - CBasePlayer *pFlagCarrierKiller; - CBasePlayer *pFlagReturner; - CBasePlayer *pCarrierHurter; - - float m_flCarrierHurtTime; - float m_flCarrierPickupTime; - float m_flFlagCarrierKillTime; - float m_flFlagReturnTime; - float m_flFlagStatusTime; - - float m_flRegenTime; - - int m_iRuneStatus; - - void W_FireHook ( void ); - void Throw_Grapple ( void ); - - bool m_bHook_Out; - bool m_bOn_Hook; - CBaseEntity *m_ppHook; - - void Service_Grapple ( void ); - -#endif - - -//#ifdef THREEWAVE - -//#endif - -}; - -#define AUTOAIM_2DEGREES 0.0348994967025 -#define AUTOAIM_5DEGREES 0.08715574274766 -#define AUTOAIM_8DEGREES 0.1391731009601 -#define AUTOAIM_10DEGREES 0.1736481776669 - - - - - - -// QUAKECLASSIC -#define Q_SMALL_PUNCHANGLE_KICK -2 -#define Q_BIG_PUNCHANGLE_KICK -4 - -#define IT_AXE (1 << 0) -#define IT_SHOTGUN (1 << 1) -#define IT_SUPER_SHOTGUN (1 << 2) -#define IT_NAILGUN (1 << 3) -#define IT_SUPER_NAILGUN (1 << 4) -#define IT_GRENADE_LAUNCHER (1 << 5) -#define IT_ROCKET_LAUNCHER (1 << 6) -#define IT_LIGHTNING (1 << 7) -#define IT_EXTRA_WEAPON (1 << 8) - -#define IT_SHELLS (1 << 9) -#define IT_NAILS (1 << 10) -#define IT_ROCKETS (1 << 11) -#define IT_CELLS (1 << 12) - -#define IT_ARMOR1 (1 << 13) -#define IT_ARMOR2 (1 << 14) -#define IT_ARMOR3 (1 << 15) -#define IT_SUPERHEALTH (1 << 16) - -#define IT_KEY1 (1 << 17) -#define IT_KEY2 (1 << 18) - -#define IT_INVISIBILITY (1 << 19) -#define IT_INVULNERABILITY (1 << 20) -#define IT_SUIT (1 << 21) -#define IT_QUAD (1 << 22) - - -#define ITEM_RUNE1_FLAG 1 -#define ITEM_RUNE2_FLAG 2 -#define ITEM_RUNE3_FLAG 3 -#define ITEM_RUNE4_FLAG 4 - - - - -extern int gmsgHudText; -extern BOOL gInitHUD; - -#define MAX_TELES 256 - -#endif // PLAYER_H diff --git a/dmc/dlls/quake_gun.cpp b/dmc/dlls/quake_gun.cpp deleted file mode 100644 index ff550ff..0000000 --- a/dmc/dlls/quake_gun.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== quake_gun.cpp ======================================================== - - This is a half-life weapon that fires every one of the quake weapons. - It's automatically given to all players. - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "quake_gun.h" - -LINK_ENTITY_TO_CLASS( weapon_quakegun, CQuakeGun ); - - -//=========================================================== -void CQuakeGun::Spawn( ) -{ - Precache( ); - SET_MODEL(ENT(pev), "models/v_crowbar.mdl"); - m_iDefaultAmmo = GLOCK_DEFAULT_GIVE; - FallInit(); -} - -void CQuakeGun::Precache( void ) -{ - PRECACHE_MODEL("models/v_crowbar.mdl"); - PRECACHE_MODEL("models/p_9mmhandgun.mdl"); -} - -int CQuakeGun::GetItemInfo(ItemInfo *p) -{ - p->pszName = STRING(pev->classname); - p->pszAmmo1 = NULL; - p->iMaxAmmo1 = -1; - p->pszAmmo2 = NULL; - p->iMaxAmmo2 = -1; - p->iMaxClip = -1; - p->iSlot = 1; - p->iPosition = 1; - p->iFlags = 0; - p->iId = m_iId = WEAPON_GLOCK; - p->iWeight = GLOCK_WEIGHT; - - return 1; -} - -void CQuakeGun::DestroyEffect( void ) -{ - -#ifndef CLIENT_DLL - if ( m_pBeam ) - { - UTIL_Remove( m_pBeam ); - m_pBeam = NULL; - } -#endif - -} - -void CQuakeGun::CreateEffect( void ) -{ - -#ifndef CLIENT_DLL - DestroyEffect(); - - m_pBeam = CBeam::BeamCreate( "sprites/laserbeam.spr", 40 ); - m_pBeam->PointEntInit( pev->origin, m_pPlayer->entindex() ); - m_pBeam->SetBrightness( 100 ); - m_pBeam->SetEndAttachment( 1 ); - m_pBeam->pev->spawnflags |= SF_BEAM_TEMPORARY; // Flag these to be destroyed on save/restore or level transition - m_pBeam->pev->flags |= FL_SKIPLOCALHOST; - m_pBeam->pev->owner = m_pPlayer->edict(); - - m_pBeam->SetScrollRate( 110 ); - m_pBeam->SetNoise( 5 ); -#endif - -} - -void CQuakeGun::UpdateEffect( void ) -{ -#if !defined( CLIENT_DLL ) - UTIL_MakeVectors( m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle ); - Vector vecAiming = gpGlobals->v_forward; - Vector vecSrc = m_pPlayer->GetGunPosition( ); - - Vector vecDest = vecSrc + vecAiming * 2048; - edict_t *pentIgnore; - TraceResult tr; - - pentIgnore = m_pPlayer->edict(); - Vector tmpSrc = vecSrc + gpGlobals->v_up * -8 + gpGlobals->v_right * 3; - - // ALERT( at_console, "." ); - - UTIL_TraceLine( vecSrc, vecDest, dont_ignore_monsters, pentIgnore, &tr ); - - if (tr.fAllSolid) - return; - - if ( !m_pBeam ) - { - CreateEffect(); - } - - m_pBeam->SetStartPos( tr.vecEndPos ); -#endif - -} - -#if !defined( CLIENT_DLL ) -BOOL CQuakeGun::Deploy( ) -{ - m_pPlayer->pev->viewmodel = MAKE_STRING("models/v_crowbar.mdl"); - m_pPlayer->pev->weaponmodel = MAKE_STRING("models/p_9mmhandgun.mdl"); - strcpy( m_pPlayer->m_szAnimExtention, "onehanded" ); - -#ifdef CLIENT_DLL - g_flLightTime = 0.0; -#endif - - SendWeaponAnim( 0 ); - return TRUE; -} -#endif - -// Plays quad sound if needed -int CQuakeGun::SuperDamageSound() -{ - if ( m_pPlayer->m_iQuakeItems & IT_QUAD ) - { - if ( m_pPlayer->m_flNextQuadSound < gpGlobals->time) - { - m_pPlayer->m_flNextQuadSound = gpGlobals->time + 1; - return 1; - } - } - - return 0; -} - -// Firing the Quakegun forces the player to fire the appropriate weapon -void CQuakeGun::PrimaryAttack( void ) -{ - int iQuadSound = 0; - iQuadSound = SuperDamageSound(); - m_pPlayer->W_Attack( iQuadSound ); - -#if !defined( CLIENT_DLL ) - if ( m_pPlayer->m_iQuakeWeapon == IT_LIGHTNING && m_pPlayer->pev->deadflag == DEAD_NO ) - UpdateEffect(); -#endif - - m_bPlayedIdleAnim = FALSE; -} diff --git a/dmc/dlls/quake_gun.h b/dmc/dlls/quake_gun.h deleted file mode 100644 index a0d16ec..0000000 --- a/dmc/dlls/quake_gun.h +++ /dev/null @@ -1,44 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== quake_gun.h ======================================================== - - This is a half-life weapon that fires every one of the quake weapons. - It's automatically given to all players. - -*/ -#include "effects.h" - -class CQuakeGun : public CBasePlayerWeapon -{ -public: - void Spawn( void ); - void Precache( void ); - int iItemSlot( void ) { return 1; } - int GetItemInfo(ItemInfo *p); - - int SuperDamageSound( void ); - - void PrimaryAttack( void ); - BOOL Deploy( void ); - - void UpdateEffect( void ); - - void CreateEffect ( void ); - void DestroyEffect ( void ); - - CBeam *m_pBeam; -}; diff --git a/dmc/dlls/quake_items.cpp b/dmc/dlls/quake_items.cpp deleted file mode 100644 index 0d83fe5..0000000 --- a/dmc/dlls/quake_items.cpp +++ /dev/null @@ -1,1866 +0,0 @@ -//=========== (C) Copyright 1996-2002, Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Quake world items -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "shake.h" -#include "../engine/studio.h" -#include "weapons.h" -#include "quake_gun.h" -#include "hltv.h" - -extern unsigned short g_usPowerUp; - -class CQuakeItem : public CBaseEntity -{ -public: - void Spawn( void ); - - // Respawning - void EXPORT Materialize( void ); - void Respawn( float flTime ); - - virtual void SetObjectCollisionBox ( void ); - - // Touch - void EXPORT ItemTouch( CBaseEntity *pOther ); - virtual BOOL MyTouch( CBasePlayer *pOther ) { return FALSE; }; - - float m_flRespawnTime; -}; - -//----------------------------------------------------------------------------- -// Purpose: Spawn and drop to the floor -//----------------------------------------------------------------------------- - -void CQuakeItem :: SetObjectCollisionBox( void ) -{ - pev->absmin = pev->origin + Vector(-32, -32, 0); - pev->absmax = pev->origin + Vector(32, 32, 56); -} - -void CQuakeItem::Spawn() -{ - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - - SetTouch(&CQuakeItem::ItemTouch); - - 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; - } - - //UTIL_SetOrigin( pev, pev->origin + Vector(0,0,16) ); - - if (!m_flRespawnTime) - m_flRespawnTime = 20; -} - -//----------------------------------------------------------------------------- -// Purpose: Bring the item back -//----------------------------------------------------------------------------- -void CQuakeItem::Materialize() -{ - // Become visible and touchable - pev->effects &= ~EF_NODRAW; - SetTouch( &CQuakeItem::ItemTouch ); - - // Play respawn sound - EMIT_SOUND( ENT(pev), CHAN_WEAPON, "items/itembk2.wav", 1, ATTN_NORM ); -} - -//----------------------------------------------------------------------------- -// Purpose: Setup the item's respawn in the time set -//----------------------------------------------------------------------------- -void CQuakeItem::Respawn( float flTime ) -{ - pev->effects |= EF_NODRAW; - SetTouch( NULL ); - - // Come back in time - SetThink ( &CQuakeItem::Materialize ); - pev->nextthink = gpGlobals->time + flTime; -} - - -//----------------------------------------------------------------------------- -// Purpose: Touch function that calls the virtual touch function -//----------------------------------------------------------------------------- -void CQuakeItem::ItemTouch( CBaseEntity *pOther ) -{ - // if it's not a player, ignore - if ( !pOther->IsPlayer() ) - return; - - //Dead? - if (pOther->pev->health <= 0) - return; - - CBasePlayer *pPlayer = (CBasePlayer *)pOther; - - // Call the virtual touch function - if ( MyTouch( pPlayer ) ) - { - SUB_UseTargets( pOther, USE_TOGGLE, 0 ); - - // Respawn if it's not DM==2 - if (gpGlobals->deathmatch != 2) - { - Respawn( m_flRespawnTime ); - } - else - { - UTIL_Remove( this ); - } - } -} - -//====================================================================================== -// HEALTH ITEMS -//====================================================================================== -#define H_ROTTEN 1 -#define H_MEGA 2 - -class CItemHealth : public CQuakeItem -{ -public: - void Spawn( void ); - void Precache( void ); - BOOL MyTouch( CBasePlayer *pPlayer ); - void EXPORT MegahealthRot( void ); - - EHANDLE m_hRotTarget; - int m_iHealAmount; - int m_iHealType; -}; -LINK_ENTITY_TO_CLASS(item_health, CItemHealth); - -//-------------------------------------------- -// Spawn -void CItemHealth::Spawn( void ) -{ - Precache(); - - // Setup healing method - if (pev->spawnflags & H_ROTTEN) - { - SET_MODEL(ENT(pev), "models/w_medkits.mdl"); - pev->noise = MAKE_STRING( "items/r_item1.wav" ); - m_iHealAmount = 15; - m_iHealType = H_ROTTEN; - } - else if (pev->spawnflags & H_MEGA) - { - SET_MODEL(ENT(pev), "models/w_medkitl.mdl"); - pev->noise = MAKE_STRING( "items/r_item2.wav" ); - m_iHealAmount = 100; - m_iHealType = H_MEGA; - } - else - { - SET_MODEL(ENT(pev), "models/w_medkit.mdl"); - pev->noise = MAKE_STRING( "items/health1.wav" ); - m_iHealAmount = 25; - m_iHealType = H_ROTTEN; - } - - CQuakeItem::Spawn(); -} - -//-------------------------------------------- -// Precache -void CItemHealth::Precache() -{ - PRECACHE_MODEL("models/w_medkitl.mdl"); - PRECACHE_MODEL("models/w_medkits.mdl"); - PRECACHE_MODEL("models/w_medkit.mdl"); - PRECACHE_SOUND("items/r_item1.wav"); - PRECACHE_SOUND("items/r_item2.wav"); - PRECACHE_SOUND("items/health1.wav"); -} - -//-------------------------------------------- -// Health Touch -BOOL CItemHealth::MyTouch( CBasePlayer *pPlayer ) -{ - // Don't heal in DM==4 if they're invincible - if (gpGlobals->deathmatch == 4 && pPlayer->m_flInvincibleFinished > 0) - return FALSE; - - if (pPlayer->pev->health <= 0) - return FALSE; - - if (m_iHealType == H_MEGA) - { - if (pPlayer->pev->health >= 250) - return FALSE; - if ( !pPlayer->TakeHealth( m_iHealAmount, DMG_GENERIC | DMG_IGNORE_MAXHEALTH) ) - return FALSE; - } - else - { - // Heal the Player - if ( !pPlayer->TakeHealth( m_iHealAmount, DMG_GENERIC ) ) - return FALSE; - } - - ClientPrint( pPlayer->pev, HUD_PRINTNOTIFY, "#Get_Health", UTIL_dtos1(m_iHealAmount) ); - EMIT_SOUND( ENT(pev), CHAN_ITEM, STRING(pev->noise), 1, ATTN_NORM ); - - // Setup for respawn - if (m_iHealType == H_MEGA) - { - // Go invisible and fire targets - pev->effects |= EF_NODRAW; - SetTouch( NULL ); - SUB_UseTargets( pPlayer, USE_TOGGLE, 0 ); - - pPlayer->m_iQuakeItems |= IT_SUPERHEALTH; - if (gpGlobals->deathmatch != 4) - { - SetThink( &CItemHealth::MegahealthRot ); - pev->nextthink = gpGlobals->time + 5; - } - m_hRotTarget = pPlayer; - - // Return FALSE, because we want to handle our respawn ourselves - return FALSE; - } - - // Respawn as normal - return TRUE; -} - -//-------------------------------------------- -// Megahealth Rot function. Reduce player's health until it's below 100. Then respawn. -void CItemHealth::MegahealthRot( void ) -{ - if (m_hRotTarget) - { - CBasePlayer *pPlayer = ((CBasePlayer *)((CBaseEntity *)m_hRotTarget)); - - if (pPlayer->pev->health > pPlayer->pev->max_health ) - { - pPlayer->pev->health--; - pev->nextthink = gpGlobals->time + 1; - return; - } - - pPlayer->m_iQuakeItems &= ~IT_SUPERHEALTH; - } - - // Respawn if it's not DM==2 - if (gpGlobals->deathmatch != 2) - { - SetThink ( &CItemHealth::Materialize ); - pev->nextthink = gpGlobals->time + 20; - } - else - { - UTIL_Remove( this ); - } -} - -//====================================================================================== -// ARMOR ITEMS -//====================================================================================== -class CItemArmor : public CQuakeItem -{ -public: - BOOL MyTouch( CBasePlayer *pPlayer ); - - float m_flArmorValue; - float m_flArmorType; - int m_iArmorBit; -}; - -// Armor Touch -BOOL CItemArmor::MyTouch( CBasePlayer *pPlayer ) -{ - if (pPlayer->pev->health <= 0) - return FALSE; - - // Don't pickup in DM==4 if they're invincible - if (gpGlobals->deathmatch == 4 && pPlayer->m_flInvincibleFinished > 0) - return FALSE; - - // Don't pickup if this armor isn't as good as the stuff we've got - if ( (pPlayer->pev->armortype * pPlayer->pev->armorvalue) >= (m_flArmorType * m_flArmorValue) ) - return FALSE; - - pPlayer->pev->armortype = m_flArmorType; - pPlayer->pev->armorvalue = m_flArmorValue; - pPlayer->m_iQuakeItems &= ~(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3); - pPlayer->m_iQuakeItems |= m_iArmorBit; - - EMIT_SOUND( ENT( pPlayer->pev ), CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM ); - - return TRUE; -} - -//=============== -// Green Armor -class CItemArmorGreen : public CItemArmor -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(item_armor1, CItemArmorGreen); - -// Spawn -void CItemArmorGreen::Spawn( void ) -{ - Precache(); - SET_MODEL(ENT(pev), "models/armour_g.mdl"); - CItemArmor::Spawn(); - - m_flArmorValue = 100; - m_flArmorType = 0.3; - m_iArmorBit = IT_ARMOR1; -} - -// Precache -void CItemArmorGreen::Precache( void ) -{ - PRECACHE_MODEL( "models/armour_g.mdl" ); - PRECACHE_SOUND( "items/armor1.wav" ); -} - -//=============== -// Yellow Armor -class CItemArmorYellow : public CItemArmor -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(item_armor2, CItemArmorYellow); - -// Spawn -void CItemArmorYellow::Spawn( void ) -{ - Precache(); - SET_MODEL(ENT(pev), "models/armour_y.mdl"); - CItemArmor::Spawn(); - - m_flArmorValue = 150; - m_flArmorType = 0.6; - m_iArmorBit = IT_ARMOR2; -} - -// Precache -void CItemArmorYellow::Precache( void ) -{ - PRECACHE_MODEL( "models/armour_y.mdl" ); - PRECACHE_SOUND( "items/armor1.wav" ); -} - -//=============== -// Red Armor -class CItemArmorRed : public CItemArmor -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(item_armor3, CItemArmorRed); -LINK_ENTITY_TO_CLASS(item_armorInv, CItemArmorRed); - -// Spawn -void CItemArmorRed::Spawn( void ) -{ - Precache(); - SET_MODEL(ENT(pev), "models/armour_r.mdl"); - CItemArmor::Spawn(); - - m_flArmorValue = 200; - m_flArmorType = 0.8; - m_iArmorBit = IT_ARMOR3; -} - -// Precache -void CItemArmorRed::Precache( void ) -{ - PRECACHE_MODEL( "models/armour_r.mdl" ); - PRECACHE_SOUND( "items/armor1.wav" ); -} - -//====================================================================================== -// WEAPON ITEMS -//====================================================================================== -void CBasePlayer::CheckAmmo() -{ - if (m_iAmmoShells > 100) - m_iAmmoShells = 100; - if (m_iAmmoNails > 200) - m_iAmmoNails = 200; - if (m_iAmmoRockets > 100) - m_iAmmoRockets = 100; - if (m_iAmmoCells > 100) - m_iAmmoCells = 100; -} - -int RankForWeapon(int iWeapon) -{ - switch (iWeapon) - { - case IT_LIGHTNING: - return 1; break; - case IT_ROCKET_LAUNCHER: - return 2; break; - case IT_SUPER_NAILGUN: - return 3; break; - case IT_GRENADE_LAUNCHER: - return 4; break; - case IT_SUPER_SHOTGUN: - return 5; break; - case IT_NAILGUN: - return 6; break; - - default: - break; - } - - return 7; -} - -int WeaponCode(int iWeapon) -{ - switch (iWeapon) - { - case IT_SUPER_SHOTGUN: - return 3; break; - case IT_NAILGUN: - return 4; break; - case IT_SUPER_NAILGUN: - return 5; break; - case IT_GRENADE_LAUNCHER: - return 6; break; - case IT_ROCKET_LAUNCHER: - return 7; break; - case IT_LIGHTNING: - return 8; break; - - default: - break; - } - - return 1; -} - -int GetWeaponValue ( int iWeapon ) -{ - int iWepValue; - - switch ( iWeapon ) - { - case IT_AXE: iWepValue = 1; break; - case IT_SHOTGUN: iWepValue = 2; break; - case IT_SUPER_SHOTGUN: iWepValue = 3; break; - case IT_NAILGUN: iWepValue = 4; break; - case IT_SUPER_NAILGUN: iWepValue = 5; break; - case IT_GRENADE_LAUNCHER: iWepValue = 6; break; - case IT_ROCKET_LAUNCHER: iWepValue = 7; break; - case IT_LIGHTNING: iWepValue = 8; break; - } - - return iWepValue; -} -// Change weapon only if the new one's better -void CBasePlayer::Deathmatch_Weapon(int iOldWeapon, int iNewWeapon) -{ - int iPickedWep = GetWeaponValue( iNewWeapon ); - int iOldWep = GetWeaponValue( m_iQuakeWeapon ); - - switch ( m_iAutoWepSwitch ) - { - case 0: return; break; - case 1: - W_ChangeWeapon( iPickedWep ); break; - case 2: - - if ( iPickedWep == 8 && !FBitSet(pev->flags , FL_INWATER) || iPickedWep > iOldWep ) - W_ChangeWeapon( iPickedWep ); - break; - } - - -} - -//----------------------------------------------- -// Base Quake Weapon object -class CItemWeapon : public CQuakeItem -{ -public: - BOOL MyTouch( CBasePlayer *pPlayer ); - - int m_iWeapon; -}; - -BOOL CItemWeapon::MyTouch( CBasePlayer *pPlayer ) -{ - BOOL bLeaveWeapon = FALSE; - - if (gpGlobals->deathmatch == 2 || gpGlobals->deathmatch == 3 || gpGlobals->deathmatch == 5 || CVAR_GET_FLOAT("mp_weaponstay") > 0 ) - bLeaveWeapon = TRUE; - - // Leave the weapon if the player's already got it - if ( bLeaveWeapon && (pPlayer->m_iQuakeItems & m_iWeapon) ) - return FALSE; - - if ( pPlayer->pev->health <= 0) - return FALSE; - - // Give the player some ammo - switch (m_iWeapon) - { - case IT_NAILGUN: - pPlayer->m_iAmmoNails += 30; - break; - case IT_SUPER_NAILGUN: - pPlayer->m_iAmmoNails += 30; - break; - case IT_SUPER_SHOTGUN: - pPlayer->m_iAmmoShells += 5; - break; - case IT_ROCKET_LAUNCHER: - pPlayer->m_iAmmoRockets += 5; - break; - case IT_GRENADE_LAUNCHER: - pPlayer->m_iAmmoRockets += 5; - break; - case IT_LIGHTNING: - pPlayer->m_iAmmoCells += 15; - break; - default: - break; - } - pPlayer->CheckAmmo(); - - EMIT_SOUND( ENT(pev), CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM ); - - // Change to new weapon? - int iOldItems = pPlayer->m_iQuakeWeapon; - pPlayer->m_iQuakeItems |= m_iWeapon; - - pPlayer->Deathmatch_Weapon(iOldItems, m_iWeapon); - - - // Update HUD - pPlayer->W_SetCurrentAmmo(); - pPlayer->m_iClientQuakeWeapon = -1; - pPlayer->m_fWeapon = FALSE; - pPlayer->m_fKnownItem = FALSE; - pPlayer->UpdateClientData(); - - if (bLeaveWeapon) - return FALSE; - - // Respawn - m_flRespawnTime = 30; - - return TRUE; -} - -//=============== -// Super Shotgun -class CItemWeaponSuperShotgun : public CItemWeapon -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(weapon_supershotgun, CItemWeaponSuperShotgun); - -// Spawn -void CItemWeaponSuperShotgun::Spawn( void ) -{ - if ( gpGlobals->deathmatch > 3) - { - UTIL_Remove(this); - return; - } - - Precache(); - SET_MODEL(ENT(pev), "models/g_shot2.mdl"); - CItemWeapon::Spawn(); - - m_iWeapon = IT_SUPER_SHOTGUN; - pev->netname = MAKE_STRING("Double-barrelled Shotgun"); -} - -// Precache -void CItemWeaponSuperShotgun::Precache( void ) -{ - PRECACHE_MODEL( "models/g_shot2.mdl" ); -} - -//=============== -// Nailgun -class CItemWeaponNailgun : public CItemWeapon -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(weapon_nailgun, CItemWeaponNailgun); - -// Spawn -void CItemWeaponNailgun::Spawn( void ) -{ - if ( gpGlobals->deathmatch > 3) - { - UTIL_Remove(this); - return; - } - - Precache(); - SET_MODEL(ENT(pev), "models/g_nail.mdl"); - CItemWeapon::Spawn(); - - m_iWeapon = IT_NAILGUN; - pev->netname = MAKE_STRING("Nailgun"); -} - -// Precache -void CItemWeaponNailgun::Precache( void ) -{ - PRECACHE_MODEL( "models/g_nail.mdl" ); -} - -//=============== -// Super Nailgun -class CItemWeaponSuperNailgun : public CItemWeapon -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(weapon_supernailgun, CItemWeaponSuperNailgun); - -// Spawn -void CItemWeaponSuperNailgun::Spawn( void ) -{ - if ( gpGlobals->deathmatch > 3) - { - UTIL_Remove(this); - return; - } - - Precache(); - SET_MODEL(ENT(pev), "models/g_nail2.mdl"); - CItemWeapon::Spawn(); - - m_iWeapon = IT_SUPER_NAILGUN; - pev->netname = MAKE_STRING("Super Nailgun"); -} - -// Precache -void CItemWeaponSuperNailgun::Precache( void ) -{ - PRECACHE_MODEL( "models/g_nail2.mdl" ); -} - -//=============== -// Grenade Launcher -class CItemWeaponGrenadeLauncher : public CItemWeapon -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(weapon_grenadelauncher, CItemWeaponGrenadeLauncher); - -// Spawn -void CItemWeaponGrenadeLauncher::Spawn( void ) -{ - if ( gpGlobals->deathmatch > 3) - { - UTIL_Remove(this); - return; - } - - Precache(); - SET_MODEL(ENT(pev), "models/g_rock.mdl"); - CItemWeapon::Spawn(); - - m_iWeapon = IT_GRENADE_LAUNCHER; - pev->netname = MAKE_STRING("Grenade Launcher"); -} - -// Precache -void CItemWeaponGrenadeLauncher::Precache( void ) -{ - PRECACHE_MODEL( "models/g_rock.mdl" ); -} - -//=============== -// Rocket Launcher -class CItemWeaponRocketLauncher : public CItemWeapon -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(weapon_rocketlauncher, CItemWeaponRocketLauncher); - -// Spawn -void CItemWeaponRocketLauncher::Spawn( void ) -{ - if ( gpGlobals->deathmatch > 3) - { - UTIL_Remove(this); - return; - } - - Precache(); - SET_MODEL(ENT(pev), "models/g_rock2.mdl"); - CItemWeapon::Spawn(); - - m_iWeapon = IT_ROCKET_LAUNCHER; - pev->netname = MAKE_STRING("Rocket Launcher"); -} - -// Precache -void CItemWeaponRocketLauncher::Precache( void ) -{ - PRECACHE_MODEL( "models/g_rock2.mdl" ); -} - -//=============== -// Lightning Gun -class CItemWeaponLightning : public CItemWeapon -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(weapon_lightning, CItemWeaponLightning); - -// Spawn -void CItemWeaponLightning::Spawn( void ) -{ - if ( gpGlobals->deathmatch > 3) - { - UTIL_Remove(this); - return; - } - - Precache(); - SET_MODEL(ENT(pev), "models/g_light.mdl"); - CItemWeapon::Spawn(); - - m_iWeapon = IT_LIGHTNING; - pev->netname = MAKE_STRING("Thunderbolt"); -} - -// Precache -void CItemWeaponLightning::Precache( void ) -{ - PRECACHE_MODEL( "models/g_light.mdl" ); -} - -//====================================================================================== -// AMMO ITEMS -//====================================================================================== -#define BIG_AMMOBOX 1 - -class CItemAmmo : public CQuakeItem -{ -public: - void Spawn( void ); - void Precache( void ); - BOOL MyTouch( CBasePlayer *pPlayer ); - - int m_isSmallBox; - int m_isLargeBox; - int ammo_shells; - int ammo_nails; - int ammo_rockets; - int ammo_cells; -}; - -// Spawn -void CItemAmmo::Spawn( void ) -{ - Precache(); - - // Set the box size - if (pev->spawnflags & BIG_AMMOBOX) - { - SET_MODEL( ENT(pev), STRING(m_isLargeBox) ); - ammo_shells *= 2; - ammo_nails *= 2; - ammo_rockets *= 2; - ammo_cells *= 2; - } - else - { - SET_MODEL( ENT(pev), STRING(m_isSmallBox) ); - } - - // Halve respawn times in DM==3 and DM==5 - if (gpGlobals->deathmatch == 3 || gpGlobals->deathmatch == 5) - m_flRespawnTime = 15; - else - m_flRespawnTime = 30; - - CQuakeItem::Spawn(); -} - -// Precache -void CItemAmmo::Precache( void ) -{ - if (pev->spawnflags & BIG_AMMOBOX) - PRECACHE_MODEL( (char*)STRING(m_isLargeBox) ); - else - PRECACHE_MODEL( (char*)STRING(m_isSmallBox) ); -} - -BOOL CItemAmmo::MyTouch( CBasePlayer *pPlayer ) -{ - if (pPlayer->pev->health <= 0) - return FALSE; - - // Find the player's best weapon - int iBestWeapon = pPlayer->W_BestWeapon(); - - // Return if the player can't carry - if (ammo_shells && pPlayer->m_iAmmoShells >= 100) - return FALSE; - if (ammo_nails && pPlayer->m_iAmmoNails >= 200) - return FALSE; - if (ammo_rockets && pPlayer->m_iAmmoRockets >= 100) - return FALSE; - if (ammo_cells && pPlayer->m_iAmmoCells >= 100) - return FALSE; - - pPlayer->m_iAmmoShells += ammo_shells; - pPlayer->m_iAmmoNails += ammo_nails; - pPlayer->m_iAmmoRockets += ammo_rockets; - pPlayer->m_iAmmoCells += ammo_cells; - pPlayer->CheckAmmo(); - - EMIT_SOUND( ENT(pev), CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM ); - - // Change to a better weapon if possible - if ( pPlayer->m_iQuakeWeapon == iBestWeapon ) - { - pPlayer->m_iQuakeWeapon = pPlayer->W_BestWeapon(); - } - - pPlayer->W_SetCurrentAmmo(); - return TRUE; -} - -//=============== -// Shells -class CItemAmmoShells : public CItemAmmo -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS(item_shells, CItemAmmoShells); - -// Spawn -void CItemAmmoShells::Spawn( void ) -{ - if ( gpGlobals->deathmatch == 4) - { - UTIL_Remove(this); - return; - } - - m_isSmallBox = MAKE_STRING("models/w_shotbox.mdl"); - m_isLargeBox = MAKE_STRING("models/w_shotbox_big.mdl"); - pev->netname = MAKE_STRING("shells"); - ammo_shells = 20; - - CItemAmmo::Spawn(); -} - -//=============== -// Spikes -class CItemAmmoSpikes : public CItemAmmo -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS(item_spikes, CItemAmmoSpikes); - -// Spawn -void CItemAmmoSpikes::Spawn( void ) -{ - if ( gpGlobals->deathmatch == 4) - { - UTIL_Remove(this); - return; - } - - m_isSmallBox = MAKE_STRING("models/b_nail0.mdl"); - m_isLargeBox = MAKE_STRING("models/b_nail1.mdl"); - pev->netname = MAKE_STRING("nails"); - ammo_nails = 25; - - CItemAmmo::Spawn(); -} - -//=============== -// Rockets -class CItemAmmoRockets : public CItemAmmo -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS(item_rockets, CItemAmmoRockets); - -// Spawn -void CItemAmmoRockets::Spawn( void ) -{ - if ( gpGlobals->deathmatch == 4) - { - UTIL_Remove(this); - return; - } - - m_isSmallBox = MAKE_STRING("models/w_rpgammo.mdl"); - m_isLargeBox = MAKE_STRING("models/w_rpgammo_big.mdl"); - pev->netname = MAKE_STRING("rockets"); - ammo_rockets = 5; - - CItemAmmo::Spawn(); -} - -//=============== -// Cells -class CItemAmmoCells : public CItemAmmo -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS(item_cells, CItemAmmoCells); - -// Spawn -void CItemAmmoCells::Spawn( void ) -{ - if ( gpGlobals->deathmatch == 4) - { - UTIL_Remove(this); - return; - } - - m_isSmallBox = MAKE_STRING("models/w_battery.mdl"); - m_isLargeBox = MAKE_STRING("models/w_battery.mdl"); - pev->netname = MAKE_STRING("cells"); - ammo_cells = 6; - - CItemAmmo::Spawn(); -} - -//=============== -// Weapon ammo -// Another method of placing ammo. Quake still uses it in some maps. -#define AW_SHOTGUN 1 -#define AW_ROCKET 2 -#define AW_SPIKES 4 -#define AW_BIG 8 - -class CItemAmmoWeapon : public CItemAmmo -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS(item_weapon, CItemAmmoWeapon); - -// Spawn -void CItemAmmoWeapon::Spawn( void ) -{ - if ( gpGlobals->deathmatch == 4) - { - UTIL_Remove(this); - return; - } - - // Shells - if (pev->spawnflags & AW_SHOTGUN) - { - m_isSmallBox = MAKE_STRING("models/w_shotbox.mdl"); - m_isLargeBox = MAKE_STRING("models/w_shotbox_big.mdl"); - pev->netname = MAKE_STRING("shells"); - ammo_shells = 20; - } - - // Nails - if (pev->spawnflags & AW_SPIKES) - { - m_isSmallBox = MAKE_STRING("models/b_nail0.mdl"); - m_isLargeBox = MAKE_STRING("models/b_nail1.mdl"); - pev->netname = MAKE_STRING("nails"); - ammo_nails = 25; - } - - // Rockets - if (pev->spawnflags & AW_ROCKET) - { - m_isSmallBox = MAKE_STRING("models/w_rpgammo.mdl"); - m_isLargeBox = MAKE_STRING("models/w_rpgammo_big.mdl"); - pev->netname = MAKE_STRING("rockets"); - ammo_rockets = 5; - } - - // Big? - if (pev->spawnflags & AW_BIG) - pev->spawnflags = BIG_AMMOBOX; - else - pev->spawnflags = 0; - - CItemAmmo::Spawn(); -} - -//=============================================================================== -// POWERUPS -//=============================================================================== -class CItemPowerup : public CQuakeItem -{ -public: - BOOL MyTouch( CBasePlayer *pPlayer ); - - int m_iPowerupBit; - float invincible_finished; - float radsuit_finished; - float invisible_finished; - float super_damage_finished; -}; - -// Powerup Touch -BOOL CItemPowerup::MyTouch( CBasePlayer *pPlayer ) -{ - if (pPlayer->pev->health <= 0) - return FALSE; - - EMIT_SOUND( ENT(pev), CHAN_ITEM, STRING(pev->noise), 1, ATTN_NORM ); - - pPlayer->m_iQuakeItems |= m_iPowerupBit; - - int iPowerUp = 0; - - // Invincibility - if (invincible_finished) - { - // Make them glow red - - if ( pPlayer->m_iQuakeItems & IT_QUAD ) - { - pPlayer->pev->renderfx = kRenderFxGlowShell; - pPlayer->pev->rendercolor = Vector( 255, 125, 255 ); // RGB - pPlayer->pev->renderamt = 100; // Shell size - - iPowerUp = 3; - } - else - { - pPlayer->pev->renderfx = kRenderFxGlowShell; - pPlayer->pev->rendercolor = Vector( 255, 128, 0 ); // RGB - pPlayer->pev->renderamt = 100; // Shell size - - iPowerUp = 2; - } - - if ( pPlayer->m_iQuakeItems & IT_INVISIBILITY ) - { - pPlayer->pev->rendermode = kRenderTransColor; - pPlayer->pev->renderamt = 1; - } - pPlayer->m_flInvincibleFinished = gpGlobals->time + invincible_finished; - - } - - // Quad Damage - if (super_damage_finished) - { - // Make them glow blue - - if ( pPlayer->m_iQuakeItems & IT_INVULNERABILITY ) - { - pPlayer->pev->renderfx = kRenderFxGlowShell; - pPlayer->pev->rendercolor = Vector( 255, 125, 255 ); // RGB - pPlayer->pev->renderamt = 100; // Shell size - - iPowerUp = 3; - } - else - { - pPlayer->pev->renderfx = kRenderFxGlowShell; - pPlayer->pev->rendercolor = Vector( 128, 128, 255 ); // RGB - pPlayer->pev->renderamt = 100; // Shell size - - iPowerUp = 1; - } - - if ( pPlayer->m_iQuakeItems & IT_INVISIBILITY ) - { - pPlayer->pev->rendermode = kRenderTransColor; - pPlayer->pev->renderamt = 1; - } - - - pPlayer->m_flSuperDamageFinished = gpGlobals->time + super_damage_finished; - - // Remove armor and cells if DM==4 - if (gpGlobals->deathmatch == 4) - { - pPlayer->pev->armortype = 0; - pPlayer->pev->armorvalue = 0; - pPlayer->m_iAmmoCells = 0; - } - } - - // Radiation suit - if (radsuit_finished) - pPlayer->m_flRadsuitFinished = gpGlobals->time + radsuit_finished; - - // Invisibility - if (invisible_finished) - { - pPlayer->m_flInvisibleFinished = gpGlobals->time + invisible_finished; - - pPlayer->pev->renderfx = kRenderFxGlowShell; - pPlayer->pev->rendercolor = Vector( 128, 128, 128 ); // RGB - pPlayer->pev->renderamt = 5; // Shell size - - } - - // tell director about it - MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR ); - WRITE_BYTE ( 9 ); // command length in bytes - WRITE_BYTE ( DRC_CMD_EVENT ); // powerup pickup - WRITE_SHORT( ENTINDEX(pPlayer->edict()) ); // player is primary target - WRITE_SHORT( ENTINDEX(this->edict()) ); // powerup as second target - WRITE_LONG( 9 ); // highst prio in game - MESSAGE_END(); - - pPlayer->W_SetCurrentAmmo(); - - PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, - pPlayer->edict(), g_usPowerUp, 0, (float *)&g_vecZero, (float *)&g_vecZero, - (float)iPowerUp, 0.0, pPlayer->entindex(), pPlayer->pev->team, 0, 0 ); - - return TRUE; -} - - -//=============== -// Pentagram -class CItemPowerupInvincible : public CItemPowerup -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(item_artifact_invulnerability, CItemPowerupInvincible); - -// Spawn -void CItemPowerupInvincible::Spawn( void ) -{ - Precache(); - CQuakeItem::Spawn(); - - m_flRespawnTime = 300; - invincible_finished = 30; - - SET_MODEL(ENT(pev), "models/pow_invuln.mdl"); - pev->netname = MAKE_STRING("Pentagram of Protection"); - pev->noise = MAKE_STRING("items/protect.wav"); - m_iPowerupBit = IT_INVULNERABILITY; - - // Make it glow red - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 255, 128, 0 ); // RGB - pev->renderamt = 100; // Shellsize -} - -// Precache -void CItemPowerupInvincible::Precache( void ) -{ - PRECACHE_MODEL("models/pow_invuln.mdl"); - PRECACHE_SOUND("items/protect.wav"); - PRECACHE_SOUND("items/protect2.wav"); - PRECACHE_SOUND("items/protect3.wav"); -} - -//=============== -// Radiation Suit -class CItemPowerupRadsuit : public CItemPowerup -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(item_artifact_envirosuit, CItemPowerupRadsuit); - -// Spawn -void CItemPowerupRadsuit::Spawn( void ) -{ - Precache(); - CQuakeItem::Spawn(); - - m_flRespawnTime = 60; - radsuit_finished = 30; - - SET_MODEL(ENT(pev), "models/suit.mdl"); - pev->netname = MAKE_STRING("Biosuit"); - pev->noise = MAKE_STRING("items/suit.wav"); - m_iPowerupBit = IT_SUIT; -} - -// Precache -void CItemPowerupRadsuit::Precache( void ) -{ - PRECACHE_MODEL("models/suit.mdl"); - PRECACHE_SOUND("items/suit.wav"); - PRECACHE_SOUND("items/suit2.wav"); -} - -//=============== -// Ring of Invisibility -class CItemPowerupInvisibility : public CItemPowerup -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(item_artifact_invisibility, CItemPowerupInvisibility); - -// Spawn -void CItemPowerupInvisibility::Spawn( void ) -{ - Precache(); - CQuakeItem::Spawn(); - - m_flRespawnTime = 300; - invisible_finished = 30; - - SET_MODEL(ENT(pev), "models/pow_invis.mdl"); - pev->netname = MAKE_STRING("Ring of Shadows"); - pev->noise = MAKE_STRING("items/inv1.wav"); - m_iPowerupBit = IT_INVISIBILITY; - - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 128, 128, 128 ); // RGB - pev->renderamt = 25; // Shell size - - pev->rendermode = kRenderTransColor; - pev->renderamt = 30; -} - -// Precache -void CItemPowerupInvisibility::Precache( void ) -{ - PRECACHE_MODEL("models/pow_invis.mdl"); - PRECACHE_SOUND("items/inv1.wav"); - PRECACHE_SOUND("items/inv2.wav"); - PRECACHE_SOUND("items/inv3.wav"); -} - -//=============== -// Quad Damage -class CItemPowerupQuad : public CItemPowerup -{ -public: - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS(item_artifact_super_damage, CItemPowerupQuad); - -// Spawn -void CItemPowerupQuad::Spawn( void ) -{ - Precache(); - CQuakeItem::Spawn(); - - m_flRespawnTime = 60; - super_damage_finished = 30; - - SET_MODEL(ENT(pev), "models/pow_quad.mdl"); - pev->netname = MAKE_STRING("Quad Damage"); - pev->noise = MAKE_STRING("items/damage.wav"); - m_iPowerupBit = IT_QUAD; - - // Make it glow blue - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor = Vector( 128, 128, 255 ); // RGB - pev->renderamt = 100; // Shell size -} - -// Precache -void CItemPowerupQuad::Precache( void ) -{ - PRECACHE_MODEL("models/pow_quad.mdl"); - PRECACHE_SOUND("items/damage.wav"); - PRECACHE_SOUND("items/damage2.wav"); - PRECACHE_SOUND("items/damage3.wav"); -} - -//=============================================================================== -// PLAYER BACKPACKS -//=============================================================================== -class CItemBackpack : public CQuakeItem -{ -public: - void Spawn( void ); -// void SetBox ( void ); - virtual void SetObjectCollisionBox ( void ); - - BOOL MyTouch( CBasePlayer *pPlayer ); - - int m_iItems; - int ammo_shells; - int ammo_nails; - int ammo_rockets; - int ammo_cells; -}; -LINK_ENTITY_TO_CLASS(item_backpack, CItemBackpack); - -void CItemBackpack :: SetObjectCollisionBox( void ) -{ - pev->absmin = pev->origin + Vector(-32, -32, 0); - pev->absmax = pev->origin + Vector(32, 32, 56); -} - -// Spawn -void CItemBackpack::Spawn() -{ - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - UTIL_SetOrigin( pev, pev->origin ); - SET_MODEL(ENT(pev), "models/backpack.mdl"); - - SetTouch(&CItemBackpack::ItemTouch); -} - -// Drop a backpack containing this player's ammo/weapons -void CBasePlayer::DropBackpack() -{ - // Any ammo to drop? - if ( !(m_iAmmoShells + m_iAmmoNails + m_iAmmoRockets + m_iAmmoCells) ) - return; - - // Create the pack - CItemBackpack *pPack = (CItemBackpack *)CBaseEntity::Create( "item_backpack", pev->origin - Vector(0, 0, 24), g_vecZero, edict() ); - pPack->pev->velocity = Vector( RANDOM_FLOAT(-100,100), RANDOM_FLOAT(-100,100), 300 ); - pPack->Spawn(); - - // Put the player's weapon in the pack - pPack->m_iItems = m_iQuakeWeapon; - switch (pPack->m_iItems) - { - case IT_AXE: - pPack->pev->netname = MAKE_STRING("Crowbar"); break; - case IT_SHOTGUN: - pPack->pev->netname = MAKE_STRING("Shotgun"); break; - case IT_SUPER_SHOTGUN: - pPack->pev->netname = MAKE_STRING("Double-barrelled Shotgun"); break; - case IT_NAILGUN: - pPack->pev->netname = MAKE_STRING("Nailgun"); break; - case IT_SUPER_NAILGUN: - pPack->pev->netname = MAKE_STRING("Super Nailgun"); break; - case IT_GRENADE_LAUNCHER: - pPack->pev->netname = MAKE_STRING("Grenade Launcher"); break; - case IT_ROCKET_LAUNCHER: - pPack->pev->netname = MAKE_STRING("Rocket Launcher"); break; - case IT_LIGHTNING: - pPack->pev->netname = MAKE_STRING("Thunderbolt"); break; - default: - pPack->pev->netname = MAKE_STRING("Invalid weapon."); break; - } - - // Put the ammo in - pPack->ammo_shells = m_iAmmoShells; - pPack->ammo_nails = m_iAmmoNails; - pPack->ammo_rockets = m_iAmmoRockets; - pPack->ammo_cells = m_iAmmoCells; - - //Remove them from the player - m_iAmmoShells = m_iAmmoNails = m_iAmmoRockets = m_iAmmoCells = 0; - - // Remove after 2 mins - pPack->pev->nextthink = gpGlobals->time + 120; - pPack->SetThink( &CItemBackpack::SUB_Remove ); - - // Remove all weapons - m_iQuakeItems = 0; - m_iQuakeWeapon = 0; -} - -// Pickup backpack -BOOL CItemBackpack::MyTouch( CBasePlayer *pPlayer ) -{ - if (pPlayer->pev->health <= 0) - return FALSE; - if (gpGlobals->deathmatch == 4 && pPlayer->m_flInvincibleFinished > 0) - return FALSE; - - - - if (gpGlobals->deathmatch == 4) - { - pPlayer->pev->health += 10; - ClientPrint( pPlayer->pev, HUD_PRINTNOTIFY, "#Additional_Health" ); - if ((pPlayer->pev->health > 250) && (pPlayer->pev->health < 300)) - EMIT_SOUND( ENT(pPlayer->pev), CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM ); - else - EMIT_SOUND( ENT(pPlayer->pev), CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM ); - - // Become invulnerable if the player's reached 300 health - if (pPlayer->pev->health > 299) - { - if (pPlayer->m_flInvincibleFinished == 0) - { - // Give player invincibility and quad - pPlayer->m_flInvincibleFinished = gpGlobals->time + 30; - pPlayer->m_flSuperDamageFinished = gpGlobals->time + 30; - pPlayer->m_iQuakeItems |= (IT_INVULNERABILITY | IT_QUAD); - pPlayer->m_iAmmoCells = 0; - - // Make player glow red - pPlayer->pev->renderfx = kRenderFxGlowShell; - pPlayer->pev->rendercolor = Vector( 255, 128, 0 ); // RGB - pPlayer->pev->renderamt = 100; // Shell size - - EMIT_SOUND( ENT(pPlayer->pev), CHAN_VOICE, "items/sight1.wav", 1, ATTN_NORM ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Bonus_Power", STRING(pPlayer->pev->netname) ); - } - } - - UTIL_Remove( this ); - - // We've removed ourself, so don't let CQuakeItem handle respawn - return FALSE; - } - - BOOL bPrintComma = FALSE; - - // Get the weapon from the pack - if (m_iItems) - { - if ( !(pPlayer->m_iQuakeItems & m_iItems) ) - { - bPrintComma = TRUE; - - switch ( m_iItems ) - { - case IT_SUPER_SHOTGUN: - ClientPrint( pPlayer->pev, HUD_PRINTNOTIFY, "#You_Get_SS", UTIL_dtos1( ammo_shells ), UTIL_dtos2 ( ammo_nails ), UTIL_dtos3 ( ammo_rockets ), UTIL_dtos4 ( ammo_cells ) ); break; - case IT_NAILGUN: - ClientPrint( pPlayer->pev, HUD_PRINTNOTIFY, "#You_Get_NG", UTIL_dtos1( ammo_shells ), UTIL_dtos2 ( ammo_nails ), UTIL_dtos3 ( ammo_rockets ), UTIL_dtos4 ( ammo_cells ) ); break; - case IT_SUPER_NAILGUN: - ClientPrint( pPlayer->pev, HUD_PRINTNOTIFY, "#You_Get_SG", UTIL_dtos1( ammo_shells ), UTIL_dtos2 ( ammo_nails ), UTIL_dtos3 ( ammo_rockets ), UTIL_dtos4 ( ammo_cells ) ); break; - case IT_GRENADE_LAUNCHER: - ClientPrint( pPlayer->pev, HUD_PRINTNOTIFY, "#You_Get_GL", UTIL_dtos1( ammo_shells ), UTIL_dtos2 ( ammo_nails ), UTIL_dtos3 ( ammo_rockets ), UTIL_dtos4 ( ammo_cells ) ); break; - case IT_ROCKET_LAUNCHER: - ClientPrint( pPlayer->pev, HUD_PRINTNOTIFY, "#You_Get_RL", UTIL_dtos1( ammo_shells ), UTIL_dtos2 ( ammo_nails ), UTIL_dtos3 ( ammo_rockets ), UTIL_dtos4 ( ammo_cells ) ); break; - case IT_LIGHTNING: - ClientPrint( pPlayer->pev, HUD_PRINTNOTIFY, "#You_Get_LG", UTIL_dtos1( ammo_shells ), UTIL_dtos2 ( ammo_nails ), UTIL_dtos3 ( ammo_rockets ), UTIL_dtos4 ( ammo_cells ) ); break; - } - } - else - ClientPrint( pPlayer->pev, HUD_PRINTNOTIFY, "#You_Get_NoGun", UTIL_dtos1( ammo_shells ), UTIL_dtos2 ( ammo_nails ), UTIL_dtos3 ( ammo_rockets ), UTIL_dtos4 ( ammo_cells ) ); - } - - // Get ammo from pack - pPlayer->m_iAmmoShells += ammo_shells; - pPlayer->m_iAmmoNails += ammo_nails; - pPlayer->m_iAmmoRockets += ammo_rockets; - pPlayer->m_iAmmoCells += ammo_cells; - pPlayer->CheckAmmo(); - - int iNewWeapon = m_iItems; - if (!iNewWeapon) - iNewWeapon = pPlayer->m_iQuakeWeapon; - int iOldWeapon = pPlayer->m_iQuakeItems; - pPlayer->m_iQuakeItems |= m_iItems; - - // Give them at least 5 rockets in DM==3 and DM==5 - if ( (gpGlobals->deathmatch==3 || gpGlobals->deathmatch == 5) & ( (WeaponCode(iNewWeapon)==6) || (WeaponCode(iNewWeapon)==7) ) & (pPlayer->m_iAmmoRockets < 5) ) - pPlayer->m_iAmmoRockets = 5; - - EMIT_SOUND( ENT(pPlayer->pev), CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM ); - - // Switch to a better weapon - if ( WeaponCode(iNewWeapon) <= pPlayer->m_iBackpackSwitch ) - { - if (pPlayer->pev->flags & FL_INWATER) - { - if (iNewWeapon != IT_LIGHTNING) - { - pPlayer->Deathmatch_Weapon(iOldWeapon, iNewWeapon); - } - } - else - { - pPlayer->Deathmatch_Weapon(iOldWeapon, iNewWeapon); - } - } - pPlayer->W_SetCurrentAmmo(); - pPlayer->m_iClientQuakeWeapon = -1; - pPlayer->m_fWeapon = FALSE; - pPlayer->m_fKnownItem = FALSE; - pPlayer->UpdateClientData(); - - UTIL_Remove( this ); - - // We've removed ourself, so don't let CQuakeItem handle respawn - return FALSE; -} - -#if 0 - -/* -=============================================================================== -KEYS -=============================================================================== -*/ - -void() key_touch = -{ -local entity stemp; -local float best; - - if (other.classname != "player") - return; - if (other.health <= 0) - return; - if (other.items & self.items) - return; - - sprint (other, PRINT_LOW, "You got the "); - sprint (other, PRINT_LOW, self.netname); - sprint (other,PRINT_LOW, "\n"); - - sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); - stuffcmd (other, "bf\n"); - other.items = other.items | self.items; - - self.solid = SOLID_NOT; - self.model = string_null; - - activator = other; - SUB_UseTargets(); // fire all targets / killtargets -}; - - -void() key_setsounds = -{ - if (world.worldtype == 0) - { - precache_sound ("misc/medkey.wav"); - self.noise = "misc/medkey.wav"; - } - if (world.worldtype == 1) - { - precache_sound ("misc/runekey.wav"); - self.noise = "misc/runekey.wav"; - } - if (world.worldtype == 2) - { - precache_sound2 ("misc/basekey.wav"); - self.noise = "misc/basekey.wav"; - } -}; - -/*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32) -SILVER key -In order for keys to work -you MUST set your maps -worldtype to one of the -following: -0: medieval -1: metal -2: base -*/ - -void() item_key1 = -{ - if (world.worldtype == 0) - { - precache_model ("progs/w_s_key.mdl"); - setmodel (self, "progs/w_s_key.mdl"); - self.netname = "silver key"; - } - else if (world.worldtype == 1) - { - precache_model ("progs/m_s_key.mdl"); - setmodel (self, "progs/m_s_key.mdl"); - self.netname = "silver runekey"; - } - else if (world.worldtype == 2) - { - precache_model2 ("progs/b_s_key.mdl"); - setmodel (self, "progs/b_s_key.mdl"); - self.netname = "silver keycard"; - } - key_setsounds(); - self.touch = key_touch; - self.items = IT_KEY1; - setsize (self, '-16 -16 -24', '16 16 32'); - StartItem (); -}; - -/*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) -GOLD key -In order for keys to work -you MUST set your maps -worldtype to one of the -following: -0: medieval -1: metal -2: base -*/ - -void() item_key2 = -{ - if (world.worldtype == 0) - { - precache_model ("progs/w_g_key.mdl"); - setmodel (self, "progs/w_g_key.mdl"); - self.netname = "gold key"; - } - if (world.worldtype == 1) - { - precache_model ("progs/m_g_key.mdl"); - setmodel (self, "progs/m_g_key.mdl"); - self.netname = "gold runekey"; - } - if (world.worldtype == 2) - { - precache_model2 ("progs/b_g_key.mdl"); - setmodel (self, "progs/b_g_key.mdl"); - self.netname = "gold keycard"; - } - key_setsounds(); - self.touch = key_touch; - self.items = IT_KEY2; - setsize (self, '-16 -16 -24', '16 16 32'); - StartItem (); -}; - - - -/* -=============================================================================== - -END OF LEVEL RUNES - -=============================================================================== -*/ - -void() sigil_touch = -{ -local entity stemp; -local float best; - - if (other.classname != "player") - return; - if (other.health <= 0) - return; - - centerprint (other, "You got the rune!"); - - sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM); - stuffcmd (other, "bf\n"); - self.solid = SOLID_NOT; - self.model = string_null; - serverflags = serverflags | (self.spawnflags & 15); - self.classname = ""; // so rune doors won't find it - - activator = other; - SUB_UseTargets(); // fire all targets / killtargets -}; - - -/*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4 -End of level sigil, pick up to end episode and return to jrstart. -*/ - -void() item_sigil = -{ - if (!self.spawnflags) - objerror ("no spawnflags"); - - precache_sound ("misc/runekey.wav"); - self.noise = "misc/runekey.wav"; - - if (self.spawnflags & 1) - { - precache_model ("progs/end1.mdl"); - setmodel (self, "progs/end1.mdl"); - } - if (self.spawnflags & 2) - { - precache_model2 ("progs/end2.mdl"); - setmodel (self, "progs/end2.mdl"); - } - if (self.spawnflags & 4) - { - precache_model2 ("progs/end3.mdl"); - setmodel (self, "progs/end3.mdl"); - } - if (self.spawnflags & 8) - { - precache_model2 ("progs/end4.mdl"); - setmodel (self, "progs/end4.mdl"); - } - - self.touch = sigil_touch; - setsize (self, '-16 -16 -24', '16 16 32'); - StartItem (); -}; - -void() q_touch = -{ -local entity stemp; -local float best; -local string s; - - if (other.classname != "player") - return; - if (other.health <= 0) - return; - - self.mdl = self.model; - - sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); - stuffcmd (other, "bf\n"); - self.solid = SOLID_NOT; - other.items = other.items | IT_QUAD; - self.model = string_null; - if (deathmatch == 4) - { - other.armortype = 0; - other.armorvalue = 0 * 0.01; - other.ammo_cells = 0; - } - -// do the apropriate action - other.super_time = 1; - other.super_damage_finished = self.cnt; - - s=ftos(rint(other.super_damage_finished - time)); - - bprint (PRINT_LOW, other.netname); - if (deathmatch == 4) - bprint (PRINT_LOW, " recovered an OctaPower with "); - else - bprint (PRINT_LOW, " recovered a Quad with "); - bprint (PRINT_LOW, s); - bprint (PRINT_LOW, " seconds remaining!\n"); - - activator = other; - SUB_UseTargets(); // fire all targets / killtargets -}; - - -void(float timeleft) DropQuad = -{ - local entity item; - - item = spawn(); - item.origin = self.origin - '0 0 24'; - - item.velocity_z = 300; - item.velocity_x = -100 + (random() * 200); - item.velocity_y = -100 + (random() * 200); - - item.flags = FL_ITEM; - item.solid = SOLID_TRIGGER; - item.movetype = MOVETYPE_TOSS; - item.noise = "items/damage.wav"; - setmodel (item, "progs/quaddama.mdl"); - setsize (item, '-16 -16 -24', '16 16 32'); - item.cnt = time + timeleft; - item.touch = q_touch; - item.nextthink = time + timeleft; // remove it with the time left on it - item.think = SUB_Remove; -}; - - -void() r_touch; - -void() r_touch = -{ -local entity stemp; -local float best; -local string s; - - if (other.classname != "player") - return; - if (other.health <= 0) - return; - - self.mdl = self.model; - - sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM); - stuffcmd (other, "bf\n"); - self.solid = SOLID_NOT; - other.items = other.items | IT_INVISIBILITY; - self.model = string_null; - -// do the apropriate action - other.invisible_time = 1; - other.invisible_finished = self.cnt; - s=ftos(rint(other.invisible_finished - time)); - bprint (PRINT_LOW, other.netname); - bprint (PRINT_LOW, " recovered a Ring with "); - bprint (PRINT_LOW, s); - bprint (PRINT_LOW, " seconds remaining!\n"); - - - activator = other; - SUB_UseTargets(); // fire all targets / killtargets -}; - - -void(float timeleft) DropRing = -{ - local entity item; - - item = spawn(); - item.origin = self.origin - '0 0 24'; - - item.velocity_z = 300; - item.velocity_x = -100 + (random() * 200); - item.velocity_y = -100 + (random() * 200); - - item.flags = FL_ITEM; - item.solid = SOLID_TRIGGER; - item.movetype = MOVETYPE_TOSS; - item.noise = "items/inv1.wav"; - setmodel (item, "progs/invisibl.mdl"); - setsize (item, '-16 -16 -24', '16 16 32'); - item.cnt = time + timeleft; - item.touch = r_touch; - item.nextthink = time + timeleft; // remove after 30 seconds - item.think = SUB_Remove; -}; -#endif diff --git a/dmc/dlls/quake_nail.cpp b/dmc/dlls/quake_nail.cpp deleted file mode 100644 index 6ef51f4..0000000 --- a/dmc/dlls/quake_nail.cpp +++ /dev/null @@ -1,122 +0,0 @@ -//=========== (C) Copyright 1996-2002, Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Quake nail entity -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "weapons.h" -#include "decals.h" -#include "gamerules.h" - -LINK_ENTITY_TO_CLASS( quake_nail, CQuakeNail ); - -//========================================================= -CQuakeNail *CQuakeNail::CreateNail( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner ) -{ - CQuakeNail *pNail = GetClassPtr( (CQuakeNail *)NULL ); - - UTIL_SetOrigin( pNail->pev, vecOrigin ); - - pNail->pev->velocity = vecAngles * 1000; - pNail->pev->angles = UTIL_VecToAngles(vecAngles); - pNail->pev->owner = pOwner->edict(); - pNail->Spawn(); - pNail->pev->classname = MAKE_STRING("spike"); - - // don't send to clients. - pNail->pev->effects |= EF_NODRAW; - - return pNail; -} - -CQuakeNail *CQuakeNail::CreateSuperNail( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner ) -{ - CQuakeNail *pNail = CreateNail( vecOrigin, vecAngles, pOwner ); - pNail->pev->classname = MAKE_STRING("superspike"); - - // Super nails simply do more damage - pNail->pev->dmg = 18; - return pNail; -} - -//========================================================= -void CQuakeNail::Spawn( void ) -{ - Precache(); - - // Setup - pev->movetype = MOVETYPE_FLYMISSILE; - pev->solid = SOLID_BBOX; - - // Safety removal - pev->nextthink = gpGlobals->time + 6; - SetThink( &CQuakeNail::SUB_Remove ); - - // Touch - SetTouch( &CQuakeNail::NailTouch ); - - // Model - SET_MODEL( ENT(pev), "models/spike.mdl" ); - UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0)); - UTIL_SetOrigin( pev, pev->origin ); - - // Damage - pev->dmg = 9; -} - -//========================================================= -void CQuakeNail::NailTouch( CBaseEntity *pOther ) -{ - if (pOther->pev->solid == SOLID_TRIGGER) - return; - - // Remove if we've hit skybrush - if ( UTIL_PointContents(pev->origin) == CONTENT_SKY ) - { - UTIL_Remove( this ); - return; - } - - // Hit something that bleeds - if (pOther->pev->takedamage) - { - CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner); - - if ( g_pGameRules->PlayerRelationship( pOther, pOwner ) != GR_TEAMMATE ) - SpawnBlood( pev->origin, pOther->BloodColor(), pev->dmg ); - - pOther->TakeDamage( pev, pOwner->pev, pev->dmg, DMG_GENERIC ); - } - else - { - if ( pOther->pev->solid == SOLID_BSP || pOther->pev->movetype == MOVETYPE_PUSHSTEP ) - { - TraceResult tr; - tr.vecEndPos = pev->origin; - tr.pHit = pOther->edict(); - - //Arent we doing this client side? - //UTIL_GunshotDecalTrace( &tr, DECAL_GUNSHOT1 + RANDOM_LONG( 0, 4 ) ); - } - } - - UTIL_Remove( this ); -} - - - diff --git a/dmc/dlls/quake_player.cpp b/dmc/dlls/quake_player.cpp deleted file mode 100644 index 1a4d6c6..0000000 --- a/dmc/dlls/quake_player.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== quake_player.cpp ======================================================== - - Quake Classic player functionality. - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "gamerules.h" -#include "hltv.h" - -extern entvars_t *g_pevLastInflictor; -extern int gmsgStatusText; -extern int gmsgStatusValue; -extern DLL_GLOBAL Vector g_vecAttackDir; - -/************************************* - STATUS BAR -/*************************************/ - -// Initialise the player's status bar -void CBasePlayer::InitStatusBar() -{ - m_flStatusBarDisappearDelay = 0; - m_SbarString1[0] = m_SbarString0[0] = 0; -} - -void CBasePlayer::UpdateStatusBar() -{ - int newSBarState[ SBAR_END ]; - memset( newSBarState, 0, sizeof(newSBarState) ); - - // Find an ID Target - TraceResult tr; - UTIL_MakeVectors( pev->v_angle + pev->punchangle ); - Vector vecSrc = EyePosition(); - Vector vecEnd = vecSrc + (gpGlobals->v_forward * MAX_ID_RANGE); - UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, edict(), &tr); - - if (tr.flFraction != 1.0) - { - if ( !FNullEnt( tr.pHit ) ) - { - CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit ); - - if ( pEntity->Classify() == CLASS_PLAYER ) - { - newSBarState[ SBAR_ID_TARGETNAME ] = ENTINDEX( pEntity->edict() ); - newSBarState[ SBAR_ID_TARGETTEAM ] = FALSE; - - m_flStatusBarDisappearDelay = gpGlobals->time + 1.0; - } - } - else if ( m_flStatusBarDisappearDelay > gpGlobals->time ) - { - // hold the values for a short amount of time after viewing the object - newSBarState[ SBAR_ID_TARGETNAME ] = m_izSBarState[ SBAR_ID_TARGETNAME ]; - newSBarState[ SBAR_ID_TARGETHEALTH ] = m_izSBarState[ SBAR_ID_TARGETHEALTH ]; - newSBarState[ SBAR_ID_TARGETARMOR ] = m_izSBarState[ SBAR_ID_TARGETARMOR ]; - newSBarState[ SBAR_ID_TARGETTEAM ] = m_izSBarState[ SBAR_ID_TARGETTEAM ]; - } - } - - // Check values and send if they don't match - for (int i = 1; i < SBAR_END; i++) - { - if ( newSBarState[i] != m_izSBarState[i] ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgStatusValue, NULL, pev ); - WRITE_BYTE( i ); - WRITE_SHORT( newSBarState[i] ); - MESSAGE_END(); - - m_izSBarState[i] = newSBarState[i]; - } - } -} - - -//----------------------------------------------------------------------------- -// Purpose: Player has taken some damage. This is now using the Quake functionality. -//----------------------------------------------------------------------------- -int CBasePlayer::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) -{ - if ( (pev->takedamage == DAMAGE_NO) || (IsAlive() == FALSE) ) - return 0; - - - //We are wearing the suit and we want to be hurt by lava or slime - if ( m_iQuakeItems & IT_SUIT ) - { - if ( bitsDamageType & DMG_BURN || bitsDamageType & DMG_ACID ) - return 0; - } - - CBaseEntity *pAttacker = CBaseEntity::Instance(pevAttacker); - - // keep track of amount of damage last sustained - m_lastDamageAmount = flDamage; - - // check for quad damage powerup on the attacker - if (pAttacker->IsPlayer()) - { - if ( ((CBasePlayer*)pAttacker)->m_flSuperDamageFinished > gpGlobals->time ) - { - if (gpGlobals->deathmatch == 4) - flDamage *= 8; - else - flDamage *= 4; - } - } - - // team play damage avoidance - if ( g_pGameRules->PlayerRelationship( this, pAttacker ) == GR_TEAMMATE ) - { - // Teamplay 3 you can still hurt yourself - if ( CVAR_GET_FLOAT( "mp_teamplay" ) == 3 && pAttacker != this ) - return 0; - // Teamplay 1 can't hurt any teammates, including yourself - if ( CVAR_GET_FLOAT( "mp_teamplay" ) == 1 ) - return 0; - // Teamplay 2 you can still hurt teammates - } - - - // save damage based on the target's armor level - float flSave = ceil(pev->armortype * flDamage); - if (flSave >= pev->armorvalue) - { - flSave = pev->armorvalue; - pev->armortype = 0; // lost all armor - m_iQuakeItems &= ~(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3); - } - pev->armorvalue -= flSave; - float flTake = ceil(flDamage - flSave); - - // add to the damage total for clients, which will be sent as a single message at the end of the frame - pev->dmg_take = pev->dmg_take + flTake; - pev->dmg_inflictor = ENT(pevInflictor); - - Vector vecTemp; - - if ( pevAttacker == pevInflictor ) - { - vecTemp = pevAttacker->origin - ( VecBModelOrigin(pev) ); - } - else - // an actual missile was involved. - { - vecTemp = pevInflictor->origin - ( VecBModelOrigin(pev) ); - } - - // this global is still used for glass and other non-monster killables, along with decals. - g_vecAttackDir = vecTemp.Normalize(); - - - // figure momentum add - if ( (pevInflictor) && (pev->movetype == MOVETYPE_WALK) && !( FBitSet (bitsDamageType, DMG_BURN) ) && !( FBitSet (bitsDamageType, DMG_ACID) ) ) - { - - - Vector vecPush = (pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5).Normalize(); - // Set kickback for smaller weapons - // Read: only if it's not yourself doing the damage - if ( (flDamage < 60) && pAttacker->IsPlayer() && (pAttacker != this) ) - pev->velocity = pev->velocity + vecPush * flDamage * 11; - else - { - // Otherwise, these rules apply to rockets and grenades - // for blast velocity - if ( pAttacker == this ) - { - if ( m_iQuakeWeapon != IT_LIGHTNING ) - pev->velocity = pev->velocity + vecPush * flDamage * 8; - } - else - pev->velocity = pev->velocity + vecPush * flDamage * 8; - } - - // Rocket Jump modifiers - int iRocketJumpModifier = (int)CVAR_GET_FLOAT("rj"); - - if ( (iRocketJumpModifier > 1) && (pAttacker == this) && m_iQuakeWeapon == ( IT_ROCKET_LAUNCHER | IT_GRENADE_LAUNCHER ) ) - pev->velocity = pev->velocity + vecPush * flDamage * iRocketJumpModifier; - } - - // check for godmode or invincibility - if (pev->flags & FL_GODMODE) - return 0; - if (m_flInvincibleFinished > gpGlobals->time) - { - if (m_fInvincSound < gpGlobals->time) - { - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/protect3.wav", 1, ATTN_NORM); - m_fInvincSound = gpGlobals->time + 2; - } - return 0; - } - - - // do the damage - pev->health -= (int)flTake; - - // tell director about it - MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR ); - WRITE_BYTE ( 9 ); // command length in bytes - WRITE_BYTE ( DRC_CMD_EVENT ); // take damage event - WRITE_SHORT( ENTINDEX(this->edict()) ); // index number of primary entity - WRITE_SHORT( ENTINDEX(ENT(pevInflictor)) ); // index number of secondary entity - WRITE_LONG( 5 ); // eventflags (priority and flags) - MESSAGE_END(); - - // react to the damage - m_bitsDamageType |= bitsDamageType; // Save this so we can report it to the client - m_bitsHUDDamage = -1; // make sure the damage bits get resent - - if ( pev->health <= 0 ) - { - g_pevLastInflictor = pevInflictor; - - Killed( pevAttacker, GIB_NORMAL ); - - g_pevLastInflictor = NULL; - return 0; - } - - // play pain sound - Pain( pAttacker ); - - return flTake; -} - diff --git a/dmc/dlls/quake_rocket.cpp b/dmc/dlls/quake_rocket.cpp deleted file mode 100644 index 3526981..0000000 --- a/dmc/dlls/quake_rocket.cpp +++ /dev/null @@ -1,191 +0,0 @@ -//=========== (C) Copyright 1996-2002, Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Quake rocket entity -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "weapons.h" - -#define GRENADE_TRAIL 1 -#define ROCKET_TRAIL 2 - -extern unsigned short g_sTrail; -extern unsigned short g_sExplosion; - -LINK_ENTITY_TO_CLASS( quake_rocket, CQuakeRocket ); - -//========================================================= -CQuakeRocket *CQuakeRocket::CreateRocket( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner ) -{ - CQuakeRocket *pRocket = GetClassPtr( (CQuakeRocket *)NULL ); - - UTIL_SetOrigin( pRocket->pev, vecOrigin ); - SET_MODEL(ENT(pRocket->pev), "models/rocket.mdl"); - pRocket->Spawn(); - pRocket->pev->classname = MAKE_STRING("missile"); - pRocket->pev->owner = pOwner->edict(); - - // Setup - pRocket->pev->movetype = MOVETYPE_FLYMISSILE; - pRocket->pev->solid = SOLID_BBOX; - - // Velocity - pRocket->pev->velocity = vecAngles * 1000; - pRocket->pev->angles = UTIL_VecToAngles( vecAngles ); - - // Touch - pRocket->SetTouch( &CQuakeRocket::RocketTouch ); - - // Safety Remove - pRocket->pev->nextthink = gpGlobals->time + 5; - pRocket->SetThink( &CQuakeRocket::SUB_Remove ); - - // Effects -// pRocket->pev->effects |= EF_LIGHT; - - PLAYBACK_EVENT_FULL (FEV_GLOBAL, pRocket->edict(), g_sTrail, 0.0, - (float *)&pRocket->pev->origin, (float *)&pRocket->pev->angles, 0.7, 0.0, pRocket->entindex(), ROCKET_TRAIL, 0, 0); - - return pRocket; -} - -//========================================================= -CQuakeRocket *CQuakeRocket::CreateGrenade( Vector vecOrigin, Vector vecVelocity, CBaseEntity *pOwner ) -{ - CQuakeRocket *pRocket = GetClassPtr( (CQuakeRocket *)NULL ); - - UTIL_SetOrigin( pRocket->pev, vecOrigin ); - SET_MODEL(ENT(pRocket->pev), "models/grenade.mdl"); - pRocket->Spawn(); - pRocket->pev->classname = MAKE_STRING("grenade"); - pRocket->pev->owner = pOwner->edict(); - - // Setup - pRocket->pev->movetype = MOVETYPE_BOUNCE; - pRocket->pev->solid = SOLID_BBOX; - - pRocket->pev->avelocity = Vector(300,300,300); - - // Velocity - pRocket->pev->velocity = vecVelocity; - pRocket->pev->angles = UTIL_VecToAngles(vecVelocity); - pRocket->pev->friction = 0.5; - - // Touch - pRocket->SetTouch( &CQuakeRocket::GrenadeTouch ); - - // set newmis duration - if ( gpGlobals->deathmatch == 4 ) - { - pRocket->m_flAttackFinished = gpGlobals->time + 1.1; // What's this used for? - if (pOwner) - pOwner->TakeDamage( pOwner->pev, pOwner->pev, 10, DMG_GENERIC ); - } - - pRocket->pev->nextthink = gpGlobals->time + 2.5; - pRocket->SetThink( &CQuakeRocket::GrenadeExplode ); - - PLAYBACK_EVENT_FULL (FEV_GLOBAL, pRocket->edict(), g_sTrail, 0.0, - (float *)&g_vecZero, (float *)&g_vecZero, 0.7, 0.0, pRocket->entindex(), GRENADE_TRAIL, 0, 0); - - - return pRocket; -} - -//========================================================= -void CQuakeRocket::Spawn( void ) -{ - Precache(); - - UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0)); - UTIL_SetOrigin( pev, pev->origin ); -} - -//========================================================= -void CQuakeRocket::Precache( void ) -{ - m_iTrail = PRECACHE_MODEL("sprites/smoke.spr"); -} - -//========================================================= -void CQuakeRocket::RocketTouch ( CBaseEntity *pOther ) -{ - // Remove if we've hit skybrush - if ( UTIL_PointContents(pev->origin) == CONTENT_SKY ) - { - UTIL_Remove( this ); - return; - } - - // Do touch damage - float flDmg = RANDOM_FLOAT( 100, 120 ); - CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner); - if (pOther->pev->health) - pOther->TakeDamage( pev, pOwner->pev, flDmg, DMG_BULLET ); - - // Don't do radius damage to the other, because all the damage was done in the impact - Q_RadiusDamage(this, pOwner, 120, pOther); - - // Finish and remove - Explode(); -} - -//========================================================= -void CQuakeRocket::GrenadeTouch( CBaseEntity *pOther ) -{ - if (pOther->pev->takedamage == DAMAGE_AIM) - { - GrenadeExplode(); - return; - } - - if (pev->flags & FL_ONGROUND) - { - // add a bit of static friction - pev->velocity = pev->velocity * 0.75; - - if (pev->velocity.Length() <= 20) - { - pev->avelocity = g_vecZero; - } - } - - EMIT_SOUND(ENT(pev), CHAN_WEAPON, "weapons/bounce.wav", 1, ATTN_NORM); - - if (pev->velocity == g_vecZero) - pev->avelocity = g_vecZero; -} - -//========================================================= -void CQuakeRocket::GrenadeExplode() -{ - CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner); - Q_RadiusDamage(this, pOwner, 120, NULL); - - // Finish and remove - Explode(); -} - -//========================================================= -void CQuakeRocket::Explode() -{ - //We use the angles field to send the rocket velocity. - PLAYBACK_EVENT_FULL( FEV_GLOBAL, edict(), g_sExplosion, 0.0, (float *)&pev->origin, (float *)&pev->velocity, 0.0, 0.0, 0, 0, 0, 0 ); - - UTIL_Remove( this ); -} diff --git a/dmc/dlls/quake_weapons_all.cpp b/dmc/dlls/quake_weapons_all.cpp deleted file mode 100644 index d639ecd..0000000 --- a/dmc/dlls/quake_weapons_all.cpp +++ /dev/null @@ -1,1087 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -/* - -===== quake_weapons.cpp ======================================================== - - Quake weaponry - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "quake_gun.h" - -char gszQ_DeathType[128]; -DLL_GLOBAL short g_sModelIndexNail; - -#ifdef THREEWAVE -extern unsigned short g_usHook; -extern unsigned short g_usCable; -extern unsigned short g_usCarried; -#endif - -#ifdef CLIENT_DLL -#include "cl_entity.h" -struct cl_entity_s *GetViewEntity( void ); -extern float g_flLightTime; -#endif - -// called by worldspawn -void QuakeClassicPrecache( void ) -{ - // Weapon sounds - PRECACHE_SOUND("weapons/ax1.wav"); - PRECACHE_SOUND("player/axhit2.wav"); - PRECACHE_SOUND("player/axhitbod.wav"); - PRECACHE_SOUND("weapons/r_exp3.wav"); // new rocket explosion - PRECACHE_SOUND("weapons/rocket1i.wav");// spike gun - PRECACHE_SOUND("weapons/sgun1.wav"); - PRECACHE_SOUND("weapons/lhit.wav"); - PRECACHE_SOUND("weapons/guncock.wav"); // player shotgun - PRECACHE_SOUND("weapons/ric1.wav"); // ricochet (used in c code) - PRECACHE_SOUND("weapons/ric2.wav"); // ricochet (used in c code) - PRECACHE_SOUND("weapons/ric3.wav"); // ricochet (used in c code) - PRECACHE_SOUND("weapons/spike2.wav"); // super spikes - PRECACHE_SOUND("weapons/tink1.wav"); // spikes tink (used in c code) - PRECACHE_SOUND("weapons/grenade.wav"); // grenade launcher - PRECACHE_SOUND("weapons/bounce.wav"); // grenade bounce - PRECACHE_SOUND("weapons/shotgn2.wav"); // super shotgun - PRECACHE_SOUND("weapons/lstart.wav"); // lightning start - - // Weapon models - PRECACHE_MODEL("models/v_crowbar.mdl"); - PRECACHE_MODEL("models/v_shot.mdl"); - PRECACHE_MODEL("models/v_shot2.mdl"); - PRECACHE_MODEL("models/v_nail.mdl"); - PRECACHE_MODEL("models/v_nail2.mdl"); - PRECACHE_MODEL("models/v_rock.mdl"); - PRECACHE_MODEL("models/v_rock2.mdl"); - PRECACHE_MODEL("models/v_light.mdl"); - - // Weapon player models - PRECACHE_MODEL("models/p_crowbar.mdl"); - PRECACHE_MODEL("models/p_rock2.mdl"); - PRECACHE_MODEL("models/p_rock.mdl"); - PRECACHE_MODEL("models/p_shot2.mdl"); - PRECACHE_MODEL("models/p_nail.mdl"); - PRECACHE_MODEL("models/p_nail2.mdl"); - PRECACHE_MODEL("models/p_light.mdl"); - PRECACHE_MODEL("models/p_shot.mdl"); - - - // Weapon effect models - PRECACHE_MODEL("models/rocket.mdl"); // rocket - PRECACHE_MODEL("models/grenade.mdl"); // grenade - g_sModelIndexNail = PRECACHE_MODEL("models/spike.mdl"); - g_sModelIndexLaser = PRECACHE_MODEL("sprites/laserbeam.spr"); - PRECACHE_MODEL("sprites/smoke.spr"); - - // Powerup models - - // Powerup sounds - PRECACHE_SOUND("items/damage3.wav"); - PRECACHE_SOUND("items/sight1.wav"); - - // Teleport sounds - PRECACHE_SOUND("misc/r_tele1.wav"); - PRECACHE_SOUND("misc/r_tele2.wav"); - PRECACHE_SOUND("misc/r_tele3.wav"); - PRECACHE_SOUND("misc/r_tele4.wav"); - PRECACHE_SOUND("misc/r_tele5.wav"); - - // Misc - PRECACHE_SOUND("weapons/lock4.wav"); - PRECACHE_SOUND("weapons/pkup.wav"); - PRECACHE_SOUND("items/itembk2.wav"); - PRECACHE_MODEL("models/backpack.mdl"); - -#ifdef THREEWAVE - PRECACHE_MODEL("models/v_grapple.mdl"); -#endif - -} - -//================================================================================================ -// WEAPON SELECTION -//================================================================================================ -// Return the ID of the best weapon being carried by the player -int CBasePlayer::W_BestWeapon() -{ - if (pev->waterlevel <= 1 && m_iAmmoCells >= 1 && (m_iQuakeItems & IT_LIGHTNING) ) - return IT_LIGHTNING; - else if(m_iAmmoNails >= 2 && (m_iQuakeItems & IT_SUPER_NAILGUN) ) - return IT_SUPER_NAILGUN; - else if(m_iAmmoShells >= 2 && (m_iQuakeItems & IT_SUPER_SHOTGUN) ) - return IT_SUPER_SHOTGUN; - else if(m_iAmmoNails >= 1 && (m_iQuakeItems & IT_NAILGUN) ) - return IT_NAILGUN; - else if(m_iAmmoShells >= 1 && (m_iQuakeItems & IT_SHOTGUN) ) - return IT_SHOTGUN; - - return IT_AXE; -} - -// Weapon setup after weapon switch -void CBasePlayer::W_SetCurrentAmmo( int sendanim /* = 1 */ ) -{ - m_iQuakeItems &= ~(IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS); - int iszViewModel = 0; - char *viewmodel = ""; - int iszWeaponModel = 0; - char *szAnimExt; - - // Find out what weapon the player's using - if (m_iQuakeWeapon == IT_AXE) - { - m_pCurrentAmmo = NULL; - viewmodel = "models/v_crowbar.mdl"; - iszViewModel = MAKE_STRING(viewmodel); - szAnimExt = "crowbar"; - iszWeaponModel = MAKE_STRING("models/p_crowbar.mdl"); - } - else if (m_iQuakeWeapon == IT_SHOTGUN) - { - m_pCurrentAmmo = &m_iAmmoShells; - viewmodel = "models/v_shot.mdl"; - iszViewModel = MAKE_STRING(viewmodel); - iszWeaponModel = MAKE_STRING("models/p_shot.mdl"); - m_iQuakeItems |= IT_SHELLS; - szAnimExt = "shotgun"; - } - else if (m_iQuakeWeapon == IT_SUPER_SHOTGUN) - { - m_pCurrentAmmo = &m_iAmmoShells; - viewmodel = "models/v_shot2.mdl"; - iszViewModel = MAKE_STRING(viewmodel); - iszWeaponModel = MAKE_STRING("models/p_shot2.mdl"); - m_iQuakeItems |= IT_SHELLS; - szAnimExt = "shotgun"; - } - else if (m_iQuakeWeapon == IT_NAILGUN) - { - m_pCurrentAmmo = &m_iAmmoNails; - viewmodel = "models/v_nail.mdl"; - iszViewModel = MAKE_STRING(viewmodel); - iszWeaponModel = MAKE_STRING("models/p_nail.mdl"); - m_iQuakeItems |= IT_NAILS; - szAnimExt = "mp5"; - } - else if (m_iQuakeWeapon == IT_SUPER_NAILGUN) - { - m_pCurrentAmmo = &m_iAmmoNails; - viewmodel = "models/v_nail2.mdl"; - iszViewModel = MAKE_STRING(viewmodel); - iszWeaponModel = MAKE_STRING("models/p_nail2.mdl"); - m_iQuakeItems |= IT_NAILS; - szAnimExt = "mp5"; - } - else if (m_iQuakeWeapon == IT_GRENADE_LAUNCHER) - { - m_pCurrentAmmo = &m_iAmmoRockets; - viewmodel = "models/v_rock.mdl"; - iszViewModel = MAKE_STRING(viewmodel); - m_iQuakeItems |= IT_ROCKETS; - iszWeaponModel = MAKE_STRING("models/p_rock.mdl"); - szAnimExt = "gauss"; - } - else if (m_iQuakeWeapon == IT_ROCKET_LAUNCHER) - { - m_pCurrentAmmo = &m_iAmmoRockets; - viewmodel = "models/v_rock2.mdl"; - iszViewModel = MAKE_STRING(viewmodel); - m_iQuakeItems |= IT_ROCKETS; - iszWeaponModel = MAKE_STRING("models/p_rock2.mdl"); - szAnimExt = "gauss"; - } - else if (m_iQuakeWeapon == IT_LIGHTNING) - { - m_pCurrentAmmo = &m_iAmmoCells; - viewmodel = "models/v_light.mdl"; - iszViewModel = MAKE_STRING(viewmodel); - iszWeaponModel = MAKE_STRING("models/p_light.mdl"); - m_iQuakeItems |= IT_CELLS; - szAnimExt = "gauss"; - } -#ifdef THREEWAVE - else if (m_iQuakeWeapon == IT_EXTRA_WEAPON) - { - m_pCurrentAmmo = NULL; - viewmodel = "models/v_grapple.mdl"; - iszViewModel = MAKE_STRING(viewmodel); - szAnimExt = "crowbar"; - } -#endif - - else - { - m_pCurrentAmmo = NULL; - } - -#if !defined( CLIENT_DLL ) - - pev->viewmodel = iszViewModel; - - pev->weaponmodel = iszWeaponModel; - strcpy( m_szAnimExtention, szAnimExt ); - -#else - { - - int HUD_GetModelIndex( char *modelname ); - pev->viewmodel = HUD_GetModelIndex( viewmodel ); - - cl_entity_t *view; - view = GetViewEntity(); - - //Adrian - The actual "magic" is done in the - //Studio drawing code. - if ( m_iQuakeItems & IT_INVISIBILITY ) - { - if( view ) - { - view->curstate.renderfx = kRenderFxGlowShell; - view->curstate.renderamt = 5; - - view->curstate.rendercolor.r = 125; - view->curstate.rendercolor.g = 125; - view->curstate.rendercolor.b = 125; - } - } - else - { - if ( m_iQuakeItems & IT_INVULNERABILITY ) - { - if( view ) - { - view->curstate.renderfx = kRenderFxGlowShell; - view->curstate.renderamt = 15; - - view->curstate.rendercolor.r = 255; - view->curstate.rendercolor.g = 125; - view->curstate.rendercolor.b = 125; - } - } - else if ( m_iQuakeItems & IT_QUAD ) - { - if( view ) - { - view->curstate.renderfx = kRenderFxGlowShell; - view->curstate.renderamt = 15; - - view->curstate.rendercolor.r = 125; - view->curstate.rendercolor.g = 125; - view->curstate.rendercolor.b = 255; - } - } - else if ( m_iQuakeItems & ( IT_INVULNERABILITY | IT_QUAD ) ) - { - if( view ) - { - view->curstate.renderfx = kRenderFxGlowShell; - view->curstate.renderamt = 15; - - view->curstate.rendercolor.r = 255; - view->curstate.rendercolor.g = 125; - view->curstate.rendercolor.b = 255; - } - } - else - view->curstate.renderfx = kRenderFxNone; // Clear it. - } - } -#endif -} - -// Return TRUE if the weapon still has ammo -BOOL CBasePlayer::W_CheckNoAmmo() -{ - if ( m_pCurrentAmmo && *m_pCurrentAmmo > 0 ) - return TRUE; - - if ( m_iQuakeWeapon == IT_AXE ) - return TRUE; - -#ifdef THREEWAVE - if ( m_iQuakeWeapon == IT_EXTRA_WEAPON ) - return TRUE; -#endif - - if ( m_iQuakeWeapon == IT_LIGHTNING ) - { - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usLightning, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, 0, 1, 0, 0 ); - - if ( m_pActiveItem ) - ((CQuakeGun*)m_pActiveItem)->DestroyEffect(); - } - - m_iQuakeWeapon = W_BestWeapon(); - W_SetCurrentAmmo(); - return FALSE; -} - -// Change to the specified weapon -void CBasePlayer::W_ChangeWeapon( int iWeaponNumber ) -{ - if ( m_iQuakeWeapon == IT_LIGHTNING ) - { - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usLightning, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, 0, 1, 0, 0 ); - - if ( m_pActiveItem ) - ((CQuakeGun*)m_pActiveItem)->DestroyEffect(); - } - - int iWeapon = 0; - BOOL bHaveAmmo = TRUE; - - if (iWeaponNumber == 1) - { - iWeapon = IT_AXE; - } - else if (iWeaponNumber == 2) - { - iWeapon = IT_SHOTGUN; - if (m_iAmmoShells < 1) - bHaveAmmo = FALSE; - } - else if (iWeaponNumber == 3) - { - iWeapon = IT_SUPER_SHOTGUN; - if (m_iAmmoShells < 2) - bHaveAmmo = FALSE; - } - else if (iWeaponNumber == 4) - { - iWeapon = IT_NAILGUN; - if (m_iAmmoNails < 1) - bHaveAmmo = FALSE; - } - else if (iWeaponNumber == 5) - { - iWeapon = IT_SUPER_NAILGUN; - if (m_iAmmoNails < 2) - bHaveAmmo = FALSE; - } - else if (iWeaponNumber == 6) - { - iWeapon = IT_GRENADE_LAUNCHER; - if (m_iAmmoRockets < 1) - bHaveAmmo = FALSE; - } - else if (iWeaponNumber == 7) - { - iWeapon = IT_ROCKET_LAUNCHER; - if (m_iAmmoRockets < 1) - bHaveAmmo = FALSE; - } - else if (iWeaponNumber == 8) - { - iWeapon = IT_LIGHTNING; - - if (m_iAmmoCells < 1) - bHaveAmmo = FALSE; - } -#ifdef THREEWAVE - else if (iWeaponNumber == 9) - { - iWeapon = IT_EXTRA_WEAPON; - } -#endif - - // Have the weapon? - if ( !(m_iQuakeItems & iWeapon) ) - { - ClientPrint( pev, HUD_PRINTCONSOLE, "#No_Weapon" ); - return; - } - - // Have ammo for it? - if ( !bHaveAmmo ) - { - ClientPrint( pev, HUD_PRINTCONSOLE, "#No_Ammo" ); - return; - } - - // Set weapon, update ammo - m_iQuakeWeapon = iWeapon; - W_SetCurrentAmmo(); - -#ifdef CLIENT_DLL - g_flLightTime = 0.0; -#endif -} - -// Go to the next weapon with ammo -void CBasePlayer::W_CycleWeaponCommand( void ) -{ - while (1) - { - BOOL bHaveAmmo = TRUE; - - if (m_iQuakeWeapon == IT_LIGHTNING) - { - m_iQuakeWeapon = IT_EXTRA_WEAPON; - } - else if (m_iQuakeWeapon == IT_EXTRA_WEAPON) - { - m_iQuakeWeapon = IT_AXE; - } - else if (m_iQuakeWeapon == IT_AXE) - { - m_iQuakeWeapon = IT_SHOTGUN; - if (m_iAmmoShells < 1) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_SHOTGUN) - { - m_iQuakeWeapon = IT_SUPER_SHOTGUN; - if (m_iAmmoShells < 2) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_SUPER_SHOTGUN) - { - m_iQuakeWeapon = IT_NAILGUN; - if (m_iAmmoNails < 1) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_NAILGUN) - { - m_iQuakeWeapon = IT_SUPER_NAILGUN; - if (m_iAmmoNails < 2) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_SUPER_NAILGUN) - { - m_iQuakeWeapon = IT_GRENADE_LAUNCHER; - if (m_iAmmoRockets < 1) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_GRENADE_LAUNCHER) - { - m_iQuakeWeapon = IT_ROCKET_LAUNCHER; - if (m_iAmmoRockets < 1) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_ROCKET_LAUNCHER) - { - m_iQuakeWeapon = IT_LIGHTNING; - if (m_iAmmoCells < 1) - bHaveAmmo = FALSE; - } - - if ( (m_iQuakeItems & m_iQuakeWeapon) && bHaveAmmo ) - { - W_SetCurrentAmmo(); - return; - } - } - -} - -// Go to the prev weapon with ammo -void CBasePlayer::W_CycleWeaponReverseCommand() -{ - while (1) - { - BOOL bHaveAmmo = TRUE; - - if (m_iQuakeWeapon == IT_EXTRA_WEAPON) - { - m_iQuakeWeapon = IT_LIGHTNING; - } - else if (m_iQuakeWeapon == IT_LIGHTNING) - { - m_iQuakeWeapon = IT_ROCKET_LAUNCHER; - if (m_iAmmoRockets < 1) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_ROCKET_LAUNCHER) - { - m_iQuakeWeapon = IT_GRENADE_LAUNCHER; - if (m_iAmmoRockets < 1) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_GRENADE_LAUNCHER) - { - m_iQuakeWeapon = IT_SUPER_NAILGUN; - if (m_iAmmoNails < 2) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_SUPER_NAILGUN) - { - m_iQuakeWeapon = IT_NAILGUN; - if (m_iAmmoNails < 1) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_NAILGUN) - { - m_iQuakeWeapon = IT_SUPER_SHOTGUN; - if (m_iAmmoShells < 2) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_SUPER_SHOTGUN) - { - m_iQuakeWeapon = IT_SHOTGUN; - if (m_iAmmoShells < 1) - bHaveAmmo = FALSE; - } - else if (m_iQuakeWeapon == IT_SHOTGUN) - { - m_iQuakeWeapon = IT_AXE; - } - else if (m_iQuakeWeapon == IT_AXE) - { - m_iQuakeWeapon = IT_EXTRA_WEAPON; - } - else if (m_iQuakeWeapon == IT_EXTRA_WEAPON) - { - m_iQuakeWeapon = IT_LIGHTNING; - if (m_iAmmoCells < 1) - bHaveAmmo = FALSE; - } - - - if ( (m_iQuakeItems & m_iQuakeWeapon) && bHaveAmmo ) - { - W_SetCurrentAmmo(); - return; - } - } - -} - -//================================================================================================ -// WEAPON FUNCTIONS -//================================================================================================ -// Returns true if the inflictor can directly damage the target. Used for explosions and melee attacks. -float Q_CanDamage(CBaseEntity *pTarget, CBaseEntity *pInflictor) -{ - TraceResult trace; - - // bmodels need special checking because their origin is 0,0,0 - if (pTarget->pev->movetype == MOVETYPE_PUSH) - { - UTIL_TraceLine( pInflictor->pev->origin, 0.5 * (pTarget->pev->absmin + pTarget->pev->absmax), ignore_monsters, NULL, &trace ); - if (trace.flFraction == 1) - return TRUE; - CBaseEntity *pEntity = CBaseEntity::Instance(trace.pHit); - if (pEntity == pTarget) - return TRUE; - return FALSE; - } - - UTIL_TraceLine( pInflictor->pev->origin, pTarget->pev->origin, ignore_monsters, NULL, &trace ); - if (trace.flFraction == 1) - return TRUE; - UTIL_TraceLine( pInflictor->pev->origin, pTarget->pev->origin + Vector(15,15,0), ignore_monsters, NULL, &trace ); - if (trace.flFraction == 1) - return TRUE; - UTIL_TraceLine( pInflictor->pev->origin, pTarget->pev->origin + Vector(-15,-15,0), ignore_monsters, NULL, &trace ); - if (trace.flFraction == 1) - return TRUE; - UTIL_TraceLine( pInflictor->pev->origin, pTarget->pev->origin + Vector(-15,15,0), ignore_monsters, NULL, &trace ); - if (trace.flFraction == 1) - return TRUE; - UTIL_TraceLine( pInflictor->pev->origin, pTarget->pev->origin + Vector(15,-15,0), ignore_monsters, NULL, &trace ); - if (trace.flFraction == 1) - return TRUE; - - return FALSE; -} - -// Quake Bullet firing -void CBasePlayer::Q_FireBullets(int iShots, Vector vecDir, Vector vecSpread) -{ - TraceResult trace; - UTIL_MakeVectors(pev->v_angle); - - Vector vecSrc = pev->origin + (gpGlobals->v_forward * 10); - vecSrc.z = pev->absmin.z + (pev->size.z * 0.7); - ClearMultiDamage(); - - while ( iShots > 0 ) - { - Vector vecPath = vecDir + ( RANDOM_FLOAT( -1, 1 ) * vecSpread.x * gpGlobals->v_right ) + ( RANDOM_FLOAT( -1, 1 ) * vecSpread.y * gpGlobals->v_up ); - Vector vecEnd = vecSrc + ( vecPath * 2048 ); - UTIL_TraceLine( vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &trace ); - if (trace.flFraction != 1.0) - { - CBaseEntity *pEntity = CBaseEntity::Instance(trace.pHit); - if (pEntity && pEntity->pev->takedamage && pEntity->IsPlayer() ) - { - pEntity->TraceAttack(pev, 4, vecPath, &trace, DMG_BULLET); - //AddMultiDamage(pev, pEntity, 4, DMG_BULLET); - } - else if ( pEntity && pEntity->pev->takedamage ) - { - pEntity->TakeDamage( pev, pev, 4, DMG_BULLET ); - } - } - - iShots--; - } - - ApplyMultiDamage( pev, pev ); -} - -#if !defined( CLIENT_DLL ) -// Quake Radius damage -void Q_RadiusDamage( CBaseEntity *pInflictor, CBaseEntity *pAttacker, float flDamage, CBaseEntity *pIgnore ) -{ - CBaseEntity *pEnt = NULL; - - while ( (pEnt = UTIL_FindEntityInSphere( pEnt, pInflictor->pev->origin, flDamage+40 )) != NULL ) - { - if (pEnt != pIgnore) - { - if (pEnt->pev->takedamage) - { - Vector vecOrg = pEnt->pev->origin + ((pEnt->pev->mins + pEnt->pev->maxs) * 0.5); - float flPoints = 0.5 * (pInflictor->pev->origin - vecOrg).Length(); - if (flPoints < 0) - flPoints = 0; - flPoints = flDamage - flPoints; - - if (pEnt == pAttacker) - flPoints = flPoints * 0.5; - if (flPoints > 0) - { - if ( Q_CanDamage( pEnt, pInflictor ) ) - pEnt->TakeDamage( pInflictor->pev, pAttacker->pev, flPoints, DMG_GENERIC ); - } - } - } - } -} -#endif - -// Lightning hit a target -void LightningHit(CBaseEntity *pTarget, CBaseEntity *pAttacker, Vector vecHitPos, float flDamage, TraceResult *ptr, Vector vecDir ) -{ - -#ifndef CLIENT_DLL - SpawnBlood( vecHitPos, BLOOD_COLOR_RED, flDamage * 1.5 ); - - if ( g_pGameRules->PlayerRelationship( pTarget, pAttacker ) != GR_TEAMMATE ) - { - - pTarget->TakeDamage( pAttacker->pev, pAttacker->pev, flDamage, DMG_GENERIC ); - pTarget->TraceBleed( flDamage, vecDir, ptr, DMG_BULLET ); // have to use DMG_BULLET or it wont spawn. - - } -#endif -} - -// Lightning Damage -void CBasePlayer::LightningDamage( Vector p1, Vector p2, CBaseEntity *pAttacker, float flDamage, Vector vecDir) -{ -#if !defined( CLIENT_DLL ) - TraceResult trace; - Vector vecThru = (p2 - p1).Normalize(); - vecThru.x = 0 - vecThru.y; - vecThru.y = vecThru.x; - vecThru.z = 0; - vecThru = vecThru * 16; - - CBaseEntity *pEntity1 = NULL; - CBaseEntity *pEntity2 = NULL; - - // Hit first target? - UTIL_TraceLine( p1, p2, dont_ignore_monsters, ENT(pev), &trace ); - CBaseEntity *pEntity = CBaseEntity::Instance(trace.pHit); - if (pEntity && pEntity->pev->takedamage) - { - LightningHit(pEntity, pAttacker, trace.vecEndPos, flDamage, &trace, vecDir ); - } - pEntity1 = pEntity; - - // Hit second target? - UTIL_TraceLine( p1 + vecThru, p2 + vecThru, dont_ignore_monsters, ENT(pev), &trace ); - pEntity = CBaseEntity::Instance(trace.pHit); - if (pEntity && pEntity != pEntity1 && pEntity->pev->takedamage) - { - LightningHit(pEntity, pAttacker, trace.vecEndPos, flDamage, &trace, vecDir ); - } - pEntity2 = pEntity; - - // Hit third target? - UTIL_TraceLine( p1 - vecThru, p2 - vecThru, dont_ignore_monsters, ENT(pev), &trace ); - pEntity = CBaseEntity::Instance(trace.pHit); - if (pEntity && pEntity != pEntity1 && pEntity != pEntity2 && pEntity->pev->takedamage) - { - LightningHit(pEntity, pAttacker, trace.vecEndPos, flDamage, &trace, vecDir ); - } -#endif -} - -//================================================================================================ -// WEAPON FIRING -//================================================================================================ -// Axe -void CBasePlayer::W_FireAxe() -{ - TraceResult trace; - Vector vecSrc = pev->origin + Vector(0, 0, 16); - - // Swing forward 64 units - UTIL_MakeVectors(pev->v_angle); - UTIL_TraceLine( vecSrc, vecSrc + (gpGlobals->v_forward * 64), dont_ignore_monsters, ENT(pev), &trace ); - if (trace.flFraction == 1.0) - return; - - Vector vecOrg = trace.vecEndPos - gpGlobals->v_forward * 4; - - CBaseEntity *pEntity = CBaseEntity::Instance(trace.pHit); - if (pEntity && pEntity->pev->takedamage) - { - pEntity->m_bAxHitMe = TRUE; - int iDmg = 20; - if (gpGlobals->deathmatch > 3) - iDmg = 75; - - pEntity->TakeDamage( pev, pev, iDmg, DMG_GENERIC ); - -#ifndef CLIENT_DLL - if ( g_pGameRules->PlayerRelationship( this, pEntity ) != GR_TEAMMATE ) - SpawnBlood( vecOrg, BLOOD_COLOR_RED, iDmg * 4 ); // Make a lot of Blood! -#endif - } -} - -// Single barrel shotgun -void CBasePlayer::W_FireShotgun( int iQuadSound ) -{ - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usShotgunSingle, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, iQuadSound, 0, 0, 0 ); - - if (gpGlobals->deathmatch != 4 ) - *m_pCurrentAmmo -= 1; - - Vector vecDir = GetAutoaimVector( AUTOAIM_5DEGREES ); - Q_FireBullets(6, vecDir, Vector(0.04, 0.04, 0) ); -} - - -#ifdef THREEWAVE -void CBasePlayer::W_FireHook( void ) -{ - PLAYBACK_EVENT_FULL( FEV_NOTHOST | FEV_GLOBAL, edict(), g_usHook, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, 0, 0, 0, 0 ); - - Throw_Grapple(); -} -#endif - -#ifdef THREEWAVE - -#ifdef CLIENT_DLL -unsigned short g_usCable; -unsigned short g_usHook; -unsigned short g_usCarried; - -void CBasePlayer::Throw_Grapple( void ) -{ -} -#endif -#endif - -// Double barrel shotgun -void CBasePlayer::W_FireSuperShotgun( int iQuadSound ) -{ - if (*m_pCurrentAmmo == 1) - { - W_FireShotgun( iQuadSound ); - return; - } - - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usShotgunDouble, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, iQuadSound, 0, 0, 0 ); - - if (gpGlobals->deathmatch != 4 ) - *m_pCurrentAmmo -= 2; - Vector vecDir = GetAutoaimVector( AUTOAIM_5DEGREES ); - Q_FireBullets(14, vecDir, Vector(0.14, 0.08, 0) ); -}; - -// Rocket launcher -void CBasePlayer::W_FireRocket( int iQuadSound ) -{ - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usRocket, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, iQuadSound, 0, 0, 0 ); - - if (gpGlobals->deathmatch != 4 ) - *m_pCurrentAmmo -= 1; - - // Create the rocket - UTIL_MakeVectors( pev->v_angle ); - Vector vecOrg = pev->origin + (gpGlobals->v_forward * 8) + Vector(0,0,16); - Vector vecDir = GetAutoaimVector( AUTOAIM_5DEGREES ); - CQuakeRocket *pRocket = CQuakeRocket::CreateRocket( vecOrg, vecDir, this ); -} - -// Grenade launcher -void CBasePlayer::W_FireGrenade( int iQuadSound ) -{ - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usGrenade, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, iQuadSound, 0, 0, 0 ); - - if (gpGlobals->deathmatch != 4 ) - *m_pCurrentAmmo -= 1; - - // Get initial velocity - UTIL_MakeVectors( pev->v_angle ); - Vector vecVelocity; - if ( pev->v_angle.x ) - { - vecVelocity = gpGlobals->v_forward * 600 + gpGlobals->v_up * 200 + RANDOM_FLOAT(-1,1) * gpGlobals->v_right * 10 + RANDOM_FLOAT(-1,1) * gpGlobals->v_up * 10; - } - else - { - vecVelocity = GetAutoaimVector( AUTOAIM_5DEGREES ); - vecVelocity = vecVelocity * 600; - vecVelocity.z = 200; - } - - // Create the grenade - CQuakeRocket *pRocket = CQuakeRocket::CreateGrenade( pev->origin, vecVelocity, this ); -} - -// Lightning Gun -void CBasePlayer::W_FireLightning( int iQuadSound ) -{ - if (*m_pCurrentAmmo < 1) - { - //This should already be IT_LIGHTNING but what the heck. - if ( m_iQuakeWeapon == IT_LIGHTNING ) - { - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usLightning, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, 0, 1, 0, 0 ); - - if ( m_pActiveItem ) - ((CQuakeGun*)m_pActiveItem)->DestroyEffect(); - } - - m_iQuakeWeapon = W_BestWeapon (); - W_SetCurrentAmmo(); - return; - } - - bool playsound = false; - - // Make lightning sound every 0.6 seconds - if ( m_flLightningTime <= gpGlobals->time ) - { - playsound = true; - m_flLightningTime = gpGlobals->time + 0.6; - } - - // explode if under water - if (pev->waterlevel > 1) - { - if ( (gpGlobals->deathmatch > 3) && (RANDOM_FLOAT(0, 1) <= 0.5) ) - { - strcpy( gszQ_DeathType, "selfwater" ); - TakeDamage( pev, pev, 4000, DMG_GENERIC ); - } - else - { - float flCellsBurnt = *m_pCurrentAmmo; - *m_pCurrentAmmo = 0; - W_SetCurrentAmmo(); -#if !defined( CLIENT_DLL ) - Q_RadiusDamage( this, this, 35 * flCellsBurnt, NULL ); -#endif - return; - } - } - - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usLightning, 0, (float *)&pev->origin, (float *)&pev->angles, 0.0, 0.0, iQuadSound, 0, playsound, 0 ); - -#if !defined( CLIENT_DLL ) - - if (gpGlobals->deathmatch != 4 ) - *m_pCurrentAmmo -= 1; - - // Lightning bolt effect - TraceResult trace; - Vector vecOrg = pev->origin + Vector(0,0,16); - UTIL_MakeVectors( pev->v_angle ); - UTIL_TraceLine( vecOrg, vecOrg + (gpGlobals->v_forward * 600), ignore_monsters, ENT(pev), &trace ); - - Vector vecDir = gpGlobals->v_forward + ( 0.001 * gpGlobals->v_right ) + ( 0.001 * gpGlobals->v_up ); - // Do damage - LightningDamage(pev->origin, trace.vecEndPos + (gpGlobals->v_forward * 4), this, 30, vecDir ); - -#endif -} - -// Super Nailgun -void CBasePlayer::W_FireSuperSpikes( int iQuadSound ) -{ - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usSuperSpike, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, iQuadSound, 0, m_iNailOffset > 0.0 ? 1 : 0, 0 ); - - if (gpGlobals->deathmatch != 4 ) - *m_pCurrentAmmo -= 2; - m_flNextAttack = UTIL_WeaponTimeBase() + 0.1; - - // Fire the Nail - Vector vecDir = GetAutoaimVector( AUTOAIM_5DEGREES ); - CQuakeNail *pNail = CQuakeNail::CreateSuperNail( pev->origin + Vector(0,0,16), vecDir, this ); -} - -// Nailgun -void CBasePlayer::W_FireSpikes( int iQuadSound ) -{ - // If we're wielding the Super nailgun and we've got ammo for it, fire Super nails - if (*m_pCurrentAmmo >= 2 && m_iQuakeWeapon == IT_SUPER_NAILGUN) - { - W_FireSuperSpikes( iQuadSound ); - return; - } - - // Swap to next best weapon if this one just ran out - if (*m_pCurrentAmmo < 1) - { - m_iQuakeWeapon = W_BestWeapon (); - W_SetCurrentAmmo(); - return; - } - - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usSpike, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, iQuadSound, 0, m_iNailOffset > 0.0 ? 1 : 0, 0 ); - - // Fire left then right - if (m_iNailOffset == 2) - m_iNailOffset = -2; - else - m_iNailOffset = 2; - - if (gpGlobals->deathmatch != 4 ) - *m_pCurrentAmmo -= 1; - m_flNextAttack = UTIL_WeaponTimeBase() + 0.1; - - // Fire the nail - UTIL_MakeVectors( pev->v_angle ); - Vector vecDir = GetAutoaimVector( AUTOAIM_5DEGREES ); - CQuakeNail *pNail = CQuakeNail::CreateNail( pev->origin + Vector(0,0,10) + (gpGlobals->v_right * m_iNailOffset), vecDir, this ); -} - -//=============================================================================== -// PLAYER WEAPON USE -//=============================================================================== -void CBasePlayer::W_Attack( int iQuadSound ) -{ - // Out of ammo? - if ( !W_CheckNoAmmo() ) - return; - - if ( m_iQuakeWeapon != IT_LIGHTNING ) - ((CBasePlayerWeapon*)m_pActiveItem)->SendWeaponAnim( 1, 1 ); - - if (m_iQuakeWeapon == IT_AXE) - { -#ifdef THREEWAVE - if ( m_iRuneStatus == ITEM_RUNE3_FLAG ) - m_flNextAttack = UTIL_WeaponTimeBase() + 0.3; - else -#endif - m_flNextAttack = UTIL_WeaponTimeBase() + 0.5; - - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usAxeSwing, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, iQuadSound, 0, 0, 0 ); - - // Delay attack for 0.3 - m_flAxeFire = gpGlobals->time + 0.3; - - PLAYBACK_EVENT_FULL( FEV_NOTHOST, edict(), m_usAxe, 0.3, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, iQuadSound, 0, 0, 0 ); - - } - else if (m_iQuakeWeapon == IT_SHOTGUN) - { -#ifdef THREEWAVE - if ( m_iRuneStatus == ITEM_RUNE3_FLAG ) - m_flNextAttack = UTIL_WeaponTimeBase() + 0.3; - else -#endif - m_flNextAttack = UTIL_WeaponTimeBase() + 0.5; - - W_FireShotgun( iQuadSound ); - } - else if (m_iQuakeWeapon == IT_SUPER_SHOTGUN) - { -#ifdef THREEWAVE - if ( m_iRuneStatus == ITEM_RUNE3_FLAG ) - m_flNextAttack = UTIL_WeaponTimeBase() + 0.4; - else -#endif - m_flNextAttack = UTIL_WeaponTimeBase() + 0.7; - - W_FireSuperShotgun( iQuadSound ); - } - else if (m_iQuakeWeapon == IT_NAILGUN) - { - m_flNextAttack = UTIL_WeaponTimeBase() + 0.1; - - W_FireSpikes( iQuadSound ); - } - else if (m_iQuakeWeapon == IT_SUPER_NAILGUN) - { - m_flNextAttack = UTIL_WeaponTimeBase() + 0.1; - W_FireSpikes( iQuadSound ); - } - else if (m_iQuakeWeapon == IT_GRENADE_LAUNCHER) - { -#ifdef THREEWAVE - if ( m_iRuneStatus == ITEM_RUNE3_FLAG ) - m_flNextAttack = UTIL_WeaponTimeBase() + 0.3; - else -#endif - m_flNextAttack = UTIL_WeaponTimeBase() + 0.6; - - W_FireGrenade( iQuadSound ); - } - else if (m_iQuakeWeapon == IT_ROCKET_LAUNCHER) - { -#ifdef THREEWAVE - if ( m_iRuneStatus == ITEM_RUNE3_FLAG ) - m_flNextAttack = UTIL_WeaponTimeBase() + 0.4; - else -#endif - m_flNextAttack = UTIL_WeaponTimeBase() + 0.8; - - W_FireRocket( iQuadSound ); - } - else if (m_iQuakeWeapon == IT_LIGHTNING) - { - m_flNextAttack = UTIL_WeaponTimeBase() + 0.1; - - // Play the lightning start sound if gun just started firing - if (m_afButtonPressed & IN_ATTACK) - EMIT_SOUND(ENT(pev), CHAN_AUTO, "weapons/lstart.wav", 1, ATTN_NORM); - - W_FireLightning( iQuadSound ); - } - -#ifdef THREEWAVE - else if ( m_iQuakeWeapon == IT_EXTRA_WEAPON ) - { - - if ( !m_bHook_Out ) - W_FireHook (); - - m_flNextAttack = UTIL_WeaponTimeBase() + 0.1; - } -#endif - - // Make player attack - if ( pev->health >= 0 ) - SetAnimation( PLAYER_ATTACK1 ); -} diff --git a/dmc/dlls/saverestore.h b/dmc/dlls/saverestore.h deleted file mode 100644 index bcca972..0000000 --- a/dmc/dlls/saverestore.h +++ /dev/null @@ -1,170 +0,0 @@ -/*** -* -* 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. -* -****/ -// Implementation in UTIL.CPP -#ifndef SAVERESTORE_H -#define SAVERESTORE_H - -class CBaseEntity; - -class CSaveRestoreBuffer -{ -public: - CSaveRestoreBuffer( void ); - CSaveRestoreBuffer( SAVERESTOREDATA *pdata ); - ~CSaveRestoreBuffer( void ); - - int EntityIndex( entvars_t *pevLookup ); - int EntityIndex( edict_t *pentLookup ); - int EntityIndex( EOFFSET eoLookup ); - int EntityIndex( CBaseEntity *pEntity ); - - int EntityFlags( int entityIndex, int flags ) { return EntityFlagsSet( entityIndex, 0 ); } - int EntityFlagsSet( int entityIndex, int flags ); - - edict_t *EntityFromIndex( int entityIndex ); - - unsigned short TokenHash( const char *pszToken ); - -protected: - SAVERESTOREDATA *m_pdata; - void BufferRewind( int size ); - unsigned int HashString( const char *pszToken ); -}; - - -class CSave : public CSaveRestoreBuffer -{ -public: - CSave( SAVERESTOREDATA *pdata ) : CSaveRestoreBuffer( pdata ) {}; - - void WriteShort( const char *pname, const short *value, int count ); - void WriteInt( const char *pname, const int *value, int count ); // Save an int - void WriteFloat( const char *pname, const float *value, int count ); // Save a float - void WriteTime( const char *pname, const float *value, int count ); // Save a float (timevalue) - void WriteData( const char *pname, int size, const char *pdata ); // Save a binary data block - void WriteString( const char *pname, const char *pstring ); // Save a null-terminated string - void WriteString( const char *pname, const int *stringId, int count ); // Save a null-terminated string (engine string) - void WriteVector( const char *pname, const Vector &value ); // Save a vector - void WriteVector( const char *pname, const float *value, int count ); // Save a vector - void WritePositionVector( const char *pname, const Vector &value ); // Offset for landmark if necessary - void WritePositionVector( const char *pname, const float *value, int count ); // array of pos vectors - void WriteFunction( const char *pname, void **value, int count ); // Save a function pointer - int WriteEntVars( const char *pname, entvars_t *pev ); // Save entvars_t (entvars_t) - int WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); - -private: - int DataEmpty( const char *pdata, int size ); - void BufferField( const char *pname, int size, const char *pdata ); - void BufferString( char *pdata, int len ); - void BufferData( const char *pdata, int size ); - void BufferHeader( const char *pname, int size ); -}; - -typedef struct -{ - unsigned short size; - unsigned short token; - char *pData; -} HEADER; - -class CRestore : public CSaveRestoreBuffer -{ -public: - CRestore( SAVERESTOREDATA *pdata ) : CSaveRestoreBuffer( pdata ) { m_global = 0; m_precache = TRUE; } - - int ReadEntVars( const char *pname, entvars_t *pev ); // entvars_t - int ReadFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); - int ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount, int startField, int size, char *pName, void *pData ); - int ReadInt( void ); - short ReadShort( void ); - int ReadNamedInt( const char *pName ); - char *ReadNamedString( const char *pName ); - int Empty( void ) { return (m_pdata == NULL) || ((m_pdata->pCurrentData-m_pdata->pBaseData)>=m_pdata->bufferSize); } - inline void SetGlobalMode( int global ) { m_global = global; } - void PrecacheMode( BOOL mode ) { m_precache = mode; } - -private: - char *BufferPointer( void ); - void BufferReadBytes( char *pOutput, int size ); - void BufferSkipBytes( int bytes ); - int BufferSkipZString( void ); - int BufferCheckZString( const char *string ); - - void BufferReadHeader( HEADER *pheader ); - - int m_global; // Restoring a global entity? - BOOL m_precache; -}; - -#define MAX_ENTITYARRAY 64 - -//#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) - -#define IMPLEMENT_SAVERESTORE(derivedClass,baseClass) \ - int derivedClass::Save( CSave &save )\ - {\ - if ( !baseClass::Save(save) )\ - return 0;\ - return save.WriteFields( #derivedClass, this, m_SaveData, ARRAYSIZE(m_SaveData) );\ - }\ - int derivedClass::Restore( CRestore &restore )\ - {\ - if ( !baseClass::Restore(restore) )\ - return 0;\ - return restore.ReadFields( #derivedClass, this, m_SaveData, ARRAYSIZE(m_SaveData) );\ - } - - -typedef enum { GLOBAL_OFF = 0, GLOBAL_ON = 1, GLOBAL_DEAD = 2 } GLOBALESTATE; - -typedef struct globalentity_s globalentity_t; - -struct globalentity_s -{ - char name[64]; - char levelName[32]; - GLOBALESTATE state; - globalentity_t *pNext; -}; - -class CGlobalState -{ -public: - CGlobalState(); - void Reset( void ); - void ClearStates( void ); - void EntityAdd( string_t globalname, string_t mapName, GLOBALESTATE state ); - void EntitySetState( string_t globalname, GLOBALESTATE state ); - void EntityUpdate( string_t globalname, string_t mapname ); - const globalentity_t *EntityFromTable( string_t globalname ); - GLOBALESTATE EntityGetState( string_t globalname ); - int EntityInTable( string_t globalname ) { return (Find( globalname ) != NULL) ? 1 : 0; } - int Save( CSave &save ); - int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - -//#ifdef _DEBUG - void DumpGlobals( void ); -//#endif - -private: - globalentity_t *Find( string_t globalname ); - globalentity_t *m_pList; - int m_listCount; -}; - -extern CGlobalState gGlobalState; - -#endif //SAVERESTORE_H diff --git a/dmc/dlls/schedule.cpp b/dmc/dlls/schedule.cpp deleted file mode 100644 index 9b15dcf..0000000 --- a/dmc/dlls/schedule.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -//========================================================= -// schedule.cpp - functions and data pertaining to the -// monsters' AI scheduling system. -//========================================================= -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "animation.h" -#include "scripted.h" -#include "nodes.h" -#include "defaultai.h" - -extern CGraph WorldGraph; - -BOOL CBaseMonster :: FHaveSchedule( void ) { return FALSE; }; -void CBaseMonster :: ClearSchedule( void ) { }; -BOOL CBaseMonster :: FScheduleDone ( void ) { return FALSE; }; -void CBaseMonster :: ChangeSchedule ( Schedule_t *pNewSchedule ) { }; -void CBaseMonster :: NextScheduledTask ( void ) { }; -int CBaseMonster :: IScheduleFlags ( void ) { return 0; }; -BOOL CBaseMonster :: FScheduleValid ( void ) { return FALSE; }; -void CBaseMonster :: MaintainSchedule ( void ) { }; -void CBaseMonster :: SetTurnActivity ( void ) { }; -Task_t *CBaseMonster :: GetTask ( void ) { return NULL; }; diff --git a/dmc/dlls/schedule.h b/dmc/dlls/schedule.h deleted file mode 100644 index 82cbdeb..0000000 --- a/dmc/dlls/schedule.h +++ /dev/null @@ -1,290 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -//========================================================= -// Scheduling -//========================================================= - -#ifndef SCHEDULE_H -#define SCHEDULE_H - -#define TASKSTATUS_NEW 0 // Just started -#define TASKSTATUS_RUNNING 1 // Running task & movement -#define TASKSTATUS_RUNNING_MOVEMENT 2 // Just running movement -#define TASKSTATUS_RUNNING_TASK 3 // Just running task -#define TASKSTATUS_COMPLETE 4 // Completed, get next task - - -//========================================================= -// These are the schedule types -//========================================================= -typedef enum -{ - SCHED_NONE = 0, - SCHED_IDLE_STAND, - SCHED_IDLE_WALK, - SCHED_WAKE_ANGRY, - SCHED_WAKE_CALLED, - SCHED_ALERT_FACE, - SCHED_ALERT_SMALL_FLINCH, - SCHED_ALERT_BIG_FLINCH, - SCHED_ALERT_STAND, - SCHED_INVESTIGATE_SOUND, - SCHED_COMBAT_FACE, - SCHED_COMBAT_STAND, - SCHED_CHASE_ENEMY, - SCHED_CHASE_ENEMY_FAILED, - SCHED_VICTORY_DANCE, - SCHED_TARGET_FACE, - SCHED_TARGET_CHASE, - SCHED_SMALL_FLINCH, - SCHED_TAKE_COVER_FROM_ENEMY, - SCHED_TAKE_COVER_FROM_BEST_SOUND, - SCHED_TAKE_COVER_FROM_ORIGIN, - SCHED_COWER, // usually a last resort! - SCHED_MELEE_ATTACK1, - SCHED_MELEE_ATTACK2, - SCHED_RANGE_ATTACK1, - SCHED_RANGE_ATTACK2, - SCHED_SPECIAL_ATTACK1, - SCHED_SPECIAL_ATTACK2, - SCHED_STANDOFF, - SCHED_ARM_WEAPON, - SCHED_RELOAD, - SCHED_GUARD, - SCHED_AMBUSH, - SCHED_DIE, - SCHED_WAIT_TRIGGER, - SCHED_FOLLOW, - SCHED_SLEEP, - SCHED_WAKE, - SCHED_BARNACLE_VICTIM_GRAB, - SCHED_BARNACLE_VICTIM_CHOMP, - SCHED_AISCRIPT, - SCHED_FAIL, - - LAST_COMMON_SCHEDULE // Leave this at the bottom -} SCHEDULE_TYPE; - -//========================================================= -// These are the shared tasks -//========================================================= -typedef enum -{ - TASK_INVALID = 0, - TASK_WAIT, - TASK_WAIT_FACE_ENEMY, - TASK_WAIT_PVS, - TASK_SUGGEST_STATE, - TASK_WALK_TO_TARGET, - TASK_RUN_TO_TARGET, - TASK_MOVE_TO_TARGET_RANGE, - TASK_GET_PATH_TO_ENEMY, - TASK_GET_PATH_TO_ENEMY_LKP, - TASK_GET_PATH_TO_ENEMY_CORPSE, - TASK_GET_PATH_TO_LEADER, - TASK_GET_PATH_TO_SPOT, - TASK_GET_PATH_TO_TARGET, - TASK_GET_PATH_TO_HINTNODE, - TASK_GET_PATH_TO_LASTPOSITION, - TASK_GET_PATH_TO_BESTSOUND, - TASK_GET_PATH_TO_BESTSCENT, - TASK_RUN_PATH, - TASK_WALK_PATH, - TASK_STRAFE_PATH, - TASK_CLEAR_MOVE_WAIT, - TASK_STORE_LASTPOSITION, - TASK_CLEAR_LASTPOSITION, - TASK_PLAY_ACTIVE_IDLE, - TASK_FIND_HINTNODE, - TASK_CLEAR_HINTNODE, - TASK_SMALL_FLINCH, - TASK_FACE_IDEAL, - TASK_FACE_ROUTE, - TASK_FACE_ENEMY, - TASK_FACE_HINTNODE, - TASK_FACE_TARGET, - TASK_FACE_LASTPOSITION, - TASK_RANGE_ATTACK1, - TASK_RANGE_ATTACK2, - TASK_MELEE_ATTACK1, - TASK_MELEE_ATTACK2, - TASK_RELOAD, - TASK_RANGE_ATTACK1_NOTURN, - TASK_RANGE_ATTACK2_NOTURN, - TASK_MELEE_ATTACK1_NOTURN, - TASK_MELEE_ATTACK2_NOTURN, - TASK_RELOAD_NOTURN, - TASK_SPECIAL_ATTACK1, - TASK_SPECIAL_ATTACK2, - TASK_CROUCH, - TASK_STAND, - TASK_GUARD, - TASK_STEP_LEFT, - TASK_STEP_RIGHT, - TASK_STEP_FORWARD, - TASK_STEP_BACK, - TASK_DODGE_LEFT, - TASK_DODGE_RIGHT, - TASK_SOUND_ANGRY, - TASK_SOUND_DEATH, - TASK_SET_ACTIVITY, - TASK_SET_SCHEDULE, - TASK_SET_FAIL_SCHEDULE, - TASK_CLEAR_FAIL_SCHEDULE, - TASK_PLAY_SEQUENCE, - TASK_PLAY_SEQUENCE_FACE_ENEMY, - TASK_PLAY_SEQUENCE_FACE_TARGET, - TASK_SOUND_IDLE, - TASK_SOUND_WAKE, - TASK_SOUND_PAIN, - TASK_SOUND_DIE, - TASK_FIND_COVER_FROM_BEST_SOUND,// tries lateral cover first, then node cover - TASK_FIND_COVER_FROM_ENEMY,// tries lateral cover first, then node cover - TASK_FIND_LATERAL_COVER_FROM_ENEMY, - TASK_FIND_NODE_COVER_FROM_ENEMY, - TASK_FIND_NEAR_NODE_COVER_FROM_ENEMY,// data for this one is the MAXIMUM acceptable distance to the cover. - TASK_FIND_FAR_NODE_COVER_FROM_ENEMY,// data for this one is there MINIMUM aceptable distance to the cover. - TASK_FIND_COVER_FROM_ORIGIN, - TASK_EAT, - TASK_DIE, - TASK_WAIT_FOR_SCRIPT, - TASK_PLAY_SCRIPT, - TASK_ENABLE_SCRIPT, - TASK_PLANT_ON_SCRIPT, - TASK_FACE_SCRIPT, - TASK_WAIT_RANDOM, - TASK_WAIT_INDEFINITE, - TASK_STOP_MOVING, - TASK_TURN_LEFT, - TASK_TURN_RIGHT, - TASK_REMEMBER, - TASK_FORGET, - TASK_WAIT_FOR_MOVEMENT, // wait until MovementIsComplete() - LAST_COMMON_TASK, // LEAVE THIS AT THE BOTTOM!! (sjb) -} SHARED_TASKS; - - -// These go in the flData member of the TASK_WALK_TO_TARGET, TASK_RUN_TO_TARGET -enum -{ - TARGET_MOVE_NORMAL = 0, - TARGET_MOVE_SCRIPTED = 1, -}; - - -// A goal should be used for a task that requires several schedules to complete. -// The goal index should indicate which schedule (ordinally) the monster is running. -// That way, when tasks fail, the AI can make decisions based on the context of the -// current goal and sequence rather than just the current schedule. -enum -{ - GOAL_ATTACK_ENEMY, - GOAL_MOVE, - GOAL_TAKE_COVER, - GOAL_MOVE_TARGET, - GOAL_EAT, -}; - -// an array of tasks is a task list -// an array of schedules is a schedule list -struct Task_t -{ - - int iTask; - float flData; -}; - -struct Schedule_t -{ - - Task_t *pTasklist; - int cTasks; - int iInterruptMask;// a bit mask of conditions that can interrupt this schedule - - // a more specific mask that indicates which TYPES of sounds will interrupt the schedule in the - // event that the schedule is broken by COND_HEAR_SOUND - int iSoundMask; - const char *pName; -}; - -// an array of waypoints makes up the monster's route. -// !!!LATER- this declaration doesn't belong in this file. -struct WayPoint_t -{ - Vector vecLocation; - int iType; -}; - -// these MoveFlag values are assigned to a WayPoint's TYPE in order to demonstrate the -// type of movement the monster should use to get there. -#define bits_MF_TO_TARGETENT ( 1 << 0 ) // local move to targetent. -#define bits_MF_TO_ENEMY ( 1 << 1 ) // local move to enemy -#define bits_MF_TO_COVER ( 1 << 2 ) // local move to a hiding place -#define bits_MF_TO_DETOUR ( 1 << 3 ) // local move to detour point. -#define bits_MF_TO_PATHCORNER ( 1 << 4 ) // local move to a path corner -#define bits_MF_TO_NODE ( 1 << 5 ) // local move to a node -#define bits_MF_TO_LOCATION ( 1 << 6 ) // local move to an arbitrary point -#define bits_MF_IS_GOAL ( 1 << 7 ) // this waypoint is the goal of the whole move. -#define bits_MF_DONT_SIMPLIFY ( 1 << 8 ) // Don't let the route code simplify this waypoint - -// If you define any flags that aren't _TO_ flags, add them here so we can mask -// them off when doing compares. -#define bits_MF_NOT_TO_MASK (bits_MF_IS_GOAL | bits_MF_DONT_SIMPLIFY) - -#define MOVEGOAL_NONE (0) -#define MOVEGOAL_TARGETENT (bits_MF_TO_TARGETENT) -#define MOVEGOAL_ENEMY (bits_MF_TO_ENEMY) -#define MOVEGOAL_PATHCORNER (bits_MF_TO_PATHCORNER) -#define MOVEGOAL_LOCATION (bits_MF_TO_LOCATION) -#define MOVEGOAL_NODE (bits_MF_TO_NODE) - -// these bits represent conditions that may befall the monster, of which some are allowed -// to interrupt certain schedules. -#define bits_COND_NO_AMMO_LOADED ( 1 << 0 ) // weapon needs to be reloaded! -#define bits_COND_SEE_HATE ( 1 << 1 ) // see something that you hate -#define bits_COND_SEE_FEAR ( 1 << 2 ) // see something that you are afraid of -#define bits_COND_SEE_DISLIKE ( 1 << 3 ) // see something that you dislike -#define bits_COND_SEE_ENEMY ( 1 << 4 ) // target entity is in full view. -#define bits_COND_ENEMY_OCCLUDED ( 1 << 5 ) // target entity occluded by the world -#define bits_COND_SMELL_FOOD ( 1 << 6 ) -#define bits_COND_ENEMY_TOOFAR ( 1 << 7 ) -#define bits_COND_LIGHT_DAMAGE ( 1 << 8 ) // hurt a little -#define bits_COND_HEAVY_DAMAGE ( 1 << 9 ) // hurt a lot -#define bits_COND_CAN_RANGE_ATTACK1 ( 1 << 10) -#define bits_COND_CAN_MELEE_ATTACK1 ( 1 << 11) -#define bits_COND_CAN_RANGE_ATTACK2 ( 1 << 12) -#define bits_COND_CAN_MELEE_ATTACK2 ( 1 << 13) -// #define bits_COND_CAN_RANGE_ATTACK3 ( 1 << 14) -#define bits_COND_PROVOKED ( 1 << 15) -#define bits_COND_NEW_ENEMY ( 1 << 16) -#define bits_COND_HEAR_SOUND ( 1 << 17) // there is an interesting sound -#define bits_COND_SMELL ( 1 << 18) // there is an interesting scent -#define bits_COND_ENEMY_FACING_ME ( 1 << 19) // enemy is facing me -#define bits_COND_ENEMY_DEAD ( 1 << 20) // enemy was killed. If you get this in combat, try to find another enemy. If you get it in alert, victory dance. -#define bits_COND_SEE_CLIENT ( 1 << 21) // see a client -#define bits_COND_SEE_NEMESIS ( 1 << 22) // see my nemesis - -#define bits_COND_SPECIAL1 ( 1 << 28) // Defined by individual monster -#define bits_COND_SPECIAL2 ( 1 << 29) // Defined by individual monster - -#define bits_COND_TASK_FAILED ( 1 << 30) -#define bits_COND_SCHEDULE_DONE ( 1 << 31) - - -#define bits_COND_ALL_SPECIAL (bits_COND_SPECIAL1 | bits_COND_SPECIAL2) - -#define bits_COND_CAN_ATTACK (bits_COND_CAN_RANGE_ATTACK1 | bits_COND_CAN_MELEE_ATTACK1 | bits_COND_CAN_RANGE_ATTACK2 | bits_COND_CAN_MELEE_ATTACK2) - -#endif // SCHEDULE_H diff --git a/dmc/dlls/scripted.cpp b/dmc/dlls/scripted.cpp deleted file mode 100644 index 10659f5..0000000 --- a/dmc/dlls/scripted.cpp +++ /dev/null @@ -1,1260 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -/* - - -===== scripted.cpp ======================================================== - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" - -#ifndef ANIMATION_H -#include "animation.h" -#endif - -#ifndef SAVERESTORE_H -#include "saverestore.h" -#endif - -#include "schedule.h" -#include "scripted.h" -#include "defaultai.h" - - - -/* -classname "scripted_sequence" -targetname "me" - there can be more than one with the same name, and they act in concert -target "the_entity_I_want_to_start_playing" or "class entity_classname" will pick the closest inactive scientist -play "name_of_sequence" -idle "name of idle sequence to play before starting" -donetrigger "whatever" - can be any other triggerable entity such as another sequence, train, door, or a special case like "die" or "remove" -moveto - if set the monster first moves to this nodes position -range # - only search this far to find the target -spawnflags - (stop if blocked, stop if player seen) -*/ - - -// -// Cache user-entity-field values until spawn is called. -// - -void CCineMonster :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "m_iszIdle")) - { - m_iszIdle = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_iszPlay")) - { - m_iszPlay = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_iszEntity")) - { - m_iszEntity = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_fMoveTo")) - { - m_fMoveTo = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_flRepeat")) - { - m_flRepeat = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_flRadius")) - { - m_flRadius = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_iFinishSchedule")) - { - m_iFinishSchedule = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - { - CBaseMonster::KeyValue( pkvd ); - } -} - -TYPEDESCRIPTION CCineMonster::m_SaveData[] = -{ - DEFINE_FIELD( CCineMonster, m_iszIdle, FIELD_STRING ), - DEFINE_FIELD( CCineMonster, m_iszPlay, FIELD_STRING ), - DEFINE_FIELD( CCineMonster, m_iszEntity, FIELD_STRING ), - DEFINE_FIELD( CCineMonster, m_fMoveTo, FIELD_INTEGER ), - DEFINE_FIELD( CCineMonster, m_flRepeat, FIELD_FLOAT ), - DEFINE_FIELD( CCineMonster, m_flRadius, FIELD_FLOAT ), - - DEFINE_FIELD( CCineMonster, m_iDelay, FIELD_INTEGER ), - DEFINE_FIELD( CCineMonster, m_startTime, FIELD_TIME ), - - DEFINE_FIELD( CCineMonster, m_saved_movetype, FIELD_INTEGER ), - DEFINE_FIELD( CCineMonster, m_saved_solid, FIELD_INTEGER ), - DEFINE_FIELD( CCineMonster, m_saved_effects, FIELD_INTEGER ), - DEFINE_FIELD( CCineMonster, m_iFinishSchedule, FIELD_INTEGER ), - DEFINE_FIELD( CCineMonster, m_interruptable, FIELD_BOOLEAN ), -}; - - -IMPLEMENT_SAVERESTORE( CCineMonster, CBaseMonster ); - -LINK_ENTITY_TO_CLASS( scripted_sequence, CCineMonster ); -#define CLASSNAME "scripted_sequence" - -LINK_ENTITY_TO_CLASS( aiscripted_sequence, CCineAI ); - - -void CCineMonster :: Spawn( void ) -{ - // pev->solid = SOLID_TRIGGER; - // UTIL_SetSize(pev, Vector(-8, -8, -8), Vector(8, 8, 8)); - pev->solid = SOLID_NOT; - - - // REMOVE: The old side-effect -#if 0 - if ( m_iszIdle ) - m_fMoveTo = 4; -#endif - - // if no targetname, start now - if ( FStringNull(pev->targetname) || !FStringNull( m_iszIdle ) ) - { - SetThink( CineThink ); - pev->nextthink = gpGlobals->time + 1.0; - // Wait to be used? - if ( pev->targetname ) - m_startTime = gpGlobals->time + 1E6; - } - if ( pev->spawnflags & SF_SCRIPT_NOINTERRUPT ) - m_interruptable = FALSE; - else - m_interruptable = TRUE; -} - -//========================================================= -// FCanOverrideState - returns FALSE, scripted sequences -// cannot possess entities regardless of state. -//========================================================= -BOOL CCineMonster :: FCanOverrideState( void ) -{ - if ( pev->spawnflags & SF_SCRIPT_OVERRIDESTATE ) - return TRUE; - return FALSE; -} - -//========================================================= -// FCanOverrideState - returns true because scripted AI can -// possess entities regardless of their state. -//========================================================= -BOOL CCineAI :: FCanOverrideState( void ) -{ - return TRUE; -} - - -// -// CineStart -// -void CCineMonster :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // do I already know who I should use - CBaseEntity *pEntity = m_hTargetEnt; - CBaseMonster *pTarget = NULL; - - if ( pEntity ) - pTarget = pEntity->MyMonsterPointer(); - - if ( pTarget ) - { - // am I already playing the script? - if ( pTarget->m_scriptState == SCRIPT_PLAYING ) - return; - - m_startTime = gpGlobals->time + 0.05; - } - else - { - // if not, try finding them - SetThink( CineThink ); - pev->nextthink = gpGlobals->time; - } -} - - -// This doesn't really make sense since only MOVETYPE_PUSH get 'Blocked' events -void CCineMonster :: Blocked( CBaseEntity *pOther ) -{ - -} - -void CCineMonster :: Touch( CBaseEntity *pOther ) -{ -/* - ALERT( at_aiconsole, "Cine Touch\n" ); - if (m_pentTarget && OFFSET(pOther->pev) == OFFSET(m_pentTarget)) - { - CBaseMonster *pTarget = GetClassPtr((CBaseMonster *)VARS(m_pentTarget)); - pTarget->m_monsterState == MONSTERSTATE_SCRIPT; - } -*/ -} - - -/* - entvars_t *pevOther = VARS( gpGlobals->other ); - - if ( !FBitSet ( pevOther->flags , FL_MONSTER ) ) - {// touched by a non-monster. - return; - } - - pevOther->origin.z += 1; - - if ( FBitSet ( pevOther->flags, FL_ONGROUND ) ) - {// clear the onground so physics don't bitch - pevOther->flags -= FL_ONGROUND; - } - - // toss the monster! - pevOther->velocity = pev->movedir * pev->speed; - pevOther->velocity.z += m_flHeight; - - - pev->solid = SOLID_NOT;// kill the trigger for now !!!UNDONE -} -*/ - - -// -// ********** Cinematic DIE ********** -// -void CCineMonster :: Die( void ) -{ - SetThink( SUB_Remove ); -} - -// -// ********** Cinematic PAIN ********** -// -void CCineMonster :: Pain( void ) -{ - -} - -// -// ********** Cinematic Think ********** -// - -// find a viable entity -int CCineMonster :: FindEntity( void ) -{ - edict_t *pentTarget; - - pentTarget = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszEntity)); - m_hTargetEnt = NULL; - CBaseMonster *pTarget = NULL; - - while (!FNullEnt(pentTarget)) - { - if ( FBitSet( VARS(pentTarget)->flags, FL_MONSTER )) - { - pTarget = GetMonsterPointer( pentTarget ); - if ( pTarget && pTarget->CanPlaySequence( FCanOverrideState(), SS_INTERRUPT_BY_NAME ) ) - { - m_hTargetEnt = pTarget; - return TRUE; - } - ALERT( at_console, "Found %s, but can't play!\n", STRING(m_iszEntity) ); - } - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(m_iszEntity)); - pTarget = NULL; - } - - if ( !pTarget ) - { - CBaseEntity *pEntity = NULL; - while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, m_flRadius )) != NULL) - { - if (FClassnameIs( pEntity->pev, STRING(m_iszEntity))) - { - if ( FBitSet( pEntity->pev->flags, FL_MONSTER )) - { - pTarget = pEntity->MyMonsterPointer( ); - if ( pTarget && pTarget->CanPlaySequence( FCanOverrideState(), SS_INTERRUPT_IDLE ) ) - { - m_hTargetEnt = pTarget; - return TRUE; - } - } - } - } - } - pTarget = NULL; - m_hTargetEnt = NULL; - return FALSE; -} - -// make the entity enter a scripted sequence -void CCineMonster :: PossessEntity( void ) -{ - CBaseEntity *pEntity = m_hTargetEnt; - CBaseMonster *pTarget = NULL; - if ( pEntity ) - pTarget = pEntity->MyMonsterPointer(); - - if ( pTarget ) - { - - // FindEntity() just checked this! -#if 0 - if ( !pTarget->CanPlaySequence( FCanOverrideState() ) ) - { - ALERT( at_aiconsole, "Can't possess entity %s\n", STRING(pTarget->pev->classname) ); - return; - } -#endif - - pTarget->m_pGoalEnt = this; - pTarget->m_pCine = this; - pTarget->m_hTargetEnt = this; - - m_saved_movetype = pTarget->pev->movetype; - m_saved_solid = pTarget->pev->solid; - m_saved_effects = pTarget->pev->effects; - pTarget->pev->effects |= pev->effects; - - switch (m_fMoveTo) - { - case 0: - pTarget->m_scriptState = SCRIPT_WAIT; - break; - - case 1: - pTarget->m_scriptState = SCRIPT_WALK_TO_MARK; - DelayStart( 1 ); - break; - - case 2: - pTarget->m_scriptState = SCRIPT_RUN_TO_MARK; - DelayStart( 1 ); - break; - - case 4: - UTIL_SetOrigin( pTarget->pev, pev->origin ); - pTarget->pev->ideal_yaw = pev->angles.y; - pTarget->pev->avelocity = Vector( 0, 0, 0 ); - pTarget->pev->velocity = Vector( 0, 0, 0 ); - pTarget->pev->effects |= EF_NOINTERP; - pTarget->pev->angles.y = pev->angles.y; - pTarget->m_scriptState = SCRIPT_WAIT; - m_startTime = gpGlobals->time + 1E6; - // UNDONE: Add a flag to do this so people can fixup physics after teleporting monsters - // pTarget->pev->flags &= ~FL_ONGROUND; - break; - } -// ALERT( at_aiconsole, "\"%s\" found and used (INT: %s)\n", STRING( pTarget->pev->targetname ), FBitSet(pev->spawnflags, SF_SCRIPT_NOINTERRUPT)?"No":"Yes" ); - - pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT; - if (m_iszIdle) - { - StartSequence( pTarget, m_iszIdle, FALSE ); - if (FStrEq( STRING(m_iszIdle), STRING(m_iszPlay))) - { - pTarget->pev->framerate = 0; - } - } - } -} - -// make the entity carry out the scripted sequence instructions, but without -// destroying the monster's state. -void CCineAI :: PossessEntity( void ) -{ - Schedule_t *pNewSchedule; - - CBaseEntity *pEntity = m_hTargetEnt; - CBaseMonster *pTarget = NULL; - if ( pEntity ) - pTarget = pEntity->MyMonsterPointer(); - - if ( pTarget ) - { - if ( !pTarget->CanPlaySequence( FCanOverrideState(), SS_INTERRUPT_AI ) ) - { - ALERT( at_aiconsole, "(AI)Can't possess entity %s\n", STRING(pTarget->pev->classname) ); - return; - } - - pTarget->m_pGoalEnt = this; - pTarget->m_pCine = this; - pTarget->m_hTargetEnt = this; - - m_saved_movetype = pTarget->pev->movetype; - m_saved_solid = pTarget->pev->solid; - m_saved_effects = pTarget->pev->effects; - pTarget->pev->effects |= pev->effects; - - switch (m_fMoveTo) - { - case 0: - case 5: - pTarget->m_scriptState = SCRIPT_WAIT; - break; - - case 1: - pTarget->m_scriptState = SCRIPT_WALK_TO_MARK; - break; - - case 2: - pTarget->m_scriptState = SCRIPT_RUN_TO_MARK; - break; - - case 4: - // zap the monster instantly to the site of the script entity. - UTIL_SetOrigin( pTarget->pev, pev->origin ); - pTarget->pev->ideal_yaw = pev->angles.y; - pTarget->pev->avelocity = Vector( 0, 0, 0 ); - pTarget->pev->velocity = Vector( 0, 0, 0 ); - pTarget->pev->effects |= EF_NOINTERP; - pTarget->pev->angles.y = pev->angles.y; - pTarget->m_scriptState = SCRIPT_WAIT; - m_startTime = gpGlobals->time + 1E6; - // UNDONE: Add a flag to do this so people can fixup physics after teleporting monsters - pTarget->pev->flags &= ~FL_ONGROUND; - break; - default: - ALERT ( at_aiconsole, "aiscript: invalid Move To Position value!" ); - break; - } - - ALERT( at_aiconsole, "\"%s\" found and used\n", STRING( pTarget->pev->targetname ) ); - - pTarget->m_IdealMonsterState = MONSTERSTATE_SCRIPT; - -/* - if (m_iszIdle) - { - StartSequence( pTarget, m_iszIdle, FALSE ); - if (FStrEq( STRING(m_iszIdle), STRING(m_iszPlay))) - { - pTarget->pev->framerate = 0; - } - } -*/ - // Already in a scripted state? - if ( pTarget->m_MonsterState == MONSTERSTATE_SCRIPT ) - { - pNewSchedule = pTarget->GetScheduleOfType( SCHED_AISCRIPT ); - pTarget->ChangeSchedule( pNewSchedule ); - } - } -} - -void CCineMonster :: CineThink( void ) -{ - if (FindEntity()) - { - PossessEntity( ); - ALERT( at_aiconsole, "script \"%s\" using monster \"%s\"\n", STRING( pev->targetname ), STRING( m_iszEntity ) ); - } - else - { - CancelScript( ); - ALERT( at_aiconsole, "script \"%s\" can't find monster \"%s\"\n", STRING( pev->targetname ), STRING( m_iszEntity ) ); - pev->nextthink = gpGlobals->time + 1.0; - } -} - - -// lookup a sequence name and setup the target monster to play it -BOOL CCineMonster :: StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty ) -{ - if ( !iszSeq && completeOnEmpty ) - { - SequenceDone( pTarget ); - return FALSE; - } - - pTarget->pev->sequence = pTarget->LookupSequence( STRING( iszSeq ) ); - if (pTarget->pev->sequence == -1) - { - ALERT( at_error, "%s: unknown scripted sequence \"%s\"\n", STRING( pTarget->pev->targetname ), STRING( iszSeq) ); - pTarget->pev->sequence = 0; - // return FALSE; - } - -#if 0 - char *s; - if ( pev->spawnflags & SF_SCRIPT_NOINTERRUPT ) - s = "No"; - else - s = "Yes"; - - ALERT( at_console, "%s (%s): started \"%s\":INT:%s\n", STRING( pTarget->pev->targetname ), STRING( pTarget->pev->classname ), STRING( iszSeq), s ); -#endif - - pTarget->pev->frame = 0; - pTarget->ResetSequenceInfo( ); - return TRUE; -} - -// lookup a sequence name and setup the target monster to play it -// overridden for CCineAI because it's ok for them to not have an animation sequence -// for the monster to play. For a regular Scripted Sequence, that situation is an error. -BOOL CCineAI :: StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty ) -{ - if ( iszSeq == 0 && completeOnEmpty ) - { - // no sequence was provided. Just let the monster proceed, however, we still have to fire any Sequence target - // and remove any non-repeatable CineAI entities here ( because there is code elsewhere that handles those tasks, but - // not until the animation sequence is finished. We have to manually take care of these things where there is no sequence. - - SequenceDone ( pTarget ); - - return TRUE; - } - - pTarget->pev->sequence = pTarget->LookupSequence( STRING( iszSeq ) ); - - if (pTarget->pev->sequence == -1) - { - ALERT( at_error, "%s: unknown aiscripted sequence \"%s\"\n", STRING( pTarget->pev->targetname ), STRING( iszSeq) ); - pTarget->pev->sequence = 0; - // return FALSE; - } - - pTarget->pev->frame = 0; - pTarget->ResetSequenceInfo( ); - return TRUE; -} - -//========================================================= -// SequenceDone - called when a scripted sequence animation -// sequence is done playing ( or when an AI Scripted Sequence -// doesn't supply an animation sequence to play ). Expects -// the CBaseMonster pointer to the monster that the sequence -// possesses. -//========================================================= -void CCineMonster :: SequenceDone ( CBaseMonster *pMonster ) -{ - //ALERT( at_aiconsole, "Sequence %s finished\n", STRING( m_pCine->m_iszPlay ) ); - - if ( !( pev->spawnflags & SF_SCRIPT_REPEATABLE ) ) - { - SetThink( SUB_Remove ); - pev->nextthink = gpGlobals->time + 0.1; - } - - // This is done so that another sequence can take over the monster when triggered by the first - - pMonster->CineCleanup(); - - FixScriptMonsterSchedule( pMonster ); - - // This may cause a sequence to attempt to grab this guy NOW, so we have to clear him out - // of the existing sequence - SUB_UseTargets( NULL, USE_TOGGLE, 0 ); -} - -//========================================================= -// When a monster finishes a scripted sequence, we have to -// fix up its state and schedule for it to return to a -// normal AI monster. -// -// Scripted sequences just dirty the Schedule and drop the -// monster in Idle State. -//========================================================= -void CCineMonster :: FixScriptMonsterSchedule( CBaseMonster *pMonster ) -{ - if ( pMonster->m_IdealMonsterState != MONSTERSTATE_DEAD ) - pMonster->m_IdealMonsterState = MONSTERSTATE_IDLE; - pMonster->ClearSchedule(); -} - -//========================================================= -// When a monster finishes a scripted sequence, we have to -// fix up its state and schedule for it to return to a -// normal AI monster. -// -// AI Scripted sequences will, depending on what the level -// designer selects: -// -// -Dirty the monster's schedule and drop out of the -// sequence in their current state. -// -// -Select a specific AMBUSH schedule, regardless of state. -//========================================================= -void CCineAI :: FixScriptMonsterSchedule( CBaseMonster *pMonster ) -{ - switch ( m_iFinishSchedule ) - { - case SCRIPT_FINISHSCHED_DEFAULT: - pMonster->ClearSchedule(); - break; - case SCRIPT_FINISHSCHED_AMBUSH: - pMonster->ChangeSchedule( pMonster->GetScheduleOfType( SCHED_AMBUSH ) ); - break; - default: - ALERT ( at_aiconsole, "FixScriptMonsterSchedule - no case!\n" ); - pMonster->ClearSchedule(); - break; - } -} - -BOOL CBaseMonster :: ExitScriptedSequence( ) -{ - if ( pev->deadflag == DEAD_DYING ) - { - // is this legal? - // BUGBUG -- This doesn't call Killed() - m_IdealMonsterState = MONSTERSTATE_DEAD; - return FALSE; - } - - if (m_pCine) - { - m_pCine->CancelScript( ); - } - - return TRUE; -} - - -void CCineMonster::AllowInterrupt( BOOL fAllow ) -{ - if ( pev->spawnflags & SF_SCRIPT_NOINTERRUPT ) - return; - m_interruptable = fAllow; -} - - -BOOL CCineMonster::CanInterrupt( void ) -{ - if ( !m_interruptable ) - return FALSE; - - CBaseEntity *pTarget = m_hTargetEnt; - - if ( pTarget != NULL && pTarget->pev->deadflag == DEAD_NO ) - return TRUE; - - return FALSE; -} - - -int CCineMonster::IgnoreConditions( void ) -{ - if ( CanInterrupt() ) - return 0; - return SCRIPT_BREAK_CONDITIONS; -} - - -void ScriptEntityCancel( edict_t *pentCine ) -{ - // make sure they are a scripted_sequence - if (FClassnameIs( pentCine, CLASSNAME )) - { - CCineMonster *pCineTarget = GetClassPtr((CCineMonster *)VARS(pentCine)); - // make sure they have a monster in mind for the script - CBaseEntity *pEntity = pCineTarget->m_hTargetEnt; - CBaseMonster *pTarget = NULL; - if ( pEntity ) - pTarget = pEntity->MyMonsterPointer(); - - if (pTarget) - { - // make sure their monster is actually playing a script - if ( pTarget->m_MonsterState == MONSTERSTATE_SCRIPT ) - { - // tell them do die - pTarget->m_scriptState = CCineMonster::SCRIPT_CLEANUP; - // do it now - pTarget->CineCleanup( ); - } - } - } -} - - -// find all the cinematic entities with my targetname and stop them from playing -void CCineMonster :: CancelScript( void ) -{ - ALERT( at_aiconsole, "Cancelling script: %s\n", STRING(m_iszPlay) ); - - if ( !pev->targetname ) - { - ScriptEntityCancel( edict() ); - return; - } - - edict_t *pentCineTarget = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(pev->targetname)); - - while (!FNullEnt(pentCineTarget)) - { - ScriptEntityCancel( pentCineTarget ); - pentCineTarget = FIND_ENTITY_BY_TARGETNAME(pentCineTarget, STRING(pev->targetname)); - } -} - - -// find all the cinematic entities with my targetname and tell them to wait before starting -void CCineMonster :: DelayStart( int state ) -{ - edict_t *pentCine = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(pev->targetname)); - - while (!FNullEnt(pentCine)) - { - if (FClassnameIs( pentCine, "scripted_sequence" )) - { - CCineMonster *pTarget = GetClassPtr((CCineMonster *)VARS(pentCine)); - if (state) - { - pTarget->m_iDelay++; - } - else - { - pTarget->m_iDelay--; - if (pTarget->m_iDelay <= 0) - pTarget->m_startTime = gpGlobals->time + 0.05; - } - } - pentCine = FIND_ENTITY_BY_TARGETNAME(pentCine, STRING(pev->targetname)); - } -} - - - -// Find an entity that I'm interested in and precache the sounds he'll need in the sequence. -void CCineMonster :: Activate( void ) -{ - edict_t *pentTarget; - CBaseMonster *pTarget; - - // The entity name could be a target name or a classname - // Check the targetname - pentTarget = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszEntity)); - pTarget = NULL; - - while (!pTarget && !FNullEnt(pentTarget)) - { - if ( FBitSet( VARS(pentTarget)->flags, FL_MONSTER )) - { - pTarget = GetMonsterPointer( pentTarget ); - } - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(m_iszEntity)); - } - - // If no entity with that targetname, check the classname - if ( !pTarget ) - { - pentTarget = FIND_ENTITY_BY_CLASSNAME(NULL, STRING(m_iszEntity)); - while (!pTarget && !FNullEnt(pentTarget)) - { - pTarget = GetMonsterPointer( pentTarget ); - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(m_iszEntity)); - } - } - // Found a compatible entity - if ( pTarget ) - { - void *pmodel; - pmodel = GET_MODEL_PTR( pTarget->edict() ); - if ( pmodel ) - { - // Look through the event list for stuff to precache - SequencePrecache( pmodel, STRING( m_iszIdle ) ); - SequencePrecache( pmodel, STRING( m_iszPlay ) ); - } - } -} - - -BOOL CBaseMonster :: CineCleanup( ) -{ - CCineMonster *pOldCine = m_pCine; - - // am I linked to a cinematic? - if (m_pCine) - { - // okay, reset me to what it thought I was before - m_pCine->m_hTargetEnt = NULL; - pev->movetype = m_pCine->m_saved_movetype; - pev->solid = m_pCine->m_saved_solid; - pev->effects = m_pCine->m_saved_effects; - } - else - { - // arg, punt - pev->movetype = MOVETYPE_STEP;// this is evil - pev->solid = SOLID_SLIDEBOX; - } - m_pCine = NULL; - m_hTargetEnt = NULL; - m_pGoalEnt = NULL; - if (pev->deadflag == DEAD_DYING) - { - // last frame of death animation? - pev->health = 0; - pev->framerate = 0.0; - pev->solid = SOLID_NOT; - SetState( MONSTERSTATE_DEAD ); - pev->deadflag = DEAD_DEAD; - UTIL_SetSize( pev, pev->mins, Vector(pev->maxs.x, pev->maxs.y, pev->mins.z + 2) ); - - if ( pOldCine && FBitSet( pOldCine->pev->spawnflags, SF_SCRIPT_LEAVECORPSE ) ) - { - SetUse( NULL ); // BUGBUG -- This doesn't call Killed() - SetThink( NULL ); // This will probably break some stuff - SetTouch( NULL ); - } - else - SUB_StartFadeOut(); // SetThink( SUB_DoNothing ); - // This turns off animation & physics in case their origin ends up stuck in the world or something - StopAnimation(); - pev->movetype = MOVETYPE_NONE; - pev->effects |= EF_NOINTERP; // Don't interpolate either, assume the corpse is positioned in its final resting place - return FALSE; - } - - // If we actually played a sequence - if ( pOldCine && pOldCine->m_iszPlay ) - { - if ( !(pOldCine->pev->spawnflags & SF_SCRIPT_NOSCRIPTMOVEMENT) ) - { - // reset position - Vector new_origin, new_angle; - GetBonePosition( 0, new_origin, new_angle ); - - // Figure out how far they have moved - // We can't really solve this problem because we can't query the movement of the origin relative - // to the sequence. We can get the root bone's position as we do here, but there are - // cases where the root bone is in a different relative position to the entity's origin - // before/after the sequence plays. So we are stuck doing this: - - // !!!HACKHACK: Float the origin up and drop to floor because some sequences have - // irregular motion that can't be properly accounted for. - - // UNDONE: THIS SHOULD ONLY HAPPEN IF WE ACTUALLY PLAYED THE SEQUENCE. - Vector oldOrigin = pev->origin; - - // UNDONE: ugly hack. Don't move monster if they don't "seem" to move - // this really needs to be done with the AX,AY,etc. flags, but that aren't consistantly - // being set, so animations that really do move won't be caught. - if ((oldOrigin - new_origin).Length2D() < 8.0) - new_origin = oldOrigin; - - pev->origin.x = new_origin.x; - pev->origin.y = new_origin.y; - pev->origin.z += 1; - - pev->flags |= FL_ONGROUND; - int drop = DROP_TO_FLOOR( ENT(pev) ); - - // Origin in solid? Set to org at the end of the sequence - if ( drop < 0 ) - pev->origin = oldOrigin; - else if ( drop == 0 ) // Hanging in air? - { - pev->origin.z = new_origin.z; - pev->flags &= ~FL_ONGROUND; - } - // else entity hit floor, leave there - - // pEntity->pev->origin.z = new_origin.z + 5.0; // damn, got to fix this - - UTIL_SetOrigin( pev, pev->origin ); - pev->effects |= EF_NOINTERP; - } - - // We should have some animation to put these guys in, but for now it's idle. - // Due to NOINTERP above, there won't be any blending between this anim & the sequence - m_Activity = ACT_RESET; - } - // set them back into a normal state - pev->enemy = NULL; - if ( pev->health > 0 ) - m_IdealMonsterState = MONSTERSTATE_IDLE; // m_previousState; - else - { - // Dropping out because he got killed - // Can't call killed() no attacker and weirdness (late gibbing) may result - m_IdealMonsterState = MONSTERSTATE_DEAD; - SetConditions( bits_COND_LIGHT_DAMAGE ); - pev->deadflag = DEAD_DYING; - FCheckAITrigger(); - pev->deadflag = DEAD_NO; - } - - - // SetAnimation( m_MonsterState ); - ClearBits(pev->spawnflags, SF_MONSTER_WAIT_FOR_SCRIPT ); - - return TRUE; -} - - - - -class CScriptedSentence : public CBaseToggle -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT FindThink( void ); - void EXPORT DelayThink( void ); - int ObjectCaps( void ) { return (CBaseToggle :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - CBaseMonster *FindEntity( void ); - BOOL AcceptableSpeaker( CBaseMonster *pMonster ); - BOOL StartSentence( CBaseMonster *pTarget ); - - -private: - int m_iszSentence; // string index for idle animation - int m_iszEntity; // entity that is wanted for this sentence - float m_flRadius; // range to search - float m_flDuration; // How long the sentence lasts - float m_flRepeat; // repeat rate - float m_flAttenuation; - float m_flVolume; - BOOL m_active; - int m_iszListener; // name of entity to look at while talking -}; - -#define SF_SENTENCE_ONCE 0x0001 -#define SF_SENTENCE_FOLLOWERS 0x0002 // only say if following player -#define SF_SENTENCE_INTERRUPT 0x0004 // force talking except when dead -#define SF_SENTENCE_CONCURRENT 0x0008 // allow other people to keep talking - -TYPEDESCRIPTION CScriptedSentence::m_SaveData[] = -{ - DEFINE_FIELD( CScriptedSentence, m_iszSentence, FIELD_STRING ), - DEFINE_FIELD( CScriptedSentence, m_iszEntity, FIELD_STRING ), - DEFINE_FIELD( CScriptedSentence, m_flRadius, FIELD_FLOAT ), - DEFINE_FIELD( CScriptedSentence, m_flDuration, FIELD_FLOAT ), - DEFINE_FIELD( CScriptedSentence, m_flRepeat, FIELD_FLOAT ), - DEFINE_FIELD( CScriptedSentence, m_flAttenuation, FIELD_FLOAT ), - DEFINE_FIELD( CScriptedSentence, m_flVolume, FIELD_FLOAT ), - DEFINE_FIELD( CScriptedSentence, m_active, FIELD_BOOLEAN ), - DEFINE_FIELD( CScriptedSentence, m_iszListener, FIELD_STRING ), -}; - - -IMPLEMENT_SAVERESTORE( CScriptedSentence, CBaseToggle ); - -LINK_ENTITY_TO_CLASS( scripted_sentence, CScriptedSentence ); - -void CScriptedSentence :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "sentence")) - { - m_iszSentence = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "entity")) - { - m_iszEntity = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "duration")) - { - m_flDuration = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "radius")) - { - m_flRadius = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "refire")) - { - m_flRepeat = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if(FStrEq(pkvd->szKeyName, "attenuation")) - { - pev->impulse = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if(FStrEq(pkvd->szKeyName, "volume")) - { - m_flVolume = atof( pkvd->szValue ) * 0.1; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "listener")) - { - m_iszListener = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - - -void CScriptedSentence :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !m_active ) - return; -// ALERT( at_console, "Firing sentence: %s\n", STRING(m_iszSentence) ); - SetThink( FindThink ); - pev->nextthink = gpGlobals->time; -} - - -void CScriptedSentence :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - - m_active = TRUE; - // if no targetname, start now - if ( !pev->targetname ) - { - SetThink( FindThink ); - pev->nextthink = gpGlobals->time + 1.0; - } - - switch( pev->impulse ) - { - case 1: // Medium radius - m_flAttenuation = ATTN_STATIC; - break; - - case 2: // Large radius - m_flAttenuation = ATTN_NORM; - break; - - case 3: //EVERYWHERE - m_flAttenuation = ATTN_NONE; - break; - - default: - case 0: // Small radius - m_flAttenuation = ATTN_IDLE; - break; - } - pev->impulse = 0; - - // No volume, use normal - if ( m_flVolume <= 0 ) - m_flVolume = 1.0; -} - - -void CScriptedSentence :: FindThink( void ) -{ - CBaseMonster *pMonster = FindEntity(); - if ( pMonster ) - { - StartSentence( pMonster ); - if ( pev->spawnflags & SF_SENTENCE_ONCE ) - UTIL_Remove( this ); - SetThink( DelayThink ); - pev->nextthink = gpGlobals->time + m_flDuration + m_flRepeat; - m_active = FALSE; -// ALERT( at_console, "%s: found monster %s\n", STRING(m_iszSentence), STRING(m_iszEntity) ); - } - else - { -// ALERT( at_console, "%s: can't find monster %s\n", STRING(m_iszSentence), STRING(m_iszEntity) ); - pev->nextthink = gpGlobals->time + m_flRepeat + 0.5; - } -} - - -void CScriptedSentence :: DelayThink( void ) -{ - m_active = TRUE; - if ( !pev->targetname ) - pev->nextthink = gpGlobals->time + 0.1; - SetThink( FindThink ); -} - - -BOOL CScriptedSentence :: AcceptableSpeaker( CBaseMonster *pMonster ) -{ - if ( pMonster ) - { - if ( pev->spawnflags & SF_SENTENCE_FOLLOWERS ) - { - if ( pMonster->m_hTargetEnt == NULL || !FClassnameIs(pMonster->m_hTargetEnt->pev, "player") ) - return FALSE; - } - BOOL override; - if ( pev->spawnflags & SF_SENTENCE_INTERRUPT ) - override = TRUE; - else - override = FALSE; - if ( pMonster->CanPlaySentence( override ) ) - return TRUE; - } - return FALSE; -} - - -CBaseMonster *CScriptedSentence :: FindEntity( void ) -{ - edict_t *pentTarget; - CBaseMonster *pMonster; - - - pentTarget = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(m_iszEntity)); - pMonster = NULL; - - while (!FNullEnt(pentTarget)) - { - pMonster = GetMonsterPointer( pentTarget ); - if ( pMonster != NULL ) - { - if ( AcceptableSpeaker( pMonster ) ) - return pMonster; -// ALERT( at_console, "%s (%s), not acceptable\n", STRING(pMonster->pev->classname), STRING(pMonster->pev->targetname) ); - } - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(m_iszEntity)); - } - - CBaseEntity *pEntity = NULL; - while ((pEntity = UTIL_FindEntityInSphere( pEntity, pev->origin, m_flRadius )) != NULL) - { - if (FClassnameIs( pEntity->pev, STRING(m_iszEntity))) - { - if ( FBitSet( pEntity->pev->flags, FL_MONSTER )) - { - pMonster = pEntity->MyMonsterPointer( ); - if ( AcceptableSpeaker( pMonster ) ) - return pMonster; - } - } - } - - return NULL; -} - - -BOOL CScriptedSentence :: StartSentence( CBaseMonster *pTarget ) -{ - if ( !pTarget ) - { - ALERT( at_aiconsole, "Not Playing sentence %s\n", STRING(m_iszSentence) ); - return NULL; - } - - BOOL bConcurrent = FALSE; - if ( !(pev->spawnflags & SF_SENTENCE_CONCURRENT) ) - bConcurrent = TRUE; - - CBaseEntity *pListener = NULL; - if (!FStringNull(m_iszListener)) - { - float radius = m_flRadius; - - if ( FStrEq( STRING(m_iszListener ), "player" ) ) - radius = 4096; // Always find the player - - pListener = UTIL_FindEntityGeneric( STRING( m_iszListener ), pTarget->pev->origin, radius ); - } - - pTarget->PlayScriptedSentence( STRING(m_iszSentence), m_flDuration, m_flVolume, m_flAttenuation, bConcurrent, pListener ); - ALERT( at_aiconsole, "Playing sentence %s (%.1f)\n", STRING(m_iszSentence), m_flDuration ); - SUB_UseTargets( NULL, USE_TOGGLE, 0 ); - return TRUE; -} - - - - - -/* - -*/ - - -//========================================================= -// Furniture - this is the cool comment I cut-and-pasted -//========================================================= -class CFurniture : public CBaseMonster -{ -public: - void Spawn ( void ); - void Die( void ); - int Classify ( void ); - virtual int ObjectCaps( void ) { return (CBaseMonster :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } -}; - - -LINK_ENTITY_TO_CLASS( monster_furniture, CFurniture ); - - -//========================================================= -// Furniture is killed -//========================================================= -void CFurniture :: Die ( void ) -{ - SetThink ( SUB_Remove ); - pev->nextthink = gpGlobals->time; -} - -//========================================================= -// This used to have something to do with bees flying, but -// now it only initializes moving furniture in scripted sequences -//========================================================= -void CFurniture :: Spawn( ) -{ - PRECACHE_MODEL((char *)STRING(pev->model)); - SET_MODEL(ENT(pev), STRING(pev->model)); - - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_BBOX; - pev->health = 80000; - pev->takedamage = DAMAGE_AIM; - pev->effects = 0; - pev->yaw_speed = 0; - pev->sequence = 0; - pev->frame = 0; - -// pev->nextthink += 1.0; -// SetThink (WalkMonsterDelay); - - ResetSequenceInfo( ); - pev->frame = 0; - MonsterInit(); -} - -//========================================================= -// ID's Furniture as neutral (noone will attack it) -//========================================================= -int CFurniture::Classify ( void ) -{ - return CLASS_NONE; -} - - diff --git a/dmc/dlls/scripted.h b/dmc/dlls/scripted.h deleted file mode 100644 index dee12d7..0000000 --- a/dmc/dlls/scripted.h +++ /dev/null @@ -1,107 +0,0 @@ -/*** -* -* 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. -* -* This source code contains proprietary and confidential information of -* Valve LLC and its suppliers. Access to this code is restricted to -* persons who have executed a written SDK license with Valve. Any access, -* use or distribution of this code by or to any unlicensed person is illegal. -* -****/ -#ifndef SCRIPTED_H -#define SCRIPTED_H - -#ifndef SCRIPTEVENT_H -#include "scriptevent.h" -#endif - -#define SF_SCRIPT_WAITTILLSEEN 1 -#define SF_SCRIPT_EXITAGITATED 2 -#define SF_SCRIPT_REPEATABLE 4 -#define SF_SCRIPT_LEAVECORPSE 8 -//#define SF_SCRIPT_INTERPOLATE 16 // don't use, old bug -#define SF_SCRIPT_NOINTERRUPT 32 -#define SF_SCRIPT_OVERRIDESTATE 64 -#define SF_SCRIPT_NOSCRIPTMOVEMENT 128 - -#define SCRIPT_BREAK_CONDITIONS (bits_COND_LIGHT_DAMAGE|bits_COND_HEAVY_DAMAGE) - -enum SS_INTERRUPT -{ - SS_INTERRUPT_IDLE = 0, - SS_INTERRUPT_BY_NAME, - SS_INTERRUPT_AI, -}; - -// when a monster finishes an AI scripted sequence, we can choose -// a schedule to place them in. These defines are the aliases to -// resolve worldcraft input to real schedules (sjb) -#define SCRIPT_FINISHSCHED_DEFAULT 0 -#define SCRIPT_FINISHSCHED_AMBUSH 1 - -class CCineMonster : public CBaseMonster -{ -public: - void Spawn( void ); - virtual void KeyValue( KeyValueData *pkvd ); - virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual void Blocked( CBaseEntity *pOther ); - virtual void Touch( CBaseEntity *pOther ); - virtual int ObjectCaps( void ) { return (CBaseMonster :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } - virtual void Activate( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - // void EXPORT CineSpawnThink( void ); - void EXPORT CineThink( void ); - void Pain( void ); - void Die( void ); - void DelayStart( int state ); - BOOL FindEntity( void ); - virtual void PossessEntity( void ); - - void ReleaseEntity( CBaseMonster *pEntity ); - void CancelScript( void ); - virtual BOOL StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty ); - virtual BOOL FCanOverrideState ( void ); - void SequenceDone ( CBaseMonster *pMonster ); - virtual void FixScriptMonsterSchedule( CBaseMonster *pMonster ); - BOOL CanInterrupt( void ); - void AllowInterrupt( BOOL fAllow ); - int IgnoreConditions( void ); - - int m_iszIdle; // string index for idle animation - int m_iszPlay; // string index for scripted animation - int m_iszEntity; // entity that is wanted for this script - int m_fMoveTo; - int m_iFinishSchedule; - float m_flRadius; // range to search - float m_flRepeat; // repeat rate - - int m_iDelay; - float m_startTime; - - int m_saved_movetype; - int m_saved_solid; - int m_saved_effects; -// Vector m_vecOrigOrigin; - BOOL m_interruptable; -}; - -class CCineAI : public CCineMonster -{ - BOOL StartSequence( CBaseMonster *pTarget, int iszSeq, BOOL completeOnEmpty ); - void PossessEntity( void ); - BOOL FCanOverrideState ( void ); - virtual void FixScriptMonsterSchedule( CBaseMonster *pMonster ); -}; - - -#endif //SCRIPTED_H diff --git a/dmc/dlls/scriptevent.h b/dmc/dlls/scriptevent.h deleted file mode 100644 index 42377cf..0000000 --- a/dmc/dlls/scriptevent.h +++ /dev/null @@ -1,29 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef SCRIPTEVENT_H -#define SCRIPTEVENT_H - -#define SCRIPT_EVENT_DEAD 1000 // character is now dead -#define SCRIPT_EVENT_NOINTERRUPT 1001 // does not allow interrupt -#define SCRIPT_EVENT_CANINTERRUPT 1002 // will allow interrupt -#define SCRIPT_EVENT_FIREEVENT 1003 // event now fires -#define SCRIPT_EVENT_SOUND 1004 // Play named wave file (on CHAN_BODY) -#define SCRIPT_EVENT_SENTENCE 1005 // Play named sentence -#define SCRIPT_EVENT_INAIR 1006 // Leave the character in air at the end of the sequence (don't find the floor) -#define SCRIPT_EVENT_ENDANIMATION 1007 // Set the animation by name after the sequence completes -#define SCRIPT_EVENT_SOUND_VOICE 1008 // Play named wave file (on CHAN_VOICE) -#define SCRIPT_EVENT_SENTENCE_RND1 1009 // Play sentence group 25% of the time -#define SCRIPT_EVENT_NOT_DEAD 1010 // Bring back to life (for life/death sequences) -#endif //SCRIPTEVENT_H diff --git a/dmc/dlls/singleplay_gamerules.cpp b/dmc/dlls/singleplay_gamerules.cpp deleted file mode 100644 index 947df3f..0000000 --- a/dmc/dlls/singleplay_gamerules.cpp +++ /dev/null @@ -1,336 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// teamplay_gamerules.cpp -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "skill.h" -#include "items.h" - -extern DLL_GLOBAL CGameRules *g_pGameRules; -extern DLL_GLOBAL BOOL g_fGameOver; -extern int gmsgDeathMsg; // client dll messages -extern int gmsgScoreInfo; -extern int gmsgMOTD; - -//========================================================= -//========================================================= -CHalfLifeRules::CHalfLifeRules( void ) -{ - RefreshSkillData(); -} - -//========================================================= -//========================================================= -void CHalfLifeRules::Think ( void ) -{ -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::IsMultiplayer( void ) -{ - return FALSE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::IsDeathmatch ( void ) -{ - return FALSE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::IsCoOp( void ) -{ - return FALSE; -} - - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ - if ( !pPlayer->m_pActiveItem ) - { - // player doesn't have an active item! - return TRUE; - } - - if ( !pPlayer->m_pActiveItem->CanHolster() ) - { - return FALSE; - } - - return TRUE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) -{ - return FALSE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) -{ - return TRUE; -} - -void CHalfLifeRules :: InitHUD( CBasePlayer *pl ) -{ -} - -//========================================================= -//========================================================= -void CHalfLifeRules :: ClientDisconnected( edict_t *pClient ) -{ -} - -//========================================================= -//========================================================= -float CHalfLifeRules::FlPlayerFallDamage( CBasePlayer *pPlayer ) -{ - // subtract off the speed at which a player is allowed to fall without being hurt, - // so damage will be based on speed beyond that, not the entire fall - pPlayer->m_flFallVelocity -= PLAYER_MAX_SAFE_FALL_SPEED; - return pPlayer->m_flFallVelocity * DAMAGE_FOR_FALL_SPEED; -} - -//========================================================= -//========================================================= -void CHalfLifeRules :: PlayerSpawn( CBasePlayer *pPlayer ) -{ - // Start with init ammoload - pPlayer->m_iAmmoShells = 25; - - // Start with shotgun and axe - pPlayer->GiveNamedItem( "weapon_quakegun" ); - pPlayer->m_iQuakeItems |= (IT_SHOTGUN | IT_AXE); - pPlayer->m_iQuakeWeapon = pPlayer->W_BestWeapon(); - pPlayer->W_SetCurrentAmmo(); -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: AllowAutoTargetCrosshair( void ) -{ - return ( g_iSkillLevel == SKILL_EASY ); -} - -//========================================================= -//========================================================= -void CHalfLifeRules :: PlayerThink( CBasePlayer *pPlayer ) -{ -} - - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: FPlayerCanRespawn( CBasePlayer *pPlayer ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -float CHalfLifeRules :: FlPlayerSpawnTime( CBasePlayer *pPlayer ) -{ - return gpGlobals->time;//now! -} - -//========================================================= -// IPointsForKill - how many points awarded to anyone -// that kills this player? -//========================================================= -int CHalfLifeRules :: IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) -{ - return 1; -} - -//========================================================= -// PlayerKilled - someone/something killed this player -//========================================================= -void CHalfLifeRules :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ -} - -//========================================================= -// Deathnotice -//========================================================= -void CHalfLifeRules::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ -} - -//========================================================= -// PlayerGotWeapon - player has grabbed a weapon that was -// sitting in the world -//========================================================= -void CHalfLifeRules :: PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ -} - -//========================================================= -// FlWeaponRespawnTime - what is the time in the future -// at which this weapon may spawn? -//========================================================= -float CHalfLifeRules :: FlWeaponRespawnTime( CBasePlayerItem *pWeapon ) -{ - return -1; -} - -//========================================================= -// FlWeaponRespawnTime - Returns 0 if the weapon can respawn -// now, otherwise it returns the time at which it can try -// to spawn again. -//========================================================= -float CHalfLifeRules :: FlWeaponTryRespawn( CBasePlayerItem *pWeapon ) -{ - return 0; -} - -//========================================================= -// VecWeaponRespawnSpot - where should this weapon spawn? -// Some game variations may choose to randomize spawn locations -//========================================================= -Vector CHalfLifeRules :: VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ) -{ - return pWeapon->pev->origin; -} - -//========================================================= -// WeaponShouldRespawn - any conditions inhibiting the -// respawning of this weapon? -//========================================================= -int CHalfLifeRules :: WeaponShouldRespawn( CBasePlayerItem *pWeapon ) -{ - return GR_WEAPON_RESPAWN_NO; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -void CHalfLifeRules::PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ) -{ -} - -//========================================================= -//========================================================= -int CHalfLifeRules::ItemShouldRespawn( CItem *pItem ) -{ - return GR_ITEM_RESPAWN_NO; -} - - -//========================================================= -// At what time in the future may this Item respawn? -//========================================================= -float CHalfLifeRules::FlItemRespawnTime( CItem *pItem ) -{ - return -1; -} - -//========================================================= -// Where should this item respawn? -// Some game variations may choose to randomize spawn locations -//========================================================= -Vector CHalfLifeRules::VecItemRespawnSpot( CItem *pItem ) -{ - return pItem->pev->origin; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::IsAllowedToSpawn( CBaseEntity *pEntity ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -void CHalfLifeRules::PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ) -{ -} - -//========================================================= -//========================================================= -int CHalfLifeRules::AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ) -{ - return GR_AMMO_RESPAWN_NO; -} - -//========================================================= -//========================================================= -float CHalfLifeRules::FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ) -{ - return -1; -} - -//========================================================= -//========================================================= -Vector CHalfLifeRules::VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ) -{ - return pAmmo->pev->origin; -} - -//========================================================= -//========================================================= -float CHalfLifeRules::FlHealthChargerRechargeTime( void ) -{ - return 0;// don't recharge -} - -//========================================================= -//========================================================= -int CHalfLifeRules::DeadPlayerWeapons( CBasePlayer *pPlayer ) -{ - return GR_PLR_DROP_GUN_NO; -} - -//========================================================= -//========================================================= -int CHalfLifeRules::DeadPlayerAmmo( CBasePlayer *pPlayer ) -{ - return GR_PLR_DROP_AMMO_NO; -} - -//========================================================= -//========================================================= -int CHalfLifeRules::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) -{ - // why would a single player in half life need this? - return GR_NOTTEAMMATE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: FAllowMonsters( void ) -{ - return TRUE; -} diff --git a/dmc/dlls/skill.cpp b/dmc/dlls/skill.cpp deleted file mode 100644 index d82a607..0000000 --- a/dmc/dlls/skill.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/*** -* -* 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. -* -****/ -//========================================================= -// skill.cpp - code for skill level concerns -//========================================================= -#include "extdll.h" -#include "util.h" -#include "skill.h" - - -skilldata_t gSkillData; - - -//========================================================= -// take the name of a cvar, tack a digit for the skill level -// on, and return the value.of that Cvar -//========================================================= -float GetSkillCvar( char *pName ) -{ - int iCount; - float flValue; - char szBuffer[ 64 ]; - - iCount = sprintf( szBuffer, "%s%d",pName, gSkillData.iSkillLevel ); - - flValue = CVAR_GET_FLOAT ( szBuffer ); - - if ( flValue <= 0 ) - { - ALERT ( at_console, "\n\n** GetSkillCVar Got a zero for %s **\n\n", szBuffer ); - } - - return flValue; -} - diff --git a/dmc/dlls/skill.h b/dmc/dlls/skill.h deleted file mode 100644 index 5ec320c..0000000 --- a/dmc/dlls/skill.h +++ /dev/null @@ -1,147 +0,0 @@ -/*** -* -* 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. -* -****/ -//========================================================= -// skill.h - skill level concerns -//========================================================= - -struct skilldata_t -{ - - int iSkillLevel; // game skill level - -// Monster Health & Damage - float agruntHealth; - float agruntDmgPunch; - - float apacheHealth; - - float barneyHealth; - - float bigmommaHealthFactor; // Multiply each node's health by this - float bigmommaDmgSlash; // melee attack damage - float bigmommaDmgBlast; // mortar attack damage - float bigmommaRadiusBlast; // mortar attack radius - - float bullsquidHealth; - float bullsquidDmgBite; - float bullsquidDmgWhip; - float bullsquidDmgSpit; - - float gargantuaHealth; - float gargantuaDmgSlash; - float gargantuaDmgFire; - float gargantuaDmgStomp; - - float hassassinHealth; - - float headcrabHealth; - float headcrabDmgBite; - - float hgruntHealth; - float hgruntDmgKick; - float hgruntShotgunPellets; - float hgruntGrenadeSpeed; - - float houndeyeHealth; - float houndeyeDmgBlast; - - float slaveHealth; - float slaveDmgClaw; - float slaveDmgClawrake; - float slaveDmgZap; - - float ichthyosaurHealth; - float ichthyosaurDmgShake; - - float leechHealth; - float leechDmgBite; - - float controllerHealth; - float controllerDmgZap; - float controllerSpeedBall; - float controllerDmgBall; - - float nihilanthHealth; - float nihilanthZap; - - float scientistHealth; - - float snarkHealth; - float snarkDmgBite; - float snarkDmgPop; - - float zombieHealth; - float zombieDmgOneSlash; - float zombieDmgBothSlash; - - float turretHealth; - float miniturretHealth; - float sentryHealth; - - -// Player Weapons - float plrDmgCrowbar; - float plrDmg9MM; - float plrDmg357; - float plrDmgMP5; - float plrDmgM203Grenade; - float plrDmgBuckshot; - float plrDmgCrossbowClient; - float plrDmgCrossbowMonster; - float plrDmgRPG; - float plrDmgGauss; - float plrDmgEgonNarrow; - float plrDmgEgonWide; - float plrDmgHornet; - float plrDmgHandGrenade; - float plrDmgSatchel; - float plrDmgTripmine; - -// weapons shared by monsters - float monDmg9MM; - float monDmgMP5; - float monDmg12MM; - float monDmgHornet; - -// health/suit charge - float suitchargerCapacity; - float batteryCapacity; - float healthchargerCapacity; - float healthkitCapacity; - float scientistHeal; - -// monster damage adj - float monHead; - float monChest; - float monStomach; - float monLeg; - float monArm; - -// player damage adj - float plrHead; - float plrChest; - float plrStomach; - float plrLeg; - float plrArm; -}; - -extern DLL_GLOBAL skilldata_t gSkillData; -float GetSkillCvar( char *pName ); - -extern DLL_GLOBAL int g_iSkillLevel; - -#define SKILL_EASY 1 -#define SKILL_MEDIUM 2 -#define SKILL_HARD 3 diff --git a/dmc/dlls/sound.cpp b/dmc/dlls/sound.cpp deleted file mode 100644 index a7a2e97..0000000 --- a/dmc/dlls/sound.cpp +++ /dev/null @@ -1,1990 +0,0 @@ -/*** -* -* 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. -* -****/ -//========================================================= -// sound.cpp -//========================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "weapons.h" -#include "player.h" -#include "gamerules.h" - -#if !defined ( _WIN32 ) -#include -#endif - -static char *memfgets( byte *pMemFile, int fileSize, int &filePos, char *pBuffer, int bufferSize ); - - -// ==================== GENERIC AMBIENT SOUND ====================================== - -// runtime pitch shift and volume fadein/out structure - -// NOTE: IF YOU CHANGE THIS STRUCT YOU MUST CHANGE THE SAVE/RESTORE VERSION NUMBER -// SEE BELOW (in the typedescription for the class) -typedef struct dynpitchvol -{ - // NOTE: do not change the order of these parameters - // NOTE: unless you also change order of rgdpvpreset array elements! - int preset; - - int pitchrun; // pitch shift % when sound is running 0 - 255 - int pitchstart; // pitch shift % when sound stops or starts 0 - 255 - int spinup; // spinup time 0 - 100 - int spindown; // spindown time 0 - 100 - - int volrun; // volume change % when sound is running 0 - 10 - int volstart; // volume change % when sound stops or starts 0 - 10 - int fadein; // volume fade in time 0 - 100 - int fadeout; // volume fade out time 0 - 100 - - // Low Frequency Oscillator - int lfotype; // 0) off 1) square 2) triangle 3) random - int lforate; // 0 - 1000, how fast lfo osciallates - - int lfomodpitch; // 0-100 mod of current pitch. 0 is off. - int lfomodvol; // 0-100 mod of current volume. 0 is off. - - int cspinup; // each trigger hit increments counter and spinup pitch - - - int cspincount; - - int pitch; - int spinupsav; - int spindownsav; - int pitchfrac; - - int vol; - int fadeinsav; - int fadeoutsav; - int volfrac; - - int lfofrac; - int lfomult; - - -} dynpitchvol_t; - -#define CDPVPRESETMAX 27 - -// presets for runtime pitch and vol modulation of ambient sounds - -dynpitchvol_t rgdpvpreset[CDPVPRESETMAX] = -{ -// pitch pstart spinup spindwn volrun volstrt fadein fadeout lfotype lforate modptch modvol cspnup -{1, 255, 75, 95, 95, 10, 1, 50, 95, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{2, 255, 85, 70, 88, 10, 1, 20, 88, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{3, 255, 100, 50, 75, 10, 1, 10, 75, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{4, 100, 100, 0, 0, 10, 1, 90, 90, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{5, 100, 100, 0, 0, 10, 1, 80, 80, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{6, 100, 100, 0, 0, 10, 1, 50, 70, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{7, 100, 100, 0, 0, 5, 1, 40, 50, 1, 50, 0, 10, 0, 0,0,0,0,0,0,0,0,0,0}, -{8, 100, 100, 0, 0, 5, 1, 40, 50, 1, 150, 0, 10, 0, 0,0,0,0,0,0,0,0,0,0}, -{9, 100, 100, 0, 0, 5, 1, 40, 50, 1, 750, 0, 10, 0, 0,0,0,0,0,0,0,0,0,0}, -{10,128, 100, 50, 75, 10, 1, 30, 40, 2, 8, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{11,128, 100, 50, 75, 10, 1, 30, 40, 2, 25, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{12,128, 100, 50, 75, 10, 1, 30, 40, 2, 70, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{13,50, 50, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{14,70, 70, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{15,90, 90, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{16,120, 120, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{17,180, 180, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{18,255, 255, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{19,200, 75, 90, 90, 10, 1, 50, 90, 2, 100, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{20,255, 75, 97, 90, 10, 1, 50, 90, 1, 40, 50, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{21,100, 100, 0, 0, 10, 1, 30, 50, 3, 15, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{22,160, 160, 0, 0, 10, 1, 50, 50, 3, 500, 25, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{23,255, 75, 88, 0, 10, 1, 40, 0, 0, 0, 0, 0, 5, 0,0,0,0,0,0,0,0,0,0}, -{24,200, 20, 95, 70, 10, 1, 70, 70, 3, 20, 50, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{25,180, 100, 50, 60, 10, 1, 40, 60, 2, 90, 100, 100, 0, 0,0,0,0,0,0,0,0,0,0}, -{26,60, 60, 0, 0, 10, 1, 40, 70, 3, 80, 20, 50, 0, 0,0,0,0,0,0,0,0,0,0}, -{27,128, 90, 10, 10, 10, 1, 20, 40, 1, 5, 10, 20, 0, 0,0,0,0,0,0,0,0,0,0} -}; - -class CAmbientGeneric : public CBaseEntity -{ -public: - void KeyValue( KeyValueData* pkvd); - void Spawn( void ); - void Precache( void ); - void EXPORT ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT RampThink( void ); - void InitModulationParms(void); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } - - float m_flAttenuation; // attenuation value - dynpitchvol_t m_dpv; - - BOOL m_fActive; // only TRUE when the entity is playing a looping sound - BOOL m_fLooping; // TRUE when the sound played will loop -}; - -LINK_ENTITY_TO_CLASS( ambient_generic, CAmbientGeneric ); -TYPEDESCRIPTION CAmbientGeneric::m_SaveData[] = -{ - DEFINE_FIELD( CAmbientGeneric, m_flAttenuation, FIELD_FLOAT ), - DEFINE_FIELD( CAmbientGeneric, m_fActive, FIELD_BOOLEAN ), - DEFINE_FIELD( CAmbientGeneric, m_fLooping, FIELD_BOOLEAN ), - - // HACKHACK - This is not really in the spirit of the save/restore design, but save this - // out as a binary data block. If the dynpitchvol_t is changed, old saved games will NOT - // load these correctly, so bump the save/restore version if you change the size of the struct - // The right way to do this is to split the input parms (read in keyvalue) into members and re-init this - // struct in Precache(), but it's unlikely that the struct will change, so it's not worth the time right now. - DEFINE_ARRAY( CAmbientGeneric, m_dpv, FIELD_CHARACTER, sizeof(dynpitchvol_t) ), -}; - -IMPLEMENT_SAVERESTORE( CAmbientGeneric, CBaseEntity ); - -// -// ambient_generic - general-purpose user-defined static sound -// -void CAmbientGeneric :: Spawn( void ) -{ -/* - -1 : "Default" - 0 : "Everywhere" - 200 : "Small Radius" - 125 : "Medium Radius" - 80 : "Large Radius" -*/ - - if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_EVERYWHERE) ) - { - m_flAttenuation = ATTN_NONE; - } - else if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_SMALLRADIUS) ) - { - m_flAttenuation = ATTN_IDLE; - } - else if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_MEDIUMRADIUS) ) - { - m_flAttenuation = ATTN_STATIC; - } - else if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_LARGERADIUS) ) - { - m_flAttenuation = ATTN_NORM; - } - else - {// if the designer didn't set a sound attenuation, default to one. - m_flAttenuation = ATTN_STATIC; - } - - char* szSoundFile = (char*) STRING(pev->message); - - if ( FStringNull( pev->message ) || strlen( szSoundFile ) < 1 ) - { - ALERT( at_error, "EMPTY AMBIENT AT: %f, %f, %f\n", pev->origin.x, pev->origin.y, pev->origin.z ); - pev->nextthink = gpGlobals->time + 0.1; - SetThink( &CAmbientGeneric::SUB_Remove ); - return; - } - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - - // Set up think function for dynamic modification - // of ambient sound's pitch or volume. Don't - // start thinking yet. - - SetThink(&CAmbientGeneric::RampThink); - pev->nextthink = 0; - - // allow on/off switching via 'use' function. - - SetUse ( &CAmbientGeneric::ToggleUse ); - - m_fActive = FALSE; - - if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_NOT_LOOPING ) ) - m_fLooping = FALSE; - else - m_fLooping = TRUE; - Precache( ); -} - - -void CAmbientGeneric :: Precache( void ) -{ - char* szSoundFile = (char*) STRING(pev->message); - - if ( !FStringNull( pev->message ) && strlen( szSoundFile ) > 1 ) - { - if (*szSoundFile != '!') - PRECACHE_SOUND(szSoundFile); - } - // init all dynamic modulation parms - InitModulationParms(); - - if ( !FBitSet (pev->spawnflags, AMBIENT_SOUND_START_SILENT ) ) - { - // start the sound ASAP - if (m_fLooping) - m_fActive = TRUE; - } - if ( m_fActive ) - { - UTIL_EmitAmbientSound ( ENT(pev), pev->origin, szSoundFile, - (m_dpv.vol * 0.01), m_flAttenuation, SND_SPAWNING, m_dpv.pitch); - - pev->nextthink = gpGlobals->time + 0.1; - } -} - -// RampThink - Think at 5hz if we are dynamically modifying -// pitch or volume of the playing sound. This function will -// ramp pitch and/or volume up or down, modify pitch/volume -// with lfo if active. - -void CAmbientGeneric :: RampThink( void ) -{ - char* szSoundFile = (char*) STRING(pev->message); - int pitch = m_dpv.pitch; - int vol = m_dpv.vol; - int flags = 0; - int fChanged = 0; // FALSE if pitch and vol remain unchanged this round - int prev; - - if (!m_dpv.spinup && !m_dpv.spindown && !m_dpv.fadein && !m_dpv.fadeout && !m_dpv.lfotype) - return; // no ramps or lfo, stop thinking - - // ============== - // pitch envelope - // ============== - if (m_dpv.spinup || m_dpv.spindown) - { - prev = m_dpv.pitchfrac >> 8; - - if (m_dpv.spinup > 0) - m_dpv.pitchfrac += m_dpv.spinup; - else if (m_dpv.spindown > 0) - m_dpv.pitchfrac -= m_dpv.spindown; - - pitch = m_dpv.pitchfrac >> 8; - - if (pitch > m_dpv.pitchrun) - { - pitch = m_dpv.pitchrun; - m_dpv.spinup = 0; // done with ramp up - } - - if (pitch < m_dpv.pitchstart) - { - pitch = m_dpv.pitchstart; - m_dpv.spindown = 0; // done with ramp down - - // shut sound off - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_STOP, 0); - - // return without setting nextthink - return; - } - - if (pitch > 255) pitch = 255; - if (pitch < 1) pitch = 1; - - m_dpv.pitch = pitch; - - fChanged |= (prev != pitch); - flags |= SND_CHANGE_PITCH; - } - - // ================== - // amplitude envelope - // ================== - if (m_dpv.fadein || m_dpv.fadeout) - { - prev = m_dpv.volfrac >> 8; - - if (m_dpv.fadein > 0) - m_dpv.volfrac += m_dpv.fadein; - else if (m_dpv.fadeout > 0) - m_dpv.volfrac -= m_dpv.fadeout; - - vol = m_dpv.volfrac >> 8; - - if (vol > m_dpv.volrun) - { - vol = m_dpv.volrun; - m_dpv.fadein = 0; // done with ramp up - } - - if (vol < m_dpv.volstart) - { - vol = m_dpv.volstart; - m_dpv.fadeout = 0; // done with ramp down - - // shut sound off - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_STOP, 0); - - // return without setting nextthink - return; - } - - if (vol > 100) vol = 100; - if (vol < 1) vol = 1; - - m_dpv.vol = vol; - - fChanged |= (prev != vol); - flags |= SND_CHANGE_VOL; - } - - // =================== - // pitch/amplitude LFO - // =================== - if (m_dpv.lfotype) - { - int pos; - - if (m_dpv.lfofrac > 0x6fffffff) - m_dpv.lfofrac = 0; - - // update lfo, lfofrac/255 makes a triangle wave 0-255 - m_dpv.lfofrac += m_dpv.lforate; - pos = m_dpv.lfofrac >> 8; - - if (m_dpv.lfofrac < 0) - { - m_dpv.lfofrac = 0; - m_dpv.lforate = abs(m_dpv.lforate); - pos = 0; - } - else if (pos > 255) - { - pos = 255; - m_dpv.lfofrac = (255 << 8); - m_dpv.lforate = -abs(m_dpv.lforate); - } - - switch(m_dpv.lfotype) - { - case LFO_SQUARE: - if (pos < 128) - m_dpv.lfomult = 255; - else - m_dpv.lfomult = 0; - - break; - case LFO_RANDOM: - if (pos == 255) - m_dpv.lfomult = RANDOM_LONG(0, 255); - break; - case LFO_TRIANGLE: - default: - m_dpv.lfomult = pos; - break; - } - - if (m_dpv.lfomodpitch) - { - prev = pitch; - - // pitch 0-255 - pitch += ((m_dpv.lfomult - 128) * m_dpv.lfomodpitch) / 100; - - if (pitch > 255) pitch = 255; - if (pitch < 1) pitch = 1; - - - fChanged |= (prev != pitch); - flags |= SND_CHANGE_PITCH; - } - - if (m_dpv.lfomodvol) - { - // vol 0-100 - prev = vol; - - vol += ((m_dpv.lfomult - 128) * m_dpv.lfomodvol) / 100; - - if (vol > 100) vol = 100; - if (vol < 0) vol = 0; - - fChanged |= (prev != vol); - flags |= SND_CHANGE_VOL; - } - - } - - // Send update to playing sound only if we actually changed - // pitch or volume in this routine. - - if (flags && fChanged) - { - if (pitch == PITCH_NORM) - pitch = PITCH_NORM + 1; // don't send 'no pitch' ! - - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - (vol * 0.01), m_flAttenuation, flags, pitch); - } - - // update ramps at 5hz - pev->nextthink = gpGlobals->time + 0.2; - return; -} - -// Init all ramp params in preparation to -// play a new sound - -void CAmbientGeneric :: InitModulationParms(void) -{ - int pitchinc; - - m_dpv.volrun = pev->health * 10; // 0 - 100 - if (m_dpv.volrun > 100) m_dpv.volrun = 100; - if (m_dpv.volrun < 0) m_dpv.volrun = 0; - - // get presets - if (m_dpv.preset != 0 && m_dpv.preset <= CDPVPRESETMAX) - { - // load preset values - m_dpv = rgdpvpreset[m_dpv.preset - 1]; - - // fixup preset values, just like - // fixups in KeyValue routine. - if (m_dpv.spindown > 0) - m_dpv.spindown = (101 - m_dpv.spindown) * 64; - if (m_dpv.spinup > 0) - m_dpv.spinup = (101 - m_dpv.spinup) * 64; - - m_dpv.volstart *= 10; - m_dpv.volrun *= 10; - - if (m_dpv.fadein > 0) - m_dpv.fadein = (101 - m_dpv.fadein) * 64; - if (m_dpv.fadeout > 0) - m_dpv.fadeout = (101 - m_dpv.fadeout) * 64; - - m_dpv.lforate *= 256; - - m_dpv.fadeinsav = m_dpv.fadein; - m_dpv.fadeoutsav = m_dpv.fadeout; - m_dpv.spinupsav = m_dpv.spinup; - m_dpv.spindownsav = m_dpv.spindown; - } - - m_dpv.fadein = m_dpv.fadeinsav; - m_dpv.fadeout = 0; - - if (m_dpv.fadein) - m_dpv.vol = m_dpv.volstart; - else - m_dpv.vol = m_dpv.volrun; - - m_dpv.spinup = m_dpv.spinupsav; - m_dpv.spindown = 0; - - if (m_dpv.spinup) - m_dpv.pitch = m_dpv.pitchstart; - else - m_dpv.pitch = m_dpv.pitchrun; - - if (m_dpv.pitch == 0) - m_dpv.pitch = PITCH_NORM; - - m_dpv.pitchfrac = m_dpv.pitch << 8; - m_dpv.volfrac = m_dpv.vol << 8; - - m_dpv.lfofrac = 0; - m_dpv.lforate = abs(m_dpv.lforate); - - m_dpv.cspincount = 1; - - if (m_dpv.cspinup) - { - pitchinc = (255 - m_dpv.pitchstart) / m_dpv.cspinup; - - m_dpv.pitchrun = m_dpv.pitchstart + pitchinc; - if (m_dpv.pitchrun > 255) m_dpv.pitchrun = 255; - } - - if ((m_dpv.spinupsav || m_dpv.spindownsav || (m_dpv.lfotype && m_dpv.lfomodpitch)) - && (m_dpv.pitch == PITCH_NORM)) - m_dpv.pitch = PITCH_NORM + 1; // must never send 'no pitch' as first pitch - // if we intend to pitch shift later! -} - -// -// ToggleUse - turns an ambient sound on or off. If the -// ambient is a looping sound, mark sound as active (m_fActive) -// if it's playing, innactive if not. If the sound is not -// a looping sound, never mark it as active. -// -void CAmbientGeneric :: ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - char* szSoundFile = (char*) STRING(pev->message); - float fraction; - - if ( useType != USE_TOGGLE ) - { - if ( (m_fActive && useType == USE_ON) || (!m_fActive && useType == USE_OFF) ) - return; - } - // Directly change pitch if arg passed. Only works if sound is already playing. - - if (useType == USE_SET && m_fActive) // Momentary buttons will pass down a float in here - { - - fraction = value; - - if ( fraction > 1.0 ) - fraction = 1.0; - if (fraction < 0.0) - fraction = 0.01; - - m_dpv.pitch = fraction * 255; - - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_CHANGE_PITCH, m_dpv.pitch); - - return; - } - - // Toggle - - // m_fActive is TRUE only if a looping sound is playing. - - if ( m_fActive ) - {// turn sound off - - if (m_dpv.cspinup) - { - // Don't actually shut off. Each toggle causes - // incremental spinup to max pitch - - if (m_dpv.cspincount <= m_dpv.cspinup) - { - int pitchinc; - - // start a new spinup - m_dpv.cspincount++; - - pitchinc = (255 - m_dpv.pitchstart) / m_dpv.cspinup; - - m_dpv.spinup = m_dpv.spinupsav; - m_dpv.spindown = 0; - - m_dpv.pitchrun = m_dpv.pitchstart + pitchinc * m_dpv.cspincount; - if (m_dpv.pitchrun > 255) m_dpv.pitchrun = 255; - - pev->nextthink = gpGlobals->time + 0.1; - } - - } - else - { - m_fActive = FALSE; - - // HACKHACK - this makes the code in Precache() work properly after a save/restore - pev->spawnflags |= AMBIENT_SOUND_START_SILENT; - - if (m_dpv.spindownsav || m_dpv.fadeoutsav) - { - // spin it down (or fade it) before shutoff if spindown is set - m_dpv.spindown = m_dpv.spindownsav; - m_dpv.spinup = 0; - - m_dpv.fadeout = m_dpv.fadeoutsav; - m_dpv.fadein = 0; - pev->nextthink = gpGlobals->time + 0.1; - } - else - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_STOP, 0); - } - } - else - {// turn sound on - - // only toggle if this is a looping sound. If not looping, each - // trigger will cause the sound to play. If the sound is still - // playing from a previous trigger press, it will be shut off - // and then restarted. - - if (m_fLooping) - m_fActive = TRUE; - else - // shut sound off now - may be interrupting a long non-looping sound - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_STOP, 0); - - // init all ramp params for startup - - InitModulationParms(); - - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - (m_dpv.vol * 0.01), m_flAttenuation, 0, m_dpv.pitch); - - pev->nextthink = gpGlobals->time + 0.1; - - } -} -// KeyValue - load keyvalue pairs into member data of the -// ambient generic. NOTE: called BEFORE spawn! - -void CAmbientGeneric :: KeyValue( KeyValueData *pkvd ) -{ - // NOTE: changing any of the modifiers in this code - // NOTE: also requires changing InitModulationParms code. - - // preset - if (FStrEq(pkvd->szKeyName, "preset")) - { - m_dpv.preset = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - - // pitchrun - else if (FStrEq(pkvd->szKeyName, "pitch")) - { - m_dpv.pitchrun = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - - if (m_dpv.pitchrun > 255) m_dpv.pitchrun = 255; - if (m_dpv.pitchrun < 0) m_dpv.pitchrun = 0; - } - - // pitchstart - else if (FStrEq(pkvd->szKeyName, "pitchstart")) - { - m_dpv.pitchstart = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - - if (m_dpv.pitchstart > 255) m_dpv.pitchstart = 255; - if (m_dpv.pitchstart < 0) m_dpv.pitchstart = 0; - } - - // spinup - else if (FStrEq(pkvd->szKeyName, "spinup")) - { - m_dpv.spinup = atoi(pkvd->szValue); - - if (m_dpv.spinup > 100) m_dpv.spinup = 100; - if (m_dpv.spinup < 0) m_dpv.spinup = 0; - - if (m_dpv.spinup > 0) - m_dpv.spinup = (101 - m_dpv.spinup) * 64; - m_dpv.spinupsav = m_dpv.spinup; - pkvd->fHandled = TRUE; - } - - // spindown - else if (FStrEq(pkvd->szKeyName, "spindown")) - { - m_dpv.spindown = atoi(pkvd->szValue); - - if (m_dpv.spindown > 100) m_dpv.spindown = 100; - if (m_dpv.spindown < 0) m_dpv.spindown = 0; - - if (m_dpv.spindown > 0) - m_dpv.spindown = (101 - m_dpv.spindown) * 64; - m_dpv.spindownsav = m_dpv.spindown; - pkvd->fHandled = TRUE; - } - - // volstart - else if (FStrEq(pkvd->szKeyName, "volstart")) - { - m_dpv.volstart = atoi(pkvd->szValue); - - if (m_dpv.volstart > 10) m_dpv.volstart = 10; - if (m_dpv.volstart < 0) m_dpv.volstart = 0; - - m_dpv.volstart *= 10; // 0 - 100 - - pkvd->fHandled = TRUE; - } - - // fadein - else if (FStrEq(pkvd->szKeyName, "fadein")) - { - m_dpv.fadein = atoi(pkvd->szValue); - - if (m_dpv.fadein > 100) m_dpv.fadein = 100; - if (m_dpv.fadein < 0) m_dpv.fadein = 0; - - if (m_dpv.fadein > 0) - m_dpv.fadein = (101 - m_dpv.fadein) * 64; - m_dpv.fadeinsav = m_dpv.fadein; - pkvd->fHandled = TRUE; - } - - // fadeout - else if (FStrEq(pkvd->szKeyName, "fadeout")) - { - m_dpv.fadeout = atoi(pkvd->szValue); - - if (m_dpv.fadeout > 100) m_dpv.fadeout = 100; - if (m_dpv.fadeout < 0) m_dpv.fadeout = 0; - - if (m_dpv.fadeout > 0) - m_dpv.fadeout = (101 - m_dpv.fadeout) * 64; - m_dpv.fadeoutsav = m_dpv.fadeout; - pkvd->fHandled = TRUE; - } - - // lfotype - else if (FStrEq(pkvd->szKeyName, "lfotype")) - { - m_dpv.lfotype = atoi(pkvd->szValue); - if (m_dpv.lfotype > 4) m_dpv.lfotype = LFO_TRIANGLE; - pkvd->fHandled = TRUE; - } - - // lforate - else if (FStrEq(pkvd->szKeyName, "lforate")) - { - m_dpv.lforate = atoi(pkvd->szValue); - - if (m_dpv.lforate > 1000) m_dpv.lforate = 1000; - if (m_dpv.lforate < 0) m_dpv.lforate = 0; - - m_dpv.lforate *= 256; - - pkvd->fHandled = TRUE; - } - // lfomodpitch - else if (FStrEq(pkvd->szKeyName, "lfomodpitch")) - { - m_dpv.lfomodpitch = atoi(pkvd->szValue); - if (m_dpv.lfomodpitch > 100) m_dpv.lfomodpitch = 100; - if (m_dpv.lfomodpitch < 0) m_dpv.lfomodpitch = 0; - - - pkvd->fHandled = TRUE; - } - - // lfomodvol - else if (FStrEq(pkvd->szKeyName, "lfomodvol")) - { - m_dpv.lfomodvol = atoi(pkvd->szValue); - if (m_dpv.lfomodvol > 100) m_dpv.lfomodvol = 100; - if (m_dpv.lfomodvol < 0) m_dpv.lfomodvol = 0; - - pkvd->fHandled = TRUE; - } - - // cspinup - else if (FStrEq(pkvd->szKeyName, "cspinup")) - { - m_dpv.cspinup = atoi(pkvd->szValue); - if (m_dpv.cspinup > 100) m_dpv.cspinup = 100; - if (m_dpv.cspinup < 0) m_dpv.cspinup = 0; - - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -// =================== ROOM SOUND FX ========================================== - -class CEnvSound : public CPointEntity -{ -public: - void KeyValue( KeyValueData* pkvd); - void Spawn( void ); - - void Think( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - float m_flRadius; - float m_flRoomtype; -}; - -LINK_ENTITY_TO_CLASS( env_sound, CEnvSound ); -TYPEDESCRIPTION CEnvSound::m_SaveData[] = -{ - DEFINE_FIELD( CEnvSound, m_flRadius, FIELD_FLOAT ), - DEFINE_FIELD( CEnvSound, m_flRoomtype, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CEnvSound, CBaseEntity ); - - -void CEnvSound :: KeyValue( KeyValueData *pkvd ) -{ - - if (FStrEq(pkvd->szKeyName, "radius")) - { - m_flRadius = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - if (FStrEq(pkvd->szKeyName, "roomtype")) - { - m_flRoomtype = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } -} - -// returns TRUE if the given sound entity (pev) is in range -// and can see the given player entity (pevTarget) - -BOOL FEnvSoundInRange(entvars_t *pev, entvars_t *pevTarget, float *pflRange) -{ - CEnvSound *pSound = GetClassPtr( (CEnvSound *)pev ); - Vector vecSpot1 = pev->origin + pev->view_ofs; - Vector vecSpot2 = pevTarget->origin + pevTarget->view_ofs; - Vector vecRange; - float flRange; - TraceResult tr; - - UTIL_TraceLine(vecSpot1, vecSpot2, ignore_monsters, ENT(pev), &tr); - - // check if line of sight crosses water boundary, or is blocked - - if ((tr.fInOpen && tr.fInWater) || tr.flFraction != 1) - return FALSE; - - // calc range from sound entity to player - - vecRange = tr.vecEndPos - vecSpot1; - flRange = vecRange.Length(); - - if (pSound->m_flRadius < flRange) - return FALSE; - - if (pflRange) - *pflRange = flRange; - - return TRUE; -} - -// -// A client that is visible and in range of a sound entity will -// have its room_type set by that sound entity. If two or more -// sound entities are contending for a client, then the nearest -// sound entity to the client will set the client's room_type. -// A client's room_type will remain set to its prior value until -// a new in-range, visible sound entity resets a new room_type. -// - -// CONSIDER: if player in water state, autoset roomtype to 14,15 or 16. - -void CEnvSound :: Think( void ) -{ - // get pointer to client if visible; FIND_CLIENT_IN_PVS will - // cycle through visible clients on consecutive calls. - - edict_t *pentPlayer = FIND_CLIENT_IN_PVS(edict()); - CBasePlayer *pPlayer = NULL; - - if (FNullEnt(pentPlayer)) - goto env_sound_Think_slow; // no player in pvs of sound entity, slow it down - - pPlayer = GetClassPtr( (CBasePlayer *)VARS(pentPlayer)); - float flRange; - - // check to see if this is the sound entity that is - // currently affecting this player - - if(!FNullEnt(pPlayer->m_pentSndLast) && (pPlayer->m_pentSndLast == ENT(pev))) { - - // this is the entity currently affecting player, check - // for validity - - if (pPlayer->m_flSndRoomtype != 0 && pPlayer->m_flSndRange != 0) { - - // we're looking at a valid sound entity affecting - // player, make sure it's still valid, update range - - if (FEnvSoundInRange(pev, VARS(pentPlayer), &flRange)) { - pPlayer->m_flSndRange = flRange; - goto env_sound_Think_fast; - } else { - - // current sound entity affecting player is no longer valid, - // flag this state by clearing room_type and range. - // NOTE: we do not actually change the player's room_type - // NOTE: until we have a new valid room_type to change it to. - - pPlayer->m_flSndRange = 0; - pPlayer->m_flSndRoomtype = 0; - goto env_sound_Think_slow; - } - } else { - // entity is affecting player but is out of range, - // wait passively for another entity to usurp it... - goto env_sound_Think_slow; - } - } - - // if we got this far, we're looking at an entity that is contending - // for current player sound. the closest entity to player wins. - - if (FEnvSoundInRange(pev, VARS(pentPlayer), &flRange)) - { - if (flRange < pPlayer->m_flSndRange || pPlayer->m_flSndRange == 0) - { - // new entity is closer to player, so it wins. - pPlayer->m_pentSndLast = ENT(pev); - pPlayer->m_flSndRoomtype = m_flRoomtype; - pPlayer->m_flSndRange = flRange; - - // send room_type command to player's server. - // this should be a rare event - once per change of room_type - // only! - - //CLIENT_COMMAND(pentPlayer, "room_type %f", m_flRoomtype); - - MESSAGE_BEGIN( MSG_ONE, SVC_ROOMTYPE, NULL, pentPlayer ); // use the magic #1 for "one client" - WRITE_SHORT( (short)m_flRoomtype ); // sequence number - MESSAGE_END(); - - // crank up nextthink rate for new active sound entity - // by falling through to think_fast... - } - // player is not closer to the contending sound entity, - // just fall through to think_fast. this effectively - // cranks up the think_rate of entities near the player. - } - - // player is in pvs of sound entity, but either not visible or - // not in range. do nothing, fall through to think_fast... - -env_sound_Think_fast: - pev->nextthink = gpGlobals->time + 0.25; - return; - -env_sound_Think_slow: - pev->nextthink = gpGlobals->time + 0.75; - return; -} - -// -// env_sound - spawn a sound entity that will set player roomtype -// when player moves in range and sight. -// -// -void CEnvSound :: Spawn( ) -{ - // spread think times - pev->nextthink = gpGlobals->time + RANDOM_FLOAT(0.0, 0.5); -} - -// ==================== SENTENCE GROUPS, UTILITY FUNCTIONS ====================================== - -#define CSENTENCE_LRU_MAX 32 // max number of elements per sentence group - -// group of related sentences - -typedef struct sentenceg -{ - char szgroupname[CBSENTENCENAME_MAX]; - int count; - unsigned char rgblru[CSENTENCE_LRU_MAX]; - -} SENTENCEG; - -#define CSENTENCEG_MAX 200 // max number of sentence groups -// globals - -SENTENCEG rgsentenceg[CSENTENCEG_MAX]; -int fSentencesInit = FALSE; - -char gszallsentencenames[CVOXFILESENTENCEMAX][CBSENTENCENAME_MAX]; -int gcallsentences = 0; - -// randomize list of sentence name indices - -void USENTENCEG_InitLRU(unsigned char *plru, int count) -{ - int i, j, k; - unsigned char temp; - - if (!fSentencesInit) - return; - - if (count > CSENTENCE_LRU_MAX) - count = CSENTENCE_LRU_MAX; - - for (i = 0; i < count; i++) - plru[i] = (unsigned char) i; - - // randomize array - for (i = 0; i < (count * 4); i++) - { - j = RANDOM_LONG(0,count-1); - k = RANDOM_LONG(0,count-1); - temp = plru[j]; - plru[j] = plru[k]; - plru[k] = temp; - } -} - -// ignore lru. pick next sentence from sentence group. Go in order until we hit the last sentence, -// then repeat list if freset is true. If freset is false, then repeat last sentence. -// ipick is passed in as the requested sentence ordinal. -// ipick 'next' is returned. -// return of -1 indicates an error. - -int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int freset) -{ - char *szgroupname; - unsigned char count; - char sznum[8]; - - if (!fSentencesInit) - return -1; - - if (isentenceg < 0) - return -1; - - szgroupname = rgsentenceg[isentenceg].szgroupname; - count = rgsentenceg[isentenceg].count; - - if (count == 0) - return -1; - - if (ipick >= count) - ipick = count-1; - - strcpy(szfound, "!"); - strcat(szfound, szgroupname); - // Shepard - UNTESTED LINUX FIX!!! -#ifdef WIN32 - itoa(ipick, sznum, 10); -#else - ipick = atol(sznum); -#endif - strcat(szfound, sznum); - - if (ipick >= count) - { - if (freset) - // reset at end of list - return 0; - else - return count; - } - - return ipick + 1; -} - - - -// pick a random sentence from rootname0 to rootnameX. -// picks from the rgsentenceg[isentenceg] least -// recently used, modifies lru array. returns the sentencename. -// note, lru must be seeded with 0-n randomized sentence numbers, with the -// rest of the lru filled with -1. The first integer in the lru is -// actually the size of the list. Returns ipick, the ordinal -// of the picked sentence within the group. - -int USENTENCEG_Pick(int isentenceg, char *szfound) -{ - char *szgroupname; - unsigned char *plru; - unsigned char i; - unsigned char count; - char sznum[8]; - unsigned char ipick; - int ffound = FALSE; - - if (!fSentencesInit) - return -1; - - if (isentenceg < 0) - return -1; - - szgroupname = rgsentenceg[isentenceg].szgroupname; - count = rgsentenceg[isentenceg].count; - plru = rgsentenceg[isentenceg].rgblru; - - while (!ffound) - { - for (i = 0; i < count; i++) - if (plru[i] != 0xFF) - { - ipick = plru[i]; - plru[i] = 0xFF; - ffound = TRUE; - break; - } - - if (!ffound) - USENTENCEG_InitLRU(plru, count); - else - { - strcpy(szfound, "!"); - strcat(szfound, szgroupname); - // Shepard - UNTESTED LINUX FIX!!! -#ifdef WIN32 - itoa(ipick, sznum, 10); -#else - ipick = atol(sznum); -#endif - strcat(szfound, sznum); - return ipick; - } - } - return -1; -} - -// ===================== SENTENCE GROUPS, MAIN ROUTINES ======================== - -// Given sentence group rootname (name without number suffix), -// get sentence group index (isentenceg). Returns -1 if no such name. - -int SENTENCEG_GetIndex(const char *szgroupname) -{ - int i; - - if (!fSentencesInit || !szgroupname) - return -1; - - // search rgsentenceg for match on szgroupname - - i = 0; - while (rgsentenceg[i].count) - { - if (!strcmp(szgroupname, rgsentenceg[i].szgroupname)) - return i; - i++; - } - - return -1; -} - -// given sentence group index, play random sentence for given entity. -// returns ipick - which sentence was picked to -// play from the group. Ipick is only needed if you plan on stopping -// the sound before playback is done (see SENTENCEG_Stop). - -int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, - float volume, float attenuation, int flags, int pitch) -{ - char name[64]; - int ipick; - - if (!fSentencesInit) - return -1; - - name[0] = 0; - - ipick = USENTENCEG_Pick(isentenceg, name); - if (ipick > 0 && name) - EMIT_SOUND_DYN(entity, CHAN_VOICE, name, volume, attenuation, flags, pitch); - return ipick; -} - -// same as above, but takes sentence group name instead of index - -int SENTENCEG_PlayRndSz(edict_t *entity, const char *szgroupname, - float volume, float attenuation, int flags, int pitch) -{ - char name[64]; - int ipick; - int isentenceg; - - if (!fSentencesInit) - return -1; - - name[0] = 0; - - isentenceg = SENTENCEG_GetIndex(szgroupname); - if (isentenceg < 0) - { - ALERT( at_console, "No such sentence group %s\n", szgroupname ); - return -1; - } - - ipick = USENTENCEG_Pick(isentenceg, name); - if (ipick >= 0 && name[0]) - EMIT_SOUND_DYN(entity, CHAN_VOICE, name, volume, attenuation, flags, pitch); - - return ipick; -} - -// play sentences in sequential order from sentence group. Reset after last sentence. - -int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szgroupname, - float volume, float attenuation, int flags, int pitch, int ipick, int freset) -{ - char name[64]; - int ipicknext; - int isentenceg; - - if (!fSentencesInit) - return -1; - - name[0] = 0; - - isentenceg = SENTENCEG_GetIndex(szgroupname); - if (isentenceg < 0) - return -1; - - ipicknext = USENTENCEG_PickSequential(isentenceg, name, ipick, freset); - if (ipicknext >= 0 && name[0]) - EMIT_SOUND_DYN(entity, CHAN_VOICE, name, volume, attenuation, flags, pitch); - return ipicknext; -} - - -// for this entity, for the given sentence within the sentence group, stop -// the sentence. - -void SENTENCEG_Stop(edict_t *entity, int isentenceg, int ipick) -{ - char buffer[64]; - char sznum[8]; - - if (!fSentencesInit) - return; - - if (isentenceg < 0 || ipick < 0) - return; - - strcpy(buffer, "!"); - strcat(buffer, rgsentenceg[isentenceg].szgroupname); - // Shepard - UNTESTED LINUX FIX!!! -#ifdef WIN32 - itoa(ipick, sznum, 10); -#else - ipick = atol(sznum); -#endif - strcat(buffer, sznum); - - STOP_SOUND(entity, CHAN_VOICE, buffer); -} - -// open sentences.txt, scan for groups, build rgsentenceg -// Should be called from world spawn, only works on the -// first call and is ignored subsequently. - -void SENTENCEG_Init() -{ - char buffer[512]; - char szgroup[64]; - int i, j; - int isentencegs; - - if (fSentencesInit) - return; - - memset(gszallsentencenames, 0, CVOXFILESENTENCEMAX * CBSENTENCENAME_MAX); - gcallsentences = 0; - - memset(rgsentenceg, 0, CSENTENCEG_MAX * sizeof(SENTENCEG)); - memset(buffer, 0, 512); - memset(szgroup, 0, 64); - isentencegs = -1; - - - int filePos = 0, fileSize; - byte *pMemFile = g_engfuncs.pfnLoadFileForMe( "sound/sentences.txt", &fileSize ); - if ( !pMemFile ) - return; - - // for each line in the file... - while ( memfgets(pMemFile, fileSize, filePos, buffer, 511) != NULL ) - { - // skip whitespace - i = 0; - while(buffer[i] && buffer[i] == ' ') - i++; - - if (!buffer[i]) - continue; - - if (buffer[i] == '/' || !isalpha(buffer[i])) - continue; - - // get sentence name - j = i; - while (buffer[j] && buffer[j] != ' ') - j++; - - if (!buffer[j]) - continue; - - if (gcallsentences > CVOXFILESENTENCEMAX) - { - ALERT (at_error, "Too many sentences in sentences.txt!\n"); - break; - } - - // null-terminate name and save in sentences array - buffer[j] = 0; - const char *pString = buffer + i; - - if ( strlen( pString ) >= CBSENTENCENAME_MAX ) - ALERT( at_warning, "Sentence %s longer than %d letters\n", pString, CBSENTENCENAME_MAX-1 ); - - strcpy( gszallsentencenames[gcallsentences++], pString ); - - j--; - if (j <= i) - continue; - if (!isdigit(buffer[j])) - continue; - - // cut out suffix numbers - while (j > i && isdigit(buffer[j])) - j--; - - if (j <= i) - continue; - - buffer[j+1] = 0; - - // if new name doesn't match previous group name, - // make a new group. - - if (strcmp(szgroup, &(buffer[i]))) - { - // name doesn't match with prev name, - // copy name into group, init count to 1 - isentencegs++; - if (isentencegs >= CSENTENCEG_MAX) - { - ALERT (at_error, "Too many sentence groups in sentences.txt!\n"); - break; - } - - strcpy(rgsentenceg[isentencegs].szgroupname, &(buffer[i])); - rgsentenceg[isentencegs].count = 1; - - strcpy(szgroup, &(buffer[i])); - - continue; - } - else - { - //name matches with previous, increment group count - if (isentencegs >= 0) - rgsentenceg[isentencegs].count++; - } - } - - g_engfuncs.pfnFreeFile( pMemFile ); - - fSentencesInit = TRUE; - - // init lru lists - - i = 0; - - while (rgsentenceg[i].count && i < CSENTENCEG_MAX) - { - USENTENCEG_InitLRU(&(rgsentenceg[i].rgblru[0]), rgsentenceg[i].count); - i++; - } - -} - -// convert sentence (sample) name to !sentencenum, return !sentencenum - -int SENTENCEG_Lookup(const char *sample, char *sentencenum) -{ - char sznum[8]; - int i; - - // this is a sentence name; lookup sentence number - // and give to engine as string. - for (i = 0; i < gcallsentences; i++) - if (!stricmp(gszallsentencenames[i], sample+1)) - { - if (sentencenum) - { - strcpy(sentencenum, "!"); - // Shepard - UNTESTED LINUX FIX!!! -#ifdef WIN32 - itoa(i, sznum, 10); -#else - i = atol(sznum); -#endif - strcat(sentencenum, sznum); - } - return i; - } - // sentence name not found! - return -1; -} - -void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, - int flags, int pitch) -{ - if (sample && *sample == '!') - { - char name[32]; - if (SENTENCEG_Lookup(sample, name) >= 0) - EMIT_SOUND_DYN2(entity, channel, name, volume, attenuation, flags, pitch); - else - ALERT( at_aiconsole, "Unable to find %s in sentences.txt\n", sample ); - } - else - EMIT_SOUND_DYN2(entity, channel, sample, volume, attenuation, flags, pitch); -} - -// play a specific sentence over the HEV suit speaker - just pass player entity, and !sentencename - -void EMIT_SOUND_SUIT(edict_t *entity, const char *sample) -{ - float fvol; - int pitch = PITCH_NORM; - - fvol = CVAR_GET_FLOAT("suitvolume"); - if (RANDOM_LONG(0,1)) - pitch = RANDOM_LONG(0,6) + 98; - - if (fvol > 0.05) - EMIT_SOUND_DYN(entity, CHAN_STATIC, sample, fvol, ATTN_NORM, 0, pitch); -} - -// play a sentence, randomly selected from the passed in group id, over the HEV suit speaker - -void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg) -{ - float fvol; - int pitch = PITCH_NORM; - - fvol = CVAR_GET_FLOAT("suitvolume"); - if (RANDOM_LONG(0,1)) - pitch = RANDOM_LONG(0,6) + 98; - - if (fvol > 0.05) - SENTENCEG_PlayRndI(entity, isentenceg, fvol, ATTN_NORM, 0, pitch); -} - -// play a sentence, randomly selected from the passed in groupname - -void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname) -{ - float fvol; - int pitch = PITCH_NORM; - - fvol = CVAR_GET_FLOAT("suitvolume"); - if (RANDOM_LONG(0,1)) - pitch = RANDOM_LONG(0,6) + 98; - - if (fvol > 0.05) - SENTENCEG_PlayRndSz(entity, groupname, fvol, ATTN_NORM, 0, pitch); -} - -// ===================== MATERIAL TYPE DETECTION, MAIN ROUTINES ======================== -// -// Used to detect the texture the player is standing on, map the -// texture name to a material type. Play footstep sound based -// on material type. - -int fTextureTypeInit = FALSE; - -#define CTEXTURESMAX 512 // max number of textures loaded - -int gcTextures = 0; -char grgszTextureName[CTEXTURESMAX][CBTEXTURENAMEMAX]; // texture names -char grgchTextureType[CTEXTURESMAX]; // parallel array of texture types - -// open materials.txt, get size, alloc space, -// save in array. Only works first time called, -// ignored on subsequent calls. - -static char *memfgets( byte *pMemFile, int fileSize, int &filePos, char *pBuffer, int bufferSize ) -{ - // Bullet-proofing - if ( !pMemFile || !pBuffer ) - return NULL; - - if ( filePos >= fileSize ) - return NULL; - - int i = filePos; - int last = fileSize; - - // fgets always NULL terminates, so only read bufferSize-1 characters - if ( last - filePos > (bufferSize-1) ) - last = filePos + (bufferSize-1); - - int stop = 0; - - // Stop at the next newline (inclusive) or end of buffer - while ( i < last && !stop ) - { - if ( pMemFile[i] == '\n' ) - stop = 1; - i++; - } - - - // If we actually advanced the pointer, copy it over - if ( i != filePos ) - { - // We read in size bytes - int size = i - filePos; - // copy it out - memcpy( pBuffer, pMemFile + filePos, sizeof(byte)*size ); - - // If the buffer isn't full, terminate (this is always true) - if ( size < bufferSize ) - pBuffer[size] = 0; - - // Update file pointer - filePos = i; - return pBuffer; - } - - // No data read, bail - return NULL; -} - - -void TEXTURETYPE_Init() -{ - char buffer[512]; - int i, j; - byte *pMemFile; - int fileSize, filePos; - - if (fTextureTypeInit) - return; - - memset(&(grgszTextureName[0][0]), 0, CTEXTURESMAX * CBTEXTURENAMEMAX); - memset(grgchTextureType, 0, CTEXTURESMAX); - - gcTextures = 0; - memset(buffer, 0, 512); - - pMemFile = g_engfuncs.pfnLoadFileForMe( "sound/materials.txt", &fileSize ); - if ( !pMemFile ) - return; - - // for each line in the file... - while (memfgets(pMemFile, fileSize, filePos, buffer, 511) != NULL && (gcTextures < CTEXTURESMAX)) - { - // skip whitespace - i = 0; - while(buffer[i] && isspace(buffer[i])) - i++; - - if (!buffer[i]) - continue; - - // skip comment lines - if (buffer[i] == '/' || !isalpha(buffer[i])) - continue; - - // get texture type - grgchTextureType[gcTextures] = toupper(buffer[i++]); - - // skip whitespace - while(buffer[i] && isspace(buffer[i])) - i++; - - if (!buffer[i]) - continue; - - // get sentence name - j = i; - while (buffer[j] && !isspace(buffer[j])) - j++; - - if (!buffer[j]) - continue; - - // null-terminate name and save in sentences array - j = V_min (j, CBTEXTURENAMEMAX-1+i); - buffer[j] = 0; - strcpy(&(grgszTextureName[gcTextures++][0]), &(buffer[i])); - } - - g_engfuncs.pfnFreeFile( pMemFile ); - - fTextureTypeInit = TRUE; -} - -// given texture name, find texture type -// if not found, return type 'concrete' - -// NOTE: this routine should ONLY be called if the -// current texture under the player changes! - -char TEXTURETYPE_Find(char *name) -{ - // CONSIDER: pre-sort texture names and perform faster binary search here - - for (int i = 0; i < gcTextures; i++) - { - if (!_strnicmp(name, &(grgszTextureName[i][0]), CBTEXTURENAMEMAX-1)) - return (grgchTextureType[i]); - } - - return CHAR_TEX_CONCRETE; -} - -// play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the -// original traceline endpoints used by the attacker, iBulletType is the type of bullet that hit the texture. -// returns volume of strike instrument (crowbar) to play - -float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int iBulletType) -{ -// hit the world, try to play sound based on texture material type - - char chTextureType; - float fvol; - float fvolbar; - char szbuffer[64]; - const char *pTextureName; - float rgfl1[3]; - float rgfl2[3]; - char *rgsz[4]; - int cnt; - float fattn = ATTN_NORM; - - if ( !g_pGameRules->PlayTextureSounds() ) - return 0.0; - - CBaseEntity *pEntity = CBaseEntity::Instance(ptr->pHit); - - chTextureType = 0; - - if (pEntity && pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE) - // hit body - chTextureType = CHAR_TEX_FLESH; - else - { - // hit world - - // find texture under strike, get material type - - // copy trace vector into array for trace_texture - - vecSrc.CopyToArray(rgfl1); - vecEnd.CopyToArray(rgfl2); - - // get texture from entity or world (world is ent(0)) - if (pEntity) - pTextureName = TRACE_TEXTURE( ENT(pEntity->pev), rgfl1, rgfl2 ); - else - pTextureName = TRACE_TEXTURE( ENT(0), rgfl1, rgfl2 ); - - if ( pTextureName ) - { - // strip leading '-0' or '+0~' or '{' or '!' - if (*pTextureName == '-' || *pTextureName == '+') - pTextureName += 2; - - if (*pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ') - pTextureName++; - // '}}' - strcpy(szbuffer, pTextureName); - szbuffer[CBTEXTURENAMEMAX - 1] = 0; - - // ALERT ( at_console, "texture hit: %s\n", szbuffer); - - // get texture type - chTextureType = TEXTURETYPE_Find(szbuffer); - } - } - - switch (chTextureType) - { - default: - case CHAR_TEX_CONCRETE: fvol = 0.9; fvolbar = 0.6; - rgsz[0] = "player/pl_step1.wav"; - rgsz[1] = "player/pl_step2.wav"; - cnt = 2; - break; - case CHAR_TEX_METAL: fvol = 0.9; fvolbar = 0.3; - rgsz[0] = "player/pl_metal1.wav"; - rgsz[1] = "player/pl_metal2.wav"; - cnt = 2; - break; - case CHAR_TEX_DIRT: fvol = 0.9; fvolbar = 0.1; - rgsz[0] = "player/pl_dirt1.wav"; - rgsz[1] = "player/pl_dirt2.wav"; - rgsz[2] = "player/pl_dirt3.wav"; - cnt = 3; - break; - case CHAR_TEX_VENT: fvol = 0.5; fvolbar = 0.3; - rgsz[0] = "player/pl_duct1.wav"; - rgsz[1] = "player/pl_duct1.wav"; - cnt = 2; - break; - case CHAR_TEX_GRATE: fvol = 0.9; fvolbar = 0.5; - rgsz[0] = "player/pl_grate1.wav"; - rgsz[1] = "player/pl_grate4.wav"; - cnt = 2; - break; - case CHAR_TEX_TILE: fvol = 0.8; fvolbar = 0.2; - rgsz[0] = "player/pl_tile1.wav"; - rgsz[1] = "player/pl_tile3.wav"; - rgsz[2] = "player/pl_tile2.wav"; - rgsz[3] = "player/pl_tile4.wav"; - cnt = 4; - break; - case CHAR_TEX_SLOSH: fvol = 0.9; fvolbar = 0.0; - rgsz[0] = "player/pl_slosh1.wav"; - rgsz[1] = "player/pl_slosh3.wav"; - rgsz[2] = "player/pl_slosh2.wav"; - rgsz[3] = "player/pl_slosh4.wav"; - cnt = 4; - break; - case CHAR_TEX_WOOD: fvol = 0.9; fvolbar = 0.2; - rgsz[0] = "debris/wood1.wav"; - rgsz[1] = "debris/wood2.wav"; - rgsz[2] = "debris/wood3.wav"; - cnt = 3; - break; - case CHAR_TEX_GLASS: - case CHAR_TEX_COMPUTER: - fvol = 0.8; fvolbar = 0.2; - rgsz[0] = "debris/glass1.wav"; - rgsz[1] = "debris/glass2.wav"; - rgsz[2] = "debris/glass3.wav"; - cnt = 3; - break; - case CHAR_TEX_FLESH: - if (iBulletType == BULLET_PLAYER_CROWBAR) - return 0.0; // crowbar already makes this sound - fvol = 1.0; fvolbar = 0.2; - rgsz[0] = "weapons/bullet_hit1.wav"; - rgsz[1] = "weapons/bullet_hit2.wav"; - fattn = 1.0; - cnt = 2; - break; - } - - // did we hit a breakable? - - if (pEntity && FClassnameIs(pEntity->pev, "func_breakable")) - { - // drop volumes, the object will already play a damaged sound - fvol /= 1.5; - fvolbar /= 2.0; - } - else if (chTextureType == CHAR_TEX_COMPUTER) - { - // play random spark if computer - - if ( ptr->flFraction != 1.0 && RANDOM_LONG(0,1)) - { - UTIL_Sparks( ptr->vecEndPos ); - - float flVolume = RANDOM_FLOAT ( 0.7 , 1.0 );//random volume range - switch ( RANDOM_LONG(0,1) ) - { - case 0: UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, "buttons/spark5.wav", flVolume, ATTN_NORM, 0, 100); break; - case 1: UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, "buttons/spark6.wav", flVolume, ATTN_NORM, 0, 100); break; - // case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM); break; - // case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM); break; - } - } - } - - // play material hit sound - UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, rgsz[RANDOM_LONG(0,cnt-1)], fvol, fattn, 0, 96 + RANDOM_LONG(0,0xf)); - //EMIT_SOUND_DYN( ENT(m_pPlayer->pev), CHAN_WEAPON, rgsz[RANDOM_LONG(0,cnt-1)], fvol, ATTN_NORM, 0, 96 + RANDOM_LONG(0,0xf)); - - return fvolbar; -} - -// =================================================================================== -// -// Speaker class. Used for announcements per level, for door lock/unlock spoken voice. -// - -class CSpeaker : public CBaseEntity -{ -public: - void KeyValue( KeyValueData* pkvd); - void Spawn( void ); - void Precache( void ); - void EXPORT ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT SpeakerThink( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } - - int m_preset; // preset number -}; - -LINK_ENTITY_TO_CLASS( speaker, CSpeaker ); -TYPEDESCRIPTION CSpeaker::m_SaveData[] = -{ - DEFINE_FIELD( CSpeaker, m_preset, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CSpeaker, CBaseEntity ); - -// -// ambient_generic - general-purpose user-defined static sound -// -void CSpeaker :: Spawn( void ) -{ - char* szSoundFile = (char*) STRING(pev->message); - - if ( !m_preset && (FStringNull( pev->message ) || strlen( szSoundFile ) < 1 )) - { - ALERT( at_error, "SPEAKER with no Level/Sentence! at: %f, %f, %f\n", pev->origin.x, pev->origin.y, pev->origin.z ); - pev->nextthink = gpGlobals->time + 0.1; - SetThink( &CSpeaker::SUB_Remove ); - return; - } - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - - - SetThink(&CSpeaker::SpeakerThink); - pev->nextthink = 0.0; - - // allow on/off switching via 'use' function. - - SetUse ( &CSpeaker::ToggleUse ); - - Precache( ); -} - -#define ANNOUNCE_MINUTES_MIN 0.25 -#define ANNOUNCE_MINUTES_MAX 2.25 - -void CSpeaker :: Precache( void ) -{ - if ( !FBitSet (pev->spawnflags, SPEAKER_START_SILENT ) ) - // set first announcement time for random n second - pev->nextthink = gpGlobals->time + RANDOM_FLOAT(5.0, 15.0); -} -void CSpeaker :: SpeakerThink( void ) -{ - char* szSoundFile; - float flvolume = pev->health * 0.1; - float flattenuation = 0.3; - int flags = 0; - int pitch = 100; - - if (m_preset) - { - // go lookup preset text, assign szSoundFile - switch (m_preset) - { - case 1: szSoundFile = "C1A0_"; break; - case 2: szSoundFile = "C1A1_"; break; - case 3: szSoundFile = "C1A2_"; break; - case 4: szSoundFile = "C1A3_"; break; - case 5: szSoundFile = "C1A4_"; break; - case 6: szSoundFile = "C2A1_"; break; - case 7: szSoundFile = "C2A2_"; break; - case 8: szSoundFile = "C2A3_"; break; - case 9: szSoundFile = "C2A4_"; break; - case 10: szSoundFile = "C2A5_"; break; - case 11: szSoundFile = "C3A1_"; break; - case 12: szSoundFile = "C3A2_"; break; - } - } else - szSoundFile = (char*) STRING(pev->message); - - if (szSoundFile[0] == '!') - { - // play single sentence, one shot - UTIL_EmitAmbientSound ( ENT(pev), pev->origin, szSoundFile, - flvolume, flattenuation, flags, pitch); - - // shut off and reset - pev->nextthink = 0.0; - } - else - { - // make random announcement from sentence group - - if (SENTENCEG_PlayRndSz(ENT(pev), szSoundFile, flvolume, flattenuation, flags, pitch) < 0) - ALERT(at_console, "Level Design Error!\nSPEAKER has bad sentence group name: %s\n",szSoundFile); - - // set next announcement time for random 5 to 10 minute delay - pev->nextthink = gpGlobals->time + - RANDOM_FLOAT(ANNOUNCE_MINUTES_MIN * 60.0, ANNOUNCE_MINUTES_MAX * 60.0); - } - - return; -} - - -// -// ToggleUse - if an announcement is pending, cancel it. If no announcement is pending, start one. -// -void CSpeaker :: ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int fActive = (pev->nextthink > 0.0); - - // fActive is TRUE only if an announcement is pending - - if ( useType != USE_TOGGLE ) - { - // ignore if we're just turning something on that's already on, or - // turning something off that's already off. - if ( (fActive && useType == USE_ON) || (!fActive && useType == USE_OFF) ) - return; - } - - if ( useType == USE_ON ) - { - // turn on announcements - pev->nextthink = gpGlobals->time + 0.1; - return; - } - - if ( useType == USE_OFF ) - { - // turn off announcements - pev->nextthink = 0.0; - return; - - } - - // Toggle announcements - - - if ( fActive ) - { - // turn off announcements - pev->nextthink = 0.0; - } - else - { - // turn on announcements - pev->nextthink = gpGlobals->time + 0.1; - } -} - -// KeyValue - load keyvalue pairs into member data -// NOTE: called BEFORE spawn! - -void CSpeaker :: KeyValue( KeyValueData *pkvd ) -{ - - // preset - if (FStrEq(pkvd->szKeyName, "preset")) - { - m_preset = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} diff --git a/dmc/dlls/soundent.cpp b/dmc/dlls/soundent.cpp deleted file mode 100644 index ffd5786..0000000 --- a/dmc/dlls/soundent.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "soundent.h" - - -LINK_ENTITY_TO_CLASS( soundent, CSoundEnt ); - -CSoundEnt *pSoundEnt; - -//========================================================= -// CSound - Clear - zeros all fields for a sound -//========================================================= -void CSound :: Clear ( void ) -{ - m_vecOrigin = g_vecZero; - m_iType = 0; - m_iVolume = 0; - m_flExpireTime = 0; - m_iNext = SOUNDLIST_EMPTY; - m_iNextAudible = 0; -} - -//========================================================= -// Reset - clears the volume, origin, and type for a sound, -// but doesn't expire or unlink it. -//========================================================= -void CSound :: Reset ( void ) -{ - m_vecOrigin = g_vecZero; - m_iType = 0; - m_iVolume = 0; - m_iNext = SOUNDLIST_EMPTY; -} - -//========================================================= -// FIsSound - returns TRUE if the sound is an Audible sound -//========================================================= -BOOL CSound :: FIsSound ( void ) -{ - if ( m_iType & ( bits_SOUND_COMBAT | bits_SOUND_WORLD | bits_SOUND_PLAYER | bits_SOUND_DANGER ) ) - { - return TRUE; - } - - return FALSE; -} - -//========================================================= -// FIsScent - returns TRUE if the sound is actually a scent -//========================================================= -BOOL CSound :: FIsScent ( void ) -{ - if ( m_iType & ( bits_SOUND_CARCASS | bits_SOUND_MEAT | bits_SOUND_GARBAGE ) ) - { - return TRUE; - } - - return FALSE; -} - -//========================================================= -// Spawn -//========================================================= -void CSoundEnt :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - Initialize(); - - pev->nextthink = gpGlobals->time + 1; -} - -//========================================================= -// Think - at interval, the entire active sound list is checked -// for sounds that have ExpireTimes less than or equal -// to the current world time, and these sounds are deallocated. -//========================================================= -void CSoundEnt :: Think ( void ) -{ - int iSound; - int iPreviousSound; - - pev->nextthink = gpGlobals->time + 0.3;// how often to check the sound list. - - iPreviousSound = SOUNDLIST_EMPTY; - iSound = m_iActiveSound; - - while ( iSound != SOUNDLIST_EMPTY ) - { - if ( m_SoundPool[ iSound ].m_flExpireTime <= gpGlobals->time && m_SoundPool[ iSound ].m_flExpireTime != SOUND_NEVER_EXPIRE ) - { - int iNext = m_SoundPool[ iSound ].m_iNext; - - // move this sound back into the free list - FreeSound( iSound, iPreviousSound ); - - iSound = iNext; - } - else - { - iPreviousSound = iSound; - iSound = m_SoundPool[ iSound ].m_iNext; - } - } - - if ( m_fShowReport ) - { - ALERT ( at_aiconsole, "Soundlist: %d / %d (%d)\n", ISoundsInList( SOUNDLISTTYPE_ACTIVE ),ISoundsInList( SOUNDLISTTYPE_FREE ), ISoundsInList( SOUNDLISTTYPE_ACTIVE ) - m_cLastActiveSounds ); - m_cLastActiveSounds = ISoundsInList ( SOUNDLISTTYPE_ACTIVE ); - } - -} - -//========================================================= -// Precache - dummy function -//========================================================= -void CSoundEnt :: Precache ( void ) -{ -} - -//========================================================= -// FreeSound - clears the passed active sound and moves it -// to the top of the free list. TAKE CARE to only call this -// function for sounds in the Active list!! -//========================================================= -void CSoundEnt :: FreeSound ( int iSound, int iPrevious ) -{ - if ( !pSoundEnt ) - { - // no sound ent! - return; - } - - if ( iPrevious != SOUNDLIST_EMPTY ) - { - // iSound is not the head of the active list, so - // must fix the index for the Previous sound -// pSoundEnt->m_SoundPool[ iPrevious ].m_iNext = m_SoundPool[ iSound ].m_iNext; - pSoundEnt->m_SoundPool[ iPrevious ].m_iNext = pSoundEnt->m_SoundPool[ iSound ].m_iNext; - } - else - { - // the sound we're freeing IS the head of the active list. - pSoundEnt->m_iActiveSound = pSoundEnt->m_SoundPool [ iSound ].m_iNext; - } - - // make iSound the head of the Free list. - pSoundEnt->m_SoundPool[ iSound ].m_iNext = pSoundEnt->m_iFreeSound; - pSoundEnt->m_iFreeSound = iSound; -} - -//========================================================= -// IAllocSound - moves a sound from the Free list to the -// Active list returns the index of the alloc'd sound -//========================================================= -int CSoundEnt :: IAllocSound( void ) -{ - int iNewSound; - - if ( m_iFreeSound == SOUNDLIST_EMPTY ) - { - // no free sound! - ALERT ( at_console, "Free Sound List is full!\n" ); - return SOUNDLIST_EMPTY; - } - - // there is at least one sound available, so move it to the - // Active sound list, and return its SoundPool index. - - iNewSound = m_iFreeSound;// copy the index of the next free sound - - m_iFreeSound = m_SoundPool[ m_iFreeSound ].m_iNext;// move the index down into the free list. - - m_SoundPool[ iNewSound ].m_iNext = m_iActiveSound;// point the new sound at the top of the active list. - - m_iActiveSound = iNewSound;// now make the new sound the top of the active list. You're done. - - return iNewSound; -} - -//========================================================= -// InsertSound - Allocates a free sound and fills it with -// sound info. -//========================================================= -void CSoundEnt :: InsertSound ( int iType, const Vector &vecOrigin, int iVolume, float flDuration ) -{ - int iThisSound; - - if ( !pSoundEnt ) - { - // no sound ent! - return; - } - - iThisSound = pSoundEnt->IAllocSound(); - - if ( iThisSound == SOUNDLIST_EMPTY ) - { - ALERT ( at_console, "Could not AllocSound() for InsertSound() (DLL)\n" ); - return; - } - - pSoundEnt->m_SoundPool[ iThisSound ].m_vecOrigin = vecOrigin; - pSoundEnt->m_SoundPool[ iThisSound ].m_iType = iType; - pSoundEnt->m_SoundPool[ iThisSound ].m_iVolume = iVolume; - pSoundEnt->m_SoundPool[ iThisSound ].m_flExpireTime = gpGlobals->time + flDuration; -} - -//========================================================= -// Initialize - clears all sounds and moves them into the -// free sound list. -//========================================================= -void CSoundEnt :: Initialize ( void ) -{ - int i; - int iSound; - - m_cLastActiveSounds; - m_iFreeSound = 0; - m_iActiveSound = SOUNDLIST_EMPTY; - - for ( i = 0 ; i < MAX_WORLD_SOUNDS ; i++ ) - {// clear all sounds, and link them into the free sound list. - m_SoundPool[ i ].Clear(); - m_SoundPool[ i ].m_iNext = i + 1; - } - - m_SoundPool[ i - 1 ].m_iNext = SOUNDLIST_EMPTY;// terminate the list here. - - - // now reserve enough sounds for each client - for ( i = 0 ; i < gpGlobals->maxClients ; i++ ) - { - iSound = pSoundEnt->IAllocSound(); - - if ( iSound == SOUNDLIST_EMPTY ) - { - ALERT ( at_console, "Could not AllocSound() for Client Reserve! (DLL)\n" ); - return; - } - - pSoundEnt->m_SoundPool[ iSound ].m_flExpireTime = SOUND_NEVER_EXPIRE; - } - - if ( CVAR_GET_FLOAT("displaysoundlist") == 1 ) - { - m_fShowReport = TRUE; - } - else - { - m_fShowReport = FALSE; - } -} - -//========================================================= -// ISoundsInList - returns the number of sounds in the desired -// sound list. -//========================================================= -int CSoundEnt :: ISoundsInList ( int iListType ) -{ - int i; - int iThisSound; - - if ( iListType == SOUNDLISTTYPE_FREE ) - { - iThisSound = m_iFreeSound; - } - else if ( iListType == SOUNDLISTTYPE_ACTIVE ) - { - iThisSound = m_iActiveSound; - } - else - { - ALERT ( at_console, "Unknown Sound List Type!\n" ); - } - - if ( iThisSound == SOUNDLIST_EMPTY ) - { - return 0; - } - - i = 0; - - while ( iThisSound != SOUNDLIST_EMPTY ) - { - i++; - - iThisSound = m_SoundPool[ iThisSound ].m_iNext; - } - - return i; -} - -//========================================================= -// ActiveList - returns the head of the active sound list -//========================================================= -int CSoundEnt :: ActiveList ( void ) -{ - if ( !pSoundEnt ) - { - return SOUNDLIST_EMPTY; - } - - return pSoundEnt->m_iActiveSound; -} - -//========================================================= -// FreeList - returns the head of the free sound list -//========================================================= -int CSoundEnt :: FreeList ( void ) -{ - if ( !pSoundEnt ) - { - return SOUNDLIST_EMPTY; - } - - return pSoundEnt->m_iFreeSound; -} - -//========================================================= -// SoundPointerForIndex - returns a pointer to the instance -// of CSound at index's position in the sound pool. -//========================================================= -CSound* CSoundEnt :: SoundPointerForIndex( int iIndex ) -{ - if ( !pSoundEnt ) - { - return NULL; - } - - if ( iIndex > ( MAX_WORLD_SOUNDS - 1 ) ) - { - ALERT ( at_console, "SoundPointerForIndex() - Index too large!\n" ); - return NULL; - } - - if ( iIndex < 0 ) - { - ALERT ( at_console, "SoundPointerForIndex() - Index < 0!\n" ); - return NULL; - } - - return &pSoundEnt->m_SoundPool[ iIndex ]; -} - -//========================================================= -// Clients are numbered from 1 to MAXCLIENTS, but the client -// reserved sounds in the soundlist are from 0 to MAXCLIENTS - 1, -// so this function ensures that a client gets the proper index -// to his reserved sound in the soundlist. -//========================================================= -int CSoundEnt :: ClientSoundIndex ( edict_t *pClient ) -{ - int iReturn = ENTINDEX( pClient ) - 1; - -#ifdef _DEBUG - if ( iReturn < 0 || iReturn > gpGlobals->maxClients ) - { - ALERT ( at_console, "** ClientSoundIndex returning a bogus value! **\n" ); - } -#endif // _DEBUG - - return iReturn; -} \ No newline at end of file diff --git a/dmc/dlls/soundent.h b/dmc/dlls/soundent.h deleted file mode 100644 index 150daac..0000000 --- a/dmc/dlls/soundent.h +++ /dev/null @@ -1,95 +0,0 @@ -/*** -* -* 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. -* -****/ -//========================================================= -// Soundent.h - the entity that spawns when the world -// spawns, and handles the world's active and free sound -// lists. -//========================================================= - -#define MAX_WORLD_SOUNDS 64 // maximum number of sounds handled by the world at one time. - -#define bits_SOUND_NONE 0 -#define bits_SOUND_COMBAT ( 1 << 0 )// gunshots, explosions -#define bits_SOUND_WORLD ( 1 << 1 )// door opening/closing, glass breaking -#define bits_SOUND_PLAYER ( 1 << 2 )// all noises generated by player. walking, shooting, falling, splashing -#define bits_SOUND_CARCASS ( 1 << 3 )// dead body -#define bits_SOUND_MEAT ( 1 << 4 )// gib or pork chop -#define bits_SOUND_DANGER ( 1 << 5 )// pending danger. Grenade that is about to explode, explosive barrel that is damaged, falling crate -#define bits_SOUND_GARBAGE ( 1 << 6 )// trash cans, banana peels, old fast food bags. - -#define bits_ALL_SOUNDS 0xFFFFFFFF - -#define SOUNDLIST_EMPTY -1 - -#define SOUNDLISTTYPE_FREE 1// identifiers passed to functions that can operate on either list, to indicate which list to operate on. -#define SOUNDLISTTYPE_ACTIVE 2 - -#define SOUND_NEVER_EXPIRE -1 // with this set as a sound's ExpireTime, the sound will never expire. - -//========================================================= -// CSound - an instance of a sound in the world. -//========================================================= -class CSound -{ -public: - - void Clear ( void ); - void Reset ( void ); - - Vector m_vecOrigin; // sound's location in space - int m_iType; // what type of sound this is - int m_iVolume; // how loud the sound is - float m_flExpireTime; // when the sound should be purged from the list - int m_iNext; // index of next sound in this list ( Active or Free ) - int m_iNextAudible; // temporary link that monsters use to build a list of audible sounds - - BOOL FIsSound( void ); - BOOL FIsScent( void ); -}; - -//========================================================= -// CSoundEnt - a single instance of this entity spawns when -// the world spawns. The SoundEnt's job is to update the -// world's Free and Active sound lists. -//========================================================= -class CSoundEnt : public CBaseEntity -{ -public: - - void Precache ( void ); - void Spawn( void ); - void Think( void ); - void Initialize ( void ); - - static void InsertSound ( int iType, const Vector &vecOrigin, int iVolume, float flDuration ); - static void FreeSound ( int iSound, int iPrevious ); - static int ActiveList( void );// return the head of the active list - static int FreeList( void );// return the head of the free list - static CSound* SoundPointerForIndex( int iIndex );// return a pointer for this index in the sound list - static int ClientSoundIndex ( edict_t *pClient ); - - BOOL IsEmpty( void ) { return m_iActiveSound == SOUNDLIST_EMPTY; } - int ISoundsInList ( int iListType ); - int IAllocSound ( void ); - virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; } - - int m_iFreeSound; // index of the first sound in the free sound list - int m_iActiveSound; // indes of the first sound in the active sound list - int m_cLastActiveSounds; // keeps track of the number of active sounds at the last update. (for diagnostic work) - BOOL m_fShowReport; // if true, dump information about free/active sounds. - -private: - CSound m_SoundPool[ MAX_WORLD_SOUNDS ]; -}; diff --git a/dmc/dlls/spectator.cpp b/dmc/dlls/spectator.cpp deleted file mode 100644 index 5f91731..0000000 --- a/dmc/dlls/spectator.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/*** -* -* 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. -* -****/ -// CBaseSpectator - -// YWB: UNDONE - -// Spectator functions -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "spectator.h" - -/* -=========== -SpectatorConnect - -called when a spectator connects to a server -============ -*/ -void CBaseSpectator::SpectatorConnect(void) -{ - pev->flags = FL_SPECTATOR; - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NOCLIP; - - m_pGoalEnt = NULL; -} - -/* -=========== -SpectatorDisconnect - -called when a spectator disconnects from a server -============ -*/ -void CBaseSpectator::SpectatorDisconnect(void) -{ -} - -/* -================ -SpectatorImpulseCommand - -Called by SpectatorThink if the spectator entered an impulse -================ -*/ -void CBaseSpectator::SpectatorImpulseCommand(void) -{ - static edict_t *pGoal = NULL; - edict_t *pPreviousGoal; - edict_t *pCurrentGoal; - BOOL bFound; - - switch (pev->impulse) - { - case 1: - // teleport the spectator to the next spawn point - // note that if the spectator is tracking, this doesn't do - // much - pPreviousGoal = pGoal; - pCurrentGoal = pGoal; - // Start at the current goal, skip the world, and stop if we looped - // back around - - bFound = FALSE; - while (1) - { - pCurrentGoal = FIND_ENTITY_BY_CLASSNAME(pCurrentGoal, "info_player_deathmatch"); - // Looped around, failure - if (pCurrentGoal == pPreviousGoal) - { - ALERT(at_console, "Could not find a spawn spot.\n"); - break; - } - // Found a non-world entity, set success, otherwise, look for the next one. - if (!FNullEnt(pCurrentGoal)) - { - bFound = TRUE; - break; - } - } - - if (!bFound) // Didn't find a good spot. - break; - - pGoal = pCurrentGoal; - UTIL_SetOrigin( pev, pGoal->v.origin ); - pev->angles = pGoal->v.angles; - pev->fixangle = FALSE; - break; - default: - ALERT(at_console, "Unknown spectator impulse\n"); - break; - } - - pev->impulse = 0; -} - -/* -================ -SpectatorThink - -Called every frame after physics are run -================ -*/ -void CBaseSpectator::SpectatorThink(void) -{ - if (!(pev->flags & FL_SPECTATOR)) - { - pev->flags = FL_SPECTATOR; - } - - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NOCLIP; - - if (pev->impulse) - SpectatorImpulseCommand(); -} - -/* -=========== -Spawn - - Called when spectator is initialized: - UNDONE: Is this actually being called because spectators are not allocated in normal fashion? -============ -*/ -void CBaseSpectator::Spawn() -{ - pev->flags = FL_SPECTATOR; - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NOCLIP; - - m_pGoalEnt = NULL; -} diff --git a/dmc/dlls/spectator.h b/dmc/dlls/spectator.h deleted file mode 100644 index 2f755d6..0000000 --- a/dmc/dlls/spectator.h +++ /dev/null @@ -1,27 +0,0 @@ -/*** -* -* 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. -* -****/ -// Spectator.h - -class CBaseSpectator : public CBaseEntity -{ -public: - void Spawn(); - void SpectatorConnect(void); - void SpectatorDisconnect(void); - void SpectatorThink(void); - -private: - void SpectatorImpulseCommand(void); -}; diff --git a/dmc/dlls/subs.cpp b/dmc/dlls/subs.cpp deleted file mode 100644 index d3560bd..0000000 --- a/dmc/dlls/subs.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== subs.cpp ======================================================== - - frequently used global functions - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "nodes.h" -#include "doors.h" - -extern CGraph WorldGraph; - -extern BOOL FEntIsVisible(entvars_t* pev, entvars_t* pevTarget); - -extern DLL_GLOBAL int g_iSkillLevel; - - -// Landmark class -void CPointEntity :: Spawn( void ) -{ - pev->solid = SOLID_NOT; -// UTIL_SetSize(pev, g_vecZero, g_vecZero); -} - - -class CNullEntity : public CBaseEntity -{ -public: - void Spawn( void ); -}; - - -// Null Entity, remove on startup -void CNullEntity :: Spawn( void ) -{ - REMOVE_ENTITY(ENT(pev)); -} -LINK_ENTITY_TO_CLASS(info_null,CNullEntity); - -class CBaseDMStart : public CPointEntity -{ -public: - void KeyValue( KeyValueData *pkvd ); - BOOL IsTriggered( CBaseEntity *pEntity ); - -private: -}; - -// These are the new entry points to entities. -LINK_ENTITY_TO_CLASS(info_player_deathmatch,CBaseDMStart); -LINK_ENTITY_TO_CLASS(info_player_start,CPointEntity); -LINK_ENTITY_TO_CLASS(info_landmark,CPointEntity); - -void CBaseDMStart::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "master")) - { - pev->netname = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -BOOL CBaseDMStart::IsTriggered( CBaseEntity *pEntity ) -{ - BOOL master = UTIL_IsMasterTriggered( pev->netname, pEntity ); - - return master; -} - -// This updates global tables that need to know about entities being removed -void CBaseEntity::UpdateOnRemove( void ) -{ - int i; - - if ( FBitSet( pev->flags, FL_GRAPHED ) ) - { - // this entity was a LinkEnt in the world node graph, so we must remove it from - // the graph since we are removing it from the world. - for ( i = 0 ; i < WorldGraph.m_cLinks ; i++ ) - { - if ( WorldGraph.m_pLinkPool [ i ].m_pLinkEnt == pev ) - { - // if this link has a link ent which is the same ent that is removing itself, remove it! - WorldGraph.m_pLinkPool [ i ].m_pLinkEnt = NULL; - } - } - } - if ( pev->globalname ) - gGlobalState.EntitySetState( pev->globalname, GLOBAL_DEAD ); -} - -// Convenient way to delay removing oneself -void CBaseEntity :: SUB_Remove( void ) -{ - UpdateOnRemove(); - if (pev->health > 0) - { - // this situation can screw up monsters who can't tell their entity pointers are invalid. - pev->health = 0; - ALERT( at_aiconsole, "SUB_Remove called on entity with health > 0\n"); - } - - REMOVE_ENTITY(ENT(pev)); -} - - -// Convenient way to explicitly do nothing (passed to functions that require a method) -void CBaseEntity :: SUB_DoNothing( void ) -{ -} - - -// Global Savedata for Delay -TYPEDESCRIPTION CBaseDelay::m_SaveData[] = -{ - DEFINE_FIELD( CBaseDelay, m_flDelay, FIELD_FLOAT ), - DEFINE_FIELD( CBaseDelay, m_iszKillTarget, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CBaseDelay, CBaseEntity ); - -void CBaseDelay :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "delay")) - { - m_flDelay = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "killtarget")) - { - m_iszKillTarget = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - { - CBaseEntity::KeyValue( pkvd ); - } -} - - -/* -============================== -SUB_UseTargets - -If self.delay is set, a DelayedUse entity will be created that will actually -do the SUB_UseTargets after that many seconds have passed. - -Removes all entities with a targetname that match self.killtarget, -and removes them, so some events can remove other triggers. - -Search for (string)targetname in all entities that -match (string)self.target and call their .use function (if they have one) - -============================== -*/ -void CBaseEntity :: SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ) -{ - // - // fire targets - // - if (!FStringNull(pev->target)) - { - FireTargets( STRING(pev->target), pActivator, this, useType, value ); - } -} - - -void FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - edict_t *pentTarget = NULL; - if ( !targetName ) - return; - - ALERT( at_aiconsole, "Firing: (%s)\n", targetName ); - - for (;;) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, targetName); - if (FNullEnt(pentTarget)) - break; - - CBaseEntity *pTarget = CBaseEntity::Instance( pentTarget ); - if ( pTarget && !(pTarget->pev->flags & FL_KILLME) ) // Don't use dying ents - { - ALERT( at_aiconsole, "Found: %s, firing (%s)\n", STRING(pTarget->pev->classname), targetName ); - pTarget->Use( pActivator, pCaller, useType, value ); - } - } -} - -LINK_ENTITY_TO_CLASS( DelayedUse, CBaseDelay ); - - -void CBaseDelay :: SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ) -{ - // - // exit immediatly if we don't have a target or kill target - // - if (FStringNull(pev->target) && !m_iszKillTarget) - return; - - // - // check for a delay - // - if (m_flDelay != 0) - { - // create a temp object to fire at a later time - CBaseDelay *pTemp = GetClassPtr( (CBaseDelay *)NULL); - pTemp->pev->classname = MAKE_STRING("DelayedUse"); - - pTemp->pev->nextthink = gpGlobals->time + m_flDelay; - - pTemp->SetThink( &CBaseDelay::DelayThink ); - - // Save the useType - pTemp->pev->button = (int)useType; - pTemp->m_iszKillTarget = m_iszKillTarget; - pTemp->m_flDelay = 0; // prevent "recursion" - pTemp->pev->target = pev->target; - - // HACKHACK - // This wasn't in the release build of Half-Life. We should have moved m_hActivator into this class - // but changing member variable hierarchy would break save/restore without some ugly code. - // This code is not as ugly as that code - if ( pActivator && pActivator->IsPlayer() ) // If a player activates, then save it - { - pTemp->pev->owner = pActivator->edict(); - } - else - { - pTemp->pev->owner = NULL; - } - - return; - } - - // - // kill the killtargets - // - - if ( m_iszKillTarget ) - { - edict_t *pentKillTarget = NULL; - - ALERT( at_aiconsole, "KillTarget: %s\n", STRING(m_iszKillTarget) ); - pentKillTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_iszKillTarget) ); - while ( !FNullEnt(pentKillTarget) ) - { - UTIL_Remove( CBaseEntity::Instance(pentKillTarget) ); - - ALERT( at_aiconsole, "killing %s\n", STRING( pentKillTarget->v.classname ) ); - pentKillTarget = FIND_ENTITY_BY_TARGETNAME( pentKillTarget, STRING(m_iszKillTarget) ); - } - } - - // - // fire targets - // - if (!FStringNull(pev->target)) - { - FireTargets( STRING(pev->target), pActivator, this, useType, value ); - } -} - - -/* -void CBaseDelay :: SUB_UseTargetsEntMethod( void ) -{ - SUB_UseTargets(pev); -} -*/ - -/* -QuakeEd only writes a single float for angles (bad idea), so up and down are -just constant angles. -*/ -void SetMovedir( entvars_t *pev ) -{ - if (pev->angles == Vector(0, -1, 0)) - { - pev->movedir = Vector(0, 0, 1); - } - else if (pev->angles == Vector(0, -2, 0)) - { - pev->movedir = Vector(0, 0, -1); - } - else - { - UTIL_MakeVectors(pev->angles); - pev->movedir = gpGlobals->v_forward; - } - - pev->angles = g_vecZero; -} - - - - -void CBaseDelay::DelayThink( void ) -{ - CBaseEntity *pActivator = NULL; - - if ( pev->owner != NULL ) // A player activated this on delay - { - pActivator = CBaseEntity::Instance( pev->owner ); - } - // The use type is cached (and stashed) in pev->button - SUB_UseTargets( pActivator, (USE_TYPE)pev->button, 0 ); - REMOVE_ENTITY(ENT(pev)); -} - - -// Global Savedata for Toggle -TYPEDESCRIPTION CBaseToggle::m_SaveData[] = -{ - DEFINE_FIELD( CBaseToggle, m_toggle_state, FIELD_INTEGER ), - DEFINE_FIELD( CBaseToggle, m_flActivateFinished, FIELD_TIME ), - DEFINE_FIELD( CBaseToggle, m_flMoveDistance, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_flWait, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_flLip, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_flTWidth, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_flTLength, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_vecPosition1, FIELD_POSITION_VECTOR ), - DEFINE_FIELD( CBaseToggle, m_vecPosition2, FIELD_POSITION_VECTOR ), - DEFINE_FIELD( CBaseToggle, m_vecAngle1, FIELD_VECTOR ), // UNDONE: Position could go through transition, but also angle? - DEFINE_FIELD( CBaseToggle, m_vecAngle2, FIELD_VECTOR ), // UNDONE: Position could go through transition, but also angle? - DEFINE_FIELD( CBaseToggle, m_cTriggersLeft, FIELD_INTEGER ), - DEFINE_FIELD( CBaseToggle, m_flHeight, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_hActivator, FIELD_EHANDLE ), - DEFINE_FIELD( CBaseToggle, m_pfnCallWhenMoveDone, FIELD_FUNCTION ), - DEFINE_FIELD( CBaseToggle, m_vecFinalDest, FIELD_POSITION_VECTOR ), - DEFINE_FIELD( CBaseToggle, m_vecFinalAngle, FIELD_VECTOR ), - DEFINE_FIELD( CBaseToggle, m_sMaster, FIELD_STRING), - DEFINE_FIELD( CBaseToggle, m_bitsDamageInflict, FIELD_INTEGER ), // damage type inflicted -}; -IMPLEMENT_SAVERESTORE( CBaseToggle, CBaseAnimating ); - - -void CBaseToggle::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "lip")) - { - m_flLip = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "master")) - { - m_sMaster = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "distance")) - { - m_flMoveDistance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - -/* -============= -LinearMove - -calculate pev->velocity and pev->nextthink to reach vecDest from -pev->origin traveling at flSpeed -=============== -*/ -void CBaseToggle :: LinearMove( Vector vecDest, float flSpeed ) -{ - ASSERTSZ(flSpeed != 0, "LinearMove: no speed is defined!"); -// ASSERTSZ(m_pfnCallWhenMoveDone != NULL, "LinearMove: no post-move function defined"); - - m_vecFinalDest = vecDest; - - // Already there? - if (vecDest == pev->origin) - { - LinearMoveDone(); - return; - } - - // set destdelta to the vector needed to move - Vector vecDestDelta = vecDest - pev->origin; - - // divide vector length by speed to get time to reach dest - float flTravelTime = vecDestDelta.Length() / flSpeed; - - // set nextthink to trigger a call to LinearMoveDone when dest is reached - pev->nextthink = pev->ltime + flTravelTime; - SetThink( &CBaseToggle::LinearMoveDone ); - - // scale the destdelta vector by the time spent traveling to get velocity - pev->velocity = vecDestDelta / flTravelTime; -} - - -/* -============ -After moving, set origin to exact final destination, call "move done" function -============ -*/ -void CBaseToggle :: LinearMoveDone( void ) -{ - UTIL_SetOrigin(pev, m_vecFinalDest); - pev->velocity = g_vecZero; - pev->nextthink = -1; - if ( m_pfnCallWhenMoveDone ) - (this->*m_pfnCallWhenMoveDone)(); -} - -BOOL CBaseToggle :: IsLockedByMaster( void ) -{ - if (m_sMaster && !UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) - return TRUE; - else - return FALSE; -} - -/* -============= -AngularMove - -calculate pev->velocity and pev->nextthink to reach vecDest from -pev->origin traveling at flSpeed -Just like LinearMove, but rotational. -=============== -*/ -void CBaseToggle :: AngularMove( Vector vecDestAngle, float flSpeed ) -{ - ASSERTSZ(flSpeed != 0, "AngularMove: no speed is defined!"); -// ASSERTSZ(m_pfnCallWhenMoveDone != NULL, "AngularMove: no post-move function defined"); - - m_vecFinalAngle = vecDestAngle; - - // Already there? - if (vecDestAngle == pev->angles) - { - AngularMoveDone(); - return; - } - - // set destdelta to the vector needed to move - Vector vecDestDelta = vecDestAngle - pev->angles; - - // divide by speed to get time to reach dest - float flTravelTime = vecDestDelta.Length() / flSpeed; - - // set nextthink to trigger a call to AngularMoveDone when dest is reached - pev->nextthink = pev->ltime + flTravelTime; - SetThink( &CBaseToggle::AngularMoveDone ); - - // scale the destdelta vector by the time spent traveling to get velocity - pev->avelocity = vecDestDelta / flTravelTime; -} - - -/* -============ -After rotating, set angle to exact final angle, call "move done" function -============ -*/ -void CBaseToggle :: AngularMoveDone( void ) -{ - pev->angles = m_vecFinalAngle; - pev->avelocity = g_vecZero; - pev->nextthink = -1; - if ( m_pfnCallWhenMoveDone ) - (this->*m_pfnCallWhenMoveDone)(); -} - - -float CBaseToggle :: AxisValue( int flags, const Vector &angles ) -{ - if ( FBitSet(flags, SF_DOOR_ROTATE_Z) ) - return angles.z; - if ( FBitSet(flags, SF_DOOR_ROTATE_X) ) - return angles.x; - - return angles.y; -} - - -void CBaseToggle :: AxisDir( entvars_t *pev ) -{ - if ( FBitSet(pev->spawnflags, SF_DOOR_ROTATE_Z) ) - pev->movedir = Vector ( 0, 0, 1 ); // around z-axis - else if ( FBitSet(pev->spawnflags, SF_DOOR_ROTATE_X) ) - pev->movedir = Vector ( 1, 0, 0 ); // around x-axis - else - pev->movedir = Vector ( 0, 1, 0 ); // around y-axis -} - - -float CBaseToggle :: AxisDelta( int flags, const Vector &angle1, const Vector &angle2 ) -{ - if ( FBitSet (flags, SF_DOOR_ROTATE_Z) ) - return angle1.z - angle2.z; - - if ( FBitSet (flags, SF_DOOR_ROTATE_X) ) - return angle1.x - angle2.x; - - return angle1.y - angle2.y; -} - - -/* -============= -FEntIsVisible - -returns TRUE if the passed entity is visible to caller, even if not infront () -============= -*/ - BOOL -FEntIsVisible( - entvars_t* pev, - entvars_t* pevTarget) - { - Vector vecSpot1 = pev->origin + pev->view_ofs; - Vector vecSpot2 = pevTarget->origin + pevTarget->view_ofs; - TraceResult tr; - - UTIL_TraceLine(vecSpot1, vecSpot2, ignore_monsters, ENT(pev), &tr); - - if (tr.fInOpen && tr.fInWater) - return FALSE; // sight line crossed contents - - if (tr.flFraction == 1) - return TRUE; - - return FALSE; - } - - diff --git a/dmc/dlls/teamplay_gamerules.cpp b/dmc/dlls/teamplay_gamerules.cpp deleted file mode 100644 index 292d707..0000000 --- a/dmc/dlls/teamplay_gamerules.cpp +++ /dev/null @@ -1,618 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// teamplay_gamerules.cpp -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "teamplay_gamerules.h" -#include "game.h" - - -/*class CDMCGameMgrHelper : public IVoiceGameMgrHelper -{ -public: - virtual bool ComparePlayerTeams(CBasePlayer *pPlayer1, CBasePlayer *pPlayer2) - { - return true; - } -}; -static CDMCGameMgrHelper g_GameMgrHelper;*/ - - -static char team_names[MAX_TEAMS][MAX_TEAMNAME_LENGTH]; -static int team_scores[MAX_TEAMS]; -static int num_teams = 0; - -extern DLL_GLOBAL BOOL g_fGameOver; - -CHalfLifeTeamplay :: CHalfLifeTeamplay() -{ -// m_VoiceGameMgr.Init(&g_GameMgrHelper, VGMode(HearPVS), gpGlobals->maxClients); - - m_DisableDeathMessages = FALSE; - m_DisableDeathPenalty = FALSE; - - memset( team_names, 0, sizeof(team_names) ); - memset( team_scores, 0, sizeof(team_scores) ); - num_teams = 0; - - // Copy over the team from the server config - m_szTeamList[0] = 0; - - // Cache this because the team code doesn't want to deal with changing this in the middle of a game - strncpy( m_szTeamList, teamlist.string, TEAMPLAY_TEAMLISTLENGTH ); - - edict_t *pWorld = INDEXENT(0); - if ( pWorld && pWorld->v.team ) - { - if ( teamoverride.value ) - { - const char *pTeamList = STRING(pWorld->v.team); - if ( pTeamList && strlen(pTeamList) ) - { - strncpy( m_szTeamList, pTeamList, TEAMPLAY_TEAMLISTLENGTH ); - } - } - } - // Has the server set teams - if ( strlen( m_szTeamList ) ) - m_teamLimit = TRUE; - else - m_teamLimit = FALSE; - - RecountTeams(); -} - -BOOL CHalfLifeTeamplay::ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) -{ -// m_VoiceGameMgr.ClientConnected(pEntity); - - return CHalfLifeMultiplay::ClientConnected(pEntity, pszName, pszAddress, szRejectReason); -} - - -extern cvar_t timeleft, fragsleft; - -void CHalfLifeTeamplay :: Think ( void ) -{ -// m_VoiceGameMgr.Update(gpGlobals->frametime); - - ///// Check game rules ///// - static int last_frags; - static int last_time; - - int frags_remaining = 0; - int time_remaining = 0; - - if ( g_fGameOver ) // someone else quit the game already - { - CHalfLifeMultiplay::Think(); - return; - } - - float flTimeLimit = CVAR_GET_FLOAT("mp_timelimit") * 60; - - time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0); - - if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit ) - { - GoToIntermission(); - return; - } - - float flFragLimit = fraglimit.value; - if ( flFragLimit ) - { - int bestfrags = 9999; - int remain; - - // check if any team is over the frag limit - for ( int i = 0; i < num_teams; i++ ) - { - if ( team_scores[i] >= flFragLimit ) - { - GoToIntermission(); - return; - } - - remain = flFragLimit - team_scores[i]; - if ( remain < bestfrags ) - { - bestfrags = remain; - } - } - frags_remaining = bestfrags; - } - - // Updates when frags change - if ( frags_remaining != last_frags ) - { - g_engfuncs.pfnCvar_DirectSet( &fragsleft, UTIL_VarArgs( "%i", frags_remaining ) ); - } - - // Updates once per second - if ( timeleft.value != last_time ) - { - g_engfuncs.pfnCvar_DirectSet( &timeleft, UTIL_VarArgs( "%i", time_remaining ) ); - } - - last_frags = frags_remaining; - last_time = time_remaining; -} - -//========================================================= -// ClientCommand -// the user has typed a command which is unrecognized by everything else; -// this check to see if the gamerules knows anything about the command -//========================================================= -BOOL CHalfLifeTeamplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) -{ -// if(m_VoiceGameMgr.ClientCommand(pPlayer, pcmd)) -// return TRUE; - - if ( FStrEq( pcmd, "menuselect" ) ) - { - if ( CMD_ARGC() < 2 ) - return TRUE; - - int slot = atoi( CMD_ARGV(1) ); - - // select the item from the current menu - - return TRUE; - } - - return FALSE; -} - -extern int gmsgGameMode; -extern int gmsgSayText; -extern int gmsgTeamInfo; - - -void CHalfLifeTeamplay :: UpdateGameMode( CBasePlayer *pPlayer ) -{ - MESSAGE_BEGIN( MSG_ONE, gmsgGameMode, NULL, pPlayer->edict() ); - WRITE_BYTE( 1 ); // game mode teamplay - MESSAGE_END(); -} - - -const char *CHalfLifeTeamplay::SetDefaultPlayerTeam( CBasePlayer *pPlayer ) -{ - // copy out the team name from the model - char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ); - strncpy( pPlayer->m_szTeamName, mdls, TEAM_NAME_LENGTH ); - - RecountTeams(); - - // update the current player of the team he is joining - if ( pPlayer->m_szTeamName[0] == '\0' || !IsValidTeam( pPlayer->m_szTeamName ) || defaultteam.value ) - { - const char *pTeamName = NULL; - - if ( defaultteam.value ) - { - pTeamName = team_names[0]; - } - else - { - pTeamName = TeamWithFewestPlayers(); - } - strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH ); - } - - return pPlayer->m_szTeamName; -} - - -//========================================================= -// InitHUD -//========================================================= -void CHalfLifeTeamplay::InitHUD( CBasePlayer *pPlayer ) -{ - SetDefaultPlayerTeam( pPlayer ); - CHalfLifeMultiplay::InitHUD( pPlayer ); - - RecountTeams(); - - char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ); - // update the current player of the team he is joining - char text[1024]; - if ( !strcmp( mdls, pPlayer->m_szTeamName ) ) - { - sprintf( text, "* you are on team \'%s\'\n", pPlayer->m_szTeamName ); - } - else - { - sprintf( text, "* assigned to team %s\n", pPlayer->m_szTeamName ); - } - - ChangePlayerTeam( pPlayer, pPlayer->m_szTeamName, FALSE, FALSE ); - UTIL_SayText( text, pPlayer ); - int clientIndex = pPlayer->entindex(); - RecountTeams(); - // update this player with all the other players team info - // loop through all active players and send their team info to the new client - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - if ( plr && IsValidTeam( plr->TeamID() ) ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgTeamInfo, NULL, pPlayer->edict() ); - WRITE_BYTE( plr->entindex() ); - WRITE_STRING( plr->TeamID() ); - MESSAGE_END(); - } - } -} - - -void CHalfLifeTeamplay::ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ) -{ - int damageFlags = DMG_GENERIC; - int clientIndex = pPlayer->entindex(); - - if ( !bGib ) - { - damageFlags |= DMG_NEVERGIB; - } - else - { - damageFlags |= DMG_ALWAYSGIB; - } - - if ( bKill ) - { - // kill the player, remove a death, and let them start on the new team - m_DisableDeathMessages = TRUE; - m_DisableDeathPenalty = TRUE; - - entvars_t *pevWorld = VARS( INDEXENT(0) ); - pPlayer->TakeDamage( pevWorld, pevWorld, 900, damageFlags ); - - m_DisableDeathMessages = FALSE; - m_DisableDeathPenalty = FALSE; - } - - // copy out the team name from the model - strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH ); - - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName ); - - // notify everyone's HUD of the team change - MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo ); - WRITE_BYTE( clientIndex ); - WRITE_STRING( pPlayer->m_szTeamName ); - MESSAGE_END(); -} - - -//========================================================= -// ClientUserInfoChanged -//========================================================= -void CHalfLifeTeamplay::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) -{ - char text[1024]; - - // prevent skin/color/model changes - char *mdls = g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ); - - if ( !stricmp( mdls, pPlayer->m_szTeamName ) ) - return; - - if ( defaultteam.value ) - { - int clientIndex = pPlayer->entindex(); - - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName ); - sprintf( text, "* Not allowed to change teams in this game!\n" ); - UTIL_SayText( text, pPlayer ); - return; - } - - if ( defaultteam.value || !IsValidTeam( mdls ) ) - { - int clientIndex = pPlayer->entindex(); - - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); - sprintf( text, "* Can't change team to \'%s\'\n", mdls ); - UTIL_SayText( text, pPlayer ); - sprintf( text, "* Server limits teams to \'%s\'\n", m_szTeamList ); - UTIL_SayText( text, pPlayer ); - return; - } - // notify everyone of the team change - sprintf( text, "* %s has changed to team \'%s\'\n", STRING(pPlayer->pev->netname), mdls ); - UTIL_SayTextAll( text, pPlayer ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", - STRING(pPlayer->pev->netname), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - pPlayer->m_szTeamName, - mdls ); - - ChangePlayerTeam( pPlayer, mdls, TRUE, TRUE ); - // recound stuff - RecountTeams(); -} - -extern int gmsgDeathMsg; - -//========================================================= -// Deathnotice. -//========================================================= -void CHalfLifeTeamplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ) -{ - if ( m_DisableDeathMessages ) - return; - - if ( pVictim && pKiller && pKiller->flags & FL_CLIENT ) - { - CBasePlayer *pk = (CBasePlayer*) CBaseEntity::Instance( pKiller ); - - if ( pk ) - { - if ( (pk != pVictim) && (PlayerRelationship( pVictim, pk ) == GR_TEAMMATE) ) - { - MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); - WRITE_BYTE( ENTINDEX(ENT(pKiller)) ); // the killer - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim - WRITE_STRING( "teammate" ); // flag this as a teammate kill - MESSAGE_END(); - return; - } - } - } - - CHalfLifeMultiplay::DeathNotice( pVictim, pKiller, pevInflictor ); -} - -//========================================================= -//========================================================= -void CHalfLifeTeamplay :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ - if ( !m_DisableDeathPenalty ) - { - CHalfLifeMultiplay::PlayerKilled( pVictim, pKiller, pInflictor ); - RecountTeams(); - } -} - - -//========================================================= -// IsTeamplay -//========================================================= -BOOL CHalfLifeTeamplay::IsTeamplay( void ) -{ - return TRUE; -} - -BOOL CHalfLifeTeamplay::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) -{ - if ( pAttacker && PlayerRelationship( pPlayer, pAttacker ) == GR_TEAMMATE ) - { - // my teammate hit me. - if ( (CVAR_GET_FLOAT("mp_friendlyfire") == 0) && (pAttacker != pPlayer) ) - { - // friendly fire is off, and this hit came from someone other than myself, then don't get hurt - return FALSE; - } - } - - return CHalfLifeMultiplay::FPlayerCanTakeDamage( pPlayer, pAttacker ); -} - -//========================================================= -//========================================================= -int CHalfLifeTeamplay::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) -{ - // half life multiplay has a simple concept of Player Relationships. - // you are either on another player's team, or you are not. - if ( !pPlayer || !pTarget || !pTarget->IsPlayer() ) - return GR_NOTTEAMMATE; - - if ( (*GetTeamID(pPlayer) != '\0') && (*GetTeamID(pTarget) != '\0') && !stricmp( GetTeamID(pPlayer), GetTeamID(pTarget) ) ) - { - return GR_TEAMMATE; - } - - return GR_NOTTEAMMATE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeTeamplay::ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) -{ - // always autoaim, unless target is a teammate - CBaseEntity *pTgt = CBaseEntity::Instance( target ); - if ( pTgt && pTgt->IsPlayer() ) - { - if ( PlayerRelationship( pPlayer, pTgt ) == GR_TEAMMATE ) - return FALSE; // don't autoaim at teammates - } - - return CHalfLifeMultiplay::ShouldAutoAim( pPlayer, target ); -} - -//========================================================= -//========================================================= -int CHalfLifeTeamplay::IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) -{ - if ( !pKilled ) - return 0; - - if ( !pAttacker ) - return 1; - - if ( pAttacker != pKilled && PlayerRelationship( pAttacker, pKilled ) == GR_TEAMMATE ) - return -1; - - return 1; -} - -//========================================================= -//========================================================= -const char *CHalfLifeTeamplay::GetTeamID( CBaseEntity *pEntity ) -{ - if ( pEntity == NULL || pEntity->pev == NULL ) - return ""; - - // return their team name - return pEntity->TeamID(); -} - - -int CHalfLifeTeamplay::GetTeamIndex( const char *pTeamName ) -{ - if ( pTeamName && *pTeamName != 0 ) - { - // try to find existing team - for ( int tm = 0; tm < num_teams; tm++ ) - { - if ( !stricmp( team_names[tm], pTeamName ) ) - return tm; - } - } - - return -1; // No match -} - - -const char *CHalfLifeTeamplay::GetIndexedTeamName( int teamIndex ) -{ - if ( teamIndex < 0 || teamIndex >= num_teams ) - return ""; - - return team_names[ teamIndex ]; -} - - -BOOL CHalfLifeTeamplay::IsValidTeam( const char *pTeamName ) -{ - if ( !m_teamLimit ) // Any team is valid if the teamlist isn't set - return TRUE; - - return ( GetTeamIndex( pTeamName ) != -1 ) ? TRUE : FALSE; -} - -const char *CHalfLifeTeamplay::TeamWithFewestPlayers( void ) -{ - int i; - int minPlayers = MAX_TEAMS; - int teamCount[ MAX_TEAMS ]; - char *pTeamName = NULL; - - memset( teamCount, 0, MAX_TEAMS * sizeof(int) ); - - // loop through all clients, count number of players on each team - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - - if ( plr ) - { - int team = GetTeamIndex( plr->TeamID() ); - if ( team >= 0 ) - teamCount[team] ++; - } - } - - // Find team with least players - for ( i = 0; i < num_teams; i++ ) - { - if ( teamCount[i] < minPlayers ) - { - minPlayers = teamCount[i]; - pTeamName = team_names[i]; - } - } - - return pTeamName; -} - - -//========================================================= -//========================================================= -void CHalfLifeTeamplay::RecountTeams( void ) -{ - char *pName; - char teamlist[TEAMPLAY_TEAMLISTLENGTH]; - - // loop through all teams, recounting everything - num_teams = 0; - - // Copy all of the teams from the teamlist - // make a copy because strtok is destructive - strcpy( teamlist, m_szTeamList ); - pName = teamlist; - pName = strtok( pName, ";" ); - while ( pName != NULL && *pName ) - { - if ( GetTeamIndex( pName ) < 0 ) - { - strcpy( team_names[num_teams], pName ); - num_teams++; - } - pName = strtok( NULL, ";" ); - } - - if ( num_teams < 2 ) - { - num_teams = 0; - m_teamLimit = FALSE; - } - - // Sanity check - memset( team_scores, 0, sizeof(team_scores) ); - - // loop through all clients - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - - if ( plr ) - { - const char *pTeamName = plr->TeamID(); - // try add to existing team - int tm = GetTeamIndex( pTeamName ); - - if ( tm < 0 ) // no team match found - { - if ( !m_teamLimit ) - { - // add to new team - tm = num_teams; - num_teams++; - team_scores[tm] = 0; - strncpy( team_names[tm], pTeamName, MAX_TEAMNAME_LENGTH ); - } - } - - if ( tm >= 0 ) - { - team_scores[tm] += plr->pev->frags; - } - } - } -} diff --git a/dmc/dlls/teamplay_gamerules.h b/dmc/dlls/teamplay_gamerules.h deleted file mode 100644 index f9de3cb..0000000 --- a/dmc/dlls/teamplay_gamerules.h +++ /dev/null @@ -1,62 +0,0 @@ -/*** -* -* 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. -* -****/ -// -// teamplay_gamerules.h -// - -#include "voice_gamemgr.h" - -#define MAX_TEAMNAME_LENGTH 16 -#define MAX_TEAMS 32 - -#define TEAMPLAY_TEAMLISTLENGTH MAX_TEAMS*MAX_TEAMNAME_LENGTH - -class CHalfLifeTeamplay : public CHalfLifeMultiplay -{ -public: - CHalfLifeTeamplay(); - - virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); - virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ); - virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ); - virtual BOOL IsTeamplay( void ); - virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ); - virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); - virtual const char *GetTeamID( CBaseEntity *pEntity ); - virtual BOOL ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ); - virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); - virtual void InitHUD( CBasePlayer *pl ); - virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ); - virtual const char *GetGameDescription( void ) { return "HL Teamplay"; } // this is the game name that gets seen in the server browser - virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode - virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - virtual void Think ( void ); - virtual int GetTeamIndex( const char *pTeamName ); - virtual const char *GetIndexedTeamName( int teamIndex ); - virtual BOOL IsValidTeam( const char *pTeamName ); - const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer ); - virtual void ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ); - - CVoiceGameMgr m_VoiceGameMgr; - -private: - void RecountTeams( void ); - const char *TeamWithFewestPlayers( void ); - - BOOL m_DisableDeathMessages; - BOOL m_DisableDeathPenalty; - BOOL m_teamLimit; // This means the server set only some teams as valid - char m_szTeamList[TEAMPLAY_TEAMLISTLENGTH]; -}; diff --git a/dmc/dlls/threewave_gamerules.cpp b/dmc/dlls/threewave_gamerules.cpp deleted file mode 100644 index e235322..0000000 --- a/dmc/dlls/threewave_gamerules.cpp +++ /dev/null @@ -1,3275 +0,0 @@ -/*** -* -* Copyright (c) 2001, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -/* - -===== threewave_gamerules.cpp ======================================================== - - This contains all the gamerules for the ThreeWave CTF Gamemode. - It also contains the Flag entity information. - -*/ - -#ifdef THREEWAVE - -#define NUM_TEAMS 2 - -char *sTeamNames[] = -{ - "SPECTATOR", - "RED", - "BLUE", -}; - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "skill.h" -#include "game.h" -#include "items.h" -#include "threewave_gamerules.h" - -extern int gmsgCTFMsgs; -extern int gmsgShowMenu; -extern int gmsgFlagStatus; -extern int gmsgRuneStatus; -extern int gmsgFlagCarrier; -extern int gmsgScoreInfo; - -extern unsigned short g_usHook; -extern unsigned short g_usCable; -extern unsigned short g_usCarried; -extern unsigned short g_usFlagSpawn; - - -static char team_names[MAX_TEAMS][MAX_TEAMNAME_LENGTH]; -static int team_scores[MAX_TEAMS]; -static int num_teams = 0; - -bool g_bSpawnedRunes; -void SpawnRunes( void ); - -extern edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer, bool bCheckDM ); -extern edict_t *RuneSelectSpawnPoint( void ); - -// 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 - - - -class CThreeWaveGameMgrHelper : public IVoiceGameMgrHelper -{ -public: - virtual bool CanPlayerHearPlayer(CBasePlayer *pPlayer1, CBasePlayer *pPlayer2) - { - return stricmp(pPlayer1->TeamID(), pPlayer2->TeamID()) == 0; - } -}; -static CThreeWaveGameMgrHelper g_GameMgrHelper; - - - -extern DLL_GLOBAL BOOL g_fGameOver; - -char* GetTeamName( int team ) -{ - if ( team < 0 || team > NUM_TEAMS ) - team = 0; - - return sTeamNames[ team ]; -} - -CThreeWave :: CThreeWave() -{ - // CHalfLifeMultiplay already initialized it - just override its helper callback. - m_VoiceGameMgr.SetHelper(&g_GameMgrHelper); - - m_DisableDeathMessages = FALSE; - m_DisableDeathPenalty = FALSE; - - memset( team_names, 0, sizeof(team_names) ); - memset( team_scores, 0, sizeof(team_scores) ); - num_teams = 0; - - iBlueTeamScore = iRedTeamScore = 0; - g_bSpawnedRunes = FALSE; - - // Copy over the team from the server config - m_szTeamList[0] = 0; - - // Cache this because the team code doesn't want to deal with changing this in the middle of a game - strncpy( m_szTeamList, teamlist.string, TEAMPLAY_TEAMLISTLENGTH ); - - edict_t *pWorld = INDEXENT(0); - if ( pWorld && pWorld->v.team ) - { - if ( teamoverride.value ) - { - const char *pTeamList = STRING(pWorld->v.team); - if ( pTeamList && strlen(pTeamList) ) - { - strncpy( m_szTeamList, pTeamList, TEAMPLAY_TEAMLISTLENGTH ); - } - } - } - // Has the server set teams - if ( strlen( m_szTeamList ) ) - m_teamLimit = TRUE; - else - m_teamLimit = FALSE; - - RecountTeams(); -} - - -BOOL CThreeWave::ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) -{ - return CHalfLifeMultiplay::ClientConnected(pEntity, pszName, pszAddress, szRejectReason); -} - - -extern cvar_t timeleft, fragsleft; - -void CThreeWave :: Think ( void ) -{ - m_VoiceGameMgr.Update(gpGlobals->frametime); - - ///// Check game rules ///// - static int last_frags; - static int last_time; - - int frags_remaining = 0; - int time_remaining = 0; - - if ( g_fGameOver ) // someone else quit the game already - { - CHalfLifeMultiplay::Think(); - return; - } - - float flTimeLimit = CVAR_GET_FLOAT("mp_timelimit") * 60; - - time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0); - - if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit ) - { - GoToIntermission(); - return; - } - - float flFragLimit = fraglimit.value; - if ( flFragLimit ) - { - int bestfrags = 9999; - int remain; - - // check if any team is over the frag limit - for ( int i = 0; i < num_teams; i++ ) - { - if ( team_scores[i] >= flFragLimit ) - { - GoToIntermission(); - return; - } - - remain = flFragLimit - team_scores[i]; - if ( remain < bestfrags ) - { - bestfrags = remain; - } - } - frags_remaining = bestfrags; - } - - if ( !g_bSpawnedRunes ) - SpawnRunes(); - - if ( m_flFlagStatusTime && m_flFlagStatusTime <= gpGlobals->time ) - GetFlagStatus( NULL ); - - // Updates when frags change - if ( frags_remaining != last_frags ) - { - g_engfuncs.pfnCvar_DirectSet( &fragsleft, UTIL_VarArgs( "%i", frags_remaining ) ); - } - - // Updates once per second - if ( timeleft.value != last_time ) - { - g_engfuncs.pfnCvar_DirectSet( &timeleft, UTIL_VarArgs( "%i", time_remaining ) ); - } - - last_frags = frags_remaining; - last_time = time_remaining; -} - -void CThreeWave :: JoinTeam ( CBasePlayer *pPlayer, int iTeam ) -{ - if ( pPlayer->pev->team == iTeam ) - return; - - if ( pPlayer->m_flNextTeamChange > gpGlobals->time ) - return; - - pPlayer->m_flNextTeamChange = gpGlobals->time + 5; - - if ( pPlayer->pev->team == 0 ) - { - ChangePlayerTeam( pPlayer, iTeam ); - RecountTeams(); - - pPlayer->Spawn(); - } - else - { - ChangePlayerTeam( pPlayer, iTeam ); - RecountTeams(); - } -} - -int CThreeWave::TeamWithFewestPlayers( void ) -{ - - CBaseEntity *pPlayer = NULL; - CBasePlayer *player = NULL; - - int iNumRed, iNumBlue; - - int iTeam; - - // Initialize the player counts.. - iNumRed = iNumBlue = 0; - - pPlayer = UTIL_FindEntityByClassname ( pPlayer, "player" ); - - while ( (pPlayer != NULL) && (!FNullEnt(pPlayer->edict())) ) - { - if (pPlayer->pev->flags != FL_DORMANT) - { - player = GetClassPtr((CBasePlayer *)pPlayer->pev); - - - if ( player->pev->team == RED ) - iNumRed += 1; - - else if ( player->pev->team == BLUE ) - iNumBlue += 1; - - } - pPlayer = UTIL_FindEntityByClassname ( pPlayer, "player" ); - } - - if ( iNumRed == iNumBlue ) - { - switch ( RANDOM_LONG( 0, 1 ) ) - { - case 0: iTeam = RED; break; - case 1: iTeam = BLUE; break; - } - } - else if ( iNumRed == 0 && iNumBlue == 0) - { - switch ( RANDOM_LONG( 0, 1 ) ) - { - case 0: iTeam = RED; break; - case 1: iTeam = BLUE; break; - } - } - - else if ( iNumRed > iNumBlue ) - iTeam = BLUE; - - else if ( iNumRed < iNumBlue ) - iTeam = RED; - - return iTeam; - -} - -void DropRune ( CBasePlayer *pPlayer ); -//========================================================= -// ClientCommand -// the user has typed a command which is unrecognized by everything else; -// this check to see if the gamerules knows anything about the command -//========================================================= -BOOL CThreeWave :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) -{ - if( m_VoiceGameMgr.ClientCommand( pPlayer, pcmd ) ) - return TRUE; - - if ( FStrEq( pcmd, "menuselect" ) ) - { - if ( CMD_ARGC() < 2 ) - return TRUE; - - int slot = atoi( CMD_ARGV(1) ); - - // select the item from the current menu - switch( pPlayer->m_iMenu ) - { - case Team_Menu: - - switch ( slot ) - { - case 1: - JoinTeam( pPlayer, RED ); - break; - case 2: - JoinTeam( pPlayer, BLUE ); - break; - case 5: - JoinTeam( pPlayer, TeamWithFewestPlayers() ); - break; - } - - break; - - case Team_Menu_IG: - - switch ( slot ) - { - case 1: - JoinTeam( pPlayer, RED ); - break; - case 2: - JoinTeam( pPlayer, BLUE ); - break; - case 5: - JoinTeam( pPlayer, TeamWithFewestPlayers() ); - break; - default: - return TRUE; - } - - break; - } - - return TRUE; - } - else if ( FStrEq( pcmd, "droprune" ) ) - { - DropRune( pPlayer ); - - return TRUE; - } - else if ( FStrEq( pcmd, "changeteam" ) ) - { - if ( pPlayer->pev->team != 0 ) - { - pPlayer->ShowMenu( 1 + 2 + 16 + 512, -1, FALSE, "#Team_Menu_Join_IG" ); - pPlayer->m_iMenu = Team_Menu_IG; - } - - return TRUE; - } - - return FALSE; -} - -extern int gmsgGameMode; -extern int gmsgSayText; -extern int gmsgTeamInfo; - -void CThreeWave :: UpdateGameMode( CBasePlayer *pPlayer ) -{ - MESSAGE_BEGIN( MSG_ONE, gmsgGameMode, NULL, pPlayer->edict() ); - WRITE_BYTE( 1 ); // game mode teamplay - MESSAGE_END(); -} - -edict_t *CThreeWave::GetPlayerSpawnSpot( CBasePlayer *pPlayer ) -{ - edict_t *pentSpawnSpot; - - if ( FBitSet( pPlayer->m_afPhysicsFlags, PFLAG_OBSERVER ) || pPlayer->pev->team == 0 ) - pentSpawnSpot = EntSelectSpawnPoint( pPlayer, FALSE ); - else - { - if ( RANDOM_LONG ( 1, 7 ) < 3 ) - pentSpawnSpot= EntSelectSpawnPoint( pPlayer, TRUE ); - else - pentSpawnSpot= EntSelectSpawnPoint( pPlayer, FALSE ); - } - - if ( IsMultiplayer() && pentSpawnSpot->v.target ) - { - FireTargets( STRING(pentSpawnSpot->v.target), pPlayer, pPlayer, USE_TOGGLE, 0 ); - } - - pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1); - pPlayer->pev->v_angle = g_vecZero; - pPlayer->pev->velocity = g_vecZero; - pPlayer->pev->angles = VARS(pentSpawnSpot)->angles; - pPlayer->pev->punchangle = g_vecZero; - pPlayer->pev->fixangle = TRUE; - - return pentSpawnSpot; -} - -void CThreeWave :: PlayerTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) -{ - if ( !pAttacker->IsPlayer() ) - return; - - if ( pPlayer->pev->team == pAttacker->pev->team ) - return; - - if ( pPlayer->m_bHasFlag ) - { - pPlayer->pCarrierHurter = (CBasePlayer *)pAttacker; - pPlayer->m_flCarrierHurtTime = gpGlobals->time + TEAM_CAPTURE_CARRIER_DANGER_PROTECT_TIMEOUT; - } - -} - -void CThreeWave :: PlayerSpawn( CBasePlayer *pPlayer ) -{ - BOOL addDefault; - CBaseEntity *pWeaponEntity = NULL; - - if ( pPlayer->pev->team == 0 ) - { - pPlayer->pev->takedamage = DAMAGE_NO; - pPlayer->pev->solid = SOLID_NOT; - pPlayer->pev->movetype = MOVETYPE_NOCLIP; - pPlayer->pev->effects |= EF_NODRAW; - pPlayer->pev->flags |= FL_NOTARGET; - pPlayer->m_afPhysicsFlags |= PFLAG_OBSERVER; - pPlayer->m_iHideHUD |= HIDEHUD_WEAPONS | HIDEHUD_FLASHLIGHT | HIDEHUD_HEALTH; - - pPlayer->m_flFlagStatusTime = gpGlobals->time + 0.1; - } - else - { - pPlayer->pev->weapons |= (1<Touch( pPlayer ); - addDefault = FALSE; - } - - if ( addDefault ) - { - pPlayer->m_bHasFlag = FALSE; - - pPlayer->m_iHideHUD &= ~HIDEHUD_WEAPONS; - pPlayer->m_iHideHUD &= ~HIDEHUD_FLASHLIGHT; - pPlayer->m_iHideHUD &= ~HIDEHUD_HEALTH; - pPlayer->m_afPhysicsFlags &= ~PFLAG_OBSERVER; - - // Start with init ammoload - pPlayer->m_iAmmoShells = 25; - - // Start with shotgun and axe - pPlayer->GiveNamedItem( "weapon_quakegun" ); - pPlayer->m_iQuakeItems |= ( IT_SHOTGUN | IT_AXE | IT_EXTRA_WEAPON ); - pPlayer->m_iQuakeWeapon = pPlayer->W_BestWeapon(); - pPlayer->W_SetCurrentAmmo(); - - pPlayer->m_flFlagStatusTime = gpGlobals->time + 0.1; - } - } - -/* MESSAGE_BEGIN( MSG_ONE, gmsgRuneStatus, NULL, pPlayer->pev); - WRITE_BYTE( pPlayer->m_iRuneStatus ); - MESSAGE_END();*/ -} - -void CBasePlayer::ShowMenu ( int bitsValidSlots, int nDisplayTime, BOOL fNeedMore, char *pszText ) -{ - MESSAGE_BEGIN( MSG_ONE, gmsgShowMenu, NULL, pev); - WRITE_SHORT( bitsValidSlots); - WRITE_CHAR( nDisplayTime ); - WRITE_BYTE( fNeedMore ); - WRITE_STRING (pszText); - MESSAGE_END(); -} - -//========================================================= -// InitHUD -//========================================================= -void CThreeWave::InitHUD( CBasePlayer *pPlayer ) -{ - CHalfLifeMultiplay::InitHUD( pPlayer ); - - int clientIndex = pPlayer->entindex(); - // update this player with all the other players team info - // loop through all active players and send their team info to the new client - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - if ( plr ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgTeamInfo, NULL, pPlayer->edict() ); - WRITE_BYTE( plr->entindex() ); - WRITE_STRING( plr->TeamID() ); - MESSAGE_END(); - - if ( ((CBasePlayer *)plr)->m_bHasFlag ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgFlagCarrier, NULL, pPlayer->edict() ); - WRITE_BYTE( plr->entindex() ); - WRITE_BYTE( 1 ); - MESSAGE_END(); - } - } - } - - //Remove Rune icon if we have one. - MESSAGE_BEGIN( MSG_ONE, gmsgRuneStatus, NULL, pPlayer->pev); - WRITE_BYTE( 0 ); - MESSAGE_END(); - - if ( pPlayer->pev->team == 0) - { - pPlayer->ShowMenu( 1 + 2 + 16, -1, FALSE, "#Team_Menu_Join" ); - pPlayer->m_iMenu = Team_Menu; - } -} - - -void CThreeWave::ChangePlayerTeam( CBasePlayer *pPlayer, int iTeam ) -{ - int damageFlags = DMG_GENERIC; - int clientIndex = pPlayer->entindex(); - - if ( pPlayer->pev->team != 0 ) - { - damageFlags |= DMG_ALWAYSGIB; - - // kill the player, remove a death, and let them start on the new team - m_DisableDeathMessages = TRUE; - m_DisableDeathPenalty = TRUE; - - entvars_t *pevWorld = VARS( INDEXENT(0) ); - pPlayer->TakeDamage( pevWorld, pevWorld, 900, damageFlags ); - - m_DisableDeathMessages = FALSE; - m_DisableDeathPenalty = FALSE; - } - - int oldTeam = pPlayer->pev->team; - pPlayer->pev->team = iTeam; - - if ( pPlayer->pev->team == RED ) - { - strncpy( pPlayer->m_szTeamName, "RED", TEAM_NAME_LENGTH ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", "red" ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "topcolor", UTIL_VarArgs( "%d", 255 ) ); - } - else if ( pPlayer->pev->team == BLUE ) - { - strncpy( pPlayer->m_szTeamName, "BLUE", TEAM_NAME_LENGTH ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", "blue" ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "topcolor", UTIL_VarArgs( "%d", 153 ) ); - } - - // notify everyone's HUD of the team change - MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo ); - WRITE_BYTE( clientIndex ); - WRITE_STRING( pPlayer->m_szTeamName ); - MESSAGE_END(); - - MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); - WRITE_BYTE( ENTINDEX(pPlayer->edict()) ); - WRITE_SHORT( pPlayer->pev->frags ); - WRITE_SHORT( pPlayer->m_iDeaths ); - WRITE_SHORT( pPlayer->pev->team ); - MESSAGE_END(); - - // log the change - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", - STRING(pPlayer->pev->netname), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - GetTeamName( oldTeam ), - pPlayer->m_szTeamName ); -} - - -//========================================================= -// ClientUserInfoChanged -//========================================================= -void CThreeWave::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) -{ - - int clientIndex = pPlayer->entindex(); - - if ( pPlayer->pev->team == RED ) - { - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "topcolor", UTIL_VarArgs( "%d", 255 ) ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", "red" ); - } - else if ( pPlayer->pev->team == BLUE ) - { - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "topcolor", UTIL_VarArgs( "%d", 153 ) ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", "blue" ); - } - -} - -extern int gmsgDeathMsg; - -//========================================================= -// Deathnotice. -//========================================================= -void CThreeWave::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ) -{ - if ( m_DisableDeathMessages ) - return; - - if ( pVictim && pKiller && pKiller->flags & FL_CLIENT ) - { - CBasePlayer *pk = (CBasePlayer*) CBaseEntity::Instance( pKiller ); - - if ( pk ) - { - if ( (pk != pVictim) && (PlayerRelationship( pVictim, pk ) == GR_TEAMMATE) ) - { - MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); - WRITE_BYTE( ENTINDEX(ENT(pKiller)) ); // the killer - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim - WRITE_STRING( "teammate" ); // flag this as a teammate kill - MESSAGE_END(); - return; - } - } - } - - CHalfLifeMultiplay::DeathNotice( pVictim, pKiller, pevInflictor ); -} - -//========================================================= -//========================================================= -void CThreeWave :: ClientDisconnected( edict_t *pClient ) -{ - if ( pClient ) - { - CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance( pClient ); - - if ( pPlayer ) - { - //We have the flag, spawn it - if ( pPlayer->m_bHasFlag ) - { - CBaseEntity *pEnt; - - //We have the BLUE flag, Spawn it - if ( pPlayer->pev->team == RED ) - { - pEnt = CBaseEntity::Create( "item_flag_team2", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Dropped_Blue_Flag\"\n", - STRING( pPlayer->pev->netname ), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - GetTeamName( pPlayer->pev->team ) ); - } - //We have the RED flag, Spawn it - else if ( pPlayer->pev->team == BLUE ) - { - pEnt = CBaseEntity::Create( "item_flag_team1", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Dropped_Red_Flag\"\n", - STRING( pPlayer->pev->netname ), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - GetTeamName( pPlayer->pev->team ) ); - } - - pEnt->pev->velocity = pPlayer->pev->velocity * 1.2; - pEnt->pev->angles.x = 0; - - CItemFlag *pFlag = (CItemFlag *)pEnt; - pFlag->Dropped = TRUE; - pFlag->m_flDroppedTime = gpGlobals->time + TEAM_CAPTURE_FLAG_RETURN_TIME; - - 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 ); - - MESSAGE_BEGIN ( MSG_ALL, gmsgCTFMsgs, NULL ); - if ( pPlayer->pev->team == RED ) - WRITE_BYTE( BLUE_FLAG_LOST ); - else if ( pPlayer->pev->team == BLUE ) - WRITE_BYTE( RED_FLAG_LOST ); - - WRITE_STRING( STRING(pPlayer->pev->netname) ); - MESSAGE_END(); - - m_flFlagStatusTime = gpGlobals->time + 0.1; - - pPlayer->m_bHasFlag = FALSE; - } - - // drop any runes the player has - CBaseEntity *pRune; - char * runeName; - - switch ( pPlayer->m_iRuneStatus ) - { - case ITEM_RUNE1_FLAG: - - pRune = CBaseEntity::Create( "item_rune1", pPlayer->pev->origin, pPlayer->pev->angles, NULL ); - - pRune->pev->velocity = pPlayer->pev->velocity * 1.5; - pRune->pev->angles.x = 0; - ((CResistRune*)pRune)->dropped = true; - - runeName = "ResistRune"; - - break; - - case ITEM_RUNE2_FLAG: - - pRune = CBaseEntity::Create( "item_rune2", pPlayer->pev->origin, pPlayer->pev->angles, NULL ); - - pRune->pev->velocity = pPlayer->pev->velocity * 1.5; - pRune->pev->angles.x = 0; - ((CStrengthRune*)pRune)->dropped = true; - - runeName = "StrengthRune"; - - break; - - case ITEM_RUNE3_FLAG: - - pRune = CBaseEntity::Create( "item_rune3", pPlayer->pev->origin, pPlayer->pev->angles, NULL ); - - pRune->pev->velocity = pPlayer->pev->velocity * 1.5; - pRune->pev->angles.x = 0; - ((CHasteRune*)pRune)->dropped = true; - - runeName = "HasteRune"; - - break; - - case ITEM_RUNE4_FLAG: - - pRune = CBaseEntity::Create( "item_rune4", pPlayer->pev->origin, pPlayer->pev->angles, NULL ); - - pRune->pev->velocity = pPlayer->pev->velocity * 1.5; - pRune->pev->angles.x = 0; - ((CRegenRune*)pRune)->dropped = true; - - runeName = "RegenRune"; - - break; - - default: - - runeName = "Unknown"; - - break; - } - - if ( pPlayer->m_iRuneStatus ) - { - pPlayer->m_iRuneStatus = 0; - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Dropped_%s\"\n", - STRING(pPlayer->pev->netname), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - pPlayer->m_szTeamName, - runeName ); - } - - FireTargets( "game_playerleave", pPlayer, pPlayer, USE_TOGGLE, 0 ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" disconnected\n", - STRING( pPlayer->pev->netname ), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - GetTeamName( pPlayer->pev->team ) ); - - pPlayer->RemoveAllItems( TRUE );// destroy all of the players weapons and items - } - } -} - -void CThreeWave :: PlayerThink( CBasePlayer *pPlayer ) -{ - if ( g_fGameOver ) - { - // check for button presses - if ( pPlayer->m_afButtonPressed & ( IN_DUCK | IN_ATTACK | IN_ATTACK2 | IN_USE | IN_JUMP ) ) - m_iEndIntermissionButtonHit = TRUE; - - // clear attack/use commands from player - pPlayer->m_afButtonPressed = 0; - pPlayer->pev->button = 0; - pPlayer->m_afButtonReleased = 0; - } - - if ( pPlayer->pFlagCarrierKiller ) - { - if ( pPlayer->m_flFlagCarrierKillTime <= gpGlobals->time ) - pPlayer->pFlagCarrierKiller = NULL; - } - - if ( pPlayer->pFlagReturner ) - { - if ( pPlayer->m_flFlagReturnTime <= gpGlobals->time ) - pPlayer->pFlagReturner = NULL; - } - - if ( pPlayer->pCarrierHurter ) - { - if ( pPlayer->m_flCarrierHurtTime <= gpGlobals->time ) - pPlayer->pCarrierHurter = NULL; - } - - if ( pPlayer->m_iRuneStatus == ITEM_RUNE4_FLAG) - { - if ( pPlayer->m_flRegenTime <= gpGlobals->time) - { - - - if ( pPlayer->pev->health < 150 ) - { - pPlayer->pev->health += 5; - - if ( pPlayer->pev->health > 150) - pPlayer->pev->health = 150; - - pPlayer->m_flRegenTime = gpGlobals->time + 1; - - EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "rune/rune4.wav", 1, ATTN_NORM); - } - if ( pPlayer->pev->armorvalue < 150 && pPlayer->pev->armorvalue ) - { - pPlayer->pev->armorvalue += 5; - - if ( pPlayer->pev->armorvalue > 150) - pPlayer->pev->armorvalue = 150; - - pPlayer->m_flRegenTime = gpGlobals->time + 1; - - EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "rune/rune4.wav", 1, ATTN_NORM); - } - } - } - - if ( pPlayer->m_bOn_Hook ) - pPlayer->Service_Grapple(); - - if ( pPlayer->m_flFlagStatusTime && pPlayer->m_flFlagStatusTime <= gpGlobals->time ) - GetFlagStatus( pPlayer ); -} - -//========================================================= -//========================================================= -void CThreeWave :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ - CBasePlayer *pk = NULL; - - if ( pKiller ) - { - CBaseEntity *pTemp = CBaseEntity::Instance( pKiller ); - - if ( pTemp->IsPlayer() ) - pk = (CBasePlayer*)pTemp; - } - - //Only award a bonus if the Flag carrier had the flag for more than 2 secs - //Prevents from people waiting for the flag carrier to grab the flag and then killing him - //Instead of actually defending the flag. - if ( pVictim->m_bHasFlag ) - { - if ( pk ) - { - if ( pVictim->pev->team != pk->pev->team ) - { - if ( pVictim->m_flCarrierPickupTime <= gpGlobals->time ) - pk->AddPoints( TEAM_CAPTURE_FRAG_CARRIER_BONUS, TRUE ); - - if ( pk->pev->team == RED ) - { - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING( pk->pev->netname ) ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " fragged " ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "BLUE" ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "'s flag carrier!\n" ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Killed_Enemy_Flag_Carrier\"\n", - STRING( pk->pev->netname ), - GETPLAYERUSERID( pk->edict() ), - GETPLAYERAUTHID( pk->edict() ), - GetTeamName( pk->pev->team ) ); - - if ( 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->pFlagCarrierKiller = pk; - pTeamMate->m_flFlagCarrierKillTime = gpGlobals->time + TEAM_CAPTURE_FRAG_CARRIER_ASSIST_TIMEOUT; - } - } - } - } - } - - if ( pk->pev->team == BLUE ) - { - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING( pk->pev->netname ) ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " fragged " ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "RED" ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "'s flag carrier!\n" ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Killed_Enemy_Flag_Carrier\"\n", - STRING( pk->pev->netname ), - GETPLAYERUSERID( pk->edict() ), - GETPLAYERAUTHID( pk->edict() ), - GetTeamName( pk->pev->team ) ); - - if ( 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->pFlagCarrierKiller = pk; - pTeamMate->m_flFlagCarrierKillTime = gpGlobals->time + TEAM_CAPTURE_FRAG_CARRIER_ASSIST_TIMEOUT; - } - } - } - } - } - } - } - - - CBaseEntity *pEnt; - - //We have the BLUE flag, Spawn it - if ( pVictim->pev->team == RED ) - { - pEnt = CBaseEntity::Create( "item_flag_team2", pVictim->pev->origin, pVictim->pev->angles, pVictim->edict() ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Dropped_Blue_Flag\"\n", - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GetTeamName( pVictim->pev->team ) ); - } - else if ( pVictim->pev->team == BLUE ) - { - pEnt = CBaseEntity::Create( "item_flag_team1", pVictim->pev->origin, pVictim->pev->angles, pVictim->edict() ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Dropped_Red_Flag\"\n", - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GetTeamName( pVictim->pev->team ) ); - } - - pEnt->pev->velocity = pVictim->pev->velocity * 1.2; - pEnt->pev->angles.x = 0; - - CItemFlag *pFlag = (CItemFlag *)pEnt; - pFlag->Dropped = TRUE; - - PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, - pVictim->edict(), g_usCarried, 0, (float *)&g_vecZero, (float *)&g_vecZero, - 0.0, 0.0, pVictim->entindex(), pVictim->pev->team, 1, 0 ); - - pFlag->m_flDroppedTime = gpGlobals->time + TEAM_CAPTURE_FLAG_RETURN_TIME; - - MESSAGE_BEGIN ( MSG_ALL, gmsgCTFMsgs, NULL ); - if ( pVictim->pev->team == RED ) - WRITE_BYTE( BLUE_FLAG_LOST ); - else if ( pVictim->pev->team == BLUE ) - WRITE_BYTE( RED_FLAG_LOST ); - - WRITE_STRING( STRING(pVictim->pev->netname) ); - MESSAGE_END(); - - pVictim->m_bHasFlag = FALSE; - - m_flFlagStatusTime = gpGlobals->time + 0.1; - } - else - { - if ( pk ) - { - if ( pk->pev->team == RED ) - { - if ( iBlueFlagStatus == BLUE_FLAG_STOLEN ) - { - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pTeamMate = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if ( pTeamMate && pTeamMate != pk ) - { - if ( pTeamMate->pev->team == pk->pev->team ) - { - if ( pTeamMate->m_bHasFlag ) - { - if ( pTeamMate->pCarrierHurter ) - { - if ( pTeamMate->pCarrierHurter == pVictim ) - { - if ( pTeamMate->m_flCarrierHurtTime > gpGlobals->time ) - { - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING( pk->pev->netname ) ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " defends "); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "RED" ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "'s flag carrier against an agressive enemy\n"); - - pk->AddPoints( TEAM_CAPTURE_CARRIER_DANGER_PROTECT_BONUS, TRUE ); - } - } - } - } - } - } - } - } - } - - if ( pk->pev->team == BLUE ) - { - if ( iRedFlagStatus == RED_FLAG_STOLEN ) - { - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pTeamMate = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if ( pTeamMate && pTeamMate != pk ) - { - if ( pTeamMate->pev->team == pk->pev->team ) - { - if ( pTeamMate->m_bHasFlag ) - { - if ( pTeamMate->pCarrierHurter ) - { - if ( pTeamMate->pCarrierHurter == pVictim ) - { - if ( pTeamMate->m_flCarrierHurtTime > gpGlobals->time ) - { - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING( pk->pev->netname ) ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " defends "); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "BLUE" ); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "'s flag carrier against an agressive enemy\n"); - - pk->AddPoints( TEAM_CAPTURE_CARRIER_DANGER_PROTECT_BONUS, TRUE ); - } - } - } - } - } - } - } - } - } - } - - } - - // Find if this guy is near our flag or our flag carrier - CBaseEntity *ent = NULL; - float Dist; - - if ( pk ) - { - if ( pk->pev->team == RED ) - { - while((ent = UTIL_FindEntityByClassname( ent, "item_flag_team1")) != NULL) - { - //Do not defend a invisible flag - if ( ent->pev->effects & EF_NODRAW ) - break; - - Dist = (pk->pev->origin - ent->pev->origin).Length(); - - if ( Dist <= TEAM_CAPTURE_TARGET_PROTECT_RADIUS ) - { - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING ( pk->pev->netname )); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " defends the "); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "RED"); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " flag\n"); - - pk->AddPoints( TEAM_CAPTURE_FLAG_DEFENSE_BONUS, TRUE ); - break; - } - } - - if ( iBlueFlagStatus == BLUE_FLAG_STOLEN ) - { - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pTeamMate = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if ( pTeamMate && pTeamMate != pk ) - { - if ( pTeamMate->pev->team == pk->pev->team ) - { - if ( pTeamMate->m_bHasFlag ) - { - Dist = (pk->pev->origin - pTeamMate->pev->origin).Length(); - - if ( Dist <= TEAM_CAPTURE_TARGET_PROTECT_RADIUS ) - { - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING ( pk->pev->netname )); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " defends "); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "RED"); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "'s flag carrier\n"); - - pk->AddPoints( TEAM_CAPTURE_CARRIER_PROTECT_BONUS, TRUE ); - } - } - } - } - } - } - - } - else if ( pk->pev->team == BLUE ) - { - while((ent = UTIL_FindEntityByClassname( ent, "item_flag_team2")) != NULL) - { - //Do not defend a invisible flag - if ( ent->pev->effects & EF_NODRAW ) - break; - - Dist = (pk->pev->origin - ent->pev->origin).Length(); - - if ( Dist <= TEAM_CAPTURE_TARGET_PROTECT_RADIUS ) - { - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING ( pk->pev->netname )); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " defends the "); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "RED"); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " flag\n"); - - pk->AddPoints( TEAM_CAPTURE_FLAG_DEFENSE_BONUS, TRUE ); - break; - } - } - - if ( iRedFlagStatus == RED_FLAG_STOLEN ) - { - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pTeamMate = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if ( pTeamMate && pTeamMate != pk ) - { - if ( pTeamMate->pev->team == pk->pev->team ) - { - if ( pTeamMate->m_bHasFlag ) - { - Dist = (pk->pev->origin - pTeamMate->pev->origin).Length(); - - if ( Dist <= TEAM_CAPTURE_TARGET_PROTECT_RADIUS ) - { - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING ( pk->pev->netname )); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " defends "); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "RED"); - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "'s flag carrier\n"); - - pk->AddPoints( TEAM_CAPTURE_CARRIER_PROTECT_BONUS, TRUE ); - } - } - } - } - } - } - - } - } - - CBaseEntity *pRune; - char * runeName; - - switch ( pVictim->m_iRuneStatus ) - { - case ITEM_RUNE1_FLAG: - - pRune = CBaseEntity::Create( "item_rune1", pVictim->pev->origin, pVictim->pev->angles, NULL ); - - pRune->pev->velocity = pVictim->pev->velocity * 1.5; - pRune->pev->angles.x = 0; - ((CResistRune*)pRune)->dropped = true; - - runeName = "ResistRune"; - - break; - - case ITEM_RUNE2_FLAG: - - pRune = CBaseEntity::Create( "item_rune2", pVictim->pev->origin, pVictim->pev->angles, NULL ); - - pRune->pev->velocity = pVictim->pev->velocity * 1.5; - pRune->pev->angles.x = 0; - ((CStrengthRune*)pRune)->dropped = true; - - runeName = "StrengthRune"; - - break; - - case ITEM_RUNE3_FLAG: - - pRune = CBaseEntity::Create( "item_rune3", pVictim->pev->origin, pVictim->pev->angles, NULL ); - - pRune->pev->velocity = pVictim->pev->velocity * 1.5; - pRune->pev->angles.x = 0; - ((CHasteRune*)pRune)->dropped = true; - - runeName = "HasteRune"; - - break; - - case ITEM_RUNE4_FLAG: - - pRune = CBaseEntity::Create( "item_rune4", pVictim->pev->origin, pVictim->pev->angles, NULL ); - - pRune->pev->velocity = pVictim->pev->velocity * 1.5; - pRune->pev->angles.x = 0; - ((CRegenRune*)pRune)->dropped = true; - - runeName = "RegenRune"; - - break; - - default: - - runeName = "Unknown"; - - break; - } - - if ( pVictim->m_iRuneStatus ) - { - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Dropped_%s\"\n", - STRING(pVictim->pev->netname), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - pVictim->m_szTeamName, - runeName ); - } - - if ( pVictim->m_ppHook ) - (( CGrapple *)pVictim->m_ppHook)->Reset_Grapple(); - - pVictim->m_iRuneStatus = 0; - - MESSAGE_BEGIN( MSG_ONE, gmsgRuneStatus, NULL, pVictim->pev); - WRITE_BYTE( pVictim->m_iRuneStatus ); - MESSAGE_END(); - - if ( !m_DisableDeathPenalty ) - { - CHalfLifeMultiplay::PlayerKilled( pVictim, pKiller, pInflictor ); - RecountTeams(); - } -} - - -//========================================================= -// IsTeamplay -//========================================================= -BOOL CThreeWave::IsTeamplay( void ) -{ - return TRUE; -} - -BOOL CThreeWave::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) -{ - if ( pAttacker && PlayerRelationship( pPlayer, pAttacker ) == GR_TEAMMATE ) - { - // my teammate hit me. - if ( (CVAR_GET_FLOAT("mp_friendlyfire") == 0) && (pAttacker != pPlayer) ) - { - // friendly fire is off, and this hit came from someone other than myself, then don't get hurt - return FALSE; - } - } - - return CHalfLifeMultiplay::FPlayerCanTakeDamage( pPlayer, pAttacker ); -} - -//========================================================= -//========================================================= -int CThreeWave::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) -{ - // half life multiplay has a simple concept of Player Relationships. - // you are either on another player's team, or you are not. - if ( !pPlayer || !pTarget || !pTarget->IsPlayer() ) - return GR_NOTTEAMMATE; - - //As simple as this - if ( pPlayer->pev->team == pTarget->pev->team ) - { - return GR_TEAMMATE; - } - - return GR_NOTTEAMMATE; -} - -//========================================================= -//========================================================= -BOOL CThreeWave::ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) -{ - // always autoaim, unless target is a teammate - CBaseEntity *pTgt = CBaseEntity::Instance( target ); - if ( pTgt && pTgt->IsPlayer() ) - { - if ( PlayerRelationship( pPlayer, pTgt ) == GR_TEAMMATE ) - return FALSE; // don't autoaim at teammates - } - - return CHalfLifeMultiplay::ShouldAutoAim( pPlayer, target ); -} - -//========================================================= -//========================================================= -int CThreeWave::IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) -{ - if ( !pKilled ) - return 0; - - if ( !pAttacker ) - return 1; - - if ( pAttacker != pKilled && PlayerRelationship( pAttacker, pKilled ) == GR_TEAMMATE ) - return -1; - - return 1; -} - -//========================================================= -//========================================================= -const char *CThreeWave::GetTeamID( CBaseEntity *pEntity ) -{ - if ( pEntity == NULL || pEntity->pev == NULL ) - return ""; - - // return their team name - return pEntity->TeamID(); -} - - -int CThreeWave::GetTeamIndex( const char *pTeamName ) -{ - if ( pTeamName && *pTeamName != 0 ) - { - // try to find existing team - for ( int tm = 0; tm < num_teams; tm++ ) - { - if ( !stricmp( team_names[tm], pTeamName ) ) - return tm; - } - } - - return -1; // No match -} - - -const char *CThreeWave::GetIndexedTeamName( int teamIndex ) -{ - if ( teamIndex < 0 || teamIndex >= num_teams ) - return ""; - - return team_names[ teamIndex ]; -} - - -BOOL CThreeWave::IsValidTeam( const char *pTeamName ) -{ - if ( !m_teamLimit ) // Any team is valid if the teamlist isn't set - return TRUE; - - return ( GetTeamIndex( pTeamName ) != -1 ) ? TRUE : FALSE; -} - - -void CThreeWave::GetFlagStatus( CBasePlayer *pPlayer ) -{ - - CBaseEntity *pFlag = NULL; - int iFoundCount = 0; - int iDropped = 0; - - while((pFlag = UTIL_FindEntityByClassname( pFlag, "carried_flag_team1")) != NULL) - { - if ( pFlag && !FBitSet( pFlag->pev->flags, FL_KILLME) ) - iFoundCount++; - } - - if ( iFoundCount >= 1 ) - iRedFlagStatus = RED_FLAG_STOLEN; - - if ( !iFoundCount ) - { - while((pFlag = UTIL_FindEntityByClassname( pFlag, "item_flag_team1")) != NULL) - { - if ( pFlag ) - { - if ( ((CItemFlag *)pFlag)->Dropped ) - iDropped++; - - iFoundCount++; - } - } - - if ( iFoundCount > 1 && iDropped == 1 ) - iRedFlagStatus = RED_FLAG_DROPPED; - else if ( iFoundCount >= 1 && iDropped == 0 ) - iRedFlagStatus = RED_FLAG_ATBASE; - } - - iDropped = iFoundCount = 0; - - while((pFlag = UTIL_FindEntityByClassname( pFlag, "carried_flag_team2")) != NULL) - { - if ( pFlag && !FBitSet( pFlag->pev->flags, FL_KILLME) ) - iFoundCount++; - } - - if ( iFoundCount >= 1 ) - iBlueFlagStatus = BLUE_FLAG_STOLEN; - - if ( !iFoundCount ) - { - - while((pFlag = UTIL_FindEntityByClassname( pFlag, "item_flag_team2")) != NULL) - { - if ( pFlag ) - { - if ( ((CItemFlag *)pFlag)->Dropped ) - iDropped++; - - iFoundCount++; - } - } - - if ( iFoundCount > 1 && iDropped == 1 ) - iBlueFlagStatus = BLUE_FLAG_DROPPED; - else if ( iFoundCount >= 1 && iDropped == 0 ) - iBlueFlagStatus = BLUE_FLAG_ATBASE; - } - - if ( pPlayer ) - { - if ( pPlayer->pev->team == 0 ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgFlagStatus, NULL, pPlayer->edict() ); - WRITE_BYTE( 0 ); - WRITE_BYTE( iRedFlagStatus ); - WRITE_BYTE( iBlueFlagStatus ); - WRITE_BYTE( iRedTeamScore ); - WRITE_BYTE( iBlueTeamScore ); - MESSAGE_END(); - } - else - { - MESSAGE_BEGIN( MSG_ONE, gmsgFlagStatus, NULL, pPlayer->edict() ); - WRITE_BYTE( 1 ); - WRITE_BYTE( iRedFlagStatus ); - WRITE_BYTE( iBlueFlagStatus ); - WRITE_BYTE( iRedTeamScore ); - WRITE_BYTE( iBlueTeamScore ); - MESSAGE_END(); - } - - pPlayer->m_flFlagStatusTime = 0.0; - } - else - { - MESSAGE_BEGIN( MSG_ALL, gmsgFlagStatus, NULL ); - WRITE_BYTE( 1 ); - WRITE_BYTE( iRedFlagStatus ); - WRITE_BYTE( iBlueFlagStatus ); - WRITE_BYTE( iRedTeamScore ); - WRITE_BYTE( iBlueTeamScore ); - MESSAGE_END(); - - m_flFlagStatusTime = 0.0; - } - - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - if ( plr ) - { - if ( ((CBasePlayer *)plr)->m_bHasFlag ) - { - MESSAGE_BEGIN( MSG_ALL, gmsgFlagCarrier, NULL ); - WRITE_BYTE( plr->entindex() ); - WRITE_BYTE( 1 ); - MESSAGE_END(); - } - else - { - MESSAGE_BEGIN( MSG_ALL, gmsgFlagCarrier, NULL ); - WRITE_BYTE( plr->entindex() ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - } - } - } -} - - -//========================================================= -//========================================================= -void CThreeWave::RecountTeams( void ) -{ - char *pName; - char teamlist[TEAMPLAY_TEAMLISTLENGTH]; - - // loop through all teams, recounting everything - num_teams = 0; - - // Copy all of the teams from the teamlist - // make a copy because strtok is destructive - strcpy( teamlist, m_szTeamList ); - pName = teamlist; - pName = strtok( pName, ";" ); - while ( pName != NULL && *pName ) - { - if ( GetTeamIndex( pName ) < 0 ) - { - strcpy( team_names[num_teams], pName ); - num_teams++; - } - pName = strtok( NULL, ";" ); - } - - if ( num_teams < 2 ) - { - num_teams = 0; - m_teamLimit = FALSE; - } - - // Sanity check - memset( team_scores, 0, sizeof(team_scores) ); - - // loop through all clients - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - - if ( plr ) - { - const char *pTeamName = plr->TeamID(); - // try add to existing team - int tm = GetTeamIndex( pTeamName ); - - if ( tm < 0 ) // no team match found - { - if ( !m_teamLimit ) - { - // add to new team - tm = num_teams; - num_teams++; - team_scores[tm] = 0; - strncpy( team_names[tm], pTeamName, MAX_TEAMNAME_LENGTH ); - } - } - - if ( tm >= 0 ) - { - team_scores[tm] += plr->pev->frags; - } - } - } -} - -/***************************************************** -****************************************************** - THREEWAVE CTF FLAG CODE -****************************************************** -*****************************************************/ - -enum Flag_Anims -{ - ON_GROUND = 0, - NOT_CARRIED, - CARRIED, - WAVE_IDLE, - FLAG_POSITION -}; - - -void CItemFlag::Spawn ( void ) -{ - 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( FlagThink ); - SetTouch( 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 if ( !Dropped ) - { - //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( void ) -{ - 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( FlagTouch ); - SetThink( 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( void ) -{ - 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( void ) -{ - 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( void ) - { - pev->team = RED; - CItemFlag::Spawn( ); - } -}; - -class CItemFlagTeam2 : public CItemFlag -{ - void Spawn( void ) - { - pev->team = BLUE; - CItemFlag::Spawn( ); - } -}; - -LINK_ENTITY_TO_CLASS( item_flag_team1, CItemFlagTeam1 ); -LINK_ENTITY_TO_CLASS( item_flag_team2, 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; - - m_iOwnerOldVel = 0; - - SetThink( 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; - - //Remove if owner is death - if (!Owner->IsAlive()) - UTIL_Remove( this ); - - //If owner lost flag, remove - if ( !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( void ) - { - pev->team = RED; - - CCarriedFlag::Spawn( ); - } -}; - -class CCarriedFlagTeam2 : public CCarriedFlag -{ - void Spawn( void ) - { - pev->team = BLUE; - - CCarriedFlag::Spawn( ); - } -}; - -LINK_ENTITY_TO_CLASS( carried_flag_team1, CCarriedFlagTeam1 ); -LINK_ENTITY_TO_CLASS( carried_flag_team2, CCarriedFlagTeam2 ); - - -/*************************************** -**************************************** - RUNES -**************************************** -***************************************/ - -/*---------------------------------------------------------------------- - 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 ( !strcmp( STRING( ent->pev->classname ), "item_rune1") || - !strcmp( STRING( ent->pev->classname ), "item_rune2") || - !strcmp( STRING( ent->pev->classname ), "item_rune3") || - !strcmp( STRING( ent->pev->classname ), "item_rune4") ) - return FALSE; - } - - return TRUE; -} - -edict_t *RuneSelectSpawnPoint( void ) -{ - CBaseEntity *pSpot; - - 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 == Vector( 0, 0, 0 ) ) - { - 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"); - if ( pSpot ) - goto ReturnSpot; - } - else - { - pSpot = UTIL_FindEntityByTargetname( NULL, STRING(gpGlobals->startspot) ); - if ( pSpot ) - goto ReturnSpot; - } - -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; - } - - CBaseEntity *pRune = NULL; - char * runeName; - - if ( pPlayer->m_iRuneStatus == ITEM_RUNE1_FLAG ) - { - pRune = CBaseEntity::Create( "item_rune1", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() ); - runeName = "ResistRune"; - - if ( pRune ) - ((CResistRune*)pRune)->dropped = true; - } - else if ( pPlayer->m_iRuneStatus == ITEM_RUNE2_FLAG ) - { - pRune = CBaseEntity::Create( "item_rune2", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() ); - runeName = "StrengthRune"; - - if ( pRune ) - ((CStrengthRune*)pRune)->dropped = true; - } - else if ( pPlayer->m_iRuneStatus == ITEM_RUNE3_FLAG ) - { - pRune = CBaseEntity::Create( "item_rune3", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() ); - runeName = "HasteRune"; - - if ( pRune ) - ((CHasteRune*)pRune)->dropped = true; - } - else if ( pPlayer->m_iRuneStatus == ITEM_RUNE4_FLAG ) - { - pRune = CBaseEntity::Create( "item_rune4", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() ); - runeName = "RegenRune"; - - if ( pRune ) - ((CRegenRune*)pRune)->dropped = true; - } - else - { - runeName = "Unknown"; - } - - if ( pPlayer->m_iRuneStatus == ITEM_RUNE3_FLAG ) - g_engfuncs.pfnSetClientMaxspeed( ENT( pPlayer->pev ), PLAYER_MAX_SPEED ); //Reset Haste player speed to normal - - pPlayer->m_iRuneStatus = 0; - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Dropped_%s\"\n", - STRING(pPlayer->pev->netname), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - pPlayer->m_szTeamName, - runeName ); - - MESSAGE_BEGIN( MSG_ONE, gmsgRuneStatus, NULL, pPlayer->pev); - WRITE_BYTE( pPlayer->m_iRuneStatus ); - MESSAGE_END(); -} - - -void CResistRune::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; - - //Only one per customer - if ( ((CBasePlayer *)pOther)->m_iRuneStatus ) - { - ClientPrint( pOther->pev, HUD_PRINTCENTER, "You already have a rune!\n" ); - return; - } - - if ( !m_bTouchable ) - return; - - ((CBasePlayer *)pOther)->m_iRuneStatus = m_iRuneFlag; //Add me the rune flag - - ClientPrint( pOther->pev, HUD_PRINTCENTER, "You got the rune of Resistance!\n" ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Found_ResistRune\"\n", - STRING(pOther->pev->netname), - GETPLAYERUSERID( pOther->edict() ), - GETPLAYERAUTHID( pOther->edict() ), - ((CBasePlayer *)pOther)->m_szTeamName ); - - 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( ((CBasePlayer *)pOther)->m_iRuneStatus ); - MESSAGE_END(); - - //And Remove this entity - UTIL_Remove( this ); -} - - -void CResistRune::RuneRespawn ( void ) -{ - edict_t *pentSpawnSpot; - vec3_t vOrigin; - - pentSpawnSpot = RuneSelectSpawnPoint(); - vOrigin = VARS(pentSpawnSpot)->origin; - - UTIL_SetOrigin( pev, vOrigin ); - - if ( dropped ) - UTIL_LogPrintf( "\"<-1><><>\" triggered triggered \"Respawn_ResistRune\"\n" ); - - Spawn(); -} - -void CResistRune::MakeTouchable ( void ) -{ - 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 ( RuneRespawn ); -} - -void CResistRune::Spawn ( void ) -{ - SET_MODEL( ENT(pev), "models/rune_resist.mdl"); - - m_bTouchable = FALSE; - - m_iRuneFlag = ITEM_RUNE1_FLAG; - - dropped = false; - - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - - vec3_t forward, right, up; - - 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 ) - g_engfuncs.pfnAngleVectors ( pev->owner->v.angles, forward, right, up ); - else - g_engfuncs.pfnAngleVectors ( pev->angles, 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( RuneTouch ); - - pev->nextthink = gpGlobals->time + 1; - SetThink ( MakeTouchable ); -} - - -LINK_ENTITY_TO_CLASS( item_rune1, CResistRune ); - - -void CStrengthRune::MakeTouchable ( void ) -{ - 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 ( RuneRespawn ); -} - -void CStrengthRune::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; - - //Only one per customer - if ( ((CBasePlayer *)pOther)->m_iRuneStatus ) - { - ClientPrint( pOther->pev, HUD_PRINTCENTER, "You already have a rune!\n" ); - return; - } - - if ( !m_bTouchable ) - return; - - ((CBasePlayer *)pOther)->m_iRuneStatus = m_iRuneFlag; //Add me the rune flag - - ClientPrint( pOther->pev, HUD_PRINTCENTER, "You got the rune of Strength!\n" ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Found_StrengthRune\"\n", - STRING(pOther->pev->netname), - GETPLAYERUSERID( pOther->edict() ), - GETPLAYERAUTHID( pOther->edict() ), - ((CBasePlayer *)pOther)->m_szTeamName ); - - 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( ((CBasePlayer *)pOther)->m_iRuneStatus ); - MESSAGE_END(); - - //And Remove this entity - UTIL_Remove( this ); -} - -void CStrengthRune::RuneRespawn ( void ) -{ - edict_t *pentSpawnSpot; - vec3_t vOrigin; - - pentSpawnSpot = RuneSelectSpawnPoint(); - vOrigin = VARS(pentSpawnSpot)->origin; - - UTIL_SetOrigin( pev, vOrigin ); - - if ( dropped ) - UTIL_LogPrintf( "\"<-1><><>\" triggered triggered \"Respawn_StrengthRune\"\n" ); - - Spawn(); -} - - -void CStrengthRune::Spawn ( void ) -{ - SET_MODEL( ENT(pev), "models/rune_strength.mdl"); - - m_bTouchable = FALSE; - - m_iRuneFlag = ITEM_RUNE2_FLAG; - - dropped = false; - - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - - vec3_t forward, right, up; - - 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 ) - g_engfuncs.pfnAngleVectors ( pev->owner->v.angles, forward, right, up); - else - g_engfuncs.pfnAngleVectors ( pev->angles, 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( RuneTouch ); - - pev->nextthink = gpGlobals->time + 1; - SetThink ( MakeTouchable ); -} - - -LINK_ENTITY_TO_CLASS( item_rune2, CStrengthRune ); - -void CHasteRune::MakeTouchable ( void ) -{ - 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 ( RuneRespawn ); -} - - -void CHasteRune::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; - - //Only one per customer - if ( ((CBasePlayer *)pOther)->m_iRuneStatus ) - { - ClientPrint( pOther->pev, HUD_PRINTCENTER, "You already have a rune!\n" ); - return; - } - - if ( !m_bTouchable ) - return; - - ((CBasePlayer *)pOther)->m_iRuneStatus = m_iRuneFlag; //Add me the rune flag - - ClientPrint( pOther->pev, HUD_PRINTCENTER, "You got the rune of Haste!\n" ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Found_HasteRune\"\n", - STRING(pOther->pev->netname), - GETPLAYERUSERID( pOther->edict() ), - GETPLAYERAUTHID( pOther->edict() ), - ((CBasePlayer *)pOther)->m_szTeamName ); - - g_engfuncs.pfnSetClientMaxspeed( ENT( pOther->pev ), ( PLAYER_MAX_SPEED * 1.25 ) ); //25% more speed - - 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( ((CBasePlayer *)pOther)->m_iRuneStatus ); - MESSAGE_END(); - - //And Remove this entity - UTIL_Remove( this ); -} - -void CHasteRune::RuneRespawn ( void ) -{ - edict_t *pentSpawnSpot; - vec3_t vOrigin; - - pentSpawnSpot = RuneSelectSpawnPoint(); - vOrigin = VARS(pentSpawnSpot)->origin; - - UTIL_SetOrigin( pev, vOrigin ); - - if ( dropped ) - UTIL_LogPrintf( "\"<-1><><>\" triggered triggered \"Respawn_HasteRune\"\n" ); - - Spawn(); -} - - -void CHasteRune::Spawn ( void ) -{ - SET_MODEL( ENT(pev), "models/rune_haste.mdl"); - - m_bTouchable = FALSE; - - m_iRuneFlag = ITEM_RUNE3_FLAG; - - dropped = false; - - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - - vec3_t forward, right, up; - - 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 ) - g_engfuncs.pfnAngleVectors ( pev->owner->v.angles, forward, right, up); - else - g_engfuncs.pfnAngleVectors ( pev->angles, 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( 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 ( MakeTouchable ); -} - - -LINK_ENTITY_TO_CLASS( item_rune3, CHasteRune ); - - -void CRegenRune::MakeTouchable ( void ) -{ - 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 ( RuneRespawn ); -} - -void CRegenRune::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; - - //Only one per customer - if ( ((CBasePlayer *)pOther)->m_iRuneStatus ) - { - ClientPrint( pOther->pev, HUD_PRINTCENTER, "You already have a rune!\n" ); - return; - } - - if ( !m_bTouchable ) - return; - - ((CBasePlayer *)pOther)->m_iRuneStatus = m_iRuneFlag; //Add me the rune flag - - ClientPrint( pOther->pev, HUD_PRINTCENTER, "You got the rune of Regeneration!\n" ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Found_RegenRune\"\n", - STRING(pOther->pev->netname), - GETPLAYERUSERID( pOther->edict() ), - GETPLAYERAUTHID( pOther->edict() ), - ((CBasePlayer *)pOther)->m_szTeamName ); - - 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( ((CBasePlayer *)pOther)->m_iRuneStatus ); - MESSAGE_END(); - - //And Remove this entity - UTIL_Remove( this ); -} - -void CRegenRune::RuneRespawn ( void ) -{ - edict_t *pentSpawnSpot; - vec3_t vOrigin; - - pentSpawnSpot = RuneSelectSpawnPoint(); - vOrigin = VARS(pentSpawnSpot)->origin; - - UTIL_SetOrigin( pev, vOrigin ); - - if ( dropped ) - UTIL_LogPrintf( "\"<-1><><>\" triggered triggered \"Respawn_RegenRune\"\n" ); - - Spawn(); -} - - -void CRegenRune::Spawn ( void ) -{ - - SET_MODEL( ENT(pev), "models/rune_regen.mdl" ); - - m_bTouchable = FALSE; - - m_iRuneFlag = ITEM_RUNE4_FLAG; - - dropped = false; - - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - - vec3_t forward, right, up; - - 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 ) - g_engfuncs.pfnAngleVectors ( pev->owner->v.angles, forward, right, up); - else - g_engfuncs.pfnAngleVectors ( pev->angles, 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( 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 ( MakeTouchable ); -} - - -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( void ) -{ - 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; -} - - -/*********************************************** -************************************************ - GRAPPLE -************************************************ -***********************************************/ - -void CGrapple::Reset_Grapple ( void ) -{ - CBaseEntity *pOwner = CBaseEntity::Instance( pev->owner ); - - ((CBasePlayer *)pOwner)->m_bOn_Hook = FALSE; - ((CBasePlayer *)pOwner)->m_bHook_Out = FALSE; - - PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE, - ((CBasePlayer *)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( ((CBasePlayer *)pOwner)->edict(), CHAN_WEAPON, "weapons/grfire.wav" ); - STOP_SOUND( ((CBasePlayer *)pOwner)->edict(), CHAN_WEAPON, "weapons/grpull.wav" ); - - ((CBasePlayer *)pOwner)->m_ppHook = NULL; - pev->enemy = NULL; - - UTIL_Remove ( this ); -} - -void CGrapple::GrappleTouch ( CBaseEntity *pOther ) -{ - CBaseEntity *pOwner = 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 ( FClassnameIs( pOther->pev, "grenade" )|| - FClassnameIs( pOther->pev, "spike" ) || - FClassnameIs( pOther->pev, "hook" ) ) - return; - - if ( FClassnameIs( pOther->pev, "player" ) ) - { - // 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 = Vector(0,0,0); - UTIL_SetOrigin( pev, pOther->pev->origin); - } - else if ( !FClassnameIs( pOther->pev, "player" ) ) - { - // 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 = Vector(0,0,0); - - 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 ( ((CBasePlayer*)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'); - } - - ((CBasePlayer*)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( ((CBasePlayer *)pOwner)->edict(), CHAN_WEAPON, "weapons/grfire.wav" ); - - pev->enemy = pOther->edict();// remember this guy! - SetThink ( 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 ( void ) -{ - CBaseEntity *pOwner = CBaseEntity::Instance( pev->owner ); - CBaseEntity *pEnemy = CBaseEntity::Instance( pev->enemy ); - - // Release dead targets - if ( FClassnameIs( pEnemy->pev, "player" ) && pEnemy->pev->health <= 0) - Reset_Grapple(); - - - // drop the hook if owner is dead or has released the button - if ( !((CBasePlayer*)pOwner)->m_bOn_Hook|| ((CBasePlayer*)pOwner)->pev->health <= 0) - { - Reset_Grapple(); - return; - } - - if ( !(pOwner->pev->button & IN_ATTACK) ) - { - if ( ((CBasePlayer*)pOwner)->m_iQuakeWeapon == IT_EXTRA_WEAPON ) - { - Reset_Grapple(); - return; - } - } - - // bring the pAiN! - if ( FClassnameIs( pEnemy->pev, "player" ) ) - { - 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. - if ( !FClassnameIs( pEnemy->pev, "player" ) ) - pev->velocity = pEnemy->pev->velocity; - - pev->nextthink = gpGlobals->time + 0.1; -}; - -void CBasePlayer::Service_Grapple ( void ) -{ - 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 ) - { - ((CGrapple *)m_ppHook)->Reset_Grapple(); - return; - } - } - - if ( m_ppHook->pev->enemy != NULL ) - { - // If hooked to a player, track them directly! - if ( FClassnameIs( pEnemy->pev, "player" ) ) - { - pEnemy = CBaseEntity::Instance( pev->enemy ); - hook_dir = ( pEnemy->pev->origin - pev->origin ); - } - // else, track to hook - else if ( !FClassnameIs( pEnemy->pev, "player" ) ) - hook_dir = ( m_ppHook->pev->origin - pev->origin ); - - pev->velocity = ( (hook_dir).Normalize() * 750 ); - pev->speed = 750; - - if ( ((CGrapple *)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); - - ((CGrapple *)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 ( ((CGrapple *)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); - ((CGrapple *)m_ppHook)->m_flNextIdleTime = gpGlobals->time + RANDOM_LONG( 1, 3 ); - } - - } -}; - -void CGrapple::OnAirThink ( void ) -{ - 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 ( void ) -{ - pev->movetype = MOVETYPE_FLYMISSILE; - pev->solid = SOLID_BBOX; - - SET_MODEL ( ENT(pev),"models/hook.mdl"); - - SetTouch ( GrappleTouch ); - SetThink ( OnAirThink ); - - pev->nextthink = gpGlobals->time + 0.1; -} - -LINK_ENTITY_TO_CLASS( hook, CGrapple ); - -void CBasePlayer::Throw_Grapple ( void ) -{ - if ( m_bHook_Out ) - return; - - CBaseEntity *pHookCBEnt = NULL; - - pHookCBEnt = 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, Vector(0,0,0) , Vector(0,0,0) ); - - 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; - } -}; - - - -#endif diff --git a/dmc/dlls/threewave_gamerules.h b/dmc/dlls/threewave_gamerules.h deleted file mode 100644 index 9f7d148..0000000 --- a/dmc/dlls/threewave_gamerules.h +++ /dev/null @@ -1,221 +0,0 @@ -#ifdef THREEWAVE - -#define BLUE 2 -#define RED 1 - - -#include "voice_gamemgr.h" - - - -//========================================================= -// Flags -//========================================================= -class CItemFlag : public CBaseEntity -{ -public: - void Spawn( void ); - - BOOL Dropped; - float m_flDroppedTime; - - void EXPORT FlagThink( void ); - -private: - void Precache ( void ); - void Capture(CBasePlayer *pPlayer, int iTeam ); - void ResetFlag( int iTeam ); - void Materialize( void ); - void EXPORT FlagTouch( CBaseEntity *pOther ); - // BOOL MyTouch( CBasePlayer *pPlayer ); - -}; - -class CCarriedFlag : public CBaseEntity -{ -public: - void Spawn( void ); - - CBasePlayer *Owner; - - int m_iOwnerOldVel; - -private: - void Precache ( void ); - void EXPORT FlagThink( void ); -}; - - -class CResistRune : public CBaseEntity -{ -private: - - void EXPORT RuneRespawn ( void ); - -public: - - void EXPORT RuneTouch ( CBaseEntity *pOther ); - void Spawn( void ); - - void EXPORT MakeTouchable ( void ); - - int m_iRuneFlag; - bool m_bTouchable; - bool dropped; -}; - -class CStrengthRune : public CBaseEntity -{ - -private: - void EXPORT RuneRespawn ( void ); - -public: - - void EXPORT RuneTouch ( CBaseEntity *pOther ); - void Spawn( void ); - - void EXPORT MakeTouchable ( void ); - - int m_iRuneFlag; - bool m_bTouchable; - bool dropped; -}; - - -class CHasteRune : public CBaseEntity -{ - -private: - void EXPORT RuneRespawn ( void ); -public: - - void EXPORT RuneTouch ( CBaseEntity *pOther ); - - void EXPORT MakeTouchable ( void ); - void Spawn( void ); - - int m_iRuneFlag; - bool m_bTouchable; - bool dropped; -}; - - -class CRegenRune : public CBaseEntity -{ - -private: - void EXPORT RuneRespawn ( void ); - -public: - - void EXPORT RuneTouch ( CBaseEntity *pOther ); - void Spawn( void ); - - void EXPORT MakeTouchable ( void ); - - int m_iRuneFlag; - bool m_bTouchable; - bool dropped; -}; - -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 ( void ); - void EXPORT OnAirThink ( void ); - void EXPORT GrappleTouch ( CBaseEntity *pOther ); - void Reset_Grapple ( void ); - void EXPORT Grapple_Track ( void ); - - float m_flNextIdleTime; - -}; - - - -#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 - - -#define MAX_TEAMNAME_LENGTH 16 -#define MAX_TEAMS 32 - -#define TEAMPLAY_TEAMLISTLENGTH MAX_TEAMS*MAX_TEAMNAME_LENGTH - -class CThreeWave : public CHalfLifeMultiplay -{ -public: - CThreeWave(); - - virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); - virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ); - virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ); - virtual BOOL IsTeamplay( void ); - virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ); - virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); - virtual const char *GetTeamID( CBaseEntity *pEntity ); - virtual BOOL ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ); - virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); - virtual void InitHUD( CBasePlayer *pl ); - virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ); - virtual const char *GetGameDescription( void ) { return "3Wave CTF"; } // this is the game name that gets seen in the server browser - virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode - virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - virtual void Think ( void ); - virtual int GetTeamIndex( const char *pTeamName ); - virtual const char *GetIndexedTeamName( int teamIndex ); - virtual BOOL IsValidTeam( const char *pTeamName ); - virtual void ChangePlayerTeam( CBasePlayer *pPlayer, int iTeam ); - virtual void PlayerSpawn( CBasePlayer *pPlayer ); - void JoinTeam ( CBasePlayer *pPlayer, int iTeam ); - int TeamWithFewestPlayers ( void ); - virtual void ClientDisconnected( edict_t *pClient ); - void GetFlagStatus( CBasePlayer *pPlayer ); - - virtual edict_t *GetPlayerSpawnSpot( CBasePlayer *pPlayer ); - - virtual void PlayerThink( CBasePlayer *pPlayer ); - - void PlayerTakeDamage( CBasePlayer *pPlayer , CBaseEntity *pAttacker ); - - int iBlueFlagStatus; - int iRedFlagStatus; - - int iBlueTeamScore; - int iRedTeamScore; - - float m_flFlagStatusTime; - -private: - void RecountTeams( void ); - - BOOL m_DisableDeathMessages; - BOOL m_DisableDeathPenalty; - BOOL m_teamLimit; // This means the server set only some teams as valid - char m_szTeamList[TEAMPLAY_TEAMLISTLENGTH]; -}; - -#endif diff --git a/dmc/dlls/trains.h b/dmc/dlls/trains.h deleted file mode 100644 index 87aec76..0000000 --- a/dmc/dlls/trains.h +++ /dev/null @@ -1,127 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef TRAINS_H -#define TRAINS_H - -// Tracktrain spawn flags -#define SF_TRACKTRAIN_NOPITCH 0x0001 -#define SF_TRACKTRAIN_NOCONTROL 0x0002 -#define SF_TRACKTRAIN_FORWARDONLY 0x0004 -#define SF_TRACKTRAIN_PASSABLE 0x0008 - -// Spawnflag for CPathTrack -#define SF_PATH_DISABLED 0x00000001 -#define SF_PATH_FIREONCE 0x00000002 -#define SF_PATH_ALTREVERSE 0x00000004 -#define SF_PATH_DISABLE_TRAIN 0x00000008 -#define SF_PATH_ALTERNATE 0x00008000 - -// Spawnflags of CPathCorner -#define SF_CORNER_WAITFORTRIG 0x001 -#define SF_CORNER_TELEPORT 0x002 -#define SF_CORNER_FIREONCE 0x004 - -//#define PATH_SPARKLE_DEBUG 1 // This makes a particle effect around path_track entities for debugging -class CPathTrack : public CPointEntity -{ -public: - void Spawn( void ); - void Activate( void ); - void KeyValue( KeyValueData* pkvd); - - void SetPrevious( CPathTrack *pprevious ); - void Link( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - CPathTrack *ValidPath( CPathTrack *ppath, int testFlag ); // Returns ppath if enabled, NULL otherwise - void Project( CPathTrack *pstart, CPathTrack *pend, Vector *origin, float dist ); - - static CPathTrack *Instance( edict_t *pent ); - - CPathTrack *LookAhead( Vector *origin, float dist, int move ); - CPathTrack *Nearest( Vector origin ); - - CPathTrack *GetNext( void ); - CPathTrack *GetPrevious( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; -#if PATH_SPARKLE_DEBUG - void EXPORT Sparkle(void); -#endif - - float m_length; - string_t m_altName; - CPathTrack *m_pnext; - CPathTrack *m_pprevious; - CPathTrack *m_paltpath; -}; - - -class CFuncTrackTrain : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - - void Blocked( CBaseEntity *pOther ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData* pkvd ); - - void EXPORT Next( void ); - void EXPORT Find( void ); - void EXPORT NearestPath( void ); - void EXPORT DeadEnd( void ); - - void NextThink( float thinkTime, BOOL alwaysThink ); - - void SetTrack( CPathTrack *track ) { m_ppath = track->Nearest(pev->origin); } - void SetControls( entvars_t *pevControls ); - BOOL OnControls( entvars_t *pev ); - - void StopSound ( void ); - void UpdateSound ( void ); - - static CFuncTrackTrain *Instance( edict_t *pent ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DIRECTIONAL_USE; } - - virtual void OverrideReset( void ); - - CPathTrack *m_ppath; - float m_length; - float m_height; - float m_speed; - float m_dir; - float m_startSpeed; - Vector m_controlMins; - Vector m_controlMaxs; - int m_soundPlaying; - int m_sounds; - float m_flVolume; - float m_flBank; - float m_oldSpeed; - -private: - unsigned short m_usAdjustPitch; -}; - -#endif diff --git a/dmc/dlls/triggers.cpp b/dmc/dlls/triggers.cpp deleted file mode 100644 index 8fbf734..0000000 --- a/dmc/dlls/triggers.cpp +++ /dev/null @@ -1,2716 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== triggers.cpp ======================================================== - - spawn and use functions for editor-placed triggers - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "saverestore.h" -#include "trains.h" // trigger_camera has train functionality -#include "gamerules.h" - -#define SF_TRIGGER_PUSH_START_OFF 2//spawnflag that makes trigger_push spawn turned OFF -#define SF_TRIGGER_HURT_TARGETONCE 1// Only fire hurt target once -#define SF_TRIGGER_HURT_START_OFF 2//spawnflag that makes trigger_push spawn turned OFF -#define SF_TRIGGER_HURT_NO_CLIENTS 8//spawnflag that makes trigger_push spawn turned OFF -#define SF_TRIGGER_HURT_CLIENTONLYFIRE 16// trigger hurt will only fire its target if it is hurting a client -#define SF_TRIGGER_HURT_CLIENTONLYTOUCH 32// only clients may touch this trigger. - -extern DLL_GLOBAL BOOL g_fGameOver; - -extern Vector g_vecTeleMins[ MAX_TELES ]; -extern Vector g_vecTeleMaxs[ MAX_TELES ]; -extern int g_iTeleNum; - -extern void SetMovedir(entvars_t* pev); -extern Vector VecBModelOrigin( entvars_t* pevBModel ); - -extern unsigned short g_sTeleport; - -class CFrictionModifier : public CBaseEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT ChangeFriction( CBaseEntity *pOther ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - static TYPEDESCRIPTION m_SaveData[]; - - float m_frictionFraction; // Sorry, couldn't resist this name :) -}; - -LINK_ENTITY_TO_CLASS( func_friction, CFrictionModifier ); - -// Global Savedata for changelevel friction modifier -TYPEDESCRIPTION CFrictionModifier::m_SaveData[] = -{ - DEFINE_FIELD( CFrictionModifier, m_frictionFraction, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE(CFrictionModifier,CBaseEntity); - - -// Modify an entity's friction -void CFrictionModifier :: Spawn( void ) -{ - pev->solid = SOLID_TRIGGER; - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world - pev->movetype = MOVETYPE_NONE; - SetTouch( &CFrictionModifier::ChangeFriction ); -} - - -// Sets toucher's friction to m_frictionFraction (1.0 = normal friction) -void CFrictionModifier :: ChangeFriction( CBaseEntity *pOther ) -{ - if ( pOther->pev->movetype != MOVETYPE_BOUNCEMISSILE && pOther->pev->movetype != MOVETYPE_BOUNCE ) - pOther->pev->friction = m_frictionFraction; -} - - - -// Sets toucher's friction to m_frictionFraction (1.0 = normal friction) -void CFrictionModifier :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "modifier")) - { - m_frictionFraction = atof(pkvd->szValue) / 100.0; - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -// This trigger will fire when the level spawns (or respawns if not fire once) -// It will check a global state before firing. It supports delay and killtargets - -#define SF_AUTO_FIREONCE 0x0001 - -class CAutoTrigger : public CBaseDelay -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn( void ); - void Precache( void ); - void Think( void ); - - int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - int m_globalstate; - USE_TYPE triggerType; -}; -LINK_ENTITY_TO_CLASS( trigger_auto, CAutoTrigger ); - -TYPEDESCRIPTION CAutoTrigger::m_SaveData[] = -{ - DEFINE_FIELD( CAutoTrigger, m_globalstate, FIELD_STRING ), - DEFINE_FIELD( CAutoTrigger, triggerType, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE(CAutoTrigger,CBaseDelay); - -void CAutoTrigger::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "globalstate")) - { - m_globalstate = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "triggerstate")) - { - int type = atoi( pkvd->szValue ); - switch( type ) - { - case 0: - triggerType = USE_OFF; - break; - case 2: - triggerType = USE_TOGGLE; - break; - default: - triggerType = USE_ON; - break; - } - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - - -void CAutoTrigger::Spawn( void ) -{ - Precache(); -} - - -void CAutoTrigger::Precache( void ) -{ - pev->nextthink = gpGlobals->time + 0.1; -} - - -void CAutoTrigger::Think( void ) -{ - if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON ) - { - SUB_UseTargets( this, triggerType, 0 ); - if ( pev->spawnflags & SF_AUTO_FIREONCE ) - UTIL_Remove( this ); - } -} - - - -#define SF_RELAY_FIREONCE 0x0001 - -class CTriggerRelay : public CBaseDelay -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - USE_TYPE triggerType; -}; -LINK_ENTITY_TO_CLASS( trigger_relay, CTriggerRelay ); - -TYPEDESCRIPTION CTriggerRelay::m_SaveData[] = -{ - DEFINE_FIELD( CTriggerRelay, triggerType, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE(CTriggerRelay,CBaseDelay); - -void CTriggerRelay::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "triggerstate")) - { - int type = atoi( pkvd->szValue ); - switch( type ) - { - case 0: - triggerType = USE_OFF; - break; - case 2: - triggerType = USE_TOGGLE; - break; - default: - triggerType = USE_ON; - break; - } - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - - -void CTriggerRelay::Spawn( void ) -{ -} - - - - -void CTriggerRelay::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SUB_UseTargets( this, triggerType, 0 ); - if ( pev->spawnflags & SF_RELAY_FIREONCE ) - UTIL_Remove( this ); -} - - -//********************************************************** -// The Multimanager Entity - when fired, will fire up to 16 targets -// at specified times. -// FLAG: THREAD (create clones when triggered) -// FLAG: CLONE (this is a clone for a threaded execution) - -#define SF_MULTIMAN_CLONE 0x80000000 -#define SF_MULTIMAN_THREAD 0x00000001 - -class CMultiManager : public CBaseToggle -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn ( void ); - void EXPORT ManagerThink ( void ); - void EXPORT ManagerUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -#if _DEBUG - void EXPORT ManagerReport( void ); -#endif - - BOOL HasTarget( string_t targetname ); - - int ObjectCaps( void ) { return CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - int m_cTargets; // the total number of targets in this manager's fire list. - int m_index; // Current target - float m_startTime;// Time we started firing - int m_iTargetName [ MAX_MULTI_TARGETS ];// list if indexes into global string array - float m_flTargetDelay [ MAX_MULTI_TARGETS ];// delay (in seconds) from time of manager fire to target fire -private: - inline BOOL IsClone( void ) { return (pev->spawnflags & SF_MULTIMAN_CLONE) ? TRUE : FALSE; } - inline BOOL ShouldClone( void ) - { - if ( IsClone() ) - return FALSE; - - return (pev->spawnflags & SF_MULTIMAN_THREAD) ? TRUE : FALSE; - } - - CMultiManager *Clone( void ); -}; -LINK_ENTITY_TO_CLASS( multi_manager, CMultiManager ); - -// Global Savedata for multi_manager -TYPEDESCRIPTION CMultiManager::m_SaveData[] = -{ - DEFINE_FIELD( CMultiManager, m_cTargets, FIELD_INTEGER ), - DEFINE_FIELD( CMultiManager, m_index, FIELD_INTEGER ), - DEFINE_FIELD( CMultiManager, m_startTime, FIELD_TIME ), - DEFINE_ARRAY( CMultiManager, m_iTargetName, FIELD_STRING, MAX_MULTI_TARGETS ), - DEFINE_ARRAY( CMultiManager, m_flTargetDelay, FIELD_FLOAT, MAX_MULTI_TARGETS ), -}; - -IMPLEMENT_SAVERESTORE(CMultiManager,CBaseToggle); - -void CMultiManager :: KeyValue( KeyValueData *pkvd ) -{ - // UNDONE: Maybe this should do something like this: - //CBaseToggle::KeyValue( pkvd ); - // if ( !pkvd->fHandled ) - // ... etc. - - if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else // add this field to the target list - { - // this assumes that additional fields are targetnames and their values are delay values. - if ( m_cTargets < MAX_MULTI_TARGETS ) - { - char tmp[128]; - - UTIL_StripToken( pkvd->szKeyName, tmp ); - m_iTargetName [ m_cTargets ] = ALLOC_STRING( tmp ); - m_flTargetDelay [ m_cTargets ] = atof (pkvd->szValue); - m_cTargets++; - pkvd->fHandled = TRUE; - } - } -} - - -void CMultiManager :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - SetUse ( &CMultiManager::ManagerUse ); - SetThink ( &CMultiManager::ManagerThink); - - // Sort targets - // Quick and dirty bubble sort - int swapped = 1; - - while ( swapped ) - { - swapped = 0; - for ( int i = 1; i < m_cTargets; i++ ) - { - if ( m_flTargetDelay[i] < m_flTargetDelay[i-1] ) - { - // Swap out of order elements - int name = m_iTargetName[i]; - float delay = m_flTargetDelay[i]; - m_iTargetName[i] = m_iTargetName[i-1]; - m_flTargetDelay[i] = m_flTargetDelay[i-1]; - m_iTargetName[i-1] = name; - m_flTargetDelay[i-1] = delay; - swapped = 1; - } - } - } -} - - -BOOL CMultiManager::HasTarget( string_t targetname ) -{ - for ( int i = 0; i < m_cTargets; i++ ) - if ( FStrEq(STRING(targetname), STRING(m_iTargetName[i])) ) - return TRUE; - - return FALSE; -} - - -// Designers were using this to fire targets that may or may not exist -- -// so I changed it to use the standard target fire code, made it a little simpler. -void CMultiManager :: ManagerThink ( void ) -{ - float time; - - time = gpGlobals->time - m_startTime; - while ( m_index < m_cTargets && m_flTargetDelay[ m_index ] <= time ) - { - FireTargets( STRING( m_iTargetName[ m_index ] ), m_hActivator, this, USE_TOGGLE, 0 ); - m_index++; - } - - if ( m_index >= m_cTargets )// have we fired all targets? - { - SetThink( NULL ); - if ( IsClone() ) - { - UTIL_Remove( this ); - return; - } - SetUse ( &CMultiManager::ManagerUse );// allow manager re-use - } - else - pev->nextthink = m_startTime + m_flTargetDelay[ m_index ]; -} - -CMultiManager *CMultiManager::Clone( void ) -{ - CMultiManager *pMulti = GetClassPtr( (CMultiManager *)NULL ); - - edict_t *pEdict = pMulti->pev->pContainingEntity; - memcpy( pMulti->pev, pev, sizeof(*pev) ); - pMulti->pev->pContainingEntity = pEdict; - - pMulti->pev->spawnflags |= SF_MULTIMAN_CLONE; - pMulti->m_cTargets = m_cTargets; - memcpy( pMulti->m_iTargetName, m_iTargetName, sizeof( m_iTargetName ) ); - memcpy( pMulti->m_flTargetDelay, m_flTargetDelay, sizeof( m_flTargetDelay ) ); - - return pMulti; -} - - -// The USE function builds the time table and starts the entity thinking. -void CMultiManager :: ManagerUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // In multiplayer games, clone the MM and execute in the clone (like a thread) - // to allow multiple players to trigger the same multimanager - if ( ShouldClone() ) - { - CMultiManager *pClone = Clone(); - pClone->ManagerUse( pActivator, pCaller, useType, value ); - return; - } - - m_hActivator = pActivator; - m_index = 0; - m_startTime = gpGlobals->time; - - SetUse( NULL );// disable use until all targets have fired - - SetThink ( &CMultiManager::ManagerThink ); - pev->nextthink = gpGlobals->time; -} - -#if _DEBUG -void CMultiManager :: ManagerReport ( void ) -{ - int cIndex; - - for ( cIndex = 0 ; cIndex < m_cTargets ; cIndex++ ) - { - ALERT ( at_console, "%s %f\n", STRING(m_iTargetName[cIndex]), m_flTargetDelay[cIndex] ); - } -} -#endif - -//*********************************************************** - - -// -// Render parameters trigger -// -// This entity will copy its render parameters (renderfx, rendermode, rendercolor, renderamt) -// to its targets when triggered. -// - - -// Flags to indicate masking off various render parameters that are normally copied to the targets -#define SF_RENDER_MASKFX (1<<0) -#define SF_RENDER_MASKAMT (1<<1) -#define SF_RENDER_MASKMODE (1<<2) -#define SF_RENDER_MASKCOLOR (1<<3) - -class CRenderFxManager : public CBaseEntity -{ -public: - void Spawn( void ); - void Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); -}; - -LINK_ENTITY_TO_CLASS( env_render, CRenderFxManager ); - - -void CRenderFxManager :: Spawn ( void ) -{ - pev->solid = SOLID_NOT; -} - -void CRenderFxManager :: Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if (!FStringNull(pev->target)) - { - edict_t* pentTarget = NULL; - while ( 1 ) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target)); - if (FNullEnt(pentTarget)) - break; - - entvars_t *pevTarget = VARS( pentTarget ); - if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKFX ) ) - pevTarget->renderfx = pev->renderfx; - if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKAMT ) ) - pevTarget->renderamt = pev->renderamt; - if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKMODE ) ) - pevTarget->rendermode = pev->rendermode; - if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKCOLOR ) ) - pevTarget->rendercolor = pev->rendercolor; - } - } -} - - - -class CBaseTrigger : public CBaseToggle -{ -public: - void EXPORT TeleportTouch ( CBaseEntity *pOther ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT MultiTouch( CBaseEntity *pOther ); - void EXPORT HurtTouch ( CBaseEntity *pOther ); - void EXPORT EnvTouch ( CBaseEntity *pOther ); - void EXPORT CDAudioTouch ( CBaseEntity *pOther ); - void ActivateMultiTrigger( CBaseEntity *pActivator ); - void EXPORT MultiWaitOver( void ); - void EXPORT CounterUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void InitTrigger( void ); - - virtual int ObjectCaps( void ) { return CBaseToggle :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } -}; - -LINK_ENTITY_TO_CLASS( trigger, CBaseTrigger ); - -/* -================ -InitTrigger -================ -*/ -void CBaseTrigger::InitTrigger( ) -{ - // trigger angles are used for one-way touches. An angle of 0 is assumed - // to mean no restrictions, so use a yaw of 360 instead. - if (pev->angles != g_vecZero) - SetMovedir(pev); - pev->solid = SOLID_TRIGGER; - pev->movetype = MOVETYPE_NONE; - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world -// if ( CVAR_GET_FLOAT("showtriggers") == 0 ) - SetBits( pev->effects, EF_NODRAW ); -} - - -// -// Cache user-entity-field values until spawn is called. -// - -void CBaseTrigger :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "damage")) - { - pev->dmg = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "count")) - { - m_cTriggersLeft = (int) atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "damagetype")) - { - m_bitsDamageInflict = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -class CTriggerHurt : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT RadiationThink( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_hurt, CTriggerHurt ); - -class CTriggerEnvHurt : public CBaseTrigger -{ -public: - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_env_hurt, CTriggerEnvHurt ); - - -// -// trigger_monsterjump -// -class CTriggerMonsterJump : public CBaseTrigger -{ -public: - void Spawn( void ); - void Touch( CBaseEntity *pOther ); - void Think( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_monsterjump, CTriggerMonsterJump ); - - -void CTriggerMonsterJump :: Spawn ( void ) -{ - SetMovedir ( pev ); - - InitTrigger (); - - pev->nextthink = 0; - pev->speed = 200; - m_flHeight = 150; - - if ( !FStringNull ( pev->targetname ) ) - {// if targetted, spawn turned off - pev->solid = SOLID_NOT; - UTIL_SetOrigin( pev, pev->origin ); // Unlink from trigger list - SetUse( &CTriggerMonsterJump::ToggleUse ); - } -} - - -void CTriggerMonsterJump :: Think( void ) -{ - pev->solid = SOLID_NOT;// kill the trigger for now !!!UNDONE - UTIL_SetOrigin( pev, pev->origin ); // Unlink from trigger list - SetThink( NULL ); -} - -void CTriggerMonsterJump :: Touch( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - if ( !FBitSet ( pevOther->flags , FL_MONSTER ) ) - {// touched by a non-monster. - return; - } - - pevOther->origin.z += 1; - - if ( FBitSet ( pevOther->flags, FL_ONGROUND ) ) - {// clear the onground so physics don't bitch - pevOther->flags &= ~FL_ONGROUND; - } - - // toss the monster! - pevOther->velocity = pev->movedir * pev->speed; - pevOther->velocity.z += m_flHeight; - pev->nextthink = gpGlobals->time; -} - - -//===================================== -// -// trigger_cdaudio - starts/stops cd audio tracks -// -class CTriggerCDAudio : public CBaseTrigger -{ -public: - void Spawn( void ); - - virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void PlayTrack( void ); - void Touch ( CBaseEntity *pOther ); -}; - -LINK_ENTITY_TO_CLASS( trigger_cdaudio, CTriggerCDAudio ); - -// -// Changes tracks or stops CD when player touches -// -// !!!HACK - overloaded HEALTH to avoid adding new field -void CTriggerCDAudio :: Touch ( CBaseEntity *pOther ) -{ - if ( !pOther->IsPlayer() ) - {// only clients may trigger these events - return; - } - - PlayTrack(); -} - -void CTriggerCDAudio :: Spawn( void ) -{ - InitTrigger(); -} - -void CTriggerCDAudio::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - PlayTrack(); -} - -void PlayCDTrack( int iTrack ) -{ - edict_t *pClient; - - // manually find the single player. - pClient = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - - // Can't play if the client is not connected! - if ( !pClient ) - return; - - if ( iTrack < -1 || iTrack > 30 ) - { - ALERT ( at_console, "TriggerCDAudio - Track %d out of range\n" ); - return; - } - - if ( iTrack == -1 ) - { - CLIENT_COMMAND ( pClient, "cd stop\n"); - } - else - { - char string [ 64 ]; - - sprintf( string, "cd play %3d\n", iTrack ); - CLIENT_COMMAND ( pClient, string); - } -} - - -// only plays for ONE client, so only use in single play! -void CTriggerCDAudio :: PlayTrack( void ) -{ - //PlayCDTrack( (int)pev->health ); - - SetTouch( NULL ); - UTIL_Remove( this ); -} - - -// This plays a CD track when fired or when the player enters it's radius -class CTargetCDAudio : public CPointEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - - virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void Think( void ); - void Play( void ); -}; - -LINK_ENTITY_TO_CLASS( target_cdaudio, CTargetCDAudio ); - -void CTargetCDAudio :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "radius")) - { - pev->scale = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -void CTargetCDAudio :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - - if ( pev->scale > 0 ) - pev->nextthink = gpGlobals->time + 1.0; -} - -void CTargetCDAudio::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - Play(); -} - -// only plays for ONE client, so only use in single play! -void CTargetCDAudio::Think( void ) -{ - edict_t *pClient; - - // manually find the single player. - pClient = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - - // Can't play if the client is not connected! - if ( !pClient ) - return; - - pev->nextthink = gpGlobals->time + 0.5; - - if ( (pClient->v.origin - pev->origin).Length() <= pev->scale ) - Play(); - -} - -void CTargetCDAudio::Play( void ) -{ - //PlayCDTrack( (int)pev->health ); - UTIL_Remove(this); -} - -//===================================== - -/* -========================== -CTriggerEnvHurt -Used to represent Slime or Lava -========================== -*/ - -void CTriggerEnvHurt :: Spawn( void ) -{ - InitTrigger(); - SetTouch ( &CBaseTrigger::EnvTouch ); - - if ( FBitSet (pev->spawnflags, SF_TRIGGER_HURT_START_OFF) )// if flagged to Start Turned Off, make trigger nonsolid. - pev->solid = SOLID_NOT; - - UTIL_SetOrigin( pev, pev->origin ); // Link into the list -} - -// When touched, a hurt trigger does DMG points of damage each half-second -void CBaseTrigger :: EnvTouch ( CBaseEntity *pOther ) -{ - float fldmg; - - if ( !pOther->pev->takedamage ) - return; - - if ( (pev->spawnflags & SF_TRIGGER_HURT_CLIENTONLYTOUCH) && !pOther->IsPlayer() ) - { - // this trigger is only allowed to touch clients, and this ain't a client. - return; - } - - if ( (pev->spawnflags & SF_TRIGGER_HURT_NO_CLIENTS) && pOther->IsPlayer() ) - return; - - // HACKHACK -- In multiplayer, players touch this based on packet receipt. - // So the players who send packets later aren't always hurt. Keep track of - // how much time has passed and whether or not you've touched that player - if ( g_pGameRules->IsMultiplayer() ) - { - if ( pev->dmgtime > gpGlobals->time ) - { - if ( gpGlobals->time != pev->pain_finished ) - {// too early to hurt again, and not same frame with a different entity - if ( pOther->IsPlayer() ) - { - int playerMask = 1 << (pOther->entindex() - 1); - - // If I've already touched this player (this time), then bail out - if ( pev->impulse & playerMask ) - return; - - // Mark this player as touched - // BUGBUG - There can be only 32 players! - pev->impulse |= playerMask; - } - else - { - return; - } - } - } - else - { - // New clock, "un-touch" all players - pev->impulse = 0; - if ( pOther->IsPlayer() ) - { - int playerMask = 1 << (pOther->entindex() - 1); - - // Mark this player as touched - // BUGBUG - There can be only 32 players! - pev->impulse |= playerMask; - } - } - } - else // Original code -- single player - { - if ( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->pain_finished ) - {// too early to hurt again, and not same frame with a different entity - return; - } - } - - - //We are in slime - if ( m_bitsDamageInflict & DMG_ACID ) - { - pev->dmg = 4; //Default damage of 4 - fldmg = (float)( pev->dmg * pOther->pev->waterlevel ); // pev->damage plus our current waterlevel - - pev->dmgtime = gpGlobals->time + 1.0; //Next damage in 1 second - } - //We are in lava - else if ( m_bitsDamageInflict & DMG_BURN ) - { - pev->dmg = 10; //Default damage of 10 - fldmg = (float)( pev->dmg * pOther->pev->waterlevel ); // pev->damage plus our current waterlevel - - if ( pOther->IsPlayer() ) - { - if ( ( (CBasePlayer *)pOther )->m_iQuakeItems & IT_SUIT) // Wearing the suit slows down the next damage time - pev->dmgtime = gpGlobals->time + 1.0; - else - pev->dmgtime = gpGlobals->time + 0.2; - } - else - pev->dmgtime = gpGlobals->time + 0.2; - } - - if ( fldmg < 0 ) - pOther->TakeHealth( -fldmg, m_bitsDamageInflict ); - else - pOther->TakeDamage( pev, pev, fldmg, m_bitsDamageInflict ); - - // Store pain time so we can get all of the other entities on this frame - pev->pain_finished = gpGlobals->time; - - - if ( pev->target ) - { - // trigger has a target it wants to fire. - if ( pev->spawnflags & SF_TRIGGER_HURT_CLIENTONLYFIRE ) - { - // if the toucher isn't a client, don't fire the target! - if ( !pOther->IsPlayer() ) - { - return; - } - } - - SUB_UseTargets( pOther, USE_TOGGLE, 0 ); - if ( pev->spawnflags & SF_TRIGGER_HURT_TARGETONCE ) - pev->target = 0; - } -} - -// trigger_hurt - hurts anything that touches it. if the trigger has a targetname, firing it will toggle state -// -//int gfToggleState = 0; // used to determine when all radiation trigger hurts have called 'RadiationThink' -void CTriggerHurt :: Spawn( void ) -{ - InitTrigger(); - SetTouch ( &CTriggerHurt::HurtTouch ); - - if ( !FStringNull ( pev->targetname ) ) - { - SetUse ( &CTriggerHurt::ToggleUse ); - } - else - { - SetUse ( NULL ); - } - - if (m_bitsDamageInflict & DMG_RADIATION) - { - SetThink ( &CTriggerHurt::RadiationThink ); - pev->nextthink = gpGlobals->time + RANDOM_FLOAT(0.0, 0.5); - } - - if ( FBitSet (pev->spawnflags, SF_TRIGGER_HURT_START_OFF) )// if flagged to Start Turned Off, make trigger nonsolid. - pev->solid = SOLID_NOT; - - UTIL_SetOrigin( pev, pev->origin ); // Link into the list -} - -// trigger hurt that causes radiation will do a radius -// check and set the player's geiger counter level -// according to distance from center of trigger - -void CTriggerHurt :: RadiationThink( void ) -{ - - edict_t *pentPlayer; - CBasePlayer *pPlayer = NULL; - float flRange; - entvars_t *pevTarget; - Vector vecSpot1; - Vector vecSpot2; - Vector vecRange; - Vector origin; - Vector view_ofs; - - // check to see if a player is in pvs - // if not, continue - - // set origin to center of trigger so that this check works - origin = pev->origin; - view_ofs = pev->view_ofs; - - pev->origin = (pev->absmin + pev->absmax) * 0.5; - pev->view_ofs = pev->view_ofs * 0.0; - - pentPlayer = FIND_CLIENT_IN_PVS(edict()); - - pev->origin = origin; - pev->view_ofs = view_ofs; - - // reset origin - - if (!FNullEnt(pentPlayer)) - { - - pPlayer = GetClassPtr( (CBasePlayer *)VARS(pentPlayer)); - - pevTarget = VARS(pentPlayer); - - // get range to player; - - vecSpot1 = (pev->absmin + pev->absmax) * 0.5; - vecSpot2 = (pevTarget->absmin + pevTarget->absmax) * 0.5; - - vecRange = vecSpot1 - vecSpot2; - flRange = vecRange.Length(); - - // if player's current geiger counter range is larger - // than range to this trigger hurt, reset player's - // geiger counter range - - if (pPlayer->m_flgeigerRange >= flRange) - pPlayer->m_flgeigerRange = flRange; - } - - pev->nextthink = gpGlobals->time + 0.25; -} - -// -// ToggleUse - If this is the USE function for a trigger, its state will toggle every time it's fired -// -void CBaseTrigger :: ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if (pev->solid == SOLID_NOT) - {// if the trigger is off, turn it on - pev->solid = SOLID_TRIGGER; - - // Force retouch - gpGlobals->force_retouch++; - } - else - {// turn the trigger off - pev->solid = SOLID_NOT; - } - UTIL_SetOrigin( pev, pev->origin ); -} - -// When touched, a hurt trigger does DMG points of damage each half-second -void CBaseTrigger :: HurtTouch ( CBaseEntity *pOther ) -{ - float fldmg; - - if ( !pOther->pev->takedamage ) - return; - - if ( (pev->spawnflags & SF_TRIGGER_HURT_CLIENTONLYTOUCH) && !pOther->IsPlayer() ) - { - // this trigger is only allowed to touch clients, and this ain't a client. - return; - } - - if ( (pev->spawnflags & SF_TRIGGER_HURT_NO_CLIENTS) && pOther->IsPlayer() ) - return; - - // HACKHACK -- In multiplayer, players touch this based on packet receipt. - // So the players who send packets later aren't always hurt. Keep track of - // how much time has passed and whether or not you've touched that player - if ( g_pGameRules->IsMultiplayer() ) - { - if ( pev->dmgtime > gpGlobals->time ) - { - if ( gpGlobals->time != pev->pain_finished ) - {// too early to hurt again, and not same frame with a different entity - if ( pOther->IsPlayer() ) - { - int playerMask = 1 << (pOther->entindex() - 1); - - // If I've already touched this player (this time), then bail out - if ( pev->impulse & playerMask ) - return; - - // Mark this player as touched - // BUGBUG - There can be only 32 players! - pev->impulse |= playerMask; - } - else - { - return; - } - } - } - else - { - // New clock, "un-touch" all players - pev->impulse = 0; - if ( pOther->IsPlayer() ) - { - int playerMask = 1 << (pOther->entindex() - 1); - - // Mark this player as touched - // BUGBUG - There can be only 32 players! - pev->impulse |= playerMask; - } - } - } - else // Original code -- single player - { - if ( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->pain_finished ) - {// too early to hurt again, and not same frame with a different entity - return; - } - } - - - - // If this is time_based damage (poison, radiation), override the pev->dmg with a - // default for the given damage type. Monsters only take time-based damage - // while touching the trigger. Player continues taking damage for a while after - // leaving the trigger - - fldmg = pev->dmg * 0.5; // 0.5 seconds worth of damage, pev->dmg is damage/second - - - // JAY: Cut this because it wasn't fully realized. Damage is simpler now. -#if 0 - switch (m_bitsDamageInflict) - { - default: break; - case DMG_POISON: fldmg = POISON_DAMAGE/4; break; - case DMG_NERVEGAS: fldmg = NERVEGAS_DAMAGE/4; break; - case DMG_RADIATION: fldmg = RADIATION_DAMAGE/4; break; - case DMG_PARALYZE: fldmg = PARALYZE_DAMAGE/4; break; // UNDONE: cut this? should slow movement to 50% - case DMG_ACID: fldmg = ACID_DAMAGE/4; break; - case DMG_SLOWBURN: fldmg = SLOWBURN_DAMAGE/4; break; - case DMG_SLOWFREEZE: fldmg = SLOWFREEZE_DAMAGE/4; break; - } -#endif - - if ( fldmg < 0 ) - pOther->TakeHealth( -fldmg, m_bitsDamageInflict ); - else - pOther->TakeDamage( pev, pev, fldmg, m_bitsDamageInflict ); - - // Store pain time so we can get all of the other entities on this frame - pev->pain_finished = gpGlobals->time; - - // Apply damage every half second - pev->dmgtime = gpGlobals->time + 0.5;// half second delay until this trigger can hurt toucher again - - - - if ( pev->target ) - { - // trigger has a target it wants to fire. - if ( pev->spawnflags & SF_TRIGGER_HURT_CLIENTONLYFIRE ) - { - // if the toucher isn't a client, don't fire the target! - if ( !pOther->IsPlayer() ) - { - return; - } - } - - SUB_UseTargets( pOther, USE_TOGGLE, 0 ); - if ( pev->spawnflags & SF_TRIGGER_HURT_TARGETONCE ) - pev->target = 0; - } -} - - -/*QUAKED trigger_multiple (.5 .5 .5) ? notouch -Variable sized repeatable trigger. Must be targeted at one or more entities. -If "health" is set, the trigger must be killed to activate each time. -If "delay" is set, the trigger waits some time after activating before firing. -"wait" : Seconds between triggerings. (.2 default) -If notouch is set, the trigger is only fired by other entities, not by touching. -NOTOUCH has been obsoleted by trigger_relay! -sounds -1) secret -2) beep beep -3) large switch -4) -NEW -if a trigger has a NETNAME, that NETNAME will become the TARGET of the triggered object. -*/ -class CTriggerMultiple : public CBaseTrigger -{ -public: - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_multiple, CTriggerMultiple ); - - -void CTriggerMultiple :: Spawn( void ) -{ - if (m_flWait == 0) - m_flWait = 0.2; - - InitTrigger(); - - ASSERTSZ(pev->health == 0, "trigger_multiple with health"); -// UTIL_SetOrigin(pev, pev->origin); -// SET_MODEL( ENT(pev), STRING(pev->model) ); -// if (pev->health > 0) -// { -// if (FBitSet(pev->spawnflags, SPAWNFLAG_NOTOUCH)) -// ALERT(at_error, "trigger_multiple spawn: health and notouch don't make sense"); -// pev->max_health = pev->health; -//UNDONE: where to get pfnDie from? -// pev->pfnDie = multi_killed; -// pev->takedamage = DAMAGE_YES; -// pev->solid = SOLID_BBOX; -// UTIL_SetOrigin(pev, pev->origin); // make sure it links into the world -// } -// else - { - SetTouch( &CTriggerMultiple::MultiTouch ); - } - } - - -/*QUAKED trigger_once (.5 .5 .5) ? notouch -Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching -"targetname". If "health" is set, the trigger must be killed to activate. -If notouch is set, the trigger is only fired by other entities, not by touching. -if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired. -if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0. -sounds -1) secret -2) beep beep -3) large switch -4) -*/ -class CTriggerOnce : public CTriggerMultiple -{ -public: - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_once, CTriggerOnce ); -void CTriggerOnce::Spawn( void ) -{ - m_flWait = -1; - - CTriggerMultiple :: Spawn(); -} - - - -void CBaseTrigger :: MultiTouch( CBaseEntity *pOther ) -{ - entvars_t *pevToucher; - - pevToucher = pOther->pev; - - // Only touch clients, monsters, or pushables (depending on flags) - if ( ((pevToucher->flags & FL_CLIENT) && !(pev->spawnflags & SF_TRIGGER_NOCLIENTS)) || - ((pevToucher->flags & FL_MONSTER) && (pev->spawnflags & SF_TRIGGER_ALLOWMONSTERS)) || - (pev->spawnflags & SF_TRIGGER_PUSHABLES) && FClassnameIs(pevToucher,"func_pushable") ) - { - -#if 0 - // if the trigger has an angles field, check player's facing direction - if (pev->movedir != g_vecZero) - { - UTIL_MakeVectors( pevToucher->angles ); - if ( DotProduct( gpGlobals->v_forward, pev->movedir ) < 0 ) - return; // not facing the right way - } -#endif - - ActivateMultiTrigger( pOther ); - } -} - - -// -// the trigger was just touched/killed/used -// self.enemy should be set to the activator so it can be held through a delay -// so wait for the delay time before firing -// -void CBaseTrigger :: ActivateMultiTrigger( CBaseEntity *pActivator ) -{ - if (pev->nextthink > gpGlobals->time) - return; // still waiting for reset time - - if (!UTIL_IsMasterTriggered(m_sMaster,pActivator)) - return; - - if (FClassnameIs(pev, "trigger_secret")) - { - if ( pev->enemy == NULL || !FClassnameIs(pev->enemy, "player")) - return; - gpGlobals->found_secrets++; - } - - if (!FStringNull(pev->noise)) - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - -// don't trigger again until reset -// pev->takedamage = DAMAGE_NO; - - m_hActivator = pActivator; - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); - - if ( pev->message && pActivator->IsPlayer() ) - { - UTIL_ShowMessage( STRING(pev->message), pActivator ); -// CLIENT_PRINTF( ENT( pActivator->pev ), print_center, STRING(pev->message) ); - } - - if (m_flWait > 0) - { - SetThink( &CBaseTrigger::MultiWaitOver ); - pev->nextthink = gpGlobals->time + m_flWait; - } - else - { - // we can't just remove (self) here, because this is a touch function - // called while C code is looping through area links... - SetTouch( NULL ); - pev->nextthink = gpGlobals->time + 0.1; - SetThink( &CBaseTrigger::SUB_Remove ); - } -} - - -// the wait time has passed, so set back up for another activation -void CBaseTrigger :: MultiWaitOver( void ) -{ -// if (pev->max_health) -// { -// pev->health = pev->max_health; -// pev->takedamage = DAMAGE_YES; -// pev->solid = SOLID_BBOX; -// } - SetThink( NULL ); -} - - -// ========================= COUNTING TRIGGER ===================================== - -// -// GLOBALS ASSUMED SET: g_eoActivator -// -void CBaseTrigger::CounterUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - m_cTriggersLeft--; - m_hActivator = pActivator; - - if (m_cTriggersLeft < 0) - return; - - BOOL fTellActivator = - (m_hActivator != 0) && - FClassnameIs(m_hActivator->pev, "player") && - !FBitSet(pev->spawnflags, SPAWNFLAG_NOMESSAGE); - if (m_cTriggersLeft != 0) - { - if (fTellActivator) - { - // UNDONE: I don't think we want these Quakesque messages - switch (m_cTriggersLeft) - { - case 1: ALERT(at_console, "Only 1 more to go..."); break; - case 2: ALERT(at_console, "Only 2 more to go..."); break; - case 3: ALERT(at_console, "Only 3 more to go..."); break; - default: ALERT(at_console, "There are more to go..."); break; - } - } - return; - } - - // !!!UNDONE: I don't think we want these Quakesque messages - if (fTellActivator) - ALERT(at_console, "Sequence completed!"); - - ActivateMultiTrigger( m_hActivator ); -} - - -/*QUAKED trigger_counter (.5 .5 .5) ? nomessage -Acts as an intermediary for an action that takes multiple inputs. -If nomessage is not set, it will print "1 more.. " etc when triggered and -"sequence complete" when finished. After the counter has been triggered "cTriggersLeft" -times (default 2), it will fire all of it's targets and remove itself. -*/ -class CTriggerCounter : public CBaseTrigger -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS( trigger_counter, CTriggerCounter ); - -void CTriggerCounter :: Spawn( void ) -{ - // By making the flWait be -1, this counter-trigger will disappear after it's activated - // (but of course it needs cTriggersLeft "uses" before that happens). - m_flWait = -1; - - if (m_cTriggersLeft == 0) - m_cTriggersLeft = 2; - SetUse( &CTriggerCounter::CounterUse ); -} - -// ====================== TRIGGER_CHANGELEVEL ================================ - -class CTriggerVolume : public CPointEntity // Derive from point entity so this doesn't move across levels -{ -public: - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_transition, CTriggerVolume ); - -// Define space that travels across a level transition -void CTriggerVolume :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world - pev->model = NULL; - pev->modelindex = 0; -} - - -// Fires a target after level transition and then dies -class CFireAndDie : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - void Think( void ); - int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() | FCAP_FORCE_TRANSITION; } // Always go across transitions -}; -LINK_ENTITY_TO_CLASS( fireanddie, CFireAndDie ); - -void CFireAndDie::Spawn( void ) -{ - pev->classname = MAKE_STRING("fireanddie"); - // Don't call Precache() - it should be called on restore -} - - -void CFireAndDie::Precache( void ) -{ - // This gets called on restore - pev->nextthink = gpGlobals->time + m_flDelay; -} - - -void CFireAndDie::Think( void ) -{ - SUB_UseTargets( this, USE_TOGGLE, 0 ); - UTIL_Remove( this ); -} - - -#define SF_CHANGELEVEL_USEONLY 0x0002 -class CChangeLevel : public CBaseTrigger -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT UseChangeLevel ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT TriggerChangeLevel( void ); - void EXPORT ExecuteChangeLevel( void ); - void EXPORT TouchChangeLevel( CBaseEntity *pOther ); - void ChangeLevelNow( CBaseEntity *pActivator ); - - static edict_t *FindLandmark( const char *pLandmarkName ); - static int ChangeList( LEVELLIST *pLevelList, int maxList ); - static int AddTransitionToList( LEVELLIST *pLevelList, int listCount, const char *pMapName, const char *pLandmarkName, edict_t *pentLandmark ); - static int InTransitionVolume( CBaseEntity *pEntity, char *pVolumeName ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - char m_szMapName[cchMapNameMost]; // trigger_changelevel only: next map - char m_szLandmarkName[cchMapNameMost]; // trigger_changelevel only: landmark on next map - int m_changeTarget; - float m_changeTargetDelay; -}; -LINK_ENTITY_TO_CLASS( trigger_changelevel, CChangeLevel ); - -// Global Savedata for changelevel trigger -TYPEDESCRIPTION CChangeLevel::m_SaveData[] = -{ - DEFINE_ARRAY( CChangeLevel, m_szMapName, FIELD_CHARACTER, cchMapNameMost ), - DEFINE_ARRAY( CChangeLevel, m_szLandmarkName, FIELD_CHARACTER, cchMapNameMost ), - DEFINE_FIELD( CChangeLevel, m_changeTarget, FIELD_STRING ), - DEFINE_FIELD( CChangeLevel, m_changeTargetDelay, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE(CChangeLevel,CBaseTrigger); - -// -// Cache user-entity-field values until spawn is called. -// - -void CChangeLevel :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "map")) - { - if (strlen(pkvd->szValue) >= cchMapNameMost) - ALERT( at_error, "Map name '%s' too long (32 chars)\n", pkvd->szValue ); - strcpy(m_szMapName, pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "landmark")) - { - if (strlen(pkvd->szValue) >= cchMapNameMost) - ALERT( at_error, "Landmark name '%s' too long (32 chars)\n", pkvd->szValue ); - strcpy(m_szLandmarkName, pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "changetarget")) - { - m_changeTarget = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "changedelay")) - { - m_changeTargetDelay = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseTrigger::KeyValue( pkvd ); -} - - -/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION -When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats. -*/ - -void CChangeLevel :: Spawn( void ) -{ - if ( FStrEq( m_szMapName, "" ) ) - ALERT( at_console, "a trigger_changelevel doesn't have a map" ); - - if ( FStrEq( m_szLandmarkName, "" ) ) - ALERT( at_console, "trigger_changelevel to %s doesn't have a landmark", m_szMapName ); - - if (!FStringNull ( pev->targetname ) ) - { - SetUse ( &CChangeLevel::UseChangeLevel ); - } - InitTrigger(); - if ( !(pev->spawnflags & SF_CHANGELEVEL_USEONLY) ) - SetTouch( &CChangeLevel::TouchChangeLevel ); -// ALERT( at_console, "TRANSITION: %s (%s)\n", m_szMapName, m_szLandmarkName ); -} - - -void CChangeLevel :: ExecuteChangeLevel( void ) -{ - MESSAGE_BEGIN( MSG_ALL, SVC_CDTRACK ); - WRITE_BYTE( 3 ); - WRITE_BYTE( 3 ); - MESSAGE_END(); - - MESSAGE_BEGIN(MSG_ALL, SVC_INTERMISSION); - MESSAGE_END(); -} - - -FILE_GLOBAL char st_szNextMap[cchMapNameMost]; -FILE_GLOBAL char st_szNextSpot[cchMapNameMost]; - -edict_t *CChangeLevel :: FindLandmark( const char *pLandmarkName ) -{ - edict_t *pentLandmark; - - pentLandmark = FIND_ENTITY_BY_STRING( NULL, "targetname", pLandmarkName ); - while ( !FNullEnt( pentLandmark ) ) - { - // Found the landmark - if ( FClassnameIs( pentLandmark, "info_landmark" ) ) - return pentLandmark; - else - pentLandmark = FIND_ENTITY_BY_STRING( pentLandmark, "targetname", pLandmarkName ); - } - ALERT( at_error, "Can't find landmark %s\n", pLandmarkName ); - return NULL; -} - - -//========================================================= -// CChangeLevel :: Use - allows level transitions to be -// triggered by buttons, etc. -// -//========================================================= -void CChangeLevel :: UseChangeLevel ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - ChangeLevelNow( pActivator ); -} - -void CChangeLevel :: ChangeLevelNow( CBaseEntity *pActivator ) -{ - edict_t *pentLandmark; - LEVELLIST levels[16]; - - ASSERT(!FStrEq(m_szMapName, "")); - - // Don't work in deathmatch - if ( g_pGameRules->IsDeathmatch() ) - return; - - // Some people are firing these multiple times in a frame, disable - if ( gpGlobals->time == pev->dmgtime ) - return; - - pev->dmgtime = gpGlobals->time; - - - CBaseEntity *pPlayer = CBaseEntity::Instance( g_engfuncs.pfnPEntityOfEntIndex( 1 ) ); - if ( !InTransitionVolume( pPlayer, m_szLandmarkName ) ) - { - ALERT( at_aiconsole, "Player isn't in the transition volume %s, aborting\n", m_szLandmarkName ); - return; - } - - // Create an entity to fire the changetarget - if ( m_changeTarget ) - { - CFireAndDie *pFireAndDie = GetClassPtr( (CFireAndDie *)NULL ); - if ( pFireAndDie ) - { - // Set target and delay - pFireAndDie->pev->target = m_changeTarget; - pFireAndDie->m_flDelay = m_changeTargetDelay; - pFireAndDie->pev->origin = pPlayer->pev->origin; - // Call spawn - DispatchSpawn( pFireAndDie->edict() ); - } - } - // This object will get removed in the call to CHANGE_LEVEL, copy the params into "safe" memory - strcpy(st_szNextMap, m_szMapName); - - m_hActivator = pActivator; - SUB_UseTargets( pActivator, USE_TOGGLE, 0 ); - st_szNextSpot[0] = 0; // Init landmark to NULL - - // look for a landmark entity - pentLandmark = FindLandmark( m_szLandmarkName ); - if ( !FNullEnt( pentLandmark ) ) - { - strcpy(st_szNextSpot, m_szLandmarkName); - gpGlobals->vecLandmarkOffset = VARS(pentLandmark)->origin; - } -// ALERT( at_console, "Level touches %d levels\n", ChangeList( levels, 16 ) ); - ALERT( at_console, "CHANGE LEVEL: %s %s\n", st_szNextMap, st_szNextSpot ); - CHANGE_LEVEL( st_szNextMap, st_szNextSpot ); -} - -// -// GLOBALS ASSUMED SET: st_szNextMap -// -void CChangeLevel :: TouchChangeLevel( CBaseEntity *pOther ) -{ - if (!FClassnameIs(pOther->pev, "player")) - return; - - ChangeLevelNow( pOther ); -} - - -// Add a transition to the list, but ignore duplicates -// (a designer may have placed multiple trigger_changelevels with the same landmark) -int CChangeLevel::AddTransitionToList( LEVELLIST *pLevelList, int listCount, const char *pMapName, const char *pLandmarkName, edict_t *pentLandmark ) -{ - int i; - - if ( !pLevelList || !pMapName || !pLandmarkName || !pentLandmark ) - return 0; - - for ( i = 0; i < listCount; i++ ) - { - if ( pLevelList[i].pentLandmark == pentLandmark && strcmp( pLevelList[i].mapName, pMapName ) == 0 ) - return 0; - } - strcpy( pLevelList[listCount].mapName, pMapName ); - strcpy( pLevelList[listCount].landmarkName, pLandmarkName ); - pLevelList[listCount].pentLandmark = pentLandmark; - pLevelList[listCount].vecLandmarkOrigin = VARS(pentLandmark)->origin; - - return 1; -} - -int BuildChangeList( LEVELLIST *pLevelList, int maxList ) -{ - return CChangeLevel::ChangeList( pLevelList, maxList ); -} - - -int CChangeLevel::InTransitionVolume( CBaseEntity *pEntity, char *pVolumeName ) -{ - edict_t *pentVolume; - - - if ( pEntity->ObjectCaps() & FCAP_FORCE_TRANSITION ) - return 1; - - // If you're following another entity, follow it through the transition (weapons follow the player) - if ( pEntity->pev->movetype == MOVETYPE_FOLLOW ) - { - if ( pEntity->pev->aiment != NULL ) - pEntity = CBaseEntity::Instance( pEntity->pev->aiment ); - } - - int inVolume = 1; // Unless we find a trigger_transition, everything is in the volume - - pentVolume = FIND_ENTITY_BY_TARGETNAME( NULL, pVolumeName ); - while ( !FNullEnt( pentVolume ) ) - { - CBaseEntity *pVolume = CBaseEntity::Instance( pentVolume ); - - if ( pVolume && FClassnameIs( pVolume->pev, "trigger_transition" ) ) - { - if ( pVolume->Intersects( pEntity ) ) // It touches one, it's in the volume - return 1; - else - inVolume = 0; // Found a trigger_transition, but I don't intersect it -- if I don't find another, don't go! - } - pentVolume = FIND_ENTITY_BY_TARGETNAME( pentVolume, pVolumeName ); - } - - return inVolume; -} - - -// We can only ever move 512 entities across a transition -#define MAX_ENTITY 512 - -// This has grown into a complicated beast -// Can we make this more elegant? -// This builds the list of all transitions on this level and which entities are in their PVS's and can / should -// be moved across. -int CChangeLevel::ChangeList( LEVELLIST *pLevelList, int maxList ) -{ - edict_t *pentChangelevel, *pentLandmark; - int i, count; - - count = 0; - - // Find all of the possible level changes on this BSP - pentChangelevel = FIND_ENTITY_BY_STRING( NULL, "classname", "trigger_changelevel" ); - if ( FNullEnt( pentChangelevel ) ) - return 0; - while ( !FNullEnt( pentChangelevel ) ) - { - CChangeLevel *pTrigger; - - pTrigger = GetClassPtr((CChangeLevel *)VARS(pentChangelevel)); - if ( pTrigger ) - { - // Find the corresponding landmark - pentLandmark = FindLandmark( pTrigger->m_szLandmarkName ); - if ( pentLandmark ) - { - // Build a list of unique transitions - if ( AddTransitionToList( pLevelList, count, pTrigger->m_szMapName, pTrigger->m_szLandmarkName, pentLandmark ) ) - { - count++; - if ( count >= maxList ) // FULL!! - break; - } - } - } - pentChangelevel = FIND_ENTITY_BY_STRING( pentChangelevel, "classname", "trigger_changelevel" ); - } - - if ( gpGlobals->pSaveData && ((SAVERESTOREDATA *)gpGlobals->pSaveData)->pTable ) - { - CSave saveHelper( (SAVERESTOREDATA *)gpGlobals->pSaveData ); - - for ( i = 0; i < count; i++ ) - { - int j, entityCount = 0; - CBaseEntity *pEntList[ MAX_ENTITY ]; - int entityFlags[ MAX_ENTITY ]; - - // Follow the linked list of entities in the PVS of the transition landmark - edict_t *pent = UTIL_EntitiesInPVS( pLevelList[i].pentLandmark ); - - // Build a list of valid entities in this linked list (we're going to use pent->v.chain again) - while ( !FNullEnt( pent ) ) - { - CBaseEntity *pEntity = CBaseEntity::Instance(pent); - if ( pEntity ) - { -// ALERT( at_console, "Trying %s\n", STRING(pEntity->pev->classname) ); - int caps = pEntity->ObjectCaps(); - if ( !(caps & FCAP_DONT_SAVE) ) - { - int flags = 0; - - // If this entity can be moved or is global, mark it - if ( caps & FCAP_ACROSS_TRANSITION ) - flags |= FENTTABLE_MOVEABLE; - if ( pEntity->pev->globalname && !pEntity->IsDormant() ) - flags |= FENTTABLE_GLOBAL; - if ( flags ) - { - pEntList[ entityCount ] = pEntity; - entityFlags[ entityCount ] = flags; - entityCount++; - if ( entityCount > MAX_ENTITY ) - ALERT( at_error, "Too many entities across a transition!" ); - } -// else -// ALERT( at_console, "Failed %s\n", STRING(pEntity->pev->classname) ); - } -// else -// ALERT( at_console, "DON'T SAVE %s\n", STRING(pEntity->pev->classname) ); - } - pent = pent->v.chain; - } - - for ( j = 0; j < entityCount; j++ ) - { - // Check to make sure the entity isn't screened out by a trigger_transition - if ( entityFlags[j] && InTransitionVolume( pEntList[j], pLevelList[i].landmarkName ) ) - { - // Mark entity table with 1<pev->classname) ); - - } - } - } - - return count; -} - -/* -go to the next level for deathmatch -only called if a time or frag limit has expired -*/ -void NextLevel( void ) -{ - edict_t* pent; - CChangeLevel *pChange; - - // find a trigger_changelevel - pent = FIND_ENTITY_BY_CLASSNAME(NULL, "trigger_changelevel"); - - // go back to start if no trigger_changelevel - if (FNullEnt(pent)) - { - gpGlobals->mapname = ALLOC_STRING("start"); - pChange = GetClassPtr( (CChangeLevel *)NULL ); - strcpy(pChange->m_szMapName, "start"); - } - else - pChange = GetClassPtr( (CChangeLevel *)VARS(pent)); - - strcpy(st_szNextMap, pChange->m_szMapName); - g_fGameOver = TRUE; - - if (pChange->pev->nextthink < gpGlobals->time) - { - pChange->SetThink( &CChangeLevel::ExecuteChangeLevel ); - pChange->pev->nextthink = gpGlobals->time + 0.1; - } -} - - -// ============================== LADDER ======================================= - -class CLadder : public CBaseTrigger -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS( func_ladder, CLadder ); - - -void CLadder :: KeyValue( KeyValueData *pkvd ) -{ - CBaseTrigger::KeyValue( pkvd ); -} - - -//========================================================= -// func_ladder - makes an area vertically negotiable -//========================================================= -void CLadder :: Precache( void ) -{ - // Do all of this in here because we need to 'convert' old saved games - pev->solid = SOLID_NOT; - pev->skin = CONTENTS_LADDER; - if ( CVAR_GET_FLOAT("showtriggers") == 0 ) - { - pev->rendermode = kRenderTransTexture; - pev->renderamt = 0; - } - pev->effects &= ~EF_NODRAW; -} - - -void CLadder :: Spawn( void ) -{ - Precache(); - - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world - pev->movetype = MOVETYPE_PUSH; -} - - -// ========================== A TRIGGER THAT PUSHES YOU =============================== - -class CTriggerPush : public CBaseTrigger -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void Touch( CBaseEntity *pOther ); -}; -LINK_ENTITY_TO_CLASS( trigger_push, CTriggerPush ); - - -void CTriggerPush :: KeyValue( KeyValueData *pkvd ) -{ - CBaseTrigger::KeyValue( pkvd ); -} - - -/*QUAKED trigger_push (.5 .5 .5) ? TRIG_PUSH_ONCE -Pushes the player -*/ - -void CTriggerPush :: Spawn( ) -{ - if ( pev->angles == g_vecZero ) - pev->angles.y = 360; - InitTrigger(); - - if (pev->speed == 0) - pev->speed = 100; - - if ( FBitSet (pev->spawnflags, SF_TRIGGER_PUSH_START_OFF) )// if flagged to Start Turned Off, make trigger nonsolid. - pev->solid = SOLID_NOT; - - SetUse( &CTriggerPush::ToggleUse ); - - UTIL_SetOrigin( pev, pev->origin ); // Link into the list -} - - -void CTriggerPush :: Touch( CBaseEntity *pOther ) -{ - entvars_t* pevToucher = pOther->pev; - - // UNDONE: Is there a better way than health to detect things that have physics? (clients/monsters) - switch( pevToucher->movetype ) - { - case MOVETYPE_NONE: - case MOVETYPE_PUSH: - case MOVETYPE_NOCLIP: - case MOVETYPE_FOLLOW: - return; - } - - //Only players - if ( !pOther->IsPlayer() ) - return; - - if ( pevToucher->solid != SOLID_NOT && pevToucher->solid != SOLID_BSP ) - { - // Instant trigger, just transfer velocity and remove - if (FBitSet(pev->spawnflags, SF_TRIG_PUSH_ONCE)) - { - pevToucher->velocity = pevToucher->velocity + (pev->speed * pev->movedir); - if ( pevToucher->velocity.z > 0 ) - pevToucher->flags &= ~FL_ONGROUND; - UTIL_Remove( this ); - } - else - { // Push field, transfer to base velocity - Vector vecPush = (pev->speed * pev->movedir); - if ( pevToucher->flags & FL_BASEVELOCITY ) - vecPush = vecPush + pevToucher->basevelocity; - - pevToucher->basevelocity = vecPush; - - pevToucher->flags |= FL_BASEVELOCITY; -// ALERT( at_console, "Vel %f, base %f\n", pevToucher->velocity.z, pevToucher->basevelocity.z ); - } - } -} - -//======================================================================================== -// TELEPORT TRIGGERS -//======================================================================================== - -//----------------------------------------------------------------------------- -// Purpose: Teleport Death entity. Kills anything it touches -//----------------------------------------------------------------------------- -class CTeleDeath : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT DeathTouch( CBaseEntity *pOther ); -}; -LINK_ENTITY_TO_CLASS( teledeath, CTeleDeath ); - -void CTeleDeath::Spawn( void ) -{ - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_TRIGGER; - pev->angles = g_vecZero; - - // Owner is the player who's spawned this - CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner); - if (!pOwner) - return; - - UTIL_SetSize( pev, pOwner->pev->mins - Vector(1,1,1), pOwner->pev->maxs + Vector(1,1,1) ); - UTIL_SetOrigin( pev, pev->origin ); - - SetTouch( &CTeleDeath::DeathTouch ); - pev->nextthink = gpGlobals->time + 0.2; - SetThink( &CTeleDeath::SUB_Remove ); - - // Touch still players - gpGlobals->force_retouch = 2; -} - -void CTeleDeath::DeathTouch( CBaseEntity *pOther ) -{ - CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner); - - if ( pOther == pOwner ) - return; - - // frag anyone who teleports in on top of an invincible player - if ( pOther->IsPlayer() ) - { - if ( ((CBasePlayer*)pOther)->m_flInvincibleFinished > gpGlobals->time ) - { - // Note: This did not work in Quake. Fixed in QUAKECLASSIC. - if ( pOwner->IsPlayer() ) - { - g_szDeathType = "teledeath2"; - pOwner->TakeDamage( pOwner->pev, pOwner->pev, 1000, DMG_GENERIC | DMG_ALWAYSGIB); - return; - } - } - } - - if ( pOther->pev->health ) - { - g_szDeathType = "teledeath"; - pOther->TakeDamage( pOther->pev, pOwner->pev, 1000, DMG_GENERIC | DMG_ALWAYSGIB); - } -} - -//====================================== -// teleport trigger -// -// QUAKECLASSIC: Different bitflags -#define TELE_PLAYER_ONLY 1 -#define TELE_SILENT 2 - -//----------------------------------------------------------------------------- -// Purpose: Spawn a teleport fog at the vector specified -//----------------------------------------------------------------------------- -void CBaseEntity::Spawn_Telefog( Vector vecOrg, CBaseEntity *pOther ) -{ - //Moved to the client - PLAYBACK_EVENT_FULL ( FEV_GLOBAL | FEV_NOTHOST, pOther->edict(), g_sTeleport, 0.0, (float *)&vecOrg, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0); -} - -//----------------------------------------------------------------------------- -// Purpose: Kill anything at the teleport destination -//----------------------------------------------------------------------------- -void CBaseTrigger :: TeleportTouch( CBaseEntity *pOther ) -{ - // no clients allowed? - if ( ( pev->spawnflags & TELE_PLAYER_ONLY ) ) - { - if ( pOther->IsPlayer() ) - return; - } - - // only teleport living creatures - if (pOther->pev->health <= 0 || pOther->pev->solid != SOLID_SLIDEBOX) - return; - - SUB_UseTargets( this, USE_TOGGLE, 0 ); - - // put a tfog where the player was - Spawn_Telefog(pOther->pev->origin, pOther ); - - edict_t *pentTarget = NULL; - pentTarget = FIND_ENTITY_BY_TARGETNAME( pentTarget, STRING(pev->target) ); - if (FNullEnt(pentTarget)) - return; - - // spawn a tfog flash in front of the destination - CBaseEntity *pTarget = CBaseEntity::Instance( pentTarget ); - UTIL_MakeVectors(pTarget->m_vecTeleAngles); - Vector vecNewOrg = pTarget->pev->origin + (gpGlobals->v_forward * 32); - pTarget->Spawn_Telefog( vecNewOrg, pOther ); - - // Spawn teledeath at destination - CTeleDeath *pDeath = GetClassPtr( (CTeleDeath *)NULL ); - pDeath->pev->owner = pOther->edict(); - pDeath->pev->origin = pTarget->pev->origin; - pDeath->Spawn(); - - // May be killed by teleporting onto an invulnerable player - if (!pOther->pev->health) - { - pOther->pev->origin = pTarget->pev->origin; - pOther->pev->velocity = (gpGlobals->v_forward * pOther->pev->velocity.x) + (gpGlobals->v_forward * pOther->pev->velocity.y); - return; - } - - // Move the player - UTIL_SetOrigin( pOther->pev, pTarget->pev->origin ); - pOther->pev->angles = pTarget->m_vecTeleAngles; - - if (pOther->IsPlayer()) - { - // pOther->pev->fixangle = 1; // turn this way immediately - - //Err, why is this here? - pOther->pev->fuser4 = gpGlobals->time + 0.7; - pOther->pev->velocity = gpGlobals->v_forward * 300; - } - pOther->pev->flags &= ~FL_ONGROUND; -} - - -class CTriggerTeleport : public CBaseTrigger -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS( trigger_teleport, CTriggerTeleport ); - -void CTriggerTeleport :: Spawn( void ) -{ - InitTrigger(); - - SetTouch( &CTriggerTeleport::TeleportTouch ); - - g_vecTeleMins[ g_iTeleNum ] = pev->absmin; - g_vecTeleMaxs[ g_iTeleNum ] = pev->absmax; - - g_iTeleNum++; - - if (!(pev->spawnflags & TELE_SILENT)) - { - PRECACHE_SOUND("ambience/hum1.wav"); - UTIL_EmitAmbientSound(ENT(pev), (pev->mins + pev->maxs) * 0.5, "ambience/hum1.wav", 0.5, ATTN_STATIC, 0, 100); - } -} - - -class CTriggerTeleportDest : public CBaseTrigger -{ -public: - void Spawn( void ); -}; - -void CTriggerTeleportDest :: Spawn( void ) -{ - m_vecTeleAngles = pev->angles; - pev->angles = g_vecZero; - pev->origin.z += 27; - UTIL_SetOrigin( pev, pev->origin ); -} - -LINK_ENTITY_TO_CLASS( info_teleport_destination, CTriggerTeleportDest ); - -//========================================================================== -class CTriggerSave : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT SaveTouch( CBaseEntity *pOther ); -}; -LINK_ENTITY_TO_CLASS( trigger_autosave, CTriggerSave ); - -void CTriggerSave::Spawn( void ) -{ - if ( g_pGameRules->IsDeathmatch() ) - { - REMOVE_ENTITY( ENT(pev) ); - return; - } - - InitTrigger(); - SetTouch( &CTriggerSave::SaveTouch ); -} - -void CTriggerSave::SaveTouch( CBaseEntity *pOther ) -{ - if ( !UTIL_IsMasterTriggered( m_sMaster, pOther ) ) - return; - - // Only save on clients - if ( !pOther->IsPlayer() ) - return; - - SetTouch( NULL ); - UTIL_Remove( this ); - SERVER_COMMAND( "autosave\n" ); -} - -#define SF_ENDSECTION_USEONLY 0x0001 - -class CTriggerEndSection : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT EndSectionTouch( CBaseEntity *pOther ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT EndSectionUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); -}; -LINK_ENTITY_TO_CLASS( trigger_endsection, CTriggerEndSection ); - - -void CTriggerEndSection::EndSectionUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // Only save on clients - if ( !pActivator->IsNetClient() ) - return; - - SetUse( NULL ); - - if ( pev->message ) - { - g_engfuncs.pfnEndSection(STRING(pev->message)); - } - UTIL_Remove( this ); -} - -void CTriggerEndSection::Spawn( void ) -{ - if ( g_pGameRules->IsDeathmatch() ) - { - REMOVE_ENTITY( ENT(pev) ); - return; - } - - InitTrigger(); - - SetUse ( &CTriggerEndSection::EndSectionUse ); - // If it is a "use only" trigger, then don't set the touch function. - if ( ! (pev->spawnflags & SF_ENDSECTION_USEONLY) ) - SetTouch( &CTriggerEndSection::EndSectionTouch ); -} - -void CTriggerEndSection::EndSectionTouch( CBaseEntity *pOther ) -{ - // Only save on clients - if ( !pOther->IsNetClient() ) - return; - - SetTouch( NULL ); - - if (pev->message) - { - g_engfuncs.pfnEndSection(STRING(pev->message)); - } - UTIL_Remove( this ); -} - -void CTriggerEndSection :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "section")) - { -// m_iszSectionName = ALLOC_STRING( pkvd->szValue ); - // Store this in message so we don't have to write save/restore for this ent - pev->message = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseTrigger::KeyValue( pkvd ); -} - - -class CTriggerGravity : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT GravityTouch( CBaseEntity *pOther ); -}; -LINK_ENTITY_TO_CLASS( trigger_gravity, CTriggerGravity ); - -void CTriggerGravity::Spawn( void ) -{ - InitTrigger(); - SetTouch( &CTriggerGravity::GravityTouch ); -} - -void CTriggerGravity::GravityTouch( CBaseEntity *pOther ) -{ - // Only save on clients - if ( !pOther->IsPlayer() ) - return; - - pOther->pev->gravity = pev->gravity; -} - - - - - - - -// this is a really bad idea. -class CTriggerChangeTarget : public CBaseDelay -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - int m_iszNewTarget; -}; -LINK_ENTITY_TO_CLASS( trigger_changetarget, CTriggerChangeTarget ); - -TYPEDESCRIPTION CTriggerChangeTarget::m_SaveData[] = -{ - DEFINE_FIELD( CTriggerChangeTarget, m_iszNewTarget, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE(CTriggerChangeTarget,CBaseDelay); - -void CTriggerChangeTarget::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "m_iszNewTarget")) - { - m_iszNewTarget = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - -void CTriggerChangeTarget::Spawn( void ) -{ -} - - -void CTriggerChangeTarget::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - CBaseEntity *pTarget = UTIL_FindEntityByString( NULL, "targetname", STRING( pev->target ) ); - - if (pTarget) - { - pTarget->pev->target = m_iszNewTarget; - CBaseMonster *pMonster = pTarget->MyMonsterPointer( ); - if (pMonster) - { - pMonster->m_pGoalEnt = NULL; - } - } -} - - - - -#define SF_CAMERA_PLAYER_POSITION 1 -#define SF_CAMERA_PLAYER_TARGET 2 -#define SF_CAMERA_PLAYER_TAKECONTROL 4 - -class CTriggerCamera : public CBaseDelay -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT FollowTarget( void ); - void Move(void); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - static TYPEDESCRIPTION m_SaveData[]; - - EHANDLE m_hPlayer; - EHANDLE m_hTarget; - CBaseEntity *m_pentPath; - int m_sPath; - float m_flWait; - float m_flReturnTime; - float m_flStopTime; - float m_moveDistance; - float m_targetSpeed; - float m_initialSpeed; - float m_acceleration; - float m_deceleration; - int m_state; - -}; -LINK_ENTITY_TO_CLASS( trigger_camera, CTriggerCamera ); - -// Global Savedata for changelevel friction modifier -TYPEDESCRIPTION CTriggerCamera::m_SaveData[] = -{ - DEFINE_FIELD( CTriggerCamera, m_hPlayer, FIELD_EHANDLE ), - DEFINE_FIELD( CTriggerCamera, m_hTarget, FIELD_EHANDLE ), - DEFINE_FIELD( CTriggerCamera, m_pentPath, FIELD_CLASSPTR ), - DEFINE_FIELD( CTriggerCamera, m_sPath, FIELD_STRING ), - DEFINE_FIELD( CTriggerCamera, m_flWait, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_flReturnTime, FIELD_TIME ), - DEFINE_FIELD( CTriggerCamera, m_flStopTime, FIELD_TIME ), - DEFINE_FIELD( CTriggerCamera, m_moveDistance, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_targetSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_initialSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_acceleration, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_deceleration, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_state, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE(CTriggerCamera,CBaseDelay); - -void CTriggerCamera::Spawn( void ) -{ - pev->movetype = MOVETYPE_NOCLIP; - pev->solid = SOLID_NOT; // Remove model & collisions - pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on - pev->rendermode = kRenderTransTexture; - - m_initialSpeed = pev->speed; - if ( m_acceleration == 0 ) - m_acceleration = 500; - if ( m_deceleration == 0 ) - m_deceleration = 500; -} - - -void CTriggerCamera :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "moveto")) - { - m_sPath = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "acceleration")) - { - m_acceleration = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "deceleration")) - { - m_deceleration = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - - - -void CTriggerCamera::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, m_state ) ) - return; - - // Toggle state - m_state = !m_state; - if (m_state == 0) - { - m_flReturnTime = gpGlobals->time; - return; - } - if ( !pActivator || !pActivator->IsPlayer() ) - { - pActivator = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex( 1 )); - } - - m_hPlayer = pActivator; - - m_flReturnTime = gpGlobals->time + m_flWait; - pev->speed = m_initialSpeed; - m_targetSpeed = m_initialSpeed; - - if (FBitSet (pev->spawnflags, SF_CAMERA_PLAYER_TARGET ) ) - { - m_hTarget = m_hPlayer; - } - else - { - m_hTarget = GetNextTarget(); - } - - // Nothing to look at! - if ( m_hTarget == NULL ) - { - return; - } - - - if (FBitSet (pev->spawnflags, SF_CAMERA_PLAYER_TAKECONTROL ) ) - { - ((CBasePlayer *)pActivator)->EnableControl(FALSE); - } - - if ( m_sPath ) - { - m_pentPath = Instance( FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(m_sPath)) ); - } - else - { - m_pentPath = NULL; - } - - m_flStopTime = gpGlobals->time; - if ( m_pentPath ) - { - if ( m_pentPath->pev->speed != 0 ) - m_targetSpeed = m_pentPath->pev->speed; - - m_flStopTime += m_pentPath->GetDelay(); - } - - // copy over player information - if (FBitSet (pev->spawnflags, SF_CAMERA_PLAYER_POSITION ) ) - { - UTIL_SetOrigin( pev, pActivator->pev->origin + pActivator->pev->view_ofs ); - pev->angles.x = -pActivator->pev->angles.x; - pev->angles.y = pActivator->pev->angles.y; - pev->angles.z = 0; - pev->velocity = pActivator->pev->velocity; - } - else - { - pev->velocity = Vector( 0, 0, 0 ); - } - - SET_VIEW( pActivator->edict(), edict() ); - - SET_MODEL(ENT(pev), STRING(pActivator->pev->model) ); - - // follow the player down - SetThink( &CTriggerCamera::FollowTarget ); - pev->nextthink = gpGlobals->time; - - m_moveDistance = 0; - Move(); -} - - -void CTriggerCamera::FollowTarget( ) -{ - if (m_hPlayer == NULL) - return; - - if (m_hTarget == NULL || m_flReturnTime < gpGlobals->time) - { - if (m_hPlayer->IsAlive( )) - { - SET_VIEW( m_hPlayer->edict(), m_hPlayer->edict() ); - ((CBasePlayer *)((CBaseEntity *)m_hPlayer))->EnableControl(TRUE); - } - SUB_UseTargets( this, USE_TOGGLE, 0 ); - pev->avelocity = Vector( 0, 0, 0 ); - m_state = 0; - return; - } - - Vector vecGoal = UTIL_VecToAngles( m_hTarget->pev->origin - pev->origin ); - vecGoal.x = -vecGoal.x; - - if (pev->angles.y > 360) - pev->angles.y -= 360; - - if (pev->angles.y < 0) - pev->angles.y += 360; - - float dx = vecGoal.x - pev->angles.x; - float dy = vecGoal.y - pev->angles.y; - - if (dx < -180) - dx += 360; - if (dx > 180) - dx = dx - 360; - - if (dy < -180) - dy += 360; - if (dy > 180) - dy = dy - 360; - - pev->avelocity.x = dx * 40 * gpGlobals->frametime; - pev->avelocity.y = dy * 40 * gpGlobals->frametime; - - - if (!(FBitSet (pev->spawnflags, SF_CAMERA_PLAYER_TAKECONTROL))) - { - pev->velocity = pev->velocity * 0.8; - if (pev->velocity.Length( ) < 10.0) - pev->velocity = g_vecZero; - } - - pev->nextthink = gpGlobals->time; - - Move(); -} - -void CTriggerCamera::Move() -{ - // Not moving on a path, return - if (!m_pentPath) - return; - - // Subtract movement from the previous frame - m_moveDistance -= pev->speed * gpGlobals->frametime; - - // Have we moved enough to reach the target? - if ( m_moveDistance <= 0 ) - { - // Fire the passtarget if there is one - if ( m_pentPath->pev->message ) - { - FireTargets( STRING(m_pentPath->pev->message), this, this, USE_TOGGLE, 0 ); - if ( FBitSet( m_pentPath->pev->spawnflags, SF_CORNER_FIREONCE ) ) - m_pentPath->pev->message = 0; - } - // Time to go to the next target - m_pentPath = m_pentPath->GetNextTarget(); - - // Set up next corner - if ( !m_pentPath ) - { - pev->velocity = g_vecZero; - } - else - { - if ( m_pentPath->pev->speed != 0 ) - m_targetSpeed = m_pentPath->pev->speed; - - Vector delta = m_pentPath->pev->origin - pev->origin; - m_moveDistance = delta.Length(); - pev->movedir = delta.Normalize(); - m_flStopTime = gpGlobals->time + m_pentPath->GetDelay(); - } - } - - if ( m_flStopTime > gpGlobals->time ) - pev->speed = UTIL_Approach( 0, pev->speed, m_deceleration * gpGlobals->frametime ); - else - pev->speed = UTIL_Approach( m_targetSpeed, pev->speed, m_acceleration * gpGlobals->frametime ); - - float fraction = 2 * gpGlobals->frametime; - pev->velocity = ((pev->movedir * pev->speed) * fraction) + (pev->velocity * (1-fraction)); -} - -void CClientFog :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "startdist")) - { - m_iStartDist = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "enddist")) - { - m_iEndDist = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -void CClientFog :: Spawn ( void ) -{ - pev->movetype = MOVETYPE_NOCLIP; - pev->solid = SOLID_NOT; // Remove model & collisions - pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on - pev->rendermode = kRenderTransTexture; -} - -LINK_ENTITY_TO_CLASS( env_fog, CClientFog ); diff --git a/dmc/dlls/util.cpp b/dmc/dlls/util.cpp deleted file mode 100644 index 94a989f..0000000 --- a/dmc/dlls/util.cpp +++ /dev/null @@ -1,2713 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== util.cpp ======================================================== - - Utility code. Really not optional after all. - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include -#include "../engine/shake.h" -#include "decals.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" - -/* -===================== -UTIL_WeaponTimeBase - -Time basis for weapons ( zero based of predicting client weapons ) -===================== -*/ -float UTIL_WeaponTimeBase( void ) -{ - return 0.0; -} - -static unsigned int glSeed = 0; - -unsigned int seed_table[ 256 ] = -{ - 28985, 27138, 26457, 9451, 17764, 10909, 28790, 8716, 6361, 4853, 17798, 21977, 19643, 20662, 10834, 20103, - 27067, 28634, 18623, 25849, 8576, 26234, 23887, 18228, 32587, 4836, 3306, 1811, 3035, 24559, 18399, 315, - 26766, 907, 24102, 12370, 9674, 2972, 10472, 16492, 22683, 11529, 27968, 30406, 13213, 2319, 23620, 16823, - 10013, 23772, 21567, 1251, 19579, 20313, 18241, 30130, 8402, 20807, 27354, 7169, 21211, 17293, 5410, 19223, - 10255, 22480, 27388, 9946, 15628, 24389, 17308, 2370, 9530, 31683, 25927, 23567, 11694, 26397, 32602, 15031, - 18255, 17582, 1422, 28835, 23607, 12597, 20602, 10138, 5212, 1252, 10074, 23166, 19823, 31667, 5902, 24630, - 18948, 14330, 14950, 8939, 23540, 21311, 22428, 22391, 3583, 29004, 30498, 18714, 4278, 2437, 22430, 3439, - 28313, 23161, 25396, 13471, 19324, 15287, 2563, 18901, 13103, 16867, 9714, 14322, 15197, 26889, 19372, 26241, - 31925, 14640, 11497, 8941, 10056, 6451, 28656, 10737, 13874, 17356, 8281, 25937, 1661, 4850, 7448, 12744, - 21826, 5477, 10167, 16705, 26897, 8839, 30947, 27978, 27283, 24685, 32298, 3525, 12398, 28726, 9475, 10208, - 617, 13467, 22287, 2376, 6097, 26312, 2974, 9114, 21787, 28010, 4725, 15387, 3274, 10762, 31695, 17320, - 18324, 12441, 16801, 27376, 22464, 7500, 5666, 18144, 15314, 31914, 31627, 6495, 5226, 31203, 2331, 4668, - 12650, 18275, 351, 7268, 31319, 30119, 7600, 2905, 13826, 11343, 13053, 15583, 30055, 31093, 5067, 761, - 9685, 11070, 21369, 27155, 3663, 26542, 20169, 12161, 15411, 30401, 7580, 31784, 8985, 29367, 20989, 14203, - 29694, 21167, 10337, 1706, 28578, 887, 3373, 19477, 14382, 675, 7033, 15111, 26138, 12252, 30996, 21409, - 25678, 18555, 13256, 23316, 22407, 16727, 991, 9236, 5373, 29402, 6117, 15241, 27715, 19291, 19888, 19847 -}; - -unsigned int U_Random( void ) -{ - glSeed *= 69069; - glSeed += seed_table[ glSeed & 0xff ]; - - return ( ++glSeed & 0x0fffffff ); -} - -void U_Srand( unsigned int seed ) -{ - glSeed = seed_table[ seed & 0xff ]; -} - -/* -===================== -UTIL_SharedRandomLong -===================== -*/ -int UTIL_SharedRandomLong( unsigned int seed, int low, int high ) -{ - - unsigned int range; - - U_Srand( (int)seed + low + high ); - - range = high - low + 1; - if ( !(range - 1) ) - { - return low; - } - else - { - int offset; - int rnum; - - rnum = U_Random(); - - offset = rnum % range; - - return (low + offset); - } -} - -/* -===================== -UTIL_SharedRandomFloat -===================== -*/ -float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ) -{ - // - unsigned int range; - - U_Srand( (int)seed + *(int *)&low + *(int *)&high ); - - U_Random(); - U_Random(); - - range = high - low; - if ( !range ) - { - return low; - } - else - { - int tensixrand; - float offset; - - tensixrand = U_Random() & 65535; - - offset = (float)tensixrand / 65536.0; - - return (low + offset * range ); - } -} - -void UTIL_ParametricRocket( entvars_t *pev, Vector vecOrigin, Vector vecAngles, edict_t *owner ) -{ - pev->startpos = vecOrigin; - // Trace out line to end pos - TraceResult tr; - UTIL_MakeVectors( vecAngles ); - UTIL_TraceLine( pev->startpos, pev->startpos + gpGlobals->v_forward * 8192, ignore_monsters, owner, &tr); - pev->endpos = tr.vecEndPos; - - // Now compute how long it will take based on current velocity - Vector vecTravel = pev->endpos - pev->startpos; - float travelTime = 0.0; - if ( pev->velocity.Length() > 0 ) - { - travelTime = vecTravel.Length() / pev->velocity.Length(); - } - pev->starttime = gpGlobals->time; - pev->impacttime = gpGlobals->time + travelTime; -} - -void UTIL_ClientProjectile( const Vector &vecOrigin, const Vector &vecVelocity, short sModelIndex, int iOwnerIndex, int iLife ) -{ - // we'd like to just send this projectile to a person in the shooter's PAS. However - // the projectile won't be sent to a player outside of water if shot from inside water - // and vice-versa, so we do a trace here to figure out if the trace starts or stops in water. - // if it crosses contents, we'll just broadcast the projectile. Otherwise, just send to PVS - // of the trace's endpoint. - BOOL fBroadcast; - - fBroadcast = FALSE; // assume we're just gonna send this message to PVS. - - TraceResult tr; - Vector vecTraceDir; - - vecTraceDir = vecVelocity.Normalize(); - - UTIL_TraceLine( vecOrigin, vecOrigin + vecTraceDir * 4096, ignore_monsters, ENT(iOwnerIndex), &tr ); - - if ( UTIL_PointContents( vecOrigin ) != UTIL_PointContents( tr.vecEndPos ) ) - { - fBroadcast = TRUE; - } - - if ( fBroadcast ) - { - // The projectile is going to cross content types - // (which will block PVS/PAS). Send to every client - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - } - else - { - // just the PVS of where the projectile will hit. - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, tr.vecEndPos ); - } - WRITE_BYTE( TE_PROJECTILE ); - WRITE_COORD( vecOrigin.x ); - WRITE_COORD( vecOrigin.y ); - WRITE_COORD( vecOrigin.z ); - - WRITE_COORD( vecVelocity.x ); - WRITE_COORD( vecVelocity.y ); - WRITE_COORD( vecVelocity.z ); - - WRITE_SHORT( sModelIndex ); - WRITE_BYTE ( iLife ); - WRITE_BYTE ( (BYTE)iOwnerIndex ); - MESSAGE_END(); -} - -int g_groupmask = 0; -int g_groupop = 0; - -// Normal overrides -void UTIL_SetGroupTrace( int groupmask, int op ) -{ - g_groupmask = groupmask; - g_groupop = op; - - ENGINE_SETGROUPMASK( g_groupmask, g_groupop ); -} - -void UTIL_UnsetGroupTrace( void ) -{ - g_groupmask = 0; - g_groupop = 0; - - ENGINE_SETGROUPMASK( 0, 0 ); -} - -// Smart version, it'll clean itself up when it pops off stack -UTIL_GroupTrace::UTIL_GroupTrace( int groupmask, int op ) -{ - m_oldgroupmask = g_groupmask; - m_oldgroupop = g_groupop; - - g_groupmask = groupmask; - g_groupop = op; - - ENGINE_SETGROUPMASK( g_groupmask, g_groupop ); -} - -UTIL_GroupTrace::~UTIL_GroupTrace( void ) -{ - g_groupmask = m_oldgroupmask; - g_groupop = m_oldgroupop; - - ENGINE_SETGROUPMASK( g_groupmask, g_groupop ); -} - -TYPEDESCRIPTION gEntvarsDescription[] = -{ - DEFINE_ENTITY_FIELD( classname, FIELD_STRING ), - DEFINE_ENTITY_GLOBAL_FIELD( globalname, FIELD_STRING ), - - DEFINE_ENTITY_FIELD( origin, FIELD_POSITION_VECTOR ), - DEFINE_ENTITY_FIELD( oldorigin, FIELD_POSITION_VECTOR ), - DEFINE_ENTITY_FIELD( velocity, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( basevelocity, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( movedir, FIELD_VECTOR ), - - DEFINE_ENTITY_FIELD( angles, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( v_angle, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( fixangle, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( idealpitch, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( pitch_speed, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( ideal_yaw, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( yaw_speed, FIELD_FLOAT ), - - DEFINE_ENTITY_FIELD( modelindex, FIELD_INTEGER ), - DEFINE_ENTITY_GLOBAL_FIELD( model, FIELD_MODELNAME ), - - DEFINE_ENTITY_FIELD( viewmodel, FIELD_MODELNAME ), - DEFINE_ENTITY_FIELD( weaponmodel, FIELD_MODELNAME ), - - DEFINE_ENTITY_FIELD( absmin, FIELD_POSITION_VECTOR ), - DEFINE_ENTITY_FIELD( absmax, FIELD_POSITION_VECTOR ), - DEFINE_ENTITY_GLOBAL_FIELD( mins, FIELD_VECTOR ), - DEFINE_ENTITY_GLOBAL_FIELD( maxs, FIELD_VECTOR ), - DEFINE_ENTITY_GLOBAL_FIELD( size, FIELD_VECTOR ), - - DEFINE_ENTITY_FIELD( ltime, FIELD_TIME ), - DEFINE_ENTITY_FIELD( nextthink, FIELD_TIME ), - - DEFINE_ENTITY_FIELD( solid, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( movetype, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( skin, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( body, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( effects, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( gravity, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( friction, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( light_level, FIELD_FLOAT ), - - DEFINE_ENTITY_FIELD( frame, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( scale, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( sequence, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( animtime, FIELD_TIME ), - DEFINE_ENTITY_FIELD( framerate, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( controller, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( blending, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( rendermode, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( renderamt, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( rendercolor, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( renderfx, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( health, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( frags, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( weapons, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( takedamage, FIELD_FLOAT ), - - DEFINE_ENTITY_FIELD( deadflag, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( view_ofs, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( button, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( impulse, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( chain, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( dmg_inflictor, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( enemy, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( aiment, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( owner, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( groundentity, FIELD_EDICT ), - - DEFINE_ENTITY_FIELD( spawnflags, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( flags, FIELD_FLOAT ), - - DEFINE_ENTITY_FIELD( colormap, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( team, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( max_health, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( teleport_time, FIELD_TIME ), - DEFINE_ENTITY_FIELD( armortype, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( armorvalue, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( waterlevel, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( watertype, FIELD_INTEGER ), - - // Having these fields be local to the individual levels makes it easier to test those levels individually. - DEFINE_ENTITY_GLOBAL_FIELD( target, FIELD_STRING ), - DEFINE_ENTITY_GLOBAL_FIELD( targetname, FIELD_STRING ), - DEFINE_ENTITY_FIELD( netname, FIELD_STRING ), - DEFINE_ENTITY_FIELD( message, FIELD_STRING ), - - DEFINE_ENTITY_FIELD( dmg_take, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( dmg_save, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( dmg, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( dmgtime, FIELD_TIME ), - - DEFINE_ENTITY_FIELD( noise, FIELD_SOUNDNAME ), - DEFINE_ENTITY_FIELD( noise1, FIELD_SOUNDNAME ), - DEFINE_ENTITY_FIELD( noise2, FIELD_SOUNDNAME ), - DEFINE_ENTITY_FIELD( noise3, FIELD_SOUNDNAME ), - DEFINE_ENTITY_FIELD( speed, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( air_finished, FIELD_TIME ), - DEFINE_ENTITY_FIELD( pain_finished, FIELD_TIME ), - DEFINE_ENTITY_FIELD( radsuit_finished, FIELD_TIME ), -}; - -#define ENTVARS_COUNT (sizeof(gEntvarsDescription)/sizeof(gEntvarsDescription[0])) - - -#ifdef DEBUG -edict_t *DBG_EntOfVars( const entvars_t *pev ) -{ - if (pev->pContainingEntity != NULL) - return pev->pContainingEntity; - ALERT(at_console, "entvars_t pContainingEntity is NULL, calling into engine"); - edict_t* pent = (*g_engfuncs.pfnFindEntityByVars)((entvars_t*)pev); - if (pent == NULL) - ALERT(at_console, "DAMN! Even the engine couldn't FindEntityByVars!"); - ((entvars_t *)pev)->pContainingEntity = pent; - return pent; -} -#endif //DEBUG - - -#ifdef DEBUG - void -DBG_AssertFunction( - BOOL fExpr, - const char* szExpr, - const char* szFile, - int szLine, - const char* szMessage) - { - if (fExpr) - return; - char szOut[512]; - if (szMessage != NULL) - sprintf(szOut, "ASSERT FAILED:\n %s \n(%s@%d)\n%s", szExpr, szFile, szLine, szMessage); - else - sprintf(szOut, "ASSERT FAILED:\n %s \n(%s@%d)", szExpr, szFile, szLine); - ALERT(at_console, szOut); - } -#endif // DEBUG - -BOOL UTIL_GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) -{ - return g_pGameRules->GetNextBestWeapon( pPlayer, pCurrentWeapon ); -} - -// ripped this out of the engine -float UTIL_AngleMod(float a) -{ - if (a < 0) - { - a = a + 360 * ((int)(a / 360) + 1); - } - else if (a >= 360) - { - a = a - 360 * ((int)(a / 360)); - } - // a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535); - return a; -} - -float UTIL_AngleDiff( float destAngle, float srcAngle ) -{ - float delta; - - delta = destAngle - srcAngle; - if ( destAngle > srcAngle ) - { - if ( delta >= 180 ) - delta -= 360; - } - else - { - if ( delta <= -180 ) - delta += 360; - } - return delta; -} - - -void EffectPrint( CBasePlayer *pPlayer, int color, int effect, int channel, char *text ) -{ - hudtextparms_t m_TesParms; - - memset(&m_TesParms, 0, sizeof(m_TesParms)); - - if (channel == WIN_MSG) - { - m_TesParms.x = -1; - m_TesParms.y = 0.4; - } - - if (channel == NOTIFY) - { - m_TesParms.x = -1; - m_TesParms.y = 0.9; - } - - else if (channel == INFO) - { - m_TesParms.x = 0; - m_TesParms.y = 0.85; - } - else if (channel == LEADER_HIT) - { - m_TesParms.x = -1; - m_TesParms.y = 1.0; - } - else if (channel == CRITICAL) - { - m_TesParms.x = -1; - m_TesParms.y = 0.7; - } - - else if (channel == MISC_SHIT) - { - m_TesParms.x = -1; - m_TesParms.y = 0.25; - } - else if (channel == CHASECAM) - { - m_TesParms.x = 0.0; - m_TesParms.y = 0.3; - } - else if (channel == CHASECAM_TARGET) - { - m_TesParms.x = 0.09; - m_TesParms.y = 0.3; - } - - m_TesParms.channel = channel; - - /* - effect = F_IN_OUT - FADE IN / FADE OUT - effect = CREDITS - CREDITS - effect = SCANOUT - SCAN OUT - */ - - m_TesParms.effect = effect; - - - if (color == BLUE) // Blue Color - { - m_TesParms.r1 = 0; - m_TesParms.g1 = 0; - m_TesParms.b1 = 255; - m_TesParms.a1 = 0; - } - else if (color == RED) // Red Color - { - m_TesParms.r1 = 255; - m_TesParms.g1 = 0; - m_TesParms.b1 = 0; - m_TesParms.a1 = 0; - } - else if (color == WHITE) //Whitey Color - { - m_TesParms.r1 = 255; - m_TesParms.g1 = 255; - m_TesParms.b1 = 200; - } - - //This is the second color in the effect, this is white for now... - m_TesParms.r2 = 255; - m_TesParms.g2 = 255; - m_TesParms.b2 = 255; - m_TesParms.a2 = 0; - - //Fade In Time - if (effect == SCANOUT) - m_TesParms.fadeinTime = 0.01; - else - m_TesParms.fadeinTime = 0.3; - - //Fade Out Time - - m_TesParms.fadeoutTime = 0.3; - - //Time the Effect is going to be up - if (effect == F_IN_OUT) - m_TesParms.holdTime = 1.5; - - else - m_TesParms.holdTime = 3.5; - - //Time the effect is aplied (?) - m_TesParms.fxTime = 0.25; - - if (pPlayer == NULL) - UTIL_HudMessageAll( m_TesParms, text ); - else - UTIL_HudMessage(pPlayer, m_TesParms, text ); - - -} - -Vector UTIL_VecToAngles( const Vector &vec ) -{ - float rgflVecOut[3]; - VEC_TO_ANGLES(vec, rgflVecOut); - return Vector(rgflVecOut); -} - -// float UTIL_MoveToOrigin( edict_t *pent, const Vector vecGoal, float flDist, int iMoveType ) -void UTIL_MoveToOrigin( edict_t *pent, const Vector &vecGoal, float flDist, int iMoveType ) -{ - float rgfl[3]; - vecGoal.CopyToArray(rgfl); -// return MOVE_TO_ORIGIN ( pent, rgfl, flDist, iMoveType ); - MOVE_TO_ORIGIN ( pent, rgfl, flDist, iMoveType ); -} - - -int UTIL_EntitiesInBox( CBaseEntity **pList, int listMax, const Vector &mins, const Vector &maxs, int flagMask ) -{ - edict_t *pEdict = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - CBaseEntity *pEntity; - int count; - - count = 0; - - if ( !pEdict ) - return count; - - for ( int i = 1; i < gpGlobals->maxEntities; i++, pEdict++ ) - { - if ( pEdict->free ) // Not in use - continue; - - if ( flagMask && !(pEdict->v.flags & flagMask) ) // Does it meet the criteria? - continue; - - if ( mins.x > pEdict->v.absmax.x || - mins.y > pEdict->v.absmax.y || - mins.z > pEdict->v.absmax.z || - maxs.x < pEdict->v.absmin.x || - maxs.y < pEdict->v.absmin.y || - maxs.z < pEdict->v.absmin.z ) - continue; - - pEntity = CBaseEntity::Instance(pEdict); - if ( !pEntity ) - continue; - - pList[ count ] = pEntity; - count++; - - if ( count >= listMax ) - return count; - } - - return count; -} - - -int UTIL_MonstersInSphere( CBaseEntity **pList, int listMax, const Vector ¢er, float radius ) -{ - edict_t *pEdict = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - CBaseEntity *pEntity; - int count; - float distance, delta; - - count = 0; - float radiusSquared = radius * radius; - - if ( !pEdict ) - return count; - - for ( int i = 1; i < gpGlobals->maxEntities; i++, pEdict++ ) - { - if ( pEdict->free ) // Not in use - continue; - - if ( !(pEdict->v.flags & (FL_CLIENT|FL_MONSTER)) ) // Not a client/monster ? - continue; - - // Use origin for X & Y since they are centered for all monsters - // Now X - delta = center.x - pEdict->v.origin.x;//(pEdict->v.absmin.x + pEdict->v.absmax.x)*0.5; - delta *= delta; - - if ( delta > radiusSquared ) - continue; - distance = delta; - - // Now Y - delta = center.y - pEdict->v.origin.y;//(pEdict->v.absmin.y + pEdict->v.absmax.y)*0.5; - delta *= delta; - - distance += delta; - if ( distance > radiusSquared ) - continue; - - // Now Z - delta = center.z - (pEdict->v.absmin.z + pEdict->v.absmax.z)*0.5; - delta *= delta; - - distance += delta; - if ( distance > radiusSquared ) - continue; - - pEntity = CBaseEntity::Instance(pEdict); - if ( !pEntity ) - continue; - - pList[ count ] = pEntity; - count++; - - if ( count >= listMax ) - return count; - } - - - return count; -} - - -CBaseEntity *UTIL_FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius ) -{ - edict_t *pentEntity; - - if (pStartEntity) - pentEntity = pStartEntity->edict(); - else - pentEntity = NULL; - - pentEntity = FIND_ENTITY_IN_SPHERE( pentEntity, vecCenter, flRadius); - - if (!FNullEnt(pentEntity)) - return CBaseEntity::Instance(pentEntity); - return NULL; -} - - -CBaseEntity *UTIL_FindEntityByString( CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue ) -{ - edict_t *pentEntity; - - if (pStartEntity) - pentEntity = pStartEntity->edict(); - else - pentEntity = NULL; - - pentEntity = FIND_ENTITY_BY_STRING( pentEntity, szKeyword, szValue ); - - if (!FNullEnt(pentEntity)) - return CBaseEntity::Instance(pentEntity); - return NULL; -} - -CBaseEntity *UTIL_FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ) -{ - return UTIL_FindEntityByString( pStartEntity, "classname", szName ); -} - -CBaseEntity *UTIL_FindEntityByTargetname( CBaseEntity *pStartEntity, const char *szName ) -{ - return UTIL_FindEntityByString( pStartEntity, "targetname", szName ); -} - - -CBaseEntity *UTIL_FindEntityGeneric( const char *szWhatever, Vector &vecSrc, float flRadius ) -{ - CBaseEntity *pEntity = NULL; - - pEntity = UTIL_FindEntityByTargetname( NULL, szWhatever ); - if (pEntity) - return pEntity; - - CBaseEntity *pSearch = NULL; - float flMaxDist2 = flRadius * flRadius; - while ((pSearch = UTIL_FindEntityByClassname( pSearch, szWhatever )) != NULL) - { - float flDist2 = (pSearch->pev->origin - vecSrc).Length(); - flDist2 = flDist2 * flDist2; - if (flMaxDist2 > flDist2) - { - pEntity = pSearch; - flMaxDist2 = flDist2; - } - } - return pEntity; -} - - -// returns a CBaseEntity pointer to a player by index. Only returns if the player is spawned and connected -// otherwise returns NULL -// Index is 1 based -CBaseEntity *UTIL_PlayerByIndex( int playerIndex ) -{ - CBaseEntity *pPlayer = NULL; - - if ( playerIndex > 0 && playerIndex <= gpGlobals->maxClients ) - { - edict_t *pPlayerEdict = INDEXENT( playerIndex ); - if ( pPlayerEdict && !pPlayerEdict->free ) - { - pPlayer = CBaseEntity::Instance( pPlayerEdict ); - } - } - - return pPlayer; -} - - -void UTIL_MakeVectors( const Vector &vecAngles ) -{ - MAKE_VECTORS( vecAngles ); -} - - -void UTIL_MakeAimVectors( const Vector &vecAngles ) -{ - float rgflVec[3]; - vecAngles.CopyToArray(rgflVec); - rgflVec[0] = -rgflVec[0]; - MAKE_VECTORS(rgflVec); -} - - -#define SWAP(a,b,temp) ((temp)=(a),(a)=(b),(b)=(temp)) - -void UTIL_MakeInvVectors( const Vector &vec, globalvars_t *pgv ) -{ - MAKE_VECTORS(vec); - - float tmp; - pgv->v_right = pgv->v_right * -1; - - SWAP(pgv->v_forward.y, pgv->v_right.x, tmp); - SWAP(pgv->v_forward.z, pgv->v_up.x, tmp); - SWAP(pgv->v_right.z, pgv->v_up.y, tmp); -} - - -void UTIL_EmitAmbientSound( edict_t *entity, const Vector &vecOrigin, const char *samp, float vol, float attenuation, int fFlags, int pitch ) -{ - float rgfl[3]; - vecOrigin.CopyToArray(rgfl); - - if (samp && *samp == '!') - { - char name[32]; - if (SENTENCEG_Lookup(samp, name) >= 0) - EMIT_AMBIENT_SOUND(entity, rgfl, name, vol, attenuation, fFlags, pitch); - } - else - EMIT_AMBIENT_SOUND(entity, rgfl, samp, vol, attenuation, fFlags, pitch); -} - -static unsigned short FixedUnsigned16( float value, float scale ) -{ - int output; - - output = value * scale; - if ( output < 0 ) - output = 0; - if ( output > 0xFFFF ) - output = 0xFFFF; - - return (unsigned short)output; -} - -static short FixedSigned16( float value, float scale ) -{ - int output; - - output = value * scale; - - if ( output > 32767 ) - output = 32767; - - if ( output < -32768 ) - output = -32768; - - return (short)output; -} - -// Shake the screen of all clients within radius -// radius == 0, shake all clients -// UNDONE: Allow caller to shake clients not ONGROUND? -// UNDONE: Fix falloff model (disabled)? -// UNDONE: Affect user controls? -void UTIL_ScreenShake( const Vector ¢er, float amplitude, float frequency, float duration, float radius ) -{ - int i; - float localAmplitude; - ScreenShake shake; - - shake.duration = FixedUnsigned16( duration, 1<<12 ); // 4.12 fixed - shake.frequency = FixedUnsigned16( frequency, 1<<8 ); // 8.8 fixed - - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - - if ( !pPlayer || !(pPlayer->pev->flags & FL_ONGROUND) ) // Don't shake if not onground - continue; - - localAmplitude = 0; - - if ( radius <= 0 ) - localAmplitude = amplitude; - else - { - Vector delta = center - pPlayer->pev->origin; - float distance = delta.Length(); - - // Had to get rid of this falloff - it didn't work well - if ( distance < radius ) - localAmplitude = amplitude;//radius - distance; - } - if ( localAmplitude ) - { - shake.amplitude = FixedUnsigned16( localAmplitude, 1<<12 ); // 4.12 fixed - - MESSAGE_BEGIN( MSG_ONE, gmsgShake, NULL, pPlayer->edict() ); // use the magic #1 for "one client" - - WRITE_SHORT( shake.amplitude ); // shake amount - WRITE_SHORT( shake.duration ); // shake lasts this long - WRITE_SHORT( shake.frequency ); // shake noise frequency - - MESSAGE_END(); - } - } -} - - - -void UTIL_ScreenShakeAll( const Vector ¢er, float amplitude, float frequency, float duration ) -{ - UTIL_ScreenShake( center, amplitude, frequency, duration, 0 ); -} - - -void UTIL_ScreenFadeBuild( ScreenFade &fade, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags ) -{ - fade.duration = FixedUnsigned16( fadeTime, 1<<12 ); // 4.12 fixed - fade.holdTime = FixedUnsigned16( fadeHold, 1<<12 ); // 4.12 fixed - fade.r = (int)color.x; - fade.g = (int)color.y; - fade.b = (int)color.z; - fade.a = alpha; - fade.fadeFlags = flags; -} - - -void UTIL_ScreenFadeWrite( const ScreenFade &fade, CBaseEntity *pEntity ) -{ - if ( !pEntity || !pEntity->IsNetClient() ) - return; - - MESSAGE_BEGIN( MSG_ONE, gmsgFade, NULL, pEntity->edict() ); // use the magic #1 for "one client" - - WRITE_SHORT( fade.duration ); // fade lasts this long - WRITE_SHORT( fade.holdTime ); // fade lasts this long - WRITE_SHORT( fade.fadeFlags ); // fade type (in / out) - WRITE_BYTE( fade.r ); // fade red - WRITE_BYTE( fade.g ); // fade green - WRITE_BYTE( fade.b ); // fade blue - WRITE_BYTE( fade.a ); // fade blue - - MESSAGE_END(); -} - - -void UTIL_ScreenFadeAll( const Vector &color, float fadeTime, float fadeHold, int alpha, int flags ) -{ - int i; - ScreenFade fade; - - - UTIL_ScreenFadeBuild( fade, color, fadeTime, fadeHold, alpha, flags ); - - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - - UTIL_ScreenFadeWrite( fade, pPlayer ); - } -} - - -void UTIL_ScreenFade( CBaseEntity *pEntity, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags ) -{ - ScreenFade fade; - - UTIL_ScreenFadeBuild( fade, color, fadeTime, fadeHold, alpha, flags ); - UTIL_ScreenFadeWrite( fade, pEntity ); -} - - -void UTIL_HudMessage( CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage ) -{ - if ( !pEntity || !pEntity->IsNetClient() ) - return; - - MESSAGE_BEGIN( MSG_ONE, SVC_TEMPENTITY, NULL, pEntity->edict() ); - WRITE_BYTE( TE_TEXTMESSAGE ); - WRITE_BYTE( textparms.channel & 0xFF ); - - WRITE_SHORT( FixedSigned16( textparms.x, 1<<13 ) ); - WRITE_SHORT( FixedSigned16( textparms.y, 1<<13 ) ); - WRITE_BYTE( textparms.effect ); - - WRITE_BYTE( textparms.r1 ); - WRITE_BYTE( textparms.g1 ); - WRITE_BYTE( textparms.b1 ); - WRITE_BYTE( textparms.a1 ); - - WRITE_BYTE( textparms.r2 ); - WRITE_BYTE( textparms.g2 ); - WRITE_BYTE( textparms.b2 ); - WRITE_BYTE( textparms.a2 ); - - WRITE_SHORT( FixedUnsigned16( textparms.fadeinTime, 1<<8 ) ); - WRITE_SHORT( FixedUnsigned16( textparms.fadeoutTime, 1<<8 ) ); - WRITE_SHORT( FixedUnsigned16( textparms.holdTime, 1<<8 ) ); - - if ( textparms.effect == 2 ) - WRITE_SHORT( FixedUnsigned16( textparms.fxTime, 1<<8 ) ); - - if ( strlen( pMessage ) < 512 ) - { - WRITE_STRING( pMessage ); - } - else - { - char tmp[512]; - strncpy( tmp, pMessage, 511 ); - tmp[511] = 0; - WRITE_STRING( tmp ); - } - MESSAGE_END(); -} - -void UTIL_HudMessageAll( const hudtextparms_t &textparms, const char *pMessage ) -{ - int i; - - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - if ( pPlayer ) - UTIL_HudMessage( pPlayer, textparms, pMessage ); - } -} - - -extern int gmsgTextMsg, gmsgSayText; -void UTIL_ClientPrintAll( int msg_dest, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) -{ - MESSAGE_BEGIN( MSG_ALL, gmsgTextMsg ); - WRITE_BYTE( msg_dest ); - WRITE_STRING( msg_name ); - - if ( param1 ) - WRITE_STRING( param1 ); - if ( param2 ) - WRITE_STRING( param2 ); - if ( param3 ) - WRITE_STRING( param3 ); - if ( param4 ) - WRITE_STRING( param4 ); - - MESSAGE_END(); -} - -void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) -{ - MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, client ); - WRITE_BYTE( msg_dest ); - WRITE_STRING( msg_name ); - - if ( param1 ) - WRITE_STRING( param1 ); - if ( param2 ) - WRITE_STRING( param2 ); - if ( param3 ) - WRITE_STRING( param3 ); - if ( param4 ) - WRITE_STRING( param4 ); - - MESSAGE_END(); -} - -void UTIL_SayText( const char *pText, CBaseEntity *pEntity ) -{ - if ( !pEntity->IsNetClient() ) - return; - - MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, pEntity->edict() ); - WRITE_BYTE( pEntity->entindex() ); - WRITE_STRING( pText ); - MESSAGE_END(); -} - -void UTIL_SayTextAll( const char *pText, CBaseEntity *pEntity ) -{ - MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); - WRITE_BYTE( pEntity->entindex() ); - WRITE_STRING( pText ); - MESSAGE_END(); -} - - -char *UTIL_dtos1( int d ) -{ - static char buf[8]; - sprintf( buf, "%d", d ); - return buf; -} - -char *UTIL_dtos2( int d ) -{ - static char buf[8]; - sprintf( buf, "%d", d ); - return buf; -} - -char *UTIL_dtos3( int d ) -{ - static char buf[8]; - sprintf( buf, "%d", d ); - return buf; -} - -char *UTIL_dtos4( int d ) -{ - static char buf[8]; - sprintf( buf, "%d", d ); - return buf; -} - -void UTIL_ShowMessage( const char *pString, CBaseEntity *pEntity ) -{ - if ( !pEntity || !pEntity->IsNetClient() ) - return; - - MESSAGE_BEGIN( MSG_ONE, gmsgHudText, NULL, pEntity->edict() ); - WRITE_STRING( pString ); - MESSAGE_END(); -} - - -void UTIL_ShowMessageAll( const char *pString ) -{ - int i; - - // loop through all players - - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - if ( pPlayer ) - UTIL_ShowMessage( pString, pPlayer ); - } -} - -// Overloaded to add IGNORE_GLASS -void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, IGNORE_GLASS ignoreGlass, edict_t *pentIgnore, TraceResult *ptr ) -{ - TRACE_LINE( vecStart, vecEnd, (igmon == ignore_monsters ? TRUE : FALSE) | (ignoreGlass?0x100:0), pentIgnore, ptr ); -} - - -void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr ) -{ - TRACE_LINE( vecStart, vecEnd, (igmon == ignore_monsters ? TRUE : FALSE), pentIgnore, ptr ); -} - - -void UTIL_TraceHull( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, int hullNumber, edict_t *pentIgnore, TraceResult *ptr ) -{ - TRACE_HULL( vecStart, vecEnd, (igmon == ignore_monsters ? TRUE : FALSE), hullNumber, pentIgnore, ptr ); -} - -void UTIL_TraceModel( const Vector &vecStart, const Vector &vecEnd, int hullNumber, edict_t *pentModel, TraceResult *ptr ) -{ - g_engfuncs.pfnTraceModel( vecStart, vecEnd, hullNumber, pentModel, ptr ); -} - - -TraceResult UTIL_GetGlobalTrace( ) -{ - TraceResult tr; - - tr.fAllSolid = gpGlobals->trace_allsolid; - tr.fStartSolid = gpGlobals->trace_startsolid; - tr.fInOpen = gpGlobals->trace_inopen; - tr.fInWater = gpGlobals->trace_inwater; - tr.flFraction = gpGlobals->trace_fraction; - tr.flPlaneDist = gpGlobals->trace_plane_dist; - tr.pHit = gpGlobals->trace_ent; - tr.vecEndPos = gpGlobals->trace_endpos; - tr.vecPlaneNormal = gpGlobals->trace_plane_normal; - tr.iHitgroup = gpGlobals->trace_hitgroup; - return tr; -} - - -void UTIL_SetSize( entvars_t *pev, const Vector &vecMin, const Vector &vecMax ) -{ - SET_SIZE( ENT(pev), vecMin, vecMax ); -} - - -float UTIL_VecToYaw( const Vector &vec ) -{ - return VEC_TO_YAW(vec); -} - - -void UTIL_SetOrigin( entvars_t *pev, const Vector &vecOrigin ) -{ - SET_ORIGIN(ENT(pev), vecOrigin ); -} - -void UTIL_ParticleEffect( const Vector &vecOrigin, const Vector &vecDirection, ULONG ulColor, ULONG ulCount ) -{ - PARTICLE_EFFECT( vecOrigin, vecDirection, (float)ulColor, (float)ulCount ); -} - - -float UTIL_Approach( float target, float value, float speed ) -{ - float delta = target - value; - - if ( delta > speed ) - value += speed; - else if ( delta < -speed ) - value -= speed; - else - value = target; - - return value; -} - - -float UTIL_ApproachAngle( float target, float value, float speed ) -{ - target = UTIL_AngleMod( target ); - value = UTIL_AngleMod( target ); - - float delta = target - value; - - // Speed is assumed to be positive - if ( speed < 0 ) - speed = -speed; - - if ( delta < -180 ) - delta += 360; - else if ( delta > 180 ) - delta -= 360; - - if ( delta > speed ) - value += speed; - else if ( delta < -speed ) - value -= speed; - else - value = target; - - return value; -} - - -float UTIL_AngleDistance( float next, float cur ) -{ - float delta = next - cur; - - if ( delta < -180 ) - delta += 360; - else if ( delta > 180 ) - delta -= 360; - - return delta; -} - - -float UTIL_SplineFraction( float value, float scale ) -{ - value = scale * value; - float valueSquared = value * value; - - // Nice little ease-in, ease-out spline-like curve - return 3 * valueSquared - 2 * valueSquared * value; -} - - -char* UTIL_VarArgs( char *format, ... ) -{ - va_list argptr; - static char string[1024]; - - va_start (argptr, format); - vsprintf (string, format,argptr); - va_end (argptr); - - return string; -} - -Vector UTIL_GetAimVector( edict_t *pent, float flSpeed ) -{ - Vector tmp; - GET_AIM_VECTOR(pent, flSpeed, tmp); - return tmp; -} - -int UTIL_IsMasterTriggered(string_t sMaster, CBaseEntity *pActivator) -{ - if (sMaster) - { - edict_t *pentTarget = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(sMaster)); - - if ( !FNullEnt(pentTarget) ) - { - CBaseEntity *pMaster = CBaseEntity::Instance(pentTarget); - if ( pMaster && (pMaster->ObjectCaps() & FCAP_MASTER) ) - return pMaster->IsTriggered( pActivator ); - } - - ALERT(at_console, "Master was null or not a master!\n"); - } - - // if this isn't a master entity, just say yes. - return 1; -} - -BOOL UTIL_ShouldShowBlood( int color ) -{ - if ( color != DONT_BLEED ) - { - if ( color == BLOOD_COLOR_RED ) - { - if ( CVAR_GET_FLOAT("violence_hblood") != 0 ) - return TRUE; - } - else - { - if ( CVAR_GET_FLOAT("violence_ablood") != 0 ) - return TRUE; - } - } - return FALSE; -} - -int UTIL_PointContents( const Vector &vec ) -{ - return POINT_CONTENTS(vec); -} - -void UTIL_BloodStream( const Vector &origin, const Vector &direction, int color, int amount ) -{ - if ( !UTIL_ShouldShowBlood( color ) ) - return; - - if ( g_Language == LANGUAGE_GERMAN && color == BLOOD_COLOR_RED ) - color = 0; - - - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, origin ); - WRITE_BYTE( TE_BLOODSTREAM ); - WRITE_COORD( origin.x ); - WRITE_COORD( origin.y ); - WRITE_COORD( origin.z ); - WRITE_COORD( direction.x ); - WRITE_COORD( direction.y ); - WRITE_COORD( direction.z ); - WRITE_BYTE( color ); - WRITE_BYTE( V_min( amount, 255 ) ); - MESSAGE_END(); -} - -void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ) -{ - if ( !UTIL_ShouldShowBlood( color ) ) - return; - - if ( color == DONT_BLEED || amount == 0 ) - return; - - if ( g_Language == LANGUAGE_GERMAN && color == BLOOD_COLOR_RED ) - color = 0; - - if ( g_pGameRules->IsMultiplayer() ) - { - // scale up blood effect in multiplayer for better visibility - amount *= 2; - } - - if ( amount > 255 ) - amount = 255; - - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, origin ); - WRITE_BYTE( TE_BLOODSPRITE ); - WRITE_COORD( origin.x); // pos - WRITE_COORD( origin.y); - WRITE_COORD( origin.z); - WRITE_SHORT( g_sModelIndexBloodSpray ); // initial sprite model - WRITE_SHORT( g_sModelIndexBloodDrop ); // droplet sprite models - WRITE_BYTE( color ); // color index into host_basepal - WRITE_BYTE( V_min( V_max( 3, amount / 10 ), 16 ) ); // size - MESSAGE_END(); -} - -Vector UTIL_RandomBloodVector( void ) -{ - Vector direction; - - direction.x = RANDOM_FLOAT ( -1, 1 ); - direction.y = RANDOM_FLOAT ( -1, 1 ); - direction.z = RANDOM_FLOAT ( 0, 1 ); - - return direction; -} - - -void UTIL_BloodDecalTrace( TraceResult *pTrace, int bloodColor ) -{ - if ( UTIL_ShouldShowBlood( bloodColor ) ) - { - if ( bloodColor == BLOOD_COLOR_RED ) - UTIL_DecalTrace( pTrace, DECAL_BLOOD1 + RANDOM_LONG(0,5) ); - else - UTIL_DecalTrace( pTrace, DECAL_YBLOOD1 + RANDOM_LONG(0,5) ); - } -} - - -void UTIL_DecalTrace( TraceResult *pTrace, int decalNumber ) -{ - short entityIndex; - int index; - int message; - - if ( decalNumber < 0 ) - return; - - index = gDecals[ decalNumber ].index; - - if ( index < 0 ) - return; - - if (pTrace->flFraction == 1.0) - return; - - // Only decal BSP models - if ( pTrace->pHit ) - { - CBaseEntity *pEntity = CBaseEntity::Instance( pTrace->pHit ); - if ( pEntity && !pEntity->IsBSPModel() ) - return; - entityIndex = ENTINDEX( pTrace->pHit ); - } - else - entityIndex = 0; - - message = TE_DECAL; - if ( entityIndex != 0 ) - { - if ( index > 255 ) - { - message = TE_DECALHIGH; - index -= 256; - } - } - else - { - message = TE_WORLDDECAL; - if ( index > 255 ) - { - message = TE_WORLDDECALHIGH; - index -= 256; - } - } - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( message ); - WRITE_COORD( pTrace->vecEndPos.x ); - WRITE_COORD( pTrace->vecEndPos.y ); - WRITE_COORD( pTrace->vecEndPos.z ); - WRITE_BYTE( index ); - if ( entityIndex ) - WRITE_SHORT( entityIndex ); - MESSAGE_END(); -} - -/* -============== -UTIL_PlayerDecalTrace - -A player is trying to apply his custom decal for the spray can. -Tell connected clients to display it, or use the default spray can decal -if the custom can't be loaded. -============== -*/ -void UTIL_PlayerDecalTrace( TraceResult *pTrace, int playernum, int decalNumber, BOOL bIsCustom ) -{ - int index; - - if (!bIsCustom) - { - if ( decalNumber < 0 ) - return; - - index = gDecals[ decalNumber ].index; - if ( index < 0 ) - return; - } - else - index = decalNumber; - - if (pTrace->flFraction == 1.0) - return; - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_PLAYERDECAL ); - WRITE_BYTE ( playernum ); - WRITE_COORD( pTrace->vecEndPos.x ); - WRITE_COORD( pTrace->vecEndPos.y ); - WRITE_COORD( pTrace->vecEndPos.z ); - WRITE_SHORT( (short)ENTINDEX(pTrace->pHit) ); - WRITE_BYTE( index ); - MESSAGE_END(); -} - -void UTIL_GunshotDecalTrace( TraceResult *pTrace, int decalNumber ) -{ - if ( decalNumber < 0 ) - return; - - int index = gDecals[ decalNumber ].index; - if ( index < 0 ) - return; - - if (pTrace->flFraction == 1.0) - return; - - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pTrace->vecEndPos ); - WRITE_BYTE( TE_GUNSHOTDECAL ); - WRITE_COORD( pTrace->vecEndPos.x ); - WRITE_COORD( pTrace->vecEndPos.y ); - WRITE_COORD( pTrace->vecEndPos.z ); - WRITE_SHORT( (short)ENTINDEX(pTrace->pHit) ); - WRITE_BYTE( index ); - MESSAGE_END(); -} - - -void UTIL_Sparks( const Vector &position ) -{ - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, position ); - WRITE_BYTE( TE_SPARKS ); - WRITE_COORD( position.x ); - WRITE_COORD( position.y ); - WRITE_COORD( position.z ); - MESSAGE_END(); -} - - -void UTIL_Ricochet( const Vector &position, float scale ) -{ - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, position ); - WRITE_BYTE( TE_ARMOR_RICOCHET ); - WRITE_COORD( position.x ); - WRITE_COORD( position.y ); - WRITE_COORD( position.z ); - WRITE_BYTE( (int)(scale*10) ); - MESSAGE_END(); -} - - -BOOL UTIL_TeamsMatch( const char *pTeamName1, const char *pTeamName2 ) -{ - // Everyone matches unless it's teamplay - if ( !g_pGameRules->IsTeamplay() ) - return TRUE; - - // Both on a team? - if ( *pTeamName1 != 0 && *pTeamName2 != 0 ) - { - if ( !stricmp( pTeamName1, pTeamName2 ) ) // Same Team? - return TRUE; - } - - return FALSE; -} - - -void UTIL_StringToVector( float *pVector, const char *pString ) -{ - char *pstr, *pfront, tempString[128]; - int j; - - strcpy( tempString, pString ); - pstr = pfront = tempString; - - for ( j = 0; j < 3; j++ ) // lifted from pr_edict.c - { - pVector[j] = atof( pfront ); - - while ( *pstr && *pstr != ' ' ) - pstr++; - if (!*pstr) - break; - pstr++; - pfront = pstr; - } - if (j < 2) - { - /* - ALERT( at_error, "Bad field in entity!! %s:%s == \"%s\"\n", - pkvd->szClassName, pkvd->szKeyName, pkvd->szValue ); - */ - for (j = j+1;j < 3; j++) - pVector[j] = 0; - } -} - - -void UTIL_StringToIntArray( int *pVector, int count, const char *pString ) -{ - char *pstr, *pfront, tempString[128]; - int j; - - strcpy( tempString, pString ); - pstr = pfront = tempString; - - for ( j = 0; j < count; j++ ) // lifted from pr_edict.c - { - pVector[j] = atoi( pfront ); - - while ( *pstr && *pstr != ' ' ) - pstr++; - if (!*pstr) - break; - pstr++; - pfront = pstr; - } - - for ( j++; j < count; j++ ) - { - pVector[j] = 0; - } -} - -Vector UTIL_ClampVectorToBox( const Vector &input, const Vector &clampSize ) -{ - Vector sourceVector = input; - - if ( sourceVector.x > clampSize.x ) - sourceVector.x -= clampSize.x; - else if ( sourceVector.x < -clampSize.x ) - sourceVector.x += clampSize.x; - else - sourceVector.x = 0; - - if ( sourceVector.y > clampSize.y ) - sourceVector.y -= clampSize.y; - else if ( sourceVector.y < -clampSize.y ) - sourceVector.y += clampSize.y; - else - sourceVector.y = 0; - - if ( sourceVector.z > clampSize.z ) - sourceVector.z -= clampSize.z; - else if ( sourceVector.z < -clampSize.z ) - sourceVector.z += clampSize.z; - else - sourceVector.z = 0; - - return sourceVector.Normalize(); -} - - -float UTIL_WaterLevel( const Vector &position, float minz, float maxz ) -{ - Vector midUp = position; - midUp.z = minz; - - if (UTIL_PointContents(midUp) != CONTENTS_WATER) - return minz; - - midUp.z = maxz; - if (UTIL_PointContents(midUp) == CONTENTS_WATER) - return maxz; - - float diff = maxz - minz; - while (diff > 1.0) - { - midUp.z = minz + diff/2.0; - if (UTIL_PointContents(midUp) == CONTENTS_WATER) - { - minz = midUp.z; - } - else - { - maxz = midUp.z; - } - diff = maxz - minz; - } - - return midUp.z; -} - - -extern DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model - -void UTIL_Bubbles( Vector mins, Vector maxs, int count ) -{ - Vector mid = (mins + maxs) * 0.5; - - float flHeight = UTIL_WaterLevel( mid, mid.z, mid.z + 1024 ); - flHeight = flHeight - mins.z; - - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, mid ); - WRITE_BYTE( TE_BUBBLES ); - WRITE_COORD( mins.x ); // mins - WRITE_COORD( mins.y ); - WRITE_COORD( mins.z ); - WRITE_COORD( maxs.x ); // maxz - WRITE_COORD( maxs.y ); - WRITE_COORD( maxs.z ); - WRITE_COORD( flHeight ); // height - WRITE_SHORT( g_sModelIndexBubbles ); - WRITE_BYTE( count ); // count - WRITE_COORD( 8 ); // speed - MESSAGE_END(); -} - -void UTIL_BubbleTrail( Vector from, Vector to, int count ) -{ - float flHeight = UTIL_WaterLevel( from, from.z, from.z + 256 ); - flHeight = flHeight - from.z; - - // Return if the start point isn't in water - if (flHeight < 8) - return; - - flHeight = UTIL_WaterLevel( to, to.z, to.z + 256 ); - flHeight = flHeight - to.z; - if (flHeight < 8) - return; - - // UNDONE: do a ploink sound - flHeight = flHeight + to.z - from.z; - - if (count > 255) - count = 255; - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_BUBBLETRAIL ); - WRITE_COORD( from.x ); // mins - WRITE_COORD( from.y ); - WRITE_COORD( from.z ); - WRITE_COORD( to.x ); // maxz - WRITE_COORD( to.y ); - WRITE_COORD( to.z ); - WRITE_COORD( flHeight ); // height - WRITE_SHORT( g_sModelIndexBubbles ); - WRITE_BYTE( count ); // count - WRITE_COORD( 8 ); // speed - MESSAGE_END(); -} - - -void UTIL_Remove( CBaseEntity *pEntity ) -{ - if ( !pEntity ) - return; - - pEntity->UpdateOnRemove(); - pEntity->pev->flags |= FL_KILLME; - pEntity->pev->targetname = 0; -} - - -BOOL UTIL_IsValidEntity( edict_t *pent ) -{ - if ( !pent || pent->free || (pent->v.flags & FL_KILLME) ) - return FALSE; - return TRUE; -} - - -void UTIL_PrecacheOther( const char *szClassname ) -{ - edict_t *pent; - - pent = CREATE_NAMED_ENTITY( MAKE_STRING( szClassname ) ); - if ( FNullEnt( pent ) ) - { - ALERT ( at_console, "NULL Ent in UTIL_PrecacheOther\n" ); - return; - } - - CBaseEntity *pEntity = CBaseEntity::Instance (VARS( pent )); - if (pEntity) - pEntity->Precache( ); - REMOVE_ENTITY(pent); -} - -//========================================================= -// UTIL_LogPrintf - Prints a logged message to console. -// Preceded by LOG: ( timestamp ) < message > -//========================================================= -void UTIL_LogPrintf( char *fmt, ... ) -{ - va_list argptr; - static char string[1024]; - - va_start ( argptr, fmt ); - vsprintf ( string, fmt, argptr ); - va_end ( argptr ); - - // Print to server console - ALERT( at_logged, "%s", string ); -} - -//========================================================= -// UTIL_DotPoints - returns the dot product of a line from -// src to check and vecdir. -//========================================================= -float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ) -{ - Vector2D vec2LOS; - - vec2LOS = ( vecCheck - vecSrc ).Make2D(); - vec2LOS = vec2LOS.Normalize(); - - return DotProduct (vec2LOS , ( vecDir.Make2D() ) ); -} - - -//========================================================= -// UTIL_StripToken - for redundant keynames -//========================================================= -void UTIL_StripToken( const char *pKey, char *pDest ) -{ - int i = 0; - - while ( pKey[i] && pKey[i] != '#' ) - { - pDest[i] = pKey[i]; - i++; - } - pDest[i] = 0; -} - - -// -------------------------------------------------------------- -// -// CSave -// -// -------------------------------------------------------------- -static int gSizes[FIELD_TYPECOUNT] = -{ - sizeof(float), // FIELD_FLOAT - sizeof(int), // FIELD_STRING - sizeof(int), // FIELD_ENTITY - sizeof(int), // FIELD_CLASSPTR - sizeof(int), // FIELD_EHANDLE - sizeof(int), // FIELD_entvars_t - sizeof(int), // FIELD_EDICT - sizeof(float)*3, // FIELD_VECTOR - sizeof(float)*3, // FIELD_POSITION_VECTOR - sizeof(int *), // FIELD_POINTER - sizeof(int), // FIELD_INTEGER - sizeof(int *), // FIELD_FUNCTION - sizeof(int), // FIELD_BOOLEAN - sizeof(short), // FIELD_SHORT - sizeof(char), // FIELD_CHARACTER - sizeof(float), // FIELD_TIME - sizeof(int), // FIELD_MODELNAME - sizeof(int), // FIELD_SOUNDNAME -}; - - -// Base class includes common SAVERESTOREDATA pointer, and manages the entity table -CSaveRestoreBuffer :: CSaveRestoreBuffer( void ) -{ - m_pdata = NULL; -} - - -CSaveRestoreBuffer :: CSaveRestoreBuffer( SAVERESTOREDATA *pdata ) -{ - m_pdata = pdata; -} - - -CSaveRestoreBuffer :: ~CSaveRestoreBuffer( void ) -{ -} - -int CSaveRestoreBuffer :: EntityIndex( CBaseEntity *pEntity ) -{ - if ( pEntity == NULL ) - return -1; - return EntityIndex( pEntity->pev ); -} - - -int CSaveRestoreBuffer :: EntityIndex( entvars_t *pevLookup ) -{ - if ( pevLookup == NULL ) - return -1; - return EntityIndex( ENT( pevLookup ) ); -} - -int CSaveRestoreBuffer :: EntityIndex( EOFFSET eoLookup ) -{ - return EntityIndex( ENT( eoLookup ) ); -} - - -int CSaveRestoreBuffer :: EntityIndex( edict_t *pentLookup ) -{ - if ( !m_pdata || pentLookup == NULL ) - return -1; - - int i; - ENTITYTABLE *pTable; - - for ( i = 0; i < m_pdata->tableCount; i++ ) - { - pTable = m_pdata->pTable + i; - if ( pTable->pent == pentLookup ) - return i; - } - return -1; -} - - -edict_t *CSaveRestoreBuffer :: EntityFromIndex( int entityIndex ) -{ - if ( !m_pdata || entityIndex < 0 ) - return NULL; - - int i; - ENTITYTABLE *pTable; - - for ( i = 0; i < m_pdata->tableCount; i++ ) - { - pTable = m_pdata->pTable + i; - if ( pTable->id == entityIndex ) - return pTable->pent; - } - return NULL; -} - - -int CSaveRestoreBuffer :: EntityFlagsSet( int entityIndex, int flags ) -{ - if ( !m_pdata || entityIndex < 0 ) - return 0; - if ( entityIndex > m_pdata->tableCount ) - return 0; - - m_pdata->pTable[ entityIndex ].flags |= flags; - - return m_pdata->pTable[ entityIndex ].flags; -} - - -void CSaveRestoreBuffer :: BufferRewind( int size ) -{ - if ( !m_pdata ) - return; - - if ( m_pdata->size < size ) - size = m_pdata->size; - - m_pdata->pCurrentData -= size; - m_pdata->size -= size; -} - -#ifndef _WIN32 -extern "C" { -unsigned _rotr ( unsigned val, int shift) -{ - register unsigned lobit; /* non-zero means lo bit set */ - register unsigned num = val; /* number to rotate */ - - shift &= 0x1f; /* modulo 32 -- this will also make - negative shifts work */ - - while (shift--) { - lobit = num & 1; /* get high bit */ - num >>= 1; /* shift right one bit */ - if (lobit) - num |= 0x80000000; /* set hi bit if lo bit was set */ - } - - return num; -} -} -#endif - -unsigned int CSaveRestoreBuffer :: HashString( const char *pszToken ) -{ - unsigned int hash = 0; - - while ( *pszToken ) - hash = _rotr( hash, 4 ) ^ *pszToken++; - - return hash; -} - -unsigned short CSaveRestoreBuffer :: TokenHash( const char *pszToken ) -{ - unsigned short hash = (unsigned short)(HashString( pszToken ) % (unsigned)m_pdata->tokenCount ); - -#if _DEBUG - static int tokensparsed = 0; - tokensparsed++; - if ( !m_pdata->tokenCount || !m_pdata->pTokens ) - ALERT( at_error, "No token table array in TokenHash()!" ); -#endif - - for ( int i=0; itokenCount; i++ ) - { -#if _DEBUG - static qboolean beentheredonethat = FALSE; - if ( i > 50 && !beentheredonethat ) - { - beentheredonethat = TRUE; - ALERT( at_error, "CSaveRestoreBuffer :: TokenHash() is getting too full!" ); - } -#endif - - int index = hash + i; - if ( index >= m_pdata->tokenCount ) - index -= m_pdata->tokenCount; - - if ( !m_pdata->pTokens[index] || strcmp( pszToken, m_pdata->pTokens[index] ) == 0 ) - { - m_pdata->pTokens[index] = (char *)pszToken; - return index; - } - } - - // Token hash table full!!! - // [Consider doing overflow table(s) after the main table & limiting linear hash table search] - ALERT( at_error, "CSaveRestoreBuffer :: TokenHash() is COMPLETELY FULL!" ); - return 0; -} - -void CSave :: WriteData( const char *pname, int size, const char *pdata ) -{ - BufferField( pname, size, pdata ); -} - - -void CSave :: WriteShort( const char *pname, const short *data, int count ) -{ - BufferField( pname, sizeof(short) * count, (const char *)data ); -} - - -void CSave :: WriteInt( const char *pname, const int *data, int count ) -{ - BufferField( pname, sizeof(int) * count, (const char *)data ); -} - - -void CSave :: WriteFloat( const char *pname, const float *data, int count ) -{ - BufferField( pname, sizeof(float) * count, (const char *)data ); -} - - -void CSave :: WriteTime( const char *pname, const float *data, int count ) -{ - int i; - Vector tmp, input; - - BufferHeader( pname, sizeof(float) * count ); - for ( i = 0; i < count; i++ ) - { - float tmp = data[0]; - - // Always encode time as a delta from the current time so it can be re-based if loaded in a new level - // Times of 0 are never written to the file, so they will be restored as 0, not a relative time - if ( m_pdata ) - tmp -= m_pdata->time; - - BufferData( (const char *)&tmp, sizeof(float) ); - data ++; - } -} - - -void CSave :: WriteString( const char *pname, const char *pdata ) -{ -#ifdef TOKENIZE - short token = (short)TokenHash( pdata ); - WriteShort( pname, &token, 1 ); -#else - BufferField( pname, strlen(pdata) + 1, pdata ); -#endif -} - - -void CSave :: WriteString( const char *pname, const int *stringId, int count ) -{ - int i, size; - -#ifdef TOKENIZE - short token = (short)TokenHash( STRING( *stringId ) ); - WriteShort( pname, &token, 1 ); -#else -#if 0 - if ( count != 1 ) - ALERT( at_error, "No string arrays!\n" ); - WriteString( pname, (char *)STRING(*stringId) ); -#endif - - size = 0; - for ( i = 0; i < count; i++ ) - size += strlen( STRING( stringId[i] ) ) + 1; - - BufferHeader( pname, size ); - for ( i = 0; i < count; i++ ) - { - const char *pString = STRING(stringId[i]); - BufferData( pString, strlen(pString)+1 ); - } -#endif -} - - -void CSave :: WriteVector( const char *pname, const Vector &value ) -{ - WriteVector( pname, &value.x, 1 ); -} - - -void CSave :: WriteVector( const char *pname, const float *value, int count ) -{ - BufferHeader( pname, sizeof(float) * 3 * count ); - BufferData( (const char *)value, sizeof(float) * 3 * count ); -} - - - -void CSave :: WritePositionVector( const char *pname, const Vector &value ) -{ - - if ( m_pdata && m_pdata->fUseLandmark ) - { - Vector tmp = value - m_pdata->vecLandmarkOffset; - WriteVector( pname, tmp ); - } - - WriteVector( pname, value ); -} - - -void CSave :: WritePositionVector( const char *pname, const float *value, int count ) -{ - int i; - Vector tmp, input; - - BufferHeader( pname, sizeof(float) * 3 * count ); - for ( i = 0; i < count; i++ ) - { - Vector tmp( value[0], value[1], value[2] ); - - if ( m_pdata && m_pdata->fUseLandmark ) - tmp = tmp - m_pdata->vecLandmarkOffset; - - BufferData( (const char *)&tmp.x, sizeof(float) * 3 ); - value += 3; - } -} - - -void CSave :: WriteFunction( const char *pname, void **data, int count ) -{ - const char *functionName; - - functionName = NAME_FOR_FUNCTION( (uint32)*data ); - if ( functionName ) - BufferField( pname, strlen(functionName) + 1, functionName ); - else - ALERT( at_error, "Invalid function pointer in entity!" ); -} - - -void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd ) -{ - int i; - TYPEDESCRIPTION *pField; - - for ( i = 0; i < ENTVARS_COUNT; i++ ) - { - pField = &gEntvarsDescription[i]; - - if ( !stricmp( pField->fieldName, pkvd->szKeyName ) ) - { - switch( pField->fieldType ) - { - case FIELD_MODELNAME: - case FIELD_SOUNDNAME: - case FIELD_STRING: - (*(int *)((char *)pev + pField->fieldOffset)) = ALLOC_STRING( pkvd->szValue ); - break; - - case FIELD_TIME: - case FIELD_FLOAT: - (*(float *)((char *)pev + pField->fieldOffset)) = atof( pkvd->szValue ); - break; - - case FIELD_INTEGER: - (*(int *)((char *)pev + pField->fieldOffset)) = atoi( pkvd->szValue ); - break; - - case FIELD_POSITION_VECTOR: - case FIELD_VECTOR: - UTIL_StringToVector( (float *)((char *)pev + pField->fieldOffset), pkvd->szValue ); - break; - - default: - case FIELD_EVARS: - case FIELD_CLASSPTR: - case FIELD_EDICT: - case FIELD_ENTITY: - case FIELD_POINTER: - ALERT( at_error, "Bad field in entity!!\n" ); - break; - } - pkvd->fHandled = TRUE; - return; - } - } -} - - - -int CSave :: WriteEntVars( const char *pname, entvars_t *pev ) -{ - return WriteFields( pname, pev, gEntvarsDescription, ENTVARS_COUNT ); -} - - - -int CSave :: WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ) -{ - int i, j, actualCount, emptyCount; - TYPEDESCRIPTION *pTest; - int entityArray[MAX_ENTITYARRAY]; - - // Precalculate the number of empty fields - emptyCount = 0; - for ( i = 0; i < fieldCount; i++ ) - { - void *pOutputData; - pOutputData = ((char *)pBaseData + pFields[i].fieldOffset ); - if ( DataEmpty( (const char *)pOutputData, pFields[i].fieldSize * gSizes[pFields[i].fieldType] ) ) - emptyCount++; - } - - // Empty fields will not be written, write out the actual number of fields to be written - actualCount = fieldCount - emptyCount; - WriteInt( pname, &actualCount, 1 ); - - for ( i = 0; i < fieldCount; i++ ) - { - void *pOutputData; - pTest = &pFields[ i ]; - pOutputData = ((char *)pBaseData + pTest->fieldOffset ); - - // UNDONE: Must we do this twice? - if ( DataEmpty( (const char *)pOutputData, pTest->fieldSize * gSizes[pTest->fieldType] ) ) - continue; - - switch( pTest->fieldType ) - { - case FIELD_FLOAT: - WriteFloat( pTest->fieldName, (float *)pOutputData, pTest->fieldSize ); - break; - case FIELD_TIME: - WriteTime( pTest->fieldName, (float *)pOutputData, pTest->fieldSize ); - break; - case FIELD_MODELNAME: - case FIELD_SOUNDNAME: - case FIELD_STRING: - WriteString( pTest->fieldName, (int *)pOutputData, pTest->fieldSize ); - break; - case FIELD_CLASSPTR: - case FIELD_EVARS: - case FIELD_EDICT: - case FIELD_ENTITY: - case FIELD_EHANDLE: - if ( pTest->fieldSize > MAX_ENTITYARRAY ) - ALERT( at_error, "Can't save more than %d entities in an array!!!\n", MAX_ENTITYARRAY ); - for ( j = 0; j < pTest->fieldSize; j++ ) - { - switch( pTest->fieldType ) - { - case FIELD_EVARS: - entityArray[j] = EntityIndex( ((entvars_t **)pOutputData)[j] ); - break; - case FIELD_CLASSPTR: - entityArray[j] = EntityIndex( ((CBaseEntity **)pOutputData)[j] ); - break; - case FIELD_EDICT: - entityArray[j] = EntityIndex( ((edict_t **)pOutputData)[j] ); - break; - case FIELD_ENTITY: - entityArray[j] = EntityIndex( ((EOFFSET *)pOutputData)[j] ); - break; - case FIELD_EHANDLE: - entityArray[j] = EntityIndex( (CBaseEntity *)(((EHANDLE *)pOutputData)[j]) ); - break; - } - } - WriteInt( pTest->fieldName, entityArray, pTest->fieldSize ); - break; - case FIELD_POSITION_VECTOR: - WritePositionVector( pTest->fieldName, (float *)pOutputData, pTest->fieldSize ); - break; - case FIELD_VECTOR: - WriteVector( pTest->fieldName, (float *)pOutputData, pTest->fieldSize ); - break; - - case FIELD_BOOLEAN: - case FIELD_INTEGER: - WriteInt( pTest->fieldName, (int *)pOutputData, pTest->fieldSize ); - break; - - case FIELD_SHORT: - WriteData( pTest->fieldName, 2 * pTest->fieldSize, ((char *)pOutputData) ); - break; - - case FIELD_CHARACTER: - WriteData( pTest->fieldName, pTest->fieldSize, ((char *)pOutputData) ); - break; - - // For now, just write the address out, we're not going to change memory while doing this yet! - case FIELD_POINTER: - WriteInt( pTest->fieldName, (int *)(char *)pOutputData, pTest->fieldSize ); - break; - - case FIELD_FUNCTION: - WriteFunction( pTest->fieldName, (void **)pOutputData, pTest->fieldSize ); - break; - default: - ALERT( at_error, "Bad field type\n" ); - } - } - - return 1; -} - - -void CSave :: BufferString( char *pdata, int len ) -{ - char c = 0; - - BufferData( pdata, len ); // Write the string - BufferData( &c, 1 ); // Write a null terminator -} - - -int CSave :: DataEmpty( const char *pdata, int size ) -{ - for ( int i = 0; i < size; i++ ) - { - if ( pdata[i] ) - return 0; - } - return 1; -} - - -void CSave :: BufferField( const char *pname, int size, const char *pdata ) -{ - BufferHeader( pname, size ); - BufferData( pdata, size ); -} - - -void CSave :: BufferHeader( const char *pname, int size ) -{ - short hashvalue = TokenHash( pname ); - if ( size > 1<<(sizeof(short)*8) ) - ALERT( at_error, "CSave :: BufferHeader() size parameter exceeds 'short'!" ); - BufferData( (const char *)&size, sizeof(short) ); - BufferData( (const char *)&hashvalue, sizeof(short) ); -} - - -void CSave :: BufferData( const char *pdata, int size ) -{ - if ( !m_pdata ) - return; - - if ( m_pdata->size + size > m_pdata->bufferSize ) - { - ALERT( at_error, "Save/Restore overflow!" ); - m_pdata->size = m_pdata->bufferSize; - return; - } - - memcpy( m_pdata->pCurrentData, pdata, size ); - m_pdata->pCurrentData += size; - m_pdata->size += size; -} - - - -// -------------------------------------------------------------- -// -// CRestore -// -// -------------------------------------------------------------- - -int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount, int startField, int size, char *pName, void *pData ) -{ - int i, j, stringCount, fieldNumber, entityIndex; - TYPEDESCRIPTION *pTest; - float time, timeData; - Vector position; - edict_t *pent; - char *pString; - - time = 0; - position = Vector(0,0,0); - - if ( m_pdata ) - { - time = m_pdata->time; - if ( m_pdata->fUseLandmark ) - position = m_pdata->vecLandmarkOffset; - } - - for ( i = 0; i < fieldCount; i++ ) - { - fieldNumber = (i+startField)%fieldCount; - pTest = &pFields[ fieldNumber ]; - if ( !stricmp( pTest->fieldName, pName ) ) - { - if ( !m_global || !(pTest->flags & FTYPEDESC_GLOBAL) ) - { - for ( j = 0; j < pTest->fieldSize; j++ ) - { - void *pOutputData = ((char *)pBaseData + pTest->fieldOffset + (j*gSizes[pTest->fieldType]) ); - void *pInputData = (char *)pData + j * gSizes[pTest->fieldType]; - - switch( pTest->fieldType ) - { - case FIELD_TIME: - timeData = *(float *)pInputData; - // Re-base time variables - timeData += time; - *((float *)pOutputData) = timeData; - break; - case FIELD_FLOAT: - *((float *)pOutputData) = *(float *)pInputData; - break; - case FIELD_MODELNAME: - case FIELD_SOUNDNAME: - case FIELD_STRING: - // Skip over j strings - pString = (char *)pData; - for ( stringCount = 0; stringCount < j; stringCount++ ) - { - while (*pString) - pString++; - pString++; - } - pInputData = pString; - if ( strlen( (char *)pInputData ) == 0 ) - *((int *)pOutputData) = 0; - else - { - int string; - - string = ALLOC_STRING( (char *)pInputData ); - - *((int *)pOutputData) = string; - - if ( !FStringNull( string ) && m_precache ) - { - if ( pTest->fieldType == FIELD_MODELNAME ) - PRECACHE_MODEL( (char *)STRING( string ) ); - else if ( pTest->fieldType == FIELD_SOUNDNAME ) - PRECACHE_SOUND( (char *)STRING( string ) ); - } - } - break; - case FIELD_EVARS: - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - if ( pent ) - *((entvars_t **)pOutputData) = VARS(pent); - else - *((entvars_t **)pOutputData) = NULL; - break; - case FIELD_CLASSPTR: - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - if ( pent ) - *((CBaseEntity **)pOutputData) = CBaseEntity::Instance(pent); - else - *((CBaseEntity **)pOutputData) = NULL; - break; - case FIELD_EDICT: - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - *((edict_t **)pOutputData) = pent; - break; - case FIELD_EHANDLE: - // Input and Output sizes are different! - pOutputData = (char *)pOutputData + j*(sizeof(EHANDLE) - gSizes[pTest->fieldType]); - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - if ( pent ) - *((EHANDLE *)pOutputData) = CBaseEntity::Instance(pent); - else - *((EHANDLE *)pOutputData) = NULL; - break; - case FIELD_ENTITY: - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - if ( pent ) - *((EOFFSET *)pOutputData) = OFFSET(pent); - else - *((EOFFSET *)pOutputData) = 0; - break; - case FIELD_VECTOR: - ((float *)pOutputData)[0] = ((float *)pInputData)[0]; - ((float *)pOutputData)[1] = ((float *)pInputData)[1]; - ((float *)pOutputData)[2] = ((float *)pInputData)[2]; - break; - case FIELD_POSITION_VECTOR: - ((float *)pOutputData)[0] = ((float *)pInputData)[0] + position.x; - ((float *)pOutputData)[1] = ((float *)pInputData)[1] + position.y; - ((float *)pOutputData)[2] = ((float *)pInputData)[2] + position.z; - break; - - case FIELD_BOOLEAN: - case FIELD_INTEGER: - *((int *)pOutputData) = *( int *)pInputData; - break; - - case FIELD_SHORT: - *((short *)pOutputData) = *( short *)pInputData; - break; - - case FIELD_CHARACTER: - *((char *)pOutputData) = *( char *)pInputData; - break; - - case FIELD_POINTER: - *((int *)pOutputData) = *( int *)pInputData; - break; - case FIELD_FUNCTION: - if ( strlen( (char *)pInputData ) == 0 ) - *((int *)pOutputData) = 0; - else - *((int *)pOutputData) = FUNCTION_FROM_NAME( (char *)pInputData ); - break; - - default: - ALERT( at_error, "Bad field type\n" ); - } - } - } -#if 0 - else - { - ALERT( at_console, "Skipping global field %s\n", pName ); - } -#endif - return fieldNumber; - } - } - - return -1; -} - - -int CRestore::ReadEntVars( const char *pname, entvars_t *pev ) -{ - return ReadFields( pname, pev, gEntvarsDescription, ENTVARS_COUNT ); -} - - -int CRestore::ReadFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ) -{ - unsigned short i, token; - int lastField, fileCount; - HEADER header; - - i = ReadShort(); - ASSERT( i == sizeof(int) ); // First entry should be an int - - token = ReadShort(); - - // Check the struct name - if ( token != TokenHash(pname) ) // Field Set marker - { -// ALERT( at_error, "Expected %s found %s!\n", pname, BufferPointer() ); - BufferRewind( 2*sizeof(short) ); - return 0; - } - - // Skip over the struct name - fileCount = ReadInt(); // Read field count - - lastField = 0; // Make searches faster, most data is read/written in the same order - - // Clear out base data - for ( i = 0; i < fieldCount; i++ ) - { - // Don't clear global fields - if ( !m_global || !(pFields[i].flags & FTYPEDESC_GLOBAL) ) - memset( ((char *)pBaseData + pFields[i].fieldOffset), 0, pFields[i].fieldSize * gSizes[pFields[i].fieldType] ); - } - - for ( i = 0; i < fileCount; i++ ) - { - BufferReadHeader( &header ); - lastField = ReadField( pBaseData, pFields, fieldCount, lastField, header.size, m_pdata->pTokens[header.token], header.pData ); - lastField++; - } - - return 1; -} - - -void CRestore::BufferReadHeader( HEADER *pheader ) -{ - ASSERT( pheader!=NULL ); - pheader->size = ReadShort(); // Read field size - pheader->token = ReadShort(); // Read field name token - pheader->pData = BufferPointer(); // Field Data is next - BufferSkipBytes( pheader->size ); // Advance to next field -} - - -short CRestore::ReadShort( void ) -{ - short tmp = 0; - - BufferReadBytes( (char *)&tmp, sizeof(short) ); - - return tmp; -} - -int CRestore::ReadInt( void ) -{ - int tmp = 0; - - BufferReadBytes( (char *)&tmp, sizeof(int) ); - - return tmp; -} - -int CRestore::ReadNamedInt( const char *pName ) -{ - HEADER header; - - BufferReadHeader( &header ); - return ((int *)header.pData)[0]; -} - -char *CRestore::ReadNamedString( const char *pName ) -{ - HEADER header; - - BufferReadHeader( &header ); -#ifdef TOKENIZE - return (char *)(m_pdata->pTokens[*(short *)header.pData]); -#else - return (char *)header.pData; -#endif -} - - -char *CRestore::BufferPointer( void ) -{ - if ( !m_pdata ) - return NULL; - - return m_pdata->pCurrentData; -} - -void CRestore::BufferReadBytes( char *pOutput, int size ) -{ - ASSERT( m_pdata !=NULL ); - - if ( !m_pdata || Empty() ) - return; - - if ( (m_pdata->size + size) > m_pdata->bufferSize ) - { - ALERT( at_error, "Restore overflow!" ); - m_pdata->size = m_pdata->bufferSize; - return; - } - - if ( pOutput ) - memcpy( pOutput, m_pdata->pCurrentData, size ); - m_pdata->pCurrentData += size; - m_pdata->size += size; -} - - -void CRestore::BufferSkipBytes( int bytes ) -{ - BufferReadBytes( NULL, bytes ); -} - -int CRestore::BufferSkipZString( void ) -{ - char *pszSearch; - int len; - - if ( !m_pdata ) - return 0; - - int maxLen = m_pdata->bufferSize - m_pdata->size; - - len = 0; - pszSearch = m_pdata->pCurrentData; - while ( *pszSearch++ && len < maxLen ) - len++; - - len++; - - BufferSkipBytes( len ); - - return len; -} - -int CRestore::BufferCheckZString( const char *string ) -{ - if ( !m_pdata ) - return 0; - - int maxLen = m_pdata->bufferSize - m_pdata->size; - int len = strlen( string ); - if ( len <= maxLen ) - { - if ( !strncmp( string, m_pdata->pCurrentData, len ) ) - return 1; - } - return 0; -} diff --git a/dmc/dlls/util.h b/dmc/dlls/util.h deleted file mode 100644 index 3206f12..0000000 --- a/dmc/dlls/util.h +++ /dev/null @@ -1,593 +0,0 @@ -/*** -* -* 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. -* -****/ -#include "archtypes.h" // DAL - -// -// Misc utility code -// -#ifndef ACTIVITY_H -#include "activity.h" -#endif - -#ifndef ENGINECALLBACK_H -#include "enginecallback.h" -#endif -inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin, entvars_t *ent ); // implementation later in this file - -extern globalvars_t *gpGlobals; - -// Use this instead of ALLOC_STRING on constant strings -#define STRING(offset) ((const char *)(gpGlobals->pStringBase + (unsigned int)(offset))) -#define MAKE_STRING(str) ((uint64)(str) - (uint64)STRING(0)) - - -inline edict_t *FIND_ENTITY_BY_CLASSNAME(edict_t *entStart, const char *pszName) -{ - return FIND_ENTITY_BY_STRING(entStart, "classname", pszName); -} - -inline edict_t *FIND_ENTITY_BY_TARGETNAME(edict_t *entStart, const char *pszName) -{ - return FIND_ENTITY_BY_STRING(entStart, "targetname", pszName); -} - -// for doing a reverse lookup. Say you have a door, and want to find its button. -inline edict_t *FIND_ENTITY_BY_TARGET(edict_t *entStart, const char *pszName) -{ - return FIND_ENTITY_BY_STRING(entStart, "target", pszName); -} - -// Keeps clutter down a bit, when writing key-value pairs -#define WRITEKEY_INT(pf, szKeyName, iKeyValue) \ - ENGINE_FPRINTF(pf, "\"%s\" \"%d\"\n", szKeyName, iKeyValue) -#define WRITEKEY_FLOAT(pf, szKeyName, flKeyValue) \ - ENGINE_FPRINTF(pf, "\"%s\" \"%f\"\n", szKeyName, flKeyValue) -#define WRITEKEY_STRING(pf, szKeyName, szKeyValue) \ - ENGINE_FPRINTF(pf, "\"%s\" \"%s\"\n", szKeyName, szKeyValue) -#define WRITEKEY_VECTOR(pf, szKeyName, flX, flY, flZ) \ - ENGINE_FPRINTF(pf, "\"%s\" \"%f %f %f\"\n", szKeyName, flX, flY, flZ) - -// Keeps clutter down a bit, when using a float as a bit-vector -#define SetBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) | (bits)) -#define ClearBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) & ~(bits)) -#define FBitSet(flBitVector, bit) ((int)(flBitVector) & (bit)) - -// Makes these more explicit, and easier to find -#define FILE_GLOBAL static -#define DLL_GLOBAL - -// Until we figure out why "const" gives the compiler problems, we'll just have to use -// this bogus "empty" define to mark things as constant. -#define CONSTANT - -// More explicit than "int" -typedef int EOFFSET; - -// In case it's not alread defined -typedef int BOOL; - -// In case this ever changes -#define M_PI 3.14159265358979323846 - -// Keeps clutter down a bit, when declaring external entity/global method prototypes -#define DECLARE_GLOBAL_METHOD(MethodName) \ - extern void DLLEXPORT MethodName( void ) -#define GLOBAL_METHOD(funcname) void DLLEXPORT funcname(void) - -// This is the glue that hooks .MAP entity class names to our CPP classes -// The _declspec forces them to be exported by name so we can do a lookup with GetProcAddress() -// The function is used to intialize / allocate the object for the entity -#define LINK_ENTITY_TO_CLASS(mapClassName,DLLClassName) \ - extern "C" DLLEXPORT void mapClassName( entvars_t *pev ); \ - void mapClassName( entvars_t *pev ) { GetClassPtr( (DLLClassName *)pev ); } - - -// -// Conversion among the three types of "entity", including identity-conversions. -// -#ifdef DEBUG - extern edict_t *DBG_EntOfVars(const entvars_t *pev); - inline edict_t *ENT(const entvars_t *pev) { return DBG_EntOfVars(pev); } -#else - inline edict_t *ENT(const entvars_t *pev) { return pev->pContainingEntity; } -#endif -inline edict_t *ENT(edict_t *pent) { return pent; } -inline edict_t *ENT(EOFFSET eoffset) { return (*g_engfuncs.pfnPEntityOfEntOffset)(eoffset); } -inline EOFFSET OFFSET(EOFFSET eoffset) { return eoffset; } -inline EOFFSET OFFSET(const edict_t *pent) -{ -#if _DEBUG - if ( !pent ) - ALERT( at_error, "Bad ent in OFFSET()\n" ); -#endif - return (*g_engfuncs.pfnEntOffsetOfPEntity)(pent); -} -inline EOFFSET OFFSET(entvars_t *pev) -{ -#if _DEBUG - if ( !pev ) - ALERT( at_error, "Bad pev in OFFSET()\n" ); -#endif - return OFFSET(ENT(pev)); -} -inline entvars_t *VARS(entvars_t *pev) { return pev; } - -inline entvars_t *VARS(edict_t *pent) -{ - if ( !pent ) - return NULL; - - return &pent->v; -} - -inline entvars_t* VARS(EOFFSET eoffset) { return VARS(ENT(eoffset)); } -inline int ENTINDEX(edict_t *pEdict) { return (*g_engfuncs.pfnIndexOfEdict)(pEdict); } -inline edict_t* INDEXENT( int iEdictNum ) { return (*g_engfuncs.pfnPEntityOfEntIndex)(iEdictNum); } -inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin, entvars_t *ent ) { - (*g_engfuncs.pfnMessageBegin)(msg_dest, msg_type, pOrigin, ENT(ent)); -} - -// Testing the three types of "entity" for nullity -#define eoNullEntity 0 -inline BOOL FNullEnt(EOFFSET eoffset) { return eoffset == 0; } -inline BOOL FNullEnt(const edict_t* pent) { return pent == NULL || FNullEnt(OFFSET(pent)); } -inline BOOL FNullEnt(entvars_t* pev) { return pev == NULL || FNullEnt(OFFSET(pev)); } - -// Testing strings for nullity -#define iStringNull 0 -inline BOOL FStringNull(int iString) { return iString == iStringNull; } - -#define cchMapNameMost 32 - -// Dot products for view cone checking -#define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees -#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks -#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks -#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks - -// All monsters need this data -#define DONT_BLEED -1 -#define BLOOD_COLOR_RED (BYTE)247 -#define BLOOD_COLOR_YELLOW (BYTE)195 -#define BLOOD_COLOR_GREEN BLOOD_COLOR_YELLOW - -typedef enum -{ - - MONSTERSTATE_NONE = 0, - MONSTERSTATE_IDLE, - MONSTERSTATE_COMBAT, - MONSTERSTATE_ALERT, - MONSTERSTATE_HUNT, - MONSTERSTATE_PRONE, - MONSTERSTATE_SCRIPT, - MONSTERSTATE_PLAYDEAD, - MONSTERSTATE_DEAD - -} MONSTERSTATE; - - - -// Things that toggle (buttons/triggers/doors) need this -typedef enum - { - TS_AT_TOP, - TS_AT_BOTTOM, - TS_GOING_UP, - TS_GOING_DOWN - } TOGGLE_STATE; - -// Misc useful -inline BOOL FStrEq(const char*sz1, const char*sz2) - { return (strcmp(sz1, sz2) == 0); } -inline BOOL FClassnameIs(edict_t* pent, const char* szClassname) - { return FStrEq(STRING(VARS(pent)->classname), szClassname); } -inline BOOL FClassnameIs(entvars_t* pev, const char* szClassname) - { return FStrEq(STRING(pev->classname), szClassname); } - -class CBaseEntity; - -// Misc. Prototypes -extern void UTIL_SetSize (entvars_t* pev, const Vector &vecMin, const Vector &vecMax); -extern float UTIL_VecToYaw (const Vector &vec); -extern Vector UTIL_VecToAngles (const Vector &vec); -extern float UTIL_AngleMod (float a); -extern float UTIL_AngleDiff ( float destAngle, float srcAngle ); - -extern CBaseEntity *UTIL_FindEntityInSphere(CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius); -extern CBaseEntity *UTIL_FindEntityByString(CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue ); -extern CBaseEntity *UTIL_FindEntityByClassname(CBaseEntity *pStartEntity, const char *szName ); -extern CBaseEntity *UTIL_FindEntityByTargetname(CBaseEntity *pStartEntity, const char *szName ); -extern CBaseEntity *UTIL_FindEntityGeneric(const char *szName, Vector &vecSrc, float flRadius ); - -// returns a CBaseEntity pointer to a player by index. Only returns if the player is spawned and connected -// otherwise returns NULL -// Index is 1 based -extern CBaseEntity *UTIL_PlayerByIndex( int playerIndex ); - -#define UTIL_EntitiesInPVS(pent) (*g_engfuncs.pfnEntitiesInPVS)(pent) -extern void UTIL_MakeVectors (const Vector &vecAngles); - -// Pass in an array of pointers and an array size, it fills the array and returns the number inserted -extern int UTIL_MonstersInSphere( CBaseEntity **pList, int listMax, const Vector ¢er, float radius ); -extern int UTIL_EntitiesInBox( CBaseEntity **pList, int listMax, const Vector &mins, const Vector &maxs, int flagMask ); - -inline void UTIL_MakeVectorsPrivate( const Vector &vecAngles, float *p_vForward, float *p_vRight, float *p_vUp ) -{ - g_engfuncs.pfnAngleVectors( vecAngles, p_vForward, p_vRight, p_vUp ); -} - -extern void UTIL_MakeAimVectors ( const Vector &vecAngles ); // like MakeVectors, but assumes pitch isn't inverted -extern void UTIL_MakeInvVectors ( const Vector &vec, globalvars_t *pgv ); - -extern void UTIL_SetOrigin ( entvars_t* pev, const Vector &vecOrigin ); -extern void UTIL_EmitAmbientSound ( edict_t *entity, const Vector &vecOrigin, const char *samp, float vol, float attenuation, int fFlags, int pitch ); -extern void UTIL_ParticleEffect ( const Vector &vecOrigin, const Vector &vecDirection, ULONG ulColor, ULONG ulCount ); -extern void UTIL_ScreenShake ( const Vector ¢er, float amplitude, float frequency, float duration, float radius ); -extern void UTIL_ScreenShakeAll ( const Vector ¢er, float amplitude, float frequency, float duration ); -extern void UTIL_ShowMessage ( const char *pString, CBaseEntity *pPlayer ); -extern void UTIL_ShowMessageAll ( const char *pString ); -extern void UTIL_ScreenFadeAll ( const Vector &color, float fadeTime, float holdTime, int alpha, int flags ); -extern void UTIL_ScreenFade ( CBaseEntity *pEntity, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags ); - -typedef enum { ignore_monsters=1, dont_ignore_monsters=0, missile=2 } IGNORE_MONSTERS; -typedef enum { ignore_glass=1, dont_ignore_glass=0 } IGNORE_GLASS; -extern void UTIL_TraceLine (const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr); -extern void UTIL_TraceLine (const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, IGNORE_GLASS ignoreGlass, edict_t *pentIgnore, TraceResult *ptr); -enum { point_hull=0, human_hull=1, large_hull=2, head_hull=3 }; -extern void UTIL_TraceHull (const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, int hullNumber, edict_t *pentIgnore, TraceResult *ptr); -extern TraceResult UTIL_GetGlobalTrace (void); -extern void UTIL_TraceModel (const Vector &vecStart, const Vector &vecEnd, int hullNumber, edict_t *pentModel, TraceResult *ptr); -extern Vector UTIL_GetAimVector (edict_t* pent, float flSpeed); -extern int UTIL_PointContents (const Vector &vec); - -extern int UTIL_IsMasterTriggered (string_t sMaster, CBaseEntity *pActivator); -extern void UTIL_BloodStream( const Vector &origin, const Vector &direction, int color, int amount ); -extern void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ); -extern Vector UTIL_RandomBloodVector( void ); -extern BOOL UTIL_ShouldShowBlood( int bloodColor ); -extern void UTIL_BloodDecalTrace( TraceResult *pTrace, int bloodColor ); -extern void UTIL_DecalTrace( TraceResult *pTrace, int decalNumber ); -extern void UTIL_PlayerDecalTrace( TraceResult *pTrace, int playernum, int decalNumber, BOOL bIsCustom ); -extern void UTIL_GunshotDecalTrace( TraceResult *pTrace, int decalNumber ); -extern void UTIL_Sparks( const Vector &position ); -extern void UTIL_Ricochet( const Vector &position, float scale ); -extern void UTIL_StringToVector( float *pVector, const char *pString ); -extern void UTIL_StringToIntArray( int *pVector, int count, const char *pString ); -extern Vector UTIL_ClampVectorToBox( const Vector &input, const Vector &clampSize ); -extern float UTIL_Approach( float target, float value, float speed ); -extern float UTIL_ApproachAngle( float target, float value, float speed ); -extern float UTIL_AngleDistance( float next, float cur ); - -extern char *UTIL_VarArgs( char *format, ... ); -extern void UTIL_Remove( CBaseEntity *pEntity ); -extern BOOL UTIL_IsValidEntity( edict_t *pent ); -extern BOOL UTIL_TeamsMatch( const char *pTeamName1, const char *pTeamName2 ); - -// create a TENT projectile on all clients -extern void UTIL_ClientProjectile( const Vector &vecOrigin, const Vector &vecVelocity, short sModelIndex, int iOwnerIndex, int iLife ); - -// Use for ease-in, ease-out style interpolation (accel/decel) -extern float UTIL_SplineFraction( float value, float scale ); - -// Search for water transition along a vertical line -extern float UTIL_WaterLevel( const Vector &position, float minz, float maxz ); -extern void UTIL_Bubbles( Vector mins, Vector maxs, int count ); -extern void UTIL_BubbleTrail( Vector from, Vector to, int count ); - -// allows precacheing of other entities -extern void UTIL_PrecacheOther( const char *szClassname ); - -// prints a message to each client -extern void UTIL_ClientPrintAll( int msg_dest, const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ); -inline void UTIL_CenterPrintAll( const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ) -{ - UTIL_ClientPrintAll( HUD_PRINTCENTER, msg_name, param1, param2, param3, param4 ); -} - -class CBasePlayerItem; -class CBasePlayer; -extern BOOL UTIL_GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ); - -// prints messages through the HUD -extern void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ); - -// prints a message to the HUD say (chat) -extern void UTIL_SayText( const char *pText, CBaseEntity *pEntity ); -extern void UTIL_SayTextAll( const char *pText, CBaseEntity *pEntity ); - - -typedef struct hudtextparms_s -{ - float x; - float y; - int effect; - byte r1, g1, b1, a1; - byte r2, g2, b2, a2; - float fadeinTime; - float fadeoutTime; - float holdTime; - float fxTime; - int channel; -} hudtextparms_t; - -// prints as transparent 'title' to the HUD -extern void UTIL_HudMessageAll( const hudtextparms_t &textparms, const char *pMessage ); -extern void UTIL_HudMessage( CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage ); - -// for handy use with ClientPrint params -extern char *UTIL_dtos1( int d ); -extern char *UTIL_dtos2( int d ); -extern char *UTIL_dtos3( int d ); -extern char *UTIL_dtos4( int d ); - -// Writes message to console with timestamp and FragLog header. -extern void UTIL_LogPrintf( char *fmt, ... ); - -// Sorta like FInViewCone, but for nonmonsters. -extern float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ); - -extern void UTIL_StripToken( const char *pKey, char *pDest );// for redundant keynames - -// Misc functions -extern void SetMovedir(entvars_t* pev); -extern Vector VecBModelOrigin( entvars_t* pevBModel ); -extern int BuildChangeList( LEVELLIST *pLevelList, int maxList ); - -// -// How did I ever live without ASSERT? -// -#ifdef DEBUG -void DBG_AssertFunction(BOOL fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage); -#define ASSERT(f) DBG_AssertFunction(f, #f, __FILE__, __LINE__, NULL) -#define ASSERTSZ(f, sz) DBG_AssertFunction(f, #f, __FILE__, __LINE__, sz) -#else // !DEBUG -#define ASSERT(f) -#define ASSERTSZ(f, sz) -#endif // !DEBUG - - -extern DLL_GLOBAL const Vector g_vecZero; - -// -// Constants that were used only by QC (maybe not used at all now) -// -// Un-comment only as needed -// -#define LANGUAGE_ENGLISH 0 -#define LANGUAGE_GERMAN 1 -#define LANGUAGE_FRENCH 2 -#define LANGUAGE_BRITISH 3 - -extern DLL_GLOBAL int g_Language; - -#define AMBIENT_SOUND_STATIC 0 // medium radius attenuation -#define AMBIENT_SOUND_EVERYWHERE 1 -#define AMBIENT_SOUND_SMALLRADIUS 2 -#define AMBIENT_SOUND_MEDIUMRADIUS 4 -#define AMBIENT_SOUND_LARGERADIUS 8 -#define AMBIENT_SOUND_START_SILENT 16 -#define AMBIENT_SOUND_NOT_LOOPING 32 - -#define SPEAKER_START_SILENT 1 // wait for trigger 'on' to start announcements - -#define SND_SPAWNING (1<<8) // duplicated in protocol.h we're spawing, used in some cases for ambients -#define SND_STOP (1<<5) // duplicated in protocol.h stop sound -#define SND_CHANGE_VOL (1<<6) // duplicated in protocol.h change sound vol -#define SND_CHANGE_PITCH (1<<7) // duplicated in protocol.h change sound pitch - -#define LFO_SQUARE 1 -#define LFO_TRIANGLE 2 -#define LFO_RANDOM 3 - -// func_rotating -#define SF_BRUSH_ROTATE_Y_AXIS 0 -#define SF_BRUSH_ROTATE_INSTANT 1 -#define SF_BRUSH_ROTATE_BACKWARDS 2 -#define SF_BRUSH_ROTATE_Z_AXIS 4 -#define SF_BRUSH_ROTATE_X_AXIS 8 -#define SF_PENDULUM_AUTO_RETURN 16 -#define SF_PENDULUM_PASSABLE 32 - - -#define SF_BRUSH_ROTATE_SMALLRADIUS 128 -#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256 -#define SF_BRUSH_ROTATE_LARGERADIUS 512 - -#define PUSH_BLOCK_ONLY_X 1 -#define PUSH_BLOCK_ONLY_Y 2 - -// QUAKECLASSIC: Different player sizes -//#define VEC_HULL_MIN Vector(-16, -16, -36) -//#define VEC_HULL_MAX Vector( 16, 16, 36) -#define VEC_HULL_MIN Vector(-16, -16, -24) -#define VEC_HULL_MAX Vector(16, 16, 32) - -#define VEC_HUMAN_HULL_MIN Vector( -16, -16, 0 ) -#define VEC_HUMAN_HULL_MAX Vector( 16, 16, 72 ) -#define VEC_HUMAN_HULL_DUCK Vector( 16, 16, 36 ) - -#define VEC_VIEW Vector( 0, 0, 18 ) - -#define VEC_DUCK_HULL_MIN Vector(-16, -16, -18 ) -#define VEC_DUCK_HULL_MAX Vector( 16, 16, 18) -#define VEC_DUCK_VIEW Vector( 0, 0, 12 ) - -#define SVC_TEMPENTITY 23 -#define SVC_INTERMISSION 30 -#define SVC_CDTRACK 32 -#define SVC_WEAPONANIM 35 -#define SVC_ROOMTYPE 37 -#define SVC_ADDANGLE 38 // [vec3] add this angle to the view angle -#define SVC_NEWUSERMSG 39 -#define SVC_DIRECTOR 51 - - -// triggers -#define SF_TRIGGER_ALLOWMONSTERS 1// monsters allowed to fire this trigger -#define SF_TRIGGER_NOCLIENTS 2// players not allowed to fire this trigger -#define SF_TRIGGER_PUSHABLES 4// only pushables can fire this trigger - -// func breakable -#define SF_BREAK_TRIGGER_ONLY 1// may only be broken by trigger -#define SF_BREAK_TOUCH 2// can be 'crashed through' by running player (plate glass) -#define SF_BREAK_PRESSURE 4// can be broken by a player standing on it -#define SF_BREAK_CROWBAR 256// instant break if hit with crowbar - -// func_pushable (it's also func_breakable, so don't collide with those flags) -#define SF_PUSH_BREAKABLE 128 - -#define SF_LIGHT_START_OFF 1 - -#define SPAWNFLAG_NOMESSAGE 1 -#define SPAWNFLAG_NOTOUCH 1 -#define SPAWNFLAG_DROIDONLY 4 - -#define SPAWNFLAG_USEONLY 1 // can't be touched, must be used (buttons) - -#define TELE_PLAYER_ONLY 1 -#define TELE_SILENT 2 - -#define SF_TRIG_PUSH_ONCE 1 - - -// Sound Utilities - -// sentence groups -#define CBSENTENCENAME_MAX 16 -#define CVOXFILESENTENCEMAX 1536 // max number of sentences in game. NOTE: this must match - // CVOXFILESENTENCEMAX in engine\sound.h!!! - -extern char gszallsentencenames[CVOXFILESENTENCEMAX][CBSENTENCENAME_MAX]; -extern int gcallsentences; - -int USENTENCEG_Pick(int isentenceg, char *szfound); -int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int freset); -void USENTENCEG_InitLRU(unsigned char *plru, int count); - -void SENTENCEG_Init(); -void SENTENCEG_Stop(edict_t *entity, int isentenceg, int ipick); -int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, float volume, float attenuation, int flags, int pitch); -int SENTENCEG_PlayRndSz(edict_t *entity, const char *szrootname, float volume, float attenuation, int flags, int pitch); -int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szrootname, float volume, float attenuation, int flags, int pitch, int ipick, int freset); -int SENTENCEG_GetIndex(const char *szrootname); -int SENTENCEG_Lookup(const char *sample, char *sentencenum); - -void TEXTURETYPE_Init(); -char TEXTURETYPE_Find(char *name); -float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int iBulletType); - -#define CBTEXTURENAMEMAX 13 // only load first n chars of name - -#define CHAR_TEX_CONCRETE 'C' // texture types -#define CHAR_TEX_METAL 'M' -#define CHAR_TEX_DIRT 'D' -#define CHAR_TEX_VENT 'V' -#define CHAR_TEX_GRATE 'G' -#define CHAR_TEX_TILE 'T' -#define CHAR_TEX_SLOSH 'S' -#define CHAR_TEX_WOOD 'W' -#define CHAR_TEX_COMPUTER 'P' -#define CHAR_TEX_GLASS 'Y' -#define CHAR_TEX_FLESH 'F' - -// NOTE: use EMIT_SOUND_DYN to set the pitch of a sound. Pitch of 100 -// is no pitch shift. Pitch > 100 up to 255 is a higher pitch, pitch < 100 -// down to 1 is a lower pitch. 150 to 70 is the realistic range. -// EMIT_SOUND_DYN with pitch != 100 should be used sparingly, as it's not quite as -// fast as EMIT_SOUND (the pitchshift mixer is not native coded). - -void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, - int flags, int pitch); - - -inline void EMIT_SOUND(edict_t *entity, int channel, const char *sample, float volume, float attenuation) -{ - EMIT_SOUND_DYN(entity, channel, sample, volume, attenuation, 0, PITCH_NORM); -} - -inline void STOP_SOUND(edict_t *entity, int channel, const char *sample) -{ - EMIT_SOUND_DYN(entity, channel, sample, 0, 0, SND_STOP, PITCH_NORM); -} - -void EMIT_SOUND_SUIT(edict_t *entity, const char *sample); -void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg); -void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); - -#define PRECACHE_SOUND_ARRAY( a ) \ - { for (int i = 0; i < ARRAYSIZE( a ); i++ ) PRECACHE_SOUND((char *) a [i]); } - -#define EMIT_SOUND_ARRAY_DYN( chan, array ) \ - EMIT_SOUND_DYN ( ENT(pev), chan , array [ RANDOM_LONG(0,ARRAYSIZE( array )-1) ], 1.0, ATTN_NORM, 0, RANDOM_LONG(95,105) ); - -#define RANDOM_SOUND_ARRAY( array ) (array) [ RANDOM_LONG(0,ARRAYSIZE( (array) )-1) ] - - -#define PLAYBACK_EVENT( flags, who, index ) PLAYBACK_EVENT_FULL( flags, who, index, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); -#define PLAYBACK_EVENT_DELAY( flags, who, index, delay ) PLAYBACK_EVENT_FULL( flags, who, index, delay, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); - -#define GROUP_OP_AND 0 -#define GROUP_OP_NAND 1 - -extern int g_groupmask; -extern int g_groupop; - -class UTIL_GroupTrace -{ -public: - UTIL_GroupTrace( int groupmask, int op ); - ~UTIL_GroupTrace( void ); - -private: - int m_oldgroupmask, m_oldgroupop; -}; - -void UTIL_SetGroupTrace( int groupmask, int op ); -void UTIL_UnsetGroupTrace( void ); - -int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); -float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ); - -float UTIL_WeaponTimeBase( void ); - -typedef enum { - RED = 1, - BLUE, - GREEN, - YELLOW, - WHITE -} printcolor_t; - -typedef enum { - F_IN_OUT, - CREDITS, - SCANOUT -} printeffect_t; - -typedef enum { - - WIN_MSG, - CRITICAL, - INFO, - LEADER_HIT, - MISC_SHIT, - CHASECAM, - CHASECAM_TARGET, - NOTIFY, - -} effectchannel_t; - -extern void EffectPrint( CBasePlayer *pPlayer, int color, int effect, int channel, char *text ); diff --git a/dmc/dlls/vector.h b/dmc/dlls/vector.h deleted file mode 100644 index 9f475b0..0000000 --- a/dmc/dlls/vector.h +++ /dev/null @@ -1,112 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef VECTOR_H -#define VECTOR_H - -//========================================================= -// 2DVector - used for many pathfinding and many other -// operations that are treated as planar rather than 3d. -//========================================================= -class Vector2D -{ -public: - inline Vector2D(void) { } - inline Vector2D(float X, float Y) { x = X; y = Y; } - inline Vector2D operator+(const Vector2D& v) const { return Vector2D(x+v.x, y+v.y); } - inline Vector2D operator-(const Vector2D& v) const { return Vector2D(x-v.x, y-v.y); } - inline Vector2D operator*(float fl) const { return Vector2D(x*fl, y*fl); } - inline Vector2D operator/(float fl) const { return Vector2D(x/fl, y/fl); } - - inline float Length(void) const { return sqrt(x*x + y*y ); } - - inline Vector2D Normalize ( void ) const - { - Vector2D vec2; - - float flLen = Length(); - if ( flLen == 0 ) - { - return Vector2D( 0, 0 ); - } - else - { - flLen = 1 / flLen; - return Vector2D( x * flLen, y * flLen ); - } - } - - vec_t x, y; -}; - -inline float DotProduct(const Vector2D& a, const Vector2D& b) { return( a.x*b.x + a.y*b.y ); } -inline Vector2D operator*(float fl, const Vector2D& v) { return v * fl; } - -//========================================================= -// 3D Vector -//========================================================= -class Vector // same data-layout as engine's vec3_t, -{ // which is a vec_t[3] -public: - // Construction/destruction - inline Vector(void) { } - inline Vector(float X, float Y, float Z) { x = X; y = Y; z = Z; } - //inline Vector(double X, double Y, double Z) { x = (float)X; y = (float)Y; z = (float)Z; } - //inline Vector(int X, int Y, int Z) { x = (float)X; y = (float)Y; z = (float)Z; } - inline Vector(const Vector& v) { x = v.x; y = v.y; z = v.z; } - inline Vector(float rgfl[3]) { x = rgfl[0]; y = rgfl[1]; z = rgfl[2]; } - - // Operators - inline Vector operator-(void) const { return Vector(-x,-y,-z); } - inline int operator==(const Vector& v) const { return x==v.x && y==v.y && z==v.z; } - inline int operator!=(const Vector& v) const { return !(*this==v); } - inline Vector operator+(const Vector& v) const { return Vector(x+v.x, y+v.y, z+v.z); } - inline Vector operator-(const Vector& v) const { return Vector(x-v.x, y-v.y, z-v.z); } - inline Vector operator*(float fl) const { return Vector(x*fl, y*fl, z*fl); } - inline Vector operator/(float fl) const { return Vector(x/fl, y/fl, z/fl); } - - // Methods - inline void CopyToArray(float* rgfl) const { rgfl[0] = x, rgfl[1] = y, rgfl[2] = z; } - inline float Length(void) const { return sqrt(x*x + y*y + z*z); } - operator float *() { return &x; } // Vectors will now automatically convert to float * when needed - operator const float *() const { return &x; } // Vectors will now automatically convert to float * when needed - inline Vector Normalize(void) const - { - float flLen = Length(); - if (flLen == 0) return Vector(0,0,1); // ???? - flLen = 1 / flLen; - return Vector(x * flLen, y * flLen, z * flLen); - } - - inline Vector2D Make2D ( void ) const - { - Vector2D Vec2; - - Vec2.x = x; - Vec2.y = y; - - return Vec2; - } - inline float Length2D(void) const { return sqrt(x*x + y*y); } - - // Members - vec_t x, y, z; -}; -inline Vector operator*(float fl, const Vector& v) { return v * fl; } -inline float DotProduct(const Vector& a, const Vector& b) { return(a.x*b.x+a.y*b.y+a.z*b.z); } -inline Vector CrossProduct(const Vector& a, const Vector& b) { return Vector( a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x ); } - - - -#endif diff --git a/dmc/dlls/weapons.cpp b/dmc/dlls/weapons.cpp deleted file mode 100644 index c738476..0000000 --- a/dmc/dlls/weapons.cpp +++ /dev/null @@ -1,1417 +0,0 @@ -/*** -* -* 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. -* -****/ -/* - -===== weapons.cpp ======================================================== - - functions governing the selection/use of weapons for players - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "monsters.h" -#include "weapons.h" -#include "nodes.h" -#include "decals.h" -#include "gamerules.h" -#include "quake_gun.h" - -extern CGraph WorldGraph; -extern int gEvilImpulse101; - - -#define NOT_USED 255 - -DLL_GLOBAL short g_sModelIndexLaser;// holds the index for the laser beam -DLL_GLOBAL const char *g_pModelNameLaser = "sprites/laserbeam.spr"; -DLL_GLOBAL short g_sModelIndexLaserDot;// holds the index for the laser beam dot -DLL_GLOBAL short g_sModelIndexFireball;// holds the index for the fireball -DLL_GLOBAL short g_sModelIndexSmoke;// holds the index for the smoke cloud -DLL_GLOBAL short g_sModelIndexWExplosion;// holds the index for the underwater explosion -DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model -DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for the initial blood -DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for splattered blood - -ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS]; -AmmoInfo CBasePlayerItem::AmmoInfoArray[MAX_AMMO_SLOTS]; - -extern int gmsgCurWeapon; - -MULTIDAMAGE gMultiDamage; - -#define TRACER_FREQ 4 // Tracers fire every fourth bullet - - -//========================================================= -// MaxAmmoCarry - pass in a name and this function will tell -// you the maximum amount of that type of ammunition that a -// player can carry. -//========================================================= -int MaxAmmoCarry( int iszName ) -{ - for ( int i = 0; i < MAX_WEAPONS; i++ ) - { - if ( CBasePlayerItem::ItemInfoArray[i].pszAmmo1 && !strcmp( STRING(iszName), CBasePlayerItem::ItemInfoArray[i].pszAmmo1 ) ) - return CBasePlayerItem::ItemInfoArray[i].iMaxAmmo1; - if ( CBasePlayerItem::ItemInfoArray[i].pszAmmo2 && !strcmp( STRING(iszName), CBasePlayerItem::ItemInfoArray[i].pszAmmo2 ) ) - return CBasePlayerItem::ItemInfoArray[i].iMaxAmmo2; - } - - ALERT( at_console, "MaxAmmoCarry() doesn't recognize '%s'!\n", STRING( iszName ) ); - return -1; -} - - -/* -============================================================================== - -MULTI-DAMAGE - -Collects multiple small damages into a single damage - -============================================================================== -*/ - -// -// ClearMultiDamage - resets the global multi damage accumulator -// -void ClearMultiDamage(void) -{ - gMultiDamage.pEntity = NULL; - gMultiDamage.amount = 0; - gMultiDamage.type = 0; -} - - -// -// ApplyMultiDamage - inflicts contents of global multi damage register on gMultiDamage.pEntity -// -// GLOBALS USED: -// gMultiDamage - -void ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker ) -{ - Vector vecSpot1;//where blood comes from - Vector vecDir;//direction blood should go - TraceResult tr; - - if ( !gMultiDamage.pEntity ) - return; - - gMultiDamage.pEntity->TakeDamage(pevInflictor, pevAttacker, gMultiDamage.amount, gMultiDamage.type ); -} - - -// GLOBALS USED: -// gMultiDamage - -void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType) -{ - if ( !pEntity ) - return; - - gMultiDamage.type |= bitsDamageType; - - if ( pEntity != gMultiDamage.pEntity ) - { - ApplyMultiDamage(pevInflictor,pevInflictor); // UNDONE: wrong attacker! - gMultiDamage.pEntity = pEntity; - gMultiDamage.amount = 0; - } - - gMultiDamage.amount += flDamage; -} - -/* -================ -SpawnBlood -================ -*/ -void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage) -{ - UTIL_BloodDrips( vecSpot, g_vecAttackDir, bloodColor, (int)flDamage ); -} - - -int DamageDecal( CBaseEntity *pEntity, int bitsDamageType ) -{ - if ( !pEntity ) - return (DECAL_GUNSHOT1 + RANDOM_LONG(0,4)); - - return pEntity->DamageDecal( bitsDamageType ); -} - -void DecalGunshot( TraceResult *pTrace, int iBulletType ) -{ - // Is the entity valid - if ( !UTIL_IsValidEntity( pTrace->pHit ) ) - return; - - if ( VARS(pTrace->pHit)->solid == SOLID_BSP || VARS(pTrace->pHit)->movetype == MOVETYPE_PUSHSTEP ) - { - CBaseEntity *pEntity = NULL; - // Decal the wall with a gunshot - if ( !FNullEnt(pTrace->pHit) ) - pEntity = CBaseEntity::Instance(pTrace->pHit); - - switch( iBulletType ) - { - case BULLET_PLAYER_9MM: - case BULLET_MONSTER_9MM: - case BULLET_PLAYER_MP5: - case BULLET_MONSTER_MP5: - case BULLET_PLAYER_BUCKSHOT: - case BULLET_PLAYER_357: - default: - // smoke and decal - UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) ); - break; - case BULLET_MONSTER_12MM: - // smoke and decal - UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) ); - break; - case BULLET_PLAYER_CROWBAR: - // wall decal - UTIL_DecalTrace( pTrace, DamageDecal( pEntity, DMG_CLUB ) ); - break; - } - } -} - - - -// -// EjectBrass - tosses a brass shell from passed origin at passed velocity -// -void EjectBrass ( const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype ) -{ - // FIX: when the player shoots, their gun isn't in the same position as it is on the model other players see. - - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecOrigin ); - WRITE_BYTE( TE_MODEL); - WRITE_COORD( vecOrigin.x); - WRITE_COORD( vecOrigin.y); - WRITE_COORD( vecOrigin.z); - WRITE_COORD( vecVelocity.x); - WRITE_COORD( vecVelocity.y); - WRITE_COORD( vecVelocity.z); - WRITE_ANGLE( rotation ); - WRITE_SHORT( model ); - WRITE_BYTE ( soundtype); - WRITE_BYTE ( 25 );// 2.5 seconds - MESSAGE_END(); -} - - -#if 0 -// UNDONE: This is no longer used? -void ExplodeModel( const Vector &vecOrigin, float speed, int model, int count ) -{ - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecOrigin ); - WRITE_BYTE ( TE_EXPLODEMODEL ); - WRITE_COORD( vecOrigin.x ); - WRITE_COORD( vecOrigin.y ); - WRITE_COORD( vecOrigin.z ); - WRITE_COORD( speed ); - WRITE_SHORT( model ); - WRITE_SHORT( count ); - WRITE_BYTE ( 15 );// 1.5 seconds - MESSAGE_END(); -} -#endif - - -int giAmmoIndex = 0; - -// Precaches the ammo and queues the ammo info for sending to clients -void AddAmmoNameToAmmoRegistry( const char *szAmmoname ) -{ - // make sure it's not already in the registry - for ( int i = 0; i < MAX_AMMO_SLOTS; i++ ) - { - if ( !CBasePlayerItem::AmmoInfoArray[i].pszName) - continue; - - if ( stricmp( CBasePlayerItem::AmmoInfoArray[i].pszName, szAmmoname ) == 0 ) - return; // ammo already in registry, just quite - } - - - giAmmoIndex++; - ASSERT( giAmmoIndex < MAX_AMMO_SLOTS ); - if ( giAmmoIndex >= MAX_AMMO_SLOTS ) - giAmmoIndex = 0; - - CBasePlayerItem::AmmoInfoArray[giAmmoIndex].pszName = szAmmoname; - CBasePlayerItem::AmmoInfoArray[giAmmoIndex].iId = giAmmoIndex; // yes, this info is redundant -} - - -// Precaches the weapon and queues the weapon info for sending to clients -void UTIL_PrecacheOtherWeapon( const char *szClassname ) -{ - edict_t *pent; - - pent = CREATE_NAMED_ENTITY( MAKE_STRING( szClassname ) ); - if ( FNullEnt( pent ) ) - { - ALERT ( at_console, "NULL Ent in UTIL_PrecacheOtherWeapon\n" ); - return; - } - - CBaseEntity *pEntity = CBaseEntity::Instance (VARS( pent )); - - if (pEntity) - { - ItemInfo II; - pEntity->Precache( ); - memset( &II, 0, sizeof II ); - if ( ((CBasePlayerItem*)pEntity)->GetItemInfo( &II ) ) - { - CBasePlayerItem::ItemInfoArray[II.iId] = II; - - if ( II.pszAmmo1 && *II.pszAmmo1 ) - { - AddAmmoNameToAmmoRegistry( II.pszAmmo1 ); - } - - if ( II.pszAmmo2 && *II.pszAmmo2 ) - { - AddAmmoNameToAmmoRegistry( II.pszAmmo2 ); - } - - memset( &II, 0, sizeof II ); - } - } - - REMOVE_ENTITY(pent); -} - -// called by worldspawn -void W_Precache(void) -{ - memset( CBasePlayerItem::ItemInfoArray, 0, sizeof(CBasePlayerItem::ItemInfoArray) ); - memset( CBasePlayerItem::AmmoInfoArray, 0, sizeof(CBasePlayerItem::AmmoInfoArray) ); - giAmmoIndex = 0; - - // quake gun - UTIL_PrecacheOtherWeapon( "weapon_quakegun" ); - AddAmmoNameToAmmoRegistry( "shells" ); - AddAmmoNameToAmmoRegistry( "nails" ); - AddAmmoNameToAmmoRegistry( "rockets" ); - AddAmmoNameToAmmoRegistry( "cells" ); - - // global sprites - g_sModelIndexFireball = PRECACHE_MODEL ("sprites/zerogxplode.spr");// fireball - g_sModelIndexWExplosion = PRECACHE_MODEL ("sprites/WXplo1.spr");// underwater fireball - g_sModelIndexSmoke = PRECACHE_MODEL ("sprites/steam1.spr");// smoke - g_sModelIndexBubbles = PRECACHE_MODEL ("sprites/bubble.spr");//bubbles - g_sModelIndexBloodSpray = PRECACHE_MODEL ("sprites/bloodspray.spr"); // initial blood - g_sModelIndexBloodDrop = PRECACHE_MODEL ("sprites/blood.spr"); // splattered blood - - // used by explosions - PRECACHE_SOUND ("weapons/debris1.wav");// explosion aftermaths - PRECACHE_SOUND ("weapons/debris2.wav");// explosion aftermaths - PRECACHE_SOUND ("weapons/debris3.wav");// explosion aftermaths - - PRECACHE_SOUND ("weapons/grenade_hit1.wav");//grenade - PRECACHE_SOUND ("weapons/grenade_hit2.wav");//grenade - PRECACHE_SOUND ("weapons/grenade_hit3.wav");//grenade - - PRECACHE_SOUND ("weapons/bullet_hit1.wav"); // hit by bullet - PRECACHE_SOUND ("weapons/bullet_hit2.wav"); // hit by bullet - - PRECACHE_SOUND ("items/weapondrop1.wav");// weapon falls to the ground - - PRECACHE_EVENT( 1, "events/shotgun1.sc" ); - PRECACHE_EVENT( 1, "events/shotgun2.sc" ); - PRECACHE_EVENT( 1, "events/axe.sc" ); - PRECACHE_EVENT( 1, "events/axeswing.sc" ); - PRECACHE_EVENT( 1, "events/rocket.sc" ); - PRECACHE_EVENT( 1, "events/grenade.sc" ); - PRECACHE_EVENT( 1, "events/lightning.sc" ); - PRECACHE_EVENT( 1, "events/spike.sc" ); - PRECACHE_EVENT( 1, "events/superspike.sc" ); -} - - - - -TYPEDESCRIPTION CBasePlayerItem::m_SaveData[] = -{ - DEFINE_FIELD( CBasePlayerItem, m_pPlayer, FIELD_CLASSPTR ), - DEFINE_FIELD( CBasePlayerItem, m_pNext, FIELD_CLASSPTR ), - //DEFINE_FIELD( CBasePlayerItem, m_fKnown, FIELD_INTEGER ),Reset to zero on load - DEFINE_FIELD( CBasePlayerItem, m_iId, FIELD_INTEGER ), - // DEFINE_FIELD( CBasePlayerItem, m_iIdPrimary, FIELD_INTEGER ), - // DEFINE_FIELD( CBasePlayerItem, m_iIdSecondary, FIELD_INTEGER ), -}; -IMPLEMENT_SAVERESTORE( CBasePlayerItem, CBaseAnimating ); - - -TYPEDESCRIPTION CBasePlayerWeapon::m_SaveData[] = -{ - DEFINE_FIELD( CBasePlayerWeapon, m_flNextPrimaryAttack, FIELD_TIME ), - DEFINE_FIELD( CBasePlayerWeapon, m_flNextSecondaryAttack, FIELD_TIME ), - DEFINE_FIELD( CBasePlayerWeapon, m_flTimeWeaponIdle, FIELD_TIME ), - DEFINE_FIELD( CBasePlayerWeapon, m_iPrimaryAmmoType, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayerWeapon, m_iSecondaryAmmoType, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayerWeapon, m_iClip, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayerWeapon, m_iDefaultAmmo, FIELD_INTEGER ), -// DEFINE_FIELD( CBasePlayerWeapon, m_iClientClip, FIELD_INTEGER ) , reset to zero on load so hud gets updated correctly -// DEFINE_FIELD( CBasePlayerWeapon, m_iClientWeaponState, FIELD_INTEGER ), reset to zero on load so hud gets updated correctly -}; - -IMPLEMENT_SAVERESTORE( CBasePlayerWeapon, CBasePlayerItem ); - - -void CBasePlayerItem :: SetObjectCollisionBox( void ) -{ - pev->absmin = pev->origin + Vector(-24, -24, 0); - pev->absmax = pev->origin + Vector(24, 24, 16); -} - - -//========================================================= -// Sets up movetype, size, solidtype for a new weapon. -//========================================================= -void CBasePlayerItem :: FallInit( void ) -{ - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_BBOX; - - UTIL_SetOrigin( pev, pev->origin ); - UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0) );//pointsize until it lands on the ground. - - SetTouch( &CBasePlayerItem::DefaultTouch ); - SetThink( &CBasePlayerItem::FallThink ); - - pev->nextthink = gpGlobals->time + 0.1; -} - -//========================================================= -// FallThink - Items that have just spawned run this think -// to catch them when they hit the ground. Once we're sure -// that the object is grounded, we change its solid type -// to trigger and set it in a large box that helps the -// player get it. -//========================================================= -void CBasePlayerItem::FallThink ( void ) -{ - pev->nextthink = gpGlobals->time + 0.1; - - - - if ( pev->flags & FL_ONGROUND ) - { - // clatter if we have an owner (i.e., dropped by someone) - // don't clatter if the gun is waiting to respawn (if it's waiting, it is invisible!) - if ( !FNullEnt( pev->owner ) ) - { - int pitch = 95 + RANDOM_LONG(0,29); - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "items/weapondrop1.wav", 1, ATTN_NORM, 0, pitch); - } - - // lie flat - pev->angles.x = 0; - pev->angles.z = 0; - - Materialize(); - } -} - -//========================================================= -// Materialize - make a CBasePlayerItem visible and tangible -//========================================================= -void CBasePlayerItem::Materialize( void ) -{ - if ( pev->effects & EF_NODRAW ) - { - // 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; - } - - pev->solid = SOLID_TRIGGER; - - UTIL_SetOrigin( pev, pev->origin );// link into world. - SetTouch (&CBasePlayerItem::DefaultTouch); - SetThink (NULL); - -} - -//========================================================= -// AttemptToMaterialize - the item is trying to rematerialize, -// should it do so now or wait longer? -//========================================================= -void CBasePlayerItem::AttemptToMaterialize( void ) -{ - float time = g_pGameRules->FlWeaponTryRespawn( this ); - - if ( time == 0 ) - { - Materialize(); - return; - } - - pev->nextthink = gpGlobals->time + time; -} - -//========================================================= -// CheckRespawn - a player is taking this weapon, should -// it respawn? -//========================================================= -void CBasePlayerItem :: CheckRespawn ( void ) -{ - switch ( g_pGameRules->WeaponShouldRespawn( this ) ) - { - case GR_WEAPON_RESPAWN_YES: - Respawn(); - break; - case GR_WEAPON_RESPAWN_NO: - return; - break; - } -} - -//========================================================= -// Respawn- this item is already in the world, but it is -// invisible and intangible. Make it visible and tangible. -//========================================================= -CBaseEntity* CBasePlayerItem::Respawn( void ) -{ - // make a copy of this weapon that is invisible and inaccessible to players (no touch function). The weapon spawn/respawn code - // will decide when to make the weapon visible and touchable. - CBaseEntity *pNewWeapon = CBaseEntity::Create( (char *)STRING( pev->classname ), g_pGameRules->VecWeaponRespawnSpot( this ), pev->angles, pev->owner ); - - if ( pNewWeapon ) - { - pNewWeapon->pev->effects |= EF_NODRAW;// invisible for now - pNewWeapon->SetTouch( NULL );// no touch - pNewWeapon->SetThink( &CBasePlayerItem::AttemptToMaterialize ); - - DROP_TO_FLOOR ( ENT(pev) ); - - // not a typo! We want to know when the weapon the player just picked up should respawn! This new entity we created is the replacement, - // but when it should respawn is based on conditions belonging to the weapon that was taken. - pNewWeapon->pev->nextthink = g_pGameRules->FlWeaponRespawnTime( this ); - } - else - { - ALERT ( at_console, "Respawn failed to create %s!\n", STRING( pev->classname ) ); - } - - return pNewWeapon; -} - -void CBasePlayerItem::DefaultTouch( CBaseEntity *pOther ) -{ - // if it's not a player, ignore - if ( !pOther->IsPlayer() ) - return; - - CBasePlayer *pPlayer = (CBasePlayer *)pOther; - - // can I have this? - if ( !g_pGameRules->CanHavePlayerItem( pPlayer, this ) ) - { - - if ( gEvilImpulse101 || FClassnameIs( pev, "weapon_quakegun" ) ) - { - UTIL_Remove( this ); - } - return; - } - - if (pOther->AddPlayerItem( this )) - { - AttachToPlayer( pPlayer ); - EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM); - } - - SUB_UseTargets( pOther, USE_TOGGLE, 0 ); // UNDONE: when should this happen? -} - -BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted ) -{ - if ( !isPredicted ) - { - return ( attack_time <= curtime ) ? TRUE : FALSE; - } - else - { - return ( attack_time <= 0.0 ) ? TRUE : FALSE; - } -} - -void CBasePlayerWeapon::ItemPostFrame( void ) -{ - if ((m_fInReload) && ( m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase() ) ) - { - // complete the reload. - int j = V_min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); - - // Add them to the clip - m_iClip += j; - m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j; - - m_fInReload = FALSE; - } - - if ((m_pPlayer->pev->button & IN_ATTACK2) && CanAttack( m_flNextSecondaryAttack, gpGlobals->time, UseDecrement() ) ) - { - if ( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] ) - { - m_fFireOnEmpty = TRUE; - } - - SecondaryAttack(); - m_pPlayer->pev->button &= ~IN_ATTACK2; - } - else if ((m_pPlayer->pev->button & IN_ATTACK) && CanAttack( m_flNextPrimaryAttack, gpGlobals->time, UseDecrement() ) ) - { - if ( (m_iClip == 0 && pszAmmo1()) || (iMaxClip() == -1 && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] ) ) - { - m_fFireOnEmpty = TRUE; - } - - PrimaryAttack(); - } - else if ( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload ) - { - // reload when reload is pressed, or if no buttons are down and weapon is empty. - Reload(); - } - else if ( !(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2) ) ) - { - // no fire buttons down - if ( !m_bPlayedIdleAnim ) - { - m_bPlayedIdleAnim = TRUE; - SendWeaponAnim( 0, 1 ); - - if ( m_pPlayer->m_iQuakeWeapon == IT_LIGHTNING ) - { - PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_pPlayer->m_usLightning, 0, (float *)&m_pPlayer->pev->origin, (float *)&m_pPlayer->pev->angles, 0.0, 0.0, 0, 1, 0, 0 ); - - if ( m_pPlayer->m_pActiveItem ) - ((CQuakeGun*)m_pPlayer->m_pActiveItem)->DestroyEffect(); - } - } - - WeaponIdle( ); - return; - } - - // catch all - if ( ShouldWeaponIdle() ) - { - WeaponIdle(); - } -} - -void CBasePlayerItem::DestroyItem( void ) -{ - if ( m_pPlayer ) - { - // if attached to a player, remove. - m_pPlayer->RemovePlayerItem( this ); - } - - Kill( ); -} - -int CBasePlayerItem::AddToPlayer( CBasePlayer *pPlayer ) -{ - m_pPlayer = pPlayer; - - return TRUE; -} - -void CBasePlayerItem::Drop( void ) -{ - SetTouch( NULL ); - SetThink(&CBasePlayerItem::SUB_Remove); - pev->nextthink = gpGlobals->time + .1; -} - -void CBasePlayerItem::Kill( void ) -{ - SetTouch( NULL ); - SetThink(&CBasePlayerItem::SUB_Remove); - pev->nextthink = gpGlobals->time + .1; -} - -void CBasePlayerItem::Holster( int skiplocal /* = 0 */ ) -{ - m_pPlayer->pev->viewmodel = 0; - m_pPlayer->pev->weaponmodel = 0; -} - -void CBasePlayerItem::AttachToPlayer ( CBasePlayer *pPlayer ) -{ - pev->movetype = MOVETYPE_FOLLOW; - pev->solid = SOLID_NOT; - pev->aiment = pPlayer->edict(); - pev->effects = EF_NODRAW; // ?? - pev->modelindex = 0;// server won't send down to clients if modelindex == 0 - pev->model = iStringNull; - pev->owner = pPlayer->edict(); - pev->nextthink = gpGlobals->time + .1; - SetTouch( NULL ); -} - -// CALLED THROUGH the newly-touched weapon's instance. The existing player weapon is pOriginal -int CBasePlayerWeapon::AddDuplicate( CBasePlayerItem *pOriginal ) -{ - if ( m_iDefaultAmmo ) - { - return ExtractAmmo( (CBasePlayerWeapon *)pOriginal ); - } - else - { - // a dead player dropped this. - return ExtractClipAmmo( (CBasePlayerWeapon *)pOriginal ); - } -} - - -int CBasePlayerWeapon::AddToPlayer( CBasePlayer *pPlayer ) -{ - int bResult = CBasePlayerItem::AddToPlayer( pPlayer ); - - pPlayer->pev->weapons |= (1<GetAmmoIndex( pszAmmo1() ); - m_iSecondaryAmmoType = pPlayer->GetAmmoIndex( pszAmmo2() ); - } - - - if (bResult) - return AddWeapon( ); - return FALSE; -} - -int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer ) -{ - BOOL bSend = FALSE; - int state = 0; - if ( pPlayer->m_pActiveItem == this ) - { - if ( pPlayer->m_fOnTarget ) - state = WEAPON_IS_ONTARGET; - else - state = 1; - } - - // Forcing send of all data! - if ( !pPlayer->m_fWeapon ) - bSend = TRUE; - - // See if the Quake Gun has changed "weapons" - if ( pPlayer->m_iQuakeWeapon != pPlayer->m_iClientQuakeWeapon ) - bSend = TRUE; - - // QUAKECLASSIC - m_iClip = 0; - - int iId; - - switch ( pPlayer->m_iQuakeWeapon ) - { - case IT_AXE: iId = IT_AXE; break; - case IT_SHOTGUN: iId = IT_SHOTGUN; break; - case IT_SUPER_SHOTGUN: iId = IT_SUPER_SHOTGUN; break; - case IT_NAILGUN: iId = IT_NAILGUN; break; - case IT_SUPER_NAILGUN: iId = IT_SUPER_NAILGUN; break; - case IT_GRENADE_LAUNCHER: iId = IT_GRENADE_LAUNCHER; break; - case IT_ROCKET_LAUNCHER: iId = IT_ROCKET_LAUNCHER; break; - case IT_LIGHTNING: iId = IT_LIGHTNING; break; - } - - if ( bSend ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pPlayer->pev ); - WRITE_BYTE( state ); - WRITE_BYTE( iId ); - WRITE_BYTE( m_iClip ); - MESSAGE_END(); - - m_iClientClip = m_iClip; - m_iClientWeaponState = state; - pPlayer->m_fWeapon = TRUE; - } - - if ( m_pNext ) - m_pNext->UpdateClientData( pPlayer ); - - return 1; -} - - -void CBasePlayerWeapon::SendWeaponAnim( int iAnim, int skiplocal ) -{ - m_pPlayer->pev->weaponanim = iAnim; - - if ( skiplocal && ENGINE_CANSKIP( m_pPlayer->edict() ) ) - return; - - MESSAGE_BEGIN( MSG_ONE, SVC_WEAPONANIM, NULL, m_pPlayer->pev ); - WRITE_BYTE( iAnim ); // sequence number - WRITE_BYTE( pev->body ); // weaponmodel bodygroup. - MESSAGE_END(); -} - -BOOL CBasePlayerWeapon :: AddPrimaryAmmo( int iCount, char *szName, int iMaxClip, int iMaxCarry ) -{ - int iIdAmmo; - - if (iMaxClip < 1) - { - m_iClip = -1; - iIdAmmo = m_pPlayer->GiveAmmo( iCount, szName, iMaxCarry ); - } - else if (m_iClip == 0) - { - int i; - i = V_min( m_iClip + iCount, iMaxClip ) - m_iClip; - m_iClip += i; - iIdAmmo = m_pPlayer->GiveAmmo( iCount - i, szName, iMaxCarry ); - } - else - { - iIdAmmo = m_pPlayer->GiveAmmo( iCount, szName, iMaxCarry ); - } - - // m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] = iMaxCarry; // hack for testing - - if (iIdAmmo > 0) - { - m_iPrimaryAmmoType = iIdAmmo; - if (m_pPlayer->HasPlayerItem( this ) ) - { - // play the "got ammo" sound only if we gave some ammo to a player that already had this gun. - // if the player is just getting this gun for the first time, DefaultTouch will play the "picked up gun" sound for us. - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM); - } - } - - return iIdAmmo > 0 ? TRUE : FALSE; -} - - -BOOL CBasePlayerWeapon :: AddSecondaryAmmo( int iCount, char *szName, int iMax ) -{ - int iIdAmmo; - - iIdAmmo = m_pPlayer->GiveAmmo( iCount, szName, iMax ); - - //m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] = iMax; // hack for testing - - if (iIdAmmo > 0) - { - m_iSecondaryAmmoType = iIdAmmo; - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM); - } - return iIdAmmo > 0 ? TRUE : FALSE; -} - -//========================================================= -// IsUseable - this function determines whether or not a -// weapon is useable by the player in its current state. -// (does it have ammo loaded? do I have any ammo for the -// weapon?, etc) -//========================================================= -BOOL CBasePlayerWeapon :: IsUseable( void ) -{ - if ( m_iClip <= 0 ) - { - if ( m_pPlayer->m_rgAmmo[ PrimaryAmmoIndex() ] <= 0 && iMaxAmmo1() != -1 ) - { - // clip is empty (or nonexistant) and the player has no more ammo of this type. - return FALSE; - } - } - - return TRUE; -} - -BOOL CBasePlayerWeapon :: CanDeploy( void ) -{ - BOOL bHasAmmo = 0; - - if ( !pszAmmo1() ) - { - // this weapon doesn't use ammo, can always deploy. - return TRUE; - } - - if ( pszAmmo1() ) - { - bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0); - } - if ( pszAmmo2() ) - { - bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] != 0); - } - if (m_iClip > 0) - { - bHasAmmo |= 1; - } - if (!bHasAmmo) - { - return FALSE; - } - - return TRUE; -} - -BOOL CBasePlayerWeapon :: DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal /* = 0 */ ) -{ - if (!CanDeploy( )) - return FALSE; - - m_bPlayedIdleAnim = FALSE; - - m_pPlayer->pev->viewmodel = MAKE_STRING(szViewModel); - m_pPlayer->pev->weaponmodel = MAKE_STRING(szWeaponModel); - strcpy( m_pPlayer->m_szAnimExtention, szAnimExt ); - SendWeaponAnim( iAnim, skiplocal ); - - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5; - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0; - - return TRUE; -} - - -BOOL CBasePlayerWeapon :: DefaultReload( int iClipSize, int iAnim, float fDelay ) -{ - if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) - return FALSE; - - int j = V_min(iClipSize - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); - - if (j == 0) - return FALSE; - - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + fDelay; - - //!!UNDONE -- reload sound goes here !!! - SendWeaponAnim( iAnim ); - - m_fInReload = TRUE; - - m_flTimeWeaponIdle = gpGlobals->time + 3; - return TRUE; -} - -BOOL CBasePlayerWeapon :: PlayEmptySound( void ) -{ - if (m_iPlayEmptySound) - { - EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/357_cock1.wav", 0.8, ATTN_NORM); - m_iPlayEmptySound = 0; - return 0; - } - return 0; -} - -void CBasePlayerWeapon :: ResetEmptySound( void ) -{ - m_iPlayEmptySound = 1; -} - -//========================================================= -//========================================================= -int CBasePlayerWeapon::PrimaryAmmoIndex( void ) -{ - return m_iPrimaryAmmoType; -} - -//========================================================= -//========================================================= -int CBasePlayerWeapon::SecondaryAmmoIndex( void ) -{ - return -1; -} - -void CBasePlayerWeapon::Holster( int skiplocal /* = 0 */ ) -{ - m_fInReload = FALSE; // cancel any reload in progress. - m_pPlayer->pev->viewmodel = 0; - m_pPlayer->pev->weaponmodel = 0; -} - -void CBasePlayerAmmo::Spawn( void ) -{ - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16)); - UTIL_SetOrigin( pev, pev->origin ); - - SetTouch( &CBasePlayerAmmo::DefaultTouch ); -} - -CBaseEntity* CBasePlayerAmmo::Respawn( void ) -{ - pev->effects |= EF_NODRAW; - SetTouch( NULL ); - - UTIL_SetOrigin( pev, g_pGameRules->VecAmmoRespawnSpot( this ) );// move to wherever I'm supposed to repawn. - - SetThink( &CBasePlayerAmmo::Materialize ); - pev->nextthink = g_pGameRules->FlAmmoRespawnTime( this ); - - return this; -} - -void CBasePlayerAmmo::Materialize( void ) -{ - if ( pev->effects & EF_NODRAW ) - { - // 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( &CBasePlayerAmmo::DefaultTouch ); -} - -void CBasePlayerAmmo :: DefaultTouch( CBaseEntity *pOther ) -{ - if ( !pOther->IsPlayer() ) - { - return; - } - - if (AddAmmo( pOther )) - { - if ( g_pGameRules->AmmoShouldRespawn( this ) == GR_AMMO_RESPAWN_YES ) - { - Respawn(); - } - else - { - SetTouch( NULL ); - SetThink(&CBasePlayerAmmo::SUB_Remove); - pev->nextthink = gpGlobals->time + .1; - } - } - else if (gEvilImpulse101) - { - // evil impulse 101 hack, kill always - SetTouch( NULL ); - SetThink(&CBasePlayerAmmo::SUB_Remove); - pev->nextthink = gpGlobals->time + .1; - } -} - -//========================================================= -// called by the new item with the existing item as parameter -// -// if we call ExtractAmmo(), it's because the player is picking up this type of weapon for -// the first time. If it is spawned by the world, m_iDefaultAmmo will have a default ammo amount in it. -// if this is a weapon dropped by a dying player, has 0 m_iDefaultAmmo, which means only the ammo in -// the weapon clip comes along. -//========================================================= -int CBasePlayerWeapon::ExtractAmmo( CBasePlayerWeapon *pWeapon ) -{ - int iReturn = 0; - - if ( pszAmmo1() != NULL ) - { - // blindly call with m_iDefaultAmmo. It's either going to be a value or zero. If it is zero, - // we only get the ammo in the weapon's clip, which is what we want. - iReturn = pWeapon->AddPrimaryAmmo( m_iDefaultAmmo, (char *)pszAmmo1(), iMaxClip(), iMaxAmmo1() ); - m_iDefaultAmmo = 0; - } - - if ( pszAmmo2() != NULL ) - { - iReturn = pWeapon->AddSecondaryAmmo( 0, (char *)pszAmmo2(), iMaxAmmo2() ); - } - - return iReturn; -} - -//========================================================= -// called by the new item's class with the existing item as parameter -//========================================================= -int CBasePlayerWeapon::ExtractClipAmmo( CBasePlayerWeapon *pWeapon ) -{ - int iAmmo; - - if ( m_iClip == WEAPON_NOCLIP ) - { - iAmmo = 0;// guns with no clips always come empty if they are second-hand - } - else - { - iAmmo = m_iClip; - } - - return pWeapon->m_pPlayer->GiveAmmo( iAmmo, (char *)pszAmmo1(), iMaxAmmo1() ); // , &m_iPrimaryAmmoType -} - -//========================================================= -// RetireWeapon - no more ammo for this gun, put it away. -//========================================================= -void CBasePlayerWeapon::RetireWeapon( void ) -{ - // first, no viewmodel at all. - m_pPlayer->pev->viewmodel = iStringNull; - m_pPlayer->pev->weaponmodel = iStringNull; - //m_pPlayer->pev->viewmodelindex = NULL; - - g_pGameRules->GetNextBestWeapon( m_pPlayer, this ); -} - -//********************************************************* -// weaponbox code: -//********************************************************* - -LINK_ENTITY_TO_CLASS( weaponbox, CWeaponBox ); - -TYPEDESCRIPTION CWeaponBox::m_SaveData[] = -{ - DEFINE_ARRAY( CWeaponBox, m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ), - DEFINE_ARRAY( CWeaponBox, m_rgiszAmmo, FIELD_STRING, MAX_AMMO_SLOTS ), - DEFINE_ARRAY( CWeaponBox, m_rgpPlayerItems, FIELD_CLASSPTR, MAX_ITEM_TYPES ), - DEFINE_FIELD( CWeaponBox, m_cAmmoTypes, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CWeaponBox, CBaseEntity ); - -//========================================================= -// -//========================================================= -void CWeaponBox::Precache( void ) -{ - PRECACHE_MODEL("models/w_weaponbox.mdl"); -} - -//========================================================= -//========================================================= -void CWeaponBox :: KeyValue( KeyValueData *pkvd ) -{ - if ( m_cAmmoTypes < MAX_AMMO_SLOTS ) - { - PackAmmo( ALLOC_STRING(pkvd->szKeyName), atoi(pkvd->szValue) ); - m_cAmmoTypes++;// count this new ammo type. - - pkvd->fHandled = TRUE; - } - else - { - ALERT ( at_console, "WeaponBox too full! only %d ammotypes allowed\n", MAX_AMMO_SLOTS ); - } -} - -//========================================================= -// CWeaponBox - Spawn -//========================================================= -void CWeaponBox::Spawn( void ) -{ - Precache( ); - - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - - UTIL_SetSize( pev, g_vecZero, g_vecZero ); - - SET_MODEL( ENT(pev), "models/w_weaponbox.mdl"); -} - -//========================================================= -// CWeaponBox - Kill - the think function that removes the -// box from the world. -//========================================================= -void CWeaponBox::Kill( void ) -{ - CBasePlayerItem *pWeapon; - int i; - - // destroy the weapons - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - pWeapon = m_rgpPlayerItems[ i ]; - - while ( pWeapon ) - { - pWeapon->SetThink(&CBasePlayerItem::SUB_Remove); - pWeapon->pev->nextthink = gpGlobals->time + 0.1; - pWeapon = pWeapon->m_pNext; - } - } - - // remove the box - UTIL_Remove( this ); -} - -//========================================================= -// CWeaponBox - Touch: try to add my contents to the toucher -// if the toucher is a player. -//========================================================= -void CWeaponBox::Touch( CBaseEntity *pOther ) -{ - if ( !(pev->flags & FL_ONGROUND ) ) - { - return; - } - - if ( !pOther->IsPlayer() ) - { - // only players may touch a weaponbox. - return; - } - - if ( !pOther->IsAlive() ) - { - // no dead guys. - return; - } - - CBasePlayer *pPlayer = (CBasePlayer *)pOther; - int i; - -// dole out ammo - for ( i = 0 ; i < MAX_AMMO_SLOTS ; i++ ) - { - if ( !FStringNull( m_rgiszAmmo[ i ] ) ) - { - // there's some ammo of this type. - pPlayer->GiveAmmo( m_rgAmmo[ i ], (char *)STRING( m_rgiszAmmo[ i ] ), MaxAmmoCarry( m_rgiszAmmo[ i ] ) ); - - //ALERT ( at_console, "Gave %d rounds of %s\n", m_rgAmmo[i], STRING(m_rgiszAmmo[i]) ); - - // now empty the ammo from the weaponbox since we just gave it to the player - m_rgiszAmmo[ i ] = iStringNull; - m_rgAmmo[ i ] = 0; - } - } - -// go through my weapons and try to give the usable ones to the player. -// it's important the the player be given ammo first, so the weapons code doesn't refuse -// to deploy a better weapon that the player may pick up because he has no ammo for it. - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - if ( m_rgpPlayerItems[ i ] ) - { - CBasePlayerItem *pItem; - - // have at least one weapon in this slot - while ( m_rgpPlayerItems[ i ] ) - { - //ALERT ( at_console, "trying to give %s\n", STRING( m_rgpPlayerItems[ i ]->pev->classname ) ); - - pItem = m_rgpPlayerItems[ i ]; - m_rgpPlayerItems[ i ] = m_rgpPlayerItems[ i ]->m_pNext;// unlink this weapon from the box - - if ( pPlayer->AddPlayerItem( pItem ) ) - { - pItem->AttachToPlayer( pPlayer ); - } - } - } - } - - EMIT_SOUND( pOther->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); - SetTouch(NULL); - UTIL_Remove(this); -} - -//========================================================= -// CWeaponBox - PackWeapon: Add this weapon to the box -//========================================================= -BOOL CWeaponBox::PackWeapon( CBasePlayerItem *pWeapon ) -{ - // is one of these weapons already packed in this box? - if ( HasWeapon( pWeapon ) ) - { - return FALSE;// box can only hold one of each weapon type - } - - if ( pWeapon->m_pPlayer ) - { - if ( !pWeapon->m_pPlayer->RemovePlayerItem( pWeapon ) ) - { - // failed to unhook the weapon from the player! - return FALSE; - } - } - - int iWeaponSlot = pWeapon->iItemSlot(); - - if ( m_rgpPlayerItems[ iWeaponSlot ] ) - { - // there's already one weapon in this slot, so link this into the slot's column - pWeapon->m_pNext = m_rgpPlayerItems[ iWeaponSlot ]; - m_rgpPlayerItems[ iWeaponSlot ] = pWeapon; - } - else - { - // first weapon we have for this slot - m_rgpPlayerItems[ iWeaponSlot ] = pWeapon; - pWeapon->m_pNext = NULL; - } - - pWeapon->pev->spawnflags |= SF_NORESPAWN;// never respawn - pWeapon->pev->movetype = MOVETYPE_NONE; - pWeapon->pev->solid = SOLID_NOT; - pWeapon->pev->effects = EF_NODRAW; - pWeapon->pev->modelindex = 0; - pWeapon->pev->model = iStringNull; - pWeapon->pev->owner = edict(); - pWeapon->SetThink( NULL );// crowbar may be trying to swing again, etc. - pWeapon->SetTouch( NULL ); - pWeapon->m_pPlayer = NULL; - - //ALERT ( at_console, "packed %s\n", STRING(pWeapon->pev->classname) ); - - return TRUE; -} - -//========================================================= -// CWeaponBox - PackAmmo -//========================================================= -BOOL CWeaponBox::PackAmmo( int iszName, int iCount ) -{ - int iMaxCarry; - - if ( FStringNull( iszName ) ) - { - // error here - ALERT ( at_console, "NULL String in PackAmmo!\n" ); - return FALSE; - } - - iMaxCarry = MaxAmmoCarry( iszName ); - - if ( iMaxCarry != -1 && iCount > 0 ) - { - //ALERT ( at_console, "Packed %d rounds of %s\n", iCount, STRING(iszName) ); - GiveAmmo( iCount, (char *)STRING( iszName ), iMaxCarry ); - return TRUE; - } - - return FALSE; -} - -//========================================================= -// CWeaponBox - GiveAmmo -//========================================================= -int CWeaponBox::GiveAmmo( int iCount, char *szName, int iMax, int *pIndex/* = NULL*/ ) -{ - int i; - - for (i = 1; i < MAX_AMMO_SLOTS && !FStringNull( m_rgiszAmmo[i] ); i++) - { - if (stricmp( szName, STRING( m_rgiszAmmo[i])) == 0) - { - if (pIndex) - *pIndex = i; - - int iAdd = V_min( iCount, iMax - m_rgAmmo[i]); - if (iCount == 0 || iAdd > 0) - { - m_rgAmmo[i] += iAdd; - - return i; - } - return -1; - } - } - if (i < MAX_AMMO_SLOTS) - { - if (pIndex) - *pIndex = i; - - m_rgiszAmmo[i] = MAKE_STRING( szName ); - m_rgAmmo[i] = iCount; - - return i; - } - ALERT( at_console, "out of named ammo slots\n"); - return i; -} - -//========================================================= -// CWeaponBox::HasWeapon - is a weapon of this type already -// packed in this box? -//========================================================= -BOOL CWeaponBox::HasWeapon( CBasePlayerItem *pCheckItem ) -{ - CBasePlayerItem *pItem = m_rgpPlayerItems[pCheckItem->iItemSlot()]; - - while (pItem) - { - if (FClassnameIs( pItem->pev, STRING( pCheckItem->pev->classname) )) - { - return TRUE; - } - pItem = pItem->m_pNext; - } - - return FALSE; -} - -//========================================================= -// CWeaponBox::IsEmpty - is there anything in this box? -//========================================================= -BOOL CWeaponBox::IsEmpty( void ) -{ - int i; - - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - if ( m_rgpPlayerItems[ i ] ) - { - return FALSE; - } - } - - for ( i = 0 ; i < MAX_AMMO_SLOTS ; i++ ) - { - if ( !FStringNull( m_rgiszAmmo[ i ] ) ) - { - // still have a bit of this type of ammo - return FALSE; - } - } - - return TRUE; -} - -//========================================================= -//========================================================= -void CWeaponBox::SetObjectCollisionBox( void ) -{ - pev->absmin = pev->origin + Vector(-16, -16, 0); - pev->absmax = pev->origin + Vector(16, 16, 16); -} - -void CBasePlayerWeapon::PrintState( void ) -{ -} - - diff --git a/dmc/dlls/weapons.h b/dmc/dlls/weapons.h deleted file mode 100644 index a3d19d1..0000000 --- a/dmc/dlls/weapons.h +++ /dev/null @@ -1,492 +0,0 @@ -/*** -* -* 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. -* -****/ -#ifndef WEAPONS_H -#define WEAPONS_H - - -class CBasePlayer; -extern int gmsgWeapPickup; - -// Contact Grenade / Timed grenade / Satchel Charge -class CGrenade : public CBaseMonster -{ -public: - void Spawn( void ); - - typedef enum { SATCHEL_DETONATE = 0, SATCHEL_RELEASE } SATCHELCODE; - - static CGrenade *ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time ); - static CGrenade *ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ); - static CGrenade *ShootSatchelCharge( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ); - static void UseSatchelCharges( entvars_t *pevOwner, SATCHELCODE code ); - - void Explode( Vector vecSrc, Vector vecAim ); - void Explode( TraceResult *pTrace, int bitsDamageType ); - void EXPORT Smoke( void ); - - void EXPORT BounceTouch( CBaseEntity *pOther ); - void EXPORT SlideTouch( CBaseEntity *pOther ); - void EXPORT ExplodeTouch( CBaseEntity *pOther ); - void EXPORT DangerSoundThink( void ); - void EXPORT PreDetonate( void ); - void EXPORT Detonate( void ); - void EXPORT DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT TumbleThink( void ); - - virtual void BounceSound( void ); - virtual int BloodColor( void ) { return DONT_BLEED; } - virtual void Killed( entvars_t *pevAttacker, int iGib ); - - BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet. -}; - - -// constant items -#define ITEM_HEALTHKIT 1 -#define ITEM_ANTIDOTE 2 -#define ITEM_SECURITY 3 -#define ITEM_BATTERY 4 - -#define WEAPON_NONE 0 -#define WEAPON_CROWBAR 1 -#define WEAPON_GLOCK 2 -#define WEAPON_PYTHON 3 -#define WEAPON_MP5 4 -#define WEAPON_CHAINGUN 5 -#define WEAPON_CROSSBOW 6 -#define WEAPON_SHOTGUN 7 -#define WEAPON_RPG 8 -#define WEAPON_GAUSS 9 -#define WEAPON_EGON 10 -#define WEAPON_HORNETGUN 11 -#define WEAPON_HANDGRENADE 12 -#define WEAPON_TRIPMINE 13 -#define WEAPON_SATCHEL 14 -#define WEAPON_SNARK 15 - -#define WEAPON_ALLWEAPONS (~(1<skin < 0 || (gpGlobals->deathmatch && FBitSet( pev->spawnflags, SF_DECAL_NOTINDEATHMATCH )) ) - { - REMOVE_ENTITY(ENT(pev)); - return; - } - - if ( FStringNull ( pev->targetname ) ) - { - SetThink( &CDecal::StaticDecal ); - // if there's no targetname, the decal will spray itself on as soon as the world is done spawning. - pev->nextthink = gpGlobals->time; - } - else - { - // if there IS a targetname, the decal sprays itself on when it is triggered. - SetThink ( &CDecal::SUB_DoNothing ); - SetUse(&CDecal::TriggerDecal); - } -} - -void CDecal :: TriggerDecal ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // this is set up as a USE function for infodecals that have targetnames, so that the - // decal doesn't get applied until it is fired. (usually by a scripted sequence) - TraceResult trace; - int entityIndex; - - UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace ); - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY); - WRITE_BYTE( TE_BSPDECAL ); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( (int)pev->skin ); - entityIndex = (short)ENTINDEX(trace.pHit); - WRITE_SHORT( entityIndex ); - if ( entityIndex ) - WRITE_SHORT( (int)VARS(trace.pHit)->modelindex ); - MESSAGE_END(); - - SetThink( &CDecal::SUB_Remove ); - pev->nextthink = gpGlobals->time + 0.1; -} - - -void CDecal :: StaticDecal( void ) -{ - TraceResult trace; - int entityIndex, modelIndex; - - UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace ); - - entityIndex = (short)ENTINDEX(trace.pHit); - if ( entityIndex ) - modelIndex = (int)VARS(trace.pHit)->modelindex; - else - modelIndex = 0; - - g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex ); - - SUB_Remove(); -} - - -void CDecal :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "texture")) - { - pev->skin = DECAL_INDEX( pkvd->szValue ); - - // Found - if ( pev->skin >= 0 ) - return; - ALERT( at_console, "Can't find decal %s\n", pkvd->szValue ); - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -// Body queue class here.... It's really just CBaseEntity -class CCorpse : public CBaseEntity -{ - virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; } -}; - -LINK_ENTITY_TO_CLASS( bodyque, CCorpse ); - -static void InitBodyQue(void) -{ - string_t istrClassname = MAKE_STRING("bodyque"); - - g_pBodyQueueHead = CREATE_NAMED_ENTITY( istrClassname ); - entvars_t *pev = VARS(g_pBodyQueueHead); - - // Reserve 3 more slots for dead bodies - for ( int i = 0; i < 3; i++ ) - { - pev->owner = CREATE_NAMED_ENTITY( istrClassname ); - pev = VARS(pev->owner); - } - - pev->owner = g_pBodyQueueHead; -} - - -// -// make a body que entry for the given ent so the ent can be respawned elsewhere -// -// GLOBALS ASSUMED SET: g_eoBodyQueueHead -// -void CopyToBodyQue(entvars_t *pev) -{ - if (pev->effects & EF_NODRAW) - return; - - entvars_t *pevHead = VARS(g_pBodyQueueHead); - - pevHead->angles = pev->angles; - pevHead->model = pev->model; - pevHead->modelindex = pev->modelindex; - pevHead->frame = pev->frame; - pevHead->colormap = pev->colormap; - pevHead->movetype = MOVETYPE_TOSS; - pevHead->velocity = pev->velocity; - pevHead->flags = 0; - pevHead->deadflag = pev->deadflag; - pevHead->renderfx = kRenderFxDeadPlayer; - pevHead->renderamt = ENTINDEX( ENT( pev ) ); - - pevHead->effects = pev->effects | EF_NOINTERP; - //pevHead->goalstarttime = pev->goalstarttime; - //pevHead->goalframe = pev->goalframe; - //pevHead->goalendtime = pev->goalendtime ; - - pevHead->sequence = pev->sequence; - pevHead->animtime = pev->animtime; - - UTIL_SetOrigin(pevHead, pev->origin); - UTIL_SetSize(pevHead, pev->mins, pev->maxs); - g_pBodyQueueHead = pevHead->owner; -} - - -CGlobalState::CGlobalState( void ) -{ - Reset(); -} - -void CGlobalState::Reset( void ) -{ - m_pList = NULL; - m_listCount = 0; -} - -globalentity_t *CGlobalState :: Find( string_t globalname ) -{ - if ( !globalname ) - return NULL; - - globalentity_t *pTest; - const char *pEntityName = STRING(globalname); - - - pTest = m_pList; - while ( pTest ) - { - if ( FStrEq( pEntityName, pTest->name ) ) - break; - - pTest = pTest->pNext; - } - - return pTest; -} - - -// This is available all the time now on impulse 104, remove later -//#ifdef _DEBUG -void CGlobalState :: DumpGlobals( void ) -{ - static char *estates[] = { "Off", "On", "Dead" }; - globalentity_t *pTest; - - ALERT( at_console, "-- Globals --\n" ); - pTest = m_pList; - while ( pTest ) - { - ALERT( at_console, "%s: %s (%s)\n", pTest->name, pTest->levelName, estates[pTest->state] ); - pTest = pTest->pNext; - } -} -//#endif - - -void CGlobalState :: EntityAdd( string_t globalname, string_t mapName, GLOBALESTATE state ) -{ - ASSERT( !Find(globalname) ); - - globalentity_t *pNewEntity = (globalentity_t *)calloc( sizeof( globalentity_t ), 1 ); - ASSERT( pNewEntity != NULL ); - pNewEntity->pNext = m_pList; - m_pList = pNewEntity; - strcpy( pNewEntity->name, STRING( globalname ) ); - strcpy( pNewEntity->levelName, STRING(mapName) ); - pNewEntity->state = state; - m_listCount++; -} - - -void CGlobalState :: EntitySetState( string_t globalname, GLOBALESTATE state ) -{ - globalentity_t *pEnt = Find( globalname ); - - if ( pEnt ) - pEnt->state = state; -} - - -const globalentity_t *CGlobalState :: EntityFromTable( string_t globalname ) -{ - globalentity_t *pEnt = Find( globalname ); - - return pEnt; -} - - -GLOBALESTATE CGlobalState :: EntityGetState( string_t globalname ) -{ - globalentity_t *pEnt = Find( globalname ); - if ( pEnt ) - return pEnt->state; - - return GLOBAL_OFF; -} - - -// Global Savedata for Delay -TYPEDESCRIPTION CGlobalState::m_SaveData[] = -{ - DEFINE_FIELD( CGlobalState, m_listCount, FIELD_INTEGER ), -}; - -// Global Savedata for Delay -TYPEDESCRIPTION gGlobalEntitySaveData[] = -{ - DEFINE_ARRAY( globalentity_t, name, FIELD_CHARACTER, 64 ), - DEFINE_ARRAY( globalentity_t, levelName, FIELD_CHARACTER, 32 ), - DEFINE_FIELD( globalentity_t, state, FIELD_INTEGER ), -}; - - -int CGlobalState::Save( CSave &save ) -{ - int i; - globalentity_t *pEntity; - - if ( !save.WriteFields( "GLOBAL", this, m_SaveData, ARRAYSIZE(m_SaveData) ) ) - return 0; - - pEntity = m_pList; - for ( i = 0; i < m_listCount && pEntity; i++ ) - { - if ( !save.WriteFields( "GENT", pEntity, gGlobalEntitySaveData, ARRAYSIZE(gGlobalEntitySaveData) ) ) - return 0; - - pEntity = pEntity->pNext; - } - - return 1; -} - -int CGlobalState::Restore( CRestore &restore ) -{ - int i, listCount; - globalentity_t tmpEntity; - - - ClearStates(); - if ( !restore.ReadFields( "GLOBAL", this, m_SaveData, ARRAYSIZE(m_SaveData) ) ) - return 0; - - listCount = m_listCount; // Get new list count - m_listCount = 0; // Clear loaded data - - for ( i = 0; i < listCount; i++ ) - { - if ( !restore.ReadFields( "GENT", &tmpEntity, gGlobalEntitySaveData, ARRAYSIZE(gGlobalEntitySaveData) ) ) - return 0; - EntityAdd( MAKE_STRING(tmpEntity.name), MAKE_STRING(tmpEntity.levelName), tmpEntity.state ); - } - return 1; -} - -void CGlobalState::EntityUpdate( string_t globalname, string_t mapname ) -{ - globalentity_t *pEnt = Find( globalname ); - - if ( pEnt ) - strcpy( pEnt->levelName, STRING(mapname) ); -} - - -void CGlobalState::ClearStates( void ) -{ - globalentity_t *pFree = m_pList; - while ( pFree ) - { - globalentity_t *pNext = pFree->pNext; - free( pFree ); - pFree = pNext; - } - Reset(); -} - - -void SaveGlobalState( SAVERESTOREDATA *pSaveData ) -{ - CSave saveHelper( pSaveData ); - gGlobalState.Save( saveHelper ); -} - - -void RestoreGlobalState( SAVERESTOREDATA *pSaveData ) -{ - CRestore restoreHelper( pSaveData ); - gGlobalState.Restore( restoreHelper ); -} - - -void ResetGlobalState( void ) -{ - gGlobalState.ClearStates(); - gInitHUD = TRUE; // Init the HUD on a new game / load game -} - -// moved CWorld class definition to cbase.h -//======================= -// CWorld -// -// This spawns first when each level begins. -//======================= - -LINK_ENTITY_TO_CLASS( worldspawn, CWorld ); - -#define SF_WORLD_DARK 0x0001 // Fade from black at startup -#define SF_WORLD_TITLE 0x0002 // Display game title at startup -#define SF_WORLD_FORCETEAM 0x0004 // Force teams - -extern DLL_GLOBAL BOOL g_fGameOver; -float g_flWeaponCheat; - -void CWorld :: Spawn( void ) -{ - g_fGameOver = FALSE; - Precache( ); - g_flWeaponCheat = CVAR_GET_FLOAT( "sv_cheats" ); // Is the impulse 101 command allowed? -} - -void CWorld :: Precache( void ) -{ - g_pLastSpawn = NULL; - -#if 1 - CVAR_SET_STRING("sv_gravity", "800"); // 67ft/sec - CVAR_SET_STRING("sv_stepsize", "18"); -#else - CVAR_SET_STRING("sv_gravity", "384"); // 32ft/sec - CVAR_SET_STRING("sv_stepsize", "24"); -#endif - - CVAR_SET_STRING("room_type", "0");// clear DSP - - // QUAKECLASSIC - // Set various physics cvars to Quake's values - CVAR_SET_STRING("sv_friction", "4"); - CVAR_SET_STRING("sv_maxspeed", "400"); - CVAR_SET_STRING("sv_airaccelerate", "0.7"); - - // Set up game rules - if (g_pGameRules) - { - delete g_pGameRules; - } - - g_pGameRules = InstallGameRules( ); - - //!!!UNDONE why is there so much Spawn code in the Precache function? I'll just keep it here - InitBodyQue(); - -// init sentence group playback stuff from sentences.txt. -// ok to call this multiple times, calls after first are ignored. - - SENTENCEG_Init(); - -// init texture type array from materials.txt - - TEXTURETYPE_Init(); - - -// the area based ambient sounds MUST be the first precache_sounds - -// player precaches - W_Precache (); // get weapon precaches - - ClientPrecache(); - - // QUAKECLASSIC - QuakeClassicPrecache(); - -// sounds used from C physics code - PRECACHE_SOUND("common/null.wav"); // clears sound channels - - PRECACHE_SOUND( "items/suitchargeok1.wav" );//!!! temporary sound for respawning weapons. - PRECACHE_SOUND( "items/gunpickup2.wav" );// player picks up a gun. - - PRECACHE_SOUND( "common/bodydrop3.wav" );// dead bodies hitting the ground (animation events) - PRECACHE_SOUND( "common/bodydrop4.wav" ); - - g_Language = (int)CVAR_GET_FLOAT( "sv_language" ); - if ( g_Language == LANGUAGE_GERMAN ) - { - PRECACHE_MODEL( "models/germangibs.mdl" ); - } - else - { - PRECACHE_MODEL( "models/hgibs.mdl" ); - PRECACHE_MODEL( "models/agibs.mdl" ); - } - - PRECACHE_SOUND ("weapons/ric1.wav"); - PRECACHE_SOUND ("weapons/ric2.wav"); - PRECACHE_SOUND ("weapons/ric3.wav"); - PRECACHE_SOUND ("weapons/ric4.wav"); - PRECACHE_SOUND ("weapons/ric5.wav"); -// -// Setup light animation tables. 'a' is total darkness, 'z' is maxbright. -// - - // 0 normal - LIGHT_STYLE(0, "m"); - - // 1 FLICKER (first variety) - LIGHT_STYLE(1, "mmnmmommommnonmmonqnmmo"); - - // 2 SLOW STRONG PULSE - LIGHT_STYLE(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); - - // 3 CANDLE (first variety) - LIGHT_STYLE(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); - - // 4 FAST STROBE - LIGHT_STYLE(4, "mamamamamama"); - - // 5 GENTLE PULSE 1 - LIGHT_STYLE(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); - - // 6 FLICKER (second variety) - LIGHT_STYLE(6, "nmonqnmomnmomomno"); - - // 7 CANDLE (second variety) - LIGHT_STYLE(7, "mmmaaaabcdefgmmmmaaaammmaamm"); - - // 8 CANDLE (third variety) - LIGHT_STYLE(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); - - // 9 SLOW STROBE (fourth variety) - LIGHT_STYLE(9, "aaaaaaaazzzzzzzz"); - - // 10 FLUORESCENT FLICKER - LIGHT_STYLE(10, "mmamammmmammamamaaamammma"); - - // 11 SLOW PULSE NOT FADE TO BLACK - LIGHT_STYLE(11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); - - // 12 UNDERWATER LIGHT MUTATION - // this light only distorts the lightmap - no contribution - // is made to the brightness of affected surfaces - LIGHT_STYLE(12, "mmnnmmnnnmmnn"); - - // styles 32-62 are assigned by the light program for switchable lights - - // 63 testing - LIGHT_STYLE(63, "a"); - - for ( int i = 0; i < ARRAYSIZE(gDecals); i++ ) - gDecals[i].index = DECAL_INDEX( gDecals[i].name ); - -// init the WorldGraph. - WorldGraph.InitGraph(); - -// make sure the .NOD file is newer than the .BSP file. - if ( !WorldGraph.CheckNODFile ( ( char * )STRING( gpGlobals->mapname ) ) ) - {// NOD file is not present, or is older than the BSP file. - WorldGraph.AllocNodes (); - } - else - {// Load the node graph for this level - if ( !WorldGraph.FLoadGraph ( (char *)STRING( gpGlobals->mapname ) ) ) - {// couldn't load, so alloc and prepare to build a graph. - ALERT ( at_console, "*Error opening .NOD file\n" ); - WorldGraph.AllocNodes (); - } - else - { - ALERT ( at_console, "\n*Graph Loaded!\n" ); - } - } - - if ( pev->speed > 0 ) - CVAR_SET_FLOAT( "sv_zmax", pev->speed ); - else - CVAR_SET_FLOAT( "sv_zmax", 4096 ); - - // QUAKECLASSIC: No Fades - /* - if ( pev->netname ) - { - ALERT( at_aiconsole, "Chapter title: %s\n", STRING(pev->netname) ); - CBaseEntity *pEntity = CBaseEntity::Create( "env_message", g_vecZero, g_vecZero, NULL ); - if ( pEntity ) - { - pEntity->SetThink( SUB_CallUseToggle ); - pEntity->pev->message = pev->netname; - pev->netname = 0; - pEntity->pev->nextthink = gpGlobals->time + 0.3; - pEntity->pev->spawnflags = SF_MESSAGE_ONCE; - } - } - */ - - // QUAKECLASSIC: No Darkness - /* - if ( pev->spawnflags & SF_WORLD_DARK ) - CVAR_SET_FLOAT( "v_dark", 1.0 ); - else - CVAR_SET_FLOAT( "v_dark", 0.0 ); - */ - - if ( pev->spawnflags & SF_WORLD_TITLE ) - gDisplayTitle = TRUE; // display the game title if this key is set - else - gDisplayTitle = FALSE; - - if ( pev->spawnflags & SF_WORLD_FORCETEAM ) - { - CVAR_SET_FLOAT( "mp_defaultteam", 1 ); - } - else - { - CVAR_SET_FLOAT( "mp_defaultteam", 0 ); - } -} - - -// -// Just to ignore the "wad" field. -// -void CWorld :: KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "skyname") ) - { - // Sent over net now. - CVAR_SET_STRING( "sv_skyname", pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "sounds") ) - { - gpGlobals->cdAudioTrack = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "WaveHeight") ) - { - // Sent over net now. - pev->scale = atof(pkvd->szValue) * (1.0/8.0); - pkvd->fHandled = TRUE; - CVAR_SET_FLOAT( "sv_wateramp", pev->scale ); - } - else if ( FStrEq(pkvd->szKeyName, "MaxRange") ) - { - pev->speed = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "chaptertitle") ) - { - pev->netname = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "startdark") ) - { - // UNDONE: This is a gross hack!!! The CVAR is NOT sent over the client/sever link - // but it will work for single player - int flag = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - if ( flag ) - pev->spawnflags |= SF_WORLD_DARK; - } - else if ( FStrEq(pkvd->szKeyName, "newunit") ) - { - // Single player only. Clear save directory if set - if ( atoi(pkvd->szValue) ) - CVAR_SET_FLOAT( "sv_newunit", 1 ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "gametitle") ) - { - if ( atoi(pkvd->szValue) ) - pev->spawnflags |= SF_WORLD_TITLE; - - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "mapteams") ) - { - pev->team = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "defaultteam") ) - { - if ( atoi(pkvd->szValue) ) - { - pev->spawnflags |= SF_WORLD_FORCETEAM; - } - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} diff --git a/dmc/pm_shared/pm_debug.cpp b/dmc/pm_shared/pm_debug.cpp deleted file mode 100644 index 4d3a202..0000000 --- a/dmc/pm_shared/pm_debug.cpp +++ /dev/null @@ -1,296 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#include "mathlib.h" -#include "const.h" -#include "usercmd.h" -#include "pm_defs.h" -#include "pm_shared.h" -#include "pm_movevars.h" -#include "pm_debug.h" - -#include - -#pragma warning(disable : 4244) -#pragma warning(disable : 4305) - -extern playermove_t *pmove; - -// Expand debugging BBOX particle hulls by this many units. -#define BOX_GAP 0.0f - -static int PM_boxpnt[6][4] = -{ - { 0, 4, 6, 2 }, // +X - { 0, 1, 5, 4 }, // +Y - { 0, 2, 3, 1 }, // +Z - { 7, 5, 1, 3 }, // -X - { 7, 3, 2, 6 }, // -Y - { 7, 6, 4, 5 }, // -Z -}; - -void PM_ShowClipBox( void ) -{ -#if defined( _DEBUG ) - if ( !pmove->runfuncs ) - return; - - // More debugging, draw the particle bbox for player and for the entity we are looking directly at. - // aslo prints entity info to the console overlay. - if ( !pmove->server ) - return; - - // Draw entity in center of view - // Also draws the normal to the clip plane that intersects our movement ray. Leaves a particle - // trail at the intersection point. - PM_ViewEntity(); - - // Show our BBOX in particles. - //PM_DrawBBox( pmove->player_mins[pmove->usehull], pmove->player_maxs[pmove->usehull], pmove->origin, 132, 0.1 ); -/* - { - int i; - for ( i = 0; i < pmove->numphysent; i++ ) - { - if ( pmove->physents[ i ].info >= 1 && pmove->physents[ i ].info <= 4 ) - { - PM_DrawBBox( pmove->player_mins[pmove->usehull], pmove->player_maxs[pmove->usehull], pmove->physents[i].origin, 132, 0.1 ); - } - } - } -*/ -#endif -} - -/* -=============== -PM_ParticleLine(vec3_t start, vec3_t end, int color, float life) - -================ -*/ -void PM_ParticleLine(vec3_t start, vec3_t end, int pcolor, float life, float vert) -{ - float linestep = 2.0f; - float curdist; - float len; - vec3_t curpos; - vec3_t diff; - int i; - // Determine distance; - - VectorSubtract(end, start, diff); - - len = VectorNormalize(diff); - - curdist = 0; - while (curdist <= len) - { - for (i = 0; i < 3; i++) - curpos[i] = start[i] + curdist * diff[i]; - - pmove->PM_Particle( curpos, pcolor, life, 0, vert); - curdist += linestep; - } - -} - -/* -================ -PM_DrawRectangle(vec3_t tl, vec3_t br) - -================ -*/ -void PM_DrawRectangle(vec3_t tl, vec3_t bl, vec3_t tr, vec3_t br, int pcolor, float life) -{ - PM_ParticleLine(tl, bl, pcolor, life, 0); - PM_ParticleLine(bl, br, pcolor, life, 0); - PM_ParticleLine(br, tr, pcolor, life, 0); - PM_ParticleLine(tr, tl, pcolor, life, 0); -} - -/* -================ -PM_DrawPhysEntBBox(int num) - -================ -*/ -void PM_DrawPhysEntBBox(int num, int pcolor, float life) -{ - physent_t *pe; - vec3_t org; - int j; - vec3_t tmp; - vec3_t p[8]; - float gap = BOX_GAP; - vec3_t modelmins, modelmaxs; - - if (num >= pmove->numphysent || - num <= 0) - return; - - pe = &pmove->physents[num]; - - if (pe->model) - { - VectorCopy(pe->origin, org); - - pmove->PM_GetModelBounds( pe->model, modelmins, modelmaxs ); - for (j = 0; j < 8; j++) - { - tmp[0] = (j & 1) ? modelmins[0] - gap : modelmaxs[0] + gap; - tmp[1] = (j & 2) ? modelmins[1] - gap : modelmaxs[1] + gap; - tmp[2] = (j & 4) ? modelmins[2] - gap : modelmaxs[2] + gap; - - VectorCopy(tmp, p[j]); - } - - // If the bbox should be rotated, do that - if (pe->angles[0] || pe->angles[1] || pe->angles[2]) - { - vec3_t forward, right, up; - - AngleVectorsTranspose(pe->angles, forward, right, up); - for (j = 0; j < 8; j++) - { - VectorCopy(p[j], tmp); - p[j][0] = DotProduct ( tmp, forward ); - p[j][1] = DotProduct ( tmp, right ); - p[j][2] = DotProduct ( tmp, up ); - } - } - - // Offset by entity origin, if any. - for (j = 0; j < 8; j++) - VectorAdd(p[j], org, p[j]); - - for (j = 0; j < 6; j++) - { - PM_DrawRectangle( - p[PM_boxpnt[j][1]], - p[PM_boxpnt[j][0]], - p[PM_boxpnt[j][2]], - p[PM_boxpnt[j][3]], - pcolor, life); - } - } - else - { - for (j = 0; j < 8; j++) - { - tmp[0] = (j & 1) ? pe->mins[0] : pe->maxs[0]; - tmp[1] = (j & 2) ? pe->mins[1] : pe->maxs[1]; - tmp[2] = (j & 4) ? pe->mins[2] : pe->maxs[2]; - - VectorAdd(tmp, pe->origin, tmp); - VectorCopy(tmp, p[j]); - } - - for (j = 0; j < 6; j++) - { - PM_DrawRectangle( - p[PM_boxpnt[j][1]], - p[PM_boxpnt[j][0]], - p[PM_boxpnt[j][2]], - p[PM_boxpnt[j][3]], - pcolor, life); - } - - } -} - -/* -================ -PM_DrawBBox(vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life) - -================ -*/ -void PM_DrawBBox(vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life) -{ - int j; - - vec3_t tmp; - vec3_t p[8]; - float gap = BOX_GAP; - - for (j = 0; j < 8; j++) - { - tmp[0] = (j & 1) ? mins[0] - gap : maxs[0] + gap; - tmp[1] = (j & 2) ? mins[1] - gap : maxs[1] + gap ; - tmp[2] = (j & 4) ? mins[2] - gap : maxs[2] + gap ; - - VectorAdd(tmp, origin, tmp); - VectorCopy(tmp, p[j]); - } - - for (j = 0; j < 6; j++) - { - PM_DrawRectangle( - p[PM_boxpnt[j][1]], - p[PM_boxpnt[j][0]], - p[PM_boxpnt[j][2]], - p[PM_boxpnt[j][3]], - pcolor, life); - } -} - - -#ifndef DEDICATED - -/* -================ -PM_ViewEntity - -Shows a particle trail from player to entity in crosshair. -Shows particles at that entities bbox - -Tries to shoot a ray out by about 128 units. -================ -*/ -void PM_ViewEntity( void ) -{ - vec3_t forward, right, up; - float raydist = 256.0f; - vec3_t origin; - vec3_t end; - int i; - pmtrace_t trace; - int pcolor = 77; - float fup; - -#if 0 - if ( !pm_showclip.value ) - return; -#endif - - AngleVectors (pmove->angles, forward, right, up); // Determine movement angles - - VectorCopy( pmove->origin, origin); - - fup = 0.5*( pmove->player_mins[pmove->usehull][2] + pmove->player_maxs[pmove->usehull][2] ); - fup += pmove->view_ofs[2]; - fup -= 4; - - for (i = 0; i < 3; i++) - { - end[i] = origin[i] + raydist * forward[i]; - } - - trace = pmove->PM_PlayerTrace( origin, end, PM_STUDIO_BOX, -1 ); - - if (trace.ent > 0) // Not the world - { - pcolor = 111; - } - - // Draw the hull or bbox. - if (trace.ent > 0) - { - PM_DrawPhysEntBBox(trace.ent, pcolor, 0.3f); - } -} - -#endif \ No newline at end of file diff --git a/dmc/pm_shared/pm_debug.h b/dmc/pm_shared/pm_debug.h deleted file mode 100644 index 552253f..0000000 --- a/dmc/pm_shared/pm_debug.h +++ /dev/null @@ -1,17 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef PM_DEBUG_H -#define PM_DEBUG_H -#pragma once - -void PM_ViewEntity( void ); -void PM_DrawBBox(vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life); -void PM_ParticleLine(vec3_t start, vec3_t end, int pcolor, float life, float vert); -void PM_ShowClipBox( void ); - -#endif // PMOVEDBG_H \ No newline at end of file diff --git a/dmc/pm_shared/pm_defs.h b/dmc/pm_shared/pm_defs.h deleted file mode 100644 index a8e4045..0000000 --- a/dmc/pm_shared/pm_defs.h +++ /dev/null @@ -1,213 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// pm_defs.h -#if !defined( PM_DEFSH ) -#define PM_DEFSH -#pragma once - -#define MAX_PHYSENTS 600 // Must have room for all entities in the world. -#define MAX_MOVEENTS 64 -#define MAX_CLIP_PLANES 5 - -#define PM_NORMAL 0x00000000 -#define PM_STUDIO_IGNORE 0x00000001 // Skip studio models -#define PM_STUDIO_BOX 0x00000002 // Use boxes for non-complex studio models (even in traceline) -#define PM_GLASS_IGNORE 0x00000004 // Ignore entities with non-normal rendermode -#define PM_WORLD_ONLY 0x00000008 // Only trace against the world - -// Values for flags parameter of PM_TraceLine -#define PM_TRACELINE_ANYVISIBLE 0 -#define PM_TRACELINE_PHYSENTSONLY 1 - -#include "archtypes.h" // DAL -#include "pm_info.h" - -// PM_PlayerTrace results. -#include "pmtrace.h" - -#if !defined ( USERCMD_H ) -#include "usercmd.h" -#endif - - -// physent_t -typedef struct physent_s -{ - char name[32]; // Name of model, or "player" or "world". - int player; - vec3_t origin; // Model's origin in world coordinates. - struct model_s *model; // only for bsp models - struct model_s *studiomodel; // SOLID_BBOX, but studio clip intersections. - vec3_t mins, maxs; // only for non-bsp models - int info; // For client or server to use to identify (index into edicts or cl_entities) - vec3_t angles; // rotated entities need this info for hull testing to work. - - int solid; // Triggers and func_door type WATER brushes are SOLID_NOT - int skin; // BSP Contents for such things like fun_door water brushes. - int rendermode; // So we can ignore glass - - // Complex collision detection. - float frame; - int sequence; - byte controller[4]; - byte blending[2]; - - int movetype; - int takedamage; - int blooddecal; - int team; - int classnumber; - - // For mods - int iuser1; - int iuser2; - int iuser3; - int iuser4; - float fuser1; - float fuser2; - float fuser3; - float fuser4; - vec3_t vuser1; - vec3_t vuser2; - vec3_t vuser3; - vec3_t vuser4; -} physent_t; - -typedef struct playermove_s playermove_t; - -struct playermove_s -{ - int player_index; // So we don't try to run the PM_CheckStuck nudging too quickly. - qboolean server; // For debugging, are we running physics code on server side? - - qboolean multiplayer; // 1 == multiplayer server - float time; // realtime on host, for reckoning duck timing - float frametime; // Duration of this frame - - vec3_t forward, right, up; // Vectors for angles - // player state - vec3_t origin; // Movement origin. - vec3_t angles; // Movement view angles. - vec3_t oldangles; // Angles before movement view angles were looked at. - vec3_t velocity; // Current movement direction. - vec3_t movedir; // For waterjumping, a forced forward velocity so we can fly over lip of ledge. - vec3_t basevelocity; // Velocity of the conveyor we are standing, e.g. - - // For ducking/dead - vec3_t view_ofs; // Our eye position. - float flDuckTime; // Time we started duck - qboolean bInDuck; // In process of ducking or ducked already? - - // For walking/falling - int flTimeStepSound; // Next time we can play a step sound - int iStepLeft; - - float flFallVelocity; - vec3_t punchangle; - - float flSwimTime; - - float flNextPrimaryAttack; - - int effects; // MUZZLE FLASH, e.g. - - int flags; // FL_ONGROUND, FL_DUCKING, etc. - int usehull; // 0 = regular player hull, 1 = ducked player hull, 2 = point hull - float gravity; // Our current gravity and friction. - float friction; - int oldbuttons; // Buttons last usercmd - float waterjumptime; // Amount of time left in jumping out of water cycle. - qboolean dead; // Are we a dead player? - int deadflag; - int spectator; // Should we use spectator physics model? - int movetype; // Our movement type, NOCLIP, WALK, FLY - - int onground; - int waterlevel; - int watertype; - int oldwaterlevel; - - char sztexturename[256]; - char chtexturetype; - - float maxspeed; - float clientmaxspeed; // Player specific maxspeed - - // For mods - int iuser1; - int iuser2; - int iuser3; - int iuser4; - float fuser1; - float fuser2; - float fuser3; - float fuser4; - vec3_t vuser1; - vec3_t vuser2; - vec3_t vuser3; - vec3_t vuser4; - // world state - // Number of entities to clip against. - int numphysent; - physent_t physents[MAX_PHYSENTS]; - // Number of momvement entities (ladders) - int nummoveent; - // just a list of ladders - physent_t moveents[MAX_MOVEENTS]; - - // All things being rendered, for tracing against things you don't actually collide with - int numvisent; - physent_t visents[ MAX_PHYSENTS ]; - - // input to run through physics. - usercmd_t cmd; - - // Trace results for objects we collided with. - int numtouch; - pmtrace_t touchindex[MAX_PHYSENTS]; - - char physinfo[ MAX_PHYSINFO_STRING ]; // Physics info string - - struct movevars_s *movevars; - vec3_t player_mins[4]; - vec3_t player_maxs[4]; - - // Common functions - const char *(*PM_Info_ValueForKey) ( const char *s, const char *key ); - void (*PM_Particle)( vec3_t origin, int color, float life, int zpos, int zvel); - int (*PM_TestPlayerPosition) (vec3_t pos, pmtrace_t *ptrace ); - void (*Con_NPrintf)( int idx, char *fmt, ... ); - void (*Con_DPrintf)( char *fmt, ... ); - void (*Con_Printf)( char *fmt, ... ); - double (*Sys_FloatTime)( void ); - void (*PM_StuckTouch)( int hitent, pmtrace_t *ptraceresult ); - int (*PM_PointContents) (vec3_t p, int *truecontents /*filled in if this is non-null*/ ); - int (*PM_TruePointContents) (vec3_t p); - int (*PM_HullPointContents) ( struct hull_s *hull, int num, vec3_t p); - pmtrace_t (*PM_PlayerTrace) (vec3_t start, vec3_t end, int traceFlags, int ignore_pe ); - struct pmtrace_s *(*PM_TraceLine)( float *start, float *end, int flags, int usehulll, int ignore_pe ); - int32 (*RandomLong)( int32 lLow, int32 lHigh ); - float (*RandomFloat)( float flLow, float flHigh ); - int (*PM_GetModelType)( struct model_s *mod ); - void (*PM_GetModelBounds)( struct model_s *mod, vec3_t mins, vec3_t maxs ); - void *(*PM_HullForBsp)( physent_t *pe, vec3_t offset ); - float (*PM_TraceModel)( physent_t *pEnt, vec3_t start, vec3_t end, trace_t *trace ); - int (*COM_FileSize)(char *filename); - byte *(*COM_LoadFile) (char *path, int usehunk, int *pLength); - void (*COM_FreeFile) ( void *buffer ); - char *(*memfgets)( byte *pMemFile, int fileSize, int *pFilePos, char *pBuffer, int bufferSize ); - - // Functions - // Run functions for this frame? - qboolean runfuncs; - void (*PM_PlaySound) ( int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch ); - const char *(*PM_TraceTexture) ( int ground, vec3_t vstart, vec3_t vend ); - void (*PM_PlaybackEventFull) ( int flags, int clientindex, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); -}; - -#endif diff --git a/dmc/pm_shared/pm_info.h b/dmc/pm_shared/pm_info.h deleted file mode 100644 index e9cc6d3..0000000 --- a/dmc/pm_shared/pm_info.h +++ /dev/null @@ -1,15 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// Physics info string definition -#if !defined( PM_INFOH ) -#define PM_INFOH -#pragma once - -#define MAX_PHYSINFO_STRING 256 - -#endif // PM_INFOH \ No newline at end of file diff --git a/dmc/pm_shared/pm_materials.h b/dmc/pm_shared/pm_materials.h deleted file mode 100644 index ad9aaac..0000000 --- a/dmc/pm_shared/pm_materials.h +++ /dev/null @@ -1,26 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( PM_MATERIALSH ) -#define PM_MATERIALSH -#pragma once - -#define CBTEXTURENAMEMAX 13 // only load first n chars of name - -#define CHAR_TEX_CONCRETE 'C' // texture types -#define CHAR_TEX_METAL 'M' -#define CHAR_TEX_DIRT 'D' -#define CHAR_TEX_VENT 'V' -#define CHAR_TEX_GRATE 'G' -#define CHAR_TEX_TILE 'T' -#define CHAR_TEX_SLOSH 'S' -#define CHAR_TEX_WOOD 'W' -#define CHAR_TEX_COMPUTER 'P' -#define CHAR_TEX_GLASS 'Y' -#define CHAR_TEX_FLESH 'F' - -#endif // !PM_MATERIALSH \ No newline at end of file diff --git a/dmc/pm_shared/pm_math.cpp b/dmc/pm_shared/pm_math.cpp deleted file mode 100644 index a91a1dc..0000000 --- a/dmc/pm_shared/pm_math.cpp +++ /dev/null @@ -1,445 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// mathlib.c -- math primitives - -#include "mathlib.h" -#include "const.h" -#include - -// up / down -#define PITCH 0 -// left / right -#define YAW 1 -// fall over -#define ROLL 2 - -#pragma warning(disable : 4244) - -int nanmask = 255<<23; - -float anglemod(float a) -{ - a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535); - return a; -} - -void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = angles[YAW] * (M_PI*2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = angles[PITCH] * (M_PI*2 / 360); - sp = sin(angle); - cp = cos(angle); - angle = angles[ROLL] * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); - - if (forward) - { - forward[0] = cp*cy; - forward[1] = cp*sy; - forward[2] = -sp; - } - if (right) - { - right[0] = (-1*sr*sp*cy+-1*cr*-sy); - right[1] = (-1*sr*sp*sy+-1*cr*cy); - right[2] = -1*sr*cp; - } - if (up) - { - up[0] = (cr*sp*cy+-sr*-sy); - up[1] = (cr*sp*sy+-sr*cy); - up[2] = cr*cp; - } -} - -void AngleVectorsTranspose (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = angles[YAW] * (M_PI*2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = angles[PITCH] * (M_PI*2 / 360); - sp = sin(angle); - cp = cos(angle); - angle = angles[ROLL] * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); - - if (forward) - { - forward[0] = cp*cy; - forward[1] = (sr*sp*cy+cr*-sy); - forward[2] = (cr*sp*cy+-sr*-sy); - } - if (right) - { - right[0] = cp*sy; - right[1] = (sr*sp*sy+cr*cy); - right[2] = (cr*sp*sy+-sr*cy); - } - if (up) - { - up[0] = -sp; - up[1] = sr*cp; - up[2] = cr*cp; - } -} - - -void AngleMatrix (const float* angles, float (*matrix)[4] ) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = angles[YAW] * (M_PI*2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = angles[PITCH] * (M_PI*2 / 360); - sp = sin(angle); - cp = cos(angle); - angle = angles[ROLL] * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); - - // matrix = (YAW * PITCH) * ROLL - matrix[0][0] = cp*cy; - matrix[1][0] = cp*sy; - matrix[2][0] = -sp; - matrix[0][1] = sr*sp*cy+cr*-sy; - matrix[1][1] = sr*sp*sy+cr*cy; - matrix[2][1] = sr*cp; - matrix[0][2] = (cr*sp*cy+-sr*-sy); - matrix[1][2] = (cr*sp*sy+-sr*cy); - matrix[2][2] = cr*cp; - matrix[0][3] = 0.0; - matrix[1][3] = 0.0; - matrix[2][3] = 0.0; -} - -void AngleIMatrix (const vec3_t angles, float matrix[3][4] ) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = angles[YAW] * (M_PI*2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = angles[PITCH] * (M_PI*2 / 360); - sp = sin(angle); - cp = cos(angle); - angle = angles[ROLL] * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); - - // matrix = (YAW * PITCH) * ROLL - matrix[0][0] = cp*cy; - matrix[0][1] = cp*sy; - matrix[0][2] = -sp; - matrix[1][0] = sr*sp*cy+cr*-sy; - matrix[1][1] = sr*sp*sy+cr*cy; - matrix[1][2] = sr*cp; - matrix[2][0] = (cr*sp*cy+-sr*-sy); - matrix[2][1] = (cr*sp*sy+-sr*cy); - matrix[2][2] = cr*cp; - matrix[0][3] = 0.0; - matrix[1][3] = 0.0; - matrix[2][3] = 0.0; -} - -void NormalizeAngles( float *angles ) -{ - int i; - // Normalize angles - for ( i = 0; i < 3; i++ ) - { - if ( angles[i] > 180.0 ) - { - angles[i] -= 360.0; - } - else if ( angles[i] < -180.0 ) - { - angles[i] += 360.0; - } - } -} - -/* -=================== -InterpolateAngles - -Interpolate Euler angles. -FIXME: Use Quaternions to avoid discontinuities -Frac is 0.0 to 1.0 ( i.e., should probably be clamped, but doesn't have to be ) -=================== -*/ -void InterpolateAngles( float *start, float *end, float *output, float frac ) -{ - int i; - float ang1, ang2; - float d; - - NormalizeAngles( start ); - NormalizeAngles( end ); - - for ( i = 0 ; i < 3 ; i++ ) - { - ang1 = start[i]; - ang2 = end[i]; - - d = ang2 - ang1; - if ( d > 180 ) - { - d -= 360; - } - else if ( d < -180 ) - { - d += 360; - } - - output[i] = ang1 + d * frac; - } - - NormalizeAngles( output ); -} - - -/* -=================== -AngleBetweenVectors - -=================== -*/ -float AngleBetweenVectors( const float * v1, const float * v2 ) -{ - float angle; - float l1 = Length( v1 ); - float l2 = Length( v2 ); - - if ( !l1 || !l2 ) - return 0.0f; - - angle = acos( DotProduct( v1, v2 ) ) / (l1*l2); - angle = ( angle * 180.0f ) / M_PI; - - return angle; -} - -void VectorTransform (const float* in1, float in2[3][4], float* out) -{ - out[0] = DotProduct(in1, in2[0]) + in2[0][3]; - out[1] = DotProduct(in1, in2[1]) + in2[1][3]; - out[2] = DotProduct(in1, in2[2]) + in2[2][3]; -} - - -int VectorCompare (const float* v1, const float* v2) -{ - int i; - - for (i=0 ; i<3 ; i++) - if (v1[i] != v2[i]) - return 0; - - return 1; -} - -void VectorMA (const float* veca, float scale, const float* vecb, float* vecc) -{ - vecc[0] = veca[0] + scale*vecb[0]; - vecc[1] = veca[1] + scale*vecb[1]; - vecc[2] = veca[2] + scale*vecb[2]; -} - - -vec_t _DotProduct (vec3_t v1, vec3_t v2) -{ - return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; -} - -void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out) -{ - out[0] = veca[0]-vecb[0]; - out[1] = veca[1]-vecb[1]; - out[2] = veca[2]-vecb[2]; -} - -void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out) -{ - out[0] = veca[0]+vecb[0]; - out[1] = veca[1]+vecb[1]; - out[2] = veca[2]+vecb[2]; -} - -void _VectorCopy (vec3_t in, vec3_t out) -{ - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; -} - -void CrossProduct (const float* v1, const float* v2, float* cross) -{ - cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; - cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; - cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; -} - -float Length(const float* v) -{ - int i; - float length = 0.0f; - - for (i=0 ; i< 3 ; i++) - length += v[i]*v[i]; - length = sqrt (length); // FIXME - - return length; -} - -float Distance(const float * v1, const float * v2) -{ - vec3_t d; - VectorSubtract(v2,v1,d); - return Length(d); -} - -float VectorNormalize ( float* v) -{ - float length, ilength; - - length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - length = sqrt (length); // FIXME - - if (length) - { - ilength = 1/length; - v[0] *= ilength; - v[1] *= ilength; - v[2] *= ilength; - } - - return length; - -} - -void VectorInverse ( float* v) -{ - v[0] = -v[0]; - v[1] = -v[1]; - v[2] = -v[2]; -} - -void VectorScale (const float* in, float scale, float* out) -{ - out[0] = in[0]*scale; - out[1] = in[1]*scale; - out[2] = in[2]*scale; -} - - -int Q_log2(int val) -{ - int answer=0; - while (val>>=1) - answer++; - return answer; -} - -void VectorMatrix( vec3_t forward, vec3_t right, vec3_t up) -{ - vec3_t tmp; - - if (forward[0] == 0 && forward[1] == 0) - { - right[0] = 1; - right[1] = 0; - right[2] = 0; - up[0] = -forward[2]; - up[1] = 0; - up[2] = 0; - return; - } - - tmp[0] = 0; tmp[1] = 0; tmp[2] = 1.0; - CrossProduct( forward, tmp, right ); - VectorNormalize( right ); - CrossProduct( right, forward, up ); - VectorNormalize( up ); -} - - -void VectorAngles( const float* forward, float* angles ) -{ - double tmp, yaw, pitch; - - if (forward[1] == 0 && forward[0] == 0) - { - yaw = 0; - if (forward[2] > 0) - pitch = 90; - else - pitch = 270; - } - else - { - yaw = (atan2(forward[1], forward[0]) * 180 / M_PI); - if (yaw < 0) - yaw += 360; - - tmp = sqrt (forward[0]*forward[0] + forward[1]*forward[1]); - pitch = (atan2(forward[2], tmp) * 180 / M_PI); - if (pitch < 0) - pitch += 360; - } - - angles[0] = pitch; - angles[1] = yaw; - angles[2] = 0; -} - -/* -================ -ConcatTransforms - -================ -*/ -void ConcatTransforms( float in1[ 3 ][ 4 ], float in2[ 3 ][ 4 ], float out[ 3 ][ 4 ] ) -{ - out[ 0 ][ 0 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 0 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 0 ] + - in1[ 0 ][ 2 ] * in2[ 2 ][ 0 ]; - out[ 0 ][ 1 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 1 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 1 ] + - in1[ 0 ][ 2 ] * in2[ 2 ][ 1 ]; - out[ 0 ][ 2 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 2 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 2 ] + - in1[ 0 ][ 2 ] * in2[ 2 ][ 2 ]; - out[ 0 ][ 3 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 3 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 3 ] + - in1[ 0 ][ 2 ] * in2[ 2 ][ 3 ] + in1[ 0 ][ 3 ]; - out[ 1 ][ 0 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 0 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 0 ] + - in1[ 1 ][ 2 ] * in2[ 2 ][ 0 ]; - out[ 1 ][ 1 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 1 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 1 ] + - in1[ 1 ][ 2 ] * in2[ 2 ][ 1 ]; - out[ 1 ][ 2 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 2 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 2 ] + - in1[ 1 ][ 2 ] * in2[ 2 ][ 2 ]; - out[ 1 ][ 3 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 3 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 3 ] + - in1[ 1 ][ 2 ] * in2[ 2 ][ 3 ] + in1[ 1 ][ 3 ]; - out[ 2 ][ 0 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 0 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 0 ] + - in1[ 2 ][ 2 ] * in2[ 2 ][ 0 ]; - out[ 2 ][ 1 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 1 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 1 ] + - in1[ 2 ][ 2 ] * in2[ 2 ][ 1 ]; - out[ 2 ][ 2 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 2 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 2 ] + - in1[ 2 ][ 2 ] * in2[ 2 ][ 2 ]; - out[ 2 ][ 3 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 3 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 3 ] + - in1[ 2 ][ 2 ] * in2[ 2 ][ 3 ] + in1[ 2 ][ 3 ]; -} diff --git a/dmc/pm_shared/pm_movevars.h b/dmc/pm_shared/pm_movevars.h deleted file mode 100644 index f4f46ca..0000000 --- a/dmc/pm_shared/pm_movevars.h +++ /dev/null @@ -1,47 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// pm_movevars.h -#if !defined( PM_MOVEVARSH ) -#define PM_MOVEVARSH - -// movevars_t // Physics variables. -typedef struct movevars_s movevars_t; - -struct movevars_s -{ - float gravity; // Gravity for map - float stopspeed; // Deceleration when not moving - float maxspeed; // Max allowed speed - float spectatormaxspeed; - float accelerate; // Acceleration factor - float airaccelerate; // Same for when in open air - float wateraccelerate; // Same for when in water - float friction; - float edgefriction; // Extra friction near dropofs - float waterfriction; // Less in water - float entgravity; // 1.0 - float bounce; // Wall bounce value. 1.0 - float stepsize; // sv_stepsize; - float maxvelocity; // maximum server velocity. - float zmax; // Max z-buffer range (for GL) - float waveHeight; // Water wave height (for GL) - qboolean footsteps; // Play footstep sounds - char skyName[32]; // Name of the sky map - float rollangle; - float rollspeed; - float skycolor_r; // Sky color - float skycolor_g; // - float skycolor_b; // - float skyvec_x; // Sky vector - float skyvec_y; // - float skyvec_z; // -}; - -extern movevars_t movevars; - -#endif \ No newline at end of file diff --git a/dmc/pm_shared/pm_shared.cpp b/dmc/pm_shared/pm_shared.cpp deleted file mode 100644 index 8233800..0000000 --- a/dmc/pm_shared/pm_shared.cpp +++ /dev/null @@ -1,2804 +0,0 @@ -/*** -* -* Copyright (c) 1999, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ - -#include "Platform.h" - -#include -#include "mathlib.h" -#include "const.h" -#include "usercmd.h" -#include "pm_defs.h" -#include "pm_shared.h" -#include "pm_movevars.h" -#include "pm_debug.h" -#include // NULL -#include // sqrt -#include // strcpy -#include // atoi -#include // isspace - -#ifdef CLIENT_DLL - // Spectator Mode - int iJumpSpectator; -#ifndef DISABLE_JUMP_ORIGIN - float vJumpOrigin[3]; - float vJumpAngles[3]; -#else - extern float vJumpOrigin[3]; - extern float vJumpAngles[3]; -#endif -#endif - -static int pm_shared_initialized = 0; - -//Because physics code is now compiled as C++ it conflicts with the version in util.cpp -//That version is actually considered to be Vector vec3_origin, so some compilers will fail to link it -//Until the code for vectors is rewritten to allow for a single definition on client and server, this separate version is needed -//TODO: fix -vec3_t shared_vec3_origin = { 0,0,0 }; - -#pragma warning( disable : 4305 ) - -typedef enum {mod_brush, mod_sprite, mod_alias, mod_studio} modtype_t; - -playermove_t *pmove = NULL; - -typedef struct -{ - int planenum; - short children[2]; // negative numbers are contents -} dclipnode_t; - -typedef struct mplane_s -{ - vec3_t normal; // surface normal - float dist; // closest appoach to origin - byte type; // for texture axis selection and fast side tests - byte signbits; // signx + signy<<1 + signz<<1 - byte pad[2]; -} mplane_t; - -typedef struct hull_s -{ - dclipnode_t *clipnodes; - mplane_t *planes; - int firstclipnode; - int lastclipnode; - vec3_t clip_mins; - vec3_t clip_maxs; -} hull_t; - -// Ducking time -#define TIME_TO_DUCK 0.4 -#define VEC_DUCK_HULL_MIN -18 -#define VEC_DUCK_HULL_MAX 18 -#define VEC_DUCK_VIEW 12 -#define PM_DEAD_VIEWHEIGHT -8 -#define MAX_CLIMB_SPEED 200 -#define STUCK_MOVEUP 1 -#define STUCK_MOVEDOWN -1 -#define VEC_HULL_MIN -36 -#define VEC_HULL_MAX 36 -#define VEC_VIEW 28 -#define STOP_EPSILON 0.1 - -#define CTEXTURESMAX 512 // max number of textures loaded -#define CBTEXTURENAMEMAX 13 // only load first n chars of name - -#define CHAR_TEX_CONCRETE 'C' // texture types -#define CHAR_TEX_METAL 'M' -#define CHAR_TEX_DIRT 'D' -#define CHAR_TEX_VENT 'V' -#define CHAR_TEX_GRATE 'G' -#define CHAR_TEX_TILE 'T' -#define CHAR_TEX_SLOSH 'S' -#define CHAR_TEX_WOOD 'W' -#define CHAR_TEX_COMPUTER 'P' -#define CHAR_TEX_GLASS 'Y' -#define CHAR_TEX_FLESH 'F' - -#define STEP_CONCRETE 0 // default step sound -#define STEP_METAL 1 // metal floor -#define STEP_DIRT 2 // dirt, sand, rock -#define STEP_VENT 3 // ventillation duct -#define STEP_GRATE 4 // metal grating -#define STEP_TILE 5 // floor tiles -#define STEP_SLOSH 6 // shallow liquid puddle -#define STEP_WADE 7 // wading in liquid -#define STEP_LADDER 8 // climbing ladder - -#define PLAYER_FATAL_FALL_SPEED 1024// approx 60 feet -#define PLAYER_MAX_SAFE_FALL_SPEED 580// approx 20 feet -#define DAMAGE_FOR_FALL_SPEED (float) 100 / ( PLAYER_FATAL_FALL_SPEED - PLAYER_MAX_SAFE_FALL_SPEED )// damage per unit per second. -#define PLAYER_MIN_BOUNCE_SPEED 200 -#define PLAYER_FALL_PUNCH_THRESHHOLD (float)350 // won't punch player's screen/make scrape noise unless player falling at least this fast. - -#define PLAYER_LONGJUMP_SPEED 350 // how fast we longjump - -// double to float warning -#pragma warning(disable : 4244) -// up / down -#define PITCH 0 -// left / right -#define YAW 1 -// fall over -#define ROLL 2 - -#define MAX_CLIENTS 32 - -#define CONTENTS_CURRENT_0 -9 -#define CONTENTS_CURRENT_90 -10 -#define CONTENTS_CURRENT_180 -11 -#define CONTENTS_CURRENT_270 -12 -#define CONTENTS_CURRENT_UP -13 -#define CONTENTS_CURRENT_DOWN -14 - -#define CONTENTS_TRANSLUCENT -15 - -static vec3_t rgv3tStuckTable[54]; -static int rgStuckLast[MAX_CLIENTS][2]; - -// Texture names -static int gcTextures = 0; -static char grgszTextureName[CTEXTURESMAX][CBTEXTURENAMEMAX]; -static char grgchTextureType[CTEXTURESMAX]; - -int g_onladder = 0; - -void PM_SwapTextures( int i, int j ) -{ - char chTemp; - char szTemp[ CBTEXTURENAMEMAX ]; - - strcpy( szTemp, grgszTextureName[ i ] ); - chTemp = grgchTextureType[ i ]; - - strcpy( grgszTextureName[ i ], grgszTextureName[ j ] ); - grgchTextureType[ i ] = grgchTextureType[ j ]; - - strcpy( grgszTextureName[ j ], szTemp ); - grgchTextureType[ j ] = chTemp; -} - -void PM_SortTextures( void ) -{ - // Bubble sort, yuck, but this only occurs at startup and it's only 512 elements... - // - int i, j; - - for ( i = 0 ; i < gcTextures; i++ ) - { - for ( j = i + 1; j < gcTextures; j++ ) - { - if ( stricmp( grgszTextureName[ i ], grgszTextureName[ j ] ) > 0 ) - { - // Swap - // - PM_SwapTextures( i, j ); - } - } - } -} - -void PM_InitTextureTypes() -{ - char buffer[512]; - int i, j; - byte *pMemFile; - int fileSize, filePos; - static qboolean bTextureTypeInit = false; - - if ( bTextureTypeInit ) - return; - - memset(&(grgszTextureName[0][0]), 0, CTEXTURESMAX * CBTEXTURENAMEMAX); - memset(grgchTextureType, 0, CTEXTURESMAX); - - gcTextures = 0; - memset(buffer, 0, 512); - - fileSize = pmove->COM_FileSize( "sound/materials.txt" ); - pMemFile = pmove->COM_LoadFile( "sound/materials.txt", 5, NULL ); - if ( !pMemFile ) - return; - - filePos = 0; - // for each line in the file... - while ( pmove->memfgets( pMemFile, fileSize, &filePos, buffer, 511 ) != NULL && (gcTextures < CTEXTURESMAX) ) - { - // skip whitespace - i = 0; - while(buffer[i] && isspace(buffer[i])) - i++; - - if (!buffer[i]) - continue; - - // skip comment lines - if (buffer[i] == '/' || !isalpha(buffer[i])) - continue; - - // get texture type - grgchTextureType[gcTextures] = toupper(buffer[i++]); - - // skip whitespace - while(buffer[i] && isspace(buffer[i])) - i++; - - if (!buffer[i]) - continue; - - // get sentence name - j = i; - while (buffer[j] && !isspace(buffer[j])) - j++; - - if (!buffer[j]) - continue; - - // null-terminate name and save in sentences array - j = V_min (j, CBTEXTURENAMEMAX-1+i); - buffer[j] = 0; - strcpy(&(grgszTextureName[gcTextures++][0]), &(buffer[i])); - } - - // Must use engine to free since we are in a .dll - pmove->COM_FreeFile ( pMemFile ); - - PM_SortTextures(); - - bTextureTypeInit = true; -} - -char PM_FindTextureType( char *name ) -{ - int left, right, pivot; - int val; - - assert( pm_shared_initialized ); - - left = 0; - right = gcTextures - 1; - - while ( left <= right ) - { - pivot = ( left + right ) / 2; - - val = strnicmp( name, grgszTextureName[ pivot ], CBTEXTURENAMEMAX-1 ); - if ( val == 0 ) - { - return grgchTextureType[ pivot ]; - } - else if ( val > 0 ) - { - left = pivot + 1; - } - else if ( val < 0 ) - { - right = pivot - 1; - } - } - - return CHAR_TEX_CONCRETE; -} -int PM_MapTextureTypeStepType(char chTextureType) -{ - switch (chTextureType) - { - default: - case CHAR_TEX_CONCRETE: return STEP_CONCRETE; - case CHAR_TEX_METAL: return STEP_METAL; - case CHAR_TEX_DIRT: return STEP_DIRT; - case CHAR_TEX_VENT: return STEP_VENT; - case CHAR_TEX_GRATE: return STEP_GRATE; - case CHAR_TEX_TILE: return STEP_TILE; - case CHAR_TEX_SLOSH: return STEP_SLOSH; - } -} - -/* -==================== -PM_CatagorizeTextureType - -Determine texture info for the texture we are standing on. -==================== -*/ -void PM_CatagorizeTextureType( void ) -{ - vec3_t start, end; - const char *pTextureName; - - VectorCopy( pmove->origin, start ); - VectorCopy( pmove->origin, end ); - - // Straight down - end[2] -= 64; - - // Fill in default values, just in case. - pmove->sztexturename[0] = '\0'; - pmove->chtexturetype = CHAR_TEX_CONCRETE; - - pTextureName = pmove->PM_TraceTexture( pmove->onground, start, end ); - if ( !pTextureName ) - return; - - // strip leading '-0' or '+0~' or '{' or '!' - if (*pTextureName == '-' || *pTextureName == '+') - pTextureName += 2; - - if (*pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ') - pTextureName++; - // '}}' - - strcpy( pmove->sztexturename, pTextureName); - pmove->sztexturename[ CBTEXTURENAMEMAX - 1 ] = 0; - - // get texture type - pmove->chtexturetype = PM_FindTextureType( pmove->sztexturename ); -} - -void PM_UpdateStepSound( void ) -{ - int fWalking; - float fvol; - vec3_t knee; - vec3_t feet; - vec3_t center; - float height; - float speed; - float velrun; - float velwalk; - float flduck; - int fLadder; - int step; - - if ( pmove->flTimeStepSound > 0 ) - return; - - if ( pmove->flags & FL_FROZEN ) - return; - - PM_CatagorizeTextureType(); - - speed = Length( pmove->velocity ); - - // determine if we are on a ladder - fLadder = ( pmove->movetype == MOVETYPE_FLY );// IsOnLadder(); - - // UNDONE: need defined numbers for run, walk, crouch, crouch run velocities!!!! - if ( ( pmove->flags & FL_DUCKING) || fLadder ) - { - velwalk = 60; // These constants should be based on cl_movespeedkey * cl_forwardspeed somehow - velrun = 80; // UNDONE: Move walking to server - flduck = 100; - } - else - { - velwalk = 120; - velrun = 210; - flduck = 0; - } - - // If we're on a ladder or on the ground, and we're moving fast enough, - // play step sound. Also, if pmove->flTimeStepSound is zero, get the new - // sound right away - we just started moving in new level. - if ( (fLadder || ( pmove->onground != -1 ) ) && - ( Length( pmove->velocity ) > 0.0 ) && - ( speed >= velwalk || !pmove->flTimeStepSound ) ) - { - fWalking = speed < velrun; - - VectorCopy( pmove->origin, center ); - VectorCopy( pmove->origin, knee ); - VectorCopy( pmove->origin, feet ); - - height = pmove->player_maxs[ pmove->usehull ][ 2 ] - pmove->player_mins[ pmove->usehull ][ 2 ]; - - knee[2] = pmove->origin[2] - 0.3 * height; - feet[2] = pmove->origin[2] - 0.5 * height; - - if ( pmove->PM_PointContents ( knee, NULL ) == CONTENTS_WATER ) - { - step = STEP_WADE; - fvol = 0.65; - pmove->flTimeStepSound = 600; - } - else if ( pmove->PM_PointContents ( feet, NULL ) == CONTENTS_WATER ) - { - step = STEP_SLOSH; - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - } - else - { - // find texture under player, if different from current texture, - // get material type - step = PM_MapTextureTypeStepType( pmove->chtexturetype ); - - switch ( pmove->chtexturetype ) - { - default: - case CHAR_TEX_CONCRETE: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_METAL: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_DIRT: - fvol = fWalking ? 0.25 : 0.55; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_VENT: - fvol = fWalking ? 0.4 : 0.7; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_GRATE: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_TILE: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_SLOSH: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - } - } - - pmove->flTimeStepSound += flduck; // slower step time if ducking - } -} - -/* -================ -PM_AddToTouched - -Add's the trace result to touch list, if contact is not already in list. -================ -*/ -qboolean PM_AddToTouched(pmtrace_t tr, vec3_t impactvelocity) -{ - int i; - - for (i = 0; i < pmove->numtouch; i++) - { - if (pmove->touchindex[i].ent == tr.ent) - break; - } - if (i != pmove->numtouch) // Already in list. - return false; - - VectorCopy( impactvelocity, tr.deltavelocity ); - - if (pmove->numtouch >= MAX_PHYSENTS) - pmove->Con_DPrintf("Too many entities were touched!\n"); - - pmove->touchindex[pmove->numtouch++] = tr; - return true; -} - -/* -================ -PM_CheckVelocity - -See if the player has a bogus velocity value. -================ -*/ -void PM_CheckVelocity () -{ - int i; - -// -// bound velocity -// - for (i=0 ; i<3 ; i++) - { - // See if it's bogus. - if (IS_NAN(pmove->velocity[i])) - { - pmove->Con_Printf ("PM Got a NaN velocity %i\n", i); - pmove->velocity[i] = 0; - } - if (IS_NAN(pmove->origin[i])) - { - pmove->Con_Printf ("PM Got a NaN origin on %i\n", i); - pmove->origin[i] = 0; - } - - // Bound it. - if (pmove->velocity[i] > pmove->movevars->maxvelocity) - { - pmove->Con_DPrintf ("PM Got a velocity too high on %i\n", i); - pmove->velocity[i] = pmove->movevars->maxvelocity; - } - else if (pmove->velocity[i] < -pmove->movevars->maxvelocity) - { - pmove->Con_DPrintf ("PM Got a velocity too low on %i\n", i); - pmove->velocity[i] = -pmove->movevars->maxvelocity; - } - } -} - -/* -================== -PM_ClipVelocity - -Slide off of the impacting object -returns the blocked flags: -0x01 == floor -0x02 == step / wall -================== -*/ -int PM_ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) -{ - float backoff; - float change; - float angle; - int i, blocked; - - angle = normal[ 2 ]; - - blocked = 0x00; // Assume unblocked. - if (angle > 0) // If the plane that is blocking us has a positive z component, then assume it's a floor. - blocked |= 0x01; // - if (!angle) // If the plane has no Z, it is vertical (wall/step) - blocked |= 0x02; // - - // Determine how far along plane to slide based on incoming direction. - // Scale by overbounce factor. - backoff = DotProduct (in, normal) * overbounce; - - for (i=0 ; i<3 ; i++) - { - change = normal[i]*backoff; - out[i] = in[i] - change; - // If out velocity is too small, zero it out. - if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) - out[i] = 0; - } - - // Return blocking flags. - return blocked; -} - -void PM_AddCorrectGravity () -{ - float ent_gravity; - - if ( pmove->waterjumptime ) - return; - - if (pmove->gravity) - ent_gravity = pmove->gravity; - else - ent_gravity = 1.0; - - // Add gravity so they'll be in the correct position during movement - // yes, this 0.5 looks wrong, but it's not. - pmove->velocity[2] -= (ent_gravity * pmove->movevars->gravity * 0.5 * pmove->frametime ); - pmove->velocity[2] += pmove->basevelocity[2] * pmove->frametime; - pmove->basevelocity[2] = 0; - - PM_CheckVelocity(); -} - - -void PM_FixupGravityVelocity () -{ - float ent_gravity; - - if ( pmove->waterjumptime ) - return; - - if (pmove->gravity) - ent_gravity = pmove->gravity; - else - ent_gravity = 1.0; - - // Get the correct velocity for the end of the dt - pmove->velocity[2] -= (ent_gravity * pmove->movevars->gravity * pmove->frametime * 0.5 ); - - PM_CheckVelocity(); -} - -/* -============ -PM_FlyMove - -The basic solid body movement clip that slides along multiple planes -============ -*/ -int PM_FlyMove (void) -{ - int bumpcount, numbumps; - vec3_t dir; - float d; - int numplanes; - vec3_t planes[MAX_CLIP_PLANES]; - vec3_t primal_velocity, original_velocity; - vec3_t new_velocity; - int i, j; - pmtrace_t trace; - vec3_t end; - float time_left, allFraction; - int blocked; - - numbumps = 4; // Bump up to four times - - blocked = 0; // Assume not blocked - numplanes = 0; // and not sliding along any planes - VectorCopy (pmove->velocity, original_velocity); // Store original velocity - VectorCopy (pmove->velocity, primal_velocity); - - allFraction = 0; - time_left = pmove->frametime; // Total time for this movement operation. - - for (bumpcount=0 ; bumpcountvelocity[0] && !pmove->velocity[1] && !pmove->velocity[2]) - break; - - // Assume we can move all the way from the current origin to the - // end point. - for (i=0 ; i<3 ; i++) - end[i] = pmove->origin[i] + time_left * pmove->velocity[i]; - - // See if we can make it from origin to end point. - trace = pmove->PM_PlayerTrace (pmove->origin, end, PM_NORMAL, -1 ); - - allFraction += trace.fraction; - // If we started in a solid object, or we were in solid space - // the whole way, zero out our velocity and return that we - // are blocked by floor and wall. - if (trace.allsolid) - { // entity is trapped in another solid - VectorCopy (shared_vec3_origin, pmove->velocity); - //Con_DPrintf("Trapped 4\n"); - return 4; - } - - // If we moved some portion of the total distance, then - // copy the end position into the pmove->origin and - // zero the plane counter. - if (trace.fraction > 0) - { // actually covered some distance - VectorCopy (trace.endpos, pmove->origin); - VectorCopy (pmove->velocity, original_velocity); - numplanes = 0; - } - - // If we covered the entire distance, we are done - // and can return. - if (trace.fraction == 1) - break; // moved the entire distance - - //if (!trace.ent) - // Sys_Error ("PM_PlayerTrace: !trace.ent"); - - // Save entity that blocked us (since fraction was < 1.0) - // for contact - // Add it if it's not already in the list!!! - PM_AddToTouched(trace, pmove->velocity); - - // If the plane we hit has a high z component in the normal, then - // it's probably a floor - if (trace.plane.normal[2] > 0.7) - { - blocked |= 1; // floor - } - // If the plane has a zero z component in the normal, then it's a - // step or wall - if (!trace.plane.normal[2]) - { - blocked |= 2; // step / wall - //Con_DPrintf("Blocked by %i\n", trace.ent); - } - - // Reduce amount of pmove->frametime left by total time left * fraction - // that we covered. - time_left -= time_left * trace.fraction; - - // Did we run out of planes to clip against? - if (numplanes >= MAX_CLIP_PLANES) - { // this shouldn't really happen - // Stop our movement if so. - VectorCopy (shared_vec3_origin, pmove->velocity); - //Con_DPrintf("Too many planes 4\n"); - - break; - } - - // Set up next clipping plane - VectorCopy (trace.plane.normal, planes[numplanes]); - numplanes++; -// - -// modify original_velocity so it parallels all of the clip planes -// - if ( pmove->movetype == MOVETYPE_WALK && - ((pmove->onground == -1) || (pmove->friction != 1)) ) // relfect player velocity - { - for ( i = 0; i < numplanes; i++ ) - { - if ( planes[i][2] > 0.7 ) - {// floor or slope - PM_ClipVelocity( original_velocity, planes[i], new_velocity, 1 ); - VectorCopy( new_velocity, original_velocity ); - } - else - PM_ClipVelocity( original_velocity, planes[i], new_velocity, 1.0 + pmove->movevars->bounce * (1-pmove->friction) ); - } - - VectorCopy( new_velocity, pmove->velocity ); - VectorCopy( new_velocity, original_velocity ); - } - else - { - for (i=0 ; ivelocity, - 1); - for (j=0 ; jvelocity, planes[j]) < 0) - break; // not ok - } - if (j == numplanes) // Didn't have to clip, so we're ok - break; - } - - // Did we go all the way through plane set - if (i != numplanes) - { // go along this plane - // pmove->velocity is set in clipping call, no need to set again. - ; - } - else - { // go along the crease - if (numplanes != 2) - { - //Con_Printf ("clip velocity, numplanes == %i\n",numplanes); - VectorCopy (shared_vec3_origin, pmove->velocity); - //Con_DPrintf("Trapped 4\n"); - - break; - } - CrossProduct (planes[0], planes[1], dir); - d = DotProduct (dir, pmove->velocity); - VectorScale (dir, d, pmove->velocity ); - } - - // - // if original velocity is against the original velocity, stop dead - // to avoid tiny occilations in sloping corners - // - if (DotProduct (pmove->velocity, primal_velocity) <= 0) - { - //Con_DPrintf("Back\n"); - VectorCopy (shared_vec3_origin, pmove->velocity); - break; - } - } - } - - if ( allFraction == 0 ) - { - VectorCopy (shared_vec3_origin, pmove->velocity); - //Con_DPrintf( "Don't stick\n" ); - } - - return blocked; -} - -/* -============== -PM_Accelerate -============== -*/ -void PM_Accelerate (vec3_t wishdir, float wishspeed, float accel) -{ - int i; - float addspeed, accelspeed, currentspeed; - - // Dead player's don't accelerate - if (pmove->dead) - return; - - // If waterjumping, don't accelerate - if (pmove->waterjumptime) - return; - - // See if we are changing direction a bit - currentspeed = DotProduct (pmove->velocity, wishdir); - - // Reduce wishspeed by the amount of veer. - addspeed = wishspeed - currentspeed; - - // If not going to add any speed, done. - if (addspeed <= 0) - return; - - // Determine amount of accleration. - accelspeed = accel * pmove->frametime * wishspeed * pmove->friction; - - // Cap at addspeed - if (accelspeed > addspeed) - accelspeed = addspeed; - - // Adjust velocity. - for (i=0 ; i<3 ; i++) - { - pmove->velocity[i] += accelspeed * wishdir[i]; - } -} - -/* -===================== -PM_WalkMove - -Only used by players. Moves along the ground when player is a MOVETYPE_WALK. -====================== -*/ -void PM_WalkMove () -{ - int clip; - int oldonground; - int i; - - vec3_t wishvel; - float spd; - float fmove, smove; - vec3_t wishdir; - float wishspeed; - - vec3_t dest, start; - vec3_t original, originalvel; - vec3_t down, downvel; - float downdist, updist; - - pmtrace_t trace; - - // Copy movement amounts - fmove = pmove->cmd.forwardmove; - smove = pmove->cmd.sidemove; - - // Zero out z components of movement vectors - pmove->forward[2] = 0; - pmove->right[2] = 0; - - VectorNormalize (pmove->forward); // Normalize remainder of vectors. - VectorNormalize (pmove->right); // - - for (i=0 ; i<2 ; i++) // Determine x and y parts of velocity - wishvel[i] = pmove->forward[i]*fmove + pmove->right[i]*smove; - - wishvel[2] = 0; // Zero out z part of velocity - - VectorCopy (wishvel, wishdir); // Determine maginitude of speed of move - wishspeed = VectorNormalize(wishdir); - -// -// Clamp to server defined max speed -// - if (wishspeed > pmove->maxspeed) - { - VectorScale (wishvel, pmove->maxspeed/wishspeed, wishvel); - wishspeed = pmove->maxspeed; - } - - // Set pmove velocity - pmove->velocity[2] = 0; - PM_Accelerate (wishdir, wishspeed, pmove->movevars->accelerate); - pmove->velocity[2] = 0; - - // Add in any base velocity to the current velocity. - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity ); - - spd = Length( pmove->velocity ); - - if (spd < 1.0f) - { - VectorClear( pmove->velocity ); - return; - } - - // If we are not moving, do nothing - //if (!pmove->velocity[0] && !pmove->velocity[1] && !pmove->velocity[2]) - // return; - - oldonground = pmove->onground; - -// first try just moving to the destination - dest[0] = pmove->origin[0] + pmove->velocity[0]*pmove->frametime; - dest[1] = pmove->origin[1] + pmove->velocity[1]*pmove->frametime; - dest[2] = pmove->origin[2]; - - // first try moving directly to the next spot - VectorCopy (dest, start); - trace = pmove->PM_PlayerTrace (pmove->origin, dest, PM_NORMAL, -1 ); - // If we made it all the way, then copy trace end - // as new player position. - if (trace.fraction == 1) - { - VectorCopy (trace.endpos, pmove->origin); - return; - } - - if (oldonground == -1 && // Don't walk up stairs if not on ground. - pmove->waterlevel == 0) - return; - - if (pmove->waterjumptime) // If we are jumping out of water, don't do anything more. - return; - - // Try sliding forward both on ground and up 16 pixels - // take the move that goes farthest - VectorCopy (pmove->origin, original); // Save out original pos & - VectorCopy (pmove->velocity, originalvel); // velocity. - - // Slide move - clip = PM_FlyMove (); - - // Copy the results out - VectorCopy (pmove->origin , down); - VectorCopy (pmove->velocity, downvel); - - // Reset original values. - VectorCopy (original, pmove->origin); - - VectorCopy (originalvel, pmove->velocity); - - // Start out up one stair height - VectorCopy (pmove->origin, dest); - dest[2] += pmove->movevars->stepsize; - - trace = pmove->PM_PlayerTrace (pmove->origin, dest, PM_NORMAL, -1 ); - // If we started okay and made it part of the way at least, - // copy the results to the movement start position and then - // run another move try. - if (!trace.startsolid && !trace.allsolid) - { - VectorCopy (trace.endpos, pmove->origin); - } - -// slide move the rest of the way. - clip = PM_FlyMove (); - -// Now try going back down from the end point -// press down the stepheight - VectorCopy (pmove->origin, dest); - dest[2] -= pmove->movevars->stepsize; - - trace = pmove->PM_PlayerTrace (pmove->origin, dest, PM_NORMAL, -1 ); - - // If we are not on the ground any more then - // use the original movement attempt - if ( trace.plane.normal[2] < 0.7) - goto usedown; - // If the trace ended up in empty space, copy the end - // over to the origin. - if (!trace.startsolid && !trace.allsolid) - { - VectorCopy (trace.endpos, pmove->origin); - } - // Copy this origion to up. - VectorCopy (pmove->origin, pmove->up); - - // decide which one went farther - downdist = (down[0] - original[0])*(down[0] - original[0]) - + (down[1] - original[1])*(down[1] - original[1]); - updist = (pmove->up[0] - original[0])*(pmove->up[0] - original[0]) - + (pmove->up[1] - original[1])*(pmove->up[1] - original[1]); - - if (downdist > updist) - { -usedown: - VectorCopy (down , pmove->origin); - VectorCopy (downvel, pmove->velocity); - } else // copy z value from slide move - pmove->velocity[2] = downvel[2]; - -} - -/* -================== -PM_Friction - -Handles both ground friction and water friction -================== -*/ -void PM_Friction (void) -{ - float *vel; - float speed, newspeed, control; - float friction; - float drop; - vec3_t newvel; - - // If we are in water jump cycle, don't apply friction - if (pmove->waterjumptime) - return; - - // Get velocity - vel = pmove->velocity; - - // Calculate speed - speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1] + vel[2]*vel[2]); - - // If too slow, return - if (speed < 0.1f) - { - return; - } - - drop = 0; - -// apply ground friction - if (pmove->onground != -1) // On an entity that is the ground - { - vec3_t start, stop; - pmtrace_t trace; - - start[0] = stop[0] = pmove->origin[0] + vel[0]/speed*16; - start[1] = stop[1] = pmove->origin[1] + vel[1]/speed*16; - start[2] = pmove->origin[2] + pmove->player_mins[pmove->usehull][2]; - stop[2] = start[2] - 34; - - trace = pmove->PM_PlayerTrace (start, stop, PM_NORMAL, -1 ); - - if (trace.fraction == 1.0) - friction = pmove->movevars->friction*pmove->movevars->edgefriction; - else - friction = pmove->movevars->friction; - - // Grab friction value. - //friction = pmove->movevars->friction; - - friction *= pmove->friction; // player friction? - - // Bleed off some speed, but if we have less than the bleed - // threshhold, bleed the theshold amount. - control = (speed < pmove->movevars->stopspeed) ? - pmove->movevars->stopspeed : speed; - // Add the amount to t'he drop amount. - drop += control*friction*pmove->frametime; - } - -// apply water friction -// if (pmove->waterlevel) -// drop += speed * pmove->movevars->waterfriction * waterlevel * pmove->frametime; - -// scale the velocity - newspeed = speed - drop; - if (newspeed < 0) - newspeed = 0; - - // Determine proportion of old speed we are using. - newspeed /= speed; - - // Adjust velocity according to proportion. - newvel[0] = vel[0] * newspeed; - newvel[1] = vel[1] * newspeed; - newvel[2] = vel[2] * newspeed; - - VectorCopy( newvel, pmove->velocity ); -} - -void PM_AirAccelerate (vec3_t wishdir, float wishspeed, float accel) -{ - int i; - float addspeed, accelspeed, currentspeed, wishspd = wishspeed; - - if (pmove->dead) - return; - if (pmove->waterjumptime) - return; - - // Cap speed - //wishspd = VectorNormalize (pmove->wishveloc); - - if (wishspd > 30) - wishspd = 30; - // Determine veer amount - currentspeed = DotProduct (pmove->velocity, wishdir); - // See how much to add - addspeed = wishspd - currentspeed; - // If not adding any, done. - if (addspeed <= 0) - return; - // Determine acceleration speed after acceleration - - // QUAKECLASSIC: accelspeed = accel * wishspeed * pmove->frametime * pmove->friction; - accelspeed = accel * wishspeed * pmove->frametime; - - // Cap it - if (accelspeed > addspeed) - accelspeed = addspeed; - - // Adjust pmove vel. - for (i=0 ; i<3 ; i++) - { - pmove->velocity[i] += accelspeed*wishdir[i]; - } -} - -/* -=================== -PM_WaterMove - -=================== -*/ -void PM_WaterMove (void) -{ - int i; - vec3_t wishvel; - float wishspeed; - vec3_t wishdir; - vec3_t start, dest; - vec3_t temp; - pmtrace_t trace; - - float speed, newspeed, addspeed, accelspeed; - -// -// user intentions -// - for (i=0 ; i<3 ; i++) - wishvel[i] = pmove->forward[i]*pmove->cmd.forwardmove + pmove->right[i]*pmove->cmd.sidemove; - - // Sinking after no other movement occurs - if (!pmove->cmd.forwardmove && !pmove->cmd.sidemove && !pmove->cmd.upmove) - wishvel[2] -= 60; // drift towards bottom - else // Go straight up by upmove amount. - wishvel[2] += pmove->cmd.upmove; - - // Copy it over and determine speed - VectorCopy (wishvel, wishdir); - wishspeed = VectorNormalize(wishdir); - - // Cap speed. - if (wishspeed > pmove->maxspeed) - { - VectorScale (wishvel, pmove->maxspeed/wishspeed, wishvel); - wishspeed = pmove->maxspeed; - } - // Slow us down a bit. - // QUAKECLASSIC: wishspeed *= 0.8; - wishspeed *= 0.7; - - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity); -// Water friction - VectorCopy(pmove->velocity, temp); - speed = VectorNormalize(temp); - if (speed) - { - newspeed = speed - pmove->frametime * speed * pmove->movevars->friction * pmove->friction; - - if (newspeed < 0) - newspeed = 0; - VectorScale (pmove->velocity, newspeed/speed, pmove->velocity); - } - else - newspeed = 0; - -// -// water acceleration -// - if ( wishspeed < 0.1f ) - { - return; - } - - addspeed = wishspeed - newspeed; - if (addspeed > 0) - { - - VectorNormalize(wishvel); - accelspeed = pmove->movevars->accelerate * wishspeed * pmove->frametime * pmove->friction; - if (accelspeed > addspeed) - accelspeed = addspeed; - - for (i = 0; i < 3; i++) - pmove->velocity[i] += accelspeed * wishvel[i]; - } - -// Now move -// assume it is a stair or a slope, so press down from stepheight above - VectorMA (pmove->origin, pmove->frametime, pmove->velocity, dest); - VectorCopy (dest, start); - start[2] += pmove->movevars->stepsize + 1; - trace = pmove->PM_PlayerTrace (start, dest, PM_NORMAL, -1 ); - if (!trace.startsolid && !trace.allsolid) // FIXME: check steep slope? - { // walked up the step, so just keep result and exit - VectorCopy (trace.endpos, pmove->origin); - return; - } - - // Try moving straight along out normal path. - PM_FlyMove (); -} - - -/* -=================== -PM_AirMove - -=================== -*/ -void PM_AirMove (void) -{ - int i; - vec3_t wishvel; - float fmove, smove; - vec3_t wishdir; - float wishspeed; - - // Copy movement amounts - fmove = pmove->cmd.forwardmove; - smove = pmove->cmd.sidemove; - - // Zero out z components of movement vectors - pmove->forward[2] = 0; - pmove->right[2] = 0; - // Renormalize - VectorNormalize (pmove->forward); - VectorNormalize (pmove->right); - - // Determine x and y parts of velocity - for (i=0 ; i<2 ; i++) - { - wishvel[i] = pmove->forward[i]*fmove + pmove->right[i]*smove; - } - // Zero out z part of velocity - wishvel[2] = 0; - - // Determine maginitude of speed of move - VectorCopy (wishvel, wishdir); - wishspeed = VectorNormalize(wishdir); - - // Clamp to server defined max speed - if (wishspeed > pmove->maxspeed) - { - VectorScale (wishvel, pmove->maxspeed/wishspeed, wishvel); - wishspeed = pmove->maxspeed; - } - - // QUAKECLASSIC: PM_AirAccelerate (wishdir, wishspeed, pmove->movevars->airaccelerate); - PM_AirAccelerate (wishdir, wishspeed, pmove->movevars->accelerate); - - // Add in any base velocity to the current velocity. - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity ); - - PM_FlyMove (); -} - -qboolean PM_InWater( void ) -{ - return ( pmove->waterlevel > 1 ); -} - -qboolean PM_CheckWater () -{ - vec3_t point; - int cont; - int truecont; - float height; - float heightover2; - - // Pick a spot just above the players feet. - point[0] = pmove->origin[0] + (pmove->player_mins[pmove->usehull][0] + pmove->player_maxs[pmove->usehull][0]) * 0.5; - point[1] = pmove->origin[1] + (pmove->player_mins[pmove->usehull][1] + pmove->player_maxs[pmove->usehull][1]) * 0.5; - point[2] = pmove->origin[2] + pmove->player_mins[pmove->usehull][2] + 1; - - // Assume that we are not in water at all. - pmove->waterlevel = 0; - pmove->watertype = CONTENTS_EMPTY; - - // Grab point contents. - cont = pmove->PM_PointContents (point, &truecont ); - // Are we under water? (not solid and not empty?) - if (cont <= CONTENTS_WATER && cont > CONTENTS_TRANSLUCENT ) - { - // Set water type - pmove->watertype = cont; - - // We are at least at level one - pmove->waterlevel = 1; - - height = (pmove->player_mins[pmove->usehull][2] + pmove->player_maxs[pmove->usehull][2]); - heightover2 = height * 0.5; - - // Now check a point that is at the player hull midpoint. - point[2] = pmove->origin[2] + heightover2; - cont = pmove->PM_PointContents (point, NULL ); - // If that point is also under water... - if (cont <= CONTENTS_WATER && cont > CONTENTS_TRANSLUCENT ) - { - // Set a higher water level. - pmove->waterlevel = 2; - - // Now check the eye position. (view_ofs is relative to the origin) - point[2] = pmove->origin[2] + pmove->view_ofs[2]; - - cont = pmove->PM_PointContents (point, NULL ); - if (cont <= CONTENTS_WATER && cont > CONTENTS_TRANSLUCENT ) - pmove->waterlevel = 3; // In over our eyes - } - - // Adjust velocity based on water current, if any. - if ( ( truecont <= CONTENTS_CURRENT_0 ) && - ( truecont >= CONTENTS_CURRENT_DOWN ) ) - { - // The deeper we are, the stronger the current. - static vec3_t current_table[] = - { - {1, 0, 0}, {0, 1, 0}, {-1, 0, 0}, - {0, -1, 0}, {0, 0, 1}, {0, 0, -1} - }; - - VectorMA (pmove->basevelocity, 50.0*pmove->waterlevel, current_table[CONTENTS_CURRENT_0 - truecont], pmove->basevelocity); - } - } - - return pmove->waterlevel > 1; -} - -/* -============= -PM_CatagorizePosition -============= -*/ -void PM_CatagorizePosition (void) -{ - vec3_t point; - pmtrace_t tr; - -// if the player hull point one unit down is solid, the player -// is on ground - -// see if standing on something solid - - // Doing this before we move may introduce a potential latency in water detection, but - // doing it after can get us stuck on the bottom in water if the amount we move up - // is less than the 1 pixel 'threshold' we're about to snap to. Also, we'll call - // this several times per frame, so we really need to avoid sticking to the bottom of - // water on each call, and the converse case will correct itself if called twice. - PM_CheckWater(); - - point[0] = pmove->origin[0]; - point[1] = pmove->origin[1]; - point[2] = pmove->origin[2] - 2; - - if (pmove->velocity[2] > 180) // Shooting up really fast. Definitely not on ground. - { - pmove->onground = -1; - } - else - { - // Try and move down. - tr = pmove->PM_PlayerTrace (pmove->origin, point, PM_NORMAL, -1 ); - // If we hit a steep plane, we are not on ground - if ( tr.plane.normal[2] < 0.7) - pmove->onground = -1; // too steep - else - pmove->onground = tr.ent; // Otherwise, point to index of ent under us. - - // If we are on something... - if (pmove->onground != -1) - { - // Then we are not in water jump sequence - pmove->waterjumptime = 0; - // If we could make the move, drop us down that 1 pixel - // QUAKECLASSIC: - //if (!tr.startsolid && !tr.allsolid) - if ( pmove->waterlevel < 2 && !tr.startsolid && !tr.allsolid ) - VectorCopy (tr.endpos, pmove->origin); - } - - // Standing on an entity other than the world - if (tr.ent > 0) // So signal that we are touching something. - { - PM_AddToTouched(tr, pmove->velocity); - } - } -} - -/* -================= -PM_GetRandomStuckOffsets - -When a player is stuck, it's costly to try and unstick them -Grab a test offset for the player based on a passed in index -================= -*/ -int PM_GetRandomStuckOffsets(int nIndex, int server, vec3_t offset) -{ - // Last time we did a full - int idx; - idx = rgStuckLast[nIndex][server]++; - - VectorCopy(rgv3tStuckTable[idx % 54], offset); - - return (idx % 54); -} - -void PM_ResetStuckOffsets(int nIndex, int server) -{ - rgStuckLast[nIndex][server] = 0; -} - -/* -================= -NudgePosition - -If pmove->origin is in a solid position, -try nudging slightly on all axis to -allow for the cut precision of the net coordinates -================= -*/ -#define PM_CHECKSTUCK_MINTIME 0.05 // Don't check again too quickly. - -int PM_CheckStuck (void) -{ - vec3_t base; - vec3_t offset; - vec3_t test; - int hitent; - int idx; - float fTime; - int i; - pmtrace_t traceresult; - - static float rgStuckCheckTime[MAX_CLIENTS][2]; // Last time we did a full - - // If position is okay, exit - hitent = pmove->PM_TestPlayerPosition (pmove->origin, &traceresult ); - if (hitent == -1 ) - { - PM_ResetStuckOffsets( pmove->player_index, pmove->server ); - return 0; - } - - VectorCopy (pmove->origin, base); - - // - // Deal with precision error in network. - // - if (!pmove->server) - { - // World or BSP model - if ( ( hitent == 0 ) || - ( pmove->physents[hitent].model != NULL ) ) - { - int nReps = 0; - PM_ResetStuckOffsets( pmove->player_index, pmove->server ); - do - { - i = PM_GetRandomStuckOffsets(pmove->player_index, pmove->server, offset); - - VectorAdd(base, offset, test); - if (pmove->PM_TestPlayerPosition (test, &traceresult ) == -1) - { - PM_ResetStuckOffsets( pmove->player_index, pmove->server ); - - VectorCopy ( test, pmove->origin ); - return 0; - } - nReps++; - } while (nReps < 54); - } - } - - // Only an issue on the client. - - if (pmove->server) - idx = 0; - else - idx = 1; - - fTime = pmove->Sys_FloatTime(); - // Too soon? - if (rgStuckCheckTime[pmove->player_index][idx] >= - ( fTime - PM_CHECKSTUCK_MINTIME ) ) - { - return 1; - } - rgStuckCheckTime[pmove->player_index][idx] = fTime; - - pmove->PM_StuckTouch( hitent, &traceresult ); - - i = PM_GetRandomStuckOffsets(pmove->player_index, pmove->server, offset); - - VectorAdd(base, offset, test); - if ( ( hitent = pmove->PM_TestPlayerPosition ( test, NULL ) ) == -1 ) - { - //Con_DPrintf("Nudged\n"); - - PM_ResetStuckOffsets( pmove->player_index, pmove->server ); - - if (i >= 27) - VectorCopy ( test, pmove->origin ); - - return 0; - } - - // If player is flailing while stuck in another player ( should never happen ), then see - // if we can't "unstick" them forceably. - if ( pmove->cmd.buttons & ( IN_JUMP | IN_DUCK | IN_ATTACK ) && ( pmove->physents[ hitent ].player != 0 ) ) - { - float x, y, z; - float xystep = 8.0; - float zstep = 18.0; - float xyminmax = xystep; - float zminmax = 4 * zstep; - - for ( z = 0; z <= zminmax; z += zstep ) - { - for ( x = -xyminmax; x <= xyminmax; x += xystep ) - { - for ( y = -xyminmax; y <= xyminmax; y += xystep ) - { - VectorCopy( base, test ); - test[0] += x; - test[1] += y; - test[2] += z; - - if ( pmove->PM_TestPlayerPosition ( test, NULL ) == -1 ) - { - VectorCopy( test, pmove->origin ); - return 0; - } - } - } - } - } - - //VectorCopy (base, pmove->origin); - - return 1; -} - -/* -=============== -PM_SpectatorMove -=============== -*/ -void PM_SpectatorMove (void) -{ - float speed, drop, friction, control, newspeed; - //float accel; - float currentspeed, addspeed, accelspeed; - int i; - vec3_t wishvel; - float fmove, smove; - vec3_t wishdir; - float wishspeed; - // this routine keeps track of the spectators psoition - // there a two different main move types : track player or moce freely (OBS_ROAMING) - // doesn't need excate track position, only to generate PVS, so just copy - // targets position and real view position is calculated on client (saves server CPU) - -#ifdef CLIENT_DLL - // execute all jumps - if ( iJumpSpectator ) - { - VectorCopy( vJumpOrigin, pmove->origin ); - VectorCopy( vJumpAngles, pmove->angles ); - VectorCopy(shared_vec3_origin, pmove->velocity ); - iJumpSpectator = 0; - return; - } -#endif - - if ( pmove->iuser1 == OBS_ROAMING) - { - // Move around in normal spectator method - - speed = Length (pmove->velocity); - if (speed < 1) - { - VectorCopy (shared_vec3_origin, pmove->velocity) - } - else - { - drop = 0; - - friction = pmove->movevars->friction*1.5; // extra friction - control = speed < pmove->movevars->stopspeed ? pmove->movevars->stopspeed : speed; - drop += control*friction*pmove->frametime; - - // scale the velocity - newspeed = speed - drop; - if (newspeed < 0) - newspeed = 0; - newspeed /= speed; - - VectorScale (pmove->velocity, newspeed, pmove->velocity); - } - - // accelerate - fmove = pmove->cmd.forwardmove; - smove = pmove->cmd.sidemove; - - VectorNormalize (pmove->forward); - VectorNormalize (pmove->right); - - for (i=0 ; i<3 ; i++) - { - wishvel[i] = pmove->forward[i]*fmove + pmove->right[i]*smove; - } - wishvel[2] += pmove->cmd.upmove; - - VectorCopy (wishvel, wishdir); - wishspeed = VectorNormalize(wishdir); - - // - // clamp to server defined max speed - // - if (wishspeed > pmove->movevars->spectatormaxspeed) - { - VectorScale (wishvel, pmove->movevars->spectatormaxspeed/wishspeed, wishvel); - wishspeed = pmove->movevars->spectatormaxspeed; - } - - currentspeed = DotProduct(pmove->velocity, wishdir); - addspeed = wishspeed - currentspeed; - if (addspeed <= 0) - return; - - accelspeed = pmove->movevars->accelerate*pmove->frametime*wishspeed; - if (accelspeed > addspeed) - accelspeed = addspeed; - - for (i=0 ; i<3 ; i++) - pmove->velocity[i] += accelspeed*wishdir[i]; - - // move - VectorMA (pmove->origin, pmove->frametime, pmove->velocity, pmove->origin); - } - else - { - // all other modes just track some kind of target, so spectator PVS = target PVS - - int target; - - // Find the client this player's targeting - for (target = 0; target < pmove->numphysent; target++) - { - if ( pmove->physents[target].info == pmove->iuser2 ) - break; - } - - if (target == pmove->numphysent) - return; - - // use targets position as own origin for PVS - VectorCopy( pmove->physents[target].angles, pmove->angles ); - VectorCopy( pmove->physents[target].origin, pmove->origin ); - - // no velocity - VectorCopy(shared_vec3_origin, pmove->velocity ); - } -} - -/* -================== -PM_SplineFraction - -Use for ease-in, ease-out style interpolation (accel/decel) -Used by ducking code. -================== -*/ -float PM_SplineFraction( float value, float scale ) -{ - float valueSquared; - - value = scale * value; - valueSquared = value * value; - - // Nice little ease-in, ease-out spline-like curve - return 3 * valueSquared - 2 * valueSquared * value; -} - -void PM_FixPlayerCrouchStuck( int direction ) -{ - int hitent; - int i; - vec3_t test; - - hitent = pmove->PM_TestPlayerPosition ( pmove->origin, NULL ); - if (hitent == -1 ) - return; - - VectorCopy( pmove->origin, test ); - for ( i = 0; i < 36; i++ ) - { - pmove->origin[2] += direction; - hitent = pmove->PM_TestPlayerPosition ( pmove->origin, NULL ); - if (hitent == -1 ) - return; - } - - VectorCopy( test, pmove->origin ); // Failed -} - -void PM_WaterJump (void) -{ - if ( pmove->waterjumptime > 10000 ) - { - pmove->waterjumptime = 10000; - } - - if ( !pmove->waterjumptime ) - return; - - pmove->waterjumptime -= pmove->cmd.msec; - if ( pmove->waterjumptime < 0 || - !pmove->waterlevel ) - { - pmove->waterjumptime = 0; - pmove->flags &= ~FL_WATERJUMP; - } - - pmove->velocity[0] = pmove->movedir[0]; - pmove->velocity[1] = pmove->movedir[1]; -} - -/* -============ -PM_AddGravity - -============ -*/ -void PM_AddGravity () -{ - float ent_gravity; - - if (pmove->gravity) - ent_gravity = pmove->gravity; - else - ent_gravity = 1.0; - - // Add gravity incorrectly - pmove->velocity[2] -= (ent_gravity * pmove->movevars->gravity * pmove->frametime ); - pmove->velocity[2] += pmove->basevelocity[2] * pmove->frametime; - pmove->basevelocity[2] = 0; - PM_CheckVelocity(); -} -/* -============ -PM_PushEntity - -Does not change the entities velocity at all -============ -*/ -pmtrace_t PM_PushEntity (vec3_t push) -{ - pmtrace_t trace; - vec3_t end; - - VectorAdd (pmove->origin, push, end); - - trace = pmove->PM_PlayerTrace (pmove->origin, end, PM_NORMAL, -1 ); - - VectorCopy (trace.endpos, pmove->origin); - - // So we can run impact function afterwards. - if (trace.fraction < 1.0 && - !trace.allsolid) - { - PM_AddToTouched(trace, pmove->velocity); - } - - return trace; -} - -/* -============ -PM_Physics_Toss() - -Dead player flying through air., e.g. -============ -*/ -void PM_Physics_Toss() -{ - pmtrace_t trace; - vec3_t move; - float backoff; - - PM_CheckWater(); - - if (pmove->velocity[2] > 0) - pmove->onground = -1; - - // If on ground and not moving, return. - if ( pmove->onground != -1 ) - { - if (VectorCompare(pmove->basevelocity, shared_vec3_origin) && - VectorCompare(pmove->velocity, shared_vec3_origin)) - return; - } - - PM_CheckVelocity (); - -// add gravity - if ( pmove->movetype != MOVETYPE_FLY && - pmove->movetype != MOVETYPE_BOUNCEMISSILE && - pmove->movetype != MOVETYPE_FLYMISSILE ) - PM_AddGravity (); - -// move origin - // Base velocity is not properly accounted for since this entity will move again after the bounce without - // taking it into account - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity); - - PM_CheckVelocity(); - VectorScale (pmove->velocity, pmove->frametime, move); - VectorSubtract (pmove->velocity, pmove->basevelocity, pmove->velocity); - - trace = PM_PushEntity (move); // Should this clear basevelocity - - PM_CheckVelocity(); - - if (trace.allsolid) - { - // entity is trapped in another solid - pmove->onground = trace.ent; - VectorCopy (shared_vec3_origin, pmove->velocity); - return; - } - - if (trace.fraction == 1) - { - PM_CheckWater(); - return; - } - - - if (pmove->movetype == MOVETYPE_BOUNCE) - // QUAKECLASSIC: backoff = 2.0 - pmove->friction; - backoff = 1.5; - // QUAKECLASSIC: else if (pmove->movetype == MOVETYPE_BOUNCEMISSILE) - // QUAKECLASSIC: backoff = 2.0; - else - backoff = 1; - - PM_ClipVelocity (pmove->velocity, trace.plane.normal, pmove->velocity, backoff); - - // stop if on ground - if (trace.plane.normal[2] > 0.7) - { - float vel; - vec3_t base; - - VectorClear( base ); - - // QUAKECLASSIC: No Static friction - /* - if (pmove->velocity[2] < pmove->movevars->gravity * pmove->frametime) - { - // we're rolling on the ground, add static friction. - pmove->onground = trace.ent; - pmove->velocity[2] = 0; - } - */ - - vel = DotProduct( pmove->velocity, pmove->velocity ); - - // Con_DPrintf("%f %f: %.0f %.0f %.0f\n", vel, trace.fraction, ent->velocity[0], ent->velocity[1], ent->velocity[2] ); - - if (vel < (30 * 30) || (pmove->movetype != MOVETYPE_BOUNCE && pmove->movetype != MOVETYPE_BOUNCEMISSILE)) - { - pmove->onground = trace.ent; - VectorCopy (shared_vec3_origin, pmove->velocity); - } - } - -// check for in water - PM_CheckWater(); -} - -/* -==================== -PM_NoClip - -==================== -*/ -void PM_NoClip() -{ - int i; - vec3_t wishvel; - float fmove, smove; - - // Copy movement amounts - fmove = pmove->cmd.forwardmove; - smove = pmove->cmd.sidemove; - - VectorNormalize ( pmove->forward ); - VectorNormalize ( pmove->right ); - - for (i=0 ; i<3 ; i++) // Determine x and y parts of velocity - { - wishvel[i] = pmove->forward[i]*fmove + pmove->right[i]*smove; - } - wishvel[2] += pmove->cmd.upmove; - - VectorMA (pmove->origin, pmove->frametime, wishvel, pmove->origin); - - // Zero out the velocity so that we don't accumulate a huge downward velocity from - // gravity, etc. - VectorClear( pmove->velocity ); - -} - - -// Only allow bunny jumping up to 1.7x server / player maxspeed setting -#define BUNNYJUMP_MAX_SPEED_FACTOR 1.7f - -//----------------------------------------------------------------------------- -// Purpose: Corrects bunny jumping ( where player initiates a bunny jump before other -// movement logic runs, thus making onground == -1 thus making PM_Friction get skipped and -// running PM_AirMove, which doesn't crop velocity to maxspeed like the ground / other -// movement logic does. -//----------------------------------------------------------------------------- -void PM_PreventMegaBunnyJumping( void ) -{ - // Current player speed - float spd; - // If we have to crop, apply this cropping fraction to velocity - float fraction; - // Speed at which bunny jumping is limited - float maxscaledspeed; - - maxscaledspeed = BUNNYJUMP_MAX_SPEED_FACTOR * pmove->maxspeed; - - // Don't divide by zero - if ( maxscaledspeed <= 0.0f ) - return; - - spd = Length( pmove->velocity ); - - if ( spd <= maxscaledspeed ) - return; - - fraction = ( maxscaledspeed / spd ) * 0.65; //Returns the modifier for the velocity - - VectorScale( pmove->velocity, fraction, pmove->velocity ); //Crop it down!. -} - - -/* -============= -PM_Jump -============= -*/ -void PM_Jump (void) -{ - if ( pmove->dead ) - { - pmove->oldbuttons |= IN_JUMP ; // don't jump again until released - return; - } - - if ( pmove->maxspeed == 1 ) - return; - - // See if we are waterjumping. If so, decrement count and return. - if ( pmove->waterjumptime ) - { - pmove->waterjumptime -= pmove->cmd.msec; - if (pmove->waterjumptime < 0) - { - pmove->waterjumptime = 0; - } - return; - } - - // If we are in the water most of the way... - if (pmove->waterlevel >= 2) - { // swimming, not jumping - pmove->onground = -1; - - if (pmove->watertype == CONTENTS_WATER) // We move up a certain amount - pmove->velocity[2] = 100; - else if (pmove->watertype == CONTENTS_SLIME) - pmove->velocity[2] = 80; - else // LAVA - pmove->velocity[2] = 50; - - // play swiming sound - if ( pmove->flSwimTime <= 0 ) - { - // Don't play sound again for 1 second - pmove->flSwimTime = 1000; - switch ( pmove->RandomLong( 0, 3 ) ) - { - case 0: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 1: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade2.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 2: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade3.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 3: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade4.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - } - } - - return; - } - - // No more effect - if ( pmove->onground == -1 ) - { - // Flag that we jumped. - // HACK HACK HACK - // Remove this when the game .dll no longer does physics code!!!! - pmove->oldbuttons |= IN_JUMP; // don't jump again until released - return; // in air, so no effect - } - - if ( pmove->oldbuttons & IN_JUMP ) - return; // don't pogo stick - - // In the air now. - pmove->onground = -1; - - PM_PreventMegaBunnyJumping(); - - pmove->PM_PlaySound( CHAN_BODY, "player/plyrjmp8.wav", 0.5, ATTN_NORM, 0, PITCH_NORM ); - - pmove->velocity[2] += 295; - - // Decay it for simulation - PM_FixupGravityVelocity(); - - // Flag that we jumped. - pmove->oldbuttons |= IN_JUMP; // don't jump again until released -} - -/* -============= -PM_CheckWaterJump -============= -*/ -#define WJ_HEIGHT 8 -void PM_CheckWaterJump (void) -{ - vec3_t vecStart, vecEnd; - vec3_t flatforward; - vec3_t flatvelocity; - float curspeed; - pmtrace_t tr; - int savehull; - - // Already water jumping. - if ( pmove->waterjumptime ) - return; - - // Don't hop out if we just jumped in - if ( pmove->velocity[2] < -180 ) - return; // only hop out if we are moving up - - // See if we are backing up - flatvelocity[0] = pmove->velocity[0]; - flatvelocity[1] = pmove->velocity[1]; - flatvelocity[2] = 0; - - // Must be moving - curspeed = VectorNormalize( flatvelocity ); - - // see if near an edge - flatforward[0] = pmove->forward[0]; - flatforward[1] = pmove->forward[1]; - flatforward[2] = 0; - VectorNormalize (flatforward); - - // Are we backing into water from steps or something? If so, don't pop forward - if ( curspeed != 0.0 && ( DotProduct( flatvelocity, flatforward ) < 0.0 ) ) - return; - - VectorCopy( pmove->origin, vecStart ); - vecStart[2] += WJ_HEIGHT; - - VectorMA ( vecStart, 24, flatforward, vecEnd ); - - // Trace, this trace should use the point sized collision hull - savehull = pmove->usehull; - pmove->usehull = 2; - tr = pmove->PM_PlayerTrace( vecStart, vecEnd, PM_NORMAL, -1 ); - if ( tr.fraction < 1.0 && fabs( tr.plane.normal[2] ) < 0.1f ) // Facing a near vertical wall? - { - vecStart[2] += pmove->player_maxs[ savehull ][2] - WJ_HEIGHT; - VectorMA( vecStart, 24, flatforward, vecEnd ); - VectorMA(shared_vec3_origin, -50, tr.plane.normal, pmove->movedir ); - - tr = pmove->PM_PlayerTrace( vecStart, vecEnd, PM_NORMAL, -1 ); - if ( tr.fraction == 1.0 ) - { - pmove->waterjumptime = 2000; - pmove->velocity[2] = 225; - pmove->oldbuttons |= IN_JUMP; - pmove->flags |= FL_WATERJUMP; - } - } - - // Reset the collision hull - pmove->usehull = savehull; -} - -void PM_CheckFalling( void ) -{ - if ( pmove->onground != -1 && - !pmove->dead && - pmove->flFallVelocity >= PLAYER_FALL_PUNCH_THRESHHOLD ) - { - float fvol = 0.5; - - if ( pmove->waterlevel > 0 ) - { - } - else if ( pmove->flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED ) - { - pmove->PM_PlaySound( CHAN_VOICE, "player/pl_fallpain3.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - fvol = 1.0; - } - else if ( pmove->flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED / 2 ) - { - fvol = 0.85; - } - else if ( pmove->flFallVelocity < PLAYER_MIN_BOUNCE_SPEED ) - { - fvol = 0; - } - - if ( fvol > 0.0 ) - { - // Play landing step right away - pmove->flTimeStepSound = 0; - - PM_UpdateStepSound(); - - // Knock the screen around a little bit, temporary effect - pmove->punchangle[ 2 ] = pmove->flFallVelocity * 0.013; // punch z axis - - if ( pmove->punchangle[ 0 ] > 8 ) - { - pmove->punchangle[ 0 ] = 8; - } - } - } - - if ( pmove->onground != -1 ) - { - pmove->flFallVelocity = 0; - } -} - -/* -================= -PM_PlayWaterSounds - -================= -*/ -void PM_PlayWaterSounds( void ) -{ - // Did we enter or leave water? - if ( ( pmove->oldwaterlevel == 0 && pmove->waterlevel != 0 ) || - ( pmove->oldwaterlevel != 0 && pmove->waterlevel == 0 ) ) - { - switch ( pmove->RandomLong(0,3) ) - { - case 0: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 1: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade2.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 2: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade3.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 3: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade4.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - } - } -} - -/* -=============== -PM_CalcRoll - -=============== -*/ -float PM_CalcRoll (vec3_t angles, vec3_t velocity, float rollangle, float rollspeed ) -{ - float sign; - float side; - float value; - vec3_t forward, right, up; - - AngleVectors (angles, forward, right, up); - - side = DotProduct (velocity, right); - - sign = side < 0 ? -1 : 1; - - side = fabs(side); - - value = rollangle; - - if (side < rollspeed) - { - side = side * value / rollspeed; - } - else - { - side = value; - } - - return side * sign; -} - -/* -============= -PM_DropPunchAngle - -============= -*/ -void PM_DropPunchAngle ( vec3_t punchangle ) -{ - float len; - - len = VectorNormalize ( punchangle ); - len -= (10.0 + len * 0.5) * pmove->frametime; - len = V_max( len, 0.0 ); - VectorScale ( punchangle, len, punchangle); -} - -/* -============== -PM_CheckParamters - -============== -*/ -void PM_CheckParamters( void ) -{ - float spd; - float maxspeed; - vec3_t v_angle; - - spd = ( pmove->cmd.forwardmove * pmove->cmd.forwardmove ) + - ( pmove->cmd.sidemove * pmove->cmd.sidemove ) + - ( pmove->cmd.upmove * pmove->cmd.upmove ); - spd = sqrt( spd ); - - maxspeed = pmove->clientmaxspeed; //atof( pmove->PM_Info_ValueForKey( pmove->physinfo, "maxspd" ) ); - if ( maxspeed != 0.0 ) - { - pmove->maxspeed = V_min( maxspeed, pmove->maxspeed ); - } - - if ( ( spd != 0.0 ) && - ( spd > pmove->maxspeed ) ) - { - float fRatio = pmove->maxspeed / spd; - pmove->cmd.forwardmove *= fRatio; - pmove->cmd.sidemove *= fRatio; - pmove->cmd.upmove *= fRatio; - } - - if ( pmove->flags & FL_FROZEN || - pmove->flags & FL_ONTRAIN || - pmove->dead ) - { - pmove->cmd.forwardmove = 0; - pmove->cmd.sidemove = 0; - pmove->cmd.upmove = 0; - } - - - PM_DropPunchAngle( pmove->punchangle ); - - // Take angles from command. - if ( !pmove->dead ) - { - VectorCopy ( pmove->cmd.viewangles, v_angle ); - VectorAdd( v_angle, pmove->punchangle, v_angle ); - - // Set up view angles. - pmove->angles[ROLL] = PM_CalcRoll ( v_angle, pmove->velocity, pmove->movevars->rollangle, pmove->movevars->rollspeed )*4; - pmove->angles[PITCH] = v_angle[PITCH]; - pmove->angles[YAW] = v_angle[YAW]; - } - else - { - VectorCopy( pmove->oldangles, pmove->angles ); - } - - // Set dead player view_offset - if ( pmove->dead ) - { - pmove->view_ofs[2] = PM_DEAD_VIEWHEIGHT; - } - - // Adjust client view angles to match values used on server. - if (pmove->angles[YAW] > 180.0f) - { - pmove->angles[YAW] -= 360.0f; - } - -} - -void PM_ReduceTimers( void ) -{ - if ( pmove->flTimeStepSound > 0 ) - { - pmove->flTimeStepSound -= pmove->cmd.msec; - if ( pmove->flTimeStepSound < 0 ) - { - pmove->flTimeStepSound = 0; - } - } - if ( pmove->flDuckTime > 0 ) - { - pmove->flDuckTime -= pmove->cmd.msec; - if ( pmove->flDuckTime < 0 ) - { - pmove->flDuckTime = 0; - } - } - if ( pmove->flSwimTime > 0 ) - { - pmove->flSwimTime -= pmove->cmd.msec; - if ( pmove->flSwimTime < 0 ) - { - pmove->flSwimTime = 0; - } - } -} - -/* -============= -PlayerMove - -Returns with origin, angles, and velocity modified in place. - -Numtouch and touchindex[] will be set if any of the physents -were contacted during the move. -============= -*/ -void PM_PlayerMove ( qboolean server ) -{ - physent_t *pLadder = NULL; - - // Are we running server code? - pmove->server = server; - - // Adjust speeds etc. - PM_CheckParamters(); - - // Assume we don't touch anything - pmove->numtouch = 0; - - // # of msec to apply movement - pmove->frametime = pmove->cmd.msec * 0.001; - - PM_ReduceTimers(); - - // Convert view angles to vectors - AngleVectors (pmove->angles, pmove->forward, pmove->right, pmove->up); - - // PM_ShowClipBox(); - - // Special handling for spectator and observers. (iuser1 is set if the player's in observer mode) - if ( pmove->spectator || pmove->iuser1 > 0 ) - { - PM_SpectatorMove(); - PM_CatagorizePosition(); - return; - } - - // Always try and unstick us unless we are in NOCLIP mode - if ( pmove->movetype != MOVETYPE_NOCLIP && pmove->movetype != MOVETYPE_NONE ) - { - if ( PM_CheckStuck() ) - { - return; // Can't move, we're stuck - } - } - - // Now that we are "unstuck", see where we are ( waterlevel and type, pmove->onground ). - PM_CatagorizePosition(); - - // Store off the starting water level - pmove->oldwaterlevel = pmove->waterlevel; - - // If we are not on ground, store off how fast we are moving down - if ( pmove->onground == -1 ) - { - pmove->flFallVelocity = -pmove->velocity[2]; - } - - g_onladder = 0; - - PM_UpdateStepSound(); - - // Don't run ladder code if dead or on a train - if ( !pmove->dead && !(pmove->flags & FL_ONTRAIN) ) - { - if ( pmove->movetype != MOVETYPE_WALK && - pmove->movetype != MOVETYPE_NOCLIP ) - { - // Clear ladder stuff unless player is noclipping - // it will be set immediately again next frame if necessary - pmove->movetype = MOVETYPE_WALK; - } - } - - // Slow down, I'm pulling it! (a box maybe) but only when I'm standing on ground - if ( ( pmove->onground != -1 ) && ( pmove->cmd.buttons & IN_USE) ) - { - VectorScale( pmove->velocity, 0.3, pmove->velocity ); - } - - // Handle movement - switch ( pmove->movetype ) - { - default: - pmove->Con_DPrintf("Bogus pmove player movetype %i on (%i) 0=cl 1=sv\n", pmove->movetype, pmove->server); - break; - - case MOVETYPE_NONE: - break; - - case MOVETYPE_NOCLIP: - PM_NoClip(); - break; - - case MOVETYPE_TOSS: - case MOVETYPE_BOUNCE: - PM_Physics_Toss(); - break; - - case MOVETYPE_FLY: - - PM_CheckWater(); - - // Was jump button pressed? - // If so, set velocity to 270 away from ladder. This is currently wrong. - // Also, set MOVE_TYPE to walk, too. - if ( pmove->cmd.buttons & IN_JUMP ) - { - if ( !pLadder ) - { - PM_Jump (); - } - } - else - { - pmove->oldbuttons &= ~IN_JUMP; - } - - // Perform the move accounting for any base velocity. - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity); - PM_FlyMove (); - VectorSubtract (pmove->velocity, pmove->basevelocity, pmove->velocity); - break; - - case MOVETYPE_WALK: - if ( !PM_InWater() ) - { - PM_AddCorrectGravity(); - } - - // If we are leaping out of the water, just update the counters. - if ( pmove->waterjumptime ) - { - PM_WaterJump(); - PM_FlyMove(); - - // Make sure waterlevel is set correctly - PM_CheckWater(); - return; - } - - // If we are swimming in the water, see if we are nudging against a place we can jump up out - // of, and, if so, start out jump. Otherwise, if we are not moving up, then reset jump timer to 0 - if ( pmove->waterlevel >= 2 ) - { - if ( pmove->waterlevel == 2 ) - { - PM_CheckWaterJump(); - } - - // If we are falling again, then we must not trying to jump out of water any more. - if ( pmove->velocity[2] < 0 && pmove->waterjumptime ) - { - pmove->waterjumptime = 0; - } - - // Was jump button pressed? - if (pmove->cmd.buttons & IN_JUMP) - { - PM_Jump (); - } - else - { - pmove->oldbuttons &= ~IN_JUMP; - } - - // Perform regular water movement - PM_WaterMove(); - - VectorSubtract (pmove->velocity, pmove->basevelocity, pmove->velocity); - - // Get a final position - PM_CatagorizePosition(); - } - else - - // Not underwater - { - // Was jump button pressed? - if ( pmove->cmd.buttons & IN_JUMP ) - { - if ( !pLadder ) - { - PM_Jump (); - } - } - else - { - pmove->oldbuttons &= ~IN_JUMP; - } - - // Fricion is handled before we add in any base velocity. That way, if we are on a conveyor, - // we don't slow when standing still, relative to the conveyor. - if ( pmove->onground != -1 ) - { - pmove->velocity[2] = 0.0; - PM_Friction(); - } - - // Make sure velocity is valid. - PM_CheckVelocity(); - - // Are we on ground now - if ( pmove->onground != -1 ) - { - PM_WalkMove(); - } - else - { - PM_AirMove(); // Take into account movement when in air. - } - - // Set final flags. - PM_CatagorizePosition(); - - // Now pull the base velocity back out. - // Base velocity is set if you are on a moving object, like - // a conveyor (or maybe another monster?) - VectorSubtract (pmove->velocity, pmove->basevelocity, pmove->velocity ); - - // Make sure velocity is valid. - PM_CheckVelocity(); - - // Add any remaining gravitational component. - if ( !PM_InWater() ) - { - PM_FixupGravityVelocity(); - } - - // If we are on ground, no downward velocity. - if ( pmove->onground != -1 ) - { - pmove->velocity[2] = 0; - } - - // See if we landed on the ground with enough force to play - // a landing sound. - PM_CheckFalling(); - } - - // Did we enter or leave the water? - PM_PlayWaterSounds(); - break; - } -} - -void PM_CreateStuckTable( void ) -{ - float x, y, z; - int idx; - int i; - float zi[3]; - - memset(rgv3tStuckTable, 0, 54 * sizeof(vec3_t)); - - idx = 0; - // Little Moves. - x = y = 0; - // Z moves - for (z = -0.125 ; z <= 0.125 ; z += 0.125) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - x = z = 0; - // Y moves - for (y = -0.125 ; y <= 0.125 ; y += 0.125) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - y = z = 0; - // X moves - for (x = -0.125 ; x <= 0.125 ; x += 0.125) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - - // Remaining multi axis nudges. - for ( x = - 0.125; x <= 0.125; x += 0.250 ) - { - for ( y = - 0.125; y <= 0.125; y += 0.250 ) - { - for ( z = - 0.125; z <= 0.125; z += 0.250 ) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - } - } - - // Big Moves. - x = y = 0; - zi[0] = 0.0f; - zi[1] = 1.0f; - zi[2] = 6.0f; - - for (i = 0; i < 3; i++) - { - // Z moves - z = zi[i]; - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - - x = z = 0; - - // Y moves - for (y = -2.0f ; y <= 2.0f ; y += 2.0) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - y = z = 0; - // X moves - for (x = -2.0f ; x <= 2.0f ; x += 2.0f) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - - // Remaining multi axis nudges. - for (i = 0 ; i < 3; i++) - { - z = zi[i]; - - for (x = -2.0f ; x <= 2.0f ; x += 2.0f) - { - for (y = -2.0f ; y <= 2.0f ; y += 2.0) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - } - } -} - - - -/* -This modume implements the shared player physics code between any particular game and -the engine. The same PM_Move routine is built into the game .dll and the client .dll and is -invoked by each side as appropriate. There should be no distinction, internally, between server -and client. This will ensure that prediction behaves appropriately. -*/ - -void PM_Move ( struct playermove_s *ppmove, int server ) -{ - assert( pm_shared_initialized ); - - pmove = ppmove; - - pmove->player_mins[ pmove->usehull ][ 2 ] = -24; - pmove->player_maxs[ pmove->usehull ][ 2 ] = 32; - - PM_PlayerMove( ( server != 0 ) ? true : false ); - - if ( pmove->onground != -1 ) - { - pmove->flags |= FL_ONGROUND; - } - else - { - pmove->flags &= ~FL_ONGROUND; - } - - // In single player, reset friction after each movement to FrictionModifier Triggers work still. - if ( !pmove->multiplayer && ( pmove->movetype == MOVETYPE_WALK ) ) - { - pmove->friction = 1.0f; - } -} - -int PM_GetInfo( int ent ) -{ - if ( ent >= 0 && ent <= pmove->numvisent ) - { - return pmove->visents[ ent ].info; - } - return -1; -} - -void PM_Init( struct playermove_s *ppmove ) -{ - assert( !pm_shared_initialized ); - - pmove = ppmove; - - PM_CreateStuckTable(); - PM_InitTextureTypes(); - - pm_shared_initialized = 1; -} diff --git a/dmc/pm_shared/pm_shared.h b/dmc/pm_shared/pm_shared.h deleted file mode 100644 index ce8a1c6..0000000 --- a/dmc/pm_shared/pm_shared.h +++ /dev/null @@ -1,36 +0,0 @@ -/*** -* -* 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. -* -****/ - -// -// pm_shared.h -// -#if !defined( PM_SHAREDH ) -#define PM_SHAREDH -#pragma once - -void PM_Init( struct playermove_s *ppmove ); -void PM_Move ( struct playermove_s *ppmove, int server ); -char PM_FindTextureType( char *name ); - -// Spectator Movement modes (stored in pev->iuser1, so the physics code can get at them) -#define OBS_NONE 0 -#define OBS_CHASE_LOCKED 1 -#define OBS_CHASE_FREE 2 -#define OBS_ROAMING 3 -#define OBS_IN_EYE 4 -#define OBS_MAP_FREE 5 -#define OBS_MAP_CHASE 6 - -#endif diff --git a/ricochet/cl_dll/Exports.h b/ricochet/cl_dll/Exports.h deleted file mode 100644 index 09345fd..0000000 --- a/ricochet/cl_dll/Exports.h +++ /dev/null @@ -1,219 +0,0 @@ -#include "Platform.h" - -extern "C" -{ - // From hl_weapons - void DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ); - - // From cdll_int - int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ); - int DLLEXPORT HUD_VidInit( void ); - void DLLEXPORT HUD_Init( void ); - int DLLEXPORT HUD_Redraw( float flTime, int intermission ); - int DLLEXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime ); - void DLLEXPORT HUD_Reset ( void ); - void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ); - void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ); - char DLLEXPORT HUD_PlayerMoveTexture( char *name ); - int DLLEXPORT HUD_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); - int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ); - void DLLEXPORT HUD_Frame( double time ); - void DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking); - void DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf ); - void DLLEXPORT HUD_ChatInputPosition( int *x, int *y ); - int DLLEXPORT HUD_GetPlayerTeam(int iplayer); - - // From demo - void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer ); - - // From entity - int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void DLLEXPORT HUD_CreateEntities( void ); - void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); - void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); - void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); - void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd ); - void DLLEXPORT HUD_TempEntUpdate( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( struct cl_entity_s *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) ); - struct cl_entity_s DLLEXPORT *HUD_GetUserEntity( int index ); - - // From in_camera - void DLLEXPORT CAM_Think( void ); - int DLLEXPORT CL_IsThirdPerson( void ); - void DLLEXPORT CL_CameraOffset( float *ofs ); - - // From input - struct kbutton_s DLLEXPORT *KB_Find( const char *name ); - void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ); - void DLLEXPORT HUD_Shutdown( void ); - int DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding ); - - // From inputw32 - void DLLEXPORT IN_ActivateMouse( void ); - void DLLEXPORT IN_DeactivateMouse( void ); - void DLLEXPORT IN_MouseEvent (int mstate); - void DLLEXPORT IN_Accumulate (void); - void DLLEXPORT IN_ClearStates (void); - - // From tri - void DLLEXPORT HUD_DrawNormalTriangles( void ); - void DLLEXPORT HUD_DrawTransparentTriangles( void ); - - // From view - void DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams ); - - // From GameStudioModelRenderer - int DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio ); -} - -extern modfuncs_t g_modfuncs; -//extern cldll_func_dst_t *g_pcldstAddrs; - -/* -// Macros for the client receiving calls from the engine -#define RecClInitialize(a, b) (g_pcldstAddrs->pInitFunc(&a, &b)) -#define RecClHudInit() (g_pcldstAddrs->pHudInitFunc()) -#define RecClHudVidInit() (g_pcldstAddrs->pHudVidInitFunc()) -#define RecClHudRedraw(a, b) (g_pcldstAddrs->pHudRedrawFunc(&a, &b)) -#define RecClHudUpdateClientData(a, b) (g_pcldstAddrs->pHudUpdateClientDataFunc(&a, &b)) -#define RecClHudReset() (g_pcldstAddrs->pHudResetFunc()) -#define RecClClientMove(a, b) (g_pcldstAddrs->pClientMove(&a, &b)) -#define RecClClientMoveInit(a) (g_pcldstAddrs->pClientMoveInit(&a)) -#define RecClClientTextureType(a) (g_pcldstAddrs->pClientTextureType(&a)) -#define RecClIN_ActivateMouse() (g_pcldstAddrs->pIN_ActivateMouse()) -#define RecClIN_DeactivateMouse() (g_pcldstAddrs->pIN_DeactivateMouse()) -#define RecClIN_MouseEvent(a) (g_pcldstAddrs->pIN_MouseEvent(&a)) -#define RecClIN_ClearStates() (g_pcldstAddrs->pIN_ClearStates()) -#define RecClIN_Accumulate() (g_pcldstAddrs->pIN_Accumulate()) -#define RecClCL_CreateMove(a, b, c) (g_pcldstAddrs->pCL_CreateMove(&a, &b, &c)) -#define RecClCL_IsThirdPerson() (g_pcldstAddrs->pCL_IsThirdPerson()) -#define RecClCL_GetCameraOffsets(a) (g_pcldstAddrs->pCL_GetCameraOffsets(&a)) -#define RecClFindKey(a) (g_pcldstAddrs->pFindKey(&a)) -#define RecClCamThink() (g_pcldstAddrs->pCamThink()) -#define RecClCalcRefdef(a) (g_pcldstAddrs->pCalcRefdef(&a)) -#define RecClAddEntity(a, b, c) (g_pcldstAddrs->pAddEntity(&a, &b, &c)) -#define RecClCreateEntities() (g_pcldstAddrs->pCreateEntities()) -#define RecClDrawNormalTriangles() (g_pcldstAddrs->pDrawNormalTriangles()) -#define RecClDrawTransparentTriangles() (g_pcldstAddrs->pDrawTransparentTriangles()) -#define RecClStudioEvent(a, b) (g_pcldstAddrs->pStudioEvent(&a, &b)) -#define RecClPostRunCmd(a, b, c, d, e, f) (g_pcldstAddrs->pPostRunCmd(&a, &b, &c, &d, &e, &f)) -#define RecClShutdown() (g_pcldstAddrs->pShutdown()) -#define RecClTxferLocalOverrides(a, b) (g_pcldstAddrs->pTxferLocalOverrides(&a, &b)) -#define RecClProcessPlayerState(a, b) (g_pcldstAddrs->pProcessPlayerState(&a, &b)) -#define RecClTxferPredictionData(a, b, c, d, e, f) (g_pcldstAddrs->pTxferPredictionData(&a, &b, &c, &d, &e, &f)) -#define RecClReadDemoBuffer(a, b) (g_pcldstAddrs->pReadDemoBuffer(&a, &b)) -#define RecClConnectionlessPacket(a, b, c, d) (g_pcldstAddrs->pConnectionlessPacket(&a, &b, &c, &d)) -#define RecClGetHullBounds(a, b, c) (g_pcldstAddrs->pGetHullBounds(&a, &b, &c)) -#define RecClHudFrame(a) (g_pcldstAddrs->pHudFrame(&a)) -#define RecClKeyEvent(a, b, c) (g_pcldstAddrs->pKeyEvent(&a, &b, &c)) -#define RecClTempEntUpdate(a, b, c, d, e, f, g) (g_pcldstAddrs->pTempEntUpdate(&a, &b, &c, &d, &e, &f, &g)) -#define RecClGetUserEntity(a) (g_pcldstAddrs->pGetUserEntity(&a)) -#define RecClVoiceStatus(a, b) (g_pcldstAddrs->pVoiceStatus(&a, &b)) -#define RecClDirectorMessage(a, b) (g_pcldstAddrs->pDirectorMessage(&a, &b)) -#define RecClStudioInterface(a, b, c) (g_pcldstAddrs->pStudioInterface(&a, &b, &c)) -#define RecClChatInputPosition(a, b) (g_pcldstAddrs->pChatInputPosition(&a, &b)) - -*/ -// Macros for calling into the engine -#define CallEngSPR_Load(a) (gEngfuncs.pfnSPR_Load(a)) -#define CallEngSPR_Frames(a) (gEngfuncs.pfnSPR_Frames(a)) -#define CallEngSPR_Height(a, b) (gEngfuncs.pfnSPR_Height(a, b)) -#define CallEngSPR_Width(a, b) (gEngfuncs.pfnSPR_Width(a, b)) -#define CallEngSPR_Set(a, b, c, d) (gEngfuncs.pfnSPR_Set(a, b, c, d)) -#define CallEngSPR_Draw(a, b, c, d) (gEngfuncs.pfnSPR_Draw(a, b, c, d)) -#define CallEngSPR_DrawHoles(a, b, c, d) (gEngfuncs.pfnSPR_DrawHoles(a, b, c, d)) -#define CallEngSPR_DrawAdditive(a, b, c, d) (gEngfuncs.pfnSPR_DrawAdditive(a, b, c, d)) -#define CallEngSPR_EnableScissor(a, b, c, d) (gEngfuncs.pfnSPR_EnableScissor(a, b, c, d)) -#define CallEngSPR_DisableScissor() (gEngfuncs.pfnSPR_DisableScissor()) -#define CallEngSPR_GetList(a, b) (gEngfuncs.pfnSPR_GetList(a, b)) -#define CallEngDraw_FillRGBA(a, b, c, d, e, f, g, h) (gEngfuncs.pfnFillRGBA(a, b, c, d, e, f, g, h)) -#define CallEngDraw_FillRGBABlend(a, b, c, d, e, f, g, h) (gEngfuncs.pfnFillRGBABlend(a, b, c, d, e, f, g, h)) -#define CallEnghudGetScreenInfo(a) (gEngfuncs.pfnGetScreenInfo(a)) -#define CallEngSetCrosshair(a, b, c, d, e) (gEngfuncs.pfnSetCrosshair(a, b, c, d, e)) -#define CallEnghudRegisterVariable(a, b, c) (gEngfuncs.pfnRegisterVariable(a, b, c)) -#define CallEnghudGetCvarFloat(a) (gEngfuncs.pfnGetCvarFloat(a)) -#define CallEnghudGetCvarString(a) (gEngfuncs.pfnGetCvarString(a)) -#define CallEnghudAddCommand(a, b) (gEngfuncs.pfnAddCommand(a, b)) -#define CallEnghudHookUserMsg(a, b) (gEngfuncs.pfnHookUserMsg(a, b)) -#define CallEnghudServerCmd(a) (gEngfuncs.pfnServerCmd(a)) -#define CallEnghudClientCmd(a) (gEngfuncs.pfnClientCmd(a)) -#define CallEngPrimeMusicStream(a, b) (gEngfuncs.pfnPrimeMusicStream(a, b)) -#define CallEnghudGetPlayerInfo(a, b) (gEngfuncs.pfnGetPlayerInfo(a, b)) -#define CallEnghudPlaySoundByName(a, b) (gEngfuncs.pfnPlaySoundByName(a, b)) -#define CallEnghudPlaySoundByNameAtPitch(a, b, c) (gEngfuncs.pfnPlaySoundByNameAtPitch(a, b, c)) -#define CallEnghudPlaySoundVoiceByName(a, b, c) (gEngfuncs.pfnPlaySoundVoiceByName(a, b, c)) -#define CallEnghudPlaySoundByIndex(a, b) (gEngfuncs.pfnPlaySoundByIndex(a, b)) -#define CallEngAngleVectors(a, b, c, d) (gEngfuncs.pfnAngleVectors(a, b, c, d)) -#define CallEngTextMessageGet(a) (gEngfuncs.pfnTextMessageGet(a)) -#define CallEngTextMessageDrawCharacter(a, b, c, d, e, f) (gEngfuncs.pfnDrawCharacter(a, b, c, d, e, f)) -#define CallEngDraw_String(a, b, c) (gEngfuncs.pfnDrawConsoleString(a, b, c)) -#define CallEngDraw_SetTextColor(a, b, c) (gEngfuncs.pfnDrawSetTextColor(a, b, c)) -#define CallEnghudDrawConsoleStringLen(a, b, c) (gEngfuncs.pfnDrawConsoleStringLen(a, b, c)) -#define CallEnghudConsolePrint(a) (gEngfuncs.pfnConsolePrint(a)) -#define CallEnghudCenterPrint(a) (gEngfuncs.pfnCenterPrint(a)) -#define CallEnghudCenterX() (gEngfuncs.GetWindowCenterX()) -#define CallEnghudCenterY() (gEngfuncs.GetWindowCenterY()) -#define CallEnghudGetViewAngles(a) (gEngfuncs.GetViewAngles(a)) -#define CallEnghudSetViewAngles(a) (gEngfuncs.SetViewAngles(a)) -#define CallEnghudGetMaxClients() (gEngfuncs.GetMaxClients()) -#define CallEngCvar_SetValue(a, b) (gEngfuncs.Cvar_SetValue(a, b)) -#define CallEngCmd_Argc() (gEngfuncs.Cmd_Argc()) -#define CallEngCmd_Argv(a) (gEngfuncs.Cmd_Argv(a)) -#define CallEnghudPhysInfo_ValueForKey(a) (gEngfuncs.PhysInfo_ValueForKey(a)) -#define CallEnghudServerInfo_ValueForKey(a) (gEngfuncs.ServerInfo_ValueForKey(a)) -#define CallEnghudGetClientMaxspeed() (gEngfuncs.GetClientMaxspeed()) -#define CallEnghudCheckParm(a, b) (gEngfuncs.CheckParm(a, b)) -#define CallEngKey_Event(a, b) (gEngfuncs.Key_Event(a, b)) -#define CallEnghudGetMousePosition(a, b) (gEngfuncs.GetMousePosition(a, b)) -#define CallEnghudIsNoClipping() (gEngfuncs.IsNoClipping()) -#define CallEnghudGetLocalPlayer() (gEngfuncs.GetLocalPlayer()) -#define CallEnghudGetViewModel() (gEngfuncs.GetViewModel()) -#define CallEnghudGetEntityByIndex(a) (gEngfuncs.GetEntityByIndex(a)) -#define CallEnghudGetClientTime() (gEngfuncs.GetClientTime()) -#define CallEngV_CalcShake() (gEngfuncs.V_CalcShake()) -#define CallEngV_ApplyShake(a, b, c) (gEngfuncs.V_ApplyShake(a, b, c)) -#define CallEngPM_PointContents(a, b) (gEngfuncs.PM_PointContents(a, b)) -#define CallEngPM_WaterEntity(a) (gEngfuncs.PM_WaterEntity(a)) -#define CallEngPM_TraceLine(a, b, c, d, e) (gEngfuncs.PM_TraceLine(a, b, c, d, e)) -#define CallEngCL_LoadModel(a, b) (gEngfuncs.CL_LoadModel(a, b)) -#define CallEngCL_CreateVisibleEntity(a, b) (gEngfuncs.CL_CreateVisibleEntity(a, b)) -#define CallEnghudGetSpritePointer(a) (gEngfuncs.GetSpritePointer(a)) -#define CallEnghudPlaySoundByNameAtLocation(a, b, c) (gEngfuncs.pfnPlaySoundByNameAtLocation(a, b, c)) -#define CallEnghudPrecacheEvent(a, b) (gEngfuncs.pfnPrecacheEvent(a, b)) -#define CallEnghudPlaybackEvent(a, b, c, d, e, f, g, h, i, j, k, l) (gEngfuncs.pfnPlaybackEvent(a, b, c, d, e, f, g, h, i, j, k, l)) -#define CallEnghudWeaponAnim(a, b) (gEngfuncs.pfnWeaponAnim(a, b)) -#define CallEngRandomFloat(a, b) (gEngfuncs.pfnRandomFloat(a, b)) -#define CallEngRandomLong(a, b) (gEngfuncs.pfnRandomLong(a, b)) -#define CallEngCL_HookEvent(a, b) (gEngfuncs.pfnHookEvent(a, b)) -#define CallEngCon_IsVisible() (gEngfuncs.Con_IsVisible()) -#define CallEnghudGetGameDir() (gEngfuncs.pfnGetGameDirectory()) -#define CallEngCvar_FindVar(a) (gEngfuncs.pfnGetCvarPointer(a)) -#define CallEngKey_NameForBinding(a) (gEngfuncs.Key_LookupBinding(a)) -#define CallEnghudGetLevelName() (gEngfuncs.pfnGetLevelName()) -#define CallEnghudGetScreenFade(a) (gEngfuncs.pfnGetScreenFade(a)) -#define CallEnghudSetScreenFade(a) (gEngfuncs.pfnSetScreenFade(a)) -#define CallEngVGuiWrap_GetPanel() (gEngfuncs.VGui_GetPanel()) -#define CallEngVGui_ViewportPaintBackground(a) (gEngfuncs.VGui_ViewportPaintBackground(a)) -#define CallEngCOM_LoadFile(a, b, c) (gEngfuncs.COM_LoadFile(a, b, c)) -#define CallEngCOM_ParseFile(a, b) (gEngfuncs.COM_ParseFile(a, b)) -#define CallEngCOM_FreeFile(a) (gEngfuncs.COM_FreeFile(a)) -#define CallEngCL_IsSpectateOnly() (gEngfuncs.IsSpectateOnly()) -#define CallEngR_LoadMapSprite(a) (gEngfuncs.LoadMapSprite(a)) -#define CallEngCOM_AddAppDirectoryToSearchPath(a, b) (gEngfuncs.COM_AddAppDirectoryToSearchPath(a, b)) -#define CallEngClientDLL_ExpandFileName(a, b, c)(gEngfuncs.COM_ExpandFilename(a, b, c)) -#define CallEngPlayerInfo_ValueForKey(a, b) (gEngfuncs.PlayerInfo_ValueForKey(a, b)) -#define CallEngPlayerInfo_SetValueForKey(a, b) (gEngfuncs.PlayerInfo_SetValueForKey(a, b)) -#define CallEngGetPlayerUniqueID(a, b) (gEngfuncs.GetPlayerUniqueID(a, b)) -#define CallEngGetTrackerIDForPlayer(a) (gEngfuncs.GetTrackerIDForPlayer(a)) -#define CallEngGetPlayerForTrackerID(a) (gEngfuncs.GetPlayerForTrackerID(a)) -#define CallEnghudServerCmdUnreliable(a) (gEngfuncs.pfnServerCmdUnreliable(a)) -#define CallEngGetMousePos(a) (gEngfuncs.pfnGetMousePos(a)) -#define CallEngSetMousePos(a, b) (gEngfuncs.pfnSetMousePos(a, b)) -#define CallEngSetMouseEnable(a) (gEngfuncs.pfnSetMouseEnable(a)) -#define CallEngLocalPlayerInfo_ValueForKey(a) (gEngfuncs.LocalPlayerInfo_ValueForKey(a)) - -#if 0 -inline float CVAR_GET_FLOAT( const char *x ) { return CallEnghudGetCvarFloat( (char*)x ); } -inline char* CVAR_GET_STRING( const char *x ) { return CallEnghudGetCvarString( (char*)x ); } -inline struct cvar_s *CVAR_CREATE( const char *cv, const char *val, const int flags ) { return CallEnghudRegisterVariable( (char*)cv, (char*)val, flags ); } -#endif - diff --git a/ricochet/cl_dll/GameStudioModelRenderer.cpp b/ricochet/cl_dll/GameStudioModelRenderer.cpp deleted file mode 100644 index 05f7afe..0000000 --- a/ricochet/cl_dll/GameStudioModelRenderer.cpp +++ /dev/null @@ -1,981 +0,0 @@ -#include -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "com_model.h" -#include "studio.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "dlight.h" -#include "triangleapi.h" - -#include -#include -#include -#include - -#include "studio_util.h" -#include "r_studioint.h" - -#include "StudioModelRenderer.h" -#include "GameStudioModelRenderer.h" - -void Ricochet_GetSequence( int *seq, int *gaitseq ); -void Ricochet_GetOrientation( float *o, float *a ); - -float g_flStartScaleTime; -int iPrevRenderState; -int iRenderStateChanged; - -// Global engine <-> studio model rendering code interface -extern engine_studio_api_t IEngineStudio; - -typedef struct -{ - vec3_t origin; - vec3_t angles; - - vec3_t realangles; - - float animtime; - float frame; - int sequence; - int gaitsequence; - float framerate; - - int m_fSequenceLoops; - int m_fSequenceFinished; - - byte controller[ 4 ]; - byte blending[ 2 ]; - - latchedvars_t lv; -} client_anim_state_t; - -static client_anim_state_t g_state; -static client_anim_state_t g_clientstate; - -// The renderer object, created on the stack. -CGameStudioModelRenderer g_StudioRenderer; -/* -==================== -CGameStudioModelRenderer - -==================== -*/ -CGameStudioModelRenderer::CGameStudioModelRenderer( void ) -{ - // If you want to predict animations locally, set this to TRUE - // NOTE: The animation code is somewhat broken, but gives you a sense for how - // to do client side animation of the predicted player in a third person game. - m_bLocal = false; -} - -/* -==================== -StudioSetupBones - -==================== -*/ -void CGameStudioModelRenderer::StudioSetupBones ( void ) -{ - int i; - double f; - - mstudiobone_t *pbones; - mstudioseqdesc_t *pseqdesc; - mstudioanim_t *panim; - - static float pos[MAXSTUDIOBONES][3]; - static vec4_t q[MAXSTUDIOBONES]; - float bonematrix[3][4]; - - static float pos2[MAXSTUDIOBONES][3]; - static vec4_t q2[MAXSTUDIOBONES]; - static float pos3[MAXSTUDIOBONES][3]; - static vec4_t q3[MAXSTUDIOBONES]; - static float pos4[MAXSTUDIOBONES][3]; - static vec4_t q4[MAXSTUDIOBONES]; - - // Use default bone setup for nonplayers - if ( !m_pCurrentEntity->player ) - { - CStudioModelRenderer::StudioSetupBones(); - return; - } - - // Bound sequence number. - if ( m_pCurrentEntity->curstate.sequence >= m_pStudioHeader->numseq ) - { - m_pCurrentEntity->curstate.sequence = 0; - } - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; - - if ( m_pPlayerInfo && m_pPlayerInfo->gaitsequence != 0 ) - { - f = m_pPlayerInfo->gaitframe; - } - else - { - f = StudioEstimateFrame( pseqdesc ); - } - - // Discwar knows how to do three way blending - if ( pseqdesc->numblends == 3 ) - { - float s; - - // Get left anim - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - - // Blending is 0-127 == Left to Middle, 128 to 255 == Middle to right - if ( m_pCurrentEntity->curstate.blending[0] <= 127 ) - { - StudioCalcRotations( pos, q, pseqdesc, panim, f ); - - // Scale 0-127 blending up to 0-255 - s = m_pCurrentEntity->curstate.blending[0]; - s = ( s * 2.0 ); - } - else - { - - // Skip ahead to middle - panim += m_pStudioHeader->numbones; - - StudioCalcRotations( pos, q, pseqdesc, panim, f ); - - // Scale 127-255 blending up to 0-255 - s = m_pCurrentEntity->curstate.blending[0]; - s = 2.0 * ( s - 127.0 ); - } - - // Normalize interpolant - s /= 255.0; - - // Go to middle or right - panim += m_pStudioHeader->numbones; - - StudioCalcRotations( pos2, q2, pseqdesc, panim, f ); - - // Spherically interpolate the bones - StudioSlerpBones( q, pos, q2, pos2, s ); - } - else - { - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - StudioCalcRotations( pos, q, pseqdesc, panim, f ); - } - - // Are we in the process of transitioning from one sequence to another. - if ( m_fDoInterp && - m_pCurrentEntity->latched.sequencetime && - ( m_pCurrentEntity->latched.sequencetime + 0.2 > m_clTime ) && - ( m_pCurrentEntity->latched.prevsequence < m_pStudioHeader->numseq )) - { - // blend from last sequence - static float pos1b[MAXSTUDIOBONES][3]; - static vec4_t q1b[MAXSTUDIOBONES]; - float s; - - // Blending value into last sequence - unsigned char prevseqblending = m_pCurrentEntity->latched.prevseqblending[ 0 ]; - - // Point at previous sequenece - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->latched.prevsequence; - - // Know how to do three way blends - if ( pseqdesc->numblends == 3 ) - { - float s; - - // Get left animation - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - - if ( prevseqblending <= 127 ) - { - // Set up bones based on final frame of previous sequence - StudioCalcRotations( pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - s = prevseqblending; - s = ( s * 2.0 ); - } - else - { - // Skip to middle blend - panim += m_pStudioHeader->numbones; - - StudioCalcRotations( pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - s = prevseqblending; - s = 2.0 * ( s - 127.0 ); - } - - // Normalize - s /= 255.0; - - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos2, q2, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - // Interpolate bones - StudioSlerpBones( q1b, pos1b, q2, pos2, s ); - } - else - { - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - // clip prevframe - StudioCalcRotations( pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - } - - // Now blend last frame of previous sequence with current sequence. - s = 1.0 - (m_clTime - m_pCurrentEntity->latched.sequencetime) / 0.2; - StudioSlerpBones( q, pos, q1b, pos1b, s ); - } - else - { - m_pCurrentEntity->latched.prevframe = f; - } - - // Now convert quaternions and bone positions into matrices - pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - QuaternionMatrix( q[i], bonematrix ); - - bonematrix[0][3] = pos[i][0]; - bonematrix[1][3] = pos[i][1]; - bonematrix[2][3] = pos[i][2]; - - if (pbones[i].parent == -1) - { - if ( IEngineStudio.IsHardware() ) - { - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - } - else - { - ConcatTransforms ((*m_paliastransform), bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - } - - // Apply client-side effects to the transformation matrix - StudioFxTransform( m_pCurrentEntity, (*m_pbonetransform)[i] ); - } - else - { - ConcatTransforms ((*m_pbonetransform)[pbones[i].parent], bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_plighttransform)[pbones[i].parent], bonematrix, (*m_plighttransform)[i]); - } - } -} - -/* -==================== -StudioEstimateGait - -==================== -*/ -void CGameStudioModelRenderer::StudioEstimateGait( entity_state_t *pplayer ) -{ - float dt; - vec3_t est_velocity; - - dt = (m_clTime - m_clOldTime); - dt = V_max( 0.0, dt ); - dt = V_min( 1.0, dt ); - - if (dt == 0 || m_pPlayerInfo->renderframe == m_nFrameCount) - { - m_flGaitMovement = 0; - return; - } - - // VectorAdd( pplayer->velocity, pplayer->prediction_error, est_velocity ); - if ( m_fGaitEstimation ) - { - VectorSubtract( m_pCurrentEntity->origin, m_pPlayerInfo->prevgaitorigin, est_velocity ); - VectorCopy( m_pCurrentEntity->origin, m_pPlayerInfo->prevgaitorigin ); - m_flGaitMovement = Length( est_velocity ); - if (dt <= 0 || m_flGaitMovement / dt < 5) - { - m_flGaitMovement = 0; - est_velocity[0] = 0; - est_velocity[1] = 0; - } - } - else - { - VectorCopy( pplayer->velocity, est_velocity ); - m_flGaitMovement = Length( est_velocity ) * dt; - } - - if (est_velocity[1] == 0 && est_velocity[0] == 0) - { - float flYawDiff = m_pCurrentEntity->angles[YAW] - m_pPlayerInfo->gaityaw; - flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360; - if (flYawDiff > 180) - flYawDiff -= 360; - if (flYawDiff < -180) - flYawDiff += 360; - - if (dt < 0.25) - flYawDiff *= dt * 4; - else - flYawDiff *= dt; - - m_pPlayerInfo->gaityaw += flYawDiff; - m_pPlayerInfo->gaityaw = m_pPlayerInfo->gaityaw - (int)(m_pPlayerInfo->gaityaw / 360) * 360; - - m_flGaitMovement = 0; - } - else - { - m_pPlayerInfo->gaityaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI); - if (m_pPlayerInfo->gaityaw > 180) - m_pPlayerInfo->gaityaw = 180; - if (m_pPlayerInfo->gaityaw < -180) - m_pPlayerInfo->gaityaw = -180; - } - -} - -/* -==================== -StudioProcessGait - -==================== -*/ -void CGameStudioModelRenderer::StudioProcessGait( entity_state_t *pplayer ) -{ - mstudioseqdesc_t *pseqdesc; - float dt; - float flYaw; // view direction relative to movement - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; - - m_pCurrentEntity->angles[PITCH] = 0; - m_pCurrentEntity->latched.prevangles[PITCH] = m_pCurrentEntity->angles[PITCH]; - - dt = (m_clTime - m_clOldTime); - dt = V_max( 0.0, dt ); - dt = V_min( 1.0, dt ); - - StudioEstimateGait( pplayer ); - - // calc side to side turning - flYaw = m_pCurrentEntity->angles[YAW] - m_pPlayerInfo->gaityaw; - - flYaw = fmod( flYaw, 360.0f ); - - if (flYaw < -180) - { - flYaw = flYaw + 360; - } - else if (flYaw > 180) - { - flYaw = flYaw - 360; - } - - float maxyaw = 120.0; - - if (flYaw > maxyaw) - { - m_pPlayerInfo->gaityaw = m_pPlayerInfo->gaityaw - 180; - m_flGaitMovement = -m_flGaitMovement; - flYaw = flYaw - 180; - } - else if (flYaw < -maxyaw) - { - m_pPlayerInfo->gaityaw = m_pPlayerInfo->gaityaw + 180; - m_flGaitMovement = -m_flGaitMovement; - flYaw = flYaw + 180; - } - - float blend_yaw = ( flYaw / 90.0 ) * 128.0 + 127.0; - blend_yaw = V_min( 255.0, blend_yaw ); - blend_yaw = V_max( 0.0, blend_yaw ); - - blend_yaw = 255.0 - blend_yaw; - - m_pCurrentEntity->curstate.blending[0] = (int)(blend_yaw); - m_pCurrentEntity->latched.prevblending[0] = m_pCurrentEntity->curstate.blending[0]; - m_pCurrentEntity->latched.prevseqblending[0] = m_pCurrentEntity->curstate.blending[0]; - - m_pCurrentEntity->angles[YAW] = m_pPlayerInfo->gaityaw; - if (m_pCurrentEntity->angles[YAW] < -0) - { - m_pCurrentEntity->angles[YAW] += 360; - } - m_pCurrentEntity->latched.prevangles[YAW] = m_pCurrentEntity->angles[YAW]; - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + pplayer->gaitsequence; - - // Calc gait frame - if (pseqdesc->linearmovement[0] > 0) - { - m_pPlayerInfo->gaitframe += (m_flGaitMovement / pseqdesc->linearmovement[0]) * pseqdesc->numframes; - } - else - { - m_pPlayerInfo->gaitframe += pseqdesc->fps * dt * m_pCurrentEntity->curstate.framerate; - } - - // Do modulo - m_pPlayerInfo->gaitframe = m_pPlayerInfo->gaitframe - (int)(m_pPlayerInfo->gaitframe / pseqdesc->numframes) * pseqdesc->numframes; - if (m_pPlayerInfo->gaitframe < 0) - { - m_pPlayerInfo->gaitframe += pseqdesc->numframes; - } -} - -/* -============================== -SavePlayerState - -For local player, in third person, we need to store real render data and then - setup for with fake/client side animation data -============================== -*/ -void CGameStudioModelRenderer::SavePlayerState( entity_state_t *pplayer ) -{ - client_anim_state_t *st; - cl_entity_t *ent = IEngineStudio.GetCurrentEntity(); - assert( ent ); - if ( !ent ) - return; - - st = &g_state; - - st->angles = ent->curstate.angles; - st->origin = ent->curstate.origin; - - st->realangles = ent->angles; - - st->sequence = ent->curstate.sequence; - st->gaitsequence = pplayer->gaitsequence; - st->animtime = ent->curstate.animtime; - st->frame = ent->curstate.frame; - st->framerate = ent->curstate.framerate; - memcpy( st->blending, ent->curstate.blending, 2 ); - memcpy( st->controller, ent->curstate.controller, 4 ); - - st->lv = ent->latched; -} - -void GetSequenceInfo( void *pmodel, client_anim_state_t *pev, float *pflFrameRate, float *pflGroundSpeed ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return; - - mstudioseqdesc_t *pseqdesc; - - if (pev->sequence >= pstudiohdr->numseq) - { - *pflFrameRate = 0.0; - *pflGroundSpeed = 0.0; - return; - } - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - if (pseqdesc->numframes > 1) - { - *pflFrameRate = 256 * pseqdesc->fps / (pseqdesc->numframes - 1); - *pflGroundSpeed = sqrt( pseqdesc->linearmovement[0]*pseqdesc->linearmovement[0]+ pseqdesc->linearmovement[1]*pseqdesc->linearmovement[1]+ pseqdesc->linearmovement[2]*pseqdesc->linearmovement[2] ); - *pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1); - } - else - { - *pflFrameRate = 256.0; - *pflGroundSpeed = 0.0; - } -} - -int GetSequenceFlags( void *pmodel, client_anim_state_t *pev ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr || pev->sequence >= pstudiohdr->numseq ) - return 0; - - mstudioseqdesc_t *pseqdesc; - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - return pseqdesc->flags; -} - -float StudioFrameAdvance ( client_anim_state_t *st, float framerate, float flInterval ) -{ - if (flInterval == 0.0) - { - flInterval = (gEngfuncs.GetClientTime() - st->animtime); - if (flInterval <= 0.001) - { - st->animtime = gEngfuncs.GetClientTime(); - return 0.0; - } - } - if (!st->animtime) - flInterval = 0.0; - - st->frame += flInterval * framerate * st->framerate; - st->animtime = gEngfuncs.GetClientTime(); - - if (st->frame < 0.0 || st->frame >= 256.0) - { - if ( st->m_fSequenceLoops ) - st->frame -= (int)(st->frame / 256.0) * 256.0; - else - st->frame = (st->frame < 0.0) ? 0 : 255; - st->m_fSequenceFinished = TRUE; // just in case it wasn't caught in GetEvents - } - - return flInterval; -} - -/* -============================== -SetupClientAnimation - -Called to set up local player's animation values -============================== -*/ -void CGameStudioModelRenderer::SetupClientAnimation( entity_state_t *pplayer ) -{ - static double oldtime; - double curtime, dt; - - client_anim_state_t *st; - float fr, gs; - - cl_entity_t *ent = IEngineStudio.GetCurrentEntity(); - assert( ent ); - if ( !ent ) - return; - - curtime = gEngfuncs.GetClientTime(); - dt = curtime - oldtime; - dt = V_min( 1.0, V_max( 0.0, dt ) ); - - oldtime = curtime; - st = &g_clientstate; - - st->framerate = 1.0; - - int oldseq = st->sequence; - Ricochet_GetSequence( &st->sequence, &st->gaitsequence ); - Ricochet_GetOrientation( (float *)&st->origin, (float *)&st->angles ); - st->realangles = st->angles; - - if ( st->sequence != oldseq ) - { - st->frame = 0.0; - st->lv.prevsequence = oldseq; - st->lv.sequencetime = st->animtime; - - memcpy( st->lv.prevseqblending, st->blending, 2 ); - memcpy( st->lv.prevcontroller, st->controller, 4 ); - } - - void *pmodel = (studiohdr_t *)IEngineStudio.Mod_Extradata( ent->model ); - - GetSequenceInfo( pmodel, st, &fr, &gs ); - st->m_fSequenceLoops = ((GetSequenceFlags( pmodel, st ) & STUDIO_LOOPING) != 0); - StudioFrameAdvance( st, fr, dt ); - - ent->angles = st->realangles; - ent->curstate.angles = st->angles; - ent->curstate.origin = st->origin; - - ent->curstate.sequence = st->sequence; - pplayer->gaitsequence = st->gaitsequence; - ent->curstate.animtime = st->animtime; - ent->curstate.frame = st->frame; - ent->curstate.framerate = st->framerate; - memcpy( ent->curstate.blending, st->blending, 2 ); - memcpy( ent->curstate.controller, st->controller, 4 ); - - ent->latched = st->lv; -} - -/* -============================== -RestorePlayerState - -Called to restore original player state information -============================== -*/ -void CGameStudioModelRenderer::RestorePlayerState( entity_state_t *pplayer ) -{ - client_anim_state_t *st; - cl_entity_t *ent = IEngineStudio.GetCurrentEntity(); - assert( ent ); - if ( !ent ) - return; - - st = &g_clientstate; - - st->angles = ent->curstate.angles; - st->origin = ent->curstate.origin; - st->realangles = ent->angles; - - st->sequence = ent->curstate.sequence; - st->gaitsequence = pplayer->gaitsequence; - st->animtime = ent->curstate.animtime; - st->frame = ent->curstate.frame; - st->framerate = ent->curstate.framerate; - memcpy( st->blending, ent->curstate.blending, 2 ); - memcpy( st->controller, ent->curstate.controller, 4 ); - - st->lv = ent->latched; - - st = &g_state; - - ent->curstate.angles = st->angles; - ent->curstate.origin = st->origin; - ent->angles = st->realangles; - - ent->curstate.sequence = st->sequence; - pplayer->gaitsequence = st->gaitsequence; - ent->curstate.animtime = st->animtime; - ent->curstate.frame = st->frame; - ent->curstate.framerate = st->framerate; - memcpy( ent->curstate.blending, st->blending, 2 ); - memcpy( ent->curstate.controller, st->controller, 4 ); - - ent->latched = st->lv; -} - -/* -============================== -StudioDrawPlayer - -============================== -*/ -int CGameStudioModelRenderer::StudioDrawPlayer( int flags, entity_state_t *pplayer ) -{ - int iret = 0; - - bool isLocalPlayer = false; - - // Set up for client? - if ( m_bLocal && IEngineStudio.GetCurrentEntity() == gEngfuncs.GetLocalPlayer() ) - { - isLocalPlayer = true; - } - - if ( isLocalPlayer ) - { - // Store original data - SavePlayerState( pplayer ); - - // Copy in client side animation data - SetupClientAnimation( pplayer ); - } - - // Call real draw function - iret = _StudioDrawPlayer( flags, pplayer ); - - // Restore for client? - if ( isLocalPlayer ) - { - // Restore the original data for the player - RestorePlayerState( pplayer ); - } - - return iret; -} - -/* -==================== -_StudioDrawPlayer - -==================== -*/ -int CGameStudioModelRenderer::_StudioDrawPlayer( int flags, entity_state_t *pplayer ) -{ - alight_t lighting; - vec3_t dir; - - m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); - IEngineStudio.GetTimes( &m_nFrameCount, &m_clTime, &m_clOldTime ); - IEngineStudio.GetViewInfo( m_vRenderOrigin, m_vUp, m_vRight, m_vNormal ); - IEngineStudio.GetAliasScale( &m_fSoftwareXScale, &m_fSoftwareYScale ); - - m_nPlayerIndex = pplayer->number - 1; - - if (m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients()) - return 0; - - m_pRenderModel = IEngineStudio.SetupPlayerModel( m_nPlayerIndex ); - if (m_pRenderModel == NULL) - return 0; - - m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (m_pRenderModel); - IEngineStudio.StudioSetHeader( m_pStudioHeader ); - IEngineStudio.SetRenderModel( m_pRenderModel ); - - if (pplayer->gaitsequence) - { - vec3_t orig_angles; - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - - VectorCopy( m_pCurrentEntity->angles, orig_angles ); - - StudioProcessGait( pplayer ); - - m_pPlayerInfo->gaitsequence = pplayer->gaitsequence; - m_pPlayerInfo = NULL; - - StudioSetUpTransform( 0 ); - VectorCopy( orig_angles, m_pCurrentEntity->angles ); - } - else - { - m_pCurrentEntity->curstate.controller[0] = 127; - m_pCurrentEntity->curstate.controller[1] = 127; - m_pCurrentEntity->curstate.controller[2] = 127; - m_pCurrentEntity->curstate.controller[3] = 127; - m_pCurrentEntity->latched.prevcontroller[0] = m_pCurrentEntity->curstate.controller[0]; - m_pCurrentEntity->latched.prevcontroller[1] = m_pCurrentEntity->curstate.controller[1]; - m_pCurrentEntity->latched.prevcontroller[2] = m_pCurrentEntity->curstate.controller[2]; - m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; - - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - m_pPlayerInfo->gaitsequence = 0; - - StudioSetUpTransform( 0 ); - } - - if (flags & STUDIO_RENDER) - { - // see if the bounding box lets us trivially reject, also sets - if (!IEngineStudio.StudioCheckBBox ()) - return 0; - - (*m_pModelsDrawn)++; - (*m_pStudioModelCount)++; // render data cache cookie - - if (m_pStudioHeader->numbodyparts == 0) - return 1; - } - - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - StudioSetupBones( ); - StudioSaveBones( ); - m_pPlayerInfo->renderframe = m_nFrameCount; - - m_pPlayerInfo = NULL; - - if (flags & STUDIO_EVENTS) - { - StudioCalcAttachments( ); - IEngineStudio.StudioClientEvents( ); - // copy attachments into global entity array - if ( m_pCurrentEntity->index > 0 ) - { - cl_entity_t *ent = gEngfuncs.GetEntityByIndex( m_pCurrentEntity->index ); - - memcpy( ent->attachment, m_pCurrentEntity->attachment, sizeof( vec3_t ) * 4 ); - } - } - - if (flags & STUDIO_RENDER) - { - /* - if (m_pCvarHiModels->value && m_pRenderModel != m_pCurrentEntity->model ) - { - // show highest resolution multiplayer model - m_pCurrentEntity->curstate.body = 255; - } - - if (!(m_pCvarDeveloper->value == 0 && gEngfuncs.GetMaxClients() == 1 ) && ( m_pRenderModel == m_pCurrentEntity->model ) ) - { - m_pCurrentEntity->curstate.body = 1; // force helmet - } - */ - - lighting.plightvec = dir; - IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting ); - - IEngineStudio.StudioEntityLight( &lighting ); - - // model and frame independant - IEngineStudio.StudioSetupLighting (&lighting); - - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - - // get remap colors - m_nTopColor = m_pPlayerInfo->topcolor; - if (m_nTopColor < 0) - m_nTopColor = 0; - if (m_nTopColor > 360) - m_nTopColor = 360; - m_nBottomColor = m_pPlayerInfo->bottomcolor; - if (m_nBottomColor < 0) - m_nBottomColor = 0; - if (m_nBottomColor > 360) - m_nBottomColor = 360; - - IEngineStudio.StudioSetRemapColors( m_nTopColor, m_nBottomColor ); - - StudioRenderModel( ); - m_pPlayerInfo = NULL; - - if (pplayer->weaponmodel) - { - cl_entity_t saveent = *m_pCurrentEntity; - - model_t *pweaponmodel = IEngineStudio.GetModelByIndex( pplayer->weaponmodel ); - - m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (pweaponmodel); - IEngineStudio.StudioSetHeader( m_pStudioHeader ); - - StudioMergeBones( pweaponmodel); - - IEngineStudio.StudioSetupLighting (&lighting); - - StudioRenderModel( ); - - StudioCalcAttachments( ); - - *m_pCurrentEntity = saveent; - } - } - - return 1; -} - -/* -==================== -Studio_FxTransform - -==================== -*/ -void CGameStudioModelRenderer::StudioFxTransform( cl_entity_t *ent, float transform[3][4] ) -{ - switch( ent->curstate.renderfx ) - { - case kRenderFxDistort: - case kRenderFxHologram: - if ( gEngfuncs.pfnRandomLong(0,49) == 0 ) - { - int axis = gEngfuncs.pfnRandomLong(0,1); - if ( axis == 1 ) // Choose between x & z - axis = 2; - VectorScale( transform[axis], gEngfuncs.pfnRandomFloat(1,1.484), transform[axis] ); - } - else if ( gEngfuncs.pfnRandomLong(0,49) == 0 ) - { - float offset; - int axis = gEngfuncs.pfnRandomLong(0,1); - if ( axis == 1 ) // Choose between x & z - axis = 2; - offset = gEngfuncs.pfnRandomFloat(-10,10); - transform[gEngfuncs.pfnRandomLong(0,2)][3] += offset; - } - break; - case kRenderFxExplode: - { - if ( iRenderStateChanged ) - { - g_flStartScaleTime = m_clTime; - iRenderStateChanged = FALSE; - } - - // Make the Model continue to shrink - float flTimeDelta = m_clTime - g_flStartScaleTime; - if ( flTimeDelta > 0 ) - { - float flScale = 0.001; - // Goes almost all away - if ( flTimeDelta <= 2.0 ) - flScale = 1.0 - (flTimeDelta / 2.0); - - for (int i = 0; i < 3; i++) - { - for (int j = 0; j < 3; j++) - transform[i][j] *= flScale; - } - } - } - break; - } -} - -//////////////////////////////////// -// Hooks to class implementation -//////////////////////////////////// - -/* -==================== -R_StudioDrawPlayer - -==================== -*/ -int R_StudioDrawPlayer( int flags, entity_state_t *pplayer ) -{ - return g_StudioRenderer.StudioDrawPlayer( flags, pplayer ); -} - -/* -==================== -R_StudioDrawModel - -==================== -*/ -int R_StudioDrawModel( int flags ) -{ - return g_StudioRenderer.StudioDrawModel( flags ); -} - -/* -==================== -R_StudioInit - -==================== -*/ -void R_StudioInit( void ) -{ - g_StudioRenderer.Init(); -} - -// The simple drawing interface we'll pass back to the engine -r_studio_interface_t studio = -{ - STUDIO_INTERFACE_VERSION, - R_StudioDrawModel, - R_StudioDrawPlayer, -}; - -/* -==================== -HUD_GetStudioModelInterface - -Export this function for the engine to use the studio renderer class to render objects. -==================== -*/ -extern "C" int DLLEXPORT HUD_GetStudioModelInterface( int version, struct r_studio_interface_s **ppinterface, struct engine_studio_api_s *pstudio ) -{ - if ( version != STUDIO_INTERFACE_VERSION ) - return 0; - - // Point the engine to our callbacks - *ppinterface = &studio; - - // Copy in engine helper functions - memcpy( &IEngineStudio, pstudio, sizeof( IEngineStudio ) ); - - // Initialize local variables, etc. - R_StudioInit(); - - // Success - return 1; -} diff --git a/ricochet/cl_dll/GameStudioModelRenderer.h b/ricochet/cl_dll/GameStudioModelRenderer.h deleted file mode 100644 index 64f6c8b..0000000 --- a/ricochet/cl_dll/GameStudioModelRenderer.h +++ /dev/null @@ -1,48 +0,0 @@ -#if !defined( GAMESTUDIOMODELRENDERER_H ) -#define GAMESTUDIOMODELRENDERER_H -#if defined( _WIN32 ) -#pragma once -#endif - -/* -==================== -CGameStudioModelRenderer - -==================== -*/ -class CGameStudioModelRenderer : public CStudioModelRenderer -{ -public: - CGameStudioModelRenderer( void ); - - // Set up model bone positions - virtual void StudioSetupBones ( void ); - - // Estimate gait frame for player - virtual void StudioEstimateGait ( entity_state_t *pplayer ); - - // Process movement of player - virtual void StudioProcessGait ( entity_state_t *pplayer ); - - // Player drawing code - virtual int StudioDrawPlayer( int flags, entity_state_t *pplayer ); - virtual int _StudioDrawPlayer( int flags, entity_state_t *pplayer ); - - // Apply special effects to transform matrix - virtual void StudioFxTransform( cl_entity_t *ent, float transform[3][4] ); - -private: - // For local player, in third person, we need to store real render data and then - // setup for with fake/client side animation data - void SavePlayerState( entity_state_t *pplayer ); - // Called to set up local player's animation values - void SetupClientAnimation( entity_state_t *pplayer ); - // Called to restore original player state information - void RestorePlayerState( entity_state_t *pplayer ); - -private: - // Private data - bool m_bLocal; -}; - -#endif // GAMESTUDIOMODELRENDERER_H \ No newline at end of file diff --git a/ricochet/cl_dll/Ricochet_BSPFile.h b/ricochet/cl_dll/Ricochet_BSPFile.h deleted file mode 100644 index 8e21ea0..0000000 --- a/ricochet/cl_dll/Ricochet_BSPFile.h +++ /dev/null @@ -1,41 +0,0 @@ -#if !defined( RICOCHET_BSPFILE_H ) -#define RICOCHET_BSPFILE_H -#ifdef _WIN32 -#pragma once -#endif - -// MINI-version of BSPFILE.H to support Ricochet entity lump extraction stuff. - -#define BSPVERSION 30 - -typedef struct -{ - int fileofs, filelen; -} lump_t; - -#define LUMP_ENTITIES 0 -#define LUMP_PLANES 1 -#define LUMP_TEXTURES 2 -#define LUMP_VERTEXES 3 -#define LUMP_VISIBILITY 4 -#define LUMP_NODES 5 -#define LUMP_TEXINFO 6 -#define LUMP_FACES 7 -#define LUMP_LIGHTING 8 -#define LUMP_CLIPNODES 9 -#define LUMP_LEAFS 10 -#define LUMP_MARKSURFACES 11 -#define LUMP_EDGES 12 -#define LUMP_SURFEDGES 13 -#define LUMP_MODELS 14 - -#define HEADER_LUMPS 15 - -typedef struct -{ - int version; - lump_t lumps[HEADER_LUMPS]; -} dheader_t; - - -#endif // RICOCHET_BSPFILE_H \ No newline at end of file diff --git a/ricochet/cl_dll/Ricochet_JumpPads.cpp b/ricochet/cl_dll/Ricochet_JumpPads.cpp deleted file mode 100644 index b3787b6..0000000 --- a/ricochet/cl_dll/Ricochet_JumpPads.cpp +++ /dev/null @@ -1,580 +0,0 @@ -#include "extdll.h" -#include "entity_state.h" -#include "pm_defs.h" -#include "pm_movevars.h" -#include "hud_iface.h" -#include "com_model.h" -#include "event_api.h" -#include "com_weapons.h" -#include "event_flags.h" -#include "Ricochet_BSPFile.h" - -extern playermove_t *pmove; -extern int g_runfuncs; - -// Don't support more than MAX_PADS pads ( map still can load, but we'll just have some pads that don't predict. ) -#define MAX_PADS 256 - -// We only care about two kinds of entities for now: Jump pads and their targets -// FIXME: After loading, store a pointer from pad to target instead of looking up all the time. -typedef enum -{ - // Entity is a jump pad - RIC_PAD = 0, - // Entity is a target - RIC_TARGET -} ric_padtype_t; - -typedef struct -{ - // Type of entity - ric_padtype_t type; - - // Classname - char classname[ 32 ]; - - // Model name - char modelname[ 32 ]; - - // What this entity targets - char target[ 32 ]; - - // If entity is a target, the name tag it uses - char targetname[ 32 ]; - - // Orientation of the pad - float angles[3]; - - // Target origin - float origin[3]; - - // Bounding box of the pad - float absmin[3]; - float absmax[3]; - - // Model associated with the pad - struct model_s *model; - - float height; -} ric_pad_t; - -// Pad/Target entity database -static ric_pad_t s_pads[ MAX_PADS ]; -static int s_num_pads = 0; - -// We'll use this for playing the jump sounds locally. -static unsigned short s_usJump; - -/* -============================== -Ricochet_SetKeyValue - -Fill in key/values fro the pad -============================== -*/ -void Ricochet_SetKeyValue( ric_pad_t *pad, const char *key, const char *value ) -{ - float x, y, z; - - if ( !stricmp( key, "classname" ) ) - { - strcpy( pad->classname, value ); - } - else if ( !stricmp( key, "target" ) ) - { - strcpy( pad->target, value ); - } - else if ( !stricmp( key, "targetname" ) ) - { - strcpy( pad->targetname, value ); - } - else if ( !stricmp( key, "model" ) ) - { - strcpy( pad->modelname, value ); - } - else if ( !stricmp( key, "height" ) ) - { - pad->height = atof( value ); - } - else if ( !stricmp( key, "angles" ) ) - { - if ( sscanf( value, "%f %f %f", &x, &y, &z ) == 3 ) - { - pad->angles[ 0 ] = x ; - pad->angles[ 1 ] = y; - pad->angles[ 2 ] = z; - } - } - else if ( !stricmp( key, "origin" ) ) - { - if ( sscanf( value, "%f %f %f", &x, &y, &z ) == 3 ) - { - pad->origin[ 0 ] = x; - pad->origin[ 1 ] = y; - pad->origin[ 2 ] = z; - } - } -} - -/* -============================== -Ricochet_ParsePad - -Evaluate Key/Value pairs for the entity -============================== -*/ -char *Ricochet_ParsePad( char *buffer, ric_pad_t *pad, int *error ) -{ - char key[256]; - char token[ 1024 ]; - int n; - - memset( pad, 0, sizeof( *pad ) ); - - while (1) - { - // Parse key - buffer = gEngfuncs.COM_ParseFile ( buffer, token ); - if ( token[0] == '}' ) - break; - - // Ran out of input buffer? - if ( !buffer ) - { - *error = 1; - break; - } - - // Store off the key - strcpy ( key, token ); - - // Fix heynames with trailing spaces - n = strlen( key ); - while (n && key[n-1] == ' ') - { - key[n-1] = 0; - n--; - } - - // Parse value - buffer = gEngfuncs.COM_ParseFile ( buffer, token ); - - // Ran out of buffer? - if (!buffer) - { - *error = 1; - break; - } - - // Hit the end instead of a value? - if ( token[0] == '}' ) - { - *error = 1; - break; - } - - // Assign k/v pair - Ricochet_SetKeyValue( pad, key, token ); - } - - // Return what's left in the stream - return buffer; -} - -/* -============================== -Ricochet_ProcessEnts - -Parse through entity lump looking for pads or targets -============================== -*/ -void Ricochet_ProcessEnts( char *buffer ) -{ - int i; - char token[ 1024 ]; - ric_pad_t *pad = NULL; - int error = 0; - - // parse entities from entity lump of .bsp file - while (1) - { - // parse the opening brace - buffer = gEngfuncs.COM_ParseFile ( buffer, token ); - if (!buffer) - break; - - // Didn't find opening brace? - if ( token[0] != '{' ) - { - gEngfuncs.Con_Printf ("Ricochet_ProcessEnts: found %s when expecting {\n", token ); - return; - } - - // Assume we're filling in this pad - pad = &s_pads[ s_num_pads ]; - - // Fill in data - buffer = Ricochet_ParsePad( buffer, pad, &error ); - - // Check for errors and abort if any - if ( error ) - { - gEngfuncs.Con_Printf ("Ricochet_ProcessEnts: error parsing entities\n" ); - return; - } - - // Check classname - if ( stricmp( pad->classname, "trigger_jump" ) && stricmp( pad->classname, "info_target" ) ) - continue; - - // Set type based on classname - if ( !stricmp( pad->classname, "trigger_jump" ) ) - { - pad->type = RIC_PAD; - } - else - { - pad->type = RIC_TARGET; - } - - // Load up the model - pad->model = gEngfuncs.CL_LoadModel( pad->modelname, NULL ); - if ( pad->model ) - { - // Fill in abs bbox - for ( i = 0; i < 3; i++ ) - { - pad->absmin[ i ] = pad->model->mins[ i ] - 1.0; - pad->absmax[ i ] = pad->model->maxs[ i ] + 1.0; - } - } - - // If we got to here, we're using the entity - s_num_pads++; - - // No more room... - if ( s_num_pads >= MAX_PADS ) - break; - } -} - -/* -============================== -Ricochet_LoadEntityLump - -Open the .bsp and read in the entity lump -============================== -*/ -char *Ricochet_LoadEntityLump( const char *filename ) -{ - int i; - dheader_t header; - int size = 0; - lump_t *curLump; - char *fileBuffer = NULL, *buffer, *entlump; - - fileBuffer = (char *)gEngfuncs.COM_LoadFile((char *)filename, 5, &size); - if (size < sizeof(dheader_t)) - return NULL; - - // Read in the .bsp header - memcpy(&header, fileBuffer, sizeof(dheader_t)); - - // Check the version - i = header.version; - if ( i != 29 && i != 30) - { - gEngfuncs.COM_FreeFile(fileBuffer); - gEngfuncs.Con_Printf("Ricochet_LoadEntityLump: Map [%s] has incorrect BSP version (%i should be %i).\n", filename, i, BSPVERSION); - return NULL; - } - - // Get entity lump - curLump = &header.lumps[ LUMP_ENTITIES ]; - // and entity lump size - size = curLump->filelen; - - // Jump to it - entlump = fileBuffer + curLump->fileofs; - - // Allocate sufficient memmory - buffer = (char *)malloc( size + 1 ); - if ( !buffer ) - { - gEngfuncs.COM_FreeFile(fileBuffer); - gEngfuncs.Con_Printf("Ricochet_LoadEntityLump: Couldn't allocate %i bytes\n", size + 1 ); - return NULL; - } - - // Read in the entity lump - memcpy( buffer, entlump, size ); - - // Terminate the string - buffer[ size ] = '\0'; - - if (fileBuffer) - { - gEngfuncs.COM_FreeFile(fileBuffer); - } - - return buffer; -} - -/* -============================== -Ricochet_LoadJumpPads - -Load in the .bsp file and process the entities -============================== -*/ -void Ricochet_LoadJumpPads( const char *map ) -{ - char *buffer = NULL; - char filename[ 256 ]; - - sprintf( filename, "%s/%s", gEngfuncs.pfnGetGameDirectory(), map ); - - // TODO: Fix Slashes? - - // Reset count - s_num_pads = 0; - - // Load entity lump - buffer = Ricochet_LoadEntityLump( filename ); - if ( !buffer ) - return; - - // Process buffer and extract pads/targets - Ricochet_ProcessEnts( buffer ); - - // Discard buffer - free( buffer ); -} - -/* -============================== -Ricochet_FindTarget - -Search entity list for target matching "name" -============================== -*/ -ric_pad_t *Ricochet_FindTarget( const char *name, int numpads, ric_pad_t *pads ) -{ - int i; - ric_pad_t *target; - - // Find the target - for ( i = 0; i < numpads; i++ ) - { - target = &pads[ i ]; - if ( !target ) - continue; - - if ( stricmp( target->targetname, name ) ) - continue; - - return target; - } - - return NULL; -} - -/* -============================== -Ricochet_PadTouched - -Register impact ( impart velocity on player and if final function call, play appropriate jump sound ) -============================== -*/ -void Ricochet_PadTouched( int numpads, ric_pad_t *pads, ric_pad_t *pad, struct local_state_s *player ) -{ - int i; - ric_pad_t *target; - float origin[ 3 ]; - pmtrace_t tr; - float flGravity = pmove->movevars->gravity; - - float vecMidPoint[3]; - float end[ 3 ]; - - // Ricochet jump pads use default jump height - float flHeight = 150; - - float zero[ 3 ] = { 0.0, 0.0, 0.0 }; - - // Find the target - target = Ricochet_FindTarget( pad->target, numpads, pads ); - - // Target now points to target pad - for ( i = 0; i < 3; i++ ) - { - origin[ i ] = player->playerstate.origin[ i ]; - - // Get a rough idea of how high to launch - vecMidPoint[ i ] = origin[ i ] + ( target->origin[ i ] - origin[ i ]) * 0.5; - end[ i ] = vecMidPoint[ i ]; - } - - if ( pad->height != 0.0 ) - { - flHeight = pad->height; - } - - // Move up by height - end[ 2 ] += flHeight; - - // See if we can reach the apex from the midpoint - gEngfuncs.pEventAPI->EV_PlayerTrace( vecMidPoint, end, PM_STUDIO_BOX, -1, &tr ); - - // Use the end point of the trace as the midpoint of the actual toss - for ( i = 0; i < 3; i++ ) - { - vecMidPoint[i] = tr.endpos[i]; - } - - // Subtract some units so we don't hit the ceiling) - vecMidPoint[2] -= 15; - - // How high should we travel to reach the apex - float distance1 = fabs(vecMidPoint[2] - origin[2]); - float distance2 = fabs(vecMidPoint[2] - target->origin[2]); - - // How long will it take to travel this distance - float time1 = sqrt( distance1 / (0.5 * flGravity) ); - float time2 = sqrt( distance2 / (0.5 * flGravity) ); - if (time1 < 0.1) - return; - - // Determine how hard to launch to get there in time. - float vecTargetVel[3]; - - for ( i = 0; i < 3; i++ ) - { - vecTargetVel[ i ] = (target->origin[ i ] - origin[ i ]) / (time1 + time2); - } - - // Adjust upward velocity needed - vecTargetVel[ 2 ] = flGravity * time1; - - // Fill in needed velocity - for ( i = 0; i < 3; i++ ) - { - player->client.velocity[i] = vecTargetVel[i]; - } - - // Play sound if appropriate - if ( s_usJump && g_runfuncs ) - { - gEngfuncs.pfnPlaybackEvent( FEV_NOTHOST, NULL, s_usJump, 0.0, zero, zero, 0.0, 0.0, 0, 0, 0, 0 ); - } -} - -/* -============================== -Ricochet_TouchPads - -See if player's resting position impacts any jump pads -============================== -*/ -void Ricochet_TouchPads ( struct local_state_s *player, ric_pad_t *pads, int numpads ) -{ - int i, j; - ric_pad_t *pad; - float absmin[3], absmax[3]; - physent_t pe; - hull_t *hull; - int num; - float test[3]; - float pmins[ 3 ] = { 16, 16, 36 }; - - // Determine player's bbox - for ( j = 0; j < 3; j++ ) - { - absmin[ j ] = player->playerstate.origin[ j ] - pmins[ j ]; - absmax[ j ] = player->playerstate.origin[ j ] + pmins[ j ]; - } - - // Cycle through pads looking for a match - for ( i = 0; i < numpads; i++ ) - { - pad = &pads[ i ]; - if ( !pad ) - continue; - - // Target entities don't make us jump - if ( pad->type != RIC_PAD ) - continue; - - // Trivial reject? - if ( absmin[0] > pad->absmax[0] - || absmin[1] > pad->absmax[1] - || absmin[2] > pad->absmax[2] - || absmax[0] < pad->absmin[0] - || absmax[1] < pad->absmin[1] - || absmax[2] < pad->absmin[2] ) - continue; - - // Set up physent for the test case - pe.model = pad->model; - pe.origin = pad->origin; - - // Use standing player hull - pmove->usehull = 0; - - // Make sure it's a brush model, of course - if ( !pe.model || (modtype_t)pmove->PM_GetModelType( pe.model ) != mod_brush ) - continue; - - // Get the hull - hull = (hull_t *)pmove->PM_HullForBsp( &pe, test ); - num = hull->firstclipnode; - - // Offset the origin by the offset appropriate for this hull. - for ( j = 0; j < 3; j++ ) - { - test[ j ] = player->playerstate.origin[ j ] - test[ j ]; - } - - // Test the player's hull for intersection with this model - if ( pmove->PM_HullPointContents ( hull, num, test ) != CONTENTS_SOLID ) - { - continue; - } - - // TOUCHED!!! - Ricochet_PadTouched( numpads, pads, pad, player ); - - // Only touch one pad at a time - break; - } -} - -/* -============================== -Ricochet_CheckJumpPads - -Load data if needed, otherwise just run checks on player's final position to see if jump pad needs - to impart velocity on the player. -============================== -*/ -void Ricochet_CheckJumpPads( struct local_state_s *from, struct local_state_s *to ) -{ - static char current_level[ 128 ]; - - // See if we've changed to a new map - if ( stricmp( current_level, gEngfuncs.pfnGetLevelName() ) ) - { - strcpy( current_level, gEngfuncs.pfnGetLevelName() ); - Ricochet_LoadJumpPads( current_level ); - - // Grab sound event - s_usJump = gEngfuncs.pfnPrecacheEvent( 1, "events/jump.sc" ); - } - - // Not while spectating - if ( to->client.iuser1 ) - return; - - // Run test - Ricochet_TouchPads( to, s_pads, s_num_pads ); -} \ No newline at end of file diff --git a/ricochet/cl_dll/Ricochet_JumpPads.h b/ricochet/cl_dll/Ricochet_JumpPads.h deleted file mode 100644 index 7243df9..0000000 --- a/ricochet/cl_dll/Ricochet_JumpPads.h +++ /dev/null @@ -1,9 +0,0 @@ -#if !defined( RICHOCHET_JUMPADS_H ) -#define RICHOCHET_JUMPADS_H -#ifdef _WIN32 -#pragma once -#endif - -void Ricochet_CheckJumpPads( struct local_state_s *from, struct local_state_s *to ); - -#endif // RICHOCHET_JUMPADS_H \ No newline at end of file diff --git a/ricochet/cl_dll/StudioModelRenderer.cpp b/ricochet/cl_dll/StudioModelRenderer.cpp deleted file mode 100644 index d346723..0000000 --- a/ricochet/cl_dll/StudioModelRenderer.cpp +++ /dev/null @@ -1,1607 +0,0 @@ -// studio_model.cpp -// routines for setting up to draw 3DStudio models - -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "com_model.h" -#include "studio.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "dlight.h" -#include "triangleapi.h" - -#include -#include -#include -#include - -#include "studio_util.h" -#include "r_studioint.h" - -#include "StudioModelRenderer.h" -#include "GameStudioModelRenderer.h" - -// Global engine <-> studio model rendering code interface -engine_studio_api_t IEngineStudio; - -///////////////////// -// Implementation of CStudioModelRenderer.h - -/* -==================== -Init - -==================== -*/ -void CStudioModelRenderer::Init( void ) -{ - // Set up some variables shared with engine - m_pCvarHiModels = IEngineStudio.GetCvar( "cl_himodels" ); - m_pCvarDeveloper = IEngineStudio.GetCvar( "developer" ); - m_pCvarDrawEntities = IEngineStudio.GetCvar( "r_drawentities" ); - - m_pChromeSprite = IEngineStudio.GetChromeSprite(); - - IEngineStudio.GetModelCounters( &m_pStudioModelCount, &m_pModelsDrawn ); - - // Get pointers to engine data structures - m_pbonetransform = (float (*)[MAXSTUDIOBONES][3][4])IEngineStudio.StudioGetBoneTransform(); - m_plighttransform = (float (*)[MAXSTUDIOBONES][3][4])IEngineStudio.StudioGetLightTransform(); - m_paliastransform = (float (*)[3][4])IEngineStudio.StudioGetAliasTransform(); - m_protationmatrix = (float (*)[3][4])IEngineStudio.StudioGetRotationMatrix(); -} - -/* -==================== -CStudioModelRenderer - -==================== -*/ -CStudioModelRenderer::CStudioModelRenderer( void ) -{ - m_fDoInterp = 1; - m_fGaitEstimation = 1; - m_pCurrentEntity = NULL; - m_pCvarHiModels = NULL; - m_pCvarDeveloper = NULL; - m_pCvarDrawEntities = NULL; - m_pChromeSprite = NULL; - m_pStudioModelCount = NULL; - m_pModelsDrawn = NULL; - m_protationmatrix = NULL; - m_paliastransform = NULL; - m_pbonetransform = NULL; - m_plighttransform = NULL; - m_pStudioHeader = NULL; - m_pBodyPart = NULL; - m_pSubModel = NULL; - m_pPlayerInfo = NULL; - m_pRenderModel = NULL; -} - -/* -==================== -~CStudioModelRenderer - -==================== -*/ -CStudioModelRenderer::~CStudioModelRenderer( void ) -{ -} - -/* -==================== -StudioCalcBoneAdj - -==================== -*/ -void CStudioModelRenderer::StudioCalcBoneAdj( float dadt, float *adj, const byte *pcontroller1, const byte *pcontroller2, byte mouthopen ) -{ - int i, j; - float value; - mstudiobonecontroller_t *pbonecontroller; - - pbonecontroller = (mstudiobonecontroller_t *)((byte *)m_pStudioHeader + m_pStudioHeader->bonecontrollerindex); - - for (j = 0; j < m_pStudioHeader->numbonecontrollers; j++) - { - i = pbonecontroller[j].index; - if (i <= 3) - { - // check for 360% wrapping - if (pbonecontroller[j].type & STUDIO_RLOOP) - { - if (abs(pcontroller1[i] - pcontroller2[i]) > 128) - { - int a, b; - a = (pcontroller1[j] + 128) % 256; - b = (pcontroller2[j] + 128) % 256; - value = ((a * dadt) + (b * (1 - dadt)) - 128) * (360.0/256.0) + pbonecontroller[j].start; - } - else - { - value = ((pcontroller1[i] * dadt + (pcontroller2[i]) * (1.0 - dadt))) * (360.0/256.0) + pbonecontroller[j].start; - } - } - else - { - value = (pcontroller1[i] * dadt + pcontroller2[i] * (1.0 - dadt)) / 255.0; - if (value < 0) value = 0; - if (value > 1.0) value = 1.0; - value = (1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end; - } - } - else - { - value = mouthopen / 64.0; - if (value > 1.0) value = 1.0; - value = (1.0 - value) * pbonecontroller[j].start + value * pbonecontroller[j].end; - } - switch(pbonecontroller[j].type & STUDIO_TYPES) - { - case STUDIO_XR: - case STUDIO_YR: - case STUDIO_ZR: - adj[j] = value * (M_PI / 180.0); - break; - case STUDIO_X: - case STUDIO_Y: - case STUDIO_Z: - adj[j] = value; - break; - } - } -} - - -/* -==================== -StudioCalcBoneQuaterion - -==================== -*/ -void CStudioModelRenderer::StudioCalcBoneQuaterion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *q ) -{ - int j, k; - vec4_t q1, q2; - vec3_t angle1, angle2; - mstudioanimvalue_t *panimvalue; - - for (j = 0; j < 3; j++) - { - if (panim->offset[j+3] == 0) - { - angle2[j] = angle1[j] = pbone->value[j+3]; // default; - } - else - { - panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]); - k = frame; - // DEBUG - if (panimvalue->num.total < panimvalue->num.valid) - k = 0; - while (panimvalue->num.total <= k) - { - k -= panimvalue->num.total; - panimvalue += panimvalue->num.valid + 1; - // DEBUG - if (panimvalue->num.total < panimvalue->num.valid) - k = 0; - } - // Bah, missing blend! - if (panimvalue->num.valid > k) - { - angle1[j] = panimvalue[k+1].value; - - if (panimvalue->num.valid > k + 1) - { - angle2[j] = panimvalue[k+2].value; - } - else - { - if (panimvalue->num.total > k + 1) - angle2[j] = angle1[j]; - else - angle2[j] = panimvalue[panimvalue->num.valid+2].value; - } - } - else - { - angle1[j] = panimvalue[panimvalue->num.valid].value; - if (panimvalue->num.total > k + 1) - { - angle2[j] = angle1[j]; - } - else - { - angle2[j] = panimvalue[panimvalue->num.valid + 2].value; - } - } - angle1[j] = pbone->value[j+3] + angle1[j] * pbone->scale[j+3]; - angle2[j] = pbone->value[j+3] + angle2[j] * pbone->scale[j+3]; - } - - if (pbone->bonecontroller[j+3] != -1) - { - angle1[j] += adj[pbone->bonecontroller[j+3]]; - angle2[j] += adj[pbone->bonecontroller[j+3]]; - } - } - - if (!VectorCompare( angle1, angle2 )) - { - AngleQuaternion( angle1, q1 ); - AngleQuaternion( angle2, q2 ); - QuaternionSlerp( q1, q2, s, q ); - } - else - { - AngleQuaternion( angle1, q ); - } -} - -/* -==================== -StudioCalcBonePosition - -==================== -*/ -void CStudioModelRenderer::StudioCalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *pos ) -{ - int j, k; - mstudioanimvalue_t *panimvalue; - - for (j = 0; j < 3; j++) - { - pos[j] = pbone->value[j]; // default; - if (panim->offset[j] != 0) - { - panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]); - /* - if (i == 0 && j == 0) - Con_DPrintf("%d %d:%d %f\n", frame, panimvalue->num.valid, panimvalue->num.total, s ); - */ - - k = frame; - // DEBUG - if (panimvalue->num.total < panimvalue->num.valid) - k = 0; - // find span of values that includes the frame we want - while (panimvalue->num.total <= k) - { - k -= panimvalue->num.total; - panimvalue += panimvalue->num.valid + 1; - // DEBUG - if (panimvalue->num.total < panimvalue->num.valid) - k = 0; - } - // if we're inside the span - if (panimvalue->num.valid > k) - { - // and there's more data in the span - if (panimvalue->num.valid > k + 1) - { - pos[j] += (panimvalue[k+1].value * (1.0 - s) + s * panimvalue[k+2].value) * pbone->scale[j]; - } - else - { - pos[j] += panimvalue[k+1].value * pbone->scale[j]; - } - } - else - { - // are we at the end of the repeating values section and there's another section with data? - if (panimvalue->num.total <= k + 1) - { - pos[j] += (panimvalue[panimvalue->num.valid].value * (1.0 - s) + s * panimvalue[panimvalue->num.valid + 2].value) * pbone->scale[j]; - } - else - { - pos[j] += panimvalue[panimvalue->num.valid].value * pbone->scale[j]; - } - } - } - if ( pbone->bonecontroller[j] != -1 && adj ) - { - pos[j] += adj[pbone->bonecontroller[j]]; - } - } -} - -/* -==================== -StudioSlerpBones - -==================== -*/ -void CStudioModelRenderer::StudioSlerpBones( vec4_t q1[], float pos1[][3], vec4_t q2[], float pos2[][3], float s ) -{ - int i; - vec4_t q3; - float s1; - - if (s < 0) s = 0; - else if (s > 1.0) s = 1.0; - - s1 = 1.0 - s; - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - QuaternionSlerp( q1[i], q2[i], s, q3 ); - q1[i][0] = q3[0]; - q1[i][1] = q3[1]; - q1[i][2] = q3[2]; - q1[i][3] = q3[3]; - pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s; - pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s; - pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s; - } -} - -/* -==================== -StudioGetAnim - -==================== -*/ -mstudioanim_t *CStudioModelRenderer::StudioGetAnim( model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc ) -{ - mstudioseqgroup_t *pseqgroup; - cache_user_t *paSequences; - - pseqgroup = (mstudioseqgroup_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqgroupindex) + pseqdesc->seqgroup; - - if (pseqdesc->seqgroup == 0) - { - return (mstudioanim_t *)((byte *)m_pStudioHeader + pseqdesc->animindex); - } - - paSequences = (cache_user_t *)m_pSubModel->submodels; - - if (paSequences == NULL) - { - paSequences = (cache_user_t *)IEngineStudio.Mem_Calloc( 16, sizeof( cache_user_t ) ); // UNDONE: leak! - m_pSubModel->submodels = (dmodel_t *)paSequences; - } - - if (!IEngineStudio.Cache_Check( (struct cache_user_s *)&(paSequences[pseqdesc->seqgroup]))) - { - gEngfuncs.Con_DPrintf("loading %s\n", pseqgroup->name ); - IEngineStudio.LoadCacheFile( pseqgroup->name, (struct cache_user_s *)&paSequences[pseqdesc->seqgroup] ); - } - return (mstudioanim_t *)((byte *)paSequences[pseqdesc->seqgroup].data + pseqdesc->animindex); -} - -/* -==================== -StudioPlayerBlend - -==================== -*/ -void CStudioModelRenderer::StudioPlayerBlend( mstudioseqdesc_t *pseqdesc, int *pBlend, float *pPitch ) -{ - // calc up/down pointing - *pBlend = (*pPitch * 3); - if (*pBlend < pseqdesc->blendstart[0]) - { - *pPitch -= pseqdesc->blendstart[0] / 3.0; - *pBlend = 0; - } - else if (*pBlend > pseqdesc->blendend[0]) - { - *pPitch -= pseqdesc->blendend[0] / 3.0; - *pBlend = 255; - } - else - { - if (pseqdesc->blendend[0] - pseqdesc->blendstart[0] < 0.1) // catch qc error - *pBlend = 127; - else - *pBlend = 255 * (*pBlend - pseqdesc->blendstart[0]) / (pseqdesc->blendend[0] - pseqdesc->blendstart[0]); - *pPitch = 0; - } -} - -/* -==================== -StudioSetUpTransform - -==================== -*/ -void CStudioModelRenderer::StudioSetUpTransform (int trivial_accept) -{ - int i; - vec3_t angles; - vec3_t modelpos; - - VectorCopy( m_pCurrentEntity->origin, modelpos ); - -// TODO: should really be stored with the entity instead of being reconstructed -// TODO: should use a look-up table -// TODO: could cache lazily, stored in the entity - angles[ROLL] = m_pCurrentEntity->curstate.angles[ROLL]; - angles[PITCH] = m_pCurrentEntity->curstate.angles[PITCH]; - angles[YAW] = m_pCurrentEntity->curstate.angles[YAW]; - - if (m_pCurrentEntity->curstate.movetype == MOVETYPE_STEP) - { - float f = 0; - float d; - - // don't do it if the goalstarttime hasn't updated in a while. - - // NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit - // was increased to 1.0 s., which is 2x the max lag we are accounting for. - - if ( ( m_clTime < m_pCurrentEntity->curstate.animtime + 1.0f ) && - ( m_pCurrentEntity->curstate.animtime != m_pCurrentEntity->latched.prevanimtime ) ) - { - f = (m_clTime - m_pCurrentEntity->curstate.animtime) / (m_pCurrentEntity->curstate.animtime - m_pCurrentEntity->latched.prevanimtime); - } - - if (m_fDoInterp) - { - // ugly hack to interpolate angle, position. current is reached 0.1 seconds after being set - f = f - 1.0; - } - else - { - f = 0; - } - - for (i = 0; i < 3; i++) - { - modelpos[i] += (m_pCurrentEntity->origin[i] - m_pCurrentEntity->latched.prevorigin[i]) * f; - } - - for (i = 0; i < 3; i++) - { - float ang1, ang2; - - ang1 = m_pCurrentEntity->angles[i]; - ang2 = m_pCurrentEntity->latched.prevangles[i]; - - d = ang1 - ang2; - if (d > 180) - { - d -= 360; - } - else if (d < -180) - { - d += 360; - } - - angles[i] += d * f; - } - } - else if ( m_pCurrentEntity->curstate.movetype != MOVETYPE_NONE ) - { - VectorCopy( m_pCurrentEntity->angles, angles ); - } - - angles[PITCH] = -angles[PITCH]; - AngleMatrix (angles, (*m_protationmatrix)); - - if ( !IEngineStudio.IsHardware() ) - { - static float viewmatrix[3][4]; - - VectorCopy (m_vRight, viewmatrix[0]); - VectorCopy (m_vUp, viewmatrix[1]); - VectorInverse (viewmatrix[1]); - VectorCopy (m_vNormal, viewmatrix[2]); - - (*m_protationmatrix)[0][3] = modelpos[0] - m_vRenderOrigin[0]; - (*m_protationmatrix)[1][3] = modelpos[1] - m_vRenderOrigin[1]; - (*m_protationmatrix)[2][3] = modelpos[2] - m_vRenderOrigin[2]; - - ConcatTransforms (viewmatrix, (*m_protationmatrix), (*m_paliastransform)); - - // do the scaling up of x and y to screen coordinates as part of the transform - // for the unclipped case (it would mess up clipping in the clipped case). - // Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y - // correspondingly so the projected x and y come out right - // FIXME: make this work for clipped case too? - if (trivial_accept) - { - for (i=0 ; i<4 ; i++) - { - (*m_paliastransform)[0][i] *= m_fSoftwareXScale * - (1.0 / (ZISCALE * 0x10000)); - (*m_paliastransform)[1][i] *= m_fSoftwareYScale * - (1.0 / (ZISCALE * 0x10000)); - (*m_paliastransform)[2][i] *= 1.0 / (ZISCALE * 0x10000); - - } - } - } - - (*m_protationmatrix)[0][3] = modelpos[0]; - (*m_protationmatrix)[1][3] = modelpos[1]; - (*m_protationmatrix)[2][3] = modelpos[2]; -} - - -/* -==================== -StudioEstimateInterpolant - -==================== -*/ -float CStudioModelRenderer::StudioEstimateInterpolant( void ) -{ - float dadt = 1.0; - - if ( m_fDoInterp && ( m_pCurrentEntity->curstate.animtime >= m_pCurrentEntity->latched.prevanimtime + 0.01 ) ) - { - dadt = (m_clTime - m_pCurrentEntity->curstate.animtime) / 0.1; - if (dadt > 2.0) - { - dadt = 2.0; - } - } - return dadt; -} - -/* -==================== -StudioCalcRotations - -==================== -*/ -void CStudioModelRenderer::StudioCalcRotations ( float pos[][3], vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f ) -{ - int i; - int frame; - mstudiobone_t *pbone; - - float s; - float adj[MAXSTUDIOCONTROLLERS]; - float dadt; - - if (f > pseqdesc->numframes - 1) - { - f = 0; // bah, fix this bug with changing sequences too fast - } - // BUG ( somewhere else ) but this code should validate this data. - // This could cause a crash if the frame # is negative, so we'll go ahead - // and clamp it here - else if ( f < -0.01 ) - { - f = -0.01; - } - - frame = (int)f; - - dadt = StudioEstimateInterpolant( ); - s = (f - frame); - - // add in programtic controllers - pbone = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); - - StudioCalcBoneAdj( dadt, adj, m_pCurrentEntity->curstate.controller, m_pCurrentEntity->latched.prevcontroller, m_pCurrentEntity->mouth.mouthopen ); - - for (i = 0; i < m_pStudioHeader->numbones; i++, pbone++, panim++) - { - StudioCalcBoneQuaterion( frame, s, pbone, panim, adj, q[i] ); - - StudioCalcBonePosition( frame, s, pbone, panim, adj, pos[i] ); - } - - if (pseqdesc->motiontype & STUDIO_X) - { - pos[pseqdesc->motionbone][0] = 0.0; - } - if (pseqdesc->motiontype & STUDIO_Y) - { - pos[pseqdesc->motionbone][1] = 0.0; - } - if (pseqdesc->motiontype & STUDIO_Z) - { - pos[pseqdesc->motionbone][2] = 0.0; - } - - s = 0 * ((1.0 - (f - (int)(f))) / (pseqdesc->numframes)) * m_pCurrentEntity->curstate.framerate; - - if (pseqdesc->motiontype & STUDIO_LX) - { - pos[pseqdesc->motionbone][0] += s * pseqdesc->linearmovement[0]; - } - if (pseqdesc->motiontype & STUDIO_LY) - { - pos[pseqdesc->motionbone][1] += s * pseqdesc->linearmovement[1]; - } - if (pseqdesc->motiontype & STUDIO_LZ) - { - pos[pseqdesc->motionbone][2] += s * pseqdesc->linearmovement[2]; - } -} - -/* -==================== -Studio_FxTransform - -==================== -*/ -void CStudioModelRenderer::StudioFxTransform( cl_entity_t *ent, float transform[3][4] ) -{ - switch( ent->curstate.renderfx ) - { - case kRenderFxDistort: - case kRenderFxHologram: - if ( gEngfuncs.pfnRandomLong(0,49) == 0 ) - { - int axis = gEngfuncs.pfnRandomLong(0,1); - if ( axis == 1 ) // Choose between x & z - axis = 2; - VectorScale( transform[axis], gEngfuncs.pfnRandomFloat(1,1.484), transform[axis] ); - } - else if ( gEngfuncs.pfnRandomLong(0,49) == 0 ) - { - float offset; - int axis = gEngfuncs.pfnRandomLong(0,1); - if ( axis == 1 ) // Choose between x & z - axis = 2; - offset = gEngfuncs.pfnRandomFloat(-10,10); - transform[gEngfuncs.pfnRandomLong(0,2)][3] += offset; - } - break; - case kRenderFxExplode: - { - float scale; - - scale = 1.0 + ( m_clTime - ent->curstate.animtime) * 10.0; - if ( scale > 2 ) // Don't blow up more than 200% - scale = 2; - transform[0][1] *= scale; - transform[1][1] *= scale; - transform[2][1] *= scale; - } - break; - - } -} - -/* -==================== -StudioEstimateFrame - -==================== -*/ -float CStudioModelRenderer::StudioEstimateFrame( mstudioseqdesc_t *pseqdesc ) -{ - double dfdt, f; - - if ( m_fDoInterp ) - { - if ( m_clTime < m_pCurrentEntity->curstate.animtime ) - { - dfdt = 0; - } - else - { - dfdt = (m_clTime - m_pCurrentEntity->curstate.animtime) * m_pCurrentEntity->curstate.framerate * pseqdesc->fps; - - } - } - else - { - dfdt = 0; - } - - if (pseqdesc->numframes <= 1) - { - f = 0; - } - else - { - f = (m_pCurrentEntity->curstate.frame * (pseqdesc->numframes - 1)) / 256.0; - } - - f += dfdt; - - if (pseqdesc->flags & STUDIO_LOOPING) - { - if (pseqdesc->numframes > 1) - { - f -= (int)(f / (pseqdesc->numframes - 1)) * (pseqdesc->numframes - 1); - } - if (f < 0) - { - f += (pseqdesc->numframes - 1); - } - } - else - { - if (f >= pseqdesc->numframes - 1.001) - { - f = pseqdesc->numframes - 1.001; - } - if (f < 0.0) - { - f = 0.0; - } - } - return f; -} - -/* -==================== -StudioSetupBones - -==================== -*/ -void CStudioModelRenderer::StudioSetupBones ( void ) -{ - int i; - double f; - - mstudiobone_t *pbones; - mstudioseqdesc_t *pseqdesc; - mstudioanim_t *panim; - - static float pos[MAXSTUDIOBONES][3]; - static vec4_t q[MAXSTUDIOBONES]; - float bonematrix[3][4]; - - static float pos2[MAXSTUDIOBONES][3]; - static vec4_t q2[MAXSTUDIOBONES]; - static float pos3[MAXSTUDIOBONES][3]; - static vec4_t q3[MAXSTUDIOBONES]; - static float pos4[MAXSTUDIOBONES][3]; - static vec4_t q4[MAXSTUDIOBONES]; - - if (m_pCurrentEntity->curstate.sequence >= m_pStudioHeader->numseq) - { - m_pCurrentEntity->curstate.sequence = 0; - } - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; - - f = StudioEstimateFrame( pseqdesc ); - - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - StudioCalcRotations( pos, q, pseqdesc, panim, f ); - - if (pseqdesc->numblends > 1) - { - float s; - float dadt; - - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos2, q2, pseqdesc, panim, f ); - - dadt = StudioEstimateInterpolant(); - s = (m_pCurrentEntity->curstate.blending[0] * dadt + m_pCurrentEntity->latched.prevblending[0] * (1.0 - dadt)) / 255.0; - - StudioSlerpBones( q, pos, q2, pos2, s ); - - if (pseqdesc->numblends == 4) - { - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos3, q3, pseqdesc, panim, f ); - - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos4, q4, pseqdesc, panim, f ); - - s = (m_pCurrentEntity->curstate.blending[0] * dadt + m_pCurrentEntity->latched.prevblending[0] * (1.0 - dadt)) / 255.0; - StudioSlerpBones( q3, pos3, q4, pos4, s ); - - s = (m_pCurrentEntity->curstate.blending[1] * dadt + m_pCurrentEntity->latched.prevblending[1] * (1.0 - dadt)) / 255.0; - StudioSlerpBones( q, pos, q3, pos3, s ); - } - } - - if (m_fDoInterp && - m_pCurrentEntity->latched.sequencetime && - ( m_pCurrentEntity->latched.sequencetime + 0.2 > m_clTime ) && - ( m_pCurrentEntity->latched.prevsequence < m_pStudioHeader->numseq )) - { - // blend from last sequence - static float pos1b[MAXSTUDIOBONES][3]; - static vec4_t q1b[MAXSTUDIOBONES]; - float s; - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->latched.prevsequence; - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - // clip prevframe - StudioCalcRotations( pos1b, q1b, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - if (pseqdesc->numblends > 1) - { - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos2, q2, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - s = (m_pCurrentEntity->latched.prevseqblending[0]) / 255.0; - StudioSlerpBones( q1b, pos1b, q2, pos2, s ); - - if (pseqdesc->numblends == 4) - { - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos3, q3, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - panim += m_pStudioHeader->numbones; - StudioCalcRotations( pos4, q4, pseqdesc, panim, m_pCurrentEntity->latched.prevframe ); - - s = (m_pCurrentEntity->latched.prevseqblending[0]) / 255.0; - StudioSlerpBones( q3, pos3, q4, pos4, s ); - - s = (m_pCurrentEntity->latched.prevseqblending[1]) / 255.0; - StudioSlerpBones( q1b, pos1b, q3, pos3, s ); - } - } - - s = 1.0 - (m_clTime - m_pCurrentEntity->latched.sequencetime) / 0.2; - StudioSlerpBones( q, pos, q1b, pos1b, s ); - } - else - { - m_pCurrentEntity->latched.prevframe = f; - } - - pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); - - // calc gait animation - if (m_pPlayerInfo && m_pPlayerInfo->gaitsequence != 0) - { - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pPlayerInfo->gaitsequence; - - panim = StudioGetAnim( m_pRenderModel, pseqdesc ); - StudioCalcRotations( pos2, q2, pseqdesc, panim, m_pPlayerInfo->gaitframe ); - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - if (strcmp( pbones[i].name, "Bip01 Spine") == 0) - break; - memcpy( pos[i], pos2[i], sizeof( pos[i] )); - memcpy( q[i], q2[i], sizeof( q[i] )); - } - } - - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - QuaternionMatrix( q[i], bonematrix ); - - bonematrix[0][3] = pos[i][0]; - bonematrix[1][3] = pos[i][1]; - bonematrix[2][3] = pos[i][2]; - - if (pbones[i].parent == -1) - { - if ( IEngineStudio.IsHardware() ) - { - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]); - - // MatrixCopy should be faster... - //ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - MatrixCopy( (*m_pbonetransform)[i], (*m_plighttransform)[i] ); - } - else - { - ConcatTransforms ((*m_paliastransform), bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - } - - // Apply client-side effects to the transformation matrix - StudioFxTransform( m_pCurrentEntity, (*m_pbonetransform)[i] ); - } - else - { - ConcatTransforms ((*m_pbonetransform)[pbones[i].parent], bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_plighttransform)[pbones[i].parent], bonematrix, (*m_plighttransform)[i]); - } - } -} - - -/* -==================== -StudioSaveBones - -==================== -*/ -void CStudioModelRenderer::StudioSaveBones( void ) -{ - int i; - - mstudiobone_t *pbones; - pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); - - m_nCachedBones = m_pStudioHeader->numbones; - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - strcpy( m_nCachedBoneNames[i], pbones[i].name ); - MatrixCopy( (*m_pbonetransform)[i], m_rgCachedBoneTransform[i] ); - MatrixCopy( (*m_plighttransform)[i], m_rgCachedLightTransform[i] ); - } -} - - -/* -==================== -StudioMergeBones - -==================== -*/ -void CStudioModelRenderer::StudioMergeBones ( model_t *m_pSubModel ) -{ - int i, j; - double f; - int do_hunt = true; - - mstudiobone_t *pbones; - mstudioseqdesc_t *pseqdesc; - mstudioanim_t *panim; - - static float pos[MAXSTUDIOBONES][3]; - float bonematrix[3][4]; - static vec4_t q[MAXSTUDIOBONES]; - - if (m_pCurrentEntity->curstate.sequence >= m_pStudioHeader->numseq) - { - m_pCurrentEntity->curstate.sequence = 0; - } - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; - - f = StudioEstimateFrame( pseqdesc ); - - panim = StudioGetAnim( m_pSubModel, pseqdesc ); - StudioCalcRotations( pos, q, pseqdesc, panim, f ); - - pbones = (mstudiobone_t *)((byte *)m_pStudioHeader + m_pStudioHeader->boneindex); - - - for (i = 0; i < m_pStudioHeader->numbones; i++) - { - for (j = 0; j < m_nCachedBones; j++) - { - if (stricmp(pbones[i].name, m_nCachedBoneNames[j]) == 0) - { - MatrixCopy( m_rgCachedBoneTransform[j], (*m_pbonetransform)[i] ); - MatrixCopy( m_rgCachedLightTransform[j], (*m_plighttransform)[i] ); - break; - } - } - if (j >= m_nCachedBones) - { - QuaternionMatrix( q[i], bonematrix ); - - bonematrix[0][3] = pos[i][0]; - bonematrix[1][3] = pos[i][1]; - bonematrix[2][3] = pos[i][2]; - - if (pbones[i].parent == -1) - { - if ( IEngineStudio.IsHardware() ) - { - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]); - - // MatrixCopy should be faster... - //ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - MatrixCopy( (*m_pbonetransform)[i], (*m_plighttransform)[i] ); - } - else - { - ConcatTransforms ((*m_paliastransform), bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]); - } - - // Apply client-side effects to the transformation matrix - StudioFxTransform( m_pCurrentEntity, (*m_pbonetransform)[i] ); - } - else - { - ConcatTransforms ((*m_pbonetransform)[pbones[i].parent], bonematrix, (*m_pbonetransform)[i]); - ConcatTransforms ((*m_plighttransform)[pbones[i].parent], bonematrix, (*m_plighttransform)[i]); - } - } - } -} - -/* -==================== -StudioDrawModel - -==================== -*/ -int CStudioModelRenderer::StudioDrawModel( int flags ) -{ - alight_t lighting; - vec3_t dir; - - m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); - IEngineStudio.GetTimes( &m_nFrameCount, &m_clTime, &m_clOldTime ); - IEngineStudio.GetViewInfo( m_vRenderOrigin, m_vUp, m_vRight, m_vNormal ); - IEngineStudio.GetAliasScale( &m_fSoftwareXScale, &m_fSoftwareYScale ); - - if (m_pCurrentEntity->curstate.renderfx == kRenderFxDeadPlayer) - { - entity_state_t deadplayer; - - int result; - int save_interp; - - if (m_pCurrentEntity->curstate.renderamt <= 0 || m_pCurrentEntity->curstate.renderamt > gEngfuncs.GetMaxClients() ) - return 0; - - // get copy of player - deadplayer = *(IEngineStudio.GetPlayerState( m_pCurrentEntity->curstate.renderamt - 1 )); //cl.frames[cl.parsecount & CL_UPDATE_MASK].playerstate[m_pCurrentEntity->curstate.renderamt-1]; - - // clear weapon, movement state - deadplayer.number = m_pCurrentEntity->curstate.renderamt; - deadplayer.weaponmodel = 0; - deadplayer.gaitsequence = 0; - - deadplayer.movetype = MOVETYPE_NONE; - VectorCopy( m_pCurrentEntity->curstate.angles, deadplayer.angles ); - VectorCopy( m_pCurrentEntity->curstate.origin, deadplayer.origin ); - - save_interp = m_fDoInterp; - m_fDoInterp = 0; - - // draw as though it were a player - result = StudioDrawPlayer( flags, &deadplayer ); - - m_fDoInterp = save_interp; - return result; - } - - m_pRenderModel = m_pCurrentEntity->model; - m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (m_pRenderModel); - IEngineStudio.StudioSetHeader( m_pStudioHeader ); - IEngineStudio.SetRenderModel( m_pRenderModel ); - - StudioSetUpTransform( 0 ); - - if (flags & STUDIO_RENDER) - { - // see if the bounding box lets us trivially reject, also sets - if (!IEngineStudio.StudioCheckBBox ()) - return 0; - - (*m_pModelsDrawn)++; - (*m_pStudioModelCount)++; // render data cache cookie - - if (m_pStudioHeader->numbodyparts == 0) - return 1; - } - - if (m_pCurrentEntity->curstate.movetype == MOVETYPE_FOLLOW) - { - StudioMergeBones( m_pRenderModel ); - } - else - { - StudioSetupBones( ); - } - StudioSaveBones( ); - - if (flags & STUDIO_EVENTS) - { - StudioCalcAttachments( ); - IEngineStudio.StudioClientEvents( ); - // copy attachments into global entity array - if ( m_pCurrentEntity->index > 0 ) - { - cl_entity_t *ent = gEngfuncs.GetEntityByIndex( m_pCurrentEntity->index ); - - memcpy( ent->attachment, m_pCurrentEntity->attachment, sizeof( vec3_t ) * 4 ); - } - } - - if (flags & STUDIO_RENDER) - { - lighting.plightvec = dir; - IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting ); - - IEngineStudio.StudioEntityLight( &lighting ); - - // model and frame independant - IEngineStudio.StudioSetupLighting (&lighting); - - // get remap colors - m_nTopColor = m_pCurrentEntity->curstate.colormap & 0xFF; - m_nBottomColor = (m_pCurrentEntity->curstate.colormap & 0xFF00) >> 8; - - IEngineStudio.StudioSetRemapColors( m_nTopColor, m_nBottomColor ); - - StudioRenderModel( ); - } - - return 1; -} - -/* -==================== -StudioEstimateGait - -==================== -*/ -void CStudioModelRenderer::StudioEstimateGait( entity_state_t *pplayer ) -{ - float dt; - vec3_t est_velocity; - - dt = (m_clTime - m_clOldTime); - if (dt < 0) - dt = 0; - else if (dt > 1.0) - dt = 1; - - if (dt == 0 || m_pPlayerInfo->renderframe == m_nFrameCount) - { - m_flGaitMovement = 0; - return; - } - - // VectorAdd( pplayer->velocity, pplayer->prediction_error, est_velocity ); - if ( m_fGaitEstimation ) - { - VectorSubtract( m_pCurrentEntity->origin, m_pPlayerInfo->prevgaitorigin, est_velocity ); - VectorCopy( m_pCurrentEntity->origin, m_pPlayerInfo->prevgaitorigin ); - m_flGaitMovement = Length( est_velocity ); - if (dt <= 0 || m_flGaitMovement / dt < 5) - { - m_flGaitMovement = 0; - est_velocity[0] = 0; - est_velocity[1] = 0; - } - } - else - { - VectorCopy( pplayer->velocity, est_velocity ); - m_flGaitMovement = Length( est_velocity ) * dt; - } - - if (est_velocity[1] == 0 && est_velocity[0] == 0) - { - float flYawDiff = m_pCurrentEntity->angles[YAW] - m_pPlayerInfo->gaityaw; - flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360; - if (flYawDiff > 180) - flYawDiff -= 360; - if (flYawDiff < -180) - flYawDiff += 360; - - if (dt < 0.25) - flYawDiff *= dt * 4; - else - flYawDiff *= dt; - - m_pPlayerInfo->gaityaw += flYawDiff; - m_pPlayerInfo->gaityaw = m_pPlayerInfo->gaityaw - (int)(m_pPlayerInfo->gaityaw / 360) * 360; - - m_flGaitMovement = 0; - } - else - { - m_pPlayerInfo->gaityaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI); - if (m_pPlayerInfo->gaityaw > 180) - m_pPlayerInfo->gaityaw = 180; - if (m_pPlayerInfo->gaityaw < -180) - m_pPlayerInfo->gaityaw = -180; - } - -} - -/* -==================== -StudioProcessGait - -==================== -*/ -void CStudioModelRenderer::StudioProcessGait( entity_state_t *pplayer ) -{ - mstudioseqdesc_t *pseqdesc; - float dt; - int iBlend; - float flYaw; // view direction relative to movement - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + m_pCurrentEntity->curstate.sequence; - - StudioPlayerBlend( pseqdesc, &iBlend, &m_pCurrentEntity->angles[PITCH] ); - - m_pCurrentEntity->latched.prevangles[PITCH] = m_pCurrentEntity->angles[PITCH]; - m_pCurrentEntity->curstate.blending[0] = iBlend; - m_pCurrentEntity->latched.prevblending[0] = m_pCurrentEntity->curstate.blending[0]; - m_pCurrentEntity->latched.prevseqblending[0] = m_pCurrentEntity->curstate.blending[0]; - - dt = (m_clTime - m_clOldTime); - if (dt < 0) - dt = 0; - else if (dt > 1.0) - dt = 1; - - StudioEstimateGait( pplayer ); - - // calc side to side turning - flYaw = m_pCurrentEntity->angles[YAW] - m_pPlayerInfo->gaityaw; - flYaw = flYaw - (int)(flYaw / 360) * 360; - if (flYaw < -180) - flYaw = flYaw + 360; - if (flYaw > 180) - flYaw = flYaw - 360; - - if (flYaw > 120) - { - m_pPlayerInfo->gaityaw = m_pPlayerInfo->gaityaw - 180; - m_flGaitMovement = -m_flGaitMovement; - flYaw = flYaw - 180; - } - else if (flYaw < -120) - { - m_pPlayerInfo->gaityaw = m_pPlayerInfo->gaityaw + 180; - m_flGaitMovement = -m_flGaitMovement; - flYaw = flYaw + 180; - } - - // adjust torso - m_pCurrentEntity->curstate.controller[0] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); - m_pCurrentEntity->curstate.controller[1] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); - m_pCurrentEntity->curstate.controller[2] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); - m_pCurrentEntity->curstate.controller[3] = ((flYaw / 4.0) + 30) / (60.0 / 255.0); - m_pCurrentEntity->latched.prevcontroller[0] = m_pCurrentEntity->curstate.controller[0]; - m_pCurrentEntity->latched.prevcontroller[1] = m_pCurrentEntity->curstate.controller[1]; - m_pCurrentEntity->latched.prevcontroller[2] = m_pCurrentEntity->curstate.controller[2]; - m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; - - m_pCurrentEntity->angles[YAW] = m_pPlayerInfo->gaityaw; - if (m_pCurrentEntity->angles[YAW] < -0) - m_pCurrentEntity->angles[YAW] += 360; - m_pCurrentEntity->latched.prevangles[YAW] = m_pCurrentEntity->angles[YAW]; - - pseqdesc = (mstudioseqdesc_t *)((byte *)m_pStudioHeader + m_pStudioHeader->seqindex) + pplayer->gaitsequence; - - // calc gait frame - if (pseqdesc->linearmovement[0] > 0) - { - m_pPlayerInfo->gaitframe += (m_flGaitMovement / pseqdesc->linearmovement[0]) * pseqdesc->numframes; - } - else - { - m_pPlayerInfo->gaitframe += pseqdesc->fps * dt; - } - - // do modulo - m_pPlayerInfo->gaitframe = m_pPlayerInfo->gaitframe - (int)(m_pPlayerInfo->gaitframe / pseqdesc->numframes) * pseqdesc->numframes; - if (m_pPlayerInfo->gaitframe < 0) - m_pPlayerInfo->gaitframe += pseqdesc->numframes; -} - -/* -==================== -StudioDrawPlayer - -==================== -*/ -int CStudioModelRenderer::StudioDrawPlayer( int flags, entity_state_t *pplayer ) -{ - alight_t lighting; - vec3_t dir; - - m_pCurrentEntity = IEngineStudio.GetCurrentEntity(); - IEngineStudio.GetTimes( &m_nFrameCount, &m_clTime, &m_clOldTime ); - IEngineStudio.GetViewInfo( m_vRenderOrigin, m_vUp, m_vRight, m_vNormal ); - IEngineStudio.GetAliasScale( &m_fSoftwareXScale, &m_fSoftwareYScale ); - - m_nPlayerIndex = pplayer->number - 1; - - if (m_nPlayerIndex < 0 || m_nPlayerIndex >= gEngfuncs.GetMaxClients()) - return 0; - - m_pRenderModel = IEngineStudio.SetupPlayerModel( m_nPlayerIndex ); - if (m_pRenderModel == NULL) - return 0; - - m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (m_pRenderModel); - IEngineStudio.StudioSetHeader( m_pStudioHeader ); - IEngineStudio.SetRenderModel( m_pRenderModel ); - - if (pplayer->gaitsequence) - { - vec3_t orig_angles; - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - - VectorCopy( m_pCurrentEntity->angles, orig_angles ); - - StudioProcessGait( pplayer ); - - m_pPlayerInfo->gaitsequence = pplayer->gaitsequence; - m_pPlayerInfo = NULL; - - StudioSetUpTransform( 0 ); - VectorCopy( orig_angles, m_pCurrentEntity->angles ); - } - else - { - m_pCurrentEntity->curstate.controller[0] = 127; - m_pCurrentEntity->curstate.controller[1] = 127; - m_pCurrentEntity->curstate.controller[2] = 127; - m_pCurrentEntity->curstate.controller[3] = 127; - m_pCurrentEntity->latched.prevcontroller[0] = m_pCurrentEntity->curstate.controller[0]; - m_pCurrentEntity->latched.prevcontroller[1] = m_pCurrentEntity->curstate.controller[1]; - m_pCurrentEntity->latched.prevcontroller[2] = m_pCurrentEntity->curstate.controller[2]; - m_pCurrentEntity->latched.prevcontroller[3] = m_pCurrentEntity->curstate.controller[3]; - - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - m_pPlayerInfo->gaitsequence = 0; - - StudioSetUpTransform( 0 ); - } - - if (flags & STUDIO_RENDER) - { - // see if the bounding box lets us trivially reject, also sets - if (!IEngineStudio.StudioCheckBBox ()) - return 0; - - (*m_pModelsDrawn)++; - (*m_pStudioModelCount)++; // render data cache cookie - - if (m_pStudioHeader->numbodyparts == 0) - return 1; - } - - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - StudioSetupBones( ); - StudioSaveBones( ); - m_pPlayerInfo->renderframe = m_nFrameCount; - - m_pPlayerInfo = NULL; - - if (flags & STUDIO_EVENTS) - { - StudioCalcAttachments( ); - IEngineStudio.StudioClientEvents( ); - // copy attachments into global entity array - if ( m_pCurrentEntity->index > 0 ) - { - cl_entity_t *ent = gEngfuncs.GetEntityByIndex( m_pCurrentEntity->index ); - - memcpy( ent->attachment, m_pCurrentEntity->attachment, sizeof( vec3_t ) * 4 ); - } - } - - if (flags & STUDIO_RENDER) - { - if (m_pCvarHiModels->value && m_pRenderModel != m_pCurrentEntity->model ) - { - // show highest resolution multiplayer model - m_pCurrentEntity->curstate.body = 255; - } - - if (!(m_pCvarDeveloper->value == 0 && gEngfuncs.GetMaxClients() == 1 ) && ( m_pRenderModel == m_pCurrentEntity->model ) ) - { - m_pCurrentEntity->curstate.body = 1; // force helmet - } - - lighting.plightvec = dir; - IEngineStudio.StudioDynamicLight(m_pCurrentEntity, &lighting ); - - IEngineStudio.StudioEntityLight( &lighting ); - - // model and frame independant - IEngineStudio.StudioSetupLighting (&lighting); - - m_pPlayerInfo = IEngineStudio.PlayerInfo( m_nPlayerIndex ); - - // get remap colors - m_nTopColor = m_pPlayerInfo->topcolor; - if (m_nTopColor < 0) - m_nTopColor = 0; - if (m_nTopColor > 360) - m_nTopColor = 360; - m_nBottomColor = m_pPlayerInfo->bottomcolor; - if (m_nBottomColor < 0) - m_nBottomColor = 0; - if (m_nBottomColor > 360) - m_nBottomColor = 360; - - IEngineStudio.StudioSetRemapColors( m_nTopColor, m_nBottomColor ); - - StudioRenderModel( ); - m_pPlayerInfo = NULL; - - if (pplayer->weaponmodel) - { - cl_entity_t saveent = *m_pCurrentEntity; - - model_t *pweaponmodel = IEngineStudio.GetModelByIndex( pplayer->weaponmodel ); - - m_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata (pweaponmodel); - IEngineStudio.StudioSetHeader( m_pStudioHeader ); - - StudioMergeBones( pweaponmodel); - - IEngineStudio.StudioSetupLighting (&lighting); - - StudioRenderModel( ); - - StudioCalcAttachments( ); - - *m_pCurrentEntity = saveent; - } - } - - return 1; -} - -/* -==================== -StudioCalcAttachments - -==================== -*/ -void CStudioModelRenderer::StudioCalcAttachments( void ) -{ - int i; - mstudioattachment_t *pattachment; - - if ( m_pStudioHeader->numattachments > 4 ) - { - gEngfuncs.Con_DPrintf( "Too many attachments on %s\n", m_pCurrentEntity->model->name ); - exit( -1 ); - } - - // calculate attachment points - pattachment = (mstudioattachment_t *)((byte *)m_pStudioHeader + m_pStudioHeader->attachmentindex); - for (i = 0; i < m_pStudioHeader->numattachments; i++) - { - VectorTransform( pattachment[i].org, (*m_plighttransform)[pattachment[i].bone], m_pCurrentEntity->attachment[i] ); - } -} - -/* -==================== -StudioRenderModel - -==================== -*/ -void CStudioModelRenderer::StudioRenderModel( void ) -{ - IEngineStudio.SetChromeOrigin(); - IEngineStudio.SetForceFaceFlags( 0 ); - - if ( m_pCurrentEntity->curstate.renderfx == kRenderFxGlowShell ) - { - m_pCurrentEntity->curstate.renderfx = kRenderFxNone; - StudioRenderFinal( ); - - if ( !IEngineStudio.IsHardware() ) - { - gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); - } - - IEngineStudio.SetForceFaceFlags( STUDIO_NF_CHROME ); - - gEngfuncs.pTriAPI->SpriteTexture( m_pChromeSprite, 0 ); - m_pCurrentEntity->curstate.renderfx = kRenderFxGlowShell; - - StudioRenderFinal( ); - if ( !IEngineStudio.IsHardware() ) - { - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); - } - } - else - { - StudioRenderFinal( ); - } -} - -/* -==================== -StudioRenderFinal_Software - -==================== -*/ -void CStudioModelRenderer::StudioRenderFinal_Software( void ) -{ - int i; - - // Note, rendermode set here has effect in SW - IEngineStudio.SetupRenderer( 0 ); - - if (m_pCvarDrawEntities->value == 2) - { - IEngineStudio.StudioDrawBones( ); - } - else if (m_pCvarDrawEntities->value == 3) - { - IEngineStudio.StudioDrawHulls( ); - } - else - { - for (i=0 ; i < m_pStudioHeader->numbodyparts ; i++) - { - IEngineStudio.StudioSetupModel( i, (void **)&m_pBodyPart, (void **)&m_pSubModel ); - IEngineStudio.StudioDrawPoints( ); - } - } - - if (m_pCvarDrawEntities->value == 4) - { - gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); - IEngineStudio.StudioDrawHulls( ); - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); - } - - if (m_pCvarDrawEntities->value == 5) - { - IEngineStudio.StudioDrawAbsBBox( ); - } - - IEngineStudio.RestoreRenderer(); -} - -/* -==================== -StudioRenderFinal_Hardware - -==================== -*/ -void CStudioModelRenderer::StudioRenderFinal_Hardware( void ) -{ - int i; - int rendermode; - - rendermode = IEngineStudio.GetForceFaceFlags() ? kRenderTransAdd : m_pCurrentEntity->curstate.rendermode; - IEngineStudio.SetupRenderer( rendermode ); - - if (m_pCvarDrawEntities->value == 2) - { - IEngineStudio.StudioDrawBones(); - } - else if (m_pCvarDrawEntities->value == 3) - { - IEngineStudio.StudioDrawHulls(); - } - else - { - for (i=0 ; i < m_pStudioHeader->numbodyparts ; i++) - { - IEngineStudio.StudioSetupModel( i, (void **)&m_pBodyPart, (void **)&m_pSubModel ); - - if (m_fDoInterp) - { - // interpolation messes up bounding boxes. - m_pCurrentEntity->trivial_accept = 0; - } - - IEngineStudio.GL_SetRenderMode( rendermode ); - IEngineStudio.StudioDrawPoints(); - IEngineStudio.GL_StudioDrawShadow(); - } - } - - if ( m_pCvarDrawEntities->value == 4 ) - { - gEngfuncs.pTriAPI->RenderMode( kRenderTransAdd ); - IEngineStudio.StudioDrawHulls( ); - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); - } - - IEngineStudio.RestoreRenderer(); -} - -/* -==================== -StudioRenderFinal - -==================== -*/ -void CStudioModelRenderer::StudioRenderFinal(void) -{ - if ( IEngineStudio.IsHardware() ) - { - StudioRenderFinal_Hardware(); - } - else - { - StudioRenderFinal_Software(); - } -} - diff --git a/ricochet/cl_dll/StudioModelRenderer.h b/ricochet/cl_dll/StudioModelRenderer.h deleted file mode 100644 index fae3a8e..0000000 --- a/ricochet/cl_dll/StudioModelRenderer.h +++ /dev/null @@ -1,182 +0,0 @@ -#if !defined ( STUDIOMODELRENDERER_H ) -#define STUDIOMODELRENDERER_H -#if defined( _WIN32 ) -#pragma once -#endif - -/* -==================== -CStudioModelRenderer - -==================== -*/ -class CStudioModelRenderer -{ -public: - // Construction/Destruction - CStudioModelRenderer( void ); - virtual ~CStudioModelRenderer( void ); - - // Initialization - virtual void Init( void ); - -public: - // Public Interfaces - virtual int StudioDrawModel ( int flags ); - virtual int StudioDrawPlayer ( int flags, struct entity_state_s *pplayer ); - -public: - // Local interfaces - // - - // Look up animation data for sequence - virtual mstudioanim_t *StudioGetAnim ( model_t *m_pSubModel, mstudioseqdesc_t *pseqdesc ); - - // Interpolate model position and angles and set up matrices - virtual void StudioSetUpTransform (int trivial_accept); - - // Set up model bone positions - virtual void StudioSetupBones ( void ); - - // Find final attachment points - virtual void StudioCalcAttachments ( void ); - - // Save bone matrices and names - virtual void StudioSaveBones( void ); - - // Merge cached bones with current bones for model - virtual void StudioMergeBones ( model_t *m_pSubModel ); - - // Determine interpolation fraction - virtual float StudioEstimateInterpolant( void ); - - // Determine current frame for rendering - virtual float StudioEstimateFrame ( mstudioseqdesc_t *pseqdesc ); - - // Apply special effects to transform matrix - virtual void StudioFxTransform( cl_entity_t *ent, float transform[3][4] ); - - // Spherical interpolation of bones - virtual void StudioSlerpBones ( vec4_t q1[], float pos1[][3], vec4_t q2[], float pos2[][3], float s ); - - // Compute bone adjustments ( bone controllers ) - virtual void StudioCalcBoneAdj ( float dadt, float *adj, const byte *pcontroller1, const byte *pcontroller2, byte mouthopen ); - - // Get bone quaternions - virtual void StudioCalcBoneQuaterion ( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *q ); - - // Get bone positions - virtual void StudioCalcBonePosition ( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *pos ); - - // Compute rotations - virtual void StudioCalcRotations ( float pos[][3], vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f ); - - // Send bones and verts to renderer - virtual void StudioRenderModel ( void ); - - // Finalize rendering - virtual void StudioRenderFinal (void); - - // GL&D3D vs. Software renderer finishing functions - virtual void StudioRenderFinal_Software ( void ); - virtual void StudioRenderFinal_Hardware ( void ); - - // Player specific data - // Determine pitch and blending amounts for players - virtual void StudioPlayerBlend ( mstudioseqdesc_t *pseqdesc, int *pBlend, float *pPitch ); - - // Estimate gait frame for player - virtual void StudioEstimateGait ( entity_state_t *pplayer ); - - // Process movement of player - virtual void StudioProcessGait ( entity_state_t *pplayer ); - -public: - - // Client clock - double m_clTime; - // Old Client clock - double m_clOldTime; - - // Do interpolation? - int m_fDoInterp; - // Do gait estimation? - int m_fGaitEstimation; - - // Current render frame # - int m_nFrameCount; - - // Cvars that studio model code needs to reference - // - // Use high quality models? - cvar_t *m_pCvarHiModels; - // Developer debug output desired? - cvar_t *m_pCvarDeveloper; - // Draw entities bone hit boxes, etc? - cvar_t *m_pCvarDrawEntities; - - // The entity which we are currently rendering. - cl_entity_t *m_pCurrentEntity; - - // The model for the entity being rendered - model_t *m_pRenderModel; - - // Player info for current player, if drawing a player - player_info_t *m_pPlayerInfo; - - // The index of the player being drawn - int m_nPlayerIndex; - - // The player's gait movement - float m_flGaitMovement; - - // Pointer to header block for studio model data - studiohdr_t *m_pStudioHeader; - - // Pointers to current body part and submodel - mstudiobodyparts_t *m_pBodyPart; - mstudiomodel_t *m_pSubModel; - - // Palette substition for top and bottom of model - int m_nTopColor; - int m_nBottomColor; - - // - // Sprite model used for drawing studio model chrome - model_t *m_pChromeSprite; - - // Caching - // Number of bones in bone cache - int m_nCachedBones; - // Names of cached bones - char m_nCachedBoneNames[ MAXSTUDIOBONES ][ 32 ]; - // Cached bone & light transformation matrices - float m_rgCachedBoneTransform [ MAXSTUDIOBONES ][ 3 ][ 4 ]; - float m_rgCachedLightTransform[ MAXSTUDIOBONES ][ 3 ][ 4 ]; - - // Software renderer scale factors - float m_fSoftwareXScale, m_fSoftwareYScale; - - // Current view vectors and render origin - float m_vUp[ 3 ]; - float m_vRight[ 3 ]; - float m_vNormal[ 3 ]; - - float m_vRenderOrigin[ 3 ]; - - // Model render counters ( from engine ) - int *m_pStudioModelCount; - int *m_pModelsDrawn; - - // Matrices - // Model to world transformation - float (*m_protationmatrix)[ 3 ][ 4 ]; - // Model to view transformation - float (*m_paliastransform)[ 3 ][ 4 ]; - - // Concatenated bone and light transforms - float (*m_pbonetransform) [ MAXSTUDIOBONES ][ 3 ][ 4 ]; - float (*m_plighttransform)[ MAXSTUDIOBONES ][ 3 ][ 4 ]; -}; - -#endif // STUDIOMODELRENDERER_H \ No newline at end of file diff --git a/ricochet/cl_dll/ammo.cpp b/ricochet/cl_dll/ammo.cpp deleted file mode 100644 index f136418..0000000 --- a/ricochet/cl_dll/ammo.cpp +++ /dev/null @@ -1,930 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// Ammo.cpp -// -// implementation of CHudAmmo class -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -#include "ammohistory.h" - -WEAPON *gpActiveSel; // NULL means off, 1 means just the menu bar, otherwise - // this points to the active weapon menu item -WEAPON *gpLastSel; // Last weapon menu selection - -client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes, int iCount); - -WeaponsResource gWR; - -int g_weaponselect = 0; - -void WeaponsResource :: LoadAllWeaponSprites( void ) -{ - for (int i = 0; i < MAX_WEAPONS; i++) - { - if ( rgWeapons[i].iId ) - LoadWeaponSprites( &rgWeapons[i] ); - } -} - -int WeaponsResource :: CountAmmo( int iId ) -{ - if ( iId < 0 ) - return 0; - - return riAmmo[iId]; -} - -int WeaponsResource :: HasAmmo( WEAPON *p ) -{ - if ( !p ) - return FALSE; - - // weapons with no max ammo can always be selected - if ( p->iMax1 == -1 ) - return TRUE; - - return (p->iAmmoType == -1) || p->iClip > 0 || CountAmmo(p->iAmmoType) - || CountAmmo(p->iAmmo2Type) || ( p->iFlags & WEAPON_FLAGS_SELECTONEMPTY ); -} - - -void WeaponsResource :: LoadWeaponSprites( WEAPON *pWeapon ) -{ - int i, iRes; - - if (ScreenWidth < 640) - iRes = 320; - else - iRes = 640; - - char sz[128]; - - if ( !pWeapon ) - return; - - memset( &pWeapon->rcActive, 0, sizeof(wrect_t) ); - memset( &pWeapon->rcInactive, 0, sizeof(wrect_t) ); - memset( &pWeapon->rcAmmo, 0, sizeof(wrect_t) ); - memset( &pWeapon->rcAmmo2, 0, sizeof(wrect_t) ); - pWeapon->hInactive = 0; - pWeapon->hActive = 0; - pWeapon->hAmmo = 0; - pWeapon->hAmmo2 = 0; - - sprintf(sz, "sprites/%s.txt", pWeapon->szName); - client_sprite_t *pList = SPR_GetList(sz, &i); - - if (!pList) - return; - - client_sprite_t *p; - - p = GetSpriteList( pList, "crosshair", iRes, i ); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hCrosshair = SPR_Load(sz); - pWeapon->rcCrosshair = p->rc; - } - else - pWeapon->hCrosshair = NULL; - - p = GetSpriteList(pList, "autoaim", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hAutoaim = SPR_Load(sz); - pWeapon->rcAutoaim = p->rc; - } - else - pWeapon->hAutoaim = 0; - - p = GetSpriteList( pList, "zoom", iRes, i ); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hZoomedCrosshair = SPR_Load(sz); - pWeapon->rcZoomedCrosshair = p->rc; - } - else - { - pWeapon->hZoomedCrosshair = pWeapon->hCrosshair; //default to non-zoomed crosshair - pWeapon->rcZoomedCrosshair = pWeapon->rcCrosshair; - } - - p = GetSpriteList(pList, "zoom_autoaim", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hZoomedAutoaim = SPR_Load(sz); - pWeapon->rcZoomedAutoaim = p->rc; - } - else - { - pWeapon->hZoomedAutoaim = pWeapon->hZoomedCrosshair; //default to zoomed crosshair - pWeapon->rcZoomedAutoaim = pWeapon->rcZoomedCrosshair; - } - - p = GetSpriteList(pList, "weapon", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hInactive = SPR_Load(sz); - pWeapon->rcInactive = p->rc; - - gHR.iHistoryGap = V_max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top ); - } - else - pWeapon->hInactive = 0; - - p = GetSpriteList(pList, "weapon_s", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hActive = SPR_Load(sz); - pWeapon->rcActive = p->rc; - } - else - pWeapon->hActive = 0; - - p = GetSpriteList(pList, "ammo", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hAmmo = SPR_Load(sz); - pWeapon->rcAmmo = p->rc; - - gHR.iHistoryGap = V_max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top ); - } - else - pWeapon->hAmmo = 0; - - p = GetSpriteList(pList, "ammo2", iRes, i); - if (p) - { - sprintf(sz, "sprites/%s.spr", p->szSprite); - pWeapon->hAmmo2 = SPR_Load(sz); - pWeapon->rcAmmo2 = p->rc; - - gHR.iHistoryGap = V_max( gHR.iHistoryGap, pWeapon->rcActive.bottom - pWeapon->rcActive.top ); - } - else - pWeapon->hAmmo2 = 0; - -} - -// Returns the first weapon for a given slot. -WEAPON *WeaponsResource :: GetFirstPos( int iSlot ) -{ - WEAPON *pret = NULL; - - for (int i = 0; i < MAX_WEAPON_POSITIONS; i++) - { - if ( rgSlots[iSlot][i] && HasAmmo( rgSlots[iSlot][i] ) ) - { - pret = rgSlots[iSlot][i]; - break; - } - } - - return pret; -} - - -WEAPON* WeaponsResource :: GetNextActivePos( int iSlot, int iSlotPos ) -{ - if ( iSlotPos >= MAX_WEAPON_POSITIONS || iSlot >= MAX_WEAPON_SLOTS ) - return NULL; - - WEAPON *p = gWR.rgSlots[ iSlot ][ iSlotPos+1 ]; - - if ( !p || !gWR.HasAmmo(p) ) - return GetNextActivePos( iSlot, iSlotPos + 1 ); - - return p; -} - - -int giBucketHeight, giBucketWidth, giABHeight, giABWidth; // Ammo Bar width and height - -HSPRITE ghsprBuckets; // Sprite for top row of weapons menu - -DECLARE_MESSAGE(m_Ammo, CurWeapon ); // Current weapon and clip -DECLARE_MESSAGE(m_Ammo, WeaponList); // new weapon type -DECLARE_MESSAGE(m_Ammo, AmmoX); // update known ammo type's count -DECLARE_MESSAGE(m_Ammo, AmmoPickup); // flashes an ammo pickup record -DECLARE_MESSAGE(m_Ammo, WeapPickup); // flashes a weapon pickup record -DECLARE_MESSAGE(m_Ammo, HideWeapon); // hides the weapon, ammo, and crosshair displays temporarily -DECLARE_MESSAGE(m_Ammo, ItemPickup); - -DECLARE_COMMAND(m_Ammo, Slot1); -DECLARE_COMMAND(m_Ammo, Slot2); -DECLARE_COMMAND(m_Ammo, Slot3); -DECLARE_COMMAND(m_Ammo, Slot4); -DECLARE_COMMAND(m_Ammo, Slot5); -DECLARE_COMMAND(m_Ammo, Slot6); -DECLARE_COMMAND(m_Ammo, Slot7); -DECLARE_COMMAND(m_Ammo, Slot8); -DECLARE_COMMAND(m_Ammo, Slot9); -DECLARE_COMMAND(m_Ammo, Slot10); -DECLARE_COMMAND(m_Ammo, Close); -DECLARE_COMMAND(m_Ammo, NextWeapon); -DECLARE_COMMAND(m_Ammo, PrevWeapon); - -// width of ammo fonts -#define AMMO_SMALL_WIDTH 10 -#define AMMO_LARGE_WIDTH 20 - -#define HISTORY_DRAW_TIME "5" - -int CHudAmmo::Init(void) -{ - gHUD.AddHudElem(this); - - HOOK_MESSAGE(CurWeapon); - HOOK_MESSAGE(WeaponList); - HOOK_MESSAGE(AmmoPickup); - HOOK_MESSAGE(WeapPickup); - HOOK_MESSAGE(ItemPickup); - HOOK_MESSAGE(HideWeapon); - HOOK_MESSAGE(AmmoX); - - HOOK_COMMAND("slot1", Slot1); - HOOK_COMMAND("slot2", Slot2); - HOOK_COMMAND("slot3", Slot3); - HOOK_COMMAND("slot4", Slot4); - HOOK_COMMAND("slot5", Slot5); - HOOK_COMMAND("slot6", Slot6); - HOOK_COMMAND("slot7", Slot7); - HOOK_COMMAND("slot8", Slot8); - HOOK_COMMAND("slot9", Slot9); - HOOK_COMMAND("slot10", Slot10); - HOOK_COMMAND("cancelselect", Close); - HOOK_COMMAND("invnext", NextWeapon); - HOOK_COMMAND("invprev", PrevWeapon); - - Reset(); - - CVAR_CREATE( "hud_drawhistory_time", HISTORY_DRAW_TIME, 0 ); - CVAR_CREATE( "hud_fastswitch", "0", FCVAR_ARCHIVE ); // controls whether or not weapons can be selected in one keypress - - m_iFlags |= HUD_ACTIVE; //!!! - - gWR.Init(); - gHR.Init(); - - return 1; -}; - -void CHudAmmo::Reset(void) -{ - m_fFade = 0; - m_iFlags |= HUD_ACTIVE; //!!! - - gpActiveSel = NULL; - gHUD.m_iHideHUDDisplay = 0; - - gWR.Reset(); - gHR.Reset(); - - // VidInit(); - -} - -int CHudAmmo::VidInit(void) -{ - // Load sprites for buckets (top row of weapon menu) - m_HUD_bucket0 = gHUD.GetSpriteIndex( "bucket1" ); - m_HUD_selection = gHUD.GetSpriteIndex( "selection" ); - - ghsprBuckets = gHUD.GetSprite(m_HUD_bucket0); - giBucketWidth = gHUD.GetSpriteRect(m_HUD_bucket0).right - gHUD.GetSpriteRect(m_HUD_bucket0).left; - giBucketHeight = gHUD.GetSpriteRect(m_HUD_bucket0).bottom - gHUD.GetSpriteRect(m_HUD_bucket0).top; - - gHR.iHistoryGap = V_max( gHR.iHistoryGap, gHUD.GetSpriteRect(m_HUD_bucket0).bottom - gHUD.GetSpriteRect(m_HUD_bucket0).top); - - // If we've already loaded weapons, let's get new sprites - gWR.LoadAllWeaponSprites(); - - if (ScreenWidth >= 640) - { - giABWidth = 20; - giABHeight = 4; - } - else - { - giABWidth = 10; - giABHeight = 2; - } - - return 1; -} - -// -// Think: -// Used for selection of weapon menu item. -// -void CHudAmmo::Think(void) -{ - if ( gHUD.m_fPlayerDead ) - return; - - if ( gHUD.m_iWeaponBits != gWR.iOldWeaponBits ) - { - gWR.iOldWeaponBits = gHUD.m_iWeaponBits; - - for (int i = MAX_WEAPONS-1; i > 0; i-- ) - { - WEAPON *p = gWR.GetWeapon(i); - - if ( p ) - { - if ( gHUD.m_iWeaponBits & ( 1 << p->iId ) ) - gWR.PickupWeapon( p ); - else - gWR.DropWeapon( p ); - } - } - } - - if (!gpActiveSel) - return; - - // has the player selected one? - if (gHUD.m_iKeyBits & IN_ATTACK) - { - if (gpActiveSel != (WEAPON *)1) - { - ServerCmd(gpActiveSel->szName); - g_weaponselect = gpActiveSel->iId; - } - - gpLastSel = gpActiveSel; - gpActiveSel = NULL; - gHUD.m_iKeyBits &= ~IN_ATTACK; - - PlaySound("common/wpn_select.wav", 1); - } - -} - -// -// Helper function to return a Ammo pointer from id -// - -HSPRITE* WeaponsResource :: GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect ) -{ - for ( int i = 0; i < MAX_WEAPONS; i++ ) - { - if ( rgWeapons[i].iAmmoType == iAmmoId ) - { - rect = rgWeapons[i].rcAmmo; - return &rgWeapons[i].hAmmo; - } - else if ( rgWeapons[i].iAmmo2Type == iAmmoId ) - { - rect = rgWeapons[i].rcAmmo2; - return &rgWeapons[i].hAmmo2; - } - } - - return NULL; -} - - -// Menu Selection Code - -void WeaponsResource :: SelectSlot( int iSlot, int fAdvance, int iDirection ) -{ - // Discwar has no weapons to switch to - return; - - if ( gHUD.m_Menu.m_fMenuDisplayed && (fAdvance == FALSE) && (iDirection == 1) ) - { // menu is overriding slot use commands - gHUD.m_Menu.SelectMenuItem( iSlot + 1 ); // slots are one off the key numbers - return; - } - - if ( iSlot > MAX_WEAPON_SLOTS ) - return; - - if ( gHUD.m_fPlayerDead || gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) - return; - - if (!(gHUD.m_iWeaponBits & (1<<(WEAPON_SUIT)) )) - return; - - if ( ! ( gHUD.m_iWeaponBits & ~(1<<(WEAPON_SUIT)) )) - return; - - WEAPON *p = NULL; - bool fastSwitch = CVAR_GET_FLOAT( "hud_fastswitch" ) != 0; - - if ( (gpActiveSel == NULL) || (gpActiveSel == (WEAPON *)1) || (iSlot != gpActiveSel->iSlot) ) - { - PlaySound( "common/wpn_hudon.wav", 1 ); - p = GetFirstPos( iSlot ); - - if ( p && fastSwitch ) // check for fast weapon switch mode - { - // if fast weapon switch is on, then weapons can be selected in a single keypress - // but only if there is only one item in the bucket - WEAPON *p2 = GetNextActivePos( p->iSlot, p->iSlotPos ); - if ( !p2 ) - { // only one active item in bucket, so change directly to weapon - ServerCmd( p->szName ); - g_weaponselect = p->iId; - return; - } - } - } - else - { - PlaySound("common/wpn_moveselect.wav", 1); - if ( gpActiveSel ) - p = GetNextActivePos( gpActiveSel->iSlot, gpActiveSel->iSlotPos ); - if ( !p ) - p = GetFirstPos( iSlot ); - } - - - if ( !p ) // no selection found - { - // just display the weapon list, unless fastswitch is on just ignore it - if ( !fastSwitch ) - gpActiveSel = (WEAPON *)1; - else - gpActiveSel = NULL; - } - else - gpActiveSel = p; -} - - -//------------------------------------------------------------------------ -// Message Handlers -//------------------------------------------------------------------------ - -// -// AmmoX -- Update the count of a known type of ammo -// -int CHudAmmo::MsgFunc_AmmoX(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - int iIndex = READ_BYTE(); - int iCount = READ_BYTE(); - - gWR.SetAmmo( iIndex, abs(iCount) ); - - return 1; -} - -int CHudAmmo::MsgFunc_AmmoPickup( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - int iIndex = READ_BYTE(); - int iCount = READ_BYTE(); - - // Add ammo to the history - gHR.AddToHistory( HISTSLOT_AMMO, iIndex, abs(iCount) ); - - return 1; -} - -int CHudAmmo::MsgFunc_WeapPickup( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - int iIndex = READ_BYTE(); - - // Add the weapon to the history - gHR.AddToHistory( HISTSLOT_WEAP, iIndex ); - - return 1; -} - -int CHudAmmo::MsgFunc_ItemPickup( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - const char *szName = READ_STRING(); - - // Add the weapon to the history - gHR.AddToHistory( HISTSLOT_ITEM, szName ); - - return 1; -} - - -int CHudAmmo::MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - gHUD.m_iHideHUDDisplay = READ_BYTE(); - - if ( gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL ) ) - { - static wrect_t nullrc; - gpActiveSel = NULL; - SetCrosshair( 0, nullrc, 0, 0, 0 ); - } - else - { - if ( m_pWeapon ) - SetCrosshair( m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255 ); - } - - return 1; -} - -// -// CurWeapon: Update hud state with the current weapon and clip count. Ammo -// counts are updated with AmmoX. Server assures that the Weapon ammo type -// numbers match a real ammo type. -// -int CHudAmmo::MsgFunc_CurWeapon(const char *pszName, int iSize, void *pbuf ) -{ - static wrect_t nullrc; - int fOnTarget = FALSE; - - BEGIN_READ( pbuf, iSize ); - - int iState = READ_BYTE(); - int iId = READ_CHAR(); - int iClip = READ_CHAR(); - - // detect if we're also on target - if ( iState > 1 ) - { - fOnTarget = TRUE; - } - - if ( iId < 1 ) - { - SetCrosshair(0, nullrc, 0, 0, 0); - return 0; - } - - // Is player dead??? - if ((iId == -1) && (iClip == -1)) - { - gHUD.m_fPlayerDead = TRUE; - gpActiveSel = NULL; - return 1; - } - gHUD.m_fPlayerDead = FALSE; - - WEAPON *pWeapon = gWR.GetWeapon( iId ); - - if ( !pWeapon ) - return 0; - - if ( iClip < -1 ) - pWeapon->iClip = abs(iClip); - else - pWeapon->iClip = iClip; - - - if ( iState == 0 ) // we're not the current weapon, so update no more - return 1; - - m_pWeapon = pWeapon; - - if ( !(gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL )) ) - { - if ( gHUD.m_iFOV >= 90 ) - { // normal crosshairs - if (fOnTarget && m_pWeapon->hAutoaim) - SetCrosshair(m_pWeapon->hAutoaim, m_pWeapon->rcAutoaim, 255, 255, 255); - else - SetCrosshair(m_pWeapon->hCrosshair, m_pWeapon->rcCrosshair, 255, 255, 255); - } - else - { // zoomed crosshairs - if (fOnTarget && m_pWeapon->hZoomedAutoaim) - SetCrosshair(m_pWeapon->hZoomedAutoaim, m_pWeapon->rcZoomedAutoaim, 255, 255, 255); - else - SetCrosshair(m_pWeapon->hZoomedCrosshair, m_pWeapon->rcZoomedCrosshair, 255, 255, 255); - } - } - - m_fFade = 200.0f; //!!! - m_iFlags |= HUD_ACTIVE; - - return 1; -} - -// -// WeaponList -- Tells the hud about a new weapon type. -// -int CHudAmmo::MsgFunc_WeaponList(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - WEAPON Weapon; - - strcpy( Weapon.szName, READ_STRING() ); - Weapon.iAmmoType = (int)READ_CHAR(); - - Weapon.iMax1 = READ_BYTE(); - if (Weapon.iMax1 == 255) - Weapon.iMax1 = -1; - - Weapon.iAmmo2Type = READ_CHAR(); - Weapon.iMax2 = READ_BYTE(); - if (Weapon.iMax2 == 255) - Weapon.iMax2 = -1; - - Weapon.iSlot = READ_CHAR(); - Weapon.iSlotPos = READ_CHAR(); - Weapon.iId = READ_CHAR(); - Weapon.iFlags = READ_BYTE(); - Weapon.iClip = 0; - - gWR.AddWeapon( &Weapon ); - - return 1; - -} - -//------------------------------------------------------------------------ -// Command Handlers -//------------------------------------------------------------------------ - -void CHudAmmo::UserCmd_Slot1(void) -{ - gWR.SelectSlot(0, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot2(void) -{ - gWR.SelectSlot(1, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot3(void) -{ - gWR.SelectSlot(2, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot4(void) -{ - gWR.SelectSlot(3, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot5(void) -{ - gWR.SelectSlot(4, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot6(void) -{ - gWR.SelectSlot(5, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot7(void) -{ - gWR.SelectSlot(6, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot8(void) -{ - gWR.SelectSlot(7, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot9(void) -{ - gWR.SelectSlot(8, FALSE, 1); -} - -void CHudAmmo::UserCmd_Slot10(void) -{ - gWR.SelectSlot(9, FALSE, 1); -} - -void CHudAmmo::UserCmd_Close(void) -{ - if (gpActiveSel) - { - gpLastSel = gpActiveSel; - gpActiveSel = NULL; - PlaySound("common/wpn_hudoff.wav", 1); - } - else - ClientCmd("escape"); -} - - -// Selects the next item in the weapon menu -void CHudAmmo::UserCmd_NextWeapon(void) -{ - if ( gHUD.m_fPlayerDead || (gHUD.m_iHideHUDDisplay & (HIDEHUD_WEAPONS | HIDEHUD_ALL)) ) - return; - - if ( !gpActiveSel || gpActiveSel == (WEAPON*)1 ) - gpActiveSel = m_pWeapon; - - int pos = 0; - int slot = 0; - if ( gpActiveSel ) - { - pos = gpActiveSel->iSlotPos + 1; - slot = gpActiveSel->iSlot; - } - - for ( int loop = 0; loop <= 1; loop++ ) - { - for ( ; slot < MAX_WEAPON_SLOTS; slot++ ) - { - for ( ; pos < MAX_WEAPON_POSITIONS; pos++ ) - { - WEAPON *wsp = gWR.GetWeaponSlot( slot, pos ); - - if ( wsp && gWR.HasAmmo(wsp) ) - { - gpActiveSel = wsp; - return; - } - } - - pos = 0; - } - - slot = 0; // start looking from the first slot again - } - - gpActiveSel = NULL; -} - -// Selects the previous item in the menu -void CHudAmmo::UserCmd_PrevWeapon(void) -{ - if ( gHUD.m_fPlayerDead || (gHUD.m_iHideHUDDisplay & (HIDEHUD_WEAPONS | HIDEHUD_ALL)) ) - return; - - if ( !gpActiveSel || gpActiveSel == (WEAPON*)1 ) - gpActiveSel = m_pWeapon; - - int pos = MAX_WEAPON_POSITIONS-1; - int slot = MAX_WEAPON_SLOTS-1; - if ( gpActiveSel ) - { - pos = gpActiveSel->iSlotPos - 1; - slot = gpActiveSel->iSlot; - } - - for ( int loop = 0; loop <= 1; loop++ ) - { - for ( ; slot >= 0; slot-- ) - { - for ( ; pos >= 0; pos-- ) - { - WEAPON *wsp = gWR.GetWeaponSlot( slot, pos ); - - if ( wsp && gWR.HasAmmo(wsp) ) - { - gpActiveSel = wsp; - return; - } - } - - pos = MAX_WEAPON_POSITIONS-1; - } - - slot = MAX_WEAPON_SLOTS-1; - } - - gpActiveSel = NULL; -} - - - -//------------------------------------------------------------------------- -// Drawing code -//------------------------------------------------------------------------- - -int CHudAmmo::Draw(float flTime) -{ - // No ammo in discwar - return 1; -} - - -// -// Draws the ammo bar on the hud -// -int DrawBar(int x, int y, int width, int height, float f) -{ - int r, g, b; - - if (f < 0) - f = 0; - if (f > 1) - f = 1; - - if (f) - { - int w = f * width; - - // Always show at least one pixel if we have ammo. - if (w <= 0) - w = 1; - UnpackRGB(r, g, b, RGB_GREENISH); - FillRGBA(x, y, w, height, r, g, b, 255); - x += w; - width -= w; - } - - UnpackRGB(r, g, b, RGB_YELLOWISH); - - FillRGBA(x, y, width, height, r, g, b, 128); - - return (x + width); -} - - - -void DrawAmmoBar(WEAPON *p, int x, int y, int width, int height) -{ - if ( !p ) - return; - - if (p->iAmmoType != -1) - { - if (!gWR.CountAmmo(p->iAmmoType)) - return; - - float f = (float)gWR.CountAmmo(p->iAmmoType)/(float)p->iMax1; - - x = DrawBar(x, y, width, height, f); - - - // Do we have secondary ammo too? - - if (p->iAmmo2Type != -1) - { - f = (float)gWR.CountAmmo(p->iAmmo2Type)/(float)p->iMax2; - - x += 5; //!!! - - DrawBar(x, y, width, height, f); - } - } -} - - - - -// -// Draw Weapon Menu -// -int CHudAmmo::DrawWList(float flTime) -{ - // No ammo in discwar - return 0; -} - - -/* ================================= - GetSpriteList - -Finds and returns the matching -sprite name 'psz' and resolution 'iRes' -in the given sprite list 'pList' -iCount is the number of items in the pList -================================= */ -client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes, int iCount) -{ - if (!pList) - return NULL; - - int i = iCount; - client_sprite_t *p = pList; - - while(i--) - { - if ((!strcmp(psz, p->szName)) && (p->iRes == iRes)) - return p; - p++; - } - - return NULL; -} diff --git a/ricochet/cl_dll/ammo.h b/ricochet/cl_dll/ammo.h deleted file mode 100644 index a3125ab..0000000 --- a/ricochet/cl_dll/ammo.h +++ /dev/null @@ -1,62 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ - -#ifndef __AMMO_H__ -#define __AMMO_H__ - -#define MAX_WEAPON_NAME 128 - - -#define WEAPON_FLAGS_SELECTONEMPTY 1 - -#define WEAPON_IS_ONTARGET 0x40 - -struct WEAPON -{ - char szName[MAX_WEAPON_NAME]; - int iAmmoType; - int iAmmo2Type; - int iMax1; - int iMax2; - int iSlot; - int iSlotPos; - int iFlags; - int iId; - int iClip; - - int iCount; // # of itesm in plist - - HSPRITE hActive; - wrect_t rcActive; - HSPRITE hInactive; - wrect_t rcInactive; - HSPRITE hAmmo; - wrect_t rcAmmo; - HSPRITE hAmmo2; - wrect_t rcAmmo2; - HSPRITE hCrosshair; - wrect_t rcCrosshair; - HSPRITE hAutoaim; - wrect_t rcAutoaim; - HSPRITE hZoomedCrosshair; - wrect_t rcZoomedCrosshair; - HSPRITE hZoomedAutoaim; - wrect_t rcZoomedAutoaim; -}; - -typedef int AMMO; - - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/ammo_secondary.cpp b/ricochet/cl_dll/ammo_secondary.cpp deleted file mode 100644 index a83bade..0000000 --- a/ricochet/cl_dll/ammo_secondary.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// ammo_secondary.cpp -// -// implementation of CHudAmmoSecondary class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE( m_AmmoSecondary, SecAmmoVal ); -DECLARE_MESSAGE( m_AmmoSecondary, SecAmmoIcon ); - -int CHudAmmoSecondary :: Init( void ) -{ - HOOK_MESSAGE( SecAmmoVal ); - HOOK_MESSAGE( SecAmmoIcon ); - - gHUD.AddHudElem(this); - m_HUD_ammoicon = 0; - - for ( int i = 0; i < MAX_SEC_AMMO_VALUES; i++ ) - m_iAmmoAmounts[i] = -1; // -1 means don't draw this value - - Reset(); - - return 1; -} - -void CHudAmmoSecondary :: Reset( void ) -{ - m_fFade = 0; -} - -int CHudAmmoSecondary :: VidInit( void ) -{ - return 1; -} - -int CHudAmmoSecondary :: Draw(float flTime) -{ - if ( (gHUD.m_iHideHUDDisplay & ( HIDEHUD_WEAPONS | HIDEHUD_ALL )) ) - return 1; - - // draw secondary ammo icons above normal ammo readout - int a, x, y, r, g, b, AmmoWidth; - UnpackRGB( r, g, b, RGB_YELLOWISH ); - a = (int) V_max( MIN_ALPHA, m_fFade ); - if (m_fFade > 0) - m_fFade -= (gHUD.m_flTimeDelta * 20); // slowly lower alpha to fade out icons - ScaleColors( r, g, b, a ); - - AmmoWidth = gHUD.GetSpriteRect(gHUD.m_HUD_number_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).left; - - y = ScreenHeight - (gHUD.m_iFontHeight*4); // this is one font height higher than the weapon ammo values - x = ScreenWidth - AmmoWidth; - - if ( m_HUD_ammoicon ) - { - // Draw the ammo icon - x -= (gHUD.GetSpriteRect(m_HUD_ammoicon).right - gHUD.GetSpriteRect(m_HUD_ammoicon).left); - y -= (gHUD.GetSpriteRect(m_HUD_ammoicon).top - gHUD.GetSpriteRect(m_HUD_ammoicon).bottom); - - SPR_Set( gHUD.GetSprite(m_HUD_ammoicon), r, g, b ); - SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(m_HUD_ammoicon) ); - } - else - { // move the cursor by the '0' char instead, since we don't have an icon to work with - x -= AmmoWidth; - y -= (gHUD.GetSpriteRect(gHUD.m_HUD_number_0).top - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).bottom); - } - - // draw the ammo counts, in reverse order, from right to left - for ( int i = MAX_SEC_AMMO_VALUES-1; i >= 0; i-- ) - { - if ( m_iAmmoAmounts[i] < 0 ) - continue; // negative ammo amounts imply that they shouldn't be drawn - - // half a char gap between the ammo number and the previous pic - x -= (AmmoWidth / 2); - - // draw the number, right-aligned - x -= (gHUD.GetNumWidth( m_iAmmoAmounts[i], DHN_DRAWZERO ) * AmmoWidth); - gHUD.DrawHudNumber( x, y, DHN_DRAWZERO, m_iAmmoAmounts[i], r, g, b ); - - if ( i != 0 ) - { - // draw the divider bar - x -= (AmmoWidth / 2); - FillRGBA(x, y, (AmmoWidth/10), gHUD.m_iFontHeight, r, g, b, a); - } - } - - return 1; -} - -// Message handler for Secondary Ammo Value -// accepts one value: -// string: sprite name -int CHudAmmoSecondary :: MsgFunc_SecAmmoIcon( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - m_HUD_ammoicon = gHUD.GetSpriteIndex( READ_STRING() ); - - return 1; -} - -// Message handler for Secondary Ammo Icon -// Sets an ammo value -// takes two values: -// byte: ammo index -// byte: ammo value -int CHudAmmoSecondary :: MsgFunc_SecAmmoVal( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int index = READ_BYTE(); - if ( index < 0 || index >= MAX_SEC_AMMO_VALUES ) - return 1; - - m_iAmmoAmounts[index] = READ_BYTE(); - m_iFlags |= HUD_ACTIVE; - - // check to see if there is anything left to draw - int count = 0; - for ( int i = 0; i < MAX_SEC_AMMO_VALUES; i++ ) - { - count += V_max( 0, m_iAmmoAmounts[i] ); - } - - if ( count == 0 ) - { // the ammo fields are all empty, so turn off this hud area - m_iFlags &= ~HUD_ACTIVE; - return 1; - } - - // make the icons light up - m_fFade = 200.0f; - - return 1; -} - - diff --git a/ricochet/cl_dll/ammohistory.cpp b/ricochet/cl_dll/ammohistory.cpp deleted file mode 100644 index 22d577a..0000000 --- a/ricochet/cl_dll/ammohistory.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// ammohistory.cpp -// - - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -#include "ammohistory.h" - -HistoryResource gHR; - -#define AMMO_PICKUP_GAP (gHR.iHistoryGap+5) -#define AMMO_PICKUP_PICK_HEIGHT (32 + (gHR.iHistoryGap * 2)) -#define AMMO_PICKUP_HEIGHT_MAX (ScreenHeight - 100) - -#define MAX_ITEM_NAME 32 -int HISTORY_DRAW_TIME = 5; - -// keep a list of items -struct ITEM_INFO -{ - char szName[MAX_ITEM_NAME]; - HSPRITE spr; - wrect_t rect; -}; - -void HistoryResource :: AddToHistory( int iType, int iId, int iCount ) -{ - if ( iType == HISTSLOT_AMMO && !iCount ) - return; // no amount, so don't add - - if ( (((AMMO_PICKUP_GAP * iCurrentHistorySlot) + AMMO_PICKUP_PICK_HEIGHT) > AMMO_PICKUP_HEIGHT_MAX) || (iCurrentHistorySlot >= MAX_HISTORY) ) - { // the pic would have to be drawn too high - // so start from the bottom - iCurrentHistorySlot = 0; - } - - HIST_ITEM *freeslot = &rgAmmoHistory[iCurrentHistorySlot++]; // default to just writing to the first slot - HISTORY_DRAW_TIME = CVAR_GET_FLOAT( "hud_drawhistory_time" ); - - freeslot->type = iType; - freeslot->iId = iId; - freeslot->iCount = iCount; - freeslot->DisplayTime = gHUD.m_flTime + HISTORY_DRAW_TIME; -} - -void HistoryResource :: AddToHistory( int iType, const char *szName, int iCount ) -{ - if ( iType != HISTSLOT_ITEM ) - return; - - if ( (((AMMO_PICKUP_GAP * iCurrentHistorySlot) + AMMO_PICKUP_PICK_HEIGHT) > AMMO_PICKUP_HEIGHT_MAX) || (iCurrentHistorySlot >= MAX_HISTORY) ) - { // the pic would have to be drawn too high - // so start from the bottom - iCurrentHistorySlot = 0; - } - - HIST_ITEM *freeslot = &rgAmmoHistory[iCurrentHistorySlot++]; // default to just writing to the first slot - - // I am really unhappy with all the code in this file - - int i = gHUD.GetSpriteIndex( szName ); - if ( i == -1 ) - return; // unknown sprite name, don't add it to history - - freeslot->iId = i; - freeslot->type = iType; - freeslot->iCount = iCount; - - HISTORY_DRAW_TIME = CVAR_GET_FLOAT( "hud_drawhistory_time" ); - freeslot->DisplayTime = gHUD.m_flTime + HISTORY_DRAW_TIME; -} - - -void HistoryResource :: CheckClearHistory( void ) -{ - for ( int i = 0; i < MAX_HISTORY; i++ ) - { - if ( rgAmmoHistory[i].type ) - return; - } - - iCurrentHistorySlot = 0; -} - -// -// Draw Ammo pickup history -// -int HistoryResource :: DrawAmmoHistory( float flTime ) -{ - for ( int i = 0; i < MAX_HISTORY; i++ ) - { - if ( rgAmmoHistory[i].type ) - { - rgAmmoHistory[i].DisplayTime = V_min( rgAmmoHistory[i].DisplayTime, gHUD.m_flTime + HISTORY_DRAW_TIME ); - - if ( rgAmmoHistory[i].DisplayTime <= flTime ) - { // pic drawing time has expired - memset( &rgAmmoHistory[i], 0, sizeof(HIST_ITEM) ); - CheckClearHistory(); - } - else if ( rgAmmoHistory[i].type == HISTSLOT_AMMO ) - { - wrect_t rcPic; - HSPRITE *spr = gWR.GetAmmoPicFromWeapon( rgAmmoHistory[i].iId, rcPic ); - - int r, g, b; - UnpackRGB(r,g,b, RGB_YELLOWISH); - float scale = (rgAmmoHistory[i].DisplayTime - flTime) * 80; - ScaleColors(r, g, b, V_min(scale, 255) ); - - // Draw the pic - int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth - 24; - if ( spr && *spr ) // weapon isn't loaded yet so just don't draw the pic - { // the dll has to make sure it has sent info the weapons you need - SPR_Set( *spr, r, g, b ); - SPR_DrawAdditive( 0, xpos, ypos, &rcPic ); - } - - // Draw the number - gHUD.DrawHudNumberString( xpos - 10, ypos, xpos - 100, rgAmmoHistory[i].iCount, r, g, b ); - } - else if ( rgAmmoHistory[i].type == HISTSLOT_WEAP ) - { - WEAPON *weap = gWR.GetWeapon( rgAmmoHistory[i].iId ); - - if ( !weap ) - return 1; // we don't know about the weapon yet, so don't draw anything - - int r, g, b; - UnpackRGB(r,g,b, RGB_YELLOWISH); - - if ( !gWR.HasAmmo( weap ) ) - UnpackRGB(r,g,b, RGB_REDISH); // if the weapon doesn't have ammo, display it as red - - float scale = (rgAmmoHistory[i].DisplayTime - flTime) * 80; - ScaleColors(r, g, b, V_min(scale, 255) ); - - int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth - (weap->rcInactive.right - weap->rcInactive.left); - SPR_Set( weap->hInactive, r, g, b ); - SPR_DrawAdditive( 0, xpos, ypos, &weap->rcInactive ); - } - else if ( rgAmmoHistory[i].type == HISTSLOT_ITEM ) - { - int r, g, b; - - if ( !rgAmmoHistory[i].iId ) - continue; // sprite not loaded - - wrect_t rect = gHUD.GetSpriteRect( rgAmmoHistory[i].iId ); - - UnpackRGB(r,g,b, RGB_YELLOWISH); - float scale = (rgAmmoHistory[i].DisplayTime - flTime) * 80; - ScaleColors(r, g, b, V_min(scale, 255) ); - - int ypos = ScreenHeight - (AMMO_PICKUP_PICK_HEIGHT + (AMMO_PICKUP_GAP * i)); - int xpos = ScreenWidth - (rect.right - rect.left) - 10; - - SPR_Set( gHUD.GetSprite( rgAmmoHistory[i].iId ), r, g, b ); - SPR_DrawAdditive( 0, xpos, ypos, &rect ); - } - } - } - - - return 1; -} - - diff --git a/ricochet/cl_dll/ammohistory.h b/ricochet/cl_dll/ammohistory.h deleted file mode 100644 index a717508..0000000 --- a/ricochet/cl_dll/ammohistory.h +++ /dev/null @@ -1,143 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// -// ammohistory.h -// - -// this is the max number of items in each bucket -#define MAX_WEAPON_POSITIONS MAX_WEAPON_SLOTS - -class WeaponsResource -{ -private: - // Information about weapons & ammo - WEAPON rgWeapons[MAX_WEAPONS]; // Weapons Array - - // counts of weapons * ammo - WEAPON* rgSlots[MAX_WEAPON_SLOTS+1][MAX_WEAPON_POSITIONS+1]; // The slots currently in use by weapons. The value is a pointer to the weapon; if it's NULL, no weapon is there - int riAmmo[MAX_AMMO_TYPES]; // count of each ammo type - -public: - void Init( void ) - { - memset( rgWeapons, 0, sizeof rgWeapons ); - Reset(); - } - - void Reset( void ) - { - iOldWeaponBits = 0; - memset( rgSlots, 0, sizeof rgSlots ); - memset( riAmmo, 0, sizeof riAmmo ); - } - -///// WEAPON ///// - int iOldWeaponBits; - - WEAPON *GetWeapon( int iId ) { return &rgWeapons[iId]; } - void AddWeapon( WEAPON *wp ) - { - rgWeapons[ wp->iId ] = *wp; - LoadWeaponSprites( &rgWeapons[ wp->iId ] ); - } - - void PickupWeapon( WEAPON *wp ) - { - rgSlots[ wp->iSlot ][ wp->iSlotPos ] = wp; - } - - void DropWeapon( WEAPON *wp ) - { - rgSlots[ wp->iSlot ][ wp->iSlotPos ] = NULL; - } - - void DropAllWeapons( void ) - { - for ( int i = 0; i < MAX_WEAPONS; i++ ) - { - if ( rgWeapons[i].iId ) - DropWeapon( &rgWeapons[i] ); - } - } - - WEAPON* GetWeaponSlot( int slot, int pos ) { return rgSlots[slot][pos]; } - - void LoadWeaponSprites( WEAPON* wp ); - void LoadAllWeaponSprites( void ); - WEAPON* GetFirstPos( int iSlot ); - void SelectSlot( int iSlot, int fAdvance, int iDirection ); - WEAPON* GetNextActivePos( int iSlot, int iSlotPos ); - - int HasAmmo( WEAPON *p ); - -///// AMMO ///// - AMMO GetAmmo( int iId ) { return riAmmo[ iId ]; } - - void SetAmmo( int iId, int iCount ) { riAmmo[ iId ] = iCount; } - - int CountAmmo( int iId ); - - HSPRITE* GetAmmoPicFromWeapon( int iAmmoId, wrect_t& rect ); -}; - -extern WeaponsResource gWR; - - -#define MAX_HISTORY 12 -enum { - HISTSLOT_EMPTY, - HISTSLOT_AMMO, - HISTSLOT_WEAP, - HISTSLOT_ITEM, -}; - -class HistoryResource -{ -private: - struct HIST_ITEM { - int type; - float DisplayTime; // the time at which this item should be removed from the history - int iCount; - int iId; - }; - - HIST_ITEM rgAmmoHistory[MAX_HISTORY]; - -public: - - void Init( void ) - { - Reset(); - } - - void Reset( void ) - { - memset( rgAmmoHistory, 0, sizeof rgAmmoHistory ); - } - - int iHistoryGap; - int iCurrentHistorySlot; - - void AddToHistory( int iType, int iId, int iCount = 0 ); - void AddToHistory( int iType, const char *szName, int iCount = 0 ); - - void CheckClearHistory( void ); - int DrawAmmoHistory( float flTime ); -}; - -extern HistoryResource gHR; - - - diff --git a/ricochet/cl_dll/battery.cpp b/ricochet/cl_dll/battery.cpp deleted file mode 100644 index f5e9d39..0000000 --- a/ricochet/cl_dll/battery.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// battery.cpp -// -// implementation of CHudBattery class -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -DECLARE_MESSAGE(m_Battery, Battery) - -int CHudBattery::Init(void) -{ - m_iBat = 0; - m_fFade = 0; - m_iFlags = 0; - - HOOK_MESSAGE(Battery); - - gHUD.AddHudElem(this); - - return 1; -}; - - -int CHudBattery::VidInit(void) -{ - int HUD_suit_empty = gHUD.GetSpriteIndex( "suit_empty" ); - int HUD_suit_full = gHUD.GetSpriteIndex( "suit_full" ); - - m_hSprite1 = m_hSprite2 = 0; // delaying get sprite handles until we know the sprites are loaded - m_prc1 = &gHUD.GetSpriteRect( HUD_suit_empty ); - m_prc2 = &gHUD.GetSpriteRect( HUD_suit_full ); - m_iHeight = m_prc2->bottom - m_prc1->top; - m_fFade = 0; - return 1; -}; - -int CHudBattery:: MsgFunc_Battery(const char *pszName, int iSize, void *pbuf ) -{ - m_iFlags |= HUD_ACTIVE; - - - BEGIN_READ( pbuf, iSize ); - int x = READ_SHORT(); - - if (x != m_iBat) - { - m_fFade = FADE_TIME; - m_iBat = x; - } - - return 1; -} - - -int CHudBattery::Draw(float flTime) -{ - // No Armor in Discwar - return 1; -} \ No newline at end of file diff --git a/ricochet/cl_dll/camera.h b/ricochet/cl_dll/camera.h deleted file mode 100644 index 607142b..0000000 --- a/ricochet/cl_dll/camera.h +++ /dev/null @@ -1,31 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// Camera.h -- defines and such for a 3rd person camera -// NOTE: must include quakedef.h first - -#ifndef _CAMERA_H_ -#define _CAMEA_H_ - -// pitch, yaw, dist -extern vec3_t cam_ofs; -// Using third person camera -extern int cam_thirdperson; - -void CAM_Init( void ); -void CAM_ClearStates( void ); -void CAM_StartMouseMove(void); -void CAM_EndMouseMove(void); - -#endif // _CAMERA_H_ diff --git a/ricochet/cl_dll/cdll_int.cpp b/ricochet/cl_dll/cdll_int.cpp deleted file mode 100644 index a0e1f5f..0000000 --- a/ricochet/cl_dll/cdll_int.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// cdll_int.c -// -// this implementation handles the linking of the engine to the DLL -// - -#include "hud.h" -#include "cl_util.h" -#include -#include "netadr.h" -#include "vgui_SchemeManager.h" - -#include "interface.h" - -cl_enginefunc_t gEngfuncs; -CHud gHUD ; -TeamFortressViewport *gViewPort = NULL; - -#include "pm_shared.h" - -#include "hud_servers.h" -#include "vgui_int.h" - -CSysModule *g_hTrackerModule = NULL; -#ifdef _WIN32 -#endif -void InitInput (void); -void EV_HookEvents( void ); -void IN_Commands( void ); - -/* -========================== - Initialize - -Called when the DLL is first loaded. -========================== -*/ -extern "C" -{ -int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ); -int DLLEXPORT HUD_VidInit( void ); -int DLLEXPORT HUD_Init( void ); -int DLLEXPORT HUD_Redraw( float flTime, int intermission ); -int DLLEXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime ); -int DLLEXPORT HUD_Reset ( void ); -void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ); -void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ); -char DLLEXPORT HUD_PlayerMoveTexture( char *name ); -int DLLEXPORT HUD_ConnectionlessPacket( struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); -int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ); -void DLLEXPORT HUD_Frame( double time ); -void DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ); -void DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking); -} - -/* -================================ -HUD_GetHullBounds - - Engine calls this to enumerate player collision hulls, for prediction. Return 0 if the hullnumber doesn't exist. -================================ -*/ -int DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ) -{ - int iret = 0; - - switch ( hullnumber ) - { - case 0: // Normal player - mins = Vector(-16, -16, -36); - maxs = Vector(16, 16, 36); - iret = 1; - break; - case 1: // Crouched player - mins = Vector(-16, -16, -18 ); - maxs = Vector(16, 16, 18 ); - iret = 1; - break; - case 2: // Point based hull - mins = Vector( 0, 0, 0 ); - maxs = Vector( 0, 0, 0 ); - iret = 1; - break; - } - - return iret; -} - -/* -================================ -HUD_ConnectionlessPacket - - Return 1 if the packet is valid. Set response_buffer_size if you want to send a response packet. Incoming, it holds the max - size of the response_buffer, so you must zero it out if you choose not to respond. -================================ -*/ -int DLLEXPORT HUD_ConnectionlessPacket( struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ) -{ - // Parse stuff from args - int max_buffer_size = *response_buffer_size; - - // Zero it out since we aren't going to respond. - // If we wanted to response, we'd write data into response_buffer - *response_buffer_size = 0; - - // Since we don't listen for anything here, just respond that it's a bogus message - // If we didn't reject the message, we'd return 1 for success instead. - return 0; -} - -void DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ) -{ - PM_Init( ppmove ); -} - -char DLLEXPORT HUD_PlayerMoveTexture( char *name ) -{ - return PM_FindTextureType( name ); -} - -void DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ) -{ - PM_Move( ppmove, server ); -} - -int DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ) -{ - gEngfuncs = *pEnginefuncs; - - //!!! mwh UNDONE We need to think about our versioning strategy. Do we want to try to be compatible - // with previous versions, especially when we're only 'bonus' functionality? Should it be the engine - // that decides if the DLL is compliant? - - if (iVersion != CLDLL_INTERFACE_VERSION) - return 0; - - memcpy(&gEngfuncs, pEnginefuncs, sizeof(cl_enginefunc_t)); - - EV_HookEvents(); - - return 1; -} - - -/* -========================== - HUD_VidInit - -Called when the game initializes -and whenever the vid_mode is changed -so the HUD can reinitialize itself. -========================== -*/ - -int DLLEXPORT HUD_VidInit( void ) -{ - gHUD.VidInit(); - - VGui_Startup(); - - return 1; -} - -/* -========================== - HUD_Init - -Called whenever the client connects -to a server. Reinitializes all -the hud variables. -========================== -*/ - -int DLLEXPORT HUD_Init( void ) -{ - InitInput(); - gHUD.Init(); - Scheme_Init(); - return 1; -} - - -/* -========================== - HUD_Redraw - -called every screen frame to -redraw the HUD. -=========================== -*/ - -int DLLEXPORT HUD_Redraw( float time, int intermission ) -{ - gHUD.Redraw( time, intermission ); - - return 1; -} - - -/* -========================== - HUD_UpdateClientData - -called every time shared client -dll/engine data gets changed, -and gives the cdll a chance -to modify the data. - -returns 1 if anything has been changed, 0 otherwise. -========================== -*/ - -int DLLEXPORT HUD_UpdateClientData(client_data_t *pcldata, float flTime ) -{ - IN_Commands(); - - return gHUD.UpdateClientData(pcldata, flTime ); -} - -/* -========================== - HUD_Reset - -Called at start and end of demos to restore to "non"HUD state. -========================== -*/ - -int DLLEXPORT HUD_Reset( void ) -{ - gHUD.VidInit(); - return 1; -} - - -/* -========================== -HUD_Frame - -Called by engine every frame that client .dll is loaded -========================== -*/ - -void DLLEXPORT HUD_Frame( double time ) -{ - ServersThink( time ); - - GetClientVoiceMgr()->Frame(time); -} - -/* -========================== -HUD_VoiceStatus - -Called when a player starts or stops talking. -========================== -*/ - -void DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking) -{ - GetClientVoiceMgr()->UpdateSpeakerStatus(entindex, bTalking); -} \ No newline at end of file diff --git a/ricochet/cl_dll/cl_dll.dsp b/ricochet/cl_dll/cl_dll.dsp deleted file mode 100644 index 58b0ddb..0000000 --- a/ricochet/cl_dll/cl_dll.dsp +++ /dev/null @@ -1,555 +0,0 @@ -# Microsoft Developer Studio Project File - Name="cl_dll" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=cl_dll - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "cl_dll.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "cl_dll.mak" CFG="cl_dll - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "cl_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "cl_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$Goldsrc/discwar/cl_dll", HGEBAAAA" -# PROP Scc_LocalPath "." -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "cl_dll - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir ".\Release" -# PROP BASE Intermediate_Dir ".\Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\Release" -# PROP Intermediate_Dir ".\Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /MT /W3 /GX /Zi /O2 /I "..\\" /I "..\dlls" /I ".\\" /I "..\..\game_shared" /I "..\..\engine" /I "..\..\public" /I "..\..\common" /I "..\pm_shared" /I "..\..\utils\vgui\include" /I "..\..\external" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "CLIENT_DLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ../../utils/vgui/lib/win32_vc6/vgui.lib wsock32.lib ..\..\lib\public\sdl2.lib /nologo /subsystem:windows /dll /map /debug /machine:I386 /out:".\Release\client.dll" -# SUBTRACT LINK32 /pdb:none -# Begin Custom Build - Copying to d:\quiver\ricochet\cl_dlls -InputDir=.\Release -ProjDir=. -InputPath=.\Release\client.dll -SOURCE="$(InputPath)" - -BuildCmds= \ - call ..\..\filecopy.bat $(InputPath) $(ProjDir)\..\..\..\game\mod\cl_dlls\client.dll \ - call ..\..\filecopy.bat $(InputDir)\client.pdb $(ProjDir)\..\..\..\game\mod\cl_dlls\client.pdb \ - - -"$(ProjDir)\..\..\..\game\mod\cl_dlls\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) - -"$(ProjDir)\..\..\..\game\mod\cl_dlls\client.pdb" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) -# End Custom Build - -!ELSEIF "$(CFG)" == "cl_dll - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir ".\Debug" -# PROP BASE Intermediate_Dir ".\Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\Debug" -# PROP Intermediate_Dir ".\Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /G5 /MTd /W3 /Gm /GX /ZI /Od /I "..\\" /I "..\dlls" /I ".\\" /I "..\..\game_shared" /I "..\..\engine" /I "..\..\public" /I "..\..\common" /I "..\pm_shared" /I "..\..\utils\vgui\include" /I "..\..\external" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "CLIENT_DLL" /FR /YX /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib winmm.lib ../../utils/vgui/lib/win32_vc6/vgui.lib wsock32.lib ..\..\lib\public\sdl2.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:".\Debug\client.dll" -# SUBTRACT LINK32 /pdb:none -# Begin Custom Build - Copying to \quiver\ricochet\cl_dlls -ProjDir=. -InputPath=.\Debug\client.dll -SOURCE="$(InputPath)" - -"$(ProjDir)\..\..\..\game\mod\cl_dlls\client.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - call ..\..\filecopy.bat $(InputPath) $(ProjDir)\..\..\..\game\mod\cl_dlls\client.dll - -# End Custom Build - -!ENDIF - -# Begin Target - -# Name "cl_dll - Win32 Release" -# Name "cl_dll - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90" -# Begin Group "hl" - -# PROP Default_Filter "*.cpp" -# Begin Source File - -SOURCE=..\dlls\wpn_shared\disc_weapon_disc.cpp -# End Source File -# Begin Source File - -SOURCE=.\ev_hldm.cpp -# End Source File -# Begin Source File - -SOURCE=.\hl\hl_baseentity.cpp -# End Source File -# Begin Source File - -SOURCE=.\hl\hl_events.cpp -# End Source File -# Begin Source File - -SOURCE=.\hl\hl_objects.cpp -# End Source File -# Begin Source File - -SOURCE=.\hl\hl_weapons.cpp -# End Source File -# Begin Source File - -SOURCE=.\Ricochet_JumpPads.cpp -# End Source File -# End Group -# Begin Source File - -SOURCE=.\ammo.cpp -# End Source File -# Begin Source File - -SOURCE=.\ammo_secondary.cpp -# End Source File -# Begin Source File - -SOURCE=.\ammohistory.cpp -# End Source File -# Begin Source File - -SOURCE=.\battery.cpp -# End Source File -# Begin Source File - -SOURCE=.\cdll_int.cpp -# End Source File -# Begin Source File - -SOURCE=.\com_weapons.cpp -# End Source File -# Begin Source File - -SOURCE=.\death.cpp -# End Source File -# Begin Source File - -SOURCE=.\demo.cpp -# End Source File -# Begin Source File - -SOURCE=.\entity.cpp -# End Source File -# Begin Source File - -SOURCE=.\ev_common.cpp -# End Source File -# Begin Source File - -SOURCE=.\events.cpp -# End Source File -# Begin Source File - -SOURCE=.\flashlight.cpp -# End Source File -# Begin Source File - -SOURCE=.\GameStudioModelRenderer.cpp -# End Source File -# Begin Source File - -SOURCE=.\geiger.cpp -# End Source File -# Begin Source File - -SOURCE=.\health.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud_msg.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud_redraw.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud_servers.cpp -# End Source File -# Begin Source File - -SOURCE=.\hud_update.cpp -# End Source File -# Begin Source File - -SOURCE=.\in_camera.cpp -# End Source File -# Begin Source File - -SOURCE=.\input.cpp -# End Source File -# Begin Source File - -SOURCE=.\inputw32.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\public\interface.cpp -# End Source File -# Begin Source File - -SOURCE=.\menu.cpp -# End Source File -# Begin Source File - -SOURCE=.\message.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\common\parsemsg.cpp -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_debug.c -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_math.c -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_shared.c -# End Source File -# Begin Source File - -SOURCE=.\saytext.cpp -# End Source File -# Begin Source File - -SOURCE=.\status_icons.cpp -# End Source File -# Begin Source File - -SOURCE=.\statusbar.cpp -# End Source File -# Begin Source File - -SOURCE=.\studio_util.cpp -# End Source File -# Begin Source File - -SOURCE=.\StudioModelRenderer.cpp -# End Source File -# Begin Source File - -SOURCE=.\text_message.cpp -# End Source File -# Begin Source File - -SOURCE=.\train.cpp -# End Source File -# Begin Source File - -SOURCE=.\tri.cpp -# End Source File -# Begin Source File - -SOURCE=.\util.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_checkbutton2.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_ConsolePanel.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_ControlConfigPanel.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_CustomObjects.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_discobjects.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_grid.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_helpers.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_int.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_listbox.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_loadtga.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_MOTDWindow.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_SchemeManager.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_ScorePanel.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_scrollbar2.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_ServerBrowser.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\vgui_slider2.cpp -# End Source File -# Begin Source File - -SOURCE=.\vgui_TeamFortressViewport.cpp -# End Source File -# Begin Source File - -SOURCE=.\view.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\voice_banmgr.cpp -# End Source File -# Begin Source File - -SOURCE=.\voice_status.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" -# Begin Source File - -SOURCE=.\ammo.h -# End Source File -# Begin Source File - -SOURCE=.\ammohistory.h -# End Source File -# Begin Source File - -SOURCE=.\camera.h -# End Source File -# Begin Source File - -SOURCE=.\cl_dll.h -# End Source File -# Begin Source File - -SOURCE=.\cl_util.h -# End Source File -# Begin Source File - -SOURCE=.\com_weapons.h -# End Source File -# Begin Source File - -SOURCE=.\demo.h -# End Source File -# Begin Source File - -SOURCE=.\ev_hldm.h -# End Source File -# Begin Source File - -SOURCE=.\eventscripts.h -# End Source File -# Begin Source File - -SOURCE=.\GameStudioModelRenderer.h -# End Source File -# Begin Source File - -SOURCE=.\health.h -# End Source File -# Begin Source File - -SOURCE=.\hud.h -# End Source File -# Begin Source File - -SOURCE=.\hud_iface.h -# End Source File -# Begin Source File - -SOURCE=.\hud_servers.h -# End Source File -# Begin Source File - -SOURCE=.\hud_servers_priv.h -# End Source File -# Begin Source File - -SOURCE=.\in_defs.h -# End Source File -# Begin Source File - -SOURCE=.\kbutton.h -# End Source File -# Begin Source File - -SOURCE=..\..\common\parsemsg.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_debug.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_defs.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_info.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_materials.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_movevars.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_shared.h -# End Source File -# Begin Source File - -SOURCE=.\Ricochet_BSPFile.h -# End Source File -# Begin Source File - -SOURCE=.\Ricochet_JumpPads.h -# End Source File -# Begin Source File - -SOURCE=.\studio_util.h -# End Source File -# Begin Source File - -SOURCE=.\StudioModelRenderer.h -# End Source File -# Begin Source File - -SOURCE=.\util_vector.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_ConsolePanel.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_ControlConfigPanel.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_discobjects.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_int.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_SchemeManager.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_ScorePanel.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_ServerBrowser.h -# End Source File -# Begin Source File - -SOURCE=.\vgui_TeamFortressViewport.h -# End Source File -# Begin Source File - -SOURCE=.\view.h -# End Source File -# Begin Source File - -SOURCE=.\wrect.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/ricochet/cl_dll/cl_dll.h b/ricochet/cl_dll/cl_dll.h deleted file mode 100644 index e17438c..0000000 --- a/ricochet/cl_dll/cl_dll.h +++ /dev/null @@ -1,40 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// cl_dll.h -// - -// 4-23-98 JOHN - -// -// This DLL is linked by the client when they first initialize. -// This DLL is responsible for the following tasks: -// - Loading the HUD graphics upon initialization -// - Drawing the HUD graphics every frame -// - Handling the custum HUD-update packets -// - -#include "Platform.h" - -typedef unsigned char byte; -typedef unsigned short word; -typedef float vec_t; -typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf); - -#include "util_vector.h" -#include "../engine/cdll_int.h" -#include "../dlls/cdll_dll.h" - -extern cl_enginefunc_t gEngfuncs; diff --git a/ricochet/cl_dll/cl_util.h b/ricochet/cl_dll/cl_util.h deleted file mode 100644 index 5330ce9..0000000 --- a/ricochet/cl_dll/cl_util.h +++ /dev/null @@ -1,178 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// util.h -// - -#include "cvardef.h" - -#include "Platform.h" - -// Macros to hook function calls into the HUD object -#define HOOK_MESSAGE(x) gEngfuncs.pfnHookUserMsg(#x, __MsgFunc_##x ); - -#define DECLARE_MESSAGE(y, x) int __MsgFunc_##x(const char *pszName, int iSize, void *pbuf) \ - { \ - return gHUD.y.MsgFunc_##x(pszName, iSize, pbuf ); \ - } - - -#define HOOK_COMMAND(x, y) gEngfuncs.pfnAddCommand( x, __CmdFunc_##y ); -#define DECLARE_COMMAND(y, x) void __CmdFunc_##x( void ) \ - { \ - gHUD.y.UserCmd_##x( ); \ - } - -inline float CVAR_GET_FLOAT( const char *x ) { return gEngfuncs.pfnGetCvarFloat( (char*)x ); } -inline char* CVAR_GET_STRING( const char *x ) { return gEngfuncs.pfnGetCvarString( (char*)x ); } -inline struct cvar_s *CVAR_CREATE( const char *cv, const char *val, const int flags ) { return gEngfuncs.pfnRegisterVariable( (char*)cv, (char*)val, flags ); } - -#define SPR_Load (*gEngfuncs.pfnSPR_Load) -#define SPR_Set (*gEngfuncs.pfnSPR_Set) -#define SPR_Frames (*gEngfuncs.pfnSPR_Frames) -#define SPR_GetList (*gEngfuncs.pfnSPR_GetList) - -// SPR_Draw draws a the current sprite as solid -#define SPR_Draw (*gEngfuncs.pfnSPR_Draw) -// SPR_DrawHoles draws the current sprites, with color index255 not drawn (transparent) -#define SPR_DrawHoles (*gEngfuncs.pfnSPR_DrawHoles) -// SPR_DrawAdditive adds the sprites RGB values to the background (additive transulency) -#define SPR_DrawAdditive (*gEngfuncs.pfnSPR_DrawAdditive) - -// SPR_EnableScissor sets a clipping rect for HUD sprites. (0,0) is the top-left hand corner of the screen. -#define SPR_EnableScissor (*gEngfuncs.pfnSPR_EnableScissor) -// SPR_DisableScissor disables the clipping rect -#define SPR_DisableScissor (*gEngfuncs.pfnSPR_DisableScissor) -// -#define FillRGBA (*gEngfuncs.pfnFillRGBA) - - -// ScreenHeight returns the height of the screen, in pixels -#define ScreenHeight (gHUD.m_scrinfo.iHeight) -// ScreenWidth returns the width of the screen, in pixels -#define ScreenWidth (gHUD.m_scrinfo.iWidth) - -#define GetScreenInfo (*gEngfuncs.pfnGetScreenInfo) -#define ServerCmd (*gEngfuncs.pfnServerCmd) -#define ClientCmd (*gEngfuncs.pfnClientCmd) -#define SetCrosshair (*gEngfuncs.pfnSetCrosshair) -#define AngleVectors (*gEngfuncs.pfnAngleVectors) - - -// Gets the height & width of a sprite, at the specified frame -inline int SPR_Height( HSPRITE x, int f ) { return gEngfuncs.pfnSPR_Height(x, f); } -inline int SPR_Width( HSPRITE x, int f ) { return gEngfuncs.pfnSPR_Width(x, f); } - -inline client_textmessage_t *TextMessageGet( const char *pName ) { return gEngfuncs.pfnTextMessageGet( pName ); } -inline int TextMessageDrawChar( int x, int y, int number, int r, int g, int b ) -{ - return gEngfuncs.pfnDrawCharacter( x, y, number, r, g, b ); -} - -inline int DrawConsoleString( int x, int y, const char *string ) -{ - return gEngfuncs.pfnDrawConsoleString( x, y, (char*) string ); -} - -inline void GetConsoleStringSize( const char *string, int *width, int *height ) -{ - gEngfuncs.pfnDrawConsoleStringLen( string, width, height ); -} - -inline int ConsoleStringLen( const char *string ) -{ - int _width, _height; - GetConsoleStringSize( string, &_width, &_height ); - return _width; -} - -inline void ConsolePrint( const char *string ) -{ - gEngfuncs.pfnConsolePrint( string ); -} - -inline void CenterPrint( const char *string ) -{ - gEngfuncs.pfnCenterPrint( string ); -} - - -inline char *safe_strcpy( char *dst, const char *src, int len_dst) -{ - if( len_dst <= 0 ) - { - return NULL; // this is bad - } - - strncpy(dst,src,len_dst); - dst[ len_dst - 1 ] = '\0'; - - return dst; -} - -inline int safe_sprintf( char *dst, int len_dst, const char *format, ...) -{ - if( len_dst <= 0 ) - { - return -1; // this is bad - } - - va_list v; - - va_start(v, format); - - _vsnprintf(dst,len_dst,format,v); - - va_end(v); - - dst[ len_dst - 1 ] = '\0'; - - return 0; -} - -// returns the players name of entity no. -#define GetPlayerInfo (*gEngfuncs.pfnGetPlayerInfo) - -// sound functions -inline void PlaySound( char *szSound, float vol ) { gEngfuncs.pfnPlaySoundByName( szSound, vol ); } -inline void PlaySound( int iSound, float vol ) { gEngfuncs.pfnPlaySoundByIndex( iSound, vol ); } - -void ScaleColors( int &r, int &g, int &b, int a ); - -#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) -#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];} -#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];} -#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];} -#define VectorClear(a) { a[0]=0.0;a[1]=0.0;a[2]=0.0;} -float Length(const float *v); -void VectorMA (const float *veca, float scale, const float *vecb, float *vecc); -void VectorScale (const float *in, float scale, float *out); -float VectorNormalize (float *v); -void VectorInverse ( float *v ); - -extern vec3_t vec3_origin; -// disable 'possible loss of data converting float to int' warning message -#pragma warning( disable: 4244 ) -// disable 'truncation from 'const double' to 'float' warning message -#pragma warning( disable: 4305 ) - -inline void UnpackRGB(int &r, int &g, int &b, unsigned long ulRGB)\ -{\ - r = (ulRGB & 0xFF0000) >>16;\ - g = (ulRGB & 0xFF00) >> 8;\ - b = ulRGB & 0xFF;\ -} - -HSPRITE LoadSprite(const char *pszName); diff --git a/ricochet/cl_dll/com_weapons.cpp b/ricochet/cl_dll/com_weapons.cpp deleted file mode 100644 index c5bce1b..0000000 --- a/ricochet/cl_dll/com_weapons.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ - -// Com_Weapons.cpp -// Shared weapons common/shared functions -#include -#include "hud.h" -#include "cl_util.h" -#include "com_weapons.h" - -#include "const.h" -#include "entity_state.h" -#include "r_efx.h" - -// g_runfuncs is true if this is the first time we've "predicated" a particular movement/firing -// command. If it is 1, then we should play events/sounds etc., otherwise, we just will be -// updating state info, but not firing events -int g_runfuncs = 0; - -// During our weapon prediction processing, we'll need to reference some data that is part of -// the final state passed into the postthink functionality. We'll set this pointer and then -// reset it to NULL as appropriate -struct local_state_s *g_finalstate = NULL; - -/* -==================== -COM_Log - -Log debug messages to file ( appends ) -==================== -*/ -void COM_Log( char *pszFile, char *fmt, ...) -{ - va_list argptr; - char string[1024]; - FILE *fp; - char *pfilename; - - if ( !pszFile ) - { - pfilename = "c:\\hllog.txt"; - } - else - { - pfilename = pszFile; - } - - va_start (argptr,fmt); - vsprintf (string, fmt,argptr); - va_end (argptr); - - fp = fopen( pfilename, "a+t"); - if (fp) - { - fprintf(fp, "%s", string); - fclose(fp); - } -} - -// remember the current animation for the view model, in case we get out of sync with -// server. -static int g_currentanim; - -/* -===================== -HUD_SendWeaponAnim - -Change weapon model animation -===================== -*/ -void HUD_SendWeaponAnim( int iAnim, int body, int force ) -{ - // Don't actually change it. - if ( !g_runfuncs && !force ) - return; - - g_currentanim = iAnim; - - // Tell animation system new info - gEngfuncs.pfnWeaponAnim( iAnim, body ); -} - -/* -===================== -HUD_GetWeaponAnim - -Retrieve current predicted weapon animation -===================== -*/ -int HUD_GetWeaponAnim( void ) -{ - return g_currentanim; -} - -/* -===================== -HUD_PlaySound - -Play a sound, if we are seeing this command for the first time -===================== -*/ -void HUD_PlaySound( char *sound, float volume ) -{ - if ( !g_runfuncs || !g_finalstate ) - return; - - gEngfuncs.pfnPlaySoundByNameAtLocation( sound, volume, (float *)&g_finalstate->playerstate.origin ); -} - -/* -===================== -HUD_PlaybackEvent - -Directly queue up an event on the client -===================== -*/ -void HUD_PlaybackEvent( int flags, const edict_t *pInvoker, unsigned short eventindex, float delay, - float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ) -{ - vec3_t org; - vec3_t ang; - - if ( !g_runfuncs || !g_finalstate ) - return; - - // Weapon prediction events are assumed to occur at the player's origin - org = g_finalstate->playerstate.origin; - ang = v_angles; - gEngfuncs.pfnPlaybackEvent( flags, pInvoker, eventindex, delay, (float *)&org, (float *)&ang, fparam1, fparam2, iparam1, iparam2, bparam1, bparam2 ); -} - -/* -===================== -HUD_SetMaxSpeed - -===================== -*/ -void HUD_SetMaxSpeed( const edict_t *ed, float speed ) -{ -} - - -/* -===================== -UTIL_WeaponTimeBase - -Always 0.0 on client, even if not predicting weapons ( won't get called - in that case ) -===================== -*/ -float UTIL_WeaponTimeBase( void ) -{ - return 0.0; -} - -static unsigned int glSeed = 0; - -unsigned int seed_table[ 256 ] = -{ - 28985, 27138, 26457, 9451, 17764, 10909, 28790, 8716, 6361, 4853, 17798, 21977, 19643, 20662, 10834, 20103, - 27067, 28634, 18623, 25849, 8576, 26234, 23887, 18228, 32587, 4836, 3306, 1811, 3035, 24559, 18399, 315, - 26766, 907, 24102, 12370, 9674, 2972, 10472, 16492, 22683, 11529, 27968, 30406, 13213, 2319, 23620, 16823, - 10013, 23772, 21567, 1251, 19579, 20313, 18241, 30130, 8402, 20807, 27354, 7169, 21211, 17293, 5410, 19223, - 10255, 22480, 27388, 9946, 15628, 24389, 17308, 2370, 9530, 31683, 25927, 23567, 11694, 26397, 32602, 15031, - 18255, 17582, 1422, 28835, 23607, 12597, 20602, 10138, 5212, 1252, 10074, 23166, 19823, 31667, 5902, 24630, - 18948, 14330, 14950, 8939, 23540, 21311, 22428, 22391, 3583, 29004, 30498, 18714, 4278, 2437, 22430, 3439, - 28313, 23161, 25396, 13471, 19324, 15287, 2563, 18901, 13103, 16867, 9714, 14322, 15197, 26889, 19372, 26241, - 31925, 14640, 11497, 8941, 10056, 6451, 28656, 10737, 13874, 17356, 8281, 25937, 1661, 4850, 7448, 12744, - 21826, 5477, 10167, 16705, 26897, 8839, 30947, 27978, 27283, 24685, 32298, 3525, 12398, 28726, 9475, 10208, - 617, 13467, 22287, 2376, 6097, 26312, 2974, 9114, 21787, 28010, 4725, 15387, 3274, 10762, 31695, 17320, - 18324, 12441, 16801, 27376, 22464, 7500, 5666, 18144, 15314, 31914, 31627, 6495, 5226, 31203, 2331, 4668, - 12650, 18275, 351, 7268, 31319, 30119, 7600, 2905, 13826, 11343, 13053, 15583, 30055, 31093, 5067, 761, - 9685, 11070, 21369, 27155, 3663, 26542, 20169, 12161, 15411, 30401, 7580, 31784, 8985, 29367, 20989, 14203, - 29694, 21167, 10337, 1706, 28578, 887, 3373, 19477, 14382, 675, 7033, 15111, 26138, 12252, 30996, 21409, - 25678, 18555, 13256, 23316, 22407, 16727, 991, 9236, 5373, 29402, 6117, 15241, 27715, 19291, 19888, 19847 -}; - -unsigned int U_Random( void ) -{ - glSeed *= 69069; - glSeed += seed_table[ glSeed & 0xff ]; - - return ( ++glSeed & 0x0fffffff ); -} - -void U_Srand( unsigned int seed ) -{ - glSeed = seed_table[ seed & 0xff ]; -} - -/* -===================== -UTIL_SharedRandomLong -===================== -*/ -int UTIL_SharedRandomLong( unsigned int seed, int low, int high ) -{ - - unsigned int range; - - U_Srand( (int)seed + low + high ); - - range = high - low + 1; - if ( !(range - 1) ) - { - return low; - } - else - { - int offset; - int rnum; - - rnum = U_Random(); - - offset = rnum % range; - - return (low + offset); - } -} - -/* -===================== -UTIL_SharedRandomFloat -===================== -*/ -float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ) -{ - // - unsigned int range; - - U_Srand( (int)seed + *(int *)&low + *(int *)&high ); - - U_Random(); - U_Random(); - - range = high - low; - if ( !range ) - { - return low; - } - else - { - int tensixrand; - float offset; - - tensixrand = U_Random() & 65535; - - offset = (float)tensixrand / 65536.0; - - return (low + offset * range ); - } -} - -/* -====================== -stub_* - -stub functions for such things as precaching. So we don't have to modify weapons code that - is compiled into both game and client .dlls. -====================== -*/ -int stub_PrecacheModel ( const char* s ) { return 0; } -int stub_PrecacheSound ( const char* s ) { return 0; } -unsigned short stub_PrecacheEvent ( int type, const char *s ) { return 0; } -const char *stub_NameForFunction ( uint32 function ) { return "func"; } -void stub_SetModel ( edict_t *e, const char *m ) {} diff --git a/ricochet/cl_dll/com_weapons.h b/ricochet/cl_dll/com_weapons.h deleted file mode 100644 index 37d24fa..0000000 --- a/ricochet/cl_dll/com_weapons.h +++ /dev/null @@ -1,41 +0,0 @@ -// com_weapons.h -// Shared weapons common function prototypes -#if !defined( COM_WEAPONSH ) -#define COM_WEAPONSH -#ifdef _WIN32 -#pragma once -#endif - -#include "hud_iface.h" - -extern "C" -{ - void DLLEXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ); -} - -void COM_Log( char *pszFile, char *fmt, ...); -int CL_IsDead( void ); - -float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ); -int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); - -int HUD_GetWeaponAnim( void ); -void HUD_SendWeaponAnim( int iAnim, int body, int force ); -void HUD_PlaySound( char *sound, float volume ); -void HUD_PlaybackEvent( int flags, const struct edict_s *pInvoker, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); -void HUD_SetMaxSpeed( const struct edict_s *ed, float speed ); -int stub_PrecacheModel( const char* s ); -int stub_PrecacheSound( const char* s ); -unsigned short stub_PrecacheEvent( int type, const char *s ); -const char *stub_NameForFunction ( uint32 function ); -void stub_SetModel ( struct edict_s *e, const char *m ); - - -extern cvar_t *cl_lw; - -extern int g_runfuncs; -extern vec3_t v_angles; -extern float g_lastFOV; -extern struct local_state_s *g_finalstate; - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/death.cpp b/ricochet/cl_dll/death.cpp deleted file mode 100644 index 7eff162..0000000 --- a/ricochet/cl_dll/death.cpp +++ /dev/null @@ -1,307 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// -// death notice -// -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -#include "vgui_TeamFortressViewport.h" - -DECLARE_MESSAGE( m_DeathNotice, DeathMsg ); - -struct DeathNoticeItem { - char szKiller[MAX_PLAYER_NAME_LENGTH*2]; - char szVictim[MAX_PLAYER_NAME_LENGTH*2]; - int iId; // the index number of the associated sprite - int iSuicide; - int iTeamKill; - int iNonPlayerKill; - float flDisplayTime; - float *KillerColor; - float *VictimColor; -}; - -#define MAX_DEATHNOTICES 4 -static int DEATHNOTICE_DISPLAY_TIME = 6; - -#define DEATHNOTICE_TOP 20 - -DeathNoticeItem rgDeathNoticeList[ MAX_DEATHNOTICES + 1 ]; - -float g_ColorBlue[3] = { 0.6, 0.8, 1.0 }; -float g_ColorRed[3] = { 1.0, 0.6, 0.3 }; -float g_ColorGreen[3] = { 0.6, 1.0, 0.6 }; -float g_ColorYellow[3] = { 1.0, 0.7, 0.0 }; - -float *GetClientColor( int clientIndex ) -{ - const char *teamName = g_PlayerExtraInfo[clientIndex].teamname; - - if ( !teamName || *teamName == 0 ) - return NULL; - - if ( !stricmp( "blue", teamName ) ) - return g_ColorBlue; - else if ( !stricmp( "red", teamName ) ) - return g_ColorRed; - else if ( !stricmp( "green", teamName ) ) - return g_ColorGreen; - else if ( !stricmp( "yellow", teamName ) ) - return g_ColorYellow; - - return NULL; -} - - -int CHudDeathNotice :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( DeathMsg ); - - CVAR_CREATE( "hud_deathnotice_time", "6", 0 ); - - return 1; -} - - -void CHudDeathNotice :: InitHUDData( void ) -{ - memset( rgDeathNoticeList, 0, sizeof(rgDeathNoticeList) ); -} - - -int CHudDeathNotice :: VidInit( void ) -{ - m_HUD_d_skull = gHUD.GetSpriteIndex( "d_skull" ); - - return 1; -} - -int CHudDeathNotice :: Draw( float flTime ) -{ - int x, y, r, g, b; - - for ( int i = 0; i < MAX_DEATHNOTICES; i++ ) - { - if ( rgDeathNoticeList[i].iId == 0 ) - break; // we've gone through them all - - if ( rgDeathNoticeList[i].flDisplayTime < flTime ) - { // display time has expired - // remove the current item from the list - memmove( &rgDeathNoticeList[i], &rgDeathNoticeList[i+1], sizeof(DeathNoticeItem) * (MAX_DEATHNOTICES - i) ); - i--; // continue on the next item; stop the counter getting incremented - continue; - } - - rgDeathNoticeList[i].flDisplayTime = V_min( rgDeathNoticeList[i].flDisplayTime, gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME ); - - // Draw the death notice - - // Make it a bigger increment in 640, 'cos the Discwar death sprites are 32 tall, not 16 in 640 - if ( ScreenHeight >= 640 ) - y = DEATHNOTICE_TOP + (36 * i); //!!! - else - y = DEATHNOTICE_TOP + (20 * i); //!!! - - int id = (rgDeathNoticeList[i].iId == -1) ? m_HUD_d_skull : rgDeathNoticeList[i].iId; - x = ScreenWidth - ConsoleStringLen(rgDeathNoticeList[i].szVictim) - (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left); - - if ( !rgDeathNoticeList[i].iSuicide ) - { - x -= (5 + ConsoleStringLen( rgDeathNoticeList[i].szKiller ) ); - - // Draw killers name - if ( rgDeathNoticeList[i].KillerColor ) - gEngfuncs.pfnDrawSetTextColor( rgDeathNoticeList[i].KillerColor[0], rgDeathNoticeList[i].KillerColor[1], rgDeathNoticeList[i].KillerColor[2] ); - x = 5 + DrawConsoleString( x, y, rgDeathNoticeList[i].szKiller ); - } - - r = 255; g = 80; b = 0; - if ( rgDeathNoticeList[i].iTeamKill ) - { - r = 10; g = 240; b = 10; // display it in sickly green - } - - // Draw death weapon - SPR_Set( gHUD.GetSprite(id), r, g, b ); - SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(id) ); - - x += (gHUD.GetSpriteRect(id).right - gHUD.GetSpriteRect(id).left); - - // Draw victims name (if it was a player that was killed) - if (rgDeathNoticeList[i].iNonPlayerKill == FALSE) - { - if ( rgDeathNoticeList[i].VictimColor ) - gEngfuncs.pfnDrawSetTextColor( rgDeathNoticeList[i].VictimColor[0], rgDeathNoticeList[i].VictimColor[1], rgDeathNoticeList[i].VictimColor[2] ); - x = DrawConsoleString( x, y, rgDeathNoticeList[i].szVictim ); - } - } - - return 1; -} - -// This message handler may be better off elsewhere -int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbuf ) -{ - m_iFlags |= HUD_ACTIVE; - - BEGIN_READ( pbuf, iSize ); - - int killer = READ_BYTE(); - int victim = READ_BYTE(); - - char killedwith[32]; - strcpy( killedwith, "d_" ); - strncat( killedwith, READ_STRING(), 32 ); - - if (gViewPort) - gViewPort->DeathMsg( killer, victim ); - - int i; - for ( i = 0; i < MAX_DEATHNOTICES; i++ ) - { - if ( rgDeathNoticeList[i].iId == 0 ) - break; - } - if ( i == MAX_DEATHNOTICES ) - { // move the rest of the list forward to make room for this item - memmove( rgDeathNoticeList, rgDeathNoticeList+1, sizeof(DeathNoticeItem) * MAX_DEATHNOTICES ); - i = MAX_DEATHNOTICES - 1; - } - - if (gViewPort) - gViewPort->GetAllPlayersInfo(); - - // Get the Killer's name - char *killer_name = g_PlayerInfoList[ killer ].name; - if ( !killer_name ) - { - killer_name = ""; - rgDeathNoticeList[i].szKiller[0] = 0; - } - else - { - rgDeathNoticeList[i].KillerColor = GetClientColor( killer ); - strncpy( rgDeathNoticeList[i].szKiller, killer_name, MAX_PLAYER_NAME_LENGTH ); - rgDeathNoticeList[i].szKiller[MAX_PLAYER_NAME_LENGTH-1] = 0; - } - - // Get the Victim's name - char *victim_name = NULL; - // If victim is -1, the killer killed a specific, non-player object (like a sentrygun) - if ( ((char)victim) != -1 ) - victim_name = g_PlayerInfoList[ victim ].name; - if ( !victim_name ) - { - victim_name = ""; - rgDeathNoticeList[i].szVictim[0] = 0; - } - else - { - rgDeathNoticeList[i].VictimColor = GetClientColor( victim ); - strncpy( rgDeathNoticeList[i].szVictim, victim_name, MAX_PLAYER_NAME_LENGTH ); - rgDeathNoticeList[i].szVictim[MAX_PLAYER_NAME_LENGTH-1] = 0; - } - - // Is it a non-player object kill? - if ( ((char)victim) == -1 ) - { - rgDeathNoticeList[i].iNonPlayerKill = TRUE; - - // Store the object's name in the Victim slot (skip the d_ bit) - strcpy( rgDeathNoticeList[i].szVictim, killedwith+2 ); - } - else - { - if ( killer == victim || killer == 0 ) - rgDeathNoticeList[i].iSuicide = TRUE; - - if ( !strcmp( killedwith, "d_teammate" ) ) - rgDeathNoticeList[i].iTeamKill = TRUE; - } - - // Find the sprite in the list - int spr = gHUD.GetSpriteIndex( killedwith ); - - rgDeathNoticeList[i].iId = spr; - - DEATHNOTICE_DISPLAY_TIME = CVAR_GET_FLOAT( "hud_deathnotice_time" ); - rgDeathNoticeList[i].flDisplayTime = gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME; - - if (rgDeathNoticeList[i].iNonPlayerKill) - { - ConsolePrint( rgDeathNoticeList[i].szKiller ); - ConsolePrint( " killed a " ); - ConsolePrint( rgDeathNoticeList[i].szVictim ); - ConsolePrint( "\n" ); - } - else - { - // record the death notice in the console - if ( rgDeathNoticeList[i].iSuicide ) - { - ConsolePrint( rgDeathNoticeList[i].szVictim ); - - if ( !strcmp( killedwith, "d_world" ) ) - { - ConsolePrint( " died" ); - } - else - { - ConsolePrint( " killed self" ); - } - } - else if ( rgDeathNoticeList[i].iTeamKill ) - { - ConsolePrint( rgDeathNoticeList[i].szKiller ); - ConsolePrint( " killed his teammate " ); - ConsolePrint( rgDeathNoticeList[i].szVictim ); - } - else - { - ConsolePrint( rgDeathNoticeList[i].szKiller ); - ConsolePrint( " killed " ); - ConsolePrint( rgDeathNoticeList[i].szVictim ); - } - - if ( killedwith && *killedwith && (*killedwith > 13 ) && strcmp( killedwith, "d_world" ) && !rgDeathNoticeList[i].iTeamKill ) - { - ConsolePrint( " with " ); - - // replace the code names with the 'real' names - if ( !strcmp( killedwith+2, "egon" ) ) - strcpy( killedwith, "d_gluon gun" ); - if ( !strcmp( killedwith+2, "gauss" ) ) - strcpy( killedwith, "d_tau cannon" ); - - ConsolePrint( killedwith+2 ); // skip over the "d_" part - } - - ConsolePrint( "\n" ); - } - - return 1; -} - - - - diff --git a/ricochet/cl_dll/demo.cpp b/ricochet/cl_dll/demo.cpp deleted file mode 100644 index 0ccf3f8..0000000 --- a/ricochet/cl_dll/demo.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "hud.h" -#include "cl_util.h" -#include "demo.h" -#include "demo_api.h" -#include - -extern "C" -{ - void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer ); -} - -/* -===================== -Demo_WriteBuffer - -Write some data to the demo stream -===================== -*/ -void Demo_WriteBuffer( int type, int size, unsigned char *buffer ) -{ - int pos = 0; - unsigned char buf[ 32 * 1024 ]; - *( int * )&buf[pos] = type; - pos+=sizeof( int ); - - memcpy( &buf[pos], buffer, size ); - - // Write full buffer out - gEngfuncs.pDemoAPI->WriteBuffer( size + sizeof( int ), buf ); -} - -/* -===================== -Demo_ReadBuffer - -Engine wants us to parse some data from the demo stream -===================== -*/ -void DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer ) -{ - int type; - int i = 0; - - type = *( int * )buffer; - i += sizeof( int ); - switch ( type ) - { - case TYPE_USER: - break; - default: - gEngfuncs.Con_DPrintf( "Unknown demo buffer type, skipping.\n" ); - break; - } -} \ No newline at end of file diff --git a/ricochet/cl_dll/demo.h b/ricochet/cl_dll/demo.h deleted file mode 100644 index f538e82..0000000 --- a/ricochet/cl_dll/demo.h +++ /dev/null @@ -1,27 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#if !defined( DEMOH ) -#define DEMOH -#pragma once - -// Types of demo messages we can write/parse -enum -{ - TYPE_USER = 0, -}; - -void Demo_WriteBuffer( int type, int size, unsigned char *buffer ); - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/entity.cpp b/ricochet/cl_dll/entity.cpp deleted file mode 100644 index 9568b7f..0000000 --- a/ricochet/cl_dll/entity.cpp +++ /dev/null @@ -1,641 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000, 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. -* -****/ -// Client side entity management functions -#include - -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "entity_types.h" -#include "studio_event.h" // def. of mstudioevent_t -#include "r_efx.h" -#include "event_api.h" -#include "pm_defs.h" -#include "pmtrace.h" - -#include - -extern vec3_t v_origin; -extern int iPrevRenderState; -extern int iRenderStateChanged; - -void Game_AddObjects( void ); - -extern "C" -{ - int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void DLLEXPORT HUD_CreateEntities( void ); - void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); - void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); - void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); - void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd ); - void DLLEXPORT HUD_TempEntUpdate( double frametime, double client_time, double cl_gravity, struct tempent_s **ppTempEntFree, struct tempent_s **ppTempEntActive, int ( *Callback_AddVisibleEntity )( struct cl_entity_s *pEntity ), void ( *Callback_TempEntPlaySound )( struct tempent_s *pTemp, float damp ) ); - struct cl_entity_s DLLEXPORT *HUD_GetUserEntity( int index ); -} - -/* -======================== -HUD_AddEntity - Return 0 to filter entity from visible list for rendering -======================== -*/ -int DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ) -{ - switch ( type ) - { - case ET_NORMAL: - case ET_PLAYER: - case ET_BEAM: - case ET_TEMPENTITY: - case ET_FRAGMENTED: - default: - break; - } - - return 1; -} - -/* -========================= -HUD_TxferLocalOverrides - -The server sends us our origin with extra precision as part of the clientdata structure, not during the normal -playerstate update in entity_state_t. In order for these overrides to eventually get to the appropriate playerstate -structure, we need to copy them into the state structure at this point. -========================= -*/ -void DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ) -{ - VectorCopy( client->origin, state->origin ); - - // Spectator - state->iuser1 = client->iuser1; - state->iuser2 = client->iuser2; -} - -/* -========================= -HUD_ProcessPlayerState - -We have received entity_state_t for this player over the network. We need to copy appropriate fields to the -playerstate structure -========================= -*/ -void DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ) -{ - cl_entity_t *player = gEngfuncs.GetLocalPlayer(); // Get the local player's index - - // Copy in network data - VectorCopy( src->origin, dst->origin ); - VectorCopy( src->angles, dst->angles ); - - VectorCopy( src->velocity, dst->velocity ); - - dst->frame = src->frame; - dst->modelindex = src->modelindex; - dst->skin = src->skin; - dst->effects = src->effects; - dst->weaponmodel = src->weaponmodel; - dst->movetype = src->movetype; - dst->sequence = src->sequence; - dst->animtime = src->animtime; - - dst->solid = src->solid; - - dst->rendermode = src->rendermode; - dst->renderamt = src->renderamt; - dst->rendercolor.r = src->rendercolor.r; - dst->rendercolor.g = src->rendercolor.g; - dst->rendercolor.b = src->rendercolor.b; - dst->renderfx = src->renderfx; - - // Hack to find out when our render state changes. - // Needed because we need the previous render state when we flip to thirdperson - if ( dst->number == player->index ) - { - if ( iPrevRenderState != dst->renderfx ) - iRenderStateChanged = TRUE; - iPrevRenderState = dst->renderfx; - } - - dst->framerate = src->framerate; - dst->body = src->body; - - memcpy( &dst->controller[0], &src->controller[0], 4 * sizeof( byte ) ); - memcpy( &dst->blending[0], &src->blending[0], 2 * sizeof( byte ) ); - - VectorCopy( src->basevelocity, dst->basevelocity ); - - dst->friction = src->friction; - dst->gravity = src->gravity; - dst->gaitsequence = src->gaitsequence; - dst->spectator = src->spectator; - dst->usehull = src->usehull; - dst->playerclass = src->playerclass; - dst->team = src->team; - dst->colormap = src->colormap; - - // Save off some data so other areas of the Client DLL can get to it - if ( dst->number == player->index ) - { - g_iPlayerClass = dst->playerclass; - g_iTeamNumber = dst->team; - g_iUser1 = src->iuser1; - g_iUser2 = src->iuser2; - } -} - -/* -========================= -HUD_TxferPredictionData - -Because we can predict an arbitrary number of frames before the server responds with an update, we need to be able to copy client side prediction data in - from the state that the server ack'd receiving, which can be anywhere along the predicted frame path ( i.e., we could predict 20 frames into the future and the server ack's - up through 10 of those frames, so we need to copy persistent client-side only state from the 10th predicted frame to the slot the server - update is occupying. -========================= -*/ -void DLLEXPORT HUD_TxferPredictionData ( struct entity_state_s *ps, const struct entity_state_s *pps, struct clientdata_s *pcd, const struct clientdata_s *ppcd, struct weapon_data_s *wd, const struct weapon_data_s *pwd ) -{ - ps->oldbuttons = pps->oldbuttons; - ps->flFallVelocity = pps->flFallVelocity; - ps->iStepLeft = pps->iStepLeft; - ps->playerclass = pps->playerclass; - - ps->sequence = pps->sequence; - ps->gaitsequence = pps->gaitsequence; - - pcd->viewmodel = ppcd->viewmodel; - pcd->m_iId = ppcd->m_iId; - pcd->ammo_shells = ppcd->ammo_shells; - pcd->ammo_nails = ppcd->ammo_nails; - pcd->ammo_cells = ppcd->ammo_cells; - pcd->ammo_rockets = ppcd->ammo_rockets; - pcd->m_flNextAttack = ppcd->m_flNextAttack; - pcd->fov = ppcd->fov; - pcd->weaponanim = ppcd->weaponanim; - pcd->tfstate = ppcd->tfstate; - pcd->maxspeed = ppcd->maxspeed; - - pcd->deadflag = ppcd->deadflag; - - // Spectator - pcd->iuser1 = ppcd->iuser1; - pcd->iuser2 = ppcd->iuser2; - - pcd->fuser1 = ppcd->fuser1; - pcd->fuser2 = ppcd->fuser2; - pcd->fuser3 = ppcd->fuser3; - - memcpy( wd, pwd, 32 * sizeof( weapon_data_t ) ); -} - -/* -========================= -HUD_CreateEntities - -Gives us a chance to add additional entities to the render this frame -========================= -*/ -void DLLEXPORT HUD_CreateEntities( void ) -{ - // e.g., create a persistent cl_entity_t somewhere. - // Load an appropriate model into it ( gEngfuncs.CL_LoadModel ) - // Call gEngfuncs.CL_CreateVisibleEntity to add it to the visedicts list - - // Add in any game specific objects - Game_AddObjects(); - - GetClientVoiceMgr()->CreateEntities(); -} - -/* -========================= -HUD_StudioEvent - -The entity's studio model description indicated an event was -fired during this frame, handle the event by it's tag ( e.g., muzzleflash, sound ) -========================= -*/ -void DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ) -{ - switch( event->event ) - { - case 5001: - gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[0], atoi( event->options) ); - break; - case 5011: - gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[1], atoi( event->options) ); - break; - case 5021: - gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[2], atoi( event->options) ); - break; - case 5031: - gEngfuncs.pEfxAPI->R_MuzzleFlash( (float *)&entity->attachment[3], atoi( event->options) ); - break; - case 5002: - gEngfuncs.pEfxAPI->R_SparkEffect( (float *)&entity->attachment[0], atoi( event->options), -100, 100 ); - break; - // Client side sound - case 5004: - gEngfuncs.pfnPlaySoundByNameAtLocation( (char *)event->options, 1.0, (float *)&entity->attachment[0] ); - break; - default: - break; - } -} - -/* -================= -CL_UpdateTEnts - -Simulation and cleanup of temporary entities -================= -*/ -void DLLEXPORT HUD_TempEntUpdate ( - double frametime, // Simulation time - double client_time, // Absolute time on client - double cl_gravity, // True gravity on client - TEMPENTITY **ppTempEntFree, // List of freed temporary ents - TEMPENTITY **ppTempEntActive, // List - int ( *Callback_AddVisibleEntity )( cl_entity_t *pEntity ), - void ( *Callback_TempEntPlaySound )( TEMPENTITY *pTemp, float damp ) ) -{ - static int gTempEntFrame = 0; - int i; - TEMPENTITY *pTemp, *pnext, *pprev; - float freq, gravity, gravitySlow, life, fastFreq; - - // Nothing to simulate - if ( !*ppTempEntActive ) - return; - - // in order to have tents collide with players, we have to run the player prediction code so - // that the client has the player list. We run this code once when we detect any COLLIDEALL - // tent, then set this BOOL to true so the code doesn't get run again if there's more than - // one COLLIDEALL ent for this update. (often are). - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( -1 ); - - // !!!BUGBUG -- This needs to be time based - gTempEntFrame = (gTempEntFrame+1) & 31; - - pTemp = *ppTempEntActive; - - // !!! Don't simulate while paused.... This is sort of a hack, revisit. - if ( frametime <= 0 ) - { - while ( pTemp ) - { - if ( !(pTemp->flags & FTENT_NOMODEL ) ) - { - Callback_AddVisibleEntity( &pTemp->entity ); - } - pTemp = pTemp->next; - } - goto finish; - } - - pprev = NULL; - freq = client_time * 0.01; - fastFreq = client_time * 5.5; - gravity = -frametime * cl_gravity; - gravitySlow = gravity * 0.5; - - while ( pTemp ) - { - int active; - - active = 1; - - life = pTemp->die - client_time; - pnext = pTemp->next; - if ( life < 0 ) - { - if ( pTemp->flags & FTENT_FADEOUT ) - { - if (pTemp->entity.curstate.rendermode == kRenderNormal) - pTemp->entity.curstate.rendermode = kRenderTransTexture; - pTemp->entity.curstate.renderamt = pTemp->entity.baseline.renderamt * ( 1 + life * pTemp->fadeSpeed ); - if ( pTemp->entity.curstate.renderamt <= 0 ) - active = 0; - - } - else - active = 0; - } - if ( !active ) // Kill it - { - pTemp->next = *ppTempEntFree; - *ppTempEntFree = pTemp; - if ( !pprev ) // Deleting at head of list - *ppTempEntActive = pnext; - else - pprev->next = pnext; - } - else - { - pprev = pTemp; - - VectorCopy( pTemp->entity.origin, pTemp->entity.prevstate.origin ); - - if ( pTemp->flags & FTENT_SPARKSHOWER ) - { - // Adjust speed if it's time - // Scale is next think time - if ( client_time > pTemp->entity.baseline.scale ) - { - // Show Sparks - gEngfuncs.pEfxAPI->R_SparkEffect( pTemp->entity.origin, 8, -200, 200 ); - - // Reduce life - pTemp->entity.baseline.framerate -= 0.1; - - if ( pTemp->entity.baseline.framerate <= 0.0 ) - { - pTemp->die = client_time; - } - else - { - // So it will die no matter what - pTemp->die = client_time + 0.5; - - // Next think - pTemp->entity.baseline.scale = client_time + 0.1; - } - } - } - else if ( pTemp->flags & FTENT_PLYRATTACHMENT ) - { - cl_entity_t *pClient; - - pClient = gEngfuncs.GetEntityByIndex( pTemp->clientIndex ); - - VectorAdd( pClient->origin, pTemp->tentOffset, pTemp->entity.origin ); - } - else if ( pTemp->flags & FTENT_SINEWAVE ) - { - pTemp->x += pTemp->entity.baseline.origin[0] * frametime; - pTemp->y += pTemp->entity.baseline.origin[1] * frametime; - - pTemp->entity.origin[0] = pTemp->x + sin( pTemp->entity.baseline.origin[2] + client_time * pTemp->entity.prevstate.frame ) * (10*pTemp->entity.curstate.framerate); - pTemp->entity.origin[1] = pTemp->y + sin( pTemp->entity.baseline.origin[2] + fastFreq + 0.7 ) * (8*pTemp->entity.curstate.framerate); - pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime; - } - else if ( pTemp->flags & FTENT_SPIRAL ) - { - float s, c; - s = sin( pTemp->entity.baseline.origin[2] + fastFreq ); - c = cos( pTemp->entity.baseline.origin[2] + fastFreq ); - - pTemp->entity.origin[0] += pTemp->entity.baseline.origin[0] * frametime + 8 * sin( client_time * 20 + (int)pTemp ); - pTemp->entity.origin[1] += pTemp->entity.baseline.origin[1] * frametime + 4 * sin( client_time * 30 + (int)pTemp ); - pTemp->entity.origin[2] += pTemp->entity.baseline.origin[2] * frametime; - } - else - { - for ( i = 0; i < 3; i++ ) - pTemp->entity.origin[i] += pTemp->entity.baseline.origin[i] * frametime; - } - - if ( pTemp->flags & FTENT_SPRANIMATE ) - { - pTemp->entity.curstate.frame += frametime * pTemp->entity.curstate.framerate; - if ( pTemp->entity.curstate.frame >= pTemp->frameMax ) - { - pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame); - - if ( !(pTemp->flags & FTENT_SPRANIMATELOOP) ) - { - // this animating sprite isn't set to loop, so destroy it. - pTemp->die = client_time; - pTemp = pnext; - continue; - } - } - } - else if ( pTemp->flags & FTENT_SPRCYCLE ) - { - pTemp->entity.curstate.frame += frametime * 10; - if ( pTemp->entity.curstate.frame >= pTemp->frameMax ) - { - pTemp->entity.curstate.frame = pTemp->entity.curstate.frame - (int)(pTemp->entity.curstate.frame); - } - } -// Experiment -#if 0 - if ( pTemp->flags & FTENT_SCALE ) - pTemp->entity.curstate.framerate += 20.0 * (frametime / pTemp->entity.curstate.framerate); -#endif - - if ( pTemp->flags & FTENT_ROTATE ) - { - pTemp->entity.angles[0] += pTemp->entity.baseline.angles[0] * frametime; - pTemp->entity.angles[1] += pTemp->entity.baseline.angles[1] * frametime; - pTemp->entity.angles[2] += pTemp->entity.baseline.angles[2] * frametime; - - VectorCopy( pTemp->entity.angles, pTemp->entity.latched.prevangles ); - } - - if ( pTemp->flags & (FTENT_COLLIDEALL | FTENT_COLLIDEWORLD) ) - { - vec3_t traceNormal; - float traceFraction = 1; - - if ( pTemp->flags & FTENT_COLLIDEALL ) - { - pmtrace_t pmtrace; - physent_t *pe; - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - - gEngfuncs.pEventAPI->EV_PlayerTrace( pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX, -1, &pmtrace ); - - - if ( pmtrace.fraction != 1 ) - { - pe = gEngfuncs.pEventAPI->EV_GetPhysent( pmtrace.ent ); - - if ( !pmtrace.ent || ( pe->info != pTemp->clientIndex ) ) - { - traceFraction = pmtrace.fraction; - VectorCopy( pmtrace.plane.normal, traceNormal ); - - if ( pTemp->hitcallback ) - { - (*pTemp->hitcallback)( pTemp, &pmtrace ); - } - } - } - } - else if ( pTemp->flags & FTENT_COLLIDEWORLD ) - { - pmtrace_t pmtrace; - - gEngfuncs.pEventAPI->EV_SetTraceHull( 2 ); - - gEngfuncs.pEventAPI->EV_PlayerTrace( pTemp->entity.prevstate.origin, pTemp->entity.origin, PM_STUDIO_BOX | PM_WORLD_ONLY, -1, &pmtrace ); - - if ( pmtrace.fraction != 1 ) - { - traceFraction = pmtrace.fraction; - VectorCopy( pmtrace.plane.normal, traceNormal ); - - if ( pTemp->flags & FTENT_SPARKSHOWER ) - { - // Chop spark speeds a bit more - // - VectorScale( pTemp->entity.baseline.origin, 0.6, pTemp->entity.baseline.origin ); - - if ( Length( pTemp->entity.baseline.origin ) < 10 ) - { - pTemp->entity.baseline.framerate = 0.0; - } - } - - if ( pTemp->hitcallback ) - { - (*pTemp->hitcallback)( pTemp, &pmtrace ); - } - } - } - - if ( traceFraction != 1 ) // Decent collision now, and damping works - { - float proj, damp; - - // Place at contact point - VectorMA( pTemp->entity.prevstate.origin, traceFraction*frametime, pTemp->entity.baseline.origin, pTemp->entity.origin ); - // Damp velocity - damp = pTemp->bounceFactor; - if ( pTemp->flags & (FTENT_GRAVITY|FTENT_SLOWGRAVITY) ) - { - damp *= 0.5; - if ( traceNormal[2] > 0.9 ) // Hit floor? - { - if ( pTemp->entity.baseline.origin[2] <= 0 && pTemp->entity.baseline.origin[2] >= gravity*3 ) - { - damp = 0; // Stop - pTemp->flags &= ~(FTENT_ROTATE|FTENT_GRAVITY|FTENT_SLOWGRAVITY|FTENT_COLLIDEWORLD|FTENT_SMOKETRAIL); - pTemp->entity.angles[0] = 0; - pTemp->entity.angles[2] = 0; - } - } - } - - if (pTemp->hitSound) - { - Callback_TempEntPlaySound(pTemp, damp); - } - - if (pTemp->flags & FTENT_COLLIDEKILL) - { - // die on impact - pTemp->flags &= ~FTENT_FADEOUT; - pTemp->die = client_time; - } - else - { - // Reflect velocity - if ( damp != 0 ) - { - proj = DotProduct( pTemp->entity.baseline.origin, traceNormal ); - VectorMA( pTemp->entity.baseline.origin, -proj*2, traceNormal, pTemp->entity.baseline.origin ); - // Reflect rotation (fake) - - pTemp->entity.angles[1] = -pTemp->entity.angles[1]; - } - - if ( damp != 1 ) - { - - VectorScale( pTemp->entity.baseline.origin, damp, pTemp->entity.baseline.origin ); - VectorScale( pTemp->entity.angles, 0.9, pTemp->entity.angles ); - } - } - } - } - - - if ( (pTemp->flags & FTENT_FLICKER) && gTempEntFrame == pTemp->entity.curstate.effects ) - { - dlight_t *dl = gEngfuncs.pEfxAPI->CL_AllocDlight (0); - VectorCopy (pTemp->entity.origin, dl->origin); - dl->radius = 60; - dl->color.r = 255; - dl->color.g = 120; - dl->color.b = 0; - dl->die = client_time + 0.01; - } - - if ( pTemp->flags & FTENT_SMOKETRAIL ) - { - gEngfuncs.pEfxAPI->R_RocketTrail (pTemp->entity.prevstate.origin, pTemp->entity.origin, 1); - } - - if ( pTemp->flags & FTENT_GRAVITY ) - pTemp->entity.baseline.origin[2] += gravity; - else if ( pTemp->flags & FTENT_SLOWGRAVITY ) - pTemp->entity.baseline.origin[2] += gravitySlow; - - if ( pTemp->flags & FTENT_CLIENTCUSTOM ) - { - if ( pTemp->callback ) - { - ( *pTemp->callback )( pTemp, frametime, client_time ); - } - } - - // Cull to PVS (not frustum cull, just PVS) - if ( !(pTemp->flags & FTENT_NOMODEL ) ) - { - if ( !Callback_AddVisibleEntity( &pTemp->entity ) ) - { - if ( !(pTemp->flags & FTENT_PERSIST) ) - { - pTemp->die = client_time; // If we can't draw it this frame, just dump it. - pTemp->flags &= ~FTENT_FADEOUT; // Don't fade out, just die - } - } - } - } - pTemp = pnext; - } - -finish: - // Restore state info - gEngfuncs.pEventAPI->EV_PopPMStates(); -} - -/* -================= -HUD_GetUserEntity - -If you specify negative numbers for beam start and end point entities, then - the engine will call back into this function requesting a pointer to a cl_entity_t - object that describes the entity to attach the beam onto. - -Indices must start at 1, not zero. -================= -*/ -cl_entity_t DLLEXPORT *HUD_GetUserEntity( int index ) -{ -return NULL; -} diff --git a/ricochet/cl_dll/ev_common.cpp b/ricochet/cl_dll/ev_common.cpp deleted file mode 100644 index 2d2e37e..0000000 --- a/ricochet/cl_dll/ev_common.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// shared event functions -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" - -#include "r_efx.h" - -#include "eventscripts.h" -#include "event_api.h" - -/* -================= -GetEntity - -Return's the requested cl_entity_t -================= -*/ -struct cl_entity_s *GetEntity( int idx ) -{ - return gEngfuncs.GetEntityByIndex( idx ); -} - -/* -================= -GetViewEntity - -Return's the current weapon/view model -================= -*/ -struct cl_entity_s *GetViewEntity( void ) -{ - return gEngfuncs.GetViewModel(); -} - -/* -================= -EV_CreateTracer - -Creates a tracer effect -================= -*/ -void EV_CreateTracer( float *start, float *end ) -{ - gEngfuncs.pEfxAPI->R_TracerEffect( start, end ); -} - -/* -================= -EV_IsPlayer - -Is the entity's index in the player range? -================= -*/ -qboolean EV_IsPlayer( int idx ) -{ - if ( idx >= 1 && idx <= gEngfuncs.GetMaxClients() ) - return true; - - return false; -} - -/* -================= -EV_IsLocal - -Is the entity == the local player -================= -*/ -qboolean EV_IsLocal( int idx ) -{ - return gEngfuncs.pEventAPI->EV_IsLocal( idx - 1 ) ? true : false; -} - -/* -================= -EV_GetGunPosition - -Figure out the height of the gun -================= -*/ -void EV_GetGunPosition( event_args_t *args, float *pos, float *origin ) -{ - int idx; - vec3_t view_ofs; - - idx = args->entindex; - - VectorClear( view_ofs ); - view_ofs[2] = DEFAULT_VIEWHEIGHT; - - if ( EV_IsPlayer( idx ) ) - { - if ( EV_IsLocal( idx ) ) - { - // Grab predicted result for local player - gEngfuncs.pEventAPI->EV_LocalPlayerViewheight( view_ofs ); - } - else if ( args->ducking == 1 ) - { - view_ofs[2] = VEC_DUCK_VIEW; - } - } - - VectorAdd( origin, view_ofs, pos ); -} - -/* -================= -EV_EjectBrass - -Bullet shell casings -================= -*/ -void EV_EjectBrass( float *origin, float *velocity, float rotation, int model, int soundtype ) -{ - vec3_t endpos; - VectorClear( endpos ); - endpos[1] = rotation; - gEngfuncs.pEfxAPI->R_TempModel( origin, velocity, endpos, 2.5, model, soundtype ); -} - -/* -================= -EV_GetDefaultShellInfo - -Determine where to eject shells from -================= -*/ -void EV_GetDefaultShellInfo( event_args_t *args, float *origin, float *velocity, float *ShellVelocity, float *ShellOrigin, float *forward, float *right, float *up, float forwardScale, float upScale, float rightScale ) -{ - int i; - vec3_t view_ofs; - float fR, fU; - - int idx; - - idx = args->entindex; - - VectorClear( view_ofs ); - view_ofs[2] = DEFAULT_VIEWHEIGHT; - - if ( EV_IsPlayer( idx ) ) - { - if ( EV_IsLocal( idx ) ) - { - gEngfuncs.pEventAPI->EV_LocalPlayerViewheight( view_ofs ); - } - else if ( args->ducking == 1 ) - { - view_ofs[2] = VEC_DUCK_VIEW; - } - } - - fR = gEngfuncs.pfnRandomFloat( 50, 70 ); - fU = gEngfuncs.pfnRandomFloat( 100, 150 ); - - for ( i = 0; i < 3; i++ ) - { - ShellVelocity[i] = velocity[i] + right[i] * fR + up[i] * fU + forward[i] * 25; - ShellOrigin[i] = origin[i] + view_ofs[i] + up[i] * upScale + forward[i] * forwardScale + right[i] * rightScale; - } -} - -/* -================= -EV_MuzzleFlash - -Flag weapon/view model for muzzle flash -================= -*/ -void EV_MuzzleFlash( void ) -{ - // Add muzzle flash to current weapon model - cl_entity_t *ent = GetViewEntity(); - if ( !ent ) - { - return; - } - - // Or in the muzzle flash - ent->curstate.effects |= EF_MUZZLEFLASH; -} \ No newline at end of file diff --git a/ricochet/cl_dll/ev_hldm.cpp b/ricochet/cl_dll/ev_hldm.cpp deleted file mode 100644 index 11dbf66..0000000 --- a/ricochet/cl_dll/ev_hldm.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/*** -* -* Copyright (c) 1999, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "entity_types.h" -#include "usercmd.h" -#include "pm_defs.h" -#include "pm_materials.h" - -#include "eventscripts.h" -#include "ev_hldm.h" - -#include "r_efx.h" -#include "event_api.h" -#include "event_args.h" -#include "in_defs.h" - -#include - -extern "C" -{ -// RICOCHET -void EV_FireDisc( struct event_args_s *args ); -void EV_TriggerJump( struct event_args_s *args ); -void EV_TrainPitchAdjust( struct event_args_s *args ); -} - -/* -============================== -EV_TriggerJump - -Plays the jump pad sound -============================== -*/ -void EV_TriggerJump( event_args_t *args ) -{ - int idx; - idx = args->entindex; - vec3_t origin; - - VectorCopy( args->origin, origin ); - - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_AUTO, "triggerjump.wav", 1.0, ATTN_NORM, 0, 98 + gEngfuncs.pfnRandomLong( 0, 3 ) ); -} - -/* -============================== -EV_FireDisc - -Play's disc firing animation and play's appropriate sound effect -============================== -*/ -void EV_FireDisc( event_args_t *args ) -{ - int idx; - - idx = args->entindex; - vec3_t origin; - int decap; - - VectorCopy( args->origin, origin ); - decap = args->bparam1 ? 1 : 0; - - if ( EV_IsLocal( idx ) ) - { - // Add muzzle flash to current weapon model - gEngfuncs.pEventAPI->EV_WeaponAnimation( DISC_THROW1, 2 ); - } - - if ( decap ) - { - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/altfire.wav", 0.8, ATTN_NORM, 0, 100 ); - } - else - { - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_WEAPON, "weapons/cbar_miss1.wav", 0.8, ATTN_NORM, 0, 100 ); - } -} - -#define SND_CHANGE_PITCH (1<<7) - -/* -============================== -EV_TrainPitchAdjust - -Do we support trains in Ricochet? -============================== -*/ -void EV_TrainPitchAdjust( event_args_t *args ) -{ - int idx; - vec3_t origin; - - unsigned short us_params; - int noise; - float m_flVolume; - int pitch; - int stop; - - char sz[ 256 ]; - - idx = args->entindex; - - VectorCopy( args->origin, origin ); - - us_params = (unsigned short)args->iparam1; - stop = args->bparam1; - - m_flVolume = (float)(us_params & 0x003f)/40.0; - noise = (int)(((us_params) >> 12 ) & 0x0007); - pitch = (int)( 10.0 * (float)( ( us_params >> 6 ) & 0x003f ) ); - - switch ( noise ) - { - case 1: strcpy( sz, "plats/ttrain1.wav"); break; - case 2: strcpy( sz, "plats/ttrain2.wav"); break; - case 3: strcpy( sz, "plats/ttrain3.wav"); break; - case 4: strcpy( sz, "plats/ttrain4.wav"); break; - case 5: strcpy( sz, "plats/ttrain6.wav"); break; - case 6: strcpy( sz, "plats/ttrain7.wav"); break; - default: - // no sound - strcpy( sz, "" ); - return; - } - - if ( stop ) - { - gEngfuncs.pEventAPI->EV_StopSound( idx, CHAN_STATIC, sz ); - } - else - { - gEngfuncs.pEventAPI->EV_PlaySound( idx, origin, CHAN_STATIC, sz, m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, pitch ); - } -} diff --git a/ricochet/cl_dll/ev_hldm.h b/ricochet/cl_dll/ev_hldm.h deleted file mode 100644 index 8d3aec7..0000000 --- a/ricochet/cl_dll/ev_hldm.h +++ /dev/null @@ -1,16 +0,0 @@ -#if !defined ( EV_HLDMH ) -#define EV_HLDMH - -enum disc_e -{ - DISC_IDLE = 0, - DISC_FIDGET, - DISC_PINPULL, - DISC_THROW1, // toss - DISC_THROW2, // medium - DISC_THROW3, // hard - DISC_HOLSTER, - DISC_DRAW -}; - -#endif // EV_HLDMH \ No newline at end of file diff --git a/ricochet/cl_dll/events.cpp b/ricochet/cl_dll/events.cpp deleted file mode 100644 index 04c8f57..0000000 --- a/ricochet/cl_dll/events.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "hud.h" -#include "cl_util.h" - -void Game_HookEvents( void ); - -/* -=================== -EV_HookEvents - -See if game specific code wants to hook any events. -=================== -*/ -void EV_HookEvents( void ) -{ - Game_HookEvents(); -} \ No newline at end of file diff --git a/ricochet/cl_dll/eventscripts.h b/ricochet/cl_dll/eventscripts.h deleted file mode 100644 index 0ac3251..0000000 --- a/ricochet/cl_dll/eventscripts.h +++ /dev/null @@ -1,80 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// eventscripts.h -#if !defined ( EVENTSCRIPTSH ) -#define EVENTSCRIPTSH - -// defaults for clientinfo messages -#define DEFAULT_VIEWHEIGHT 28 -#define VEC_DUCK_VIEW 12 - -#define FTENT_FADEOUT 0x00000080 - -#define DMG_GENERIC 0 // generic damage was done -#define DMG_CRUSH (1 << 0) // crushed by falling or moving object -#define DMG_BULLET (1 << 1) // shot -#define DMG_SLASH (1 << 2) // cut, clawed, stabbed -#define DMG_BURN (1 << 3) // heat burned -#define DMG_FREEZE (1 << 4) // frozen -#define DMG_FALL (1 << 5) // fell too far -#define DMG_BLAST (1 << 6) // explosive blast damage -#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt -#define DMG_SHOCK (1 << 8) // electric shock -#define DMG_SONIC (1 << 9) // sound pulse shockwave -#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam -#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death -#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death. - -// time-based damage -//mask off TF-specific stuff too -#define DMG_TIMEBASED (~(0xff003fff)) // mask for time-based damage - -#define DMG_DROWN (1 << 14) // Drowning -#define DMG_FIRSTTIMEBASED DMG_DROWN - -#define DMG_PARALYZE (1 << 15) // slows affected creature down -#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad -#define DMG_POISON (1 << 17) // blood poisioning -#define DMG_RADIATION (1 << 18) // radiation exposure -#define DMG_DROWNRECOVER (1 << 19) // drowning recovery -#define DMG_ACID (1 << 20) // toxic chemicals or acid burns -#define DMG_SLOWBURN (1 << 21) // in an oven -#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer -#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar) - -//TF ADDITIONS -#define DMG_IGNITE (1 << 24) // Players hit by this begin to burn -#define DMG_RADIUS_MAX (1 << 25) // Radius damage with this flag doesn't decrease over distance -#define DMG_RADIUS_QUAKE (1 << 26) // Radius damage is done like Quake. 1/2 damage at 1/2 radius. -#define DMG_IGNOREARMOR (1 << 27) // Damage ignores target's armor -#define DMG_AIMED (1 << 28) // Does Hit location damage -#define DMG_WALLPIERCING (1 << 29) // Blast Damages ents through walls - -#define DMG_CALTROP (1<<30) -#define DMG_HALLUC (1<<31) - -// Some of these are HL/TFC specific? -void EV_EjectBrass( float *origin, float *velocity, float rotation, int model, int soundtype ); -void EV_GetGunPosition( struct event_args_s *args, float *pos, float *origin ); -void EV_GetDefaultShellInfo( struct event_args_s *args, float *origin, float *velocity, float *ShellVelocity, float *ShellOrigin, float *forward, float *right, float *up, float forwardScale, float upScale, float rightScale ); -qboolean EV_IsLocal( int idx ); -qboolean EV_IsPlayer( int idx ); -void EV_CreateTracer( float *start, float *end ); - -struct cl_entity_s *GetEntity( int idx ); -struct cl_entity_s *GetViewEntity( void ); -void EV_MuzzleFlash( void ); - -#endif // EVENTSCRIPTSH diff --git a/ricochet/cl_dll/flashlight.cpp b/ricochet/cl_dll/flashlight.cpp deleted file mode 100644 index 48a73f4..0000000 --- a/ricochet/cl_dll/flashlight.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// flashlight.cpp -// -// implementation of CHudFlashlight class -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - - - -DECLARE_MESSAGE(m_Flash, FlashBat) -DECLARE_MESSAGE(m_Flash, Flashlight) - -#define BAT_NAME "sprites/%d_Flashlight.spr" - -int CHudFlashlight::Init(void) -{ - m_fFade = 0; - m_fOn = 0; - - HOOK_MESSAGE(Flashlight); - HOOK_MESSAGE(FlashBat); - - m_iFlags |= HUD_ACTIVE; - - gHUD.AddHudElem(this); - - return 1; -}; - -void CHudFlashlight::Reset(void) -{ - m_fFade = 0; - m_fOn = 0; -} - -int CHudFlashlight::VidInit(void) -{ - int HUD_flash_empty = gHUD.GetSpriteIndex( "flash_empty" ); - int HUD_flash_full = gHUD.GetSpriteIndex( "flash_full" ); - int HUD_flash_beam = gHUD.GetSpriteIndex( "flash_beam" ); - - m_hSprite1 = gHUD.GetSprite(HUD_flash_empty); - m_hSprite2 = gHUD.GetSprite(HUD_flash_full); - m_hBeam = gHUD.GetSprite(HUD_flash_beam); - m_prc1 = &gHUD.GetSpriteRect(HUD_flash_empty); - m_prc2 = &gHUD.GetSpriteRect(HUD_flash_full); - m_prcBeam = &gHUD.GetSpriteRect(HUD_flash_beam); - m_iWidth = m_prc2->right - m_prc2->left; - - return 1; -}; - -int CHudFlashlight:: MsgFunc_FlashBat(const char *pszName, int iSize, void *pbuf ) -{ - - - BEGIN_READ( pbuf, iSize ); - int x = READ_BYTE(); - m_iBat = x; - m_flBat = ((float)x)/100.0; - - return 1; -} - -int CHudFlashlight:: MsgFunc_Flashlight(const char *pszName, int iSize, void *pbuf ) -{ - - BEGIN_READ( pbuf, iSize ); - m_fOn = READ_BYTE(); - int x = READ_BYTE(); - m_iBat = x; - m_flBat = ((float)x)/100.0; - - return 1; -} - -int CHudFlashlight::Draw(float flTime) -{ - return 1; -} \ No newline at end of file diff --git a/ricochet/cl_dll/geiger.cpp b/ricochet/cl_dll/geiger.cpp deleted file mode 100644 index 7087e59..0000000 --- a/ricochet/cl_dll/geiger.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// Geiger.cpp -// -// implementation of CHudAmmo class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include - -#include "parsemsg.h" - -DECLARE_MESSAGE(m_Geiger, Geiger ) - -int CHudGeiger::Init(void) -{ - HOOK_MESSAGE( Geiger ); - - m_iGeigerRange = 0; - m_iFlags = 0; - - gHUD.AddHudElem(this); - - srand( (unsigned)time( NULL ) ); - - return 1; -}; - -int CHudGeiger::VidInit(void) -{ - return 1; -}; - -int CHudGeiger::MsgFunc_Geiger(const char *pszName, int iSize, void *pbuf) -{ - - BEGIN_READ( pbuf, iSize ); - - // update geiger data - m_iGeigerRange = READ_BYTE(); - m_iGeigerRange = m_iGeigerRange << 2; - - m_iFlags |= HUD_ACTIVE; - - return 1; -} - -int CHudGeiger::Draw (float flTime) -{ - int pct; - float flvol; - int rg[3]; - int i; - - if (m_iGeigerRange <= 800 && m_iGeigerRange > 0) - { - // peicewise linear is better than continuous formula for this - if (m_iGeigerRange > 600) - { - pct = 2; - flvol = 0.4; //Con_Printf ( "range > 600\n"); - rg[0] = 1; - rg[1] = 1; - i = 2; - } - else if (m_iGeigerRange > 500) - { - pct = 4; - flvol = 0.5; //Con_Printf ( "range > 500\n"); - rg[0] = 1; - rg[1] = 2; - i = 2; - } - else if (m_iGeigerRange > 400) - { - pct = 8; - flvol = 0.6; //Con_Printf ( "range > 400\n"); - rg[0] = 1; - rg[1] = 2; - rg[2] = 3; - i = 3; - } - else if (m_iGeigerRange > 300) - { - pct = 8; - flvol = 0.7; //Con_Printf ( "range > 300\n"); - rg[0] = 2; - rg[1] = 3; - rg[2] = 4; - i = 3; - } - else if (m_iGeigerRange > 200) - { - pct = 28; - flvol = 0.78; //Con_Printf ( "range > 200\n"); - rg[0] = 2; - rg[1] = 3; - rg[2] = 4; - i = 3; - } - else if (m_iGeigerRange > 150) - { - pct = 40; - flvol = 0.80; //Con_Printf ( "range > 150\n"); - rg[0] = 3; - rg[1] = 4; - rg[2] = 5; - i = 3; - } - else if (m_iGeigerRange > 100) - { - pct = 60; - flvol = 0.85; //Con_Printf ( "range > 100\n"); - rg[0] = 3; - rg[1] = 4; - rg[2] = 5; - i = 3; - } - else if (m_iGeigerRange > 75) - { - pct = 80; - flvol = 0.9; //Con_Printf ( "range > 75\n"); - //gflGeigerDelay = cl.time + GEIGERDELAY * 0.75; - rg[0] = 4; - rg[1] = 5; - rg[2] = 6; - i = 3; - } - else if (m_iGeigerRange > 50) - { - pct = 90; - flvol = 0.95; //Con_Printf ( "range > 50\n"); - rg[0] = 5; - rg[1] = 6; - i = 2; - } - else - { - pct = 95; - flvol = 1.0; //Con_Printf ( "range < 50\n"); - rg[0] = 5; - rg[1] = 6; - i = 2; - } - - flvol = (flvol * ((rand() & 127)) / 255) + 0.25; // UTIL_RandomFloat(0.25, 0.5); - - if ((rand() & 127) < pct || (rand() & 127) < pct) - { - //S_StartDynamicSound (-1, 0, rgsfx[rand() % i], r_origin, flvol, 1.0, 0, 100); - char sz[256]; - - int j = rand() & 1; - if (i > 2) - j += rand() & 1; - - sprintf(sz, "player/geiger%d.wav", j + 1); - PlaySound(sz, flvol); - - } - } - - return 1; -} diff --git a/ricochet/cl_dll/health.cpp b/ricochet/cl_dll/health.cpp deleted file mode 100644 index 593ed89..0000000 --- a/ricochet/cl_dll/health.cpp +++ /dev/null @@ -1,425 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// -// Health.cpp -// -// implementation of CHudHealth class -// - -#include "stdio.h" -#include "stdlib.h" -#include "math.h" - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" -#include "vgui_TeamFortressViewport.h" -#include - - -DECLARE_MESSAGE(m_Health, Health ) -DECLARE_MESSAGE(m_Health, Damage ) - -#define PAIN_NAME "sprites/%d_pain.spr" -#define DAMAGE_NAME "sprites/%d_dmg.spr" - -int giDmgHeight, giDmgWidth; - -int giDmgFlags[NUM_DMG_TYPES] = -{ - DMG_POISON, - DMG_ACID, - DMG_FREEZE|DMG_SLOWFREEZE, - DMG_DROWN, - DMG_BURN|DMG_SLOWBURN, - DMG_NERVEGAS, - DMG_RADIATION, - DMG_SHOCK, - DMG_CALTROP, - DMG_TRANQ, - DMG_CONCUSS, - DMG_HALLUC -}; - -int CHudHealth::Init(void) -{ - HOOK_MESSAGE(Health); - HOOK_MESSAGE(Damage); - m_iHealth = 100; - m_fFade = 0; - m_iFlags = 0; - m_bitsDamage = 0; - m_fAttackFront = m_fAttackRear = m_fAttackRight = m_fAttackLeft = 0; - giDmgHeight = 0; - giDmgWidth = 0; - - memset(m_dmg, 0, sizeof(DAMAGE_IMAGE) * NUM_DMG_TYPES); - - - gHUD.AddHudElem(this); - return 1; -} - -void CHudHealth::Reset( void ) -{ - // make sure the pain compass is cleared when the player respawns - m_fAttackFront = m_fAttackRear = m_fAttackRight = m_fAttackLeft = 0; - - - // force all the flashing damage icons to expire - m_bitsDamage = 0; - for ( int i = 0; i < NUM_DMG_TYPES; i++ ) - { - m_dmg[i].fExpire = 0; - } -} - -int CHudHealth::VidInit(void) -{ - m_hSprite = 0; - - m_HUD_dmg_bio = gHUD.GetSpriteIndex( "dmg_bio" ) + 1; - m_HUD_cross = gHUD.GetSpriteIndex( "cross" ); - - giDmgHeight = gHUD.GetSpriteRect(m_HUD_dmg_bio).right - gHUD.GetSpriteRect(m_HUD_dmg_bio).left; - giDmgWidth = gHUD.GetSpriteRect(m_HUD_dmg_bio).bottom - gHUD.GetSpriteRect(m_HUD_dmg_bio).top; - return 1; -} - -int CHudHealth:: MsgFunc_Health(const char *pszName, int iSize, void *pbuf ) -{ - // TODO: update local health data - BEGIN_READ( pbuf, iSize ); - int x = READ_BYTE(); - - m_iFlags |= HUD_ACTIVE; - - // Only update the fade if we've changed health - if (x != m_iHealth) - { - m_fFade = FADE_TIME; - m_iHealth = x; - } - - return 1; -} - - -int CHudHealth:: MsgFunc_Damage(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int armor = READ_BYTE(); // armor - int damageTaken = READ_BYTE(); // health - long bitsDamage = READ_LONG(); // damage bits - - vec3_t vecFrom; - - for ( int i = 0 ; i < 3 ; i++) - vecFrom[i] = READ_COORD(); - - UpdateTiles(gHUD.m_flTime, bitsDamage); - - // Actually took damage? - if ( damageTaken > 0 || armor > 0 ) - CalcDamageDirection(vecFrom); - - return 1; -} - - -// Returns back a color from the -// Green <-> Yellow <-> Red ramp -void CHudHealth::GetPainColor( int &r, int &g, int &b ) -{ - int iHealth = m_iHealth; - - if (iHealth > 25) - iHealth -= 25; - else if ( iHealth < 0 ) - iHealth = 0; -#if 0 - g = iHealth * 255 / 100; - r = 255 - g; - b = 0; -#else - if (m_iHealth > 25) - { - UnpackRGB(r,g,b, RGB_YELLOWISH); - } - else - { - r = 250; - g = 0; - b = 0; - } -#endif -} - -int CHudHealth::Draw(float flTime) -{ - // No Health in Discwar - if ( gHUD.m_iHideHUDDisplay & HIDEHUD_HEALTH ) - return 1; - - if ( !m_hSprite ) - m_hSprite = LoadSprite(PAIN_NAME); - - return DrawDamage(flTime); -} - -void CHudHealth::CalcDamageDirection(vec3_t vecFrom) -{ - vec3_t forward, right, up; - float side, front; - vec3_t vecOrigin, vecAngles; - - if (!vecFrom[0] && !vecFrom[1] && !vecFrom[2]) - { - m_fAttackFront = m_fAttackRear = m_fAttackRight = m_fAttackLeft = 0; - return; - } - - - memcpy(vecOrigin, gHUD.m_vecOrigin, sizeof(vec3_t)); - memcpy(vecAngles, gHUD.m_vecAngles, sizeof(vec3_t)); - - - VectorSubtract (vecFrom, vecOrigin, vecFrom); - - float flDistToTarget = vecFrom.Length(); - - vecFrom = vecFrom.Normalize(); - AngleVectors (vecAngles, forward, right, up); - - front = DotProduct (vecFrom, right); - side = DotProduct (vecFrom, forward); - - if (flDistToTarget <= 50) - { - m_fAttackFront = m_fAttackRear = m_fAttackRight = m_fAttackLeft = 1; - } - else - { - if (side > 0) - { - if (side > 0.3) - m_fAttackFront = V_max(m_fAttackFront, side); - } - else - { - float f = fabs(side); - if (f > 0.3) - m_fAttackRear = V_max(m_fAttackRear, f); - } - - if (front > 0) - { - if (front > 0.3) - m_fAttackRight = V_max(m_fAttackRight, front); - } - else - { - float f = fabs(front); - if (f > 0.3) - m_fAttackLeft = V_max(m_fAttackLeft, f); - } - } -} - -int CHudHealth::DrawPain(float flTime) -{ - if (!(m_fAttackFront || m_fAttackRear || m_fAttackLeft || m_fAttackRight)) - return 1; - - int r, g, b; - int x, y, a, shade; - - // TODO: get the shift value of the health - a = 255; // max brightness until then - - float fFade = gHUD.m_flTimeDelta * 2; - - // SPR_Draw top - if (m_fAttackFront > 0.4) - { - GetPainColor(r,g,b); - shade = a * V_max( m_fAttackFront, 0.5 ); - ScaleColors(r, g, b, shade); - SPR_Set(m_hSprite, r, g, b ); - - x = ScreenWidth/2 - SPR_Width(m_hSprite, 0)/2; - y = ScreenHeight/2 - SPR_Height(m_hSprite,0) * 3; - SPR_DrawAdditive(0, x, y, NULL); - m_fAttackFront = V_max( 0, m_fAttackFront - fFade ); - } else - m_fAttackFront = 0; - - if (m_fAttackRight > 0.4) - { - GetPainColor(r,g,b); - shade = a * V_max( m_fAttackRight, 0.5 ); - ScaleColors(r, g, b, shade); - SPR_Set(m_hSprite, r, g, b ); - - x = ScreenWidth/2 + SPR_Width(m_hSprite, 1) * 2; - y = ScreenHeight/2 - SPR_Height(m_hSprite,1)/2; - SPR_DrawAdditive(1, x, y, NULL); - m_fAttackRight = V_max( 0, m_fAttackRight - fFade ); - } else - m_fAttackRight = 0; - - if (m_fAttackRear > 0.4) - { - GetPainColor(r,g,b); - shade = a * V_max( m_fAttackRear, 0.5 ); - ScaleColors(r, g, b, shade); - SPR_Set(m_hSprite, r, g, b ); - - x = ScreenWidth/2 - SPR_Width(m_hSprite, 2)/2; - y = ScreenHeight/2 + SPR_Height(m_hSprite,2) * 2; - SPR_DrawAdditive(2, x, y, NULL); - m_fAttackRear = V_max( 0, m_fAttackRear - fFade ); - } else - m_fAttackRear = 0; - - if (m_fAttackLeft > 0.4) - { - GetPainColor(r,g,b); - shade = a * V_max( m_fAttackLeft, 0.5 ); - ScaleColors(r, g, b, shade); - SPR_Set(m_hSprite, r, g, b ); - - x = ScreenWidth/2 - SPR_Width(m_hSprite, 3) * 3; - y = ScreenHeight/2 - SPR_Height(m_hSprite,3)/2; - SPR_DrawAdditive(3, x, y, NULL); - - m_fAttackLeft = V_max( 0, m_fAttackLeft - fFade ); - } else - m_fAttackLeft = 0; - - return 1; -} - -int CHudHealth::DrawDamage(float flTime) -{ - int r, g, b, a; - DAMAGE_IMAGE *pdmg; - - if (!m_bitsDamage) - return 1; - - UnpackRGB(r,g,b, RGB_YELLOWISH); - - a = (int)( fabs(sin(flTime*2)) * 256.0); - - ScaleColors(r, g, b, a); - - // Draw all the items - for (int i = 0; i < NUM_DMG_TYPES; i++) - { - if (m_bitsDamage & giDmgFlags[i]) - { - pdmg = &m_dmg[i]; - SPR_Set(gHUD.GetSprite(m_HUD_dmg_bio + i), r, g, b ); - - // Discwar: Hack. Freeze is the only icon we use. Just place it directly above the disc ammo - int iX = (ScreenWidth - DISC_ICON_WIDTH) / 2; - int iXPos = iX - DISC_ICON_SPACER; - SPR_DrawAdditive(0, iXPos + (DISC_ICON_SPACER), ScreenHeight - YRES(92), &gHUD.GetSpriteRect(m_HUD_dmg_bio + i)); - } - } - -/* - // check for bits that should be expired - for ( i = 0; i < NUM_DMG_TYPES; i++ ) - { - DAMAGE_IMAGE *pdmg = &m_dmg[i]; - - if ( m_bitsDamage & giDmgFlags[i] ) - { - pdmg->fExpire = V_min( flTime + DMG_IMAGE_LIFE, pdmg->fExpire ); - - if ( pdmg->fExpire <= flTime // when the time has expired - && a < 40 ) // and the flash is at the low point of the cycle - { - pdmg->fExpire = 0; - - int y = pdmg->y; - pdmg->x = pdmg->y = 0; - - // move everyone above down - for (int j = 0; j < NUM_DMG_TYPES; j++) - { - pdmg = &m_dmg[j]; - if ((pdmg->y) && (pdmg->y < y)) - pdmg->y += giDmgHeight; - - } - - m_bitsDamage &= ~giDmgFlags[i]; // clear the bits - } - } - } -*/ - return 1; -} - - -void CHudHealth::UpdateTiles(float flTime, long bitsDamage) -{ - DAMAGE_IMAGE *pdmg; - - // Which types are new? - long bitsOn = ~m_bitsDamage & bitsDamage; - - for (int i = 0; i < NUM_DMG_TYPES; i++) - { - pdmg = &m_dmg[i]; - - // Is this one already on? - if (m_bitsDamage & giDmgFlags[i]) - { - pdmg->fExpire = flTime + DMG_IMAGE_LIFE; // extend the duration - if (!pdmg->fBaseline) - pdmg->fBaseline = flTime; - } - - // Are we just turning it on? - if (bitsOn & giDmgFlags[i]) - { - // put this one at the bottom - pdmg->x = giDmgWidth/8; - pdmg->y = ScreenHeight - giDmgHeight * 2; - pdmg->fExpire=flTime + DMG_IMAGE_LIFE; - - // move everyone else up - for (int j = 0; j < NUM_DMG_TYPES; j++) - { - if (j == i) - continue; - - pdmg = &m_dmg[j]; - if (pdmg->y) - pdmg->y -= giDmgHeight; - - } - pdmg = &m_dmg[i]; - } - } - - // damage bits are only turned on here; they are turned off when the draw time has expired (in DrawDamage()) - m_bitsDamage |= bitsDamage; -} diff --git a/ricochet/cl_dll/health.h b/ricochet/cl_dll/health.h deleted file mode 100644 index dd59897..0000000 --- a/ricochet/cl_dll/health.h +++ /dev/null @@ -1,128 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ - -#define DMG_IMAGE_LIFE 2 // seconds that image is up - -#define DMG_IMAGE_POISON 0 -#define DMG_IMAGE_ACID 1 -#define DMG_IMAGE_COLD 2 -#define DMG_IMAGE_DROWN 3 -#define DMG_IMAGE_BURN 4 -#define DMG_IMAGE_NERVE 5 -#define DMG_IMAGE_RAD 6 -#define DMG_IMAGE_SHOCK 7 -//tf defines -#define DMG_IMAGE_CALTROP 8 -#define DMG_IMAGE_TRANQ 9 -#define DMG_IMAGE_CONCUSS 10 -#define DMG_IMAGE_HALLUC 11 -#define NUM_DMG_TYPES 12 -// instant damage - -#define DMG_GENERIC 0 // generic damage was done -#define DMG_CRUSH (1 << 0) // crushed by falling or moving object -#define DMG_BULLET (1 << 1) // shot -#define DMG_SLASH (1 << 2) // cut, clawed, stabbed -#define DMG_BURN (1 << 3) // heat burned -#define DMG_FREEZE (1 << 4) // frozen -#define DMG_FALL (1 << 5) // fell too far -#define DMG_BLAST (1 << 6) // explosive blast damage -#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt -#define DMG_SHOCK (1 << 8) // electric shock -#define DMG_SONIC (1 << 9) // sound pulse shockwave -#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam -#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death -#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death. - - -// time-based damage -//mask off TF-specific stuff too -#define DMG_TIMEBASED (~(0xff003fff)) // mask for time-based damage - - -#define DMG_DROWN (1 << 14) // Drowning -#define DMG_FIRSTTIMEBASED DMG_DROWN - -#define DMG_PARALYZE (1 << 15) // slows affected creature down -#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad -#define DMG_POISON (1 << 17) // blood poisioning -#define DMG_RADIATION (1 << 18) // radiation exposure -#define DMG_DROWNRECOVER (1 << 19) // drowning recovery -#define DMG_ACID (1 << 20) // toxic chemicals or acid burns -#define DMG_SLOWBURN (1 << 21) // in an oven -#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer -#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar) - -//TF ADDITIONS -#define DMG_IGNITE (1 << 24) // Players hit by this begin to burn -#define DMG_RADIUS_MAX (1 << 25) // Radius damage with this flag doesn't decrease over distance -#define DMG_RADIUS_QUAKE (1 << 26) // Radius damage is done like Quake. 1/2 damage at 1/2 radius. -#define DMG_IGNOREARMOR (1 << 27) // Damage ignores target's armor -#define DMG_AIMED (1 << 28) // Does Hit location damage -#define DMG_WALLPIERCING (1 << 29) // Blast Damages ents through walls - -#define DMG_CALTROP (1<<30) -#define DMG_HALLUC (1<<31) - -// TF Healing Additions for TakeHealth -#define DMG_IGNORE_MAXHEALTH DMG_IGNITE -// TF Redefines since we never use the originals -#define DMG_NAIL DMG_SLASH -#define DMG_NOT_SELF DMG_FREEZE - - -#define DMG_TRANQ DMG_MORTAR -#define DMG_CONCUSS DMG_SONIC - - - -typedef struct -{ - float fExpire; - float fBaseline; - int x, y; -} DAMAGE_IMAGE; - -// -//----------------------------------------------------- -// -class CHudHealth: public CHudBase -{ -public: - virtual int Init( void ); - virtual int VidInit( void ); - virtual int Draw(float fTime); - virtual void Reset( void ); - int MsgFunc_Health(const char *pszName, int iSize, void *pbuf); - int MsgFunc_Damage(const char *pszName, int iSize, void *pbuf); - int m_iHealth; - int m_HUD_dmg_bio; - int m_HUD_cross; - float m_fAttackFront, m_fAttackRear, m_fAttackLeft, m_fAttackRight; - void GetPainColor( int &r, int &g, int &b ); - float m_fFade; - - int m_bitsDamage; - -private: - HSPRITE m_hSprite; - HSPRITE m_hDamage; - - DAMAGE_IMAGE m_dmg[NUM_DMG_TYPES]; - int DrawPain(float fTime); - int DrawDamage(float fTime); - void CalcDamageDirection(vec3_t vecFrom); - void UpdateTiles(float fTime, long bits); -}; diff --git a/ricochet/cl_dll/hl/hl_baseentity.cpp b/ricochet/cl_dll/hl/hl_baseentity.cpp deleted file mode 100644 index 16809e9..0000000 --- a/ricochet/cl_dll/hl/hl_baseentity.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ - -/* -========================== -This file contains "stubs" of class member implementations so that we can predict certain - weapons client side. From time to time you might find that you need to implement part of the - these functions. If so, cut it from here, paste it in hl_weapons.cpp or somewhere else and - add in the functionality you need. -========================== -*/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "nodes.h" - -// Globals used by game logic -const Vector g_vecZero = Vector( 0, 0, 0 ); -int gmsgWeapPickup = 0; -enginefuncs_t g_engfuncs; -globalvars_t *gpGlobals; - -ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS]; - -void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, int flags, int pitch) { } - -// CBaseEntity Stubs -int CBaseEntity :: TakeHealth( float flHealth, int bitsDamageType ) { return 1; } -int CBaseEntity :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) { return 1; } -CBaseEntity *CBaseEntity::GetNextTarget( void ) { return NULL; } -int CBaseEntity::Save( CSave &save ) { return 1; } -int CBaseEntity::Restore( CRestore &restore ) { return 1; } -void CBaseEntity::SetObjectCollisionBox( void ) { } -int CBaseEntity :: Intersects( CBaseEntity *pOther ) { return 0; } -void CBaseEntity :: MakeDormant( void ) { } -int CBaseEntity :: IsDormant( void ) { return 0; } -BOOL CBaseEntity :: IsInWorld( void ) { return TRUE; } -int CBaseEntity::ShouldToggle( USE_TYPE useType, BOOL currentState ) { return 0; } -int CBaseEntity :: DamageDecal( int bitsDamageType ) { return -1; } -CBaseEntity * CBaseEntity::Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) { return NULL; } -void CBaseEntity::SUB_Remove( void ) { } - -// CBaseDelay Stubs -void CBaseDelay :: KeyValue( struct KeyValueData_s * ) { } -int CBaseDelay::Restore( class CRestore & ) { return 1; } -int CBaseDelay::Save( class CSave & ) { return 1; } - -// CBaseAnimating Stubs -int CBaseAnimating::Restore( class CRestore & ) { return 1; } -int CBaseAnimating::Save( class CSave & ) { return 1; } - -// DEBUG Stubs -edict_t *DBG_EntOfVars( const entvars_t *pev ) { return NULL; } -void DBG_AssertFunction(BOOL fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage) { } - -// UTIL_* Stubs -void UTIL_PrecacheOther( const char *szClassname ) { } -void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ) { } -void UTIL_DecalTrace( TraceResult *pTrace, int decalNumber ) { } -void UTIL_GunshotDecalTrace( TraceResult *pTrace, int decalNumber ) { } -BOOL UTIL_IsValidEntity( edict_t *pent ) { return TRUE; } -void UTIL_SetOrigin( entvars_t *, const Vector &org ) { } -BOOL UTIL_GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) { return TRUE; } -void UTIL_LogPrintf(char *,...) { } -void UTIL_ClientPrintAll( int,char const *,char const *,char const *,char const *,char const *) { } -void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) { } - -// CBaseToggle Stubs -int CBaseToggle::Restore( class CRestore & ) { return 1; } -int CBaseToggle::Save( class CSave & ) { return 1; } -void CBaseToggle :: KeyValue( struct KeyValueData_s * ) { } - -// CGrenade Stubs -void CGrenade::BounceSound( void ) { } -void CGrenade::Explode( Vector, Vector ) { } -void CGrenade::Explode( TraceResult *, int ) { } -void CGrenade::Killed( entvars_t *, int ) { } -void CGrenade::Spawn( void ) { } - -CBaseEntity* CBaseMonster :: CheckTraceHullAttack( float flDist, int iDamage, int iDmgType ) { return NULL; } -void CBaseMonster :: Look ( int iDistance ) { } -float CBaseAnimating :: StudioFrameAdvance ( float flInterval ) { return 0.0; } -int CBaseMonster::IRelationship ( CBaseEntity *pTarget ) { return 0; } -CBaseEntity *CBaseMonster :: BestVisibleEnemy ( void ) { return NULL; } -BOOL CBaseMonster :: FInViewCone ( CBaseEntity *pEntity ) { return FALSE; } -BOOL CBaseMonster :: FInViewCone ( Vector *pOrigin ) { return FALSE; } -BOOL CBaseEntity :: FVisible ( CBaseEntity *pEntity ) { return FALSE; } -BOOL CBaseEntity :: FVisible ( const Vector &vecOrigin ) { return FALSE; } -void CBaseMonster :: MakeIdealYaw( Vector vecTarget ) { } -float CBaseMonster::ChangeYaw ( int yawSpeed ) { return 0; } -int CBaseAnimating :: LookupActivity ( int activity ) { return 0; } -int CBaseAnimating :: LookupActivityHeaviest ( int activity ) { return 0; } - -BOOL CBaseAnimating :: GetSequenceFlags( ) { return FALSE; } -void CBaseAnimating :: DispatchAnimEvents ( float flInterval ) { } -float CBaseAnimating :: SetBoneController ( int iController, float flValue ) { return 0.0; } -void CBaseAnimating :: InitBoneControllers ( void ) { } -float CBaseAnimating :: SetBlending ( int iBlender, float flValue ) { return 0; } -void CBaseAnimating :: GetBonePosition ( int iBone, Vector &origin, Vector &angles ) { } -void CBaseAnimating :: GetAttachment ( int iAttachment, Vector &origin, Vector &angles ) { } -int CBaseAnimating :: FindTransition( int iEndingSequence, int iGoalSequence, int *piDir ) { return -1; } -void CBaseAnimating :: GetAutomovement( Vector &origin, Vector &angles, float flInterval ) { } -void CBaseAnimating :: SetBodygroup( int iGroup, int iValue ) { } -int CBaseAnimating :: GetBodygroup( int iGroup ) { return 0; } -void CBaseEntity::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { } -void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker ) { } -void CBaseEntity :: TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ) { } -void CBaseMonster :: MakeDamageBloodDecal ( int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir ) { } -void CBaseMonster::ReportAIState( void ) { } -void CBaseMonster :: KeyValue( KeyValueData *pkvd ) { } -BOOL CBaseMonster :: FCheckAITrigger ( void ) { return FALSE; } -void CBaseMonster::CorpseFallThink( void ) { } -void CBaseMonster :: MonsterInitDead( void ) { } -void CBaseMonster :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { } -BOOL CBaseMonster :: ShouldFadeOnDeath( void ) { return FALSE; } -void CBaseMonster :: RadiusDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) { } -void CBaseMonster :: RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) { } -void CBaseMonster::FadeMonster( void ) { } -void CBaseMonster :: GibMonster( void ) { } -BOOL CBaseMonster :: HasHumanGibs( void ) { return FALSE; } -BOOL CBaseMonster :: HasAlienGibs( void ) { return FALSE; } -Activity CBaseMonster :: GetDeathActivity ( void ) { return (Activity)0; } -void CBaseMonster::BecomeDead( void ) {} -void CBaseMonster :: Killed( entvars_t *pevAttacker, int iGib ) {} -int CBaseMonster :: TakeHealth (float flHealth, int bitsDamageType) { return 0; } -int CBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { return 0; } - -int TrainSpeed(int iSpeed, int iMax) { return 0; } -void CBasePlayer :: DeathSound( void ) { } -int CBasePlayer :: TakeHealth( float flHealth, int bitsDamageType ) { return 0; } -void CBasePlayer :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) { } -int CBasePlayer :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { return 0; } -void CBasePlayer::RemoveAllItems( BOOL removeSuit ) { } -void CBasePlayer::WaterMove() { } -BOOL CBasePlayer::IsOnLadder( void ) { return FALSE; } -void CBasePlayer::PlayerDeathThink(void) { } -void CBasePlayer::StartDeathCam( void ) { } -void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) { } -void CBasePlayer::PlayerUse ( void ) { } -void CBasePlayer::Jump() { } -void CBasePlayer::Duck( ) { } -int CBasePlayer::Classify ( void ) { return 0; } -void CBasePlayer :: PlayStepSound(int step, float fvol) { } -void CBasePlayer :: UpdateStepSound( void ) { } -void CBasePlayer::PreThink(void) { } -void CBasePlayer::CheckTimeBasedDamage() { } -void CBasePlayer :: UpdateGeigerCounter( void ) { } -void CBasePlayer::CheckSuitUpdate() { } -void CBasePlayer::SetSuitUpdate(char *name, int fgroup, int iNoRepeatTime) { } -void CBasePlayer :: UpdatePlayerSound ( void ) { } -void CBasePlayer :: Precache( void ) { } -int CBasePlayer::Save( CSave &save ) { return 0; } -void CBasePlayer::RenewItems(void) { } -int CBasePlayer::Restore( CRestore &restore ) { return 0; } -void CBasePlayer::SelectNextItem( int iItem ) { } -BOOL CBasePlayer::HasWeapons( void ) { return FALSE; } -void CBasePlayer::SelectPrevItem( int iItem ) { } -CBaseEntity *FindEntityForward( CBaseEntity *pMe ) { return NULL; } -BOOL CBasePlayer :: FlashlightIsOn( void ) { return FALSE; } -void CBasePlayer :: FlashlightTurnOn( void ) { } -void CBasePlayer :: FlashlightTurnOff( void ) { } -void CBasePlayer :: ForceClientDllUpdate( void ) { } -void CBasePlayer::ImpulseCommands( ) { } -void CBasePlayer::CheatImpulseCommands( int iImpulse ) { } -int CBasePlayer::AddPlayerItem( CBasePlayerItem *pItem ) { return FALSE; } -int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem ) { return FALSE; } -void CBasePlayer::ItemPreFrame() { } -void CBasePlayer::ItemPostFrame() { } -int CBasePlayer::AmmoInventory( int iAmmoIndex ) { return -1; } -int CBasePlayer::GetAmmoIndex(const char *psz) { return -1; } -void CBasePlayer::SendAmmoUpdate(void) { } -void CBasePlayer :: UpdateClientData( void ) { } -BOOL CBasePlayer :: FBecomeProne ( void ) { return TRUE; } -void CBasePlayer :: BarnacleVictimBitten ( entvars_t *pevBarnacle ) { } -void CBasePlayer :: BarnacleVictimReleased ( void ) { } -int CBasePlayer :: Illumination( void ) { return 0; } -void CBasePlayer :: EnableControl(BOOL fControl) { } -Vector CBasePlayer :: GetAutoaimVector( float flDelta ) { return g_vecZero; } -Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta ) { return g_vecZero; } -void CBasePlayer :: ResetAutoaim( ) { } -void CBasePlayer :: SetCustomDecalFrames( int nFrames ) { } -int CBasePlayer :: GetCustomDecalFrames( void ) { return -1; } -void CBasePlayer::DropPlayerItem ( char *pszItemName ) { } -BOOL CBasePlayer::HasPlayerItem( CBasePlayerItem *pCheckItem ) { return FALSE; } -BOOL CBasePlayer :: SwitchWeapon( CBasePlayerItem *pWeapon ) { return FALSE; } -Vector CBasePlayer :: GetGunPosition( void ) { return g_vecZero; } -const char *CBasePlayer::TeamID( void ) { return ""; } -int CBasePlayer :: GiveAmmo( int iCount, char *szName, int iMax ) { return 0; } -void CBasePlayer::AddPoints( int score, BOOL bAllowNegativeScore ) { } -void CBasePlayer::AddPointsToTeam( int score, BOOL bAllowNegativeScore ) { } -void CBasePlayer::RemoveAllPowerups( void ) {} -bool CBasePlayer::HasPowerup(int) { return 0; } - -void ClearMultiDamage(void) { } -void ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker ) { } -void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType) { } -void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage) { } -int DamageDecal( CBaseEntity *pEntity, int bitsDamageType ) { return 0; } -void DecalGunshot( TraceResult *pTrace, int iBulletType ) { } -void EjectBrass ( const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype ) { } -void AddAmmoNameToAmmoRegistry( const char *szAmmoname ) { } -int CBasePlayerItem::Restore( class CRestore & ) { return 1; } -int CBasePlayerItem::Save( class CSave & ) { return 1; } -int CBasePlayerWeapon::Restore( class CRestore & ) { return 1; } -int CBasePlayerWeapon::Save( class CSave & ) { return 1; } -void CBasePlayerItem :: SetObjectCollisionBox( void ) { } -void CBasePlayerItem :: FallInit( void ) { } -void CBasePlayerItem::FallThink ( void ) { } -void CBasePlayerItem::Materialize( void ) { } -void CBasePlayerItem::AttemptToMaterialize( void ) { } -void CBasePlayerItem :: CheckRespawn ( void ) { } -CBaseEntity* CBasePlayerItem::Respawn( void ) { return NULL; } -void CBasePlayerItem::DefaultTouch( CBaseEntity *pOther ) { } -void CBasePlayerItem::DestroyItem( void ) { } -int CBasePlayerItem::AddToPlayer( CBasePlayer *pPlayer ) { return TRUE; } -void CBasePlayerItem::Drop( void ) { } -void CBasePlayerItem::Kill( void ) { } -void CBasePlayerItem::Holster( int skiplocal ) { } -void CBasePlayerItem::AttachToPlayer ( CBasePlayer *pPlayer ) { } -int CBasePlayerWeapon::AddDuplicate( CBasePlayerItem *pOriginal ) { return 0; } -int CBasePlayerWeapon::AddToPlayer( CBasePlayer *pPlayer ) { return FALSE; } -int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer ) { return 0; } -BOOL CBasePlayerWeapon :: AddPrimaryAmmo( int iCount, char *szName, int iMaxClip, int iMaxCarry ) { return TRUE; } -BOOL CBasePlayerWeapon :: AddSecondaryAmmo( int iCount, char *szName, int iMax ) { return TRUE; } -BOOL CBasePlayerWeapon :: IsUseable( void ) { return TRUE; } -int CBasePlayerWeapon::PrimaryAmmoIndex( void ) { return -1; } -int CBasePlayerWeapon::SecondaryAmmoIndex( void ) { return -1; } -void CBasePlayerAmmo::Spawn( void ) { } -CBaseEntity* CBasePlayerAmmo::Respawn( void ) { return this; } -void CBasePlayerAmmo::Materialize( void ) { } -void CBasePlayerAmmo :: DefaultTouch( CBaseEntity *pOther ) { } -int CBasePlayerWeapon::ExtractAmmo( CBasePlayerWeapon *pWeapon ) { return 0; } -int CBasePlayerWeapon::ExtractClipAmmo( CBasePlayerWeapon *pWeapon ) { return 0; } -void CBasePlayerWeapon::RetireWeapon( void ) { } \ No newline at end of file diff --git a/ricochet/cl_dll/hl/hl_events.cpp b/ricochet/cl_dll/hl/hl_events.cpp deleted file mode 100644 index 0906ab3..0000000 --- a/ricochet/cl_dll/hl/hl_events.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/*** -* -* Copyright (c) 1999, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "../hud.h" -#include "../cl_util.h" -#include "event_api.h" - -extern "C" -{ -// RICOCHET -void EV_TriggerJump( struct event_args_s *args ); -void EV_FireDisc( struct event_args_s *args ); -void EV_TrainPitchAdjust( struct event_args_s *args ); -} - -/* -====================== -Game_HookEvents - -Associate script file name with callback functions. Callback's must be extern "C" so - the engine doesn't get confused about name mangling stuff. Note that the format is - always the same. Of course, a clever mod team could actually embed parameters, behavior - into the actual .sc files and create a .sc file parser and hook their functionality through - that.. i.e., a scripting system. - -That was what we were going to do, but we ran out of time...oh well. -====================== -*/ -void Game_HookEvents( void ) -{ - gEngfuncs.pfnHookEvent( "events/train.sc", EV_TrainPitchAdjust ); - gEngfuncs.pfnHookEvent( "events/firedisc.sc", EV_FireDisc ); - gEngfuncs.pfnHookEvent( "events/jump.sc", EV_TriggerJump ); -} \ No newline at end of file diff --git a/ricochet/cl_dll/hl/hl_objects.cpp b/ricochet/cl_dll/hl/hl_objects.cpp deleted file mode 100644 index 204d0bc..0000000 --- a/ricochet/cl_dll/hl/hl_objects.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/*** -* -* Copyright (c) 1999, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "../hud.h" -#include "../cl_util.h" -#include "../demo.h" - -/* -===================== -Game_AddObjects - -Add game specific, client-side objects here -===================== -*/ -void Game_AddObjects( void ) -{ -} \ No newline at end of file diff --git a/ricochet/cl_dll/hl/hl_weapons.cpp b/ricochet/cl_dll/hl/hl_weapons.cpp deleted file mode 100644 index 5ff1a96..0000000 --- a/ricochet/cl_dll/hl/hl_weapons.cpp +++ /dev/null @@ -1,1423 +0,0 @@ -/*** -* -* Copyright (c) 1999, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "weapons.h" -#include "disc_weapon.h" -#include "discwar.h" -#include "nodes.h" -#include "player.h" - -#include "usercmd.h" -#include "entity_state.h" -#include "demo_api.h" -#include "pm_defs.h" -#include "event_api.h" -#include "r_efx.h" - -#include "../hud_iface.h" -#include "../com_weapons.h" -#include "../demo.h" - -#include "r_studioint.h" - -#include "../Ricochet_JumpPads.h" -#include "studio.h" -#include "com_model.h" - -// Global engine <-> studio model rendering code interface -extern engine_studio_api_t IEngineStudio; - -extern globalvars_t *gpGlobals; - -// Pool of client side entities/entvars_t -static entvars_t ev[ 32 ]; -static int num_ents = 0; - -// The entity we'll use to represent the local client -static CBasePlayer player; - -// Local version of game .dll global variables ( time, etc. ) -static globalvars_t Globals; - -static CBasePlayerWeapon *g_pWpns[ 32 ]; - -// For storing predicted sequence and gaitsequence and origin/angles data -static int g_rseq = 0, g_gaitseq = 0; -static vec3_t g_clorg, g_clang; - -// HLDM Weapon placeholder entities. -CDiscWeapon g_Disc; -extern int g_iCannotFire; - -/* -====================== -AlertMessage - -Print debug messages to console -====================== -*/ -void AlertMessage( ALERT_TYPE atype, const char *szFmt, ... ) -{ - va_list argptr; - static char string[1024]; - - va_start (argptr, szFmt); - vsprintf (string, szFmt,argptr); - va_end (argptr); - - gEngfuncs.Con_Printf( "cl: " ); - gEngfuncs.Con_Printf( string ); -} - -/* -===================== -HUD_PrepEntity - -Links the raw entity to an entvars_s holder. If a player is passed in as the owner, then -we set up the m_pPlayer field. -===================== -*/ -void HUD_PrepEntity( CBaseEntity *pEntity, CBasePlayer *pWeaponOwner ) -{ - memset( &ev[ num_ents ], 0, sizeof( entvars_t ) ); - pEntity->pev = &ev[ num_ents++ ]; - - pEntity->Precache(); - pEntity->Spawn(); - - if ( pWeaponOwner ) - { - ItemInfo info; - - ((CBasePlayerWeapon *)pEntity)->m_pPlayer = pWeaponOwner; - - ((CBasePlayerWeapon *)pEntity)->GetItemInfo( &info ); - - g_pWpns[ info.iId ] = (CBasePlayerWeapon *)pEntity; - } -} - -/* -===================== -CBaseEntity :: Killed - -If weapons code "kills" an entity, just set its effects to EF_NODRAW -===================== -*/ -void CBaseEntity :: Killed( entvars_t *pevAttacker, int iGib ) -{ - pev->effects |= EF_NODRAW; -} - -/* -===================== -CBasePlayerWeapon :: DefaultReload -===================== -*/ -BOOL CBasePlayerWeapon :: DefaultReload( int iClipSize, int iAnim, float fDelay ) -{ -#if 0 // FIXME, need to know primary ammo to get this right - if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) - return FALSE; - - int j = V_min(iClipSize - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); - - if (j == 0) - return FALSE; -#endif - - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + fDelay; - - //!!UNDONE -- reload sound goes here !!! - SendWeaponAnim( iAnim ); - - m_fInReload = TRUE; - - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3; - return TRUE; -} - -/* -===================== -CBasePlayerWeapon :: CanDeploy -===================== -*/ -BOOL CBasePlayerWeapon :: CanDeploy( void ) -{ - BOOL bHasAmmo = 0; - - if ( !pszAmmo1() ) - { - // this weapon doesn't use ammo, can always deploy. - return TRUE; - } - - if ( pszAmmo1() ) - { - bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0); - } - if ( pszAmmo2() ) - { - bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] != 0); - } - if (m_iClip > 0) - { - bHasAmmo |= 1; - } - if (!bHasAmmo) - { - return FALSE; - } - - return TRUE; -} - -/* -===================== -CBasePlayerWeapon :: DefaultDeploy - -===================== -*/ -BOOL CBasePlayerWeapon :: DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal ) -{ - if ( !CanDeploy() ) - return FALSE; - - gEngfuncs.CL_LoadModel( szViewModel, &m_pPlayer->pev->viewmodel ); - - SendWeaponAnim( iAnim ); - - m_pPlayer->m_flNextAttack = 0.5; - m_flTimeWeaponIdle = 1.0; - return TRUE; -} - -/* -===================== -CBasePlayerWeapon :: PlayEmptySound - -===================== -*/ -BOOL CBasePlayerWeapon :: PlayEmptySound( void ) -{ - if (m_iPlayEmptySound) - { - HUD_PlaySound( "weapons/357_cock1.wav", 0.8 ); - m_iPlayEmptySound = 0; - return 0; - } - return 0; -} - -/* -===================== -CBasePlayerWeapon :: ResetEmptySound - -===================== -*/ -void CBasePlayerWeapon :: ResetEmptySound( void ) -{ - m_iPlayEmptySound = 1; -} - -/* -===================== -CBasePlayerWeapon::Holster - -Put away weapon -===================== -*/ -void CBasePlayerWeapon::Holster( int skiplocal /* = 0 */ ) -{ - m_fInReload = FALSE; // cancel any reload in progress. - m_pPlayer->pev->viewmodel = 0; -} - -/* -===================== -CBasePlayerWeapon::SendWeaponAnim - -Animate weapon model -===================== -*/ -void CBasePlayerWeapon::SendWeaponAnim( int iAnim, int skiplocal ) -{ - m_pPlayer->pev->weaponanim = iAnim; - - int body = 0; - - HUD_SendWeaponAnim( iAnim, body, 0 ); -} - -/* -===================== -CBasePlayerWeapon::ItemPostFrame - -Handles weapon firing, reloading, etc. -===================== -*/ -void CBasePlayerWeapon::ItemPostFrame( void ) -{ - if ((m_fInReload) && (m_pPlayer->m_flNextAttack <= 0.0)) - { -#if 0 // FIXME, need ammo on client to make this work right - // complete the reload. - int j = V_min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); - - // Add them to the clip - m_iClip += j; - m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j; -#else - m_iClip += 10; -#endif - m_fInReload = FALSE; - } - - if ((m_pPlayer->pev->button & IN_ATTACK2) && (m_flNextSecondaryAttack <= 0.0)) - { - if ( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] ) - { - m_fFireOnEmpty = TRUE; - } - - SecondaryAttack(); - m_pPlayer->pev->button &= ~IN_ATTACK2; - } - else if ((m_pPlayer->pev->button & IN_ATTACK) && (m_flNextPrimaryAttack <= 0.0)) - { - if ( (m_iClip == 0 && pszAmmo1()) || (iMaxClip() == -1 && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] ) ) - { - m_fFireOnEmpty = TRUE; - } - - PrimaryAttack(); - } - else if ( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload ) - { - // reload when reload is pressed, or if no buttons are down and weapon is empty. - Reload(); - } - else if ( !(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2) ) ) - { - // no fire buttons down - - m_fFireOnEmpty = FALSE; - - // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing - if ( m_iClip == 0 && !(iFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < 0.0 ) - { - Reload(); - return; - } - - WeaponIdle( ); - return; - } - - // catch all - if ( ShouldWeaponIdle() ) - { - WeaponIdle(); - } -} - -/* -===================== -CBasePlayer::SelectItem - - Switch weapons -===================== -*/ -void CBasePlayer::SelectItem(const char *pstr) -{ - if (!pstr) - return; - - CBasePlayerItem *pItem = NULL; - - if (!pItem) - return; - - - if (pItem == m_pActiveItem) - return; - - if (m_pActiveItem) - m_pActiveItem->Holster( ); - - m_pLastItem = m_pActiveItem; - m_pActiveItem = pItem; - - if (m_pActiveItem) - { - m_pActiveItem->Deploy( ); - } -} - -/* -===================== -CBasePlayer::SelectLastItem - -===================== -*/ -void CBasePlayer::SelectLastItem(void) -{ - if (!m_pLastItem) - { - return; - } - - if ( m_pActiveItem && !m_pActiveItem->CanHolster() ) - { - return; - } - - if (m_pActiveItem) - m_pActiveItem->Holster( ); - - CBasePlayerItem *pTemp = m_pActiveItem; - m_pActiveItem = m_pLastItem; - m_pLastItem = pTemp; - m_pActiveItem->Deploy( ); -} - -/* -===================== -CBasePlayer::Killed - -===================== -*/ -void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib ) -{ - // Holster weapon immediately, to allow it to cleanup - if (m_pActiveItem) - m_pActiveItem->Holster( ); -} - -/* -===================== -CBasePlayer::Spawn - -===================== -*/ -void CBasePlayer::Spawn( void ) -{ - if (m_pActiveItem) - m_pActiveItem->Deploy( ); -} - -/* -===================== -UTIL_TraceLine - -Don't actually trace, but act like the trace didn't hit anything. -===================== -*/ -void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr ) -{ - memset( ptr, 0, sizeof( *ptr ) ); - ptr->flFraction = 1.0; -} - -/* -===================== -UTIL_ParticleBox - -For debugging, draw a box around a player made out of particles -===================== -*/ -void UTIL_ParticleBox( CBasePlayer *player, float *mins, float *maxs, float life, unsigned char r, unsigned char g, unsigned char b ) -{ - int i; - vec3_t mmin, mmax; - - for ( i = 0; i < 3; i++ ) - { - mmin[ i ] = player->pev->origin[ i ] + mins[ i ]; - mmax[ i ] = player->pev->origin[ i ] + maxs[ i ]; - } - - gEngfuncs.pEfxAPI->R_ParticleBox( (float *)&mmin, (float *)&mmax, 5.0, 0, 255, 0 ); -} - -/* -===================== -UTIL_ParticleBoxes - -For debugging, draw boxes for other collidable players -===================== -*/ -void UTIL_ParticleBoxes( void ) -{ - int idx; - physent_t *pe; - cl_entity_t *player; - vec3_t mins, maxs; - - gEngfuncs.pEventAPI->EV_SetUpPlayerPrediction( false, true ); - - // Store off the old count - gEngfuncs.pEventAPI->EV_PushPMStates(); - - player = gEngfuncs.GetLocalPlayer(); - // Now add in all of the players. - gEngfuncs.pEventAPI->EV_SetSolidPlayers ( player->index - 1 ); - - for ( idx = 1; idx < 100; idx++ ) - { - pe = gEngfuncs.pEventAPI->EV_GetPhysent( idx ); - if ( !pe ) - break; - - if ( pe->info >= 1 && pe->info <= gEngfuncs.GetMaxClients() ) - { - mins = pe->origin + pe->mins; - maxs = pe->origin + pe->maxs; - - gEngfuncs.pEfxAPI->R_ParticleBox( (float *)&mins, (float *)&maxs, 0, 0, 255, 2.0 ); - } - } - - gEngfuncs.pEventAPI->EV_PopPMStates(); -} - -/* -===================== -UTIL_ParticleLine - -For debugging, draw a line made out of particles -===================== -*/ -void UTIL_ParticleLine( CBasePlayer *player, float *start, float *end, float life, unsigned char r, unsigned char g, unsigned char b ) -{ - gEngfuncs.pEfxAPI->R_ParticleLine( start, end, r, g, b, life ); -} - -/* -===================== -CBasePlayerWeapon::PrintState - -For debugging, print out state variables to log file -===================== -*/ -void CBasePlayerWeapon::PrintState( void ) -{ - COM_Log( "c:\\hl.log", "%.4f ", gpGlobals->time ); - COM_Log( "c:\\hl.log", "%.4f ", m_pPlayer->m_flNextAttack ); - COM_Log( "c:\\hl.log", "%.4f ", m_flNextPrimaryAttack ); - COM_Log( "c:\\hl.log", "%.4f ", m_flTimeWeaponIdle - gpGlobals->time); - COM_Log( "c:\\hl.log", "%i ", m_iClip ); -} - -/* -===================== -HUD_InitClientWeapons - -Set up weapons, player and functions needed to run weapons code client-side. -===================== -*/ -void HUD_InitClientWeapons( void ) -{ - static int initialized = 0; - if ( initialized ) - return; - - initialized = 1; - - // Set up pointer ( dummy object ) - gpGlobals = &Globals; - - // Fill in current time ( probably not needed ) - gpGlobals->time = gEngfuncs.GetClientTime(); - - // Fake functions - g_engfuncs.pfnPrecacheModel = stub_PrecacheModel; - g_engfuncs.pfnPrecacheSound = stub_PrecacheSound; - g_engfuncs.pfnPrecacheEvent = stub_PrecacheEvent; - g_engfuncs.pfnNameForFunction = stub_NameForFunction; - g_engfuncs.pfnSetModel = stub_SetModel; - g_engfuncs.pfnSetClientMaxspeed = HUD_SetMaxSpeed; - - // Handled locally - g_engfuncs.pfnPlaybackEvent = HUD_PlaybackEvent; - g_engfuncs.pfnAlertMessage = AlertMessage; - - // Pass through to engine - g_engfuncs.pfnPrecacheEvent = gEngfuncs.pfnPrecacheEvent; - g_engfuncs.pfnRandomFloat = gEngfuncs.pfnRandomFloat; - g_engfuncs.pfnRandomLong = gEngfuncs.pfnRandomLong; - - // Allocate a slot for the local player - HUD_PrepEntity( &player , NULL ); - - // Allocate slot(s) for each weapon that we are going to be predicting - HUD_PrepEntity( &g_Disc , &player ); -} - -/* -============================== -LookupSequence - -Find sequence # of named sequence -============================== -*/ -int LookupSequence( void *pmodel, const char *label ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return 0; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - for (int i = 0; i < pstudiohdr->numseq; i++) - { - if (stricmp( pseqdesc[i].label, label ) == 0) - return i; - } - - return -1; -} - -/* -============================== -LookupSequence - -============================== -*/ -int CBaseAnimating :: LookupSequence ( const char *label ) -{ - cl_entity_t *current; - - current = gEngfuncs.GetLocalPlayer(); - if ( !current || !current->model ) - return 0; - - return ::LookupSequence( (studiohdr_t *)IEngineStudio.Mod_Extradata( current->model ), label ); -} - -/* -============================== -GetSequenceInfo - -============================== -*/ -void GetSequenceInfo( void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return; - - mstudioseqdesc_t *pseqdesc; - - if (pev->sequence >= pstudiohdr->numseq) - { - *pflFrameRate = 0.0; - *pflGroundSpeed = 0.0; - return; - } - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - if (pseqdesc->numframes > 1) - { - *pflFrameRate = 256 * pseqdesc->fps / (pseqdesc->numframes - 1); - *pflGroundSpeed = sqrt( pseqdesc->linearmovement[0]*pseqdesc->linearmovement[0]+ pseqdesc->linearmovement[1]*pseqdesc->linearmovement[1]+ pseqdesc->linearmovement[2]*pseqdesc->linearmovement[2] ); - *pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1); - } - else - { - *pflFrameRate = 256.0; - *pflGroundSpeed = 0.0; - } -} - -/* -============================== -GetSequenceFlags - -============================== -*/ -int GetSequenceFlags( void *pmodel, entvars_t *pev ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr || pev->sequence >= pstudiohdr->numseq ) - return 0; - - mstudioseqdesc_t *pseqdesc; - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - return pseqdesc->flags; -} - -/* -============================== -ResetSequenceInfo - -============================== -*/ -void CBaseAnimating :: ResetSequenceInfo ( ) -{ - cl_entity_t *current; - - current = gEngfuncs.GetLocalPlayer(); - if ( !current || !current->model ) - return; - - void *pmodel = (studiohdr_t *)IEngineStudio.Mod_Extradata( current->model ); - - GetSequenceInfo( pmodel, pev, &m_flFrameRate, &m_flGroundSpeed ); - m_fSequenceLoops = ((GetSequenceFlags() & STUDIO_LOOPING) != 0); - pev->animtime = gpGlobals->time; - pev->framerate = 1.0; - m_fSequenceFinished = FALSE; - m_flLastEventCheck = gpGlobals->time; -} - -/* -============================== -UTIL_MakeVectors - -============================== -*/ -void UTIL_MakeVectors( const Vector &vecAngles ) -{ - gEngfuncs.pfnAngleVectors ( (float *)&vecAngles, gpGlobals->v_forward, gpGlobals->v_right, gpGlobals->v_up); -} - -/* -============================== -GetFallAnimation - -============================== -*/ -int CBasePlayer::GetFallAnimation( void ) -{ - Vector vecNormVel = pev->velocity; - vecNormVel.Normalize(); - int fallAnim; - - UTIL_MakeVectors( pev->angles ); - float flDot = DotProduct( vecNormVel, gpGlobals->v_forward ); - float flSideDot = DotProduct( vecNormVel, gpGlobals->v_right ); - // Choose a falling animation based upon the velocity vector - if ( flDot < -0.6 ) - fallAnim = LookupSequence( "fall_b" ); - else if ( flSideDot < -0.6 ) - fallAnim = LookupSequence( "fall_r" ); - else if ( flSideDot > 0.6 ) - fallAnim = LookupSequence( "fall_l" ); - else - fallAnim = LookupSequence( "fall_f" ); - - return fallAnim; -} - -#define WALK_SPEED 100 -// Set the activity based on an event or current state - -/* -============================== -SetAnimation - -============================== -*/ -void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim ) -{ - int animDesired; - float speed; - - speed = pev->velocity.Length2D(); - - switch (playerAnim) - { - case PLAYER_JUMP: - m_IdealActivity = ACT_HOP; - break; - - case PLAYER_SUPERJUMP: - m_IdealActivity = ACT_LEAP; - break; - - case PLAYER_ATTACK1: - m_IdealActivity = ACT_BASE_THROW; - break; - - case PLAYER_FALL: - m_IdealActivity = ACT_FALL; - break; - - case PLAYER_IDLE: - case PLAYER_WALK: - if ( !FBitSet( pev->flags, FL_ONGROUND ) && (m_Activity == ACT_HOP) ) // Still jumping - { - m_IdealActivity = m_Activity; - } - else - { - m_IdealActivity = ACT_BASE_WALK; - } - break; - } - - Vector vecNormVel; - float flDot, flSideDot, flVelDot; - bool bInReverse; - int iFrame; - - // Decide which sequence to play based upon the activity - switch (m_IdealActivity) - { - case ACT_DIEFORWARD: - case ACT_FALL: - default: - if ( m_Activity == m_IdealActivity) - return; - m_Activity = ACT_FALL; - - animDesired = GetFallAnimation(); - // Already using the desired animation? - if (pev->sequence == animDesired) - return; - - pev->gaitsequence = 0; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - - case ACT_LEAP: - UTIL_MakeVectors( pev->angles ); - vecNormVel = pev->velocity; - vecNormVel.Normalize(); - flDot = DotProduct( vecNormVel, gpGlobals->v_forward ); - if ( flDot < -0.6 ) - { - // Use non-blended backflip - animDesired = LookupSequence( "backflip" ); - m_Activity = m_IdealActivity; - pev->gaitsequence = 0; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - } - else - { - // Use blended longjump - animDesired = LookupSequence( "longjump" ); - m_Activity = ACT_LEAP; - pev->gaitsequence = animDesired; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - } - break; - - case ACT_DIE_HEADSHOT: - animDesired = LookupSequence( "die_simple" ); - m_Activity = m_IdealActivity; - - pev->gaitsequence = 0; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - - case ACT_HOP: - iFrame = pev->frame / 18; - if ( iFrame >= 2 && iFrame <= 11 ) - animDesired = LookupSequence( "jump" ); - else - animDesired = LookupSequence( "jumpl" ); - // Already using the desired animation? - if (pev->sequence == animDesired) - return; - - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - - case ACT_BASE_THROW: - // No throw animation during backflip - if ( pev->sequence == LookupSequence( "backflip" ) ) - return; - - // If we're in the air, we need to use the blended longjump throw - if ( pev->sequence == LookupSequence( "longjump" ) ) - { - // Use blended longjump - animDesired = LookupSequence( "longjump_throw" ); - m_Activity = ACT_FLINCH_CLOCKWISE; - pev->gaitsequence = animDesired; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - } - - animDesired = GetThrowAnim(); - m_Activity = m_IdealActivity; - m_flThrowTime = 0.25; - break; - - case ACT_BASE_WALK: - UTIL_MakeVectors( pev->angles ); - bInReverse = ( pev->sequence == LookupSequence("base_reverse") ); - vecNormVel = pev->velocity; - vecNormVel.Normalize(); - flDot = DotProduct( vecNormVel, gpGlobals->v_forward ); - flSideDot = DotProduct( vecNormVel, gpGlobals->v_right ); - flVelDot = DotProduct( m_vecOldVelocity, vecNormVel ); - - if ( ( m_flBackupTime <= 0 ) && (m_Activity != ACT_BASE_THROW) || m_fSequenceFinished ) - { - if ( speed == 0 ) - { - animDesired = LookupSequence( "base_stand" ); - } - else if ( flDot < -0.6 ) - { - animDesired = LookupSequence( "base_backup" ); - } - else if ( ( flVelDot <= 0 ) && ( flDot <= 0.6 ) ) - { - animDesired = LookupSequence( "base_reverse" ); - m_flBackupTime = 0.7; - pev->effects |= EF_NOINTERP; - } - else - { - if ( speed > WALK_SPEED ) - animDesired = LookupSequence( "base_run" ); - else - animDesired = LookupSequence( "base_walk" ); - } - - if (animDesired == -1) - { - animDesired = 0; - } - m_Activity = ACT_BASE_WALK; - } - else if ( bInReverse ) - { - // Don't play the backup run if we're still in the backup run - if ( DotProduct( m_vecOldVelocity, vecNormVel ) < 0 ) - { - m_flBackupTime = 0; - if ( speed > WALK_SPEED ) - animDesired = LookupSequence( "base_run" ); - else - animDesired = LookupSequence( "base_walk" ); - pev->effects |= EF_NOINTERP; - } - else - { - animDesired = pev->sequence; - } - } - else - { - animDesired = pev->sequence; - } - break; - } - - // Set gait animation - if ( m_flBackupTime > 0 ) - { - pev->gaitsequence = LookupSequence( "base_backup" ); - } - else - { - if ( speed > WALK_SPEED ) - { - pev->gaitsequence = LookupSequence( "base_run" ); - } - else if (speed > 0) - { - pev->gaitsequence = LookupSequence( "base_walk" ); - } - } - - // Idle? - if (speed <= 0) - { - pev->gaitsequence = LookupSequence( "base_stand" ); - } - - // Already using the desired animation? - if (pev->sequence == animDesired) - return; - - // Reset to first frame of desired animation - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); -} - -int CBasePlayer::GetThrowAnim( void ) -{ - int throwAnim; - - if ( pev->velocity.Length2D() == 0 ) - throwAnim = LookupSequence( "base_stand_throw" ); - else - throwAnim = LookupSequence( "base_throw" ); - - return throwAnim; -} - -int CBasePlayer::GetHoldAnim( void ) -{ - int holdAnim; - - // Choose hold anim based upon powerups. - // Multiple Powerups can be had, in which case the one considered more dangerous has the animation. - if ( m_iPowerups & POW_TRIPLE ) - holdAnim = LookupSequence( "triple_ready" ); - else if ( m_iPowerups & POW_FAST ) - holdAnim = LookupSequence( "kill_ready" ); - else if ( m_iPowerups & POW_HARD ) - holdAnim = LookupSequence( "hard_ready" ); - else if ( m_iPowerups & POW_FREEZE ) - holdAnim = LookupSequence( "freeze_ready" ); - else - holdAnim = LookupSequence( "base_ready" ); - - return holdAnim; -} - -/* -============================== -PostThink - -============================== -*/ -void CBasePlayer::PostThink() -{ - if ( !g_runfuncs ) - return; - - // select the proper animation for the player character - if ( !CL_IsDead() && (m_flTouchedByJumpPad < gpGlobals->time) ) - { - if (!pev->velocity.x && !pev->velocity.y) - SetAnimation( PLAYER_IDLE ); - else if ((pev->velocity.x || pev->velocity.y) && (FBitSet(pev->flags, FL_ONGROUND))) - SetAnimation( PLAYER_WALK ); - else if (pev->waterlevel > 1) - SetAnimation( PLAYER_WALK ); - } - - if ( !CL_IsDead() && ( m_flThrowTime <= 0.0 ) ) - { - m_Activity = ACT_BASE_WALK; - m_flThrowTime = 0.0; - if (!pev->velocity.x && !pev->velocity.y) - { - SetAnimation( PLAYER_IDLE ); - } - else - { - SetAnimation( PLAYER_WALK ); - } - } - - // Store old velocity for use in backpedalling animations - m_vecOldVelocity = pev->velocity; - m_vecOldVelocity.Normalize(); -} - -/* -===================== -HUD_WeaponsPostThink - -Run Weapon firing code on client -===================== -*/ -void HUD_WeaponsPostThink( local_state_s *from, local_state_s *to, usercmd_t *cmd, double time, unsigned int random_seed ) -{ - int i; - int buttonsChanged; - CBasePlayerWeapon *pWeapon = NULL; - CBasePlayerWeapon *pCurrent; - weapon_data_t nulldata, *pfrom, *pto; - static int lasthealth; - - memset( &nulldata, 0, sizeof( nulldata ) ); - - HUD_InitClientWeapons(); - - // Get current clock - gpGlobals->time = time; - - // Fill in data based on selected weapon - // FIXME, make this a method in each weapon? where you pass in an entity_state_t *? - switch ( from->client.m_iId ) - { - case WEAPON_DISC: - pWeapon = &g_Disc; - break; - } - - // We are not predicting the current weapon, just bow out here. - if ( !pWeapon ) - return; - - for ( i = 0; i < 32; i++ ) - { - pCurrent = g_pWpns[ i ]; - if ( !pCurrent ) - { - continue; - } - - pfrom = &from->weapondata[ i ]; - - pCurrent->m_fInReload = pfrom->m_fInReload; - pCurrent->m_iClip = pfrom->m_iClip; - pCurrent->m_flNextPrimaryAttack = pfrom->m_flNextPrimaryAttack; - pCurrent->m_flNextSecondaryAttack = pfrom->m_flNextSecondaryAttack; - pCurrent->m_flTimeWeaponIdle = pfrom->m_flTimeWeaponIdle; - - // Ricochet uses m_iClip to transmit current/primary ammo to client - if ( pWeapon == pCurrent ) - { - player.m_rgAmmo[pCurrent->m_iPrimaryAmmoType] = pfrom->m_iClip; - } - } - - // For random weapon events, use this seed to seed random # generator - player.random_seed = random_seed; - - // Get old buttons from previous state. - player.m_afButtonLast = from->playerstate.oldbuttons; - - // Which buttsons chave changed - buttonsChanged = (player.m_afButtonLast ^ cmd->buttons); // These buttons have changed this frame - - // Debounced button codes for pressed/released - // The changed ones still down are "pressed" - player.m_afButtonPressed = buttonsChanged & cmd->buttons; - // The ones not down are "released" - player.m_afButtonReleased = buttonsChanged & (~cmd->buttons); - - // Set player variables that weapons code might check/alter - player.pev->button = cmd->buttons; - - player.pev->velocity = from->client.velocity; - player.pev->flags = from->client.flags; - - player.pev->deadflag = from->client.deadflag; - player.pev->waterlevel = from->client.waterlevel; - player.pev->maxspeed = from->client.maxspeed; - player.pev->fov = from->client.fov; - player.pev->weaponanim = from->client.weaponanim; - player.pev->viewmodel = from->client.viewmodel; - player.m_flNextAttack = from->client.m_flNextAttack; - player.m_flBackupTime = from->client.fuser1; - player.m_Activity = (Activity)(int)from->client.fuser2; - player.m_flThrowTime = from->client.fuser3; - - player.m_vecOldVelocity = from->client.vuser1; - - player.pev->sequence = from->playerstate.sequence; - player.pev->gaitsequence = from->playerstate.gaitsequence; - player.pev->angles = from->playerstate.angles; - - // Point to current weapon object - if ( from->client.m_iId ) - { - player.m_pActiveItem = g_pWpns[ from->client.m_iId ]; - } - - // Store pointer to our destination entity_state_t so we can get our origin, etc. from it - // for setting up events on the client - g_finalstate = to; - - // Don't go firing anything if we have died. - // Or if we don't have a weapon model deployed - if ( ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) && !CL_IsDead() && player.pev->viewmodel ) - { - if ( player.m_flNextAttack <= 0 ) - { - pWeapon->ItemPostFrame(); - } - } - - // If we are running events/etc. go ahead and see if we - // managed to die between last frame and this one - // If so, run the appropriate player killed or spawn function - if ( g_runfuncs ) - { - if ( to->client.health <= 0 && lasthealth > 0 ) - { - player.Killed( NULL, 0 ); - } - else if ( to->client.health > 0 && lasthealth <= 0 ) - { - player.Spawn(); - } - - lasthealth = to->client.health; - } - - // Fix up animations, etc. - player.PostThink(); - - // Assume that we are not going to switch weapons - to->client.m_iId = from->client.m_iId; - - // Now see if we issued a changeweapon command ( and we're not dead ) - if ( cmd->weaponselect && ( player.pev->deadflag != ( DEAD_DISCARDBODY + 1 ) ) ) - { - // Switched to a different weapon? - if ( from->weapondata[ cmd->weaponselect ].m_iId == cmd->weaponselect ) - { - CBasePlayerWeapon *pNew = g_pWpns[ cmd->weaponselect ]; - if ( pNew && ( pNew != pWeapon ) ) - { - // Put away old weapon - if (player.m_pActiveItem) - player.m_pActiveItem->Holster( ); - - player.m_pLastItem = player.m_pActiveItem; - player.m_pActiveItem = pNew; - - // Deploy new weapon - if (player.m_pActiveItem) - { - player.m_pActiveItem->Deploy( ); - } - - // Update weapon id so we can predict things correctly. - to->client.m_iId = cmd->weaponselect; - } - } - } - - // Copy in results of predcition code - to->client.viewmodel = player.pev->viewmodel; - to->client.fov = player.pev->fov; - to->client.weaponanim = player.pev->weaponanim; - to->client.m_flNextAttack = player.m_flNextAttack; - to->client.maxspeed = player.pev->maxspeed; - to->client.fuser1 = player.m_flBackupTime; - to->client.fuser2 = (float)(int)player.m_Activity; - to->client.fuser3 = player.m_flThrowTime; - - to->client.vuser1 = player.m_vecOldVelocity; - - to->playerstate.sequence = player.pev->sequence; - to->playerstate.gaitsequence = player.pev->gaitsequence; - - // Make sure that weapon animation matches what the game .dll is telling us - // over the wire ( fixes some animation glitches ) - if ( g_runfuncs && ( HUD_GetWeaponAnim() != to->client.weaponanim ) ) - { - int body = 2; - // Force a fixed anim down to viewmodel - HUD_SendWeaponAnim( to->client.weaponanim, body, 1 ); - } - - for ( i = 0; i < 32; i++ ) - { - pCurrent = g_pWpns[ i ]; - - pto = &to->weapondata[ i ]; - - if ( !pCurrent ) - { - memset( pto, 0, sizeof( weapon_data_t ) ); - continue; - } - - pto->m_fInReload = pCurrent->m_fInReload; - pto->m_iClip = pCurrent->m_iClip; - pto->m_flNextPrimaryAttack = pCurrent->m_flNextPrimaryAttack; - pto->m_flNextSecondaryAttack = pCurrent->m_flNextSecondaryAttack; - pto->m_flTimeWeaponIdle = pCurrent->m_flTimeWeaponIdle; - - // Decrement weapon counters, server does this at same time ( during post think, after doing everything else ) - pto->m_flNextReload -= cmd->msec / 1000.0; - pto->m_fNextAimBonus -= cmd->msec / 1000.0; - pto->m_flNextPrimaryAttack -= cmd->msec / 1000.0; - pto->m_flNextSecondaryAttack -= cmd->msec / 1000.0; - pto->m_flTimeWeaponIdle -= cmd->msec / 1000.0; - - if ( pto->m_flPumpTime != -9999 ) - { - pto->m_flPumpTime -= cmd->msec / 1000.0; - if ( pto->m_flPumpTime < -0.001 ) - pto->m_flPumpTime = -0.001; - } - - if ( pto->m_fNextAimBonus < -1.0 ) - { - pto->m_fNextAimBonus = -1.0; - } - - if ( pto->m_flNextPrimaryAttack < -1.0 ) - { - pto->m_flNextPrimaryAttack = -1.0; - } - - if ( pto->m_flNextSecondaryAttack < -0.001 ) - { - pto->m_flNextSecondaryAttack = -0.001; - } - - if ( pto->m_flTimeWeaponIdle < -0.001 ) - { - pto->m_flTimeWeaponIdle = -0.001; - } - - if ( pto->m_flNextReload < -0.001 ) - { - pto->m_flNextReload = -0.001; - } - } - - // m_flNextAttack is now part of the weapons, but is part of the player instead - to->client.m_flNextAttack -= cmd->msec / 1000.0; - if ( to->client.m_flNextAttack < -0.001 ) - { - to->client.m_flNextAttack = -0.001; - } - - to->client.fuser1 -= cmd->msec / 1000.0; - if ( to->client.fuser1 < -0.001 ) - { - to->client.fuser1 = -0.001; - } - - to->client.fuser3 -= cmd->msec / 1000.0; - if ( to->client.fuser3 < -0.001 ) - { - to->client.fuser3 = -0.001; - } - - // Wipe it so we can't use it after this frame - g_finalstate = NULL; -} - -/* -============================== -Ricochet_GetSequence - -============================== -*/ -void Ricochet_GetSequence( int *seq, int *gaitseq ) -{ - *seq = g_rseq; - *gaitseq = g_gaitseq; -} - -/* -============================== -Ricochet_SetSequence - -============================== -*/ -void Ricochet_SetSequence( int seq, int gaitseq ) -{ - g_rseq = seq; - g_gaitseq = gaitseq; -} - -/* -============================== -Ricochet_SetOrientation - -============================== -*/ -void Ricochet_SetOrientation( vec3_t o, vec3_t a ) -{ - g_clorg = o; - g_clang = a; -} - -/* -============================== -Ricochet_GetOrientation - -============================== -*/ -void Ricochet_GetOrientation( float *o, float *a ) -{ - int i; - - for ( i = 0; i < 3; i++ ) - { - o[ i ] = g_clorg[ i ]; - a[ i ] = g_clang[ i ]; - } -} - - -/* -===================== -HUD_PostRunCmd - -Client calls this during prediction, after it has moved the player and updated any info changed into to-> -time is the current client clock based on prediction -cmd is the command that caused the movement, etc -runfuncs is 1 if this is the first time we've predicted this command. If so, sounds and effects should play, otherwise, they should -be ignored -===================== -*/ -void EXPORT HUD_PostRunCmd( struct local_state_s *from, struct local_state_s *to, struct usercmd_s *cmd, int runfuncs, double time, unsigned int random_seed ) -{ - g_runfuncs = runfuncs; - - // We'll always do prediction of disc throwing - if ( cl_lw && cl_lw->value ) - { - // Allowed to fire? - if ( g_iCannotFire == FALSE ) - HUD_WeaponsPostThink( from, to, cmd, time, random_seed ); - } - else - { - to->client.fov = g_lastFOV; - } - - // Store of final sequence, etc. for client side animation - if ( g_runfuncs ) - { - Ricochet_SetSequence( to->playerstate.sequence, to->playerstate.gaitsequence ); - Ricochet_SetOrientation( to->playerstate.origin, cmd->viewangles ); - } - - // See if we stepped on a jump pad - Ricochet_CheckJumpPads( from, to ); - - // All games can use FOV state - g_lastFOV = to->client.fov; -} diff --git a/ricochet/cl_dll/hud.cpp b/ricochet/cl_dll/hud.cpp deleted file mode 100644 index a0e6da1..0000000 --- a/ricochet/cl_dll/hud.cpp +++ /dev/null @@ -1,590 +0,0 @@ - /*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// hud.cpp -// -// implementation of CHud class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" -#include "hud_servers.h" -#include "vgui_TeamFortressViewport.h" - -#include "demo.h" -#include "demo_api.h" - -#include "vgui_ScorePanel.h" - -extern TeamFortressViewport *gViewPort; - - -class CHLVoiceStatusHelper : public IVoiceStatusHelper -{ -public: - virtual void GetPlayerTextColor(int entindex, int color[3]) - { - color[0] = color[1] = color[2] = 255; - - /* if( entindex >= 0 && entindex < sizeof(g_PlayerExtraInfo)/sizeof(g_PlayerExtraInfo[0]) ) - { - int iTeam = g_PlayerExtraInfo[entindex].teamnumber; - - if ( iTeam < 0 ) - { - iTeam = 0; - } - - iTeam = iTeam % iNumberOfTeamColors; - - color[0] = iTeamColors[iTeam][0]; - color[1] = iTeamColors[iTeam][1]; - color[2] = iTeamColors[iTeam][2]; - }*/ - } - - virtual void UpdateCursorState() - { - gViewPort->UpdateCursorState(); - } - - virtual int GetAckIconHeight() - { - return ScreenHeight - gHUD.m_iFontHeight*3 - 6; - } - - virtual bool CanShowSpeakerLabels() - { - if( gViewPort && gViewPort->m_pScoreBoard ) - return !gViewPort->m_pScoreBoard->isVisible(); - else - return false; - } -}; -static CHLVoiceStatusHelper g_VoiceStatusHelper; - -extern client_sprite_t *GetSpriteList(client_sprite_t *pList, const char *psz, int iRes, int iCount); - -extern cvar_t *sensitivity; -cvar_t *cl_lw = NULL; - -void ShutdownInput (void); - -void __CmdFunc_ToggleServerBrowser( void ) -{ - if ( gViewPort ) - { - gViewPort->ToggleServerBrowser(); - } -} - -//DECLARE_MESSAGE(m_Logo, Logo) -int __MsgFunc_Logo(const char *pszName, int iSize, void *pbuf) -{ - return gHUD.MsgFunc_Logo(pszName, iSize, pbuf ); -} - -//DECLARE_MESSAGE(m_Logo, Logo) -int __MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf) -{ - return gHUD.MsgFunc_ResetHUD(pszName, iSize, pbuf ); -} - -int __MsgFunc_InitHUD(const char *pszName, int iSize, void *pbuf) -{ - gHUD.MsgFunc_InitHUD( pszName, iSize, pbuf ); - return 1; -} - -int __MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf) -{ - return gHUD.MsgFunc_SetFOV( pszName, iSize, pbuf ); -} - -int __MsgFunc_Concuss(const char *pszName, int iSize, void *pbuf) -{ - return gHUD.MsgFunc_Concuss( pszName, iSize, pbuf ); -} - -int __MsgFunc_GameMode(const char *pszName, int iSize, void *pbuf ) -{ - return gHUD.MsgFunc_GameMode( pszName, iSize, pbuf ); -} - -void __CmdFunc_OpenCommandMenu(void) -{ - if ( gViewPort ) - { - gViewPort->ShowCommandMenu(); - } -} - -void __CmdFunc_CloseCommandMenu(void) -{ - if ( gViewPort ) - { - gViewPort->InputSignalHideCommandMenu(); - } -} - -int __MsgFunc_StartRnd(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_StartRnd( pszName, iSize, pbuf ); - return 0; -} - -int __MsgFunc_EndRnd(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_EndRnd( pszName, iSize, pbuf ); - return 0; -} - -int __MsgFunc_ScoreInfo(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_ScoreInfo( pszName, iSize, pbuf ); - return 0; -} - -int __MsgFunc_TeamScore(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_TeamScore( pszName, iSize, pbuf ); - return 0; -} - -int __MsgFunc_TeamInfo(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_TeamInfo( pszName, iSize, pbuf ); - return 0; -} - -int __MsgFunc_Powerup(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_Powerup( pszName, iSize, pbuf ); - return 0; -} - -int __MsgFunc_Reward(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_Reward( pszName, iSize, pbuf ); - return 0; -} - -int __MsgFunc_Frozen(const char *pszName, int iSize, void *pbuf) -{ - if (gViewPort) - return gViewPort->MsgFunc_Frozen( pszName, iSize, pbuf ); - return 0; -} - -// This is called every time the DLL is loaded -void CHud :: Init( void ) -{ - HOOK_MESSAGE( Logo ); - HOOK_MESSAGE( ResetHUD ); - HOOK_MESSAGE( GameMode ); - HOOK_MESSAGE( InitHUD ); - HOOK_MESSAGE( SetFOV ); - HOOK_MESSAGE( Concuss ); - - HOOK_MESSAGE( ScoreInfo ); - HOOK_MESSAGE( TeamScore ); - HOOK_MESSAGE( TeamInfo ); - - // Discwar - HOOK_MESSAGE( StartRnd ); - HOOK_MESSAGE( EndRnd ); - HOOK_MESSAGE( Powerup ); - HOOK_MESSAGE( Reward ); - HOOK_MESSAGE( Frozen ); - - HOOK_COMMAND( "+commandmenu", OpenCommandMenu ); - HOOK_COMMAND( "-commandmenu", CloseCommandMenu ); - - m_iLogo = 0; - m_iFOV = 0; - - CVAR_CREATE( "zoom_sensitivity_ratio", "1.2", 0 ); - default_fov = CVAR_CREATE( "default_fov", "90", 0 ); - m_pCvarStealMouse = CVAR_CREATE( "hud_capturemouse", "1", FCVAR_ARCHIVE ); - cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); - - m_pSpriteList = NULL; - - // Clear any old HUD list - if ( m_pHudList ) - { - HUDLIST *pList; - while ( m_pHudList ) - { - pList = m_pHudList; - m_pHudList = m_pHudList->pNext; - free( pList ); - } - m_pHudList = NULL; - } - - // In case we get messages before the first update -- time will be valid - m_flTime = 1.0; - - m_Ammo.Init(); - m_Health.Init(); - m_Geiger.Init(); - m_Train.Init(); - m_Battery.Init(); - m_Flash.Init(); - m_Message.Init(); - m_StatusBar.Init(); - m_DeathNotice.Init(); - m_AmmoSecondary.Init(); - m_TextMessage.Init(); - m_StatusIcons.Init(); - - m_SayText.Init(); - m_Menu.Init(); - - GetClientVoiceMgr()->Init(&g_VoiceStatusHelper, (vgui::Panel **)&gViewPort); - - ServersInit(); - - MsgFunc_ResetHUD(0, 0, NULL ); -} - -// CHud destructor -// cleans up memory allocated for m_rg* arrays -CHud :: ~CHud() -{ - delete [] m_rghSprites; - delete [] m_rgrcRects; - delete [] m_rgszSpriteNames; - - if ( m_pHudList ) - { - HUDLIST *pList; - while ( m_pHudList ) - { - pList = m_pHudList; - m_pHudList = m_pHudList->pNext; - free( pList ); - } - m_pHudList = NULL; - } - - ServersShutdown(); -} - -// GetSpriteIndex() -// searches through the sprite list loaded from hud.txt for a name matching SpriteName -// returns an index into the gHUD.m_rghSprites[] array -// returns 0 if sprite not found -int CHud :: GetSpriteIndex( const char *SpriteName ) -{ - // look through the loaded sprite name list for SpriteName - for ( int i = 0; i < m_iSpriteCount; i++ ) - { - if ( strncmp( SpriteName, m_rgszSpriteNames + (i * MAX_SPRITE_NAME_LENGTH), MAX_SPRITE_NAME_LENGTH ) == 0 ) - return i; - } - - return -1; // invalid sprite -} - -void CHud :: VidInit( void ) -{ - m_scrinfo.iSize = sizeof(m_scrinfo); - GetScreenInfo(&m_scrinfo); - - // ---------- - // Load Sprites - // --------- -// m_hsprFont = LoadSprite("sprites/%d_font.spr"); - - m_hsprLogo = 0; - m_hsprCursor = 0; - - if (ScreenWidth < 640) - m_iRes = 320; - else - m_iRes = 640; - - // Only load this once - if ( !m_pSpriteList ) - { - // we need to load the hud.txt, and all sprites within - m_pSpriteList = SPR_GetList("sprites/hud.txt", &m_iSpriteCountAllRes); - - if (m_pSpriteList) - { - // count the number of sprites of the appropriate res - m_iSpriteCount = 0; - client_sprite_t *p = m_pSpriteList; - int j; - for ( j = 0; j < m_iSpriteCountAllRes; j++ ) - { - if ( p->iRes == m_iRes ) - m_iSpriteCount++; - p++; - } - - // allocated memory for sprite handle arrays - m_rghSprites = new HSPRITE[m_iSpriteCount]; - m_rgrcRects = new wrect_t[m_iSpriteCount]; - m_rgszSpriteNames = new char[m_iSpriteCount * MAX_SPRITE_NAME_LENGTH]; - - p = m_pSpriteList; - int index = 0; - for ( j = 0; j < m_iSpriteCountAllRes; j++ ) - { - if ( p->iRes == m_iRes ) - { - char sz[256]; - sprintf(sz, "sprites/%s.spr", p->szSprite); - m_rghSprites[index] = SPR_Load(sz); - m_rgrcRects[index] = p->rc; - strncpy( &m_rgszSpriteNames[index * MAX_SPRITE_NAME_LENGTH], p->szName, MAX_SPRITE_NAME_LENGTH ); - - index++; - } - - p++; - } - } - } - else - { - // we have already have loaded the sprite reference from hud.txt, but - // we need to make sure all the sprites have been loaded (we've gone through a transition, or loaded a save game) - client_sprite_t *p = m_pSpriteList; - int index = 0; - for ( int j = 0; j < m_iSpriteCountAllRes; j++ ) - { - if ( p->iRes == m_iRes ) - { - char sz[256]; - sprintf( sz, "sprites/%s.spr", p->szSprite ); - m_rghSprites[index] = SPR_Load(sz); - index++; - } - - p++; - } - } - - // assumption: number_1, number_2, etc, are all listed and loaded sequentially - m_HUD_number_0 = GetSpriteIndex( "number_0" ); - - m_iFontHeight = m_rgrcRects[m_HUD_number_0].bottom - m_rgrcRects[m_HUD_number_0].top; - - m_Ammo.VidInit(); - m_Health.VidInit(); - m_Geiger.VidInit(); - m_Train.VidInit(); - m_Battery.VidInit(); - m_Flash.VidInit(); - m_Message.VidInit(); - m_StatusBar.VidInit(); - m_DeathNotice.VidInit(); - m_SayText.VidInit(); - m_Menu.VidInit(); - m_AmmoSecondary.VidInit(); - m_TextMessage.VidInit(); - m_StatusIcons.VidInit(); - - GetClientVoiceMgr()->VidInit(); -} - -int CHud::MsgFunc_Logo(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - // update Train data - m_iLogo = READ_BYTE(); - - return 1; -} - -float g_lastFOV = 0.0; - -/* -============ -COM_FileBase -============ -*/ -// Extracts the base name of a file (no path, no extension, assumes '/' as path separator) -void COM_FileBase ( const char *in, char *out) -{ - int len, start, end; - - len = strlen( in ); - - // scan backward for '.' - end = len - 1; - while ( end && in[end] != '.' && in[end] != '/' && in[end] != '\\' ) - end--; - - if ( in[end] != '.' ) // no '.', copy to end - end = len-1; - else - end--; // Found ',', copy to left of '.' - - - // Scan backward for '/' - start = len-1; - while ( start >= 0 && in[start] != '/' && in[start] != '\\' ) - start--; - - if ( in[start] != '/' && in[start] != '\\' ) - start = 0; - else - start++; - - // Length of new sting - len = end - start + 1; - - // Copy partial string - strncpy( out, &in[start], len ); - // Terminate it - out[len] = 0; -} - -/* -================= -HUD_IsGame - -================= -*/ -int HUD_IsGame( const char *game ) -{ - const char *gamedir; - char gd[ 1024 ]; - - gamedir = gEngfuncs.pfnGetGameDirectory(); - if ( gamedir && gamedir[0] ) - { - COM_FileBase( gamedir, gd ); - if ( !stricmp( gd, game ) ) - return 1; - } - return 0; -} - -/* -===================== -HUD_GetFOV - -Returns last FOV -===================== -*/ -float HUD_GetFOV( void ) -{ -/* - if ( gEngfuncs.pDemoAPI->IsRecording() ) - { - // Write it - int i = 0; - unsigned char buf[ 100 ]; - - // Active - *( float * )&buf[ i ] = g_lastFOV; - i += sizeof( float ); - - Demo_WriteBuffer( TYPE_ZOOM, i, buf ); - } - - if ( gEngfuncs.pDemoAPI->IsPlayingback() ) - { - g_lastFOV = g_demozoom; - } -*/ - return g_lastFOV; -} - -int CHud::MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - int newfov = READ_BYTE(); - int def_fov = CVAR_GET_FLOAT( "default_fov" ); - - if ( newfov == 0 ) - { - m_iFOV = def_fov; - } - else - { - m_iFOV = newfov; - } - - // the clients fov is actually set in the client data update section of the hud - - // Set a new sensitivity - if ( m_iFOV == def_fov ) - { - // reset to saved sensitivity - m_flMouseSensitivity = 0; - } - else - { - // set a new sensitivity that is proportional to the change from the FOV default - m_flMouseSensitivity = sensitivity->value * ((float)newfov / (float)def_fov) * CVAR_GET_FLOAT("zoom_sensitivity_ratio"); - } - - return 1; -} - - -void CHud::AddHudElem(CHudBase *phudelem) -{ - HUDLIST *pdl, *ptemp; - -//phudelem->Think(); - - if (!phudelem) - return; - - pdl = (HUDLIST *)malloc(sizeof(HUDLIST)); - if (!pdl) - return; - - memset(pdl, 0, sizeof(HUDLIST)); - pdl->p = phudelem; - - if (!m_pHudList) - { - m_pHudList = pdl; - return; - } - - ptemp = m_pHudList; - - while (ptemp->pNext) - ptemp = ptemp->pNext; - - ptemp->pNext = pdl; -} - -float CHud::GetSensitivity( void ) -{ - return m_flMouseSensitivity; -} diff --git a/ricochet/cl_dll/hud.h b/ricochet/cl_dll/hud.h deleted file mode 100644 index 4d82c2b..0000000 --- a/ricochet/cl_dll/hud.h +++ /dev/null @@ -1,586 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// hud.h -// -// class CHud declaration -// -// CHud handles the message, calculation, and drawing the HUD -// - - -#define RGB_YELLOWISH 0x00FFA000 //255,160,0 -#define RGB_REDISH 0x00FF1010 //255,160,0 -#define RGB_GREENISH 0x0000A000 //0,160,0 - -#include "wrect.h" -#include "cl_dll.h" -#include "ammo.h" - -#define DHN_DRAWZERO 1 -#define DHN_2DIGITS 2 -#define DHN_3DIGITS 4 -#define MIN_ALPHA 100 - -#define HUDELEM_ACTIVE 1 - -typedef struct { - int x, y; -} POSITION; - -typedef struct { - unsigned char r,g,b,a; -} RGBA; - - -#define HUD_ACTIVE 1 -#define HUD_INTERMISSION 2 - -#define MAX_PLAYER_NAME_LENGTH 32 -#define MAX_MOTD_LENGTH 1024 - -#ifndef _WIN32 -#define _cdecl -#endif -// -//----------------------------------------------------- -// -class CHudBase -{ -public: - POSITION m_pos; - int m_type; - int m_iFlags; // active, moving, - virtual int Init( void ) {return 0;} - virtual int VidInit( void ) {return 0;} - virtual int Draw(float flTime) {return 0;} - virtual void Think(void) {return;} - virtual void Reset(void) {return;} - virtual void InitHUDData( void ) {} // called every time a server is connected to - -}; - -struct HUDLIST { - CHudBase *p; - HUDLIST *pNext; -}; - -#include "voice_status.h" - -// -//----------------------------------------------------- -// -class CHudAmmo: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - void Think(void); - void Reset(void); - int DrawWList(float flTime); - int MsgFunc_CurWeapon(const char *pszName, int iSize, void *pbuf); - int MsgFunc_WeaponList(const char *pszName, int iSize, void *pbuf); - int MsgFunc_AmmoX(const char *pszName, int iSize, void *pbuf); - int MsgFunc_AmmoPickup( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_WeapPickup( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_ItemPickup( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_HideWeapon( const char *pszName, int iSize, void *pbuf ); - - void _cdecl UserCmd_Slot1( void ); - void _cdecl UserCmd_Slot2( void ); - void _cdecl UserCmd_Slot3( void ); - void _cdecl UserCmd_Slot4( void ); - void _cdecl UserCmd_Slot5( void ); - void _cdecl UserCmd_Slot6( void ); - void _cdecl UserCmd_Slot7( void ); - void _cdecl UserCmd_Slot8( void ); - void _cdecl UserCmd_Slot9( void ); - void _cdecl UserCmd_Slot10( void ); - void _cdecl UserCmd_Close( void ); - void _cdecl UserCmd_NextWeapon( void ); - void _cdecl UserCmd_PrevWeapon( void ); - -private: - float m_fFade; - RGBA m_rgba; - WEAPON *m_pWeapon; - int m_HUD_bucket0; - int m_HUD_selection; - -}; - -// -//----------------------------------------------------- -// - -class CHudAmmoSecondary: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - void Reset( void ); - int Draw(float flTime); - - int MsgFunc_SecAmmoVal( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_SecAmmoIcon( const char *pszName, int iSize, void *pbuf ); - -private: - enum { - MAX_SEC_AMMO_VALUES = 4 - }; - - int m_HUD_ammoicon; // sprite indices - int m_iAmmoAmounts[MAX_SEC_AMMO_VALUES]; - float m_fFade; -}; - - -#include "health.h" - - -#define FADE_TIME 100 - - -// -//----------------------------------------------------- -// -class CHudGeiger: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - int MsgFunc_Geiger(const char *pszName, int iSize, void *pbuf); - -private: - int m_iGeigerRange; - -}; - -// -//----------------------------------------------------- -// -class CHudTrain: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - int MsgFunc_Train(const char *pszName, int iSize, void *pbuf); - -private: - HSPRITE m_hSprite; - int m_iPos; - -}; - -// -//----------------------------------------------------- -// -class CHudStatusBar : public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw( float flTime ); - void Reset( void ); - void ParseStatusString( int line_num ); - - int MsgFunc_StatusText( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_StatusValue( const char *pszName, int iSize, void *pbuf ); - -protected: - enum { - MAX_STATUSTEXT_LENGTH = 128, - MAX_STATUSBAR_VALUES = 8, - MAX_STATUSBAR_LINES = 2, - }; - - char m_szStatusText[MAX_STATUSBAR_LINES][MAX_STATUSTEXT_LENGTH]; // a text string describing how the status bar is to be drawn - char m_szStatusBar[MAX_STATUSBAR_LINES][MAX_STATUSTEXT_LENGTH]; // the constructed bar that is drawn - int m_iStatusValues[MAX_STATUSBAR_VALUES]; // an array of values for use in the status bar - - int m_bReparseString; // set to TRUE whenever the m_szStatusBar needs to be recalculated -}; - -// -//----------------------------------------------------- -// -enum -{ - MAX_PLAYERS = 64, - MAX_TEAMS = 64, - MAX_TEAM_NAME = 16, -}; - -struct extra_player_info_t -{ - short frags; - short deaths; - short playerclass; - short teamnumber; - char teamname[MAX_TEAM_NAME]; -}; - -struct team_info_t -{ - char name[MAX_TEAM_NAME]; - short frags; - short deaths; - short ping; - short packetloss; - short ownteam; - short players; - int already_drawn; - int scores_overriden; - int teamnumber; -}; - -extern hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine -extern extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll -extern team_info_t g_TeamInfo[MAX_TEAMS+1]; -extern int g_IsSpectator[MAX_PLAYERS+1]; - - -// -//----------------------------------------------------- -// -class CHudDeathNotice : public CHudBase -{ -public: - int Init( void ); - void InitHUDData( void ); - int VidInit( void ); - int Draw( float flTime ); - int MsgFunc_DeathMsg( const char *pszName, int iSize, void *pbuf ); - -private: - int m_HUD_d_skull; // sprite index of skull icon -}; - -// -//----------------------------------------------------- -// -class CHudMenu : public CHudBase -{ -public: - int Init( void ); - void InitHUDData( void ); - int VidInit( void ); - void Reset( void ); - int Draw( float flTime ); - int MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf ); - - void SelectMenuItem( int menu_item ); - - int m_fMenuDisplayed; - int m_bitsValidSlots; - float m_flShutoffTime; - int m_fWaitingForMore; -}; - -// -//----------------------------------------------------- -// -class CHudSayText : public CHudBase -{ -public: - int Init( void ); - void InitHUDData( void ); - int VidInit( void ); - int Draw( float flTime ); - int MsgFunc_SayText( const char *pszName, int iSize, void *pbuf ); - void SayTextPrint( const char *pszBuf, int iBufSize, int clientIndex = -1 ); - void EnsureTextFitsInOneLineAndWrapIfHaveTo( int line ); -}; - -// -//----------------------------------------------------- -// -class CHudBattery: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - int MsgFunc_Battery(const char *pszName, int iSize, void *pbuf ); - -private: - HSPRITE m_hSprite1; - HSPRITE m_hSprite2; - wrect_t *m_prc1; - wrect_t *m_prc2; - int m_iBat; - float m_fFade; - int m_iHeight; // width of the battery innards -}; - - -// -//----------------------------------------------------- -// -class CHudFlashlight: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - void Reset( void ); - int MsgFunc_Flashlight(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_FlashBat(const char *pszName, int iSize, void *pbuf ); - -private: - HSPRITE m_hSprite1; - HSPRITE m_hSprite2; - HSPRITE m_hBeam; - wrect_t *m_prc1; - wrect_t *m_prc2; - wrect_t *m_prcBeam; - float m_flBat; - int m_iBat; - int m_fOn; - float m_fFade; - int m_iWidth; // width of the battery innards -}; - -// -//----------------------------------------------------- -// -const int maxHUDMessages = 16; -struct message_parms_t -{ - client_textmessage_t *pMessage; - float time; - int x, y; - int totalWidth, totalHeight; - int width; - int lines; - int lineLength; - int length; - int r, g, b; - int text; - int fadeBlend; - float charTime; - float fadeTime; -}; - -// -//----------------------------------------------------- -// - -class CHudTextMessage: public CHudBase -{ -public: - int Init( void ); - static char *LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size ); - static char *BufferedLocaliseTextString( const char *msg ); - char *LookupString( const char *msg_name, int *msg_dest = NULL ); - int MsgFunc_TextMsg(const char *pszName, int iSize, void *pbuf); -}; - -// -//----------------------------------------------------- -// - -class CHudMessage: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - int Draw(float flTime); - int MsgFunc_HudText(const char *pszName, int iSize, void *pbuf); - int MsgFunc_GameTitle(const char *pszName, int iSize, void *pbuf); - - float FadeBlend( float fadein, float fadeout, float hold, float localTime ); - int XPosition( float x, int width, int lineWidth ); - int YPosition( float y, int height ); - - void MessageAdd( const char *pName, float time ); - void MessageDrawScan( client_textmessage_t *pMessage, float time ); - void MessageScanStart( void ); - void MessageScanNextChar( void ); - void Reset( void ); - -private: - client_textmessage_t *m_pMessages[maxHUDMessages]; - float m_startTime[maxHUDMessages]; - message_parms_t m_parms; - float m_gameTitleTime; - client_textmessage_t *m_pGameTitle; - - int m_HUD_title_life; - int m_HUD_title_half; -}; - -// -//----------------------------------------------------- -// -#define MAX_SPRITE_NAME_LENGTH 24 - -class CHudStatusIcons: public CHudBase -{ -public: - int Init( void ); - int VidInit( void ); - void Reset( void ); - int Draw(float flTime); - int MsgFunc_StatusIcon(const char *pszName, int iSize, void *pbuf); - - enum { - MAX_ICONSPRITENAME_LENGTH = MAX_SPRITE_NAME_LENGTH, - MAX_ICONSPRITES = 4, - }; - - - //had to make these public so CHud could access them (to enable concussion icon) - //could use a friend declaration instead... - void EnableIcon( char *pszIconName, unsigned char red, unsigned char green, unsigned char blue ); - void DisableIcon( char *pszIconName ); - -private: - - typedef struct - { - char szSpriteName[MAX_ICONSPRITENAME_LENGTH]; - HSPRITE spr; - wrect_t rc; - unsigned char r, g, b; - } icon_sprite_t; - - icon_sprite_t m_IconList[MAX_ICONSPRITES]; - -}; - - -// -//----------------------------------------------------- -// -typedef struct cvar_s cvar_t; - -class CHud -{ -private: - HUDLIST *m_pHudList; - HSPRITE m_hsprLogo; - int m_iLogo; - client_sprite_t *m_pSpriteList; - int m_iSpriteCount; - int m_iSpriteCountAllRes; - float m_flMouseSensitivity; - int m_iConcussionEffect; - -public: - - HSPRITE m_hsprCursor; - float m_flTime; // the current client time - float m_fOldTime; // the time at which the HUD was last redrawn - double m_flTimeDelta; // the difference between flTime and fOldTime - Vector m_vecOrigin; - Vector m_vecAngles; - int m_iKeyBits; - int m_iHideHUDDisplay; - int m_iFOV; - int m_Teamplay; - int m_iRes; - cvar_t *m_pCvarStealMouse; - - int m_iFontHeight; - int DrawHudNumber(int x, int y, int iFlags, int iNumber, int r, int g, int b ); - int DrawHudString(int x, int y, int iMaxX, char *szString, int r, int g, int b ); - int DrawHudStringReverse( int xpos, int ypos, int iMinX, char *szString, int r, int g, int b ); - int DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r, int g, int b ); - int GetNumWidth(int iNumber, int iFlags); - -private: - // the memory for these arrays are allocated in the first call to CHud::VidInit(), when the hud.txt and associated sprites are loaded. - // freed in ~CHud() - HSPRITE *m_rghSprites; /*[HUD_SPRITE_COUNT]*/ // the sprites loaded from hud.txt - wrect_t *m_rgrcRects; /*[HUD_SPRITE_COUNT]*/ - char *m_rgszSpriteNames; /*[HUD_SPRITE_COUNT][MAX_SPRITE_NAME_LENGTH]*/ - - struct cvar_s *default_fov; -public: - HSPRITE GetSprite( int index ) - { - return (index < 0) ? 0 : m_rghSprites[index]; - } - - wrect_t& GetSpriteRect( int index ) - { - return m_rgrcRects[index]; - } - - - int GetSpriteIndex( const char *SpriteName ); // gets a sprite index, for use in the m_rghSprites[] array - - CHudAmmo m_Ammo; - CHudHealth m_Health; - CHudGeiger m_Geiger; - CHudBattery m_Battery; - CHudTrain m_Train; - CHudFlashlight m_Flash; - CHudMessage m_Message; - CHudStatusBar m_StatusBar; - CHudDeathNotice m_DeathNotice; - CHudSayText m_SayText; - CHudMenu m_Menu; - CHudAmmoSecondary m_AmmoSecondary; - CHudTextMessage m_TextMessage; - CHudStatusIcons m_StatusIcons; - - void Init( void ); - void VidInit( void ); - void Think(void); - int Redraw( float flTime, int intermission ); - int UpdateClientData( client_data_t *cdata, float time ); - - CHud() : m_iSpriteCount(0), m_pHudList(NULL) {} - ~CHud(); // destructor, frees allocated memory - - // user messages - int _cdecl MsgFunc_Damage(const char *pszName, int iSize, void *pbuf ); - int _cdecl MsgFunc_GameMode(const char *pszName, int iSize, void *pbuf ); - int _cdecl MsgFunc_Logo(const char *pszName, int iSize, void *pbuf); - int _cdecl MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf); - void _cdecl MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf ); - int _cdecl MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf); - int _cdecl MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf ); - // Screen information - SCREENINFO m_scrinfo; - - int m_iWeaponBits; - int m_fPlayerDead; - int m_iIntermission; - - // sprite indexes - int m_HUD_number_0; - - - void AddHudElem(CHudBase *p); - - float GetSensitivity(); -}; - -extern CHud gHUD; - -class TeamFortressViewport; - -extern TeamFortressViewport *gViewPort; - -extern int g_iPlayerClass; -extern int g_iTeamNumber; -extern int g_iUser1; -extern int g_iUser2; diff --git a/ricochet/cl_dll/hud_iface.h b/ricochet/cl_dll/hud_iface.h deleted file mode 100644 index 060db69..0000000 --- a/ricochet/cl_dll/hud_iface.h +++ /dev/null @@ -1,26 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#if !defined( HUD_IFACEH ) -#define HUD_IFACEH -#pragma once - -#include "Platform.h" - -typedef int (*pfnUserMsgHook)(const char *pszName, int iSize, void *pbuf); -#include "wrect.h" -#include "../engine/cdll_int.h" -extern cl_enginefunc_t gEngfuncs; - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/hud_msg.cpp b/ricochet/cl_dll/hud_msg.cpp deleted file mode 100644 index 0c83bd3..0000000 --- a/ricochet/cl_dll/hud_msg.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// hud_msg.cpp -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include "vgui_int.h" -#include "vgui_TeamFortressViewport.h" -#include "vgui_discobjects.h" - -/// USER-DEFINED SERVER MESSAGE HANDLERS - -int g_iArenaMode = 0; - -int CHud :: MsgFunc_ResetHUD(const char *pszName, int iSize, void *pbuf ) -{ - ASSERT( iSize == 0 ); - - // clear all hud data - HUDLIST *pList = m_pHudList; - - while ( pList ) - { - if ( pList->p ) - pList->p->Reset(); - pList = pList->pNext; - } - - // reset sensitivity - m_flMouseSensitivity = 0; - - // reset concussion effect - m_iConcussionEffect = 0; - - return 1; -} - -void CHud :: MsgFunc_InitHUD( const char *pszName, int iSize, void *pbuf ) -{ - // prepare all hud data - HUDLIST *pList = m_pHudList; - - while (pList) - { - if ( pList->p ) - pList->p->InitHUDData(); - pList = pList->pNext; - } -} - - -int CHud :: MsgFunc_GameMode(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - g_iArenaMode = READ_BYTE(); - - if (gViewPort) - { - gViewPort->m_pDiscEndRound->setVisible( false ); - gViewPort->m_pDiscStartRound->setVisible ( false ); - } - - return 1; -} - - -int CHud :: MsgFunc_Damage(const char *pszName, int iSize, void *pbuf ) -{ - int armor, blood; - Vector from; - int i; - float count; - - BEGIN_READ( pbuf, iSize ); - armor = READ_BYTE(); - blood = READ_BYTE(); - - for (i=0 ; i<3 ; i++) - from[i] = READ_COORD(); - - count = (blood * 0.5) + (armor * 0.5); - - if (count < 10) - count = 10; - - // TODO: kick viewangles, show damage visually - - return 1; -} - -int CHud :: MsgFunc_Concuss( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - m_iConcussionEffect = READ_BYTE(); - if (m_iConcussionEffect) - this->m_StatusIcons.EnableIcon("dmg_concuss",255,160,0); - else - this->m_StatusIcons.DisableIcon("dmg_concuss"); - return 1; -} - diff --git a/ricochet/cl_dll/hud_redraw.cpp b/ricochet/cl_dll/hud_redraw.cpp deleted file mode 100644 index 4cd779d..0000000 --- a/ricochet/cl_dll/hud_redraw.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// hud_redraw.cpp -// -#include -#include "hud.h" -#include "cl_util.h" - - -#define MAX_LOGO_FRAMES 56 - -int grgLogoFrame[MAX_LOGO_FRAMES] = -{ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 12, 11, 10, 9, 8, 14, 15, - 16, 17, 18, 19, 20, 20, 20, 20, 20, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 29, 29, 29, 29, 29, 28, 27, 26, 25, 24, 30, 31 -}; - -extern int g_iVisibleMouse; - -// Think -void CHud::Think(void) -{ - m_scrinfo.iSize = sizeof(m_scrinfo); - GetScreenInfo(&m_scrinfo); - - HUDLIST *pList = m_pHudList; - while (pList) - { - if (pList->p->m_iFlags & HUD_ACTIVE) - pList->p->Think(); - pList = pList->pNext; - } - - // think about default fov - if ( m_iFOV == 0 ) - { // only let players adjust up in fov, and only if they are not overriden by something else - m_iFOV = V_max( default_fov->value, 90 ); - } -} - -// Redraw -// step through the local data, placing the appropriate graphics & text as appropriate -// returns 1 if they've changed, 0 otherwise -int CHud :: Redraw( float flTime, int intermission ) -{ - m_fOldTime = m_flTime; // save time of previous redraw - m_flTime = flTime; - m_flTimeDelta = (double)m_flTime - m_fOldTime; - - // Clock was reset, reset delta - if ( m_flTimeDelta < 0 ) - m_flTimeDelta = 0; - - m_iIntermission = intermission; - - // if no redrawing is necessary - // return 0; - - HUDLIST *pList = m_pHudList; - - while (pList) - { - if ( !intermission ) - { - if ((pList->p->m_iFlags & HUD_ACTIVE) && !(m_iHideHUDDisplay & HIDEHUD_ALL)) - pList->p->Draw(flTime); - } - else - { // it's an intermission, so only draw hud elements that are set to draw during intermissions - if ( pList->p->m_iFlags & HUD_INTERMISSION ) - pList->p->Draw( flTime ); - } - - pList = pList->pNext; - } - - // are we in demo mode? do we need to draw the logo in the top corner? - if (m_iLogo) - { - int x, y, i; - - if (m_hsprLogo == 0) - m_hsprLogo = LoadSprite("sprites/%d_logo.spr"); - - SPR_Set(m_hsprLogo, 250, 250, 250 ); - - x = SPR_Width(m_hsprLogo, 0); - x = ScreenWidth - x; - y = SPR_Height(m_hsprLogo, 0)/2; - - // Draw the logo at 20 fps - int iFrame = (int)(flTime * 20) % MAX_LOGO_FRAMES; - i = grgLogoFrame[iFrame] - 1; - - SPR_DrawAdditive(i, x, y, NULL); - } - - return 1; -} - -void ScaleColors( int &r, int &g, int &b, int a ) -{ - float x = (float)a / 255; - r = (int)(r * x); - g = (int)(g * x); - b = (int)(b * x); -} - -int CHud :: DrawHudString(int xpos, int ypos, int iMaxX, char *szIt, int r, int g, int b ) -{ - // draw the string until we hit the null character or a newline character - for ( ; *szIt != 0 && *szIt != '\n'; szIt++ ) - { - int next = xpos + gHUD.m_scrinfo.charWidths[ *szIt ]; // variable-width fonts look cool - if ( next > iMaxX ) - return xpos; - - TextMessageDrawChar( xpos, ypos, *szIt, r, g, b ); - xpos = next; - } - - return xpos; -} - -int CHud :: DrawHudNumberString( int xpos, int ypos, int iMinX, int iNumber, int r, int g, int b ) -{ - char szString[32]; - sprintf( szString, "%d", iNumber ); - return DrawHudStringReverse( xpos, ypos, iMinX, szString, r, g, b ); - -} - -// draws a string from right to left (right-aligned) -int CHud :: DrawHudStringReverse( int xpos, int ypos, int iMinX, char *szString, int r, int g, int b ) -{ - // find the end of the string - char *szIt; - for ( szIt = szString; *szIt != 0; szIt++ ) - { // we should count the length? - } - - // iterate throug the string in reverse - for ( szIt--; szIt != (szString-1); szIt-- ) - { - int next = xpos - gHUD.m_scrinfo.charWidths[ *szIt ]; // variable-width fonts look cool - if ( next < iMinX ) - return xpos; - xpos = next; - - TextMessageDrawChar( xpos, ypos, *szIt, r, g, b ); - } - - return xpos; -} - -int CHud :: DrawHudNumber( int x, int y, int iFlags, int iNumber, int r, int g, int b) -{ - int iWidth = GetSpriteRect(m_HUD_number_0).right - GetSpriteRect(m_HUD_number_0).left; - int k; - - if (iNumber > 0) - { - // SPR_Draw 100's - if (iNumber >= 100) - { - k = iNumber/100; - SPR_Set(GetSprite(m_HUD_number_0 + k), r, g, b ); - SPR_DrawAdditive( 0, x, y, &GetSpriteRect(m_HUD_number_0 + k)); - x += iWidth; - } - else if (iFlags & (DHN_3DIGITS)) - { - //SPR_DrawAdditive( 0, x, y, &rc ); - x += iWidth; - } - - // SPR_Draw 10's - if (iNumber >= 10) - { - k = (iNumber % 100)/10; - SPR_Set(GetSprite(m_HUD_number_0 + k), r, g, b ); - SPR_DrawAdditive( 0, x, y, &GetSpriteRect(m_HUD_number_0 + k)); - x += iWidth; - } - else if (iFlags & (DHN_3DIGITS | DHN_2DIGITS)) - { - //SPR_DrawAdditive( 0, x, y, &rc ); - x += iWidth; - } - - // SPR_Draw ones - k = iNumber % 10; - SPR_Set(GetSprite(m_HUD_number_0 + k), r, g, b ); - SPR_DrawAdditive(0, x, y, &GetSpriteRect(m_HUD_number_0 + k)); - x += iWidth; - } - else if (iFlags & DHN_DRAWZERO) - { - SPR_Set(GetSprite(m_HUD_number_0), r, g, b ); - - // SPR_Draw 100's - if (iFlags & (DHN_3DIGITS)) - { - //SPR_DrawAdditive( 0, x, y, &rc ); - x += iWidth; - } - - if (iFlags & (DHN_3DIGITS | DHN_2DIGITS)) - { - //SPR_DrawAdditive( 0, x, y, &rc ); - x += iWidth; - } - - // SPR_Draw ones - - SPR_DrawAdditive( 0, x, y, &GetSpriteRect(m_HUD_number_0)); - x += iWidth; - } - - return x; -} - - -int CHud::GetNumWidth( int iNumber, int iFlags ) -{ - if (iFlags & (DHN_3DIGITS)) - return 3; - - if (iFlags & (DHN_2DIGITS)) - return 2; - - if (iNumber <= 0) - { - if (iFlags & (DHN_DRAWZERO)) - return 1; - else - return 0; - } - - if (iNumber < 10) - return 1; - - if (iNumber < 100) - return 2; - - return 3; - -} - - diff --git a/ricochet/cl_dll/hud_servers.cpp b/ricochet/cl_dll/hud_servers.cpp deleted file mode 100644 index 2050d09..0000000 --- a/ricochet/cl_dll/hud_servers.cpp +++ /dev/null @@ -1,1249 +0,0 @@ -// hud_servers.cpp -#include "hud.h" -#include "cl_util.h" -#include "hud_servers_priv.h" -#include "hud_servers.h" -#include "net_api.h" -#include -#ifdef _WIN32 -#include "winsani_in.h" -#include -#include "winsani_out.h" -#else -#include -#endif -static int context_id; - -// Default master server address in case we can't read any from valvecomm.lst file -#define VALVE_MASTER_ADDRESS "half-life.east.won.net" -#define PORT_MASTER 27010 -#define PORT_SERVER 27015 - -// File where we really should look for master servers -#define MASTER_PARSE_FILE "valvecomm.lst" - -#define MAX_QUERIES 20 - -#define NET_API gEngfuncs.pNetAPI - -static CHudServers *g_pServers = NULL; - -/* -=================== -ListResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK ListResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->ListResponse( response ); - } -} - -/* -=================== -ServerResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK ServerResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->ServerResponse( response ); - } -} - -/* -=================== -PingResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK PingResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->PingResponse( response ); - } -} - -/* -=================== -RulesResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK RulesResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->RulesResponse( response ); - } -} -/* -=================== -PlayersResponse - -Callback from engine -=================== -*/ -void NET_CALLBACK PlayersResponse( struct net_response_s *response ) -{ - if ( g_pServers ) - { - g_pServers->PlayersResponse( response ); - } -} -/* -=================== -ListResponse - -=================== -*/ -void CHudServers::ListResponse( struct net_response_s *response ) -{ - request_t *list; - request_t *p; - int c = 0; - - if ( !( response->error == NET_SUCCESS ) ) - return; - - if ( response->type != NETAPI_REQUEST_SERVERLIST ) - return; - - if ( response->response ) - { - list = ( request_t * ) response->response; - while ( list ) - { - c++; - - //if ( c < 40 ) - { - // Copy from parsed stuff - p = new request_t; - p->context = -1; - p->remote_address = list->remote_address; - p->next = m_pServerList; - m_pServerList = p; - } - - // Move on - list = list->next; - } - } - - gEngfuncs.Con_Printf( "got list\n" ); - - m_nQuerying = 1; - m_nActiveQueries = 0; -} - -/* -=================== -ServerResponse - -=================== -*/ -void CHudServers::ServerResponse( struct net_response_s *response ) -{ - char *szresponse; - request_t *p; - server_t *browser; - int len; - char sz[ 32 ]; - - // Remove from active list - p = FindRequest( response->context, m_pActiveList ); - if ( p ) - { - static int first = 0; - - RemoveServerFromList( &m_pActiveList, p ); - m_nActiveQueries--; - - if ( !first ) - { - gEngfuncs.Con_Printf( "recv first %f\n", gEngfuncs.GetClientTime() ); - first = 1; - } - } - - - if ( response->error != NET_SUCCESS ) - return; - - switch ( response->type ) - { - case NETAPI_REQUEST_DETAILS: - if ( response->response ) - { - szresponse = (char *)response->response; - len = strlen( szresponse ) + 100 + 1; - sprintf( sz, "%i", (int)( 1000.0 * response->ping ) ); - - browser = new server_t; - browser->remote_address = response->remote_address; - browser->info = new char[ len ]; - browser->ping = (int)( 1000.0 * response->ping ); - strcpy( browser->info, szresponse ); - - NET_API->SetValueForKey( browser->info, "address", gEngfuncs.pNetAPI->AdrToString( &response->remote_address ), len ); - NET_API->SetValueForKey( browser->info, "ping", sz, len ); - - AddServer( &m_pServers, browser ); - } - break; - default: - break; - } -} - -/* -=================== -PingResponse - -=================== -*/ -void CHudServers::PingResponse( struct net_response_s *response ) -{ - char sz[ 32 ]; - - if ( response->error != NET_SUCCESS ) - return; - - switch ( response->type ) - { - case NETAPI_REQUEST_PING: - sprintf( sz, "%.2f", 1000.0 * response->ping ); - - gEngfuncs.Con_Printf( "ping == %s\n", sz ); - break; - default: - break; - } -} - -/* -=================== -RulesResponse - -=================== -*/ -void CHudServers::RulesResponse( struct net_response_s *response ) -{ - char *szresponse; - - if ( response->error != NET_SUCCESS ) - return; - - switch ( response->type ) - { - case NETAPI_REQUEST_RULES: - if ( response->response ) - { - szresponse = (char *)response->response; - - gEngfuncs.Con_Printf( "rules %s\n", szresponse ); - } - break; - default: - break; - } -} - -/* -=================== -PlayersResponse - -=================== -*/ -void CHudServers::PlayersResponse( struct net_response_s *response ) -{ - char *szresponse; - - if ( response->error != NET_SUCCESS ) - return; - - switch ( response->type ) - { - case NETAPI_REQUEST_PLAYERS: - if ( response->response ) - { - szresponse = (char *)response->response; - - gEngfuncs.Con_Printf( "players %s\n", szresponse ); - } - break; - default: - break; - } -} - -/* -=================== -CompareServers - -Return 1 if p1 is "less than" p2, 0 otherwise -=================== -*/ -int CHudServers::CompareServers( server_t *p1, server_t *p2 ) -{ - const char *n1, *n2; - - if ( p1->ping < p2->ping ) - return 1; - - if ( p1->ping == p2->ping ) - { - // Pings equal, sort by second key: hostname - if ( p1->info && p2->info ) - { - n1 = NET_API->ValueForKey( p1->info, "hostname" ); - n2 = NET_API->ValueForKey( p2->info, "hostname" ); - - if ( n1 && n2 ) - { - if ( stricmp( n1, n2 ) < 0 ) - return 1; - } - } - } - - return 0; -} - -/* -=================== -AddServer - -=================== -*/ -void CHudServers::AddServer( server_t **ppList, server_t *p ) -{ -server_t *list; - - if ( !ppList || ! p ) - return; - - m_nServerCount++; - - // What sort key? Ping? - list = *ppList; - - // Head of list? - if ( !list ) - { - p->next = NULL; - *ppList = p; - return; - } - - // Put on head of list - if ( CompareServers( p, list ) ) - { - p->next = *ppList; - *ppList = p; - } - else - { - while ( list->next ) - { - // Insert before list next - if ( CompareServers( p, list->next ) ) - { - p->next = list->next->next; - list->next = p; - return; - } - - list = list->next; - } - - // Just add at end - p->next = NULL; - list->next = p; - } -} - -/* -=================== -Think - -=================== -*/ -void CHudServers::Think( double time ) -{ - m_fElapsed += time; - - if ( !m_nRequesting ) - return; - - if ( !m_nQuerying ) - return; - - QueryThink(); - - if ( ServerListSize() > 0 ) - return; - - m_dStarted = 0.0; - m_nRequesting = 0; - m_nDone = 0; - m_nQuerying = 0; - m_nActiveQueries = 0; -} - -/* -=================== -QueryThink - -=================== -*/ -void CHudServers::QueryThink( void ) -{ - request_t *p; - - if ( !m_nRequesting || m_nDone ) - return; - - if ( !m_nQuerying ) - return; - - if ( m_nActiveQueries > MAX_QUERIES ) - return; - - // Nothing left - if ( !m_pServerList ) - return; - - while ( 1 ) - { - static int first = 0; - p = m_pServerList; - - // No more in list? - if ( !p ) - break; - - // Move to next - m_pServerList = m_pServerList->next; - - // Setup context_id - p->context = context_id; - - // Make sure networking system has started. - // NET_API->InitNetworking(); - - if ( !first ) - { - gEngfuncs.Con_Printf( "send first %f\n", gEngfuncs.GetClientTime() ); - first = 1; - } - - // Start up query on this one - NET_API->SendRequest( context_id++, NETAPI_REQUEST_DETAILS, 0, 2.0, &p->remote_address, ::ServerResponse ); - - // Increment active list - m_nActiveQueries++; - - // Add to active list - p->next = m_pActiveList; - m_pActiveList = p; - - // Too many active? - if ( m_nActiveQueries > MAX_QUERIES ) - break; - } -} - -/* -================== -ServerListSize - -# of servers in active query and in pending to be queried lists -================== -*/ -int CHudServers::ServerListSize( void ) -{ - int c = 0; - request_t *p; - - p = m_pServerList; - while ( p ) - { - c++; - p = p->next; - } - - p = m_pActiveList; - while ( p ) - { - c++; - p = p->next; - } - - return c; -} - -/* -=================== -FindRequest - -Look up a request by context id -=================== -*/ -CHudServers::request_t *CHudServers::FindRequest( int context, request_t *pList ) -{ - request_t *p; - p = pList; - while ( p ) - { - if ( context == p->context ) - return p; - - p = p->next; - } - return NULL; -} - -/* -=================== -RemoveServerFromList - -Remote, but don't delete, item from *ppList -=================== -*/ -void CHudServers::RemoveServerFromList( request_t **ppList, request_t *item ) -{ - request_t *p, *n; - request_t *newlist = NULL; - - if ( !ppList ) - return; - - p = *ppList; - while ( p ) - { - n = p->next; - if ( p != item ) - { - p->next = newlist; - newlist = p; - } - p = n; - } - *ppList = newlist; -} - -/* -=================== -ClearRequestList - -=================== -*/ -void CHudServers::ClearRequestList( request_t **ppList ) -{ - request_t *p, *n; - - if ( !ppList ) - return; - - p = *ppList; - while ( p ) - { - n = p->next; - delete p; - p = n; - } - *ppList = NULL; -} - -/* -=================== -ClearServerList - -=================== -*/ -void CHudServers::ClearServerList( server_t **ppList ) -{ - server_t *p, *n; - - if ( !ppList ) - return; - - p = *ppList; - while ( p ) - { - n = p->next; - delete[] p->info; - delete p; - p = n; - } - *ppList = NULL; -} - -int CompareField( CHudServers::server_t *p1, CHudServers::server_t *p2, const char *fieldname, int iSortOrder ) -{ - const char *sz1, *sz2; - float fv1, fv2; - - sz1 = NET_API->ValueForKey( p1->info, fieldname ); - sz2 = NET_API->ValueForKey( p2->info, fieldname ); - - fv1 = atof( sz1 ); - fv2 = atof( sz2 ); - - if ( fv1 && fv2 ) - { - if ( fv1 > fv2 ) - return iSortOrder; - else if ( fv1 < fv2 ) - return -iSortOrder; - else - return 0; - } - - // String compare - return stricmp( sz1, sz2 ); -} - -int ServerListCompareFunc( CHudServers::server_t *p1, CHudServers::server_t *p2, const char *fieldname ) -{ - if (!p1 || !p2) // No meaningful comparison - return 0; - - int iSortOrder = 1; - - int retval = 0; - - retval = CompareField( p1, p2, fieldname, iSortOrder ); - - return retval; -} -#ifndef _WIN32 -#define __cdecl -#endif -static char g_fieldname[ 256 ]; -int __cdecl FnServerCompare(const void *elem1, const void *elem2 ) -{ - CHudServers::server_t *list1, *list2; - - list1 = *(CHudServers::server_t **)elem1; - list2 = *(CHudServers::server_t **)elem2; - - return ServerListCompareFunc( list1, list2, g_fieldname ); -} - -void CHudServers::SortServers( const char *fieldname ) -{ - server_t *p; - // Create a list - if ( !m_pServers ) - return; - - strcpy( g_fieldname, fieldname ); - - int i; - int c = 0; - - p = m_pServers; - while ( p ) - { - c++; - p = p->next; - } - - server_t **pSortArray; - - pSortArray = new server_t *[ c ]; - memset( pSortArray, 0, c * sizeof( server_t * ) ); - - // Now copy the list into the pSortArray: - p = m_pServers; - i = 0; - while ( p ) - { - pSortArray[ i++ ] = p; - p = p->next; - } - - // Now do that actual sorting. - size_t nCount = c; - size_t nSize = sizeof( server_t * ); - - qsort( - pSortArray, - (size_t)nCount, - (size_t)nSize, - FnServerCompare - ); - - // Now rebuild the list. - m_pServers = pSortArray[0]; - for ( i = 0; i < c - 1; i++ ) - { - pSortArray[ i ]->next = pSortArray[ i + 1 ]; - } - pSortArray[ c - 1 ]->next = NULL; - - // Clean Up. - delete[] pSortArray; -} - -/* -=================== -GetServer - -Return particular server -=================== -*/ -CHudServers::server_t *CHudServers::GetServer( int server ) -{ - int c = 0; - server_t *p; - - p = m_pServers; - while ( p ) - { - if ( c == server ) - return p; - - c++; - p = p->next; - } - return NULL; -} - -/* -=================== -GetServerInfo - -Return info ( key/value ) string for particular server -=================== -*/ -char *CHudServers::GetServerInfo( int server ) -{ - server_t *p = GetServer( server ); - if ( p ) - { - return p->info; - } - return NULL; -} - -/* -=================== -CancelRequest - -Kill all pending requests in engine -=================== -*/ -void CHudServers::CancelRequest( void ) -{ - m_nRequesting = 0; - m_nQuerying = 0; - m_nDone = 1; - - NET_API->CancelAllRequests(); -} - -/* -================== -LoadMasterAddresses - -Loads the master server addresses from file and into the passed in array -================== -*/ -int CHudServers::LoadMasterAddresses( int maxservers, int *count, netadr_t *padr ) -{ - int i; - char szMaster[ 256 ]; - char szMasterFile[256]; - char *pbuffer = NULL; - char *pstart = NULL ; - netadr_t adr; - char szAdr[64]; - int nPort; - int nCount = 0; - bool bIgnore; - int nDefaultPort; - - // Assume default master and master file - strcpy( szMaster, VALVE_MASTER_ADDRESS ); // IP:PORT string - strcpy( szMasterFile, MASTER_PARSE_FILE ); - - // See if there is a command line override - i = gEngfuncs.CheckParm( "-comm", &pstart ); - if ( i && pstart ) - { - strcpy (szMasterFile, pstart ); - } - - // Read them in from proper file - pbuffer = (char *)gEngfuncs.COM_LoadFile( szMasterFile, 5, NULL ); // Use malloc - if ( !pbuffer ) - { - goto finish_master; - } - - pstart = pbuffer; - - while ( nCount < maxservers ) - { - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - - if ( strlen(m_szToken) <= 0) - break; - - bIgnore = true; - - if ( !stricmp( m_szToken, "Master" ) ) - { - nDefaultPort = PORT_MASTER; - bIgnore = FALSE; - } - - // Now parse all addresses between { } - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - if ( strlen(m_szToken) <= 0 ) - break; - - if ( stricmp ( m_szToken, "{" ) ) - break; - - // Parse addresses until we get to "}" - while ( nCount < maxservers ) - { - char base[256]; - - // Now parse all addresses between { } - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - - if (strlen(m_szToken) <= 0) - break; - - if ( !stricmp ( m_szToken, "}" ) ) - break; - - sprintf( base, "%s", m_szToken ); - - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - - if (strlen(m_szToken) <= 0) - break; - - if ( stricmp( m_szToken, ":" ) ) - break; - - pstart = gEngfuncs.COM_ParseFile( pstart, m_szToken ); - - if (strlen(m_szToken) <= 0) - break; - - nPort = atoi ( m_szToken ); - if ( !nPort ) - nPort = nDefaultPort; - - sprintf( szAdr, "%s:%i", base, nPort ); - - // Can we resolve it any better - if ( !NET_API->StringToAdr( szAdr, &adr ) ) - bIgnore = true; - - if ( !bIgnore ) - { - padr[ nCount++ ] = adr; - } - } - } - -finish_master: - if ( !nCount ) - { - sprintf( szMaster, VALVE_MASTER_ADDRESS ); // IP:PORT string - - // Convert to netadr_t - if ( NET_API->StringToAdr ( szMaster, &adr ) ) - { - - padr[ nCount++ ] = adr; - } - } - - *count = nCount; - - if ( pbuffer ) - { - gEngfuncs.COM_FreeFile( pbuffer ); - } - - return ( nCount > 0 ) ? 1 : 0; -} - -/* -=================== -RequestList - -Request list of game servers from master -=================== -*/ -void CHudServers::RequestList( void ) -{ - m_nRequesting = 1; - m_nDone = 0; - m_dStarted = m_fElapsed; - - int count = 0; - netadr_t adr; - - if ( !LoadMasterAddresses( 1, &count, &adr ) ) - { - gEngfuncs.Con_DPrintf( "SendRequest: Unable to read master server addresses\n" ); - return; - } - - ClearRequestList( &m_pActiveList ); - ClearRequestList( &m_pServerList ); - ClearServerList( &m_pServers ); - - m_nServerCount = 0; - - // Make sure networking system has started. - NET_API->InitNetworking(); - - // Kill off left overs if any - NET_API->CancelAllRequests(); - - // Request Server List from master - NET_API->SendRequest( context_id++, NETAPI_REQUEST_SERVERLIST, 0, 5.0, &adr, ::ListResponse ); -} - -void CHudServers::RequestBroadcastList( int clearpending ) -{ - m_nRequesting = 1; - m_nDone = 0; - m_dStarted = m_fElapsed; - - netadr_t adr; - memset( &adr, 0, sizeof( adr ) ); - - if ( clearpending ) - { - ClearRequestList( &m_pActiveList ); - ClearRequestList( &m_pServerList ); - ClearServerList( &m_pServers ); - - m_nServerCount = 0; - } - - // Make sure to byte swap server if necessary ( using "host" to "net" conversion - adr.port = htons( PORT_SERVER ); - - // Make sure networking system has started. - NET_API->InitNetworking(); - - if ( clearpending ) - { - // Kill off left overs if any - NET_API->CancelAllRequests(); - } - - adr.type = NA_BROADCAST; - - // Request Servers from LAN via IP - NET_API->SendRequest( context_id++, NETAPI_REQUEST_DETAILS, FNETAPI_MULTIPLE_RESPONSE, 5.0, &adr, ::ServerResponse ); - - adr.type = NA_BROADCAST_IPX; - - // Request Servers from LAN via IPX ( if supported ) - NET_API->SendRequest( context_id++, NETAPI_REQUEST_DETAILS, FNETAPI_MULTIPLE_RESPONSE, 5.0, &adr, ::ServerResponse ); -} - -void CHudServers::ServerPing( int server ) -{ - server_t *p; - - p = GetServer( server ); - if ( !p ) - return; - - // Make sure networking system has started. - NET_API->InitNetworking(); - - // Request Server List from master - NET_API->SendRequest( context_id++, NETAPI_REQUEST_PING, 0, 5.0, &p->remote_address, ::PingResponse ); -} - -void CHudServers::ServerRules( int server ) -{ - server_t *p; - - p = GetServer( server ); - if ( !p ) - return; - - // Make sure networking system has started. - NET_API->InitNetworking(); - - // Request Server List from master - NET_API->SendRequest( context_id++, NETAPI_REQUEST_RULES, 0, 5.0, &p->remote_address, ::RulesResponse ); -} - -void CHudServers::ServerPlayers( int server ) -{ - server_t *p; - - p = GetServer( server ); - if ( !p ) - return; - - // Make sure networking system has started. - NET_API->InitNetworking(); - - // Request Server List from master - NET_API->SendRequest( context_id++, NETAPI_REQUEST_PLAYERS, 0, 5.0, &p->remote_address, ::PlayersResponse ); -} - -int CHudServers::isQuerying() -{ - return m_nRequesting ? 1 : 0; -} - - -/* -=================== -GetServerCount - -Return number of servers in browser list -=================== -*/ -int CHudServers::GetServerCount( void ) -{ - return m_nServerCount; -} - -/* -=================== -CHudServers - -=================== -*/ -CHudServers::CHudServers( void ) -{ - m_nRequesting = 0; - m_dStarted = 0.0; - m_nDone = 0; - m_pServerList = NULL; - m_pServers = NULL; - m_pActiveList = NULL; - m_nQuerying = 0; - m_nActiveQueries = 0; - - m_fElapsed = 0.0; - - - m_pPingRequest = NULL; - m_pRulesRequest = NULL; - m_pPlayersRequest = NULL; -} - -/* -=================== -~CHudServers - -=================== -*/ -CHudServers::~CHudServers( void ) -{ - ClearRequestList( &m_pActiveList ); - ClearRequestList( &m_pServerList ); - ClearServerList( &m_pServers ); - - m_nServerCount = 0; - - if ( m_pPingRequest ) - { - delete m_pPingRequest; - m_pPingRequest = NULL; - - } - - if ( m_pRulesRequest ) - { - delete m_pRulesRequest; - m_pRulesRequest = NULL; - } - - if ( m_pPlayersRequest ) - { - delete m_pPlayersRequest; - m_pPlayersRequest = NULL; - } -} - -/////////////////////////////// -// -// PUBLIC APIs -// -/////////////////////////////// - -/* -=================== -ServersGetCount - -=================== -*/ -int ServersGetCount( void ) -{ - if ( g_pServers ) - { - return g_pServers->GetServerCount(); - } - return 0; -} - -int ServersIsQuerying( void ) -{ - if ( g_pServers ) - { - return g_pServers->isQuerying(); - } - return 0; -} - -/* -=================== -ServersGetInfo - -=================== -*/ -const char *ServersGetInfo( int server ) -{ - if ( g_pServers ) - { - return g_pServers->GetServerInfo( server ); - } - - return NULL; -} - -void SortServers( const char *fieldname ) -{ - if ( g_pServers ) - { - g_pServers->SortServers( fieldname ); - } -} - -/* -=================== -ServersShutdown - -=================== -*/ -void ServersShutdown( void ) -{ - if ( g_pServers ) - { - delete g_pServers; - g_pServers = NULL; - } -} - -/* -=================== -ServersInit - -=================== -*/ -void ServersInit( void ) -{ - // Kill any previous instance - ServersShutdown(); - - g_pServers = new CHudServers(); -} - -/* -=================== -ServersThink - -=================== -*/ -void ServersThink( double time ) -{ - if ( g_pServers ) - { - g_pServers->Think( time ); - } -} - -/* -=================== -ServersCancel - -=================== -*/ -void ServersCancel( void ) -{ - if ( g_pServers ) - { - g_pServers->CancelRequest(); - } -} - -// Requests -/* -=================== -ServersList - -=================== -*/ -void ServersList( void ) -{ - if ( g_pServers ) - { - g_pServers->RequestList(); - } -} - -void BroadcastServersList( int clearpending ) -{ - if ( g_pServers ) - { - g_pServers->RequestBroadcastList( clearpending ); - } -} - -void ServerPing( int server ) -{ - if ( g_pServers ) - { - g_pServers->ServerPing( server ); - } -} - -void ServerRules( int server ) -{ - if ( g_pServers ) - { - g_pServers->ServerRules( server ); - } -} - -void ServerPlayers( int server ) -{ - if ( g_pServers ) - { - g_pServers->ServerPlayers( server ); - } -} diff --git a/ricochet/cl_dll/hud_servers.h b/ricochet/cl_dll/hud_servers.h deleted file mode 100644 index 577b555..0000000 --- a/ricochet/cl_dll/hud_servers.h +++ /dev/null @@ -1,34 +0,0 @@ -#if !defined( HUD_SERVERSH ) -#define HUD_SERVERSH -#pragma once - -#define NET_CALLBACK /* */ - -// Dispatchers -void NET_CALLBACK ListResponse( struct net_response_s *response ); -void NET_CALLBACK ServerResponse( struct net_response_s *response ); -void NET_CALLBACK PingResponse( struct net_response_s *response ); -void NET_CALLBACK RulesResponse( struct net_response_s *response ); -void NET_CALLBACK PlayersResponse( struct net_response_s *response ); - -void ServersInit( void ); -void ServersShutdown( void ); -void ServersThink( double time ); -void ServersCancel( void ); - -// Get list and get server info from each -void ServersList( void ); - -// Query for IP / IPX LAN servers -void BroadcastServersList( int clearpending ); - -void ServerPing( int server ); -void ServerRules( int server ); -void ServerPlayers( int server ); - -int ServersGetCount( void ); -const char *ServersGetInfo( int server ); -int ServersIsQuerying( void ); -void SortServers( const char *fieldname ); - -#endif // HUD_SERVERSH \ No newline at end of file diff --git a/ricochet/cl_dll/hud_servers_priv.h b/ricochet/cl_dll/hud_servers_priv.h deleted file mode 100644 index 84f1e2a..0000000 --- a/ricochet/cl_dll/hud_servers_priv.h +++ /dev/null @@ -1,91 +0,0 @@ -#if !defined( HUD_SERVERS_PRIVH ) -#define HUD_SERVERS_PRIVH -#pragma once - -#include "netadr.h" - -class CHudServers -{ -public: - typedef struct request_s - { - struct request_s *next; - netadr_t remote_address; - int context; - } request_t; - - typedef struct server_s - { - struct server_s *next; - netadr_t remote_address; - char *info; - int ping; - } server_t; - - CHudServers(); - ~CHudServers(); - - void Think( double time ); - void QueryThink( void ); - int isQuerying( void ); - - int LoadMasterAddresses( int maxservers, int *count, netadr_t *padr ); - - void RequestList( void ); - void RequestBroadcastList( int clearpending ); - - void ServerPing( int server ); - void ServerRules( int server ); - void ServerPlayers( int server ); - - void CancelRequest( void ); - - int CompareServers( server_t *p1, server_t *p2 ); - - void ClearServerList( server_t **ppList ); - void ClearRequestList( request_t **ppList ); - - void AddServer( server_t **ppList, server_t *p ); - - void RemoveServerFromList( request_t **ppList, request_t *item ); - - request_t *FindRequest( int context, request_t *pList ); - - int ServerListSize( void ); - char *GetServerInfo( int server ); - int GetServerCount( void ); - void SortServers( const char *fieldname ); - - void ListResponse( struct net_response_s *response ); - void ServerResponse( struct net_response_s *response ); - void PingResponse( struct net_response_s *response ); - void RulesResponse( struct net_response_s *response ); - void PlayersResponse( struct net_response_s *response ); -private: - - server_t *GetServer( int server ); - - // - char m_szToken[ 1024 ]; - int m_nRequesting; - int m_nDone; - - double m_dStarted; - - request_t *m_pServerList; - request_t *m_pActiveList; - - server_t *m_pServers; - - int m_nServerCount; - - int m_nActiveQueries; - int m_nQuerying; - double m_fElapsed; - - request_t *m_pPingRequest; - request_t *m_pRulesRequest; - request_t *m_pPlayersRequest; -}; - -#endif // HUD_SERVERS_PRIVH \ No newline at end of file diff --git a/ricochet/cl_dll/hud_update.cpp b/ricochet/cl_dll/hud_update.cpp deleted file mode 100644 index 3a69a00..0000000 --- a/ricochet/cl_dll/hud_update.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// hud_update.cpp -// - -#include -#include "hud.h" -#include "cl_util.h" -#include -#include - -int CL_ButtonBits( int ); -void CL_ResetButtonBits( int bits ); - -extern float v_idlescale; -float in_fov; -extern void HUD_SetCmdBits( int bits ); - -int CHud::UpdateClientData(client_data_t *cdata, float time) -{ - memcpy(m_vecOrigin, cdata->origin, sizeof(vec3_t)); - memcpy(m_vecAngles, cdata->viewangles, sizeof(vec3_t)); - - m_iKeyBits = CL_ButtonBits( 0 ); - m_iWeaponBits = cdata->iWeaponBits; - - in_fov = cdata->fov; - - Think(); - - cdata->fov = m_iFOV; - - v_idlescale = m_iConcussionEffect; - - CL_ResetButtonBits( m_iKeyBits ); - - // return 1 if in anything in the client_data struct has been changed, 0 otherwise - return 1; -} - - diff --git a/ricochet/cl_dll/in_camera.cpp b/ricochet/cl_dll/in_camera.cpp deleted file mode 100644 index 3e1695d..0000000 --- a/ricochet/cl_dll/in_camera.cpp +++ /dev/null @@ -1,630 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" - -#include "SDL2/SDL_mouse.h" -#include "port.h" - -float CL_KeyState (kbutton_t *key); - -extern "C" -{ - void DLLEXPORT CAM_Think( void ); - int DLLEXPORT CL_IsThirdPerson( void ); - void DLLEXPORT CL_CameraOffset( float *ofs ); -} - -extern cl_enginefunc_t gEngfuncs; - -//-------------------------------------------------- Constants - -#define CAM_DIST_DELTA 1.0 -#define CAM_ANGLE_DELTA 2.5 -#define CAM_ANGLE_SPEED 2.5 -#define CAM_MIN_DIST 30.0 -#define CAM_ANGLE_MOVE .5 -#define MAX_ANGLE_DIFF 10.0 -#define PITCH_MAX 90.0 -#define PITCH_MIN 0 -#define YAW_MAX 135.0 -#define YAW_MIN -135.0 - -enum ECAM_Command -{ - CAM_COMMAND_NONE = 0, - CAM_COMMAND_TOTHIRDPERSON = 1, - CAM_COMMAND_TOFIRSTPERSON = 2 -}; - -//-------------------------------------------------- Global Variables - -cvar_t *cam_command; -cvar_t *cam_snapto; -cvar_t *cam_idealyaw; -cvar_t *cam_idealpitch; -cvar_t *cam_idealdist; -cvar_t *cam_contain; - -cvar_t *c_maxpitch; -cvar_t *c_minpitch; -cvar_t *c_maxyaw; -cvar_t *c_minyaw; -cvar_t *c_maxdistance; -cvar_t *c_mindistance; - -// pitch, yaw, dist -vec3_t cam_ofs; - - -// In third person -int cam_thirdperson; -int cam_mousemove; //true if we are moving the cam with the mouse, False if not -int iMouseInUse=0; -int cam_distancemove; -extern int mouse_x, mouse_y; //used to determine what the current x and y values are -int cam_old_mouse_x, cam_old_mouse_y; //holds the last ticks mouse movement -POINT cam_mouse; -//-------------------------------------------------- Local Variables - -static kbutton_t cam_pitchup, cam_pitchdown, cam_yawleft, cam_yawright; -static kbutton_t cam_in, cam_out, cam_move; - -//-------------------------------------------------- Prototypes - -void CAM_ToThirdPerson(void); -void CAM_ToFirstPerson(void); -void CAM_StartDistance(void); -void CAM_EndDistance(void); - -void SDL_GetCursorPos( POINT *p ) -{ - SDL_GetMouseState( (int *)&p->x, (int *)&p->y ); -} - -void SDL_SetCursorPos( const int x, const int y ) -{ -} - - -//-------------------------------------------------- Local Functions - -float MoveToward( float cur, float goal, float maxspeed ) -{ - if( cur != goal ) - { - if( fabs( cur - goal ) > 180.0 ) - { - if( cur < goal ) - cur += 360.0; - else - cur -= 360.0; - } - - if( cur < goal ) - { - if( cur < goal - 1.0 ) - cur += ( goal - cur ) / 4.0; - else - cur = goal; - } - else - { - if( cur > goal + 1.0 ) - cur -= ( cur - goal ) / 4.0; - else - cur = goal; - } - } - - - // bring cur back into range - if( cur < 0 ) - cur += 360.0; - else if( cur >= 360 ) - cur -= 360; - - return cur; -} - - -//-------------------------------------------------- Gobal Functions - -typedef struct -{ - vec3_t boxmins, boxmaxs;// enclose the test object along entire move - float *mins, *maxs; // size of the moving object - vec3_t mins2, maxs2; // size when clipping against mosnters - float *start, *end; - trace_t trace; - int type; - edict_t *passedict; - qboolean monsterclip; -} moveclip_t; - -extern trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end); - -void DLLEXPORT CAM_Think( void ) -{ - vec3_t origin; - vec3_t ext, pnt, camForward, camRight, camUp; - moveclip_t clip; - float dist; - vec3_t camAngles; - float flSensitivity; -#ifdef LATER - int i; -#endif - vec3_t viewangles; - - switch( (int) cam_command->value ) - { - case CAM_COMMAND_TOTHIRDPERSON: - CAM_ToThirdPerson(); - break; - - case CAM_COMMAND_TOFIRSTPERSON: - CAM_ToFirstPerson(); - break; - - case CAM_COMMAND_NONE: - default: - break; - } - - if( !cam_thirdperson ) - return; - -#ifdef LATER - if ( cam_contain->value ) - { - gEngfuncs.GetClientOrigin( origin ); - ext[0] = ext[1] = ext[2] = 0.0; - } -#endif - - camAngles[ PITCH ] = cam_idealpitch->value; - camAngles[ YAW ] = cam_idealyaw->value; - dist = cam_idealdist->value; - // - //movement of the camera with the mouse - // - if (cam_mousemove) - { - //get windows cursor position - SDL_GetCursorPos (&cam_mouse); - //check for X delta values and adjust accordingly - //eventually adjust YAW based on amount of movement - //don't do any movement of the cam using YAW/PITCH if we are zooming in/out the camera - if (!cam_distancemove) - { - - //keep the camera within certain limits around the player (ie avoid certain bad viewing angles) - if (cam_mouse.x>gEngfuncs.GetWindowCenterX()) - { - //if ((camAngles[YAW]>=225.0)||(camAngles[YAW]<135.0)) - if (camAngles[YAW]value) - { - camAngles[ YAW ] += (CAM_ANGLE_MOVE)*((cam_mouse.x-gEngfuncs.GetWindowCenterX())/2); - } - if (camAngles[YAW]>c_maxyaw->value) - { - - camAngles[YAW]=c_maxyaw->value; - } - } - else if (cam_mouse.x225.0)) - if (camAngles[YAW]>c_minyaw->value) - { - camAngles[ YAW ] -= (CAM_ANGLE_MOVE)* ((gEngfuncs.GetWindowCenterX()-cam_mouse.x)/2); - - } - if (camAngles[YAW]value) - { - camAngles[YAW]=c_minyaw->value; - - } - } - - //check for y delta values and adjust accordingly - //eventually adjust PITCH based on amount of movement - //also make sure camera is within bounds - if (cam_mouse.y>gEngfuncs.GetWindowCenterY()) - { - if(camAngles[PITCH]value) - { - camAngles[PITCH] +=(CAM_ANGLE_MOVE)* ((cam_mouse.y-gEngfuncs.GetWindowCenterY())/2); - } - if (camAngles[PITCH]>c_maxpitch->value) - { - camAngles[PITCH]=c_maxpitch->value; - } - } - else if (cam_mouse.yc_minpitch->value) - { - camAngles[PITCH] -= (CAM_ANGLE_MOVE)*((gEngfuncs.GetWindowCenterY()-cam_mouse.y)/2); - } - if (camAngles[PITCH]value) - { - camAngles[PITCH]=c_minpitch->value; - } - } - - //set old mouse coordinates to current mouse coordinates - //since we are done with the mouse - - if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 ) - { - cam_old_mouse_x=cam_mouse.x*flSensitivity; - cam_old_mouse_y=cam_mouse.y*flSensitivity; - } - else - { - cam_old_mouse_x=cam_mouse.x; - cam_old_mouse_y=cam_mouse.y; - } - SDL_SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); - } - } - - //Nathan code here - if( CL_KeyState( &cam_pitchup ) ) - camAngles[ PITCH ] += CAM_ANGLE_DELTA; - else if( CL_KeyState( &cam_pitchdown ) ) - camAngles[ PITCH ] -= CAM_ANGLE_DELTA; - - if( CL_KeyState( &cam_yawleft ) ) - camAngles[ YAW ] -= CAM_ANGLE_DELTA; - else if( CL_KeyState( &cam_yawright ) ) - camAngles[ YAW ] += CAM_ANGLE_DELTA; - - if( CL_KeyState( &cam_in ) ) - { - dist -= CAM_DIST_DELTA; - if( dist < CAM_MIN_DIST ) - { - // If we go back into first person, reset the angle - camAngles[ PITCH ] = 0; - camAngles[ YAW ] = 0; - dist = CAM_MIN_DIST; - } - - } - else if( CL_KeyState( &cam_out ) ) - dist += CAM_DIST_DELTA; - - if (cam_distancemove) - { - if (cam_mouse.y>gEngfuncs.GetWindowCenterY()) - { - if(distvalue) - { - dist +=CAM_DIST_DELTA * ((cam_mouse.y-gEngfuncs.GetWindowCenterY())/2); - } - if (dist>c_maxdistance->value) - { - dist=c_maxdistance->value; - } - } - else if (cam_mouse.yc_mindistance->value) - { - dist -= (CAM_DIST_DELTA)*((gEngfuncs.GetWindowCenterY()-cam_mouse.y)/2); - } - if (distvalue) - { - dist=c_mindistance->value; - } - } - //set old mouse coordinates to current mouse coordinates - //since we are done with the mouse - cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity(); - cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity(); - SDL_SetCursorPos (gEngfuncs.GetWindowCenterX(), gEngfuncs.GetWindowCenterY()); - } -#ifdef LATER - if( cam_contain->value ) - { - // check new ideal - VectorCopy( origin, pnt ); - AngleVectors( camAngles, camForward, camRight, camUp ); - for (i=0 ; i<3 ; i++) - pnt[i] += -dist*camForward[i]; - - // check line from r_refdef.vieworg to pnt - memset ( &clip, 0, sizeof ( moveclip_t ) ); - clip.trace = SV_ClipMoveToEntity( sv.edicts, r_refdef.vieworg, ext, ext, pnt ); - if( clip.trace.fraction == 1.0 ) - { - // update ideal - cam_idealpitch->value = camAngles[ PITCH ]; - cam_idealyaw->value = camAngles[ YAW ]; - cam_idealdist->value = dist; - } - } - else -#endif - { - // update ideal - cam_idealpitch->value = camAngles[ PITCH ]; - cam_idealyaw->value = camAngles[ YAW ]; - cam_idealdist->value = dist; - } - - // Move towards ideal - VectorCopy( cam_ofs, camAngles ); - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - if( cam_snapto->value ) - { - camAngles[ YAW ] = cam_idealyaw->value + viewangles[ YAW ]; - camAngles[ PITCH ] = cam_idealpitch->value + viewangles[ PITCH ]; - camAngles[ 2 ] = cam_idealdist->value; - } - else - { - if( camAngles[ YAW ] - viewangles[ YAW ] != cam_idealyaw->value ) - camAngles[ YAW ] = MoveToward( camAngles[ YAW ], cam_idealyaw->value + viewangles[ YAW ], CAM_ANGLE_SPEED ); - - if( camAngles[ PITCH ] - viewangles[ PITCH ] != cam_idealpitch->value ) - camAngles[ PITCH ] = MoveToward( camAngles[ PITCH ], cam_idealpitch->value + viewangles[ PITCH ], CAM_ANGLE_SPEED ); - - if( fabs( camAngles[ 2 ] - cam_idealdist->value ) < 2.0 ) - camAngles[ 2 ] = cam_idealdist->value; - else - camAngles[ 2 ] += ( cam_idealdist->value - camAngles[ 2 ] ) / 4.0; - } -#ifdef LATER - if( cam_contain->value ) - { - // Test new position - dist = camAngles[ ROLL ]; - camAngles[ ROLL ] = 0; - - VectorCopy( origin, pnt ); - AngleVectors( camAngles, camForward, camRight, camUp ); - for (i=0 ; i<3 ; i++) - pnt[i] += -dist*camForward[i]; - - // check line from r_refdef.vieworg to pnt - memset ( &clip, 0, sizeof ( moveclip_t ) ); - ext[0] = ext[1] = ext[2] = 0.0; - clip.trace = SV_ClipMoveToEntity( sv.edicts, r_refdef.vieworg, ext, ext, pnt ); - if( clip.trace.fraction != 1.0 ) - return; - } -#endif - cam_ofs[ 0 ] = camAngles[ 0 ]; - cam_ofs[ 1 ] = camAngles[ 1 ]; - cam_ofs[ 2 ] = dist; -} - -extern void KeyDown (kbutton_t *b); // HACK -extern void KeyUp (kbutton_t *b); // HACK - -void CAM_PitchUpDown(void) { KeyDown( &cam_pitchup ); } -void CAM_PitchUpUp(void) { KeyUp( &cam_pitchup ); } -void CAM_PitchDownDown(void) { KeyDown( &cam_pitchdown ); } -void CAM_PitchDownUp(void) { KeyUp( &cam_pitchdown ); } -void CAM_YawLeftDown(void) { KeyDown( &cam_yawleft ); } -void CAM_YawLeftUp(void) { KeyUp( &cam_yawleft ); } -void CAM_YawRightDown(void) { KeyDown( &cam_yawright ); } -void CAM_YawRightUp(void) { KeyUp( &cam_yawright ); } -void CAM_InDown(void) { KeyDown( &cam_in ); } -void CAM_InUp(void) { KeyUp( &cam_in ); } -void CAM_OutDown(void) { KeyDown( &cam_out ); } -void CAM_OutUp(void) { KeyUp( &cam_out ); } - -void CAM_ToThirdPerson(void) -{ - vec3_t viewangles; - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - if( !cam_thirdperson ) - { - cam_thirdperson = 1; - - cam_ofs[ YAW ] = viewangles[ YAW ]; - cam_ofs[ PITCH ] = viewangles[ PITCH ]; - cam_ofs[ 2 ] = CAM_MIN_DIST; - } - - gEngfuncs.Cvar_SetValue( "cam_command", 0 ); -} - -void CAM_ToFirstPerson(void) -{ - cam_thirdperson = 0; - - gEngfuncs.Cvar_SetValue( "cam_command", 0 ); -} - -void CAM_ToggleSnapto( void ) -{ - cam_snapto->value = !cam_snapto->value; -} - -void CAM_Init( void ) -{ - gEngfuncs.pfnAddCommand( "+campitchup", CAM_PitchUpDown ); - gEngfuncs.pfnAddCommand( "-campitchup", CAM_PitchUpUp ); - gEngfuncs.pfnAddCommand( "+campitchdown", CAM_PitchDownDown ); - gEngfuncs.pfnAddCommand( "-campitchdown", CAM_PitchDownUp ); - gEngfuncs.pfnAddCommand( "+camyawleft", CAM_YawLeftDown ); - gEngfuncs.pfnAddCommand( "-camyawleft", CAM_YawLeftUp ); - gEngfuncs.pfnAddCommand( "+camyawright", CAM_YawRightDown ); - gEngfuncs.pfnAddCommand( "-camyawright", CAM_YawRightUp ); - gEngfuncs.pfnAddCommand( "+camin", CAM_InDown ); - gEngfuncs.pfnAddCommand( "-camin", CAM_InUp ); - gEngfuncs.pfnAddCommand( "+camout", CAM_OutDown ); - gEngfuncs.pfnAddCommand( "-camout", CAM_OutUp ); - gEngfuncs.pfnAddCommand( "thirdperson", CAM_ToThirdPerson ); - gEngfuncs.pfnAddCommand( "firstperson", CAM_ToFirstPerson ); - gEngfuncs.pfnAddCommand( "+cammousemove",CAM_StartMouseMove); - gEngfuncs.pfnAddCommand( "-cammousemove",CAM_EndMouseMove); - gEngfuncs.pfnAddCommand( "+camdistance", CAM_StartDistance ); - gEngfuncs.pfnAddCommand( "-camdistance", CAM_EndDistance ); - gEngfuncs.pfnAddCommand( "snapto", CAM_ToggleSnapto ); - - cam_command = gEngfuncs.pfnRegisterVariable ( "cam_command", "0", 0 ); // tells camera to go to thirdperson - cam_snapto = gEngfuncs.pfnRegisterVariable ( "cam_snapto", "0", 0 ); // snap to thirdperson view - cam_idealyaw = gEngfuncs.pfnRegisterVariable ( "cam_idealyaw", "0", 0 ); // ? yaw - cam_idealpitch = gEngfuncs.pfnRegisterVariable ( "cam_idealpitch", "0", 0 ); // thirperson pitch - cam_idealdist = gEngfuncs.pfnRegisterVariable ( "cam_idealdist", "196", 0 ); // thirdperson distance - cam_contain = gEngfuncs.pfnRegisterVariable ( "cam_contain", "0", 0 ); // contain camera to world - - c_maxpitch = gEngfuncs.pfnRegisterVariable ( "c_maxpitch", "90.0", 0 ); - c_minpitch = gEngfuncs.pfnRegisterVariable ( "c_minpitch", "0.0", 0 ); - c_maxyaw = gEngfuncs.pfnRegisterVariable ( "c_maxyaw", "135.0", 0 ); - c_minyaw = gEngfuncs.pfnRegisterVariable ( "c_minyaw", "-135.0", 0 ); - c_maxdistance = gEngfuncs.pfnRegisterVariable ( "c_maxdistance", "200.0", 0 ); - c_mindistance = gEngfuncs.pfnRegisterVariable ( "c_mindistance", "30.0", 0 ); -} - -void CAM_ClearStates( void ) -{ - vec3_t viewangles; - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - cam_pitchup.state = 0; - cam_pitchdown.state = 0; - cam_yawleft.state = 0; - cam_yawright.state = 0; - cam_in.state = 0; - cam_out.state = 0; - - cam_thirdperson = 0; - cam_command->value = 0; - cam_mousemove=0; - - cam_snapto->value = 0; - cam_distancemove = 0; - - cam_ofs[ 0 ] = 0.0; - cam_ofs[ 1 ] = 0.0; - cam_ofs[ 2 ] = CAM_MIN_DIST; - - cam_idealpitch->value = viewangles[ PITCH ]; - cam_idealyaw->value = viewangles[ YAW ]; - cam_idealdist->value = CAM_MIN_DIST; -} - -void CAM_StartMouseMove(void) -{ - float flSensitivity; - - //only move the cam with mouse if we are in third person. - if (cam_thirdperson) - { - //set appropriate flags and initialize the old mouse position - //variables for mouse camera movement - if (!cam_mousemove) - { - cam_mousemove=1; - iMouseInUse=1; - SDL_GetCursorPos (&cam_mouse); - - if ( ( flSensitivity = gHUD.GetSensitivity() ) != 0 ) - { - cam_old_mouse_x=cam_mouse.x*flSensitivity; - cam_old_mouse_y=cam_mouse.y*flSensitivity; - } - else - { - cam_old_mouse_x=cam_mouse.x; - cam_old_mouse_y=cam_mouse.y; - } - } - } - //we are not in 3rd person view..therefore do not allow camera movement - else - { - cam_mousemove=0; - iMouseInUse=0; - } -} - -//the key has been released for camera movement -//tell the engine that mouse camera movement is off -void CAM_EndMouseMove(void) -{ - cam_mousemove=0; - iMouseInUse=0; -} - - -//---------------------------------------------------------- -//routines to start the process of moving the cam in or out -//using the mouse -//---------------------------------------------------------- -void CAM_StartDistance(void) -{ - //only move the cam with mouse if we are in third person. - if (cam_thirdperson) - { - //set appropriate flags and initialize the old mouse position - //variables for mouse camera movement - if (!cam_distancemove) - { - cam_distancemove=1; - cam_mousemove=1; - iMouseInUse=1; - SDL_GetCursorPos (&cam_mouse); - cam_old_mouse_x=cam_mouse.x*gHUD.GetSensitivity(); - cam_old_mouse_y=cam_mouse.y*gHUD.GetSensitivity(); - } - } - //we are not in 3rd person view..therefore do not allow camera movement - else - { - cam_distancemove=0; - cam_mousemove=0; - iMouseInUse=0; - } -} - -//the key has been released for camera movement -//tell the engine that mouse camera movement is off -void CAM_EndDistance(void) -{ - cam_distancemove=0; - cam_mousemove=0; - iMouseInUse=0; -} - -int DLLEXPORT CL_IsThirdPerson( void ) -{ - return cam_thirdperson ? 1 : 0; -} - -void DLLEXPORT CL_CameraOffset( float *ofs ) -{ - VectorCopy( cam_ofs, ofs ); -} diff --git a/ricochet/cl_dll/in_defs.h b/ricochet/cl_dll/in_defs.h deleted file mode 100644 index 18ec79e..0000000 --- a/ricochet/cl_dll/in_defs.h +++ /dev/null @@ -1,27 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#if !defined( IN_DEFSH ) -#define IN_DEFSH -#pragma once - -// up / down -#define PITCH 0 -// left / right -#define YAW 1 -// fall over -#define ROLL 2 - - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/input.cpp b/ricochet/cl_dll/input.cpp deleted file mode 100644 index 65fb170..0000000 --- a/ricochet/cl_dll/input.cpp +++ /dev/null @@ -1,988 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// input.cpp -- builds an intended movement command to send to the server -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -extern "C" -{ -#include "kbutton.h" -} -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "view.h" -#include -#include - -#include "vgui_TeamFortressViewport.h" -#include "vgui_discobjects.h" - -// Observer Movement modes (stored in pev->iuser1, so the physics code can get at them) -#define OBS_CHASE_LOCKED 1 -#define OBS_CHASE_FREE 2 -#define OBS_ROAMING 3 -#define OBS_LOCKEDVIEW 4 - -extern "C" -{ - struct kbutton_s DLLEXPORT *KB_Find( const char *name ); - void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ); - void DLLEXPORT HUD_Shutdown( void ); - int DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding ); -} - -extern int g_weaponselect; -extern cl_enginefunc_t gEngfuncs; - -// Defined in pm_math.c -float anglemod( float a ); - -void IN_Init (void); -void IN_Move ( float frametime, usercmd_t *cmd); -void IN_Shutdown( void ); -void V_Init( void ); -int CL_ButtonBits( int ); - -// xxx need client dll function to get and clear impuse -extern cvar_t *in_joystick; - -int in_impulse = 0; -int in_cancel = 0; - -cvar_t *m_pitch; -cvar_t *m_yaw; -cvar_t *m_forward; -cvar_t *m_side; - -cvar_t *lookstrafe; -cvar_t *lookspring; -cvar_t *cl_pitchup; -cvar_t *cl_pitchdown; -cvar_t *cl_upspeed; -cvar_t *cl_forwardspeed; -cvar_t *cl_backspeed; -cvar_t *cl_sidespeed; -cvar_t *cl_movespeedkey; -cvar_t *cl_yawspeed; -cvar_t *cl_pitchspeed; -cvar_t *cl_anglespeedkey; -cvar_t *cl_vsmoothing; -/* -=============================================================================== - -KEY BUTTONS - -Continuous button event tracking is complicated by the fact that two different -input sources (say, mouse button 1 and the control key) can both press the -same button, but the button should only be released when both of the -pressing key have been released. - -When a key event issues a button command (+forward, +attack, etc), it appends -its key number as a parameter to the command so it can be matched up with -the release. - -state bit 0 is the current state of the key -state bit 1 is edge triggered on the up to down transition -state bit 2 is edge triggered on the down to up transition - -=============================================================================== -*/ - - -kbutton_t in_mlook; -kbutton_t in_klook; -kbutton_t in_jlook; -kbutton_t in_left; -kbutton_t in_right; -kbutton_t in_forward; -kbutton_t in_back; -kbutton_t in_lookup; -kbutton_t in_lookdown; -kbutton_t in_moveleft; -kbutton_t in_moveright; -kbutton_t in_strafe; -kbutton_t in_speed; -kbutton_t in_use; -kbutton_t in_jump; -kbutton_t in_attack; -kbutton_t in_attack2; -kbutton_t in_up; -kbutton_t in_down; -kbutton_t in_duck; -kbutton_t in_reload; -kbutton_t in_alt1; -kbutton_t in_score; -kbutton_t in_break; -kbutton_t in_graph; // Display the netgraph - -typedef struct kblist_s -{ - struct kblist_s *next; - kbutton_t *pkey; - char name[32]; -} kblist_t; - -kblist_t *g_kbkeys = NULL; - -/* -============ -KB_ConvertString - -Removes references to +use and replaces them with the keyname in the output string. If - a binding is unfound, then the original text is retained. -NOTE: Only works for text with +word in it. -============ -*/ -int KB_ConvertString( char *in, char **ppout ) -{ - char sz[ 4096 ]; - char binding[ 64 ]; - char *p; - char *pOut; - char *pEnd; - const char *pBinding; - - if ( !ppout ) - return 0; - - *ppout = NULL; - p = in; - pOut = sz; - while ( *p ) - { - if ( *p == '+' ) - { - pEnd = binding; - while ( *p && ( isalnum( *p ) || ( pEnd == binding ) ) && ( ( pEnd - binding ) < 63 ) ) - { - *pEnd++ = *p++; - } - - *pEnd = '\0'; - - pBinding = NULL; - if ( strlen( binding + 1 ) > 0 ) - { - // See if there is a binding for binding? - pBinding = gEngfuncs.Key_LookupBinding( binding + 1 ); - } - - if ( pBinding ) - { - *pOut++ = '['; - pEnd = (char *)pBinding; - } - else - { - pEnd = binding; - } - - while ( *pEnd ) - { - *pOut++ = *pEnd++; - } - - if ( pBinding ) - { - *pOut++ = ']'; - } - } - else - { - *pOut++ = *p++; - } - } - - *pOut = '\0'; - - pOut = ( char * )malloc( strlen( sz ) + 1 ); - strcpy( pOut, sz ); - *ppout = pOut; - - return 1; -} - -/* -============ -KB_Find - -Allows the engine to get a kbutton_t directly ( so it can check +mlook state, etc ) for saving out to .cfg files -============ -*/ -struct kbutton_s DLLEXPORT *KB_Find( const char *name ) -{ - kblist_t *p; - p = g_kbkeys; - while ( p ) - { - if ( !stricmp( name, p->name ) ) - return p->pkey; - - p = p->next; - } - return NULL; -} - -/* -============ -KB_Add - -Add a kbutton_t * to the list of pointers the engine can retrieve via KB_Find -============ -*/ -void KB_Add( const char *name, kbutton_t *pkb ) -{ - kblist_t *p; - kbutton_t *kb; - - kb = KB_Find( name ); - - if ( kb ) - return; - - p = ( kblist_t * )malloc( sizeof( kblist_t ) ); - memset( p, 0, sizeof( *p ) ); - - strcpy( p->name, name ); - p->pkey = pkb; - - p->next = g_kbkeys; - g_kbkeys = p; -} - -/* -============ -KB_Init - -Add kbutton_t definitions that the engine can query if needed -============ -*/ -void KB_Init( void ) -{ - g_kbkeys = NULL; - - KB_Add( "in_graph", &in_graph ); - KB_Add( "in_mlook", &in_mlook ); - KB_Add( "in_jlook", &in_jlook ); -} - -/* -============ -KB_Shutdown - -Clear kblist -============ -*/ -void KB_Shutdown( void ) -{ - kblist_t *p, *n; - p = g_kbkeys; - while ( p ) - { - n = p->next; - free( p ); - p = n; - } - g_kbkeys = NULL; -} - -/* -============ -KeyDown -============ -*/ -void KeyDown (kbutton_t *b) -{ - int k; - char *c; - - c = gEngfuncs.Cmd_Argv(1); - if (c[0]) - k = atoi(c); - else - k = -1; // typed manually at the console for continuous down - - if (k == b->down[0] || k == b->down[1]) - return; // repeating key - - if (!b->down[0]) - b->down[0] = k; - else if (!b->down[1]) - b->down[1] = k; - else - { - gEngfuncs.Con_DPrintf ("Three keys down for a button '%c' '%c' '%c'!\n", b->down[0], b->down[1], c); - return; - } - - if (b->state & 1) - return; // still down - b->state |= 1 + 2; // down + impulse down -} - -/* -============ -KeyUp -============ -*/ -void KeyUp (kbutton_t *b) -{ - int k; - char *c; - - c = gEngfuncs.Cmd_Argv(1); - if (c[0]) - k = atoi(c); - else - { // typed manually at the console, assume for unsticking, so clear all - b->down[0] = b->down[1] = 0; - b->state = 4; // impulse up - return; - } - - if (b->down[0] == k) - b->down[0] = 0; - else if (b->down[1] == k) - b->down[1] = 0; - else - return; // key up without coresponding down (menu pass through) - if (b->down[0] || b->down[1]) - { - return; // some other key is still holding it down - } - - if (!(b->state & 1)) - return; // still up (this should not happen) - - b->state &= ~1; // now up - b->state |= 4; // impulse up -} -/* -============ -HUD_Key_Event - -Return 1 to allow engine to process the key, otherwise, act on it as needed -============ -*/ -int DLLEXPORT HUD_Key_Event( int down, int keynum, const char *pszCurrentBinding ) -{ - if (gViewPort) - return gViewPort->KeyInput(down, keynum, pszCurrentBinding); - - return 1; -} - -void IN_BreakDown( void ) { KeyDown( &in_break );}; -void IN_BreakUp( void ) { KeyUp( &in_break ); }; -void IN_KLookDown (void) {KeyDown(&in_klook);} -void IN_KLookUp (void) {KeyUp(&in_klook);} -void IN_JLookDown (void) {KeyDown(&in_jlook);} -void IN_JLookUp (void) {KeyUp(&in_jlook);} -void IN_MLookDown (void) {KeyDown(&in_mlook);} -void IN_UpDown(void) {KeyDown(&in_up);} -void IN_UpUp(void) {KeyUp(&in_up);} -void IN_DownDown(void) {KeyDown(&in_down);} -void IN_DownUp(void) {KeyUp(&in_down);} -void IN_LeftDown(void) {KeyDown(&in_left);} -void IN_LeftUp(void) {KeyUp(&in_left);} -void IN_RightDown(void) {KeyDown(&in_right);} -void IN_RightUp(void) {KeyUp(&in_right);} -void IN_ForwardDown(void) {KeyDown(&in_forward);} -void IN_ForwardUp(void) {KeyUp(&in_forward);} -void IN_BackDown(void) {KeyDown(&in_back);} -void IN_BackUp(void) {KeyUp(&in_back);} -void IN_LookupDown(void) {KeyDown(&in_lookup);} -void IN_LookupUp(void) {KeyUp(&in_lookup);} -void IN_LookdownDown(void) {KeyDown(&in_lookdown);} -void IN_LookdownUp(void) {KeyUp(&in_lookdown);} -void IN_MoveleftDown(void) {KeyDown(&in_moveleft);} -void IN_MoveleftUp(void) {KeyUp(&in_moveleft);} -void IN_MoverightDown(void) {KeyDown(&in_moveright);} -void IN_MoverightUp(void) {KeyUp(&in_moveright);} -void IN_SpeedDown(void) {KeyDown(&in_speed);} -void IN_SpeedUp(void) {KeyUp(&in_speed);} -void IN_StrafeDown(void) {KeyDown(&in_strafe);} -void IN_StrafeUp(void) {KeyUp(&in_strafe);} -void IN_Attack2Down(void) {KeyDown(&in_attack2);} -void IN_Attack2Up(void) {KeyUp(&in_attack2);} -void IN_UseDown (void) {KeyDown(&in_use);} -void IN_UseUp (void) {KeyUp(&in_use);} -void IN_JumpDown (void) {KeyDown(&in_jump);} -void IN_JumpUp (void) {KeyUp(&in_jump);} -void IN_DuckDown(void) {KeyDown(&in_duck);} -void IN_DuckUp(void) {KeyUp(&in_duck);} -void IN_ReloadDown(void) {KeyDown(&in_reload);} -void IN_ReloadUp(void) {KeyUp(&in_reload);} -void IN_Alt1Down(void) {KeyDown(&in_alt1);} -void IN_Alt1Up(void) {KeyUp(&in_alt1);} -void IN_GraphDown(void) {KeyDown(&in_graph);} -void IN_GraphUp(void) {KeyUp(&in_graph);} - -void IN_AttackDown(void) -{ - KeyDown( &in_attack ); -} - -void IN_AttackUp(void) -{ - KeyUp( &in_attack ); - in_cancel = 0; -} - -// Special handling -void IN_Cancel(void) -{ - in_cancel = 1; -} - -void IN_Impulse (void) -{ - in_impulse = atoi( gEngfuncs.Cmd_Argv(1) ); -} - -void IN_ScoreDown(void) -{ - KeyDown(&in_score); - if ( gViewPort ) - { - gViewPort->ShowScoreBoard(); - } -} - -void IN_ScoreUp(void) -{ - KeyUp(&in_score); - if ( gViewPort ) - { - gViewPort->HideScoreBoard(); - } -} - -void IN_MLookUp (void) -{ - KeyUp( &in_mlook ); - if ( !( in_mlook.state & 1 ) && lookspring->value ) - { - V_StartPitchDrift(); - } -} - -/* -=============== -CL_KeyState - -Returns 0.25 if a key was pressed and released during the frame, -0.5 if it was pressed and held -0 if held then released, and -1.0 if held for the entire time -=============== -*/ -float CL_KeyState (kbutton_t *key) -{ - float val = 0.0; - int impulsedown, impulseup, down; - - impulsedown = key->state & 2; - impulseup = key->state & 4; - down = key->state & 1; - - if ( impulsedown && !impulseup ) - { - // pressed and held this frame? - val = down ? 0.5 : 0.0; - } - - if ( impulseup && !impulsedown ) - { - // released this frame? - val = down ? 0.0 : 0.0; - } - - if ( !impulsedown && !impulseup ) - { - // held the entire frame? - val = down ? 1.0 : 0.0; - } - - if ( impulsedown && impulseup ) - { - if ( down ) - { - // released and re-pressed this frame - val = 0.75; - } - else - { - // pressed and released this frame - val = 0.25; - } - } - - // clear impulses - key->state &= 1; - return val; -} - -bool bCanMoveMouse ( void ) -{ - if ( gViewPort && ( gViewPort->m_iUser1 == OBS_ROAMING || gViewPort->m_iUser1 == OBS_CHASE_FREE ) ) - return TRUE; - - if ( gViewPort && gViewPort->m_iUser1 == OBS_LOCKEDVIEW ) - return FALSE; - - return TRUE; -} -/* -================ -CL_AdjustAngles - -Moves the local angle positions -================ -*/ -void CL_AdjustAngles ( float frametime, float *viewangles ) -{ - float speed; - float up, down; - - if (in_speed.state & 1) - { - speed = frametime * cl_anglespeedkey->value; - } - else - { - speed = frametime; - } - - // Ricochet: Don't let them move the mouse when they're in spectator mode - if ( bCanMoveMouse() == FALSE ) - return; - - if (!(in_strafe.state & 1)) - { - viewangles[YAW] -= speed*cl_yawspeed->value*CL_KeyState (&in_right); - viewangles[YAW] += speed*cl_yawspeed->value*CL_KeyState (&in_left); - viewangles[YAW] = anglemod(viewangles[YAW]); - } - if (in_klook.state & 1) - { - V_StopPitchDrift (); - viewangles[PITCH] -= speed*cl_pitchspeed->value * CL_KeyState (&in_forward); - viewangles[PITCH] += speed*cl_pitchspeed->value * CL_KeyState (&in_back); - } - - up = CL_KeyState (&in_lookup); - down = CL_KeyState(&in_lookdown); - - viewangles[PITCH] -= speed*cl_pitchspeed->value * up; - viewangles[PITCH] += speed*cl_pitchspeed->value * down; - - if (up || down) - V_StopPitchDrift (); - - if (viewangles[PITCH] > cl_pitchdown->value) - viewangles[PITCH] = cl_pitchdown->value; - if (viewangles[PITCH] < -cl_pitchup->value) - viewangles[PITCH] = -cl_pitchup->value; - - if (viewangles[ROLL] > 50) - viewangles[ROLL] = 50; - if (viewangles[ROLL] < -50) - viewangles[ROLL] = -50; -} - -/* -================ -CL_CreateMove - -Send the intended movement message to the server -if active == 1 then we are 1) not playing back demos ( where our commands are ignored ) and -2 ) we have finished signing on to server -================ -*/ -void DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ) -{ - float spd; - vec3_t viewangles; - static vec3_t oldangles; - - if ( active ) - { - //memset( viewangles, 0, sizeof( vec3_t ) ); - //viewangles[ 0 ] = viewangles[ 1 ] = viewangles[ 2 ] = 0.0; - gEngfuncs.GetViewAngles( (float *)viewangles ); - - CL_AdjustAngles ( frametime, viewangles ); - - memset (cmd, 0, sizeof(*cmd)); - - gEngfuncs.SetViewAngles( (float *)viewangles ); - - if ( in_strafe.state & 1 ) - { - cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_right); - cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_left); - } - - cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_moveright); - cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_moveleft); - - cmd->upmove += cl_upspeed->value * CL_KeyState (&in_up); - cmd->upmove -= cl_upspeed->value * CL_KeyState (&in_down); - - if ( !(in_klook.state & 1 ) ) - { - cmd->forwardmove += cl_forwardspeed->value * CL_KeyState (&in_forward); - cmd->forwardmove -= cl_backspeed->value * CL_KeyState (&in_back); - } - - // adjust for speed key - if ( in_speed.state & 1 ) - { - cmd->forwardmove *= cl_movespeedkey->value; - cmd->sidemove *= cl_movespeedkey->value; - cmd->upmove *= cl_movespeedkey->value; - } - - // clip to maxspeed - spd = gEngfuncs.GetClientMaxspeed(); - if ( spd != 0.0 ) - { - // scale the 3 speeds so that the total velocity is not > cl.maxspeed - float fmov = sqrt( (cmd->forwardmove*cmd->forwardmove) + (cmd->sidemove*cmd->sidemove) + (cmd->upmove*cmd->upmove) ); - - if ( fmov > spd ) - { - float fratio = spd / fmov; - cmd->forwardmove *= fratio; - cmd->sidemove *= fratio; - cmd->upmove *= fratio; - } - } - - // Allow mice and other controllers to add their inputs - IN_Move ( frametime, cmd ); - } - - cmd->impulse = in_impulse; - in_impulse = 0; - - cmd->weaponselect = g_weaponselect; - g_weaponselect = 0; - // - // set button and flag bits - // - cmd->buttons = CL_ButtonBits( 1 ); - - // If they're in a modal dialog, ignore the attack button. - if( GetClientVoiceMgr()->IsInSquelchMode() ) - cmd->buttons &= ~IN_ATTACK; - - // Using joystick? - if ( in_joystick->value ) - { - if ( cmd->forwardmove > 0 ) - { - cmd->buttons |= IN_FORWARD; - } - else if ( cmd->forwardmove < 0 ) - { - cmd->buttons |= IN_BACK; - } - } - - gEngfuncs.GetViewAngles( (float *)viewangles ); - // Set current view angles. - - if ( gHUD.m_Health.m_iHealth > 0 ) - { - VectorCopy( viewangles, cmd->viewangles ); - VectorCopy( viewangles, oldangles ); - } - else - { - VectorCopy( oldangles, cmd->viewangles ); - } -} - -/* -============ -CL_IsDead - -Returns 1 if health is <= 0 -============ -*/ -int CL_IsDead( void ) -{ - return ( gHUD.m_Health.m_iHealth <= 0 ) ? 1 : 0; -} - -/* -============ -CL_ButtonBits - -Returns appropriate button info for keyboard and mouse state -Set bResetState to 1 to clear old state info -============ -*/ -int CL_ButtonBits( int bResetState ) -{ - int bits = 0; - - if ( in_attack.state & 3 ) - { - bits |= IN_ATTACK; - } - - if (in_duck.state & 3) - { - bits |= IN_DUCK; - } - - if (in_jump.state & 3) - { - bits |= IN_JUMP; - } - - if ( in_forward.state & 3 ) - { - bits |= IN_FORWARD; - } - - if (in_back.state & 3) - { - bits |= IN_BACK; - } - - if (in_use.state & 3) - { - bits |= IN_USE; - } - - if (in_cancel) - { - bits |= IN_CANCEL; - } - - if ( in_left.state & 3 ) - { - bits |= IN_LEFT; - } - - if (in_right.state & 3) - { - bits |= IN_RIGHT; - } - - if ( in_moveleft.state & 3 ) - { - bits |= IN_MOVELEFT; - } - - if (in_moveright.state & 3) - { - bits |= IN_MOVERIGHT; - } - - if (in_attack2.state & 3) - { - bits |= IN_ATTACK2; - } - - if (in_reload.state & 3) - { - bits |= IN_RELOAD; - } - - if (in_alt1.state & 3) - { - bits |= IN_ALT1; - } - - if ( in_score.state & 3 ) - { - bits |= IN_SCORE; - } - - // Dead or in intermission? Shore scoreboard, too - if ( CL_IsDead() || gHUD.m_iIntermission ) - { - bits |= IN_SCORE; - } - - if ( bResetState ) - { - in_attack.state &= ~2; - in_duck.state &= ~2; - in_jump.state &= ~2; - in_forward.state &= ~2; - in_back.state &= ~2; - in_use.state &= ~2; - in_left.state &= ~2; - in_right.state &= ~2; - in_moveleft.state &= ~2; - in_moveright.state &= ~2; - in_attack2.state &= ~2; - in_reload.state &= ~2; - in_alt1.state &= ~2; - in_score.state &= ~2; - } - - return bits; -} - -/* -============ -CL_ResetButtonBits - -============ -*/ -void CL_ResetButtonBits( int bits ) -{ - int bitsNew = CL_ButtonBits( 0 ) ^ bits; - - // Has the attack button been changed - if ( bitsNew & IN_ATTACK ) - { - // Was it pressed? or let go? - if ( bits & IN_ATTACK ) - { - KeyDown( &in_attack ); - } - else - { - // totally clear state - in_attack.state &= ~7; - } - } -} - -/* -============ -InitInput -============ -*/ -void InitInput (void) -{ - gEngfuncs.pfnAddCommand ("+moveup",IN_UpDown); - gEngfuncs.pfnAddCommand ("-moveup",IN_UpUp); - gEngfuncs.pfnAddCommand ("+movedown",IN_DownDown); - gEngfuncs.pfnAddCommand ("-movedown",IN_DownUp); - gEngfuncs.pfnAddCommand ("+left",IN_LeftDown); - gEngfuncs.pfnAddCommand ("-left",IN_LeftUp); - gEngfuncs.pfnAddCommand ("+right",IN_RightDown); - gEngfuncs.pfnAddCommand ("-right",IN_RightUp); - gEngfuncs.pfnAddCommand ("+forward",IN_ForwardDown); - gEngfuncs.pfnAddCommand ("-forward",IN_ForwardUp); - gEngfuncs.pfnAddCommand ("+back",IN_BackDown); - gEngfuncs.pfnAddCommand ("-back",IN_BackUp); - gEngfuncs.pfnAddCommand ("+lookup", IN_LookupDown); - gEngfuncs.pfnAddCommand ("-lookup", IN_LookupUp); - gEngfuncs.pfnAddCommand ("+lookdown", IN_LookdownDown); - gEngfuncs.pfnAddCommand ("-lookdown", IN_LookdownUp); - gEngfuncs.pfnAddCommand ("+strafe", IN_StrafeDown); - gEngfuncs.pfnAddCommand ("-strafe", IN_StrafeUp); - gEngfuncs.pfnAddCommand ("+moveleft", IN_MoveleftDown); - gEngfuncs.pfnAddCommand ("-moveleft", IN_MoveleftUp); - gEngfuncs.pfnAddCommand ("+moveright", IN_MoverightDown); - gEngfuncs.pfnAddCommand ("-moveright", IN_MoverightUp); - gEngfuncs.pfnAddCommand ("+speed", IN_SpeedDown); - gEngfuncs.pfnAddCommand ("-speed", IN_SpeedUp); - gEngfuncs.pfnAddCommand ("+attack", IN_AttackDown); - gEngfuncs.pfnAddCommand ("-attack", IN_AttackUp); - gEngfuncs.pfnAddCommand ("+attack2", IN_Attack2Down); - gEngfuncs.pfnAddCommand ("-attack2", IN_Attack2Up); - gEngfuncs.pfnAddCommand ("+use", IN_UseDown); - gEngfuncs.pfnAddCommand ("-use", IN_UseUp); - gEngfuncs.pfnAddCommand ("+jump", IN_JumpDown); - gEngfuncs.pfnAddCommand ("-jump", IN_JumpUp); - gEngfuncs.pfnAddCommand ("impulse", IN_Impulse); - gEngfuncs.pfnAddCommand ("+klook", IN_KLookDown); - gEngfuncs.pfnAddCommand ("-klook", IN_KLookUp); - gEngfuncs.pfnAddCommand ("+mlook", IN_MLookDown); - gEngfuncs.pfnAddCommand ("-mlook", IN_MLookUp); - gEngfuncs.pfnAddCommand ("+jlook", IN_JLookDown); - gEngfuncs.pfnAddCommand ("-jlook", IN_JLookUp); - gEngfuncs.pfnAddCommand ("+duck", IN_DuckDown); - gEngfuncs.pfnAddCommand ("-duck", IN_DuckUp); - gEngfuncs.pfnAddCommand ("+reload", IN_ReloadDown); - gEngfuncs.pfnAddCommand ("-reload", IN_ReloadUp); - gEngfuncs.pfnAddCommand ("+alt1", IN_Alt1Down); - gEngfuncs.pfnAddCommand ("-alt1", IN_Alt1Up); - gEngfuncs.pfnAddCommand ("+score", IN_ScoreDown); - gEngfuncs.pfnAddCommand ("-score", IN_ScoreUp); - gEngfuncs.pfnAddCommand ("+showscores", IN_ScoreDown); - gEngfuncs.pfnAddCommand ("-showscores", IN_ScoreUp); - gEngfuncs.pfnAddCommand ("+graph", IN_GraphDown); - gEngfuncs.pfnAddCommand ("-graph", IN_GraphUp); - gEngfuncs.pfnAddCommand ("+break",IN_BreakDown); - gEngfuncs.pfnAddCommand ("-break",IN_BreakUp); - - lookstrafe = gEngfuncs.pfnRegisterVariable ( "lookstrafe", "0", FCVAR_ARCHIVE ); - lookspring = gEngfuncs.pfnRegisterVariable ( "lookspring", "0", FCVAR_ARCHIVE ); - cl_anglespeedkey = gEngfuncs.pfnRegisterVariable ( "cl_anglespeedkey", "0.67", 0 ); - cl_yawspeed = gEngfuncs.pfnRegisterVariable ( "cl_yawspeed", "210", 0 ); - cl_pitchspeed = gEngfuncs.pfnRegisterVariable ( "cl_pitchspeed", "225", 0 ); - cl_upspeed = gEngfuncs.pfnRegisterVariable ( "cl_upspeed", "320", 0 ); - cl_forwardspeed = gEngfuncs.pfnRegisterVariable ( "cl_forwardspeed", "400", FCVAR_ARCHIVE ); - cl_backspeed = gEngfuncs.pfnRegisterVariable ( "cl_backspeed", "400", FCVAR_ARCHIVE ); - cl_sidespeed = gEngfuncs.pfnRegisterVariable ( "cl_sidespeed", "400", 0 ); - cl_movespeedkey = gEngfuncs.pfnRegisterVariable ( "cl_movespeedkey", "0.3", 0 ); - cl_pitchup = gEngfuncs.pfnRegisterVariable ( "cl_pitchup", "89", 0 ); - cl_pitchdown = gEngfuncs.pfnRegisterVariable ( "cl_pitchdown", "89", 0 ); - - cl_vsmoothing = gEngfuncs.pfnRegisterVariable ( "cl_vsmoothing", "0.05", FCVAR_ARCHIVE ); - - m_pitch = gEngfuncs.pfnRegisterVariable ( "m_pitch","0.022", FCVAR_ARCHIVE ); - m_yaw = gEngfuncs.pfnRegisterVariable ( "m_yaw","0.022", FCVAR_ARCHIVE ); - m_forward = gEngfuncs.pfnRegisterVariable ( "m_forward","1", FCVAR_ARCHIVE ); - m_side = gEngfuncs.pfnRegisterVariable ( "m_side","0.8", FCVAR_ARCHIVE ); - - // Initialize third person camera controls. - CAM_Init(); - // Initialize inputs - IN_Init(); - // Initialize keyboard - KB_Init(); - // Initialize view system - V_Init(); -} - -/* -============ -ShutdownInput -============ -*/ -void ShutdownInput (void) -{ - IN_Shutdown(); - KB_Shutdown(); -} - -#include "interface.h" - -void DLLEXPORT HUD_Shutdown( void ) -{ - ShutdownInput(); - - extern CSysModule *g_hTrackerModule; - if (g_hTrackerModule) - { - Sys_UnloadModule(g_hTrackerModule); - } -} \ No newline at end of file diff --git a/ricochet/cl_dll/inputw32.cpp b/ricochet/cl_dll/inputw32.cpp deleted file mode 100644 index 8074aff..0000000 --- a/ricochet/cl_dll/inputw32.cpp +++ /dev/null @@ -1,938 +0,0 @@ -// in_win.c -- windows 95 mouse and joystick code -// 02/21/97 JCB Added extended DirectInput code to support external controllers. - -#include "port.h" -#include -#include - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "../public/keydefs.h" -#include "view.h" -#include "Exports.h" - -#define MOUSE_BUTTON_COUNT 5 - -// Set this to 1 to show mouse cursor. Experimental -int g_iVisibleMouse = 0; - -extern cl_enginefunc_t gEngfuncs; - -extern int iMouseInUse; - -extern kbutton_t in_strafe; -extern kbutton_t in_mlook; -extern kbutton_t in_speed; -extern kbutton_t in_jlook; - -extern cvar_t *m_pitch; -extern cvar_t *m_yaw; -extern cvar_t *m_forward; -extern cvar_t *m_side; - -extern cvar_t *lookstrafe; -extern cvar_t *lookspring; -extern cvar_t *cl_pitchdown; -extern cvar_t *cl_pitchup; -extern cvar_t *cl_yawspeed; -extern cvar_t *cl_sidespeed; -extern cvar_t *cl_forwardspeed; -extern cvar_t *cl_pitchspeed; -extern cvar_t *cl_movespeedkey; - -// mouse variables -cvar_t *m_filter; -cvar_t *sensitivity; - -// Custom mouse acceleration (0 disable, 1 to enable, 2 enable with separate yaw/pitch rescale) -static cvar_t *m_customaccel; -//Formula: mousesensitivity = ( rawmousedelta^m_customaccel_exponent ) * m_customaccel_scale + sensitivity -// If mode is 2, then x and y sensitivity are scaled by m_pitch and m_yaw respectively. -// Custom mouse acceleration value. -static cvar_t *m_customaccel_scale; -//Max mouse move scale factor, 0 for no limit -static cvar_t *m_customaccel_max; -//Mouse move is raised to this power before being scaled by scale factor -static cvar_t *m_customaccel_exponent; - -int mouse_buttons; -int mouse_oldbuttonstate; -POINT current_pos; -int old_mouse_x, old_mouse_y, mx_accum, my_accum; -float mouse_x, mouse_y; - -static int restore_spi; -static int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; -static int mouseactive; -int mouseinitialized; -static int mouseparmsvalid; -static int mouseshowtoggle = 1; - -// joystick defines and variables -// where should defines be moved? -#define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick -#define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball -#define JOY_MAX_AXES 6 // X, Y, Z, R, U, V -#define JOY_AXIS_X 0 -#define JOY_AXIS_Y 1 -#define JOY_AXIS_Z 2 -#define JOY_AXIS_R 3 -#define JOY_AXIS_U 4 -#define JOY_AXIS_V 5 - -enum _ControlList -{ - AxisNada = 0, - AxisForward, - AxisLook, - AxisSide, - AxisTurn -}; - - -DWORD dwAxisMap[ JOY_MAX_AXES ]; -DWORD dwControlMap[ JOY_MAX_AXES ]; -DWORD pdwRawValue[ JOY_MAX_AXES ]; -DWORD joy_oldbuttonstate, joy_oldpovstate; - -int joy_id; -DWORD joy_numbuttons; -SDL_GameController *s_pJoystick = NULL; - - -// none of these cvars are saved over a session -// this means that advanced controller configuration needs to be executed -// each time. this avoids any problems with getting back to a default usage -// or when changing from one controller to another. this way at least something -// works. -cvar_t *in_joystick; -cvar_t *joy_name; -cvar_t *joy_advanced; -cvar_t *joy_advaxisx; -cvar_t *joy_advaxisy; -cvar_t *joy_advaxisz; -cvar_t *joy_advaxisr; -cvar_t *joy_advaxisu; -cvar_t *joy_advaxisv; -cvar_t *joy_forwardthreshold; -cvar_t *joy_sidethreshold; -cvar_t *joy_pitchthreshold; -cvar_t *joy_yawthreshold; -cvar_t *joy_forwardsensitivity; -cvar_t *joy_sidesensitivity; -cvar_t *joy_pitchsensitivity; -cvar_t *joy_yawsensitivity; -cvar_t *joy_wwhack1; -cvar_t *joy_wwhack2; - -int joy_avail, joy_advancedinit, joy_haspov; - -/* -=========== -Force_CenterView_f -=========== -*/ -void Force_CenterView_f (void) -{ - vec3_t viewangles; - - if (!iMouseInUse) - { - gEngfuncs.GetViewAngles( (float *)viewangles ); - viewangles[PITCH] = 0; - gEngfuncs.SetViewAngles( (float *)viewangles ); - } -} - -/* -=========== -IN_ActivateMouse -=========== -*/ -void DLLEXPORT IN_ActivateMouse (void) -{ - if (mouseinitialized) - { -#ifdef _WIN32 - if (mouseparmsvalid) - restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); -#endif - mouseactive = 1; - } -} - -/* -=========== -IN_DeactivateMouse -=========== -*/ -void DLLEXPORT IN_DeactivateMouse (void) -{ - if (mouseinitialized) - { -#ifdef _WIN32 - if (restore_spi) - SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); -#endif - - mouseactive = 0; - } -} - -/* -=========== -IN_StartupMouse -=========== -*/ -void IN_StartupMouse (void) -{ - if ( gEngfuncs.CheckParm ("-nomouse", NULL ) ) - return; - - mouseinitialized = 1; -#ifdef _WIN32 - mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); - - if (mouseparmsvalid) - { - if ( gEngfuncs.CheckParm ("-noforcemspd", NULL ) ) - newmouseparms[2] = originalmouseparms[2]; - - if ( gEngfuncs.CheckParm ("-noforcemaccel", NULL ) ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - } - - if ( gEngfuncs.CheckParm ("-noforcemparms", NULL ) ) - { - newmouseparms[0] = originalmouseparms[0]; - newmouseparms[1] = originalmouseparms[1]; - newmouseparms[2] = originalmouseparms[2]; - } - } -#endif - - mouse_buttons = MOUSE_BUTTON_COUNT; -} - -/* -=========== -IN_Shutdown -=========== -*/ -void IN_Shutdown (void) -{ - IN_DeactivateMouse (); -} - -/* -=========== -IN_GetMousePos - -Ask for mouse position from engine -=========== -*/ -void IN_GetMousePos( int *mx, int *my ) -{ - gEngfuncs.GetMousePosition( mx, my ); -} - -/* -=========== -IN_ResetMouse - -FIXME: Call through to engine? -=========== -*/ -void IN_ResetMouse( void ) -{ -} - -/* -=========== -IN_MouseEvent -=========== -*/ -void DLLEXPORT IN_MouseEvent (int mstate) -{ - int i; - - if ( iMouseInUse || g_iVisibleMouse ) - return; - - // perform button actions - for (i=0 ; ivalue; - - // Using special accleration values - if ( m_customaccel->value != 0 ) - { - float raw_mouse_movement_distance = sqrt( mx * mx + my * my ); - float acceleration_scale = m_customaccel_scale->value; - float accelerated_sensitivity_max = m_customaccel_max->value; - float accelerated_sensitivity_exponent = m_customaccel_exponent->value; - float accelerated_sensitivity = ( (float)pow( raw_mouse_movement_distance, accelerated_sensitivity_exponent ) * acceleration_scale + mouse_senstivity ); - - if ( accelerated_sensitivity_max > 0.0001f && - accelerated_sensitivity > accelerated_sensitivity_max ) - { - accelerated_sensitivity = accelerated_sensitivity_max; - } - - *x *= accelerated_sensitivity; - *y *= accelerated_sensitivity; - - // Further re-scale by yaw and pitch magnitude if user requests alternate mode 2 - // This means that they will need to up their value for m_customaccel_scale greatly (>40x) since m_pitch/yaw default - // to 0.022 - if ( m_customaccel->value == 2 ) - { - *x *= m_yaw->value; - *y *= m_pitch->value; - } - } - else - { - // Just apply the default - *x *= mouse_senstivity; - *y *= mouse_senstivity; - } -} - -/* -=========== -IN_MouseMove -=========== -*/ -bool bCanMoveMouse ( void ); -void IN_MouseMove ( float frametime, usercmd_t *cmd) -{ - int mx, my; - vec3_t viewangles; - - gEngfuncs.GetViewAngles( (float *)viewangles ); - - if ( in_mlook.state & 1) - { - V_StopPitchDrift (); - } - - // Ricochet: Don't let them move the mouse when they're in spectator mode - int iSpectator = !bCanMoveMouse(); - - //jjb - this disbles normal mouse control if the user is trying to - // move the camera, or if the mouse cursor is visible or if we're in intermission - if ( !iMouseInUse && !gHUD.m_iIntermission && !g_iVisibleMouse && !iSpectator ) - { - int deltaX, deltaY; - SDL_GetRelativeMouseState( &deltaX, &deltaY ); - current_pos.x = deltaX; - current_pos.y = deltaY; - mx = deltaX + mx_accum; - my = deltaY + my_accum; - - mx_accum = 0; - my_accum = 0; - - if (m_filter->value) - { - mouse_x = (mx + old_mouse_x) * 0.5; - mouse_y = (my + old_mouse_y) * 0.5; - } - else - { - mouse_x = mx; - mouse_y = my; - } - - old_mouse_x = mx; - old_mouse_y = my; - - // Apply custom mouse scaling/acceleration - IN_ScaleMouse( &mouse_x, &mouse_y ); - - // add mouse X/Y movement to cmd - if ( (in_strafe.state & 1) || (lookstrafe->value && (in_mlook.state & 1) )) - cmd->sidemove += m_side->value * mouse_x; - else - viewangles[YAW] -= m_yaw->value * mouse_x; - - if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) - { - viewangles[PITCH] += m_pitch->value * mouse_y; - if (viewangles[PITCH] > cl_pitchdown->value) - viewangles[PITCH] = cl_pitchdown->value; - if (viewangles[PITCH] < -cl_pitchup->value) - viewangles[PITCH] = -cl_pitchup->value; - } - else - { - if ((in_strafe.state & 1) && gEngfuncs.IsNoClipping() ) - { - cmd->upmove -= m_forward->value * mouse_y; - } - else - { - cmd->forwardmove -= m_forward->value * mouse_y; - } - } - - // if the mouse has moved, force it to the center, so there's room to move - if ( mx || my ) - { - IN_ResetMouse(); - } - } - - gEngfuncs.SetViewAngles( (float *)viewangles ); - -/* -//#define TRACE_TEST -#if defined( TRACE_TEST ) - { - int mx, my; - void V_Move( int mx, int my ); - IN_GetMousePos( &mx, &my ); - V_Move( mx, my ); - } -#endif -*/ -} - -/* -=========== -IN_Accumulate -=========== -*/ -void DLLEXPORT IN_Accumulate (void) -{ - //only accumulate mouse if we are not moving the camera with the mouse - if ( !iMouseInUse && !g_iVisibleMouse) - { - if (mouseactive) - { - int deltaX, deltaY; - SDL_GetRelativeMouseState( &deltaX, &deltaY ); - mx_accum += deltaX; - my_accum += deltaY; - // force the mouse to the center, so there's room to move - IN_ResetMouse(); - - } - } - -} - -/* -=================== -IN_ClearStates -=================== -*/ -void DLLEXPORT IN_ClearStates (void) -{ - if ( !mouseactive ) - return; - - mx_accum = 0; - my_accum = 0; - mouse_oldbuttonstate = 0; -} - -/* -=============== -IN_StartupJoystick -=============== -*/ -void IN_StartupJoystick (void) -{ - // abort startup if user requests no joystick - if ( gEngfuncs.CheckParm ("-nojoy", NULL ) ) - return; - - // assume no joystick - joy_avail = 0; - - int nJoysticks = SDL_NumJoysticks(); - if ( nJoysticks > 0 ) - { - for ( int i = 0; i < nJoysticks; i++ ) - { - if ( SDL_IsGameController( i ) ) - { - s_pJoystick = SDL_GameControllerOpen( i ); - if ( s_pJoystick ) - { - //save the joystick's number of buttons and POV status - joy_numbuttons = SDL_CONTROLLER_BUTTON_MAX; - joy_haspov = 0; - - // old button and POV states default to no buttons pressed - joy_oldbuttonstate = joy_oldpovstate = 0; - - // mark the joystick as available and advanced initialization not completed - // this is needed as cvars are not available during initialization - gEngfuncs.Con_Printf ("joystick found\n\n", SDL_GameControllerName(s_pJoystick)); - joy_avail = 1; - joy_advancedinit = 0; - break; - } - - } - } - } - else - { - gEngfuncs.Con_DPrintf ("joystick not found -- driver not present\n\n"); - } - -} - -int RawValuePointer (int axis) -{ - switch (axis) - { - default: - case JOY_AXIS_X: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTX ); - case JOY_AXIS_Y: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_LEFTY ); - case JOY_AXIS_Z: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTX ); - case JOY_AXIS_R: - return SDL_GameControllerGetAxis( s_pJoystick, SDL_CONTROLLER_AXIS_RIGHTY ); - - } -} - - -/* -=========== -Joy_AdvancedUpdate_f -=========== -*/ -void Joy_AdvancedUpdate_f (void) -{ - - // called once by IN_ReadJoystick and by user whenever an update is needed - // cvars are now available - int i; - DWORD dwTemp; - - // initialize all the maps - for (i = 0; i < JOY_MAX_AXES; i++) - { - dwAxisMap[i] = AxisNada; - dwControlMap[i] = JOY_ABSOLUTE_AXIS; - pdwRawValue[i] = RawValuePointer(i); - } - - if( joy_advanced->value == 0.0) - { - // default joystick initialization - // 2 axes only with joystick control - dwAxisMap[JOY_AXIS_X] = AxisTurn; - // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS; - dwAxisMap[JOY_AXIS_Y] = AxisForward; - // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS; - } - else - { - if ( strcmp ( joy_name->string, "joystick") != 0 ) - { - // notify user of advanced controller - gEngfuncs.Con_Printf ("\n%s configured\n\n", joy_name->string); - } - - // advanced initialization here - // data supplied by user via joy_axisn cvars - dwTemp = (DWORD) joy_advaxisx->value; - dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisy->value; - dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisz->value; - dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisr->value; - dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisu->value; - dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; - dwTemp = (DWORD) joy_advaxisv->value; - dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; - dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; - } - -} - - -/* -=========== -IN_Commands -=========== -*/ -void IN_Commands (void) -{ - int i, key_index; - - if (!joy_avail) - { - return; - } - - DWORD buttonstate, povstate; - - // loop through the joystick buttons - // key a joystick event or auxillary event for higher number buttons for each state change - buttonstate = 0; - for ( i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++ ) - { - if ( SDL_GameControllerGetButton( s_pJoystick, (SDL_GameControllerButton)i ) ) - { - buttonstate |= 1<value) - { - return; - } - - // collect the joystick data, if possible - if (IN_ReadJoystick () != 1) - { - return; - } - - if (in_speed.state & 1) - speed = cl_movespeedkey->value; - else - speed = 1; - - aspeed = speed * frametime; - - // loop through the axes - for (i = 0; i < JOY_MAX_AXES; i++) - { - // get the floating point zero-centered, potentially-inverted data for the current axis - fAxisValue = (float) pdwRawValue[i]; - // move centerpoint to zero - fAxisValue -= 32768.0; - - if (joy_wwhack2->value != 0.0) - { - if (dwAxisMap[i] == AxisTurn) - { - // this is a special formula for the Logitech WingMan Warrior - // y=ax^b; where a = 300 and b = 1.3 - // also x values are in increments of 800 (so this is factored out) - // then bounds check result to level out excessively high spin rates - fTemp = 300.0 * pow( fabs(fAxisValue) / 800.0, 1.3); - if (fTemp > 14000.0) - fTemp = 14000.0; - // restore direction information - fAxisValue = (fAxisValue > 0.0) ? fTemp : -fTemp; - } - } - - // convert range from -32768..32767 to -1..1 - fAxisValue /= 32768.0; - - switch (dwAxisMap[i]) - { - case AxisForward: - if ((joy_advanced->value == 0.0) && (in_jlook.state & 1)) - { - // user wants forward control to become look control - if (fabs(fAxisValue) > joy_pitchthreshold->value) - { - // if mouse invert is on, invert the joystick pitch value - // only absolute control support here (joy_advanced is 0) - if (m_pitch->value < 0.0) - { - viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; - } - else - { - viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; - } - V_StopPitchDrift(); - } - else - { - // no pitch movement - // disable pitch return-to-center unless requested by user - // *** this code can be removed when the lookspring bug is fixed - // *** the bug always has the lookspring feature on - if(lookspring->value == 0.0) - { - V_StopPitchDrift(); - } - } - } - else - { - // user wants forward control to be forward control - if (fabs(fAxisValue) > joy_forwardthreshold->value) - { - cmd->forwardmove += (fAxisValue * joy_forwardsensitivity->value) * speed * cl_forwardspeed->value; - } - } - break; - - case AxisSide: - if (fabs(fAxisValue) > joy_sidethreshold->value) - { - cmd->sidemove += (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; - } - break; - - case AxisTurn: - if ((in_strafe.state & 1) || (lookstrafe->value && (in_jlook.state & 1))) - { - // user wants turn control to become side control - if (fabs(fAxisValue) > joy_sidethreshold->value) - { - cmd->sidemove -= (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; - } - } - else - { - // user wants turn control to be turn control - if (fabs(fAxisValue) > joy_yawthreshold->value) - { - if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) - { - viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * aspeed * cl_yawspeed->value; - } - else - { - viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * speed * 180.0; - } - - } - } - break; - - case AxisLook: - if (in_jlook.state & 1) - { - if (fabs(fAxisValue) > joy_pitchthreshold->value) - { - // pitch movement detected and pitch movement desired by user - if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) - { - viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; - } - else - { - viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * speed * 180.0; - } - V_StopPitchDrift(); - } - else - { - // no pitch movement - // disable pitch return-to-center unless requested by user - // *** this code can be removed when the lookspring bug is fixed - // *** the bug always has the lookspring feature on - if( lookspring->value == 0.0 ) - { - V_StopPitchDrift(); - } - } - } - break; - - default: - break; - } - } - - // bounds check pitch - if (viewangles[PITCH] > cl_pitchdown->value) - viewangles[PITCH] = cl_pitchdown->value; - if (viewangles[PITCH] < -cl_pitchup->value) - viewangles[PITCH] = -cl_pitchup->value; - - gEngfuncs.SetViewAngles( (float *)viewangles ); -#endif -} - -/* -=========== -IN_Move -=========== -*/ -void IN_Move ( float frametime, usercmd_t *cmd) -{ - if ( !iMouseInUse && mouseactive ) - { - IN_MouseMove ( frametime, cmd); - } - - IN_JoyMove ( frametime, cmd); -} - -/* -=========== -IN_Init -=========== -*/ -void IN_Init (void) -{ - m_filter = gEngfuncs.pfnRegisterVariable ( "m_filter","0", FCVAR_ARCHIVE ); - sensitivity = gEngfuncs.pfnRegisterVariable ( "sensitivity","3", FCVAR_ARCHIVE ); // user mouse sensitivity setting. - - in_joystick = gEngfuncs.pfnRegisterVariable ( "joystick","0", FCVAR_ARCHIVE ); - joy_name = gEngfuncs.pfnRegisterVariable ( "joyname", "joystick", 0 ); - joy_advanced = gEngfuncs.pfnRegisterVariable ( "joyadvanced", "0", 0 ); - joy_advaxisx = gEngfuncs.pfnRegisterVariable ( "joyadvaxisx", "0", 0 ); - joy_advaxisy = gEngfuncs.pfnRegisterVariable ( "joyadvaxisy", "0", 0 ); - joy_advaxisz = gEngfuncs.pfnRegisterVariable ( "joyadvaxisz", "0", 0 ); - joy_advaxisr = gEngfuncs.pfnRegisterVariable ( "joyadvaxisr", "0", 0 ); - joy_advaxisu = gEngfuncs.pfnRegisterVariable ( "joyadvaxisu", "0", 0 ); - joy_advaxisv = gEngfuncs.pfnRegisterVariable ( "joyadvaxisv", "0", 0 ); - joy_forwardthreshold = gEngfuncs.pfnRegisterVariable ( "joyforwardthreshold", "0.15", 0 ); - joy_sidethreshold = gEngfuncs.pfnRegisterVariable ( "joysidethreshold", "0.15", 0 ); - joy_pitchthreshold = gEngfuncs.pfnRegisterVariable ( "joypitchthreshold", "0.15", 0 ); - joy_yawthreshold = gEngfuncs.pfnRegisterVariable ( "joyyawthreshold", "0.15", 0 ); - joy_forwardsensitivity = gEngfuncs.pfnRegisterVariable ( "joyforwardsensitivity", "-1.0", 0 ); - joy_sidesensitivity = gEngfuncs.pfnRegisterVariable ( "joysidesensitivity", "-1.0", 0 ); - joy_pitchsensitivity = gEngfuncs.pfnRegisterVariable ( "joypitchsensitivity", "1.0", 0 ); - joy_yawsensitivity = gEngfuncs.pfnRegisterVariable ( "joyyawsensitivity", "-1.0", 0 ); - joy_wwhack1 = gEngfuncs.pfnRegisterVariable ( "joywwhack1", "0.0", 0 ); - joy_wwhack2 = gEngfuncs.pfnRegisterVariable ( "joywwhack2", "0.0", 0 ); - - m_customaccel = gEngfuncs.pfnRegisterVariable ( "m_customaccel", "0", FCVAR_ARCHIVE ); - m_customaccel_scale = gEngfuncs.pfnRegisterVariable ( "m_customaccel_scale", "0.04", FCVAR_ARCHIVE ); - m_customaccel_max = gEngfuncs.pfnRegisterVariable ( "m_customaccel_max", "0", FCVAR_ARCHIVE ); - m_customaccel_exponent = gEngfuncs.pfnRegisterVariable ( "m_customaccel_exponent", "1", FCVAR_ARCHIVE ); - - gEngfuncs.pfnAddCommand ("force_centerview", Force_CenterView_f); - gEngfuncs.pfnAddCommand ("joyadvancedupdate", Joy_AdvancedUpdate_f); - - IN_StartupMouse (); - IN_StartupJoystick (); -} diff --git a/ricochet/cl_dll/kbutton.h b/ricochet/cl_dll/kbutton.h deleted file mode 100644 index f4ccf85..0000000 --- a/ricochet/cl_dll/kbutton.h +++ /dev/null @@ -1,25 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#if !defined( KBUTTONH ) -#define KBUTTONH -#pragma once - -typedef struct kbutton_s -{ - int down[2]; // key nums holding it down - int state; // low bit is down state -} kbutton_t; - -#endif // !KBUTTONH \ No newline at end of file diff --git a/ricochet/cl_dll/menu.cpp b/ricochet/cl_dll/menu.cpp deleted file mode 100644 index 222dae3..0000000 --- a/ricochet/cl_dll/menu.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// menu.cpp -// -// generic menu handler -// -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -#include "vgui_TeamFortressViewport.h" - -#define MAX_MENU_STRING 512 -char g_szMenuString[MAX_MENU_STRING]; -char g_szPrelocalisedMenuString[MAX_MENU_STRING]; - -int KB_ConvertString( char *in, char **ppout ); - -DECLARE_MESSAGE( m_Menu, ShowMenu ); - -int CHudMenu :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( ShowMenu ); - - InitHUDData(); - - return 1; -} - -void CHudMenu :: InitHUDData( void ) -{ - m_fMenuDisplayed = 0; - m_bitsValidSlots = 0; - Reset(); -} - -void CHudMenu :: Reset( void ) -{ - g_szPrelocalisedMenuString[0] = 0; - m_fWaitingForMore = FALSE; -} - -int CHudMenu :: VidInit( void ) -{ - return 1; -} - -int CHudMenu :: Draw( float flTime ) -{ - // check for if menu is set to disappear - if ( m_flShutoffTime > 0 ) - { - if ( m_flShutoffTime <= gHUD.m_flTime ) - { // times up, shutoff - m_fMenuDisplayed = 0; - m_iFlags &= ~HUD_ACTIVE; - return 1; - } - } - - // don't draw the menu if the scoreboard is being shown - if ( gViewPort && gViewPort->IsScoreBoardVisible() ) - return 1; - - // draw the menu, along the left-hand side of the screen - - // count the number of newlines - int nlc = 0; - int i; - for ( i = 0; i < MAX_MENU_STRING && g_szMenuString[i] != '\0'; i++ ) - { - if ( g_szMenuString[i] == '\n' ) - nlc++; - } - - // center it - int y = (ScreenHeight/2) - ((nlc/2)*12) - 40; // make sure it is above the say text - int x = 20; - - i = 0; - while ( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' ) - { - gHUD.DrawHudString( x, y, 320, g_szMenuString + i, 255, 255, 255 ); - y += 12; - - while ( i < MAX_MENU_STRING && g_szMenuString[i] != '\0' && g_szMenuString[i] != '\n' ) - i++; - if ( g_szMenuString[i] == '\n' ) - i++; - } - - return 1; -} - -// selects an item from the menu -void CHudMenu :: SelectMenuItem( int menu_item ) -{ - // if menu_item is in a valid slot, send a menuselect command to the server - if ( (menu_item > 0) && (m_bitsValidSlots & (1 << (menu_item-1))) ) - { - char szbuf[32]; - sprintf( szbuf, "menuselect %d\n", menu_item ); - ClientCmd( szbuf ); - - // remove the menu - m_fMenuDisplayed = 0; - m_iFlags &= ~HUD_ACTIVE; - } -} - - -// Message handler for ShowMenu message -// takes four values: -// short: a bitfield of keys that are valid input -// char : the duration, in seconds, the menu should stay up. -1 means is stays until something is chosen. -// byte : a boolean, TRUE if there is more string yet to be received before displaying the menu, FALSE if it's the last string -// string: menu string to display -// if this message is never received, then scores will simply be the combined totals of the players. -int CHudMenu :: MsgFunc_ShowMenu( const char *pszName, int iSize, void *pbuf ) -{ - char *temp = NULL; - - BEGIN_READ( pbuf, iSize ); - - m_bitsValidSlots = READ_SHORT(); - int DisplayTime = READ_CHAR(); - int NeedMore = READ_BYTE(); - - if ( DisplayTime > 0 ) - m_flShutoffTime = DisplayTime + gHUD.m_flTime; - else - m_flShutoffTime = -1; - - if ( m_bitsValidSlots ) - { - if ( !m_fWaitingForMore ) // this is the start of a new menu - { - strncpy( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING ); - } - else - { // append to the current menu string - strncat( g_szPrelocalisedMenuString, READ_STRING(), MAX_MENU_STRING - strlen(g_szPrelocalisedMenuString) ); - } - g_szPrelocalisedMenuString[MAX_MENU_STRING-1] = 0; // ensure null termination (strncat/strncpy does not) - - if ( !NeedMore ) - { // we have the whole string, so we can localise it now - strcpy( g_szMenuString, gHUD.m_TextMessage.BufferedLocaliseTextString( g_szPrelocalisedMenuString ) ); - - // Swap in characters - if ( KB_ConvertString( g_szMenuString, &temp ) ) - { - strcpy( g_szMenuString, temp ); - free( temp ); - } - } - - m_fMenuDisplayed = 1; - m_iFlags |= HUD_ACTIVE; - } - else - { - m_fMenuDisplayed = 0; // no valid slots means that the menu should be turned off - m_iFlags &= ~HUD_ACTIVE; - } - - m_fWaitingForMore = NeedMore; - - return 1; -} diff --git a/ricochet/cl_dll/message.cpp b/ricochet/cl_dll/message.cpp deleted file mode 100644 index 64dbcd9..0000000 --- a/ricochet/cl_dll/message.cpp +++ /dev/null @@ -1,462 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// Message.cpp -// -// implementation of CHudMessage class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE( m_Message, HudText ) -DECLARE_MESSAGE( m_Message, GameTitle ) - - -int CHudMessage::Init(void) -{ - HOOK_MESSAGE( HudText ); - HOOK_MESSAGE( GameTitle ); - - gHUD.AddHudElem(this); - - Reset(); - - return 1; -}; - -int CHudMessage::VidInit( void ) -{ - m_HUD_title_half = gHUD.GetSpriteIndex( "title_half" ); - m_HUD_title_life = gHUD.GetSpriteIndex( "title_life" ); - - return 1; -}; - - -void CHudMessage::Reset( void ) -{ - memset( m_pMessages, 0, sizeof( m_pMessages[0] ) * maxHUDMessages ); - memset( m_startTime, 0, sizeof( m_startTime[0] ) * maxHUDMessages ); - - m_gameTitleTime = 0; - m_pGameTitle = NULL; -} - - -float CHudMessage::FadeBlend( float fadein, float fadeout, float hold, float localTime ) -{ - float fadeTime = fadein + hold; - float fadeBlend; - - if ( localTime < 0 ) - return 0; - - if ( localTime < fadein ) - { - fadeBlend = 1 - ((fadein - localTime) / fadein); - } - else if ( localTime > fadeTime ) - { - if ( fadeout > 0 ) - fadeBlend = 1 - ((localTime - fadeTime) / fadeout); - else - fadeBlend = 0; - } - else - fadeBlend = 1; - - return fadeBlend; -} - - -int CHudMessage::XPosition( float x, int width, int totalWidth ) -{ - int xPos; - - if ( x == -1 ) - { - xPos = (ScreenWidth - width) / 2; - } - else - { - if ( x < 0 ) - xPos = (1.0 + x) * ScreenWidth - totalWidth; // Alight right - else - xPos = x * ScreenWidth; - } - - if ( xPos + width > ScreenWidth ) - xPos = ScreenWidth - width; - else if ( xPos < 0 ) - xPos = 0; - - return xPos; -} - - -int CHudMessage::YPosition( float y, int height ) -{ - int yPos; - - if ( y == -1 ) // Centered? - yPos = (ScreenHeight - height) * 0.5; - else - { - // Alight bottom? - if ( y < 0 ) - yPos = (1.0 + y) * ScreenHeight - height; // Alight bottom - else // align top - yPos = y * ScreenHeight; - } - - if ( yPos + height > ScreenHeight ) - yPos = ScreenHeight - height; - else if ( yPos < 0 ) - yPos = 0; - - return yPos; -} - - -void CHudMessage::MessageScanNextChar( void ) -{ - int srcRed, srcGreen, srcBlue, destRed, destGreen, destBlue; - int blend; - - srcRed = m_parms.pMessage->r1; - srcGreen = m_parms.pMessage->g1; - srcBlue = m_parms.pMessage->b1; - blend = 0; // Pure source - destRed = destGreen = destBlue = 0; - - switch( m_parms.pMessage->effect ) - { - // Fade-in / Fade-out - case 0: - case 1: - blend = m_parms.fadeBlend; - break; - - case 2: - m_parms.charTime += m_parms.pMessage->fadein; - if ( m_parms.charTime > m_parms.time ) - { - srcRed = srcGreen = srcBlue = 0; - blend = 0; // pure source - } - else - { - float deltaTime = m_parms.time - m_parms.charTime; - - if ( m_parms.time > m_parms.fadeTime ) - { - blend = m_parms.fadeBlend; - } - else if ( deltaTime > m_parms.pMessage->fxtime ) - blend = 0; // pure dest - else - { - destRed = m_parms.pMessage->r2; - destGreen = m_parms.pMessage->g2; - destBlue = m_parms.pMessage->b2; - blend = 255 - (deltaTime * (1.0/m_parms.pMessage->fxtime) * 255.0 + 0.5); - } - } - break; - } - if ( blend > 255 ) - blend = 255; - else if ( blend < 0 ) - blend = 0; - - m_parms.r = ((srcRed * (255-blend)) + (destRed * blend)) >> 8; - m_parms.g = ((srcGreen * (255-blend)) + (destGreen * blend)) >> 8; - m_parms.b = ((srcBlue * (255-blend)) + (destBlue * blend)) >> 8; - - if ( m_parms.pMessage->effect == 1 && m_parms.charTime != 0 ) - { - if ( m_parms.x >= 0 && m_parms.y >= 0 && (m_parms.x + gHUD.m_scrinfo.charWidths[ m_parms.text ]) <= ScreenWidth ) - TextMessageDrawChar( m_parms.x, m_parms.y, m_parms.text, m_parms.pMessage->r2, m_parms.pMessage->g2, m_parms.pMessage->b2 ); - } -} - - -void CHudMessage::MessageScanStart( void ) -{ - switch( m_parms.pMessage->effect ) - { - // Fade-in / out with flicker - case 1: - case 0: - m_parms.fadeTime = m_parms.pMessage->fadein + m_parms.pMessage->holdtime; - - - if ( m_parms.time < m_parms.pMessage->fadein ) - { - m_parms.fadeBlend = ((m_parms.pMessage->fadein - m_parms.time) * (1.0/m_parms.pMessage->fadein) * 255); - } - else if ( m_parms.time > m_parms.fadeTime ) - { - if ( m_parms.pMessage->fadeout > 0 ) - m_parms.fadeBlend = (((m_parms.time - m_parms.fadeTime) / m_parms.pMessage->fadeout) * 255); - else - m_parms.fadeBlend = 255; // Pure dest (off) - } - else - m_parms.fadeBlend = 0; // Pure source (on) - m_parms.charTime = 0; - - if ( m_parms.pMessage->effect == 1 && (rand()%100) < 10 ) - m_parms.charTime = 1; - break; - - case 2: - m_parms.fadeTime = (m_parms.pMessage->fadein * m_parms.length) + m_parms.pMessage->holdtime; - - if ( m_parms.time > m_parms.fadeTime && m_parms.pMessage->fadeout > 0 ) - m_parms.fadeBlend = (((m_parms.time - m_parms.fadeTime) / m_parms.pMessage->fadeout) * 255); - else - m_parms.fadeBlend = 0; - break; - } -} - - -void CHudMessage::MessageDrawScan( client_textmessage_t *pMessage, float time ) -{ - int i, j, length, width; - const char *pText; - unsigned char line[80]; - - pText = pMessage->pMessage; - // Count lines - m_parms.lines = 1; - m_parms.time = time; - m_parms.pMessage = pMessage; - length = 0; - width = 0; - m_parms.totalWidth = 0; - while ( *pText ) - { - if ( *pText == '\n' ) - { - m_parms.lines++; - if ( width > m_parms.totalWidth ) - m_parms.totalWidth = width; - width = 0; - } - else - width += gHUD.m_scrinfo.charWidths[*pText]; - pText++; - length++; - } - m_parms.length = length; - m_parms.totalHeight = (m_parms.lines * gHUD.m_scrinfo.iCharHeight); - - - m_parms.y = YPosition( pMessage->y, m_parms.totalHeight ); - pText = pMessage->pMessage; - - m_parms.charTime = 0; - - MessageScanStart(); - - for ( i = 0; i < m_parms.lines; i++ ) - { - m_parms.lineLength = 0; - m_parms.width = 0; - while ( *pText && *pText != '\n' ) - { - unsigned char c = *pText; - line[m_parms.lineLength] = c; - m_parms.width += gHUD.m_scrinfo.charWidths[c]; - m_parms.lineLength++; - pText++; - } - pText++; // Skip LF - line[m_parms.lineLength] = 0; - - m_parms.x = XPosition( pMessage->x, m_parms.width, m_parms.totalWidth ); - - for ( j = 0; j < m_parms.lineLength; j++ ) - { - m_parms.text = line[j]; - int next = m_parms.x + gHUD.m_scrinfo.charWidths[ m_parms.text ]; - MessageScanNextChar(); - - if ( m_parms.x >= 0 && m_parms.y >= 0 && next <= ScreenWidth ) - TextMessageDrawChar( m_parms.x, m_parms.y, m_parms.text, m_parms.r, m_parms.g, m_parms.b ); - m_parms.x = next; - } - - m_parms.y += gHUD.m_scrinfo.iCharHeight; - } -} - - -int CHudMessage::Draw( float fTime ) -{ - int i, drawn; - client_textmessage_t *pMessage; - float endTime; - - drawn = 0; - - if ( m_gameTitleTime > 0 ) - { - float localTime = gHUD.m_flTime - m_gameTitleTime; - float brightness; - - // Maybe timer isn't set yet - if ( m_gameTitleTime > gHUD.m_flTime ) - m_gameTitleTime = gHUD.m_flTime; - - if ( localTime > (m_pGameTitle->fadein + m_pGameTitle->holdtime + m_pGameTitle->fadeout) ) - m_gameTitleTime = 0; - else - { - brightness = FadeBlend( m_pGameTitle->fadein, m_pGameTitle->fadeout, m_pGameTitle->holdtime, localTime ); - - int halfWidth = gHUD.GetSpriteRect(m_HUD_title_half).right - gHUD.GetSpriteRect(m_HUD_title_half).left; - int fullWidth = halfWidth + gHUD.GetSpriteRect(m_HUD_title_life).right - gHUD.GetSpriteRect(m_HUD_title_life).left; - int fullHeight = gHUD.GetSpriteRect(m_HUD_title_half).bottom - gHUD.GetSpriteRect(m_HUD_title_half).top; - - int x = XPosition( m_pGameTitle->x, fullWidth, fullWidth ); - int y = YPosition( m_pGameTitle->y, fullHeight ); - - - SPR_Set( gHUD.GetSprite(m_HUD_title_half), brightness * m_pGameTitle->r1, brightness * m_pGameTitle->g1, brightness * m_pGameTitle->b1 ); - SPR_DrawAdditive( 0, x, y, &gHUD.GetSpriteRect(m_HUD_title_half) ); - - SPR_Set( gHUD.GetSprite(m_HUD_title_life), brightness * m_pGameTitle->r1, brightness * m_pGameTitle->g1, brightness * m_pGameTitle->b1 ); - SPR_DrawAdditive( 0, x + halfWidth, y, &gHUD.GetSpriteRect(m_HUD_title_life) ); - - drawn = 1; - } - } - // Fixup level transitions - for ( i = 0; i < maxHUDMessages; i++ ) - { - // Assume m_parms.time contains last time - if ( m_pMessages[i] ) - { - pMessage = m_pMessages[i]; - if ( m_startTime[i] > gHUD.m_flTime ) - m_startTime[i] = gHUD.m_flTime + m_parms.time - m_startTime[i] + 0.2; // Server takes 0.2 seconds to spawn, adjust for this - } - } - - for ( i = 0; i < maxHUDMessages; i++ ) - { - if ( m_pMessages[i] ) - { - pMessage = m_pMessages[i]; - - // This is when the message is over - switch( pMessage->effect ) - { - case 0: - case 1: - endTime = m_startTime[i] + pMessage->fadein + pMessage->fadeout + pMessage->holdtime; - break; - - // Fade in is per character in scanning messages - case 2: - endTime = m_startTime[i] + (pMessage->fadein * strlen( pMessage->pMessage )) + pMessage->fadeout + pMessage->holdtime; - break; - } - - if ( fTime <= endTime ) - { - float messageTime = fTime - m_startTime[i]; - - // Draw the message - // effect 0 is fade in/fade out - // effect 1 is flickery credits - // effect 2 is write out (training room) - MessageDrawScan( pMessage, messageTime ); - - drawn++; - } - else - { - // The message is over - m_pMessages[i] = NULL; - } - } - } - - // Remember the time -- to fix up level transitions - m_parms.time = gHUD.m_flTime; - // Don't call until we get another message - if ( !drawn ) - m_iFlags &= ~HUD_ACTIVE; - - return 1; -} - - -void CHudMessage::MessageAdd( const char *pName, float time ) -{ - int i; - - for ( i = 0; i < maxHUDMessages; i++ ) - { - if ( !m_pMessages[i] ) - { - m_pMessages[i] = TextMessageGet( pName ); - m_startTime[i] = time; - return; - } - } -} - - -int CHudMessage::MsgFunc_HudText( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - char *pString = READ_STRING(); - - MessageAdd( pString, gHUD.m_flTime ); - // Remember the time -- to fix up level transitions - m_parms.time = gHUD.m_flTime; - - // Turn on drawing - if ( !(m_iFlags & HUD_ACTIVE) ) - m_iFlags |= HUD_ACTIVE; - - return 1; -} - - -int CHudMessage::MsgFunc_GameTitle( const char *pszName, int iSize, void *pbuf ) -{ - m_pGameTitle = TextMessageGet( "GAMETITLE" ); - if ( m_pGameTitle != NULL ) - { - m_gameTitleTime = gHUD.m_flTime; - - // Turn on drawing - if ( !(m_iFlags & HUD_ACTIVE) ) - m_iFlags |= HUD_ACTIVE; - } - - return 1; -} diff --git a/ricochet/cl_dll/readme.txt b/ricochet/cl_dll/readme.txt deleted file mode 100644 index 249205c..0000000 --- a/ricochet/cl_dll/readme.txt +++ /dev/null @@ -1,107 +0,0 @@ - client dll readme.txt -------------------------- - -This file details the structure of the half-life client dll, and -how it communicates with the half-life game engine. - - -Engine callback functions: - -Drawing functions: - HSPRITE SPR_Load( char *picname ); - Loads a sprite into memory, and returns a handle to it. - - int SPR_Frames( HSPRITE sprite ); - Returns the number of frames stored in the specified sprite. - - int SPR_Height( HSPRITE x, int frame ) - Returns the height, in pixels, of a sprite at the specified frame. - Returns 0 is the frame number or the sprite handle is invalid. - - int SPR_Width( HSPRITE x, int f ) - Returns the width, in pixels, of a sprite at the specified frame. - Returns 0 is the frame number or the sprite handle is invalid. - - int SPR_Set( HSPRITE sprite, int r, int g, int b ); - Prepares a sprite about to be drawn. RBG color values are applied to the sprite at this time. - - - void SPR_Draw( int frame, int x, int y ); - Precondition: SPR_Set has already been called for a sprite. - Draws the currently active sprite to the screen, at position (x,y), where (0,0) is - the top left-hand corner of the screen. - - - void SPR_DrawHoles( int frame, int x, int y ); - Precondition: SPR_Set has already been called for a sprite. - Draws the currently active sprite to the screen. Color index #255 is treated as transparent. - - void SPR_DrawAdditive( int frame, int x, int y ); - Precondition: SPR_Set has already been called for a sprite. - Draws the currently active sprite to the screen, adding it's color values to the background. - - void SPR_EnableScissor( int x, int y, int width, int height ); - Creates a clipping rectangle. No pixels will be drawn outside the specified area. Will - stay in effect until either the next frame, or SPR_DisableScissor is called. - - void SPR_DisableScissor( void ); - Disables the effect of an SPR_EnableScissor call. - - int IsHighRes( void ); - returns 1 if the res mode is 640x480 or higher; 0 otherwise. - - int ScreenWidth( void ); - returns the screen width, in pixels. - - int ScreenHeight( void ); - returns the screen height, in pixels. - -// Sound functions - void PlaySound( char *szSound, int volume ) - plays the sound 'szSound' at the specified volume. Loads the sound if it hasn't been cached. - If it can't find the sound, it displays an error message and plays no sound. - - void PlaySound( int iSound, int volume ) - Precondition: iSound has been precached. - Plays the sound, from the precache list. - - -// Communication functions - void SendClientCmd( char *szCmdString ); - sends a command to the server, just as if the client had typed the szCmdString at the console. - - char *GetPlayerName( int entity_number ); - returns a pointer to a string, that contains the name of the specified client. - Returns NULL if the entity_number is not a client. - - - DECLARE_MESSAGE(), HOOK_MESSAGE() - These two macros bind the message sending between the entity DLL and the client DLL to - the CHud object. - - HOOK_MESSAGE( message_name ) - This is used inside CHud::Init(). It calls into the engine to hook that message - from the incoming message stream. - Precondition: There must be a function of name UserMsg_message_name declared - for CHud. Eg, CHud::UserMsg_Health() must be declared if you want to - use HOOK_MESSAGE( Health ); - - DECLARE_MESSAGE( message_name ) - For each HOOK_MESSAGE you must have an equivalent DECLARE_MESSAGE. This creates - a function which passes the hooked messages into the CHud object. - - - HOOK_COMMAND(), DECLARE_COMMAND() - These two functions declare and hook console commands into the client dll. - - HOOK_COMMAND( char *command, command_name ) - Whenever the user types the 'command' at the console, the function 'command_name' - will be called. - Precondition: There must be a function of the name UserCmd_command_name declared - for CHud. Eg, CHud::UserMsg_ShowScores() must be declared if you want to - use HOOK_COMMAND( "+showscores", ShowScores ); - - DECLARE_COMMAND( command_name ) - For each HOOK_COMMAND you must have an equivelant DECLARE_COMMAND. This creates - a function which passes the hooked commands into the CHud object. - diff --git a/ricochet/cl_dll/saytext.cpp b/ricochet/cl_dll/saytext.cpp deleted file mode 100644 index 26b8118..0000000 --- a/ricochet/cl_dll/saytext.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// -// saytext.cpp -// -// implementation of CHudSayText class -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -extern float *GetClientColor( int clientIndex ); - -#define MAX_LINES 5 -#define MAX_CHARS_PER_LINE 256 /* it can be less than this, depending on char size */ - -// allow 20 pixels on either side of the text -#define MAX_LINE_WIDTH ( ScreenWidth - 40 ) -#define LINE_START 10 -static float SCROLL_SPEED = 5; - -static char g_szLineBuffer[ MAX_LINES + 1 ][ MAX_CHARS_PER_LINE ]; -static float *g_pflNameColors[ MAX_LINES + 1 ]; -static int g_iNameLengths[ MAX_LINES + 1 ]; -static float flScrollTime = 0; // the time at which the lines next scroll up - -static int Y_START = 0; -static int line_height = 0; - -DECLARE_MESSAGE( m_SayText, SayText ); - -int CHudSayText :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( SayText ); - - InitHUDData(); - - CVAR_CREATE( "hud_saytext_time", "5", 0 ); - - return 1; -} - - -void CHudSayText :: InitHUDData( void ) -{ - memset( g_szLineBuffer, 0, sizeof g_szLineBuffer ); - memset( g_pflNameColors, 0, sizeof g_pflNameColors ); - memset( g_iNameLengths, 0, sizeof g_iNameLengths ); -} - -int CHudSayText :: VidInit( void ) -{ - return 1; -} - - -int ScrollTextUp( void ) -{ - ConsolePrint( g_szLineBuffer[0] ); // move the first line into the console buffer - g_szLineBuffer[MAX_LINES][0] = 0; - memmove( g_szLineBuffer[0], g_szLineBuffer[1], sizeof(g_szLineBuffer) - sizeof(g_szLineBuffer[0]) ); // overwrite the first line - memmove( &g_pflNameColors[0], &g_pflNameColors[1], sizeof(g_pflNameColors) - sizeof(g_pflNameColors[0]) ); - memmove( &g_iNameLengths[0], &g_iNameLengths[1], sizeof(g_iNameLengths) - sizeof(g_iNameLengths[0]) ); - g_szLineBuffer[MAX_LINES-1][0] = 0; - - if ( g_szLineBuffer[0][0] == ' ' ) // also scroll up following lines - { - g_szLineBuffer[0][0] = 2; - return 1 + ScrollTextUp(); - } - - return 1; -} - -int CHudSayText :: Draw( float flTime ) -{ - int y = Y_START; - - // make sure the scrolltime is within reasonable bounds, to guard against the clock being reset - flScrollTime = V_min( flScrollTime, flTime + SCROLL_SPEED ); - - // make sure the scrolltime is within reasonable bounds, to guard against the clock being reset - flScrollTime = V_min( flScrollTime, flTime + SCROLL_SPEED ); - - if ( flScrollTime <= flTime ) - { - if ( *g_szLineBuffer[0] ) - { - flScrollTime = flTime + SCROLL_SPEED; - // push the console up - ScrollTextUp(); - } - else - { // buffer is empty, just disable drawing of this section - m_iFlags &= ~HUD_ACTIVE; - } - } - - for ( int i = 0; i < MAX_LINES; i++ ) - { - if ( *g_szLineBuffer[i] ) - { - if ( *g_szLineBuffer[i] == 2 && g_pflNameColors[i] ) - { - // it's a saytext string - static char buf[MAX_PLAYER_NAME_LENGTH+32]; - - // draw the first x characters in the player color - strncpy( buf, g_szLineBuffer[i], V_min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+32) ); - buf[ V_min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+31) ] = 0; - gEngfuncs.pfnDrawSetTextColor( g_pflNameColors[i][0], g_pflNameColors[i][1], g_pflNameColors[i][2] ); - int x = DrawConsoleString( LINE_START, y, buf ); - - // color is reset after each string draw - DrawConsoleString( x, y, g_szLineBuffer[i] + g_iNameLengths[i] ); - } - else - { - // normal draw - DrawConsoleString( LINE_START, y, g_szLineBuffer[i] ); - } - } - - y += line_height; - } - - - return 1; -} - -int CHudSayText :: MsgFunc_SayText( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int client_index = READ_BYTE(); // the client who spoke the message - SayTextPrint( READ_STRING(), iSize - 1, client_index ); - - return 1; -} - -void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIndex ) -{ - // find an empty string slot - int i; - for ( i = 0; i < MAX_LINES; i++ ) - { - if ( ! *g_szLineBuffer[i] ) - break; - } - if ( i == MAX_LINES ) - { - // force scroll buffer up - ScrollTextUp(); - i = MAX_LINES - 1; - } - - g_iNameLengths[i] = 0; - g_pflNameColors[i] = NULL; - - // if it's a say message, search for the players name in the string - if ( *pszBuf == 2 && clientIndex > 0 ) - { - GetPlayerInfo( clientIndex, &g_PlayerInfoList[clientIndex] ); - const char *pName = g_PlayerInfoList[clientIndex].name; - - if ( pName ) - { - const char *nameInString = strstr( pszBuf, pName ); - - if ( nameInString ) - { - g_iNameLengths[i] = strlen( pName ) + (nameInString - pszBuf); - g_pflNameColors[i] = GetClientColor( clientIndex ); - } - } - } - - strncpy( g_szLineBuffer[i], pszBuf, V_max(iBufSize -1, MAX_CHARS_PER_LINE-1) ); - - // make sure the text fits in one line - EnsureTextFitsInOneLineAndWrapIfHaveTo( i ); - - // Set scroll time - if ( i == 0 ) - { - SCROLL_SPEED = CVAR_GET_FLOAT( "hud_saytext_time" ); - flScrollTime = gHUD.m_flTime + SCROLL_SPEED; - } - - m_iFlags |= HUD_ACTIVE; - PlaySound( "misc/talk.wav", 1 ); - - if ( ScreenHeight >= 480 ) - Y_START = ScreenHeight - 45; - else - Y_START = ScreenHeight - 35; - Y_START -= (line_height * (MAX_LINES+1)); - -} - -void CHudSayText :: EnsureTextFitsInOneLineAndWrapIfHaveTo( int line ) -{ - int line_width = 0; - GetConsoleStringSize( g_szLineBuffer[line], &line_width, &line_height ); - - if ( (line_width + LINE_START) > MAX_LINE_WIDTH ) - { // string is too long to fit on line - // scan the string until we find what word is too long, and wrap the end of the sentence after the word - int length = LINE_START; - int tmp_len = 0; - char *last_break = NULL; - for ( char *x = g_szLineBuffer[line]; *x != 0; x++ ) - { - // check for a color change, if so skip past it - if ( x[0] == '/' && x[1] == '(' ) - { - x += 2; - // skip forward until past mode specifier - while ( *x != 0 && *x != ')' ) - x++; - - if ( *x != 0 ) - x++; - - if ( *x == 0 ) - break; - } - - char buf[2]; - buf[1] = 0; - - if ( *x == ' ' && x != g_szLineBuffer[line] ) // store each line break, except for the very first character - last_break = x; - - buf[0] = *x; // get the length of the current character - GetConsoleStringSize( buf, &tmp_len, &line_height ); - length += tmp_len; - - if ( length > MAX_LINE_WIDTH ) - { // needs to be broken up - if ( !last_break ) - last_break = x-1; - - x = last_break; - - // find an empty string slot - int j; - do - { - for ( j = 0; j < MAX_LINES; j++ ) - { - if ( ! *g_szLineBuffer[j] ) - break; - } - if ( j == MAX_LINES ) - { - // need to make more room to display text, scroll stuff up then fix the pointers - int linesmoved = ScrollTextUp(); - line -= linesmoved; - last_break = last_break - (sizeof(g_szLineBuffer[0]) * linesmoved); - } - } - while ( j == MAX_LINES ); - - // copy remaining string into next buffer, making sure it starts with a space character - if ( (char)*last_break == (char)' ' ) - { - int linelen = strlen(g_szLineBuffer[j]); - int remaininglen = strlen(last_break); - - if ( (linelen - remaininglen) <= MAX_CHARS_PER_LINE ) - strcat( g_szLineBuffer[j], last_break ); - } - else - { - if ( (strlen(g_szLineBuffer[j]) - strlen(last_break) - 2) < MAX_CHARS_PER_LINE ) - { - strcat( g_szLineBuffer[j], " " ); - strcat( g_szLineBuffer[j], last_break ); - } - } - - *last_break = 0; // cut off the last string - - EnsureTextFitsInOneLineAndWrapIfHaveTo( j ); - break; - } - } - } -} \ No newline at end of file diff --git a/ricochet/cl_dll/status_icons.cpp b/ricochet/cl_dll/status_icons.cpp deleted file mode 100644 index bf0b298..0000000 --- a/ricochet/cl_dll/status_icons.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// status_icons.cpp -// -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE( m_StatusIcons, StatusIcon ); - -int CHudStatusIcons::Init( void ) -{ - HOOK_MESSAGE( StatusIcon ); - - gHUD.AddHudElem( this ); - - Reset(); - - return 1; -} - -int CHudStatusIcons::VidInit( void ) -{ - - return 1; -} - -void CHudStatusIcons::Reset( void ) -{ - memset( m_IconList, 0, sizeof m_IconList ); - m_iFlags &= ~HUD_ACTIVE; -} - -// Draw status icons along the left-hand side of the screen -int CHudStatusIcons::Draw( float flTime ) -{ - // find starting position to draw from, along right-hand side of screen - int x = 5; - int y = ScreenHeight / 2; - - // loop through icon list, and draw any valid icons drawing up from the middle of screen - for ( int i = 0; i < MAX_ICONSPRITES; i++ ) - { - if ( m_IconList[i].spr ) - { - y -= ( m_IconList[i].rc.bottom - m_IconList[i].rc.top ) + 5; - - SPR_Set( m_IconList[i].spr, m_IconList[i].r, m_IconList[i].g, m_IconList[i].b ); - SPR_DrawAdditive( 0, x, y, &m_IconList[i].rc ); - } - } - - return 1; -} - -// Message handler for StatusIcon message -// accepts five values: -// byte : TRUE = ENABLE icon, FALSE = DISABLE icon -// string : the sprite name to display -// byte : red -// byte : green -// byte : blue -int CHudStatusIcons::MsgFunc_StatusIcon( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int ShouldEnable = READ_BYTE(); - char *pszIconName = READ_STRING(); - if ( ShouldEnable ) - { - int r = READ_BYTE(); - int g = READ_BYTE(); - int b = READ_BYTE(); - EnableIcon( pszIconName, r, g, b ); - m_iFlags |= HUD_ACTIVE; - } - else - { - DisableIcon( pszIconName ); - } - - return 1; -} - -// add the icon to the icon list, and set it's drawing color -void CHudStatusIcons::EnableIcon( char *pszIconName, unsigned char red, unsigned char green, unsigned char blue ) -{ - // check to see if the sprite is in the current list - int i; - for ( i = 0; i < MAX_ICONSPRITES; i++ ) - { - if ( !stricmp( m_IconList[i].szSpriteName, pszIconName ) ) - break; - } - - if ( i == MAX_ICONSPRITES ) - { - // icon not in list, so find an empty slot to add to - for ( i = 0; i < MAX_ICONSPRITES; i++ ) - { - if ( !m_IconList[i].spr ) - break; - } - } - - // if we've run out of space in the list, overwrite the first icon - if ( i == MAX_ICONSPRITES ) - { - i = 0; - } - - // Load the sprite and add it to the list - // the sprite must be listed in hud.txt - int spr_index = gHUD.GetSpriteIndex( pszIconName ); - m_IconList[i].spr = gHUD.GetSprite( spr_index ); - m_IconList[i].rc = gHUD.GetSpriteRect( spr_index ); - m_IconList[i].r = red; - m_IconList[i].g = green; - m_IconList[i].b = blue; - strcpy( m_IconList[i].szSpriteName, pszIconName ); -} - -void CHudStatusIcons::DisableIcon( char *pszIconName ) -{ - // find the sprite is in the current list - for ( int i = 0; i < MAX_ICONSPRITES; i++ ) - { - if ( !stricmp( m_IconList[i].szSpriteName, pszIconName ) ) - { - // clear the item from the list - memset( &m_IconList[i], 0, sizeof(icon_sprite_t) ); - return; - } - } -} diff --git a/ricochet/cl_dll/statusbar.cpp b/ricochet/cl_dll/statusbar.cpp deleted file mode 100644 index 019b2f7..0000000 --- a/ricochet/cl_dll/statusbar.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ -// -// statusbar.cpp -// -// generic text status bar, set by game dll -// runs across bottom of screen -// - -#include "hud.h" -#include "cl_util.h" -#include "parsemsg.h" - -#include -#include - -DECLARE_MESSAGE( m_StatusBar, StatusText ); -DECLARE_MESSAGE( m_StatusBar, StatusValue ); - -#define STATUSBAR_ID_LINE 1 - -int CHudStatusBar :: Init( void ) -{ - gHUD.AddHudElem( this ); - - HOOK_MESSAGE( StatusText ); - HOOK_MESSAGE( StatusValue ); - - Reset(); - - CVAR_CREATE( "hud_centerid", "0", FCVAR_ARCHIVE ); - - return 1; -} - -int CHudStatusBar :: VidInit( void ) -{ - // Load sprites here - - return 1; -} - -void CHudStatusBar :: Reset( void ) -{ - m_iFlags &= ~HUD_ACTIVE; // start out inactive - for ( int i = 0; i < MAX_STATUSBAR_LINES; i++ ) - m_szStatusText[i][0] = 0; - memset( m_iStatusValues, 0, sizeof m_iStatusValues ); - - m_iStatusValues[0] = 1; // 0 is the special index, which always returns true -} - -void CHudStatusBar :: ParseStatusString( int line_num ) -{ - // localise string first - char szBuffer[MAX_STATUSTEXT_LENGTH]; - memset( szBuffer, 0, sizeof szBuffer ); - gHUD.m_TextMessage.LocaliseTextString( m_szStatusText[line_num], szBuffer, MAX_STATUSTEXT_LENGTH ); - - // parse m_szStatusText & m_iStatusValues into m_szStatusBar - memset( m_szStatusBar[line_num], 0, MAX_STATUSTEXT_LENGTH ); - char *src = szBuffer; - char *dst = m_szStatusBar[line_num]; - - char *src_start = src, *dst_start = dst; - - while ( *src != 0 ) - { - while ( *src == '\n' ) - src++; // skip over any newlines - - if ( ((src - src_start) >= MAX_STATUSTEXT_LENGTH) || ((dst - dst_start) >= MAX_STATUSTEXT_LENGTH) ) - break; - - int index = atoi( src ); - // should we draw this line? - if ( (index >= 0 && index < MAX_STATUSBAR_VALUES) && (m_iStatusValues[index] != 0) ) - { // parse this line and append result to the status bar - while ( *src >= '0' && *src <= '9' ) - src++; - - if ( *src == '\n' || *src == 0 ) - continue; // no more left in this text line - - // copy the text, char by char, until we hit a % or a \n - while ( *src != '\n' && *src != 0 ) - { - if ( *src != '%' ) - { // just copy the character - *dst = *src; - dst++, src++; - } - else - { - // get the descriptor - char valtype = *(++src); // move over % - - // if it's a %, draw a % sign - if ( valtype == '%' ) - { - *dst = valtype; - dst++, src++; - continue; - } - - // move over descriptor, then get and move over the index - index = atoi( ++src ); - while ( *src >= '0' && *src <= '9' ) - src++; - - if ( index >= 0 && index < MAX_STATUSBAR_VALUES ) - { - int indexval = m_iStatusValues[index]; - - // get the string to substitute in place of the %XX - char szRepString[MAX_PLAYER_NAME_LENGTH]; - switch ( valtype ) - { - case 'p': // player name - GetPlayerInfo( indexval, &g_PlayerInfoList[indexval] ); - if ( g_PlayerInfoList[indexval].name != NULL ) - { - strncpy( szRepString, g_PlayerInfoList[indexval].name, MAX_PLAYER_NAME_LENGTH ); - } - else - { - strcpy( szRepString, "******" ); - } - break; - case 'i': // number - sprintf( szRepString, "%d", indexval ); - break; - default: - szRepString[0] = 0; - } - - for ( char *cp = szRepString; *cp != 0 && ((dst - dst_start) < MAX_STATUSTEXT_LENGTH); cp++, dst++ ) - *dst = *cp; - } - } - } - } - else - { - // skip to next line of text - while ( *src != 0 && *src != '\n' ) - src++; - } - } -} - -int CHudStatusBar :: Draw( float fTime ) -{ - if ( m_bReparseString ) - { - for ( int i = 0; i < MAX_STATUSBAR_LINES; i++ ) - ParseStatusString( i ); - m_bReparseString = FALSE; - } - - // Draw the status bar lines - for ( int i = 0; i < MAX_STATUSBAR_LINES; i++ ) - { - int TextHeight, TextWidth; - GetConsoleStringSize( m_szStatusBar[i], &TextWidth, &TextHeight ); - - int Y_START; - if ( ScreenHeight >= 480 ) - Y_START = ScreenHeight - 45; - else - Y_START = ScreenHeight - 35; - - int x = 5; - int y = Y_START - ( TextHeight * i ); // draw along bottom of screen - - // let user set status ID bar centering - if ( (i == STATUSBAR_ID_LINE) && CVAR_GET_FLOAT("hud_centerid") ) - { - x = V_max( 0, V_max(2, (ScreenWidth - TextWidth)) / 2 ); - y = (ScreenHeight / 2) + (TextHeight*CVAR_GET_FLOAT("hud_centerid")); - } - - DrawConsoleString( x, y, m_szStatusBar[i] ); - } - - return 1; -} - -// Message handler for StatusText message -// accepts two values: -// byte: line number of status bar text -// string: status bar text -// this string describes how the status bar should be drawn -// a semi-regular expression: -// ( slotnum ([a..z] [%pX] [%iX])*)* -// where slotnum is an index into the Value table (see below) -// if slotnum is 0, the string is always drawn -// if StatusValue[slotnum] != 0, the following string is drawn, upto the next newline - otherwise the text is skipped upto next newline -// %pX, where X is an integer, will substitute a player name here, getting the player index from StatusValue[X] -// %iX, where X is an integer, will substitute a number here, getting the number from StatusValue[X] -int CHudStatusBar :: MsgFunc_StatusText( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int line = READ_BYTE(); - - if ( line < 0 || line >= MAX_STATUSBAR_LINES ) - return 1; - - strncpy( m_szStatusText[line], READ_STRING(), MAX_STATUSTEXT_LENGTH ); - m_szStatusText[line][MAX_STATUSTEXT_LENGTH-1] = 0; // ensure it's null terminated ( strncpy() won't null terminate if read string too long) - - if ( m_szStatusText[0] == 0 ) - m_iFlags &= ~HUD_ACTIVE; - else - m_iFlags |= HUD_ACTIVE; // we have status text, so turn on the status bar - - m_bReparseString = TRUE; - - return 1; -} - -// Message handler for StatusText message -// accepts two values: -// byte: index into the status value array -// short: value to store -int CHudStatusBar :: MsgFunc_StatusValue( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int index = READ_BYTE(); - if ( index < 1 || index >= MAX_STATUSBAR_VALUES ) - return 1; // index out of range - - m_iStatusValues[index] = READ_SHORT(); - - m_bReparseString = TRUE; - - return 1; -} \ No newline at end of file diff --git a/ricochet/cl_dll/studio_util.cpp b/ricochet/cl_dll/studio_util.cpp deleted file mode 100644 index 9d8dd2c..0000000 --- a/ricochet/cl_dll/studio_util.cpp +++ /dev/null @@ -1,131 +0,0 @@ -#include -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "com_model.h" -#include "studio_util.h" - -// angles index are not the same as ROLL, PITCH, YAW - -/* -==================== -AngleQuaternion - -==================== -*/ -void AngleQuaternion( float *angles, vec4_t quaternion ) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - // FIXME: rescale the inputs to 1/2 angle - angle = angles[2] * 0.5; - sy = sin(angle); - cy = cos(angle); - angle = angles[1] * 0.5; - sp = sin(angle); - cp = cos(angle); - angle = angles[0] * 0.5; - sr = sin(angle); - cr = cos(angle); - - quaternion[0] = sr*cp*cy-cr*sp*sy; // X - quaternion[1] = cr*sp*cy+sr*cp*sy; // Y - quaternion[2] = cr*cp*sy-sr*sp*cy; // Z - quaternion[3] = cr*cp*cy+sr*sp*sy; // W -} - -/* -==================== -QuaternionSlerp - -==================== -*/ -void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt ) -{ - int i; - float omega, cosom, sinom, sclp, sclq; - - // decide if one of the quaternions is backwards - float a = 0; - float b = 0; - - for (i = 0; i < 4; i++) - { - a += (p[i]-q[i])*(p[i]-q[i]); - b += (p[i]+q[i])*(p[i]+q[i]); - } - if (a > b) - { - for (i = 0; i < 4; i++) - { - q[i] = -q[i]; - } - } - - cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3]; - - if ((1.0 + cosom) > 0.000001) - { - if ((1.0 - cosom) > 0.000001) - { - omega = acos( cosom ); - sinom = sin( omega ); - sclp = sin( (1.0 - t)*omega) / sinom; - sclq = sin( t*omega ) / sinom; - } - else - { - sclp = 1.0 - t; - sclq = t; - } - for (i = 0; i < 4; i++) { - qt[i] = sclp * p[i] + sclq * q[i]; - } - } - else - { - qt[0] = -q[1]; - qt[1] = q[0]; - qt[2] = -q[3]; - qt[3] = q[2]; - sclp = sin( (1.0 - t) * (0.5 * M_PI)); - sclq = sin( t * (0.5 * M_PI)); - for (i = 0; i < 3; i++) - { - qt[i] = sclp * p[i] + sclq * qt[i]; - } - } -} - -/* -==================== -QuaternionMatrix - -==================== -*/ -void QuaternionMatrix( vec4_t quaternion, float (*matrix)[4] ) -{ - matrix[0][0] = 1.0 - 2.0 * quaternion[1] * quaternion[1] - 2.0 * quaternion[2] * quaternion[2]; - matrix[1][0] = 2.0 * quaternion[0] * quaternion[1] + 2.0 * quaternion[3] * quaternion[2]; - matrix[2][0] = 2.0 * quaternion[0] * quaternion[2] - 2.0 * quaternion[3] * quaternion[1]; - - matrix[0][1] = 2.0 * quaternion[0] * quaternion[1] - 2.0 * quaternion[3] * quaternion[2]; - matrix[1][1] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[2] * quaternion[2]; - matrix[2][1] = 2.0 * quaternion[1] * quaternion[2] + 2.0 * quaternion[3] * quaternion[0]; - - matrix[0][2] = 2.0 * quaternion[0] * quaternion[2] + 2.0 * quaternion[3] * quaternion[1]; - matrix[1][2] = 2.0 * quaternion[1] * quaternion[2] - 2.0 * quaternion[3] * quaternion[0]; - matrix[2][2] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[1] * quaternion[1]; -} - -/* -==================== -MatrixCopy - -==================== -*/ -void MatrixCopy( float in[3][4], float out[3][4] ) -{ - memcpy( out, in, sizeof( float ) * 3 * 4 ); -} \ No newline at end of file diff --git a/ricochet/cl_dll/studio_util.h b/ricochet/cl_dll/studio_util.h deleted file mode 100644 index 49e506f..0000000 --- a/ricochet/cl_dll/studio_util.h +++ /dev/null @@ -1,33 +0,0 @@ -#if !defined( STUDIO_UTIL_H ) -#define STUDIO_UTIL_H -#if defined( WIN32 ) -#pragma once -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -#ifndef PITCH -// MOVEMENT INFO -// up / down -#define PITCH 0 -// left / right -#define YAW 1 -// fall over -#define ROLL 2 -#endif - -#define FDotProduct( a, b ) (fabs((a[0])*(b[0])) + fabs((a[1])*(b[1])) + fabs((a[2])*(b[2]))) - -void AngleMatrix (const float *angles, float (*matrix)[4] ); -int VectorCompare (const float *v1, const float *v2); -void CrossProduct (const float *v1, const float *v2, float *cross); -void VectorTransform (const float *in1, float in2[3][4], float *out); -void ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]); -void MatrixCopy( float in[3][4], float out[3][4] ); -void QuaternionMatrix( vec4_t quaternion, float (*matrix)[4] ); -void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt ); -void AngleQuaternion( float *angles, vec4_t quaternion ); - -#endif // STUDIO_UTIL_H \ No newline at end of file diff --git a/ricochet/cl_dll/text_message.cpp b/ricochet/cl_dll/text_message.cpp deleted file mode 100644 index e2283d2..0000000 --- a/ricochet/cl_dll/text_message.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// text_message.cpp -// -// implementation of CHudTextMessage class -// -// this class routes messages through titles.txt for localisation -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE( m_TextMessage, TextMsg ); - -int CHudTextMessage::Init(void) -{ - HOOK_MESSAGE( TextMsg ); - - gHUD.AddHudElem( this ); - - Reset(); - - return 1; -}; - -// Searches through the string for any msg names (indicated by a '#') -// any found are looked up in titles.txt and the new message substituted -// the new value is pushed into dst_buffer -char *CHudTextMessage::LocaliseTextString( const char *msg, char *dst_buffer, int buffer_size ) -{ - char *dst = dst_buffer; - for ( char *src = (char*)msg; *src != 0 && buffer_size > 0; buffer_size-- ) - { - if ( *src == '#' ) - { - // cut msg name out of string - static char word_buf[255]; - char *wdst = word_buf, *word_start = src; - for ( ++src ; (*src >= 'A' && *src <= 'z') || (*src >= '0' && *src <= '9'); wdst++, src++ ) - { - *wdst = *src; - } - *wdst = 0; - - // lookup msg name in titles.txt - client_textmessage_t *clmsg = TextMessageGet( word_buf ); - if ( !clmsg || !(clmsg->pMessage) ) - { - src = word_start; - *dst = *src; - dst++, src++; - continue; - } - - // copy string into message over the msg name - for ( char *wsrc = (char*)clmsg->pMessage; *wsrc != 0; wsrc++, dst++ ) - { - *dst = *wsrc; - } - *dst = 0; - } - else - { - *dst = *src; - dst++, src++; - *dst = 0; - } - } - - dst_buffer[buffer_size-1] = 0; // ensure null termination - return dst_buffer; -} - -// As above, but with a local static buffer -char *CHudTextMessage::BufferedLocaliseTextString( const char *msg ) -{ - char dst_buffer[1024]; - return LocaliseTextString( msg, dst_buffer, 1024 ); -} - -// Simplified version of LocaliseTextString; assumes string is only one word -char *CHudTextMessage::LookupString( const char *msg, int *msg_dest ) -{ - if ( !msg ) - return ""; - - // '#' character indicates this is a reference to a string in titles.txt, and not the string itself - if ( msg[0] == '#' ) - { - // this is a message name, so look up the real message - client_textmessage_t *clmsg = TextMessageGet( msg+1 ); - - if ( !clmsg || !(clmsg->pMessage) ) - return (char*)msg; // lookup failed, so return the original string - - if ( msg_dest ) - { - // check to see if titles.txt info overrides msg destination - // if clmsg->effect is less than 0, then clmsg->effect holds -1 * message_destination - if ( clmsg->effect < 0 ) // - *msg_dest = -clmsg->effect; - } - - return (char*)clmsg->pMessage; - } - else - { // nothing special about this message, so just return the same string - return (char*)msg; - } -} - -void StripEndNewlineFromString( char *str ) -{ - int s = strlen( str ) - 1; - if ( str[s] == '\n' || str[s] == '\r' ) - str[s] = 0; -} - -// converts all '\r' characters to '\n', so that the engine can deal with the properly -// returns a pointer to str -char* ConvertCRtoNL( char *str ) -{ - for ( char *ch = str; *ch != 0; ch++ ) - if ( *ch == '\r' ) - *ch = '\n'; - return str; -} - -// Message handler for text messages -// displays a string, looking them up from the titles.txt file, which can be localised -// parameters: -// byte: message direction ( HUD_PRINTCONSOLE, HUD_PRINTNOTIFY, HUD_PRINTCENTER, HUD_PRINTTALK ) -// string: message -// optional parameters: -// string: message parameter 1 -// string: message parameter 2 -// string: message parameter 3 -// string: message parameter 4 -// any string that starts with the character '#' is a message name, and is used to look up the real message in titles.txt -// the next (optional) one to four strings are parameters for that string (which can also be message names if they begin with '#') -int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int msg_dest = READ_BYTE(); - -#define MSG_BUF_SIZE 128 - static char szBuf[6][MSG_BUF_SIZE]; - char *msg_text = LookupString( READ_STRING(), &msg_dest ); - msg_text = safe_strcpy( szBuf[0], msg_text, MSG_BUF_SIZE ); - - // keep reading strings and using C format strings for subsituting the strings into the localised text string - char *sstr1 = LookupString( READ_STRING() ); - sstr1 = safe_strcpy( szBuf[1], sstr1 , MSG_BUF_SIZE ); - StripEndNewlineFromString( sstr1 ); // these strings are meant for subsitution into the main strings, so cull the automatic end newlines - char *sstr2 = LookupString( READ_STRING() ); - sstr2 = safe_strcpy( szBuf[2], sstr2 , MSG_BUF_SIZE ); - StripEndNewlineFromString( sstr2 ); - char *sstr3 = LookupString( READ_STRING() ); - sstr3 = safe_strcpy( szBuf[3], sstr3 , MSG_BUF_SIZE ); - StripEndNewlineFromString( sstr3 ); - char *sstr4 = LookupString( READ_STRING() ); - sstr4 = safe_strcpy( szBuf[4], sstr4 , MSG_BUF_SIZE ); - StripEndNewlineFromString( sstr4 ); - char *psz = szBuf[5]; - - switch ( msg_dest ) - { - case HUD_PRINTCENTER: - safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); - CenterPrint( ConvertCRtoNL( psz ) ); - break; - - case HUD_PRINTNOTIFY: - psz[0] = 1; // mark this message to go into the notify buffer - safe_sprintf( psz+1, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); - ConsolePrint( ConvertCRtoNL( psz ) ); - break; - - case HUD_PRINTTALK: - safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); - gHUD.m_SayText.SayTextPrint( ConvertCRtoNL( psz ), 128 ); - break; - - case HUD_PRINTCONSOLE: - safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); - ConsolePrint( ConvertCRtoNL( psz ) ); - break; - } - - return 1; -} diff --git a/ricochet/cl_dll/tf_defs.h b/ricochet/cl_dll/tf_defs.h deleted file mode 100644 index 5d7c227..0000000 --- a/ricochet/cl_dll/tf_defs.h +++ /dev/null @@ -1,1357 +0,0 @@ -/*** -* -* Copyright (c) 1998, 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. -* -****/ - -#ifndef __TF_DEFS_H -#define __TF_DEFS_H - -//=========================================================================== -// OLD OPTIONS.QC -//=========================================================================== -#define DEFAULT_AUTOZOOM FALSE -#define WEINER_SNIPER // autoaiming for sniper rifle -#define FLAME_MAXWORLDNUM 20 // maximum number of flames in the world. DO NOT PUT BELOW 20. - -//#define MAX_WORLD_PIPEBOMBS 15 // This is divided between teams - this is the most you should have on a net server -#define MAX_PLAYER_PIPEBOMBS 8 // maximum number of pipebombs any 1 player can have active -#define MAX_PLAYER_AMMOBOXES 3 // maximum number of ammoboxes any 1 player can have active - -//#define MAX_WORLD_FLARES 9 // This is the total number of flares allowed in the world at one time -//#define MAX_WORLD_AMMOBOXES 20 // This is divided between teams - this is the most you should have on a net server -#define GR_TYPE_MIRV_NO 4 // Number of Mirvs a Mirv Grenade breaks into -#define GR_TYPE_NAPALM_NO 8 // Number of flames napalm grenade breaks into (unused if net server) -#define MEDIKIT_IS_BIOWEAPON // Medikit acts as a bioweapon against enemies - -#define TEAM_HELP_RATE 60 // used only if teamplay bit 64 (help team with lower score) is set. - // 60 is a mild setting, and won't make too much difference - // increasing it _decreases_ the amount of help the losing team gets - // Minimum setting is 1, which would really help the losing team - -#define DISPLAY_CLASS_HELP TRUE // Change this to #OFF if you don't want the class help to - // appear whenever a player connects -#define NEVER_TEAMFRAGS FALSE // teamfrags options always off -#define ALWAYS_TEAMFRAGS FALSE // teamfrags options always on -#define CHECK_SPEEDS TRUE // makes sure players aren't moving too fast -#define SNIPER_RIFLE_RELOAD_TIME 1.5 // seconds - -#define MAPBRIEFING_MAXTEXTLENGTH 512 -#define PLAYER_PUSH_VELOCITY 50 // Players push teammates if they're moving under this speed - -// Debug Options -//#define MAP_DEBUG // Debug for Map code. I suggest running in a hi-res - // mode and/or piping the output from the server to a file. -#ifdef MAP_DEBUG - #define MDEBUG(x) x -#else - #define MDEBUG(x) -#endif -//#define VERBOSE // Verbose Debugging on/off - -//=========================================================================== -// OLD QUAKE Defs -//=========================================================================== -// items -#define IT_AXE 4096 -#define IT_SHOTGUN 1 -#define IT_SUPER_SHOTGUN 2 -#define IT_NAILGUN 4 -#define IT_SUPER_NAILGUN 8 -#define IT_GRENADE_LAUNCHER 16 -#define IT_ROCKET_LAUNCHER 32 -#define IT_LIGHTNING 64 -#define IT_EXTRA_WEAPON 128 - -#define IT_SHELLS 256 -#define IT_NAILS 512 -#define IT_ROCKETS 1024 -#define IT_CELLS 2048 - -#define IT_ARMOR1 8192 -#define IT_ARMOR2 16384 -#define IT_ARMOR3 32768 -#define IT_SUPERHEALTH 65536 - -#define IT_KEY1 131072 -#define IT_KEY2 262144 - -#define IT_INVISIBILITY 524288 -#define IT_INVULNERABILITY 1048576 -#define IT_SUIT 2097152 -#define IT_QUAD 4194304 -#define IT_HOOK 8388608 - -#define IT_KEY3 16777216 // Stomp invisibility -#define IT_KEY4 33554432 // Stomp invulnerability - -//=========================================================================== -// TEAMFORTRESS Defs -//=========================================================================== -// TeamFortress State Flags -#define TFSTATE_GRENPRIMED 1 // Whether the player has a primed grenade -#define TFSTATE_RELOADING 2 // Whether the player is reloading -#define TFSTATE_ALTKILL 4 // #TRUE if killed with a weapon not in self.weapon: NOT USED ANYMORE -#define TFSTATE_RANDOMPC 8 // Whether Playerclass is random, new one each respawn -#define TFSTATE_INFECTED 16 // set when player is infected by the bioweapon -#define TFSTATE_INVINCIBLE 32 // Player has permanent Invincibility (Usually by GoalItem) -#define TFSTATE_INVISIBLE 64 // Player has permanent Invisibility (Usually by GoalItem) -#define TFSTATE_QUAD 128 // Player has permanent Quad Damage (Usually by GoalItem) -#define TFSTATE_RADSUIT 256 // Player has permanent Radsuit (Usually by GoalItem) -#define TFSTATE_BURNING 512 // Is on fire -#define TFSTATE_GRENTHROWING 1024 // is throwing a grenade -#define TFSTATE_AIMING 2048 // is using the laser sight -#define TFSTATE_ZOOMOFF 4096 // doesn't want the FOV changed when zooming -#define TFSTATE_RESPAWN_READY 8192 // is waiting for respawn, and has pressed fire -#define TFSTATE_HALLUCINATING 16384 // set when player is hallucinating -#define TFSTATE_TRANQUILISED 32768 // set when player is tranquilised -#define TFSTATE_CANT_MOVE 65536 // set when player is setting a detpack -#define TFSTATE_RESET_FLAMETIME 131072 // set when the player has to have his flames increased in health - -// Defines used by TF_T_Damage (see combat.qc) -#define TF_TD_IGNOREARMOUR 1 // Bypasses the armour of the target -#define TF_TD_NOTTEAM 2 // Doesn't damage a team member (indicates direct fire weapon) -#define TF_TD_NOTSELF 4 // Doesn't damage self - -#define TF_TD_OTHER 0 // Ignore armorclass -#define TF_TD_SHOT 1 // Bullet damage -#define TF_TD_NAIL 2 // Nail damage -#define TF_TD_EXPLOSION 4 // Explosion damage -#define TF_TD_ELECTRICITY 8 // Electric damage -#define TF_TD_FIRE 16 // Fire damage -#define TF_TD_NOSOUND 256 // Special damage. Makes no sound/painframe, etc - -/*==================================================*/ -/* Toggleable Game Settings */ -/*==================================================*/ -#define TF_RESPAWNDELAY1 5 // seconds of waiting before player can respawn -#define TF_RESPAWNDELAY2 10 // seconds of waiting before player can respawn -#define TF_RESPAWNDELAY3 20 // seconds of waiting before player can respawn - -#define TEAMPLAY_NORMAL 1 -#define TEAMPLAY_HALFDIRECT 2 -#define TEAMPLAY_NODIRECT 4 -#define TEAMPLAY_HALFEXPLOSIVE 8 -#define TEAMPLAY_NOEXPLOSIVE 16 -#define TEAMPLAY_LESSPLAYERSHELP 32 -#define TEAMPLAY_LESSSCOREHELP 64 -#define TEAMPLAY_HALFDIRECTARMOR 128 -#define TEAMPLAY_NODIRECTARMOR 256 -#define TEAMPLAY_HALFEXPARMOR 512 -#define TEAMPLAY_NOEXPARMOR 1024 -#define TEAMPLAY_HALFDIRMIRROR 2048 -#define TEAMPLAY_FULLDIRMIRROR 4096 -#define TEAMPLAY_HALFEXPMIRROR 8192 -#define TEAMPLAY_FULLEXPMIRROR 16384 - -#define TEAMPLAY_TEAMDAMAGE (TEAMPLAY_NODIRECT | TEAMPLAY_HALFDIRECT | TEAMPLAY_HALFEXPLOSIVE | TEAMPLAY_NOEXPLOSIVE) -// FortressMap stuff -#define TEAM1_CIVILIANS 1 -#define TEAM2_CIVILIANS 2 -#define TEAM3_CIVILIANS 4 -#define TEAM4_CIVILIANS 8 - -// Defines for the playerclass -#define PC_UNDEFINED 0 - -#define PC_SCOUT 1 -#define PC_SNIPER 2 -#define PC_SOLDIER 3 -#define PC_DEMOMAN 4 -#define PC_MEDIC 5 -#define PC_HVYWEAP 6 -#define PC_PYRO 7 -#define PC_SPY 8 -#define PC_ENGINEER 9 - -// Insert new class definitions here - -// PC_RANDOM _MUST_ be the third last class -#define PC_RANDOM 10 // Random playerclass -#define PC_CIVILIAN 11 // Civilians are a special class. They cannot - // be chosen by players, only enforced by maps -#define PC_LASTCLASS 12 // Use this as the high-boundary for any loops - // through the playerclass. - -// These are just for the scanner -#define SCAN_SENTRY 13 -#define SCAN_GOALITEM 14 - -// Values returned by CheckArea -enum -{ - CAREA_CLEAR, - CAREA_BLOCKED, - CAREA_NOBUILD -}; - -/*==================================================*/ -/* Impulse Defines */ -/*==================================================*/ -// Alias check to see whether they already have the aliases -#define TF_ALIAS_CHECK 13 - -// CTF Support Impulses -#define HOOK_IMP1 22 -#define FLAG_INFO 23 -#define HOOK_IMP2 39 - -// Axe -#define AXE_IMP 40 - -// Camera Impulse -#define TF_CAM_TARGET 50 -#define TF_CAM_ZOOM 51 -#define TF_CAM_ANGLE 52 -#define TF_CAM_VEC 53 -#define TF_CAM_PROJECTILE 54 -#define TF_CAM_PROJECTILE_Z 55 -#define TF_CAM_REVANGLE 56 -#define TF_CAM_OFFSET 57 -#define TF_CAM_DROP 58 -#define TF_CAM_FADETOBLACK 59 -#define TF_CAM_FADEFROMBLACK 60 -#define TF_CAM_FADETOWHITE 61 -#define TF_CAM_FADEFROMWHITE 62 - -// Last Weapon impulse -#define TF_LAST_WEAPON 69 - -// Status Bar Resolution Settings. Same as CTF to maintain ease of use. -#define TF_STATUSBAR_RES_START 71 -#define TF_STATUSBAR_RES_END 81 - -// Clan Messages -#define TF_MESSAGE_1 82 -#define TF_MESSAGE_2 83 -#define TF_MESSAGE_3 84 -#define TF_MESSAGE_4 85 -#define TF_MESSAGE_5 86 - -#define TF_CHANGE_CLASS 99 // Bring up the Class Change menu - -// Added to PC_??? to get impulse to use if this clashes with your -// own impulses, just change this value, not the PC_?? -#define TF_CHANGEPC 100 -// The next few impulses are all the class selections -//PC_SCOUT 101 -//PC_SNIPER 102 -//PC_SOLDIER 103 -//PC_DEMOMAN 104 -//PC_MEDIC 105 -//PC_HVYWEAP 106 -//PC_PYRO 107 -//PC_RANDOM 108 -//PC_CIVILIAN 109 // Cannot be used -//PC_SPY 110 -//PC_ENGINEER 111 - -// Help impulses -#define TF_DISPLAYLOCATION 118 -#define TF_STATUS_QUERY 119 - -#define TF_HELP_MAP 131 - -// Information impulses -#define TF_INVENTORY 135 -#define TF_SHOWTF 136 -#define TF_SHOWLEGALCLASSES 137 - -// Team Impulses -#define TF_TEAM_1 140 // Join Team 1 -#define TF_TEAM_2 141 // Join Team 2 -#define TF_TEAM_3 142 // Join Team 3 -#define TF_TEAM_4 143 // Join Team 4 -#define TF_TEAM_CLASSES 144 // Impulse to display team classes -#define TF_TEAM_SCORES 145 // Impulse to display team scores -#define TF_TEAM_LIST 146 // Impulse to display the players in each team. - -// Grenade Impulses -#define TF_GRENADE_1 150 // Prime grenade type 1 -#define TF_GRENADE_2 151 // Prime grenade type 2 -#define TF_GRENADE_T 152 // Throw primed grenade - -// Impulses for new items -//#define TF_SCAN 159 // Scanner Pre-Impulse -#define TF_AUTO_SCAN 159 // Scanner On/Off -#define TF_SCAN_ENEMY 160 // Impulses to toggle scanning of enemies -#define TF_SCAN_FRIENDLY 161 // Impulses to toggle scanning of friendlies -//#define TF_SCAN_10 162 // Scan using 10 enery (1 cell) -#define TF_SCAN_SOUND 162 // Scanner sounds on/off -#define TF_SCAN_30 163 // Scan using 30 energy (2 cells) -#define TF_SCAN_100 164 // Scan using 100 energy (5 cells) -#define TF_DETPACK_5 165 // Detpack set to 5 seconds -#define TF_DETPACK_20 166 // Detpack set to 20 seconds -#define TF_DETPACK_50 167 // Detpack set to 50 seconds -#define TF_DETPACK 168 // Detpack Pre-Impulse -#define TF_DETPACK_STOP 169 // Impulse to stop setting detpack -#define TF_PB_DETONATE 170 // Detonate Pipebombs - -// Special skill -#define TF_SPECIAL_SKILL 171 - -// Ammo Drop impulse -#define TF_DROP_AMMO 172 - -// Reload impulse -#define TF_RELOAD 173 - -// auto-zoom toggle -#define TF_AUTOZOOM 174 - -// drop/pass commands -#define TF_DROPKEY 175 - -// Select Medikit -#define TF_MEDIKIT 176 - -// Spy Impulses -#define TF_SPY_SPY 177 // On net, go invisible, on LAN, change skin/color -#define TF_SPY_DIE 178 // Feign Death - -// Engineer Impulses -#define TF_ENGINEER_BUILD 179 -#define TF_ENGINEER_SANDBAG 180 - -// Medic -#define TF_MEDIC_HELPME 181 - -// Status bar -#define TF_STATUSBAR_ON 182 -#define TF_STATUSBAR_OFF 183 - -// Discard impulse -#define TF_DISCARD 184 - -// ID Player impulse -#define TF_ID 185 - -// Clan Battle impulses -#define TF_SHOWIDS 186 - -// More Engineer Impulses -#define TF_ENGINEER_DETDISP 187 -#define TF_ENGINEER_DETSENT 188 - -// Admin Commands -#define TF_ADMIN_DEAL_CYCLE 189 -#define TF_ADMIN_KICK 190 -#define TF_ADMIN_BAN 191 -#define TF_ADMIN_COUNTPLAYERS 192 -#define TF_ADMIN_CEASEFIRE 193 - -// Drop Goal Items -#define TF_DROPGOALITEMS 194 - -// More Admin Commands -#define TF_ADMIN_NEXT 195 - -// More Engineer Impulses -#define TF_ENGINEER_DETEXIT 196 -#define TF_ENGINEER_DETENTRANCE 197 - -// Yet MORE Admin Commands -#define TF_ADMIN_LISTIPS 198 - -// Silent Spy Feign -#define TF_SPY_SILENTDIE 199 - - -/*==================================================*/ -/* Colors */ -/*==================================================*/ -#define TEAM1_COLOR 150 -#define TEAM2_COLOR 250 -#define TEAM3_COLOR 45 -#define TEAM4_COLOR 100 - -/*==================================================*/ -/* Defines for the ENGINEER's Building ability */ -/*==================================================*/ -// Ammo costs -#define AMMO_COST_SHELLS 2 // Metal needed to make 1 shell -#define AMMO_COST_NAILS 1 -#define AMMO_COST_ROCKETS 2 -#define AMMO_COST_CELLS 2 - -// Building types -#define BUILD_DISPENSER 1 -#define BUILD_SENTRYGUN 2 -#define BUILD_MORTAR 3 -#define BUILD_TELEPORTER_ENTRANCE 4 -#define BUILD_TELEPORTER_EXIT 5 - -// Building metal costs -#define BUILD_COST_DISPENSER 100 // Metal needed to built -#define BUILD_COST_SENTRYGUN 130 -#define BUILD_COST_MORTAR 150 -#define BUILD_COST_TELEPORTER 125 - -#define BUILD_COST_SANDBAG 20 // Built with a separate alias - -// Building times -#define BUILD_TIME_DISPENSER 2 // seconds to build -#define BUILD_TIME_SENTRYGUN 5 -#define BUILD_TIME_MORTAR 5 -#define BUILD_TIME_TELEPORTER 4 - -// Building health levels -#define BUILD_HEALTH_DISPENSER 150 // Health of the building -#define BUILD_HEALTH_SENTRYGUN 150 -#define BUILD_HEALTH_MORTAR 200 -#define BUILD_HEALTH_TELEPORTER 80 - -// Dispenser's maximum carrying capability -#define BUILD_DISPENSER_MAX_SHELLS 400 -#define BUILD_DISPENSER_MAX_NAILS 600 -#define BUILD_DISPENSER_MAX_ROCKETS 300 -#define BUILD_DISPENSER_MAX_CELLS 400 -#define BUILD_DISPENSER_MAX_ARMOR 500 - -// Build state sent down to client -#define BS_BUILDING (1<<0) -#define BS_HAS_DISPENSER (1<<1) -#define BS_HAS_SENTRYGUN (1<<2) -#define BS_CANB_DISPENSER (1<<3) -#define BS_CANB_SENTRYGUN (1<<4) -/*==================================================*/ -/* Ammo quantities for dropping & dispenser use */ -/*==================================================*/ -#define DROP_SHELLS 20 -#define DROP_NAILS 20 -#define DROP_ROCKETS 10 -#define DROP_CELLS 10 -#define DROP_ARMOR 40 - -/*==================================================*/ -/* Team Defines */ -/*==================================================*/ -#define TM_MAX_NO 4 // Max number of teams. Simply changing this value isn't enough. - // A new global to hold new team colors is needed, and more flags - // in the spawnpoint spawnflags may need to be used. - // Basically, don't change this unless you know what you're doing :) - -/*==================================================*/ -/* New Weapon Defines */ -/*==================================================*/ -#define WEAP_HOOK 1 -#define WEAP_BIOWEAPON 2 -#define WEAP_MEDIKIT 4 -#define WEAP_SPANNER 8 -#define WEAP_AXE 16 -#define WEAP_SNIPER_RIFLE 32 -#define WEAP_AUTO_RIFLE 64 -#define WEAP_SHOTGUN 128 -#define WEAP_SUPER_SHOTGUN 256 -#define WEAP_NAILGUN 512 -#define WEAP_SUPER_NAILGUN 1024 -#define WEAP_GRENADE_LAUNCHER 2048 -#define WEAP_FLAMETHROWER 4096 -#define WEAP_ROCKET_LAUNCHER 8192 -#define WEAP_INCENDIARY 16384 -#define WEAP_ASSAULT_CANNON 32768 -#define WEAP_LIGHTNING 65536 -#define WEAP_DETPACK 131072 -#define WEAP_TRANQ 262144 -#define WEAP_LASER 524288 -// still room for 12 more weapons -// but we can remove some by giving the weapons -// a weapon mode (like the rifle) - -// HL-compatible weapon numbers -#define WEAPON_HOOK 1 -#define WEAPON_BIOWEAPON (WEAPON_HOOK+1) -#define WEAPON_MEDIKIT (WEAPON_HOOK+2) -#define WEAPON_SPANNER (WEAPON_HOOK+3) -#define WEAPON_AXE (WEAPON_HOOK+4) -#define WEAPON_SNIPER_RIFLE (WEAPON_HOOK+5) -#define WEAPON_AUTO_RIFLE (WEAPON_HOOK+6) -#define WEAPON_TF_SHOTGUN (WEAPON_HOOK+7) -#define WEAPON_SUPER_SHOTGUN (WEAPON_HOOK+8) -#define WEAPON_NAILGUN (WEAPON_HOOK+9) -#define WEAPON_SUPER_NAILGUN (WEAPON_HOOK+10) -#define WEAPON_GRENADE_LAUNCHER (WEAPON_HOOK+11) -#define WEAPON_FLAMETHROWER (WEAPON_HOOK+12) -#define WEAPON_ROCKET_LAUNCHER (WEAPON_HOOK+13) -#define WEAPON_INCENDIARY (WEAPON_HOOK+14) -#define WEAPON_ASSAULT_CANNON (WEAPON_HOOK+16) -#define WEAPON_LIGHTNING (WEAPON_HOOK+17) -#define WEAPON_DETPACK (WEAPON_HOOK+18) -#define WEAPON_TRANQ (WEAPON_HOOK+19) -#define WEAPON_LASER (WEAPON_HOOK+20) -#define WEAPON_PIPEBOMB_LAUNCHER (WEAPON_HOOK+21) -#define WEAPON_KNIFE (WEAPON_HOOK+22) -#define WEAPON_BENCHMARK (WEAPON_HOOK+23) - -/*==================================================*/ -/* New Weapon Related Defines */ -/*==================================================*/ -// shots per reload -#define RE_SHOTGUN 8 -#define RE_SUPER_SHOTGUN 16 // 8 shots -#define RE_GRENADE_LAUNCHER 6 -#define RE_ROCKET_LAUNCHER 4 - -// reload times -#define RE_SHOTGUN_TIME 2 -#define RE_SUPER_SHOTGUN_TIME 3 -#define RE_GRENADE_LAUNCHER_TIME 4 -#define RE_ROCKET_LAUNCHER_TIME 5 - -// Maximum velocity you can move and fire the Sniper Rifle -#define WEAP_SNIPER_RIFLE_MAX_MOVE 50 - -// Medikit -#define WEAP_MEDIKIT_HEAL 200 // Amount medikit heals per hit -#define WEAP_MEDIKIT_OVERHEAL 50 // Amount of superhealth over max_health the medikit will dispense - -// Spanner -#define WEAP_SPANNER_REPAIR 10 - -// Detpack -#define WEAP_DETPACK_DISARMTIME 3 // Time it takes to disarm a Detpack -#define WEAP_DETPACK_SETTIME 3 // Time it takes to set a Detpack -#define WEAP_DETPACK_SIZE 700 // Explosion Size -#define WEAP_DETPACK_GOAL_SIZE 1500 // Explosion Size for goal triggering -#define WEAP_DETPACK_BITS_NO 12 // Bits that detpack explodes into - -// Tranquiliser Gun -#define TRANQ_TIME 15 - -// Grenades -#define GR_PRIMETIME 3 -#define GR_CALTROP_PRIME 0.5 -#define GR_TYPE_NONE 0 -#define GR_TYPE_NORMAL 1 -#define GR_TYPE_CONCUSSION 2 -#define GR_TYPE_NAIL 3 -#define GR_TYPE_MIRV 4 -#define GR_TYPE_NAPALM 5 -//#define GR_TYPE_FLARE 6 -#define GR_TYPE_GAS 7 -#define GR_TYPE_EMP 8 -#define GR_TYPE_CALTROP 9 -//#define GR_TYPE_FLASH 10 - -// Defines for WeaponMode -#define GL_NORMAL 0 -#define GL_PIPEBOMB 1 - -// Defines for OLD Concussion Grenade -#define GR_OLD_CONCUSS_TIME 5 -#define GR_OLD_CONCUSS_DEC 20 - -// Defines for Concussion Grenade -#define GR_CONCUSS_TIME 0.25 -#define GR_CONCUSS_DEC 10 -#define MEDIUM_PING 150 -#define HIGH_PING 200 - -// Defines for the Gas Grenade -#define GR_HALLU_TIME 0.3 -#define GR_OLD_HALLU_TIME 0.5 -#define GR_HALLU_DEC 2.5 - -// Defines for the BioInfection -#define BIO_JUMP_RADIUS 128 // The distance the bioinfection can jump between players - -/*==================================================*/ -/* New Items */ -/*==================================================*/ -#define NIT_SCANNER 1 - -#define NIT_SILVER_DOOR_OPENED #IT_KEY1 // 131072 -#define NIT_GOLD_DOOR_OPENED #IT_KEY2 // 262144 - -/*==================================================*/ -/* New Item Flags */ -/*==================================================*/ -#define NIT_SCANNER_ENEMY 1 // Detect enemies -#define NIT_SCANNER_FRIENDLY 2 // Detect friendlies (team members) -#define NIT_SCANNER_SOUND 4 // Motion detection. Only report moving entities. - -/*==================================================*/ -/* New Item Related Defines */ -/*==================================================*/ -#define NIT_SCANNER_POWER 25 // The amount of power spent on a scan with the scanner - // is multiplied by this to get the scanrange. -#define NIT_SCANNER_MAXCELL 50 // The maximum number of cells than can be used in one scan -#define NIT_SCANNER_MIN_MOVEMENT 50 // The minimum velocity an entity must have to be detected - // by scanners that only detect movement - -/*==================================================*/ -/* Variables used for New Weapons and Reloading */ -/*==================================================*/ -// Armor Classes : Bitfields. Use the "armorclass" of armor for the Armor Type. -#define AT_SAVESHOT 1 // Kevlar : Reduces bullet damage by 15% -#define AT_SAVENAIL 2 // Wood :) : Reduces nail damage by 15% -#define AT_SAVEEXPLOSION 4 // Blast : Reduces explosion damage by 15% -#define AT_SAVEELECTRICITY 8 // Shock : Reduces electricity damage by 15% -#define AT_SAVEFIRE 16 // Asbestos : Reduces fire damage by 15% - -/*==========================================================================*/ -/* TEAMFORTRESS CLASS DETAILS */ -/*==========================================================================*/ -// Class Details for SCOUT -#define PC_SCOUT_SKIN 4 // Skin for this class when Classkin is on. -#define PC_SCOUT_MAXHEALTH 75 // Maximum Health Level -#define PC_SCOUT_MAXSPEED 400 // Maximum movement speed -#define PC_SCOUT_MAXSTRAFESPEED 400 // Maximum strafing movement speed -#define PC_SCOUT_MAXARMOR 50 // Maximum Armor Level, of any armor class -#define PC_SCOUT_INITARMOR 25 // Armor level when respawned -#define PC_SCOUT_MAXARMORTYPE 0.3 // Maximum level of Armor absorption -#define PC_SCOUT_INITARMORTYPE 0.3 // Absorption Level of armor when respawned -#define PC_SCOUT_ARMORCLASSES 3 // #AT_SAVESHOT | #AT_SAVENAIL <-Armor Classes allowed for this class -#define PC_SCOUT_INITARMORCLASS 0 // Armorclass worn when respawned -#define PC_SCOUT_WEAPONS WEAP_AXE | WEAP_SHOTGUN | WEAP_NAILGUN -#define PC_SCOUT_MAXAMMO_SHOT 50 // Maximum amount of shot ammo this class can carry -#define PC_SCOUT_MAXAMMO_NAIL 200 // Maximum amount of nail ammo this class can carry -#define PC_SCOUT_MAXAMMO_CELL 100 // Maximum amount of cell ammo this class can carry -#define PC_SCOUT_MAXAMMO_ROCKET 25 // Maximum amount of rocket ammo this class can carry -#define PC_SCOUT_INITAMMO_SHOT 25 // Amount of shot ammo this class has when respawned -#define PC_SCOUT_INITAMMO_NAIL 100 // Amount of nail ammo this class has when respawned -#define PC_SCOUT_INITAMMO_CELL 50 // Amount of cell ammo this class has when respawned -#define PC_SCOUT_INITAMMO_ROCKET 0 // Amount of rocket ammo this class has when respawned -#define PC_SCOUT_GRENADE_TYPE_1 GR_TYPE_CALTROP // <- 1st Type of Grenade this class has -#define PC_SCOUT_GRENADE_TYPE_2 GR_TYPE_CONCUSSION // <- 2nd Type of Grenade this class has -#define PC_SCOUT_GRENADE_INIT_1 2 // Number of grenades of Type 1 this class has when respawned -#define PC_SCOUT_GRENADE_INIT_2 3 // Number of grenades of Type 2 this class has when respawned -#define PC_SCOUT_TF_ITEMS NIT_SCANNER // <- TeamFortress Items this class has - -#define PC_SCOUT_MOTION_MIN_I 0.5 // < Short range -#define PC_SCOUT_MOTION_MIN_MOVE 50 // Minimum vlen of player velocity to be picked up by motion detector -#define PC_SCOUT_SCAN_TIME 2 // # of seconds between each scan pulse -#define PC_SCOUT_SCAN_RANGE 100 // Default scanner range -#define PC_SCOUT_SCAN_COST 2 // Default scanner cell useage per scan - -// Class Details for SNIPER -#define PC_SNIPER_SKIN 5 -#define PC_SNIPER_MAXHEALTH 90 -#define PC_SNIPER_MAXSPEED 300 -#define PC_SNIPER_MAXSTRAFESPEED 300 -#define PC_SNIPER_MAXARMOR 50 -#define PC_SNIPER_INITARMOR 0 -#define PC_SNIPER_MAXARMORTYPE 0.3 -#define PC_SNIPER_INITARMORTYPE 0.3 -#define PC_SNIPER_ARMORCLASSES 3 // #AT_SAVESHOT | #AT_SAVENAIL -#define PC_SNIPER_INITARMORCLASS 0 -#define PC_SNIPER_WEAPONS WEAP_SNIPER_RIFLE | WEAP_AUTO_RIFLE | WEAP_AXE | WEAP_NAILGUN -#define PC_SNIPER_MAXAMMO_SHOT 75 -#define PC_SNIPER_MAXAMMO_NAIL 100 -#define PC_SNIPER_MAXAMMO_CELL 50 -#define PC_SNIPER_MAXAMMO_ROCKET 25 -#define PC_SNIPER_INITAMMO_SHOT 60 -#define PC_SNIPER_INITAMMO_NAIL 50 -#define PC_SNIPER_INITAMMO_CELL 0 -#define PC_SNIPER_INITAMMO_ROCKET 0 -#define PC_SNIPER_GRENADE_TYPE_1 GR_TYPE_NORMAL -#define PC_SNIPER_GRENADE_TYPE_2 GR_TYPE_NONE -#define PC_SNIPER_GRENADE_INIT_1 2 -#define PC_SNIPER_GRENADE_INIT_2 0 -#define PC_SNIPER_TF_ITEMS 0 - -// Class Details for SOLDIER -#define PC_SOLDIER_SKIN 6 -#define PC_SOLDIER_MAXHEALTH 100 -#define PC_SOLDIER_MAXSPEED 240 -#define PC_SOLDIER_MAXSTRAFESPEED 240 -#define PC_SOLDIER_MAXARMOR 200 -#define PC_SOLDIER_INITARMOR 100 -#define PC_SOLDIER_MAXARMORTYPE 0.8 -#define PC_SOLDIER_INITARMORTYPE 0.8 -#define PC_SOLDIER_ARMORCLASSES 31 // ALL -#define PC_SOLDIER_INITARMORCLASS 0 -#define PC_SOLDIER_WEAPONS WEAP_AXE | WEAP_SHOTGUN | WEAP_SUPER_SHOTGUN | WEAP_ROCKET_LAUNCHER -#define PC_SOLDIER_MAXAMMO_SHOT 100 -#define PC_SOLDIER_MAXAMMO_NAIL 100 -#define PC_SOLDIER_MAXAMMO_CELL 50 -#define PC_SOLDIER_MAXAMMO_ROCKET 50 -#define PC_SOLDIER_INITAMMO_SHOT 50 -#define PC_SOLDIER_INITAMMO_NAIL 0 -#define PC_SOLDIER_INITAMMO_CELL 0 -#define PC_SOLDIER_INITAMMO_ROCKET 10 -#define PC_SOLDIER_GRENADE_TYPE_1 GR_TYPE_NORMAL -#define PC_SOLDIER_GRENADE_TYPE_2 GR_TYPE_NAIL -#define PC_SOLDIER_GRENADE_INIT_1 4 -#define PC_SOLDIER_GRENADE_INIT_2 1 -#define PC_SOLDIER_TF_ITEMS 0 - -#define MAX_NAIL_GRENS 2 // Can only have 2 Nail grens active -#define MAX_NAPALM_GRENS 2 // Can only have 2 Napalm grens active -#define MAX_GAS_GRENS 2 // Can only have 2 Gas grenades active -#define MAX_MIRV_GRENS 2 // Can only have 2 Mirv's -#define MAX_CONCUSSION_GRENS 3 -#define MAX_CALTROP_CANS 3 - -// Class Details for DEMOLITION MAN -#define PC_DEMOMAN_SKIN 1 -#define PC_DEMOMAN_MAXHEALTH 90 -#define PC_DEMOMAN_MAXSPEED 280 -#define PC_DEMOMAN_MAXSTRAFESPEED 280 -#define PC_DEMOMAN_MAXARMOR 120 -#define PC_DEMOMAN_INITARMOR 50 -#define PC_DEMOMAN_MAXARMORTYPE 0.6 -#define PC_DEMOMAN_INITARMORTYPE 0.6 -#define PC_DEMOMAN_ARMORCLASSES 31 // ALL -#define PC_DEMOMAN_INITARMORCLASS 0 -#define PC_DEMOMAN_WEAPONS WEAP_AXE | WEAP_SHOTGUN | WEAP_GRENADE_LAUNCHER | WEAP_DETPACK -#define PC_DEMOMAN_MAXAMMO_SHOT 75 -#define PC_DEMOMAN_MAXAMMO_NAIL 50 -#define PC_DEMOMAN_MAXAMMO_CELL 50 -#define PC_DEMOMAN_MAXAMMO_ROCKET 50 -#define PC_DEMOMAN_MAXAMMO_DETPACK 1 -#define PC_DEMOMAN_INITAMMO_SHOT 30 -#define PC_DEMOMAN_INITAMMO_NAIL 0 -#define PC_DEMOMAN_INITAMMO_CELL 0 -#define PC_DEMOMAN_INITAMMO_ROCKET 20 -#define PC_DEMOMAN_INITAMMO_DETPACK 1 -#define PC_DEMOMAN_GRENADE_TYPE_1 GR_TYPE_NORMAL -#define PC_DEMOMAN_GRENADE_TYPE_2 GR_TYPE_MIRV -#define PC_DEMOMAN_GRENADE_INIT_1 4 -#define PC_DEMOMAN_GRENADE_INIT_2 4 -#define PC_DEMOMAN_TF_ITEMS 0 - -// Class Details for COMBAT MEDIC -#define PC_MEDIC_SKIN 3 -#define PC_MEDIC_MAXHEALTH 90 -#define PC_MEDIC_MAXSPEED 320 -#define PC_MEDIC_MAXSTRAFESPEED 320 -#define PC_MEDIC_MAXARMOR 100 -#define PC_MEDIC_INITARMOR 50 -#define PC_MEDIC_MAXARMORTYPE 0.6 -#define PC_MEDIC_INITARMORTYPE 0.3 -#define PC_MEDIC_ARMORCLASSES 11 // ALL except EXPLOSION -#define PC_MEDIC_INITARMORCLASS 0 -#define PC_MEDIC_WEAPONS WEAP_BIOWEAPON | WEAP_MEDIKIT | WEAP_SHOTGUN | WEAP_SUPER_SHOTGUN | WEAP_SUPER_NAILGUN -#define PC_MEDIC_MAXAMMO_SHOT 75 -#define PC_MEDIC_MAXAMMO_NAIL 150 -#define PC_MEDIC_MAXAMMO_CELL 50 -#define PC_MEDIC_MAXAMMO_ROCKET 25 -#define PC_MEDIC_MAXAMMO_MEDIKIT 100 -#define PC_MEDIC_INITAMMO_SHOT 50 -#define PC_MEDIC_INITAMMO_NAIL 50 -#define PC_MEDIC_INITAMMO_CELL 0 -#define PC_MEDIC_INITAMMO_ROCKET 0 -#define PC_MEDIC_INITAMMO_MEDIKIT 50 -#define PC_MEDIC_GRENADE_TYPE_1 GR_TYPE_NORMAL -#define PC_MEDIC_GRENADE_TYPE_2 GR_TYPE_CONCUSSION -#define PC_MEDIC_GRENADE_INIT_1 3 -#define PC_MEDIC_GRENADE_INIT_2 2 -#define PC_MEDIC_TF_ITEMS 0 -#define PC_MEDIC_REGEN_TIME 3 // Number of seconds between each regen. -#define PC_MEDIC_REGEN_AMOUNT 2 // Amount of health regenerated each regen. - -// Class Details for HVYWEAP -#define PC_HVYWEAP_SKIN 2 -#define PC_HVYWEAP_MAXHEALTH 100 -#define PC_HVYWEAP_MAXSPEED 230 -#define PC_HVYWEAP_MAXSTRAFESPEED 230 -#define PC_HVYWEAP_MAXARMOR 300 -#define PC_HVYWEAP_INITARMOR 150 -#define PC_HVYWEAP_MAXARMORTYPE 0.8 -#define PC_HVYWEAP_INITARMORTYPE 0.8 -#define PC_HVYWEAP_ARMORCLASSES 31 // ALL -#define PC_HVYWEAP_INITARMORCLASS 0 -#define PC_HVYWEAP_WEAPONS WEAP_ASSAULT_CANNON | WEAP_AXE | WEAP_SHOTGUN | WEAP_SUPER_SHOTGUN -#define PC_HVYWEAP_MAXAMMO_SHOT 200 -#define PC_HVYWEAP_MAXAMMO_NAIL 200 -#define PC_HVYWEAP_MAXAMMO_CELL 50 -#define PC_HVYWEAP_MAXAMMO_ROCKET 25 -#define PC_HVYWEAP_INITAMMO_SHOT 200 -#define PC_HVYWEAP_INITAMMO_NAIL 0 -#define PC_HVYWEAP_INITAMMO_CELL 30 -#define PC_HVYWEAP_INITAMMO_ROCKET 0 -#define PC_HVYWEAP_GRENADE_TYPE_1 GR_TYPE_NORMAL -#define PC_HVYWEAP_GRENADE_TYPE_2 GR_TYPE_MIRV -#define PC_HVYWEAP_GRENADE_INIT_1 4 -#define PC_HVYWEAP_GRENADE_INIT_2 1 -#define PC_HVYWEAP_TF_ITEMS 0 -#define PC_HVYWEAP_CELL_USAGE 7 // Amount of cells spent to power up assault cannon - - - -// Class Details for PYRO -#define PC_PYRO_SKIN 21 -#define PC_PYRO_MAXHEALTH 100 -#define PC_PYRO_MAXSPEED 300 -#define PC_PYRO_MAXSTRAFESPEED 300 -#define PC_PYRO_MAXARMOR 150 -#define PC_PYRO_INITARMOR 50 -#define PC_PYRO_MAXARMORTYPE 0.6 -#define PC_PYRO_INITARMORTYPE 0.6 -#define PC_PYRO_ARMORCLASSES 27 // ALL except EXPLOSION -#define PC_PYRO_INITARMORCLASS 16 // #AT_SAVEFIRE -#define PC_PYRO_WEAPONS WEAP_INCENDIARY | WEAP_FLAMETHROWER | WEAP_AXE | WEAP_SHOTGUN -#define PC_PYRO_MAXAMMO_SHOT 40 -#define PC_PYRO_MAXAMMO_NAIL 50 -#define PC_PYRO_MAXAMMO_CELL 200 -#define PC_PYRO_MAXAMMO_ROCKET 20 -#define PC_PYRO_INITAMMO_SHOT 20 -#define PC_PYRO_INITAMMO_NAIL 0 -#define PC_PYRO_INITAMMO_CELL 120 -#define PC_PYRO_INITAMMO_ROCKET 5 -#define PC_PYRO_GRENADE_TYPE_1 GR_TYPE_NORMAL -#define PC_PYRO_GRENADE_TYPE_2 GR_TYPE_NAPALM -#define PC_PYRO_GRENADE_INIT_1 1 -#define PC_PYRO_GRENADE_INIT_2 4 -#define PC_PYRO_TF_ITEMS 0 -#define PC_PYRO_ROCKET_USAGE 3 // Number of rockets per incendiary cannon shot - -// Class Details for SPY -#define PC_SPY_SKIN 22 -#define PC_SPY_MAXHEALTH 90 -#define PC_SPY_MAXSPEED 300 -#define PC_SPY_MAXSTRAFESPEED 300 -#define PC_SPY_MAXARMOR 100 -#define PC_SPY_INITARMOR 25 -#define PC_SPY_MAXARMORTYPE 0.6 // Was 0.3 -#define PC_SPY_INITARMORTYPE 0.6 // Was 0.3 -#define PC_SPY_ARMORCLASSES 27 // ALL except EXPLOSION -#define PC_SPY_INITARMORCLASS 0 -#define PC_SPY_WEAPONS WEAP_AXE | WEAP_TRANQ | WEAP_SUPER_SHOTGUN | WEAP_NAILGUN -#define PC_SPY_MAXAMMO_SHOT 40 -#define PC_SPY_MAXAMMO_NAIL 100 -#define PC_SPY_MAXAMMO_CELL 30 -#define PC_SPY_MAXAMMO_ROCKET 15 -#define PC_SPY_INITAMMO_SHOT 40 -#define PC_SPY_INITAMMO_NAIL 50 -#define PC_SPY_INITAMMO_CELL 10 -#define PC_SPY_INITAMMO_ROCKET 0 -#define PC_SPY_GRENADE_TYPE_1 GR_TYPE_NORMAL -#define PC_SPY_GRENADE_TYPE_2 GR_TYPE_GAS -#define PC_SPY_GRENADE_INIT_1 2 -#define PC_SPY_GRENADE_INIT_2 2 -#define PC_SPY_TF_ITEMS 0 -#define PC_SPY_CELL_REGEN_TIME 5 -#define PC_SPY_CELL_REGEN_AMOUNT 1 -#define PC_SPY_CELL_USAGE 3 // Amount of cells spent while invisible -#define PC_SPY_GO_UNDERCOVER_TIME 4 // Time it takes to go undercover - -// Class Details for ENGINEER -#define PC_ENGINEER_SKIN 22 // Not used anymore -#define PC_ENGINEER_MAXHEALTH 80 -#define PC_ENGINEER_MAXSPEED 300 -#define PC_ENGINEER_MAXSTRAFESPEED 300 -#define PC_ENGINEER_MAXARMOR 50 -#define PC_ENGINEER_INITARMOR 25 -#define PC_ENGINEER_MAXARMORTYPE 0.6 -#define PC_ENGINEER_INITARMORTYPE 0.3 -#define PC_ENGINEER_ARMORCLASSES 31 // ALL -#define PC_ENGINEER_INITARMORCLASS 0 -#define PC_ENGINEER_WEAPONS WEAP_SPANNER | WEAP_LASER | WEAP_SUPER_SHOTGUN -#define PC_ENGINEER_MAXAMMO_SHOT 50 -#define PC_ENGINEER_MAXAMMO_NAIL 50 -#define PC_ENGINEER_MAXAMMO_CELL 200 // synonymous with metal -#define PC_ENGINEER_MAXAMMO_ROCKET 30 -#define PC_ENGINEER_INITAMMO_SHOT 20 -#define PC_ENGINEER_INITAMMO_NAIL 25 -#define PC_ENGINEER_INITAMMO_CELL 100 // synonymous with metal -#define PC_ENGINEER_INITAMMO_ROCKET 0 -#define PC_ENGINEER_GRENADE_TYPE_1 GR_TYPE_NORMAL -#define PC_ENGINEER_GRENADE_TYPE_2 GR_TYPE_EMP -#define PC_ENGINEER_GRENADE_INIT_1 2 -#define PC_ENGINEER_GRENADE_INIT_2 2 -#define PC_ENGINEER_TF_ITEMS 0 - -// Class Details for CIVILIAN -#define PC_CIVILIAN_SKIN 22 -#define PC_CIVILIAN_MAXHEALTH 50 -#define PC_CIVILIAN_MAXSPEED 240 -#define PC_CIVILIAN_MAXSTRAFESPEED 240 -#define PC_CIVILIAN_MAXARMOR 0 -#define PC_CIVILIAN_INITARMOR 0 -#define PC_CIVILIAN_MAXARMORTYPE 0 -#define PC_CIVILIAN_INITARMORTYPE 0 -#define PC_CIVILIAN_ARMORCLASSES 0 -#define PC_CIVILIAN_INITARMORCLASS 0 -#define PC_CIVILIAN_WEAPONS WEAP_AXE -#define PC_CIVILIAN_MAXAMMO_SHOT 0 -#define PC_CIVILIAN_MAXAMMO_NAIL 0 -#define PC_CIVILIAN_MAXAMMO_CELL 0 -#define PC_CIVILIAN_MAXAMMO_ROCKET 0 -#define PC_CIVILIAN_INITAMMO_SHOT 0 -#define PC_CIVILIAN_INITAMMO_NAIL 0 -#define PC_CIVILIAN_INITAMMO_CELL 0 -#define PC_CIVILIAN_INITAMMO_ROCKET 0 -#define PC_CIVILIAN_GRENADE_TYPE_1 0 -#define PC_CIVILIAN_GRENADE_TYPE_2 0 -#define PC_CIVILIAN_GRENADE_INIT_1 0 -#define PC_CIVILIAN_GRENADE_INIT_2 0 -#define PC_CIVILIAN_TF_ITEMS 0 - - -/*==========================================================================*/ -/* TEAMFORTRESS GOALS */ -/*==========================================================================*/ -// For all these defines, see the tfortmap.txt that came with the zip -// for complete descriptions. -// Defines for Goal Activation types : goal_activation (in goals) -#define TFGA_TOUCH 1 // Activated when touched -#define TFGA_TOUCH_DETPACK 2 // Activated when touched by a detpack explosion -#define TFGA_REVERSE_AP 4 // Activated when AP details are _not_ met -#define TFGA_SPANNER 8 // Activated when hit by an engineer's spanner -#define TFGA_DROPTOGROUND 2048 // Drop to Ground when spawning - -// Defines for Goal Effects types : goal_effect -#define TFGE_AP 1 // AP is affected. Default. -#define TFGE_AP_TEAM 2 // All of the AP's team. -#define TFGE_NOT_AP_TEAM 4 // All except AP's team. -#define TFGE_NOT_AP 8 // All except AP. -#define TFGE_WALL 16 // If set, walls stop the Radius effects -#define TFGE_SAME_ENVIRONMENT 32 // If set, players in a different environment to the Goal are not affected -#define TFGE_TIMER_CHECK_AP 64 // If set, Timer Goals check their critera for all players fitting their effects - -// Defines for Goal Result types : goal_result -#define TFGR_SINGLE 1 // Goal can only be activated once -#define TFGR_ADD_BONUSES 2 // Any Goals activated by this one give their bonuses -#define TFGR_ENDGAME 4 // Goal fires Intermission, displays scores, and ends level -#define TFGR_NO_ITEM_RESULTS 8 // GoalItems given by this Goal don't do results -#define TFGR_REMOVE_DISGUISE 16 // Prevent/Remove undercover from any Spy -#define TFGR_FORCE_RESPAWN 32 // Forces the player to teleport to a respawn point -#define TFGR_DESTROY_BUILDINGS 64 // Destroys this player's buildings, if anys - -// Defines for Goal Group Result types : goal_group -// None! -// But I'm leaving this variable in there, since it's fairly likely -// that some will show up sometime. - -// Defines for Goal Item types, : goal_activation (in items) -#define TFGI_GLOW 1 // Players carrying this GoalItem will glow -#define TFGI_SLOW 2 // Players carrying this GoalItem will move at half-speed -#define TFGI_DROP 4 // Players dying with this item will drop it -#define TFGI_RETURN_DROP 8 // Return if a player with it dies -#define TFGI_RETURN_GOAL 16 // Return if a player with it has it removed by a goal's activation -#define TFGI_RETURN_REMOVE 32 // Return if it is removed by TFGI_REMOVE -#define TFGI_REVERSE_AP 64 // Only pickup if the player _doesn't_ match AP Details -#define TFGI_REMOVE 128 // Remove if left untouched for 2 minutes after being dropped -#define TFGI_KEEP 256 // Players keep this item even when they die -#define TFGI_ITEMGLOWS 512 // Item glows when on the ground -#define TFGI_DONTREMOVERES 1024 // Don't remove results when the item is removed -#define TFGI_DROPTOGROUND 2048 // Drop To Ground when spawning -#define TFGI_CANBEDROPPED 4096 // Can be voluntarily dropped by players -#define TFGI_SOLID 8192 // Is solid... blocks bullets, etc - -// Defines for methods of GoalItem returning -#define GI_RET_DROP_DEAD 0 // Dropped by a dead player -#define GI_RET_DROP_LIVING 1 // Dropped by a living player -#define GI_RET_GOAL 2 // Returned by a Goal -#define GI_RET_TIME 3 // Returned due to timeout - -// Defines for TeamSpawnpoints : goal_activation (in teamspawns) -#define TFSP_MULTIPLEITEMS 1 // Give out the GoalItem multiple times -#define TFSP_MULTIPLEMSGS 2 // Display the message multiple times - -// Defines for TeamSpawnpoints : goal_effects (in teamspawns) -#define TFSP_REMOVESELF 1 // Remove itself after being spawned on - -// Defines for Goal States -#define TFGS_ACTIVE 1 -#define TFGS_INACTIVE 2 -#define TFGS_REMOVED 3 -#define TFGS_DELAYED 4 - -// Defines for GoalItem Removing from Player Methods -#define GI_DROP_PLAYERDEATH 0 // Dropped by a dying player -#define GI_DROP_REMOVEGOAL 1 // Removed by a Goal -#define GI_DROP_PLAYERDROP 2 // Dropped by a player - -// Legal Playerclass Handling -#define TF_ILL_SCOUT 1 -#define TF_ILL_SNIPER 2 -#define TF_ILL_SOLDIER 4 -#define TF_ILL_DEMOMAN 8 -#define TF_ILL_MEDIC 16 -#define TF_ILL_HVYWEP 32 -#define TF_ILL_PYRO 64 -#define TF_ILL_RANDOMPC 128 -#define TF_ILL_SPY 256 -#define TF_ILL_ENGINEER 512 - -// Addition classes -#define CLASS_TFGOAL 128 -#define CLASS_TFGOAL_TIMER 129 -#define CLASS_TFGOAL_ITEM 130 -#define CLASS_TFSPAWN 131 - -/*==========================================================================*/ -/* Flamethrower */ -/*==========================================================================*/ -#define FLAME_PLYRMAXTIME 4.5 // lifetime in seconds of a flame on a player -#define FLAME_MAXBURNTIME 8 // lifetime in seconds of a flame on the world (big ones) -#define NAPALM_MAXBURNTIME 20 // lifetime in seconds of flame from a napalm grenade -#define FLAME_MAXPLYRFLAMES 4 // maximum number of flames on a player -#define FLAME_NUMLIGHTS 1 // maximum number of light flame -#define FLAME_BURNRATIO 0.3 // the chance of a flame not 'sticking' -#define GR_TYPE_FLAMES_NO 15 // number of flames spawned when a grenade explode -#define FLAME_DAMAGE_TIME 1 // Interval between damage burns from flames -#define FLAME_EFFECT_TIME 0.2 // frequency at which we display flame effects. -#define FLAME_THINK_TIME 0.1 // Seconds between times the flame checks burn - -/*==================================================*/ -/* CTF Support defines */ -/*==================================================*/ -#define CTF_FLAG1 1 -#define CTF_FLAG2 2 -#define CTF_DROPOFF1 3 -#define CTF_DROPOFF2 4 -#define CTF_SCORE1 5 -#define CTF_SCORE2 6 - -//.float hook_out; - -/*==================================================*/ -/* Camera defines */ -/*==================================================*/ -/* -float live_camera; -.float camdist; -.vector camangle; -.entity camera_list; -*/ - -/*==================================================*/ -/* QuakeWorld defines */ -/*==================================================*/ -/* -float already_chosen_map; - -// grappling hook variables -.entity hook; -.float on_hook; -.float fire_held_down;// flag - TRUE if player is still holding down the - // fire button after throwing a hook. -*/ -/*==================================================*/ -/* Server Settings */ -/*==================================================*/ -// Admin modes -#define ADMIN_MODE_NONE 0 -#define ADMIN_MODE_DEAL 1 - -/*==================================================*/ -/* Death Message defines */ -/*==================================================*/ -#define DMSG_SHOTGUN 1 -#define DMSG_SSHOTGUN 2 -#define DMSG_NAILGUN 3 -#define DMSG_SNAILGUN 4 -#define DMSG_GRENADEL 5 -#define DMSG_ROCKETL 6 -#define DMSG_LIGHTNING 7 -#define DMSG_GREN_HAND 8 -#define DMSG_GREN_NAIL 9 -#define DMSG_GREN_MIRV 10 -#define DMSG_GREN_PIPE 11 -#define DMSG_DETPACK 12 -#define DMSG_BIOWEAPON 13 -#define DMSG_BIOWEAPON_ATT 14 -#define DMSG_FLAME 15 -#define DMSG_DETPACK_DIS 16 -#define DMSG_AXE 17 -#define DMSG_SNIPERRIFLE 18 -#define DMSG_AUTORIFLE 19 -#define DMSG_ASSAULTCANNON 20 -#define DMSG_HOOK 21 -#define DMSG_BACKSTAB 22 -#define DMSG_MEDIKIT 23 -#define DMSG_GREN_GAS 24 -#define DMSG_TRANQ 25 -#define DMSG_LASERBOLT 26 -#define DMSG_SENTRYGUN_BULLET 27 -#define DMSG_SNIPERLEGSHOT 28 -#define DMSG_SNIPERHEADSHOT 29 -#define DMSG_GREN_EMP 30 -#define DMSG_GREN_EMP_AMMO 31 -#define DMSG_SPANNER 32 -#define DMSG_INCENDIARY 33 -#define DMSG_SENTRYGUN_ROCKET 34 -#define DMSG_GREN_FLASH 35 -#define DMSG_TRIGGER 36 -#define DMSG_MIRROR 37 -#define DMSG_SENTRYDEATH 38 -#define DMSG_DISPENSERDEATH 39 -#define DMSG_GREN_AIRPIPE 40 -#define DMSG_CALTROP 41 - -/*==================================================*/ -// TOGGLEFLAGS -/*==================================================*/ -// Some of the toggleflags aren't used anymore, but the bits are still -// there to provide compatability with old maps -#define TFLAG_CLASS_PERSIST (1 << 0) // Persistent Classes Bit -#define TFLAG_CHEATCHECK (1 << 1) // Cheatchecking Bit -#define TFLAG_RESPAWNDELAY (1 << 2) // RespawnDelay bit -//#define TFLAG_UN (1 << 3) // NOT USED ANYMORE -#define TFLAG_OLD_GRENS (1 << 3) // Use old concussion grenade and flash grenade -#define TFLAG_UN2 (1 << 4) // NOT USED ANYMORE -#define TFLAG_UN3 (1 << 5) // NOT USED ANYMORE -#define TFLAG_UN4 (1 << 6) // NOT USED ANYMORE: Was Autoteam. CVAR tfc_autoteam used now. -#define TFLAG_TEAMFRAGS (1 << 7) // Individual Frags, or Frags = TeamScore -#define TFLAG_FIRSTENTRY (1 << 8) // Used to determine the first time toggleflags is set - // In a map. Cannot be toggled by players. -#define TFLAG_SPYINVIS (1 << 9) // Spy invisible only -#define TFLAG_GRAPPLE (1 << 10) // Grapple on/off -//#define TFLAG_FULLTEAMSCORE (1 << 11) // Each Team's score is TeamScore + Frags -#define TFLAG_FLAGEMULATION (1 << 12) // Flag emulation on for old TF maps -#define TFLAG_USE_STANDARD (1 << 13) // Use the TF War standard for Flag emulation - -#define TFLAG_FRAGSCORING (1 << 14) // Use frag scoring only - -/*======================*/ -// Menu stuff // -/*======================*/ - -#define MENU_DEFAULT 1 -#define MENU_TEAM 2 -#define MENU_CLASS 3 -#define MENU_MAPBRIEFING 4 -#define MENU_INTRO 5 -#define MENU_CLASSHELP 6 -#define MENU_CLASSHELP2 7 -#define MENU_REPEATHELP 8 - - - -#define MENU_SPY 12 -#define MENU_SPY_SKIN 13 -#define MENU_SPY_COLOR 14 -#define MENU_ENGINEER 15 -#define MENU_ENGINEER_FIX_DISPENSER 16 -#define MENU_ENGINEER_FIX_SENTRYGUN 17 -#define MENU_ENGINEER_FIX_MORTAR 18 -#define MENU_DISPENSER 19 -#define MENU_CLASS_CHANGE 20 -#define MENU_TEAM_CHANGE 21 - -#define MENU_REFRESH_RATE 25 - -//============================ -// Timer Types -#define TF_TIMER_ANY 0 -#define TF_TIMER_CONCUSSION 1 -#define TF_TIMER_INFECTION 2 -#define TF_TIMER_HALLUCINATION 3 -#define TF_TIMER_TRANQUILISATION 4 -#define TF_TIMER_ROTHEALTH 5 -#define TF_TIMER_REGENERATION 6 -#define TF_TIMER_GRENPRIME 7 -#define TF_TIMER_CELLREGENERATION 8 -#define TF_TIMER_DETPACKSET 9 -#define TF_TIMER_DETPACKDISARM 10 -#define TF_TIMER_BUILD 11 -#define TF_TIMER_CHECKBUILDDISTANCE 12 -#define TF_TIMER_DISGUISE 13 - -// Non Player timers -#define TF_TIMER_RETURNITEM 100 -#define TF_TIMER_DELAYEDGOAL 101 - -//============================ -// Teamscore printing -#define TS_PRINT_SHORT 1 -#define TS_PRINT_LONG 2 -#define TS_PRINT_LONG_TO_ALL 3 - -#ifndef TF_DEFS_ONLY -/*==================================================*/ -/* GLOBAL VARIABLES */ -/*==================================================*/ -// FortressMap stuff -extern float number_of_teams; // number of teams supported by the map -extern int illegalclasses[5]; // Illegal playerclasses for all teams -extern int civilianteams; // Bitfield holding Civilian teams -extern Vector rgbcolors[5]; // RGB colors for each of the 4 teams -extern int teamcolors[5]; // Colours for each of the 4 teams -extern int teamscores[5]; // Goal Score of each team -extern int g_iOrderedTeams[5]; // Teams ordered into order of winners->losers -extern int teamfrags[5]; // Total Frags for each team -extern int teamlives[5]; // Number of lives each team's players have -extern int teammaxplayers[5]; // Max number of players allowed in each team -extern float teamadvantage[5]; // only used if the teamplay equalisation bits are set - // stores the damage ratio players take/give -extern int teamallies[5]; // Keeps track of which teams are allied -extern string_t team_names[5]; - -extern BOOL CTF_Map; -extern BOOL birthday; -extern BOOL christmas; - -extern float num_world_flames; - -// Clan Battle stuff -extern float clan_scores_dumped; -extern float cb_prematch_time; -extern float fOldPrematch; -extern float fOldCeaseFire; -extern float cb_ceasefire_time; -extern float last_id; -extern float spy_off; -extern float old_grens; -extern float flagem_checked; -extern float flNextEqualisationCalc; -extern BOOL cease_fire; -extern BOOL initial_cease_fire; -extern BOOL last_cease_fire; -// Autokick stuff -extern float autokick_kills; - -extern float deathmsg; // Global, which is set before every T_Damage, to indicate - // the death message that should be used. - -extern char *sTeamSpawnNames[]; -extern char *sClassNames[]; -extern char *sClassModelFiles[]; -extern char *sClassModels[]; -extern char *sClassCfgs[]; -extern char *sGrenadeNames[]; -extern string_t team_menu_string; - -extern int toggleflags; // toggleable flags - -extern CBaseEntity* g_pLastSpawns[5]; -extern BOOL g_bFirstClient; - -extern float g_fNextPrematchAlert; - -typedef struct -{ - int ip; - edict_t *pEdict; -} ip_storage_t; - -extern ip_storage_t g_IpStorage[32]; - -class CGhost; -/*==========================================================================*/ -BOOL ClassIsRestricted(float tno, int pc); -char* GetTeamName(int tno); -int TeamFortress_GetNoPlayers(); -void DestroyBuilding(CBaseEntity *eng, char *bld); -void teamsprint( int tno, CBaseEntity *ignore, int msg_dest, const char *st, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL ); -float anglemod( float v ); - -// Team Funcs -BOOL TeamFortress_TeamIsCivilian(float tno); -void TeamFortress_TeamShowScores(BOOL bLong, CBasePlayer *pPlayer); -BOOL TeamFortress_TeamPutPlayerInTeam(); -void TeamFortress_TeamSetColor(int tno); -void TeamFortress_TeamIncreaseScore(int tno, int scoretoadd); -int TeamFortress_TeamGetScoreFrags(int tno); -int TeamFortress_TeamGetNoPlayers(int tno); -float TeamEqualiseDamage(CBaseEntity *targ, CBaseEntity *attacker, float damage); -BOOL IsSpawnPointValid( Vector &pos ); -BOOL TeamFortress_SortTeams( void ); -void DumpClanScores( void ); -void CalculateTeamEqualiser(); - -// mapscript funcs -void ParseTFServerSettings(); -void ParseTFMapSettings(); -CBaseEntity* Finditem(int ino); -CBaseEntity* Findgoal(int gno); -CBaseEntity* Findteamspawn(int gno); -void RemoveGoal(CBaseEntity *Goal); -void tfgoalitem_GiveToPlayer(CBaseEntity *Item, CBasePlayer *AP, CBaseEntity *Goal); -void dremove( CBaseEntity *te ); -void tfgoalitem_RemoveFromPlayer(CBaseEntity *Item, CBasePlayer *AP, int iMethod); -void tfgoalitem_drop(CBaseEntity *Item, BOOL PAlive, CBasePlayer *P); -void DisplayItemStatus(CBaseEntity *Goal, CBasePlayer *Player, CBaseEntity *Item); -void tfgoalitem_checkgoalreturn(CBaseEntity *Item); -void DoGoalWork(CBaseEntity *Goal, CBasePlayer *AP); -void DoResults(CBaseEntity *Goal, CBasePlayer *AP, BOOL bAddBonuses); -void DoGroupWork(CBaseEntity *Goal, CBasePlayer *AP); -// hooks into the mapscript for all entities -BOOL ActivateDoResults(CBaseEntity *Goal, CBasePlayer *AP, CBaseEntity *ActivatingGoal); -BOOL ActivationSucceeded(CBaseEntity *Goal, CBasePlayer *AP, CBaseEntity *ActivatingGoal); - -// prematch & ceasefire -void Display_Prematch(); -void Check_Ceasefire(); - -// admin -void KickPlayer( CBaseEntity *pTarget ); -void BanPlayer( CBaseEntity *pTarget ); -CGhost *FindGhost( int iGhostID ); -int GetBattleID( edict_t *pEntity ); - -extern cvar_t tfc_spam_penalty1;// the initial gag penalty for a spammer (seconds) -extern cvar_t tfc_spam_penalty2;// incremental gag penalty (seconds) for each time gagged spammer continues to speak. -extern cvar_t tfc_spam_limit; // at this many points, gag the spammer -extern cvar_t tfc_clanbattle, tfc_clanbattle_prematch, tfc_prematch, tfc_clanbattle_ceasefire, tfc_balance_teams, tfc_balance_scores; -extern cvar_t tfc_clanbattle_locked, tfc_birthday, tfc_autokick_kills, tfc_fragscoring, tfc_autokick_time, tfc_adminpwd; -extern cvar_t weaponstay, footsteps, flashlight, aimcrosshair, falldamage, teamplay; - -/*==========================================================================*/ -class CTFFlame : public CBaseMonster -{ -public: - void Spawn( void ); - void Precache( void ); - void EXPORT FlameThink( void ); - static CTFFlame *FlameSpawn( CBaseEntity *pOwner, CBaseEntity *pTarget ); - void FlameDestroy( void ); - - float m_flNextDamageTime; -}; - -/*==========================================================================*/ -// MAPSCRIPT CLASSES -class CTFGoal : public CBaseAnimating -{ -public: - void Spawn( void ); - void StartGoal( void ); - void EXPORT PlaceGoal( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - int Classify ( void ) { return CLASS_TFGOAL; } - - void SetObjectCollisionBox( void ); -}; - -class CTFGoalItem : public CTFGoal -{ -public: - void Spawn( void ); - void StartItem( void ); - void EXPORT PlaceItem( void ); - int Classify ( void ) { return CLASS_TFGOAL_ITEM; } - - float m_flDroppedAt; -}; - -class CTFTimerGoal : public CTFGoal -{ -public: - void Spawn( void ); - int Classify ( void ) { return CLASS_TFGOAL_TIMER; } -}; - -class CTFSpawn : public CBaseEntity -{ -public: - void Spawn( void ); - int Classify ( void ) { return CLASS_TFSPAWN; } -}; - -class CTFDetect : public CBaseEntity -{ -public: - void Spawn( void ); - int Classify ( void ) { return CLASS_TFGOAL; } -}; - -class CTelefragDeath : public CBaseEntity -{ -public: - void Spawn( void ); - void EXPORT DeathTouch( CBaseEntity *pOther ); -}; - -#endif // TF_DEFS_ONLY -#endif // __TF_DEFS_H - - diff --git a/ricochet/cl_dll/train.cpp b/ricochet/cl_dll/train.cpp deleted file mode 100644 index 9e15e16..0000000 --- a/ricochet/cl_dll/train.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// Train.cpp -// -// implementation of CHudAmmo class -// - -#include "hud.h" -#include "cl_util.h" -#include -#include -#include "parsemsg.h" - -DECLARE_MESSAGE(m_Train, Train ) - - -int CHudTrain::Init(void) -{ - HOOK_MESSAGE( Train ); - - m_iPos = 0; - m_iFlags = 0; - gHUD.AddHudElem(this); - - return 1; -}; - -int CHudTrain::VidInit(void) -{ - m_hSprite = 0; - - return 1; -}; - -int CHudTrain::Draw(float fTime) -{ - if ( !m_hSprite ) - m_hSprite = LoadSprite("sprites/%d_train.spr"); - - if (m_iPos) - { - int r, g, b, x, y; - - UnpackRGB(r,g,b, RGB_YELLOWISH); - SPR_Set(m_hSprite, r, g, b ); - - // This should show up to the right and part way up the armor number - y = ScreenHeight - SPR_Height(m_hSprite,0) - gHUD.m_iFontHeight; - x = ScreenWidth/3 + SPR_Width(m_hSprite,0)/4; - - SPR_DrawAdditive( m_iPos - 1, x, y, NULL); - - } - - return 1; -} - - -int CHudTrain::MsgFunc_Train(const char *pszName, int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - // update Train data - m_iPos = READ_BYTE(); - - if (m_iPos) - m_iFlags |= HUD_ACTIVE; - else - m_iFlags &= ~HUD_ACTIVE; - - return 1; -} diff --git a/ricochet/cl_dll/tri.cpp b/ricochet/cl_dll/tri.cpp deleted file mode 100644 index 4eb71c0..0000000 --- a/ricochet/cl_dll/tri.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// Triangle rendering, if any - -#include "hud.h" -#include "cl_util.h" - -// Triangle rendering apis are in gEngfuncs.pTriAPI - -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "triangleapi.h" - -extern "C" -{ - void DLLEXPORT HUD_DrawNormalTriangles( void ); - void DLLEXPORT HUD_DrawTransparentTriangles( void ); -}; - -//#define TEST_IT -#if defined( TEST_IT ) - -/* -================= -Draw_Triangles - -Example routine. Draws a sprite offset from the player origin. -================= -*/ -void Draw_Triangles( void ) -{ - cl_entity_t *player; - vec3_t org; - - // Load it up with some bogus data - player = gEngfuncs.GetLocalPlayer(); - if ( !player ) - return; - - org = player->origin; - - org.x += 50; - org.y += 50; - - if (gHUD.m_hsprCursor == 0) - { - char sz[256]; - sprintf( sz, "sprites/cursor.spr" ); - gHUD.m_hsprCursor = SPR_Load( sz ); - } - - if ( !gEngfuncs.pTriAPI->SpriteTexture( (struct model_s *)gEngfuncs.GetSpritePointer( gHUD.m_hsprCursor ), 0 )) - { - return; - } - - // Create a triangle, sigh - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); - gEngfuncs.pTriAPI->CullFace( TRI_NONE ); - gEngfuncs.pTriAPI->Begin( TRI_QUADS ); - // Overload p->color with index into tracer palette, p->packedColor with brightness - gEngfuncs.pTriAPI->Color4f( 1.0, 1.0, 1.0, 1.0 ); - // UNDONE: This gouraud shading causes tracers to disappear on some cards (permedia2) - gEngfuncs.pTriAPI->Brightness( 1 ); - gEngfuncs.pTriAPI->TexCoord2f( 0, 0 ); - gEngfuncs.pTriAPI->Vertex3f( org.x, org.y, org.z ); - - gEngfuncs.pTriAPI->Brightness( 1 ); - gEngfuncs.pTriAPI->TexCoord2f( 0, 1 ); - gEngfuncs.pTriAPI->Vertex3f( org.x, org.y + 50, org.z ); - - gEngfuncs.pTriAPI->Brightness( 1 ); - gEngfuncs.pTriAPI->TexCoord2f( 1, 1 ); - gEngfuncs.pTriAPI->Vertex3f( org.x + 50, org.y + 50, org.z ); - - gEngfuncs.pTriAPI->Brightness( 1 ); - gEngfuncs.pTriAPI->TexCoord2f( 1, 0 ); - gEngfuncs.pTriAPI->Vertex3f( org.x + 50, org.y, org.z ); - - gEngfuncs.pTriAPI->End(); - gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); -} - -#endif - -/* -================= -HUD_DrawNormalTriangles - -Non-transparent triangles-- add them here -================= -*/ -void DLLEXPORT HUD_DrawNormalTriangles( void ) -{ - -#if defined( TEST_IT ) -// Draw_Triangles(); -#endif -} - -/* -================= -HUD_DrawTransparentTriangles - -Render any triangles with transparent rendermode needs here -================= -*/ -void DLLEXPORT HUD_DrawTransparentTriangles( void ) -{ - -#if defined( TEST_IT ) -// Draw_Triangles(); -#endif -} \ No newline at end of file diff --git a/ricochet/cl_dll/util.cpp b/ricochet/cl_dll/util.cpp deleted file mode 100644 index 5495a38..0000000 --- a/ricochet/cl_dll/util.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// util.cpp -// -// implementation of class-less helper functions -// - -#include -#include -#include - -#include "hud.h" -#include "cl_util.h" -#include - -vec3_t vec3_origin( 0, 0, 0 ); - -HSPRITE LoadSprite(const char *pszName) -{ - int i; - char sz[256]; - - if (ScreenWidth < 640) - i = 320; - else - i = 640; - - sprintf(sz, pszName, i); - - return SPR_Load(sz); -} - diff --git a/ricochet/cl_dll/util_vector.h b/ricochet/cl_dll/util_vector.h deleted file mode 100644 index 1505dc1..0000000 --- a/ricochet/cl_dll/util_vector.h +++ /dev/null @@ -1,121 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// Vector.h -// A subset of the extdll.h in the project HL Entity DLL -// - -// Misc C-runtime library headers -#include "stdio.h" -#include "stdlib.h" -#include "math.h" - -// Header file containing definition of globalvars_t and entvars_t -typedef unsigned int func_t; // -typedef unsigned int string_t; // from engine's pr_comp.h; -typedef float vec_t; // needed before including progdefs.h - -//========================================================= -// 2DVector - used for many pathfinding and many other -// operations that are treated as planar rather than 3d. -//========================================================= -class Vector2D -{ -public: - inline Vector2D(void) { } - inline Vector2D(float X, float Y) { x = X; y = Y; } - inline Vector2D operator+(const Vector2D& v) const { return Vector2D(x+v.x, y+v.y); } - inline Vector2D operator-(const Vector2D& v) const { return Vector2D(x-v.x, y-v.y); } - inline Vector2D operator*(float fl) const { return Vector2D(x*fl, y*fl); } - inline Vector2D operator/(float fl) const { return Vector2D(x/fl, y/fl); } - - inline float Length(void) const { return (float)sqrt(x*x + y*y ); } - - inline Vector2D Normalize ( void ) const - { - Vector2D vec2; - - float flLen = Length(); - if ( flLen == 0 ) - { - return Vector2D( (float)0, (float)0 ); - } - else - { - flLen = 1 / flLen; - return Vector2D( x * flLen, y * flLen ); - } - } - - vec_t x, y; -}; - -inline float DotProduct(const Vector2D& a, const Vector2D& b) { return( a.x*b.x + a.y*b.y ); } -inline Vector2D operator*(float fl, const Vector2D& v) { return v * fl; } - -//========================================================= -// 3D Vector -//========================================================= -class Vector // same data-layout as engine's vec3_t, -{ // which is a vec_t[3] -public: - // Construction/destruction - inline Vector(void) { } - inline Vector(float X, float Y, float Z) { x = X; y = Y; z = Z; } - inline Vector(double X, double Y, double Z) { x = (float)X; y = (float)Y; z = (float)Z; } - inline Vector(int X, int Y, int Z) { x = (float)X; y = (float)Y; z = (float)Z; } - inline Vector(const Vector& v) { x = v.x; y = v.y; z = v.z; } - inline Vector(float rgfl[3]) { x = rgfl[0]; y = rgfl[1]; z = rgfl[2]; } - - // Operators - inline Vector operator-(void) const { return Vector(-x,-y,-z); } - inline int operator==(const Vector& v) const { return x==v.x && y==v.y && z==v.z; } - inline int operator!=(const Vector& v) const { return !(*this==v); } - inline Vector operator+(const Vector& v) const { return Vector(x+v.x, y+v.y, z+v.z); } - inline Vector operator-(const Vector& v) const { return Vector(x-v.x, y-v.y, z-v.z); } - inline Vector operator*(float fl) const { return Vector(x*fl, y*fl, z*fl); } - inline Vector operator/(float fl) const { return Vector(x/fl, y/fl, z/fl); } - - // Methods - inline void CopyToArray(float* rgfl) const { rgfl[0] = x, rgfl[1] = y, rgfl[2] = z; } - inline float Length(void) const { return (float)sqrt(x*x + y*y + z*z); } - operator float *() { return &x; } // Vectors will now automatically convert to float * when needed - operator const float *() const { return &x; } // Vectors will now automatically convert to float * when needed - inline Vector Normalize(void) const - { - float flLen = Length(); - if (flLen == 0) return Vector(0,0,1); // ???? - flLen = 1 / flLen; - return Vector(x * flLen, y * flLen, z * flLen); - } - - inline Vector2D Make2D ( void ) const - { - Vector2D Vec2; - - Vec2.x = x; - Vec2.y = y; - - return Vec2; - } - inline float Length2D(void) const { return (float)sqrt(x*x + y*y); } - - // Members - vec_t x, y, z; -}; -inline Vector operator*(float fl, const Vector& v) { return v * fl; } -inline float DotProduct(const Vector& a, const Vector& b) { return(a.x*b.x+a.y*b.y+a.z*b.z); } -inline Vector CrossProduct(const Vector& a, const Vector& b) { return Vector( a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x ); } - -#define vec3_t Vector diff --git a/ricochet/cl_dll/vgui_ConsolePanel.cpp b/ricochet/cl_dll/vgui_ConsolePanel.cpp deleted file mode 100644 index 172ec1f..0000000 --- a/ricochet/cl_dll/vgui_ConsolePanel.cpp +++ /dev/null @@ -1,95 +0,0 @@ - -#include"vgui_ConsolePanel.h" -#include"hud.h" -#include -#include -#include -#include -#include - -using namespace vgui; - - -namespace -{ - -class Handler : public ActionSignal -{ -private: - - ConsolePanel* _consolePanel; - -public: - - Handler(ConsolePanel* consolePanel) - { - _consolePanel=consolePanel; - } - -public: - - virtual void actionPerformed(Panel* panel) - { - _consolePanel->doExecCommand(); - } - -}; - -} - - - -ConsolePanel::ConsolePanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall) -{ - setBorder(new EtchedBorder()); - - _textGrid=new TextGrid(80,21,5,5,200,100); - _textGrid->setBorder(new LoweredBorder()); - _textGrid->setParent(this); - - _textEntry=new TextEntry("",5,5,200,20); - _textEntry->setParent(this); - _textEntry->addActionSignal(new Handler(this)); -} - -int ConsolePanel::print(const char* text) -{ - return _textGrid->printf("%s",text); -} - -int ConsolePanel::vprintf(const char* format,va_list argList) -{ - return _textGrid->vprintf(format,argList); -} - -int ConsolePanel::printf(const char* format,...) -{ - va_list argList; - va_start(argList,format); - int ret=vprintf(format,argList); - va_end(argList); - return ret; -} - -void ConsolePanel::doExecCommand() -{ - char buf[2048]; - _textEntry->getText(0,buf,2048); - _textEntry->setText(null,0); - gEngfuncs.pfnClientCmd(buf); -} - -void ConsolePanel::setSize(int wide,int tall) -{ - Panel::setSize(wide,tall); - - getPaintSize(wide,tall); - - _textGrid->setBounds(5,5,wide-10,tall-35); - _textEntry->setBounds(5,tall-25,wide-10,20); -} - - - - - diff --git a/ricochet/cl_dll/vgui_ConsolePanel.h b/ricochet/cl_dll/vgui_ConsolePanel.h deleted file mode 100644 index 7e545e7..0000000 --- a/ricochet/cl_dll/vgui_ConsolePanel.h +++ /dev/null @@ -1,32 +0,0 @@ - -#ifndef CONSOLEPANEL_H -#define CONSOLEPANEL_H - -#include -#include - -namespace vgui -{ -class TextGrid; -class TextEntry; -} - - -class ConsolePanel : public vgui::Panel -{ -private: - vgui::TextGrid* _textGrid; - vgui::TextEntry* _textEntry; -public: - ConsolePanel(int x,int y,int wide,int tall); -public: - virtual void setSize(int wide,int tall); - virtual int print(const char* text); - virtual int vprintf(const char* format,va_list argList); - virtual int printf(const char* format,...); - virtual void doExecCommand(); -}; - - - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/vgui_ControlConfigPanel.cpp b/ricochet/cl_dll/vgui_ControlConfigPanel.cpp deleted file mode 100644 index 4c53f5c..0000000 --- a/ricochet/cl_dll/vgui_ControlConfigPanel.cpp +++ /dev/null @@ -1,206 +0,0 @@ - -#include -#include"vgui_ControlConfigPanel.h" -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace vgui; - -namespace -{ -class FooTablePanel : public TablePanel -{ -private: - Label* _label; - TextEntry* _textEntry; - ControlConfigPanel* _controlConfigPanel; -public: - FooTablePanel(ControlConfigPanel* controlConfigPanel,int x,int y,int wide,int tall,int columnCount) : TablePanel(x,y,wide,tall,columnCount) - { - _controlConfigPanel=controlConfigPanel; - _label=new Label("You are a dumb monkey",0,0,100,20); - _label->setBgColor(Scheme::sc_primary3); - _label->setFgColor(Scheme::sc_primary1); - _label->setFont(Scheme::sf_primary3); - - _textEntry=new TextEntry("",0,0,100,20); - //_textEntry->setFont(Scheme::sf_primary3); - } -public: - virtual int getRowCount() - { - return _controlConfigPanel->GetCVarCount(); - } - virtual int getCellTall(int row) - { - return 12; - } - virtual Panel* getCellRenderer(int column,int row,bool columnSelected,bool rowSelected,bool cellSelected) - { - char cvar[128],desc[128],bind[128],bindAlt[128]; - _controlConfigPanel->GetCVar(row,cvar,128,desc,128); - - if(cellSelected) - { - _label->setBgColor(Scheme::sc_primary1); - _label->setFgColor(Scheme::sc_primary3); - } - else - if(rowSelected) - { - _label->setBgColor(Scheme::sc_primary2); - _label->setFgColor(Scheme::sc_primary1); - } - else - { - _label->setBgColor(Scheme::sc_primary3); - _label->setFgColor(Scheme::sc_primary1); - } - - switch(column) - { - case 0: - { - _label->setText(desc); - _label->setContentAlignment(Label::a_west); - break; - } - case 1: - { - _controlConfigPanel->GetCVarBind(cvar,bind,128,bindAlt,128); - _label->setText(bind); - _label->setContentAlignment(Label::a_center); - break; - } - case 2: - { - _controlConfigPanel->GetCVarBind(cvar,bind,128,bindAlt,128); - _label->setText(bindAlt); - _label->setContentAlignment(Label::a_center); - break; - } - default: - { - _label->setText(""); - break; - } - } - - return _label; - } - virtual Panel* startCellEditing(int column,int row) - { - _textEntry->setText("Goat",strlen("Goat")); - _textEntry->requestFocus(); - return _textEntry; - } -}; -} - -ControlConfigPanel::ControlConfigPanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall) -{ - setPaintBorderEnabled(false); - setPaintBackgroundEnabled(false); - setPaintEnabled(false); - - _actionLabel=new Label("Action"); - _actionLabel->setBgColor(Scheme::sc_primary3); - _actionLabel->setFgColor(Scheme::sc_primary3); - - _keyButtonLabel=new Label("Key / Button"); - _keyButtonLabel->setBgColor(Scheme::sc_primary3); - _keyButtonLabel->setFgColor(Scheme::sc_primary3); - - _alternateLabel=new Label("Alternate"); - _alternateLabel->setBgColor(Scheme::sc_primary3); - _alternateLabel->setFgColor(Scheme::sc_primary3); - - _headerPanel=new HeaderPanel(0,0,wide,20); - _headerPanel->setParent(this); - - _headerPanel->addSectionPanel(_actionLabel); - _headerPanel->addSectionPanel(_keyButtonLabel); - _headerPanel->addSectionPanel(_alternateLabel); - - _headerPanel->setSliderPos( 0, wide/2 ); - _headerPanel->setSliderPos( 1, (wide/2) + (wide/4) ); - _headerPanel->setSliderPos( 2, wide ); - - _scrollPanel=new ScrollPanel(0,20,wide,tall-20); - _scrollPanel->setParent(this); - _scrollPanel->setPaintBorderEnabled(false); - _scrollPanel->setPaintBackgroundEnabled(false); - _scrollPanel->setPaintEnabled(false); - _scrollPanel->getClient()->setPaintBorderEnabled(false); - _scrollPanel->getClient()->setPaintBackgroundEnabled(false); - _scrollPanel->getClient()->setPaintEnabled(false); - _scrollPanel->setScrollBarVisible(false,true); - - _tablePanel=new FooTablePanel(this,0,0,_scrollPanel->getClient()->getWide(),800, 3); - _tablePanel->setParent(_scrollPanel->getClient()); - _tablePanel->setHeaderPanel(_headerPanel); - _tablePanel->setBgColor(Color(200,0,0,255)); - _tablePanel->setFgColor(Color(Scheme::sc_primary2)); - _tablePanel->setGridVisible(true,true); - _tablePanel->setGridSize(1,1); -} - -void ControlConfigPanel::AddCVar(const char* cvar,const char* desc) -{ - _cvarDar.addElement(vgui_strdup(cvar)); - _descDar.addElement(vgui_strdup(desc)); -} - -int ControlConfigPanel::GetCVarCount() -{ - return _cvarDar.getCount(); -} - -void ControlConfigPanel::GetCVar(int index,char* cvar,int cvarLen,char* desc,int descLen) -{ - vgui_strcpy(cvar,cvarLen,_cvarDar[index]); - vgui_strcpy(desc,descLen,_descDar[index]); -} - -void ControlConfigPanel::AddCVarFromInputStream(InputStream* is) -{ - if(is==null) - { - return; - } - - DataInputStream dis(is); - - bool success; - - while(1) - { - char buf[256],cvar[128],desc[128]; - dis.readLine(buf,256,success); - if(!success) - { - break; - } - if(sscanf(buf,"\"%[^\"]\" \"%[^\"]\"",cvar,desc)==2) - { - AddCVar(cvar,desc); - } - } -} - -void ControlConfigPanel::GetCVarBind(const char* cvar,char* bind,int bindLen,char* bindAlt,int bindAltLen) -{ - sprintf(bind,"%s : Bind",cvar); - sprintf(bindAlt,"%s : BindAlt",cvar); -} - -void ControlConfigPanel::SetCVarBind(const char* cvar,const char* bind,const char* bindAlt) -{ -} - diff --git a/ricochet/cl_dll/vgui_ControlConfigPanel.h b/ricochet/cl_dll/vgui_ControlConfigPanel.h deleted file mode 100644 index 1c362c4..0000000 --- a/ricochet/cl_dll/vgui_ControlConfigPanel.h +++ /dev/null @@ -1,41 +0,0 @@ - -#ifndef CONTROLCONFIGPANEL_H -#define CONTROLCONFIGPANEL_H - -#include -#include - -namespace vgui -{ -class HeaderPanel; -class TablePanel; -class ScrollPanel; -class InputStream; -class Label; -} - -class ControlConfigPanel : public vgui::Panel -{ -private: - vgui::HeaderPanel* _headerPanel; - vgui::TablePanel* _tablePanel; - vgui::ScrollPanel* _scrollPanel; - vgui::Dar _cvarDar; - vgui::Dar _descDar; - vgui::Label* _actionLabel; - vgui::Label* _keyButtonLabel; - vgui::Label* _alternateLabel; -public: - ControlConfigPanel(int x,int y,int wide,int tall); -public: - void AddCVar(const char* cvar,const char* desc); - void AddCVarFromInputStream(vgui::InputStream* is); - int GetCVarCount(); - void GetCVar(int index,char* cvar,int cvarLen,char* desc,int descLen); - void GetCVarBind(const char* cvar,char* bind,int bindLen,char* bindAlt,int bindAltLen); - void SetCVarBind(const char* cvar,const char* bind,const char* bindAlt); -}; - - - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/vgui_CustomObjects.cpp b/ricochet/cl_dll/vgui_CustomObjects.cpp deleted file mode 100644 index 9e9c730..0000000 --- a/ricochet/cl_dll/vgui_CustomObjects.cpp +++ /dev/null @@ -1,501 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Contains implementation of various VGUI-derived objects -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "VGUI_Font.h" - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "parsemsg.h" - -#include "vgui_int.h" -#include "vgui_TeamFortressViewport.h" -#include "vgui_ServerBrowser.h" -#include "vgui_loadtga.h" - -// Arrow filenames -char *sArrowFilenames[] = -{ - "arrowup", - "arrowdn", - "arrowlt", - "arrowrt", -}; - -// Get the name of TGA file, without a gamedir -char *GetTGANameForRes(const char *pszName) -{ - int i; - char sz[256]; - static char gd[256]; - if (ScreenWidth < 640) - i = 320; - else - i = 640; - sprintf(sz, pszName, i); - sprintf(gd, "gfx/vgui/%s.tga", sz); - return gd; -} - -//----------------------------------------------------------------------------- -// Purpose: Loads a .tga file and returns a pointer to the VGUI tga object -//----------------------------------------------------------------------------- -BitmapTGA *LoadTGAForRes( const char* pImageName ) -{ - BitmapTGA *pTGA; - - char sz[256]; - sprintf(sz, "%%d_%s", pImageName); - pTGA = vgui_LoadTGA(GetTGANameForRes(sz)); - - return pTGA; -} - -//=========================================================== -// All TFC Hud buttons are derived from this one. -CommandButton::CommandButton( const char* text,int x,int y,int wide,int tall, bool bNoHighlight) : Button("",x,y,wide,tall) -{ - m_iPlayerClass = 0; - m_bNoHighlight = bNoHighlight; - Init(); - setText( text ); -} - -CommandButton::CommandButton( int iPlayerClass, const char* text,int x,int y,int wide,int tall) : Button("",x,y,wide,tall) -{ - m_iPlayerClass = iPlayerClass; - m_bNoHighlight = false; - Init(); - setText( text ); -} - -void CommandButton::Init( void ) -{ - m_pSubMenu = NULL; - m_pSubLabel = NULL; - m_pParentMenu = NULL; - - // Set text color to orange - setFgColor(Scheme::sc_primary1); - - // left align - setContentAlignment( vgui::Label::a_west ); - - // Add the Highlight signal - if (!m_bNoHighlight) - addInputSignal( new CHandler_CommandButtonHighlight(this) ); - - // not bound to any button yet - m_cBoundKey = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: Prepends the button text with the current bound key -// if no bound key, then a clear space ' ' instead -//----------------------------------------------------------------------------- -void CommandButton::RecalculateText( void ) -{ - char szBuf[128]; - - if ( m_cBoundKey != 0 ) - { - sprintf( szBuf, " %c %s", m_cBoundKey, m_sMainText ); - szBuf[MAX_BUTTON_SIZE-1] = 0; - } - else - { - // just draw a space if no key bound - sprintf( szBuf, " %s", m_sMainText ); - szBuf[MAX_BUTTON_SIZE-1] = 0; - } - - Button::setText( szBuf ); -} - -void CommandButton::setText( const char *text ) -{ - strncpy( m_sMainText, text, MAX_BUTTON_SIZE ); - m_sMainText[MAX_BUTTON_SIZE-1] = 0; - - RecalculateText(); -} - -void CommandButton::setBoundKey( char boundKey ) -{ - m_cBoundKey = boundKey; - RecalculateText(); -} - -char CommandButton::getBoundKey( void ) -{ - return m_cBoundKey; -} - -void CommandButton::AddSubMenu( CCommandMenu *pNewMenu ) -{ - m_pSubMenu = pNewMenu; - - // Prevent this button from being pushed - setMouseClickEnabled( MOUSE_LEFT, false ); -} - -void CommandButton::UpdateSubMenus( int iAdjustment ) -{ - if ( m_pSubMenu ) - m_pSubMenu->RecalculatePositions( iAdjustment ); -} - -void CommandButton::paint() -{ - // Make the sub label paint the same as the button - if ( m_pSubLabel ) - { - if ( isSelected() ) - m_pSubLabel->PushDown(); - else - m_pSubLabel->PushUp(); - } - - // draw armed button text in white - if ( isArmed() ) - { - setFgColor( Scheme::sc_secondary2 ); - } - else - { - setFgColor( Scheme::sc_primary1 ); - } - - Button::paint(); -} - -void CommandButton::paintBackground() -{ - if ( isArmed() ) - { - // Orange highlight background - drawSetColor( Scheme::sc_primary2 ); - drawFilledRect(0,0,_size[0],_size[1]); - } - - // Orange Border - drawSetColor( Scheme::sc_secondary1 ); - drawOutlinedRect(0,0,_size[0],_size[1]); -} - -//----------------------------------------------------------------------------- -// Purpose: Highlights the current button, and all it's parent menus -//----------------------------------------------------------------------------- -void CommandButton::cursorEntered( void ) -{ - // unarm all the other buttons in this menu - CCommandMenu *containingMenu = getParentMenu(); - if ( containingMenu ) - { - containingMenu->ClearButtonsOfArmedState(); - - // make all our higher buttons armed - CCommandMenu *pCParent = containingMenu->GetParentMenu(); - if ( pCParent ) - { - CommandButton *pParentButton = pCParent->FindButtonWithSubmenu( containingMenu ); - - pParentButton->cursorEntered(); - } - } - - // arm ourselves - setArmed( true ); -} - -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -void CommandButton::cursorExited( void ) -{ - // only clear ourselves if we have do not have a containing menu - // only stay armed if we have a sub menu - // the buttons only unarm themselves when another button is armed instead - if ( !getParentMenu() || !GetSubMenu() ) - { - setArmed( false ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Returns the command menu that the button is part of, if any -// Output : CCommandMenu * -//----------------------------------------------------------------------------- -CCommandMenu *CommandButton::getParentMenu( void ) -{ - return m_pParentMenu; -} - -//----------------------------------------------------------------------------- -// Purpose: Sets the menu that contains this button -// Input : *pParentMenu - -//----------------------------------------------------------------------------- -void CommandButton::setParentMenu( CCommandMenu *pParentMenu ) -{ - m_pParentMenu = pParentMenu; -} - - -//=========================================================== -int ClassButton::IsNotValid() -{ - // If this is the main ChangeClass button, remove it if the player's only able to be civilians - if ( m_iPlayerClass == -1 ) - { - if (gViewPort->GetValidClasses(g_iTeamNumber) == -1) - return true; - - return false; - } - - // Is it an illegal class? - if ((gViewPort->GetValidClasses(0) & sTFValidClassInts[ m_iPlayerClass ]) || (gViewPort->GetValidClasses(g_iTeamNumber) & sTFValidClassInts[ m_iPlayerClass ])) - return true; - - // Only check current class if they've got autokill on - bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0; - if ( bAutoKill ) - { - // Is it the player's current class? - if ( (gViewPort->IsRandomPC() && m_iPlayerClass == PC_RANDOM) || (!gViewPort->IsRandomPC() && (m_iPlayerClass == g_iPlayerClass)) ) - return true; - } - - return false; -} - -//=========================================================== -// Button with Class image beneath it -CImageLabel::CImageLabel( const char* pImageName,int x,int y ) : Label( "", x,y ) -{ - setContentFitted(true); - m_pTGA = LoadTGAForRes(pImageName); - setImage( m_pTGA ); -} - -CImageLabel::CImageLabel( const char* pImageName,int x,int y,int wide,int tall ) : Label( "", x,y,wide,tall ) -{ - setContentFitted(true); - m_pTGA = LoadTGAForRes(pImageName); - setImage( m_pTGA ); -} - -//=========================================================== -// Image size -int CImageLabel::getImageWide( void ) -{ - if( m_pTGA ) - { - int iXSize, iYSize; - m_pTGA->getSize( iXSize, iYSize ); - return iXSize; - } - else - { - return 1; - } -} - -int CImageLabel::getImageTall( void ) -{ - if( m_pTGA ) - { - int iXSize, iYSize; - m_pTGA->getSize( iXSize, iYSize ); - return iYSize; - } - else - { - return 1; - } -} - -void CImageLabel::LoadImage(const char * pImageName) -{ - if ( m_pTGA ) - delete m_pTGA; - - // Load the Image - m_pTGA = LoadTGAForRes(pImageName); - - if ( m_pTGA == NULL ) - { - // we didn't find a matching image file for this resolution - // try to load file resolution independent - - char sz[256]; - sprintf(sz, "%s/%s",gEngfuncs.pfnGetGameDirectory(), pImageName ); - FileInputStream* fis = new FileInputStream( sz, false ); - m_pTGA = new BitmapTGA(fis,true); - fis->close(); - } - - if ( m_pTGA == NULL ) - return; // unable to load image - - int w,t; - - m_pTGA->getSize( w, t ); - - setSize( XRES (w),YRES (t) ); - setImage( m_pTGA ); -} - -//=========================================================== -// Various overloaded paint functions for Custom VGUI objects -void CCommandMenu::paintBackground() -{ - // Transparent black background - drawSetColor(Scheme::sc_primary3); - drawFilledRect(0,0,_size[0],_size[1]); -} - -//================================================================================= -// CUSTOM SCROLLPANEL -//================================================================================= -CTFScrollButton::CTFScrollButton(int iArrow, const char* text,int x,int y,int wide,int tall) : CommandButton(text,x,y,wide,tall) -{ - // Set text color to orange - setFgColor(Scheme::sc_primary1); - - // Load in the arrow - m_pTGA = LoadTGAForRes( sArrowFilenames[iArrow] ); - setImage( m_pTGA ); - - // Highlight signal - InputSignal *pISignal = new CHandler_CommandButtonHighlight(this); - addInputSignal(pISignal); -} - -void CTFScrollButton::paint( void ) -{ - if (!m_pTGA) - return; - // draw armed button text in white - if ( isArmed() ) - { - m_pTGA->setColor( Color(255,255,255, 0) ); - } - else - { - m_pTGA->setColor( Color(255,255,255, 128) ); - } - - m_pTGA->doPaint(this); -} - -void CTFScrollButton::paintBackground( void ) -{ -/* - if ( isArmed() ) - { - // Orange highlight background - drawSetColor( Scheme::sc_primary2 ); - drawFilledRect(0,0,_size[0],_size[1]); - } - - // Orange Border - drawSetColor( Scheme::sc_secondary1 ); - drawOutlinedRect(0,0,_size[0]-1,_size[1]); -*/ -} - -void CTFSlider::paintBackground( void ) -{ - int wide,tall,nobx,noby; - getPaintSize(wide,tall); - getNobPos(nobx,noby); - - // Border - drawSetColor( Scheme::sc_secondary1 ); - drawOutlinedRect( 0,0,wide,tall ); - - if( isVertical() ) - { - // Nob Fill - drawSetColor( Scheme::sc_primary2 ); - drawFilledRect( 0,nobx,wide,noby ); - - // Nob Outline - drawSetColor( Scheme::sc_primary1 ); - drawOutlinedRect( 0,nobx,wide,noby ); - } - else - { - // Nob Fill - drawSetColor( Scheme::sc_primary2 ); - drawFilledRect( nobx,0,noby,tall ); - - // Nob Outline - drawSetColor( Scheme::sc_primary1 ); - drawOutlinedRect( nobx,0,noby,tall ); - } -} - -CTFScrollPanel::CTFScrollPanel(int x,int y,int wide,int tall) : ScrollPanel(x,y,wide,tall) -{ - ScrollBar *pScrollBar = getVerticalScrollBar(); - pScrollBar->setButton( new CTFScrollButton( ARROW_UP, "", 0,0,16,16 ), 0 ); - pScrollBar->setButton( new CTFScrollButton( ARROW_DOWN, "", 0,0,16,16 ), 1 ); - pScrollBar->setSlider( new CTFSlider(0,wide-1,wide,(tall-(wide*2))+2,true) ); - pScrollBar->setPaintBorderEnabled(false); - pScrollBar->setPaintBackgroundEnabled(false); - pScrollBar->setPaintEnabled(false); - - pScrollBar = getHorizontalScrollBar(); - pScrollBar->setButton( new CTFScrollButton( ARROW_LEFT, "", 0,0,16,16 ), 0 ); - pScrollBar->setButton( new CTFScrollButton( ARROW_RIGHT, "", 0,0,16,16 ), 1 ); - pScrollBar->setSlider( new CTFSlider(tall,0,wide-(tall*2),tall,false) ); - pScrollBar->setPaintBorderEnabled(false); - pScrollBar->setPaintBackgroundEnabled(false); - pScrollBar->setPaintEnabled(false); -} - - -//================================================================================= -// CUSTOM HANDLERS -//================================================================================= -void CHandler_MenuButtonOver::cursorEntered(Panel *panel) -{ - if ( gViewPort && m_pMenuPanel ) - { - m_pMenuPanel->SetActiveInfo( m_iButton ); - } -} - -void CMenuHandler_StringCommandClassSelect::actionPerformed(Panel* panel) -{ - CMenuHandler_StringCommand::actionPerformed( panel ); - - bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0; - if ( bAutoKill && g_iPlayerClass != 0 ) - gEngfuncs.pfnClientCmd("kill"); -} - - diff --git a/ricochet/cl_dll/vgui_MOTDWindow.cpp b/ricochet/cl_dll/vgui_MOTDWindow.cpp deleted file mode 100644 index ae2f026..0000000 --- a/ricochet/cl_dll/vgui_MOTDWindow.cpp +++ /dev/null @@ -1,154 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "VGUI_Font.h" -#include "VGUI_ScrollPanel.h" -#include "VGUI_TextImage.h" - -#include - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "const.h" - -#include "vgui_int.h" -#include "vgui_TeamFortressViewport.h" -#include "vgui_ServerBrowser.h" - -#define MOTD_TITLE_X XRES(16) -#define MOTD_TITLE_Y YRES(16) - -#define MOTD_WINDOW_X XRES(112) -#define MOTD_WINDOW_Y YRES(80) -#define MOTD_WINDOW_SIZE_X XRES(424) -#define MOTD_WINDOW_SIZE_Y YRES(312) - -//----------------------------------------------------------------------------- -// Purpose: Displays the MOTD and basic server information -//----------------------------------------------------------------------------- -class CMessageWindowPanel : public CMenuPanel -{ -public: - CMessageWindowPanel( const char *szMOTD, const char *szTitle, int iShadeFullScreen, int iRemoveMe, int x, int y, int wide, int tall ); - -private: - CTransparentPanel *m_pBackgroundPanel; - -}; - -//----------------------------------------------------------------------------- -// Purpose: Creates a new CMessageWindowPanel -// Output : CMenuPanel - interface to the panel -//----------------------------------------------------------------------------- -CMenuPanel *CMessageWindowPanel_Create( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall ) -{ - return new CMessageWindowPanel( szMOTD, szTitle, iShadeFullscreen, iRemoveMe, x, y, wide, tall ); -} - -//----------------------------------------------------------------------------- -// Purpose: Constructs a message panel -//----------------------------------------------------------------------------- -CMessageWindowPanel::CMessageWindowPanel( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall ) : CMenuPanel( iShadeFullscreen ? 100 : 255, iRemoveMe, x, y, wide, tall ) -{ - // Get the scheme used for the Titles - CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); - - // schemes - SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" ); - SchemeHandle_t hMOTDText = pSchemes->getSchemeHandle( "Briefing Text" ); - - // color schemes - int r, g, b, a; - - // Create the window - m_pBackgroundPanel = new CTransparentPanel( iShadeFullscreen ? 255 : 100, MOTD_WINDOW_X, MOTD_WINDOW_Y, MOTD_WINDOW_SIZE_X, MOTD_WINDOW_SIZE_Y ); - m_pBackgroundPanel->setParent( this ); - m_pBackgroundPanel->setBorder( new LineBorder( Color(255 * 0.7,170 * 0.7,0,0)) ); - m_pBackgroundPanel->setVisible( true ); - - int iXSize,iYSize,iXPos,iYPos; - m_pBackgroundPanel->getPos( iXPos,iYPos ); - m_pBackgroundPanel->getSize( iXSize,iYSize ); - - // Create the title - Label *pLabel = new Label( "", iXPos + MOTD_TITLE_X, iYPos + MOTD_TITLE_Y ); - pLabel->setParent( this ); - pLabel->setFont( pSchemes->getFont(hTitleScheme) ); - pLabel->setFont( Scheme::sf_primary1 ); - - pSchemes->getFgColor( hTitleScheme, r, g, b, a ); - pLabel->setFgColor( r, g, b, a ); - pLabel->setFgColor( Scheme::sc_primary1 ); - pSchemes->getBgColor( hTitleScheme, r, g, b, a ); - pLabel->setBgColor( r, g, b, a ); - pLabel->setContentAlignment( vgui::Label::a_west ); - pLabel->setText(szTitle); - - // Create the Scroll panel - ScrollPanel *pScrollPanel = new CTFScrollPanel( iXPos + XRES(16), iYPos + MOTD_TITLE_Y*2 + YRES(16), iXSize - XRES(32), iYSize - (YRES(48) + BUTTON_SIZE_Y*2) ); - pScrollPanel->setParent(this); - - //force the scrollbars on so clientClip will take them in account after the validate - pScrollPanel->setScrollBarAutoVisible(false, false); - pScrollPanel->setScrollBarVisible(true, true); - pScrollPanel->validate(); - - // Create the text panel - TextPanel *pText = new TextPanel( "", 0,0, 64,64); - pText->setParent( pScrollPanel->getClient() ); - - // get the font and colors from the scheme - pText->setFont( pSchemes->getFont(hMOTDText) ); - pSchemes->getFgColor( hMOTDText, r, g, b, a ); - pText->setFgColor( r, g, b, a ); - pSchemes->getBgColor( hMOTDText, r, g, b, a ); - pText->setBgColor( r, g, b, a ); - pText->setText(szMOTD); - - // Get the total size of the MOTD text and resize the text panel - int iScrollSizeX, iScrollSizeY; - - // First, set the size so that the client's wdith is correct at least because the - // width is critical for getting the "wrapped" size right. - // You'll see a horizontal scroll bar if there is a single word that won't wrap in the - // specified width. - pText->getTextImage()->setSize(pScrollPanel->getClientClip()->getWide(), pScrollPanel->getClientClip()->getTall()); - pText->getTextImage()->getTextSizeWrapped( iScrollSizeX, iScrollSizeY ); - - // Now resize the textpanel to fit the scrolled size - pText->setSize( iScrollSizeX , iScrollSizeY ); - - //turn the scrollbars back into automode - pScrollPanel->setScrollBarAutoVisible(true, true); - pScrollPanel->setScrollBarVisible(false, false); - - pScrollPanel->validate(); - - CommandButton *pButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_OK" ), iXPos + XRES(16), iYPos + iYSize - YRES(16) - BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_TextWindow(HIDE_TEXTWINDOW)); - pButton->setParent(this); - -} - - - - - - diff --git a/ricochet/cl_dll/vgui_SchemeManager.cpp b/ricochet/cl_dll/vgui_SchemeManager.cpp deleted file mode 100644 index c61d1f7..0000000 --- a/ricochet/cl_dll/vgui_SchemeManager.cpp +++ /dev/null @@ -1,556 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "hud.h" -#include "vgui_SchemeManager.h" -#include "cvardef.h" - -#include - - -cvar_t *g_CV_BitmapFonts; - - -void Scheme_Init() -{ - g_CV_BitmapFonts = gEngfuncs.pfnRegisterVariable("bitmapfonts", "1", 0); -} - - - -//----------------------------------------------------------------------------- -// Purpose: Scheme managers data container -//----------------------------------------------------------------------------- -class CSchemeManager::CScheme -{ -public: - enum { - SCHEME_NAME_LENGTH = 32, - FONT_NAME_LENGTH = 48, - FONT_FILENAME_LENGTH = 64, - }; - - // name - char schemeName[SCHEME_NAME_LENGTH]; - - // font - char fontName[FONT_NAME_LENGTH]; - - int fontSize; - int fontWeight; - - vgui::Font *font; - int ownFontPointer; // true if the font is ours to delete - - // scheme - byte fgColor[4]; - byte bgColor[4]; - byte armedFgColor[4]; - byte armedBgColor[4]; - byte mousedownFgColor[4]; - byte mousedownBgColor[4]; - byte borderColor[4]; - - // construction/destruction - CScheme(); - ~CScheme(); -}; - -CSchemeManager::CScheme::CScheme() -{ - schemeName[0] = 0; - fontName[0] = 0; - fontSize = 0; - fontWeight = 0; - font = NULL; - ownFontPointer = false; -} - -CSchemeManager::CScheme::~CScheme() -{ - // only delete our font pointer if we own it - if ( ownFontPointer ) - { - delete font; - } -} - -//----------------------------------------------------------------------------- -// Purpose: resolution information -// !! needs to be shared out -//----------------------------------------------------------------------------- -static int g_ResArray[] = -{ - 320, - 400, - 512, - 640, - 800, - 1024, - 1152, - 1280, - 1600 -}; -static int g_NumReses = sizeof(g_ResArray) / sizeof(int); - -static byte *LoadFileByResolution( const char *filePrefix, int xRes, const char *filePostfix ) -{ - // find our resolution in the res array - int resNum = g_NumReses - 1; - while ( g_ResArray[resNum] > xRes ) - { - resNum--; - - if ( resNum < 0 ) - return NULL; - } - - // try open the file - byte *pFile = NULL; - while ( 1 ) - { - - // try load - char fname[256]; - sprintf( fname, "%s%d%s", filePrefix, g_ResArray[resNum], filePostfix ); - pFile = gEngfuncs.COM_LoadFile( fname, 5, NULL ); - - if ( pFile ) - break; - - if ( resNum == 0 ) - return NULL; - - resNum--; - }; - - return pFile; -} - -static void ParseRGBAFromString( byte colorArray[4], const char *colorVector ) -{ - int r, g, b, a; - sscanf( colorVector, "%d %d %d %d", &r, &g, &b, &a ); - colorArray[0] = r; - colorArray[1] = g; - colorArray[2] = b; - colorArray[3] = a; -} - -//----------------------------------------------------------------------------- -// Purpose: initializes the scheme manager -// loading the scheme files for the current resolution -// Input : xRes - -// yRes - dimensions of output window -//----------------------------------------------------------------------------- -CSchemeManager::CSchemeManager( int xRes, int yRes ) -{ - // basic setup - m_pSchemeList = NULL; - m_iNumSchemes = 0; - - // find the closest matching scheme file to our resolution - char token[1024]; - char *pFile = (char*)LoadFileByResolution( "", xRes, "_textscheme.txt" ); - m_xRes = xRes; - - char *pFileStart = pFile; - - byte *pFontData; - int fontFileLength; - char fontFilename[512]; - - // - // Read the scheme descriptions from the text file, into a temporary array - // format is simply: - // = - // - // a of "SchemeName" signals a new scheme is being described - // - - const static int numTmpSchemes = 64; - static CScheme tmpSchemes[numTmpSchemes]; - memset( tmpSchemes, 0, sizeof(tmpSchemes) ); - int currentScheme = -1; - CScheme *pScheme = NULL; - - if ( !pFile ) - { - gEngfuncs.Con_DPrintf( "Unable to find *_textscheme.txt\n"); - goto buildDefaultFont; - } - - // record what has been entered so we can create defaults from the different values - bool hasFgColor, hasBgColor, hasArmedFgColor, hasArmedBgColor, hasMouseDownFgColor, hasMouseDownBgColor; - - pFile = gEngfuncs.COM_ParseFile( pFile, token ); - while ( strlen(token) > 0 && (currentScheme < numTmpSchemes) ) - { - // get the paramName name - static const int tokenSize = 64; - char paramName[tokenSize], paramValue[tokenSize]; - - strncpy( paramName, token, tokenSize ); - paramName[tokenSize-1] = 0; // ensure null termination - - // get the '=' character - pFile = gEngfuncs.COM_ParseFile( pFile, token ); - if ( stricmp( token, "=" ) ) - { - if ( currentScheme < 0 ) - { - gEngfuncs.Con_Printf( "error parsing font scheme text file at file start - expected '=', found '%s''\n", token ); - } - else - { - gEngfuncs.Con_Printf( "error parsing font scheme text file at scheme '%s' - expected '=', found '%s''\n", tmpSchemes[currentScheme].schemeName, token ); - } - break; - } - - // get paramValue - pFile = gEngfuncs.COM_ParseFile( pFile, token ); - strncpy( paramValue, token, tokenSize ); - paramValue[tokenSize-1] = 0; // ensure null termination - - // is this a new scheme? - if ( !stricmp(paramName, "SchemeName") ) - { - // setup the defaults for the current scheme - if ( pScheme ) - { - // foreground color defaults (normal -> armed -> mouse down) - if ( !hasFgColor ) - { - pScheme->fgColor[0] = pScheme->fgColor[1] = pScheme->fgColor[2] = pScheme->fgColor[3] = 255; - } - if ( !hasArmedFgColor ) - { - memcpy( pScheme->armedFgColor, pScheme->fgColor, sizeof(pScheme->armedFgColor) ); - } - if ( !hasMouseDownFgColor ) - { - memcpy( pScheme->mousedownFgColor, pScheme->armedFgColor, sizeof(pScheme->mousedownFgColor) ); - } - - // background color (normal -> armed -> mouse down) - if ( !hasBgColor ) - { - pScheme->bgColor[0] = pScheme->bgColor[1] = pScheme->bgColor[2] = pScheme->bgColor[3] = 0; - } - if ( !hasArmedBgColor ) - { - memcpy( pScheme->armedBgColor, pScheme->bgColor, sizeof(pScheme->armedBgColor) ); - } - if ( !hasMouseDownBgColor ) - { - memcpy( pScheme->mousedownBgColor, pScheme->armedBgColor, sizeof(pScheme->mousedownBgColor) ); - } - - // font size - if ( !pScheme->fontSize ) - { - pScheme->fontSize = 17; - } - if ( !pScheme->fontName[0] ) - { - strcpy( pScheme->fontName, "Arial" ); - } - } - - // create the new scheme - currentScheme++; - pScheme = &tmpSchemes[currentScheme]; - hasFgColor = hasBgColor = hasArmedFgColor = hasArmedBgColor = hasMouseDownFgColor = hasMouseDownBgColor = false; - - strncpy( pScheme->schemeName, paramValue, CScheme::SCHEME_NAME_LENGTH ); - pScheme->schemeName[CScheme::SCHEME_NAME_LENGTH-1] = '\0'; // ensure null termination of string - } - - if ( !pScheme ) - { - gEngfuncs.Con_Printf( "font scheme text file MUST start with a 'SchemeName'\n"); - break; - } - - // pull the data out into the scheme - if ( !stricmp(paramName, "FontName") ) - { - strncpy( pScheme->fontName, paramValue, CScheme::FONT_NAME_LENGTH ); - pScheme->fontName[CScheme::FONT_NAME_LENGTH-1] = 0; - } - else if ( !stricmp(paramName, "FontSize") ) - { - pScheme->fontSize = atoi( paramValue ); - } - else if ( !stricmp(paramName, "FontWeight") ) - { - pScheme->fontWeight = atoi( paramValue ); - } - else if ( !stricmp(paramName, "FgColor") ) - { - ParseRGBAFromString( pScheme->fgColor, paramValue ); - hasFgColor = true; - } - else if ( !stricmp(paramName, "BgColor") ) - { - ParseRGBAFromString( pScheme->bgColor, paramValue ); - hasBgColor = true; - } - else if ( !stricmp(paramName, "FgColorArmed") ) - { - ParseRGBAFromString( pScheme->armedFgColor, paramValue ); - hasArmedFgColor = true; - } - else if ( !stricmp(paramName, "BgColorArmed") ) - { - ParseRGBAFromString( pScheme->armedBgColor, paramValue ); - hasArmedBgColor = true; - } - else if ( !stricmp(paramName, "FgColorMousedown") ) - { - ParseRGBAFromString( pScheme->mousedownFgColor, paramValue ); - hasMouseDownFgColor = true; - } - else if ( !stricmp(paramName, "BgColorMousedown") ) - { - ParseRGBAFromString( pScheme->mousedownBgColor, paramValue ); - hasMouseDownBgColor = true; - } - else if ( !stricmp(paramName, "BorderColor") ) - { - ParseRGBAFromString( pScheme->borderColor, paramValue ); - hasMouseDownBgColor = true; - } - - // get the new token last, so we now if the loop needs to be continued or not - pFile = gEngfuncs.COM_ParseFile( pFile, token ); - } - - // free the file - gEngfuncs.COM_FreeFile( pFileStart ); - - -buildDefaultFont: - - // make sure we have at least 1 valid font - if ( currentScheme < 0 ) - { - currentScheme = 0; - strcpy( tmpSchemes[0].schemeName, "Default Scheme" ); - strcpy( tmpSchemes[0].fontName, "Arial" ); - tmpSchemes[0].fontSize = 0; - tmpSchemes[0].fgColor[0] = tmpSchemes[0].fgColor[1] = tmpSchemes[0].fgColor[2] = tmpSchemes[0].fgColor[3] = 255; - tmpSchemes[0].armedFgColor[0] = tmpSchemes[0].armedFgColor[1] = tmpSchemes[0].armedFgColor[2] = tmpSchemes[0].armedFgColor[3] = 255; - tmpSchemes[0].mousedownFgColor[0] = tmpSchemes[0].mousedownFgColor[1] = tmpSchemes[0].mousedownFgColor[2] = tmpSchemes[0].mousedownFgColor[3] = 255; - } - - // we have the full list of schemes in the tmpSchemes array - // now allocate the correct sized list - m_iNumSchemes = currentScheme + 1; // 0-based index - m_pSchemeList = new CScheme[ m_iNumSchemes ]; - - // copy in the data - memcpy( m_pSchemeList, tmpSchemes, sizeof(CScheme) * m_iNumSchemes ); - - // create the fonts - for ( int i = 0; i < m_iNumSchemes; i++ ) - { - m_pSchemeList[i].font = NULL; - - // see if the current font values exist in a previously loaded font - for ( int j = 0; j < i; j++ ) - { - // check if the font name, size, and weight are the same - if ( !stricmp(m_pSchemeList[i].fontName, m_pSchemeList[j].fontName) - && m_pSchemeList[i].fontSize == m_pSchemeList[j].fontSize - && m_pSchemeList[i].fontWeight == m_pSchemeList[j].fontWeight ) - { - // copy the pointer, but mark i as not owning it - m_pSchemeList[i].font = m_pSchemeList[j].font; - m_pSchemeList[i].ownFontPointer = false; - } - } - - // if we haven't found the font already, load it ourselves - if ( !m_pSchemeList[i].font ) - { - fontFileLength = -1; - pFontData = NULL; - - if(g_CV_BitmapFonts && g_CV_BitmapFonts->value) - { - int fontRes = 640; - if ( m_xRes >= 1600 ) - fontRes = 1600; - else if ( m_xRes >= 1280 ) - fontRes = 1280; - else if ( m_xRes >= 1152 ) - fontRes = 1152; - else if ( m_xRes >= 1024 ) - fontRes = 1024; - else if ( m_xRes >= 800 ) - fontRes = 800; - - sprintf(fontFilename, "gfx\\vgui\\fonts\\%d_%s.tga", fontRes, m_pSchemeList[i].schemeName); - pFontData = gEngfuncs.COM_LoadFile( fontFilename, 5, &fontFileLength ); - if(!pFontData) - gEngfuncs.Con_Printf("Missing bitmap font: %s\n", fontFilename); - } - - m_pSchemeList[i].font = new vgui::Font( - m_pSchemeList[i].fontName, - pFontData, - fontFileLength, - m_pSchemeList[i].fontSize, - 0, - 0, - m_pSchemeList[i].fontWeight, - false, - false, - false, - false); - - m_pSchemeList[i].ownFontPointer = true; - } - - // fix up alpha values; VGUI uses 1-A (A=0 being solid, A=255 transparent) - m_pSchemeList[i].fgColor[3] = 255 - m_pSchemeList[i].fgColor[3]; - m_pSchemeList[i].bgColor[3] = 255 - m_pSchemeList[i].bgColor[3]; - m_pSchemeList[i].armedFgColor[3] = 255 - m_pSchemeList[i].armedFgColor[3]; - m_pSchemeList[i].armedBgColor[3] = 255 - m_pSchemeList[i].armedBgColor[3]; - m_pSchemeList[i].mousedownFgColor[3] = 255 - m_pSchemeList[i].mousedownFgColor[3]; - m_pSchemeList[i].mousedownBgColor[3] = 255 - m_pSchemeList[i].mousedownBgColor[3]; - } -} - -//----------------------------------------------------------------------------- -// Purpose: frees all the memory used by the scheme manager -//----------------------------------------------------------------------------- -CSchemeManager::~CSchemeManager() -{ - delete [] m_pSchemeList; - m_iNumSchemes = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: Finds a scheme in the list, by name -// Input : char *schemeName - string name of the scheme -// Output : SchemeHandle_t handle to the scheme -//----------------------------------------------------------------------------- -SchemeHandle_t CSchemeManager::getSchemeHandle( const char *schemeName ) -{ - // iterate through the list - for ( int i = 0; i < m_iNumSchemes; i++ ) - { - if ( !stricmp(schemeName, m_pSchemeList[i].schemeName) ) - return i; - } - - return 0; -} - -//----------------------------------------------------------------------------- -// Purpose: always returns a valid scheme handle -// Input : schemeHandle - -// Output : CScheme -//----------------------------------------------------------------------------- -CSchemeManager::CScheme *CSchemeManager::getSafeScheme( SchemeHandle_t schemeHandle ) -{ - if ( schemeHandle < m_iNumSchemes ) - return m_pSchemeList + schemeHandle; - - return m_pSchemeList; -} - - -//----------------------------------------------------------------------------- -// Purpose: Returns the schemes pointer to a font -// Input : schemeHandle - -// Output : vgui::Font -//----------------------------------------------------------------------------- -vgui::Font *CSchemeManager::getFont( SchemeHandle_t schemeHandle ) -{ - return getSafeScheme( schemeHandle )->font; -} - -void CSchemeManager::getFgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->fgColor[0]; - g = pScheme->fgColor[1]; - b = pScheme->fgColor[2]; - a = pScheme->fgColor[3]; -} - -void CSchemeManager::getBgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->bgColor[0]; - g = pScheme->bgColor[1]; - b = pScheme->bgColor[2]; - a = pScheme->bgColor[3]; -} - -void CSchemeManager::getFgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->armedFgColor[0]; - g = pScheme->armedFgColor[1]; - b = pScheme->armedFgColor[2]; - a = pScheme->armedFgColor[3]; -} - -void CSchemeManager::getBgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->armedBgColor[0]; - g = pScheme->armedBgColor[1]; - b = pScheme->armedBgColor[2]; - a = pScheme->armedBgColor[3]; -} - -void CSchemeManager::getFgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->mousedownFgColor[0]; - g = pScheme->mousedownFgColor[1]; - b = pScheme->mousedownFgColor[2]; - a = pScheme->mousedownFgColor[3]; -} - -void CSchemeManager::getBgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->mousedownBgColor[0]; - g = pScheme->mousedownBgColor[1]; - b = pScheme->mousedownBgColor[2]; - a = pScheme->mousedownBgColor[3]; -} - -void CSchemeManager::getBorderColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ) -{ - CScheme *pScheme = getSafeScheme( schemeHandle ); - r = pScheme->borderColor[0]; - g = pScheme->borderColor[1]; - b = pScheme->borderColor[2]; - a = pScheme->borderColor[3]; -} - - - diff --git a/ricochet/cl_dll/vgui_SchemeManager.h b/ricochet/cl_dll/vgui_SchemeManager.h deleted file mode 100644 index b1da639..0000000 --- a/ricochet/cl_dll/vgui_SchemeManager.h +++ /dev/null @@ -1,47 +0,0 @@ -#include - - -// handle to an individual scheme -typedef int SchemeHandle_t; - - -// Register console variables, etc.. -void Scheme_Init(); - - -//----------------------------------------------------------------------------- -// Purpose: Handles the loading of text scheme description from disk -// supports different font/color/size schemes at different resolutions -//----------------------------------------------------------------------------- -class CSchemeManager -{ -public: - // initialization - CSchemeManager( int xRes, int yRes ); - virtual ~CSchemeManager(); - - // scheme handling - SchemeHandle_t getSchemeHandle( const char *schemeName ); - - // getting info from schemes - vgui::Font *getFont( SchemeHandle_t schemeHandle ); - void getFgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getBgColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getFgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getBgArmedColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getFgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getBgMousedownColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - void getBorderColor( SchemeHandle_t schemeHandle, int &r, int &g, int &b, int &a ); - -private: - class CScheme; - CScheme *m_pSchemeList; - int m_iNumSchemes; - - // Resolution we were initted at. - int m_xRes; - - CScheme *getSafeScheme( SchemeHandle_t schemeHandle ); -}; - - diff --git a/ricochet/cl_dll/vgui_ScorePanel.cpp b/ricochet/cl_dll/vgui_ScorePanel.cpp deleted file mode 100644 index 2fad7d3..0000000 --- a/ricochet/cl_dll/vgui_ScorePanel.cpp +++ /dev/null @@ -1,1145 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: VGUI scoreboard -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - - -#include - -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "entity_state.h" -#include "cl_entity.h" -#include "vgui_TeamFortressViewport.h" -#include "vgui_ScorePanel.h" -#include "vgui_helpers.h" -#include "vgui_loadtga.h" -//#include "ITrackerUser.h" -//extern ITrackerUser *g_pTrackerUser; - -hud_player_info_t g_PlayerInfoList[MAX_PLAYERS+1]; // player info from the engine -extra_player_info_t g_PlayerExtraInfo[MAX_PLAYERS+1]; // additional player info sent directly to the client dll -team_info_t g_TeamInfo[MAX_TEAMS+1]; -int g_IsSpectator[MAX_PLAYERS+1]; - -int HUD_IsGame( const char *game ); -int EV_TFC_IsAllyTeam( int iTeam1, int iTeam2 ){ return 1; } - -int iNumberOfTeamColors = 33; - -// Scoreboard dimensions -#define SBOARD_TITLE_SIZE_Y YRES(22) - -#define X_BORDER XRES(4) - -// Column sizes -class SBColumnInfo -{ -public: - char *m_pTitle; // If null, ignore, if starts with #, it's localized, otherwise use the string directly. - int m_Width; // Based on 640 width. Scaled to fit other resolutions. - Label::Alignment m_Alignment; -}; - -// grid size is marked out for 640x480 screen - -SBColumnInfo g_ColumnInfo[NUM_COLUMNS] = -{ - {NULL, 24, Label::a_east}, // tracker column - {NULL, 140, Label::a_east}, // name - {"#QUEUE", 56, Label::a_east}, // class - {"#WINS", 40, Label::a_east}, - {"#POINTS", 46, Label::a_east}, - {"#LATENCY", 46, Label::a_east}, - {"#VOICE", 40, Label::a_east}, - {NULL, 2, Label::a_east}, // blank column to take up the slack -}; - -extern float g_iaDiscColors[33][3]; - -#define TEAM_NO 0 -#define TEAM_YES 1 -#define TEAM_UNASSIGNED 2 -#define TEAM_SPECTATORS 3 - - -//----------------------------------------------------------------------------- -// ScorePanel::HitTestPanel. -//----------------------------------------------------------------------------- - -void ScorePanel::HitTestPanel::internalMousePressed(MouseCode code) -{ - for(int i=0;i<_inputSignalDar.getCount();i++) - { - _inputSignalDar[i]->mousePressed(code,this); - } -} - - - -//----------------------------------------------------------------------------- -// Purpose: Create the ScoreBoard panel -//----------------------------------------------------------------------------- -ScorePanel::ScorePanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall) -{ - CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); - SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle("Scoreboard Title Text"); - SchemeHandle_t hSmallScheme = pSchemes->getSchemeHandle("Scoreboard Small Text"); - Font *tfont = pSchemes->getFont(hTitleScheme); - Font *smallfont = pSchemes->getFont(hSmallScheme); - - setBgColor(0, 0, 0, 96); - m_pCurrentHighlightLabel = NULL; - m_iHighlightRow = -1; - - m_pTrackerIcon = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_scoreboardtracker.tga"); - - // Initialize the top title. - m_TitleLabel.setFont(tfont); - m_TitleLabel.setText(""); - m_TitleLabel.setBgColor( 0, 0, 0, 255 ); - m_TitleLabel.setFgColor( Scheme::sc_primary1 ); - m_TitleLabel.setContentAlignment( vgui::Label::a_west ); - - LineBorder *border = new LineBorder(Color(60, 60, 60, 128)); - setBorder(border); - setPaintBorderEnabled(true); - - int xpos = g_ColumnInfo[0].m_Width + 3; - if (ScreenWidth >= 640) - { - // only expand column size for res greater than 640 - xpos = XRES(xpos); - } - m_TitleLabel.setBounds(xpos, 4, wide, SBOARD_TITLE_SIZE_Y); - m_TitleLabel.setContentFitted(false); - m_TitleLabel.setParent(this); - - // Setup the header (labels like "name", "class", etc..). - m_HeaderGrid.SetDimensions(NUM_COLUMNS, 1); - m_HeaderGrid.SetSpacing(0, 0); - - for(int i=0; i < NUM_COLUMNS; i++) - { - if (g_ColumnInfo[i].m_pTitle && g_ColumnInfo[i].m_pTitle[0] == '#') - m_HeaderLabels[i].setText(CHudTextMessage::BufferedLocaliseTextString(g_ColumnInfo[i].m_pTitle)); - else if(g_ColumnInfo[i].m_pTitle) - m_HeaderLabels[i].setText(g_ColumnInfo[i].m_pTitle); - - int xwide = g_ColumnInfo[i].m_Width; - if (ScreenWidth >= 640) - { - xwide = XRES(xwide); - } - else if (ScreenWidth == 400) - { - // hack to make 400x300 resolution scoreboard fit - if (i == 1) - { - // reduces size of player name cell - xwide -= 28; - } - else if (i == 0) - { - // tracker icon cell - xwide -= 8; - } - } - - m_HeaderGrid.SetColumnWidth(i, xwide); - m_HeaderGrid.SetEntry(i, 0, &m_HeaderLabels[i]); - - m_HeaderLabels[i].setBgColor(0,0,0,255); - m_HeaderLabels[i].setFgColor(Scheme::sc_primary1); - m_HeaderLabels[i].setFont(smallfont); - m_HeaderLabels[i].setContentAlignment(g_ColumnInfo[i].m_Alignment); - - int yres = 12; - if (ScreenHeight >= 480) - { - yres = YRES(yres); - } - m_HeaderLabels[i].setSize(50, yres); - } - - // Set the width of the last column to be the remaining space. - int ex, ey, ew, eh; - m_HeaderGrid.GetEntryBox(NUM_COLUMNS - 2, 0, ex, ey, ew, eh); - m_HeaderGrid.SetColumnWidth(NUM_COLUMNS - 1, (wide - X_BORDER) - (ex + ew)); - - m_HeaderGrid.AutoSetRowHeights(); - m_HeaderGrid.setBounds(X_BORDER, SBOARD_TITLE_SIZE_Y, wide - X_BORDER*2, m_HeaderGrid.GetRowHeight(0)); - m_HeaderGrid.setParent(this); - m_HeaderGrid.setBgColor(0,0,0,255); - - - // Now setup the listbox with the actual player data in it. - int headerX, headerY, headerWidth, headerHeight; - m_HeaderGrid.getBounds(headerX, headerY, headerWidth, headerHeight); - m_PlayerList.setBounds(headerX, headerY+headerHeight, headerWidth, tall - headerY - headerHeight - 6); - m_PlayerList.setBgColor(0,0,0,255); - m_PlayerList.setParent(this); - - for(int row=0; row < NUM_ROWS; row++) - { - CGrid *pGridRow = &m_PlayerGrids[row]; - - pGridRow->SetDimensions(NUM_COLUMNS, 1); - - for(int col=0; col < NUM_COLUMNS; col++) - { - m_PlayerEntries[col][row].setContentFitted(false); - m_PlayerEntries[col][row].setRow(row); - m_PlayerEntries[col][row].addInputSignal(this); - pGridRow->SetEntry(col, 0, &m_PlayerEntries[col][row]); - } - - pGridRow->setBgColor(0,0,0,255); - pGridRow->SetSpacing(0, 0); - pGridRow->CopyColumnWidths(&m_HeaderGrid); - pGridRow->AutoSetRowHeights(); - pGridRow->setSize(PanelWidth(pGridRow), pGridRow->CalcDrawHeight()); - pGridRow->RepositionContents(); - - m_PlayerList.AddItem(pGridRow); - } - - - // Add the hit test panel. It is invisible and traps mouse clicks so we can go into squelch mode. - m_HitTestPanel.setBgColor(0,0,0,255); - m_HitTestPanel.setParent(this); - m_HitTestPanel.setBounds(0, 0, wide, tall); - m_HitTestPanel.addInputSignal(this); - -/* m_pCloseButton = new CommandButton( "x", wide-XRES(12 + 4), YRES(2), XRES( 12 ) , YRES( 12 ) ); - m_pCloseButton->setParent( this ); - m_pCloseButton->addActionSignal( new CMenuHandler_StringCommandWatch( "-showscores", true ) ); - m_pCloseButton->setBgColor(0,0,0,255); - m_pCloseButton->setFgColor( 255, 255, 255, 0 ); - m_pCloseButton->setFont(tfont); - m_pCloseButton->setBoundKey( (char)255 ); - m_pCloseButton->setContentAlignment(Label::a_center);*/ - - - Initialize(); -} - - -//----------------------------------------------------------------------------- -// Purpose: Called each time a new level is started. -//----------------------------------------------------------------------------- -void ScorePanel::Initialize( void ) -{ - // Clear out scoreboard data - m_iLastKilledBy = 0; - m_fLastKillTime = 0; - m_iPlayerNum = 0; - m_iNumTeams = 0; - memset( g_PlayerExtraInfo, 0, sizeof g_PlayerExtraInfo ); - memset( g_TeamInfo, 0, sizeof g_TeamInfo ); -} - -bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] ) -{ - return !!gEngfuncs.GetPlayerUniqueID( iPlayer, playerID ); // TODO remove after testing -} - -extern int g_iArenaMode; - -//----------------------------------------------------------------------------- -// Purpose: Recalculate the internal scoreboard data -//----------------------------------------------------------------------------- -void ScorePanel::Update() -{ - int i; - - // Set the title - if (gViewPort->m_szServerName) - { - char sz[MAX_SERVERNAME_LENGTH + 16]; - sprintf(sz, "%s", gViewPort->m_szServerName ); - m_TitleLabel.setText(sz); - } - - m_iRows = 0; - gViewPort->GetAllPlayersInfo(); - - - //Hide or show the QUEUE and WINS labels. - if ( g_iArenaMode == TRUE ) - { - m_HeaderLabels[2].setVisible ( true ); - m_HeaderLabels[3].setVisible ( true ); - } - else - { - m_HeaderLabels[2].setVisible ( false ); - m_HeaderLabels[3].setVisible ( false ); - } - - // Clear out sorts - for (i = 0; i < NUM_ROWS; i++) - { - m_iSortedRows[i] = 0; - m_iIsATeam[i] = TEAM_NO; - } - for (i = 0; i < MAX_PLAYERS; i++) - { - m_bHasBeenSorted[i] = false; - } - - SortTeams(); - - // If it's not teamplay, sort all the players. Otherwise, sort the teams. -// if ( !gHUD.m_Teamplay ) - SortPlayers( 0, NULL ); -// else - - - // set scrollbar range - m_PlayerList.SetScrollRange(m_iRows); - - FillGrid(); -} - -//----------------------------------------------------------------------------- -// Purpose: Sort all the teams -//----------------------------------------------------------------------------- -void ScorePanel::SortTeams() -{ - // clear out team scores - int i; - for ( i = 1; i <= m_iNumTeams; i++ ) - { - if ( !g_TeamInfo[i].scores_overriden ) - g_TeamInfo[i].frags = g_TeamInfo[i].deaths = 0; - g_TeamInfo[i].ping = g_TeamInfo[i].packetloss = 0; - } - - // recalc the team scores, then draw them - for ( i = 1; i < MAX_PLAYERS; i++ ) - { - if ( g_PlayerInfoList[i].name == NULL ) - continue; // empty player slot, skip - - if ( g_PlayerExtraInfo[i].teamname[0] == 0 ) - continue; // skip over players who are not in a team - - // find what team this player is in - int j; - for ( j = 1; j <= m_iNumTeams; j++ ) - { - if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) ) - break; - } - if ( j > m_iNumTeams ) // player is not in a team, skip to the next guy - continue; - - if ( !g_TeamInfo[j].scores_overriden ) - { - g_TeamInfo[j].frags += g_PlayerExtraInfo[i].frags; - g_TeamInfo[j].deaths += g_PlayerExtraInfo[i].deaths; - } - - g_TeamInfo[j].ping += g_PlayerInfoList[i].ping; - g_TeamInfo[j].packetloss += g_PlayerInfoList[i].packetloss; - - if ( g_PlayerInfoList[i].thisplayer ) - g_TeamInfo[j].ownteam = TRUE; - else - g_TeamInfo[j].ownteam = FALSE; - - // Set the team's number (used for team colors) - g_TeamInfo[j].teamnumber = g_PlayerExtraInfo[i].teamnumber; - } - - // find team ping/packetloss averages - for ( i = 1; i <= m_iNumTeams; i++ ) - { - g_TeamInfo[i].already_drawn = FALSE; - - if ( g_TeamInfo[i].players > 0 ) - { - g_TeamInfo[i].ping /= g_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping - g_TeamInfo[i].packetloss /= g_TeamInfo[i].players; // use the average ping of all the players in the team as the teams ping - } - } - - // Draw the teams - while ( 1 ) - { - int highest_frags = -99999; int lowest_deaths = 99999; - int best_team = 0; - - for ( i = 1; i <= m_iNumTeams; i++ ) - { - if ( g_TeamInfo[i].players < 1 ) - continue; - - if ( !g_TeamInfo[i].already_drawn && g_TeamInfo[i].frags >= highest_frags ) - { - if ( g_TeamInfo[i].frags > highest_frags || g_TeamInfo[i].deaths < lowest_deaths ) - { - best_team = i; - lowest_deaths = g_TeamInfo[i].deaths; - highest_frags = g_TeamInfo[i].frags; - } - } - } - - // draw the best team on the scoreboard - if ( !best_team ) - break; - - // Put this team in the sorted list - m_iSortedRows[ m_iRows ] = best_team; - m_iIsATeam[ m_iRows ] = TEAM_YES; - g_TeamInfo[best_team].already_drawn = TRUE; // set the already_drawn to be TRUE, so this team won't get sorted again - m_iRows++; - - // Now sort all the players on this team - SortPlayers( 0, g_TeamInfo[best_team].name ); - } - - // Add all the players who aren't in a team yet into spectators - SortPlayers( TEAM_SPECTATORS, NULL ); -} - -//----------------------------------------------------------------------------- -// Purpose: Sort a list of players -//----------------------------------------------------------------------------- -void ScorePanel::SortPlayers( int iTeam, char *team ) -{ - bool bCreatedTeam = false; - - // draw the players, in order, and restricted to team if set - while ( 1 ) - { - // Find the top ranking player - int highest_frags = -99999; int lowest_deaths = 99999; - int best_player; - best_player = 0; - - for ( int i = 1; i < MAX_PLAYERS; i++ ) - { - if ( m_bHasBeenSorted[i] == false && g_PlayerInfoList[i].name && g_PlayerExtraInfo[i].frags >= highest_frags ) - { - cl_entity_t *ent = gEngfuncs.GetEntityByIndex( i ); - - if ( ent && !(team && stricmp(g_PlayerExtraInfo[i].teamname, team)) ) - { - extra_player_info_t *pl_info = &g_PlayerExtraInfo[i]; - if ( pl_info->frags > highest_frags || pl_info->deaths < lowest_deaths ) - { - best_player = i; - lowest_deaths = pl_info->deaths; - highest_frags = pl_info->frags; - } - } - } - } - - if ( !best_player ) - break; - - // If we haven't created the Team yet, do it first - if (!bCreatedTeam && iTeam) - { - m_iIsATeam[ m_iRows ] = iTeam; - m_iRows++; - - bCreatedTeam = true; - } - - // Put this player in the sorted list - m_iSortedRows[ m_iRows ] = best_player; - m_bHasBeenSorted[ best_player ] = true; - m_iRows++; - } - - if (team) - { - m_iIsATeam[m_iRows++] = TEAM_SPECTATORS; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Recalculate the existing teams in the match -//----------------------------------------------------------------------------- -void ScorePanel::RebuildTeams() -{ - // clear out player counts from teams - int i; - for ( i = 1; i <= m_iNumTeams; i++ ) - { - g_TeamInfo[i].players = 0; - } - - // rebuild the team list - gViewPort->GetAllPlayersInfo(); - m_iNumTeams = 0; - for ( i = 1; i < MAX_PLAYERS; i++ ) - { - if ( g_PlayerInfoList[i].name == NULL ) - continue; - - if ( g_PlayerExtraInfo[i].teamname[0] == 0 ) - continue; // skip over players who are not in a team - - // is this player in an existing team? - int j; - for ( j = 1; j <= m_iNumTeams; j++ ) - { - if ( g_TeamInfo[j].name[0] == '\0' ) - break; - - if ( !stricmp( g_PlayerExtraInfo[i].teamname, g_TeamInfo[j].name ) ) - break; - } - - if ( j > m_iNumTeams ) - { // they aren't in a listed team, so make a new one - // search through for an empty team slot - for ( int j = 1; j <= m_iNumTeams; j++ ) - { - if ( g_TeamInfo[j].name[0] == '\0' ) - break; - } - m_iNumTeams = V_max( j, m_iNumTeams ); - - strncpy( g_TeamInfo[j].name, g_PlayerExtraInfo[i].teamname, MAX_TEAM_NAME ); - g_TeamInfo[j].players = 0; - } - - g_TeamInfo[j].players++; - } - - // clear out any empty teams - for ( i = 1; i <= m_iNumTeams; i++ ) - { - if ( g_TeamInfo[i].players < 1 ) - memset( &g_TeamInfo[i], 0, sizeof(team_info_t) ); - } - - // Update the scoreboard - Update(); -} - - -void ScorePanel::FillGrid() -{ - CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); - SchemeHandle_t hScheme = pSchemes->getSchemeHandle("Scoreboard Text"); - SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle("Scoreboard Title Text"); - SchemeHandle_t hSmallScheme = pSchemes->getSchemeHandle("Scoreboard Small Text"); - - Font *sfont = pSchemes->getFont(hScheme); - Font *tfont = pSchemes->getFont(hTitleScheme); - Font *smallfont = pSchemes->getFont(hSmallScheme); - int i = 0; - - // update highlight position - int x, y; - getApp()->getCursorPos(x, y); - cursorMoved(x, y, this); - - // remove highlight row if we're not in squelch mode - if (!GetClientVoiceMgr()->IsInSquelchMode()) - { - m_iHighlightRow = -1; - } - - bool bNextRowIsGap = false; - - int row; - for(row=0; row < NUM_ROWS; row++) - { - CGrid *pGridRow = &m_PlayerGrids[row]; - pGridRow->SetRowUnderline(0, false, 0, 0, 0, 0, 0); - - if(row >= m_iRows) - { - for(int col=0; col < NUM_COLUMNS; col++) - m_PlayerEntries[col][row].setVisible(false); - - continue; - } - - bool bRowIsGap = false; - if (bNextRowIsGap) - { - bNextRowIsGap = false; - bRowIsGap = true; - } - - for(int col=0; col < NUM_COLUMNS; col++) - { - CLabelHeader *pLabel = &m_PlayerEntries[col][row]; - - pLabel->setVisible(true); - pLabel->setText2(""); - pLabel->setImage(NULL); - pLabel->setFont(sfont); - pLabel->setTextOffset(0, 0); - - int rowheight = 13; - if (ScreenHeight > 480) - { - rowheight = YRES(rowheight); - } - else - { - // more tweaking, make sure icons fit at low res - rowheight = 15; - } - pLabel->setSize(pLabel->getWide(), rowheight); - pLabel->setBgColor(0, 0, 0, 255); - - char sz[128]; - hud_player_info_t *pl_info = NULL; - team_info_t *team_info = NULL; - - if (m_iIsATeam[row] == TEAM_SPECTATORS) - { - pLabel->setText(" "); - continue; - } - else if ( m_iIsATeam[row] == TEAM_YES ) - { - // Get the team's data - team_info = &g_TeamInfo[ m_iSortedRows[row] ]; - - // team color text for team names - pLabel->setFgColor( iTeamColors[team_info->teamnumber % 5][0], - iTeamColors[team_info->teamnumber % 5][1], - iTeamColors[team_info->teamnumber % 5][2], - 0 ); - - // different height for team header rows - rowheight = 20; - if (ScreenHeight >= 480) - { - rowheight = YRES(rowheight); - } - pLabel->setSize(pLabel->getWide(), rowheight); - pLabel->setFont(tfont); - - pGridRow->SetRowUnderline( 0, - true, - YRES(3), - iTeamColors[team_info->teamnumber % 5][0], - iTeamColors[team_info->teamnumber % 5][1], - iTeamColors[team_info->teamnumber % 5][2], - 0 ); - } - else if ( m_iIsATeam[row] == TEAM_SPECTATORS ) - { - // grey text for spectators - pLabel->setFgColor(100, 100, 100, 0); - - // different height for team header rows - rowheight = 20; - if (ScreenHeight >= 480) - { - rowheight = YRES(rowheight); - } - pLabel->setSize(pLabel->getWide(), rowheight); - pLabel->setFont(tfont); - - pGridRow->SetRowUnderline(0, true, YRES(3), 100, 100, 100, 0); - } - else - { - // team color text for player names - pLabel->setFgColor( g_iaDiscColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber % iNumberOfTeamColors ][0], - g_iaDiscColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber % iNumberOfTeamColors ][1], - g_iaDiscColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber % iNumberOfTeamColors ][2], - 0 ); - - // Get the player's data - pl_info = &g_PlayerInfoList[ m_iSortedRows[row] ]; - - // Set background color - if ( pl_info->thisplayer ) // if it is their name, draw it a different color - { - // Highlight this player - pLabel->setFgColor(Scheme::sc_white); - pLabel->setBgColor( g_iaDiscColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber % iNumberOfTeamColors ][0], - g_iaDiscColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber % iNumberOfTeamColors ][1], - g_iaDiscColors[ g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber % iNumberOfTeamColors ][2], - 196 ); - } - else if ( m_iSortedRows[row] == m_iLastKilledBy && m_fLastKillTime && m_fLastKillTime > gHUD.m_flTime ) - { - // Killer's name - pLabel->setBgColor( 255,0,0, 255 - ((float)15 * (float)(m_fLastKillTime - gHUD.m_flTime)) ); - } - } - - // Align - if (col == COLUMN_NAME ) - { - pLabel->setContentAlignment( vgui::Label::a_west ); - } - else if (col == COLUMN_TRACKER) - { - pLabel->setContentAlignment( vgui::Label::a_center ); - } - else - { - pLabel->setContentAlignment( vgui::Label::a_east ); - } - - // Fill out with the correct data - strcpy(sz, ""); - if ( m_iIsATeam[row] ) - { - char sz2[128]; - - switch (col) - { - case COLUMN_NAME: - if ( m_iIsATeam[row] == TEAM_UNASSIGNED ) - { - sprintf( sz2, CHudTextMessage::BufferedLocaliseTextString( "#Queue" ) ); - } - else if ( m_iIsATeam[row] == TEAM_SPECTATORS ) - { - sprintf( sz2, CHudTextMessage::BufferedLocaliseTextString( "#Spectators" ) ); - } - else - { - sprintf( sz2, CHudTextMessage::BufferedLocaliseTextString( team_info->name ) ); - } - - // Uppercase it - for ( i = 0; i < (int)strlen(sz2); i++) - { - if ( *(sz2 + i) ) - sz[i] = toupper( *(sz2 + i) ); - } - sz[i] = '\0'; - - // Append the number of players - if ( m_iIsATeam[row] == TEAM_YES ) - { - char *pszTemp = NULL; - - if ( team_info->players == 1 ) - { - pszTemp = "#Player"; - } - else - { - pszTemp = "#Player_plural"; - } - - sprintf(sz, "%s (%d %s)", sz, team_info->players, CHudTextMessage::BufferedLocaliseTextString( pszTemp ) ); - } - - break; - case COLUMN_VOICE: - break; - case COLUMN_CLASS: - break; - case COLUMN_KILLS: //Wins - if ( g_iArenaMode == FALSE ) - strcpy ( sz, " " ); - else - { - if ( m_iIsATeam[row] == TEAM_YES ) - sprintf(sz, "%d", team_info->deaths ); - } - break; - case COLUMN_DEATHS: //Points - if ( m_iIsATeam[row] == TEAM_YES ) - sprintf(sz, "%d", team_info->frags ); - break; - case COLUMN_LATENCY: - if ( m_iIsATeam[row] == TEAM_YES ) - sprintf(sz, "%d", team_info->ping ); - break; - default: - break; - } - } - else - { - bool bShowClass = false; - - switch (col) - { - case COLUMN_NAME: - /* - if (g_pTrackerUser) - { - int playerSlot = m_iSortedRows[row]; - int trackerID = gEngfuncs.GetTrackerIDForPlayer(playerSlot); - const char *trackerName = g_pTrackerUser->GetUserName(trackerID); - if (trackerName && *trackerName) - { - sprintf(sz, " (%s)", trackerName); - pLabel->setText2(sz); - } - } - */ - sprintf(sz, "%s ", pl_info->name); - break; - case COLUMN_VOICE: - sz[0] = 0; - GetClientVoiceMgr()->UpdateSpeakerImage(pLabel, m_iSortedRows[row]); - break; - case COLUMN_CLASS: - - if ( g_PlayerExtraInfo[ m_iSortedRows[row] ].teamnumber == 0 && g_iArenaMode == TRUE ) - { - sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].playerclass ); - } - else - { - strcpy(sz, ""); - } - - break; - - case COLUMN_TRACKER: - /* - if (g_pTrackerUser) - { - int playerSlot = m_iSortedRows[row]; - int trackerID = gEngfuncs.GetTrackerIDForPlayer(playerSlot); - - if (g_pTrackerUser->IsFriend(trackerID) && trackerID != g_pTrackerUser->GetTrackerID()) - { - pLabel->setImage(m_pTrackerIcon); - pLabel->setFgColorAsImageColor(false); - m_pTrackerIcon->setColor(Color(255, 255, 255, 0)); - } - }*/ - break; - - case COLUMN_KILLS: //Wins - if ( g_iArenaMode == TRUE ) - sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].deaths ); - break; - case COLUMN_DEATHS: //Points - sprintf(sz, "%d", g_PlayerExtraInfo[ m_iSortedRows[row] ].frags ); - break; - case COLUMN_LATENCY: - sprintf(sz, "%d", g_PlayerInfoList[ m_iSortedRows[row] ].ping ); - break; - default: - break; - } - } - - pLabel->setText(sz); - } - } - - for(row=0; row < NUM_ROWS; row++) - { - CGrid *pGridRow = &m_PlayerGrids[row]; - - pGridRow->AutoSetRowHeights(); - pGridRow->setSize(PanelWidth(pGridRow), pGridRow->CalcDrawHeight()); - pGridRow->RepositionContents(); - } - - // hack, for the thing to resize - m_PlayerList.getSize(x, y); - m_PlayerList.setSize(x, y); -} - - -//----------------------------------------------------------------------------- -// Purpose: Setup highlights for player names in scoreboard -//----------------------------------------------------------------------------- -void ScorePanel::DeathMsg( int killer, int victim ) -{ - // if we were the one killed, or the world killed us, set the scoreboard to indicate suicide - if ( victim == m_iPlayerNum || killer == 0 ) - { - m_iLastKilledBy = killer ? killer : m_iPlayerNum; - m_fLastKillTime = gHUD.m_flTime + 10; // display who we were killed by for 10 seconds - - if ( killer == m_iPlayerNum ) - m_iLastKilledBy = m_iPlayerNum; - } -} - - -void ScorePanel::Open( void ) -{ - RebuildTeams(); - setVisible(true); - m_HitTestPanel.setVisible(true); -} - - -void ScorePanel::mousePressed(MouseCode code, Panel* panel) -{ - if(gHUD.m_iIntermission) - return; - - if (!GetClientVoiceMgr()->IsInSquelchMode()) - { - GetClientVoiceMgr()->StartSquelchMode(); - m_HitTestPanel.setVisible(false); - } - else if (m_iHighlightRow >= 0) - { - // mouse has been pressed, toggle mute state - int iPlayer = m_iSortedRows[m_iHighlightRow]; - if (iPlayer > 0) - { - // print text message - hud_player_info_t *pl_info = &g_PlayerInfoList[iPlayer]; - - if (pl_info && pl_info->name && pl_info->name[0]) - { - char string[256]; - if (GetClientVoiceMgr()->IsPlayerBlocked(iPlayer)) - { - char string1[1024]; - - // remove mute - GetClientVoiceMgr()->SetPlayerBlockedState(iPlayer, false); - - sprintf( string1, CHudTextMessage::BufferedLocaliseTextString( "#Unmuted" ), pl_info->name ); - sprintf( string, "%c** %s\n", HUD_PRINTTALK, string1 ); - - gHUD.m_TextMessage.MsgFunc_TextMsg(NULL, strlen(string)+1, string ); - } - else - { - char string1[1024]; - char string2[1024]; - - // mute the player - GetClientVoiceMgr()->SetPlayerBlockedState(iPlayer, true); - - sprintf( string1, CHudTextMessage::BufferedLocaliseTextString( "#Muted" ), pl_info->name ); - sprintf( string2, CHudTextMessage::BufferedLocaliseTextString( "#No_longer_hear_that_player" ) ); - sprintf( string, "%c** %s %s\n", HUD_PRINTTALK, string1, string2 ); - - gHUD.m_TextMessage.MsgFunc_TextMsg(NULL, strlen(string)+1, string ); - } - } - } - } -} - -void ScorePanel::cursorMoved(int x, int y, Panel *panel) -{ - if (GetClientVoiceMgr()->IsInSquelchMode()) - { - // look for which cell the mouse is currently over - for (int i = 0; i < NUM_ROWS; i++) - { - int row, col; - if (m_PlayerGrids[i].getCellAtPoint(x, y, row, col)) - { - MouseOverCell(i, col); - return; - } - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Handles mouse movement over a cell -// Input : row - -// col - -//----------------------------------------------------------------------------- -void ScorePanel::MouseOverCell(int row, int col) -{ - CLabelHeader *label = &m_PlayerEntries[col][row]; - - // clear the previously highlighted label - if (m_pCurrentHighlightLabel != label) - { - m_pCurrentHighlightLabel = NULL; - m_iHighlightRow = -1; - } - if (!label) - return; - - // don't act on teams - if (m_iIsATeam[row] != TEAM_NO) - return; - - // don't act on disconnected players or ourselves - hud_player_info_t *pl_info = &g_PlayerInfoList[ m_iSortedRows[row] ]; - if (!pl_info->name || !pl_info->name[0]) - return; - - if (pl_info->thisplayer && !gEngfuncs.IsSpectateOnly() ) - return; - - // setup the new highlight - m_pCurrentHighlightLabel = label; - m_iHighlightRow = row; -} - -//----------------------------------------------------------------------------- -// Purpose: Label paint functions - take into account current highligh status -//----------------------------------------------------------------------------- -void CLabelHeader::paintBackground() -{ - Color oldBg; - getBgColor(oldBg); - - if (gViewPort->GetScoreBoard()->m_iHighlightRow == _row) - { - setBgColor(134, 91, 19, 0); - } - - Panel::paintBackground(); - - setBgColor(oldBg); -} - - -//----------------------------------------------------------------------------- -// Purpose: Label paint functions - take into account current highligh status -//----------------------------------------------------------------------------- -void CLabelHeader::paint() -{ - Color oldFg; - getFgColor(oldFg); - - if (gViewPort->GetScoreBoard()->m_iHighlightRow == _row) - { - setFgColor(255, 255, 255, 0); - } - - // draw text - int x, y, iwide, itall; - getTextSize(iwide, itall); - calcAlignment(iwide, itall, x, y); - _dualImage->setPos(x, y); - - int x1, y1; - _dualImage->GetImage(1)->getPos(x1, y1); - _dualImage->GetImage(1)->setPos(_gap, y1); - - _dualImage->doPaint(this); - - // get size of the panel and the image - if (_image) - { - Color imgColor; - getFgColor( imgColor ); - if( _useFgColorAsImageColor ) - { - _image->setColor( imgColor ); - } - - _image->getSize(iwide, itall); - calcAlignment(iwide, itall, x, y); - _image->setPos(x, y); - _image->doPaint(this); - } - - setFgColor(oldFg[0], oldFg[1], oldFg[2], oldFg[3]); -} - - -void CLabelHeader::calcAlignment(int iwide, int itall, int &x, int &y) -{ - // calculate alignment ourselves, since vgui is so broken - int wide, tall; - getSize(wide, tall); - - x = 0, y = 0; - - // align left/right - switch (_contentAlignment) - { - // left - case Label::a_northwest: - case Label::a_west: - case Label::a_southwest: - { - x = 0; - break; - } - - // center - case Label::a_north: - case Label::a_center: - case Label::a_south: - { - x = (wide - iwide) / 2; - break; - } - - // right - case Label::a_northeast: - case Label::a_east: - case Label::a_southeast: - { - x = wide - iwide; - break; - } - } - - // top/down - switch (_contentAlignment) - { - // top - case Label::a_northwest: - case Label::a_north: - case Label::a_northeast: - { - y = 0; - break; - } - - // center - case Label::a_west: - case Label::a_center: - case Label::a_east: - { - y = (tall - itall) / 2; - break; - } - - // south - case Label::a_southwest: - case Label::a_south: - case Label::a_southeast: - { - y = tall - itall; - break; - } - } - -// don't clip to Y -// if (y < 0) -// { -// y = 0; -// } - if (x < 0) - { - x = 0; - } - - x += _offset[0]; - y += _offset[1]; -} diff --git a/ricochet/cl_dll/vgui_ScorePanel.h b/ricochet/cl_dll/vgui_ScorePanel.h deleted file mode 100644 index cefeafe..0000000 --- a/ricochet/cl_dll/vgui_ScorePanel.h +++ /dev/null @@ -1,307 +0,0 @@ - -#ifndef SCOREPANEL_H -#define SCOREPANEL_H - -#include -#include -#include -#include -#include -#include -#include "vgui_listbox.h" - -#include - -#define MAX_SCORES 10 -#define MAX_SCOREBOARD_TEAMS 5 - -// Scoreboard cells -#define COLUMN_TRACKER 0 -#define COLUMN_NAME 1 -#define COLUMN_CLASS 2 -#define COLUMN_KILLS 3 -#define COLUMN_DEATHS 4 -#define COLUMN_LATENCY 5 -#define COLUMN_VOICE 6 -#define COLUMN_BLANK 7 -#define NUM_COLUMNS 8 -#define NUM_ROWS (MAX_PLAYERS + (MAX_SCOREBOARD_TEAMS * 2)) - -using namespace vgui; - -class CTextImage2 : public Image -{ -public: - CTextImage2() - { - _image[0] = new TextImage(""); - _image[1] = new TextImage(""); - } - - ~CTextImage2() - { - delete _image[0]; - delete _image[1]; - } - - TextImage *GetImage(int image) - { - return _image[image]; - } - - void getSize(int &wide, int &tall) - { - int w1, w2, t1, t2; - _image[0]->getTextSize(w1, t1); - _image[1]->getTextSize(w2, t2); - - wide = w1 + w2; - tall = V_max(t1, t2); - setSize(wide, tall); - } - - void doPaint(Panel *panel) - { - _image[0]->doPaint(panel); - _image[1]->doPaint(panel); - } - - void setPos(int x, int y) - { - _image[0]->setPos(x, y); - - int swide, stall; - _image[0]->getSize(swide, stall); - - int wide, tall; - _image[1]->getSize(wide, tall); - _image[1]->setPos(x + wide, y + (stall * 0.9) - tall); - } - - void setColor(Color color) - { - _image[0]->setColor(color); - } - - void setColor2(Color color) - { - _image[1]->setColor(color); - } - -private: - TextImage *_image[2]; - -}; - -//----------------------------------------------------------------------------- -// Purpose: Custom label for cells in the Scoreboard's Table Header -//----------------------------------------------------------------------------- -class CLabelHeader : public Label -{ -public: - CLabelHeader() : Label("") - { - _dualImage = new CTextImage2(); - _dualImage->setColor2(Color(255, 170, 0, 0)); - _row = -2; - _useFgColorAsImageColor = true; - _offset[0] = 0; - _offset[1] = 0; - } - - ~CLabelHeader() - { - delete _dualImage; - } - - void setRow(int row) - { - _row = row; - } - - void setFgColorAsImageColor(bool state) - { - _useFgColorAsImageColor = state; - } - - virtual void setText(int textBufferLen, const char* text) - { - _dualImage->GetImage(0)->setText(text); - - // calculate the text size - Font *font = _dualImage->GetImage(0)->getFont(); - _gap = 0; - for (const char *ch = text; *ch != 0; ch++) - { - int a, b, c; - font->getCharABCwide(*ch, a, b, c); - _gap += (a + b + c); - } - - _gap += XRES(5); - } - - virtual void setText(const char* text) - { - // strip any non-alnum characters from the end - char buf[512]; - strcpy(buf, text); - - int len = strlen(buf); - while (len && isspace(buf[--len])) - { - buf[len] = 0; - } - - CLabelHeader::setText(0, buf); - } - - void setText2(const char *text) - { - _dualImage->GetImage(1)->setText(text); - } - - void getTextSize(int &wide, int &tall) - { - _dualImage->getSize(wide, tall); - } - - void setFgColor(int r,int g,int b,int a) - { - Label::setFgColor(r,g,b,a); - Color color(r,g,b,a); - _dualImage->setColor(color); - _dualImage->setColor2(color); - repaint(); - } - - void setFgColor(Scheme::SchemeColor sc) - { - int r, g, b, a; - Label::setFgColor(sc); - Label::getFgColor( r, g, b, a ); - - // Call the r,g,b,a version so it sets the color in the dualImage.. - setFgColor( r, g, b, a ); - } - - void setFont(Font *font) - { - _dualImage->GetImage(0)->setFont(font); - } - - void setFont2(Font *font) - { - _dualImage->GetImage(1)->setFont(font); - } - - // this adjust the absolute position of the text after alignment is calculated - void setTextOffset(int x, int y) - { - _offset[0] = x; - _offset[1] = y; - } - - void paint(); - void paintBackground(); - void calcAlignment(int iwide, int itall, int &x, int &y); - -private: - CTextImage2 *_dualImage; - int _row; - int _gap; - int _offset[2]; - bool _useFgColorAsImageColor; -}; - -class ScoreTablePanel; - -#include "vgui_grid.h" -#include "vgui_defaultinputsignal.h" - -//----------------------------------------------------------------------------- -// Purpose: Scoreboard back panel -//----------------------------------------------------------------------------- -class ScorePanel : public Panel, public vgui::CDefaultInputSignal -{ -private: - // Default panel implementation doesn't forward mouse messages when there is no cursor and we need them. - class HitTestPanel : public Panel - { - public: - virtual void internalMousePressed(MouseCode code); - }; - - -private: - - Label m_TitleLabel; - - // Here is how these controls are arranged hierarchically. - // m_HeaderGrid - // m_HeaderLabels - - // m_PlayerGridScroll - // m_PlayerGrid - // m_PlayerEntries - - CGrid m_HeaderGrid; - CLabelHeader m_HeaderLabels[NUM_COLUMNS]; // Labels above the - CLabelHeader *m_pCurrentHighlightLabel; - int m_iHighlightRow; - - vgui::CListBox m_PlayerList; - CGrid m_PlayerGrids[NUM_ROWS]; // The grid with player and team info. - CLabelHeader m_PlayerEntries[NUM_COLUMNS][NUM_ROWS]; // Labels for the grid entries. - - ScorePanel::HitTestPanel m_HitTestPanel; -// CommandButton *m_pCloseButton; - CLabelHeader* GetPlayerEntry(int x, int y) {return &m_PlayerEntries[x][y];} - - vgui::BitmapTGA *m_pTrackerIcon; - - -public: - - int m_iNumTeams; - int m_iPlayerNum; - int m_iShowscoresHeld; - - int m_iRows; - int m_iSortedRows[NUM_ROWS]; - int m_iIsATeam[NUM_ROWS]; - bool m_bHasBeenSorted[MAX_PLAYERS]; - int m_iLastKilledBy; - int m_fLastKillTime; - - -public: - - ScorePanel(int x,int y,int wide,int tall); - - void Update( void ); - - void SortTeams( void ); - void SortPlayers( int iTeam, char *team ); - void RebuildTeams( void ); - - void FillGrid(); - - void DeathMsg( int killer, int victim ); - - void Initialize( void ); - - void Open( void ); - - void MouseOverCell(int row, int col); - -// InputSignal overrides. -public: - - virtual void mousePressed(MouseCode code, Panel* panel); - virtual void cursorMoved(int x, int y, Panel *panel); - - friend class CLabelHeader; -}; - -#endif diff --git a/ricochet/cl_dll/vgui_ServerBrowser.cpp b/ricochet/cl_dll/vgui_ServerBrowser.cpp deleted file mode 100644 index 2ba3da3..0000000 --- a/ricochet/cl_dll/vgui_ServerBrowser.cpp +++ /dev/null @@ -1,616 +0,0 @@ - -#include -#include -#include -#include -#include -#include - -#include "hud.h" -#include "cl_util.h" -#include "hud_servers.h" -#include "net_api.h" - -#include "vgui_TeamFortressViewport.h" -#include "vgui_ServerBrowser.h" - -using namespace vgui; - -namespace -{ - -#define MAX_SB_ROWS 24 - -#define NUM_COLUMNS 5 - -#define HEADER_SIZE_Y YRES(18) - -// Column sizes -#define CSIZE_ADDRESS XRES(200) -#define CSIZE_SERVER XRES(400) -#define CSIZE_MAP XRES(500) -#define CSIZE_CURRENT XRES(570) -#define CSIZE_PING XRES(640) - -#define CELL_HEIGHT YRES(15) - -class ServerBrowserTablePanel; - -class CBrowser_InputSignal : public InputSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; -public: - CBrowser_InputSignal( ServerBrowserTablePanel *pBrowser ) - { - m_pBrowser = pBrowser; - } - - virtual void cursorMoved(int x,int y,Panel* panel) {}; - virtual void cursorEntered(Panel* panel){}; - virtual void cursorExited(Panel* Panel) {}; - - virtual void mousePressed(MouseCode code,Panel* panel); - - virtual void mouseDoublePressed(MouseCode code,Panel* panel); - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -class ServerBrowserTablePanel : public TablePanel -{ -private: - Label *m_pLabel; - int m_nMouseOverRow; - -public: - - ServerBrowserTablePanel( int x,int y,int wide,int tall,int columnCount) : TablePanel( x,y,wide,tall,columnCount) - { - m_pLabel = new Label( "", 0, 0 /*,wide, tall*/ ); - - m_nMouseOverRow = 0; - } - -public: - void setMouseOverRow( int row ) - { - m_nMouseOverRow = row; - } - - void DoSort( char *sortkey ) - { - // Request server list and refresh servers... - SortServers( sortkey ); - } - - void DoRefresh( void ) - { - // Request server list and refresh servers... - ServersList(); - BroadcastServersList( 0 ); - } - - void DoBroadcastRefresh( void ) - { - // Request server list and refresh servers... - BroadcastServersList( 1 ); - } - - void DoStop( void ) - { - // Stop requesting - ServersCancel(); - } - - void DoCancel( void ) - { - ClientCmd( "togglebrowser\n" ); - } - - void DoConnect( void ) - { - const char *info; - const char *address; - char sz[ 256 ]; - - info = ServersGetInfo( m_nMouseOverRow ); - if ( !info ) - return; - - address = gEngfuncs.pNetAPI->ValueForKey( info, "address" ); - //gEngfuncs.Con_Printf( "Connecting to %s\n", address ); - - sprintf( sz, "connect %s\n", address ); - - ClientCmd( sz ); - - DoCancel(); - } - - void DoPing( void ) - { - ServerPing( 0 ); - ServerRules( 0 ); - ServerPlayers( 0 ); - } - - virtual int getRowCount() - { - int rowcount; - int height, width; - - getSize( width, height ); - - // Space for buttons - height -= YRES(20); - height = V_max( 0, height ); - - rowcount = height / CELL_HEIGHT; - - return rowcount; - } - - virtual int getCellTall(int row) - { - return CELL_HEIGHT - 2; - } - - virtual Panel* getCellRenderer(int column,int row,bool columnSelected,bool rowSelected,bool cellSelected) - { - const char *info; - const char *val, *val2; - char sz[ 32 ]; - - info = ServersGetInfo( row ); - - if ( row == m_nMouseOverRow ) - { - m_pLabel->setFgColor( 200, 240, 63, 100 ); - } - else - { - m_pLabel->setFgColor( 255, 255, 255, 0 ); - } - m_pLabel->setBgColor( 0, 0, 0, 200 ); - m_pLabel->setContentAlignment( vgui::Label::a_west ); - m_pLabel->setFont( Scheme::sf_primary2 ); - - if ( info ) - { - // Fill out with the correct data - switch ( column ) - { - case 0: - val = gEngfuncs.pNetAPI->ValueForKey( info, "address" ); - if ( val ) - { - strncpy( sz, val, 31 ); - sz[ 31 ] = '\0'; - // Server Name; - m_pLabel->setText( sz ); - } - break; - case 1: - val = gEngfuncs.pNetAPI->ValueForKey( info, "hostname" ); - if ( val ) - { - strncpy( sz, val, 31 ); - sz[ 31 ] = '\0'; - // Server Map; - m_pLabel->setText( sz ); - } - break; - case 2: - val = gEngfuncs.pNetAPI->ValueForKey( info, "map" ); - if ( val ) - { - strncpy( sz, val, 31 ); - sz[ 31 ] = '\0'; - // Server Name; - m_pLabel->setText( sz ); - } - break; - case 3: - val = gEngfuncs.pNetAPI->ValueForKey( info, "current" ); - val2 = gEngfuncs.pNetAPI->ValueForKey( info, "max" ); - if ( val && val2 ) - { - sprintf( sz, "%s/%s", val, val2 ); - sz[ 31 ] = '\0'; - // Server Map; - m_pLabel->setText( sz ); - } - break; - case 4: - val = gEngfuncs.pNetAPI->ValueForKey( info, "ping" ); - if ( val ) - { - strncpy( sz, val, 31 ); - sz[ 31 ] = '\0'; - // Server Name; - m_pLabel->setText( sz ); - } - break; - default: - break; - } - } - else - { - if ( !row && !column ) - { - if ( ServersIsQuerying() ) - { - m_pLabel->setText( "Waiting for servers to respond..." ); - } - else - { - m_pLabel->setText( "Press 'Refresh' to search for servers..." ); - } - } - else - { - m_pLabel->setText( "" ); - } - } - - return m_pLabel; - } - - virtual Panel* startCellEditing(int column,int row) - { - return null; - } - -}; - -class ConnectHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - ConnectHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoConnect(); - } -}; - -class RefreshHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - RefreshHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoRefresh(); - } -}; - -class BroadcastRefreshHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - BroadcastRefreshHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoBroadcastRefresh(); - } -}; - -class StopHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - StopHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoStop(); - } -}; - -class CancelHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - CancelHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoCancel(); - } -}; - -class PingHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - PingHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoPing(); - } -}; - -class SortHandler : public ActionSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - -public: - SortHandler( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - } - - virtual void actionPerformed( Panel *panel ) - { - m_pBrowser->DoSort( "map" ); - } -}; - -} - -class LabelSortInputHandler : public InputSignal -{ -private: - ServerBrowserTablePanel *m_pBrowser; - char m_szSortKey[ 64 ]; - -public: - LabelSortInputHandler( ServerBrowserTablePanel *pBrowser, char *name ) - { - m_pBrowser = pBrowser; - strcpy( m_szSortKey, name ); - } - - virtual void cursorMoved(int x,int y,Panel* panel) {}; - virtual void cursorEntered(Panel* panel){}; - virtual void cursorExited(Panel* Panel) {}; - - virtual void mousePressed(MouseCode code,Panel* panel) - { - m_pBrowser->DoSort( m_szSortKey ); - } - - virtual void mouseDoublePressed(MouseCode code,Panel* panel) - { - m_pBrowser->DoSort( m_szSortKey ); - } - - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -class CSBLabel : public Label -{ - -private: - char m_szSortKey[ 64 ]; - ServerBrowserTablePanel *m_pBrowser; - -public: - CSBLabel( char *name, char *sortkey ) : Label( name ) - { - m_pBrowser = NULL; - - strcpy( m_szSortKey, sortkey ); - - int label_bg_r = 120, - label_bg_g = 75, - label_bg_b = 32, - label_bg_a = 200; - - int label_fg_r = 255, - label_fg_g = 0, - label_fg_b = 0, - label_fg_a = 0; - - setContentAlignment( vgui::Label::a_west ); - setFgColor( label_fg_r, label_fg_g, label_fg_b, label_fg_a ); - setBgColor( label_bg_r, label_bg_g, label_bg_b, label_bg_a ); - setFont( Scheme::sf_primary2 ); - - } - - void setTable( ServerBrowserTablePanel *browser ) - { - m_pBrowser = browser; - - addInputSignal( new LabelSortInputHandler( (ServerBrowserTablePanel * )m_pBrowser, m_szSortKey ) ); - } -}; - -ServerBrowser::ServerBrowser(int x,int y,int wide,int tall) : CTransparentPanel( 100, x,y,wide,tall ) -{ - int i; - - _headerPanel = new HeaderPanel(0,0,wide,HEADER_SIZE_Y); - _headerPanel->setParent(this); - _headerPanel->setFgColor( 100,100,100, 100 ); - _headerPanel->setBgColor( 0, 0, 0, 100 ); - - CSBLabel *pLabel[5]; - - pLabel[0] = new CSBLabel( "Address", "address" ); - pLabel[1] = new CSBLabel( "Server", "hostname" ); - pLabel[2] = new CSBLabel( "Map", "map" ); - pLabel[3] = new CSBLabel( "Current", "current" ); - pLabel[4] = new CSBLabel( "Latency", "ping" ); - - for ( i = 0; i < 5; i++ ) - { - _headerPanel->addSectionPanel( pLabel[i] ); - } - - // _headerPanel->setFont( Scheme::sf_primary1 ); - - _headerPanel->setSliderPos( 0, CSIZE_ADDRESS ); - _headerPanel->setSliderPos( 1, CSIZE_SERVER ); - _headerPanel->setSliderPos( 2, CSIZE_MAP ); - _headerPanel->setSliderPos( 3, CSIZE_CURRENT ); - _headerPanel->setSliderPos( 4, CSIZE_PING ); - - _tablePanel = new ServerBrowserTablePanel( 0, HEADER_SIZE_Y, wide, tall - HEADER_SIZE_Y, NUM_COLUMNS ); - _tablePanel->setParent(this); - _tablePanel->setHeaderPanel(_headerPanel); - _tablePanel->setFgColor( 100,100,100, 100 ); - _tablePanel->setBgColor( 0, 0, 0, 100 ); - - _tablePanel->addInputSignal( new CBrowser_InputSignal( (ServerBrowserTablePanel *)_tablePanel ) ); - - for ( i = 0; i < 5; i++ ) - { - pLabel[i]->setTable( (ServerBrowserTablePanel * )_tablePanel ); - } - - int bw = 80, bh = 15; - int by = tall - HEADER_SIZE_Y; - - int btnx = 10; - - _connectButton = new CommandButton( "Connect", btnx, by, bw, bh ); - _connectButton->setParent( this ); - _connectButton->addActionSignal( new ConnectHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - btnx += bw; - - _refreshButton = new CommandButton( "Refresh", btnx, by, bw, bh ); - _refreshButton->setParent( this ); - _refreshButton->addActionSignal( new RefreshHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - /* - btnx += bw; - - _broadcastRefreshButton = new CommandButton( "LAN", btnx, by, bw, bh ); - _broadcastRefreshButton->setParent( this ); - _broadcastRefreshButton->addActionSignal( new BroadcastRefreshHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - */ - - btnx += bw; - - _stopButton = new CommandButton( "Stop", btnx, by, bw, bh ); - _stopButton->setParent( this ); - _stopButton->addActionSignal( new StopHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - /* - btnx += bw; - - _pingButton = new CommandButton( "Test", btnx, by, bw, bh ); - _pingButton->setParent( this ); - _pingButton->addActionSignal( new PingHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - btnx += bw; - - _sortButton = new CommandButton( "Sort", btnx, by, bw, bh ); - _sortButton->setParent( this ); - _sortButton->addActionSignal( new SortHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - */ - - btnx += bw; - - _cancelButton = new CommandButton( "Close", btnx, by, bw, bh ); - _cancelButton->setParent( this ); - _cancelButton->addActionSignal( new CancelHandler( (ServerBrowserTablePanel * )_tablePanel ) ); - - setPaintBorderEnabled(false); - setPaintBackgroundEnabled(false); - setPaintEnabled(false); -} - -void ServerBrowser::setSize(int wide,int tall) -{ - Panel::setSize(wide,tall); - - _headerPanel->setBounds(0,0,wide,HEADER_SIZE_Y); - _tablePanel->setBounds(0,HEADER_SIZE_Y,wide,tall - HEADER_SIZE_Y); - - _connectButton->setBounds( 5, tall - HEADER_SIZE_Y, 75, 15 ); - _refreshButton->setBounds( 85, tall - HEADER_SIZE_Y, 75, 15 ); - /* - _broadcastRefreshButton->setBounds( 165, tall - HEADER_SIZE_Y, 75, 15 ); - */ - _stopButton->setBounds( 165, tall - HEADER_SIZE_Y, 75, 15 ); - /* - _pingButton->setBounds( 325, tall - HEADER_SIZE_Y, 75, 15 ); - */ - _cancelButton->setBounds( 245, tall - HEADER_SIZE_Y, 75, 15 ); -} - -void CBrowser_InputSignal::mousePressed(MouseCode code,Panel* panel) -{ - int x, y; - int therow = 2; - - if ( code != MOUSE_LEFT ) - return; - - panel->getApp()->getCursorPos(x,y); - panel->screenToLocal( x, y ); - - therow = y / CELL_HEIGHT; - - // Figure out which row it's on - m_pBrowser->setMouseOverRow( therow ); -} - -void CBrowser_InputSignal::mouseDoublePressed(MouseCode code,Panel* panel) -{ - int x, y; - int therow = 2; - - if ( code != MOUSE_LEFT ) - return; - - panel->getApp()->getCursorPos(x,y); - panel->screenToLocal( x, y ); - - therow = y / CELL_HEIGHT; - - // Figure out which row it's on - m_pBrowser->setMouseOverRow( therow ); - m_pBrowser->DoConnect(); -} \ No newline at end of file diff --git a/ricochet/cl_dll/vgui_ServerBrowser.h b/ricochet/cl_dll/vgui_ServerBrowser.h deleted file mode 100644 index b826770..0000000 --- a/ricochet/cl_dll/vgui_ServerBrowser.h +++ /dev/null @@ -1,44 +0,0 @@ - -#ifndef ServerBrowser_H -#define ServerBrowser_H - -#include - -namespace vgui -{ -class Button; -class TablePanel; -class HeaderPanel; -} - -class CTransparentPanel; -class CommandButton; - -// Scoreboard positions -#define SB_X_INDENT (20 * ((float)ScreenHeight / 640)) -#define SB_Y_INDENT (20 * ((float)ScreenHeight / 480)) - -class ServerBrowser : public CTransparentPanel -{ -private: - HeaderPanel * _headerPanel; - TablePanel* _tablePanel; - - CommandButton* _connectButton; - CommandButton* _refreshButton; - CommandButton* _broadcastRefreshButton; - CommandButton* _stopButton; - CommandButton* _sortButton; - CommandButton* _cancelButton; - - CommandButton* _pingButton; - -public: - ServerBrowser(int x,int y,int wide,int tall); -public: - virtual void setSize(int wide,int tall); -}; - - - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/vgui_TeamFortressViewport.cpp b/ricochet/cl_dll/vgui_TeamFortressViewport.cpp deleted file mode 100644 index 2eac79b..0000000 --- a/ricochet/cl_dll/vgui_TeamFortressViewport.cpp +++ /dev/null @@ -1,2220 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Client DLL VGUI Viewport -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "parsemsg.h" -#include "keydefs.h" -#include "demo.h" -#include "demo_api.h" -#include "ammohistory.h" - -#include "vgui_int.h" -#include "vgui_TeamFortressViewport.h" -#include "vgui_ServerBrowser.h" -#include "vgui_ScorePanel.h" -#include "vgui_discobjects.h" - -extern WeaponsResource gWR; -extern int g_iVisibleMouse; -class CCommandMenu; -int g_iPlayerClass; -int g_iTeamNumber; -int g_iUser1; -int g_iUser2; - -// Scoreboard positions -#define SBOARD_INDENT_X XRES(104) -#define SBOARD_INDENT_Y YRES(40) - -// low-res scoreboard indents -#define SBOARD_INDENT_X_512 30 -#define SBOARD_INDENT_Y_512 30 - -#define SBOARD_INDENT_X_400 0 -#define SBOARD_INDENT_Y_400 20 - -void IN_ResetMouse( void ); -extern CMenuPanel *CMessageWindowPanel_Create( const char *szMOTD, const char *szTitle, int iShadeFullscreen, int iRemoveMe, int x, int y, int wide, int tall ); - -using namespace vgui; - -// Team Colors -int iTeamColors[5][3] = -{ - { 255, 255, 255 }, - { 66, 115, 247 }, - { 220, 51, 38 }, - { 240, 135, 0 }, - { 115, 240, 115 }, -}; - -// Used for Class specific buttons -char *sTFClasses[] = -{ - "", - "SCOUT", - "SNIPER", - "SOLDIER", - "DEMOMAN", - "MEDIC", - "HWGUY", - "PYRO", - "SPY", - "ENGINEER", - "CIVILIAN", -}; - -char *sLocalisedClasses[] = -{ - "#Civilian", - "#Scout", - "#Sniper", - "#Soldier", - "#Demoman", - "#Medic", - "#HWGuy", - "#Pyro", - "#Spy", - "#Engineer", - "#Random", - "#Civilian", -}; - -char *sTFClassSelection[] = -{ - "civilian", - "scout", - "sniper", - "soldier", - "demoman", - "medic", - "hwguy", - "pyro", - "spy", - "engineer", - "randompc", - "civilian", -}; - -int iBuildingCosts[] = -{ - BUILD_COST_DISPENSER, - BUILD_COST_SENTRYGUN -}; - -// This maps class numbers to the Invalid Class bit. -// This is needed for backwards compatability in maps that were finished before -// all the classes were in TF. Hence the wacky sequence. -int sTFValidClassInts[] = -{ - 0, - TF_ILL_SCOUT, - TF_ILL_SNIPER, - TF_ILL_SOLDIER, - TF_ILL_DEMOMAN, - TF_ILL_MEDIC, - TF_ILL_HVYWEP, - TF_ILL_PYRO, - TF_ILL_SPY, - TF_ILL_ENGINEER, - TF_ILL_RANDOMPC, -}; - -// Get the name of TGA file, based on GameDir -char* GetVGUITGAName(const char *pszName) -{ - int i; - char sz[256]; - static char gd[256]; - const char *gamedir; - - if (ScreenWidth < 640) - i = 320; - else - i = 640; - sprintf(sz, pszName, i); - - gamedir = gEngfuncs.pfnGetGameDirectory(); - sprintf(gd, "%s/gfx/vgui/%s.tga",gamedir,sz); - - return gd; -} - -//================================================================ -// COMMAND MENU -//================================================================ -void CCommandMenu::AddButton( CommandButton *pButton ) -{ - if (m_iButtons >= MAX_BUTTONS) - return; - - m_aButtons[m_iButtons] = pButton; - m_iButtons++; - pButton->setParent( this ); - pButton->setFont( Scheme::sf_primary3 ); - - // give the button a default key binding - if ( m_iButtons < 10 ) - { - pButton->setBoundKey( m_iButtons + '0' ); - } - else if ( m_iButtons == 10 ) - { - pButton->setBoundKey( '0' ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Tries to find a button that has a key bound to the input, and -// presses the button if found -// Input : keyNum - the character number of the input key -// Output : Returns true if the command menu should close, false otherwise -//----------------------------------------------------------------------------- -bool CCommandMenu::KeyInput( int keyNum ) -{ - // loop through all our buttons looking for one bound to keyNum - for ( int i = 0; i < m_iButtons; i++ ) - { - if ( !m_aButtons[i]->IsNotValid() ) - { - if ( m_aButtons[i]->getBoundKey() == keyNum ) - { - // hit the button - if ( m_aButtons[i]->GetSubMenu() ) - { - // open the sub menu - gViewPort->SetCurrentCommandMenu( m_aButtons[i]->GetSubMenu() ); - return false; - } - else - { - // run the bound command - m_aButtons[i]->fireActionSignal(); - return true; - } - } - } - } - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: clears the current menus buttons of any armed (highlighted) -// state, and all their sub buttons -//----------------------------------------------------------------------------- -void CCommandMenu::ClearButtonsOfArmedState( void ) -{ - for ( int i = 0; i < GetNumButtons(); i++ ) - { - m_aButtons[i]->setArmed( false ); - - if ( m_aButtons[i]->GetSubMenu() ) - { - m_aButtons[i]->GetSubMenu()->ClearButtonsOfArmedState(); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pSubMenu - -// Output : CommandButton -//----------------------------------------------------------------------------- -CommandButton *CCommandMenu::FindButtonWithSubmenu( CCommandMenu *pSubMenu ) -{ - for ( int i = 0; i < GetNumButtons(); i++ ) - { - if ( m_aButtons[i]->GetSubMenu() == pSubMenu ) - return m_aButtons[i]; - } - - return NULL; -} - -// Recalculate the visible buttons -bool CCommandMenu::RecalculateVisibles( int iNewYPos, bool bHideAll ) -{ - int iCurrentY = 0; - int iXPos, iYPos; - bool bHasButton = false; - - if (iNewYPos) - setPos( _pos[0], iNewYPos ); - - // Cycle through all the buttons in this menu, and see which will be visible - for (int i = 0; i < m_iButtons; i++) - { - int iClass = m_aButtons[i]->GetPlayerClass(); - if ( (iClass && iClass != g_iPlayerClass ) || ( m_aButtons[i]->IsNotValid() ) || bHideAll ) - { - m_aButtons[i]->setVisible( false ); - if ( m_aButtons[i]->GetSubMenu() != NULL ) - { - (m_aButtons[i]->GetSubMenu())->RecalculateVisibles( _pos[1] + iCurrentY, true ); - } - } - else - { - // If it's got a submenu, force it to check visibilities - if ( m_aButtons[i]->GetSubMenu() != NULL ) - { - if ( !(m_aButtons[i]->GetSubMenu())->RecalculateVisibles( _pos[1] + iCurrentY, false ) ) - { - // The submenu had no visible buttons, so don't display this button - m_aButtons[i]->setVisible( false ); - continue; - } - } - - m_aButtons[i]->setVisible( true ); - - // Make sure it's at the right Y position - m_aButtons[i]->getPos( iXPos, iYPos ); - m_aButtons[i]->setPos( iXPos, iCurrentY ); - - iCurrentY += BUTTON_SIZE_Y - 1; - bHasButton = true; - } - } - - // Set Size - setSize( _size[0], iCurrentY + 1 ); - - return bHasButton; -} - -// Make sure all submenus can fit on the screen -void CCommandMenu::RecalculatePositions( int iYOffset ) -{ - int iNewYPos = _pos[1] + iYOffset; - int iAdjust = 0; - - // Calculate if this is going to fit onscreen, and shuffle it up if it won't - int iBottom = iNewYPos + _size[1]; - if ( iBottom > ScreenHeight ) - { - // Move in increments of button sizes - while (iAdjust < (iBottom - ScreenHeight)) - { - iAdjust += BUTTON_SIZE_Y - 1; - } - iNewYPos -= iAdjust; - - // Make sure it doesn't move off the top of the screen (the menu's too big to fit it all) - if ( iNewYPos < 0 ) - { - iAdjust -= (0 - iNewYPos); - iNewYPos = 0; - } - } - - // We need to force all menus below this one to update their positions now, because they - // might have submenus riding off buttons in this menu that have just shifted. - for (int i = 0; i < m_iButtons; i++) - m_aButtons[i]->UpdateSubMenus( iAdjust ); - - setPos( _pos[0], iNewYPos ); -} - - -// Make this menu and all menus above it in the chain visible -void CCommandMenu::MakeVisible( CCommandMenu *pChildMenu ) -{ -/* - // Push down the button leading to the child menu - for (int i = 0; i < m_iButtons; i++) - { - if ( (pChildMenu != NULL) && (m_aButtons[i]->GetSubMenu() == pChildMenu) ) - { - m_aButtons[i]->setArmed( true ); - } - else - { - m_aButtons[i]->setArmed( false ); - } - } -*/ - - setVisible(true); - if (m_pParentMenu) - m_pParentMenu->MakeVisible( this ); -} - -//================================================================ -// CreateSubMenu -CCommandMenu *TeamFortressViewport::CreateSubMenu( CommandButton *pButton, CCommandMenu *pParentMenu ) -{ - int iXPos = 0; - int iYPos = 0; - int iWide = CMENU_SIZE_X; - int iTall = 0; - - if (pParentMenu) - { - iXPos = pParentMenu->GetXOffset() + CMENU_SIZE_X - 1; - iYPos = pParentMenu->GetYOffset() + BUTTON_SIZE_Y * (m_pCurrentCommandMenu->GetNumButtons() - 1); - } - - CCommandMenu *pMenu = new CCommandMenu(pParentMenu, iXPos, iYPos, iWide, iTall ); - pMenu->setParent(this); - pButton->AddSubMenu( pMenu ); - pButton->setFont( Scheme::sf_primary3 ); - - // Create the Submenu-open signal - InputSignal *pISignal = new CMenuHandler_PopupSubMenuInput(pButton, pMenu); - pButton->addInputSignal(pISignal); - - // Put a > to show it's a submenu - CImageLabel *pLabel = new CImageLabel( "arrow", CMENU_SIZE_X - SUBMENU_SIZE_X, SUBMENU_SIZE_Y ); - pLabel->setParent(pButton); - pLabel->addInputSignal(pISignal); - - // Reposition - pLabel->getPos( iXPos, iYPos ); - pLabel->setPos( CMENU_SIZE_X - pLabel->getImageWide(), (BUTTON_SIZE_Y - pLabel->getImageTall()) / 2 ); - - // Create the mouse off signal for the Label too - if (!pButton->m_bNoHighlight) - pLabel->addInputSignal( new CHandler_CommandButtonHighlight(pButton) ); - - return pMenu; -} - -//----------------------------------------------------------------------------- -// Purpose: Makes sure the memory allocated for TeamFortressViewport is nulled out -// Input : stAllocateBlock - -// Output : void * -//----------------------------------------------------------------------------- -void *TeamFortressViewport::operator new( size_t stAllocateBlock ) -{ -// void *mem = Panel::operator new( stAllocateBlock ); - void *mem = ::operator new( stAllocateBlock ); - memset( mem, 0, stAllocateBlock ); - return mem; -} - -//----------------------------------------------------------------------------- -// Purpose: InputSignal handler for the main viewport -//----------------------------------------------------------------------------- -class CViewPortInputHandler : public InputSignal -{ -public: - bool bPressed; - - CViewPortInputHandler() - { - } - - virtual void cursorMoved(int x,int y,Panel* panel) {} - virtual void cursorEntered(Panel* panel) {} - virtual void cursorExited(Panel* panel) {} - virtual void mousePressed(MouseCode code,Panel* panel) - { - if ( code != MOUSE_LEFT ) - { - // send a message to close the command menu - // this needs to be a message, since a direct call screws the timing - gEngfuncs.pfnClientCmd( "ForceCloseCommandMenu\n" ); - } - } - virtual void mouseReleased(MouseCode code,Panel* panel) - { - } - - virtual void mouseDoublePressed(MouseCode code,Panel* panel) {} - virtual void mouseWheeled(int delta,Panel* panel) {} - virtual void keyPressed(KeyCode code,Panel* panel) {} - virtual void keyTyped(KeyCode code,Panel* panel) {} - virtual void keyReleased(KeyCode code,Panel* panel) {} - virtual void keyFocusTicked(Panel* panel) {} -}; - - -//================================================================ -TeamFortressViewport::TeamFortressViewport(int x,int y,int wide,int tall) : Panel(x,y,wide,tall), m_SchemeManager(wide,tall) -{ - gViewPort = this; - m_iInitialized = false; - m_pScoreBoard = NULL; - m_pSpectatorMenu = NULL; - m_pCurrentMenu = NULL; - m_pCurrentCommandMenu = NULL; - - CVAR_CREATE( "hud_classautokill", "1", FCVAR_ARCHIVE ); // controls whether or not to suicide immediately on TF class switch - CVAR_CREATE( "hud_takesshots", "0", FCVAR_ARCHIVE ); // controls whether or not to automatically take screenshots at the end of a round - - Initialize(); - addInputSignal( new CViewPortInputHandler ); - - int r, g, b, a; - - Scheme* pScheme = App::getInstance()->getScheme(); - - // primary text color - // Get the colors - //!! two different types of scheme here, need to integrate - SchemeHandle_t hPrimaryScheme = m_SchemeManager.getSchemeHandle( "Primary Button Text" ); - { - // font - pScheme->setFont( Scheme::sf_primary1, m_SchemeManager.getFont(hPrimaryScheme) ); - - // text color - m_SchemeManager.getFgColor( hPrimaryScheme, r, g, b, a ); - pScheme->setColor(Scheme::sc_primary1, r, g, b, a ); // sc_primary1 is non-transparent orange - - // background color (transparent black) - m_SchemeManager.getBgColor( hPrimaryScheme, r, g, b, a ); - pScheme->setColor(Scheme::sc_primary3, r, g, b, a ); - - // armed foreground color - m_SchemeManager.getFgArmedColor( hPrimaryScheme, r, g, b, a ); - pScheme->setColor(Scheme::sc_secondary2, r, g, b, a ); - - // armed background color - m_SchemeManager.getBgArmedColor( hPrimaryScheme, r, g, b, a ); - pScheme->setColor(Scheme::sc_primary2, r, g, b, a ); - - //!! need to get this color from scheme file - // used for orange borders around buttons - m_SchemeManager.getBorderColor( hPrimaryScheme, r, g, b, a ); - // pScheme->setColor(Scheme::sc_secondary1, r, g, b, a ); - pScheme->setColor(Scheme::sc_secondary1, 255*0.7, 170*0.7, 0, 0); - } - - // Change the second primary font (used in the scoreboard) - SchemeHandle_t hScoreboardScheme = m_SchemeManager.getSchemeHandle( "Scoreboard Text" ); - { - pScheme->setFont(Scheme::sf_primary2, m_SchemeManager.getFont(hScoreboardScheme) ); - } - - // Change the third primary font (used in command menu) - SchemeHandle_t hCommandMenuScheme = m_SchemeManager.getSchemeHandle( "CommandMenu Text" ); - { - pScheme->setFont(Scheme::sf_primary3, m_SchemeManager.getFont(hCommandMenuScheme) ); - } - - App::getInstance()->setScheme(pScheme); - - // VGUI MENUS - CreateScoreBoard(); - CreateCommandMenu(); - CreateServerBrowser(); - CreateSpectatorMenu(); - - // Discwar - CreateDiscIcons(); -} - -//----------------------------------------------------------------------------- -// Purpose: Called everytime a new level is started. Viewport clears out it's data. -//----------------------------------------------------------------------------- -void TeamFortressViewport::Initialize( void ) -{ - // Force each menu to Initialize - if (m_pScoreBoard) - { - m_pScoreBoard->Initialize(); - HideScoreBoard(); - } - if (m_pSpectatorMenu) - { - // Spectator menu doesn't need initializing - m_pSpectatorMenu->setVisible( false ); - } - - // Make sure all menus are hidden - HideVGUIMenu(); - HideCommandMenu(); - - // Clear out some data - m_iGotAllMOTD = true; - m_iRandomPC = false; - m_flScoreBoardLastUpdated = 0; - - // reset player info - g_iPlayerClass = 0; - g_iTeamNumber = 0; - - strcpy(m_sMapName, ""); - strcpy(m_szServerName, ""); - for (int i = 0; i < 5; i++) - { - m_iValidClasses[i] = 0; - strcpy(m_sTeamNames[i], ""); - } - - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_none) ); -} - -class CException; -//----------------------------------------------------------------------------- -// Purpose: Read the Command Menu structure from the txt file and create the menu. -//----------------------------------------------------------------------------- -void TeamFortressViewport::CreateCommandMenu( void ) -{ - // COMMAND MENU - // Create the root of the Command Menu - m_pCommandMenus[0] = new CCommandMenu(NULL, 0, CMENU_TOP, CMENU_SIZE_X, 300); // This will be resized once we know how many items are in it - m_pCommandMenus[0]->setParent(this); - m_pCommandMenus[0]->setVisible(false); - m_iNumMenus = 1; - m_iCurrentTeamNumber = m_iUser1 = m_iUser2 = 0; - - // Read Command Menu from the txt file - char token[1024]; - char *pfile = (char*)gEngfuncs.COM_LoadFile("commandmenu.txt", 5, NULL); - if (!pfile) - { - gEngfuncs.Con_DPrintf( "Unable to open commandmenu.txt\n"); - SetCurrentCommandMenu( NULL ); - return; - } - -#ifdef _WIN32 -try -{ -#endif - // First, read in the localisation strings - - // Detpack strings - gHUD.m_TextMessage.LocaliseTextString( "#DetpackSet_For5Seconds", m_sDetpackStrings[0], MAX_BUTTON_SIZE ); - gHUD.m_TextMessage.LocaliseTextString( "#DetpackSet_For20Seconds", m_sDetpackStrings[1], MAX_BUTTON_SIZE ); - gHUD.m_TextMessage.LocaliseTextString( "#DetpackSet_For50Seconds", m_sDetpackStrings[2], MAX_BUTTON_SIZE ); - - // Now start parsing the menu structure - m_pCurrentCommandMenu = m_pCommandMenus[0]; - char szLastButtonText[32] = "file start"; - pfile = gEngfuncs.COM_ParseFile(pfile, token); - while ( ( strlen ( token ) > 0 ) && ( m_iNumMenus < MAX_MENUS ) ) - { - // Keep looping until we hit the end of this menu - while ( token[0] != '}' && ( strlen( token ) > 0 ) ) - { - char cText[32] = ""; - char cBoundKey[32] = ""; - char cCustom[32] = ""; - static const int cCommandLength = 128; - char cCommand[cCommandLength] = ""; - char szMap[MAX_MAPNAME] = ""; - int iPlayerClass = 0; - int iCustom = false; - int iTeamOnly = 0; - bool bGetExtraToken = true; - CommandButton *pButton = NULL; - - // We should never be here without a Command Menu - if (!m_pCurrentCommandMenu) - { - gEngfuncs.Con_Printf("Error in Commandmenu.txt file after '%s'.\n", szLastButtonText ); - m_iInitialized = false; - return; - } - - // token should already be the bound key, or the custom name - strncpy( cCustom, token, 32 ); - cCustom[31] = '\0'; - - // See if it's a custom button - if (!strcmp(cCustom, "CUSTOM") ) - { - iCustom = true; - - // Get the next token - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } - // See if it's a map - else if (!strcmp(cCustom, "MAP") ) - { - // Get the mapname - pfile = gEngfuncs.COM_ParseFile(pfile, token); - strncpy( szMap, token, MAX_MAPNAME ); - szMap[MAX_MAPNAME-1] = '\0'; - - // Get the next token - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } - else if ( !strncmp(cCustom, "TEAM", 4) ) // TEAM1, TEAM2, TEAM3, TEAM4 - { - // make it a team only button - iTeamOnly = atoi( cCustom + 4 ); - - // Get the next token - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } - else - { - // See if it's a Class - for (int i = 1; i <= PC_ENGINEER; i++) - { - if ( !strcmp(token, sTFClasses[i]) ) - { - // Save it off - iPlayerClass = i; - - // Get the button text - pfile = gEngfuncs.COM_ParseFile(pfile, token); - break; - } - } - } - - // Get the button bound key - strncpy( cBoundKey, token, 32 ); - cText[31] = '\0'; - - // Get the button text - pfile = gEngfuncs.COM_ParseFile(pfile, token); - strncpy( cText, token, 32 ); - cText[31] = '\0'; - - // save off the last button text we've come across (for error reporting) - strcpy( szLastButtonText, cText ); - - // Get the button command - pfile = gEngfuncs.COM_ParseFile(pfile, token); - strncpy( cCommand, token, cCommandLength ); - cCommand[cCommandLength - 1] = '\0'; - - // Custom button handling - if ( iCustom ) - { - pButton = CreateCustomButton( cText, cCommand ); - - // Get the next token to see if we're a menu - pfile = gEngfuncs.COM_ParseFile(pfile, token); - - if ( token[0] == '{' ) - { - strcpy( cCommand, token ); - } - else - { - bGetExtraToken = false; - } - } - else if ( szMap[0] != '\0' ) - { - // create a map button - pButton = new MapButton(szMap, cText,0, BUTTON_SIZE_Y * m_pCurrentCommandMenu->GetNumButtons(), CMENU_SIZE_X, BUTTON_SIZE_Y); - } - else if ( iTeamOnly ) - { - // button that only shows up if the player is on team iTeamOnly - pButton = new TeamOnlyCommandButton( iTeamOnly, cText,0, BUTTON_SIZE_Y * m_pCurrentCommandMenu->GetNumButtons(), CMENU_SIZE_X, BUTTON_SIZE_Y ); - } - else - { - // normal button - pButton = new CommandButton( iPlayerClass, cText,0, BUTTON_SIZE_Y * m_pCurrentCommandMenu->GetNumButtons(), CMENU_SIZE_X, BUTTON_SIZE_Y ); - } - - // add the button into the command menu - if ( pButton ) - { - m_pCurrentCommandMenu->AddButton( pButton ); - pButton->setBoundKey( cBoundKey[0] ); - pButton->setParentMenu( m_pCurrentCommandMenu ); - - // Override font in CommandMenu - pButton->setFont( Scheme::sf_primary3 ); - } - - // Find out if it's a submenu or a button we're dealing with - if ( cCommand[0] == '{' ) - { - if ( m_iNumMenus >= MAX_MENUS ) - { - gEngfuncs.Con_Printf( "Too many menus in commandmenu.txt past '%s'\n", szLastButtonText ); - } - else - { - // Create the menu - m_pCommandMenus[m_iNumMenus] = CreateSubMenu(pButton, m_pCurrentCommandMenu); - m_pCurrentCommandMenu = m_pCommandMenus[m_iNumMenus]; - m_iNumMenus++; - } - } - else if ( !iCustom ) - { - // Create the button and attach it to the current menu - pButton->addActionSignal(new CMenuHandler_StringCommand(cCommand)); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - - // Get the next token - if ( bGetExtraToken ) - { - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } - } - - // Move back up a menu - m_pCurrentCommandMenu = m_pCurrentCommandMenu->GetParentMenu(); - - pfile = gEngfuncs.COM_ParseFile(pfile, token); - } -#ifdef _WIN32 -} -catch( CException *e ) -{ - e; - //e->Delete(); - e = NULL; - m_iInitialized = false; - return; -} -#endif - - SetCurrentMenu( NULL ); - SetCurrentCommandMenu( NULL ); - gEngfuncs.COM_FreeFile( pfile ); - - m_iInitialized = true; -} - -//----------------------------------------------------------------------------- -// Purpose: Creates all the class choices under a spy's disguise menus, and -// maps a command to them -// Output : CCommandMenu -//----------------------------------------------------------------------------- -CCommandMenu *TeamFortressViewport::CreateDisguiseSubmenu( CommandButton *pButton, CCommandMenu *pParentMenu, const char *commandText ) -{ - // create the submenu, under which the class choices will be listed - CCommandMenu *pMenu = CreateSubMenu( pButton, pParentMenu ); - m_pCommandMenus[m_iNumMenus] = pMenu; - m_iNumMenus++; - - // create the class choice buttons - for ( int i = PC_SCOUT; i <= PC_ENGINEER; i++ ) - { - CommandButton *pDisguiseButton = new CommandButton( CHudTextMessage::BufferedLocaliseTextString( sLocalisedClasses[i] ), 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y ); - - char sz[256]; - sprintf(sz, "%s %d", commandText, i ); - pDisguiseButton->addActionSignal(new CMenuHandler_StringCommand(sz)); - - pMenu->AddButton( pDisguiseButton ); - } - - return pMenu; -} - -//----------------------------------------------------------------------------- -// Purpose: -// Input : *pButtonText - -// *pButtonName - -// Output : CommandButton -//----------------------------------------------------------------------------- -CommandButton *TeamFortressViewport::CreateCustomButton( char *pButtonText, char *pButtonName ) -{ - CommandButton *pButton = NULL; - CCommandMenu *pMenu = NULL; - - // ChangeTeam - if ( !strcmp( pButtonName, "!CHANGETEAM" ) ) - { - // ChangeTeam Submenu - pButton = new CommandButton(pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - - // Create the submenu - pMenu = CreateSubMenu(pButton, m_pCurrentCommandMenu); - m_pCommandMenus[m_iNumMenus] = pMenu; - m_iNumMenus++; - - // ChangeTeam buttons - for (int i = 0; i < 4; i++) - { - char sz[256]; - sprintf(sz, "jointeam %d", i+1); - m_pTeamButtons[i] = new TeamButton(i+1, "teamname", 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - m_pTeamButtons[i]->addActionSignal(new CMenuHandler_StringCommandWatch( sz )); - pMenu->AddButton( m_pTeamButtons[i] ); - } - - // Auto Assign button - m_pTeamButtons[4] = new TeamButton(5, gHUD.m_TextMessage.BufferedLocaliseTextString( "#Team_AutoAssign" ), 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - m_pTeamButtons[4]->addActionSignal(new CMenuHandler_StringCommand( "jointeam 5" )); - pMenu->AddButton( m_pTeamButtons[4] ); - - // Spectate button - m_pTeamButtons[5] = new SpectateButton( CHudTextMessage::BufferedLocaliseTextString( "#Menu_Spectate" ), 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y, false); - m_pTeamButtons[5]->addActionSignal(new CMenuHandler_StringCommand( "spectate" )); - pMenu->AddButton( m_pTeamButtons[5] ); - } - // ChangeClass - else if ( !strcmp( pButtonName, "!CHANGECLASS" ) ) - { - // Create the Change class menu - pButton = new ClassButton(-1, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y, false); - - // ChangeClass Submenu - pMenu = CreateSubMenu(pButton, m_pCurrentCommandMenu); - m_pCommandMenus[m_iNumMenus] = pMenu; - m_iNumMenus++; - - for (int i = PC_SCOUT; i <= PC_RANDOM; i++ ) - { - char sz[256]; - - // ChangeClass buttons - CHudTextMessage::LocaliseTextString( sLocalisedClasses[i], sz, 256 ); - ClassButton *pClassButton = new ClassButton( i, sz, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y, false); - - sprintf(sz, "%s", sTFClassSelection[i]); - pClassButton->addActionSignal(new CMenuHandler_StringCommandClassSelect(sz)); - pMenu->AddButton( pClassButton ); - } - } - // Map Briefing - else if ( !strcmp( pButtonName, "!MAPBRIEFING" ) ) - { - pButton = new CommandButton(pButtonText, 0, BUTTON_SIZE_Y * m_pCurrentCommandMenu->GetNumButtons(), CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_TextWindow(MENU_MAPBRIEFING)); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - // Class Descriptions - else if ( !strcmp( pButtonName, "!CLASSDESC" ) ) - { - pButton = new ClassButton(0, pButtonText, 0, BUTTON_SIZE_Y * m_pCurrentCommandMenu->GetNumButtons(), CMENU_SIZE_X, BUTTON_SIZE_Y, false); - pButton->addActionSignal(new CMenuHandler_TextWindow(MENU_CLASSHELP)); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - else if ( !strcmp( pButtonName, "!SERVERINFO" ) ) - { - pButton = new ClassButton(0, pButtonText, 0, BUTTON_SIZE_Y * m_pCurrentCommandMenu->GetNumButtons(), CMENU_SIZE_X, BUTTON_SIZE_Y, false); - pButton->addActionSignal(new CMenuHandler_TextWindow(MENU_INTRO)); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - // Spy abilities - else if ( !strcmp( pButtonName, "!SPY" ) ) - { - pButton = new DisguiseButton( 0, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y ); - } - // Feign - else if ( !strcmp( pButtonName, "!FEIGN" ) ) - { - pButton = new FeignButton(FALSE, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand( "feign" )); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - // Feign Silently - else if ( !strcmp( pButtonName, "!FEIGNSILENT" ) ) - { - pButton = new FeignButton(FALSE, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand( "sfeign" )); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - // Stop Feigning - else if ( !strcmp( pButtonName, "!FEIGNSTOP" ) ) - { - pButton = new FeignButton(TRUE, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand( "feign" )); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - // Disguise - else if ( !strcmp( pButtonName, "!DISGUISEENEMY" ) ) - { - // Create the disguise enemy button, which active only if there are 2 teams - pButton = new DisguiseButton(DISGUISE_TEAM2, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - CreateDisguiseSubmenu( pButton, m_pCurrentCommandMenu, "disguise_enemy" ); - } - else if ( !strcmp( pButtonName, "!DISGUISEFRIENDLY" ) ) - { - // Create the disguise friendly button, which active only if there are 1 or 2 teams - pButton = new DisguiseButton(DISGUISE_TEAM1 | DISGUISE_TEAM2, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - CreateDisguiseSubmenu( pButton, m_pCurrentCommandMenu, "disguise_friendly" ); - } - else if ( !strcmp( pButtonName, "!DISGUISE" ) ) - { - // Create the Disguise button - pButton = new DisguiseButton( DISGUISE_TEAM3 | DISGUISE_TEAM4, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - CCommandMenu *pDisguiseMenu = CreateSubMenu( pButton, m_pCurrentCommandMenu ); - m_pCommandMenus[m_iNumMenus] = pDisguiseMenu; - m_iNumMenus++; - - // Disguise Enemy submenu buttons - for ( int i = 1; i <= 4; i++ ) - { - // only show the 4th disguise button if we have 4 teams - m_pDisguiseButtons[i] = new DisguiseButton( ((i < 4) ? DISGUISE_TEAM3 : 0) | DISGUISE_TEAM4, "Disguise", 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - - pDisguiseMenu->AddButton( m_pDisguiseButtons[i] ); - - char sz[256]; - sprintf( sz, "disguise %d", i ); - CreateDisguiseSubmenu( m_pDisguiseButtons[i], pDisguiseMenu, sz ); - } - } - // Start setting a Detpack - else if ( !strcmp( pButtonName, "!DETPACKSTART" ) ) - { - // Detpack Submenu - pButton = new DetpackButton(2, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - - // Create the submenu - pMenu = CreateSubMenu(pButton, m_pCurrentCommandMenu); - m_pCommandMenus[m_iNumMenus] = pMenu; - m_iNumMenus++; - - // Set detpack buttons - CommandButton *pDetButton; - pDetButton = new CommandButton(m_sDetpackStrings[0], 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - pDetButton->addActionSignal(new CMenuHandler_StringCommand("detstart 5")); - pMenu->AddButton( pDetButton ); - pDetButton = new CommandButton(m_sDetpackStrings[1], 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - pDetButton->addActionSignal(new CMenuHandler_StringCommand("detstart 20")); - pMenu->AddButton( pDetButton ); - pDetButton = new CommandButton(m_sDetpackStrings[2], 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - pDetButton->addActionSignal(new CMenuHandler_StringCommand("detstart 50")); - pMenu->AddButton( pDetButton ); - } - // Stop setting a Detpack - else if ( !strcmp( pButtonName, "!DETPACKSTOP" ) ) - { - pButton = new DetpackButton(1, pButtonText, 0, BUTTON_SIZE_Y, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand( "detstop" )); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - // Engineer building - else if ( !strcmp( pButtonName, "!BUILD" ) ) - { - // only appears if the player is an engineer, and either they have built something or have enough metal to build - pButton = new BuildButton( BUILDSTATE_BASE, 0, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - } - else if ( !strcmp( pButtonName, "!BUILDSENTRY" ) ) - { - pButton = new BuildButton( BUILDSTATE_CANBUILD, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand("build 2")); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - else if ( !strcmp( pButtonName, "!BUILDDISPENSER" ) ) - { - pButton = new BuildButton( BUILDSTATE_CANBUILD, BuildButton::DISPENSER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand("build 1")); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - else if ( !strcmp( pButtonName, "!ROTATESENTRY180" ) ) - { - pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand("rotatesentry180")); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - else if ( !strcmp( pButtonName, "!ROTATESENTRY" ) ) - { - pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand("rotatesentry")); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - else if ( !strcmp( pButtonName, "!DISMANTLEDISPENSER" ) ) - { - pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::DISPENSER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand("dismantle 1")); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - else if ( !strcmp( pButtonName, "!DISMANTLESENTRY" ) ) - { - pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand("dismantle 2")); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - else if ( !strcmp( pButtonName, "!DETONATEDISPENSER" ) ) - { - pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::DISPENSER, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand("detdispenser")); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - else if ( !strcmp( pButtonName, "!DETONATESENTRY" ) ) - { - pButton = new BuildButton( BUILDSTATE_HASBUILDING, BuildButton::SENTRYGUN, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand("detsentry")); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - // Stop building - else if ( !strcmp( pButtonName, "!BUILDSTOP" ) ) - { - pButton = new BuildButton( BUILDSTATE_BUILDING, 0, pButtonText, 0, BUTTON_SIZE_Y * 2, CMENU_SIZE_X, BUTTON_SIZE_Y); - pButton->addActionSignal(new CMenuHandler_StringCommand("build")); - // Create an input signal that'll popup the current menu - pButton->addInputSignal( new CMenuHandler_PopupSubMenuInput(pButton, m_pCurrentCommandMenu) ); - } - - return pButton; -} - -void TeamFortressViewport::ToggleServerBrowser() -{ - if (!m_iInitialized) - return; - - if ( !m_pServerBrowser ) - return; - - if ( m_pServerBrowser->isVisible() ) - { - m_pServerBrowser->setVisible( false ); - } - else - { - m_pServerBrowser->setVisible( true ); - } - - UpdateCursorState(); -} - -//======================================================================= -void TeamFortressViewport::ShowCommandMenu() -{ - if (!m_iInitialized) - return; - - // Not visible while undefined - if (g_iPlayerClass == 0) - return; - - // is the command menu open? - if ( m_pCurrentCommandMenu ) - { - HideCommandMenu(); - return; - } - - // Not visible while in intermission - if ( gHUD.m_iIntermission ) - return; - - // Recalculate visible menus - UpdateCommandMenu(); - HideVGUIMenu(); - - SetCurrentCommandMenu( m_pCommandMenus[0] ); - m_flMenuOpenTime = gHUD.m_flTime; - UpdateCursorState(); - - // get command menu parameters - for ( int i = 2; i < gEngfuncs.Cmd_Argc(); i++ ) - { - const char *param = gEngfuncs.Cmd_Argv( i - 1 ); - if ( param ) - { - if ( m_pCurrentCommandMenu->KeyInput(param[0]) ) - { - // kill the menu open time, since the key input is final - HideCommandMenu(); - } - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Handles the key input of "-commandmenu" -// Input : -//----------------------------------------------------------------------------- -void TeamFortressViewport::InputSignalHideCommandMenu() -{ - if (!m_iInitialized) - return; - - // if they've just tapped the command menu key, leave it open - if ( (m_flMenuOpenTime + 0.3) > gHUD.m_flTime ) - return; - - HideCommandMenu(); -} - -//----------------------------------------------------------------------------- -// Purpose: Hides the command menu -//----------------------------------------------------------------------------- -void TeamFortressViewport::HideCommandMenu( void ) -{ - if (!m_iInitialized) - return; - - if ( m_pCommandMenus[0] ) - { - m_pCommandMenus[0]->ClearButtonsOfArmedState(); - } - - m_flMenuOpenTime = 0.0f; - SetCurrentCommandMenu( NULL ); - UpdateCursorState(); -} - -//----------------------------------------------------------------------------- -// Purpose: Bring up the scoreboard -//----------------------------------------------------------------------------- -void TeamFortressViewport::ShowScoreBoard( void ) -{ - if (m_pScoreBoard) - { - // No Scoreboard in single-player - if ( gEngfuncs.GetMaxClients() > 1 ) - { - m_pScoreBoard->Open(); - UpdateCursorState(); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Returns true if the scoreboard is up -//----------------------------------------------------------------------------- -bool TeamFortressViewport::IsScoreBoardVisible( void ) -{ - if (m_pScoreBoard) - return m_pScoreBoard->isVisible(); - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: Hide the scoreboard -//----------------------------------------------------------------------------- -void TeamFortressViewport::HideScoreBoard( void ) -{ - // Prevent removal of scoreboard during intermission - if ( gHUD.m_iIntermission ) - return; - - if (m_pScoreBoard) - { - m_pScoreBoard->setVisible(false); - - GetClientVoiceMgr()->StopSquelchMode(); - - UpdateCursorState(); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Activate's the player special ability -// called when the player hits their "special" key -//----------------------------------------------------------------------------- -void TeamFortressViewport::InputPlayerSpecial( void ) -{ - if (!m_iInitialized) - return; - - if ( g_iPlayerClass == PC_ENGINEER || g_iPlayerClass == PC_SPY ) - { - ShowCommandMenu(); - - if ( m_pCurrentCommandMenu ) - { - m_pCurrentCommandMenu->KeyInput( '7' ); - } - } - else - { - // if it's any other class, just send the command down to the server - ClientCmd( "_special" ); - } -} - -// Set the submenu of the Command Menu -void TeamFortressViewport::SetCurrentCommandMenu( CCommandMenu *pNewMenu ) -{ - for (int i = 0; i < m_iNumMenus; i++) - m_pCommandMenus[i]->setVisible(false); - - m_pCurrentCommandMenu = pNewMenu; - - if (m_pCurrentCommandMenu) - m_pCurrentCommandMenu->MakeVisible( NULL ); -} - -void TeamFortressViewport::UpdateCommandMenu() -{ - m_pCommandMenus[0]->RecalculateVisibles( 0, false ); - m_pCommandMenus[0]->RecalculatePositions( 0 ); -} - -void TeamFortressViewport::UpdateSpectatorMenu() -{ - char sz[64]; - - if (!m_pSpectatorMenu) - return; - - // Don't pop up if the round windows are up - if ( m_pDiscStartRound && m_pDiscStartRound->isVisible() ) - return; - if ( m_pDiscEndRound && m_pDiscEndRound->isVisible() ) - return; - - if (m_iUser1) - { - m_pSpectatorMenu->setVisible( true ); - - if (m_iUser2 > 0 && m_iUser1 != 4 ) - { - // Locked onto a target, show the player's name - sprintf(sz, "#Spec_Mode%d : %s", m_iUser1, g_PlayerInfoList[ m_iUser2 ].name); - m_pSpectatorLabel->setText( CHudTextMessage::BufferedLocaliseTextString( sz ) ); - } - else - { - sprintf(sz, "#Spec_Mode%d", m_iUser1); - m_pSpectatorLabel->setText( CHudTextMessage::BufferedLocaliseTextString( sz ) ); - } - } - else - { - m_pSpectatorMenu->setVisible( false ); - } -} - -//====================================================================== -void TeamFortressViewport::CreateScoreBoard( void ) -{ - m_pScoreBoard = new ScorePanel(SBOARD_INDENT_X,SBOARD_INDENT_Y, ScreenWidth - (SBOARD_INDENT_X * 2), ScreenHeight - (SBOARD_INDENT_Y * 2)); - m_pScoreBoard->setParent(this); - m_pScoreBoard->setVisible(false); -} - -void TeamFortressViewport::CreateServerBrowser( void ) -{ - m_pServerBrowser = new ServerBrowser( 0, 0, ScreenWidth, ScreenHeight ); - m_pServerBrowser->setParent(this); - m_pServerBrowser->setVisible(false); -} - -//====================================================================== -// Disc vgui objects -void TeamFortressViewport::CreateDiscIcons( void ) -{ - m_iDiscPowerup = 0; - - // Create the disc ammo icons - int iX = (ScreenWidth - DISC_ICON_WIDTH) / 2; - int iXPos = iX - DISC_ICON_SPACER; - for (int i = 0; i < MAX_DISCS; i++) - { - m_pDiscIcons[i] = new CDiscPanel( iXPos + (i * DISC_ICON_SPACER), ScreenHeight - YRES(48), DISC_ICON_WIDTH, YRES(32) ); - m_pDiscIcons[i]->setParent(this); - } - - // Create the Arena Windows - m_pDiscStartRound = new CDiscArena_RoundStart(); - m_pDiscStartRound->setParent(this); - m_pDiscEndRound = new CDiscArena_RoundEnd(); - m_pDiscEndRound->setParent(this); - - // Create the Powerup window - m_pDiscPowerupWindow = new CDiscPowerups(); - m_pDiscPowerupWindow->setParent(this); - - // Create the Reward window - m_pDiscRewardWindow = new CDiscRewards(); - m_pDiscRewardWindow->setParent(this); -} - -//====================================================================== -// Set the VGUI Menu -void TeamFortressViewport::SetCurrentMenu( CMenuPanel *pMenu ) -{ - m_pCurrentMenu = pMenu; - if ( m_pCurrentMenu ) - { - // Don't open menus in demo playback - if ( gEngfuncs.pDemoAPI->IsPlayingback() ) - return; - - m_pCurrentMenu->Open(); - } -} - -//================================================================ -// Text Window -CMenuPanel* TeamFortressViewport::CreateTextWindow( int iTextToShow ) -{ - char sz[256]; - char *cText; - char *pfile = NULL; - static const int MAX_TITLE_LENGTH = 32; - char cTitle[MAX_TITLE_LENGTH]; - - if ( iTextToShow == SHOW_MOTD ) - { - if (!m_szServerName || !m_szServerName[0]) - strcpy( cTitle, "Half-Life" ); - else - strncpy( cTitle, m_szServerName, MAX_TITLE_LENGTH ); - cTitle[MAX_TITLE_LENGTH-1] = 0; - cText = m_szMOTD; - } - else if ( iTextToShow == SHOW_MAPBRIEFING ) - { - // Get the current mapname, and open it's map briefing text - if (m_sMapName && m_sMapName[0]) - { - strcpy( sz, "maps/"); - strcat( sz, m_sMapName ); - strcat( sz, ".txt" ); - } - else - { - const char *level = gEngfuncs.pfnGetLevelName(); - if (!level) - return NULL; - - strcpy( sz, level ); - char *ch = strchr( sz, '.' ); - *ch = '\0'; - strcat( sz, ".txt" ); - - // pull out the map name - strcpy( m_sMapName, level ); - ch = strchr( m_sMapName, '.' ); - if ( ch ) - { - *ch = 0; - } - - ch = strchr( m_sMapName, '/' ); - if ( ch ) - { - // move the string back over the '/' - memmove( m_sMapName, ch+1, strlen(ch)+1 ); - } - } - - pfile = (char*)gEngfuncs.COM_LoadFile( sz, 5, NULL ); - - if (!pfile) - return NULL; - - cText = pfile; - - strncpy( cTitle, m_sMapName, MAX_TITLE_LENGTH ); - cTitle[MAX_TITLE_LENGTH-1] = 0; - } - else if ( iTextToShow == SHOW_CLASSDESC ) - { - switch ( g_iPlayerClass ) - { - case PC_SCOUT: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_scout" ); - CHudTextMessage::LocaliseTextString( "#Title_scout", cTitle, MAX_TITLE_LENGTH ); break; - case PC_SNIPER: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_sniper" ); - CHudTextMessage::LocaliseTextString( "#Title_sniper", cTitle, MAX_TITLE_LENGTH ); break; - case PC_SOLDIER: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_soldier" ); - CHudTextMessage::LocaliseTextString( "#Title_soldier", cTitle, MAX_TITLE_LENGTH ); break; - case PC_DEMOMAN: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_demoman" ); - CHudTextMessage::LocaliseTextString( "#Title_demoman", cTitle, MAX_TITLE_LENGTH ); break; - case PC_MEDIC: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_medic" ); - CHudTextMessage::LocaliseTextString( "#Title_medic", cTitle, MAX_TITLE_LENGTH ); break; - case PC_HVYWEAP: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_hwguy" ); - CHudTextMessage::LocaliseTextString( "#Title_hwguy", cTitle, MAX_TITLE_LENGTH ); break; - case PC_PYRO: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_pyro" ); - CHudTextMessage::LocaliseTextString( "#Title_pyro", cTitle, MAX_TITLE_LENGTH ); break; - case PC_SPY: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_spy" ); - CHudTextMessage::LocaliseTextString( "#Title_spy", cTitle, MAX_TITLE_LENGTH ); break; - case PC_ENGINEER: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_engineer" ); - CHudTextMessage::LocaliseTextString( "#Title_engineer", cTitle, MAX_TITLE_LENGTH ); break; - case PC_CIVILIAN: cText = CHudTextMessage::BufferedLocaliseTextString( "#Help_civilian" ); - CHudTextMessage::LocaliseTextString( "#Title_civilian", cTitle, MAX_TITLE_LENGTH ); break; - default: - return NULL; - } - - if ( g_iPlayerClass == PC_CIVILIAN ) - { - sprintf(sz, "classes/long_civilian.txt"); - } - else - { - sprintf(sz, "classes/long_%s.txt", sTFClassSelection[ g_iPlayerClass ]); - } - char *pfile = (char*)gEngfuncs.COM_LoadFile( sz, 5, NULL ); - if (pfile) - { - cText = pfile; - } - } - - // if we're in the game (ie. have selected a class), flag the menu to be only grayed in the dialog box, instead of full screen - CMenuPanel *pMOTDPanel = CMessageWindowPanel_Create( cText, cTitle, g_iPlayerClass == PC_UNDEFINED, false, 0, 0, ScreenWidth, ScreenHeight ); - pMOTDPanel->setParent( this ); - - if ( pfile ) - gEngfuncs.COM_FreeFile( pfile ); - - return pMOTDPanel; -} - -//================================================================ -// VGUI Menus -void TeamFortressViewport::ShowVGUIMenu( int iMenu ) -{ - CMenuPanel *pNewMenu = NULL; - - // Don't open menus in demo playback - if ( gEngfuncs.pDemoAPI->IsPlayingback() ) - return; - - // Don't create one if it's already in the list - if (m_pCurrentMenu) - { - CMenuPanel *pMenu = m_pCurrentMenu; - while (pMenu != NULL) - { - if (pMenu->GetMenuID() == iMenu) - return; - pMenu = pMenu->GetNextMenu(); - } - } - - switch ( iMenu ) - { - // Map Briefing removed now that it appears in the team menu - case MENU_MAPBRIEFING: - pNewMenu = CreateTextWindow( SHOW_MAPBRIEFING ); - break; - - case MENU_INTRO: - pNewMenu = CreateTextWindow( SHOW_MOTD ); - break; - - case MENU_CLASSHELP: - pNewMenu = CreateTextWindow( SHOW_CLASSDESC ); - break; - - default: - break; - } - - if (!pNewMenu) - return; - - // Close the Command Menu if it's open - HideCommandMenu(); - - pNewMenu->SetMenuID( iMenu ); - pNewMenu->SetActive( true ); - - // See if another menu is visible, and if so, cache this one for display once the other one's finished - if (m_pCurrentMenu) - { - m_pCurrentMenu->SetNextMenu( pNewMenu ); - } - else - { - m_pCurrentMenu = pNewMenu; - m_pCurrentMenu->Open(); - UpdateCursorState(); - } -} - -// Removes all VGUI Menu's onscreen -void TeamFortressViewport::HideVGUIMenu() -{ - while (m_pCurrentMenu) - { - HideTopMenu(); - } -} - -// Remove the top VGUI menu, and bring up the next one -void TeamFortressViewport::HideTopMenu() -{ - if (m_pCurrentMenu) - { - // Close the top one - m_pCurrentMenu->Close(); - - // Bring up the next one - gViewPort->SetCurrentMenu( m_pCurrentMenu->GetNextMenu() ); - } - - UpdateCursorState(); -} - -// Return TRUE if the HUD's allowed to print text messages -bool TeamFortressViewport::AllowedToPrintText( void ) -{ - // Prevent text messages when fullscreen menus are up - if ( m_pCurrentMenu && g_iPlayerClass == 0 ) - { - int iId = m_pCurrentMenu->GetMenuID(); - if ( iId == MENU_TEAM || iId == MENU_CLASS || iId == MENU_INTRO || iId == MENU_CLASSHELP ) - return FALSE; - } - - return TRUE; -} - -//====================================================================================== -// SPECTATOR MENU -//====================================================================================== -// Spectator "Menu" explaining the Spectator buttons -void TeamFortressViewport::CreateSpectatorMenu() -{ - // Create the Panel - m_pSpectatorMenu = new CTransparentPanel(100, 0, ScreenHeight - YRES(60), ScreenWidth, YRES(60)); - m_pSpectatorMenu->setParent(this); - m_pSpectatorMenu->setVisible(false); - - // Get the scheme used for the Titles - CSchemeManager *pSchemes = gViewPort->GetSchemeManager(); - - // schemes - SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" ); - SchemeHandle_t hHelpText = pSchemes->getSchemeHandle( "Primary Button Text" ); - - // color schemes - int r, g, b, a; - - // Create the title - m_pSpectatorLabel = new Label( "Spectator", 0, 0, ScreenWidth, YRES(25) ); - m_pSpectatorLabel->setParent( m_pSpectatorMenu ); - m_pSpectatorLabel->setFont( pSchemes->getFont(hTitleScheme) ); - pSchemes->getFgColor( hTitleScheme, r, g, b, a ); - m_pSpectatorLabel->setFgColor( r, g, b, a ); - pSchemes->getBgColor( hTitleScheme, r, g, b, a ); - m_pSpectatorLabel->setBgColor( r, g, b, 255 ); - m_pSpectatorLabel->setContentAlignment( vgui::Label::a_north ); - - // Create the Help - Label *pLabel = new Label( CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help" ), 0, YRES(25), ScreenWidth, YRES(15) ); - pLabel->setParent( m_pSpectatorMenu ); - pLabel->setFont( pSchemes->getFont(hHelpText) ); - pSchemes->getFgColor( hHelpText, r, g, b, a ); - pLabel->setFgColor( r, g, b, a ); - pSchemes->getBgColor( hHelpText, r, g, b, a ); - pLabel->setBgColor( r, g, b, 255 ); - pLabel->setContentAlignment( vgui::Label::a_north ); - - pLabel = new Label( CHudTextMessage::BufferedLocaliseTextString( "#Spec_Help2" ), 0, YRES(40), ScreenWidth, YRES(20) ); - pLabel->setParent( m_pSpectatorMenu ); - pLabel->setFont( pSchemes->getFont(hHelpText) ); - pSchemes->getFgColor( hHelpText, r, g, b, a ); - pLabel->setFgColor( r, g, b, a ); - pSchemes->getBgColor( hHelpText, r, g, b, a ); - pLabel->setBgColor( r, g, b, 255 ); - pLabel->setContentAlignment( vgui::Label::a_center ); -} - -//====================================================================================== -// UPDATE HUD SECTIONS -//====================================================================================== -// We've got an update on player info -// Recalculate any menus that use it. -void TeamFortressViewport::UpdateOnPlayerInfo() -{ - if (m_pScoreBoard) - m_pScoreBoard->Update(); -} - -void TeamFortressViewport::UpdateCursorState() -{ - // Need cursor if any VGUI window is up - if ( m_pCurrentMenu || m_pServerBrowser->isVisible() || GetClientVoiceMgr()->IsInSquelchMode() ) - { - g_iVisibleMouse = true; - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_arrow) ); - return; - } - else if ( m_pCurrentCommandMenu ) - { - // commandmenu doesn't have cursor if hud_capturemouse is turned off - if ( gHUD.m_pCvarStealMouse->value != 0.0f ) - { - g_iVisibleMouse = true; - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_arrow) ); - return; - } - } - - IN_ResetMouse(); - g_iVisibleMouse = false; - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_none) ); -} - -void TeamFortressViewport::UpdateHighlights() -{ - if (m_pCurrentCommandMenu) - m_pCurrentCommandMenu->MakeVisible( NULL ); -} - -void TeamFortressViewport::GetAllPlayersInfo( void ) -{ - for ( int i = 1; i < MAX_PLAYERS; i++ ) - { - GetPlayerInfo( i, &g_PlayerInfoList[i] ); - - if ( g_PlayerInfoList[i].thisplayer ) - m_pScoreBoard->m_iPlayerNum = i; // !!!HACK: this should be initialized elsewhere... maybe gotten from the engine - } -} - -void TeamFortressViewport::paintBackground() -{ - int wide, tall; - getParent()->getSize( wide, tall ); - setSize( wide, tall ); - - if (m_pScoreBoard) - { - int x, y; - getApp()->getCursorPos(x, y); - m_pScoreBoard->cursorMoved(x, y, m_pScoreBoard); - } - - // See if the command menu is visible and needs recalculating due to some external change - if ( g_iTeamNumber != m_iCurrentTeamNumber ) - { - UpdateCommandMenu(); - for (int i = 0; i < MAX_DISCS; i++) - { - if ( m_pDiscIcons[i] ) - m_pDiscIcons[i]->Update( i, false, m_iDiscPowerup ); - } - - m_iCurrentTeamNumber = g_iTeamNumber; - } - - if ( g_iPlayerClass != m_iCurrentPlayerClass ) - { - UpdateCommandMenu(); - - m_iCurrentPlayerClass = g_iPlayerClass; - } - - // Update the Reward window - if ( m_flRewardOpenTime && ( m_flRewardOpenTime < gHUD.m_flTime ) ) - { - m_pDiscRewardWindow->setVisible(false); - m_flRewardOpenTime = 0; - } - - // Update the disc icons the player has - bool bVisible = true; - if ( m_pDiscStartRound && m_pDiscStartRound->isVisible() ) - bVisible = false; - if ( m_pDiscEndRound && m_pDiscEndRound->isVisible() ) - bVisible = false; - if ( m_pSpectatorMenu && m_pSpectatorMenu->isVisible() ) - bVisible = false; - for (int i = 0; i < MAX_DISCS; i++) - { - if ( bVisible == false ) - { - m_pDiscIcons[i]->setVisible(false); - } - else - { - m_pDiscIcons[i]->Update(i, true, m_iDiscPowerup); - m_pDiscIcons[i]->setVisible(true); - } - } - - // See if the Spectator Menu needs to be update - if ( g_iUser1 != m_iUser1 || g_iUser2 != m_iUser2 ) - { - m_iUser1 = g_iUser1; - m_iUser2 = g_iUser2; - UpdateSpectatorMenu(); - } - - // Update the Scoreboard, if it's visible - if ( m_pScoreBoard->isVisible() && (m_flScoreBoardLastUpdated < gHUD.m_flTime) ) - { - m_pScoreBoard->Update(); - m_flScoreBoardLastUpdated = gHUD.m_flTime + 0.5; - } - - int extents[4]; - getAbsExtents(extents[0],extents[1],extents[2],extents[3]); - VGui_ViewportPaintBackground(extents); -} - -//================================================================ -// Input Handler for Drag N Drop panels -void CDragNDropHandler::cursorMoved(int x,int y,Panel* panel) -{ - if(m_bDragging) - { - App::getInstance()->getCursorPos(x,y); - m_pPanel->setPos(m_iaDragOrgPos[0]+(x-m_iaDragStart[0]),m_iaDragOrgPos[1]+(y-m_iaDragStart[1])); - - if(m_pPanel->getParent()!=null) - { - m_pPanel->getParent()->repaint(); - } - } -} - -void CDragNDropHandler::mousePressed(MouseCode code,Panel* panel) -{ - int x,y; - App::getInstance()->getCursorPos(x,y); - m_bDragging=true; - m_iaDragStart[0]=x; - m_iaDragStart[1]=y; - m_pPanel->getPos(m_iaDragOrgPos[0],m_iaDragOrgPos[1]); - App::getInstance()->setMouseCapture(panel); - - m_pPanel->setDragged(m_bDragging); - m_pPanel->requestFocus(); -} - -void CDragNDropHandler::mouseReleased(MouseCode code,Panel* panel) -{ - m_bDragging=false; - m_pPanel->setDragged(m_bDragging); - App::getInstance()->setMouseCapture(null); -} - -//================================================================ -// Number Key Input -bool TeamFortressViewport::SlotInput( int iSlot ) -{ - // If there's a menu up, give it the input - if ( m_pCurrentMenu ) - return m_pCurrentMenu->SlotInput( iSlot ); - - return FALSE; -} - -// Direct Key Input -int TeamFortressViewport::KeyInput( int down, int keynum, const char *pszCurrentBinding ) -{ - // Enter gets out of Spectator Mode by bringing up the Team Menu - if (m_iUser1 && gEngfuncs.Con_IsVisible() == false ) - { - if ( down && keynum == K_SPACE ) - gEngfuncs.pfnClientCmd("ob_next"); - if ( down && keynum == K_ENTER ) - gEngfuncs.pfnClientCmd("ob_mode"); - if ( down && keynum == K_CTRL ) - gEngfuncs.pfnClientCmd("ob_prev"); - } - - // Open Text Window? - if (m_pCurrentMenu && gEngfuncs.Con_IsVisible() == false) - { - int iMenuID = m_pCurrentMenu->GetMenuID(); - - // Get number keys as Input for Team/Class menus - if (iMenuID == MENU_TEAM || iMenuID == MENU_CLASS) - { - // Escape gets you out of Team/Class menus if the Cancel button is visible - if ( keynum == K_ESCAPE ) - { - if ( (iMenuID == MENU_TEAM && g_iTeamNumber) || (iMenuID == MENU_CLASS && g_iPlayerClass) ) - { - HideTopMenu(); - return 0; - } - } - - for (int i = '0'; i <= '9'; i++) - { - if ( down && (keynum == i) ) - { - SlotInput( i - '0' ); - return 0; - } - } - } - - // Grab enter keys to close TextWindows - if ( down && (keynum == K_ENTER || keynum == K_KP_ENTER || keynum == K_SPACE || keynum == K_ESCAPE) ) - { - if ( iMenuID == MENU_MAPBRIEFING || iMenuID == MENU_INTRO || iMenuID == MENU_CLASSHELP ) - { - HideTopMenu(); - return 0; - } - } - - } - - // if we're in a command menu, try hit one of it's buttons - if ( down && m_pCurrentCommandMenu ) - { - // Escape hides the command menu - if ( keynum == K_ESCAPE ) - { - HideCommandMenu(); - return 0; - } - - // only trap the number keys - if ( keynum >= '0' && keynum <= '9' ) - { - if ( m_pCurrentCommandMenu->KeyInput(keynum) ) - { - // a final command has been issued, so close the command menu - HideCommandMenu(); - } - - return 0; - } - } - - return 1; -} - -//================================================================ -// Message Handlers -int TeamFortressViewport::MsgFunc_ValClass(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - for (int i = 0; i < 5; i++) - m_iValidClasses[i] = READ_SHORT(); - - // Force the menu to update - UpdateCommandMenu(); - - return 1; -} - -int TeamFortressViewport::MsgFunc_TeamNames(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iNumberOfTeams = READ_BYTE(); - - for (int i = 0; i < m_iNumberOfTeams; i++) - { - int teamNum = i + 1; - - gHUD.m_TextMessage.LocaliseTextString( READ_STRING(), m_sTeamNames[teamNum], MAX_TEAMNAME_SIZE ); - - // Set the team name buttons - if (m_pTeamButtons[i]) - m_pTeamButtons[i]->setText( m_sTeamNames[teamNum] ); - - // Set the disguise buttons - if (m_pDisguiseButtons[i]) - m_pDisguiseButtons[i]->setText( m_sTeamNames[teamNum] ); - } - - return 1; -} - -int TeamFortressViewport::MsgFunc_Feign(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iIsFeigning = READ_BYTE(); - - // Force the menu to update - UpdateCommandMenu(); - - return 1; -} - -int TeamFortressViewport::MsgFunc_Detpack(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iIsSettingDetpack = READ_BYTE(); - - // Force the menu to update - UpdateCommandMenu(); - - return 1; -} - -int TeamFortressViewport::MsgFunc_VGUIMenu(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int iMenu = READ_BYTE(); - - // Map briefing includes the name of the map (because it's sent down before the client knows what map it is) - if (iMenu == MENU_MAPBRIEFING) - { - strncpy( m_sMapName, READ_STRING(), sizeof(m_sMapName) ); - m_sMapName[ sizeof(m_sMapName) - 1 ] = '\0'; - } - - // Bring up the menu6 - ShowVGUIMenu( iMenu ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf ) -{ - if (m_iGotAllMOTD) - m_szMOTD[0] = 0; - - BEGIN_READ( pbuf, iSize ); - - m_iGotAllMOTD = READ_BYTE(); - strncat( m_szMOTD, READ_STRING(), sizeof(m_szMOTD) - strlen(m_szMOTD) ); - m_szMOTD[ sizeof(m_szMOTD)-1 ] = '\0'; - - if ( m_iGotAllMOTD ) - { - ShowVGUIMenu( MENU_INTRO ); - } - - return 1; -} - -int TeamFortressViewport::MsgFunc_BuildSt( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iBuildState = READ_BYTE(); - - // Force the menu to update - UpdateCommandMenu(); - - return 1; -} - -int TeamFortressViewport::MsgFunc_RandomPC( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iRandomPC = READ_BYTE(); - - return 1; -} - -int TeamFortressViewport::MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - strncpy( m_szServerName, READ_STRING(), MAX_SERVERNAME_LENGTH ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - short cl = READ_BYTE(); - short frags = READ_SHORT(); - short deaths = READ_SHORT(); - short playerclass = READ_SHORT(); - short teamnumber = READ_SHORT(); - - if ( cl > 0 && cl <= MAX_PLAYERS ) - { - g_PlayerExtraInfo[cl].frags = frags; - g_PlayerExtraInfo[cl].deaths = deaths; - g_PlayerExtraInfo[cl].playerclass = playerclass; - g_PlayerExtraInfo[cl].teamnumber = teamnumber; - - UpdateOnPlayerInfo(); - } - - return 1; -} - -// Message handler for TeamScore message -// accepts three values: -// string: team name -// short: teams kills -// short: teams deaths -// if this message is never received, then scores will simply be the combined totals of the players. -int TeamFortressViewport::MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - char *TeamName = READ_STRING(); - - // find the team matching the name - int i; - for ( i = 1; i <= m_pScoreBoard->m_iNumTeams; i++ ) - { - if ( !stricmp( TeamName, g_TeamInfo[i].name ) ) - break; - } - - if ( i > m_pScoreBoard->m_iNumTeams ) - return 1; - - // use this new score data instead of combined player scoresw - g_TeamInfo[i].scores_overriden = TRUE; - g_TeamInfo[i].frags = READ_SHORT(); - g_TeamInfo[i].deaths = READ_SHORT(); - - return 1; -} - -// Message handler for TeamInfo message -// accepts two values: -// byte: client number -// string: client team name -int TeamFortressViewport::MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf ) -{ - if (!m_pScoreBoard) - return 1; - - BEGIN_READ( pbuf, iSize ); - short cl = READ_BYTE(); - - if ( cl > 0 && cl <= MAX_PLAYERS ) - { - // set the players team - strncpy( g_PlayerExtraInfo[cl].teamname, READ_STRING(), MAX_TEAM_NAME ); - } - - // rebuild the list of teams - m_pScoreBoard->RebuildTeams(); - - return 1; -} - -void TeamFortressViewport::DeathMsg( int killer, int victim ) -{ - m_pScoreBoard->DeathMsg(killer,victim); -} - -int TeamFortressViewport::MsgFunc_Spectator( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - short cl = READ_BYTE(); - if ( cl > 0 && cl <= MAX_PLAYERS ) - { - g_IsSpectator[cl] = READ_BYTE(); - } - - return 1; -} - -int TeamFortressViewport::MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iAllowSpectators = READ_BYTE(); - - // Force the menu to update - UpdateCommandMenu(); - - return 1; -} - -int TeamFortressViewport::MsgFunc_StartRnd(const char *pszName, int iSize, void *pbuf ) -{ - if (m_pDiscStartRound) - return m_pDiscStartRound->MsgFunc_GetPlayers( pszName, iSize, pbuf ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_EndRnd(const char *pszName, int iSize, void *pbuf ) -{ - if (m_pDiscEndRound) - return m_pDiscEndRound->MsgFunc_GetPlayers( pszName, iSize, pbuf ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_Frozen(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - int iFrozen = READ_BYTE(); - - if ( iFrozen ) - { - gHUD.m_Health.m_bitsDamage = DMG_FREEZE; - gHUD.m_Health.m_iFlags |= HUD_ACTIVE; - } - else - { - gHUD.m_Health.m_bitsDamage = 0; - gHUD.m_Health.m_iFlags &= ~HUD_ACTIVE; - } - - return 1; -} - -int TeamFortressViewport::MsgFunc_Powerup( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iDiscPowerup = READ_BYTE(); - - // Force the disc icons to update - for (int i = 0; i < MAX_DISCS; i++) - { - if ( m_pDiscIcons[i] ) - m_pDiscIcons[i]->Update( i, false, m_iDiscPowerup ); - } - - // Update the powerup window - m_pDiscPowerupWindow->RecalculateText( m_iDiscPowerup ); - - return 1; -} - -int TeamFortressViewport::MsgFunc_Reward( const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - int iReward = READ_SHORT(); - - // Update the reward window - m_pDiscRewardWindow->RecalculateText( iReward ); - m_flRewardOpenTime = gHUD.m_flTime + 2.0; - - return 1; -} - - diff --git a/ricochet/cl_dll/vgui_TeamFortressViewport.h b/ricochet/cl_dll/vgui_TeamFortressViewport.h deleted file mode 100644 index b1415cf..0000000 --- a/ricochet/cl_dll/vgui_TeamFortressViewport.h +++ /dev/null @@ -1,1207 +0,0 @@ - -#ifndef TEAMFORTRESSVIEWPORT_H -#define TEAMFORTRESSVIEWPORT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// custom scheme handling -#include "vgui_SchemeManager.h" - -#define TF_DEFS_ONLY -#include "tf_defs.h" - -#include "discwar.h" - -using namespace vgui; - -class Cursor; -class ScorePanel; -class CCommandMenu; -class CommandLabel; -class CommandButton; -class BuildButton; -class ClassButton; -class CMenuPanel; -class ServerBrowser; -class DragNDropPanel; -class CTransparentPanel; -class CDiscPanel; -class CDiscArena_RoundStart; -class CDiscArena_RoundEnd; -class CDiscPowerups; -class CDiscRewards; - -char* GetVGUITGAName(const char *pszName); -BitmapTGA *LoadTGAForRes( const char* pImageName ); -void ScaleColors( int &r, int &g, int &b, int a ); -extern char *sTFClassSelection[]; -extern int sTFValidClassInts[]; -extern char *sLocalisedClasses[]; -extern int iTeamColors[5][3]; - -#define MAX_SERVERNAME_LENGTH 32 - -// Use this to set any co-ords in 640x480 space -#define XRES(x) (x * ((float)ScreenWidth / 640)) -#define YRES(y) (y * ((float)ScreenHeight / 480)) - -// Command Menu positions -#define MAX_MENUS 40 -#define MAX_BUTTONS 100 - -#define BUTTON_SIZE_Y YRES(30) -#define CMENU_SIZE_X XRES(160) - -#define SUBMENU_SIZE_X (CMENU_SIZE_X / 8) -#define SUBMENU_SIZE_Y (BUTTON_SIZE_Y / 6) - -#define CMENU_TOP (BUTTON_SIZE_Y * 4) - -#define MAX_TEAMNAME_SIZE 64 -#define MAX_BUTTON_SIZE 32 - -// Map Briefing Window -#define MAPBRIEF_INDENT 30 - -// Team Menu -#define TMENU_INDENT_X (30 * ((float)ScreenHeight / 640)) -#define TMENU_HEADER 100 -#define TMENU_SIZE_X (ScreenWidth - (TMENU_INDENT_X * 2)) -#define TMENU_SIZE_Y (TMENU_HEADER + BUTTON_SIZE_Y * 7) -#define TMENU_PLAYER_INDENT (((float)TMENU_SIZE_X / 3) * 2) -#define TMENU_INDENT_Y (((float)ScreenHeight - TMENU_SIZE_Y) / 2) - -// Class Menu -#define CLMENU_INDENT_X (30 * ((float)ScreenHeight / 640)) -#define CLMENU_HEADER 100 -#define CLMENU_SIZE_X (ScreenWidth - (CLMENU_INDENT_X * 2)) -#define CLMENU_SIZE_Y (CLMENU_HEADER + BUTTON_SIZE_Y * 11) -#define CLMENU_PLAYER_INDENT (((float)CLMENU_SIZE_X / 3) * 2) -#define CLMENU_INDENT_Y (((float)ScreenHeight - CLMENU_SIZE_Y) / 2) - -// Discwar icons -#define DISC_ICON_WIDTH XRES(32) -#define DISC_ICON_SPACER XRES(72) - -// Arrows -enum -{ - ARROW_UP, - ARROW_DOWN, - ARROW_LEFT, - ARROW_RIGHT, -}; - -//============================================================================== -// VIEWPORT PIECES -//============================================================ -// Wrapper for an Image Label without a background -class CImageLabel : public Label -{ -public: - BitmapTGA *m_pTGA; - -public: - void LoadImage(const char * pImageName); - CImageLabel( const char* pImageName,int x,int y ); - CImageLabel( const char* pImageName,int x,int y,int wide,int tall ); - - virtual int getImageTall(); - virtual int getImageWide(); - - virtual void paintBackground() - { - // Do nothing, so the background's left transparent. - } -}; - -// Command Label -// Overridden label so we can darken it when submenus open -class CommandLabel : public Label -{ -private: - int m_iState; - -public: - CommandLabel(const char* text,int x,int y,int wide,int tall) : Label(text,x,y,wide,tall) - { - m_iState = false; - } - - void PushUp() - { - m_iState = false; - repaint(); - } - - void PushDown() - { - m_iState = true; - repaint(); - } -}; - -//============================================================ -// Command Buttons -class CommandButton : public Button -{ -private: - int m_iPlayerClass; - - // Submenus under this button - CCommandMenu *m_pSubMenu; - CCommandMenu *m_pParentMenu; - CommandLabel *m_pSubLabel; - - char m_sMainText[MAX_BUTTON_SIZE]; - char m_cBoundKey; - - SchemeHandle_t m_hTextScheme; - - void RecalculateText( void ); - -public: - bool m_bNoHighlight; - -public: - // Constructors - CommandButton( const char* text,int x,int y,int wide,int tall, bool bNoHighlight = false); - CommandButton( int iPlayerClass, const char* text,int x,int y,int wide,int tall); - - void Init( void ); - - // Menu Handling - void AddSubMenu( CCommandMenu *pNewMenu ); - void AddSubLabel( CommandLabel *pSubLabel ) - { - m_pSubLabel = pSubLabel; - } - - virtual int IsNotValid( void ) - { - return false; - } - - void UpdateSubMenus( int iAdjustment ); - int GetPlayerClass() { return m_iPlayerClass; }; - CCommandMenu *GetSubMenu() { return m_pSubMenu; }; - - CCommandMenu *getParentMenu( void ); - void setParentMenu( CCommandMenu *pParentMenu ); - - // Overloaded vgui functions - virtual void paint(); - virtual void setText( const char *text ); - virtual void paintBackground(); - - void cursorEntered( void ); - void cursorExited( void ); - - void setBoundKey( char boundKey ); - char getBoundKey( void ); -}; - -//============================================================ -// Command Menus -class CCommandMenu : public Panel -{ -private: - CCommandMenu *m_pParentMenu; - int m_iXOffset; - int m_iYOffset; - - // Buttons in this menu - CommandButton *m_aButtons[ MAX_BUTTONS ]; - int m_iButtons; - -public: - CCommandMenu( CCommandMenu *pParentMenu, int x,int y,int wide,int tall ) : Panel(x,y,wide,tall) - { - m_pParentMenu = pParentMenu; - m_iXOffset = x; - m_iYOffset = y; - m_iButtons = 0; - } - - void AddButton( CommandButton *pButton ); - bool RecalculateVisibles( int iNewYPos, bool bHideAll ); - void RecalculatePositions( int iYOffset ); - void MakeVisible( CCommandMenu *pChildMenu ); - - CCommandMenu *GetParentMenu() { return m_pParentMenu; }; - int GetXOffset() { return m_iXOffset; }; - int GetYOffset() { return m_iYOffset; }; - int GetNumButtons() { return m_iButtons; }; - CommandButton *FindButtonWithSubmenu( CCommandMenu *pSubMenu ); - - void ClearButtonsOfArmedState( void ); - - - bool KeyInput( int keyNum ); - - virtual void paintBackground(); -}; - -//============================================================================== -class TeamFortressViewport : public Panel -{ -private: - vgui::Cursor* _cursorNone; - vgui::Cursor* _cursorArrow; - - int m_iInitialized; - - CCommandMenu *m_pCommandMenus[ MAX_MENUS ]; - CCommandMenu *m_pCurrentCommandMenu; - float m_flMenuOpenTime; - float m_flScoreBoardLastUpdated; - int m_iNumMenus; - int m_iCurrentTeamNumber; - int m_iCurrentPlayerClass; - - // VGUI Menus - void CreateSpectatorMenu( void ); - - // Scheme handler - CSchemeManager m_SchemeManager; - - // MOTD - int m_iGotAllMOTD; - char m_szMOTD[ MAX_MOTD_LENGTH ]; - - // Command Menu Team buttons - CommandButton *m_pTeamButtons[6]; - CommandButton *m_pDisguiseButtons[5]; - BuildButton *m_pBuildButtons[3]; - BuildButton *m_pBuildActiveButtons[3]; - - // Server Browser - ServerBrowser *m_pServerBrowser; - - // Spectator "menu" - Label *m_pSpectatorLabel; - int m_iAllowSpectators; - - // Data for specific sections of the Command Menu - int m_iValidClasses[5]; - int m_iIsFeigning; - int m_iIsSettingDetpack; - int m_iNumberOfTeams; - int m_iBuildState; - int m_iRandomPC; - char m_sTeamNames[5][MAX_TEAMNAME_SIZE]; - - // Localisation strings - char m_sDetpackStrings[3][MAX_BUTTON_SIZE]; - - char m_sMapName[64]; -public: - TeamFortressViewport(int x,int y,int wide,int tall); - void Initialize( void ); - - void CreateCommandMenu( void ); - void CreateScoreBoard( void ); - void CreateServerBrowser( void ); - CommandButton *CreateCustomButton( char *pButtonText, char *pButtonName ); - CCommandMenu *CreateDisguiseSubmenu( CommandButton *pButton, CCommandMenu *pParentMenu, const char *commandText ); - void CreateDiscIcons( void ); - - void UpdateCursorState( void ); - void UpdateCommandMenu( void ); - void UpdateOnPlayerInfo( void ); - void UpdateHighlights( void ); - void UpdateSpectatorMenu( void ); - - int KeyInput( int down, int keynum, const char *pszCurrentBinding ); - void InputPlayerSpecial( void ); - void GetAllPlayersInfo( void ); - void DeathMsg( int killer, int victim ); - - void ShowCommandMenu( void ); - void InputSignalHideCommandMenu( void ); - void HideCommandMenu( void ); - void SetCurrentCommandMenu( CCommandMenu *pNewMenu ); - void SetCurrentMenu( CMenuPanel *pMenu ); - - void ShowScoreBoard( void ); - void HideScoreBoard( void ); - bool IsScoreBoardVisible( void ); - - bool AllowedToPrintText( void ); - - void ShowVGUIMenu( int iMenu ); - void HideVGUIMenu( void ); - void HideTopMenu( void ); - - void ToggleServerBrowser( void ); - - CMenuPanel* CreateTextWindow( int iTextToShow ); - - CCommandMenu *CreateSubMenu( CommandButton *pButton, CCommandMenu *pParentMenu ); - - // Data Handlers - int GetValidClasses(int iTeam) { return m_iValidClasses[iTeam]; }; - int GetNumberOfTeams() { return m_iNumberOfTeams; }; - int GetIsFeigning() { return m_iIsFeigning; }; - int GetIsSettingDetpack() { return m_iIsSettingDetpack; }; - int GetBuildState() { return m_iBuildState; }; - int IsRandomPC() { return m_iRandomPC; }; - char *GetTeamName( int iTeam ) { return m_sTeamNames[iTeam]; }; - int GetAllowSpectators() { return m_iAllowSpectators; }; - - // Message Handlers - int MsgFunc_ValClass(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_TeamNames(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_Feign(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_Detpack(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_VGUIMenu(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_BuildSt( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_RandomPC( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_ServerName( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_ScoreInfo( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_TeamScore( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_TeamInfo( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_Spectator( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_AllowSpec( const char *pszName, int iSize, void *pbuf ); - // Discwar - int MsgFunc_StartRnd(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_EndRnd(const char *pszName, int iSize, void *pbuf ); - int MsgFunc_Powerup( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_Reward( const char *pszName, int iSize, void *pbuf ); - int MsgFunc_Frozen( const char *pszName, int iSize, void *pbuf ); - - // Input - bool SlotInput( int iSlot ); - - virtual void paintBackground(); - - CSchemeManager *GetSchemeManager( void ) { return &m_SchemeManager; } - ScorePanel *GetScoreBoard( void ) { return m_pScoreBoard; } - - void *operator new( size_t stAllocateBlock ); - -public: - // VGUI Menus - CMenuPanel *m_pCurrentMenu; - ScorePanel *m_pScoreBoard; - char m_szServerName[ MAX_SERVERNAME_LENGTH ]; - CDiscPanel *m_pDiscIcons[MAX_DISCS]; - CDiscArena_RoundStart *m_pDiscStartRound; - CDiscArena_RoundEnd *m_pDiscEndRound; - CDiscPowerups *m_pDiscPowerupWindow; - CDiscRewards *m_pDiscRewardWindow; - - CTransparentPanel *m_pSpectatorMenu; - float m_flRewardOpenTime; - int m_iUser1; - int m_iUser2; - int m_iDiscPowerup; -}; - -//============================================================ -// Command Menu Button Handlers -#define MAX_COMMAND_SIZE 256 - -class CMenuHandler_StringCommand : public ActionSignal -{ -protected: - char m_pszCommand[MAX_COMMAND_SIZE]; - int m_iCloseVGUIMenu; -public: - CMenuHandler_StringCommand( char *pszCommand ) - { - strncpy( m_pszCommand, pszCommand, MAX_COMMAND_SIZE); - m_pszCommand[MAX_COMMAND_SIZE-1] = '\0'; - m_iCloseVGUIMenu = false; - } - - CMenuHandler_StringCommand( char *pszCommand, int iClose ) - { - strncpy( m_pszCommand, pszCommand, MAX_COMMAND_SIZE); - m_pszCommand[MAX_COMMAND_SIZE-1] = '\0'; - m_iCloseVGUIMenu = true; - } - - virtual void actionPerformed(Panel* panel) - { - gEngfuncs.pfnClientCmd(m_pszCommand); - - if (m_iCloseVGUIMenu) - gViewPort->HideTopMenu(); - else - gViewPort->HideCommandMenu(); - } -}; - -// This works the same as CMenuHandler_StringCommand, except it watches the string command -// for specific commands, and modifies client vars based upon them. -class CMenuHandler_StringCommandWatch : public CMenuHandler_StringCommand -{ -private: -public: - CMenuHandler_StringCommandWatch( char *pszCommand ) : CMenuHandler_StringCommand( pszCommand ) - { - } - - CMenuHandler_StringCommandWatch( char *pszCommand, int iClose ) : CMenuHandler_StringCommand( pszCommand, iClose ) - { - } - - virtual void actionPerformed(Panel* panel) - { - CMenuHandler_StringCommand::actionPerformed( panel ); - - // Try to guess the player's new team (it'll be corrected if it's wrong) - if ( !strcmp( m_pszCommand, "jointeam 1" ) ) - g_iTeamNumber = 1; - else if ( !strcmp( m_pszCommand, "jointeam 2" ) ) - g_iTeamNumber = 2; - else if ( !strcmp( m_pszCommand, "jointeam 3" ) ) - g_iTeamNumber = 3; - else if ( !strcmp( m_pszCommand, "jointeam 4" ) ) - g_iTeamNumber = 4; - } -}; - -// Used instead of CMenuHandler_StringCommand for Class Selection buttons. -// Checks the state of hud_classautokill and kills the player if set -class CMenuHandler_StringCommandClassSelect : public CMenuHandler_StringCommand -{ -private: -public: - CMenuHandler_StringCommandClassSelect( char *pszCommand ) : CMenuHandler_StringCommand( pszCommand ) - { - } - - CMenuHandler_StringCommandClassSelect( char *pszCommand, int iClose ) : CMenuHandler_StringCommand( pszCommand, iClose ) - { - } - - virtual void actionPerformed(Panel* panel); -}; - -class CMenuHandler_PopupSubMenuInput : public InputSignal -{ -private: - CCommandMenu *m_pSubMenu; - Button *m_pButton; -public: - CMenuHandler_PopupSubMenuInput( Button *pButton, CCommandMenu *pSubMenu ) - { - m_pSubMenu = pSubMenu; - m_pButton = pButton; - } - - virtual void cursorMoved(int x,int y,Panel* panel) - { - //gViewPort->SetCurrentCommandMenu( m_pSubMenu ); - } - - virtual void cursorEntered(Panel* panel) - { - gViewPort->SetCurrentCommandMenu( m_pSubMenu ); - - if (m_pButton) - m_pButton->setArmed(true); - }; - virtual void cursorExited(Panel* Panel) {}; - virtual void mousePressed(MouseCode code,Panel* panel) {}; - virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}; - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -class CMenuHandler_LabelInput : public InputSignal -{ -private: - ActionSignal *m_pActionSignal; -public: - CMenuHandler_LabelInput( ActionSignal *pSignal ) - { - m_pActionSignal = pSignal; - } - - virtual void mousePressed(MouseCode code,Panel* panel) - { - m_pActionSignal->actionPerformed( panel ); - } - - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void cursorEntered(Panel* panel) {}; - virtual void cursorExited(Panel* Panel) {}; - virtual void cursorMoved(int x,int y,Panel* panel) {}; - virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -#define HIDE_TEXTWINDOW 0 -#define SHOW_MAPBRIEFING 1 -#define SHOW_CLASSDESC 2 -#define SHOW_MOTD 3 - -class CMenuHandler_TextWindow : public ActionSignal -{ -private: - int m_iState; -public: - CMenuHandler_TextWindow( int iState ) - { - m_iState = iState; - } - - virtual void actionPerformed(Panel* panel) - { - if (m_iState == HIDE_TEXTWINDOW) - { - gViewPort->HideTopMenu(); - } - else - { - gViewPort->HideCommandMenu(); - gViewPort->ShowVGUIMenu( m_iState ); - } - } -}; - -class CDragNDropHandler : public InputSignal -{ -private: - DragNDropPanel* m_pPanel; - bool m_bDragging; - int m_iaDragOrgPos[2]; - int m_iaDragStart[2]; - -public: - CDragNDropHandler(DragNDropPanel* pPanel) - { - m_pPanel = pPanel; - m_bDragging = false; - } - - void cursorMoved(int x,int y,Panel* panel); - void mousePressed(MouseCode code,Panel* panel); - void mouseReleased(MouseCode code,Panel* panel); - - void mouseDoublePressed(MouseCode code,Panel* panel) {}; - void cursorEntered(Panel* panel) {}; - void cursorExited(Panel* panel) {}; - void mouseWheeled(int delta,Panel* panel) {}; - void keyPressed(KeyCode code,Panel* panel) {}; - void keyTyped(KeyCode code,Panel* panel) {}; - void keyReleased(KeyCode code,Panel* panel) {}; - void keyFocusTicked(Panel* panel) {}; -}; - -class CHandler_MenuButtonOver : public InputSignal -{ -private: - int m_iButton; - CMenuPanel *m_pMenuPanel; -public: - CHandler_MenuButtonOver( CMenuPanel *pPanel, int iButton ) - { - m_iButton = iButton; - m_pMenuPanel = pPanel; - } - - void cursorEntered(Panel *panel); - - void cursorMoved(int x,int y,Panel* panel) {}; - void mousePressed(MouseCode code,Panel* panel) {}; - void mouseReleased(MouseCode code,Panel* panel) {}; - void mouseDoublePressed(MouseCode code,Panel* panel) {}; - void cursorExited(Panel* panel) {}; - void mouseWheeled(int delta,Panel* panel) {}; - void keyPressed(KeyCode code,Panel* panel) {}; - void keyTyped(KeyCode code,Panel* panel) {}; - void keyReleased(KeyCode code,Panel* panel) {}; - void keyFocusTicked(Panel* panel) {}; -}; - -class CHandler_ButtonHighlight : public InputSignal -{ -private: - Button *m_pButton; -public: - CHandler_ButtonHighlight( Button *pButton ) - { - m_pButton = pButton; - } - - virtual void cursorEntered(Panel* panel) - { - m_pButton->setArmed(true); - }; - virtual void cursorExited(Panel* Panel) - { - m_pButton->setArmed(false); - }; - virtual void mousePressed(MouseCode code,Panel* panel) {}; - virtual void mouseReleased(MouseCode code,Panel* panel) {}; - virtual void cursorMoved(int x,int y,Panel* panel) {}; - virtual void mouseDoublePressed(MouseCode code,Panel* panel) {}; - virtual void mouseWheeled(int delta,Panel* panel) {}; - virtual void keyPressed(KeyCode code,Panel* panel) {}; - virtual void keyTyped(KeyCode code,Panel* panel) {}; - virtual void keyReleased(KeyCode code,Panel* panel) {}; - virtual void keyFocusTicked(Panel* panel) {}; -}; - -//----------------------------------------------------------------------------- -// Purpose: Special handler for highlighting of command menu buttons -//----------------------------------------------------------------------------- -class CHandler_CommandButtonHighlight : public CHandler_ButtonHighlight -{ -private: - CommandButton *m_pCommandButton; -public: - CHandler_CommandButtonHighlight( CommandButton *pButton ) : CHandler_ButtonHighlight( pButton ) - { - m_pCommandButton = pButton; - } - - virtual void cursorEntered( Panel *panel ) - { - m_pCommandButton->cursorEntered(); - } - - virtual void cursorExited( Panel *panel ) - { - m_pCommandButton->cursorExited(); - } -}; - - -//================================================================ -// Overidden Command Buttons for special visibilities -class ClassButton : public CommandButton -{ -protected: - int m_iPlayerClass; - -public: - ClassButton( int iClass, const char* text,int x,int y,int wide,int tall, bool bNoHighlight ) : CommandButton( text,x,y,wide,tall, bNoHighlight) - { - m_iPlayerClass = iClass; - } - - virtual int IsNotValid(); -}; - -class TeamButton : public CommandButton -{ -private: - int m_iTeamNumber; -public: - TeamButton( int iTeam, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - m_iTeamNumber = iTeam; - } - - virtual int IsNotValid() - { - int iTeams = gViewPort->GetNumberOfTeams(); - // Never valid if there's only 1 team - if (iTeams == 1) - return true; - - // Auto Team's always visible - if (m_iTeamNumber == 5) - return false; - - if (iTeams >= m_iTeamNumber && m_iTeamNumber != g_iTeamNumber) - return false; - - return true; - } -}; - -class FeignButton : public CommandButton -{ -private: - int m_iFeignState; -public: - FeignButton( int iState, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - m_iFeignState = iState; - } - - virtual int IsNotValid() - { - // Only visible for spies - if (g_iPlayerClass != PC_SPY) - return true; - - if (m_iFeignState == gViewPort->GetIsFeigning()) - return false; - - return true; - } -}; - -class SpectateButton : public CommandButton -{ -public: - SpectateButton( const char* text,int x,int y,int wide,int tall, bool bNoHighlight ) : CommandButton( text,x,y,wide,tall, bNoHighlight) - { - } - - virtual int IsNotValid() - { - // Only visible if the server allows it - if ( gViewPort->GetAllowSpectators() != 0 ) - return false; - - return true; - } -}; - -#define DISGUISE_TEAM1 (1<<0) -#define DISGUISE_TEAM2 (1<<1) -#define DISGUISE_TEAM3 (1<<2) -#define DISGUISE_TEAM4 (1<<3) - -class DisguiseButton : public CommandButton -{ -private: - int m_iValidTeamsBits; - int m_iThisTeam; -public: - DisguiseButton( int iValidTeamNumsBits, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall,false ) - { - m_iValidTeamsBits = iValidTeamNumsBits; - } - - virtual int IsNotValid() - { - // Only visible for spies - if ( g_iPlayerClass != PC_SPY ) - return true; - - // if it's not tied to a specific team, then always show (for spies) - if ( !m_iValidTeamsBits ) - return false; - - // if we're tied to a team make sure we can change to that team - int iTmp = 1 << (gViewPort->GetNumberOfTeams() - 1); - if ( m_iValidTeamsBits & iTmp ) - return false; - - return true; - } -}; - -class DetpackButton : public CommandButton -{ -private: - int m_iDetpackState; -public: - DetpackButton( int iState, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - m_iDetpackState = iState; - } - - virtual int IsNotValid() - { - // Only visible for demomen - if (g_iPlayerClass != PC_DEMOMAN) - return true; - - if (m_iDetpackState == gViewPort->GetIsSettingDetpack()) - return false; - - return true; - } -}; - -extern int iBuildingCosts[]; -#define BUILDSTATE_HASBUILDING (1<<0) // Data is building ID (1 = Dispenser, 2 = Sentry) -#define BUILDSTATE_BUILDING (1<<1) -#define BUILDSTATE_BASE (1<<2) -#define BUILDSTATE_CANBUILD (1<<3) // Data is building ID (0 = Dispenser, 1 = Sentry) - -class BuildButton : public CommandButton -{ -private: - int m_iBuildState; - int m_iBuildData; - -public: - enum Buildings - { - DISPENSER = 0, - SENTRYGUN = 1, - }; - - BuildButton( int iState, int iData, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - m_iBuildState = iState; - m_iBuildData = iData; - } - - virtual int IsNotValid() - { - // Only visible for engineers - if (g_iPlayerClass != PC_ENGINEER) - return true; - - // If this isn't set, it's only active when they're not building - if (m_iBuildState & BUILDSTATE_BUILDING) - { - // Make sure the player's building - if ( !(gViewPort->GetBuildState() & BS_BUILDING) ) - return true; - } - else - { - // Make sure the player's not building - if ( gViewPort->GetBuildState() & BS_BUILDING ) - return true; - } - - if (m_iBuildState & BUILDSTATE_BASE) - { - // Only appear if we've got enough metal to build something, or something already built - if ( gViewPort->GetBuildState() & (BS_HAS_SENTRYGUN | BS_HAS_DISPENSER | BS_CANB_SENTRYGUN | BS_CANB_DISPENSER) ) - return false; - - return true; - } - - // Must have a building - if (m_iBuildState & BUILDSTATE_HASBUILDING) - { - if ( m_iBuildData == BuildButton::DISPENSER && !(gViewPort->GetBuildState() & BS_HAS_DISPENSER) ) - return true; - if ( m_iBuildData == BuildButton::SENTRYGUN && !(gViewPort->GetBuildState() & BS_HAS_SENTRYGUN) ) - return true; - } - - // Can build something - if (m_iBuildState & BUILDSTATE_CANBUILD) - { - // Make sure they've got the ammo and don't have one already - if ( m_iBuildData == BuildButton::DISPENSER && (gViewPort->GetBuildState() & BS_CANB_DISPENSER) ) - return false; - if ( m_iBuildData == BuildButton::SENTRYGUN && (gViewPort->GetBuildState() & BS_CANB_SENTRYGUN) ) - return false; - - return true; - } - - return false; - } -}; - -#define MAX_MAPNAME 256 - -class MapButton : public CommandButton -{ -private: - char m_szMapName[ MAX_MAPNAME ]; - -public: - MapButton( const char *pMapName, const char* text,int x,int y,int wide,int tall ) : CommandButton( text,x,y,wide,tall) - { - sprintf( m_szMapName, "maps/%s.bsp", pMapName ); - } - - virtual int IsNotValid() - { - const char *level = gEngfuncs.pfnGetLevelName(); - if (!level) - return true; - - // Does it match the current map name? - if ( strcmp(m_szMapName, level) ) - return true; - - return false; - } -}; - -//----------------------------------------------------------------------------- -// Purpose: CommandButton which is only displayed if the player is on team X -//----------------------------------------------------------------------------- -class TeamOnlyCommandButton : public CommandButton -{ -private: - int m_iTeamNum; - -public: - TeamOnlyCommandButton( int iTeamNum, const char* text,int x,int y,int wide,int tall ) : - CommandButton( text, x, y, wide, tall ), m_iTeamNum(iTeamNum) {} - - virtual int IsNotValid() - { - if ( g_iTeamNumber != m_iTeamNum ) - return true; - - return CommandButton::IsNotValid(); - } -}; - -//============================================================ -// Panel that can be dragged around -class DragNDropPanel : public Panel -{ -private: - bool m_bBeingDragged; - LineBorder *m_pBorder; -public: - DragNDropPanel(int x,int y,int wide,int tall) : Panel(x,y,wide,tall) - { - m_bBeingDragged = false; - - // Create the Drag Handler - addInputSignal( new CDragNDropHandler(this) ); - - // Create the border (for dragging) - m_pBorder = new LineBorder(); - } - - virtual void setDragged( bool bState ) - { - m_bBeingDragged = bState; - - if (m_bBeingDragged) - setBorder(m_pBorder); - else - setBorder(NULL); - } -}; - -//================================================================ -// Panel that draws itself with a transparent black background -class CTransparentPanel : public Panel -{ -private: - int m_iTransparency; -public: - CTransparentPanel(int iTrans, int x,int y,int wide,int tall) : Panel(x,y,wide,tall) - { - m_iTransparency = iTrans; - } - - virtual void paintBackground() - { - if (m_iTransparency) - { - // Transparent black background - drawSetColor( 0,0,0, m_iTransparency ); - drawFilledRect(0,0,_size[0],_size[1]); - } - } -}; - -//================================================================ -// Menu Panel that supports buffering of menus -class CMenuPanel : public CTransparentPanel -{ -private: - CMenuPanel *m_pNextMenu; - int m_iMenuID; - int m_iRemoveMe; - int m_iIsActive; - float m_flOpenTime; -public: - CMenuPanel(int iRemoveMe, int x,int y,int wide,int tall) : CTransparentPanel(100, x,y,wide,tall) - { - Reset(); - m_iRemoveMe = iRemoveMe; - } - - CMenuPanel(int iTrans, int iRemoveMe, int x,int y,int wide,int tall) : CTransparentPanel(iTrans, x,y,wide,tall) - { - Reset(); - m_iRemoveMe = iRemoveMe; - } - - virtual void Reset( void ) - { - m_pNextMenu = NULL; - m_iIsActive = false; - m_flOpenTime = 0; - } - - void SetNextMenu( CMenuPanel *pNextPanel ) - { - if (m_pNextMenu) - m_pNextMenu->SetNextMenu( pNextPanel ); - else - m_pNextMenu = pNextPanel; - } - - void SetMenuID( int iID ) - { - m_iMenuID = iID; - } - - void SetActive( int iState ) - { - m_iIsActive = iState; - } - - virtual void Open( void ) - { - setVisible( true ); - - // Note the open time, so we can delay input for a bit - m_flOpenTime = gHUD.m_flTime; - } - - virtual void Close( void ) - { - setVisible( false ); - m_iIsActive = false; - - if ( m_iRemoveMe ) - gViewPort->removeChild( this ); - - // This MenuPanel has now been deleted. Don't append code here. - } - - int ShouldBeRemoved() { return m_iRemoveMe; }; - CMenuPanel* GetNextMenu() { return m_pNextMenu; }; - int GetMenuID() { return m_iMenuID; }; - int IsActive() { return m_iIsActive; }; - float GetOpenTime() { return m_flOpenTime; }; - - // Numeric input - virtual bool SlotInput( int iSlot ) { return false; }; - virtual void SetActiveInfo( int iInput ) {}; -}; - -//================================================================ -// Custom drawn scroll bars -class CTFScrollButton : public CommandButton -{ -private: - BitmapTGA *m_pTGA; - -public: - CTFScrollButton(int iArrow, const char* text,int x,int y,int wide,int tall); - - virtual void paint( void ); - virtual void paintBackground( void ); -}; - -// Custom drawn slider bar -class CTFSlider : public Slider -{ -public: - CTFSlider(int x,int y,int wide,int tall,bool vertical) : Slider(x,y,wide,tall,vertical) - { - }; - - virtual void paintBackground( void ); -}; - -// Custom drawn scrollpanel -class CTFScrollPanel : public ScrollPanel -{ -public: - CTFScrollPanel(int x,int y,int wide,int tall); -}; - -//================================================================ -// Specific Menus to handle old HUD sections -class CHealthPanel : public DragNDropPanel -{ -private: - BitmapTGA *m_pHealthTGA; - Label *m_pHealthLabel; -public: - CHealthPanel(int x,int y,int wide,int tall) : DragNDropPanel(x,y,wide,tall) - { - // Load the Health icon - FileInputStream* fis = new FileInputStream( GetVGUITGAName("%d_hud_health"), false); - m_pHealthTGA = new BitmapTGA(fis,true); - fis->close(); - - // Create the Health Label - int iXSize,iYSize; - m_pHealthTGA->getSize(iXSize,iYSize); - m_pHealthLabel = new Label("",0,0,iXSize,iYSize); - m_pHealthLabel->setImage(m_pHealthTGA); - m_pHealthLabel->setParent(this); - - // Set panel dimension - // Shouldn't be needed once Billy's fized setImage not recalculating the size - //setSize( iXSize + 100, gHUD.m_iFontHeight + 10 ); - //m_pHealthLabel->setPos( 10, (getTall() - iYSize) / 2 ); - } - - virtual void paintBackground() - { - } - - void paint() - { - // Get the paint color - int r,g,b,a; - // Has health changed? Flash the health # - if (gHUD.m_Health.m_fFade) - { - gHUD.m_Health.m_fFade -= (gHUD.m_flTimeDelta * 20); - if (gHUD.m_Health.m_fFade <= 0) - { - a = MIN_ALPHA; - gHUD.m_Health.m_fFade = 0; - } - - // Fade the health number back to dim - a = MIN_ALPHA + (gHUD.m_Health.m_fFade/FADE_TIME) * 128; - } - else - a = MIN_ALPHA; - - gHUD.m_Health.GetPainColor( r, g, b ); - ScaleColors(r, g, b, a ); - - // If health is getting low, make it bright red - if (gHUD.m_Health.m_iHealth <= 15) - a = 255; - - int iXSize,iYSize, iXPos, iYPos; - m_pHealthTGA->getSize(iXSize,iYSize); - m_pHealthTGA->getPos(iXPos, iYPos); - - // Paint the player's health - int x = gHUD.DrawHudNumber( iXPos + iXSize + 5, iYPos + 5, DHN_3DIGITS | DHN_DRAWZERO, gHUD.m_Health.m_iHealth, r, g, b); - - // Draw the vertical line - int HealthWidth = gHUD.GetSpriteRect(gHUD.m_HUD_number_0).right - gHUD.GetSpriteRect(gHUD.m_HUD_number_0).left; - x += HealthWidth / 2; - FillRGBA(x, iYPos + 5, HealthWidth / 10, gHUD.m_iFontHeight, 255, 160, 0, a); - } -}; - -#endif diff --git a/ricochet/cl_dll/vgui_discobjects.cpp b/ricochet/cl_dll/vgui_discobjects.cpp deleted file mode 100644 index 39401e8..0000000 --- a/ricochet/cl_dll/vgui_discobjects.cpp +++ /dev/null @@ -1,593 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: VGUI objects for Discwar -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "VGUI_Font.h" - -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "parsemsg.h" -#include "ammo.h" -#include "string.h" -#include "ammohistory.h" - -#include "vgui_int.h" -#include "vgui_TeamFortressViewport.h" -#include "vgui_ServerBrowser.h" -#include "vgui_discobjects.h" - -// Positions and Dimensions -#define ARENAWINDOW_SIZE_X (ScreenWidth) -#define ARENAWINDOW_SIZE_Y YRES(128) -#define ARENAWINDOW_X ((ScreenWidth - ARENAWINDOW_SIZE_X) / 2) -#define ARENAWINDOW_Y (ScreenHeight - ARENAWINDOW_SIZE_Y) - -#define POWERUP_SIZE_X (ScreenWidth) -#define POWERUP_SIZE_Y YRES(32) -#define POWERUP_X ((ScreenWidth - POWERUP_SIZE_X) / 2) -#define POWERUP_Y (ScreenHeight - POWERUP_SIZE_Y) - -#define REWARD_SIZE_X (ScreenWidth) -#define REWARD_SIZE_Y YRES(48) -#define REWARD_X ((ScreenWidth - POWERUP_SIZE_X) / 2) -#define REWARD_Y (ScreenHeight / 6) - -extern WeaponsResource gWR; -int g_iCannotFire; - -//=========================================================== -// Disc ammo icon -CDiscPanel::CDiscPanel(int x,int y,int wide,int tall) : Label("", x,y,wide,tall) -{ - setContentFitted(true); - - // Standard discs - m_pDiscTGA_Red = LoadTGAForRes("discred"); - m_pDiscTGA_RedGlow = LoadTGAForRes("discred2"); - m_pDiscTGA_Blue = LoadTGAForRes("discblue"); - m_pDiscTGA_BlueGlow = LoadTGAForRes("discblue2"); - m_pDiscTGA_Grey = LoadTGAForRes("discgrey"); - - // Powerup discs - m_pDiscTGA_Fast = LoadTGAForRes("fast"); - m_pDiscTGA_Freeze = LoadTGAForRes("freeze"); - m_pDiscTGA_Hard = LoadTGAForRes("hard"); - m_pDiscTGA_Triple = LoadTGAForRes("triple"); - - setImage( m_pDiscTGA_Red ); -} - -void CDiscPanel::Update( int iDiscNo, bool bGlow, int iPowerup ) -{ - int iDiscs = gWR.GetAmmo( 1 ); - - // Grey disc for missing discs - if ( iDiscs < iDiscNo+1 ) - { - setImage( m_pDiscTGA_Grey ); - } - // Powerups override team colored discs - else if ( iPowerup & POW_TRIPLE ) - { - setImage( m_pDiscTGA_Triple ); - } - else if ( iPowerup & POW_FAST ) - { - setImage( m_pDiscTGA_Fast ); - } - else if ( iPowerup & POW_FREEZE ) - { - setImage( m_pDiscTGA_Freeze ); - } - else if ( iPowerup & POW_HARD ) - { - setImage( m_pDiscTGA_Hard ); - } - else if (g_iTeamNumber == 1) - { - if ( gWR.GetAmmo( 1 ) == 3 ) - setImage( m_pDiscTGA_RedGlow ); - else - setImage( m_pDiscTGA_Red ); - } - else - { - if ( gWR.GetAmmo( 1 ) == 3 ) - setImage( m_pDiscTGA_BlueGlow ); - else - setImage( m_pDiscTGA_Blue ); - } -} - -//=========================================================== -// Arena window -CDiscArenaPanel::CDiscArenaPanel( int x, int y, int wide, int tall ) : CTransparentPanel(255, x,y,wide,tall) -{ - m_iNumPlayers = 0; -} - -//=========================================================== -// Message handler. Gets the Ids of the players in the round. -int CDiscArenaPanel::MsgFunc_GetPlayers(const char *pszName, int iSize, void *pbuf ) -{ - BEGIN_READ( pbuf, iSize ); - - m_iRoundNumber = READ_BYTE(); - m_iSecondsToGo = READ_BYTE(); - - m_iNumPlayers = READ_BYTE(); - if ( m_iNumPlayers > 0 && m_iNumPlayers <= MAX_PLAYERS ) - { - for (int i = 0; i < m_iNumPlayers; i++) - m_iClients[i] = READ_SHORT(); - } - - RecalculateText(); - - return 1; -} - -//=========================================================== -// Message handler. Gets the Ids of the players in the round. -void CDiscArenaPanel::GetClientList( char *pszString ) -{ - strcpy( pszString, "" ); - for (int i = 0; i < m_iNumPlayers; i++ ) - { - if ( m_iClients[i] <= 0 || m_iClients[i] > MAX_PLAYERS ) - { - gEngfuncs.Con_Printf( "Combatant %d out of range: %d\n", i, m_iClients[i] ); - continue; - } - - if ( g_PlayerInfoList[ m_iClients[i] ].name && g_PlayerInfoList[ m_iClients[i] ].name[0] ) - { - if ( i > 0 ) - { - if ( i == (m_iNumPlayers - 1) ) - { - strcat( pszString, CHudTextMessage::BufferedLocaliseTextString( "#And" ) ); - } - else - { - strcat( pszString, ", " ); - } - } - - strcat( pszString, g_PlayerInfoList[ m_iClients[i] ].name ); - } - } -} - -//=========================================================== -// Round start window -#define ROUND_Y YRES(0) -#define TEAMONE_Y (ROUND_Y + YRES(32)) -#define VERSUS_Y (TEAMONE_Y + YRES(32)) -#define TEAMTWO_Y (VERSUS_Y + YRES(32)) - -CDiscArena_RoundStart::CDiscArena_RoundStart( void ) : CDiscArenaPanel( ARENAWINDOW_X, ARENAWINDOW_Y, ARENAWINDOW_SIZE_X, ARENAWINDOW_SIZE_Y ) -{ - m_pRound = new Label( "Round 1", 0, ROUND_Y, getWide(), YRES(32) ); - m_pRound->setParent( this ); - m_pRound->setBgColor( 0, 0, 0, 128 ); - m_pRound->setFgColor( 255,255,255, 0 ); - m_pRound->setContentAlignment( vgui::Label::a_center ); - - m_pTeamOne = new Label( "Team One", 0, TEAMONE_Y, getWide(), YRES(32) ); - m_pTeamOne->setParent( this ); - m_pTeamOne->setBgColor( 128, 0, 0, 128 ); - m_pTeamOne->setFgColor( 255,255,255, 0 ); - m_pTeamOne->setContentAlignment( vgui::Label::a_center ); - - // Trim the trailing \n from the VS string - char sz[32]; - strcpy( sz, CHudTextMessage::BufferedLocaliseTextString( "#Versus" ) ); - sz[ strlen(sz) - 1 ] = '\0'; - Label *pLabel = new Label( sz, 0, VERSUS_Y, getWide(), YRES(32) ); - pLabel->setParent( this ); - pLabel->setBgColor( 0, 0, 0, 255 ); - pLabel->setFgColor( 255,255,255, 0 ); - pLabel->setContentAlignment( vgui::Label::a_center ); - - m_pTeamTwo = new Label( "Team Two", 0, TEAMTWO_Y, getWide(), YRES(32) ); - m_pTeamTwo->setParent( this ); - m_pTeamTwo->setBgColor( 0, 0, 128, 128 ); - m_pTeamTwo->setFgColor( 255,255,255, 0 ); - m_pTeamTwo->setContentAlignment( vgui::Label::a_center ); - - setVisible(false); -} - -// Recalculate the Text in the window -void CDiscArena_RoundStart::RecalculateText( void ) -{ - char sz[1024]; - char szOpponents[1024]; - char szTemp[256]; - char szTemp2[256]; - char szTemp3[256]; - char *pszLocalized = NULL; - - // Round started? - if (m_iSecondsToGo == 0) - { - setVisible(false); - g_iCannotFire = FALSE; - - // Force spectator menu to update - if (gViewPort) - gViewPort->m_iUser1 = 0; - return; - } - - g_iCannotFire = TRUE; - - // Round Number - if ( m_iSecondsToGo != 1 ) - { - pszLocalized = "#Round_Start_n_Seconds"; - } - else - { - pszLocalized = "#Round_Start_1_Second"; - } - - strncpy( szTemp3, CHudTextMessage::BufferedLocaliseTextString( pszLocalized ), sizeof( szTemp3 ) - 1 ); - szTemp3[ sizeof( szTemp3 ) - 1 ] = '\0'; - sprintf( sz, szTemp3, m_iRoundNumber, m_iSecondsToGo ); - - m_pRound->setText( sz ); - - // We may have just got an update for the time to go. If so, m_iNumPlayers will be 0. - if ( !m_iNumPlayers ) - return; - - if (gViewPort) - gViewPort->GetAllPlayersInfo(); - - // Find out what team this client's on (if a new battle's just starting) - strcpy( szOpponents, "" ); - int iMyTeamNumber = 0; - if ( m_iRoundNumber == 1 ) - { - for (int i = 0; i < m_iNumPlayers; i++ ) - { - if ( g_PlayerInfoList[ m_iClients[i] ].thisplayer ) - iMyTeamNumber = (i < (m_iNumPlayers / 2)) ? 1 : 2; - } - } - - // Team 1 - strcpy( sz, "" ); - int i; - for (i = 0; i < (m_iNumPlayers / 2); i++ ) - { - if ( g_PlayerInfoList[ m_iClients[i] ].name && g_PlayerInfoList[ m_iClients[i] ].name[0] ) - strcat( sz, g_PlayerInfoList[ m_iClients[i] ].name ); - - if ( iMyTeamNumber == 2 ) - { - strcpy( szTemp, CHudTextMessage::BufferedLocaliseTextString( "#Opponent" ) ); - sprintf( szTemp2, szTemp, g_PlayerInfoList[ m_iClients[i] ].name, g_PlayerExtraInfo[ m_iClients[i] ].deaths, g_PlayerExtraInfo[ m_iClients[i] ].frags ); - strcat( szOpponents, szTemp2 ); - } - } - m_pTeamOne->setText( sz ); - - // Team 2 - strcpy( sz, "" ); - for ( ; i < m_iNumPlayers; i++ ) - { - if ( g_PlayerInfoList[ m_iClients[i] ].name && g_PlayerInfoList[ m_iClients[i] ].name[0] ) - strcat( sz, g_PlayerInfoList[ m_iClients[i] ].name ); - - if ( iMyTeamNumber == 1 ) - { - strcpy( szTemp, CHudTextMessage::BufferedLocaliseTextString( "#Opponent" ) ); - sprintf( szTemp2, szTemp, g_PlayerInfoList[ m_iClients[i] ].name, g_PlayerExtraInfo[ m_iClients[i] ].deaths, g_PlayerExtraInfo[ m_iClients[i] ].frags ); - strcat( szOpponents, szTemp2 ); - } - } - m_pTeamTwo->setText( sz ); - - // Bring up the Opponent details - if (gViewPort) - gViewPort->m_pDiscRewardWindow->SetMessage( szOpponents ); - - // Become visible - setVisible(true); - - // Hide the other windows if it's up - if (gViewPort) - { - gViewPort->m_pSpectatorMenu->setVisible( false ); - gViewPort->m_pDiscPowerupWindow->setVisible( false ); - gViewPort->m_pDiscEndRound->setVisible( false ); - } -} - -//=========================================================== -// Round end window -CDiscArena_RoundEnd::CDiscArena_RoundEnd( void ) : CDiscArenaPanel( ARENAWINDOW_X, ARENAWINDOW_Y, ARENAWINDOW_SIZE_X, ARENAWINDOW_SIZE_Y ) -{ - m_pRound = new Label( "Round 1 Won By", 0, ROUND_Y, getWide(), YRES(32) ); - m_pRound->setParent( this ); - m_pRound->setBgColor( 0, 0, 0, 128 ); - m_pRound->setFgColor( 255,255,255, 0 ); - m_pRound->setContentAlignment( vgui::Label::a_center ); - - m_pWinners = new Label( "Winners", 0, TEAMONE_Y, getWide(), YRES(32) ); - m_pWinners->setParent( this ); - m_pWinners->setBgColor( 128, 0, 0, 128 ); - m_pWinners->setFgColor( 255,255,255, 0 ); - m_pWinners->setContentAlignment( vgui::Label::a_center ); - - m_pWinningTeam = new Label( "Winners", 0, TEAMTWO_Y, getWide(), YRES(32) ); - m_pWinningTeam->setParent( this ); - m_pWinningTeam->setBgColor( 128, 0, 0, 128 ); - m_pWinningTeam->setFgColor( 255,255,255, 0 ); - m_pWinningTeam->setContentAlignment( vgui::Label::a_center ); - - setVisible(false); -} - -// Recalculate the Text in the window -void CDiscArena_RoundEnd::RecalculateText( void ) -{ - char sz[1024]; - char szTemp1[256]; - char szTemp2[256]; - - // Sends down a 0 for time when this should be removed - if (m_iSecondsToGo == 0) - { - setVisible(false); - g_iCannotFire = FALSE; - - // Force spectator menu to update - if (gViewPort) - gViewPort->m_iUser1 = 0; - return; - } - - g_iCannotFire = TRUE; - - // Round Number - strncpy( szTemp1, CHudTextMessage::BufferedLocaliseTextString( "#Round_Won" ), sizeof( szTemp1 ) - 1 ); - szTemp1[ sizeof( szTemp1 ) - 1 ] = '\0'; - sprintf( sz, szTemp1, m_iRoundNumber ); - - m_pRound->setText( sz ); - - if (gViewPort) - gViewPort->GetAllPlayersInfo(); - - // Winners - GetClientList( sz ); - m_pWinners->setText( sz ); - - // Scores - m_iNumPlayers = READ_BYTE(); - if ( m_iNumPlayers >= 0 && m_iNumPlayers <= MAX_PLAYERS ) - { - for (int i = 0; i < m_iNumPlayers; i++) - m_iClients[i] = READ_SHORT(); - - int iWinningScore = READ_BYTE(); - int iLosingScore = READ_BYTE(); - int iBattleOver = READ_BYTE(); - - // Battle over? - if ( iBattleOver ) - { - GetClientList( sz ); - - strncpy( szTemp2, CHudTextMessage::BufferedLocaliseTextString( "#Round_Won_Scores" ), sizeof( szTemp2 ) - 1 ); - szTemp2[ sizeof( szTemp2 ) - 1 ] = '\0'; - - _snprintf( sz, sizeof( sz ) - 1, szTemp2, sz, iWinningScore, iLosingScore ); - } - // Tied? - else if ( iWinningScore == iLosingScore ) - { - strncpy( szTemp2, CHudTextMessage::BufferedLocaliseTextString( "#Round_Tied" ), sizeof( szTemp2 ) - 1 ); - szTemp2[ sizeof( szTemp2 ) - 1 ] = '\0'; - - _snprintf( sz, sizeof( sz ) - 1, szTemp2, iWinningScore ); - } - else - { - char *pszTemp = NULL; - - GetClientList( sz ); - - if ( m_iNumPlayers == 1 ) - { - pszTemp = "#Round_Leads"; - } - else - { - pszTemp = "#Round_Lead"; - } - - strncpy( szTemp2, CHudTextMessage::BufferedLocaliseTextString( pszTemp ), sizeof( szTemp2 ) - 1 ); - szTemp2[ sizeof( szTemp2 ) - 1 ] = '\0'; - - _snprintf( sz, sizeof( sz ) - 1, szTemp2, sz, iWinningScore, iLosingScore ); - } - - sz[ sizeof( sz ) - 1 ] = '\0'; - m_pWinningTeam->setText( sz ); - } - - // Become visible - setVisible(true); - - // Hide the other windows if it's up - if (gViewPort) - { - gViewPort->m_pSpectatorMenu->setVisible( false ); - gViewPort->m_pDiscPowerupWindow->setVisible( false ); - gViewPort->m_pDiscStartRound->setVisible( false ); - } -} - -//=========================================================== -// Powerup name window -CDiscPowerups::CDiscPowerups() : CTransparentPanel( 255, POWERUP_X, POWERUP_Y, POWERUP_SIZE_X, POWERUP_SIZE_Y ) -{ - m_pLabel = new Label( "Powerups Go Here", 0, ROUND_Y, getWide(), YRES(32) ); - m_pLabel->setParent( this ); - m_pLabel->setBgColor( 0, 0, 0, 255 ); - m_pLabel->setFgColor( 255,255,255, 0 ); - m_pLabel->setContentAlignment( vgui::Label::a_center ); - setVisible(false); -}; - -void CDiscPowerups::RecalculateText( int iPowerup ) -{ - char sz[512]; - bool bAnd = false; - - // Don't appear if a round message is up - if (gViewPort) - { - if ( gViewPort->m_pDiscStartRound->isVisible() || gViewPort->m_pDiscEndRound->isVisible() ) - return; - } - - sprintf(sz, ""); - - if ( iPowerup & POW_TRIPLE ) - { - strcat(sz, CHudTextMessage::BufferedLocaliseTextString("#Triple") ); - bAnd = true; - } - - if ( iPowerup & POW_FAST ) - { - if (bAnd) - strcat(sz, ", "); - strcat(sz, CHudTextMessage::BufferedLocaliseTextString("#Fast") ); - bAnd = true; - } - - if ( iPowerup & POW_FREEZE ) - { - if (bAnd) - strcat(sz, ", "); - strcat(sz, CHudTextMessage::BufferedLocaliseTextString("#Freeze") ); - bAnd = true; - } - - if ( iPowerup & POW_HARD ) - { - if (bAnd) - strcat(sz, ", "); - strcat(sz, CHudTextMessage::BufferedLocaliseTextString("#Hard") ); - } - - m_pLabel->setText( sz ); - - // Become visible - if (sz && sz[0]) - setVisible(true); - else - setVisible(false); -} - -//=========================================================== -// Reward menu -CDiscRewards::CDiscRewards() : CTransparentPanel( 255, REWARD_X, REWARD_Y, REWARD_SIZE_X, REWARD_SIZE_Y ) -{ - m_pReward = new Label( "Well Done!", 0, ROUND_Y, getWide(), (REWARD_SIZE_Y / 2) ); - m_pReward->setParent( this ); - m_pReward->setBgColor( 0, 0, 0, 255 ); - m_pReward->setFgColor( 255,255,255, 0 ); - m_pReward->setContentAlignment( vgui::Label::a_center ); - setVisible(false); - - m_pTeleBonus = new Label( CHudTextMessage::BufferedLocaliseTextString( "#Hit_Tele" ), 0, (REWARD_SIZE_Y / 2), getWide(), (REWARD_SIZE_Y / 2) ); - m_pTeleBonus->setParent( this ); - m_pTeleBonus->setBgColor( 0, 0, 0, 255 ); - m_pTeleBonus->setFgColor( 255,255,255, 0 ); - m_pTeleBonus->setContentAlignment( vgui::Label::a_center ); -}; - -void CDiscRewards::RecalculateText( int iReward ) -{ - char sz[512]; - - // Don't appear if a round message is up - if (gViewPort) - { - if ( gViewPort->m_pDiscStartRound->isVisible() || gViewPort->m_pDiscEndRound->isVisible() ) - return; - } - - if ( !iReward ) - { - setVisible( false ); - return; - } - - // Rewards - if ( iReward & REWARD_BOUNCE_NONE ) - sprintf( sz, CHudTextMessage::BufferedLocaliseTextString( "#Hit_Direct" ) ); - if ( iReward & REWARD_BOUNCE_ONE ) - sprintf( sz, CHudTextMessage::BufferedLocaliseTextString( "#Hit_One" ) ); - if ( iReward & REWARD_BOUNCE_TWO ) - sprintf( sz, CHudTextMessage::BufferedLocaliseTextString( "#Hit_Two" ) ); - if ( iReward & REWARD_BOUNCE_THREE ) - sprintf( sz, CHudTextMessage::BufferedLocaliseTextString( "#Hit_Three" ) ); - if ( iReward & REWARD_DECAPITATE ) - sprintf( sz, CHudTextMessage::BufferedLocaliseTextString( "#Hit_Decap" ) ); - if ( iReward & REWARD_DOUBLEKILL ) - sprintf( sz, CHudTextMessage::BufferedLocaliseTextString( "#Hit_Multiple" ) ); - - if ( iReward & REWARD_TELEPORT ) - m_pTeleBonus->setVisible( true ); - else - m_pTeleBonus->setVisible( false ); - - m_pReward->setText( sz ); - setVisible( true ); -} - -void CDiscRewards::SetMessage( char *pMessage ) -{ - if (!pMessage) - { - setVisible(false); - return; - } - - m_pTeleBonus->setVisible( false ); - m_pReward->setText( pMessage ); - setVisible( true ); - - if (gViewPort) - gViewPort->m_flRewardOpenTime = gHUD.m_flTime + 5.0; -} \ No newline at end of file diff --git a/ricochet/cl_dll/vgui_discobjects.h b/ricochet/cl_dll/vgui_discobjects.h deleted file mode 100644 index 0290a59..0000000 --- a/ricochet/cl_dll/vgui_discobjects.h +++ /dev/null @@ -1,109 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: VGUI objects for Discwar -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#ifndef VGUI_DISCOBJECTS_H -#define VGUI_DISCOBJECTS_H -#pragma once - -//=========================================================== -// Disc ammo icon -class CDiscPanel : public Label -{ -private: - BitmapTGA *m_pDiscTGA_Red; - BitmapTGA *m_pDiscTGA_RedGlow; - BitmapTGA *m_pDiscTGA_Blue; - BitmapTGA *m_pDiscTGA_BlueGlow; - BitmapTGA *m_pDiscTGA_Grey; - BitmapTGA *m_pDiscTGA_Fast; - BitmapTGA *m_pDiscTGA_Freeze; - BitmapTGA *m_pDiscTGA_Hard; - BitmapTGA *m_pDiscTGA_Triple; -public: - CDiscPanel(int x,int y,int wide,int tall); - void Update( int iDiscNo, bool bGlow, int iPowerup ); - - virtual void paintBackground() - { - // Do nothing, so the background's left transparent. - } -}; - -//=========================================================== -// Powerup -class CDiscPowerups : public CTransparentPanel -{ -public: - CDiscPowerups(); - - void RecalculateText( int iPowerup ); - Label *m_pLabel; -}; - -class CDiscRewards : public CTransparentPanel -{ -public: - CDiscRewards(); - - void RecalculateText( int iReward ); - void SetMessage( char *pMessage ); - Label *m_pReward; - Label *m_pTeleBonus; -}; - -//=========================================================== -// Arena windows -class CDiscArenaPanel : public CTransparentPanel -{ -public: - CDiscArenaPanel( int x, int y, int wide, int tall ); - int MsgFunc_GetPlayers(const char *pszName, int iSize, void *pbuf ); - virtual void RecalculateText( void ) {}; - void GetClientList( char *pszString ); - - int m_iNumPlayers; - int m_iClients[ MAX_PLAYERS ]; - int m_iRoundNumber; - int m_iSecondsToGo; -}; - -class CDiscArena_RoundStart : public CDiscArenaPanel -{ -public: - CDiscArena_RoundStart(); - - void RecalculateText( void ); - - Label *m_pRound; - Label *m_pTeamOne; - Label *m_pTeamTwo; -}; - -class CDiscArena_RoundEnd : public CDiscArenaPanel -{ -public: - CDiscArena_RoundEnd(); - - void RecalculateText( void ); - - Label *m_pRound; - Label *m_pWinners; - Label *m_pWinningTeam; -}; - -#endif // VGUI_DISCOBJECTS_H diff --git a/ricochet/cl_dll/vgui_int.cpp b/ricochet/cl_dll/vgui_int.cpp deleted file mode 100644 index cb30561..0000000 --- a/ricochet/cl_dll/vgui_int.cpp +++ /dev/null @@ -1,122 +0,0 @@ - -#include"vgui_int.h" -#include -#include -#include -#include -#include -#include -#include -#include "hud.h" -#include "cl_util.h" -#include "camera.h" -#include "kbutton.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" -#include "camera.h" -#include "in_defs.h" -#include "vgui_TeamFortressViewport.h" -#include "vgui_ControlConfigPanel.h" - -namespace -{ - -class TexturePanel : public Panel , public ActionSignal -{ -private: - int _bindIndex; - TextEntry* _textEntry; -public: - TexturePanel() : Panel(0,0,256,276) - { - _bindIndex=2700; - _textEntry=new TextEntry("2700",0,0,128,20); - _textEntry->setParent(this); - _textEntry->addActionSignal(this); - } -public: - virtual bool isWithin(int x,int y) - { - return _textEntry->isWithin(x,y); - } -public: - virtual void actionPerformed(Panel* panel) - { - char buf[256]; - _textEntry->getText(0,buf,256); - sscanf(buf,"%d",&_bindIndex); - } -protected: - virtual void paintBackground() - { - Panel::paintBackground(); - - int wide,tall; - getPaintSize(wide,tall); - - drawSetColor(0,0,255,0); - drawSetTexture(_bindIndex); - drawTexturedRect(0,19,257,257); - } - -}; - -} - -using namespace vgui; - -void VGui_ViewportPaintBackground(int extents[4]) -{ - gEngfuncs.VGui_ViewportPaintBackground(extents); -} - -void* VGui_GetPanel() -{ - return (Panel*)gEngfuncs.VGui_GetPanel(); -} - -void VGui_Startup() -{ - Panel* root=(Panel*)VGui_GetPanel(); - root->setBgColor(128,128,0,0); - //root->setNonPainted(false); - //root->setBorder(new LineBorder()); - root->setLayout(new BorderLayout(0)); - - - //root->getSurfaceBase()->setEmulatedCursorVisible(true); - - if (gViewPort != NULL) - { -// root->removeChild(gViewPort); - - // free the memory -// delete gViewPort; -// gViewPort = NULL; - - gViewPort->Initialize(); - } - else - { - gViewPort = new TeamFortressViewport(0,0,root->getWide(),root->getTall()); - gViewPort->setParent(root); - } - - /* - TexturePanel* texturePanel=new TexturePanel(); - texturePanel->setParent(gViewPort); - */ - -} - -void VGui_Shutdown() -{ - delete gViewPort; - gViewPort = NULL; -} - - - - - diff --git a/ricochet/cl_dll/vgui_int.h b/ricochet/cl_dll/vgui_int.h deleted file mode 100644 index a90f80c..0000000 --- a/ricochet/cl_dll/vgui_int.h +++ /dev/null @@ -1,15 +0,0 @@ - -#ifndef VGUI_INT_H -#define VGUI_INT_H - -extern "C" -{ -void VGui_Startup(); -void VGui_Shutdown(); - -//Only safe to call from inside subclass of Panel::paintBackground -void VGui_ViewportPaintBackground(int extents[4]); -} - - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/view.cpp b/ricochet/cl_dll/view.cpp deleted file mode 100644 index aab55ea..0000000 --- a/ricochet/cl_dll/view.cpp +++ /dev/null @@ -1,1058 +0,0 @@ -// view/refresh setup functions - -#include "hud.h" -#include "cl_util.h" -#include "cvardef.h" -#include "usercmd.h" -#include "const.h" - -#include "entity_state.h" -#include "cl_entity.h" -#include "ref_params.h" -#include "in_defs.h" // PITCH YAW ROLL -#include "pm_movevars.h" -#include "pm_shared.h" -#include "pmtrace.h" -#include "screenfade.h" -#include "shake.h" - -// Spectator Mode -extern float vecNewViewAngles[3]; -extern int iHasNewViewAngles; -extern float vecNewViewOrigin[3]; -extern int iHasNewViewOrigin; -extern int iIsSpectator; - -extern float g_flStartScaleTime; -extern int iMouseInUse; -void CAM_ToThirdPerson(void); -void CAM_ToFirstPerson(void); - -#ifndef M_PI -#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h -#endif - -extern "C" -{ - int CL_IsThirdPerson( void ); - void CL_CameraOffset( float *ofs ); - - void DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams ); - - void PM_ParticleLine( float *start, float *end, int pcolor, float life, float vert); - int PM_GetInfo( int ent ); - -} - -void V_DropPunchAngle ( float frametime, float *ev_punchangle ); -void VectorAngles( const float *forward, float *angles ); - -/* -The view is allowed to move slightly from it's true position for bobbing, -but if it exceeds 8 pixels linear distance (spherical, not box), the list of -entities sent from the server may not include everything in the pvs, especially -when crossing a water boudnary. -*/ - -extern cvar_t *cl_forwardspeed; -extern cvar_t *chase_active; -extern cvar_t *scr_ofsx, *scr_ofsy, *scr_ofsz; -extern cvar_t *cl_vsmoothing; - -vec3_t v_origin, v_angles; - -vec3_t ev_punchangle; - -cvar_t *scr_ofsx; -cvar_t *scr_ofsy; -cvar_t *scr_ofsz; - -cvar_t *v_centermove; -cvar_t *v_centerspeed; - -cvar_t *cl_bobcycle; -cvar_t *cl_bob; -cvar_t *cl_bobup; -cvar_t *cl_waterdist; - -// These cvars are not registered (so users can't cheat), so set the ->value field directly -// Register these cvars in V_Init() if needed for easy tweaking -cvar_t v_iyaw_cycle = {"v_iyaw_cycle", "2", 0, 2}; -cvar_t v_iroll_cycle = {"v_iroll_cycle", "0.5", 0, 0.5}; -cvar_t v_ipitch_cycle = {"v_ipitch_cycle", "1", 0, 1}; -cvar_t v_iyaw_level = {"v_iyaw_level", "0.3", 0, 0.3}; -cvar_t v_iroll_level = {"v_iroll_level", "0.1", 0, 0.1}; -cvar_t v_ipitch_level = {"v_ipitch_level", "0.3", 0, 0.3}; - -float v_idlescale; // used by TFC for concussion grenade effect - -//============================================================================= -void V_NormalizeAngles( float *angles ) -{ - int i; - // Normalize angles - for ( i = 0; i < 3; i++ ) - { - if ( angles[i] > 180.0 ) - { - angles[i] -= 360.0; - } - else if ( angles[i] < -180.0 ) - { - angles[i] += 360.0; - } - } -} - -/* -=================== -V_InterpolateAngles - -Interpolate Euler angles. -FIXME: Use Quaternions to avoid discontinuities -Frac is 0.0 to 1.0 ( i.e., should probably be clamped, but doesn't have to be ) -=================== -*/ -void V_InterpolateAngles( float *start, float *end, float *output, float frac ) -{ - int i; - float ang1, ang2; - float d; - - V_NormalizeAngles( start ); - V_NormalizeAngles( end ); - - for ( i = 0 ; i < 3 ; i++ ) - { - ang1 = start[i]; - ang2 = end[i]; - - d = ang2 - ang1; - if ( d > 180 ) - { - d -= 360; - } - else if ( d < -180 ) - { - d += 360; - } - - output[i] = ang1 + d * frac; - } - - V_NormalizeAngles( output ); -} - -// Quakeworld bob code, this fixes jitters in the mutliplayer since the clock (pparams->time) isn't quite linear -float V_CalcBob ( struct ref_params_s *pparams ) -{ - static double bobtime; - static float bob; - float cycle; - static float lasttime; - vec3_t vel; - - if ( pparams->spectator || iIsSpectator ) - return 0; - - if ( pparams->onground == -1 || - pparams->time == lasttime ) - { - // just use old value - return bob; - } - - lasttime = pparams->time; - - bobtime += pparams->frametime; - cycle = bobtime - (int)( bobtime / cl_bobcycle->value ) * cl_bobcycle->value; - cycle /= cl_bobcycle->value; - - if ( cycle < cl_bobup->value ) - { - cycle = M_PI * cycle / cl_bobup->value; - } - else - { - cycle = M_PI + M_PI * ( cycle - cl_bobup->value )/( 1.0 - cl_bobup->value ); - } - - // bob is proportional to simulated velocity in the xy plane - // (don't count Z, or jumping messes it up) - VectorCopy( pparams->simvel, vel ); - vel[2] = 0; - - bob = sqrt( vel[0] * vel[0] + vel[1] * vel[1] ) * cl_bob->value; - bob = bob * 0.3 + bob * 0.7 * sin(cycle); - bob = V_min( bob, 4 ); - bob = V_max( bob, -7 ); - return bob; - -} - -/* -=============== -V_CalcRoll -Used by view and sv_user -=============== -*/ -float V_CalcRoll (vec3_t angles, vec3_t velocity, float rollangle, float rollspeed ) -{ - float sign; - float side; - float value; - vec3_t forward, right, up; - - AngleVectors ( angles, forward, right, up ); - - side = DotProduct (velocity, right); - sign = side < 0 ? -1 : 1; - side = fabs( side ); - - value = rollangle; - if (side < rollspeed) - { - side = side * value / rollspeed; - } - else - { - side = value; - } - return side * sign; -} - -typedef struct pitchdrift_s -{ - float pitchvel; - int nodrift; - float driftmove; - double laststop; -} pitchdrift_t; - -static pitchdrift_t pd; - -void V_StartPitchDrift( void ) -{ - if ( pd.laststop == gEngfuncs.GetClientTime() ) - { - return; // something else is keeping it from drifting - } - - if ( pd.nodrift || !pd.pitchvel ) - { - pd.pitchvel = v_centerspeed->value; - pd.nodrift = 0; - pd.driftmove = 0; - } -} - -void V_StopPitchDrift ( void ) -{ - pd.laststop = gEngfuncs.GetClientTime(); - pd.nodrift = 1; - pd.pitchvel = 0; -} - -/* -=============== -V_DriftPitch - -Moves the client pitch angle towards idealpitch sent by the server. - -If the user is adjusting pitch manually, either with lookup/lookdown, -mlook and mouse, or klook and keyboard, pitch drifting is constantly stopped. -=============== -*/ -void V_DriftPitch ( struct ref_params_s *pparams ) -{ - float delta, move; - - if ( gEngfuncs.IsNoClipping() || !pparams->onground || pparams->demoplayback || pparams->spectator ) - { - pd.driftmove = 0; - pd.pitchvel = 0; - return; - } - - // don't count small mouse motion - if (pd.nodrift) - { - if ( fabs( pparams->cmd->forwardmove ) < cl_forwardspeed->value ) - pd.driftmove = 0; - else - pd.driftmove += pparams->frametime; - - if ( pd.driftmove > v_centermove->value) - { - V_StartPitchDrift (); - } - return; - } - - delta = pparams->idealpitch - pparams->cl_viewangles[PITCH]; - - if (!delta) - { - pd.pitchvel = 0; - return; - } - - move = pparams->frametime * pd.pitchvel; - pd.pitchvel += pparams->frametime * v_centerspeed->value; - -//Con_Printf ("move: %f (%f)\n", move, pparams->frametime); - - if (delta > 0) - { - if (move > delta) - { - pd.pitchvel = 0; - move = delta; - } - pparams->cl_viewangles[PITCH] += move; - } - else if (delta < 0) - { - if (move > -delta) - { - pd.pitchvel = 0; - move = -delta; - } - pparams->cl_viewangles[PITCH] -= move; - } -} - -/* -============================================================================== - VIEW RENDERING -============================================================================== -*/ - -/* -================== -V_CalcGunAngle -================== -*/ -void V_CalcGunAngle ( struct ref_params_s *pparams ) -{ - cl_entity_t *viewent; - - viewent = gEngfuncs.GetViewModel(); - if ( !viewent ) - return; - - viewent->angles[YAW] = pparams->viewangles[YAW] + pparams->crosshairangle[YAW]; - viewent->angles[PITCH] = -pparams->viewangles[PITCH] + pparams->crosshairangle[PITCH] * 0.25; - viewent->angles[ROLL] -= v_idlescale * sin(pparams->time*v_iroll_cycle.value) * v_iroll_level.value; - - // don't apply all of the v_ipitch to prevent normally unseen parts of viewmodel from coming into view. - viewent->angles[PITCH] -= v_idlescale * sin(pparams->time*v_ipitch_cycle.value) * (v_ipitch_level.value * 0.5); - viewent->angles[YAW] -= v_idlescale * sin(pparams->time*v_iyaw_cycle.value) * v_iyaw_level.value; - - VectorCopy( viewent->angles, viewent->curstate.angles ); - VectorCopy( viewent->angles, viewent->latched.prevangles ); -} - -/* -============== -V_AddIdle - -Idle swaying -============== -*/ -void V_AddIdle ( struct ref_params_s *pparams ) -{ - pparams->viewangles[ROLL] += v_idlescale * sin(pparams->time*v_iroll_cycle.value) * v_iroll_level.value; - pparams->viewangles[PITCH] += v_idlescale * sin(pparams->time*v_ipitch_cycle.value) * v_ipitch_level.value; - pparams->viewangles[YAW] += v_idlescale * sin(pparams->time*v_iyaw_cycle.value) * v_iyaw_level.value; -} - - -/* -============== -V_CalcViewRoll - -Roll is induced by movement and damage -============== -*/ -void V_CalcViewRoll ( struct ref_params_s *pparams ) -{ - float side; - cl_entity_t *viewentity; - - viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); - if ( !viewentity ) - return; - - side = V_CalcRoll ( viewentity->angles, pparams->simvel, pparams->movevars->rollangle, pparams->movevars->rollspeed ); - - pparams->viewangles[ROLL] += side; - - if ( pparams->health <= 0 && ( pparams->viewheight[2] != 0 ) ) - { - // only roll the view if the player is dead and the viewheight[2] is nonzero - // this is so deadcam in multiplayer will work. - pparams->viewangles[ROLL] = 80; // dead view angle - return; - } -} - - -/* -================== -V_CalcIntermissionRefdef - -================== -*/ -void V_CalcIntermissionRefdef ( struct ref_params_s *pparams ) -{ - cl_entity_t *ent, *view; - float old; - -// don't allow cheats in multiplayer -#if !defined( _DEBUG ) - if ( pparams->maxclients > 1 ) - { - gEngfuncs.Cvar_SetValue ("scr_ofsx", 0); - gEngfuncs.Cvar_SetValue ("scr_ofsy", 0); - gEngfuncs.Cvar_SetValue ("scr_ofsz", 0); - } -#endif - - // ent is the player model ( visible when out of body ) - ent = gEngfuncs.GetLocalPlayer(); - - // view is the weapon model (only visible from inside body ) - view = gEngfuncs.GetViewModel(); - - VectorCopy ( pparams->simorg, pparams->vieworg ); - VectorCopy ( pparams->cl_viewangles, pparams->viewangles ); - - view->model = NULL; - - // allways idle in intermission - old = v_idlescale; - v_idlescale = 1; - - V_AddIdle ( pparams ); - - v_idlescale = old; - - v_origin = pparams->vieworg; - v_angles = pparams->viewangles; -} - -#define ORIGIN_BACKUP 64 -#define ORIGIN_MASK ( ORIGIN_BACKUP - 1 ) - -typedef struct -{ - float Origins[ ORIGIN_BACKUP ][3]; - float OriginTime[ ORIGIN_BACKUP ]; - - float Angles[ ORIGIN_BACKUP ][3]; - float AngleTime[ ORIGIN_BACKUP ]; - - int CurrentOrigin; - int CurrentAngle; -} viewinterp_t; - -/* -================== -V_CalcRefdef - -================== -*/ -void V_CalcNormalRefdef ( struct ref_params_s *pparams ) -{ - cl_entity_t *ent, *view; - int i; - vec3_t angles; - float bob, waterOffset; - static viewinterp_t ViewInterp; - - static float oldz = 0; - static float lasttime; - - static float lastang[3]; - vec3_t angdelta; - - vec3_t camAngles, camForward, camRight, camUp; - cl_entity_t *pwater; - - // don't allow cheats in multiplayer - if ( pparams->maxclients > 1 ) - { - scr_ofsx->value = 0.0; - scr_ofsy->value = 0.0; - scr_ofsz->value = 0.0; - } - - - V_DriftPitch ( pparams ); - - // ent is the player model ( visible when out of body ) - ent = gEngfuncs.GetLocalPlayer(); - - // view is the weapon model (only visible from inside body ) - view = gEngfuncs.GetViewModel(); - - // transform the view offset by the model's matrix to get the offset from - // model origin for the view - bob = V_CalcBob ( pparams ); - - // Observer angle capturing and smoothing - if ( iHasNewViewOrigin ) - { - // Get the angles from the physics code - VectorCopy( vecNewViewOrigin, pparams->vieworg ); - VectorCopy( vecNewViewOrigin, pparams->simorg ); - } - - // refresh position - VectorCopy ( pparams->simorg, pparams->vieworg ); - pparams->vieworg[2] += ( bob ); - VectorAdd( pparams->vieworg, pparams->viewheight, pparams->vieworg ); - - // Observer angle capturing and smoothing - if ( iHasNewViewAngles ) - { - // Get the angles from the physics code - VectorCopy( vecNewViewAngles, pparams->cl_viewangles ); - } - else if ( pparams->health == -5 ) - { - CAM_ToThirdPerson(); - - // Lock mouse movement - iMouseInUse=1; - - pparams->cl_viewangles[0] = 89; - - // Spin the view - float flTimeDelta = (pparams->time - g_flStartScaleTime); - if ( flTimeDelta > 0 ) - { - float flROFSpin = 1.0 + (flTimeDelta * 2.0); - float flSpin = flTimeDelta * 45; - - pparams->cl_viewangles[1] = flSpin * flROFSpin; - } - } - else - { - CAM_ToFirstPerson(); - - // Unlock mouse movement - iMouseInUse=0; - } - - VectorSubtract( pparams->cl_viewangles, lastang, angdelta ); - if ( Length( angdelta ) != 0.0 ) - { - VectorCopy( pparams->cl_viewangles, ViewInterp.Angles[ ViewInterp.CurrentAngle & ORIGIN_MASK ] ); - ViewInterp.AngleTime[ ViewInterp.CurrentAngle & ORIGIN_MASK ] = pparams->time; - ViewInterp.CurrentAngle++; - - VectorCopy( pparams->cl_viewangles, lastang ); - } - - if ( cl_vsmoothing && cl_vsmoothing->value && ( iIsSpectator & SPEC_SMOOTH_ANGLES ) ) - { - int foundidx; - int i; - float t; - - if ( cl_vsmoothing->value < 0.0 ) - { - gEngfuncs.Cvar_SetValue( "cl_vsmoothing", 0.0 ); - } - - t = pparams->time - cl_vsmoothing->value; - - for ( i = 1; i < ORIGIN_MASK; i++ ) - { - foundidx = ViewInterp.CurrentAngle - 1 - i; - if ( ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ] <= t ) - break; - } - - if ( i < ORIGIN_MASK && ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ] != 0.0 ) - { - // Interpolate - double dt; - - dt = ViewInterp.AngleTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.AngleTime[ foundidx & ORIGIN_MASK ]; - if ( dt > 0.0 ) - { - double frac; - - frac = ( t - ViewInterp.AngleTime[ foundidx & ORIGIN_MASK] ) / dt; - frac = V_min( 1.0, frac ); - - // interpolate angles - V_InterpolateAngles( ViewInterp.Angles[ foundidx & ORIGIN_MASK ], ViewInterp.Angles[ (foundidx + 1) & ORIGIN_MASK ], pparams->cl_viewangles, frac ); - - VectorCopy( pparams->cl_viewangles, vecNewViewAngles ); - } - } - } - - VectorCopy ( pparams->cl_viewangles, pparams->viewangles ); - - gEngfuncs.V_CalcShake(); - gEngfuncs.V_ApplyShake( pparams->vieworg, pparams->viewangles, 1.0 ); - - // never let view origin sit exactly on a node line, because a water plane can - // dissapear when viewed with the eye exactly on it. - // FIXME, we send origin at 1/128 now, change this? - // the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis - - pparams->vieworg[0] += 1.0/32; - pparams->vieworg[1] += 1.0/32; - pparams->vieworg[2] += 1.0/32; - - // Check for problems around water, move the viewer artificially if necessary - // -- this prevents drawing errors in GL due to waves - - waterOffset = 0; - if ( pparams->waterlevel >= 2 ) - { - int i, contents, waterDist, waterEntity; - vec3_t point; - waterDist = cl_waterdist->value; - - if ( pparams->hardware ) - { - waterEntity = gEngfuncs.PM_WaterEntity( pparams->simorg ); - if ( waterEntity >= 0 && waterEntity < pparams->max_entities ) - { - pwater = gEngfuncs.GetEntityByIndex( waterEntity ); - if ( pwater && ( pwater->model != NULL ) ) - { - waterDist += ( pwater->curstate.scale * 16 ); // Add in wave height - } - } - } - else - { - waterEntity = 0; // Don't need this in software - } - - VectorCopy( pparams->vieworg, point ); - - // Eyes are above water, make sure we're above the waves - if ( pparams->waterlevel == 2 ) - { - point[2] -= waterDist; - for ( i = 0; i < waterDist; i++ ) - { - contents = gEngfuncs.PM_PointContents( point, NULL ); - if ( contents > CONTENTS_WATER ) - break; - point[2] += 1; - } - waterOffset = (point[2] + waterDist) - pparams->vieworg[2]; - } - else - { - // eyes are under water. Make sure we're far enough under - point[2] += waterDist; - - for ( i = 0; i < waterDist; i++ ) - { - contents = gEngfuncs.PM_PointContents( point, NULL ); - if ( contents <= CONTENTS_WATER ) - break; - point[2] -= 1; - } - waterOffset = (point[2] - waterDist) - pparams->vieworg[2]; - } - } - - pparams->vieworg[2] += waterOffset; - - V_CalcViewRoll ( pparams ); - - V_AddIdle ( pparams ); - - // offsets - VectorCopy( pparams->cl_viewangles, angles ); - - AngleVectors ( angles, pparams->forward, pparams->right, pparams->up ); - - for ( i=0 ; i<3 ; i++ ) - { - pparams->vieworg[i] += scr_ofsx->value*pparams->forward[i] + scr_ofsy->value*pparams->right[i] + scr_ofsz->value*pparams->up[i]; - } - - // Treating cam_ofs[2] as the distance - if( CL_IsThirdPerson() ) - { - vec3_t ofs; - ofs[0] = ofs[1] = ofs[2] = 0.0; - CL_CameraOffset( (float *)&ofs ); - - VectorCopy( ofs, camAngles ); - camAngles[ ROLL ] = 0; - AngleVectors( camAngles, camForward, camRight, camUp ); - - // Is the player in a falling anim? If so, raise camera above and look down - if ( pparams->health == -5 ) - { - pparams->vieworg[2] += 92; - } - else - { - for ( i = 0; i < 3; i++ ) - { - pparams->vieworg[ i ] += -ofs[2] * camForward[ i ]; - } - - pparams->vieworg[2] += 20; - } - } - - // Give gun our viewangles - VectorCopy ( pparams->cl_viewangles, view->angles ); - - // set up gun position - V_CalcGunAngle ( pparams ); - - // Use predicted origin as view origin. - VectorCopy ( pparams->simorg, view->origin ); - view->origin[2] += ( waterOffset ); - VectorAdd( view->origin, pparams->viewheight, view->origin ); - - // Let the viewmodel shake at about 10% of the amplitude - gEngfuncs.V_ApplyShake( view->origin, view->angles, 0.9 ); - - for ( i = 0; i < 3; i++ ) - { - view->origin[ i ] += bob * 0.4 * pparams->forward[ i ]; - } - view->origin[2] += bob; - - // throw in a little tilt. - view->angles[YAW] -= bob * 0.5; - view->angles[ROLL] -= bob * 1; - view->angles[PITCH] -= bob * 0.3; - - // pushing the view origin down off of the same X/Z plane as the ent's origin will give the - // gun a very nice 'shifting' effect when the player looks up/down. If there is a problem - // with view model distortion, this may be a cause. (SJB). - view->origin[2] -= 1; - - // fudge position around to keep amount of weapon visible - // roughly equal with different FOV - if (pparams->viewsize == 110) - { - view->origin[2] += 1; - } - else if (pparams->viewsize == 100) - { - view->origin[2] += 2; - } - else if (pparams->viewsize == 90) - { - view->origin[2] += 1; - } - else if (pparams->viewsize == 80) - { - view->origin[2] += 0.5; - } - - // Add in the punchangle, if any - VectorAdd ( pparams->viewangles, pparams->punchangle, pparams->viewangles ); - - // Include client side punch, too - VectorAdd ( pparams->viewangles, (float *)&ev_punchangle, pparams->viewangles); - - V_DropPunchAngle ( pparams->frametime, (float *)&ev_punchangle ); - - // smooth out stair step ups -#if 1 - if ( !pparams->smoothing && pparams->onground && pparams->simorg[2] - oldz > 0) - { - float steptime; - - steptime = pparams->time - lasttime; - if (steptime < 0) - //FIXME I_Error ("steptime < 0"); - steptime = 0; - - oldz += steptime * 150; - if (oldz > pparams->simorg[2]) - oldz = pparams->simorg[2]; - if (pparams->simorg[2] - oldz > 18) - oldz = pparams->simorg[2]- 18; - pparams->vieworg[2] += oldz - pparams->simorg[2]; - view->origin[2] += oldz - pparams->simorg[2]; - } - else - { - oldz = pparams->simorg[2]; - } -#endif - - { - static float lastorg[3]; - vec3_t delta; - - VectorSubtract( pparams->simorg, lastorg, delta ); - - if ( Length( delta ) != 0.0 ) - { - VectorCopy( pparams->simorg, ViewInterp.Origins[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] ); - ViewInterp.OriginTime[ ViewInterp.CurrentOrigin & ORIGIN_MASK ] = pparams->time; - ViewInterp.CurrentOrigin++; - - VectorCopy( pparams->simorg, lastorg ); - } - } - - // Smooth out whole view in multiplayer when on trains, lifts - if ( cl_vsmoothing && cl_vsmoothing->value && - ( ( iIsSpectator & SPEC_SMOOTH_ORIGIN ) || (pparams->smoothing && ( pparams->maxclients > 1 ) ) ) ) - { - int foundidx; - int i; - float t; - - if ( cl_vsmoothing->value < 0.0 ) - { - gEngfuncs.Cvar_SetValue( "cl_vsmoothing", 0.0 ); - } - - t = pparams->time - cl_vsmoothing->value; - - for ( i = 1; i < ORIGIN_MASK; i++ ) - { - foundidx = ViewInterp.CurrentOrigin - 1 - i; - if ( ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] <= t ) - break; - } - - if ( i < ORIGIN_MASK && ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ] != 0.0 ) - { - // Interpolate - vec3_t delta; - double frac; - double dt; - vec3_t neworg; - - dt = ViewInterp.OriginTime[ (foundidx + 1) & ORIGIN_MASK ] - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK ]; - if ( dt > 0.0 ) - { - frac = ( t - ViewInterp.OriginTime[ foundidx & ORIGIN_MASK] ) / dt; - frac = V_min( 1.0, frac ); - VectorSubtract( ViewInterp.Origins[ ( foundidx + 1 ) & ORIGIN_MASK ], ViewInterp.Origins[ foundidx & ORIGIN_MASK ], delta ); - VectorMA( ViewInterp.Origins[ foundidx & ORIGIN_MASK ], frac, delta, neworg ); - - // Dont interpolate large changes - if ( Length( delta ) < 64 ) - { - VectorSubtract( neworg, pparams->simorg, delta ); - - VectorAdd( pparams->simorg, delta, pparams->simorg ); - VectorAdd( pparams->vieworg, delta, pparams->vieworg ); - VectorAdd( view->origin, delta, view->origin ); - - VectorCopy( pparams->simorg, vecNewViewOrigin ); - } - } - } - } - - // Store off v_angles before munging for third person - v_angles = pparams->viewangles; - - if ( CL_IsThirdPerson() ) - { - VectorCopy( camAngles, pparams->viewangles); - } - - // override all previous settings if the viewent isn't the client - if ( pparams->viewentity > pparams->maxclients ) - { - cl_entity_t *viewentity; - viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); - if ( viewentity ) - { - VectorCopy( viewentity->origin, pparams->vieworg ); - VectorCopy( viewentity->angles, pparams->viewangles ); - - // Store off overridden viewangles - v_angles = pparams->viewangles; - } - } - - lasttime = pparams->time; - - v_origin = pparams->vieworg; -} - -void DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams ) -{ - // intermission / finale rendering - if ( pparams->intermission ) - { - V_CalcIntermissionRefdef ( pparams ); - } - else if ( !pparams->paused ) - { - V_CalcNormalRefdef ( pparams ); - } - -/* -// Example of how to overlay the whole screen with red at 50 % alpha -#define SF_TEST -#if defined SF_TEST - { - screenfade_t sf; - gEngfuncs.pfnGetScreenFade( &sf ); - - sf.fader = 255; - sf.fadeg = 0; - sf.fadeb = 0; - sf.fadealpha = 128; - sf.fadeFlags = FFADE_STAYOUT | FFADE_OUT; - - gEngfuncs.pfnSetScreenFade( &sf ); - } -#endif -*/ -} - -/* -============= -V_DropPunchAngle - -============= -*/ -void V_DropPunchAngle ( float frametime, float *ev_punchangle ) -{ - float len; - - len = VectorNormalize ( ev_punchangle ); - len -= (10.0 + len * 0.5) * frametime; - len = V_max( len, 0.0 ); - VectorScale ( ev_punchangle, len, ev_punchangle ); -} - -/* -============= -V_PunchAxis - -Client side punch effect -============= -*/ -void V_PunchAxis( int axis, float punch ) -{ - ev_punchangle[ axis ] = punch; -} - -/* -============= -V_Init -============= -*/ -void V_Init (void) -{ - gEngfuncs.pfnAddCommand ("centerview", V_StartPitchDrift ); - - scr_ofsx = gEngfuncs.pfnRegisterVariable( "scr_ofsx","0", 0 ); - scr_ofsy = gEngfuncs.pfnRegisterVariable( "scr_ofsy","0", 0 ); - scr_ofsz = gEngfuncs.pfnRegisterVariable( "scr_ofsz","0", 0 ); - - v_centermove = gEngfuncs.pfnRegisterVariable( "v_centermove", "0.15", 0 ); - v_centerspeed = gEngfuncs.pfnRegisterVariable( "v_centerspeed","500", 0 ); - - cl_bobcycle = gEngfuncs.pfnRegisterVariable( "cl_bobcycle","0.8", 0 );// best default for my experimental gun wag (sjb) - cl_bob = gEngfuncs.pfnRegisterVariable( "cl_bob","0.01", 0 );// best default for my experimental gun wag (sjb) - cl_bobup = gEngfuncs.pfnRegisterVariable( "cl_bobup","0.5", 0 ); - cl_waterdist = gEngfuncs.pfnRegisterVariable( "cl_waterdist","4", 0 ); -} - - -//#define TRACE_TEST -#if defined( TRACE_TEST ) - -extern float in_fov; -/* -==================== -CalcFov -==================== -*/ -float CalcFov (float fov_x, float width, float height) -{ - float a; - float x; - - if (fov_x < 1 || fov_x > 179) - fov_x = 90; // error, set to 90 - - x = width/tan(fov_x/360*M_PI); - - a = atan (height/x); - - a = a*360/M_PI; - - return a; -} - -int hitent = -1; - -void V_Move( int mx, int my ) -{ - float fov; - float fx, fy; - float dx, dy; - float c_x, c_y; - float dX, dY; - vec3_t forward, up, right; - vec3_t newangles; - - vec3_t farpoint; - pmtrace_t tr; - - fov = CalcFov( in_fov, (float)ScreenWidth, (float)ScreenHeight ); - - c_x = (float)ScreenWidth / 2.0; - c_y = (float)ScreenHeight / 2.0; - - dx = (float)mx - c_x; - dy = (float)my - c_y; - - // Proportion we moved in each direction - fx = dx / c_x; - fy = dy / c_y; - - dX = fx * in_fov / 2.0 ; - dY = fy * fov / 2.0; - - newangles = v_angles; - - newangles[ YAW ] -= dX; - newangles[ PITCH ] += dY; - - // Now rotate v_forward around that point - AngleVectors ( newangles, forward, right, up ); - - farpoint = v_origin + 8192 * forward; - - // Trace - tr = *(gEngfuncs.PM_TraceLine( (float *)&v_origin, (float *)&farpoint, PM_TRACELINE_PHYSENTSONLY, 2 /*point sized hull*/, -1 )); - - if ( tr.fraction != 1.0 && tr.ent != 0 ) - { - hitent = PM_GetInfo( tr.ent ); - PM_ParticleLine( (float *)&v_origin, (float *)&tr.endpos, 5, 1.0, 0.0 ); - } - else - { - hitent = -1; - } -} - -#endif \ No newline at end of file diff --git a/ricochet/cl_dll/view.h b/ricochet/cl_dll/view.h deleted file mode 100644 index 24d444f..0000000 --- a/ricochet/cl_dll/view.h +++ /dev/null @@ -1,22 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#if !defined ( VIEWH ) -#define VIEWH -#pragma once - -void V_StartPitchDrift( void ); -void V_StopPitchDrift( void ); - -#endif // !VIEWH \ No newline at end of file diff --git a/ricochet/cl_dll/voice_status.cpp b/ricochet/cl_dll/voice_status.cpp deleted file mode 100644 index 0b09684..0000000 --- a/ricochet/cl_dll/voice_status.cpp +++ /dev/null @@ -1,885 +0,0 @@ -//========= Copyright � 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -// There are hud.h's coming out of the woodwork so this ensures that we get the right one. -#if defined(THREEWAVE) || defined(DMC_BUILD) - #include "../dmc/cl_dll/hud.h" -#elif defined(CSTRIKE) - #include "../cstrike/cl_dll/hud.h" -#elif defined(DOD) - #include "../dod/cl_dll/hud.h" -#else - #include "hud.h" -#endif - -#include "cl_util.h" -#include -#include -#include -#include "parsemsg.h" -#include "hud_servers.h" -#include "demo.h" -#include "demo_api.h" -#include "voice_status.h" -#include "r_efx.h" -#include "entity_types.h" -#include "VGUI_ActionSignal.h" -#include "VGUI_Scheme.h" -#include "VGUI_TextImage.h" -#include "vgui_loadtga.h" -#include "vgui_helpers.h" -#include "VGUI_MouseCode.h" - - - -using namespace vgui; - - -extern int cam_thirdperson; - - -#define VOICE_MODEL_INTERVAL 0.3 -#define SCOREBOARD_BLINK_FREQUENCY 0.3 // How often to blink the scoreboard icons. -#define SQUELCHOSCILLATE_PER_SECOND 2.0f - - -extern BitmapTGA *LoadTGA( const char* pImageName ); - - - -// ---------------------------------------------------------------------- // -// The voice manager for the client. -// ---------------------------------------------------------------------- // -CVoiceStatus g_VoiceStatus; - -CVoiceStatus* GetClientVoiceMgr() -{ - return &g_VoiceStatus; -} - - - -// ---------------------------------------------------------------------- // -// CVoiceStatus. -// ---------------------------------------------------------------------- // - -static CVoiceStatus *g_pInternalVoiceStatus = NULL; - -int __MsgFunc_VoiceMask(const char *pszName, int iSize, void *pbuf) -{ - if(g_pInternalVoiceStatus) - g_pInternalVoiceStatus->HandleVoiceMaskMsg(iSize, pbuf); - - return 1; -} - -int __MsgFunc_ReqState(const char *pszName, int iSize, void *pbuf) -{ - if(g_pInternalVoiceStatus) - g_pInternalVoiceStatus->HandleReqStateMsg(iSize, pbuf); - - return 1; -} - - -int g_BannedPlayerPrintCount; -void ForEachBannedPlayer(char id[16]) -{ - char str[256]; - sprintf(str, "Ban %d: %2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x\n", - g_BannedPlayerPrintCount++, - id[0], id[1], id[2], id[3], - id[4], id[5], id[6], id[7], - id[8], id[9], id[10], id[11], - id[12], id[13], id[14], id[15] - ); -#ifdef _WIN32 - strupr(str); -#endif - gEngfuncs.pfnConsolePrint(str); -} - - -void ShowBannedCallback() -{ - if(g_pInternalVoiceStatus) - { - g_BannedPlayerPrintCount = 0; - gEngfuncs.pfnConsolePrint("------- BANNED PLAYERS -------\n"); - g_pInternalVoiceStatus->m_BanMgr.ForEachBannedPlayer(ForEachBannedPlayer); - gEngfuncs.pfnConsolePrint("------------------------------\n"); - } -} - - -// ---------------------------------------------------------------------- // -// CVoiceStatus. -// ---------------------------------------------------------------------- // - -CVoiceStatus::CVoiceStatus() -{ - m_bBanMgrInitialized = false; - m_LastUpdateServerState = 0; - - m_pSpeakerLabelIcon = NULL; - m_pScoreboardNeverSpoken = NULL; - m_pScoreboardNotSpeaking = NULL; - m_pScoreboardSpeaking = NULL; - m_pScoreboardSpeaking2 = NULL; - m_pScoreboardSquelch = NULL; - m_pScoreboardBanned = NULL; - - m_pLocalBitmap = NULL; - m_pAckBitmap = NULL; - - m_bTalking = m_bServerAcked = false; - - memset(m_pBanButtons, 0, sizeof(m_pBanButtons)); - - m_pParentPanel = NULL; - - m_bServerModEnable = -1; - - m_pchGameDir = NULL; -} - - -CVoiceStatus::~CVoiceStatus() -{ - g_pInternalVoiceStatus = NULL; - - for(int i=0; i < MAX_VOICE_SPEAKERS; i++) - { - delete m_Labels[i].m_pLabel; - m_Labels[i].m_pLabel = NULL; - - delete m_Labels[i].m_pIcon; - m_Labels[i].m_pIcon = NULL; - - delete m_Labels[i].m_pBackground; - m_Labels[i].m_pBackground = NULL; - } - - delete m_pLocalLabel; - m_pLocalLabel = NULL; - - FreeBitmaps(); - - if(m_pchGameDir) - { - if(m_bBanMgrInitialized) - { - m_BanMgr.SaveState(m_pchGameDir); - } - - free(m_pchGameDir); - } -} - - -int CVoiceStatus::Init( - IVoiceStatusHelper *pHelper, - Panel **pParentPanel) -{ - // Setup the voice_modenable cvar. - gEngfuncs.pfnRegisterVariable("voice_modenable", "1", FCVAR_ARCHIVE); - - gEngfuncs.pfnRegisterVariable("voice_clientdebug", "0", 0); - - gEngfuncs.pfnAddCommand("voice_showbanned", ShowBannedCallback); - - if(gEngfuncs.pfnGetGameDirectory()) - { - m_BanMgr.Init(gEngfuncs.pfnGetGameDirectory()); - m_bBanMgrInitialized = true; - } - - assert(!g_pInternalVoiceStatus); - g_pInternalVoiceStatus = this; - - m_BlinkTimer = 0; - m_VoiceHeadModel = NULL; - memset(m_Labels, 0, sizeof(m_Labels)); - - for(int i=0; i < MAX_VOICE_SPEAKERS; i++) - { - CVoiceLabel *pLabel = &m_Labels[i]; - - pLabel->m_pBackground = new Label(""); - - if(pLabel->m_pLabel = new Label("")) - { - pLabel->m_pLabel->setVisible( true ); - pLabel->m_pLabel->setFont( Scheme::sf_primary2 ); - pLabel->m_pLabel->setTextAlignment( Label::a_east ); - pLabel->m_pLabel->setContentAlignment( Label::a_east ); - pLabel->m_pLabel->setParent( pLabel->m_pBackground ); - } - - if( pLabel->m_pIcon = new ImagePanel( NULL ) ) - { - pLabel->m_pIcon->setVisible( true ); - pLabel->m_pIcon->setParent( pLabel->m_pBackground ); - } - - pLabel->m_clientindex = -1; - } - - m_pLocalLabel = new ImagePanel(NULL); - - m_bInSquelchMode = false; - - m_pHelper = pHelper; - m_pParentPanel = pParentPanel; - gHUD.AddHudElem(this); - m_iFlags = HUD_ACTIVE; - HOOK_MESSAGE(VoiceMask); - HOOK_MESSAGE(ReqState); - - // Cache the game directory for use when we shut down - const char *pchGameDirT = gEngfuncs.pfnGetGameDirectory(); - m_pchGameDir = (char *)malloc(strlen(pchGameDirT) + 1); - strcpy(m_pchGameDir, pchGameDirT); - - return 1; -} - - -int CVoiceStatus::VidInit() -{ - FreeBitmaps(); - - - if( m_pLocalBitmap = vgui_LoadTGA("gfx/vgui/icntlk_pl.tga") ) - { - m_pLocalBitmap->setColor(Color(255,255,255,135)); - } - - if( m_pAckBitmap = vgui_LoadTGA("gfx/vgui/icntlk_sv.tga") ) - { - m_pAckBitmap->setColor(Color(255,255,255,135)); // Give just a tiny bit of translucency so software draws correctly. - } - - m_pLocalLabel->setImage( m_pLocalBitmap ); - m_pLocalLabel->setVisible( false ); - - - if( m_pSpeakerLabelIcon = vgui_LoadTGANoInvertAlpha("gfx/vgui/speaker4.tga" ) ) - m_pSpeakerLabelIcon->setColor( Color(255,255,255,1) ); // Give just a tiny bit of translucency so software draws correctly. - - if (m_pScoreboardNeverSpoken = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker1.tga")) - m_pScoreboardNeverSpoken->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardNotSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker2.tga")) - m_pScoreboardNotSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardSpeaking = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker3.tga")) - m_pScoreboardSpeaking->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardSpeaking2 = vgui_LoadTGANoInvertAlpha("gfx/vgui/640_speaker4.tga")) - m_pScoreboardSpeaking2->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardSquelch = vgui_LoadTGA("gfx/vgui/icntlk_squelch.tga")) - m_pScoreboardSquelch->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - if(m_pScoreboardBanned = vgui_LoadTGA("gfx/vgui/640_voiceblocked.tga")) - m_pScoreboardBanned->setColor(Color(255,255,255,1)); // Give just a tiny bit of translucency so software draws correctly. - - // Figure out the voice head model height. - m_VoiceHeadModelHeight = 45; - char *pFile = (char *)gEngfuncs.COM_LoadFile("scripts/voicemodel.txt", 5, NULL); - if(pFile) - { - char token[4096]; - gEngfuncs.COM_ParseFile(pFile, token); - if(token[0] >= '0' && token[0] <= '9') - { - m_VoiceHeadModelHeight = (float)atof(token); - } - - gEngfuncs.COM_FreeFile(pFile); - } - - m_VoiceHeadModel = gEngfuncs.pfnSPR_Load("sprites/voiceicon.spr"); - return TRUE; -} - - -void CVoiceStatus::Frame(double frametime) -{ - // check server banned players once per second - if(gEngfuncs.GetClientTime() - m_LastUpdateServerState > 1) - { - UpdateServerState(false); - } - - m_BlinkTimer += frametime; - - // Update speaker labels. - if( m_pHelper->CanShowSpeakerLabels() ) - { - for( int i=0; i < MAX_VOICE_SPEAKERS; i++ ) - m_Labels[i].m_pBackground->setVisible( m_Labels[i].m_clientindex != -1 ); - } - else - { - for( int i=0; i < MAX_VOICE_SPEAKERS; i++ ) - m_Labels[i].m_pBackground->setVisible( false ); - } - - for(int i=0; i < VOICE_MAX_PLAYERS; i++) - UpdateBanButton(i); -} - - -void CVoiceStatus::CreateEntities() -{ - if(!m_VoiceHeadModel) - return; - - cl_entity_t *localPlayer = gEngfuncs.GetLocalPlayer(); - - int iOutModel = 0; - for(int i=0; i < VOICE_MAX_PLAYERS; i++) - { - if(!m_VoicePlayers[i]) - continue; - - cl_entity_s *pClient = gEngfuncs.GetEntityByIndex(i+1); - - // Don't show an icon if the player is not in our PVS. - if(!pClient || pClient->curstate.messagenum < localPlayer->curstate.messagenum) - continue; - - // Don't show an icon for dead or spectating players (ie: invisible entities). - if(pClient->curstate.effects & EF_NODRAW) - continue; - - // Don't show an icon for the local player unless we're in thirdperson mode. - if(pClient == localPlayer && !cam_thirdperson) - continue; - - cl_entity_s *pEnt = &m_VoiceHeadModels[iOutModel]; - ++iOutModel; - - memset(pEnt, 0, sizeof(*pEnt)); - - pEnt->curstate.rendermode = kRenderTransAdd; - pEnt->curstate.renderamt = 255; - pEnt->baseline.renderamt = 255; - pEnt->curstate.renderfx = kRenderFxNoDissipation; - pEnt->curstate.framerate = 1; - pEnt->curstate.frame = 0; - pEnt->model = (struct model_s*)gEngfuncs.GetSpritePointer(m_VoiceHeadModel); - pEnt->angles[0] = pEnt->angles[1] = pEnt->angles[2] = 0; - pEnt->curstate.scale = 0.5f; - - pEnt->origin[0] = pEnt->origin[1] = 0; - pEnt->origin[2] = 45; - - VectorAdd(pEnt->origin, pClient->origin, pEnt->origin); - - // Tell the engine. - gEngfuncs.CL_CreateVisibleEntity(ET_NORMAL, pEnt); - } -} - - -void CVoiceStatus::UpdateSpeakerStatus( int entindex, qboolean bTalking ) -{ - cvar_t *pVoiceLoopback = NULL; - - if ( !m_pParentPanel || !*m_pParentPanel ) - { - return; - } - - if ( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) ) - { - char msg[256]; - _snprintf( msg, sizeof( msg ), "CVoiceStatus::UpdateSpeakerStatus: ent %d talking = %d\n", entindex, bTalking ); - gEngfuncs.pfnConsolePrint( msg ); - } - - int iLocalPlayerIndex = gEngfuncs.GetLocalPlayer()->index; - - // Is it the local player talking? - if ( entindex == -1 ) - { - m_bTalking = !!bTalking; - if( bTalking ) - { - // Enable voice for them automatically if they try to talk. - gEngfuncs.pfnClientCmd( "voice_modenable 1" ); - } - - // now set the player index to the correct index for the local player - // this will allow us to have the local player's icon flash in the scoreboard - entindex = iLocalPlayerIndex; - - pVoiceLoopback = gEngfuncs.pfnGetCvarPointer( "voice_loopback" ); - } - else if ( entindex == -2 ) - { - m_bServerAcked = !!bTalking; - } - - if ( entindex >= 0 && entindex <= VOICE_MAX_PLAYERS ) - { - int iClient = entindex - 1; - if ( iClient < 0 ) - { - return; - } - - CVoiceLabel *pLabel = FindVoiceLabel( iClient ); - if ( bTalking ) - { - m_VoicePlayers[iClient] = true; - m_VoiceEnabledPlayers[iClient] = true; - - // If we don't have a label for this guy yet, then create one. - if ( !pLabel ) - { - // if this isn't the local player (unless they have voice_loopback on) - if ( ( entindex != iLocalPlayerIndex ) || ( pVoiceLoopback && pVoiceLoopback->value ) ) - { - if ( pLabel = GetFreeVoiceLabel() ) - { - // Get the name from the engine. - hud_player_info_t info; - memset( &info, 0, sizeof( info ) ); - GetPlayerInfo( entindex, &info ); - - char paddedName[512]; - _snprintf( paddedName, sizeof( paddedName ), "%s ", info.name ); - - int color[3]; - m_pHelper->GetPlayerTextColor( entindex, color ); - - if ( pLabel->m_pBackground ) - { - pLabel->m_pBackground->setBgColor( color[0], color[1], color[2], 135 ); - pLabel->m_pBackground->setParent( *m_pParentPanel ); - pLabel->m_pBackground->setVisible( m_pHelper->CanShowSpeakerLabels() ); - } - - if ( pLabel->m_pLabel ) - { - pLabel->m_pLabel->setFgColor( 255, 255, 255, 0 ); - pLabel->m_pLabel->setBgColor( 0, 0, 0, 255 ); - pLabel->m_pLabel->setText( paddedName ); - } - - pLabel->m_clientindex = iClient; - } - } - } - } - else - { - m_VoicePlayers[iClient] = false; - - // If we have a label for this guy, kill it. - if ( pLabel ) - { - pLabel->m_pBackground->setVisible( false ); - pLabel->m_clientindex = -1; - } - } - } - - RepositionLabels(); -} - - -void CVoiceStatus::UpdateServerState(bool bForce) -{ - // Can't do anything when we're not in a level. - char const *pLevelName = gEngfuncs.pfnGetLevelName(); - if( pLevelName[0] == 0 ) - { - if( gEngfuncs.pfnGetCvarFloat("voice_clientdebug") ) - { - gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: pLevelName[0]==0\n" ); - } - - return; - } - - int bCVarModEnable = !!gEngfuncs.pfnGetCvarFloat("voice_modenable"); - if(bForce || m_bServerModEnable != bCVarModEnable) - { - m_bServerModEnable = bCVarModEnable; - - char str[256]; - _snprintf(str, sizeof(str), "VModEnable %d", m_bServerModEnable); - ServerCmd(str); - - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - char msg[256]; - sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str); - gEngfuncs.pfnConsolePrint(msg); - } - } - - char str[2048]; - sprintf(str, "vban"); - bool bChange = false; - - for(unsigned long dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++) - { - unsigned long serverBanMask = 0; - unsigned long banMask = 0; - for(unsigned long i=0; i < 32; i++) - { - char playerID[16]; - if(!gEngfuncs.GetPlayerUniqueID(i+1, playerID)) - continue; - - if(m_BanMgr.GetPlayerBan(playerID)) - banMask |= 1 << i; - - if(m_ServerBannedPlayers[dw*32 + i]) - serverBanMask |= 1 << i; - } - - if(serverBanMask != banMask) - bChange = true; - - // Ok, the server needs to be updated. - char numStr[512]; - sprintf(numStr, " %x", banMask); - strcat(str, numStr); - } - - if(bChange || bForce) - { - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - char msg[256]; - sprintf(msg, "CVoiceStatus::UpdateServerState: Sending '%s'\n", str); - gEngfuncs.pfnConsolePrint(msg); - } - - gEngfuncs.pfnServerCmdUnreliable(str); // Tell the server.. - } - else - { - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: no change\n" ); - } - } - - m_LastUpdateServerState = gEngfuncs.GetClientTime(); -} - -void CVoiceStatus::UpdateSpeakerImage(Label *pLabel, int iPlayer) -{ - m_pBanButtons[iPlayer-1] = pLabel; - UpdateBanButton(iPlayer-1); -} - -void CVoiceStatus::UpdateBanButton(int iClient) -{ - Label *pPanel = m_pBanButtons[iClient]; - - if (!pPanel) - return; - - char playerID[16]; - extern bool HACK_GetPlayerUniqueID( int iPlayer, char playerID[16] ); - if(!HACK_GetPlayerUniqueID(iClient+1, playerID)) - return; - - // Figure out if it's blinking or not. - bool bBlink = fmod(m_BlinkTimer, SCOREBOARD_BLINK_FREQUENCY*2) < SCOREBOARD_BLINK_FREQUENCY; - bool bTalking = !!m_VoicePlayers[iClient]; - bool bBanned = m_BanMgr.GetPlayerBan(playerID); - bool bNeverSpoken = !m_VoiceEnabledPlayers[iClient]; - - // Get the appropriate image to display on the panel. - if (bBanned) - { - pPanel->setImage(m_pScoreboardBanned); - } - else if (bTalking) - { - if (bBlink) - { - pPanel->setImage(m_pScoreboardSpeaking2); - } - else - { - pPanel->setImage(m_pScoreboardSpeaking); - } - pPanel->setFgColor(255, 170, 0, 1); - } - else if (bNeverSpoken) - { - pPanel->setImage(m_pScoreboardNeverSpoken); - pPanel->setFgColor(100, 100, 100, 1); - } - else - { - pPanel->setImage(m_pScoreboardNotSpeaking); - } -} - - -void CVoiceStatus::HandleVoiceMaskMsg(int iSize, void *pbuf) -{ - BEGIN_READ( pbuf, iSize ); - - unsigned long dw; - for(dw=0; dw < VOICE_MAX_PLAYERS_DW; dw++) - { - m_AudiblePlayers.SetDWord(dw, (unsigned long)READ_LONG()); - m_ServerBannedPlayers.SetDWord(dw, (unsigned long)READ_LONG()); - - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - char str[256]; - gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleVoiceMaskMsg\n"); - - sprintf(str, " - m_AudiblePlayers[%d] = %lu\n", dw, m_AudiblePlayers.GetDWord(dw)); - gEngfuncs.pfnConsolePrint(str); - - sprintf(str, " - m_ServerBannedPlayers[%d] = %lu\n", dw, m_ServerBannedPlayers.GetDWord(dw)); - gEngfuncs.pfnConsolePrint(str); - } - } - - m_bServerModEnable = READ_BYTE(); -} - -void CVoiceStatus::HandleReqStateMsg(int iSize, void *pbuf) -{ - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleReqStateMsg\n"); - } - - UpdateServerState(true); -} - -void CVoiceStatus::StartSquelchMode() -{ - if(m_bInSquelchMode) - return; - - m_bInSquelchMode = true; - m_pHelper->UpdateCursorState(); -} - -void CVoiceStatus::StopSquelchMode() -{ - m_bInSquelchMode = false; - m_pHelper->UpdateCursorState(); -} - -bool CVoiceStatus::IsInSquelchMode() -{ - return m_bInSquelchMode; -} - -CVoiceLabel* CVoiceStatus::FindVoiceLabel(int clientindex) -{ - for(int i=0; i < MAX_VOICE_SPEAKERS; i++) - { - if(m_Labels[i].m_clientindex == clientindex) - return &m_Labels[i]; - } - - return NULL; -} - - -CVoiceLabel* CVoiceStatus::GetFreeVoiceLabel() -{ - return FindVoiceLabel(-1); -} - - -void CVoiceStatus::RepositionLabels() -{ - // find starting position to draw from, along right-hand side of screen - int y = ScreenHeight / 2; - - int iconWide = 8, iconTall = 8; - if( m_pSpeakerLabelIcon ) - { - m_pSpeakerLabelIcon->getSize( iconWide, iconTall ); - } - - // Reposition active labels. - for(int i = 0; i < MAX_VOICE_SPEAKERS; i++) - { - CVoiceLabel *pLabel = &m_Labels[i]; - - if( pLabel->m_clientindex == -1 || !pLabel->m_pLabel ) - { - if( pLabel->m_pBackground ) - pLabel->m_pBackground->setVisible( false ); - - continue; - } - - int textWide, textTall; - pLabel->m_pLabel->getContentSize( textWide, textTall ); - - // Don't let it stretch too far across their screen. - if( textWide > (ScreenWidth*2)/3 ) - textWide = (ScreenWidth*2)/3; - - // Setup the background label to fit everything in. - int border = 2; - int bgWide = textWide + iconWide + border*3; - int bgTall = V_max( textTall, iconTall ) + border*2; - pLabel->m_pBackground->setBounds( ScreenWidth - bgWide - 8, y, bgWide, bgTall ); - - // Put the text at the left. - pLabel->m_pLabel->setBounds( border, (bgTall - textTall) / 2, textWide, textTall ); - - // Put the icon at the right. - int iconLeft = border + textWide + border; - int iconTop = (bgTall - iconTall) / 2; - if( pLabel->m_pIcon ) - { - pLabel->m_pIcon->setImage( m_pSpeakerLabelIcon ); - pLabel->m_pIcon->setBounds( iconLeft, iconTop, iconWide, iconTall ); - } - - y += bgTall + 2; - } - - if( m_pLocalBitmap && m_pAckBitmap && m_pLocalLabel && (m_bTalking || m_bServerAcked) ) - { - m_pLocalLabel->setParent(*m_pParentPanel); - m_pLocalLabel->setVisible( true ); - - if( m_bServerAcked && !!gEngfuncs.pfnGetCvarFloat("voice_clientdebug") ) - m_pLocalLabel->setImage( m_pAckBitmap ); - else - m_pLocalLabel->setImage( m_pLocalBitmap ); - - int sizeX, sizeY; - m_pLocalBitmap->getSize(sizeX, sizeY); - - int local_xPos = ScreenWidth - sizeX - 10; - int local_yPos = m_pHelper->GetAckIconHeight() - sizeY; - - m_pLocalLabel->setPos( local_xPos, local_yPos ); - } - else - { - m_pLocalLabel->setVisible( false ); - } -} - - -void CVoiceStatus::FreeBitmaps() -{ - // Delete all the images we have loaded. - delete m_pLocalBitmap; - m_pLocalBitmap = NULL; - - delete m_pAckBitmap; - m_pAckBitmap = NULL; - - delete m_pSpeakerLabelIcon; - m_pSpeakerLabelIcon = NULL; - - delete m_pScoreboardNeverSpoken; - m_pScoreboardNeverSpoken = NULL; - - delete m_pScoreboardNotSpeaking; - m_pScoreboardNotSpeaking = NULL; - - delete m_pScoreboardSpeaking; - m_pScoreboardSpeaking = NULL; - - delete m_pScoreboardSpeaking2; - m_pScoreboardSpeaking2 = NULL; - - delete m_pScoreboardSquelch; - m_pScoreboardSquelch = NULL; - - delete m_pScoreboardBanned; - m_pScoreboardBanned = NULL; - - // Clear references to the images in panels. - for(int i=0; i < VOICE_MAX_PLAYERS; i++) - { - if (m_pBanButtons[i]) - { - m_pBanButtons[i]->setImage(NULL); - } - } - - if(m_pLocalLabel) - m_pLocalLabel->setImage(NULL); -} - -//----------------------------------------------------------------------------- -// Purpose: returns true if the target client has been banned -// Input : playerID - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool CVoiceStatus::IsPlayerBlocked(int iPlayer) -{ - char playerID[16]; - if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID)) - return false; - - return m_BanMgr.GetPlayerBan(playerID); -} - -//----------------------------------------------------------------------------- -// Purpose: returns true if the player can't hear the other client due to game rules (eg. the other team) -// Input : playerID - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -bool CVoiceStatus::IsPlayerAudible(int iPlayer) -{ - return !!m_AudiblePlayers[iPlayer-1]; -} - -//----------------------------------------------------------------------------- -// Purpose: blocks/unblocks the target client from being heard -// Input : playerID - -// Output : Returns true on success, false on failure. -//----------------------------------------------------------------------------- -void CVoiceStatus::SetPlayerBlockedState(int iPlayer, bool blocked) -{ - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 1\n" ); - } - - char playerID[16]; - if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID)) - return; - - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 2\n" ); - } - - // Squelch or (try to) unsquelch this player. - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) - { - char str[256]; - sprintf(str, "CVoiceStatus::SetPlayerBlockedState: setting player %d ban to %d\n", iPlayer, !m_BanMgr.GetPlayerBan(playerID)); - gEngfuncs.pfnConsolePrint(str); - } - - m_BanMgr.SetPlayerBan( playerID, blocked ); - UpdateServerState(false); -} diff --git a/ricochet/cl_dll/voice_status.h b/ricochet/cl_dll/voice_status.h deleted file mode 100644 index 8edf58c..0000000 --- a/ricochet/cl_dll/voice_status.h +++ /dev/null @@ -1,228 +0,0 @@ -//========= Copyright © 1996-2001, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#ifndef VOICE_STATUS_H -#define VOICE_STATUS_H -#pragma once - - -#include "VGUI_Label.h" -#include "VGUI_LineBorder.h" -#include "VGUI_ImagePanel.h" -#include "VGUI_BitmapTGA.h" -#include "VGUI_InputSignal.h" -#include "VGUI_Button.h" -#include "voice_common.h" -#include "cl_entity.h" -#include "voice_banmgr.h" -#include "vgui_checkbutton2.h" -#include "vgui_defaultinputsignal.h" - - -class CVoiceStatus; - - -class CVoiceLabel -{ -public: - vgui::Label *m_pLabel; - vgui::Label *m_pBackground; - vgui::ImagePanel *m_pIcon; // Voice icon next to player name. - int m_clientindex; // Client index of the speaker. -1 if this label isn't being used. -}; - - -// This is provided by each mod to access data that may not be the same across mods. -class IVoiceStatusHelper -{ -public: - virtual ~IVoiceStatusHelper() {} - - // Get RGB color for voice status text about this player. - virtual void GetPlayerTextColor(int entindex, int color[3]) = 0; - - // Force it to update the cursor state. - virtual void UpdateCursorState() = 0; - - // Return the height above the bottom that the voice ack icons should be drawn at. - virtual int GetAckIconHeight() = 0; - - // Return true if the voice manager is allowed to show speaker labels - // (mods usually return false when the scoreboard is up). - virtual bool CanShowSpeakerLabels() = 0; -}; - -//----------------------------------------------------------------------------- -// Purpose: Holds a color for the shared image -//----------------------------------------------------------------------------- -class VoiceImagePanel : public vgui::ImagePanel -{ - virtual void paintBackground() - { - if (_image!=null) - { - vgui::Color col; - getFgColor(col); - _image->setColor(col); - _image->doPaint(this); - } - } -}; - - -class CVoiceStatus : public CHudBase, public vgui::CDefaultInputSignal -{ -public: - CVoiceStatus(); - virtual ~CVoiceStatus(); - -// CHudBase overrides. -public: - - // Initialize the cl_dll's voice manager. - virtual int Init( - IVoiceStatusHelper *m_pHelper, - vgui::Panel **pParentPanel); - - // ackPosition is the bottom position of where CVoiceStatus will draw the voice acknowledgement labels. - virtual int VidInit(); - - -public: - - // Call from HUD_Frame each frame. - void Frame(double frametime); - - // Called when a player starts or stops talking. - // entindex is -1 to represent the local client talking (before the data comes back from the server). - // When the server acknowledges that the local client is talking, then entindex will be gEngfuncs.GetLocalPlayer(). - // entindex is -2 to represent the local client's voice being acked by the server. - void UpdateSpeakerStatus(int entindex, qboolean bTalking); - - // sets the correct image in the label for the player - void UpdateSpeakerImage(vgui::Label *pLabel, int iPlayer); - - // Call from the HUD_CreateEntities function so it can add sprites above player heads. - void CreateEntities(); - - // Called when the server registers a change to who this client can hear. - void HandleVoiceMaskMsg(int iSize, void *pbuf); - - // The server sends this message initially to tell the client to send their state. - void HandleReqStateMsg(int iSize, void *pbuf); - - -// Squelch mode functions. -public: - - // When you enter squelch mode, pass in - void StartSquelchMode(); - void StopSquelchMode(); - bool IsInSquelchMode(); - - // returns true if the target client has been banned - // playerIndex is of range 1..maxplayers - bool IsPlayerBlocked(int iPlayerIndex); - - // returns false if the player can't hear the other client due to game rules (eg. the other team) - bool IsPlayerAudible(int iPlayerIndex); - - // blocks the target client from being heard - void SetPlayerBlockedState(int iPlayerIndex, bool blocked); - -public: - - CVoiceLabel* FindVoiceLabel(int clientindex); // Find a CVoiceLabel representing the specified speaker. - // Returns NULL if none. - // entindex can be -1 if you want a currently-unused voice label. - CVoiceLabel* GetFreeVoiceLabel(); // Get an unused voice label. Returns NULL if none. - - void RepositionLabels(); - - void FreeBitmaps(); - - void UpdateServerState(bool bForce); - - // Update the button artwork to reflect the client's current state. - void UpdateBanButton(int iClient); - - -public: - - enum {MAX_VOICE_SPEAKERS=7}; - - float m_LastUpdateServerState; // Last time we called this function. - int m_bServerModEnable; // What we've sent to the server about our "voice_modenable" cvar. - - vgui::Panel **m_pParentPanel; - CPlayerBitVec m_VoicePlayers; // Who is currently talking. Indexed by client index. - - // This is the gamerules-defined list of players that you can hear. It is based on what teams people are on - // and is totally separate from the ban list. Indexed by client index. - CPlayerBitVec m_AudiblePlayers; - - // Players who have spoken at least once in the game so far - CPlayerBitVec m_VoiceEnabledPlayers; - - // This is who the server THINKS we have banned (it can become incorrect when a new player arrives on the server). - // It is checked periodically, and the server is told to squelch or unsquelch the appropriate players. - CPlayerBitVec m_ServerBannedPlayers; - - cl_entity_s m_VoiceHeadModels[VOICE_MAX_PLAYERS]; // These aren't necessarily in the order of players. They are just - // a place for it to put data in during CreateEntities. - - IVoiceStatusHelper *m_pHelper; // Each mod provides an implementation of this. - - - // Scoreboard icons. - double m_BlinkTimer; // Blink scoreboard icons.. - vgui::BitmapTGA *m_pScoreboardNeverSpoken; - vgui::BitmapTGA *m_pScoreboardNotSpeaking; - vgui::BitmapTGA *m_pScoreboardSpeaking; - vgui::BitmapTGA *m_pScoreboardSpeaking2; - vgui::BitmapTGA *m_pScoreboardSquelch; - vgui::BitmapTGA *m_pScoreboardBanned; - - vgui::Label *m_pBanButtons[VOICE_MAX_PLAYERS]; // scoreboard buttons. - - // Squelch mode stuff. - bool m_bInSquelchMode; - - HSPRITE m_VoiceHeadModel; // Voice head model (goes above players who are speaking). - float m_VoiceHeadModelHeight; // Height above their head to place the model. - - vgui::Image *m_pSpeakerLabelIcon; // Icon next to speaker labels. - - // Lower-right icons telling when the local player is talking.. - vgui::BitmapTGA *m_pLocalBitmap; // Represents the local client talking. - vgui::BitmapTGA *m_pAckBitmap; // Represents the server ack'ing the client talking. - vgui::ImagePanel *m_pLocalLabel; // Represents the local client talking. - - bool m_bTalking; // Set to true when the client thinks it's talking. - bool m_bServerAcked; // Set to true when the server knows the client is talking. - -public: - - CVoiceBanMgr m_BanMgr; // Tracks which users we have squelched and don't want to hear. - -public: - - bool m_bBanMgrInitialized; - - // Labels telling who is speaking. - CVoiceLabel m_Labels[MAX_VOICE_SPEAKERS]; - - // Cache the game directory for use when we shut down - char * m_pchGameDir; -}; - - -// Get the (global) voice manager. -CVoiceStatus* GetClientVoiceMgr(); - - -#endif // VOICE_STATUS_H diff --git a/ricochet/cl_dll/wrect.h b/ricochet/cl_dll/wrect.h deleted file mode 100644 index f2c4f12..0000000 --- a/ricochet/cl_dll/wrect.h +++ /dev/null @@ -1,23 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#if !defined( WRECTH ) -#define WRECTH - -typedef struct rect_s -{ - int left, right, top, bottom; -} wrect_t; - -#endif \ No newline at end of file diff --git a/ricochet/dlls/Makefile b/ricochet/dlls/Makefile deleted file mode 100644 index b16c1b5..0000000 --- a/ricochet/dlls/Makefile +++ /dev/null @@ -1,136 +0,0 @@ -# -# Half-Life Ricochet SDK 2.3 ricochet_i386.so Makefile for x86 Linux -# -# October 2002 by Leon Hartwig (hartwig@valvesoftware.com) -# - -DLLNAME=ricochet - -ARCH=i386 - -#make sure this is the correct compiler for your system -CC=gcc - -DLL_SRCDIR=. -ENGINE_SRCDIR=../../engine -COMMON_SRCDIR=../../common -PM_SHARED_SRCDIR=../pm_shared -GAME_SHARED_SRCDIR=../../game_shared -WPN_SRC_DIR=$(DLL_SRCDIR)/wpn_shared - -DLL_OBJDIR=$(DLL_SRCDIR)/obj -PM_SHARED_OBJDIR=$(DLL_OBJDIR)/pm_shared -GAME_SHARED_OBJDIR=$(DLL_OBJDIR)/game_shared -WPN_OBJ_DIR=$(DLL_OBJDIR)/wpn_shared - -BASE_CFLAGS=-Dstricmp=strcasecmp -D_strnicmp=strncasecmp -Dstrnicmp=strncasecmp -D_vsnprintf=vsnprintf - -#safe optimization -CFLAGS=$(BASE_CFLAGS) -w -m486 -O1 - -#full optimization -#CFLAGS=$(BASE_CFLAGS) -w -O2 -m486 -ffast-math -funroll-loops \ - -fomit-frame-pointer -fexpensive-optimizations \ - -malign-loops=2 -malign-jumps=2 -malign-functions=2 - -#use these when debugging -#CFLAGS=$(BASE_CFLAGS) -g - -INCLUDEDIRS=-I. -I$(ENGINE_SRCDIR) -I$(COMMON_SRCDIR) -I$(PM_SHARED_SRCDIR) -I$(GAME_SHARED_SRCDIR) - -LDFLAGS= - -SHLIBEXT=so -SHLIBCFLAGS=-fPIC -SHLIBLDFLAGS=-shared - -DO_CC=$(CC) $(CFLAGS) $(SHLIBCFLAGS) $(INCLUDEDIRS) -o $@ -c $< - -############################################################################# -# SETUP AND BUILD -# GAME -############################################################################# - -$(DLL_OBJDIR)/%.o: $(DLL_SRCDIR)/%.cpp - $(DO_CC) - -$(GAME_SHARED_OBJDIR)/%.o: $(GAME_SHARED_SRCDIR)/%.cpp - $(DO_CC) - -$(PM_SHARED_OBJDIR)/%.o: $(PM_SHARED_SRCDIR)/%.c - $(DO_CC) - -$(WPN_OBJ_DIR)/%.o : $(WPN_SRC_DIR)/%.cpp - $(DO_CC) - -OBJ = \ - $(DLL_OBJDIR)/airtank.o \ - $(DLL_OBJDIR)/animating.o \ - $(DLL_OBJDIR)/animation.o \ - $(DLL_OBJDIR)/bmodels.o \ - $(DLL_OBJDIR)/buttons.o \ - $(DLL_OBJDIR)/cbase.o \ - $(DLL_OBJDIR)/client.o \ - $(DLL_OBJDIR)/combat.o \ - $(DLL_OBJDIR)/disc_arena.o \ - $(DLL_OBJDIR)/disc_powerups.o \ - $(DLL_OBJDIR)/doors.o \ - $(DLL_OBJDIR)/effects.o \ - $(DLL_OBJDIR)/explode.o \ - $(DLL_OBJDIR)/func_break.o \ - $(DLL_OBJDIR)/func_tank.o \ - $(DLL_OBJDIR)/game.o \ - $(DLL_OBJDIR)/gamerules.o \ - $(DLL_OBJDIR)/ggrenade.o \ - $(DLL_OBJDIR)/globals.o \ - $(DLL_OBJDIR)/h_ai.o \ - $(DLL_OBJDIR)/h_battery.o \ - $(DLL_OBJDIR)/h_cycler.o \ - $(DLL_OBJDIR)/h_export.o \ - $(DLL_OBJDIR)/healthkit.o \ - $(DLL_OBJDIR)/items.o \ - $(DLL_OBJDIR)/lights.o \ - $(DLL_OBJDIR)/maprules.o \ - $(DLL_OBJDIR)/mortar.o \ - $(DLL_OBJDIR)/mpstubb.o \ - $(DLL_OBJDIR)/multiplay_gamerules.o \ - $(DLL_OBJDIR)/observer.o \ - $(DLL_OBJDIR)/pathcorner.o \ - $(DLL_OBJDIR)/plane.o \ - $(DLL_OBJDIR)/plats.o \ - $(DLL_OBJDIR)/player.o \ - $(DLL_OBJDIR)/singleplay_gamerules.o \ - $(DLL_OBJDIR)/skill.o \ - $(DLL_OBJDIR)/sound.o \ - $(DLL_OBJDIR)/soundent.o \ - $(DLL_OBJDIR)/spectator.o \ - $(DLL_OBJDIR)/subs.o \ - $(DLL_OBJDIR)/teamplay_gamerules.o \ - $(DLL_OBJDIR)/triggers.o \ - $(DLL_OBJDIR)/util.o \ - $(DLL_OBJDIR)/weapons.o \ - $(DLL_OBJDIR)/world.o \ - $(DLL_OBJDIR)/xen.o \ - $(WPN_OBJ_DIR)/disc_weapon_disc.o \ - $(PM_SHARED_OBJDIR)/pm_shared.o \ - $(PM_SHARED_OBJDIR)/pm_math.o \ - $(PM_SHARED_OBJDIR)/pm_debug.o \ - $(GAME_SHARED_OBJDIR)/voice_gamemgr.o - -$(DLLNAME)_$(ARCH).$(SHLIBEXT) : neat $(OBJ) - $(CC) $(CFLAGS) $(SHLIBLDFLAGS) $(LDFLAGS) -o $@ $(OBJ) - -neat: - -mkdir $(DLL_OBJDIR) - -mkdir $(GAME_SHARED_OBJDIR) - -mkdir $(PM_SHARED_OBJDIR) - -mkdir $(WPN_OBJ_DIR) -clean: - -rm -f $(OBJ) - -rm -f $(DLLNAME)_$(ARCH).$(SHLIBEXT) -spotless: clean - -rm -r $(WPN_OBJ_DIR) - -rm -r $(GAME_SHARED_OBJDIR) - -rm -r $(PM_SHARED_OBJDIR) - -rm -r $(DLL_OBJDIR) - diff --git a/ricochet/dlls/activity.h b/ricochet/dlls/activity.h deleted file mode 100644 index a496c12..0000000 --- a/ricochet/dlls/activity.h +++ /dev/null @@ -1,79 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ - -#ifndef ACTIVITY_H -#define ACTIVITY_H - - -typedef enum { - ACT_RESET = 0, // Set m_Activity to this invalid value to force a reset to m_IdealActivity - ACT_IDLE, - ACT_HOP, - ACT_HOP_LEFT_FOOT, - ACT_LEAP, - - ACT_TURN_LEFT, - ACT_TURN_RIGHT, - - ACT_BASE_STAND, - ACT_BASE_STAND_THROW, - ACT_FREEZE_STAND, - ACT_FREEZE_STAND_THROW, - ACT_HARD_STAND, - ACT_HARD_STAND_THROW, - ACT_TRIPLE_STAND, - ACT_TRIPLE_STAND_THROW, - - ACT_UNARMED_WALK, - ACT_UNARMED_RUN, - ACT_UNARMED_BACKPEDAL, - - ACT_BASE_WALK, - ACT_BASE_RUN, - ACT_BASE_THROW, - ACT_BASE_BACKUP, - ACT_BASE_BACKUP_THROW, - - ACT_BASE_REVERSE, - ACT_BASE_REVERSE_THROW, - - ACT_FALL, - ACT_FALL_FORWARD, - ACT_FALL_BACKWARD, - ACT_FALL_LEFT, - ACT_FALL_RIGHT, - - ACT_FLINCH_CLOCKWISE, - ACT_FLINCH_COUNTERCLOCKWISE, - ACT_FLINCH_BACK, - ACT_FLINCH_LEFT, - ACT_FLINCH_RIGHT, - ACT_FLINCH_FORWARD, - - ACT_DIE_HEADSHOT, - ACT_DIEFORWARD, - ACT_DIEBACKWARD, -} Activity; - - -typedef struct { - int type; - char *name; -} activity_map_t; - -extern activity_map_t activity_map[]; - - -#endif //ACTIVITY_H diff --git a/ricochet/dlls/activitymap.h b/ricochet/dlls/activitymap.h deleted file mode 100644 index 390d634..0000000 --- a/ricochet/dlls/activitymap.h +++ /dev/null @@ -1,37 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ - -#define _A( a ) { a, #a } - -activity_map_t activity_map[] = -{ -_A( ACT_IDLE ), -_A( ACT_HOP ), - -_A( ACT_FALL_FORWARD ), -_A( ACT_FALL_BACKWARD ), -_A( ACT_FALL_LEFT ), -_A( ACT_FALL_RIGHT ), - -_A( ACT_FLINCH_BACK ), -_A( ACT_FLINCH_LEFT ), -_A( ACT_FLINCH_RIGHT ), -_A( ACT_FLINCH_FORWARD ), - -_A( ACT_DIE_HEADSHOT ), -_A( ACT_DIEFORWARD ), -_A( ACT_DIEBACKWARD ), -0, NULL -}; diff --git a/ricochet/dlls/airtank.cpp b/ricochet/dlls/airtank.cpp deleted file mode 100644 index fa74af4..0000000 --- a/ricochet/dlls/airtank.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "weapons.h" -#include "nodes.h" -#include "player.h" - -class CAirtank : public CGrenade -{ - void Spawn( void ); - void Precache( void ); - void EXPORT TankThink( void ); - void EXPORT TankTouch( CBaseEntity *pOther ); - int BloodColor( void ) { return DONT_BLEED; }; - void Killed( entvars_t *pevAttacker, int iGib ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - int m_state; -}; - - -LINK_ENTITY_TO_CLASS( item_airtank, CAirtank ); -TYPEDESCRIPTION CAirtank::m_SaveData[] = -{ - DEFINE_FIELD( CAirtank, m_state, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CAirtank, CGrenade ); - - -void CAirtank :: Spawn( void ) -{ - Precache( ); - // motor - pev->movetype = MOVETYPE_FLY; - pev->solid = SOLID_BBOX; - - SET_MODEL(ENT(pev), "models/w_oxygen.mdl"); - UTIL_SetSize(pev, Vector( -16, -16, 0), Vector(16, 16, 36)); - UTIL_SetOrigin( pev, pev->origin ); - - SetTouch( &CAirtank::TankTouch ); - SetThink( &CAirtank::TankThink ); - - pev->flags |= FL_MONSTER; - pev->takedamage = DAMAGE_YES; - pev->health = 20; - pev->dmg = 50; - m_state = 1; -} - -void CAirtank::Precache( void ) -{ - PRECACHE_MODEL("models/w_oxygen.mdl"); - PRECACHE_SOUND("doors/aliendoor3.wav"); -} - - -void CAirtank :: Killed( entvars_t *pevAttacker, int iGib ) -{ - pev->owner = ENT( pevAttacker ); - - // UNDONE: this should make a big bubble cloud, not an explosion - - Explode( pev->origin, Vector( 0, 0, -1 ) ); -} - - -void CAirtank::TankThink( void ) -{ - // Fire trigger - m_state = 1; - SUB_UseTargets( this, USE_TOGGLE, 0 ); -} - - -void CAirtank::TankTouch( CBaseEntity *pOther ) -{ - if ( !pOther->IsPlayer() ) - return; - - if (!m_state) - { - // "no oxygen" sound - EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_swim2.wav", 1.0, ATTN_NORM ); - return; - } - - // give player 12 more seconds of air - pOther->pev->air_finished = gpGlobals->time + 12; - - // suit recharge sound - EMIT_SOUND( ENT(pev), CHAN_VOICE, "doors/aliendoor3.wav", 1.0, ATTN_NORM ); - - // recharge airtank in 30 seconds - pev->nextthink = gpGlobals->time + 30; - m_state = 0; - SUB_UseTargets( this, USE_TOGGLE, 1 ); -} diff --git a/ricochet/dlls/animating.cpp b/ricochet/dlls/animating.cpp deleted file mode 100644 index 7fc20c2..0000000 --- a/ricochet/dlls/animating.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== monsters.cpp ======================================================== - - Monster-related utility code - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "animation.h" -#include "saverestore.h" - -TYPEDESCRIPTION CBaseAnimating::m_SaveData[] = -{ - DEFINE_FIELD( CBaseMonster, m_flFrameRate, FIELD_FLOAT ), - DEFINE_FIELD( CBaseMonster, m_flGroundSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CBaseMonster, m_flLastEventCheck, FIELD_TIME ), - DEFINE_FIELD( CBaseMonster, m_fSequenceFinished, FIELD_BOOLEAN ), - DEFINE_FIELD( CBaseMonster, m_fSequenceLoops, FIELD_BOOLEAN ), -}; - -IMPLEMENT_SAVERESTORE( CBaseAnimating, CBaseDelay ); - - -//========================================================= -// StudioFrameAdvance - advance the animation frame up to the current time -// if an flInterval is passed in, only advance animation that number of seconds -//========================================================= -float CBaseAnimating :: StudioFrameAdvance ( float flInterval ) -{ - if (flInterval == 0.0) - { - flInterval = (gpGlobals->time - pev->animtime); - if (flInterval <= 0.001) - { - pev->animtime = gpGlobals->time; - return 0.0; - } - } - if (! pev->animtime) - flInterval = 0.0; - - pev->frame += flInterval * m_flFrameRate * pev->framerate; - pev->animtime = gpGlobals->time; - - if (pev->frame < 0.0 || pev->frame >= 256.0) - { - if (m_fSequenceLoops) - pev->frame -= (int)(pev->frame / 256.0) * 256.0; - else - pev->frame = (pev->frame < 0.0) ? 0 : 255; - m_fSequenceFinished = TRUE; // just in case it wasn't caught in GetEvents - } - - return flInterval; -} - -//========================================================= -// LookupActivity -//========================================================= -int CBaseAnimating :: LookupActivity ( int activity ) -{ - ASSERT( activity != 0 ); - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::LookupActivity( pmodel, pev, activity ); -} - -//========================================================= -// LookupActivityHeaviest -// -// Get activity with highest 'weight' -// -//========================================================= -int CBaseAnimating :: LookupActivityHeaviest ( int activity ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::LookupActivityHeaviest( pmodel, pev, activity ); -} - -//========================================================= -//========================================================= -int CBaseAnimating :: LookupSequence ( const char *label ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::LookupSequence( pmodel, label ); -} - - -//========================================================= -//========================================================= -void CBaseAnimating :: ResetSequenceInfo ( ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - GetSequenceInfo( pmodel, pev, &m_flFrameRate, &m_flGroundSpeed ); - m_fSequenceLoops = ((GetSequenceFlags() & STUDIO_LOOPING) != 0); - pev->animtime = gpGlobals->time; - pev->framerate = 1.0; - m_fSequenceFinished = FALSE; - m_flLastEventCheck = gpGlobals->time; -} - - - -//========================================================= -//========================================================= -BOOL CBaseAnimating :: GetSequenceFlags( ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::GetSequenceFlags( pmodel, pev ); -} - -//========================================================= -// DispatchAnimEvents -//========================================================= -void CBaseAnimating :: DispatchAnimEvents ( float flInterval ) -{ - MonsterEvent_t event; - - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - if ( !pmodel ) - { - ALERT( at_aiconsole, "Gibbed monster is thinking!\n" ); - return; - } - - // FIXME: I have to do this or some events get missed, and this is probably causing the problem below - flInterval = 0.1; - - // FIX: this still sometimes hits events twice - float flStart = pev->frame + (m_flLastEventCheck - pev->animtime) * m_flFrameRate * pev->framerate; - float flEnd = pev->frame + flInterval * m_flFrameRate * pev->framerate; - m_flLastEventCheck = pev->animtime + flInterval; - - m_fSequenceFinished = FALSE; - if (flEnd >= 256 || flEnd <= 0.0) - m_fSequenceFinished = TRUE; - - int index = 0; - - while ( (index = GetAnimationEvent( pmodel, pev, &event, flStart, flEnd, index ) ) != 0 ) - { - HandleAnimEvent( &event ); - } -} - - -//========================================================= -//========================================================= -float CBaseAnimating :: SetBoneController ( int iController, float flValue ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return SetController( pmodel, pev, iController, flValue ); -} - -//========================================================= -//========================================================= -void CBaseAnimating :: InitBoneControllers ( void ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - SetController( pmodel, pev, 0, 0.0 ); - SetController( pmodel, pev, 1, 0.0 ); - SetController( pmodel, pev, 2, 0.0 ); - SetController( pmodel, pev, 3, 0.0 ); -} - -//========================================================= -//========================================================= -float CBaseAnimating :: SetBlending ( int iBlender, float flValue ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - return ::SetBlending( pmodel, pev, iBlender, flValue ); -} - -//========================================================= -//========================================================= -void CBaseAnimating :: GetBonePosition ( int iBone, Vector &origin, Vector &angles ) -{ - GET_BONE_POSITION( ENT(pev), iBone, origin, angles ); -} - -//========================================================= -//========================================================= -void CBaseAnimating :: GetAttachment ( int iAttachment, Vector &origin, Vector &angles ) -{ - GET_ATTACHMENT( ENT(pev), iAttachment, origin, angles ); -} - -//========================================================= -//========================================================= -int CBaseAnimating :: FindTransition( int iEndingSequence, int iGoalSequence, int *piDir ) -{ - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - - if (piDir == NULL) - { - int iDir; - int sequence = ::FindTransition( pmodel, iEndingSequence, iGoalSequence, &iDir ); - if (iDir != 1) - return -1; - else - return sequence; - } - - return ::FindTransition( pmodel, iEndingSequence, iGoalSequence, piDir ); -} - -//========================================================= -//========================================================= -void CBaseAnimating :: GetAutomovement( Vector &origin, Vector &angles, float flInterval ) -{ - -} - -void CBaseAnimating :: SetBodygroup( int iGroup, int iValue ) -{ - ::SetBodygroup( GET_MODEL_PTR( ENT(pev) ), pev, iGroup, iValue ); -} - -int CBaseAnimating :: GetBodygroup( int iGroup ) -{ - return ::GetBodygroup( GET_MODEL_PTR( ENT(pev) ), pev, iGroup ); -} - - -int CBaseAnimating :: ExtractBbox( int sequence, float *mins, float *maxs ) -{ - return ::ExtractBbox( GET_MODEL_PTR( ENT(pev) ), sequence, mins, maxs ); -} - -//========================================================= -//========================================================= - -void CBaseAnimating :: SetSequenceBox( void ) -{ - Vector mins, maxs; - - // Get sequence bbox - if ( ExtractBbox( pev->sequence, mins, maxs ) ) - { - // expand box for rotation - // find min / max for rotations - float yaw = pev->angles.y * (M_PI / 180.0); - - Vector xvector, yvector; - xvector.x = cos(yaw); - xvector.y = sin(yaw); - yvector.x = -sin(yaw); - yvector.y = cos(yaw); - Vector bounds[2]; - - bounds[0] = mins; - bounds[1] = maxs; - - Vector rmin( 9999, 9999, 9999 ); - Vector rmax( -9999, -9999, -9999 ); - Vector base, transformed; - - for (int i = 0; i <= 1; i++ ) - { - base.x = bounds[i].x; - for ( int j = 0; j <= 1; j++ ) - { - base.y = bounds[j].y; - for ( int k = 0; k <= 1; k++ ) - { - base.z = bounds[k].z; - - // transform the point - transformed.x = xvector.x*base.x + yvector.x*base.y; - transformed.y = xvector.y*base.x + yvector.y*base.y; - transformed.z = base.z; - - for ( int l = 0; l < 3; l++ ) - { - if (transformed[l] < rmin[l]) - rmin[l] = transformed[l]; - if (transformed[l] > rmax[l]) - rmax[l] = transformed[l]; - } - } - } - } - rmin.z = 0; - rmax.z = rmin.z + 1; - UTIL_SetSize( pev, rmin, rmax ); - } -} - diff --git a/ricochet/dlls/animation.cpp b/ricochet/dlls/animation.cpp deleted file mode 100644 index 5eea589..0000000 --- a/ricochet/dlls/animation.cpp +++ /dev/null @@ -1,522 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "Platform.h" - -// hack into header files that we can ship -typedef int qboolean; -typedef unsigned char byte; -#include "../utils/common/mathlib.h" -#include "const.h" -#include "progdefs.h" -#include "edict.h" -#include "eiface.h" - -#include "studio.h" - -#include "../engine/studio.h" - -#ifndef ACTIVITY_H -#include "activity.h" -#endif - -#include "activitymap.h" - -#ifndef ANIMATION_H -#include "animation.h" -#endif - -#ifndef SCRIPTEVENT_H -#include "scriptevent.h" -#endif - -#ifndef ENGINECALLBACK_H -#include "enginecallback.h" -#endif - -extern globalvars_t *gpGlobals; - -#pragma warning( disable : 4244 ) - - - -int ExtractBbox( void *pmodel, int sequence, float *mins, float *maxs ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return 0; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - mins[0] = pseqdesc[ sequence ].bbmin[0]; - mins[1] = pseqdesc[ sequence ].bbmin[1]; - mins[2] = pseqdesc[ sequence ].bbmin[2]; - - maxs[0] = pseqdesc[ sequence ].bbmax[0]; - maxs[1] = pseqdesc[ sequence ].bbmax[1]; - maxs[2] = pseqdesc[ sequence ].bbmax[2]; - - return 1; -} - - -int LookupActivity( void *pmodel, entvars_t *pev, int activity ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return 0; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - int weighttotal = 0; - int seq = ACTIVITY_NOT_AVAILABLE; - for (int i = 0; i < pstudiohdr->numseq; i++) - { - if (pseqdesc[i].activity == activity) - { - weighttotal += pseqdesc[i].actweight; - if (!weighttotal || RANDOM_LONG(0,weighttotal-1) < pseqdesc[i].actweight) - seq = i; - } - } - - return seq; -} - - -int LookupActivityHeaviest( void *pmodel, entvars_t *pev, int activity ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr ) - return 0; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - int weight = 0; - int seq = ACTIVITY_NOT_AVAILABLE; - for (int i = 0; i < pstudiohdr->numseq; i++) - { - if (pseqdesc[i].activity == activity) - { - if ( pseqdesc[i].actweight > weight ) - { - weight = pseqdesc[i].actweight; - seq = i; - } - } - } - - return seq; -} - -void GetEyePosition ( void *pmodel, float *vecEyePosition ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - - if ( !pstudiohdr ) - { - ALERT ( at_console, "GetEyePosition() Can't get pstudiohdr ptr!\n" ); - return; - } - - VectorCopy ( pstudiohdr->eyeposition, vecEyePosition ); -} - -int LookupSequence( void *pmodel, const char *label ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return 0; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - for (int i = 0; i < pstudiohdr->numseq; i++) - { - if (stricmp( pseqdesc[i].label, label ) == 0) - return i; - } - - return -1; -} - - -int IsSoundEvent( int eventNumber ) -{ - if ( eventNumber == SCRIPT_EVENT_SOUND || eventNumber == SCRIPT_EVENT_SOUND_VOICE ) - return 1; - return 0; -} - - -void SequencePrecache( void *pmodel, const char *pSequenceName ) -{ - int index = LookupSequence( pmodel, pSequenceName ); - if ( index >= 0 ) - { - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr || index >= pstudiohdr->numseq ) - return; - - mstudioseqdesc_t *pseqdesc; - mstudioevent_t *pevent; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + index; - pevent = (mstudioevent_t *)((byte *)pstudiohdr + pseqdesc->eventindex); - - for (int i = 0; i < pseqdesc->numevents; i++) - { - // Don't send client-side events to the server AI - if ( pevent[i].event >= EVENT_CLIENT ) - continue; - - // UNDONE: Add a callback to check to see if a sound is precached yet and don't allocate a copy - // of it's name if it is. - if ( IsSoundEvent( pevent[i].event ) ) - { - if ( !strlen(pevent[i].options) ) - { - ALERT( at_error, "Bad sound event %d in sequence %s :: %s (sound is \"%s\")\n", pevent[i].event, pstudiohdr->name, pSequenceName, pevent[i].options ); - } - - PRECACHE_SOUND( (char *)(gpGlobals->pStringBase + ALLOC_STRING(pevent[i].options) ) ); - } - } - } -} - - - -void GetSequenceInfo( void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return; - - mstudioseqdesc_t *pseqdesc; - - if (pev->sequence >= pstudiohdr->numseq) - { - *pflFrameRate = 0.0; - *pflGroundSpeed = 0.0; - return; - } - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - if (pseqdesc->numframes > 1) - { - *pflFrameRate = 256 * pseqdesc->fps / (pseqdesc->numframes - 1); - *pflGroundSpeed = sqrt( pseqdesc->linearmovement[0]*pseqdesc->linearmovement[0]+ pseqdesc->linearmovement[1]*pseqdesc->linearmovement[1]+ pseqdesc->linearmovement[2]*pseqdesc->linearmovement[2] ); - *pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1); - } - else - { - *pflFrameRate = 256.0; - *pflGroundSpeed = 0.0; - } -} - - -int GetSequenceFlags( void *pmodel, entvars_t *pev ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr || pev->sequence >= pstudiohdr->numseq ) - return 0; - - mstudioseqdesc_t *pseqdesc; - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - return pseqdesc->flags; -} - - -int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEvent, float flStart, float flEnd, int index ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if ( !pstudiohdr || pev->sequence >= pstudiohdr->numseq || !pMonsterEvent ) - return 0; - - int events = 0; - - mstudioseqdesc_t *pseqdesc; - mstudioevent_t *pevent; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - pevent = (mstudioevent_t *)((byte *)pstudiohdr + pseqdesc->eventindex); - - if (pseqdesc->numevents == 0 || index > pseqdesc->numevents ) - return 0; - - if (pseqdesc->numframes > 1) - { - flStart *= (pseqdesc->numframes - 1) / 256.0; - flEnd *= (pseqdesc->numframes - 1) / 256.0; - } - else - { - flStart = 0; - flEnd = 1.0; - } - - for (; index < pseqdesc->numevents; index++) - { - // Don't send client-side events to the server AI - if ( pevent[index].event >= EVENT_CLIENT ) - continue; - - if ( (pevent[index].frame >= flStart && pevent[index].frame < flEnd) || - ((pseqdesc->flags & STUDIO_LOOPING) && flEnd >= pseqdesc->numframes - 1 && pevent[index].frame < flEnd - pseqdesc->numframes + 1) ) - { - pMonsterEvent->event = pevent[index].event; - pMonsterEvent->options = pevent[index].options; - return index + 1; - } - } - return 0; -} - -float SetController( void *pmodel, entvars_t *pev, int iController, float flValue ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return flValue; - - mstudiobonecontroller_t *pbonecontroller = (mstudiobonecontroller_t *)((byte *)pstudiohdr + pstudiohdr->bonecontrollerindex); - - // find first controller that matches the index - int i; - for ( i = 0; i < pstudiohdr->numbonecontrollers; i++, pbonecontroller++) - { - if (pbonecontroller->index == iController) - break; - } - if (i >= pstudiohdr->numbonecontrollers) - return flValue; - - // wrap 0..360 if it's a rotational controller - - if (pbonecontroller->type & (STUDIO_XR | STUDIO_YR | STUDIO_ZR)) - { - // ugly hack, invert value if end < start - if (pbonecontroller->end < pbonecontroller->start) - flValue = -flValue; - - // does the controller not wrap? - if (pbonecontroller->start + 359.0 >= pbonecontroller->end) - { - if (flValue > ((pbonecontroller->start + pbonecontroller->end) / 2.0) + 180) - flValue = flValue - 360; - if (flValue < ((pbonecontroller->start + pbonecontroller->end) / 2.0) - 180) - flValue = flValue + 360; - } - else - { - if (flValue > 360) - flValue = flValue - (int)(flValue / 360.0) * 360.0; - else if (flValue < 0) - flValue = flValue + (int)((flValue / -360.0) + 1) * 360.0; - } - } - - int setting = 255 * (flValue - pbonecontroller->start) / (pbonecontroller->end - pbonecontroller->start); - - if (setting < 0) setting = 0; - if (setting > 255) setting = 255; - pev->controller[iController] = setting; - - return setting * (1.0 / 255.0) * (pbonecontroller->end - pbonecontroller->start) + pbonecontroller->start; -} - - -float SetBlending( void *pmodel, entvars_t *pev, int iBlender, float flValue ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return flValue; - - mstudioseqdesc_t *pseqdesc; - - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + (int)pev->sequence; - - if (pseqdesc->blendtype[iBlender] == 0) - return flValue; - - if (pseqdesc->blendtype[iBlender] & (STUDIO_XR | STUDIO_YR | STUDIO_ZR)) - { - // ugly hack, invert value if end < start - if (pseqdesc->blendend[iBlender] < pseqdesc->blendstart[iBlender]) - flValue = -flValue; - - // does the controller not wrap? - if (pseqdesc->blendstart[iBlender] + 359.0 >= pseqdesc->blendend[iBlender]) - { - if (flValue > ((pseqdesc->blendstart[iBlender] + pseqdesc->blendend[iBlender]) / 2.0) + 180) - flValue = flValue - 360; - if (flValue < ((pseqdesc->blendstart[iBlender] + pseqdesc->blendend[iBlender]) / 2.0) - 180) - flValue = flValue + 360; - } - } - - int setting = 255 * (flValue - pseqdesc->blendstart[iBlender]) / (pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender]); - - if (setting < 0) setting = 0; - if (setting > 255) setting = 255; - - pev->blending[iBlender] = setting; - - return setting * (1.0 / 255.0) * (pseqdesc->blendend[iBlender] - pseqdesc->blendstart[iBlender]) + pseqdesc->blendstart[iBlender]; -} - - - - -int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return iGoalAnim; - - mstudioseqdesc_t *pseqdesc; - pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex); - - // bail if we're going to or from a node 0 - if (pseqdesc[iEndingAnim].entrynode == 0 || pseqdesc[iGoalAnim].entrynode == 0) - { - return iGoalAnim; - } - - int iEndNode; - - // ALERT( at_console, "from %d to %d: ", pEndNode->iEndNode, pGoalNode->iStartNode ); - - if (*piDir > 0) - { - iEndNode = pseqdesc[iEndingAnim].exitnode; - } - else - { - iEndNode = pseqdesc[iEndingAnim].entrynode; - } - - if (iEndNode == pseqdesc[iGoalAnim].entrynode) - { - *piDir = 1; - return iGoalAnim; - } - - byte *pTransition = ((byte *)pstudiohdr + pstudiohdr->transitionindex); - - int iInternNode = pTransition[(iEndNode-1)*pstudiohdr->numtransitions + (pseqdesc[iGoalAnim].entrynode-1)]; - - if (iInternNode == 0) - return iGoalAnim; - - int i; - - // look for someone going - for (i = 0; i < pstudiohdr->numseq; i++) - { - if (pseqdesc[i].entrynode == iEndNode && pseqdesc[i].exitnode == iInternNode) - { - *piDir = 1; - return i; - } - if (pseqdesc[i].nodeflags) - { - if (pseqdesc[i].exitnode == iEndNode && pseqdesc[i].entrynode == iInternNode) - { - *piDir = -1; - return i; - } - } - } - - ALERT( at_console, "error in transition graph" ); - return iGoalAnim; -} - -void SetBodygroup( void *pmodel, entvars_t *pev, int iGroup, int iValue ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return; - - if (iGroup > pstudiohdr->numbodyparts) - return; - - mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + iGroup; - - if (iValue >= pbodypart->nummodels) - return; - - int iCurrent = (pev->body / pbodypart->base) % pbodypart->nummodels; - - pev->body = (pev->body - (iCurrent * pbodypart->base) + (iValue * pbodypart->base)); -} - - -int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup ) -{ - studiohdr_t *pstudiohdr; - - pstudiohdr = (studiohdr_t *)pmodel; - if (! pstudiohdr) - return 0; - - if (iGroup > pstudiohdr->numbodyparts) - return 0; - - mstudiobodyparts_t *pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex) + iGroup; - - if (pbodypart->nummodels <= 1) - return 0; - - int iCurrent = (pev->body / pbodypart->base) % pbodypart->nummodels; - - return iCurrent; -} diff --git a/ricochet/dlls/animation.h b/ricochet/dlls/animation.h deleted file mode 100644 index 3da74cb..0000000 --- a/ricochet/dlls/animation.h +++ /dev/null @@ -1,47 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef ANIMATION_H -#define ANIMATION_H - -#define ACTIVITY_NOT_AVAILABLE -1 - -#ifndef MONSTEREVENT_H -#include "monsterevent.h" -#endif - -extern int IsSoundEvent( int eventNumber ); - -int LookupActivity( void *pmodel, entvars_t *pev, int activity ); -int LookupActivityHeaviest( void *pmodel, entvars_t *pev, int activity ); -int LookupSequence( void *pmodel, const char *label ); -void GetSequenceInfo( void *pmodel, entvars_t *pev, float *pflFrameRate, float *pflGroundSpeed ); -int GetSequenceFlags( void *pmodel, entvars_t *pev ); -int LookupAnimationEvents( void *pmodel, entvars_t *pev, float flStart, float flEnd ); -float SetController( void *pmodel, entvars_t *pev, int iController, float flValue ); -float SetBlending( void *pmodel, entvars_t *pev, int iBlender, float flValue ); -void GetEyePosition( void *pmodel, float *vecEyePosition ); -void SequencePrecache( void *pmodel, const char *pSequenceName ); -int FindTransition( void *pmodel, int iEndingAnim, int iGoalAnim, int *piDir ); -void SetBodygroup( void *pmodel, entvars_t *pev, int iGroup, int iValue ); -int GetBodygroup( void *pmodel, entvars_t *pev, int iGroup ); - -int GetAnimationEvent( void *pmodel, entvars_t *pev, MonsterEvent_t *pMonsterEvent, float flStart, float flEnd, int index ); -int ExtractBbox( void *pmodel, int sequence, float *mins, float *maxs ); - -// From /engine/studio.h -#define STUDIO_LOOPING 0x0001 - - -#endif //ANIMATION_H diff --git a/ricochet/dlls/basemonster.h b/ricochet/dlls/basemonster.h deleted file mode 100644 index ab516a1..0000000 --- a/ricochet/dlls/basemonster.h +++ /dev/null @@ -1,94 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef BASEMONSTER_H -#define BASEMONSTER_H - -class CBaseMonster : public CBaseToggle -{ -public: - Activity m_Activity;// what the monster is doing (animation) - Activity m_IdealActivity;// monster should switch to this activity - int m_LastHitGroup; // the last body region that took damage - int m_bitsDamageType; // what types of damage has monster (player) taken - BYTE m_rgbTimeBasedDamage[CDMG_TIMEBASED]; - MONSTERSTATE m_MonsterState;// monster's current state - MONSTERSTATE m_IdealMonsterState;// monster should change to this state - int m_afConditions; - int m_afMemory; - float m_flNextAttack; // cannot attack again until this time - EHANDLE m_hEnemy; // the entity that the monster is fighting. - EHANDLE m_hTargetEnt; // the entity that the monster is trying to reach - float m_flFieldOfView;// width of monster's field of view ( dot product ) - int m_bloodColor; // color of blood particless - Vector m_HackedGunPos; // HACK until we can query end of gun - Vector m_vecEnemyLKP;// last known position of enemy. (enemy's origin) - - - void KeyValue( KeyValueData *pkvd ); - - void MakeIdealYaw( Vector vecTarget ); - virtual float ChangeYaw ( int speed ); - virtual BOOL HasHumanGibs( void ); - virtual BOOL HasAlienGibs( void ); - virtual void FadeMonster( void ); // Called instead of GibMonster() when gibs are disabled - virtual void GibMonster( void ); - virtual Activity GetDeathActivity ( void ); - Activity GetSmallFlinchActivity( void ); - virtual void BecomeDead( void ); - BOOL ShouldGibMonster( int iGib ); - void CallGibMonster( void ); - virtual BOOL ShouldFadeOnDeath( void ); - BOOL FCheckAITrigger( void );// checks and, if necessary, fires the monster's trigger target. - virtual int IRelationship ( CBaseEntity *pTarget ); - virtual int TakeHealth( float flHealth, int bitsDamageType ); - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType); - int DeadTakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); - float DamageForce( float damage ); - virtual void Killed( entvars_t *pevAttacker, int iGib ); - virtual void PainSound ( void ) { return; }; - - void RadiusDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ); - void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ); - - inline void SetConditions( int iConditions ) { m_afConditions |= iConditions; } - inline void ClearConditions( int iConditions ) { m_afConditions &= ~iConditions; } - inline BOOL HasConditions( int iConditions ) { if ( m_afConditions & iConditions ) return TRUE; return FALSE; } - inline BOOL HasAllConditions( int iConditions ) { if ( (m_afConditions & iConditions) == iConditions ) return TRUE; return FALSE; } - - inline void Remember( int iMemory ) { m_afMemory |= iMemory; } - inline void Forget( int iMemory ) { m_afMemory &= ~iMemory; } - inline BOOL HasMemory( int iMemory ) { if ( m_afMemory & iMemory ) return TRUE; return FALSE; } - inline BOOL HasAllMemories( int iMemory ) { if ( (m_afMemory & iMemory) == iMemory ) return TRUE; return FALSE; } - - // This will stop animation until you call ResetSequenceInfo() at some point in the future - inline void StopAnimation( void ) { pev->framerate = 0; } - - virtual void ReportAIState( void ); - virtual void MonsterInitDead( void ); // Call after animation/pose is set up - void EXPORT CorpseFallThink( void ); - - virtual void Look ( int iDistance );// basic sight function for monsters - virtual CBaseEntity* BestVisibleEnemy ( void );// finds best visible enemy for attack - CBaseEntity *CheckTraceHullAttack( float flDist, int iDamage, int iDmgType ); - virtual BOOL FInViewCone ( CBaseEntity *pEntity );// see if pEntity is in monster's view cone - virtual BOOL FInViewCone ( Vector *pOrigin );// see if given location is in monster's view cone - void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); - void MakeDamageBloodDecal ( int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir ); - virtual BOOL IsAlive( void ) { return (pev->deadflag != DEAD_DEAD); } - -}; - - -#endif diff --git a/ricochet/dlls/bmodels.cpp b/ricochet/dlls/bmodels.cpp deleted file mode 100644 index bb8a736..0000000 --- a/ricochet/dlls/bmodels.cpp +++ /dev/null @@ -1,958 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== bmodels.cpp ======================================================== - - spawn, think, and use functions for entities that use brush models - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "doors.h" - -extern DLL_GLOBAL Vector g_vecAttackDir; - -#define SF_BRUSH_ACCDCC 16// brush should accelerate and decelerate when toggled -#define SF_BRUSH_HURT 32// rotating brush that inflicts pain based on rotation speed -#define SF_ROTATING_NOT_SOLID 64 // some special rotating objects are not solid. - -// covering cheesy noise1, noise2, & noise3 fields so they make more sense (for rotating fans) -#define noiseStart noise1 -#define noiseStop noise2 -#define noiseRunning noise3 - -#define SF_PENDULUM_SWING 2 // spawnflag that makes a pendulum a rope swing. -// -// BModelOrigin - calculates origin of a bmodel from absmin/size because all bmodel origins are 0 0 0 -// -Vector VecBModelOrigin( entvars_t* pevBModel ) -{ - return pevBModel->absmin + ( pevBModel->size * 0.5 ); -} - -// =================== FUNC_WALL ============================================== - -/*QUAKED func_wall (0 .5 .8) ? -This is just a solid wall if not inhibited -*/ -class CFuncWall : public CBaseEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - // Bmodels don't go across transitions - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } -}; - -LINK_ENTITY_TO_CLASS( func_wall, CFuncWall ); - -void CFuncWall :: Spawn( void ) -{ - pev->angles = g_vecZero; - pev->movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything - pev->solid = SOLID_BSP; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - // If it can't move/go away, it's really part of the world - pev->flags |= FL_WORLDBRUSH; -} - - -void CFuncWall :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( ShouldToggle( useType, (int)(pev->frame)) ) - pev->frame = 1 - pev->frame; -} - - -#define SF_WALL_START_OFF 0x0001 - -class CFuncWallToggle : public CFuncWall -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void TurnOff( void ); - void TurnOn( void ); - BOOL IsOn( void ); -}; - -LINK_ENTITY_TO_CLASS( func_wall_toggle, CFuncWallToggle ); - -void CFuncWallToggle :: Spawn( void ) -{ - CFuncWall::Spawn(); - if ( pev->spawnflags & SF_WALL_START_OFF ) - TurnOff(); -} - - -void CFuncWallToggle :: TurnOff( void ) -{ - pev->solid = SOLID_NOT; - pev->effects |= EF_NODRAW; - UTIL_SetOrigin( pev, pev->origin ); -} - - -void CFuncWallToggle :: TurnOn( void ) -{ - pev->solid = SOLID_BSP; - pev->effects &= ~EF_NODRAW; - UTIL_SetOrigin( pev, pev->origin ); -} - - -BOOL CFuncWallToggle :: IsOn( void ) -{ - if ( pev->solid == SOLID_NOT ) - return FALSE; - return TRUE; -} - - -void CFuncWallToggle :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int status = IsOn(); - - if ( ShouldToggle( useType, status ) ) - { - if ( status ) - TurnOff(); - else - TurnOn(); - } -} - - -#define SF_CONVEYOR_VISUAL 0x0001 -#define SF_CONVEYOR_NOTSOLID 0x0002 - -class CFuncConveyor : public CFuncWall -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void UpdateSpeed( float speed ); -}; - -LINK_ENTITY_TO_CLASS( func_conveyor, CFuncConveyor ); -void CFuncConveyor :: Spawn( void ) -{ - SetMovedir( pev ); - CFuncWall::Spawn(); - - if ( !(pev->spawnflags & SF_CONVEYOR_VISUAL) ) - SetBits( pev->flags, FL_CONVEYOR ); - - // HACKHACK - This is to allow for some special effects - if ( pev->spawnflags & SF_CONVEYOR_NOTSOLID ) - { - pev->solid = SOLID_NOT; - pev->skin = 0; // Don't want the engine thinking we've got special contents on this brush - } - - if ( pev->speed == 0 ) - pev->speed = 100; - - UpdateSpeed( pev->speed ); -} - - -// HACKHACK -- This is ugly, but encode the speed in the rendercolor to avoid adding more data to the network stream -void CFuncConveyor :: UpdateSpeed( float speed ) -{ - // Encode it as an integer with 4 fractional bits - int speedCode = (int)(fabs(speed) * 16.0); - - if ( speed < 0 ) - pev->rendercolor.x = 1; - else - pev->rendercolor.x = 0; - - pev->rendercolor.y = (speedCode >> 8); - pev->rendercolor.z = (speedCode & 0xFF); -} - - -void CFuncConveyor :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - pev->speed = -pev->speed; - UpdateSpeed( pev->speed ); -} - - - -// =================== FUNC_ILLUSIONARY ============================================== - - -/*QUAKED func_illusionary (0 .5 .8) ? -A simple entity that looks solid but lets you walk through it. -*/ -class CFuncIllusionary : public CBaseToggle -{ -public: - void Spawn( void ); - void EXPORT SloshTouch( CBaseEntity *pOther ); - void KeyValue( KeyValueData *pkvd ); - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } -}; - -LINK_ENTITY_TO_CLASS( func_illusionary, CFuncIllusionary ); - -void CFuncIllusionary :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "skin"))//skin is used for content type - { - pev->skin = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -void CFuncIllusionary :: Spawn( void ) -{ - pev->angles = g_vecZero; - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_NOT;// always solid_not - SET_MODEL( ENT(pev), STRING(pev->model) ); - - // I'd rather eat the network bandwidth of this than figure out how to save/restore - // these entities after they have been moved to the client, or respawn them ala Quake - // Perhaps we can do this in deathmatch only. - // MAKE_STATIC(ENT(pev)); -} - - -// ------------------------------------------------------------------------------- -// -// Monster only clip brush -// -// This brush will be solid for any entity who has the FL_MONSTERCLIP flag set -// in pev->flags -// -// otherwise it will be invisible and not solid. This can be used to keep -// specific monsters out of certain areas -// -// ------------------------------------------------------------------------------- -class CFuncMonsterClip : public CFuncWall -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) {} // Clear out func_wall's use function -}; - -LINK_ENTITY_TO_CLASS( func_monsterclip, CFuncMonsterClip ); - -void CFuncMonsterClip::Spawn( void ) -{ - CFuncWall::Spawn(); - if ( CVAR_GET_FLOAT("showtriggers") == 0 ) - pev->effects = EF_NODRAW; - pev->flags |= FL_MONSTERCLIP; -} - - -// =================== FUNC_ROTATING ============================================== -class CFuncRotating : public CBaseEntity -{ -public: - // basic functions - void Spawn( void ); - void Precache( void ); - void EXPORT SpinUp ( void ); - void EXPORT SpinDown ( void ); - void KeyValue( KeyValueData* pkvd); - void EXPORT HurtTouch ( CBaseEntity *pOther ); - void EXPORT RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT Rotate( void ); - void RampPitchVol (int fUp ); - void Blocked( CBaseEntity *pOther ); - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - float m_flFanFriction; - float m_flAttenuation; - float m_flVolume; - float m_pitch; - int m_sounds; -}; - -TYPEDESCRIPTION CFuncRotating::m_SaveData[] = -{ - DEFINE_FIELD( CFuncRotating, m_flFanFriction, FIELD_FLOAT ), - DEFINE_FIELD( CFuncRotating, m_flAttenuation, FIELD_FLOAT ), - DEFINE_FIELD( CFuncRotating, m_flVolume, FIELD_FLOAT ), - DEFINE_FIELD( CFuncRotating, m_pitch, FIELD_FLOAT ), - DEFINE_FIELD( CFuncRotating, m_sounds, FIELD_INTEGER ) -}; - -IMPLEMENT_SAVERESTORE( CFuncRotating, CBaseEntity ); - - -LINK_ENTITY_TO_CLASS( func_rotating, CFuncRotating ); - -void CFuncRotating :: KeyValue( KeyValueData* pkvd) -{ - if (FStrEq(pkvd->szKeyName, "fanfriction")) - { - m_flFanFriction = atof(pkvd->szValue)/100; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "Volume")) - { - m_flVolume = atof(pkvd->szValue)/10.0; - - if (m_flVolume > 1.0) - m_flVolume = 1.0; - if (m_flVolume < 0.0) - m_flVolume = 0.0; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spawnorigin")) - { - Vector tmp; - UTIL_StringToVector( (float *)tmp, pkvd->szValue ); - if ( tmp != g_vecZero ) - pev->origin = tmp; - } - else if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -/*QUAKED func_rotating (0 .5 .8) ? START_ON REVERSE X_AXIS Y_AXIS -You need to have an origin brush as part of this entity. The -center of that brush will be -the point around which it is rotated. It will rotate around the Z -axis by default. You can -check either the X_AXIS or Y_AXIS box to change that. - -"speed" determines how fast it moves; default value is 100. -"dmg" damage to inflict when blocked (2 default) - -REVERSE will cause the it to rotate in the opposite direction. -*/ - - -void CFuncRotating :: Spawn( ) -{ - // set final pitch. Must not be PITCH_NORM, since we - // plan on pitch shifting later. - - m_pitch = PITCH_NORM - 1; - - // maintain compatibility with previous maps - if (m_flVolume == 0.0) - m_flVolume = 1.0; - - // if the designer didn't set a sound attenuation, default to one. - m_flAttenuation = ATTN_NORM; - - if ( FBitSet ( pev->spawnflags, SF_BRUSH_ROTATE_SMALLRADIUS) ) - { - m_flAttenuation = ATTN_IDLE; - } - else if ( FBitSet ( pev->spawnflags, SF_BRUSH_ROTATE_MEDIUMRADIUS) ) - { - m_flAttenuation = ATTN_STATIC; - } - else if ( FBitSet ( pev->spawnflags, SF_BRUSH_ROTATE_LARGERADIUS) ) - { - m_flAttenuation = ATTN_NORM; - } - - // prevent divide by zero if level designer forgets friction! - if ( m_flFanFriction == 0 ) - { - m_flFanFriction = 1; - } - - if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_Z_AXIS) ) - pev->movedir = Vector(0,0,1); - else if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_X_AXIS) ) - pev->movedir = Vector(1,0,0); - else - pev->movedir = Vector(0,1,0); // y-axis - - // check for reverse rotation - if ( FBitSet(pev->spawnflags, SF_BRUSH_ROTATE_BACKWARDS) ) - pev->movedir = pev->movedir * -1; - - // some rotating objects like fake volumetric lights will not be solid. - if ( FBitSet(pev->spawnflags, SF_ROTATING_NOT_SOLID) ) - { - pev->solid = SOLID_NOT; - pev->skin = CONTENTS_EMPTY; - pev->movetype = MOVETYPE_PUSH; - } - else - { - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - } - - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - SetUse( &CFuncRotating::RotatingUse ); - // did level designer forget to assign speed? - if (pev->speed <= 0) - pev->speed = 0; - - // Removed this per level designers request. -- JAY - // if (pev->dmg == 0) - // pev->dmg = 2; - - // instant-use brush? - if ( FBitSet( pev->spawnflags, SF_BRUSH_ROTATE_INSTANT) ) - { - SetThink( &CFuncRotating::SUB_CallUseToggle ); - pev->nextthink = pev->ltime + 1.5; // leave a magic delay for client to start up - } - // can this brush inflict pain? - if ( FBitSet (pev->spawnflags, SF_BRUSH_HURT) ) - { - SetTouch( &CFuncRotating::HurtTouch ); - } - - Precache( ); -} - - -void CFuncRotating :: Precache( void ) -{ - char* szSoundFile = (char*) STRING(pev->message); - - // set up fan sounds - - if (!FStringNull( pev->message ) && strlen( szSoundFile ) > 0) - { - // if a path is set for a wave, use it - - PRECACHE_SOUND(szSoundFile); - - pev->noiseRunning = ALLOC_STRING(szSoundFile); - } else - { - // otherwise use preset sound - switch (m_sounds) - { - case 1: - PRECACHE_SOUND ("fans/fan1.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan1.wav"); - break; - case 2: - PRECACHE_SOUND ("fans/fan2.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan2.wav"); - break; - case 3: - PRECACHE_SOUND ("fans/fan3.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan3.wav"); - break; - case 4: - PRECACHE_SOUND ("fans/fan4.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan4.wav"); - break; - case 5: - PRECACHE_SOUND ("fans/fan5.wav"); - pev->noiseRunning = ALLOC_STRING("fans/fan5.wav"); - break; - - case 0: - default: - if (!FStringNull( pev->message ) && strlen( szSoundFile ) > 0) - { - PRECACHE_SOUND(szSoundFile); - - pev->noiseRunning = ALLOC_STRING(szSoundFile); - break; - } else - { - pev->noiseRunning = ALLOC_STRING("common/null.wav"); - break; - } - } - } - - if (pev->avelocity != g_vecZero ) - { - // if fan was spinning, and we went through transition or save/restore, - // make sure we restart the sound. 1.5 sec delay is magic number. KDB - - SetThink ( &CFuncRotating::SpinUp ); - pev->nextthink = pev->ltime + 1.5; - } -} - - - -// -// Touch - will hurt others based on how fast the brush is spinning -// -void CFuncRotating :: HurtTouch ( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - // we can't hurt this thing, so we're not concerned with it - if ( !pevOther->takedamage ) - return; - - // calculate damage based on rotation speed - pev->dmg = pev->avelocity.Length() / 10; - - pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH); - - pevOther->velocity = (pevOther->origin - VecBModelOrigin(pev) ).Normalize() * pev->dmg; -} - -// -// RampPitchVol - ramp pitch and volume up to final values, based on difference -// between how fast we're going vs how fast we plan to go -// -#define FANPITCHMIN 30 -#define FANPITCHMAX 100 - -void CFuncRotating :: RampPitchVol (int fUp) -{ - - Vector vecAVel = pev->avelocity; - vec_t vecCur; - vec_t vecFinal; - float fpct; - float fvol; - float fpitch; - int pitch; - - // get current angular velocity - - vecCur = fabs(vecAVel.x != 0 ? vecAVel.x : (vecAVel.y != 0 ? vecAVel.y : vecAVel.z)); - - // get target angular velocity - - vecFinal = (pev->movedir.x != 0 ? pev->movedir.x : (pev->movedir.y != 0 ? pev->movedir.y : pev->movedir.z)); - vecFinal *= pev->speed; - vecFinal = fabs(vecFinal); - - // calc volume and pitch as % of final vol and pitch - - fpct = vecCur / vecFinal; -// if (fUp) -// fvol = m_flVolume * (0.5 + fpct/2.0); // spinup volume ramps up from 50% max vol -// else - fvol = m_flVolume * fpct; // slowdown volume ramps down to 0 - - fpitch = FANPITCHMIN + (FANPITCHMAX - FANPITCHMIN) * fpct; - - pitch = (int) fpitch; - if (pitch == PITCH_NORM) - pitch = PITCH_NORM-1; - - // change the fan's vol and pitch - - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), - fvol, m_flAttenuation, SND_CHANGE_PITCH | SND_CHANGE_VOL, pitch); - -} - -// -// SpinUp - accelerates a non-moving func_rotating up to it's speed -// -void CFuncRotating :: SpinUp( void ) -{ - Vector vecAVel;//rotational velocity - - pev->nextthink = pev->ltime + 0.1; - pev->avelocity = pev->avelocity + ( pev->movedir * ( pev->speed * m_flFanFriction ) ); - - vecAVel = pev->avelocity;// cache entity's rotational velocity - - // if we've met or exceeded target speed, set target speed and stop thinking - if ( fabs(vecAVel.x) >= fabs(pev->movedir.x * pev->speed) && - fabs(vecAVel.y) >= fabs(pev->movedir.y * pev->speed) && - fabs(vecAVel.z) >= fabs(pev->movedir.z * pev->speed) ) - { - pev->avelocity = pev->movedir * pev->speed;// set speed in case we overshot - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), - m_flVolume, m_flAttenuation, SND_CHANGE_PITCH | SND_CHANGE_VOL, FANPITCHMAX); - - SetThink( &CFuncRotating::Rotate ); - Rotate(); - } - else - { - RampPitchVol(TRUE); - } -} - -// -// SpinDown - decelerates a moving func_rotating to a standstill. -// -void CFuncRotating :: SpinDown( void ) -{ - Vector vecAVel;//rotational velocity - vec_t vecdir; - - pev->nextthink = pev->ltime + 0.1; - - pev->avelocity = pev->avelocity - ( pev->movedir * ( pev->speed * m_flFanFriction ) );//spin down slower than spinup - - vecAVel = pev->avelocity;// cache entity's rotational velocity - - if (pev->movedir.x != 0) - vecdir = pev->movedir.x; - else if (pev->movedir.y != 0) - vecdir = pev->movedir.y; - else - vecdir = pev->movedir.z; - - // if we've met or exceeded target speed, set target speed and stop thinking - // (note: must check for movedir > 0 or < 0) - if (((vecdir > 0) && (vecAVel.x <= 0 && vecAVel.y <= 0 && vecAVel.z <= 0)) || - ((vecdir < 0) && (vecAVel.x >= 0 && vecAVel.y >= 0 && vecAVel.z >= 0))) - { - pev->avelocity = g_vecZero;// set speed in case we overshot - - // stop sound, we're done - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning /* Stop */), - 0, 0, SND_STOP, m_pitch); - - SetThink( &CFuncRotating::Rotate ); - Rotate(); - } - else - { - RampPitchVol(FALSE); - } -} - -void CFuncRotating :: Rotate( void ) -{ - pev->nextthink = pev->ltime + 10; -} - -//========================================================= -// Rotating Use - when a rotating brush is triggered -//========================================================= -void CFuncRotating :: RotatingUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // is this a brush that should accelerate and decelerate when turned on/off (fan)? - if ( FBitSet ( pev->spawnflags, SF_BRUSH_ACCDCC ) ) - { - // fan is spinning, so stop it. - if ( pev->avelocity != g_vecZero ) - { - SetThink ( &CFuncRotating::SpinDown ); - //EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStop), - // m_flVolume, m_flAttenuation, 0, m_pitch); - - pev->nextthink = pev->ltime + 0.1; - } - else// fan is not moving, so start it - { - SetThink ( &CFuncRotating::SpinUp ); - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), - 0.01, m_flAttenuation, 0, FANPITCHMIN); - - pev->nextthink = pev->ltime + 0.1; - } - } - else if ( !FBitSet ( pev->spawnflags, SF_BRUSH_ACCDCC ) )//this is a normal start/stop brush. - { - if ( pev->avelocity != g_vecZero ) - { - // play stopping sound here - SetThink ( &CFuncRotating::SpinDown ); - - // EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, (char *)STRING(pev->noiseStop), - // m_flVolume, m_flAttenuation, 0, m_pitch); - - pev->nextthink = pev->ltime + 0.1; - // pev->avelocity = g_vecZero; - } - else - { - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseRunning), - m_flVolume, m_flAttenuation, 0, FANPITCHMAX); - pev->avelocity = pev->movedir * pev->speed; - - SetThink( &CFuncRotating::Rotate ); - Rotate(); - } - } -} - - -// -// RotatingBlocked - An entity has blocked the brush -// -void CFuncRotating :: Blocked( CBaseEntity *pOther ) - -{ - pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH); -} - - - - - - -//#endif - - -class CPendulum : public CBaseEntity -{ -public: - void Spawn ( void ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT Swing( void ); - void EXPORT PendulumUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT Stop( void ); - void Touch( CBaseEntity *pOther ); - void EXPORT RopeTouch ( CBaseEntity *pOther );// this touch func makes the pendulum a rope - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - void Blocked( CBaseEntity *pOther ); - - static TYPEDESCRIPTION m_SaveData[]; - - float m_accel; // Acceleration - float m_distance; // - float m_time; - float m_damp; - float m_maxSpeed; - float m_dampSpeed; - vec3_t m_center; - vec3_t m_start; -}; - -LINK_ENTITY_TO_CLASS( func_pendulum, CPendulum ); - -TYPEDESCRIPTION CPendulum::m_SaveData[] = -{ - DEFINE_FIELD( CPendulum, m_accel, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_distance, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_time, FIELD_TIME ), - DEFINE_FIELD( CPendulum, m_damp, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_maxSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_dampSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CPendulum, m_center, FIELD_VECTOR ), - DEFINE_FIELD( CPendulum, m_start, FIELD_VECTOR ), -}; - -IMPLEMENT_SAVERESTORE( CPendulum, CBaseEntity ); - - - -void CPendulum :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "distance")) - { - m_distance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "damp")) - { - m_damp = atof(pkvd->szValue) * 0.001; - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -void CPendulum :: Spawn( void ) -{ - // set the axis of rotation - CBaseToggle :: AxisDir( pev ); - - if ( FBitSet (pev->spawnflags, SF_DOOR_PASSABLE) ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - if ( m_distance == 0 ) - return; - - if (pev->speed == 0) - pev->speed = 100; - - m_accel = (pev->speed * pev->speed) / (2 * fabs(m_distance)); // Calculate constant acceleration from speed and distance - m_maxSpeed = pev->speed; - m_start = pev->angles; - m_center = pev->angles + (m_distance * 0.5) * pev->movedir; - - if ( FBitSet( pev->spawnflags, SF_BRUSH_ROTATE_INSTANT) ) - { - SetThink( &CPendulum::SUB_CallUseToggle ); - pev->nextthink = gpGlobals->time + 0.1; - } - pev->speed = 0; - SetUse( &CPendulum::PendulumUse ); - - if ( FBitSet( pev->spawnflags, SF_PENDULUM_SWING ) ) - { - SetTouch ( &CPendulum::RopeTouch ); - } -} - - -void CPendulum :: PendulumUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->speed ) // Pendulum is moving, stop it and auto-return if necessary - { - if ( FBitSet( pev->spawnflags, SF_PENDULUM_AUTO_RETURN ) ) - { - float delta; - - delta = CBaseToggle :: AxisDelta( pev->spawnflags, pev->angles, m_start ); - - pev->avelocity = m_maxSpeed * pev->movedir; - pev->nextthink = pev->ltime + (delta / m_maxSpeed); - SetThink( &CPendulum::Stop ); - } - else - { - pev->speed = 0; // Dead stop - SetThink( NULL ); - pev->avelocity = g_vecZero; - } - } - else - { - pev->nextthink = pev->ltime + 0.1; // Start the pendulum moving - m_time = gpGlobals->time; // Save time to calculate dt - SetThink( &CPendulum::Swing ); - m_dampSpeed = m_maxSpeed; - } -} - - -void CPendulum :: Stop( void ) -{ - pev->angles = m_start; - pev->speed = 0; - SetThink( NULL ); - pev->avelocity = g_vecZero; -} - - -void CPendulum::Blocked( CBaseEntity *pOther ) -{ - m_time = gpGlobals->time; -} - - -void CPendulum :: Swing( void ) -{ - float delta, dt; - - delta = CBaseToggle :: AxisDelta( pev->spawnflags, pev->angles, m_center ); - dt = gpGlobals->time - m_time; // How much time has passed? - m_time = gpGlobals->time; // Remember the last time called - - if ( delta > 0 && m_accel > 0 ) - pev->speed -= m_accel * dt; // Integrate velocity - else - pev->speed += m_accel * dt; - - if ( pev->speed > m_maxSpeed ) - pev->speed = m_maxSpeed; - else if ( pev->speed < -m_maxSpeed ) - pev->speed = -m_maxSpeed; - // scale the destdelta vector by the time spent traveling to get velocity - pev->avelocity = pev->speed * pev->movedir; - - // Call this again - pev->nextthink = pev->ltime + 0.1; - - if ( m_damp ) - { - m_dampSpeed -= m_damp * m_dampSpeed * dt; - if ( m_dampSpeed < 30.0 ) - { - pev->angles = m_center; - pev->speed = 0; - SetThink( NULL ); - pev->avelocity = g_vecZero; - } - else if ( pev->speed > m_dampSpeed ) - pev->speed = m_dampSpeed; - else if ( pev->speed < -m_dampSpeed ) - pev->speed = -m_dampSpeed; - - } -} - - -void CPendulum :: Touch ( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - if ( pev->dmg <= 0 ) - return; - - // we can't hurt this thing, so we're not concerned with it - if ( !pevOther->takedamage ) - return; - - // calculate damage based on rotation speed - float damage = pev->dmg * pev->speed * 0.01; - - if ( damage < 0 ) - damage = -damage; - - pOther->TakeDamage( pev, pev, damage, DMG_CRUSH ); - - pevOther->velocity = (pevOther->origin - VecBModelOrigin(pev) ).Normalize() * damage; -} - -void CPendulum :: RopeTouch ( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - if ( !pOther->IsPlayer() ) - {// not a player! - ALERT ( at_console, "Not a client\n" ); - return; - } - - if ( ENT(pevOther) == pev->enemy ) - {// this player already on the rope. - return; - } - - pev->enemy = pOther->edict(); - pevOther->velocity = g_vecZero; - pevOther->movetype = MOVETYPE_NONE; -} - - diff --git a/ricochet/dlls/buttons.cpp b/ricochet/dlls/buttons.cpp deleted file mode 100644 index eb5a3e9..0000000 --- a/ricochet/dlls/buttons.cpp +++ /dev/null @@ -1,1279 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== buttons.cpp ======================================================== - - button-related code - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "doors.h" - -#if !defined ( _WIN32 ) -#include // memset()))) -#endif - -#define SF_BUTTON_DONTMOVE 1 -#define SF_ROTBUTTON_NOTSOLID 1 -#define SF_BUTTON_TOGGLE 32 // button stays pushed until reactivated -#define SF_BUTTON_SPARK_IF_OFF 64 // button sparks in OFF state -#define SF_BUTTON_TOUCH_ONLY 256 // button only fires as a result of USE key. - -#define SF_GLOBAL_SET 1 // Set global state to initial state on spawn - -class CEnvGlobal : public CPointEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - string_t m_globalstate; - int m_triggermode; - int m_initialstate; -}; - -TYPEDESCRIPTION CEnvGlobal::m_SaveData[] = -{ - DEFINE_FIELD( CEnvGlobal, m_globalstate, FIELD_STRING ), - DEFINE_FIELD( CEnvGlobal, m_triggermode, FIELD_INTEGER ), - DEFINE_FIELD( CEnvGlobal, m_initialstate, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CEnvGlobal, CBaseEntity ); - -LINK_ENTITY_TO_CLASS( env_global, CEnvGlobal ); - -void CEnvGlobal::KeyValue( KeyValueData *pkvd ) -{ - pkvd->fHandled = TRUE; - - if ( FStrEq(pkvd->szKeyName, "globalstate") ) // State name - m_globalstate = ALLOC_STRING( pkvd->szValue ); - else if ( FStrEq(pkvd->szKeyName, "triggermode") ) - m_triggermode = atoi( pkvd->szValue ); - else if ( FStrEq(pkvd->szKeyName, "initialstate") ) - m_initialstate = atoi( pkvd->szValue ); - else - CPointEntity::KeyValue( pkvd ); -} - -void CEnvGlobal::Spawn( void ) -{ - if ( !m_globalstate ) - { - REMOVE_ENTITY( ENT(pev) ); - return; - } - if ( FBitSet( pev->spawnflags, SF_GLOBAL_SET ) ) - { - if ( !gGlobalState.EntityInTable( m_globalstate ) ) - gGlobalState.EntityAdd( m_globalstate, gpGlobals->mapname, (GLOBALESTATE)m_initialstate ); - } -} - - -void CEnvGlobal::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - GLOBALESTATE oldState = gGlobalState.EntityGetState( m_globalstate ); - GLOBALESTATE newState; - - switch( m_triggermode ) - { - case 0: - newState = GLOBAL_OFF; - break; - - case 1: - newState = GLOBAL_ON; - break; - - case 2: - newState = GLOBAL_DEAD; - break; - - default: - case 3: - if ( oldState == GLOBAL_ON ) - newState = GLOBAL_OFF; - else if ( oldState == GLOBAL_OFF ) - newState = GLOBAL_ON; - else - newState = oldState; - } - - if ( gGlobalState.EntityInTable( m_globalstate ) ) - gGlobalState.EntitySetState( m_globalstate, newState ); - else - gGlobalState.EntityAdd( m_globalstate, gpGlobals->mapname, newState ); -} - - - -TYPEDESCRIPTION CMultiSource::m_SaveData[] = -{ - //!!!BUGBUG FIX - DEFINE_ARRAY( CMultiSource, m_rgEntities, FIELD_EHANDLE, MS_MAX_TARGETS ), - DEFINE_ARRAY( CMultiSource, m_rgTriggered, FIELD_INTEGER, MS_MAX_TARGETS ), - DEFINE_FIELD( CMultiSource, m_iTotal, FIELD_INTEGER ), - DEFINE_FIELD( CMultiSource, m_globalstate, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CMultiSource, CBaseEntity ); - -LINK_ENTITY_TO_CLASS( multisource, CMultiSource ); -// -// Cache user-entity-field values until spawn is called. -// - -void CMultiSource::KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "style") || - FStrEq(pkvd->szKeyName, "height") || - FStrEq(pkvd->szKeyName, "killtarget") || - FStrEq(pkvd->szKeyName, "value1") || - FStrEq(pkvd->szKeyName, "value2") || - FStrEq(pkvd->szKeyName, "value3")) - pkvd->fHandled = TRUE; - else if ( FStrEq(pkvd->szKeyName, "globalstate") ) - { - m_globalstate = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -#define SF_MULTI_INIT 1 - -void CMultiSource::Spawn() -{ - // set up think for later registration - - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->nextthink = gpGlobals->time + 0.1; - pev->spawnflags |= SF_MULTI_INIT; // Until it's initialized - SetThink(&CMultiSource::Register); -} - -void CMultiSource::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int i = 0; - - // Find the entity in our list - while (i < m_iTotal) - if ( m_rgEntities[i++] == pCaller ) - break; - - // if we didn't find it, report error and leave - if (i > m_iTotal) - { - ALERT(at_console, "MultiSrc:Used by non member %s.\n", STRING(pCaller->pev->classname)); - return; - } - - // CONSIDER: a Use input to the multisource always toggles. Could check useType for ON/OFF/TOGGLE - - m_rgTriggered[i-1] ^= 1; - - // - if ( IsTriggered( pActivator ) ) - { - ALERT( at_aiconsole, "Multisource %s enabled (%d inputs)\n", STRING(pev->targetname), m_iTotal ); - USE_TYPE useType = USE_TOGGLE; - if ( m_globalstate ) - useType = USE_ON; - SUB_UseTargets( NULL, useType, 0 ); - } -} - - -BOOL CMultiSource::IsTriggered( CBaseEntity * ) -{ - // Is everything triggered? - int i = 0; - - // Still initializing? - if ( pev->spawnflags & SF_MULTI_INIT ) - return 0; - - while (i < m_iTotal) - { - if (m_rgTriggered[i] == 0) - break; - i++; - } - - if (i == m_iTotal) - { - if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON ) - return 1; - } - - return 0; -} - -void CMultiSource::Register(void) -{ - edict_t *pentTarget = NULL; - - m_iTotal = 0; - memset( m_rgEntities, 0, MS_MAX_TARGETS * sizeof(EHANDLE) ); - - SetThink(&CMultiSource::SUB_DoNothing); - - // search for all entities which target this multisource (pev->targetname) - - pentTarget = FIND_ENTITY_BY_STRING(NULL, "target", STRING(pev->targetname)); - - while (!FNullEnt(pentTarget) && (m_iTotal < MS_MAX_TARGETS)) - { - CBaseEntity *pTarget = CBaseEntity::Instance(pentTarget); - if ( pTarget ) - m_rgEntities[m_iTotal++] = pTarget; - - pentTarget = FIND_ENTITY_BY_STRING( pentTarget, "target", STRING(pev->targetname)); - } - - pentTarget = FIND_ENTITY_BY_STRING(NULL, "classname", "multi_manager"); - while (!FNullEnt(pentTarget) && (m_iTotal < MS_MAX_TARGETS)) - { - CBaseEntity *pTarget = CBaseEntity::Instance(pentTarget); - if ( pTarget && pTarget->HasTarget(pev->targetname) ) - m_rgEntities[m_iTotal++] = pTarget; - - pentTarget = FIND_ENTITY_BY_STRING( pentTarget, "classname", "multi_manager" ); - } - - pev->spawnflags &= ~SF_MULTI_INIT; -} - -// CBaseButton -TYPEDESCRIPTION CBaseButton::m_SaveData[] = -{ - DEFINE_FIELD( CBaseButton, m_fStayPushed, FIELD_BOOLEAN ), - DEFINE_FIELD( CBaseButton, m_fRotating, FIELD_BOOLEAN ), - - DEFINE_FIELD( CBaseButton, m_sounds, FIELD_INTEGER ), - DEFINE_FIELD( CBaseButton, m_bLockedSound, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseButton, m_bLockedSentence, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseButton, m_bUnlockedSound, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseButton, m_bUnlockedSentence, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseButton, m_strChangeTarget, FIELD_STRING ), -// DEFINE_FIELD( CBaseButton, m_ls, FIELD_??? ), // This is restored in Precache() -}; - - -IMPLEMENT_SAVERESTORE( CBaseButton, CBaseToggle ); - -void CBaseButton::Precache( void ) -{ - char *pszSound; - - if ( FBitSet ( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ) )// this button should spark in OFF state - { - PRECACHE_SOUND ("buttons/spark1.wav"); - PRECACHE_SOUND ("buttons/spark2.wav"); - PRECACHE_SOUND ("buttons/spark3.wav"); - PRECACHE_SOUND ("buttons/spark4.wav"); - PRECACHE_SOUND ("buttons/spark5.wav"); - PRECACHE_SOUND ("buttons/spark6.wav"); - } - - // get door button sounds, for doors which require buttons to open - - if (m_bLockedSound) - { - pszSound = ButtonSound( (int)m_bLockedSound ); - PRECACHE_SOUND(pszSound); - m_ls.sLockedSound = ALLOC_STRING(pszSound); - } - - if (m_bUnlockedSound) - { - pszSound = ButtonSound( (int)m_bUnlockedSound ); - PRECACHE_SOUND(pszSound); - m_ls.sUnlockedSound = ALLOC_STRING(pszSound); - } - - // get sentence group names, for doors which are directly 'touched' to open - - switch (m_bLockedSentence) - { - case 1: m_ls.sLockedSentence = MAKE_STRING("NA"); break; // access denied - case 2: m_ls.sLockedSentence = MAKE_STRING("ND"); break; // security lockout - case 3: m_ls.sLockedSentence = MAKE_STRING("NF"); break; // blast door - case 4: m_ls.sLockedSentence = MAKE_STRING("NFIRE"); break; // fire door - case 5: m_ls.sLockedSentence = MAKE_STRING("NCHEM"); break; // chemical door - case 6: m_ls.sLockedSentence = MAKE_STRING("NRAD"); break; // radiation door - case 7: m_ls.sLockedSentence = MAKE_STRING("NCON"); break; // gen containment - case 8: m_ls.sLockedSentence = MAKE_STRING("NH"); break; // maintenance door - case 9: m_ls.sLockedSentence = MAKE_STRING("NG"); break; // broken door - - default: m_ls.sLockedSentence = 0; break; - } - - switch (m_bUnlockedSentence) - { - case 1: m_ls.sUnlockedSentence = MAKE_STRING("EA"); break; // access granted - case 2: m_ls.sUnlockedSentence = MAKE_STRING("ED"); break; // security door - case 3: m_ls.sUnlockedSentence = MAKE_STRING("EF"); break; // blast door - case 4: m_ls.sUnlockedSentence = MAKE_STRING("EFIRE"); break; // fire door - case 5: m_ls.sUnlockedSentence = MAKE_STRING("ECHEM"); break; // chemical door - case 6: m_ls.sUnlockedSentence = MAKE_STRING("ERAD"); break; // radiation door - case 7: m_ls.sUnlockedSentence = MAKE_STRING("ECON"); break; // gen containment - case 8: m_ls.sUnlockedSentence = MAKE_STRING("EH"); break; // maintenance door - - default: m_ls.sUnlockedSentence = 0; break; - } -} - -// -// Cache user-entity-field values until spawn is called. -// - -void CBaseButton::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "changetarget")) - { - m_strChangeTarget = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "locked_sound")) - { - m_bLockedSound = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "locked_sentence")) - { - m_bLockedSentence = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "unlocked_sound")) - { - m_bUnlockedSound = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "unlocked_sentence")) - { - m_bUnlockedSentence = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -// -// ButtonShot -// -int CBaseButton::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - BUTTON_CODE code = ButtonResponseToTouch(); - - if ( code == BUTTON_NOTHING ) - return 0; - // Temporarily disable the touch function, until movement is finished. - SetTouch( NULL ); - - m_hActivator = CBaseEntity::Instance( pevAttacker ); - if ( m_hActivator == NULL ) - return 0; - - if ( code == BUTTON_RETURN ) - { - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - - // Toggle buttons fire when they get back to their "home" position - if ( !(pev->spawnflags & SF_BUTTON_TOGGLE) ) - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); - ButtonReturn(); - } - else // code == BUTTON_ACTIVATE - ButtonActivate( ); - - return 0; -} - -/*QUAKED func_button (0 .5 .8) ? -When a button is touched, it moves some distance in the direction of it's angle, -triggers all of it's targets, waits some time, then returns to it's original position -where it can be triggered again. - -"angle" determines the opening direction -"target" all entities with a matching targetname will be used -"speed" override the default 40 speed -"wait" override the default 1 second wait (-1 = never return) -"lip" override the default 4 pixel lip remaining at end of move -"health" if set, the button must be killed instead of touched -"sounds" -0) steam metal -1) wooden clunk -2) metallic click -3) in-out -*/ -LINK_ENTITY_TO_CLASS( func_button, CBaseButton ); - - -void CBaseButton::Spawn( ) -{ - char *pszSound; - - //---------------------------------------------------- - //determine sounds for buttons - //a sound of 0 should not make a sound - //---------------------------------------------------- - pszSound = ButtonSound( m_sounds ); - PRECACHE_SOUND(pszSound); - pev->noise = ALLOC_STRING(pszSound); - - Precache(); - - if ( FBitSet ( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ) )// this button should spark in OFF state - { - SetThink ( &CBaseButton::ButtonSpark ); - pev->nextthink = gpGlobals->time + 0.5;// no hurry, make sure everything else spawns - } - - SetMovedir(pev); - - pev->movetype = MOVETYPE_PUSH; - pev->solid = SOLID_BSP; - SET_MODEL(ENT(pev), STRING(pev->model)); - - if (pev->speed == 0) - pev->speed = 40; - - if (pev->health > 0) - { - pev->takedamage = DAMAGE_YES; - } - - if (m_flWait == 0) - m_flWait = 1; - if (m_flLip == 0) - m_flLip = 4; - - m_toggle_state = TS_AT_BOTTOM; - m_vecPosition1 = pev->origin; - // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big - m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs( pev->movedir.x * (pev->size.x-2) ) + fabs( pev->movedir.y * (pev->size.y-2) ) + fabs( pev->movedir.z * (pev->size.z-2) ) - m_flLip)); - - - // Is this a non-moving button? - if ( ((m_vecPosition2 - m_vecPosition1).Length() < 1) || (pev->spawnflags & SF_BUTTON_DONTMOVE) ) - m_vecPosition2 = m_vecPosition1; - - m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE); - m_fRotating = FALSE; - - // if the button is flagged for USE button activation only, take away it's touch function and add a use function - - if ( FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) ) // touchable button - { - SetTouch( &CBaseButton::ButtonTouch ); - } - else - { - SetTouch ( NULL ); - SetUse ( &CBaseButton::ButtonUse ); - } -} - - -// Button sound table. -// Also used by CBaseDoor to get 'touched' door lock/unlock sounds - -char *ButtonSound( int sound ) -{ - char *pszSound; - - switch ( sound ) - { - case 0: pszSound = "common/null.wav"; break; - case 1: pszSound = "buttons/button1.wav"; break; - case 2: pszSound = "buttons/button2.wav"; break; - case 3: pszSound = "buttons/button3.wav"; break; - case 4: pszSound = "buttons/button4.wav"; break; - case 5: pszSound = "buttons/button5.wav"; break; - case 6: pszSound = "buttons/button6.wav"; break; - case 7: pszSound = "buttons/button7.wav"; break; - case 8: pszSound = "buttons/button8.wav"; break; - case 9: pszSound = "buttons/button9.wav"; break; - case 10: pszSound = "buttons/button10.wav"; break; - case 11: pszSound = "buttons/button11.wav"; break; - case 12: pszSound = "buttons/latchlocked1.wav"; break; - case 13: pszSound = "buttons/latchunlocked1.wav"; break; - case 14: pszSound = "buttons/lightswitch2.wav";break; - -// next 6 slots reserved for any additional sliding button sounds we may add - - case 21: pszSound = "buttons/lever1.wav"; break; - case 22: pszSound = "buttons/lever2.wav"; break; - case 23: pszSound = "buttons/lever3.wav"; break; - case 24: pszSound = "buttons/lever4.wav"; break; - case 25: pszSound = "buttons/lever5.wav"; break; - - default:pszSound = "buttons/button9.wav"; break; - } - - return pszSound; -} - -// -// Makes flagged buttons spark when turned off -// - -void DoSpark(entvars_t *pev, const Vector &location ) -{ - Vector tmp = location + pev->size * 0.5; - UTIL_Sparks( tmp ); - - float flVolume = RANDOM_FLOAT ( 0.25 , 0.75 ) * 0.4;//random volume range - switch ( (int)(RANDOM_FLOAT(0,1) * 6) ) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark1.wav", flVolume, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark2.wav", flVolume, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark3.wav", flVolume, ATTN_NORM); break; - case 3: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark4.wav", flVolume, ATTN_NORM); break; - case 4: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM); break; - case 5: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM); break; - } -} - -void CBaseButton::ButtonSpark ( void ) -{ - SetThink ( &CBaseButton::ButtonSpark ); - pev->nextthink = gpGlobals->time + ( 0.1 + RANDOM_FLOAT ( 0, 1.5 ) );// spark again at random interval - - DoSpark( pev, pev->mins ); -} - - -// -// Button's Use function -// -void CBaseButton::ButtonUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // Ignore touches if button is moving, or pushed-in and waiting to auto-come-out. - // UNDONE: Should this use ButtonResponseToTouch() too? - if (m_toggle_state == TS_GOING_UP || m_toggle_state == TS_GOING_DOWN ) - return; - - m_hActivator = pActivator; - if ( m_toggle_state == TS_AT_TOP) - { - if (!m_fStayPushed && FBitSet(pev->spawnflags, SF_BUTTON_TOGGLE)) - { - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - - //SUB_UseTargets( m_eoActivator ); - ButtonReturn(); - } - } - else - ButtonActivate( ); -} - - -CBaseButton::BUTTON_CODE CBaseButton::ButtonResponseToTouch( void ) -{ - // Ignore touches if button is moving, or pushed-in and waiting to auto-come-out. - if (m_toggle_state == TS_GOING_UP || - m_toggle_state == TS_GOING_DOWN || - (m_toggle_state == TS_AT_TOP && !m_fStayPushed && !FBitSet(pev->spawnflags, SF_BUTTON_TOGGLE) ) ) - return BUTTON_NOTHING; - - if (m_toggle_state == TS_AT_TOP) - { - if((FBitSet(pev->spawnflags, SF_BUTTON_TOGGLE) ) && !m_fStayPushed) - { - return BUTTON_RETURN; - } - } - else - return BUTTON_ACTIVATE; - - return BUTTON_NOTHING; -} - - -// -// Touching a button simply "activates" it. -// -void CBaseButton:: ButtonTouch( CBaseEntity *pOther ) -{ - // Ignore touches by anything but players - if (!FClassnameIs(pOther->pev, "player")) - return; - - m_hActivator = pOther; - - BUTTON_CODE code = ButtonResponseToTouch(); - - if ( code == BUTTON_NOTHING ) - return; - - if (!UTIL_IsMasterTriggered(m_sMaster, pOther)) - { - // play button locked sound - PlayLockSounds(pev, &m_ls, TRUE, TRUE); - return; - } - - // Temporarily disable the touch function, until movement is finished. - SetTouch( NULL ); - - if ( code == BUTTON_RETURN ) - { - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); - ButtonReturn(); - } - else // code == BUTTON_ACTIVATE - ButtonActivate( ); -} - -// -// Starts the button moving "in/up". -// -void CBaseButton::ButtonActivate( ) -{ - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - - if (!UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) - { - // button is locked, play locked sound - PlayLockSounds(pev, &m_ls, TRUE, TRUE); - return; - } - else - { - // button is unlocked, play unlocked sound - PlayLockSounds(pev, &m_ls, FALSE, TRUE); - } - - ASSERT(m_toggle_state == TS_AT_BOTTOM); - m_toggle_state = TS_GOING_UP; - - SetMoveDone( &CBaseButton::TriggerAndWait ); - if (!m_fRotating) - LinearMove( m_vecPosition2, pev->speed); - else - AngularMove( m_vecAngle2, pev->speed); -} - -// -// Button has reached the "in/up" position. Activate its "targets", and pause before "popping out". -// -void CBaseButton::TriggerAndWait( void ) -{ - ASSERT(m_toggle_state == TS_GOING_UP); - - if (!UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) - return; - - m_toggle_state = TS_AT_TOP; - - // If button automatically comes back out, start it moving out. - // Else re-instate touch method - if (m_fStayPushed || FBitSet ( pev->spawnflags, SF_BUTTON_TOGGLE ) ) - { - if ( !FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) ) // this button only works if USED, not touched! - { - // ALL buttons are now use only - SetTouch ( NULL ); - } - else - SetTouch( &CBaseButton::ButtonTouch ); - } - else - { - pev->nextthink = pev->ltime + m_flWait; - SetThink( &CBaseButton::ButtonReturn ); - } - - pev->frame = 1; // use alternate textures - - - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); -} - - -// -// Starts the button moving "out/down". -// -void CBaseButton::ButtonReturn( void ) -{ - ASSERT(m_toggle_state == TS_AT_TOP); - m_toggle_state = TS_GOING_DOWN; - - SetMoveDone( &CBaseButton::ButtonBackHome ); - if (!m_fRotating) - LinearMove( m_vecPosition1, pev->speed); - else - AngularMove( m_vecAngle1, pev->speed); - - pev->frame = 0; // use normal textures -} - - -// -// Button has returned to start state. Quiesce it. -// -void CBaseButton::ButtonBackHome( void ) -{ - ASSERT(m_toggle_state == TS_GOING_DOWN); - m_toggle_state = TS_AT_BOTTOM; - - if ( FBitSet(pev->spawnflags, SF_BUTTON_TOGGLE) ) - { - //EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); - } - - - if (!FStringNull(pev->target)) - { - edict_t* pentTarget = NULL; - for (;;) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target)); - - if (FNullEnt(pentTarget)) - break; - - if (!FClassnameIs(pentTarget, "multisource")) - continue; - CBaseEntity *pTarget = CBaseEntity::Instance( pentTarget ); - - if ( pTarget ) - pTarget->Use( m_hActivator, this, USE_TOGGLE, 0 ); - } - } - -// Re-instate touch method, movement cycle is complete. - if ( !FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) ) // this button only works if USED, not touched! - { - // All buttons are now use only - SetTouch ( NULL ); - } - else - SetTouch( &CBaseButton::ButtonTouch ); - -// reset think for a sparking button - if ( FBitSet ( pev->spawnflags, SF_BUTTON_SPARK_IF_OFF ) ) - { - SetThink ( &CBaseButton::ButtonSpark ); - pev->nextthink = gpGlobals->time + 0.5;// no hurry. - } -} - - - -// -// Rotating button (aka "lever") -// -class CRotButton : public CBaseButton -{ -public: - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( func_rot_button, CRotButton ); - -void CRotButton::Spawn( void ) -{ - char *pszSound; - //---------------------------------------------------- - //determine sounds for buttons - //a sound of 0 should not make a sound - //---------------------------------------------------- - pszSound = ButtonSound( m_sounds ); - PRECACHE_SOUND(pszSound); - pev->noise = ALLOC_STRING(pszSound); - - // set the axis of rotation - CBaseToggle::AxisDir( pev ); - - // check for clockwise rotation - if ( FBitSet (pev->spawnflags, SF_DOOR_ROTATE_BACKWARDS) ) - pev->movedir = pev->movedir * -1; - - pev->movetype = MOVETYPE_PUSH; - - if ( pev->spawnflags & SF_ROTBUTTON_NOTSOLID ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - - SET_MODEL(ENT(pev), STRING(pev->model)); - - if (pev->speed == 0) - pev->speed = 40; - - if (m_flWait == 0) - m_flWait = 1; - - if (pev->health > 0) - { - pev->takedamage = DAMAGE_YES; - } - - m_toggle_state = TS_AT_BOTTOM; - m_vecAngle1 = pev->angles; - m_vecAngle2 = pev->angles + pev->movedir * m_flMoveDistance; - ASSERTSZ(m_vecAngle1 != m_vecAngle2, "rotating button start/end positions are equal"); - - m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE); - m_fRotating = TRUE; - - // if the button is flagged for USE button activation only, take away it's touch function and add a use function - if ( !FBitSet ( pev->spawnflags, SF_BUTTON_TOUCH_ONLY ) ) - { - SetTouch ( NULL ); - SetUse ( &CRotButton::ButtonUse ); - } - else // touchable button - SetTouch( &CRotButton::ButtonTouch ); - - //SetTouch( ButtonTouch ); -} - - -// Make this button behave like a door (HACKHACK) -// This will disable use and make the button solid -// rotating buttons were made SOLID_NOT by default since their were some -// collision problems with them... -#define SF_MOMENTARY_DOOR 0x0001 - -class CMomentaryRotButton : public CBaseToggle -{ -public: - void Spawn ( void ); - void KeyValue( KeyValueData *pkvd ); - virtual int ObjectCaps( void ) - { - int flags = CBaseToggle :: ObjectCaps() & (~FCAP_ACROSS_TRANSITION); - if ( pev->spawnflags & SF_MOMENTARY_DOOR ) - return flags; - return flags | FCAP_CONTINUOUS_USE; - } - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT Off( void ); - void EXPORT Return( void ); - void UpdateSelf( float value ); - void UpdateSelfReturn( float value ); - void UpdateAllButtons( float value, int start ); - - void PlaySound( void ); - void UpdateTarget( float value ); - - static CMomentaryRotButton *Instance( edict_t *pent ) { return (CMomentaryRotButton *)GET_PRIVATE(pent);}; - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - int m_lastUsed; - int m_direction; - float m_returnSpeed; - vec3_t m_start; - vec3_t m_end; - int m_sounds; -}; -TYPEDESCRIPTION CMomentaryRotButton::m_SaveData[] = -{ - DEFINE_FIELD( CMomentaryRotButton, m_lastUsed, FIELD_INTEGER ), - DEFINE_FIELD( CMomentaryRotButton, m_direction, FIELD_INTEGER ), - DEFINE_FIELD( CMomentaryRotButton, m_returnSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CMomentaryRotButton, m_start, FIELD_VECTOR ), - DEFINE_FIELD( CMomentaryRotButton, m_end, FIELD_VECTOR ), - DEFINE_FIELD( CMomentaryRotButton, m_sounds, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CMomentaryRotButton, CBaseToggle ); - -LINK_ENTITY_TO_CLASS( momentary_rot_button, CMomentaryRotButton ); - -void CMomentaryRotButton::Spawn( void ) -{ - CBaseToggle::AxisDir( pev ); - - if ( pev->speed == 0 ) - pev->speed = 100; - - if ( m_flMoveDistance < 0 ) - { - m_start = pev->angles + pev->movedir * m_flMoveDistance; - m_end = pev->angles; - m_direction = 1; // This will toggle to -1 on the first use() - m_flMoveDistance = -m_flMoveDistance; - } - else - { - m_start = pev->angles; - m_end = pev->angles + pev->movedir * m_flMoveDistance; - m_direction = -1; // This will toggle to +1 on the first use() - } - - if ( pev->spawnflags & SF_MOMENTARY_DOOR ) - pev->solid = SOLID_BSP; - else - pev->solid = SOLID_NOT; - - pev->movetype = MOVETYPE_PUSH; - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - char *pszSound = ButtonSound( m_sounds ); - PRECACHE_SOUND(pszSound); - pev->noise = ALLOC_STRING(pszSound); - m_lastUsed = 0; -} - -void CMomentaryRotButton::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "returnspeed")) - { - m_returnSpeed = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -void CMomentaryRotButton::PlaySound( void ) -{ - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); -} - -// BUGBUG: This design causes a latentcy. When the button is retriggered, the first impulse -// will send the target in the wrong direction because the parameter is calculated based on the -// current, not future position. -void CMomentaryRotButton::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - pev->ideal_yaw = CBaseToggle::AxisDelta( pev->spawnflags, pev->angles, m_start ) / m_flMoveDistance; - - UpdateAllButtons( pev->ideal_yaw, 1 ); - UpdateTarget( pev->ideal_yaw ); -} - -void CMomentaryRotButton::UpdateAllButtons( float value, int start ) -{ - // Update all rot buttons attached to the same target - edict_t *pentTarget = NULL; - for (;;) - { - - pentTarget = FIND_ENTITY_BY_STRING(pentTarget, "target", STRING(pev->target)); - if (FNullEnt(pentTarget)) - break; - - if ( FClassnameIs( VARS(pentTarget), "momentary_rot_button" ) ) - { - CMomentaryRotButton *pEntity = CMomentaryRotButton::Instance(pentTarget); - if ( pEntity ) - { - if ( start ) - pEntity->UpdateSelf( value ); - else - pEntity->UpdateSelfReturn( value ); - } - } - } -} - -void CMomentaryRotButton::UpdateSelf( float value ) -{ - BOOL fplaysound = FALSE; - - if ( !m_lastUsed ) - { - fplaysound = TRUE; - m_direction = -m_direction; - } - m_lastUsed = 1; - - pev->nextthink = pev->ltime + 0.1; - if ( m_direction > 0 && value >= 1.0 ) - { - pev->avelocity = g_vecZero; - pev->angles = m_end; - return; - } - else if ( m_direction < 0 && value <= 0 ) - { - pev->avelocity = g_vecZero; - pev->angles = m_start; - return; - } - - if (fplaysound) - PlaySound(); - - // HACKHACK -- If we're going slow, we'll get multiple player packets per frame, bump nexthink on each one to avoid stalling - if ( pev->nextthink < pev->ltime ) - pev->nextthink = pev->ltime + 0.1; - else - pev->nextthink += 0.1; - - pev->avelocity = (m_direction * pev->speed) * pev->movedir; - SetThink( &CMomentaryRotButton::Off ); -} - -void CMomentaryRotButton::UpdateTarget( float value ) -{ - if (!FStringNull(pev->target)) - { - edict_t* pentTarget = NULL; - for (;;) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target)); - if (FNullEnt(pentTarget)) - break; - CBaseEntity *pEntity = CBaseEntity::Instance(pentTarget); - if ( pEntity ) - { - pEntity->Use( this, this, USE_SET, value ); - } - } - } -} - -void CMomentaryRotButton::Off( void ) -{ - pev->avelocity = g_vecZero; - m_lastUsed = 0; - if ( FBitSet( pev->spawnflags, SF_PENDULUM_AUTO_RETURN ) && m_returnSpeed > 0 ) - { - SetThink( &CMomentaryRotButton::Return ); - pev->nextthink = pev->ltime + 0.1; - m_direction = -1; - } - else - SetThink( NULL ); -} - -void CMomentaryRotButton::Return( void ) -{ - float value = CBaseToggle::AxisDelta( pev->spawnflags, pev->angles, m_start ) / m_flMoveDistance; - - UpdateAllButtons( value, 0 ); // This will end up calling UpdateSelfReturn() n times, but it still works right - if ( value > 0 ) - UpdateTarget( value ); -} - - -void CMomentaryRotButton::UpdateSelfReturn( float value ) -{ - if ( value <= 0 ) - { - pev->avelocity = g_vecZero; - pev->angles = m_start; - pev->nextthink = -1; - SetThink( NULL ); - } - else - { - pev->avelocity = -m_returnSpeed * pev->movedir; - pev->nextthink = pev->ltime + 0.1; - } -} - - -//---------------------------------------------------------------- -// Spark -//---------------------------------------------------------------- - -class CEnvSpark : public CBaseEntity -{ -public: - void Spawn(void); - void Precache(void); - void EXPORT SparkThink(void); - void EXPORT SparkStart(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT SparkStop(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue(KeyValueData *pkvd); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - float m_flDelay; -}; - - -TYPEDESCRIPTION CEnvSpark::m_SaveData[] = -{ - DEFINE_FIELD( CEnvSpark, m_flDelay, FIELD_FLOAT), -}; - -IMPLEMENT_SAVERESTORE( CEnvSpark, CBaseEntity ); - -LINK_ENTITY_TO_CLASS(env_spark, CEnvSpark); -LINK_ENTITY_TO_CLASS(env_debris, CEnvSpark); - -void CEnvSpark::Spawn(void) -{ - SetThink( NULL ); - SetUse( NULL ); - - if (FBitSet(pev->spawnflags, 32)) // Use for on/off - { - if (FBitSet(pev->spawnflags, 64)) // Start on - { - SetThink(&CEnvSpark::SparkThink); // start sparking - SetUse(&CEnvSpark::SparkStop); // set up +USE to stop sparking - } - else - SetUse(&CEnvSpark::SparkStart); - } - else - SetThink(&CEnvSpark::SparkThink); - - pev->nextthink = gpGlobals->time + ( 0.1 + RANDOM_FLOAT ( 0, 1.5 ) ); - - if (m_flDelay <= 0) - m_flDelay = 1.5; - - Precache( ); -} - - -void CEnvSpark::Precache(void) -{ - PRECACHE_SOUND( "buttons/spark1.wav" ); - PRECACHE_SOUND( "buttons/spark2.wav" ); - PRECACHE_SOUND( "buttons/spark3.wav" ); - PRECACHE_SOUND( "buttons/spark4.wav" ); - PRECACHE_SOUND( "buttons/spark5.wav" ); - PRECACHE_SOUND( "buttons/spark6.wav" ); -} - -void CEnvSpark::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "MaxDelay")) - { - m_flDelay = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "style") || - FStrEq(pkvd->szKeyName, "height") || - FStrEq(pkvd->szKeyName, "killtarget") || - FStrEq(pkvd->szKeyName, "value1") || - FStrEq(pkvd->szKeyName, "value2") || - FStrEq(pkvd->szKeyName, "value3")) - pkvd->fHandled = TRUE; - else - CBaseEntity::KeyValue( pkvd ); -} - -void EXPORT CEnvSpark::SparkThink(void) -{ - pev->nextthink = gpGlobals->time + 0.1 + RANDOM_FLOAT (0, m_flDelay); - DoSpark( pev, pev->origin ); -} - -void EXPORT CEnvSpark::SparkStart(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetUse(&CEnvSpark::SparkStop); - SetThink(&CEnvSpark::SparkThink); - pev->nextthink = gpGlobals->time + (0.1 + RANDOM_FLOAT ( 0, m_flDelay)); -} - -void EXPORT CEnvSpark::SparkStop(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetUse(&CEnvSpark::SparkStart); - SetThink(NULL); -} - -#define SF_BTARGET_USE 0x0001 -#define SF_BTARGET_ON 0x0002 - -class CButtonTarget : public CBaseEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - int ObjectCaps( void ); - -}; - -LINK_ENTITY_TO_CLASS( button_target, CButtonTarget ); - -void CButtonTarget::Spawn( void ) -{ - pev->movetype = MOVETYPE_PUSH; - pev->solid = SOLID_BSP; - SET_MODEL(ENT(pev), STRING(pev->model)); - pev->takedamage = DAMAGE_YES; - - if ( FBitSet( pev->spawnflags, SF_BTARGET_ON ) ) - pev->frame = 1; -} - -void CButtonTarget::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, (int)pev->frame ) ) - return; - pev->frame = 1-pev->frame; - if ( pev->frame ) - SUB_UseTargets( pActivator, USE_ON, 0 ); - else - SUB_UseTargets( pActivator, USE_OFF, 0 ); -} - - -int CButtonTarget :: ObjectCaps( void ) -{ - int caps = CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; - - if ( FBitSet(pev->spawnflags, SF_BTARGET_USE) ) - return caps | FCAP_IMPULSE_USE; - else - return caps; -} - - -int CButtonTarget::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - Use( Instance(pevAttacker), this, USE_TOGGLE, 0 ); - - return 1; -} diff --git a/ricochet/dlls/cbase.cpp b/ricochet/dlls/cbase.cpp deleted file mode 100644 index 71c0327..0000000 --- a/ricochet/dlls/cbase.cpp +++ /dev/null @@ -1,796 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "client.h" -#include "decals.h" -#include "gamerules.h" -#include "game.h" - -void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd ); - -void PM_Move ( struct playermove_s *ppmove, int server ); -void PM_Init ( struct playermove_s *ppmove ); -char PM_FindTextureType( char *name ); - -void OnFreeEntPrivateData(edict_s *pEdict); - - -extern Vector VecBModelOrigin( entvars_t* pevBModel ); -extern DLL_GLOBAL Vector g_vecAttackDir; -extern DLL_GLOBAL int g_iSkillLevel; - -static DLL_FUNCTIONS gFunctionTable = -{ - GameDLLInit, //pfnGameInit - DispatchSpawn, //pfnSpawn - DispatchThink, //pfnThink - DispatchUse, //pfnUse - DispatchTouch, //pfnTouch - DispatchBlocked, //pfnBlocked - DispatchKeyValue, //pfnKeyValue - DispatchSave, //pfnSave - DispatchRestore, //pfnRestore - DispatchObjectCollsionBox, //pfnAbsBox - - SaveWriteFields, //pfnSaveWriteFields - SaveReadFields, //pfnSaveReadFields - - SaveGlobalState, //pfnSaveGlobalState - RestoreGlobalState, //pfnRestoreGlobalState - ResetGlobalState, //pfnResetGlobalState - - ClientConnect, //pfnClientConnect - ClientDisconnect, //pfnClientDisconnect - ClientKill, //pfnClientKill - ClientPutInServer, //pfnClientPutInServer - ClientCommand, //pfnClientCommand - ClientUserInfoChanged, //pfnClientUserInfoChanged - ServerActivate, //pfnServerActivate - ServerDeactivate, //pfnServerDeactivate - - PlayerPreThink, //pfnPlayerPreThink - PlayerPostThink, //pfnPlayerPostThink - - StartFrame, //pfnStartFrame - ParmsNewLevel, //pfnParmsNewLevel - ParmsChangeLevel, //pfnParmsChangeLevel - - GetGameDescription, //pfnGetGameDescription Returns string describing current .dll game. - PlayerCustomization, //pfnPlayerCustomization Notifies .dll of new customization for player. - - SpectatorConnect, //pfnSpectatorConnect Called when spectator joins server - SpectatorDisconnect, //pfnSpectatorDisconnect Called when spectator leaves the server - SpectatorThink, //pfnSpectatorThink Called when spectator sends a command packet (usercmd_t) - - Sys_Error, //pfnSys_Error Called when engine has encountered an error - - PM_Move, //pfnPM_Move - PM_Init, //pfnPM_Init Server version of player movement initialization - PM_FindTextureType, //pfnPM_FindTextureType - - SetupVisibility, //pfnSetupVisibility Set up PVS and PAS for networking for this client - UpdateClientData, //pfnUpdateClientData Set up data sent only to specific client - AddToFullPack, //pfnAddToFullPack - CreateBaseline, //pfnCreateBaseline Tweak entity baseline for network encoding, allows setup of player baselines, too. - RegisterEncoders, //pfnRegisterEncoders Callbacks for network encoding - GetWeaponData, //pfnGetWeaponData - CmdStart, //pfnCmdStart - CmdEnd, //pfnCmdEnd - ConnectionlessPacket, //pfnConnectionlessPacket - GetHullBounds, //pfnGetHullBounds - CreateInstancedBaselines, //pfnCreateInstancedBaselines - InconsistentFile, //pfnInconsistentFile - AllowLagCompensation, //pfnAllowLagCompensation -}; - -NEW_DLL_FUNCTIONS gNewDLLFunctions = -{ - OnFreeEntPrivateData, //pfnOnFreeEntPrivateData - GameDLLShutdown, //pfnGameShutdown - ShouldCollide, //pfnShouldCollide -}; - - -static void SetObjectCollisionBox( entvars_t *pev ); - -int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ) -{ - if ( !pFunctionTable || interfaceVersion != INTERFACE_VERSION ) - { - return FALSE; - } - - memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) ); - return TRUE; -} - -int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ) -{ - if ( !pFunctionTable || *interfaceVersion != INTERFACE_VERSION ) - { - // Tell engine what version we had, so it can figure out who is out of date. - *interfaceVersion = INTERFACE_VERSION; - return FALSE; - } - - memcpy( pFunctionTable, &gFunctionTable, sizeof( DLL_FUNCTIONS ) ); - return TRUE; -} - -int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion) -{ - if(!pFunctionTable || *interfaceVersion != NEW_DLL_FUNCTIONS_VERSION) - { - *interfaceVersion = NEW_DLL_FUNCTIONS_VERSION; - return FALSE; - } - - memcpy(pFunctionTable, &gNewDLLFunctions, sizeof(gNewDLLFunctions)); - return TRUE; -} - -int DispatchSpawn( edict_t *pent ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - - if (pEntity) - { - // Initialize these or entities who don't link to the world won't have anything in here - pEntity->pev->absmin = pEntity->pev->origin - Vector(1,1,1); - pEntity->pev->absmax = pEntity->pev->origin + Vector(1,1,1); - - pEntity->Spawn(); - - // Try to get the pointer again, in case the spawn function deleted the entity. - // UNDONE: Spawn() should really return a code to ask that the entity be deleted, but - // that would touch too much code for me to do that right now. - pEntity = (CBaseEntity *)GET_PRIVATE(pent); - - if ( pEntity ) - { - if ( g_pGameRules && !g_pGameRules->IsAllowedToSpawn( pEntity ) ) - return -1; // return that this entity should be deleted - if ( pEntity->pev->flags & FL_KILLME ) - return -1; - } - - - // Handle global stuff here - if ( pEntity && pEntity->pev->globalname ) - { - const globalentity_t *pGlobal = gGlobalState.EntityFromTable( pEntity->pev->globalname ); - if ( pGlobal ) - { - // Already dead? delete - if ( pGlobal->state == GLOBAL_DEAD ) - return -1; - else if ( !FStrEq( STRING(gpGlobals->mapname), pGlobal->levelName ) ) - pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive - // In this level & not dead, continue on as normal - } - else - { - // Spawned entities default to 'On' - gGlobalState.EntityAdd( pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON ); -// ALERT( at_console, "Added global entity %s (%s)\n", STRING(pEntity->pev->classname), STRING(pEntity->pev->globalname) ); - } - } - - } - - return 0; -} - -void DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd ) -{ - if ( !pkvd || !pentKeyvalue ) - return; - - EntvarsKeyvalue( VARS(pentKeyvalue), pkvd ); - - // If the key was an entity variable, or there's no class set yet, don't look for the object, it may - // not exist yet. - if ( pkvd->fHandled || pkvd->szClassName == NULL ) - return; - - // Get the actualy entity object - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentKeyvalue); - - if ( !pEntity ) - return; - - pEntity->KeyValue( pkvd ); -} - - -// HACKHACK -- this is a hack to keep the node graph entity from "touching" things (like triggers) -// while it builds the graph -BOOL gTouchDisabled = FALSE; -void DispatchTouch( edict_t *pentTouched, edict_t *pentOther ) -{ - if ( gTouchDisabled ) - return; - - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentTouched); - CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE( pentOther ); - - if ( pEntity && pOther && ! ((pEntity->pev->flags | pOther->pev->flags) & FL_KILLME) ) - pEntity->Touch( pOther ); -} - - -void DispatchUse( edict_t *pentUsed, edict_t *pentOther ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pentUsed); - CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE(pentOther); - - if (pEntity && !(pEntity->pev->flags & FL_KILLME) ) - pEntity->Use( pOther, pOther, USE_TOGGLE, 0 ); -} - -void DispatchThink( edict_t *pent ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - if (pEntity) - { - if ( FBitSet( pEntity->pev->flags, FL_DORMANT ) ) - ALERT( at_error, "Dormant entity %s is thinking!!\n", STRING(pEntity->pev->classname) ); - - pEntity->Think(); - } -} - -void DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE( pentBlocked ); - CBaseEntity *pOther = (CBaseEntity *)GET_PRIVATE( pentOther ); - - if (pEntity) - pEntity->Blocked( pOther ); -} - -void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - - if ( pEntity && pSaveData ) - { - ENTITYTABLE *pTable = &pSaveData->pTable[ pSaveData->currentIndex ]; - - if ( pTable->pent != pent ) - ALERT( at_error, "ENTITY TABLE OR INDEX IS WRONG!!!!\n" ); - - if ( pEntity->ObjectCaps() & FCAP_DONT_SAVE ) - return; - - // These don't use ltime & nextthink as times really, but we'll fudge around it. - if ( pEntity->pev->movetype == MOVETYPE_PUSH ) - { - float delta = pEntity->pev->nextthink - pEntity->pev->ltime; - pEntity->pev->ltime = gpGlobals->time; - pEntity->pev->nextthink = pEntity->pev->ltime + delta; - } - - pTable->location = pSaveData->size; // Remember entity position for file I/O - pTable->classname = pEntity->pev->classname; // Remember entity class for respawn - - CSave saveHelper( pSaveData ); - pEntity->Save( saveHelper ); - - pTable->size = pSaveData->size - pTable->location; // Size of entity block is data size written to block - } -} - -void OnFreeEntPrivateData(edict_s *pEdict) -{ - if(pEdict && pEdict->pvPrivateData) - { - ((CBaseEntity*)pEdict->pvPrivateData)->~CBaseEntity(); - } -} - -// Find the matching global entity. Spit out an error if the designer made entities of -// different classes with the same global name -CBaseEntity *FindGlobalEntity( string_t classname, string_t globalname ) -{ - edict_t *pent = FIND_ENTITY_BY_STRING( NULL, "globalname", STRING(globalname) ); - CBaseEntity *pReturn = CBaseEntity::Instance( pent ); - if ( pReturn ) - { - if ( !FClassnameIs( pReturn->pev, STRING(classname) ) ) - { - ALERT( at_console, "Global entity found %s, wrong class %s\n", STRING(globalname), STRING(pReturn->pev->classname) ); - pReturn = NULL; - } - } - - return pReturn; -} - - -int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - - if ( pEntity && pSaveData ) - { - entvars_t tmpVars; - Vector oldOffset; - - CRestore restoreHelper( pSaveData ); - if ( globalEntity ) - { - CRestore tmpRestore( pSaveData ); - tmpRestore.PrecacheMode( 0 ); - tmpRestore.ReadEntVars( "ENTVARS", &tmpVars ); - - // HACKHACK - reset the save pointers, we're going to restore for real this time - pSaveData->size = pSaveData->pTable[pSaveData->currentIndex].location; - pSaveData->pCurrentData = pSaveData->pBaseData + pSaveData->size; - // ------------------- - - - const globalentity_t *pGlobal = gGlobalState.EntityFromTable( tmpVars.globalname ); - - // Don't overlay any instance of the global that isn't the latest - // pSaveData->szCurrentMapName is the level this entity is coming from - // pGlobla->levelName is the last level the global entity was active in. - // If they aren't the same, then this global update is out of date. - if ( !FStrEq( pSaveData->szCurrentMapName, pGlobal->levelName ) ) - return 0; - - // Compute the new global offset - oldOffset = pSaveData->vecLandmarkOffset; - CBaseEntity *pNewEntity = FindGlobalEntity( tmpVars.classname, tmpVars.globalname ); - if ( pNewEntity ) - { -// ALERT( at_console, "Overlay %s with %s\n", STRING(pNewEntity->pev->classname), STRING(tmpVars.classname) ); - // Tell the restore code we're overlaying a global entity from another level - restoreHelper.SetGlobalMode( 1 ); // Don't overwrite global fields - pSaveData->vecLandmarkOffset = (pSaveData->vecLandmarkOffset - pNewEntity->pev->mins) + tmpVars.mins; - pEntity = pNewEntity;// we're going to restore this data OVER the old entity - pent = ENT( pEntity->pev ); - // Update the global table to say that the global definition of this entity should come from this level - gGlobalState.EntityUpdate( pEntity->pev->globalname, gpGlobals->mapname ); - } - else - { - // This entity will be freed automatically by the engine. If we don't do a restore on a matching entity (below) - // or call EntityUpdate() to move it to this level, we haven't changed global state at all. - return 0; - } - - } - - if ( pEntity->ObjectCaps() & FCAP_MUST_SPAWN ) - { - pEntity->Restore( restoreHelper ); - pEntity->Spawn(); - } - else - { - pEntity->Restore( restoreHelper ); - pEntity->Precache( ); - } - - // Again, could be deleted, get the pointer again. - pEntity = (CBaseEntity *)GET_PRIVATE(pent); - -#if 0 - if ( pEntity && pEntity->pev->globalname && globalEntity ) - { - ALERT( at_console, "Global %s is %s\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->model) ); - } -#endif - - // Is this an overriding global entity (coming over the transition), or one restoring in a level - if ( globalEntity ) - { -// ALERT( at_console, "After: %f %f %f %s\n", pEntity->pev->origin.x, pEntity->pev->origin.y, pEntity->pev->origin.z, STRING(pEntity->pev->model) ); - pSaveData->vecLandmarkOffset = oldOffset; - if ( pEntity ) - { - UTIL_SetOrigin( pEntity->pev, pEntity->pev->origin ); - pEntity->OverrideReset(); - } - } - else if ( pEntity && pEntity->pev->globalname ) - { - const globalentity_t *pGlobal = gGlobalState.EntityFromTable( pEntity->pev->globalname ); - if ( pGlobal ) - { - // Already dead? delete - if ( pGlobal->state == GLOBAL_DEAD ) - return -1; - else if ( !FStrEq( STRING(gpGlobals->mapname), pGlobal->levelName ) ) - { - pEntity->MakeDormant(); // Hasn't been moved to this level yet, wait but stay alive - } - // In this level & not dead, continue on as normal - } - else - { - ALERT( at_error, "Global Entity %s (%s) not in table!!!\n", STRING(pEntity->pev->globalname), STRING(pEntity->pev->classname) ); - // Spawned entities default to 'On' - gGlobalState.EntityAdd( pEntity->pev->globalname, gpGlobals->mapname, GLOBAL_ON ); - } - } - } - return 0; -} - - -void DispatchObjectCollsionBox( edict_t *pent ) -{ - CBaseEntity *pEntity = (CBaseEntity *)GET_PRIVATE(pent); - if (pEntity) - { - pEntity->SetObjectCollisionBox(); - } - else - SetObjectCollisionBox( &pent->v ); -} - - -void SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ) -{ - CSave saveHelper( pSaveData ); - saveHelper.WriteFields( pname, pBaseData, pFields, fieldCount ); -} - - -void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ) -{ - CRestore restoreHelper( pSaveData ); - restoreHelper.ReadFields( pname, pBaseData, pFields, fieldCount ); -} - - -edict_t * EHANDLE::Get( void ) -{ - if (m_pent) - { - if (m_pent->serialnumber == m_serialnumber) - return m_pent; - else - return NULL; - } - return NULL; -}; - -edict_t * EHANDLE::Set( edict_t *pent ) -{ - m_pent = pent; - if (pent) - m_serialnumber = m_pent->serialnumber; - return pent; -}; - - -EHANDLE :: operator CBaseEntity *() -{ - return (CBaseEntity *)GET_PRIVATE( Get( ) ); -}; - - -CBaseEntity * EHANDLE :: operator = (CBaseEntity *pEntity) -{ - if (pEntity) - { - m_pent = ENT( pEntity->pev ); - if (m_pent) - m_serialnumber = m_pent->serialnumber; - } - else - { - m_pent = NULL; - m_serialnumber = 0; - } - return pEntity; -} - -EHANDLE :: operator int () -{ - return Get() != NULL; -} - -CBaseEntity * EHANDLE :: operator -> () -{ - return (CBaseEntity *)GET_PRIVATE( Get( ) ); -} - - -// give health -int CBaseEntity :: TakeHealth( float flHealth, int bitsDamageType ) -{ - if (!pev->takedamage) - return 0; - -// heal - if ( pev->health >= pev->max_health ) - return 0; - - pev->health += flHealth; - - if (pev->health > pev->max_health) - pev->health = pev->max_health; - - return 1; -} - -// inflict damage on this entity. bitsDamageType indicates type of damage inflicted, ie: DMG_CRUSH - -int CBaseEntity :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - Vector vecTemp; - - if (!pev->takedamage) - return 0; - - // UNDONE: some entity types may be immune or resistant to some bitsDamageType - - // if Attacker == Inflictor, the attack was a melee or other instant-hit attack. - // (that is, no actual entity projectile was involved in the attack so use the shooter's origin). - if ( pevAttacker == pevInflictor ) - { - vecTemp = pevInflictor->origin - ( VecBModelOrigin(pev) ); - } - else - // an actual missile was involved. - { - vecTemp = pevInflictor->origin - ( VecBModelOrigin(pev) ); - } - -// this global is still used for glass and other non-monster killables, along with decals. - g_vecAttackDir = vecTemp.Normalize(); - -// save damage based on the target's armor level - -// figure momentum add (don't let hurt brushes or other triggers move player) - if ((!FNullEnt(pevInflictor)) && (pev->movetype == MOVETYPE_WALK || pev->movetype == MOVETYPE_STEP) && (pevAttacker->solid != SOLID_TRIGGER) ) - { - Vector vecDir = pev->origin - (pevInflictor->absmin + pevInflictor->absmax) * 0.5; - vecDir = vecDir.Normalize(); - - float flForce = flDamage * ((32 * 32 * 72.0) / (pev->size.x * pev->size.y * pev->size.z)) * 5; - - if (flForce > 1000.0) - flForce = 1000.0; - pev->velocity = pev->velocity + vecDir * flForce; - } - -// do the damage - pev->health -= flDamage; - if (pev->health <= 0) - { - Killed( pevAttacker, GIB_NORMAL ); - return 0; - } - - return 1; -} - - -void CBaseEntity :: Killed( entvars_t *pevAttacker, int iGib ) -{ - pev->takedamage = DAMAGE_NO; - pev->deadflag = DEAD_DEAD; - UTIL_Remove( this ); -} - - -CBaseEntity *CBaseEntity::GetNextTarget( void ) -{ - if ( FStringNull( pev->target ) ) - return NULL; - edict_t *pTarget = FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(pev->target) ); - if ( FNullEnt(pTarget) ) - return NULL; - - return Instance( pTarget ); -} - -// Global Savedata for Delay -TYPEDESCRIPTION CBaseEntity::m_SaveData[] = -{ - DEFINE_FIELD( CBaseEntity, m_pGoalEnt, FIELD_CLASSPTR ), - - DEFINE_FIELD( CBaseEntity, m_pfnThink, FIELD_FUNCTION ), // UNDONE: Build table of these!!! - DEFINE_FIELD( CBaseEntity, m_pfnTouch, FIELD_FUNCTION ), - DEFINE_FIELD( CBaseEntity, m_pfnUse, FIELD_FUNCTION ), - DEFINE_FIELD( CBaseEntity, m_pfnBlocked, FIELD_FUNCTION ), -}; - - -int CBaseEntity::Save( CSave &save ) -{ - if ( save.WriteEntVars( "ENTVARS", pev ) ) - return save.WriteFields( "BASE", this, m_SaveData, ARRAYSIZE(m_SaveData) ); - - return 0; -} - -int CBaseEntity::Restore( CRestore &restore ) -{ - int status; - - status = restore.ReadEntVars( "ENTVARS", pev ); - if ( status ) - status = restore.ReadFields( "BASE", this, m_SaveData, ARRAYSIZE(m_SaveData) ); - - if ( pev->modelindex != 0 && !FStringNull(pev->model) ) - { - Vector mins, maxs; - mins = pev->mins; // Set model is about to destroy these - maxs = pev->maxs; - - - PRECACHE_MODEL( (char *)STRING(pev->model) ); - SET_MODEL(ENT(pev), STRING(pev->model)); - UTIL_SetSize(pev, mins, maxs); // Reset them - } - - return status; -} - - -// Initialize absmin & absmax to the appropriate box -void SetObjectCollisionBox( entvars_t *pev ) -{ - if ( (pev->solid == SOLID_BSP) && - (pev->angles.x || pev->angles.y|| pev->angles.z) ) - { // expand for rotation - float max, v; - int i; - - max = 0; - for (i=0 ; i<3 ; i++) - { - v = fabs( pev->mins[i]); - if (v > max) - max = v; - v = fabs( pev->maxs[i]); - if (v > max) - max = v; - } - for (i=0 ; i<3 ; i++) - { - pev->absmin[i] = pev->origin[i] - max; - pev->absmax[i] = pev->origin[i] + max; - } - } - else - { - pev->absmin = pev->origin + pev->mins; - pev->absmax = pev->origin + pev->maxs; - } - - pev->absmin.x -= 1; - pev->absmin.y -= 1; - pev->absmin.z -= 1; - pev->absmax.x += 1; - pev->absmax.y += 1; - pev->absmax.z += 1; -} - - -void CBaseEntity::SetObjectCollisionBox( void ) -{ - ::SetObjectCollisionBox( pev ); -} - - -int CBaseEntity :: Intersects( CBaseEntity *pOther ) -{ - if ( pOther->pev->absmin.x > pev->absmax.x || - pOther->pev->absmin.y > pev->absmax.y || - pOther->pev->absmin.z > pev->absmax.z || - pOther->pev->absmax.x < pev->absmin.x || - pOther->pev->absmax.y < pev->absmin.y || - pOther->pev->absmax.z < pev->absmin.z ) - return 0; - return 1; -} - -void CBaseEntity :: MakeDormant( void ) -{ - SetBits( pev->flags, FL_DORMANT ); - - // Don't touch - pev->solid = SOLID_NOT; - // Don't move - pev->movetype = MOVETYPE_NONE; - // Don't draw - SetBits( pev->effects, EF_NODRAW ); - // Don't think - pev->nextthink = 0; - // Relink - UTIL_SetOrigin( pev, pev->origin ); -} - -int CBaseEntity :: IsDormant( void ) -{ - return FBitSet( pev->flags, FL_DORMANT ); -} - -BOOL CBaseEntity :: IsInWorld( void ) -{ - // position - if (pev->origin.x >= 4096) return FALSE; - if (pev->origin.y >= 4096) return FALSE; - if (pev->origin.z >= 4096) return FALSE; - if (pev->origin.x <= -4096) return FALSE; - if (pev->origin.y <= -4096) return FALSE; - if (pev->origin.z <= -4096) return FALSE; - // speed - if (pev->velocity.x >= 2000) return FALSE; - if (pev->velocity.y >= 2000) return FALSE; - if (pev->velocity.z >= 2000) return FALSE; - if (pev->velocity.x <= -2000) return FALSE; - if (pev->velocity.y <= -2000) return FALSE; - if (pev->velocity.z <= -2000) return FALSE; - - return TRUE; -} - -int CBaseEntity::ShouldToggle( USE_TYPE useType, BOOL currentState ) -{ - if ( useType != USE_TOGGLE && useType != USE_SET ) - { - if ( (currentState && useType == USE_ON) || (!currentState && useType == USE_OFF) ) - return 0; - } - return 1; -} - - -int CBaseEntity :: DamageDecal( int bitsDamageType ) -{ - if ( pev->rendermode == kRenderTransAlpha ) - return -1; - - if ( pev->rendermode != kRenderNormal ) - return DECAL_BPROOF1; - - return DECAL_GUNSHOT1 + RANDOM_LONG(0,4); -} - - - -// NOTE: szName must be a pointer to constant memory, e.g. "monster_class" because the entity -// will keep a pointer to it after this call. -CBaseEntity * CBaseEntity::Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner ) -{ - edict_t *pent; - CBaseEntity *pEntity; - - pent = CREATE_NAMED_ENTITY( MAKE_STRING( szName )); - if ( FNullEnt( pent ) ) - { - ALERT ( at_console, "NULL Ent in Create!\n" ); - return NULL; - } - pEntity = Instance( pent ); - pEntity->pev->owner = pentOwner; - pEntity->pev->origin = vecOrigin; - pEntity->pev->angles = vecAngles; - DispatchSpawn( pEntity->edict() ); - return pEntity; -} - - diff --git a/ricochet/dlls/cbase.h b/ricochet/dlls/cbase.h deleted file mode 100644 index fac8197..0000000 --- a/ricochet/dlls/cbase.h +++ /dev/null @@ -1,797 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -Class Hierachy - -CBaseEntity - CBaseDelay - CBaseToggle - CBaseItem - CBaseMonster - CBaseCycler - CBasePlayer - CBaseGroup -*/ - -#define MAX_PATH_SIZE 10 // max number of nodes available for a path. - -// These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions) -#define FCAP_CUSTOMSAVE 0x00000001 -#define FCAP_ACROSS_TRANSITION 0x00000002 // should transfer between transitions -#define FCAP_MUST_SPAWN 0x00000004 // Spawn after restore -#define FCAP_DONT_SAVE 0x80000000 // Don't save this -#define FCAP_IMPULSE_USE 0x00000008 // can be used by the player -#define FCAP_CONTINUOUS_USE 0x00000010 // can be used by the player -#define FCAP_ONOFF_USE 0x00000020 // can be used by the player -#define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains) -#define FCAP_MASTER 0x00000080 // Can be used to "master" other entities (like multisource) - -// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!! -#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions - -#include "archtypes.h" // DAL -#include "saverestore.h" -#include "schedule.h" - -#ifndef MONSTEREVENT_H -#include "monsterevent.h" -#endif - -#include "Platform.h" - -// C functions for external declarations that call the appropriate C++ methods - -#define EXPORT DLLEXPORT - -extern "C" DLLEXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); -extern "C" DLLEXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); -extern "C" DLLEXPORT int GetNewDLLFunctions( NEW_DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); - -extern int DispatchSpawn( edict_t *pent ); -extern void DispatchKeyValue( edict_t *pentKeyvalue, KeyValueData *pkvd ); -extern void DispatchTouch( edict_t *pentTouched, edict_t *pentOther ); -extern void DispatchUse( edict_t *pentUsed, edict_t *pentOther ); -extern void DispatchThink( edict_t *pent ); -extern void DispatchBlocked( edict_t *pentBlocked, edict_t *pentOther ); -extern void DispatchSave( edict_t *pent, SAVERESTOREDATA *pSaveData ); -extern int DispatchRestore( edict_t *pent, SAVERESTOREDATA *pSaveData, int globalEntity ); -extern void DispatchObjectCollsionBox( edict_t *pent ); -extern void SaveWriteFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); -extern void SaveReadFields( SAVERESTOREDATA *pSaveData, const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); -extern void SaveGlobalState( SAVERESTOREDATA *pSaveData ); -extern void RestoreGlobalState( SAVERESTOREDATA *pSaveData ); -extern void ResetGlobalState( void ); - -typedef enum { USE_OFF = 0, USE_ON = 1, USE_SET = 2, USE_TOGGLE = 3 } USE_TYPE; - -extern void FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -typedef void (CBaseEntity::*BASEPTR)(void); -typedef void (CBaseEntity::*ENTITYFUNCPTR)(CBaseEntity *pOther ); -typedef void (CBaseEntity::*USEPTR)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -// For CLASSIFY -#define CLASS_NONE 0 -#define CLASS_MACHINE 1 -#define CLASS_PLAYER 2 -#define CLASS_HUMAN_PASSIVE 3 -#define CLASS_HUMAN_MILITARY 4 -#define CLASS_ALIEN_MILITARY 5 -#define CLASS_ALIEN_PASSIVE 6 -#define CLASS_ALIEN_MONSTER 7 -#define CLASS_ALIEN_PREY 8 -#define CLASS_ALIEN_PREDATOR 9 -#define CLASS_INSECT 10 -#define CLASS_PLAYER_ALLY 11 -#define CLASS_PLAYER_BIOWEAPON 12 // hornets and snarks.launched by players -#define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks.launched by the alien menace -#define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures. - -class CBaseEntity; -class CBaseMonster; -class CBasePlayerItem; -class CSquadMonster; - - -#define SF_NORESPAWN ( 1 << 30 )// !!!set this bit on guns and stuff that should never respawn. - -// -// EHANDLE. Safe way to point to CBaseEntities who may die between frames -// -class EHANDLE -{ -private: - edict_t *m_pent; - int m_serialnumber; -public: - edict_t *Get( void ); - edict_t *Set( edict_t *pent ); - - operator int (); - - operator CBaseEntity *(); - - CBaseEntity * operator = (CBaseEntity *pEntity); - CBaseEntity * operator ->(); -}; - - -// -// Base Entity. All entity types derive from this -// -class CBaseEntity -{ -public: - // Constructor. Set engine to use C/C++ callback functions - // pointers to engine data - entvars_t *pev; // Don't need to save/restore this pointer, the engine resets it - - // path corners - CBaseEntity *m_pGoalEnt;// path corner we are heading towards - CBaseEntity *m_pLink;// used for temporary link-list operations. - - // initialization functions - virtual void Spawn( void ) { return; } - virtual void Precache( void ) { return; } - virtual void KeyValue( KeyValueData* pkvd) { pkvd->fHandled = FALSE; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - virtual int ObjectCaps( void ) { return FCAP_ACROSS_TRANSITION; } - virtual void Activate( void ) {} - - // Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box) - virtual void SetObjectCollisionBox( void ); - -// Classify - returns the type of group (i.e, "houndeye", or "human military" so that monsters with different classnames -// still realize that they are teammates. (overridden for monsters that form groups) - virtual int Classify ( void ) { return CLASS_NONE; }; - virtual void DeathNotice ( entvars_t *pevChild ) {}// monster maker children use this to tell the monster maker that they have died. - - - static TYPEDESCRIPTION m_SaveData[]; - - virtual void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - virtual int TakeHealth( float flHealth, int bitsDamageType ); - virtual void Killed( entvars_t *pevAttacker, int iGib ); - virtual int BloodColor( void ) { return DONT_BLEED; } - virtual void TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); - virtual BOOL IsTriggered( CBaseEntity *pActivator ) {return TRUE;} - virtual CBaseMonster *MyMonsterPointer( void ) { return NULL;} - virtual CSquadMonster *MySquadMonsterPointer( void ) { return NULL;} - virtual int GetToggleState( void ) { return TS_AT_TOP; } - virtual void AddPoints( int score, BOOL bAllowNegativeScore ) {} - virtual void AddPointsToTeam( int score, BOOL bAllowNegativeScore ) {} - virtual BOOL AddPlayerItem( CBasePlayerItem *pItem ) { return 0; } - virtual BOOL RemovePlayerItem( CBasePlayerItem *pItem ) { return 0; } - virtual int GiveAmmo( int iAmount, char *szName, int iMax ) { return -1; }; - virtual float GetDelay( void ) { return 0; } - virtual int IsMoving( void ) { return pev->velocity != g_vecZero; } - virtual void OverrideReset( void ) {} - virtual int DamageDecal( int bitsDamageType ); - // This is ONLY used by the node graph to test movement through a door - virtual void SetToggleState( int state ) {} - virtual void StartSneaking( void ) {} - virtual void StopSneaking( void ) {} - virtual BOOL OnControls( entvars_t *pev ) { return FALSE; } - virtual BOOL IsSneaking( void ) { return FALSE; } - virtual BOOL IsAlive( void ) { return (pev->deadflag == DEAD_NO) && pev->health > 0; } - virtual BOOL IsBSPModel( void ) { return pev->solid == SOLID_BSP || pev->movetype == MOVETYPE_PUSHSTEP; } - virtual BOOL ReflectGauss( void ) { return ( IsBSPModel() && !pev->takedamage ); } - virtual BOOL HasTarget( string_t targetname ) { return FStrEq(STRING(targetname), STRING(pev->targetname) ); } - virtual BOOL IsInWorld( void ); - virtual BOOL IsPlayer( void ) { return FALSE; } - virtual BOOL IsNetClient( void ) { return FALSE; } - virtual const char *TeamID( void ) { return ""; } - - virtual BOOL IsDisc( void ) { return FALSE; }; - -// virtual void SetActivator( CBaseEntity *pActivator ) {} - virtual CBaseEntity *GetNextTarget( void ); - - // fundamental callbacks - void (CBaseEntity ::*m_pfnThink)(void); - void (CBaseEntity ::*m_pfnTouch)( CBaseEntity *pOther ); - void (CBaseEntity ::*m_pfnUse)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void (CBaseEntity ::*m_pfnBlocked)( CBaseEntity *pOther ); - - virtual void Think( void ) { if (m_pfnThink) (this->*m_pfnThink)(); }; - virtual void Touch( CBaseEntity *pOther ) { if (m_pfnTouch) (this->*m_pfnTouch)( pOther ); }; - virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) - { - if (m_pfnUse) - (this->*m_pfnUse)( pActivator, pCaller, useType, value ); - } - virtual void Blocked( CBaseEntity *pOther ) { if (m_pfnBlocked) (this->*m_pfnBlocked)( pOther ); }; - - // allow engine to allocate instance data - void *operator new( size_t stAllocateBlock, entvars_t *pev ) - { - return (void *)ALLOC_PRIVATE(ENT(pev), stAllocateBlock); - }; - - // don't use this. -#if _MSC_VER >= 1200 // only build this code if MSVC++ 6.0 or higher - void operator delete(void *pMem, entvars_t *pev) - { - pev->flags |= FL_KILLME; - }; -#endif - - void UpdateOnRemove( void ); - - // common member functions - void EXPORT SUB_Remove( void ); - void EXPORT SUB_DoNothing( void ); - void EXPORT SUB_StartFadeOut ( void ); - void EXPORT SUB_FadeOut ( void ); - void EXPORT SUB_CallUseToggle( void ) { this->Use( this, this, USE_TOGGLE, 0 ); } - int ShouldToggle( USE_TYPE useType, BOOL currentState ); - void FireBullets( ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t *pevAttacker = NULL ); - - virtual CBaseEntity *Respawn( void ) { return NULL; } - - void SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ); - // Do the bounding boxes of these two intersect? - int Intersects( CBaseEntity *pOther ); - void MakeDormant( void ); - int IsDormant( void ); - BOOL IsLockedByMaster( void ) { return FALSE; } - -#ifdef _DEBUG - static CBaseEntity *Instance( edict_t *pent ) - { - if ( !pent ) - pent = ENT(0); - CBaseEntity *pEnt = (CBaseEntity *)GET_PRIVATE(pent); - ASSERT(pEnt!=NULL); - return pEnt; - } -#else - static CBaseEntity *Instance( edict_t *pent ) - { - if ( !pent ) - pent = ENT(0); - CBaseEntity *pEnt = (CBaseEntity *)GET_PRIVATE(pent); - return pEnt; - } -#endif - - static CBaseEntity *Instance( entvars_t *pev ) { return Instance( ENT( pev ) ); } - static CBaseEntity *Instance( int eoffset) { return Instance( ENT( eoffset) ); } - - CBaseMonster *GetMonsterPointer( entvars_t *pevMonster ) - { - CBaseEntity *pEntity = Instance( pevMonster ); - if ( pEntity ) - return pEntity->MyMonsterPointer(); - return NULL; - } - CBaseMonster *GetMonsterPointer( edict_t *pentMonster ) - { - CBaseEntity *pEntity = Instance( pentMonster ); - if ( pEntity ) - return pEntity->MyMonsterPointer(); - return NULL; - } - - - // Ugly code to lookup all functions to make sure they are exported when set. -#ifdef _DEBUG - void FunctionCheck( void *pFunction, char *name ) - { -#ifdef _WIN32 - if (pFunction && !NAME_FOR_FUNCTION((uint32)pFunction) ) - ALERT( at_error, "No EXPORT: %s:%s (%08lx)\n", STRING(pev->classname), name, pFunction ); -#endif // _WIN32 - } - - BASEPTR ThinkSet( BASEPTR func, char *name ) - { - m_pfnThink = func; - FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnThink)))), name ); - return func; - } - ENTITYFUNCPTR TouchSet( ENTITYFUNCPTR func, char *name ) - { - m_pfnTouch = func; - FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnTouch)))), name ); - return func; - } - USEPTR UseSet( USEPTR func, char *name ) - { - m_pfnUse = func; - FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnUse)))), name ); - return func; - } - ENTITYFUNCPTR BlockedSet( ENTITYFUNCPTR func, char *name ) - { - m_pfnBlocked = func; - FunctionCheck( (void *)*((int *)((char *)this + ( offsetof(CBaseEntity,m_pfnBlocked)))), name ); - return func; - } - -#endif - - - // virtual functions used by a few classes - - // used by monsters that are created by the MonsterMaker - virtual void UpdateOwner( void ) { return; }; - - - // - static CBaseEntity *Create( char *szName, const Vector &vecOrigin, const Vector &vecAngles, edict_t *pentOwner = NULL ); - - virtual BOOL FBecomeProne( void ) {return FALSE;}; - edict_t *edict() { return ENT( pev ); }; - EOFFSET eoffset( ) { return OFFSET( pev ); }; - int entindex( ) { return ENTINDEX( edict() ); }; - - virtual Vector Center( ) { return (pev->absmax + pev->absmin) * 0.5; }; // center point of entity - virtual Vector EyePosition( ) { return pev->origin + pev->view_ofs; }; // position of eyes - virtual Vector EarPosition( ) { return pev->origin + pev->view_ofs; }; // position of ears - virtual Vector BodyTarget( const Vector &posSrc ) { return Center( ); }; // position to shoot at - - virtual int Illumination( ) { return GETENTITYILLUM( ENT( pev ) ); }; - - virtual BOOL FVisible ( CBaseEntity *pEntity ); - virtual BOOL FVisible ( const Vector &vecOrigin ); - - // Last touched by Jump pad - float m_flTouchedByJumpPad; -}; - - - -// Ugly technique to override base member functions -// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a -// member function of a base class. static_cast is a sleezy way around that problem. - -#ifdef _DEBUG - -#define SetThink( a ) ThinkSet( static_cast (a), #a ) -#define SetTouch( a ) TouchSet( static_cast (a), #a ) -#define SetUse( a ) UseSet( static_cast (a), #a ) -#define SetBlocked( a ) BlockedSet( static_cast (a), #a ) - -#else - -#define SetThink( a ) m_pfnThink = static_cast (a) -#define SetTouch( a ) m_pfnTouch = static_cast (a) -#define SetUse( a ) m_pfnUse = static_cast (a) -#define SetBlocked( a ) m_pfnBlocked = static_cast (a) - -#endif - - -class CPointEntity : public CBaseEntity -{ -public: - void Spawn( void ); - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } -private: -}; - - -typedef struct locksounds // sounds that doors and buttons make when locked/unlocked -{ - string_t sLockedSound; // sound a door makes when it's locked - string_t sLockedSentence; // sentence group played when door is locked - string_t sUnlockedSound; // sound a door makes when it's unlocked - string_t sUnlockedSentence; // sentence group played when door is unlocked - - int iLockedSentence; // which sentence in sentence group to play next - int iUnlockedSentence; // which sentence in sentence group to play next - - float flwaitSound; // time delay between playing consecutive 'locked/unlocked' sounds - float flwaitSentence; // time delay between playing consecutive sentences - BYTE bEOFLocked; // true if hit end of list of locked sentences - BYTE bEOFUnlocked; // true if hit end of list of unlocked sentences -} locksound_t; - -void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton); - -// -// MultiSouce -// - -#define MAX_MULTI_TARGETS 16 // maximum number of targets a single multi_manager entity may be assigned. -#define MS_MAX_TARGETS 32 - -class CMultiSource : public CPointEntity -{ -public: - void Spawn( ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - int ObjectCaps( void ) { return (CPointEntity::ObjectCaps() | FCAP_MASTER); } - BOOL IsTriggered( CBaseEntity *pActivator ); - void EXPORT Register( void ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - EHANDLE m_rgEntities[MS_MAX_TARGETS]; - int m_rgTriggered[MS_MAX_TARGETS]; - - int m_iTotal; - string_t m_globalstate; -}; - - -// -// generic Delay entity. -// -class CBaseDelay : public CBaseEntity -{ -public: - float m_flDelay; - int m_iszKillTarget; - - virtual void KeyValue( KeyValueData* pkvd); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - // common member functions - void SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ); - void EXPORT DelayThink( void ); -}; - - -class CBaseAnimating : public CBaseDelay -{ -public: - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - // Basic Monster Animation functions - float StudioFrameAdvance( float flInterval = 0.0 ); // accumulate animation frame time from last time called until now - int GetSequenceFlags( void ); - int LookupActivity ( int activity ); - int LookupActivityHeaviest ( int activity ); - int LookupSequence ( const char *label ); - void ResetSequenceInfo ( ); - void DispatchAnimEvents ( float flFutureInterval = 0.1 ); // Handle events that have happend since last time called up until X seconds into the future - virtual void HandleAnimEvent( MonsterEvent_t *pEvent ) { return; }; - float SetBoneController ( int iController, float flValue ); - void InitBoneControllers ( void ); - float SetBlending ( int iBlender, float flValue ); - void GetBonePosition ( int iBone, Vector &origin, Vector &angles ); - void GetAutomovement( Vector &origin, Vector &angles, float flInterval = 0.1 ); - int FindTransition( int iEndingSequence, int iGoalSequence, int *piDir ); - void GetAttachment ( int iAttachment, Vector &origin, Vector &angles ); - void SetBodygroup( int iGroup, int iValue ); - int GetBodygroup( int iGroup ); - int ExtractBbox( int sequence, float *mins, float *maxs ); - void SetSequenceBox( void ); - - // animation needs - float m_flFrameRate; // computed FPS for current sequence - float m_flGroundSpeed; // computed linear movement rate for current sequence - float m_flLastEventCheck; // last time the event list was checked - BOOL m_fSequenceFinished;// flag set when StudioAdvanceFrame moves across a frame boundry - BOOL m_fSequenceLoops; // true if the sequence loops -}; - - -// -// generic Toggle entity. -// -#define SF_ITEM_USE_ONLY 256 // ITEM_USE_ONLY = BUTTON_USE_ONLY = DOOR_USE_ONLY!!! - -class CBaseToggle : public CBaseAnimating -{ -public: - void KeyValue( KeyValueData *pkvd ); - - TOGGLE_STATE m_toggle_state; - float m_flActivateFinished;//like attack_finished, but for doors - float m_flMoveDistance;// how far a door should slide or rotate - float m_flWait; - float m_flLip; - float m_flTWidth;// for plats - float m_flTLength;// for plats - - Vector m_vecPosition1; - Vector m_vecPosition2; - Vector m_vecAngle1; - Vector m_vecAngle2; - - int m_cTriggersLeft; // trigger_counter only, # of activations remaining - float m_flHeight; - EHANDLE m_hActivator; - void (CBaseToggle::*m_pfnCallWhenMoveDone)(void); - Vector m_vecFinalDest; - Vector m_vecFinalAngle; - - int m_bitsDamageInflict; // DMG_ damage type that the door or tigger does - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - virtual int GetToggleState( void ) { return m_toggle_state; } - virtual float GetDelay( void ) { return m_flWait; } - - // common member functions - void LinearMove( Vector vecDest, float flSpeed ); - void EXPORT LinearMoveDone( void ); - void AngularMove( Vector vecDestAngle, float flSpeed ); - void EXPORT AngularMoveDone( void ); - BOOL IsLockedByMaster( void ); - - static float AxisValue( int flags, const Vector &angles ); - static void AxisDir( entvars_t *pev ); - static float AxisDelta( int flags, const Vector &angle1, const Vector &angle2 ); - - string_t m_sMaster; // If this button has a master switch, this is the targetname. - // A master switch must be of the multisource type. If all - // of the switches in the multisource have been triggered, then - // the button will be allowed to operate. Otherwise, it will be - // deactivated. -}; -#define SetMoveDone( a ) m_pfnCallWhenMoveDone = static_cast (a) - - -// people gib if their health is <= this at the time of death -#define GIB_HEALTH_VALUE -30 - -#define ROUTE_SIZE 8 // how many waypoints a monster can store at one time -#define MAX_OLD_ENEMIES 4 // how many old enemies to remember - -#define bits_CAP_DUCK ( 1 << 0 )// crouch -#define bits_CAP_JUMP ( 1 << 1 )// jump/leap -#define bits_CAP_STRAFE ( 1 << 2 )// strafe ( walk/run sideways) -#define bits_CAP_SQUAD ( 1 << 3 )// can form squads -#define bits_CAP_SWIM ( 1 << 4 )// proficiently navigate in water -#define bits_CAP_CLIMB ( 1 << 5 )// climb ladders/ropes -#define bits_CAP_USE ( 1 << 6 )// open doors/push buttons/pull levers -#define bits_CAP_HEAR ( 1 << 7 )// can hear forced sounds -#define bits_CAP_AUTO_DOORS ( 1 << 8 )// can trigger auto doors -#define bits_CAP_OPEN_DOORS ( 1 << 9 )// can open manual doors -#define bits_CAP_TURN_HEAD ( 1 << 10)// can turn head, always bone controller 0 - -#define bits_CAP_RANGE_ATTACK1 ( 1 << 11)// can do a range attack 1 -#define bits_CAP_RANGE_ATTACK2 ( 1 << 12)// can do a range attack 2 -#define bits_CAP_MELEE_ATTACK1 ( 1 << 13)// can do a melee attack 1 -#define bits_CAP_MELEE_ATTACK2 ( 1 << 14)// can do a melee attack 2 - -#define bits_CAP_FLY ( 1 << 15)// can fly, move all around - -#define bits_CAP_DOORS_GROUP (bits_CAP_USE | bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS) - -// used by suit voice to indicate damage sustained and repaired type to player - -// instant damage - -#define DMG_GENERIC 0 // generic damage was done -#define DMG_CRUSH (1 << 0) // crushed by falling or moving object -#define DMG_BULLET (1 << 1) // shot -#define DMG_SLASH (1 << 2) // cut, clawed, stabbed -#define DMG_BURN (1 << 3) // heat burned -#define DMG_FREEZE (1 << 4) // frozen -#define DMG_FALL (1 << 5) // fell too far -#define DMG_BLAST (1 << 6) // explosive blast damage -#define DMG_CLUB (1 << 7) // crowbar, punch, headbutt -#define DMG_SHOCK (1 << 8) // electric shock -#define DMG_SONIC (1 << 9) // sound pulse shockwave -#define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam -#define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death -#define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death. -#define DMG_DROWN (1 << 14) // Drowning -// time-based damage -#define DMG_TIMEBASED (~(0x3fff)) // mask for time-based damage - -#define DMG_PARALYZE (1 << 15) // slows affected creature down -#define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad -#define DMG_POISON (1 << 17) // blood poisioning -#define DMG_RADIATION (1 << 18) // radiation exposure -#define DMG_DROWNRECOVER (1 << 19) // drowning recovery -#define DMG_ACID (1 << 20) // toxic chemicals or acid burns -#define DMG_SLOWBURN (1 << 21) // in an oven -#define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer -#define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar) - -// these are the damage types that are allowed to gib corpses -#define DMG_GIB_CORPSE ( DMG_CRUSH | DMG_FALL | DMG_BLAST | DMG_SONIC | DMG_CLUB ) - -// these are the damage types that have client hud art -#define DMG_SHOWNHUD (DMG_POISON | DMG_ACID | DMG_FREEZE | DMG_SLOWFREEZE | DMG_DROWN | DMG_BURN | DMG_SLOWBURN | DMG_NERVEGAS | DMG_RADIATION | DMG_SHOCK) - -// NOTE: tweak these values based on gameplay feedback: - -#define PARALYZE_DURATION 2 // number of 2 second intervals to take damage -#define PARALYZE_DAMAGE 1.0 // damage to take each 2 second interval - -#define NERVEGAS_DURATION 2 -#define NERVEGAS_DAMAGE 5.0 - -#define POISON_DURATION 5 -#define POISON_DAMAGE 2.0 - -#define RADIATION_DURATION 2 -#define RADIATION_DAMAGE 1.0 - -#define ACID_DURATION 2 -#define ACID_DAMAGE 5.0 - -#define SLOWBURN_DURATION 2 -#define SLOWBURN_DAMAGE 1.0 - -#define SLOWFREEZE_DURATION 2 -#define SLOWFREEZE_DAMAGE 1.0 - - -#define itbd_Paralyze 0 -#define itbd_NerveGas 1 -#define itbd_Poison 2 -#define itbd_Radiation 3 -#define itbd_DrownRecover 4 -#define itbd_Acid 5 -#define itbd_SlowBurn 6 -#define itbd_SlowFreeze 7 -#define CDMG_TIMEBASED 8 - -// when calling KILLED(), a value that governs gib behavior is expected to be -// one of these three values -#define GIB_NORMAL 0// gib if entity was overkilled -#define GIB_NEVER 1// never gib, no matter how much death damage is done ( freezing, etc ) -#define GIB_ALWAYS 2// always gib ( Houndeye Shock, Barnacle Bite ) - -class CBaseMonster; -class CCineMonster; -class CSound; - -#include "basemonster.h" - - -char *ButtonSound( int sound ); // get string of button sound number - - -// -// Generic Button -// -class CBaseButton : public CBaseToggle -{ -public: - void Spawn( void ); - virtual void Precache( void ); - void RotSpawn( void ); - virtual void KeyValue( KeyValueData* pkvd); - - void ButtonActivate( ); - void SparkSoundCache( void ); - - void EXPORT ButtonShot( void ); - void EXPORT ButtonTouch( CBaseEntity *pOther ); - void EXPORT ButtonSpark ( void ); - void EXPORT TriggerAndWait( void ); - void EXPORT ButtonReturn( void ); - void EXPORT ButtonBackHome( void ); - void EXPORT ButtonUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - enum BUTTON_CODE { BUTTON_NOTHING, BUTTON_ACTIVATE, BUTTON_RETURN }; - BUTTON_CODE ButtonResponseToTouch( void ); - - static TYPEDESCRIPTION m_SaveData[]; - // Buttons that don't take damage can be IMPULSE used - virtual int ObjectCaps( void ) { return (CBaseToggle:: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | (pev->takedamage?0:FCAP_IMPULSE_USE); } - - BOOL m_fStayPushed; // button stays pushed in until touched again? - BOOL m_fRotating; // a rotating button? default is a sliding button. - - string_t m_strChangeTarget; // if this field is not null, this is an index into the engine string array. - // when this button is touched, it's target entity's TARGET field will be set - // to the button's ChangeTarget. This allows you to make a func_train switch paths, etc. - - locksound_t m_ls; // door lock sounds - - BYTE m_bLockedSound; // ordinals from entity selection - BYTE m_bLockedSentence; - BYTE m_bUnlockedSound; - BYTE m_bUnlockedSentence; - int m_sounds; -}; - -// -// Weapons -// - -#define BAD_WEAPON 0x00007FFF - -// -// Converts a entvars_t * to a class pointer -// It will allocate the class and entity if necessary -// -template T * GetClassPtr( T *a ) -{ - entvars_t *pev = (entvars_t *)a; - - // allocate entity if necessary - if (pev == NULL) - pev = VARS(CREATE_ENTITY()); - - // get the private data - a = (T *)GET_PRIVATE(ENT(pev)); - - if (a == NULL) - { - // allocate private data - a = new(pev) T; - a->pev = pev; - } - return a; -} - - -/* -bit_PUSHBRUSH_DATA | bit_TOGGLE_DATA -bit_MONSTER_DATA -bit_DELAY_DATA -bit_TOGGLE_DATA | bit_DELAY_DATA | bit_MONSTER_DATA -bit_PLAYER_DATA | bit_MONSTER_DATA -bit_MONSTER_DATA | CYCLER_DATA -bit_LIGHT_DATA -path_corner_data -bit_MONSTER_DATA | wildcard_data -bit_MONSTER_DATA | bit_GROUP_DATA -boid_flock_data -boid_data -CYCLER_DATA -bit_ITEM_DATA -bit_ITEM_DATA | func_hud_data -bit_TOGGLE_DATA | bit_ITEM_DATA -EOFFSET -env_sound_data -env_sound_data -push_trigger_data -*/ - -#define TRACER_FREQ 4 // Tracers fire every 4 bullets - -typedef struct _SelAmmo -{ - BYTE Ammo1Type; - BYTE Ammo1; - BYTE Ammo2Type; - BYTE Ammo2; -} SelAmmo; - - -// this moved here from world.cpp, to allow classes to be derived from it -//======================= -// CWorld -// -// This spawns first when each level begins. -//======================= -class CWorld : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - - int m_iArenaOff; -}; diff --git a/ricochet/dlls/cdll_dll.h b/ricochet/dlls/cdll_dll.h deleted file mode 100644 index ee324ad..0000000 --- a/ricochet/dlls/cdll_dll.h +++ /dev/null @@ -1,46 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// cdll_dll.h - -// this file is included by both the game-dll and the client-dll, - -#ifndef CDLL_DLL_H -#define CDLL_DLL_H - -#define MAX_WEAPONS 32 // ??? - -#define MAX_WEAPON_SLOTS 5 // hud item selection slots -#define MAX_ITEM_TYPES 6 // hud item selection slots - -#define MAX_ITEMS 5 // hard coded item types - -#define HIDEHUD_WEAPONS ( 1<<0 ) -#define HIDEHUD_FLASHLIGHT ( 1<<1 ) -#define HIDEHUD_ALL ( 1<<2 ) -#define HIDEHUD_HEALTH ( 1<<3 ) - -#define MAX_AMMO_TYPES 32 // ??? -#define MAX_AMMO_SLOTS 32 // not really slots - -#define HUD_PRINTNOTIFY 1 -#define HUD_PRINTCONSOLE 2 -#define HUD_PRINTTALK 3 -#define HUD_PRINTCENTER 4 - - -#define WEAPON_SUIT 31 - -#endif diff --git a/ricochet/dlls/client.cpp b/ricochet/dlls/client.cpp deleted file mode 100644 index 4e976cf..0000000 --- a/ricochet/dlls/client.cpp +++ /dev/null @@ -1,1822 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// Robin, 4-22-98: Moved set_suicide_frame() here from player.cpp to allow us to -// have one without a hardcoded player.mdl in tf_client.cpp - -/* - -===== client.cpp ======================================================== - - client/server game specific stuff - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "player.h" -#include "spectator.h" -#include "client.h" -#include "soundent.h" -#include "gamerules.h" -#include "customentity.h" -#include "weapons.h" -#include "weaponinfo.h" -#include "usercmd.h" -#include "netadr.h" -#include "game.h" -#include "disc_objects.h" - -#if !defined ( _WIN32 ) -#include -#endif - -edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ); - -#include "discwar.h" -#include "disc_arena.h" - -extern DLL_GLOBAL ULONG g_ulModelIndexPlayer; -extern DLL_GLOBAL BOOL g_fGameOver; -extern DLL_GLOBAL int g_iSkillLevel; -extern DLL_GLOBAL ULONG g_ulFrameCount; - -extern void CopyToBodyQue(entvars_t* pev); -extern int giPrecacheGrunt; -extern int gmsgSayText; -extern int g_iNextArenaGroupInfo; -extern void AddClientToArena( CBasePlayer *pPlayer ); - -#define SUIT_HUE_START 192 -#define SUIT_HUE_END 223 -#define PLATE_HUE_START 160 -#define PLATE_HUE_END 191 - -int GetHueFromRGB( float r, float g, float b ) -{ - float fMax = V_max( V_max( r, g ) , b ); - float fMin = V_min( V_min( r, g ) , b ); - float fSaturation = 0; - - if ( fMax != 0 ) - fSaturation = (fMax - fMin) / fMax; - - if ( fSaturation == 0 ) - return 0; - - float fDelta = fMax - fMin; - float fHue = 0; - - if ( r == fMax ) - fHue = ( g - b ) / fDelta; - else if ( g == fMax ) - fHue = 2 + ( b - r ) / fDelta; - else if ( b == fMax ) - fHue = 4 + ( r - g ) / fDelta; - - fHue *= 60; - if ( fHue < 0 ) - fHue += 360; - - // Map it to 0-255 - fHue = fHue / 360; - fHue = (255 * fHue); - - return fHue; -} - -void LinkUserMessages( void ); -/* - * used by kill command and disconnect command - * ROBIN: Moved here from player.cpp, to allow multiple player models - */ -void set_suicide_frame(entvars_t* pev) -{ - if ( !FStrEq(STRING(pev->model), "models/player/female/female.mdl") && !FStrEq(STRING(pev->model), "models/player/male/male.mdl") ) - return; // allready gibbed - -// pev->frame = $deatha11; - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_TOSS; - pev->deadflag = DEAD_DEAD; - pev->nextthink = -1; -} - - -/* -=========== -ClientConnect - -called when a player connects to a server -============ -*/ -BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) -{ - return g_pGameRules->ClientConnected( pEntity, pszName, pszAddress, szRejectReason ); - -// a client connecting during an intermission can cause problems -// if (intermission_running) -// ExitIntermission (); - -} - - -/* -=========== -ClientDisconnect - -called when a player disconnects from a server - -GLOBALS ASSUMED SET: g_fGameOver -============ -*/ -void ClientDisconnect( edict_t *pEntity ) -{ - // If they're in an arena, remove them - CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity); - if ( pPlayer->m_pCurrentArena ) - pPlayer->m_pCurrentArena->RemoveClient( pPlayer ); - - if (g_fGameOver) - return; - -// char text[256]; -// sprintf( text, "- %s has left the game\n", STRING(pEntity->v.netname) ); -// MESSAGE_BEGIN( MSG_BROADCAST, gmsgSayText, NULL ); -// WRITE_BYTE( ENTINDEX(pEntity) ); -// WRITE_STRING( text ); -// MESSAGE_END(); - - // notify other clients the player has left - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Game_disconnected", STRING(pEntity->v.netname) ); - - CSound *pSound; - pSound = CSoundEnt::SoundPointerForIndex( CSoundEnt::ClientSoundIndex( pEntity ) ); - { - // since this client isn't around to think anymore, reset their sound. - if ( pSound ) - { - pSound->Reset(); - } - } - -// since the edict doesn't get deleted, fix it so it doesn't interfere. - pEntity->v.takedamage = DAMAGE_NO;// don't attract autoaim - pEntity->v.solid = SOLID_NOT;// nonsolid - UTIL_SetOrigin ( &pEntity->v, pEntity->v.origin ); - - g_pGameRules->ClientDisconnected( pEntity ); - - pPlayer->m_bHasDisconnected = true; -} - - -// called by ClientKill and DeadThink -void respawn(entvars_t* pev, BOOL fCopyCorpse) -{ - if (gpGlobals->coop || gpGlobals->deathmatch) - { - if ( fCopyCorpse ) - { - // make a copy of the dead body for appearances sake - CopyToBodyQue(pev); - } - - // respawn player - GetClassPtr( (CBasePlayer *)pev)->Spawn( ); - } - else - { // restart the entire server - SERVER_COMMAND("reload\n"); - } -} - -/* -============ -ClientKill - -Player entered the suicide command - -GLOBALS ASSUMED SET: g_ulModelIndexPlayer -============ -*/ -void ClientKill( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - - // Don't allow the suicide command - return; - - CBasePlayer *pl = (CBasePlayer*) CBasePlayer::Instance( pev ); - - if ( pl->m_fNextSuicideTime > gpGlobals->time ) - return; // prevent suiciding too ofter - - pl->m_fNextSuicideTime = gpGlobals->time + 1; // don't let them suicide for 5 seconds after suiciding - - // have the player kill themself - pev->health = 0; - pl->Killed( pev, GIB_NEVER ); - -// pev->modelindex = g_ulModelIndexPlayer; -// pev->frags -= 2; // extra penalty -// respawn( pev ); -} - -/* -=========== -ClientPutInServer - -called when the player is first put in the server -============ -*/ -void ClientPutInServer( edict_t *pEntity ) -{ - CBasePlayer *pPlayer; - - entvars_t *pev = &pEntity->v; - - pPlayer = GetClassPtr((CBasePlayer *)pev); - pPlayer->SetCustomDecalFrames(-1); // Assume none; - - // Allocate a CBasePlayer for pev, and call spawn - pPlayer->Spawn(); - - pPlayer->m_bHasDisconnected = FALSE; - - // Reset interpolation during first frame - pPlayer->pev->effects |= EF_NOINTERP; - pPlayer->m_pCurrentArena = NULL; - pPlayer->m_flKnownItemTime = gpGlobals->time + 0.3; - pPlayer->m_iLastGameResult = GAME_DIDNTPLAY; - - // Add to an Arena (1 maxplayer allows mapmakers to run around their map) - if ( InArenaMode() ) - { - AddClientToArena( pPlayer ); - } - else - { - // Put everyone on different teams - pPlayer->pev->team = ENTINDEX( pEntity ); - pPlayer->pev->iuser4 = pPlayer->pev->team; - - // Set colors - int iHue = GetHueFromRGB( g_iaDiscColors[ pPlayer->pev->team][0] / 255, g_iaDiscColors[pPlayer->pev->team][1] / 255, g_iaDiscColors[pPlayer->pev->team][2] / 255 ); - g_engfuncs.pfnSetClientKeyValue( ENTINDEX( pEntity ), g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "topcolor", UTIL_VarArgs("%d", iHue) ); - g_engfuncs.pfnSetClientKeyValue( ENTINDEX( pEntity ), g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "bottomcolor", UTIL_VarArgs("%d", iHue - 10) ); - } - - static char sName[128]; - strcpy(sName,STRING(pPlayer->pev->netname)); - - // First parse the name and remove any %'s - for ( char *pApersand = sName; pApersand != NULL && *pApersand != 0; pApersand++ ) - { - // Replace it with a space - if ( *pApersand == '%' ) - *pApersand = ' '; - } - - // notify other clients of player joining the game - UTIL_ClientPrintAll( HUD_PRINTNOTIFY, "#Game_connected", sName[0] != 0 ? sName : "" ); -} - -#include "voice_gamemgr.h" -extern CVoiceGameMgr g_VoiceGameMgr; - -//// HOST_SAY -// String comes in as -// say blah blah blah -// or as -// blah blah blah -// -void Host_Say( edict_t *pEntity, int teamonly ) -{ - CBasePlayer *client; - int j; - char *p; - char text[128]; - char szTemp[256]; - const char *cpSay = "say"; - const char *cpSayTeam = "say_team"; - const char *pcmd = CMD_ARGV(0); - - entvars_t *pev = &pEntity->v; - CBasePlayer* player = GetClassPtr((CBasePlayer *)pev); - - // We can get a raw string now, without the "say " prepended - if ( CMD_ARGC() == 0 ) - return; - - if ( !stricmp( pcmd, cpSay) || !stricmp( pcmd, cpSayTeam ) ) - { - if ( CMD_ARGC() >= 2 ) - { - p = (char *)CMD_ARGS(); - } - else - { - // say with a blank message, nothing to do - return; - } - } - else // Raw text, need to prepend argv[0] - { - if ( CMD_ARGC() >= 2 ) - { - sprintf( szTemp, "%s %s", ( char * )pcmd, (char *)CMD_ARGS() ); - } - else - { - // Just a one word command, use the first word...sigh - sprintf( szTemp, "%s", ( char * )pcmd ); - } - p = szTemp; - } - -// remove quotes if present - if (*p == '"') - { - p++; - p[strlen(p)-1] = 0; - } - -// make sure the text has content - char *pc; - for ( pc = p; pc != NULL && *pc != 0; pc++ ) - { - if ( isprint( *pc ) && !isspace( *pc ) ) - { - pc = NULL; // we've found an alphanumeric character, so text is valid - break; - } - } - if ( pc != NULL ) - return; // no character found, so say nothing - -// turn on color set 2 (color on, no sound) - if ( teamonly ) - sprintf( text, "%c(TEAM) %s: ", 2, STRING( pEntity->v.netname ) ); - else - sprintf( text, "%c%s: ", 2, STRING( pEntity->v.netname ) ); - - j = sizeof(text) - 2 - strlen(text); // -2 for /n and null terminator - if ( (int)strlen(p) > j ) - p[j] = 0; - - strcat( text, p ); - strcat( text, "\n" ); - - // loop through all players - // Start with the first player. - // This may return the world in single player if the client types something between levels or during spawn - // so check it, or it will infinite loop - - client = NULL; - while ( ((client = (CBasePlayer*)UTIL_FindEntityByClassname( client, "player" )) != NULL) && (!FNullEnt(client->edict())) ) - { - if ( !client->pev ) - continue; - - if ( client->edict() == pEntity ) - continue; - - if ( !(client->IsNetClient()) ) // Not a client ? (should never be true) - continue; - - // can the receiver hear the sender? or has he muted him? - if ( g_VoiceGameMgr.PlayerHasBlockedPlayer( client, player ) ) - continue; - - if ( teamonly && g_pGameRules->PlayerRelationship(client, CBaseEntity::Instance(pEntity)) != GR_TEAMMATE ) - continue; - - MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, client->pev ); - WRITE_BYTE( ENTINDEX(pEntity) ); - WRITE_STRING( text ); - MESSAGE_END(); - - } - - // print to the sending client - MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, &pEntity->v ); - WRITE_BYTE( ENTINDEX(pEntity) ); - WRITE_STRING( text ); - MESSAGE_END(); - - // echo to server console - g_engfuncs.pfnServerPrint( text ); - - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" %s \"%s\"\n", - STRING( pEntity->v.netname ), - GETPLAYERUSERID( pEntity ), - GETPLAYERAUTHID( pEntity ), - GETPLAYERUSERID( pEntity ), - teamonly ? cpSayTeam : cpSay, - p ); -} - - -/* -=========== -ClientCommand -called each time a player uses a "cmd" command -============ -*/ -extern float g_flWeaponCheat; - -// Use CMD_ARGV, CMD_ARGV, and CMD_ARGC to get pointers the character string command. -void ClientCommand( edict_t *pEntity ) -{ - const char *pcmd = CMD_ARGV(0); - const char *pstr; - - // Is the client spawned yet? - if ( !pEntity->pvPrivateData ) - return; - - entvars_t *pev = &pEntity->v; - - if ( FStrEq(pcmd, "say" ) ) - { - Host_Say( pEntity, 0 ); - } - else if ( FStrEq(pcmd, "say_team" ) ) - { - Host_Say( pEntity, 1 ); - } - else if ( FStrEq(pcmd, "spectate" ) ) - { - // Prevent this is the cvar is set - if ( allow_spectators.value ) - { - CBasePlayer *pPlayer = GetClassPtr((CBasePlayer *)pev); - edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer ); - pPlayer->StartObserver( VARS(pentSpawnSpot)->origin, VARS(pentSpawnSpot)->angles); - } - } - - else if ( FStrEq(pcmd, "ob_mode" ) ) - { - CBasePlayer *pPlayer = GetClassPtr((CBasePlayer *)pev); - pPlayer->ObserverInput_ChangeMode(); - } - else if ( FStrEq(pcmd, "ob_prev" ) ) - { - CBasePlayer *pPlayer = GetClassPtr((CBasePlayer *)pev); - pPlayer->ObserverInput_PrevPlayer(); - } - else if ( FStrEq(pcmd, "ob_next" ) ) - { - CBasePlayer *pPlayer = GetClassPtr((CBasePlayer *)pev); - pPlayer->ObserverInput_NextPlayer(); - } - - else if ( FStrEq(pcmd, "give" ) ) - { - if ( g_flWeaponCheat != 0.0) - { - int iszItem = ALLOC_STRING( CMD_ARGV(1) ); // Make a copy of the classname - GetClassPtr((CBasePlayer *)pev)->GiveNamedItem( STRING(iszItem) ); - } - } - - else if ( FStrEq(pcmd, "drop" ) ) - { - // player is dropping an item. - GetClassPtr((CBasePlayer *)pev)->DropPlayerItem((char *)CMD_ARGV(1)); - } - else if ( FStrEq(pcmd, "fov" ) ) - { - if ( g_flWeaponCheat && CMD_ARGC() > 1) - { - GetClassPtr((CBasePlayer *)pev)->m_iFOV = atoi( CMD_ARGV(1) ); - } - else - { - CLIENT_PRINTF( pEntity, print_console, UTIL_VarArgs( "\"fov\" is \"%d\"\n", (int)GetClassPtr((CBasePlayer *)pev)->m_iFOV ) ); - } - } - else if ( FStrEq(pcmd, "use" ) ) - { - GetClassPtr((CBasePlayer *)pev)->SelectItem((char *)CMD_ARGV(1)); - } - else if (((pstr = strstr(pcmd, "weapon_")) != NULL) && (pstr == pcmd)) - { - GetClassPtr((CBasePlayer *)pev)->SelectItem(pcmd); - } - else if (FStrEq(pcmd, "lastinv" )) - { - GetClassPtr((CBasePlayer *)pev)->SelectLastItem(); - } - else if ( g_pGameRules->ClientCommand( GetClassPtr((CBasePlayer *)pev), pcmd ) ) - { - // MenuSelect returns true only if the command is properly handled, so don't print a warning - } - else - { - // tell the user they entered an unknown command - char command[128]; - - // check the length of the command (prevents crash) - // max total length is 192 ...and we're adding a string below (#Game_unknown_command) - strncpy( command, pcmd, 127 ); - command[127] = '\0'; - - ClientPrint( &pEntity->v, HUD_PRINTCONSOLE, "#Game_unknown_command", command ); - } -} - -/* -======================== -ClientUserInfoChanged - -called after the player changes -userinfo - gives dll a chance to modify it before -it gets sent into the rest of the engine. -======================== -*/ -void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ) -{ - // Is the client spawned yet? - if ( !pEntity->pvPrivateData ) - return; - - // msg everyone if someone changes their name, and it isn't the first time (changing no name to current name) - if ( pEntity->v.netname && STRING(pEntity->v.netname)[0] != 0 && !FStrEq( STRING(pEntity->v.netname), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" )) ) - { - char sName[256]; - char *pName = g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ); - strncpy( sName, pName, sizeof(sName) - 1 ); - sName[ sizeof(sName) - 1 ] = '\0'; - - // First parse the name and remove any %'s - for ( char *pApersand = sName; pApersand != NULL && *pApersand != 0; pApersand++ ) - { - // Replace it with a space - if ( *pApersand == '%' ) - *pApersand = ' '; - } - - // Set the name - g_engfuncs.pfnSetClientKeyValue( ENTINDEX(pEntity), infobuffer, "name", sName ); - - char text[256]; - sprintf( text, "* %s changed name to %s\n", STRING(pEntity->v.netname), g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); - MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); - WRITE_BYTE( ENTINDEX(pEntity) ); - WRITE_STRING( text ); - MESSAGE_END(); - - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" changed name to \"%s\"\n", - STRING( pEntity->v.netname ), - GETPLAYERUSERID( pEntity ), - GETPLAYERAUTHID( pEntity ), - GETPLAYERUSERID( pEntity ), - g_engfuncs.pfnInfoKeyValue( infobuffer, "name" ) ); - } - - g_pGameRules->ClientUserInfoChanged( GetClassPtr((CBasePlayer *)&pEntity->v), infobuffer ); - - // Override model - if ( (!strcmp( "models/player/female/female.mdl", g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ) )) )//&& (!strcmp( "models/player/hgrunt/hgrunt.mdl" )) ) - SET_MODEL( pEntity, "models/player/male/male.mdl" ); - g_engfuncs.pfnSetClientKeyValue( ENTINDEX( pEntity ), infobuffer, "model", "male" ); - - // Set colors - int iHue = GetHueFromRGB( g_iaDiscColors[ pEntity->v.team][0] / 255, g_iaDiscColors[pEntity->v.team][1] / 255, g_iaDiscColors[pEntity->v.team][2] / 255 ); - g_engfuncs.pfnSetClientKeyValue( ENTINDEX( pEntity ), infobuffer, "topcolor", UTIL_VarArgs("%d", iHue) ); - g_engfuncs.pfnSetClientKeyValue( ENTINDEX( pEntity ), infobuffer, "bottomcolor", UTIL_VarArgs("%d", iHue - 10) ); -} - -static int g_serveractive = 0; - -void ServerDeactivate( void ) -{ - // It's possible that the engine will call this function more times than is necessary - // Therefore, only run it one time for each call to ServerActivate - if ( g_serveractive != 1 ) - { - return; - } - - g_serveractive = 0; - - // Peform any shutdown operations here... - // -} - -void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ) -{ - int i; - CBaseEntity *pClass; - - // Every call to ServerActivate should be matched by a call to ServerDeactivate - g_serveractive = 1; - - // Clients have not been initialized yet - for ( i = 0; i < edictCount; i++ ) - { - if ( pEdictList[i].free ) - continue; - - // Clients aren't necessarily initialized until ClientPutInServer() - if ( i < clientMax || !pEdictList[i].pvPrivateData ) - continue; - - pClass = CBaseEntity::Instance( &pEdictList[i] ); - // Activate this entity if it's got a class & isn't dormant - if ( pClass && !(pClass->pev->flags & FL_DORMANT) ) - { - pClass->Activate(); - } - else - { - ALERT( at_console, "Can't instance %s\n", STRING(pEdictList[i].v.classname) ); - } - } - - // Link user messages here to make sure first client can get them... - LinkUserMessages(); - - // Set max speed - SERVER_COMMAND( "sv_maxspeed 320\n" ); - - // Reset Arena Count - g_iNextArenaGroupInfo = 0; -} - - -/* -================ -PlayerPreThink - -Called every frame before physics are run -================ -*/ -void PlayerPreThink( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->PreThink( ); -} - -/* -================ -PlayerPostThink - -Called every frame after physics are run -================ -*/ -void PlayerPostThink( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->PostThink( ); -} - - - -void ParmsNewLevel( void ) -{ -} - - -void ParmsChangeLevel( void ) -{ - // retrieve the pointer to the save data - SAVERESTOREDATA *pSaveData = (SAVERESTOREDATA *)gpGlobals->pSaveData; - - if ( pSaveData ) - pSaveData->connectionCount = BuildChangeList( pSaveData->levelList, MAX_LEVEL_CONNECTIONS ); -} - - -// -// GLOBALS ASSUMED SET: g_ulFrameCount -// -void StartFrame( void ) -{ - if ( g_pGameRules ) - g_pGameRules->Think(); - - if ( g_fGameOver ) - return; - - gpGlobals->teamplay = CVAR_GET_FLOAT("teamplay"); - g_iSkillLevel = CVAR_GET_FLOAT("skill"); - g_ulFrameCount++; -} - - -void ClientPrecache( void ) -{ - // setup precaches always needed - PRECACHE_SOUND("player/sprayer.wav"); // spray paint sound for PreAlpha - - // PRECACHE_SOUND("player/pl_jumpland2.wav"); // UNDONE: play 2x step sound - - PRECACHE_SOUND("player/pl_fallpain2.wav"); - PRECACHE_SOUND("player/pl_fallpain3.wav"); - - PRECACHE_SOUND("player/pl_step1.wav"); // walk on concrete - PRECACHE_SOUND("player/pl_step2.wav"); - PRECACHE_SOUND("player/pl_step3.wav"); - PRECACHE_SOUND("player/pl_step4.wav"); - - PRECACHE_SOUND("common/npc_step1.wav"); // NPC walk on concrete - PRECACHE_SOUND("common/npc_step2.wav"); - PRECACHE_SOUND("common/npc_step3.wav"); - PRECACHE_SOUND("common/npc_step4.wav"); - - PRECACHE_SOUND("player/pl_metal1.wav"); // walk on metal - PRECACHE_SOUND("player/pl_metal2.wav"); - PRECACHE_SOUND("player/pl_metal3.wav"); - PRECACHE_SOUND("player/pl_metal4.wav"); - - PRECACHE_SOUND("player/pl_dirt1.wav"); // walk on dirt - PRECACHE_SOUND("player/pl_dirt2.wav"); - PRECACHE_SOUND("player/pl_dirt3.wav"); - PRECACHE_SOUND("player/pl_dirt4.wav"); - - PRECACHE_SOUND("player/pl_duct1.wav"); // walk in duct - PRECACHE_SOUND("player/pl_duct2.wav"); - PRECACHE_SOUND("player/pl_duct3.wav"); - PRECACHE_SOUND("player/pl_duct4.wav"); - - PRECACHE_SOUND("player/pl_grate1.wav"); // walk on grate - PRECACHE_SOUND("player/pl_grate2.wav"); - PRECACHE_SOUND("player/pl_grate3.wav"); - PRECACHE_SOUND("player/pl_grate4.wav"); - - PRECACHE_SOUND("player/pl_slosh1.wav"); // walk in shallow water - PRECACHE_SOUND("player/pl_slosh2.wav"); - PRECACHE_SOUND("player/pl_slosh3.wav"); - PRECACHE_SOUND("player/pl_slosh4.wav"); - - PRECACHE_SOUND("player/pl_tile1.wav"); // walk on tile - PRECACHE_SOUND("player/pl_tile2.wav"); - PRECACHE_SOUND("player/pl_tile3.wav"); - PRECACHE_SOUND("player/pl_tile4.wav"); - PRECACHE_SOUND("player/pl_tile5.wav"); - - PRECACHE_SOUND("player/pl_swim1.wav"); // breathe bubbles - PRECACHE_SOUND("player/pl_swim2.wav"); - PRECACHE_SOUND("player/pl_swim3.wav"); - PRECACHE_SOUND("player/pl_swim4.wav"); - - PRECACHE_SOUND("player/pl_ladder1.wav"); // climb ladder rung - PRECACHE_SOUND("player/pl_ladder2.wav"); - PRECACHE_SOUND("player/pl_ladder3.wav"); - PRECACHE_SOUND("player/pl_ladder4.wav"); - - PRECACHE_SOUND("player/pl_wade1.wav"); // wade in water - PRECACHE_SOUND("player/pl_wade2.wav"); - PRECACHE_SOUND("player/pl_wade3.wav"); - PRECACHE_SOUND("player/pl_wade4.wav"); - - PRECACHE_SOUND("debris/wood1.wav"); // hit wood texture - PRECACHE_SOUND("debris/wood2.wav"); - PRECACHE_SOUND("debris/wood3.wav"); - - PRECACHE_SOUND("plats/train_use1.wav"); // use a train - - PRECACHE_SOUND("buttons/spark5.wav"); // hit computer texture - PRECACHE_SOUND("buttons/spark6.wav"); - PRECACHE_SOUND("debris/glass1.wav"); - PRECACHE_SOUND("debris/glass2.wav"); - PRECACHE_SOUND("debris/glass3.wav"); - - PRECACHE_SOUND( SOUND_FLASHLIGHT_ON ); - PRECACHE_SOUND( SOUND_FLASHLIGHT_OFF ); - -// player gib sounds - PRECACHE_SOUND("common/bodysplat.wav"); - -// player pain sounds - PRECACHE_SOUND("player/pl_pain2.wav"); - PRECACHE_SOUND("player/pl_pain4.wav"); - PRECACHE_SOUND("player/pl_pain5.wav"); - PRECACHE_SOUND("player/pl_pain6.wav"); - PRECACHE_SOUND("player/pl_pain7.wav"); - - //PRECACHE_MODEL("models/player/female/female.mdl"); - PRECACHE_MODEL("models/player/male/male.mdl"); - - // hud sounds - - PRECACHE_SOUND("common/wpn_hudoff.wav"); - PRECACHE_SOUND("common/wpn_hudon.wav"); - PRECACHE_SOUND("common/wpn_moveselect.wav"); - PRECACHE_SOUND("common/wpn_select.wav"); - PRECACHE_SOUND("common/wpn_denyselect.wav"); - - - // geiger sounds - - PRECACHE_SOUND("player/geiger6.wav"); - PRECACHE_SOUND("player/geiger5.wav"); - PRECACHE_SOUND("player/geiger4.wav"); - PRECACHE_SOUND("player/geiger3.wav"); - PRECACHE_SOUND("player/geiger2.wav"); - PRECACHE_SOUND("player/geiger1.wav"); - - if (giPrecacheGrunt) - UTIL_PrecacheOther("monster_human_grunt"); -} - -/* -=============== -const char *GetGameDescription() - -Returns the descriptive name of this .dll. E.g., Half-Life, or Team Fortress 2 -=============== -*/ -const char *GetGameDescription() -{ - if ( g_pGameRules ) // this function may be called before the world has spawned, and the game rules initialized - return g_pGameRules->GetGameDescription(); - else - return "Ricochet"; -} - -/* -================ -Sys_Error - -Engine is going to shut down, allows setting a breakpoint in game .dll to catch that occasion -================ -*/ -void Sys_Error( const char *error_string ) -{ - // Default case, do nothing. MOD AUTHORS: Add code ( e.g., _asm { int 3 }; here to cause a breakpoint for debugging your game .dlls -} - -/* -================ -PlayerCustomization - -A new player customization has been registered on the server -UNDONE: This only sets the # of frames of the spray can logo -animation right now. -================ -*/ -void PlayerCustomization( edict_t *pEntity, customization_t *pCust ) -{ - entvars_t *pev = &pEntity->v; - CBasePlayer *pPlayer = (CBasePlayer *)GET_PRIVATE(pEntity); - - if (!pPlayer) - { - ALERT(at_console, "PlayerCustomization: Couldn't get player!\n"); - return; - } - - if (!pCust) - { - ALERT(at_console, "PlayerCustomization: NULL customization!\n"); - return; - } - - switch (pCust->resource.type) - { - case t_decal: - pPlayer->SetCustomDecalFrames(pCust->nUserData2); // Second int is max # of frames. - break; - case t_sound: - case t_skin: - case t_model: - // Ignore for now. - break; - default: - ALERT(at_console, "PlayerCustomization: Unknown customization type!\n"); - break; - } -} - -/* -================ -SpectatorConnect - -A spectator has joined the game -================ -*/ -void SpectatorConnect( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->SpectatorConnect( ); -} - -/* -================ -SpectatorConnect - -A spectator has left the game -================ -*/ -void SpectatorDisconnect( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->SpectatorDisconnect( ); -} - -/* -================ -SpectatorConnect - -A spectator has sent a usercmd -================ -*/ -void SpectatorThink( edict_t *pEntity ) -{ - entvars_t *pev = &pEntity->v; - CBaseSpectator *pPlayer = (CBaseSpectator *)GET_PRIVATE(pEntity); - - if (pPlayer) - pPlayer->SpectatorThink( ); -} - - -//////////////////////////////////////////////////////// -// PAS and PVS routines for client messaging -// - -/* -================ -SetupVisibility - -A client can have a separate "view entity" indicating that his/her view should depend on the origin of that -view entity. If that's the case, then pViewEntity will be non-NULL and will be used. Otherwise, the current -entity's origin is used. Either is offset by the view_ofs to get the eye position. - -From the eye position, we set up the PAS and PVS to use for filtering network messages to the client. At this point, we could - override the actual PAS or PVS values, or use a different origin. - -NOTE: Do not cache the values of pas and pvs, as they depend on reusable memory in the engine, they are only good for this one frame -================ -*/ -void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas ) -{ - Vector org; - edict_t *pView = pClient; - - // Find the client's PVS - if ( pViewEntity ) - { - pView = pViewEntity; - } - - // Tracking Spectators use the visibility of their target - CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance( pClient ); - if ( (pPlayer->pev->iuser2 != 0) && (pPlayer->m_hObserverTarget != NULL) ) - { - pView = pPlayer->m_hObserverTarget->edict(); - } - - org = pView->v.origin + pView->v.view_ofs; - if ( pView->v.flags & FL_DUCKING ) - { - org = org + ( VEC_HULL_MIN - VEC_DUCK_HULL_MIN ); - } - - *pvs = ENGINE_SET_PVS ( (float *)&org ); - *pas = ENGINE_SET_PAS ( (float *)&org ); -} - -#include "entity_state.h" - -/* -AddToFullPack - -Return 1 if the entity state has been filled in for the ent and the entity will be propagated to the client, 0 otherwise - -state is the server maintained copy of the state info that is transmitted to the client -a MOD could alter values copied into state to send the "host" a different look for a particular entity update, etc. -e and ent are the entity that is being added to the update, if 1 is returned -host is the player's edict of the player whom we are sending the update to -player is 1 if the ent/e is a player and 0 otherwise -pSet is either the PAS or PVS that we previous set up. We can use it to ask the engine to filter the entity against the PAS or PVS. -we could also use the pas/ pvs that we set in SetupVisibility, if we wanted to. Caching the value is valid in that case, but still only for the current frame -*/ -int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ) -{ - int i; - - // don't send if flagged for NODRAW and it's not the host getting the message - if ( ( ent->v.effects & EF_NODRAW ) && - ( ent != host ) ) - return 0; - - // Ignore ents without valid / visible models - if ( !ent->v.modelindex || !STRING( ent->v.model ) ) - return 0; - - // Don't send spectators to other players - if ( ( ent->v.flags & FL_SPECTATOR ) && ( ent != host ) ) - { - return 0; - } - - // Ignore if not the host and not touching a PVS/PAS leaf - // If pSet is NULL, then the test will always succeed and the entity will be added to the update - if ( ent != host ) - { - if ( !ENGINE_CHECK_VISIBILITY( (const struct edict_s *)ent, pSet ) ) - { - return 0; - } - } - - - // Don't send entity to local client if the client says it's predicting the entity itself. - if ( ent->v.flags & FL_SKIPLOCALHOST ) - { - if ( ( hostflags & 1 ) && ( ent->v.owner == host ) ) - return 0; - } - - if ( host->v.groupinfo ) - { - UTIL_SetGroupTrace( host->v.groupinfo, GROUP_OP_AND ); - - // Should always be set, of course - if ( ent->v.groupinfo ) - { - if ( g_groupop == GROUP_OP_AND ) - { - if ( !(ent->v.groupinfo & host->v.groupinfo ) ) - return 0; - } - else if ( g_groupop == GROUP_OP_NAND ) - { - if ( ent->v.groupinfo & host->v.groupinfo ) - return 0; - } - } - - UTIL_UnsetGroupTrace(); - } - - memset( state, 0, sizeof( *state ) ); - - // Assign index so we can track this entity from frame to frame and - // delta from it. - state->number = e; - state->entityType = ENTITY_NORMAL; - - // Flag custom entities. - if ( ent->v.flags & FL_CUSTOMENTITY ) - { - state->entityType = ENTITY_BEAM; - } - - // - // Copy state data - // - - // Round animtime to nearest millisecond - state->animtime = (int)(1000.0 * ent->v.animtime ) / 1000.0; - - memcpy( state->origin, ent->v.origin, 3 * sizeof( float ) ); - memcpy( state->angles, ent->v.angles, 3 * sizeof( float ) ); - memcpy( state->mins, ent->v.mins, 3 * sizeof( float ) ); - memcpy( state->maxs, ent->v.maxs, 3 * sizeof( float ) ); - - memcpy( state->startpos, ent->v.startpos, 3 * sizeof( float ) ); - memcpy( state->endpos, ent->v.endpos, 3 * sizeof( float ) ); - - state->impacttime = ent->v.impacttime; - state->starttime = ent->v.starttime; - - state->modelindex = ent->v.modelindex; - - state->frame = ent->v.frame; - - state->skin = ent->v.skin; - state->effects = ent->v.effects; - - // This non-player entity is being moved by the game .dll and not the physics simulation system - // make sure that we interpolate it's position on the client if it moves - if ( !player && - ent->v.animtime && - ent->v.velocity[ 0 ] == 0 && - ent->v.velocity[ 1 ] == 0 && - ent->v.velocity[ 2 ] == 0 ) - { - state->eflags |= EFLAG_SLERP; - } - - state->scale = ent->v.scale; - state->solid = ent->v.solid; - state->colormap = ent->v.colormap; - state->movetype = ent->v.movetype; - state->sequence = ent->v.sequence; - state->framerate = ent->v.framerate; - state->body = ent->v.body; - - for (i = 0; i < 4; i++) - { - state->controller[i] = ent->v.controller[i]; - } - - for (i = 0; i < 2; i++) - { - state->blending[i] = ent->v.blending[i]; - } - - state->rendermode = ent->v.rendermode; - state->renderamt = ent->v.renderamt; - state->renderfx = ent->v.renderfx; - state->rendercolor.r = ent->v.rendercolor[0]; - state->rendercolor.g = ent->v.rendercolor[1]; - state->rendercolor.b = ent->v.rendercolor[2]; - - state->aiment = 0; - if ( ent->v.aiment ) - { - state->aiment = ENTINDEX( ent->v.aiment ); - } - - state->owner = 0; - if ( ent->v.owner ) - { - int owner = ENTINDEX( ent->v.owner ); - - // Only care if owned by a player - if ( owner >= 1 && owner <= gpGlobals->maxClients ) - { - state->owner = owner; - } - } - - // Special stuff for players only - if ( player ) - { - memcpy( state->basevelocity, ent->v.basevelocity, 3 * sizeof( float ) ); - - state->weaponmodel = MODEL_INDEX( STRING( ent->v.weaponmodel ) ); - state->gaitsequence = ent->v.gaitsequence; - state->spectator = ent->v.flags & FL_SPECTATOR; - state->friction = ent->v.friction; - - state->gravity = ent->v.gravity; - state->team = ent->v.team; - state->playerclass = ent->v.playerclass; - state->usehull = ( ent->v.flags & FL_DUCKING ) ? 1 : 0; - state->health = ent->v.health; - } - - return 1; -} - -// defaults for clientinfo messages -#define DEFAULT_VIEWHEIGHT 28 - -/* -=================== -CreateBaseline - -Creates baselines used for network encoding, especially for player data since players are not spawned until connect time. -=================== -*/ -void CreateBaseline( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs ) -{ - baseline->origin = entity->v.origin; - baseline->angles = entity->v.angles; - baseline->frame = entity->v.frame; - baseline->skin = (short)entity->v.skin; - - // render information - baseline->rendermode = (byte)entity->v.rendermode; - baseline->renderamt = (byte)entity->v.renderamt; - baseline->rendercolor.r = (byte)entity->v.rendercolor[0]; - baseline->rendercolor.g = (byte)entity->v.rendercolor[1]; - baseline->rendercolor.b = (byte)entity->v.rendercolor[2]; - baseline->renderfx = (byte)entity->v.renderfx; - - if ( player ) - { - baseline->mins = player_mins; - baseline->maxs = player_maxs; - - baseline->colormap = eindex; - baseline->modelindex = playermodelindex; - baseline->friction = 1.0; - baseline->movetype = MOVETYPE_WALK; - - baseline->scale = entity->v.scale; - baseline->solid = SOLID_SLIDEBOX; - baseline->framerate = 1.0; - baseline->gravity = 1.0; - - baseline->playerclass = entity->v.playerclass; - } - else - { - baseline->mins = entity->v.mins; - baseline->maxs = entity->v.maxs; - - baseline->colormap = 0; - baseline->modelindex = entity->v.modelindex;//SV_ModelIndex(pr_strings + entity->v.model); - baseline->movetype = entity->v.movetype; - - baseline->scale = entity->v.scale; - baseline->solid = entity->v.solid; - baseline->framerate = entity->v.framerate; - baseline->gravity = entity->v.gravity; - } -} - -typedef struct -{ - char name[32]; - int field; -} entity_field_alias_t; - -#define FIELD_ORIGIN0 0 -#define FIELD_ORIGIN1 1 -#define FIELD_ORIGIN2 2 -#define FIELD_ANGLES0 3 -#define FIELD_ANGLES1 4 -#define FIELD_ANGLES2 5 - -static entity_field_alias_t entity_field_alias[]= -{ - { "origin[0]", 0 }, - { "origin[1]", 0 }, - { "origin[2]", 0 }, - { "angles[0]", 0 }, - { "angles[1]", 0 }, - { "angles[2]", 0 }, -}; - -void Entity_FieldInit( struct delta_s *pFields ) -{ - entity_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN0 ].name ); - entity_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN1 ].name ); - entity_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ORIGIN2 ].name ); - entity_field_alias[ FIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES0 ].name ); - entity_field_alias[ FIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES1 ].name ); - entity_field_alias[ FIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, entity_field_alias[ FIELD_ANGLES2 ].name ); -} - -/* -================== -Entity_Encode - -Callback for sending entity_state_t info over network. -FIXME: Move to script -================== -*/ -void Entity_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) -{ - entity_state_t *f, *t; - - int localplayer = 0; - static int initialized = 0; - - if ( !initialized ) - { - Entity_FieldInit( pFields ); - initialized = 1; - } - - f = (entity_state_t *)from; - t = (entity_state_t *)to; - - // Never send origin to local player, it's sent with more resolution in clientdata_t structure - localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); - if ( localplayer ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } - - if ( ( t->impacttime != 0 ) && ( t->starttime != 0 ) ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ANGLES0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ANGLES1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ANGLES2 ].field ); - } - - if ( ( t->movetype == MOVETYPE_FOLLOW ) && - ( t->aiment != 0 ) ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } - else if ( t->aiment != f->aiment ) - { - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } -} - -static entity_field_alias_t player_field_alias[]= -{ - { "origin[0]", 0 }, - { "origin[1]", 0 }, - { "origin[2]", 0 }, -}; - -void Player_FieldInit( struct delta_s *pFields ) -{ - player_field_alias[ FIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN0 ].name ); - player_field_alias[ FIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN1 ].name ); - player_field_alias[ FIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, player_field_alias[ FIELD_ORIGIN2 ].name ); -} - -/* -================== -Player_Encode - -Callback for sending entity_state_t for players info over network. -================== -*/ -void Player_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) -{ - entity_state_t *f, *t; - int localplayer = 0; - static int initialized = 0; - - if ( !initialized ) - { - Player_FieldInit( pFields ); - initialized = 1; - } - - f = (entity_state_t *)from; - t = (entity_state_t *)to; - - // Never send origin to local player, it's sent with more resolution in clientdata_t structure - localplayer = ( t->number - 1 ) == ENGINE_CURRENT_PLAYER(); - if ( localplayer ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } - - if ( ( t->movetype == MOVETYPE_FOLLOW ) && - ( t->aiment != 0 ) ) - { - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } - else if ( t->aiment != f->aiment ) - { - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN0 ].field ); - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN1 ].field ); - DELTA_SETBYINDEX( pFields, entity_field_alias[ FIELD_ORIGIN2 ].field ); - } -} - -#define CUSTOMFIELD_ORIGIN0 0 -#define CUSTOMFIELD_ORIGIN1 1 -#define CUSTOMFIELD_ORIGIN2 2 -#define CUSTOMFIELD_ANGLES0 3 -#define CUSTOMFIELD_ANGLES1 4 -#define CUSTOMFIELD_ANGLES2 5 -#define CUSTOMFIELD_SKIN 6 -#define CUSTOMFIELD_SEQUENCE 7 -#define CUSTOMFIELD_ANIMTIME 8 - -entity_field_alias_t custom_entity_field_alias[]= -{ - { "origin[0]", 0 }, - { "origin[1]", 0 }, - { "origin[2]", 0 }, - { "angles[0]", 0 }, - { "angles[1]", 0 }, - { "angles[2]", 0 }, - { "skin", 0 }, - { "sequence", 0 }, - { "animtime", 0 }, -}; - -void Custom_Entity_FieldInit( struct delta_s *pFields ) -{ - custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].name ); - custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field = DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].name ); - custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].name ); - custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field= DELTA_FINDFIELD( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].name ); -} - -/* -================== -Custom_Encode - -Callback for sending entity_state_t info ( for custom entities ) over network. -FIXME: Move to script -================== -*/ -void Custom_Encode( struct delta_s *pFields, const unsigned char *from, const unsigned char *to ) -{ - entity_state_t *f, *t; - int beamType; - static int initialized = 0; - - if ( !initialized ) - { - Custom_Entity_FieldInit( pFields ); - initialized = 1; - } - - f = (entity_state_t *)from; - t = (entity_state_t *)to; - - beamType = t->rendermode & 0x0f; - - if ( beamType != BEAM_POINTS && beamType != BEAM_ENTPOINT ) - { - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN0 ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN1 ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ORIGIN2 ].field ); - } - - if ( beamType != BEAM_POINTS ) - { - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES0 ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES1 ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANGLES2 ].field ); - } - - if ( beamType != BEAM_ENTS && beamType != BEAM_ENTPOINT ) - { - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SKIN ].field ); - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_SEQUENCE ].field ); - } - - // animtime is compared by rounding first - // see if we really shouldn't actually send it - if ( (int)f->animtime == (int)t->animtime ) - { - DELTA_UNSETBYINDEX( pFields, custom_entity_field_alias[ CUSTOMFIELD_ANIMTIME ].field ); - } -} - -/* -================= -RegisterEncoders - -Allows game .dll to override network encoding of certain types of entities and tweak values, etc. -================= -*/ -void RegisterEncoders( void ) -{ - DELTA_ADDENCODER( "Entity_Encode", Entity_Encode ); - DELTA_ADDENCODER( "Custom_Encode", Custom_Encode ); - DELTA_ADDENCODER( "Player_Encode", Player_Encode ); -} - -int GetWeaponData( struct edict_s *player, struct weapon_data_s *info ) -{ - int i; - weapon_data_t *item; - entvars_t *pev = &player->v; - CBasePlayer *pl = ( CBasePlayer *) CBasePlayer::Instance( pev ); - CBasePlayerWeapon *gun; - - ItemInfo II; - - memset( info, 0, 32 * sizeof( weapon_data_t ) ); - - if ( !pl ) - return 1; - - // go through all of the weapons and make a list of the ones to pack - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - if ( pl->m_rgpPlayerItems[ i ] ) - { - // there's a weapon here. Should I pack it? - CBasePlayerItem *pPlayerItem = pl->m_rgpPlayerItems[ i ]; - - while ( pPlayerItem ) - { - gun = (CBasePlayerWeapon *)pPlayerItem->GetWeaponPtr(); - if ( gun && gun->UseDecrement() ) - { - // Get The ID. - memset( &II, 0, sizeof( II ) ); - gun->GetItemInfo( &II ); - - if ( II.iId >= 0 && II.iId < 32 ) - { - item = &info[ II.iId ]; - - item->m_iId = II.iId; - item->m_iClip = pl->m_rgAmmo[gun->m_iPrimaryAmmoType];//gun->m_iClip; - - item->m_flTimeWeaponIdle = V_max( gun->m_flTimeWeaponIdle, -0.001 ); - item->m_flNextPrimaryAttack = V_max( gun->m_flNextPrimaryAttack, -0.001 ); - item->m_flNextSecondaryAttack = V_max( gun->m_flNextSecondaryAttack, -0.001 ); - item->m_fInReload = gun->m_fInReload; - } - } - pPlayerItem = pPlayerItem->m_pNext; - } - } - } - return 1; -} - -/* -================= -UpdateClientData - -Data sent to current client only -engine sets cd to 0 before calling. -================= -*/ -void UpdateClientData ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ) -{ - cd->flags = ent->v.flags; - cd->health = ent->v.health; - - cd->viewmodel = MODEL_INDEX( STRING( ent->v.viewmodel ) ); - cd->waterlevel = ent->v.waterlevel; - cd->watertype = ent->v.watertype; - cd->weapons = ent->v.weapons; - - // Vectors - cd->origin = ent->v.origin; - cd->velocity = ent->v.velocity; - cd->view_ofs = ent->v.view_ofs; - cd->punchangle = ent->v.punchangle; - - cd->bInDuck = ent->v.bInDuck; - cd->flTimeStepSound = ent->v.flTimeStepSound; - cd->flDuckTime = ent->v.flDuckTime; - cd->flSwimTime = ent->v.flSwimTime; - cd->waterjumptime = ent->v.teleport_time; - - strcpy( cd->physinfo, ENGINE_GETPHYSINFO( ent ) ); - - cd->maxspeed = ent->v.maxspeed; - cd->fov = ent->v.fov; - cd->weaponanim = ent->v.weaponanim; - - cd->pushmsec = ent->v.pushmsec; - - // Spectator - cd->iuser1 = ent->v.iuser1; - cd->iuser2 = ent->v.iuser2; - - if ( sendweapons ) - { - entvars_t *pev = (entvars_t *)&ent->v; - CBasePlayer *pl = ( CBasePlayer *) CBasePlayer::Instance( pev ); - - if ( pl ) - { - cd->m_flNextAttack = pl->m_flNextAttack; - - if ( pl->m_pActiveItem ) - { - CBasePlayerWeapon *gun; - gun = (CBasePlayerWeapon *)pl->m_pActiveItem->GetWeaponPtr(); - if ( gun && gun->UseDecrement() ) - { - ItemInfo II; - memset( &II, 0, sizeof( II ) ); - gun->GetItemInfo( &II ); - - cd->m_iId = II.iId; - } - } - } - } -} - -/* -================= -CmdStart - -We're about to run this usercmd for the specified player. We can set up groupinfo and masking here, etc. -This is the time to examine the usercmd for anything extra. This call happens even if think does not. -================= -*/ -void CmdStart( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed ) -{ - entvars_t *pev = (entvars_t *)&player->v; - CBasePlayer *pl = ( CBasePlayer *) CBasePlayer::Instance( pev ); - - if( !pl ) - return; - - if ( pl->pev->groupinfo != 0 ) - { - UTIL_SetGroupTrace( pl->pev->groupinfo, GROUP_OP_AND ); - } - - pl->random_seed = random_seed; -} - -/* -================= -CmdEnd - -Each cmdstart is exactly matched with a cmd end, clean up any group trace flags, etc. here -================= -*/ -void CmdEnd ( const edict_t *player ) -{ - entvars_t *pev = (entvars_t *)&player->v; - CBasePlayer *pl = ( CBasePlayer *) CBasePlayer::Instance( pev ); - - if( !pl ) - return; - if ( pl->pev->groupinfo != 0 ) - { - UTIL_UnsetGroupTrace(); - } -} - -/* -================================ -ConnectionlessPacket - - Return 1 if the packet is valid. Set response_buffer_size if you want to send a response packet. Incoming, it holds the max - size of the response_buffer, so you must zero it out if you choose not to respond. -================================ -*/ -int ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ) -{ - // Parse stuff from args - int max_buffer_size = *response_buffer_size; - - // Zero it out since we aren't going to respond. - // If we wanted to response, we'd write data into response_buffer - *response_buffer_size = 0; - - // Since we don't listen for anything here, just respond that it's a bogus message - // If we didn't reject the message, we'd return 1 for success instead. - return 0; -} - -/* -================================ -GetHullBounds - - Engine calls this to enumerate player collision hulls, for prediction. Return 0 if the hullnumber doesn't exist. -================================ -*/ -int GetHullBounds( int hullnumber, float *mins, float *maxs ) -{ - int iret = 0; - - switch ( hullnumber ) - { - case 0: // Normal player - mins = VEC_HULL_MIN; - maxs = VEC_HULL_MAX; - iret = 1; - break; - case 1: // Crouched player - mins = VEC_DUCK_HULL_MIN; - maxs = VEC_DUCK_HULL_MAX; - iret = 1; - break; - case 2: // Point based hull - mins = Vector( 0, 0, 0 ); - maxs = Vector( 0, 0, 0 ); - iret = 1; - break; - } - - return iret; -} - -/* -================================ -CreateInstancedBaselines - -Create pseudo-baselines for items that aren't placed in the map at spawn time, but which are likely -to be created during play ( e.g., grenades, ammo packs, projectiles, corpses, etc. ) -================================ -*/ -void CreateInstancedBaselines ( void ) -{ - int iret = 0; - entity_state_t state; - - memset( &state, 0, sizeof( state ) ); - - // Create any additional baselines here for things like grendates, etc. - // iret = ENGINE_INSTANCE_BASELINE( pc->pev->classname, &state ); - - // Destroy objects. - //UTIL_Remove( pc ); -} - -/* -================================ -InconsistentFile - -One of the ENGINE_FORCE_UNMODIFIED files failed the consistency check for the specified player - Return 0 to allow the client to continue, 1 to force immediate disconnection ( with an optional disconnect message of up to 256 characters ) -================================ -*/ -int InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message ) -{ - // Server doesn't care? - if ( CVAR_GET_FLOAT( "mp_consistency" ) != 1 ) - return 0; - - // Default behavior is to kick the player - sprintf( disconnect_message, "Server is enforcing file consistency for %s\n", filename ); - - // Kick now with specified disconnect message. - return 1; -} - -/* -================================ -AllowLagCompensation - - The game .dll should return 1 if lag compensation should be allowed ( could also just set - the sv_unlag cvar. - Most games right now should return 0, until client-side weapon prediction code is written - and tested for them ( note you can predict weapons, but not do lag compensation, too, - if you want. -================================ -*/ -int AllowLagCompensation( void ) -{ - return 0; -} - - -/* -================================ -ShouldCollide - - Called when the engine believes two entities are about to collide. Return 0 if you - want the two entities to just pass through each other without colliding or calling the - touch function. -================================ -*/ -int ShouldCollide( edict_t *pentTouched, edict_t *pentOther ) -{ - // To make this a fast check, use iuser4 for the discs to know what other discs they should collide with - if ( pentTouched->v.iuser4 != 0 && pentOther->v.iuser4 != 0 ) - { - // Two friendly discs will have matching iuser4's - if ( pentTouched->v.iuser4 == pentOther->v.iuser4 ) - { - return 0; - } - - // Discs hitting their owners - CBaseEntity *pTouched = CBaseEntity::Instance(pentTouched); - CBaseEntity *pOther = CBaseEntity::Instance(pentOther); - /* - if ( pOther->IsDisc() && pTouched->IsPlayer() && ((CDisc*)pOther)->m_hOwner == pTouched ) - return 0; - if ( pTouched->IsDisc() && pOther->IsPlayer() && ((CDisc*)pTouched)->m_hOwner == pOther ) - return 0; - */ - //if ( pOther->IsDisc() || pTouched->IsDisc() ) - //return 0; - } - - return 1; -} diff --git a/ricochet/dlls/client.h b/ricochet/dlls/client.h deleted file mode 100644 index 0404b6a..0000000 --- a/ricochet/dlls/client.h +++ /dev/null @@ -1,67 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef CLIENT_H -#define CLIENT_H - -extern void respawn( entvars_t* pev, BOOL fCopyCorpse ); -extern BOOL ClientConnect( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); -extern void ClientDisconnect( edict_t *pEntity ); -extern void ClientKill( edict_t *pEntity ); -extern void ClientPutInServer( edict_t *pEntity ); -extern void ClientCommand( edict_t *pEntity ); -extern void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ); -extern void ServerActivate( edict_t *pEdictList, int edictCount, int clientMax ); -extern void ServerDeactivate( void ); -extern void StartFrame( void ); -extern void PlayerPostThink( edict_t *pEntity ); -extern void PlayerPreThink( edict_t *pEntity ); -extern void ParmsNewLevel( void ); -extern void ParmsChangeLevel( void ); - -extern void ClientPrecache( void ); - -extern const char *GetGameDescription( void ); -extern void PlayerCustomization( edict_t *pEntity, customization_t *pCust ); - -extern void SpectatorConnect ( edict_t *pEntity ); -extern void SpectatorDisconnect ( edict_t *pEntity ); -extern void SpectatorThink ( edict_t *pEntity ); - -extern void Sys_Error( const char *error_string ); - -extern void SetupVisibility( edict_t *pViewEntity, edict_t *pClient, unsigned char **pvs, unsigned char **pas ); -extern void UpdateClientData ( const struct edict_s *ent, int sendweapons, struct clientdata_s *cd ); -extern int AddToFullPack( struct entity_state_s *state, int e, edict_t *ent, edict_t *host, int hostflags, int player, unsigned char *pSet ); -extern void CreateBaseline( int player, int eindex, struct entity_state_s *baseline, struct edict_s *entity, int playermodelindex, vec3_t player_mins, vec3_t player_maxs ); -extern void RegisterEncoders( void ); - -extern int GetWeaponData( struct edict_s *player, struct weapon_data_s *info ); - -extern void CmdStart( const edict_t *player, const struct usercmd_s *cmd, unsigned int random_seed ); -extern void CmdEnd ( const edict_t *player ); - -extern int ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); - -extern int GetHullBounds( int hullnumber, float *mins, float *maxs ); - -extern void CreateInstancedBaselines ( void ); - -extern int InconsistentFile( const edict_t *player, const char *filename, char *disconnect_message ); - -extern int AllowLagCompensation( void ); - -extern int ShouldCollide( edict_t *pentTouched, edict_t *pentOther ); - -#endif // CLIENT_H diff --git a/ricochet/dlls/combat.cpp b/ricochet/dlls/combat.cpp deleted file mode 100644 index e6bf4fe..0000000 --- a/ricochet/dlls/combat.cpp +++ /dev/null @@ -1,1453 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== combat.cpp ======================================================== - - functions dealing with damage infliction & death - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "soundent.h" -#include "decals.h" -#include "animation.h" -#include "weapons.h" -#include "func_break.h" - -extern DLL_GLOBAL Vector g_vecAttackDir; -extern DLL_GLOBAL int g_iSkillLevel; - -extern Vector VecBModelOrigin( entvars_t* pevBModel ); -extern entvars_t *g_pevLastInflictor; - -#define GERMAN_GIB_COUNT 4 -#define HUMAN_GIB_COUNT 6 -#define ALIEN_GIB_COUNT 4 - - -// HACKHACK -- The gib velocity equations don't work -void CGib :: LimitVelocity( void ) -{ - float length = pev->velocity.Length(); - - // ceiling at 1500. The gib velocity equation is not bounded properly. Rather than tune it - // in 3 separate places again, I'll just limit it here. - if ( length > 1500.0 ) - pev->velocity = pev->velocity.Normalize() * 1500; // This should really be sv_maxvelocity * 0.75 or something -} - - -void CGib :: SpawnStickyGibs( entvars_t *pevVictim, Vector vecOrigin, int cGibs ) -{ - int i; - - if ( g_Language == LANGUAGE_GERMAN ) - { - // no sticky gibs in germany right now! - return; - } - - for ( i = 0 ; i < cGibs ; i++ ) - { - CGib *pGib = GetClassPtr( (CGib *)NULL ); - - pGib->Spawn( "models/stickygib.mdl" ); - pGib->pev->body = RANDOM_LONG(0,2); - - if ( pevVictim ) - { - pGib->pev->origin.x = vecOrigin.x + RANDOM_FLOAT( -3, 3 ); - pGib->pev->origin.y = vecOrigin.y + RANDOM_FLOAT( -3, 3 ); - pGib->pev->origin.z = vecOrigin.z + RANDOM_FLOAT( -3, 3 ); - - /* - pGib->pev->origin.x = pevVictim->absmin.x + pevVictim->size.x * (RANDOM_FLOAT ( 0 , 1 ) ); - pGib->pev->origin.y = pevVictim->absmin.y + pevVictim->size.y * (RANDOM_FLOAT ( 0 , 1 ) ); - pGib->pev->origin.z = pevVictim->absmin.z + pevVictim->size.z * (RANDOM_FLOAT ( 0 , 1 ) ); - */ - - // make the gib fly away from the attack vector - pGib->pev->velocity = g_vecAttackDir * -1; - - // mix in some noise - pGib->pev->velocity.x += RANDOM_FLOAT ( -0.15, 0.15 ); - pGib->pev->velocity.y += RANDOM_FLOAT ( -0.15, 0.15 ); - pGib->pev->velocity.z += RANDOM_FLOAT ( -0.15, 0.15 ); - - pGib->pev->velocity = pGib->pev->velocity * 900; - - pGib->pev->avelocity.x = RANDOM_FLOAT ( 250, 400 ); - pGib->pev->avelocity.y = RANDOM_FLOAT ( 250, 400 ); - - // copy owner's blood color - pGib->m_bloodColor = (CBaseEntity::Instance(pevVictim))->BloodColor(); - - if ( pevVictim->health > -50) - { - pGib->pev->velocity = pGib->pev->velocity * 0.7; - } - else if ( pevVictim->health > -200) - { - pGib->pev->velocity = pGib->pev->velocity * 2; - } - else - { - pGib->pev->velocity = pGib->pev->velocity * 4; - } - - - pGib->pev->movetype = MOVETYPE_TOSS; - pGib->pev->solid = SOLID_BBOX; - UTIL_SetSize ( pGib->pev, Vector ( 0, 0 ,0 ), Vector ( 0, 0, 0 ) ); - pGib->SetTouch ( &CGib::StickyGibTouch ); - pGib->SetThink (NULL); - } - pGib->LimitVelocity(); - } -} - -void CGib :: SpawnHeadGib( entvars_t *pevVictim ) -{ - CGib *pGib = GetClassPtr( (CGib *)NULL ); - - if ( g_Language == LANGUAGE_GERMAN ) - { - pGib->Spawn( "models/germangibs.mdl" );// throw one head - pGib->pev->body = 0; - } - else - { - pGib->Spawn( "models/head.mdl" );// throw one head - } - - if ( pevVictim ) - { - pGib->pev->origin = pevVictim->origin + pevVictim->view_ofs; - - edict_t *pentPlayer = FIND_CLIENT_IN_PVS( pGib->edict() ); - - pGib->pev->velocity = Vector (RANDOM_FLOAT(-100,100), RANDOM_FLOAT(-100,100), RANDOM_FLOAT(300,400)); - - pGib->pev->avelocity.x = RANDOM_FLOAT ( 100, 200 ); - pGib->pev->avelocity.y = RANDOM_FLOAT ( 100, 300 ); - - // copy owner's blood color - pGib->m_bloodColor = (CBaseEntity::Instance(pevVictim))->BloodColor(); - - // Set its groupinfo to the player's - pGib->pev->groupinfo = pevVictim->groupinfo; - // Since this only ever happens when a player is hit by a frozen decapitator disc, make the gibs glow - pGib->pev->renderfx = kRenderFxGlowShell; - pGib->pev->rendercolor = Vector( 100,100, 250 ); - pGib->pev->renderamt = 25; - } - pGib->LimitVelocity(); -} - -void CGib :: SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int human ) -{ - int cSplat; - - for ( cSplat = 0 ; cSplat < cGibs ; cSplat++ ) - { - CGib *pGib = GetClassPtr( (CGib *)NULL ); - - if ( g_Language == LANGUAGE_GERMAN ) - { - pGib->Spawn( "models/germangibs.mdl" ); - pGib->pev->body = RANDOM_LONG(0,GERMAN_GIB_COUNT-1); - } - else - { - if ( human ) - { - // human pieces - pGib->Spawn( "models/hgibs.mdl" ); - pGib->pev->body = RANDOM_LONG(1,HUMAN_GIB_COUNT-1);// start at one to avoid throwing random amounts of skulls (0th gib) - } - else - { - // aliens - pGib->Spawn( "models/agibs.mdl" ); - pGib->pev->body = RANDOM_LONG(0,ALIEN_GIB_COUNT-1); - } - } - - if ( pevVictim ) - { - // spawn the gib somewhere in the monster's bounding volume - pGib->pev->origin.x = pevVictim->absmin.x + pevVictim->size.x * (RANDOM_FLOAT ( 0 , 1 ) ); - pGib->pev->origin.y = pevVictim->absmin.y + pevVictim->size.y * (RANDOM_FLOAT ( 0 , 1 ) ); - pGib->pev->origin.z = pevVictim->absmin.z + pevVictim->size.z * (RANDOM_FLOAT ( 0 , 1 ) ) + 1; // absmin.z is in the floor because the engine subtracts 1 to enlarge the box - - // make the gib fly away from the attack vector - pGib->pev->velocity = g_vecAttackDir * -1; - - // mix in some noise - pGib->pev->velocity.x += RANDOM_FLOAT ( -0.25, 0.25 ); - pGib->pev->velocity.y += RANDOM_FLOAT ( -0.25, 0.25 ); - pGib->pev->velocity.z += RANDOM_FLOAT ( -0.25, 0.25 ); - - pGib->pev->velocity = pGib->pev->velocity * RANDOM_FLOAT ( 600, 700 ); - - pGib->pev->avelocity.x = RANDOM_FLOAT ( 100, 200 ); - pGib->pev->avelocity.y = RANDOM_FLOAT ( 100, 300 ); - - // copy owner's blood color - pGib->m_bloodColor = (CBaseEntity::Instance(pevVictim))->BloodColor(); - - if ( pevVictim->health > -50) - { - pGib->pev->velocity = pGib->pev->velocity * 0.7; - } - else if ( pevVictim->health > -200) - { - pGib->pev->velocity = pGib->pev->velocity * 2; - } - else - { - pGib->pev->velocity = pGib->pev->velocity * 4; - } - - pGib->pev->solid = SOLID_BBOX; - UTIL_SetSize ( pGib->pev, Vector( 0 , 0 , 0 ), Vector ( 0, 0, 0 ) ); - - // Set its groupinfo to the player's - pGib->pev->groupinfo = pevVictim->groupinfo; - // Since this only ever happens when a player is hit by a frozen decapitator disc, make the gibs glow - pGib->pev->renderfx = kRenderFxGlowShell; - pGib->pev->rendercolor = Vector( 150,150,250 ); - pGib->pev->renderamt = 100; - } - pGib->LimitVelocity(); - } -} - - -BOOL CBaseMonster :: HasHumanGibs( void ) -{ - int myClass = Classify(); - - if ( myClass == CLASS_HUMAN_MILITARY || - myClass == CLASS_PLAYER_ALLY || - myClass == CLASS_HUMAN_PASSIVE || - myClass == CLASS_PLAYER ) - - return TRUE; - - return FALSE; -} - - -BOOL CBaseMonster :: HasAlienGibs( void ) -{ - int myClass = Classify(); - - if ( myClass == CLASS_ALIEN_MILITARY || - myClass == CLASS_ALIEN_MONSTER || - myClass == CLASS_ALIEN_PASSIVE || - myClass == CLASS_INSECT || - myClass == CLASS_ALIEN_PREDATOR || - myClass == CLASS_ALIEN_PREY ) - - return TRUE; - - return FALSE; -} - - -void CBaseMonster::FadeMonster( void ) -{ - StopAnimation(); - pev->velocity = g_vecZero; - pev->movetype = MOVETYPE_NONE; - pev->avelocity = g_vecZero; - pev->animtime = gpGlobals->time; - pev->effects |= EF_NOINTERP; - SUB_StartFadeOut(); -} - -//========================================================= -// GibMonster - create some gore and get rid of a monster's -// model. -//========================================================= -void CBaseMonster :: GibMonster( void ) -{ - TraceResult tr; - BOOL gibbed = FALSE; - - EMIT_SOUND(ENT(pev), CHAN_WEAPON, "common/bodysplat.wav", 1, ATTN_NORM); - - // only humans throw skulls !!!UNDONE - eventually monsters will have their own sets of gibs - if ( HasHumanGibs() ) - { - if ( CVAR_GET_FLOAT("violence_hgibs") != 0 ) // Only the player will ever get here - { - CGib::SpawnHeadGib( pev ); - CGib::SpawnRandomGibs( pev, 4, 1 ); // throw some human gibs. - } - gibbed = TRUE; - } - else if ( HasAlienGibs() ) - { - if ( CVAR_GET_FLOAT("violence_agibs") != 0 ) // Should never get here, but someone might call it directly - { - CGib::SpawnRandomGibs( pev, 4, 0 ); // Throw alien gibs - } - gibbed = TRUE; - } - - if ( !IsPlayer() ) - { - if ( gibbed ) - { - // don't remove players! - SetThink ( &CBaseMonster::SUB_Remove ); - pev->nextthink = gpGlobals->time; - } - else - { - FadeMonster(); - } - } -} - -//========================================================= -// GetDeathActivity - determines the best type of death -// anim to play. -//========================================================= -Activity CBaseMonster :: GetDeathActivity ( void ) -{ - Activity deathActivity; - - if ( pev->deadflag != DEAD_NO ) - { - // don't run this while dying. - return m_IdealActivity; - } - - switch ( m_LastHitGroup ) - { - // try to pick a region-specific death. - case HITGROUP_HEAD: - deathActivity = ACT_DIE_HEADSHOT; - break; - - default: - deathActivity = ACT_DIEFORWARD; - break; - } - - return deathActivity; -} - -//========================================================= -// GetSmallFlinchActivity - determines the best type of flinch -// anim to play. -//========================================================= -Activity CBaseMonster :: GetSmallFlinchActivity ( void ) -{ - Activity flinchActivity; - - flinchActivity = ACT_FLINCH_BACK; - - return flinchActivity; -} - - -void CBaseMonster::BecomeDead( void ) -{ - pev->takedamage = DAMAGE_YES;// don't let autoaim aim at corpses. - - // give the corpse half of the monster's original maximum health. - pev->health = pev->max_health / 2; - pev->max_health = 5; // max_health now becomes a counter for how many blood decals the corpse can place. - - // make the corpse fly away from the attack vector - pev->movetype = MOVETYPE_TOSS; - //pev->flags &= ~FL_ONGROUND; - //pev->origin.z += 2; - //pev->velocity = g_vecAttackDir * -1; - //pev->velocity = pev->velocity * RANDOM_FLOAT( 300, 400 ); -} - - -BOOL CBaseMonster::ShouldGibMonster( int iGib ) -{ - if ( ( iGib == GIB_NORMAL && pev->health < GIB_HEALTH_VALUE ) || ( iGib == GIB_ALWAYS ) ) - return TRUE; - - return FALSE; -} - - -void CBaseMonster::CallGibMonster( void ) -{ - BOOL fade = FALSE; - - if ( HasHumanGibs() ) - { - if ( CVAR_GET_FLOAT("violence_hgibs") == 0 ) - fade = TRUE; - } - else if ( HasAlienGibs() ) - { - if ( CVAR_GET_FLOAT("violence_agibs") == 0 ) - fade = TRUE; - } - - pev->takedamage = DAMAGE_NO; - pev->solid = SOLID_NOT;// do something with the body. while monster blows up - - if ( fade ) - { - FadeMonster(); - } - else - { - pev->effects = EF_NODRAW; // make the model invisible. - GibMonster(); - } - - pev->deadflag = DEAD_DEAD; - FCheckAITrigger(); - - // don't let the status bar glitch for players.with <0 health. - if (pev->health < -99) - { - pev->health = 0; - } - - if ( ShouldFadeOnDeath() && !fade ) - UTIL_Remove(this); -} - - -/* -============ -Killed -============ -*/ -void CBaseMonster :: Killed( entvars_t *pevAttacker, int iGib ) -{ - unsigned int cCount = 0; - BOOL fDone = FALSE; - - if ( HasMemory( bits_MEMORY_KILLED ) ) - { - if ( ShouldGibMonster( iGib ) ) - CallGibMonster(); - return; - } - - Remember( bits_MEMORY_KILLED ); - - // clear the deceased's sound channels.(may have been firing or reloading when killed) - EMIT_SOUND(ENT(pev), CHAN_WEAPON, "common/null.wav", 1, ATTN_NORM); - m_IdealMonsterState = MONSTERSTATE_DEAD; - // Make sure this condition is fired too (TakeDamage breaks out before this happens on death) - SetConditions( bits_COND_LIGHT_DAMAGE ); - - // tell owner ( if any ) that we're dead.This is mostly for MonsterMaker functionality. - CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner); - if ( pOwner ) - { - pOwner->DeathNotice( pev ); - } - - if ( ShouldGibMonster( iGib ) ) - { - CallGibMonster(); - return; - } - else if ( pev->flags & FL_MONSTER ) - { - SetTouch( NULL ); - BecomeDead(); - } - - // don't let the status bar glitch for players.with <0 health. - if (pev->health < -99) - { - pev->health = 0; - } - - //pev->enemy = ENT( pevAttacker );//why? (sjb) - - m_IdealMonsterState = MONSTERSTATE_DEAD; -} - -// -// fade out - slowly fades a entity out, then removes it. -// -// DON'T USE ME FOR GIBS AND STUFF IN MULTIPLAYER! -// SET A FUTURE THINK AND A RENDERMODE!! -void CBaseEntity :: SUB_StartFadeOut ( void ) -{ - if (pev->rendermode == kRenderNormal) - { - pev->renderamt = 255; - pev->rendermode = kRenderTransTexture; - } - - pev->solid = SOLID_NOT; - pev->avelocity = g_vecZero; - - pev->nextthink = gpGlobals->time + 0.1; - SetThink ( &CBaseEntity::SUB_FadeOut ); -} - -void CBaseEntity :: SUB_FadeOut ( void ) -{ - if ( pev->renderamt > 7 ) - { - pev->renderamt -= 7; - pev->nextthink = gpGlobals->time + 0.1; - } - else - { - pev->renderamt = 0; - pev->nextthink = gpGlobals->time + 0.2; - SetThink ( &CBaseEntity::SUB_Remove ); - } -} - -//========================================================= -// WaitTillLand - in order to emit their meaty scent from -// the proper location, gibs should wait until they stop -// bouncing to emit their scent. That's what this function -// does. -//========================================================= -void CGib :: WaitTillLand ( void ) -{ - if (!IsInWorld()) - { - UTIL_Remove( this ); - return; - } - - if ( pev->velocity == g_vecZero ) - { - SetThink (&CGib::SUB_StartFadeOut); - pev->nextthink = gpGlobals->time + m_lifeTime; - - // If you bleed, you stink! - if ( m_bloodColor != DONT_BLEED ) - { - // ok, start stinkin! - CSoundEnt::InsertSound ( bits_SOUND_MEAT, pev->origin, 384, 25 ); - } - } - else - { - // wait and check again in another half second. - pev->nextthink = gpGlobals->time + 0.5; - } -} - -// -// Gib bounces on the ground or wall, sponges some blood down, too! -// -void CGib :: BounceGibTouch ( CBaseEntity *pOther ) -{ - Vector vecSpot; - TraceResult tr; - - //if ( RANDOM_LONG(0,1) ) - // return;// don't bleed everytime - - if (pev->flags & FL_ONGROUND) - { - pev->velocity = pev->velocity * 0.9; - pev->angles.x = 0; - pev->angles.z = 0; - pev->avelocity.x = 0; - pev->avelocity.z = 0; - } - else - { - if ( g_Language != LANGUAGE_GERMAN && m_cBloodDecals > 0 && m_bloodColor != DONT_BLEED ) - { - vecSpot = pev->origin + Vector ( 0 , 0 , 8 );//move up a bit, and trace down. - UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -24 ), ignore_monsters, ENT(pev), & tr); - - UTIL_BloodDecalTrace( &tr, m_bloodColor ); - - m_cBloodDecals--; - } - - if ( m_material != matNone && RANDOM_LONG(0,2) == 0 ) - { - float volume; - float zvel = fabs(pev->velocity.z); - - volume = 0.8 * V_min(1.0, ((float)zvel) / 450.0); - - CBreakable::MaterialSoundRandom( edict(), (Materials)m_material, volume ); - } - } -} - -// -// Sticky gib puts blood on the wall and stays put. -// -void CGib :: StickyGibTouch ( CBaseEntity *pOther ) -{ - Vector vecSpot; - TraceResult tr; - - SetThink ( &CGib::SUB_Remove ); - pev->nextthink = gpGlobals->time + 10; - - if ( !FClassnameIs( pOther->pev, "worldspawn" ) ) - { - pev->nextthink = gpGlobals->time; - return; - } - - UTIL_TraceLine ( pev->origin, pev->origin + pev->velocity * 32, ignore_monsters, ENT(pev), & tr); - - UTIL_BloodDecalTrace( &tr, m_bloodColor ); - - pev->velocity = tr.vecPlaneNormal * -1; - pev->angles = UTIL_VecToAngles ( pev->velocity ); - pev->velocity = g_vecZero; - pev->avelocity = g_vecZero; - pev->movetype = MOVETYPE_NONE; -} - -// -// Throw a chunk -// -void CGib :: Spawn( const char *szGibModel ) -{ - pev->movetype = MOVETYPE_BOUNCE; - pev->friction = 0.55; // deading the bounce a bit - - // sometimes an entity inherits the edict from a former piece of glass, - // and will spawn using the same render FX or rendermode! bad! - pev->renderamt = 255; - pev->rendermode = kRenderNormal; - pev->renderfx = kRenderFxNone; - pev->solid = SOLID_SLIDEBOX;/// hopefully this will fix the VELOCITY TOO LOW crap - pev->classname = MAKE_STRING("gib"); - - SET_MODEL(ENT(pev), szGibModel); - UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0)); - - pev->nextthink = gpGlobals->time + 4; - m_lifeTime = 10; - SetThink ( &CGib::WaitTillLand ); - SetTouch ( &CGib::BounceGibTouch ); - - m_material = matNone; - m_cBloodDecals = 5;// how many blood decals this gib can place (1 per bounce until none remain). -} - -// take health -int CBaseMonster :: TakeHealth (float flHealth, int bitsDamageType) -{ - if (!pev->takedamage) - return 0; - - // clear out any damage types we healed. - // UNDONE: generic health should not heal any - // UNDONE: time-based damage - - m_bitsDamageType &= ~(bitsDamageType & ~DMG_TIMEBASED); - - return CBaseEntity::TakeHealth(flHealth, bitsDamageType); -} - -/* -============ -TakeDamage - -The damage is coming from inflictor, but get mad at attacker -This should be the only function that ever reduces health. -bitsDamageType indicates the type of damage sustained, ie: DMG_SHOCK - -Time-based damage: only occurs while the monster is within the trigger_hurt. -When a monster is poisoned via an arrow etc it takes all the poison damage at once. - - - -GLOBALS ASSUMED SET: g_iSkillLevel -============ -*/ -int CBaseMonster :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) -{ - float flTake; - Vector vecDir; - - if (!pev->takedamage) - return 0; - - if ( !IsAlive() ) - { - return DeadTakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); - } - - if ( pev->deadflag == DEAD_NO ) - { - // no pain sound during death animation. - PainSound();// "Ouch!" - } - - //!!!LATER - make armor consideration here! - flTake = flDamage; - - // set damage type sustained - m_bitsDamageType |= bitsDamageType; - - // grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit). - vecDir = Vector( 0, 0, 0 ); - if (!FNullEnt( pevInflictor )) - { - CBaseEntity *pInflictor = CBaseEntity :: Instance( pevInflictor ); - if (pInflictor) - { - vecDir = ( pInflictor->Center() - Vector ( 0, 0, 10 ) - Center() ).Normalize(); - vecDir = g_vecAttackDir = vecDir.Normalize(); - } - } - - // add to the damage total for clients, which will be sent as a single - // message at the end of the frame - // todo: remove after combining shotgun blasts? - if ( IsPlayer() ) - { - if ( pevInflictor ) - pev->dmg_inflictor = ENT(pevInflictor); - - pev->dmg_take += flTake; - - // check for godmode or invincibility - if ( pev->flags & FL_GODMODE ) - { - return 0; - } - } - - // if this is a player, move him around! - if ( ( !FNullEnt( pevInflictor ) ) && (pev->movetype == MOVETYPE_WALK) && (!pevAttacker || pevAttacker->solid != SOLID_TRIGGER) ) - { - pev->velocity = pev->velocity + vecDir * -DamageForce( flDamage ); - } - - // do the damage - pev->health -= flTake; - - // HACKHACK Don't kill monsters in a script. Let them break their scripts first - if ( m_MonsterState == MONSTERSTATE_SCRIPT ) - { - SetConditions( bits_COND_LIGHT_DAMAGE ); - return 0; - } - - if ( pev->health <= 0 ) - { - g_pevLastInflictor = pevInflictor; - - if ( bitsDamageType & DMG_ALWAYSGIB ) - { - Killed( pevAttacker, GIB_ALWAYS ); - } - else if ( bitsDamageType & DMG_NEVERGIB ) - { - Killed( pevAttacker, GIB_NEVER ); - } - else - { - Killed( pevAttacker, GIB_NORMAL ); - } - - g_pevLastInflictor = NULL; - - return 0; - } - - // react to the damage (get mad) - if ( (pev->flags & FL_MONSTER) && !FNullEnt(pevAttacker) ) - { - if ( pevAttacker->flags & (FL_MONSTER | FL_CLIENT) ) - {// only if the attack was a monster or client! - - // enemy's last known position is somewhere down the vector that the attack came from. - if (pevInflictor) - { - if (m_hEnemy == NULL || pevInflictor == m_hEnemy->pev || !HasConditions(bits_COND_SEE_ENEMY)) - { - m_vecEnemyLKP = pevInflictor->origin; - } - } - else - { - m_vecEnemyLKP = pev->origin + ( g_vecAttackDir * 64 ); - } - - MakeIdealYaw( m_vecEnemyLKP ); - - // add pain to the conditions - // !!!HACKHACK - fudged for now. Do we want to have a virtual function to determine what is light and - // heavy damage per monster class? - if ( flDamage > 0 ) - { - SetConditions(bits_COND_LIGHT_DAMAGE); - } - - if ( flDamage >= 20 ) - { - SetConditions(bits_COND_HEAVY_DAMAGE); - } - } - } - - return 1; -} - -//========================================================= -// DeadTakeDamage - takedamage function called when a monster's -// corpse is damaged. -//========================================================= -int CBaseMonster :: DeadTakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) -{ - Vector vecDir; - - // grab the vector of the incoming attack. ( pretend that the inflictor is a little lower than it really is, so the body will tend to fly upward a bit). - vecDir = Vector( 0, 0, 0 ); - if (!FNullEnt( pevInflictor )) - { - CBaseEntity *pInflictor = CBaseEntity :: Instance( pevInflictor ); - if (pInflictor) - { - vecDir = ( pInflictor->Center() - Vector ( 0, 0, 10 ) - Center() ).Normalize(); - vecDir = g_vecAttackDir = vecDir.Normalize(); - } - } - -#if 0// turn this back on when the bounding box issues are resolved. - - pev->flags &= ~FL_ONGROUND; - pev->origin.z += 1; - - // let the damage scoot the corpse around a bit. - if ( !FNullEnt(pevInflictor) && (pevAttacker->solid != SOLID_TRIGGER) ) - { - pev->velocity = pev->velocity + vecDir * -DamageForce( flDamage ); - } - -#endif - - // kill the corpse if enough damage was done to destroy the corpse and the damage is of a type that is allowed to destroy the corpse. - if ( bitsDamageType & DMG_GIB_CORPSE ) - { - if ( pev->health <= flDamage ) - { - pev->health = -50; - Killed( pevAttacker, GIB_ALWAYS ); - return 0; - } - // Accumulate corpse gibbing damage, so you can gib with multiple hits - pev->health -= flDamage * 0.1; - } - - return 1; -} - - -float CBaseMonster :: DamageForce( float damage ) -{ - float force = damage * ((32 * 32 * 72.0) / (pev->size.x * pev->size.y * pev->size.z)) * 5; - - if ( force > 1000.0) - { - force = 1000.0; - } - - return force; -} - -// -// RadiusDamage - this entity is exploding, or otherwise needs to inflict damage upon entities within a certain range. -// -// only damage ents that can clearly be seen by the explosion! - - -void RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType ) -{ - CBaseEntity *pEntity = NULL; - TraceResult tr; - float flAdjustedDamage, falloff; - Vector vecSpot; - - if ( flRadius ) - falloff = flDamage / flRadius; - else - falloff = 1.0; - - int bInWater = (UTIL_PointContents ( vecSrc ) == CONTENTS_WATER); - - vecSrc.z += 1;// in case grenade is lying on the ground - - if ( !pevAttacker ) - pevAttacker = pevInflictor; - - // iterate on all entities in the vicinity. - while ((pEntity = UTIL_FindEntityInSphere( pEntity, vecSrc, flRadius )) != NULL) - { - if ( pEntity->pev->takedamage != DAMAGE_NO ) - { - // UNDONE: this should check a damage mask, not an ignore - if ( iClassIgnore != CLASS_NONE && pEntity->Classify() == iClassIgnore ) - {// houndeyes don't hurt other houndeyes with their attack - continue; - } - - // blast's don't tavel into or out of water - if (bInWater && pEntity->pev->waterlevel == 0) - continue; - if (!bInWater && pEntity->pev->waterlevel == 3) - continue; - - vecSpot = pEntity->BodyTarget( vecSrc ); - - UTIL_TraceLine ( vecSrc, vecSpot, dont_ignore_monsters, ENT(pevInflictor), &tr ); - - if ( tr.flFraction == 1.0 || tr.pHit == pEntity->edict() ) - {// the explosion can 'see' this entity, so hurt them! - if (tr.fStartSolid) - { - // if we're stuck inside them, fixup the position and distance - tr.vecEndPos = vecSrc; - tr.flFraction = 0.0; - } - - // decrease damage for an ent that's farther from the bomb. - flAdjustedDamage = ( vecSrc - tr.vecEndPos ).Length() * falloff; - flAdjustedDamage = flDamage - flAdjustedDamage; - - if ( flAdjustedDamage < 0 ) - { - flAdjustedDamage = 0; - } - - // ALERT( at_console, "hit %s\n", STRING( pEntity->pev->classname ) ); - if (tr.flFraction != 1.0) - { - ClearMultiDamage( ); - pEntity->TraceAttack( pevInflictor, flAdjustedDamage, (tr.vecEndPos - vecSrc).Normalize( ), &tr, bitsDamageType ); - ApplyMultiDamage( pevInflictor, pevAttacker ); - } - else - { - pEntity->TakeDamage ( pevInflictor, pevAttacker, flAdjustedDamage, bitsDamageType ); - } - } - } - } -} - - -void CBaseMonster :: RadiusDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) -{ - ::RadiusDamage( pev->origin, pevInflictor, pevAttacker, flDamage, flDamage * 2.5, iClassIgnore, bitsDamageType ); -} - - -void CBaseMonster :: RadiusDamage( Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int iClassIgnore, int bitsDamageType ) -{ - ::RadiusDamage( vecSrc, pevInflictor, pevAttacker, flDamage, flDamage * 2.5, iClassIgnore, bitsDamageType ); -} - - -//========================================================= -// CheckTraceHullAttack - expects a length to trace, amount -// of damage to do, and damage type. Returns a pointer to -// the damaged entity in case the monster wishes to do -// other stuff to the victim (punchangle, etc) -// -// Used for many contact-range melee attacks. Bites, claws, etc. -//========================================================= -CBaseEntity* CBaseMonster :: CheckTraceHullAttack( float flDist, int iDamage, int iDmgType ) -{ - TraceResult tr; - - if (IsPlayer()) - UTIL_MakeVectors( pev->angles ); - else - UTIL_MakeAimVectors( pev->angles ); - - Vector vecStart = pev->origin; - vecStart.z += pev->size.z * 0.5; - Vector vecEnd = vecStart + (gpGlobals->v_forward * flDist ); - - UTIL_TraceHull( vecStart, vecEnd, dont_ignore_monsters, head_hull, ENT(pev), &tr ); - - if ( tr.pHit ) - { - CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit ); - - if ( iDamage > 0 ) - { - pEntity->TakeDamage( pev, pev, iDamage, iDmgType ); - } - - return pEntity; - } - - return NULL; -} - - -//========================================================= -// FInViewCone - returns true is the passed ent is in -// the caller's forward view cone. The dot product is performed -// in 2d, making the view cone infinitely tall. -//========================================================= -BOOL CBaseMonster :: FInViewCone ( CBaseEntity *pEntity ) -{ - Vector2D vec2LOS; - float flDot; - - UTIL_MakeVectors ( pev->angles ); - - vec2LOS = ( pEntity->pev->origin - pev->origin ).Make2D(); - vec2LOS = vec2LOS.Normalize(); - - flDot = DotProduct (vec2LOS , gpGlobals->v_forward.Make2D() ); - - if ( flDot > m_flFieldOfView ) - { - return TRUE; - } - else - { - return FALSE; - } -} - -//========================================================= -// FInViewCone - returns true is the passed vector is in -// the caller's forward view cone. The dot product is performed -// in 2d, making the view cone infinitely tall. -//========================================================= -BOOL CBaseMonster :: FInViewCone ( Vector *pOrigin ) -{ - Vector2D vec2LOS; - float flDot; - - UTIL_MakeVectors ( pev->angles ); - - vec2LOS = ( *pOrigin - pev->origin ).Make2D(); - vec2LOS = vec2LOS.Normalize(); - - flDot = DotProduct (vec2LOS , gpGlobals->v_forward.Make2D() ); - - if ( flDot > m_flFieldOfView ) - { - return TRUE; - } - else - { - return FALSE; - } -} - -//========================================================= -// FVisible - returns true if a line can be traced from -// the caller's eyes to the target -//========================================================= -BOOL CBaseEntity :: FVisible ( CBaseEntity *pEntity ) -{ - TraceResult tr; - Vector vecLookerOrigin; - Vector vecTargetOrigin; - - if (FBitSet( pEntity->pev->flags, FL_NOTARGET )) - return FALSE; - - // don't look through water - if ((pev->waterlevel != 3 && pEntity->pev->waterlevel == 3) - || (pev->waterlevel == 3 && pEntity->pev->waterlevel == 0)) - return FALSE; - - vecLookerOrigin = pev->origin + pev->view_ofs;//look through the caller's 'eyes' - vecTargetOrigin = pEntity->EyePosition(); - - UTIL_TraceLine(vecLookerOrigin, vecTargetOrigin, ignore_monsters, ignore_glass, ENT(pev)/*pentIgnore*/, &tr); - - if (tr.flFraction != 1.0) - { - return FALSE;// Line of sight is not established - } - else - { - return TRUE;// line of sight is valid. - } -} - -//========================================================= -// FVisible - returns true if a line can be traced from -// the caller's eyes to the target vector -//========================================================= -BOOL CBaseEntity :: FVisible ( const Vector &vecOrigin ) -{ - TraceResult tr; - Vector vecLookerOrigin; - - vecLookerOrigin = EyePosition();//look through the caller's 'eyes' - - UTIL_TraceLine(vecLookerOrigin, vecOrigin, ignore_monsters, ignore_glass, ENT(pev)/*pentIgnore*/, &tr); - - if (tr.flFraction != 1.0) - { - return FALSE;// Line of sight is not established - } - else - { - return TRUE;// line of sight is valid. - } -} - -/* -================ -TraceAttack -================ -*/ -void CBaseEntity::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) -{ - Vector vecOrigin = ptr->vecEndPos - vecDir * 4; - - if ( pev->takedamage ) - { - AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType ); - - int blood = BloodColor(); - - if ( blood != DONT_BLEED ) - { - SpawnBlood(vecOrigin, blood, flDamage);// a little surface blood. - TraceBleed( flDamage, vecDir, ptr, bitsDamageType ); - } - } -} - - -/* -//========================================================= -// TraceAttack -//========================================================= -void CBaseMonster::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) -{ - Vector vecOrigin = ptr->vecEndPos - vecDir * 4; - - ALERT ( at_console, "%d\n", ptr->iHitgroup ); - - - if ( pev->takedamage ) - { - AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType ); - - int blood = BloodColor(); - - if ( blood != DONT_BLEED ) - { - SpawnBlood(vecOrigin, blood, flDamage);// a little surface blood. - } - } -} -*/ - -//========================================================= -// TraceAttack -//========================================================= -void CBaseMonster :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) -{ - if ( pev->takedamage ) - { - SpawnBlood(ptr->vecEndPos, BloodColor(), flDamage);// a little surface blood. - TraceBleed( flDamage, vecDir, ptr, bitsDamageType ); - AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType ); - } -} - -/* -================ -FireBullets - -Go to the trouble of combining multiple pellets into a single damage call. -================ -*/ -void CBaseEntity::FireBullets(ULONG cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker ) -{ - static int tracerCount; - int tracer; - TraceResult tr; - Vector vecRight = gpGlobals->v_right; - Vector vecUp = gpGlobals->v_up; - - if ( pevAttacker == NULL ) - pevAttacker = pev; // the default attacker is ourselves - - // Vector vecSrc = pev->origin + gpGlobals->v_forward * 10; - //vecSrc.z = pevShooter->absmin.z + pevShooter->size.z * 0.7; - //vecSrc.z = pev->origin.z + (pev->view_ofs.z - 4); - ClearMultiDamage(); - gMultiDamage.type = DMG_BULLET | DMG_NEVERGIB; - - for (ULONG iShot = 1; iShot <= cShots; iShot++) - { - // get circular gaussian spread - float x, y, z; - do { - x = RANDOM_FLOAT(-0.5,0.5) + RANDOM_FLOAT(-0.5,0.5); - y = RANDOM_FLOAT(-0.5,0.5) + RANDOM_FLOAT(-0.5,0.5); - z = x*x+y*y; - } while (z > 1); - - Vector vecDir = vecDirShooting + - x * vecSpread.x * vecRight + - y * vecSpread.y * vecUp; - Vector vecEnd; - - vecEnd = vecSrc + vecDir * flDistance; - UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev)/*pentIgnore*/, &tr); - - tracer = 0; - if (iTracerFreq != 0 && (tracerCount++ % iTracerFreq) == 0) - { - Vector vecTracerSrc; - - if ( IsPlayer() ) - {// adjust tracer position for player - vecTracerSrc = vecSrc + Vector ( 0 , 0 , -4 ) + gpGlobals->v_right * 2 + gpGlobals->v_forward * 16; - } - else - { - vecTracerSrc = vecSrc; - } - - if ( iTracerFreq != 1 ) // guns that always trace also always decal - tracer = 1; - switch( iBulletType ) - { - case BULLET_PLAYER_MP5: - case BULLET_MONSTER_MP5: - case BULLET_MONSTER_9MM: - case BULLET_MONSTER_12MM: - default: - break; - } - } - // do damage, paint decals - if (tr.flFraction != 1.0) - { - CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit); - - if ( iDamage ) - { - pEntity->TraceAttack(pevAttacker, iDamage, vecDir, &tr, DMG_BULLET | ((iDamage > 16) ? DMG_ALWAYSGIB : DMG_NEVERGIB) ); - - TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType); - DecalGunshot( &tr, iBulletType ); - } - else switch(iBulletType) - { - default: - case BULLET_PLAYER_9MM: - pEntity->TraceAttack(pevAttacker, gSkillData.plrDmg9MM, vecDir, &tr, DMG_BULLET); - break; - - case BULLET_PLAYER_MP5: - pEntity->TraceAttack(pevAttacker, gSkillData.plrDmgMP5, vecDir, &tr, DMG_BULLET); - break; - - case BULLET_PLAYER_BUCKSHOT: - // make distance based! - pEntity->TraceAttack(pevAttacker, gSkillData.plrDmgBuckshot, vecDir, &tr, DMG_BULLET); - break; - - case BULLET_PLAYER_357: - pEntity->TraceAttack(pevAttacker, gSkillData.plrDmg357, vecDir, &tr, DMG_BULLET); - break; - - case BULLET_MONSTER_9MM: - pEntity->TraceAttack(pevAttacker, gSkillData.monDmg9MM, vecDir, &tr, DMG_BULLET); - - TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType); - DecalGunshot( &tr, iBulletType ); - - break; - - case BULLET_MONSTER_MP5: - pEntity->TraceAttack(pevAttacker, gSkillData.monDmgMP5, vecDir, &tr, DMG_BULLET); - - TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType); - DecalGunshot( &tr, iBulletType ); - - break; - - case BULLET_MONSTER_12MM: - pEntity->TraceAttack(pevAttacker, gSkillData.monDmg12MM, vecDir, &tr, DMG_BULLET); - if ( !tracer ) - { - TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType); - DecalGunshot( &tr, iBulletType ); - } - break; - - case BULLET_NONE: // FIX - pEntity->TraceAttack(pevAttacker, 50, vecDir, &tr, DMG_CLUB); - TEXTURETYPE_PlaySound(&tr, vecSrc, vecEnd, iBulletType); - // only decal glass - if ( !FNullEnt(tr.pHit) && VARS(tr.pHit)->rendermode != 0) - { - UTIL_DecalTrace( &tr, DECAL_GLASSBREAK1 + RANDOM_LONG(0,2) ); - } - - break; - } - } - // make bullet trails - UTIL_BubbleTrail( vecSrc, tr.vecEndPos, (flDistance * tr.flFraction) / 64.0 ); - } - ApplyMultiDamage(pev, pevAttacker); -} - - -void CBaseEntity :: TraceBleed( float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ) -{ - if (BloodColor() == DONT_BLEED) - return; - - if (flDamage == 0) - return; - - if (! (bitsDamageType & (DMG_CRUSH | DMG_BULLET | DMG_SLASH | DMG_BLAST | DMG_CLUB | DMG_MORTAR))) - return; - - // make blood decal on the wall! - TraceResult Bloodtr; - Vector vecTraceDir; - float flNoise; - int cCount; - int i; - -/* - if ( !IsAlive() ) - { - // dealing with a dead monster. - if ( pev->max_health <= 0 ) - { - // no blood decal for a monster that has already decalled its limit. - return; - } - else - { - pev->max_health--; - } - } -*/ - - if (flDamage < 10) - { - flNoise = 0.1; - cCount = 1; - } - else if (flDamage < 25) - { - flNoise = 0.2; - cCount = 2; - } - else - { - flNoise = 0.3; - cCount = 4; - } - - for ( i = 0 ; i < cCount ; i++ ) - { - vecTraceDir = vecDir * -1;// trace in the opposite direction the shot came from (the direction the shot is going) - - vecTraceDir.x += RANDOM_FLOAT( -flNoise, flNoise ); - vecTraceDir.y += RANDOM_FLOAT( -flNoise, flNoise ); - vecTraceDir.z += RANDOM_FLOAT( -flNoise, flNoise ); - - UTIL_TraceLine( ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * -172, ignore_monsters, ENT(pev), &Bloodtr); - - if ( Bloodtr.flFraction != 1.0 ) - { - UTIL_BloodDecalTrace( &Bloodtr, BloodColor() ); - } - } -} - -//========================================================= -//========================================================= -void CBaseMonster :: MakeDamageBloodDecal ( int cCount, float flNoise, TraceResult *ptr, const Vector &vecDir ) -{ - // make blood decal on the wall! - TraceResult Bloodtr; - Vector vecTraceDir; - int i; - - if ( !IsAlive() ) - { - // dealing with a dead monster. - if ( pev->max_health <= 0 ) - { - // no blood decal for a monster that has already decalled its limit. - return; - } - else - { - pev->max_health--; - } - } - - for ( i = 0 ; i < cCount ; i++ ) - { - vecTraceDir = vecDir; - - vecTraceDir.x += RANDOM_FLOAT( -flNoise, flNoise ); - vecTraceDir.y += RANDOM_FLOAT( -flNoise, flNoise ); - vecTraceDir.z += RANDOM_FLOAT( -flNoise, flNoise ); - - UTIL_TraceLine( ptr->vecEndPos, ptr->vecEndPos + vecTraceDir * 172, ignore_monsters, ENT(pev), &Bloodtr); - -/* - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_SHOWLINE); - WRITE_COORD( ptr->vecEndPos.x ); - WRITE_COORD( ptr->vecEndPos.y ); - WRITE_COORD( ptr->vecEndPos.z ); - - WRITE_COORD( Bloodtr.vecEndPos.x ); - WRITE_COORD( Bloodtr.vecEndPos.y ); - WRITE_COORD( Bloodtr.vecEndPos.z ); - MESSAGE_END(); -*/ - - if ( Bloodtr.flFraction != 1.0 ) - { - UTIL_BloodDecalTrace( &Bloodtr, BloodColor() ); - } - } -} diff --git a/ricochet/dlls/decals.h b/ricochet/dlls/decals.h deleted file mode 100644 index 0cb87ee..0000000 --- a/ricochet/dlls/decals.h +++ /dev/null @@ -1,75 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef DECALS_H -#define DECALS_H - -// -// Dynamic Decals -// -enum decal_e -{ - DECAL_GUNSHOT1 = 0, - DECAL_GUNSHOT2, - DECAL_GUNSHOT3, - DECAL_GUNSHOT4, - DECAL_GUNSHOT5, - DECAL_LAMBDA1, - DECAL_LAMBDA2, - DECAL_LAMBDA3, - DECAL_LAMBDA4, - DECAL_LAMBDA5, - DECAL_LAMBDA6, - DECAL_SCORCH1, - DECAL_SCORCH2, - DECAL_BLOOD1, - DECAL_BLOOD2, - DECAL_BLOOD3, - DECAL_BLOOD4, - DECAL_BLOOD5, - DECAL_BLOOD6, - DECAL_YBLOOD1, - DECAL_YBLOOD2, - DECAL_YBLOOD3, - DECAL_YBLOOD4, - DECAL_YBLOOD5, - DECAL_YBLOOD6, - DECAL_GLASSBREAK1, - DECAL_GLASSBREAK2, - DECAL_GLASSBREAK3, - DECAL_BIGSHOT1, - DECAL_BIGSHOT2, - DECAL_BIGSHOT3, - DECAL_BIGSHOT4, - DECAL_BIGSHOT5, - DECAL_SPIT1, - DECAL_SPIT2, - DECAL_BPROOF1, // Bulletproof glass decal - DECAL_GARGSTOMP1, // Gargantua stomp crack - DECAL_SMALLSCORCH1, // Small scorch mark - DECAL_SMALLSCORCH2, // Small scorch mark - DECAL_SMALLSCORCH3, // Small scorch mark - DECAL_MOMMABIRTH, // Big momma birth splatter - DECAL_MOMMASPLAT, -}; - -typedef struct -{ - char *name; - int index; -} DLL_DECALLIST; - -extern DLL_DECALLIST gDecals[]; - -#endif // DECALS_H diff --git a/ricochet/dlls/disc_arena.cpp b/ricochet/dlls/disc_arena.cpp deleted file mode 100644 index 30919c3..0000000 --- a/ricochet/dlls/disc_arena.cpp +++ /dev/null @@ -1,1048 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Handles the arena portion of discwar -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "gamerules.h" -#include "weapons.h" -#include "discwar.h" -#include "disc_arena.h" -#include "disc_objects.h" - -int g_iNextArenaGroupInfo = 0; - -void ClientUserInfoChanged( edict_t *pEntity, char *infobuffer ); -edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ); -void respawn(entvars_t* pev, BOOL fCopyCorpse); -extern int gmsgStartRnd; -extern int gmsgEndRnd; -extern int gmsgTeamInfo; -extern int g_iPlayersPerTeam; -extern int g_iMapTurnedOffArena; - -CDiscArena *g_pArenaList[ MAX_ARENAS ]; - -char *g_szCountDownVox[6] = -{ - "die", - "one", - "two", - "three", - "four", -}; - -char *g_szTeamNames[3] = -{ - "", - "red", - "blue", -}; - -int InArenaMode() -{ - if ( g_iMapTurnedOffArena ) - return FALSE; - - if ( gpGlobals->maxClients == 1 || (CVAR_GET_FLOAT("rc_arena") == 0) ) - return FALSE; - - return TRUE; -} - -LINK_ENTITY_TO_CLASS( disc_arena, CDiscArena ); - -// NOTE: -// We store queue position in pev->playerclass, so it's automatically pushed -// down to the client. The scoreboard uses pev->playerclass to display the -// positions of the players in the queue. -void CDiscArena::Spawn( void ) -{ - pev->groupinfo = 1 << (g_iNextArenaGroupInfo++); - Reset(); - - // Initialize - m_iMaxRounds = CVAR_GET_FLOAT("rc_rounds"); - m_iPlayersPerTeam = g_iPlayersPerTeam; - SetThink( NULL ); -} - -void CDiscArena::Reset( void ) -{ - // Remove all clients in the queue - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if (pPlayer && (pPlayer->m_pCurrentArena == this) && pPlayer->m_bHasDisconnected != TRUE ) - { - RemoveClient( pPlayer ); - - // Move her into spectator mode - //MoveToSpectator( pPlayer ); - } - } - - m_pPlayerQueue = NULL; - m_iPlayers = 0; - m_flTimeLimitOver = 0; - m_bShownTimeWarning = FALSE; - m_iArenaState = ARENA_WAITING_FOR_PLAYERS; - memset( m_hCombatants, 0, sizeof( m_hCombatants ) ); - - SetThink( NULL ); - pev->nextthink = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: Start a battle. Spawn all the players, and begin the countdown. -//----------------------------------------------------------------------------- -void CDiscArena::StartBattle( void ) -{ - m_iCurrRound = 0; - m_iTeamOneScore = m_iTeamTwoScore = 0; - - // First, set all players in this arena to "didn't play" - int i; - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if (pPlayer && (pPlayer->m_pCurrentArena == this) && pPlayer->m_bHasDisconnected != TRUE ) - pPlayer->m_iLastGameResult = GAME_DIDNTPLAY; - } - - // Get the players in the battle - for ( i = 0; i < (m_iPlayersPerTeam * 2); i++ ) - { - CBasePlayer *pCurr; - - // Check to see if this slot's already full - if ( m_hCombatants[ i ] ) - { - pCurr = (CBasePlayer*)(CBaseEntity*)m_hCombatants[ i ]; - } - else - { - // Pop a new player from the queue - pCurr = GetNextPlayer(); - if (!pCurr) - { - // Couldnt get enough players. Reset. - Reset(); - return; - } - } - - // Set her team number - if ( i < m_iPlayersPerTeam ) - pCurr->pev->team = 1; - else - pCurr->pev->team = 2; - pCurr->pev->iuser4 = pCurr->pev->team; - - char sz[128]; - sprintf(sz, "Arena %d", pev->groupinfo ); - MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo ); - WRITE_BYTE( pCurr->entindex() ); - WRITE_STRING( sz ); - MESSAGE_END(); - - // Add her to the list of combatants - m_hCombatants[ i ] = pCurr; - - // Force her to update her clientinfo, so her colors match her team - ClientUserInfoChanged( pCurr->edict(), g_engfuncs.pfnGetInfoKeyBuffer( pCurr->edict() ) ); - } - - // Start the first round - StartRound(); -} - -//----------------------------------------------------------------------------- -// Purpose: Start the next round in the match -//----------------------------------------------------------------------------- -void CDiscArena::StartRound( void ) -{ - m_iCurrRound++; - m_iSecondsTillStart = ARENA_TIME_PREBATTLE; - m_flTimeLimitOver = gpGlobals->time + ARENA_TIME_ROUNDLIMIT; - - RestoreWorldObjects(); - - // Tell the clients - for ( int iPlayerNum = 1; iPlayerNum <= gpGlobals->maxClients; iPlayerNum++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( iPlayerNum ); - - if (pPlayer && (pPlayer->pev->groupinfo & pev->groupinfo) && (pPlayer->m_bHasDisconnected != TRUE) ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgStartRnd, NULL, pPlayer->edict() ); - WRITE_BYTE( m_iCurrRound ); - WRITE_BYTE( m_iSecondsTillStart ); - WRITE_BYTE( (m_iPlayersPerTeam * 2) ); - - // Send down all the players in the round - for ( int j = 0; j < (m_iPlayersPerTeam * 2); j++ ) - { - if (m_hCombatants[j]) - WRITE_SHORT( ((CBaseEntity*)m_hCombatants[j])->entindex() ); - } - - MESSAGE_END(); - } - } - - // Spawn all the players in the round - for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ ) - { - CBasePlayer *pPlayer = ((CBasePlayer*)(CBaseEntity*)m_hCombatants[i]); - - if ( pPlayer ) - { - // make sure the player's groupinfo is set the arena's groupinfo - pPlayer->pev->groupinfo = pev->groupinfo; - - // is the player an observer? - if ( pPlayer->IsObserver() ) - { - SpawnCombatant( pPlayer ); - } - - // Remove any powerups - pPlayer->RemoveAllPowerups(); - } - } - - // Start counting down - m_iArenaState = ARENA_COUNTDOWN; - pev->nextthink = gpGlobals->time + 0.1; - SetThink( &CDiscArena::CountDownThink ); -} - -//----------------------------------------------------------------------------- -// Purpose: Make sure all the Combatants in the game a valid. Return FALSE if not. -//----------------------------------------------------------------------------- -int CDiscArena::ValidateCombatants( void ) -{ - for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ ) - { - CBasePlayer *pPlayer = ((CBasePlayer*)(CBaseEntity*)m_hCombatants[i]); - - if ( !pPlayer ) - return FALSE; - if ( pPlayer->m_bHasDisconnected ) - return FALSE; - } - - return TRUE; -} - -//----------------------------------------------------------------------------- -// Purpose: Restore all the world objects -//----------------------------------------------------------------------------- -void CDiscArena::RestoreWorldObjects( void ) -{ - CBaseEntity *pFunc = NULL; - while ((pFunc = UTIL_FindEntityByClassname( pFunc, "func_plat_toggleremove" )) != NULL) - { - ((CPlatToggleRemove*)pFunc)->Reset(); - } - while ((pFunc = UTIL_FindEntityByClassname( pFunc, "func_disctoggle" )) != NULL) - { - ((CDiscTarget*)pFunc)->Reset(); - } - - // Disable powerups - while ((pFunc = UTIL_FindEntityByClassname( pFunc, "item_powerup" )) != NULL) - { - ((CDiscwarPowerup*)pFunc)->Disable(); - } -} - -void CDiscArena::BattleThink( void ) -{ - if ( gpGlobals->time >= m_flTimeLimitOver - 1.0 ) - { - pev->nextthink = gpGlobals->time + 1.0; - SetThink( &CDiscArena::TimeOver ); - return; - } - - if ( !CheckBattleOver() ) - { - pev->nextthink = gpGlobals->time + 1.0; - } -} - -//----------------------------------------------------------------------------- -// Purpose: Countdown to the round start -//----------------------------------------------------------------------------- -void CDiscArena::CountDownThink( void ) -{ - // Freeze everyone until there's 3 seconds to go - if ( m_iSecondsTillStart == 3 ) - { - for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ ) - { - if (m_hCombatants[i]) - ((CBaseEntity*)m_hCombatants[i])->pev->maxspeed = 320; - } - } - - m_iSecondsTillStart--; - - // Play countdown VOX - if (m_iSecondsTillStart < 5) - { - // Speech - for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ ) - { - if (m_hCombatants[i]) - ((CBasePlayer*)(CBaseEntity*)m_hCombatants[i])->ClientHearVox( g_szCountDownVox[ m_iSecondsTillStart ] ); - } - } - - // Send the message to the clients in the arena - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if (pPlayer && (pPlayer->pev->groupinfo & pev->groupinfo) && pPlayer->m_bHasDisconnected != TRUE) - { - MESSAGE_BEGIN( MSG_ONE, gmsgStartRnd, NULL, pPlayer->edict() ); - WRITE_BYTE( m_iCurrRound ); - WRITE_BYTE( m_iSecondsTillStart ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - } - } - - if (m_iSecondsTillStart) - { - pev->nextthink = gpGlobals->time + 1.0; - } - else - { - m_iArenaState = ARENA_BATTLE_IN_PROGRESS; - - // Enable powerups - CBaseEntity *pFunc = NULL; - while ((pFunc = UTIL_FindEntityByClassname( pFunc, "item_powerup" )) != NULL) - { - ((CDiscwarPowerup*)pFunc)->Enable(); - } - - pev->nextthink = gpGlobals->time + 1.0; - SetThink( &CDiscArena::BattleThink ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: A player in the battle has died. See if we need to restart the battle. -//----------------------------------------------------------------------------- -void CDiscArena::PlayerKilled( CBasePlayer *pPlayer ) -{ - // Check to see if the battle's over in 5 seconds - if ( m_iArenaState == ARENA_BATTLE_IN_PROGRESS || m_iArenaState == ARENA_COUNTDOWN ) - { - if ( !CheckBattleOver() ) - { - pev->nextthink = gpGlobals->time + 0.5; - SetThink( &CDiscArena::CheckOverThink ); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: A player in the battle has respawned. Move them to observer mode. -//----------------------------------------------------------------------------- -void CDiscArena::PlayerRespawned( CBasePlayer *pPlayer ) -{ - if ( m_iArenaState == ARENA_BATTLE_IN_PROGRESS ) - { - // Move the player into Spectator mode - MoveToSpectator( pPlayer ); - } - else if ( m_iArenaState == ARENA_SHOWING_SCORES && ( m_iTeamOneScore >= m_iMaxRounds || m_iTeamTwoScore >= m_iMaxRounds ) ) - { - // Battle is over. If there's only 2 players in the game, just respawn. - // Otherwise, move to spectator. - int iNumPlayers = 0; - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - if (pPlayer && pPlayer->m_bHasDisconnected != TRUE) - iNumPlayers++; - } - - // Move the player into Spectator mode if there are more players - if ( iNumPlayers > 2 ) - MoveToSpectator( pPlayer ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Move the player to a spectating position -//----------------------------------------------------------------------------- -void CDiscArena::MoveToSpectator( CBasePlayer *pPlayer ) -{ - // Find the spectator spawn position - CBaseEntity *pSpot = UTIL_FindEntityByClassname( NULL, "info_player_spectator"); - if ( pSpot ) - { - pPlayer->StartObserver( pSpot->pev->origin, pSpot->pev->angles); - } - else - { - // Find any spawn point - edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer ); - pPlayer->StartObserver( VARS(pentSpawnSpot)->origin, VARS(pentSpawnSpot)->angles); - } - - pPlayer->pev->team = 0; - pPlayer->Observer_SetMode( OBS_LOCKEDVIEW ); -} - -//----------------------------------------------------------------------------- -// Purpose: Battle is over. -//----------------------------------------------------------------------------- -void CDiscArena::BattleOver( void ) -{ - pev->nextthink = gpGlobals->time + 3; - SetThink( &CDiscArena::FinishedThink ); - - m_iSecondsTillStart = ARENA_TIME_VIEWSCORES; - m_iArenaState = ARENA_SHOWING_SCORES; - - RestoreWorldObjects(); -} - -//----------------------------------------------------------------------------- -// Purpose: Round timelimit has been hit -//----------------------------------------------------------------------------- -void CDiscArena::TimeOver( void ) -{ - // Display the 10 second warning first - if ( !m_bShownTimeWarning ) - { - m_bShownTimeWarning = TRUE; - - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if (pPlayer && (pPlayer->pev->groupinfo & pev->groupinfo) && pPlayer->m_bHasDisconnected != TRUE) - ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "#Time_Warning" ); - } - - pev->nextthink = gpGlobals->time + 10; - } - else - { - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if (pPlayer && (pPlayer->pev->groupinfo & pev->groupinfo) && (pPlayer->m_bHasDisconnected != TRUE) ) - ClientPrint( pPlayer->pev, HUD_PRINTCENTER, "#Time_Over" ); - } - - // Increment both scores to force the game to end - m_iTeamOneScore++; - m_iTeamTwoScore++; - - BattleOver(); - } -} - -bool CDiscArena::CheckBattleOver( void ) -{ - bool bTeamOneAlive = false; - bool bTeamTwoAlive = false; - - // See if the battle is finished - int i; - for ( i = 0; i < (m_iPlayersPerTeam * 2); i++ ) - { - if ( m_hCombatants[i] != NULL && ((CBasePlayer*)(CBaseEntity*)m_hCombatants[i])->IsAlive() ) - { - if ( ((CBaseEntity*)m_hCombatants[i])->pev->team == 1 ) - bTeamOneAlive = true; - else if ( ((CBaseEntity*)m_hCombatants[i])->pev->team == 2 ) - bTeamTwoAlive = true; - } - } - - if ( !bTeamOneAlive || !bTeamTwoAlive ) - { - // Battle is finished. - if (bTeamOneAlive) - { - m_iWinningTeam = 1; - m_iTeamOneScore++; - } - else - { - m_iWinningTeam = 2; - m_iTeamTwoScore++; - } - - int iTeamInTheLead = 0; - if ( m_iTeamOneScore > m_iTeamTwoScore ) - iTeamInTheLead = 1; - else if ( m_iTeamOneScore < m_iTeamTwoScore ) - iTeamInTheLead = 2; - - // Send the message to the clients in the arena - for ( int iPlayerNum = 1; iPlayerNum <= gpGlobals->maxClients; iPlayerNum++ ) - { - CBasePlayer *pPlayer = (CBasePlayer*)UTIL_PlayerByIndex( iPlayerNum ); - - if (pPlayer && (pPlayer->pev->groupinfo & pev->groupinfo) && (pPlayer->m_bHasDisconnected != TRUE) ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgEndRnd, NULL, pPlayer->edict() ); - WRITE_BYTE( m_iCurrRound ); - WRITE_BYTE( 1 ); - WRITE_BYTE( m_iPlayersPerTeam ); - - // Send down the winners of this round - for (i = 0; i < (m_iPlayersPerTeam * 2); i++) - { - CBasePlayer *pPlayer = (CBasePlayer*)(CBaseEntity*)m_hCombatants[i]; - if ( !pPlayer || pPlayer->pev->team != m_iWinningTeam ) - continue; - - WRITE_SHORT( pPlayer->entindex() ); - } - - // Send down the team who's winning the battle now - if ( iTeamInTheLead == 0 ) - { - // It's a draw at the moment. - // No need to send down player data. - WRITE_BYTE( 0 ); - } - else - { - WRITE_BYTE( m_iPlayersPerTeam ); - // Send down the winners of this round - for (i = 0; i < (m_iPlayersPerTeam * 2); i++) - { - CBasePlayer *pPlayer = (CBasePlayer*)(CBaseEntity*)m_hCombatants[i]; - if ( !pPlayer || pPlayer->pev->team != iTeamInTheLead ) - continue; - - WRITE_SHORT( ((CBaseEntity*)m_hCombatants[i])->entindex() ); - } - } - - // Send down the scores - if ( iTeamInTheLead == 1 ) - { - WRITE_BYTE( m_iTeamOneScore ); - WRITE_BYTE( m_iTeamTwoScore ); - } - else - { - WRITE_BYTE( m_iTeamTwoScore ); - WRITE_BYTE( m_iTeamOneScore ); - } - - // Send down over or not - if ( m_iTeamOneScore == m_iMaxRounds || m_iTeamTwoScore == m_iMaxRounds ) - WRITE_BYTE( 1 ); - else - WRITE_BYTE( 0 ); - - MESSAGE_END(); - } - } - - BattleOver(); - return true; - } - - return false; -} - -//----------------------------------------------------------------------------- -// Purpose: Check to see if the Battle is over -//----------------------------------------------------------------------------- -void CDiscArena::CheckOverThink( void ) -{ - if ( !CheckBattleOver() ) - { - if ( m_iArenaState == ARENA_COUNTDOWN ) - { - pev->nextthink = gpGlobals->time + 0.1; - SetThink( &CDiscArena::CountDownThink ); - } - else - { - pev->nextthink = gpGlobals->time + 0.1; - SetThink( &CDiscArena::BattleThink ); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Show who won, and then restart the round -//----------------------------------------------------------------------------- -void CDiscArena::FinishedThink( void ) -{ - m_iSecondsTillStart--; - - if (m_iSecondsTillStart) - { - pev->nextthink = gpGlobals->time + 1.0; - } - else - { - SetThink( NULL ); - - // Tell the clients to remove the "Won" window - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if (pPlayer && (pPlayer->pev->groupinfo & pev->groupinfo) && pPlayer->m_bHasDisconnected != TRUE) - { - MESSAGE_BEGIN( MSG_ONE, gmsgEndRnd, NULL, pPlayer->edict() ); - WRITE_BYTE( m_iCurrRound ); - WRITE_BYTE( 0 ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - } - } - - // Round is over. See if the match is over too. - if ( m_iTeamOneScore >= m_iMaxRounds || m_iTeamTwoScore >= m_iMaxRounds ) - { - // Remove the losers from the combatants list - for (int i = 0; i < (m_iPlayersPerTeam * 2); i++) - { - CBasePlayer *pPlayer = (CBasePlayer*)(CBaseEntity*)m_hCombatants[i]; - if (!pPlayer) - continue; - if ( pPlayer->pev->team == m_iWinningTeam ) - { - pPlayer->m_iDeaths += 1; - pPlayer->m_iLastGameResult = GAME_WON; - continue; - } - - pPlayer->m_iLastGameResult = GAME_LOST; - m_hCombatants[i] = NULL; - } - - // Then start the next Battle - PostBattle(); - } - else - { - // Start the next round - StartRound(); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Spawn a player in this battle -//----------------------------------------------------------------------------- -void CDiscArena::SpawnCombatant( CBasePlayer *pPlayer ) -{ - // Make sure she's out of spectator mode - pPlayer->StopObserver(); - - // Spawn - g_pGameRules->GetPlayerSpawnSpot( pPlayer ); - - // Prevent movement for a couple of seconds - pPlayer->pev->maxspeed = 1; -} - -//----------------------------------------------------------------------------- -// Purpose: Start a Battle -//----------------------------------------------------------------------------- -void CDiscArena::StartBattleThink( void ) -{ - StartBattle(); -} - -//----------------------------------------------------------------------------- -// Purpose: Prevent firing during prematch -//----------------------------------------------------------------------------- -bool CDiscArena::AllowedToFire( void ) -{ - return ( m_iArenaState == ARENA_BATTLE_IN_PROGRESS ); -} - -//----------------------------------------------------------------------------- -// Purpose: New client was added to the arena -//----------------------------------------------------------------------------- -void CDiscArena::AddClient( CBasePlayer *pPlayer, BOOL bCheckStart ) -{ - // Remove them from any arena they're currently in - if ( pPlayer->m_pCurrentArena != NULL ) - pPlayer->m_pCurrentArena->RemoveClient( pPlayer ); - - m_iPlayers++; - - pPlayer->pev->groupinfo = pev->groupinfo; - - // Add her to the queue - AddPlayerToQueue( pPlayer ); - pPlayer->m_pCurrentArena = this; - - // Only check a restart if the flag is set - if ( bCheckStart ) - { - // Start a game if there's none going, and we now have enough players - // Allow starting of games if there aren't enough players, but there's more than 1 on the svr. - //if ( (m_iPlayersPerTeam > 1) && (m_iPlayers > 1) && (m_iPlayers < (m_iPlayersPerTeam * 2)) ) - //m_iPlayersPerTeam = 1; - // If we're in a battle, and the players-per-team isn't the map's setting, restart the battle - if ( (m_iArenaState == ARENA_WAITING_FOR_PLAYERS) && ( m_iPlayers >= (m_iPlayersPerTeam * 2) ) ) - { - // Start a battle in a second to let the clients learn about this new player - SetThink( &CDiscArena::StartBattleThink ); - pev->nextthink = gpGlobals->time + 1.0; - } - else - { - // Move her into spectator mode - MoveToSpectator( pPlayer ); - } - } -} - -//----------------------------------------------------------------------------- -// Purpose: Client was removed from the arena -//----------------------------------------------------------------------------- -void CDiscArena::RemoveClient( CBasePlayer *pPlayer ) -{ - m_iPlayers--; - - pPlayer->pev->groupinfo = 0; - pPlayer->m_pCurrentArena = NULL; - - // Is she in the current battle? - if ( pPlayer->pev->playerclass != 0 ) - { - // No, she's in the queue, so remove her. - RemovePlayerFromQueue( pPlayer ); - } - else if ( m_iArenaState != ARENA_WAITING_FOR_PLAYERS ) - { - // This team loses - m_iWinningTeam = (pPlayer->pev->team == 1) ? 2 : 1; - if ( m_iWinningTeam == 1 ) - m_iTeamOneScore = m_iMaxRounds - 1; // -1 because we'll get 1 point for winning this round in CheckOverThink - else - m_iTeamTwoScore = m_iMaxRounds - 1; // -1 because we'll get 1 point for winning this round in CheckOverThink - - // Find the player in the combatant list - for ( int i = 0; i < (m_iPlayersPerTeam * 2); i++ ) - { - // Check to see if this slot's already full - if ( m_hCombatants[ i ] == pPlayer ) - { - m_hCombatants[i] = NULL; - break; - } - } - - CheckOverThink(); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Add a player to the end of the queue -//----------------------------------------------------------------------------- -void CDiscArena::AddPlayerToQueue( CBasePlayer *pPlayer ) -{ - if ( !pPlayer ) - return; - - if ( m_pPlayerQueue ) - { - CBasePlayer *pCurr = (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue; - while ( pCurr->m_pNextPlayer ) - { - pCurr = (CBasePlayer*)(CBaseEntity*)pCurr->m_pNextPlayer; - } - - pCurr->m_pNextPlayer = pPlayer; - pPlayer->pev->playerclass = pCurr->pev->playerclass + 1; - } - else - { - m_pPlayerQueue = pPlayer; - pPlayer->pev->playerclass = 1; - } - - pPlayer->m_pNextPlayer = NULL; -} - -//----------------------------------------------------------------------------- -// Purpose: Remove a player from the queue -//----------------------------------------------------------------------------- -void CDiscArena::RemovePlayerFromQueue( CBasePlayer *pPlayer ) -{ - bool bFoundHer = false; - - if ( !pPlayer ) - return; - - CBasePlayer *pCurr = (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue; - CBasePlayer *pPrev = NULL; - - while ( pCurr ) - { - if (pCurr == pPlayer ) - { - bFoundHer = true; - if (pPrev) - pPrev->m_pNextPlayer = pCurr->m_pNextPlayer; - else - m_pPlayerQueue = pCurr->m_pNextPlayer; - } - else - { - pPrev = pCurr; - - // Adjust all the following player's queue positions - if (bFoundHer) - pCurr->pev->playerclass--; - } - - pCurr = (CBasePlayer*)(CBaseEntity*)pCurr->m_pNextPlayer; - } - - pPlayer->m_pNextPlayer = NULL; - pPlayer->pev->playerclass = 0; -} - -//----------------------------------------------------------------------------- -// Purpose: Get the next player from the queue, and shuffle the rest up -//----------------------------------------------------------------------------- -CBasePlayer *CDiscArena::GetNextPlayer( void ) -{ - if ( m_pPlayerQueue == NULL ) - return NULL; - - CBasePlayer *pCurr = (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue; - RemovePlayerFromQueue( (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue ); - - return pCurr; -} - -//----------------------------------------------------------------------------- -// Returns TRUE if the Arena is full -int CDiscArena::IsFull( void ) -{ - if ( m_iPlayers < (m_iPlayersPerTeam * 2) ) - return FALSE; - - return TRUE; -} - -//----------------------------------------------------------------------------- -// Returns the first player in the Arena's queue, if any -CBasePlayer *CDiscArena::GetFirstSparePlayer( void ) -{ - if ( m_pPlayerQueue == NULL ) - return NULL; - - return (CBasePlayer*)(CBaseEntity*)m_pPlayerQueue; -} - -//----------------------------------------------------------------------------- -// Add a client to an Arena. Find the first arena that doesn't have two -// players in it, and add this player to that. If we find a third player -// Spectating another arena, grab them and add them to this player's arena. -void AddClientToArena( CBasePlayer *pPlayer ) -{ - // First, find an arena for this player to be put into - for (int i = 0; i < MAX_ARENAS; i++) - { - if ( g_pArenaList[i]->IsFull() == FALSE ) - { - int iArenaNumber = i; - - g_pArenaList[iArenaNumber]->AddClient( pPlayer, TRUE ); - - bool bFoundOne = TRUE; - // Now, if this arena's not full, try to find more player to join her - while ( (g_pArenaList[iArenaNumber]->IsFull() == FALSE) && bFoundOne ) - { - bFoundOne = FALSE; - - // Cycle through all the arenas and find a spare player - for (int j = 0; j < MAX_ARENAS; j++) - { - CBasePlayer *pSparePlayer = g_pArenaList[j]->GetFirstSparePlayer(); - if (pSparePlayer && pSparePlayer != pPlayer) - { - g_pArenaList[j]->RemoveClient( pSparePlayer ); - g_pArenaList[iArenaNumber]->AddClient( pSparePlayer, TRUE ); - bFoundOne = TRUE; - break; - } - } - } - - // If we couldn't find another player for this arena, just add them to an existing arena - if ( g_pArenaList[iArenaNumber]->IsFull() == FALSE ) - { - // Add to the first full arena - for (int j = 0; j < MAX_ARENAS; j++) - { - if ( g_pArenaList[j]->IsFull() ) - { - // Remove from current - g_pArenaList[iArenaNumber]->RemoveClient( pPlayer ); - - // Add to full one - iArenaNumber = j; - g_pArenaList[iArenaNumber]->AddClient( pPlayer, TRUE ); - break; - } - } - } - - //ALERT( at_console, "ADDED %s to Arena %d\n", STRING(pPlayer->pev->netname), iArenaNumber ); - return; - } - } -} - -//----------------------------------------------------------------------------- -// Put the specified group of players into the current arena -int AddPlayers( int iPlayers, int iArenaNum ) -{ - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if (pPlayer && (pPlayer->m_pCurrentArena == NULL) && (pPlayer->m_bHasDisconnected != TRUE) ) - { - if ( pPlayer->m_iLastGameResult != iPlayers ) - continue; - - g_pArenaList[iArenaNum]->AddClient( pPlayer, FALSE ); - if ( g_pArenaList[iArenaNum]->IsFull() ) - iArenaNum++; - } - } - - return iArenaNum; -} - -//----------------------------------------------------------------------------- -// Take all the players not in battles and shuffle them into new groups -void ShufflePlayers( void ) -{ - int iArenaNum = 0; - - // Reset all Arenas - int i; - for ( i = 0; i < MAX_ARENAS; i++) - { - g_pArenaList[i]->Reset(); - } - - // Play the winners off against the other winners first - iArenaNum = AddPlayers( GAME_WON, iArenaNum ); - // First, add the players who didn't play at all - iArenaNum = AddPlayers( GAME_DIDNTPLAY, iArenaNum ); - // Then add the losers - iArenaNum = AddPlayers( GAME_LOST, iArenaNum ); - - // Then tell all full arenas to start - for (i = 0; i < MAX_ARENAS; i++) - { - if ( g_pArenaList[i]->IsFull() ) - { - g_pArenaList[i]->StartBattle(); - } - else - { - // If the arena has players in it, move them to the first full arena - if ( g_pArenaList[i]->m_iPlayers != 0 ) - { - for ( int j = 1; j <= gpGlobals->maxClients; j++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( j ); - - if (pPlayer && (pPlayer->m_pCurrentArena == g_pArenaList[i]) && (pPlayer->m_bHasDisconnected != TRUE) ) - { - // Add to the first arena - g_pArenaList[0]->AddClient( pPlayer, TRUE ); - - pPlayer->m_iLastGameResult = GAME_DIDNTPLAY; - } - } - } - } - } - -} - -//----------------------------------------------------------------------------- -// The Battle is over. First, check to see if there are games going on in -// other arenas. If there are, these players go watch one of them for a bit. -// If all games finish in that time, shuffle all the players and start new -// games. Otherwise, shuffle all the players who aren't still playing, and -// start new games with them. -void CDiscArena::PostBattle( void ) -{ - int iOtherGame = -1; - // First, see if there are any other games going on in other arenas - int i; - for ( i = 0; i < MAX_ARENAS; i++) - { - if ( g_pArenaList[i]->m_iArenaState != ARENA_WAITING_FOR_PLAYERS && g_pArenaList[i] != this ) - { - iOtherGame = i; - break; - } - } - - // If there are no other games, just shuffle and start again - if ( iOtherGame == -1 ) - { - ShufflePlayers(); - return; - } - - // There's another game going on. Move all the players from this arena to it to spectate. - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer *pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if (pPlayer && (pPlayer->pev->groupinfo & pev->groupinfo) && (pPlayer->m_bHasDisconnected != TRUE) ) - { - g_pArenaList[ iOtherGame ]->AddClient( (CBasePlayer*)pPlayer, TRUE ); - } - } - - m_iArenaState = ARENA_WAITING_FOR_PLAYERS; -} diff --git a/ricochet/dlls/disc_arena.h b/ricochet/dlls/disc_arena.h deleted file mode 100644 index 9670ef7..0000000 --- a/ricochet/dlls/disc_arena.h +++ /dev/null @@ -1,111 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#ifndef DISC_ARENA_H -#define DISC_ARENA_H -#pragma once - -#define MAX_ARENAS 16 - -// Arena States -#define ARENA_WAITING_FOR_PLAYERS 0 -#define ARENA_COUNTDOWN 1 -#define ARENA_BATTLE_IN_PROGRESS 2 -#define ARENA_SHOWING_SCORES 3 - -// Arena Times -#define ARENA_TIME_PREBATTLE 5 -#define ARENA_TIME_VIEWSCORES 3 -#define ARENA_TIME_ROUNDLIMIT 120 // Timelimit on rounds - -enum -{ - GAME_LOST = 0, - GAME_WON, - GAME_DIDNTPLAY, -}; - -//----------------------------------------------------------------------------- -// Arena object -class CDiscArena : public CBaseEntity -{ -public: - void Spawn( void ); - void Reset( void ); - - // Battle initialisation - void StartBattle( void ); - void StartRound( void ); - void SpawnCombatant( CBasePlayer *pPlayer ); - void MoveToSpectator( CBasePlayer *pPlayer ); - void EXPORT StartBattleThink( void ); - - // Battle running - void EXPORT CountDownThink( void ); - void PlayerKilled( CBasePlayer *pPlayer ); - void PlayerRespawned( CBasePlayer *pPlayer ); - void BattleOver( void ); - void EXPORT CheckOverThink( void ); - void EXPORT FinishedThink( void ); - void RestoreWorldObjects( void ); - int ValidateCombatants( void ); - void EXPORT TimeOver( void ); - void EXPORT BattleThink( void ); - bool CheckBattleOver( void ); - - // Client handling - void AddClient( CBasePlayer *pPlayer, BOOL bCheckStart ); - void RemoveClient( CBasePlayer *pPlayer ); - void AddPlayerToQueue( CBasePlayer *pPlayer ); - void RemovePlayerFromQueue( CBasePlayer *pPlayer ); - CBasePlayer * GetNextPlayer( void ); - - // Multiple Arena handling - int IsFull( void ); - CBasePlayer *GetFirstSparePlayer( void ); - void PostBattle( void ); - - // Game handling - bool AllowedToFire( void ); - - // Variables - int m_iArenaState; - int m_iPlayers; - int m_iMaxRounds; - int m_iCurrRound; - int m_iPlayersPerTeam; // Current players per team - int m_iSecondsTillStart; - int m_iWinningTeam; - int m_iTeamOneScore; - int m_iTeamTwoScore; - float m_flTimeLimitOver; - BOOL m_bShownTimeWarning; - - // Queue - EHANDLE m_pPlayerQueue; - - // Players in the current battle - EHANDLE m_hCombatants[ 32 ]; -}; - -extern CDiscArena *g_pArenaList[ MAX_ARENAS ]; -extern float g_iaDiscColors[33][3]; - -int InArenaMode(); - -#endif // DISC_ARENA_H diff --git a/ricochet/dlls/disc_objects.h b/ricochet/dlls/disc_objects.h deleted file mode 100644 index 067c56e..0000000 --- a/ricochet/dlls/disc_objects.h +++ /dev/null @@ -1,173 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#ifndef DISK_OBJECTS_H -#define DISK_OBJECTS_H -#pragma once - -// Disc objects -class CDiscWeapon; - -class CDisc : public CGrenade -{ -public: - void Spawn( void ); - void Precache( void ); - void EXPORT DiscTouch( CBaseEntity *pOther ); - void EXPORT DiscThink( void ); - static CDisc *CreateDisc( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CDiscWeapon *pLauncher, bool bDecapitator, int iPowerupFlags ); - - //void SetObjectCollisionBox( void ); - void ReturnToThrower( void ); - - virtual BOOL IsDisc( void ) { return TRUE; }; - - float m_fDontTouchEnemies; // Prevent enemy touches for a bit - float m_fDontTouchOwner; // Prevent friendly touches for a bit - int m_iBounces; // Number of bounces - EHANDLE m_hOwner; // Don't store in pev->owner, because it needs to hit its owner - CDiscWeapon *m_pLauncher; // pointer back to the launcher that fired me. - int m_iTrail; - int m_iSpriteTexture; - bool m_bDecapitate; // True if this is a decapitating shot - bool m_bRemoveSelf; // True if the owner of this disc has died - int m_iPowerupFlags;// Flags for any powerups active on this disc - bool m_bTeleported; // Disc has gone through a teleport - - EHANDLE m_pLockTarget; - - Vector m_vecActualVelocity; - Vector m_vecSideVelocity; - Vector m_vecOrg; -}; - -//=============================================================================== -// DISCWAR OBJECTS -//=============================================================================== -class CBaseTrigger : public CBaseToggle -{ -public: - void EXPORT TeleportTouch ( CBaseEntity *pOther ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT MultiTouch( CBaseEntity *pOther ); - void EXPORT HurtTouch ( CBaseEntity *pOther ); - void EXPORT CDAudioTouch ( CBaseEntity *pOther ); - void ActivateMultiTrigger( CBaseEntity *pActivator ); - void EXPORT MultiWaitOver( void ); - void EXPORT CounterUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void InitTrigger( void ); - - virtual int ObjectCaps( void ) { return CBaseToggle :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } -}; - -// Brush that's status gets toggled by a disc hit -#define LAST_HITBY_FRIENDLY 1 -#define LAST_HITBY_ENEMY 2 - -class CDiscTarget : public CBaseTrigger -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn( void ); - void Reset( void ); - - void EXPORT DiscToggleTouch( CBaseEntity *pOther ); - - int m_iszFriendlyHit; - int m_iszEnemyHit; - int m_iState; -}; - -//========================================================= -// Powerup object -class CDiscwarPowerup : public CBaseAnimating -{ -public: - void Spawn( void ); - void Activate( void ); - void Precache( void ); - void EXPORT PowerupTouch( CBaseEntity *pOther ); - void EXPORT ChoosePowerupThink( void ); - void EXPORT RemovePowerupThink( void ); - void EXPORT AnimateThink( void ); - void SetObjectCollisionBox( void ); - - void Disable(); - void Enable(); - - EHANDLE m_hPlayerIGaveTo; - int m_iPowerupType; -}; - -//=============================================================================== -// Brush that toggles between gone/there -#define PLAT_FADE_TIME 2.0 -class CPlatToggleRemove : public CBaseEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void Reset( void ); - - void EXPORT PlatToggleRemoveUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT PlatRemoveThink( void ); - - float m_flRemoveAt; -}; - -//=============================================================================== -// Trigger that jumps a player to a target point -class CTriggerJump : public CBaseTrigger -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void Activate( void ); - void Precache( void ); - void EXPORT JumpTouch( CBaseEntity *pOther ); - void EXPORT JumpUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - Vector m_vecTargetOrg; - float m_flHeight; - int m_iState; - -private: - unsigned short m_usJump; -}; - -//=============================================================================== -// Trigger that returns discs to their thrower immediately -class CTriggerDiscReturn : public CBaseTrigger -{ -public: - void Spawn( void ); - void Precache( void ); - void EXPORT DiscReturnTouch( CBaseEntity *pOther ); -}; - -//=============================================================================== -// Trigger that starts the fall animation for players -class CTriggerFall : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT FallTouch( CBaseEntity *pOther ); -}; - -#endif // DISK_OBJECTS_H diff --git a/ricochet/dlls/disc_powerups.cpp b/ricochet/dlls/disc_powerups.cpp deleted file mode 100644 index 52e5c61..0000000 --- a/ricochet/dlls/disc_powerups.cpp +++ /dev/null @@ -1,234 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Code for the various Discwar powerups -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "weapons.h" -#include "nodes.h" -#include "player.h" -#include "items.h" -#include "gamerules.h" -#include "discwar.h" -#include "disc_objects.h" -#include "disc_arena.h" - -extern int gmsgPowerup; - -//========================================================= -// POWERUPS -char *szPowerupModels[NUM_POWERUPS] = -{ - "models/pow_triple.mdl", - "models/pow_fast.mdl", - "models/pow_hard.mdl", - "models/pow_freeze.mdl", - //"models/pow_visual.mdl", -}; - -LINK_ENTITY_TO_CLASS( item_powerup, CDiscwarPowerup ); - -//========================================================= -void CDiscwarPowerup::Spawn( void ) -{ - Precache( ); - - // Don't fall down - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_TRIGGER; - UTIL_SetOrigin( pev, pev->origin ); - UTIL_SetSize(pev, Vector(-32, -32, -32), Vector(32, 32, 32)); - - // Use first model for now - SET_MODEL(ENT(pev), szPowerupModels[0]); - pev->effects |= EF_NODRAW; -} - -void CDiscwarPowerup::Activate( void ) -{ - // If Arena mode is on, spawn another powerup for every arena - if ( InArenaMode() ) - { - // If our groupinfo is set, we're not the first powerup - if ( pev->groupinfo == 0 ) - { - // Put this powerup in the first arena - pev->groupinfo = g_pArenaList[0]->pev->groupinfo; - - // Create a powerup for each of the other arenas - for (int i = 1; i < MAX_ARENAS; i++) - { - CBaseEntity * pPowerup; - - pPowerup = CBaseEntity::Create( "item_powerup", pev->origin, pev->angles ); - pPowerup->pev->groupinfo = g_pArenaList[i]->pev->groupinfo; - } - } - } - else - { - // Make the powerup start thinking - Enable(); - } -} - -void CDiscwarPowerup::Precache( void ) -{ - for (int i = 0; i < NUM_POWERUPS; i++) - PRECACHE_MODEL( szPowerupModels[i] ); - PRECACHE_SOUND( "powerup.wav" ); - PRECACHE_SOUND( "pspawn.wav" ); -} - -void CDiscwarPowerup::SetObjectCollisionBox( void ) -{ - pev->absmin = pev->origin + Vector( -64, -64, 0 ); - pev->absmax = pev->origin + Vector( 64, 64, 128 ); -} - -void CDiscwarPowerup::PowerupTouch( CBaseEntity *pOther ) -{ - if ( !pOther->IsPlayer() ) - return; - - CBasePlayer *pPlayer = (CBasePlayer *)pOther; - - // Give the powerup to the player - pPlayer->GivePowerup( m_iPowerupType ); - m_hPlayerIGaveTo = pPlayer; - SetTouch( NULL ); - pev->effects |= EF_NODRAW; - - // Choose another powerup soon - SetThink( &CDiscwarPowerup::ChoosePowerupThink ); - pev->nextthink = gpGlobals->time + DISC_POWERUP_RESPAWN_TIME; - - // Play the powerup sound - EMIT_SOUND_DYN( pOther->edict(), CHAN_STATIC, "powerup.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); -} - -// Disappear and don't appear again until enabled -void CDiscwarPowerup::Disable() -{ - pev->effects |= EF_NODRAW; - pev->nextthink = 0; - SetThink( NULL ); - SetTouch( NULL ); -} - -// Come back and pick a new powerup -void CDiscwarPowerup::Enable() -{ - // Pick a powerup - SetThink( &CDiscwarPowerup::ChoosePowerupThink ); - pev->nextthink = gpGlobals->time + (DISC_POWERUP_RESPAWN_TIME / 2); -} - -//========================================================= -// Randomly decide what powerup to be -void CDiscwarPowerup::ChoosePowerupThink( void ) -{ - int iPowerup = RANDOM_LONG(0, NUM_POWERUPS-1); - m_iPowerupType = (1 << iPowerup); - - SET_MODEL( ENT(pev), szPowerupModels[iPowerup] ); - pev->effects &= ~EF_NODRAW; - - SetTouch(&CDiscwarPowerup::PowerupTouch); - - // Start Animating - pev->sequence = 0; - pev->frame = 0; - ResetSequenceInfo(); - - SetThink(&CDiscwarPowerup::AnimateThink); - pev->nextthink = gpGlobals->time + 0.1; - - pev->rendermode = kRenderTransAdd; - pev->renderamt = 150; - - // Play the powerup appear sound - EMIT_SOUND_DYN( edict(), CHAN_STATIC, "pspawn.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); -} - -void CDiscwarPowerup::AnimateThink( void ) -{ - StudioFrameAdvance(); - pev->nextthink = gpGlobals->time + 0.1; -} - -// Remove the powerup from the person we gave it to -void CDiscwarPowerup::RemovePowerupThink( void ) -{ - if (m_hPlayerIGaveTo == NULL) - return; - - ((CBasePlayer*)(CBaseEntity*)m_hPlayerIGaveTo)->RemovePowerup( m_iPowerupType ); - - // Pick a powerup later - SetThink( &CDiscwarPowerup::ChoosePowerupThink ); - pev->nextthink = gpGlobals->time + DISC_POWERUP_RESPAWN_TIME; -} - -//================================================================================= -// PLAYER HANDLING FOR POWERUPS -//========================================================= -void CBasePlayer::GivePowerup( int iPowerupType ) -{ - m_iPowerups |= iPowerupType; - - if ( m_iPowerups & POW_HARD ) - strcpy( m_szAnimExtention, "models/p_disc_hard.mdl" ); - - MESSAGE_BEGIN( MSG_ONE, gmsgPowerup, NULL, pev ); - WRITE_BYTE( m_iPowerups ); - MESSAGE_END(); - - m_iPowerupDiscs = MAX_DISCS; -} - -void CBasePlayer::RemovePowerup( int iPowerupType ) -{ - if ( iPowerupType & POW_HARD ) - strcpy( m_szAnimExtention, "models/p_disc.mdl" ); - - m_iPowerups &= ~iPowerupType; - - MESSAGE_BEGIN( MSG_ONE, gmsgPowerup, NULL, pev ); - WRITE_BYTE( m_iPowerups ); - MESSAGE_END(); - - m_iPowerupDiscs = 0; -} - -void CBasePlayer::RemoveAllPowerups( void ) -{ - m_iPowerups = 0; - m_iPowerupDiscs = 0; - - MESSAGE_BEGIN( MSG_ONE, gmsgPowerup, NULL, pev ); - WRITE_BYTE( m_iPowerups ); - MESSAGE_END(); -} - -bool CBasePlayer::HasPowerup( int iPowerupType ) -{ - return (m_iPowerups & iPowerupType) != 0; -} - diff --git a/ricochet/dlls/disc_weapon.h b/ricochet/dlls/disc_weapon.h deleted file mode 100644 index c9c3f3b..0000000 --- a/ricochet/dlls/disc_weapon.h +++ /dev/null @@ -1,33 +0,0 @@ -#if !defined( DISC_WEAPON_H ) -#define DISC_WEAPON_H -#ifdef _WIN32 -#pragma once -#endif - -class CDisc; -class CDiscWeapon : public CBasePlayerWeapon -{ -public: - void Spawn( void ); - void Precache( void ); - int iItemSlot( void ) { return 5; } - int GetItemInfo(ItemInfo *p); - - int AddDuplicate( CBasePlayerItem *pOriginal ); - CDisc *FireDisc( bool bDecapitator ); - void PrimaryAttack( void ); - void SecondaryAttack( void ); - BOOL Deploy( void ); - BOOL CanHolster( void ); - void Holster( int skiplocal = 0 ); - void WeaponIdle( void ); - - BOOL UseDecrement( void ) { return TRUE; }; - - int m_iSpriteTexture; - int m_iFastShotDiscs; -private: - unsigned short m_usFireDisc; -}; - -#endif // DISC_WEAPON_H diff --git a/ricochet/dlls/discwar.h b/ricochet/dlls/discwar.h deleted file mode 100644 index 410038d..0000000 --- a/ricochet/dlls/discwar.h +++ /dev/null @@ -1,60 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Header for Discwar -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= - -#ifndef DISCWAR_H -#define DISCWAR_H -#pragma once - -#define WEAPON_DISC 1 -#define MAX_DISCS 3 // Max number of discs a player can carry -#define STARTING_DISCS MAX_DISCS // Number of discs a player starts with -#define NUM_FASTSHOT_DISCS 3 // Number of discs a player gets with the fastshot powerup per normal disc - -#define DISC_VELOCITY 1000 // Velocity multiplier for discs when thrown -#define DISC_PUSH_MULTIPLIER 1200 // Velocity multiplier used to push a player when hit by a disc - -//#define DISC_POWERUP_TIME 5 // Time (in seconds) a powerup lasts for -#define DISC_POWERUP_RESPAWN_TIME 10 // Time (in seconds) it takes after a powerup is picked up before the next one appears - -#define MAX_SCORE_TIME_AFTER_HIT 4.0 // Time (in seconds) in which a player gets a point if the enemy dies within this time - // after being hit by a disc. - -// Powerups -#define POW_TRIPLE (1<<0) -#define POW_FAST (1<<1) -#define POW_HARD (1<<2) -#define POW_FREEZE (1<<3) - -#define POW_VISUALIZE_REBOUNDS (1<<4) // Removing this one for now - -#define NUM_POWERUPS 4 // 4, not 5, because VISUALIZE_REBOUNDS is removed. - -#define FREEZE_TIME 7 -#define FREEZE_SPEED 50 - -// Rewards -#define REWARD_BOUNCE_NONE (1<<1) -#define REWARD_BOUNCE_ONE (1<<2) -#define REWARD_BOUNCE_TWO (1<<3) -#define REWARD_BOUNCE_THREE (1<<4) -#define REWARD_DECAPITATE (1<<5) -#define REWARD_TELEPORT (1<<6) -#define REWARD_DOUBLEKILL (1<<7) - -#endif // DISCWAR_H - diff --git a/ricochet/dlls/doors.cpp b/ricochet/dlls/doors.cpp deleted file mode 100644 index c084dac..0000000 --- a/ricochet/dlls/doors.cpp +++ /dev/null @@ -1,1026 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== doors.cpp ======================================================== - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "doors.h" - - -extern void SetMovedir(entvars_t* ev); - -#define noiseMoving noise1 -#define noiseArrived noise2 - -class CBaseDoor : public CBaseToggle -{ -public: - void Spawn( void ); - void Precache( void ); - virtual void KeyValue( KeyValueData *pkvd ); - virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual void Blocked( CBaseEntity *pOther ); - - - virtual int ObjectCaps( void ) - { - if (pev->spawnflags & SF_ITEM_USE_ONLY) - return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE; - else - return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION); - }; - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - virtual void SetToggleState( int state ); - - // used to selectivly override defaults - void EXPORT DoorTouch( CBaseEntity *pOther ); - - // local functions - int DoorActivate( ); - void EXPORT DoorGoUp( void ); - void EXPORT DoorGoDown( void ); - void EXPORT DoorHitTop( void ); - void EXPORT DoorHitBottom( void ); - - BYTE m_bHealthValue;// some doors are medi-kit doors, they give players health - - BYTE m_bMoveSnd; // sound a door makes while moving - BYTE m_bStopSnd; // sound a door makes when it stops - - locksound_t m_ls; // door lock sounds - - BYTE m_bLockedSound; // ordinals from entity selection - BYTE m_bLockedSentence; - BYTE m_bUnlockedSound; - BYTE m_bUnlockedSentence; -}; - - -TYPEDESCRIPTION CBaseDoor::m_SaveData[] = -{ - DEFINE_FIELD( CBaseDoor, m_bHealthValue, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bMoveSnd, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bStopSnd, FIELD_CHARACTER ), - - DEFINE_FIELD( CBaseDoor, m_bLockedSound, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bLockedSentence, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bUnlockedSound, FIELD_CHARACTER ), - DEFINE_FIELD( CBaseDoor, m_bUnlockedSentence, FIELD_CHARACTER ), - -}; - -IMPLEMENT_SAVERESTORE( CBaseDoor, CBaseToggle ); - - -#define DOOR_SENTENCEWAIT 6 -#define DOOR_SOUNDWAIT 3 -#define BUTTON_SOUNDWAIT 0.5 - -// play door or button locked or unlocked sounds. -// pass in pointer to valid locksound struct. -// if flocked is true, play 'door is locked' sound, -// otherwise play 'door is unlocked' sound -// NOTE: this routine is shared by doors and buttons - -void PlayLockSounds(entvars_t *pev, locksound_t *pls, int flocked, int fbutton) -{ - // LOCKED SOUND - - // CONSIDER: consolidate the locksound_t struct (all entries are duplicates for lock/unlock) - // CONSIDER: and condense this code. - float flsoundwait; - - if (fbutton) - flsoundwait = BUTTON_SOUNDWAIT; - else - flsoundwait = DOOR_SOUNDWAIT; - - if (flocked) - { - int fplaysound = (pls->sLockedSound && gpGlobals->time > pls->flwaitSound); - int fplaysentence = (pls->sLockedSentence && !pls->bEOFLocked && gpGlobals->time > pls->flwaitSentence); - float fvol; - - if (fplaysound && fplaysentence) - fvol = 0.25; - else - fvol = 1.0; - - // if there is a locked sound, and we've debounced, play sound - if (fplaysound) - { - // play 'door locked' sound - EMIT_SOUND(ENT(pev), CHAN_ITEM, (char*)STRING(pls->sLockedSound), fvol, ATTN_NORM); - pls->flwaitSound = gpGlobals->time + flsoundwait; - } - - // if there is a sentence, we've not played all in list, and we've debounced, play sound - if (fplaysentence) - { - // play next 'door locked' sentence in group - int iprev = pls->iLockedSentence; - - pls->iLockedSentence = SENTENCEG_PlaySequentialSz(ENT(pev), STRING(pls->sLockedSentence), - 0.85, ATTN_NORM, 0, 100, pls->iLockedSentence, FALSE); - pls->iUnlockedSentence = 0; - - // make sure we don't keep calling last sentence in list - pls->bEOFLocked = (iprev == pls->iLockedSentence); - - pls->flwaitSentence = gpGlobals->time + DOOR_SENTENCEWAIT; - } - } - else - { - // UNLOCKED SOUND - - int fplaysound = (pls->sUnlockedSound && gpGlobals->time > pls->flwaitSound); - int fplaysentence = (pls->sUnlockedSentence && !pls->bEOFUnlocked && gpGlobals->time > pls->flwaitSentence); - float fvol; - - // if playing both sentence and sound, lower sound volume so we hear sentence - if (fplaysound && fplaysentence) - fvol = 0.25; - else - fvol = 1.0; - - // play 'door unlocked' sound if set - if (fplaysound) - { - EMIT_SOUND(ENT(pev), CHAN_ITEM, (char*)STRING(pls->sUnlockedSound), fvol, ATTN_NORM); - pls->flwaitSound = gpGlobals->time + flsoundwait; - } - - // play next 'door unlocked' sentence in group - if (fplaysentence) - { - int iprev = pls->iUnlockedSentence; - - pls->iUnlockedSentence = SENTENCEG_PlaySequentialSz(ENT(pev), STRING(pls->sUnlockedSentence), - 0.85, ATTN_NORM, 0, 100, pls->iUnlockedSentence, FALSE); - pls->iLockedSentence = 0; - - // make sure we don't keep calling last sentence in list - pls->bEOFUnlocked = (iprev == pls->iUnlockedSentence); - pls->flwaitSentence = gpGlobals->time + DOOR_SENTENCEWAIT; - } - } -} - -// -// Cache user-entity-field values until spawn is called. -// - -void CBaseDoor::KeyValue( KeyValueData *pkvd ) -{ - - if (FStrEq(pkvd->szKeyName, "skin"))//skin is used for content type - { - pev->skin = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "movesnd")) - { - m_bMoveSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "stopsnd")) - { - m_bStopSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "healthvalue")) - { - m_bHealthValue = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "locked_sound")) - { - m_bLockedSound = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "locked_sentence")) - { - m_bLockedSentence = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "unlocked_sound")) - { - m_bUnlockedSound = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "unlocked_sentence")) - { - m_bUnlockedSentence = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "WaveHeight")) - { - pev->scale = atof(pkvd->szValue) * (1.0/8.0); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -/*QUAKED func_door (0 .5 .8) ? START_OPEN x DOOR_DONT_LINK TOGGLE -if two doors touch, they are assumed to be connected and operate as a unit. - -TOGGLE causes the door to wait in both the start and end states for a trigger event. - -START_OPEN causes the door to move to its destination when spawned, and operate in reverse. -It is used to temporarily or permanently close off an area when triggered (not usefull for -touch or takedamage doors). - -"angle" determines the opening direction -"targetname" if set, no touch field will be spawned and a remote button or trigger - field activates the door. -"health" if set, door must be shot open -"speed" movement speed (100 default) -"wait" wait before returning (3 default, -1 = never return) -"lip" lip remaining at end of move (8 default) -"dmg" damage to inflict when blocked (2 default) -"sounds" -0) no sound -1) stone -2) base -3) stone chain -4) screechy metal -*/ - -LINK_ENTITY_TO_CLASS( func_door, CBaseDoor ); -// -// func_water - same as a door. -// -LINK_ENTITY_TO_CLASS( func_water, CBaseDoor ); - - -void CBaseDoor::Spawn( ) -{ - Precache(); - SetMovedir (pev); - - if ( pev->skin == 0 ) - {//normal door - if ( FBitSet (pev->spawnflags, SF_DOOR_PASSABLE) ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - } - else - {// special contents - pev->solid = SOLID_NOT; - SetBits( pev->spawnflags, SF_DOOR_SILENT ); // water is silent for now - } - - pev->movetype = MOVETYPE_PUSH; - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - if (pev->speed == 0) - pev->speed = 100; - - m_vecPosition1 = pev->origin; - // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big - m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs( pev->movedir.x * (pev->size.x-2) ) + fabs( pev->movedir.y * (pev->size.y-2) ) + fabs( pev->movedir.z * (pev->size.z-2) ) - m_flLip)); - ASSERTSZ(m_vecPosition1 != m_vecPosition2, "door start/end positions are equal"); - if ( FBitSet (pev->spawnflags, SF_DOOR_START_OPEN) ) - { // swap pos1 and pos2, put door at pos2 - UTIL_SetOrigin(pev, m_vecPosition2); - m_vecPosition2 = m_vecPosition1; - m_vecPosition1 = pev->origin; - } - - m_toggle_state = TS_AT_BOTTOM; - - // if the door is flagged for USE button activation only, use NULL touch function - if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ) - { - SetTouch ( NULL ); - } - else // touchable button - SetTouch( &CBaseDoor::DoorTouch ); -} - - -void CBaseDoor :: SetToggleState( int state ) -{ - if ( state == TS_AT_TOP ) - UTIL_SetOrigin( pev, m_vecPosition2 ); - else - UTIL_SetOrigin( pev, m_vecPosition1 ); -} - - -void CBaseDoor::Precache( void ) -{ - char *pszSound; - -// set the door's "in-motion" sound - switch (m_bMoveSnd) - { - case 0: - pev->noiseMoving = ALLOC_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("doors/doormove1.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove1.wav"); - break; - case 2: - PRECACHE_SOUND ("doors/doormove2.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove2.wav"); - break; - case 3: - PRECACHE_SOUND ("doors/doormove3.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove3.wav"); - break; - case 4: - PRECACHE_SOUND ("doors/doormove4.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove4.wav"); - break; - case 5: - PRECACHE_SOUND ("doors/doormove5.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove5.wav"); - break; - case 6: - PRECACHE_SOUND ("doors/doormove6.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove6.wav"); - break; - case 7: - PRECACHE_SOUND ("doors/doormove7.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove7.wav"); - break; - case 8: - PRECACHE_SOUND ("doors/doormove8.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove8.wav"); - break; - case 9: - PRECACHE_SOUND ("doors/doormove9.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove9.wav"); - break; - case 10: - PRECACHE_SOUND ("doors/doormove10.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove10.wav"); - break; - default: - pev->noiseMoving = ALLOC_STRING("common/null.wav"); - break; - } - -// set the door's 'reached destination' stop sound - switch (m_bStopSnd) - { - case 0: - pev->noiseArrived = ALLOC_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("doors/doorstop1.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop1.wav"); - break; - case 2: - PRECACHE_SOUND ("doors/doorstop2.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop2.wav"); - break; - case 3: - PRECACHE_SOUND ("doors/doorstop3.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop3.wav"); - break; - case 4: - PRECACHE_SOUND ("doors/doorstop4.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop4.wav"); - break; - case 5: - PRECACHE_SOUND ("doors/doorstop5.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop5.wav"); - break; - case 6: - PRECACHE_SOUND ("doors/doorstop6.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop6.wav"); - break; - case 7: - PRECACHE_SOUND ("doors/doorstop7.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop7.wav"); - break; - case 8: - PRECACHE_SOUND ("doors/doorstop8.wav"); - pev->noiseArrived = ALLOC_STRING("doors/doorstop8.wav"); - break; - default: - pev->noiseArrived = ALLOC_STRING("common/null.wav"); - break; - } - - // get door button sounds, for doors which are directly 'touched' to open - - if (m_bLockedSound) - { - pszSound = ButtonSound( (int)m_bLockedSound ); - PRECACHE_SOUND(pszSound); - m_ls.sLockedSound = ALLOC_STRING(pszSound); - } - - if (m_bUnlockedSound) - { - pszSound = ButtonSound( (int)m_bUnlockedSound ); - PRECACHE_SOUND(pszSound); - m_ls.sUnlockedSound = ALLOC_STRING(pszSound); - } - - // get sentence group names, for doors which are directly 'touched' to open - - switch (m_bLockedSentence) - { - case 1: m_ls.sLockedSentence = ALLOC_STRING("NA"); break; // access denied - case 2: m_ls.sLockedSentence = ALLOC_STRING("ND"); break; // security lockout - case 3: m_ls.sLockedSentence = ALLOC_STRING("NF"); break; // blast door - case 4: m_ls.sLockedSentence = ALLOC_STRING("NFIRE"); break; // fire door - case 5: m_ls.sLockedSentence = ALLOC_STRING("NCHEM"); break; // chemical door - case 6: m_ls.sLockedSentence = ALLOC_STRING("NRAD"); break; // radiation door - case 7: m_ls.sLockedSentence = ALLOC_STRING("NCON"); break; // gen containment - case 8: m_ls.sLockedSentence = ALLOC_STRING("NH"); break; // maintenance door - case 9: m_ls.sLockedSentence = ALLOC_STRING("NG"); break; // broken door - - default: m_ls.sLockedSentence = 0; break; - } - - switch (m_bUnlockedSentence) - { - case 1: m_ls.sUnlockedSentence = ALLOC_STRING("EA"); break; // access granted - case 2: m_ls.sUnlockedSentence = ALLOC_STRING("ED"); break; // security door - case 3: m_ls.sUnlockedSentence = ALLOC_STRING("EF"); break; // blast door - case 4: m_ls.sUnlockedSentence = ALLOC_STRING("EFIRE"); break; // fire door - case 5: m_ls.sUnlockedSentence = ALLOC_STRING("ECHEM"); break; // chemical door - case 6: m_ls.sUnlockedSentence = ALLOC_STRING("ERAD"); break; // radiation door - case 7: m_ls.sUnlockedSentence = ALLOC_STRING("ECON"); break; // gen containment - case 8: m_ls.sUnlockedSentence = ALLOC_STRING("EH"); break; // maintenance door - - default: m_ls.sUnlockedSentence = 0; break; - } -} - -// -// Doors not tied to anything (e.g. button, another door) can be touched, to make them activate. -// -void CBaseDoor::DoorTouch( CBaseEntity *pOther ) -{ - entvars_t* pevToucher = pOther->pev; - - // Ignore touches by anything but players - if (!FClassnameIs(pevToucher, "player")) - return; - - // If door has master, and it's not ready to trigger, - // play 'locked' sound - - if (m_sMaster && !UTIL_IsMasterTriggered(m_sMaster, pOther)) - PlayLockSounds(pev, &m_ls, TRUE, FALSE); - - // If door is somebody's target, then touching does nothing. - // You have to activate the owner (e.g. button). - - if (!FStringNull(pev->targetname)) - { - // play locked sound - PlayLockSounds(pev, &m_ls, TRUE, FALSE); - return; - } - - m_hActivator = pOther;// remember who activated the door - - if (DoorActivate( )) - SetTouch( NULL ); // Temporarily disable the touch function, until movement is finished. -} - - -// -// Used by SUB_UseTargets, when a door is the target of a button. -// -void CBaseDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - m_hActivator = pActivator; - // if not ready to be used, ignore "use" command. - if (m_toggle_state == TS_AT_BOTTOM || FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN) && m_toggle_state == TS_AT_TOP) - DoorActivate(); -} - -// -// Causes the door to "do its thing", i.e. start moving, and cascade activation. -// -int CBaseDoor::DoorActivate( ) -{ - if (!UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) - return 0; - - if (FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN) && m_toggle_state == TS_AT_TOP) - {// door should close - DoorGoDown(); - } - else - {// door should open - - if ( m_hActivator != NULL && m_hActivator->IsPlayer() ) - {// give health if player opened the door (medikit) - // VARS( m_eoActivator )->health += m_bHealthValue; - - m_hActivator->TakeHealth( m_bHealthValue, DMG_GENERIC ); - - } - - // play door unlock sounds - PlayLockSounds(pev, &m_ls, FALSE, FALSE); - - DoorGoUp(); - } - - return 1; -} - -extern Vector VecBModelOrigin( entvars_t* pevBModel ); - -// -// Starts the door going to its "up" position (simply ToggleData->vecPosition2). -// -void CBaseDoor::DoorGoUp( void ) -{ - entvars_t *pevActivator; - - // It could be going-down, if blocked. - ASSERT(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN); - - // emit door moving and stop sounds on CHAN_STATIC so that the multicast doesn't - // filter them out and leave a client stuck with looping door sounds! - if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM); - - m_toggle_state = TS_GOING_UP; - - SetMoveDone( &CBaseDoor::DoorHitTop ); - if ( FClassnameIs(pev, "func_door_rotating")) // !!! BUGBUG Triggered doors don't work with this yet - { - float sign = 1.0; - - if ( m_hActivator != NULL ) - { - pevActivator = m_hActivator->pev; - - if ( !FBitSet( pev->spawnflags, SF_DOOR_ONEWAY ) && pev->movedir.y ) // Y axis rotation, move away from the player - { - Vector vec = pevActivator->origin - pev->origin; - Vector angles = pevActivator->angles; - angles.x = 0; - angles.z = 0; - UTIL_MakeVectors (angles); - // Vector vnext = (pevToucher->origin + (pevToucher->velocity * 10)) - pev->origin; - UTIL_MakeVectors ( pevActivator->angles ); - Vector vnext = (pevActivator->origin + (gpGlobals->v_forward * 10)) - pev->origin; - if ( (vec.x*vnext.y - vec.y*vnext.x) < 0 ) - sign = -1.0; - } - } - AngularMove(m_vecAngle2*sign, pev->speed); - } - else - LinearMove(m_vecPosition2, pev->speed); -} - - -// -// The door has reached the "up" position. Either go back down, or wait for another activation. -// -void CBaseDoor::DoorHitTop( void ) -{ - if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) - { - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) ); - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseArrived), 1, ATTN_NORM); - } - - ASSERT(m_toggle_state == TS_GOING_UP); - m_toggle_state = TS_AT_TOP; - - // toggle-doors don't come down automatically, they wait for refire. - if (FBitSet(pev->spawnflags, SF_DOOR_NO_AUTO_RETURN)) - { - // Re-instate touch method, movement is complete - if ( !FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ) - SetTouch( &CBaseDoor::DoorTouch ); - } - else - { - // In flWait seconds, DoorGoDown will fire, unless wait is -1, then door stays open - pev->nextthink = pev->ltime + m_flWait; - SetThink( &CBaseDoor::DoorGoDown ); - - if ( m_flWait == -1 ) - { - pev->nextthink = -1; - } - } - - // Fire the close target (if startopen is set, then "top" is closed) - netname is the close target - if ( pev->netname && (pev->spawnflags & SF_DOOR_START_OPEN) ) - FireTargets( STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0 ); - - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished -} - - -// -// Starts the door going to its "down" position (simply ToggleData->vecPosition1). -// -void CBaseDoor::DoorGoDown( void ) -{ - if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM); - -#ifdef DOOR_ASSERT - ASSERT(m_toggle_state == TS_AT_TOP); -#endif // DOOR_ASSERT - m_toggle_state = TS_GOING_DOWN; - - SetMoveDone( &CBaseDoor::DoorHitBottom ); - if ( FClassnameIs(pev, "func_door_rotating"))//rotating door - AngularMove( m_vecAngle1, pev->speed); - else - LinearMove( m_vecPosition1, pev->speed); -} - -// -// The door has reached the "down" position. Back to quiescence. -// -void CBaseDoor::DoorHitBottom( void ) -{ - if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) - { - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving) ); - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseArrived), 1, ATTN_NORM); - } - - ASSERT(m_toggle_state == TS_GOING_DOWN); - m_toggle_state = TS_AT_BOTTOM; - - // Re-instate touch method, cycle is complete - if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ) - {// use only door - SetTouch ( NULL ); - } - else // touchable door - SetTouch( &CBaseDoor::DoorTouch ); - - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished - - // Fire the close target (if startopen is set, then "top" is closed) - netname is the close target - if ( pev->netname && !(pev->spawnflags & SF_DOOR_START_OPEN) ) - FireTargets( STRING(pev->netname), m_hActivator, this, USE_TOGGLE, 0 ); -} - -void CBaseDoor::Blocked( CBaseEntity *pOther ) -{ - edict_t *pentTarget = NULL; - CBaseDoor *pDoor = NULL; - - - // Hurt the blocker a little. - if ( pev->dmg ) - pOther->TakeDamage( pev, pev, pev->dmg, DMG_CRUSH ); - - // if a door has a negative wait, it would never come back if blocked, - // so let it just squash the object to death real fast - - if (m_flWait >= 0) - { - if (m_toggle_state == TS_GOING_DOWN) - { - DoorGoUp(); - } - else - { - DoorGoDown(); - } - } - - // Block all door pieces with the same targetname here. - if ( !FStringNull ( pev->targetname ) ) - { - for (;;) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->targetname)); - - if ( VARS( pentTarget ) != pev ) - { - if (FNullEnt(pentTarget)) - break; - - if ( FClassnameIs ( pentTarget, "func_door" ) || FClassnameIs ( pentTarget, "func_door_rotating" ) ) - { - - pDoor = GetClassPtr( (CBaseDoor *) VARS(pentTarget) ); - - if ( pDoor->m_flWait >= 0) - { - if (pDoor->pev->velocity == pev->velocity && pDoor->pev->avelocity == pev->velocity) - { - // this is the most hacked, evil, bastardized thing I've ever seen. kjb - if ( FClassnameIs ( pentTarget, "func_door" ) ) - {// set origin to realign normal doors - pDoor->pev->origin = pev->origin; - pDoor->pev->velocity = g_vecZero;// stop! - } - else - {// set angles to realign rotating doors - pDoor->pev->angles = pev->angles; - pDoor->pev->avelocity = g_vecZero; - } - } - - if ( pDoor->m_toggle_state == TS_GOING_DOWN) - pDoor->DoorGoUp(); - else - pDoor->DoorGoDown(); - } - } - } - } - } -} - - -/*QUAKED FuncRotDoorSpawn (0 .5 .8) ? START_OPEN REVERSE -DOOR_DONT_LINK TOGGLE X_AXIS Y_AXIS -if two doors touch, they are assumed to be connected and operate as -a unit. - -TOGGLE causes the door to wait in both the start and end states for -a trigger event. - -START_OPEN causes the door to move to its destination when spawned, -and operate in reverse. It is used to temporarily or permanently -close off an area when triggered (not usefull for touch or -takedamage doors). - -You need to have an origin brush as part of this entity. The -center of that brush will be -the point around which it is rotated. It will rotate around the Z -axis by default. You can -check either the X_AXIS or Y_AXIS box to change that. - -"distance" is how many degrees the door will be rotated. -"speed" determines how fast the door moves; default value is 100. - -REVERSE will cause the door to rotate in the opposite direction. - -"angle" determines the opening direction -"targetname" if set, no touch field will be spawned and a remote -button or trigger field activates the door. -"health" if set, door must be shot open -"speed" movement speed (100 default) -"wait" wait before returning (3 default, -1 = never return) -"dmg" damage to inflict when blocked (2 default) -"sounds" -0) no sound -1) stone -2) base -3) stone chain -4) screechy metal -*/ -class CRotDoor : public CBaseDoor -{ -public: - void Spawn( void ); - virtual void SetToggleState( int state ); -}; - -LINK_ENTITY_TO_CLASS( func_door_rotating, CRotDoor ); - - -void CRotDoor::Spawn( void ) -{ - Precache(); - // set the axis of rotation - CBaseToggle::AxisDir( pev ); - - // check for clockwise rotation - if ( FBitSet (pev->spawnflags, SF_DOOR_ROTATE_BACKWARDS) ) - pev->movedir = pev->movedir * -1; - - //m_flWait = 2; who the hell did this? (sjb) - m_vecAngle1 = pev->angles; - m_vecAngle2 = pev->angles + pev->movedir * m_flMoveDistance; - - ASSERTSZ(m_vecAngle1 != m_vecAngle2, "rotating door start/end positions are equal"); - - if ( FBitSet (pev->spawnflags, SF_DOOR_PASSABLE) ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - - pev->movetype = MOVETYPE_PUSH; - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - if (pev->speed == 0) - pev->speed = 100; - -// DOOR_START_OPEN is to allow an entity to be lighted in the closed position -// but spawn in the open position - if ( FBitSet (pev->spawnflags, SF_DOOR_START_OPEN) ) - { // swap pos1 and pos2, put door at pos2, invert movement direction - pev->angles = m_vecAngle2; - Vector vecSav = m_vecAngle1; - m_vecAngle2 = m_vecAngle1; - m_vecAngle1 = vecSav; - pev->movedir = pev->movedir * -1; - } - - m_toggle_state = TS_AT_BOTTOM; - - if ( FBitSet ( pev->spawnflags, SF_DOOR_USE_ONLY ) ) - { - SetTouch ( NULL ); - } - else // touchable button - SetTouch( &CRotDoor::DoorTouch ); -} - - -void CRotDoor :: SetToggleState( int state ) -{ - if ( state == TS_AT_TOP ) - pev->angles = m_vecAngle2; - else - pev->angles = m_vecAngle1; - - UTIL_SetOrigin( pev, pev->origin ); -} - - -class CMomentaryDoor : public CBaseToggle -{ -public: - void Spawn( void ); - void Precache( void ); - - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual int ObjectCaps( void ) { return CBaseToggle :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - BYTE m_bMoveSnd; // sound a door makes while moving -}; - -LINK_ENTITY_TO_CLASS( momentary_door, CMomentaryDoor ); - -TYPEDESCRIPTION CMomentaryDoor::m_SaveData[] = -{ - DEFINE_FIELD( CMomentaryDoor, m_bMoveSnd, FIELD_CHARACTER ), -}; - -IMPLEMENT_SAVERESTORE( CMomentaryDoor, CBaseToggle ); - -void CMomentaryDoor::Spawn( void ) -{ - SetMovedir (pev); - - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - if (pev->speed == 0) - pev->speed = 100; - if (pev->dmg == 0) - pev->dmg = 2; - - m_vecPosition1 = pev->origin; - // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big - m_vecPosition2 = m_vecPosition1 + (pev->movedir * (fabs( pev->movedir.x * (pev->size.x-2) ) + fabs( pev->movedir.y * (pev->size.y-2) ) + fabs( pev->movedir.z * (pev->size.z-2) ) - m_flLip)); - ASSERTSZ(m_vecPosition1 != m_vecPosition2, "door start/end positions are equal"); - - if ( FBitSet (pev->spawnflags, SF_DOOR_START_OPEN) ) - { // swap pos1 and pos2, put door at pos2 - UTIL_SetOrigin(pev, m_vecPosition2); - m_vecPosition2 = m_vecPosition1; - m_vecPosition1 = pev->origin; - } - SetTouch( NULL ); - - Precache(); -} - -void CMomentaryDoor::Precache( void ) -{ - -// set the door's "in-motion" sound - switch (m_bMoveSnd) - { - case 0: - pev->noiseMoving = ALLOC_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("doors/doormove1.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove1.wav"); - break; - case 2: - PRECACHE_SOUND ("doors/doormove2.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove2.wav"); - break; - case 3: - PRECACHE_SOUND ("doors/doormove3.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove3.wav"); - break; - case 4: - PRECACHE_SOUND ("doors/doormove4.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove4.wav"); - break; - case 5: - PRECACHE_SOUND ("doors/doormove5.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove5.wav"); - break; - case 6: - PRECACHE_SOUND ("doors/doormove6.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove6.wav"); - break; - case 7: - PRECACHE_SOUND ("doors/doormove7.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove7.wav"); - break; - case 8: - PRECACHE_SOUND ("doors/doormove8.wav"); - pev->noiseMoving = ALLOC_STRING("doors/doormove8.wav"); - break; - default: - pev->noiseMoving = ALLOC_STRING("common/null.wav"); - break; - } -} - -void CMomentaryDoor::KeyValue( KeyValueData *pkvd ) -{ - - if (FStrEq(pkvd->szKeyName, "movesnd")) - { - m_bMoveSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "stopsnd")) - { -// m_bStopSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "healthvalue")) - { -// m_bHealthValue = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -void CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( useType != USE_SET ) // Momentary buttons will pass down a float in here - return; - - if ( value > 1.0 ) - value = 1.0; - Vector move = m_vecPosition1 + (value * (m_vecPosition2 - m_vecPosition1)); - - Vector delta = move - pev->origin; - float speed = delta.Length() * 10; - - if ( speed != 0 ) - { - // This entity only thinks when it moves, so if it's thinking, it's in the process of moving - // play the sound when it starts moving - if ( pev->nextthink < pev->ltime || pev->nextthink == 0 ) - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM); - - LinearMove( move, speed ); - } - -} diff --git a/ricochet/dlls/doors.h b/ricochet/dlls/doors.h deleted file mode 100644 index 07447a0..0000000 --- a/ricochet/dlls/doors.h +++ /dev/null @@ -1,33 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef DOORS_H -#define DOORS_H - -// doors -#define SF_DOOR_ROTATE_Y 0 -#define SF_DOOR_START_OPEN 1 -#define SF_DOOR_ROTATE_BACKWARDS 2 -#define SF_DOOR_PASSABLE 8 -#define SF_DOOR_ONEWAY 16 -#define SF_DOOR_NO_AUTO_RETURN 32 -#define SF_DOOR_ROTATE_Z 64 -#define SF_DOOR_ROTATE_X 128 -#define SF_DOOR_USE_ONLY 256 // door must be opened by player's use button. -#define SF_DOOR_NOMONSTERS 512 // Monster can't open -#define SF_DOOR_SILENT 0x80000000 - - - -#endif //DOORS_H diff --git a/ricochet/dlls/effects.cpp b/ricochet/dlls/effects.cpp deleted file mode 100644 index eef7b11..0000000 --- a/ricochet/dlls/effects.cpp +++ /dev/null @@ -1,2268 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "customentity.h" -#include "effects.h" -#include "weapons.h" -#include "decals.h" -#include "func_break.h" -#include "shake.h" - -#define SF_GIBSHOOTER_REPEATABLE 1 // allows a gibshooter to be refired - -#define SF_FUNNEL_REVERSE 1 // funnel effect repels particles instead of attracting them. - - -// Lightning target, just alias landmark -LINK_ENTITY_TO_CLASS( info_target, CPointEntity ); - - -class CBubbling : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - - void EXPORT FizzThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - virtual int ObjectCaps( void ) { return CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - static TYPEDESCRIPTION m_SaveData[]; - - int m_density; - int m_frequency; - int m_bubbleModel; - int m_state; -}; - -LINK_ENTITY_TO_CLASS( env_bubbles, CBubbling ); - -TYPEDESCRIPTION CBubbling::m_SaveData[] = -{ - DEFINE_FIELD( CBubbling, m_density, FIELD_INTEGER ), - DEFINE_FIELD( CBubbling, m_frequency, FIELD_INTEGER ), - DEFINE_FIELD( CBubbling, m_state, FIELD_INTEGER ), - // Let spawn restore this! - // DEFINE_FIELD( CBubbling, m_bubbleModel, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CBubbling, CBaseEntity ); - - -#define SF_BUBBLES_STARTOFF 0x0001 - -void CBubbling::Spawn( void ) -{ - Precache( ); - SET_MODEL( ENT(pev), STRING(pev->model) ); // Set size - - pev->solid = SOLID_NOT; // Remove model & collisions - pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on - pev->rendermode = kRenderTransTexture; - int speed = pev->speed > 0 ? pev->speed : -pev->speed; - - // HACKHACK!!! - Speed in rendercolor - pev->rendercolor.x = speed >> 8; - pev->rendercolor.y = speed & 255; - pev->rendercolor.z = (pev->speed < 0) ? 1 : 0; - - - if ( !(pev->spawnflags & SF_BUBBLES_STARTOFF) ) - { - SetThink( &CBubbling::FizzThink ); - pev->nextthink = gpGlobals->time + 2.0; - m_state = 1; - } - else - m_state = 0; -} - -void CBubbling::Precache( void ) -{ - m_bubbleModel = PRECACHE_MODEL("sprites/bubble.spr"); // Precache bubble sprite -} - - -void CBubbling::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( ShouldToggle( useType, m_state ) ) - m_state = !m_state; - - if ( m_state ) - { - SetThink( & CBubbling::FizzThink ); - pev->nextthink = gpGlobals->time + 0.1; - } - else - { - SetThink( NULL ); - pev->nextthink = 0; - } -} - - -void CBubbling::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "density")) - { - m_density = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "frequency")) - { - m_frequency = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "current")) - { - pev->speed = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -void CBubbling::FizzThink( void ) -{ - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, VecBModelOrigin(pev) ); - WRITE_BYTE( TE_FIZZ ); - WRITE_SHORT( (short)ENTINDEX( edict() ) ); - WRITE_SHORT( (short)m_bubbleModel ); - WRITE_BYTE( m_density ); - MESSAGE_END(); - - if ( m_frequency > 19 ) - pev->nextthink = gpGlobals->time + 0.5; - else - pev->nextthink = gpGlobals->time + 2.5 - (0.1 * m_frequency); -} - -// -------------------------------------------------- -// -// Beams -// -// -------------------------------------------------- - -LINK_ENTITY_TO_CLASS( beam, CBeam ); - -void CBeam::Spawn( void ) -{ - pev->solid = SOLID_NOT; // Remove model & collisions - Precache( ); -} - -void CBeam::Precache( void ) -{ - if ( pev->owner ) - SetStartEntity( ENTINDEX( pev->owner ) ); - if ( pev->aiment ) - SetEndEntity( ENTINDEX( pev->aiment ) ); -} - -void CBeam::SetStartEntity( int entityIndex ) -{ - pev->sequence = (entityIndex & 0x0FFF) | ((pev->sequence&0xF000)<<12); - pev->owner = g_engfuncs.pfnPEntityOfEntIndex( entityIndex ); -} - -void CBeam::SetEndEntity( int entityIndex ) -{ - pev->skin = (entityIndex & 0x0FFF) | ((pev->skin&0xF000)<<12); - pev->aiment = g_engfuncs.pfnPEntityOfEntIndex( entityIndex ); -} - - -// These don't take attachments into account -const Vector &CBeam::GetStartPos( void ) -{ - if ( GetType() == BEAM_ENTS ) - { - edict_t *pent = g_engfuncs.pfnPEntityOfEntIndex( GetStartEntity() ); - return pent->v.origin; - } - return pev->origin; -} - - -const Vector &CBeam::GetEndPos( void ) -{ - int type = GetType(); - if ( type == BEAM_POINTS || type == BEAM_HOSE ) - { - return pev->angles; - } - - edict_t *pent = g_engfuncs.pfnPEntityOfEntIndex( GetEndEntity() ); - if ( pent ) - return pent->v.origin; - return pev->angles; -} - - -CBeam *CBeam::BeamCreate( const char *pSpriteName, int width ) -{ - // Create a new entity with CBeam private data - CBeam *pBeam = GetClassPtr( (CBeam *)NULL ); - pBeam->pev->classname = MAKE_STRING("beam"); - - pBeam->BeamInit( pSpriteName, width ); - - return pBeam; -} - - -void CBeam::BeamInit( const char *pSpriteName, int width ) -{ - pev->flags |= FL_CUSTOMENTITY; - SetColor( 255, 255, 255 ); - SetBrightness( 255 ); - SetNoise( 0 ); - SetFrame( 0 ); - SetScrollRate( 0 ); - pev->model = MAKE_STRING( pSpriteName ); - SetTexture( PRECACHE_MODEL( (char *)pSpriteName ) ); - SetWidth( width ); - pev->skin = 0; - pev->sequence = 0; - pev->rendermode = 0; -} - - -void CBeam::PointsInit( const Vector &start, const Vector &end ) -{ - SetType( BEAM_POINTS ); - SetStartPos( start ); - SetEndPos( end ); - SetStartAttachment( 0 ); - SetEndAttachment( 0 ); - RelinkBeam(); -} - - -void CBeam::HoseInit( const Vector &start, const Vector &direction ) -{ - SetType( BEAM_HOSE ); - SetStartPos( start ); - SetEndPos( direction ); - SetStartAttachment( 0 ); - SetEndAttachment( 0 ); - RelinkBeam(); -} - - -void CBeam::PointEntInit( const Vector &start, int endIndex ) -{ - SetType( BEAM_ENTPOINT ); - SetStartPos( start ); - SetEndEntity( endIndex ); - SetStartAttachment( 0 ); - SetEndAttachment( 0 ); - RelinkBeam(); -} - -void CBeam::EntsInit( int startIndex, int endIndex ) -{ - SetType( BEAM_ENTS ); - SetStartEntity( startIndex ); - SetEndEntity( endIndex ); - SetStartAttachment( 0 ); - SetEndAttachment( 0 ); - RelinkBeam(); -} - - -void CBeam::RelinkBeam( void ) -{ - const Vector &startPos = GetStartPos(), &endPos = GetEndPos(); - - pev->mins.x = V_min( startPos.x, endPos.x ); - pev->mins.y = V_min( startPos.y, endPos.y ); - pev->mins.z = V_min( startPos.z, endPos.z ); - pev->maxs.x = V_max( startPos.x, endPos.x ); - pev->maxs.y = V_max( startPos.y, endPos.y ); - pev->maxs.z = V_max( startPos.z, endPos.z ); - pev->mins = pev->mins - pev->origin; - pev->maxs = pev->maxs - pev->origin; - - UTIL_SetSize( pev, pev->mins, pev->maxs ); - UTIL_SetOrigin( pev, pev->origin ); -} - -#if 0 -void CBeam::SetObjectCollisionBox( void ) -{ - const Vector &startPos = GetStartPos(), &endPos = GetEndPos(); - - pev->absmin.x = V_min( startPos.x, endPos.x ); - pev->absmin.y = V_min( startPos.y, endPos.y ); - pev->absmin.z = V_min( startPos.z, endPos.z ); - pev->absmax.x = V_max( startPos.x, endPos.x ); - pev->absmax.y = V_max( startPos.y, endPos.y ); - pev->absmax.z = V_max( startPos.z, endPos.z ); -} -#endif - - -void CBeam::TriggerTouch( CBaseEntity *pOther ) -{ - if ( pOther->pev->flags & (FL_CLIENT | FL_MONSTER) ) - { - if ( pev->owner ) - { - CBaseEntity *pOwner = CBaseEntity::Instance(pev->owner); - pOwner->Use( pOther, this, USE_TOGGLE, 0 ); - } - ALERT( at_console, "Firing targets!!!\n" ); - } -} - - -CBaseEntity *CBeam::RandomTargetname( const char *szName ) -{ - int total = 0; - - CBaseEntity *pEntity = NULL; - CBaseEntity *pNewEntity = NULL; - while ((pNewEntity = UTIL_FindEntityByTargetname( pNewEntity, szName )) != NULL) - { - total++; - if (RANDOM_LONG(0,total-1) < 1) - pEntity = pNewEntity; - } - return pEntity; -} - - -void CBeam::DoSparks( const Vector &start, const Vector &end ) -{ - if ( pev->spawnflags & (SF_BEAM_SPARKSTART|SF_BEAM_SPARKEND) ) - { - if ( pev->spawnflags & SF_BEAM_SPARKSTART ) - { - UTIL_Sparks( start ); - } - if ( pev->spawnflags & SF_BEAM_SPARKEND ) - { - UTIL_Sparks( end ); - } - } -} - - -class CLightning : public CBeam -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - void Activate( void ); - - void EXPORT StrikeThink( void ); - void EXPORT DamageThink( void ); - void RandomArea( void ); - void RandomPoint( Vector &vecSrc ); - void Zap( const Vector &vecSrc, const Vector &vecDest ); - void EXPORT StrikeUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - inline BOOL ServerSide( void ) - { - if ( m_life == 0 && !(pev->spawnflags & SF_BEAM_RING) ) - return TRUE; - return FALSE; - } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - void BeamUpdateVars( void ); - - int m_active; - int m_iszStartEntity; - int m_iszEndEntity; - float m_life; - int m_boltWidth; - int m_noiseAmplitude; - int m_brightness; - int m_speed; - float m_restrike; - int m_spriteTexture; - int m_iszSpriteName; - int m_frameStart; - - float m_radius; -}; - -LINK_ENTITY_TO_CLASS( env_lightning, CLightning ); -LINK_ENTITY_TO_CLASS( env_beam, CLightning ); - -// UNDONE: Jay -- This is only a test -#if _DEBUG -class CTripBeam : public CLightning -{ - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS( trip_beam, CTripBeam ); - -void CTripBeam::Spawn( void ) -{ - CLightning::Spawn(); - SetTouch( &CTripBeam::TriggerTouch ); - pev->solid = SOLID_TRIGGER; - RelinkBeam(); -} -#endif - - - -TYPEDESCRIPTION CLightning::m_SaveData[] = -{ - DEFINE_FIELD( CLightning, m_active, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_iszStartEntity, FIELD_STRING ), - DEFINE_FIELD( CLightning, m_iszEndEntity, FIELD_STRING ), - DEFINE_FIELD( CLightning, m_life, FIELD_FLOAT ), - DEFINE_FIELD( CLightning, m_boltWidth, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_noiseAmplitude, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_brightness, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_speed, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_restrike, FIELD_FLOAT ), - DEFINE_FIELD( CLightning, m_spriteTexture, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_iszSpriteName, FIELD_STRING ), - DEFINE_FIELD( CLightning, m_frameStart, FIELD_INTEGER ), - DEFINE_FIELD( CLightning, m_radius, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CLightning, CBeam ); - - -void CLightning::Spawn( void ) -{ - if ( FStringNull( m_iszSpriteName ) ) - { - SetThink( &CLightning::SUB_Remove ); - return; - } - pev->solid = SOLID_NOT; // Remove model & collisions - Precache( ); - - pev->dmgtime = gpGlobals->time; - - if ( ServerSide() ) - { - SetThink( NULL ); - if ( pev->dmg > 0 ) - { - SetThink( &CLightning::DamageThink ); - pev->nextthink = gpGlobals->time + 0.1; - } - if ( pev->targetname ) - { - if ( !(pev->spawnflags & SF_BEAM_STARTON) ) - { - pev->effects = EF_NODRAW; - m_active = 0; - pev->nextthink = 0; - } - else - m_active = 1; - - SetUse( &CLightning::ToggleUse ); - } - } - else - { - m_active = 0; - if ( !FStringNull(pev->targetname) ) - { - SetUse( &CLightning::StrikeUse ); - } - if ( FStringNull(pev->targetname) || FBitSet(pev->spawnflags, SF_BEAM_STARTON) ) - { - SetThink( &CLightning::StrikeThink ); - pev->nextthink = gpGlobals->time + 1.0; - } - } -} - -void CLightning::Precache( void ) -{ - m_spriteTexture = PRECACHE_MODEL( (char *)STRING(m_iszSpriteName) ); - CBeam::Precache(); -} - - -void CLightning::Activate( void ) -{ - if ( ServerSide() ) - BeamUpdateVars(); -} - - -void CLightning::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "LightningStart")) - { - m_iszStartEntity = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "LightningEnd")) - { - m_iszEndEntity = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "life")) - { - m_life = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "BoltWidth")) - { - m_boltWidth = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "NoiseAmplitude")) - { - m_noiseAmplitude = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "TextureScroll")) - { - m_speed = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "StrikeTime")) - { - m_restrike = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "texture")) - { - m_iszSpriteName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "framestart")) - { - m_frameStart = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "Radius")) - { - m_radius = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "damage")) - { - pev->dmg = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBeam::KeyValue( pkvd ); -} - - -void CLightning::ToggleUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, m_active ) ) - return; - if ( m_active ) - { - m_active = 0; - pev->effects |= EF_NODRAW; - pev->nextthink = 0; - } - else - { - m_active = 1; - pev->effects &= ~EF_NODRAW; - DoSparks( GetStartPos(), GetEndPos() ); - if ( pev->dmg > 0 ) - { - pev->nextthink = gpGlobals->time; - pev->dmgtime = gpGlobals->time; - } - } -} - - -void CLightning::StrikeUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, m_active ) ) - return; - - if ( m_active ) - { - m_active = 0; - SetThink( NULL ); - } - else - { - SetThink( &CLightning::StrikeThink ); - pev->nextthink = gpGlobals->time + 0.1; - } - - if ( !FBitSet( pev->spawnflags, SF_BEAM_TOGGLE ) ) - SetUse( NULL ); -} - - -int IsPointEntity( CBaseEntity *pEnt ) -{ - if ( !pEnt->pev->modelindex ) - return 1; - if ( FClassnameIs( pEnt->pev, "info_target" ) || FClassnameIs( pEnt->pev, "info_landmark" ) || FClassnameIs( pEnt->pev, "path_corner" ) ) - return 1; - - return 0; -} - - -void CLightning::StrikeThink( void ) -{ - if ( m_life != 0 ) - { - if ( pev->spawnflags & SF_BEAM_RANDOM ) - pev->nextthink = gpGlobals->time + m_life + RANDOM_FLOAT( 0, m_restrike ); - else - pev->nextthink = gpGlobals->time + m_life + m_restrike; - } - m_active = 1; - - if (FStringNull(m_iszEndEntity)) - { - if (FStringNull(m_iszStartEntity)) - { - RandomArea( ); - } - else - { - CBaseEntity *pStart = RandomTargetname( STRING(m_iszStartEntity) ); - if (pStart != NULL) - RandomPoint( pStart->pev->origin ); - else - ALERT( at_console, "env_beam: unknown entity \"%s\"\n", STRING(m_iszStartEntity) ); - } - return; - } - - CBaseEntity *pStart = RandomTargetname( STRING(m_iszStartEntity) ); - CBaseEntity *pEnd = RandomTargetname( STRING(m_iszEndEntity) ); - - if ( pStart != NULL && pEnd != NULL ) - { - if ( IsPointEntity( pStart ) || IsPointEntity( pEnd ) ) - { - if ( pev->spawnflags & SF_BEAM_RING) - { - // don't work - return; - } - } - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - if ( IsPointEntity( pStart ) || IsPointEntity( pEnd ) ) - { - if ( !IsPointEntity( pEnd ) ) // One point entity must be in pEnd - { - CBaseEntity *pTemp; - pTemp = pStart; - pStart = pEnd; - pEnd = pTemp; - } - if ( !IsPointEntity( pStart ) ) // One sided - { - WRITE_BYTE( TE_BEAMENTPOINT ); - WRITE_SHORT( pStart->entindex() ); - WRITE_COORD( pEnd->pev->origin.x); - WRITE_COORD( pEnd->pev->origin.y); - WRITE_COORD( pEnd->pev->origin.z); - } - else - { - WRITE_BYTE( TE_BEAMPOINTS); - WRITE_COORD( pStart->pev->origin.x); - WRITE_COORD( pStart->pev->origin.y); - WRITE_COORD( pStart->pev->origin.z); - WRITE_COORD( pEnd->pev->origin.x); - WRITE_COORD( pEnd->pev->origin.y); - WRITE_COORD( pEnd->pev->origin.z); - } - - - } - else - { - if ( pev->spawnflags & SF_BEAM_RING) - WRITE_BYTE( TE_BEAMRING ); - else - WRITE_BYTE( TE_BEAMENTS ); - WRITE_SHORT( pStart->entindex() ); - WRITE_SHORT( pEnd->entindex() ); - } - - WRITE_SHORT( m_spriteTexture ); - WRITE_BYTE( m_frameStart ); // framestart - WRITE_BYTE( (int)pev->framerate); // framerate - WRITE_BYTE( (int)(m_life*10.0) ); // life - WRITE_BYTE( m_boltWidth ); // width - WRITE_BYTE( m_noiseAmplitude ); // noise - WRITE_BYTE( (int)pev->rendercolor.x ); // r, g, b - WRITE_BYTE( (int)pev->rendercolor.y ); // r, g, b - WRITE_BYTE( (int)pev->rendercolor.z ); // r, g, b - WRITE_BYTE( pev->renderamt ); // brightness - WRITE_BYTE( m_speed ); // speed - MESSAGE_END(); - DoSparks( pStart->pev->origin, pEnd->pev->origin ); - if ( pev->dmg > 0 ) - { - TraceResult tr; - UTIL_TraceLine( pStart->pev->origin, pEnd->pev->origin, dont_ignore_monsters, NULL, &tr ); - BeamDamageInstant( &tr, pev->dmg ); - } - } -} - - -void CBeam::BeamDamage( TraceResult *ptr ) -{ - RelinkBeam(); - if ( ptr->flFraction != 1.0 && ptr->pHit != NULL ) - { - CBaseEntity *pHit = CBaseEntity::Instance(ptr->pHit); - if ( pHit ) - { - ClearMultiDamage(); - pHit->TraceAttack( pev, pev->dmg * (gpGlobals->time - pev->dmgtime), (ptr->vecEndPos - pev->origin).Normalize(), ptr, DMG_ENERGYBEAM ); - ApplyMultiDamage( pev, pev ); - if ( pev->spawnflags & SF_BEAM_DECALS ) - { - if ( pHit->IsBSPModel() ) - UTIL_DecalTrace( ptr, DECAL_BIGSHOT1 + RANDOM_LONG(0,4) ); - } - } - } - pev->dmgtime = gpGlobals->time; -} - - -void CLightning::DamageThink( void ) -{ - pev->nextthink = gpGlobals->time + 0.1; - TraceResult tr; - UTIL_TraceLine( GetStartPos(), GetEndPos(), dont_ignore_monsters, NULL, &tr ); - BeamDamage( &tr ); -} - - - -void CLightning::Zap( const Vector &vecSrc, const Vector &vecDest ) -{ -#if 1 - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_BEAMPOINTS); - WRITE_COORD(vecSrc.x); - WRITE_COORD(vecSrc.y); - WRITE_COORD(vecSrc.z); - WRITE_COORD(vecDest.x); - WRITE_COORD(vecDest.y); - WRITE_COORD(vecDest.z); - WRITE_SHORT( m_spriteTexture ); - WRITE_BYTE( m_frameStart ); // framestart - WRITE_BYTE( (int)pev->framerate); // framerate - WRITE_BYTE( (int)(m_life*10.0) ); // life - WRITE_BYTE( m_boltWidth ); // width - WRITE_BYTE( m_noiseAmplitude ); // noise - WRITE_BYTE( (int)pev->rendercolor.x ); // r, g, b - WRITE_BYTE( (int)pev->rendercolor.y ); // r, g, b - WRITE_BYTE( (int)pev->rendercolor.z ); // r, g, b - WRITE_BYTE( pev->renderamt ); // brightness - WRITE_BYTE( m_speed ); // speed - MESSAGE_END(); -#else - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE(TE_LIGHTNING); - WRITE_COORD(vecSrc.x); - WRITE_COORD(vecSrc.y); - WRITE_COORD(vecSrc.z); - WRITE_COORD(vecDest.x); - WRITE_COORD(vecDest.y); - WRITE_COORD(vecDest.z); - WRITE_BYTE(10); - WRITE_BYTE(50); - WRITE_BYTE(40); - WRITE_SHORT(m_spriteTexture); - MESSAGE_END(); -#endif - DoSparks( vecSrc, vecDest ); -} - -void CLightning::RandomArea( void ) -{ - int iLoops = 0; - - for (iLoops = 0; iLoops < 10; iLoops++) - { - Vector vecSrc = pev->origin; - - Vector vecDir1 = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) ); - vecDir1 = vecDir1.Normalize(); - TraceResult tr1; - UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, ignore_monsters, ENT(pev), &tr1 ); - - if (tr1.flFraction == 1.0) - continue; - - Vector vecDir2; - do { - vecDir2 = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) ); - } while (DotProduct(vecDir1, vecDir2 ) > 0); - vecDir2 = vecDir2.Normalize(); - TraceResult tr2; - UTIL_TraceLine( vecSrc, vecSrc + vecDir2 * m_radius, ignore_monsters, ENT(pev), &tr2 ); - - if (tr2.flFraction == 1.0) - continue; - - if ((tr1.vecEndPos - tr2.vecEndPos).Length() < m_radius * 0.1) - continue; - - UTIL_TraceLine( tr1.vecEndPos, tr2.vecEndPos, ignore_monsters, ENT(pev), &tr2 ); - - if (tr2.flFraction != 1.0) - continue; - - Zap( tr1.vecEndPos, tr2.vecEndPos ); - - break; - } -} - - -void CLightning::RandomPoint( Vector &vecSrc ) -{ - int iLoops = 0; - - for (iLoops = 0; iLoops < 10; iLoops++) - { - Vector vecDir1 = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) ); - vecDir1 = vecDir1.Normalize(); - TraceResult tr1; - UTIL_TraceLine( vecSrc, vecSrc + vecDir1 * m_radius, ignore_monsters, ENT(pev), &tr1 ); - - if ((tr1.vecEndPos - vecSrc).Length() < m_radius * 0.1) - continue; - - if (tr1.flFraction == 1.0) - continue; - - Zap( vecSrc, tr1.vecEndPos ); - break; - } -} - - - -void CLightning::BeamUpdateVars( void ) -{ - int beamType; - int pointStart, pointEnd; - - edict_t *pStart = FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(m_iszStartEntity) ); - edict_t *pEnd = FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(m_iszEndEntity) ); - pointStart = IsPointEntity( CBaseEntity::Instance(pStart) ); - pointEnd = IsPointEntity( CBaseEntity::Instance(pEnd) ); - - pev->skin = 0; - pev->sequence = 0; - pev->rendermode = 0; - pev->flags |= FL_CUSTOMENTITY; - pev->model = m_iszSpriteName; - SetTexture( m_spriteTexture ); - - beamType = BEAM_ENTS; - if ( pointStart || pointEnd ) - { - if ( !pointStart ) // One point entity must be in pStart - { - edict_t *pTemp; - // Swap start & end - pTemp = pStart; - pStart = pEnd; - pEnd = pTemp; - int swap = pointStart; - pointStart = pointEnd; - pointEnd = swap; - } - if ( !pointEnd ) - beamType = BEAM_ENTPOINT; - else - beamType = BEAM_POINTS; - } - - SetType( beamType ); - if ( beamType == BEAM_POINTS || beamType == BEAM_ENTPOINT || beamType == BEAM_HOSE ) - { - SetStartPos( pStart->v.origin ); - if ( beamType == BEAM_POINTS || beamType == BEAM_HOSE ) - SetEndPos( pEnd->v.origin ); - else - SetEndEntity( ENTINDEX(pEnd) ); - } - else - { - SetStartEntity( ENTINDEX(pStart) ); - SetEndEntity( ENTINDEX(pEnd) ); - } - - RelinkBeam(); - - SetWidth( m_boltWidth ); - SetNoise( m_noiseAmplitude ); - SetFrame( m_frameStart ); - SetScrollRate( m_speed ); - if ( pev->spawnflags & SF_BEAM_SHADEIN ) - SetFlags( BEAM_FSHADEIN ); - else if ( pev->spawnflags & SF_BEAM_SHADEOUT ) - SetFlags( BEAM_FSHADEOUT ); -} - - -LINK_ENTITY_TO_CLASS( env_laser, CLaser ); - -TYPEDESCRIPTION CLaser::m_SaveData[] = -{ - DEFINE_FIELD( CLaser, m_pSprite, FIELD_CLASSPTR ), - DEFINE_FIELD( CLaser, m_iszSpriteName, FIELD_STRING ), - DEFINE_FIELD( CLaser, m_firePosition, FIELD_POSITION_VECTOR ), -}; - -IMPLEMENT_SAVERESTORE( CLaser, CBeam ); - -void CLaser::Spawn( void ) -{ - if ( FStringNull( pev->model ) ) - { - SetThink( &CLaser::SUB_Remove ); - return; - } - pev->solid = SOLID_NOT; // Remove model & collisions - Precache( ); - - SetThink( &CLaser::StrikeThink ); - pev->flags |= FL_CUSTOMENTITY; - - PointsInit( pev->origin, pev->origin ); - - if ( !m_pSprite && m_iszSpriteName ) - m_pSprite = CSprite::SpriteCreate( STRING(m_iszSpriteName), pev->origin, TRUE ); - else - m_pSprite = NULL; - - if ( m_pSprite ) - m_pSprite->SetTransparency( kRenderGlow, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, pev->renderamt, pev->renderfx ); - - if ( pev->targetname && !(pev->spawnflags & SF_BEAM_STARTON) ) - TurnOff(); - else - TurnOn(); -} - -void CLaser::Precache( void ) -{ - pev->modelindex = PRECACHE_MODEL( (char *)STRING(pev->model) ); - if ( m_iszSpriteName ) - PRECACHE_MODEL( (char *)STRING(m_iszSpriteName) ); -} - - -void CLaser::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "LaserTarget")) - { - pev->message = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "width")) - { - SetWidth( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "NoiseAmplitude")) - { - SetNoise( atoi(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "TextureScroll")) - { - SetScrollRate( atoi(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "texture")) - { - pev->model = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "EndSprite")) - { - m_iszSpriteName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "framestart")) - { - pev->frame = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "damage")) - { - pev->dmg = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBeam::KeyValue( pkvd ); -} - - -int CLaser::IsOn( void ) -{ - if (pev->effects & EF_NODRAW) - return 0; - return 1; -} - - -void CLaser::TurnOff( void ) -{ - pev->effects |= EF_NODRAW; - pev->nextthink = 0; - if ( m_pSprite ) - m_pSprite->TurnOff(); -} - - -void CLaser::TurnOn( void ) -{ - pev->effects &= ~EF_NODRAW; - if ( m_pSprite ) - m_pSprite->TurnOn(); - pev->dmgtime = gpGlobals->time; - pev->nextthink = gpGlobals->time; -} - - -void CLaser::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int active = IsOn(); - - if ( !ShouldToggle( useType, active ) ) - return; - if ( active ) - { - TurnOff(); - } - else - { - TurnOn(); - } -} - - -void CLaser::FireAtPoint( TraceResult &tr ) -{ - SetEndPos( tr.vecEndPos ); - if ( m_pSprite ) - UTIL_SetOrigin( m_pSprite->pev, tr.vecEndPos ); - - BeamDamage( &tr ); - DoSparks( GetStartPos(), tr.vecEndPos ); -} - -void CLaser::StrikeThink( void ) -{ - CBaseEntity *pEnd = RandomTargetname( STRING(pev->message) ); - - if ( pEnd ) - m_firePosition = pEnd->pev->origin; - - TraceResult tr; - - UTIL_TraceLine( pev->origin, m_firePosition, dont_ignore_monsters, NULL, &tr ); - FireAtPoint( tr ); - pev->nextthink = gpGlobals->time + 0.1; -} - - - -class CGlow : public CPointEntity -{ -public: - void Spawn( void ); - void Think( void ); - void Animate( float frames ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - float m_lastTime; - float m_maxFrame; -}; - -LINK_ENTITY_TO_CLASS( env_glow, CGlow ); - -TYPEDESCRIPTION CGlow::m_SaveData[] = -{ - DEFINE_FIELD( CGlow, m_lastTime, FIELD_TIME ), - DEFINE_FIELD( CGlow, m_maxFrame, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CGlow, CPointEntity ); - -void CGlow::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; - - PRECACHE_MODEL( (char *)STRING(pev->model) ); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1; - if ( m_maxFrame > 1.0 && pev->framerate != 0 ) - pev->nextthink = gpGlobals->time + 0.1; - - m_lastTime = gpGlobals->time; -} - - -void CGlow::Think( void ) -{ - Animate( pev->framerate * (gpGlobals->time - m_lastTime) ); - - pev->nextthink = gpGlobals->time + 0.1; - m_lastTime = gpGlobals->time; -} - - -void CGlow::Animate( float frames ) -{ - if ( m_maxFrame > 0 ) - pev->frame = fmod( pev->frame + frames, m_maxFrame ); -} - - -LINK_ENTITY_TO_CLASS( env_sprite, CSprite ); - -TYPEDESCRIPTION CSprite::m_SaveData[] = -{ - DEFINE_FIELD( CSprite, m_lastTime, FIELD_TIME ), - DEFINE_FIELD( CSprite, m_maxFrame, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CSprite, CPointEntity ); - -void CSprite::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; - - Precache(); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1; - if ( pev->targetname && !(pev->spawnflags & SF_SPRITE_STARTON) ) - TurnOff(); - else - TurnOn(); - - // Worldcraft only sets y rotation, copy to Z - if ( pev->angles.y != 0 && pev->angles.z == 0 ) - { - pev->angles.z = pev->angles.y; - pev->angles.y = 0; - } -} - - -void CSprite::Precache( void ) -{ - PRECACHE_MODEL( (char *)STRING(pev->model) ); - - // Reset attachment after save/restore - if ( pev->aiment ) - SetAttachment( pev->aiment, pev->body ); - else - { - // Clear attachment - pev->skin = 0; - pev->body = 0; - } -} - - -void CSprite::SpriteInit( const char *pSpriteName, const Vector &origin ) -{ - pev->model = MAKE_STRING(pSpriteName); - pev->origin = origin; - Spawn(); -} - -CSprite *CSprite::SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate ) -{ - CSprite *pSprite = GetClassPtr( (CSprite *)NULL ); - pSprite->SpriteInit( pSpriteName, origin ); - pSprite->pev->classname = MAKE_STRING("env_sprite"); - pSprite->pev->solid = SOLID_NOT; - pSprite->pev->movetype = MOVETYPE_NOCLIP; - if ( animate ) - pSprite->TurnOn(); - - return pSprite; -} - - -void CSprite::AnimateThink( void ) -{ - Animate( pev->framerate * (gpGlobals->time - m_lastTime) ); - - pev->nextthink = gpGlobals->time + 0.1; - m_lastTime = gpGlobals->time; -} - -void CSprite::AnimateUntilDead( void ) -{ - if ( gpGlobals->time > pev->dmgtime ) - UTIL_Remove(this); - else - { - AnimateThink(); - pev->nextthink = gpGlobals->time; - } -} - -void CSprite::Expand( float scaleSpeed, float fadeSpeed ) -{ - pev->speed = scaleSpeed; - pev->health = fadeSpeed; - SetThink( &CSprite::ExpandThink ); - - pev->nextthink = gpGlobals->time; - m_lastTime = gpGlobals->time; -} - - -void CSprite::ExpandThink( void ) -{ - float frametime = gpGlobals->time - m_lastTime; - pev->scale += pev->speed * frametime; - pev->renderamt -= pev->health * frametime; - if ( pev->renderamt <= 0 ) - { - pev->renderamt = 0; - UTIL_Remove( this ); - } - else - { - pev->nextthink = gpGlobals->time + 0.1; - m_lastTime = gpGlobals->time; - } -} - - -void CSprite::Animate( float frames ) -{ - pev->frame += frames; - if ( pev->frame > m_maxFrame ) - { - if ( pev->spawnflags & SF_SPRITE_ONCE ) - { - TurnOff(); - } - else - { - if ( m_maxFrame > 0 ) - pev->frame = fmod( pev->frame, m_maxFrame ); - } - } -} - - -void CSprite::TurnOff( void ) -{ - pev->effects = EF_NODRAW; - pev->nextthink = 0; -} - - -void CSprite::TurnOn( void ) -{ - pev->effects = 0; - if ( (pev->framerate && m_maxFrame > 1.0) || (pev->spawnflags & SF_SPRITE_ONCE) ) - { - SetThink( &CSprite::AnimateThink ); - pev->nextthink = gpGlobals->time; - m_lastTime = gpGlobals->time; - } - pev->frame = 0; -} - - -void CSprite::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int on = pev->effects != EF_NODRAW; - if ( ShouldToggle( useType, on ) ) - { - if ( on ) - { - TurnOff(); - } - else - { - TurnOn(); - } - } -} - - -class CGibShooter : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT ShootThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual CGib *CreateGib( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - int m_iGibs; - int m_iGibCapacity; - int m_iGibMaterial; - int m_iGibModelIndex; - float m_flGibVelocity; - float m_flVariance; - float m_flGibLife; -}; - -TYPEDESCRIPTION CGibShooter::m_SaveData[] = -{ - DEFINE_FIELD( CGibShooter, m_iGibs, FIELD_INTEGER ), - DEFINE_FIELD( CGibShooter, m_iGibCapacity, FIELD_INTEGER ), - DEFINE_FIELD( CGibShooter, m_iGibMaterial, FIELD_INTEGER ), - DEFINE_FIELD( CGibShooter, m_iGibModelIndex, FIELD_INTEGER ), - DEFINE_FIELD( CGibShooter, m_flGibVelocity, FIELD_FLOAT ), - DEFINE_FIELD( CGibShooter, m_flVariance, FIELD_FLOAT ), - DEFINE_FIELD( CGibShooter, m_flGibLife, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CGibShooter, CBaseDelay ); -LINK_ENTITY_TO_CLASS( gibshooter, CGibShooter ); - - -void CGibShooter :: Precache ( void ) -{ - if ( g_Language == LANGUAGE_GERMAN ) - { - m_iGibModelIndex = PRECACHE_MODEL ("models/germanygibs.mdl"); - } - else - { - m_iGibModelIndex = PRECACHE_MODEL ("models/hgibs.mdl"); - } -} - - -void CGibShooter::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "m_iGibs")) - { - m_iGibs = m_iGibCapacity = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_flVelocity")) - { - m_flGibVelocity = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_flVariance")) - { - m_flVariance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_flGibLife")) - { - m_flGibLife = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - { - CBaseDelay::KeyValue( pkvd ); - } -} - -void CGibShooter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetThink( &CGibShooter::ShootThink ); - pev->nextthink = gpGlobals->time; -} - -void CGibShooter::Spawn( void ) -{ - Precache(); - - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; - - if ( m_flDelay == 0 ) - { - m_flDelay = 0.1; - } - - if ( m_flGibLife == 0 ) - { - m_flGibLife = 25; - } - - SetMovedir ( pev ); - pev->body = MODEL_FRAMES( m_iGibModelIndex ); -} - - -CGib *CGibShooter :: CreateGib ( void ) -{ - if ( CVAR_GET_FLOAT("violence_hgibs") == 0 ) - return NULL; - - CGib *pGib = GetClassPtr( (CGib *)NULL ); - pGib->Spawn( "models/hgibs.mdl" ); - pGib->m_bloodColor = BLOOD_COLOR_RED; - - if ( pev->body <= 1 ) - { - ALERT ( at_aiconsole, "GibShooter Body is <= 1!\n" ); - } - - pGib->pev->body = RANDOM_LONG ( 1, pev->body - 1 );// avoid throwing random amounts of the 0th gib. (skull). - - return pGib; -} - - -void CGibShooter :: ShootThink ( void ) -{ - pev->nextthink = gpGlobals->time + m_flDelay; - - Vector vecShootDir; - - vecShootDir = pev->movedir; - - vecShootDir = vecShootDir + gpGlobals->v_right * RANDOM_FLOAT( -1, 1) * m_flVariance;; - vecShootDir = vecShootDir + gpGlobals->v_forward * RANDOM_FLOAT( -1, 1) * m_flVariance;; - vecShootDir = vecShootDir + gpGlobals->v_up * RANDOM_FLOAT( -1, 1) * m_flVariance;; - - vecShootDir = vecShootDir.Normalize(); - CGib *pGib = CreateGib(); - - if ( pGib ) - { - pGib->pev->origin = pev->origin; - pGib->pev->velocity = vecShootDir * m_flGibVelocity; - - pGib->pev->avelocity.x = RANDOM_FLOAT ( 100, 200 ); - pGib->pev->avelocity.y = RANDOM_FLOAT ( 100, 300 ); - - float thinkTime = pGib->pev->nextthink - gpGlobals->time; - - pGib->m_lifeTime = (m_flGibLife * RANDOM_FLOAT( 0.95, 1.05 )); // +/- 5% - if ( pGib->m_lifeTime < thinkTime ) - { - pGib->pev->nextthink = gpGlobals->time + pGib->m_lifeTime; - pGib->m_lifeTime = 0; - } - - } - - if ( --m_iGibs <= 0 ) - { - if ( pev->spawnflags & SF_GIBSHOOTER_REPEATABLE ) - { - m_iGibs = m_iGibCapacity; - SetThink ( NULL ); - pev->nextthink = gpGlobals->time; - } - else - { - SetThink ( &CGibShooter::SUB_Remove ); - pev->nextthink = gpGlobals->time; - } - } -} - - -class CEnvShooter : public CGibShooter -{ - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - - CGib *CreateGib( void ); -}; - -LINK_ENTITY_TO_CLASS( env_shooter, CEnvShooter ); - -void CEnvShooter :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "shootmodel")) - { - pev->model = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "shootsounds")) - { - int iNoise = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - switch( iNoise ) - { - case 0: - m_iGibMaterial = matGlass; - break; - case 1: - m_iGibMaterial = matWood; - break; - case 2: - m_iGibMaterial = matMetal; - break; - case 3: - m_iGibMaterial = matFlesh; - break; - case 4: - m_iGibMaterial = matRocks; - break; - - default: - case -1: - m_iGibMaterial = matNone; - break; - } - } - else - { - CGibShooter::KeyValue( pkvd ); - } -} - - -void CEnvShooter :: Precache ( void ) -{ - m_iGibModelIndex = PRECACHE_MODEL( (char *)STRING(pev->model) ); - CBreakable::MaterialSoundPrecache( (Materials)m_iGibMaterial ); -} - - -CGib *CEnvShooter :: CreateGib ( void ) -{ - CGib *pGib = GetClassPtr( (CGib *)NULL ); - - pGib->Spawn( STRING(pev->model) ); - - int bodyPart = 0; - - if ( pev->body > 1 ) - bodyPart = RANDOM_LONG( 0, pev->body-1 ); - - pGib->pev->body = bodyPart; - pGib->m_bloodColor = DONT_BLEED; - pGib->m_material = m_iGibMaterial; - - pGib->pev->rendermode = pev->rendermode; - pGib->pev->renderamt = pev->renderamt; - pGib->pev->rendercolor = pev->rendercolor; - pGib->pev->renderfx = pev->renderfx; - pGib->pev->scale = pev->scale; - pGib->pev->skin = pev->skin; - - return pGib; -} - - - - -class CTestEffect : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - // void KeyValue( KeyValueData *pkvd ); - void EXPORT TestThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - int m_iLoop; - int m_iBeam; - CBeam *m_pBeam[24]; - float m_flBeamTime[24]; - float m_flStartTime; -}; - - -LINK_ENTITY_TO_CLASS( test_effect, CTestEffect ); - -void CTestEffect::Spawn( void ) -{ - Precache( ); -} - -void CTestEffect::Precache( void ) -{ - PRECACHE_MODEL( "sprites/lgtning.spr" ); -} - -void CTestEffect::TestThink( void ) -{ - int i; - float t = (gpGlobals->time - m_flStartTime); - - if (m_iBeam < 24) - { - CBeam *pbeam = CBeam::BeamCreate( "sprites/lgtning.spr", 100 ); - - TraceResult tr; - - Vector vecSrc = pev->origin; - Vector vecDir = Vector( RANDOM_FLOAT( -1.0, 1.0 ), RANDOM_FLOAT( -1.0, 1.0 ),RANDOM_FLOAT( -1.0, 1.0 ) ); - vecDir = vecDir.Normalize(); - UTIL_TraceLine( vecSrc, vecSrc + vecDir * 128, ignore_monsters, ENT(pev), &tr); - - pbeam->PointsInit( vecSrc, tr.vecEndPos ); - // pbeam->SetColor( 80, 100, 255 ); - pbeam->SetColor( 255, 180, 100 ); - pbeam->SetWidth( 100 ); - pbeam->SetScrollRate( 12 ); - - m_flBeamTime[m_iBeam] = gpGlobals->time; - m_pBeam[m_iBeam] = pbeam; - m_iBeam++; - -#if 0 - Vector vecMid = (vecSrc + tr.vecEndPos) * 0.5; - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE(TE_DLIGHT); - WRITE_COORD(vecMid.x); // X - WRITE_COORD(vecMid.y); // Y - WRITE_COORD(vecMid.z); // Z - WRITE_BYTE( 20 ); // radius * 0.1 - WRITE_BYTE( 255 ); // r - WRITE_BYTE( 180 ); // g - WRITE_BYTE( 100 ); // b - WRITE_BYTE( 20 ); // time * 10 - WRITE_BYTE( 0 ); // decay * 0.1 - MESSAGE_END( ); -#endif - } - - if (t < 3.0) - { - for (i = 0; i < m_iBeam; i++) - { - t = (gpGlobals->time - m_flBeamTime[i]) / ( 3 + m_flStartTime - m_flBeamTime[i]); - m_pBeam[i]->SetBrightness( 255 * t ); - // m_pBeam[i]->SetScrollRate( 20 * t ); - } - pev->nextthink = gpGlobals->time + 0.1; - } - else - { - for (i = 0; i < m_iBeam; i++) - { - UTIL_Remove( m_pBeam[i] ); - } - m_flStartTime = gpGlobals->time; - m_iBeam = 0; - // pev->nextthink = gpGlobals->time; - SetThink( NULL ); - } -} - - -void CTestEffect::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetThink( &CTestEffect::TestThink ); - pev->nextthink = gpGlobals->time + 0.1; - m_flStartTime = gpGlobals->time; -} - - - -// Blood effects -class CBlood : public CPointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - inline int Color( void ) { return pev->impulse; } - inline float BloodAmount( void ) { return pev->dmg; } - - inline void SetColor( int color ) { pev->impulse = color; } - inline void SetBloodAmount( float amount ) { pev->dmg = amount; } - - Vector Direction( void ); - Vector BloodPosition( CBaseEntity *pActivator ); - -private: -}; - -LINK_ENTITY_TO_CLASS( env_blood, CBlood ); - - - -#define SF_BLOOD_RANDOM 0x0001 -#define SF_BLOOD_STREAM 0x0002 -#define SF_BLOOD_PLAYER 0x0004 -#define SF_BLOOD_DECAL 0x0008 - -void CBlood::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; - SetMovedir( pev ); -} - - -void CBlood::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "color")) - { - int color = atoi(pkvd->szValue); - switch( color ) - { - case 1: - SetColor( BLOOD_COLOR_YELLOW ); - break; - default: - SetColor( BLOOD_COLOR_RED ); - break; - } - - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "amount")) - { - SetBloodAmount( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -Vector CBlood::Direction( void ) -{ - if ( pev->spawnflags & SF_BLOOD_RANDOM ) - return UTIL_RandomBloodVector(); - - return pev->movedir; -} - - -Vector CBlood::BloodPosition( CBaseEntity *pActivator ) -{ - if ( pev->spawnflags & SF_BLOOD_PLAYER ) - { - edict_t *pPlayer; - - if ( pActivator && pActivator->IsPlayer() ) - { - pPlayer = pActivator->edict(); - } - else - pPlayer = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - if ( pPlayer ) - return (pPlayer->v.origin + pPlayer->v.view_ofs) + Vector( RANDOM_FLOAT(-10,10), RANDOM_FLOAT(-10,10), RANDOM_FLOAT(-10,10) ); - } - - return pev->origin; -} - - -void CBlood::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->spawnflags & SF_BLOOD_STREAM ) - UTIL_BloodStream( BloodPosition(pActivator), Direction(), Color(), BloodAmount() ); - else - UTIL_BloodDrips( BloodPosition(pActivator), Direction(), Color(), BloodAmount() ); - - if ( pev->spawnflags & SF_BLOOD_DECAL ) - { - Vector forward = Direction(); - Vector start = BloodPosition( pActivator ); - TraceResult tr; - - UTIL_TraceLine( start, start + forward * BloodAmount() * 2, ignore_monsters, NULL, &tr ); - if ( tr.flFraction != 1.0 ) - UTIL_BloodDecalTrace( &tr, Color() ); - } -} - - - -// Screen shake -class CShake : public CPointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - inline float Amplitude( void ) { return pev->scale; } - inline float Frequency( void ) { return pev->dmg_save; } - inline float Duration( void ) { return pev->dmg_take; } - inline float Radius( void ) { return pev->dmg; } - - inline void SetAmplitude( float amplitude ) { pev->scale = amplitude; } - inline void SetFrequency( float frequency ) { pev->dmg_save = frequency; } - inline void SetDuration( float duration ) { pev->dmg_take = duration; } - inline void SetRadius( float radius ) { pev->dmg = radius; } -private: -}; - -LINK_ENTITY_TO_CLASS( env_shake, CShake ); - -// pev->scale is amplitude -// pev->dmg_save is frequency -// pev->dmg_take is duration -// pev->dmg is radius -// radius of 0 means all players -// NOTE: UTIL_ScreenShake() will only shake players who are on the ground - -#define SF_SHAKE_EVERYONE 0x0001 // Don't check radius -// UNDONE: These don't work yet -#define SF_SHAKE_DISRUPT 0x0002 // Disrupt controls -#define SF_SHAKE_INAIR 0x0004 // Shake players in air - -void CShake::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; - - if ( pev->spawnflags & SF_SHAKE_EVERYONE ) - pev->dmg = 0; -} - - -void CShake::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "amplitude")) - { - SetAmplitude( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "frequency")) - { - SetFrequency( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "duration")) - { - SetDuration( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "radius")) - { - SetRadius( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -void CShake::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - UTIL_ScreenShake( pev->origin, Amplitude(), Frequency(), Duration(), Radius() ); -} - - -class CFade : public CPointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - inline float Duration( void ) { return pev->dmg_take; } - inline float HoldTime( void ) { return pev->dmg_save; } - - inline void SetDuration( float duration ) { pev->dmg_take = duration; } - inline void SetHoldTime( float hold ) { pev->dmg_save = hold; } -private: -}; - -LINK_ENTITY_TO_CLASS( env_fade, CFade ); - -// pev->dmg_take is duration -// pev->dmg_save is hold duration -#define SF_FADE_IN 0x0001 // Fade in, not out -#define SF_FADE_MODULATE 0x0002 // Modulate, don't blend -#define SF_FADE_ONLYONE 0x0004 - -void CFade::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = 0; - pev->frame = 0; -} - - -void CFade::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "duration")) - { - SetDuration( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "holdtime")) - { - SetHoldTime( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -void CFade::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int fadeFlags = 0; - - if ( !(pev->spawnflags & SF_FADE_IN) ) - fadeFlags |= FFADE_OUT; - - if ( pev->spawnflags & SF_FADE_MODULATE ) - fadeFlags |= FFADE_MODULATE; - - if ( pev->spawnflags & SF_FADE_ONLYONE ) - { - if ( pActivator->IsNetClient() ) - { - UTIL_ScreenFade( pActivator, pev->rendercolor, Duration(), HoldTime(), pev->renderamt, fadeFlags ); - } - } - else - { - UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), pev->renderamt, fadeFlags ); - } - SUB_UseTargets( this, USE_TOGGLE, 0 ); -} - - -class CMessage : public CPointEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); -private: -}; - -LINK_ENTITY_TO_CLASS( env_message, CMessage ); - - -void CMessage::Spawn( void ) -{ - Precache(); - - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - - switch( pev->impulse ) - { - case 1: // Medium radius - pev->speed = ATTN_STATIC; - break; - - case 2: // Large radius - pev->speed = ATTN_NORM; - break; - - case 3: //EVERYWHERE - pev->speed = ATTN_NONE; - break; - - default: - case 0: // Small radius - pev->speed = ATTN_IDLE; - break; - } - pev->impulse = 0; - - // No volume, use normal - if ( pev->scale <= 0 ) - pev->scale = 1.0; -} - - -void CMessage::Precache( void ) -{ - if ( pev->noise ) - PRECACHE_SOUND( (char *)STRING(pev->noise) ); -} - -void CMessage::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "messagesound")) - { - pev->noise = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "messagevolume")) - { - pev->scale = atof(pkvd->szValue) * 0.1; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "messageattenuation")) - { - pev->impulse = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -void CMessage::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - CBaseEntity *pPlayer = NULL; - - if ( pev->spawnflags & SF_MESSAGE_ALL ) - UTIL_ShowMessageAll( STRING(pev->message) ); - else - { - if ( pActivator && pActivator->IsPlayer() ) - pPlayer = pActivator; - else - { - pPlayer = CBaseEntity::Instance( g_engfuncs.pfnPEntityOfEntIndex( 1 ) ); - } - if ( pPlayer ) - UTIL_ShowMessage( STRING(pev->message), pPlayer ); - } - if ( pev->noise ) - { - EMIT_SOUND( edict(), CHAN_BODY, STRING(pev->noise), pev->scale, pev->speed ); - } - if ( pev->spawnflags & SF_MESSAGE_ONCE ) - UTIL_Remove( this ); - - SUB_UseTargets( this, USE_TOGGLE, 0 ); -} - - - -//========================================================= -// FunnelEffect -//========================================================= -class CEnvFunnel : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - int m_iSprite; // Don't save, precache -}; - -void CEnvFunnel :: Precache ( void ) -{ - m_iSprite = PRECACHE_MODEL ( "sprites/flare6.spr" ); -} - -LINK_ENTITY_TO_CLASS( env_funnel, CEnvFunnel ); - -void CEnvFunnel::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_LARGEFUNNEL ); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( m_iSprite ); - - if ( pev->spawnflags & SF_FUNNEL_REVERSE )// funnel flows in reverse? - { - WRITE_SHORT( 1 ); - } - else - { - WRITE_SHORT( 0 ); - } - - - MESSAGE_END(); - - SetThink( &CEnvFunnel::SUB_Remove ); - pev->nextthink = gpGlobals->time; -} - -void CEnvFunnel::Spawn( void ) -{ - Precache(); - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; -} - -//========================================================= -// Beverage Dispenser -// overloaded pev->frags, is now a flag for whether or not a can is stuck in the dispenser. -// overloaded pev->health, is now how many cans remain in the machine. -//========================================================= -class CEnvBeverage : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); -}; - -void CEnvBeverage :: Precache ( void ) -{ - PRECACHE_MODEL( "models/can.mdl" ); - PRECACHE_SOUND( "weapons/g_bounce3.wav" ); -} - -LINK_ENTITY_TO_CLASS( env_beverage, CEnvBeverage ); - -void CEnvBeverage::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->frags != 0 || pev->health <= 0 ) - { - // no more cans while one is waiting in the dispenser, or if I'm out of cans. - return; - } - - CBaseEntity *pCan = CBaseEntity::Create( "item_sodacan", pev->origin, pev->angles, edict() ); - - if ( pev->skin == 6 ) - { - // random - pCan->pev->skin = RANDOM_LONG( 0, 5 ); - } - else - { - pCan->pev->skin = pev->skin; - } - - pev->frags = 1; - pev->health--; - - //SetThink (SUB_Remove); - //pev->nextthink = gpGlobals->time; -} - -void CEnvBeverage::Spawn( void ) -{ - Precache(); - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; - pev->frags = 0; - - if ( pev->health == 0 ) - { - pev->health = 10; - } -} - -//========================================================= -// Soda can -//========================================================= -class CItemSoda : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void EXPORT CanThink ( void ); - void EXPORT CanTouch ( CBaseEntity *pOther ); -}; - -void CItemSoda :: Precache ( void ) -{ -} - -LINK_ENTITY_TO_CLASS( item_sodacan, CItemSoda ); - -void CItemSoda::Spawn( void ) -{ - Precache(); - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_TOSS; - - SET_MODEL ( ENT(pev), "models/can.mdl" ); - UTIL_SetSize ( pev, Vector ( 0, 0, 0 ), Vector ( 0, 0, 0 ) ); - - SetThink (&CItemSoda::CanThink); - pev->nextthink = gpGlobals->time + 0.5; -} - -void CItemSoda::CanThink ( void ) -{ - EMIT_SOUND (ENT(pev), CHAN_WEAPON, "weapons/g_bounce3.wav", 1, ATTN_NORM ); - - pev->solid = SOLID_TRIGGER; - UTIL_SetSize ( pev, Vector ( -8, -8, 0 ), Vector ( 8, 8, 8 ) ); - SetThink ( NULL ); - SetTouch ( &CItemSoda::CanTouch ); -} - -void CItemSoda::CanTouch ( CBaseEntity *pOther ) -{ - if ( !pOther->IsPlayer() ) - { - return; - } - - // spoit sound here - - pOther->TakeHealth( 1, DMG_GENERIC );// a bit of health. - - if ( !FNullEnt( pev->owner ) ) - { - // tell the machine the can was taken - pev->owner->v.frags = 0; - } - - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = EF_NODRAW; - SetTouch ( NULL ); - SetThink ( &CItemSoda::SUB_Remove ); - pev->nextthink = gpGlobals->time; -} diff --git a/ricochet/dlls/effects.h b/ricochet/dlls/effects.h deleted file mode 100644 index d517268..0000000 --- a/ricochet/dlls/effects.h +++ /dev/null @@ -1,209 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef EFFECTS_H -#define EFFECTS_H - -#define SF_BEAM_STARTON 0x0001 -#define SF_BEAM_TOGGLE 0x0002 -#define SF_BEAM_RANDOM 0x0004 -#define SF_BEAM_RING 0x0008 -#define SF_BEAM_SPARKSTART 0x0010 -#define SF_BEAM_SPARKEND 0x0020 -#define SF_BEAM_DECALS 0x0040 -#define SF_BEAM_SHADEIN 0x0080 -#define SF_BEAM_SHADEOUT 0x0100 -#define SF_BEAM_TEMPORARY 0x8000 - -#define SF_SPRITE_STARTON 0x0001 -#define SF_SPRITE_ONCE 0x0002 -#define SF_SPRITE_TEMPORARY 0x8000 - -class CSprite : public CPointEntity -{ -public: - void Spawn( void ); - void Precache( void ); - - int ObjectCaps( void ) - { - int flags = 0; - if ( pev->spawnflags & SF_SPRITE_TEMPORARY ) - flags = FCAP_DONT_SAVE; - return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | flags; - } - void EXPORT AnimateThink( void ); - void EXPORT ExpandThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void Animate( float frames ); - void Expand( float scaleSpeed, float fadeSpeed ); - void SpriteInit( const char *pSpriteName, const Vector &origin ); - - inline void SetAttachment( edict_t *pEntity, int attachment ) - { - if ( pEntity ) - { - pev->skin = ENTINDEX(pEntity); - pev->body = attachment; - pev->aiment = pEntity; - pev->movetype = MOVETYPE_FOLLOW; - } - } - void TurnOff( void ); - void TurnOn( void ); - inline float Frames( void ) { return m_maxFrame; } - inline void SetTransparency( int rendermode, int r, int g, int b, int a, int fx ) - { - pev->rendermode = rendermode; - pev->rendercolor.x = r; - pev->rendercolor.y = g; - pev->rendercolor.z = b; - pev->renderamt = a; - pev->renderfx = fx; - } - inline void SetTexture( int spriteIndex ) { pev->modelindex = spriteIndex; } - inline void SetScale( float scale ) { pev->scale = scale; } - inline void SetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; } - inline void SetBrightness( int brightness ) { pev->renderamt = brightness; } - - inline void AnimateAndDie( float framerate ) - { - SetThink(&CSprite::AnimateUntilDead); - pev->framerate = framerate; - pev->dmgtime = gpGlobals->time + (m_maxFrame / framerate); - pev->nextthink = gpGlobals->time; - } - - void EXPORT AnimateUntilDead( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - static CSprite *SpriteCreate( const char *pSpriteName, const Vector &origin, BOOL animate ); - -private: - - float m_lastTime; - float m_maxFrame; -}; - - -class CBeam : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - int ObjectCaps( void ) - { - int flags = 0; - if ( pev->spawnflags & SF_BEAM_TEMPORARY ) - flags = FCAP_DONT_SAVE; - return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | flags; - } - - void EXPORT TriggerTouch( CBaseEntity *pOther ); - - // These functions are here to show the way beams are encoded as entities. - // Encoding beams as entities simplifies their management in the client/server architecture - inline void SetType( int type ) { pev->rendermode = (pev->rendermode & 0xF0) | (type&0x0F); } - inline void SetFlags( int flags ) { pev->rendermode = (pev->rendermode & 0x0F) | (flags&0xF0); } - inline void SetStartPos( const Vector& pos ) { pev->origin = pos; } - inline void SetEndPos( const Vector& pos ) { pev->angles = pos; } - void SetStartEntity( int entityIndex ); - void SetEndEntity( int entityIndex ); - - inline void SetStartAttachment( int attachment ) { pev->sequence = (pev->sequence & 0x0FFF) | ((attachment&0xF)<<12); } - inline void SetEndAttachment( int attachment ) { pev->skin = (pev->skin & 0x0FFF) | ((attachment&0xF)<<12); } - - inline void SetTexture( int spriteIndex ) { pev->modelindex = spriteIndex; } - inline void SetWidth( int width ) { pev->scale = width; } - inline void SetNoise( int amplitude ) { pev->body = amplitude; } - inline void SetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; } - inline void SetBrightness( int brightness ) { pev->renderamt = brightness; } - inline void SetFrame( float frame ) { pev->frame = frame; } - inline void SetScrollRate( int speed ) { pev->animtime = speed; } - - inline int GetType( void ) { return pev->rendermode & 0x0F; } - inline int GetFlags( void ) { return pev->rendermode & 0xF0; } - inline int GetStartEntity( void ) { return pev->sequence & 0xFFF; } - inline int GetEndEntity( void ) { return pev->skin & 0xFFF; } - - const Vector &GetStartPos( void ); - const Vector &GetEndPos( void ); - - Vector Center( void ) { return (GetStartPos() + GetEndPos()) * 0.5; }; // center point of beam - - inline int GetTexture( void ) { return pev->modelindex; } - inline int GetWidth( void ) { return pev->scale; } - inline int GetNoise( void ) { return pev->body; } - // inline void GetColor( int r, int g, int b ) { pev->rendercolor.x = r; pev->rendercolor.y = g; pev->rendercolor.z = b; } - inline int GetBrightness( void ) { return pev->renderamt; } - inline int GetFrame( void ) { return pev->frame; } - inline int GetScrollRate( void ) { return pev->animtime; } - - // Call after you change start/end positions - void RelinkBeam( void ); -// void SetObjectCollisionBox( void ); - - void DoSparks( const Vector &start, const Vector &end ); - CBaseEntity *RandomTargetname( const char *szName ); - void BeamDamage( TraceResult *ptr ); - // Init after BeamCreate() - void BeamInit( const char *pSpriteName, int width ); - void PointsInit( const Vector &start, const Vector &end ); - void PointEntInit( const Vector &start, int endIndex ); - void EntsInit( int startIndex, int endIndex ); - void HoseInit( const Vector &start, const Vector &direction ); - - static CBeam *BeamCreate( const char *pSpriteName, int width ); - - inline void LiveForTime( float time ) { SetThink(&CBeam::SUB_Remove); pev->nextthink = gpGlobals->time + time; } - inline void BeamDamageInstant( TraceResult *ptr, float damage ) - { - pev->dmg = damage; - pev->dmgtime = gpGlobals->time - 1; - BeamDamage(ptr); - } -}; - - -#define SF_MESSAGE_ONCE 0x0001 // Fade in, not out -#define SF_MESSAGE_ALL 0x0002 // Send to all clients - - -class CLaser : public CBeam -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - - void TurnOn( void ); - void TurnOff( void ); - int IsOn( void ); - - void FireAtPoint( TraceResult &point ); - - void EXPORT StrikeThink( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - CSprite *m_pSprite; - int m_iszSpriteName; - Vector m_firePosition; -}; - -#endif //EFFECTS_H diff --git a/ricochet/dlls/enginecallback.h b/ricochet/dlls/enginecallback.h deleted file mode 100644 index e960e9d..0000000 --- a/ricochet/dlls/enginecallback.h +++ /dev/null @@ -1,159 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef ENGINECALLBACK_H -#define ENGINECALLBACK_H -#pragma once - -#include "event_flags.h" - -// Must be provided by user of this code -extern enginefuncs_t g_engfuncs; - -// The actual engine callbacks -#define GETPLAYERUSERID (*g_engfuncs.pfnGetPlayerUserId) -#define PRECACHE_MODEL (*g_engfuncs.pfnPrecacheModel) -#define PRECACHE_SOUND (*g_engfuncs.pfnPrecacheSound) -#define PRECACHE_GENERIC (*g_engfuncs.pfnPrecacheGeneric) -#define SET_MODEL (*g_engfuncs.pfnSetModel) -#define MODEL_INDEX (*g_engfuncs.pfnModelIndex) -#define MODEL_FRAMES (*g_engfuncs.pfnModelFrames) -#define SET_SIZE (*g_engfuncs.pfnSetSize) -#define CHANGE_LEVEL (*g_engfuncs.pfnChangeLevel) -#define GET_SPAWN_PARMS (*g_engfuncs.pfnGetSpawnParms) -#define SAVE_SPAWN_PARMS (*g_engfuncs.pfnSaveSpawnParms) -#define VEC_TO_YAW (*g_engfuncs.pfnVecToYaw) -#define VEC_TO_ANGLES (*g_engfuncs.pfnVecToAngles) -#define MOVE_TO_ORIGIN (*g_engfuncs.pfnMoveToOrigin) -#define oldCHANGE_YAW (*g_engfuncs.pfnChangeYaw) -#define CHANGE_PITCH (*g_engfuncs.pfnChangePitch) -#define MAKE_VECTORS (*g_engfuncs.pfnMakeVectors) -#define CREATE_ENTITY (*g_engfuncs.pfnCreateEntity) -#define REMOVE_ENTITY (*g_engfuncs.pfnRemoveEntity) -#define CREATE_NAMED_ENTITY (*g_engfuncs.pfnCreateNamedEntity) -#define MAKE_STATIC (*g_engfuncs.pfnMakeStatic) -#define ENT_IS_ON_FLOOR (*g_engfuncs.pfnEntIsOnFloor) -#define DROP_TO_FLOOR (*g_engfuncs.pfnDropToFloor) -#define WALK_MOVE (*g_engfuncs.pfnWalkMove) -#define SET_ORIGIN (*g_engfuncs.pfnSetOrigin) -#define EMIT_SOUND_DYN2 (*g_engfuncs.pfnEmitSound) -#define BUILD_SOUND_MSG (*g_engfuncs.pfnBuildSoundMsg) -#define TRACE_LINE (*g_engfuncs.pfnTraceLine) -#define TRACE_TOSS (*g_engfuncs.pfnTraceToss) -#define TRACE_MONSTER_HULL (*g_engfuncs.pfnTraceMonsterHull) -#define TRACE_HULL (*g_engfuncs.pfnTraceHull) -#define GET_AIM_VECTOR (*g_engfuncs.pfnGetAimVector) -#define SERVER_COMMAND (*g_engfuncs.pfnServerCommand) -#define SERVER_EXECUTE (*g_engfuncs.pfnServerExecute) -#define CLIENT_COMMAND (*g_engfuncs.pfnClientCommand) -#define PARTICLE_EFFECT (*g_engfuncs.pfnParticleEffect) -#define LIGHT_STYLE (*g_engfuncs.pfnLightStyle) -#define DECAL_INDEX (*g_engfuncs.pfnDecalIndex) -#define POINT_CONTENTS (*g_engfuncs.pfnPointContents) -#define CRC32_INIT (*g_engfuncs.pfnCRC32_Init) -#define CRC32_PROCESS_BUFFER (*g_engfuncs.pfnCRC32_ProcessBuffer) -#define CRC32_PROCESS_BYTE (*g_engfuncs.pfnCRC32_ProcessByte) -#define CRC32_FINAL (*g_engfuncs.pfnCRC32_Final) -#define RANDOM_LONG (*g_engfuncs.pfnRandomLong) -#define RANDOM_FLOAT (*g_engfuncs.pfnRandomFloat) -#define GETPLAYERAUTHID (*g_engfuncs.pfnGetPlayerAuthId) - -inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin = NULL, edict_t *ed = NULL ) { - (*g_engfuncs.pfnMessageBegin)(msg_dest, msg_type, pOrigin, ed); -} -#define MESSAGE_END (*g_engfuncs.pfnMessageEnd) -#define WRITE_BYTE (*g_engfuncs.pfnWriteByte) -#define WRITE_CHAR (*g_engfuncs.pfnWriteChar) -#define WRITE_SHORT (*g_engfuncs.pfnWriteShort) -#define WRITE_LONG (*g_engfuncs.pfnWriteLong) -#define WRITE_ANGLE (*g_engfuncs.pfnWriteAngle) -#define WRITE_COORD (*g_engfuncs.pfnWriteCoord) -#define WRITE_STRING (*g_engfuncs.pfnWriteString) -#define WRITE_ENTITY (*g_engfuncs.pfnWriteEntity) -#define CVAR_REGISTER (*g_engfuncs.pfnCVarRegister) -#define CVAR_GET_FLOAT (*g_engfuncs.pfnCVarGetFloat) -#define CVAR_GET_STRING (*g_engfuncs.pfnCVarGetString) -#define CVAR_SET_FLOAT (*g_engfuncs.pfnCVarSetFloat) -#define CVAR_SET_STRING (*g_engfuncs.pfnCVarSetString) -#define ALERT (*g_engfuncs.pfnAlertMessage) -#define ENGINE_FPRINTF (*g_engfuncs.pfnEngineFprintf) -#define ALLOC_PRIVATE (*g_engfuncs.pfnPvAllocEntPrivateData) -inline void *GET_PRIVATE( edict_t *pent ) -{ - if ( pent ) - return pent->pvPrivateData; - return NULL; -} - -#define FREE_PRIVATE (*g_engfuncs.pfnFreeEntPrivateData) -//#define STRING (*g_engfuncs.pfnSzFromIndex) -#define ALLOC_STRING (*g_engfuncs.pfnAllocString) -#define FIND_ENTITY_BY_STRING (*g_engfuncs.pfnFindEntityByString) -#define GETENTITYILLUM (*g_engfuncs.pfnGetEntityIllum) -#define FIND_ENTITY_IN_SPHERE (*g_engfuncs.pfnFindEntityInSphere) -#define FIND_CLIENT_IN_PVS (*g_engfuncs.pfnFindClientInPVS) -#define EMIT_AMBIENT_SOUND (*g_engfuncs.pfnEmitAmbientSound) -#define GET_MODEL_PTR (*g_engfuncs.pfnGetModelPtr) -#define REG_USER_MSG (*g_engfuncs.pfnRegUserMsg) -#define GET_BONE_POSITION (*g_engfuncs.pfnGetBonePosition) -#define FUNCTION_FROM_NAME (*g_engfuncs.pfnFunctionFromName) -#define NAME_FOR_FUNCTION (*g_engfuncs.pfnNameForFunction) -#define TRACE_TEXTURE (*g_engfuncs.pfnTraceTexture) -#define CLIENT_PRINTF (*g_engfuncs.pfnClientPrintf) -#define CMD_ARGS (*g_engfuncs.pfnCmd_Args) -#define CMD_ARGC (*g_engfuncs.pfnCmd_Argc) -#define CMD_ARGV (*g_engfuncs.pfnCmd_Argv) -#define GET_ATTACHMENT (*g_engfuncs.pfnGetAttachment) -#define SET_VIEW (*g_engfuncs.pfnSetView) -#define SET_CROSSHAIRANGLE (*g_engfuncs.pfnCrosshairAngle) -#define LOAD_FILE_FOR_ME (*g_engfuncs.pfnLoadFileForMe) -#define FREE_FILE (*g_engfuncs.pfnFreeFile) -#define COMPARE_FILE_TIME (*g_engfuncs.pfnCompareFileTime) -#define GET_GAME_DIR (*g_engfuncs.pfnGetGameDir) -#define IS_MAP_VALID (*g_engfuncs.pfnIsMapValid) -#define NUMBER_OF_ENTITIES (*g_engfuncs.pfnNumberOfEntities) -#define IS_DEDICATED_SERVER (*g_engfuncs.pfnIsDedicatedServer) - -#define CVAR_GET_POINTER (*g_engfuncs.pfnCVarGetPointer) - -#define PRECACHE_EVENT (*g_engfuncs.pfnPrecacheEvent) -#define PLAYBACK_EVENT_FULL (*g_engfuncs.pfnPlaybackEvent) - -#define ENGINE_SET_PVS (*g_engfuncs.pfnSetFatPVS) -#define ENGINE_SET_PAS (*g_engfuncs.pfnSetFatPAS) - -#define ENGINE_CHECK_VISIBILITY (*g_engfuncs.pfnCheckVisibility) - -#define DELTA_SET ( *g_engfuncs.pfnDeltaSetField ) -#define DELTA_UNSET ( *g_engfuncs.pfnDeltaUnsetField ) -#define DELTA_ADDENCODER ( *g_engfuncs.pfnDeltaAddEncoder ) -#define ENGINE_CURRENT_PLAYER ( *g_engfuncs.pfnGetCurrentPlayer ) - -#define ENGINE_CANSKIP ( *g_engfuncs.pfnCanSkipPlayer ) - -#define DELTA_FINDFIELD ( *g_engfuncs.pfnDeltaFindField ) -#define DELTA_SETBYINDEX ( *g_engfuncs.pfnDeltaSetFieldByIndex ) -#define DELTA_UNSETBYINDEX ( *g_engfuncs.pfnDeltaUnsetFieldByIndex ) - -#define ENGINE_GETPHYSINFO ( *g_engfuncs.pfnGetPhysicsInfoString ) - -#define ENGINE_SETGROUPMASK ( *g_engfuncs.pfnSetGroupMask ) - -#define ENGINE_INSTANCE_BASELINE ( *g_engfuncs.pfnCreateInstancedBaseline ) - -#define ENGINE_FORCE_UNMODIFIED ( *g_engfuncs.pfnForceUnmodified ) - -#define PLAYER_CNX_STATS ( *g_engfuncs.pfnGetPlayerStats ) - -#endif //ENGINECALLBACK_H diff --git a/ricochet/dlls/explode.cpp b/ricochet/dlls/explode.cpp deleted file mode 100644 index adce53a..0000000 --- a/ricochet/dlls/explode.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== explode.cpp ======================================================== - - Explosion-related code - -*/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "decals.h" -#include "explode.h" - -// Spark Shower -class CShower : public CBaseEntity -{ - void Spawn( void ); - void Think( void ); - void Touch( CBaseEntity *pOther ); - int ObjectCaps( void ) { return FCAP_DONT_SAVE; } -}; - -LINK_ENTITY_TO_CLASS( spark_shower, CShower ); - -void CShower::Spawn( void ) -{ - pev->velocity = RANDOM_FLOAT( 200, 300 ) * pev->angles; - pev->velocity.x += RANDOM_FLOAT(-100.f,100.f); - pev->velocity.y += RANDOM_FLOAT(-100.f,100.f); - if ( pev->velocity.z >= 0 ) - pev->velocity.z += 200; - else - pev->velocity.z -= 200; - pev->movetype = MOVETYPE_BOUNCE; - pev->gravity = 0.5; - pev->nextthink = gpGlobals->time + 0.1; - pev->solid = SOLID_NOT; - SET_MODEL( edict(), "models/grenade.mdl"); // Need a model, just use the grenade, we don't draw it anyway - UTIL_SetSize(pev, g_vecZero, g_vecZero ); - pev->effects |= EF_NODRAW; - pev->speed = RANDOM_FLOAT( 0.5, 1.5 ); - - pev->angles = g_vecZero; -} - - -void CShower::Think( void ) -{ - UTIL_Sparks( pev->origin ); - - pev->speed -= 0.1; - if ( pev->speed > 0 ) - pev->nextthink = gpGlobals->time + 0.1; - else - UTIL_Remove( this ); - pev->flags &= ~FL_ONGROUND; -} - -void CShower::Touch( CBaseEntity *pOther ) -{ - if ( pev->flags & FL_ONGROUND ) - pev->velocity = pev->velocity * 0.1; - else - pev->velocity = pev->velocity * 0.6; - - if ( (pev->velocity.x*pev->velocity.x+pev->velocity.y*pev->velocity.y) < 10.0 ) - pev->speed = 0; -} - -class CEnvExplosion : public CBaseMonster -{ -public: - void Spawn( ); - void EXPORT Smoke ( void ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - int m_iMagnitude;// how large is the fireball? how much damage? - int m_spriteScale; // what's the exact fireball sprite scale? -}; - -TYPEDESCRIPTION CEnvExplosion::m_SaveData[] = -{ - DEFINE_FIELD( CEnvExplosion, m_iMagnitude, FIELD_INTEGER ), - DEFINE_FIELD( CEnvExplosion, m_spriteScale, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CEnvExplosion, CBaseMonster ); -LINK_ENTITY_TO_CLASS( env_explosion, CEnvExplosion ); - -void CEnvExplosion::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "iMagnitude")) - { - m_iMagnitude = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -void CEnvExplosion::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; - - pev->movetype = MOVETYPE_NONE; - /* - if ( m_iMagnitude > 250 ) - { - m_iMagnitude = 250; - } - */ - - float flSpriteScale; - flSpriteScale = ( m_iMagnitude - 50) * 0.6; - - /* - if ( flSpriteScale > 50 ) - { - flSpriteScale = 50; - } - */ - if ( flSpriteScale < 10 ) - { - flSpriteScale = 10; - } - - m_spriteScale = (int)flSpriteScale; -} - -void CEnvExplosion::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - TraceResult tr; - - pev->model = iStringNull;//invisible - pev->solid = SOLID_NOT;// intangible - - Vector vecSpot;// trace starts here! - - vecSpot = pev->origin + Vector ( 0 , 0 , 8 ); - - UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -40 ), ignore_monsters, ENT(pev), & tr); - - // Pull out of the wall a bit - if ( tr.flFraction != 1.0 ) - { - pev->origin = tr.vecEndPos + (tr.vecPlaneNormal * (m_iMagnitude - 24) * 0.6); - } - else - { - pev->origin = pev->origin; - } - - // draw decal - if (! ( pev->spawnflags & SF_ENVEXPLOSION_NODECAL)) - { - if ( RANDOM_FLOAT( 0 , 1 ) < 0.5 ) - { - UTIL_DecalTrace( &tr, DECAL_SCORCH1 ); - } - else - { - UTIL_DecalTrace( &tr, DECAL_SCORCH2 ); - } - } - - // draw fireball - if ( !( pev->spawnflags & SF_ENVEXPLOSION_NOFIREBALL ) ) - { - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); - WRITE_BYTE( TE_EXPLOSION); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( g_sModelIndexFireball ); - WRITE_BYTE( (BYTE)m_spriteScale ); // scale * 10 - WRITE_BYTE( 15 ); // framerate - WRITE_BYTE( TE_EXPLFLAG_NONE ); - MESSAGE_END(); - } - else - { - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); - WRITE_BYTE( TE_EXPLOSION); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( g_sModelIndexFireball ); - WRITE_BYTE( 0 ); // no sprite - WRITE_BYTE( 15 ); // framerate - WRITE_BYTE( TE_EXPLFLAG_NONE ); - MESSAGE_END(); - } - - // do damage - if ( !( pev->spawnflags & SF_ENVEXPLOSION_NODAMAGE ) ) - { - RadiusDamage ( pev, pev, m_iMagnitude, CLASS_NONE, DMG_BLAST ); - } - - SetThink( &CEnvExplosion::Smoke ); - pev->nextthink = gpGlobals->time + 0.3; - - // draw sparks - if ( !( pev->spawnflags & SF_ENVEXPLOSION_NOSPARKS ) ) - { - int sparkCount = RANDOM_LONG(0,3); - - for ( int i = 0; i < sparkCount; i++ ) - { - Create( "spark_shower", pev->origin, tr.vecPlaneNormal, NULL ); - } - } -} - -void CEnvExplosion::Smoke( void ) -{ - if ( !( pev->spawnflags & SF_ENVEXPLOSION_NOSMOKE ) ) - { - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); - WRITE_BYTE( TE_SMOKE ); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( g_sModelIndexSmoke ); - WRITE_BYTE( (BYTE)m_spriteScale ); // scale * 10 - WRITE_BYTE( 12 ); // framerate - MESSAGE_END(); - } - - if ( !(pev->spawnflags & SF_ENVEXPLOSION_REPEATABLE) ) - { - UTIL_Remove( this ); - } -} - - -// HACKHACK -- create one of these and fake a keyvalue to get the right explosion setup -void ExplosionCreate( const Vector ¢er, const Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage ) -{ - KeyValueData kvd; - char buf[128]; - - CBaseEntity *pExplosion = CBaseEntity::Create( "env_explosion", center, angles, pOwner ); - sprintf( buf, "%3d", magnitude ); - kvd.szKeyName = "iMagnitude"; - kvd.szValue = buf; - pExplosion->KeyValue( &kvd ); - if ( !doDamage ) - pExplosion->pev->spawnflags |= SF_ENVEXPLOSION_NODAMAGE; - - pExplosion->Spawn(); - pExplosion->Use( NULL, NULL, USE_TOGGLE, 0 ); -} diff --git a/ricochet/dlls/explode.h b/ricochet/dlls/explode.h deleted file mode 100644 index 202a581..0000000 --- a/ricochet/dlls/explode.h +++ /dev/null @@ -1,32 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef EXPLODE_H -#define EXPLODE_H - - -#define SF_ENVEXPLOSION_NODAMAGE ( 1 << 0 ) // when set, ENV_EXPLOSION will not actually inflict damage -#define SF_ENVEXPLOSION_REPEATABLE ( 1 << 1 ) // can this entity be refired? -#define SF_ENVEXPLOSION_NOFIREBALL ( 1 << 2 ) // don't draw the fireball -#define SF_ENVEXPLOSION_NOSMOKE ( 1 << 3 ) // don't draw the smoke -#define SF_ENVEXPLOSION_NODECAL ( 1 << 4 ) // don't make a scorch mark -#define SF_ENVEXPLOSION_NOSPARKS ( 1 << 5 ) // don't make a scorch mark - -extern DLL_GLOBAL short g_sModelIndexFireball; -extern DLL_GLOBAL short g_sModelIndexSmoke; - - -extern void ExplosionCreate( const Vector ¢er, const Vector &angles, edict_t *pOwner, int magnitude, BOOL doDamage ); - -#endif //EXPLODE_H diff --git a/ricochet/dlls/extdll.h b/ricochet/dlls/extdll.h deleted file mode 100644 index 451e79f..0000000 --- a/ricochet/dlls/extdll.h +++ /dev/null @@ -1,48 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef EXTDLL_H -#define EXTDLL_H - -#include "archtypes.h" // DAL - -// -// Global header file for extension DLLs -// - -#include "Platform.h" - -// Header file containing definition of globalvars_t and entvars_t -typedef unsigned int func_t; // -typedef unsigned int string_t; // from engine's pr_comp.h; -typedef float vec_t; // needed before including progdefs.h - -// Vector class -#include "vector.h" - -// Defining it as a (bogus) struct helps enforce type-checking -#define vec3_t Vector - -// Shared engine/DLL constants -#include "const.h" -#include "progdefs.h" -#include "edict.h" - -// Shared header describing protocol between engine and DLLs -#include "eiface.h" - -// Shared header between the client DLL and the game DLLs -#include "cdll_dll.h" - -#endif //EXTDLL_H diff --git a/ricochet/dlls/func_break.cpp b/ricochet/dlls/func_break.cpp deleted file mode 100644 index 086b075..0000000 --- a/ricochet/dlls/func_break.cpp +++ /dev/null @@ -1,998 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== bmodels.cpp ======================================================== - - spawn, think, and use functions for entities that use brush models - -*/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "func_break.h" -#include "decals.h" -#include "explode.h" - -extern DLL_GLOBAL Vector g_vecAttackDir; - -// =================== FUNC_Breakable ============================================== - -// Just add more items to the bottom of this array and they will automagically be supported -// This is done instead of just a classname in the FGD so we can control which entities can -// be spawned, and still remain fairly flexible -const char *CBreakable::pSpawnObjects[] = -{ - NULL, // 0 - "item_battery", // 1 - "item_healthkit", // 2 - "weapon_9mmhandgun",// 3 - "ammo_9mmclip", // 4 - "weapon_9mmAR", // 5 - "ammo_9mmAR", // 6 - "ammo_ARgrenades", // 7 - "weapon_shotgun", // 8 - "ammo_buckshot", // 9 - "weapon_crossbow", // 10 - "ammo_crossbow", // 11 - "weapon_357", // 12 - "ammo_357", // 13 - "weapon_rpg", // 14 - "ammo_rpgclip", // 15 - "ammo_gaussclip", // 16 - "weapon_handgrenade",// 17 - "weapon_tripmine", // 18 - "weapon_satchel", // 19 - "weapon_snark", // 20 - "weapon_hornetgun", // 21 -}; - -void CBreakable::KeyValue( KeyValueData* pkvd ) -{ - // UNDONE_WC: explicitly ignoring these fields, but they shouldn't be in the map file! - if (FStrEq(pkvd->szKeyName, "explosion")) - { - if (!stricmp(pkvd->szValue, "directed")) - m_Explosion = expDirected; - else if (!stricmp(pkvd->szValue, "random")) - m_Explosion = expRandom; - else - m_Explosion = expRandom; - - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "material")) - { - int i = atoi( pkvd->szValue); - - // 0:glass, 1:metal, 2:flesh, 3:wood - - if ((i < 0) || (i >= matLastMaterial)) - m_Material = matWood; - else - m_Material = (Materials)i; - - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "deadmodel")) - { - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "shards")) - { -// m_iShards = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "gibmodel") ) - { - m_iszGibModel = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spawnobject") ) - { - int object = atoi( pkvd->szValue ); - if ( object > 0 && object < ARRAYSIZE(pSpawnObjects) ) - m_iszSpawnObject = MAKE_STRING( pSpawnObjects[object] ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "explodemagnitude") ) - { - ExplosionSetMagnitude( atoi( pkvd->szValue ) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "lip") ) - pkvd->fHandled = TRUE; - else - CBaseDelay::KeyValue( pkvd ); -} - - -// -// func_breakable - bmodel that breaks into pieces after taking damage -// -LINK_ENTITY_TO_CLASS( func_breakable, CBreakable ); -TYPEDESCRIPTION CBreakable::m_SaveData[] = -{ - DEFINE_FIELD( CBreakable, m_Material, FIELD_INTEGER ), - DEFINE_FIELD( CBreakable, m_Explosion, FIELD_INTEGER ), - -// Don't need to save/restore these because we precache after restore -// DEFINE_FIELD( CBreakable, m_idShard, FIELD_INTEGER ), - - DEFINE_FIELD( CBreakable, m_angle, FIELD_FLOAT ), - DEFINE_FIELD( CBreakable, m_iszGibModel, FIELD_STRING ), - DEFINE_FIELD( CBreakable, m_iszSpawnObject, FIELD_STRING ), - - // Explosion magnitude is stored in pev->impulse -}; - -IMPLEMENT_SAVERESTORE( CBreakable, CBaseEntity ); - -void CBreakable::Spawn( void ) -{ - Precache( ); - - if ( FBitSet( pev->spawnflags, SF_BREAK_TRIGGER_ONLY ) ) - pev->takedamage = DAMAGE_NO; - else - pev->takedamage = DAMAGE_YES; - - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - m_angle = pev->angles.y; - pev->angles.y = 0; - - - SET_MODEL(ENT(pev), STRING(pev->model) );//set size and link into world. - - SetTouch( &CBreakable::BreakTouch ); - if ( FBitSet( pev->spawnflags, SF_BREAK_TRIGGER_ONLY ) ) // Only break on trigger - SetTouch( NULL ); - - // Flag unbreakable glass as "worldbrush" so it will block ALL tracelines - if ( !IsBreakable() && pev->rendermode != kRenderNormal ) - pev->flags |= FL_WORLDBRUSH; -} - - -const char *CBreakable::pSoundsWood[] = -{ - "debris/wood1.wav", - "debris/wood2.wav", - "debris/wood3.wav", -}; - -const char *CBreakable::pSoundsFlesh[] = -{ - "debris/flesh1.wav", - "debris/flesh2.wav", - "debris/flesh3.wav", - "debris/flesh5.wav", - "debris/flesh6.wav", - "debris/flesh7.wav", -}; - -const char *CBreakable::pSoundsMetal[] = -{ - "debris/metal1.wav", - "debris/metal2.wav", - "debris/metal3.wav", -}; - -const char *CBreakable::pSoundsConcrete[] = -{ - "debris/concrete1.wav", - "debris/concrete2.wav", - "debris/concrete3.wav", -}; - - -const char *CBreakable::pSoundsGlass[] = -{ - "debris/glass1.wav", - "debris/glass2.wav", - "debris/glass3.wav", -}; - -const char **CBreakable::MaterialSoundList( Materials precacheMaterial, int &soundCount ) -{ - const char **pSoundList = NULL; - - switch ( precacheMaterial ) - { - case matWood: - pSoundList = pSoundsWood; - soundCount = ARRAYSIZE(pSoundsWood); - break; - case matFlesh: - pSoundList = pSoundsFlesh; - soundCount = ARRAYSIZE(pSoundsFlesh); - break; - case matComputer: - case matUnbreakableGlass: - case matGlass: - pSoundList = pSoundsGlass; - soundCount = ARRAYSIZE(pSoundsGlass); - break; - - case matMetal: - pSoundList = pSoundsMetal; - soundCount = ARRAYSIZE(pSoundsMetal); - break; - - case matCinderBlock: - case matRocks: - pSoundList = pSoundsConcrete; - soundCount = ARRAYSIZE(pSoundsConcrete); - break; - - - case matCeilingTile: - case matNone: - default: - soundCount = 0; - break; - } - - return pSoundList; -} - -void CBreakable::MaterialSoundPrecache( Materials precacheMaterial ) -{ - const char **pSoundList; - int i, soundCount = 0; - - pSoundList = MaterialSoundList( precacheMaterial, soundCount ); - - for ( i = 0; i < soundCount; i++ ) - { - PRECACHE_SOUND( (char *)pSoundList[i] ); - } -} - -void CBreakable::MaterialSoundRandom( edict_t *pEdict, Materials soundMaterial, float volume ) -{ - const char **pSoundList; - int soundCount = 0; - - pSoundList = MaterialSoundList( soundMaterial, soundCount ); - - if ( soundCount ) - EMIT_SOUND( pEdict, CHAN_BODY, pSoundList[ RANDOM_LONG(0,soundCount-1) ], volume, 1.0 ); -} - - -void CBreakable::Precache( void ) -{ - const char *pGibName; - - switch (m_Material) - { - case matWood: - pGibName = "models/woodgibs.mdl"; - - PRECACHE_SOUND("debris/bustcrate1.wav"); - PRECACHE_SOUND("debris/bustcrate2.wav"); - break; - case matFlesh: - pGibName = "models/fleshgibs.mdl"; - - PRECACHE_SOUND("debris/bustflesh1.wav"); - PRECACHE_SOUND("debris/bustflesh2.wav"); - break; - case matComputer: - PRECACHE_SOUND("buttons/spark5.wav"); - PRECACHE_SOUND("buttons/spark6.wav"); - pGibName = "models/computergibs.mdl"; - - PRECACHE_SOUND("debris/bustmetal1.wav"); - PRECACHE_SOUND("debris/bustmetal2.wav"); - break; - - case matUnbreakableGlass: - case matGlass: - pGibName = "models/glassgibs.mdl"; - - PRECACHE_SOUND("debris/bustglass1.wav"); - PRECACHE_SOUND("debris/bustglass2.wav"); - break; - case matMetal: - pGibName = "models/metalplategibs.mdl"; - - PRECACHE_SOUND("debris/bustmetal1.wav"); - PRECACHE_SOUND("debris/bustmetal2.wav"); - break; - case matCinderBlock: - pGibName = "models/cindergibs.mdl"; - - PRECACHE_SOUND("debris/bustconcrete1.wav"); - PRECACHE_SOUND("debris/bustconcrete2.wav"); - break; - case matRocks: - pGibName = "models/rockgibs.mdl"; - - PRECACHE_SOUND("debris/bustconcrete1.wav"); - PRECACHE_SOUND("debris/bustconcrete2.wav"); - break; - case matCeilingTile: - pGibName = "models/ceilinggibs.mdl"; - - PRECACHE_SOUND ("debris/bustceiling.wav"); - break; - } - MaterialSoundPrecache( m_Material ); - if ( m_iszGibModel ) - pGibName = STRING(m_iszGibModel); - - m_idShard = PRECACHE_MODEL( (char *)pGibName ); - - // Precache the spawn item's data - if ( m_iszSpawnObject ) - UTIL_PrecacheOther( (char *)STRING( m_iszSpawnObject ) ); -} - -// play shard sound when func_breakable takes damage. -// the more damage, the louder the shard sound. - - -void CBreakable::DamageSound( void ) -{ - int pitch; - float fvol; - char *rgpsz[6]; - int i; - int material = m_Material; - -// if (RANDOM_LONG(0,1)) -// return; - - if (RANDOM_LONG(0,2)) - pitch = PITCH_NORM; - else - pitch = 95 + RANDOM_LONG(0,34); - - fvol = RANDOM_FLOAT(0.75, 1.0); - - if (material == matComputer && RANDOM_LONG(0,1)) - material = matMetal; - - switch (material) - { - case matComputer: - case matGlass: - case matUnbreakableGlass: - rgpsz[0] = "debris/glass1.wav"; - rgpsz[1] = "debris/glass2.wav"; - rgpsz[2] = "debris/glass3.wav"; - i = 3; - break; - - case matWood: - rgpsz[0] = "debris/wood1.wav"; - rgpsz[1] = "debris/wood2.wav"; - rgpsz[2] = "debris/wood3.wav"; - i = 3; - break; - - case matMetal: - rgpsz[0] = "debris/metal1.wav"; - rgpsz[1] = "debris/metal3.wav"; - rgpsz[2] = "debris/metal2.wav"; - i = 2; - break; - - case matFlesh: - rgpsz[0] = "debris/flesh1.wav"; - rgpsz[1] = "debris/flesh2.wav"; - rgpsz[2] = "debris/flesh3.wav"; - rgpsz[3] = "debris/flesh5.wav"; - rgpsz[4] = "debris/flesh6.wav"; - rgpsz[5] = "debris/flesh7.wav"; - i = 6; - break; - - case matRocks: - case matCinderBlock: - rgpsz[0] = "debris/concrete1.wav"; - rgpsz[1] = "debris/concrete2.wav"; - rgpsz[2] = "debris/concrete3.wav"; - i = 3; - break; - - case matCeilingTile: - // UNDONE: no ceiling tile shard sound yet - i = 0; - break; - } - - if (i) - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, rgpsz[RANDOM_LONG(0,i-1)], fvol, ATTN_NORM, 0, pitch); -} - -void CBreakable::BreakTouch( CBaseEntity *pOther ) -{ - float flDamage; - entvars_t* pevToucher = pOther->pev; - - // only players can break these right now - if ( !pOther->IsPlayer() || !IsBreakable() ) - { - return; - } - - if ( FBitSet ( pev->spawnflags, SF_BREAK_TOUCH ) ) - {// can be broken when run into - flDamage = pevToucher->velocity.Length() * 0.01; - - if (flDamage >= pev->health) - { - SetTouch( NULL ); - TakeDamage(pevToucher, pevToucher, flDamage, DMG_CRUSH); - - // do a little damage to player if we broke glass or computer - pOther->TakeDamage( pev, pev, flDamage/4, DMG_SLASH ); - } - } - - if ( FBitSet ( pev->spawnflags, SF_BREAK_PRESSURE ) && pevToucher->absmin.z >= pev->maxs.z - 2 ) - {// can be broken when stood upon - - // play creaking sound here. - DamageSound(); - - SetThink ( &CBreakable::Die ); - SetTouch( NULL ); - - if ( m_flDelay == 0 ) - {// !!!BUGBUG - why doesn't zero delay work? - m_flDelay = 0.1; - } - - pev->nextthink = pev->ltime + m_flDelay; - - } - -} - - -// -// Smash the our breakable object -// - -// Break when triggered -void CBreakable::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( IsBreakable() ) - { - pev->angles.y = m_angle; - UTIL_MakeVectors(pev->angles); - g_vecAttackDir = gpGlobals->v_forward; - - Die(); - } -} - - -void CBreakable::TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ) -{ - // random spark if this is a 'computer' object - if (RANDOM_LONG(0,1) ) - { - switch( m_Material ) - { - case matComputer: - { - UTIL_Sparks( ptr->vecEndPos ); - - float flVolume = RANDOM_FLOAT ( 0.7 , 1.0 );//random volume range - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM); break; - } - } - break; - - case matUnbreakableGlass: - UTIL_Ricochet( ptr->vecEndPos, RANDOM_FLOAT(0.5,1.5) ); - break; - } - } - - CBaseDelay::TraceAttack( pevAttacker, flDamage, vecDir, ptr, bitsDamageType ); -} - -//========================================================= -// Special takedamage for func_breakable. Allows us to make -// exceptions that are breakable-specific -// bitsDamageType indicates the type of damage sustained ie: DMG_CRUSH -//========================================================= -int CBreakable :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - Vector vecTemp; - - // if Attacker == Inflictor, the attack was a melee or other instant-hit attack. - // (that is, no actual entity projectile was involved in the attack so use the shooter's origin). - if ( pevAttacker == pevInflictor ) - { - vecTemp = pevInflictor->origin - ( pev->absmin + ( pev->size * 0.5 ) ); - - // if a client hit the breakable with a crowbar, and breakable is crowbar-sensitive, break it now. - if ( FBitSet ( pevAttacker->flags, FL_CLIENT ) && - FBitSet ( pev->spawnflags, SF_BREAK_CROWBAR ) && (bitsDamageType & DMG_CLUB)) - flDamage = pev->health; - } - else - // an actual missile was involved. - { - vecTemp = pevInflictor->origin - ( pev->absmin + ( pev->size * 0.5 ) ); - } - - if (!IsBreakable()) - return 0; - - // Breakables take double damage from the crowbar - if ( bitsDamageType & DMG_CLUB ) - flDamage *= 2; - - // Boxes / glass / etc. don't take much poison damage, just the impact of the dart - consider that 10% - if ( bitsDamageType & DMG_POISON ) - flDamage *= 0.1; - -// this global is still used for glass and other non-monster killables, along with decals. - g_vecAttackDir = vecTemp.Normalize(); - -// do the damage - pev->health -= flDamage; - if (pev->health <= 0) - { - Killed( pevAttacker, GIB_NORMAL ); - Die(); - return 0; - } - - // Make a shard noise each time func breakable is hit. - // Don't play shard noise if cbreakable actually died. - - DamageSound(); - - return 1; -} - - -void CBreakable::Die( void ) -{ - Vector vecSpot;// shard origin - Vector vecVelocity;// shard velocity - CBaseEntity *pEntity = NULL; - char cFlag = 0; - int pitch; - float fvol; - - pitch = 95 + RANDOM_LONG(0,29); - - if (pitch > 97 && pitch < 103) - pitch = 100; - - // The more negative pev->health, the louder - // the sound should be. - - fvol = RANDOM_FLOAT(0.85, 1.0) + ( fabs(pev->health) / 100.0); - - if (fvol > 1.0) - fvol = 1.0; - - - switch (m_Material) - { - case matGlass: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_GLASS; - break; - - case matWood: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_WOOD; - break; - - case matComputer: - case matMetal: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_METAL; - break; - - case matFlesh: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_FLESH; - break; - - case matRocks: - case matCinderBlock: - switch ( RANDOM_LONG(0,1) ) - { - case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete1.wav", fvol, ATTN_NORM, 0, pitch); - break; - case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete2.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - cFlag = BREAK_CONCRETE; - break; - - case matCeilingTile: - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustceiling.wav", fvol, ATTN_NORM, 0, pitch); - break; - } - - - if (m_Explosion == expDirected) - vecVelocity = g_vecAttackDir * 200; - else - { - vecVelocity.x = 0; - vecVelocity.y = 0; - vecVelocity.z = 0; - } - - vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot ); - WRITE_BYTE( TE_BREAKMODEL); - - // position - WRITE_COORD( vecSpot.x ); - WRITE_COORD( vecSpot.y ); - WRITE_COORD( vecSpot.z ); - - // size - WRITE_COORD( pev->size.x); - WRITE_COORD( pev->size.y); - WRITE_COORD( pev->size.z); - - // velocity - WRITE_COORD( vecVelocity.x ); - WRITE_COORD( vecVelocity.y ); - WRITE_COORD( vecVelocity.z ); - - // randomization - WRITE_BYTE( 10 ); - - // Model - WRITE_SHORT( m_idShard ); //model id# - - // # of shards - WRITE_BYTE( 0 ); // let client decide - - // duration - WRITE_BYTE( 25 );// 2.5 seconds - - // flags - WRITE_BYTE( cFlag ); - MESSAGE_END(); - - float size = pev->size.x; - if ( size < pev->size.y ) - size = pev->size.y; - if ( size < pev->size.z ) - size = pev->size.z; - - // !!! HACK This should work! - // Build a box above the entity that looks like an 8 pixel high sheet - Vector mins = pev->absmin; - Vector maxs = pev->absmax; - mins.z = pev->absmax.z; - maxs.z += 8; - - // BUGBUG -- can only find 256 entities on a breakable -- should be enough - CBaseEntity *pList[256]; - int count = UTIL_EntitiesInBox( pList, 256, mins, maxs, FL_ONGROUND ); - if ( count ) - { - for ( int i = 0; i < count; i++ ) - { - ClearBits( pList[i]->pev->flags, FL_ONGROUND ); - pList[i]->pev->groundentity = NULL; - } - } - - // Don't fire something that could fire myself - pev->targetname = 0; - - pev->solid = SOLID_NOT; - // Fire targets on break - SUB_UseTargets( NULL, USE_TOGGLE, 0 ); - - SetThink( &CBreakable::SUB_Remove ); - pev->nextthink = pev->ltime + 0.1; - if ( m_iszSpawnObject ) - CBaseEntity::Create( (char *)STRING(m_iszSpawnObject), VecBModelOrigin(pev), pev->angles, edict() ); - - - if ( Explodable() ) - { - ExplosionCreate( Center(), pev->angles, edict(), ExplosionMagnitude(), TRUE ); - } -} - - - -BOOL CBreakable :: IsBreakable( void ) -{ - return m_Material != matUnbreakableGlass; -} - - -int CBreakable :: DamageDecal( int bitsDamageType ) -{ - if ( m_Material == matGlass ) - return DECAL_GLASSBREAK1 + RANDOM_LONG(0,2); - - if ( m_Material == matUnbreakableGlass ) - return DECAL_BPROOF1; - - return CBaseEntity::DamageDecal( bitsDamageType ); -} - - -class CPushable : public CBreakable -{ -public: - void Spawn ( void ); - void Precache( void ); - void Touch ( CBaseEntity *pOther ); - void Move( CBaseEntity *pMover, int push ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT StopSound( void ); -// virtual void SetActivator( CBaseEntity *pActivator ) { m_pPusher = pActivator; } - - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_CONTINUOUS_USE; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - inline float MaxSpeed( void ) { return m_maxSpeed; } - - // breakables use an overridden takedamage - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - - static TYPEDESCRIPTION m_SaveData[]; - - static char *m_soundNames[3]; - int m_lastSound; // no need to save/restore, just keeps the same sound from playing twice in a row - float m_maxSpeed; - float m_soundTime; -}; - -TYPEDESCRIPTION CPushable::m_SaveData[] = -{ - DEFINE_FIELD( CPushable, m_maxSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CPushable, m_soundTime, FIELD_TIME ), -}; - -IMPLEMENT_SAVERESTORE( CPushable, CBreakable ); - -LINK_ENTITY_TO_CLASS( func_pushable, CPushable ); - -char *CPushable :: m_soundNames[3] = { "debris/pushbox1.wav", "debris/pushbox2.wav", "debris/pushbox3.wav" }; - - -void CPushable :: Spawn( void ) -{ - if ( pev->spawnflags & SF_PUSH_BREAKABLE ) - CBreakable::Spawn(); - else - Precache( ); - - pev->movetype = MOVETYPE_PUSHSTEP; - pev->solid = SOLID_BBOX; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - if ( pev->friction > 399 ) - pev->friction = 399; - - m_maxSpeed = 400 - pev->friction; - SetBits( pev->flags, FL_FLOAT ); - pev->friction = 0; - - pev->origin.z += 1; // Pick up off of the floor - UTIL_SetOrigin( pev, pev->origin ); - - // Multiply by area of the box's cross-section (assume 1000 units^3 standard volume) - pev->skin = ( pev->skin * (pev->maxs.x - pev->mins.x) * (pev->maxs.y - pev->mins.y) ) * 0.0005; - m_soundTime = 0; -} - - -void CPushable :: Precache( void ) -{ - for ( int i = 0; i < 3; i++ ) - PRECACHE_SOUND( m_soundNames[i] ); - - if ( pev->spawnflags & SF_PUSH_BREAKABLE ) - CBreakable::Precache( ); -} - - -void CPushable :: KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "size") ) - { - int bbox = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - - switch( bbox ) - { - case 0: // Point - UTIL_SetSize(pev, Vector(-8, -8, -8), Vector(8, 8, 8)); - break; - - case 2: // Big Hull!?!? !!!BUGBUG Figure out what this hull really is - UTIL_SetSize(pev, VEC_DUCK_HULL_MIN*2, VEC_DUCK_HULL_MAX*2); - break; - - case 3: // Player duck - UTIL_SetSize(pev, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX); - break; - - default: - case 1: // Player - UTIL_SetSize(pev, VEC_HULL_MIN, VEC_HULL_MAX); - break; - } - - } - else if ( FStrEq(pkvd->szKeyName, "buoyancy") ) - { - pev->skin = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBreakable::KeyValue( pkvd ); -} - - -// Pull the func_pushable -void CPushable :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !pActivator || !pActivator->IsPlayer() ) - { - if ( pev->spawnflags & SF_PUSH_BREAKABLE ) - this->CBreakable::Use( pActivator, pCaller, useType, value ); - return; - } - - if ( pActivator->pev->velocity != g_vecZero ) - Move( pActivator, 0 ); -} - - -void CPushable :: Touch( CBaseEntity *pOther ) -{ - if ( FClassnameIs( pOther->pev, "worldspawn" ) ) - return; - - Move( pOther, 1 ); -} - - -void CPushable :: Move( CBaseEntity *pOther, int push ) -{ - entvars_t* pevToucher = pOther->pev; - int playerTouch = 0; - - // Is entity standing on this pushable ? - if ( FBitSet(pevToucher->flags,FL_ONGROUND) && pevToucher->groundentity && VARS(pevToucher->groundentity) == pev ) - { - // Only push if floating - if ( pev->waterlevel > 0 ) - pev->velocity.z += pevToucher->velocity.z * 0.1; - - return; - } - - - if ( pOther->IsPlayer() ) - { - if ( push && !(pevToucher->button & (IN_FORWARD|IN_USE)) ) // Don't push unless the player is pushing forward and NOT use (pull) - return; - playerTouch = 1; - } - - float factor; - - if ( playerTouch ) - { - if ( !(pevToucher->flags & FL_ONGROUND) ) // Don't push away from jumping/falling players unless in water - { - if ( pev->waterlevel < 1 ) - return; - else - factor = 0.1; - } - else - factor = 1; - } - else - factor = 0.25; - - pev->velocity.x += pevToucher->velocity.x * factor; - pev->velocity.y += pevToucher->velocity.y * factor; - - float length = sqrt( pev->velocity.x * pev->velocity.x + pev->velocity.y * pev->velocity.y ); - if ( push && (length > MaxSpeed()) ) - { - pev->velocity.x = (pev->velocity.x * MaxSpeed() / length ); - pev->velocity.y = (pev->velocity.y * MaxSpeed() / length ); - } - if ( playerTouch ) - { - pevToucher->velocity.x = pev->velocity.x; - pevToucher->velocity.y = pev->velocity.y; - if ( (gpGlobals->time - m_soundTime) > 0.7 ) - { - m_soundTime = gpGlobals->time; - if ( length > 0 && FBitSet(pev->flags,FL_ONGROUND) ) - { - m_lastSound = RANDOM_LONG(0,2); - EMIT_SOUND(ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound], 0.5, ATTN_NORM); - // SetThink( StopSound ); - // pev->nextthink = pev->ltime + 0.1; - } - else - STOP_SOUND( ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound] ); - } - } -} - -#if 0 -void CPushable::StopSound( void ) -{ - Vector dist = pev->oldorigin - pev->origin; - if ( dist.Length() <= 0 ) - STOP_SOUND( ENT(pev), CHAN_WEAPON, m_soundNames[m_lastSound] ); -} -#endif - -int CPushable::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - if ( pev->spawnflags & SF_PUSH_BREAKABLE ) - return CBreakable::TakeDamage( pevInflictor, pevAttacker, flDamage, bitsDamageType ); - - return 1; -} - diff --git a/ricochet/dlls/func_break.h b/ricochet/dlls/func_break.h deleted file mode 100644 index 3c773b1..0000000 --- a/ricochet/dlls/func_break.h +++ /dev/null @@ -1,74 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef FUNC_BREAK_H -#define FUNC_BREAK_H - -typedef enum { expRandom, expDirected} Explosions; -typedef enum { matGlass = 0, matWood, matMetal, matFlesh, matCinderBlock, matCeilingTile, matComputer, matUnbreakableGlass, matRocks, matNone, matLastMaterial } Materials; - -#define NUM_SHARDS 6 // this many shards spawned when breakable objects break; - -class CBreakable : public CBaseDelay -{ -public: - // basic functions - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData* pkvd); - void EXPORT BreakTouch( CBaseEntity *pOther ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void DamageSound( void ); - - // breakables use an overridden takedamage - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - // To spark when hit - void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType ); - - BOOL IsBreakable( void ); - BOOL SparkWhenHit( void ); - - int DamageDecal( int bitsDamageType ); - - void EXPORT Die( void ); - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - inline BOOL Explodable( void ) { return ExplosionMagnitude() > 0; } - inline int ExplosionMagnitude( void ) { return pev->impulse; } - inline void ExplosionSetMagnitude( int magnitude ) { pev->impulse = magnitude; } - - static void MaterialSoundPrecache( Materials precacheMaterial ); - static void MaterialSoundRandom( edict_t *pEdict, Materials soundMaterial, float volume ); - static const char **MaterialSoundList( Materials precacheMaterial, int &soundCount ); - - static const char *pSoundsWood[]; - static const char *pSoundsFlesh[]; - static const char *pSoundsGlass[]; - static const char *pSoundsMetal[]; - static const char *pSoundsConcrete[]; - static const char *pSpawnObjects[]; - - static TYPEDESCRIPTION m_SaveData[]; - - Materials m_Material; - Explosions m_Explosion; - int m_idShard; - float m_angle; - int m_iszGibModel; - int m_iszSpawnObject; -}; - -#endif // FUNC_BREAK_H diff --git a/ricochet/dlls/func_tank.cpp b/ricochet/dlls/func_tank.cpp deleted file mode 100644 index 20b24f9..0000000 --- a/ricochet/dlls/func_tank.cpp +++ /dev/null @@ -1,1035 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "effects.h" -#include "weapons.h" -#include "explode.h" - -#include "player.h" - - -#define SF_TANK_ACTIVE 0x0001 -#define SF_TANK_PLAYER 0x0002 -#define SF_TANK_HUMANS 0x0004 -#define SF_TANK_ALIENS 0x0008 -#define SF_TANK_LINEOFSIGHT 0x0010 -#define SF_TANK_CANCONTROL 0x0020 -#define SF_TANK_SOUNDON 0x8000 - -enum TANKBULLET -{ - TANK_BULLET_NONE = 0, - TANK_BULLET_9MM = 1, - TANK_BULLET_MP5 = 2, - TANK_BULLET_12MM = 3, -}; - -// Custom damage -// env_laser (duration is 0.5 rate of fire) -// rockets -// explosion? - -class CFuncTank : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void Think( void ); - void TrackTarget( void ); - - virtual void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); - virtual Vector UpdateTargetPosition( CBaseEntity *pTarget ) - { - return pTarget->BodyTarget( pev->origin ); - } - - void StartRotSound( void ); - void StopRotSound( void ); - - // Bmodels don't go across transitions - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - inline BOOL IsActive( void ) { return (pev->spawnflags & SF_TANK_ACTIVE)?TRUE:FALSE; } - inline void TankActivate( void ) { pev->spawnflags |= SF_TANK_ACTIVE; pev->nextthink = pev->ltime + 0.1; m_fireLast = 0; } - inline void TankDeactivate( void ) { pev->spawnflags &= ~SF_TANK_ACTIVE; m_fireLast = 0; StopRotSound(); } - inline BOOL CanFire( void ) { return (gpGlobals->time - m_lastSightTime) < m_persist; } - BOOL InRange( float range ); - - // Acquire a target. pPlayer is a player in the PVS - edict_t *FindTarget( edict_t *pPlayer ); - - void TankTrace( const Vector &vecStart, const Vector &vecForward, const Vector &vecSpread, TraceResult &tr ); - - Vector BarrelPosition( void ) - { - Vector forward, right, up; - UTIL_MakeVectorsPrivate( pev->angles, forward, right, up ); - return pev->origin + (forward * m_barrelPos.x) + (right * m_barrelPos.y) + (up * m_barrelPos.z); - } - - void AdjustAnglesForBarrel( Vector &angles, float distance ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - BOOL OnControls( entvars_t *pevTest ); - BOOL StartControl( CBasePlayer* pController ); - void StopControl( void ); - void ControllerPostFrame( void ); - - -protected: - CBasePlayer* m_pController; - float m_flNextAttack; - Vector m_vecControllerUsePos; - - float m_yawCenter; // "Center" yaw - float m_yawRate; // Max turn rate to track targets - float m_yawRange; // Range of turning motion (one-sided: 30 is +/- 30 degress from center) - // Zero is full rotation - float m_yawTolerance; // Tolerance angle - - float m_pitchCenter; // "Center" pitch - float m_pitchRate; // Max turn rate on pitch - float m_pitchRange; // Range of pitch motion as above - float m_pitchTolerance; // Tolerance angle - - float m_fireLast; // Last time I fired - float m_fireRate; // How many rounds/second - float m_lastSightTime;// Last time I saw target - float m_persist; // Persistence of firing (how long do I shoot when I can't see) - float m_minRange; // Minimum range to aim/track - float m_maxRange; // Max range to aim/track - - Vector m_barrelPos; // Length of the freakin barrel - float m_spriteScale; // Scale of any sprites we shoot - int m_iszSpriteSmoke; - int m_iszSpriteFlash; - TANKBULLET m_bulletType; // Bullet type - int m_iBulletDamage; // 0 means use Bullet type's default damage - - Vector m_sightOrigin; // Last sight of target - int m_spread; // firing spread - int m_iszMaster; // Master entity (game_team_master or multisource) -}; - - -TYPEDESCRIPTION CFuncTank::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTank, m_yawCenter, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_yawRate, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_yawRange, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_yawTolerance, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_pitchCenter, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_pitchRate, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_pitchRange, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_pitchTolerance, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_fireLast, FIELD_TIME ), - DEFINE_FIELD( CFuncTank, m_fireRate, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_lastSightTime, FIELD_TIME ), - DEFINE_FIELD( CFuncTank, m_persist, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_minRange, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_maxRange, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_barrelPos, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTank, m_spriteScale, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTank, m_iszSpriteSmoke, FIELD_STRING ), - DEFINE_FIELD( CFuncTank, m_iszSpriteFlash, FIELD_STRING ), - DEFINE_FIELD( CFuncTank, m_bulletType, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTank, m_sightOrigin, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTank, m_spread, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTank, m_pController, FIELD_CLASSPTR ), - DEFINE_FIELD( CFuncTank, m_vecControllerUsePos, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTank, m_flNextAttack, FIELD_TIME ), - DEFINE_FIELD( CFuncTank, m_iBulletDamage, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTank, m_iszMaster, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTank, CBaseEntity ); - -static Vector gTankSpread[] = -{ - Vector( 0, 0, 0 ), // perfect - Vector( 0.025, 0.025, 0.025 ), // small cone - Vector( 0.05, 0.05, 0.05 ), // medium cone - Vector( 0.1, 0.1, 0.1 ), // large cone - Vector( 0.25, 0.25, 0.25 ), // extra-large cone -}; -#define MAX_FIRING_SPREADS ARRAYSIZE(gTankSpread) - - -void CFuncTank :: Spawn( void ) -{ - Precache(); - - pev->movetype = MOVETYPE_PUSH; // so it doesn't get pushed by anything - pev->solid = SOLID_BSP; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - m_yawCenter = pev->angles.y; - m_pitchCenter = pev->angles.x; - - if ( IsActive() ) - pev->nextthink = pev->ltime + 1.0; - - m_sightOrigin = BarrelPosition(); // Point at the end of the barrel - - if ( m_fireRate <= 0 ) - m_fireRate = 1; - if ( m_spread > MAX_FIRING_SPREADS ) - m_spread = 0; - - pev->oldorigin = pev->origin; -} - - -void CFuncTank :: Precache( void ) -{ - if ( m_iszSpriteSmoke ) - PRECACHE_MODEL( (char *)STRING(m_iszSpriteSmoke) ); - if ( m_iszSpriteFlash ) - PRECACHE_MODEL( (char *)STRING(m_iszSpriteFlash) ); - - if ( pev->noise ) - PRECACHE_SOUND( (char *)STRING(pev->noise) ); -} - - -void CFuncTank :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "yawrate")) - { - m_yawRate = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "yawrange")) - { - m_yawRange = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "yawtolerance")) - { - m_yawTolerance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pitchrange")) - { - m_pitchRange = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pitchrate")) - { - m_pitchRate = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pitchtolerance")) - { - m_pitchTolerance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "firerate")) - { - m_fireRate = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "barrel")) - { - m_barrelPos.x = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "barrely")) - { - m_barrelPos.y = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "barrelz")) - { - m_barrelPos.z = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spritescale")) - { - m_spriteScale = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spritesmoke")) - { - m_iszSpriteSmoke = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "spriteflash")) - { - m_iszSpriteFlash = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "rotatesound")) - { - pev->noise = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "persistence")) - { - m_persist = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "bullet")) - { - m_bulletType = (TANKBULLET)atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "bullet_damage" )) - { - m_iBulletDamage = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "firespread")) - { - m_spread = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "minRange")) - { - m_minRange = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "maxRange")) - { - m_maxRange = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "master")) - { - m_iszMaster = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -////////////// START NEW STUFF ////////////// - -//================================================================================== -// TANK CONTROLLING -BOOL CFuncTank :: OnControls( entvars_t *pevTest ) -{ - if ( !(pev->spawnflags & SF_TANK_CANCONTROL) ) - return FALSE; - - Vector offset = pevTest->origin - pev->origin; - - if ( (m_vecControllerUsePos - pevTest->origin).Length() < 30 ) - return TRUE; - - return FALSE; -} - -BOOL CFuncTank :: StartControl( CBasePlayer *pController ) -{ - if ( m_pController != NULL ) - return FALSE; - - // Team only or disabled? - if ( m_iszMaster ) - { - if ( !UTIL_IsMasterTriggered( m_iszMaster, pController ) ) - return FALSE; - } - - ALERT( at_console, "using TANK!\n"); - - // Holster player's weapon - m_pController = pController; - if ( m_pController->m_pActiveItem ) - { - m_pController->m_pActiveItem->Holster(); - m_pController->pev->weaponmodel = 0; - } - - m_pController->m_iHideHUD |= HIDEHUD_WEAPONS; - m_vecControllerUsePos = m_pController->pev->origin; - - pev->nextthink = pev->ltime + 0.1; - - return TRUE; -} - -void CFuncTank :: StopControl() -{ - // TODO: bring back the controllers current weapon - if ( !m_pController ) - return; - - if ( m_pController->m_pActiveItem ) - m_pController->m_pActiveItem->Deploy(); - - ALERT( at_console, "stopped using TANK\n"); - - m_pController->m_iHideHUD &= ~HIDEHUD_WEAPONS; - - pev->nextthink = 0; - m_pController = NULL; - - if ( IsActive() ) - pev->nextthink = pev->ltime + 1.0; -} - -// Called each frame by the player's ItemPostFrame -void CFuncTank :: ControllerPostFrame( void ) -{ - ASSERT(m_pController != NULL); - - if ( gpGlobals->time < m_flNextAttack ) - return; - - if ( m_pController->pev->button & IN_ATTACK ) - { - Vector vecForward; - UTIL_MakeVectorsPrivate( pev->angles, vecForward, NULL, NULL ); - - m_fireLast = gpGlobals->time - (1/m_fireRate) - 0.01; // to make sure the gun doesn't fire too many bullets - - Fire( BarrelPosition(), vecForward, m_pController->pev ); - - // HACKHACK -- make some noise (that the AI can hear) - if ( m_pController && m_pController->IsPlayer() ) - ((CBasePlayer *)m_pController)->m_iWeaponVolume = LOUD_GUN_VOLUME; - - m_flNextAttack = gpGlobals->time + (1/m_fireRate); - } -} -////////////// END NEW STUFF ////////////// - - -void CFuncTank :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->spawnflags & SF_TANK_CANCONTROL ) - { // player controlled turret - - if ( pActivator->Classify() != CLASS_PLAYER ) - return; - - if ( value == 2 && useType == USE_SET ) - { - ControllerPostFrame(); - } - else if ( !m_pController && useType != USE_OFF ) - { - ((CBasePlayer*)pActivator)->m_pTank = this; - StartControl( (CBasePlayer*)pActivator ); - } - else - { - StopControl(); - } - } - else - { - if ( !ShouldToggle( useType, IsActive() ) ) - return; - - if ( IsActive() ) - TankDeactivate(); - else - TankActivate(); - } -} - - -edict_t *CFuncTank :: FindTarget( edict_t *pPlayer ) -{ - return pPlayer; -} - - - -BOOL CFuncTank :: InRange( float range ) -{ - if ( range < m_minRange ) - return FALSE; - if ( m_maxRange > 0 && range > m_maxRange ) - return FALSE; - - return TRUE; -} - - -void CFuncTank :: Think( void ) -{ - pev->avelocity = g_vecZero; - TrackTarget(); - - if ( fabs(pev->avelocity.x) > 1 || fabs(pev->avelocity.y) > 1 ) - StartRotSound(); - else - StopRotSound(); -} - -void CFuncTank::TrackTarget( void ) -{ - TraceResult tr; - edict_t *pPlayer = FIND_CLIENT_IN_PVS( edict() ); - BOOL updateTime = FALSE, lineOfSight; - Vector angles, direction, targetPosition, barrelEnd; - edict_t *pTarget; - - // Get a position to aim for - if (m_pController) - { - // Tanks attempt to mirror the player's angles - angles = m_pController->pev->v_angle; - angles[0] = 0 - angles[0]; - pev->nextthink = pev->ltime + 0.05; - } - else - { - if ( IsActive() ) - pev->nextthink = pev->ltime + 0.1; - else - return; - - if ( FNullEnt( pPlayer ) ) - { - if ( IsActive() ) - pev->nextthink = pev->ltime + 2; // Wait 2 secs - return; - } - pTarget = FindTarget( pPlayer ); - if ( !pTarget ) - return; - - // Calculate angle needed to aim at target - barrelEnd = BarrelPosition(); - targetPosition = pTarget->v.origin + pTarget->v.view_ofs; - float range = (targetPosition - barrelEnd).Length(); - - if ( !InRange( range ) ) - return; - - UTIL_TraceLine( barrelEnd, targetPosition, dont_ignore_monsters, edict(), &tr ); - - lineOfSight = FALSE; - // No line of sight, don't track - if ( tr.flFraction == 1.0 || tr.pHit == pTarget ) - { - lineOfSight = TRUE; - - CBaseEntity *pInstance = CBaseEntity::Instance(pTarget); - if ( InRange( range ) && pInstance && pInstance->IsAlive() ) - { - updateTime = TRUE; - m_sightOrigin = UpdateTargetPosition( pInstance ); - } - } - - // Track sight origin - -// !!! I'm not sure what i changed - direction = m_sightOrigin - pev->origin; -// direction = m_sightOrigin - barrelEnd; - angles = UTIL_VecToAngles( direction ); - - // Calculate the additional rotation to point the end of the barrel at the target (not the gun's center) - AdjustAnglesForBarrel( angles, direction.Length() ); - } - - angles.x = -angles.x; - - // Force the angles to be relative to the center position - angles.y = m_yawCenter + UTIL_AngleDistance( angles.y, m_yawCenter ); - angles.x = m_pitchCenter + UTIL_AngleDistance( angles.x, m_pitchCenter ); - - // Limit against range in y - if ( angles.y > m_yawCenter + m_yawRange ) - { - angles.y = m_yawCenter + m_yawRange; - updateTime = FALSE; // Don't update if you saw the player, but out of range - } - else if ( angles.y < (m_yawCenter - m_yawRange) ) - { - angles.y = (m_yawCenter - m_yawRange); - updateTime = FALSE; // Don't update if you saw the player, but out of range - } - - if ( updateTime ) - m_lastSightTime = gpGlobals->time; - - // Move toward target at rate or less - float distY = UTIL_AngleDistance( angles.y, pev->angles.y ); - pev->avelocity.y = distY * 10; - if ( pev->avelocity.y > m_yawRate ) - pev->avelocity.y = m_yawRate; - else if ( pev->avelocity.y < -m_yawRate ) - pev->avelocity.y = -m_yawRate; - - // Limit against range in x - if ( angles.x > m_pitchCenter + m_pitchRange ) - angles.x = m_pitchCenter + m_pitchRange; - else if ( angles.x < m_pitchCenter - m_pitchRange ) - angles.x = m_pitchCenter - m_pitchRange; - - // Move toward target at rate or less - float distX = UTIL_AngleDistance( angles.x, pev->angles.x ); - pev->avelocity.x = distX * 10; - - if ( pev->avelocity.x > m_pitchRate ) - pev->avelocity.x = m_pitchRate; - else if ( pev->avelocity.x < -m_pitchRate ) - pev->avelocity.x = -m_pitchRate; - - if ( m_pController ) - return; - - if ( CanFire() && ( (fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (pev->spawnflags & SF_TANK_LINEOFSIGHT) ) ) - { - BOOL fire = FALSE; - Vector forward; - UTIL_MakeVectorsPrivate( pev->angles, forward, NULL, NULL ); - - if ( pev->spawnflags & SF_TANK_LINEOFSIGHT ) - { - float length = direction.Length(); - UTIL_TraceLine( barrelEnd, barrelEnd + forward * length, dont_ignore_monsters, edict(), &tr ); - if ( tr.pHit == pTarget ) - fire = TRUE; - } - else - fire = TRUE; - - if ( fire ) - { - Fire( BarrelPosition(), forward, pev ); - } - else - m_fireLast = 0; - } - else - m_fireLast = 0; -} - - -// If barrel is offset, add in additional rotation -void CFuncTank::AdjustAnglesForBarrel( Vector &angles, float distance ) -{ - float r2, d2; - - - if ( m_barrelPos.y != 0 || m_barrelPos.z != 0 ) - { - distance -= m_barrelPos.z; - d2 = distance * distance; - if ( m_barrelPos.y ) - { - r2 = m_barrelPos.y * m_barrelPos.y; - angles.y += (180.0 / M_PI) * atan2( m_barrelPos.y, sqrt( d2 - r2 ) ); - } - if ( m_barrelPos.z ) - { - r2 = m_barrelPos.z * m_barrelPos.z; - angles.x += (180.0 / M_PI) * atan2( -m_barrelPos.z, sqrt( d2 - r2 ) ); - } - } -} - - -// Fire targets and spawn sprites -void CFuncTank::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - if ( m_fireLast != 0 ) - { - if ( m_iszSpriteSmoke ) - { - CSprite *pSprite = CSprite::SpriteCreate( STRING(m_iszSpriteSmoke), barrelEnd, TRUE ); - pSprite->AnimateAndDie( RANDOM_FLOAT( 15.0, 20.0 ) ); - pSprite->SetTransparency( kRenderTransAlpha, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, 255, kRenderFxNone ); - pSprite->pev->velocity.z = RANDOM_FLOAT(40, 80); - pSprite->SetScale( m_spriteScale ); - } - if ( m_iszSpriteFlash ) - { - CSprite *pSprite = CSprite::SpriteCreate( STRING(m_iszSpriteFlash), barrelEnd, TRUE ); - pSprite->AnimateAndDie( 60 ); - pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); - pSprite->SetScale( m_spriteScale ); - } - SUB_UseTargets( this, USE_TOGGLE, 0 ); - } - m_fireLast = gpGlobals->time; -} - - -void CFuncTank::TankTrace( const Vector &vecStart, const Vector &vecForward, const Vector &vecSpread, TraceResult &tr ) -{ - // get circular gaussian spread - float x, y, z; - do { - x = RANDOM_FLOAT(-0.5,0.5) + RANDOM_FLOAT(-0.5,0.5); - y = RANDOM_FLOAT(-0.5,0.5) + RANDOM_FLOAT(-0.5,0.5); - z = x*x+y*y; - } while (z > 1); - Vector vecDir = vecForward + - x * vecSpread.x * gpGlobals->v_right + - y * vecSpread.y * gpGlobals->v_up; - Vector vecEnd; - - vecEnd = vecStart + vecDir * 4096; - UTIL_TraceLine( vecStart, vecEnd, dont_ignore_monsters, edict(), &tr ); -} - - -void CFuncTank::StartRotSound( void ) -{ - if ( !pev->noise || (pev->spawnflags & SF_TANK_SOUNDON) ) - return; - pev->spawnflags |= SF_TANK_SOUNDON; - EMIT_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noise), 0.85, ATTN_NORM); -} - - -void CFuncTank::StopRotSound( void ) -{ - if ( pev->spawnflags & SF_TANK_SOUNDON ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noise) ); - pev->spawnflags &= ~SF_TANK_SOUNDON; -} - -class CFuncTankGun : public CFuncTank -{ -public: - void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); -}; -LINK_ENTITY_TO_CLASS( func_tank, CFuncTankGun ); - -void CFuncTankGun::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - int i; - - if ( m_fireLast != 0 ) - { - // FireBullets needs gpGlobals->v_up, etc. - UTIL_MakeAimVectors(pev->angles); - - int bulletCount = (gpGlobals->time - m_fireLast) * m_fireRate; - if ( bulletCount > 0 ) - { - for ( i = 0; i < bulletCount; i++ ) - { - switch( m_bulletType ) - { - case TANK_BULLET_9MM: - FireBullets( 1, barrelEnd, forward, gTankSpread[m_spread], 4096, BULLET_MONSTER_9MM, 1, m_iBulletDamage, pevAttacker ); - break; - - case TANK_BULLET_MP5: - FireBullets( 1, barrelEnd, forward, gTankSpread[m_spread], 4096, BULLET_MONSTER_MP5, 1, m_iBulletDamage, pevAttacker ); - break; - - case TANK_BULLET_12MM: - FireBullets( 1, barrelEnd, forward, gTankSpread[m_spread], 4096, BULLET_MONSTER_12MM, 1, m_iBulletDamage, pevAttacker ); - break; - - default: - case TANK_BULLET_NONE: - break; - } - } - CFuncTank::Fire( barrelEnd, forward, pevAttacker ); - } - } - else - CFuncTank::Fire( barrelEnd, forward, pevAttacker ); -} - - - -class CFuncTankLaser : public CFuncTank -{ -public: - void Activate( void ); - void KeyValue( KeyValueData *pkvd ); - void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); - void Think( void ); - CLaser *GetLaser( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - -private: - CLaser *m_pLaser; - float m_laserTime; -}; -LINK_ENTITY_TO_CLASS( func_tanklaser, CFuncTankLaser ); - -TYPEDESCRIPTION CFuncTankLaser::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTankLaser, m_pLaser, FIELD_CLASSPTR ), - DEFINE_FIELD( CFuncTankLaser, m_laserTime, FIELD_TIME ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTankLaser, CFuncTank ); - -void CFuncTankLaser::Activate( void ) -{ - if ( !GetLaser() ) - { - UTIL_Remove(this); - ALERT( at_error, "Laser tank with no env_laser!\n" ); - } - else - { - m_pLaser->TurnOff(); - } -} - - -void CFuncTankLaser::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "laserentity")) - { - pev->message = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CFuncTank::KeyValue( pkvd ); -} - - -CLaser *CFuncTankLaser::GetLaser( void ) -{ - if ( m_pLaser ) - return m_pLaser; - - edict_t *pentLaser; - - pentLaser = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->message) ); - while ( !FNullEnt( pentLaser ) ) - { - // Found the landmark - if ( FClassnameIs( pentLaser, "env_laser" ) ) - { - m_pLaser = (CLaser *)CBaseEntity::Instance(pentLaser); - break; - } - else - pentLaser = FIND_ENTITY_BY_TARGETNAME( pentLaser, STRING(pev->message) ); - } - - return m_pLaser; -} - - -void CFuncTankLaser::Think( void ) -{ - if ( m_pLaser && (gpGlobals->time > m_laserTime) ) - m_pLaser->TurnOff(); - - CFuncTank::Think(); -} - - -void CFuncTankLaser::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - int i; - TraceResult tr; - - if ( m_fireLast != 0 && GetLaser() ) - { - // TankTrace needs gpGlobals->v_up, etc. - UTIL_MakeAimVectors(pev->angles); - - int bulletCount = (gpGlobals->time - m_fireLast) * m_fireRate; - if ( bulletCount ) - { - for ( i = 0; i < bulletCount; i++ ) - { - m_pLaser->pev->origin = barrelEnd; - TankTrace( barrelEnd, forward, gTankSpread[m_spread], tr ); - - m_laserTime = gpGlobals->time; - m_pLaser->TurnOn(); - m_pLaser->pev->dmgtime = gpGlobals->time - 1.0; - m_pLaser->FireAtPoint( tr ); - m_pLaser->pev->nextthink = 0; - } - CFuncTank::Fire( barrelEnd, forward, pev ); - } - } - else - { - CFuncTank::Fire( barrelEnd, forward, pev ); - } -} - -class CFuncTankRocket : public CFuncTank -{ -public: - void Precache( void ); - void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); -}; -LINK_ENTITY_TO_CLASS( func_tankrocket, CFuncTankRocket ); - -void CFuncTankRocket::Precache( void ) -{ - UTIL_PrecacheOther( "rpg_rocket" ); - CFuncTank::Precache(); -} - - - -void CFuncTankRocket::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - int i; - - if ( m_fireLast != 0 ) - { - int bulletCount = (gpGlobals->time - m_fireLast) * m_fireRate; - if ( bulletCount > 0 ) - { - for ( i = 0; i < bulletCount; i++ ) - { - CBaseEntity *pRocket = CBaseEntity::Create( "rpg_rocket", barrelEnd, pev->angles, edict() ); - } - CFuncTank::Fire( barrelEnd, forward, pev ); - } - } - else - CFuncTank::Fire( barrelEnd, forward, pev ); -} - - -class CFuncTankMortar : public CFuncTank -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ); -}; -LINK_ENTITY_TO_CLASS( func_tankmortar, CFuncTankMortar ); - - -void CFuncTankMortar::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "iMagnitude")) - { - pev->impulse = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CFuncTank::KeyValue( pkvd ); -} - - -void CFuncTankMortar::Fire( const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker ) -{ - if ( m_fireLast != 0 ) - { - int bulletCount = (gpGlobals->time - m_fireLast) * m_fireRate; - // Only create 1 explosion - if ( bulletCount > 0 ) - { - TraceResult tr; - - // TankTrace needs gpGlobals->v_up, etc. - UTIL_MakeAimVectors(pev->angles); - - TankTrace( barrelEnd, forward, gTankSpread[m_spread], tr ); - - ExplosionCreate( tr.vecEndPos, pev->angles, edict(), pev->impulse, TRUE ); - - CFuncTank::Fire( barrelEnd, forward, pev ); - } - } - else - CFuncTank::Fire( barrelEnd, forward, pev ); -} - - - -//============================================================================ -// FUNC TANK CONTROLS -//============================================================================ -class CFuncTankControls : public CBaseEntity -{ -public: - virtual int ObjectCaps( void ); - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void Think( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - CFuncTank *m_pTank; -}; -LINK_ENTITY_TO_CLASS( func_tankcontrols, CFuncTankControls ); - -TYPEDESCRIPTION CFuncTankControls::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTankControls, m_pTank, FIELD_CLASSPTR ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTankControls, CBaseEntity ); - -int CFuncTankControls :: ObjectCaps( void ) -{ - return (CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_IMPULSE_USE; -} - - -void CFuncTankControls :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ // pass the Use command onto the controls - if ( m_pTank ) - m_pTank->Use( pActivator, pCaller, useType, value ); - - ASSERT( m_pTank != NULL ); // if this fails, most likely means save/restore hasn't worked properly -} - - -void CFuncTankControls :: Think( void ) -{ - edict_t *pTarget = NULL; - - do - { - pTarget = FIND_ENTITY_BY_TARGETNAME( pTarget, STRING(pev->target) ); - } while ( !FNullEnt(pTarget) && strncmp( STRING(pTarget->v.classname), "func_tank", 9 ) ); - - if ( FNullEnt( pTarget ) ) - { - ALERT( at_console, "No tank %s\n", STRING(pev->target) ); - return; - } - - m_pTank = (CFuncTank*)Instance(pTarget); -} - -void CFuncTankControls::Spawn( void ) -{ - pev->solid = SOLID_TRIGGER; - pev->movetype = MOVETYPE_NONE; - pev->effects |= EF_NODRAW; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - UTIL_SetSize( pev, pev->mins, pev->maxs ); - UTIL_SetOrigin( pev, pev->origin ); - - pev->nextthink = gpGlobals->time + 0.3; // After all the func_tank's have spawned - - CBaseEntity::Spawn(); -} diff --git a/ricochet/dlls/game.cpp b/ricochet/dlls/game.cpp deleted file mode 100644 index c70b8c0..0000000 --- a/ricochet/dlls/game.cpp +++ /dev/null @@ -1,899 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "eiface.h" -#include "util.h" -#include "game.h" - - -cvar_t displaysoundlist = {"displaysoundlist","0"}; - -// multiplayer server rules -cvar_t fragsleft = {"mp_fragsleft","0", FCVAR_SERVER | FCVAR_UNLOGGED }; // Don't spam console/log files/users with this changing -cvar_t timeleft = {"mp_timeleft","0" , FCVAR_SERVER | FCVAR_UNLOGGED }; // " " - -cvar_t allow_spectators = { "allow_spectators", "1.0", FCVAR_SERVER }; // 0 prevents players from being spectators - -// discwar -cvar_t rc_rounds = {"rc_rounds", "3", FCVAR_SERVER | FCVAR_UNLOGGED }; -cvar_t rc_playersperteam = {"rc_playersperteam", "1", FCVAR_SERVER | FCVAR_UNLOGGED }; -cvar_t rc_arena = {"rc_arena", "1", FCVAR_SERVER | FCVAR_UNLOGGED }; - -// multiplayer server rules -cvar_t teamplay = {"mp_teamplay","0", FCVAR_SERVER }; -cvar_t fraglimit = {"mp_fraglimit","0", FCVAR_SERVER }; -cvar_t timelimit = {"mp_timelimit","0", FCVAR_SERVER }; -cvar_t friendlyfire= {"mp_friendlyfire","0", FCVAR_SERVER }; -cvar_t falldamage = {"mp_falldamage","0", FCVAR_SERVER }; -cvar_t weaponstay = {"mp_weaponstay","0", FCVAR_SERVER }; -cvar_t forcerespawn= {"mp_forcerespawn","1", FCVAR_SERVER }; -cvar_t flashlight = {"mp_flashlight","0", FCVAR_SERVER }; -cvar_t aimcrosshair= {"mp_autocrosshair","1", FCVAR_SERVER }; -cvar_t decalfrequency = {"decalfrequency","30", FCVAR_SERVER }; -cvar_t teamlist = {"mp_teamlist","male", FCVAR_SERVER }; -cvar_t teamoverride = {"mp_teamoverride","1" }; -cvar_t defaultteam = {"mp_defaultteam","0" }; -cvar_t allowmonsters={"mp_allowmonsters","0", FCVAR_SERVER }; - -cvar_t *g_psv_gravity = NULL; -cvar_t *g_psv_aim = NULL; -cvar_t *g_footsteps = NULL; - -//CVARS FOR SKILL LEVEL SETTINGS -// Agrunt -cvar_t sk_agrunt_health1 = {"sk_agrunt_health1","0"}; -cvar_t sk_agrunt_health2 = {"sk_agrunt_health2","0"}; -cvar_t sk_agrunt_health3 = {"sk_agrunt_health3","0"}; - -cvar_t sk_agrunt_dmg_punch1 = {"sk_agrunt_dmg_punch1","0"}; -cvar_t sk_agrunt_dmg_punch2 = {"sk_agrunt_dmg_punch2","0"}; -cvar_t sk_agrunt_dmg_punch3 = {"sk_agrunt_dmg_punch3","0"}; - -// Apache -cvar_t sk_apache_health1 = {"sk_apache_health1","0"}; -cvar_t sk_apache_health2 = {"sk_apache_health2","0"}; -cvar_t sk_apache_health3 = {"sk_apache_health3","0"}; - -// Barney -cvar_t sk_barney_health1 = {"sk_barney_health1","0"}; -cvar_t sk_barney_health2 = {"sk_barney_health2","0"}; -cvar_t sk_barney_health3 = {"sk_barney_health3","0"}; - -// Bullsquid -cvar_t sk_bullsquid_health1 = {"sk_bullsquid_health1","0"}; -cvar_t sk_bullsquid_health2 = {"sk_bullsquid_health2","0"}; -cvar_t sk_bullsquid_health3 = {"sk_bullsquid_health3","0"}; - -cvar_t sk_bullsquid_dmg_bite1 = {"sk_bullsquid_dmg_bite1","0"}; -cvar_t sk_bullsquid_dmg_bite2 = {"sk_bullsquid_dmg_bite2","0"}; -cvar_t sk_bullsquid_dmg_bite3 = {"sk_bullsquid_dmg_bite3","0"}; - -cvar_t sk_bullsquid_dmg_whip1 = {"sk_bullsquid_dmg_whip1","0"}; -cvar_t sk_bullsquid_dmg_whip2 = {"sk_bullsquid_dmg_whip2","0"}; -cvar_t sk_bullsquid_dmg_whip3 = {"sk_bullsquid_dmg_whip3","0"}; - -cvar_t sk_bullsquid_dmg_spit1 = {"sk_bullsquid_dmg_spit1","0"}; -cvar_t sk_bullsquid_dmg_spit2 = {"sk_bullsquid_dmg_spit2","0"}; -cvar_t sk_bullsquid_dmg_spit3 = {"sk_bullsquid_dmg_spit3","0"}; - - -// Big Momma -cvar_t sk_bigmomma_health_factor1 = {"sk_bigmomma_health_factor1","1.0"}; -cvar_t sk_bigmomma_health_factor2 = {"sk_bigmomma_health_factor2","1.0"}; -cvar_t sk_bigmomma_health_factor3 = {"sk_bigmomma_health_factor3","1.0"}; - -cvar_t sk_bigmomma_dmg_slash1 = {"sk_bigmomma_dmg_slash1","50"}; -cvar_t sk_bigmomma_dmg_slash2 = {"sk_bigmomma_dmg_slash2","50"}; -cvar_t sk_bigmomma_dmg_slash3 = {"sk_bigmomma_dmg_slash3","50"}; - -cvar_t sk_bigmomma_dmg_blast1 = {"sk_bigmomma_dmg_blast1","100"}; -cvar_t sk_bigmomma_dmg_blast2 = {"sk_bigmomma_dmg_blast2","100"}; -cvar_t sk_bigmomma_dmg_blast3 = {"sk_bigmomma_dmg_blast3","100"}; - -cvar_t sk_bigmomma_radius_blast1 = {"sk_bigmomma_radius_blast1","250"}; -cvar_t sk_bigmomma_radius_blast2 = {"sk_bigmomma_radius_blast2","250"}; -cvar_t sk_bigmomma_radius_blast3 = {"sk_bigmomma_radius_blast3","250"}; - -// Gargantua -cvar_t sk_gargantua_health1 = {"sk_gargantua_health1","0"}; -cvar_t sk_gargantua_health2 = {"sk_gargantua_health2","0"}; -cvar_t sk_gargantua_health3 = {"sk_gargantua_health3","0"}; - -cvar_t sk_gargantua_dmg_slash1 = {"sk_gargantua_dmg_slash1","0"}; -cvar_t sk_gargantua_dmg_slash2 = {"sk_gargantua_dmg_slash2","0"}; -cvar_t sk_gargantua_dmg_slash3 = {"sk_gargantua_dmg_slash3","0"}; - -cvar_t sk_gargantua_dmg_fire1 = {"sk_gargantua_dmg_fire1","0"}; -cvar_t sk_gargantua_dmg_fire2 = {"sk_gargantua_dmg_fire2","0"}; -cvar_t sk_gargantua_dmg_fire3 = {"sk_gargantua_dmg_fire3","0"}; - -cvar_t sk_gargantua_dmg_stomp1 = {"sk_gargantua_dmg_stomp1","0"}; -cvar_t sk_gargantua_dmg_stomp2 = {"sk_gargantua_dmg_stomp2","0"}; -cvar_t sk_gargantua_dmg_stomp3 = {"sk_gargantua_dmg_stomp3","0"}; - - -// Hassassin -cvar_t sk_hassassin_health1 = {"sk_hassassin_health1","0"}; -cvar_t sk_hassassin_health2 = {"sk_hassassin_health2","0"}; -cvar_t sk_hassassin_health3 = {"sk_hassassin_health3","0"}; - - -// Headcrab -cvar_t sk_headcrab_health1 = {"sk_headcrab_health1","0"}; -cvar_t sk_headcrab_health2 = {"sk_headcrab_health2","0"}; -cvar_t sk_headcrab_health3 = {"sk_headcrab_health3","0"}; - -cvar_t sk_headcrab_dmg_bite1 = {"sk_headcrab_dmg_bite1","0"}; -cvar_t sk_headcrab_dmg_bite2 = {"sk_headcrab_dmg_bite2","0"}; -cvar_t sk_headcrab_dmg_bite3 = {"sk_headcrab_dmg_bite3","0"}; - - -// Hgrunt -cvar_t sk_hgrunt_health1 = {"sk_hgrunt_health1","0"}; -cvar_t sk_hgrunt_health2 = {"sk_hgrunt_health2","0"}; -cvar_t sk_hgrunt_health3 = {"sk_hgrunt_health3","0"}; - -cvar_t sk_hgrunt_kick1 = {"sk_hgrunt_kick1","0"}; -cvar_t sk_hgrunt_kick2 = {"sk_hgrunt_kick2","0"}; -cvar_t sk_hgrunt_kick3 = {"sk_hgrunt_kick3","0"}; - -cvar_t sk_hgrunt_pellets1 = {"sk_hgrunt_pellets1","0"}; -cvar_t sk_hgrunt_pellets2 = {"sk_hgrunt_pellets2","0"}; -cvar_t sk_hgrunt_pellets3 = {"sk_hgrunt_pellets3","0"}; - -cvar_t sk_hgrunt_gspeed1 = {"sk_hgrunt_gspeed1","0"}; -cvar_t sk_hgrunt_gspeed2 = {"sk_hgrunt_gspeed2","0"}; -cvar_t sk_hgrunt_gspeed3 = {"sk_hgrunt_gspeed3","0"}; - -// Houndeye -cvar_t sk_houndeye_health1 = {"sk_houndeye_health1","0"}; -cvar_t sk_houndeye_health2 = {"sk_houndeye_health2","0"}; -cvar_t sk_houndeye_health3 = {"sk_houndeye_health3","0"}; - -cvar_t sk_houndeye_dmg_blast1 = {"sk_houndeye_dmg_blast1","0"}; -cvar_t sk_houndeye_dmg_blast2 = {"sk_houndeye_dmg_blast2","0"}; -cvar_t sk_houndeye_dmg_blast3 = {"sk_houndeye_dmg_blast3","0"}; - - -// ISlave -cvar_t sk_islave_health1 = {"sk_islave_health1","0"}; -cvar_t sk_islave_health2 = {"sk_islave_health2","0"}; -cvar_t sk_islave_health3 = {"sk_islave_health3","0"}; - -cvar_t sk_islave_dmg_claw1 = {"sk_islave_dmg_claw1","0"}; -cvar_t sk_islave_dmg_claw2 = {"sk_islave_dmg_claw2","0"}; -cvar_t sk_islave_dmg_claw3 = {"sk_islave_dmg_claw3","0"}; - -cvar_t sk_islave_dmg_clawrake1 = {"sk_islave_dmg_clawrake1","0"}; -cvar_t sk_islave_dmg_clawrake2 = {"sk_islave_dmg_clawrake2","0"}; -cvar_t sk_islave_dmg_clawrake3 = {"sk_islave_dmg_clawrake3","0"}; - -cvar_t sk_islave_dmg_zap1 = {"sk_islave_dmg_zap1","0"}; -cvar_t sk_islave_dmg_zap2 = {"sk_islave_dmg_zap2","0"}; -cvar_t sk_islave_dmg_zap3 = {"sk_islave_dmg_zap3","0"}; - - -// Icthyosaur -cvar_t sk_ichthyosaur_health1 = {"sk_ichthyosaur_health1","0"}; -cvar_t sk_ichthyosaur_health2 = {"sk_ichthyosaur_health2","0"}; -cvar_t sk_ichthyosaur_health3 = {"sk_ichthyosaur_health3","0"}; - -cvar_t sk_ichthyosaur_shake1 = {"sk_ichthyosaur_shake1","0"}; -cvar_t sk_ichthyosaur_shake2 = {"sk_ichthyosaur_shake2","0"}; -cvar_t sk_ichthyosaur_shake3 = {"sk_ichthyosaur_shake3","0"}; - - -// Leech -cvar_t sk_leech_health1 = {"sk_leech_health1","0"}; -cvar_t sk_leech_health2 = {"sk_leech_health2","0"}; -cvar_t sk_leech_health3 = {"sk_leech_health3","0"}; - -cvar_t sk_leech_dmg_bite1 = {"sk_leech_dmg_bite1","0"}; -cvar_t sk_leech_dmg_bite2 = {"sk_leech_dmg_bite2","0"}; -cvar_t sk_leech_dmg_bite3 = {"sk_leech_dmg_bite3","0"}; - -// Controller -cvar_t sk_controller_health1 = {"sk_controller_health1","0"}; -cvar_t sk_controller_health2 = {"sk_controller_health2","0"}; -cvar_t sk_controller_health3 = {"sk_controller_health3","0"}; - -cvar_t sk_controller_dmgzap1 = {"sk_controller_dmgzap1","0"}; -cvar_t sk_controller_dmgzap2 = {"sk_controller_dmgzap2","0"}; -cvar_t sk_controller_dmgzap3 = {"sk_controller_dmgzap3","0"}; - -cvar_t sk_controller_speedball1 = {"sk_controller_speedball1","0"}; -cvar_t sk_controller_speedball2 = {"sk_controller_speedball2","0"}; -cvar_t sk_controller_speedball3 = {"sk_controller_speedball3","0"}; - -cvar_t sk_controller_dmgball1 = {"sk_controller_dmgball1","0"}; -cvar_t sk_controller_dmgball2 = {"sk_controller_dmgball2","0"}; -cvar_t sk_controller_dmgball3 = {"sk_controller_dmgball3","0"}; - -// Nihilanth -cvar_t sk_nihilanth_health1 = {"sk_nihilanth_health1","0"}; -cvar_t sk_nihilanth_health2 = {"sk_nihilanth_health2","0"}; -cvar_t sk_nihilanth_health3 = {"sk_nihilanth_health3","0"}; - -cvar_t sk_nihilanth_zap1 = {"sk_nihilanth_zap1","0"}; -cvar_t sk_nihilanth_zap2 = {"sk_nihilanth_zap2","0"}; -cvar_t sk_nihilanth_zap3 = {"sk_nihilanth_zap3","0"}; - -// Scientist -cvar_t sk_scientist_health1 = {"sk_scientist_health1","0"}; -cvar_t sk_scientist_health2 = {"sk_scientist_health2","0"}; -cvar_t sk_scientist_health3 = {"sk_scientist_health3","0"}; - - -// Snark -cvar_t sk_snark_health1 = {"sk_snark_health1","0"}; -cvar_t sk_snark_health2 = {"sk_snark_health2","0"}; -cvar_t sk_snark_health3 = {"sk_snark_health3","0"}; - -cvar_t sk_snark_dmg_bite1 = {"sk_snark_dmg_bite1","0"}; -cvar_t sk_snark_dmg_bite2 = {"sk_snark_dmg_bite2","0"}; -cvar_t sk_snark_dmg_bite3 = {"sk_snark_dmg_bite3","0"}; - -cvar_t sk_snark_dmg_pop1 = {"sk_snark_dmg_pop1","0"}; -cvar_t sk_snark_dmg_pop2 = {"sk_snark_dmg_pop2","0"}; -cvar_t sk_snark_dmg_pop3 = {"sk_snark_dmg_pop3","0"}; - - - -// Zombie -cvar_t sk_zombie_health1 = {"sk_zombie_health1","0"}; -cvar_t sk_zombie_health2 = {"sk_zombie_health2","0"}; -cvar_t sk_zombie_health3 = {"sk_zombie_health3","0"}; - -cvar_t sk_zombie_dmg_one_slash1 = {"sk_zombie_dmg_one_slash1","0"}; -cvar_t sk_zombie_dmg_one_slash2 = {"sk_zombie_dmg_one_slash2","0"}; -cvar_t sk_zombie_dmg_one_slash3 = {"sk_zombie_dmg_one_slash3","0"}; - -cvar_t sk_zombie_dmg_both_slash1 = {"sk_zombie_dmg_both_slash1","0"}; -cvar_t sk_zombie_dmg_both_slash2 = {"sk_zombie_dmg_both_slash2","0"}; -cvar_t sk_zombie_dmg_both_slash3 = {"sk_zombie_dmg_both_slash3","0"}; - - -//Turret -cvar_t sk_turret_health1 = {"sk_turret_health1","0"}; -cvar_t sk_turret_health2 = {"sk_turret_health2","0"}; -cvar_t sk_turret_health3 = {"sk_turret_health3","0"}; - - -// MiniTurret -cvar_t sk_miniturret_health1 = {"sk_miniturret_health1","0"}; -cvar_t sk_miniturret_health2 = {"sk_miniturret_health2","0"}; -cvar_t sk_miniturret_health3 = {"sk_miniturret_health3","0"}; - - -// Sentry Turret -cvar_t sk_sentry_health1 = {"sk_sentry_health1","0"}; -cvar_t sk_sentry_health2 = {"sk_sentry_health2","0"}; -cvar_t sk_sentry_health3 = {"sk_sentry_health3","0"}; - - -// PLAYER WEAPONS - -// Crowbar whack -cvar_t sk_plr_crowbar1 = {"sk_plr_crowbar1","0"}; -cvar_t sk_plr_crowbar2 = {"sk_plr_crowbar2","0"}; -cvar_t sk_plr_crowbar3 = {"sk_plr_crowbar3","0"}; - -// Glock Round -cvar_t sk_plr_9mm_bullet1 = {"sk_plr_9mm_bullet1","0"}; -cvar_t sk_plr_9mm_bullet2 = {"sk_plr_9mm_bullet2","0"}; -cvar_t sk_plr_9mm_bullet3 = {"sk_plr_9mm_bullet3","0"}; - -// 357 Round -cvar_t sk_plr_357_bullet1 = {"sk_plr_357_bullet1","0"}; -cvar_t sk_plr_357_bullet2 = {"sk_plr_357_bullet2","0"}; -cvar_t sk_plr_357_bullet3 = {"sk_plr_357_bullet3","0"}; - -// MP5 Round -cvar_t sk_plr_9mmAR_bullet1 = {"sk_plr_9mmAR_bullet1","0"}; -cvar_t sk_plr_9mmAR_bullet2 = {"sk_plr_9mmAR_bullet2","0"}; -cvar_t sk_plr_9mmAR_bullet3 = {"sk_plr_9mmAR_bullet3","0"}; - - -// M203 grenade -cvar_t sk_plr_9mmAR_grenade1 = {"sk_plr_9mmAR_grenade1","0"}; -cvar_t sk_plr_9mmAR_grenade2 = {"sk_plr_9mmAR_grenade2","0"}; -cvar_t sk_plr_9mmAR_grenade3 = {"sk_plr_9mmAR_grenade3","0"}; - - -// Shotgun buckshot -cvar_t sk_plr_buckshot1 = {"sk_plr_buckshot1","0"}; -cvar_t sk_plr_buckshot2 = {"sk_plr_buckshot2","0"}; -cvar_t sk_plr_buckshot3 = {"sk_plr_buckshot3","0"}; - - -// Crossbow -cvar_t sk_plr_xbow_bolt_client1 = {"sk_plr_xbow_bolt_client1","0"}; -cvar_t sk_plr_xbow_bolt_client2 = {"sk_plr_xbow_bolt_client2","0"}; -cvar_t sk_plr_xbow_bolt_client3 = {"sk_plr_xbow_bolt_client3","0"}; - -cvar_t sk_plr_xbow_bolt_monster1 = {"sk_plr_xbow_bolt_monster1","0"}; -cvar_t sk_plr_xbow_bolt_monster2 = {"sk_plr_xbow_bolt_monster2","0"}; -cvar_t sk_plr_xbow_bolt_monster3 = {"sk_plr_xbow_bolt_monster3","0"}; - - -// RPG -cvar_t sk_plr_rpg1 = {"sk_plr_rpg1","0"}; -cvar_t sk_plr_rpg2 = {"sk_plr_rpg2","0"}; -cvar_t sk_plr_rpg3 = {"sk_plr_rpg3","0"}; - - -// Zero Point Generator -cvar_t sk_plr_gauss1 = {"sk_plr_gauss1","0"}; -cvar_t sk_plr_gauss2 = {"sk_plr_gauss2","0"}; -cvar_t sk_plr_gauss3 = {"sk_plr_gauss3","0"}; - - -// Tau Cannon -cvar_t sk_plr_egon_narrow1 = {"sk_plr_egon_narrow1","0"}; -cvar_t sk_plr_egon_narrow2 = {"sk_plr_egon_narrow2","0"}; -cvar_t sk_plr_egon_narrow3 = {"sk_plr_egon_narrow3","0"}; - -cvar_t sk_plr_egon_wide1 = {"sk_plr_egon_wide1","0"}; -cvar_t sk_plr_egon_wide2 = {"sk_plr_egon_wide2","0"}; -cvar_t sk_plr_egon_wide3 = {"sk_plr_egon_wide3","0"}; - - -// Hand Grendade -cvar_t sk_plr_hand_grenade1 = {"sk_plr_hand_grenade1","0"}; -cvar_t sk_plr_hand_grenade2 = {"sk_plr_hand_grenade2","0"}; -cvar_t sk_plr_hand_grenade3 = {"sk_plr_hand_grenade3","0"}; - - -// Satchel Charge -cvar_t sk_plr_satchel1 = {"sk_plr_satchel1","0"}; -cvar_t sk_plr_satchel2 = {"sk_plr_satchel2","0"}; -cvar_t sk_plr_satchel3 = {"sk_plr_satchel3","0"}; - - -// Tripmine -cvar_t sk_plr_tripmine1 = {"sk_plr_tripmine1","0"}; -cvar_t sk_plr_tripmine2 = {"sk_plr_tripmine2","0"}; -cvar_t sk_plr_tripmine3 = {"sk_plr_tripmine3","0"}; - - -// WORLD WEAPONS -cvar_t sk_12mm_bullet1 = {"sk_12mm_bullet1","0"}; -cvar_t sk_12mm_bullet2 = {"sk_12mm_bullet2","0"}; -cvar_t sk_12mm_bullet3 = {"sk_12mm_bullet3","0"}; - -cvar_t sk_9mmAR_bullet1 = {"sk_9mmAR_bullet1","0"}; -cvar_t sk_9mmAR_bullet2 = {"sk_9mmAR_bullet2","0"}; -cvar_t sk_9mmAR_bullet3 = {"sk_9mmAR_bullet3","0"}; - -cvar_t sk_9mm_bullet1 = {"sk_9mm_bullet1","0"}; -cvar_t sk_9mm_bullet2 = {"sk_9mm_bullet2","0"}; -cvar_t sk_9mm_bullet3 = {"sk_9mm_bullet3","0"}; - - -// HORNET -cvar_t sk_hornet_dmg1 = {"sk_hornet_dmg1","0"}; -cvar_t sk_hornet_dmg2 = {"sk_hornet_dmg2","0"}; -cvar_t sk_hornet_dmg3 = {"sk_hornet_dmg3","0"}; - -// HEALTH/CHARGE -cvar_t sk_suitcharger1 = { "sk_suitcharger1","0" }; -cvar_t sk_suitcharger2 = { "sk_suitcharger2","0" }; -cvar_t sk_suitcharger3 = { "sk_suitcharger3","0" }; - -cvar_t sk_battery1 = { "sk_battery1","0" }; -cvar_t sk_battery2 = { "sk_battery2","0" }; -cvar_t sk_battery3 = { "sk_battery3","0" }; - -cvar_t sk_healthcharger1 = { "sk_healthcharger1","0" }; -cvar_t sk_healthcharger2 = { "sk_healthcharger2","0" }; -cvar_t sk_healthcharger3 = { "sk_healthcharger3","0" }; - -cvar_t sk_healthkit1 = { "sk_healthkit1","0" }; -cvar_t sk_healthkit2 = { "sk_healthkit2","0" }; -cvar_t sk_healthkit3 = { "sk_healthkit3","0" }; - -cvar_t sk_scientist_heal1 = { "sk_scientist_heal1","0" }; -cvar_t sk_scientist_heal2 = { "sk_scientist_heal2","0" }; -cvar_t sk_scientist_heal3 = { "sk_scientist_heal3","0" }; - - -// monster damage adjusters -cvar_t sk_monster_head1 = { "sk_monster_head1","2" }; -cvar_t sk_monster_head2 = { "sk_monster_head2","2" }; -cvar_t sk_monster_head3 = { "sk_monster_head3","2" }; - -cvar_t sk_monster_chest1 = { "sk_monster_chest1","1" }; -cvar_t sk_monster_chest2 = { "sk_monster_chest2","1" }; -cvar_t sk_monster_chest3 = { "sk_monster_chest3","1" }; - -cvar_t sk_monster_stomach1 = { "sk_monster_stomach1","1" }; -cvar_t sk_monster_stomach2 = { "sk_monster_stomach2","1" }; -cvar_t sk_monster_stomach3 = { "sk_monster_stomach3","1" }; - -cvar_t sk_monster_arm1 = { "sk_monster_arm1","1" }; -cvar_t sk_monster_arm2 = { "sk_monster_arm2","1" }; -cvar_t sk_monster_arm3 = { "sk_monster_arm3","1" }; - -cvar_t sk_monster_leg1 = { "sk_monster_leg1","1" }; -cvar_t sk_monster_leg2 = { "sk_monster_leg2","1" }; -cvar_t sk_monster_leg3 = { "sk_monster_leg3","1" }; - -// player damage adjusters -cvar_t sk_player_head1 = { "sk_player_head1","2" }; -cvar_t sk_player_head2 = { "sk_player_head2","2" }; -cvar_t sk_player_head3 = { "sk_player_head3","2" }; - -cvar_t sk_player_chest1 = { "sk_player_chest1","1" }; -cvar_t sk_player_chest2 = { "sk_player_chest2","1" }; -cvar_t sk_player_chest3 = { "sk_player_chest3","1" }; - -cvar_t sk_player_stomach1 = { "sk_player_stomach1","1" }; -cvar_t sk_player_stomach2 = { "sk_player_stomach2","1" }; -cvar_t sk_player_stomach3 = { "sk_player_stomach3","1" }; - -cvar_t sk_player_arm1 = { "sk_player_arm1","1" }; -cvar_t sk_player_arm2 = { "sk_player_arm2","1" }; -cvar_t sk_player_arm3 = { "sk_player_arm3","1" }; - -cvar_t sk_player_leg1 = { "sk_player_leg1","1" }; -cvar_t sk_player_leg2 = { "sk_player_leg2","1" }; -cvar_t sk_player_leg3 = { "sk_player_leg3","1" }; - -// END Cvars for Skill Level settings - -// Register your console variables here -// This gets called one time when the game is initialied -void GameDLLInit( void ) -{ - // Register cvars here: - g_psv_gravity = CVAR_GET_POINTER( "sv_gravity" ); - g_psv_aim = CVAR_GET_POINTER( "sv_aim" ); - g_footsteps = CVAR_GET_POINTER( "mp_footsteps" ); - - CVAR_REGISTER (&displaysoundlist); - - CVAR_REGISTER (&teamplay); - CVAR_REGISTER (&fraglimit); - CVAR_REGISTER (&timelimit); - - CVAR_REGISTER (&fragsleft); - CVAR_REGISTER (&timeleft); - - CVAR_REGISTER( &allow_spectators ); - - // Discwar - CVAR_REGISTER (&rc_rounds); - CVAR_REGISTER (&rc_playersperteam); - CVAR_REGISTER (&rc_arena); - - CVAR_REGISTER (&friendlyfire); - CVAR_REGISTER (&falldamage); - CVAR_REGISTER (&weaponstay); - CVAR_REGISTER (&forcerespawn); - CVAR_REGISTER (&flashlight); - CVAR_REGISTER (&aimcrosshair); - CVAR_REGISTER (&decalfrequency); - CVAR_REGISTER (&teamlist); - CVAR_REGISTER (&teamoverride); - CVAR_REGISTER (&defaultteam); - CVAR_REGISTER (&allowmonsters); - -// REGISTER CVARS FOR SKILL LEVEL STUFF - // Agrunt - CVAR_REGISTER ( &sk_agrunt_health1 );// {"sk_agrunt_health1","0"}; - CVAR_REGISTER ( &sk_agrunt_health2 );// {"sk_agrunt_health2","0"}; - CVAR_REGISTER ( &sk_agrunt_health3 );// {"sk_agrunt_health3","0"}; - - CVAR_REGISTER ( &sk_agrunt_dmg_punch1 );// {"sk_agrunt_dmg_punch1","0"}; - CVAR_REGISTER ( &sk_agrunt_dmg_punch2 );// {"sk_agrunt_dmg_punch2","0"}; - CVAR_REGISTER ( &sk_agrunt_dmg_punch3 );// {"sk_agrunt_dmg_punch3","0"}; - - // Apache - CVAR_REGISTER ( &sk_apache_health1 );// {"sk_apache_health1","0"}; - CVAR_REGISTER ( &sk_apache_health2 );// {"sk_apache_health2","0"}; - CVAR_REGISTER ( &sk_apache_health3 );// {"sk_apache_health3","0"}; - - // Barney - CVAR_REGISTER ( &sk_barney_health1 );// {"sk_barney_health1","0"}; - CVAR_REGISTER ( &sk_barney_health2 );// {"sk_barney_health2","0"}; - CVAR_REGISTER ( &sk_barney_health3 );// {"sk_barney_health3","0"}; - - // Bullsquid - CVAR_REGISTER ( &sk_bullsquid_health1 );// {"sk_bullsquid_health1","0"}; - CVAR_REGISTER ( &sk_bullsquid_health2 );// {"sk_bullsquid_health2","0"}; - CVAR_REGISTER ( &sk_bullsquid_health3 );// {"sk_bullsquid_health3","0"}; - - CVAR_REGISTER ( &sk_bullsquid_dmg_bite1 );// {"sk_bullsquid_dmg_bite1","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_bite2 );// {"sk_bullsquid_dmg_bite2","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_bite3 );// {"sk_bullsquid_dmg_bite3","0"}; - - CVAR_REGISTER ( &sk_bullsquid_dmg_whip1 );// {"sk_bullsquid_dmg_whip1","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_whip2 );// {"sk_bullsquid_dmg_whip2","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_whip3 );// {"sk_bullsquid_dmg_whip3","0"}; - - CVAR_REGISTER ( &sk_bullsquid_dmg_spit1 );// {"sk_bullsquid_dmg_spit1","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_spit2 );// {"sk_bullsquid_dmg_spit2","0"}; - CVAR_REGISTER ( &sk_bullsquid_dmg_spit3 );// {"sk_bullsquid_dmg_spit3","0"}; - - - CVAR_REGISTER ( &sk_bigmomma_health_factor1 );// {"sk_bigmomma_health_factor1","1.0"}; - CVAR_REGISTER ( &sk_bigmomma_health_factor2 );// {"sk_bigmomma_health_factor2","1.0"}; - CVAR_REGISTER ( &sk_bigmomma_health_factor3 );// {"sk_bigmomma_health_factor3","1.0"}; - - CVAR_REGISTER ( &sk_bigmomma_dmg_slash1 );// {"sk_bigmomma_dmg_slash1","50"}; - CVAR_REGISTER ( &sk_bigmomma_dmg_slash2 );// {"sk_bigmomma_dmg_slash2","50"}; - CVAR_REGISTER ( &sk_bigmomma_dmg_slash3 );// {"sk_bigmomma_dmg_slash3","50"}; - - CVAR_REGISTER ( &sk_bigmomma_dmg_blast1 );// {"sk_bigmomma_dmg_blast1","100"}; - CVAR_REGISTER ( &sk_bigmomma_dmg_blast2 );// {"sk_bigmomma_dmg_blast2","100"}; - CVAR_REGISTER ( &sk_bigmomma_dmg_blast3 );// {"sk_bigmomma_dmg_blast3","100"}; - - CVAR_REGISTER ( &sk_bigmomma_radius_blast1 );// {"sk_bigmomma_radius_blast1","250"}; - CVAR_REGISTER ( &sk_bigmomma_radius_blast2 );// {"sk_bigmomma_radius_blast2","250"}; - CVAR_REGISTER ( &sk_bigmomma_radius_blast3 );// {"sk_bigmomma_radius_blast3","250"}; - - // Gargantua - CVAR_REGISTER ( &sk_gargantua_health1 );// {"sk_gargantua_health1","0"}; - CVAR_REGISTER ( &sk_gargantua_health2 );// {"sk_gargantua_health2","0"}; - CVAR_REGISTER ( &sk_gargantua_health3 );// {"sk_gargantua_health3","0"}; - - CVAR_REGISTER ( &sk_gargantua_dmg_slash1 );// {"sk_gargantua_dmg_slash1","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_slash2 );// {"sk_gargantua_dmg_slash2","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_slash3 );// {"sk_gargantua_dmg_slash3","0"}; - - CVAR_REGISTER ( &sk_gargantua_dmg_fire1 );// {"sk_gargantua_dmg_fire1","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_fire2 );// {"sk_gargantua_dmg_fire2","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_fire3 );// {"sk_gargantua_dmg_fire3","0"}; - - CVAR_REGISTER ( &sk_gargantua_dmg_stomp1 );// {"sk_gargantua_dmg_stomp1","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_stomp2 );// {"sk_gargantua_dmg_stomp2","0"}; - CVAR_REGISTER ( &sk_gargantua_dmg_stomp3 );// {"sk_gargantua_dmg_stomp3","0"}; - - - // Hassassin - CVAR_REGISTER ( &sk_hassassin_health1 );// {"sk_hassassin_health1","0"}; - CVAR_REGISTER ( &sk_hassassin_health2 );// {"sk_hassassin_health2","0"}; - CVAR_REGISTER ( &sk_hassassin_health3 );// {"sk_hassassin_health3","0"}; - - - // Headcrab - CVAR_REGISTER ( &sk_headcrab_health1 );// {"sk_headcrab_health1","0"}; - CVAR_REGISTER ( &sk_headcrab_health2 );// {"sk_headcrab_health2","0"}; - CVAR_REGISTER ( &sk_headcrab_health3 );// {"sk_headcrab_health3","0"}; - - CVAR_REGISTER ( &sk_headcrab_dmg_bite1 );// {"sk_headcrab_dmg_bite1","0"}; - CVAR_REGISTER ( &sk_headcrab_dmg_bite2 );// {"sk_headcrab_dmg_bite2","0"}; - CVAR_REGISTER ( &sk_headcrab_dmg_bite3 );// {"sk_headcrab_dmg_bite3","0"}; - - - // Hgrunt - CVAR_REGISTER ( &sk_hgrunt_health1 );// {"sk_hgrunt_health1","0"}; - CVAR_REGISTER ( &sk_hgrunt_health2 );// {"sk_hgrunt_health2","0"}; - CVAR_REGISTER ( &sk_hgrunt_health3 );// {"sk_hgrunt_health3","0"}; - - CVAR_REGISTER ( &sk_hgrunt_kick1 );// {"sk_hgrunt_kick1","0"}; - CVAR_REGISTER ( &sk_hgrunt_kick2 );// {"sk_hgrunt_kick2","0"}; - CVAR_REGISTER ( &sk_hgrunt_kick3 );// {"sk_hgrunt_kick3","0"}; - - CVAR_REGISTER ( &sk_hgrunt_pellets1 ); - CVAR_REGISTER ( &sk_hgrunt_pellets2 ); - CVAR_REGISTER ( &sk_hgrunt_pellets3 ); - - CVAR_REGISTER ( &sk_hgrunt_gspeed1 ); - CVAR_REGISTER ( &sk_hgrunt_gspeed2 ); - CVAR_REGISTER ( &sk_hgrunt_gspeed3 ); - - // Houndeye - CVAR_REGISTER ( &sk_houndeye_health1 );// {"sk_houndeye_health1","0"}; - CVAR_REGISTER ( &sk_houndeye_health2 );// {"sk_houndeye_health2","0"}; - CVAR_REGISTER ( &sk_houndeye_health3 );// {"sk_houndeye_health3","0"}; - - CVAR_REGISTER ( &sk_houndeye_dmg_blast1 );// {"sk_houndeye_dmg_blast1","0"}; - CVAR_REGISTER ( &sk_houndeye_dmg_blast2 );// {"sk_houndeye_dmg_blast2","0"}; - CVAR_REGISTER ( &sk_houndeye_dmg_blast3 );// {"sk_houndeye_dmg_blast3","0"}; - - - // ISlave - CVAR_REGISTER ( &sk_islave_health1 );// {"sk_islave_health1","0"}; - CVAR_REGISTER ( &sk_islave_health2 );// {"sk_islave_health2","0"}; - CVAR_REGISTER ( &sk_islave_health3 );// {"sk_islave_health3","0"}; - - CVAR_REGISTER ( &sk_islave_dmg_claw1 );// {"sk_islave_dmg_claw1","0"}; - CVAR_REGISTER ( &sk_islave_dmg_claw2 );// {"sk_islave_dmg_claw2","0"}; - CVAR_REGISTER ( &sk_islave_dmg_claw3 );// {"sk_islave_dmg_claw3","0"}; - - CVAR_REGISTER ( &sk_islave_dmg_clawrake1 );// {"sk_islave_dmg_clawrake1","0"}; - CVAR_REGISTER ( &sk_islave_dmg_clawrake2 );// {"sk_islave_dmg_clawrake2","0"}; - CVAR_REGISTER ( &sk_islave_dmg_clawrake3 );// {"sk_islave_dmg_clawrake3","0"}; - - CVAR_REGISTER ( &sk_islave_dmg_zap1 );// {"sk_islave_dmg_zap1","0"}; - CVAR_REGISTER ( &sk_islave_dmg_zap2 );// {"sk_islave_dmg_zap2","0"}; - CVAR_REGISTER ( &sk_islave_dmg_zap3 );// {"sk_islave_dmg_zap3","0"}; - - - // Icthyosaur - CVAR_REGISTER ( &sk_ichthyosaur_health1 );// {"sk_ichthyosaur_health1","0"}; - CVAR_REGISTER ( &sk_ichthyosaur_health2 );// {"sk_ichthyosaur_health2","0"}; - CVAR_REGISTER ( &sk_ichthyosaur_health3 );// {"sk_ichthyosaur_health3","0"}; - - CVAR_REGISTER ( &sk_ichthyosaur_shake1 );// {"sk_ichthyosaur_health3","0"}; - CVAR_REGISTER ( &sk_ichthyosaur_shake2 );// {"sk_ichthyosaur_health3","0"}; - CVAR_REGISTER ( &sk_ichthyosaur_shake3 );// {"sk_ichthyosaur_health3","0"}; - - - - // Leech - CVAR_REGISTER ( &sk_leech_health1 );// {"sk_leech_health1","0"}; - CVAR_REGISTER ( &sk_leech_health2 );// {"sk_leech_health2","0"}; - CVAR_REGISTER ( &sk_leech_health3 );// {"sk_leech_health3","0"}; - - CVAR_REGISTER ( &sk_leech_dmg_bite1 );// {"sk_leech_dmg_bite1","0"}; - CVAR_REGISTER ( &sk_leech_dmg_bite2 );// {"sk_leech_dmg_bite2","0"}; - CVAR_REGISTER ( &sk_leech_dmg_bite3 );// {"sk_leech_dmg_bite3","0"}; - - - // Controller - CVAR_REGISTER ( &sk_controller_health1 ); - CVAR_REGISTER ( &sk_controller_health2 ); - CVAR_REGISTER ( &sk_controller_health3 ); - - CVAR_REGISTER ( &sk_controller_dmgzap1 ); - CVAR_REGISTER ( &sk_controller_dmgzap2 ); - CVAR_REGISTER ( &sk_controller_dmgzap3 ); - - CVAR_REGISTER ( &sk_controller_speedball1 ); - CVAR_REGISTER ( &sk_controller_speedball2 ); - CVAR_REGISTER ( &sk_controller_speedball3 ); - - CVAR_REGISTER ( &sk_controller_dmgball1 ); - CVAR_REGISTER ( &sk_controller_dmgball2 ); - CVAR_REGISTER ( &sk_controller_dmgball3 ); - - // Nihilanth - CVAR_REGISTER ( &sk_nihilanth_health1 );// {"sk_nihilanth_health1","0"}; - CVAR_REGISTER ( &sk_nihilanth_health2 );// {"sk_nihilanth_health2","0"}; - CVAR_REGISTER ( &sk_nihilanth_health3 );// {"sk_nihilanth_health3","0"}; - - CVAR_REGISTER ( &sk_nihilanth_zap1 ); - CVAR_REGISTER ( &sk_nihilanth_zap2 ); - CVAR_REGISTER ( &sk_nihilanth_zap3 ); - - // Scientist - CVAR_REGISTER ( &sk_scientist_health1 );// {"sk_scientist_health1","0"}; - CVAR_REGISTER ( &sk_scientist_health2 );// {"sk_scientist_health2","0"}; - CVAR_REGISTER ( &sk_scientist_health3 );// {"sk_scientist_health3","0"}; - - - // Snark - CVAR_REGISTER ( &sk_snark_health1 );// {"sk_snark_health1","0"}; - CVAR_REGISTER ( &sk_snark_health2 );// {"sk_snark_health2","0"}; - CVAR_REGISTER ( &sk_snark_health3 );// {"sk_snark_health3","0"}; - - CVAR_REGISTER ( &sk_snark_dmg_bite1 );// {"sk_snark_dmg_bite1","0"}; - CVAR_REGISTER ( &sk_snark_dmg_bite2 );// {"sk_snark_dmg_bite2","0"}; - CVAR_REGISTER ( &sk_snark_dmg_bite3 );// {"sk_snark_dmg_bite3","0"}; - - CVAR_REGISTER ( &sk_snark_dmg_pop1 );// {"sk_snark_dmg_pop1","0"}; - CVAR_REGISTER ( &sk_snark_dmg_pop2 );// {"sk_snark_dmg_pop2","0"}; - CVAR_REGISTER ( &sk_snark_dmg_pop3 );// {"sk_snark_dmg_pop3","0"}; - - - - // Zombie - CVAR_REGISTER ( &sk_zombie_health1 );// {"sk_zombie_health1","0"}; - CVAR_REGISTER ( &sk_zombie_health2 );// {"sk_zombie_health3","0"}; - CVAR_REGISTER ( &sk_zombie_health3 );// {"sk_zombie_health3","0"}; - - CVAR_REGISTER ( &sk_zombie_dmg_one_slash1 );// {"sk_zombie_dmg_one_slash1","0"}; - CVAR_REGISTER ( &sk_zombie_dmg_one_slash2 );// {"sk_zombie_dmg_one_slash2","0"}; - CVAR_REGISTER ( &sk_zombie_dmg_one_slash3 );// {"sk_zombie_dmg_one_slash3","0"}; - - CVAR_REGISTER ( &sk_zombie_dmg_both_slash1 );// {"sk_zombie_dmg_both_slash1","0"}; - CVAR_REGISTER ( &sk_zombie_dmg_both_slash2 );// {"sk_zombie_dmg_both_slash2","0"}; - CVAR_REGISTER ( &sk_zombie_dmg_both_slash3 );// {"sk_zombie_dmg_both_slash3","0"}; - - - //Turret - CVAR_REGISTER ( &sk_turret_health1 );// {"sk_turret_health1","0"}; - CVAR_REGISTER ( &sk_turret_health2 );// {"sk_turret_health2","0"}; - CVAR_REGISTER ( &sk_turret_health3 );// {"sk_turret_health3","0"}; - - - // MiniTurret - CVAR_REGISTER ( &sk_miniturret_health1 );// {"sk_miniturret_health1","0"}; - CVAR_REGISTER ( &sk_miniturret_health2 );// {"sk_miniturret_health2","0"}; - CVAR_REGISTER ( &sk_miniturret_health3 );// {"sk_miniturret_health3","0"}; - - - // Sentry Turret - CVAR_REGISTER ( &sk_sentry_health1 );// {"sk_sentry_health1","0"}; - CVAR_REGISTER ( &sk_sentry_health2 );// {"sk_sentry_health2","0"}; - CVAR_REGISTER ( &sk_sentry_health3 );// {"sk_sentry_health3","0"}; - - - // PLAYER WEAPONS - - // Crowbar whack - CVAR_REGISTER ( &sk_plr_crowbar1 );// {"sk_plr_crowbar1","0"}; - CVAR_REGISTER ( &sk_plr_crowbar2 );// {"sk_plr_crowbar2","0"}; - CVAR_REGISTER ( &sk_plr_crowbar3 );// {"sk_plr_crowbar3","0"}; - - // Glock Round - CVAR_REGISTER ( &sk_plr_9mm_bullet1 );// {"sk_plr_9mm_bullet1","0"}; - CVAR_REGISTER ( &sk_plr_9mm_bullet2 );// {"sk_plr_9mm_bullet2","0"}; - CVAR_REGISTER ( &sk_plr_9mm_bullet3 );// {"sk_plr_9mm_bullet3","0"}; - - // 357 Round - CVAR_REGISTER ( &sk_plr_357_bullet1 );// {"sk_plr_357_bullet1","0"}; - CVAR_REGISTER ( &sk_plr_357_bullet2 );// {"sk_plr_357_bullet2","0"}; - CVAR_REGISTER ( &sk_plr_357_bullet3 );// {"sk_plr_357_bullet3","0"}; - - // MP5 Round - CVAR_REGISTER ( &sk_plr_9mmAR_bullet1 );// {"sk_plr_9mmAR_bullet1","0"}; - CVAR_REGISTER ( &sk_plr_9mmAR_bullet2 );// {"sk_plr_9mmAR_bullet2","0"}; - CVAR_REGISTER ( &sk_plr_9mmAR_bullet3 );// {"sk_plr_9mmAR_bullet3","0"}; - - - // M203 grenade - CVAR_REGISTER ( &sk_plr_9mmAR_grenade1 );// {"sk_plr_9mmAR_grenade1","0"}; - CVAR_REGISTER ( &sk_plr_9mmAR_grenade2 );// {"sk_plr_9mmAR_grenade2","0"}; - CVAR_REGISTER ( &sk_plr_9mmAR_grenade3 );// {"sk_plr_9mmAR_grenade3","0"}; - - - // Shotgun buckshot - CVAR_REGISTER ( &sk_plr_buckshot1 );// {"sk_plr_buckshot1","0"}; - CVAR_REGISTER ( &sk_plr_buckshot2 );// {"sk_plr_buckshot2","0"}; - CVAR_REGISTER ( &sk_plr_buckshot3 );// {"sk_plr_buckshot3","0"}; - - - // Crossbow - CVAR_REGISTER ( &sk_plr_xbow_bolt_monster1 );// {"sk_plr_xbow_bolt1","0"}; - CVAR_REGISTER ( &sk_plr_xbow_bolt_monster2 );// {"sk_plr_xbow_bolt2","0"}; - CVAR_REGISTER ( &sk_plr_xbow_bolt_monster3 );// {"sk_plr_xbow_bolt3","0"}; - - CVAR_REGISTER ( &sk_plr_xbow_bolt_client1 );// {"sk_plr_xbow_bolt1","0"}; - CVAR_REGISTER ( &sk_plr_xbow_bolt_client2 );// {"sk_plr_xbow_bolt2","0"}; - CVAR_REGISTER ( &sk_plr_xbow_bolt_client3 );// {"sk_plr_xbow_bolt3","0"}; - - - // RPG - CVAR_REGISTER ( &sk_plr_rpg1 );// {"sk_plr_rpg1","0"}; - CVAR_REGISTER ( &sk_plr_rpg2 );// {"sk_plr_rpg2","0"}; - CVAR_REGISTER ( &sk_plr_rpg3 );// {"sk_plr_rpg3","0"}; - - - // Gauss Gun - CVAR_REGISTER ( &sk_plr_gauss1 );// {"sk_plr_gauss1","0"}; - CVAR_REGISTER ( &sk_plr_gauss2 );// {"sk_plr_gauss2","0"}; - CVAR_REGISTER ( &sk_plr_gauss3 );// {"sk_plr_gauss3","0"}; - - - // Egon Gun - CVAR_REGISTER ( &sk_plr_egon_narrow1 );// {"sk_plr_egon_narrow1","0"}; - CVAR_REGISTER ( &sk_plr_egon_narrow2 );// {"sk_plr_egon_narrow2","0"}; - CVAR_REGISTER ( &sk_plr_egon_narrow3 );// {"sk_plr_egon_narrow3","0"}; - - CVAR_REGISTER ( &sk_plr_egon_wide1 );// {"sk_plr_egon_wide1","0"}; - CVAR_REGISTER ( &sk_plr_egon_wide2 );// {"sk_plr_egon_wide2","0"}; - CVAR_REGISTER ( &sk_plr_egon_wide3 );// {"sk_plr_egon_wide3","0"}; - - - // Hand Grendade - CVAR_REGISTER ( &sk_plr_hand_grenade1 );// {"sk_plr_hand_grenade1","0"}; - CVAR_REGISTER ( &sk_plr_hand_grenade2 );// {"sk_plr_hand_grenade2","0"}; - CVAR_REGISTER ( &sk_plr_hand_grenade3 );// {"sk_plr_hand_grenade3","0"}; - - - // Satchel Charge - CVAR_REGISTER ( &sk_plr_satchel1 );// {"sk_plr_satchel1","0"}; - CVAR_REGISTER ( &sk_plr_satchel2 );// {"sk_plr_satchel2","0"}; - CVAR_REGISTER ( &sk_plr_satchel3 );// {"sk_plr_satchel3","0"}; - - - // Tripmine - CVAR_REGISTER ( &sk_plr_tripmine1 );// {"sk_plr_tripmine1","0"}; - CVAR_REGISTER ( &sk_plr_tripmine2 );// {"sk_plr_tripmine2","0"}; - CVAR_REGISTER ( &sk_plr_tripmine3 );// {"sk_plr_tripmine3","0"}; - - - // WORLD WEAPONS - CVAR_REGISTER ( &sk_12mm_bullet1 );// {"sk_12mm_bullet1","0"}; - CVAR_REGISTER ( &sk_12mm_bullet2 );// {"sk_12mm_bullet2","0"}; - CVAR_REGISTER ( &sk_12mm_bullet3 );// {"sk_12mm_bullet3","0"}; - - CVAR_REGISTER ( &sk_9mmAR_bullet1 );// {"sk_9mm_bullet1","0"}; - CVAR_REGISTER ( &sk_9mmAR_bullet2 );// {"sk_9mm_bullet1","0"}; - CVAR_REGISTER ( &sk_9mmAR_bullet3 );// {"sk_9mm_bullet1","0"}; - - CVAR_REGISTER ( &sk_9mm_bullet1 );// {"sk_9mm_bullet1","0"}; - CVAR_REGISTER ( &sk_9mm_bullet2 );// {"sk_9mm_bullet2","0"}; - CVAR_REGISTER ( &sk_9mm_bullet3 );// {"sk_9mm_bullet3","0"}; - - - // HORNET - CVAR_REGISTER ( &sk_hornet_dmg1 );// {"sk_hornet_dmg1","0"}; - CVAR_REGISTER ( &sk_hornet_dmg2 );// {"sk_hornet_dmg2","0"}; - CVAR_REGISTER ( &sk_hornet_dmg3 );// {"sk_hornet_dmg3","0"}; - - // HEALTH/SUIT CHARGE DISTRIBUTION - CVAR_REGISTER ( &sk_suitcharger1 ); - CVAR_REGISTER ( &sk_suitcharger2 ); - CVAR_REGISTER ( &sk_suitcharger3 ); - - CVAR_REGISTER ( &sk_battery1 ); - CVAR_REGISTER ( &sk_battery2 ); - CVAR_REGISTER ( &sk_battery3 ); - - CVAR_REGISTER ( &sk_healthcharger1 ); - CVAR_REGISTER ( &sk_healthcharger2 ); - CVAR_REGISTER ( &sk_healthcharger3 ); - - CVAR_REGISTER ( &sk_healthkit1 ); - CVAR_REGISTER ( &sk_healthkit2 ); - CVAR_REGISTER ( &sk_healthkit3 ); - - CVAR_REGISTER ( &sk_scientist_heal1 ); - CVAR_REGISTER ( &sk_scientist_heal2 ); - CVAR_REGISTER ( &sk_scientist_heal3 ); - -// monster damage adjusters - CVAR_REGISTER ( &sk_monster_head1 ); - CVAR_REGISTER ( &sk_monster_head2 ); - CVAR_REGISTER ( &sk_monster_head3 ); - - CVAR_REGISTER ( &sk_monster_chest1 ); - CVAR_REGISTER ( &sk_monster_chest2 ); - CVAR_REGISTER ( &sk_monster_chest3 ); - - CVAR_REGISTER ( &sk_monster_stomach1 ); - CVAR_REGISTER ( &sk_monster_stomach2 ); - CVAR_REGISTER ( &sk_monster_stomach3 ); - - CVAR_REGISTER ( &sk_monster_arm1 ); - CVAR_REGISTER ( &sk_monster_arm2 ); - CVAR_REGISTER ( &sk_monster_arm3 ); - - CVAR_REGISTER ( &sk_monster_leg1 ); - CVAR_REGISTER ( &sk_monster_leg2 ); - CVAR_REGISTER ( &sk_monster_leg3 ); - -// player damage adjusters - CVAR_REGISTER ( &sk_player_head1 ); - CVAR_REGISTER ( &sk_player_head2 ); - CVAR_REGISTER ( &sk_player_head3 ); - - CVAR_REGISTER ( &sk_player_chest1 ); - CVAR_REGISTER ( &sk_player_chest2 ); - CVAR_REGISTER ( &sk_player_chest3 ); - - CVAR_REGISTER ( &sk_player_stomach1 ); - CVAR_REGISTER ( &sk_player_stomach2 ); - CVAR_REGISTER ( &sk_player_stomach3 ); - - CVAR_REGISTER ( &sk_player_arm1 ); - CVAR_REGISTER ( &sk_player_arm2 ); - CVAR_REGISTER ( &sk_player_arm3 ); - - CVAR_REGISTER ( &sk_player_leg1 ); - CVAR_REGISTER ( &sk_player_leg2 ); - CVAR_REGISTER ( &sk_player_leg3 ); -// END REGISTER CVARS FOR SKILL LEVEL STUFF - - SERVER_COMMAND( "exec skill.cfg\n" ); -} - -void GameDLLShutdown() -{ -} diff --git a/ricochet/dlls/game.h b/ricochet/dlls/game.h deleted file mode 100644 index 9597833..0000000 --- a/ricochet/dlls/game.h +++ /dev/null @@ -1,44 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ - -#ifndef GAME_H -#define GAME_H - -extern void GameDLLInit( void ); -extern void GameDLLShutdown( void ); - -extern cvar_t displaysoundlist; - -// multiplayer server rules -extern cvar_t fraglimit; -extern cvar_t timelimit; -extern cvar_t friendlyfir; -extern cvar_t falldamage; -extern cvar_t weaponstay; -extern cvar_t forcerespaw; -extern cvar_t flashlight; -extern cvar_t aimcrosshair; -extern cvar_t decalfrequency; -extern cvar_t teamlist; -extern cvar_t teamoverride; -extern cvar_t defaultteam; -extern cvar_t allow_spectators; - -// Engine Cvars -extern cvar_t *g_psv_gravity; -extern cvar_t *g_psv_aim; -extern cvar_t *g_footsteps; - -#endif // GAME_H diff --git a/ricochet/dlls/gamerules.cpp b/ricochet/dlls/gamerules.cpp deleted file mode 100644 index eb10332..0000000 --- a/ricochet/dlls/gamerules.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -//========================================================= -// GameRules.cpp -//========================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "teamplay_gamerules.h" -#include "skill.h" - -extern edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ); - -DLL_GLOBAL CGameRules* g_pGameRules = NULL; -extern DLL_GLOBAL BOOL g_fGameOver; -extern int gmsgDeathMsg; // client dll messages -extern int gmsgScoreInfo; -extern int gmsgMOTD; - -//========================================================= -//========================================================= -BOOL CGameRules::CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int iMaxCarry ) -{ - int iAmmoIndex; - - if ( pszAmmoName ) - { - iAmmoIndex = pPlayer->GetAmmoIndex( pszAmmoName ); - - if ( iAmmoIndex > -1 ) - { - if ( pPlayer->AmmoInventory( iAmmoIndex ) < iMaxCarry ) - { - // player has room for more of this type of ammo - return TRUE; - } - } - } - - return FALSE; -} - -//========================================================= -//========================================================= -edict_t *CGameRules :: GetPlayerSpawnSpot( CBasePlayer *pPlayer ) -{ - edict_t *pentSpawnSpot = EntSelectSpawnPoint( pPlayer ); - - pPlayer->pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1); - pPlayer->pev->v_angle = g_vecZero; - pPlayer->pev->velocity = g_vecZero; - pPlayer->pev->angles = VARS(pentSpawnSpot)->angles; - pPlayer->pev->punchangle = g_vecZero; - pPlayer->pev->fixangle = TRUE; - - return pentSpawnSpot; -} - -//========================================================= -//========================================================= -BOOL CGameRules::CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ - // only living players can have items - if ( pPlayer->pev->deadflag != DEAD_NO ) - return FALSE; - - if ( pWeapon->pszAmmo1() ) - { - if ( !CanHaveAmmo( pPlayer, pWeapon->pszAmmo1(), pWeapon->iMaxAmmo1() ) ) - { - // we can't carry anymore ammo for this gun. We can only - // have the gun if we aren't already carrying one of this type - if ( pPlayer->HasPlayerItem( pWeapon ) ) - { - return FALSE; - } - } - } - else - { - // weapon doesn't use ammo, don't take another if you already have it. - if ( pPlayer->HasPlayerItem( pWeapon ) ) - { - return FALSE; - } - } - - // note: will fall through to here if GetItemInfo doesn't fill the struct! - return TRUE; -} - -//========================================================= -// load the SkillData struct with the proper values based on the skill level. -//========================================================= -void CGameRules::RefreshSkillData ( void ) -{ - int iSkill; - - iSkill = (int)CVAR_GET_FLOAT("skill"); - - if ( iSkill < 1 ) - { - iSkill = 1; - } - else if ( iSkill > 3 ) - { - iSkill = 3; - } - - gSkillData.iSkillLevel = iSkill; - - ALERT ( at_console, "\nGAME SKILL LEVEL:%d\n",iSkill ); - - //Agrunt - gSkillData.agruntHealth = GetSkillCvar( "sk_agrunt_health" ); - gSkillData.agruntDmgPunch = GetSkillCvar( "sk_agrunt_dmg_punch"); - - // Apache - gSkillData.apacheHealth = GetSkillCvar( "sk_apache_health"); - - // Barney - gSkillData.barneyHealth = GetSkillCvar( "sk_barney_health"); - - // Big Momma - gSkillData.bigmommaHealthFactor = GetSkillCvar( "sk_bigmomma_health_factor" ); - gSkillData.bigmommaDmgSlash = GetSkillCvar( "sk_bigmomma_dmg_slash" ); - gSkillData.bigmommaDmgBlast = GetSkillCvar( "sk_bigmomma_dmg_blast" ); - gSkillData.bigmommaRadiusBlast = GetSkillCvar( "sk_bigmomma_radius_blast" ); - - // Bullsquid - gSkillData.bullsquidHealth = GetSkillCvar( "sk_bullsquid_health"); - gSkillData.bullsquidDmgBite = GetSkillCvar( "sk_bullsquid_dmg_bite"); - gSkillData.bullsquidDmgWhip = GetSkillCvar( "sk_bullsquid_dmg_whip"); - gSkillData.bullsquidDmgSpit = GetSkillCvar( "sk_bullsquid_dmg_spit"); - - // Gargantua - gSkillData.gargantuaHealth = GetSkillCvar( "sk_gargantua_health"); - gSkillData.gargantuaDmgSlash = GetSkillCvar( "sk_gargantua_dmg_slash"); - gSkillData.gargantuaDmgFire = GetSkillCvar( "sk_gargantua_dmg_fire"); - gSkillData.gargantuaDmgStomp = GetSkillCvar( "sk_gargantua_dmg_stomp"); - - // Hassassin - gSkillData.hassassinHealth = GetSkillCvar( "sk_hassassin_health"); - - // Headcrab - gSkillData.headcrabHealth = GetSkillCvar( "sk_headcrab_health"); - gSkillData.headcrabDmgBite = GetSkillCvar( "sk_headcrab_dmg_bite"); - - // Hgrunt - gSkillData.hgruntHealth = GetSkillCvar( "sk_hgrunt_health"); - gSkillData.hgruntDmgKick = GetSkillCvar( "sk_hgrunt_kick"); - gSkillData.hgruntShotgunPellets = GetSkillCvar( "sk_hgrunt_pellets"); - gSkillData.hgruntGrenadeSpeed = GetSkillCvar( "sk_hgrunt_gspeed"); - - // Houndeye - gSkillData.houndeyeHealth = GetSkillCvar( "sk_houndeye_health"); - gSkillData.houndeyeDmgBlast = GetSkillCvar( "sk_houndeye_dmg_blast"); - - // ISlave - gSkillData.slaveHealth = GetSkillCvar( "sk_islave_health"); - gSkillData.slaveDmgClaw = GetSkillCvar( "sk_islave_dmg_claw"); - gSkillData.slaveDmgClawrake = GetSkillCvar( "sk_islave_dmg_clawrake"); - gSkillData.slaveDmgZap = GetSkillCvar( "sk_islave_dmg_zap"); - - // Icthyosaur - gSkillData.ichthyosaurHealth = GetSkillCvar( "sk_ichthyosaur_health"); - gSkillData.ichthyosaurDmgShake = GetSkillCvar( "sk_ichthyosaur_shake"); - - // Leech - gSkillData.leechHealth = GetSkillCvar( "sk_leech_health"); - - gSkillData.leechDmgBite = GetSkillCvar( "sk_leech_dmg_bite"); - - // Controller - gSkillData.controllerHealth = GetSkillCvar( "sk_controller_health"); - gSkillData.controllerDmgZap = GetSkillCvar( "sk_controller_dmgzap"); - gSkillData.controllerSpeedBall = GetSkillCvar( "sk_controller_speedball"); - gSkillData.controllerDmgBall = GetSkillCvar( "sk_controller_dmgball"); - - // Nihilanth - gSkillData.nihilanthHealth = GetSkillCvar( "sk_nihilanth_health"); - gSkillData.nihilanthZap = GetSkillCvar( "sk_nihilanth_zap"); - - // Scientist - gSkillData.scientistHealth = GetSkillCvar( "sk_scientist_health"); - - // Snark - gSkillData.snarkHealth = GetSkillCvar( "sk_snark_health"); - gSkillData.snarkDmgBite = GetSkillCvar( "sk_snark_dmg_bite"); - gSkillData.snarkDmgPop = GetSkillCvar( "sk_snark_dmg_pop"); - - // Zombie - gSkillData.zombieHealth = GetSkillCvar( "sk_zombie_health"); - gSkillData.zombieDmgOneSlash = GetSkillCvar( "sk_zombie_dmg_one_slash"); - gSkillData.zombieDmgBothSlash = GetSkillCvar( "sk_zombie_dmg_both_slash"); - - //Turret - gSkillData.turretHealth = GetSkillCvar( "sk_turret_health"); - - // MiniTurret - gSkillData.miniturretHealth = GetSkillCvar( "sk_miniturret_health"); - - // Sentry Turret - gSkillData.sentryHealth = GetSkillCvar( "sk_sentry_health"); - -// PLAYER WEAPONS - - // Crowbar whack - gSkillData.plrDmgCrowbar = GetSkillCvar( "sk_plr_crowbar"); - - // Glock Round - gSkillData.plrDmg9MM = GetSkillCvar( "sk_plr_9mm_bullet"); - - // 357 Round - gSkillData.plrDmg357 = GetSkillCvar( "sk_plr_357_bullet"); - - // MP5 Round - gSkillData.plrDmgMP5 = GetSkillCvar( "sk_plr_9mmAR_bullet"); - - // M203 grenade - gSkillData.plrDmgM203Grenade = GetSkillCvar( "sk_plr_9mmAR_grenade"); - - // Shotgun buckshot - gSkillData.plrDmgBuckshot = GetSkillCvar( "sk_plr_buckshot"); - - // Crossbow - gSkillData.plrDmgCrossbowClient = GetSkillCvar( "sk_plr_xbow_bolt_client"); - gSkillData.plrDmgCrossbowMonster = GetSkillCvar( "sk_plr_xbow_bolt_monster"); - - // RPG - gSkillData.plrDmgRPG = GetSkillCvar( "sk_plr_rpg"); - - // Gauss gun - gSkillData.plrDmgGauss = GetSkillCvar( "sk_plr_gauss"); - - // Egon Gun - gSkillData.plrDmgEgonNarrow = GetSkillCvar( "sk_plr_egon_narrow"); - gSkillData.plrDmgEgonWide = GetSkillCvar( "sk_plr_egon_wide"); - - // Hand Grendade - gSkillData.plrDmgHandGrenade = GetSkillCvar( "sk_plr_hand_grenade"); - - // Satchel Charge - gSkillData.plrDmgSatchel = GetSkillCvar( "sk_plr_satchel"); - - // Tripmine - gSkillData.plrDmgTripmine = GetSkillCvar( "sk_plr_tripmine"); - - // MONSTER WEAPONS - gSkillData.monDmg12MM = GetSkillCvar( "sk_12mm_bullet"); - gSkillData.monDmgMP5 = GetSkillCvar ("sk_9mmAR_bullet" ); - gSkillData.monDmg9MM = GetSkillCvar( "sk_9mm_bullet"); - - // MONSTER HORNET - gSkillData.monDmgHornet = GetSkillCvar( "sk_hornet_dmg"); - - // PLAYER HORNET -// Up to this point, player hornet damage and monster hornet damage were both using -// monDmgHornet to determine how much damage to do. In tuning the hivehand, we now need -// to separate player damage and monster hivehand damage. Since it's so late in the project, we've -// added plrDmgHornet to the SKILLDATA struct, but not to the engine CVar list, so it's inaccesible -// via SKILLS.CFG. Any player hivehand tuning must take place in the code. (sjb) - gSkillData.plrDmgHornet = 7; - - - // HEALTH/CHARGE - gSkillData.suitchargerCapacity = GetSkillCvar( "sk_suitcharger" ); - gSkillData.batteryCapacity = GetSkillCvar( "sk_battery" ); - gSkillData.healthchargerCapacity = GetSkillCvar ( "sk_healthcharger" ); - gSkillData.healthkitCapacity = GetSkillCvar ( "sk_healthkit" ); - gSkillData.scientistHeal = GetSkillCvar ( "sk_scientist_heal" ); - - // monster damage adj - gSkillData.monHead = GetSkillCvar( "sk_monster_head" ); - gSkillData.monChest = GetSkillCvar( "sk_monster_chest" ); - gSkillData.monStomach = GetSkillCvar( "sk_monster_stomach" ); - gSkillData.monLeg = GetSkillCvar( "sk_monster_leg" ); - gSkillData.monArm = GetSkillCvar( "sk_monster_arm" ); - - // player damage adj - gSkillData.plrHead = GetSkillCvar( "sk_player_head" ); - gSkillData.plrChest = GetSkillCvar( "sk_player_chest" ); - gSkillData.plrStomach = GetSkillCvar( "sk_player_stomach" ); - gSkillData.plrLeg = GetSkillCvar( "sk_player_leg" ); - gSkillData.plrArm = GetSkillCvar( "sk_player_arm" ); -} - -//========================================================= -// instantiate the proper game rules object -//========================================================= - -CGameRules *InstallGameRules( void ) -{ - SERVER_COMMAND( "exec game.cfg\n" ); - SERVER_EXECUTE( ); - - if ( !gpGlobals->deathmatch ) - { - // generic half-life - return new CHalfLifeRules; - } - else - { - // Discwar's always in teamplay mode. - //CVAR_SET_FLOAT( "mp_teamplay", 1 ); - //return new CHalfLifeTeamplay; - return new CHalfLifeMultiplay; - } -} - - - diff --git a/ricochet/dlls/gamerules.h b/ricochet/dlls/gamerules.h deleted file mode 100644 index 1ebdd41..0000000 --- a/ricochet/dlls/gamerules.h +++ /dev/null @@ -1,360 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -//========================================================= -// GameRules -//========================================================= - -//#include "weapons.h" -//#include "items.h" -class CBasePlayerItem; -class CBasePlayer; -class CItem; -class CBasePlayerAmmo; - -// weapon respawning return codes -enum -{ - GR_NONE = 0, - - GR_WEAPON_RESPAWN_YES, - GR_WEAPON_RESPAWN_NO, - - GR_AMMO_RESPAWN_YES, - GR_AMMO_RESPAWN_NO, - - GR_ITEM_RESPAWN_YES, - GR_ITEM_RESPAWN_NO, - - GR_PLR_DROP_GUN_ALL, - GR_PLR_DROP_GUN_ACTIVE, - GR_PLR_DROP_GUN_NO, - - GR_PLR_DROP_AMMO_ALL, - GR_PLR_DROP_AMMO_ACTIVE, - GR_PLR_DROP_AMMO_NO, -}; - -// Player relationship return codes -enum -{ - GR_NOTTEAMMATE = 0, - GR_TEAMMATE, - GR_ENEMY, - GR_ALLY, - GR_NEUTRAL, -}; - -class CGameRules -{ -public: - virtual void RefreshSkillData( void );// fill skill data struct with proper values - virtual void Think( void ) = 0;// GR_Think - runs every server frame, should handle any timer tasks, periodic events, etc. - virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ) = 0; // Can this item spawn (eg monsters don't spawn in deathmatch). - - virtual BOOL FAllowFlashlight( void ) = 0;// Are players allowed to switch on their flashlight? - virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) = 0;// should the player switch to this weapon? - virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) = 0;// I can't use this weapon anymore, get me the next best one. - -// Functions to verify the single/multiplayer status of a game - virtual BOOL IsMultiplayer( void ) = 0;// is this a multiplayer game? (either coop or deathmatch) - virtual BOOL IsDeathmatch( void ) = 0;//is this a deathmatch game? - virtual BOOL IsTeamplay( void ) { return FALSE; };// is this deathmatch game being played with team rules? - virtual BOOL IsCoOp( void ) = 0;// is this a coop game? - virtual const char *GetGameDescription( void ) { return "Ricochet"; } // this is the game name that gets seen in the server browser - -// Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) = 0;// a client just connected to the server (player hasn't spawned yet) - virtual void InitHUD( CBasePlayer *pl ) = 0; // the client dll is ready for updating - virtual void ClientDisconnected( edict_t *pClient ) = 0;// a client just disconnected from the server - virtual void UpdateGameMode( CBasePlayer *pPlayer ) {} // the client needs to be informed of the current game mode - -// Client damage rules - virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ) = 0;// this client just hit the ground after a fall. How much damage? - virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) {return TRUE;};// can this player take damage from this attacker? - virtual BOOL ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) { return TRUE; } - -// Client spawn/respawn control - virtual void PlayerSpawn( CBasePlayer *pPlayer ) = 0;// called by CBasePlayer::Spawn just before releasing player into the game - virtual void PlayerThink( CBasePlayer *pPlayer ) = 0; // called by CBasePlayer::PreThink every frame, before physics are run and after keys are accepted - virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ) = 0;// is this player allowed to respawn now? - virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ) = 0;// When in the future will this player be able to spawn? - virtual edict_t *GetPlayerSpawnSpot( CBasePlayer *pPlayer );// Place this player on their spawnspot and face them the proper direction. - - virtual BOOL AllowAutoTargetCrosshair( void ) { return TRUE; }; - virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) { return FALSE; }; // handles the user commands; returns TRUE if command handled properly - virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) {} // the player has changed userinfo; can change it now - -// Client kills/scoring - virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) = 0;// how many points do I award whoever kills this player? - virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) = 0;// Called each time a player dies - virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor )= 0;// Call this from within a GameRules class to report an obituary. -// Weapon retrieval - virtual BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon );// The player is touching an CBasePlayerItem, do I give it to him? - virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) = 0;// Called each time a player picks up a weapon from the ground - -// Weapon spawn/respawn control - virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon ) = 0;// should this weapon respawn? - virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon ) = 0;// when may this weapon respawn? - virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon ) = 0; // can i respawn now, and if not, when should i try again? - virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ) = 0;// where in the world should this weapon respawn? - -// Item retrieval - virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ) = 0;// is this player allowed to take this item? - virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ) = 0;// call each time a player picks up an item (battery, healthkit, longjump) - -// Item spawn/respawn control - virtual int ItemShouldRespawn( CItem *pItem ) = 0;// Should this item respawn? - virtual float FlItemRespawnTime( CItem *pItem ) = 0;// when may this item respawn? - virtual Vector VecItemRespawnSpot( CItem *pItem ) = 0;// where in the world should this item respawn? - -// Ammo retrieval - virtual BOOL CanHaveAmmo( CBasePlayer *pPlayer, const char *pszAmmoName, int iMaxCarry );// can this player take more of this ammo? - virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ) = 0;// called each time a player picks up some ammo in the world - -// Ammo spawn/respawn control - virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ) = 0;// should this ammo item respawn? - virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ) = 0;// when should this ammo item respawn? - virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ) = 0;// where in the world should this ammo item respawn? - // by default, everything spawns - -// Healthcharger respawn control - virtual float FlHealthChargerRechargeTime( void ) = 0;// how long until a depleted HealthCharger recharges itself? - virtual float FlHEVChargerRechargeTime( void ) { return 0; }// how long until a depleted HealthCharger recharges itself? - -// What happens to a dead player's weapons - virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ) = 0;// what do I do with a player's weapons when he's killed? - -// What happens to a dead player's ammo - virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ) = 0;// Do I drop ammo when the player dies? How much? - -// Teamplay stuff - virtual const char *GetTeamID( CBaseEntity *pEntity ) = 0;// what team is this entity on? - virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) = 0;// What is the player's relationship with this entity? - virtual int GetTeamIndex( const char *pTeamName ) { return -1; } - virtual const char *GetIndexedTeamName( int teamIndex ) { return ""; } - virtual BOOL IsValidTeam( const char *pTeamName ) { return TRUE; } - virtual void ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ) {} - virtual const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer ) { return ""; } - -// Sounds - virtual BOOL PlayTextureSounds( void ) { return TRUE; } - virtual BOOL PlayFootstepSounds( CBasePlayer *pl, float fvol ) { return TRUE; } - -// Monsters - virtual BOOL FAllowMonsters( void ) = 0;//are monsters allowed - - // Immediately end a multiplayer game - virtual void EndMultiplayerGame( void ) {} -}; - -extern CGameRules *InstallGameRules( void ); - - -//========================================================= -// CHalfLifeRules - rules for the single player Half-Life -// game. -//========================================================= -class CHalfLifeRules : public CGameRules -{ -public: - CHalfLifeRules ( void ); - -// GR_Think - virtual void Think( void ); - virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ); - virtual BOOL FAllowFlashlight( void ) { return TRUE; }; - - virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); - virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ); - -// Functions to verify the single/multiplayer status of a game - virtual BOOL IsMultiplayer( void ); - virtual BOOL IsDeathmatch( void ); - virtual BOOL IsCoOp( void ); - -// Client connection/disconnection - virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); - virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating - virtual void ClientDisconnected( edict_t *pClient ); - -// Client damage rules - virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ); - -// Client spawn/respawn control - virtual void PlayerSpawn( CBasePlayer *pPlayer ); - virtual void PlayerThink( CBasePlayer *pPlayer ); - virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ); - virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ); - - virtual BOOL AllowAutoTargetCrosshair( void ); - -// Client kills/scoring - virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); - virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - -// Weapon retrieval - virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); - -// Weapon spawn/respawn control - virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon ); - virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon ); - virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon ); - virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ); - -// Item retrieval - virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ); - virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ); - -// Item spawn/respawn control - virtual int ItemShouldRespawn( CItem *pItem ); - virtual float FlItemRespawnTime( CItem *pItem ); - virtual Vector VecItemRespawnSpot( CItem *pItem ); - -// Ammo retrieval - virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ); - -// Ammo spawn/respawn control - virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ); - virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ); - virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ); - -// Healthcharger respawn control - virtual float FlHealthChargerRechargeTime( void ); - -// What happens to a dead player's weapons - virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ); - -// What happens to a dead player's ammo - virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ); - -// Monsters - virtual BOOL FAllowMonsters( void ); - -// Teamplay stuff - virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";}; - virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); -}; - -//========================================================= -// CHalfLifeMultiplay - rules for the basic half life multiplayer -// competition -//========================================================= -class CHalfLifeMultiplay : public CGameRules -{ -public: - CHalfLifeMultiplay(); - -// GR_Think - virtual void Think( void ); - virtual void RefreshSkillData( void ); - virtual BOOL IsAllowedToSpawn( CBaseEntity *pEntity ); - virtual BOOL FAllowFlashlight( void ); - - virtual BOOL FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); - virtual BOOL GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ); - -// Functions to verify the single/multiplayer status of a game - virtual BOOL IsMultiplayer( void ); - virtual BOOL IsDeathmatch( void ); - virtual BOOL IsCoOp( void ); - -// Client connection/disconnection - // If ClientConnected returns FALSE, the connection is rejected and the user is provided the reason specified in - // svRejectReason - // Only the client's name and remote address are provided to the dll for verification. - virtual BOOL ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ); - virtual void InitHUD( CBasePlayer *pl ); // the client dll is ready for updating - virtual void ClientDisconnected( edict_t *pClient ); - virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode - -// Client damage rules - virtual float FlPlayerFallDamage( CBasePlayer *pPlayer ); - virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ); - -// Client spawn/respawn control - virtual void PlayerSpawn( CBasePlayer *pPlayer ); - virtual void PlayerThink( CBasePlayer *pPlayer ); - virtual BOOL FPlayerCanRespawn( CBasePlayer *pPlayer ); - virtual float FlPlayerSpawnTime( CBasePlayer *pPlayer ); - virtual edict_t *GetPlayerSpawnSpot( CBasePlayer *pPlayer ); - - virtual BOOL AllowAutoTargetCrosshair( void ); - virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ); - -// Client kills/scoring - virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); - virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - -// Weapon retrieval - virtual void PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ); - virtual BOOL CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon );// The player is touching an CBasePlayerItem, do I give it to him? - -// Weapon spawn/respawn control - virtual int WeaponShouldRespawn( CBasePlayerItem *pWeapon ); - virtual float FlWeaponRespawnTime( CBasePlayerItem *pWeapon ); - virtual float FlWeaponTryRespawn( CBasePlayerItem *pWeapon ); - virtual Vector VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ); - -// Item retrieval - virtual BOOL CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ); - virtual void PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ); - -// Item spawn/respawn control - virtual int ItemShouldRespawn( CItem *pItem ); - virtual float FlItemRespawnTime( CItem *pItem ); - virtual Vector VecItemRespawnSpot( CItem *pItem ); - -// Ammo retrieval - virtual void PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ); - -// Ammo spawn/respawn control - virtual int AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ); - virtual float FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ); - virtual Vector VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ); - -// Healthcharger respawn control - virtual float FlHealthChargerRechargeTime( void ); - virtual float FlHEVChargerRechargeTime( void ); - -// What happens to a dead player's weapons - virtual int DeadPlayerWeapons( CBasePlayer *pPlayer ); - -// What happens to a dead player's ammo - virtual int DeadPlayerAmmo( CBasePlayer *pPlayer ); - -// Teamplay stuff - virtual const char *GetTeamID( CBaseEntity *pEntity ) {return "";} - virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); - - virtual BOOL PlayTextureSounds( void ) { return FALSE; } - virtual BOOL PlayFootstepSounds( CBasePlayer *pl, float fvol ); - -// Monsters - virtual BOOL FAllowMonsters( void ); - - // Immediately end a multiplayer game - virtual void EndMultiplayerGame( void ) { GoToIntermission(); } - -protected: - virtual void ChangeLevel( void ); - virtual void GoToIntermission( void ); - float m_flIntermissionEndTime; - BOOL m_iEndIntermissionButtonHit; - void SendMOTDToClient( edict_t *client ); -}; - -extern DLL_GLOBAL CGameRules* g_pGameRules; diff --git a/ricochet/dlls/ggrenade.cpp b/ricochet/dlls/ggrenade.cpp deleted file mode 100644 index faa7204..0000000 --- a/ricochet/dlls/ggrenade.cpp +++ /dev/null @@ -1,488 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== generic grenade.cpp ======================================================== - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "weapons.h" -#include "nodes.h" -#include "soundent.h" -#include "decals.h" - - -//===================grenade - - -LINK_ENTITY_TO_CLASS( grenade, CGrenade ); - -// Grenades flagged with this will be triggered when the owner calls detonateSatchelCharges -#define SF_DETONATE 0x0001 - -// -// Grenade Explode -// -void CGrenade::Explode( Vector vecSrc, Vector vecAim ) -{ - TraceResult tr; - UTIL_TraceLine ( pev->origin, pev->origin + Vector ( 0, 0, -32 ), ignore_monsters, ENT(pev), & tr); - - Explode( &tr, DMG_BLAST ); -} - -// UNDONE: temporary scorching for PreAlpha - find a less sleazy permenant solution. -void CGrenade::Explode( TraceResult *pTrace, int bitsDamageType ) -{ - float flRndSound;// sound randomizer - - pev->model = iStringNull;//invisible - pev->solid = SOLID_NOT;// intangible - - pev->takedamage = DAMAGE_NO; - - // Pull out of the wall a bit - if ( pTrace->flFraction != 1.0 ) - { - pev->origin = pTrace->vecEndPos + (pTrace->vecPlaneNormal * (pev->dmg - 24) * 0.6); - } - - int iContents = UTIL_PointContents ( pev->origin ); - - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); - WRITE_BYTE( TE_EXPLOSION ); // This makes a dynamic light and the explosion sprites/sound - WRITE_COORD( pev->origin.x ); // Send to PAS because of the sound - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - if (iContents != CONTENTS_WATER) - { - WRITE_SHORT( g_sModelIndexFireball ); - } - else - { - WRITE_SHORT( g_sModelIndexWExplosion ); - } - WRITE_BYTE( (pev->dmg - 50) * .60 ); // scale * 10 - WRITE_BYTE( 15 ); // framerate - WRITE_BYTE( TE_EXPLFLAG_NONE ); - MESSAGE_END(); - - CSoundEnt::InsertSound ( bits_SOUND_COMBAT, pev->origin, NORMAL_EXPLOSION_VOLUME, 3.0 ); - entvars_t *pevOwner; - if ( pev->owner ) - pevOwner = VARS( pev->owner ); - else - pevOwner = NULL; - - pev->owner = NULL; // can't traceline attack owner if this is set - - RadiusDamage ( pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType ); - - if ( RANDOM_FLOAT( 0 , 1 ) < 0.5 ) - { - UTIL_DecalTrace( pTrace, DECAL_SCORCH1 ); - } - else - { - UTIL_DecalTrace( pTrace, DECAL_SCORCH2 ); - } - - flRndSound = RANDOM_FLOAT( 0 , 1 ); - - switch ( RANDOM_LONG( 0, 2 ) ) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/debris1.wav", 0.55, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/debris2.wav", 0.55, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/debris3.wav", 0.55, ATTN_NORM); break; - } - - pev->effects |= EF_NODRAW; - SetThink( &CGrenade::Smoke ); - pev->velocity = g_vecZero; - pev->nextthink = gpGlobals->time + 0.3; - - if (iContents != CONTENTS_WATER) - { - int sparkCount = RANDOM_LONG(0,3); - for ( int i = 0; i < sparkCount; i++ ) - Create( "spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL ); - } -} - - -void CGrenade::Smoke( void ) -{ - if (UTIL_PointContents ( pev->origin ) == CONTENTS_WATER) - { - UTIL_Bubbles( pev->origin - Vector( 64, 64, 64 ), pev->origin + Vector( 64, 64, 64 ), 100 ); - } - else - { - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin ); - WRITE_BYTE( TE_SMOKE ); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( g_sModelIndexSmoke ); - WRITE_BYTE( (pev->dmg - 50) * 0.80 ); // scale * 10 - WRITE_BYTE( 12 ); // framerate - MESSAGE_END(); - } - UTIL_Remove( this ); -} - -void CGrenade::Killed( entvars_t *pevAttacker, int iGib ) -{ - Detonate( ); -} - - -// Timed grenade, this think is called when time runs out. -void CGrenade::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SetThink( &CGrenade::Detonate ); - pev->nextthink = gpGlobals->time; -} - -void CGrenade::PreDetonate( void ) -{ - CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin, 400, 0.3 ); - - SetThink( &CGrenade::Detonate ); - pev->nextthink = gpGlobals->time + 1; -} - - -void CGrenade::Detonate( void ) -{ - TraceResult tr; - Vector vecSpot;// trace starts here! - - vecSpot = pev->origin + Vector ( 0 , 0 , 8 ); - UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -40 ), ignore_monsters, ENT(pev), & tr); - - Explode( &tr, DMG_BLAST ); -} - - -// -// Contact grenade, explode when it touches something -// -void CGrenade::ExplodeTouch( CBaseEntity *pOther ) -{ - TraceResult tr; - Vector vecSpot;// trace starts here! - - pev->enemy = pOther->edict(); - - vecSpot = pev->origin - pev->velocity.Normalize() * 32; - UTIL_TraceLine( vecSpot, vecSpot + pev->velocity.Normalize() * 64, ignore_monsters, ENT(pev), &tr ); - - Explode( &tr, DMG_BLAST ); -} - - -void CGrenade::DangerSoundThink( void ) -{ - if (!IsInWorld()) - { - UTIL_Remove( this ); - return; - } - - CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin + pev->velocity * 0.5, pev->velocity.Length( ), 0.2 ); - pev->nextthink = gpGlobals->time + 0.2; - - if (pev->waterlevel != 0) - { - pev->velocity = pev->velocity * 0.5; - } -} - - -void CGrenade::BounceTouch( CBaseEntity *pOther ) -{ - // don't hit the guy that launched this grenade - if ( pOther->edict() == pev->owner ) - return; - - // only do damage if we're moving fairly fast - if (m_flNextAttack < gpGlobals->time && pev->velocity.Length() > 100) - { - entvars_t *pevOwner = VARS( pev->owner ); - if (pevOwner) - { - TraceResult tr = UTIL_GetGlobalTrace( ); - ClearMultiDamage( ); - pOther->TraceAttack(pevOwner, 1, gpGlobals->v_forward, &tr, DMG_CLUB ); - ApplyMultiDamage( pev, pevOwner); - } - m_flNextAttack = gpGlobals->time + 1.0; // debounce - } - - Vector vecTestVelocity; - // pev->avelocity = Vector (300, 300, 300); - - // this is my heuristic for modulating the grenade velocity because grenades dropped purely vertical - // or thrown very far tend to slow down too quickly for me to always catch just by testing velocity. - // trimming the Z velocity a bit seems to help quite a bit. - vecTestVelocity = pev->velocity; - vecTestVelocity.z *= 0.45; - - if ( !m_fRegisteredSound && vecTestVelocity.Length() <= 60 ) - { - //ALERT( at_console, "Grenade Registered!: %f\n", vecTestVelocity.Length() ); - - // grenade is moving really slow. It's probably very close to where it will ultimately stop moving. - // go ahead and emit the danger sound. - - // register a radius louder than the explosion, so we make sure everyone gets out of the way - CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin, pev->dmg / 0.4, 0.3 ); - m_fRegisteredSound = TRUE; - } - - if (pev->flags & FL_ONGROUND) - { - // add a bit of static friction - pev->velocity = pev->velocity * 0.8; - - pev->sequence = RANDOM_LONG( 1, 1 ); - } - else - { - // play bounce sound - BounceSound(); - } - pev->framerate = pev->velocity.Length() / 200.0; - if (pev->framerate > 1.0) - pev->framerate = 1; - else if (pev->framerate < 0.5) - pev->framerate = 0; - -} - - - -void CGrenade::SlideTouch( CBaseEntity *pOther ) -{ - // don't hit the guy that launched this grenade - if ( pOther->edict() == pev->owner ) - return; - - // pev->avelocity = Vector (300, 300, 300); - - if (pev->flags & FL_ONGROUND) - { - // add a bit of static friction - pev->velocity = pev->velocity * 0.95; - - if (pev->velocity.x != 0 || pev->velocity.y != 0) - { - // maintain sliding sound - } - } - else - { - BounceSound(); - } -} - -void CGrenade :: BounceSound( void ) -{ - switch ( RANDOM_LONG( 0, 2 ) ) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit1.wav", 0.25, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit2.wav", 0.25, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/grenade_hit3.wav", 0.25, ATTN_NORM); break; - } -} - -void CGrenade :: TumbleThink( void ) -{ - if (!IsInWorld()) - { - UTIL_Remove( this ); - return; - } - - StudioFrameAdvance( ); - pev->nextthink = gpGlobals->time + 0.1; - - if (pev->dmgtime - 1 < gpGlobals->time) - { - CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin + pev->velocity * (pev->dmgtime - gpGlobals->time), 400, 0.1 ); - } - - if (pev->dmgtime <= gpGlobals->time) - { - SetThink( &CGrenade::Detonate ); - } - if (pev->waterlevel != 0) - { - pev->velocity = pev->velocity * 0.5; - pev->framerate = 0.2; - } -} - - -void CGrenade:: Spawn( void ) -{ - pev->movetype = MOVETYPE_BOUNCE; - pev->classname = MAKE_STRING( "grenade" ); - - pev->solid = SOLID_BBOX; - - SET_MODEL(ENT(pev), "models/grenade.mdl"); - UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0)); - - pev->dmg = 100; - m_fRegisteredSound = FALSE; -} - - -CGrenade *CGrenade::ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ) -{ - CGrenade *pGrenade = GetClassPtr( (CGrenade *)NULL ); - pGrenade->Spawn(); - // contact grenades arc lower - pGrenade->pev->gravity = 0.5;// lower gravity since grenade is aerodynamic and engine doesn't know it. - UTIL_SetOrigin( pGrenade->pev, vecStart ); - pGrenade->pev->velocity = vecVelocity; - pGrenade->pev->angles = UTIL_VecToAngles (pGrenade->pev->velocity); - pGrenade->pev->owner = ENT(pevOwner); - - // make monsters afaid of it while in the air - pGrenade->SetThink( &CGrenade::DangerSoundThink ); - pGrenade->pev->nextthink = gpGlobals->time; - - // Tumble in air - pGrenade->pev->avelocity.x = RANDOM_FLOAT ( -100, -500 ); - - // Explode on contact - pGrenade->SetTouch( &CGrenade::ExplodeTouch ); - - pGrenade->pev->dmg = gSkillData.plrDmgM203Grenade; - - return pGrenade; -} - - -CGrenade * CGrenade:: ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time ) -{ - CGrenade *pGrenade = GetClassPtr( (CGrenade *)NULL ); - pGrenade->Spawn(); - UTIL_SetOrigin( pGrenade->pev, vecStart ); - pGrenade->pev->velocity = vecVelocity; - pGrenade->pev->angles = UTIL_VecToAngles(pGrenade->pev->velocity); - pGrenade->pev->owner = ENT(pevOwner); - - pGrenade->SetTouch( &CGrenade::BounceTouch ); // Bounce if touched - - // Take one second off of the desired detonation time and set the think to PreDetonate. PreDetonate - // will insert a DANGER sound into the world sound list and delay detonation for one second so that - // the grenade explodes after the exact amount of time specified in the call to ShootTimed(). - - pGrenade->pev->dmgtime = gpGlobals->time + time; - pGrenade->SetThink( &CGrenade::TumbleThink ); - pGrenade->pev->nextthink = gpGlobals->time + 0.1; - if (time < 0.1) - { - pGrenade->pev->nextthink = gpGlobals->time; - pGrenade->pev->velocity = Vector( 0, 0, 0 ); - } - - pGrenade->pev->sequence = RANDOM_LONG( 3, 6 ); - pGrenade->pev->framerate = 1.0; - - // Tumble through the air - // pGrenade->pev->avelocity.x = -400; - - pGrenade->pev->gravity = 0.5; - pGrenade->pev->friction = 0.8; - - SET_MODEL(ENT(pGrenade->pev), "models/w_grenade.mdl"); - pGrenade->pev->dmg = 100; - - return pGrenade; -} - - -CGrenade * CGrenade :: ShootSatchelCharge( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ) -{ - CGrenade *pGrenade = GetClassPtr( (CGrenade *)NULL ); - pGrenade->pev->movetype = MOVETYPE_BOUNCE; - pGrenade->pev->classname = MAKE_STRING( "grenade" ); - - pGrenade->pev->solid = SOLID_BBOX; - - SET_MODEL(ENT(pGrenade->pev), "models/grenade.mdl"); // Change this to satchel charge model - - UTIL_SetSize(pGrenade->pev, Vector( 0, 0, 0), Vector(0, 0, 0)); - - pGrenade->pev->dmg = 200; - UTIL_SetOrigin( pGrenade->pev, vecStart ); - pGrenade->pev->velocity = vecVelocity; - pGrenade->pev->angles = g_vecZero; - pGrenade->pev->owner = ENT(pevOwner); - - // Detonate in "time" seconds - pGrenade->SetThink( &CGrenade::SUB_DoNothing ); - pGrenade->SetUse( &CGrenade::DetonateUse ); - pGrenade->SetTouch( &CGrenade::SlideTouch ); - pGrenade->pev->spawnflags = SF_DETONATE; - - pGrenade->pev->friction = 0.9; - - return pGrenade; -} - - - -void CGrenade :: UseSatchelCharges( entvars_t *pevOwner, SATCHELCODE code ) -{ - edict_t *pentFind; - edict_t *pentOwner; - - if ( !pevOwner ) - return; - - CBaseEntity *pOwner = CBaseEntity::Instance( pevOwner ); - - pentOwner = pOwner->edict(); - - pentFind = FIND_ENTITY_BY_CLASSNAME( NULL, "grenade" ); - while ( !FNullEnt( pentFind ) ) - { - CBaseEntity *pEnt = Instance( pentFind ); - if ( pEnt ) - { - if ( FBitSet( pEnt->pev->spawnflags, SF_DETONATE ) && pEnt->pev->owner == pentOwner ) - { - if ( code == SATCHEL_DETONATE ) - pEnt->Use( pOwner, pOwner, USE_ON, 0 ); - else // SATCHEL_RELEASE - pEnt->pev->owner = NULL; - } - } - pentFind = FIND_ENTITY_BY_CLASSNAME( pentFind, "grenade" ); - } -} - -//======================end grenade - diff --git a/ricochet/dlls/globals.cpp b/ricochet/dlls/globals.cpp deleted file mode 100644 index 9f6125c..0000000 --- a/ricochet/dlls/globals.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== globals.cpp ======================================================== - - DLL-wide global variable definitions. - They're all defined here, for convenient centralization. - Source files that need them should "extern ..." declare each - variable, to better document what globals they care about. - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "soundent.h" - -DLL_GLOBAL ULONG g_ulFrameCount; -DLL_GLOBAL ULONG g_ulModelIndexEyes; -DLL_GLOBAL ULONG g_ulModelIndexPlayer; -DLL_GLOBAL Vector g_vecAttackDir; -DLL_GLOBAL int g_iSkillLevel; -DLL_GLOBAL int gDisplayTitle; -DLL_GLOBAL BOOL g_fGameOver; -DLL_GLOBAL const Vector g_vecZero = Vector(0,0,0); -DLL_GLOBAL int g_Language; diff --git a/ricochet/dlls/h_ai.cpp b/ricochet/dlls/h_ai.cpp deleted file mode 100644 index d526bcf..0000000 --- a/ricochet/dlls/h_ai.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - - h_ai.cpp - halflife specific ai code - -*/ - - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" - -#define NUM_LATERAL_CHECKS 13 // how many checks are made on each side of a monster looking for lateral cover -#define NUM_LATERAL_LOS_CHECKS 6 // how many checks are made on each side of a monster looking for lateral cover - -//float flRandom = RANDOM_FLOAT(0,1); - -DLL_GLOBAL BOOL g_fDrawLines = FALSE; - -//========================================================= -// -// AI UTILITY FUNCTIONS -// -// !!!UNDONE - move CBaseMonster functions to monsters.cpp -//========================================================= - -//========================================================= -// FBoxVisible - a more accurate ( and slower ) version -// of FVisible. -// -// !!!UNDONE - make this CBaseMonster? -//========================================================= -BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize ) -{ - // don't look through water - if ((pevLooker->waterlevel != 3 && pevTarget->waterlevel == 3) - || (pevLooker->waterlevel == 3 && pevTarget->waterlevel == 0)) - return FALSE; - - TraceResult tr; - Vector vecLookerOrigin = pevLooker->origin + pevLooker->view_ofs;//look through the monster's 'eyes' - for (int i = 0; i < 5; i++) - { - Vector vecTarget = pevTarget->origin; - vecTarget.x += RANDOM_FLOAT( pevTarget->mins.x + flSize, pevTarget->maxs.x - flSize); - vecTarget.y += RANDOM_FLOAT( pevTarget->mins.y + flSize, pevTarget->maxs.y - flSize); - vecTarget.z += RANDOM_FLOAT( pevTarget->mins.z + flSize, pevTarget->maxs.z - flSize); - - UTIL_TraceLine(vecLookerOrigin, vecTarget, ignore_monsters, ignore_glass, ENT(pevLooker)/*pentIgnore*/, &tr); - - if (tr.flFraction == 1.0) - { - vecTargetOrigin = vecTarget; - return TRUE;// line of sight is valid. - } - } - return FALSE;// Line of sight is not established -} - -// -// VecCheckToss - returns the velocity at which an object should be lobbed from vecspot1 to land near vecspot2. -// returns g_vecZero if toss is not feasible. -// -Vector VecCheckToss ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj ) -{ - TraceResult tr; - Vector vecMidPoint;// halfway point between Spot1 and Spot2 - Vector vecApex;// highest point - Vector vecScale; - Vector vecGrenadeVel; - Vector vecTemp; - float flGravity = CVAR_GET_FLOAT( "sv_gravity" ) * flGravityAdj; - - if (vecSpot2.z - vecSpot1.z > 500) - { - // to high, fail - return g_vecZero; - } - - UTIL_MakeVectors (pev->angles); - - // toss a little bit to the left or right, not right down on the enemy's bean (head). - vecSpot2 = vecSpot2 + gpGlobals->v_right * ( RANDOM_FLOAT(-8,8) + RANDOM_FLOAT(-16,16) ); - vecSpot2 = vecSpot2 + gpGlobals->v_forward * ( RANDOM_FLOAT(-8,8) + RANDOM_FLOAT(-16,16) ); - - // calculate the midpoint and apex of the 'triangle' - // UNDONE: normalize any Z position differences between spot1 and spot2 so that triangle is always RIGHT - - // How much time does it take to get there? - - // get a rough idea of how high it can be thrown - vecMidPoint = vecSpot1 + (vecSpot2 - vecSpot1) * 0.5; - UTIL_TraceLine(vecMidPoint, vecMidPoint + Vector(0,0,500), ignore_monsters, ENT(pev), &tr); - vecMidPoint = tr.vecEndPos; - // (subtract 15 so the grenade doesn't hit the ceiling) - vecMidPoint.z -= 15; - - if (vecMidPoint.z < vecSpot1.z || vecMidPoint.z < vecSpot2.z) - { - // to not enough space, fail - return g_vecZero; - } - - // How high should the grenade travel to reach the apex - float distance1 = (vecMidPoint.z - vecSpot1.z); - float distance2 = (vecMidPoint.z - vecSpot2.z); - - // How long will it take for the grenade to travel this distance - float time1 = sqrt( distance1 / (0.5 * flGravity) ); - float time2 = sqrt( distance2 / (0.5 * flGravity) ); - - if (time1 < 0.1) - { - // too close - return g_vecZero; - } - - // how hard to throw sideways to get there in time. - vecGrenadeVel = (vecSpot2 - vecSpot1) / (time1 + time2); - // how hard upwards to reach the apex at the right time. - vecGrenadeVel.z = flGravity * time1; - - // find the apex - vecApex = vecSpot1 + vecGrenadeVel * time1; - vecApex.z = vecMidPoint.z; - - UTIL_TraceLine(vecSpot1, vecApex, dont_ignore_monsters, ENT(pev), &tr); - if (tr.flFraction != 1.0) - { - // fail! - return g_vecZero; - } - - // UNDONE: either ignore monsters or change it to not care if we hit our enemy - UTIL_TraceLine(vecSpot2, vecApex, ignore_monsters, ENT(pev), &tr); - if (tr.flFraction != 1.0) - { - // fail! - return g_vecZero; - } - - return vecGrenadeVel; -} - - -// -// VecCheckThrow - returns the velocity vector at which an object should be thrown from vecspot1 to hit vecspot2. -// returns g_vecZero if throw is not feasible. -// -Vector VecCheckThrow ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj ) -{ - float flGravity = CVAR_GET_FLOAT( "sv_gravity" ) * flGravityAdj; - - Vector vecGrenadeVel = (vecSpot2 - vecSpot1); - - // throw at a constant time - float time = vecGrenadeVel.Length( ) / flSpeed; - vecGrenadeVel = vecGrenadeVel * (1.0 / time); - - // adjust upward toss to compensate for gravity loss - vecGrenadeVel.z += flGravity * time * 0.5; - - Vector vecApex = vecSpot1 + (vecSpot2 - vecSpot1) * 0.5; - vecApex.z += 0.5 * flGravity * (time * 0.5) * (time * 0.5); - - TraceResult tr; - UTIL_TraceLine(vecSpot1, vecApex, dont_ignore_monsters, ENT(pev), &tr); - if (tr.flFraction != 1.0) - { - // fail! - return g_vecZero; - } - - UTIL_TraceLine(vecSpot2, vecApex, ignore_monsters, ENT(pev), &tr); - if (tr.flFraction != 1.0) - { - // fail! - return g_vecZero; - } - - return vecGrenadeVel; -} - - diff --git a/ricochet/dlls/h_battery.cpp b/ricochet/dlls/h_battery.cpp deleted file mode 100644 index 7a029ce..0000000 --- a/ricochet/dlls/h_battery.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== h_battery.cpp ======================================================== - - battery-related code - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "skill.h" -#include "gamerules.h" - -class CRecharge : public CBaseToggle -{ -public: - void Spawn( ); - void Precache( void ); - void EXPORT Off(void); - void EXPORT Recharge(void); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual int ObjectCaps( void ) { return (CBaseToggle :: ObjectCaps() | FCAP_CONTINUOUS_USE) & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - float m_flNextCharge; - int m_iReactivate ; // DeathMatch Delay until reactvated - int m_iJuice; - int m_iOn; // 0 = off, 1 = startup, 2 = going - float m_flSoundTime; -}; - -TYPEDESCRIPTION CRecharge::m_SaveData[] = -{ - DEFINE_FIELD( CRecharge, m_flNextCharge, FIELD_TIME ), - DEFINE_FIELD( CRecharge, m_iReactivate, FIELD_INTEGER), - DEFINE_FIELD( CRecharge, m_iJuice, FIELD_INTEGER), - DEFINE_FIELD( CRecharge, m_iOn, FIELD_INTEGER), - DEFINE_FIELD( CRecharge, m_flSoundTime, FIELD_TIME ), -}; - -IMPLEMENT_SAVERESTORE( CRecharge, CBaseEntity ); - -LINK_ENTITY_TO_CLASS(func_recharge, CRecharge); - - -void CRecharge::KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "style") || - FStrEq(pkvd->szKeyName, "height") || - FStrEq(pkvd->szKeyName, "value1") || - FStrEq(pkvd->szKeyName, "value2") || - FStrEq(pkvd->szKeyName, "value3")) - { - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "dmdelay")) - { - m_iReactivate = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -void CRecharge::Spawn() -{ - Precache( ); - - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - UTIL_SetOrigin(pev, pev->origin); // set size and link into world - UTIL_SetSize(pev, pev->mins, pev->maxs); - SET_MODEL(ENT(pev), STRING(pev->model) ); - m_iJuice = gSkillData.suitchargerCapacity; - pev->frame = 0; -} - -void CRecharge::Precache() -{ - PRECACHE_SOUND("items/suitcharge1.wav"); - PRECACHE_SOUND("items/suitchargeno1.wav"); - PRECACHE_SOUND("items/suitchargeok1.wav"); -} - - -void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // if it's not a player, ignore - if (!FClassnameIs(pActivator->pev, "player")) - return; - - // if there is no juice left, turn it off - if (m_iJuice <= 0) - { - pev->frame = 1; - Off(); - } - - // if the player doesn't have the suit, or there is no juice left, make the deny noise - if ((m_iJuice <= 0) || (!(pActivator->pev->weapons & (1<time) - { - m_flSoundTime = gpGlobals->time + 0.62; - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/suitchargeno1.wav", 0.85, ATTN_NORM ); - } - return; - } - - pev->nextthink = pev->ltime + 0.25; - SetThink(&CRecharge::Off); - - // Time to recharge yet? - - if (m_flNextCharge >= gpGlobals->time) - return; - - // Make sure that we have a caller - if (!pActivator) - return; - - m_hActivator = pActivator; - - //only recharge the player - - if (!m_hActivator->IsPlayer() ) - return; - - // Play the on sound or the looping charging sound - if (!m_iOn) - { - m_iOn++; - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/suitchargeok1.wav", 0.85, ATTN_NORM ); - m_flSoundTime = 0.56 + gpGlobals->time; - } - if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->time)) - { - m_iOn++; - EMIT_SOUND(ENT(pev), CHAN_STATIC, "items/suitcharge1.wav", 0.85, ATTN_NORM ); - } - - - // charge the player - if (m_hActivator->pev->armorvalue < 100) - { - m_iJuice--; - m_hActivator->pev->armorvalue += 1; - - if (m_hActivator->pev->armorvalue > 100) - m_hActivator->pev->armorvalue = 100; - } - - // govern the rate of charge - m_flNextCharge = gpGlobals->time + 0.1; -} - -void CRecharge::Recharge(void) -{ - m_iJuice = gSkillData.suitchargerCapacity; - pev->frame = 0; - SetThink( &CRecharge::SUB_DoNothing ); -} - -void CRecharge::Off(void) -{ - // Stop looping sound. - if (m_iOn > 1) - STOP_SOUND( ENT(pev), CHAN_STATIC, "items/suitcharge1.wav" ); - - m_iOn = 0; - - if ((!m_iJuice) && ( ( m_iReactivate = g_pGameRules->FlHEVChargerRechargeTime() ) > 0) ) - { - pev->nextthink = pev->ltime + m_iReactivate; - SetThink(&CRecharge::Recharge); - } - else - SetThink( &CRecharge::SUB_DoNothing ); -} diff --git a/ricochet/dlls/h_cycler.cpp b/ricochet/dlls/h_cycler.cpp deleted file mode 100644 index 6822c85..0000000 --- a/ricochet/dlls/h_cycler.cpp +++ /dev/null @@ -1,471 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== h_cycler.cpp ======================================================== - - The Halflife Cycler Monsters - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "animation.h" -#include "weapons.h" -#include "player.h" - - -#define TEMP_FOR_SCREEN_SHOTS -#ifdef TEMP_FOR_SCREEN_SHOTS //=================================================== - -class CCycler : public CBaseMonster -{ -public: - void GenericCyclerSpawn(char *szModel, Vector vecMin, Vector vecMax); - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() | FCAP_IMPULSE_USE); } - int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - void Spawn( void ); - void Think( void ); - //void Pain( float flDamage ); - void Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - // Don't treat as a live target - virtual BOOL IsAlive( void ) { return FALSE; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - int m_animate; -}; - -TYPEDESCRIPTION CCycler::m_SaveData[] = -{ - DEFINE_FIELD( CCycler, m_animate, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CCycler, CBaseMonster ); - - -// -// we should get rid of all the other cyclers and replace them with this. -// -class CGenericCycler : public CCycler -{ -public: - void Spawn( void ) { GenericCyclerSpawn( (char *)STRING(pev->model), Vector(-16, -16, 0), Vector(16, 16, 72) ); } -}; -LINK_ENTITY_TO_CLASS( cycler, CGenericCycler ); - - - -// Probe droid imported for tech demo compatibility -// -// PROBE DROID -// -class CCyclerProbe : public CCycler -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS( cycler_prdroid, CCyclerProbe ); -void CCyclerProbe :: Spawn( void ) -{ - pev->origin = pev->origin + Vector ( 0, 0, 16 ); - GenericCyclerSpawn( "models/prdroid.mdl", Vector(-16,-16,-16), Vector(16,16,16)); -} - - - -// Cycler member functions - -void CCycler :: GenericCyclerSpawn(char *szModel, Vector vecMin, Vector vecMax) -{ - if (!szModel || !*szModel) - { - ALERT(at_error, "cycler at %.0f %.0f %0.f missing modelname", pev->origin.x, pev->origin.y, pev->origin.z ); - REMOVE_ENTITY(ENT(pev)); - return; - } - - pev->classname = MAKE_STRING("cycler"); - PRECACHE_MODEL( szModel ); - SET_MODEL(ENT(pev), szModel); - - CCycler::Spawn( ); - - UTIL_SetSize(pev, vecMin, vecMax); -} - - -void CCycler :: Spawn( ) -{ - InitBoneControllers(); - pev->solid = SOLID_SLIDEBOX; - pev->movetype = MOVETYPE_NONE; - pev->takedamage = DAMAGE_YES; - pev->effects = 0; - pev->health = 80000;// no cycler should die - pev->yaw_speed = 5; - pev->ideal_yaw = pev->angles.y; - ChangeYaw( 360 ); - - m_flFrameRate = 75; - m_flGroundSpeed = 0; - - pev->nextthink += 1.0; - - ResetSequenceInfo( ); - - if (pev->sequence != 0 || pev->frame != 0) - { - m_animate = 0; - pev->framerate = 0; - } - else - { - m_animate = 1; - } -} - - - - -// -// cycler think -// -void CCycler :: Think( void ) -{ - pev->nextthink = gpGlobals->time + 0.1; - - if (m_animate) - { - StudioFrameAdvance ( ); - } - if (m_fSequenceFinished && !m_fSequenceLoops) - { - // ResetSequenceInfo(); - // hack to avoid reloading model every frame - pev->animtime = gpGlobals->time; - pev->framerate = 1.0; - m_fSequenceFinished = FALSE; - m_flLastEventCheck = gpGlobals->time; - pev->frame = 0; - if (!m_animate) - pev->framerate = 0.0; // FIX: don't reset framerate - } -} - -// -// CyclerUse - starts a rotation trend -// -void CCycler :: Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - m_animate = !m_animate; - if (m_animate) - pev->framerate = 1.0; - else - pev->framerate = 0.0; -} - -// -// CyclerPain , changes sequences when shot -// -//void CCycler :: Pain( float flDamage ) -int CCycler :: TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - if (m_animate) - { - pev->sequence++; - - ResetSequenceInfo( ); - - if (m_flFrameRate == 0.0) - { - pev->sequence = 0; - ResetSequenceInfo( ); - } - pev->frame = 0; - } - else - { - pev->framerate = 1.0; - StudioFrameAdvance ( 0.1 ); - pev->framerate = 0; - ALERT( at_console, "sequence: %d, frame %.0f\n", pev->sequence, pev->frame ); - } - - return 0; -} - -#endif - - -class CCyclerSprite : public CBaseEntity -{ -public: - void Spawn( void ); - void Think( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() | FCAP_DONT_SAVE | FCAP_IMPULSE_USE); } - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ); - void Animate( float frames ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - inline int ShouldAnimate( void ) { return m_animate && m_maxFrame > 1.0; } - int m_animate; - float m_lastTime; - float m_maxFrame; -}; - -LINK_ENTITY_TO_CLASS( cycler_sprite, CCyclerSprite ); - -TYPEDESCRIPTION CCyclerSprite::m_SaveData[] = -{ - DEFINE_FIELD( CCyclerSprite, m_animate, FIELD_INTEGER ), - DEFINE_FIELD( CCyclerSprite, m_lastTime, FIELD_TIME ), - DEFINE_FIELD( CCyclerSprite, m_maxFrame, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CCyclerSprite, CBaseEntity ); - - -void CCyclerSprite::Spawn( void ) -{ - pev->solid = SOLID_SLIDEBOX; - pev->movetype = MOVETYPE_NONE; - pev->takedamage = DAMAGE_YES; - pev->effects = 0; - - pev->frame = 0; - pev->nextthink = gpGlobals->time + 0.1; - m_animate = 1; - m_lastTime = gpGlobals->time; - - PRECACHE_MODEL( (char *)STRING(pev->model) ); - SET_MODEL( ENT(pev), STRING(pev->model) ); - - m_maxFrame = (float) MODEL_FRAMES( pev->modelindex ) - 1; -} - - -void CCyclerSprite::Think( void ) -{ - if ( ShouldAnimate() ) - Animate( pev->framerate * (gpGlobals->time - m_lastTime) ); - - pev->nextthink = gpGlobals->time + 0.1; - m_lastTime = gpGlobals->time; -} - - -void CCyclerSprite::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - m_animate = !m_animate; - ALERT( at_console, "Sprite: %s\n", STRING(pev->model) ); -} - - -int CCyclerSprite::TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType ) -{ - if ( m_maxFrame > 1.0 ) - { - Animate( 1.0 ); - } - return 1; -} - -void CCyclerSprite::Animate( float frames ) -{ - pev->frame += frames; - if ( m_maxFrame > 0 ) - pev->frame = fmod( pev->frame, m_maxFrame ); -} - - - - - - - -class CWeaponCycler : public CBasePlayerWeapon -{ -public: - void Spawn( void ); - int iItemSlot( void ) { return 1; } - int GetItemInfo(ItemInfo *p) {return 0; } - - void PrimaryAttack( void ); - void SecondaryAttack( void ); - BOOL Deploy( void ); - void Holster( int skiplocal = 0 ); - int m_iszModel; - int m_iModel; -}; -LINK_ENTITY_TO_CLASS( cycler_weapon, CWeaponCycler ); - - -void CWeaponCycler::Spawn( ) -{ - pev->solid = SOLID_SLIDEBOX; - pev->movetype = MOVETYPE_NONE; - - PRECACHE_MODEL( (char *)STRING(pev->model) ); - SET_MODEL( ENT(pev), STRING(pev->model) ); - m_iszModel = pev->model; - m_iModel = pev->modelindex; - - UTIL_SetOrigin( pev, pev->origin ); - UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16)); - SetTouch( &CWeaponCycler::DefaultTouch ); -} - - - -BOOL CWeaponCycler::Deploy( ) -{ - m_pPlayer->pev->viewmodel = m_iszModel; - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 1.0; - SendWeaponAnim( 0 ); - m_iClip = 0; - return TRUE; -} - - -void CWeaponCycler::Holster( int skiplocal /* = 0 */ ) -{ - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5; -} - - -void CWeaponCycler::PrimaryAttack() -{ - - SendWeaponAnim( pev->sequence ); - - m_flNextPrimaryAttack = gpGlobals->time + 0.3; -} - - -void CWeaponCycler::SecondaryAttack( void ) -{ - float flFrameRate, flGroundSpeed; - - pev->sequence = (pev->sequence + 1) % 8; - - pev->modelindex = m_iModel; - void *pmodel = GET_MODEL_PTR( ENT(pev) ); - GetSequenceInfo( pmodel, pev, &flFrameRate, &flGroundSpeed ); - pev->modelindex = 0; - - if (flFrameRate == 0.0) - { - pev->sequence = 0; - } - - SendWeaponAnim( pev->sequence ); - - m_flNextSecondaryAttack = gpGlobals->time + 0.3; -} - - - -// Flaming Wreakage -class CWreckage : public CBaseMonster -{ - int Save( CSave &save ); - int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - void Spawn( void ); - void Precache( void ); - void Think( void ); - - int m_flStartTime; -}; -TYPEDESCRIPTION CWreckage::m_SaveData[] = -{ - DEFINE_FIELD( CWreckage, m_flStartTime, FIELD_TIME ), -}; -IMPLEMENT_SAVERESTORE( CWreckage, CBaseMonster ); - - -LINK_ENTITY_TO_CLASS( cycler_wreckage, CWreckage ); - -void CWreckage::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->takedamage = 0; - pev->effects = 0; - - pev->frame = 0; - pev->nextthink = gpGlobals->time + 0.1; - - if (pev->model) - { - PRECACHE_MODEL( (char *)STRING(pev->model) ); - SET_MODEL( ENT(pev), STRING(pev->model) ); - } - // pev->scale = 5.0; - - m_flStartTime = gpGlobals->time; -} - -void CWreckage::Precache( ) -{ - if ( pev->model ) - PRECACHE_MODEL( (char *)STRING(pev->model) ); -} - -void CWreckage::Think( void ) -{ - StudioFrameAdvance( ); - pev->nextthink = gpGlobals->time + 0.2; - - if (pev->dmgtime) - { - if (pev->dmgtime < gpGlobals->time) - { - UTIL_Remove( this ); - return; - } - else if (RANDOM_FLOAT( 0, pev->dmgtime - m_flStartTime ) > pev->dmgtime - gpGlobals->time) - { - return; - } - } - - Vector VecSrc; - - VecSrc.x = RANDOM_FLOAT( pev->absmin.x, pev->absmax.x ); - VecSrc.y = RANDOM_FLOAT( pev->absmin.y, pev->absmax.y ); - VecSrc.z = RANDOM_FLOAT( pev->absmin.z, pev->absmax.z ); - - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, VecSrc ); - WRITE_BYTE( TE_SMOKE ); - WRITE_COORD( VecSrc.x ); - WRITE_COORD( VecSrc.y ); - WRITE_COORD( VecSrc.z ); - WRITE_SHORT( g_sModelIndexSmoke ); - WRITE_BYTE( RANDOM_LONG(0,49) + 50 ); // scale * 10 - WRITE_BYTE( RANDOM_LONG(0, 3) + 8 ); // framerate - MESSAGE_END(); -} diff --git a/ricochet/dlls/h_export.cpp b/ricochet/dlls/h_export.cpp deleted file mode 100644 index 480bccd..0000000 --- a/ricochet/dlls/h_export.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== h_export.cpp ======================================================== - - Entity classes exported by Halflife. - -*/ - -#include "extdll.h" -#include "util.h" - -#include "cbase.h" - -// Holds engine functionality callbacks -enginefuncs_t g_engfuncs; -globalvars_t *gpGlobals; - -#undef DLLEXPORT -#ifdef _WIN32 -#define DLLEXPORT __stdcall -#else -#define DLLEXPORT __attribute__ ((visibility("default"))) -#endif - -#ifdef _WIN32 - -// Required DLL entry point -BOOL WINAPI DllMain( - HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) -{ - if (fdwReason == DLL_PROCESS_ATTACH) - { - } - else if (fdwReason == DLL_PROCESS_DETACH) - { - } - return TRUE; -} -#endif - -extern "C" void DLLEXPORT GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) -{ - memcpy(&g_engfuncs, pengfuncsFromEngine, sizeof(enginefuncs_t)); - gpGlobals = pGlobals; -} diff --git a/ricochet/dlls/healthkit.cpp b/ricochet/dlls/healthkit.cpp deleted file mode 100644 index 68ec4ef..0000000 --- a/ricochet/dlls/healthkit.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "weapons.h" -#include "nodes.h" -#include "player.h" -#include "items.h" -#include "gamerules.h" - -extern int gmsgItemPickup; - -class CHealthKit : public CItem -{ - void Spawn( void ); - void Precache( void ); - BOOL MyTouch( CBasePlayer *pPlayer ); - -/* - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; -*/ - -}; - - -LINK_ENTITY_TO_CLASS( item_healthkit, CHealthKit ); - -/* -TYPEDESCRIPTION CHealthKit::m_SaveData[] = -{ - -}; - - -IMPLEMENT_SAVERESTORE( CHealthKit, CItem); -*/ - -void CHealthKit :: Spawn( void ) -{ - Precache( ); - SET_MODEL(ENT(pev), "models/w_medkit.mdl"); - - CItem::Spawn(); -} - -void CHealthKit::Precache( void ) -{ - PRECACHE_MODEL("models/w_medkit.mdl"); - PRECACHE_SOUND("items/smallmedkit1.wav"); -} - -BOOL CHealthKit::MyTouch( CBasePlayer *pPlayer ) -{ - if ( pPlayer->TakeHealth( gSkillData.healthkitCapacity, DMG_GENERIC ) ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); - WRITE_STRING( STRING(pev->classname) ); - MESSAGE_END(); - - EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/smallmedkit1.wav", 1, ATTN_NORM); - - if ( g_pGameRules->ItemShouldRespawn( this ) ) - { - Respawn(); - } - else - { - UTIL_Remove(this); - } - - return TRUE; - } - - return FALSE; -} - - - -//------------------------------------------------------------- -// Wall mounted health kit -//------------------------------------------------------------- -class CWallHealth : public CBaseToggle -{ -public: - void Spawn( ); - void Precache( void ); - void EXPORT Off(void); - void EXPORT Recharge(void); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual int ObjectCaps( void ) { return (CBaseToggle :: ObjectCaps() | FCAP_CONTINUOUS_USE) & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - float m_flNextCharge; - int m_iReactivate ; // DeathMatch Delay until reactvated - int m_iJuice; - int m_iOn; // 0 = off, 1 = startup, 2 = going - float m_flSoundTime; -}; - -TYPEDESCRIPTION CWallHealth::m_SaveData[] = -{ - DEFINE_FIELD( CWallHealth, m_flNextCharge, FIELD_TIME), - DEFINE_FIELD( CWallHealth, m_iReactivate, FIELD_INTEGER), - DEFINE_FIELD( CWallHealth, m_iJuice, FIELD_INTEGER), - DEFINE_FIELD( CWallHealth, m_iOn, FIELD_INTEGER), - DEFINE_FIELD( CWallHealth, m_flSoundTime, FIELD_TIME), -}; - -IMPLEMENT_SAVERESTORE( CWallHealth, CBaseEntity ); - -LINK_ENTITY_TO_CLASS(func_healthcharger, CWallHealth); - - -void CWallHealth::KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "style") || - FStrEq(pkvd->szKeyName, "height") || - FStrEq(pkvd->szKeyName, "value1") || - FStrEq(pkvd->szKeyName, "value2") || - FStrEq(pkvd->szKeyName, "value3")) - { - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "dmdelay")) - { - m_iReactivate = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -void CWallHealth::Spawn() -{ - Precache( ); - - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - UTIL_SetOrigin(pev, pev->origin); // set size and link into world - UTIL_SetSize(pev, pev->mins, pev->maxs); - SET_MODEL(ENT(pev), STRING(pev->model) ); - m_iJuice = gSkillData.healthchargerCapacity; - pev->frame = 0; - -} - -void CWallHealth::Precache() -{ - PRECACHE_SOUND("items/medshot4.wav"); - PRECACHE_SOUND("items/medshotno1.wav"); - PRECACHE_SOUND("items/medcharge4.wav"); -} - - -void CWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // Make sure that we have a caller - if (!pActivator) - return; - // if it's not a player, ignore - if ( !pActivator->IsPlayer() ) - return; - - // if there is no juice left, turn it off - if (m_iJuice <= 0) - { - pev->frame = 1; - Off(); - } - - // if the player doesn't have the suit, or there is no juice left, make the deny noise - if ((m_iJuice <= 0) || (!(pActivator->pev->weapons & (1<time) - { - m_flSoundTime = gpGlobals->time + 0.62; - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshotno1.wav", 1.0, ATTN_NORM ); - } - return; - } - - pev->nextthink = pev->ltime + 0.25; - SetThink(&CWallHealth::Off); - - // Time to recharge yet? - - if (m_flNextCharge >= gpGlobals->time) - return; - - // Play the on sound or the looping charging sound - if (!m_iOn) - { - m_iOn++; - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", 1.0, ATTN_NORM ); - m_flSoundTime = 0.56 + gpGlobals->time; - } - if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->time)) - { - m_iOn++; - EMIT_SOUND(ENT(pev), CHAN_STATIC, "items/medcharge4.wav", 1.0, ATTN_NORM ); - } - - - // charge the player - if ( pActivator->TakeHealth( 1, DMG_GENERIC ) ) - { - m_iJuice--; - } - - // govern the rate of charge - m_flNextCharge = gpGlobals->time + 0.1; -} - -void CWallHealth::Recharge(void) -{ - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", 1.0, ATTN_NORM ); - m_iJuice = gSkillData.healthchargerCapacity; - pev->frame = 0; - SetThink( &CWallHealth::SUB_DoNothing ); -} - -void CWallHealth::Off(void) -{ - // Stop looping sound. - if (m_iOn > 1) - STOP_SOUND( ENT(pev), CHAN_STATIC, "items/medcharge4.wav" ); - - m_iOn = 0; - - if ((!m_iJuice) && ( ( m_iReactivate = g_pGameRules->FlHealthChargerRechargeTime() ) > 0) ) - { - pev->nextthink = pev->ltime + m_iReactivate; - SetThink(&CWallHealth::Recharge); - } - else - SetThink( &CWallHealth::SUB_DoNothing ); -} diff --git a/ricochet/dlls/items.cpp b/ricochet/dlls/items.cpp deleted file mode 100644 index 9ff9105..0000000 --- a/ricochet/dlls/items.cpp +++ /dev/null @@ -1,337 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== items.cpp ======================================================== - - functions governing the selection/use of weapons for players - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "weapons.h" -#include "player.h" -#include "skill.h" -#include "items.h" -#include "gamerules.h" - -extern int gmsgItemPickup; - -class CWorldItem : public CBaseEntity -{ -public: - void KeyValue(KeyValueData *pkvd ); - void Spawn( void ); - int m_iType; -}; - -LINK_ENTITY_TO_CLASS(world_items, CWorldItem); - -void CWorldItem::KeyValue(KeyValueData *pkvd) -{ - if (FStrEq(pkvd->szKeyName, "type")) - { - m_iType = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -void CWorldItem::Spawn( void ) -{ - CBaseEntity *pEntity = NULL; - - switch (m_iType) - { - case 44: // ITEM_BATTERY: - pEntity = CBaseEntity::Create( "item_battery", pev->origin, pev->angles ); - break; - case 42: // ITEM_ANTIDOTE: - pEntity = CBaseEntity::Create( "item_antidote", pev->origin, pev->angles ); - break; - case 43: // ITEM_SECURITY: - pEntity = CBaseEntity::Create( "item_security", pev->origin, pev->angles ); - break; - case 45: // ITEM_SUIT: - pEntity = CBaseEntity::Create( "item_suit", pev->origin, pev->angles ); - break; - } - - if (!pEntity) - { - ALERT( at_console, "unable to create world_item %d\n", m_iType ); - } - else - { - pEntity->pev->target = pev->target; - pEntity->pev->targetname = pev->targetname; - pEntity->pev->spawnflags = pev->spawnflags; - } - - REMOVE_ENTITY(edict()); -} - - -void CItem::Spawn( void ) -{ - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - UTIL_SetOrigin( pev, pev->origin ); - UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16)); - SetTouch(&CItem::ItemTouch); - - 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; - } -} - -extern int gEvilImpulse101; - -void CItem::ItemTouch( CBaseEntity *pOther ) -{ - // if it's not a player, ignore - if ( !pOther->IsPlayer() ) - { - return; - } - - CBasePlayer *pPlayer = (CBasePlayer *)pOther; - - // ok, a player is touching this item, but can he have it? - if ( !g_pGameRules->CanHaveItem( pPlayer, this ) ) - { - // no? Ignore the touch. - return; - } - - if (MyTouch( pPlayer )) - { - SUB_UseTargets( pOther, USE_TOGGLE, 0 ); - SetTouch( NULL ); - - // player grabbed the item. - g_pGameRules->PlayerGotItem( pPlayer, this ); - if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES ) - { - Respawn(); - } - else - { - UTIL_Remove( this ); - } - } - else if (gEvilImpulse101) - { - UTIL_Remove( this ); - } -} - -CBaseEntity* CItem::Respawn( void ) -{ - SetTouch( NULL ); - pev->effects |= EF_NODRAW; - - UTIL_SetOrigin( pev, g_pGameRules->VecItemRespawnSpot( this ) );// blip to whereever you should respawn. - - SetThink ( &CItem::Materialize ); - pev->nextthink = g_pGameRules->FlItemRespawnTime( this ); - return this; -} - -void CItem::Materialize( void ) -{ - if ( pev->effects & EF_NODRAW ) - { - // 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( &CItem::ItemTouch ); -} - -#define SF_SUIT_SHORTLOGON 0x0001 - -class CItemSuit : public CItem -{ - void Spawn( void ) - { - Precache( ); - SET_MODEL(ENT(pev), "models/w_suit.mdl"); - CItem::Spawn( ); - } - void Precache( void ) - { - PRECACHE_MODEL ("models/w_suit.mdl"); - } - BOOL MyTouch( CBasePlayer *pPlayer ) - { - if ( pPlayer->pev->weapons & (1<spawnflags & SF_SUIT_SHORTLOGON ) - EMIT_SOUND_SUIT(pPlayer->edict(), "!HEV_A0"); // short version of suit logon, - else - EMIT_SOUND_SUIT(pPlayer->edict(), "!HEV_AAx"); // long version of suit logon - - pPlayer->pev->weapons |= (1<pev->armorvalue < MAX_NORMAL_BATTERY) && - (pPlayer->pev->weapons & (1<pev->armorvalue += gSkillData.batteryCapacity; - pPlayer->pev->armorvalue = V_min(pPlayer->pev->armorvalue, MAX_NORMAL_BATTERY); - - EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); - - MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); - WRITE_STRING( STRING(pev->classname) ); - MESSAGE_END(); - - - // Suit reports new power level - // For some reason this wasn't working in release build -- round it. - pct = (int)( (float)(pPlayer->pev->armorvalue * 100.0) * (1.0/MAX_NORMAL_BATTERY) + 0.5); - pct = (pct / 5); - if (pct > 0) - pct--; - - sprintf( szcharge,"!HEV_%1dP", pct ); - - //EMIT_SOUND_SUIT(ENT(pev), szcharge); - pPlayer->SetSuitUpdate(szcharge, FALSE, SUIT_NEXT_IN_30SEC); - return TRUE; - } - return FALSE; - } -}; - -LINK_ENTITY_TO_CLASS(item_battery, CItemBattery); - - -class CItemAntidote : public CItem -{ - void Spawn( void ) - { - Precache( ); - SET_MODEL(ENT(pev), "models/w_antidote.mdl"); - CItem::Spawn( ); - } - void Precache( void ) - { - PRECACHE_MODEL ("models/w_antidote.mdl"); - } - BOOL MyTouch( CBasePlayer *pPlayer ) - { - pPlayer->SetSuitUpdate("!HEV_DET4", FALSE, SUIT_NEXT_IN_1MIN); - - pPlayer->m_rgItems[ITEM_ANTIDOTE] += 1; - return TRUE; - } -}; - -LINK_ENTITY_TO_CLASS(item_antidote, CItemAntidote); - - -class CItemSecurity : public CItem -{ - void Spawn( void ) - { - Precache( ); - SET_MODEL(ENT(pev), "models/w_security.mdl"); - CItem::Spawn( ); - } - void Precache( void ) - { - PRECACHE_MODEL ("models/w_security.mdl"); - } - BOOL MyTouch( CBasePlayer *pPlayer ) - { - pPlayer->m_rgItems[ITEM_SECURITY] += 1; - return TRUE; - } -}; - -LINK_ENTITY_TO_CLASS(item_security, CItemSecurity); - -class CItemLongJump : public CItem -{ - void Spawn( void ) - { - Precache( ); - SET_MODEL(ENT(pev), "models/w_longjump.mdl"); - CItem::Spawn( ); - } - void Precache( void ) - { - PRECACHE_MODEL ("models/w_longjump.mdl"); - } - BOOL MyTouch( CBasePlayer *pPlayer ) - { - if ( pPlayer->m_fLongJump ) - { - return FALSE; - } - - if ( ( pPlayer->pev->weapons & (1<m_fLongJump = TRUE;// player now has longjump module - - g_engfuncs.pfnSetPhysicsKeyValue( pPlayer->edict(), "slj", "1" ); - - MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); - WRITE_STRING( STRING(pev->classname) ); - MESSAGE_END(); - - EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A1" ); // Play the longjump sound UNDONE: Kelly? correct sound? - return TRUE; - } - return FALSE; - } -}; - -LINK_ENTITY_TO_CLASS( item_longjump, CItemLongJump ); diff --git a/ricochet/dlls/items.h b/ricochet/dlls/items.h deleted file mode 100644 index 3fbb370..0000000 --- a/ricochet/dlls/items.h +++ /dev/null @@ -1,29 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef ITEMS_H -#define ITEMS_H - - -class CItem : public CBaseEntity -{ -public: - void Spawn( void ); - CBaseEntity* Respawn( void ); - void EXPORT ItemTouch( CBaseEntity *pOther ); - void EXPORT Materialize( void ); - virtual BOOL MyTouch( CBasePlayer *pPlayer ) { return FALSE; }; -}; - -#endif // ITEMS_H diff --git a/ricochet/dlls/lights.cpp b/ricochet/dlls/lights.cpp deleted file mode 100644 index d49e181..0000000 --- a/ricochet/dlls/lights.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== lights.cpp ======================================================== - - spawn and think functions for editor-placed lights - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" - - - -class CLight : public CPointEntity -{ -public: - virtual void KeyValue( KeyValueData* pkvd ); - virtual void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - int m_iStyle; - int m_iszPattern; -}; -LINK_ENTITY_TO_CLASS( light, CLight ); - -TYPEDESCRIPTION CLight::m_SaveData[] = -{ - DEFINE_FIELD( CLight, m_iStyle, FIELD_INTEGER ), - DEFINE_FIELD( CLight, m_iszPattern, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CLight, CPointEntity ); - - -// -// Cache user-entity-field values until spawn is called. -// -void CLight :: KeyValue( KeyValueData* pkvd) -{ - if (FStrEq(pkvd->szKeyName, "style")) - { - m_iStyle = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pitch")) - { - pev->angles.x = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pattern")) - { - m_iszPattern = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - { - CPointEntity::KeyValue( pkvd ); - } -} - -/*QUAKED light (0 1 0) (-8 -8 -8) (8 8 8) LIGHT_START_OFF -Non-displayed light. -Default light value is 300 -Default style is 0 -If targeted, it will toggle between on or off. -*/ - -void CLight :: Spawn( void ) -{ - if (FStringNull(pev->targetname)) - { // inert light - REMOVE_ENTITY(ENT(pev)); - return; - } - - if (m_iStyle >= 32) - { -// CHANGE_METHOD(ENT(pev), em_use, light_use); - if (FBitSet(pev->spawnflags, SF_LIGHT_START_OFF)) - LIGHT_STYLE(m_iStyle, "a"); - else if (m_iszPattern) - LIGHT_STYLE(m_iStyle, (char *)STRING( m_iszPattern )); - else - LIGHT_STYLE(m_iStyle, "m"); - } -} - - -void CLight :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if (m_iStyle >= 32) - { - if ( !ShouldToggle( useType, !FBitSet(pev->spawnflags, SF_LIGHT_START_OFF) ) ) - return; - - if (FBitSet(pev->spawnflags, SF_LIGHT_START_OFF)) - { - if (m_iszPattern) - LIGHT_STYLE(m_iStyle, (char *)STRING( m_iszPattern )); - else - LIGHT_STYLE(m_iStyle, "m"); - ClearBits(pev->spawnflags, SF_LIGHT_START_OFF); - } - else - { - LIGHT_STYLE(m_iStyle, "a"); - SetBits(pev->spawnflags, SF_LIGHT_START_OFF); - } - } -} - -// -// shut up spawn functions for new spotlights -// -LINK_ENTITY_TO_CLASS( light_spot, CLight ); - - -class CEnvLight : public CLight -{ -public: - void KeyValue( KeyValueData* pkvd ); - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( light_environment, CEnvLight ); - -void CEnvLight::KeyValue( KeyValueData* pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "_light")) - { - int r, g, b, v, j; - char szColor[64]; - j = sscanf( pkvd->szValue, "%d %d %d %d\n", &r, &g, &b, &v ); - if (j == 1) - { - g = b = r; - } - else if (j == 4) - { - r = r * (v / 255.0); - g = g * (v / 255.0); - b = b * (v / 255.0); - } - - // simulate qrad direct, ambient,and gamma adjustments, as well as engine scaling - r = pow( r / 114.0, 0.6 ) * 264; - g = pow( g / 114.0, 0.6 ) * 264; - b = pow( b / 114.0, 0.6 ) * 264; - - pkvd->fHandled = TRUE; - sprintf( szColor, "%d", r ); - CVAR_SET_STRING( "sv_skycolor_r", szColor ); - sprintf( szColor, "%d", g ); - CVAR_SET_STRING( "sv_skycolor_g", szColor ); - sprintf( szColor, "%d", b ); - CVAR_SET_STRING( "sv_skycolor_b", szColor ); - } - else - { - CLight::KeyValue( pkvd ); - } -} - - -void CEnvLight :: Spawn( void ) -{ - char szVector[64]; - UTIL_MakeAimVectors( pev->angles ); - - sprintf( szVector, "%f", gpGlobals->v_forward.x ); - CVAR_SET_STRING( "sv_skyvec_x", szVector ); - sprintf( szVector, "%f", gpGlobals->v_forward.y ); - CVAR_SET_STRING( "sv_skyvec_y", szVector ); - sprintf( szVector, "%f", gpGlobals->v_forward.z ); - CVAR_SET_STRING( "sv_skyvec_z", szVector ); - - CLight::Spawn( ); -} diff --git a/ricochet/dlls/maprules.cpp b/ricochet/dlls/maprules.cpp deleted file mode 100644 index 6d01faa..0000000 --- a/ricochet/dlls/maprules.cpp +++ /dev/null @@ -1,918 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ - -// ------------------------------------------- -// -// maprules.cpp -// -// This module contains entities for implementing/changing game -// rules dynamically within each map (.BSP) -// -// ------------------------------------------- - -#include "extdll.h" -#include "eiface.h" -#include "util.h" -#include "gamerules.h" -#include "maprules.h" -#include "cbase.h" -#include "player.h" - -class CRuleEntity : public CBaseEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - void SetMaster( int iszMaster ) { m_iszMaster = iszMaster; } - -protected: - BOOL CanFireForActivator( CBaseEntity *pActivator ); - -private: - string_t m_iszMaster; -}; - -TYPEDESCRIPTION CRuleEntity::m_SaveData[] = -{ - DEFINE_FIELD( CRuleEntity, m_iszMaster, FIELD_STRING), -}; - -IMPLEMENT_SAVERESTORE( CRuleEntity, CBaseEntity ); - - -void CRuleEntity::Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->effects = EF_NODRAW; -} - - -void CRuleEntity::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "master")) - { - SetMaster( ALLOC_STRING(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -BOOL CRuleEntity::CanFireForActivator( CBaseEntity *pActivator ) -{ - if ( m_iszMaster ) - { - if ( UTIL_IsMasterTriggered( m_iszMaster, pActivator ) ) - return TRUE; - else - return FALSE; - } - - return TRUE; -} - -// -// CRulePointEntity -- base class for all rule "point" entities (not brushes) -// -class CRulePointEntity : public CRuleEntity -{ -public: - void Spawn( void ); -}; - -void CRulePointEntity::Spawn( void ) -{ - CRuleEntity::Spawn(); - pev->frame = 0; - pev->model = 0; -} - -// -// CRuleBrushEntity -- base class for all rule "brush" entities (not brushes) -// Default behavior is to set up like a trigger, invisible, but keep the model for volume testing -// -class CRuleBrushEntity : public CRuleEntity -{ -public: - void Spawn( void ); - -private: -}; - -void CRuleBrushEntity::Spawn( void ) -{ - SET_MODEL( edict(), STRING(pev->model) ); - CRuleEntity::Spawn(); -} - - -// CGameScore / game_score -- award points to player / team -// Points +/- total -// Flag: Allow negative scores SF_SCORE_NEGATIVE -// Flag: Award points to team in teamplay SF_SCORE_TEAM - -#define SF_SCORE_NEGATIVE 0x0001 -#define SF_SCORE_TEAM 0x0002 - -class CGameScore : public CRulePointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - inline int Points( void ) { return pev->frags; } - inline BOOL AllowNegativeScore( void ) { return pev->spawnflags & SF_SCORE_NEGATIVE; } - inline BOOL AwardToTeam( void ) { return pev->spawnflags & SF_SCORE_TEAM; } - - inline void SetPoints( int points ) { pev->frags = points; } - -private: -}; - -LINK_ENTITY_TO_CLASS( game_score, CGameScore ); - - -void CGameScore::Spawn( void ) -{ - CRulePointEntity::Spawn(); -} - - -void CGameScore::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "points")) - { - SetPoints( atoi(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CRulePointEntity::KeyValue( pkvd ); -} - - - -void CGameScore::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - // Only players can use this - if ( pActivator->IsPlayer() ) - { - if ( AwardToTeam() ) - { - pActivator->AddPointsToTeam( Points(), AllowNegativeScore() ); - } - else - { - pActivator->AddPoints( Points(), AllowNegativeScore() ); - } - } -} - - -// CGameEnd / game_end -- Ends the game in MP - -class CGameEnd : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); -private: -}; - -LINK_ENTITY_TO_CLASS( game_end, CGameEnd ); - - -void CGameEnd::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - g_pGameRules->EndMultiplayerGame(); -} - - -// -// CGameText / game_text -- NON-Localized HUD Message (use env_message to display a titles.txt message) -// Flag: All players SF_ENVTEXT_ALLPLAYERS -// - - -#define SF_ENVTEXT_ALLPLAYERS 0x0001 - - -class CGameText : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - inline BOOL MessageToAll( void ) { return (pev->spawnflags & SF_ENVTEXT_ALLPLAYERS); } - inline void MessageSet( const char *pMessage ) { pev->message = ALLOC_STRING(pMessage); } - inline const char *MessageGet( void ) { return STRING(pev->message); } - -private: - - hudtextparms_t m_textParms; -}; - -LINK_ENTITY_TO_CLASS( game_text, CGameText ); - -// Save parms as a block. Will break save/restore if the structure changes, but this entity didn't ship with Half-Life, so -// it can't impact saved Half-Life games. -TYPEDESCRIPTION CGameText::m_SaveData[] = -{ - DEFINE_ARRAY( CGameText, m_textParms, FIELD_CHARACTER, sizeof(hudtextparms_t) ), -}; - -IMPLEMENT_SAVERESTORE( CGameText, CRulePointEntity ); - - -void CGameText::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "channel")) - { - m_textParms.channel = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "x")) - { - m_textParms.x = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "y")) - { - m_textParms.y = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "effect")) - { - m_textParms.effect = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "color")) - { - int color[4]; - UTIL_StringToIntArray( color, 4, pkvd->szValue ); - m_textParms.r1 = color[0]; - m_textParms.g1 = color[1]; - m_textParms.b1 = color[2]; - m_textParms.a1 = color[3]; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "color2")) - { - int color[4]; - UTIL_StringToIntArray( color, 4, pkvd->szValue ); - m_textParms.r2 = color[0]; - m_textParms.g2 = color[1]; - m_textParms.b2 = color[2]; - m_textParms.a2 = color[3]; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "fadein")) - { - m_textParms.fadeinTime = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "fadeout")) - { - m_textParms.fadeoutTime = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "holdtime")) - { - m_textParms.holdTime = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "fxtime")) - { - m_textParms.fxTime = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CRulePointEntity::KeyValue( pkvd ); -} - - -void CGameText::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( MessageToAll() ) - { - UTIL_HudMessageAll( m_textParms, MessageGet() ); - } - else - { - if ( pActivator->IsNetClient() ) - { - UTIL_HudMessage( pActivator, m_textParms, MessageGet() ); - } - } -} - - -// -// CGameTeamMaster / game_team_master -- "Masters" like multisource, but based on the team of the activator -// Only allows mastered entity to fire if the team matches my team -// -// team index (pulled from server team list "mp_teamlist" -// Flag: Remove on Fire -// Flag: Any team until set? -- Any team can use this until the team is set (otherwise no teams can use it) -// - -#define SF_TEAMMASTER_FIREONCE 0x0001 -#define SF_TEAMMASTER_ANYTEAM 0x0002 - -class CGameTeamMaster : public CRulePointEntity -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - int ObjectCaps( void ) { return CRulePointEntity:: ObjectCaps() | FCAP_MASTER; } - - BOOL IsTriggered( CBaseEntity *pActivator ); - const char *TeamID( void ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_TEAMMASTER_FIREONCE) ? TRUE : FALSE; } - inline BOOL AnyTeam( void ) { return (pev->spawnflags & SF_TEAMMASTER_ANYTEAM) ? TRUE : FALSE; } - -private: - BOOL TeamMatch( CBaseEntity *pActivator ); - - int m_teamIndex; - USE_TYPE triggerType; -}; - -LINK_ENTITY_TO_CLASS( game_team_master, CGameTeamMaster ); - -void CGameTeamMaster::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "teamindex")) - { - m_teamIndex = atoi( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "triggerstate")) - { - int type = atoi( pkvd->szValue ); - switch( type ) - { - case 0: - triggerType = USE_OFF; - break; - case 2: - triggerType = USE_TOGGLE; - break; - default: - triggerType = USE_ON; - break; - } - pkvd->fHandled = TRUE; - } - else - CRulePointEntity::KeyValue( pkvd ); -} - - -void CGameTeamMaster::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( useType == USE_SET ) - { - if ( value < 0 ) - { - m_teamIndex = -1; - } - else - { - m_teamIndex = g_pGameRules->GetTeamIndex( pActivator->TeamID() ); - } - return; - } - - if ( TeamMatch( pActivator ) ) - { - SUB_UseTargets( pActivator, triggerType, value ); - if ( RemoveOnFire() ) - UTIL_Remove( this ); - } -} - - -BOOL CGameTeamMaster::IsTriggered( CBaseEntity *pActivator ) -{ - return TeamMatch( pActivator ); -} - - -const char *CGameTeamMaster::TeamID( void ) -{ - if ( m_teamIndex < 0 ) // Currently set to "no team" - return ""; - - return g_pGameRules->GetIndexedTeamName( m_teamIndex ); // UNDONE: Fill this in with the team from the "teamlist" -} - - -BOOL CGameTeamMaster::TeamMatch( CBaseEntity *pActivator ) -{ - if ( m_teamIndex < 0 && AnyTeam() ) - return TRUE; - - if ( !pActivator ) - return FALSE; - - return UTIL_TeamsMatch( pActivator->TeamID(), TeamID() ); -} - - -// -// CGameTeamSet / game_team_set -- Changes the team of the entity it targets to the activator's team -// Flag: Fire once -// Flag: Clear team -- Sets the team to "NONE" instead of activator - -#define SF_TEAMSET_FIREONCE 0x0001 -#define SF_TEAMSET_CLEARTEAM 0x0002 - -class CGameTeamSet : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_TEAMSET_FIREONCE) ? TRUE : FALSE; } - inline BOOL ShouldClearTeam( void ) { return (pev->spawnflags & SF_TEAMSET_CLEARTEAM) ? TRUE : FALSE; } - -private: -}; - -LINK_ENTITY_TO_CLASS( game_team_set, CGameTeamSet ); - - -void CGameTeamSet::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( ShouldClearTeam() ) - { - SUB_UseTargets( pActivator, USE_SET, -1 ); - } - else - { - SUB_UseTargets( pActivator, USE_SET, 0 ); - } - - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } -} - - -// -// CGamePlayerZone / game_player_zone -- players in the zone fire my target when I'm fired -// -// Needs master? -class CGamePlayerZone : public CRuleBrushEntity -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - -private: - string_t m_iszInTarget; - string_t m_iszOutTarget; - string_t m_iszInCount; - string_t m_iszOutCount; -}; - -LINK_ENTITY_TO_CLASS( game_zone_player, CGamePlayerZone ); -TYPEDESCRIPTION CGamePlayerZone::m_SaveData[] = -{ - DEFINE_FIELD( CGamePlayerZone, m_iszInTarget, FIELD_STRING ), - DEFINE_FIELD( CGamePlayerZone, m_iszOutTarget, FIELD_STRING ), - DEFINE_FIELD( CGamePlayerZone, m_iszInCount, FIELD_STRING ), - DEFINE_FIELD( CGamePlayerZone, m_iszOutCount, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CGamePlayerZone, CRuleBrushEntity ); - -void CGamePlayerZone::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "intarget")) - { - m_iszInTarget = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "outtarget")) - { - m_iszOutTarget = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "incount")) - { - m_iszInCount = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "outcount")) - { - m_iszOutCount = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CRuleBrushEntity::KeyValue( pkvd ); -} - -void CGamePlayerZone::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int playersInCount = 0; - int playersOutCount = 0; - - if ( !CanFireForActivator( pActivator ) ) - return; - - CBaseEntity *pPlayer = NULL; - - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - pPlayer = UTIL_PlayerByIndex( i ); - if ( pPlayer ) - { - TraceResult trace; - int hullNumber; - - hullNumber = human_hull; - if ( pPlayer->pev->flags & FL_DUCKING ) - { - hullNumber = head_hull; - } - - UTIL_TraceModel( pPlayer->pev->origin, pPlayer->pev->origin, hullNumber, edict(), &trace ); - - if ( trace.fStartSolid ) - { - playersInCount++; - if ( m_iszInTarget ) - { - FireTargets( STRING(m_iszInTarget), pPlayer, pActivator, useType, value ); - } - } - else - { - playersOutCount++; - if ( m_iszOutTarget ) - { - FireTargets( STRING(m_iszOutTarget), pPlayer, pActivator, useType, value ); - } - } - } - } - - if ( m_iszInCount ) - { - FireTargets( STRING(m_iszInCount), pActivator, this, USE_SET, playersInCount ); - } - - if ( m_iszOutCount ) - { - FireTargets( STRING(m_iszOutCount), pActivator, this, USE_SET, playersOutCount ); - } -} - - - -// -// CGamePlayerHurt / game_player_hurt -- Damages the player who fires it -// Flag: Fire once - -#define SF_PKILL_FIREONCE 0x0001 -class CGamePlayerHurt : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_PKILL_FIREONCE) ? TRUE : FALSE; } - -private: -}; - -LINK_ENTITY_TO_CLASS( game_player_hurt, CGamePlayerHurt ); - - -void CGamePlayerHurt::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( pActivator->IsPlayer() ) - { - if ( pev->dmg < 0 ) - pActivator->TakeHealth( -pev->dmg, DMG_GENERIC ); - else - pActivator->TakeDamage( pev, pev, pev->dmg, DMG_GENERIC ); - } - - SUB_UseTargets( pActivator, useType, value ); - - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } -} - - - -// -// CGameCounter / game_counter -- Counts events and fires target -// Flag: Fire once -// Flag: Reset on Fire - -#define SF_GAMECOUNT_FIREONCE 0x0001 -#define SF_GAMECOUNT_RESET 0x0002 - -class CGameCounter : public CRulePointEntity -{ -public: - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_GAMECOUNT_FIREONCE) ? TRUE : FALSE; } - inline BOOL ResetOnFire( void ) { return (pev->spawnflags & SF_GAMECOUNT_RESET) ? TRUE : FALSE; } - - inline void CountUp( void ) { pev->frags++; } - inline void CountDown( void ) { pev->frags--; } - inline void ResetCount( void ) { pev->frags = pev->dmg; } - inline int CountValue( void ) { return pev->frags; } - inline int LimitValue( void ) { return pev->health; } - - inline BOOL HitLimit( void ) { return CountValue() == LimitValue(); } - -private: - - inline void SetCountValue( int value ) { pev->frags = value; } - inline void SetInitialValue( int value ) { pev->dmg = value; } -}; - -LINK_ENTITY_TO_CLASS( game_counter, CGameCounter ); - -void CGameCounter::Spawn( void ) -{ - // Save off the initial count - SetInitialValue( CountValue() ); - CRulePointEntity::Spawn(); -} - - -void CGameCounter::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - switch( useType ) - { - case USE_ON: - case USE_TOGGLE: - CountUp(); - break; - - case USE_OFF: - CountDown(); - break; - - case USE_SET: - SetCountValue( (int)value ); - break; - } - - if ( HitLimit() ) - { - SUB_UseTargets( pActivator, USE_TOGGLE, 0 ); - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } - - if ( ResetOnFire() ) - { - ResetCount(); - } - } -} - - - -// -// CGameCounterSet / game_counter_set -- Sets the counter's value -// Flag: Fire once - -#define SF_GAMECOUNTSET_FIREONCE 0x0001 - -class CGameCounterSet : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_GAMECOUNTSET_FIREONCE) ? TRUE : FALSE; } - -private: -}; - -LINK_ENTITY_TO_CLASS( game_counter_set, CGameCounterSet ); - - -void CGameCounterSet::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - SUB_UseTargets( pActivator, USE_SET, pev->frags ); - - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } -} - - -// -// CGamePlayerEquip / game_playerequip -- Sets the default player equipment -// Flag: USE Only - -#define SF_PLAYEREQUIP_USEONLY 0x0001 -#define MAX_EQUIP 32 - -class CGamePlayerEquip : public CRulePointEntity -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Touch( CBaseEntity *pOther ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - inline BOOL UseOnly( void ) { return (pev->spawnflags & SF_PLAYEREQUIP_USEONLY) ? TRUE : FALSE; } - -private: - - void EquipPlayer( CBaseEntity *pPlayer ); - - string_t m_weaponNames[MAX_EQUIP]; - int m_weaponCount[MAX_EQUIP]; -}; - -LINK_ENTITY_TO_CLASS( game_player_equip, CGamePlayerEquip ); - - -void CGamePlayerEquip::KeyValue( KeyValueData *pkvd ) -{ - CRulePointEntity::KeyValue( pkvd ); - - if ( !pkvd->fHandled ) - { - for ( int i = 0; i < MAX_EQUIP; i++ ) - { - if ( !m_weaponNames[i] ) - { - char tmp[128]; - - UTIL_StripToken( pkvd->szKeyName, tmp ); - - m_weaponNames[i] = ALLOC_STRING(tmp); - m_weaponCount[i] = atoi(pkvd->szValue); - m_weaponCount[i] = V_max(1,m_weaponCount[i]); - pkvd->fHandled = TRUE; - break; - } - } - } -} - - -void CGamePlayerEquip::Touch( CBaseEntity *pOther ) -{ - if ( !CanFireForActivator( pOther ) ) - return; - - if ( UseOnly() ) - return; - - EquipPlayer( pOther ); -} - -void CGamePlayerEquip::EquipPlayer( CBaseEntity *pEntity ) -{ - CBasePlayer *pPlayer = NULL; - - if ( pEntity->IsPlayer() ) - { - pPlayer = (CBasePlayer *)pEntity; - } - - if ( !pPlayer ) - return; - - for ( int i = 0; i < MAX_EQUIP; i++ ) - { - if ( !m_weaponNames[i] ) - break; - for ( int j = 0; j < m_weaponCount[i]; j++ ) - { - pPlayer->GiveNamedItem( STRING(m_weaponNames[i]) ); - } - } -} - - -void CGamePlayerEquip::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - EquipPlayer( pActivator ); -} - - -// -// CGamePlayerTeam / game_player_team -- Changes the team of the player who fired it -// Flag: Fire once -// Flag: Kill Player -// Flag: Gib Player - -#define SF_PTEAM_FIREONCE 0x0001 -#define SF_PTEAM_KILL 0x0002 -#define SF_PTEAM_GIB 0x0004 - -class CGamePlayerTeam : public CRulePointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -private: - - inline BOOL RemoveOnFire( void ) { return (pev->spawnflags & SF_PTEAM_FIREONCE) ? TRUE : FALSE; } - inline BOOL ShouldKillPlayer( void ) { return (pev->spawnflags & SF_PTEAM_KILL) ? TRUE : FALSE; } - inline BOOL ShouldGibPlayer( void ) { return (pev->spawnflags & SF_PTEAM_GIB) ? TRUE : FALSE; } - - const char *TargetTeamName( const char *pszTargetName ); -}; - -LINK_ENTITY_TO_CLASS( game_player_team, CGamePlayerTeam ); - - -const char *CGamePlayerTeam::TargetTeamName( const char *pszTargetName ) -{ - CBaseEntity *pTeamEntity = NULL; - - while ((pTeamEntity = UTIL_FindEntityByTargetname( pTeamEntity, pszTargetName )) != NULL) - { - if ( FClassnameIs( pTeamEntity->pev, "game_team_master" ) ) - return pTeamEntity->TeamID(); - } - - return NULL; -} - - -void CGamePlayerTeam::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !CanFireForActivator( pActivator ) ) - return; - - if ( pActivator->IsPlayer() ) - { - const char *pszTargetTeam = TargetTeamName( STRING(pev->target) ); - if ( pszTargetTeam ) - { - CBasePlayer *pPlayer = (CBasePlayer *)pActivator; - g_pGameRules->ChangePlayerTeam( pPlayer, pszTargetTeam, ShouldKillPlayer(), ShouldGibPlayer() ); - } - } - - if ( RemoveOnFire() ) - { - UTIL_Remove( this ); - } -} - - diff --git a/ricochet/dlls/maprules.h b/ricochet/dlls/maprules.h deleted file mode 100644 index 9c50dcc..0000000 --- a/ricochet/dlls/maprules.h +++ /dev/null @@ -1,22 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ - -#ifndef MAPRULES_H -#define MAPRULES_H - - - -#endif // MAPRULES_H - diff --git a/ricochet/dlls/monsterevent.h b/ricochet/dlls/monsterevent.h deleted file mode 100644 index 27bcb05..0000000 --- a/ricochet/dlls/monsterevent.h +++ /dev/null @@ -1,34 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef MONSTEREVENT_H -#define MONSTEREVENT_H - -typedef struct -{ - int event; - char *options; -} MonsterEvent_t; - -#define EVENT_SPECIFIC 0 -#define EVENT_SCRIPTED 1000 -#define EVENT_SHARED 2000 -#define EVENT_CLIENT 5000 - -#define MONSTER_EVENT_BODYDROP_LIGHT 2001 -#define MONSTER_EVENT_BODYDROP_HEAVY 2002 - -#define MONSTER_EVENT_SWISHSOUND 2010 - -#endif // MONSTEREVENT_H diff --git a/ricochet/dlls/monsters.h b/ricochet/dlls/monsters.h deleted file mode 100644 index f46ae52..0000000 --- a/ricochet/dlls/monsters.h +++ /dev/null @@ -1,88 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef MONSTERS_H -#include "skill.h" -#define MONSTERS_H - -/* - -===== monsters.h ======================================================== - - Header file for monster-related utility code - -*/ - -// Hit Group standards -#define HITGROUP_GENERIC 0 -#define HITGROUP_HEAD 1 -#define HITGROUP_CHEST 2 -#define HITGROUP_STOMACH 3 -#define HITGROUP_LEFTARM 4 -#define HITGROUP_RIGHTARM 5 -#define HITGROUP_LEFTLEG 6 -#define HITGROUP_RIGHTLEG 7 - - -// spawn flags 256 and above are already taken by the engine -extern void UTIL_MoveToOrigin( edict_t* pent, const Vector &vecGoal, float flDist, int iMoveType ); - -Vector VecCheckToss ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flGravityAdj = 1.0 ); -Vector VecCheckThrow ( entvars_t *pev, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj = 1.0 ); -extern DLL_GLOBAL Vector g_vecAttackDir; -extern DLL_GLOBAL CONSTANT float g_flMeleeRange; -extern DLL_GLOBAL CONSTANT float g_flMediumRange; -extern DLL_GLOBAL CONSTANT float g_flLongRange; -extern void EjectBrass (const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype ); -extern void ExplodeModel( const Vector &vecOrigin, float speed, int model, int count ); - -BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget ); -BOOL FBoxVisible ( entvars_t *pevLooker, entvars_t *pevTarget, Vector &vecTargetOrigin, float flSize = 0.0 ); - -// monster to monster relationship types -#define R_AL -2 // (ALLY) pals. Good alternative to R_NO when applicable. -#define R_FR -1// (FEAR)will run -#define R_NO 0// (NO RELATIONSHIP) disregard -#define R_DL 1// (DISLIKE) will attack -#define R_HT 2// (HATE)will attack this character instead of any visible DISLIKEd characters -#define R_NM 3// (NEMESIS) A monster Will ALWAYS attack its nemsis, no matter what - - -#define bits_MEMORY_KILLED ( 1 << 7 )// HACKHACK -- remember that I've already called my Killed() - -// -// A gib is a chunk of a body, or a piece of wood/metal/rocks/etc. -// -class CGib : public CBaseEntity -{ -public: - void Spawn( const char *szGibModel ); - void EXPORT BounceGibTouch ( CBaseEntity *pOther ); - void EXPORT StickyGibTouch ( CBaseEntity *pOther ); - void EXPORT WaitTillLand( void ); - void LimitVelocity( void ); - - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; } - static void SpawnHeadGib( entvars_t *pevVictim ); - static void SpawnRandomGibs( entvars_t *pevVictim, int cGibs, int human ); - static void SpawnStickyGibs( entvars_t *pevVictim, Vector vecOrigin, int cGibs ); - - int m_bloodColor; - int m_cBloodDecals; - int m_material; - float m_lifeTime; -}; - - -#endif //MONSTERS_H diff --git a/ricochet/dlls/mortar.cpp b/ricochet/dlls/mortar.cpp deleted file mode 100644 index 22f48b5..0000000 --- a/ricochet/dlls/mortar.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== mortar.cpp ======================================================== - - the "LaBuznik" mortar device - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "weapons.h" -#include "decals.h" -#include "soundent.h" - -class CFuncMortarField : public CBaseToggle -{ -public: - void Spawn( void ); - void Precache( void ); - void KeyValue( KeyValueData *pkvd ); - - // Bmodels don't go across transitions - virtual int ObjectCaps( void ) { return CBaseToggle :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - void EXPORT FieldUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - int m_iszXController; - int m_iszYController; - float m_flSpread; - float m_flDelay; - int m_iCount; - int m_fControl; -}; - -LINK_ENTITY_TO_CLASS( func_mortar_field, CFuncMortarField ); - -TYPEDESCRIPTION CFuncMortarField::m_SaveData[] = -{ - DEFINE_FIELD( CFuncMortarField, m_iszXController, FIELD_STRING ), - DEFINE_FIELD( CFuncMortarField, m_iszYController, FIELD_STRING ), - DEFINE_FIELD( CFuncMortarField, m_flSpread, FIELD_FLOAT ), - DEFINE_FIELD( CFuncMortarField, m_flDelay, FIELD_FLOAT ), - DEFINE_FIELD( CFuncMortarField, m_iCount, FIELD_INTEGER ), - DEFINE_FIELD( CFuncMortarField, m_fControl, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CFuncMortarField, CBaseToggle ); - - -void CFuncMortarField :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "m_iszXController")) - { - m_iszXController = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_iszYController")) - { - m_iszYController = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_flSpread")) - { - m_flSpread = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_fControl")) - { - m_fControl = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "m_iCount")) - { - m_iCount = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } -} - - -// Drop bombs from above -void CFuncMortarField :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world - pev->movetype = MOVETYPE_NONE; - SetBits( pev->effects, EF_NODRAW ); - SetUse( &CFuncMortarField::FieldUse ); - Precache(); -} - - -void CFuncMortarField :: Precache( void ) -{ - PRECACHE_SOUND ("weapons/mortar.wav"); - PRECACHE_SOUND ("weapons/mortarhit.wav"); - PRECACHE_MODEL( "sprites/lgtning.spr" ); -} - - -// If connected to a table, then use the table controllers, else hit where the trigger is. -void CFuncMortarField :: FieldUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - Vector vecStart; - - vecStart.x = RANDOM_FLOAT( pev->mins.x, pev->maxs.x ); - vecStart.y = RANDOM_FLOAT( pev->mins.y, pev->maxs.y ); - vecStart.z = pev->maxs.z; - - switch( m_fControl ) - { - case 0: // random - break; - case 1: // Trigger Activator - if (pActivator != NULL) - { - vecStart.x = pActivator->pev->origin.x; - vecStart.y = pActivator->pev->origin.y; - } - break; - case 2: // table - { - CBaseEntity *pController; - - if (!FStringNull(m_iszXController)) - { - pController = UTIL_FindEntityByTargetname( NULL, STRING(m_iszXController)); - if (pController != NULL) - { - vecStart.x = pev->mins.x + pController->pev->ideal_yaw * (pev->size.x); - } - } - if (!FStringNull(m_iszYController)) - { - pController = UTIL_FindEntityByTargetname( NULL, STRING(m_iszYController)); - if (pController != NULL) - { - vecStart.y = pev->mins.y + pController->pev->ideal_yaw * (pev->size.y); - } - } - } - break; - } - - int pitch = RANDOM_LONG(95,124); - - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "weapons/mortar.wav", 1.0, ATTN_NONE, 0, pitch); - - float t = 2.5; - for (int i = 0; i < m_iCount; i++) - { - Vector vecSpot = vecStart; - vecSpot.x += RANDOM_FLOAT( -m_flSpread, m_flSpread ); - vecSpot.y += RANDOM_FLOAT( -m_flSpread, m_flSpread ); - - TraceResult tr; - UTIL_TraceLine( vecSpot, vecSpot + Vector( 0, 0, -1 ) * 4096, ignore_monsters, ENT(pev), &tr ); - - edict_t *pentOwner = NULL; - if (pActivator) pentOwner = pActivator->edict(); - - CBaseEntity *pMortar = Create("monster_mortar", tr.vecEndPos, Vector( 0, 0, 0 ), pentOwner ); - pMortar->pev->nextthink = gpGlobals->time + t; - t += RANDOM_FLOAT( 0.2, 0.5 ); - - if (i == 0) - CSoundEnt::InsertSound ( bits_SOUND_DANGER, tr.vecEndPos, 400, 0.3 ); - } -} - - -class CMortar : public CGrenade -{ -public: - void Spawn( void ); - void Precache( void ); - - void EXPORT MortarExplode( void ); - - int m_spriteTexture; -}; - -LINK_ENTITY_TO_CLASS( monster_mortar, CMortar ); - -void CMortar::Spawn( ) -{ - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_NOT; - - pev->dmg = 200; - - SetThink( &CMortar::MortarExplode ); - pev->nextthink = 0; - - Precache( ); - - -} - - -void CMortar::Precache( ) -{ - m_spriteTexture = PRECACHE_MODEL( "sprites/lgtning.spr" ); -} - -void CMortar::MortarExplode( void ) -{ -#if 1 - // mortar beam - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_BEAMPOINTS ); - WRITE_COORD(pev->origin.x); - WRITE_COORD(pev->origin.y); - WRITE_COORD(pev->origin.z); - WRITE_COORD(pev->origin.x); - WRITE_COORD(pev->origin.y); - WRITE_COORD(pev->origin.z + 1024); - WRITE_SHORT(m_spriteTexture ); - WRITE_BYTE( 0 ); // framerate - WRITE_BYTE( 0 ); // framerate - WRITE_BYTE( 1 ); // life - WRITE_BYTE( 40 ); // width - WRITE_BYTE( 0 ); // noise - WRITE_BYTE( 255 ); // r, g, b - WRITE_BYTE( 160 ); // r, g, b - WRITE_BYTE( 100 ); // r, g, b - WRITE_BYTE( 128 ); // brightness - WRITE_BYTE( 0 ); // speed - MESSAGE_END(); -#endif - -#if 0 - // blast circle - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_BEAMTORUS); - WRITE_COORD(pev->origin.x); - WRITE_COORD(pev->origin.y); - WRITE_COORD(pev->origin.z + 32); - WRITE_COORD(pev->origin.x); - WRITE_COORD(pev->origin.y); - WRITE_COORD(pev->origin.z + 32 + pev->dmg * 2 / .2); // reach damage radius over .3 seconds - WRITE_SHORT(m_spriteTexture ); - WRITE_BYTE( 0 ); // startframe - WRITE_BYTE( 0 ); // framerate - WRITE_BYTE( 2 ); // life - WRITE_BYTE( 12 ); // width - WRITE_BYTE( 0 ); // noise - WRITE_BYTE( 255 ); // r, g, b - WRITE_BYTE( 160 ); // r, g, b - WRITE_BYTE( 100 ); // r, g, b - WRITE_BYTE( 255 ); // brightness - WRITE_BYTE( 0 ); // speed - MESSAGE_END(); -#endif - - TraceResult tr; - UTIL_TraceLine( pev->origin + Vector( 0, 0, 1024 ), pev->origin - Vector( 0, 0, 1024 ), dont_ignore_monsters, ENT(pev), &tr ); - - Explode( &tr, DMG_BLAST | DMG_MORTAR ); - UTIL_ScreenShake( tr.vecEndPos, 25.0, 150.0, 1.0, 750 ); - -#if 0 - int pitch = RANDOM_LONG(95,124); - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "weapons/mortarhit.wav", 1.0, 0.55, 0, pitch); - - // ForceSound( SNDRADIUS_MP5, bits_SOUND_COMBAT ); - - // ExplodeModel( pev->origin, 400, g_sModelIndexShrapnel, 30 ); - - RadiusDamage ( pev, VARS(pev->owner), pev->dmg, CLASS_NONE, DMG_BLAST ); - - /* - if ( RANDOM_FLOAT ( 0 , 1 ) < 0.5 ) - { - UTIL_DecalTrace( pTrace, DECAL_SCORCH1 ); - } - else - { - UTIL_DecalTrace( pTrace, DECAL_SCORCH2 ); - } - */ - - SetThink( &CMortar::SUB_Remove ); - pev->nextthink = gpGlobals->time + 0.1; -#endif - -} - - -#if 0 -void CMortar::ShootTimed( EVARS *pevOwner, Vector vecStart, float time ) -{ - CMortar *pMortar = GetClassPtr( (CMortar *)NULL ); - pMortar->Spawn(); - - TraceResult tr; - UTIL_TraceLine( vecStart, vecStart + Vector( 0, 0, -1 ) * 4096, ignore_monsters, ENT(pMortar->pev), &tr ); - - pMortar->pev->nextthink = gpGlobals->time + time; - - UTIL_SetOrigin( pMortar->pev, tr.vecEndPos ); -} -#endif diff --git a/ricochet/dlls/mp.def b/ricochet/dlls/mp.def deleted file mode 100644 index 2a12a7c..0000000 --- a/ricochet/dlls/mp.def +++ /dev/null @@ -1,5 +0,0 @@ -LIBRARY mp -EXPORTS - GiveFnptrsToDll @1 -SECTIONS - .data READ WRITE diff --git a/ricochet/dlls/mp.dsp b/ricochet/dlls/mp.dsp deleted file mode 100644 index 7cfcc19..0000000 --- a/ricochet/dlls/mp.dsp +++ /dev/null @@ -1,516 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mp" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=mp - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mp.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mp.mak" CFG="mp - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName ""$/GoldSrc/discwar/dlls", HDKCAAAA" -# PROP Scc_LocalPath "." -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mp - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir ".\Release" -# PROP BASE Intermediate_Dir ".\Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\Releasemp" -# PROP Intermediate_Dir ".\Releasemp" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /G5 /MT /W3 /GX /Zi /O2 /I "." /I "..\dlls" /I "..\..\engine" /I "..\..\common" /I "..\engine" /I "..\common" /I "..\..\public" /I "..\..\game_shared" /I "..\pm_shared" /I "..\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "VALVE_DLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /map /debug /machine:I386 /def:".\mp.def" -# SUBTRACT LINK32 /profile -# Begin Custom Build - Copying to \half-life\ricochet\dlls -InputDir=.\Releasemp -ProjDir=. -InputPath=.\Releasemp\mp.dll -InputName=mp -SOURCE="$(InputPath)" - -BuildCmds= \ - call ..\..\filecopy.bat $(InputPath) $(ProjDir)\..\..\..\game\mod\dlls\$(InputName).dll \ - call ..\..\filecopy.bat $(InputDir)\$(InputName).pdb $(ProjDir)\..\..\..\game\mod\dlls\$(InputName).pdb \ - - -"$(ProjDir)\..\..\..\game\mod\dlls\$(InputName).dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) - -"$(ProjDir)\..\..\..\game\mod\dlls\$(InputName).pdb" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - $(BuildCmds) -# End Custom Build - -!ELSEIF "$(CFG)" == "mp - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir ".\mp___Win" -# PROP BASE Intermediate_Dir ".\mp___Win" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\debugmp" -# PROP Intermediate_Dir ".\debugmp" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c -# ADD CPP /nologo /G5 /MTd /W3 /Gm /GX /ZI /Od /I "..\..\engine" /I "..\..\common" /I "..\engine" /I "..\common" /I "..\..\public" /I "." /I "..\..\game_shared" /I "..\dlls" /I "..\pm_shared" /I "..\\" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "VALVE_DLL" /FR /YX /FD /c -# ADD BASE MTL /nologo /D "_DEBUG" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /i "..\engine" /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 -# ADD LINK32 user32.lib advapi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /def:".\mp.def" /implib:".\Debug\mp.lib" -# SUBTRACT LINK32 /profile -# Begin Custom Build - Copying to \quiver\ricochet\dlls -ProjDir=. -InputPath=.\debugmp\mp.dll -InputName=mp -SOURCE="$(InputPath)" - -"$(ProjDir)\..\..\..\game\mod\dlls\$(InputName).dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - call ..\..\filecopy.bat $(InputPath) $(ProjDir)\..\..\..\game\mod\dlls\$(InputName).dll - -# End Custom Build - -!ENDIF - -# Begin Target - -# Name "mp - Win32 Release" -# Name "mp - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90" -# Begin Source File - -SOURCE=.\airtank.cpp -# End Source File -# Begin Source File - -SOURCE=.\animating.cpp -# End Source File -# Begin Source File - -SOURCE=.\animation.cpp -# End Source File -# Begin Source File - -SOURCE=.\bmodels.cpp -# End Source File -# Begin Source File - -SOURCE=.\buttons.cpp -# End Source File -# Begin Source File - -SOURCE=.\cbase.cpp -# End Source File -# Begin Source File - -SOURCE=.\client.cpp -# End Source File -# Begin Source File - -SOURCE=.\combat.cpp -# End Source File -# Begin Source File - -SOURCE=.\disc_arena.cpp -# End Source File -# Begin Source File - -SOURCE=.\disc_powerups.cpp -# End Source File -# Begin Source File - -SOURCE=.\wpn_shared\disc_weapon_disc.cpp -# End Source File -# Begin Source File - -SOURCE=.\doors.cpp -# End Source File -# Begin Source File - -SOURCE=.\effects.cpp -# End Source File -# Begin Source File - -SOURCE=.\explode.cpp -# End Source File -# Begin Source File - -SOURCE=.\func_break.cpp -# End Source File -# Begin Source File - -SOURCE=.\func_tank.cpp -# End Source File -# Begin Source File - -SOURCE=.\game.cpp -# End Source File -# Begin Source File - -SOURCE=.\gamerules.cpp -# End Source File -# Begin Source File - -SOURCE=.\ggrenade.cpp -# End Source File -# Begin Source File - -SOURCE=.\globals.cpp -# End Source File -# Begin Source File - -SOURCE=.\h_ai.cpp -# End Source File -# Begin Source File - -SOURCE=.\h_battery.cpp -# End Source File -# Begin Source File - -SOURCE=.\h_cycler.cpp -# End Source File -# Begin Source File - -SOURCE=.\h_export.cpp -# End Source File -# Begin Source File - -SOURCE=.\healthkit.cpp -# End Source File -# Begin Source File - -SOURCE=.\items.cpp -# End Source File -# Begin Source File - -SOURCE=.\lights.cpp -# End Source File -# Begin Source File - -SOURCE=.\maprules.cpp -# End Source File -# Begin Source File - -SOURCE=.\mortar.cpp -# End Source File -# Begin Source File - -SOURCE=.\mpstubb.cpp -# End Source File -# Begin Source File - -SOURCE=.\multiplay_gamerules.cpp -# End Source File -# Begin Source File - -SOURCE=.\observer.cpp -# End Source File -# Begin Source File - -SOURCE=.\pathcorner.cpp -# End Source File -# Begin Source File - -SOURCE=.\plane.cpp -# End Source File -# Begin Source File - -SOURCE=.\plats.cpp -# End Source File -# Begin Source File - -SOURCE=.\player.cpp -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_debug.c -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_math.c -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_shared.c -# End Source File -# Begin Source File - -SOURCE=.\singleplay_gamerules.cpp -# End Source File -# Begin Source File - -SOURCE=.\skill.cpp -# End Source File -# Begin Source File - -SOURCE=.\sound.cpp -# End Source File -# Begin Source File - -SOURCE=.\soundent.cpp -# End Source File -# Begin Source File - -SOURCE=.\spectator.cpp -# End Source File -# Begin Source File - -SOURCE=.\subs.cpp -# End Source File -# Begin Source File - -SOURCE=.\teamplay_gamerules.cpp -# End Source File -# Begin Source File - -SOURCE=.\triggers.cpp -# End Source File -# Begin Source File - -SOURCE=.\util.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\game_shared\voice_gamemgr.cpp -# End Source File -# Begin Source File - -SOURCE=.\weapons.cpp -# End Source File -# Begin Source File - -SOURCE=.\world.cpp -# End Source File -# Begin Source File - -SOURCE=.\xen.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" -# Begin Source File - -SOURCE=.\activity.h -# End Source File -# Begin Source File - -SOURCE=.\activitymap.h -# End Source File -# Begin Source File - -SOURCE=.\animation.h -# End Source File -# Begin Source File - -SOURCE=.\basemonster.h -# End Source File -# Begin Source File - -SOURCE=.\cbase.h -# End Source File -# Begin Source File - -SOURCE=.\cdll_dll.h -# End Source File -# Begin Source File - -SOURCE=.\client.h -# End Source File -# Begin Source File - -SOURCE=.\decals.h -# End Source File -# Begin Source File - -SOURCE=.\disc_arena.h -# End Source File -# Begin Source File - -SOURCE=.\discwar.h -# End Source File -# Begin Source File - -SOURCE=.\doors.h -# End Source File -# Begin Source File - -SOURCE=.\effects.h -# End Source File -# Begin Source File - -SOURCE=.\enginecallback.h -# End Source File -# Begin Source File - -SOURCE=.\explode.h -# End Source File -# Begin Source File - -SOURCE=.\extdll.h -# End Source File -# Begin Source File - -SOURCE=.\func_break.h -# End Source File -# Begin Source File - -SOURCE=.\game.h -# End Source File -# Begin Source File - -SOURCE=.\gamerules.h -# End Source File -# Begin Source File - -SOURCE=.\hornet.h -# End Source File -# Begin Source File - -SOURCE=.\items.h -# End Source File -# Begin Source File - -SOURCE=.\maprules.h -# End Source File -# Begin Source File - -SOURCE=.\monsterevent.h -# End Source File -# Begin Source File - -SOURCE=.\monsters.h -# End Source File -# Begin Source File - -SOURCE=.\nodes.h -# End Source File -# Begin Source File - -SOURCE=.\plane.h -# End Source File -# Begin Source File - -SOURCE=.\player.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_debug.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_defs.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_info.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_materials.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_movevars.h -# End Source File -# Begin Source File - -SOURCE=..\pm_shared\pm_shared.h -# End Source File -# Begin Source File - -SOURCE=.\saverestore.h -# End Source File -# Begin Source File - -SOURCE=.\schedule.h -# End Source File -# Begin Source File - -SOURCE=.\scriptevent.h -# End Source File -# Begin Source File - -SOURCE=.\skill.h -# End Source File -# Begin Source File - -SOURCE=.\soundent.h -# End Source File -# Begin Source File - -SOURCE=.\spectator.h -# End Source File -# Begin Source File - -SOURCE=.\talkmonster.h -# End Source File -# Begin Source File - -SOURCE=.\teamplay_gamerules.h -# End Source File -# Begin Source File - -SOURCE=.\trains.h -# End Source File -# Begin Source File - -SOURCE=.\util.h -# End Source File -# Begin Source File - -SOURCE=.\vector.h -# End Source File -# Begin Source File - -SOURCE=.\weapons.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/ricochet/dlls/mpstubb.cpp b/ricochet/dlls/mpstubb.cpp deleted file mode 100644 index 41631f0..0000000 --- a/ricochet/dlls/mpstubb.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ - - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "soundent.h" -#include "nodes.h" -#include "talkmonster.h" - - -float CTalkMonster::g_talkWaitTime = 0; // time delay until it's ok to speak: used so that two NPCs don't talk at once - -/*********************************************************/ - - -CGraph WorldGraph; -void CGraph :: InitGraph( void ) { } -int CGraph :: FLoadGraph ( char *szMapName ) { return FALSE; } -int CGraph :: AllocNodes ( void ) { return FALSE; } -int CGraph :: CheckNODFile ( char *szMapName ) { return FALSE; } -int CGraph :: FSetGraphPointers ( void ) { return 0; } -void CGraph :: ShowNodeConnections ( int iNode ) { } -int CGraph :: FindNearestNode ( const Vector &vecOrigin, int afNodeTypes ) { return 0; } - - -/*********************************************************/ - - -void CBaseMonster :: ReportAIState( void ) { } -float CBaseMonster :: ChangeYaw ( int speed ) { return 0; } -void CBaseMonster :: MakeIdealYaw( Vector vecTarget ) { } - - -void CBaseMonster::CorpseFallThink( void ) -{ - if ( pev->flags & FL_ONGROUND ) - { - SetThink ( NULL ); - - SetSequenceBox( ); - UTIL_SetOrigin( pev, pev->origin );// link into world. - } - else - pev->nextthink = gpGlobals->time + 0.1; -} -// Call after animation/pose is set up -void CBaseMonster :: MonsterInitDead( void ) -{ - InitBoneControllers(); - - pev->solid = SOLID_BBOX; - pev->movetype = MOVETYPE_TOSS;// so he'll fall to ground - - pev->frame = 0; - ResetSequenceInfo( ); - pev->framerate = 0; - - // Copy health - pev->max_health = pev->health; - pev->deadflag = DEAD_DEAD; - - UTIL_SetSize(pev, g_vecZero, g_vecZero ); - UTIL_SetOrigin( pev, pev->origin ); - - // Setup health counters, etc. - BecomeDead(); - SetThink( &CBaseMonster::CorpseFallThink ); - pev->nextthink = gpGlobals->time + 0.5; -} - - -BOOL CBaseMonster :: ShouldFadeOnDeath( void ) -{ - return FALSE; -} - -BOOL CBaseMonster :: FCheckAITrigger ( void ) -{ - return FALSE; -} - -void CBaseMonster :: KeyValue( KeyValueData *pkvd ) -{ - CBaseToggle::KeyValue( pkvd ); -} - -int CBaseMonster::IRelationship ( CBaseEntity *pTarget ) -{ - static int iEnemy[14][14] = - { // NONE MACH PLYR HPASS HMIL AMIL APASS AMONST APREY APRED INSECT PLRALY PBWPN ABWPN - /*NONE*/ { R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO, R_NO, R_NO }, - /*MACHINE*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_DL, R_DL, R_DL }, - /*PLAYER*/ { R_NO ,R_DL ,R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO, R_DL, R_DL }, - /*HUMANPASSIVE*/{ R_NO ,R_NO ,R_AL ,R_AL ,R_HT ,R_FR ,R_NO ,R_HT ,R_DL ,R_FR ,R_NO ,R_AL, R_NO, R_NO }, - /*HUMANMILITAR*/{ R_NO ,R_NO ,R_HT ,R_DL ,R_NO ,R_HT ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_HT, R_NO, R_NO }, - /*ALIENMILITAR*/{ R_NO ,R_DL ,R_HT ,R_DL ,R_HT ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_DL, R_NO, R_NO }, - /*ALIENPASSIVE*/{ R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO, R_NO, R_NO }, - /*ALIENMONSTER*/{ R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_NO ,R_DL, R_NO, R_NO }, - /*ALIENPREY */{ R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_NO ,R_FR ,R_NO ,R_DL, R_NO, R_NO }, - /*ALIENPREDATO*/{ R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO ,R_NO ,R_HT ,R_DL ,R_NO ,R_DL, R_NO, R_NO }, - /*INSECT*/ { R_FR ,R_FR ,R_FR ,R_FR ,R_FR ,R_NO ,R_FR ,R_FR ,R_FR ,R_FR ,R_NO ,R_FR, R_NO, R_NO }, - /*PLAYERALLY*/ { R_NO ,R_DL ,R_AL ,R_AL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_NO, R_NO, R_NO }, - /*PBIOWEAPON*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_DL ,R_NO ,R_DL, R_NO, R_DL }, - /*ABIOWEAPON*/ { R_NO ,R_NO ,R_DL ,R_DL ,R_DL ,R_AL ,R_NO ,R_DL ,R_DL ,R_NO ,R_NO ,R_DL, R_DL, R_NO } - }; - - return iEnemy[ Classify() ][ pTarget->Classify() ]; -} - - -//========================================================= -// Look - Base class monster function to find enemies or -// food by sight. iDistance is distance ( in units ) that the -// monster can see. -// -// Sets the sight bits of the m_afConditions mask to indicate -// which types of entities were sighted. -// Function also sets the Looker's m_pLink -// to the head of a link list that contains all visible ents. -// (linked via each ent's m_pLink field) -// -//========================================================= -void CBaseMonster :: Look ( int iDistance ) -{ - int iSighted = 0; - - // DON'T let visibility information from last frame sit around! - ClearConditions(bits_COND_SEE_HATE | bits_COND_SEE_DISLIKE | bits_COND_SEE_ENEMY | bits_COND_SEE_FEAR | bits_COND_SEE_NEMESIS | bits_COND_SEE_CLIENT); - - m_pLink = NULL; - - CBaseEntity *pSightEnt = NULL;// the current visible entity that we're dealing with - - CBaseEntity *pList[100]; - - Vector delta = Vector( iDistance, iDistance, iDistance ); - - // Find only monsters/clients in box, NOT limited to PVS - int count = UTIL_EntitiesInBox( pList, 100, pev->origin - delta, pev->origin + delta, FL_CLIENT|FL_MONSTER ); - for ( int i = 0; i < count; i++ ) - { - pSightEnt = pList[i]; - if ( pSightEnt != this && pSightEnt->pev->health > 0 ) - { - // the looker will want to consider this entity - // don't check anything else about an entity that can't be seen, or an entity that you don't care about. - if ( IRelationship( pSightEnt ) != R_NO && FInViewCone( pSightEnt ) && !FBitSet( pSightEnt->pev->flags, FL_NOTARGET ) && FVisible( pSightEnt ) ) - { - if ( pSightEnt->IsPlayer() ) - { - // if we see a client, remember that (mostly for scripted AI) - iSighted |= bits_COND_SEE_CLIENT; - } - - pSightEnt->m_pLink = m_pLink; - m_pLink = pSightEnt; - - if ( pSightEnt == m_hEnemy ) - { - // we know this ent is visible, so if it also happens to be our enemy, store that now. - iSighted |= bits_COND_SEE_ENEMY; - } - - // don't add the Enemy's relationship to the conditions. We only want to worry about conditions when - // we see monsters other than the Enemy. - switch ( IRelationship ( pSightEnt ) ) - { - case R_NM: - iSighted |= bits_COND_SEE_NEMESIS; - break; - case R_HT: - iSighted |= bits_COND_SEE_HATE; - break; - case R_DL: - iSighted |= bits_COND_SEE_DISLIKE; - break; - case R_FR: - iSighted |= bits_COND_SEE_FEAR; - break; - case R_AL: - break; - default: - ALERT ( at_aiconsole, "%s can't assess %s\n", STRING(pev->classname), STRING(pSightEnt->pev->classname ) ); - break; - } - } - } - } - - SetConditions( iSighted ); -} - - -//========================================================= -// BestVisibleEnemy - this functions searches the link -// list whose head is the caller's m_pLink field, and returns -// a pointer to the enemy entity in that list that is nearest the -// caller. -// -// !!!UNDONE - currently, this only returns the closest enemy. -// we'll want to consider distance, relationship, attack types, back turned, etc. -//========================================================= -CBaseEntity *CBaseMonster :: BestVisibleEnemy ( void ) -{ - CBaseEntity *pReturn; - CBaseEntity *pNextEnt; - int iNearest; - int iDist; - int iBestRelationship; - - iNearest = 8192;// so first visible entity will become the closest. - pNextEnt = m_pLink; - pReturn = NULL; - iBestRelationship = R_NO; - - while ( pNextEnt != NULL ) - { - if ( pNextEnt->IsAlive() ) - { - if ( IRelationship( pNextEnt) > iBestRelationship ) - { - // this entity is disliked MORE than the entity that we - // currently think is the best visible enemy. No need to do - // a distance check, just get mad at this one for now. - iBestRelationship = IRelationship ( pNextEnt ); - iNearest = ( pNextEnt->pev->origin - pev->origin ).Length(); - pReturn = pNextEnt; - } - else if ( IRelationship( pNextEnt) == iBestRelationship ) - { - // this entity is disliked just as much as the entity that - // we currently think is the best visible enemy, so we only - // get mad at it if it is closer. - iDist = ( pNextEnt->pev->origin - pev->origin ).Length(); - - if ( iDist <= iNearest ) - { - iNearest = iDist; - iBestRelationship = IRelationship ( pNextEnt ); - pReturn = pNextEnt; - } - } - } - - pNextEnt = pNextEnt->m_pLink; - } - - return pReturn; -} diff --git a/ricochet/dlls/multiplay_gamerules.cpp b/ricochet/dlls/multiplay_gamerules.cpp deleted file mode 100644 index efa9e3b..0000000 --- a/ricochet/dlls/multiplay_gamerules.cpp +++ /dev/null @@ -1,1620 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// teamplay_gamerules.cpp -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "game.h" -#include "items.h" -#include "monsters.h" -#include "discwar.h" -#include "voice_gamemgr.h" - -#if !defined ( _WIN32 ) -#include -#endif - -extern DLL_GLOBAL CGameRules *g_pGameRules; -extern DLL_GLOBAL BOOL g_fGameOver; -extern int gmsgDeathMsg; // client dll messages -extern int gmsgScoreInfo; -extern int gmsgMOTD; -extern int gmsgSpectator; -extern int gmsgReward; - -extern int g_iMapTurnedOffArena; - -#define ITEM_RESPAWN_TIME 30 -#define WEAPON_RESPAWN_TIME 20 -#define AMMO_RESPAWN_TIME 20 - -CVoiceGameMgr g_VoiceGameMgr; - -int InArenaMode( void ); - -class CMultiplayGameMgrHelper : public IVoiceGameMgrHelper -{ -public: - virtual bool CanPlayerHearPlayer(CBasePlayer *pListener, CBasePlayer *pTalker) - { - //FFA - if ( InArenaMode() == FALSE ) - return true; - - if ( pListener->m_pCurrentArena == NULL && pTalker->m_pCurrentArena == NULL ) - return true; //Both spectating - - if ( pListener->m_pCurrentArena == pTalker->m_pCurrentArena ) - return true; //Same arena - - return false; - } -}; -static CMultiplayGameMgrHelper g_GameMgrHelper; - -//********************************************************* -// Rules for the half-life multiplayer game. -//********************************************************* - -CHalfLifeMultiplay :: CHalfLifeMultiplay() -{ - g_VoiceGameMgr.Init(&g_GameMgrHelper, gpGlobals->maxClients); - - RefreshSkillData(); - m_flIntermissionEndTime = 0; - - // 11/8/98 - // Modified by YWB: Server .cfg file is now a cvar, so that - // server ops can run multiple game servers, with different server .cfg files, - // from a single installed directory. - // Mapcyclefile is already a cvar. - - // 3/31/99 - // Added lservercfg file cvar, since listen and dedicated servers should not - // share a single config file. (sjb) - if ( IS_DEDICATED_SERVER() ) - { - // this code has been moved into engine, to only run server.cfg once - } - else - { - // listen server - char *lservercfgfile = (char *)CVAR_GET_STRING( "lservercfgfile" ); - - if ( lservercfgfile && lservercfgfile[0] ) - { - char szCommand[256]; - - ALERT( at_console, "Executing listen server config file\n" ); - sprintf( szCommand, "exec %s\n", lservercfgfile ); - SERVER_COMMAND( szCommand ); - } - } -} - -BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) -{ - if(g_VoiceGameMgr.ClientCommand(pPlayer, pcmd)) - return TRUE; - - return CGameRules::ClientCommand(pPlayer, pcmd); -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay::RefreshSkillData( void ) -{ -// load all default values - CGameRules::RefreshSkillData(); - -// override some values for multiplay. - - // suitcharger - gSkillData.suitchargerCapacity = 30; - - // Crowbar whack - gSkillData.plrDmgCrowbar = 25; - - // Glock Round - gSkillData.plrDmg9MM = 12; - - // 357 Round - gSkillData.plrDmg357 = 40; - - // MP5 Round - gSkillData.plrDmgMP5 = 12; - - // M203 grenade - gSkillData.plrDmgM203Grenade = 100; - - // Shotgun buckshot - gSkillData.plrDmgBuckshot = 20;// fewer pellets in deathmatch - - // Crossbow - gSkillData.plrDmgCrossbowClient = 20; - - // RPG - gSkillData.plrDmgRPG = 120; - - // Egon - gSkillData.plrDmgEgonWide = 20; - gSkillData.plrDmgEgonNarrow = 10; - - // Hand Grendade - gSkillData.plrDmgHandGrenade = 100; - - // Satchel Charge - gSkillData.plrDmgSatchel = 120; - - // Tripmine - gSkillData.plrDmgTripmine = 150; - - // hornet - gSkillData.plrDmgHornet = 10; -} - -// longest the intermission can last, in seconds -#define MAX_INTERMISSION_TIME 120 - -extern cvar_t timeleft, fragsleft; -//========================================================= -//========================================================= -void CHalfLifeMultiplay :: Think ( void ) -{ - g_VoiceGameMgr.Update(gpGlobals->frametime); - - ///// Check game rules ///// - static int last_frags; - static int last_time; - - int frags_remaining = 0; - int time_remaining = 0; - - if ( g_fGameOver ) // someone else quit the game already - { - if ( m_flIntermissionEndTime < gpGlobals->time ) - { - if ( m_iEndIntermissionButtonHit // check that someone has pressed a key, or the max intermission time is over - || ((m_flIntermissionEndTime + MAX_INTERMISSION_TIME) < gpGlobals->time) ) - ChangeLevel(); // intermission is over - } - return; - } - - float flTimeLimit = timelimit.value * 60; - float flFragLimit = fraglimit.value; - - time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0); - - if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit ) - { - GoToIntermission(); - return; - } - - if ( flFragLimit ) - { - int bestfrags = 9999; - int remain; - - // check if any player is over the frag limit - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - - if ( pPlayer && pPlayer->pev->frags >= flFragLimit ) - { - GoToIntermission(); - return; - } - - - if ( pPlayer ) - { - remain = flFragLimit - pPlayer->pev->frags; - if ( remain < bestfrags ) - { - bestfrags = remain; - } - } - - } - frags_remaining = bestfrags; - } - - // Updates when frags change - if ( frags_remaining != last_frags ) - { - g_engfuncs.pfnCvar_DirectSet( &fragsleft, UTIL_VarArgs( "%i", frags_remaining ) ); - } - - // Updates once per second - if ( timeleft.value != last_time ) - { - g_engfuncs.pfnCvar_DirectSet( &timeleft, UTIL_VarArgs( "%i", time_remaining ) ); - } - - last_frags = frags_remaining; - last_time = time_remaining; -} - - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::IsMultiplayer( void ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::IsDeathmatch( void ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::IsCoOp( void ) -{ - return gpGlobals->coop; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ - if ( !pWeapon->CanDeploy() ) - { - // that weapon can't deploy anyway. - return FALSE; - } - - if ( !pPlayer->m_pActiveItem ) - { - // player doesn't have an active item! - return TRUE; - } - - if ( !pPlayer->m_pActiveItem->CanHolster() ) - { - // can't put away the active item. - return FALSE; - } - - if ( pWeapon->iWeight() > pPlayer->m_pActiveItem->iWeight() ) - { - return TRUE; - } - - return FALSE; -} - -BOOL CHalfLifeMultiplay :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) -{ - - CBasePlayerItem *pCheck; - CBasePlayerItem *pBest;// this will be used in the event that we don't find a weapon in the same category. - int iBestWeight; - int i; - - iBestWeight = -1;// no weapon lower than -1 can be autoswitched to - pBest = NULL; - - if ( !pCurrentWeapon->CanHolster() ) - { - // can't put this gun away right now, so can't switch. - return FALSE; - } - - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - pCheck = pPlayer->m_rgpPlayerItems[ i ]; - - while ( pCheck ) - { - if ( pCheck->iWeight() > -1 && pCheck->iWeight() == pCurrentWeapon->iWeight() && pCheck != pCurrentWeapon ) - { - // this weapon is from the same category. - if ( pCheck->CanDeploy() ) - { - if ( pPlayer->SwitchWeapon( pCheck ) ) - { - return TRUE; - } - } - } - else if ( pCheck->iWeight() > iBestWeight && pCheck != pCurrentWeapon )// don't reselect the weapon we're trying to get rid of - { - //ALERT ( at_console, "Considering %s\n", STRING( pCheck->pev->classname ) ); - // we keep updating the 'best' weapon just in case we can't find a weapon of the same weight - // that the player was using. This will end up leaving the player with his heaviest-weighted - // weapon. - if ( pCheck->CanDeploy() ) - { - // if this weapon is useable, flag it as the best - iBestWeight = pCheck->iWeight(); - pBest = pCheck; - } - } - - pCheck = pCheck->m_pNext; - } - } - - // if we make it here, we've checked all the weapons and found no useable - // weapon in the same catagory as the current weapon. - - // if pBest is null, we didn't find ANYTHING. Shouldn't be possible- should always - // at least get the crowbar, but ya never know. - if ( !pBest ) - { - return FALSE; - } - - pPlayer->SwitchWeapon( pBest ); - - return TRUE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) -{ - g_VoiceGameMgr.ClientConnected(pEntity); - - // Increase their speed to the Discwar speed - MESSAGE_BEGIN( MSG_ONE, SVC_STUFFTEXT, NULL, pEntity ); - WRITE_STRING( UTIL_VarArgs("cl_forwardspeed %d\ncl_backspeed %d\ncl_sidespeed %d\n", 320, 320, 320) ); - MESSAGE_END(); - - - return TRUE; -} - -extern int gmsgSayText; -extern int gmsgGameMode; - -void CHalfLifeMultiplay :: UpdateGameMode( CBasePlayer *pPlayer ) -{ - MESSAGE_BEGIN( MSG_ONE, gmsgGameMode, NULL, pPlayer->edict() ); - WRITE_BYTE( InArenaMode() ); // game mode none - MESSAGE_END(); -} - -void CHalfLifeMultiplay :: InitHUD( CBasePlayer *pl ) -{ - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" entered the game\n", - STRING( pl->pev->netname ), - GETPLAYERUSERID( pl->edict() ), - GETPLAYERAUTHID( pl->edict() ), - GETPLAYERUSERID( pl->edict() ) ); - - UpdateGameMode( pl ); - - // sending just one score makes the hud scoreboard active; otherwise - // it is just disabled for single play - MESSAGE_BEGIN( MSG_ONE, gmsgScoreInfo, NULL, pl->edict() ); - WRITE_BYTE( ENTINDEX(pl->edict()) ); - WRITE_SHORT( 0 ); - WRITE_SHORT( 0 ); - WRITE_SHORT( 0 ); - WRITE_SHORT( 0 ); - MESSAGE_END(); - - SendMOTDToClient( pl->edict() ); - - // loop through all active players and send their score info to the new client - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - // FIXME: Probably don't need to cast this just to read m_iDeaths - CBasePlayer *plr = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if ( plr ) - { - ALERT( at_console, "Sending %s data to %s\n", STRING(plr->pev->netname), STRING( pl->pev->netname ) ); - - MESSAGE_BEGIN( MSG_ONE, gmsgScoreInfo, NULL, pl->edict() ); - WRITE_BYTE( i ); // client number - WRITE_SHORT( plr->pev->frags ); - WRITE_SHORT( plr->m_iDeaths ); - WRITE_SHORT( plr->pev->playerclass ); - WRITE_SHORT( plr->pev->team ); - MESSAGE_END(); - - // Send their spectator state - MESSAGE_BEGIN( MSG_ONE, gmsgSpectator, NULL, pl->edict() ); - WRITE_BYTE( i ); - WRITE_BYTE( (plr->pev->iuser1 != 0) ); - MESSAGE_END(); - } - } - - if ( g_fGameOver ) - { - MESSAGE_BEGIN( MSG_ONE, SVC_INTERMISSION, NULL, pl->edict() ); - MESSAGE_END(); - } -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay :: ClientDisconnected( edict_t *pClient ) -{ - if ( pClient ) - { - CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance( pClient ); - - if ( pPlayer ) - { - FireTargets( "game_playerleave", pPlayer, pPlayer, USE_TOGGLE, 0 ); - - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" disconnected\n", - STRING( pPlayer->pev->netname ), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - GETPLAYERUSERID( pPlayer->edict() ) ); - - pPlayer->RemoveAllItems( TRUE );// destroy all of the players weapons and items - - // Tell all clients this player isn't a spectator anymore - MESSAGE_BEGIN( MSG_ALL, gmsgSpectator ); - WRITE_BYTE( ENTINDEX(pClient) ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - - CBasePlayer *client = NULL; - while ( ((client = (CBasePlayer*)UTIL_FindEntityByClassname( client, "player" )) != NULL) && (!FNullEnt(client->edict())) ) - { - if ( !client->pev ) - continue; - if ( client == pPlayer ) - continue; - - // If a spectator was chasing this player, move him/her onto the next player - if ( client->m_hObserverTarget == pPlayer ) - { - int iMode = client->pev->iuser1; - client->pev->iuser1 = 0; - client->m_hObserverTarget = NULL; - client->Observer_SetMode( iMode ); - } - } - } - } -} - -//========================================================= -//========================================================= -float CHalfLifeMultiplay :: FlPlayerFallDamage( CBasePlayer *pPlayer ) -{ - int iFallDamage = (int)CVAR_GET_FLOAT("mp_falldamage"); - - switch ( iFallDamage ) - { - case 1://progressive - pPlayer->m_flFallVelocity -= PLAYER_MAX_SAFE_FALL_SPEED; - return pPlayer->m_flFallVelocity * DAMAGE_FOR_FALL_SPEED; - break; - default: - case 0:// fixed - return 10; - break; - } -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay :: PlayerThink( CBasePlayer *pPlayer ) -{ - if ( g_fGameOver ) - { - // check for button presses - if ( pPlayer->m_afButtonPressed & ( IN_DUCK | IN_ATTACK | IN_ATTACK2 | IN_USE | IN_JUMP ) ) - m_iEndIntermissionButtonHit = TRUE; - - // clear attack/use commands from player - pPlayer->m_afButtonPressed = 0; - pPlayer->pev->button = 0; - pPlayer->m_afButtonReleased = 0; - } -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay :: PlayerSpawn( CBasePlayer *pPlayer ) -{ - BOOL addDefault; - CBaseEntity *pWeaponEntity = NULL; - - pPlayer->pev->weapons |= (1<Touch( pPlayer ); - addDefault = FALSE; - } - - if ( addDefault ) - { - pPlayer->GiveNamedItem( "weapon_disc" ); - pPlayer->GiveAmmo( MAX_DISCS, "disc", MAX_DISCS ); - } -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay :: FPlayerCanRespawn( CBasePlayer *pPlayer ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -float CHalfLifeMultiplay :: FlPlayerSpawnTime( CBasePlayer *pPlayer ) -{ - return gpGlobals->time;//now! -} - -BOOL CHalfLifeMultiplay :: AllowAutoTargetCrosshair( void ) -{ - return ( CVAR_GET_FLOAT( "mp_autocrosshair" ) != 0 ); -} - -//========================================================= -// IPointsForKill - how many points awarded to anyone -// that kills this player? -//========================================================= -int CHalfLifeMultiplay :: IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) -{ - return 1; -} - - -//========================================================= -// PlayerKilled - someone/something killed this player -//========================================================= -void CHalfLifeMultiplay :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ - DeathNotice( pVictim, pKiller, pInflictor ); - - FireTargets( "game_playerdie", pVictim, pVictim, USE_TOGGLE, 0 ); - CBasePlayer *peKiller = NULL; - CBaseEntity *ktmp = CBaseEntity::Instance( pKiller ); - if ( ktmp && (ktmp->Classify() == CLASS_PLAYER) ) - peKiller = (CBasePlayer*)ktmp; - - CBaseEntity *ep = CBaseEntity::Instance( pKiller ); - if ( ep && ep->Classify() == CLASS_PLAYER ) - { - CBasePlayer *PK = (CBasePlayer*)ep; - - // let the killer paint another decal as soon as he'd like. - PK->m_flNextDecalTime = gpGlobals->time; - } -} - -//========================================================= -// Deathnotice. -//========================================================= -void CHalfLifeMultiplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ) -{ - // Work out what killed the player, and send a message to all clients about it - CBaseEntity *Killer = CBaseEntity::Instance( pKiller ); - - const char *killer_weapon_name = "world"; // by default, the player is killed by the world - int killer_index = 0; - - // Hack to fix name change - char *tau = "tau_cannon"; - char *gluon = "gluon gun"; - - if ( pKiller->flags & FL_CLIENT ) - { - killer_index = ENTINDEX(ENT(pKiller)); - - if ( pevInflictor ) - { - if ( pevInflictor == pKiller ) - { - // If the inflictor is the killer, then it must be their current weapon doing the damage - CBasePlayer *pPlayer = (CBasePlayer*)CBaseEntity::Instance( pKiller ); - - if ( pPlayer->m_pActiveItem ) - { - killer_weapon_name = pPlayer->m_pActiveItem->pszName(); - } - } - else - { - killer_weapon_name = STRING( pevInflictor->classname ); // it's just that easy - } - } - } - else - { - killer_weapon_name = STRING( pevInflictor->classname ); - } - - // strip the monster_* or weapon_* from the inflictor's classname - if ( strncmp( killer_weapon_name, "weapon_", 7 ) == 0 ) - killer_weapon_name += 7; - else if ( strncmp( killer_weapon_name, "monster_", 8 ) == 0 ) - killer_weapon_name += 8; - else if ( strncmp( killer_weapon_name, "func_", 5 ) == 0 ) - killer_weapon_name += 5; - - if ( pVictim->pev == pKiller ) - { - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"%s\"\n", - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GETPLAYERUSERID( pVictim->edict() ), - killer_weapon_name ); - - pKiller->frags -= 1; - } - else if ( pKiller->flags & FL_CLIENT ) - { - if ( !strcmp( killer_weapon_name, "disc" ) ) - { - int iTele = 0; - if ( (pVictim->m_flLastDiscHitTeleport != 0) && (gpGlobals->time < pVictim->m_flLastDiscHitTeleport + MAX_SCORE_TIME_AFTER_HIT) ) - iTele = REWARD_TELEPORT; - - // Decapitated? - if ( pVictim->m_LastHitGroup == HITGROUP_HEAD ) - { - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" killed \"%s<%i><%s><%i>\" with \"%s\" (decapitated)\n", - STRING( pKiller->netname ), - GETPLAYERUSERID( ENT(pKiller) ), - GETPLAYERAUTHID( ENT(pKiller) ), - GETPLAYERUSERID( ENT(pKiller) ), - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GETPLAYERUSERID( pVictim->edict() ), - killer_weapon_name ); - - // Tell the client to display the death message - MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); - WRITE_BYTE( killer_index ); // the killer - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim - WRITE_STRING( "decapitate" ); // what they were killed by (should this be a string?) - MESSAGE_END(); - - // Bonus point for teleport hit - if ( iTele ) - pKiller->frags++; - - pKiller->frags += 1; - - // Bring up the reward window on the killer's screen - MESSAGE_BEGIN( MSG_ONE, gmsgReward, NULL, Killer->edict() ); - WRITE_SHORT( REWARD_DECAPITATE | iTele ); - MESSAGE_END(); - - return; - } - - // Otherwise, calculate number of disc bounces - if ( pVictim->m_iLastDiscBounces == 0 ) - { - // Bring up the reward window on the killer's screen - MESSAGE_BEGIN( MSG_ONE, gmsgReward, NULL, Killer->edict() ); - WRITE_SHORT( REWARD_BOUNCE_NONE | iTele ); - MESSAGE_END(); - } - else if ( pVictim->m_iLastDiscBounces == 1 ) - { - // Bring up the reward window on the killer's screen - MESSAGE_BEGIN( MSG_ONE, gmsgReward, NULL, Killer->edict() ); - WRITE_SHORT( REWARD_BOUNCE_ONE | iTele ); - MESSAGE_END(); - } - else - { - if ( pVictim->m_iLastDiscBounces == 2 ) - { - // Bring up the reward window on the killer's screen - MESSAGE_BEGIN( MSG_ONE, gmsgReward, NULL, Killer->edict() ); - WRITE_SHORT( REWARD_BOUNCE_TWO | iTele ); - MESSAGE_END(); - } - else - { - // Bring up the reward window on the killer's screen - MESSAGE_BEGIN( MSG_ONE, gmsgReward, NULL, Killer->edict() ); - WRITE_SHORT( REWARD_BOUNCE_THREE | iTele ); - MESSAGE_END(); - - // Cap the number of frags a killer can get to 4 - pVictim->m_iLastDiscBounces = 3; - } - } - - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" killed \"%s<%i><%s><%i>\" with \"%s\" (bounces \"%d\")\n", - STRING( pKiller->netname ), - GETPLAYERUSERID( ENT(pKiller) ), - GETPLAYERAUTHID( ENT(pKiller) ), - GETPLAYERUSERID( ENT(pKiller) ), - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GETPLAYERUSERID( pVictim->edict() ), - killer_weapon_name, - pVictim->m_iLastDiscBounces ); - - char sz[1024]; - sprintf( sz, "%dbounce", pVictim->m_iLastDiscBounces ); - - // Tell the client to display the death message - MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); - WRITE_BYTE( killer_index ); // the killer - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim - WRITE_STRING( sz ); // what they were killed by (should this be a string?) - MESSAGE_END(); - - pKiller->frags += (1 + pVictim->m_iLastDiscBounces); - - // Bonus point for teleport hit - if ( iTele ) - pKiller->frags++; - } - else - { - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" killed \"%s<%i><%s><%i>\" with \"%s\"\n", - STRING( pKiller->netname ), - GETPLAYERUSERID( ENT(pKiller) ), - GETPLAYERAUTHID( ENT(pKiller) ), - GETPLAYERUSERID( ENT(pKiller) ), - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GETPLAYERUSERID( pVictim->edict() ), - killer_weapon_name ); - - // Tell the client to display the death message - MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); - WRITE_BYTE( killer_index ); // the killer - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim - WRITE_STRING( killer_weapon_name ); // what they were killed by (should this be a string?) - MESSAGE_END(); - - pKiller->frags += 1; - } - } - else - { - pKiller->frags -= 1; - - // Fell to their death - UTIL_LogPrintf( "\"%s<%i><%s><%i>\" committed suicide with \"world\"\n", - STRING( pVictim->pev->netname ), - GETPLAYERUSERID( pVictim->edict() ), - GETPLAYERAUTHID( pVictim->edict() ), - GETPLAYERUSERID( pVictim->edict() ), - killer_weapon_name ); - - // Tell the client to display the death message - MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); - WRITE_BYTE( killer_index ); // the killer - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim - WRITE_STRING( "falling" ); // what they were killed by (should this be a string?) - MESSAGE_END(); - } - - return; -} - -//========================================================= -// PlayerGotWeapon - player has grabbed a weapon that was -// sitting in the world -//========================================================= -void CHalfLifeMultiplay :: PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ -} - -//========================================================= -// FlWeaponRespawnTime - what is the time in the future -// at which this weapon may spawn? -//========================================================= -float CHalfLifeMultiplay :: FlWeaponRespawnTime( CBasePlayerItem *pWeapon ) -{ - if ( CVAR_GET_FLOAT("mp_weaponstay") > 0 ) - { - // make sure it's only certain weapons - if ( !(pWeapon->iFlags() & ITEM_FLAG_LIMITINWORLD) ) - { - return gpGlobals->time + 0; // weapon respawns almost instantly - } - } - - return gpGlobals->time + WEAPON_RESPAWN_TIME; -} - -// when we are within this close to running out of entities, items -// marked with the ITEM_FLAG_LIMITINWORLD will delay their respawn -#define ENTITY_INTOLERANCE 100 - -//========================================================= -// FlWeaponRespawnTime - Returns 0 if the weapon can respawn -// now, otherwise it returns the time at which it can try -// to spawn again. -//========================================================= -float CHalfLifeMultiplay :: FlWeaponTryRespawn( CBasePlayerItem *pWeapon ) -{ - if ( pWeapon && pWeapon->m_iId && (pWeapon->iFlags() & ITEM_FLAG_LIMITINWORLD) ) - { - if ( NUMBER_OF_ENTITIES() < (gpGlobals->maxEntities - ENTITY_INTOLERANCE) ) - return 0; - - // we're past the entity tolerance level, so delay the respawn - return FlWeaponRespawnTime( pWeapon ); - } - - return 0; -} - -//========================================================= -// VecWeaponRespawnSpot - where should this weapon spawn? -// Some game variations may choose to randomize spawn locations -//========================================================= -Vector CHalfLifeMultiplay :: VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ) -{ - return pWeapon->pev->origin; -} - -//========================================================= -// WeaponShouldRespawn - any conditions inhibiting the -// respawning of this weapon? -//========================================================= -int CHalfLifeMultiplay :: WeaponShouldRespawn( CBasePlayerItem *pWeapon ) -{ - if ( pWeapon->pev->spawnflags & SF_NORESPAWN ) - { - return GR_WEAPON_RESPAWN_NO; - } - - return GR_WEAPON_RESPAWN_YES; -} - -//========================================================= -// CanHaveWeapon - returns FALSE if the player is not allowed -// to pick up this weapon -//========================================================= -BOOL CHalfLifeMultiplay::CanHavePlayerItem( CBasePlayer *pPlayer, CBasePlayerItem *pItem ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay::PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ) -{ -} - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::ItemShouldRespawn( CItem *pItem ) -{ - if ( pItem->pev->spawnflags & SF_NORESPAWN ) - { - return GR_ITEM_RESPAWN_NO; - } - - return GR_ITEM_RESPAWN_YES; -} - - -//========================================================= -// At what time in the future may this Item respawn? -//========================================================= -float CHalfLifeMultiplay::FlItemRespawnTime( CItem *pItem ) -{ - return gpGlobals->time + ITEM_RESPAWN_TIME; -} - -//========================================================= -// Where should this item respawn? -// Some game variations may choose to randomize spawn locations -//========================================================= -Vector CHalfLifeMultiplay::VecItemRespawnSpot( CItem *pItem ) -{ - return pItem->pev->origin; -} - -//========================================================= -//========================================================= -void CHalfLifeMultiplay::PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ) -{ -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay::IsAllowedToSpawn( CBaseEntity *pEntity ) -{ -// if ( pEntity->pev->flags & FL_MONSTER ) -// return FALSE; - - return TRUE; -} - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ) -{ - if ( pAmmo->pev->spawnflags & SF_NORESPAWN ) - { - return GR_AMMO_RESPAWN_NO; - } - - return GR_AMMO_RESPAWN_YES; -} - -//========================================================= -//========================================================= -float CHalfLifeMultiplay::FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ) -{ - return gpGlobals->time + AMMO_RESPAWN_TIME; -} - -//========================================================= -//========================================================= -Vector CHalfLifeMultiplay::VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ) -{ - return pAmmo->pev->origin; -} - -//========================================================= -//========================================================= -float CHalfLifeMultiplay::FlHealthChargerRechargeTime( void ) -{ - return 60; -} - - -float CHalfLifeMultiplay::FlHEVChargerRechargeTime( void ) -{ - return 30; -} - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::DeadPlayerWeapons( CBasePlayer *pPlayer ) -{ - return GR_PLR_DROP_GUN_ACTIVE; -} - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::DeadPlayerAmmo( CBasePlayer *pPlayer ) -{ - return GR_PLR_DROP_AMMO_ACTIVE; -} - -edict_t *CHalfLifeMultiplay::GetPlayerSpawnSpot( CBasePlayer *pPlayer ) -{ - edict_t *pentSpawnSpot = CGameRules::GetPlayerSpawnSpot( pPlayer ); - if ( IsMultiplayer() && pentSpawnSpot->v.target ) - { - FireTargets( STRING(pentSpawnSpot->v.target), pPlayer, pPlayer, USE_TOGGLE, 0 ); - } - - return pentSpawnSpot; -} - - -//========================================================= -//========================================================= -int CHalfLifeMultiplay::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) -{ - // half life deathmatch has only enemies - return GR_NOTTEAMMATE; -} - -BOOL CHalfLifeMultiplay :: PlayFootstepSounds( CBasePlayer *pl, float fvol ) -{ - if ( g_footsteps && g_footsteps->value == 0 ) - return FALSE; - - if ( pl->IsOnLadder() || pl->pev->velocity.Length2D() > 220 ) - return TRUE; // only make step sounds in multiplayer if the player is moving fast enough - - return FALSE; -} - -BOOL CHalfLifeMultiplay :: FAllowFlashlight( void ) -{ - return CVAR_GET_FLOAT( "mp_flashlight" ) != 0; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeMultiplay :: FAllowMonsters( void ) -{ - return ( CVAR_GET_FLOAT( "mp_allowmonsters" ) != 0 ); -} - -//========================================================= -//======== CHalfLifeMultiplay private functions =========== -#define INTERMISSION_TIME 6 - -void CHalfLifeMultiplay :: GoToIntermission( void ) -{ - if ( g_fGameOver ) - return; // intermission has already been triggered, so ignore. - - MESSAGE_BEGIN(MSG_ALL, SVC_INTERMISSION); - MESSAGE_END(); - - m_flIntermissionEndTime = gpGlobals->time + INTERMISSION_TIME; - g_fGameOver = TRUE; - m_iEndIntermissionButtonHit = FALSE; -} - -#define MAX_RULE_BUFFER 1024 - -typedef struct mapcycle_item_s -{ - struct mapcycle_item_s *next; - - char mapname[ 32 ]; - int minplayers, maxplayers; - char rulebuffer[ MAX_RULE_BUFFER ]; -} mapcycle_item_t; - -typedef struct mapcycle_s -{ - struct mapcycle_item_s *items; - struct mapcycle_item_s *next_item; -} mapcycle_t; - -/* -============== -DestroyMapCycle - -Clean up memory used by mapcycle when switching it -============== -*/ -void DestroyMapCycle( mapcycle_t *cycle ) -{ - mapcycle_item_t *p, *n, *start; - p = cycle->items; - if ( p ) - { - start = p; - p = p->next; - while ( p != start ) - { - n = p->next; - delete p; - p = n; - } - - delete cycle->items; - } - cycle->items = NULL; - cycle->next_item = NULL; -} - -static char com_token[ 1500 ]; - -/* -============== -COM_Parse - -Parse a token out of a string -============== -*/ -char *COM_Parse (char *data) -{ - int c; - int len; - - len = 0; - com_token[0] = 0; - - if (!data) - return NULL; - -// skip whitespace -skipwhite: - while ( (c = *data) <= ' ') - { - if (c == 0) - return NULL; // end of file; - data++; - } - -// skip // comments - if (c=='/' && data[1] == '/') - { - while (*data && *data != '\n') - data++; - goto skipwhite; - } - - -// handle quoted strings specially - if (c == '\"') - { - data++; - while (1) - { - c = *data++; - if (c=='\"' || !c) - { - com_token[len] = 0; - return data; - } - com_token[len] = c; - len++; - } - } - -// parse single characters - if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' ) - { - com_token[len] = c; - len++; - com_token[len] = 0; - return data+1; - } - -// parse a regular word - do - { - com_token[len] = c; - data++; - len++; - c = *data; - if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c == ',' ) - break; - } while (c>32); - - com_token[len] = 0; - return data; -} - -/* -============== -COM_TokenWaiting - -Returns 1 if additional data is waiting to be processed on this line -============== -*/ -int COM_TokenWaiting( char *buffer ) -{ - char *p; - - p = buffer; - while ( *p && *p!='\n') - { - if ( !isspace( *p ) || isalnum( *p ) ) - return 1; - - p++; - } - - return 0; -} - -/* -============== -ReloadMapCycleFile - - -Parses mapcycle.txt file into mapcycle_t structure -============== -*/ -int ReloadMapCycleFile( char *filename, mapcycle_t *cycle ) -{ - char szBuffer[ MAX_RULE_BUFFER ]; - char szMap[ 32 ]; - int length; - char *pFileList; - char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( filename, &length ); - int hasbuffer; - mapcycle_item_s *item, *newlist = NULL, *next; - - if ( pFileList && length ) - { - // the first map name in the file becomes the default - while ( 1 ) - { - hasbuffer = 0; - memset( szBuffer, 0, MAX_RULE_BUFFER ); - - pFileList = COM_Parse( pFileList ); - if ( strlen( com_token ) <= 0 ) - break; - - strcpy( szMap, com_token ); - - // Any more tokens on this line? - if ( COM_TokenWaiting( pFileList ) ) - { - pFileList = COM_Parse( pFileList ); - if ( strlen( com_token ) > 0 ) - { - hasbuffer = 1; - strcpy( szBuffer, com_token ); - } - } - - // Check map - if ( IS_MAP_VALID( szMap ) ) - { - // Create entry - char *s; - - item = new mapcycle_item_s; - - strcpy( item->mapname, szMap ); - - item->minplayers = 0; - item->maxplayers = 0; - - memset( item->rulebuffer, 0, MAX_RULE_BUFFER ); - - if ( hasbuffer ) - { - s = g_engfuncs.pfnInfoKeyValue( szBuffer, "minplayers" ); - if ( s && s[0] ) - { - item->minplayers = atoi( s ); - item->minplayers = V_max( item->minplayers, 0 ); - item->minplayers = V_min( item->minplayers, gpGlobals->maxClients ); - } - s = g_engfuncs.pfnInfoKeyValue( szBuffer, "maxplayers" ); - if ( s && s[0] ) - { - item->maxplayers = atoi( s ); - item->maxplayers = V_max( item->maxplayers, 0 ); - item->maxplayers = V_min( item->maxplayers, gpGlobals->maxClients ); - } - - // Remove keys - // - g_engfuncs.pfnInfo_RemoveKey( szBuffer, "minplayers" ); - g_engfuncs.pfnInfo_RemoveKey( szBuffer, "maxplayers" ); - - strcpy( item->rulebuffer, szBuffer ); - } - - item->next = cycle->items; - cycle->items = item; - } - else - { - ALERT( at_console, "Skipping %s from mapcycle, not a valid map\n", szMap ); - } - - - } - - FREE_FILE( aFileList ); - } - - // Fixup circular list pointer - item = cycle->items; - - // Reverse it to get original order - while ( item ) - { - next = item->next; - item->next = newlist; - newlist = item; - item = next; - } - cycle->items = newlist; - item = cycle->items; - - // Didn't parse anything - if ( !item ) - { - return 0; - } - - while ( item->next ) - { - item = item->next; - } - item->next = cycle->items; - - cycle->next_item = item->next; - - return 1; -} - -/* -============== -CountPlayers - -Determine the current # of active players on the server for map cycling logic -============== -*/ -int CountPlayers( void ) -{ - int num = 0; - - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pEnt = UTIL_PlayerByIndex( i ); - - if ( pEnt ) - { - num = num + 1; - } - } - - return num; -} - -/* -============== -ExtractCommandString - -Parse commands/key value pairs to issue right after map xxx command is issued on server - level transition -============== -*/ -void ExtractCommandString( char *s, char *szCommand ) -{ - // Now make rules happen - char pkey[512]; - char value[512]; // use two buffers so compares - // work without stomping on each other - char *o; - - if ( *s == '\\' ) - s++; - - while (1) - { - o = pkey; - while ( *s != '\\' ) - { - if ( !*s ) - return; - *o++ = *s++; - } - *o = 0; - s++; - - o = value; - - while (*s != '\\' && *s) - { - if (!*s) - return; - *o++ = *s++; - } - *o = 0; - - strcat( szCommand, pkey ); - if ( strlen( value ) > 0 ) - { - strcat( szCommand, " " ); - strcat( szCommand, value ); - } - strcat( szCommand, "\n" ); - - if (!*s) - return; - s++; - } -} - -/* -============== -ChangeLevel - -Server is changing to a new level, check mapcycle.txt for map name and setup info -============== -*/ -void CHalfLifeMultiplay :: ChangeLevel( void ) -{ - static char szPreviousMapCycleFile[ 256 ]; - static mapcycle_t mapcycle; - - char szNextMap[32]; - char szFirstMapInList[32]; - char szCommands[ 1500 ]; - char szRules[ 1500 ]; - int minplayers = 0, maxplayers = 0; - strcpy( szFirstMapInList, "hldm1" ); // the absolute default level is hldm1 - - int curplayers; - BOOL do_cycle = TRUE; - - // find the map to change to - char *mapcfile = (char*)CVAR_GET_STRING( "mapcyclefile" ); - ASSERT( mapcfile != NULL ); - - szCommands[ 0 ] = '\0'; - szRules[ 0 ] = '\0'; - - curplayers = CountPlayers(); - - // Has the map cycle filename changed? - if ( stricmp( mapcfile, szPreviousMapCycleFile ) ) - { - strcpy( szPreviousMapCycleFile, mapcfile ); - - DestroyMapCycle( &mapcycle ); - - if ( !ReloadMapCycleFile( mapcfile, &mapcycle ) || ( !mapcycle.items ) ) - { - ALERT( at_console, "Unable to load map cycle file %s\n", mapcfile ); - do_cycle = FALSE; - } - } - - if ( do_cycle && mapcycle.items ) - { - BOOL keeplooking = FALSE; - BOOL found = FALSE; - mapcycle_item_s *item; - - // Assume current map - strcpy( szNextMap, STRING(gpGlobals->mapname) ); - strcpy( szFirstMapInList, STRING(gpGlobals->mapname) ); - - // Traverse list - for ( item = mapcycle.next_item; item->next != mapcycle.next_item; item = item->next ) - { - keeplooking = FALSE; - - ASSERT( item != NULL ); - - if ( item->minplayers != 0 ) - { - if ( curplayers >= item->minplayers ) - { - found = TRUE; - minplayers = item->minplayers; - } - else - { - keeplooking = TRUE; - } - } - - if ( item->maxplayers != 0 ) - { - if ( curplayers <= item->maxplayers ) - { - found = TRUE; - maxplayers = item->maxplayers; - } - else - { - keeplooking = TRUE; - } - } - - if ( keeplooking ) - continue; - - found = TRUE; - break; - } - - if ( !found ) - { - item = mapcycle.next_item; - } - - // Increment next item pointer - mapcycle.next_item = item->next; - - // Perform logic on current item - strcpy( szNextMap, item->mapname ); - - ExtractCommandString( item->rulebuffer, szCommands ); - strcpy( szRules, item->rulebuffer ); - } - - if ( !IS_MAP_VALID(szNextMap) ) - { - strcpy( szNextMap, szFirstMapInList ); - } - - g_fGameOver = TRUE; - - ALERT( at_console, "CHANGE LEVEL: %s\n", szNextMap ); - if ( minplayers || maxplayers ) - { - ALERT( at_console, "PLAYER COUNT: min %i max %i current %i\n", minplayers, maxplayers, curplayers ); - } - if ( strlen( szRules ) > 0 ) - { - ALERT( at_console, "RULES: %s\n", szRules ); - } - - CHANGE_LEVEL( szNextMap, NULL ); - if ( strlen( szCommands ) > 0 ) - { - SERVER_COMMAND( szCommands ); - } -} - -#define MAX_MOTD_CHUNK 60 -#define MAX_MOTD_LENGTH (MAX_MOTD_CHUNK * 4) - -void CHalfLifeMultiplay :: SendMOTDToClient( edict_t *client ) -{ - // read from the MOTD.txt file - int length, char_count = 0; - char *pFileList; - char *aFileList = pFileList = (char*)LOAD_FILE_FOR_ME( "motd.txt", &length ); - - // Send the message of the day - // read it chunk-by-chunk, and send it in parts - - while ( pFileList && *pFileList && char_count < MAX_MOTD_LENGTH ) - { - char chunk[MAX_MOTD_CHUNK+1]; - - if ( strlen( pFileList ) < MAX_MOTD_CHUNK ) - { - strcpy( chunk, pFileList ); - } - else - { - strncpy( chunk, pFileList, MAX_MOTD_CHUNK ); - chunk[MAX_MOTD_CHUNK] = 0; // strncpy doesn't always append the null terminator - } - - char_count += strlen( chunk ); - if ( char_count < MAX_MOTD_LENGTH ) - pFileList = aFileList + char_count; - else - *pFileList = 0; - - MESSAGE_BEGIN( MSG_ONE, gmsgMOTD, NULL, client ); - WRITE_BYTE( *pFileList ? FALSE : TRUE ); // FALSE means there is still more message to come - WRITE_STRING( chunk ); - MESSAGE_END(); - } - - FREE_FILE( aFileList ); -} - - diff --git a/ricochet/dlls/nodes.h b/ricochet/dlls/nodes.h deleted file mode 100644 index d6dbbd8..0000000 --- a/ricochet/dlls/nodes.h +++ /dev/null @@ -1,54 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -//========================================================= -// nodes.h -//========================================================= - -#ifndef NODES_H -#define NODES_H - -#define bits_NODE_GROUP_REALM 1 - -class CLink -{ -public: - entvars_t *m_pLinkEnt;// the entity that blocks this connection (doors, etc) -}; - - -class CGraph -{ -public: - BOOL m_fGraphPresent;// is the graph in memory? - BOOL m_fGraphPointersSet;// are the entity pointers for the graph all set? - - int m_cLinks;// total number of links - CLink *m_pLinkPool;// big list of all node connections - - void InitGraph( void ); - int AllocNodes ( void ); - - int CheckNODFile(char *szMapName); - int FLoadGraph(char *szMapName); - int FSetGraphPointers(void); - void ShowNodeConnections ( int iNode ); - int FindNearestNode ( const Vector &vecOrigin, CBaseEntity *pEntity ); - int FindNearestNode ( const Vector &vecOrigin, int afNodeTypes ); - -}; - -extern CGraph WorldGraph; - -#endif // NODES_H diff --git a/ricochet/dlls/observer.cpp b/ricochet/dlls/observer.cpp deleted file mode 100644 index 7ba4505..0000000 --- a/ricochet/dlls/observer.cpp +++ /dev/null @@ -1,325 +0,0 @@ -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= -// observer.cpp -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" - -extern int gmsgCurWeapon; -extern int gmsgSetFOV; -extern int gmsgTeamInfo; -extern int gmsgSpectator; - -// Player has become a spectator. Set it up. -// This was moved from player.cpp. -void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) -{ - // clear any clientside entities attached to this player - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); - WRITE_BYTE( TE_KILLPLAYERATTACHMENTS ); - WRITE_BYTE( (BYTE)entindex() ); - MESSAGE_END(); - - // Holster weapon immediately, to allow it to cleanup - if (m_pActiveItem) - m_pActiveItem->Holster( ); - - if ( m_pTank != NULL ) - { - m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - } - - // clear out the suit message cache so we don't keep chattering - SetSuitUpdate(NULL, FALSE, 0); - - // Tell Ammo Hud that the player is dead - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); - WRITE_BYTE(0); - WRITE_BYTE(0XFF); - WRITE_BYTE(0xFF); - MESSAGE_END(); - - // reset FOV - m_iFOV = m_iClientFOV = 0; - pev->fov = m_iFOV; - MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev ); - WRITE_BYTE(0); - MESSAGE_END(); - - // Setup flags - m_iHideHUD = (HIDEHUD_HEALTH | HIDEHUD_WEAPONS); - m_afPhysicsFlags |= PFLAG_OBSERVER; - pev->effects = EF_NODRAW; - pev->view_ofs = g_vecZero; - pev->solid = SOLID_NOT; - pev->takedamage = DAMAGE_NO; - pev->movetype = MOVETYPE_NONE; - ClearBits( m_afPhysicsFlags, PFLAG_DUCKING ); - ClearBits( pev->flags, FL_DUCKING ); - pev->deadflag = DEAD_RESPAWNABLE; - pev->health = 1; - - // Clear out the status bar - m_fInitHUD = TRUE; - - // Update Team Status - MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo ); - WRITE_BYTE( ENTINDEX(edict()) ); - WRITE_STRING( "" ); - MESSAGE_END(); - - // Remove all the player's stuff - RemoveAllItems( FALSE ); - - // Move them to the new position - UTIL_SetOrigin( pev, vecPosition ); - - // Find a player to watch - m_flNextObserverInput = 0; - Observer_SetMode(OBS_ROAMING); - - // Tell all clients this player is now a spectator - MESSAGE_BEGIN( MSG_ALL, gmsgSpectator ); - WRITE_BYTE( ENTINDEX( edict() ) ); - WRITE_BYTE( 1 ); - MESSAGE_END(); - - pev->angles = pev->v_angle = vecViewAngle; - pev->fixangle = TRUE; -} - -// Leave observer mode -void CBasePlayer::StopObserver( void ) -{ - // Turn off spectator - if ( pev->iuser1 || pev->iuser2 ) - { - // Tell all clients this player is not a spectator anymore - MESSAGE_BEGIN( MSG_ALL, gmsgSpectator ); - WRITE_BYTE( ENTINDEX( edict() ) ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - - pev->iuser1 = pev->iuser2 = 0; - m_hObserverTarget = NULL; - } - - m_fWeapon = FALSE; // force weapon send - m_iHideHUD = 0; -} - -// Find the next client in the game for this player to spectate -void CBasePlayer::Observer_FindNextPlayer( bool bReverse ) -{ - // MOD AUTHORS: Modify the logic of this function if you want to restrict the observer to watching - // only a subset of the players. e.g. Make it check the target's team. - - int iStart; - if ( m_hObserverTarget ) - iStart = ENTINDEX( m_hObserverTarget->edict() ); - else - iStart = ENTINDEX( edict() ); - int iCurrent = iStart; - m_hObserverTarget = NULL; - int iDir = bReverse ? -1 : 1; - - do - { - iCurrent += iDir; - - // Loop through the clients - if (iCurrent > gpGlobals->maxClients) - iCurrent = 1; - if (iCurrent < 1) - iCurrent = gpGlobals->maxClients; - - CBaseEntity *pEnt = UTIL_PlayerByIndex( iCurrent ); - if ( !pEnt ) - continue; - if ( pEnt == this ) - continue; - // Don't spec observers or invisible players - if ( ((CBasePlayer*)pEnt)->IsObserver() || (pEnt->pev->effects & EF_NODRAW) ) - continue; - - // MOD AUTHORS: Add checks on target here. - - m_hObserverTarget = pEnt; - break; - - } while ( iCurrent != iStart ); - - // Did we find a target? - if ( m_hObserverTarget ) - { - // Store the target in pev so the physics DLL can get to it - pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); - pev->groupinfo = m_hObserverTarget->pev->groupinfo; - - // Move to the target - if ( pev->iuser1 != OBS_LOCKEDVIEW ) - UTIL_SetOrigin( pev, m_hObserverTarget->pev->origin ); - - ALERT( at_console, "Now Tracking %s\n", STRING( m_hObserverTarget->pev->netname ) ); - } - else - { - ALERT( at_console, "No observer targets.\n" ); - } -} - -void CBasePlayer::ObserverInput_ChangeMode() -{ - if ( pev->iuser1 == OBS_ROAMING ) - Observer_SetMode( OBS_CHASE_FREE ); - else if ( pev->iuser1 == OBS_CHASE_FREE ) - Observer_SetMode( OBS_LOCKEDVIEW ); - else - Observer_SetMode( OBS_ROAMING ); -} - -void CBasePlayer::ObserverInput_NextPlayer() -{ - if ( pev->iuser1 != OBS_ROAMING ) - Observer_FindNextPlayer( false ); -} - -void CBasePlayer::ObserverInput_PrevPlayer() -{ - if ( pev->iuser1 != OBS_ROAMING ) - Observer_FindNextPlayer( true ); -} - -// Handle buttons in observer mode -void CBasePlayer::Observer_HandleButtons() -{ - - if ( m_flChangeAngles != -1 && m_flChangeAngles <= gpGlobals->time ) - { - if ( pev->iuser1 == OBS_LOCKEDVIEW ) - { - pev->angles = m_vecHitVelocity; - pev->fixangle = TRUE; - } - - m_flChangeAngles = -1; - } - - return; - - // Slow down mouse clicks - if ( m_flNextObserverInput > gpGlobals->time ) - return; - - // Jump changes from modes: Chase to Roaming - if ( m_afButtonPressed & IN_JUMP ) - { - if ( pev->iuser1 == OBS_ROAMING ) - Observer_SetMode( OBS_CHASE_FREE ); - else if ( pev->iuser1 == OBS_CHASE_FREE ) - Observer_SetMode( OBS_LOCKEDVIEW ); - else - Observer_SetMode( OBS_ROAMING ); - - m_flNextObserverInput = gpGlobals->time + 0.2; - } - - // Attack moves to the next player - if ( m_afButtonPressed & IN_ATTACK && pev->iuser1 != OBS_ROAMING ) - { - Observer_FindNextPlayer( false ); - - m_flNextObserverInput = gpGlobals->time + 0.2; - } - - // Attack2 moves to the prev player - if ( m_afButtonPressed & IN_ATTACK2 && pev->iuser1 != OBS_ROAMING ) - { - Observer_FindNextPlayer( true ); - - m_flNextObserverInput = gpGlobals->time + 0.2; - } -} - -// Attempt to change the observer mode -void CBasePlayer::Observer_SetMode( int iMode ) -{ - // Just abort if we're changing to the mode we're already in - if ( iMode == pev->iuser1 ) - return; - - // Changing to Roaming? - if ( iMode == OBS_ROAMING ) - { - // MOD AUTHORS: If you don't want to allow roaming observers at all in your mod, just abort here. - pev->iuser1 = OBS_ROAMING; - pev->iuser2 = 0; - pev->maxspeed = 320; - - ClientPrint( pev, HUD_PRINTCENTER, "#Spec_Mode3" ); - return; - } - - if ( iMode == OBS_LOCKEDVIEW ) - { - // Find the spectator spawn position - CBaseEntity *pSpot = UTIL_FindEntityByClassname( NULL, "info_player_spectator"); - - if ( pSpot ) - { - // Move them to the new position - UTIL_SetOrigin( pev, pSpot->pev->origin ); - - pev->iuser1 = OBS_LOCKEDVIEW; - - m_flChangeAngles = gpGlobals->time + 0.1; - m_vecHitVelocity = pSpot->pev->v_angle; - pev->iuser2 = 0; - pev->maxspeed = 1; - } - - return; - } - - // Changing to Chase Freelook? - if ( iMode == OBS_CHASE_FREE ) - { - // If changing from Roaming, or starting observing, make sure there is a target - if ( m_hObserverTarget == NULL ) - Observer_FindNextPlayer( false ); - - if (m_hObserverTarget) - { - pev->iuser1 = OBS_CHASE_FREE; - pev->iuser2 = ENTINDEX( m_hObserverTarget->edict() ); - ClientPrint( pev, HUD_PRINTCENTER, "#Spec_Mode2" ); - pev->maxspeed = 1; - } - else - { - ClientPrint( pev, HUD_PRINTCENTER, "#Spec_NoTarget" ); - Observer_SetMode(OBS_ROAMING); - } - - return; - } -} diff --git a/ricochet/dlls/pathcorner.cpp b/ricochet/dlls/pathcorner.cpp deleted file mode 100644 index 173b960..0000000 --- a/ricochet/dlls/pathcorner.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// ========================== PATH_CORNER =========================== -// - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "trains.h" -#include "saverestore.h" - -class CPathCorner : public CPointEntity -{ -public: - void Spawn( ); - void KeyValue( KeyValueData* pkvd ); - float GetDelay( void ) { return m_flWait; } -// void Touch( CBaseEntity *pOther ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - float m_flWait; -}; - -LINK_ENTITY_TO_CLASS( path_corner, CPathCorner ); - -// Global Savedata for Delay -TYPEDESCRIPTION CPathCorner::m_SaveData[] = -{ - DEFINE_FIELD( CPathCorner, m_flWait, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CPathCorner, CPointEntity ); - -// -// Cache user-entity-field values until spawn is called. -// -void CPathCorner :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - - -void CPathCorner :: Spawn( ) -{ - ASSERTSZ(!FStringNull(pev->targetname), "path_corner without a targetname"); -} - -#if 0 -void CPathCorner :: Touch( CBaseEntity *pOther ) -{ - entvars_t* pevToucher = pOther->pev; - - if ( FBitSet ( pevToucher->flags, FL_MONSTER ) ) - {// monsters don't navigate path corners based on touch anymore - return; - } - - // If OTHER isn't explicitly looking for this path_corner, bail out - if ( pOther->m_pGoalEnt != this ) - { - return; - } - - // If OTHER has an enemy, this touch is incidental, ignore - if ( !FNullEnt(pevToucher->enemy) ) - { - return; // fighting, not following a path - } - - // UNDONE: support non-zero flWait - /* - if (m_flWait != 0) - ALERT(at_warning, "Non-zero path-cornder waits NYI"); - */ - - // Find the next "stop" on the path, make it the goal of the "toucher". - if (FStringNull(pev->target)) - { - ALERT(at_warning, "PathCornerTouch: no next stop specified"); - } - - pOther->m_pGoalEnt = CBaseEntity::Instance( FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(pev->target) ) ); - - // If "next spot" was not found (does not exist - level design error) - if ( !pOther->m_pGoalEnt ) - { - ALERT(at_console, "PathCornerTouch--%s couldn't find next stop in path: %s", STRING(pev->classname), STRING(pev->target)); - return; - } - - // Turn towards the next stop in the path. - pevToucher->ideal_yaw = UTIL_VecToYaw ( pOther->m_pGoalEnt->pev->origin - pevToucher->origin ); -} -#endif - - - -TYPEDESCRIPTION CPathTrack::m_SaveData[] = -{ - DEFINE_FIELD( CPathTrack, m_length, FIELD_FLOAT ), - DEFINE_FIELD( CPathTrack, m_pnext, FIELD_CLASSPTR ), - DEFINE_FIELD( CPathTrack, m_paltpath, FIELD_CLASSPTR ), - DEFINE_FIELD( CPathTrack, m_pprevious, FIELD_CLASSPTR ), - DEFINE_FIELD( CPathTrack, m_altName, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CPathTrack, CBaseEntity ); -LINK_ENTITY_TO_CLASS( path_track, CPathTrack ); - -// -// Cache user-entity-field values until spawn is called. -// -void CPathTrack :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "altpath")) - { - m_altName = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -void CPathTrack :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int on; - - // Use toggles between two paths - if ( m_paltpath ) - { - on = !FBitSet( pev->spawnflags, SF_PATH_ALTERNATE ); - if ( ShouldToggle( useType, on ) ) - { - if ( on ) - SetBits( pev->spawnflags, SF_PATH_ALTERNATE ); - else - ClearBits( pev->spawnflags, SF_PATH_ALTERNATE ); - } - } - else // Use toggles between enabled/disabled - { - on = !FBitSet( pev->spawnflags, SF_PATH_DISABLED ); - - if ( ShouldToggle( useType, on ) ) - { - if ( on ) - SetBits( pev->spawnflags, SF_PATH_DISABLED ); - else - ClearBits( pev->spawnflags, SF_PATH_DISABLED ); - } - } -} - - -void CPathTrack :: Link( void ) -{ - edict_t *pentTarget; - - if ( !FStringNull(pev->target) ) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->target) ); - if ( !FNullEnt(pentTarget) ) - { - m_pnext = CPathTrack::Instance( pentTarget ); - - if ( m_pnext ) // If no next pointer, this is the end of a path - { - m_pnext->SetPrevious( this ); - } - } - else - ALERT( at_console, "Dead end link %s\n", STRING(pev->target) ); - } - - // Find "alternate" path - if ( m_altName ) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_altName) ); - if ( !FNullEnt(pentTarget) ) - { - m_paltpath = CPathTrack::Instance( pentTarget ); - - if ( m_paltpath ) // If no next pointer, this is the end of a path - { - m_paltpath->SetPrevious( this ); - } - } - } -} - - -void CPathTrack :: Spawn( void ) -{ - pev->solid = SOLID_TRIGGER; - UTIL_SetSize(pev, Vector(-8, -8, -8), Vector(8, 8, 8)); - - m_pnext = NULL; - m_pprevious = NULL; -// DEBUGGING CODE -#if PATH_SPARKLE_DEBUG - SetThink( Sparkle ); - pev->nextthink = gpGlobals->time + 0.5; -#endif -} - - -void CPathTrack::Activate( void ) -{ - if ( !FStringNull( pev->targetname ) ) // Link to next, and back-link - Link(); -} - -CPathTrack *CPathTrack :: ValidPath( CPathTrack *ppath, int testFlag ) -{ - if ( !ppath ) - return NULL; - - if ( testFlag && FBitSet( ppath->pev->spawnflags, SF_PATH_DISABLED ) ) - return NULL; - - return ppath; -} - - -void CPathTrack :: Project( CPathTrack *pstart, CPathTrack *pend, Vector *origin, float dist ) -{ - if ( pstart && pend ) - { - Vector dir = (pend->pev->origin - pstart->pev->origin); - dir = dir.Normalize(); - *origin = pend->pev->origin + dir * dist; - } -} - -CPathTrack *CPathTrack::GetNext( void ) -{ - if ( m_paltpath && FBitSet( pev->spawnflags, SF_PATH_ALTERNATE ) && !FBitSet( pev->spawnflags, SF_PATH_ALTREVERSE ) ) - return m_paltpath; - - return m_pnext; -} - - - -CPathTrack *CPathTrack::GetPrevious( void ) -{ - if ( m_paltpath && FBitSet( pev->spawnflags, SF_PATH_ALTERNATE ) && FBitSet( pev->spawnflags, SF_PATH_ALTREVERSE ) ) - return m_paltpath; - - return m_pprevious; -} - - - -void CPathTrack::SetPrevious( CPathTrack *pprev ) -{ - // Only set previous if this isn't my alternate path - if ( pprev && !FStrEq( STRING(pprev->pev->targetname), STRING(m_altName) ) ) - m_pprevious = pprev; -} - - -// Assumes this is ALWAYS enabled -CPathTrack *CPathTrack :: LookAhead( Vector *origin, float dist, int move ) -{ - CPathTrack *pcurrent; - float originalDist = dist; - - pcurrent = this; - Vector currentPos = *origin; - - if ( dist < 0 ) // Travelling backwards through path - { - dist = -dist; - while ( dist > 0 ) - { - Vector dir = pcurrent->pev->origin - currentPos; - float length = dir.Length(); - if ( !length ) - { - if ( !ValidPath(pcurrent->GetPrevious(), move) ) // If there is no previous node, or it's disabled, return now. - { - if ( !move ) - Project( pcurrent->GetNext(), pcurrent, origin, dist ); - return NULL; - } - pcurrent = pcurrent->GetPrevious(); - } - else if ( length > dist ) // enough left in this path to move - { - *origin = currentPos + (dir * (dist / length)); - return pcurrent; - } - else - { - dist -= length; - currentPos = pcurrent->pev->origin; - *origin = currentPos; - if ( !ValidPath(pcurrent->GetPrevious(), move) ) // If there is no previous node, or it's disabled, return now. - return NULL; - - pcurrent = pcurrent->GetPrevious(); - } - } - *origin = currentPos; - return pcurrent; - } - else - { - while ( dist > 0 ) - { - if ( !ValidPath(pcurrent->GetNext(), move) ) // If there is no next node, or it's disabled, return now. - { - if ( !move ) - Project( pcurrent->GetPrevious(), pcurrent, origin, dist ); - return NULL; - } - Vector dir = pcurrent->GetNext()->pev->origin - currentPos; - float length = dir.Length(); - if ( !length && !ValidPath( pcurrent->GetNext()->GetNext(), move ) ) - { - if ( dist == originalDist ) // HACK -- up against a dead end - return NULL; - return pcurrent; - } - if ( length > dist ) // enough left in this path to move - { - *origin = currentPos + (dir * (dist / length)); - return pcurrent; - } - else - { - dist -= length; - currentPos = pcurrent->GetNext()->pev->origin; - pcurrent = pcurrent->GetNext(); - *origin = currentPos; - } - } - *origin = currentPos; - } - - return pcurrent; -} - - -// Assumes this is ALWAYS enabled -CPathTrack *CPathTrack :: Nearest( Vector origin ) -{ - int deadCount; - float minDist, dist; - Vector delta; - CPathTrack *ppath, *pnearest; - - - delta = origin - pev->origin; - delta.z = 0; - minDist = delta.Length(); - pnearest = this; - ppath = GetNext(); - - // Hey, I could use the old 2 racing pointers solution to this, but I'm lazy :) - deadCount = 0; - while ( ppath && ppath != this ) - { - deadCount++; - if ( deadCount > 9999 ) - { - ALERT( at_error, "Bad sequence of path_tracks from %s", STRING(pev->targetname) ); - return NULL; - } - delta = origin - ppath->pev->origin; - delta.z = 0; - dist = delta.Length(); - if ( dist < minDist ) - { - minDist = dist; - pnearest = ppath; - } - ppath = ppath->GetNext(); - } - return pnearest; -} - - -CPathTrack *CPathTrack::Instance( edict_t *pent ) -{ - if ( FClassnameIs( pent, "path_track" ) ) - return (CPathTrack *)GET_PRIVATE(pent); - return NULL; -} - - - // DEBUGGING CODE -#if PATH_SPARKLE_DEBUG -void CPathTrack :: Sparkle( void ) -{ - - pev->nextthink = gpGlobals->time + 0.2; - if ( FBitSet( pev->spawnflags, SF_PATH_DISABLED ) ) - UTIL_ParticleEffect(pev->origin, Vector(0,0,100), 210, 10); - else - UTIL_ParticleEffect(pev->origin, Vector(0,0,100), 84, 10); -} -#endif - diff --git a/ricochet/dlls/plane.cpp b/ricochet/dlls/plane.cpp deleted file mode 100644 index 77e2273..0000000 --- a/ricochet/dlls/plane.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "plane.h" - -//========================================================= -// Plane -//========================================================= -CPlane :: CPlane ( void ) -{ - m_fInitialized = FALSE; -} - -//========================================================= -// InitializePlane - Takes a normal for the plane and a -// point on the plane and -//========================================================= -void CPlane :: InitializePlane ( const Vector &vecNormal, const Vector &vecPoint ) -{ - m_vecNormal = vecNormal; - m_flDist = DotProduct ( m_vecNormal, vecPoint ); - m_fInitialized = TRUE; -} - - -//========================================================= -// PointInFront - determines whether the given vector is -// in front of the plane. -//========================================================= -BOOL CPlane :: PointInFront ( const Vector &vecPoint ) -{ - float flFace; - - if ( !m_fInitialized ) - { - return FALSE; - } - - flFace = DotProduct ( m_vecNormal, vecPoint ) - m_flDist; - - if ( flFace >= 0 ) - { - return TRUE; - } - - return FALSE; -} - diff --git a/ricochet/dlls/plane.h b/ricochet/dlls/plane.h deleted file mode 100644 index 5b64e84..0000000 --- a/ricochet/dlls/plane.h +++ /dev/null @@ -1,43 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef PLANE_H -#define PLANE_H - -//========================================================= -// Plane -//========================================================= -class CPlane -{ -public: - CPlane ( void ); - - //========================================================= - // InitializePlane - Takes a normal for the plane and a - // point on the plane and - //========================================================= - void InitializePlane ( const Vector &vecNormal, const Vector &vecPoint ); - - //========================================================= - // PointInFront - determines whether the given vector is - // in front of the plane. - //========================================================= - BOOL PointInFront ( const Vector &vecPoint ); - - Vector m_vecNormal; - float m_flDist; - BOOL m_fInitialized; -}; - -#endif // PLANE_H diff --git a/ricochet/dlls/plats.cpp b/ricochet/dlls/plats.cpp deleted file mode 100644 index b1faeaf..0000000 --- a/ricochet/dlls/plats.cpp +++ /dev/null @@ -1,2285 +0,0 @@ -/*** -* -* Copyright (c) 1996-2001, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -/* - -===== plats.cpp ======================================================== - - spawn, think, and touch functions for trains, etc - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "trains.h" -#include "saverestore.h" - -static void PlatSpawnInsideTrigger(entvars_t* pevPlatform); - -#define SF_PLAT_TOGGLE 0x0001 - -class CBasePlatTrain : public CBaseToggle -{ -public: - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - void KeyValue( KeyValueData* pkvd); - void Precache( void ); - - // This is done to fix spawn flag collisions between this class and a derived class - virtual BOOL IsTogglePlat( void ) { return (pev->spawnflags & SF_PLAT_TOGGLE) ? TRUE : FALSE; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - BYTE m_bMoveSnd; // sound a plat makes while moving - BYTE m_bStopSnd; // sound a plat makes when it stops - float m_volume; // Sound volume -}; - -TYPEDESCRIPTION CBasePlatTrain::m_SaveData[] = -{ - DEFINE_FIELD( CBasePlatTrain, m_bMoveSnd, FIELD_CHARACTER ), - DEFINE_FIELD( CBasePlatTrain, m_bStopSnd, FIELD_CHARACTER ), - DEFINE_FIELD( CBasePlatTrain, m_volume, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CBasePlatTrain, CBaseToggle ); - -void CBasePlatTrain :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "lip")) - { - m_flLip = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "height")) - { - m_flHeight = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "rotation")) - { - m_vecFinalAngle.x = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "movesnd")) - { - m_bMoveSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "stopsnd")) - { - m_bStopSnd = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "volume")) - { - m_volume = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -#define noiseMoving noise -#define noiseArrived noise1 - -void CBasePlatTrain::Precache( void ) -{ -// set the plat's "in-motion" sound - switch (m_bMoveSnd) - { - case 0: - pev->noiseMoving = MAKE_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("plats/bigmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/bigmove1.wav"); - break; - case 2: - PRECACHE_SOUND ("plats/bigmove2.wav"); - pev->noiseMoving = MAKE_STRING("plats/bigmove2.wav"); - break; - case 3: - PRECACHE_SOUND ("plats/elevmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/elevmove1.wav"); - break; - case 4: - PRECACHE_SOUND ("plats/elevmove2.wav"); - pev->noiseMoving = MAKE_STRING("plats/elevmove2.wav"); - break; - case 5: - PRECACHE_SOUND ("plats/elevmove3.wav"); - pev->noiseMoving = MAKE_STRING("plats/elevmove3.wav"); - break; - case 6: - PRECACHE_SOUND ("plats/freightmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/freightmove1.wav"); - break; - case 7: - PRECACHE_SOUND ("plats/freightmove2.wav"); - pev->noiseMoving = MAKE_STRING("plats/freightmove2.wav"); - break; - case 8: - PRECACHE_SOUND ("plats/heavymove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/heavymove1.wav"); - break; - case 9: - PRECACHE_SOUND ("plats/rackmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/rackmove1.wav"); - break; - case 10: - PRECACHE_SOUND ("plats/railmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/railmove1.wav"); - break; - case 11: - PRECACHE_SOUND ("plats/squeekmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/squeekmove1.wav"); - break; - case 12: - PRECACHE_SOUND ("plats/talkmove1.wav"); - pev->noiseMoving = MAKE_STRING("plats/talkmove1.wav"); - break; - case 13: - PRECACHE_SOUND ("plats/talkmove2.wav"); - pev->noiseMoving = MAKE_STRING("plats/talkmove2.wav"); - break; - default: - pev->noiseMoving = MAKE_STRING("common/null.wav"); - break; - } - -// set the plat's 'reached destination' stop sound - switch (m_bStopSnd) - { - case 0: - pev->noiseArrived = MAKE_STRING("common/null.wav"); - break; - case 1: - PRECACHE_SOUND ("plats/bigstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/bigstop1.wav"); - break; - case 2: - PRECACHE_SOUND ("plats/bigstop2.wav"); - pev->noiseArrived = MAKE_STRING("plats/bigstop2.wav"); - break; - case 3: - PRECACHE_SOUND ("plats/freightstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/freightstop1.wav"); - break; - case 4: - PRECACHE_SOUND ("plats/heavystop2.wav"); - pev->noiseArrived = MAKE_STRING("plats/heavystop2.wav"); - break; - case 5: - PRECACHE_SOUND ("plats/rackstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/rackstop1.wav"); - break; - case 6: - PRECACHE_SOUND ("plats/railstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/railstop1.wav"); - break; - case 7: - PRECACHE_SOUND ("plats/squeekstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/squeekstop1.wav"); - break; - case 8: - PRECACHE_SOUND ("plats/talkstop1.wav"); - pev->noiseArrived = MAKE_STRING("plats/talkstop1.wav"); - break; - - default: - pev->noiseArrived = MAKE_STRING("common/null.wav"); - break; - } -} - -// -//====================== PLAT code ==================================================== -// - - -#define noiseMovement noise -#define noiseStopMoving noise1 - -class CFuncPlat : public CBasePlatTrain -{ -public: - void Spawn( void ); - void Precache( void ); - void Setup( void ); - - virtual void Blocked( CBaseEntity *pOther ); - - - void EXPORT PlatUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - void EXPORT CallGoDown( void ) { GoDown(); } - void EXPORT CallHitTop( void ) { HitTop(); } - void EXPORT CallHitBottom( void ) { HitBottom(); } - - virtual void GoUp( void ); - virtual void GoDown( void ); - virtual void HitTop( void ); - virtual void HitBottom( void ); -}; -LINK_ENTITY_TO_CLASS( func_plat, CFuncPlat ); - - -// UNDONE: Need to save this!!! It needs class & linkage -class CPlatTrigger : public CBaseEntity -{ -public: - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DONT_SAVE; } - void SpawnInsideTrigger( CFuncPlat *pPlatform ); - void Touch( CBaseEntity *pOther ); - CFuncPlat *m_pPlatform; -}; - - - -/*QUAKED func_plat (0 .5 .8) ? PLAT_LOW_TRIGGER -speed default 150 - -Plats are always drawn in the extended position, so they will light correctly. - -If the plat is the target of another trigger or button, it will start out disabled in -the extended position until it is trigger, when it will lower and become a normal plat. - -If the "height" key is set, that will determine the amount the plat moves, instead of -being implicitly determined by the model's height. - -Set "sounds" to one of the following: -1) base fast -2) chain slow -*/ - -void CFuncPlat :: Setup( void ) -{ - //pev->noiseMovement = MAKE_STRING("plats/platmove1.wav"); - //pev->noiseStopMoving = MAKE_STRING("plats/platstop1.wav"); - - if (m_flTLength == 0) - m_flTLength = 80; - if (m_flTWidth == 0) - m_flTWidth = 10; - - pev->angles = g_vecZero; - - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - UTIL_SetOrigin(pev, pev->origin); // set size and link into world - UTIL_SetSize(pev, pev->mins, pev->maxs); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - // vecPosition1 is the top position, vecPosition2 is the bottom - m_vecPosition1 = pev->origin; - m_vecPosition2 = pev->origin; - if (m_flHeight != 0) - m_vecPosition2.z = pev->origin.z - m_flHeight; - else - m_vecPosition2.z = pev->origin.z - pev->size.z + 8; - if (pev->speed == 0) - pev->speed = 150; - - if ( m_volume == 0 ) - m_volume = 0.85; -} - - -void CFuncPlat :: Precache( ) -{ - CBasePlatTrain::Precache(); - //PRECACHE_SOUND("plats/platmove1.wav"); - //PRECACHE_SOUND("plats/platstop1.wav"); - if ( !IsTogglePlat() ) - PlatSpawnInsideTrigger( pev ); // the "start moving" trigger -} - - -void CFuncPlat :: Spawn( ) -{ - Setup(); - - Precache(); - - // If this platform is the target of some button, it starts at the TOP position, - // and is brought down by that button. Otherwise, it starts at BOTTOM. - if ( !FStringNull(pev->targetname) ) - { - UTIL_SetOrigin (pev, m_vecPosition1); - m_toggle_state = TS_AT_TOP; - SetUse( &CFuncPlat::PlatUse ); - } - else - { - UTIL_SetOrigin (pev, m_vecPosition2); - m_toggle_state = TS_AT_BOTTOM; - } -} - - - -static void PlatSpawnInsideTrigger(entvars_t* pevPlatform) -{ - GetClassPtr( (CPlatTrigger *)NULL)->SpawnInsideTrigger( GetClassPtr( (CFuncPlat *)pevPlatform ) ); -} - - -// -// Create a trigger entity for a platform. -// -void CPlatTrigger :: SpawnInsideTrigger( CFuncPlat *pPlatform ) -{ - m_pPlatform = pPlatform; - // Create trigger entity, "point" it at the owning platform, give it a touch method - pev->solid = SOLID_TRIGGER; - pev->movetype = MOVETYPE_NONE; - pev->origin = pPlatform->pev->origin; - - // Establish the trigger field's size - Vector vecTMin = m_pPlatform->pev->mins + Vector ( 25 , 25 , 0 ); - Vector vecTMax = m_pPlatform->pev->maxs + Vector ( 25 , 25 , 8 ); - vecTMin.z = vecTMax.z - ( m_pPlatform->m_vecPosition1.z - m_pPlatform->m_vecPosition2.z + 8 ); - if (m_pPlatform->pev->size.x <= 50) - { - vecTMin.x = (m_pPlatform->pev->mins.x + m_pPlatform->pev->maxs.x) / 2; - vecTMax.x = vecTMin.x + 1; - } - if (m_pPlatform->pev->size.y <= 50) - { - vecTMin.y = (m_pPlatform->pev->mins.y + m_pPlatform->pev->maxs.y) / 2; - vecTMax.y = vecTMin.y + 1; - } - UTIL_SetSize ( pev, vecTMin, vecTMax ); -} - - -// -// When the platform's trigger field is touched, the platform ??? -// -void CPlatTrigger :: Touch( CBaseEntity *pOther ) -{ - // Ignore touches by non-players - entvars_t* pevToucher = pOther->pev; - if ( !FClassnameIs (pevToucher, "player") ) - return; - - // Ignore touches by corpses - if (!pOther->IsAlive()) - return; - - // Make linked platform go up/down. - if (m_pPlatform->m_toggle_state == TS_AT_BOTTOM) - m_pPlatform->GoUp(); - else if (m_pPlatform->m_toggle_state == TS_AT_TOP) - m_pPlatform->pev->nextthink = m_pPlatform->pev->ltime + 1;// delay going down -} - - -// -// Used by SUB_UseTargets, when a platform is the target of a button. -// Start bringing platform down. -// -void CFuncPlat :: PlatUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( IsTogglePlat() ) - { - // Top is off, bottom is on - BOOL on = (m_toggle_state == TS_AT_BOTTOM) ? TRUE : FALSE; - - if ( !ShouldToggle( useType, on ) ) - return; - - if (m_toggle_state == TS_AT_TOP) - GoDown(); - else if ( m_toggle_state == TS_AT_BOTTOM ) - GoUp(); - } - else - { - SetUse( NULL ); - - if (m_toggle_state == TS_AT_TOP) - GoDown(); - } -} - - -// -// Platform is at top, now starts moving down. -// -void CFuncPlat :: GoDown( void ) -{ - if(pev->noiseMovement) - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement), m_volume, ATTN_NORM); - - ASSERT(m_toggle_state == TS_AT_TOP || m_toggle_state == TS_GOING_UP); - m_toggle_state = TS_GOING_DOWN; - SetMoveDone(&CFuncPlat::CallHitBottom); - LinearMove(m_vecPosition2, pev->speed); -} - - -// -// Platform has hit bottom. Stops and waits forever. -// -void CFuncPlat :: HitBottom( void ) -{ - if(pev->noiseMovement) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement)); - - if (pev->noiseStopMoving) - EMIT_SOUND(ENT(pev), CHAN_WEAPON, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - - ASSERT(m_toggle_state == TS_GOING_DOWN); - m_toggle_state = TS_AT_BOTTOM; -} - - -// -// Platform is at bottom, now starts moving up -// -void CFuncPlat :: GoUp( void ) -{ - if (pev->noiseMovement) - EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement), m_volume, ATTN_NORM); - - ASSERT(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN); - m_toggle_state = TS_GOING_UP; - SetMoveDone(&CFuncPlat::CallHitTop); - LinearMove(m_vecPosition1, pev->speed); -} - - -// -// Platform has hit top. Pauses, then starts back down again. -// -void CFuncPlat :: HitTop( void ) -{ - if(pev->noiseMovement) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement)); - - if (pev->noiseStopMoving) - EMIT_SOUND(ENT(pev), CHAN_WEAPON, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - - ASSERT(m_toggle_state == TS_GOING_UP); - m_toggle_state = TS_AT_TOP; - - if ( !IsTogglePlat() ) - { - // After a delay, the platform will automatically start going down again. - SetThink( &CFuncPlat::CallGoDown ); - pev->nextthink = pev->ltime + 3; - } -} - - -void CFuncPlat :: Blocked( CBaseEntity *pOther ) -{ - ALERT( at_aiconsole, "%s Blocked by %s\n", STRING(pev->classname), STRING(pOther->pev->classname) ); - // Hurt the blocker a little - pOther->TakeDamage(pev, pev, 1, DMG_CRUSH); - - if(pev->noiseMovement) - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement)); - - // Send the platform back where it came from - ASSERT(m_toggle_state == TS_GOING_UP || m_toggle_state == TS_GOING_DOWN); - if (m_toggle_state == TS_GOING_UP) - GoDown(); - else if (m_toggle_state == TS_GOING_DOWN) - GoUp (); -} - - -class CFuncPlatRot : public CFuncPlat -{ -public: - void Spawn( void ); - void SetupRotation( void ); - - virtual void GoUp( void ); - virtual void GoDown( void ); - virtual void HitTop( void ); - virtual void HitBottom( void ); - - void RotMove( Vector &destAngle, float time ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - Vector m_end, m_start; -}; -LINK_ENTITY_TO_CLASS( func_platrot, CFuncPlatRot ); -TYPEDESCRIPTION CFuncPlatRot::m_SaveData[] = -{ - DEFINE_FIELD( CFuncPlatRot, m_end, FIELD_VECTOR ), - DEFINE_FIELD( CFuncPlatRot, m_start, FIELD_VECTOR ), -}; - -IMPLEMENT_SAVERESTORE( CFuncPlatRot, CFuncPlat ); - - -void CFuncPlatRot :: SetupRotation( void ) -{ - if ( m_vecFinalAngle.x != 0 ) // This plat rotates too! - { - CBaseToggle :: AxisDir( pev ); - m_start = pev->angles; - m_end = pev->angles + pev->movedir * m_vecFinalAngle.x; - } - else - { - m_start = g_vecZero; - m_end = g_vecZero; - } - if ( !FStringNull(pev->targetname) ) // Start at top - { - pev->angles = m_end; - } -} - - -void CFuncPlatRot :: Spawn( void ) -{ - CFuncPlat :: Spawn(); - SetupRotation(); -} - -void CFuncPlatRot :: GoDown( void ) -{ - CFuncPlat :: GoDown(); - RotMove( m_start, pev->nextthink - pev->ltime ); -} - - -// -// Platform has hit bottom. Stops and waits forever. -// -void CFuncPlatRot :: HitBottom( void ) -{ - CFuncPlat :: HitBottom(); - pev->avelocity = g_vecZero; - pev->angles = m_start; -} - - -// -// Platform is at bottom, now starts moving up -// -void CFuncPlatRot :: GoUp( void ) -{ - CFuncPlat :: GoUp(); - RotMove( m_end, pev->nextthink - pev->ltime ); -} - - -// -// Platform has hit top. Pauses, then starts back down again. -// -void CFuncPlatRot :: HitTop( void ) -{ - CFuncPlat :: HitTop(); - pev->avelocity = g_vecZero; - pev->angles = m_end; -} - - -void CFuncPlatRot :: RotMove( Vector &destAngle, float time ) -{ - // set destdelta to the vector needed to move - Vector vecDestDelta = destAngle - pev->angles; - - // Travel time is so short, we're practically there already; so make it so. - if ( time >= 0.1) - pev->avelocity = vecDestDelta / time; - else - { - pev->avelocity = vecDestDelta; - pev->nextthink = pev->ltime + 1; - } -} - - -// -//====================== TRAIN code ================================================== -// - -class CFuncTrain : public CBasePlatTrain -{ -public: - void Spawn( void ); - void Precache( void ); - void Activate( void ); - void OverrideReset( void ); - - void Blocked( CBaseEntity *pOther ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData *pkvd ); - - - void EXPORT Wait( void ); - void EXPORT Next( void ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - entvars_t *m_pevCurrentTarget; - int m_sounds; - BOOL m_activated; -}; - -LINK_ENTITY_TO_CLASS( func_train, CFuncTrain ); -TYPEDESCRIPTION CFuncTrain::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTrain, m_sounds, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTrain, m_pevCurrentTarget, FIELD_EVARS ), - DEFINE_FIELD( CFuncTrain, m_activated, FIELD_BOOLEAN ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTrain, CBasePlatTrain ); - - -void CFuncTrain :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBasePlatTrain::KeyValue( pkvd ); -} - - -void CFuncTrain :: Blocked( CBaseEntity *pOther ) - -{ - if ( gpGlobals->time < m_flActivateFinished) - return; - - m_flActivateFinished = gpGlobals->time + 0.5; - - pOther->TakeDamage(pev, pev, pev->dmg, DMG_CRUSH); -} - - -void CFuncTrain :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( pev->spawnflags & SF_TRAIN_WAIT_RETRIGGER ) - { - // Move toward my target - pev->spawnflags &= ~SF_TRAIN_WAIT_RETRIGGER; - Next(); - } - else - { - pev->spawnflags |= SF_TRAIN_WAIT_RETRIGGER; - // Pop back to last target if it's available - if ( pev->enemy ) - pev->target = pev->enemy->v.targetname; - pev->nextthink = 0; - pev->velocity = g_vecZero; - if ( pev->noiseStopMoving ) - EMIT_SOUND (ENT(pev), CHAN_VOICE, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - } -} - - -void CFuncTrain :: Wait( void ) -{ - // Fire the pass target if there is one - if ( m_pevCurrentTarget->message ) - { - FireTargets( STRING(m_pevCurrentTarget->message), this, this, USE_TOGGLE, 0 ); - if ( FBitSet( m_pevCurrentTarget->spawnflags, SF_CORNER_FIREONCE ) ) - m_pevCurrentTarget->message = 0; - } - - // need pointer to LAST target. - if ( FBitSet (m_pevCurrentTarget->spawnflags , SF_TRAIN_WAIT_RETRIGGER ) || ( pev->spawnflags & SF_TRAIN_WAIT_RETRIGGER ) ) - { - pev->spawnflags |= SF_TRAIN_WAIT_RETRIGGER; - // clear the sound channel. - if ( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noiseMovement) ); - if ( pev->noiseStopMoving ) - EMIT_SOUND (ENT(pev), CHAN_VOICE, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - pev->nextthink = 0; - return; - } - - // ALERT ( at_console, "%f\n", m_flWait ); - - if (m_flWait != 0) - {// -1 wait will wait forever! - pev->nextthink = pev->ltime + m_flWait; - if ( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noiseMovement) ); - if ( pev->noiseStopMoving ) - EMIT_SOUND (ENT(pev), CHAN_VOICE, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - SetThink( &CFuncTrain::Next ); - } - else - { - Next();// do it RIGHT now! - } -} - - -// -// Train next - path corner needs to change to next target -// -void CFuncTrain :: Next( void ) -{ - CBaseEntity *pTarg; - - - // now find our next target - pTarg = GetNextTarget(); - - if ( !pTarg ) - { - if ( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noiseMovement) ); - // Play stop sound - if ( pev->noiseStopMoving ) - EMIT_SOUND (ENT(pev), CHAN_VOICE, (char*)STRING(pev->noiseStopMoving), m_volume, ATTN_NORM); - return; - } - - // Save last target in case we need to find it again - pev->message = pev->target; - - pev->target = pTarg->pev->target; - m_flWait = pTarg->GetDelay(); - - if ( m_pevCurrentTarget && m_pevCurrentTarget->speed != 0 ) - {// don't copy speed from target if it is 0 (uninitialized) - pev->speed = m_pevCurrentTarget->speed; - ALERT( at_aiconsole, "Train %s speed to %4.2f\n", STRING(pev->targetname), pev->speed ); - } - m_pevCurrentTarget = pTarg->pev;// keep track of this since path corners change our target for us. - - pev->enemy = pTarg->edict();//hack - - if(FBitSet(m_pevCurrentTarget->spawnflags, SF_CORNER_TELEPORT)) - { - // Path corner has indicated a teleport to the next corner. - SetBits(pev->effects, EF_NOINTERP); - UTIL_SetOrigin(pev, pTarg->pev->origin - (pev->mins + pev->maxs)* 0.5); - Wait(); // Get on with doing the next path corner. - } - else - { - // Normal linear move. - - // CHANGED this from CHAN_VOICE to CHAN_STATIC around OEM beta time because trains should - // use CHAN_STATIC for their movement sounds to prevent sound field problems. - // this is not a hack or temporary fix, this is how things should be. (sjb). - if ( pev->noiseMovement ) - STOP_SOUND( edict(), CHAN_STATIC, (char*)STRING(pev->noiseMovement) ); - if ( pev->noiseMovement ) - EMIT_SOUND (ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMovement), m_volume, ATTN_NORM); - ClearBits(pev->effects, EF_NOINTERP); - SetMoveDone( &CFuncTrain::Wait ); - LinearMove (pTarg->pev->origin - (pev->mins + pev->maxs)* 0.5, pev->speed); - } -} - - -void CFuncTrain :: Activate( void ) -{ - // Not yet active, so teleport to first target - if ( !m_activated ) - { - m_activated = TRUE; - entvars_t *pevTarg = VARS( FIND_ENTITY_BY_TARGETNAME (NULL, STRING(pev->target) ) ); - - pev->target = pevTarg->target; - m_pevCurrentTarget = pevTarg;// keep track of this since path corners change our target for us. - - UTIL_SetOrigin (pev, pevTarg->origin - (pev->mins + pev->maxs) * 0.5 ); - - if ( FStringNull(pev->targetname) ) - { // not triggered, so start immediately - pev->nextthink = pev->ltime + 0.1; - SetThink( &CFuncTrain::Next ); - } - else - pev->spawnflags |= SF_TRAIN_WAIT_RETRIGGER; - } -} - -/*QUAKED func_train (0 .5 .8) ? -Trains are moving platforms that players can ride. -The targets origin specifies the min point of the train at each corner. -The train spawns at the first target it is pointing at. -If the train is the target of a button or trigger, it will not begin moving until activated. -speed default 100 -dmg default 2 -sounds -1) ratchet metal -*/ - -void CFuncTrain :: Spawn( void ) -{ - Precache(); - if (pev->speed == 0) - pev->speed = 100; - - if ( FStringNull(pev->target) ) - ALERT(at_console, "FuncTrain with no target"); - - if (pev->dmg == 0) - pev->dmg = 2; - - pev->movetype = MOVETYPE_PUSH; - - if ( FBitSet (pev->spawnflags, SF_TRACKTRAIN_PASSABLE) ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - - SET_MODEL( ENT(pev), STRING(pev->model) ); - UTIL_SetSize (pev, pev->mins, pev->maxs); - UTIL_SetOrigin(pev, pev->origin); - - m_activated = FALSE; - - if ( m_volume == 0 ) - m_volume = 0.85; -} - - -void CFuncTrain::Precache( void ) -{ - CBasePlatTrain::Precache(); - -#if 0 // obsolete - // otherwise use preset sound - switch (m_sounds) - { - case 0: - pev->noise = 0; - pev->noise1 = 0; - break; - - case 1: - PRECACHE_SOUND ("plats/train2.wav"); - PRECACHE_SOUND ("plats/train1.wav"); - pev->noise = MAKE_STRING("plats/train2.wav"); - pev->noise1 = MAKE_STRING("plats/train1.wav"); - break; - - case 2: - PRECACHE_SOUND ("plats/platmove1.wav"); - PRECACHE_SOUND ("plats/platstop1.wav"); - pev->noise = MAKE_STRING("plats/platstop1.wav"); - pev->noise1 = MAKE_STRING("plats/platmove1.wav"); - break; - } -#endif -} - - -void CFuncTrain::OverrideReset( void ) -{ - CBaseEntity *pTarg; - - // Are we moving? - if ( pev->velocity != g_vecZero && pev->nextthink != 0 ) - { - pev->target = pev->message; - // now find our next target - pTarg = GetNextTarget(); - if ( !pTarg ) - { - pev->nextthink = 0; - pev->velocity = g_vecZero; - } - else // Keep moving for 0.1 secs, then find path_corner again and restart - { - SetThink( &CFuncTrain::Next ); - pev->nextthink = pev->ltime + 0.1; - } - } -} - - - - -// --------------------------------------------------------------------- -// -// Track Train -// -// --------------------------------------------------------------------- - -TYPEDESCRIPTION CFuncTrackTrain::m_SaveData[] = -{ - DEFINE_FIELD( CFuncTrackTrain, m_ppath, FIELD_CLASSPTR ), - DEFINE_FIELD( CFuncTrackTrain, m_length, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_height, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_speed, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_dir, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_startSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_controlMins, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTrackTrain, m_controlMaxs, FIELD_VECTOR ), - DEFINE_FIELD( CFuncTrackTrain, m_sounds, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTrackTrain, m_flVolume, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_flBank, FIELD_FLOAT ), - DEFINE_FIELD( CFuncTrackTrain, m_oldSpeed, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTrackTrain, CBaseEntity ); -LINK_ENTITY_TO_CLASS( func_tracktrain, CFuncTrackTrain ); - -void CFuncTrackTrain :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "wheels")) - { - m_length = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "height")) - { - m_height = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "startspeed")) - { - m_startSpeed = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "sounds")) - { - m_sounds = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "volume")) - { - m_flVolume = (float) (atoi(pkvd->szValue)); - m_flVolume *= 0.1; - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "bank")) - { - m_flBank = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -void CFuncTrackTrain :: NextThink( float thinkTime, BOOL alwaysThink ) -{ - if ( alwaysThink ) - pev->flags |= FL_ALWAYSTHINK; - else - pev->flags &= ~FL_ALWAYSTHINK; - - pev->nextthink = thinkTime; -} - - -void CFuncTrackTrain :: Blocked( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - // Blocker is on-ground on the train - if ( FBitSet( pevOther->flags, FL_ONGROUND ) && VARS(pevOther->groundentity) == pev ) - { - float deltaSpeed = fabs(pev->speed); - if ( deltaSpeed > 50 ) - deltaSpeed = 50; - if ( !pevOther->velocity.z ) - pevOther->velocity.z += deltaSpeed; - return; - } - else - pevOther->velocity = (pevOther->origin - pev->origin ).Normalize() * pev->dmg; - - ALERT( at_aiconsole, "TRAIN(%s): Blocked by %s (dmg:%.2f)\n", STRING(pev->targetname), STRING(pOther->pev->classname), pev->dmg ); - if ( pev->dmg <= 0 ) - return; - // we can't hurt this thing, so we're not concerned with it - pOther->TakeDamage(pev, pev, pev->dmg, DMG_CRUSH); -} - - -void CFuncTrackTrain :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( useType != USE_SET ) - { - if ( !ShouldToggle( useType, (pev->speed != 0) ) ) - return; - - if ( pev->speed == 0 ) - { - pev->speed = m_speed * m_dir; - - Next(); - } - else - { - pev->speed = 0; - pev->velocity = g_vecZero; - pev->avelocity = g_vecZero; - StopSound(); - SetThink( NULL ); - } - } - else - { - float delta = value; - - delta = ((int)(pev->speed * 4) / (int)m_speed)*0.25 + 0.25 * delta; - if ( delta > 1 ) - delta = 1; - else if ( delta < -1 ) - delta = -1; - if ( pev->spawnflags & SF_TRACKTRAIN_FORWARDONLY ) - { - if ( delta < 0 ) - delta = 0; - } - pev->speed = m_speed * delta; - Next(); - ALERT( at_aiconsole, "TRAIN(%s), speed to %.2f\n", STRING(pev->targetname), pev->speed ); - } -} - - -static float Fix( float angle ) -{ - while ( angle < 0 ) - angle += 360; - while ( angle > 360 ) - angle -= 360; - - return angle; -} - - -static void FixupAngles( Vector &v ) -{ - v.x = Fix( v.x ); - v.y = Fix( v.y ); - v.z = Fix( v.z ); -} - -#define TRAIN_STARTPITCH 60 -#define TRAIN_MAXPITCH 200 -#define TRAIN_MAXSPEED 1000 // approx max speed for sound pitch calculation - -void CFuncTrackTrain :: StopSound( void ) -{ - // if sound playing, stop it - if (m_soundPlaying && pev->noise) - { - unsigned short us_encode; - unsigned short us_sound = ( ( unsigned short )( m_sounds ) & 0x0007 ) << 12; - - us_encode = us_sound; - - PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, - (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 1, 0 ); - - /* - STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noise)); - */ - EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "plats/ttrain_brake1.wav", m_flVolume, ATTN_NORM, 0, 100); - } - - m_soundPlaying = 0; -} - -// update pitch based on speed, start sound if not playing -// NOTE: when train goes through transition, m_soundPlaying should go to 0, -// which will cause the looped sound to restart. - -void CFuncTrackTrain :: UpdateSound( void ) -{ - float flpitch; - - if (!pev->noise) - return; - - flpitch = TRAIN_STARTPITCH + ( fabs(pev->speed) * (TRAIN_MAXPITCH - TRAIN_STARTPITCH) / TRAIN_MAXSPEED); - - if (!m_soundPlaying) - { - // play startup sound for train - EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, "plats/ttrain_start1.wav", m_flVolume, ATTN_NORM, 0, 100); - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noise), m_flVolume, ATTN_NORM, 0, (int) flpitch); - m_soundPlaying = 1; - } - else - { -/* - // update pitch - EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noise), m_flVolume, ATTN_NORM, SND_CHANGE_PITCH, (int) flpitch); -*/ - // volume 0.0 - 1.0 - 6 bits - // m_sounds 3 bits - // flpitch = 6 bits - // 15 bits total - - unsigned short us_encode; - unsigned short us_sound = ( ( unsigned short )( m_sounds ) & 0x0007 ) << 12; - unsigned short us_pitch = ( ( unsigned short )( flpitch / 10.0 ) & 0x003f ) << 6; - unsigned short us_volume = ( ( unsigned short )( m_flVolume * 40.0 ) & 0x003f ); - - us_encode = us_sound | us_pitch | us_volume; - - PLAYBACK_EVENT_FULL( FEV_RELIABLE | FEV_UPDATE, edict(), m_usAdjustPitch, 0.0, - (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, us_encode, 0, 0, 0 ); - } -} - - -void CFuncTrackTrain :: Next( void ) -{ - float time = 0.5; - - if ( !pev->speed ) - { - ALERT( at_aiconsole, "TRAIN(%s): Speed is 0\n", STRING(pev->targetname) ); - StopSound(); - return; - } - -// if ( !m_ppath ) -// m_ppath = CPathTrack::Instance(FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->target) )); - if ( !m_ppath ) - { - ALERT( at_aiconsole, "TRAIN(%s): Lost path\n", STRING(pev->targetname) ); - StopSound(); - return; - } - - UpdateSound(); - - Vector nextPos = pev->origin; - - nextPos.z -= m_height; - CPathTrack *pnext = m_ppath->LookAhead( &nextPos, pev->speed * 0.1, 1 ); - nextPos.z += m_height; - - pev->velocity = (nextPos - pev->origin) * 10; - Vector nextFront = pev->origin; - - nextFront.z -= m_height; - if ( m_length > 0 ) - m_ppath->LookAhead( &nextFront, m_length, 0 ); - else - m_ppath->LookAhead( &nextFront, 100, 0 ); - nextFront.z += m_height; - - Vector delta = nextFront - pev->origin; - Vector angles = UTIL_VecToAngles( delta ); - // The train actually points west - angles.y += 180; - - // !!! All of this crap has to be done to make the angles not wrap around, revisit this. - FixupAngles( angles ); - FixupAngles( pev->angles ); - - if ( !pnext || (delta.x == 0 && delta.y == 0) ) - angles = pev->angles; - - float vy, vx; - if ( !(pev->spawnflags & SF_TRACKTRAIN_NOPITCH) ) - vx = UTIL_AngleDistance( angles.x, pev->angles.x ); - else - vx = 0; - vy = UTIL_AngleDistance( angles.y, pev->angles.y ); - - pev->avelocity.y = vy * 10; - pev->avelocity.x = vx * 10; - - if ( m_flBank != 0 ) - { - if ( pev->avelocity.y < -5 ) - pev->avelocity.z = UTIL_AngleDistance( UTIL_ApproachAngle( -m_flBank, pev->angles.z, m_flBank*2 ), pev->angles.z); - else if ( pev->avelocity.y > 5 ) - pev->avelocity.z = UTIL_AngleDistance( UTIL_ApproachAngle( m_flBank, pev->angles.z, m_flBank*2 ), pev->angles.z); - else - pev->avelocity.z = UTIL_AngleDistance( UTIL_ApproachAngle( 0, pev->angles.z, m_flBank*4 ), pev->angles.z) * 4; - } - - if ( pnext ) - { - if ( pnext != m_ppath ) - { - CPathTrack *pFire; - if ( pev->speed >= 0 ) - pFire = pnext; - else - pFire = m_ppath; - - m_ppath = pnext; - // Fire the pass target if there is one - if ( pFire->pev->message ) - { - FireTargets( STRING(pFire->pev->message), this, this, USE_TOGGLE, 0 ); - if ( FBitSet( pFire->pev->spawnflags, SF_PATH_FIREONCE ) ) - pFire->pev->message = 0; - } - - if ( pFire->pev->spawnflags & SF_PATH_DISABLE_TRAIN ) - pev->spawnflags |= SF_TRACKTRAIN_NOCONTROL; - - // Don't override speed if under user control - if ( pev->spawnflags & SF_TRACKTRAIN_NOCONTROL ) - { - if ( pFire->pev->speed != 0 ) - {// don't copy speed from target if it is 0 (uninitialized) - pev->speed = pFire->pev->speed; - ALERT( at_aiconsole, "TrackTrain %s speed to %4.2f\n", STRING(pev->targetname), pev->speed ); - } - } - - } - SetThink( &CFuncTrackTrain::Next ); - NextThink( pev->ltime + time, TRUE ); - } - else // end of path, stop - { - StopSound(); - pev->velocity = (nextPos - pev->origin); - pev->avelocity = g_vecZero; - float distance = pev->velocity.Length(); - m_oldSpeed = pev->speed; - - - pev->speed = 0; - - // Move to the dead end - - // Are we there yet? - if ( distance > 0 ) - { - // no, how long to get there? - time = distance / m_oldSpeed; - pev->velocity = pev->velocity * (m_oldSpeed / distance); - SetThink( &CFuncTrackTrain::DeadEnd ); - NextThink( pev->ltime + time, FALSE ); - } - else - { - DeadEnd(); - } - } -} - - -void CFuncTrackTrain::DeadEnd( void ) -{ - // Fire the dead-end target if there is one - CPathTrack *pTrack, *pNext; - - pTrack = m_ppath; - - ALERT( at_aiconsole, "TRAIN(%s): Dead end ", STRING(pev->targetname) ); - // Find the dead end path node - // HACKHACK -- This is bugly, but the train can actually stop moving at a different node depending on it's speed - // so we have to traverse the list to it's end. - if ( pTrack ) - { - if ( m_oldSpeed < 0 ) - { - do - { - pNext = pTrack->ValidPath( pTrack->GetPrevious(), TRUE ); - if ( pNext ) - pTrack = pNext; - } while ( pNext ); - } - else - { - do - { - pNext = pTrack->ValidPath( pTrack->GetNext(), TRUE ); - if ( pNext ) - pTrack = pNext; - } while ( pNext ); - } - } - - pev->velocity = g_vecZero; - pev->avelocity = g_vecZero; - if ( pTrack ) - { - ALERT( at_aiconsole, "at %s\n", STRING(pTrack->pev->targetname) ); - if ( pTrack->pev->netname ) - FireTargets( STRING(pTrack->pev->netname), this, this, USE_TOGGLE, 0 ); - } - else - ALERT( at_aiconsole, "\n" ); -} - - -void CFuncTrackTrain :: SetControls( entvars_t *pevControls ) -{ - Vector offset = pevControls->origin - pev->oldorigin; - - m_controlMins = pevControls->mins + offset; - m_controlMaxs = pevControls->maxs + offset; -} - - -BOOL CFuncTrackTrain :: OnControls( entvars_t *pevTest ) -{ - Vector offset = pevTest->origin - pev->origin; - - if ( pev->spawnflags & SF_TRACKTRAIN_NOCONTROL ) - return FALSE; - - // Transform offset into local coordinates - UTIL_MakeVectors( pev->angles ); - Vector local; - local.x = DotProduct( offset, gpGlobals->v_forward ); - local.y = -DotProduct( offset, gpGlobals->v_right ); - local.z = DotProduct( offset, gpGlobals->v_up ); - - if ( local.x >= m_controlMins.x && local.y >= m_controlMins.y && local.z >= m_controlMins.z && - local.x <= m_controlMaxs.x && local.y <= m_controlMaxs.y && local.z <= m_controlMaxs.z ) - return TRUE; - - return FALSE; -} - - -void CFuncTrackTrain :: Find( void ) -{ - m_ppath = CPathTrack::Instance(FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->target) )); - if ( !m_ppath ) - return; - - entvars_t *pevTarget = m_ppath->pev; - if ( !FClassnameIs( pevTarget, "path_track" ) ) - { - ALERT( at_error, "func_track_train must be on a path of path_track\n" ); - m_ppath = NULL; - return; - } - - Vector nextPos = pevTarget->origin; - nextPos.z += m_height; - - Vector look = nextPos; - look.z -= m_height; - m_ppath->LookAhead( &look, m_length, 0 ); - look.z += m_height; - - pev->angles = UTIL_VecToAngles( look - nextPos ); - // The train actually points west - pev->angles.y += 180; - - if ( pev->spawnflags & SF_TRACKTRAIN_NOPITCH ) - pev->angles.x = 0; - UTIL_SetOrigin( pev, nextPos ); - NextThink( pev->ltime + 0.1, FALSE ); - SetThink( &CFuncTrackTrain::Next ); - pev->speed = m_startSpeed; - - UpdateSound(); -} - - -void CFuncTrackTrain :: NearestPath( void ) -{ - CBaseEntity *pTrack = NULL; - CBaseEntity *pNearest = NULL; - float dist, closest; - - closest = 1024; - - while ((pTrack = UTIL_FindEntityInSphere( pTrack, pev->origin, 1024 )) != NULL) - { - // filter out non-tracks - if ( !(pTrack->pev->flags & (FL_CLIENT|FL_MONSTER)) && FClassnameIs( pTrack->pev, "path_track" ) ) - { - dist = (pev->origin - pTrack->pev->origin).Length(); - if ( dist < closest ) - { - closest = dist; - pNearest = pTrack; - } - } - } - - if ( !pNearest ) - { - ALERT( at_console, "Can't find a nearby track !!!\n" ); - SetThink(NULL); - return; - } - - ALERT( at_aiconsole, "TRAIN: %s, Nearest track is %s\n", STRING(pev->targetname), STRING(pNearest->pev->targetname) ); - // If I'm closer to the next path_track on this path, then it's my real path - pTrack = ((CPathTrack *)pNearest)->GetNext(); - if ( pTrack ) - { - if ( (pev->origin - pTrack->pev->origin).Length() < (pev->origin - pNearest->pev->origin).Length() ) - pNearest = pTrack; - } - - m_ppath = (CPathTrack *)pNearest; - - if ( pev->speed != 0 ) - { - NextThink( pev->ltime + 0.1, FALSE ); - SetThink( &CFuncTrackTrain::Next ); - } -} - - -void CFuncTrackTrain::OverrideReset( void ) -{ - NextThink( pev->ltime + 0.1, FALSE ); - SetThink( &CFuncTrackTrain::NearestPath ); -} - - -CFuncTrackTrain *CFuncTrackTrain::Instance( edict_t *pent ) -{ - if ( FClassnameIs( pent, "func_tracktrain" ) ) - return (CFuncTrackTrain *)GET_PRIVATE(pent); - return NULL; -} - -/*QUAKED func_train (0 .5 .8) ? -Trains are moving platforms that players can ride. -The targets origin specifies the min point of the train at each corner. -The train spawns at the first target it is pointing at. -If the train is the target of a button or trigger, it will not begin moving until activated. -speed default 100 -dmg default 2 -sounds -1) ratchet metal -*/ - -void CFuncTrackTrain :: Spawn( void ) -{ - if ( pev->speed == 0 ) - m_speed = 100; - else - m_speed = pev->speed; - - pev->speed = 0; - pev->velocity = g_vecZero; - pev->avelocity = g_vecZero; - pev->impulse = m_speed; - - m_dir = 1; - - if ( FStringNull(pev->target) ) - ALERT( at_console, "FuncTrain with no target" ); - - if ( pev->spawnflags & SF_TRACKTRAIN_PASSABLE ) - pev->solid = SOLID_NOT; - else - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - SET_MODEL( ENT(pev), STRING(pev->model) ); - - UTIL_SetSize( pev, pev->mins, pev->maxs ); - UTIL_SetOrigin( pev, pev->origin ); - - // Cache off placed origin for train controls - pev->oldorigin = pev->origin; - - m_controlMins = pev->mins; - m_controlMaxs = pev->maxs; - m_controlMaxs.z += 72; -// start trains on the next frame, to make sure their targets have had -// a chance to spawn/activate - NextThink( pev->ltime + 0.1, FALSE ); - SetThink( &CFuncTrackTrain::Find ); - Precache(); -} - -void CFuncTrackTrain :: Precache( void ) -{ - if (m_flVolume == 0.0) - m_flVolume = 1.0; - - switch (m_sounds) - { - default: - // no sound - pev->noise = 0; - break; - case 1: PRECACHE_SOUND("plats/ttrain1.wav"); pev->noise = MAKE_STRING("plats/ttrain1.wav");break; - case 2: PRECACHE_SOUND("plats/ttrain2.wav"); pev->noise = MAKE_STRING("plats/ttrain2.wav");break; - case 3: PRECACHE_SOUND("plats/ttrain3.wav"); pev->noise = MAKE_STRING("plats/ttrain3.wav");break; - case 4: PRECACHE_SOUND("plats/ttrain4.wav"); pev->noise = MAKE_STRING("plats/ttrain4.wav");break; - case 5: PRECACHE_SOUND("plats/ttrain6.wav"); pev->noise = MAKE_STRING("plats/ttrain6.wav");break; - case 6: PRECACHE_SOUND("plats/ttrain7.wav"); pev->noise = MAKE_STRING("plats/ttrain7.wav");break; - } - - PRECACHE_SOUND("plats/ttrain_brake1.wav"); - PRECACHE_SOUND("plats/ttrain_start1.wav"); - - m_usAdjustPitch = PRECACHE_EVENT( 1, "events/train.sc" ); -} - -// This class defines the volume of space that the player must stand in to control the train -class CFuncTrainControls : public CBaseEntity -{ -public: - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - void Spawn( void ); - void EXPORT Find( void ); -}; -LINK_ENTITY_TO_CLASS( func_traincontrols, CFuncTrainControls ); - - -void CFuncTrainControls :: Find( void ) -{ - edict_t *pTarget = NULL; - - do - { - pTarget = FIND_ENTITY_BY_TARGETNAME( pTarget, STRING(pev->target) ); - } while ( !FNullEnt(pTarget) && !FClassnameIs(pTarget, "func_tracktrain") ); - - if ( FNullEnt( pTarget ) ) - { - ALERT( at_console, "No train %s\n", STRING(pev->target) ); - return; - } - - CFuncTrackTrain *ptrain = CFuncTrackTrain::Instance(pTarget); - ptrain->SetControls( pev ); - UTIL_Remove( this ); -} - - -void CFuncTrainControls :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - SET_MODEL( ENT(pev), STRING(pev->model) ); - - UTIL_SetSize( pev, pev->mins, pev->maxs ); - UTIL_SetOrigin( pev, pev->origin ); - - SetThink(&CFuncTrainControls::Find ); - pev->nextthink = gpGlobals->time; -} - - - -// ---------------------------------------------------------------------------- -// -// Track changer / Train elevator -// -// ---------------------------------------------------------------------------- - -#define SF_TRACK_ACTIVATETRAIN 0x00000001 -#define SF_TRACK_RELINK 0x00000002 -#define SF_TRACK_ROTMOVE 0x00000004 -#define SF_TRACK_STARTBOTTOM 0x00000008 -#define SF_TRACK_DONT_MOVE 0x00000010 - -// -// This entity is a rotating/moving platform that will carry a train to a new track. -// It must be larger in X-Y planar area than the train, since it must contain the -// train within these dimensions in order to operate when the train is near it. -// - -typedef enum { TRAIN_SAFE, TRAIN_BLOCKING, TRAIN_FOLLOWING } TRAIN_CODE; - -class CFuncTrackChange : public CFuncPlatRot -{ -public: - void Spawn( void ); - void Precache( void ); - -// virtual void Blocked( void ); - virtual void EXPORT GoUp( void ); - virtual void EXPORT GoDown( void ); - - void KeyValue( KeyValueData* pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT Find( void ); - TRAIN_CODE EvaluateTrain( CPathTrack *pcurrent ); - void UpdateTrain( Vector &dest ); - virtual void HitBottom( void ); - virtual void HitTop( void ); - void Touch( CBaseEntity *pOther ); - virtual void UpdateAutoTargets( int toggleState ); - virtual BOOL IsTogglePlat( void ) { return TRUE; } - - void DisableUse( void ) { m_use = 0; } - void EnableUse( void ) { m_use = 1; } - int UseEnabled( void ) { return m_use; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - virtual void OverrideReset( void ); - - - CPathTrack *m_trackTop; - CPathTrack *m_trackBottom; - - CFuncTrackTrain *m_train; - - int m_trackTopName; - int m_trackBottomName; - int m_trainName; - TRAIN_CODE m_code; - int m_targetState; - int m_use; -}; -LINK_ENTITY_TO_CLASS( func_trackchange, CFuncTrackChange ); - -TYPEDESCRIPTION CFuncTrackChange::m_SaveData[] = -{ - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trackTop, FIELD_CLASSPTR ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trackBottom, FIELD_CLASSPTR ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_train, FIELD_CLASSPTR ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trackTopName, FIELD_STRING ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trackBottomName, FIELD_STRING ), - DEFINE_GLOBAL_FIELD( CFuncTrackChange, m_trainName, FIELD_STRING ), - DEFINE_FIELD( CFuncTrackChange, m_code, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTrackChange, m_targetState, FIELD_INTEGER ), - DEFINE_FIELD( CFuncTrackChange, m_use, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CFuncTrackChange, CFuncPlatRot ); - -void CFuncTrackChange :: Spawn( void ) -{ - Setup(); - if ( FBitSet( pev->spawnflags, SF_TRACK_DONT_MOVE ) ) - m_vecPosition2.z = pev->origin.z; - - SetupRotation(); - - if ( FBitSet( pev->spawnflags, SF_TRACK_STARTBOTTOM ) ) - { - UTIL_SetOrigin (pev, m_vecPosition2); - m_toggle_state = TS_AT_BOTTOM; - pev->angles = m_start; - m_targetState = TS_AT_TOP; - } - else - { - UTIL_SetOrigin (pev, m_vecPosition1); - m_toggle_state = TS_AT_TOP; - pev->angles = m_end; - m_targetState = TS_AT_BOTTOM; - } - - EnableUse(); - pev->nextthink = pev->ltime + 2.0; - SetThink( &CFuncTrackChange::Find ); - Precache(); -} - -void CFuncTrackChange :: Precache( void ) -{ - // Can't trigger sound - PRECACHE_SOUND( "buttons/button11.wav" ); - - CFuncPlatRot::Precache(); -} - - -// UNDONE: Filter touches before re-evaluating the train. -void CFuncTrackChange :: Touch( CBaseEntity *pOther ) -{ -#if 0 - TRAIN_CODE code; - entvars_t *pevToucher = pOther->pev; -#endif -} - - - -void CFuncTrackChange :: KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "train") ) - { - m_trainName = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "toptrack") ) - { - m_trackTopName = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "bottomtrack") ) - { - m_trackBottomName = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - { - CFuncPlatRot::KeyValue( pkvd ); // Pass up to base class - } -} - - -void CFuncTrackChange::OverrideReset( void ) -{ - pev->nextthink = pev->ltime + 1.0; - SetThink( &CFuncTrackChange::Find ); -} - -void CFuncTrackChange :: Find( void ) -{ - // Find track entities - edict_t *target; - - target = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trackTopName) ); - if ( !FNullEnt(target) ) - { - m_trackTop = CPathTrack::Instance( target ); - target = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trackBottomName) ); - if ( !FNullEnt(target) ) - { - m_trackBottom = CPathTrack::Instance( target ); - target = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trainName) ); - if ( !FNullEnt(target) ) - { - m_train = CFuncTrackTrain::Instance( FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trainName) ) ); - if ( !m_train ) - { - ALERT( at_error, "Can't find train for track change! %s\n", STRING(m_trainName) ); - return; - } - Vector center = (pev->absmin + pev->absmax) * 0.5; - m_trackBottom = m_trackBottom->Nearest( center ); - m_trackTop = m_trackTop->Nearest( center ); - UpdateAutoTargets( m_toggle_state ); - SetThink( NULL ); - return; - } - else - { - ALERT( at_error, "Can't find train for track change! %s\n", STRING(m_trainName) ); - target = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_trainName) ); - } - } - else - ALERT( at_error, "Can't find bottom track for track change! %s\n", STRING(m_trackBottomName) ); - } - else - ALERT( at_error, "Can't find top track for track change! %s\n", STRING(m_trackTopName) ); -} - - - -TRAIN_CODE CFuncTrackChange :: EvaluateTrain( CPathTrack *pcurrent ) -{ - // Go ahead and work, we don't have anything to switch, so just be an elevator - if ( !pcurrent || !m_train ) - return TRAIN_SAFE; - - if ( m_train->m_ppath == pcurrent || (pcurrent->m_pprevious && m_train->m_ppath == pcurrent->m_pprevious) || - (pcurrent->m_pnext && m_train->m_ppath == pcurrent->m_pnext) ) - { - if ( m_train->pev->speed != 0 ) - return TRAIN_BLOCKING; - - Vector dist = pev->origin - m_train->pev->origin; - float length = dist.Length2D(); - if ( length < m_train->m_length ) // Empirically determined close distance - return TRAIN_FOLLOWING; - else if ( length > (150 + m_train->m_length) ) - return TRAIN_SAFE; - - return TRAIN_BLOCKING; - } - - return TRAIN_SAFE; -} - - -void CFuncTrackChange :: UpdateTrain( Vector &dest ) -{ - float time = (pev->nextthink - pev->ltime); - - m_train->pev->velocity = pev->velocity; - m_train->pev->avelocity = pev->avelocity; - m_train->NextThink( m_train->pev->ltime + time, FALSE ); - - // Attempt at getting the train to rotate properly around the origin of the trackchange - if ( time <= 0 ) - return; - - Vector offset = m_train->pev->origin - pev->origin; - Vector delta = dest - pev->angles; - // Transform offset into local coordinates - UTIL_MakeInvVectors( delta, gpGlobals ); - Vector local; - local.x = DotProduct( offset, gpGlobals->v_forward ); - local.y = DotProduct( offset, gpGlobals->v_right ); - local.z = DotProduct( offset, gpGlobals->v_up ); - - local = local - offset; - m_train->pev->velocity = pev->velocity + (local * (1.0/time)); -} - -void CFuncTrackChange :: GoDown( void ) -{ - if ( m_code == TRAIN_BLOCKING ) - return; - - // HitBottom may get called during CFuncPlat::GoDown(), so set up for that - // before you call GoDown() - - UpdateAutoTargets( TS_GOING_DOWN ); - // If ROTMOVE, move & rotate - if ( FBitSet( pev->spawnflags, SF_TRACK_DONT_MOVE ) ) - { - SetMoveDone( &CFuncTrackChange::CallHitBottom ); - m_toggle_state = TS_GOING_DOWN; - AngularMove( m_start, pev->speed ); - } - else - { - CFuncPlat :: GoDown(); - SetMoveDone( &CFuncTrackChange::CallHitBottom ); - RotMove( m_start, pev->nextthink - pev->ltime ); - } - // Otherwise, rotate first, move second - - // If the train is moving with the platform, update it - if ( m_code == TRAIN_FOLLOWING ) - { - UpdateTrain( m_start ); - m_train->m_ppath = NULL; - } -} - - -// -// Platform is at bottom, now starts moving up -// -void CFuncTrackChange :: GoUp( void ) -{ - if ( m_code == TRAIN_BLOCKING ) - return; - - // HitTop may get called during CFuncPlat::GoUp(), so set up for that - // before you call GoUp(); - - UpdateAutoTargets( TS_GOING_UP ); - if ( FBitSet( pev->spawnflags, SF_TRACK_DONT_MOVE ) ) - { - m_toggle_state = TS_GOING_UP; - SetMoveDone( &CFuncTrackChange::CallHitTop ); - AngularMove( m_end, pev->speed ); - } - else - { - // If ROTMOVE, move & rotate - CFuncPlat :: GoUp(); - SetMoveDone( &CFuncTrackChange::CallHitTop ); - RotMove( m_end, pev->nextthink - pev->ltime ); - } - - // Otherwise, move first, rotate second - - // If the train is moving with the platform, update it - if ( m_code == TRAIN_FOLLOWING ) - { - UpdateTrain( m_end ); - m_train->m_ppath = NULL; - } -} - - -// Normal track change -void CFuncTrackChange :: UpdateAutoTargets( int toggleState ) -{ - if ( !m_trackTop || !m_trackBottom ) - return; - - if ( toggleState == TS_AT_TOP ) - ClearBits( m_trackTop->pev->spawnflags, SF_PATH_DISABLED ); - else - SetBits( m_trackTop->pev->spawnflags, SF_PATH_DISABLED ); - - if ( toggleState == TS_AT_BOTTOM ) - ClearBits( m_trackBottom->pev->spawnflags, SF_PATH_DISABLED ); - else - SetBits( m_trackBottom->pev->spawnflags, SF_PATH_DISABLED ); -} - - -void CFuncTrackChange :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( m_toggle_state != TS_AT_TOP && m_toggle_state != TS_AT_BOTTOM ) - return; - - // If train is in "safe" area, but not on the elevator, play alarm sound - if ( m_toggle_state == TS_AT_TOP ) - m_code = EvaluateTrain( m_trackTop ); - else if ( m_toggle_state == TS_AT_BOTTOM ) - m_code = EvaluateTrain( m_trackBottom ); - else - m_code = TRAIN_BLOCKING; - if ( m_code == TRAIN_BLOCKING ) - { - // Play alarm and return - EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/button11.wav", 1, ATTN_NORM); - return; - } - - // Otherwise, it's safe to move - // If at top, go down - // at bottom, go up - - DisableUse(); - if (m_toggle_state == TS_AT_TOP) - GoDown(); - else - GoUp(); -} - - -// -// Platform has hit bottom. Stops and waits forever. -// -void CFuncTrackChange :: HitBottom( void ) -{ - CFuncPlatRot :: HitBottom(); - if ( m_code == TRAIN_FOLLOWING ) - { -// UpdateTrain(); - m_train->SetTrack( m_trackBottom ); - } - SetThink( NULL ); - pev->nextthink = -1; - - UpdateAutoTargets( m_toggle_state ); - - EnableUse(); -} - - -// -// Platform has hit bottom. Stops and waits forever. -// -void CFuncTrackChange :: HitTop( void ) -{ - CFuncPlatRot :: HitTop(); - if ( m_code == TRAIN_FOLLOWING ) - { -// UpdateTrain(); - m_train->SetTrack( m_trackTop ); - } - - // Don't let the plat go back down - SetThink( NULL ); - pev->nextthink = -1; - UpdateAutoTargets( m_toggle_state ); - EnableUse(); -} - - - -class CFuncTrackAuto : public CFuncTrackChange -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - virtual void UpdateAutoTargets( int toggleState ); -}; - -LINK_ENTITY_TO_CLASS( func_trackautochange, CFuncTrackAuto ); - -// Auto track change -void CFuncTrackAuto :: UpdateAutoTargets( int toggleState ) -{ - CPathTrack *pTarget, *pNextTarget; - - if ( !m_trackTop || !m_trackBottom ) - return; - - if ( m_targetState == TS_AT_TOP ) - { - pTarget = m_trackTop->GetNext(); - pNextTarget = m_trackBottom->GetNext(); - } - else - { - pTarget = m_trackBottom->GetNext(); - pNextTarget = m_trackTop->GetNext(); - } - if ( pTarget ) - { - ClearBits( pTarget->pev->spawnflags, SF_PATH_DISABLED ); - if ( m_code == TRAIN_FOLLOWING && m_train && m_train->pev->speed == 0 ) - m_train->Use( this, this, USE_ON, 0 ); - } - - if ( pNextTarget ) - SetBits( pNextTarget->pev->spawnflags, SF_PATH_DISABLED ); - -} - - -void CFuncTrackAuto :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - CPathTrack *pTarget; - - if ( !UseEnabled() ) - return; - - if ( m_toggle_state == TS_AT_TOP ) - pTarget = m_trackTop; - else if ( m_toggle_state == TS_AT_BOTTOM ) - pTarget = m_trackBottom; - else - pTarget = NULL; - - if ( FClassnameIs( pActivator->pev, "func_tracktrain" ) ) - { - m_code = EvaluateTrain( pTarget ); - // Safe to fire? - if ( m_code == TRAIN_FOLLOWING && m_toggle_state != m_targetState ) - { - DisableUse(); - if (m_toggle_state == TS_AT_TOP) - GoDown(); - else - GoUp(); - } - } - else - { - if ( pTarget ) - pTarget = pTarget->GetNext(); - if ( pTarget && m_train->m_ppath != pTarget && ShouldToggle( useType, m_targetState ) ) - { - if ( m_targetState == TS_AT_TOP ) - m_targetState = TS_AT_BOTTOM; - else - m_targetState = TS_AT_TOP; - } - - UpdateAutoTargets( m_targetState ); - } -} - - -// ---------------------------------------------------------- -// -// -// pev->speed is the travel speed -// pev->health is current health -// pev->max_health is the amount to reset to each time it starts - -#define FGUNTARGET_START_ON 0x0001 - -class CGunTarget : public CBaseMonster -{ -public: - void Spawn( void ); - void Activate( void ); - void EXPORT Next( void ); - void EXPORT Start( void ); - void EXPORT Wait( void ); - void Stop( void ); - - int BloodColor( void ) { return DONT_BLEED; } - int Classify( void ) { return CLASS_MACHINE; } - int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - Vector BodyTarget( const Vector &posSrc ) { return pev->origin; } - - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - BOOL m_on; -}; - - -LINK_ENTITY_TO_CLASS( func_guntarget, CGunTarget ); - -TYPEDESCRIPTION CGunTarget::m_SaveData[] = -{ - DEFINE_FIELD( CGunTarget, m_on, FIELD_BOOLEAN ), -}; - -IMPLEMENT_SAVERESTORE( CGunTarget, CBaseMonster ); - - -void CGunTarget::Spawn( void ) -{ - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - - UTIL_SetOrigin(pev, pev->origin); - SET_MODEL(ENT(pev), STRING(pev->model) ); - - if ( pev->speed == 0 ) - pev->speed = 100; - - // Don't take damage until "on" - pev->takedamage = DAMAGE_NO; - pev->flags |= FL_MONSTER; - - m_on = FALSE; - pev->max_health = pev->health; - - if ( pev->spawnflags & FGUNTARGET_START_ON ) - { - SetThink( &CGunTarget::Start ); - pev->nextthink = pev->ltime + 0.3; - } -} - - -void CGunTarget::Activate( void ) -{ - CBaseEntity *pTarg; - - // now find our next target - pTarg = GetNextTarget(); - if ( pTarg ) - { - m_hTargetEnt = pTarg; - UTIL_SetOrigin( pev, pTarg->pev->origin - (pev->mins + pev->maxs) * 0.5 ); - } -} - - -void CGunTarget::Start( void ) -{ - Use( this, this, USE_ON, 0 ); -} - - -void CGunTarget::Next( void ) -{ - SetThink( NULL ); - - m_hTargetEnt = GetNextTarget(); - CBaseEntity *pTarget = m_hTargetEnt; - - if ( !pTarget ) - { - Stop(); - return; - } - SetMoveDone( &CGunTarget::Wait ); - LinearMove( pTarget->pev->origin - (pev->mins + pev->maxs) * 0.5, pev->speed ); -} - - -void CGunTarget::Wait( void ) -{ - CBaseEntity *pTarget = m_hTargetEnt; - - if ( !pTarget ) - { - Stop(); - return; - } - - // Fire the pass target if there is one - if ( pTarget->pev->message ) - { - FireTargets( STRING(pTarget->pev->message), this, this, USE_TOGGLE, 0 ); - if ( FBitSet( pTarget->pev->spawnflags, SF_CORNER_FIREONCE ) ) - pTarget->pev->message = 0; - } - - m_flWait = pTarget->GetDelay(); - - pev->target = pTarget->pev->target; - SetThink( &CGunTarget::Next ); - if (m_flWait != 0) - {// -1 wait will wait forever! - pev->nextthink = pev->ltime + m_flWait; - } - else - { - Next();// do it RIGHT now! - } -} - - -void CGunTarget::Stop( void ) -{ - pev->velocity = g_vecZero; - pev->nextthink = 0; - pev->takedamage = DAMAGE_NO; -} - - -int CGunTarget::TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) -{ - if ( pev->health > 0 ) - { - pev->health -= flDamage; - if ( pev->health <= 0 ) - { - pev->health = 0; - Stop(); - if ( pev->message ) - FireTargets( STRING(pev->message), this, this, USE_TOGGLE, 0 ); - } - } - return 0; -} - - -void CGunTarget::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, m_on ) ) - return; - - if ( m_on ) - { - Stop(); - } - else - { - pev->takedamage = DAMAGE_AIM; - m_hTargetEnt = GetNextTarget(); - if ( m_hTargetEnt == NULL ) - return; - pev->health = pev->max_health; - Next(); - } -} - - - diff --git a/ricochet/dlls/player.cpp b/ricochet/dlls/player.cpp deleted file mode 100644 index 4ab6b7c..0000000 --- a/ricochet/dlls/player.cpp +++ /dev/null @@ -1,4901 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== player.cpp ======================================================== - - functions dealing with the player - -*/ - -#include "extdll.h" -#include "util.h" - -#include "cbase.h" -#include "player.h" -#include "trains.h" -#include "nodes.h" -#include "weapons.h" -#include "soundent.h" -#include "monsters.h" -#include "../engine/shake.h" -#include "decals.h" -#include "gamerules.h" -#include "animation.h" -#include "discwar.h" -#include "disc_objects.h" -#include "disc_arena.h" - -// #define DUCKFIX - -extern DLL_GLOBAL ULONG g_ulModelIndexPlayer; -extern DLL_GLOBAL BOOL g_fGameOver; -extern DLL_GLOBAL BOOL g_fDrawLines; -int gEvilImpulse101; -extern DLL_GLOBAL int g_iSkillLevel, gDisplayTitle; -BOOL gInitHUD = FALSE; - -extern void CopyToBodyQue(entvars_t* pev); -extern void respawn(entvars_t *pev, BOOL fCopyCorpse); -extern Vector VecBModelOrigin(entvars_t *pevBModel ); -extern edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ); -int MapTextureTypeStepType(char chTextureType); - -entvars_t *g_pevLastInflictor; // Set in combat.cpp. Used to pass the damage inflictor for death messages. - // Better solution: Add as parameter to all Killed() functions. - -// the world node graph -extern CGraph WorldGraph; - -#define PLAYER_WALLJUMP_SPEED 300 // how fast we can spring off walls -#define PLAYER_LONGJUMP_SPEED 350 // how fast we longjump - -#define TRAIN_ACTIVE 0x80 -#define TRAIN_NEW 0xc0 -#define TRAIN_OFF 0x00 -#define TRAIN_NEUTRAL 0x01 -#define TRAIN_SLOW 0x02 -#define TRAIN_MEDIUM 0x03 -#define TRAIN_FAST 0x04 -#define TRAIN_BACK 0x05 - -#define FLASH_DRAIN_TIME 1.2 //100 units/3 minutes -#define FLASH_CHARGE_TIME 0.2 // 100 units/20 seconds (seconds per unit) - - -//#define PLAYER_MAX_SAFE_FALL_DIST 20// falling any farther than this many feet will inflict damage -//#define PLAYER_FATAL_FALL_DIST 60// 100% damage inflicted if player falls this many feet -//#define DAMAGE_PER_UNIT_FALLEN (float)( 100 ) / ( ( PLAYER_FATAL_FALL_DIST - PLAYER_MAX_SAFE_FALL_DIST ) * 12 ) -//#define MAX_SAFE_FALL_UNITS ( PLAYER_MAX_SAFE_FALL_DIST * 12 ) - -// Global Savedata for player -TYPEDESCRIPTION CBasePlayer::m_playerSaveData[] = -{ - DEFINE_FIELD( CBasePlayer, m_flFlashLightTime, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_iFlashBattery, FIELD_INTEGER ), - - DEFINE_FIELD( CBasePlayer, m_afButtonLast, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_afButtonPressed, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_afButtonReleased, FIELD_INTEGER ), - - DEFINE_ARRAY( CBasePlayer, m_rgItems, FIELD_INTEGER, MAX_ITEMS ), - DEFINE_FIELD( CBasePlayer, m_afPhysicsFlags, FIELD_INTEGER ), - - DEFINE_FIELD( CBasePlayer, m_flTimeStepSound, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_flTimeWeaponIdle, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_flSwimTime, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_flDuckTime, FIELD_TIME ), - DEFINE_FIELD( CBasePlayer, m_flWallJumpTime, FIELD_TIME ), - - DEFINE_FIELD( CBasePlayer, m_flSuitUpdate, FIELD_TIME ), - DEFINE_ARRAY( CBasePlayer, m_rgSuitPlayList, FIELD_INTEGER, CSUITPLAYLIST ), - DEFINE_FIELD( CBasePlayer, m_iSuitPlayNext, FIELD_INTEGER ), - DEFINE_ARRAY( CBasePlayer, m_rgiSuitNoRepeat, FIELD_INTEGER, CSUITNOREPEAT ), - DEFINE_ARRAY( CBasePlayer, m_rgflSuitNoRepeatTime, FIELD_TIME, CSUITNOREPEAT ), - DEFINE_FIELD( CBasePlayer, m_lastDamageAmount, FIELD_INTEGER ), - - DEFINE_ARRAY( CBasePlayer, m_rgpPlayerItems, FIELD_CLASSPTR, MAX_ITEM_TYPES ), - DEFINE_FIELD( CBasePlayer, m_pActiveItem, FIELD_CLASSPTR ), - DEFINE_FIELD( CBasePlayer, m_pLastItem, FIELD_CLASSPTR ), - - DEFINE_ARRAY( CBasePlayer, m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS ), - DEFINE_FIELD( CBasePlayer, m_idrowndmg, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_idrownrestored, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_tSneaking, FIELD_TIME ), - - DEFINE_FIELD( CBasePlayer, m_iTrain, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_bitsHUDDamage, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_flFallVelocity, FIELD_FLOAT ), - DEFINE_FIELD( CBasePlayer, m_iTargetVolume, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_iWeaponVolume, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_iExtraSoundTypes, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_iWeaponFlash, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_fLongJump, FIELD_BOOLEAN ), - DEFINE_FIELD( CBasePlayer, m_fInitHUD, FIELD_BOOLEAN ), - DEFINE_FIELD( CBasePlayer, m_tbdPrev, FIELD_TIME ), - - DEFINE_FIELD( CBasePlayer, m_pTank, FIELD_EHANDLE ), - DEFINE_FIELD( CBasePlayer, m_iHideHUD, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayer, m_iFOV, FIELD_INTEGER ), - - //DEFINE_FIELD( CBasePlayer, m_fDeadTime, FIELD_FLOAT ), // only used in multiplayer games - //DEFINE_FIELD( CBasePlayer, m_fGameHUDInitialized, FIELD_INTEGER ), // only used in multiplayer games - //DEFINE_FIELD( CBasePlayer, m_flStopExtraSoundTime, FIELD_TIME ), - //DEFINE_FIELD( CBasePlayer, m_fKnownItem, FIELD_INTEGER ), // reset to zero on load - //DEFINE_FIELD( CBasePlayer, m_iPlayerSound, FIELD_INTEGER ), // Don't restore, set in Precache() - //DEFINE_FIELD( CBasePlayer, m_pentSndLast, FIELD_EDICT ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_flSndRoomtype, FIELD_FLOAT ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_flSndRange, FIELD_FLOAT ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_fNewAmmo, FIELD_INTEGER ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_flgeigerRange, FIELD_FLOAT ), // Don't restore, reset in Precache() - //DEFINE_FIELD( CBasePlayer, m_flgeigerDelay, FIELD_FLOAT ), // Don't restore, reset in Precache() - //DEFINE_FIELD( CBasePlayer, m_igeigerRangePrev, FIELD_FLOAT ), // Don't restore, reset in Precache() - //DEFINE_FIELD( CBasePlayer, m_iStepLeft, FIELD_INTEGER ), // Don't need to restore - //DEFINE_ARRAY( CBasePlayer, m_szTextureName, FIELD_CHARACTER, CBTEXTURENAMEMAX ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_chTextureType, FIELD_CHARACTER ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_fNoPlayerSound, FIELD_BOOLEAN ), // Don't need to restore, debug - //DEFINE_FIELD( CBasePlayer, m_iUpdateTime, FIELD_INTEGER ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_iClientHealth, FIELD_INTEGER ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_iClientBattery, FIELD_INTEGER ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_iClientHideHUD, FIELD_INTEGER ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_fWeapon, FIELD_BOOLEAN ), // Don't restore, client needs reset - //DEFINE_FIELD( CBasePlayer, m_nCustomSprayFrames, FIELD_INTEGER ), // Don't restore, depends on server message after spawning and only matters in multiplayer - //DEFINE_FIELD( CBasePlayer, m_vecAutoAim, FIELD_VECTOR ), // Don't save/restore - this is recomputed - //DEFINE_ARRAY( CBasePlayer, m_rgAmmoLast, FIELD_INTEGER, MAX_AMMO_SLOTS ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_fOnTarget, FIELD_BOOLEAN ), // Don't need to restore - //DEFINE_FIELD( CBasePlayer, m_nCustomSprayFrames, FIELD_INTEGER ), // Don't need to restore - -}; - - -int giPrecacheGrunt = 0; -int gmsgShake = 0; -int gmsgFade = 0; -int gmsgSelAmmo = 0; -int gmsgFlashlight = 0; -int gmsgFlashBattery = 0; -int gmsgResetHUD = 0; -int gmsgInitHUD = 0; -int gmsgShowGameTitle = 0; -int gmsgCurWeapon = 0; -int gmsgHealth = 0; -int gmsgDamage = 0; -int gmsgBattery = 0; -int gmsgTrain = 0; -int gmsgLogo = 0; -int gmsgWeaponList = 0; -int gmsgAmmoX = 0; -int gmsgHudText = 0; -int gmsgDeathMsg = 0; -int gmsgScoreInfo = 0; -int gmsgTeamInfo = 0; -int gmsgTeamScore = 0; -int gmsgGameMode = 0; -int gmsgMOTD = 0; -int gmsgAmmoPickup = 0; -int gmsgWeapPickup = 0; -int gmsgItemPickup = 0; -int gmsgHideWeapon = 0; -int gmsgSetCurWeap = 0; -int gmsgSayText = 0; -int gmsgTextMsg = 0; -int gmsgSetFOV = 0; -int gmsgShowMenu = 0; -int gmsgGeigerRange = 0; -int gmsgSpectator = 0; -int gmsgStartRnd = 0; -int gmsgEndRnd = 0; -int gmsgPowerup = 0; -int gmsgReward = 0; -int gmsgFrozen = 0; - -void LinkUserMessages( void ) -{ - // Already taken care of? - if ( gmsgSelAmmo ) - { - return; - } - - gmsgSelAmmo = REG_USER_MSG("SelAmmo", sizeof(SelAmmo)); - gmsgCurWeapon = REG_USER_MSG("CurWeapon", 3); - gmsgGeigerRange = REG_USER_MSG("Geiger", 1); - gmsgFlashlight = REG_USER_MSG("Flashlight", 2); - gmsgFlashBattery = REG_USER_MSG("FlashBat", 1); - gmsgHealth = REG_USER_MSG( "Health", 1 ); - gmsgDamage = REG_USER_MSG( "Damage", 12 ); - gmsgBattery = REG_USER_MSG( "Battery", 2); - gmsgTrain = REG_USER_MSG( "Train", 1); - gmsgHudText = REG_USER_MSG( "HudText", -1 ); - gmsgSayText = REG_USER_MSG( "SayText", -1 ); - gmsgTextMsg = REG_USER_MSG( "TextMsg", -1 ); - gmsgWeaponList = REG_USER_MSG("WeaponList", -1); - gmsgResetHUD = REG_USER_MSG("ResetHUD", 1); // called every respawn - gmsgInitHUD = REG_USER_MSG("InitHUD", 0 ); // called every time a new player joins the server - gmsgShowGameTitle = REG_USER_MSG("GameTitle", 1); - gmsgDeathMsg = REG_USER_MSG( "DeathMsg", -1 ); - gmsgScoreInfo = REG_USER_MSG( "ScoreInfo", 9 ); - gmsgTeamInfo = REG_USER_MSG( "TeamInfo", -1 ); // sets the name of a player's team - gmsgTeamScore = REG_USER_MSG( "TeamScore", -1 ); // sets the score of a team on the scoreboard - gmsgGameMode = REG_USER_MSG( "GameMode", 1 ); - gmsgMOTD = REG_USER_MSG( "MOTD", -1 ); - gmsgAmmoPickup = REG_USER_MSG( "AmmoPickup", 2 ); - gmsgWeapPickup = REG_USER_MSG( "WeapPickup", 1 ); - gmsgItemPickup = REG_USER_MSG( "ItemPickup", -1 ); - gmsgHideWeapon = REG_USER_MSG( "HideWeapon", 1 ); - gmsgSetFOV = REG_USER_MSG( "SetFOV", 1 ); - gmsgShowMenu = REG_USER_MSG( "ShowMenu", -1 ); - gmsgShake = REG_USER_MSG("ScreenShake", sizeof(ScreenShake)); - gmsgFade = REG_USER_MSG("ScreenFade", sizeof(ScreenFade)); - gmsgAmmoX = REG_USER_MSG("AmmoX", 2); - - gmsgSpectator = REG_USER_MSG( "Spectator", 2 ); - - // Discwar - gmsgStartRnd = REG_USER_MSG( "StartRnd", -1 ); - gmsgEndRnd = REG_USER_MSG( "EndRnd", -1 ); - gmsgPowerup = REG_USER_MSG( "Powerup", 1 ); - gmsgReward = REG_USER_MSG( "Reward", 2 ); - gmsgFrozen = REG_USER_MSG( "Frozen", 1 ); -} - -LINK_ENTITY_TO_CLASS( player, CBasePlayer ); - - - -void CBasePlayer :: Pain( void ) -{ - float flRndSound;//sound randomizer - - flRndSound = RANDOM_FLOAT ( 0 , 1 ); - - if ( flRndSound <= 0.33 ) - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_pain5.wav", 1, ATTN_NORM); - else if ( flRndSound <= 0.66 ) - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_pain6.wav", 1, ATTN_NORM); - else - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_pain7.wav", 1, ATTN_NORM); -} - -/* - * - */ -Vector VecVelocityForDamage(float flDamage) -{ - Vector vec(RANDOM_FLOAT(-100,100), RANDOM_FLOAT(-100,100), RANDOM_FLOAT(200,300)); - - if (flDamage > -50) - vec = vec * 0.7; - else if (flDamage > -200) - vec = vec * 2; - else - vec = vec * 10; - - return vec; -} - -#if 0 /* -static void ThrowGib(entvars_t *pev, char *szGibModel, float flDamage) -{ - edict_t *pentNew = CREATE_ENTITY(); - entvars_t *pevNew = VARS(pentNew); - - pevNew->origin = pev->origin; - SET_MODEL(ENT(pevNew), szGibModel); - UTIL_SetSize(pevNew, g_vecZero, g_vecZero); - - pevNew->velocity = VecVelocityForDamage(flDamage); - pevNew->movetype = MOVETYPE_BOUNCE; - pevNew->solid = SOLID_NOT; - pevNew->avelocity.x = RANDOM_FLOAT(0,600); - pevNew->avelocity.y = RANDOM_FLOAT(0,600); - pevNew->avelocity.z = RANDOM_FLOAT(0,600); - CHANGE_METHOD(ENT(pevNew), em_think, SUB_Remove); - pevNew->ltime = gpGlobals->time; - pevNew->nextthink = gpGlobals->time + RANDOM_FLOAT(10,20); - pevNew->frame = 0; - pevNew->flags = 0; -} - - -static void ThrowHead(entvars_t *pev, char *szGibModel, floatflDamage) -{ - SET_MODEL(ENT(pev), szGibModel); - pev->frame = 0; - pev->nextthink = -1; - pev->movetype = MOVETYPE_BOUNCE; - pev->takedamage = DAMAGE_NO; - pev->solid = SOLID_NOT; - pev->view_ofs = Vector(0,0,8); - UTIL_SetSize(pev, Vector(-16,-16,0), Vector(16,16,56)); - pev->velocity = VecVelocityForDamage(flDamage); - pev->avelocity = RANDOM_FLOAT(-1,1) * Vector(0,600,0); - pev->origin.z -= 24; - ClearBits(pev->flags, FL_ONGROUND); -} - - -*/ -#endif - -int TrainSpeed(int iSpeed, int iMax) -{ - float fSpeed, fMax; - int iRet = 0; - - fMax = (float)iMax; - fSpeed = iSpeed; - - fSpeed = fSpeed/fMax; - - if (iSpeed < 0) - iRet = TRAIN_BACK; - else if (iSpeed == 0) - iRet = TRAIN_NEUTRAL; - else if (fSpeed < 0.33) - iRet = TRAIN_SLOW; - else if (fSpeed < 0.66) - iRet = TRAIN_MEDIUM; - else - iRet = TRAIN_FAST; - - return iRet; -} - -void CBasePlayer :: DeathSound( void ) -{ -} - -// override takehealth -// bitsDamageType indicates type of damage healed. - -int CBasePlayer :: TakeHealth( float flHealth, int bitsDamageType ) -{ - return CBaseMonster :: TakeHealth (flHealth, bitsDamageType); - -} - -Vector CBasePlayer :: GetGunPosition( ) -{ -// UTIL_MakeVectors(pev->v_angle); -// m_HackedGunPos = pev->view_ofs; - Vector origin; - - origin = pev->origin + pev->view_ofs; - return origin; -} - -//========================================================= -// TraceAttack -//========================================================= -void CBasePlayer :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) -{ - if ( pev->takedamage ) - { - m_LastHitGroup = ptr->iHitgroup; - - switch ( ptr->iHitgroup ) - { - case HITGROUP_GENERIC: - break; - case HITGROUP_HEAD: - flDamage *= gSkillData.plrHead; - break; - case HITGROUP_CHEST: - flDamage *= gSkillData.plrChest; - break; - case HITGROUP_STOMACH: - flDamage *= gSkillData.plrStomach; - break; - case HITGROUP_LEFTARM: - case HITGROUP_RIGHTARM: - flDamage *= gSkillData.plrArm; - break; - case HITGROUP_LEFTLEG: - case HITGROUP_RIGHTLEG: - flDamage *= gSkillData.plrLeg; - break; - default: - break; - } - - SpawnBlood(ptr->vecEndPos, BloodColor(), flDamage);// a little surface blood. - TraceBleed( flDamage, vecDir, ptr, bitsDamageType ); - AddMultiDamage( pevAttacker, this, flDamage, bitsDamageType ); - } -} - -/* - Take some damage. - NOTE: each call to TakeDamage with bitsDamageType set to a time-based damage - type will cause the damage time countdown to be reset. Thus the ongoing effects of poison, radiation - etc are implemented with subsequent calls to TakeDamage using DMG_GENERIC. -*/ - -#define ARMOR_RATIO 0.2 // Armor Takes 80% of the damage -#define ARMOR_BONUS 0.5 // Each Point of Armor is work 1/x points of health - -int CBasePlayer :: TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) -{ - // Abort if its the world doing damage - //if ( ENTINDEX( ENT(pevInflictor) ) == 0 ) - //return 0; - - if (pev->takedamage == DAMAGE_NO) - return 0; - - // Discwar instantly kills everyone when they take damage - pev->health = -1; - g_pevLastInflictor = pevInflictor; - - if ( bitsDamageType & DMG_ALWAYSGIB ) - { - Killed( pevAttacker, GIB_ALWAYS ); - } - else if ( bitsDamageType & DMG_NEVERGIB ) - { - Killed( pevAttacker, GIB_NEVER ); - } - else - { - Killed( pevAttacker, GIB_NORMAL ); - } - - g_pevLastInflictor = NULL; - return 1; -} - -void CBasePlayer::RemoveAllItems( BOOL removeSuit ) -{ - if (m_pActiveItem) - { - ResetAutoaim( ); - m_pActiveItem->Holster( ); - m_pActiveItem = NULL; - } - - m_pLastItem = NULL; - - int i; - CBasePlayerItem *pPendingItem; - for (i = 0; i < MAX_ITEM_TYPES; i++) - { - m_pActiveItem = m_rgpPlayerItems[i]; - while (m_pActiveItem) - { - pPendingItem = m_pActiveItem->m_pNext; - m_pActiveItem->Drop( ); - m_pActiveItem = pPendingItem; - } - m_rgpPlayerItems[i] = NULL; - } - m_pActiveItem = NULL; - - pev->viewmodel = 0; - pev->weaponmodel = 0; - - if ( removeSuit ) - pev->weapons = 0; - else - pev->weapons &= ~WEAPON_ALLWEAPONS; - - for ( i = 0; i < MAX_AMMO_SLOTS;i++) - m_rgAmmo[i] = 0; - - UpdateClientData(); - // send Selected Weapon Message to our client - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); - WRITE_BYTE(0); - WRITE_BYTE(0); - WRITE_BYTE(0); - MESSAGE_END(); -} - -/* - * GLOBALS ASSUMED SET: g_ulModelIndexPlayer - * - * ENTITY_METHOD(PlayerDie) - */ -void CBasePlayer::Killed( entvars_t *pevAttacker, int iGib ) -{ - CSound *pSound; - - // Discwars scoring system - if ( (m_flLastDiscHit != 0) && (gpGlobals->time < m_flLastDiscHit + MAX_SCORE_TIME_AFTER_HIT) ) - { - pevAttacker = ((CBaseEntity*)m_hLastPlayerToHitMe)->pev; - g_pevLastInflictor = ((CBaseEntity*)m_hLastPlayerToHitMe)->pev; - } - - g_pGameRules->PlayerKilled( this, pevAttacker, g_pevLastInflictor ); - - if ( m_pTank != NULL ) - { - m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - } - - // this client isn't going to be thinking for a while, so reset the sound until they respawn - pSound = CSoundEnt::SoundPointerForIndex( CSoundEnt::ClientSoundIndex( edict() ) ); - { - if ( pSound ) - { - pSound->Reset(); - } - } - - SetAnimation( PLAYER_DIE ); - - m_iRespawnFrames = 0; - - pev->modelindex = g_ulModelIndexPlayer; // don't use eyes - - pev->takedamage = DAMAGE_NO; - pev->deadflag = DEAD_DYING; - pev->movetype = MOVETYPE_TOSS; - ClearBits(pev->flags, FL_ONGROUND); - if (pev->velocity.z < 10) - pev->velocity.z += RANDOM_FLOAT(0,300); - - // clear out the suit message cache so we don't keep chattering - SetSuitUpdate(NULL, FALSE, 0); - - // send "health" update message to zero - m_iClientHealth = 0; - MESSAGE_BEGIN( MSG_ONE, gmsgHealth, NULL, pev ); - WRITE_BYTE( m_iClientHealth ); - MESSAGE_END(); - - // Tell Ammo Hud that the player is dead - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); - WRITE_BYTE(0); - WRITE_BYTE(0XFF); - WRITE_BYTE(0xFF); - MESSAGE_END(); - - // reset FOV - m_iFOV = m_iClientFOV = 0; - - MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev ); - WRITE_BYTE(0); - MESSAGE_END(); - - - // UNDONE: Put this in, but add FFADE_PERMANENT and make fade time 8.8 instead of 4.12 - // UTIL_ScreenFade( edict(), Vector(128,0,0), 6, 15, 255, FFADE_OUT | FFADE_MODULATE ); - - if ( ( pev->health < -40 && iGib != GIB_NEVER ) || iGib == GIB_ALWAYS ) - { - pev->solid = SOLID_NOT; - GibMonster(); // This clears pev->model - pev->effects |= EF_NODRAW; - - // Tell the arena that this player's died - if (m_pCurrentArena) - m_pCurrentArena->PlayerKilled( this ); - - return; - } - - // Tell the arena that this player's died - if (m_pCurrentArena) - m_pCurrentArena->PlayerKilled( this ); - - DeathSound(); - - pev->angles.x = 0; - pev->angles.z = 0; - - SetThink(&CBasePlayer::PlayerDeathThink); - pev->nextthink = gpGlobals->time + 0.1; - - // Tell all this player's discs to remove themselves after the 3rd bounce - edict_t *pFind = FIND_ENTITY_BY_CLASSNAME( NULL, "disc" ); - while ( !FNullEnt( pFind ) ) - { - CBaseEntity *pEnt = CBaseEntity::Instance( pFind ); - CDisc *pDisc = (CDisc *)pEnt; - - if ( pDisc ) - { - if ( ((CBaseEntity*)pDisc->m_hOwner) == this ) - pDisc->m_bRemoveSelf = true; - } - - pFind = FIND_ENTITY_BY_CLASSNAME( pFind, "disc" ); - } -} - -// Hit by a decapitator disc -void CBasePlayer::Decapitate( entvars_t *pevKiller ) -{ - // If the player is frozen, shatter instead of decapitating - if ( m_iFrozen ) - { - Shatter( pevKiller ); - return; - } - - if ( IsAlive() ) - { - m_LastHitGroup = HITGROUP_HEAD; - m_hLastPlayerToHitMe = CBaseEntity::Instance( pevKiller ); - m_flLastDiscHit = gpGlobals->time; - TakeDamage( pev, pevKiller, 500, DMG_NEVERGIB ); - - EMIT_SOUND(ENT(pev), CHAN_AUTO, "decap.wav", 1, ATTN_NORM); - - // Remove the Head - SetBodygroup( 1, 2 ); - - // Spawn a head - CGib *pGib = GetClassPtr( (CGib *)NULL ); - pGib->Spawn( "models/head.mdl" );// throw one head - pGib->pev->solid = SOLID_NOT; - pGib->pev->groupinfo = pev->groupinfo; - pGib->pev->origin = pev->origin + pev->view_ofs; - pGib->pev->velocity = Vector (RANDOM_FLOAT(-10,10), RANDOM_FLOAT(-10,10), 300); - pGib->pev->avelocity.x = RANDOM_FLOAT ( 100, 200 ); - pGib->pev->avelocity.y = RANDOM_FLOAT ( 100, 300 ); - pGib->m_bloodColor = BloodColor(); - } -} - -// Hit by a frozen decapitator disc -void CBasePlayer::Shatter( entvars_t *pevKiller ) -{ - if ( IsAlive() ) - { - m_LastHitGroup = HITGROUP_HEAD; - m_hLastPlayerToHitMe = CBaseEntity::Instance( pevKiller ); - m_flLastDiscHit = gpGlobals->time; - TakeDamage( pev, pevKiller, 500, DMG_NEVERGIB ); - - EMIT_SOUND(ENT(pev), CHAN_AUTO, "shatter.wav", 1, ATTN_NORM); - - // make myself invisible - pev->effects |= EF_NODRAW; - pev->solid = SOLID_NOT; - UTIL_SetOrigin( pev, pev->origin ); - - // Spawn a head - CGib::SpawnHeadGib( pev ); - CGib::SpawnRandomGibs( pev, 6, 1 ); - } -} - -#define WALK_SPEED 100 - -// Set the activity based on an event or current state -void CBasePlayer::SetAnimation( PLAYER_ANIM playerAnim ) -{ - int animDesired; - float speed; - - speed = pev->velocity.Length2D(); - - if (pev->flags & FL_FROZEN) - { - speed = 0; - playerAnim = PLAYER_IDLE; - } - - switch (playerAnim) - { - case PLAYER_JUMP: - m_IdealActivity = ACT_HOP; - break; - - case PLAYER_SUPERJUMP: - m_IdealActivity = ACT_LEAP; - break; - - case PLAYER_DIE: - m_IdealActivity = GetDeathActivity(); - break; - - case PLAYER_ATTACK1: - m_IdealActivity = ACT_BASE_THROW; - break; - - case PLAYER_FALL: - m_IdealActivity = ACT_FALL; - break; - - case PLAYER_IDLE: - case PLAYER_WALK: - if ( !FBitSet( pev->flags, FL_ONGROUND ) && (m_Activity == ACT_HOP) ) // Still jumping - { - m_IdealActivity = m_Activity; - } - else - { - m_IdealActivity = ACT_BASE_WALK; - } - break; - } - - Vector vecNormVel; - float flDot, flSideDot, flVelDot; - bool bInReverse; - int iFrame; - - // Decide which sequence to play based upon the activity - switch (m_IdealActivity) - { - case ACT_DIEFORWARD: - case ACT_FALL: - default: - if ( m_Activity == m_IdealActivity) - return; - m_Activity = ACT_FALL; - - animDesired = GetFallAnimation(); - // Already using the desired animation? - if (pev->sequence == animDesired) - return; - - pev->gaitsequence = 0; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - - case ACT_LEAP: - UTIL_MakeVectors( pev->angles ); - vecNormVel = pev->velocity.Normalize(); - flDot = DotProduct( vecNormVel, gpGlobals->v_forward ); - if ( flDot < -0.6 ) - { - // Use non-blended backflip - animDesired = LookupSequence( "backflip" ); - m_Activity = m_IdealActivity; - pev->gaitsequence = 0; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - } - else - { - // Use blended longjump - animDesired = LookupSequence( "longjump" ); - m_Activity = ACT_LEAP; - pev->gaitsequence = animDesired; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - } - break; - - case ACT_DIE_HEADSHOT: - animDesired = LookupSequence( "die_simple" ); - m_Activity = m_IdealActivity; - - pev->gaitsequence = 0; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - - case ACT_HOP: - iFrame = pev->frame / 18; - if ( iFrame >= 2 && iFrame <= 11 ) - animDesired = LookupSequence( "jump" ); - else - animDesired = LookupSequence( "jumpl" ); - // Already using the desired animation? - if (pev->sequence == animDesired) - return; - - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - - case ACT_BASE_THROW: - // No throw animation during backflip - if ( pev->sequence == LookupSequence( "backflip" ) ) - return; - - // If we're in the air, we need to use the blended longjump throw - if ( pev->sequence == LookupSequence( "longjump" ) ) - { - // Use blended longjump - animDesired = LookupSequence( "longjump_throw" ); - m_Activity = ACT_FLINCH_CLOCKWISE; - pev->gaitsequence = animDesired; - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); - return; - } - - animDesired = GetThrowAnim(); - m_Activity = m_IdealActivity; - m_flThrowTime = gpGlobals->time; - break; - - case ACT_BASE_WALK: - UTIL_MakeVectors( pev->angles ); - bInReverse = ( pev->sequence == LookupSequence("base_reverse") ); - vecNormVel = pev->velocity.Normalize(); - flDot = DotProduct( vecNormVel, gpGlobals->v_forward ); - flSideDot = DotProduct( vecNormVel, gpGlobals->v_right ); - flVelDot = DotProduct( m_vecOldVelocity, vecNormVel ); - if ( ( m_flBackupTime < gpGlobals->time ) && (m_Activity != ACT_BASE_THROW) || m_fSequenceFinished ) - { - //UTIL_MakeVectors( pev->angles ); - //ALERT(at_console, "%f\n", flDot ); - //ALERT(at_console, "%f\n", flSideDot ); - //ALERT(at_console, "%f\n", flVelDot ); - //ALERT(at_console, "%f %f\n", flVelDot, flDot ); - - if ( speed == 0 ) - { - animDesired = LookupSequence( "base_stand" ); - } - /* - else if ( ( pev->sequence == LookupSequence("base_backup") ) && ( flSideDot < -0.3 || flSideDot > 0.3 ) && (flDot < -0.3) ) - { - // Detect running backwards -> strafe transition - animDesired = LookupSequence( "base_reverse" ); - m_flTransitionTime = gpGlobals->time + 0.5; - ALERT(at_console, "HERE.. "); - } - */ - else if ( flDot < -0.6 ) // && m_flTransitionTime < gpGlobals->time ) - { - animDesired = LookupSequence( "base_backup" ); - } - else if ( ( flVelDot <= 0 ) && ( flDot <= 0.6 ) ) - { - animDesired = LookupSequence( "base_reverse" ); - m_flBackupTime = gpGlobals->time + 0.7; - pev->effects |= EF_NOINTERP; - } - else - { - if ( speed > WALK_SPEED ) - animDesired = LookupSequence( "base_run" ); - else - animDesired = LookupSequence( "base_walk" ); - } - - if (animDesired == -1) - { - animDesired = 0; - } - m_Activity = ACT_BASE_WALK; - } - else if ( bInReverse ) - { - // Don't play the backup run if we're still in the backup run - if ( DotProduct( m_vecOldVelocity, vecNormVel ) < 0 ) - { - m_flBackupTime = 0; - if ( speed > WALK_SPEED ) - animDesired = LookupSequence( "base_run" ); - else - animDesired = LookupSequence( "base_walk" ); - pev->effects |= EF_NOINTERP; - } - else - { - animDesired = pev->sequence; - } - } - else - { - animDesired = pev->sequence; - } - break; - } - - // Set gait animation - if ( m_flBackupTime > gpGlobals->time ) - { - pev->gaitsequence = LookupSequence( "base_backup" ); - } - else - { - if ( speed > WALK_SPEED ) - { - pev->gaitsequence = LookupSequence( "base_run" ); - } - else if (speed > 0) - { - pev->gaitsequence = LookupSequence( "base_walk" ); - } - } - - // Idle? - if (speed <= 0) - { - pev->gaitsequence = LookupSequence( "base_stand" ); - } - - // Already using the desired animation? - if (pev->sequence == animDesired) - return; - - // Reset to first frame of desired animation - pev->sequence = animDesired; - pev->frame = 0; - ResetSequenceInfo( ); -} - -int CBasePlayer::GetThrowAnim( void ) -{ - int throwAnim; - - if ( pev->velocity.Length2D() == 0 ) - throwAnim = LookupSequence( "base_stand_throw" ); - /* - // Choose throw anim based upon powerups. - // Multiple Powerups can be had, in which case the one considered more dangerous has the throw animation. - else if ( m_iPowerups & POW_TRIPLE ) - throwAnim = LookupSequence( "triple_throw" ); - else if ( m_iPowerups & POW_FAST ) - throwAnim = LookupSequence( "kill_throw" ); - else if ( m_iPowerups & POW_HARD ) - throwAnim = LookupSequence( "hard_throw" ); - else if ( m_iPowerups & POW_FREEZE ) - throwAnim = LookupSequence( "freeze_throw" ); - */ - else - throwAnim = LookupSequence( "base_throw" ); - - return throwAnim; -} - -int CBasePlayer::GetHoldAnim( void ) -{ - int holdAnim; - - // Choose hold anim based upon powerups. - // Multiple Powerups can be had, in which case the one considered more dangerous has the animation. - if ( m_iPowerups & POW_TRIPLE ) - holdAnim = LookupSequence( "triple_ready" ); - else if ( m_iPowerups & POW_FAST ) - holdAnim = LookupSequence( "kill_ready" ); - else if ( m_iPowerups & POW_HARD ) - holdAnim = LookupSequence( "hard_ready" ); - else if ( m_iPowerups & POW_FREEZE ) - holdAnim = LookupSequence( "freeze_ready" ); - else - holdAnim = LookupSequence( "base_ready" ); - - return holdAnim; -} - -int CBasePlayer::GetFallAnimation( void ) -{ - Vector vecNormVel = pev->velocity.Normalize(); - int fallAnim; - - UTIL_MakeVectors( pev->angles ); - float flDot = DotProduct( vecNormVel, gpGlobals->v_forward ); - float flSideDot = DotProduct( vecNormVel, gpGlobals->v_right ); - // Choose a falling animation based upon the velocity vector - if ( flDot < -0.6 ) - fallAnim = LookupSequence( "fall_b" ); - else if ( flSideDot < -0.6 ) - fallAnim = LookupSequence( "fall_r" ); - else if ( flSideDot > 0.6 ) - fallAnim = LookupSequence( "fall_l" ); - else - fallAnim = LookupSequence( "fall_f" ); - - return fallAnim; -} - -/* -=========== -WaterMove -============ -*/ -#define AIRTIME 12 // lung full of air lasts this many seconds - -void CBasePlayer::WaterMove() -{ - int air; - - if (pev->movetype == MOVETYPE_NOCLIP) - return; - - if (pev->health < 0) - return; - - // waterlevel 0 - not in water - // waterlevel 1 - feet in water - // waterlevel 2 - waist in water - // waterlevel 3 - head in water - - if (pev->waterlevel != 3) - { - // not underwater - - // play 'up for air' sound - if (pev->air_finished < gpGlobals->time) - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade1.wav", 1, ATTN_NORM); - else if (pev->air_finished < gpGlobals->time + 9) - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_wade2.wav", 1, ATTN_NORM); - - pev->air_finished = gpGlobals->time + AIRTIME; - pev->dmg = 2; - - // if we took drowning damage, give it back slowly - if (m_idrowndmg > m_idrownrestored) - { - // set drowning damage bit. hack - dmg_drownrecover actually - // makes the time based damage code 'give back' health over time. - // make sure counter is cleared so we start count correctly. - - // NOTE: this actually causes the count to continue restarting - // until all drowning damage is healed. - - m_bitsDamageType |= DMG_DROWNRECOVER; - m_bitsDamageType &= ~DMG_DROWN; - m_rgbTimeBasedDamage[itbd_DrownRecover] = 0; - } - - } - else - { // fully under water - // stop restoring damage while underwater - m_bitsDamageType &= ~DMG_DROWNRECOVER; - m_rgbTimeBasedDamage[itbd_DrownRecover] = 0; - - if (pev->air_finished < gpGlobals->time) // drown! - { - if (pev->pain_finished < gpGlobals->time) - { - // take drowning damage - pev->dmg += 1; - if (pev->dmg > 5) - pev->dmg = 5; - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), pev->dmg, DMG_DROWN); - pev->pain_finished = gpGlobals->time + 1; - - // track drowning damage, give it back when - // player finally takes a breath - - m_idrowndmg += pev->dmg; - } - } - else - { - m_bitsDamageType &= ~DMG_DROWN; - } - } - - if (!pev->waterlevel) - { - if (FBitSet(pev->flags, FL_INWATER)) - { -#if 0 - // play leave water sound - switch (RANDOM_LONG(0,3)) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade2.wav", 1, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade3.wav", 1, ATTN_NORM); break; - case 3: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade4.wav", 1, ATTN_NORM); break; - } -#endif - - ClearBits(pev->flags, FL_INWATER); - } - return; - } - - // make bubbles - - air = (int)(pev->air_finished - gpGlobals->time); - if (!RANDOM_LONG(0,0x1f) && RANDOM_LONG(0,AIRTIME-1) >= air) - { - switch (RANDOM_LONG(0,3)) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_swim1.wav", 0.8, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_swim2.wav", 0.8, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_swim3.wav", 0.8, ATTN_NORM); break; - case 3: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_swim4.wav", 0.8, ATTN_NORM); break; - } - } - - if (pev->watertype == CONTENT_LAVA) // do damage - { - if (pev->dmgtime < gpGlobals->time) - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), 10 * pev->waterlevel, DMG_BURN); - } - else if (pev->watertype == CONTENT_SLIME) // do damage - { - pev->dmgtime = gpGlobals->time + 1; - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), 4 * pev->waterlevel, DMG_ACID); - } - - if (!FBitSet(pev->flags, FL_INWATER)) - { -#if 0 - // player enter water sound - if (pev->watertype == CONTENT_WATER) - { - switch (RANDOM_LONG(0,3)) - { - case 0: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade2.wav", 1, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade3.wav", 1, ATTN_NORM); break; - case 3: EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade4.wav", 1, ATTN_NORM); break; - } - } -#endif - - SetBits(pev->flags, FL_INWATER); - pev->dmgtime = 0; - } - - if (!FBitSet(pev->flags, FL_WATERJUMP)) - pev->velocity = pev->velocity - 0.8 * pev->waterlevel * gpGlobals->frametime * pev->velocity; -} - - -// TRUE if the player is attached to a ladder -BOOL CBasePlayer::IsOnLadder( void ) -{ - return (pev->movetype == MOVETYPE_FLY); -} - -void CBasePlayer::PlayerDeathThink(void) -{ - float flForward; - - if (FBitSet(pev->flags, FL_ONGROUND)) - { - flForward = pev->velocity.Length() - 20; - if (flForward <= 0) - pev->velocity = g_vecZero; - else - pev->velocity = flForward * pev->velocity.Normalize(); - } - - if (pev->modelindex && (!m_fSequenceFinished) && (pev->deadflag == DEAD_DYING)) - { - StudioFrameAdvance( ); - - m_iRespawnFrames++; // Note, these aren't necessarily real "frames", so behavior is dependent on # of client movement commands - if ( m_iRespawnFrames < 120 ) // Animations should be no longer than this - return; - } - - if (pev->deadflag == DEAD_DYING) - pev->deadflag = DEAD_DEAD; - - StopAnimation(); - - pev->effects |= EF_NOINTERP; - pev->framerate = 0.0; - - if (pev->deadflag == DEAD_DEAD) - { - if ( g_pGameRules->FPlayerCanRespawn( this ) ) - { - m_fDeadTime = gpGlobals->time; - pev->deadflag = DEAD_RESPAWNABLE; - } - - return; - } - -// if the player has been dead for one second longer than allowed by forcerespawn, -// forcerespawn isn't on. Send the player off to an intermission camera until they -// choose to respawn. - if ( g_pGameRules->IsMultiplayer() && ( gpGlobals->time > (m_fDeadTime + 6) ) && !(m_afPhysicsFlags & PFLAG_OBSERVER) ) - { - // go to dead camera. - StartDeathCam(); - } - - // wait three seconds to respawn - if ( gpGlobals->time <= ( m_fDeadTime + 3 ) ) - return; - - pev->button = 0; - m_iRespawnFrames = 0; - - //ALERT(at_console, "Respawn\n"); - respawn(pev, !(m_afPhysicsFlags & PFLAG_OBSERVER) );// don't copy a corpse if we're in deathcam. - pev->nextthink = -1; - - // Tell the arena that this player's died - if (m_pCurrentArena) - m_pCurrentArena->PlayerRespawned( this ); -} - -//========================================================= -// StartDeathCam - find an intermission spot and send the -// player off into observer mode -//========================================================= -void CBasePlayer::StartDeathCam( void ) -{ - edict_t *pSpot, *pNewSpot; - int iRand; - - if ( pev->view_ofs == g_vecZero ) - { - // don't accept subsequent attempts to StartDeathCam() - return; - } - - pSpot = FIND_ENTITY_BY_CLASSNAME( NULL, "info_intermission"); - - if ( !FNullEnt( pSpot ) ) - { - // at least one intermission spot in the world. - iRand = RANDOM_LONG( 0, 3 ); - - while ( iRand > 0 ) - { - pNewSpot = FIND_ENTITY_BY_CLASSNAME( pSpot, "info_intermission"); - - if ( pNewSpot ) - { - pSpot = pNewSpot; - } - - iRand--; - } - - CopyToBodyQue( pev ); - StartObserver( pSpot->v.origin, pSpot->v.v_angle ); - } - else - { - // no intermission spot. Push them up in the air, looking down at their corpse - TraceResult tr; - CopyToBodyQue( pev ); - UTIL_TraceLine( pev->origin, pev->origin + Vector( 0, 0, 128 ), ignore_monsters, edict(), &tr ); - StartObserver( tr.vecEndPos, UTIL_VecToAngles( tr.vecEndPos - pev->origin ) ); - return; - } -} - -// -// PlayerUse - handles USE keypress -// -#define PLAYER_SEARCH_RADIUS (float)64 - -void CBasePlayer::PlayerUse ( void ) -{ - // Was use pressed or released? - if ( ! ((pev->button | m_afButtonPressed | m_afButtonReleased) & IN_USE) ) - return; - - // Hit Use on a train? - if ( m_afButtonPressed & IN_USE ) - { - if ( m_pTank != NULL ) - { - // Stop controlling the tank - // TODO: Send HUD Update - m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - return; - } - else - { - if ( m_afPhysicsFlags & PFLAG_ONTRAIN ) - { - m_afPhysicsFlags &= ~PFLAG_ONTRAIN; - m_iTrain = TRAIN_NEW|TRAIN_OFF; - return; - } - else - { // Start controlling the train! - CBaseEntity *pTrain = CBaseEntity::Instance( pev->groundentity ); - - if ( pTrain && !(pev->button & IN_JUMP) && FBitSet(pev->flags, FL_ONGROUND) && (pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) && pTrain->OnControls(pev) ) - { - m_afPhysicsFlags |= PFLAG_ONTRAIN; - m_iTrain = TrainSpeed(pTrain->pev->speed, pTrain->pev->impulse); - m_iTrain |= TRAIN_NEW; - EMIT_SOUND( ENT(pev), CHAN_ITEM, "plats/train_use1.wav", 0.8, ATTN_NORM); - return; - } - } - } - } - - CBaseEntity *pObject = NULL; - CBaseEntity *pClosest = NULL; - Vector vecLOS; - float flMaxDot = VIEW_FIELD_NARROW; - float flDot; - - UTIL_MakeVectors ( pev->v_angle );// so we know which way we are facing - - while ((pObject = UTIL_FindEntityInSphere( pObject, pev->origin, PLAYER_SEARCH_RADIUS )) != NULL) - { - - if (pObject->ObjectCaps() & (FCAP_IMPULSE_USE | FCAP_CONTINUOUS_USE | FCAP_ONOFF_USE)) - { - // !!!PERFORMANCE- should this check be done on a per case basis AFTER we've determined that - // this object is actually usable? This dot is being done for every object within PLAYER_SEARCH_RADIUS - // when player hits the use key. How many objects can be in that area, anyway? (sjb) - vecLOS = (VecBModelOrigin( pObject->pev ) - (pev->origin + pev->view_ofs)); - - // This essentially moves the origin of the target to the corner nearest the player to test to see - // if it's "hull" is in the view cone - vecLOS = UTIL_ClampVectorToBox( vecLOS, pObject->pev->size * 0.5 ); - - flDot = DotProduct (vecLOS , gpGlobals->v_forward); - if (flDot > flMaxDot ) - {// only if the item is in front of the user - pClosest = pObject; - flMaxDot = flDot; -// ALERT( at_console, "%s : %f\n", STRING( pObject->pev->classname ), flDot ); - } -// ALERT( at_console, "%s : %f\n", STRING( pObject->pev->classname ), flDot ); - } - } - pObject = pClosest; - - // Found an object - if (pObject ) - { - //!!!UNDONE: traceline here to prevent USEing buttons through walls - int caps = pObject->ObjectCaps(); - - if ( m_afButtonPressed & IN_USE ) - EMIT_SOUND( ENT(pev), CHAN_ITEM, "common/wpn_select.wav", 0.4, ATTN_NORM); - - if ( ( (pev->button & IN_USE) && (caps & FCAP_CONTINUOUS_USE) ) || - ( (m_afButtonPressed & IN_USE) && (caps & (FCAP_IMPULSE_USE|FCAP_ONOFF_USE)) ) ) - { - if ( caps & FCAP_CONTINUOUS_USE ) - m_afPhysicsFlags |= PFLAG_USING; - - pObject->Use( this, this, USE_SET, 1 ); - } - // UNDONE: Send different USE codes for ON/OFF. Cache last ONOFF_USE object to send 'off' if you turn away - else if ( (m_afButtonReleased & IN_USE) && (pObject->ObjectCaps() & FCAP_ONOFF_USE) ) // BUGBUG This is an "off" use - { - pObject->Use( this, this, USE_SET, 0 ); - } - } - else - { - if ( m_afButtonPressed & IN_USE ) - EMIT_SOUND( ENT(pev), CHAN_ITEM, "common/wpn_denyselect.wav", 0.4, ATTN_NORM); - } -} - - - -void CBasePlayer::Jump() -{ - Vector vecWallCheckDir;// direction we're tracing a line to find a wall when walljumping - Vector vecAdjustedVelocity; - Vector vecSpot; - TraceResult tr; - - if (FBitSet(pev->flags, FL_WATERJUMP)) - return; - - if (pev->waterlevel >= 2) - { - return; - } - - // jump velocity is sqrt( height * gravity * 2) - - // If this isn't the first frame pressing the jump button, break out. - if ( !FBitSet( m_afButtonPressed, IN_JUMP ) ) - return; // don't pogo stick - - if ( !(pev->flags & FL_ONGROUND) || !pev->groundentity ) - { - return; - } - -// many features in this function use v_forward, so makevectors now. - UTIL_MakeVectors (pev->angles); - - SetAnimation( PLAYER_JUMP ); - - // If you're standing on a conveyor, add it's velocity to yours (for momentum) - entvars_t *pevGround = VARS(pev->groundentity); - if ( pevGround && (pevGround->flags & FL_CONVEYOR) ) - { - pev->velocity = pev->velocity + pev->basevelocity; - } -} - - - -// This is a glorious hack to find free space when you've crouched into some solid space -// Our crouching collisions do not work correctly for some reason and this is easier -// than fixing the problem :( -void FixPlayerCrouchStuck( edict_t *pPlayer ) -{ - TraceResult trace; - - // Move up as many as 18 pixels if the player is stuck. - for ( int i = 0; i < 18; i++ ) - { - UTIL_TraceHull( pPlayer->v.origin, pPlayer->v.origin, dont_ignore_monsters, head_hull, pPlayer, &trace ); - if ( trace.fStartSolid ) - pPlayer->v.origin.z ++; - else - break; - } -} - -void CBasePlayer::Duck( ) -{ - return; -} - -// -// ID's player as such. -// -int CBasePlayer::Classify ( void ) -{ - return CLASS_PLAYER; -} - - -void CBasePlayer::AddPoints( int score, BOOL bAllowNegativeScore ) -{ - // Positive score always adds - if ( score < 0 ) - { - if ( !bAllowNegativeScore ) - { - if ( pev->frags < 0 ) // Can't go more negative - return; - - if ( -score > pev->frags ) // Will this go negative? - { - score = -pev->frags; // Sum will be 0 - } - } - } - - pev->frags += score; -} - - -void CBasePlayer::AddPointsToTeam( int score, BOOL bAllowNegativeScore ) -{ - int index = entindex(); - - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - - if ( pPlayer && i != index ) - { - if ( g_pGameRules->PlayerRelationship( this, pPlayer ) == GR_TEAMMATE ) - { - pPlayer->AddPoints( score, bAllowNegativeScore ); - } - } - } -} - -#if 0 -void CBasePlayer::CheckWeapon(void) -{ - // play a weapon idle anim if it's time! - if ( gpGlobals->time > m_flTimeWeaponIdle ) - { - WeaponIdle ( ); - } -} -#endif - - -// play a footstep if it's time - this will eventually be frame-based. not time based. - -#define STEP_CONCRETE 0 // default step sound -#define STEP_METAL 1 // metal floor -#define STEP_DIRT 2 // dirt, sand, rock -#define STEP_VENT 3 // ventillation duct -#define STEP_GRATE 4 // metal grating -#define STEP_TILE 5 // floor tiles -#define STEP_SLOSH 6 // shallow liquid puddle -#define STEP_WADE 7 // wading in liquid -#define STEP_LADDER 8 // climbing ladder - -// Play correct step sound for material we're on or in - -void CBasePlayer :: PlayStepSound(int step, float fvol) -{ - static int iSkipStep = 0; - - if ( !g_pGameRules->PlayFootstepSounds( this, fvol ) ) - return; - - // irand - 0,1 for right foot, 2,3 for left foot - // used to alternate left and right foot - int irand = RANDOM_LONG(0,1) + (m_iStepLeft * 2); - - m_iStepLeft = !m_iStepLeft; - - switch (step) - { - default: - case STEP_CONCRETE: - switch (irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_step1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_step3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_step2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_step4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_METAL: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_metal1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_metal3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_metal2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_metal4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_DIRT: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_dirt1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_dirt3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_dirt2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_dirt4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_VENT: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_duct1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_duct3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_duct2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_duct4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_GRATE: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_grate1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_grate3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_grate2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_grate4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_TILE: - if (!RANDOM_LONG(0,4)) - irand = 4; - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile4.wav", fvol, ATTN_NORM); break; - case 4: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_tile5.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_SLOSH: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_slosh1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_slosh3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_slosh2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_slosh4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_WADE: - if ( iSkipStep == 0 ) - { - iSkipStep++; - break; - } - - if ( iSkipStep++ == 3 ) - { - iSkipStep = 0; - } - - switch (irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_wade1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_wade2.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_wade3.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_wade4.wav", fvol, ATTN_NORM); break; - } - break; - case STEP_LADDER: - switch(irand) - { - // right foot - case 0: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_ladder1.wav", fvol, ATTN_NORM); break; - case 1: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_ladder3.wav", fvol, ATTN_NORM); break; - // left foot - case 2: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_ladder2.wav", fvol, ATTN_NORM); break; - case 3: EMIT_SOUND( ENT(pev), CHAN_BODY, "player/pl_ladder4.wav", fvol, ATTN_NORM); break; - } - break; - } -} - -// Simple mapping from texture type character to step type - -int MapTextureTypeStepType(char chTextureType) -{ -switch (chTextureType) - { - default: - case CHAR_TEX_CONCRETE: return STEP_CONCRETE; - case CHAR_TEX_METAL: return STEP_METAL; - case CHAR_TEX_DIRT: return STEP_DIRT; - case CHAR_TEX_VENT: return STEP_VENT; - case CHAR_TEX_GRATE: return STEP_GRATE; - case CHAR_TEX_TILE: return STEP_TILE; - case CHAR_TEX_SLOSH: return STEP_SLOSH; - } -} - -// Play left or right footstep based on material player is on or in - -void CBasePlayer :: UpdateStepSound( void ) -{ - int fWalking; - float fvol; - char szbuffer[64]; - const char *pTextureName; - Vector start, end; - float rgfl1[3]; - float rgfl2[3]; - Vector knee; - Vector feet; - Vector center; - float height; - float speed; - float velrun; - float velwalk; - float flduck; - int fLadder; - int step; - - if (gpGlobals->time <= m_flTimeStepSound) - return; - - if (pev->flags & FL_FROZEN) - return; - - if (m_flTouchedByJumpPad > gpGlobals->time) - return; - - speed = pev->velocity.Length(); - - // determine if we are on a ladder - fLadder = IsOnLadder(); - - // UNDONE: need defined numbers for run, walk, crouch, crouch run velocities!!!! - if (FBitSet(pev->flags, FL_DUCKING) || fLadder) - { - velwalk = 60; // These constants should be based on cl_movespeedkey * cl_forwardspeed somehow - velrun = 80; // UNDONE: Move walking to server - flduck = 0.1; - } - else - { - velwalk = 120; - velrun = 210; - flduck = 0.0; - } - - // ALERT (at_console, "vel: %f\n", vecVel.Length()); - - // if we're on a ladder or on the ground, and we're moving fast enough, - // play step sound. Also, if m_flTimeStepSound is zero, get the new - // sound right away - we just started moving in new level. - - if ((fLadder || FBitSet (pev->flags, FL_ONGROUND)) && pev->velocity != g_vecZero - && (speed >= velwalk || !m_flTimeStepSound)) - { - SetAnimation( PLAYER_WALK ); - - fWalking = speed < velrun; - - center = knee = feet = (pev->absmin + pev->absmax) * 0.5; - height = pev->absmax.z - pev->absmin.z; - - knee.z = pev->absmin.z + height * 0.2; - feet.z = pev->absmin.z; - - // find out what we're stepping in or on... - if (fLadder) - { - step = STEP_LADDER; - fvol = 0.35; - m_flTimeStepSound = gpGlobals->time + 0.35; - } - else if ( UTIL_PointContents ( knee ) == CONTENTS_WATER ) - { - step = STEP_WADE; - fvol = 0.65; - m_flTimeStepSound = gpGlobals->time + 0.6; - } - else if (UTIL_PointContents ( feet ) == CONTENTS_WATER ) - { - step = STEP_SLOSH; - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - } - else - { - // find texture under player, if different from current texture, - // get material type - - start = end = center; // center point of player BB - start.z = end.z = pev->absmin.z; // copy zmin - start.z += 4.0; // extend start up - end.z -= 24.0; // extend end down - - start.CopyToArray(rgfl1); - end.CopyToArray(rgfl2); - - pTextureName = TRACE_TEXTURE( ENT( pev->groundentity), rgfl1, rgfl2 ); - if ( pTextureName ) - { - // strip leading '-0' or '{' or '!' - if (*pTextureName == '-') - pTextureName += 2; - if (*pTextureName == '{' || *pTextureName == '!') - pTextureName++; - - if (_strnicmp(pTextureName, m_szTextureName, CBTEXTURENAMEMAX-1)) - { - // current texture is different from texture player is on... - // set current texture - strcpy(szbuffer, pTextureName); - szbuffer[CBTEXTURENAMEMAX - 1] = 0; - strcpy(m_szTextureName, szbuffer); - - // ALERT ( at_aiconsole, "texture: %s\n", m_szTextureName ); - - // get texture type - m_chTextureType = TEXTURETYPE_Find(m_szTextureName); - } - } - - step = MapTextureTypeStepType(m_chTextureType); - - switch (m_chTextureType) - { - default: - case CHAR_TEX_CONCRETE: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_METAL: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_DIRT: - fvol = fWalking ? 0.25 : 0.55; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_VENT: - fvol = fWalking ? 0.4 : 0.7; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_GRATE: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_TILE: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - - case CHAR_TEX_SLOSH: - fvol = fWalking ? 0.2 : 0.5; - m_flTimeStepSound = fWalking ? gpGlobals->time + 0.4 : gpGlobals->time + 0.3; - break; - } - } - - m_flTimeStepSound += flduck; // slower step time if ducking - - // play the sound - - // 35% volume if ducking - if ( pev->flags & FL_DUCKING ) - fvol *= 0.35; - } -} - - -#define CLIMB_SHAKE_FREQUENCY 22 // how many frames in between screen shakes when climbing -#define MAX_CLIMB_SPEED 200 // fastest vertical climbing speed possible -#define CLIMB_SPEED_DEC 15 // climbing deceleration rate -#define CLIMB_PUNCH_X -7 // how far to 'punch' client X axis when climbing -#define CLIMB_PUNCH_Z 7 // how far to 'punch' client Z axis when climbing - -void CBasePlayer::PreThink(void) -{ - int buttonsChanged = (m_afButtonLast ^ pev->button); // These buttons have changed this frame - - // Fade away the renderfx - if ( pev->renderamt ) - { - if ( !m_iFrozen ) - pev->renderamt -= 25; - - if (pev->renderamt <= 0 || (m_flFreezeTime < gpGlobals->time && m_iFrozen )) - ClearFreezeAndRender(); - } - - if ( m_flSendArenaStatus != -1 && m_flSendArenaStatus <= gpGlobals->time ) - { - g_pGameRules->UpdateGameMode( this ); - m_flSendArenaStatus = -1; - } - - // Hack to pass down the weapon information to the client after they've connected. - // Needed for listen servers because they lose msgs while bringing up the svr. - if ( m_flKnownItemTime && m_flKnownItemTime < gpGlobals->time ) - { - CLIENT_COMMAND( edict(), "r_drawviewmodel 0\n" ); - m_fKnownItem = FALSE; - m_flKnownItemTime = 0; - } - - // Debounced button codes for pressed/released - // UNDONE: Do we need auto-repeat? - m_afButtonPressed = buttonsChanged & pev->button; // The changed ones still down are "pressed" - m_afButtonReleased = buttonsChanged & (~pev->button); // The ones not down are "released" - - g_pGameRules->PlayerThink( this ); - - if ( g_fGameOver ) - return; // intermission or finale - - UTIL_MakeVectors(pev->v_angle); // is this still used? - - ItemPreFrame( ); - WaterMove(); - - if ( g_pGameRules && g_pGameRules->FAllowFlashlight() ) - m_iHideHUD &= ~HIDEHUD_FLASHLIGHT; - else - m_iHideHUD |= HIDEHUD_FLASHLIGHT; - - - // JOHN: checks if new client data (for HUD and view control) needs to be sent to the client - UpdateClientData(); - - CheckTimeBasedDamage(); - - // Observer Button Handling - if ( IsObserver() ) - { - Observer_HandleButtons(); - pev->impulse = 0; - return; - } - - CheckSuitUpdate(); - - if (pev->deadflag >= DEAD_DYING) - { - PlayerDeathThink(); - return; - } - - // So the correct flags get sent to client asap. - // - if ( m_afPhysicsFlags & PFLAG_ONTRAIN ) - pev->flags |= FL_ONTRAIN; - else - pev->flags &= ~FL_ONTRAIN; - - // Train speed control - if ( m_afPhysicsFlags & PFLAG_ONTRAIN ) - { - CBaseEntity *pTrain = CBaseEntity::Instance( pev->groundentity ); - float vel; - - if ( !pTrain ) - { - TraceResult trainTrace; - // Maybe this is on the other side of a level transition - UTIL_TraceLine( pev->origin, pev->origin + Vector(0,0,-38), ignore_monsters, ENT(pev), &trainTrace ); - - // HACKHACK - Just look for the func_tracktrain classname - if ( trainTrace.flFraction != 1.0 && trainTrace.pHit ) - pTrain = CBaseEntity::Instance( trainTrace.pHit ); - - - if ( !pTrain || !(pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) || !pTrain->OnControls(pev) ) - { - //ALERT( at_error, "In train mode with no train!\n" ); - m_afPhysicsFlags &= ~PFLAG_ONTRAIN; - m_iTrain = TRAIN_NEW|TRAIN_OFF; - return; - } - } - else if ( !FBitSet( pev->flags, FL_ONGROUND ) || FBitSet( pTrain->pev->spawnflags, SF_TRACKTRAIN_NOCONTROL ) || (pev->button & (IN_MOVELEFT|IN_MOVERIGHT) ) ) - { - // Turn off the train if you jump, strafe, or the train controls go dead - m_afPhysicsFlags &= ~PFLAG_ONTRAIN; - m_iTrain = TRAIN_NEW|TRAIN_OFF; - return; - } - - pev->velocity = g_vecZero; - vel = 0; - if ( m_afButtonPressed & IN_FORWARD ) - { - vel = 1; - pTrain->Use( this, this, USE_SET, (float)vel ); - } - else if ( m_afButtonPressed & IN_BACK ) - { - vel = -1; - pTrain->Use( this, this, USE_SET, (float)vel ); - } - - if (vel) - { - m_iTrain = TrainSpeed(pTrain->pev->speed, pTrain->pev->impulse); - m_iTrain |= TRAIN_ACTIVE|TRAIN_NEW; - } - - } else if (m_iTrain & TRAIN_ACTIVE) - m_iTrain = TRAIN_NEW; // turn off train - - // DISCWAR: No Jumping or Ducking - /* - if (pev->button & IN_JUMP) - { - // If on a ladder, jump off the ladder - // else Jump - Jump(); - } - // If trying to duck, already ducked, or in the process of ducking - if ((pev->button & IN_DUCK) || FBitSet(pev->flags,FL_DUCKING) || (m_afPhysicsFlags & PFLAG_DUCKING) ) - Duck(); - */ - - // DISCWAR: Impart the velocity from a disc hit onto the player - if ( m_vecHitVelocity != g_vecZero ) - { - pev->velocity = m_vecHitVelocity; - m_vecHitVelocity = g_vecZero; - } - - // play a footstep if it's time - this will eventually be frame-based. not time based. - - UpdateStepSound(); - - if ( !FBitSet ( pev->flags, FL_ONGROUND ) ) - { - m_flFallVelocity = -pev->velocity.z; - } - - // StudioFrameAdvance( );//!!!HACKHACK!!! Can't be hit by traceline when not animating? - - // Clear out ladder pointer - m_hEnemy = NULL; - - if ( m_afPhysicsFlags & PFLAG_ONBARNACLE ) - { - pev->velocity = g_vecZero; - } -} -/* Time based Damage works as follows: - 1) There are several types of timebased damage: - - #define DMG_PARALYZE (1 << 14) // slows affected creature down - #define DMG_NERVEGAS (1 << 15) // nerve toxins, very bad - #define DMG_POISON (1 << 16) // blood poisioning - #define DMG_RADIATION (1 << 17) // radiation exposure - #define DMG_DROWNRECOVER (1 << 18) // drown recovery - #define DMG_ACID (1 << 19) // toxic chemicals or acid burns - #define DMG_SLOWBURN (1 << 20) // in an oven - #define DMG_SLOWFREEZE (1 << 21) // in a subzero freezer - - 2) A new hit inflicting tbd restarts the tbd counter - each monster has an 8bit counter, - per damage type. The counter is decremented every second, so the maximum time - an effect will last is 255/60 = 4.25 minutes. Of course, staying within the radius - of a damaging effect like fire, nervegas, radiation will continually reset the counter to max. - - 3) Every second that a tbd counter is running, the player takes damage. The damage - is determined by the type of tdb. - Paralyze - 1/2 movement rate, 30 second duration. - Nervegas - 5 points per second, 16 second duration = 80 points max dose. - Poison - 2 points per second, 25 second duration = 50 points max dose. - Radiation - 1 point per second, 50 second duration = 50 points max dose. - Drown - 5 points per second, 2 second duration. - Acid/Chemical - 5 points per second, 10 second duration = 50 points max. - Burn - 10 points per second, 2 second duration. - Freeze - 3 points per second, 10 second duration = 30 points max. - - 4) Certain actions or countermeasures counteract the damaging effects of tbds: - - Armor/Heater/Cooler - Chemical(acid),burn, freeze all do damage to armor power, then to body - - recharged by suit recharger - Air In Lungs - drowning damage is done to air in lungs first, then to body - - recharged by poking head out of water - - 10 seconds if swiming fast - Air In SCUBA - drowning damage is done to air in tanks first, then to body - - 2 minutes in tanks. Need new tank once empty. - Radiation Syringe - Each syringe full provides protection vs one radiation dosage - Antitoxin Syringe - Each syringe full provides protection vs one poisoning (nervegas or poison). - Health kit - Immediate stop to acid/chemical, fire or freeze damage. - Radiation Shower - Immediate stop to radiation damage, acid/chemical or fire damage. - - -*/ - -// If player is taking time based damage, continue doing damage to player - -// this simulates the effect of being poisoned, gassed, dosed with radiation etc - -// anything that continues to do damage even after the initial contact stops. -// Update all time based damage counters, and shut off any that are done. - -// The m_bitsDamageType bit MUST be set if any damage is to be taken. -// This routine will detect the initial on value of the m_bitsDamageType -// and init the appropriate counter. Only processes damage every second. - -//#define PARALYZE_DURATION 30 // number of 2 second intervals to take damage -//#define PARALYZE_DAMAGE 0.0 // damage to take each 2 second interval - -//#define NERVEGAS_DURATION 16 -//#define NERVEGAS_DAMAGE 5.0 - -//#define POISON_DURATION 25 -//#define POISON_DAMAGE 2.0 - -//#define RADIATION_DURATION 50 -//#define RADIATION_DAMAGE 1.0 - -//#define ACID_DURATION 10 -//#define ACID_DAMAGE 5.0 - -//#define SLOWBURN_DURATION 2 -//#define SLOWBURN_DAMAGE 1.0 - -//#define SLOWFREEZE_DURATION 1.0 -//#define SLOWFREEZE_DAMAGE 3.0 - -/* */ - - -void CBasePlayer::CheckTimeBasedDamage() -{ - int i; - BYTE bDuration = 0; - - static float gtbdPrev = 0.0; - - if (!(m_bitsDamageType & DMG_TIMEBASED)) - return; - - // only check for time based damage approx. every 2 seconds - if ( fabs(gpGlobals->time - m_tbdPrev) < 2.0) - return; - - m_tbdPrev = gpGlobals->time; - - for (i = 0; i < CDMG_TIMEBASED; i++) - { - // make sure bit is set for damage type - if (m_bitsDamageType & (DMG_PARALYZE << i)) - { - switch (i) - { - case itbd_Paralyze: - // UNDONE - flag movement as half-speed - bDuration = PARALYZE_DURATION; - break; - case itbd_NerveGas: -// TakeDamage(pev, pev, NERVEGAS_DAMAGE, DMG_GENERIC); - bDuration = NERVEGAS_DURATION; - break; - case itbd_Poison: - TakeDamage(pev, pev, POISON_DAMAGE, DMG_GENERIC); - bDuration = POISON_DURATION; - break; - case itbd_Radiation: -// TakeDamage(pev, pev, RADIATION_DAMAGE, DMG_GENERIC); - bDuration = RADIATION_DURATION; - break; - case itbd_DrownRecover: - // NOTE: this hack is actually used to RESTORE health - // after the player has been drowning and finally takes a breath - if (m_idrowndmg > m_idrownrestored) - { - int idif = V_min(m_idrowndmg - m_idrownrestored, 10); - - TakeHealth(idif, DMG_GENERIC); - m_idrownrestored += idif; - } - bDuration = 4; // get up to 5*10 = 50 points back - break; - case itbd_Acid: -// TakeDamage(pev, pev, ACID_DAMAGE, DMG_GENERIC); - bDuration = ACID_DURATION; - break; - case itbd_SlowBurn: -// TakeDamage(pev, pev, SLOWBURN_DAMAGE, DMG_GENERIC); - bDuration = SLOWBURN_DURATION; - break; - case itbd_SlowFreeze: -// TakeDamage(pev, pev, SLOWFREEZE_DAMAGE, DMG_GENERIC); - bDuration = SLOWFREEZE_DURATION; - break; - default: - bDuration = 0; - } - - if (m_rgbTimeBasedDamage[i]) - { - // use up an antitoxin on poison or nervegas after a few seconds of damage - if (((i == itbd_NerveGas) && (m_rgbTimeBasedDamage[i] < NERVEGAS_DURATION)) || - ((i == itbd_Poison) && (m_rgbTimeBasedDamage[i] < POISON_DURATION))) - { - if (m_rgItems[ITEM_ANTIDOTE]) - { - m_rgbTimeBasedDamage[i] = 0; - m_rgItems[ITEM_ANTIDOTE]--; - SetSuitUpdate("!HEV_HEAL4", FALSE, SUIT_REPEAT_OK); - } - } - - - // decrement damage duration, detect when done. - if (!m_rgbTimeBasedDamage[i] || --m_rgbTimeBasedDamage[i] == 0) - { - m_rgbTimeBasedDamage[i] = 0; - // if we're done, clear damage bits - m_bitsDamageType &= ~(DMG_PARALYZE << i); - } - } - else - // first time taking this damage type - init damage duration - m_rgbTimeBasedDamage[i] = bDuration; - } - } -} - -/* -THE POWER SUIT - -The Suit provides 3 main functions: Protection, Notification and Augmentation. -Some functions are automatic, some require power. -The player gets the suit shortly after getting off the train in C1A0 and it stays -with him for the entire game. - -Protection - - Heat/Cold - When the player enters a hot/cold area, the heating/cooling indicator on the suit - will come on and the battery will drain while the player stays in the area. - After the battery is dead, the player starts to take damage. - This feature is built into the suit and is automatically engaged. - Radiation Syringe - This will cause the player to be immune from the effects of radiation for N seconds. Single use item. - Anti-Toxin Syringe - This will cure the player from being poisoned. Single use item. - Health - Small (1st aid kits, food, etc.) - Large (boxes on walls) - Armor - The armor works using energy to create a protective field that deflects a - percentage of damage projectile and explosive attacks. After the armor has been deployed, - it will attempt to recharge itself to full capacity with the energy reserves from the battery. - It takes the armor N seconds to fully charge. - -Notification (via the HUD) - -x Health -x Ammo -x Automatic Health Care - Notifies the player when automatic healing has been engaged. -x Geiger counter - Classic Geiger counter sound and status bar at top of HUD - alerts player to dangerous levels of radiation. This is not visible when radiation levels are normal. -x Poison - Armor - Displays the current level of armor. - -Augmentation - - Reanimation (w/adrenaline) - Causes the player to come back to life after he has been dead for 3 seconds. - Will not work if player was gibbed. Single use. - Long Jump - Used by hitting the ??? key(s). Caused the player to further than normal. - SCUBA - Used automatically after picked up and after player enters the water. - Works for N seconds. Single use. - -Things powered by the battery - - Armor - Uses N watts for every M units of damage. - Heat/Cool - Uses N watts for every second in hot/cold area. - Long Jump - Uses N watts for every jump. - Alien Cloak - Uses N watts for each use. Each use lasts M seconds. - Alien Shield - Augments armor. Reduces Armor drain by one half - -*/ - -// if in range of radiation source, ping geiger counter -#define GEIGERDELAY 0.25 - -void CBasePlayer :: UpdateGeigerCounter( void ) -{ - BYTE range; - - // delay per update ie: don't flood net with these msgs - if (gpGlobals->time < m_flgeigerDelay) - return; - - m_flgeigerDelay = gpGlobals->time + GEIGERDELAY; - - // send range to radition source to client - - range = (BYTE) (m_flgeigerRange / 4); - - if (range != m_igeigerRangePrev) - { - m_igeigerRangePrev = range; - - MESSAGE_BEGIN( MSG_ONE, gmsgGeigerRange, NULL, pev ); - WRITE_BYTE( range ); - MESSAGE_END(); - } - - // reset counter and semaphore - if (!RANDOM_LONG(0,3)) - m_flgeigerRange = 1000; - -} - -/* -================ -CheckSuitUpdate - -Play suit update if it's time -================ -*/ - -#define SUITUPDATETIME 3.5 -#define SUITFIRSTUPDATETIME 0.1 - -void CBasePlayer::CheckSuitUpdate() -{ - int i; - int isentence = 0; - int isearch = m_iSuitPlayNext; - - // Ignore suit updates if no suit - if ( !(pev->weapons & (1<IsMultiplayer() ) - { - // don't bother updating HEV voice in multiplayer. - return; - } - - if ( gpGlobals->time >= m_flSuitUpdate && m_flSuitUpdate > 0) - { - // play a sentence off of the end of the queue - for (i = 0; i < CSUITPLAYLIST; i++) - { - if (isentence = m_rgSuitPlayList[isearch]) - break; - - if (++isearch == CSUITPLAYLIST) - isearch = 0; - } - - if (isentence) - { - m_rgSuitPlayList[isearch] = 0; - if (isentence > 0) - { - // play sentence number - - char sentence[CBSENTENCENAME_MAX+1]; - strcpy(sentence, "!"); - strcat(sentence, gszallsentencenames[isentence]); - EMIT_SOUND_SUIT(ENT(pev), sentence); - } - else - { - // play sentence group - EMIT_GROUPID_SUIT(ENT(pev), -isentence); - } - m_flSuitUpdate = gpGlobals->time + SUITUPDATETIME; - } - else - // queue is empty, don't check - m_flSuitUpdate = 0; - } -} - -// add sentence to suit playlist queue. if fgroup is true, then -// name is a sentence group (HEV_AA), otherwise name is a specific -// sentence name ie: !HEV_AA0. If iNoRepeat is specified in -// seconds, then we won't repeat playback of this word or sentence -// for at least that number of seconds. - -void CBasePlayer::SetSuitUpdate(char *name, int fgroup, int iNoRepeatTime) -{ - int i; - int isentence; - int iempty = -1; - - - // Ignore suit updates if no suit - if ( !(pev->weapons & (1<IsMultiplayer() ) - { - // due to static channel design, etc. We don't play HEV sounds in multiplayer right now. - return; - } - - // if name == NULL, then clear out the queue - - if (!name) - { - for (i = 0; i < CSUITPLAYLIST; i++) - m_rgSuitPlayList[i] = 0; - return; - } - // get sentence or group number - if (!fgroup) - { - isentence = SENTENCEG_Lookup(name, NULL); - if (isentence < 0) - return; - } - else - // mark group number as negative - isentence = -SENTENCEG_GetIndex(name); - - // check norepeat list - this list lets us cancel - // the playback of words or sentences that have already - // been played within a certain time. - - for (i = 0; i < CSUITNOREPEAT; i++) - { - if (isentence == m_rgiSuitNoRepeat[i]) - { - // this sentence or group is already in - // the norepeat list - - if (m_rgflSuitNoRepeatTime[i] < gpGlobals->time) - { - // norepeat time has expired, clear it out - m_rgiSuitNoRepeat[i] = 0; - m_rgflSuitNoRepeatTime[i] = 0.0; - iempty = i; - break; - } - else - { - // don't play, still marked as norepeat - return; - } - } - // keep track of empty slot - if (!m_rgiSuitNoRepeat[i]) - iempty = i; - } - - // sentence is not in norepeat list, save if norepeat time was given - - if (iNoRepeatTime) - { - if (iempty < 0) - iempty = RANDOM_LONG(0, CSUITNOREPEAT-1); // pick random slot to take over - m_rgiSuitNoRepeat[iempty] = isentence; - m_rgflSuitNoRepeatTime[iempty] = iNoRepeatTime + gpGlobals->time; - } - - // find empty spot in queue, or overwrite last spot - - m_rgSuitPlayList[m_iSuitPlayNext++] = isentence; - if (m_iSuitPlayNext == CSUITPLAYLIST) - m_iSuitPlayNext = 0; - - if (m_flSuitUpdate <= gpGlobals->time) - { - if (m_flSuitUpdate == 0) - // play queue is empty, don't delay too long before playback - m_flSuitUpdate = gpGlobals->time + SUITFIRSTUPDATETIME; - else - m_flSuitUpdate = gpGlobals->time + SUITUPDATETIME; - } - -} - -/* -================ -CheckPowerups - -Check for turning off powerups - -GLOBALS ASSUMED SET: g_ulModelIndexPlayer -================ -*/ - static void -CheckPowerups(entvars_t *pev) -{ - if (pev->health <= 0) - return; - - pev->modelindex = g_ulModelIndexPlayer; // don't use eyes -} - - -//========================================================= -// UpdatePlayerSound - updates the position of the player's -// reserved sound slot in the sound list. -//========================================================= -void CBasePlayer :: UpdatePlayerSound ( void ) -{ - int iBodyVolume; - int iVolume; - CSound *pSound; - - pSound = CSoundEnt::SoundPointerForIndex( CSoundEnt :: ClientSoundIndex( edict() ) ); - - if ( !pSound ) - { - ALERT ( at_console, "Client lost reserved sound!\n" ); - return; - } - - pSound->m_iType = bits_SOUND_NONE; - - // now calculate the best target volume for the sound. If the player's weapon - // is louder than his body/movement, use the weapon volume, else, use the body volume. - - if ( FBitSet ( pev->flags, FL_ONGROUND ) ) - { - iBodyVolume = pev->velocity.Length(); - - // clamp the noise that can be made by the body, in case a push trigger, - // weapon recoil, or anything shoves the player abnormally fast. - if ( iBodyVolume > 512 ) - { - iBodyVolume = 512; - } - } - else - { - iBodyVolume = 0; - } - - if ( pev->button & IN_JUMP ) - { - iBodyVolume += 100; - } - -// convert player move speed and actions into sound audible by monsters. - if ( m_iWeaponVolume > iBodyVolume ) - { - m_iTargetVolume = m_iWeaponVolume; - - // OR in the bits for COMBAT sound if the weapon is being louder than the player. - pSound->m_iType |= bits_SOUND_COMBAT; - } - else - { - m_iTargetVolume = iBodyVolume; - } - - // decay weapon volume over time so bits_SOUND_COMBAT stays set for a while - m_iWeaponVolume -= 250 * gpGlobals->frametime; - if ( m_iWeaponVolume < 0 ) - { - iVolume = 0; - } - - - // if target volume is greater than the player sound's current volume, we paste the new volume in - // immediately. If target is less than the current volume, current volume is not set immediately to the - // lower volume, rather works itself towards target volume over time. This gives monsters a much better chance - // to hear a sound, especially if they don't listen every frame. - iVolume = pSound->m_iVolume; - - if ( m_iTargetVolume > iVolume ) - { - iVolume = m_iTargetVolume; - } - else if ( iVolume > m_iTargetVolume ) - { - iVolume -= 250 * gpGlobals->frametime; - - if ( iVolume < m_iTargetVolume ) - { - iVolume = 0; - } - } - - if ( m_fNoPlayerSound ) - { - // debugging flag, lets players move around and shoot without monsters hearing. - iVolume = 0; - } - - if ( gpGlobals->time > m_flStopExtraSoundTime ) - { - // since the extra sound that a weapon emits only lasts for one client frame, we keep that sound around for a server frame or two - // after actual emission to make sure it gets heard. - m_iExtraSoundTypes = 0; - } - - if ( pSound ) - { - pSound->m_vecOrigin = pev->origin; - pSound->m_iType |= ( bits_SOUND_PLAYER | m_iExtraSoundTypes ); - pSound->m_iVolume = iVolume; - } - - // keep track of virtual muzzle flash - m_iWeaponFlash -= 256 * gpGlobals->frametime; - if (m_iWeaponFlash < 0) - m_iWeaponFlash = 0; - - UTIL_MakeVectors ( pev->angles ); - gpGlobals->v_forward.z = 0; - - // Below are a couple of useful little bits that make it easier to determine just how much noise the - // player is making. - // UTIL_ParticleEffect ( pev->origin + gpGlobals->v_forward * iVolume, g_vecZero, 255, 25 ); - //ALERT ( at_console, "%d/%d\n", iVolume, m_iTargetVolume ); -} - - -void CBasePlayer::PostThink() -{ - if ( g_fGameOver ) - goto pt_end; // intermission or finale - - if (!IsAlive()) - goto pt_end; - - // Handle Tank controlling - if ( m_pTank != NULL ) - { // if they've moved too far from the gun, or selected a weapon, unuse the gun - if ( m_pTank->OnControls( pev ) && !pev->weaponmodel ) - { - m_pTank->Use( this, this, USE_SET, 2 ); // try fire the gun - } - else - { // they've moved off the platform - m_pTank->Use( this, this, USE_OFF, 0 ); - m_pTank = NULL; - } - } - -// do weapon stuff - ItemPostFrame( ); - -// check to see if player landed hard enough to make a sound -// falling farther than half of the maximum safe distance, but not as far a max safe distance will -// play a bootscrape sound, and no damage will be inflicted. Fallling a distance shorter than half -// of maximum safe distance will make no sound. Falling farther than max safe distance will play a -// fallpain sound, and damage will be inflicted based on how far the player fell - - if ( (FBitSet(pev->flags, FL_ONGROUND)) && (pev->health > 0) && m_flFallVelocity >= PLAYER_FALL_PUNCH_THRESHHOLD ) - { - float fvol = 0.5; - - // ALERT ( at_console, "%f\n", m_flFallVelocity ); - - if (pev->watertype == CONTENT_WATER) - { - // Did he hit the world or a non-moving entity? - // BUG - this happens all the time in water, especially when - // BUG - water has current force - // if ( !pev->groundentity || VARS(pev->groundentity)->velocity.z == 0 ) - // EMIT_SOUND(ENT(pev), CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM); - } - else if ( m_flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED ) - {// after this point, we start doing damage - - // No falling damage in discwar - /* - float flFallDamage = g_pGameRules->FlPlayerFallDamage( this ); - - if ( flFallDamage > pev->health ) - {//splat - // note: play on item channel because we play footstep landing on body channel - EMIT_SOUND(ENT(pev), CHAN_ITEM, "common/bodysplat.wav", 1, ATTN_NORM); - } - - if ( flFallDamage > 0 ) - { - TakeDamage(VARS(eoNullEntity), VARS(eoNullEntity), flFallDamage, DMG_FALL ); - pev->punchangle.x = 0; - } - */ - - fvol = 1.0; - } - else if ( m_flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED / 2 ) - { - // EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_jumpland2.wav", 1, ATTN_NORM); - fvol = 0.85; - } - else if ( m_flFallVelocity < PLAYER_MIN_BOUNCE_SPEED ) - { - fvol = 0; - } - - if ( fvol > 0.0 ) - { - // get current texture under player right away - m_flTimeStepSound = 0; - UpdateStepSound(); - } - - if ( IsAlive() ) - { - SetAnimation( PLAYER_WALK ); - } - } - - if (FBitSet(pev->flags, FL_ONGROUND)) - { - if (m_flFallVelocity > 64 && !g_pGameRules->IsMultiplayer()) - { - CSoundEnt::InsertSound ( bits_SOUND_PLAYER, pev->origin, m_flFallVelocity, 0.2 ); - // ALERT( at_console, "fall %f\n", m_flFallVelocity ); - } - m_flFallVelocity = 0; - } - - // select the proper animation for the player character - if ( IsAlive() && (m_flTouchedByJumpPad < gpGlobals->time) ) - { - if (!pev->velocity.x && !pev->velocity.y) - SetAnimation( PLAYER_IDLE ); - else if ((pev->velocity.x || pev->velocity.y) && (FBitSet(pev->flags, FL_ONGROUND))) - SetAnimation( PLAYER_WALK ); - else if (pev->waterlevel > 1) - SetAnimation( PLAYER_WALK ); - } - - if ( IsAlive() && ( m_flThrowTime ) && ( m_flThrowTime + 0.25 < gpGlobals->time ) ) - { - m_Activity = ACT_BASE_WALK; - m_flThrowTime = 0.0; - if (!pev->velocity.x && !pev->velocity.y) - { - SetAnimation( PLAYER_IDLE ); - } - else - { - SetAnimation( PLAYER_WALK ); - } - } - - StudioFrameAdvance( ); - CheckPowerups(pev); - - UpdatePlayerSound(); - -pt_end: - - // Store old velocity for use in backpedalling animations - m_vecOldVelocity = pev->velocity.Normalize(); - - // Decay timers on weapons - // go through all of the weapons and make a list of the ones to pack - for ( int i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - if ( m_rgpPlayerItems[ i ] ) - { - CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[ i ]; - - while ( pPlayerItem ) - { - CBasePlayerWeapon *gun; - - gun = (CBasePlayerWeapon *)pPlayerItem->GetWeaponPtr(); - - if ( gun && gun->UseDecrement() ) - { - gun->m_flNextPrimaryAttack = V_max( gun->m_flNextPrimaryAttack - gpGlobals->frametime, -1.0 ); - gun->m_flNextSecondaryAttack = V_max( gun->m_flNextSecondaryAttack - gpGlobals->frametime, -0.001 ); - - if ( gun->m_flTimeWeaponIdle != 1000 ) - { - gun->m_flTimeWeaponIdle = V_max( gun->m_flTimeWeaponIdle - gpGlobals->frametime, -0.001 ); - } - } - - pPlayerItem = pPlayerItem->m_pNext; - } - } - } - - m_flNextAttack -= gpGlobals->frametime; - if ( m_flNextAttack < -0.001 ) - m_flNextAttack = -0.001; - - // Track button info so we can detect 'pressed' and 'released' buttons next frame - m_afButtonLast = pev->button; -} - - -// checks if the spot is clear of players -BOOL IsSpawnPointValid( CBaseEntity *pPlayer, CBaseEntity *pSpot ) -{ - CBaseEntity *ent = NULL; - - if ( !pSpot->IsTriggered( pPlayer ) ) - { - return FALSE; - } - - while ( (ent = UTIL_FindEntityInSphere( ent, pSpot->pev->origin, 96 )) != NULL ) - { - // if ent is a client, don't spawn on 'em - if ( ent->IsPlayer() && ent != pPlayer ) - { - if ( (pPlayer->pev->groupinfo == 0) || (ent->pev->groupinfo & pPlayer->pev->groupinfo) ) - return FALSE; - } - } - - // DISCWAR - // Make sure they're on the right team - if ( InArenaMode() && pSpot->pev->team != 0 && pSpot->pev->team != pPlayer->pev->team ) - return FALSE; - - return TRUE; -} - - -DLL_GLOBAL CBaseEntity *g_pLastSpawn; -inline int FNullEnt( CBaseEntity *ent ) { return (ent == NULL) || FNullEnt( ent->edict() ); } - -/* -============ -EntSelectSpawnPoint - -Returns the entity to spawn at - -USES AND SETS GLOBAL g_pLastSpawn -============ -*/ -edict_t *EntSelectSpawnPoint( CBaseEntity *pPlayer ) -{ - CBaseEntity *pSpot; - edict_t *player; - - player = pPlayer->edict(); - - EMIT_SOUND( player, CHAN_AUTO, "r_tele1.wav", 1, ATTN_NORM ); - -// choose a info_player_deathmatch point - if (g_pGameRules->IsCoOp()) - { - pSpot = UTIL_FindEntityByClassname( g_pLastSpawn, "info_player_coop"); - if ( !FNullEnt(pSpot) ) - goto ReturnSpot; - pSpot = UTIL_FindEntityByClassname( g_pLastSpawn, "info_player_start"); - if ( !FNullEnt(pSpot) ) - goto ReturnSpot; - } - else if ( g_pGameRules->IsDeathmatch() ) - { - pSpot = g_pLastSpawn; - // Randomize the start spot - for ( int i = RANDOM_LONG(1,5); i > 0; i-- ) - pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" ); - if ( FNullEnt( pSpot ) ) // skip over the null point - pSpot = UTIL_FindEntityByClassname( pSpot, "info_player_deathmatch" ); - - CBaseEntity *pFirstSpot = pSpot; - - do - { - if ( pSpot ) - { - // check if pSpot is valid - if ( IsSpawnPointValid( pPlayer, pSpot ) ) - { - if ( pSpot->pev->origin == Vector( 0, 0, 0 ) ) - { - 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 ( !FNullEnt( pSpot ) ) - { - CBaseEntity *ent = NULL; - while ( (ent = UTIL_FindEntityInSphere( ent, pSpot->pev->origin, 128 )) != NULL ) - { - // if ent is a client, kill em (unless they are ourselves) - if ( ent->IsPlayer() && !(ent->edict() == player) && (ent->pev->groupinfo & player->v.groupinfo) && ((CBasePlayer*)pPlayer)->IsObserver() == false) - ent->TakeDamage( VARS(INDEXENT(0)), VARS(INDEXENT(0)), 300, DMG_GENERIC | DMG_ALWAYSGIB ); - } - goto ReturnSpot; - } - } - - // If startspot is set, (re)spawn there. - if ( FStringNull( gpGlobals->startspot ) || !strlen(STRING(gpGlobals->startspot))) - { - pSpot = UTIL_FindEntityByClassname(NULL, "info_player_start"); - if ( !FNullEnt(pSpot) ) - goto ReturnSpot; - } - else - { - pSpot = UTIL_FindEntityByTargetname( NULL, STRING(gpGlobals->startspot) ); - if ( !FNullEnt(pSpot) ) - goto ReturnSpot; - } - -ReturnSpot: - if ( FNullEnt( pSpot ) ) - { - ALERT(at_error, "PutClientInServer: no info_player_start on level"); - return INDEXENT(0); - } - - g_pLastSpawn = pSpot; - return pSpot->edict(); -} - - -void CBasePlayer::Spawn( void ) -{ - pev->classname = MAKE_STRING("player"); - pev->health = 100; - pev->armorvalue = 0; - pev->takedamage = DAMAGE_AIM; - pev->solid = SOLID_SLIDEBOX; - pev->movetype = MOVETYPE_WALK; - pev->max_health = pev->health; - pev->flags = FL_CLIENT; - pev->air_finished = gpGlobals->time + 12; - pev->dmg = 2; // initial water damage - pev->effects = 0; - pev->deadflag = DEAD_NO; - pev->dmg_take = 0; - pev->dmg_save = 0; - pev->friction = 1.0; - pev->gravity = 1.0; - m_bitsHUDDamage = -1; - m_bitsDamageType = 0; - m_afPhysicsFlags = 0; - m_fLongJump = FALSE;// no longjump module. - m_flTouchedByJumpPad = 0; - m_flNextAttack = gpGlobals->time + 0.5; // Prevent fire - - g_engfuncs.pfnSetPhysicsKeyValue( edict(), "slj", "0" ); - g_engfuncs.pfnSetPhysicsKeyValue( edict(), "hl", "1" ); - - m_iFOV = 0;// init field of view. - m_iClientFOV = -1; // make sure fov reset is sent - - m_flNextDecalTime = 0;// let this player decal as soon as he spawns. - - m_flgeigerDelay = gpGlobals->time + 2.0; // wait a few seconds until user-defined message registrations - // are recieved by all clients - - m_flTimeStepSound = 0; - m_iStepLeft = 0; - m_flFieldOfView = 0.5;// some monsters use this to determine whether or not the player is looking at them. - - m_bloodColor = BLOOD_COLOR_RED; - m_flNextAttack = UTIL_WeaponTimeBase(); - StartSneaking(); - - m_iFlashBattery = 99; - m_flFlashLightTime = 1; // force first message - -// dont let uninitialized value here hurt the player - m_flFallVelocity = 0; - - g_pGameRules->GetPlayerSpawnSpot( this ); - - SET_MODEL(ENT(pev), "models/player/male/male.mdl"); - g_ulModelIndexPlayer = pev->modelindex; - pev->sequence = LookupActivity( ACT_IDLE ); - - if ( FBitSet(pev->flags, FL_DUCKING) ) - UTIL_SetSize(pev, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX); - else - UTIL_SetSize(pev, VEC_HULL_MIN, VEC_HULL_MAX); - - pev->view_ofs = VEC_VIEW; - Precache(); - m_HackedGunPos = Vector( 0, 32, 0 ); - - if ( m_iPlayerSound == SOUNDLIST_EMPTY ) - { - ALERT ( at_console, "Couldn't alloc player sound slot!\n" ); - } - - m_fNoPlayerSound = FALSE;// normal sound behavior. - - m_pLastItem = NULL; - m_iClientHideHUD = -1; // force this to be recalculated - m_fWeapon = FALSE; - m_pClientActiveItem = NULL; - m_iClientBattery = -1; - - // reset all ammo values to 0 - for ( int i = 0; i < MAX_AMMO_SLOTS; i++ ) - { - m_rgAmmo[i] = 0; - m_rgAmmoLast[i] = 0; // client ammo values also have to be reset (the death hud clear messages does on the client side) - } - - m_lastx = m_lasty = 0; - - g_pGameRules->PlayerSpawn( this ); - - SetBodygroup( 1, 1 ); - ClearFreezeAndRender(); -} - - -void CBasePlayer :: Precache( void ) -{ - // in the event that the player JUST spawned, and the level node graph - // was loaded, fix all of the node graph pointers before the game starts. - - // !!!BUGBUG - now that we have multiplayer, this needs to be moved! - if ( WorldGraph.m_fGraphPresent && !WorldGraph.m_fGraphPointersSet ) - { - if ( !WorldGraph.FSetGraphPointers() ) - { - ALERT ( at_console, "**Graph pointers were not set!\n"); - } - else - { - ALERT ( at_console, "**Graph Pointers Set!\n" ); - } - } - - // SOUNDS / MODELS ARE PRECACHED in ClientPrecache() (game specific) - // because they need to precache before any clients have connected - - // init geiger counter vars during spawn and each time - // we cross a level transition - - m_flgeigerRange = 1000; - m_igeigerRangePrev = 1000; - - m_bitsDamageType = 0; - m_bitsHUDDamage = -1; - - m_iClientBattery = -1; - - m_iTrain = TRAIN_NEW; - - // Make sure any necessary user messages have been registered - LinkUserMessages(); - - m_iUpdateTime = 5; // won't update for 1/2 a second - - if ( gInitHUD ) - m_fInitHUD = TRUE; -} - - -int CBasePlayer::Save( CSave &save ) -{ - if ( !CBaseMonster::Save(save) ) - return 0; - - return save.WriteFields( "PLAYER", this, m_playerSaveData, ARRAYSIZE(m_playerSaveData) ); -} - - -// -// Marks everything as new so the player will resend this to the hud. -// -void CBasePlayer::RenewItems(void) -{ - -} - - -int CBasePlayer::Restore( CRestore &restore ) -{ - if ( !CBaseMonster::Restore(restore) ) - return 0; - - int status = restore.ReadFields( "PLAYER", this, m_playerSaveData, ARRAYSIZE(m_playerSaveData) ); - - SAVERESTOREDATA *pSaveData = (SAVERESTOREDATA *)gpGlobals->pSaveData; - // landmark isn't present. - if ( !pSaveData->fUseLandmark ) - { - ALERT( at_console, "No Landmark:%s\n", pSaveData->szLandmarkName ); - - // default to normal spawn - edict_t* pentSpawnSpot = EntSelectSpawnPoint( this ); - pev->origin = VARS(pentSpawnSpot)->origin + Vector(0,0,1); - pev->angles = VARS(pentSpawnSpot)->angles; - } - pev->v_angle.z = 0; // Clear out roll - pev->angles = pev->v_angle; - - pev->fixangle = TRUE; // turn this way immediately - -// Copied from spawn() for now - m_bloodColor = BLOOD_COLOR_RED; - - g_ulModelIndexPlayer = pev->modelindex; - - if ( FBitSet(pev->flags, FL_DUCKING) ) - { - // Use the crouch HACK - // FixPlayerCrouchStuck( edict() ); - UTIL_SetSize(pev, VEC_DUCK_HULL_MIN, VEC_DUCK_HULL_MAX); - } - else - { - UTIL_SetSize(pev, VEC_HULL_MIN, VEC_HULL_MAX); - } - - RenewItems(); - - return status; -} - - - -void CBasePlayer::SelectNextItem( int iItem ) -{ - CBasePlayerItem *pItem; - - pItem = m_rgpPlayerItems[ iItem ]; - - if (!pItem) - return; - - if (pItem == m_pActiveItem) - { - // select the next one in the chain - pItem = m_pActiveItem->m_pNext; - if (! pItem) - { - return; - } - - CBasePlayerItem *pLast; - pLast = pItem; - while (pLast->m_pNext) - pLast = pLast->m_pNext; - - // relink chain - pLast->m_pNext = m_pActiveItem; - m_pActiveItem->m_pNext = NULL; - m_rgpPlayerItems[ iItem ] = pItem; - } - - ResetAutoaim( ); - - // FIX, this needs to queue them up and delay - if (m_pActiveItem) - { - m_pActiveItem->Holster( ); - } - - m_pActiveItem = pItem; - - if (m_pActiveItem) - { - m_pActiveItem->Deploy( ); - m_pActiveItem->UpdateItemInfo( ); - } -} - -void CBasePlayer::SelectItem(const char *pstr) -{ - if (!pstr) - return; - - CBasePlayerItem *pItem = NULL; - - for (int i = 0; i < MAX_ITEM_TYPES; i++) - { - if (m_rgpPlayerItems[i]) - { - pItem = m_rgpPlayerItems[i]; - - while (pItem) - { - if (FClassnameIs(pItem->pev, pstr)) - break; - pItem = pItem->m_pNext; - } - } - - if (pItem) - break; - } - - if (!pItem) - return; - - - if (pItem == m_pActiveItem) - return; - - ResetAutoaim( ); - - // FIX, this needs to queue them up and delay - if (m_pActiveItem) - m_pActiveItem->Holster( ); - - m_pLastItem = m_pActiveItem; - m_pActiveItem = pItem; - - if (m_pActiveItem) - { - m_pActiveItem->Deploy( ); - m_pActiveItem->UpdateItemInfo( ); - } -} - - -void CBasePlayer::SelectLastItem(void) -{ - if (!m_pLastItem) - { - return; - } - - if ( m_pActiveItem && !m_pActiveItem->CanHolster() ) - { - return; - } - - ResetAutoaim( ); - - // FIX, this needs to queue them up and delay - if (m_pActiveItem) - m_pActiveItem->Holster( ); - - CBasePlayerItem *pTemp = m_pActiveItem; - m_pActiveItem = m_pLastItem; - m_pLastItem = pTemp; - m_pActiveItem->Deploy( ); - m_pActiveItem->UpdateItemInfo( ); -} - -//============================================== -// HasWeapons - do I have any weapons at all? -//============================================== -BOOL CBasePlayer::HasWeapons( void ) -{ - int i; - - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - if ( m_rgpPlayerItems[ i ] ) - { - return TRUE; - } - } - - return FALSE; -} - -void CBasePlayer::SelectPrevItem( int iItem ) -{ -} - - -const char *CBasePlayer::TeamID( void ) -{ - if ( pev == NULL ) // Not fully connected yet - return ""; - - // return their team name - return m_szTeamName; -} - - -//============================================== -// !!!UNDONE:ultra temporary SprayCan entity to apply -// decal frame at a time. For PreAlpha CD -//============================================== -class CSprayCan : public CBaseEntity -{ -public: - void Spawn ( entvars_t *pevOwner ); - void Think( void ); - - virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; } -}; - -void CSprayCan::Spawn ( entvars_t *pevOwner ) -{ - pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->v_angle; - pev->owner = ENT(pevOwner); - pev->frame = 0; - - pev->nextthink = gpGlobals->time + 0.1; - EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/sprayer.wav", 1, ATTN_NORM); -} - -void CSprayCan::Think( void ) -{ - TraceResult tr; - int playernum; - int nFrames; - CBasePlayer *pPlayer; - - pPlayer = (CBasePlayer *)GET_PRIVATE(pev->owner); - - if (pPlayer) - nFrames = pPlayer->GetCustomDecalFrames(); - else - nFrames = -1; - - playernum = ENTINDEX(pev->owner); - - // ALERT(at_console, "Spray by player %i, %i of %i\n", playernum, (int)(pev->frame + 1), nFrames); - - UTIL_MakeVectors(pev->angles); - UTIL_TraceLine ( pev->origin, pev->origin + gpGlobals->v_forward * 128, ignore_monsters, pev->owner, & tr); - - // No customization present. - if (nFrames == -1) - { - UTIL_DecalTrace( &tr, DECAL_LAMBDA6 ); - UTIL_Remove( this ); - } - else - { - UTIL_PlayerDecalTrace( &tr, playernum, pev->frame, TRUE ); - // Just painted last custom frame. - if ( pev->frame++ >= (nFrames - 1)) - UTIL_Remove( this ); - } - - pev->nextthink = gpGlobals->time + 0.1; -} - -class CBloodSplat : public CBaseEntity -{ -public: - void Spawn ( entvars_t *pevOwner ); - void Spray ( void ); -}; - -void CBloodSplat::Spawn ( entvars_t *pevOwner ) -{ - pev->origin = pevOwner->origin + Vector ( 0 , 0 , 32 ); - pev->angles = pevOwner->v_angle; - pev->owner = ENT(pevOwner); - - SetThink ( &CBloodSplat::Spray ); - pev->nextthink = gpGlobals->time + 0.1; -} - -void CBloodSplat::Spray ( void ) -{ - TraceResult tr; - - if ( g_Language != LANGUAGE_GERMAN ) - { - UTIL_MakeVectors(pev->angles); - UTIL_TraceLine ( pev->origin, pev->origin + gpGlobals->v_forward * 128, ignore_monsters, pev->owner, & tr); - - UTIL_BloodDecalTrace( &tr, BLOOD_COLOR_RED ); - } - SetThink ( &CBloodSplat::SUB_Remove ); - pev->nextthink = gpGlobals->time + 0.1; -} - -//============================================== - - - -void CBasePlayer::GiveNamedItem( const char *pszName ) -{ - edict_t *pent; - - int istr = MAKE_STRING(pszName); - - pent = CREATE_NAMED_ENTITY(istr); - if ( FNullEnt( pent ) ) - { - ALERT ( at_console, "NULL Ent in GiveNamedItem!\n" ); - return; - } - VARS( pent )->origin = pev->origin; - pent->v.spawnflags |= SF_NORESPAWN; - - DispatchSpawn( pent ); - DispatchTouch( pent, ENT( pev ) ); -} - - - -CBaseEntity *FindEntityForward( CBaseEntity *pMe ) -{ - TraceResult tr; - - UTIL_MakeVectors(pMe->pev->v_angle); - UTIL_TraceLine(pMe->pev->origin + pMe->pev->view_ofs,pMe->pev->origin + pMe->pev->view_ofs + gpGlobals->v_forward * 8192,dont_ignore_monsters, pMe->edict(), &tr ); - if ( tr.flFraction != 1.0 && !FNullEnt( tr.pHit) ) - { - CBaseEntity *pHit = CBaseEntity::Instance( tr.pHit ); - return pHit; - } - return NULL; -} - - -BOOL CBasePlayer :: FlashlightIsOn( void ) -{ - return FBitSet(pev->effects, EF_DIMLIGHT); -} - - -void CBasePlayer :: FlashlightTurnOn( void ) -{ - if ( !g_pGameRules->FAllowFlashlight() ) - { - return; - } - - if ( (pev->weapons & (1<effects, EF_DIMLIGHT); - MESSAGE_BEGIN( MSG_ONE, gmsgFlashlight, NULL, pev ); - WRITE_BYTE(1); - WRITE_BYTE(m_iFlashBattery); - MESSAGE_END(); - - m_flFlashLightTime = FLASH_DRAIN_TIME + gpGlobals->time; - - } -} - - -void CBasePlayer :: FlashlightTurnOff( void ) -{ - EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, SOUND_FLASHLIGHT_OFF, 1.0, ATTN_NORM, 0, PITCH_NORM ); - ClearBits(pev->effects, EF_DIMLIGHT); - MESSAGE_BEGIN( MSG_ONE, gmsgFlashlight, NULL, pev ); - WRITE_BYTE(0); - WRITE_BYTE(m_iFlashBattery); - MESSAGE_END(); - - m_flFlashLightTime = FLASH_CHARGE_TIME + gpGlobals->time; - -} - -/* -=============== -ForceClientDllUpdate - -When recording a demo, we need to have the server tell us the entire client state -so that the client side .dll can behave correctly. -Reset stuff so that the state is transmitted. -=============== -*/ -void CBasePlayer :: ForceClientDllUpdate( void ) -{ - m_iClientHealth = -1; - m_iClientBattery = -1; - m_iTrain |= TRAIN_NEW; // Force new train message. - m_fWeapon = FALSE; // Force weapon send - m_fKnownItem = FALSE; // Force weaponinit messages. - - // Now force all the necessary messages - // to be sent. - UpdateClientData(); -} - -/* -============ -ImpulseCommands -============ -*/ -extern float g_flWeaponCheat; - -void CBasePlayer::ImpulseCommands( ) -{ - TraceResult tr;// UNDONE: kill me! This is temporary for PreAlpha CDs - - // Handle use events - PlayerUse(); - - int iImpulse = (int)pev->impulse; - switch (iImpulse) - { - case 99: - { - - int iOn; - - if (!gmsgLogo) - { - iOn = 1; - gmsgLogo = REG_USER_MSG("Logo", 1); - } - else - { - iOn = 0; - } - - ASSERT( gmsgLogo > 0 ); - // send "health" update message - MESSAGE_BEGIN( MSG_ONE, gmsgLogo, NULL, pev ); - WRITE_BYTE(iOn); - MESSAGE_END(); - - if(!iOn) - gmsgLogo = 0; - break; - } - case 100: - // temporary flashlight for level designers - if ( FlashlightIsOn() ) - { - FlashlightTurnOff(); - } - else - { - FlashlightTurnOn(); - } - break; - - case 201:// paint decal - - if ( gpGlobals->time < m_flNextDecalTime ) - { - // too early! - break; - } - - UTIL_MakeVectors(pev->v_angle); - UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr); - - if ( tr.flFraction != 1.0 ) - {// line hit something, so paint a decal - m_flNextDecalTime = gpGlobals->time + CVAR_GET_FLOAT("decalfrequency"); - CSprayCan *pCan = GetClassPtr((CSprayCan *)NULL); - pCan->Spawn( pev ); - } - - break; - case 204: // Demo recording, update client dll specific data again. - ForceClientDllUpdate(); - break; - default: - // check all of the cheat impulse commands now - CheatImpulseCommands( iImpulse ); - break; - } - - pev->impulse = 0; -} - -//========================================================= -//========================================================= -void CBasePlayer::CheatImpulseCommands( int iImpulse ) -{ -#if !defined( HLDEMO_BUILD ) - if ( g_flWeaponCheat == 0.0 ) - { - return; - } - - CBaseEntity *pEntity; - TraceResult tr; - - switch ( iImpulse ) - { - case 76: - { - if (!giPrecacheGrunt) - { - giPrecacheGrunt = 1; - ALERT(at_console, "You must now restart to use Grunt-o-matic.\n"); - } - else - { - UTIL_MakeVectors( Vector( 0, pev->v_angle.y, 0 ) ); - Create("monster_human_grunt", pev->origin + gpGlobals->v_forward * 128, pev->angles); - } - break; - } - - - case 101: - gEvilImpulse101 = TRUE; - GiveNamedItem( "item_suit" ); - GiveNamedItem( "item_battery" ); - GiveNamedItem( "weapon_crowbar" ); - GiveNamedItem( "weapon_9mmhandgun" ); - GiveNamedItem( "ammo_9mmclip" ); - GiveNamedItem( "weapon_shotgun" ); - GiveNamedItem( "ammo_buckshot" ); - GiveNamedItem( "weapon_9mmAR" ); - GiveNamedItem( "ammo_9mmAR" ); - GiveNamedItem( "ammo_ARgrenades" ); - GiveNamedItem( "weapon_handgrenade" ); - GiveNamedItem( "weapon_tripmine" ); -#ifndef OEM_BUILD - GiveNamedItem( "weapon_357" ); - GiveNamedItem( "ammo_357" ); - GiveNamedItem( "weapon_crossbow" ); - GiveNamedItem( "ammo_crossbow" ); - GiveNamedItem( "weapon_egon" ); - GiveNamedItem( "weapon_gauss" ); - GiveNamedItem( "ammo_gaussclip" ); - GiveNamedItem( "weapon_rpg" ); - GiveNamedItem( "ammo_rpgclip" ); - GiveNamedItem( "weapon_satchel" ); - GiveNamedItem( "weapon_snark" ); - GiveNamedItem( "weapon_hornetgun" ); -#endif - gEvilImpulse101 = FALSE; - break; - - case 102: - // Gibbage!!! - CGib::SpawnRandomGibs( pev, 1, 1 ); - break; - - case 103: - // What the hell are you doing? - pEntity = FindEntityForward( this ); - if ( pEntity ) - { - CBaseMonster *pMonster = pEntity->MyMonsterPointer(); - if ( pMonster ) - pMonster->ReportAIState(); - } - break; - - case 104: - // Dump all of the global state varaibles (and global entity names) - gGlobalState.DumpGlobals(); - break; - - case 105:// player makes no sound for monsters to hear. - { - if ( m_fNoPlayerSound ) - { - ALERT ( at_console, "Player is audible\n" ); - m_fNoPlayerSound = FALSE; - } - else - { - ALERT ( at_console, "Player is silent\n" ); - m_fNoPlayerSound = TRUE; - } - break; - } - - case 106: - // Give me the classname and targetname of this entity. - pEntity = FindEntityForward( this ); - if ( pEntity ) - { - ALERT ( at_console, "Classname: %s", STRING( pEntity->pev->classname ) ); - - if ( !FStringNull ( pEntity->pev->targetname ) ) - { - ALERT ( at_console, " - Targetname: %s\n", STRING( pEntity->pev->targetname ) ); - } - else - { - ALERT ( at_console, " - TargetName: No Targetname\n" ); - } - - ALERT ( at_console, "Model: %s\n", STRING( pEntity->pev->model ) ); - if ( pEntity->pev->globalname ) - ALERT ( at_console, "Globalname: %s\n", STRING( pEntity->pev->globalname ) ); - } - break; - - case 107: - { - TraceResult tr; - - edict_t *pWorld = g_engfuncs.pfnPEntityOfEntIndex( 0 ); - - Vector start = pev->origin + pev->view_ofs; - Vector end = start + gpGlobals->v_forward * 1024; - UTIL_TraceLine( start, end, ignore_monsters, edict(), &tr ); - if ( tr.pHit ) - pWorld = tr.pHit; - const char *pTextureName = TRACE_TEXTURE( pWorld, start, end ); - if ( pTextureName ) - ALERT( at_console, "Texture: %s\n", pTextureName ); - } - break; - case 195:// show shortest paths for entire level to nearest node - { - Create("node_viewer_fly", pev->origin, pev->angles); - } - break; - case 196:// show shortest paths for entire level to nearest node - { - Create("node_viewer_large", pev->origin, pev->angles); - } - break; - case 197:// show shortest paths for entire level to nearest node - { - Create("node_viewer_human", pev->origin, pev->angles); - } - break; - case 199:// show nearest node and all connections - { - ALERT ( at_console, "%d\n", WorldGraph.FindNearestNode ( pev->origin, bits_NODE_GROUP_REALM ) ); - WorldGraph.ShowNodeConnections ( WorldGraph.FindNearestNode ( pev->origin, bits_NODE_GROUP_REALM ) ); - } - break; - case 202:// Random blood splatter - UTIL_MakeVectors(pev->v_angle); - UTIL_TraceLine ( pev->origin + pev->view_ofs, pev->origin + pev->view_ofs + gpGlobals->v_forward * 128, ignore_monsters, ENT(pev), & tr); - - if ( tr.flFraction != 1.0 ) - {// line hit something, so paint a decal - CBloodSplat *pBlood = GetClassPtr((CBloodSplat *)NULL); - pBlood->Spawn( pev ); - } - break; - case 203:// remove creature. - pEntity = FindEntityForward( this ); - if ( pEntity ) - { - if ( pEntity->pev->takedamage ) - pEntity->SetThink(&CBaseEntity::SUB_Remove); - } - break; - } -#endif // HLDEMO_BUILD -} - -// -// Add a weapon to the player (Item == Weapon == Selectable Object) -// -int CBasePlayer::AddPlayerItem( CBasePlayerItem *pItem ) -{ - CBasePlayerItem *pInsert; - - pInsert = m_rgpPlayerItems[pItem->iItemSlot()]; - - while (pInsert) - { - if (FClassnameIs( pInsert->pev, STRING( pItem->pev->classname) )) - { - if (pItem->AddDuplicate( pInsert )) - { - g_pGameRules->PlayerGotWeapon ( this, pItem ); - pItem->CheckRespawn(); - - // ugly hack to update clip w/o an update clip message - pInsert->UpdateItemInfo( ); - if (m_pActiveItem) - m_pActiveItem->UpdateItemInfo( ); - - pItem->Kill( ); - } - else if (gEvilImpulse101) - { - // FIXME: remove anyway for deathmatch testing - pItem->Kill( ); - } - return FALSE; - } - pInsert = pInsert->m_pNext; - } - - - if (pItem->AddToPlayer( this )) - { - g_pGameRules->PlayerGotWeapon ( this, pItem ); - pItem->CheckRespawn(); - - pItem->m_pNext = m_rgpPlayerItems[pItem->iItemSlot()]; - m_rgpPlayerItems[pItem->iItemSlot()] = pItem; - - // should we switch to this item? - if ( g_pGameRules->FShouldSwitchWeapon( this, pItem ) ) - { - SwitchWeapon( pItem ); - } - - return TRUE; - } - else if (gEvilImpulse101) - { - // FIXME: remove anyway for deathmatch testing - pItem->Kill( ); - } - return FALSE; -} - - - -int CBasePlayer::RemovePlayerItem( CBasePlayerItem *pItem ) -{ - if (m_pActiveItem == pItem) - { - ResetAutoaim( ); - pItem->Holster( ); - pItem->pev->nextthink = 0;// crowbar may be trying to swing again, etc. - pItem->SetThink( NULL ); - m_pActiveItem = NULL; - pev->viewmodel = 0; - pev->weaponmodel = 0; - } - else if ( m_pLastItem == pItem ) - m_pLastItem = NULL; - - CBasePlayerItem *pPrev = m_rgpPlayerItems[pItem->iItemSlot()]; - - if (pPrev == pItem) - { - m_rgpPlayerItems[pItem->iItemSlot()] = pItem->m_pNext; - return TRUE; - } - else - { - while (pPrev && pPrev->m_pNext != pItem) - { - pPrev = pPrev->m_pNext; - } - if (pPrev) - { - pPrev->m_pNext = pItem->m_pNext; - return TRUE; - } - } - return FALSE; -} - - -// -// Returns the unique ID for the ammo, or -1 if error -// -int CBasePlayer :: GiveAmmo( int iCount, char *szName, int iMax ) -{ - if ( !szName ) - { - // no ammo. - return -1; - } - - if ( !g_pGameRules->CanHaveAmmo( this, szName, iMax ) ) - { - // game rules say I can't have any more of this ammo type. - return -1; - } - - int i = 0; - - i = GetAmmoIndex( szName ); - - if ( i < 0 || i >= MAX_AMMO_SLOTS ) - return -1; - - int iAdd = V_min( iCount, iMax - m_rgAmmo[i] ); - if ( iAdd < 1 ) - return i; - - m_rgAmmo[ i ] += iAdd; - - - if ( gmsgAmmoPickup ) // make sure the ammo messages have been linked first - { - // Send the message that ammo has been picked up - MESSAGE_BEGIN( MSG_ONE, gmsgAmmoPickup, NULL, pev ); - WRITE_BYTE( GetAmmoIndex(szName) ); // ammo ID - WRITE_BYTE( iAdd ); // amount - MESSAGE_END(); - } - - return i; -} - - -/* -============ -ItemPreFrame - -Called every frame by the player PreThink -============ -*/ -void CBasePlayer::ItemPreFrame() -{ - if ( m_flNextAttack > 0 ) - { - return; - } - - if (!m_pActiveItem) - return; - - m_pActiveItem->ItemPreFrame( ); -} - - -/* -============ -ItemPostFrame - -Called every frame by the player PostThink -============ -*/ -void CBasePlayer::ItemPostFrame() -{ - static int fInSelect = FALSE; - - // check if the player is using a tank - if ( m_pTank != NULL ) - return; - - if ( m_flNextAttack > 0 ) - { - return; - } - - ImpulseCommands(); - - if (!m_pActiveItem) - return; - - m_pActiveItem->ItemPostFrame( ); -} - -int CBasePlayer::AmmoInventory( int iAmmoIndex ) -{ - if (iAmmoIndex == -1) - { - return -1; - } - - return m_rgAmmo[ iAmmoIndex ]; -} - -int CBasePlayer::GetAmmoIndex(const char *psz) -{ - int i; - - if (!psz) - return -1; - - for (i = 1; i < MAX_AMMO_SLOTS; i++) - { - if ( !CBasePlayerItem::AmmoInfoArray[i].pszName ) - continue; - - if (stricmp( psz, CBasePlayerItem::AmmoInfoArray[i].pszName ) == 0) - return i; - } - - return -1; -} - -// Called from UpdateClientData -// makes sure the client has all the necessary ammo info, if values have changed -void CBasePlayer::SendAmmoUpdate(void) -{ - for (int i=0; i < MAX_AMMO_SLOTS;i++) - { - if (m_rgAmmo[i] != m_rgAmmoLast[i]) - { - m_rgAmmoLast[i] = m_rgAmmo[i]; - - ASSERT( m_rgAmmo[i] >= 0 ); - ASSERT( m_rgAmmo[i] < 255 ); - - // send "Ammo" update message - MESSAGE_BEGIN( MSG_ONE, gmsgAmmoX, NULL, pev ); - WRITE_BYTE( i ); - WRITE_BYTE( V_max( V_min( m_rgAmmo[i], 254 ), 0 ) ); // clamp the value to one byte - MESSAGE_END(); - } - } -} - -/* -========================================================= - UpdateClientData - -resends any changed player HUD info to the client. -Called every frame by PlayerPreThink -Also called at start of demo recording and playback by -ForceClientDllUpdate to ensure the demo gets messages -reflecting all of the HUD state info. -========================================================= -*/ -void CBasePlayer :: UpdateClientData( void ) -{ - if (m_fInitHUD) - { - m_fInitHUD = FALSE; - gInitHUD = FALSE; - m_flSendArenaStatus = gpGlobals->time = 1.0f; - - MESSAGE_BEGIN( MSG_ONE, gmsgResetHUD, NULL, pev ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - - if ( !m_fGameHUDInitialized ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgInitHUD, NULL, pev ); - MESSAGE_END(); - - g_pGameRules->InitHUD( this ); - m_fGameHUDInitialized = TRUE; - if ( g_pGameRules->IsMultiplayer() ) - { - FireTargets( "game_playerjoin", this, this, USE_TOGGLE, 0 ); - } - } - - FireTargets( "game_playerspawn", this, this, USE_TOGGLE, 0 ); - } - - if ( m_iHideHUD != m_iClientHideHUD ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgHideWeapon, NULL, pev ); - WRITE_BYTE( m_iHideHUD ); - MESSAGE_END(); - - m_iClientHideHUD = m_iHideHUD; - } - - if ( m_iFOV != m_iClientFOV ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev ); - WRITE_BYTE( m_iFOV ); - MESSAGE_END(); - - // cache FOV change at end of function, so weapon updates can see that FOV has changed - } - - // HACKHACK -- send the message to display the game title - if (gDisplayTitle) - { - MESSAGE_BEGIN( MSG_ONE, gmsgShowGameTitle, NULL, pev ); - WRITE_BYTE( 0 ); - MESSAGE_END(); - gDisplayTitle = 0; - } - - if (pev->health != m_iClientHealth) - { -#define clamp( val, min, max ) ( ((val) > (max)) ? (max) : ( ((val) < (min)) ? (min) : (val) ) ) - int iHealth = clamp( pev->health, 0, 255 ); // make sure that no negative health values are sent - if ( pev->health > 0.0f && pev->health <= 1.0f ) - iHealth = 1; - - // send "health" update message - MESSAGE_BEGIN( MSG_ONE, gmsgHealth, NULL, pev ); - WRITE_BYTE( iHealth ); - MESSAGE_END(); - - m_iClientHealth = pev->health; - } - - - if (pev->armorvalue != m_iClientBattery) - { - m_iClientBattery = pev->armorvalue; - - ASSERT( gmsgBattery > 0 ); - // send "health" update message - MESSAGE_BEGIN( MSG_ONE, gmsgBattery, NULL, pev ); - WRITE_SHORT( (int)pev->armorvalue); - MESSAGE_END(); - } - - if (pev->dmg_take || pev->dmg_save || m_bitsHUDDamage != m_bitsDamageType) - { - // Comes from inside me if not set - Vector damageOrigin = pev->origin; - // send "damage" message - // causes screen to flash, and pain compass to show direction of damage - edict_t *other = pev->dmg_inflictor; - if ( other ) - { - CBaseEntity *pEntity = CBaseEntity::Instance(other); - if ( pEntity ) - damageOrigin = pEntity->Center(); - } - - // only send down damage type that have hud art - int visibleDamageBits = m_bitsDamageType & DMG_SHOWNHUD; - - MESSAGE_BEGIN( MSG_ONE, gmsgDamage, NULL, pev ); - WRITE_BYTE( pev->dmg_save ); - WRITE_BYTE( pev->dmg_take ); - WRITE_LONG( visibleDamageBits ); - WRITE_COORD( damageOrigin.x ); - WRITE_COORD( damageOrigin.y ); - WRITE_COORD( damageOrigin.z ); - MESSAGE_END(); - - pev->dmg_take = 0; - pev->dmg_save = 0; - m_bitsHUDDamage = m_bitsDamageType; - - // Clear off non-time-based damage indicators - m_bitsDamageType &= DMG_TIMEBASED; - } - - // Update Flashlight - if ((m_flFlashLightTime) && (m_flFlashLightTime <= gpGlobals->time)) - { - if (FlashlightIsOn()) - { - if (m_iFlashBattery) - { - m_flFlashLightTime = FLASH_DRAIN_TIME + gpGlobals->time; - m_iFlashBattery--; - - if (!m_iFlashBattery) - FlashlightTurnOff(); - } - } - else - { - if (m_iFlashBattery < 100) - { - m_flFlashLightTime = FLASH_CHARGE_TIME + gpGlobals->time; - m_iFlashBattery++; - } - else - m_flFlashLightTime = 0; - } - - MESSAGE_BEGIN( MSG_ONE, gmsgFlashBattery, NULL, pev ); - WRITE_BYTE(m_iFlashBattery); - MESSAGE_END(); - } - - - if (m_iTrain & TRAIN_NEW) - { - ASSERT( gmsgTrain > 0 ); - // send "health" update message - MESSAGE_BEGIN( MSG_ONE, gmsgTrain, NULL, pev ); - WRITE_BYTE(m_iTrain & 0xF); - MESSAGE_END(); - - m_iTrain &= ~TRAIN_NEW; - } - - // - // New Weapon? - // - if (!m_fKnownItem) - { - m_fKnownItem = TRUE; - - // WeaponInit Message - // byte = # of weapons - // - // for each weapon: - // byte name str length (not including null) - // bytes... name - // byte Ammo Type - // byte Ammo2 Type - // byte bucket - // byte bucket pos - // byte flags - // ???? Icons - - // Send ALL the weapon info now - int i; - - for (i = 0; i < MAX_WEAPONS; i++) - { - ItemInfo& II = CBasePlayerItem::ItemInfoArray[i]; - - if ( !II.iId ) - continue; - - const char *pszName; - if (!II.pszName) - pszName = "Empty"; - else - pszName = II.pszName; - - MESSAGE_BEGIN( MSG_ONE, gmsgWeaponList, NULL, pev ); - WRITE_STRING(pszName); // string weapon name - WRITE_BYTE(GetAmmoIndex(II.pszAmmo1)); // byte Ammo Type - WRITE_BYTE(II.iMaxAmmo1); // byte Max Ammo 1 - WRITE_BYTE(GetAmmoIndex(II.pszAmmo2)); // byte Ammo2 Type - WRITE_BYTE(II.iMaxAmmo2); // byte Max Ammo 2 - WRITE_BYTE(II.iSlot); // byte bucket - WRITE_BYTE(II.iPosition); // byte bucket pos - WRITE_BYTE(II.iId); // byte id (bit index into pev->weapons) - WRITE_BYTE(II.iFlags); // byte Flags - MESSAGE_END(); - } - } - - - SendAmmoUpdate(); - - // Update all the items - for ( int i = 0; i < MAX_ITEM_TYPES; i++ ) - { - if ( m_rgpPlayerItems[i] ) // each item updates it's successors - m_rgpPlayerItems[i]->UpdateClientData( this ); - } - - // Cache and client weapon change - m_pClientActiveItem = m_pActiveItem; - m_iClientFOV = m_iFOV; - - if ( (m_iClientFrags != pev->frags) || (m_iClientDeaths != m_iDeaths) || (m_iClientPlayerClass != pev->playerclass) || (m_iClientTeam != pev->team) ) - { - // update all players with this info, for their scoreboards - MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); - WRITE_BYTE( ENTINDEX(edict()) ); - WRITE_SHORT( pev->frags ); - WRITE_SHORT( m_iDeaths ); - WRITE_SHORT( pev->playerclass ); - WRITE_SHORT( pev->team ); - MESSAGE_END(); - - m_iClientPlayerClass = pev->playerclass; - m_iClientTeam = pev->team; - m_iClientDeaths = m_iDeaths; - m_iClientFrags = pev->frags; - } - - // Update Freeze - if ( m_iFrozen != m_iClientFrozen ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgFrozen, NULL, pev ); - WRITE_BYTE( m_iFrozen ); - MESSAGE_END(); - - m_iClientFrozen = m_iFrozen; - } -} - - -//========================================================= -// FBecomeProne - Overridden for the player to set the proper -// physics flags when a barnacle grabs player. -//========================================================= -BOOL CBasePlayer :: FBecomeProne ( void ) -{ - m_afPhysicsFlags |= PFLAG_ONBARNACLE; - return TRUE; -} - -//========================================================= -// BarnacleVictimBitten - bad name for a function that is called -// by Barnacle victims when the barnacle pulls their head -// into its mouth. For the player, just die. -//========================================================= -void CBasePlayer :: BarnacleVictimBitten ( entvars_t *pevBarnacle ) -{ - TakeDamage ( pevBarnacle, pevBarnacle, pev->health + pev->armorvalue, DMG_SLASH | DMG_ALWAYSGIB ); -} - -//========================================================= -// BarnacleVictimReleased - overridden for player who has -// physics flags concerns. -//========================================================= -void CBasePlayer :: BarnacleVictimReleased ( void ) -{ - m_afPhysicsFlags &= ~PFLAG_ONBARNACLE; -} - - -//========================================================= -// Illumination -// return player light level plus virtual muzzle flash -//========================================================= -int CBasePlayer :: Illumination( void ) -{ - int iIllum = CBaseEntity::Illumination( ); - - iIllum += m_iWeaponFlash; - if (iIllum > 255) - return 255; - return iIllum; -} - - -void CBasePlayer :: EnableControl(BOOL fControl) -{ - if (!fControl) - pev->flags |= FL_FROZEN; - else - pev->flags &= ~FL_FROZEN; - -} - - -#define DOT_1DEGREE 0.9998476951564 -#define DOT_2DEGREE 0.9993908270191 -#define DOT_3DEGREE 0.9986295347546 -#define DOT_4DEGREE 0.9975640502598 -#define DOT_5DEGREE 0.9961946980917 -#define DOT_6DEGREE 0.9945218953683 -#define DOT_7DEGREE 0.9925461516413 -#define DOT_8DEGREE 0.9902680687416 -#define DOT_9DEGREE 0.9876883405951 -#define DOT_10DEGREE 0.9848077530122 -#define DOT_15DEGREE 0.9659258262891 -#define DOT_20DEGREE 0.9396926207859 -#define DOT_25DEGREE 0.9063077870367 - -//========================================================= -// Autoaim -// set crosshair position to point to enemey -//========================================================= -Vector CBasePlayer :: GetAutoaimVector( float flDelta ) -{ - if (g_iSkillLevel == SKILL_HARD) - { - UTIL_MakeVectors( pev->v_angle + pev->punchangle ); - return gpGlobals->v_forward; - } - - Vector vecSrc = GetGunPosition( ); - float flDist = 8192; - - // always use non-sticky autoaim - // UNDONE: use sever variable to chose! - if (1 || g_iSkillLevel == SKILL_MEDIUM) - { - m_vecAutoAim = Vector( 0, 0, 0 ); - // flDelta *= 0.5; - } - - BOOL m_fOldTargeting = m_fOnTarget; - Vector angles = AutoaimDeflection(vecSrc, flDist, flDelta ); - - // update ontarget if changed - if ( !g_pGameRules->AllowAutoTargetCrosshair() ) - m_fOnTarget = 0; - else if (m_fOldTargeting != m_fOnTarget) - { - m_pActiveItem->UpdateItemInfo( ); - } - - if (angles.x > 180) - angles.x -= 360; - if (angles.x < -180) - angles.x += 360; - if (angles.y > 180) - angles.y -= 360; - if (angles.y < -180) - angles.y += 360; - - if (angles.x > 25) - angles.x = 25; - if (angles.x < -25) - angles.x = -25; - if (angles.y > 12) - angles.y = 12; - if (angles.y < -12) - angles.y = -12; - - - // always use non-sticky autoaim - // UNDONE: use sever variable to chose! - if (0 || g_iSkillLevel == SKILL_EASY) - { - m_vecAutoAim = m_vecAutoAim * 0.67 + angles * 0.33; - } - else - { - m_vecAutoAim = angles * 0.9; - } - - // m_vecAutoAim = m_vecAutoAim * 0.99; - - // Don't send across network if sv_aim is 0 - if ( CVAR_GET_FLOAT( "sv_aim" ) != 0 ) - { - if ( m_vecAutoAim.x != m_lastx || - m_vecAutoAim.y != m_lasty ) - { - SET_CROSSHAIRANGLE( edict(), -m_vecAutoAim.x, m_vecAutoAim.y ); - - m_lastx = m_vecAutoAim.x; - m_lasty = m_vecAutoAim.y; - } - } - - // ALERT( at_console, "%f %f\n", angles.x, angles.y ); - - UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); - return gpGlobals->v_forward; -} - - -Vector CBasePlayer :: AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta ) -{ - edict_t *pEdict = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - CBaseEntity *pEntity; - float bestdot; - Vector bestdir; - edict_t *bestent; - TraceResult tr; - - if ( CVAR_GET_FLOAT("sv_aim") == 0 ) - { - m_fOnTarget = FALSE; - return g_vecZero; - } - - UTIL_MakeVectors( pev->v_angle + pev->punchangle + m_vecAutoAim ); - - // try all possible entities - bestdir = gpGlobals->v_forward; - bestdot = flDelta; // +- 10 degrees - bestent = NULL; - - m_fOnTarget = FALSE; - - UTIL_TraceLine( vecSrc, vecSrc + bestdir * flDist, dont_ignore_monsters, edict(), &tr ); - - - if ( tr.pHit && tr.pHit->v.takedamage != DAMAGE_NO) - { - // don't look through water - if (!((pev->waterlevel != 3 && tr.pHit->v.waterlevel == 3) - || (pev->waterlevel == 3 && tr.pHit->v.waterlevel == 0))) - { - if (tr.pHit->v.takedamage == DAMAGE_AIM) - m_fOnTarget = TRUE; - - return m_vecAutoAim; - } - } - - for ( int i = 1; i < gpGlobals->maxEntities; i++, pEdict++ ) - { - Vector center; - Vector dir; - float dot; - - if ( pEdict->free ) // Not in use - continue; - - if (pEdict->v.takedamage != DAMAGE_AIM) - continue; - if (pEdict == edict()) - continue; -// if (pev->team > 0 && pEdict->v.team == pev->team) -// continue; // don't aim at teammate - if ( !g_pGameRules->ShouldAutoAim( this, pEdict ) ) - continue; - - pEntity = Instance( pEdict ); - if (pEntity == NULL) - continue; - - if (!pEntity->IsAlive()) - continue; - - // don't look through water - if ((pev->waterlevel != 3 && pEntity->pev->waterlevel == 3) - || (pev->waterlevel == 3 && pEntity->pev->waterlevel == 0)) - continue; - - center = pEntity->BodyTarget( vecSrc ); - - dir = (center - vecSrc).Normalize( ); - - // make sure it's in front of the player - if (DotProduct (dir, gpGlobals->v_forward ) < 0) - continue; - - dot = fabs( DotProduct (dir, gpGlobals->v_right ) ) - + fabs( DotProduct (dir, gpGlobals->v_up ) ) * 0.5; - - // tweek for distance - dot *= 1.0 + 0.2 * ((center - vecSrc).Length() / flDist); - - if (dot > bestdot) - continue; // to far to turn - - UTIL_TraceLine( vecSrc, center, dont_ignore_monsters, edict(), &tr ); - if (tr.flFraction != 1.0 && tr.pHit != pEdict) - { - // ALERT( at_console, "hit %s, can't see %s\n", STRING( tr.pHit->v.classname ), STRING( pEdict->v.classname ) ); - continue; - } - - // don't shoot at friends - if (IRelationship( pEntity ) < 0) - { - if ( !pEntity->IsPlayer() && !g_pGameRules->IsDeathmatch()) - // ALERT( at_console, "friend\n"); - continue; - } - - // can shoot at this one - bestdot = dot; - bestent = pEdict; - bestdir = dir; - } - - if (bestent) - { - bestdir = UTIL_VecToAngles (bestdir); - bestdir.x = -bestdir.x; - bestdir = bestdir - pev->v_angle - pev->punchangle; - - if (bestent->v.takedamage == DAMAGE_AIM) - m_fOnTarget = TRUE; - - return bestdir; - } - - return Vector( 0, 0, 0 ); -} - - -void CBasePlayer :: ResetAutoaim( ) -{ - if (m_vecAutoAim.x != 0 || m_vecAutoAim.y != 0) - { - m_vecAutoAim = Vector( 0, 0, 0 ); - SET_CROSSHAIRANGLE( edict(), 0, 0 ); - } - m_fOnTarget = FALSE; -} - -/* -============= -SetCustomDecalFrames - - UNDONE: Determine real frame limit, 8 is a placeholder. - Note: -1 means no custom frames present. -============= -*/ -void CBasePlayer :: SetCustomDecalFrames( int nFrames ) -{ - if (nFrames > 0 && - nFrames < 8) - m_nCustomSprayFrames = nFrames; - else - m_nCustomSprayFrames = -1; -} - -/* -============= -GetCustomDecalFrames - - Returns the # of custom frames this player's custom clan logo contains. -============= -*/ -int CBasePlayer :: GetCustomDecalFrames( void ) -{ - return m_nCustomSprayFrames; -} - - -//========================================================= -// DropPlayerItem - drop the named item, or if no name, -// the active item. -//========================================================= -void CBasePlayer::DropPlayerItem ( char *pszItemName ) -{ - // no dropping in disc war - return; -} - -//========================================================= -// HasPlayerItem Does the player already have this item? -//========================================================= -BOOL CBasePlayer::HasPlayerItem( CBasePlayerItem *pCheckItem ) -{ - CBasePlayerItem *pItem = m_rgpPlayerItems[pCheckItem->iItemSlot()]; - - while (pItem) - { - if (FClassnameIs( pItem->pev, STRING( pCheckItem->pev->classname) )) - { - return TRUE; - } - pItem = pItem->m_pNext; - } - - return FALSE; -} - -//========================================================= -// HasNamedPlayerItem Does the player already have this item? -//========================================================= -BOOL CBasePlayer::HasNamedPlayerItem( const char *pszItemName ) -{ - CBasePlayerItem *pItem; - int i; - - for ( i = 0 ; i < MAX_ITEM_TYPES ; i++ ) - { - pItem = m_rgpPlayerItems[ i ]; - - while (pItem) - { - if ( !strcmp( pszItemName, STRING( pItem->pev->classname ) ) ) - { - return TRUE; - } - pItem = pItem->m_pNext; - } - } - - return FALSE; -} - -//========================================================= -// -//========================================================= -BOOL CBasePlayer :: SwitchWeapon( CBasePlayerItem *pWeapon ) -{ - if ( !pWeapon->CanDeploy() ) - { - return FALSE; - } - - ResetAutoaim( ); - - if (m_pActiveItem) - { - m_pActiveItem->Holster( ); - } - - m_pActiveItem = pWeapon; - pWeapon->Deploy( ); - - return TRUE; -} - -//========================================================= -// Dead HEV suit prop -//========================================================= -class CDeadHEV : public CBaseMonster -{ -public: - void Spawn( void ); - int Classify ( void ) { return CLASS_HUMAN_MILITARY; } - - void KeyValue( KeyValueData *pkvd ); - - int m_iPose;// which sequence to display -- temporary, don't need to save - static char *m_szPoses[4]; -}; - -char *CDeadHEV::m_szPoses[] = { "deadback", "deadsitting", "deadstomach", "deadtable" }; - -void CDeadHEV::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "pose")) - { - m_iPose = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseMonster::KeyValue( pkvd ); -} - -LINK_ENTITY_TO_CLASS( monster_hevsuit_dead, CDeadHEV ); - -//========================================================= -// ********** DeadHEV SPAWN ********** -//========================================================= -void CDeadHEV :: Spawn( void ) -{ - PRECACHE_MODEL("models/player.mdl"); - SET_MODEL(ENT(pev), "models/player.mdl"); - - pev->effects = 0; - pev->yaw_speed = 8; - pev->sequence = 0; - pev->body = 1; - m_bloodColor = BLOOD_COLOR_RED; - - pev->sequence = LookupSequence( m_szPoses[m_iPose] ); - - if (pev->sequence == -1) - { - ALERT ( at_console, "Dead hevsuit with bad pose\n" ); - pev->sequence = 0; - pev->effects = EF_BRIGHTFIELD; - } - - // Corpses have less health - pev->health = 8; - - MonsterInitDead(); -} - - -class CStripWeapons : public CPointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -private: -}; - -LINK_ENTITY_TO_CLASS( player_weaponstrip, CStripWeapons ); - -void CStripWeapons :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - CBasePlayer *pPlayer = NULL; - - if ( pActivator && pActivator->IsPlayer() ) - { - pPlayer = (CBasePlayer *)pActivator; - } - else if ( !g_pGameRules->IsDeathmatch() ) - { - pPlayer = (CBasePlayer *)CBaseEntity::Instance( g_engfuncs.pfnPEntityOfEntIndex( 1 ) ); - } - - if ( pPlayer ) - pPlayer->RemoveAllItems( FALSE ); -} - - -class CRevertSaved : public CPointEntity -{ -public: - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT MessageThink( void ); - void EXPORT LoadThink( void ); - void KeyValue( KeyValueData *pkvd ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - inline float Duration( void ) { return pev->dmg_take; } - inline float HoldTime( void ) { return pev->dmg_save; } - inline float MessageTime( void ) { return m_messageTime; } - inline float LoadTime( void ) { return m_loadTime; } - - inline void SetDuration( float duration ) { pev->dmg_take = duration; } - inline void SetHoldTime( float hold ) { pev->dmg_save = hold; } - inline void SetMessageTime( float time ) { m_messageTime = time; } - inline void SetLoadTime( float time ) { m_loadTime = time; } - -private: - float m_messageTime; - float m_loadTime; -}; - -LINK_ENTITY_TO_CLASS( player_loadsaved, CRevertSaved ); - -TYPEDESCRIPTION CRevertSaved::m_SaveData[] = -{ - DEFINE_FIELD( CRevertSaved, m_messageTime, FIELD_FLOAT ), // These are not actual times, but durations, so save as floats - DEFINE_FIELD( CRevertSaved, m_loadTime, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CRevertSaved, CPointEntity ); - -void CRevertSaved :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "duration")) - { - SetDuration( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "holdtime")) - { - SetHoldTime( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "messagetime")) - { - SetMessageTime( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "loadtime")) - { - SetLoadTime( atof(pkvd->szValue) ); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -void CRevertSaved :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - UTIL_ScreenFadeAll( pev->rendercolor, Duration(), HoldTime(), pev->renderamt, FFADE_OUT ); - pev->nextthink = gpGlobals->time + MessageTime(); - SetThink( &CRevertSaved::MessageThink ); -} - - -void CRevertSaved :: MessageThink( void ) -{ - UTIL_ShowMessageAll( STRING(pev->message) ); - float nextThink = LoadTime() - MessageTime(); - if ( nextThink > 0 ) - { - pev->nextthink = gpGlobals->time + nextThink; - SetThink( &CRevertSaved::LoadThink ); - } - else - LoadThink(); -} - - -void CRevertSaved :: LoadThink( void ) -{ - if ( !gpGlobals->deathmatch ) - { - SERVER_COMMAND("reload\n"); - } -} - - -//========================================================= -// Multiplayer intermission spots. -//========================================================= -class CInfoIntermission:public CPointEntity -{ - void Spawn( void ); - void Think( void ); -}; - -void CInfoIntermission::Spawn( void ) -{ - UTIL_SetOrigin( pev, pev->origin ); - pev->solid = SOLID_NOT; - pev->effects = EF_NODRAW; - pev->v_angle = g_vecZero; - - pev->nextthink = gpGlobals->time + 2;// let targets spawn! - -} - -void CInfoIntermission::Think ( void ) -{ - edict_t *pTarget; - - // find my target - pTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(pev->target) ); - - if ( !FNullEnt(pTarget) ) - { - pev->v_angle = UTIL_VecToAngles( (pTarget->v.origin - pev->origin).Normalize() ); - pev->v_angle.x = -pev->v_angle.x; - } -} - -LINK_ENTITY_TO_CLASS( info_intermission, CInfoIntermission ); - - -//========================================================= -// Freeze -//========================================================= -void CBasePlayer::Freeze( void ) -{ - // Glow blue - pev->renderfx = kRenderFxGlowShell; - pev->rendercolor.z = 200; - pev->renderamt = 25; - - pev->maxspeed = FREEZE_SPEED; - m_iFrozen = 1; - - m_flFreezeTime = gpGlobals->time + FREEZE_TIME; -} - -void CBasePlayer::ClearFreezeAndRender() -{ - pev->renderfx = kRenderFxNone; - pev->rendercolor = g_vecZero; - pev->renderamt = 0; - pev->nextthink = 0; - - m_iFrozen = 0; - - if ( IsObserver() ) - pev->maxspeed = 1; - else - pev->maxspeed = 320; -} - -// Force a client to hear a specific VOX sentence. -// This should eventually be moved into the engine. -void CBasePlayer::ClientHearVox( const char *pSentence ) -{ - MESSAGE_BEGIN( MSG_ONE, SVC_STUFFTEXT, NULL, pev ); - - // If it's a sentence, don't put quotes around it - if (pSentence[0] == '#') - { - WRITE_STRING( UTIL_VarArgs("spk %s\n", pSentence ) ); - } - else - { - WRITE_STRING( UTIL_VarArgs("spk \"%s\"\n", pSentence ) ); - } - - MESSAGE_END(); -} diff --git a/ricochet/dlls/player.h b/ricochet/dlls/player.h deleted file mode 100644 index 4490c8a..0000000 --- a/ricochet/dlls/player.h +++ /dev/null @@ -1,356 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef PLAYER_H -#define PLAYER_H - -#define PLAYER_FATAL_FALL_SPEED 1024// approx 60 feet -#define PLAYER_MAX_SAFE_FALL_SPEED 580// approx 20 feet -#define DAMAGE_FOR_FALL_SPEED (float) 100 / ( PLAYER_FATAL_FALL_SPEED - PLAYER_MAX_SAFE_FALL_SPEED )// damage per unit per second. -#define PLAYER_MIN_BOUNCE_SPEED 200 -#define PLAYER_FALL_PUNCH_THRESHHOLD (float)350 // won't punch player's screen/make scrape noise unless player falling at least this fast. - -// -// Player PHYSICS FLAGS bits -// -#define PFLAG_ONLADDER ( 1<<0 ) -#define PFLAG_ONSWING ( 1<<0 ) -#define PFLAG_ONTRAIN ( 1<<1 ) -#define PFLAG_ONBARNACLE ( 1<<2 ) -#define PFLAG_DUCKING ( 1<<3 ) // In the process of ducking, but totally squatted yet -#define PFLAG_USING ( 1<<4 ) // Using a continuous entity -#define PFLAG_OBSERVER ( 1<<5 ) // player is locked in stationary cam mode. Spectators can move, observers can't. - -// -// generic player -// -//----------------------------------------------------- -//This is Half-Life player entity -//----------------------------------------------------- -#define CSUITPLAYLIST 4 // max of 4 suit sentences queued up at any time - -#define SUIT_GROUP TRUE -#define SUIT_SENTENCE FALSE - -#define SUIT_REPEAT_OK 0 -#define SUIT_NEXT_IN_30SEC 30 -#define SUIT_NEXT_IN_1MIN 60 -#define SUIT_NEXT_IN_5MIN 300 -#define SUIT_NEXT_IN_10MIN 600 -#define SUIT_NEXT_IN_30MIN 1800 -#define SUIT_NEXT_IN_1HOUR 3600 - -#define CSUITNOREPEAT 32 - -#define SOUND_FLASHLIGHT_ON "items/flashlight1.wav" -#define SOUND_FLASHLIGHT_OFF "items/flashlight1.wav" - -#define TEAM_NAME_LENGTH 16 - -typedef enum -{ - PLAYER_IDLE, - PLAYER_WALK, - PLAYER_JUMP, - PLAYER_SUPERJUMP, - PLAYER_DIE, - PLAYER_ATTACK1, - PLAYER_FALL, -} PLAYER_ANIM; - -class CDiscArena; - -class CBasePlayer : public CBaseMonster -{ -public: - int random_seed; // See that is shared between client & server for shared weapons code - - int m_iPlayerSound;// the index of the sound list slot reserved for this player - int m_iTargetVolume;// ideal sound volume. - int m_iWeaponVolume;// how loud the player's weapon is right now. - int m_iExtraSoundTypes;// additional classification for this weapon's sound - int m_iWeaponFlash;// brightness of the weapon flash - float m_flStopExtraSoundTime; - - float m_flFlashLightTime; // Time until next battery draw/Recharge - int m_iFlashBattery; // Flashlight Battery Draw - - int m_afButtonLast; - int m_afButtonPressed; - int m_afButtonReleased; - - edict_t *m_pentSndLast; // last sound entity to modify player room type - float m_flSndRoomtype; // last roomtype set by sound entity - float m_flSndRange; // dist from player to sound entity - - float m_flFallVelocity; - - int m_rgItems[MAX_ITEMS]; - int m_fKnownItem; // True when a new item needs to be added - int m_fNewAmmo; // True when a new item has been added - - unsigned int m_afPhysicsFlags; // physics flags - set when 'normal' physics should be revisited or overriden - float m_fNextSuicideTime; // the time after which the player can next use the suicide command - - -// these are time-sensitive things that we keep track of - float m_flTimeStepSound; // when the last stepping sound was made - float m_flTimeWeaponIdle; // when to play another weapon idle animation. - float m_flSwimTime; // how long player has been underwater - float m_flDuckTime; // how long we've been ducking - float m_flWallJumpTime; // how long until next walljump - - float m_flSuitUpdate; // when to play next suit update - int m_rgSuitPlayList[CSUITPLAYLIST];// next sentencenum to play for suit update - int m_iSuitPlayNext; // next sentence slot for queue storage; - int m_rgiSuitNoRepeat[CSUITNOREPEAT]; // suit sentence no repeat list - float m_rgflSuitNoRepeatTime[CSUITNOREPEAT]; // how long to wait before allowing repeat - int m_lastDamageAmount; // Last damage taken - float m_tbdPrev; // Time-based damage timer - - float m_flgeigerRange; // range to nearest radiation source - float m_flgeigerDelay; // delay per update of range msg to client - int m_igeigerRangePrev; - int m_iStepLeft; // alternate left/right foot stepping sound - char m_szTextureName[CBTEXTURENAMEMAX]; // current texture name we're standing on - char m_chTextureType; // current texture type - - int m_idrowndmg; // track drowning damage taken - int m_idrownrestored; // track drowning damage restored - - int m_bitsHUDDamage; // Damage bits for the current fame. These get sent to - // the hude via the DAMAGE message - BOOL m_fInitHUD; // True when deferred HUD restart msg needs to be sent - BOOL m_fGameHUDInitialized; - int m_iTrain; // Train control position - BOOL m_fWeapon; // Set this to FALSE to force a reset of the current weapon HUD info - - EHANDLE m_pTank; // the tank which the player is currently controlling, NULL if no tank - float m_fDeadTime; // the time at which the player died (used in PlayerDeathThink()) - - BOOL m_fNoPlayerSound; // a debugging feature. Player makes no sound if this is true. - BOOL m_fLongJump; // does this player have the longjump module? - - float m_tSneaking; - int m_iUpdateTime; // stores the number of frame ticks before sending HUD update messages - int m_iClientHealth; // the health currently known by the client. If this changes, send a new - int m_iClientBattery; // the Battery currently known by the client. If this changes, send a new - int m_iHideHUD; // the players hud weapon info is to be hidden - int m_iClientHideHUD; - int m_iFOV; // field of view - int m_iClientFOV; // client's known FOV - // usable player items - CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES]; - CBasePlayerItem *m_pActiveItem; - CBasePlayerItem *m_pClientActiveItem; // client version of the active item - CBasePlayerItem *m_pLastItem; - // shared ammo slots - int m_rgAmmo[MAX_AMMO_SLOTS]; - int m_rgAmmoLast[MAX_AMMO_SLOTS]; - - Vector m_vecAutoAim; - BOOL m_fOnTarget; - int m_iDeaths; - float m_iRespawnFrames; // used in PlayerDeathThink() to make sure players can always respawn - - int m_lastx, m_lasty; // These are the previous update's crosshair angles, DON"T SAVE/RESTORE - - int m_nCustomSprayFrames;// Custom clan logo frames for this player - float m_flNextDecalTime;// next time this player can spray a decal - - char m_szTeamName[TEAM_NAME_LENGTH]; - - virtual void Spawn( void ); - void Pain( void ); - -// virtual void Think( void ); - virtual void Jump( void ); - virtual void Duck( void ); - virtual void PreThink( void ); - virtual void PostThink( void ); - virtual Vector GetGunPosition( void ); - virtual int TakeHealth( float flHealth, int bitsDamageType ); - virtual void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType); - virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType); - virtual void Killed( entvars_t *pevAttacker, int iGib ); - virtual Vector BodyTarget( const Vector &posSrc ) { return Center( ) + pev->view_ofs * RANDOM_FLOAT( 0.5, 1.1 ); }; // position to shoot at - virtual void StartSneaking( void ) { m_tSneaking = gpGlobals->time - 1; } - virtual void StopSneaking( void ) { m_tSneaking = gpGlobals->time + 30; } - virtual BOOL IsSneaking( void ) { return m_tSneaking <= gpGlobals->time; } - virtual BOOL IsAlive( void ) { return (pev->deadflag == DEAD_NO) && pev->health > 0; } - virtual BOOL ShouldFadeOnDeath( void ) { return FALSE; } - virtual BOOL IsPlayer( void ) { return TRUE; } // Spectators should return FALSE for this, they aren't "players" as far as game logic is concerned - - virtual BOOL IsNetClient( void ) { return TRUE; } // Bots should return FALSE for this, they can't receive NET messages - // Spectators should return TRUE for this - virtual const char *TeamID( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - void RenewItems(void); - void RemoveAllItems( BOOL removeSuit ); - BOOL SwitchWeapon( CBasePlayerItem *pWeapon ); - - // JOHN: sends custom messages if player HUD data has changed (eg health, ammo) - virtual void UpdateClientData( void ); - - static TYPEDESCRIPTION m_playerSaveData[]; - - // Player is moved across the transition by other means - virtual int ObjectCaps( void ) { return CBaseMonster :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual void Precache( void ); - BOOL IsOnLadder( void ); - BOOL FlashlightIsOn( void ); - void FlashlightTurnOn( void ); - void FlashlightTurnOff( void ); - - void UpdatePlayerSound ( void ); - void DeathSound ( void ); - - int Classify ( void ); - void SetAnimation( PLAYER_ANIM playerAnim ); - void SetWeaponAnimType( const char *szExtention ); - char m_szAnimExtention[32]; - - // custom player functions - virtual void ImpulseCommands( void ); - void CheatImpulseCommands( int iImpulse ); - - void StartDeathCam( void ); - void StartObserver( Vector vecPosition, Vector vecViewAngle ); - void StopObserver( void ); - void Observer_FindNextPlayer( bool bReverse ); - void Observer_HandleButtons(); - void Observer_SetMode( int iMode ); - EHANDLE m_hObserverTarget; - float m_flNextObserverInput; - int IsObserver() { return pev->iuser1; }; - - void AddPoints( int score, BOOL bAllowNegativeScore ); - void AddPointsToTeam( int score, BOOL bAllowNegativeScore ); - BOOL AddPlayerItem( CBasePlayerItem *pItem ); - BOOL RemovePlayerItem( CBasePlayerItem *pItem ); - void DropPlayerItem ( char *pszItemName ); - BOOL HasPlayerItem( CBasePlayerItem *pCheckItem ); - BOOL HasNamedPlayerItem( const char *pszItemName ); - BOOL HasWeapons( void );// do I have ANY weapons? - void SelectPrevItem( int iItem ); - void SelectNextItem( int iItem ); - void SelectLastItem(void); - void SelectItem(const char *pstr); - void ItemPreFrame( void ); - void ItemPostFrame( void ); - void GiveNamedItem( const char *szName ); - void EnableControl(BOOL fControl); - - int GiveAmmo( int iAmount, char *szName, int iMax ); - void SendAmmoUpdate(void); - - void WaterMove( void ); - void EXPORT PlayerDeathThink( void ); - void PlayerUse( void ); - - void CheckSuitUpdate(); - void SetSuitUpdate(char *name, int fgroup, int iNoRepeat); - void UpdateGeigerCounter( void ); - void CheckTimeBasedDamage( void ); - void UpdateStepSound( void ); - void PlayStepSound(int step, float fvol); - - BOOL FBecomeProne ( void ); - void BarnacleVictimBitten ( entvars_t *pevBarnacle ); - void BarnacleVictimReleased ( void ); - static int GetAmmoIndex(const char *psz); - int AmmoInventory( int iAmmoIndex ); - int Illumination( void ); - - void ResetAutoaim( void ); - Vector GetAutoaimVector( float flDelta ); - Vector AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta ); - - void ForceClientDllUpdate( void ); // Forces all client .dll specific data to be resent to client. - - void DeathMessage( entvars_t *pevKiller ); - - void SetCustomDecalFrames( int nFrames ); - int GetCustomDecalFrames( void ); - - // Discwar - void GivePowerup( int iPowerupType ); - void RemovePowerup( int iPowerupType ); - void RemoveAllPowerups( void ); - bool HasPowerup( int iPowerupType ); - void ClearFreezeAndRender( void ); - int m_iPowerups; - int m_iPowerupDiscs; - - void Freeze( void ); - int m_iFrozen; - int m_iClientFrozen; - float m_flFreezeTime; - EHANDLE m_hLastPlayerToHitMe; - float m_flLastDiscHit; - int m_iLastDiscBounces; - float m_flLastDiscHitTeleport; - - Vector m_vecOldVelocity; - - int m_iClientDeaths, m_iClientFrags, m_iClientPlayerClass, m_iClientTeam; - - // Discwar Arena Handling - EHANDLE m_pNextPlayer; - CDiscArena *m_pCurrentArena; - int m_iArenaCombatantNumber; - int m_iLastGameResult; - - // Discwar animation - int GetThrowAnim( void ); - int GetHoldAnim( void ); - int GetFallAnimation( void ); - void Decapitate( entvars_t *pevKiller ); - void Shatter( entvars_t *pevKiller ); - - float m_flThrowTime; - float m_flBackupTime; - float m_flTransitionTime; - Vector m_vecHitVelocity; - BOOL m_bHasDisconnected; - float m_flKnownItemTime; - - void ObserverInput_ChangeMode(); - void ObserverInput_PrevPlayer(); - void ObserverInput_NextPlayer(); - - void ClientHearVox( const char *pSentence ); - - float m_flSendArenaStatus; //Sigh. - float m_flChangeAngles; //Double sigh. -}; - -#define AUTOAIM_2DEGREES 0.0348994967025 -#define AUTOAIM_5DEGREES 0.08715574274766 -#define AUTOAIM_8DEGREES 0.1391731009601 -#define AUTOAIM_10DEGREES 0.1736481776669 - - -extern int gmsgHudText; -extern BOOL gInitHUD; - -// Observer Movement modes (stored in pev->iuser1, so the physics code can get at them) -#define OBS_CHASE_LOCKED 1 -#define OBS_CHASE_FREE 2 -#define OBS_ROAMING 3 -#define OBS_LOCKEDVIEW 4 - -#endif // PLAYER_H diff --git a/ricochet/dlls/saverestore.h b/ricochet/dlls/saverestore.h deleted file mode 100644 index 4065b04..0000000 --- a/ricochet/dlls/saverestore.h +++ /dev/null @@ -1,170 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// Implementation in UTIL.CPP -#ifndef SAVERESTORE_H -#define SAVERESTORE_H - -class CBaseEntity; - -class CSaveRestoreBuffer -{ -public: - CSaveRestoreBuffer( void ); - CSaveRestoreBuffer( SAVERESTOREDATA *pdata ); - ~CSaveRestoreBuffer( void ); - - int EntityIndex( entvars_t *pevLookup ); - int EntityIndex( edict_t *pentLookup ); - int EntityIndex( EOFFSET eoLookup ); - int EntityIndex( CBaseEntity *pEntity ); - - int EntityFlags( int entityIndex, int flags ) { return EntityFlagsSet( entityIndex, 0 ); } - int EntityFlagsSet( int entityIndex, int flags ); - - edict_t *EntityFromIndex( int entityIndex ); - - unsigned short TokenHash( const char *pszToken ); - -protected: - SAVERESTOREDATA *m_pdata; - void BufferRewind( int size ); - unsigned int HashString( const char *pszToken ); -}; - - -class CSave : public CSaveRestoreBuffer -{ -public: - CSave( SAVERESTOREDATA *pdata ) : CSaveRestoreBuffer( pdata ) {}; - - void WriteShort( const char *pname, const short *value, int count ); - void WriteInt( const char *pname, const int *value, int count ); // Save an int - void WriteFloat( const char *pname, const float *value, int count ); // Save a float - void WriteTime( const char *pname, const float *value, int count ); // Save a float (timevalue) - void WriteData( const char *pname, int size, const char *pdata ); // Save a binary data block - void WriteString( const char *pname, const char *pstring ); // Save a null-terminated string - void WriteString( const char *pname, const int *stringId, int count ); // Save a null-terminated string (engine string) - void WriteVector( const char *pname, const Vector &value ); // Save a vector - void WriteVector( const char *pname, const float *value, int count ); // Save a vector - void WritePositionVector( const char *pname, const Vector &value ); // Offset for landmark if necessary - void WritePositionVector( const char *pname, const float *value, int count ); // array of pos vectors - void WriteFunction( const char *pname, void **value, int count ); // Save a function pointer - int WriteEntVars( const char *pname, entvars_t *pev ); // Save entvars_t (entvars_t) - int WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); - -private: - int DataEmpty( const char *pdata, int size ); - void BufferField( const char *pname, int size, const char *pdata ); - void BufferString( char *pdata, int len ); - void BufferData( const char *pdata, int size ); - void BufferHeader( const char *pname, int size ); -}; - -typedef struct -{ - unsigned short size; - unsigned short token; - char *pData; -} HEADER; - -class CRestore : public CSaveRestoreBuffer -{ -public: - CRestore( SAVERESTOREDATA *pdata ) : CSaveRestoreBuffer( pdata ) { m_global = 0; m_precache = TRUE; } - - int ReadEntVars( const char *pname, entvars_t *pev ); // entvars_t - int ReadFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ); - int ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount, int startField, int size, char *pName, void *pData ); - int ReadInt( void ); - short ReadShort( void ); - int ReadNamedInt( const char *pName ); - char *ReadNamedString( const char *pName ); - int Empty( void ) { return (m_pdata == NULL) || ((m_pdata->pCurrentData-m_pdata->pBaseData)>=m_pdata->bufferSize); } - inline void SetGlobalMode( int global ) { m_global = global; } - void PrecacheMode( BOOL mode ) { m_precache = mode; } - -private: - char *BufferPointer( void ); - void BufferReadBytes( char *pOutput, int size ); - void BufferSkipBytes( int bytes ); - int BufferSkipZString( void ); - int BufferCheckZString( const char *string ); - - void BufferReadHeader( HEADER *pheader ); - - int m_global; // Restoring a global entity? - BOOL m_precache; -}; - -#define MAX_ENTITYARRAY 64 - -//#define ARRAYSIZE(p) (sizeof(p)/sizeof(p[0])) - -#define IMPLEMENT_SAVERESTORE(derivedClass,baseClass) \ - int derivedClass::Save( CSave &save )\ - {\ - if ( !baseClass::Save(save) )\ - return 0;\ - return save.WriteFields( #derivedClass, this, m_SaveData, ARRAYSIZE(m_SaveData) );\ - }\ - int derivedClass::Restore( CRestore &restore )\ - {\ - if ( !baseClass::Restore(restore) )\ - return 0;\ - return restore.ReadFields( #derivedClass, this, m_SaveData, ARRAYSIZE(m_SaveData) );\ - } - - -typedef enum { GLOBAL_OFF = 0, GLOBAL_ON = 1, GLOBAL_DEAD = 2 } GLOBALESTATE; - -typedef struct globalentity_s globalentity_t; - -struct globalentity_s -{ - char name[64]; - char levelName[32]; - GLOBALESTATE state; - globalentity_t *pNext; -}; - -class CGlobalState -{ -public: - CGlobalState(); - void Reset( void ); - void ClearStates( void ); - void EntityAdd( string_t globalname, string_t mapName, GLOBALESTATE state ); - void EntitySetState( string_t globalname, GLOBALESTATE state ); - void EntityUpdate( string_t globalname, string_t mapname ); - const globalentity_t *EntityFromTable( string_t globalname ); - GLOBALESTATE EntityGetState( string_t globalname ); - int EntityInTable( string_t globalname ) { return (Find( globalname ) != NULL) ? 1 : 0; } - int Save( CSave &save ); - int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - -//#ifdef _DEBUG - void DumpGlobals( void ); -//#endif - -private: - globalentity_t *Find( string_t globalname ); - globalentity_t *m_pList; - int m_listCount; -}; - -extern CGlobalState gGlobalState; - -#endif //SAVERESTORE_H diff --git a/ricochet/dlls/schedule.h b/ricochet/dlls/schedule.h deleted file mode 100644 index f8ee15a..0000000 --- a/ricochet/dlls/schedule.h +++ /dev/null @@ -1,31 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -//========================================================= -// Scheduling -//========================================================= -#ifndef SCHEDULE_H -#define SCHEDULE_H - -#define bits_COND_SEE_HATE ( 1 << 1 ) // see something that you hate -#define bits_COND_SEE_FEAR ( 1 << 2 ) // see something that you are afraid of -#define bits_COND_SEE_DISLIKE ( 1 << 3 ) // see something that you dislike -#define bits_COND_SEE_ENEMY ( 1 << 4 ) // target entity is in full view. -#define bits_COND_LIGHT_DAMAGE ( 1 << 8 ) // hurt a little -#define bits_COND_HEAVY_DAMAGE ( 1 << 9 ) // hurt a lot -#define bits_COND_SEE_CLIENT ( 1 << 21) // see a client -#define bits_COND_SEE_NEMESIS ( 1 << 22) // see my nemesis - - -#endif // SCHEDULE_H diff --git a/ricochet/dlls/scriptevent.h b/ricochet/dlls/scriptevent.h deleted file mode 100644 index 9aa7140..0000000 --- a/ricochet/dlls/scriptevent.h +++ /dev/null @@ -1,29 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef SCRIPTEVENT_H -#define SCRIPTEVENT_H - -#define SCRIPT_EVENT_DEAD 1000 // character is now dead -#define SCRIPT_EVENT_NOINTERRUPT 1001 // does not allow interrupt -#define SCRIPT_EVENT_CANINTERRUPT 1002 // will allow interrupt -#define SCRIPT_EVENT_FIREEVENT 1003 // event now fires -#define SCRIPT_EVENT_SOUND 1004 // Play named wave file (on CHAN_BODY) -#define SCRIPT_EVENT_SENTENCE 1005 // Play named sentence -#define SCRIPT_EVENT_INAIR 1006 // Leave the character in air at the end of the sequence (don't find the floor) -#define SCRIPT_EVENT_ENDANIMATION 1007 // Set the animation by name after the sequence completes -#define SCRIPT_EVENT_SOUND_VOICE 1008 // Play named wave file (on CHAN_VOICE) -#define SCRIPT_EVENT_SENTENCE_RND1 1009 // Play sentence group 25% of the time -#define SCRIPT_EVENT_NOT_DEAD 1010 // Bring back to life (for life/death sequences) -#endif //SCRIPTEVENT_H diff --git a/ricochet/dlls/singleplay_gamerules.cpp b/ricochet/dlls/singleplay_gamerules.cpp deleted file mode 100644 index 43d5df7..0000000 --- a/ricochet/dlls/singleplay_gamerules.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// teamplay_gamerules.cpp -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "skill.h" -#include "items.h" -#include "discwar.h" - -extern DLL_GLOBAL CGameRules *g_pGameRules; -extern DLL_GLOBAL BOOL g_fGameOver; -extern int gmsgDeathMsg; // client dll messages -extern int gmsgScoreInfo; -extern int gmsgMOTD; - -//========================================================= -//========================================================= -CHalfLifeRules::CHalfLifeRules( void ) -{ - RefreshSkillData(); -} - -//========================================================= -//========================================================= -void CHalfLifeRules::Think ( void ) -{ -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::IsMultiplayer( void ) -{ - return FALSE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::IsDeathmatch ( void ) -{ - return FALSE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::IsCoOp( void ) -{ - return FALSE; -} - - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::FShouldSwitchWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ - if ( !pPlayer->m_pActiveItem ) - { - // player doesn't have an active item! - return TRUE; - } - - if ( !pPlayer->m_pActiveItem->CanHolster() ) - { - return FALSE; - } - - return TRUE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) -{ - return FALSE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: ClientConnected( edict_t *pEntity, const char *pszName, const char *pszAddress, char szRejectReason[ 128 ] ) -{ - return TRUE; -} - -void CHalfLifeRules :: InitHUD( CBasePlayer *pl ) -{ -} - -//========================================================= -//========================================================= -void CHalfLifeRules :: ClientDisconnected( edict_t *pClient ) -{ -} - -//========================================================= -//========================================================= -float CHalfLifeRules::FlPlayerFallDamage( CBasePlayer *pPlayer ) -{ - // subtract off the speed at which a player is allowed to fall without being hurt, - // so damage will be based on speed beyond that, not the entire fall - pPlayer->m_flFallVelocity -= PLAYER_MAX_SAFE_FALL_SPEED; - return pPlayer->m_flFallVelocity * DAMAGE_FOR_FALL_SPEED; -} - -//========================================================= -//========================================================= -void CHalfLifeRules :: PlayerSpawn( CBasePlayer *pPlayer ) -{ - pPlayer->GiveNamedItem( "weapon_disc" ); - pPlayer->GiveAmmo( MAX_DISCS, "disc", MAX_DISCS ); -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: AllowAutoTargetCrosshair( void ) -{ - return ( g_iSkillLevel == SKILL_EASY ); -} - -//========================================================= -//========================================================= -void CHalfLifeRules :: PlayerThink( CBasePlayer *pPlayer ) -{ -} - - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: FPlayerCanRespawn( CBasePlayer *pPlayer ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -float CHalfLifeRules :: FlPlayerSpawnTime( CBasePlayer *pPlayer ) -{ - return gpGlobals->time;//now! -} - -//========================================================= -// IPointsForKill - how many points awarded to anyone -// that kills this player? -//========================================================= -int CHalfLifeRules :: IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) -{ - return 1; -} - -//========================================================= -// PlayerKilled - someone/something killed this player -//========================================================= -void CHalfLifeRules :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ -} - -//========================================================= -// Deathnotice -//========================================================= -void CHalfLifeRules::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ -} - -//========================================================= -// PlayerGotWeapon - player has grabbed a weapon that was -// sitting in the world -//========================================================= -void CHalfLifeRules :: PlayerGotWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pWeapon ) -{ -} - -//========================================================= -// FlWeaponRespawnTime - what is the time in the future -// at which this weapon may spawn? -//========================================================= -float CHalfLifeRules :: FlWeaponRespawnTime( CBasePlayerItem *pWeapon ) -{ - return -1; -} - -//========================================================= -// FlWeaponRespawnTime - Returns 0 if the weapon can respawn -// now, otherwise it returns the time at which it can try -// to spawn again. -//========================================================= -float CHalfLifeRules :: FlWeaponTryRespawn( CBasePlayerItem *pWeapon ) -{ - return 0; -} - -//========================================================= -// VecWeaponRespawnSpot - where should this weapon spawn? -// Some game variations may choose to randomize spawn locations -//========================================================= -Vector CHalfLifeRules :: VecWeaponRespawnSpot( CBasePlayerItem *pWeapon ) -{ - return pWeapon->pev->origin; -} - -//========================================================= -// WeaponShouldRespawn - any conditions inhibiting the -// respawning of this weapon? -//========================================================= -int CHalfLifeRules :: WeaponShouldRespawn( CBasePlayerItem *pWeapon ) -{ - return GR_WEAPON_RESPAWN_NO; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::CanHaveItem( CBasePlayer *pPlayer, CItem *pItem ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -void CHalfLifeRules::PlayerGotItem( CBasePlayer *pPlayer, CItem *pItem ) -{ -} - -//========================================================= -//========================================================= -int CHalfLifeRules::ItemShouldRespawn( CItem *pItem ) -{ - return GR_ITEM_RESPAWN_NO; -} - - -//========================================================= -// At what time in the future may this Item respawn? -//========================================================= -float CHalfLifeRules::FlItemRespawnTime( CItem *pItem ) -{ - return -1; -} - -//========================================================= -// Where should this item respawn? -// Some game variations may choose to randomize spawn locations -//========================================================= -Vector CHalfLifeRules::VecItemRespawnSpot( CItem *pItem ) -{ - return pItem->pev->origin; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules::IsAllowedToSpawn( CBaseEntity *pEntity ) -{ - return TRUE; -} - -//========================================================= -//========================================================= -void CHalfLifeRules::PlayerGotAmmo( CBasePlayer *pPlayer, char *szName, int iCount ) -{ -} - -//========================================================= -//========================================================= -int CHalfLifeRules::AmmoShouldRespawn( CBasePlayerAmmo *pAmmo ) -{ - return GR_AMMO_RESPAWN_NO; -} - -//========================================================= -//========================================================= -float CHalfLifeRules::FlAmmoRespawnTime( CBasePlayerAmmo *pAmmo ) -{ - return -1; -} - -//========================================================= -//========================================================= -Vector CHalfLifeRules::VecAmmoRespawnSpot( CBasePlayerAmmo *pAmmo ) -{ - return pAmmo->pev->origin; -} - -//========================================================= -//========================================================= -float CHalfLifeRules::FlHealthChargerRechargeTime( void ) -{ - return 0;// don't recharge -} - -//========================================================= -//========================================================= -int CHalfLifeRules::DeadPlayerWeapons( CBasePlayer *pPlayer ) -{ - return GR_PLR_DROP_GUN_NO; -} - -//========================================================= -//========================================================= -int CHalfLifeRules::DeadPlayerAmmo( CBasePlayer *pPlayer ) -{ - return GR_PLR_DROP_AMMO_NO; -} - -//========================================================= -//========================================================= -int CHalfLifeRules::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) -{ - // why would a single player in half life need this? - return GR_NOTTEAMMATE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeRules :: FAllowMonsters( void ) -{ - return TRUE; -} diff --git a/ricochet/dlls/skill.cpp b/ricochet/dlls/skill.cpp deleted file mode 100644 index 5e06914..0000000 --- a/ricochet/dlls/skill.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -//========================================================= -// skill.cpp - code for skill level concerns -//========================================================= -#include "extdll.h" -#include "util.h" -#include "skill.h" - - -skilldata_t gSkillData; - - -//========================================================= -// take the name of a cvar, tack a digit for the skill level -// on, and return the value.of that Cvar -//========================================================= -float GetSkillCvar( char *pName ) -{ - int iCount; - float flValue; - char szBuffer[ 64 ]; - - iCount = sprintf( szBuffer, "%s%d",pName, gSkillData.iSkillLevel ); - - flValue = CVAR_GET_FLOAT ( szBuffer ); - - if ( flValue <= 0 ) - { - ALERT ( at_console, "\n\n** GetSkillCVar Got a zero for %s **\n\n", szBuffer ); - } - - return flValue; -} - diff --git a/ricochet/dlls/skill.h b/ricochet/dlls/skill.h deleted file mode 100644 index 30e25f8..0000000 --- a/ricochet/dlls/skill.h +++ /dev/null @@ -1,147 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -//========================================================= -// skill.h - skill level concerns -//========================================================= - -struct skilldata_t -{ - - int iSkillLevel; // game skill level - -// Monster Health & Damage - float agruntHealth; - float agruntDmgPunch; - - float apacheHealth; - - float barneyHealth; - - float bigmommaHealthFactor; // Multiply each node's health by this - float bigmommaDmgSlash; // melee attack damage - float bigmommaDmgBlast; // mortar attack damage - float bigmommaRadiusBlast; // mortar attack radius - - float bullsquidHealth; - float bullsquidDmgBite; - float bullsquidDmgWhip; - float bullsquidDmgSpit; - - float gargantuaHealth; - float gargantuaDmgSlash; - float gargantuaDmgFire; - float gargantuaDmgStomp; - - float hassassinHealth; - - float headcrabHealth; - float headcrabDmgBite; - - float hgruntHealth; - float hgruntDmgKick; - float hgruntShotgunPellets; - float hgruntGrenadeSpeed; - - float houndeyeHealth; - float houndeyeDmgBlast; - - float slaveHealth; - float slaveDmgClaw; - float slaveDmgClawrake; - float slaveDmgZap; - - float ichthyosaurHealth; - float ichthyosaurDmgShake; - - float leechHealth; - float leechDmgBite; - - float controllerHealth; - float controllerDmgZap; - float controllerSpeedBall; - float controllerDmgBall; - - float nihilanthHealth; - float nihilanthZap; - - float scientistHealth; - - float snarkHealth; - float snarkDmgBite; - float snarkDmgPop; - - float zombieHealth; - float zombieDmgOneSlash; - float zombieDmgBothSlash; - - float turretHealth; - float miniturretHealth; - float sentryHealth; - - -// Player Weapons - float plrDmgCrowbar; - float plrDmg9MM; - float plrDmg357; - float plrDmgMP5; - float plrDmgM203Grenade; - float plrDmgBuckshot; - float plrDmgCrossbowClient; - float plrDmgCrossbowMonster; - float plrDmgRPG; - float plrDmgGauss; - float plrDmgEgonNarrow; - float plrDmgEgonWide; - float plrDmgHornet; - float plrDmgHandGrenade; - float plrDmgSatchel; - float plrDmgTripmine; - -// weapons shared by monsters - float monDmg9MM; - float monDmgMP5; - float monDmg12MM; - float monDmgHornet; - -// health/suit charge - float suitchargerCapacity; - float batteryCapacity; - float healthchargerCapacity; - float healthkitCapacity; - float scientistHeal; - -// monster damage adj - float monHead; - float monChest; - float monStomach; - float monLeg; - float monArm; - -// player damage adj - float plrHead; - float plrChest; - float plrStomach; - float plrLeg; - float plrArm; -}; - -extern DLL_GLOBAL skilldata_t gSkillData; -float GetSkillCvar( char *pName ); - -extern DLL_GLOBAL int g_iSkillLevel; - -#define SKILL_EASY 1 -#define SKILL_MEDIUM 2 -#define SKILL_HARD 3 diff --git a/ricochet/dlls/sound.cpp b/ricochet/dlls/sound.cpp deleted file mode 100644 index 7aa61e7..0000000 --- a/ricochet/dlls/sound.cpp +++ /dev/null @@ -1,2005 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -//========================================================= -// sound.cpp -//========================================================= - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "weapons.h" -#include "player.h" -#include "talkmonster.h" -#include "gamerules.h" - -#if !defined ( _WIN32 ) -#include -#endif - -static char *memfgets( byte *pMemFile, int fileSize, int &filePos, char *pBuffer, int bufferSize ); - - -// ==================== GENERIC AMBIENT SOUND ====================================== - -// runtime pitch shift and volume fadein/out structure - -// NOTE: IF YOU CHANGE THIS STRUCT YOU MUST CHANGE THE SAVE/RESTORE VERSION NUMBER -// SEE BELOW (in the typedescription for the class) -typedef struct dynpitchvol -{ - // NOTE: do not change the order of these parameters - // NOTE: unless you also change order of rgdpvpreset array elements! - int preset; - - int pitchrun; // pitch shift % when sound is running 0 - 255 - int pitchstart; // pitch shift % when sound stops or starts 0 - 255 - int spinup; // spinup time 0 - 100 - int spindown; // spindown time 0 - 100 - - int volrun; // volume change % when sound is running 0 - 10 - int volstart; // volume change % when sound stops or starts 0 - 10 - int fadein; // volume fade in time 0 - 100 - int fadeout; // volume fade out time 0 - 100 - - // Low Frequency Oscillator - int lfotype; // 0) off 1) square 2) triangle 3) random - int lforate; // 0 - 1000, how fast lfo osciallates - - int lfomodpitch; // 0-100 mod of current pitch. 0 is off. - int lfomodvol; // 0-100 mod of current volume. 0 is off. - - int cspinup; // each trigger hit increments counter and spinup pitch - - - int cspincount; - - int pitch; - int spinupsav; - int spindownsav; - int pitchfrac; - - int vol; - int fadeinsav; - int fadeoutsav; - int volfrac; - - int lfofrac; - int lfomult; - - -} dynpitchvol_t; - -#define CDPVPRESETMAX 27 - -// presets for runtime pitch and vol modulation of ambient sounds - -dynpitchvol_t rgdpvpreset[CDPVPRESETMAX] = -{ -// pitch pstart spinup spindwn volrun volstrt fadein fadeout lfotype lforate modptch modvol cspnup -{1, 255, 75, 95, 95, 10, 1, 50, 95, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{2, 255, 85, 70, 88, 10, 1, 20, 88, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{3, 255, 100, 50, 75, 10, 1, 10, 75, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{4, 100, 100, 0, 0, 10, 1, 90, 90, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{5, 100, 100, 0, 0, 10, 1, 80, 80, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{6, 100, 100, 0, 0, 10, 1, 50, 70, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{7, 100, 100, 0, 0, 5, 1, 40, 50, 1, 50, 0, 10, 0, 0,0,0,0,0,0,0,0,0,0}, -{8, 100, 100, 0, 0, 5, 1, 40, 50, 1, 150, 0, 10, 0, 0,0,0,0,0,0,0,0,0,0}, -{9, 100, 100, 0, 0, 5, 1, 40, 50, 1, 750, 0, 10, 0, 0,0,0,0,0,0,0,0,0,0}, -{10,128, 100, 50, 75, 10, 1, 30, 40, 2, 8, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{11,128, 100, 50, 75, 10, 1, 30, 40, 2, 25, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{12,128, 100, 50, 75, 10, 1, 30, 40, 2, 70, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{13,50, 50, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{14,70, 70, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{15,90, 90, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{16,120, 120, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{17,180, 180, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{18,255, 255, 0, 0, 10, 1, 20, 50, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{19,200, 75, 90, 90, 10, 1, 50, 90, 2, 100, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{20,255, 75, 97, 90, 10, 1, 50, 90, 1, 40, 50, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{21,100, 100, 0, 0, 10, 1, 30, 50, 3, 15, 20, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{22,160, 160, 0, 0, 10, 1, 50, 50, 3, 500, 25, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{23,255, 75, 88, 0, 10, 1, 40, 0, 0, 0, 0, 0, 5, 0,0,0,0,0,0,0,0,0,0}, -{24,200, 20, 95, 70, 10, 1, 70, 70, 3, 20, 50, 0, 0, 0,0,0,0,0,0,0,0,0,0}, -{25,180, 100, 50, 60, 10, 1, 40, 60, 2, 90, 100, 100, 0, 0,0,0,0,0,0,0,0,0,0}, -{26,60, 60, 0, 0, 10, 1, 40, 70, 3, 80, 20, 50, 0, 0,0,0,0,0,0,0,0,0,0}, -{27,128, 90, 10, 10, 10, 1, 20, 40, 1, 5, 10, 20, 0, 0,0,0,0,0,0,0,0,0,0} -}; - -class CAmbientGeneric : public CBaseEntity -{ -public: - void KeyValue( KeyValueData* pkvd); - void Spawn( void ); - void Precache( void ); - void EXPORT ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT RampThink( void ); - void InitModulationParms(void); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } - - float m_flAttenuation; // attenuation value - dynpitchvol_t m_dpv; - - BOOL m_fActive; // only TRUE when the entity is playing a looping sound - BOOL m_fLooping; // TRUE when the sound played will loop -}; - -LINK_ENTITY_TO_CLASS( ambient_generic, CAmbientGeneric ); -TYPEDESCRIPTION CAmbientGeneric::m_SaveData[] = -{ - DEFINE_FIELD( CAmbientGeneric, m_flAttenuation, FIELD_FLOAT ), - DEFINE_FIELD( CAmbientGeneric, m_fActive, FIELD_BOOLEAN ), - DEFINE_FIELD( CAmbientGeneric, m_fLooping, FIELD_BOOLEAN ), - - // HACKHACK - This is not really in the spirit of the save/restore design, but save this - // out as a binary data block. If the dynpitchvol_t is changed, old saved games will NOT - // load these correctly, so bump the save/restore version if you change the size of the struct - // The right way to do this is to split the input parms (read in keyvalue) into members and re-init this - // struct in Precache(), but it's unlikely that the struct will change, so it's not worth the time right now. - DEFINE_ARRAY( CAmbientGeneric, m_dpv, FIELD_CHARACTER, sizeof(dynpitchvol_t) ), -}; - -IMPLEMENT_SAVERESTORE( CAmbientGeneric, CBaseEntity ); - -// -// ambient_generic - general-purpose user-defined static sound -// -void CAmbientGeneric :: Spawn( void ) -{ -/* - -1 : "Default" - 0 : "Everywhere" - 200 : "Small Radius" - 125 : "Medium Radius" - 80 : "Large Radius" -*/ - - if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_EVERYWHERE) ) - { - m_flAttenuation = ATTN_NONE; - } - else if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_SMALLRADIUS) ) - { - m_flAttenuation = ATTN_IDLE; - } - else if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_MEDIUMRADIUS) ) - { - m_flAttenuation = ATTN_STATIC; - } - else if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_LARGERADIUS) ) - { - m_flAttenuation = ATTN_NORM; - } - else - {// if the designer didn't set a sound attenuation, default to one. - m_flAttenuation = ATTN_STATIC; - } - - char* szSoundFile = (char*) STRING(pev->message); - - if ( FStringNull( pev->message ) || strlen( szSoundFile ) < 1 ) - { - ALERT( at_error, "EMPTY AMBIENT AT: %f, %f, %f\n", pev->origin.x, pev->origin.y, pev->origin.z ); - pev->nextthink = gpGlobals->time + 0.1; - SetThink( &CAmbientGeneric::SUB_Remove ); - return; - } - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - - // Set up think function for dynamic modification - // of ambient sound's pitch or volume. Don't - // start thinking yet. - - SetThink(&CAmbientGeneric::RampThink); - pev->nextthink = 0; - - // allow on/off switching via 'use' function. - - SetUse ( &CAmbientGeneric::ToggleUse ); - - m_fActive = FALSE; - - if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_NOT_LOOPING ) ) - m_fLooping = FALSE; - else - m_fLooping = TRUE; - Precache( ); -} - - -void CAmbientGeneric :: Precache( void ) -{ - char* szSoundFile = (char*) STRING(pev->message); - - if ( !FStringNull( pev->message ) && strlen( szSoundFile ) > 1 ) - { - if (*szSoundFile != '!') - PRECACHE_SOUND(szSoundFile); - } - // init all dynamic modulation parms - InitModulationParms(); - - if ( !FBitSet (pev->spawnflags, AMBIENT_SOUND_START_SILENT ) ) - { - // start the sound ASAP - if (m_fLooping) - m_fActive = TRUE; - } - if ( m_fActive ) - { - UTIL_EmitAmbientSound ( ENT(pev), pev->origin, szSoundFile, - (m_dpv.vol * 0.01), m_flAttenuation, SND_SPAWNING, m_dpv.pitch); - - pev->nextthink = gpGlobals->time + 0.1; - } -} - -// RampThink - Think at 5hz if we are dynamically modifying -// pitch or volume of the playing sound. This function will -// ramp pitch and/or volume up or down, modify pitch/volume -// with lfo if active. - -void CAmbientGeneric :: RampThink( void ) -{ - char* szSoundFile = (char*) STRING(pev->message); - int pitch = m_dpv.pitch; - int vol = m_dpv.vol; - int flags = 0; - int fChanged = 0; // FALSE if pitch and vol remain unchanged this round - int prev; - - if (!m_dpv.spinup && !m_dpv.spindown && !m_dpv.fadein && !m_dpv.fadeout && !m_dpv.lfotype) - return; // no ramps or lfo, stop thinking - - // ============== - // pitch envelope - // ============== - if (m_dpv.spinup || m_dpv.spindown) - { - prev = m_dpv.pitchfrac >> 8; - - if (m_dpv.spinup > 0) - m_dpv.pitchfrac += m_dpv.spinup; - else if (m_dpv.spindown > 0) - m_dpv.pitchfrac -= m_dpv.spindown; - - pitch = m_dpv.pitchfrac >> 8; - - if (pitch > m_dpv.pitchrun) - { - pitch = m_dpv.pitchrun; - m_dpv.spinup = 0; // done with ramp up - } - - if (pitch < m_dpv.pitchstart) - { - pitch = m_dpv.pitchstart; - m_dpv.spindown = 0; // done with ramp down - - // shut sound off - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_STOP, 0); - - // return without setting nextthink - return; - } - - if (pitch > 255) pitch = 255; - if (pitch < 1) pitch = 1; - - m_dpv.pitch = pitch; - - fChanged |= (prev != pitch); - flags |= SND_CHANGE_PITCH; - } - - // ================== - // amplitude envelope - // ================== - if (m_dpv.fadein || m_dpv.fadeout) - { - prev = m_dpv.volfrac >> 8; - - if (m_dpv.fadein > 0) - m_dpv.volfrac += m_dpv.fadein; - else if (m_dpv.fadeout > 0) - m_dpv.volfrac -= m_dpv.fadeout; - - vol = m_dpv.volfrac >> 8; - - if (vol > m_dpv.volrun) - { - vol = m_dpv.volrun; - m_dpv.fadein = 0; // done with ramp up - } - - if (vol < m_dpv.volstart) - { - vol = m_dpv.volstart; - m_dpv.fadeout = 0; // done with ramp down - - // shut sound off - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_STOP, 0); - - // return without setting nextthink - return; - } - - if (vol > 100) vol = 100; - if (vol < 1) vol = 1; - - m_dpv.vol = vol; - - fChanged |= (prev != vol); - flags |= SND_CHANGE_VOL; - } - - // =================== - // pitch/amplitude LFO - // =================== - if (m_dpv.lfotype) - { - int pos; - - if (m_dpv.lfofrac > 0x6fffffff) - m_dpv.lfofrac = 0; - - // update lfo, lfofrac/255 makes a triangle wave 0-255 - m_dpv.lfofrac += m_dpv.lforate; - pos = m_dpv.lfofrac >> 8; - - if (m_dpv.lfofrac < 0) - { - m_dpv.lfofrac = 0; - m_dpv.lforate = abs(m_dpv.lforate); - pos = 0; - } - else if (pos > 255) - { - pos = 255; - m_dpv.lfofrac = (255 << 8); - m_dpv.lforate = -abs(m_dpv.lforate); - } - - switch(m_dpv.lfotype) - { - case LFO_SQUARE: - if (pos < 128) - m_dpv.lfomult = 255; - else - m_dpv.lfomult = 0; - - break; - case LFO_RANDOM: - if (pos == 255) - m_dpv.lfomult = RANDOM_LONG(0, 255); - break; - case LFO_TRIANGLE: - default: - m_dpv.lfomult = pos; - break; - } - - if (m_dpv.lfomodpitch) - { - prev = pitch; - - // pitch 0-255 - pitch += ((m_dpv.lfomult - 128) * m_dpv.lfomodpitch) / 100; - - if (pitch > 255) pitch = 255; - if (pitch < 1) pitch = 1; - - - fChanged |= (prev != pitch); - flags |= SND_CHANGE_PITCH; - } - - if (m_dpv.lfomodvol) - { - // vol 0-100 - prev = vol; - - vol += ((m_dpv.lfomult - 128) * m_dpv.lfomodvol) / 100; - - if (vol > 100) vol = 100; - if (vol < 0) vol = 0; - - fChanged |= (prev != vol); - flags |= SND_CHANGE_VOL; - } - - } - - // Send update to playing sound only if we actually changed - // pitch or volume in this routine. - - if (flags && fChanged) - { - if (pitch == PITCH_NORM) - pitch = PITCH_NORM + 1; // don't send 'no pitch' ! - - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - (vol * 0.01), m_flAttenuation, flags, pitch); - } - - // update ramps at 5hz - pev->nextthink = gpGlobals->time + 0.2; - return; -} - -// Init all ramp params in preparation to -// play a new sound - -void CAmbientGeneric :: InitModulationParms(void) -{ - int pitchinc; - - m_dpv.volrun = pev->health * 10; // 0 - 100 - if (m_dpv.volrun > 100) m_dpv.volrun = 100; - if (m_dpv.volrun < 0) m_dpv.volrun = 0; - - // get presets - if (m_dpv.preset != 0 && m_dpv.preset <= CDPVPRESETMAX) - { - // load preset values - m_dpv = rgdpvpreset[m_dpv.preset - 1]; - - // fixup preset values, just like - // fixups in KeyValue routine. - if (m_dpv.spindown > 0) - m_dpv.spindown = (101 - m_dpv.spindown) * 64; - if (m_dpv.spinup > 0) - m_dpv.spinup = (101 - m_dpv.spinup) * 64; - - m_dpv.volstart *= 10; - m_dpv.volrun *= 10; - - if (m_dpv.fadein > 0) - m_dpv.fadein = (101 - m_dpv.fadein) * 64; - if (m_dpv.fadeout > 0) - m_dpv.fadeout = (101 - m_dpv.fadeout) * 64; - - m_dpv.lforate *= 256; - - m_dpv.fadeinsav = m_dpv.fadein; - m_dpv.fadeoutsav = m_dpv.fadeout; - m_dpv.spinupsav = m_dpv.spinup; - m_dpv.spindownsav = m_dpv.spindown; - } - - m_dpv.fadein = m_dpv.fadeinsav; - m_dpv.fadeout = 0; - - if (m_dpv.fadein) - m_dpv.vol = m_dpv.volstart; - else - m_dpv.vol = m_dpv.volrun; - - m_dpv.spinup = m_dpv.spinupsav; - m_dpv.spindown = 0; - - if (m_dpv.spinup) - m_dpv.pitch = m_dpv.pitchstart; - else - m_dpv.pitch = m_dpv.pitchrun; - - if (m_dpv.pitch == 0) - m_dpv.pitch = PITCH_NORM; - - m_dpv.pitchfrac = m_dpv.pitch << 8; - m_dpv.volfrac = m_dpv.vol << 8; - - m_dpv.lfofrac = 0; - m_dpv.lforate = abs(m_dpv.lforate); - - m_dpv.cspincount = 1; - - if (m_dpv.cspinup) - { - pitchinc = (255 - m_dpv.pitchstart) / m_dpv.cspinup; - - m_dpv.pitchrun = m_dpv.pitchstart + pitchinc; - if (m_dpv.pitchrun > 255) m_dpv.pitchrun = 255; - } - - if ((m_dpv.spinupsav || m_dpv.spindownsav || (m_dpv.lfotype && m_dpv.lfomodpitch)) - && (m_dpv.pitch == PITCH_NORM)) - m_dpv.pitch = PITCH_NORM + 1; // must never send 'no pitch' as first pitch - // if we intend to pitch shift later! -} - -// -// ToggleUse - turns an ambient sound on or off. If the -// ambient is a looping sound, mark sound as active (m_fActive) -// if it's playing, innactive if not. If the sound is not -// a looping sound, never mark it as active. -// -void CAmbientGeneric :: ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - char* szSoundFile = (char*) STRING(pev->message); - float fraction; - - if ( useType != USE_TOGGLE ) - { - if ( (m_fActive && useType == USE_ON) || (!m_fActive && useType == USE_OFF) ) - return; - } - // Directly change pitch if arg passed. Only works if sound is already playing. - - if (useType == USE_SET && m_fActive) // Momentary buttons will pass down a float in here - { - - fraction = value; - - if ( fraction > 1.0 ) - fraction = 1.0; - if (fraction < 0.0) - fraction = 0.01; - - m_dpv.pitch = fraction * 255; - - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_CHANGE_PITCH, m_dpv.pitch); - - return; - } - - // Toggle - - // m_fActive is TRUE only if a looping sound is playing. - - if ( m_fActive ) - {// turn sound off - - if (m_dpv.cspinup) - { - // Don't actually shut off. Each toggle causes - // incremental spinup to max pitch - - if (m_dpv.cspincount <= m_dpv.cspinup) - { - int pitchinc; - - // start a new spinup - m_dpv.cspincount++; - - pitchinc = (255 - m_dpv.pitchstart) / m_dpv.cspinup; - - m_dpv.spinup = m_dpv.spinupsav; - m_dpv.spindown = 0; - - m_dpv.pitchrun = m_dpv.pitchstart + pitchinc * m_dpv.cspincount; - if (m_dpv.pitchrun > 255) m_dpv.pitchrun = 255; - - pev->nextthink = gpGlobals->time + 0.1; - } - - } - else - { - m_fActive = FALSE; - - // HACKHACK - this makes the code in Precache() work properly after a save/restore - pev->spawnflags |= AMBIENT_SOUND_START_SILENT; - - if (m_dpv.spindownsav || m_dpv.fadeoutsav) - { - // spin it down (or fade it) before shutoff if spindown is set - m_dpv.spindown = m_dpv.spindownsav; - m_dpv.spinup = 0; - - m_dpv.fadeout = m_dpv.fadeoutsav; - m_dpv.fadein = 0; - pev->nextthink = gpGlobals->time + 0.1; - } - else - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_STOP, 0); - } - } - else - {// turn sound on - - // only toggle if this is a looping sound. If not looping, each - // trigger will cause the sound to play. If the sound is still - // playing from a previous trigger press, it will be shut off - // and then restarted. - - if (m_fLooping) - m_fActive = TRUE; - else - // shut sound off now - may be interrupting a long non-looping sound - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - 0, 0, SND_STOP, 0); - - // init all ramp params for startup - - InitModulationParms(); - - UTIL_EmitAmbientSound(ENT(pev), pev->origin, szSoundFile, - (m_dpv.vol * 0.01), m_flAttenuation, 0, m_dpv.pitch); - - pev->nextthink = gpGlobals->time + 0.1; - - } -} -// KeyValue - load keyvalue pairs into member data of the -// ambient generic. NOTE: called BEFORE spawn! - -void CAmbientGeneric :: KeyValue( KeyValueData *pkvd ) -{ - // NOTE: changing any of the modifiers in this code - // NOTE: also requires changing InitModulationParms code. - - // preset - if (FStrEq(pkvd->szKeyName, "preset")) - { - m_dpv.preset = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - - // pitchrun - else if (FStrEq(pkvd->szKeyName, "pitch")) - { - m_dpv.pitchrun = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - - if (m_dpv.pitchrun > 255) m_dpv.pitchrun = 255; - if (m_dpv.pitchrun < 0) m_dpv.pitchrun = 0; - } - - // pitchstart - else if (FStrEq(pkvd->szKeyName, "pitchstart")) - { - m_dpv.pitchstart = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - - if (m_dpv.pitchstart > 255) m_dpv.pitchstart = 255; - if (m_dpv.pitchstart < 0) m_dpv.pitchstart = 0; - } - - // spinup - else if (FStrEq(pkvd->szKeyName, "spinup")) - { - m_dpv.spinup = atoi(pkvd->szValue); - - if (m_dpv.spinup > 100) m_dpv.spinup = 100; - if (m_dpv.spinup < 0) m_dpv.spinup = 0; - - if (m_dpv.spinup > 0) - m_dpv.spinup = (101 - m_dpv.spinup) * 64; - m_dpv.spinupsav = m_dpv.spinup; - pkvd->fHandled = TRUE; - } - - // spindown - else if (FStrEq(pkvd->szKeyName, "spindown")) - { - m_dpv.spindown = atoi(pkvd->szValue); - - if (m_dpv.spindown > 100) m_dpv.spindown = 100; - if (m_dpv.spindown < 0) m_dpv.spindown = 0; - - if (m_dpv.spindown > 0) - m_dpv.spindown = (101 - m_dpv.spindown) * 64; - m_dpv.spindownsav = m_dpv.spindown; - pkvd->fHandled = TRUE; - } - - // volstart - else if (FStrEq(pkvd->szKeyName, "volstart")) - { - m_dpv.volstart = atoi(pkvd->szValue); - - if (m_dpv.volstart > 10) m_dpv.volstart = 10; - if (m_dpv.volstart < 0) m_dpv.volstart = 0; - - m_dpv.volstart *= 10; // 0 - 100 - - pkvd->fHandled = TRUE; - } - - // fadein - else if (FStrEq(pkvd->szKeyName, "fadein")) - { - m_dpv.fadein = atoi(pkvd->szValue); - - if (m_dpv.fadein > 100) m_dpv.fadein = 100; - if (m_dpv.fadein < 0) m_dpv.fadein = 0; - - if (m_dpv.fadein > 0) - m_dpv.fadein = (101 - m_dpv.fadein) * 64; - m_dpv.fadeinsav = m_dpv.fadein; - pkvd->fHandled = TRUE; - } - - // fadeout - else if (FStrEq(pkvd->szKeyName, "fadeout")) - { - m_dpv.fadeout = atoi(pkvd->szValue); - - if (m_dpv.fadeout > 100) m_dpv.fadeout = 100; - if (m_dpv.fadeout < 0) m_dpv.fadeout = 0; - - if (m_dpv.fadeout > 0) - m_dpv.fadeout = (101 - m_dpv.fadeout) * 64; - m_dpv.fadeoutsav = m_dpv.fadeout; - pkvd->fHandled = TRUE; - } - - // lfotype - else if (FStrEq(pkvd->szKeyName, "lfotype")) - { - m_dpv.lfotype = atoi(pkvd->szValue); - if (m_dpv.lfotype > 4) m_dpv.lfotype = LFO_TRIANGLE; - pkvd->fHandled = TRUE; - } - - // lforate - else if (FStrEq(pkvd->szKeyName, "lforate")) - { - m_dpv.lforate = atoi(pkvd->szValue); - - if (m_dpv.lforate > 1000) m_dpv.lforate = 1000; - if (m_dpv.lforate < 0) m_dpv.lforate = 0; - - m_dpv.lforate *= 256; - - pkvd->fHandled = TRUE; - } - // lfomodpitch - else if (FStrEq(pkvd->szKeyName, "lfomodpitch")) - { - m_dpv.lfomodpitch = atoi(pkvd->szValue); - if (m_dpv.lfomodpitch > 100) m_dpv.lfomodpitch = 100; - if (m_dpv.lfomodpitch < 0) m_dpv.lfomodpitch = 0; - - - pkvd->fHandled = TRUE; - } - - // lfomodvol - else if (FStrEq(pkvd->szKeyName, "lfomodvol")) - { - m_dpv.lfomodvol = atoi(pkvd->szValue); - if (m_dpv.lfomodvol > 100) m_dpv.lfomodvol = 100; - if (m_dpv.lfomodvol < 0) m_dpv.lfomodvol = 0; - - pkvd->fHandled = TRUE; - } - - // cspinup - else if (FStrEq(pkvd->szKeyName, "cspinup")) - { - m_dpv.cspinup = atoi(pkvd->szValue); - if (m_dpv.cspinup > 100) m_dpv.cspinup = 100; - if (m_dpv.cspinup < 0) m_dpv.cspinup = 0; - - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -// =================== ROOM SOUND FX ========================================== - -class CEnvSound : public CPointEntity -{ -public: - void KeyValue( KeyValueData* pkvd); - void Spawn( void ); - - void Think( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - float m_flRadius; - float m_flRoomtype; -}; - -LINK_ENTITY_TO_CLASS( env_sound, CEnvSound ); -TYPEDESCRIPTION CEnvSound::m_SaveData[] = -{ - DEFINE_FIELD( CEnvSound, m_flRadius, FIELD_FLOAT ), - DEFINE_FIELD( CEnvSound, m_flRoomtype, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE( CEnvSound, CBaseEntity ); - - -void CEnvSound :: KeyValue( KeyValueData *pkvd ) -{ - - if (FStrEq(pkvd->szKeyName, "radius")) - { - m_flRadius = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - if (FStrEq(pkvd->szKeyName, "roomtype")) - { - m_flRoomtype = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } -} - -// returns TRUE if the given sound entity (pev) is in range -// and can see the given player entity (pevTarget) - -BOOL FEnvSoundInRange(entvars_t *pev, entvars_t *pevTarget, float *pflRange) -{ - CEnvSound *pSound = GetClassPtr( (CEnvSound *)pev ); - Vector vecSpot1 = pev->origin + pev->view_ofs; - Vector vecSpot2 = pevTarget->origin + pevTarget->view_ofs; - Vector vecRange; - float flRange; - TraceResult tr; - - UTIL_TraceLine(vecSpot1, vecSpot2, ignore_monsters, ENT(pev), &tr); - - // check if line of sight crosses water boundary, or is blocked - - if ((tr.fInOpen && tr.fInWater) || tr.flFraction != 1) - return FALSE; - - // calc range from sound entity to player - - vecRange = tr.vecEndPos - vecSpot1; - flRange = vecRange.Length(); - - if (pSound->m_flRadius < flRange) - return FALSE; - - if (pflRange) - *pflRange = flRange; - - return TRUE; -} - -// -// A client that is visible and in range of a sound entity will -// have its room_type set by that sound entity. If two or more -// sound entities are contending for a client, then the nearest -// sound entity to the client will set the client's room_type. -// A client's room_type will remain set to its prior value until -// a new in-range, visible sound entity resets a new room_type. -// - -// CONSIDER: if player in water state, autoset roomtype to 14,15 or 16. - -void CEnvSound :: Think( void ) -{ - // get pointer to client if visible; FIND_CLIENT_IN_PVS will - // cycle through visible clients on consecutive calls. - - edict_t *pentPlayer = FIND_CLIENT_IN_PVS(edict()); - CBasePlayer *pPlayer = NULL; - - if (FNullEnt(pentPlayer)) - goto env_sound_Think_slow; // no player in pvs of sound entity, slow it down - - pPlayer = GetClassPtr( (CBasePlayer *)VARS(pentPlayer)); - float flRange; - - // check to see if this is the sound entity that is - // currently affecting this player - - if(!FNullEnt(pPlayer->m_pentSndLast) && (pPlayer->m_pentSndLast == ENT(pev))) { - - // this is the entity currently affecting player, check - // for validity - - if (pPlayer->m_flSndRoomtype != 0 && pPlayer->m_flSndRange != 0) { - - // we're looking at a valid sound entity affecting - // player, make sure it's still valid, update range - - if (FEnvSoundInRange(pev, VARS(pentPlayer), &flRange)) { - pPlayer->m_flSndRange = flRange; - goto env_sound_Think_fast; - } else { - - // current sound entity affecting player is no longer valid, - // flag this state by clearing room_type and range. - // NOTE: we do not actually change the player's room_type - // NOTE: until we have a new valid room_type to change it to. - - pPlayer->m_flSndRange = 0; - pPlayer->m_flSndRoomtype = 0; - goto env_sound_Think_slow; - } - } else { - // entity is affecting player but is out of range, - // wait passively for another entity to usurp it... - goto env_sound_Think_slow; - } - } - - // if we got this far, we're looking at an entity that is contending - // for current player sound. the closest entity to player wins. - - if (FEnvSoundInRange(pev, VARS(pentPlayer), &flRange)) - { - if (flRange < pPlayer->m_flSndRange || pPlayer->m_flSndRange == 0) - { - // new entity is closer to player, so it wins. - pPlayer->m_pentSndLast = ENT(pev); - pPlayer->m_flSndRoomtype = m_flRoomtype; - pPlayer->m_flSndRange = flRange; - - // send room_type command to player's server. - // this should be a rare event - once per change of room_type - // only! - - //CLIENT_COMMAND(pentPlayer, "room_type %f", m_flRoomtype); - - MESSAGE_BEGIN( MSG_ONE, SVC_ROOMTYPE, NULL, pentPlayer ); // use the magic #1 for "one client" - WRITE_SHORT( (short)m_flRoomtype ); // sequence number - MESSAGE_END(); - - // crank up nextthink rate for new active sound entity - // by falling through to think_fast... - } - // player is not closer to the contending sound entity, - // just fall through to think_fast. this effectively - // cranks up the think_rate of entities near the player. - } - - // player is in pvs of sound entity, but either not visible or - // not in range. do nothing, fall through to think_fast... - -env_sound_Think_fast: - pev->nextthink = gpGlobals->time + 0.25; - return; - -env_sound_Think_slow: - pev->nextthink = gpGlobals->time + 0.75; - return; -} - -// -// env_sound - spawn a sound entity that will set player roomtype -// when player moves in range and sight. -// -// -void CEnvSound :: Spawn( ) -{ - // spread think times - pev->nextthink = gpGlobals->time + RANDOM_FLOAT(0.0, 0.5); -} - -// ==================== SENTENCE GROUPS, UTILITY FUNCTIONS ====================================== - -#define CSENTENCE_LRU_MAX 32 // max number of elements per sentence group - -// group of related sentences - -typedef struct sentenceg -{ - char szgroupname[CBSENTENCENAME_MAX]; - int count; - unsigned char rgblru[CSENTENCE_LRU_MAX]; - -} SENTENCEG; - -#define CSENTENCEG_MAX 200 // max number of sentence groups -// globals - -SENTENCEG rgsentenceg[CSENTENCEG_MAX]; -int fSentencesInit = FALSE; - -char gszallsentencenames[CVOXFILESENTENCEMAX][CBSENTENCENAME_MAX]; -int gcallsentences = 0; - -// randomize list of sentence name indices - -void USENTENCEG_InitLRU(unsigned char *plru, int count) -{ - int i, j, k; - unsigned char temp; - - if (!fSentencesInit) - return; - - if (count > CSENTENCE_LRU_MAX) - count = CSENTENCE_LRU_MAX; - - for (i = 0; i < count; i++) - plru[i] = (unsigned char) i; - - // randomize array - for (i = 0; i < (count * 4); i++) - { - j = RANDOM_LONG(0,count-1); - k = RANDOM_LONG(0,count-1); - temp = plru[j]; - plru[j] = plru[k]; - plru[k] = temp; - } -} - -// ignore lru. pick next sentence from sentence group. Go in order until we hit the last sentence, -// then repeat list if freset is true. If freset is false, then repeat last sentence. -// ipick is passed in as the requested sentence ordinal. -// ipick 'next' is returned. -// return of -1 indicates an error. - -int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int freset) -{ - char *szgroupname; - unsigned char count; - char sznum[8]; - - if (!fSentencesInit) - return -1; - - if (isentenceg < 0) - return -1; - - szgroupname = rgsentenceg[isentenceg].szgroupname; - count = rgsentenceg[isentenceg].count; - - if (count == 0) - return -1; - - if (ipick >= count) - ipick = count-1; - - strcpy(szfound, "!"); - strcat(szfound, szgroupname); - // Shepard - UNTESTED LINUX FIX!!! -#ifdef WIN32 - itoa(ipick, sznum, 10); -#else - ipick = atol(ipick); -#endif - strcat(szfound, sznum); - - if (ipick >= count) - { - if (freset) - // reset at end of list - return 0; - else - return count; - } - - return ipick + 1; -} - - - -// pick a random sentence from rootname0 to rootnameX. -// picks from the rgsentenceg[isentenceg] least -// recently used, modifies lru array. returns the sentencename. -// note, lru must be seeded with 0-n randomized sentence numbers, with the -// rest of the lru filled with -1. The first integer in the lru is -// actually the size of the list. Returns ipick, the ordinal -// of the picked sentence within the group. - -int USENTENCEG_Pick(int isentenceg, char *szfound) -{ - char *szgroupname; - unsigned char *plru; - unsigned char i; - unsigned char count; - char sznum[8]; - unsigned char ipick; - int ffound = FALSE; - - if (!fSentencesInit) - return -1; - - if (isentenceg < 0) - return -1; - - szgroupname = rgsentenceg[isentenceg].szgroupname; - count = rgsentenceg[isentenceg].count; - plru = rgsentenceg[isentenceg].rgblru; - - while (!ffound) - { - for (i = 0; i < count; i++) - if (plru[i] != 0xFF) - { - ipick = plru[i]; - plru[i] = 0xFF; - ffound = TRUE; - break; - } - - if (!ffound) - USENTENCEG_InitLRU(plru, count); - else - { - strcpy(szfound, "!"); - strcat(szfound, szgroupname); - // Shepard - UNTESTED LINUX FIX!!! -#ifdef WIN32 - itoa(ipick, sznum, 10); -#else - ipick = atol(sznum); -#endif - strcat(szfound, sznum); - return ipick; - } - } - return -1; -} - -// ===================== SENTENCE GROUPS, MAIN ROUTINES ======================== - -// Given sentence group rootname (name without number suffix), -// get sentence group index (isentenceg). Returns -1 if no such name. - -int SENTENCEG_GetIndex(const char *szgroupname) -{ - int i; - - if (!fSentencesInit || !szgroupname) - return -1; - - // search rgsentenceg for match on szgroupname - - i = 0; - while (rgsentenceg[i].count) - { - if (!strcmp(szgroupname, rgsentenceg[i].szgroupname)) - return i; - i++; - } - - return -1; -} - -// given sentence group index, play random sentence for given entity. -// returns ipick - which sentence was picked to -// play from the group. Ipick is only needed if you plan on stopping -// the sound before playback is done (see SENTENCEG_Stop). - -int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, - float volume, float attenuation, int flags, int pitch) -{ - char name[64]; - int ipick; - - if (!fSentencesInit) - return -1; - - name[0] = 0; - - ipick = USENTENCEG_Pick(isentenceg, name); - if (ipick > 0 && name) - EMIT_SOUND_DYN(entity, CHAN_VOICE, name, volume, attenuation, flags, pitch); - return ipick; -} - -// same as above, but takes sentence group name instead of index - -int SENTENCEG_PlayRndSz(edict_t *entity, const char *szgroupname, - float volume, float attenuation, int flags, int pitch) -{ - char name[64]; - int ipick; - int isentenceg; - - if (!fSentencesInit) - return -1; - - name[0] = 0; - - isentenceg = SENTENCEG_GetIndex(szgroupname); - if (isentenceg < 0) - { - ALERT( at_console, "No such sentence group %s\n", szgroupname ); - return -1; - } - - ipick = USENTENCEG_Pick(isentenceg, name); - if (ipick >= 0 && name[0]) - EMIT_SOUND_DYN(entity, CHAN_VOICE, name, volume, attenuation, flags, pitch); - - return ipick; -} - -// play sentences in sequential order from sentence group. Reset after last sentence. - -int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szgroupname, - float volume, float attenuation, int flags, int pitch, int ipick, int freset) -{ - char name[64]; - int ipicknext; - int isentenceg; - - if (!fSentencesInit) - return -1; - - name[0] = 0; - - isentenceg = SENTENCEG_GetIndex(szgroupname); - if (isentenceg < 0) - return -1; - - ipicknext = USENTENCEG_PickSequential(isentenceg, name, ipick, freset); - if (ipicknext >= 0 && name[0]) - EMIT_SOUND_DYN(entity, CHAN_VOICE, name, volume, attenuation, flags, pitch); - return ipicknext; -} - - -// for this entity, for the given sentence within the sentence group, stop -// the sentence. - -void SENTENCEG_Stop(edict_t *entity, int isentenceg, int ipick) -{ - char buffer[64]; - char sznum[8]; - - if (!fSentencesInit) - return; - - if (isentenceg < 0 || ipick < 0) - return; - - strcpy(buffer, "!"); - strcat(buffer, rgsentenceg[isentenceg].szgroupname); - // Shepard - UNTESTED LINUX FIX!!! -#ifdef WIN32 - itoa(ipick, sznum, 10); -#else - ipick = atol(sznum); -#endif - strcat(buffer, sznum); - - STOP_SOUND(entity, CHAN_VOICE, buffer); -} - -// open sentences.txt, scan for groups, build rgsentenceg -// Should be called from world spawn, only works on the -// first call and is ignored subsequently. - -void SENTENCEG_Init() -{ - char buffer[512]; - char szgroup[64]; - int i, j; - int isentencegs; - - if (fSentencesInit) - return; - - memset(gszallsentencenames, 0, CVOXFILESENTENCEMAX * CBSENTENCENAME_MAX); - gcallsentences = 0; - - memset(rgsentenceg, 0, CSENTENCEG_MAX * sizeof(SENTENCEG)); - memset(buffer, 0, 512); - memset(szgroup, 0, 64); - isentencegs = -1; - - - int filePos = 0, fileSize; - byte *pMemFile = g_engfuncs.pfnLoadFileForMe( "sound/sentences.txt", &fileSize ); - if ( !pMemFile ) - return; - - // for each line in the file... - while ( memfgets(pMemFile, fileSize, filePos, buffer, 511) != NULL ) - { - // skip whitespace - i = 0; - while(buffer[i] && buffer[i] == ' ') - i++; - - if (!buffer[i]) - continue; - - if (buffer[i] == '/' || !isalpha(buffer[i])) - continue; - - // get sentence name - j = i; - while (buffer[j] && buffer[j] != ' ') - j++; - - if (!buffer[j]) - continue; - - if (gcallsentences > CVOXFILESENTENCEMAX) - { - ALERT (at_error, "Too many sentences in sentences.txt!\n"); - break; - } - - // null-terminate name and save in sentences array - buffer[j] = 0; - const char *pString = buffer + i; - - if ( strlen( pString ) >= CBSENTENCENAME_MAX ) - ALERT( at_warning, "Sentence %s longer than %d letters\n", pString, CBSENTENCENAME_MAX-1 ); - - strcpy( gszallsentencenames[gcallsentences++], pString ); - - j--; - if (j <= i) - continue; - if (!isdigit(buffer[j])) - continue; - - // cut out suffix numbers - while (j > i && isdigit(buffer[j])) - j--; - - if (j <= i) - continue; - - buffer[j+1] = 0; - - // if new name doesn't match previous group name, - // make a new group. - - if (strcmp(szgroup, &(buffer[i]))) - { - // name doesn't match with prev name, - // copy name into group, init count to 1 - isentencegs++; - if (isentencegs >= CSENTENCEG_MAX) - { - ALERT (at_error, "Too many sentence groups in sentences.txt!\n"); - break; - } - - strcpy(rgsentenceg[isentencegs].szgroupname, &(buffer[i])); - rgsentenceg[isentencegs].count = 1; - - strcpy(szgroup, &(buffer[i])); - - continue; - } - else - { - //name matches with previous, increment group count - if (isentencegs >= 0) - rgsentenceg[isentencegs].count++; - } - } - - g_engfuncs.pfnFreeFile( pMemFile ); - - fSentencesInit = TRUE; - - // init lru lists - - i = 0; - - while (rgsentenceg[i].count && i < CSENTENCEG_MAX) - { - USENTENCEG_InitLRU(&(rgsentenceg[i].rgblru[0]), rgsentenceg[i].count); - i++; - } - -} - -// convert sentence (sample) name to !sentencenum, return !sentencenum - -int SENTENCEG_Lookup(const char *sample, char *sentencenum) -{ - char sznum[8]; - -//#ifdef GERMANY -// return -1; // no constructed sentences in international versions -//#endif // GERMANY - - int i; - // this is a sentence name; lookup sentence number - // and give to engine as string. - for (i = 0; i < gcallsentences; i++) - if (!stricmp(gszallsentencenames[i], sample+1)) - { - if (sentencenum) - { - strcpy(sentencenum, "!"); - // Shepard - UNTESTED LINUX FIX!!! -#ifdef WIN32 - itoa(i, sznum, 10); -#else - i = atol(sznum); -#endif - strcat(sentencenum, sznum); - } - return i; - } - // sentence name not found! - return -1; -} - -void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, - int flags, int pitch) -{ - if (sample && *sample == '!') - { - char name[32]; - if (SENTENCEG_Lookup(sample, name) >= 0) - EMIT_SOUND_DYN2(entity, channel, name, volume, attenuation, flags, pitch); - else - ALERT( at_aiconsole, "Unable to find %s in sentences.txt\n", sample ); - } - else - EMIT_SOUND_DYN2(entity, channel, sample, volume, attenuation, flags, pitch); -} - -// play a specific sentence over the HEV suit speaker - just pass player entity, and !sentencename - -void EMIT_SOUND_SUIT(edict_t *entity, const char *sample) -{ - float fvol; - int pitch = PITCH_NORM; - - fvol = CVAR_GET_FLOAT("suitvolume"); - if (RANDOM_LONG(0,1)) - pitch = RANDOM_LONG(0,6) + 98; - - if (fvol > 0.05) - EMIT_SOUND_DYN(entity, CHAN_STATIC, sample, fvol, ATTN_NORM, 0, pitch); -} - -// play a sentence, randomly selected from the passed in group id, over the HEV suit speaker - -void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg) -{ - float fvol; - int pitch = PITCH_NORM; - - fvol = CVAR_GET_FLOAT("suitvolume"); - if (RANDOM_LONG(0,1)) - pitch = RANDOM_LONG(0,6) + 98; - - if (fvol > 0.05) - SENTENCEG_PlayRndI(entity, isentenceg, fvol, ATTN_NORM, 0, pitch); -} - -// play a sentence, randomly selected from the passed in groupname - -void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname) -{ - float fvol; - int pitch = PITCH_NORM; - - fvol = CVAR_GET_FLOAT("suitvolume"); - if (RANDOM_LONG(0,1)) - pitch = RANDOM_LONG(0,6) + 98; - - if (fvol > 0.05) - SENTENCEG_PlayRndSz(entity, groupname, fvol, ATTN_NORM, 0, pitch); -} - -// ===================== MATERIAL TYPE DETECTION, MAIN ROUTINES ======================== -// -// Used to detect the texture the player is standing on, map the -// texture name to a material type. Play footstep sound based -// on material type. - -int fTextureTypeInit = FALSE; - -#define CTEXTURESMAX 512 // max number of textures loaded - -int gcTextures = 0; -char grgszTextureName[CTEXTURESMAX][CBTEXTURENAMEMAX]; // texture names -char grgchTextureType[CTEXTURESMAX]; // parallel array of texture types - -// open materials.txt, get size, alloc space, -// save in array. Only works first time called, -// ignored on subsequent calls. - -static char *memfgets( byte *pMemFile, int fileSize, int &filePos, char *pBuffer, int bufferSize ) -{ - // Bullet-proofing - if ( !pMemFile || !pBuffer ) - return NULL; - - if ( filePos >= fileSize ) - return NULL; - - int i = filePos; - int last = fileSize; - - // fgets always NULL terminates, so only read bufferSize-1 characters - if ( last - filePos > (bufferSize-1) ) - last = filePos + (bufferSize-1); - - int stop = 0; - - // Stop at the next newline (inclusive) or end of buffer - while ( i < last && !stop ) - { - if ( pMemFile[i] == '\n' ) - stop = 1; - i++; - } - - - // If we actually advanced the pointer, copy it over - if ( i != filePos ) - { - // We read in size bytes - int size = i - filePos; - // copy it out - memcpy( pBuffer, pMemFile + filePos, sizeof(byte)*size ); - - // If the buffer isn't full, terminate (this is always true) - if ( size < bufferSize ) - pBuffer[size] = 0; - - // Update file pointer - filePos = i; - return pBuffer; - } - - // No data read, bail - return NULL; -} - - -void TEXTURETYPE_Init() -{ - char buffer[512]; - int i, j; - byte *pMemFile; - int fileSize, filePos; - - if (fTextureTypeInit) - return; - - memset(&(grgszTextureName[0][0]), 0, CTEXTURESMAX * CBTEXTURENAMEMAX); - memset(grgchTextureType, 0, CTEXTURESMAX); - - gcTextures = 0; - memset(buffer, 0, 512); - - pMemFile = g_engfuncs.pfnLoadFileForMe( "sound/materials.txt", &fileSize ); - if ( !pMemFile ) - return; - - // for each line in the file... - while (memfgets(pMemFile, fileSize, filePos, buffer, 511) != NULL && (gcTextures < CTEXTURESMAX)) - { - // skip whitespace - i = 0; - while(buffer[i] && isspace(buffer[i])) - i++; - - if (!buffer[i]) - continue; - - // skip comment lines - if (buffer[i] == '/' || !isalpha(buffer[i])) - continue; - - // get texture type - grgchTextureType[gcTextures] = toupper(buffer[i++]); - - // skip whitespace - while(buffer[i] && isspace(buffer[i])) - i++; - - if (!buffer[i]) - continue; - - // get sentence name - j = i; - while (buffer[j] && !isspace(buffer[j])) - j++; - - if (!buffer[j]) - continue; - - // null-terminate name and save in sentences array - j = V_min (j, CBTEXTURENAMEMAX-1+i); - buffer[j] = 0; - strcpy(&(grgszTextureName[gcTextures++][0]), &(buffer[i])); - } - - g_engfuncs.pfnFreeFile( pMemFile ); - - fTextureTypeInit = TRUE; -} - -// given texture name, find texture type -// if not found, return type 'concrete' - -// NOTE: this routine should ONLY be called if the -// current texture under the player changes! - -char TEXTURETYPE_Find(char *name) -{ - // CONSIDER: pre-sort texture names and perform faster binary search here - - for (int i = 0; i < gcTextures; i++) - { - if (!_strnicmp(name, &(grgszTextureName[i][0]), CBTEXTURENAMEMAX-1)) - return (grgchTextureType[i]); - } - - return CHAR_TEX_CONCRETE; -} - -// play a strike sound based on the texture that was hit by the attack traceline. VecSrc/VecEnd are the -// original traceline endpoints used by the attacker, iBulletType is the type of bullet that hit the texture. -// returns volume of strike instrument (crowbar) to play - -float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int iBulletType) -{ -// hit the world, try to play sound based on texture material type - - char chTextureType; - float fvol; - float fvolbar; - char szbuffer[64]; - const char *pTextureName; - float rgfl1[3]; - float rgfl2[3]; - char *rgsz[4]; - int cnt; - float fattn = ATTN_NORM; - - if ( !g_pGameRules->PlayTextureSounds() ) - return 0.0; - - CBaseEntity *pEntity = CBaseEntity::Instance(ptr->pHit); - - chTextureType = 0; - - if (pEntity && pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE) - // hit body - chTextureType = CHAR_TEX_FLESH; - else - { - // hit world - - // find texture under strike, get material type - - // copy trace vector into array for trace_texture - - vecSrc.CopyToArray(rgfl1); - vecEnd.CopyToArray(rgfl2); - - // get texture from entity or world (world is ent(0)) - if (pEntity) - pTextureName = TRACE_TEXTURE( ENT(pEntity->pev), rgfl1, rgfl2 ); - else - pTextureName = TRACE_TEXTURE( ENT(0), rgfl1, rgfl2 ); - - if ( pTextureName ) - { - // strip leading '-0' or '+0~' or '{' or '!' - if (*pTextureName == '-' || *pTextureName == '+') - pTextureName += 2; - - if (*pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ') - pTextureName++; - // '}}' - strcpy(szbuffer, pTextureName); - szbuffer[CBTEXTURENAMEMAX - 1] = 0; - - // ALERT ( at_console, "texture hit: %s\n", szbuffer); - - // get texture type - chTextureType = TEXTURETYPE_Find(szbuffer); - } - } - - switch (chTextureType) - { - default: - case CHAR_TEX_CONCRETE: fvol = 0.9; fvolbar = 0.6; - rgsz[0] = "player/pl_step1.wav"; - rgsz[1] = "player/pl_step2.wav"; - cnt = 2; - break; - case CHAR_TEX_METAL: fvol = 0.9; fvolbar = 0.3; - rgsz[0] = "player/pl_metal1.wav"; - rgsz[1] = "player/pl_metal2.wav"; - cnt = 2; - break; - case CHAR_TEX_DIRT: fvol = 0.9; fvolbar = 0.1; - rgsz[0] = "player/pl_dirt1.wav"; - rgsz[1] = "player/pl_dirt2.wav"; - rgsz[2] = "player/pl_dirt3.wav"; - cnt = 3; - break; - case CHAR_TEX_VENT: fvol = 0.5; fvolbar = 0.3; - rgsz[0] = "player/pl_duct1.wav"; - rgsz[1] = "player/pl_duct1.wav"; - cnt = 2; - break; - case CHAR_TEX_GRATE: fvol = 0.9; fvolbar = 0.5; - rgsz[0] = "player/pl_grate1.wav"; - rgsz[1] = "player/pl_grate4.wav"; - cnt = 2; - break; - case CHAR_TEX_TILE: fvol = 0.8; fvolbar = 0.2; - rgsz[0] = "player/pl_tile1.wav"; - rgsz[1] = "player/pl_tile3.wav"; - rgsz[2] = "player/pl_tile2.wav"; - rgsz[3] = "player/pl_tile4.wav"; - cnt = 4; - break; - case CHAR_TEX_SLOSH: fvol = 0.9; fvolbar = 0.0; - rgsz[0] = "player/pl_slosh1.wav"; - rgsz[1] = "player/pl_slosh3.wav"; - rgsz[2] = "player/pl_slosh2.wav"; - rgsz[3] = "player/pl_slosh4.wav"; - cnt = 4; - break; - case CHAR_TEX_WOOD: fvol = 0.9; fvolbar = 0.2; - rgsz[0] = "debris/wood1.wav"; - rgsz[1] = "debris/wood2.wav"; - rgsz[2] = "debris/wood3.wav"; - cnt = 3; - break; - case CHAR_TEX_GLASS: - case CHAR_TEX_COMPUTER: - fvol = 0.8; fvolbar = 0.2; - rgsz[0] = "debris/glass1.wav"; - rgsz[1] = "debris/glass2.wav"; - rgsz[2] = "debris/glass3.wav"; - cnt = 3; - break; - case CHAR_TEX_FLESH: - if (iBulletType == BULLET_PLAYER_CROWBAR) - return 0.0; // crowbar already makes this sound - fvol = 1.0; fvolbar = 0.2; - rgsz[0] = "weapons/bullet_hit1.wav"; - rgsz[1] = "weapons/bullet_hit2.wav"; - fattn = 1.0; - cnt = 2; - break; - } - - // did we hit a breakable? - - if (pEntity && FClassnameIs(pEntity->pev, "func_breakable")) - { - // drop volumes, the object will already play a damaged sound - fvol /= 1.5; - fvolbar /= 2.0; - } - else if (chTextureType == CHAR_TEX_COMPUTER) - { - // play random spark if computer - - if ( ptr->flFraction != 1.0 && RANDOM_LONG(0,1)) - { - UTIL_Sparks( ptr->vecEndPos ); - - float flVolume = RANDOM_FLOAT ( 0.7 , 1.0 );//random volume range - switch ( RANDOM_LONG(0,1) ) - { - case 0: UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, "buttons/spark5.wav", flVolume, ATTN_NORM, 0, 100); break; - case 1: UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, "buttons/spark6.wav", flVolume, ATTN_NORM, 0, 100); break; - // case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark5.wav", flVolume, ATTN_NORM); break; - // case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "buttons/spark6.wav", flVolume, ATTN_NORM); break; - } - } - } - - // play material hit sound - UTIL_EmitAmbientSound(ENT(0), ptr->vecEndPos, rgsz[RANDOM_LONG(0,cnt-1)], fvol, fattn, 0, 96 + RANDOM_LONG(0,0xf)); - //EMIT_SOUND_DYN( ENT(m_pPlayer->pev), CHAN_WEAPON, rgsz[RANDOM_LONG(0,cnt-1)], fvol, ATTN_NORM, 0, 96 + RANDOM_LONG(0,0xf)); - - return fvolbar; -} - -// =================================================================================== -// -// Speaker class. Used for announcements per level, for door lock/unlock spoken voice. -// - -class CSpeaker : public CBaseEntity -{ -public: - void KeyValue( KeyValueData* pkvd); - void Spawn( void ); - void Precache( void ); - void EXPORT ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT SpeakerThink( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION); } - - int m_preset; // preset number -}; - -LINK_ENTITY_TO_CLASS( speaker, CSpeaker ); -TYPEDESCRIPTION CSpeaker::m_SaveData[] = -{ - DEFINE_FIELD( CSpeaker, m_preset, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CSpeaker, CBaseEntity ); - -// -// ambient_generic - general-purpose user-defined static sound -// -void CSpeaker :: Spawn( void ) -{ - char* szSoundFile = (char*) STRING(pev->message); - - if ( !m_preset && (FStringNull( pev->message ) || strlen( szSoundFile ) < 1 )) - { - ALERT( at_error, "SPEAKER with no Level/Sentence! at: %f, %f, %f\n", pev->origin.x, pev->origin.y, pev->origin.z ); - pev->nextthink = gpGlobals->time + 0.1; - SetThink( &CSpeaker::SUB_Remove ); - return; - } - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - - - SetThink(&CSpeaker::SpeakerThink); - pev->nextthink = 0.0; - - // allow on/off switching via 'use' function. - - SetUse ( &CSpeaker::ToggleUse ); - - Precache( ); -} - -#define ANNOUNCE_MINUTES_MIN 0.25 -#define ANNOUNCE_MINUTES_MAX 2.25 - -void CSpeaker :: Precache( void ) -{ - if ( !FBitSet (pev->spawnflags, SPEAKER_START_SILENT ) ) - // set first announcement time for random n second - pev->nextthink = gpGlobals->time + RANDOM_FLOAT(5.0, 15.0); -} -void CSpeaker :: SpeakerThink( void ) -{ - char* szSoundFile; - float flvolume = pev->health * 0.1; - float flattenuation = 0.3; - int flags = 0; - int pitch = 100; - - - // Wait for the talkmonster to finish first. - if (gpGlobals->time <= CTalkMonster::g_talkWaitTime) - { - pev->nextthink = CTalkMonster::g_talkWaitTime + RANDOM_FLOAT( 5, 10 ); - return; - } - - if (m_preset) - { - // go lookup preset text, assign szSoundFile - switch (m_preset) - { - case 1: szSoundFile = "C1A0_"; break; - case 2: szSoundFile = "C1A1_"; break; - case 3: szSoundFile = "C1A2_"; break; - case 4: szSoundFile = "C1A3_"; break; - case 5: szSoundFile = "C1A4_"; break; - case 6: szSoundFile = "C2A1_"; break; - case 7: szSoundFile = "C2A2_"; break; - case 8: szSoundFile = "C2A3_"; break; - case 9: szSoundFile = "C2A4_"; break; - case 10: szSoundFile = "C2A5_"; break; - case 11: szSoundFile = "C3A1_"; break; - case 12: szSoundFile = "C3A2_"; break; - } - } else - szSoundFile = (char*) STRING(pev->message); - - if (szSoundFile[0] == '!') - { - // play single sentence, one shot - UTIL_EmitAmbientSound ( ENT(pev), pev->origin, szSoundFile, - flvolume, flattenuation, flags, pitch); - - // shut off and reset - pev->nextthink = 0.0; - } - else - { - // make random announcement from sentence group - - if (SENTENCEG_PlayRndSz(ENT(pev), szSoundFile, flvolume, flattenuation, flags, pitch) < 0) - ALERT(at_console, "Level Design Error!\nSPEAKER has bad sentence group name: %s\n",szSoundFile); - - // set next announcement time for random 5 to 10 minute delay - pev->nextthink = gpGlobals->time + - RANDOM_FLOAT(ANNOUNCE_MINUTES_MIN * 60.0, ANNOUNCE_MINUTES_MAX * 60.0); - - CTalkMonster::g_talkWaitTime = gpGlobals->time + 5; // time delay until it's ok to speak: used so that two NPCs don't talk at once - } - - return; -} - - -// -// ToggleUse - if an announcement is pending, cancel it. If no announcement is pending, start one. -// -void CSpeaker :: ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - int fActive = (pev->nextthink > 0.0); - - // fActive is TRUE only if an announcement is pending - - if ( useType != USE_TOGGLE ) - { - // ignore if we're just turning something on that's already on, or - // turning something off that's already off. - if ( (fActive && useType == USE_ON) || (!fActive && useType == USE_OFF) ) - return; - } - - if ( useType == USE_ON ) - { - // turn on announcements - pev->nextthink = gpGlobals->time + 0.1; - return; - } - - if ( useType == USE_OFF ) - { - // turn off announcements - pev->nextthink = 0.0; - return; - - } - - // Toggle announcements - - - if ( fActive ) - { - // turn off announcements - pev->nextthink = 0.0; - } - else - { - // turn on announcements - pev->nextthink = gpGlobals->time + 0.1; - } -} - -// KeyValue - load keyvalue pairs into member data -// NOTE: called BEFORE spawn! - -void CSpeaker :: KeyValue( KeyValueData *pkvd ) -{ - - // preset - if (FStrEq(pkvd->szKeyName, "preset")) - { - m_preset = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} diff --git a/ricochet/dlls/soundent.cpp b/ricochet/dlls/soundent.cpp deleted file mode 100644 index 65dac45..0000000 --- a/ricochet/dlls/soundent.cpp +++ /dev/null @@ -1,379 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "soundent.h" - - -LINK_ENTITY_TO_CLASS( soundent, CSoundEnt ); - -CSoundEnt *pSoundEnt; - -//========================================================= -// CSound - Clear - zeros all fields for a sound -//========================================================= -void CSound :: Clear ( void ) -{ - m_vecOrigin = g_vecZero; - m_iType = 0; - m_iVolume = 0; - m_flExpireTime = 0; - m_iNext = SOUNDLIST_EMPTY; - m_iNextAudible = 0; -} - -//========================================================= -// Reset - clears the volume, origin, and type for a sound, -// but doesn't expire or unlink it. -//========================================================= -void CSound :: Reset ( void ) -{ - m_vecOrigin = g_vecZero; - m_iType = 0; - m_iVolume = 0; - m_iNext = SOUNDLIST_EMPTY; -} - -//========================================================= -// FIsSound - returns TRUE if the sound is an Audible sound -//========================================================= -BOOL CSound :: FIsSound ( void ) -{ - if ( m_iType & ( bits_SOUND_COMBAT | bits_SOUND_WORLD | bits_SOUND_PLAYER | bits_SOUND_DANGER ) ) - { - return TRUE; - } - - return FALSE; -} - -//========================================================= -// FIsScent - returns TRUE if the sound is actually a scent -//========================================================= -BOOL CSound :: FIsScent ( void ) -{ - if ( m_iType & ( bits_SOUND_CARCASS | bits_SOUND_MEAT | bits_SOUND_GARBAGE ) ) - { - return TRUE; - } - - return FALSE; -} - -//========================================================= -// Spawn -//========================================================= -void CSoundEnt :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - Initialize(); - - pev->nextthink = gpGlobals->time + 1; -} - -//========================================================= -// Think - at interval, the entire active sound list is checked -// for sounds that have ExpireTimes less than or equal -// to the current world time, and these sounds are deallocated. -//========================================================= -void CSoundEnt :: Think ( void ) -{ - int iSound; - int iPreviousSound; - - pev->nextthink = gpGlobals->time + 0.3;// how often to check the sound list. - - iPreviousSound = SOUNDLIST_EMPTY; - iSound = m_iActiveSound; - - while ( iSound != SOUNDLIST_EMPTY ) - { - if ( m_SoundPool[ iSound ].m_flExpireTime <= gpGlobals->time && m_SoundPool[ iSound ].m_flExpireTime != SOUND_NEVER_EXPIRE ) - { - int iNext = m_SoundPool[ iSound ].m_iNext; - - // move this sound back into the free list - FreeSound( iSound, iPreviousSound ); - - iSound = iNext; - } - else - { - iPreviousSound = iSound; - iSound = m_SoundPool[ iSound ].m_iNext; - } - } - - if ( m_fShowReport ) - { - ALERT ( at_aiconsole, "Soundlist: %d / %d (%d)\n", ISoundsInList( SOUNDLISTTYPE_ACTIVE ),ISoundsInList( SOUNDLISTTYPE_FREE ), ISoundsInList( SOUNDLISTTYPE_ACTIVE ) - m_cLastActiveSounds ); - m_cLastActiveSounds = ISoundsInList ( SOUNDLISTTYPE_ACTIVE ); - } - -} - -//========================================================= -// Precache - dummy function -//========================================================= -void CSoundEnt :: Precache ( void ) -{ -} - -//========================================================= -// FreeSound - clears the passed active sound and moves it -// to the top of the free list. TAKE CARE to only call this -// function for sounds in the Active list!! -//========================================================= -void CSoundEnt :: FreeSound ( int iSound, int iPrevious ) -{ - if ( !pSoundEnt ) - { - // no sound ent! - return; - } - - if ( iPrevious != SOUNDLIST_EMPTY ) - { - // iSound is not the head of the active list, so - // must fix the index for the Previous sound -// pSoundEnt->m_SoundPool[ iPrevious ].m_iNext = m_SoundPool[ iSound ].m_iNext; - pSoundEnt->m_SoundPool[ iPrevious ].m_iNext = pSoundEnt->m_SoundPool[ iSound ].m_iNext; - } - else - { - // the sound we're freeing IS the head of the active list. - pSoundEnt->m_iActiveSound = pSoundEnt->m_SoundPool [ iSound ].m_iNext; - } - - // make iSound the head of the Free list. - pSoundEnt->m_SoundPool[ iSound ].m_iNext = pSoundEnt->m_iFreeSound; - pSoundEnt->m_iFreeSound = iSound; -} - -//========================================================= -// IAllocSound - moves a sound from the Free list to the -// Active list returns the index of the alloc'd sound -//========================================================= -int CSoundEnt :: IAllocSound( void ) -{ - int iNewSound; - - if ( m_iFreeSound == SOUNDLIST_EMPTY ) - { - // no free sound! - ALERT ( at_console, "Free Sound List is full!\n" ); - return SOUNDLIST_EMPTY; - } - - // there is at least one sound available, so move it to the - // Active sound list, and return its SoundPool index. - - iNewSound = m_iFreeSound;// copy the index of the next free sound - - m_iFreeSound = m_SoundPool[ m_iFreeSound ].m_iNext;// move the index down into the free list. - - m_SoundPool[ iNewSound ].m_iNext = m_iActiveSound;// point the new sound at the top of the active list. - - m_iActiveSound = iNewSound;// now make the new sound the top of the active list. You're done. - - return iNewSound; -} - -//========================================================= -// InsertSound - Allocates a free sound and fills it with -// sound info. -//========================================================= -void CSoundEnt :: InsertSound ( int iType, const Vector &vecOrigin, int iVolume, float flDuration ) -{ - int iThisSound; - - if ( !pSoundEnt ) - { - // no sound ent! - return; - } - - iThisSound = pSoundEnt->IAllocSound(); - - if ( iThisSound == SOUNDLIST_EMPTY ) - { - ALERT ( at_console, "Could not AllocSound() for InsertSound() (DLL)\n" ); - return; - } - - pSoundEnt->m_SoundPool[ iThisSound ].m_vecOrigin = vecOrigin; - pSoundEnt->m_SoundPool[ iThisSound ].m_iType = iType; - pSoundEnt->m_SoundPool[ iThisSound ].m_iVolume = iVolume; - pSoundEnt->m_SoundPool[ iThisSound ].m_flExpireTime = gpGlobals->time + flDuration; -} - -//========================================================= -// Initialize - clears all sounds and moves them into the -// free sound list. -//========================================================= -void CSoundEnt :: Initialize ( void ) -{ - int i; - int iSound; - - m_cLastActiveSounds; - m_iFreeSound = 0; - m_iActiveSound = SOUNDLIST_EMPTY; - - for ( i = 0 ; i < MAX_WORLD_SOUNDS ; i++ ) - {// clear all sounds, and link them into the free sound list. - m_SoundPool[ i ].Clear(); - m_SoundPool[ i ].m_iNext = i + 1; - } - - m_SoundPool[ i - 1 ].m_iNext = SOUNDLIST_EMPTY;// terminate the list here. - - - // now reserve enough sounds for each client - for ( i = 0 ; i < gpGlobals->maxClients ; i++ ) - { - iSound = pSoundEnt->IAllocSound(); - - if ( iSound == SOUNDLIST_EMPTY ) - { - ALERT ( at_console, "Could not AllocSound() for Client Reserve! (DLL)\n" ); - return; - } - - pSoundEnt->m_SoundPool[ iSound ].m_flExpireTime = SOUND_NEVER_EXPIRE; - } - - if ( CVAR_GET_FLOAT("displaysoundlist") == 1 ) - { - m_fShowReport = TRUE; - } - else - { - m_fShowReport = FALSE; - } -} - -//========================================================= -// ISoundsInList - returns the number of sounds in the desired -// sound list. -//========================================================= -int CSoundEnt :: ISoundsInList ( int iListType ) -{ - int i; - int iThisSound; - - if ( iListType == SOUNDLISTTYPE_FREE ) - { - iThisSound = m_iFreeSound; - } - else if ( iListType == SOUNDLISTTYPE_ACTIVE ) - { - iThisSound = m_iActiveSound; - } - else - { - ALERT ( at_console, "Unknown Sound List Type!\n" ); - } - - if ( iThisSound == SOUNDLIST_EMPTY ) - { - return 0; - } - - i = 0; - - while ( iThisSound != SOUNDLIST_EMPTY ) - { - i++; - - iThisSound = m_SoundPool[ iThisSound ].m_iNext; - } - - return i; -} - -//========================================================= -// ActiveList - returns the head of the active sound list -//========================================================= -int CSoundEnt :: ActiveList ( void ) -{ - if ( !pSoundEnt ) - { - return SOUNDLIST_EMPTY; - } - - return pSoundEnt->m_iActiveSound; -} - -//========================================================= -// FreeList - returns the head of the free sound list -//========================================================= -int CSoundEnt :: FreeList ( void ) -{ - if ( !pSoundEnt ) - { - return SOUNDLIST_EMPTY; - } - - return pSoundEnt->m_iFreeSound; -} - -//========================================================= -// SoundPointerForIndex - returns a pointer to the instance -// of CSound at index's position in the sound pool. -//========================================================= -CSound* CSoundEnt :: SoundPointerForIndex( int iIndex ) -{ - if ( !pSoundEnt ) - { - return NULL; - } - - if ( iIndex > ( MAX_WORLD_SOUNDS - 1 ) ) - { - ALERT ( at_console, "SoundPointerForIndex() - Index too large!\n" ); - return NULL; - } - - if ( iIndex < 0 ) - { - ALERT ( at_console, "SoundPointerForIndex() - Index < 0!\n" ); - return NULL; - } - - return &pSoundEnt->m_SoundPool[ iIndex ]; -} - -//========================================================= -// Clients are numbered from 1 to MAXCLIENTS, but the client -// reserved sounds in the soundlist are from 0 to MAXCLIENTS - 1, -// so this function ensures that a client gets the proper index -// to his reserved sound in the soundlist. -//========================================================= -int CSoundEnt :: ClientSoundIndex ( edict_t *pClient ) -{ - int iReturn = ENTINDEX( pClient ) - 1; - -#ifdef _DEBUG - if ( iReturn < 0 || iReturn > gpGlobals->maxClients ) - { - ALERT ( at_console, "** ClientSoundIndex returning a bogus value! **\n" ); - } -#endif // _DEBUG - - return iReturn; -} \ No newline at end of file diff --git a/ricochet/dlls/soundent.h b/ricochet/dlls/soundent.h deleted file mode 100644 index 1967e97..0000000 --- a/ricochet/dlls/soundent.h +++ /dev/null @@ -1,95 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -//========================================================= -// Soundent.h - the entity that spawns when the world -// spawns, and handles the world's active and free sound -// lists. -//========================================================= - -#define MAX_WORLD_SOUNDS 64 // maximum number of sounds handled by the world at one time. - -#define bits_SOUND_NONE 0 -#define bits_SOUND_COMBAT ( 1 << 0 )// gunshots, explosions -#define bits_SOUND_WORLD ( 1 << 1 )// door opening/closing, glass breaking -#define bits_SOUND_PLAYER ( 1 << 2 )// all noises generated by player. walking, shooting, falling, splashing -#define bits_SOUND_CARCASS ( 1 << 3 )// dead body -#define bits_SOUND_MEAT ( 1 << 4 )// gib or pork chop -#define bits_SOUND_DANGER ( 1 << 5 )// pending danger. Grenade that is about to explode, explosive barrel that is damaged, falling crate -#define bits_SOUND_GARBAGE ( 1 << 6 )// trash cans, banana peels, old fast food bags. - -#define bits_ALL_SOUNDS 0xFFFFFFFF - -#define SOUNDLIST_EMPTY -1 - -#define SOUNDLISTTYPE_FREE 1// identifiers passed to functions that can operate on either list, to indicate which list to operate on. -#define SOUNDLISTTYPE_ACTIVE 2 - -#define SOUND_NEVER_EXPIRE -1 // with this set as a sound's ExpireTime, the sound will never expire. - -//========================================================= -// CSound - an instance of a sound in the world. -//========================================================= -class CSound -{ -public: - - void Clear ( void ); - void Reset ( void ); - - Vector m_vecOrigin; // sound's location in space - int m_iType; // what type of sound this is - int m_iVolume; // how loud the sound is - float m_flExpireTime; // when the sound should be purged from the list - int m_iNext; // index of next sound in this list ( Active or Free ) - int m_iNextAudible; // temporary link that monsters use to build a list of audible sounds - - BOOL FIsSound( void ); - BOOL FIsScent( void ); -}; - -//========================================================= -// CSoundEnt - a single instance of this entity spawns when -// the world spawns. The SoundEnt's job is to update the -// world's Free and Active sound lists. -//========================================================= -class CSoundEnt : public CBaseEntity -{ -public: - - void Precache ( void ); - void Spawn( void ); - void Think( void ); - void Initialize ( void ); - - static void InsertSound ( int iType, const Vector &vecOrigin, int iVolume, float flDuration ); - static void FreeSound ( int iSound, int iPrevious ); - static int ActiveList( void );// return the head of the active list - static int FreeList( void );// return the head of the free list - static CSound* SoundPointerForIndex( int iIndex );// return a pointer for this index in the sound list - static int ClientSoundIndex ( edict_t *pClient ); - - BOOL IsEmpty( void ) { return m_iActiveSound == SOUNDLIST_EMPTY; } - int ISoundsInList ( int iListType ); - int IAllocSound ( void ); - virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; } - - int m_iFreeSound; // index of the first sound in the free sound list - int m_iActiveSound; // indes of the first sound in the active sound list - int m_cLastActiveSounds; // keeps track of the number of active sounds at the last update. (for diagnostic work) - BOOL m_fShowReport; // if true, dump information about free/active sounds. - -private: - CSound m_SoundPool[ MAX_WORLD_SOUNDS ]; -}; diff --git a/ricochet/dlls/spectator.cpp b/ricochet/dlls/spectator.cpp deleted file mode 100644 index 7d7f4a8..0000000 --- a/ricochet/dlls/spectator.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// CBaseSpectator - -// YWB: UNDONE - -// Spectator functions -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "spectator.h" - -/* -=========== -SpectatorConnect - -called when a spectator connects to a server -============ -*/ -void CBaseSpectator::SpectatorConnect(void) -{ - pev->flags = FL_SPECTATOR; - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NOCLIP; - - m_pGoalEnt = NULL; -} - -/* -=========== -SpectatorDisconnect - -called when a spectator disconnects from a server -============ -*/ -void CBaseSpectator::SpectatorDisconnect(void) -{ -} - -/* -================ -SpectatorImpulseCommand - -Called by SpectatorThink if the spectator entered an impulse -================ -*/ -void CBaseSpectator::SpectatorImpulseCommand(void) -{ - static edict_t *pGoal = NULL; - edict_t *pPreviousGoal; - edict_t *pCurrentGoal; - BOOL bFound; - - switch (pev->impulse) - { - case 1: - // teleport the spectator to the next spawn point - // note that if the spectator is tracking, this doesn't do - // much - pPreviousGoal = pGoal; - pCurrentGoal = pGoal; - // Start at the current goal, skip the world, and stop if we looped - // back around - - bFound = FALSE; - while (1) - { - pCurrentGoal = FIND_ENTITY_BY_CLASSNAME(pCurrentGoal, "info_player_deathmatch"); - // Looped around, failure - if (pCurrentGoal == pPreviousGoal) - { - ALERT(at_console, "Could not find a spawn spot.\n"); - break; - } - // Found a non-world entity, set success, otherwise, look for the next one. - if (!FNullEnt(pCurrentGoal)) - { - bFound = TRUE; - break; - } - } - - if (!bFound) // Didn't find a good spot. - break; - - pGoal = pCurrentGoal; - UTIL_SetOrigin( pev, pGoal->v.origin ); - pev->angles = pGoal->v.angles; - pev->fixangle = FALSE; - break; - default: - ALERT(at_console, "Unknown spectator impulse\n"); - break; - } - - pev->impulse = 0; -} - -/* -================ -SpectatorThink - -Called every frame after physics are run -================ -*/ -void CBaseSpectator::SpectatorThink(void) -{ - if (!(pev->flags & FL_SPECTATOR)) - { - pev->flags = FL_SPECTATOR; - } - - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NOCLIP; - - if (pev->impulse) - SpectatorImpulseCommand(); -} - -/* -=========== -Spawn - - Called when spectator is initialized: - UNDONE: Is this actually being called because spectators are not allocated in normal fashion? -============ -*/ -void CBaseSpectator::Spawn() -{ - pev->flags = FL_SPECTATOR; - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NOCLIP; - - m_pGoalEnt = NULL; -} diff --git a/ricochet/dlls/spectator.h b/ricochet/dlls/spectator.h deleted file mode 100644 index cf27d0c..0000000 --- a/ricochet/dlls/spectator.h +++ /dev/null @@ -1,27 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// Spectator.h - -class CBaseSpectator : public CBaseEntity -{ -public: - void Spawn(); - void SpectatorConnect(void); - void SpectatorDisconnect(void); - void SpectatorThink(void); - -private: - void SpectatorImpulseCommand(void); -}; diff --git a/ricochet/dlls/subs.cpp b/ricochet/dlls/subs.cpp deleted file mode 100644 index b9cc133..0000000 --- a/ricochet/dlls/subs.cpp +++ /dev/null @@ -1,582 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== subs.cpp ======================================================== - - frequently used global functions - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include "nodes.h" -#include "doors.h" - -extern CGraph WorldGraph; - -extern BOOL FEntIsVisible(entvars_t* pev, entvars_t* pevTarget); - -extern DLL_GLOBAL int g_iSkillLevel; - - -// Landmark class -void CPointEntity :: Spawn( void ) -{ - pev->solid = SOLID_NOT; -// UTIL_SetSize(pev, g_vecZero, g_vecZero); -} - - -class CNullEntity : public CBaseEntity -{ -public: - void Spawn( void ); -}; - - -// Null Entity, remove on startup -void CNullEntity :: Spawn( void ) -{ - REMOVE_ENTITY(ENT(pev)); -} -LINK_ENTITY_TO_CLASS(info_null,CNullEntity); - -class CBaseDMStart : public CPointEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - BOOL IsTriggered( CBaseEntity *pEntity ); - -private: - int m_iPitch; -}; - -// These are the new entry points to entities. -LINK_ENTITY_TO_CLASS(info_player_deathmatch,CBaseDMStart); -LINK_ENTITY_TO_CLASS(info_player_start,CPointEntity); -LINK_ENTITY_TO_CLASS(info_player_spectator,CBaseDMStart); -LINK_ENTITY_TO_CLASS(info_landmark,CPointEntity); - -void CBaseDMStart::Spawn( void ) -{ - pev->angles.x = -m_iPitch; -} - -void CBaseDMStart::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "master")) - { - pev->netname = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "pitch")) - { - m_iPitch = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -BOOL CBaseDMStart::IsTriggered( CBaseEntity *pEntity ) -{ - BOOL master = UTIL_IsMasterTriggered( pev->netname, pEntity ); - - return master; -} - -// This updates global tables that need to know about entities being removed -void CBaseEntity::UpdateOnRemove( void ) -{ - int i; - - if ( FBitSet( pev->flags, FL_GRAPHED ) ) - { - // this entity was a LinkEnt in the world node graph, so we must remove it from - // the graph since we are removing it from the world. - for ( i = 0 ; i < WorldGraph.m_cLinks ; i++ ) - { - if ( WorldGraph.m_pLinkPool [ i ].m_pLinkEnt == pev ) - { - // if this link has a link ent which is the same ent that is removing itself, remove it! - WorldGraph.m_pLinkPool [ i ].m_pLinkEnt = NULL; - } - } - } - if ( pev->globalname ) - gGlobalState.EntitySetState( pev->globalname, GLOBAL_DEAD ); -} - -// Convenient way to delay removing oneself -void CBaseEntity :: SUB_Remove( void ) -{ - UpdateOnRemove(); - if (pev->health > 0) - { - // this situation can screw up monsters who can't tell their entity pointers are invalid. - pev->health = 0; - ALERT( at_aiconsole, "SUB_Remove called on entity with health > 0\n"); - } - - REMOVE_ENTITY(ENT(pev)); -} - - -// Convenient way to explicitly do nothing (passed to functions that require a method) -void CBaseEntity :: SUB_DoNothing( void ) -{ -} - - -// Global Savedata for Delay -TYPEDESCRIPTION CBaseDelay::m_SaveData[] = -{ - DEFINE_FIELD( CBaseDelay, m_flDelay, FIELD_FLOAT ), - DEFINE_FIELD( CBaseDelay, m_iszKillTarget, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE( CBaseDelay, CBaseEntity ); - -void CBaseDelay :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "delay")) - { - m_flDelay = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "killtarget")) - { - m_iszKillTarget = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - { - CBaseEntity::KeyValue( pkvd ); - } -} - - -/* -============================== -SUB_UseTargets - -If self.delay is set, a DelayedUse entity will be created that will actually -do the SUB_UseTargets after that many seconds have passed. - -Removes all entities with a targetname that match self.killtarget, -and removes them, so some events can remove other triggers. - -Search for (string)targetname in all entities that -match (string)self.target and call their .use function (if they have one) - -============================== -*/ -void CBaseEntity :: SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ) -{ - // - // fire targets - // - if (!FStringNull(pev->target)) - { - FireTargets( STRING(pev->target), pActivator, this, useType, value ); - } -} - - -void FireTargets( const char *targetName, CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - edict_t *pentTarget = NULL; - if ( !targetName ) - return; - - ALERT( at_aiconsole, "Firing: (%s)\n", targetName ); - - for (;;) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, targetName); - if (FNullEnt(pentTarget)) - break; - - CBaseEntity *pTarget = CBaseEntity::Instance( pentTarget ); - if ( pTarget && !(pTarget->pev->flags & FL_KILLME) ) // Don't use dying ents - { - ALERT( at_aiconsole, "Found: %s, firing (%s)\n", STRING(pTarget->pev->classname), targetName ); - - // Discwar: Only fire ents that are in the same groupinfo as the activator - if ( pActivator && pActivator->pev->groupinfo && pTarget->pev->groupinfo ) - { - if ( pActivator->pev->groupinfo & pTarget->pev->groupinfo ) - pTarget->Use( pActivator, pCaller, useType, value ); - } - else - { - pTarget->Use( pActivator, pCaller, useType, value ); - } - } - } -} - -LINK_ENTITY_TO_CLASS( DelayedUse, CBaseDelay ); - - -void CBaseDelay :: SUB_UseTargets( CBaseEntity *pActivator, USE_TYPE useType, float value ) -{ - // - // exit immediatly if we don't have a target or kill target - // - if (FStringNull(pev->target) && !m_iszKillTarget) - return; - - // - // check for a delay - // - if (m_flDelay != 0) - { - // create a temp object to fire at a later time - CBaseDelay *pTemp = GetClassPtr( (CBaseDelay *)NULL); - pTemp->pev->classname = MAKE_STRING("DelayedUse"); - - pTemp->pev->nextthink = gpGlobals->time + m_flDelay; - - pTemp->SetThink( &CBaseDelay::DelayThink ); - - // Save the useType - pTemp->pev->button = (int)useType; - pTemp->m_iszKillTarget = m_iszKillTarget; - pTemp->m_flDelay = 0; // prevent "recursion" - pTemp->pev->target = pev->target; - - // HACKHACK - // This wasn't in the release build of Half-Life. We should have moved m_hActivator into this class - // but changing member variable hierarchy would break save/restore without some ugly code. - // This code is not as ugly as that code - if ( pActivator && pActivator->IsPlayer() ) // If a player activates, then save it - { - pTemp->pev->owner = pActivator->edict(); - } - else - { - pTemp->pev->owner = NULL; - } - - return; - } - - // - // kill the killtargets - // - - if ( m_iszKillTarget ) - { - edict_t *pentKillTarget = NULL; - - ALERT( at_aiconsole, "KillTarget: %s\n", STRING(m_iszKillTarget) ); - pentKillTarget = FIND_ENTITY_BY_TARGETNAME( NULL, STRING(m_iszKillTarget) ); - while ( !FNullEnt(pentKillTarget) ) - { - UTIL_Remove( CBaseEntity::Instance(pentKillTarget) ); - - ALERT( at_aiconsole, "killing %s\n", STRING( pentKillTarget->v.classname ) ); - pentKillTarget = FIND_ENTITY_BY_TARGETNAME( pentKillTarget, STRING(m_iszKillTarget) ); - } - } - - // - // fire targets - // - if (!FStringNull(pev->target)) - { - FireTargets( STRING(pev->target), pActivator, this, useType, value ); - } -} - - -/* -void CBaseDelay :: SUB_UseTargetsEntMethod( void ) -{ - SUB_UseTargets(pev); -} -*/ - -/* -QuakeEd only writes a single float for angles (bad idea), so up and down are -just constant angles. -*/ -void SetMovedir( entvars_t *pev ) -{ - if (pev->angles == Vector(0, -1, 0)) - { - pev->movedir = Vector(0, 0, 1); - } - else if (pev->angles == Vector(0, -2, 0)) - { - pev->movedir = Vector(0, 0, -1); - } - else - { - UTIL_MakeVectors(pev->angles); - pev->movedir = gpGlobals->v_forward; - } - - pev->angles = g_vecZero; -} - - - - -void CBaseDelay::DelayThink( void ) -{ - CBaseEntity *pActivator = NULL; - - if ( pev->owner != NULL ) // A player activated this on delay - { - pActivator = CBaseEntity::Instance( pev->owner ); - } - // The use type is cached (and stashed) in pev->button - SUB_UseTargets( pActivator, (USE_TYPE)pev->button, 0 ); - REMOVE_ENTITY(ENT(pev)); -} - - -// Global Savedata for Toggle -TYPEDESCRIPTION CBaseToggle::m_SaveData[] = -{ - DEFINE_FIELD( CBaseToggle, m_toggle_state, FIELD_INTEGER ), - DEFINE_FIELD( CBaseToggle, m_flActivateFinished, FIELD_TIME ), - DEFINE_FIELD( CBaseToggle, m_flMoveDistance, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_flWait, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_flLip, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_flTWidth, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_flTLength, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_vecPosition1, FIELD_POSITION_VECTOR ), - DEFINE_FIELD( CBaseToggle, m_vecPosition2, FIELD_POSITION_VECTOR ), - DEFINE_FIELD( CBaseToggle, m_vecAngle1, FIELD_VECTOR ), // UNDONE: Position could go through transition, but also angle? - DEFINE_FIELD( CBaseToggle, m_vecAngle2, FIELD_VECTOR ), // UNDONE: Position could go through transition, but also angle? - DEFINE_FIELD( CBaseToggle, m_cTriggersLeft, FIELD_INTEGER ), - DEFINE_FIELD( CBaseToggle, m_flHeight, FIELD_FLOAT ), - DEFINE_FIELD( CBaseToggle, m_hActivator, FIELD_EHANDLE ), - DEFINE_FIELD( CBaseToggle, m_pfnCallWhenMoveDone, FIELD_FUNCTION ), - DEFINE_FIELD( CBaseToggle, m_vecFinalDest, FIELD_POSITION_VECTOR ), - DEFINE_FIELD( CBaseToggle, m_vecFinalAngle, FIELD_VECTOR ), - DEFINE_FIELD( CBaseToggle, m_sMaster, FIELD_STRING), - DEFINE_FIELD( CBaseToggle, m_bitsDamageInflict, FIELD_INTEGER ), // damage type inflicted -}; -IMPLEMENT_SAVERESTORE( CBaseToggle, CBaseAnimating ); - - -void CBaseToggle::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "lip")) - { - m_flLip = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "master")) - { - m_sMaster = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "distance")) - { - m_flMoveDistance = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - -/* -============= -LinearMove - -calculate pev->velocity and pev->nextthink to reach vecDest from -pev->origin traveling at flSpeed -=============== -*/ -void CBaseToggle :: LinearMove( Vector vecDest, float flSpeed ) -{ - ASSERTSZ(flSpeed != 0, "LinearMove: no speed is defined!"); -// ASSERTSZ(m_pfnCallWhenMoveDone != NULL, "LinearMove: no post-move function defined"); - - m_vecFinalDest = vecDest; - - // Already there? - if (vecDest == pev->origin) - { - LinearMoveDone(); - return; - } - - // set destdelta to the vector needed to move - Vector vecDestDelta = vecDest - pev->origin; - - // divide vector length by speed to get time to reach dest - float flTravelTime = vecDestDelta.Length() / flSpeed; - - // set nextthink to trigger a call to LinearMoveDone when dest is reached - pev->nextthink = pev->ltime + flTravelTime; - SetThink( &CBaseToggle::LinearMoveDone ); - - // scale the destdelta vector by the time spent traveling to get velocity - pev->velocity = vecDestDelta / flTravelTime; -} - - -/* -============ -After moving, set origin to exact final destination, call "move done" function -============ -*/ -void CBaseToggle :: LinearMoveDone( void ) -{ - UTIL_SetOrigin(pev, m_vecFinalDest); - pev->velocity = g_vecZero; - pev->nextthink = -1; - if ( m_pfnCallWhenMoveDone ) - (this->*m_pfnCallWhenMoveDone)(); -} - -BOOL CBaseToggle :: IsLockedByMaster( void ) -{ - if (m_sMaster && !UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) - return TRUE; - else - return FALSE; -} - -/* -============= -AngularMove - -calculate pev->velocity and pev->nextthink to reach vecDest from -pev->origin traveling at flSpeed -Just like LinearMove, but rotational. -=============== -*/ -void CBaseToggle :: AngularMove( Vector vecDestAngle, float flSpeed ) -{ - ASSERTSZ(flSpeed != 0, "AngularMove: no speed is defined!"); -// ASSERTSZ(m_pfnCallWhenMoveDone != NULL, "AngularMove: no post-move function defined"); - - m_vecFinalAngle = vecDestAngle; - - // Already there? - if (vecDestAngle == pev->angles) - { - AngularMoveDone(); - return; - } - - // set destdelta to the vector needed to move - Vector vecDestDelta = vecDestAngle - pev->angles; - - // divide by speed to get time to reach dest - float flTravelTime = vecDestDelta.Length() / flSpeed; - - // set nextthink to trigger a call to AngularMoveDone when dest is reached - pev->nextthink = pev->ltime + flTravelTime; - SetThink( &CBaseToggle::AngularMoveDone ); - - // scale the destdelta vector by the time spent traveling to get velocity - pev->avelocity = vecDestDelta / flTravelTime; -} - - -/* -============ -After rotating, set angle to exact final angle, call "move done" function -============ -*/ -void CBaseToggle :: AngularMoveDone( void ) -{ - pev->angles = m_vecFinalAngle; - pev->avelocity = g_vecZero; - pev->nextthink = -1; - if ( m_pfnCallWhenMoveDone ) - (this->*m_pfnCallWhenMoveDone)(); -} - - -float CBaseToggle :: AxisValue( int flags, const Vector &angles ) -{ - if ( FBitSet(flags, SF_DOOR_ROTATE_Z) ) - return angles.z; - if ( FBitSet(flags, SF_DOOR_ROTATE_X) ) - return angles.x; - - return angles.y; -} - - -void CBaseToggle :: AxisDir( entvars_t *pev ) -{ - if ( FBitSet(pev->spawnflags, SF_DOOR_ROTATE_Z) ) - pev->movedir = Vector ( 0, 0, 1 ); // around z-axis - else if ( FBitSet(pev->spawnflags, SF_DOOR_ROTATE_X) ) - pev->movedir = Vector ( 1, 0, 0 ); // around x-axis - else - pev->movedir = Vector ( 0, 1, 0 ); // around y-axis -} - - -float CBaseToggle :: AxisDelta( int flags, const Vector &angle1, const Vector &angle2 ) -{ - if ( FBitSet (flags, SF_DOOR_ROTATE_Z) ) - return angle1.z - angle2.z; - - if ( FBitSet (flags, SF_DOOR_ROTATE_X) ) - return angle1.x - angle2.x; - - return angle1.y - angle2.y; -} - - -/* -============= -FEntIsVisible - -returns TRUE if the passed entity is visible to caller, even if not infront () -============= -*/ - BOOL -FEntIsVisible( - entvars_t* pev, - entvars_t* pevTarget) - { - Vector vecSpot1 = pev->origin + pev->view_ofs; - Vector vecSpot2 = pevTarget->origin + pevTarget->view_ofs; - TraceResult tr; - - UTIL_TraceLine(vecSpot1, vecSpot2, ignore_monsters, ENT(pev), &tr); - - if (tr.fInOpen && tr.fInWater) - return FALSE; // sight line crossed contents - - if (tr.flFraction == 1) - return TRUE; - - return FALSE; - } - - diff --git a/ricochet/dlls/talkmonster.h b/ricochet/dlls/talkmonster.h deleted file mode 100644 index d8a92eb..0000000 --- a/ricochet/dlls/talkmonster.h +++ /dev/null @@ -1,26 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ - -#ifndef TALKMONSTER_H -#define TALKMONSTER_H - -class CTalkMonster : public CBaseMonster -{ -public: - static float g_talkWaitTime; - -}; - -#endif //TALKMONSTER_H diff --git a/ricochet/dlls/teamplay_gamerules.cpp b/ricochet/dlls/teamplay_gamerules.cpp deleted file mode 100644 index 60338e4..0000000 --- a/ricochet/dlls/teamplay_gamerules.cpp +++ /dev/null @@ -1,611 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// teamplay_gamerules.cpp -// -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" -#include "teamplay_gamerules.h" -#include "game.h" - -static char team_names[MAX_TEAMS][MAX_TEAMNAME_LENGTH]; -static int team_scores[MAX_TEAMS]; -static int num_teams = 0; - -extern DLL_GLOBAL BOOL g_fGameOver; - -CHalfLifeTeamplay :: CHalfLifeTeamplay() -{ - m_DisableDeathMessages = FALSE; - m_DisableDeathPenalty = FALSE; - - memset( team_names, 0, sizeof(team_names) ); - memset( team_scores, 0, sizeof(team_scores) ); - num_teams = 0; - - // Copy over the team from the server config - m_szTeamList[0] = 0; - - // Cache this because the team code doesn't want to deal with changing this in the middle of a game - strncpy( m_szTeamList, teamlist.string, TEAMPLAY_TEAMLISTLENGTH ); - - edict_t *pWorld = INDEXENT(0); - if ( pWorld && pWorld->v.team ) - { - if ( teamoverride.value ) - { - const char *pTeamList = STRING(pWorld->v.team); - if ( pTeamList && strlen(pTeamList) ) - { - strncpy( m_szTeamList, pTeamList, TEAMPLAY_TEAMLISTLENGTH ); - } - } - } - // Has the server set teams - if ( strlen( m_szTeamList ) ) - m_teamLimit = TRUE; - else - m_teamLimit = FALSE; - - RecountTeams(); -} - -extern cvar_t timeleft, fragsleft; - -#include "voice_gamemgr.h" -extern CVoiceGameMgr g_VoiceGameMgr; - -void CHalfLifeTeamplay :: Think ( void ) -{ - ///// Check game rules ///// - static int last_frags; - static int last_time; - - int frags_remaining = 0; - int time_remaining = 0; - - g_VoiceGameMgr.Update(gpGlobals->frametime); - - if ( g_fGameOver ) // someone else quit the game already - { - CHalfLifeMultiplay::Think(); - return; - } - - float flTimeLimit = CVAR_GET_FLOAT("mp_timelimit") * 60; - - time_remaining = (int)(flTimeLimit ? ( flTimeLimit - gpGlobals->time ) : 0); - - if ( flTimeLimit != 0 && gpGlobals->time >= flTimeLimit ) - { - GoToIntermission(); - return; - } - - float flFragLimit = fraglimit.value; - if ( flFragLimit ) - { - int bestfrags = 9999; - int remain; - - // check if any team is over the frag limit - for ( int i = 0; i < num_teams; i++ ) - { - if ( team_scores[i] >= flFragLimit ) - { - GoToIntermission(); - return; - } - - remain = flFragLimit - team_scores[i]; - if ( remain < bestfrags ) - { - bestfrags = remain; - } - } - frags_remaining = bestfrags; - } - - // Updates when frags change - if ( frags_remaining != last_frags ) - { - g_engfuncs.pfnCvar_DirectSet( &fragsleft, UTIL_VarArgs( "%i", frags_remaining ) ); - } - - // Updates once per second - if ( timeleft.value != last_time ) - { - g_engfuncs.pfnCvar_DirectSet( &timeleft, UTIL_VarArgs( "%i", time_remaining ) ); - } - - last_frags = frags_remaining; - last_time = time_remaining; -} - -//========================================================= -// ClientCommand -// the user has typed a command which is unrecognized by everything else; -// this check to see if the gamerules knows anything about the command -//========================================================= -BOOL CHalfLifeTeamplay :: ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) -{ - if(g_VoiceGameMgr.ClientCommand(pPlayer, pcmd)) - return TRUE; - - if ( FStrEq( pcmd, "menuselect" ) ) - { - if ( CMD_ARGC() < 2 ) - return TRUE; - - int slot = atoi( CMD_ARGV(1) ); - - // select the item from the current menu - - return TRUE; - } - - return FALSE; -} - -extern int gmsgGameMode; -extern int gmsgSayText; -extern int gmsgTeamInfo; - - -void CHalfLifeTeamplay :: UpdateGameMode( CBasePlayer *pPlayer ) -{ - MESSAGE_BEGIN( MSG_ONE, gmsgGameMode, NULL, pPlayer->edict() ); - WRITE_BYTE( 1 ); // game mode teamplay - MESSAGE_END(); -} - - -const char *CHalfLifeTeamplay::SetDefaultPlayerTeam( CBasePlayer *pPlayer ) -{ - // copy out the team name from the model - char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ); - strncpy( pPlayer->m_szTeamName, mdls, TEAM_NAME_LENGTH ); - - RecountTeams(); - - // update the current player of the team he is joining - if ( pPlayer->m_szTeamName[0] == '\0' || !IsValidTeam( pPlayer->m_szTeamName ) || defaultteam.value ) - { - const char *pTeamName = NULL; - - if ( defaultteam.value ) - { - pTeamName = team_names[0]; - } - else - { - pTeamName = TeamWithFewestPlayers(); - } - strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH ); - } - - return pPlayer->m_szTeamName; -} - - -//========================================================= -// InitHUD -//========================================================= -void CHalfLifeTeamplay::InitHUD( CBasePlayer *pPlayer ) -{ - SetDefaultPlayerTeam( pPlayer ); - CHalfLifeMultiplay::InitHUD( pPlayer ); - - RecountTeams(); - - char *mdls = g_engfuncs.pfnInfoKeyValue( g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model" ); - // update the current player of the team he is joining - char text[1024]; - if ( !strcmp( mdls, pPlayer->m_szTeamName ) ) - { - sprintf( text, "* you are on team \'%s\'\n", pPlayer->m_szTeamName ); - } - else - { - sprintf( text, "* assigned to team %s\n", pPlayer->m_szTeamName ); - } - - ChangePlayerTeam( pPlayer, pPlayer->m_szTeamName, FALSE, FALSE ); - UTIL_SayText( text, pPlayer ); - int clientIndex = pPlayer->entindex(); - RecountTeams(); - // update this player with all the other players team info - // loop through all active players and send their team info to the new client - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - if ( plr && IsValidTeam( plr->TeamID() ) ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgTeamInfo, NULL, pPlayer->edict() ); - WRITE_BYTE( plr->entindex() ); - WRITE_STRING( plr->TeamID() ); - MESSAGE_END(); - } - } -} - - -void CHalfLifeTeamplay::ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ) -{ - int damageFlags = DMG_GENERIC; - int clientIndex = pPlayer->entindex(); - - if ( !bGib ) - { - damageFlags |= DMG_NEVERGIB; - } - else - { - damageFlags |= DMG_ALWAYSGIB; - } - - if ( bKill ) - { - // kill the player, remove a death, and let them start on the new team - m_DisableDeathMessages = TRUE; - m_DisableDeathPenalty = TRUE; - - entvars_t *pevWorld = VARS( INDEXENT(0) ); - pPlayer->TakeDamage( pevWorld, pevWorld, 900, damageFlags ); - - m_DisableDeathMessages = FALSE; - m_DisableDeathPenalty = FALSE; - } - - // copy out the team name from the model - strncpy( pPlayer->m_szTeamName, pTeamName, TEAM_NAME_LENGTH ); - - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName ); - - // notify everyone's HUD of the team change - MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo ); - WRITE_BYTE( clientIndex ); - WRITE_STRING( pPlayer->m_szTeamName ); - MESSAGE_END(); -} - - -//========================================================= -// ClientUserInfoChanged -//========================================================= -void CHalfLifeTeamplay::ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ) -{ - char text[1024]; - - // prevent skin/color/model changes - char *mdls = g_engfuncs.pfnInfoKeyValue( infobuffer, "model" ); - - if ( !stricmp( mdls, pPlayer->m_szTeamName ) ) - return; - - if ( defaultteam.value ) - { - int clientIndex = pPlayer->entindex(); - - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "team", pPlayer->m_szTeamName ); - sprintf( text, "* Not allowed to change teams in this game!\n" ); - UTIL_SayText( text, pPlayer ); - return; - } - - if ( defaultteam.value || !IsValidTeam( mdls ) ) - { - int clientIndex = pPlayer->entindex(); - - g_engfuncs.pfnSetClientKeyValue( clientIndex, g_engfuncs.pfnGetInfoKeyBuffer( pPlayer->edict() ), "model", pPlayer->m_szTeamName ); - sprintf( text, "* Can't change team to \'%s\'\n", mdls ); - UTIL_SayText( text, pPlayer ); - sprintf( text, "* Server limits teams to \'%s\'\n", m_szTeamList ); - UTIL_SayText( text, pPlayer ); - return; - } - - // notify everyone of the team change - sprintf( text, "* %s has changed to team \'%s\'\n", STRING(pPlayer->pev->netname), mdls ); - UTIL_SayTextAll( text, pPlayer ); - - UTIL_LogPrintf( "\"%s<%i><%s><%s>\" joined team \"%s\"\n", - STRING(pPlayer->pev->netname), - GETPLAYERUSERID( pPlayer->edict() ), - GETPLAYERAUTHID( pPlayer->edict() ), - pPlayer->m_szTeamName, - mdls ); - - ChangePlayerTeam( pPlayer, mdls, TRUE, TRUE ); - // recound stuff - RecountTeams( TRUE ); -} - -extern int gmsgDeathMsg; - -//========================================================= -// Deathnotice. -//========================================================= -void CHalfLifeTeamplay::DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ) -{ - if ( m_DisableDeathMessages ) - return; - - if ( pVictim && pKiller && pKiller->flags & FL_CLIENT ) - { - CBasePlayer *pk = (CBasePlayer*) CBaseEntity::Instance( pKiller ); - - if ( pk ) - { - if ( (pk != pVictim) && (PlayerRelationship( pVictim, pk ) == GR_TEAMMATE) ) - { - MESSAGE_BEGIN( MSG_ALL, gmsgDeathMsg ); - WRITE_BYTE( ENTINDEX(ENT(pKiller)) ); // the killer - WRITE_BYTE( ENTINDEX(pVictim->edict()) ); // the victim - WRITE_STRING( "teammate" ); // flag this as a teammate kill - MESSAGE_END(); - return; - } - } - } - - CHalfLifeMultiplay::DeathNotice( pVictim, pKiller, pevInflictor ); -} - -//========================================================= -//========================================================= -void CHalfLifeTeamplay :: PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ) -{ - if ( !m_DisableDeathPenalty ) - { - CHalfLifeMultiplay::PlayerKilled( pVictim, pKiller, pInflictor ); - RecountTeams(); - } -} - - -//========================================================= -// IsTeamplay -//========================================================= -BOOL CHalfLifeTeamplay::IsTeamplay( void ) -{ - return TRUE; -} - -BOOL CHalfLifeTeamplay::FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ) -{ - if ( pAttacker && PlayerRelationship( pPlayer, pAttacker ) == GR_TEAMMATE ) - { - // my teammate hit me. - if ( (CVAR_GET_FLOAT("mp_friendlyfire") == 0) && (pAttacker != pPlayer) ) - { - // friendly fire is off, and this hit came from someone other than myself, then don't get hurt - return FALSE; - } - } - - return CHalfLifeMultiplay::FPlayerCanTakeDamage( pPlayer, pAttacker ); -} - -//========================================================= -//========================================================= -int CHalfLifeTeamplay::PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ) -{ - // half life multiplay has a simple concept of Player Relationships. - // you are either on another player's team, or you are not. - if ( !pPlayer || !pTarget || !pTarget->IsPlayer() ) - return GR_NOTTEAMMATE; - - if ( (*GetTeamID(pPlayer) != '\0') && (*GetTeamID(pTarget) != '\0') && !stricmp( GetTeamID(pPlayer), GetTeamID(pTarget) ) ) - { - return GR_TEAMMATE; - } - - return GR_NOTTEAMMATE; -} - -//========================================================= -//========================================================= -BOOL CHalfLifeTeamplay::ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ) -{ - // always autoaim, unless target is a teammate - CBaseEntity *pTgt = CBaseEntity::Instance( target ); - if ( pTgt && pTgt->IsPlayer() ) - { - if ( PlayerRelationship( pPlayer, pTgt ) == GR_TEAMMATE ) - return FALSE; // don't autoaim at teammates - } - - return CHalfLifeMultiplay::ShouldAutoAim( pPlayer, target ); -} - -//========================================================= -//========================================================= -int CHalfLifeTeamplay::IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ) -{ - if ( !pKilled ) - return 0; - - if ( !pAttacker ) - return 1; - - if ( pAttacker != pKilled && PlayerRelationship( pAttacker, pKilled ) == GR_TEAMMATE ) - return -1; - - return 1; -} - -//========================================================= -//========================================================= -const char *CHalfLifeTeamplay::GetTeamID( CBaseEntity *pEntity ) -{ - if ( pEntity == NULL || pEntity->pev == NULL ) - return ""; - - // return their team name - return pEntity->TeamID(); -} - - -int CHalfLifeTeamplay::GetTeamIndex( const char *pTeamName ) -{ - if ( pTeamName && *pTeamName != 0 ) - { - // try to find existing team - for ( int tm = 0; tm < num_teams; tm++ ) - { - if ( !stricmp( team_names[tm], pTeamName ) ) - return tm; - } - } - - return -1; // No match -} - - -const char *CHalfLifeTeamplay::GetIndexedTeamName( int teamIndex ) -{ - if ( teamIndex < 0 || teamIndex >= num_teams ) - return ""; - - return team_names[ teamIndex ]; -} - - -BOOL CHalfLifeTeamplay::IsValidTeam( const char *pTeamName ) -{ - if ( !m_teamLimit ) // Any team is valid if the teamlist isn't set - return TRUE; - - return ( GetTeamIndex( pTeamName ) != -1 ) ? TRUE : FALSE; -} - -const char *CHalfLifeTeamplay::TeamWithFewestPlayers( void ) -{ - int i; - int minPlayers = MAX_TEAMS; - int teamCount[ MAX_TEAMS ]; - char *pTeamName = NULL; - - memset( teamCount, 0, MAX_TEAMS * sizeof(int) ); - - // loop through all clients, count number of players on each team - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - - if ( plr ) - { - int team = GetTeamIndex( plr->TeamID() ); - if ( team >= 0 ) - teamCount[team] ++; - } - } - - // Find team with least players - for ( i = 0; i < num_teams; i++ ) - { - if ( teamCount[i] < minPlayers ) - { - minPlayers = teamCount[i]; - pTeamName = team_names[i]; - } - } - - return pTeamName; -} - - -//========================================================= -//========================================================= -void CHalfLifeTeamplay::RecountTeams( bool bResendInfo ) -{ - char *pName; - char teamlist[TEAMPLAY_TEAMLISTLENGTH]; - - // loop through all teams, recounting everything - num_teams = 0; - - // Copy all of the teams from the teamlist - // make a copy because strtok is destructive - strcpy( teamlist, m_szTeamList ); - pName = teamlist; - pName = strtok( pName, ";" ); - while ( pName != NULL && *pName ) - { - if ( GetTeamIndex( pName ) < 0 ) - { - strcpy( team_names[num_teams], pName ); - num_teams++; - } - pName = strtok( NULL, ";" ); - } - - if ( num_teams < 2 ) - { - num_teams = 0; - m_teamLimit = FALSE; - } - - // Sanity check - memset( team_scores, 0, sizeof(team_scores) ); - - // loop through all clients - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *plr = UTIL_PlayerByIndex( i ); - - if ( plr ) - { - const char *pTeamName = plr->TeamID(); - // try add to existing team - int tm = GetTeamIndex( pTeamName ); - - if ( tm < 0 ) // no team match found - { - if ( !m_teamLimit ) - { - // add to new team - tm = num_teams; - num_teams++; - team_scores[tm] = 0; - strncpy( team_names[tm], pTeamName, MAX_TEAMNAME_LENGTH ); - } - } - - if ( tm >= 0 ) - { - team_scores[tm] += plr->pev->frags; - } - - if ( bResendInfo ) //Someone's info changed, let's send the team info again. - { - if ( plr && IsValidTeam( plr->TeamID() ) ) - { - MESSAGE_BEGIN( MSG_ALL, gmsgTeamInfo, NULL ); - WRITE_BYTE( plr->entindex() ); - WRITE_STRING( plr->TeamID() ); - MESSAGE_END(); - } - } - } - } -} diff --git a/ricochet/dlls/teamplay_gamerules.h b/ricochet/dlls/teamplay_gamerules.h deleted file mode 100644 index 86d0814..0000000 --- a/ricochet/dlls/teamplay_gamerules.h +++ /dev/null @@ -1,57 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -// -// teamplay_gamerules.h -// - -#define MAX_TEAMNAME_LENGTH 16 -#define MAX_TEAMS 32 - -#define TEAMPLAY_TEAMLISTLENGTH MAX_TEAMS*MAX_TEAMNAME_LENGTH - -class CHalfLifeTeamplay : public CHalfLifeMultiplay -{ -public: - CHalfLifeTeamplay(); - - virtual BOOL ClientCommand( CBasePlayer *pPlayer, const char *pcmd ); - virtual void ClientUserInfoChanged( CBasePlayer *pPlayer, char *infobuffer ); - virtual BOOL IsTeamplay( void ); - virtual BOOL FPlayerCanTakeDamage( CBasePlayer *pPlayer, CBaseEntity *pAttacker ); - virtual int PlayerRelationship( CBaseEntity *pPlayer, CBaseEntity *pTarget ); - virtual const char *GetTeamID( CBaseEntity *pEntity ); - virtual BOOL ShouldAutoAim( CBasePlayer *pPlayer, edict_t *target ); - virtual int IPointsForKill( CBasePlayer *pAttacker, CBasePlayer *pKilled ); - virtual void InitHUD( CBasePlayer *pl ); - virtual void DeathNotice( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pevInflictor ); - virtual const char *GetGameDescription( void ) { return "HL Teamplay"; } // this is the game name that gets seen in the server browser - virtual void UpdateGameMode( CBasePlayer *pPlayer ); // the client needs to be informed of the current game mode - virtual void PlayerKilled( CBasePlayer *pVictim, entvars_t *pKiller, entvars_t *pInflictor ); - virtual void Think ( void ); - virtual int GetTeamIndex( const char *pTeamName ); - virtual const char *GetIndexedTeamName( int teamIndex ); - virtual BOOL IsValidTeam( const char *pTeamName ); - const char *SetDefaultPlayerTeam( CBasePlayer *pPlayer ); - virtual void ChangePlayerTeam( CBasePlayer *pPlayer, const char *pTeamName, BOOL bKill, BOOL bGib ); - -private: - void RecountTeams( bool bResendInfo = FALSE ); - const char *TeamWithFewestPlayers( void ); - - BOOL m_DisableDeathMessages; - BOOL m_DisableDeathPenalty; - BOOL m_teamLimit; // This means the server set only some teams as valid - char m_szTeamList[TEAMPLAY_TEAMLISTLENGTH]; -}; diff --git a/ricochet/dlls/trains.h b/ricochet/dlls/trains.h deleted file mode 100644 index 5912441..0000000 --- a/ricochet/dlls/trains.h +++ /dev/null @@ -1,127 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef TRAINS_H -#define TRAINS_H - -// Tracktrain spawn flags -#define SF_TRACKTRAIN_NOPITCH 0x0001 -#define SF_TRACKTRAIN_NOCONTROL 0x0002 -#define SF_TRACKTRAIN_FORWARDONLY 0x0004 -#define SF_TRACKTRAIN_PASSABLE 0x0008 - -// Spawnflag for CPathTrack -#define SF_PATH_DISABLED 0x00000001 -#define SF_PATH_FIREONCE 0x00000002 -#define SF_PATH_ALTREVERSE 0x00000004 -#define SF_PATH_DISABLE_TRAIN 0x00000008 -#define SF_PATH_ALTERNATE 0x00008000 - -// Spawnflags of CPathCorner -#define SF_CORNER_WAITFORTRIG 0x001 -#define SF_CORNER_TELEPORT 0x002 -#define SF_CORNER_FIREONCE 0x004 - -//#define PATH_SPARKLE_DEBUG 1 // This makes a particle effect around path_track entities for debugging -class CPathTrack : public CPointEntity -{ -public: - void Spawn( void ); - void Activate( void ); - void KeyValue( KeyValueData* pkvd); - - void SetPrevious( CPathTrack *pprevious ); - void Link( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - CPathTrack *ValidPath( CPathTrack *ppath, int testFlag ); // Returns ppath if enabled, NULL otherwise - void Project( CPathTrack *pstart, CPathTrack *pend, Vector *origin, float dist ); - - static CPathTrack *Instance( edict_t *pent ); - - CPathTrack *LookAhead( Vector *origin, float dist, int move ); - CPathTrack *Nearest( Vector origin ); - - CPathTrack *GetNext( void ); - CPathTrack *GetPrevious( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; -#if PATH_SPARKLE_DEBUG - void EXPORT Sparkle(void); -#endif - - float m_length; - string_t m_altName; - CPathTrack *m_pnext; - CPathTrack *m_pprevious; - CPathTrack *m_paltpath; -}; - - -class CFuncTrackTrain : public CBaseEntity -{ -public: - void Spawn( void ); - void Precache( void ); - - void Blocked( CBaseEntity *pOther ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void KeyValue( KeyValueData* pkvd ); - - void EXPORT Next( void ); - void EXPORT Find( void ); - void EXPORT NearestPath( void ); - void EXPORT DeadEnd( void ); - - void NextThink( float thinkTime, BOOL alwaysThink ); - - void SetTrack( CPathTrack *track ) { m_ppath = track->Nearest(pev->origin); } - void SetControls( entvars_t *pevControls ); - BOOL OnControls( entvars_t *pev ); - - void StopSound ( void ); - void UpdateSound ( void ); - - static CFuncTrackTrain *Instance( edict_t *pent ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - virtual int ObjectCaps( void ) { return (CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | FCAP_DIRECTIONAL_USE; } - - virtual void OverrideReset( void ); - - CPathTrack *m_ppath; - float m_length; - float m_height; - float m_speed; - float m_dir; - float m_startSpeed; - Vector m_controlMins; - Vector m_controlMaxs; - int m_soundPlaying; - int m_sounds; - float m_flVolume; - float m_flBank; - float m_oldSpeed; - -private: - unsigned short m_usAdjustPitch; -}; - -#endif diff --git a/ricochet/dlls/triggers.cpp b/ricochet/dlls/triggers.cpp deleted file mode 100644 index 8f275eb..0000000 --- a/ricochet/dlls/triggers.cpp +++ /dev/null @@ -1,2790 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== triggers.cpp ======================================================== - - spawn and use functions for editor-placed triggers - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "effects.h" -#include "player.h" -#include "saverestore.h" -#include "trains.h" // trigger_camera has train functionality -#include "gamerules.h" -#include "weapons.h" -#include "discwar.h" -#include "disc_arena.h" -#include "disc_objects.h" - -#define SF_TRIGGER_PUSH_START_OFF 2//spawnflag that makes trigger_push spawn turned OFF -#define SF_TRIGGER_HURT_TARGETONCE 1// Only fire hurt target once -#define SF_TRIGGER_HURT_START_OFF 2//spawnflag that makes trigger_push spawn turned OFF -#define SF_TRIGGER_HURT_NO_CLIENTS 8//spawnflag that makes trigger_push spawn turned OFF -#define SF_TRIGGER_HURT_CLIENTONLYFIRE 16// trigger hurt will only fire its target if it is hurting a client -#define SF_TRIGGER_HURT_CLIENTONLYTOUCH 32// only clients may touch this trigger. - -extern DLL_GLOBAL BOOL g_fGameOver; - -extern void SetMovedir(entvars_t* pev); -extern Vector VecBModelOrigin( entvars_t* pevBModel ); - -class CFrictionModifier : public CBaseEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT ChangeFriction( CBaseEntity *pOther ); - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - static TYPEDESCRIPTION m_SaveData[]; - - float m_frictionFraction; // Sorry, couldn't resist this name :) -}; - -LINK_ENTITY_TO_CLASS( func_friction, CFrictionModifier ); - -// Global Savedata for changelevel friction modifier -TYPEDESCRIPTION CFrictionModifier::m_SaveData[] = -{ - DEFINE_FIELD( CFrictionModifier, m_frictionFraction, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE(CFrictionModifier,CBaseEntity); - - -// Modify an entity's friction -void CFrictionModifier :: Spawn( void ) -{ - pev->solid = SOLID_TRIGGER; - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world - pev->movetype = MOVETYPE_NONE; - SetTouch( &CFrictionModifier::ChangeFriction ); -} - - -// Sets toucher's friction to m_frictionFraction (1.0 = normal friction) -void CFrictionModifier :: ChangeFriction( CBaseEntity *pOther ) -{ - if ( pOther->pev->movetype != MOVETYPE_BOUNCEMISSILE && pOther->pev->movetype != MOVETYPE_BOUNCE ) - pOther->pev->friction = m_frictionFraction; -} - - - -// Sets toucher's friction to m_frictionFraction (1.0 = normal friction) -void CFrictionModifier :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "modifier")) - { - m_frictionFraction = atof(pkvd->szValue) / 100.0; - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -// This trigger will fire when the level spawns (or respawns if not fire once) -// It will check a global state before firing. It supports delay and killtargets - -#define SF_AUTO_FIREONCE 0x0001 - -class CAutoTrigger : public CBaseDelay -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn( void ); - void Precache( void ); - void Think( void ); - - int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - int m_globalstate; - USE_TYPE triggerType; -}; -LINK_ENTITY_TO_CLASS( trigger_auto, CAutoTrigger ); - -TYPEDESCRIPTION CAutoTrigger::m_SaveData[] = -{ - DEFINE_FIELD( CAutoTrigger, m_globalstate, FIELD_STRING ), - DEFINE_FIELD( CAutoTrigger, triggerType, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE(CAutoTrigger,CBaseDelay); - -void CAutoTrigger::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "globalstate")) - { - m_globalstate = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "triggerstate")) - { - int type = atoi( pkvd->szValue ); - switch( type ) - { - case 0: - triggerType = USE_OFF; - break; - case 2: - triggerType = USE_TOGGLE; - break; - default: - triggerType = USE_ON; - break; - } - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - - -void CAutoTrigger::Spawn( void ) -{ - Precache(); -} - - -void CAutoTrigger::Precache( void ) -{ - pev->nextthink = gpGlobals->time + 0.1; -} - - -void CAutoTrigger::Think( void ) -{ - if ( !m_globalstate || gGlobalState.EntityGetState( m_globalstate ) == GLOBAL_ON ) - { - SUB_UseTargets( this, triggerType, 0 ); - if ( pev->spawnflags & SF_AUTO_FIREONCE ) - UTIL_Remove( this ); - } -} - - - -#define SF_RELAY_FIREONCE 0x0001 - -class CTriggerRelay : public CBaseDelay -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - USE_TYPE triggerType; -}; -LINK_ENTITY_TO_CLASS( trigger_relay, CTriggerRelay ); - -TYPEDESCRIPTION CTriggerRelay::m_SaveData[] = -{ - DEFINE_FIELD( CTriggerRelay, triggerType, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE(CTriggerRelay,CBaseDelay); - -void CTriggerRelay::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "triggerstate")) - { - int type = atoi( pkvd->szValue ); - switch( type ) - { - case 0: - triggerType = USE_OFF; - break; - case 2: - triggerType = USE_TOGGLE; - break; - default: - triggerType = USE_ON; - break; - } - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - - -void CTriggerRelay::Spawn( void ) -{ -} - - - - -void CTriggerRelay::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - SUB_UseTargets( this, triggerType, 0 ); - if ( pev->spawnflags & SF_RELAY_FIREONCE ) - UTIL_Remove( this ); -} - - -//********************************************************** -// The Multimanager Entity - when fired, will fire up to 16 targets -// at specified times. -// FLAG: THREAD (create clones when triggered) -// FLAG: CLONE (this is a clone for a threaded execution) - -#define SF_MULTIMAN_CLONE 0x80000000 -#define SF_MULTIMAN_THREAD 0x00000001 - -class CMultiManager : public CBaseToggle -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn ( void ); - void EXPORT ManagerThink ( void ); - void EXPORT ManagerUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - -#if _DEBUG - void EXPORT ManagerReport( void ); -#endif - - BOOL HasTarget( string_t targetname ); - - int ObjectCaps( void ) { return CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - int m_cTargets; // the total number of targets in this manager's fire list. - int m_index; // Current target - float m_startTime;// Time we started firing - int m_iTargetName [ MAX_MULTI_TARGETS ];// list if indexes into global string array - float m_flTargetDelay [ MAX_MULTI_TARGETS ];// delay (in seconds) from time of manager fire to target fire -private: - inline BOOL IsClone( void ) { return (pev->spawnflags & SF_MULTIMAN_CLONE) ? TRUE : FALSE; } - inline BOOL ShouldClone( void ) - { - if ( IsClone() ) - return FALSE; - - return (pev->spawnflags & SF_MULTIMAN_THREAD) ? TRUE : FALSE; - } - - CMultiManager *Clone( void ); -}; -LINK_ENTITY_TO_CLASS( multi_manager, CMultiManager ); - -// Global Savedata for multi_manager -TYPEDESCRIPTION CMultiManager::m_SaveData[] = -{ - DEFINE_FIELD( CMultiManager, m_cTargets, FIELD_INTEGER ), - DEFINE_FIELD( CMultiManager, m_index, FIELD_INTEGER ), - DEFINE_FIELD( CMultiManager, m_startTime, FIELD_TIME ), - DEFINE_ARRAY( CMultiManager, m_iTargetName, FIELD_STRING, MAX_MULTI_TARGETS ), - DEFINE_ARRAY( CMultiManager, m_flTargetDelay, FIELD_FLOAT, MAX_MULTI_TARGETS ), -}; - -IMPLEMENT_SAVERESTORE(CMultiManager,CBaseToggle); - -void CMultiManager :: KeyValue( KeyValueData *pkvd ) -{ - // UNDONE: Maybe this should do something like this: - //CBaseToggle::KeyValue( pkvd ); - // if ( !pkvd->fHandled ) - // ... etc. - - if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else // add this field to the target list - { - // this assumes that additional fields are targetnames and their values are delay values. - if ( m_cTargets < MAX_MULTI_TARGETS ) - { - char tmp[128]; - - UTIL_StripToken( pkvd->szKeyName, tmp ); - m_iTargetName [ m_cTargets ] = ALLOC_STRING( tmp ); - m_flTargetDelay [ m_cTargets ] = atof (pkvd->szValue); - m_cTargets++; - pkvd->fHandled = TRUE; - } - } -} - - -void CMultiManager :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - SetUse ( &CMultiManager::ManagerUse ); - SetThink ( &CMultiManager::ManagerThink); - - // Sort targets - // Quick and dirty bubble sort - int swapped = 1; - - while ( swapped ) - { - swapped = 0; - for ( int i = 1; i < m_cTargets; i++ ) - { - if ( m_flTargetDelay[i] < m_flTargetDelay[i-1] ) - { - // Swap out of order elements - int name = m_iTargetName[i]; - float delay = m_flTargetDelay[i]; - m_iTargetName[i] = m_iTargetName[i-1]; - m_flTargetDelay[i] = m_flTargetDelay[i-1]; - m_iTargetName[i-1] = name; - m_flTargetDelay[i-1] = delay; - swapped = 1; - } - } - } -} - - -BOOL CMultiManager::HasTarget( string_t targetname ) -{ - for ( int i = 0; i < m_cTargets; i++ ) - if ( FStrEq(STRING(targetname), STRING(m_iTargetName[i])) ) - return TRUE; - - return FALSE; -} - - -// Designers were using this to fire targets that may or may not exist -- -// so I changed it to use the standard target fire code, made it a little simpler. -void CMultiManager :: ManagerThink ( void ) -{ - float time; - - time = gpGlobals->time - m_startTime; - while ( m_index < m_cTargets && m_flTargetDelay[ m_index ] <= time ) - { - FireTargets( STRING( m_iTargetName[ m_index ] ), m_hActivator, this, USE_TOGGLE, 0 ); - m_index++; - } - - if ( m_index >= m_cTargets )// have we fired all targets? - { - SetThink( NULL ); - if ( IsClone() ) - { - UTIL_Remove( this ); - return; - } - SetUse ( &CMultiManager::ManagerUse );// allow manager re-use - } - else - pev->nextthink = m_startTime + m_flTargetDelay[ m_index ]; -} - -CMultiManager *CMultiManager::Clone( void ) -{ - CMultiManager *pMulti = GetClassPtr( (CMultiManager *)NULL ); - - edict_t *pEdict = pMulti->pev->pContainingEntity; - memcpy( pMulti->pev, pev, sizeof(*pev) ); - pMulti->pev->pContainingEntity = pEdict; - - pMulti->pev->spawnflags |= SF_MULTIMAN_CLONE; - pMulti->m_cTargets = m_cTargets; - memcpy( pMulti->m_iTargetName, m_iTargetName, sizeof( m_iTargetName ) ); - memcpy( pMulti->m_flTargetDelay, m_flTargetDelay, sizeof( m_flTargetDelay ) ); - - return pMulti; -} - - -// The USE function builds the time table and starts the entity thinking. -void CMultiManager :: ManagerUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // In multiplayer games, clone the MM and execute in the clone (like a thread) - // to allow multiple players to trigger the same multimanager - if ( ShouldClone() ) - { - CMultiManager *pClone = Clone(); - pClone->ManagerUse( pActivator, pCaller, useType, value ); - return; - } - - m_hActivator = pActivator; - m_index = 0; - m_startTime = gpGlobals->time; - - SetUse( NULL );// disable use until all targets have fired - - SetThink ( &CMultiManager::ManagerThink ); - pev->nextthink = gpGlobals->time; -} - -#if _DEBUG -void CMultiManager :: ManagerReport ( void ) -{ - int cIndex; - - for ( cIndex = 0 ; cIndex < m_cTargets ; cIndex++ ) - { - ALERT ( at_console, "%s %f\n", STRING(m_iTargetName[cIndex]), m_flTargetDelay[cIndex] ); - } -} -#endif - -//*********************************************************** - - -// -// Render parameters trigger -// -// This entity will copy its render parameters (renderfx, rendermode, rendercolor, renderamt) -// to its targets when triggered. -// - - -// Flags to indicate masking off various render parameters that are normally copied to the targets -#define SF_RENDER_MASKFX (1<<0) -#define SF_RENDER_MASKAMT (1<<1) -#define SF_RENDER_MASKMODE (1<<2) -#define SF_RENDER_MASKCOLOR (1<<3) - -class CRenderFxManager : public CBaseEntity -{ -public: - void Spawn( void ); - void Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); -}; - -LINK_ENTITY_TO_CLASS( env_render, CRenderFxManager ); - - -void CRenderFxManager :: Spawn ( void ) -{ - pev->solid = SOLID_NOT; -} - -void CRenderFxManager :: Use ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if (!FStringNull(pev->target)) - { - edict_t* pentTarget = NULL; - while ( 1 ) - { - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target)); - if (FNullEnt(pentTarget)) - break; - - entvars_t *pevTarget = VARS( pentTarget ); - if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKFX ) ) - pevTarget->renderfx = pev->renderfx; - if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKAMT ) ) - pevTarget->renderamt = pev->renderamt; - if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKMODE ) ) - pevTarget->rendermode = pev->rendermode; - if ( !FBitSet( pev->spawnflags, SF_RENDER_MASKCOLOR ) ) - pevTarget->rendercolor = pev->rendercolor; - } - } -} - - - -LINK_ENTITY_TO_CLASS( trigger, CBaseTrigger ); - -/* -================ -InitTrigger -================ -*/ -void CBaseTrigger::InitTrigger( ) -{ - // trigger angles are used for one-way touches. An angle of 0 is assumed - // to mean no restrictions, so use a yaw of 360 instead. - if (pev->angles != g_vecZero) - SetMovedir(pev); - pev->solid = SOLID_TRIGGER; - pev->movetype = MOVETYPE_NONE; - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world - if ( CVAR_GET_FLOAT("showtriggers") == 0 ) - SetBits( pev->effects, EF_NODRAW ); -} - - -// -// Cache user-entity-field values until spawn is called. -// - -void CBaseTrigger :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "damage")) - { - pev->dmg = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "count")) - { - m_cTriggersLeft = (int) atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "damagetype")) - { - m_bitsDamageInflict = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseToggle::KeyValue( pkvd ); -} - -class CTriggerHurt : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT RadiationThink( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_hurt, CTriggerHurt ); - -// -// trigger_monsterjump -// -class CTriggerMonsterJump : public CBaseTrigger -{ -public: - void Spawn( void ); - void Touch( CBaseEntity *pOther ); - void Think( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_monsterjump, CTriggerMonsterJump ); - - -void CTriggerMonsterJump :: Spawn ( void ) -{ - SetMovedir ( pev ); - - InitTrigger (); - - pev->nextthink = 0; - pev->speed = 200; - m_flHeight = 150; - - if ( !FStringNull ( pev->targetname ) ) - {// if targetted, spawn turned off - pev->solid = SOLID_NOT; - UTIL_SetOrigin( pev, pev->origin ); // Unlink from trigger list - SetUse( &CTriggerMonsterJump::ToggleUse ); - } -} - - -void CTriggerMonsterJump :: Think( void ) -{ - pev->solid = SOLID_NOT;// kill the trigger for now !!!UNDONE - UTIL_SetOrigin( pev, pev->origin ); // Unlink from trigger list - SetThink( NULL ); -} - -void CTriggerMonsterJump :: Touch( CBaseEntity *pOther ) -{ - entvars_t *pevOther = pOther->pev; - - if ( !FBitSet ( pevOther->flags , FL_MONSTER ) ) - {// touched by a non-monster. - return; - } - - pevOther->origin.z += 1; - - if ( FBitSet ( pevOther->flags, FL_ONGROUND ) ) - {// clear the onground so physics don't bitch - pevOther->flags &= ~FL_ONGROUND; - } - - // toss the monster! - pevOther->velocity = pev->movedir * pev->speed; - pevOther->velocity.z += m_flHeight; - pev->nextthink = gpGlobals->time; -} - - -//===================================== -// -// trigger_cdaudio - starts/stops cd audio tracks -// -class CTriggerCDAudio : public CBaseTrigger -{ -public: - void Spawn( void ); - - virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void PlayTrack( void ); - void Touch ( CBaseEntity *pOther ); -}; - -LINK_ENTITY_TO_CLASS( trigger_cdaudio, CTriggerCDAudio ); - -// -// Changes tracks or stops CD when player touches -// -// !!!HACK - overloaded HEALTH to avoid adding new field -void CTriggerCDAudio :: Touch ( CBaseEntity *pOther ) -{ - if ( !pOther->IsPlayer() ) - {// only clients may trigger these events - return; - } - - PlayTrack(); -} - -void CTriggerCDAudio :: Spawn( void ) -{ - InitTrigger(); -} - -void CTriggerCDAudio::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - PlayTrack(); -} - -void PlayCDTrack( int iTrack ) -{ - edict_t *pClient; - - // manually find the single player. - pClient = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - - // Can't play if the client is not connected! - if ( !pClient ) - return; - - if ( iTrack < -1 || iTrack > 30 ) - { - ALERT ( at_console, "TriggerCDAudio - Track %d out of range\n" ); - return; - } - - if ( iTrack == -1 ) - { - CLIENT_COMMAND ( pClient, "cd stop\n"); - } - else - { - char string [ 64 ]; - - sprintf( string, "cd play %3d\n", iTrack ); - CLIENT_COMMAND ( pClient, string); - } -} - - -// only plays for ONE client, so only use in single play! -void CTriggerCDAudio :: PlayTrack( void ) -{ - PlayCDTrack( (int)pev->health ); - - SetTouch( NULL ); - UTIL_Remove( this ); -} - - -// This plays a CD track when fired or when the player enters it's radius -class CTargetCDAudio : public CPointEntity -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - - virtual void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void Think( void ); - void Play( void ); -}; - -LINK_ENTITY_TO_CLASS( target_cdaudio, CTargetCDAudio ); - -void CTargetCDAudio :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "radius")) - { - pev->scale = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CPointEntity::KeyValue( pkvd ); -} - -void CTargetCDAudio :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - - if ( pev->scale > 0 ) - pev->nextthink = gpGlobals->time + 1.0; -} - -void CTargetCDAudio::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - Play(); -} - -// only plays for ONE client, so only use in single play! -void CTargetCDAudio::Think( void ) -{ - edict_t *pClient; - - // manually find the single player. - pClient = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - - // Can't play if the client is not connected! - if ( !pClient ) - return; - - pev->nextthink = gpGlobals->time + 0.5; - - if ( (pClient->v.origin - pev->origin).Length() <= pev->scale ) - Play(); - -} - -void CTargetCDAudio::Play( void ) -{ - PlayCDTrack( (int)pev->health ); - UTIL_Remove(this); -} - -//===================================== - -// -// trigger_hurt - hurts anything that touches it. if the trigger has a targetname, firing it will toggle state -// -//int gfToggleState = 0; // used to determine when all radiation trigger hurts have called 'RadiationThink' - -void CTriggerHurt :: Spawn( void ) -{ - InitTrigger(); - SetTouch ( &CTriggerHurt::HurtTouch ); - - if ( !FStringNull ( pev->targetname ) ) - { - SetUse ( &CTriggerHurt::ToggleUse ); - } - else - { - SetUse ( NULL ); - } - - if (m_bitsDamageInflict & DMG_RADIATION) - { - SetThink ( &CTriggerHurt::RadiationThink ); - pev->nextthink = gpGlobals->time + RANDOM_FLOAT(0.0, 0.5); - } - - if ( FBitSet (pev->spawnflags, SF_TRIGGER_HURT_START_OFF) )// if flagged to Start Turned Off, make trigger nonsolid. - pev->solid = SOLID_NOT; - - UTIL_SetOrigin( pev, pev->origin ); // Link into the list -} - -// trigger hurt that causes radiation will do a radius -// check and set the player's geiger counter level -// according to distance from center of trigger - -void CTriggerHurt :: RadiationThink( void ) -{ - - edict_t *pentPlayer; - CBasePlayer *pPlayer = NULL; - float flRange; - entvars_t *pevTarget; - Vector vecSpot1; - Vector vecSpot2; - Vector vecRange; - Vector origin; - Vector view_ofs; - - // check to see if a player is in pvs - // if not, continue - - // set origin to center of trigger so that this check works - origin = pev->origin; - view_ofs = pev->view_ofs; - - pev->origin = (pev->absmin + pev->absmax) * 0.5; - pev->view_ofs = pev->view_ofs * 0.0; - - pentPlayer = FIND_CLIENT_IN_PVS(edict()); - - pev->origin = origin; - pev->view_ofs = view_ofs; - - // reset origin - - if (!FNullEnt(pentPlayer)) - { - - pPlayer = GetClassPtr( (CBasePlayer *)VARS(pentPlayer)); - - pevTarget = VARS(pentPlayer); - - // get range to player; - - vecSpot1 = (pev->absmin + pev->absmax) * 0.5; - vecSpot2 = (pevTarget->absmin + pevTarget->absmax) * 0.5; - - vecRange = vecSpot1 - vecSpot2; - flRange = vecRange.Length(); - - // if player's current geiger counter range is larger - // than range to this trigger hurt, reset player's - // geiger counter range - - if (pPlayer->m_flgeigerRange >= flRange) - pPlayer->m_flgeigerRange = flRange; - } - - pev->nextthink = gpGlobals->time + 0.25; -} - -// -// ToggleUse - If this is the USE function for a trigger, its state will toggle every time it's fired -// -void CBaseTrigger :: ToggleUse ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if (pev->solid == SOLID_NOT) - {// if the trigger is off, turn it on - pev->solid = SOLID_TRIGGER; - - // Force retouch - gpGlobals->force_retouch++; - } - else - {// turn the trigger off - pev->solid = SOLID_NOT; - } - UTIL_SetOrigin( pev, pev->origin ); -} - -// When touched, a hurt trigger does DMG points of damage each half-second -void CBaseTrigger :: HurtTouch ( CBaseEntity *pOther ) -{ - float fldmg; - - if ( !pOther->pev->takedamage || pOther->IsAlive() == false ) - return; - - if ( (pev->spawnflags & SF_TRIGGER_HURT_CLIENTONLYTOUCH) && !pOther->IsPlayer() ) - { - // this trigger is only allowed to touch clients, and this ain't a client. - return; - } - - if ( (pev->spawnflags & SF_TRIGGER_HURT_NO_CLIENTS) && pOther->IsPlayer() ) - return; - - // HACKHACK -- In multiplayer, players touch this based on packet receipt. - // So the players who send packets later aren't always hurt. Keep track of - // how much time has passed and whether or not you've touched that player - if ( g_pGameRules->IsMultiplayer() ) - { - if ( pev->dmgtime > gpGlobals->time ) - { - if ( gpGlobals->time != pev->pain_finished ) - {// too early to hurt again, and not same frame with a different entity - if ( pOther->IsPlayer() ) - { - int playerMask = 1 << (pOther->entindex() - 1); - - // If I've already touched this player (this time), then bail out - if ( pev->impulse & playerMask ) - return; - - // Mark this player as touched - // BUGBUG - There can be only 32 players! - pev->impulse |= playerMask; - } - else - { - return; - } - } - } - else - { - // New clock, "un-touch" all players - pev->impulse = 0; - if ( pOther->IsPlayer() ) - { - int playerMask = 1 << (pOther->entindex() - 1); - - // Mark this player as touched - // BUGBUG - There can be only 32 players! - pev->impulse |= playerMask; - } - } - } - else // Original code -- single player - { - if ( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->pain_finished ) - {// too early to hurt again, and not same frame with a different entity - return; - } - } - - - - // If this is time_based damage (poison, radiation), override the pev->dmg with a - // default for the given damage type. Monsters only take time-based damage - // while touching the trigger. Player continues taking damage for a while after - // leaving the trigger - - fldmg = pev->dmg * 0.5; // 0.5 seconds worth of damage, pev->dmg is damage/second - - - // JAY: Cut this because it wasn't fully realized. Damage is simpler now. -#if 0 - switch (m_bitsDamageInflict) - { - default: break; - case DMG_POISON: fldmg = POISON_DAMAGE/4; break; - case DMG_NERVEGAS: fldmg = NERVEGAS_DAMAGE/4; break; - case DMG_RADIATION: fldmg = RADIATION_DAMAGE/4; break; - case DMG_PARALYZE: fldmg = PARALYZE_DAMAGE/4; break; // UNDONE: cut this? should slow movement to 50% - case DMG_ACID: fldmg = ACID_DAMAGE/4; break; - case DMG_SLOWBURN: fldmg = SLOWBURN_DAMAGE/4; break; - case DMG_SLOWFREEZE: fldmg = SLOWFREEZE_DAMAGE/4; break; - } -#endif - - if ( fldmg < 0 ) - pOther->TakeHealth( -fldmg, m_bitsDamageInflict ); - else - pOther->TakeDamage( pev, pev, fldmg, m_bitsDamageInflict ); - - // Store pain time so we can get all of the other entities on this frame - pev->pain_finished = gpGlobals->time; - - // Apply damage every half second - pev->dmgtime = gpGlobals->time + 0.5;// half second delay until this trigger can hurt toucher again - - - - if ( pev->target ) - { - // trigger has a target it wants to fire. - if ( pev->spawnflags & SF_TRIGGER_HURT_CLIENTONLYFIRE ) - { - // if the toucher isn't a client, don't fire the target! - if ( !pOther->IsPlayer() ) - { - return; - } - } - - SUB_UseTargets( pOther, USE_TOGGLE, 0 ); - if ( pev->spawnflags & SF_TRIGGER_HURT_TARGETONCE ) - pev->target = 0; - } -} - - -/*QUAKED trigger_multiple (.5 .5 .5) ? notouch -Variable sized repeatable trigger. Must be targeted at one or more entities. -If "health" is set, the trigger must be killed to activate each time. -If "delay" is set, the trigger waits some time after activating before firing. -"wait" : Seconds between triggerings. (.2 default) -If notouch is set, the trigger is only fired by other entities, not by touching. -NOTOUCH has been obsoleted by trigger_relay! -sounds -1) secret -2) beep beep -3) large switch -4) -NEW -if a trigger has a NETNAME, that NETNAME will become the TARGET of the triggered object. -*/ -class CTriggerMultiple : public CBaseTrigger -{ -public: - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_multiple, CTriggerMultiple ); - - -void CTriggerMultiple :: Spawn( void ) -{ - if (m_flWait == 0) - m_flWait = 0.2; - - InitTrigger(); - - ASSERTSZ(pev->health == 0, "trigger_multiple with health"); -// UTIL_SetOrigin(pev, pev->origin); -// SET_MODEL( ENT(pev), STRING(pev->model) ); -// if (pev->health > 0) -// { -// if (FBitSet(pev->spawnflags, SPAWNFLAG_NOTOUCH)) -// ALERT(at_error, "trigger_multiple spawn: health and notouch don't make sense"); -// pev->max_health = pev->health; -//UNDONE: where to get pfnDie from? -// pev->pfnDie = multi_killed; -// pev->takedamage = DAMAGE_YES; -// pev->solid = SOLID_BBOX; -// UTIL_SetOrigin(pev, pev->origin); // make sure it links into the world -// } -// else - { - SetTouch( &CTriggerMultiple::MultiTouch ); - } - } - - -/*QUAKED trigger_once (.5 .5 .5) ? notouch -Variable sized trigger. Triggers once, then removes itself. You must set the key "target" to the name of another object in the level that has a matching -"targetname". If "health" is set, the trigger must be killed to activate. -If notouch is set, the trigger is only fired by other entities, not by touching. -if "killtarget" is set, any objects that have a matching "target" will be removed when the trigger is fired. -if "angle" is set, the trigger will only fire when someone is facing the direction of the angle. Use "360" for an angle of 0. -sounds -1) secret -2) beep beep -3) large switch -4) -*/ -class CTriggerOnce : public CTriggerMultiple -{ -public: - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_once, CTriggerOnce ); -void CTriggerOnce::Spawn( void ) -{ - m_flWait = -1; - - CTriggerMultiple :: Spawn(); -} - - - -void CBaseTrigger :: MultiTouch( CBaseEntity *pOther ) -{ - entvars_t *pevToucher; - - pevToucher = pOther->pev; - - // Only touch clients, monsters, or pushables (depending on flags) - if ( ((pevToucher->flags & FL_CLIENT) && !(pev->spawnflags & SF_TRIGGER_NOCLIENTS)) || - ((pevToucher->flags & FL_MONSTER) && (pev->spawnflags & SF_TRIGGER_ALLOWMONSTERS)) || - (pev->spawnflags & SF_TRIGGER_PUSHABLES) && FClassnameIs(pevToucher,"func_pushable") ) - { - -#if 0 - // if the trigger has an angles field, check player's facing direction - if (pev->movedir != g_vecZero) - { - UTIL_MakeVectors( pevToucher->angles ); - if ( DotProduct( gpGlobals->v_forward, pev->movedir ) < 0 ) - return; // not facing the right way - } -#endif - - ActivateMultiTrigger( pOther ); - } -} - - -// -// the trigger was just touched/killed/used -// self.enemy should be set to the activator so it can be held through a delay -// so wait for the delay time before firing -// -void CBaseTrigger :: ActivateMultiTrigger( CBaseEntity *pActivator ) -{ - if (pev->nextthink > gpGlobals->time) - return; // still waiting for reset time - - if (!UTIL_IsMasterTriggered(m_sMaster,pActivator)) - return; - - if (FClassnameIs(pev, "trigger_secret")) - { - if ( pev->enemy == NULL || !FClassnameIs(pev->enemy, "player")) - return; - gpGlobals->found_secrets++; - } - - if (!FStringNull(pev->noise)) - EMIT_SOUND(ENT(pev), CHAN_VOICE, (char*)STRING(pev->noise), 1, ATTN_NORM); - -// don't trigger again until reset -// pev->takedamage = DAMAGE_NO; - - m_hActivator = pActivator; - SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); - - if ( pev->message && pActivator->IsPlayer() ) - { - UTIL_ShowMessage( STRING(pev->message), pActivator ); -// CLIENT_PRINTF( ENT( pActivator->pev ), print_center, STRING(pev->message) ); - } - - if (m_flWait > 0) - { - SetThink( &CBaseTrigger::MultiWaitOver ); - pev->nextthink = gpGlobals->time + m_flWait; - } - else - { - // we can't just remove (self) here, because this is a touch function - // called while C code is looping through area links... - SetTouch( NULL ); - pev->nextthink = gpGlobals->time + 0.1; - SetThink( &CBaseTrigger::SUB_Remove ); - } -} - - -// the wait time has passed, so set back up for another activation -void CBaseTrigger :: MultiWaitOver( void ) -{ -// if (pev->max_health) -// { -// pev->health = pev->max_health; -// pev->takedamage = DAMAGE_YES; -// pev->solid = SOLID_BBOX; -// } - SetThink( NULL ); -} - - -// ========================= COUNTING TRIGGER ===================================== - -// -// GLOBALS ASSUMED SET: g_eoActivator -// -void CBaseTrigger::CounterUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - m_cTriggersLeft--; - m_hActivator = pActivator; - - if (m_cTriggersLeft < 0) - return; - - BOOL fTellActivator = - (m_hActivator != 0) && - FClassnameIs(m_hActivator->pev, "player") && - !FBitSet(pev->spawnflags, SPAWNFLAG_NOMESSAGE); - if (m_cTriggersLeft != 0) - { - if (fTellActivator) - { - // UNDONE: I don't think we want these Quakesque messages - switch (m_cTriggersLeft) - { - case 1: ALERT(at_console, "Only 1 more to go..."); break; - case 2: ALERT(at_console, "Only 2 more to go..."); break; - case 3: ALERT(at_console, "Only 3 more to go..."); break; - default: ALERT(at_console, "There are more to go..."); break; - } - } - return; - } - - // !!!UNDONE: I don't think we want these Quakesque messages - if (fTellActivator) - ALERT(at_console, "Sequence completed!"); - - ActivateMultiTrigger( m_hActivator ); -} - - -/*QUAKED trigger_counter (.5 .5 .5) ? nomessage -Acts as an intermediary for an action that takes multiple inputs. -If nomessage is not set, it will print "1 more.. " etc when triggered and -"sequence complete" when finished. After the counter has been triggered "cTriggersLeft" -times (default 2), it will fire all of it's targets and remove itself. -*/ -class CTriggerCounter : public CBaseTrigger -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS( trigger_counter, CTriggerCounter ); - -void CTriggerCounter :: Spawn( void ) -{ - // By making the flWait be -1, this counter-trigger will disappear after it's activated - // (but of course it needs cTriggersLeft "uses" before that happens). - m_flWait = -1; - - if (m_cTriggersLeft == 0) - m_cTriggersLeft = 2; - SetUse( &CTriggerCounter::CounterUse ); -} - -// ====================== TRIGGER_CHANGELEVEL ================================ - -class CTriggerVolume : public CPointEntity // Derive from point entity so this doesn't move across levels -{ -public: - void Spawn( void ); -}; - -LINK_ENTITY_TO_CLASS( trigger_transition, CTriggerVolume ); - -// Define space that travels across a level transition -void CTriggerVolume :: Spawn( void ) -{ - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world - pev->model = NULL; - pev->modelindex = 0; -} - - -// Fires a target after level transition and then dies -class CFireAndDie : public CBaseDelay -{ -public: - void Spawn( void ); - void Precache( void ); - void Think( void ); - int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() | FCAP_FORCE_TRANSITION; } // Always go across transitions -}; -LINK_ENTITY_TO_CLASS( fireanddie, CFireAndDie ); - -void CFireAndDie::Spawn( void ) -{ - pev->classname = MAKE_STRING("fireanddie"); - // Don't call Precache() - it should be called on restore -} - - -void CFireAndDie::Precache( void ) -{ - // This gets called on restore - pev->nextthink = gpGlobals->time + m_flDelay; -} - - -void CFireAndDie::Think( void ) -{ - SUB_UseTargets( this, USE_TOGGLE, 0 ); - UTIL_Remove( this ); -} - - -#define SF_CHANGELEVEL_USEONLY 0x0002 -class CChangeLevel : public CBaseTrigger -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT UseChangeLevel ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT TriggerChangeLevel( void ); - void EXPORT ExecuteChangeLevel( void ); - void EXPORT TouchChangeLevel( CBaseEntity *pOther ); - void ChangeLevelNow( CBaseEntity *pActivator ); - - static edict_t *FindLandmark( const char *pLandmarkName ); - static int ChangeList( LEVELLIST *pLevelList, int maxList ); - static int AddTransitionToList( LEVELLIST *pLevelList, int listCount, const char *pMapName, const char *pLandmarkName, edict_t *pentLandmark ); - static int InTransitionVolume( CBaseEntity *pEntity, char *pVolumeName ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - - char m_szMapName[cchMapNameMost]; // trigger_changelevel only: next map - char m_szLandmarkName[cchMapNameMost]; // trigger_changelevel only: landmark on next map - int m_changeTarget; - float m_changeTargetDelay; -}; -LINK_ENTITY_TO_CLASS( trigger_changelevel, CChangeLevel ); - -// Global Savedata for changelevel trigger -TYPEDESCRIPTION CChangeLevel::m_SaveData[] = -{ - DEFINE_ARRAY( CChangeLevel, m_szMapName, FIELD_CHARACTER, cchMapNameMost ), - DEFINE_ARRAY( CChangeLevel, m_szLandmarkName, FIELD_CHARACTER, cchMapNameMost ), - DEFINE_FIELD( CChangeLevel, m_changeTarget, FIELD_STRING ), - DEFINE_FIELD( CChangeLevel, m_changeTargetDelay, FIELD_FLOAT ), -}; - -IMPLEMENT_SAVERESTORE(CChangeLevel,CBaseTrigger); - -// -// Cache user-entity-field values until spawn is called. -// - -void CChangeLevel :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "map")) - { - if (strlen(pkvd->szValue) >= cchMapNameMost) - ALERT( at_error, "Map name '%s' too long (32 chars)\n", pkvd->szValue ); - strcpy(m_szMapName, pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "landmark")) - { - if (strlen(pkvd->szValue) >= cchMapNameMost) - ALERT( at_error, "Landmark name '%s' too long (32 chars)\n", pkvd->szValue ); - strcpy(m_szLandmarkName, pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "changetarget")) - { - m_changeTarget = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "changedelay")) - { - m_changeTargetDelay = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseTrigger::KeyValue( pkvd ); -} - - -/*QUAKED trigger_changelevel (0.5 0.5 0.5) ? NO_INTERMISSION -When the player touches this, he gets sent to the map listed in the "map" variable. Unless the NO_INTERMISSION flag is set, the view will go to the info_intermission spot and display stats. -*/ - -void CChangeLevel :: Spawn( void ) -{ - if ( FStrEq( m_szMapName, "" ) ) - ALERT( at_console, "a trigger_changelevel doesn't have a map" ); - - if ( FStrEq( m_szLandmarkName, "" ) ) - ALERT( at_console, "trigger_changelevel to %s doesn't have a landmark", m_szMapName ); - - if (!FStringNull ( pev->targetname ) ) - { - SetUse ( &CChangeLevel::UseChangeLevel ); - } - InitTrigger(); - if ( !(pev->spawnflags & SF_CHANGELEVEL_USEONLY) ) - SetTouch( &CChangeLevel::TouchChangeLevel ); -// ALERT( at_console, "TRANSITION: %s (%s)\n", m_szMapName, m_szLandmarkName ); -} - - -void CChangeLevel :: ExecuteChangeLevel( void ) -{ - MESSAGE_BEGIN( MSG_ALL, SVC_CDTRACK ); - WRITE_BYTE( 3 ); - WRITE_BYTE( 3 ); - MESSAGE_END(); - - MESSAGE_BEGIN(MSG_ALL, SVC_INTERMISSION); - MESSAGE_END(); -} - - -FILE_GLOBAL char st_szNextMap[cchMapNameMost]; -FILE_GLOBAL char st_szNextSpot[cchMapNameMost]; - -edict_t *CChangeLevel :: FindLandmark( const char *pLandmarkName ) -{ - edict_t *pentLandmark; - - pentLandmark = FIND_ENTITY_BY_STRING( NULL, "targetname", pLandmarkName ); - while ( !FNullEnt( pentLandmark ) ) - { - // Found the landmark - if ( FClassnameIs( pentLandmark, "info_landmark" ) ) - return pentLandmark; - else - pentLandmark = FIND_ENTITY_BY_STRING( pentLandmark, "targetname", pLandmarkName ); - } - ALERT( at_error, "Can't find landmark %s\n", pLandmarkName ); - return NULL; -} - - -//========================================================= -// CChangeLevel :: Use - allows level transitions to be -// triggered by buttons, etc. -// -//========================================================= -void CChangeLevel :: UseChangeLevel ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - ChangeLevelNow( pActivator ); -} - -void CChangeLevel :: ChangeLevelNow( CBaseEntity *pActivator ) -{ - edict_t *pentLandmark; - LEVELLIST levels[16]; - - ASSERT(!FStrEq(m_szMapName, "")); - - // Don't work in deathmatch - if ( g_pGameRules->IsDeathmatch() ) - return; - - // Some people are firing these multiple times in a frame, disable - if ( gpGlobals->time == pev->dmgtime ) - return; - - pev->dmgtime = gpGlobals->time; - - - CBaseEntity *pPlayer = CBaseEntity::Instance( g_engfuncs.pfnPEntityOfEntIndex( 1 ) ); - if ( !InTransitionVolume( pPlayer, m_szLandmarkName ) ) - { - ALERT( at_aiconsole, "Player isn't in the transition volume %s, aborting\n", m_szLandmarkName ); - return; - } - - // Create an entity to fire the changetarget - if ( m_changeTarget ) - { - CFireAndDie *pFireAndDie = GetClassPtr( (CFireAndDie *)NULL ); - if ( pFireAndDie ) - { - // Set target and delay - pFireAndDie->pev->target = m_changeTarget; - pFireAndDie->m_flDelay = m_changeTargetDelay; - pFireAndDie->pev->origin = pPlayer->pev->origin; - // Call spawn - DispatchSpawn( pFireAndDie->edict() ); - } - } - // This object will get removed in the call to CHANGE_LEVEL, copy the params into "safe" memory - strcpy(st_szNextMap, m_szMapName); - - m_hActivator = pActivator; - SUB_UseTargets( pActivator, USE_TOGGLE, 0 ); - st_szNextSpot[0] = 0; // Init landmark to NULL - - // look for a landmark entity - pentLandmark = FindLandmark( m_szLandmarkName ); - if ( !FNullEnt( pentLandmark ) ) - { - strcpy(st_szNextSpot, m_szLandmarkName); - gpGlobals->vecLandmarkOffset = VARS(pentLandmark)->origin; - } -// ALERT( at_console, "Level touches %d levels\n", ChangeList( levels, 16 ) ); - ALERT( at_console, "CHANGE LEVEL: %s %s\n", st_szNextMap, st_szNextSpot ); - CHANGE_LEVEL( st_szNextMap, st_szNextSpot ); -} - -// -// GLOBALS ASSUMED SET: st_szNextMap -// -void CChangeLevel :: TouchChangeLevel( CBaseEntity *pOther ) -{ - if (!FClassnameIs(pOther->pev, "player")) - return; - - ChangeLevelNow( pOther ); -} - - -// Add a transition to the list, but ignore duplicates -// (a designer may have placed multiple trigger_changelevels with the same landmark) -int CChangeLevel::AddTransitionToList( LEVELLIST *pLevelList, int listCount, const char *pMapName, const char *pLandmarkName, edict_t *pentLandmark ) -{ - int i; - - if ( !pLevelList || !pMapName || !pLandmarkName || !pentLandmark ) - return 0; - - for ( i = 0; i < listCount; i++ ) - { - if ( pLevelList[i].pentLandmark == pentLandmark && strcmp( pLevelList[i].mapName, pMapName ) == 0 ) - return 0; - } - strcpy( pLevelList[listCount].mapName, pMapName ); - strcpy( pLevelList[listCount].landmarkName, pLandmarkName ); - pLevelList[listCount].pentLandmark = pentLandmark; - pLevelList[listCount].vecLandmarkOrigin = VARS(pentLandmark)->origin; - - return 1; -} - -int BuildChangeList( LEVELLIST *pLevelList, int maxList ) -{ - return CChangeLevel::ChangeList( pLevelList, maxList ); -} - - -int CChangeLevel::InTransitionVolume( CBaseEntity *pEntity, char *pVolumeName ) -{ - edict_t *pentVolume; - - - if ( pEntity->ObjectCaps() & FCAP_FORCE_TRANSITION ) - return 1; - - // If you're following another entity, follow it through the transition (weapons follow the player) - if ( pEntity->pev->movetype == MOVETYPE_FOLLOW ) - { - if ( pEntity->pev->aiment != NULL ) - pEntity = CBaseEntity::Instance( pEntity->pev->aiment ); - } - - int inVolume = 1; // Unless we find a trigger_transition, everything is in the volume - - pentVolume = FIND_ENTITY_BY_TARGETNAME( NULL, pVolumeName ); - while ( !FNullEnt( pentVolume ) ) - { - CBaseEntity *pVolume = CBaseEntity::Instance( pentVolume ); - - if ( pVolume && FClassnameIs( pVolume->pev, "trigger_transition" ) ) - { - if ( pVolume->Intersects( pEntity ) ) // It touches one, it's in the volume - return 1; - else - inVolume = 0; // Found a trigger_transition, but I don't intersect it -- if I don't find another, don't go! - } - pentVolume = FIND_ENTITY_BY_TARGETNAME( pentVolume, pVolumeName ); - } - - return inVolume; -} - - -// We can only ever move 512 entities across a transition -#define MAX_ENTITY 512 - -// This has grown into a complicated beast -// Can we make this more elegant? -// This builds the list of all transitions on this level and which entities are in their PVS's and can / should -// be moved across. -int CChangeLevel::ChangeList( LEVELLIST *pLevelList, int maxList ) -{ - edict_t *pentChangelevel, *pentLandmark; - int i, count; - - count = 0; - - // Find all of the possible level changes on this BSP - pentChangelevel = FIND_ENTITY_BY_STRING( NULL, "classname", "trigger_changelevel" ); - if ( FNullEnt( pentChangelevel ) ) - return 0; - while ( !FNullEnt( pentChangelevel ) ) - { - CChangeLevel *pTrigger; - - pTrigger = GetClassPtr((CChangeLevel *)VARS(pentChangelevel)); - if ( pTrigger ) - { - // Find the corresponding landmark - pentLandmark = FindLandmark( pTrigger->m_szLandmarkName ); - if ( pentLandmark ) - { - // Build a list of unique transitions - if ( AddTransitionToList( pLevelList, count, pTrigger->m_szMapName, pTrigger->m_szLandmarkName, pentLandmark ) ) - { - count++; - if ( count >= maxList ) // FULL!! - break; - } - } - } - pentChangelevel = FIND_ENTITY_BY_STRING( pentChangelevel, "classname", "trigger_changelevel" ); - } - - if ( gpGlobals->pSaveData && ((SAVERESTOREDATA *)gpGlobals->pSaveData)->pTable ) - { - CSave saveHelper( (SAVERESTOREDATA *)gpGlobals->pSaveData ); - - for ( i = 0; i < count; i++ ) - { - int j, entityCount = 0; - CBaseEntity *pEntList[ MAX_ENTITY ]; - int entityFlags[ MAX_ENTITY ]; - - // Follow the linked list of entities in the PVS of the transition landmark - edict_t *pent = UTIL_EntitiesInPVS( pLevelList[i].pentLandmark ); - - // Build a list of valid entities in this linked list (we're going to use pent->v.chain again) - while ( !FNullEnt( pent ) ) - { - CBaseEntity *pEntity = CBaseEntity::Instance(pent); - if ( pEntity ) - { -// ALERT( at_console, "Trying %s\n", STRING(pEntity->pev->classname) ); - int caps = pEntity->ObjectCaps(); - if ( !(caps & FCAP_DONT_SAVE) ) - { - int flags = 0; - - // If this entity can be moved or is global, mark it - if ( caps & FCAP_ACROSS_TRANSITION ) - flags |= FENTTABLE_MOVEABLE; - if ( pEntity->pev->globalname && !pEntity->IsDormant() ) - flags |= FENTTABLE_GLOBAL; - if ( flags ) - { - pEntList[ entityCount ] = pEntity; - entityFlags[ entityCount ] = flags; - entityCount++; - if ( entityCount > MAX_ENTITY ) - ALERT( at_error, "Too many entities across a transition!" ); - } -// else -// ALERT( at_console, "Failed %s\n", STRING(pEntity->pev->classname) ); - } -// else -// ALERT( at_console, "DON'T SAVE %s\n", STRING(pEntity->pev->classname) ); - } - pent = pent->v.chain; - } - - for ( j = 0; j < entityCount; j++ ) - { - // Check to make sure the entity isn't screened out by a trigger_transition - if ( entityFlags[j] && InTransitionVolume( pEntList[j], pLevelList[i].landmarkName ) ) - { - // Mark entity table with 1<pev->classname) ); - - } - } - } - - return count; -} - -/* -go to the next level for deathmatch -only called if a time or frag limit has expired -*/ -void NextLevel( void ) -{ - edict_t* pent; - CChangeLevel *pChange; - - // find a trigger_changelevel - pent = FIND_ENTITY_BY_CLASSNAME(NULL, "trigger_changelevel"); - - // go back to start if no trigger_changelevel - if (FNullEnt(pent)) - { - gpGlobals->mapname = ALLOC_STRING("start"); - pChange = GetClassPtr( (CChangeLevel *)NULL ); - strcpy(pChange->m_szMapName, "start"); - } - else - pChange = GetClassPtr( (CChangeLevel *)VARS(pent)); - - strcpy(st_szNextMap, pChange->m_szMapName); - g_fGameOver = TRUE; - - if (pChange->pev->nextthink < gpGlobals->time) - { - pChange->SetThink( &CChangeLevel::ExecuteChangeLevel ); - pChange->pev->nextthink = gpGlobals->time + 0.1; - } -} - - -// ============================== LADDER ======================================= - -class CLadder : public CBaseTrigger -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn( void ); - void Precache( void ); -}; -LINK_ENTITY_TO_CLASS( func_ladder, CLadder ); - - -void CLadder :: KeyValue( KeyValueData *pkvd ) -{ - CBaseTrigger::KeyValue( pkvd ); -} - - -//========================================================= -// func_ladder - makes an area vertically negotiable -//========================================================= -void CLadder :: Precache( void ) -{ - // Do all of this in here because we need to 'convert' old saved games - pev->solid = SOLID_NOT; - pev->skin = CONTENTS_LADDER; - if ( CVAR_GET_FLOAT("showtriggers") == 0 ) - { - pev->rendermode = kRenderTransTexture; - pev->renderamt = 0; - } - pev->effects &= ~EF_NODRAW; -} - - -void CLadder :: Spawn( void ) -{ - Precache(); - - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world - pev->movetype = MOVETYPE_PUSH; -} - - -// ========================== A TRIGGER THAT PUSHES YOU =============================== - -class CTriggerPush : public CBaseTrigger -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void Touch( CBaseEntity *pOther ); -}; -LINK_ENTITY_TO_CLASS( trigger_push, CTriggerPush ); - - -void CTriggerPush :: KeyValue( KeyValueData *pkvd ) -{ - CBaseTrigger::KeyValue( pkvd ); -} - - -/*QUAKED trigger_push (.5 .5 .5) ? TRIG_PUSH_ONCE -Pushes the player -*/ - -void CTriggerPush :: Spawn( ) -{ - if ( pev->angles == g_vecZero ) - pev->angles.y = 360; - InitTrigger(); - - if (pev->speed == 0) - pev->speed = 100; - - if ( FBitSet (pev->spawnflags, SF_TRIGGER_PUSH_START_OFF) )// if flagged to Start Turned Off, make trigger nonsolid. - pev->solid = SOLID_NOT; - - SetUse( &CTriggerPush::ToggleUse ); - - UTIL_SetOrigin( pev, pev->origin ); // Link into the list -} - - -void CTriggerPush :: Touch( CBaseEntity *pOther ) -{ - entvars_t* pevToucher = pOther->pev; - - // UNDONE: Is there a better way than health to detect things that have physics? (clients/monsters) - switch( pevToucher->movetype ) - { - case MOVETYPE_NONE: - case MOVETYPE_PUSH: - case MOVETYPE_NOCLIP: - case MOVETYPE_FOLLOW: - return; - } - - if ( pevToucher->solid != SOLID_NOT && pevToucher->solid != SOLID_BSP ) - { - // Instant trigger, just transfer velocity and remove - if (FBitSet(pev->spawnflags, SF_TRIG_PUSH_ONCE)) - { - pevToucher->velocity = pevToucher->velocity + (pev->speed * pev->movedir); - if ( pevToucher->velocity.z > 0 ) - pevToucher->flags &= ~FL_ONGROUND; - UTIL_Remove( this ); - } - else - { // Push field, transfer to base velocity - Vector vecPush = (pev->speed * pev->movedir); - if ( pevToucher->flags & FL_BASEVELOCITY ) - vecPush = vecPush + pevToucher->basevelocity; - - pevToucher->basevelocity = vecPush; - - pevToucher->flags |= FL_BASEVELOCITY; -// ALERT( at_console, "Vel %f, base %f\n", pevToucher->velocity.z, pevToucher->basevelocity.z ); - } - } -} - - -//====================================== -// teleport trigger -// -// - -void CBaseTrigger :: TeleportTouch( CBaseEntity *pOther ) -{ - entvars_t* pevToucher = pOther->pev; - edict_t *pentTarget = NULL; - - if (!UTIL_IsMasterTriggered(m_sMaster, pOther)) - return; - - if ( !( pev->spawnflags & SF_TRIGGER_ALLOWMONSTERS ) ) - {// no monsters allowed! - if ( FBitSet( pevToucher->flags, FL_MONSTER ) ) - { - return; - } - } - - if ( ( pev->spawnflags & SF_TRIGGER_NOCLIENTS ) ) - {// no clients allowed - if ( pOther->IsPlayer() ) - { - return; - } - } - - pentTarget = FIND_ENTITY_BY_TARGETNAME( pentTarget, STRING(pev->target) ); - if (FNullEnt(pentTarget)) - return; - - Vector tmp = VARS( pentTarget )->origin; - - if ( pOther->IsPlayer() ) - { - tmp.z -= pOther->pev->mins.z;// make origin adjustments in case the teleportee is a player. (origin in center, not at feet) - } - - tmp.z++; - - // Sprite in old position - CSprite *pSprite = CSprite::SpriteCreate( "sprites/discreturn.spr", pOther->pev->origin, TRUE ); - pSprite->AnimateAndDie( 60 ); - pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); - pSprite->SetScale( 1 ); - pSprite->pev->groupinfo = pOther->pev->groupinfo; - - pevToucher->flags &= ~FL_ONGROUND; - //UTIL_SetOrigin( pevToucher, tmp ); - pevToucher->origin = tmp; - - // Play a warp sound and sprite - pSprite = CSprite::SpriteCreate( "sprites/discreturn.spr", pOther->pev->origin, TRUE ); - pSprite->AnimateAndDie( 60 ); - pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); - pSprite->SetScale( 1 ); - pSprite->pev->groupinfo = pOther->pev->groupinfo; - EMIT_SOUND_DYN( pOther->edict(), CHAN_AUTO, "discreturn.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); - - pevToucher->angles = pentTarget->v.angles; - - if ( pOther->IsPlayer() ) - { - pevToucher->v_angle = pentTarget->v.angles; - pevToucher->fixangle = TRUE; - } - - // Discs keep their velocity - if ( strcmp( STRING(pOther->pev->classname), "disc" ) ) - { - pevToucher->velocity = pevToucher->basevelocity = g_vecZero; - } - else - { - UTIL_MakeVectors( pevToucher->angles ); - if ( ((CDisc*)pOther)->m_iPowerupFlags & POW_FAST ) - pevToucher->velocity = pevToucher->basevelocity = gpGlobals->v_forward * DISC_VELOCITY * 1.5; - else - pevToucher->velocity = pevToucher->basevelocity = gpGlobals->v_forward * DISC_VELOCITY; - - ((CDisc*)pOther)->m_bTeleported = true; - } -} - - -class CTriggerTeleport : public CBaseTrigger -{ -public: - void Spawn( void ); -}; -LINK_ENTITY_TO_CLASS( trigger_teleport, CTriggerTeleport ); - -void CTriggerTeleport :: Spawn( void ) -{ - InitTrigger(); - - SetTouch( &CTriggerTeleport::TeleportTouch ); -} - - -LINK_ENTITY_TO_CLASS( info_teleport_destination, CPointEntity ); - - - -class CTriggerSave : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT SaveTouch( CBaseEntity *pOther ); -}; -LINK_ENTITY_TO_CLASS( trigger_autosave, CTriggerSave ); - -void CTriggerSave::Spawn( void ) -{ - if ( g_pGameRules->IsDeathmatch() ) - { - REMOVE_ENTITY( ENT(pev) ); - return; - } - - InitTrigger(); - SetTouch( &CTriggerSave::SaveTouch ); -} - -void CTriggerSave::SaveTouch( CBaseEntity *pOther ) -{ - if ( !UTIL_IsMasterTriggered( m_sMaster, pOther ) ) - return; - - // Only save on clients - if ( !pOther->IsPlayer() ) - return; - - SetTouch( NULL ); - UTIL_Remove( this ); - SERVER_COMMAND( "autosave\n" ); -} - -#define SF_ENDSECTION_USEONLY 0x0001 - -class CTriggerEndSection : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT EndSectionTouch( CBaseEntity *pOther ); - void KeyValue( KeyValueData *pkvd ); - void EXPORT EndSectionUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); -}; -LINK_ENTITY_TO_CLASS( trigger_endsection, CTriggerEndSection ); - - -void CTriggerEndSection::EndSectionUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // Only save on clients - if ( !pActivator->IsNetClient() ) - return; - - SetUse( NULL ); - - if ( pev->message ) - { - g_engfuncs.pfnEndSection(STRING(pev->message)); - } - UTIL_Remove( this ); -} - -void CTriggerEndSection::Spawn( void ) -{ - if ( g_pGameRules->IsDeathmatch() ) - { - REMOVE_ENTITY( ENT(pev) ); - return; - } - - InitTrigger(); - - SetUse ( &CTriggerEndSection::EndSectionUse ); - // If it is a "use only" trigger, then don't set the touch function. - if ( ! (pev->spawnflags & SF_ENDSECTION_USEONLY) ) - SetTouch( &CTriggerEndSection::EndSectionTouch ); -} - -void CTriggerEndSection::EndSectionTouch( CBaseEntity *pOther ) -{ - // Only save on clients - if ( !pOther->IsNetClient() ) - return; - - SetTouch( NULL ); - - if (pev->message) - { - g_engfuncs.pfnEndSection(STRING(pev->message)); - } - UTIL_Remove( this ); -} - -void CTriggerEndSection :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "section")) - { -// m_iszSectionName = ALLOC_STRING( pkvd->szValue ); - // Store this in message so we don't have to write save/restore for this ent - pev->message = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseTrigger::KeyValue( pkvd ); -} - - -class CTriggerGravity : public CBaseTrigger -{ -public: - void Spawn( void ); - void EXPORT GravityTouch( CBaseEntity *pOther ); -}; -LINK_ENTITY_TO_CLASS( trigger_gravity, CTriggerGravity ); - -void CTriggerGravity::Spawn( void ) -{ - InitTrigger(); - SetTouch( &CTriggerGravity::GravityTouch ); -} - -void CTriggerGravity::GravityTouch( CBaseEntity *pOther ) -{ - // Only save on clients - if ( !pOther->IsPlayer() ) - return; - - pOther->pev->gravity = pev->gravity; -} - - - - - - - -// this is a really bad idea. -class CTriggerChangeTarget : public CBaseDelay -{ -public: - void KeyValue( KeyValueData *pkvd ); - void Spawn( void ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - - int ObjectCaps( void ) { return CBaseDelay::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - - static TYPEDESCRIPTION m_SaveData[]; - -private: - int m_iszNewTarget; -}; -LINK_ENTITY_TO_CLASS( trigger_changetarget, CTriggerChangeTarget ); - -TYPEDESCRIPTION CTriggerChangeTarget::m_SaveData[] = -{ - DEFINE_FIELD( CTriggerChangeTarget, m_iszNewTarget, FIELD_STRING ), -}; - -IMPLEMENT_SAVERESTORE(CTriggerChangeTarget,CBaseDelay); - -void CTriggerChangeTarget::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "m_iszNewTarget")) - { - m_iszNewTarget = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - -void CTriggerChangeTarget::Spawn( void ) -{ -} - - -void CTriggerChangeTarget::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - CBaseEntity *pTarget = UTIL_FindEntityByString( NULL, "targetname", STRING( pev->target ) ); - - if (pTarget) - { - pTarget->pev->target = m_iszNewTarget; - CBaseMonster *pMonster = pTarget->MyMonsterPointer( ); - if (pMonster) - { - pMonster->m_pGoalEnt = NULL; - } - } -} - - - - -#define SF_CAMERA_PLAYER_POSITION 1 -#define SF_CAMERA_PLAYER_TARGET 2 -#define SF_CAMERA_PLAYER_TAKECONTROL 4 - -class CTriggerCamera : public CBaseDelay -{ -public: - void Spawn( void ); - void KeyValue( KeyValueData *pkvd ); - void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT FollowTarget( void ); - void Move(void); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - virtual int ObjectCaps( void ) { return CBaseEntity :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - static TYPEDESCRIPTION m_SaveData[]; - - EHANDLE m_hPlayer; - EHANDLE m_hTarget; - CBaseEntity *m_pentPath; - int m_sPath; - float m_flWait; - float m_flReturnTime; - float m_flStopTime; - float m_moveDistance; - float m_targetSpeed; - float m_initialSpeed; - float m_acceleration; - float m_deceleration; - int m_state; - -}; -LINK_ENTITY_TO_CLASS( trigger_camera, CTriggerCamera ); - -// Global Savedata for changelevel friction modifier -TYPEDESCRIPTION CTriggerCamera::m_SaveData[] = -{ - DEFINE_FIELD( CTriggerCamera, m_hPlayer, FIELD_EHANDLE ), - DEFINE_FIELD( CTriggerCamera, m_hTarget, FIELD_EHANDLE ), - DEFINE_FIELD( CTriggerCamera, m_pentPath, FIELD_CLASSPTR ), - DEFINE_FIELD( CTriggerCamera, m_sPath, FIELD_STRING ), - DEFINE_FIELD( CTriggerCamera, m_flWait, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_flReturnTime, FIELD_TIME ), - DEFINE_FIELD( CTriggerCamera, m_flStopTime, FIELD_TIME ), - DEFINE_FIELD( CTriggerCamera, m_moveDistance, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_targetSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_initialSpeed, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_acceleration, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_deceleration, FIELD_FLOAT ), - DEFINE_FIELD( CTriggerCamera, m_state, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE(CTriggerCamera,CBaseDelay); - -void CTriggerCamera::Spawn( void ) -{ - pev->movetype = MOVETYPE_NOCLIP; - pev->solid = SOLID_NOT; // Remove model & collisions - pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on - pev->rendermode = kRenderTransTexture; - - m_initialSpeed = pev->speed; - if ( m_acceleration == 0 ) - m_acceleration = 500; - if ( m_deceleration == 0 ) - m_deceleration = 500; -} - - -void CTriggerCamera :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "wait")) - { - m_flWait = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "moveto")) - { - m_sPath = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "acceleration")) - { - m_acceleration = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "deceleration")) - { - m_deceleration = atof( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else - CBaseDelay::KeyValue( pkvd ); -} - - - -void CTriggerCamera::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( !ShouldToggle( useType, m_state ) ) - return; - - // Toggle state - m_state = !m_state; - if (m_state == 0) - { - m_flReturnTime = gpGlobals->time; - return; - } - if ( !pActivator || !pActivator->IsPlayer() ) - { - pActivator = CBaseEntity::Instance(g_engfuncs.pfnPEntityOfEntIndex( 1 )); - } - - m_hPlayer = pActivator; - - m_flReturnTime = gpGlobals->time + m_flWait; - pev->speed = m_initialSpeed; - m_targetSpeed = m_initialSpeed; - - if (FBitSet (pev->spawnflags, SF_CAMERA_PLAYER_TARGET ) ) - { - m_hTarget = m_hPlayer; - } - else - { - m_hTarget = GetNextTarget(); - } - - // Nothing to look at! - if ( m_hTarget == NULL ) - { - return; - } - - - if (FBitSet (pev->spawnflags, SF_CAMERA_PLAYER_TAKECONTROL ) ) - { - ((CBasePlayer *)pActivator)->EnableControl(FALSE); - } - - if ( m_sPath ) - { - m_pentPath = Instance( FIND_ENTITY_BY_TARGETNAME ( NULL, STRING(m_sPath)) ); - } - else - { - m_pentPath = NULL; - } - - m_flStopTime = gpGlobals->time; - if ( m_pentPath ) - { - if ( m_pentPath->pev->speed != 0 ) - m_targetSpeed = m_pentPath->pev->speed; - - m_flStopTime += m_pentPath->GetDelay(); - } - - // copy over player information - if (FBitSet (pev->spawnflags, SF_CAMERA_PLAYER_POSITION ) ) - { - UTIL_SetOrigin( pev, pActivator->pev->origin + pActivator->pev->view_ofs ); - pev->angles.x = -pActivator->pev->angles.x; - pev->angles.y = pActivator->pev->angles.y; - pev->angles.z = 0; - pev->velocity = pActivator->pev->velocity; - } - else - { - pev->velocity = Vector( 0, 0, 0 ); - } - - SET_VIEW( pActivator->edict(), edict() ); - - SET_MODEL(ENT(pev), STRING(pActivator->pev->model) ); - - // follow the player down - SetThink( &CTriggerCamera::FollowTarget ); - pev->nextthink = gpGlobals->time; - - m_moveDistance = 0; - Move(); -} - - -void CTriggerCamera::FollowTarget( ) -{ - if (m_hPlayer == NULL) - return; - - if (m_hTarget == NULL || m_flReturnTime < gpGlobals->time) - { - if (m_hPlayer->IsAlive( )) - { - SET_VIEW( m_hPlayer->edict(), m_hPlayer->edict() ); - ((CBasePlayer *)((CBaseEntity *)m_hPlayer))->EnableControl(TRUE); - } - SUB_UseTargets( this, USE_TOGGLE, 0 ); - pev->avelocity = Vector( 0, 0, 0 ); - m_state = 0; - return; - } - - Vector vecGoal = UTIL_VecToAngles( m_hTarget->pev->origin - pev->origin ); - vecGoal.x = -vecGoal.x; - - if (pev->angles.y > 360) - pev->angles.y -= 360; - - if (pev->angles.y < 0) - pev->angles.y += 360; - - float dx = vecGoal.x - pev->angles.x; - float dy = vecGoal.y - pev->angles.y; - - if (dx < -180) - dx += 360; - if (dx > 180) - dx = dx - 360; - - if (dy < -180) - dy += 360; - if (dy > 180) - dy = dy - 360; - - pev->avelocity.x = dx * 40 * gpGlobals->frametime; - pev->avelocity.y = dy * 40 * gpGlobals->frametime; - - - if (!(FBitSet (pev->spawnflags, SF_CAMERA_PLAYER_TAKECONTROL))) - { - pev->velocity = pev->velocity * 0.8; - if (pev->velocity.Length( ) < 10.0) - pev->velocity = g_vecZero; - } - - pev->nextthink = gpGlobals->time; - - Move(); -} - -void CTriggerCamera::Move() -{ - // Not moving on a path, return - if (!m_pentPath) - return; - - // Subtract movement from the previous frame - m_moveDistance -= pev->speed * gpGlobals->frametime; - - // Have we moved enough to reach the target? - if ( m_moveDistance <= 0 ) - { - // Fire the passtarget if there is one - if ( m_pentPath->pev->message ) - { - FireTargets( STRING(m_pentPath->pev->message), this, this, USE_TOGGLE, 0 ); - if ( FBitSet( m_pentPath->pev->spawnflags, SF_CORNER_FIREONCE ) ) - m_pentPath->pev->message = 0; - } - // Time to go to the next target - m_pentPath = m_pentPath->GetNextTarget(); - - // Set up next corner - if ( !m_pentPath ) - { - pev->velocity = g_vecZero; - } - else - { - if ( m_pentPath->pev->speed != 0 ) - m_targetSpeed = m_pentPath->pev->speed; - - Vector delta = m_pentPath->pev->origin - pev->origin; - m_moveDistance = delta.Length(); - pev->movedir = delta.Normalize(); - m_flStopTime = gpGlobals->time + m_pentPath->GetDelay(); - } - } - - if ( m_flStopTime > gpGlobals->time ) - pev->speed = UTIL_Approach( 0, pev->speed, m_deceleration * gpGlobals->frametime ); - else - pev->speed = UTIL_Approach( m_targetSpeed, pev->speed, m_acceleration * gpGlobals->frametime ); - - float fraction = 2 * gpGlobals->frametime; - pev->velocity = ((pev->movedir * pev->speed) * fraction) + (pev->velocity * (1-fraction)); -} - - -//=============================================================================== -// DISCWAR OBJECTS -//=============================================================================== -// Brush that's status gets toggled by a disc hit -LINK_ENTITY_TO_CLASS( func_disctoggle, CDiscTarget ); - -void CDiscTarget::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "hitby_friendly") ) - { - m_iszFriendlyHit = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "hitby_enemy") ) - { - m_iszEnemyHit = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if (FStrEq(pkvd->szKeyName, "arena") ) - { - pev->groupinfo = 1 << (atoi( pkvd->szValue ) - 1); - pkvd->fHandled = TRUE; - } - else - CBaseTrigger::KeyValue( pkvd ); -} - -void CDiscTarget::Spawn( void ) -{ - Precache(); - - pev->solid = SOLID_TRIGGER; - SET_MODEL(ENT(pev), STRING(pev->model)); // set size and link into world - - m_iState = 0; - SetTouch( &CDiscTarget::DiscToggleTouch ); -} - -void CDiscTarget::Reset( void ) -{ - m_iState = 0; - pev->frame = 0; - pev->target = m_iszFriendlyHit; -} - -void CDiscTarget::DiscToggleTouch( CBaseEntity *pOther ) -{ - if ( strcmp( STRING(pOther->pev->classname), "disc" ) ) - return; - - int iHitBy = 0; - CBaseEntity *pOwner = (CBaseEntity *)((CDisc *)pOther)->m_hOwner; - - // Hit by friendly if the teams match. Enemy otherwise - if ( pOwner && pOwner->pev->team == pev->team ) - { - Reset(); - iHitBy = LAST_HITBY_FRIENDLY; - } - else - { - pev->target = m_iszEnemyHit; - iHitBy = LAST_HITBY_ENEMY; - - pev->frame = 1; - } - - // Don't toggle if we were last hit by the same team - if (m_iState == iHitBy) - return; - - // Fire the target - SUB_UseTargets( pOwner, USE_TOGGLE, iHitBy ); - m_iState = iHitBy; -} - -//=============================================================================== -// Brush that toggles between gone/there -LINK_ENTITY_TO_CLASS( func_plat_toggleremove, CPlatToggleRemove ); - -void CPlatToggleRemove::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "arena") ) - { - pev->groupinfo = 1 << (atoi( pkvd->szValue ) - 1); - pkvd->fHandled = TRUE; - } - else - CBaseEntity::KeyValue( pkvd ); -} - -void CPlatToggleRemove::Spawn( void ) -{ - Precache(); - - // Remove all but one copy of this ent if we're not in arena mode - if ( InArenaMode() == FALSE ) - { - if ( pev->groupinfo > 1 ) - { - pev->flags |= FL_KILLME; - return; - } - - // Clear groupinfo - pev->groupinfo = 0; - } - - pev->solid = SOLID_BSP; - pev->movetype = MOVETYPE_PUSH; - SET_MODEL(ENT(pev), STRING(pev->model)); - - SetUse( &CPlatToggleRemove::PlatToggleRemoveUse ); -} - -void CPlatToggleRemove::Reset( void ) -{ - pev->rendermode = kRenderNormal; - pev->renderamt = 255; - - pev->effects &= ~EF_NODRAW; - pev->solid = SOLID_BSP; - SET_MODEL(ENT(pev), STRING(pev->model)); - - SetThink( NULL ); - pev->nextthink = 0; -} - -void CPlatToggleRemove::PlatToggleRemoveUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( value == LAST_HITBY_ENEMY ) - { - // Make it fade out - SetThink( &CPlatToggleRemove::PlatRemoveThink ); - pev->nextthink = pev->ltime + 0.1; - m_flRemoveAt = gpGlobals->time + PLAT_FADE_TIME; - - pev->rendermode = kRenderTransAdd; - pev->renderamt = 250; - } - else - { - Reset(); - } -} - -void CPlatToggleRemove::PlatRemoveThink( void ) -{ - float flTimeLeft = m_flRemoveAt - gpGlobals->time; - - // Fade until m_flRemoveAt - if ( flTimeLeft > 0 ) - { - float flPercent = flTimeLeft / PLAT_FADE_TIME; - pev->renderamt = 250 * flPercent; - pev->nextthink = pev->ltime + 0.1; - } - else - { - // Fully gone - pev->effects |= EF_NODRAW; - pev->solid = SOLID_NOT; - SET_MODEL(ENT(pev), STRING(pev->model)); - } -} - -//=============================================================================== -// Brush that jumps a player to a target point -LINK_ENTITY_TO_CLASS( trigger_jump, CTriggerJump ); - -void CTriggerJump::Spawn( void ) -{ - Precache(); - InitTrigger(); - SetTouch( &CTriggerJump::JumpTouch ); - SetUse( &CTriggerJump::JumpUse ); - - if (!m_flHeight) - m_flHeight = 150; -} - -void CTriggerJump::KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "height") ) - { - m_flHeight = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else - CBaseTrigger::KeyValue( pkvd ); -} - -void CTriggerJump::Precache( void ) -{ - PRECACHE_SOUND( "triggerjump.wav" ); - - m_usJump = PRECACHE_EVENT( 1, "events/jump.sc" ); -} - -void CTriggerJump::Activate( void ) -{ - // Find the target point - if (!FStringNull(pev->target)) - { - edict_t* pentTarget = NULL; - pentTarget = FIND_ENTITY_BY_TARGETNAME(pentTarget, STRING(pev->target)); - if (FNullEnt(pentTarget)) - { - ALERT ( at_console, "trigger_jump - Could not find target %s\n", STRING(pev->target) ); - pev->flags |= FL_KILLME; - } - else - { - m_vecTargetOrg = pentTarget->v.origin; - } - } -} - -void CTriggerJump::JumpUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - if ( m_iState == 0 ) - { - m_iState = 1; - SetTouch( &CTriggerJump::JumpTouch ); - } - else - { - m_iState = 0; - SetTouch( NULL ); - } -} - -void CTriggerJump::JumpTouch( CBaseEntity *pOther ) -{ - TraceResult tr; - float flGravity = CVAR_GET_FLOAT( "sv_gravity" ); - - // Don't touch again immediately - if ( pOther->m_flTouchedByJumpPad > gpGlobals->time ) - { - m_flTouchedByJumpPad = gpGlobals->time + 0.1; - return; - } - - // get a rough idea of how high to launch - Vector vecMidPoint = pOther->pev->origin + (m_vecTargetOrg - pOther->pev->origin) * 0.5; - UTIL_TraceLine(vecMidPoint, vecMidPoint + Vector(0,0,m_flHeight), ignore_monsters, ENT(pev), &tr); - vecMidPoint = tr.vecEndPos; - // (subtract 15 so we don't hit the ceiling) - vecMidPoint.z -= 15; - - // How high should we travel to reach the apex - float distance1 = (vecMidPoint.z - pOther->pev->origin.z); - float distance2 = (vecMidPoint.z - m_vecTargetOrg.z); - - // How long will it take to travel this distance - float time1 = sqrt( distance1 / (0.5 * flGravity) ); - float time2 = sqrt( distance2 / (0.5 * flGravity) ); - if (time1 < 0.1) - return; - - // how hard to launch to get there in time. - Vector vecTargetVel = (m_vecTargetOrg - pOther->pev->origin) / (time1 + time2); - vecTargetVel.z = flGravity * time1; - - // don't affect the player again for a bit - pOther->m_flTouchedByJumpPad = gpGlobals->time + 0.2; - pOther->pev->velocity = vecTargetVel; - if ( pOther->IsPlayer() ) - ((CBasePlayer*)pOther)->SetAnimation( PLAYER_SUPERJUMP ); - - // Play a sound - PLAYBACK_EVENT_FULL( FEV_NOTHOST, pOther->edict(), m_usJump, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); -} - -//=============================================================================== -// Trigger that returns discs to their thrower immediately -LINK_ENTITY_TO_CLASS( trigger_discreturn, CTriggerDiscReturn ); - -void CTriggerDiscReturn::Spawn( void ) -{ - Precache(); - InitTrigger(); - SetTouch( &CTriggerDiscReturn::DiscReturnTouch ); -} - -void CTriggerDiscReturn::Precache( void ) -{ - PRECACHE_MODEL( "sprites/discreturn.spr" ); - PRECACHE_SOUND( "discreturn.wav" ); -} - -void CTriggerDiscReturn::DiscReturnTouch( CBaseEntity *pOther ) -{ - if ( strcmp( STRING(pOther->pev->classname), "disc" ) ) - return; - - // Play a warp sound and sprite - CSprite *pSprite = CSprite::SpriteCreate( "sprites/discreturn.spr", pOther->pev->origin, TRUE ); - pSprite->AnimateAndDie( 60 ); - pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); - pSprite->SetScale( 1 ); - pSprite->pev->groupinfo = pOther->pev->groupinfo; - - EMIT_SOUND_DYN( pOther->edict(), CHAN_AUTO, "discreturn.wav", 0.2, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); - - // Return - ((CDisc*)pOther)->ReturnToThrower(); -} - -//=============================================================================== -// Trigger that starts the fall animation for players -LINK_ENTITY_TO_CLASS( trigger_fall, CTriggerFall ); - -void CTriggerFall::Spawn( void ) -{ - Precache(); - InitTrigger(); - SetTouch( &CTriggerFall::FallTouch ); -} - -void CTriggerFall::FallTouch( CBaseEntity *pOther ) -{ - if ( pOther->IsPlayer() == FALSE ) - return; - - if ( pOther->IsAlive() == FALSE ) - return; - - switch( RANDOM_LONG(0,2) ) - { - default: - case 0: EMIT_SOUND(ENT(pOther->pev), CHAN_STATIC, "scream1.wav", 1, ATTN_NORM); break; - case 1: EMIT_SOUND(ENT(pOther->pev), CHAN_STATIC, "scream2.wav", 1, ATTN_NORM); break; - case 2: EMIT_SOUND(ENT(pOther->pev), CHAN_STATIC, "scream3.wav", 1, ATTN_NORM); break; - } - - pOther->TakeDamage( pev, pev, 500, DMG_NEVERGIB ); - ((CBasePlayer*)pOther)->SetAnimation( PLAYER_FALL ); - - // Make their model shrink away to nothing - pOther->pev->renderfx = kRenderFxExplode; - pOther->pev->health = -5; // Setting this to -5 starts the client-side fall animation -} - diff --git a/ricochet/dlls/util.cpp b/ricochet/dlls/util.cpp deleted file mode 100644 index a819384..0000000 --- a/ricochet/dlls/util.cpp +++ /dev/null @@ -1,2565 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== util.cpp ======================================================== - - Utility code. Really not optional after all. - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "saverestore.h" -#include -#include "../engine/shake.h" -#include "decals.h" -#include "player.h" -#include "weapons.h" -#include "gamerules.h" - -/* -===================== -UTIL_WeaponTimeBase - -Time basis for weapons ( zero based of predicting client weapons ) -===================== -*/ -float UTIL_WeaponTimeBase( void ) -{ - return 0.0; -} - -static unsigned int glSeed = 0; - -unsigned int seed_table[ 256 ] = -{ - 28985, 27138, 26457, 9451, 17764, 10909, 28790, 8716, 6361, 4853, 17798, 21977, 19643, 20662, 10834, 20103, - 27067, 28634, 18623, 25849, 8576, 26234, 23887, 18228, 32587, 4836, 3306, 1811, 3035, 24559, 18399, 315, - 26766, 907, 24102, 12370, 9674, 2972, 10472, 16492, 22683, 11529, 27968, 30406, 13213, 2319, 23620, 16823, - 10013, 23772, 21567, 1251, 19579, 20313, 18241, 30130, 8402, 20807, 27354, 7169, 21211, 17293, 5410, 19223, - 10255, 22480, 27388, 9946, 15628, 24389, 17308, 2370, 9530, 31683, 25927, 23567, 11694, 26397, 32602, 15031, - 18255, 17582, 1422, 28835, 23607, 12597, 20602, 10138, 5212, 1252, 10074, 23166, 19823, 31667, 5902, 24630, - 18948, 14330, 14950, 8939, 23540, 21311, 22428, 22391, 3583, 29004, 30498, 18714, 4278, 2437, 22430, 3439, - 28313, 23161, 25396, 13471, 19324, 15287, 2563, 18901, 13103, 16867, 9714, 14322, 15197, 26889, 19372, 26241, - 31925, 14640, 11497, 8941, 10056, 6451, 28656, 10737, 13874, 17356, 8281, 25937, 1661, 4850, 7448, 12744, - 21826, 5477, 10167, 16705, 26897, 8839, 30947, 27978, 27283, 24685, 32298, 3525, 12398, 28726, 9475, 10208, - 617, 13467, 22287, 2376, 6097, 26312, 2974, 9114, 21787, 28010, 4725, 15387, 3274, 10762, 31695, 17320, - 18324, 12441, 16801, 27376, 22464, 7500, 5666, 18144, 15314, 31914, 31627, 6495, 5226, 31203, 2331, 4668, - 12650, 18275, 351, 7268, 31319, 30119, 7600, 2905, 13826, 11343, 13053, 15583, 30055, 31093, 5067, 761, - 9685, 11070, 21369, 27155, 3663, 26542, 20169, 12161, 15411, 30401, 7580, 31784, 8985, 29367, 20989, 14203, - 29694, 21167, 10337, 1706, 28578, 887, 3373, 19477, 14382, 675, 7033, 15111, 26138, 12252, 30996, 21409, - 25678, 18555, 13256, 23316, 22407, 16727, 991, 9236, 5373, 29402, 6117, 15241, 27715, 19291, 19888, 19847 -}; - -unsigned int U_Random( void ) -{ - glSeed *= 69069; - glSeed += seed_table[ glSeed & 0xff ]; - - return ( ++glSeed & 0x0fffffff ); -} - -void U_Srand( unsigned int seed ) -{ - glSeed = seed_table[ seed & 0xff ]; -} - -/* -===================== -UTIL_SharedRandomLong -===================== -*/ -int UTIL_SharedRandomLong( unsigned int seed, int low, int high ) -{ - - unsigned int range; - - U_Srand( (int)seed + low + high ); - - range = high - low + 1; - if ( !(range - 1) ) - { - return low; - } - else - { - int offset; - int rnum; - - rnum = U_Random(); - - offset = rnum % range; - - return (low + offset); - } -} - -/* -===================== -UTIL_SharedRandomFloat -===================== -*/ -float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ) -{ - // - unsigned int range; - - U_Srand( (int)seed + *(int *)&low + *(int *)&high ); - - U_Random(); - U_Random(); - - range = high - low; - if ( !range ) - { - return low; - } - else - { - int tensixrand; - float offset; - - tensixrand = U_Random() & 65535; - - offset = (float)tensixrand / 65536.0; - - return (low + offset * range ); - } -} - -void UTIL_ParametricRocket( entvars_t *pev, Vector vecOrigin, Vector vecAngles, edict_t *owner ) -{ - pev->startpos = vecOrigin; - // Trace out line to end pos - TraceResult tr; - UTIL_MakeVectors( vecAngles ); - UTIL_TraceLine( pev->startpos, pev->startpos + gpGlobals->v_forward * 8192, ignore_monsters, owner, &tr); - pev->endpos = tr.vecEndPos; - - // Now compute how long it will take based on current velocity - Vector vecTravel = pev->endpos - pev->startpos; - float travelTime = 0.0; - if ( pev->velocity.Length() > 0 ) - { - travelTime = vecTravel.Length() / pev->velocity.Length(); - } - pev->starttime = gpGlobals->time; - pev->impacttime = gpGlobals->time + travelTime; -} - -int g_groupmask = 0; -int g_groupop = 0; - -// Normal overrides -void UTIL_SetGroupTrace( int groupmask, int op ) -{ - g_groupmask = groupmask; - g_groupop = op; - - ENGINE_SETGROUPMASK( g_groupmask, g_groupop ); -} - -void UTIL_UnsetGroupTrace( void ) -{ - g_groupmask = 0; - g_groupop = 0; - - ENGINE_SETGROUPMASK( 0, 0 ); -} - -// Smart version, it'll clean itself up when it pops off stack -UTIL_GroupTrace::UTIL_GroupTrace( int groupmask, int op ) -{ - m_oldgroupmask = g_groupmask; - m_oldgroupop = g_groupop; - - g_groupmask = groupmask; - g_groupop = op; - - ENGINE_SETGROUPMASK( g_groupmask, g_groupop ); -} - -UTIL_GroupTrace::~UTIL_GroupTrace( void ) -{ - g_groupmask = m_oldgroupmask; - g_groupop = m_oldgroupop; - - ENGINE_SETGROUPMASK( g_groupmask, g_groupop ); -} - -TYPEDESCRIPTION gEntvarsDescription[] = -{ - DEFINE_ENTITY_FIELD( classname, FIELD_STRING ), - DEFINE_ENTITY_GLOBAL_FIELD( globalname, FIELD_STRING ), - - DEFINE_ENTITY_FIELD( origin, FIELD_POSITION_VECTOR ), - DEFINE_ENTITY_FIELD( oldorigin, FIELD_POSITION_VECTOR ), - DEFINE_ENTITY_FIELD( velocity, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( basevelocity, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( movedir, FIELD_VECTOR ), - - DEFINE_ENTITY_FIELD( angles, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( avelocity, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( punchangle, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( v_angle, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( fixangle, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( idealpitch, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( pitch_speed, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( ideal_yaw, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( yaw_speed, FIELD_FLOAT ), - - DEFINE_ENTITY_FIELD( modelindex, FIELD_INTEGER ), - DEFINE_ENTITY_GLOBAL_FIELD( model, FIELD_MODELNAME ), - - DEFINE_ENTITY_FIELD( viewmodel, FIELD_MODELNAME ), - DEFINE_ENTITY_FIELD( weaponmodel, FIELD_MODELNAME ), - - DEFINE_ENTITY_FIELD( absmin, FIELD_POSITION_VECTOR ), - DEFINE_ENTITY_FIELD( absmax, FIELD_POSITION_VECTOR ), - DEFINE_ENTITY_GLOBAL_FIELD( mins, FIELD_VECTOR ), - DEFINE_ENTITY_GLOBAL_FIELD( maxs, FIELD_VECTOR ), - DEFINE_ENTITY_GLOBAL_FIELD( size, FIELD_VECTOR ), - - DEFINE_ENTITY_FIELD( ltime, FIELD_TIME ), - DEFINE_ENTITY_FIELD( nextthink, FIELD_TIME ), - - DEFINE_ENTITY_FIELD( solid, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( movetype, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( skin, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( body, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( effects, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( gravity, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( friction, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( light_level, FIELD_FLOAT ), - - DEFINE_ENTITY_FIELD( frame, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( scale, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( sequence, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( animtime, FIELD_TIME ), - DEFINE_ENTITY_FIELD( framerate, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( controller, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( blending, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( rendermode, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( renderamt, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( rendercolor, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( renderfx, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( health, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( frags, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( weapons, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( takedamage, FIELD_FLOAT ), - - DEFINE_ENTITY_FIELD( deadflag, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( view_ofs, FIELD_VECTOR ), - DEFINE_ENTITY_FIELD( button, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( impulse, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( chain, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( dmg_inflictor, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( enemy, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( aiment, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( owner, FIELD_EDICT ), - DEFINE_ENTITY_FIELD( groundentity, FIELD_EDICT ), - - DEFINE_ENTITY_FIELD( spawnflags, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( flags, FIELD_FLOAT ), - - DEFINE_ENTITY_FIELD( colormap, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( team, FIELD_INTEGER ), - - DEFINE_ENTITY_FIELD( max_health, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( teleport_time, FIELD_TIME ), - DEFINE_ENTITY_FIELD( armortype, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( armorvalue, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( waterlevel, FIELD_INTEGER ), - DEFINE_ENTITY_FIELD( watertype, FIELD_INTEGER ), - - // Having these fields be local to the individual levels makes it easier to test those levels individually. - DEFINE_ENTITY_GLOBAL_FIELD( target, FIELD_STRING ), - DEFINE_ENTITY_GLOBAL_FIELD( targetname, FIELD_STRING ), - DEFINE_ENTITY_FIELD( netname, FIELD_STRING ), - DEFINE_ENTITY_FIELD( message, FIELD_STRING ), - - DEFINE_ENTITY_FIELD( dmg_take, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( dmg_save, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( dmg, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( dmgtime, FIELD_TIME ), - - DEFINE_ENTITY_FIELD( noise, FIELD_SOUNDNAME ), - DEFINE_ENTITY_FIELD( noise1, FIELD_SOUNDNAME ), - DEFINE_ENTITY_FIELD( noise2, FIELD_SOUNDNAME ), - DEFINE_ENTITY_FIELD( noise3, FIELD_SOUNDNAME ), - DEFINE_ENTITY_FIELD( speed, FIELD_FLOAT ), - DEFINE_ENTITY_FIELD( air_finished, FIELD_TIME ), - DEFINE_ENTITY_FIELD( pain_finished, FIELD_TIME ), - DEFINE_ENTITY_FIELD( radsuit_finished, FIELD_TIME ), -}; - -#define ENTVARS_COUNT (sizeof(gEntvarsDescription)/sizeof(gEntvarsDescription[0])) - - -#ifdef DEBUG -edict_t *DBG_EntOfVars( const entvars_t *pev ) -{ - if (pev->pContainingEntity != NULL) - return pev->pContainingEntity; - ALERT(at_console, "entvars_t pContainingEntity is NULL, calling into engine"); - edict_t* pent = (*g_engfuncs.pfnFindEntityByVars)((entvars_t*)pev); - if (pent == NULL) - ALERT(at_console, "DAMN! Even the engine couldn't FindEntityByVars!"); - ((entvars_t *)pev)->pContainingEntity = pent; - return pent; -} -#endif //DEBUG - - -#ifdef DEBUG - void -DBG_AssertFunction( - BOOL fExpr, - const char* szExpr, - const char* szFile, - int szLine, - const char* szMessage) - { - if (fExpr) - return; - char szOut[512]; - if (szMessage != NULL) - sprintf(szOut, "ASSERT FAILED:\n %s \n(%s@%d)\n%s", szExpr, szFile, szLine, szMessage); - else - sprintf(szOut, "ASSERT FAILED:\n %s \n(%s@%d)", szExpr, szFile, szLine); -// ALERT(at_console, szOut); - } -#endif // DEBUG - -BOOL UTIL_GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ) -{ - return g_pGameRules->GetNextBestWeapon( pPlayer, pCurrentWeapon ); -} - -// ripped this out of the engine -float UTIL_AngleMod(float a) -{ - if (a < 0) - { - a = a + 360 * ((int)(a / 360) + 1); - } - else if (a >= 360) - { - a = a - 360 * ((int)(a / 360)); - } - // a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535); - return a; -} - -float UTIL_AngleDiff( float destAngle, float srcAngle ) -{ - float delta; - - delta = destAngle - srcAngle; - if ( destAngle > srcAngle ) - { - if ( delta >= 180 ) - delta -= 360; - } - else - { - if ( delta <= -180 ) - delta += 360; - } - return delta; -} - -Vector UTIL_VecToAngles( const Vector &vec ) -{ - float rgflVecOut[3]; - VEC_TO_ANGLES(vec, rgflVecOut); - return Vector(rgflVecOut); -} - -// float UTIL_MoveToOrigin( edict_t *pent, const Vector vecGoal, float flDist, int iMoveType ) -void UTIL_MoveToOrigin( edict_t *pent, const Vector &vecGoal, float flDist, int iMoveType ) -{ - float rgfl[3]; - vecGoal.CopyToArray(rgfl); -// return MOVE_TO_ORIGIN ( pent, rgfl, flDist, iMoveType ); - MOVE_TO_ORIGIN ( pent, rgfl, flDist, iMoveType ); -} - - -int UTIL_EntitiesInBox( CBaseEntity **pList, int listMax, const Vector &mins, const Vector &maxs, int flagMask ) -{ - edict_t *pEdict = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - CBaseEntity *pEntity; - int count; - - count = 0; - - if ( !pEdict ) - return count; - - for ( int i = 1; i < gpGlobals->maxEntities; i++, pEdict++ ) - { - if ( pEdict->free ) // Not in use - continue; - - if ( flagMask && !(pEdict->v.flags & flagMask) ) // Does it meet the criteria? - continue; - - if ( mins.x > pEdict->v.absmax.x || - mins.y > pEdict->v.absmax.y || - mins.z > pEdict->v.absmax.z || - maxs.x < pEdict->v.absmin.x || - maxs.y < pEdict->v.absmin.y || - maxs.z < pEdict->v.absmin.z ) - continue; - - pEntity = CBaseEntity::Instance(pEdict); - if ( !pEntity ) - continue; - - pList[ count ] = pEntity; - count++; - - if ( count >= listMax ) - return count; - } - - return count; -} - - -int UTIL_MonstersInSphere( CBaseEntity **pList, int listMax, const Vector ¢er, float radius ) -{ - edict_t *pEdict = g_engfuncs.pfnPEntityOfEntIndex( 1 ); - CBaseEntity *pEntity; - int count; - float distance, delta; - - count = 0; - float radiusSquared = radius * radius; - - if ( !pEdict ) - return count; - - for ( int i = 1; i < gpGlobals->maxEntities; i++, pEdict++ ) - { - if ( pEdict->free ) // Not in use - continue; - - if ( !(pEdict->v.flags & (FL_CLIENT|FL_MONSTER)) ) // Not a client/monster ? - continue; - - // Use origin for X & Y since they are centered for all monsters - // Now X - delta = center.x - pEdict->v.origin.x;//(pEdict->v.absmin.x + pEdict->v.absmax.x)*0.5; - delta *= delta; - - if ( delta > radiusSquared ) - continue; - distance = delta; - - // Now Y - delta = center.y - pEdict->v.origin.y;//(pEdict->v.absmin.y + pEdict->v.absmax.y)*0.5; - delta *= delta; - - distance += delta; - if ( distance > radiusSquared ) - continue; - - // Now Z - delta = center.z - (pEdict->v.absmin.z + pEdict->v.absmax.z)*0.5; - delta *= delta; - - distance += delta; - if ( distance > radiusSquared ) - continue; - - pEntity = CBaseEntity::Instance(pEdict); - if ( !pEntity ) - continue; - - pList[ count ] = pEntity; - count++; - - if ( count >= listMax ) - return count; - } - - - return count; -} - - -CBaseEntity *UTIL_FindEntityInSphere( CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius ) -{ - edict_t *pentEntity; - - if (pStartEntity) - pentEntity = pStartEntity->edict(); - else - pentEntity = NULL; - - pentEntity = FIND_ENTITY_IN_SPHERE( pentEntity, vecCenter, flRadius); - - if (!FNullEnt(pentEntity)) - return CBaseEntity::Instance(pentEntity); - return NULL; -} - - -CBaseEntity *UTIL_FindEntityByString( CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue ) -{ - edict_t *pentEntity; - - if (pStartEntity) - pentEntity = pStartEntity->edict(); - else - pentEntity = NULL; - - pentEntity = FIND_ENTITY_BY_STRING( pentEntity, szKeyword, szValue ); - - if (!FNullEnt(pentEntity)) - return CBaseEntity::Instance(pentEntity); - return NULL; -} - -CBaseEntity *UTIL_FindEntityByClassname( CBaseEntity *pStartEntity, const char *szName ) -{ - return UTIL_FindEntityByString( pStartEntity, "classname", szName ); -} - -CBaseEntity *UTIL_FindEntityByTargetname( CBaseEntity *pStartEntity, const char *szName ) -{ - return UTIL_FindEntityByString( pStartEntity, "targetname", szName ); -} - - -CBaseEntity *UTIL_FindEntityGeneric( const char *szWhatever, Vector &vecSrc, float flRadius ) -{ - CBaseEntity *pEntity = NULL; - - pEntity = UTIL_FindEntityByTargetname( NULL, szWhatever ); - if (pEntity) - return pEntity; - - CBaseEntity *pSearch = NULL; - float flMaxDist2 = flRadius * flRadius; - while ((pSearch = UTIL_FindEntityByClassname( pSearch, szWhatever )) != NULL) - { - float flDist2 = (pSearch->pev->origin - vecSrc).Length(); - flDist2 = flDist2 * flDist2; - if (flMaxDist2 > flDist2) - { - pEntity = pSearch; - flMaxDist2 = flDist2; - } - } - return pEntity; -} - - -// returns a CBaseEntity pointer to a player by index. Only returns if the player is spawned and connected -// otherwise returns NULL -// Index is 1 based -CBaseEntity *UTIL_PlayerByIndex( int playerIndex ) -{ - CBaseEntity *pPlayer = NULL; - - if ( playerIndex > 0 && playerIndex <= gpGlobals->maxClients ) - { - edict_t *pPlayerEdict = INDEXENT( playerIndex ); - if ( pPlayerEdict && !pPlayerEdict->free ) - { - pPlayer = CBaseEntity::Instance( pPlayerEdict ); - } - } - - return pPlayer; -} - - -void UTIL_MakeVectors( const Vector &vecAngles ) -{ - MAKE_VECTORS( vecAngles ); -} - - -void UTIL_MakeAimVectors( const Vector &vecAngles ) -{ - float rgflVec[3]; - vecAngles.CopyToArray(rgflVec); - rgflVec[0] = -rgflVec[0]; - MAKE_VECTORS(rgflVec); -} - - -#define SWAP(a,b,temp) ((temp)=(a),(a)=(b),(b)=(temp)) - -void UTIL_MakeInvVectors( const Vector &vec, globalvars_t *pgv ) -{ - MAKE_VECTORS(vec); - - float tmp; - pgv->v_right = pgv->v_right * -1; - - SWAP(pgv->v_forward.y, pgv->v_right.x, tmp); - SWAP(pgv->v_forward.z, pgv->v_up.x, tmp); - SWAP(pgv->v_right.z, pgv->v_up.y, tmp); -} - - -void UTIL_EmitAmbientSound( edict_t *entity, const Vector &vecOrigin, const char *samp, float vol, float attenuation, int fFlags, int pitch ) -{ - float rgfl[3]; - vecOrigin.CopyToArray(rgfl); - - if (samp && *samp == '!') - { - char name[32]; - if (SENTENCEG_Lookup(samp, name) >= 0) - EMIT_AMBIENT_SOUND(entity, rgfl, name, vol, attenuation, fFlags, pitch); - } - else - EMIT_AMBIENT_SOUND(entity, rgfl, samp, vol, attenuation, fFlags, pitch); -} - -static unsigned short FixedUnsigned16( float value, float scale ) -{ - int output; - - output = value * scale; - if ( output < 0 ) - output = 0; - if ( output > 0xFFFF ) - output = 0xFFFF; - - return (unsigned short)output; -} - -static short FixedSigned16( float value, float scale ) -{ - int output; - - output = value * scale; - - if ( output > 32767 ) - output = 32767; - - if ( output < -32768 ) - output = -32768; - - return (short)output; -} - -// Shake the screen of all clients within radius -// radius == 0, shake all clients -// UNDONE: Allow caller to shake clients not ONGROUND? -// UNDONE: Fix falloff model (disabled)? -// UNDONE: Affect user controls? -void UTIL_ScreenShake( const Vector ¢er, float amplitude, float frequency, float duration, float radius ) -{ - int i; - float localAmplitude; - ScreenShake shake; - - shake.duration = FixedUnsigned16( duration, 1<<12 ); // 4.12 fixed - shake.frequency = FixedUnsigned16( frequency, 1<<8 ); // 8.8 fixed - - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - - if ( !pPlayer || !(pPlayer->pev->flags & FL_ONGROUND) ) // Don't shake if not onground - continue; - - localAmplitude = 0; - - if ( radius <= 0 ) - localAmplitude = amplitude; - else - { - Vector delta = center - pPlayer->pev->origin; - float distance = delta.Length(); - - // Had to get rid of this falloff - it didn't work well - if ( distance < radius ) - localAmplitude = amplitude;//radius - distance; - } - if ( localAmplitude ) - { - shake.amplitude = FixedUnsigned16( localAmplitude, 1<<12 ); // 4.12 fixed - - MESSAGE_BEGIN( MSG_ONE, gmsgShake, NULL, pPlayer->edict() ); // use the magic #1 for "one client" - - WRITE_SHORT( shake.amplitude ); // shake amount - WRITE_SHORT( shake.duration ); // shake lasts this long - WRITE_SHORT( shake.frequency ); // shake noise frequency - - MESSAGE_END(); - } - } -} - - - -void UTIL_ScreenShakeAll( const Vector ¢er, float amplitude, float frequency, float duration ) -{ - UTIL_ScreenShake( center, amplitude, frequency, duration, 0 ); -} - - -void UTIL_ScreenFadeBuild( ScreenFade &fade, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags ) -{ - fade.duration = FixedUnsigned16( fadeTime, 1<<12 ); // 4.12 fixed - fade.holdTime = FixedUnsigned16( fadeHold, 1<<12 ); // 4.12 fixed - fade.r = (int)color.x; - fade.g = (int)color.y; - fade.b = (int)color.z; - fade.a = alpha; - fade.fadeFlags = flags; -} - - -void UTIL_ScreenFadeWrite( const ScreenFade &fade, CBaseEntity *pEntity ) -{ - if ( !pEntity || !pEntity->IsNetClient() ) - return; - - MESSAGE_BEGIN( MSG_ONE, gmsgFade, NULL, pEntity->edict() ); // use the magic #1 for "one client" - - WRITE_SHORT( fade.duration ); // fade lasts this long - WRITE_SHORT( fade.holdTime ); // fade lasts this long - WRITE_SHORT( fade.fadeFlags ); // fade type (in / out) - WRITE_BYTE( fade.r ); // fade red - WRITE_BYTE( fade.g ); // fade green - WRITE_BYTE( fade.b ); // fade blue - WRITE_BYTE( fade.a ); // fade blue - - MESSAGE_END(); -} - - -void UTIL_ScreenFadeAll( const Vector &color, float fadeTime, float fadeHold, int alpha, int flags ) -{ - int i; - ScreenFade fade; - - - UTIL_ScreenFadeBuild( fade, color, fadeTime, fadeHold, alpha, flags ); - - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - - UTIL_ScreenFadeWrite( fade, pPlayer ); - } -} - - -void UTIL_ScreenFade( CBaseEntity *pEntity, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags ) -{ - ScreenFade fade; - - UTIL_ScreenFadeBuild( fade, color, fadeTime, fadeHold, alpha, flags ); - UTIL_ScreenFadeWrite( fade, pEntity ); -} - - -void UTIL_HudMessage( CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage ) -{ - if ( !pEntity || !pEntity->IsNetClient() ) - return; - - MESSAGE_BEGIN( MSG_ONE, SVC_TEMPENTITY, NULL, pEntity->edict() ); - WRITE_BYTE( TE_TEXTMESSAGE ); - WRITE_BYTE( textparms.channel & 0xFF ); - - WRITE_SHORT( FixedSigned16( textparms.x, 1<<13 ) ); - WRITE_SHORT( FixedSigned16( textparms.y, 1<<13 ) ); - WRITE_BYTE( textparms.effect ); - - WRITE_BYTE( textparms.r1 ); - WRITE_BYTE( textparms.g1 ); - WRITE_BYTE( textparms.b1 ); - WRITE_BYTE( textparms.a1 ); - - WRITE_BYTE( textparms.r2 ); - WRITE_BYTE( textparms.g2 ); - WRITE_BYTE( textparms.b2 ); - WRITE_BYTE( textparms.a2 ); - - WRITE_SHORT( FixedUnsigned16( textparms.fadeinTime, 1<<8 ) ); - WRITE_SHORT( FixedUnsigned16( textparms.fadeoutTime, 1<<8 ) ); - WRITE_SHORT( FixedUnsigned16( textparms.holdTime, 1<<8 ) ); - - if ( textparms.effect == 2 ) - WRITE_SHORT( FixedUnsigned16( textparms.fxTime, 1<<8 ) ); - - if ( strlen( pMessage ) < 512 ) - { - WRITE_STRING( pMessage ); - } - else - { - char tmp[512]; - strncpy( tmp, pMessage, 511 ); - tmp[511] = 0; - WRITE_STRING( tmp ); - } - MESSAGE_END(); -} - -void UTIL_HudMessageAll( const hudtextparms_t &textparms, const char *pMessage ) -{ - int i; - - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - if ( pPlayer ) - UTIL_HudMessage( pPlayer, textparms, pMessage ); - } -} - - -extern int gmsgTextMsg, gmsgSayText; -void UTIL_ClientPrintAll( int msg_dest, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) -{ - MESSAGE_BEGIN( MSG_ALL, gmsgTextMsg ); - WRITE_BYTE( msg_dest ); - WRITE_STRING( msg_name ); - - if ( param1 ) - WRITE_STRING( param1 ); - if ( param2 ) - WRITE_STRING( param2 ); - if ( param3 ) - WRITE_STRING( param3 ); - if ( param4 ) - WRITE_STRING( param4 ); - - MESSAGE_END(); -} - -void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name, const char *param1, const char *param2, const char *param3, const char *param4 ) -{ - MESSAGE_BEGIN( MSG_ONE, gmsgTextMsg, NULL, client ); - WRITE_BYTE( msg_dest ); - WRITE_STRING( msg_name ); - - if ( param1 ) - WRITE_STRING( param1 ); - if ( param2 ) - WRITE_STRING( param2 ); - if ( param3 ) - WRITE_STRING( param3 ); - if ( param4 ) - WRITE_STRING( param4 ); - - MESSAGE_END(); -} - -void UTIL_SayText( const char *pText, CBaseEntity *pEntity ) -{ - if ( !pEntity->IsNetClient() ) - return; - - MESSAGE_BEGIN( MSG_ONE, gmsgSayText, NULL, pEntity->edict() ); - WRITE_BYTE( pEntity->entindex() ); - WRITE_STRING( pText ); - MESSAGE_END(); -} - -void UTIL_SayTextAll( const char *pText, CBaseEntity *pEntity ) -{ - MESSAGE_BEGIN( MSG_ALL, gmsgSayText, NULL ); - WRITE_BYTE( pEntity->entindex() ); - WRITE_STRING( pText ); - MESSAGE_END(); -} - - -char *UTIL_dtos1( int d ) -{ - static char buf[8]; - sprintf( buf, "%d", d ); - return buf; -} - -char *UTIL_dtos2( int d ) -{ - static char buf[8]; - sprintf( buf, "%d", d ); - return buf; -} - -char *UTIL_dtos3( int d ) -{ - static char buf[8]; - sprintf( buf, "%d", d ); - return buf; -} - -char *UTIL_dtos4( int d ) -{ - static char buf[8]; - sprintf( buf, "%d", d ); - return buf; -} - -void UTIL_ShowMessage( const char *pString, CBaseEntity *pEntity ) -{ - if ( !pEntity || !pEntity->IsNetClient() ) - return; - - MESSAGE_BEGIN( MSG_ONE, gmsgHudText, NULL, pEntity->edict() ); - WRITE_STRING( pString ); - MESSAGE_END(); -} - - -void UTIL_ShowMessageAll( const char *pString ) -{ - int i; - - // loop through all players - - for ( i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBaseEntity *pPlayer = UTIL_PlayerByIndex( i ); - if ( pPlayer ) - UTIL_ShowMessage( pString, pPlayer ); - } -} - -// Overloaded to add IGNORE_GLASS -void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, IGNORE_GLASS ignoreGlass, edict_t *pentIgnore, TraceResult *ptr ) -{ - TRACE_LINE( vecStart, vecEnd, (igmon == ignore_monsters ? TRUE : FALSE) | (ignoreGlass?0x100:0), pentIgnore, ptr ); -} - - -void UTIL_TraceLine( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr ) -{ - TRACE_LINE( vecStart, vecEnd, (igmon == ignore_monsters ? TRUE : FALSE), pentIgnore, ptr ); -} - - -void UTIL_TraceHull( const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, int hullNumber, edict_t *pentIgnore, TraceResult *ptr ) -{ - TRACE_HULL( vecStart, vecEnd, (igmon == ignore_monsters ? TRUE : FALSE), hullNumber, pentIgnore, ptr ); -} - -void UTIL_TraceModel( const Vector &vecStart, const Vector &vecEnd, int hullNumber, edict_t *pentModel, TraceResult *ptr ) -{ - g_engfuncs.pfnTraceModel( vecStart, vecEnd, hullNumber, pentModel, ptr ); -} - - -TraceResult UTIL_GetGlobalTrace( ) -{ - TraceResult tr; - - tr.fAllSolid = gpGlobals->trace_allsolid; - tr.fStartSolid = gpGlobals->trace_startsolid; - tr.fInOpen = gpGlobals->trace_inopen; - tr.fInWater = gpGlobals->trace_inwater; - tr.flFraction = gpGlobals->trace_fraction; - tr.flPlaneDist = gpGlobals->trace_plane_dist; - tr.pHit = gpGlobals->trace_ent; - tr.vecEndPos = gpGlobals->trace_endpos; - tr.vecPlaneNormal = gpGlobals->trace_plane_normal; - tr.iHitgroup = gpGlobals->trace_hitgroup; - return tr; -} - - -void UTIL_SetSize( entvars_t *pev, const Vector &vecMin, const Vector &vecMax ) -{ - SET_SIZE( ENT(pev), vecMin, vecMax ); -} - - -float UTIL_VecToYaw( const Vector &vec ) -{ - return VEC_TO_YAW(vec); -} - - -void UTIL_SetOrigin( entvars_t *pev, const Vector &vecOrigin ) -{ - SET_ORIGIN(ENT(pev), vecOrigin ); -} - -void UTIL_ParticleEffect( const Vector &vecOrigin, const Vector &vecDirection, ULONG ulColor, ULONG ulCount ) -{ - PARTICLE_EFFECT( vecOrigin, vecDirection, (float)ulColor, (float)ulCount ); -} - - -float UTIL_Approach( float target, float value, float speed ) -{ - float delta = target - value; - - if ( delta > speed ) - value += speed; - else if ( delta < -speed ) - value -= speed; - else - value = target; - - return value; -} - - -float UTIL_ApproachAngle( float target, float value, float speed ) -{ - target = UTIL_AngleMod( target ); - value = UTIL_AngleMod( target ); - - float delta = target - value; - - // Speed is assumed to be positive - if ( speed < 0 ) - speed = -speed; - - if ( delta < -180 ) - delta += 360; - else if ( delta > 180 ) - delta -= 360; - - if ( delta > speed ) - value += speed; - else if ( delta < -speed ) - value -= speed; - else - value = target; - - return value; -} - - -float UTIL_AngleDistance( float next, float cur ) -{ - float delta = next - cur; - - if ( delta < -180 ) - delta += 360; - else if ( delta > 180 ) - delta -= 360; - - return delta; -} - - -float UTIL_SplineFraction( float value, float scale ) -{ - value = scale * value; - float valueSquared = value * value; - - // Nice little ease-in, ease-out spline-like curve - return 3 * valueSquared - 2 * valueSquared * value; -} - - -char* UTIL_VarArgs( char *format, ... ) -{ - va_list argptr; - static char string[1024]; - - va_start (argptr, format); - vsprintf (string, format,argptr); - va_end (argptr); - - return string; -} - -Vector UTIL_GetAimVector( edict_t *pent, float flSpeed ) -{ - Vector tmp; - GET_AIM_VECTOR(pent, flSpeed, tmp); - return tmp; -} - -int UTIL_IsMasterTriggered(string_t sMaster, CBaseEntity *pActivator) -{ - if (sMaster) - { - edict_t *pentTarget = FIND_ENTITY_BY_TARGETNAME(NULL, STRING(sMaster)); - - if ( !FNullEnt(pentTarget) ) - { - CBaseEntity *pMaster = CBaseEntity::Instance(pentTarget); - if ( pMaster && (pMaster->ObjectCaps() & FCAP_MASTER) ) - return pMaster->IsTriggered( pActivator ); - } - - ALERT(at_console, "Master was null or not a master!\n"); - } - - // if this isn't a master entity, just say yes. - return 1; -} - -BOOL UTIL_ShouldShowBlood( int color ) -{ - if ( color != DONT_BLEED ) - { - if ( color == BLOOD_COLOR_RED ) - { - if ( CVAR_GET_FLOAT("violence_hblood") != 0 ) - return TRUE; - } - else - { - if ( CVAR_GET_FLOAT("violence_ablood") != 0 ) - return TRUE; - } - } - return FALSE; -} - -int UTIL_PointContents( const Vector &vec ) -{ - return POINT_CONTENTS(vec); -} - -void UTIL_BloodStream( const Vector &origin, const Vector &direction, int color, int amount ) -{ - if ( !UTIL_ShouldShowBlood( color ) ) - return; - - if ( g_Language == LANGUAGE_GERMAN && color == BLOOD_COLOR_RED ) - color = 0; - - - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, origin ); - WRITE_BYTE( TE_BLOODSTREAM ); - WRITE_COORD( origin.x ); - WRITE_COORD( origin.y ); - WRITE_COORD( origin.z ); - WRITE_COORD( direction.x ); - WRITE_COORD( direction.y ); - WRITE_COORD( direction.z ); - WRITE_BYTE( color ); - WRITE_BYTE( V_min( amount, 255 ) ); - MESSAGE_END(); -} - -void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ) -{ - if ( !UTIL_ShouldShowBlood( color ) ) - return; - - if ( color == DONT_BLEED || amount == 0 ) - return; - - if ( g_Language == LANGUAGE_GERMAN && color == BLOOD_COLOR_RED ) - color = 0; - - if ( g_pGameRules->IsMultiplayer() ) - { - // scale up blood effect in multiplayer for better visibility - amount *= 2; - } - - if ( amount > 255 ) - amount = 255; - - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, origin ); - WRITE_BYTE( TE_BLOODSPRITE ); - WRITE_COORD( origin.x); // pos - WRITE_COORD( origin.y); - WRITE_COORD( origin.z); - WRITE_SHORT( g_sModelIndexBloodSpray ); // initial sprite model - WRITE_SHORT( g_sModelIndexBloodDrop ); // droplet sprite models - WRITE_BYTE( color ); // color index into host_basepal - WRITE_BYTE( V_min( V_max( 3, amount / 10 ), 16 ) ); // size - MESSAGE_END(); -} - -Vector UTIL_RandomBloodVector( void ) -{ - Vector direction; - - direction.x = RANDOM_FLOAT ( -1, 1 ); - direction.y = RANDOM_FLOAT ( -1, 1 ); - direction.z = RANDOM_FLOAT ( 0, 1 ); - - return direction; -} - - -void UTIL_BloodDecalTrace( TraceResult *pTrace, int bloodColor ) -{ - if ( UTIL_ShouldShowBlood( bloodColor ) ) - { - if ( bloodColor == BLOOD_COLOR_RED ) - UTIL_DecalTrace( pTrace, DECAL_BLOOD1 + RANDOM_LONG(0,5) ); - else - UTIL_DecalTrace( pTrace, DECAL_YBLOOD1 + RANDOM_LONG(0,5) ); - } -} - - -void UTIL_DecalTrace( TraceResult *pTrace, int decalNumber ) -{ - short entityIndex; - int index; - int message; - - if ( decalNumber < 0 ) - return; - - index = gDecals[ decalNumber ].index; - - if ( index < 0 ) - return; - - if (pTrace->flFraction == 1.0) - return; - - // Only decal BSP models - if ( pTrace->pHit ) - { - CBaseEntity *pEntity = CBaseEntity::Instance( pTrace->pHit ); - if ( pEntity && !pEntity->IsBSPModel() ) - return; - entityIndex = ENTINDEX( pTrace->pHit ); - } - else - entityIndex = 0; - - message = TE_DECAL; - if ( entityIndex != 0 ) - { - if ( index > 255 ) - { - message = TE_DECALHIGH; - index -= 256; - } - } - else - { - message = TE_WORLDDECAL; - if ( index > 255 ) - { - message = TE_WORLDDECALHIGH; - index -= 256; - } - } - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( message ); - WRITE_COORD( pTrace->vecEndPos.x ); - WRITE_COORD( pTrace->vecEndPos.y ); - WRITE_COORD( pTrace->vecEndPos.z ); - WRITE_BYTE( index ); - if ( entityIndex ) - WRITE_SHORT( entityIndex ); - MESSAGE_END(); -} - -/* -============== -UTIL_PlayerDecalTrace - -A player is trying to apply his custom decal for the spray can. -Tell connected clients to display it, or use the default spray can decal -if the custom can't be loaded. -============== -*/ -void UTIL_PlayerDecalTrace( TraceResult *pTrace, int playernum, int decalNumber, BOOL bIsCustom ) -{ - int index; - - if (!bIsCustom) - { - if ( decalNumber < 0 ) - return; - - index = gDecals[ decalNumber ].index; - if ( index < 0 ) - return; - } - else - index = decalNumber; - - if (pTrace->flFraction == 1.0) - return; - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_PLAYERDECAL ); - WRITE_BYTE ( playernum ); - WRITE_COORD( pTrace->vecEndPos.x ); - WRITE_COORD( pTrace->vecEndPos.y ); - WRITE_COORD( pTrace->vecEndPos.z ); - WRITE_SHORT( (short)ENTINDEX(pTrace->pHit) ); - WRITE_BYTE( index ); - MESSAGE_END(); -} - -void UTIL_GunshotDecalTrace( TraceResult *pTrace, int decalNumber ) -{ - if ( decalNumber < 0 ) - return; - - int index = gDecals[ decalNumber ].index; - if ( index < 0 ) - return; - - if (pTrace->flFraction == 1.0) - return; - - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pTrace->vecEndPos ); - WRITE_BYTE( TE_GUNSHOTDECAL ); - WRITE_COORD( pTrace->vecEndPos.x ); - WRITE_COORD( pTrace->vecEndPos.y ); - WRITE_COORD( pTrace->vecEndPos.z ); - WRITE_SHORT( (short)ENTINDEX(pTrace->pHit) ); - WRITE_BYTE( index ); - MESSAGE_END(); -} - - -void UTIL_Sparks( const Vector &position, edict_t * ed ) -{ -// MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, position ); -// WRITE_BYTE( TE_SPARKS ); -// WRITE_COORD( position.x ); -// WRITE_COORD( position.y ); -// WRITE_COORD( position.z ); -// MESSAGE_END(); - - for ( int i = 1; i <= gpGlobals->maxClients; i++ ) - { - CBasePlayer * pPlayer = (CBasePlayer *)UTIL_PlayerByIndex( i ); - - if ( - pPlayer && - ( pPlayer->m_bHasDisconnected != TRUE ) && - ( !ed || ( pPlayer->pev->groupinfo & VARS(ed)->groupinfo ) ) - ) - { - MESSAGE_BEGIN( MSG_ONE, SVC_TEMPENTITY, position, pPlayer->edict() ); - WRITE_BYTE( TE_SPARKS ); - WRITE_COORD( position.x ); - WRITE_COORD( position.y ); - WRITE_COORD( position.z ); - MESSAGE_END(); - } - } -} - - -void UTIL_Ricochet( const Vector &position, float scale ) -{ - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, position ); - WRITE_BYTE( TE_ARMOR_RICOCHET ); - WRITE_COORD( position.x ); - WRITE_COORD( position.y ); - WRITE_COORD( position.z ); - WRITE_BYTE( (int)(scale*10) ); - MESSAGE_END(); -} - - -BOOL UTIL_TeamsMatch( const char *pTeamName1, const char *pTeamName2 ) -{ - // Everyone matches unless it's teamplay - if ( !g_pGameRules->IsTeamplay() ) - return TRUE; - - // Both on a team? - if ( *pTeamName1 != 0 && *pTeamName2 != 0 ) - { - if ( !stricmp( pTeamName1, pTeamName2 ) ) // Same Team? - return TRUE; - } - - return FALSE; -} - - -void UTIL_StringToVector( float *pVector, const char *pString ) -{ - char *pstr, *pfront, tempString[128]; - int j; - - strcpy( tempString, pString ); - pstr = pfront = tempString; - - for ( j = 0; j < 3; j++ ) // lifted from pr_edict.c - { - pVector[j] = atof( pfront ); - - while ( *pstr && *pstr != ' ' ) - pstr++; - if (!*pstr) - break; - pstr++; - pfront = pstr; - } - if (j < 2) - { - /* - ALERT( at_error, "Bad field in entity!! %s:%s == \"%s\"\n", - pkvd->szClassName, pkvd->szKeyName, pkvd->szValue ); - */ - for (j = j+1;j < 3; j++) - pVector[j] = 0; - } -} - - -void UTIL_StringToIntArray( int *pVector, int count, const char *pString ) -{ - char *pstr, *pfront, tempString[128]; - int j; - - strcpy( tempString, pString ); - pstr = pfront = tempString; - - for ( j = 0; j < count; j++ ) // lifted from pr_edict.c - { - pVector[j] = atoi( pfront ); - - while ( *pstr && *pstr != ' ' ) - pstr++; - if (!*pstr) - break; - pstr++; - pfront = pstr; - } - - for ( j++; j < count; j++ ) - { - pVector[j] = 0; - } -} - -Vector UTIL_ClampVectorToBox( const Vector &input, const Vector &clampSize ) -{ - Vector sourceVector = input; - - if ( sourceVector.x > clampSize.x ) - sourceVector.x -= clampSize.x; - else if ( sourceVector.x < -clampSize.x ) - sourceVector.x += clampSize.x; - else - sourceVector.x = 0; - - if ( sourceVector.y > clampSize.y ) - sourceVector.y -= clampSize.y; - else if ( sourceVector.y < -clampSize.y ) - sourceVector.y += clampSize.y; - else - sourceVector.y = 0; - - if ( sourceVector.z > clampSize.z ) - sourceVector.z -= clampSize.z; - else if ( sourceVector.z < -clampSize.z ) - sourceVector.z += clampSize.z; - else - sourceVector.z = 0; - - return sourceVector.Normalize(); -} - - -float UTIL_WaterLevel( const Vector &position, float minz, float maxz ) -{ - Vector midUp = position; - midUp.z = minz; - - if (UTIL_PointContents(midUp) != CONTENTS_WATER) - return minz; - - midUp.z = maxz; - if (UTIL_PointContents(midUp) == CONTENTS_WATER) - return maxz; - - float diff = maxz - minz; - while (diff > 1.0) - { - midUp.z = minz + diff/2.0; - if (UTIL_PointContents(midUp) == CONTENTS_WATER) - { - minz = midUp.z; - } - else - { - maxz = midUp.z; - } - diff = maxz - minz; - } - - return midUp.z; -} - - -extern DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model - -void UTIL_Bubbles( Vector mins, Vector maxs, int count ) -{ - Vector mid = (mins + maxs) * 0.5; - - float flHeight = UTIL_WaterLevel( mid, mid.z, mid.z + 1024 ); - flHeight = flHeight - mins.z; - - MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, mid ); - WRITE_BYTE( TE_BUBBLES ); - WRITE_COORD( mins.x ); // mins - WRITE_COORD( mins.y ); - WRITE_COORD( mins.z ); - WRITE_COORD( maxs.x ); // maxz - WRITE_COORD( maxs.y ); - WRITE_COORD( maxs.z ); - WRITE_COORD( flHeight ); // height - WRITE_SHORT( g_sModelIndexBubbles ); - WRITE_BYTE( count ); // count - WRITE_COORD( 8 ); // speed - MESSAGE_END(); -} - -void UTIL_BubbleTrail( Vector from, Vector to, int count ) -{ - float flHeight = UTIL_WaterLevel( from, from.z, from.z + 256 ); - flHeight = flHeight - from.z; - - if (flHeight < 8) - { - flHeight = UTIL_WaterLevel( to, to.z, to.z + 256 ); - flHeight = flHeight - to.z; - if (flHeight < 8) - return; - - // UNDONE: do a ploink sound - flHeight = flHeight + to.z - from.z; - } - - if (count > 255) - count = 255; - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_BUBBLETRAIL ); - WRITE_COORD( from.x ); // mins - WRITE_COORD( from.y ); - WRITE_COORD( from.z ); - WRITE_COORD( to.x ); // maxz - WRITE_COORD( to.y ); - WRITE_COORD( to.z ); - WRITE_COORD( flHeight ); // height - WRITE_SHORT( g_sModelIndexBubbles ); - WRITE_BYTE( count ); // count - WRITE_COORD( 8 ); // speed - MESSAGE_END(); -} - - -void UTIL_Remove( CBaseEntity *pEntity ) -{ - if ( !pEntity ) - return; - - pEntity->UpdateOnRemove(); - pEntity->pev->flags |= FL_KILLME; - pEntity->pev->targetname = 0; -} - - -BOOL UTIL_IsValidEntity( edict_t *pent ) -{ - if ( !pent || pent->free || (pent->v.flags & FL_KILLME) ) - return FALSE; - return TRUE; -} - - -void UTIL_PrecacheOther( const char *szClassname ) -{ - edict_t *pent; - - pent = CREATE_NAMED_ENTITY( MAKE_STRING( szClassname ) ); - if ( FNullEnt( pent ) ) - { - ALERT ( at_console, "NULL Ent in UTIL_PrecacheOther\n" ); - return; - } - - CBaseEntity *pEntity = CBaseEntity::Instance (VARS( pent )); - if (pEntity) - pEntity->Precache( ); - REMOVE_ENTITY(pent); -} - -//========================================================= -// UTIL_LogPrintf - Prints a logged message to console. -// Preceded by LOG: ( timestamp ) < message > -//========================================================= -void UTIL_LogPrintf( char *fmt, ... ) -{ - va_list argptr; - static char string[1024]; - - va_start ( argptr, fmt ); - vsprintf ( string, fmt, argptr ); - va_end ( argptr ); - - // Print to server console - ALERT( at_logged, "%s", string ); -} - -//========================================================= -// UTIL_DotPoints - returns the dot product of a line from -// src to check and vecdir. -//========================================================= -float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ) -{ - Vector2D vec2LOS; - - vec2LOS = ( vecCheck - vecSrc ).Make2D(); - vec2LOS = vec2LOS.Normalize(); - - return DotProduct (vec2LOS , ( vecDir.Make2D() ) ); -} - - -//========================================================= -// UTIL_StripToken - for redundant keynames -//========================================================= -void UTIL_StripToken( const char *pKey, char *pDest ) -{ - int i = 0; - - while ( pKey[i] && pKey[i] != '#' ) - { - pDest[i] = pKey[i]; - i++; - } - pDest[i] = 0; -} - - -// -------------------------------------------------------------- -// -// CSave -// -// -------------------------------------------------------------- -static int gSizes[FIELD_TYPECOUNT] = -{ - sizeof(float), // FIELD_FLOAT - sizeof(int), // FIELD_STRING - sizeof(int), // FIELD_ENTITY - sizeof(int), // FIELD_CLASSPTR - sizeof(int), // FIELD_EHANDLE - sizeof(int), // FIELD_entvars_t - sizeof(int), // FIELD_EDICT - sizeof(float)*3, // FIELD_VECTOR - sizeof(float)*3, // FIELD_POSITION_VECTOR - sizeof(int *), // FIELD_POINTER - sizeof(int), // FIELD_INTEGER - sizeof(int *), // FIELD_FUNCTION - sizeof(int), // FIELD_BOOLEAN - sizeof(short), // FIELD_SHORT - sizeof(char), // FIELD_CHARACTER - sizeof(float), // FIELD_TIME - sizeof(int), // FIELD_MODELNAME - sizeof(int), // FIELD_SOUNDNAME -}; - - -// Base class includes common SAVERESTOREDATA pointer, and manages the entity table -CSaveRestoreBuffer :: CSaveRestoreBuffer( void ) -{ - m_pdata = NULL; -} - - -CSaveRestoreBuffer :: CSaveRestoreBuffer( SAVERESTOREDATA *pdata ) -{ - m_pdata = pdata; -} - - -CSaveRestoreBuffer :: ~CSaveRestoreBuffer( void ) -{ -} - -int CSaveRestoreBuffer :: EntityIndex( CBaseEntity *pEntity ) -{ - if ( pEntity == NULL ) - return -1; - return EntityIndex( pEntity->pev ); -} - - -int CSaveRestoreBuffer :: EntityIndex( entvars_t *pevLookup ) -{ - if ( pevLookup == NULL ) - return -1; - return EntityIndex( ENT( pevLookup ) ); -} - -int CSaveRestoreBuffer :: EntityIndex( EOFFSET eoLookup ) -{ - return EntityIndex( ENT( eoLookup ) ); -} - - -int CSaveRestoreBuffer :: EntityIndex( edict_t *pentLookup ) -{ - if ( !m_pdata || pentLookup == NULL ) - return -1; - - int i; - ENTITYTABLE *pTable; - - for ( i = 0; i < m_pdata->tableCount; i++ ) - { - pTable = m_pdata->pTable + i; - if ( pTable->pent == pentLookup ) - return i; - } - return -1; -} - - -edict_t *CSaveRestoreBuffer :: EntityFromIndex( int entityIndex ) -{ - if ( !m_pdata || entityIndex < 0 ) - return NULL; - - int i; - ENTITYTABLE *pTable; - - for ( i = 0; i < m_pdata->tableCount; i++ ) - { - pTable = m_pdata->pTable + i; - if ( pTable->id == entityIndex ) - return pTable->pent; - } - return NULL; -} - - -int CSaveRestoreBuffer :: EntityFlagsSet( int entityIndex, int flags ) -{ - if ( !m_pdata || entityIndex < 0 ) - return 0; - if ( entityIndex > m_pdata->tableCount ) - return 0; - - m_pdata->pTable[ entityIndex ].flags |= flags; - - return m_pdata->pTable[ entityIndex ].flags; -} - - -void CSaveRestoreBuffer :: BufferRewind( int size ) -{ - if ( !m_pdata ) - return; - - if ( m_pdata->size < size ) - size = m_pdata->size; - - m_pdata->pCurrentData -= size; - m_pdata->size -= size; -} - -#ifndef _WIN32 -extern "C" { -unsigned _rotr ( unsigned val, int shift) -{ - register unsigned lobit; /* non-zero means lo bit set */ - register unsigned num = val; /* number to rotate */ - - shift &= 0x1f; /* modulo 32 -- this will also make - negative shifts work */ - - while (shift--) { - lobit = num & 1; /* get high bit */ - num >>= 1; /* shift right one bit */ - if (lobit) - num |= 0x80000000; /* set hi bit if lo bit was set */ - } - - return num; -} -} -#endif - -unsigned int CSaveRestoreBuffer :: HashString( const char *pszToken ) -{ - unsigned int hash = 0; - - while ( *pszToken ) - hash = _rotr( hash, 4 ) ^ *pszToken++; - - return hash; -} - -unsigned short CSaveRestoreBuffer :: TokenHash( const char *pszToken ) -{ - unsigned short hash = (unsigned short)(HashString( pszToken ) % (unsigned)m_pdata->tokenCount ); - -#if _DEBUG - static int tokensparsed = 0; - tokensparsed++; - if ( !m_pdata->tokenCount || !m_pdata->pTokens ) - ALERT( at_error, "No token table array in TokenHash()!" ); -#endif - - for ( int i=0; itokenCount; i++ ) - { -#if _DEBUG - static qboolean beentheredonethat = FALSE; - if ( i > 50 && !beentheredonethat ) - { - beentheredonethat = TRUE; - ALERT( at_error, "CSaveRestoreBuffer :: TokenHash() is getting too full!" ); - } -#endif - - int index = hash + i; - if ( index >= m_pdata->tokenCount ) - index -= m_pdata->tokenCount; - - if ( !m_pdata->pTokens[index] || strcmp( pszToken, m_pdata->pTokens[index] ) == 0 ) - { - m_pdata->pTokens[index] = (char *)pszToken; - return index; - } - } - - // Token hash table full!!! - // [Consider doing overflow table(s) after the main table & limiting linear hash table search] - ALERT( at_error, "CSaveRestoreBuffer :: TokenHash() is COMPLETELY FULL!" ); - return 0; -} - -void CSave :: WriteData( const char *pname, int size, const char *pdata ) -{ - BufferField( pname, size, pdata ); -} - - -void CSave :: WriteShort( const char *pname, const short *data, int count ) -{ - BufferField( pname, sizeof(short) * count, (const char *)data ); -} - - -void CSave :: WriteInt( const char *pname, const int *data, int count ) -{ - BufferField( pname, sizeof(int) * count, (const char *)data ); -} - - -void CSave :: WriteFloat( const char *pname, const float *data, int count ) -{ - BufferField( pname, sizeof(float) * count, (const char *)data ); -} - - -void CSave :: WriteTime( const char *pname, const float *data, int count ) -{ - int i; - Vector tmp, input; - - BufferHeader( pname, sizeof(float) * count ); - for ( i = 0; i < count; i++ ) - { - float tmp = data[0]; - - // Always encode time as a delta from the current time so it can be re-based if loaded in a new level - // Times of 0 are never written to the file, so they will be restored as 0, not a relative time - if ( m_pdata ) - tmp -= m_pdata->time; - - BufferData( (const char *)&tmp, sizeof(float) ); - data ++; - } -} - - -void CSave :: WriteString( const char *pname, const char *pdata ) -{ -#ifdef TOKENIZE - short token = (short)TokenHash( pdata ); - WriteShort( pname, &token, 1 ); -#else - BufferField( pname, strlen(pdata) + 1, pdata ); -#endif -} - - -void CSave :: WriteString( const char *pname, const int *stringId, int count ) -{ - int i, size; - -#ifdef TOKENIZE - short token = (short)TokenHash( STRING( *stringId ) ); - WriteShort( pname, &token, 1 ); -#else -#if 0 - if ( count != 1 ) - ALERT( at_error, "No string arrays!\n" ); - WriteString( pname, (char *)STRING(*stringId) ); -#endif - - size = 0; - for ( i = 0; i < count; i++ ) - size += strlen( STRING( stringId[i] ) ) + 1; - - BufferHeader( pname, size ); - for ( i = 0; i < count; i++ ) - { - const char *pString = STRING(stringId[i]); - BufferData( pString, strlen(pString)+1 ); - } -#endif -} - - -void CSave :: WriteVector( const char *pname, const Vector &value ) -{ - WriteVector( pname, &value.x, 1 ); -} - - -void CSave :: WriteVector( const char *pname, const float *value, int count ) -{ - BufferHeader( pname, sizeof(float) * 3 * count ); - BufferData( (const char *)value, sizeof(float) * 3 * count ); -} - - - -void CSave :: WritePositionVector( const char *pname, const Vector &value ) -{ - - if ( m_pdata && m_pdata->fUseLandmark ) - { - Vector tmp = value - m_pdata->vecLandmarkOffset; - WriteVector( pname, tmp ); - } - - WriteVector( pname, value ); -} - - -void CSave :: WritePositionVector( const char *pname, const float *value, int count ) -{ - int i; - Vector tmp, input; - - BufferHeader( pname, sizeof(float) * 3 * count ); - for ( i = 0; i < count; i++ ) - { - Vector tmp( value[0], value[1], value[2] ); - - if ( m_pdata && m_pdata->fUseLandmark ) - tmp = tmp - m_pdata->vecLandmarkOffset; - - BufferData( (const char *)&tmp.x, sizeof(float) * 3 ); - value += 3; - } -} - - -void CSave :: WriteFunction( const char *pname, void **data, int count ) -{ - const char *functionName; - - functionName = NAME_FOR_FUNCTION( (uint32)*data ); - if ( functionName ) - BufferField( pname, strlen(functionName) + 1, functionName ); - else - ALERT( at_error, "Invalid function pointer in entity!" ); -} - - -void EntvarsKeyvalue( entvars_t *pev, KeyValueData *pkvd ) -{ - int i; - TYPEDESCRIPTION *pField; - - for ( i = 0; i < ENTVARS_COUNT; i++ ) - { - pField = &gEntvarsDescription[i]; - - if ( !stricmp( pField->fieldName, pkvd->szKeyName ) ) - { - switch( pField->fieldType ) - { - case FIELD_MODELNAME: - case FIELD_SOUNDNAME: - case FIELD_STRING: - (*(int *)((char *)pev + pField->fieldOffset)) = ALLOC_STRING( pkvd->szValue ); - break; - - case FIELD_TIME: - case FIELD_FLOAT: - (*(float *)((char *)pev + pField->fieldOffset)) = atof( pkvd->szValue ); - break; - - case FIELD_INTEGER: - (*(int *)((char *)pev + pField->fieldOffset)) = atoi( pkvd->szValue ); - break; - - case FIELD_POSITION_VECTOR: - case FIELD_VECTOR: - UTIL_StringToVector( (float *)((char *)pev + pField->fieldOffset), pkvd->szValue ); - break; - - default: - case FIELD_EVARS: - case FIELD_CLASSPTR: - case FIELD_EDICT: - case FIELD_ENTITY: - case FIELD_POINTER: - ALERT( at_error, "Bad field in entity!!\n" ); - break; - } - pkvd->fHandled = TRUE; - return; - } - } -} - - - -int CSave :: WriteEntVars( const char *pname, entvars_t *pev ) -{ - return WriteFields( pname, pev, gEntvarsDescription, ENTVARS_COUNT ); -} - - - -int CSave :: WriteFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ) -{ - int i, j, actualCount, emptyCount; - TYPEDESCRIPTION *pTest; - int entityArray[MAX_ENTITYARRAY]; - - // Precalculate the number of empty fields - emptyCount = 0; - for ( i = 0; i < fieldCount; i++ ) - { - void *pOutputData; - pOutputData = ((char *)pBaseData + pFields[i].fieldOffset ); - if ( DataEmpty( (const char *)pOutputData, pFields[i].fieldSize * gSizes[pFields[i].fieldType] ) ) - emptyCount++; - } - - // Empty fields will not be written, write out the actual number of fields to be written - actualCount = fieldCount - emptyCount; - WriteInt( pname, &actualCount, 1 ); - - for ( i = 0; i < fieldCount; i++ ) - { - void *pOutputData; - pTest = &pFields[ i ]; - pOutputData = ((char *)pBaseData + pTest->fieldOffset ); - - // UNDONE: Must we do this twice? - if ( DataEmpty( (const char *)pOutputData, pTest->fieldSize * gSizes[pTest->fieldType] ) ) - continue; - - switch( pTest->fieldType ) - { - case FIELD_FLOAT: - WriteFloat( pTest->fieldName, (float *)pOutputData, pTest->fieldSize ); - break; - case FIELD_TIME: - WriteTime( pTest->fieldName, (float *)pOutputData, pTest->fieldSize ); - break; - case FIELD_MODELNAME: - case FIELD_SOUNDNAME: - case FIELD_STRING: - WriteString( pTest->fieldName, (int *)pOutputData, pTest->fieldSize ); - break; - case FIELD_CLASSPTR: - case FIELD_EVARS: - case FIELD_EDICT: - case FIELD_ENTITY: - case FIELD_EHANDLE: - if ( pTest->fieldSize > MAX_ENTITYARRAY ) - ALERT( at_error, "Can't save more than %d entities in an array!!!\n", MAX_ENTITYARRAY ); - for ( j = 0; j < pTest->fieldSize; j++ ) - { - switch( pTest->fieldType ) - { - case FIELD_EVARS: - entityArray[j] = EntityIndex( ((entvars_t **)pOutputData)[j] ); - break; - case FIELD_CLASSPTR: - entityArray[j] = EntityIndex( ((CBaseEntity **)pOutputData)[j] ); - break; - case FIELD_EDICT: - entityArray[j] = EntityIndex( ((edict_t **)pOutputData)[j] ); - break; - case FIELD_ENTITY: - entityArray[j] = EntityIndex( ((EOFFSET *)pOutputData)[j] ); - break; - case FIELD_EHANDLE: - entityArray[j] = EntityIndex( (CBaseEntity *)(((EHANDLE *)pOutputData)[j]) ); - break; - } - } - WriteInt( pTest->fieldName, entityArray, pTest->fieldSize ); - break; - case FIELD_POSITION_VECTOR: - WritePositionVector( pTest->fieldName, (float *)pOutputData, pTest->fieldSize ); - break; - case FIELD_VECTOR: - WriteVector( pTest->fieldName, (float *)pOutputData, pTest->fieldSize ); - break; - - case FIELD_BOOLEAN: - case FIELD_INTEGER: - WriteInt( pTest->fieldName, (int *)pOutputData, pTest->fieldSize ); - break; - - case FIELD_SHORT: - WriteData( pTest->fieldName, 2 * pTest->fieldSize, ((char *)pOutputData) ); - break; - - case FIELD_CHARACTER: - WriteData( pTest->fieldName, pTest->fieldSize, ((char *)pOutputData) ); - break; - - // For now, just write the address out, we're not going to change memory while doing this yet! - case FIELD_POINTER: - WriteInt( pTest->fieldName, (int *)(char *)pOutputData, pTest->fieldSize ); - break; - - case FIELD_FUNCTION: - WriteFunction( pTest->fieldName, (void **)pOutputData, pTest->fieldSize ); - break; - default: - ALERT( at_error, "Bad field type\n" ); - } - } - - return 1; -} - - -void CSave :: BufferString( char *pdata, int len ) -{ - char c = 0; - - BufferData( pdata, len ); // Write the string - BufferData( &c, 1 ); // Write a null terminator -} - - -int CSave :: DataEmpty( const char *pdata, int size ) -{ - for ( int i = 0; i < size; i++ ) - { - if ( pdata[i] ) - return 0; - } - return 1; -} - - -void CSave :: BufferField( const char *pname, int size, const char *pdata ) -{ - BufferHeader( pname, size ); - BufferData( pdata, size ); -} - - -void CSave :: BufferHeader( const char *pname, int size ) -{ - short hashvalue = TokenHash( pname ); - if ( size > 1<<(sizeof(short)*8) ) - ALERT( at_error, "CSave :: BufferHeader() size parameter exceeds 'short'!" ); - BufferData( (const char *)&size, sizeof(short) ); - BufferData( (const char *)&hashvalue, sizeof(short) ); -} - - -void CSave :: BufferData( const char *pdata, int size ) -{ - if ( !m_pdata ) - return; - - if ( m_pdata->size + size > m_pdata->bufferSize ) - { - ALERT( at_error, "Save/Restore overflow!" ); - m_pdata->size = m_pdata->bufferSize; - return; - } - - memcpy( m_pdata->pCurrentData, pdata, size ); - m_pdata->pCurrentData += size; - m_pdata->size += size; -} - - - -// -------------------------------------------------------------- -// -// CRestore -// -// -------------------------------------------------------------- - -int CRestore::ReadField( void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount, int startField, int size, char *pName, void *pData ) -{ - int i, j, stringCount, fieldNumber, entityIndex; - TYPEDESCRIPTION *pTest; - float time, timeData; - Vector position; - edict_t *pent; - char *pString; - - time = 0; - position = Vector(0,0,0); - - if ( m_pdata ) - { - time = m_pdata->time; - if ( m_pdata->fUseLandmark ) - position = m_pdata->vecLandmarkOffset; - } - - for ( i = 0; i < fieldCount; i++ ) - { - fieldNumber = (i+startField)%fieldCount; - pTest = &pFields[ fieldNumber ]; - if ( !stricmp( pTest->fieldName, pName ) ) - { - if ( !m_global || !(pTest->flags & FTYPEDESC_GLOBAL) ) - { - for ( j = 0; j < pTest->fieldSize; j++ ) - { - void *pOutputData = ((char *)pBaseData + pTest->fieldOffset + (j*gSizes[pTest->fieldType]) ); - void *pInputData = (char *)pData + j * gSizes[pTest->fieldType]; - - switch( pTest->fieldType ) - { - case FIELD_TIME: - timeData = *(float *)pInputData; - // Re-base time variables - timeData += time; - *((float *)pOutputData) = timeData; - break; - case FIELD_FLOAT: - *((float *)pOutputData) = *(float *)pInputData; - break; - case FIELD_MODELNAME: - case FIELD_SOUNDNAME: - case FIELD_STRING: - // Skip over j strings - pString = (char *)pData; - for ( stringCount = 0; stringCount < j; stringCount++ ) - { - while (*pString) - pString++; - pString++; - } - pInputData = pString; - if ( strlen( (char *)pInputData ) == 0 ) - *((int *)pOutputData) = 0; - else - { - int string; - - string = ALLOC_STRING( (char *)pInputData ); - - *((int *)pOutputData) = string; - - if ( !FStringNull( string ) && m_precache ) - { - if ( pTest->fieldType == FIELD_MODELNAME ) - PRECACHE_MODEL( (char *)STRING( string ) ); - else if ( pTest->fieldType == FIELD_SOUNDNAME ) - PRECACHE_SOUND( (char *)STRING( string ) ); - } - } - break; - case FIELD_EVARS: - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - if ( pent ) - *((entvars_t **)pOutputData) = VARS(pent); - else - *((entvars_t **)pOutputData) = NULL; - break; - case FIELD_CLASSPTR: - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - if ( pent ) - *((CBaseEntity **)pOutputData) = CBaseEntity::Instance(pent); - else - *((CBaseEntity **)pOutputData) = NULL; - break; - case FIELD_EDICT: - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - *((edict_t **)pOutputData) = pent; - break; - case FIELD_EHANDLE: - // Input and Output sizes are different! - pOutputData = (char *)pOutputData + j*(sizeof(EHANDLE) - gSizes[pTest->fieldType]); - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - if ( pent ) - *((EHANDLE *)pOutputData) = CBaseEntity::Instance(pent); - else - *((EHANDLE *)pOutputData) = NULL; - break; - case FIELD_ENTITY: - entityIndex = *( int *)pInputData; - pent = EntityFromIndex( entityIndex ); - if ( pent ) - *((EOFFSET *)pOutputData) = OFFSET(pent); - else - *((EOFFSET *)pOutputData) = 0; - break; - case FIELD_VECTOR: - ((float *)pOutputData)[0] = ((float *)pInputData)[0]; - ((float *)pOutputData)[1] = ((float *)pInputData)[1]; - ((float *)pOutputData)[2] = ((float *)pInputData)[2]; - break; - case FIELD_POSITION_VECTOR: - ((float *)pOutputData)[0] = ((float *)pInputData)[0] + position.x; - ((float *)pOutputData)[1] = ((float *)pInputData)[1] + position.y; - ((float *)pOutputData)[2] = ((float *)pInputData)[2] + position.z; - break; - - case FIELD_BOOLEAN: - case FIELD_INTEGER: - *((int *)pOutputData) = *( int *)pInputData; - break; - - case FIELD_SHORT: - *((short *)pOutputData) = *( short *)pInputData; - break; - - case FIELD_CHARACTER: - *((char *)pOutputData) = *( char *)pInputData; - break; - - case FIELD_POINTER: - *((int *)pOutputData) = *( int *)pInputData; - break; - case FIELD_FUNCTION: - if ( strlen( (char *)pInputData ) == 0 ) - *((int *)pOutputData) = 0; - else - *((int *)pOutputData) = FUNCTION_FROM_NAME( (char *)pInputData ); - break; - - default: - ALERT( at_error, "Bad field type\n" ); - } - } - } -#if 0 - else - { - ALERT( at_console, "Skipping global field %s\n", pName ); - } -#endif - return fieldNumber; - } - } - - return -1; -} - - -int CRestore::ReadEntVars( const char *pname, entvars_t *pev ) -{ - return ReadFields( pname, pev, gEntvarsDescription, ENTVARS_COUNT ); -} - - -int CRestore::ReadFields( const char *pname, void *pBaseData, TYPEDESCRIPTION *pFields, int fieldCount ) -{ - unsigned short i, token; - int lastField, fileCount; - HEADER header; - - i = ReadShort(); - ASSERT( i == sizeof(int) ); // First entry should be an int - - token = ReadShort(); - - // Check the struct name - if ( token != TokenHash(pname) ) // Field Set marker - { -// ALERT( at_error, "Expected %s found %s!\n", pname, BufferPointer() ); - BufferRewind( 2*sizeof(short) ); - return 0; - } - - // Skip over the struct name - fileCount = ReadInt(); // Read field count - - lastField = 0; // Make searches faster, most data is read/written in the same order - - // Clear out base data - for ( i = 0; i < fieldCount; i++ ) - { - // Don't clear global fields - if ( !m_global || !(pFields[i].flags & FTYPEDESC_GLOBAL) ) - memset( ((char *)pBaseData + pFields[i].fieldOffset), 0, pFields[i].fieldSize * gSizes[pFields[i].fieldType] ); - } - - for ( i = 0; i < fileCount; i++ ) - { - BufferReadHeader( &header ); - lastField = ReadField( pBaseData, pFields, fieldCount, lastField, header.size, m_pdata->pTokens[header.token], header.pData ); - lastField++; - } - - return 1; -} - - -void CRestore::BufferReadHeader( HEADER *pheader ) -{ - ASSERT( pheader!=NULL ); - pheader->size = ReadShort(); // Read field size - pheader->token = ReadShort(); // Read field name token - pheader->pData = BufferPointer(); // Field Data is next - BufferSkipBytes( pheader->size ); // Advance to next field -} - - -short CRestore::ReadShort( void ) -{ - short tmp = 0; - - BufferReadBytes( (char *)&tmp, sizeof(short) ); - - return tmp; -} - -int CRestore::ReadInt( void ) -{ - int tmp = 0; - - BufferReadBytes( (char *)&tmp, sizeof(int) ); - - return tmp; -} - -int CRestore::ReadNamedInt( const char *pName ) -{ - HEADER header; - - BufferReadHeader( &header ); - return ((int *)header.pData)[0]; -} - -char *CRestore::ReadNamedString( const char *pName ) -{ - HEADER header; - - BufferReadHeader( &header ); -#ifdef TOKENIZE - return (char *)(m_pdata->pTokens[*(short *)header.pData]); -#else - return (char *)header.pData; -#endif -} - - -char *CRestore::BufferPointer( void ) -{ - if ( !m_pdata ) - return NULL; - - return m_pdata->pCurrentData; -} - -void CRestore::BufferReadBytes( char *pOutput, int size ) -{ - ASSERT( m_pdata !=NULL ); - - if ( !m_pdata || Empty() ) - return; - - if ( (m_pdata->size + size) > m_pdata->bufferSize ) - { - ALERT( at_error, "Restore overflow!" ); - m_pdata->size = m_pdata->bufferSize; - return; - } - - if ( pOutput ) - memcpy( pOutput, m_pdata->pCurrentData, size ); - m_pdata->pCurrentData += size; - m_pdata->size += size; -} - - -void CRestore::BufferSkipBytes( int bytes ) -{ - BufferReadBytes( NULL, bytes ); -} - -int CRestore::BufferSkipZString( void ) -{ - char *pszSearch; - int len; - - if ( !m_pdata ) - return 0; - - int maxLen = m_pdata->bufferSize - m_pdata->size; - - len = 0; - pszSearch = m_pdata->pCurrentData; - while ( *pszSearch++ && len < maxLen ) - len++; - - len++; - - BufferSkipBytes( len ); - - return len; -} - -int CRestore::BufferCheckZString( const char *string ) -{ - if ( !m_pdata ) - return 0; - - int maxLen = m_pdata->bufferSize - m_pdata->size; - int len = strlen( string ); - if ( len <= maxLen ) - { - if ( !strncmp( string, m_pdata->pCurrentData, len ) ) - return 1; - } - return 0; -} diff --git a/ricochet/dlls/util.h b/ricochet/dlls/util.h deleted file mode 100644 index 03e6b83..0000000 --- a/ricochet/dlls/util.h +++ /dev/null @@ -1,556 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "archtypes.h" // DAL - -// -// Misc utility code -// -#ifndef ACTIVITY_H -#include "activity.h" -#endif - -#ifndef ENGINECALLBACK_H -#include "enginecallback.h" -#endif -inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin, entvars_t *ent ); // implementation later in this file - -extern globalvars_t *gpGlobals; - -// Use this instead of ALLOC_STRING on constant strings -#define STRING(offset) ((const char *)(gpGlobals->pStringBase + (unsigned int)(offset))) -#define MAKE_STRING(str) ((uint64)(str) - (uint64)STRING(0)) - - -inline edict_t *FIND_ENTITY_BY_CLASSNAME(edict_t *entStart, const char *pszName) -{ - return FIND_ENTITY_BY_STRING(entStart, "classname", pszName); -} - -inline edict_t *FIND_ENTITY_BY_TARGETNAME(edict_t *entStart, const char *pszName) -{ - return FIND_ENTITY_BY_STRING(entStart, "targetname", pszName); -} - -// for doing a reverse lookup. Say you have a door, and want to find its button. -inline edict_t *FIND_ENTITY_BY_TARGET(edict_t *entStart, const char *pszName) -{ - return FIND_ENTITY_BY_STRING(entStart, "target", pszName); -} - -// Keeps clutter down a bit, when writing key-value pairs -#define WRITEKEY_INT(pf, szKeyName, iKeyValue) \ - ENGINE_FPRINTF(pf, "\"%s\" \"%d\"\n", szKeyName, iKeyValue) -#define WRITEKEY_FLOAT(pf, szKeyName, flKeyValue) \ - ENGINE_FPRINTF(pf, "\"%s\" \"%f\"\n", szKeyName, flKeyValue) -#define WRITEKEY_STRING(pf, szKeyName, szKeyValue) \ - ENGINE_FPRINTF(pf, "\"%s\" \"%s\"\n", szKeyName, szKeyValue) -#define WRITEKEY_VECTOR(pf, szKeyName, flX, flY, flZ) \ - ENGINE_FPRINTF(pf, "\"%s\" \"%f %f %f\"\n", szKeyName, flX, flY, flZ) - -// Keeps clutter down a bit, when using a float as a bit-vector -#define SetBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) | (bits)) -#define ClearBits(flBitVector, bits) ((flBitVector) = (int)(flBitVector) & ~(bits)) -#define FBitSet(flBitVector, bit) ((int)(flBitVector) & (bit)) - -// Makes these more explicit, and easier to find -#define FILE_GLOBAL static -#define DLL_GLOBAL - -// Until we figure out why "const" gives the compiler problems, we'll just have to use -// this bogus "empty" define to mark things as constant. -#define CONSTANT - -// More explicit than "int" -typedef int EOFFSET; - -// In case it's not alread defined -typedef int BOOL; - -// In case this ever changes -#define M_PI 3.14159265358979323846 - -// Keeps clutter down a bit, when declaring external entity/global method prototypes -#define DECLARE_GLOBAL_METHOD(MethodName) \ - extern void DLLEXPORT MethodName( void ) -#define GLOBAL_METHOD(funcname) void DLLEXPORT funcname(void) - -// This is the glue that hooks .MAP entity class names to our CPP classes -// The _declspec forces them to be exported by name so we can do a lookup with GetProcAddress() -// The function is used to intialize / allocate the object for the entity -#define LINK_ENTITY_TO_CLASS(mapClassName,DLLClassName) \ - extern "C" DLLEXPORT void mapClassName( entvars_t *pev ); \ - void mapClassName( entvars_t *pev ) { GetClassPtr( (DLLClassName *)pev ); } - - -// -// Conversion among the three types of "entity", including identity-conversions. -// -#ifdef DEBUG - extern edict_t *DBG_EntOfVars(const entvars_t *pev); - inline edict_t *ENT(const entvars_t *pev) { return DBG_EntOfVars(pev); } -#else - inline edict_t *ENT(const entvars_t *pev) { return pev->pContainingEntity; } -#endif -inline edict_t *ENT(edict_t *pent) { return pent; } -inline edict_t *ENT(EOFFSET eoffset) { return (*g_engfuncs.pfnPEntityOfEntOffset)(eoffset); } -inline EOFFSET OFFSET(EOFFSET eoffset) { return eoffset; } -inline EOFFSET OFFSET(const edict_t *pent) -{ -#if _DEBUG - if ( !pent ) - ALERT( at_error, "Bad ent in OFFSET()\n" ); -#endif - return (*g_engfuncs.pfnEntOffsetOfPEntity)(pent); -} -inline EOFFSET OFFSET(entvars_t *pev) -{ -#if _DEBUG - if ( !pev ) - ALERT( at_error, "Bad pev in OFFSET()\n" ); -#endif - return OFFSET(ENT(pev)); -} -inline entvars_t *VARS(entvars_t *pev) { return pev; } - -inline entvars_t *VARS(edict_t *pent) -{ - if ( !pent ) - return NULL; - - return &pent->v; -} - -inline entvars_t* VARS(EOFFSET eoffset) { return VARS(ENT(eoffset)); } -inline int ENTINDEX(edict_t *pEdict) { return (*g_engfuncs.pfnIndexOfEdict)(pEdict); } -inline edict_t* INDEXENT( int iEdictNum ) { return (*g_engfuncs.pfnPEntityOfEntIndex)(iEdictNum); } -inline void MESSAGE_BEGIN( int msg_dest, int msg_type, const float *pOrigin, entvars_t *ent ) { - (*g_engfuncs.pfnMessageBegin)(msg_dest, msg_type, pOrigin, ENT(ent)); -} - -// Testing the three types of "entity" for nullity -#define eoNullEntity 0 -inline BOOL FNullEnt(EOFFSET eoffset) { return eoffset == 0; } -inline BOOL FNullEnt(const edict_t* pent) { return pent == NULL || FNullEnt(OFFSET(pent)); } -inline BOOL FNullEnt(entvars_t* pev) { return pev == NULL || FNullEnt(OFFSET(pev)); } - -// Testing strings for nullity -#define iStringNull 0 -inline BOOL FStringNull(int iString) { return iString == iStringNull; } - -#define cchMapNameMost 32 - -// Dot products for view cone checking -#define VIEW_FIELD_FULL (float)-1.0 // +-180 degrees -#define VIEW_FIELD_WIDE (float)-0.7 // +-135 degrees 0.1 // +-85 degrees, used for full FOV checks -#define VIEW_FIELD_NARROW (float)0.7 // +-45 degrees, more narrow check used to set up ranged attacks -#define VIEW_FIELD_ULTRA_NARROW (float)0.9 // +-25 degrees, more narrow check used to set up ranged attacks - -// All monsters need this data -#define DONT_BLEED -1 -#define BLOOD_COLOR_RED (BYTE)247 -#define BLOOD_COLOR_YELLOW (BYTE)195 -#define BLOOD_COLOR_GREEN BLOOD_COLOR_YELLOW - -typedef enum -{ - - MONSTERSTATE_NONE = 0, - MONSTERSTATE_IDLE, - MONSTERSTATE_COMBAT, - MONSTERSTATE_ALERT, - MONSTERSTATE_HUNT, - MONSTERSTATE_PRONE, - MONSTERSTATE_SCRIPT, - MONSTERSTATE_PLAYDEAD, - MONSTERSTATE_DEAD - -} MONSTERSTATE; - - - -// Things that toggle (buttons/triggers/doors) need this -typedef enum - { - TS_AT_TOP, - TS_AT_BOTTOM, - TS_GOING_UP, - TS_GOING_DOWN - } TOGGLE_STATE; - -// Misc useful -inline BOOL FStrEq(const char*sz1, const char*sz2) - { return (strcmp(sz1, sz2) == 0); } -inline BOOL FClassnameIs(edict_t* pent, const char* szClassname) - { return FStrEq(STRING(VARS(pent)->classname), szClassname); } -inline BOOL FClassnameIs(entvars_t* pev, const char* szClassname) - { return FStrEq(STRING(pev->classname), szClassname); } - -class CBaseEntity; - -// Misc. Prototypes -extern void UTIL_SetSize (entvars_t* pev, const Vector &vecMin, const Vector &vecMax); -extern float UTIL_VecToYaw (const Vector &vec); -extern Vector UTIL_VecToAngles (const Vector &vec); -extern float UTIL_AngleMod (float a); -extern float UTIL_AngleDiff ( float destAngle, float srcAngle ); - -extern CBaseEntity *UTIL_FindEntityInSphere(CBaseEntity *pStartEntity, const Vector &vecCenter, float flRadius); -extern CBaseEntity *UTIL_FindEntityByString(CBaseEntity *pStartEntity, const char *szKeyword, const char *szValue ); -extern CBaseEntity *UTIL_FindEntityByClassname(CBaseEntity *pStartEntity, const char *szName ); -extern CBaseEntity *UTIL_FindEntityByTargetname(CBaseEntity *pStartEntity, const char *szName ); -extern CBaseEntity *UTIL_FindEntityGeneric(const char *szName, Vector &vecSrc, float flRadius ); - -// returns a CBaseEntity pointer to a player by index. Only returns if the player is spawned and connected -// otherwise returns NULL -// Index is 1 based -extern CBaseEntity *UTIL_PlayerByIndex( int playerIndex ); - -#define UTIL_EntitiesInPVS(pent) (*g_engfuncs.pfnEntitiesInPVS)(pent) -extern void UTIL_MakeVectors (const Vector &vecAngles); - -// Pass in an array of pointers and an array size, it fills the array and returns the number inserted -extern int UTIL_MonstersInSphere( CBaseEntity **pList, int listMax, const Vector ¢er, float radius ); -extern int UTIL_EntitiesInBox( CBaseEntity **pList, int listMax, const Vector &mins, const Vector &maxs, int flagMask ); - -inline void UTIL_MakeVectorsPrivate( const Vector &vecAngles, float *p_vForward, float *p_vRight, float *p_vUp ) -{ - g_engfuncs.pfnAngleVectors( vecAngles, p_vForward, p_vRight, p_vUp ); -} - -extern void UTIL_MakeAimVectors ( const Vector &vecAngles ); // like MakeVectors, but assumes pitch isn't inverted -extern void UTIL_MakeInvVectors ( const Vector &vec, globalvars_t *pgv ); - -extern void UTIL_SetOrigin ( entvars_t* pev, const Vector &vecOrigin ); -extern void UTIL_EmitAmbientSound ( edict_t *entity, const Vector &vecOrigin, const char *samp, float vol, float attenuation, int fFlags, int pitch ); -extern void UTIL_ParticleEffect ( const Vector &vecOrigin, const Vector &vecDirection, ULONG ulColor, ULONG ulCount ); -extern void UTIL_ScreenShake ( const Vector ¢er, float amplitude, float frequency, float duration, float radius ); -extern void UTIL_ScreenShakeAll ( const Vector ¢er, float amplitude, float frequency, float duration ); -extern void UTIL_ShowMessage ( const char *pString, CBaseEntity *pPlayer ); -extern void UTIL_ShowMessageAll ( const char *pString ); -extern void UTIL_ScreenFadeAll ( const Vector &color, float fadeTime, float holdTime, int alpha, int flags ); -extern void UTIL_ScreenFade ( CBaseEntity *pEntity, const Vector &color, float fadeTime, float fadeHold, int alpha, int flags ); - -typedef enum { ignore_monsters=1, dont_ignore_monsters=0, missile=2 } IGNORE_MONSTERS; -typedef enum { ignore_glass=1, dont_ignore_glass=0 } IGNORE_GLASS; -extern void UTIL_TraceLine (const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, edict_t *pentIgnore, TraceResult *ptr); -extern void UTIL_TraceLine (const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, IGNORE_GLASS ignoreGlass, edict_t *pentIgnore, TraceResult *ptr); -enum { point_hull=0, human_hull=1, large_hull=2, head_hull=3 }; -extern void UTIL_TraceHull (const Vector &vecStart, const Vector &vecEnd, IGNORE_MONSTERS igmon, int hullNumber, edict_t *pentIgnore, TraceResult *ptr); -extern TraceResult UTIL_GetGlobalTrace (void); -extern void UTIL_TraceModel (const Vector &vecStart, const Vector &vecEnd, int hullNumber, edict_t *pentModel, TraceResult *ptr); -extern Vector UTIL_GetAimVector (edict_t* pent, float flSpeed); -extern int UTIL_PointContents (const Vector &vec); - -extern int UTIL_IsMasterTriggered (string_t sMaster, CBaseEntity *pActivator); -extern void UTIL_BloodStream( const Vector &origin, const Vector &direction, int color, int amount ); -extern void UTIL_BloodDrips( const Vector &origin, const Vector &direction, int color, int amount ); -extern Vector UTIL_RandomBloodVector( void ); -extern BOOL UTIL_ShouldShowBlood( int bloodColor ); -extern void UTIL_BloodDecalTrace( TraceResult *pTrace, int bloodColor ); -extern void UTIL_DecalTrace( TraceResult *pTrace, int decalNumber ); -extern void UTIL_PlayerDecalTrace( TraceResult *pTrace, int playernum, int decalNumber, BOOL bIsCustom ); -extern void UTIL_GunshotDecalTrace( TraceResult *pTrace, int decalNumber ); -extern void UTIL_Sparks( const Vector &position, edict_t * ed = NULL ); -extern void UTIL_Ricochet( const Vector &position, float scale ); -extern void UTIL_StringToVector( float *pVector, const char *pString ); -extern void UTIL_StringToIntArray( int *pVector, int count, const char *pString ); -extern Vector UTIL_ClampVectorToBox( const Vector &input, const Vector &clampSize ); -extern float UTIL_Approach( float target, float value, float speed ); -extern float UTIL_ApproachAngle( float target, float value, float speed ); -extern float UTIL_AngleDistance( float next, float cur ); - -extern char *UTIL_VarArgs( char *format, ... ); -extern void UTIL_Remove( CBaseEntity *pEntity ); -extern BOOL UTIL_IsValidEntity( edict_t *pent ); -extern BOOL UTIL_TeamsMatch( const char *pTeamName1, const char *pTeamName2 ); - -// Use for ease-in, ease-out style interpolation (accel/decel) -extern float UTIL_SplineFraction( float value, float scale ); - -// Search for water transition along a vertical line -extern float UTIL_WaterLevel( const Vector &position, float minz, float maxz ); -extern void UTIL_Bubbles( Vector mins, Vector maxs, int count ); -extern void UTIL_BubbleTrail( Vector from, Vector to, int count ); - -// allows precacheing of other entities -extern void UTIL_PrecacheOther( const char *szClassname ); - -// prints a message to each client -extern void UTIL_ClientPrintAll( int msg_dest, const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ); -inline void UTIL_CenterPrintAll( const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ) -{ - UTIL_ClientPrintAll( HUD_PRINTCENTER, msg_name, param1, param2, param3, param4 ); -} - -class CBasePlayerItem; -class CBasePlayer; -extern BOOL UTIL_GetNextBestWeapon( CBasePlayer *pPlayer, CBasePlayerItem *pCurrentWeapon ); - - -// prints messages through the HUD -extern void ClientPrint( entvars_t *client, int msg_dest, const char *msg_name, const char *param1 = NULL, const char *param2 = NULL, const char *param3 = NULL, const char *param4 = NULL ); - -// prints a message to the HUD say (chat) -extern void UTIL_SayText( const char *pText, CBaseEntity *pEntity ); -extern void UTIL_SayTextAll( const char *pText, CBaseEntity *pEntity ); - - -typedef struct hudtextparms_s -{ - float x; - float y; - int effect; - byte r1, g1, b1, a1; - byte r2, g2, b2, a2; - float fadeinTime; - float fadeoutTime; - float holdTime; - float fxTime; - int channel; -} hudtextparms_t; - -// prints as transparent 'title' to the HUD -extern void UTIL_HudMessageAll( const hudtextparms_t &textparms, const char *pMessage ); -extern void UTIL_HudMessage( CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage ); - -// for handy use with ClientPrint params -extern char *UTIL_dtos1( int d ); -extern char *UTIL_dtos2( int d ); -extern char *UTIL_dtos3( int d ); -extern char *UTIL_dtos4( int d ); - -// Writes message to console with timestamp and FragLog header. -extern void UTIL_LogPrintf( char *fmt, ... ); - -// Sorta like FInViewCone, but for nonmonsters. -extern float UTIL_DotPoints ( const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir ); - -extern void UTIL_StripToken( const char *pKey, char *pDest );// for redundant keynames - -// Misc functions -extern void SetMovedir(entvars_t* pev); -extern Vector VecBModelOrigin( entvars_t* pevBModel ); -extern int BuildChangeList( LEVELLIST *pLevelList, int maxList ); - -// -// How did I ever live without ASSERT? -// -#ifdef DEBUG -void DBG_AssertFunction(BOOL fExpr, const char* szExpr, const char* szFile, int szLine, const char* szMessage); -#define ASSERT(f) DBG_AssertFunction(f, #f, __FILE__, __LINE__, NULL) -#define ASSERTSZ(f, sz) DBG_AssertFunction(f, #f, __FILE__, __LINE__, sz) -#else // !DEBUG -#define ASSERT(f) -#define ASSERTSZ(f, sz) -#endif // !DEBUG - - -extern DLL_GLOBAL const Vector g_vecZero; - -// -// Constants that were used only by QC (maybe not used at all now) -// -// Un-comment only as needed -// -#define LANGUAGE_ENGLISH 0 -#define LANGUAGE_GERMAN 1 -#define LANGUAGE_FRENCH 2 -#define LANGUAGE_BRITISH 3 - -extern DLL_GLOBAL int g_Language; - -#define AMBIENT_SOUND_STATIC 0 // medium radius attenuation -#define AMBIENT_SOUND_EVERYWHERE 1 -#define AMBIENT_SOUND_SMALLRADIUS 2 -#define AMBIENT_SOUND_MEDIUMRADIUS 4 -#define AMBIENT_SOUND_LARGERADIUS 8 -#define AMBIENT_SOUND_START_SILENT 16 -#define AMBIENT_SOUND_NOT_LOOPING 32 - -#define SPEAKER_START_SILENT 1 // wait for trigger 'on' to start announcements - -#define SND_SPAWNING (1<<8) // duplicated in protocol.h we're spawing, used in some cases for ambients -#define SND_STOP (1<<5) // duplicated in protocol.h stop sound -#define SND_CHANGE_VOL (1<<6) // duplicated in protocol.h change sound vol -#define SND_CHANGE_PITCH (1<<7) // duplicated in protocol.h change sound pitch - -#define LFO_SQUARE 1 -#define LFO_TRIANGLE 2 -#define LFO_RANDOM 3 - -// func_rotating -#define SF_BRUSH_ROTATE_Y_AXIS 0 -#define SF_BRUSH_ROTATE_INSTANT 1 -#define SF_BRUSH_ROTATE_BACKWARDS 2 -#define SF_BRUSH_ROTATE_Z_AXIS 4 -#define SF_BRUSH_ROTATE_X_AXIS 8 -#define SF_PENDULUM_AUTO_RETURN 16 -#define SF_PENDULUM_PASSABLE 32 - - -#define SF_BRUSH_ROTATE_SMALLRADIUS 128 -#define SF_BRUSH_ROTATE_MEDIUMRADIUS 256 -#define SF_BRUSH_ROTATE_LARGERADIUS 512 - -#define PUSH_BLOCK_ONLY_X 1 -#define PUSH_BLOCK_ONLY_Y 2 - -#define VEC_HULL_MIN Vector(-16, -16, -36) -#define VEC_HULL_MAX Vector( 16, 16, 36) -#define VEC_HUMAN_HULL_MIN Vector( -16, -16, 0 ) -#define VEC_HUMAN_HULL_MAX Vector( 16, 16, 72 ) -#define VEC_HUMAN_HULL_DUCK Vector( 16, 16, 36 ) - -#define VEC_VIEW Vector( 0, 0, 28 ) - -#define VEC_DUCK_HULL_MIN Vector(-16, -16, -18 ) -#define VEC_DUCK_HULL_MAX Vector( 16, 16, 18) -#define VEC_DUCK_VIEW Vector( 0, 0, 12 ) - -#define SVC_TEMPENTITY 23 -#define SVC_INTERMISSION 30 -#define SVC_CDTRACK 32 -#define SVC_WEAPONANIM 35 -#define SVC_ROOMTYPE 37 - -// Added to stuff text to the clients -#define SVC_STUFFTEXT 9 // [string] stuffed into client's console buffer - -// triggers -#define SF_TRIGGER_ALLOWMONSTERS 1// monsters allowed to fire this trigger -#define SF_TRIGGER_NOCLIENTS 2// players not allowed to fire this trigger -#define SF_TRIGGER_PUSHABLES 4// only pushables can fire this trigger - -// func breakable -#define SF_BREAK_TRIGGER_ONLY 1// may only be broken by trigger -#define SF_BREAK_TOUCH 2// can be 'crashed through' by running player (plate glass) -#define SF_BREAK_PRESSURE 4// can be broken by a player standing on it -#define SF_BREAK_CROWBAR 256// instant break if hit with crowbar - -// func_pushable (it's also func_breakable, so don't collide with those flags) -#define SF_PUSH_BREAKABLE 128 - -#define SF_LIGHT_START_OFF 1 - -#define SPAWNFLAG_NOMESSAGE 1 -#define SPAWNFLAG_NOTOUCH 1 -#define SPAWNFLAG_DROIDONLY 4 - -#define SPAWNFLAG_USEONLY 1 // can't be touched, must be used (buttons) - -#define TELE_PLAYER_ONLY 1 -#define TELE_SILENT 2 - -#define SF_TRIG_PUSH_ONCE 1 - - -// Sound Utilities - -// sentence groups -#define CBSENTENCENAME_MAX 16 -#define CVOXFILESENTENCEMAX 1536 // max number of sentences in game. NOTE: this must match - // CVOXFILESENTENCEMAX in engine\sound.h!!! - -extern char gszallsentencenames[CVOXFILESENTENCEMAX][CBSENTENCENAME_MAX]; -extern int gcallsentences; - -int USENTENCEG_Pick(int isentenceg, char *szfound); -int USENTENCEG_PickSequential(int isentenceg, char *szfound, int ipick, int freset); -void USENTENCEG_InitLRU(unsigned char *plru, int count); - -void SENTENCEG_Init(); -void SENTENCEG_Stop(edict_t *entity, int isentenceg, int ipick); -int SENTENCEG_PlayRndI(edict_t *entity, int isentenceg, float volume, float attenuation, int flags, int pitch); -int SENTENCEG_PlayRndSz(edict_t *entity, const char *szrootname, float volume, float attenuation, int flags, int pitch); -int SENTENCEG_PlaySequentialSz(edict_t *entity, const char *szrootname, float volume, float attenuation, int flags, int pitch, int ipick, int freset); -int SENTENCEG_GetIndex(const char *szrootname); -int SENTENCEG_Lookup(const char *sample, char *sentencenum); - -void TEXTURETYPE_Init(); -char TEXTURETYPE_Find(char *name); -float TEXTURETYPE_PlaySound(TraceResult *ptr, Vector vecSrc, Vector vecEnd, int iBulletType); - -#define CBTEXTURENAMEMAX 13 // only load first n chars of name - -#define CHAR_TEX_CONCRETE 'C' // texture types -#define CHAR_TEX_METAL 'M' -#define CHAR_TEX_DIRT 'D' -#define CHAR_TEX_VENT 'V' -#define CHAR_TEX_GRATE 'G' -#define CHAR_TEX_TILE 'T' -#define CHAR_TEX_SLOSH 'S' -#define CHAR_TEX_WOOD 'W' -#define CHAR_TEX_COMPUTER 'P' -#define CHAR_TEX_GLASS 'Y' -#define CHAR_TEX_FLESH 'F' - -// NOTE: use EMIT_SOUND_DYN to set the pitch of a sound. Pitch of 100 -// is no pitch shift. Pitch > 100 up to 255 is a higher pitch, pitch < 100 -// down to 1 is a lower pitch. 150 to 70 is the realistic range. -// EMIT_SOUND_DYN with pitch != 100 should be used sparingly, as it's not quite as -// fast as EMIT_SOUND (the pitchshift mixer is not native coded). - -void EMIT_SOUND_DYN(edict_t *entity, int channel, const char *sample, float volume, float attenuation, - int flags, int pitch); - - -inline void EMIT_SOUND(edict_t *entity, int channel, const char *sample, float volume, float attenuation) -{ - EMIT_SOUND_DYN(entity, channel, sample, volume, attenuation, 0, PITCH_NORM); -} - -inline void STOP_SOUND(edict_t *entity, int channel, const char *sample) -{ - EMIT_SOUND_DYN(entity, channel, sample, 0, 0, SND_STOP, PITCH_NORM); -} - -void EMIT_SOUND_SUIT(edict_t *entity, const char *sample); -void EMIT_GROUPID_SUIT(edict_t *entity, int isentenceg); -void EMIT_GROUPNAME_SUIT(edict_t *entity, const char *groupname); - -#define PRECACHE_SOUND_ARRAY( a ) \ - { for (int i = 0; i < ARRAYSIZE( a ); i++ ) PRECACHE_SOUND((char *) a [i]); } - -#define EMIT_SOUND_ARRAY_DYN( chan, array ) \ - EMIT_SOUND_DYN ( ENT(pev), chan , array [ RANDOM_LONG(0,ARRAYSIZE( array )-1) ], 1.0, ATTN_NORM, 0, RANDOM_LONG(95,105) ); - -#define RANDOM_SOUND_ARRAY( array ) (array) [ RANDOM_LONG(0,ARRAYSIZE( (array) )-1) ] - -#define PLAYBACK_EVENT( flags, who, index ) PLAYBACK_EVENT_FULL( flags, who, index, 0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); -#define PLAYBACK_EVENT_DELAY( flags, who, index, delay ) PLAYBACK_EVENT_FULL( flags, who, index, delay, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); - -#define GROUP_OP_AND 0 -#define GROUP_OP_NAND 1 - -extern int g_groupmask; -extern int g_groupop; - -class UTIL_GroupTrace -{ -public: - UTIL_GroupTrace( int groupmask, int op ); - ~UTIL_GroupTrace( void ); - -private: - int m_oldgroupmask, m_oldgroupop; -}; - -void UTIL_SetGroupTrace( int groupmask, int op ); -void UTIL_UnsetGroupTrace( void ); - -int UTIL_SharedRandomLong( unsigned int seed, int low, int high ); -float UTIL_SharedRandomFloat( unsigned int seed, float low, float high ); - -float UTIL_WeaponTimeBase( void ); diff --git a/ricochet/dlls/vector.h b/ricochet/dlls/vector.h deleted file mode 100644 index adfb436..0000000 --- a/ricochet/dlls/vector.h +++ /dev/null @@ -1,112 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef VECTOR_H -#define VECTOR_H - -//========================================================= -// 2DVector - used for many pathfinding and many other -// operations that are treated as planar rather than 3d. -//========================================================= -class Vector2D -{ -public: - inline Vector2D(void) { } - inline Vector2D(float X, float Y) { x = X; y = Y; } - inline Vector2D operator+(const Vector2D& v) const { return Vector2D(x+v.x, y+v.y); } - inline Vector2D operator-(const Vector2D& v) const { return Vector2D(x-v.x, y-v.y); } - inline Vector2D operator*(float fl) const { return Vector2D(x*fl, y*fl); } - inline Vector2D operator/(float fl) const { return Vector2D(x/fl, y/fl); } - - inline float Length(void) const { return sqrt(x*x + y*y ); } - - inline Vector2D Normalize ( void ) const - { - Vector2D vec2; - - float flLen = Length(); - if ( flLen == 0 ) - { - return Vector2D( 0, 0 ); - } - else - { - flLen = 1 / flLen; - return Vector2D( x * flLen, y * flLen ); - } - } - - vec_t x, y; -}; - -inline float DotProduct(const Vector2D& a, const Vector2D& b) { return( a.x*b.x + a.y*b.y ); } -inline Vector2D operator*(float fl, const Vector2D& v) { return v * fl; } - -//========================================================= -// 3D Vector -//========================================================= -class Vector // same data-layout as engine's vec3_t, -{ // which is a vec_t[3] -public: - // Construction/destruction - inline Vector(void) { } - inline Vector(float X, float Y, float Z) { x = X; y = Y; z = Z; } - //inline Vector(double X, double Y, double Z) { x = (float)X; y = (float)Y; z = (float)Z; } - //inline Vector(int X, int Y, int Z) { x = (float)X; y = (float)Y; z = (float)Z; } - inline Vector(const Vector& v) { x = v.x; y = v.y; z = v.z; } - inline Vector(float rgfl[3]) { x = rgfl[0]; y = rgfl[1]; z = rgfl[2]; } - - // Operators - inline Vector operator-(void) const { return Vector(-x,-y,-z); } - inline int operator==(const Vector& v) const { return x==v.x && y==v.y && z==v.z; } - inline int operator!=(const Vector& v) const { return !(*this==v); } - inline Vector operator+(const Vector& v) const { return Vector(x+v.x, y+v.y, z+v.z); } - inline Vector operator-(const Vector& v) const { return Vector(x-v.x, y-v.y, z-v.z); } - inline Vector operator*(float fl) const { return Vector(x*fl, y*fl, z*fl); } - inline Vector operator/(float fl) const { return Vector(x/fl, y/fl, z/fl); } - - // Methods - inline void CopyToArray(float* rgfl) const { rgfl[0] = x, rgfl[1] = y, rgfl[2] = z; } - inline float Length(void) const { return sqrt(x*x + y*y + z*z); } - operator float *() { return &x; } // Vectors will now automatically convert to float * when needed - operator const float *() const { return &x; } // Vectors will now automatically convert to float * when needed - inline Vector Normalize(void) const - { - float flLen = Length(); - if (flLen == 0) return Vector(0,0,1); // ???? - flLen = 1 / flLen; - return Vector(x * flLen, y * flLen, z * flLen); - } - - inline Vector2D Make2D ( void ) const - { - Vector2D Vec2; - - Vec2.x = x; - Vec2.y = y; - - return Vec2; - } - inline float Length2D(void) const { return sqrt(x*x + y*y); } - - // Members - vec_t x, y, z; -}; -inline Vector operator*(float fl, const Vector& v) { return v * fl; } -inline float DotProduct(const Vector& a, const Vector& b) { return(a.x*b.x+a.y*b.y+a.z*b.z); } -inline Vector CrossProduct(const Vector& a, const Vector& b) { return Vector( a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x ); } - - - -#endif diff --git a/ricochet/dlls/weapons.cpp b/ricochet/dlls/weapons.cpp deleted file mode 100644 index 1e6a943..0000000 --- a/ricochet/dlls/weapons.cpp +++ /dev/null @@ -1,1058 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -/* - -===== weapons.cpp ======================================================== - - functions governing the selection/use of weapons for players - -*/ - -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "player.h" -#include "monsters.h" -#include "weapons.h" -#include "nodes.h" -#include "soundent.h" -#include "decals.h" -#include "gamerules.h" - -extern CGraph WorldGraph; -extern int gEvilImpulse101; - - -#define NOT_USED 255 - -DLL_GLOBAL short g_sModelIndexLaser;// holds the index for the laser beam -DLL_GLOBAL const char *g_pModelNameLaser = "sprites/laserbeam.spr"; -DLL_GLOBAL short g_sModelIndexLaserDot;// holds the index for the laser beam dot -DLL_GLOBAL short g_sModelIndexFireball;// holds the index for the fireball -DLL_GLOBAL short g_sModelIndexSmoke;// holds the index for the smoke cloud -DLL_GLOBAL short g_sModelIndexWExplosion;// holds the index for the underwater explosion -DLL_GLOBAL short g_sModelIndexBubbles;// holds the index for the bubbles model -DLL_GLOBAL short g_sModelIndexBloodDrop;// holds the sprite index for the initial blood -DLL_GLOBAL short g_sModelIndexBloodSpray;// holds the sprite index for splattered blood - -ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS]; -AmmoInfo CBasePlayerItem::AmmoInfoArray[MAX_AMMO_SLOTS]; - -extern int gmsgCurWeapon; - -MULTIDAMAGE gMultiDamage; - -#define TRACER_FREQ 4 // Tracers fire every fourth bullet - - -//========================================================= -// MaxAmmoCarry - pass in a name and this function will tell -// you the maximum amount of that type of ammunition that a -// player can carry. -//========================================================= -int MaxAmmoCarry( int iszName ) -{ - for ( int i = 0; i < MAX_WEAPONS; i++ ) - { - if ( CBasePlayerItem::ItemInfoArray[i].pszAmmo1 && !strcmp( STRING(iszName), CBasePlayerItem::ItemInfoArray[i].pszAmmo1 ) ) - return CBasePlayerItem::ItemInfoArray[i].iMaxAmmo1; - if ( CBasePlayerItem::ItemInfoArray[i].pszAmmo2 && !strcmp( STRING(iszName), CBasePlayerItem::ItemInfoArray[i].pszAmmo2 ) ) - return CBasePlayerItem::ItemInfoArray[i].iMaxAmmo2; - } - - ALERT( at_console, "MaxAmmoCarry() doesn't recognize '%s'!\n", STRING( iszName ) ); - return -1; -} - - -/* -============================================================================== - -MULTI-DAMAGE - -Collects multiple small damages into a single damage - -============================================================================== -*/ - -// -// ClearMultiDamage - resets the global multi damage accumulator -// -void ClearMultiDamage(void) -{ - gMultiDamage.pEntity = NULL; - gMultiDamage.amount = 0; - gMultiDamage.type = 0; -} - - -// -// ApplyMultiDamage - inflicts contents of global multi damage register on gMultiDamage.pEntity -// -// GLOBALS USED: -// gMultiDamage - -void ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker ) -{ - Vector vecSpot1;//where blood comes from - Vector vecDir;//direction blood should go - TraceResult tr; - - if ( !gMultiDamage.pEntity ) - return; - - gMultiDamage.pEntity->TakeDamage(pevInflictor, pevAttacker, gMultiDamage.amount, gMultiDamage.type ); -} - - -// GLOBALS USED: -// gMultiDamage - -void AddMultiDamage( entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType) -{ - if ( !pEntity ) - return; - - gMultiDamage.type |= bitsDamageType; - - if ( pEntity != gMultiDamage.pEntity ) - { - ApplyMultiDamage(pevInflictor,pevInflictor); // UNDONE: wrong attacker! - gMultiDamage.pEntity = pEntity; - gMultiDamage.amount = 0; - } - - gMultiDamage.amount += flDamage; -} - -/* -================ -SpawnBlood -================ -*/ -void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage) -{ - UTIL_BloodDrips( vecSpot, g_vecAttackDir, bloodColor, (int)flDamage ); -} - - -int DamageDecal( CBaseEntity *pEntity, int bitsDamageType ) -{ - if ( !pEntity ) - return (DECAL_GUNSHOT1 + RANDOM_LONG(0,4)); - - return pEntity->DamageDecal( bitsDamageType ); -} - -void DecalGunshot( TraceResult *pTrace, int iBulletType ) -{ - // Is the entity valid - if ( !UTIL_IsValidEntity( pTrace->pHit ) ) - return; - - if ( VARS(pTrace->pHit)->solid == SOLID_BSP || VARS(pTrace->pHit)->movetype == MOVETYPE_PUSHSTEP ) - { - CBaseEntity *pEntity = NULL; - // Decal the wall with a gunshot - if ( !FNullEnt(pTrace->pHit) ) - pEntity = CBaseEntity::Instance(pTrace->pHit); - - switch( iBulletType ) - { - case BULLET_PLAYER_9MM: - case BULLET_MONSTER_9MM: - case BULLET_PLAYER_MP5: - case BULLET_MONSTER_MP5: - case BULLET_PLAYER_BUCKSHOT: - case BULLET_PLAYER_357: - default: - // smoke and decal - UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) ); - break; - case BULLET_MONSTER_12MM: - // smoke and decal - UTIL_GunshotDecalTrace( pTrace, DamageDecal( pEntity, DMG_BULLET ) ); - break; - case BULLET_PLAYER_CROWBAR: - // wall decal - UTIL_DecalTrace( pTrace, DamageDecal( pEntity, DMG_CLUB ) ); - break; - } - } -} - - - -// -// EjectBrass - tosses a brass shell from passed origin at passed velocity -// -void EjectBrass ( const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype ) -{ - // FIX: when the player shoots, their gun isn't in the same position as it is on the model other players see. - - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecOrigin ); - WRITE_BYTE( TE_MODEL); - WRITE_COORD( vecOrigin.x); - WRITE_COORD( vecOrigin.y); - WRITE_COORD( vecOrigin.z); - WRITE_COORD( vecVelocity.x); - WRITE_COORD( vecVelocity.y); - WRITE_COORD( vecVelocity.z); - WRITE_ANGLE( rotation ); - WRITE_SHORT( model ); - WRITE_BYTE ( soundtype); - WRITE_BYTE ( 25 );// 2.5 seconds - MESSAGE_END(); -} - - -#if 0 -// UNDONE: This is no longer used? -void ExplodeModel( const Vector &vecOrigin, float speed, int model, int count ) -{ - MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecOrigin ); - WRITE_BYTE ( TE_EXPLODEMODEL ); - WRITE_COORD( vecOrigin.x ); - WRITE_COORD( vecOrigin.y ); - WRITE_COORD( vecOrigin.z ); - WRITE_COORD( speed ); - WRITE_SHORT( model ); - WRITE_SHORT( count ); - WRITE_BYTE ( 15 );// 1.5 seconds - MESSAGE_END(); -} -#endif - - -int giAmmoIndex = 0; - -// Precaches the ammo and queues the ammo info for sending to clients -void AddAmmoNameToAmmoRegistry( const char *szAmmoname ) -{ - // make sure it's not already in the registry - for ( int i = 0; i < MAX_AMMO_SLOTS; i++ ) - { - if ( !CBasePlayerItem::AmmoInfoArray[i].pszName) - continue; - - if ( stricmp( CBasePlayerItem::AmmoInfoArray[i].pszName, szAmmoname ) == 0 ) - return; // ammo already in registry, just quite - } - - - giAmmoIndex++; - ASSERT( giAmmoIndex < MAX_AMMO_SLOTS ); - if ( giAmmoIndex >= MAX_AMMO_SLOTS ) - giAmmoIndex = 0; - - CBasePlayerItem::AmmoInfoArray[giAmmoIndex].pszName = szAmmoname; - CBasePlayerItem::AmmoInfoArray[giAmmoIndex].iId = giAmmoIndex; // yes, this info is redundant -} - - -// Precaches the weapon and queues the weapon info for sending to clients -void UTIL_PrecacheOtherWeapon( const char *szClassname ) -{ - edict_t *pent; - - pent = CREATE_NAMED_ENTITY( MAKE_STRING( szClassname ) ); - if ( FNullEnt( pent ) ) - { - ALERT ( at_console, "NULL Ent in UTIL_PrecacheOtherWeapon\n" ); - return; - } - - CBaseEntity *pEntity = CBaseEntity::Instance (VARS( pent )); - - if (pEntity) - { - ItemInfo II; - pEntity->Precache( ); - memset( &II, 0, sizeof II ); - if ( ((CBasePlayerItem*)pEntity)->GetItemInfo( &II ) ) - { - CBasePlayerItem::ItemInfoArray[II.iId] = II; - - if ( II.pszAmmo1 && *II.pszAmmo1 ) - { - AddAmmoNameToAmmoRegistry( II.pszAmmo1 ); - } - - if ( II.pszAmmo2 && *II.pszAmmo2 ) - { - AddAmmoNameToAmmoRegistry( II.pszAmmo2 ); - } - - memset( &II, 0, sizeof II ); - } - } - - REMOVE_ENTITY(pent); -} - -// called by worldspawn -void W_Precache(void) -{ - memset( CBasePlayerItem::ItemInfoArray, 0, sizeof(CBasePlayerItem::ItemInfoArray) ); - memset( CBasePlayerItem::AmmoInfoArray, 0, sizeof(CBasePlayerItem::AmmoInfoArray) ); - giAmmoIndex = 0; - - // Discwar - UTIL_PrecacheOtherWeapon( "weapon_disc" ); - UTIL_PrecacheOther( "disc" ); -} - - - - -TYPEDESCRIPTION CBasePlayerItem::m_SaveData[] = -{ - DEFINE_FIELD( CBasePlayerItem, m_pPlayer, FIELD_CLASSPTR ), - DEFINE_FIELD( CBasePlayerItem, m_pNext, FIELD_CLASSPTR ), - //DEFINE_FIELD( CBasePlayerItem, m_fKnown, FIELD_INTEGER ),Reset to zero on load - DEFINE_FIELD( CBasePlayerItem, m_iId, FIELD_INTEGER ), - // DEFINE_FIELD( CBasePlayerItem, m_iIdPrimary, FIELD_INTEGER ), - // DEFINE_FIELD( CBasePlayerItem, m_iIdSecondary, FIELD_INTEGER ), -}; -IMPLEMENT_SAVERESTORE( CBasePlayerItem, CBaseAnimating ); - - -TYPEDESCRIPTION CBasePlayerWeapon::m_SaveData[] = -{ - DEFINE_FIELD( CBasePlayerWeapon, m_flNextPrimaryAttack, FIELD_TIME ), - DEFINE_FIELD( CBasePlayerWeapon, m_flNextSecondaryAttack, FIELD_TIME ), - DEFINE_FIELD( CBasePlayerWeapon, m_flTimeWeaponIdle, FIELD_TIME ), - DEFINE_FIELD( CBasePlayerWeapon, m_iPrimaryAmmoType, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayerWeapon, m_iSecondaryAmmoType, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayerWeapon, m_iClip, FIELD_INTEGER ), - DEFINE_FIELD( CBasePlayerWeapon, m_iDefaultAmmo, FIELD_INTEGER ), -// DEFINE_FIELD( CBasePlayerWeapon, m_iClientClip, FIELD_INTEGER ) , reset to zero on load so hud gets updated correctly -// DEFINE_FIELD( CBasePlayerWeapon, m_iClientWeaponState, FIELD_INTEGER ), reset to zero on load so hud gets updated correctly -}; - -IMPLEMENT_SAVERESTORE( CBasePlayerWeapon, CBasePlayerItem ); - - -void CBasePlayerItem :: SetObjectCollisionBox( void ) -{ - pev->absmin = pev->origin + Vector(-24, -24, 0); - pev->absmax = pev->origin + Vector(24, 24, 16); -} - - -//========================================================= -// Sets up movetype, size, solidtype for a new weapon. -//========================================================= -void CBasePlayerItem :: FallInit( void ) -{ - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_BBOX; - - UTIL_SetOrigin( pev, pev->origin ); - UTIL_SetSize(pev, Vector( 0, 0, 0), Vector(0, 0, 0) );//pointsize until it lands on the ground. - - SetTouch( &CBasePlayerItem::DefaultTouch ); - SetThink( &CBasePlayerItem::FallThink ); - - pev->nextthink = gpGlobals->time + 0.1; -} - -//========================================================= -// FallThink - Items that have just spawned run this think -// to catch them when they hit the ground. Once we're sure -// that the object is grounded, we change its solid type -// to trigger and set it in a large box that helps the -// player get it. -//========================================================= -void CBasePlayerItem::FallThink ( void ) -{ - pev->nextthink = gpGlobals->time + 0.1; - - if ( pev->flags & FL_ONGROUND ) - { - // clatter if we have an owner (i.e., dropped by someone) - // don't clatter if the gun is waiting to respawn (if it's waiting, it is invisible!) - if ( !FNullEnt( pev->owner ) ) - { - int pitch = 95 + RANDOM_LONG(0,29); - EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "items/weapondrop1.wav", 1, ATTN_NORM, 0, pitch); - } - - // lie flat - pev->angles.x = 0; - pev->angles.z = 0; - - Materialize(); - } -} - -//========================================================= -// Materialize - make a CBasePlayerItem visible and tangible -//========================================================= -void CBasePlayerItem::Materialize( void ) -{ - if ( pev->effects & EF_NODRAW ) - { - // 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; - } - - pev->solid = SOLID_TRIGGER; - - UTIL_SetOrigin( pev, pev->origin );// link into world. - SetTouch (&CBasePlayerItem::DefaultTouch); - SetThink (NULL); - -} - -//========================================================= -// AttemptToMaterialize - the item is trying to rematerialize, -// should it do so now or wait longer? -//========================================================= -void CBasePlayerItem::AttemptToMaterialize( void ) -{ - float time = g_pGameRules->FlWeaponTryRespawn( this ); - - if ( time == 0 ) - { - Materialize(); - return; - } - - pev->nextthink = gpGlobals->time + time; -} - -//========================================================= -// CheckRespawn - a player is taking this weapon, should -// it respawn? -//========================================================= -void CBasePlayerItem :: CheckRespawn ( void ) -{ - switch ( g_pGameRules->WeaponShouldRespawn( this ) ) - { - case GR_WEAPON_RESPAWN_YES: - Respawn(); - break; - case GR_WEAPON_RESPAWN_NO: - return; - break; - } -} - -//========================================================= -// Respawn- this item is already in the world, but it is -// invisible and intangible. Make it visible and tangible. -//========================================================= -CBaseEntity* CBasePlayerItem::Respawn( void ) -{ - // make a copy of this weapon that is invisible and inaccessible to players (no touch function). The weapon spawn/respawn code - // will decide when to make the weapon visible and touchable. - CBaseEntity *pNewWeapon = CBaseEntity::Create( (char *)STRING( pev->classname ), g_pGameRules->VecWeaponRespawnSpot( this ), pev->angles, pev->owner ); - - if ( pNewWeapon ) - { - pNewWeapon->pev->effects |= EF_NODRAW;// invisible for now - pNewWeapon->SetTouch( NULL );// no touch - pNewWeapon->SetThink( &CBasePlayerItem::AttemptToMaterialize ); - - DROP_TO_FLOOR ( ENT(pev) ); - - // not a typo! We want to know when the weapon the player just picked up should respawn! This new entity we created is the replacement, - // but when it should respawn is based on conditions belonging to the weapon that was taken. - pNewWeapon->pev->nextthink = g_pGameRules->FlWeaponRespawnTime( this ); - } - else - { - ALERT ( at_console, "Respawn failed to create %s!\n", STRING( pev->classname ) ); - } - - return pNewWeapon; -} - -void CBasePlayerItem::DefaultTouch( CBaseEntity *pOther ) -{ - // if it's not a player, ignore - if ( !pOther->IsPlayer() ) - return; - - CBasePlayer *pPlayer = (CBasePlayer *)pOther; - - // can I have this? - if ( !g_pGameRules->CanHavePlayerItem( pPlayer, this ) ) - { - if ( gEvilImpulse101 ) - { - UTIL_Remove( this ); - } - return; - } - - if (pOther->AddPlayerItem( this )) - { - AttachToPlayer( pPlayer ); - EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM); - } - - SUB_UseTargets( pOther, USE_TOGGLE, 0 ); // UNDONE: when should this happen? -} - -BOOL CanAttack( float attack_time, float curtime, BOOL isPredicted ) -{ - if ( !isPredicted ) - { - return ( attack_time <= curtime ) ? TRUE : FALSE; - } - else - { - return ( attack_time <= 0.0 ) ? TRUE : FALSE; - } -} - -void CBasePlayerWeapon::ItemPostFrame( void ) -{ - if ((m_fInReload) && ( m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase() ) ) - { - // complete the reload. - int j = V_min( iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); - - // Add them to the clip - m_iClip += j; - m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j; - - m_fInReload = FALSE; - } - - if ((m_pPlayer->pev->button & IN_ATTACK2) && CanAttack( m_flNextSecondaryAttack, gpGlobals->time, UseDecrement() ) ) - { - if ( pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()] ) - { - m_fFireOnEmpty = TRUE; - } - - SecondaryAttack(); - m_pPlayer->pev->button &= ~IN_ATTACK2; - } - else if ((m_pPlayer->pev->button & IN_ATTACK) && CanAttack( m_flNextPrimaryAttack, gpGlobals->time, UseDecrement() ) ) - { - if ( (m_iClip == 0 && pszAmmo1()) || (iMaxClip() == -1 && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] ) ) - { - m_fFireOnEmpty = TRUE; - } - - PrimaryAttack(); - } - else if ( m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload ) - { - // reload when reload is pressed, or if no buttons are down and weapon is empty. - Reload(); - } - else if ( !(m_pPlayer->pev->button & (IN_ATTACK|IN_ATTACK2) ) ) - { - // no fire buttons down - - m_fFireOnEmpty = FALSE; - - if ( !IsUseable() && m_flNextPrimaryAttack < ( UseDecrement() ? 0.0 : gpGlobals->time ) ) - { - // weapon isn't useable, switch. - if ( !(iFlags() & ITEM_FLAG_NOAUTOSWITCHEMPTY) && g_pGameRules->GetNextBestWeapon( m_pPlayer, this ) ) - { - m_flNextPrimaryAttack = ( UseDecrement() ? 0.0 : gpGlobals->time ) + 0.3; - return; - } - } - else - { - // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing - if ( m_iClip == 0 && !(iFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < ( UseDecrement() ? 0.0 : gpGlobals->time ) ) - { - Reload(); - return; - } - } - - WeaponIdle( ); - return; - } - - // catch all - if ( ShouldWeaponIdle() ) - { - WeaponIdle(); - } -} - -void CBasePlayerItem::DestroyItem( void ) -{ - if ( m_pPlayer ) - { - // if attached to a player, remove. - m_pPlayer->RemovePlayerItem( this ); - } - - Kill( ); -} - -int CBasePlayerItem::AddToPlayer( CBasePlayer *pPlayer ) -{ - m_pPlayer = pPlayer; - - return TRUE; -} - -void CBasePlayerItem::Drop( void ) -{ - SetTouch( NULL ); - SetThink(&CBasePlayerItem::SUB_Remove); - pev->nextthink = gpGlobals->time + .1; -} - -void CBasePlayerItem::Kill( void ) -{ - SetTouch( NULL ); - SetThink(&CBasePlayerItem::SUB_Remove); - pev->nextthink = gpGlobals->time + .1; -} - -void CBasePlayerItem::Holster( int skiplocal /* = 0 */ ) -{ - m_pPlayer->pev->viewmodel = 0; - m_pPlayer->pev->weaponmodel = 0; -} - -void CBasePlayerItem::AttachToPlayer ( CBasePlayer *pPlayer ) -{ - pev->movetype = MOVETYPE_FOLLOW; - pev->solid = SOLID_NOT; - pev->aiment = pPlayer->edict(); - pev->effects = EF_NODRAW; // ?? - pev->modelindex = 0;// server won't send down to clients if modelindex == 0 - pev->model = iStringNull; - pev->owner = pPlayer->edict(); - pev->nextthink = gpGlobals->time + .1; - SetTouch( NULL ); -} - -// CALLED THROUGH the newly-touched weapon's instance. The existing player weapon is pOriginal -int CBasePlayerWeapon::AddDuplicate( CBasePlayerItem *pOriginal ) -{ - if ( m_iDefaultAmmo ) - { - return ExtractAmmo( (CBasePlayerWeapon *)pOriginal ); - } - else - { - // a dead player dropped this. - return ExtractClipAmmo( (CBasePlayerWeapon *)pOriginal ); - } -} - - -int CBasePlayerWeapon::AddToPlayer( CBasePlayer *pPlayer ) -{ - int bResult = CBasePlayerItem::AddToPlayer( pPlayer ); - - pPlayer->pev->weapons |= (1<GetAmmoIndex( pszAmmo1() ); - m_iSecondaryAmmoType = pPlayer->GetAmmoIndex( pszAmmo2() ); - } - - - if (bResult) - return AddWeapon( ); - return FALSE; -} - -int CBasePlayerWeapon::UpdateClientData( CBasePlayer *pPlayer ) -{ - BOOL bSend = FALSE; - int state = 0; - if ( pPlayer->m_pActiveItem == this ) - { - if ( pPlayer->m_fOnTarget ) - state = WEAPON_IS_ONTARGET; - else - state = 1; - } - - // Forcing send of all data! - if ( !pPlayer->m_fWeapon ) - { - bSend = TRUE; - } - - // This is the current or last weapon, so the state will need to be updated - if ( this == pPlayer->m_pActiveItem || - this == pPlayer->m_pClientActiveItem ) - { - if ( pPlayer->m_pActiveItem != pPlayer->m_pClientActiveItem ) - { - bSend = TRUE; - } - } - - // If the ammo, state, or fov has changed, update the weapon - if ( m_iClip != m_iClientClip || - state != m_iClientWeaponState || - pPlayer->m_iFOV != pPlayer->m_iClientFOV ) - { - bSend = TRUE; - } - - if ( bSend ) - { - MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pPlayer->pev ); - WRITE_BYTE( state ); - WRITE_BYTE( m_iId ); - WRITE_BYTE( m_iClip ); - MESSAGE_END(); - - m_iClientClip = m_iClip; - m_iClientWeaponState = state; - pPlayer->m_fWeapon = TRUE; - } - - if ( m_pNext ) - m_pNext->UpdateClientData( pPlayer ); - - return 1; -} - - -void CBasePlayerWeapon::SendWeaponAnim( int iAnim, int skiplocal ) -{ - m_pPlayer->pev->weaponanim = iAnim; - - if ( skiplocal && ENGINE_CANSKIP( m_pPlayer->edict() ) ) - return; - - MESSAGE_BEGIN( MSG_ONE, SVC_WEAPONANIM, NULL, m_pPlayer->pev ); - WRITE_BYTE( iAnim ); // sequence number - WRITE_BYTE( pev->body ); // weaponmodel bodygroup. - MESSAGE_END(); -} - -BOOL CBasePlayerWeapon :: AddPrimaryAmmo( int iCount, char *szName, int iMaxClip, int iMaxCarry ) -{ - int iIdAmmo; - - if (iMaxClip < 1) - { - m_iClip = -1; - iIdAmmo = m_pPlayer->GiveAmmo( iCount, szName, iMaxCarry ); - } - else if (m_iClip == 0) - { - int i; - i = V_min( m_iClip + iCount, iMaxClip ) - m_iClip; - m_iClip += i; - iIdAmmo = m_pPlayer->GiveAmmo( iCount - i, szName, iMaxCarry ); - } - else - { - iIdAmmo = m_pPlayer->GiveAmmo( iCount, szName, iMaxCarry ); - } - - // m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] = iMaxCarry; // hack for testing - - if (iIdAmmo > 0) - { - m_iPrimaryAmmoType = iIdAmmo; - if (m_pPlayer->HasPlayerItem( this ) ) - { - // play the "got ammo" sound only if we gave some ammo to a player that already had this gun. - // if the player is just getting this gun for the first time, DefaultTouch will play the "picked up gun" sound for us. - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM); - } - } - - return iIdAmmo > 0 ? TRUE : FALSE; -} - - -BOOL CBasePlayerWeapon :: AddSecondaryAmmo( int iCount, char *szName, int iMax ) -{ - int iIdAmmo; - - iIdAmmo = m_pPlayer->GiveAmmo( iCount, szName, iMax ); - - //m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] = iMax; // hack for testing - - if (iIdAmmo > 0) - { - m_iSecondaryAmmoType = iIdAmmo; - EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM); - } - return iIdAmmo > 0 ? TRUE : FALSE; -} - -//========================================================= -// IsUseable - this function determines whether or not a -// weapon is useable by the player in its current state. -// (does it have ammo loaded? do I have any ammo for the -// weapon?, etc) -//========================================================= -BOOL CBasePlayerWeapon :: IsUseable( void ) -{ - if ( m_iClip <= 0 ) - { - if ( m_pPlayer->m_rgAmmo[ PrimaryAmmoIndex() ] <= 0 && iMaxAmmo1() != -1 ) - { - // clip is empty (or nonexistant) and the player has no more ammo of this type. - return FALSE; - } - } - - return TRUE; -} - -BOOL CBasePlayerWeapon :: CanDeploy( void ) -{ - BOOL bHasAmmo = 0; - - if ( !pszAmmo1() ) - { - // this weapon doesn't use ammo, can always deploy. - return TRUE; - } - - if ( pszAmmo1() ) - { - bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] != 0); - } - if ( pszAmmo2() ) - { - bHasAmmo |= (m_pPlayer->m_rgAmmo[m_iSecondaryAmmoType] != 0); - } - if (m_iClip > 0) - { - bHasAmmo |= 1; - } - if (!bHasAmmo) - { - return FALSE; - } - - return TRUE; -} - -BOOL CBasePlayerWeapon :: DefaultDeploy( char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal /* = 0 */ ) -{ - if (!CanDeploy( )) - return FALSE; - - m_pPlayer->pev->viewmodel = MAKE_STRING(szViewModel); - m_pPlayer->pev->weaponmodel = MAKE_STRING(szWeaponModel); - strcpy( m_pPlayer->m_szAnimExtention, szAnimExt ); - SendWeaponAnim( iAnim, skiplocal ); - - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5; - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.0; - - return TRUE; -} - - -BOOL CBasePlayerWeapon :: DefaultReload( int iClipSize, int iAnim, float fDelay ) -{ - if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) - return FALSE; - - int j = V_min(iClipSize - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); - - if (j == 0) - return FALSE; - - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + fDelay; - - //!!UNDONE -- reload sound goes here !!! - SendWeaponAnim( iAnim, UseDecrement() ? 1 : 0 ); - - m_fInReload = TRUE; - - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 3; - return TRUE; -} - -BOOL CBasePlayerWeapon :: PlayEmptySound( void ) -{ - if (m_iPlayEmptySound) - { - EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/357_cock1.wav", 0.8, ATTN_NORM); - m_iPlayEmptySound = 0; - return 0; - } - return 0; -} - -void CBasePlayerWeapon :: ResetEmptySound( void ) -{ - m_iPlayEmptySound = 1; -} - -//========================================================= -//========================================================= -int CBasePlayerWeapon::PrimaryAmmoIndex( void ) -{ - return m_iPrimaryAmmoType; -} - -//========================================================= -//========================================================= -int CBasePlayerWeapon::SecondaryAmmoIndex( void ) -{ - return -1; -} - -void CBasePlayerWeapon::Holster( int skiplocal /* = 0 */ ) -{ - m_fInReload = FALSE; // cancel any reload in progress. - m_pPlayer->pev->viewmodel = 0; - m_pPlayer->pev->weaponmodel = 0; -} - -void CBasePlayerAmmo::Spawn( void ) -{ - pev->movetype = MOVETYPE_TOSS; - pev->solid = SOLID_TRIGGER; - UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16)); - UTIL_SetOrigin( pev, pev->origin ); - - SetTouch( &CBasePlayerAmmo::DefaultTouch ); -} - -CBaseEntity* CBasePlayerAmmo::Respawn( void ) -{ - pev->effects |= EF_NODRAW; - SetTouch( NULL ); - - UTIL_SetOrigin( pev, g_pGameRules->VecAmmoRespawnSpot( this ) );// move to wherever I'm supposed to repawn. - - SetThink( &CBasePlayerAmmo::Materialize ); - pev->nextthink = g_pGameRules->FlAmmoRespawnTime( this ); - - return this; -} - -void CBasePlayerAmmo::Materialize( void ) -{ - if ( pev->effects & EF_NODRAW ) - { - // 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( &CBasePlayerAmmo::DefaultTouch ); -} - -void CBasePlayerAmmo :: DefaultTouch( CBaseEntity *pOther ) -{ - if ( !pOther->IsPlayer() ) - { - return; - } - - if (AddAmmo( pOther )) - { - if ( g_pGameRules->AmmoShouldRespawn( this ) == GR_AMMO_RESPAWN_YES ) - { - Respawn(); - } - else - { - SetTouch( NULL ); - SetThink(&CBasePlayerAmmo::SUB_Remove); - pev->nextthink = gpGlobals->time + .1; - } - } - else if (gEvilImpulse101) - { - // evil impulse 101 hack, kill always - SetTouch( NULL ); - SetThink(&CBasePlayerAmmo::SUB_Remove); - pev->nextthink = gpGlobals->time + .1; - } -} - -//========================================================= -// called by the new item with the existing item as parameter -// -// if we call ExtractAmmo(), it's because the player is picking up this type of weapon for -// the first time. If it is spawned by the world, m_iDefaultAmmo will have a default ammo amount in it. -// if this is a weapon dropped by a dying player, has 0 m_iDefaultAmmo, which means only the ammo in -// the weapon clip comes along. -//========================================================= -int CBasePlayerWeapon::ExtractAmmo( CBasePlayerWeapon *pWeapon ) -{ - int iReturn = 0; - - if ( pszAmmo1() != NULL ) - { - // blindly call with m_iDefaultAmmo. It's either going to be a value or zero. If it is zero, - // we only get the ammo in the weapon's clip, which is what we want. - iReturn = pWeapon->AddPrimaryAmmo( m_iDefaultAmmo, (char *)pszAmmo1(), iMaxClip(), iMaxAmmo1() ); - m_iDefaultAmmo = 0; - } - - if ( pszAmmo2() != NULL ) - { - iReturn = pWeapon->AddSecondaryAmmo( 0, (char *)pszAmmo2(), iMaxAmmo2() ); - } - - return iReturn; -} - -//========================================================= -// called by the new item's class with the existing item as parameter -//========================================================= -int CBasePlayerWeapon::ExtractClipAmmo( CBasePlayerWeapon *pWeapon ) -{ - int iAmmo; - - if ( m_iClip == WEAPON_NOCLIP ) - { - iAmmo = 0;// guns with no clips always come empty if they are second-hand - } - else - { - iAmmo = m_iClip; - } - - return pWeapon->m_pPlayer->GiveAmmo( iAmmo, (char *)pszAmmo1(), iMaxAmmo1() ); // , &m_iPrimaryAmmoType -} - -//========================================================= -// RetireWeapon - no more ammo for this gun, put it away. -//========================================================= -void CBasePlayerWeapon::RetireWeapon( void ) -{ - // first, no viewmodel at all. - m_pPlayer->pev->viewmodel = iStringNull; - m_pPlayer->pev->weaponmodel = iStringNull; - //m_pPlayer->pev->viewmodelindex = NULL; - - g_pGameRules->GetNextBestWeapon( m_pPlayer, this ); -} - -void CBasePlayerWeapon::PrintState( void ) -{ -} diff --git a/ricochet/dlls/weapons.h b/ricochet/dlls/weapons.h deleted file mode 100644 index 533ee2d..0000000 --- a/ricochet/dlls/weapons.h +++ /dev/null @@ -1,451 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 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. -* -****/ -#ifndef WEAPONS_H -#define WEAPONS_H - - -class CBasePlayer; -extern int gmsgWeapPickup; - -// Contact Grenade / Timed grenade / Satchel Charge -class CGrenade : public CBaseMonster -{ -public: - void Spawn( void ); - - typedef enum { SATCHEL_DETONATE = 0, SATCHEL_RELEASE } SATCHELCODE; - - static CGrenade *ShootTimed( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity, float time ); - static CGrenade *ShootContact( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ); - static CGrenade *ShootSatchelCharge( entvars_t *pevOwner, Vector vecStart, Vector vecVelocity ); - static void UseSatchelCharges( entvars_t *pevOwner, SATCHELCODE code ); - - void Explode( Vector vecSrc, Vector vecAim ); - void Explode( TraceResult *pTrace, int bitsDamageType ); - void EXPORT Smoke( void ); - - void EXPORT BounceTouch( CBaseEntity *pOther ); - void EXPORT SlideTouch( CBaseEntity *pOther ); - void EXPORT ExplodeTouch( CBaseEntity *pOther ); - void EXPORT DangerSoundThink( void ); - void EXPORT PreDetonate( void ); - void EXPORT Detonate( void ); - void EXPORT DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); - void EXPORT TumbleThink( void ); - - virtual void BounceSound( void ); - virtual int BloodColor( void ) { return DONT_BLEED; } - virtual void Killed( entvars_t *pevAttacker, int iGib ); - - BOOL m_fRegisteredSound;// whether or not this grenade has issued its DANGER sound to the world sound list yet. -}; - - -// constant items -#define ITEM_HEALTHKIT 1 -#define ITEM_ANTIDOTE 2 -#define ITEM_SECURITY 3 -#define ITEM_BATTERY 4 - -#define WEAPON_NONE 0 -#define WEAPON_CROWBAR 1 -#define WEAPON_GLOCK 2 -#define WEAPON_PYTHON 3 -#define WEAPON_MP5 4 -#define WEAPON_CHAINGUN 5 -#define WEAPON_CROSSBOW 6 -#define WEAPON_SHOTGUN 7 -#define WEAPON_RPG 8 -#define WEAPON_GAUSS 9 -#define WEAPON_EGON 10 -#define WEAPON_HORNETGUN 11 -#define WEAPON_HANDGRENADE 12 -#define WEAPON_TRIPMINE 13 -#define WEAPON_SATCHEL 14 -#define WEAPON_SNARK 15 - -#define WEAPON_ALLWEAPONS (~(1<skin < 0 || (gpGlobals->deathmatch && FBitSet( pev->spawnflags, SF_DECAL_NOTINDEATHMATCH )) ) - { - REMOVE_ENTITY(ENT(pev)); - return; - } - - if ( FStringNull ( pev->targetname ) ) - { - SetThink( &CDecal::StaticDecal ); - // if there's no targetname, the decal will spray itself on as soon as the world is done spawning. - pev->nextthink = gpGlobals->time; - } - else - { - // if there IS a targetname, the decal sprays itself on when it is triggered. - SetThink ( &CDecal::SUB_DoNothing ); - SetUse(&CDecal::TriggerDecal); - } -} - -void CDecal :: TriggerDecal ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) -{ - // this is set up as a USE function for infodecals that have targetnames, so that the - // decal doesn't get applied until it is fired. (usually by a scripted sequence) - TraceResult trace; - int entityIndex; - - UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace ); - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY); - WRITE_BYTE( TE_BSPDECAL ); - WRITE_COORD( pev->origin.x ); - WRITE_COORD( pev->origin.y ); - WRITE_COORD( pev->origin.z ); - WRITE_SHORT( (int)pev->skin ); - entityIndex = (short)ENTINDEX(trace.pHit); - WRITE_SHORT( entityIndex ); - if ( entityIndex ) - WRITE_SHORT( (int)VARS(trace.pHit)->modelindex ); - MESSAGE_END(); - - SetThink( &CDecal::SUB_Remove ); - pev->nextthink = gpGlobals->time + 0.1; -} - - -void CDecal :: StaticDecal( void ) -{ - TraceResult trace; - int entityIndex, modelIndex; - - UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace ); - - entityIndex = (short)ENTINDEX(trace.pHit); - if ( entityIndex ) - modelIndex = (int)VARS(trace.pHit)->modelindex; - else - modelIndex = 0; - - g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex ); - - SUB_Remove(); -} - - -void CDecal :: KeyValue( KeyValueData *pkvd ) -{ - if (FStrEq(pkvd->szKeyName, "texture")) - { - pev->skin = DECAL_INDEX( pkvd->szValue ); - - // Found - if ( pev->skin >= 0 ) - return; - ALERT( at_console, "Can't find decal %s\n", pkvd->szValue ); - } - else - CBaseEntity::KeyValue( pkvd ); -} - - -// Body queue class here.... It's really just CBaseEntity -class CCorpse : public CBaseEntity -{ - virtual int ObjectCaps( void ) { return FCAP_DONT_SAVE; } -}; - -LINK_ENTITY_TO_CLASS( bodyque, CCorpse ); - -static void InitBodyQue(void) -{ - string_t istrClassname = MAKE_STRING("bodyque"); - - g_pBodyQueueHead = CREATE_NAMED_ENTITY( istrClassname ); - entvars_t *pev = VARS(g_pBodyQueueHead); - - // Reserve 3 more slots for dead bodies - for ( int i = 0; i < 3; i++ ) - { - pev->owner = CREATE_NAMED_ENTITY( istrClassname ); - pev = VARS(pev->owner); - } - - pev->owner = g_pBodyQueueHead; -} - - -// -// make a body que entry for the given ent so the ent can be respawned elsewhere -// -// GLOBALS ASSUMED SET: g_eoBodyQueueHead -// -void CopyToBodyQue(entvars_t *pev) -{ - // DISCWAR: No corpses - return; - - if (pev->effects & EF_NODRAW) - return; - - entvars_t *pevHead = VARS(g_pBodyQueueHead); - - pevHead->angles = pev->angles; - pevHead->model = pev->model; - pevHead->modelindex = pev->modelindex; - pevHead->frame = pev->frame; - pevHead->colormap = pev->colormap; - pevHead->movetype = MOVETYPE_TOSS; - pevHead->velocity = pev->velocity; - pevHead->flags = 0; - pevHead->deadflag = pev->deadflag; - pevHead->renderfx = kRenderFxDeadPlayer; - pevHead->renderamt = ENTINDEX( ENT( pev ) ); - - pevHead->effects = pev->effects | EF_NOINTERP; - //pevHead->goalstarttime = pev->goalstarttime; - //pevHead->goalframe = pev->goalframe; - //pevHead->goalendtime = pev->goalendtime ; - - pevHead->sequence = pev->sequence; - pevHead->animtime = pev->animtime; - - UTIL_SetOrigin(pevHead, pev->origin); - UTIL_SetSize(pevHead, pev->mins, pev->maxs); - g_pBodyQueueHead = pevHead->owner; -} - - -CGlobalState::CGlobalState( void ) -{ - Reset(); -} - -void CGlobalState::Reset( void ) -{ - m_pList = NULL; - m_listCount = 0; -} - -globalentity_t *CGlobalState :: Find( string_t globalname ) -{ - if ( !globalname ) - return NULL; - - globalentity_t *pTest; - const char *pEntityName = STRING(globalname); - - - pTest = m_pList; - while ( pTest ) - { - if ( FStrEq( pEntityName, pTest->name ) ) - break; - - pTest = pTest->pNext; - } - - return pTest; -} - - -// This is available all the time now on impulse 104, remove later -//#ifdef _DEBUG -void CGlobalState :: DumpGlobals( void ) -{ - static char *estates[] = { "Off", "On", "Dead" }; - globalentity_t *pTest; - - ALERT( at_console, "-- Globals --\n" ); - pTest = m_pList; - while ( pTest ) - { - ALERT( at_console, "%s: %s (%s)\n", pTest->name, pTest->levelName, estates[pTest->state] ); - pTest = pTest->pNext; - } -} -//#endif - - -void CGlobalState :: EntityAdd( string_t globalname, string_t mapName, GLOBALESTATE state ) -{ - ASSERT( !Find(globalname) ); - - globalentity_t *pNewEntity = (globalentity_t *)calloc( sizeof( globalentity_t ), 1 ); - ASSERT( pNewEntity != NULL ); - pNewEntity->pNext = m_pList; - m_pList = pNewEntity; - strcpy( pNewEntity->name, STRING( globalname ) ); - strcpy( pNewEntity->levelName, STRING(mapName) ); - pNewEntity->state = state; - m_listCount++; -} - - -void CGlobalState :: EntitySetState( string_t globalname, GLOBALESTATE state ) -{ - globalentity_t *pEnt = Find( globalname ); - - if ( pEnt ) - pEnt->state = state; -} - - -const globalentity_t *CGlobalState :: EntityFromTable( string_t globalname ) -{ - globalentity_t *pEnt = Find( globalname ); - - return pEnt; -} - - -GLOBALESTATE CGlobalState :: EntityGetState( string_t globalname ) -{ - globalentity_t *pEnt = Find( globalname ); - if ( pEnt ) - return pEnt->state; - - return GLOBAL_OFF; -} - - -// Global Savedata for Delay -TYPEDESCRIPTION CGlobalState::m_SaveData[] = -{ - DEFINE_FIELD( CGlobalState, m_listCount, FIELD_INTEGER ), -}; - -// Global Savedata for Delay -TYPEDESCRIPTION gGlobalEntitySaveData[] = -{ - DEFINE_ARRAY( globalentity_t, name, FIELD_CHARACTER, 64 ), - DEFINE_ARRAY( globalentity_t, levelName, FIELD_CHARACTER, 32 ), - DEFINE_FIELD( globalentity_t, state, FIELD_INTEGER ), -}; - - -int CGlobalState::Save( CSave &save ) -{ - int i; - globalentity_t *pEntity; - - if ( !save.WriteFields( "GLOBAL", this, m_SaveData, ARRAYSIZE(m_SaveData) ) ) - return 0; - - pEntity = m_pList; - for ( i = 0; i < m_listCount && pEntity; i++ ) - { - if ( !save.WriteFields( "GENT", pEntity, gGlobalEntitySaveData, ARRAYSIZE(gGlobalEntitySaveData) ) ) - return 0; - - pEntity = pEntity->pNext; - } - - return 1; -} - -int CGlobalState::Restore( CRestore &restore ) -{ - int i, listCount; - globalentity_t tmpEntity; - - - ClearStates(); - if ( !restore.ReadFields( "GLOBAL", this, m_SaveData, ARRAYSIZE(m_SaveData) ) ) - return 0; - - listCount = m_listCount; // Get new list count - m_listCount = 0; // Clear loaded data - - for ( i = 0; i < listCount; i++ ) - { - if ( !restore.ReadFields( "GENT", &tmpEntity, gGlobalEntitySaveData, ARRAYSIZE(gGlobalEntitySaveData) ) ) - return 0; - EntityAdd( MAKE_STRING(tmpEntity.name), MAKE_STRING(tmpEntity.levelName), tmpEntity.state ); - } - return 1; -} - -void CGlobalState::EntityUpdate( string_t globalname, string_t mapname ) -{ - globalentity_t *pEnt = Find( globalname ); - - if ( pEnt ) - strcpy( pEnt->levelName, STRING(mapname) ); -} - - -void CGlobalState::ClearStates( void ) -{ - globalentity_t *pFree = m_pList; - while ( pFree ) - { - globalentity_t *pNext = pFree->pNext; - free( pFree ); - pFree = pNext; - } - Reset(); -} - - -void SaveGlobalState( SAVERESTOREDATA *pSaveData ) -{ - CSave saveHelper( pSaveData ); - gGlobalState.Save( saveHelper ); -} - - -void RestoreGlobalState( SAVERESTOREDATA *pSaveData ) -{ - CRestore restoreHelper( pSaveData ); - gGlobalState.Restore( restoreHelper ); -} - - -void ResetGlobalState( void ) -{ - gGlobalState.ClearStates(); - gInitHUD = TRUE; // Init the HUD on a new game / load game - g_iPlayersPerTeam = 0; -} - -// moved CWorld class definition to cbase.h -//======================= -// CWorld -// -// This spawns first when each level begins. -//======================= - -LINK_ENTITY_TO_CLASS( worldspawn, CWorld ); - -#define SF_WORLD_DARK 0x0001 // Fade from black at startup -#define SF_WORLD_TITLE 0x0002 // Display game title at startup -#define SF_WORLD_FORCETEAM 0x0004 // Force teams - -extern DLL_GLOBAL BOOL g_fGameOver; -float g_flWeaponCheat; - -void CWorld :: Spawn( void ) -{ - g_fGameOver = FALSE; - Precache( ); - g_flWeaponCheat = CVAR_GET_FLOAT( "sv_cheats" ); // Is the impulse 101 command allowed? - - if ( m_iArenaOff ) - g_iMapTurnedOffArena = TRUE; - else - g_iMapTurnedOffArena = FALSE; -} - -void CWorld :: Precache( void ) -{ - g_pLastSpawn = NULL; - - CVAR_SET_STRING("sv_gravity", "800"); // 67ft/sec - CVAR_SET_STRING("sv_stepsize", "18"); - CVAR_SET_STRING("room_type", "0"); // clear DSP - - // Create all the arenas - int i; - for ( i = 0; i < MAX_ARENAS; i++) - { - g_pArenaList[i] = GetClassPtr( ( CDiscArena *)NULL ); - g_pArenaList[i]->Spawn(); - } - - // Set up game rules - if (g_pGameRules) - { - delete g_pGameRules; - } - - g_pGameRules = InstallGameRules( ); - - //!!!UNDONE why is there so much Spawn code in the Precache function? I'll just keep it here - - ///!!!LATER - do we want a sound ent in deathmatch? (sjb) - //pSoundEnt = CBaseEntity::Create( "soundent", g_vecZero, g_vecZero, edict() ); - pSoundEnt = GetClassPtr( ( CSoundEnt *)NULL ); - pSoundEnt->Spawn(); - - if ( !pSoundEnt ) - { - ALERT ( at_console, "**COULD NOT CREATE SOUNDENT**\n" ); - } - - InitBodyQue(); - -// init sentence group playback stuff from sentences.txt. -// ok to call this multiple times, calls after first are ignored. - - SENTENCEG_Init(); - -// init texture type array from materials.txt - - TEXTURETYPE_Init(); - - -// the area based ambient sounds MUST be the first precache_sounds - -// player precaches - W_Precache (); // get weapon precaches - - ClientPrecache(); - -// sounds used from C physics code - PRECACHE_SOUND("common/null.wav"); // clears sound channels - - PRECACHE_SOUND( "items/suitchargeok1.wav" );//!!! temporary sound for respawning weapons. - PRECACHE_SOUND( "items/gunpickup2.wav" );// player picks up a gun. - - PRECACHE_SOUND( "common/bodydrop3.wav" );// dead bodies hitting the ground (animation events) - PRECACHE_SOUND( "common/bodydrop4.wav" ); - - PRECACHE_SOUND( "r_tele1.wav" ); // respawn sound - PRECACHE_SOUND( "scream1.wav" ); // falling scream sound - PRECACHE_SOUND( "scream2.wav" ); // falling scream sound - PRECACHE_SOUND( "scream3.wav" ); // falling scream sound - PRECACHE_SOUND( "decap.wav" ); // decapitation sound - PRECACHE_SOUND( "shatter.wav" ); // freeze decapitation sound - PRECACHE_MODEL( "models/head.mdl" ); // head - - g_Language = (int)CVAR_GET_FLOAT( "sv_language" ); - if ( g_Language == LANGUAGE_GERMAN ) - { - PRECACHE_MODEL( "models/germangibs.mdl" ); - } - else - { - PRECACHE_MODEL( "models/hgibs.mdl" ); - PRECACHE_MODEL( "models/agibs.mdl" ); - } - - PRECACHE_SOUND ("weapons/ric1.wav"); - PRECACHE_SOUND ("weapons/ric2.wav"); - PRECACHE_SOUND ("weapons/ric3.wav"); - PRECACHE_SOUND ("weapons/ric4.wav"); - PRECACHE_SOUND ("weapons/ric5.wav"); -// -// Setup light animation tables. 'a' is total darkness, 'z' is maxbright. -// - - // 0 normal - LIGHT_STYLE(0, "m"); - - // 1 FLICKER (first variety) - LIGHT_STYLE(1, "mmnmmommommnonmmonqnmmo"); - - // 2 SLOW STRONG PULSE - LIGHT_STYLE(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba"); - - // 3 CANDLE (first variety) - LIGHT_STYLE(3, "mmmmmaaaaammmmmaaaaaabcdefgabcdefg"); - - // 4 FAST STROBE - LIGHT_STYLE(4, "mamamamamama"); - - // 5 GENTLE PULSE 1 - LIGHT_STYLE(5,"jklmnopqrstuvwxyzyxwvutsrqponmlkj"); - - // 6 FLICKER (second variety) - LIGHT_STYLE(6, "nmonqnmomnmomomno"); - - // 7 CANDLE (second variety) - LIGHT_STYLE(7, "mmmaaaabcdefgmmmmaaaammmaamm"); - - // 8 CANDLE (third variety) - LIGHT_STYLE(8, "mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa"); - - // 9 SLOW STROBE (fourth variety) - LIGHT_STYLE(9, "aaaaaaaazzzzzzzz"); - - // 10 FLUORESCENT FLICKER - LIGHT_STYLE(10, "mmamammmmammamamaaamammma"); - - // 11 SLOW PULSE NOT FADE TO BLACK - LIGHT_STYLE(11, "abcdefghijklmnopqrrqponmlkjihgfedcba"); - - // 12 UNDERWATER LIGHT MUTATION - // this light only distorts the lightmap - no contribution - // is made to the brightness of affected surfaces - LIGHT_STYLE(12, "mmnnmmnnnmmnn"); - - // styles 32-62 are assigned by the light program for switchable lights - - // 63 testing - LIGHT_STYLE(63, "a"); - - for ( i = 0; i < ARRAYSIZE(gDecals); i++ ) - gDecals[i].index = DECAL_INDEX( gDecals[i].name ); - -// init the WorldGraph. - WorldGraph.InitGraph(); - -// make sure the .NOD file is newer than the .BSP file. - if ( !WorldGraph.CheckNODFile ( ( char * )STRING( gpGlobals->mapname ) ) ) - {// NOD file is not present, or is older than the BSP file. - WorldGraph.AllocNodes (); - } - else - {// Load the node graph for this level - if ( !WorldGraph.FLoadGraph ( (char *)STRING( gpGlobals->mapname ) ) ) - {// couldn't load, so alloc and prepare to build a graph. - ALERT ( at_console, "*Error opening .NOD file\n" ); - WorldGraph.AllocNodes (); - } - else - { - ALERT ( at_console, "\n*Graph Loaded!\n" ); - } - } - - if ( pev->speed > 0 ) - CVAR_SET_FLOAT( "sv_zmax", pev->speed ); - else - CVAR_SET_FLOAT( "sv_zmax", 4096 ); - - if ( pev->netname ) - { - ALERT( at_aiconsole, "Chapter title: %s\n", STRING(pev->netname) ); - CBaseEntity *pEntity = CBaseEntity::Create( "env_message", g_vecZero, g_vecZero, NULL ); - if ( pEntity ) - { - pEntity->SetThink( &CBaseEntity::SUB_CallUseToggle ); - pEntity->pev->message = pev->netname; - pev->netname = 0; - pEntity->pev->nextthink = gpGlobals->time + 0.3; - pEntity->pev->spawnflags = SF_MESSAGE_ONCE; - } - } - - if ( pev->spawnflags & SF_WORLD_DARK ) - CVAR_SET_FLOAT( "v_dark", 1.0 ); - else - CVAR_SET_FLOAT( "v_dark", 0.0 ); - - if ( pev->spawnflags & SF_WORLD_TITLE ) - gDisplayTitle = TRUE; // display the game title if this key is set - else - gDisplayTitle = FALSE; - - if ( pev->spawnflags & SF_WORLD_FORCETEAM ) - { - CVAR_SET_FLOAT( "mp_defaultteam", 1 ); - } - else - { - CVAR_SET_FLOAT( "mp_defaultteam", 0 ); - } - - // Discwar - if ( g_iPlayersPerTeam < 1 ) - g_iPlayersPerTeam = CVAR_GET_FLOAT("rc_playersperteam"); -} - - -// -// Just to ignore the "wad" field. -// -void CWorld :: KeyValue( KeyValueData *pkvd ) -{ - if ( FStrEq(pkvd->szKeyName, "skyname") ) - { - // Sent over net now. - CVAR_SET_STRING( "sv_skyname", pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "sounds") ) - { - gpGlobals->cdAudioTrack = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "WaveHeight") ) - { - // Sent over net now. - pev->scale = atof(pkvd->szValue) * (1.0/8.0); - pkvd->fHandled = TRUE; - CVAR_SET_FLOAT( "sv_wateramp", pev->scale ); - } - else if ( FStrEq(pkvd->szKeyName, "MaxRange") ) - { - pev->speed = atof(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "chaptertitle") ) - { - pev->netname = ALLOC_STRING(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "startdark") ) - { - // UNDONE: This is a gross hack!!! The CVAR is NOT sent over the client/sever link - // but it will work for single player - int flag = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - if ( flag ) - pev->spawnflags |= SF_WORLD_DARK; - } - else if ( FStrEq(pkvd->szKeyName, "newunit") ) - { - // Single player only. Clear save directory if set - if ( atoi(pkvd->szValue) ) - CVAR_SET_FLOAT( "sv_newunit", 1 ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "gametitle") ) - { - if ( atoi(pkvd->szValue) ) - pev->spawnflags |= SF_WORLD_TITLE; - - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "mapteams") ) - { - pev->team = ALLOC_STRING( pkvd->szValue ); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "defaultteam") ) - { - if ( atoi(pkvd->szValue) ) - { - pev->spawnflags |= SF_WORLD_FORCETEAM; - } - pkvd->fHandled = TRUE; - } - - // Discwar - else if ( FStrEq(pkvd->szKeyName, "playersperteam") ) - { - g_iPlayersPerTeam = atoi(pkvd->szValue); - pkvd->fHandled = TRUE; - } - else if ( FStrEq(pkvd->szKeyName, "no_arena") ) - { - if ( atoi(pkvd->szValue) ) - m_iArenaOff = TRUE; - pkvd->fHandled = TRUE; - } - - else - CBaseEntity::KeyValue( pkvd ); -} diff --git a/ricochet/dlls/wpn_shared/disc_weapon_disc.cpp b/ricochet/dlls/wpn_shared/disc_weapon_disc.cpp deleted file mode 100644 index 5f7a170..0000000 --- a/ricochet/dlls/wpn_shared/disc_weapon_disc.cpp +++ /dev/null @@ -1,753 +0,0 @@ - -//=========== (C) Copyright 1999 Valve, L.L.C. All rights reserved. =========== -// -// The copyright to the contents herein is the property of Valve, L.L.C. -// The contents may be used and/or copied only with the written permission of -// Valve, L.L.C., or in accordance with the terms and conditions stipulated in -// the agreement/contract under which the contents have been supplied. -// -// Purpose: Weapon functionality for Discwar -// -// $Workfile: $ -// $Date: $ -// -//----------------------------------------------------------------------------- -// $Log: $ -// -// $NoKeywords: $ -//============================================================================= -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "monsters.h" -#include "weapons.h" -#include "nodes.h" -#include "player.h" -#include "effects.h" -#include "discwar.h" -#include "disc_objects.h" -#include "disc_arena.h" - -// Disc trail colors -float g_iaDiscColors[33][3] = -{ - { 255, 255, 255, }, - { 250, 0, 0 }, - { 0, 0, 250 }, - { 0, 250, 0 }, - { 128, 128, 0 }, - { 128, 0, 128 }, - { 0, 128, 128 }, - { 128, 128, 128 }, - { 64, 128, 0 }, - { 128, 64, 0 }, - { 128, 0, 64 }, - { 64, 0, 128 }, - { 0, 64, 128 }, - { 64, 64, 128 }, - { 128, 64, 64 }, - { 64, 128, 64 }, - { 128, 128, 64 }, - { 128, 64, 128 }, - { 64, 128, 128 }, - { 250, 128, 0 }, - { 128, 250, 0 }, - { 128, 0, 250 }, - { 250, 0, 128 }, - { 0, 250, 128 }, - { 250, 250, 128 }, - { 250, 128, 250 }, - { 128, 250, 250 }, - { 250, 128, 64 }, - { 250, 64, 128 }, - { 128, 250, 64 }, - { 64, 128, 250 }, - { 128, 64, 250 }, -}; - -enum disc_e -{ - DISC_IDLE = 0, - DISC_FIDGET, - DISC_PINPULL, - DISC_THROW1, // toss - DISC_THROW2, // medium - DISC_THROW3, // hard - DISC_HOLSTER, - DISC_DRAW -}; - -#include "disc_weapon.h" - -LINK_ENTITY_TO_CLASS( weapon_disc, CDiscWeapon ); - -#if !defined( CLIENT_DLL ) -LINK_ENTITY_TO_CLASS( disc, CDisc ); - -//======================================================================================== -// DISC -//======================================================================================== -void CDisc::Spawn( void ) -{ - Precache( ); - - pev->classname = MAKE_STRING("disc"); - pev->movetype = MOVETYPE_BOUNCEMISSILE; - pev->solid = SOLID_TRIGGER; - - // Setup model - if ( m_iPowerupFlags & POW_HARD ) - SET_MODEL(ENT(pev), "models/disc_hard.mdl"); - else - SET_MODEL(ENT(pev), "models/disc.mdl"); - UTIL_SetSize(pev, Vector( -4,-4,-4 ), Vector(4, 4, 4)); - - UTIL_SetOrigin( pev, pev->origin ); - SetTouch( &CDisc::DiscTouch ); - SetThink( &CDisc::DiscThink ); - - m_iBounces = 0; - m_fDontTouchOwner = gpGlobals->time + 0.2; - m_fDontTouchEnemies = 0; - m_bRemoveSelf = false; - m_bTeleported = false; - m_pLockTarget = NULL; - - UTIL_MakeVectors( pev->angles ); - - // Fast powerup makes discs go faster - if ( m_iPowerupFlags & POW_FAST ) - pev->velocity = gpGlobals->v_forward * DISC_VELOCITY * 1.5; - else - pev->velocity = gpGlobals->v_forward * DISC_VELOCITY; - - // Pull our owner out so we will still touch it - if ( pev->owner ) - m_hOwner = Instance(pev->owner); - pev->owner = NULL; - - // Trail - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_BEAMFOLLOW ); - WRITE_SHORT(entindex()); // entity - WRITE_SHORT(m_iTrail ); // model - - if (m_bDecapitate) - WRITE_BYTE( 5 ); // life - else - WRITE_BYTE( 3 ); // life - - WRITE_BYTE( 5 ); // width - - WRITE_BYTE( g_iaDiscColors[pev->team][0] ); // r, g, b - WRITE_BYTE( g_iaDiscColors[pev->team][1] ); // r, g, b - WRITE_BYTE( g_iaDiscColors[pev->team][2] ); // r, g, b - - WRITE_BYTE( 250 ); // brightness - MESSAGE_END(); - - // Decapitator's make sound - if (m_bDecapitate) - EMIT_SOUND( ENT(pev), CHAN_VOICE, "weapons/rocket1.wav", 0.5, 0.5 ); - - // Highlighter - pev->renderfx = kRenderFxGlowShell; - for (int i = 0; i <= 2;i ++) - pev->rendercolor[i] = g_iaDiscColors[pev->team][i]; - pev->renderamt = 100; - - pev->nextthink = gpGlobals->time + 0.1; -} - -void CDisc::Precache( void ) -{ - PRECACHE_MODEL("models/disc.mdl"); - PRECACHE_MODEL("models/disc_hard.mdl"); - PRECACHE_SOUND("weapons/cbar_hitbod1.wav"); - PRECACHE_SOUND("weapons/cbar_hitbod2.wav"); - PRECACHE_SOUND("weapons/cbar_hitbod3.wav"); - PRECACHE_SOUND("weapons/altfire.wav"); - PRECACHE_SOUND("items/gunpickup2.wav"); - PRECACHE_SOUND("weapons/electro5.wav"); - PRECACHE_SOUND("weapons/xbow_hit1.wav"); - PRECACHE_SOUND("weapons/xbow_hit2.wav"); - PRECACHE_SOUND("weapons/rocket1.wav"); - PRECACHE_SOUND("dischit.wav"); - m_iTrail = PRECACHE_MODEL("sprites/smoke.spr"); - m_iSpriteTexture = PRECACHE_MODEL( "sprites/lgtning.spr" ); -} - -/* -void CDisc::SetObjectCollisionBox( void ) -{ - pev->absmin = pev->origin + Vector( -8, -8, 8 ); - pev->absmax = pev->origin + Vector( 8, 8, 8 ); -} -*/ - -// Give the disc back to it's owner -void CDisc::ReturnToThrower( void ) -{ - if (m_bDecapitate) - { - STOP_SOUND( edict(), CHAN_VOICE, "weapons/rocket1.wav" ); - if ( !m_bRemoveSelf ) - ((CBasePlayer*)(CBaseEntity*)m_hOwner)->GiveAmmo( MAX_DISCS, "disc", MAX_DISCS ); - } - else - { - if ( !m_bRemoveSelf ) - ((CBasePlayer*)(CBaseEntity*)m_hOwner)->GiveAmmo( 1, "disc", MAX_DISCS ); - } - - UTIL_Remove( this ); -} - -void CDisc::DiscTouch ( CBaseEntity *pOther ) -{ - // Push players backwards - if ( pOther->IsPlayer() ) - { - if ( ((CBaseEntity*)m_hOwner) == pOther ) - { - if (m_fDontTouchOwner < gpGlobals->time) - { - // Play catch sound - EMIT_SOUND_DYN( pOther->edict(), CHAN_WEAPON, "items/gunpickup2.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); - - ReturnToThrower(); - } - - return; - } - else if ( m_fDontTouchEnemies < gpGlobals->time) - { - if ( pev->team != pOther->pev->team ) - { - ((CBasePlayer*)pOther)->m_LastHitGroup = HITGROUP_GENERIC; - - // Do freeze seperately so you can freeze and shatter a person with a single shot - if ( m_iPowerupFlags & POW_FREEZE && ((CBasePlayer*)pOther)->m_iFrozen == FALSE ) - { - // Freeze the player and make them glow blue - EMIT_SOUND_DYN( pOther->edict(), CHAN_WEAPON, "weapons/electro5.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); - ((CBasePlayer*)pOther)->Freeze(); - - // If it's not a decap, return now. If it's a decap, continue to shatter - if ( !m_bDecapitate ) - { - m_fDontTouchEnemies = gpGlobals->time + 2.0; - return; - } - } - - // Decap or push - if (m_bDecapitate) - { - // Decapitate! - if ( m_bTeleported ) - ((CBasePlayer*)pOther)->m_flLastDiscHitTeleport = gpGlobals->time; - ((CBasePlayer*)pOther)->Decapitate( ((CBaseEntity*)m_hOwner)->pev ); - - m_fDontTouchEnemies = gpGlobals->time + 0.5; - } - else - { - // Play thwack sound - switch( RANDOM_LONG(0,2) ) - { - case 0: - EMIT_SOUND_DYN( pOther->edict(), CHAN_ITEM, "weapons/cbar_hitbod1.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); - break; - case 1: - EMIT_SOUND_DYN( pOther->edict(), CHAN_ITEM, "weapons/cbar_hitbod2.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); - break; - case 2: - EMIT_SOUND_DYN( pOther->edict(), CHAN_ITEM, "weapons/cbar_hitbod3.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); - break; - } - - // Push the player - Vector vecDir = pev->velocity.Normalize(); - pOther->pev->flags &= ~FL_ONGROUND; - ((CBasePlayer*)pOther)->m_vecHitVelocity = vecDir * DISC_PUSH_MULTIPLIER; - - // Shield flash only if the player isnt frozen - if ( ((CBasePlayer*)pOther)->m_iFrozen == false ) - { - pOther->pev->renderfx = kRenderFxGlowShell; - pOther->pev->rendercolor.x = 255; - pOther->pev->renderamt = 150; - } - - ((CBasePlayer*)pOther)->m_hLastPlayerToHitMe = m_hOwner; - ((CBasePlayer*)pOther)->m_flLastDiscHit = gpGlobals->time; - ((CBasePlayer*)pOther)->m_iLastDiscBounces = m_iBounces; - if ( m_bTeleported ) - ((CBasePlayer*)pOther)->m_flLastDiscHitTeleport = gpGlobals->time; - - m_fDontTouchEnemies = gpGlobals->time + 2.0; - } - } - } - } - // Hit a disc? - else if ( pOther->pev->iuser4 ) - { - // Enemy Discs destroy each other - if ( pOther->pev->iuser4 != pev->iuser4 ) - { - // Play a warp sound and sprite - CSprite *pSprite = CSprite::SpriteCreate( "sprites/discreturn.spr", pev->origin, TRUE ); - pSprite->AnimateAndDie( 60 ); - pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); - pSprite->SetScale( 1 ); - EMIT_SOUND_DYN( edict(), CHAN_ITEM, "dischit.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); - - // Return both discs to their owners - ((CDisc*)pOther)->ReturnToThrower(); - ReturnToThrower(); - } - else - { - // Friendly discs just pass through each other - } - } - else - { - m_iBounces++; - - switch ( RANDOM_LONG( 0, 1 ) ) - { - case 0: EMIT_SOUND_DYN( edict(), CHAN_ITEM, "weapons/xbow_hit1.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); break; - case 1: EMIT_SOUND_DYN( edict(), CHAN_ITEM, "weapons/xbow_hit2.wav", 1.0, ATTN_NORM, 0, 98 + RANDOM_LONG(0,3)); break; - } - - UTIL_Sparks( pev->origin, edict() ); - } -} - -void CDisc::DiscThink() -{ - // Make Freeze discs home towards any player ahead of them - if ( (m_iPowerupFlags & POW_FREEZE) && (m_iBounces == 0) ) - { - // Use an existing target if he's still in the view cone - if ( m_pLockTarget != NULL ) - { - Vector vecDir = (m_pLockTarget->pev->origin - pev->origin).Normalize(); - UTIL_MakeVectors( pev->angles ); - float flDot = DotProduct( gpGlobals->v_forward, vecDir ); - if ( flDot < 0.6 ) - m_pLockTarget = NULL; - } - - // Get a new target if we don't have one - if ( m_pLockTarget == NULL ) - { - CBaseEntity *pOther = NULL; - - // Examine all entities within a reasonable radius - while ((pOther = UTIL_FindEntityByClassname( pOther, "player" )) != NULL) - { - // Skip the guy who threw this - if ( ((CBaseEntity*)m_hOwner) == pOther ) - continue; - // Skip observers - if ( ((CBasePlayer*)pOther)->IsObserver() ) - continue; - - // Make sure the enemy's in a cone ahead of us - Vector vecDir = (pOther->pev->origin - pev->origin).Normalize(); - UTIL_MakeVectors( pev->angles ); - float flDot = DotProduct( gpGlobals->v_forward, vecDir ); - if ( flDot > 0.6 ) - { - m_pLockTarget = pOther; - break; - } - } - } - - // Track towards our target - if ( m_pLockTarget != NULL ) - { - // Calculate new velocity - Vector vecDir = (m_pLockTarget->pev->origin - pev->origin).Normalize(); - pev->velocity = ( pev->velocity.Normalize() + (vecDir.Normalize() * 0.25)).Normalize(); - pev->velocity = pev->velocity * DISC_VELOCITY; - pev->angles = UTIL_VecToAngles( pev->velocity ); - } - } - - // Track the player if we've bounced 3 or more times ( Fast discs remove immediately ) - if ( m_iBounces >= 3 || (m_iPowerupFlags & POW_FAST && m_iBounces >= 1) ) - { - // Remove myself if my owner's died - if (m_bRemoveSelf) - { - STOP_SOUND( edict(), CHAN_VOICE, "weapons/rocket1.wav" ); - UTIL_Remove( this ); - return; - } - - // 7 Bounces, just remove myself - if ( m_iBounces > 7 ) - { - ReturnToThrower(); - return; - } - - // Start heading for the player - if ( m_hOwner ) - { - Vector vecDir = ( m_hOwner->pev->origin - pev->origin ); - vecDir = vecDir.Normalize(); - pev->velocity = vecDir * DISC_VELOCITY; - pev->nextthink = gpGlobals->time + 0.1; - } - else - { - UTIL_Remove( this ); - } - } - - // Sanity check - if ( pev->velocity == g_vecZero ) - ReturnToThrower(); - - pev->nextthink = gpGlobals->time + 0.1; -} - -CDisc *CDisc::CreateDisc( Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, CDiscWeapon *pLauncher, bool bDecapitator, int iPowerupFlags ) -{ - CDisc *pDisc = GetClassPtr( (CDisc *)NULL ); - - UTIL_SetOrigin( pDisc->pev, vecOrigin ); - pDisc->m_iPowerupFlags = iPowerupFlags; - // Hard shots always decapitate - if ( pDisc->m_iPowerupFlags & POW_HARD ) - pDisc->m_bDecapitate = TRUE; - else - pDisc->m_bDecapitate = bDecapitator; - - pDisc->pev->angles = vecAngles; - pDisc->pev->owner = pOwner->edict(); - pDisc->pev->team = pOwner->pev->team; - pDisc->pev->iuser4 = pOwner->pev->iuser4; - - // Set the Group Info - pDisc->pev->groupinfo = pOwner->pev->groupinfo; - - pDisc->m_pLauncher = pLauncher; - - pDisc->Spawn(); - - return pDisc; -} -#endif // !CLIENT_DLL - -//======================================================================================== -// DISC WEAPON -//======================================================================================== -void CDiscWeapon::Spawn( ) -{ - Precache( ); - m_iId = WEAPON_DISC; - SET_MODEL(ENT(pev), "models/disc.mdl"); - -#if !defined( CLIENT_DLL ) - pev->dmg = gSkillData.plrDmgHandGrenade; -#endif - - m_iDefaultAmmo = STARTING_DISCS; - m_iFastShotDiscs = NUM_FASTSHOT_DISCS; - - FallInit();// get ready to fall down. -} - - -void CDiscWeapon::Precache( void ) -{ - PRECACHE_MODEL("models/disc.mdl"); - PRECACHE_MODEL("models/disc_hard.mdl"); - PRECACHE_MODEL("models/v_disc.mdl"); - PRECACHE_MODEL("models/p_disc.mdl"); - PRECACHE_SOUND("weapons/cbar_miss1.wav"); - m_iSpriteTexture = PRECACHE_MODEL( "sprites/lgtning.spr" ); - - m_usFireDisc = PRECACHE_EVENT( 1, "events/firedisc.sc" ); -} - -int CDiscWeapon::GetItemInfo(ItemInfo *p) -{ - p->pszName = STRING(pev->classname); - p->pszAmmo1 = "disc"; - p->iMaxAmmo1 = MAX_DISCS; - p->pszAmmo2 = NULL; - p->iMaxAmmo2 = -1; - p->iMaxClip = WEAPON_NOCLIP; - p->iSlot = 4; - p->iPosition = 0; - p->iId = WEAPON_DISC; - p->iWeight = 100; - p->iFlags = ITEM_FLAG_NOAUTORELOAD | ITEM_FLAG_NOAUTOSWITCHEMPTY; - - return 1; -} - - -BOOL CDiscWeapon::Deploy( ) -{ - return DefaultDeploy( "models/v_disc.mdl", "models/p_disc.mdl", DISC_DRAW, "crowbar" ); -} - -BOOL CDiscWeapon::CanHolster( void ) -{ - return TRUE; -} - -void CDiscWeapon::Holster( int skiplocal /* = 0 */ ) -{ - m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5; - if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]) - { - SendWeaponAnim( DISC_HOLSTER, 1 ); - } - else - { - // no more grenades! - m_pPlayer->pev->weapons &= ~(1<nextthink = gpGlobals->time + 0.1; - } - - EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "common/null.wav", 1.0, ATTN_NORM); -} - -CDisc *CDiscWeapon::FireDisc( bool bDecapitator ) -{ - CDisc *pReturnDisc = NULL; - - SendWeaponAnim( DISC_THROW1, 1 ); - - m_pPlayer->SetAnimation( PLAYER_ATTACK1 ); - -#if !defined( CLIENT_DLL ) - Vector vecFireDir = g_vecZero; - vecFireDir[1] = m_pPlayer->pev->v_angle[1]; - UTIL_MakeVectors( vecFireDir ); - Vector vecSrc = m_pPlayer->pev->origin + (m_pPlayer->pev->view_ofs * 0.25) + gpGlobals->v_forward * 16; - CDisc *pDisc = CDisc::CreateDisc( vecSrc, vecFireDir, m_pPlayer, this, bDecapitator, m_pPlayer->m_iPowerups ); - pReturnDisc = pDisc; - - // Triple shot fires 2 more disks - if ( m_pPlayer->HasPowerup( POW_TRIPLE ) ) - { - // The 2 extra discs from triple shot are removed after their 3rd bounce - vecFireDir[1] = m_pPlayer->pev->v_angle[1] - 7; - UTIL_MakeVectors( vecFireDir ); - vecSrc = m_pPlayer->pev->origin + (m_pPlayer->pev->view_ofs * 0.25) + gpGlobals->v_forward * 16; - pDisc = CDisc::CreateDisc( vecSrc, vecFireDir, m_pPlayer, this, bDecapitator, POW_TRIPLE ); - pDisc->m_bRemoveSelf = true; - - vecFireDir[1] = m_pPlayer->pev->v_angle[1] + 7; - UTIL_MakeVectors( vecFireDir ); - vecSrc = m_pPlayer->pev->origin + (m_pPlayer->pev->view_ofs * 0.25) + gpGlobals->v_forward * 16; - pDisc = CDisc::CreateDisc( vecSrc, vecFireDir, m_pPlayer, this, bDecapitator, POW_TRIPLE ); - pDisc->m_bRemoveSelf = true; - } - -#endif - - // Fast shot allows faster throwing - float flTimeToNextShot = 0.5; - if ( m_pPlayer->HasPowerup( POW_FAST ) ) - flTimeToNextShot = 0.2; - - m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + flTimeToNextShot; - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + flTimeToNextShot; - - return pReturnDisc; -} - -void CDiscWeapon::PrimaryAttack() -{ -#if !defined( CLIENT_DLL ) - if ( m_pPlayer->m_pCurrentArena ) - { - if ( m_pPlayer->m_pCurrentArena->AllowedToFire() == false ) - return; - } -#endif - - if ( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] ) - { - PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usFireDisc, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 0, 0 ); - CDisc *pDisc = FireDisc( false ); - - // Fast powerup has a number of discs per 1 normal disc - if ( m_pPlayer->HasPowerup( POW_FAST ) ) - { - m_iFastShotDiscs--; - if ( m_iFastShotDiscs ) - { - // Make this disc remove itself - pDisc->m_bRemoveSelf = true; - return; - } - - m_iFastShotDiscs = NUM_FASTSHOT_DISCS; - } - - m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; - - // If we have powered discs, remove one - if ( m_pPlayer->m_iPowerupDiscs ) - { - m_pPlayer->m_iPowerupDiscs--; - if ( !m_pPlayer->m_iPowerupDiscs ) - m_pPlayer->RemoveAllPowerups(); - } - } -} - -void CDiscWeapon::SecondaryAttack() -{ -#if !defined( CLIENT_DLL ) - if ( m_pPlayer->m_pCurrentArena ) - { - if ( m_pPlayer->m_pCurrentArena->AllowedToFire() == false ) - return; - } -#endif - - // Fast powerup has a number of discs per 1 normal disc (so it can throw a decap when it has at least 1 real disc) - if ( (m_pPlayer->HasPowerup( POW_FAST ) && m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0 ) || - ( m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] == MAX_DISCS ) ) - { - PLAYBACK_EVENT_FULL( FEV_NOTHOST, m_pPlayer->edict(), m_usFireDisc, 0.0, (float *)&g_vecZero, (float *)&g_vecZero, 0.0, 0.0, 0, 0, 1, 0 ); - - FireDisc( true ); - - // Deduct MAX_DISCS from fast shot, or deduct all discs if we don't have fast shot - if ( m_pPlayer->HasPowerup( POW_FAST ) ) - { - for ( int i = 1; i <= MAX_DISCS; i++ ) - { - m_iFastShotDiscs--; - if ( m_iFastShotDiscs == 0 ) - { - m_iFastShotDiscs = NUM_FASTSHOT_DISCS; - m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]--; - - // Remove a powered disc - m_pPlayer->m_iPowerupDiscs--; - if ( !m_pPlayer->m_iPowerupDiscs ) - m_pPlayer->RemoveAllPowerups(); - } - } - } - else - { - m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] = 0; - - // If we have powered discs, remove one - if ( m_pPlayer->m_iPowerupDiscs ) - { - m_pPlayer->m_iPowerupDiscs--; - if ( !m_pPlayer->m_iPowerupDiscs ) - m_pPlayer->RemoveAllPowerups(); - } - } - } -} - - -void CDiscWeapon::WeaponIdle( void ) -{ -#if !defined( CLIENT_DLL ) - if ( m_pPlayer->HasPowerup(POW_VISUALIZE_REBOUNDS) ) - { - Vector vecFireDir = g_vecZero; - Vector vecSrc = m_pPlayer->pev->origin + (m_pPlayer->pev->view_ofs * 0.25); - vecFireDir[1] = m_pPlayer->pev->v_angle[1]; - - // Draw beams to show where rebounds will go - for (int i = 0; i < 3; i++) - { - TraceResult tr; - UTIL_MakeVectors( vecFireDir ); - UTIL_TraceLine( vecSrc, (vecSrc + gpGlobals->v_forward * 2048), ignore_monsters, ENT(pev), &tr ); - - MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); - WRITE_BYTE( TE_BEAMPOINTS ); - WRITE_COORD( vecSrc.x); - WRITE_COORD( vecSrc.y); - WRITE_COORD( vecSrc.z); - WRITE_COORD( tr.vecEndPos.x); - WRITE_COORD( tr.vecEndPos.y); - WRITE_COORD( tr.vecEndPos.z); - WRITE_SHORT( m_iSpriteTexture ); - WRITE_BYTE( 0 ); // framerate - WRITE_BYTE( 0 ); // framerate - WRITE_BYTE( 1 ); // life - WRITE_BYTE( 40 ); // width - WRITE_BYTE( 0 ); // noise - WRITE_BYTE( i * 50 ); // r, g, b - WRITE_BYTE( i * 50 ); // r, g, b - WRITE_BYTE( 200 - (i * 50)); // r, g, b - WRITE_BYTE( 128 - (i * 30) ); // r, g, b - WRITE_BYTE( 0 ); // speed - MESSAGE_END(); - - // Calculate rebound angle - Vector vecOut; - Vector vecIn = tr.vecEndPos - (tr.vecEndPos - (gpGlobals->v_forward * 5)); - float backoff = DotProduct( vecIn, tr.vecPlaneNormal ) * 2.0; - for (int i=0 ; i<3 ; i++) - { - float change = tr.vecPlaneNormal[i] * backoff; - vecOut[i] = vecIn[i] - change; - if (vecOut[i] > -0.1 && vecOut[i] < 0.1) - vecOut[i] = 0; - } - - vecOut = vecOut.Normalize(); - vecSrc = tr.vecEndPos; - vecFireDir = UTIL_VecToAngles(vecOut); - } - } -#endif - - if (m_flTimeWeaponIdle > UTIL_WeaponTimeBase()) - return; - - if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]) - { - int iAnim; - float flRand = UTIL_SharedRandomFloat( m_pPlayer->random_seed, 0, 1 ); - if (flRand <= 0.75) - { - iAnim = DISC_IDLE; - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + UTIL_SharedRandomFloat( m_pPlayer->random_seed, 10, 15 );// how long till we do this again. - } - else - { - iAnim = DISC_FIDGET; - m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 75.0 / 30.0; - } - - SendWeaponAnim( iAnim, 1 ); - } -} - -// Prevent disc weapons lying around on the ground -int CDiscWeapon::AddDuplicate( CBasePlayerItem *pOriginal ) -{ - pev->flags |= FL_KILLME; - return FALSE; -} - - - diff --git a/ricochet/dlls/xen.cpp b/ricochet/dlls/xen.cpp deleted file mode 100644 index ebd9b44..0000000 --- a/ricochet/dlls/xen.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/*** -* -* Copyright (c) 1999, 2000 Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ -#include "extdll.h" -#include "util.h" -#include "cbase.h" -#include "animation.h" -#include "effects.h" - - -#define XEN_PLANT_GLOW_SPRITE "sprites/flare3.spr" -#define XEN_PLANT_HIDE_TIME 5 - - -class CActAnimating : public CBaseAnimating -{ -public: - void SetActivity( Activity act ); - inline Activity GetActivity( void ) { return m_Activity; } - - virtual int ObjectCaps( void ) { return CBaseAnimating :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - -private: - Activity m_Activity; -}; - -TYPEDESCRIPTION CActAnimating::m_SaveData[] = -{ - DEFINE_FIELD( CActAnimating, m_Activity, FIELD_INTEGER ), -}; - -IMPLEMENT_SAVERESTORE( CActAnimating, CBaseAnimating ); - -void CActAnimating :: SetActivity( Activity act ) -{ - int sequence = LookupActivity( act ); - if ( sequence != ACTIVITY_NOT_AVAILABLE ) - { - pev->sequence = sequence; - m_Activity = act; - pev->frame = 0; - ResetSequenceInfo( ); - } -} - - - - -class CXenPLight : public CActAnimating -{ -public: - void Spawn( void ); - void Precache( void ); - void Touch( CBaseEntity *pOther ); - void Think( void ); - - void LightOn( void ); - void LightOff( void ); - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - -private: - CSprite *m_pGlow; -}; - -LINK_ENTITY_TO_CLASS( xen_plantlight, CXenPLight ); - -TYPEDESCRIPTION CXenPLight::m_SaveData[] = -{ - DEFINE_FIELD( CXenPLight, m_pGlow, FIELD_CLASSPTR ), -}; - -IMPLEMENT_SAVERESTORE( CXenPLight, CActAnimating ); - -void CXenPLight :: Spawn( void ) -{ - Precache(); - - SET_MODEL( ENT(pev), "models/light.mdl" ); - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_TRIGGER; - - UTIL_SetSize( pev, Vector(-80,-80,0), Vector(80,80,32)); - SetActivity( ACT_IDLE ); - pev->nextthink = gpGlobals->time + 0.1; - pev->frame = RANDOM_FLOAT(0,255); - - m_pGlow = CSprite::SpriteCreate( XEN_PLANT_GLOW_SPRITE, pev->origin + Vector(0,0,(pev->mins.z+pev->maxs.z)*0.5), FALSE ); - m_pGlow->SetTransparency( kRenderGlow, pev->rendercolor.x, pev->rendercolor.y, pev->rendercolor.z, pev->renderamt, pev->renderfx ); - m_pGlow->SetAttachment( edict(), 1 ); -} - - -void CXenPLight :: Precache( void ) -{ - PRECACHE_MODEL( "models/light.mdl" ); - PRECACHE_MODEL( XEN_PLANT_GLOW_SPRITE ); -} - - -void CXenPLight :: Think( void ) -{ - StudioFrameAdvance(); - pev->nextthink = gpGlobals->time + 0.1; -} - - -void CXenPLight :: Touch( CBaseEntity *pOther ) -{ - if ( pOther->IsPlayer() ) - { - pev->dmgtime = gpGlobals->time + XEN_PLANT_HIDE_TIME; - } -} - - -void CXenPLight :: LightOn( void ) -{ - SUB_UseTargets( this, USE_ON, 0 ); - if ( m_pGlow ) - m_pGlow->pev->effects &= ~EF_NODRAW; -} - - -void CXenPLight :: LightOff( void ) -{ - SUB_UseTargets( this, USE_OFF, 0 ); - if ( m_pGlow ) - m_pGlow->pev->effects |= EF_NODRAW; -} - - - -class CXenHair : public CActAnimating -{ -public: - void Spawn( void ); - void Precache( void ); - void Think( void ); -}; - -LINK_ENTITY_TO_CLASS( xen_hair, CXenHair ); - -#define SF_HAIR_SYNC 0x0001 - -void CXenHair::Spawn( void ) -{ - Precache(); - SET_MODEL( edict(), "models/hair.mdl" ); - UTIL_SetSize( pev, Vector(-4,-4,0), Vector(4,4,32)); - pev->sequence = 0; - - if ( !(pev->spawnflags & SF_HAIR_SYNC) ) - { - pev->frame = RANDOM_FLOAT(0,255); - pev->framerate = RANDOM_FLOAT( 0.7, 1.4 ); - } - ResetSequenceInfo( ); - - pev->solid = SOLID_NOT; - pev->movetype = MOVETYPE_NONE; - pev->nextthink = gpGlobals->time + RANDOM_FLOAT( 0.1, 0.4 ); // Load balance these a bit -} - - -void CXenHair::Think( void ) -{ - StudioFrameAdvance(); - pev->nextthink = gpGlobals->time + 0.5; -} - - -void CXenHair::Precache( void ) -{ - PRECACHE_MODEL( "models/hair.mdl" ); -} - - -class CXenTreeTrigger : public CBaseEntity -{ -public: - void Touch( CBaseEntity *pOther ); - static CXenTreeTrigger *TriggerCreate( edict_t *pOwner, const Vector &position ); -}; -LINK_ENTITY_TO_CLASS( xen_ttrigger, CXenTreeTrigger ); - -CXenTreeTrigger *CXenTreeTrigger :: TriggerCreate( edict_t *pOwner, const Vector &position ) -{ - CXenTreeTrigger *pTrigger = GetClassPtr( (CXenTreeTrigger *)NULL ); - pTrigger->pev->origin = position; - pTrigger->pev->classname = MAKE_STRING("xen_ttrigger"); - pTrigger->pev->solid = SOLID_TRIGGER; - pTrigger->pev->movetype = MOVETYPE_NONE; - pTrigger->pev->owner = pOwner; - - return pTrigger; -} - - -void CXenTreeTrigger::Touch( CBaseEntity *pOther ) -{ - if ( pev->owner ) - { - CBaseEntity *pEntity = CBaseEntity::Instance(pev->owner); - pEntity->Touch( pOther ); - } -} - - -#define TREE_AE_ATTACK 1 - -class CXenTree : public CActAnimating -{ -public: - void Spawn( void ); - void Precache( void ); - void Touch( CBaseEntity *pOther ); - void Think( void ); - int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { Attack(); return 0; } - void HandleAnimEvent( MonsterEvent_t *pEvent ); - void Attack( void ); - int Classify( void ) { return CLASS_BARNACLE; } - - virtual int Save( CSave &save ); - virtual int Restore( CRestore &restore ); - static TYPEDESCRIPTION m_SaveData[]; - - static const char *pAttackHitSounds[]; - static const char *pAttackMissSounds[]; - -private: - CXenTreeTrigger *m_pTrigger; -}; - -LINK_ENTITY_TO_CLASS( xen_tree, CXenTree ); - -TYPEDESCRIPTION CXenTree::m_SaveData[] = -{ - DEFINE_FIELD( CXenTree, m_pTrigger, FIELD_CLASSPTR ), -}; - -IMPLEMENT_SAVERESTORE( CXenTree, CActAnimating ); - -void CXenTree :: Spawn( void ) -{ - Precache(); - - SET_MODEL( ENT(pev), "models/tree.mdl" ); - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_BBOX; - - pev->takedamage = DAMAGE_YES; - - UTIL_SetSize( pev, Vector(-30,-30,0), Vector(30,30,188)); - SetActivity( ACT_IDLE ); - pev->nextthink = gpGlobals->time + 0.1; - pev->frame = RANDOM_FLOAT(0,255); - pev->framerate = RANDOM_FLOAT( 0.7, 1.4 ); - - Vector triggerPosition; - UTIL_MakeVectorsPrivate( pev->angles, triggerPosition, NULL, NULL ); - triggerPosition = pev->origin + (triggerPosition * 64); - // Create the trigger - m_pTrigger = CXenTreeTrigger::TriggerCreate( edict(), triggerPosition ); - UTIL_SetSize( m_pTrigger->pev, Vector( -24, -24, 0 ), Vector( 24, 24, 128 ) ); -} - -const char *CXenTree::pAttackHitSounds[] = -{ - "zombie/claw_strike1.wav", - "zombie/claw_strike2.wav", - "zombie/claw_strike3.wav", -}; - -const char *CXenTree::pAttackMissSounds[] = -{ - "zombie/claw_miss1.wav", - "zombie/claw_miss2.wav", -}; - -void CXenTree :: Precache( void ) -{ - PRECACHE_MODEL( "models/tree.mdl" ); - PRECACHE_MODEL( XEN_PLANT_GLOW_SPRITE ); - PRECACHE_SOUND_ARRAY( pAttackHitSounds ); - PRECACHE_SOUND_ARRAY( pAttackMissSounds ); -} - - -void CXenTree :: Touch( CBaseEntity *pOther ) -{ - if ( !pOther->IsPlayer() && FClassnameIs( pOther->pev, "monster_bigmomma" ) ) - return; - - Attack(); -} - - -void CXenTree :: Attack( void ) -{ -} - - -void CXenTree :: HandleAnimEvent( MonsterEvent_t *pEvent ) -{ - switch( pEvent->event ) - { - case TREE_AE_ATTACK: - { - CBaseEntity *pList[8]; - BOOL sound = FALSE; - int count = UTIL_EntitiesInBox( pList, 8, m_pTrigger->pev->absmin, m_pTrigger->pev->absmax, FL_MONSTER|FL_CLIENT ); - Vector forward; - - UTIL_MakeVectorsPrivate( pev->angles, forward, NULL, NULL ); - - for ( int i = 0; i < count; i++ ) - { - if ( pList[i] != this ) - { - if ( pList[i]->pev->owner != edict() ) - { - sound = TRUE; - pList[i]->TakeDamage( pev, pev, 25, DMG_CRUSH | DMG_SLASH ); - pList[i]->pev->punchangle.x = 15; - pList[i]->pev->velocity = pList[i]->pev->velocity + forward * 100; - } - } - } - - if ( sound ) - { - EMIT_SOUND_ARRAY_DYN( CHAN_WEAPON, pAttackHitSounds ); - } - } - return; - } - - CActAnimating::HandleAnimEvent( pEvent ); -} - -void CXenTree :: Think( void ) -{ - float flInterval = StudioFrameAdvance(); - pev->nextthink = gpGlobals->time + 0.1; - DispatchAnimEvents( flInterval ); -} - - -// UNDONE: These need to smoke somehow when they take damage -// Touch behavior? -// Cause damage in smoke area - -// -// Spores -// -class CXenSpore : public CActAnimating -{ -public: - void Spawn( void ); - void Precache( void ); - void Touch( CBaseEntity *pOther ); - void Think( void ); - int TakeDamage( entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType ) { Attack(); return 0; } -// void HandleAnimEvent( MonsterEvent_t *pEvent ); - void Attack( void ) {} - - static const char *pModelNames[]; -}; - -class CXenSporeSmall : public CXenSpore -{ - void Spawn( void ); -}; - -class CXenSporeMed : public CXenSpore -{ - void Spawn( void ); -}; - -class CXenSporeLarge : public CXenSpore -{ - void Spawn( void ); - - static const Vector m_hullSizes[]; -}; - -// Fake collision box for big spores -class CXenHull : public CPointEntity -{ -public: - static CXenHull *CreateHull( CBaseEntity *source, const Vector &mins, const Vector &maxs, const Vector &offset ); - int Classify( void ) { return CLASS_BARNACLE; } -}; - -CXenHull *CXenHull :: CreateHull( CBaseEntity *source, const Vector &mins, const Vector &maxs, const Vector &offset ) -{ - CXenHull *pHull = GetClassPtr( (CXenHull *)NULL ); - - UTIL_SetOrigin( pHull->pev, source->pev->origin + offset ); - SET_MODEL( pHull->edict(), STRING(source->pev->model) ); - pHull->pev->solid = SOLID_BBOX; - pHull->pev->classname = MAKE_STRING("xen_hull"); - pHull->pev->movetype = MOVETYPE_NONE; - pHull->pev->owner = source->edict(); - UTIL_SetSize( pHull->pev, mins, maxs ); - pHull->pev->renderamt = 0; - pHull->pev->rendermode = kRenderTransTexture; - // pHull->pev->effects = EF_NODRAW; - - return pHull; -} - - -LINK_ENTITY_TO_CLASS( xen_spore_small, CXenSporeSmall ); -LINK_ENTITY_TO_CLASS( xen_spore_medium, CXenSporeMed ); -LINK_ENTITY_TO_CLASS( xen_spore_large, CXenSporeLarge ); -LINK_ENTITY_TO_CLASS( xen_hull, CXenHull ); - -void CXenSporeSmall::Spawn( void ) -{ - pev->skin = 0; - CXenSpore::Spawn(); - UTIL_SetSize( pev, Vector(-16,-16,0), Vector(16,16,64)); -} -void CXenSporeMed::Spawn( void ) -{ - pev->skin = 1; - CXenSpore::Spawn(); - UTIL_SetSize( pev, Vector(-40,-40,0), Vector(40,40,120)); -} - - -// I just eyeballed these -- fill in hulls for the legs -const Vector CXenSporeLarge::m_hullSizes[] = -{ - Vector( 90, -25, 0 ), - Vector( 25, 75, 0 ), - Vector( -15, -100, 0 ), - Vector( -90, -35, 0 ), - Vector( -90, 60, 0 ), -}; - -void CXenSporeLarge::Spawn( void ) -{ - pev->skin = 2; - CXenSpore::Spawn(); - UTIL_SetSize( pev, Vector(-48,-48,110), Vector(48,48,240)); - - Vector forward, right; - - UTIL_MakeVectorsPrivate( pev->angles, forward, right, NULL ); - - // Rotate the leg hulls into position - for ( int i = 0; i < ARRAYSIZE(m_hullSizes); i++ ) - CXenHull :: CreateHull( this, Vector(-12, -12, 0 ), Vector( 12, 12, 120 ), (m_hullSizes[i].x * forward) + (m_hullSizes[i].y * right) ); -} - -void CXenSpore :: Spawn( void ) -{ - Precache(); - - SET_MODEL( ENT(pev), pModelNames[pev->skin] ); - pev->movetype = MOVETYPE_NONE; - pev->solid = SOLID_BBOX; - pev->takedamage = DAMAGE_YES; - -// SetActivity( ACT_IDLE ); - pev->sequence = 0; - pev->frame = RANDOM_FLOAT(0,255); - pev->framerate = RANDOM_FLOAT( 0.7, 1.4 ); - ResetSequenceInfo( ); - pev->nextthink = gpGlobals->time + RANDOM_FLOAT( 0.1, 0.4 ); // Load balance these a bit -} - -const char *CXenSpore::pModelNames[] = -{ - "models/fungus(small).mdl", - "models/fungus.mdl", - "models/fungus(large).mdl", -}; - - -void CXenSpore :: Precache( void ) -{ - PRECACHE_MODEL( (char *)pModelNames[pev->skin] ); -} - - -void CXenSpore :: Touch( CBaseEntity *pOther ) -{ -} - - -void CXenSpore :: Think( void ) -{ - float flInterval = StudioFrameAdvance(); - pev->nextthink = gpGlobals->time + 0.1; - -#if 0 - DispatchAnimEvents( flInterval ); - - switch( GetActivity() ) - { - default: - case ACT_IDLE: - break; - - } -#endif -} - - diff --git a/ricochet/pm_shared/pm_debug.cpp b/ricochet/pm_shared/pm_debug.cpp deleted file mode 100644 index 2ccb8a5..0000000 --- a/ricochet/pm_shared/pm_debug.cpp +++ /dev/null @@ -1,305 +0,0 @@ -#include "mathlib.h" -#include "const.h" -#include "usercmd.h" -#include "pm_defs.h" -#include "pm_shared.h" -#include "pm_movevars.h" -#include "pm_debug.h" - -#include - -#pragma warning(disable : 4244) -#pragma warning(disable : 4305) - -extern playermove_t *pmove; - -// Expand debugging BBOX particle hulls by this many units. -#define BOX_GAP 0.0f - -static int PM_boxpnt[6][4] = -{ - { 0, 4, 6, 2 }, // +X - { 0, 1, 5, 4 }, // +Y - { 0, 2, 3, 1 }, // +Z - { 7, 5, 1, 3 }, // -X - { 7, 3, 2, 6 }, // -Y - { 7, 6, 4, 5 }, // -Z -}; - -void PM_ShowClipBox( void ) -{ -#if defined( _DEBUG ) - vec3_t org; - vec3_t offset = { 0, 0, 0 }; - - if ( !pmove->runfuncs ) - return; - - // More debugging, draw the particle bbox for player and for the entity we are looking directly at. - // aslo prints entity info to the console overlay. - //if ( !pmove->server ) - // return; - - // Draw entity in center of view - // Also draws the normal to the clip plane that intersects our movement ray. Leaves a particle - // trail at the intersection point. - PM_ViewEntity(); - - VectorCopy( pmove->origin, org ); - - if ( pmove->server ) - { - VectorAdd( org, offset, org ); - } - else - { - VectorSubtract( org, offset, org ); - } - - // Show our BBOX in particles. - PM_DrawBBox( pmove->player_mins[pmove->usehull], pmove->player_maxs[pmove->usehull], org, pmove->server ? 132 : 0, 0.1 ); - - PM_ParticleLine( org, org, pmove->server ? 132 : 0, 0.1, 5.0 ); -/* - { - int i; - for ( i = 0; i < pmove->numphysent; i++ ) - { - if ( pmove->physents[ i ].info >= 1 && pmove->physents[ i ].info <= 4 ) - { - PM_DrawBBox( pmove->player_mins[pmove->usehull], pmove->player_maxs[pmove->usehull], pmove->physents[i].origin, 132, 0.1 ); - } - } - } -*/ -#endif -} - -/* -=============== -PM_ParticleLine(vec3_t start, vec3_t end, int color, float life) - -================ -*/ -void PM_ParticleLine(vec3_t start, vec3_t end, int pcolor, float life, float vert) -{ - float linestep = 2.0f; - float curdist; - float len; - vec3_t curpos; - vec3_t diff; - int i; - // Determine distance; - - VectorSubtract(end, start, diff); - - len = VectorNormalize(diff); - - curdist = 0; - while (curdist <= len) - { - for (i = 0; i < 3; i++) - curpos[i] = start[i] + curdist * diff[i]; - - pmove->PM_Particle( curpos, pcolor, life, 0, vert); - curdist += linestep; - } - -} - -/* -================ -PM_DrawRectangle(vec3_t tl, vec3_t br) - -================ -*/ -void PM_DrawRectangle(vec3_t tl, vec3_t bl, vec3_t tr, vec3_t br, int pcolor, float life) -{ - PM_ParticleLine(tl, bl, pcolor, life, 0); - PM_ParticleLine(bl, br, pcolor, life, 0); - PM_ParticleLine(br, tr, pcolor, life, 0); - PM_ParticleLine(tr, tl, pcolor, life, 0); -} - -/* -================ -PM_DrawPhysEntBBox(int num) - -================ -*/ -void PM_DrawPhysEntBBox(int num, int pcolor, float life) -{ - physent_t *pe; - vec3_t org; - int j; - vec3_t tmp; - vec3_t p[8]; - float gap = BOX_GAP; - vec3_t modelmins, modelmaxs; - - if (num >= pmove->numphysent || - num <= 0) - return; - - pe = &pmove->physents[num]; - - if (pe->model) - { - VectorCopy(pe->origin, org); - - pmove->PM_GetModelBounds( pe->model, modelmins, modelmaxs ); - for (j = 0; j < 8; j++) - { - tmp[0] = (j & 1) ? modelmins[0] - gap : modelmaxs[0] + gap; - tmp[1] = (j & 2) ? modelmins[1] - gap : modelmaxs[1] + gap; - tmp[2] = (j & 4) ? modelmins[2] - gap : modelmaxs[2] + gap; - - VectorCopy(tmp, p[j]); - } - - // If the bbox should be rotated, do that - if (pe->angles[0] || pe->angles[1] || pe->angles[2]) - { - vec3_t forward, right, up; - - AngleVectorsTranspose(pe->angles, forward, right, up); - for (j = 0; j < 8; j++) - { - VectorCopy(p[j], tmp); - p[j][0] = DotProduct ( tmp, forward ); - p[j][1] = DotProduct ( tmp, right ); - p[j][2] = DotProduct ( tmp, up ); - } - } - - // Offset by entity origin, if any. - for (j = 0; j < 8; j++) - VectorAdd(p[j], org, p[j]); - - for (j = 0; j < 6; j++) - { - PM_DrawRectangle( - p[PM_boxpnt[j][1]], - p[PM_boxpnt[j][0]], - p[PM_boxpnt[j][2]], - p[PM_boxpnt[j][3]], - pcolor, life); - } - } - else - { - for (j = 0; j < 8; j++) - { - tmp[0] = (j & 1) ? pe->mins[0] : pe->maxs[0]; - tmp[1] = (j & 2) ? pe->mins[1] : pe->maxs[1]; - tmp[2] = (j & 4) ? pe->mins[2] : pe->maxs[2]; - - VectorAdd(tmp, pe->origin, tmp); - VectorCopy(tmp, p[j]); - } - - for (j = 0; j < 6; j++) - { - PM_DrawRectangle( - p[PM_boxpnt[j][1]], - p[PM_boxpnt[j][0]], - p[PM_boxpnt[j][2]], - p[PM_boxpnt[j][3]], - pcolor, life); - } - - } -} - -/* -================ -PM_DrawBBox(vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life) - -================ -*/ -void PM_DrawBBox(vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life) -{ - int j; - - vec3_t tmp; - vec3_t p[8]; - float gap = BOX_GAP; - - for (j = 0; j < 8; j++) - { - tmp[0] = (j & 1) ? mins[0] - gap : maxs[0] + gap; - tmp[1] = (j & 2) ? mins[1] - gap : maxs[1] + gap ; - tmp[2] = (j & 4) ? mins[2] - gap : maxs[2] + gap ; - - VectorAdd(tmp, origin, tmp); - VectorCopy(tmp, p[j]); - } - - for (j = 0; j < 6; j++) - { - PM_DrawRectangle( - p[PM_boxpnt[j][1]], - p[PM_boxpnt[j][0]], - p[PM_boxpnt[j][2]], - p[PM_boxpnt[j][3]], - pcolor, life); - } -} - - -#ifndef DEDICATED - -/* -================ -PM_ViewEntity - -Shows a particle trail from player to entity in crosshair. -Shows particles at that entities bbox - -Tries to shoot a ray out by about 128 units. -================ -*/ -void PM_ViewEntity( void ) -{ - vec3_t forward, right, up; - float raydist = 256.0f; - vec3_t origin; - vec3_t end; - int i; - pmtrace_t trace; - int pcolor = 77; - float fup; - -#if 0 - if ( !pm_showclip.value ) - return; -#endif - - AngleVectors (pmove->angles, forward, right, up); // Determine movement angles - - VectorCopy( pmove->origin, origin); - - fup = 0.5*( pmove->player_mins[pmove->usehull][2] + pmove->player_maxs[pmove->usehull][2] ); - fup += pmove->view_ofs[2]; - fup -= 4; - - for (i = 0; i < 3; i++) - { - end[i] = origin[i] + raydist * forward[i]; - } - - trace = pmove->PM_PlayerTrace( origin, end, PM_STUDIO_BOX, -1 ); - - if (trace.ent > 0) // Not the world - { - pcolor = 111; - } - - // Draw the hull or bbox. - if (trace.ent > 0) - { - PM_DrawPhysEntBBox(trace.ent, pcolor, 0.3f); - } -} - -#endif \ No newline at end of file diff --git a/ricochet/pm_shared/pm_debug.h b/ricochet/pm_shared/pm_debug.h deleted file mode 100644 index 18db48b..0000000 --- a/ricochet/pm_shared/pm_debug.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef PM_DEBUG_H -#define PM_DEBUG_H -#pragma once - -void PM_ViewEntity( void ); -void PM_DrawBBox(vec3_t mins, vec3_t maxs, vec3_t origin, int pcolor, float life); -void PM_ParticleLine(vec3_t start, vec3_t end, int pcolor, float life, float vert); -void PM_ShowClipBox( void ); - -#endif // PMOVEDBG_H \ No newline at end of file diff --git a/ricochet/pm_shared/pm_defs.h b/ricochet/pm_shared/pm_defs.h deleted file mode 100644 index d445ad1..0000000 --- a/ricochet/pm_shared/pm_defs.h +++ /dev/null @@ -1,208 +0,0 @@ -// pm_defs.h -#if !defined( PM_DEFSH ) -#define PM_DEFSH -#pragma once - -#define MAX_PHYSENTS 600 // Must have room for all entities in the world. -#define MAX_MOVEENTS 64 -#define MAX_CLIP_PLANES 5 - -#define PM_NORMAL 0x00000000 -#define PM_STUDIO_IGNORE 0x00000001 // Skip studio models -#define PM_STUDIO_BOX 0x00000002 // Use boxes for non-complex studio models (even in traceline) -#define PM_GLASS_IGNORE 0x00000004 // Ignore entities with non-normal rendermode -#define PM_WORLD_ONLY 0x00000008 // Only trace against the world - -// Values for flags parameter of PM_TraceLine -#define PM_TRACELINE_ANYVISIBLE 0 -#define PM_TRACELINE_PHYSENTSONLY 1 - -#include "archtypes.h" // DAL -#include "pm_info.h" - -// PM_PlayerTrace results. -#include "pmtrace.h" - -#if !defined ( USERCMD_H ) -#include "usercmd.h" -#endif - -// physent_t -typedef struct physent_s -{ - char name[32]; // Name of model, or "player" or "world". - int player; - vec3_t origin; // Model's origin in world coordinates. - struct model_s *model; // only for bsp models - struct model_s *studiomodel; // SOLID_BBOX, but studio clip intersections. - vec3_t mins, maxs; // only for non-bsp models - int info; // For client or server to use to identify (index into edicts or cl_entities) - vec3_t angles; // rotated entities need this info for hull testing to work. - - int solid; // Triggers and func_door type WATER brushes are SOLID_NOT - int skin; // BSP Contents for such things like fun_door water brushes. - int rendermode; // So we can ignore glass - - // Complex collision detection. - float frame; - int sequence; - byte controller[4]; - byte blending[2]; - - int movetype; - int takedamage; - int blooddecal; - int team; - int classnumber; - - // For mods - int iuser1; - int iuser2; - int iuser3; - int iuser4; - float fuser1; - float fuser2; - float fuser3; - float fuser4; - vec3_t vuser1; - vec3_t vuser2; - vec3_t vuser3; - vec3_t vuser4; -} physent_t; - - -typedef struct playermove_s -{ - int player_index; // So we don't try to run the PM_CheckStuck nudging too quickly. - qboolean server; // For debugging, are we running physics code on server side? - - qboolean multiplayer; // 1 == multiplayer server - float time; // realtime on host, for reckoning duck timing - float frametime; // Duration of this frame - - vec3_t forward, right, up; // Vectors for angles - // player state - vec3_t origin; // Movement origin. - vec3_t angles; // Movement view angles. - vec3_t oldangles; // Angles before movement view angles were looked at. - vec3_t velocity; // Current movement direction. - vec3_t movedir; // For waterjumping, a forced forward velocity so we can fly over lip of ledge. - vec3_t basevelocity; // Velocity of the conveyor we are standing, e.g. - - // For ducking/dead - vec3_t view_ofs; // Our eye position. - float flDuckTime; // Time we started duck - qboolean bInDuck; // In process of ducking or ducked already? - - // For walking/falling - int flTimeStepSound; // Next time we can play a step sound - int iStepLeft; - - float flFallVelocity; - vec3_t punchangle; - - float flSwimTime; - - float flNextPrimaryAttack; - - int effects; // MUZZLE FLASH, e.g. - - int flags; // FL_ONGROUND, FL_DUCKING, etc. - int usehull; // 0 = regular player hull, 1 = ducked player hull, 2 = point hull - float gravity; // Our current gravity and friction. - float friction; - int oldbuttons; // Buttons last usercmd - float waterjumptime; // Amount of time left in jumping out of water cycle. - qboolean dead; // Are we a dead player? - int deadflag; - int spectator; // Should we use spectator physics model? - int movetype; // Our movement type, NOCLIP, WALK, FLY - - int onground; - int waterlevel; - int watertype; - int oldwaterlevel; - - char sztexturename[256]; - char chtexturetype; - - float maxspeed; - float clientmaxspeed; // Player specific maxspeed - - // For mods - int iuser1; - int iuser2; - int iuser3; - int iuser4; - float fuser1; - float fuser2; - float fuser3; - float fuser4; - vec3_t vuser1; - vec3_t vuser2; - vec3_t vuser3; - vec3_t vuser4; - // world state - // Number of entities to clip against. - int numphysent; - physent_t physents[MAX_PHYSENTS]; - // Number of momvement entities (ladders) - int nummoveent; - // just a list of ladders - physent_t moveents[MAX_MOVEENTS]; - - // All things being rendered, for tracing against things you don't actually collide with - int numvisent; - physent_t visents[ MAX_PHYSENTS ]; - - // input to run through physics. - usercmd_t cmd; - - // Trace results for objects we collided with. - int numtouch; - pmtrace_t touchindex[MAX_PHYSENTS]; - - char physinfo[ MAX_PHYSINFO_STRING ]; // Physics info string - - struct movevars_s *movevars; - vec3_t player_mins[ 4 ]; - vec3_t player_maxs[ 4 ]; - - // Common functions - const char *(*PM_Info_ValueForKey) ( const char *s, const char *key ); - void (*PM_Particle)( float *origin, int color, float life, int zpos, int zvel); - int (*PM_TestPlayerPosition) (float *pos, pmtrace_t *ptrace ); - void (*Con_NPrintf)( int idx, char *fmt, ... ); - void (*Con_DPrintf)( char *fmt, ... ); - void (*Con_Printf)( char *fmt, ... ); - double (*Sys_FloatTime)( void ); - void (*PM_StuckTouch)( int hitent, pmtrace_t *ptraceresult ); - int (*PM_PointContents) (float *p, int *truecontents /*filled in if this is non-null*/ ); - int (*PM_TruePointContents) (float *p); - int (*PM_HullPointContents) ( struct hull_s *hull, int num, float *p); - pmtrace_t (*PM_PlayerTrace) (float *start, float *end, int traceFlags, int ignore_pe ); - struct pmtrace_s *(*PM_TraceLine)( float *start, float *end, int flags, int usehulll, int ignore_pe ); - int32 (*RandomLong)( int32 lLow, int32 lHigh ); - float (*RandomFloat)( float flLow, float flHigh ); - int (*PM_GetModelType)( struct model_s *mod ); - void (*PM_GetModelBounds)( struct model_s *mod, float *mins, float *maxs ); - void *(*PM_HullForBsp)( physent_t *pe, float *offset ); - float (*PM_TraceModel)( physent_t *pEnt, float *start, float *end, trace_t *trace ); - int (*COM_FileSize)(char *filename); - byte *(*COM_LoadFile) (char *path, int usehunk, int *pLength); - void (*COM_FreeFile) ( void *buffer ); - char *(*memfgets)( byte *pMemFile, int fileSize, int *pFilePos, char *pBuffer, int bufferSize ); - - // Functions - // Run functions for this frame? - qboolean runfuncs; - void (*PM_PlaySound) ( int channel, const char *sample, float volume, float attenuation, int fFlags, int pitch ); - const char *(*PM_TraceTexture) ( int ground, float *vstart, float *vend ); - void (*PM_PlaybackEventFull) ( int flags, int clientindex, unsigned short eventindex, float delay, float *origin, float *angles, float fparam1, float fparam2, int iparam1, int iparam2, int bparam1, int bparam2 ); - - pmtrace_t (*PM_PlayerTraceEx) (float *start, float *end, int traceFlags, int (*pfnIgnore)( physent_t *pe ) ); - int (*PM_TestPlayerPositionEx) (float *pos, pmtrace_t *ptrace, int (*pfnIgnore)( physent_t *pe ) ); - struct pmtrace_s *(*PM_TraceLineEx)( float *start, float *end, int flags, int usehulll, int (*pfnIgnore)( physent_t *pe ) ); -} playermove_t; - -#endif diff --git a/ricochet/pm_shared/pm_info.h b/ricochet/pm_shared/pm_info.h deleted file mode 100644 index bb08d4e..0000000 --- a/ricochet/pm_shared/pm_info.h +++ /dev/null @@ -1,10 +0,0 @@ -// Physics info string definition -#if !defined( PM_INFOH ) -#define PM_INFOH -#ifdef _WIN32 -#pragma once -#endif - -#define MAX_PHYSINFO_STRING 256 - -#endif // PM_INFOH diff --git a/ricochet/pm_shared/pm_materials.h b/ricochet/pm_shared/pm_materials.h deleted file mode 100644 index 67deed6..0000000 --- a/ricochet/pm_shared/pm_materials.h +++ /dev/null @@ -1,19 +0,0 @@ -#if !defined( PM_MATERIALSH ) -#define PM_MATERIALSH -#pragma once - -#define CBTEXTURENAMEMAX 13 // only load first n chars of name - -#define CHAR_TEX_CONCRETE 'C' // texture types -#define CHAR_TEX_METAL 'M' -#define CHAR_TEX_DIRT 'D' -#define CHAR_TEX_VENT 'V' -#define CHAR_TEX_GRATE 'G' -#define CHAR_TEX_TILE 'T' -#define CHAR_TEX_SLOSH 'S' -#define CHAR_TEX_WOOD 'W' -#define CHAR_TEX_COMPUTER 'P' -#define CHAR_TEX_GLASS 'Y' -#define CHAR_TEX_FLESH 'F' - -#endif // !PM_MATERIALSH \ No newline at end of file diff --git a/ricochet/pm_shared/pm_math.cpp b/ricochet/pm_shared/pm_math.cpp deleted file mode 100644 index fc51efc..0000000 --- a/ricochet/pm_shared/pm_math.cpp +++ /dev/null @@ -1,355 +0,0 @@ -// mathlib.c -- math primitives - -#include "mathlib.h" -#include "const.h" -#include - -// up / down -#define PITCH 0 -// left / right -#define YAW 1 -// fall over -#define ROLL 2 - -#pragma warning(disable : 4244) - -int nanmask = 255<<23; - -float anglemod(float a) -{ - a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535); - return a; -} - -void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = angles[YAW] * (M_PI*2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = angles[PITCH] * (M_PI*2 / 360); - sp = sin(angle); - cp = cos(angle); - angle = angles[ROLL] * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); - - if (forward) - { - forward[0] = cp*cy; - forward[1] = cp*sy; - forward[2] = -sp; - } - if (right) - { - right[0] = (-1*sr*sp*cy+-1*cr*-sy); - right[1] = (-1*sr*sp*sy+-1*cr*cy); - right[2] = -1*sr*cp; - } - if (up) - { - up[0] = (cr*sp*cy+-sr*-sy); - up[1] = (cr*sp*sy+-sr*cy); - up[2] = cr*cp; - } -} - -void AngleVectorsTranspose (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = angles[YAW] * (M_PI*2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = angles[PITCH] * (M_PI*2 / 360); - sp = sin(angle); - cp = cos(angle); - angle = angles[ROLL] * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); - - if (forward) - { - forward[0] = cp*cy; - forward[1] = (sr*sp*cy+cr*-sy); - forward[2] = (cr*sp*cy+-sr*-sy); - } - if (right) - { - right[0] = cp*sy; - right[1] = (sr*sp*sy+cr*cy); - right[2] = (cr*sp*sy+-sr*cy); - } - if (up) - { - up[0] = -sp; - up[1] = sr*cp; - up[2] = cr*cp; - } -} - - -void AngleMatrix (const float* angles, float (*matrix)[4] ) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = angles[YAW] * (M_PI*2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = angles[PITCH] * (M_PI*2 / 360); - sp = sin(angle); - cp = cos(angle); - angle = angles[ROLL] * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); - - // matrix = (YAW * PITCH) * ROLL - matrix[0][0] = cp*cy; - matrix[1][0] = cp*sy; - matrix[2][0] = -sp; - matrix[0][1] = sr*sp*cy+cr*-sy; - matrix[1][1] = sr*sp*sy+cr*cy; - matrix[2][1] = sr*cp; - matrix[0][2] = (cr*sp*cy+-sr*-sy); - matrix[1][2] = (cr*sp*sy+-sr*cy); - matrix[2][2] = cr*cp; - matrix[0][3] = 0.0; - matrix[1][3] = 0.0; - matrix[2][3] = 0.0; -} - -void AngleIMatrix (const vec3_t angles, float matrix[3][4] ) -{ - float angle; - float sr, sp, sy, cr, cp, cy; - - angle = angles[YAW] * (M_PI*2 / 360); - sy = sin(angle); - cy = cos(angle); - angle = angles[PITCH] * (M_PI*2 / 360); - sp = sin(angle); - cp = cos(angle); - angle = angles[ROLL] * (M_PI*2 / 360); - sr = sin(angle); - cr = cos(angle); - - // matrix = (YAW * PITCH) * ROLL - matrix[0][0] = cp*cy; - matrix[0][1] = cp*sy; - matrix[0][2] = -sp; - matrix[1][0] = sr*sp*cy+cr*-sy; - matrix[1][1] = sr*sp*sy+cr*cy; - matrix[1][2] = sr*cp; - matrix[2][0] = (cr*sp*cy+-sr*-sy); - matrix[2][1] = (cr*sp*sy+-sr*cy); - matrix[2][2] = cr*cp; - matrix[0][3] = 0.0; - matrix[1][3] = 0.0; - matrix[2][3] = 0.0; -} - - -void VectorTransform (const float* in1, float in2[3][4], float* out) -{ - out[0] = DotProduct(in1, in2[0]) + in2[0][3]; - out[1] = DotProduct(in1, in2[1]) + in2[1][3]; - out[2] = DotProduct(in1, in2[2]) + in2[2][3]; -} - - -int VectorCompare (const float* v1, const float* v2) -{ - int i; - - for (i=0 ; i<3 ; i++) - if (v1[i] != v2[i]) - return 0; - - return 1; -} - -void VectorMA (const float* veca, float scale, const float* vecb, float* vecc) -{ - vecc[0] = veca[0] + scale*vecb[0]; - vecc[1] = veca[1] + scale*vecb[1]; - vecc[2] = veca[2] + scale*vecb[2]; -} - - -vec_t _DotProduct (vec3_t v1, vec3_t v2) -{ - return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; -} - -void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out) -{ - out[0] = veca[0]-vecb[0]; - out[1] = veca[1]-vecb[1]; - out[2] = veca[2]-vecb[2]; -} - -void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out) -{ - out[0] = veca[0]+vecb[0]; - out[1] = veca[1]+vecb[1]; - out[2] = veca[2]+vecb[2]; -} - -void _VectorCopy (vec3_t in, vec3_t out) -{ - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; -} - -void CrossProduct (const float* v1, const float* v2, float* cross) -{ - cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; - cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; - cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; -} - -float Length(const float* v) -{ - int i; - float length; - - length = 0; - for (i=0 ; i< 3 ; i++) - length += v[i]*v[i]; - length = sqrt (length); // FIXME - - return length; -} - -float VectorNormalize ( float* v) -{ - float length, ilength; - - length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2]; - length = sqrt (length); // FIXME - - if (length) - { - ilength = 1/length; - v[0] *= ilength; - v[1] *= ilength; - v[2] *= ilength; - } - - return length; - -} - -void VectorInverse ( float* v) -{ - v[0] = -v[0]; - v[1] = -v[1]; - v[2] = -v[2]; -} - -void VectorScale (const float* in, float scale, float* out) -{ - out[0] = in[0]*scale; - out[1] = in[1]*scale; - out[2] = in[2]*scale; -} - - -int Q_log2(int val) -{ - int answer=0; - while (val>>=1) - answer++; - return answer; -} - -void VectorMatrix( vec3_t forward, vec3_t right, vec3_t up) -{ - vec3_t tmp; - - if (forward[0] == 0 && forward[1] == 0) - { - right[0] = 1; - right[1] = 0; - right[2] = 0; - up[0] = -forward[2]; - up[1] = 0; - up[2] = 0; - return; - } - - tmp[0] = 0; tmp[1] = 0; tmp[2] = 1.0; - CrossProduct( forward, tmp, right ); - VectorNormalize( right ); - CrossProduct( right, forward, up ); - VectorNormalize( up ); -} - - -void VectorAngles( const float* forward, float* angles ) -{ - double tmp, yaw, pitch; - - if (forward[1] == 0 && forward[0] == 0) - { - yaw = 0; - if (forward[2] > 0) - pitch = 90; - else - pitch = 270; - } - else - { - yaw = (atan2(forward[1], forward[0]) * 180 / M_PI); - if (yaw < 0) - yaw += 360; - - tmp = sqrt (forward[0]*forward[0] + forward[1]*forward[1]); - pitch = (atan2(forward[2], tmp) * 180 / M_PI); - if (pitch < 0) - pitch += 360; - } - - angles[0] = pitch; - angles[1] = yaw; - angles[2] = 0; -} - -/* -================ -ConcatTransforms - -================ -*/ -void ConcatTransforms( float in1[ 3 ][ 4 ], float in2[ 3 ][ 4 ], float out[ 3 ][ 4 ] ) -{ - out[ 0 ][ 0 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 0 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 0 ] + - in1[ 0 ][ 2 ] * in2[ 2 ][ 0 ]; - out[ 0 ][ 1 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 1 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 1 ] + - in1[ 0 ][ 2 ] * in2[ 2 ][ 1 ]; - out[ 0 ][ 2 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 2 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 2 ] + - in1[ 0 ][ 2 ] * in2[ 2 ][ 2 ]; - out[ 0 ][ 3 ] = in1[ 0 ][ 0 ] * in2[ 0 ][ 3 ] + in1[ 0 ][ 1 ] * in2[ 1 ][ 3 ] + - in1[ 0 ][ 2 ] * in2[ 2 ][ 3 ] + in1[ 0 ][ 3 ]; - out[ 1 ][ 0 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 0 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 0 ] + - in1[ 1 ][ 2 ] * in2[ 2 ][ 0 ]; - out[ 1 ][ 1 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 1 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 1 ] + - in1[ 1 ][ 2 ] * in2[ 2 ][ 1 ]; - out[ 1 ][ 2 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 2 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 2 ] + - in1[ 1 ][ 2 ] * in2[ 2 ][ 2 ]; - out[ 1 ][ 3 ] = in1[ 1 ][ 0 ] * in2[ 0 ][ 3 ] + in1[ 1 ][ 1 ] * in2[ 1 ][ 3 ] + - in1[ 1 ][ 2 ] * in2[ 2 ][ 3 ] + in1[ 1 ][ 3 ]; - out[ 2 ][ 0 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 0 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 0 ] + - in1[ 2 ][ 2 ] * in2[ 2 ][ 0 ]; - out[ 2 ][ 1 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 1 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 1 ] + - in1[ 2 ][ 2 ] * in2[ 2 ][ 1 ]; - out[ 2 ][ 2 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 2 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 2 ] + - in1[ 2 ][ 2 ] * in2[ 2 ][ 2 ]; - out[ 2 ][ 3 ] = in1[ 2 ][ 0 ] * in2[ 0 ][ 3 ] + in1[ 2 ][ 1 ] * in2[ 1 ][ 3 ] + - in1[ 2 ][ 2 ] * in2[ 2 ][ 3 ] + in1[ 2 ][ 3 ]; -} diff --git a/ricochet/pm_shared/pm_movevars.h b/ricochet/pm_shared/pm_movevars.h deleted file mode 100644 index 71f2179..0000000 --- a/ricochet/pm_shared/pm_movevars.h +++ /dev/null @@ -1,40 +0,0 @@ -// pm_movevars.h -#if !defined( PM_MOVEVARSH ) -#define PM_MOVEVARSH - -// movevars_t // Physics variables. -typedef struct movevars_s movevars_t; - -struct movevars_s -{ - float gravity; // Gravity for map - float stopspeed; // Deceleration when not moving - float maxspeed; // Max allowed speed - float spectatormaxspeed; - float accelerate; // Acceleration factor - float airaccelerate; // Same for when in open air - float wateraccelerate; // Same for when in water - float friction; - float edgefriction; // Extra friction near dropofs - float waterfriction; // Less in water - float entgravity; // 1.0 - float bounce; // Wall bounce value. 1.0 - float stepsize; // sv_stepsize; - float maxvelocity; // maximum server velocity. - float zmax; // Max z-buffer range (for GL) - float waveHeight; // Water wave height (for GL) - qboolean footsteps; // Play footstep sounds - char skyName[32]; // Name of the sky map - float rollangle; - float rollspeed; - float skycolor_r; // Sky color - float skycolor_g; // - float skycolor_b; // - float skyvec_x; // Sky vector - float skyvec_y; // - float skyvec_z; // -}; - -extern movevars_t movevars; - -#endif \ No newline at end of file diff --git a/ricochet/pm_shared/pm_shared.cpp b/ricochet/pm_shared/pm_shared.cpp deleted file mode 100644 index 5226277..0000000 --- a/ricochet/pm_shared/pm_shared.cpp +++ /dev/null @@ -1,3380 +0,0 @@ -/*** -* -* Copyright (c) 1999, Valve LLC. All rights reserved. -* -* This product contains software technology licensed from Id -* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. -* All Rights Reserved. -* -* Use, distribution, and modification of this source code and/or resulting -* object code is restricted to non-commercial enhancements to products from -* Valve LLC. All other use, distribution, or modification is prohibited -* without written permission from Valve LLC. -* -****/ - -#include "Platform.h" - -#include -#include "mathlib.h" -#include "const.h" -#include "usercmd.h" -#include "pm_defs.h" -#include "pm_shared.h" -#include "pm_movevars.h" -#include "pm_debug.h" -#include // NULL -#include // sqrt -#include // strcpy -#include // atoi -#include // isspace - -#ifdef CLIENT_DLL - // Spectator Mode - float vecNewViewAngles[3]; - float vecNewViewOrigin[3]; - int iHasNewViewAngles; - int iHasNewViewOrigin; - int iIsSpectator; -#endif - -static int pm_shared_initialized = 0; - -//Because physics code is now compiled as C++ it conflicts with the version in util.cpp -//That version is actually considered to be Vector vec3_origin, so some compilers will fail to link it -//Until the code for vectors is rewritten to allow for a single definition on client and server, this separate version is needed -//TODO: fix -vec3_t shared_vec3_origin = { 0,0,0 }; - -#pragma warning( disable : 4305 ) - -typedef enum {mod_brush, mod_sprite, mod_alias, mod_studio} modtype_t; - -playermove_t *pmove = NULL; - -typedef struct -{ - int planenum; - short children[2]; // negative numbers are contents -} dclipnode_t; - -typedef struct mplane_s -{ - vec3_t normal; // surface normal - float dist; // closest appoach to origin - byte type; // for texture axis selection and fast side tests - byte signbits; // signx + signy<<1 + signz<<1 - byte pad[2]; -} mplane_t; - -typedef struct hull_s -{ - dclipnode_t *clipnodes; - mplane_t *planes; - int firstclipnode; - int lastclipnode; - vec3_t clip_mins; - vec3_t clip_maxs; -} hull_t; - -// Ducking time -#define TIME_TO_DUCK 0.4 -#define VEC_DUCK_HULL_MIN -18 -#define VEC_DUCK_HULL_MAX 18 -#define VEC_DUCK_VIEW 12 -#define PM_DEAD_VIEWHEIGHT -8 -#define MAX_CLIMB_SPEED 200 -#define STUCK_MOVEUP 1 -#define STUCK_MOVEDOWN -1 -#define VEC_HULL_MIN -36 -#define VEC_HULL_MAX 36 -#define VEC_VIEW 28 -#define STOP_EPSILON 0.1 - -#define CTEXTURESMAX 512 // max number of textures loaded -#define CBTEXTURENAMEMAX 13 // only load first n chars of name - -#define CHAR_TEX_CONCRETE 'C' // texture types -#define CHAR_TEX_METAL 'M' -#define CHAR_TEX_DIRT 'D' -#define CHAR_TEX_VENT 'V' -#define CHAR_TEX_GRATE 'G' -#define CHAR_TEX_TILE 'T' -#define CHAR_TEX_SLOSH 'S' -#define CHAR_TEX_WOOD 'W' -#define CHAR_TEX_COMPUTER 'P' -#define CHAR_TEX_GLASS 'Y' -#define CHAR_TEX_FLESH 'F' - -#define STEP_CONCRETE 0 // default step sound -#define STEP_METAL 1 // metal floor -#define STEP_DIRT 2 // dirt, sand, rock -#define STEP_VENT 3 // ventillation duct -#define STEP_GRATE 4 // metal grating -#define STEP_TILE 5 // floor tiles -#define STEP_SLOSH 6 // shallow liquid puddle -#define STEP_WADE 7 // wading in liquid -#define STEP_LADDER 8 // climbing ladder - -#define PLAYER_FATAL_FALL_SPEED 1024// approx 60 feet -#define PLAYER_MAX_SAFE_FALL_SPEED 580// approx 20 feet -#define DAMAGE_FOR_FALL_SPEED (float) 100 / ( PLAYER_FATAL_FALL_SPEED - PLAYER_MAX_SAFE_FALL_SPEED )// damage per unit per second. -#define PLAYER_MIN_BOUNCE_SPEED 200 -#define PLAYER_FALL_PUNCH_THRESHHOLD (float)350 // won't punch player's screen/make scrape noise unless player falling at least this fast. - -#define PLAYER_LONGJUMP_SPEED 350 // how fast we longjump - -#define PLAYER_DUCKING_MULTIPLIER 0.333 - -// double to float warning -#pragma warning(disable : 4244) -// up / down -#define PITCH 0 -// left / right -#define YAW 1 -// fall over -#define ROLL 2 - -#define MAX_CLIENTS 32 - -#define CONTENTS_CURRENT_0 -9 -#define CONTENTS_CURRENT_90 -10 -#define CONTENTS_CURRENT_180 -11 -#define CONTENTS_CURRENT_270 -12 -#define CONTENTS_CURRENT_UP -13 -#define CONTENTS_CURRENT_DOWN -14 - -#define CONTENTS_TRANSLUCENT -15 - -static vec3_t rgv3tStuckTable[54]; -static int rgStuckLast[MAX_CLIENTS][2]; - -// Texture names -static int gcTextures = 0; -static char grgszTextureName[CTEXTURESMAX][CBTEXTURENAMEMAX]; -static char grgchTextureType[CTEXTURESMAX]; - -int g_onladder = 0; - -int PM_Ignore( physent_t *pe ) -{ - //if ( !stricmp( pe->name, "models/disc.mdl" ) ) - // return 1; - return 0; -} - -void PM_SwapTextures( int i, int j ) -{ - char chTemp; - char szTemp[ CBTEXTURENAMEMAX ]; - - strcpy( szTemp, grgszTextureName[ i ] ); - chTemp = grgchTextureType[ i ]; - - strcpy( grgszTextureName[ i ], grgszTextureName[ j ] ); - grgchTextureType[ i ] = grgchTextureType[ j ]; - - strcpy( grgszTextureName[ j ], szTemp ); - grgchTextureType[ j ] = chTemp; -} - -void PM_SortTextures( void ) -{ - // Bubble sort, yuck, but this only occurs at startup and it's only 512 elements... - // - int i, j; - - for ( i = 0 ; i < gcTextures; i++ ) - { - for ( j = i + 1; j < gcTextures; j++ ) - { - if ( stricmp( grgszTextureName[ i ], grgszTextureName[ j ] ) > 0 ) - { - // Swap - // - PM_SwapTextures( i, j ); - } - } - } -} - -void PM_InitTextureTypes() -{ - char buffer[512]; - int i, j; - byte *pMemFile; - int fileSize, filePos; - static qboolean bTextureTypeInit = false; - - if ( bTextureTypeInit ) - return; - - memset(&(grgszTextureName[0][0]), 0, CTEXTURESMAX * CBTEXTURENAMEMAX); - memset(grgchTextureType, 0, CTEXTURESMAX); - - gcTextures = 0; - memset(buffer, 0, 512); - - fileSize = pmove->COM_FileSize( "sound/materials.txt" ); - pMemFile = pmove->COM_LoadFile( "sound/materials.txt", 5, NULL ); - if ( !pMemFile ) - return; - - filePos = 0; - // for each line in the file... - while ( pmove->memfgets( pMemFile, fileSize, &filePos, buffer, 511 ) != NULL && (gcTextures < CTEXTURESMAX) ) - { - // skip whitespace - i = 0; - while(buffer[i] && isspace(buffer[i])) - i++; - - if (!buffer[i]) - continue; - - // skip comment lines - if (buffer[i] == '/' || !isalpha(buffer[i])) - continue; - - // get texture type - grgchTextureType[gcTextures] = toupper(buffer[i++]); - - // skip whitespace - while(buffer[i] && isspace(buffer[i])) - i++; - - if (!buffer[i]) - continue; - - // get sentence name - j = i; - while (buffer[j] && !isspace(buffer[j])) - j++; - - if (!buffer[j]) - continue; - - // null-terminate name and save in sentences array - j = V_min (j, CBTEXTURENAMEMAX-1+i); - buffer[j] = 0; - strcpy(&(grgszTextureName[gcTextures++][0]), &(buffer[i])); - } - - // Must use engine to free since we are in a .dll - pmove->COM_FreeFile ( pMemFile ); - - PM_SortTextures(); - - bTextureTypeInit = true; -} - -char PM_FindTextureType( char *name ) -{ - int left, right, pivot; - int val; - - assert( pm_shared_initialized ); - - left = 0; - right = gcTextures - 1; - - while ( left <= right ) - { - pivot = ( left + right ) / 2; - - val = strnicmp( name, grgszTextureName[ pivot ], CBTEXTURENAMEMAX-1 ); - if ( val == 0 ) - { - return grgchTextureType[ pivot ]; - } - else if ( val > 0 ) - { - left = pivot + 1; - } - else if ( val < 0 ) - { - right = pivot - 1; - } - } - - return CHAR_TEX_CONCRETE; -} - -void PM_PlayStepSound( int step, float fvol ) -{ - static int iSkipStep = 0; - int irand; - vec3_t hvel; - - pmove->iStepLeft = !pmove->iStepLeft; - - if ( !pmove->runfuncs ) - { - return; - } - - irand = pmove->RandomLong(0,1) + ( pmove->iStepLeft * 2 ); - - // FIXME mp_footsteps needs to be a movevar - if ( pmove->multiplayer && !pmove->movevars->footsteps ) - return; - - VectorCopy( pmove->velocity, hvel ); - hvel[2] = 0.0; - - if ( pmove->multiplayer && ( !g_onladder && Length( hvel ) <= 220 ) ) - return; - - // irand - 0,1 for right foot, 2,3 for left foot - // used to alternate left and right foot - // FIXME, move to player state - - switch (step) - { - default: - case STEP_CONCRETE: - switch (irand) - { - // right foot - case 0: pmove->PM_PlaySound( CHAN_BODY, "player/pl_step1.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: pmove->PM_PlaySound( CHAN_BODY, "player/pl_step3.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - // left foot - case 2: pmove->PM_PlaySound( CHAN_BODY, "player/pl_step2.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: pmove->PM_PlaySound( CHAN_BODY, "player/pl_step4.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - } - break; - case STEP_METAL: - switch(irand) - { - // right foot - case 0: pmove->PM_PlaySound( CHAN_BODY, "player/pl_metal1.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: pmove->PM_PlaySound( CHAN_BODY, "player/pl_metal3.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - // left foot - case 2: pmove->PM_PlaySound( CHAN_BODY, "player/pl_metal2.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: pmove->PM_PlaySound( CHAN_BODY, "player/pl_metal4.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - } - break; - case STEP_DIRT: - switch(irand) - { - // right foot - case 0: pmove->PM_PlaySound( CHAN_BODY, "player/pl_dirt1.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: pmove->PM_PlaySound( CHAN_BODY, "player/pl_dirt3.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - // left foot - case 2: pmove->PM_PlaySound( CHAN_BODY, "player/pl_dirt2.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: pmove->PM_PlaySound( CHAN_BODY, "player/pl_dirt4.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - } - break; - case STEP_VENT: - switch(irand) - { - // right foot - case 0: pmove->PM_PlaySound( CHAN_BODY, "player/pl_duct1.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: pmove->PM_PlaySound( CHAN_BODY, "player/pl_duct3.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - // left foot - case 2: pmove->PM_PlaySound( CHAN_BODY, "player/pl_duct2.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: pmove->PM_PlaySound( CHAN_BODY, "player/pl_duct4.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - } - break; - case STEP_GRATE: - switch(irand) - { - // right foot - case 0: pmove->PM_PlaySound( CHAN_BODY, "player/pl_grate1.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: pmove->PM_PlaySound( CHAN_BODY, "player/pl_grate3.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - // left foot - case 2: pmove->PM_PlaySound( CHAN_BODY, "player/pl_grate2.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: pmove->PM_PlaySound( CHAN_BODY, "player/pl_grate4.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - } - break; - case STEP_TILE: - if ( !pmove->RandomLong(0,4) ) - irand = 4; - switch(irand) - { - // right foot - case 0: pmove->PM_PlaySound( CHAN_BODY, "player/pl_tile1.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: pmove->PM_PlaySound( CHAN_BODY, "player/pl_tile3.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - // left foot - case 2: pmove->PM_PlaySound( CHAN_BODY, "player/pl_tile2.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: pmove->PM_PlaySound( CHAN_BODY, "player/pl_tile4.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 4: pmove->PM_PlaySound( CHAN_BODY, "player/pl_tile5.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - } - break; - case STEP_SLOSH: - switch(irand) - { - // right foot - case 0: pmove->PM_PlaySound( CHAN_BODY, "player/pl_slosh1.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: pmove->PM_PlaySound( CHAN_BODY, "player/pl_slosh3.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - // left foot - case 2: pmove->PM_PlaySound( CHAN_BODY, "player/pl_slosh2.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: pmove->PM_PlaySound( CHAN_BODY, "player/pl_slosh4.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - } - break; - case STEP_WADE: - if ( iSkipStep == 0 ) - { - iSkipStep++; - break; - } - - if ( iSkipStep++ == 3 ) - { - iSkipStep = 0; - } - - switch (irand) - { - // right foot - case 0: pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade1.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade2.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - // left foot - case 2: pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade3.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade4.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - } - break; - case STEP_LADDER: - switch(irand) - { - // right foot - case 0: pmove->PM_PlaySound( CHAN_BODY, "player/pl_ladder1.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 1: pmove->PM_PlaySound( CHAN_BODY, "player/pl_ladder3.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - // left foot - case 2: pmove->PM_PlaySound( CHAN_BODY, "player/pl_ladder2.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - case 3: pmove->PM_PlaySound( CHAN_BODY, "player/pl_ladder4.wav", fvol, ATTN_NORM, 0, PITCH_NORM ); break; - } - break; - } -} - -int PM_MapTextureTypeStepType(char chTextureType) -{ - switch (chTextureType) - { - default: - case CHAR_TEX_CONCRETE: return STEP_CONCRETE; - case CHAR_TEX_METAL: return STEP_METAL; - case CHAR_TEX_DIRT: return STEP_DIRT; - case CHAR_TEX_VENT: return STEP_VENT; - case CHAR_TEX_GRATE: return STEP_GRATE; - case CHAR_TEX_TILE: return STEP_TILE; - case CHAR_TEX_SLOSH: return STEP_SLOSH; - } -} - -/* -==================== -PM_CatagorizeTextureType - -Determine texture info for the texture we are standing on. -==================== -*/ -void PM_CatagorizeTextureType( void ) -{ - vec3_t start, end; - const char *pTextureName; - - VectorCopy( pmove->origin, start ); - VectorCopy( pmove->origin, end ); - - // Straight down - end[2] -= 64; - - // Fill in default values, just in case. - pmove->sztexturename[0] = '\0'; - pmove->chtexturetype = CHAR_TEX_CONCRETE; - - pTextureName = pmove->PM_TraceTexture( pmove->onground, start, end ); - if ( !pTextureName ) - return; - - // strip leading '-0' or '+0~' or '{' or '!' - if (*pTextureName == '-' || *pTextureName == '+') - pTextureName += 2; - - if (*pTextureName == '{' || *pTextureName == '!' || *pTextureName == '~' || *pTextureName == ' ') - pTextureName++; - // '}}' - - strcpy( pmove->sztexturename, pTextureName); - pmove->sztexturename[ CBTEXTURENAMEMAX - 1 ] = 0; - - // get texture type - pmove->chtexturetype = PM_FindTextureType( pmove->sztexturename ); -} - -void PM_UpdateStepSound( void ) -{ - int fWalking; - float fvol; - vec3_t knee; - vec3_t feet; - vec3_t center; - float height; - float speed; - float velrun; - float velwalk; - float flduck; - int fLadder; - int step; - - if ( pmove->flTimeStepSound > 0 ) - return; - - if ( pmove->flags & FL_FROZEN ) - return; - - PM_CatagorizeTextureType(); - - speed = Length( pmove->velocity ); - - // determine if we are on a ladder - fLadder = ( pmove->movetype == MOVETYPE_FLY );// IsOnLadder(); - - // UNDONE: need defined numbers for run, walk, crouch, crouch run velocities!!!! - if ( ( pmove->flags & FL_DUCKING) || fLadder ) - { - velwalk = 60; // These constants should be based on cl_movespeedkey * cl_forwardspeed somehow - velrun = 80; // UNDONE: Move walking to server - flduck = 100; - } - else - { - velwalk = 120; - velrun = 210; - flduck = 0; - } - - // If we're on a ladder or on the ground, and we're moving fast enough, - // play step sound. Also, if pmove->flTimeStepSound is zero, get the new - // sound right away - we just started moving in new level. - if ( (fLadder || ( pmove->onground != -1 ) ) && - ( Length( pmove->velocity ) > 0.0 ) && - ( speed >= velwalk || !pmove->flTimeStepSound ) ) - { - fWalking = speed < velrun; - - VectorCopy( pmove->origin, center ); - VectorCopy( pmove->origin, knee ); - VectorCopy( pmove->origin, feet ); - - height = pmove->player_maxs[ pmove->usehull ][ 2 ] - pmove->player_mins[ pmove->usehull ][ 2 ]; - - knee[2] = pmove->origin[2] - 0.3 * height; - feet[2] = pmove->origin[2] - 0.5 * height; - - // find out what we're stepping in or on... - if (fLadder) - { - step = STEP_LADDER; - fvol = 0.35; - pmove->flTimeStepSound = 350; - } - else if ( pmove->PM_PointContents ( knee, NULL ) == CONTENTS_WATER ) - { - step = STEP_WADE; - fvol = 0.65; - pmove->flTimeStepSound = 600; - } - else if ( pmove->PM_PointContents ( feet, NULL ) == CONTENTS_WATER ) - { - step = STEP_SLOSH; - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - } - else - { - // find texture under player, if different from current texture, - // get material type - step = PM_MapTextureTypeStepType( pmove->chtexturetype ); - - switch ( pmove->chtexturetype ) - { - default: - case CHAR_TEX_CONCRETE: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_METAL: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_DIRT: - fvol = fWalking ? 0.25 : 0.55; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_VENT: - fvol = fWalking ? 0.4 : 0.7; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_GRATE: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_TILE: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - - case CHAR_TEX_SLOSH: - fvol = fWalking ? 0.2 : 0.5; - pmove->flTimeStepSound = fWalking ? 400 : 300; - break; - } - } - - pmove->flTimeStepSound += flduck; // slower step time if ducking - - // play the sound - // 35% volume if ducking - if ( pmove->flags & FL_DUCKING ) - { - fvol *= 0.35; - } - - PM_PlayStepSound( step, fvol ); - } -} - -/* -================ -PM_AddToTouched - -Add's the trace result to touch list, if contact is not already in list. -================ -*/ -qboolean PM_AddToTouched(pmtrace_t tr, vec3_t impactvelocity) -{ - int i; - - for (i = 0; i < pmove->numtouch; i++) - { - if (pmove->touchindex[i].ent == tr.ent) - break; - } - if (i != pmove->numtouch) // Already in list. - return false; - - VectorCopy( impactvelocity, tr.deltavelocity ); - - if (pmove->numtouch >= MAX_PHYSENTS) - pmove->Con_DPrintf("Too many entities were touched!\n"); - - pmove->touchindex[pmove->numtouch++] = tr; - return true; -} - -/* -================ -PM_CheckVelocity - -See if the player has a bogus velocity value. -================ -*/ -void PM_CheckVelocity () -{ - int i; - -// -// bound velocity -// - for (i=0 ; i<3 ; i++) - { - // See if it's bogus. - if (IS_NAN(pmove->velocity[i])) - { - pmove->Con_Printf ("PM Got a NaN velocity %i\n", i); - pmove->velocity[i] = 0; - } - if (IS_NAN(pmove->origin[i])) - { - pmove->Con_Printf ("PM Got a NaN origin on %i\n", i); - pmove->origin[i] = 0; - } - - // Bound it. - if (pmove->velocity[i] > pmove->movevars->maxvelocity) - { - pmove->Con_DPrintf ("PM Got a velocity too high on %i\n", i); - pmove->velocity[i] = pmove->movevars->maxvelocity; - } - else if (pmove->velocity[i] < -pmove->movevars->maxvelocity) - { - pmove->Con_DPrintf ("PM Got a velocity too low on %i\n", i); - pmove->velocity[i] = -pmove->movevars->maxvelocity; - } - } -} - -/* -================== -PM_ClipVelocity - -Slide off of the impacting object -returns the blocked flags: -0x01 == floor -0x02 == step / wall -================== -*/ -int PM_ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce) -{ - float backoff; - float change; - float angle; - int i, blocked; - - angle = normal[ 2 ]; - - blocked = 0x00; // Assume unblocked. - if (angle > 0) // If the plane that is blocking us has a positive z component, then assume it's a floor. - blocked |= 0x01; // - if (!angle) // If the plane has no Z, it is vertical (wall/step) - blocked |= 0x02; // - - // Determine how far along plane to slide based on incoming direction. - // Scale by overbounce factor. - backoff = DotProduct (in, normal) * overbounce; - - for (i=0 ; i<3 ; i++) - { - change = normal[i]*backoff; - out[i] = in[i] - change; - // If out velocity is too small, zero it out. - if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) - out[i] = 0; - } - - // Return blocking flags. - return blocked; -} - -void PM_AddCorrectGravity () -{ - float ent_gravity; - - if ( pmove->waterjumptime ) - return; - - if (pmove->gravity) - ent_gravity = pmove->gravity; - else - ent_gravity = 1.0; - - // Add gravity so they'll be in the correct position during movement - // yes, this 0.5 looks wrong, but it's not. - pmove->velocity[2] -= (ent_gravity * pmove->movevars->gravity * 0.5 * pmove->frametime ); - pmove->velocity[2] += pmove->basevelocity[2] * pmove->frametime; - pmove->basevelocity[2] = 0; - - PM_CheckVelocity(); -} - - -void PM_FixupGravityVelocity () -{ - float ent_gravity; - - if ( pmove->waterjumptime ) - return; - - if (pmove->gravity) - ent_gravity = pmove->gravity; - else - ent_gravity = 1.0; - - // Get the correct velocity for the end of the dt - pmove->velocity[2] -= (ent_gravity * pmove->movevars->gravity * pmove->frametime * 0.5 ); - - PM_CheckVelocity(); -} - -/* -============ -PM_FlyMove - -The basic solid body movement clip that slides along multiple planes -============ -*/ -int PM_FlyMove (void) -{ - int bumpcount, numbumps; - vec3_t dir; - float d; - int numplanes; - vec3_t planes[MAX_CLIP_PLANES]; - vec3_t primal_velocity, original_velocity; - vec3_t new_velocity; - int i, j; - pmtrace_t trace; - vec3_t end; - float time_left, allFraction; - int blocked; - - numbumps = 4; // Bump up to four times - - blocked = 0; // Assume not blocked - numplanes = 0; // and not sliding along any planes - VectorCopy (pmove->velocity, original_velocity); // Store original velocity - VectorCopy (pmove->velocity, primal_velocity); - - allFraction = 0; - time_left = pmove->frametime; // Total time for this movement operation. - - for (bumpcount=0 ; bumpcountvelocity[0] && !pmove->velocity[1] && !pmove->velocity[2]) - break; - - // Assume we can move all the way from the current origin to the - // end point. - for (i=0 ; i<3 ; i++) - end[i] = pmove->origin[i] + time_left * pmove->velocity[i]; - - // See if we can make it from origin to end point. - trace = pmove->PM_PlayerTraceEx (pmove->origin, end, PM_NORMAL, PM_Ignore ); - - allFraction += trace.fraction; - // If we started in a solid object, or we were in solid space - // the whole way, zero out our velocity and return that we - // are blocked by floor and wall. - if (trace.allsolid) - { // entity is trapped in another solid - VectorCopy (shared_vec3_origin, pmove->velocity); - //Con_DPrintf("Trapped 4\n"); - return 4; - } - - // If we moved some portion of the total distance, then - // copy the end position into the pmove->origin and - // zero the plane counter. - if (trace.fraction > 0) - { // actually covered some distance - VectorCopy (trace.endpos, pmove->origin); - VectorCopy (pmove->velocity, original_velocity); - numplanes = 0; - } - - // If we covered the entire distance, we are done - // and can return. - if (trace.fraction == 1) - break; // moved the entire distance - - //if (!trace.ent) - // Sys_Error ("PM_PlayerTrace: !trace.ent"); - - // Save entity that blocked us (since fraction was < 1.0) - // for contact - // Add it if it's not already in the list!!! - PM_AddToTouched(trace, pmove->velocity); - - // If the plane we hit has a high z component in the normal, then - // it's probably a floor - if (trace.plane.normal[2] > 0.7) - { - blocked |= 1; // floor - } - // If the plane has a zero z component in the normal, then it's a - // step or wall - if (!trace.plane.normal[2]) - { - blocked |= 2; // step / wall - //Con_DPrintf("Blocked by %i\n", trace.ent); - } - - // Reduce amount of pmove->frametime left by total time left * fraction - // that we covered. - time_left -= time_left * trace.fraction; - - // Did we run out of planes to clip against? - if (numplanes >= MAX_CLIP_PLANES) - { // this shouldn't really happen - // Stop our movement if so. - VectorCopy (shared_vec3_origin, pmove->velocity); - //Con_DPrintf("Too many planes 4\n"); - - break; - } - - // Set up next clipping plane - VectorCopy (trace.plane.normal, planes[numplanes]); - numplanes++; -// - -// modify original_velocity so it parallels all of the clip planes -// - if ( pmove->movetype == MOVETYPE_WALK && - ((pmove->onground == -1) || (pmove->friction != 1)) ) // relfect player velocity - { - for ( i = 0; i < numplanes; i++ ) - { - if ( planes[i][2] > 0.7 ) - {// floor or slope - PM_ClipVelocity( original_velocity, planes[i], new_velocity, 1 ); - VectorCopy( new_velocity, original_velocity ); - } - else - PM_ClipVelocity( original_velocity, planes[i], new_velocity, 1.0 + pmove->movevars->bounce * (1-pmove->friction) ); - } - - VectorCopy( new_velocity, pmove->velocity ); - VectorCopy( new_velocity, original_velocity ); - } - else - { - for (i=0 ; ivelocity, - 1); - for (j=0 ; jvelocity, planes[j]) < 0) - break; // not ok - } - if (j == numplanes) // Didn't have to clip, so we're ok - break; - } - - // Did we go all the way through plane set - if (i != numplanes) - { // go along this plane - // pmove->velocity is set in clipping call, no need to set again. - ; - } - else - { // go along the crease - if (numplanes != 2) - { - //Con_Printf ("clip velocity, numplanes == %i\n",numplanes); - VectorCopy (shared_vec3_origin, pmove->velocity); - //Con_DPrintf("Trapped 4\n"); - - break; - } - CrossProduct (planes[0], planes[1], dir); - d = DotProduct (dir, pmove->velocity); - VectorScale (dir, d, pmove->velocity ); - } - - // - // if original velocity is against the original velocity, stop dead - // to avoid tiny occilations in sloping corners - // - if (DotProduct (pmove->velocity, primal_velocity) <= 0) - { - //Con_DPrintf("Back\n"); - VectorCopy (shared_vec3_origin, pmove->velocity); - break; - } - } - } - - if ( allFraction == 0 ) - { - VectorCopy (shared_vec3_origin, pmove->velocity); - //Con_DPrintf( "Don't stick\n" ); - } - - return blocked; -} - -/* -============== -PM_Accelerate -============== -*/ -void PM_Accelerate (vec3_t wishdir, float wishspeed, float accel) -{ - int i; - float addspeed, accelspeed, currentspeed; - - // Dead player's don't accelerate - if (pmove->dead) - return; - - // If waterjumping, don't accelerate - if (pmove->waterjumptime) - return; - - // See if we are changing direction a bit - currentspeed = DotProduct (pmove->velocity, wishdir); - - // Reduce wishspeed by the amount of veer. - addspeed = wishspeed - currentspeed; - - // If not going to add any speed, done. - if (addspeed <= 0) - return; - - // Determine amount of accleration. - accelspeed = accel * pmove->frametime * wishspeed * pmove->friction; - - // Cap at addspeed - if (accelspeed > addspeed) - accelspeed = addspeed; - - // Adjust velocity. - for (i=0 ; i<3 ; i++) - { - pmove->velocity[i] += accelspeed * wishdir[i]; - } -} - -/* -===================== -PM_WalkMove - -Only used by players. Moves along the ground when player is a MOVETYPE_WALK. -====================== -*/ -void PM_WalkMove () -{ - int clip; - int oldonground; - int i; - - vec3_t wishvel; - float spd; - float fmove, smove; - vec3_t wishdir; - float wishspeed; - - vec3_t dest, start; - vec3_t original, originalvel; - vec3_t down, downvel; - float downdist, updist; - - pmtrace_t trace; - - // Copy movement amounts - fmove = pmove->cmd.forwardmove; - smove = pmove->cmd.sidemove; - - // Zero out z components of movement vectors - pmove->forward[2] = 0; - pmove->right[2] = 0; - - VectorNormalize (pmove->forward); // Normalize remainder of vectors. - VectorNormalize (pmove->right); // - - for (i=0 ; i<2 ; i++) // Determine x and y parts of velocity - wishvel[i] = pmove->forward[i]*fmove + pmove->right[i]*smove; - - wishvel[2] = 0; // Zero out z part of velocity - - VectorCopy (wishvel, wishdir); // Determine maginitude of speed of move - wishspeed = VectorNormalize(wishdir); - -// -// Clamp to server defined max speed -// - if (wishspeed > pmove->maxspeed) - { - VectorScale (wishvel, pmove->maxspeed/wishspeed, wishvel); - wishspeed = pmove->maxspeed; - } - - // Set pmove velocity - pmove->velocity[2] = 0; - PM_Accelerate (wishdir, wishspeed, pmove->movevars->accelerate); - pmove->velocity[2] = 0; - - // Add in any base velocity to the current velocity. - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity ); - - spd = Length( pmove->velocity ); - - if (spd < 1.0f) - { - VectorClear( pmove->velocity ); - return; - } - - // If we are not moving, do nothing - //if (!pmove->velocity[0] && !pmove->velocity[1] && !pmove->velocity[2]) - // return; - - oldonground = pmove->onground; - -// first try just moving to the destination - dest[0] = pmove->origin[0] + pmove->velocity[0]*pmove->frametime; - dest[1] = pmove->origin[1] + pmove->velocity[1]*pmove->frametime; - dest[2] = pmove->origin[2]; - - // first try moving directly to the next spot - VectorCopy (dest, start); - trace = pmove->PM_PlayerTraceEx (pmove->origin, dest, PM_NORMAL, PM_Ignore ); - // If we made it all the way, then copy trace end - // as new player position. - if (trace.fraction == 1) - { - VectorCopy (trace.endpos, pmove->origin); - return; - } - - if (oldonground == -1 && // Don't walk up stairs if not on ground. - pmove->waterlevel == 0) - return; - - if (pmove->waterjumptime) // If we are jumping out of water, don't do anything more. - return; - - // Try sliding forward both on ground and up 16 pixels - // take the move that goes farthest - VectorCopy (pmove->origin, original); // Save out original pos & - VectorCopy (pmove->velocity, originalvel); // velocity. - - // Slide move - clip = PM_FlyMove (); - - // Copy the results out - VectorCopy (pmove->origin , down); - VectorCopy (pmove->velocity, downvel); - - // Reset original values. - VectorCopy (original, pmove->origin); - - VectorCopy (originalvel, pmove->velocity); - - // Start out up one stair height - VectorCopy (pmove->origin, dest); - dest[2] += pmove->movevars->stepsize; - - trace = pmove->PM_PlayerTraceEx (pmove->origin, dest, PM_NORMAL, PM_Ignore ); - // If we started okay and made it part of the way at least, - // copy the results to the movement start position and then - // run another move try. - if (!trace.startsolid && !trace.allsolid) - { - VectorCopy (trace.endpos, pmove->origin); - } - -// slide move the rest of the way. - clip = PM_FlyMove (); - -// Now try going back down from the end point -// press down the stepheight - VectorCopy (pmove->origin, dest); - dest[2] -= pmove->movevars->stepsize; - - trace = pmove->PM_PlayerTraceEx (pmove->origin, dest, PM_NORMAL, PM_Ignore ); - - // If we are not on the ground any more then - // use the original movement attempt - if ( trace.plane.normal[2] < 0.7) - goto usedown; - // If the trace ended up in empty space, copy the end - // over to the origin. - if (!trace.startsolid && !trace.allsolid) - { - VectorCopy (trace.endpos, pmove->origin); - } - // Copy this origion to up. - VectorCopy (pmove->origin, pmove->up); - - // decide which one went farther - downdist = (down[0] - original[0])*(down[0] - original[0]) - + (down[1] - original[1])*(down[1] - original[1]); - updist = (pmove->up[0] - original[0])*(pmove->up[0] - original[0]) - + (pmove->up[1] - original[1])*(pmove->up[1] - original[1]); - - if (downdist > updist) - { -usedown: - VectorCopy (down , pmove->origin); - VectorCopy (downvel, pmove->velocity); - } else // copy z value from slide move - pmove->velocity[2] = downvel[2]; - -} - -/* -================== -PM_Friction - -Handles both ground friction and water friction -================== -*/ -void PM_Friction (void) -{ - float *vel; - float speed, newspeed, control; - float friction; - float drop; - vec3_t newvel; - - // If we are in water jump cycle, don't apply friction - if (pmove->waterjumptime) - return; - - // Get velocity - vel = pmove->velocity; - - // Calculate speed - speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1] + vel[2]*vel[2]); - - // If too slow, return - if (speed < 0.1f) - { - return; - } - - drop = 0; - -// apply ground friction - if (pmove->onground != -1) // On an entity that is the ground - { - vec3_t start, stop; - pmtrace_t trace; - - start[0] = stop[0] = pmove->origin[0] + vel[0]/speed*16; - start[1] = stop[1] = pmove->origin[1] + vel[1]/speed*16; - start[2] = pmove->origin[2] + pmove->player_mins[pmove->usehull][2]; - stop[2] = start[2] - 34; - - trace = pmove->PM_PlayerTraceEx (start, stop, PM_NORMAL, PM_Ignore ); - - if (trace.fraction == 1.0) - friction = pmove->movevars->friction*pmove->movevars->edgefriction; - else - friction = pmove->movevars->friction; - - // Grab friction value. - //friction = pmove->movevars->friction; - - friction *= pmove->friction; // player friction? - - // Bleed off some speed, but if we have less than the bleed - // threshhold, bleed the theshold amount. - control = (speed < pmove->movevars->stopspeed) ? - pmove->movevars->stopspeed : speed; - // Add the amount to t'he drop amount. - drop += control*friction*pmove->frametime; - } - -// apply water friction -// if (pmove->waterlevel) -// drop += speed * pmove->movevars->waterfriction * waterlevel * pmove->frametime; - -// scale the velocity - newspeed = speed - drop; - if (newspeed < 0) - newspeed = 0; - - // Determine proportion of old speed we are using. - newspeed /= speed; - - // Adjust velocity according to proportion. - newvel[0] = vel[0] * newspeed; - newvel[1] = vel[1] * newspeed; - newvel[2] = vel[2] * newspeed; - - VectorCopy( newvel, pmove->velocity ); -} - -void PM_AirAccelerate (vec3_t wishdir, float wishspeed, float accel) -{ - int i; - float addspeed, accelspeed, currentspeed, wishspd = wishspeed; - - if (pmove->dead) - return; - if (pmove->waterjumptime) - return; - - // Cap speed - //wishspd = VectorNormalize (pmove->wishveloc); - - if (wishspd > 30) - wishspd = 30; - // Determine veer amount - currentspeed = DotProduct (pmove->velocity, wishdir); - // See how much to add - addspeed = wishspd - currentspeed; - // If not adding any, done. - if (addspeed <= 0) - return; - // Determine acceleration speed after acceleration - - accelspeed = accel * wishspeed * pmove->frametime * pmove->friction; - // Cap it - if (accelspeed > addspeed) - accelspeed = addspeed; - - // Adjust pmove vel. - for (i=0 ; i<3 ; i++) - { - pmove->velocity[i] += accelspeed*wishdir[i]; - } -} - -/* -=================== -PM_WaterMove - -=================== -*/ -void PM_WaterMove (void) -{ - int i; - vec3_t wishvel; - float wishspeed; - vec3_t wishdir; - vec3_t start, dest; - vec3_t temp; - pmtrace_t trace; - - float speed, newspeed, addspeed, accelspeed; - -// -// user intentions -// - for (i=0 ; i<3 ; i++) - wishvel[i] = pmove->forward[i]*pmove->cmd.forwardmove + pmove->right[i]*pmove->cmd.sidemove; - - // Sinking after no other movement occurs - if (!pmove->cmd.forwardmove && !pmove->cmd.sidemove && !pmove->cmd.upmove) - wishvel[2] -= 60; // drift towards bottom - else // Go straight up by upmove amount. - wishvel[2] += pmove->cmd.upmove; - - // Copy it over and determine speed - VectorCopy (wishvel, wishdir); - wishspeed = VectorNormalize(wishdir); - - // Cap speed. - if (wishspeed > pmove->maxspeed) - { - VectorScale (wishvel, pmove->maxspeed/wishspeed, wishvel); - wishspeed = pmove->maxspeed; - } - // Slow us down a bit. - wishspeed *= 0.8; - - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity); -// Water friction - VectorCopy(pmove->velocity, temp); - speed = VectorNormalize(temp); - if (speed) - { - newspeed = speed - pmove->frametime * speed * pmove->movevars->friction * pmove->friction; - - if (newspeed < 0) - newspeed = 0; - VectorScale (pmove->velocity, newspeed/speed, pmove->velocity); - } - else - newspeed = 0; - -// -// water acceleration -// - if ( wishspeed < 0.1f ) - { - return; - } - - addspeed = wishspeed - newspeed; - if (addspeed > 0) - { - - VectorNormalize(wishvel); - accelspeed = pmove->movevars->accelerate * wishspeed * pmove->frametime * pmove->friction; - if (accelspeed > addspeed) - accelspeed = addspeed; - - for (i = 0; i < 3; i++) - pmove->velocity[i] += accelspeed * wishvel[i]; - } - -// Now move -// assume it is a stair or a slope, so press down from stepheight above - VectorMA (pmove->origin, pmove->frametime, pmove->velocity, dest); - VectorCopy (dest, start); - start[2] += pmove->movevars->stepsize + 1; - trace = pmove->PM_PlayerTraceEx (start, dest, PM_NORMAL, PM_Ignore ); - if (!trace.startsolid && !trace.allsolid) // FIXME: check steep slope? - { // walked up the step, so just keep result and exit - VectorCopy (trace.endpos, pmove->origin); - return; - } - - // Try moving straight along out normal path. - PM_FlyMove (); -} - - -/* -=================== -PM_AirMove - -=================== -*/ -void PM_AirMove (void) -{ - int i; - vec3_t wishvel; - float fmove, smove; - vec3_t wishdir; - float wishspeed; - - // Copy movement amounts - fmove = pmove->cmd.forwardmove; - smove = pmove->cmd.sidemove; - - // Zero out z components of movement vectors - pmove->forward[2] = 0; - pmove->right[2] = 0; - // Renormalize - VectorNormalize (pmove->forward); - VectorNormalize (pmove->right); - - // Determine x and y parts of velocity - for (i=0 ; i<2 ; i++) - { - wishvel[i] = pmove->forward[i]*fmove + pmove->right[i]*smove; - } - // Zero out z part of velocity - wishvel[2] = 0; - - // Determine maginitude of speed of move - VectorCopy (wishvel, wishdir); - wishspeed = VectorNormalize(wishdir); - - // Clamp to server defined max speed - if (wishspeed > pmove->maxspeed) - { - VectorScale (wishvel, pmove->maxspeed/wishspeed, wishvel); - wishspeed = pmove->maxspeed; - } - - PM_AirAccelerate (wishdir, wishspeed, pmove->movevars->airaccelerate); - - // Add in any base velocity to the current velocity. - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity ); - - PM_FlyMove (); -} - -qboolean PM_InWater( void ) -{ - return ( pmove->waterlevel > 1 ); -} - -/* -============= -PM_CheckWater - -Sets pmove->waterlevel and pmove->watertype values. -============= -*/ -qboolean PM_CheckWater () -{ - vec3_t point; - int cont; - int truecont; - float height; - float heightover2; - - // Pick a spot just above the players feet. - point[0] = pmove->origin[0] + (pmove->player_mins[pmove->usehull][0] + pmove->player_maxs[pmove->usehull][0]) * 0.5; - point[1] = pmove->origin[1] + (pmove->player_mins[pmove->usehull][1] + pmove->player_maxs[pmove->usehull][1]) * 0.5; - point[2] = pmove->origin[2] + pmove->player_mins[pmove->usehull][2] + 1; - - // Assume that we are not in water at all. - pmove->waterlevel = 0; - pmove->watertype = CONTENTS_EMPTY; - - // Grab point contents. - cont = pmove->PM_PointContents (point, &truecont ); - // Are we under water? (not solid and not empty?) - if (cont <= CONTENTS_WATER && cont > CONTENTS_TRANSLUCENT ) - { - // Set water type - pmove->watertype = cont; - - // We are at least at level one - pmove->waterlevel = 1; - - height = (pmove->player_mins[pmove->usehull][2] + pmove->player_maxs[pmove->usehull][2]); - heightover2 = height * 0.5; - - // Now check a point that is at the player hull midpoint. - point[2] = pmove->origin[2] + heightover2; - cont = pmove->PM_PointContents (point, NULL ); - // If that point is also under water... - if (cont <= CONTENTS_WATER && cont > CONTENTS_TRANSLUCENT ) - { - // Set a higher water level. - pmove->waterlevel = 2; - - // Now check the eye position. (view_ofs is relative to the origin) - point[2] = pmove->origin[2] + pmove->view_ofs[2]; - - cont = pmove->PM_PointContents (point, NULL ); - if (cont <= CONTENTS_WATER && cont > CONTENTS_TRANSLUCENT ) - pmove->waterlevel = 3; // In over our eyes - } - - // Adjust velocity based on water current, if any. - if ( ( truecont <= CONTENTS_CURRENT_0 ) && - ( truecont >= CONTENTS_CURRENT_DOWN ) ) - { - // The deeper we are, the stronger the current. - static vec3_t current_table[] = - { - {1, 0, 0}, {0, 1, 0}, {-1, 0, 0}, - {0, -1, 0}, {0, 0, 1}, {0, 0, -1} - }; - - VectorMA (pmove->basevelocity, 50.0*pmove->waterlevel, current_table[CONTENTS_CURRENT_0 - truecont], pmove->basevelocity); - } - } - - return pmove->waterlevel > 1; -} - -/* -============= -PM_CatagorizePosition -============= -*/ -void PM_CatagorizePosition (void) -{ - vec3_t point; - pmtrace_t tr; - -// if the player hull point one unit down is solid, the player -// is on ground - -// see if standing on something solid - - // Doing this before we move may introduce a potential latency in water detection, but - // doing it after can get us stuck on the bottom in water if the amount we move up - // is less than the 1 pixel 'threshold' we're about to snap to. Also, we'll call - // this several times per frame, so we really need to avoid sticking to the bottom of - // water on each call, and the converse case will correct itself if called twice. - PM_CheckWater(); - - point[0] = pmove->origin[0]; - point[1] = pmove->origin[1]; - point[2] = pmove->origin[2] - 2; - - if (pmove->velocity[2] > 180) // Shooting up really fast. Definitely not on ground. - { - pmove->onground = -1; - } - else - { - // Try and move down. - tr = pmove->PM_PlayerTraceEx (pmove->origin, point, PM_NORMAL, PM_Ignore ); - // If we hit a steep plane, we are not on ground - if ( tr.plane.normal[2] < 0.7) - pmove->onground = -1; // too steep - else - pmove->onground = tr.ent; // Otherwise, point to index of ent under us. - - // If we are on something... - if (pmove->onground != -1) - { - // Then we are not in water jump sequence - pmove->waterjumptime = 0; - // If we could make the move, drop us down that 1 pixel - if (pmove->waterlevel < 2 && !tr.startsolid && !tr.allsolid) - VectorCopy (tr.endpos, pmove->origin); - } - - // Standing on an entity other than the world - if (tr.ent > 0) // So signal that we are touching something. - { - PM_AddToTouched(tr, pmove->velocity); - } - } -} - -/* -================= -PM_GetRandomStuckOffsets - -When a player is stuck, it's costly to try and unstick them -Grab a test offset for the player based on a passed in index -================= -*/ -int PM_GetRandomStuckOffsets(int nIndex, int server, vec3_t offset) -{ - // Last time we did a full - int idx; - idx = rgStuckLast[nIndex][server]++; - - VectorCopy(rgv3tStuckTable[idx % 54], offset); - - return (idx % 54); -} - -void PM_ResetStuckOffsets(int nIndex, int server) -{ - rgStuckLast[nIndex][server] = 0; -} - -/* -================= -NudgePosition - -If pmove->origin is in a solid position, -try nudging slightly on all axis to -allow for the cut precision of the net coordinates -================= -*/ -#define PM_CHECKSTUCK_MINTIME 0.05 // Don't check again too quickly. - -int PM_CheckStuck (void) -{ - vec3_t base; - vec3_t offset; - vec3_t test; - int hitent; - int idx; - float fTime; - int i; - pmtrace_t traceresult; - - static float rgStuckCheckTime[MAX_CLIENTS][2]; // Last time we did a full - - // If position is okay, exit - hitent = pmove->PM_TestPlayerPositionEx (pmove->origin, &traceresult, PM_Ignore ); - if (hitent == -1 ) - { - PM_ResetStuckOffsets( pmove->player_index, pmove->server ); - return 0; - } - - VectorCopy (pmove->origin, base); - - // - // Deal with precision error in network. - // - if (!pmove->server) - { - // World or BSP model - if ( ( hitent == 0 ) || - ( pmove->physents[hitent].model != NULL ) ) - { - int nReps = 0; - PM_ResetStuckOffsets( pmove->player_index, pmove->server ); - do - { - i = PM_GetRandomStuckOffsets(pmove->player_index, pmove->server, offset); - - VectorAdd(base, offset, test); - if (pmove->PM_TestPlayerPositionEx (test, &traceresult, PM_Ignore ) == -1) - { - PM_ResetStuckOffsets( pmove->player_index, pmove->server ); - - VectorCopy ( test, pmove->origin ); - return 0; - } - nReps++; - } while (nReps < 54); - } - } - - // Only an issue on the client. - - if (pmove->server) - idx = 0; - else - idx = 1; - - fTime = pmove->Sys_FloatTime(); - // Too soon? - if (rgStuckCheckTime[pmove->player_index][idx] >= - ( fTime - PM_CHECKSTUCK_MINTIME ) ) - { - return 1; - } - rgStuckCheckTime[pmove->player_index][idx] = fTime; - - pmove->PM_StuckTouch( hitent, &traceresult ); - - i = PM_GetRandomStuckOffsets(pmove->player_index, pmove->server, offset); - - VectorAdd(base, offset, test); - if ( ( hitent = pmove->PM_TestPlayerPositionEx ( test, NULL, PM_Ignore ) ) == -1 ) - { - //Con_DPrintf("Nudged\n"); - - PM_ResetStuckOffsets( pmove->player_index, pmove->server ); - - if (i >= 27) - VectorCopy ( test, pmove->origin ); - - return 0; - } - - // If player is flailing while stuck in another player ( should never happen ), then see - // if we can't "unstick" them forceably. - if ( pmove->cmd.buttons & ( IN_JUMP | IN_DUCK | IN_ATTACK ) && ( pmove->physents[ hitent ].player != 0 ) ) - { - float x, y, z; - float xystep = 8.0; - float zstep = 18.0; - float xyminmax = xystep; - float zminmax = 4 * zstep; - - for ( z = 0; z <= zminmax; z += zstep ) - { - for ( x = -xyminmax; x <= xyminmax; x += xystep ) - { - for ( y = -xyminmax; y <= xyminmax; y += xystep ) - { - VectorCopy( base, test ); - test[0] += x; - test[1] += y; - test[2] += z; - - if ( pmove->PM_TestPlayerPositionEx ( test, NULL, PM_Ignore ) == -1 ) - { - VectorCopy( test, pmove->origin ); - return 0; - } - } - } - } - } - - //VectorCopy (base, pmove->origin); - - return 1; -} - -#define CHASE_DISTANCE 112 // Desired distance from target -#define CHASE_PADDING 4 // Minimum allowable distance between the view and a solid face - -// Get the origin of the Observer based around the target's position and angles -void GetChaseOrigin( vec3_t targetangles, int iTargetIndex, vec3_t offset, vec3_t *returnvec ) -{ - vec3_t forward; - vec3_t vecEnd; - vec3_t vecStart; - struct pmtrace_s *trace; - physent_t *target; - - target = &(pmove->physents[ iTargetIndex ]); - - // Trace back from the target using the player's view angles - AngleVectors(targetangles, forward, NULL, NULL); - - // Without view_ofs, just guess at adding 28 (standing player) to the origin to get the eye-height - VectorCopy( target->origin, vecStart ); - vecStart[2] += 28; - VectorMA(offset, CHASE_DISTANCE, forward, vecEnd); - VectorSubtract( vecStart, vecEnd, vecEnd ); - - trace = pmove->PM_TraceLine( vecStart, vecEnd, 0, 2, iTargetIndex ); - - // Return the position - VectorMA( trace->endpos, CHASE_PADDING, trace->plane.normal, *returnvec ); - -#ifdef CLIENT_DLL - // pmove->Con_NPrintf( 9, "vecStart %f %f %f.\n", vecStart[0], vecStart[1], vecStart[2] ); - // pmove->Con_NPrintf( 10, " vecEnd %f %f %f.\n", vecEnd[0], vecEnd[1], vecEnd[2] ); - // pmove->Con_NPrintf( 11, " EndPos %f %f %f.\n", trace->endpos[0], trace->endpos[1], trace->endpos[2] ); -#endif -} - -/* -=============== -PM_SpectatorMove -=============== -*/ -void PM_SpectatorMove (void) -{ - float speed, drop, friction, control, newspeed; - //float accel; - float currentspeed, addspeed, accelspeed; - int i; - vec3_t wishvel; - float fmove, smove; - vec3_t wishdir; - float wishspeed; - -#ifdef CLIENT_DLL - if ( pmove->runfuncs ) - { - // Set spectator flag - iIsSpectator = SPEC_IS_SPECTATOR; - } -#endif - - // Are we locked onto a target? - if ( pmove->iuser2 ) - { - vec3_t vecViewAngle; - vec3_t vecNewOrg; - vec3_t vecOffset; - int i; - - // Find the client this player's targeting - for (i = 0; i < pmove->numphysent; i++) - { - if ( pmove->physents[i].info == pmove->iuser2 ) - break; - } - - if (i == pmove->numphysent) - return; - - VectorCopy(shared_vec3_origin, vecOffset ); - - // Calculate a camera position based upon the target's origin and angles - if (pmove->iuser1 == 1) - { - // Locked onto the target - VectorCopy( pmove->physents[i].angles, vecViewAngle ); - vecViewAngle[0] = 0; - -#ifdef CLIENT_DLL - if ( pmove->runfuncs ) - { - // Force the client to start smoothing both the spectator's origin and angles - iIsSpectator |= (SPEC_SMOOTH_ANGLES | SPEC_SMOOTH_ORIGIN); - } -#endif - } - else - { - // Freelooking around the target - VectorCopy( pmove->angles, vecViewAngle ); - } - - GetChaseOrigin( vecViewAngle, i, vecOffset, &vecNewOrg); - VectorCopy( vecNewOrg, pmove->origin ); - VectorCopy( vecViewAngle, pmove->angles ); - VectorCopy(shared_vec3_origin, pmove->velocity ); - -#ifdef CLIENT_DLL - if ( pmove->runfuncs ) - { - // Copy the desired angles into the client global var so we can force them to the player's view - VectorCopy( pmove->angles, vecNewViewAngles ); - iHasNewViewAngles = true; - VectorCopy( pmove->origin, vecNewViewOrigin ); - iHasNewViewOrigin = true; - } -#endif - } - else - { - // Move around in normal spectator method - // friction - speed = Length (pmove->velocity); - if (speed < 1) - { - VectorCopy (shared_vec3_origin, pmove->velocity) - } - else - { - drop = 0; - - friction = pmove->movevars->friction*1.5; // extra friction - control = speed < pmove->movevars->stopspeed ? pmove->movevars->stopspeed : speed; - drop += control*friction*pmove->frametime; - - // scale the velocity - newspeed = speed - drop; - if (newspeed < 0) - newspeed = 0; - newspeed /= speed; - - VectorScale (pmove->velocity, newspeed, pmove->velocity); - } - - // accelerate - fmove = pmove->cmd.forwardmove; - smove = pmove->cmd.sidemove; - - VectorNormalize (pmove->forward); - VectorNormalize (pmove->right); - - for (i=0 ; i<3 ; i++) - { - wishvel[i] = pmove->forward[i]*fmove + pmove->right[i]*smove; - } - wishvel[2] += pmove->cmd.upmove; - - VectorCopy (wishvel, wishdir); - wishspeed = VectorNormalize(wishdir); - - // - // clamp to server defined max speed - // - if (wishspeed > pmove->movevars->spectatormaxspeed) - { - VectorScale (wishvel, pmove->movevars->spectatormaxspeed/wishspeed, wishvel); - wishspeed = pmove->movevars->spectatormaxspeed; - } - - currentspeed = DotProduct(pmove->velocity, wishdir); - addspeed = wishspeed - currentspeed; - if (addspeed <= 0) - return; - accelspeed = pmove->movevars->accelerate*pmove->frametime*wishspeed; - if (accelspeed > addspeed) - accelspeed = addspeed; - - for (i=0 ; i<3 ; i++) - pmove->velocity[i] += accelspeed*wishdir[i]; - - // move - VectorMA (pmove->origin, pmove->frametime, pmove->velocity, pmove->origin); - } -} - -/* -================== -PM_SplineFraction - -Use for ease-in, ease-out style interpolation (accel/decel) -Used by ducking code. -================== -*/ -float PM_SplineFraction( float value, float scale ) -{ - float valueSquared; - - value = scale * value; - valueSquared = value * value; - - // Nice little ease-in, ease-out spline-like curve - return 3 * valueSquared - 2 * valueSquared * value; -} - -void PM_FixPlayerCrouchStuck( int direction ) -{ - int hitent; - int i; - vec3_t test; - - hitent = pmove->PM_TestPlayerPositionEx ( pmove->origin, NULL, PM_Ignore ); - if (hitent == -1 ) - return; - - VectorCopy( pmove->origin, test ); - for ( i = 0; i < 36; i++ ) - { - pmove->origin[2] += direction; - hitent = pmove->PM_TestPlayerPositionEx ( pmove->origin, NULL, PM_Ignore ); - if (hitent == -1 ) - return; - } - - VectorCopy( test, pmove->origin ); // Failed -} - -void PM_Duck( void ) -{ - int i; - float time; - float duckFraction; - - int buttonsChanged = ( pmove->oldbuttons ^ pmove->cmd.buttons ); // These buttons have changed this frame - int nButtonPressed = buttonsChanged & pmove->cmd.buttons; // The changed ones still down are "pressed" - - int duckchange = buttonsChanged & IN_DUCK ? 1 : 0; - int duckpressed = nButtonPressed & IN_DUCK ? 1 : 0; - - if ( pmove->cmd.buttons & IN_DUCK ) - { - pmove->oldbuttons |= IN_DUCK; - } - else - { - pmove->oldbuttons &= ~IN_DUCK; - } - - // Discwar: Prevent ducking - return; - - if ( pmove->dead ) - return; - - if ( ( pmove->cmd.buttons & IN_DUCK ) || ( pmove->bInDuck ) || ( pmove->flags & FL_DUCKING ) ) - { - pmove->cmd.forwardmove *= PLAYER_DUCKING_MULTIPLIER; - pmove->cmd.sidemove *= PLAYER_DUCKING_MULTIPLIER; - pmove->cmd.upmove *= PLAYER_DUCKING_MULTIPLIER; - - if ( pmove->cmd.buttons & IN_DUCK ) - { - if ( (nButtonPressed & IN_DUCK ) && !( pmove->flags & FL_DUCKING ) ) - { - // Use 1 second so super long jump will work - pmove->flDuckTime = 1000; - pmove->bInDuck = true; - } - - time = V_max( 0.0, ( 1.0 - (float)pmove->flDuckTime / 1000.0 ) ); - - if ( pmove->bInDuck ) - { - // Finish ducking immediately if duck time is over or not on ground - if ( ( (float)pmove->flDuckTime / 1000.0 <= ( 1.0 - TIME_TO_DUCK ) ) || - ( pmove->onground == -1 ) ) - { - pmove->usehull = 1; - pmove->view_ofs[2] = VEC_DUCK_VIEW; - pmove->flags |= FL_DUCKING; - pmove->bInDuck = false; - - // HACKHACK - Fudge for collision bug - no time to fix this properly - if ( pmove->onground != -1 ) - { - for ( i = 0; i < 3; i++ ) - { - pmove->origin[i] -= ( pmove->player_mins[1][i] - pmove->player_mins[0][i] ); - } - // See if we are stuck? - PM_FixPlayerCrouchStuck( STUCK_MOVEUP ); - - // Recatagorize position since ducking can change origin - PM_CatagorizePosition(); - } - } - else - { - float fMore = (VEC_DUCK_HULL_MIN - VEC_HULL_MIN); - - // Calc parametric time - duckFraction = PM_SplineFraction( time, (1.0/TIME_TO_DUCK) ); - pmove->view_ofs[2] = ((VEC_DUCK_VIEW - fMore ) * duckFraction) + (VEC_VIEW * (1-duckFraction)); - } - } - } - else - { - pmtrace_t trace; - vec3_t newOrigin; - - VectorCopy( pmove->origin, newOrigin ); - - if ( pmove->onground != -1 ) - { - for ( i = 0; i < 3; i++ ) - { - newOrigin[i] += ( pmove->player_mins[1][i] - pmove->player_mins[0][i] ); - } - } - - trace = pmove->PM_PlayerTraceEx ( newOrigin, newOrigin, PM_NORMAL, PM_Ignore ); - - if ( !trace.startsolid ) - { - pmove->usehull = 0; - - // Oh, no, changing hulls stuck us into something, try unsticking downward first. - trace = pmove->PM_PlayerTraceEx( newOrigin, newOrigin, PM_NORMAL, PM_Ignore ); - if ( trace.startsolid ) - { - // See if we are stuck? If so, stay ducked with the duck hull until we have a clear spot - //Con_Printf( "unstick got stuck\n" ); - pmove->usehull = 1; - return; - } - - pmove->flags &= ~FL_DUCKING; - pmove->bInDuck = false; - pmove->view_ofs[2] = VEC_VIEW; - pmove->flDuckTime = 0; - - VectorCopy( newOrigin, pmove->origin ); - - // Recatagorize position since ducking can change origin - PM_CatagorizePosition(); - } - } - } -} - -void PM_LadderMove( physent_t *pLadder ) -{ - vec3_t ladderCenter; - trace_t trace; - qboolean onFloor; - vec3_t floor; - vec3_t modelmins, modelmaxs; - - if ( pmove->movetype == MOVETYPE_NOCLIP ) - return; - - pmove->PM_GetModelBounds( pLadder->model, modelmins, modelmaxs ); - - VectorAdd( modelmins, modelmaxs, ladderCenter ); - VectorScale( ladderCenter, 0.5, ladderCenter ); - - pmove->movetype = MOVETYPE_FLY; - - // On ladder, convert movement to be relative to the ladder - - VectorCopy( pmove->origin, floor ); - floor[2] += pmove->player_mins[pmove->usehull][2] - 1; - - if ( pmove->PM_PointContents( floor, NULL ) == CONTENTS_SOLID ) - onFloor = true; - else - onFloor = false; - - pmove->gravity = 0; - pmove->PM_TraceModel( pLadder, pmove->origin, ladderCenter, &trace ); - if ( trace.fraction != 1.0 ) - { - float forward = 0, right = 0; - vec3_t vpn, v_right; - float flSpeed = MAX_CLIMB_SPEED; - - // they shouldn't be able to move faster than their maxspeed - if ( flSpeed > pmove->maxspeed ) - { - flSpeed = pmove->maxspeed; - } - - AngleVectors( pmove->angles, vpn, v_right, NULL ); - - if ( pmove->flags & FL_DUCKING ) - { - flSpeed *= PLAYER_DUCKING_MULTIPLIER; - } - - if ( pmove->cmd.buttons & IN_BACK ) - { - forward -= flSpeed; - } - if ( pmove->cmd.buttons & IN_FORWARD ) - { - forward += flSpeed; - } - if ( pmove->cmd.buttons & IN_MOVELEFT ) - { - right -= flSpeed; - } - if ( pmove->cmd.buttons & IN_MOVERIGHT ) - { - right += flSpeed; - } - - if ( pmove->cmd.buttons & IN_JUMP ) - { - pmove->movetype = MOVETYPE_WALK; - VectorScale( trace.plane.normal, 270, pmove->velocity ); - } - else - { - if ( forward != 0 || right != 0 ) - { - vec3_t velocity, perp, cross, lateral, tmp; - float normal; - - //ALERT(at_console, "pev %.2f %.2f %.2f - ", - // pev->velocity.x, pev->velocity.y, pev->velocity.z); - // Calculate player's intended velocity - //Vector velocity = (forward * gpGlobals->v_forward) + (right * gpGlobals->v_right); - VectorScale( vpn, forward, velocity ); - VectorMA( velocity, right, v_right, velocity ); - - - // Perpendicular in the ladder plane - // Vector perp = CrossProduct( Vector(0,0,1), trace.vecPlaneNormal ); - // perp = perp.Normalize(); - VectorClear( tmp ); - tmp[2] = 1; - CrossProduct( tmp, trace.plane.normal, perp ); - VectorNormalize( perp ); - - - // decompose velocity into ladder plane - normal = DotProduct( velocity, trace.plane.normal ); - // This is the velocity into the face of the ladder - VectorScale( trace.plane.normal, normal, cross ); - - - // This is the player's additional velocity - VectorSubtract( velocity, cross, lateral ); - - // This turns the velocity into the face of the ladder into velocity that - // is roughly vertically perpendicular to the face of the ladder. - // NOTE: It IS possible to face up and move down or face down and move up - // because the velocity is a sum of the directional velocity and the converted - // velocity through the face of the ladder -- by design. - CrossProduct( trace.plane.normal, perp, tmp ); - VectorMA( lateral, -normal, tmp, pmove->velocity ); - if ( onFloor && normal > 0 ) // On ground moving away from the ladder - { - VectorMA( pmove->velocity, MAX_CLIMB_SPEED, trace.plane.normal, pmove->velocity ); - } - //pev->velocity = lateral - (CrossProduct( trace.vecPlaneNormal, perp ) * normal); - } - else - { - VectorClear( pmove->velocity ); - } - } - } -} - -physent_t *PM_Ladder( void ) -{ - int i; - physent_t *pe; - hull_t *hull; - int num; - vec3_t test; - - for ( i = 0; i < pmove->nummoveent; i++ ) - { - pe = &pmove->moveents[i]; - - if ( pe->model && (modtype_t)pmove->PM_GetModelType( pe->model ) == mod_brush && pe->skin == CONTENTS_LADDER ) - { - - hull = (hull_t *)pmove->PM_HullForBsp( pe, test ); - num = hull->firstclipnode; - - // Offset the test point appropriately for this hull. - VectorSubtract ( pmove->origin, test, test); - - // Test the player's hull for intersection with this model - if ( pmove->PM_HullPointContents (hull, num, test) == CONTENTS_EMPTY) - continue; - - return pe; - } - } - - return NULL; -} - - - -void PM_WaterJump (void) -{ - if ( pmove->waterjumptime > 10000 ) - { - pmove->waterjumptime = 10000; - } - - if ( !pmove->waterjumptime ) - return; - - pmove->waterjumptime -= pmove->cmd.msec; - if ( pmove->waterjumptime < 0 || - !pmove->waterlevel ) - { - pmove->waterjumptime = 0; - pmove->flags &= ~FL_WATERJUMP; - } - - pmove->velocity[0] = pmove->movedir[0]; - pmove->velocity[1] = pmove->movedir[1]; -} - -/* -============ -PM_AddGravity - -============ -*/ -void PM_AddGravity () -{ - float ent_gravity; - - if (pmove->gravity) - ent_gravity = pmove->gravity; - else - ent_gravity = 1.0; - - // Add gravity incorrectly - pmove->velocity[2] -= (ent_gravity * pmove->movevars->gravity * pmove->frametime ); - pmove->velocity[2] += pmove->basevelocity[2] * pmove->frametime; - pmove->basevelocity[2] = 0; - PM_CheckVelocity(); -} -/* -============ -PM_PushEntity - -Does not change the entities velocity at all -============ -*/ -pmtrace_t PM_PushEntity (vec3_t push) -{ - pmtrace_t trace; - vec3_t end; - - VectorAdd (pmove->origin, push, end); - - trace = pmove->PM_PlayerTraceEx (pmove->origin, end, PM_NORMAL, PM_Ignore ); - - VectorCopy (trace.endpos, pmove->origin); - - // So we can run impact function afterwards. - if (trace.fraction < 1.0 && - !trace.allsolid) - { - PM_AddToTouched(trace, pmove->velocity); - } - - return trace; -} - -/* -============ -PM_Physics_Toss() - -Dead player flying through air., e.g. -============ -*/ -void PM_Physics_Toss() -{ - pmtrace_t trace; - vec3_t move; - float backoff; - - PM_CheckWater(); - - if (pmove->velocity[2] > 0) - pmove->onground = -1; - - // If on ground and not moving, return. - if ( pmove->onground != -1 ) - { - if (VectorCompare(pmove->basevelocity, shared_vec3_origin) && - VectorCompare(pmove->velocity, shared_vec3_origin)) - return; - } - - PM_CheckVelocity (); - -// add gravity - if ( pmove->movetype != MOVETYPE_FLY && - pmove->movetype != MOVETYPE_BOUNCEMISSILE && - pmove->movetype != MOVETYPE_FLYMISSILE ) - PM_AddGravity (); - -// move origin - // Base velocity is not properly accounted for since this entity will move again after the bounce without - // taking it into account - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity); - - PM_CheckVelocity(); - VectorScale (pmove->velocity, pmove->frametime, move); - VectorSubtract (pmove->velocity, pmove->basevelocity, pmove->velocity); - - trace = PM_PushEntity (move); // Should this clear basevelocity - - PM_CheckVelocity(); - - if (trace.allsolid) - { - // entity is trapped in another solid - pmove->onground = trace.ent; - VectorCopy (shared_vec3_origin, pmove->velocity); - return; - } - - if (trace.fraction == 1) - { - PM_CheckWater(); - return; - } - - - if (pmove->movetype == MOVETYPE_BOUNCE) - backoff = 2.0 - pmove->friction; - else if (pmove->movetype == MOVETYPE_BOUNCEMISSILE) - backoff = 2.0; - else - backoff = 1; - - PM_ClipVelocity (pmove->velocity, trace.plane.normal, pmove->velocity, backoff); - - // stop if on ground - if (trace.plane.normal[2] > 0.7) - { - float vel; - vec3_t base; - - VectorClear( base ); - if (pmove->velocity[2] < pmove->movevars->gravity * pmove->frametime) - { - // we're rolling on the ground, add static friction. - pmove->onground = trace.ent; - pmove->velocity[2] = 0; - } - - vel = DotProduct( pmove->velocity, pmove->velocity ); - - // Con_DPrintf("%f %f: %.0f %.0f %.0f\n", vel, trace.fraction, ent->velocity[0], ent->velocity[1], ent->velocity[2] ); - - if (vel < (30 * 30) || (pmove->movetype != MOVETYPE_BOUNCE && pmove->movetype != MOVETYPE_BOUNCEMISSILE)) - { - pmove->onground = trace.ent; - VectorCopy (shared_vec3_origin, pmove->velocity); - } - else - { - VectorScale (pmove->velocity, (1.0 - trace.fraction) * pmove->frametime * 0.9, move); - trace = PM_PushEntity (move); - } - VectorSubtract( pmove->velocity, base, pmove->velocity ) - } - -// check for in water - PM_CheckWater(); -} - -/* -==================== -PM_NoClip - -==================== -*/ -void PM_NoClip() -{ - int i; - vec3_t wishvel; - float fmove, smove; -// float currentspeed, addspeed, accelspeed; - - // Copy movement amounts - fmove = pmove->cmd.forwardmove; - smove = pmove->cmd.sidemove; - - VectorNormalize ( pmove->forward ); - VectorNormalize ( pmove->right ); - - for (i=0 ; i<3 ; i++) // Determine x and y parts of velocity - { - wishvel[i] = pmove->forward[i]*fmove + pmove->right[i]*smove; - } - wishvel[2] += pmove->cmd.upmove; - - VectorMA (pmove->origin, pmove->frametime, wishvel, pmove->origin); - - // Zero out the velocity so that we don't accumulate a huge downward velocity from - // gravity, etc. - VectorClear( pmove->velocity ); - -} - -/* -============= -PM_Jump -============= -*/ -void PM_Jump (void) -{ - int i; - qboolean tfc = false; - - qboolean cansuperjump = false; - - // Discwar: Prevent jumping - return; - - if (pmove->dead) - { - pmove->oldbuttons |= IN_JUMP ; // don't jump again until released - return; - } - - tfc = atoi( pmove->PM_Info_ValueForKey( pmove->physinfo, "tfc" ) ) == 1 ? true : false; - - // Spy that's feigning death cannot jump - if ( tfc && - ( pmove->deadflag == ( DEAD_DISCARDBODY + 1 ) ) ) - { - return; - } - - // See if we are waterjumping. If so, decrement count and return. - if ( pmove->waterjumptime ) - { - pmove->waterjumptime -= pmove->cmd.msec; - if (pmove->waterjumptime < 0) - { - pmove->waterjumptime = 0; - } - return; - } - - // If we are in the water most of the way... - if (pmove->waterlevel >= 2) - { // swimming, not jumping - pmove->onground = -1; - - if (pmove->watertype == CONTENTS_WATER) // We move up a certain amount - pmove->velocity[2] = 100; - else if (pmove->watertype == CONTENTS_SLIME) - pmove->velocity[2] = 80; - else // LAVA - pmove->velocity[2] = 50; - - // play swiming sound - if ( pmove->flSwimTime <= 0 ) - { - // Don't play sound again for 1 second - pmove->flSwimTime = 1000; - switch ( pmove->RandomLong( 0, 3 ) ) - { - case 0: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 1: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade2.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 2: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade3.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 3: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade4.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - } - } - - return; - } - - // No more effect - if ( pmove->onground == -1 ) - { - // Flag that we jumped. - // HACK HACK HACK - // Remove this when the game .dll no longer does physics code!!!! - pmove->oldbuttons |= IN_JUMP; // don't jump again until released - return; // in air, so no effect - } - - if ( pmove->oldbuttons & IN_JUMP ) - return; // don't pogo stick - - // In the air now. - pmove->onground = -1; - - if ( tfc ) - { - pmove->PM_PlaySound( CHAN_BODY, "player/plyrjmp8.wav", 0.5, ATTN_NORM, 0, PITCH_NORM ); - } - else - { - PM_PlayStepSound( PM_MapTextureTypeStepType( pmove->chtexturetype ), 1.0 ); - } - - // See if user can super long jump? - cansuperjump = atoi( pmove->PM_Info_ValueForKey( pmove->physinfo, "slj" ) ) == 1 ? true : false; - - // Acclerate upward - // If we are ducking... - if ( ( pmove->bInDuck ) || ( pmove->flags & FL_DUCKING ) ) - { - // Adjust for super long jump module - // UNDONE -- note this should be based on forward angles, not current velocity. - if ( cansuperjump && - ( pmove->cmd.buttons & IN_DUCK ) && - ( pmove->flDuckTime > 0 ) && - Length( pmove->velocity ) > 50 ) - { - pmove->punchangle[0] = -5; - - for (i =0; i < 2; i++) - { - pmove->velocity[i] = pmove->forward[i] * PLAYER_LONGJUMP_SPEED * 1.6; - } - - pmove->velocity[2] = sqrt(2 * 800 * 56.0); - } - else - { - pmove->velocity[2] = sqrt(2 * 800 * 45.0); - } - } - else - { - pmove->velocity[2] = sqrt(2 * 800 * 45.0); - } - - // Decay it for simulation - PM_FixupGravityVelocity(); - - // Flag that we jumped. - pmove->oldbuttons |= IN_JUMP; // don't jump again until released -} - -/* -============= -PM_CheckWaterJump -============= -*/ -#define WJ_HEIGHT 8 -void PM_CheckWaterJump (void) -{ - vec3_t vecStart, vecEnd; - vec3_t flatforward; - vec3_t flatvelocity; - float curspeed; - pmtrace_t tr; - int savehull; - - // Already water jumping. - if ( pmove->waterjumptime ) - return; - - // Don't hop out if we just jumped in - if ( pmove->velocity[2] < -180 ) - return; // only hop out if we are moving up - - // See if we are backing up - flatvelocity[0] = pmove->velocity[0]; - flatvelocity[1] = pmove->velocity[1]; - flatvelocity[2] = 0; - - // Must be moving - curspeed = VectorNormalize( flatvelocity ); - - // see if near an edge - flatforward[0] = pmove->forward[0]; - flatforward[1] = pmove->forward[1]; - flatforward[2] = 0; - VectorNormalize (flatforward); - - // Are we backing into water from steps or something? If so, don't pop forward - if ( curspeed != 0.0 && ( DotProduct( flatvelocity, flatforward ) < 0.0 ) ) - return; - - VectorCopy( pmove->origin, vecStart ); - vecStart[2] += WJ_HEIGHT; - - VectorMA ( vecStart, 24, flatforward, vecEnd ); - - // Trace, this trace should use the point sized collision hull - savehull = pmove->usehull; - pmove->usehull = 2; - tr = pmove->PM_PlayerTraceEx( vecStart, vecEnd, PM_NORMAL, PM_Ignore ); - if ( tr.fraction < 1.0 && fabs( tr.plane.normal[2] ) < 0.1f ) // Facing a near vertical wall? - { - vecStart[2] += pmove->player_maxs[ savehull ][2] - WJ_HEIGHT; - VectorMA( vecStart, 24, flatforward, vecEnd ); - VectorMA(shared_vec3_origin, -50, tr.plane.normal, pmove->movedir ); - - tr = pmove->PM_PlayerTraceEx( vecStart, vecEnd, PM_NORMAL, PM_Ignore ); - if ( tr.fraction == 1.0 ) - { - pmove->waterjumptime = 2000; - pmove->velocity[2] = 225; - pmove->oldbuttons |= IN_JUMP; - pmove->flags |= FL_WATERJUMP; - } - } - - // Reset the collision hull - pmove->usehull = savehull; -} - -void PM_CheckFalling( void ) -{ - if ( pmove->onground != -1 && - !pmove->dead && - pmove->flFallVelocity >= PLAYER_FALL_PUNCH_THRESHHOLD ) - { - float fvol = 0.5; - - if ( pmove->waterlevel > 0 ) - { - } - else if ( pmove->flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED ) - { - // NOTE: In the original game dll , there were no breaks after these cases, causing the first one to - // cascade into the second - //switch ( RandomLong(0,1) ) - //{ - //case 0: - //pmove->PM_PlaySound( CHAN_VOICE, "player/pl_fallpain2.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - //break; - //case 1: - pmove->PM_PlaySound( CHAN_VOICE, "player/pl_fallpain3.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - // break; - //} - fvol = 1.0; - } - else if ( pmove->flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED / 2 ) - { - qboolean tfc = false; - tfc = atoi( pmove->PM_Info_ValueForKey( pmove->physinfo, "tfc" ) ) == 1 ? true : false; - - if ( tfc ) - { - pmove->PM_PlaySound( CHAN_VOICE, "player/pl_fallpain3.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - } - - fvol = 0.85; - } - else if ( pmove->flFallVelocity < PLAYER_MIN_BOUNCE_SPEED ) - { - fvol = 0; - } - - if ( fvol > 0.0 ) - { - // Play landing step right away - pmove->flTimeStepSound = 0; - - PM_UpdateStepSound(); - - // play step sound for current texture - PM_PlayStepSound( PM_MapTextureTypeStepType( pmove->chtexturetype ), fvol ); - - // Knock the screen around a little bit, temporary effect - //pmove->punchangle[ 2 ] = pmove->flFallVelocity * 0.013; // punch z axis - - if ( pmove->punchangle[ 0 ] > 8 ) - { - pmove->punchangle[ 0 ] = 8; - } - } - } - - if ( pmove->onground != -1 ) - { - pmove->flFallVelocity = 0; - } -} - -/* -================= -PM_PlayWaterSounds - -================= -*/ -void PM_PlayWaterSounds( void ) -{ - // Did we enter or leave water? - if ( ( pmove->oldwaterlevel == 0 && pmove->waterlevel != 0 ) || - ( pmove->oldwaterlevel != 0 && pmove->waterlevel == 0 ) ) - { - switch ( pmove->RandomLong(0,3) ) - { - case 0: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 1: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade2.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 2: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade3.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - case 3: - pmove->PM_PlaySound( CHAN_BODY, "player/pl_wade4.wav", 1, ATTN_NORM, 0, PITCH_NORM ); - break; - } - } -} - -/* -=============== -PM_CalcRoll - -=============== -*/ -float PM_CalcRoll (vec3_t angles, vec3_t velocity, float rollangle, float rollspeed ) -{ - float sign; - float side; - float value; - vec3_t forward, right, up; - - AngleVectors (angles, forward, right, up); - - side = DotProduct (velocity, right); - - sign = side < 0 ? -1 : 1; - - side = fabs(side); - - value = rollangle; - - if (side < rollspeed) - { - side = side * value / rollspeed; - } - else - { - side = value; - } - - return side * sign; -} - -/* -============= -PM_DropPunchAngle - -============= -*/ -void PM_DropPunchAngle ( vec3_t punchangle ) -{ - float len; - - len = VectorNormalize ( punchangle ); - len -= (10.0 + len * 0.5) * pmove->frametime; - len = V_max( len, 0.0 ); - VectorScale ( punchangle, len, punchangle); -} - -/* -============== -PM_CheckParamters - -============== -*/ -void PM_CheckParamters( void ) -{ - float spd; - float maxspeed; - vec3_t v_angle; - - spd = ( pmove->cmd.forwardmove * pmove->cmd.forwardmove ) + - ( pmove->cmd.sidemove * pmove->cmd.sidemove ) + - ( pmove->cmd.upmove * pmove->cmd.upmove ); - spd = sqrt( spd ); - - maxspeed = pmove->clientmaxspeed; //atof( pmove->PM_Info_ValueForKey( pmove->physinfo, "maxspd" ) ); - if ( maxspeed != 0.0 ) - { - pmove->maxspeed = V_min( maxspeed, pmove->maxspeed ); - } - - if ( ( spd != 0.0 ) && - ( spd > pmove->maxspeed ) ) - { - float fRatio = pmove->maxspeed / spd; - pmove->cmd.forwardmove *= fRatio; - pmove->cmd.sidemove *= fRatio; - pmove->cmd.upmove *= fRatio; - } - - if ( pmove->flags & FL_FROZEN || - pmove->flags & FL_ONTRAIN || - pmove->dead ) - { - pmove->cmd.forwardmove = 0; - pmove->cmd.sidemove = 0; - pmove->cmd.upmove = 0; - } - - - PM_DropPunchAngle( pmove->punchangle ); - - // Take angles from command. - if ( !pmove->dead ) - { - VectorCopy ( pmove->cmd.viewangles, v_angle ); - VectorAdd( v_angle, pmove->punchangle, v_angle ); - - // Set up view angles. - pmove->angles[ROLL] = PM_CalcRoll ( v_angle, pmove->velocity, pmove->movevars->rollangle, pmove->movevars->rollspeed )*4; - pmove->angles[PITCH] = v_angle[PITCH]; - pmove->angles[YAW] = v_angle[YAW]; - } - else - { - VectorCopy( pmove->oldangles, pmove->angles ); - } - - // Set dead player view_offset - if ( pmove->dead ) - { - pmove->view_ofs[2] = PM_DEAD_VIEWHEIGHT; - } - - // Adjust client view angles to match values used on server. - if (pmove->angles[YAW] > 180.0f) - { - pmove->angles[YAW] -= 360.0f; - } - -} - -void PM_ReduceTimers( void ) -{ - if ( pmove->flTimeStepSound > 0 ) - { - pmove->flTimeStepSound -= pmove->cmd.msec; - if ( pmove->flTimeStepSound < 0 ) - { - pmove->flTimeStepSound = 0; - } - } - if ( pmove->flDuckTime > 0 ) - { - pmove->flDuckTime -= pmove->cmd.msec; - if ( pmove->flDuckTime < 0 ) - { - pmove->flDuckTime = 0; - } - } - if ( pmove->flSwimTime > 0 ) - { - pmove->flSwimTime -= pmove->cmd.msec; - if ( pmove->flSwimTime < 0 ) - { - pmove->flSwimTime = 0; - } - } -} - -/* -============= -PlayerMove - -Returns with origin, angles, and velocity modified in place. - -Numtouch and touchindex[] will be set if any of the physents -were contacted during the move. -============= -*/ -void PM_PlayerMove ( qboolean server ) -{ - physent_t *pLadder = NULL; - - // Are we running server code? - pmove->server = server; - - // Adjust speeds etc. - PM_CheckParamters(); - - // Assume we don't touch anything - pmove->numtouch = 0; - - // # of msec to apply movement - pmove->frametime = pmove->cmd.msec * 0.001; - - PM_ReduceTimers(); - - // Convert view angles to vectors - AngleVectors (pmove->angles, pmove->forward, pmove->right, pmove->up); - - // PM_ShowClipBox(); - -#ifdef CLIENT_DLL - if ( pmove->runfuncs ) - { - iIsSpectator = false; - iHasNewViewAngles = false; - iHasNewViewOrigin = false; - } -#endif - - if ( pmove->iuser1 == 4 ) - return; - - // Special handling for spectator and observers. (iuser1 is set if the player's in observer mode) - if ( pmove->spectator || pmove->iuser1 > 0 ) - { - PM_SpectatorMove(); - PM_CatagorizePosition(); - return; - } - - // Always try and unstick us unless we are in NOCLIP mode - if ( pmove->movetype != MOVETYPE_NOCLIP && pmove->movetype != MOVETYPE_NONE ) - { - if ( PM_CheckStuck() ) - { - return; // Can't move, we're stuck - } - } - - // Now that we are "unstuck", see where we are ( waterlevel and type, pmove->onground ). - PM_CatagorizePosition(); - - // Store off the starting water level - pmove->oldwaterlevel = pmove->waterlevel; - - // If we are not on ground, store off how fast we are moving down - if ( pmove->onground == -1 ) - { - pmove->flFallVelocity = -pmove->velocity[2]; - } - - g_onladder = 0; - // Don't run ladder code if dead or on a train - if ( !pmove->dead && !(pmove->flags & FL_ONTRAIN) ) - { - pLadder = PM_Ladder(); - if ( pLadder ) - { - g_onladder = 1; - } - } - - PM_UpdateStepSound(); - - PM_Duck(); - - // Don't run ladder code if dead or on a train - if ( !pmove->dead && !(pmove->flags & FL_ONTRAIN) ) - { - if ( pLadder ) - { - PM_LadderMove( pLadder ); - } - else if ( pmove->movetype != MOVETYPE_WALK && - pmove->movetype != MOVETYPE_NOCLIP ) - { - // Clear ladder stuff unless player is noclipping - // it will be set immediately again next frame if necessary - pmove->movetype = MOVETYPE_WALK; - } - } - - // Slow down, I'm pulling it! (a box maybe) but only when I'm standing on ground - if ( ( pmove->onground != -1 ) && ( pmove->cmd.buttons & IN_USE) ) - { - VectorScale( pmove->velocity, 0.3, pmove->velocity ); - } - - // Handle movement - switch ( pmove->movetype ) - { - default: - pmove->Con_DPrintf("Bogus pmove player movetype %i on (%i) 0=cl 1=sv\n", pmove->movetype, pmove->server); - break; - - case MOVETYPE_NONE: - break; - - case MOVETYPE_NOCLIP: - PM_NoClip(); - break; - - case MOVETYPE_TOSS: - case MOVETYPE_BOUNCE: - PM_Physics_Toss(); - break; - - case MOVETYPE_FLY: - - PM_CheckWater(); - - // Was jump button pressed? - // If so, set velocity to 270 away from ladder. This is currently wrong. - // Also, set MOVE_TYPE to walk, too. - if ( pmove->cmd.buttons & IN_JUMP ) - { - if ( !pLadder ) - { - PM_Jump (); - } - } - else - { - pmove->oldbuttons &= ~IN_JUMP; - } - - // Perform the move accounting for any base velocity. - VectorAdd (pmove->velocity, pmove->basevelocity, pmove->velocity); - PM_FlyMove (); - VectorSubtract (pmove->velocity, pmove->basevelocity, pmove->velocity); - break; - - case MOVETYPE_WALK: - if ( !PM_InWater() ) - { - PM_AddCorrectGravity(); - } - - // If we are leaping out of the water, just update the counters. - if ( pmove->waterjumptime ) - { - PM_WaterJump(); - PM_FlyMove(); - - // Make sure waterlevel is set correctly - PM_CheckWater(); - return; - } - - // If we are swimming in the water, see if we are nudging against a place we can jump up out - // of, and, if so, start out jump. Otherwise, if we are not moving up, then reset jump timer to 0 - if ( pmove->waterlevel >= 2 ) - { - if ( pmove->waterlevel == 2 ) - { - PM_CheckWaterJump(); - } - - // If we are falling again, then we must not trying to jump out of water any more. - if ( pmove->velocity[2] < 0 && pmove->waterjumptime ) - { - pmove->waterjumptime = 0; - } - - // Was jump button pressed? - if (pmove->cmd.buttons & IN_JUMP) - { - PM_Jump (); - } - else - { - pmove->oldbuttons &= ~IN_JUMP; - } - - // Perform regular water movement - PM_WaterMove(); - - VectorSubtract (pmove->velocity, pmove->basevelocity, pmove->velocity); - - // Get a final position - PM_CatagorizePosition(); - } - else - - // Not underwater - { - // Was jump button pressed? - if ( pmove->cmd.buttons & IN_JUMP ) - { - if ( !pLadder ) - { - PM_Jump (); - } - } - else - { - pmove->oldbuttons &= ~IN_JUMP; - } - - // Fricion is handled before we add in any base velocity. That way, if we are on a conveyor, - // we don't slow when standing still, relative to the conveyor. - if ( pmove->onground != -1 ) - { - pmove->velocity[2] = 0.0; - PM_Friction(); - } - - // Make sure velocity is valid. - PM_CheckVelocity(); - - // Are we on ground now - if ( pmove->onground != -1 ) - { - PM_WalkMove(); - } - else - { - PM_AirMove(); // Take into account movement when in air. - } - - // Set final flags. - PM_CatagorizePosition(); - - // Now pull the base velocity back out. - // Base velocity is set if you are on a moving object, like - // a conveyor (or maybe another monster?) - VectorSubtract (pmove->velocity, pmove->basevelocity, pmove->velocity ); - - // Make sure velocity is valid. - PM_CheckVelocity(); - - // Add any remaining gravitational component. - if ( !PM_InWater() ) - { - PM_FixupGravityVelocity(); - } - - // If we are on ground, no downward velocity. - if ( pmove->onground != -1 ) - { - pmove->velocity[2] = 0; - } - - // See if we landed on the ground with enough force to play - // a landing sound. - PM_CheckFalling(); - } - - // Did we enter or leave the water? - PM_PlayWaterSounds(); - break; - } -} - -void PM_CreateStuckTable( void ) -{ - float x, y, z; - int idx; - int i; - float zi[3]; - - memset(rgv3tStuckTable, 0, 54 * sizeof(vec3_t)); - - idx = 0; - // Little Moves. - x = y = 0; - // Z moves - for (z = -0.125 ; z <= 0.125 ; z += 0.125) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - x = z = 0; - // Y moves - for (y = -0.125 ; y <= 0.125 ; y += 0.125) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - y = z = 0; - // X moves - for (x = -0.125 ; x <= 0.125 ; x += 0.125) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - - // Remaining multi axis nudges. - for ( x = - 0.125; x <= 0.125; x += 0.250 ) - { - for ( y = - 0.125; y <= 0.125; y += 0.250 ) - { - for ( z = - 0.125; z <= 0.125; z += 0.250 ) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - } - } - - // Big Moves. - x = y = 0; - zi[0] = 0.0f; - zi[1] = 1.0f; - zi[2] = 6.0f; - - for (i = 0; i < 3; i++) - { - // Z moves - z = zi[i]; - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - - x = z = 0; - - // Y moves - for (y = -2.0f ; y <= 2.0f ; y += 2.0) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - y = z = 0; - // X moves - for (x = -2.0f ; x <= 2.0f ; x += 2.0f) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - - // Remaining multi axis nudges. - for (i = 0 ; i < 3; i++) - { - z = zi[i]; - - for (x = -2.0f ; x <= 2.0f ; x += 2.0f) - { - for (y = -2.0f ; y <= 2.0f ; y += 2.0) - { - rgv3tStuckTable[idx][0] = x; - rgv3tStuckTable[idx][1] = y; - rgv3tStuckTable[idx][2] = z; - idx++; - } - } - } -} - - - -/* -This modume implements the shared player physics code between any particular game and -the engine. The same PM_Move routine is built into the game .dll and the client .dll and is -invoked by each side as appropriate. There should be no distinction, internally, between server -and client. This will ensure that prediction behaves appropriately. -*/ - -void PM_Move ( struct playermove_s *ppmove, int server ) -{ - assert( pm_shared_initialized ); - - pmove = ppmove; - - PM_PlayerMove( ( server != 0 ) ? true : false ); - - if ( pmove->onground != -1 ) - { - pmove->flags |= FL_ONGROUND; - } - else - { - pmove->flags &= ~FL_ONGROUND; - } - - // In single player, reset friction after each movement to FrictionModifier Triggers work still. - if ( !pmove->multiplayer && ( pmove->movetype == MOVETYPE_WALK ) ) - { - pmove->friction = 1.0f; - } -} - -int PM_GetInfo( int ent ) -{ - if ( ent >= 0 && ent <= pmove->numvisent ) - { - return pmove->visents[ ent ].info; - } - return -1; -} - -void PM_Init( struct playermove_s *ppmove ) -{ - assert( !pm_shared_initialized ); - - pmove = ppmove; - - PM_CreateStuckTable(); - PM_InitTextureTypes(); - - pm_shared_initialized = 1; -} diff --git a/ricochet/pm_shared/pm_shared.h b/ricochet/pm_shared/pm_shared.h deleted file mode 100644 index 9da8001..0000000 --- a/ricochet/pm_shared/pm_shared.h +++ /dev/null @@ -1,32 +0,0 @@ -/*** -* -* Copyright (c) 1999, 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. -* -****/ - -// -// pm_shared.h -// -#if !defined( PM_SHAREDH ) -#define PM_SHAREDH -#pragma once - -void PM_Init( struct playermove_s *ppmove ); -void PM_Move ( struct playermove_s *ppmove, int server ); -char PM_FindTextureType( char *name ); - -// Spectator flags -#define SPEC_IS_SPECTATOR (1<<0) -#define SPEC_SMOOTH_ANGLES (1<<1) -#define SPEC_SMOOTH_ORIGIN (1<<2) - -#endif \ No newline at end of file