From 92d04ab82ba46e616a9070e8cd878a78702adda4 Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Fri, 7 Jan 2022 16:07:20 +0400 Subject: [PATCH 01/42] Added cl_hide_center_messages, moved custom viewmodel pointers below of m_pStudioHeader (#152) * Moved custom viewmodel pointers below of m_pStudioHeader * Added cl_hide_center_messages --- cl_dll/StudioModelRenderer.h | 15 ++++++++------- cl_dll/text_message.cpp | 10 ++++++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/cl_dll/StudioModelRenderer.h b/cl_dll/StudioModelRenderer.h index ea4196e5..313ef97a 100644 --- a/cl_dll/StudioModelRenderer.h +++ b/cl_dll/StudioModelRenderer.h @@ -1,4 +1,4 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ +//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ // // Purpose: // @@ -133,12 +133,6 @@ class CStudioModelRenderer cvar_t *m_pCvarDeveloper; // Draw entities bone hit boxes, etc? cvar_t *m_pCvarDrawEntities; - // Change viewmodel FOV - cvar_t *m_pCvarViewmodelFov; - // Disable viewmodel idle/fidget animations on viewmodels - cvar_t *m_pCvarViewmodelNoIdle; - // Disable viewmodel draw/holster/deploy animations on viewmodels - cvar_t *m_pCvarViewmodelNoEquip; // The entity which we are currently rendering. cl_entity_t *m_pCurrentEntity; @@ -201,6 +195,13 @@ class CStudioModelRenderer // Concatenated bone and light transforms float (*m_pbonetransform) [ MAXSTUDIOBONES ][ 3 ][ 4 ]; float (*m_plighttransform)[ MAXSTUDIOBONES ][ 3 ][ 4 ]; + + // Change viewmodel FOV + cvar_t *m_pCvarViewmodelFov; + // Disable viewmodel idle/fidget animations on viewmodels + cvar_t *m_pCvarViewmodelNoIdle; + // Disable viewmodel draw/holster/deploy animations on viewmodels + cvar_t *m_pCvarViewmodelNoEquip; }; #endif // STUDIOMODELRENDERER_H \ No newline at end of file diff --git a/cl_dll/text_message.cpp b/cl_dll/text_message.cpp index 778b3b7e..59f6cbd9 100644 --- a/cl_dll/text_message.cpp +++ b/cl_dll/text_message.cpp @@ -28,6 +28,8 @@ #include "vgui_TeamFortressViewport.h" +cvar_t *m_pCvarHideCenterMessages; + DECLARE_MESSAGE( m_TextMessage, TextMsg ); int CHudTextMessage::Init(void) @@ -37,6 +39,8 @@ int CHudTextMessage::Init(void) ignored_message_types.push_back(CVAR_CREATE("cl_ignore_spawn_messages", "0", FCVAR_ARCHIVE)); ignored_message_types.push_back(CVAR_CREATE("cl_ignore_damage_messages", "0", FCVAR_ARCHIVE)); + m_pCvarHideCenterMessages = CVAR_CREATE( "cl_hide_center_messages", "0", FCVAR_ARCHIVE ); + gHUD.AddHudElem( this ); Reset(); @@ -200,8 +204,10 @@ int CHudTextMessage::MsgFunc_TextMsg( const char *pszName, int iSize, void *pbuf switch ( msg_dest ) { case HUD_PRINTCENTER: - safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); - CenterPrint( ConvertCRtoNL( psz ) ); + if (m_pCvarHideCenterMessages->value == 0.0f) { + safe_sprintf( psz, MSG_BUF_SIZE, msg_text, sstr1, sstr2, sstr3, sstr4 ); + CenterPrint( ConvertCRtoNL( psz ) ); + } break; case HUD_PRINTNOTIFY: From 9fe60e5c1012392f7eec2ff673cc38c3a5595bd0 Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Sun, 30 Jan 2022 10:58:12 +0400 Subject: [PATCH 02/42] Register showtriggers as client command (#153) --- cl_dll/hud.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index aab256d6..67456b71 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -528,6 +528,7 @@ void CHud :: Init( void ) m_pCvarHideCorpses = CVAR_CREATE("cl_hidecorpses", "0", FCVAR_ARCHIVE); m_pCvarColor = CVAR_CREATE( "hud_color", "", FCVAR_ARCHIVE ); cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); + CVAR_CREATE("showtriggers", "0", 0); m_pSpriteList = NULL; From e5bea9eba6836a2d9a8436f3b8103ef7d74a717e Mon Sep 17 00:00:00 2001 From: Schlufi <81391208+Schlufi@users.noreply.github.com> Date: Sun, 30 Jan 2022 07:58:45 +0100 Subject: [PATCH 03/42] Strafing HUD (#149) * Rudimentary strafing HUD. Green means you're accelerating, red means you're decelerating, white means you're not doing either. Friction isn't taken into account (so on the ground this is kind of useless at the moment), and I haven't added any indicator for the "optimal" strafing angle yet. * Fixed online play, added cvars, and fixed some bugs at low speed. * Update cdll_int.cpp * Fixed some bugs with the accel calculation (I accidentally multiplied by sv_friction, and not the entity friction like I should have). Also reworked hud_strafeguide_fov into using default_fov and a hud_strafeguide_zoom cvar. * Before this I used the angles directly for the width of the boxes. This implements the same perspective projection as the game uses, so if you set hud_strafeguide_zoom to 1 everything should line up correctly. * Fix Windows Compile (and a minor bug) --- cl_dll/CMakeLists.txt | 2 + cl_dll/hud.cpp | 1 + cl_dll/hud.h | 2 + cl_dll/hud_redraw.cpp | 3 + cl_dll/hud_strafeguide.cpp | 170 +++++++++++++++++++++++++++++++++++++ cl_dll/hud_strafeguide.h | 21 +++++ cl_dll/view.cpp | 1 + 7 files changed, 200 insertions(+) create mode 100644 cl_dll/hud_strafeguide.cpp create mode 100644 cl_dll/hud_strafeguide.h diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index bef17721..a1904d93 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -69,6 +69,8 @@ add_sources( hud_spectator.h hud_speedometer.cpp hud_speedometer.h + hud_strafeguide.cpp + hud_strafeguide.h hud_suddendeath.cpp hud_suddendeath.h hud_timeout.cpp diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 67456b71..d56eccb8 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -575,6 +575,7 @@ void CHud :: Init( void ) m_Scores.Init(); m_Settings.Init(); m_Speedometer.Init(); + m_StrafeGuide.Init(); m_SuddenDeath.Init(); m_Timeout.Init(); m_Timer.Init(); diff --git a/cl_dll/hud.h b/cl_dll/hud.h index f16e21e8..3173c95c 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -105,6 +105,7 @@ struct HUDLIST { #include "hud_scores.h" #include "hud_settings.h" #include "hud_speedometer.h" +#include "hud_strafeguide.h" #include "hud_suddendeath.h" #include "hud_timeout.h" #include "hud_timer.h" @@ -686,6 +687,7 @@ class CHud CHudScores m_Scores; CHudSettings m_Settings; CHudSpeedometer m_Speedometer; + CHudStrafeGuide m_StrafeGuide; CHudJumpspeed m_Jumpspeed; CHudSuddenDeath m_SuddenDeath; CHudTimeout m_Timeout; diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index 05334f49..1cf37883 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -201,6 +201,9 @@ int CHud :: Redraw( float flTime, int intermission ) if (m_Speedometer.m_iFlags & HUD_ACTIVE) m_Speedometer.Draw(flTime); + + if (m_StrafeGuide.m_iFlags & HUD_ACTIVE) + m_StrafeGuide.Draw(flTime); if (m_Jumpspeed.m_iFlags & HUD_ACTIVE) m_Jumpspeed.Draw(flTime); diff --git a/cl_dll/hud_strafeguide.cpp b/cl_dll/hud_strafeguide.cpp new file mode 100644 index 00000000..5103a193 --- /dev/null +++ b/cl_dll/hud_strafeguide.cpp @@ -0,0 +1,170 @@ +#define _USE_MATH_DEFINES +#include +#include + +#include "hud.h" +#include "cl_util.h" + +#include "pm_defs.h" +#include "pm_movevars.h" + +enum border { + RED_GREEN, + GREEN_WHITE, + WHITE_GREEN, + GREEN_RED +}; + +int CHudStrafeGuide::Init() +{ + m_iFlags = HUD_ACTIVE; + + hud_strafeguide = CVAR_CREATE("hud_strafeguide", "0", FCVAR_ARCHIVE); + hud_strafeguide_zoom = CVAR_CREATE("hud_strafeguide_zoom", "1", FCVAR_ARCHIVE); + hud_strafeguide_height = CVAR_CREATE("hud_strafeguide_height", "0", FCVAR_ARCHIVE); + hud_strafeguide_size = CVAR_CREATE("hud_strafeguide_size", "0", FCVAR_ARCHIVE); + + gHUD.AddHudElem(this); + return 0; +} + +int CHudStrafeGuide::VidInit() +{ + return 1; +} + +int CHudStrafeGuide::Draw(float time) +{ + if (hud_strafeguide->value == 0) + return 0; + + double fov = gHUD.default_fov->value / 180 * M_PI / 2; + double zoom = hud_strafeguide_zoom->value; + + int size = gHUD.m_iFontHeight; + int height = ScreenHeight / 2 - 2*size; + + if (hud_strafeguide_size->value != 0) + size = hud_strafeguide_size->value; + + if (hud_strafeguide_height->value != 0) + height = hud_strafeguide_height->value; + + for (int i = 0; i < 4; ++i) { + int r, g, b; + switch (i) { + case RED_GREEN: case WHITE_GREEN: + r = 0; g = 255; b = 0; break; + case GREEN_WHITE: + r = 255; g = 255; b = 255; break; + case GREEN_RED: + r = 255; g = 0; b = 0; break; + } + + double boxLeftBase = -angles[i]; + double boxRightBase = -angles[(i+1)%4]; + + if (std::abs(boxLeftBase - boxRightBase) < 1e-10) + continue; + if (boxLeftBase >= boxRightBase) + boxRightBase += 2 * M_PI; + if (std::abs(boxLeftBase - boxRightBase) < 1e-10) + continue; + + for (int iCopy = -8; iCopy <= 8; ++iCopy) { + double boxLeft = boxLeftBase + iCopy * 2 * M_PI; + double boxRight = boxRightBase + iCopy * 2 * M_PI; + boxLeft *= zoom; + boxRight *= zoom; + + if (std::abs(boxLeft) > fov && std::abs(boxRight) > fov && boxRight * boxLeft > 0) + continue; + + boxLeft = boxLeft > fov ? fov : boxLeft < -fov ? -fov : boxLeft; + boxRight = boxRight > fov ? fov : boxRight < -fov ? -fov : boxRight; + + boxLeft = std::tan(boxLeft ) / std::tan(fov); + boxRight = std::tan(boxRight) / std::tan(fov); + + int boxLeftI = boxLeft / 1 * ScreenWidth / 2; + int boxRightI = boxRight/ 1 * ScreenWidth / 2; + boxLeftI += ScreenWidth / 2; + boxRightI += ScreenWidth / 2; + + FillRGBA(boxLeftI, height, boxRightI-boxLeftI, size, r, g, b, 60); + } + } + + return 0; +} + +static double angleReduce(double a) +{ + double tmp = std::fmod(a, 2*M_PI); + if (tmp < 0) tmp += 2*M_PI; + if (tmp > M_PI) tmp -= 2*M_PI; + return tmp; +} + +void CHudStrafeGuide::Update(struct ref_params_s *pparams) +{ + double frameTime = pparams->frametime; + auto input = std::complex(pparams->cmd->forwardmove, pparams->cmd->sidemove); + double viewAngle = pparams->viewangles[1] / 180 * M_PI; + + if (std::norm(input) == 0) { + for (int i = 0; i < 4; ++i) { + if (i < 2) + angles[i] = M_PI; + else + angles[i] = -M_PI; + } + return; + } + + std::complex velocity = lastSimvel; + lastSimvel = std::complex(pparams->simvel[0], pparams->simvel[1]); + + bool onground = pparams->onground; + double accelCoeff = onground ? pparams->movevars->accelerate : pparams->movevars->airaccelerate; + //TODO: grab the entity friction from somewhere. pparams->movevars->friction is sv_friction + //just use the default 1 for now + double frictionCoeff = 1; + + double inputAbs = std::abs(input); + if (onground) + inputAbs = min(inputAbs, pparams->movevars->maxspeed); + else + inputAbs = min(inputAbs, 30); + + input *= inputAbs / std::abs(input); + + double uncappedAccel = accelCoeff * frictionCoeff * inputAbs * frameTime; + double velocityAbs = std::abs(velocity); + + if (uncappedAccel >= 2 * velocityAbs) + angles[RED_GREEN] = M_PI; + else + angles[RED_GREEN] = std::acos(-uncappedAccel / velocityAbs / 2); + + if (velocityAbs <= inputAbs) + angles[GREEN_WHITE] = 0; + else + angles[GREEN_WHITE] = std::acos(inputAbs / velocityAbs); + + angles[GREEN_RED] = -angles[RED_GREEN]; + angles[WHITE_GREEN] = -angles[GREEN_WHITE]; + + double inputAngle = std::log(input).imag(); + double velocityAngle; + + if (velocityAbs == 0) + velocityAngle = 0; + else + velocityAngle = std::log(velocity).imag(); + + for (int i = 0; i < 4; ++i) { + angles[i] += velocityAngle + inputAngle - viewAngle; + angles[i] = angleReduce(angles[i]); + } +} diff --git a/cl_dll/hud_strafeguide.h b/cl_dll/hud_strafeguide.h new file mode 100644 index 00000000..b0a4031e --- /dev/null +++ b/cl_dll/hud_strafeguide.h @@ -0,0 +1,21 @@ +#pragma once +#include + +class CHudStrafeGuide : public CHudBase +{ + double angles[6] = {0.}; + + std::complex lastSimvel = 0.; + + cvar_t* hud_strafeguide; + cvar_t* hud_strafeguide_zoom; + cvar_t* hud_strafeguide_height; + cvar_t* hud_strafeguide_size; + +public: + virtual int Init(); + virtual int VidInit(); + virtual int Draw(float time); + + void Update(struct ref_params_s *ppmove); +}; diff --git a/cl_dll/view.cpp b/cl_dll/view.cpp index 28d03463..4d410bc2 100644 --- a/cl_dll/view.cpp +++ b/cl_dll/view.cpp @@ -1699,6 +1699,7 @@ void CL_DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams ) // RecClCalcRefdef(pparams); gHUD.m_Speedometer.UpdateSpeed(pparams->simvel); + gHUD.m_StrafeGuide.Update(pparams); gHUD.m_Jumpspeed.UpdateSpeed(pparams->simvel); // intermission / finale rendering From c13970360b3f298763546cab55214d101113f4fa Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Fri, 18 Feb 2022 09:11:39 +0300 Subject: [PATCH 04/42] CI: Specify windows-2019 -latest image strikes again by updating and breaking the build. --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 07ed03f3..51687ff9 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -23,7 +23,7 @@ on: jobs: build-windows: - runs-on: windows-latest + runs-on: windows-2019 env: POWERSHELL_TELEMETRY_OPTOUT: 1 strategy: From 070cad983313aa74b20aeb4204b49a6c90fc925f Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Fri, 18 Feb 2022 02:17:17 +0400 Subject: [PATCH 05/42] Added r_drawentities 5 for hardware rendering --- cl_dll/StudioModelRenderer.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cl_dll/StudioModelRenderer.cpp b/cl_dll/StudioModelRenderer.cpp index 3de53831..79de89d2 100644 --- a/cl_dll/StudioModelRenderer.cpp +++ b/cl_dll/StudioModelRenderer.cpp @@ -2225,6 +2225,11 @@ void CStudioModelRenderer::StudioRenderFinal_Hardware( void ) gEngfuncs.pTriAPI->RenderMode( kRenderNormal ); } + if ( m_pCvarDrawEntities->value == 5 ) + { + IEngineStudio.StudioDrawAbsBBox( ); + } + IEngineStudio.RestoreRenderer(); } From 256588c1409f11abad738ba9476905e94aacc6f3 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Thu, 24 Feb 2022 09:58:17 +0300 Subject: [PATCH 06/42] CI: Remove intermediate compiler version tests Let's only test on the minimum and maximum supported version. This speeds up the CI and lowers the chance of spurious failure due to Microsoft server issues. --- .github/workflows/CI.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 51687ff9..e0e77a0d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -29,7 +29,7 @@ jobs: strategy: fail-fast: false matrix: - toolset: [v141_xp, v141, v142] + toolset: [v141_xp, v142] configuration: [Release, Debug] steps: - uses: actions/checkout@v2 @@ -52,7 +52,7 @@ jobs: strategy: fail-fast: false matrix: - gcc-ver: [6, 7, 8, 9, 10, 11] + gcc-ver: [6, 11] configuration: [Release, Debug] env: CC: gcc-${{ matrix.gcc-ver }} @@ -84,7 +84,7 @@ jobs: strategy: fail-fast: false matrix: - clang-ver: [3.9, '4.0', '5.0', '6.0', 7, 8, 9, 10, 11, 12] # #.0 is interpreted as integer without quotation marks + clang-ver: [3.9, 12] configuration: [Release, Debug] env: CC: clang-${{ matrix.clang-ver }} From ddb00321ab746b49f2311579e0a9c2a2b8209202 Mon Sep 17 00:00:00 2001 From: yhoiluhi <42908948+yhoiluhi@users.noreply.github.com> Date: Fri, 25 Feb 2022 16:58:55 +0300 Subject: [PATCH 07/42] Ducktap fix (#155) * ducktap fix * remove cl_duck_priority * some changes * remove unnecessary set --- cl_dll/input.cpp | 125 ++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 57 deletions(-) diff --git a/cl_dll/input.cpp b/cl_dll/input.cpp index 5f9b2ba2..3ab62579 100644 --- a/cl_dll/input.cpp +++ b/cl_dll/input.cpp @@ -67,63 +67,6 @@ cvar_t *cl_pitchspeed; cvar_t *cl_anglespeedkey; cvar_t *cl_vsmoothing; -namespace autofuncs -{ - static cvar_t* cl_autojump; - - static struct { - bool onground = false; - bool inwater = false; - bool walking = true; // Movetype == MOVETYPE_WALK. Filters out noclip, being on ladder, etc. - } player; - - static void handle_autojump(usercmd_t* cmd) - { - static bool s_jump_was_down_last_frame = false; - - if (cl_autojump->value != 0.0f) - { - bool should_release_jump = (!player.onground && !player.inwater && player.walking); - - /* - * Spam pressing and releasing jump if we're stuck in a spot where jumping still results in - * being onground in the end of the frame. Without this check, +jump would remain held and - * when the player exits this spot they would have to release and press the jump button to - * start jumping again. This also helps with exiting water or ladder right onto the ground. - */ - if (s_jump_was_down_last_frame && player.onground && !player.inwater && player.walking) - should_release_jump = true; - - if (should_release_jump) - cmd->buttons &= ~IN_JUMP; - } - - s_jump_was_down_last_frame = ((cmd->buttons & IN_JUMP) != 0); - } - - static void handle_ducktap(usercmd_t* cmd) - { - static bool s_duck_was_down_last_frame = false; - - bool should_release_duck = (!player.onground && !player.inwater && player.walking); - - if (s_duck_was_down_last_frame && player.onground && !player.inwater && player.walking) - should_release_duck = true; - - if (should_release_duck) - cmd->buttons &= ~IN_DUCK; - - s_duck_was_down_last_frame = ((cmd->buttons & IN_DUCK) != 0); - } -} - -extern "C" void update_player_info(int onground, int inwater, int walking) -{ - autofuncs::player.onground = (onground != 0); - autofuncs::player.inwater = (inwater != 0); - autofuncs::player.walking = (walking != 0); -} - /* =============================================================================== @@ -182,6 +125,74 @@ typedef struct kblist_s kblist_t *g_kbkeys = NULL; +namespace autofuncs +{ + static cvar_t* cl_autojump; + + static struct { + bool onground = false; + bool inwater = false; + bool walking = true; // Movetype == MOVETYPE_WALK. Filters out noclip, being on ladder, etc. + } player; + + static void handle_autojump(usercmd_t* cmd) + { + static bool s_jump_was_down_last_frame = false; + + if (cl_autojump->value != 0.0f) + { + bool should_release_jump = (!player.onground && !player.inwater && player.walking); + + /* + * Spam pressing and releasing jump if we're stuck in a spot where jumping still results in + * being onground in the end of the frame. Without this check, +jump would remain held and + * when the player exits this spot they would have to release and press the jump button to + * start jumping again. This also helps with exiting water or ladder right onto the ground. + */ + if (s_jump_was_down_last_frame && player.onground && !player.inwater && player.walking) + should_release_jump = true; + + if (should_release_jump) + cmd->buttons &= ~IN_JUMP; + } + + s_jump_was_down_last_frame = ((cmd->buttons & IN_JUMP) != 0); + } + + static void handle_ducktap(usercmd_t* cmd) + { + static bool s_duck_was_down_last_frame = false; + static bool should_release_duck; + + bool duck_is_pressed = false; + + if (in_duck.state & 1) + duck_is_pressed = true; + else + duck_is_pressed = false; + + should_release_duck = (!player.onground && !player.inwater && player.walking && !duck_is_pressed); + + if (s_duck_was_down_last_frame && player.onground && !player.inwater && player.walking) + should_release_duck = true; + + if (should_release_duck) + { + cmd->buttons &= ~IN_DUCK; + in_duck.state &= 0; + } + + s_duck_was_down_last_frame = ((cmd->buttons & IN_DUCK) != 0); + } +} + +extern "C" void update_player_info(int onground, int inwater, int walking) +{ + autofuncs::player.onground = (onground != 0); + autofuncs::player.inwater = (inwater != 0); + autofuncs::player.walking = (walking != 0); +} + /* ============ KB_ConvertString From d013b41ffdd2491344395ef415534bac6150735d Mon Sep 17 00:00:00 2001 From: Jakub Date: Sat, 12 Mar 2022 13:09:08 +0100 Subject: [PATCH 08/42] Added cl_team_sounds_volume (#158) * Added cl_ignore_playsound_messages * Change to volume --- cl_dll/hud.cpp | 3 ++- cl_dll/hud.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index d56eccb8..fcc1e833 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -196,7 +196,7 @@ int __MsgFunc_PlaySound(const char* name, int size, void* buf) origin[i] = READ_COORD(); const auto sound = READ_STRING(); - gEngfuncs.pfnPlaySoundByName(sound, 1); + gEngfuncs.pfnPlaySoundByName(sound, gHUD.m_pCvarPlayTeamSoundsVolume->value); return 1; } @@ -527,6 +527,7 @@ void CHud :: Init( void ) m_pCvarViewheightMode = CVAR_CREATE("cl_viewheight_mode", "0", FCVAR_ARCHIVE); m_pCvarHideCorpses = CVAR_CREATE("cl_hidecorpses", "0", FCVAR_ARCHIVE); m_pCvarColor = CVAR_CREATE( "hud_color", "", FCVAR_ARCHIVE ); + m_pCvarPlayTeamSoundsVolume = CVAR_CREATE("cl_team_sounds_volume", "1.0", FCVAR_ARCHIVE); cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); CVAR_CREATE("showtriggers", "0", 0); diff --git a/cl_dll/hud.h b/cl_dll/hud.h index 3173c95c..c830c2c5 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -597,6 +597,7 @@ class CHud cvar_t *m_pCvarAutostop; cvar_t *m_pCvarViewheightMode; cvar_t *m_pCvarHideCorpses; + cvar_t *m_pCvarPlayTeamSoundsVolume; int m_iFontHeight; From b997b80531eb285d0f857014d09a8506112a4733 Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Wed, 6 Apr 2022 00:02:49 +0400 Subject: [PATCH 09/42] Added cl_killsound & cl_killsound_path & hud_saytext_sound_path (#157) * Added cl_killsound & cl_killsound_path * Allow to regulate volume for killsound & saytext, added hud_saytext_sound_path * Change conditions * Allow killsound to be played if player was spectating (tysm soup) --- cl_dll/death.cpp | 16 ++++++++++++++++ cl_dll/hud.h | 1 + cl_dll/saytext.cpp | 5 +++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cl_dll/death.cpp b/cl_dll/death.cpp index 8c3772b0..b9051f5a 100644 --- a/cl_dll/death.cpp +++ b/cl_dll/death.cpp @@ -51,6 +51,9 @@ float g_ColorGreen[3] = { 0.6, 1.0, 0.6 }; float g_ColorYellow[3] = { 1.0, 0.7, 0.0 }; float g_ColorGrey[3] = { 0.8, 0.8, 0.8 }; +cvar_t *m_pCvarKillSnd; +cvar_t *m_pCvarKillSndPath; + float *GetClientColor( int clientIndex ) { switch ( g_PlayerExtraInfo[clientIndex].teamnumber ) @@ -75,6 +78,9 @@ int CHudDeathNotice :: Init( void ) CVAR_CREATE( "hud_deathnotice_time", "6", FCVAR_ARCHIVE ); + m_pCvarKillSnd = CVAR_CREATE( "cl_killsound", "0", FCVAR_ARCHIVE ); + m_pCvarKillSndPath = CVAR_CREATE( "cl_killsound_path", "buttons/bell1.wav", FCVAR_ARCHIVE ); + return 1; } @@ -262,6 +268,16 @@ int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *p DEATHNOTICE_DISPLAY_TIME = CVAR_GET_FLOAT( "hud_deathnotice_time" ); rgDeathNoticeList[i].flDisplayTime = gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME; + // Play kill sound + if ((g_PlayerInfoList[killer].thisplayer || g_iUser2 == killer) && + !rgDeathNoticeList[i].iNonPlayerKill && + !rgDeathNoticeList[i].iSuicide && + m_pCvarKillSnd->value > 0.0f) + { + PlaySound(m_pCvarKillSndPath->string, m_pCvarKillSnd->value); + } + + // Print to console if (rgDeathNoticeList[i].iNonPlayerKill) { ConsolePrint( rgDeathNoticeList[i].szKiller ); diff --git a/cl_dll/hud.h b/cl_dll/hud.h index c830c2c5..9e44cce4 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -340,6 +340,7 @@ friend class CHudSpectator; struct cvar_s * m_HUD_saytext; struct cvar_s * m_HUD_saytext_time; struct cvar_s * m_HUD_saytext_sound; + struct cvar_s * m_HUD_saytext_sound_path; }; // diff --git a/cl_dll/saytext.cpp b/cl_dll/saytext.cpp index 1274b5fd..b7a535a2 100644 --- a/cl_dll/saytext.cpp +++ b/cl_dll/saytext.cpp @@ -60,6 +60,7 @@ int CHudSayText :: Init( void ) m_HUD_saytext = gEngfuncs.pfnRegisterVariable( "hud_saytext", "1", 0 ); m_HUD_saytext_time = gEngfuncs.pfnRegisterVariable( "hud_saytext_time", "5", FCVAR_ARCHIVE ); m_HUD_saytext_sound = gEngfuncs.pfnRegisterVariable( "hud_saytext_sound", "0", FCVAR_ARCHIVE ); + m_HUD_saytext_sound_path = gEngfuncs.pfnRegisterVariable( "hud_saytext_sound_path", "misc/talk.wav", FCVAR_ARCHIVE ); m_iFlags |= HUD_INTERMISSION; // is always drawn during an intermission @@ -279,8 +280,8 @@ void CHudSayText :: SayTextPrint( const char *pszBuf, int iBufSize, int clientIn m_iFlags |= HUD_ACTIVE; - if (m_HUD_saytext_sound->value != 0.0f) - PlaySound( "misc/talk.wav", 1 ); + if (m_HUD_saytext_sound->value > 0.0f) + PlaySound(m_HUD_saytext_sound_path->string, m_HUD_saytext_sound->value); Y_START = ScreenHeight - 60 - ( line_height * (MAX_LINES+2) ); } From eb4d4719a0c4451a3722048a71d6535d667bf45b Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Wed, 6 Apr 2022 02:21:32 +0400 Subject: [PATCH 10/42] discord: hardcode hl1_bhop maps without a beta prefix for thumbnails --- cl_dll/discord_integration.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/cl_dll/discord_integration.cpp b/cl_dll/discord_integration.cpp index 349d1bdc..b09ac8df 100644 --- a/cl_dll/discord_integration.cpp +++ b/cl_dll/discord_integration.cpp @@ -103,12 +103,19 @@ namespace discord_integration "gasworks"s, "gayl0rd_bhop"s, "havoc"s, - "hl1_bhop_am_beta3"s, - "hl1_bhop_bp1_beta"s, - "hl1_bhop_bp2_beta2"s, - "hl1_bhop_ocwgh_beta"s, - "hl1_bhop_uc1_beta2"s, - "hl1_bhop_uc2_beta2"s, + "hl1_bhop_am"s, + "hl1_bhop_bp1"s, + "hl1_bhop_bp2"s, + "hl1_bhop_faf"s, + "hl1_bhop_lc"s, + "hl1_bhop_oar"s, + "hl1_bhop_ocwgh"s, + "hl1_bhop_pu"s, + "hl1_bhop_qe"s, + "hl1_bhop_rp"s, + "hl1_bhop_st"s, + "hl1_bhop_uc1"s, + "hl1_bhop_uc2"s, "hl_trick"s, "hm_castlebhop"s, "hm_speedwinterz"s, From d15e427a4ead5491d4c563ff47b7e7b27f0c5a5f Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Wed, 6 Apr 2022 02:22:18 +0400 Subject: [PATCH 11/42] discord: hardcode e1m1 too D --- cl_dll/discord_integration.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cl_dll/discord_integration.cpp b/cl_dll/discord_integration.cpp index b09ac8df..513271e4 100644 --- a/cl_dll/discord_integration.cpp +++ b/cl_dll/discord_integration.cpp @@ -93,6 +93,7 @@ namespace discord_integration "dyd_axn_plant"s, "dyd_axn_sky"s, "dyd_cosy_cupbhop_ez"s, + "e1m1"s, "eden"s, "elixir"s, "endcamp"s, From 44fcb20efd4fff7119a7ed2c7eb7c63db3985eff Mon Sep 17 00:00:00 2001 From: Margen67 Date: Sat, 16 Oct 2021 04:02:48 -1000 Subject: [PATCH 12/42] CI improvements Ignore more files. Upgrade from v142 to v143. Only build Release. Upgrade checkout and upload-artifact to v3. Upgrade to Clang 14. --- .github/workflows/CI.yml | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e0e77a0d..920fd663 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -3,16 +3,20 @@ name: CI on: push: paths-ignore: + - '.gitattributes' - '.github/*' - '.github/*_TEMPLATE/**' + - '.gitignore' - '*.bat' - '*.yml' - '*.md' - 'LICENSE*' pull_request: paths-ignore: + - '.gitattributes' - '.github/*' - '.github/*_TEMPLATE/**' + - '.gitignore' - '*.bat' - '*.yml' - '*.md' @@ -23,31 +27,34 @@ on: jobs: build-windows: - runs-on: windows-2019 + name: Build (Windows, ${{ matrix.config.toolset }}, ${{ matrix.configuration }}) + runs-on: ${{ matrix.config.runs-on }} env: POWERSHELL_TELEMETRY_OPTOUT: 1 strategy: fail-fast: false matrix: - toolset: [v141_xp, v142] + config: + - {runs-on: windows-2019, toolset: v141_xp} + - {runs-on: windows-2022, toolset: v143} configuration: [Release, Debug] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: recursive - name: CMake generate - run: cmake -T ${{ matrix.toolset }} -A Win32 -B build + run: cmake -T ${{ matrix.config.toolset }} -A Win32 -B build - name: Build run: cmake --build build -j $env:NUMBER_OF_PROCESSORS --config ${{ matrix.configuration }} - - uses: actions/upload-artifact@v2 - if: matrix.toolset == 'v141_xp' + - uses: actions/upload-artifact@v3 + if: matrix.config.toolset == 'v141_xp' with: name: openag-${{ runner.os }}-${{ matrix.configuration }} path: build\${{ matrix.configuration }}\client.dll if-no-files-found: error build-linux-gcc: - name: build-linux (gcc-${{ matrix.gcc-ver }}, ${{ matrix.configuration }}) + name: Build (Linux, gcc-${{ matrix.gcc-ver }}, ${{ matrix.configuration }}) runs-on: ubuntu-18.04 strategy: fail-fast: false @@ -58,7 +65,7 @@ jobs: CC: gcc-${{ matrix.gcc-ver }} CXX: g++-${{ matrix.gcc-ver }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: recursive - name: Setup @@ -71,7 +78,7 @@ jobs: - name: Build working-directory: build run: ninja - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 if: matrix.gcc-ver == '11' with: name: openag-${{ runner.os }}-${{ matrix.configuration }} @@ -79,26 +86,25 @@ jobs: if-no-files-found: error build-linux-clang: - name: build-linux (clang-${{ matrix.clang-ver }}, ${{ matrix.configuration }}) + name: Build (Linux, clang-${{ matrix.clang-ver }}, ${{ matrix.configuration }}) runs-on: ubuntu-18.04 strategy: fail-fast: false matrix: - clang-ver: [3.9, 12] + clang-ver: [3.9, 14] configuration: [Release, Debug] env: CC: clang-${{ matrix.clang-ver }} CXX: clang++-${{ matrix.clang-ver }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: recursive - name: Setup run: | - if [ '${{ matrix.clang-ver }}' -ge '11' ]; then + if [ ${{ matrix.clang-ver }} -eq 14 ]; then wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo add-apt-repository 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-11 main' - sudo add-apt-repository 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-12 main' + sudo add-apt-repository 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-${{ matrix.clang-ver }} main' fi sudo apt-get update sudo apt-get install -y clang-${{ matrix.clang-ver }} g++-multilib libgl-dev ninja-build rapidjson-dev From e560896f73fc1c4ccf08a69d947b001c0a13e447 Mon Sep 17 00:00:00 2001 From: Margen67 Date: Wed, 6 Apr 2022 16:06:15 -0700 Subject: [PATCH 13/42] Remove Travis --- .travis.yml | 23 ----------------------- README.md | 1 - 2 files changed, 24 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 7ab2c91d..00000000 --- a/.travis.yml +++ /dev/null @@ -1,23 +0,0 @@ -language: cpp -os: osx - -env: - - CONFIGURATION=Debug - - CONFIGURATION=Release - -script: - - mkdir build - - cd build - - cmake -DCMAKE_BUILD_TYPE="${CONFIGURATION}" .. - - make - -deploy: - provider: releases - file: client.dylib - skip_cleanup: true - draft: true - on: - tags: true - condition: $CONFIGURATION = Release - api_key: - secure: "SGx2fPSxBr95VJbLW/oFOS5NaW+ZFjamP4r2lAuJMGeTPt9MxSP/QGxtTRXu9qfVAjb2Lxum8tY2+g4GvSwkhNEAbt2lcsALk2tGQsPe1BCSUtaS5VyuvuryvYn6KgcfACTz6Hx2i7wrPpzF2kRr7VTOHmBxb16Iwe74QKbAQfKXusoolHfIqZ8rSO0J7QAQr+FV7oJ0W/z1mZtvL1Amum6kLBjdNMJCu3+svryhmc4Zy7Brtm+hdabbuArCtneE7sgcsAt4fWmmVX7MUZABSi4kpqyHBsMNoVmkk3ZxbHQj54Z3vN8Gqf6khcS6KnNuEL3qrMfc8XNAbg65IrvpE7oJKKubSMGiFsDPaNIMdlX8yHxhQ7MlV/fdjPCO9E1fYCdt3vr5piDWIZIsOu50NCyXWd4LqXkOX24PZ6gdAa6sE8AVP8VXuYuh+pL/TQcdoa61Qh/c2Q1a7wG+1HWNxCubdWNz55xeRmUQwfPfOalt4gFpFypYrAAlYOvJrE7ba+nEjLwrea6MXhmw78NJEOtTXFuiLkj+PSEP9f61GwBXWBkT8K4SEoGmaThylzwe30WNhvAiSD91LpmZn7i+r9SYvs+Fa8u3VQlVx00GE8N8aaULz4pcMUF2fmS8M5A2vqLFqt+UrC5jLy0ptnHNC1evkrgIRER48hC8m7TUQHs=" diff --git a/README.md b/README.md index 12ad8574..5a9f502d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ OpenAG ====================== [![Build Status](https://github.com/YaLTeR/OpenAG/workflows/CI/badge.svg?branch=master)](https://github.com/YaLTeR/OpenAG/actions?query=branch:master) -[![Build Status](https://travis-ci.org/YaLTeR/OpenAG.svg?branch=master)](https://travis-ci.org/YaLTeR/OpenAG) [![Chat on Discord](https://discordapp.com/api/guilds/252168904359542784/widget.png)](https://discord.gg/jCYhYNH) OpenAG is an open-source client of the Half-Life promod Adrenaline Gamer, completely rewritten from scratch on latest Half-Life SDK. It adds new features, bugfixes and other tweaks over the original mod, while maintaining the ability to play on all currently existing servers. From 679f146ff7a9f15d574b4e37ce3f5622f635faee Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Thu, 14 Apr 2022 18:48:34 +0400 Subject: [PATCH 14/42] RPC: Always convert current map name to lowercase for thumbnails (#164) * RPC: Always convert current map name to lowercase for thumbnails * RPC: Replaced bhop_MoLwiz with bhop_molwiz That was a single map from list with uppercase name before lmao * RPC: Change directly map_name to lowercase instead of copying to temp --- cl_dll/discord_integration.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cl_dll/discord_integration.cpp b/cl_dll/discord_integration.cpp index 513271e4..30614821 100644 --- a/cl_dll/discord_integration.cpp +++ b/cl_dll/discord_integration.cpp @@ -40,7 +40,6 @@ namespace discord_integration "bh_axn_tunnel"s, "bhm_assault"s, "bhm_ramp"s, - "bhop_MoLwiz"s, "bhop_aeonflux"s, "bhop_avantura"s, "bhop_axn_project64"s, @@ -58,6 +57,7 @@ namespace discord_integration "bhop_maratona"s, "bhop_medieval"s, "bhop_minecraft_v1"s, + "bhop_molwiz"s, "bhop_platinum"s, "bhop_pool_day"s, "bhop_river_wb"s, @@ -343,6 +343,13 @@ namespace discord_integration get_map_name(map_name, ARRAYSIZE(map_name)); if (map_name[0]) { + // adjust to lowercase + unsigned char *tptr = (unsigned char *)map_name; + while (*tptr) { + *tptr = tolower(*tptr); + tptr++; + } + if (maps_with_thumbnails.find(map_name) != maps_with_thumbnails.cend()) presence.largeImageKey = map_name; From 173ebd450d2d0ac56daaad7e414d512528642901 Mon Sep 17 00:00:00 2001 From: UnkwUsr Date: Sun, 20 Mar 2022 18:59:58 +0300 Subject: [PATCH 15/42] StudioModelRenderer: Move new methods to end of virtual table To make openag more binary compatible with original hl1 client --- cl_dll/StudioModelRenderer.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cl_dll/StudioModelRenderer.h b/cl_dll/StudioModelRenderer.h index 313ef97a..af3f4b24 100644 --- a/cl_dll/StudioModelRenderer.h +++ b/cl_dll/StudioModelRenderer.h @@ -32,9 +32,6 @@ class CStudioModelRenderer virtual int StudioDrawModel ( int flags ); virtual int StudioDrawPlayer ( int flags, struct entity_state_s *pplayer ); -private: - virtual model_t* GetPlayerModel(int player_index); - public: // Local interfaces // @@ -50,12 +47,6 @@ class CStudioModelRenderer // Find final attachment points virtual void StudioCalcAttachments ( void ); - - // Returns whether StudioAdjustViewmodelAttachments needs to be called for the viewmodel - virtual bool NeedAdjustViewmodelAdjustments(); - - // Reprojects attachments of the viewmodel if FOV is changed - virtual void StudioAdjustViewmodelAttachments(Vector &vOrigin); // Save bone matrices and names virtual void StudioSaveBones( void ); @@ -110,6 +101,15 @@ class CStudioModelRenderer // Calculate the viewmodel fov and set the OpenGL projection matrix virtual void SetViewmodelFovProjection ( void ); + // Returns whether StudioAdjustViewmodelAttachments needs to be called for the viewmodel + virtual bool NeedAdjustViewmodelAdjustments(); + + // Reprojects attachments of the viewmodel if FOV is changed + virtual void StudioAdjustViewmodelAttachments(Vector &vOrigin); + +private: + virtual model_t* GetPlayerModel(int player_index); + public: // Client clock From 75bff14bf01806924fb9a95447d385b2d24689e5 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 22 May 2022 11:56:32 +0300 Subject: [PATCH 16/42] flatpak: Update runtime version --- build-aux/flatpak/pro.openag.OpenAG.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-aux/flatpak/pro.openag.OpenAG.json b/build-aux/flatpak/pro.openag.OpenAG.json index 09a30105..0190f457 100644 --- a/build-aux/flatpak/pro.openag.OpenAG.json +++ b/build-aux/flatpak/pro.openag.OpenAG.json @@ -1,7 +1,7 @@ { "app-id": "pro.openag.OpenAG", "runtime": "org.freedesktop.Sdk", - "runtime-version": "19.08", + "runtime-version": "21.08", "command": "", "sdk": "org.freedesktop.Sdk", "sdk-extensions": [ From 502f5d2d47d8bc5aefce8e7d2c5d6e8842e8f54f Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 22 May 2022 11:56:43 +0300 Subject: [PATCH 17/42] flatpak: Set empty finish-args It was needed for something, I guess fenv. --- build-aux/flatpak/pro.openag.OpenAG.json | 1 + 1 file changed, 1 insertion(+) diff --git a/build-aux/flatpak/pro.openag.OpenAG.json b/build-aux/flatpak/pro.openag.OpenAG.json index 0190f457..fa6e3043 100644 --- a/build-aux/flatpak/pro.openag.OpenAG.json +++ b/build-aux/flatpak/pro.openag.OpenAG.json @@ -8,6 +8,7 @@ "org.freedesktop.Sdk.Compat.i386", "org.freedesktop.Sdk.Extension.toolchain-i386" ], + "finish-args": [], "build-options": { "append-path": "/usr/lib/sdk/toolchain-i386/bin", "env": { From 2252a445bc95f3eca88863ee708ef3c63edf7871 Mon Sep 17 00:00:00 2001 From: tmp64 Date: Tue, 16 Aug 2022 19:09:39 +0700 Subject: [PATCH 18/42] SayText: Add cvar to disable rainbow color Resolves #169 --- cl_dll/hud.h | 1 + cl_dll/rainbow.cpp | 21 +++++++++++++++++++++ cl_dll/rainbow.h | 5 +++++ cl_dll/saytext.cpp | 8 ++++++++ 4 files changed, 35 insertions(+) diff --git a/cl_dll/hud.h b/cl_dll/hud.h index 9e44cce4..f20c229e 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -341,6 +341,7 @@ friend class CHudSpectator; struct cvar_s * m_HUD_saytext_time; struct cvar_s * m_HUD_saytext_sound; struct cvar_s * m_HUD_saytext_sound_path; + struct cvar_s * m_HUD_rainbow_chat; }; // diff --git a/cl_dll/rainbow.cpp b/cl_dll/rainbow.cpp index 3cd8b784..50968e82 100644 --- a/cl_dll/rainbow.cpp +++ b/cl_dll/rainbow.cpp @@ -46,6 +46,9 @@ void CRainbow::Think() void CRainbow::GetRainbowColor(int x, int y, int &r, int &g, int &b) { + if (m_iDisableStack > 0) + return; + float phase = m_pCvarRainbowSpeed->value * gHUD.m_flTime; phase += m_pCvarRainbowXPhase->value * x; phase += m_pCvarRainbowYPhase->value * y; @@ -56,6 +59,17 @@ void CRainbow::GetRainbowColor(int x, int y, int &r, int &g, int &b) HSVtoRGB(phase, m_flSat, m_flVal, r, g, b); } +void CRainbow::PushDisable() +{ + m_iDisableStack++; +} + +void CRainbow::PopDisable() +{ + m_iDisableStack--; + assert(m_iDisableStack >= 0); +} + void CRainbow::HookFuncs() { gEngfuncs.pfnSPR_Set = &SPR_SetRainbow; @@ -120,6 +134,13 @@ int CRainbow::DrawStringReverse(int x, int y, const char *str, int r, int g, int int CRainbow::DrawConsoleString(int x, int y, const char *string) { + if (gHUD.m_Rainbow.m_iDisableStack > 0) + { + // pfnDrawConsoleString has weird color handling with con_color cvar + // Check in GetRainbowColor breaks text color + return gHUD.m_Rainbow.m_pfnDrawConsoleString(x, y, string); + } + return x + DrawRainbowString(x, y, string, [](int x, int y, const char *str, int r, int g, int b) { gEngfuncs.pfnDrawSetTextColor(r * 255.f, g * 255.f, b * 255.f); return gHUD.m_Rainbow.m_pfnDrawConsoleString(x, y, str) - x; diff --git a/cl_dll/rainbow.h b/cl_dll/rainbow.h index 57d46ab3..12d43bf2 100644 --- a/cl_dll/rainbow.h +++ b/cl_dll/rainbow.h @@ -22,6 +22,10 @@ class CRainbow */ void GetRainbowColor(int x, int y, int &r, int &g, int &b); + //! Disables rainbow color until PopDisable() is called. + void PushDisable(); + void PopDisable(); + private: /** * Function that draws an input string at input position with input color. @@ -30,6 +34,7 @@ class CRainbow using DrawStringFn = std::function; bool m_bIsEnabled = false; + int m_iDisableStack = 0; float m_flSat = 100; float m_flVal = 100; cvar_t *m_pCvarRainbow = nullptr; diff --git a/cl_dll/saytext.cpp b/cl_dll/saytext.cpp index b7a535a2..fdc57f8b 100644 --- a/cl_dll/saytext.cpp +++ b/cl_dll/saytext.cpp @@ -61,6 +61,7 @@ int CHudSayText :: Init( void ) m_HUD_saytext_time = gEngfuncs.pfnRegisterVariable( "hud_saytext_time", "5", FCVAR_ARCHIVE ); m_HUD_saytext_sound = gEngfuncs.pfnRegisterVariable( "hud_saytext_sound", "0", FCVAR_ARCHIVE ); m_HUD_saytext_sound_path = gEngfuncs.pfnRegisterVariable( "hud_saytext_sound_path", "misc/talk.wav", FCVAR_ARCHIVE ); + m_HUD_rainbow_chat = gEngfuncs.pfnRegisterVariable( "hud_rainbow_chat", "1", FCVAR_ARCHIVE ); m_iFlags |= HUD_INTERMISSION; // is always drawn during an intermission @@ -105,6 +106,10 @@ int CHudSayText :: Draw( float flTime ) if ( ( gViewPort && gViewPort->AllowedToPrintText() == FALSE) || !m_HUD_saytext->value ) return 1; + bool enableRainbow = m_HUD_rainbow_chat->value; + if (!enableRainbow) + gHUD.m_Rainbow.PushDisable(); + // make sure the scrolltime is within reasonable bounds, to guard against the clock being reset flScrollTime = min( flScrollTime, flTime + m_HUD_saytext_time->value ); @@ -159,6 +164,9 @@ int CHudSayText :: Draw( float flTime ) y += line_height; } + if (!enableRainbow) + gHUD.m_Rainbow.PopDisable(); + return 1; } From b1d3f5583bbdc00af6d08c9d17b6a554c6921426 Mon Sep 17 00:00:00 2001 From: Jakub Mach Date: Wed, 12 Oct 2022 22:07:30 +0200 Subject: [PATCH 19/42] Added cl_hide_other_players --- cl_dll/entity.cpp | 4 ++++ cl_dll/hud.cpp | 1 + cl_dll/hud.h | 1 + 3 files changed, 6 insertions(+) diff --git a/cl_dll/entity.cpp b/cl_dll/entity.cpp index f578643f..d6142d23 100644 --- a/cl_dll/entity.cpp +++ b/cl_dll/entity.cpp @@ -14,6 +14,7 @@ #include "pm_shared.h" #include "bench.h" #include "Exports.h" +#include "demo_api.h" #include "discord_integration.h" @@ -63,6 +64,9 @@ int CL_DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *m // each frame every entity passes this function, so the overview hooks // it to filter the overview entities + if (gHUD.m_pCvarHideOtherPlayers->value > 0 && ent->player && gEngfuncs.pDemoAPI->IsPlayingback() && ent->index != g_iUser2) + return 0; + if ( g_iUser1 ) { gHUD.m_Spectator.AddOverviewEntity( type, ent, modelname ); diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index fcc1e833..d8d9486b 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -526,6 +526,7 @@ void CHud :: Init( void ) m_pCvarAutostop = CVAR_CREATE("cl_autostop", "0", FCVAR_ARCHIVE); m_pCvarViewheightMode = CVAR_CREATE("cl_viewheight_mode", "0", FCVAR_ARCHIVE); m_pCvarHideCorpses = CVAR_CREATE("cl_hidecorpses", "0", FCVAR_ARCHIVE); + m_pCvarHideOtherPlayers = CVAR_CREATE("cl_hide_other_players", "0", 0); m_pCvarColor = CVAR_CREATE( "hud_color", "", FCVAR_ARCHIVE ); m_pCvarPlayTeamSoundsVolume = CVAR_CREATE("cl_team_sounds_volume", "1.0", FCVAR_ARCHIVE); cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); diff --git a/cl_dll/hud.h b/cl_dll/hud.h index f20c229e..bebc755d 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -599,6 +599,7 @@ class CHud cvar_t *m_pCvarAutostop; cvar_t *m_pCvarViewheightMode; cvar_t *m_pCvarHideCorpses; + cvar_t *m_pCvarHideOtherPlayers; cvar_t *m_pCvarPlayTeamSoundsVolume; int m_iFontHeight; From 3286fe3aae7cb3a428684c67de4068986eca694d Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Mon, 3 Oct 2022 22:36:11 +0400 Subject: [PATCH 20/42] CustomTimer: Use float time instead of decimal --- cl_dll/hud_customtimer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cl_dll/hud_customtimer.cpp b/cl_dll/hud_customtimer.cpp index 2acb63a5..d34b22a7 100644 --- a/cl_dll/hud_customtimer.cpp +++ b/cl_dll/hud_customtimer.cpp @@ -34,7 +34,7 @@ int CHudCustomTimer::Draw(float time) UnpackRGB(r, g, b, gHUD.m_iDefaultHUDColor); FillRGBA((ScreenWidth / 2) - 50, (gHUD.m_scrinfo.iCharHeight * 4) - 6, (diff / m_flSeconds) * 100, 4, r, g, b, 210); - snprintf(str, sizeof(str), "Timer: %d", (int)diff); + snprintf(str, sizeof(str), "Timer: %.1f", diff); gHUD.DrawHudStringCentered(ScreenWidth / 2, gHUD.m_scrinfo.iCharHeight * 4, str, r, g, b); return 0; From 8eb1d98baf57772f86e7e73f7b126b88236f5ba3 Mon Sep 17 00:00:00 2001 From: fireblizzard <16053926+fireblizzard@users.noreply.github.com> Date: Sat, 24 Dec 2022 14:08:40 +0100 Subject: [PATCH 21/42] Make name/team change and game leave messages ignorable --- cl_dll/text_message.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cl_dll/text_message.cpp b/cl_dll/text_message.cpp index 59f6cbd9..8ecd924e 100644 --- a/cl_dll/text_message.cpp +++ b/cl_dll/text_message.cpp @@ -38,6 +38,9 @@ int CHudTextMessage::Init(void) ignored_message_types.push_back(CVAR_CREATE("cl_ignore_spawn_messages", "0", FCVAR_ARCHIVE)); ignored_message_types.push_back(CVAR_CREATE("cl_ignore_damage_messages", "0", FCVAR_ARCHIVE)); + ignored_message_types.push_back(CVAR_CREATE("cl_ignore_name_change_messages", "0", FCVAR_ARCHIVE)); + ignored_message_types.push_back(CVAR_CREATE("cl_ignore_team_change_messages", "0", FCVAR_ARCHIVE)); + ignored_message_types.push_back(CVAR_CREATE("cl_ignore_game_leave_messages", "0", FCVAR_ARCHIVE)); m_pCvarHideCenterMessages = CVAR_CREATE( "cl_hide_center_messages", "0", FCVAR_ARCHIVE ); From 76b33bfaa1a87c3f5a4bd4ea9e9a3c898e80a2e9 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Tue, 2 May 2023 07:18:00 +0300 Subject: [PATCH 22/42] CI: Update to ubuntu-20.04 I guess 18.04 is no longer a thing. --- .github/workflows/CI.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 920fd663..fbc0e61f 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -55,11 +55,11 @@ jobs: build-linux-gcc: name: Build (Linux, gcc-${{ matrix.gcc-ver }}, ${{ matrix.configuration }}) - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: - gcc-ver: [6, 11] + gcc-ver: [9, 11] configuration: [Release, Debug] env: CC: gcc-${{ matrix.gcc-ver }} @@ -87,11 +87,11 @@ jobs: build-linux-clang: name: Build (Linux, clang-${{ matrix.clang-ver }}, ${{ matrix.configuration }}) - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 strategy: fail-fast: false matrix: - clang-ver: [3.9, 14] + clang-ver: [6.0, 16] configuration: [Release, Debug] env: CC: clang-${{ matrix.clang-ver }} @@ -104,7 +104,7 @@ jobs: run: | if [ ${{ matrix.clang-ver }} -eq 14 ]; then wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo add-apt-repository 'deb https://apt.llvm.org/bionic/ llvm-toolchain-bionic-${{ matrix.clang-ver }} main' + sudo add-apt-repository 'deb https://apt.llvm.org/focal/ llvm-toolchain-focal-${{ matrix.clang-ver }} main' fi sudo apt-get update sudo apt-get install -y clang-${{ matrix.clang-ver }} g++-multilib libgl-dev ninja-build rapidjson-dev From 78fac3a9d0d8c033166f13d099d50ca1410e89e4 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Tue, 2 May 2023 07:20:02 +0300 Subject: [PATCH 23/42] CI: Fix mistakes --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index fbc0e61f..1dbd3bb0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -91,7 +91,7 @@ jobs: strategy: fail-fast: false matrix: - clang-ver: [6.0, 16] + clang-ver: ['6.0', 16] configuration: [Release, Debug] env: CC: clang-${{ matrix.clang-ver }} @@ -102,7 +102,7 @@ jobs: submodules: recursive - name: Setup run: | - if [ ${{ matrix.clang-ver }} -eq 14 ]; then + if [ ${{ matrix.clang-ver }} -eq 16 ]; then wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - sudo add-apt-repository 'deb https://apt.llvm.org/focal/ llvm-toolchain-focal-${{ matrix.clang-ver }} main' fi From 27e7143daee4823b12cda4bcd1f1e8d1fbdaa4d6 Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Sat, 10 Dec 2022 00:47:23 +0400 Subject: [PATCH 24/42] Make hud_saytext draw even when hud_draw is 0 --- cl_dll/hud_redraw.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index 1cf37883..8170f911 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -208,6 +208,9 @@ int CHud :: Redraw( float flTime, int intermission ) if (m_Jumpspeed.m_iFlags & HUD_ACTIVE) m_Jumpspeed.Draw(flTime); + if (m_SayText.m_iFlags & HUD_ACTIVE) + m_SayText.Draw(flTime); + if (gHUD.m_pCvarDrawDeathNoticesAlways->value != 0.0f && m_DeathNotice.m_iFlags & HUD_ACTIVE) m_DeathNotice.Draw(flTime); From 28878c23d1638ef2b469c71d156d18d166abdd46 Mon Sep 17 00:00:00 2001 From: Roman Chistokhodov Date: Wed, 20 Dec 2023 02:16:40 +0300 Subject: [PATCH 25/42] Make sure the client is linked to libSDL2 --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bde5790..1bd33cd7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,6 +203,7 @@ elseif(UNIX) # I wasn't able to do this in any other way. # Things like imported targets result in linking with relative path. set(VGUI_LINK_FLAGS "-L${CMAKE_SOURCE_DIR}/linux/release -l:vgui.so") + set(SDL2_LINK_FLAGS "-L${CMAKE_SOURCE_DIR}/linux -lSDL2") # --push-state isn't supported on older compilers. I tried checking for support # using CheckCXXCompilerFlag and CheckCXXSourceCompiles, but they were reporting @@ -210,7 +211,7 @@ elseif(UNIX) # --no-as-needed for all compilers. set(VGUI_LINK_FLAGS "-Wl,--no-as-needed ${VGUI_LINK_FLAGS}") - set_property(TARGET client PROPERTY LINK_FLAGS ${VGUI_LINK_FLAGS}) + set_property(TARGET client PROPERTY LINK_FLAGS "${VGUI_LINK_FLAGS} ${SDL2_LINK_FLAGS}") endif(APPLE) endif(WIN32) From f57684cc0c596b5b8dfbaf10da59324c5bfc0831 Mon Sep 17 00:00:00 2001 From: SmileyAG Date: Sat, 10 Dec 2022 00:58:03 +0400 Subject: [PATCH 26/42] Removed DMC and Ricochet files --- dmc/cl_dll/CTF_FlagStatus.cpp | 246 - dmc/cl_dll/CTF_HudMessage.cpp | 184 - dmc/cl_dll/DMC_BSPFile.h | 48 - dmc/cl_dll/DMC_Teleporters.cpp | 520 -- dmc/cl_dll/DMC_Teleporters.h | 16 - dmc/cl_dll/Exports.h | 117 - dmc/cl_dll/GameStudioModelRenderer.cpp | 119 - dmc/cl_dll/GameStudioModelRenderer.h | 26 - dmc/cl_dll/MOTD.cpp | 155 - dmc/cl_dll/StudioModelRenderer.cpp | 1723 ------ dmc/cl_dll/StudioModelRenderer.h | 189 - dmc/cl_dll/ammo.cpp | 1131 ---- dmc/cl_dll/ammo.h | 62 - dmc/cl_dll/ammo_secondary.cpp | 159 - dmc/cl_dll/ammohistory.cpp | 190 - dmc/cl_dll/ammohistory.h | 144 - dmc/cl_dll/battery.cpp | 135 - dmc/cl_dll/camera.h | 24 - dmc/cl_dll/cdll_int.cpp | 344 -- dmc/cl_dll/cl_dll.dsp | 598 -- dmc/cl_dll/cl_dll.h | 43 - dmc/cl_dll/cl_util.h | 199 - dmc/cl_dll/com_model.h | 359 -- dmc/cl_dll/com_weapons.cpp | 278 - dmc/cl_dll/com_weapons.h | 48 - dmc/cl_dll/death.cpp | 293 - dmc/cl_dll/demo.cpp | 61 - dmc/cl_dll/demo.h | 20 - dmc/cl_dll/entity.cpp | 860 --- dmc/cl_dll/ev_common.cpp | 198 - dmc/cl_dll/ev_hldm.cpp | 1544 ------ dmc/cl_dll/ev_hldm.h | 96 - dmc/cl_dll/events.cpp | 30 - dmc/cl_dll/eventscripts.h | 73 - dmc/cl_dll/flashlight.cpp | 146 - dmc/cl_dll/geiger.cpp | 180 - dmc/cl_dll/health.cpp | 476 -- dmc/cl_dll/health.h | 130 - dmc/cl_dll/hud.cpp | 594 -- dmc/cl_dll/hud.h | 659 --- dmc/cl_dll/hud_iface.h | 24 - dmc/cl_dll/hud_msg.cpp | 171 - dmc/cl_dll/hud_redraw.cpp | 445 -- dmc/cl_dll/hud_servers.cpp | 1256 ----- dmc/cl_dll/hud_servers.h | 41 - dmc/cl_dll/hud_servers_priv.h | 98 - dmc/cl_dll/hud_spectator.cpp | 1576 ------ dmc/cl_dll/hud_spectator.h | 129 - dmc/cl_dll/hud_update.cpp | 56 - dmc/cl_dll/in_camera.cpp | 598 -- dmc/cl_dll/in_defs.h | 21 - dmc/cl_dll/input.cpp | 1039 ---- dmc/cl_dll/inputw32.cpp | 987 ---- dmc/cl_dll/kbutton.h | 18 - dmc/cl_dll/menu.cpp | 282 - dmc/cl_dll/message.cpp | 481 -- dmc/cl_dll/quake/quake_baseentity.cpp | 330 -- dmc/cl_dll/quake/quake_events.cpp | 83 - dmc/cl_dll/quake/quake_objects.cpp | 81 - dmc/cl_dll/quake/quake_weapons.cpp | 988 ---- dmc/cl_dll/readme.txt | 107 - dmc/cl_dll/saytext.cpp | 312 -- dmc/cl_dll/scoreboard.cpp | 527 -- dmc/cl_dll/status_icons.cpp | 150 - dmc/cl_dll/statusbar.cpp | 262 - dmc/cl_dll/studio_util.cpp | 251 - dmc/cl_dll/studio_util.h | 40 - dmc/cl_dll/text_message.cpp | 208 - dmc/cl_dll/train.cpp | 85 - dmc/cl_dll/tri.cpp | 129 - dmc/cl_dll/util.cpp | 134 - dmc/cl_dll/util.h | 152 - dmc/cl_dll/util_vector.h | 121 - dmc/cl_dll/vgui_ControlConfigPanel.h | 47 - dmc/cl_dll/vgui_CustomObjects.cpp | 428 -- dmc/cl_dll/vgui_MOTDWindow.cpp | 153 - dmc/cl_dll/vgui_SchemeManager.cpp | 556 -- dmc/cl_dll/vgui_SchemeManager.h | 52 - dmc/cl_dll/vgui_ScorePanel.cpp | 1031 ---- dmc/cl_dll/vgui_ScorePanel.h | 314 -- dmc/cl_dll/vgui_ServerBrowser.cpp | 623 --- dmc/cl_dll/vgui_ServerBrowser.h | 50 - dmc/cl_dll/vgui_SpectatorPanel.cpp | 204 - dmc/cl_dll/vgui_SpectatorPanel.h | 93 - dmc/cl_dll/vgui_int.cpp | 128 - dmc/cl_dll/vgui_int.h | 21 - dmc/cl_dll/vgui_viewport.cpp | 1983 ------- dmc/cl_dll/vgui_viewport.h | 1331 ----- dmc/cl_dll/view.cpp | 1677 ------ dmc/cl_dll/view.h | 15 - dmc/cl_dll/voice_status.cpp | 885 --- dmc/cl_dll/voice_status.h | 228 - dmc/cl_dll/wrect.h | 16 - dmc/dlls/Makefile | 126 - dmc/dlls/activity.h | 109 - dmc/dlls/activitymap.h | 97 - dmc/dlls/animating.cpp | 313 -- dmc/dlls/animation.cpp | 527 -- dmc/dlls/animation.h | 47 - dmc/dlls/basemonster.h | 339 -- dmc/dlls/bmodels.cpp | 958 ---- dmc/dlls/buttons.cpp | 1279 ----- dmc/dlls/cbase.cpp | 767 --- dmc/dlls/cbase.h | 805 --- dmc/dlls/cdll_dll.h | 46 - dmc/dlls/client.cpp | 1817 ------ dmc/dlls/client.h | 65 - dmc/dlls/combat.cpp | 1099 ---- dmc/dlls/decals.h | 75 - dmc/dlls/defaultai.cpp | 240 - dmc/dlls/defaultai.h | 98 - dmc/dlls/dmc.def | 5 - dmc/dlls/dmcgl.def | 15 - dmc/dlls/doors.cpp | 1099 ---- dmc/dlls/doors.h | 33 - dmc/dlls/effects.cpp | 2268 -------- dmc/dlls/effects.h | 209 - dmc/dlls/enginecallback.h | 159 - dmc/dlls/explode.cpp | 273 - dmc/dlls/explode.h | 32 - dmc/dlls/extdll.h | 101 - dmc/dlls/func_break.cpp | 998 ---- dmc/dlls/func_break.h | 74 - dmc/dlls/func_tank.cpp | 1039 ---- dmc/dlls/game.cpp | 892 --- dmc/dlls/game.h | 46 - dmc/dlls/gamerules.cpp | 179 - dmc/dlls/gamerules.h | 370 -- dmc/dlls/globals.cpp | 39 - dmc/dlls/h_ai.cpp | 198 - dmc/dlls/h_export.cpp | 63 - dmc/dlls/hl.def | 5 - dmc/dlls/hl.dsp | 509 -- dmc/dlls/hlgl.def | 15 - dmc/dlls/items.cpp | 337 -- dmc/dlls/items.h | 29 - dmc/dlls/lights.cpp | 199 - dmc/dlls/maprules.cpp | 918 --- dmc/dlls/maprules.h | 22 - dmc/dlls/monsterevent.h | 34 - dmc/dlls/monsters.cpp | 134 - dmc/dlls/monsters.h | 183 - dmc/dlls/monsterstate.cpp | 28 - dmc/dlls/multiplay_gamerules.cpp | 1672 ------ dmc/dlls/nodes.cpp | 3654 ------------ dmc/dlls/nodes.h | 374 -- dmc/dlls/observer.cpp | 142 - dmc/dlls/pathcorner.cpp | 428 -- dmc/dlls/plane.cpp | 60 - dmc/dlls/plane.h | 43 - dmc/dlls/plats.cpp | 2285 -------- dmc/dlls/player.cpp | 4887 ---------------- dmc/dlls/player.h | 497 -- dmc/dlls/quake_gun.cpp | 174 - dmc/dlls/quake_gun.h | 44 - dmc/dlls/quake_items.cpp | 1866 ------- dmc/dlls/quake_nail.cpp | 122 - dmc/dlls/quake_player.cpp | 250 - dmc/dlls/quake_rocket.cpp | 191 - dmc/dlls/quake_weapons_all.cpp | 1087 ---- dmc/dlls/saverestore.h | 170 - dmc/dlls/schedule.cpp | 39 - dmc/dlls/schedule.h | 290 - dmc/dlls/scripted.cpp | 1260 ----- dmc/dlls/scripted.h | 107 - dmc/dlls/scriptevent.h | 29 - dmc/dlls/singleplay_gamerules.cpp | 336 -- dmc/dlls/skill.cpp | 47 - dmc/dlls/skill.h | 147 - dmc/dlls/sound.cpp | 1970 ------- dmc/dlls/soundent.cpp | 379 -- dmc/dlls/soundent.h | 95 - dmc/dlls/spectator.cpp | 149 - dmc/dlls/spectator.h | 27 - dmc/dlls/subs.cpp | 559 -- dmc/dlls/teamplay_gamerules.cpp | 618 --- dmc/dlls/teamplay_gamerules.h | 62 - dmc/dlls/threewave_gamerules.cpp | 3275 ----------- dmc/dlls/threewave_gamerules.h | 221 - dmc/dlls/trains.h | 127 - dmc/dlls/triggers.cpp | 2716 --------- dmc/dlls/util.cpp | 2713 --------- dmc/dlls/util.h | 601 -- dmc/dlls/vector.h | 112 - dmc/dlls/weapons.cpp | 1417 ----- dmc/dlls/weapons.h | 492 -- dmc/dlls/world.cpp | 745 --- dmc/pm_shared/pm_debug.c | 296 - dmc/pm_shared/pm_debug.h | 17 - dmc/pm_shared/pm_defs.h | 213 - dmc/pm_shared/pm_info.h | 15 - dmc/pm_shared/pm_materials.h | 26 - dmc/pm_shared/pm_math.c | 416 -- dmc/pm_shared/pm_movevars.h | 47 - dmc/pm_shared/pm_shared.c | 2798 ---------- dmc/pm_shared/pm_shared.h | 36 - linux/Makefile.dmc_cdll | 164 - linux/Makefile.dmcdll | 114 - linux/Makefile.ricochet_cdll | 163 - linux/Makefile.ricochetdll | 128 - projects/vs2010/dmc_cdll.vcxproj | 229 - projects/vs2010/dmc_cdll.vcxproj.filters | 411 -- projects/vs2010/dmcdll.vcxproj | 205 - projects/vs2010/dmcdll.vcxproj.filters | 333 -- projects/vs2010/ricochet_cdll.vcxproj | 221 - projects/vs2010/ricochet_cdll.vcxproj.filters | 384 -- projects/vs2010/ricochetdll.vcxproj | 208 - projects/vs2010/ricochetdll.vcxproj.filters | 333 -- ricochet/cl_dll/Exports.h | 224 - ricochet/cl_dll/GameStudioModelRenderer.cpp | 981 ---- ricochet/cl_dll/GameStudioModelRenderer.h | 48 - ricochet/cl_dll/Ricochet_BSPFile.h | 41 - ricochet/cl_dll/Ricochet_JumpPads.cpp | 580 -- ricochet/cl_dll/Ricochet_JumpPads.h | 9 - ricochet/cl_dll/StudioModelRenderer.cpp | 1607 ------ ricochet/cl_dll/StudioModelRenderer.h | 182 - ricochet/cl_dll/ammo.cpp | 930 ---- ricochet/cl_dll/ammo.h | 62 - ricochet/cl_dll/ammo_secondary.cpp | 159 - ricochet/cl_dll/ammohistory.cpp | 190 - ricochet/cl_dll/ammohistory.h | 143 - ricochet/cl_dll/battery.cpp | 79 - ricochet/cl_dll/camera.h | 31 - ricochet/cl_dll/cdll_int.cpp | 278 - ricochet/cl_dll/cl_dll.dsp | 555 -- ricochet/cl_dll/cl_dll.h | 42 - ricochet/cl_dll/cl_util.h | 189 - ricochet/cl_dll/com_weapons.cpp | 278 - ricochet/cl_dll/com_weapons.h | 41 - ricochet/cl_dll/death.cpp | 307 -- ricochet/cl_dll/demo.cpp | 68 - ricochet/cl_dll/demo.h | 27 - ricochet/cl_dll/entity.cpp | 641 --- ricochet/cl_dll/ev_common.cpp | 198 - ricochet/cl_dll/ev_hldm.cpp | 150 - ricochet/cl_dll/ev_hldm.h | 16 - ricochet/cl_dll/events.cpp | 30 - ricochet/cl_dll/eventscripts.h | 80 - ricochet/cl_dll/flashlight.cpp | 100 - ricochet/cl_dll/geiger.cpp | 180 - ricochet/cl_dll/health.cpp | 425 -- ricochet/cl_dll/health.h | 128 - ricochet/cl_dll/hl/hl_baseentity.cpp | 248 - ricochet/cl_dll/hl/hl_events.cpp | 45 - ricochet/cl_dll/hl/hl_objects.cpp | 28 - ricochet/cl_dll/hl/hl_weapons.cpp | 1423 ----- ricochet/cl_dll/hud.cpp | 590 -- ricochet/cl_dll/hud.h | 586 -- ricochet/cl_dll/hud_iface.h | 31 - ricochet/cl_dll/hud_msg.cpp | 117 - ricochet/cl_dll/hud_redraw.cpp | 262 - ricochet/cl_dll/hud_servers.cpp | 1249 ----- ricochet/cl_dll/hud_servers.h | 34 - ricochet/cl_dll/hud_servers_priv.h | 91 - ricochet/cl_dll/hud_update.cpp | 54 - ricochet/cl_dll/in_camera.cpp | 600 -- ricochet/cl_dll/in_defs.h | 27 - ricochet/cl_dll/input.cpp | 988 ---- ricochet/cl_dll/inputw32.cpp | 991 ---- ricochet/cl_dll/kbutton.h | 25 - ricochet/cl_dll/menu.cpp | 188 - ricochet/cl_dll/message.cpp | 462 -- ricochet/cl_dll/readme.txt | 107 - ricochet/cl_dll/saytext.cpp | 308 -- ricochet/cl_dll/status_icons.cpp | 150 - ricochet/cl_dll/statusbar.cpp | 252 - ricochet/cl_dll/studio_util.cpp | 244 - ricochet/cl_dll/studio_util.h | 33 - ricochet/cl_dll/text_message.cpp | 208 - ricochet/cl_dll/tf_defs.h | 1357 ----- ricochet/cl_dll/train.cpp | 85 - ricochet/cl_dll/tri.cpp | 127 - ricochet/cl_dll/util.cpp | 101 - ricochet/cl_dll/util_vector.h | 121 - ricochet/cl_dll/vgui_ConsolePanel.cpp | 95 - ricochet/cl_dll/vgui_ConsolePanel.h | 32 - ricochet/cl_dll/vgui_ControlConfigPanel.cpp | 206 - ricochet/cl_dll/vgui_ControlConfigPanel.h | 41 - ricochet/cl_dll/vgui_CustomObjects.cpp | 501 -- ricochet/cl_dll/vgui_MOTDWindow.cpp | 154 - ricochet/cl_dll/vgui_SchemeManager.cpp | 556 -- ricochet/cl_dll/vgui_SchemeManager.h | 47 - ricochet/cl_dll/vgui_ScorePanel.cpp | 1145 ---- ricochet/cl_dll/vgui_ScorePanel.h | 307 -- ricochet/cl_dll/vgui_ServerBrowser.cpp | 616 --- ricochet/cl_dll/vgui_ServerBrowser.h | 44 - ricochet/cl_dll/vgui_TeamFortressViewport.cpp | 2220 -------- ricochet/cl_dll/vgui_TeamFortressViewport.h | 1207 ---- ricochet/cl_dll/vgui_discobjects.cpp | 593 -- ricochet/cl_dll/vgui_discobjects.h | 109 - ricochet/cl_dll/vgui_int.cpp | 122 - ricochet/cl_dll/vgui_int.h | 15 - ricochet/cl_dll/view.cpp | 1061 ---- ricochet/cl_dll/view.h | 22 - ricochet/cl_dll/voice_status.cpp | 885 --- ricochet/cl_dll/voice_status.h | 228 - ricochet/cl_dll/wrect.h | 23 - ricochet/dlls/Makefile | 136 - ricochet/dlls/activity.h | 79 - ricochet/dlls/activitymap.h | 37 - ricochet/dlls/airtank.cpp | 118 - ricochet/dlls/animating.cpp | 313 -- ricochet/dlls/animation.cpp | 526 -- ricochet/dlls/animation.h | 47 - ricochet/dlls/basemonster.h | 94 - ricochet/dlls/bmodels.cpp | 958 ---- ricochet/dlls/buttons.cpp | 1279 ----- ricochet/dlls/cbase.cpp | 796 --- ricochet/dlls/cbase.h | 803 --- ricochet/dlls/cdll_dll.h | 46 - ricochet/dlls/client.cpp | 1822 ------ ricochet/dlls/client.h | 67 - ricochet/dlls/combat.cpp | 1453 ----- ricochet/dlls/decals.h | 75 - ricochet/dlls/disc_arena.cpp | 1048 ---- ricochet/dlls/disc_arena.h | 111 - ricochet/dlls/disc_objects.h | 173 - ricochet/dlls/disc_powerups.cpp | 234 - ricochet/dlls/disc_weapon.h | 33 - ricochet/dlls/discwar.h | 60 - ricochet/dlls/doors.cpp | 1026 ---- ricochet/dlls/doors.h | 33 - ricochet/dlls/effects.cpp | 2268 -------- ricochet/dlls/effects.h | 209 - ricochet/dlls/enginecallback.h | 159 - ricochet/dlls/explode.cpp | 273 - ricochet/dlls/explode.h | 32 - ricochet/dlls/extdll.h | 101 - ricochet/dlls/func_break.cpp | 998 ---- ricochet/dlls/func_break.h | 74 - ricochet/dlls/func_tank.cpp | 1035 ---- ricochet/dlls/game.cpp | 899 --- ricochet/dlls/game.h | 44 - ricochet/dlls/gamerules.cpp | 328 -- ricochet/dlls/gamerules.h | 360 -- ricochet/dlls/ggrenade.cpp | 488 -- ricochet/dlls/globals.cpp | 39 - ricochet/dlls/h_ai.cpp | 198 - ricochet/dlls/h_battery.cpp | 200 - ricochet/dlls/h_cycler.cpp | 471 -- ricochet/dlls/h_export.cpp | 61 - ricochet/dlls/healthkit.cpp | 259 - ricochet/dlls/items.cpp | 337 -- ricochet/dlls/items.h | 29 - ricochet/dlls/lights.cpp | 199 - ricochet/dlls/maprules.cpp | 918 --- ricochet/dlls/maprules.h | 22 - ricochet/dlls/monsterevent.h | 34 - ricochet/dlls/monsters.h | 88 - ricochet/dlls/mortar.cpp | 323 -- ricochet/dlls/mp.def | 5 - ricochet/dlls/mp.dsp | 516 -- ricochet/dlls/mpstubb.cpp | 264 - ricochet/dlls/multiplay_gamerules.cpp | 1620 ------ ricochet/dlls/nodes.h | 54 - ricochet/dlls/observer.cpp | 325 -- ricochet/dlls/pathcorner.cpp | 428 -- ricochet/dlls/plane.cpp | 60 - ricochet/dlls/plane.h | 43 - ricochet/dlls/plats.cpp | 2285 -------- ricochet/dlls/player.cpp | 4901 ----------------- ricochet/dlls/player.h | 356 -- ricochet/dlls/saverestore.h | 170 - ricochet/dlls/schedule.h | 31 - ricochet/dlls/scriptevent.h | 29 - ricochet/dlls/singleplay_gamerules.cpp | 331 -- ricochet/dlls/skill.cpp | 47 - ricochet/dlls/skill.h | 147 - ricochet/dlls/sound.cpp | 1985 ------- ricochet/dlls/soundent.cpp | 379 -- ricochet/dlls/soundent.h | 95 - ricochet/dlls/spectator.cpp | 149 - ricochet/dlls/spectator.h | 27 - ricochet/dlls/subs.cpp | 582 -- ricochet/dlls/talkmonster.h | 26 - ricochet/dlls/teamplay_gamerules.cpp | 611 -- ricochet/dlls/teamplay_gamerules.h | 57 - ricochet/dlls/trains.h | 127 - ricochet/dlls/triggers.cpp | 2790 ---------- ricochet/dlls/util.cpp | 2565 --------- ricochet/dlls/util.h | 564 -- ricochet/dlls/vector.h | 112 - ricochet/dlls/weapons.cpp | 1058 ---- ricochet/dlls/weapons.h | 451 -- ricochet/dlls/world.cpp | 782 --- ricochet/dlls/wpn_shared/disc_weapon_disc.cpp | 753 --- ricochet/dlls/xen.cpp | 530 -- ricochet/pm_shared/pm_debug.c | 305 - ricochet/pm_shared/pm_debug.h | 10 - ricochet/pm_shared/pm_defs.h | 208 - ricochet/pm_shared/pm_info.h | 10 - ricochet/pm_shared/pm_materials.h | 19 - ricochet/pm_shared/pm_math.c | 326 -- ricochet/pm_shared/pm_movevars.h | 40 - ricochet/pm_shared/pm_shared.c | 3374 ------------ ricochet/pm_shared/pm_shared.h | 32 - 396 files changed, 177734 deletions(-) delete mode 100644 dmc/cl_dll/CTF_FlagStatus.cpp delete mode 100644 dmc/cl_dll/CTF_HudMessage.cpp delete mode 100644 dmc/cl_dll/DMC_BSPFile.h delete mode 100644 dmc/cl_dll/DMC_Teleporters.cpp delete mode 100644 dmc/cl_dll/DMC_Teleporters.h delete mode 100644 dmc/cl_dll/Exports.h delete mode 100644 dmc/cl_dll/GameStudioModelRenderer.cpp delete mode 100644 dmc/cl_dll/GameStudioModelRenderer.h delete mode 100644 dmc/cl_dll/MOTD.cpp delete mode 100644 dmc/cl_dll/StudioModelRenderer.cpp delete mode 100644 dmc/cl_dll/StudioModelRenderer.h delete mode 100644 dmc/cl_dll/ammo.cpp delete mode 100644 dmc/cl_dll/ammo.h delete mode 100644 dmc/cl_dll/ammo_secondary.cpp delete mode 100644 dmc/cl_dll/ammohistory.cpp delete mode 100644 dmc/cl_dll/ammohistory.h delete mode 100644 dmc/cl_dll/battery.cpp delete mode 100644 dmc/cl_dll/camera.h delete mode 100644 dmc/cl_dll/cdll_int.cpp delete mode 100644 dmc/cl_dll/cl_dll.dsp delete mode 100644 dmc/cl_dll/cl_dll.h delete mode 100644 dmc/cl_dll/cl_util.h delete mode 100644 dmc/cl_dll/com_model.h delete mode 100644 dmc/cl_dll/com_weapons.cpp delete mode 100644 dmc/cl_dll/com_weapons.h delete mode 100644 dmc/cl_dll/death.cpp delete mode 100644 dmc/cl_dll/demo.cpp delete mode 100644 dmc/cl_dll/demo.h delete mode 100644 dmc/cl_dll/entity.cpp delete mode 100644 dmc/cl_dll/ev_common.cpp delete mode 100644 dmc/cl_dll/ev_hldm.cpp delete mode 100644 dmc/cl_dll/ev_hldm.h delete mode 100644 dmc/cl_dll/events.cpp delete mode 100644 dmc/cl_dll/eventscripts.h delete mode 100644 dmc/cl_dll/flashlight.cpp delete mode 100644 dmc/cl_dll/geiger.cpp delete mode 100644 dmc/cl_dll/health.cpp delete mode 100644 dmc/cl_dll/health.h delete mode 100644 dmc/cl_dll/hud.cpp delete mode 100644 dmc/cl_dll/hud.h delete mode 100644 dmc/cl_dll/hud_iface.h delete mode 100644 dmc/cl_dll/hud_msg.cpp delete mode 100644 dmc/cl_dll/hud_redraw.cpp delete mode 100644 dmc/cl_dll/hud_servers.cpp delete mode 100644 dmc/cl_dll/hud_servers.h delete mode 100644 dmc/cl_dll/hud_servers_priv.h delete mode 100644 dmc/cl_dll/hud_spectator.cpp delete mode 100644 dmc/cl_dll/hud_spectator.h delete mode 100644 dmc/cl_dll/hud_update.cpp delete mode 100644 dmc/cl_dll/in_camera.cpp delete mode 100644 dmc/cl_dll/in_defs.h delete mode 100644 dmc/cl_dll/input.cpp delete mode 100644 dmc/cl_dll/inputw32.cpp delete mode 100644 dmc/cl_dll/kbutton.h delete mode 100644 dmc/cl_dll/menu.cpp delete mode 100644 dmc/cl_dll/message.cpp delete mode 100644 dmc/cl_dll/quake/quake_baseentity.cpp delete mode 100644 dmc/cl_dll/quake/quake_events.cpp delete mode 100644 dmc/cl_dll/quake/quake_objects.cpp delete mode 100644 dmc/cl_dll/quake/quake_weapons.cpp delete mode 100644 dmc/cl_dll/readme.txt delete mode 100644 dmc/cl_dll/saytext.cpp delete mode 100644 dmc/cl_dll/scoreboard.cpp delete mode 100644 dmc/cl_dll/status_icons.cpp delete mode 100644 dmc/cl_dll/statusbar.cpp delete mode 100644 dmc/cl_dll/studio_util.cpp delete mode 100644 dmc/cl_dll/studio_util.h delete mode 100644 dmc/cl_dll/text_message.cpp delete mode 100644 dmc/cl_dll/train.cpp delete mode 100644 dmc/cl_dll/tri.cpp delete mode 100644 dmc/cl_dll/util.cpp delete mode 100644 dmc/cl_dll/util.h delete mode 100644 dmc/cl_dll/util_vector.h delete mode 100644 dmc/cl_dll/vgui_ControlConfigPanel.h delete mode 100644 dmc/cl_dll/vgui_CustomObjects.cpp delete mode 100644 dmc/cl_dll/vgui_MOTDWindow.cpp delete mode 100644 dmc/cl_dll/vgui_SchemeManager.cpp delete mode 100644 dmc/cl_dll/vgui_SchemeManager.h delete mode 100644 dmc/cl_dll/vgui_ScorePanel.cpp delete mode 100644 dmc/cl_dll/vgui_ScorePanel.h delete mode 100644 dmc/cl_dll/vgui_ServerBrowser.cpp delete mode 100644 dmc/cl_dll/vgui_ServerBrowser.h delete mode 100644 dmc/cl_dll/vgui_SpectatorPanel.cpp delete mode 100644 dmc/cl_dll/vgui_SpectatorPanel.h delete mode 100644 dmc/cl_dll/vgui_int.cpp delete mode 100644 dmc/cl_dll/vgui_int.h delete mode 100644 dmc/cl_dll/vgui_viewport.cpp delete mode 100644 dmc/cl_dll/vgui_viewport.h delete mode 100644 dmc/cl_dll/view.cpp delete mode 100644 dmc/cl_dll/view.h delete mode 100644 dmc/cl_dll/voice_status.cpp delete mode 100644 dmc/cl_dll/voice_status.h delete mode 100644 dmc/cl_dll/wrect.h delete mode 100644 dmc/dlls/Makefile delete mode 100644 dmc/dlls/activity.h delete mode 100644 dmc/dlls/activitymap.h delete mode 100644 dmc/dlls/animating.cpp delete mode 100644 dmc/dlls/animation.cpp delete mode 100644 dmc/dlls/animation.h delete mode 100644 dmc/dlls/basemonster.h delete mode 100644 dmc/dlls/bmodels.cpp delete mode 100644 dmc/dlls/buttons.cpp delete mode 100644 dmc/dlls/cbase.cpp delete mode 100644 dmc/dlls/cbase.h delete mode 100644 dmc/dlls/cdll_dll.h delete mode 100644 dmc/dlls/client.cpp delete mode 100644 dmc/dlls/client.h delete mode 100644 dmc/dlls/combat.cpp delete mode 100644 dmc/dlls/decals.h delete mode 100644 dmc/dlls/defaultai.cpp delete mode 100644 dmc/dlls/defaultai.h delete mode 100644 dmc/dlls/dmc.def delete mode 100644 dmc/dlls/dmcgl.def delete mode 100644 dmc/dlls/doors.cpp delete mode 100644 dmc/dlls/doors.h delete mode 100644 dmc/dlls/effects.cpp delete mode 100644 dmc/dlls/effects.h delete mode 100644 dmc/dlls/enginecallback.h delete mode 100644 dmc/dlls/explode.cpp delete mode 100644 dmc/dlls/explode.h delete mode 100644 dmc/dlls/extdll.h delete mode 100644 dmc/dlls/func_break.cpp delete mode 100644 dmc/dlls/func_break.h delete mode 100644 dmc/dlls/func_tank.cpp delete mode 100644 dmc/dlls/game.cpp delete mode 100644 dmc/dlls/game.h delete mode 100644 dmc/dlls/gamerules.cpp delete mode 100644 dmc/dlls/gamerules.h delete mode 100644 dmc/dlls/globals.cpp delete mode 100644 dmc/dlls/h_ai.cpp delete mode 100644 dmc/dlls/h_export.cpp delete mode 100644 dmc/dlls/hl.def delete mode 100644 dmc/dlls/hl.dsp delete mode 100644 dmc/dlls/hlgl.def delete mode 100644 dmc/dlls/items.cpp delete mode 100644 dmc/dlls/items.h delete mode 100644 dmc/dlls/lights.cpp delete mode 100644 dmc/dlls/maprules.cpp delete mode 100644 dmc/dlls/maprules.h delete mode 100644 dmc/dlls/monsterevent.h delete mode 100644 dmc/dlls/monsters.cpp delete mode 100644 dmc/dlls/monsters.h delete mode 100644 dmc/dlls/monsterstate.cpp delete mode 100644 dmc/dlls/multiplay_gamerules.cpp delete mode 100644 dmc/dlls/nodes.cpp delete mode 100644 dmc/dlls/nodes.h delete mode 100644 dmc/dlls/observer.cpp delete mode 100644 dmc/dlls/pathcorner.cpp delete mode 100644 dmc/dlls/plane.cpp delete mode 100644 dmc/dlls/plane.h delete mode 100644 dmc/dlls/plats.cpp delete mode 100644 dmc/dlls/player.cpp delete mode 100644 dmc/dlls/player.h delete mode 100644 dmc/dlls/quake_gun.cpp delete mode 100644 dmc/dlls/quake_gun.h delete mode 100644 dmc/dlls/quake_items.cpp delete mode 100644 dmc/dlls/quake_nail.cpp delete mode 100644 dmc/dlls/quake_player.cpp delete mode 100644 dmc/dlls/quake_rocket.cpp delete mode 100644 dmc/dlls/quake_weapons_all.cpp delete mode 100644 dmc/dlls/saverestore.h delete mode 100644 dmc/dlls/schedule.cpp delete mode 100644 dmc/dlls/schedule.h delete mode 100644 dmc/dlls/scripted.cpp delete mode 100644 dmc/dlls/scripted.h delete mode 100644 dmc/dlls/scriptevent.h delete mode 100644 dmc/dlls/singleplay_gamerules.cpp delete mode 100644 dmc/dlls/skill.cpp delete mode 100644 dmc/dlls/skill.h delete mode 100644 dmc/dlls/sound.cpp delete mode 100644 dmc/dlls/soundent.cpp delete mode 100644 dmc/dlls/soundent.h delete mode 100644 dmc/dlls/spectator.cpp delete mode 100644 dmc/dlls/spectator.h delete mode 100644 dmc/dlls/subs.cpp delete mode 100644 dmc/dlls/teamplay_gamerules.cpp delete mode 100644 dmc/dlls/teamplay_gamerules.h delete mode 100644 dmc/dlls/threewave_gamerules.cpp delete mode 100644 dmc/dlls/threewave_gamerules.h delete mode 100644 dmc/dlls/trains.h delete mode 100644 dmc/dlls/triggers.cpp delete mode 100644 dmc/dlls/util.cpp delete mode 100644 dmc/dlls/util.h delete mode 100644 dmc/dlls/vector.h delete mode 100644 dmc/dlls/weapons.cpp delete mode 100644 dmc/dlls/weapons.h delete mode 100644 dmc/dlls/world.cpp delete mode 100644 dmc/pm_shared/pm_debug.c delete mode 100644 dmc/pm_shared/pm_debug.h delete mode 100644 dmc/pm_shared/pm_defs.h delete mode 100644 dmc/pm_shared/pm_info.h delete mode 100644 dmc/pm_shared/pm_materials.h delete mode 100644 dmc/pm_shared/pm_math.c delete mode 100644 dmc/pm_shared/pm_movevars.h delete mode 100644 dmc/pm_shared/pm_shared.c delete mode 100644 dmc/pm_shared/pm_shared.h delete mode 100644 linux/Makefile.dmc_cdll delete mode 100644 linux/Makefile.dmcdll delete mode 100644 linux/Makefile.ricochet_cdll delete mode 100644 linux/Makefile.ricochetdll delete mode 100644 projects/vs2010/dmc_cdll.vcxproj delete mode 100644 projects/vs2010/dmc_cdll.vcxproj.filters delete mode 100644 projects/vs2010/dmcdll.vcxproj delete mode 100644 projects/vs2010/dmcdll.vcxproj.filters delete mode 100644 projects/vs2010/ricochet_cdll.vcxproj delete mode 100644 projects/vs2010/ricochet_cdll.vcxproj.filters delete mode 100644 projects/vs2010/ricochetdll.vcxproj delete mode 100644 projects/vs2010/ricochetdll.vcxproj.filters delete mode 100644 ricochet/cl_dll/Exports.h delete mode 100644 ricochet/cl_dll/GameStudioModelRenderer.cpp delete mode 100644 ricochet/cl_dll/GameStudioModelRenderer.h delete mode 100644 ricochet/cl_dll/Ricochet_BSPFile.h delete mode 100644 ricochet/cl_dll/Ricochet_JumpPads.cpp delete mode 100644 ricochet/cl_dll/Ricochet_JumpPads.h delete mode 100644 ricochet/cl_dll/StudioModelRenderer.cpp delete mode 100644 ricochet/cl_dll/StudioModelRenderer.h delete mode 100644 ricochet/cl_dll/ammo.cpp delete mode 100644 ricochet/cl_dll/ammo.h delete mode 100644 ricochet/cl_dll/ammo_secondary.cpp delete mode 100644 ricochet/cl_dll/ammohistory.cpp delete mode 100644 ricochet/cl_dll/ammohistory.h delete mode 100644 ricochet/cl_dll/battery.cpp delete mode 100644 ricochet/cl_dll/camera.h delete mode 100644 ricochet/cl_dll/cdll_int.cpp delete mode 100644 ricochet/cl_dll/cl_dll.dsp delete mode 100644 ricochet/cl_dll/cl_dll.h delete mode 100644 ricochet/cl_dll/cl_util.h delete mode 100644 ricochet/cl_dll/com_weapons.cpp delete mode 100644 ricochet/cl_dll/com_weapons.h delete mode 100644 ricochet/cl_dll/death.cpp delete mode 100644 ricochet/cl_dll/demo.cpp delete mode 100644 ricochet/cl_dll/demo.h delete mode 100644 ricochet/cl_dll/entity.cpp delete mode 100644 ricochet/cl_dll/ev_common.cpp delete mode 100644 ricochet/cl_dll/ev_hldm.cpp delete mode 100644 ricochet/cl_dll/ev_hldm.h delete mode 100644 ricochet/cl_dll/events.cpp delete mode 100644 ricochet/cl_dll/eventscripts.h delete mode 100644 ricochet/cl_dll/flashlight.cpp delete mode 100644 ricochet/cl_dll/geiger.cpp delete mode 100644 ricochet/cl_dll/health.cpp delete mode 100644 ricochet/cl_dll/health.h delete mode 100644 ricochet/cl_dll/hl/hl_baseentity.cpp delete mode 100644 ricochet/cl_dll/hl/hl_events.cpp delete mode 100644 ricochet/cl_dll/hl/hl_objects.cpp delete mode 100644 ricochet/cl_dll/hl/hl_weapons.cpp delete mode 100644 ricochet/cl_dll/hud.cpp delete mode 100644 ricochet/cl_dll/hud.h delete mode 100644 ricochet/cl_dll/hud_iface.h delete mode 100644 ricochet/cl_dll/hud_msg.cpp delete mode 100644 ricochet/cl_dll/hud_redraw.cpp delete mode 100644 ricochet/cl_dll/hud_servers.cpp delete mode 100644 ricochet/cl_dll/hud_servers.h delete mode 100644 ricochet/cl_dll/hud_servers_priv.h delete mode 100644 ricochet/cl_dll/hud_update.cpp delete mode 100644 ricochet/cl_dll/in_camera.cpp delete mode 100644 ricochet/cl_dll/in_defs.h delete mode 100644 ricochet/cl_dll/input.cpp delete mode 100644 ricochet/cl_dll/inputw32.cpp delete mode 100644 ricochet/cl_dll/kbutton.h delete mode 100644 ricochet/cl_dll/menu.cpp delete mode 100644 ricochet/cl_dll/message.cpp delete mode 100644 ricochet/cl_dll/readme.txt delete mode 100644 ricochet/cl_dll/saytext.cpp delete mode 100644 ricochet/cl_dll/status_icons.cpp delete mode 100644 ricochet/cl_dll/statusbar.cpp delete mode 100644 ricochet/cl_dll/studio_util.cpp delete mode 100644 ricochet/cl_dll/studio_util.h delete mode 100644 ricochet/cl_dll/text_message.cpp delete mode 100644 ricochet/cl_dll/tf_defs.h delete mode 100644 ricochet/cl_dll/train.cpp delete mode 100644 ricochet/cl_dll/tri.cpp delete mode 100644 ricochet/cl_dll/util.cpp delete mode 100644 ricochet/cl_dll/util_vector.h delete mode 100644 ricochet/cl_dll/vgui_ConsolePanel.cpp delete mode 100644 ricochet/cl_dll/vgui_ConsolePanel.h delete mode 100644 ricochet/cl_dll/vgui_ControlConfigPanel.cpp delete mode 100644 ricochet/cl_dll/vgui_ControlConfigPanel.h delete mode 100644 ricochet/cl_dll/vgui_CustomObjects.cpp delete mode 100644 ricochet/cl_dll/vgui_MOTDWindow.cpp delete mode 100644 ricochet/cl_dll/vgui_SchemeManager.cpp delete mode 100644 ricochet/cl_dll/vgui_SchemeManager.h delete mode 100644 ricochet/cl_dll/vgui_ScorePanel.cpp delete mode 100644 ricochet/cl_dll/vgui_ScorePanel.h delete mode 100644 ricochet/cl_dll/vgui_ServerBrowser.cpp delete mode 100644 ricochet/cl_dll/vgui_ServerBrowser.h delete mode 100644 ricochet/cl_dll/vgui_TeamFortressViewport.cpp delete mode 100644 ricochet/cl_dll/vgui_TeamFortressViewport.h delete mode 100644 ricochet/cl_dll/vgui_discobjects.cpp delete mode 100644 ricochet/cl_dll/vgui_discobjects.h delete mode 100644 ricochet/cl_dll/vgui_int.cpp delete mode 100644 ricochet/cl_dll/vgui_int.h delete mode 100644 ricochet/cl_dll/view.cpp delete mode 100644 ricochet/cl_dll/view.h delete mode 100644 ricochet/cl_dll/voice_status.cpp delete mode 100644 ricochet/cl_dll/voice_status.h delete mode 100644 ricochet/cl_dll/wrect.h delete mode 100644 ricochet/dlls/Makefile delete mode 100644 ricochet/dlls/activity.h delete mode 100644 ricochet/dlls/activitymap.h delete mode 100644 ricochet/dlls/airtank.cpp delete mode 100644 ricochet/dlls/animating.cpp delete mode 100644 ricochet/dlls/animation.cpp delete mode 100644 ricochet/dlls/animation.h delete mode 100644 ricochet/dlls/basemonster.h delete mode 100644 ricochet/dlls/bmodels.cpp delete mode 100644 ricochet/dlls/buttons.cpp delete mode 100644 ricochet/dlls/cbase.cpp delete mode 100644 ricochet/dlls/cbase.h delete mode 100644 ricochet/dlls/cdll_dll.h delete mode 100644 ricochet/dlls/client.cpp delete mode 100644 ricochet/dlls/client.h delete mode 100644 ricochet/dlls/combat.cpp delete mode 100644 ricochet/dlls/decals.h delete mode 100644 ricochet/dlls/disc_arena.cpp delete mode 100644 ricochet/dlls/disc_arena.h delete mode 100644 ricochet/dlls/disc_objects.h delete mode 100644 ricochet/dlls/disc_powerups.cpp delete mode 100644 ricochet/dlls/disc_weapon.h delete mode 100644 ricochet/dlls/discwar.h delete mode 100644 ricochet/dlls/doors.cpp delete mode 100644 ricochet/dlls/doors.h delete mode 100644 ricochet/dlls/effects.cpp delete mode 100644 ricochet/dlls/effects.h delete mode 100644 ricochet/dlls/enginecallback.h delete mode 100644 ricochet/dlls/explode.cpp delete mode 100644 ricochet/dlls/explode.h delete mode 100644 ricochet/dlls/extdll.h delete mode 100644 ricochet/dlls/func_break.cpp delete mode 100644 ricochet/dlls/func_break.h delete mode 100644 ricochet/dlls/func_tank.cpp delete mode 100644 ricochet/dlls/game.cpp delete mode 100644 ricochet/dlls/game.h delete mode 100644 ricochet/dlls/gamerules.cpp delete mode 100644 ricochet/dlls/gamerules.h delete mode 100644 ricochet/dlls/ggrenade.cpp delete mode 100644 ricochet/dlls/globals.cpp delete mode 100644 ricochet/dlls/h_ai.cpp delete mode 100644 ricochet/dlls/h_battery.cpp delete mode 100644 ricochet/dlls/h_cycler.cpp delete mode 100644 ricochet/dlls/h_export.cpp delete mode 100644 ricochet/dlls/healthkit.cpp delete mode 100644 ricochet/dlls/items.cpp delete mode 100644 ricochet/dlls/items.h delete mode 100644 ricochet/dlls/lights.cpp delete mode 100644 ricochet/dlls/maprules.cpp delete mode 100644 ricochet/dlls/maprules.h delete mode 100644 ricochet/dlls/monsterevent.h delete mode 100644 ricochet/dlls/monsters.h delete mode 100644 ricochet/dlls/mortar.cpp delete mode 100644 ricochet/dlls/mp.def delete mode 100644 ricochet/dlls/mp.dsp delete mode 100644 ricochet/dlls/mpstubb.cpp delete mode 100644 ricochet/dlls/multiplay_gamerules.cpp delete mode 100644 ricochet/dlls/nodes.h delete mode 100644 ricochet/dlls/observer.cpp delete mode 100644 ricochet/dlls/pathcorner.cpp delete mode 100644 ricochet/dlls/plane.cpp delete mode 100644 ricochet/dlls/plane.h delete mode 100644 ricochet/dlls/plats.cpp delete mode 100644 ricochet/dlls/player.cpp delete mode 100644 ricochet/dlls/player.h delete mode 100644 ricochet/dlls/saverestore.h delete mode 100644 ricochet/dlls/schedule.h delete mode 100644 ricochet/dlls/scriptevent.h delete mode 100644 ricochet/dlls/singleplay_gamerules.cpp delete mode 100644 ricochet/dlls/skill.cpp delete mode 100644 ricochet/dlls/skill.h delete mode 100644 ricochet/dlls/sound.cpp delete mode 100644 ricochet/dlls/soundent.cpp delete mode 100644 ricochet/dlls/soundent.h delete mode 100644 ricochet/dlls/spectator.cpp delete mode 100644 ricochet/dlls/spectator.h delete mode 100644 ricochet/dlls/subs.cpp delete mode 100644 ricochet/dlls/talkmonster.h delete mode 100644 ricochet/dlls/teamplay_gamerules.cpp delete mode 100644 ricochet/dlls/teamplay_gamerules.h delete mode 100644 ricochet/dlls/trains.h delete mode 100644 ricochet/dlls/triggers.cpp delete mode 100644 ricochet/dlls/util.cpp delete mode 100644 ricochet/dlls/util.h delete mode 100644 ricochet/dlls/vector.h delete mode 100644 ricochet/dlls/weapons.cpp delete mode 100644 ricochet/dlls/weapons.h delete mode 100644 ricochet/dlls/world.cpp delete mode 100644 ricochet/dlls/wpn_shared/disc_weapon_disc.cpp delete mode 100644 ricochet/dlls/xen.cpp delete mode 100644 ricochet/pm_shared/pm_debug.c delete mode 100644 ricochet/pm_shared/pm_debug.h delete mode 100644 ricochet/pm_shared/pm_defs.h delete mode 100644 ricochet/pm_shared/pm_info.h delete mode 100644 ricochet/pm_shared/pm_materials.h delete mode 100644 ricochet/pm_shared/pm_math.c delete mode 100644 ricochet/pm_shared/pm_movevars.h delete mode 100644 ricochet/pm_shared/pm_shared.c delete mode 100644 ricochet/pm_shared/pm_shared.h diff --git a/dmc/cl_dll/CTF_FlagStatus.cpp b/dmc/cl_dll/CTF_FlagStatus.cpp deleted file mode 100644 index b11adcf4..00000000 --- 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 c7d640f7..00000000 --- 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 a6bf4a6d..00000000 --- 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 17107d67..00000000 --- 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 "C" 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 e14a3c7f..00000000 --- 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 cc66e15b..00000000 --- a/dmc/cl_dll/Exports.h +++ /dev/null @@ -1,117 +0,0 @@ -// CL_DLLEXPORT is the client version of dllexport. It's turned off for secure clients. -#ifdef _WIN32 -#define CL_DLLEXPORT __declspec(dllexport) -#else -#define CL_DLLEXPORT __attribute__ ((visibility("default"))) -#endif - -extern "C" -{ - // From hl_weapons - void CL_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 CL_DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ); - int CL_DLLEXPORT HUD_VidInit( void ); - void CL_DLLEXPORT HUD_Init( void ); - int CL_DLLEXPORT HUD_Redraw( float flTime, int intermission ); - int CL_DLLEXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime ); - void CL_DLLEXPORT HUD_Reset ( void ); - void CL_DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ); - void CL_DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ); - char CL_DLLEXPORT HUD_PlayerMoveTexture( char *name ); - int CL_DLLEXPORT HUD_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); - int CL_DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ); - void CL_DLLEXPORT HUD_Frame( double time ); - void CL_DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking); - void CL_DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf ); - void CL_DLLEXPORT HUD_ChatInputPosition( int *x, int *y ); - - // From demo - void CL_DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer ); - - // From entity - int CL_DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void CL_DLLEXPORT HUD_CreateEntities( void ); - void CL_DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); - void CL_DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); - void CL_DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); - void CL_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 CL_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 CL_DLLEXPORT *HUD_GetUserEntity( int index ); - - // From in_camera - void CL_DLLEXPORT CAM_Think( void ); - int CL_DLLEXPORT CL_IsThirdPerson( void ); - void CL_DLLEXPORT CL_CameraOffset( float *ofs ); - - // From input - struct kbutton_s CL_DLLEXPORT *KB_Find( const char *name ); - void CL_DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ); - void CL_DLLEXPORT HUD_Shutdown( void ); - int CL_DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding ); - - // From inputw32 - void CL_DLLEXPORT IN_ActivateMouse( void ); - void CL_DLLEXPORT IN_DeactivateMouse( void ); - void CL_DLLEXPORT IN_MouseEvent (int mstate); - void CL_DLLEXPORT IN_Accumulate (void); - void CL_DLLEXPORT IN_ClearStates (void); - - // From tri - void CL_DLLEXPORT HUD_DrawNormalTriangles( void ); - void CL_DLLEXPORT HUD_DrawTransparentTriangles( void ); - - // From view - void CL_DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams ); - - // From GameStudioModelRenderer - int CL_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 57cc8ce0..00000000 --- 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 EXPORT 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 7d06f70f..00000000 --- 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 a06b231a..00000000 --- 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 = max( 0.0, fElapsed ); - // Don't let time go hugely positive ( first connection to active server ? ) - fElapsed = 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 = 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 = 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 6095566d..00000000 --- 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 8f1427ff..00000000 --- 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 a6077394..00000000 --- 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 = 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 = 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 = 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 = 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) 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 5e44065a..00000000 --- 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 e2a2f591..00000000 --- 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) 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 += 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 bc78dad5..00000000 --- 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 = 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, 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, 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, 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 5da8921d..00000000 --- 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 1c328efb..00000000 --- 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-(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 08c87920..00000000 --- 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 6c4baeeb..00000000 --- a/dmc/cl_dll/cdll_int.cpp +++ /dev/null @@ -1,344 +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" - -#ifdef _WIN32 -#include "winsani_in.h" -#include -#include "winsani_out.h" -#endif - -CSysModule *g_pFileSystemModule = NULL; -IFileSystem *g_pFileSystem = NULL; - -CSysModule *g_hTrackerModule = NULL; - -cl_enginefunc_t gEngfuncs; -CHud gHUD; -TeamFortressViewport *gViewPort = NULL; - -extern "C" -{ -#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 EXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ); -int EXPORT HUD_VidInit( void ); -int EXPORT HUD_Init( void ); -int EXPORT HUD_Redraw( float flTime, int intermission ); -int EXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime ); -int EXPORT HUD_Reset ( void ); -void EXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ); -void EXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ); -char EXPORT HUD_PlayerMoveTexture( char *name ); -int EXPORT HUD_ConnectionlessPacket( struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); -int EXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ); -void EXPORT HUD_Frame( double time ); -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 ); -void EXPORT HUD_VoiceStatus(int entindex, qboolean bTalking); -void EXPORT 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 EXPORT 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 EXPORT 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 EXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ) -{ - PM_Init( ppmove ); -} - -char EXPORT HUD_PlayerMoveTexture( char *name ) -{ - return PM_FindTextureType( name ); -} - -void EXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ) -{ - PM_Move( ppmove, server ); -} - -int EXPORT 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 EXPORT 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 EXPORT HUD_Init( void ) -{ - InitInput(); - gHUD.Init(); - Scheme_Init(); - - return 1; -} - - -/* -========================== - HUD_Redraw - -called every screen frame to -redraw the HUD. -=========================== -*/ - -int EXPORT 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 EXPORT 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 EXPORT HUD_Reset( void ) -{ - gHUD.VidInit(); - return 1; -} - -/* -========================== -HUD_Frame - -Called by engine every frame that client .dll is loaded -========================== -*/ - -void EXPORT HUD_Frame( double time ) -{ - IN_Commands(); - - ServersThink( time ); - - GetClientVoiceMgr()->Frame(time); -} - - -/* -========================== -HUD_VoiceStatus - -Called when a player starts or stops talking. -========================== -*/ - -void EXPORT HUD_VoiceStatus(int entindex, qboolean bTalking) -{ - GetClientVoiceMgr()->UpdateSpeakerStatus(entindex, bTalking); -} - -/* -========================== -HUD_DirectorMessage - -Called when a director event message was received -========================== -*/ - -void EXPORT 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 d64a5144..00000000 --- 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 1422cfa7..00000000 --- a/dmc/cl_dll/cl_dll.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. -* -****/ -// -// 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 -// -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" -#ifdef _WIN32 -#define EXPORT _declspec( dllexport ) -#else -#define EXPORT __attribute__ ((visibility("default"))) -#endif - -#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 33162eca..00000000 --- a/dmc/cl_dll/cl_util.h +++ /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. -* -****/ -// -// cl_util.h -// - -#include "cvardef.h" - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#include // for safe_sprintf() -#include // " -#include // for safe_strcpy() - - -// 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 ); } - -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#define fabs(x) ((x) > 0 ? (x) : 0 - (x)) - -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 27115997..00000000 --- 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 ee51d5bd..00000000 --- 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 ( char* s ) { return 0; } -int stub_PrecacheSound ( 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 2edd6750..00000000 --- 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( char* s ); -int stub_PrecacheSound( 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 086a539f..00000000 --- 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 = 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 a7cb395f..00000000 --- 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 EXPORT 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 EXPORT 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 a220327b..00000000 --- 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 9c1a17a8..00000000 --- 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 EXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void EXPORT HUD_CreateEntities( void ); - void EXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); - void EXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); - void EXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); - void EXPORT 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 EXPORT 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 EXPORT *HUD_GetUserEntity( int index ); -} - -/* -======================== -HUD_AddEntity - Return 0 to filter entity from visible list for rendering -======================== -*/ -int EXPORT 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 EXPORT 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 EXPORT 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 EXPORT 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 EXPORT 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 EXPORT 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 EXPORT 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 EXPORT *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 91384095..00000000 --- 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 2a9b2e4d..00000000 --- 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 - -extern "C" 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 2c5e4ce8..00000000 --- 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 a1708881..00000000 --- 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 5611729a..00000000 --- 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 8578334c..00000000 --- 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 99442677..00000000 --- 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 8d7f6df2..00000000 --- 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 = max(m_fAttackFront, side); - } - else - { - float f = fabs(side); - if (f > 0.3) - m_fAttackRear = max(m_fAttackRear, f); - } - - if (front > 0) - { - if (front > 0.3) - m_fAttackRight = max(m_fAttackRight, front); - } - else - { - float f = fabs(front); - if (f > 0.3) - m_fAttackLeft = 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 * 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 = max( 0, m_fAttackFront - fFade ); - } else - m_fAttackFront = 0; - - if (m_fAttackRight > 0.4) - { - GetPainColor(r,g,b); - shade = a * 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 = max( 0, m_fAttackRight - fFade ); - } else - m_fAttackRight = 0; - - if (m_fAttackRear > 0.4) - { - GetPainColor(r,g,b); - shade = a * 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 = max( 0, m_fAttackRear - fFade ); - } else - m_fAttackRear = 0; - - if (m_fAttackLeft > 0.4) - { - GetPainColor(r,g,b); - shade = a * 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 = 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 = 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 51201038..00000000 --- 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 65fa8524..00000000 --- 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 dd74d36b..00000000 --- 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 f3d9356d..00000000 --- a/dmc/cl_dll/hud_iface.h +++ /dev/null @@ -1,24 +0,0 @@ -//========= Copyright © 1996-2002, Valve LLC, All rights reserved. ============ -// -// Purpose: -// -// $NoKeywords: $ -//============================================================================= - -#if !defined( HUD_IFACEH ) -#define HUD_IFACEH -#pragma once - -#ifdef _WIN32 -#define EXPORT _declspec( dllexport ) -#else -#define EXPORT __attribute__ ((visibility("default"))) -#endif -#define _DLLEXPORT EXPORT - -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 1be43ea0..00000000 --- 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 94fb4365..00000000 --- a/dmc/cl_dll/hud_redraw.cpp +++ /dev/null @@ -1,445 +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" - -#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 = 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 06138ae9..00000000 --- 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 01e94425..00000000 --- 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 73692f46..00000000 --- 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 c043b9ea..00000000 --- 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 "C" int iJumpSpectator; -extern "C" float vJumpOrigin[3]; -extern "C" 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 ); -extern "C" 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 ca57ea85..00000000 --- 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 7f2b2b8b..00000000 --- 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 f5130bce..00000000 --- a/dmc/cl_dll/in_camera.cpp +++ /dev/null @@ -1,598 +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 "Exports.h" - -#include "port.h" - -float CL_KeyState (kbutton_t *key); - -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 MAX_ANGLE_DIFF 10.0 -#define PITCH_MAX 90.0 -#define PITCH_MIN 0 -#define YAW_MAX 135.0 -#define YAW_MIN -135.0 -#define CAM_DIST_MOUSEFAC 0.05 -#define CAM_ANGLE_MOUSEFAC 1.67 - -enum ECAM_Command -{ - CAM_COMMAND_NONE = 0, - CAM_COMMAND_TOTHIRDPERSON = 1, - CAM_COMMAND_TOFIRSTPERSON = 2 -}; - -//-------------------------------------------------- Global Variables - -extern cvar_t *m_pitch; -extern cvar_t *m_yaw; -extern cvar_t *m_forward; -extern cvar_t *m_side; - -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; - -//-------------------------------------------------- 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); - -//-------------------------------------------------- - -// defined in inputw32.cpp: -void IN_GetMouseDelta( int *pOutX, int *pOuty); -void IN_ScaleMouse( float *x, float *y ); - -void CAM_GetScaledMouseDelta( float *pOutX, float *pOutY ) -{ - int x,y; - float fx, fy; - - IN_GetMouseDelta( &x, &y ); - - fx = x; - fy = y; - - IN_ScaleMouse( &fx, &fy ); - - if(pOutX) *pOutX = fx; - if(pOutY) *pOutY = fy; -} - -//-------------------------------------------------- Local Functions - -float MoveToward( float cur, float goal, float maxspeed ) -{ - if( cur != goal ) - { - if( abs( 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 CL_DLLEXPORT CAM_Think( void ) -{ - float cam_mouse_x, cam_mouse_y; - vec3_t origin; - vec3_t ext, pnt, camForward, camRight, camUp; - moveclip_t clip; - float dist; - vec3_t camAngles; -#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 mouse cursor delta - CAM_GetScaledMouseDelta (&cam_mouse_x,&cam_mouse_y); - //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>0) - { - //if ((camAngles[YAW]>=225.0)||(camAngles[YAW]<135.0)) - if (camAngles[YAW]value) - { - camAngles[ YAW ] += CAM_ANGLE_MOUSEFAC * m_yaw->value * cam_mouse_x; - } - if (camAngles[YAW]>c_maxyaw->value) - { - - camAngles[YAW]=c_maxyaw->value; - } - } - else if (cam_mouse_x<0) - { - //if ((camAngles[YAW]<=135.0)||(camAngles[YAW]>225.0)) - if (camAngles[YAW]>c_minyaw->value) - { - camAngles[ YAW ] -= CAM_ANGLE_MOUSEFAC * m_yaw->value * -cam_mouse_x; - - } - 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>0) - { - if(camAngles[PITCH]value) - { - camAngles[PITCH] += CAM_ANGLE_MOUSEFAC * m_pitch->value * cam_mouse_y; - } - if (camAngles[PITCH]>c_maxpitch->value) - { - camAngles[PITCH]=c_maxpitch->value; - } - } - else if (cam_mouse_y<0) - { - if (camAngles[PITCH]>c_minpitch->value) - { - camAngles[PITCH] -= CAM_ANGLE_MOUSEFAC * m_pitch->value * -cam_mouse_y; - } - if (camAngles[PITCH]value) - { - camAngles[PITCH]=c_minpitch->value; - } - } - } - } - - //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>0) - { - if(distvalue) - { - dist += CAM_DIST_MOUSEFAC * m_forward->value * cam_mouse_y; - } - if (dist>c_maxdistance->value) - { - dist=c_maxdistance->value; - } - } - else if (cam_mouse_y<0) - { - if (dist>c_mindistance->value) - { - dist -= CAM_DIST_MOUSEFAC * m_forward->value * -cam_mouse_y; - } - if (distvalue) - { - dist=c_mindistance->value; - } - } - } -#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( abs( 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) -{ - //only move the cam with mouse if we are in third person. - if (cam_thirdperson) - { - //set appropriate flags - if (!cam_mousemove) - { - cam_mousemove=1; - iMouseInUse=1; - } - } - //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 - if (!cam_distancemove) - { - cam_distancemove=1; - cam_mousemove=1; - iMouseInUse=1; - } - } - //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 CL_DLLEXPORT CL_IsThirdPerson( void ) -{ - return cam_thirdperson ? 1 : 0; -} - -void CL_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 19ae0045..00000000 --- a/dmc/cl_dll/in_defs.h +++ /dev/null @@ -1,21 +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 - -#define DLLEXPORT __declspec( dllexport ) - -#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 b4631000..00000000 --- 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 EXPORT *KB_Find( const char *name ); - void EXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ); - void EXPORT HUD_Shutdown( void ); - int EXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding ); -} - -extern int g_weaponselect; -extern cl_enginefunc_t gEngfuncs; - -// Defined in pm_math.c -extern "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 EXPORT *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 EXPORT 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 EXPORT 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 EXPORT 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 f648ff57..00000000 --- a/dmc/cl_dll/inputw32.cpp +++ /dev/null @@ -1,987 +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 "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" - -#include -#include - -#define MOUSE_BUTTON_COUNT 5 - -// use IN_SetVisibleMouse to set: -int 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 = 0; -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 ]; -int 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 ); - } -} - -void IN_SetMouseMode(bool enable) -{ - static bool currentMouseMode = false; - - if(enable == currentMouseMode) - return; - - if(enable) - { -#ifdef _WIN32 - if (mouseparmsvalid) - restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); -#endif - SDL_SetRelativeMouseMode(SDL_TRUE); - - currentMouseMode = true; - } - else - { - SDL_SetRelativeMouseMode(SDL_FALSE); - -#ifdef _WIN32 - if (restore_spi) - SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); -#endif - - currentMouseMode = false; - } -} - -void IN_SetVisibleMouse(bool visible) -{ - iVisibleMouse = visible; - - IN_SetMouseMode(!visible); -} - -void IN_ResetMouse( void ); - -/* -=========== -IN_ActivateMouse -=========== -*/ -void CL_DLLEXPORT IN_ActivateMouse (void) -{ - if (mouseinitialized) - { - IN_SetMouseMode(true); - - mouseactive = 1; - - // now is a good time to reset mouse positon: - IN_ResetMouse(); - } -} - - -/* -=========== -IN_DeactivateMouse -=========== -*/ -void CL_DLLEXPORT IN_DeactivateMouse (void) -{ - if (mouseinitialized) - { - IN_SetMouseMode(false); - - 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 CL_DLLEXPORT IN_MouseEvent (int mstate) -{ - int i; - - if ( iMouseInUse || 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; - } -} - -void IN_GetMouseDelta( int *pOutX, int *pOutY) -{ - bool active = mouseactive && !iVisibleMouse; - int mx, my; - - if(active) - { - 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; - - // reset mouse position if required, so there is room to move: - IN_ResetMouse(); - } - else - { - mx = my = 0; - } - - if(pOutX) *pOutX = mx; - if(pOutY) *pOutY = my; -} - -/* -=========== -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 && !iVisibleMouse ) - { - IN_GetMouseDelta( &mx, &my ); - - if (m_filter && 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; - } - } - } - - 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 CL_DLLEXPORT IN_Accumulate (void) -{ - //only accumulate mouse if we are not moving the camera with the mouse - if ( !iMouseInUse && !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 CL_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]; - - 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(abs(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 23cd8acc..00000000 --- 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 47ed242a..00000000 --- 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, min( ( sptr - ptr), (int)sizeof( menubuf ) )); - menubuf[ 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 b4d81189..00000000 --- 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 fb0d3943..00000000 --- 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 6925bbf9..00000000 --- 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 68c0a82c..00000000 --- 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 a42fdfce..00000000 --- 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, 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 = 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 249205ca..00000000 --- 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 20d30ff7..00000000 --- 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 = min( flScrollTime, flTime + m_HUD_saytext_time->value ); - - // make sure the scrolltime is within reasonable bounds, to guard against the clock being reset - flScrollTime = 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], min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+32) ); - buf[ 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, 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 adfe64d1..00000000 --- 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 = 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 8733dcc9..00000000 --- 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 43ef0612..00000000 --- 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 df5fc4bf..00000000 --- a/dmc/cl_dll/studio_util.cpp +++ /dev/null @@ -1,251 +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" - -/* -==================== -AngleMatrix - -==================== -*/ -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; -} - -/* -==================== -VectorCompare - -==================== -*/ -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; -} - -/* -==================== -CrossProduct - -==================== -*/ -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]; -} - -/* -==================== -VectorTransform - -==================== -*/ -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]; -} - -/* -================ -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]; -} - -// 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 aa8dcf6b..00000000 --- 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 721c2455..00000000 --- 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 0286c689..00000000 --- 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 beff737a..00000000 --- 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 EXPORT HUD_DrawNormalTriangles( void ); - void EXPORT 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 EXPORT HUD_DrawNormalTriangles( void ) -{ - gHUD.m_Spectator.DrawOverview(); -} - -/* -================= -HUD_DrawTransparentTriangles - -Render any triangles with transparent rendermode needs here -================= -*/ -void EXPORT HUD_DrawTransparentTriangles( void ) -{ - - RenderFog(); -} diff --git a/dmc/cl_dll/util.cpp b/dmc/cl_dll/util.cpp deleted file mode 100644 index cf88cd0a..00000000 --- a/dmc/cl_dll/util.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. -* -* 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 "stdio.h" -#include "stdlib.h" -#include "math.h" - -#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 ); - -double sqrt(double x); - -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; -} - -void VectorAngles( const float *forward, float *angles ) -{ - float 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; -} - -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; -} - -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]; -} - - -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 2a7ff204..00000000 --- a/dmc/cl_dll/util.h +++ /dev/null @@ -1,152 +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 ); } - -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#define fabs(x) ((x) > 0 ? (x) : 0 - (x)) - -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 fdac17cc..00000000 --- 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 4c413a0c..00000000 --- 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 9a6beb1e..00000000 --- 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 66d09b48..00000000 --- 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 dddd268c..00000000 --- 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 0e7d99a3..00000000 --- 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 d7fd71ec..00000000 --- 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 = 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 2df04b92..00000000 --- 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 = 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 55b89cd5..00000000 --- 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 = 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 01f56935..00000000 --- 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 e3a85d60..00000000 --- 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 ee1f712c..00000000 --- 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 0f4b9e5a..00000000 --- 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 6510853e..00000000 --- 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 89bc4e67..00000000 --- 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" - -void IN_SetVisibleMouse(bool visible); -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() ) - { - IN_SetVisibleMouse(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 ) - { - IN_SetVisibleMouse(true); - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_arrow) ); - return; - } - } - - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_none) ); - IN_SetVisibleMouse(false); - IN_ResetMouse(); -} - -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 1fcd1569..00000000 --- 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 13dfc869..00000000 --- a/dmc/cl_dll/view.cpp +++ /dev/null @@ -1,1677 +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 EXPORT 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 ); - - float vJumpOrigin[3]; - 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 = min( bob, 4 ); - bob = 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 = 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 = 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 = 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 EXPORT 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 = 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 1afbe38e..00000000 --- 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 f6cda4d3..00000000 --- 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 = 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 8edf58c7..00000000 --- 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 a3494aed..00000000 --- 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 e383cdac..00000000 --- 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 6fd3a188..00000000 --- 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 92cadae7..00000000 --- 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 2da7536c..00000000 --- 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 42707f4d..00000000 --- a/dmc/dlls/animation.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. -* -****/ -#include -#include -#include - -typedef bool BOOL; - -// 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 174bd712..00000000 --- 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 190965d9..00000000 --- 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 e08ffa49..00000000 --- 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 = abs(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 = abs(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 ( abs(vecAVel.x) >= abs(pev->movedir.x * pev->speed) && - abs(vecAVel.y) >= abs(pev->movedir.y * pev->speed) && - abs(vecAVel.z) >= abs(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 5ea927d1..00000000 --- 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 0d5c083f..00000000 --- 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" - -extern "C" void PM_Move ( struct playermove_s *ppmove, int server ); -extern "C" void PM_Init ( struct playermove_s *ppmove ); -extern "C" 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 a26595bd..00000000 --- a/dmc/dlls/cbase.h +++ /dev/null @@ -1,805 +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 - -// C functions for external declarations that call the appropriate C++ methods -#ifndef CBASE_DLLEXPORT -#ifdef _WIN32 -#define CBASE_DLLEXPORT _declspec( dllexport ) -#else -#define CBASE_DLLEXPORT __attribute__ ((visibility("default"))) -#endif -#endif - -#define EXPORT CBASE_DLLEXPORT - -extern "C" CBASE_DLLEXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); -extern "C" CBASE_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 65279fcd..00000000 --- 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 a248f375..00000000 --- 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 = max( gun->m_flTimeWeaponIdle, -0.001 ); - item->m_flNextPrimaryAttack = max( gun->m_flNextPrimaryAttack, -0.001 ); - item->m_flNextSecondaryAttack = 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 1e66cc89..00000000 --- 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 53e3dabf..00000000 --- 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 * 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 95fa44f5..00000000 --- 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 2b231245..00000000 --- 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 652d1085..00000000 --- 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 b455ca11..00000000 --- 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 a02b87cb..00000000 --- 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 9de01f2b..00000000 --- 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 80088615..00000000 --- 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 7c02b408..00000000 --- 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 = min( startPos.x, endPos.x ); - pev->mins.y = min( startPos.y, endPos.y ); - pev->mins.z = min( startPos.z, endPos.z ); - pev->maxs.x = max( startPos.x, endPos.x ); - pev->maxs.y = max( startPos.y, endPos.y ); - pev->maxs.z = 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 = min( startPos.x, endPos.x ); - pev->absmin.y = min( startPos.y, endPos.y ); - pev->absmin.z = min( startPos.z, endPos.z ); - pev->absmax.x = max( startPos.x, endPos.x ); - pev->absmax.y = max( startPos.y, endPos.y ); - pev->absmax.z = 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 f93a9d88..00000000 --- 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 28f31417..00000000 --- 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 4e5f1c15..00000000 --- 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 3feb011c..00000000 --- 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 b9488cdb..00000000 --- a/dmc/dlls/extdll.h +++ /dev/null @@ -1,101 +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 -// - -// Allow "DEBUG" in addition to default "_DEBUG" -#ifdef _DEBUG -#define DEBUG 1 -#endif - -// Silence certain warnings -#pragma warning(disable : 4244) // int or float down-conversion -#pragma warning(disable : 4305) // int or float data truncation -#pragma warning(disable : 4201) // nameless struct/union -#pragma warning(disable : 4514) // unreferenced inline function removed -#pragma warning(disable : 4100) // unreferenced formal parameter - -#ifdef _WIN32 -// Prevent tons of unused windows definitions -#define WIN32_LEAN_AND_MEAN -#define NOWINRES -#define NOSERVICE -#define NOMCX -#define NOIME -#include "winsani_in.h" -#include "windows.h" -#include "winsani_out.h" - -#else // _WIN32 -#define FALSE 0 -#define TRUE (!FALSE) - -typedef uint32 ULONG; -typedef unsigned char BYTE; -typedef int BOOL; - -#define MAX_PATH PATH_MAX - -#include -#include -#include - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#define itoa(a,b,c) sprintf(b, "%d", a) -#define _snprintf snprintf -#define _vsnprintf vsnprintf -#endif //_WIN32 - -// 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 - -// 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 393c86c1..00000000 --- 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) + (abs(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 9bb281d6..00000000 --- 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 20762854..00000000 --- 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 e5148153..00000000 --- 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 e61c3f30..00000000 --- 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 c5da3fcf..00000000 --- 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 7886df4a..00000000 --- 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 ef657c2d..00000000 --- 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 7eabdf83..00000000 --- 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 85a54da7..00000000 --- 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 b4211ab3..00000000 --- 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 e261503e..00000000 --- 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 b94aa63c..00000000 --- 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 6458eeb6..00000000 --- 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 = 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 e9852966..00000000 --- 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 312aa30a..00000000 --- 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 f6d13343..00000000 --- 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] = 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 37720944..00000000 --- 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 46c5624a..00000000 --- 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 f2ff0b49..00000000 --- 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 f7f1a03f..00000000 --- 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 ddc0e70d..00000000 --- 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 cae23d11..00000000 --- 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 = max( item->minplayers, 0 ); - item->minplayers = min( item->minplayers, gpGlobals->maxClients ); - } - s = g_engfuncs.pfnInfoKeyValue( szBuffer, "maxplayers" ); - if ( s && s[0] ) - { - item->maxplayers = atoi( s ); - item->maxplayers = max( item->maxplayers, 0 ); - item->maxplayers = 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 b2bd199b..00000000 --- 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 = max(0, Temp); - Upper = Best; - } - else - { - Upper = 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 = 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 = 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 = 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 = 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 = 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", j ); - } - - 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 %f\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 %f\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 %f\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 269fe420..00000000 --- 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 2fe0ee2e..00000000 --- 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 b2c1e3f5..00000000 --- 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 39a91c32..00000000 --- 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 af70f1cc..00000000 --- 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 73872edd..00000000 --- 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 + (abs(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 58b0d80a..00000000 --- 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 (abs(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 = 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 = max( gun->m_flNextPrimaryAttack - gpGlobals->frametime, -1.0 ); - gun->m_flNextSecondaryAttack = max( gun->m_flNextSecondaryAttack - gpGlobals->frametime, -0.001 ); - - if ( gun->m_flTimeWeaponIdle != 1000 ) - { - gun->m_flTimeWeaponIdle = 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 = 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( max( 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 a9be4209..00000000 --- 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 ff550ff8..00000000 --- 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 a0d16ec5..00000000 --- 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 0d83fe5a..00000000 --- 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 6ef51f49..00000000 --- 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 1a4d6c6b..00000000 --- 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 35269819..00000000 --- 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 d639ecdc..00000000 --- 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 bcca9725..00000000 --- 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 9b15dcfa..00000000 --- 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 82cbdeb7..00000000 --- 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 10659f54..00000000 --- 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 dee12d72..00000000 --- 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 42377cf0..00000000 --- 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 947df3f7..00000000 --- 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 d82a607b..00000000 --- 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 5ec320c2..00000000 --- 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 5d2790ef..00000000 --- a/dmc/dlls/sound.cpp +++ /dev/null @@ -1,1970 +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); - itoa(ipick, sznum, 10); - 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); - itoa(ipick, sznum, 10); - 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); - itoa(ipick, sznum, 10); - 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, "!"); - itoa(i, sznum, 10); - 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 = 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 ffd5786f..00000000 --- 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 150daac7..00000000 --- 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 5f91731e..00000000 --- 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 2f755d6b..00000000 --- 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 d3560bd5..00000000 --- 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 292d7079..00000000 --- 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 f9de3cb8..00000000 --- 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 e2353223..00000000 --- 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 9f7d148b..00000000 --- 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 87aec763..00000000 --- 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 8fbf7340..00000000 --- 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 4a1d347e..00000000 --- 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( 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( min( 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 b4923866..00000000 --- a/dmc/dlls/util.h +++ /dev/null @@ -1,601 +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 - -#ifndef UTIL_DLLEXPORT -#ifdef _WIN32 -#define UTIL_DLLEXPORT _declspec( dllexport ) -#else -#define UTIL_DLLEXPORT __attribute__ ((visibility("default"))) -#endif -#endif - -// Keeps clutter down a bit, when declaring external entity/global method prototypes -#define DECLARE_GLOBAL_METHOD(MethodName) \ - extern void UTIL_DLLEXPORT MethodName( void ) -#define GLOBAL_METHOD(funcname) void UTIL_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" UTIL_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); -typedef 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 9f475b06..00000000 --- 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 13ff03f8..00000000 --- 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 = 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 = 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 = 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 = 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 a3d19d17..00000000 --- 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.c b/dmc/pm_shared/pm_debug.c deleted file mode 100644 index 4d3a2025..00000000 --- a/dmc/pm_shared/pm_debug.c +++ /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 552253fc..00000000 --- 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 a8e4045c..00000000 --- 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 e9cc6d3b..00000000 --- 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 ad9aaacf..00000000 --- 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.c b/dmc/pm_shared/pm_math.c deleted file mode 100644 index 09814f56..00000000 --- a/dmc/pm_shared/pm_math.c +++ /dev/null @@ -1,416 +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) - -#ifndef DISABLE_VEC_ORIGIN -vec3_t vec3_origin = {0,0,0}; -#endif -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 vec3_t 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 vec3_t v1, const vec3_t 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 vec3_t in1, float in2[3][4], vec3_t 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 vec3_t v1, const vec3_t v2) -{ - int i; - - for (i=0 ; i<3 ; i++) - if (v1[i] != v2[i]) - return 0; - - return 1; -} - -void VectorMA (const vec3_t veca, float scale, const vec3_t vecb, vec3_t 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 vec3_t v1, const vec3_t v2, vec3_t 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]; -} - -double sqrt(double x); - -float Length(const vec3_t 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 vec3_t v1, const vec3_t v2) -{ - vec3_t d; - VectorSubtract(v2,v1,d); - return Length(d); -} - -float VectorNormalize (vec3_t 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 (vec3_t v) -{ - v[0] = -v[0]; - v[1] = -v[1]; - v[2] = -v[2]; -} - -void VectorScale (const vec3_t in, vec_t scale, vec3_t 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 vec3_t forward, vec3_t angles ) -{ - float 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; -} diff --git a/dmc/pm_shared/pm_movevars.h b/dmc/pm_shared/pm_movevars.h deleted file mode 100644 index f4f46ca8..00000000 --- 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.c b/dmc/pm_shared/pm_shared.c deleted file mode 100644 index bf1c4913..00000000 --- a/dmc/pm_shared/pm_shared.c +++ /dev/null @@ -1,2798 +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 -#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; - -#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) -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#define min(a, b) (((a) < (b)) ? (a) : (b)) -// 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 = 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 (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 (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 (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 (vec3_origin, pmove->velocity); - break; - } - } - } - - if ( allFraction == 0 ) - { - VectorCopy (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( 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 (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( 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, vec3_origin) && - VectorCompare(pmove->velocity, 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 (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 (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( 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 = 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 = 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 ce8a1c61..00000000 --- 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/linux/Makefile.dmc_cdll b/linux/Makefile.dmc_cdll deleted file mode 100644 index edcfe815..00000000 --- a/linux/Makefile.dmc_cdll +++ /dev/null @@ -1,164 +0,0 @@ -# -# dmc client Makefile for x86 Linux -# -# - -DMC_SRC_DIR=$(SOURCE_DIR)/dmc/cl_dll -GAME_SHARED_SRC_DIR=$(SOURCE_DIR)/game_shared -PM_SHARED_SRC_DIR=$(DMC_SRC_DIR)/../pm_shared - -DMC_OBJ_DIR=$(BUILD_OBJ_DIR)/dmc_client -PUBLIC_OBJ_DIR=$(DMC_OBJ_DIR)/public -COMMON_OBJ_DIR=$(DMC_OBJ_DIR)/common -GAME_SHARED_OBJ_DIR=$(DMC_OBJ_DIR)/game_shared -PM_SHARED_OBJ_DIR=$(DMC_OBJ_DIR)/pm_shared - -CFLAGS=$(BASE_CFLAGS) $(ARCH_CFLAGS) -DCLIENT_DLL -DDMC_BUILD -I/usr/include/malloc -D_snwprintf=swprintf \ - -DDISABLE_JUMP_ORIGIN -DDISABLE_VEC_ORIGIN -D_MAX_PATH=PATH_MAX - -INCLUDEDIRS=-I$(PUBLIC_SRC_DIR) -I../utils/vgui/include -I$(DMC_SRC_DIR)/../dlls \ - -I../engine -I$(COMMON_SRC_DIR) -I../utils/common -I$(DMC_SRC_DIR)/../pm_shared -I$(DMC_SRC_DIR) -I../game_shared -I../external - -ifeq ($(OS),Darwin) -LDFLAGS=$(SHLIBLDFLAGS) $(CPP_LIB) -framework Carbon $(CFG)/vgui.dylib -L. -lSDL2-2.0.0 -else -LDFLAGS=$(SHLIBLDFLAGS) $(CPP_LIB) vgui.so -L. libSDL2-2.0.so.0 -endif - -DO_CC=$(CPLUS) $(INCLUDEDIRS) $(CFLAGS) -o $@ -c $< -DO_PUBLIC_CC=$(CPLUS) $(COMMON_INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< -DO_COMMON_CC=$(CPLUS) $(INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< -DO_PM_SHARED_CC=$(CC) $(INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< - -##################################################################### - -DMC_OBJS = \ - $(DMC_OBJ_DIR)/ev_common.o \ - $(DMC_OBJ_DIR)/CTF_FlagStatus.o \ - $(DMC_OBJ_DIR)/CTF_HudMessage.o \ - $(DMC_OBJ_DIR)/DMC_Teleporters.o \ - $(DMC_OBJ_DIR)/ev_hldm.o \ - $(DMC_OBJ_DIR)/quake/quake_baseentity.o \ - $(DMC_OBJ_DIR)/quake/quake_events.o \ - $(DMC_OBJ_DIR)/quake/quake_objects.o \ - $(DMC_OBJ_DIR)/quake/quake_weapons.o \ - $(DMC_OBJ_DIR)/studio_util.o \ - $(DMC_OBJ_DIR)/vgui_SpectatorPanel.o \ - $(DMC_OBJ_DIR)/ammo.o \ - $(DMC_OBJ_DIR)/ammo_secondary.o \ - $(DMC_OBJ_DIR)/ammohistory.o \ - $(DMC_OBJ_DIR)/battery.o \ - $(DMC_OBJ_DIR)/cdll_int.o \ - $(DMC_OBJ_DIR)/com_weapons.o \ - $(DMC_OBJ_DIR)/death.o \ - $(DMC_OBJ_DIR)/demo.o \ - $(DMC_OBJ_DIR)/entity.o \ - $(DMC_OBJ_DIR)/events.o \ - $(DMC_OBJ_DIR)/GameStudioModelRenderer.o \ - $(DMC_OBJ_DIR)/geiger.o \ - $(DMC_OBJ_DIR)/health.o \ - $(DMC_OBJ_DIR)/hud.o \ - $(DMC_OBJ_DIR)/hud_msg.o \ - $(DMC_OBJ_DIR)/hud_redraw.o \ - $(DMC_OBJ_DIR)/hud_spectator.o \ - $(DMC_OBJ_DIR)/hud_update.o \ - $(DMC_OBJ_DIR)/hud_servers.o \ - $(DMC_OBJ_DIR)/in_camera.o \ - $(DMC_OBJ_DIR)/input.o \ - $(DMC_OBJ_DIR)/inputw32.o \ - $(DMC_OBJ_DIR)/menu.o \ - $(DMC_OBJ_DIR)/message.o \ - $(DMC_OBJ_DIR)/saytext.o \ - $(DMC_OBJ_DIR)/status_icons.o \ - $(DMC_OBJ_DIR)/statusbar.o \ - $(DMC_OBJ_DIR)/StudioModelRenderer.o \ - $(DMC_OBJ_DIR)/text_message.o \ - $(DMC_OBJ_DIR)/train.o \ - $(DMC_OBJ_DIR)/tri.o \ - $(DMC_OBJ_DIR)/util.o \ - $(DMC_OBJ_DIR)/view.o \ - $(DMC_OBJ_DIR)/voice_status.o \ - $(DMC_OBJ_DIR)/vgui_int.o \ - $(DMC_OBJ_DIR)/vgui_ScorePanel.o \ - $(DMC_OBJ_DIR)/vgui_ServerBrowser.o \ - $(DMC_OBJ_DIR)/vgui_viewport.o \ - $(DMC_OBJ_DIR)/vgui_CustomObjects.o \ - $(DMC_OBJ_DIR)/vgui_MOTDWindow.o \ - $(DMC_OBJ_DIR)/vgui_SchemeManager.o \ - $(DMC_OBJ_DIR)/dlls/quake_weapons_all.o \ - $(DMC_OBJ_DIR)/dlls/quake_gun.o \ - - -PUBLIC_OBJS = \ - $(PUBLIC_OBJ_DIR)/interface.o \ - -COMMON_OBJS = \ - $(COMMON_OBJ_DIR)/parsemsg.o \ - -GAME_SHARED_OBJS = \ - $(GAME_SHARED_OBJ_DIR)/voice_banmgr.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_checkbutton2.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_grid.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_helpers.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_listbox.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_loadtga.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_scrollbar2.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_slider2.o \ - -PM_SHARED_OBJS = \ - $(PM_SHARED_OBJ_DIR)/pm_debug.o \ - $(PM_SHARED_OBJ_DIR)/pm_shared.o \ - $(PM_SHARED_OBJ_DIR)/pm_math.o \ - - -all: client_dmc.$(SHLIBEXT) - -client_dmc.$(SHLIBEXT): $(DMC_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(GAME_SHARED_OBJS) $(PM_SHARED_OBJS) - $(CLINK) -o $(BUILD_DIR)/$@ $(DMC_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(GAME_SHARED_OBJS) $(PM_SHARED_OBJS) $(LDFLAGS) $(CPP_LIB) - p4 edit ../../game/mod/cl_dlls/client.$(SHLIBEXT) - cp $(BUILD_DIR)/$@ ../../game/mod/cl_dlls/client.$(SHLIBEXT) - ./gendbg.sh ../../game/mod/cl_dlls/client.$(SHLIBEXT) - - -$(DMC_OBJ_DIR): - mkdir -p $(DMC_OBJ_DIR) - mkdir -p $(DMC_OBJ_DIR)/dlls - mkdir -p $(DMC_OBJ_DIR)/quake - -$(PUBLIC_OBJ_DIR): - mkdir -p $(PUBLIC_OBJ_DIR) - -$(COMMON_OBJ_DIR): - mkdir -p $(COMMON_OBJ_DIR) - -$(GAME_SHARED_OBJ_DIR): - mkdir -p $(GAME_SHARED_OBJ_DIR) - -$(PM_SHARED_OBJ_DIR): - mkdir -p $(PM_SHARED_OBJ_DIR) - -$(DMC_OBJ_DIR)/%.o: $(DMC_SRC_DIR)/%.cpp $(filter-out $(wildcard $(DMC_OBJ_DIR)), $(DMC_OBJ_DIR)) - $(DO_CC) - -$(DMC_OBJ_DIR)/%.o: $(DMC_SRC_DIR)/../%.cpp $(filter-out $(wildcard $(DMC_OBJ_DIR)), $(DMC_OBJ_DIR)) - $(DO_CC) - -$(DMC_OBJ_DIR)/%.o: $(DMC_SRC_DIR)/quake/%.cpp $(filter-out $(wildcard $(DMC_OBJ_DIR)), $(DMC_OBJ_DIR)) - $(DO_CC) - -$(PUBLIC_OBJ_DIR)/%.o : $(PUBLIC_SRC_DIR)/%.cpp $(filter-out $(wildcard $(PUBLIC_OBJ_DIR)), $(PUBLIC_OBJ_DIR)) - $(DO_PUBLIC_CC) - -$(COMMON_OBJ_DIR)/%.o : $(COMMON_SRC_DIR)/%.cpp $(filter-out $(wildcard $(COMMON_OBJ_DIR)), $(COMMON_OBJ_DIR)) - $(DO_COMMON_CC) - -$(GAME_SHARED_OBJ_DIR)/%.o : $(GAME_SHARED_SRC_DIR)/%.cpp $(filter-out $(wildcard $(GAME_SHARED_OBJ_DIR)), $(GAME_SHARED_OBJ_DIR)) - $(DO_COMMON_CC) - -$(PM_SHARED_OBJ_DIR)/%.o : $(PM_SHARED_SRC_DIR)/%.c $(filter-out $(wildcard $(PM_SHARED_OBJ_DIR)), $(PM_SHARED_OBJ_DIR)) - $(DO_PM_SHARED_CC) - - -clean: - -rm -rf $(DMC_OBJ_DIR) - -rm -f client.$(SHLIBEXT) diff --git a/linux/Makefile.dmcdll b/linux/Makefile.dmcdll deleted file mode 100644 index 8d7aa6e0..00000000 --- a/linux/Makefile.dmcdll +++ /dev/null @@ -1,114 +0,0 @@ -# -# DMC game library Makefile for x86 Linux -# -# May 2001 by Leon Hartwig (hartwig@valvesoftware.com) -# -OS:=$(shell uname) - -DMCDLL_SRC_DIR=$(SOURCE_DIR)/dmc/dlls -PM_SRC_DIR=$(SOURCE_DIR)/dmc/pm_shared - -DMCDLL_OBJ_DIR=$(BUILD_OBJ_DIR)/dmcdll -PM_OBJ_DIR=$(DMCDLL_OBJ_DIR)/pm_shared -GAME_SHARED_OBJ_DIR=$(DMCDLL_OBJ_DIR)/game_shared - -#full optimization -CFLAGS=$(BASE_CFLAGS) $(ARCH_CFLAGS) - -DMCDLL_INCLUDEDIRS=-I$(ENGINE_SRC_DIR) -I$(COMMON_SRC_DIR) -I$(PM_SRC_DIR) -I$(GAME_SHARED_SRC_DIR) -I$(PUBLIC_SRC_DIR) -PM_INCLUDEDIRS=-I$(COMMON_SRC_DIR) -I$(PUBLIC_SRC_DIR) -GAME_SHARED_INCLUDEDIRS=-I$(DMCDLL_SRC_DIR) -I$(ENGINE_SRC_DIR) -I$(COMMON_SRC_DIR) -I$(PUBLIC_SRC_DIR) - -LDFLAGS= - -DO_DMCDLL_CC=$(CC) $(DMCDLL_INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< -DO_PM_CC=$(CC) $(PM_INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< -DO_GAME_SHARED_CC=$(CC) $(GAME_SHARED_INCLUDEDIRS) $(CFLAGS) $(SHLIBFLAGS) -o $@ -c $< - -############################################################################# - -DMCDLL_OBJS = \ - $(DMCDLL_OBJ_DIR)/animating.o \ - $(DMCDLL_OBJ_DIR)/animation.o \ - $(DMCDLL_OBJ_DIR)/bmodels.o \ - $(DMCDLL_OBJ_DIR)/buttons.o \ - $(DMCDLL_OBJ_DIR)/cbase.o \ - $(DMCDLL_OBJ_DIR)/client.o \ - $(DMCDLL_OBJ_DIR)/combat.o \ - $(DMCDLL_OBJ_DIR)/doors.o \ - $(DMCDLL_OBJ_DIR)/effects.o \ - $(DMCDLL_OBJ_DIR)/explode.o \ - $(DMCDLL_OBJ_DIR)/func_break.o \ - $(DMCDLL_OBJ_DIR)/func_tank.o \ - $(DMCDLL_OBJ_DIR)/game.o \ - $(DMCDLL_OBJ_DIR)/gamerules.o \ - $(DMCDLL_OBJ_DIR)/globals.o \ - $(DMCDLL_OBJ_DIR)/h_ai.o \ - $(DMCDLL_OBJ_DIR)/h_export.o \ - $(DMCDLL_OBJ_DIR)/lights.o \ - $(DMCDLL_OBJ_DIR)/maprules.o \ - $(DMCDLL_OBJ_DIR)/monsters.o \ - $(DMCDLL_OBJ_DIR)/monsterstate.o \ - $(DMCDLL_OBJ_DIR)/multiplay_gamerules.o \ - $(DMCDLL_OBJ_DIR)/nodes.o \ - $(DMCDLL_OBJ_DIR)/observer.o \ - $(DMCDLL_OBJ_DIR)/pathcorner.o \ - $(DMCDLL_OBJ_DIR)/plane.o \ - $(DMCDLL_OBJ_DIR)/plats.o \ - $(DMCDLL_OBJ_DIR)/player.o \ - $(DMCDLL_OBJ_DIR)/quake_gun.o \ - $(DMCDLL_OBJ_DIR)/quake_items.o \ - $(DMCDLL_OBJ_DIR)/quake_nail.o \ - $(DMCDLL_OBJ_DIR)/quake_player.o \ - $(DMCDLL_OBJ_DIR)/quake_rocket.o \ - $(DMCDLL_OBJ_DIR)/quake_weapons_all.o \ - $(DMCDLL_OBJ_DIR)/schedule.o \ - $(DMCDLL_OBJ_DIR)/singleplay_gamerules.o \ - $(DMCDLL_OBJ_DIR)/skill.o \ - $(DMCDLL_OBJ_DIR)/sound.o \ - $(DMCDLL_OBJ_DIR)/spectator.o \ - $(DMCDLL_OBJ_DIR)/subs.o \ - $(DMCDLL_OBJ_DIR)/teamplay_gamerules.o \ - $(DMCDLL_OBJ_DIR)/threewave_gamerules.o \ - $(DMCDLL_OBJ_DIR)/triggers.o \ - $(DMCDLL_OBJ_DIR)/util.o \ - $(DMCDLL_OBJ_DIR)/weapons.o \ - $(DMCDLL_OBJ_DIR)/world.o - -PM_OBJS = \ - $(PM_OBJ_DIR)/pm_shared.o \ - $(PM_OBJ_DIR)/pm_math.o \ - $(PM_OBJ_DIR)/pm_debug.o - -GAME_SHARED_OBJS = \ - $(GAME_SHARED_OBJ_DIR)/voice_gamemgr.o - -all: dirs dmc.$(SHLIBEXT) - -dirs: - -mkdir $(BUILD_OBJ_DIR) - -mkdir $(DMCDLL_OBJ_DIR) - -mkdir $(PM_OBJ_DIR) - -mkdir $(GAME_SHARED_OBJ_DIR) - -dmc.$(SHLIBEXT): $(DMCDLL_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) - $(CLINK) $(SHLIBLDFLAGS) -o $(BUILD_DIR)/$@ $(DMCDLL_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) $(LDFLAGS) $(CPP_LIB) - p4 edit ../../game/mod/dlls/$@ - cp $(BUILD_DIR)/$@ ../../game/mod/dlls - ./gendbg.sh ../../game/mod/dlls/dmc.$(SHLIBEXT) - -$(DMCDLL_OBJ_DIR)/%.o : $(DMCDLL_SRC_DIR)/%.cpp - $(DO_DMCDLL_CC) - -$(PM_OBJ_DIR)/%.o : $(PM_SRC_DIR)/%.c - $(DO_PM_CC) - -$(GAME_SHARED_OBJ_DIR)/%.o : $(GAME_SHARED_SRC_DIR)/%.cpp - $(DO_GAME_SHARED_CC) - -clean: - -rm -rf $(GAME_SHARED_OBJ_DIR) - -rm -rf $(PM_OBJ_DIR) - -rm -rf $(DMCDLL_OBJ_DIR) - -rm -f dmc_$(ARCH).$(SHLIBEXT) - diff --git a/linux/Makefile.ricochet_cdll b/linux/Makefile.ricochet_cdll deleted file mode 100644 index 80b7df3f..00000000 --- a/linux/Makefile.ricochet_cdll +++ /dev/null @@ -1,163 +0,0 @@ -# -# ricochet client Makefile for x86 Linux -# -# - -RICOCHET_SRC_DIR=$(SOURCE_DIR)/ricochet/cl_dll -GAME_SHARED_SRC_DIR=$(SOURCE_DIR)/game_shared -PM_SHARED_SRC_DIR=$(RICOCHET_SRC_DIR)/../pm_shared - -RICOCHET_OBJ_DIR=$(BUILD_OBJ_DIR)/ricochet_client -PUBLIC_OBJ_DIR=$(RICOCHET_OBJ_DIR)/public -COMMON_OBJ_DIR=$(RICOCHET_OBJ_DIR)/common -GAME_SHARED_OBJ_DIR=$(RICOCHET_OBJ_DIR)/game_shared -PM_SHARED_OBJ_DIR=$(RICOCHET_OBJ_DIR)/pm_shared - -CFLAGS=$(BASE_CFLAGS) $(ARCH_CFLAGS) -DCLIENT_DLL -I/usr/include/malloc -D_snwprintf=swprintf \ - -DDISABLE_JUMP_ORIGIN -DDISABLE_VEC_ORIGIN -D_MAX_PATH=PATH_MAX - -INCLUDEDIRS=-I$(RICOCHET_SRC_DIR) -I$(RICOCHET_SRC_DIR)/../dlls -I../engine -I$(PUBLIC_SRC_DIR) -I$(COMMON_SRC_DIR) \ - -I../game_shared -I$(RICOCHET_SRC_DIR)/../pm_shared -I../utils/vgui/include -I../utils/common -I../external - -ifeq ($(OS),Darwin) -LDFLAGS=$(SHLIBLDFLAGS) $(CPP_LIB) -framework Carbon $(CFG)/vgui.dylib -L. -lSDL2-2.0.0 -else -LDFLAGS=$(SHLIBLDFLAGS) $(CPP_LIB) vgui.so -L. libSDL2-2.0.so.0 -endif - -DO_CC=$(CPLUS) $(INCLUDEDIRS) $(CFLAGS) -o $@ -c $< -DO_PUBLIC_CC=$(CPLUS) $(COMMON_INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< -DO_COMMON_CC=$(CPLUS) $(INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< -DO_PM_SHARED_CC=$(CC) $(INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< - -##################################################################### - -RICOCHET_OBJS = \ - $(RICOCHET_OBJ_DIR)/ev_common.o \ - $(RICOCHET_OBJ_DIR)/ev_hldm.o \ - $(RICOCHET_OBJ_DIR)/hl/hl_baseentity.o \ - $(RICOCHET_OBJ_DIR)/hl/hl_events.o \ - $(RICOCHET_OBJ_DIR)/hl/hl_objects.o \ - $(RICOCHET_OBJ_DIR)/hl/hl_weapons.o \ - $(RICOCHET_OBJ_DIR)/disc_weapon_disc.o \ - $(RICOCHET_OBJ_DIR)/Ricochet_JumpPads.o \ - $(RICOCHET_OBJ_DIR)/ammo.o \ - $(RICOCHET_OBJ_DIR)/ammo_secondary.o \ - $(RICOCHET_OBJ_DIR)/ammohistory.o \ - $(RICOCHET_OBJ_DIR)/battery.o \ - $(RICOCHET_OBJ_DIR)/cdll_int.o \ - $(RICOCHET_OBJ_DIR)/com_weapons.o \ - $(RICOCHET_OBJ_DIR)/death.o \ - $(RICOCHET_OBJ_DIR)/demo.o \ - $(RICOCHET_OBJ_DIR)/entity.o \ - $(RICOCHET_OBJ_DIR)/events.o \ - $(RICOCHET_OBJ_DIR)/flashlight.o \ - $(RICOCHET_OBJ_DIR)/GameStudioModelRenderer.o \ - $(RICOCHET_OBJ_DIR)/geiger.o \ - $(RICOCHET_OBJ_DIR)/health.o \ - $(RICOCHET_OBJ_DIR)/hud.o \ - $(RICOCHET_OBJ_DIR)/hud_msg.o \ - $(RICOCHET_OBJ_DIR)/hud_redraw.o \ - $(RICOCHET_OBJ_DIR)/hud_servers.o \ - $(RICOCHET_OBJ_DIR)/hud_update.o \ - $(RICOCHET_OBJ_DIR)/in_camera.o \ - $(RICOCHET_OBJ_DIR)/input.o \ - $(RICOCHET_OBJ_DIR)/inputw32.o \ - $(RICOCHET_OBJ_DIR)/menu.o \ - $(RICOCHET_OBJ_DIR)/message.o \ - $(RICOCHET_OBJ_DIR)/saytext.o \ - $(RICOCHET_OBJ_DIR)/status_icons.o \ - $(RICOCHET_OBJ_DIR)/statusbar.o \ - $(RICOCHET_OBJ_DIR)/StudioModelRenderer.o \ - $(RICOCHET_OBJ_DIR)/text_message.o \ - $(RICOCHET_OBJ_DIR)/train.o \ - $(RICOCHET_OBJ_DIR)/tri.o \ - $(RICOCHET_OBJ_DIR)/util.o \ - $(RICOCHET_OBJ_DIR)/view.o \ - $(RICOCHET_OBJ_DIR)/vgui_int.o \ - $(RICOCHET_OBJ_DIR)/vgui_ConsolePanel.o \ - $(RICOCHET_OBJ_DIR)/vgui_ControlConfigPanel.o \ - $(RICOCHET_OBJ_DIR)/vgui_CustomObjects.o \ - $(RICOCHET_OBJ_DIR)/vgui_discobjects.o \ - $(RICOCHET_OBJ_DIR)/vgui_MOTDWindow.o \ - $(RICOCHET_OBJ_DIR)/vgui_ScorePanel.o \ - $(RICOCHET_OBJ_DIR)/vgui_ServerBrowser.o \ - $(RICOCHET_OBJ_DIR)/vgui_TeamFortressViewport.o \ - $(RICOCHET_OBJ_DIR)/vgui_SchemeManager.o \ - $(RICOCHET_OBJ_DIR)/studio_util.o \ - $(RICOCHET_OBJ_DIR)/voice_status.o \ - -PUBLIC_OBJS = \ - $(PUBLIC_OBJ_DIR)/interface.o \ - -COMMON_OBJS = \ - $(COMMON_OBJ_DIR)/parsemsg.o \ - -GAME_SHARED_OBJS = \ - $(GAME_SHARED_OBJ_DIR)/voice_banmgr.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_checkbutton2.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_grid.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_helpers.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_listbox.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_loadtga.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_scrollbar2.o \ - $(GAME_SHARED_OBJ_DIR)/vgui_slider2.o \ -# $(GAME_SHARED_OBJ_DIR)/voice_status.o \ - -PM_SHARED_OBJS = \ - $(PM_SHARED_OBJ_DIR)/pm_debug.o \ - $(PM_SHARED_OBJ_DIR)/pm_shared.o \ - $(PM_SHARED_OBJ_DIR)/pm_math.o \ - - -all: client_ricochet.$(SHLIBEXT) - -client_ricochet.$(SHLIBEXT): $(RICOCHET_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(GAME_SHARED_OBJS) $(PM_SHARED_OBJS) - $(CLINK) -o $(BUILD_DIR)/$@ $(RICOCHET_OBJS) $(PUBLIC_OBJS) $(COMMON_OBJS) $(GAME_SHARED_OBJS) $(PM_SHARED_OBJS) $(LDFLAGS) $(CPP_LIB) - p4 edit ../../game/mod/cl_dlls/client.$(SHLIBEXT) - cp $(BUILD_DIR)/$@ ../../game/mod/cl_dlls/client.$(SHLIBEXT) - ./gendbg.sh ../../game/mod/cl_dlls/client.$(SHLIBEXT) - -$(RICOCHET_OBJ_DIR): - mkdir -p $(RICOCHET_OBJ_DIR) - mkdir -p $(RICOCHET_OBJ_DIR)/dlls - mkdir -p $(RICOCHET_OBJ_DIR)/dlls/wpn_shared - mkdir -p $(RICOCHET_OBJ_DIR)/hl - -$(PUBLIC_OBJ_DIR): - mkdir -p $(PUBLIC_OBJ_DIR) - -$(COMMON_OBJ_DIR): - mkdir -p $(COMMON_OBJ_DIR) - -$(GAME_SHARED_OBJ_DIR): - mkdir -p $(GAME_SHARED_OBJ_DIR) - -$(PM_SHARED_OBJ_DIR): - mkdir -p $(PM_SHARED_OBJ_DIR) - -$(RICOCHET_OBJ_DIR)/%.o: $(RICOCHET_SRC_DIR)/%.cpp $(filter-out $(wildcard $(RICOCHET_OBJ_DIR)), $(RICOCHET_OBJ_DIR)) - $(DO_CC) - -$(RICOCHET_OBJ_DIR)/%.o: $(RICOCHET_SRC_DIR)/hl/%.cpp $(filter-out $(wildcard $(RICOCHET_OBJ_DIR)), $(RICOCHET_OBJ_DIR)) - $(DO_CC) - -$(RICOCHET_OBJ_DIR)/%.o: $(RICOCHET_SRC_DIR)/../dlls/wpn_shared/%.cpp $(filter-out $(wildcard $(RICOCHET_OBJ_DIR)), $(RICOCHET_OBJ_DIR)) - $(DO_CC) - -$(PUBLIC_OBJ_DIR)/%.o : $(PUBLIC_SRC_DIR)/%.cpp $(filter-out $(wildcard $(PUBLIC_OBJ_DIR)), $(PUBLIC_OBJ_DIR)) - $(DO_PUBLIC_CC) - -$(COMMON_OBJ_DIR)/%.o : $(COMMON_SRC_DIR)/%.cpp $(filter-out $(wildcard $(COMMON_OBJ_DIR)), $(COMMON_OBJ_DIR)) - $(DO_COMMON_CC) - -$(GAME_SHARED_OBJ_DIR)/%.o : $(GAME_SHARED_SRC_DIR)/%.cpp $(filter-out $(wildcard $(GAME_SHARED_OBJ_DIR)), $(GAME_SHARED_OBJ_DIR)) - $(DO_COMMON_CC) - -$(PM_SHARED_OBJ_DIR)/%.o : $(PM_SHARED_SRC_DIR)/%.c $(filter-out $(wildcard $(PM_SHARED_OBJ_DIR)), $(PM_SHARED_OBJ_DIR)) - $(DO_PM_SHARED_CC) - - -clean: - -rm -rf $(RICOCHET_OBJ_DIR) - -rm -f client_ricochet.$(SHLIBEXT) diff --git a/linux/Makefile.ricochetdll b/linux/Makefile.ricochetdll deleted file mode 100644 index 4a422c6c..00000000 --- a/linux/Makefile.ricochetdll +++ /dev/null @@ -1,128 +0,0 @@ -# -# Ricochet game library Makefile for x86 Linux -# -# June 2001 by Leon Hartwig (hartwig@valvesoftware.com) -# -OS:=$(shell uname) - -RICOCHETDLL_SRC_DIR=$(SOURCE_DIR)/ricochet/dlls -RICOCHETWPN_SRC_DIR=$(RICOCHETDLL_SRC_DIR)/wpn_shared -PM_SRC_DIR=$(SOURCE_DIR)/ricochet/pm_shared - -RICOCHETDLL_OBJ_DIR=$(BUILD_OBJ_DIR)/ricochetdll -RICOCHETWPN_OBJ_DIR=$(RICOCHETDLL_OBJ_DIR)/wpn_shared -PM_OBJ_DIR=$(RICOCHETDLL_OBJ_DIR)/pm_shared -GAME_SHARED_OBJ_DIR=$(RICOCHETDLL_OBJ_DIR)/game_shared - -#CFLAGS=$(BASE_CFLAGS) -g -CFLAGS=$(BASE_CFLAGS) -O3 -ffast-math -fno-strength-reduce - -RICOCHETDLL_INCLUDEDIRS=-I$(ENGINE_SRC_DIR) -I$(COMMON_SRC_DIR) -I$(PM_SRC_DIR) -I$(GAME_SHARED_SRC_DIR) -I$(PUBLIC_SRC_DIR) -RICOCHETWPN_INCLUDEDIRS=-I$(RICOCHETDLL_SRC_DIR) -I$(ENGINE_SRC_DIR) -I$(COMMON_SRC_DIR) -I$(PM_SRC_DIR) -I$(PUBLIC_SRC_DIR) -PM_INCLUDEDIRS=-I$(COMMON_SRC_DIR) -I$(PUBLIC_SRC_DIR) -GAME_SHARED_INCLUDEDIRS=-I$(RICOCHETDLL_SRC_DIR) -I$(ENGINE_SRC_DIR) -I$(COMMON_SRC_DIR) -I$(PUBLIC_SRC_DIR) - -LDFLAGS= - -DO_RICOCHETDLL_CC=$(CC) $(RICOCHETDLL_INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< -DO_RICOCHETWPN_CC=$(CC) $(RICOCHETWPN_INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< -DO_PM_CC=$(CC) $(PM_INCLUDEDIRS) $(CFLAGS) $(SHLIBCFLAGS) -o $@ -c $< -DO_GAME_SHARED_CC=$(CC) $(GAME_SHARED_INCLUDEDIRS) $(CFLAGS) $(SHLIBFLAGS) -o $@ -c $< - -##################################################################### - -RICOCHETDLL_OBJS = \ - $(RICOCHETDLL_OBJ_DIR)/airtank.o \ - $(RICOCHETDLL_OBJ_DIR)/animating.o \ - $(RICOCHETDLL_OBJ_DIR)/animation.o \ - $(RICOCHETDLL_OBJ_DIR)/bmodels.o \ - $(RICOCHETDLL_OBJ_DIR)/buttons.o \ - $(RICOCHETDLL_OBJ_DIR)/cbase.o \ - $(RICOCHETDLL_OBJ_DIR)/client.o \ - $(RICOCHETDLL_OBJ_DIR)/combat.o \ - $(RICOCHETDLL_OBJ_DIR)/disc_arena.o \ - $(RICOCHETDLL_OBJ_DIR)/disc_powerups.o \ - $(RICOCHETDLL_OBJ_DIR)/doors.o \ - $(RICOCHETDLL_OBJ_DIR)/effects.o \ - $(RICOCHETDLL_OBJ_DIR)/explode.o \ - $(RICOCHETDLL_OBJ_DIR)/func_break.o \ - $(RICOCHETDLL_OBJ_DIR)/func_tank.o \ - $(RICOCHETDLL_OBJ_DIR)/game.o \ - $(RICOCHETDLL_OBJ_DIR)/gamerules.o \ - $(RICOCHETDLL_OBJ_DIR)/ggrenade.o \ - $(RICOCHETDLL_OBJ_DIR)/globals.o \ - $(RICOCHETDLL_OBJ_DIR)/h_ai.o \ - $(RICOCHETDLL_OBJ_DIR)/h_battery.o \ - $(RICOCHETDLL_OBJ_DIR)/h_cycler.o \ - $(RICOCHETDLL_OBJ_DIR)/h_export.o \ - $(RICOCHETDLL_OBJ_DIR)/healthkit.o \ - $(RICOCHETDLL_OBJ_DIR)/items.o \ - $(RICOCHETDLL_OBJ_DIR)/lights.o \ - $(RICOCHETDLL_OBJ_DIR)/maprules.o \ - $(RICOCHETDLL_OBJ_DIR)/mortar.o \ - $(RICOCHETDLL_OBJ_DIR)/mpstubb.o \ - $(RICOCHETDLL_OBJ_DIR)/multiplay_gamerules.o \ - $(RICOCHETDLL_OBJ_DIR)/observer.o \ - $(RICOCHETDLL_OBJ_DIR)/pathcorner.o \ - $(RICOCHETDLL_OBJ_DIR)/plane.o \ - $(RICOCHETDLL_OBJ_DIR)/plats.o \ - $(RICOCHETDLL_OBJ_DIR)/player.o \ - $(RICOCHETDLL_OBJ_DIR)/singleplay_gamerules.o \ - $(RICOCHETDLL_OBJ_DIR)/skill.o \ - $(RICOCHETDLL_OBJ_DIR)/sound.o \ - $(RICOCHETDLL_OBJ_DIR)/soundent.o \ - $(RICOCHETDLL_OBJ_DIR)/spectator.o \ - $(RICOCHETDLL_OBJ_DIR)/subs.o \ - $(RICOCHETDLL_OBJ_DIR)/teamplay_gamerules.o \ - $(RICOCHETDLL_OBJ_DIR)/triggers.o \ - $(RICOCHETDLL_OBJ_DIR)/util.o \ - $(RICOCHETDLL_OBJ_DIR)/weapons.o \ - $(RICOCHETDLL_OBJ_DIR)/world.o \ - $(RICOCHETDLL_OBJ_DIR)/xen.o - -RICOCHETWPN_OBJS = \ - $(RICOCHETWPN_OBJ_DIR)/disc_weapon_disc.o - -PM_OBJS = \ - $(PM_OBJ_DIR)/pm_shared.o \ - $(PM_OBJ_DIR)/pm_math.o \ - $(PM_OBJ_DIR)/pm_debug.o - -GAME_SHARED_OBJS = \ - $(GAME_SHARED_OBJ_DIR)/voice_gamemgr.o - -all: dirs ricochet.$(SHLIBEXT) - -dirs: - -mkdir $(BUILD_OBJ_DIR) - -mkdir $(RICOCHETDLL_OBJ_DIR) - -mkdir $(RICOCHETWPN_OBJ_DIR) - -mkdir $(PM_OBJ_DIR) - -mkdir $(GAME_SHARED_OBJ_DIR) - -ricochet.$(SHLIBEXT): $(RICOCHETDLL_OBJS) $(RICOCHETWPN_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) - $(CLINK) $(SHLIBLDFLAGS) -o $(BUILD_DIR)/$@ $(RICOCHETDLL_OBJS) $(RICOCHETWPN_OBJS) $(PM_OBJS) $(GAME_SHARED_OBJS) $(LDFLAGS) $(CPP_LIB) - p4 edit ../../game/mod/dlls/$@ - cp $(BUILD_DIR)/$@ ../../game/mod/dlls - ./gendbg.sh ../../game/mod/dlls/$@ - -$(RICOCHETWPN_OBJ_DIR)/%.o : $(RICOCHETWPN_SRC_DIR)/%.cpp - $(DO_RICOCHETWPN_CC) - -$(RICOCHETDLL_OBJ_DIR)/%.o : $(RICOCHETDLL_SRC_DIR)/%.cpp - $(DO_RICOCHETDLL_CC) - -$(PM_OBJ_DIR)/%.o : $(PM_SRC_DIR)/%.c - $(DO_PM_CC) - -$(GAME_SHARED_OBJ_DIR)/%.o : $(GAME_SHARED_SRC_DIR)/%.cpp - $(DO_GAME_SHARED_CC) - -clean: - -rm -rf $(GAME_SHARED_OBJ_DIR) - -rm -rf $(PM_OBJ_DIR) - -rm -rf $(RICOCHETWPN_OBJ_DIR) - -rm -rf $(RICOCHETDLL_OBJ_DIR) - -rm -f ricochet_$(ARCH).$(SHLIBEXT) - -rm -f ricochet.$(SHLIBEXT) - diff --git a/projects/vs2010/dmc_cdll.vcxproj b/projects/vs2010/dmc_cdll.vcxproj deleted file mode 100644 index dd0fd6ca..00000000 --- a/projects/vs2010/dmc_cdll.vcxproj +++ /dev/null @@ -1,229 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {50BD4CD5-4043-4457-BA51-7CF8FFC43767} - Win32Proj - dmc_cdll - 10.0.16299.0 - - - - DynamicLibrary - true - NotSet - v141 - - - DynamicLibrary - false - true - NotSet - v141 - - - - - - - - - - - - - true - $(Configuration)\$(ProjectName)\ - client - $(Configuration)\$(ProjectName)\int\ - - - false - $(Configuration)\$(ProjectName)\ - client - $(Configuration)\$(ProjectName)\int\ - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;CLIENT_DLL;DMC_BUILD;%(PreprocessorDefinitions) - MultiThreadedDebug - ..\..\public;..\..\dmc\dlls;..\..\engine;..\..\common;..\..\dmc\pm_shared;..\..\utils\vgui\include;..\..\dmc\cl_dll;..\..\game_shared;..\..\external;%(AdditionalIncludeDirectories) - - - Windows - true - ..\..\utils\vgui\lib\win32_vc6\vgui.lib;wsock32.lib;..\..\lib\public\sdl2.lib;%(AdditionalDependencies) - - - - - call ..\..\filecopy.bat $(TargetPath) ..\..\..\game\mod\cl_dlls\$(TargetName).dll -call ..\..\filecopy.bat $(TargetDir)\$(TargetName).pdb ..\..\..\game\mod\cl_dlls\$(TargetName).pdb - - - Performing Post-Build Event - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;CLIENT_DLL;DMC_BUILD;%(PreprocessorDefinitions) - MultiThreaded - ..\..\public;..\..\dmc\dlls;..\..\engine;..\..\common;..\..\dmc\pm_shared;..\..\utils\vgui\include;..\..\dmc\cl_dll;..\..\game_shared;..\..\external;%(AdditionalIncludeDirectories) - - - Windows - true - true - true - ..\..\utils\vgui\lib\win32_vc6\vgui.lib;wsock32.lib;..\..\lib\public\sdl2.lib;%(AdditionalDependencies) - - - - - call ..\..\filecopy.bat $(TargetPath) ..\..\..\game\mod\cl_dlls\$(TargetName).dll -call ..\..\filecopy.bat $(TargetDir)\$(TargetName).pdb ..\..\..\game\mod\cl_dlls\$(TargetName).pdb - - - Performing Post-Build Event - - - - - - \ No newline at end of file diff --git a/projects/vs2010/dmc_cdll.vcxproj.filters b/projects/vs2010/dmc_cdll.vcxproj.filters deleted file mode 100644 index b5b10897..00000000 --- a/projects/vs2010/dmc_cdll.vcxproj.filters +++ /dev/null @@ -1,411 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {ba2e92e5-2bf1-4a18-bfe8-9bc0a15c543c} - - - {86d90742-ec24-48ae-b07e-3df59ef6a396} - - - {a5a4b4d3-85ff-47c2-bc80-2ff5a63bc0b9} - - - {4c151355-546d-4443-84c4-1ba971369673} - - - {be83ab2d-f1d8-460a-9305-a04d3d10a47c} - - - {4bf24b6f-ef41-4f61-b6b0-ce72c3f73024} - - - {31fcf31c-1923-42b1-b9fe-01999692a141} - - - {841cb2e7-79c0-401e-902c-1f611e2a9b3b} - - - {b9feaf89-58f1-4793-890d-6e83fc5fb5d4} - - - {d820ee67-598d-43dc-bbde-c2f752cc2042} - - - {edb88f62-96a7-40c3-8359-970e191dc3f6} - - - {3156f528-cb57-4cd3-b345-721adac4edd3} - - - {1f8decdb-4fcb-4acc-b89b-eb581ed1ec7d} - - - {63fd35da-8094-4173-856a-c2f2fedf547d} - - - {91fac5dc-7cd5-4d5a-8819-36bdefdb7fd6} - - - {32a1be15-b6a8-4181-945a-ef7081d4e4e5} - - - {c7b58d57-c9fe-4904-94e4-4c70a89ee725} - - - - - Source Files\_quake\dmc\cl_dll - - - Source Files\_quake\dmc\cl_dll - - - Source Files\_quake\dmc\cl_dll - - - Source Files\_quake\dmc\cl_dll - - - Source Files\_quake\dmc\cl_dll\quake - - - Source Files\_quake\dmc\cl_dll\quake - - - Source Files\_quake\dmc\cl_dll\quake - - - Source Files\_quake\dmc\cl_dll\quake - - - Source Files\_quake\dmc\dlls - - - Source Files\_quake\dmc\dlls - - - Source Files\_quake\dmc\cl_dll - - - Source Files\_quake\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\public - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\common - - - Source Files\dmc\pm_shared - - - Source Files\dmc\pm_shared - - - Source Files\dmc\pm_shared - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - Source Files\dmc\cl_dll - - - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\common - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\dlls - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\game_shared - - - Header Files\game_shared - - - Header Files\game_shared - - - Header Files\game_shared - - - Header Files\game_shared - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - Header Files\dmc\cl_dll - - - \ No newline at end of file diff --git a/projects/vs2010/dmcdll.vcxproj b/projects/vs2010/dmcdll.vcxproj deleted file mode 100644 index 12771ea0..00000000 --- a/projects/vs2010/dmcdll.vcxproj +++ /dev/null @@ -1,205 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {6C5EBEF4-40AE-4167-B3D5-26F0AB47E382} - Win32Proj - dmcdll - 10.0.16299.0 - - - - DynamicLibrary - true - NotSet - v141 - - - DynamicLibrary - false - true - NotSet - v141 - - - - - - - - - - - - - true - $(Configuration)\$(ProjectName)\ - $(Configuration)\$(ProjectName)\int\ - dmc - - - false - $(Configuration)\$(ProjectName)\ - $(Configuration)\$(ProjectName)\int\ - dmc - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;QUIVER;VOXEL;QUAKE2;VALVE_DLL;%(PreprocessorDefinitions) - ..\..\public;..\..\game_shared;..\..\dmc\dlls;..\..\engine;..\..\common;..\..\dmc\pm_shared;..\..\dmc;%(AdditionalIncludeDirectories) - MultiThreadedDebug - - - Windows - true - $(ProjectDir)..\..\dmc\dlls\dmc.def - - - call ..\..\filecopy.bat $(TargetPath) ..\..\..\game\mod\dlls\$(TargetName).dll -call ..\..\filecopy.bat $(TargetDir)\$(TargetName).pdb ..\..\..\game\mod\dlls\$(TargetName).pdb - - - Performing Post-Build Event - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;QUIVER;VOXEL;QUAKE2;VALVE_DLL;%(PreprocessorDefinitions) - ..\..\public;..\..\game_shared;..\..\dmc\dlls;..\..\engine;..\..\common;..\..\dmc\pm_shared;..\..\dmc;%(AdditionalIncludeDirectories) - MultiThreaded - - - Windows - true - true - true - $(ProjectDir)..\..\dmc\dlls\dmc.def - - - call ..\..\filecopy.bat $(TargetPath) ..\..\..\game\mod\dlls\$(TargetName).dll -call ..\..\filecopy.bat $(TargetDir)\$(TargetName).pdb ..\..\..\game\mod\dlls\$(TargetName).pdb - - - Performing Post-Build Event - - - - - - \ No newline at end of file diff --git a/projects/vs2010/dmcdll.vcxproj.filters b/projects/vs2010/dmcdll.vcxproj.filters deleted file mode 100644 index d6e992f0..00000000 --- a/projects/vs2010/dmcdll.vcxproj.filters +++ /dev/null @@ -1,333 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {c5ff4571-ca04-4e1f-80e9-a19506da02f2} - - - {5dec4dc2-32bf-42c2-b2f2-d1d51e0570ac} - - - {bdf7ca1b-850d-4ba7-bd67-415aa43b6253} - - - {cb42fc3a-444b-4840-8de8-b4130a14d9d6} - - - {91a827c4-689d-46e4-8f96-ace43cdbc9c9} - - - {cc570f9a-1abf-41cc-b5ba-e0b498ca4b81} - - - {6de9e702-afbc-41de-a5a3-2f8dfd99d18b} - - - {3546bbd0-6019-4fd3-b958-359c4bf3a897} - - - {c7a2ed7b-dc8c-4df5-9fb9-d37c542058af} - - - {646a6534-4acb-4aa0-8341-17a34671b226} - - - {f1606514-06e0-4c6e-b751-4c0b6bf1e171} - - - - - Source Files\_Shared Weapons\dmc\dlls - - - Source Files\_Shared Weapons\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\pm_shared - - - Source Files\dmc\pm_shared - - - Source Files\dmc\pm_shared - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - Source Files\game_shared - - - Source Files\dmc\dlls - - - Source Files\dmc\dlls - - - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\pm_shared - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\dmc\dlls - - - Header Files\game_shared - - - \ No newline at end of file diff --git a/projects/vs2010/ricochet_cdll.vcxproj b/projects/vs2010/ricochet_cdll.vcxproj deleted file mode 100644 index 04953114..00000000 --- a/projects/vs2010/ricochet_cdll.vcxproj +++ /dev/null @@ -1,221 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {EA7DE935-F997-4EA8-9135-E2FE5E5D2C1B} - Win32Proj - ricochet_cdll - 10.0.16299.0 - - - - DynamicLibrary - true - NotSet - v141 - - - DynamicLibrary - false - true - NotSet - v141 - - - - - - - - - - - - - true - $(Configuration)\$(ProjectName)\ - client - $(Configuration)\$(ProjectName)\int\ - - - false - $(Configuration)\$(ProjectName)\ - client - $(Configuration)\$(ProjectName)\int\ - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;CLIENT_DLL;%(PreprocessorDefinitions) - MultiThreadedDebug - ..\..\ricochet;..\..\ricochet\dlls;..\..\ricochet\cl_dll;..\..\game_shared;..\..\engine;..\..\public;..\..\common;..\..\ricochet\pm_shared;..\..\utils\vgui\include;..\..\external;%(AdditionalIncludeDirectories) - - - Windows - true - ..\..\utils\vgui\lib\win32_vc6\vgui.lib;wsock32.lib;..\..\lib\public\sdl2.lib;%(AdditionalDependencies) - - - - - call ..\..\filecopy.bat $(TargetPath) ..\..\..\game\mod\cl_dlls\$(TargetName).dll -call ..\..\filecopy.bat $(TargetDir)\$(TargetName).pdb ..\..\..\game\mod\cl_dlls\$(TargetName).pdb - - - Performing Post-Build Event - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;CLIENT_DLL;%(PreprocessorDefinitions) - MultiThreaded - ..\..\ricochet;..\..\ricochet\dlls;..\..\ricochet\cl_dll;..\..\game_shared;..\..\engine;..\..\public;..\..\common;..\..\ricochet\pm_shared;..\..\utils\vgui\include;..\..\external;%(AdditionalIncludeDirectories) - - - Windows - true - true - true - ..\..\utils\vgui\lib\win32_vc6\vgui.lib;wsock32.lib;..\..\lib\public\sdl2.lib;%(AdditionalDependencies) - - - - - call ..\..\filecopy.bat $(TargetPath) ..\..\..\game\mod\cl_dlls\$(TargetName).dll -call ..\..\filecopy.bat $(TargetDir)\$(TargetName).pdb ..\..\..\game\mod\cl_dlls\$(TargetName).pdb - - - Performing Post-Build Event - - - - - - \ No newline at end of file diff --git a/projects/vs2010/ricochet_cdll.vcxproj.filters b/projects/vs2010/ricochet_cdll.vcxproj.filters deleted file mode 100644 index 9d061fe0..00000000 --- a/projects/vs2010/ricochet_cdll.vcxproj.filters +++ /dev/null @@ -1,384 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {0142d5e4-5caa-4286-8740-78fe5f63f90c} - - - {d79b1e48-d35a-4c47-a48a-06c124d7d5f2} - - - {db1142bc-09dd-40f1-8e5b-7d2e5873fbfb} - - - {14ceca51-597d-4ae0-ad1e-616f9c76afb7} - - - {a659561b-3095-458c-9ac3-98a1f8fda89d} - - - {de1d2011-0a49-4c1e-b1ee-e6e31c6ba173} - - - {8f0ebcb6-1036-4fb2-8955-0992878a0f76} - - - {6d32d06c-ab53-4cc4-9580-61fd0802aeb7} - - - {a62dbc7a-0e7a-4926-9415-c81e6b3e2820} - - - {2263acfb-32b9-437e-b357-289dc027689c} - - - {739d96f5-318f-4326-ac16-acad51f23a39} - - - {0f1d61fd-fd1b-41fb-aa84-b3226848ae8c} - - - {482b21b8-5e14-4d3a-9f6d-000f8fe9c81d} - - - {8ee6bc62-6027-4bb6-bba1-bd7eb71b8ded} - - - {acab3107-5b1a-47d3-95fa-d374360ea28c} - - - {2c1b936b-1f82-449f-be5a-1254ef73c3d2} - - - - - Source Files\_hl\ricochet\dlls\wpn_shared - - - Source Files\_hl\ricochet\cl_dll - - - Source Files\_hl\ricochet\cl_dll\hl - - - Source Files\_hl\ricochet\cl_dll\hl - - - Source Files\_hl\ricochet\cl_dll\hl - - - Source Files\_hl\ricochet\cl_dll\hl - - - Source Files\_hl\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\public - - - Source Files\common - - - Source Files\ricochet\pm_shared - - - Source Files\ricochet\pm_shared - - - Source Files\ricochet\pm_shared - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\game_shared - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - Source Files\game_shared - - - Source Files\ricochet\cl_dll - - - Source Files\ricochet\cl_dll - - - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\common - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - Header Files\ricochet\cl_dll - - - \ No newline at end of file diff --git a/projects/vs2010/ricochetdll.vcxproj b/projects/vs2010/ricochetdll.vcxproj deleted file mode 100644 index 9fa7ab03..00000000 --- a/projects/vs2010/ricochetdll.vcxproj +++ /dev/null @@ -1,208 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {CE8DCBE4-D8DB-46E5-8607-8FCC5FA667FB} - Win32Proj - ricochetdll - 10.0.16299.0 - - - - DynamicLibrary - true - NotSet - v141 - - - DynamicLibrary - false - true - NotSet - v141 - - - - - - - - - - - - - true - $(Configuration)\$(ProjectName)\ - $(Configuration)\$(ProjectName)\int\ - mp - - - false - $(Configuration)\$(ProjectName)\ - $(Configuration)\$(ProjectName)\int\ - mp - - - - - - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;VALVE_DLL;%(PreprocessorDefinitions) - ..\..\ricochet\dlls;..\..\engine;..\..\common;..\..\public;..\..\game_shared;..\..\ricochet\pm_shared;..\..\ricochet;%(AdditionalIncludeDirectories) - MultiThreadedDebug - - - Windows - true - $(ProjectDir)..\..\ricochet\dlls\mp.def - - - call ..\..\filecopy.bat $(TargetPath) ..\..\..\game\mod\dlls\$(TargetName).dll -call ..\..\filecopy.bat $(TargetDir)\$(TargetName).pdb ..\..\..\game\mod\dlls\$(TargetName).pdb - - - Performing Post-Build Event - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;VALVE_DLL;%(PreprocessorDefinitions) - ..\..\ricochet\dlls;..\..\engine;..\..\common;..\..\public;..\..\game_shared;..\..\ricochet\pm_shared;..\..\ricochet;%(AdditionalIncludeDirectories) - MultiThreaded - - - Windows - true - true - true - $(ProjectDir)..\..\ricochet\dlls\mp.def - - - call ..\..\filecopy.bat $(TargetPath) ..\..\..\game\mod\dlls\$(TargetName).dll -call ..\..\filecopy.bat $(TargetDir)\$(TargetName).pdb ..\..\..\game\mod\dlls\$(TargetName).pdb - - - Performing Post-Build Event - - - - - - \ No newline at end of file diff --git a/projects/vs2010/ricochetdll.vcxproj.filters b/projects/vs2010/ricochetdll.vcxproj.filters deleted file mode 100644 index 2fac37cc..00000000 --- a/projects/vs2010/ricochetdll.vcxproj.filters +++ /dev/null @@ -1,333 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {a3e19434-b8d9-43ec-a1ed-e260f8aee591} - - - {9b833c3f-4e64-4ba6-9143-c7a365cef6fa} - - - {c683dfc8-f9d2-49d0-bc80-c2aa7e10dab5} - - - {6334b1f8-a9a7-44e0-a020-afa31543406a} - - - {be7399a9-5600-4d83-b06d-4edbed45200b} - - - {684ab4d1-82f9-4ff3-868a-0d9919cc32f7} - - - {2dc019ff-0dfb-4478-9ecd-58c90ae0111e} - - - {8b020c05-4536-4f4f-82c9-2206caef635a} - - - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls\wpn_shared - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\pm_shared - - - Source Files\ricochet\pm_shared - - - Source Files\ricochet\pm_shared - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\ricochet\dlls - - - Source Files\game_shared - - - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\pm_shared - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - Header Files\ricochet\dlls - - - \ No newline at end of file diff --git a/ricochet/cl_dll/Exports.h b/ricochet/cl_dll/Exports.h deleted file mode 100644 index 3b66c4f5..00000000 --- a/ricochet/cl_dll/Exports.h +++ /dev/null @@ -1,224 +0,0 @@ -// CL_DLLEXPORT is the client version of dllexport. It's turned off for secure clients. -#ifdef _WIN32 -#define CL_DLLEXPORT __declspec(dllexport) -#else -#define CL_DLLEXPORT __attribute__ ((visibility("default"))) -#endif - -extern "C" -{ - // From hl_weapons - void CL_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 CL_DLLEXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ); - int CL_DLLEXPORT HUD_VidInit( void ); - void CL_DLLEXPORT HUD_Init( void ); - int CL_DLLEXPORT HUD_Redraw( float flTime, int intermission ); - int CL_DLLEXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime ); - void CL_DLLEXPORT HUD_Reset ( void ); - void CL_DLLEXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ); - void CL_DLLEXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ); - char CL_DLLEXPORT HUD_PlayerMoveTexture( char *name ); - int CL_DLLEXPORT HUD_ConnectionlessPacket( const struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); - int CL_DLLEXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ); - void CL_DLLEXPORT HUD_Frame( double time ); - void CL_DLLEXPORT HUD_VoiceStatus(int entindex, qboolean bTalking); - void CL_DLLEXPORT HUD_DirectorMessage( int iSize, void *pbuf ); - void CL_DLLEXPORT HUD_ChatInputPosition( int *x, int *y ); - int CL_DLLEXPORT HUD_GetPlayerTeam(int iplayer); - - // From demo - void CL_DLLEXPORT Demo_ReadBuffer( int size, unsigned char *buffer ); - - // From entity - int CL_DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void CL_DLLEXPORT HUD_CreateEntities( void ); - void CL_DLLEXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); - void CL_DLLEXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); - void CL_DLLEXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); - void CL_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 CL_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 CL_DLLEXPORT *HUD_GetUserEntity( int index ); - - // From in_camera - void CL_DLLEXPORT CAM_Think( void ); - int CL_DLLEXPORT CL_IsThirdPerson( void ); - void CL_DLLEXPORT CL_CameraOffset( float *ofs ); - - // From input - struct kbutton_s CL_DLLEXPORT *KB_Find( const char *name ); - void CL_DLLEXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ); - void CL_DLLEXPORT HUD_Shutdown( void ); - int CL_DLLEXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding ); - - // From inputw32 - void CL_DLLEXPORT IN_ActivateMouse( void ); - void CL_DLLEXPORT IN_DeactivateMouse( void ); - void CL_DLLEXPORT IN_MouseEvent (int mstate); - void CL_DLLEXPORT IN_Accumulate (void); - void CL_DLLEXPORT IN_ClearStates (void); - - // From tri - void CL_DLLEXPORT HUD_DrawNormalTriangles( void ); - void CL_DLLEXPORT HUD_DrawTransparentTriangles( void ); - - // From view - void CL_DLLEXPORT V_CalcRefdef( struct ref_params_s *pparams ); - - // From GameStudioModelRenderer - int CL_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 c0de0448..00000000 --- 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 = max( 0.0, dt ); - dt = 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 = max( 0.0, dt ); - dt = 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 = min( 255.0, blend_yaw ); - blend_yaw = 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 = min( 1.0, 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 EXPORT 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 64f6c8b0..00000000 --- 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 8e21ea0d..00000000 --- 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 c5ca9e52..00000000 --- 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 "C" 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 7243df9b..00000000 --- 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 d346723e..00000000 --- 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 fae3a8ee..00000000 --- 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 c7573c82..00000000 --- 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 = 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 = 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 = 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 = 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 a3125ab7..00000000 --- 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 d71b2ee4..00000000 --- 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) 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 += 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 e9cbbd42..00000000 --- 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 = 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, 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, 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, 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 a717508f..00000000 --- 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 f5e9d390..00000000 --- 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 607142bf..00000000 --- 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 c4d9af41..00000000 --- a/ricochet/cl_dll/cdll_int.cpp +++ /dev/null @@ -1,278 +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; - -extern "C" -{ -#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 EXPORT Initialize( cl_enginefunc_t *pEnginefuncs, int iVersion ); -int EXPORT HUD_VidInit( void ); -int EXPORT HUD_Init( void ); -int EXPORT HUD_Redraw( float flTime, int intermission ); -int EXPORT HUD_UpdateClientData( client_data_t *cdata, float flTime ); -int EXPORT HUD_Reset ( void ); -void EXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ); -void EXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ); -char EXPORT HUD_PlayerMoveTexture( char *name ); -int EXPORT HUD_ConnectionlessPacket( struct netadr_s *net_from, const char *args, char *response_buffer, int *response_buffer_size ); -int EXPORT HUD_GetHullBounds( int hullnumber, float *mins, float *maxs ); -void EXPORT HUD_Frame( double time ); -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 ); -void EXPORT 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 EXPORT 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 EXPORT 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 EXPORT HUD_PlayerMoveInit( struct playermove_s *ppmove ) -{ - PM_Init( ppmove ); -} - -char EXPORT HUD_PlayerMoveTexture( char *name ) -{ - return PM_FindTextureType( name ); -} - -void EXPORT HUD_PlayerMove( struct playermove_s *ppmove, int server ) -{ - PM_Move( ppmove, server ); -} - -int EXPORT 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 EXPORT 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 EXPORT HUD_Init( void ) -{ - InitInput(); - gHUD.Init(); - Scheme_Init(); - return 1; -} - - -/* -========================== - HUD_Redraw - -called every screen frame to -redraw the HUD. -=========================== -*/ - -int EXPORT 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 EXPORT 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 EXPORT HUD_Reset( void ) -{ - gHUD.VidInit(); - return 1; -} - - -/* -========================== -HUD_Frame - -Called by engine every frame that client .dll is loaded -========================== -*/ - -void EXPORT HUD_Frame( double time ) -{ - ServersThink( time ); - - GetClientVoiceMgr()->Frame(time); -} - -/* -========================== -HUD_VoiceStatus - -Called when a player starts or stops talking. -========================== -*/ - -void EXPORT 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 58b0ddb8..00000000 --- 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 2662c289..00000000 --- a/ricochet/cl_dll/cl_dll.h +++ /dev/null @@ -1,42 +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 -// -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" -#ifdef _WIN32 -#define EXPORT _declspec( dllexport ) -#else -#define EXPORT __attribute__ ((visibility("default"))) -#endif -#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 017327ea..00000000 --- a/ricochet/cl_dll/cl_util.h +++ /dev/null @@ -1,189 +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" - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#include // for safe_sprintf() -#include // " -#include - -// 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 ); } - -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#define fabs(x) ((x) > 0 ? (x) : 0 - (x)) - -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 677ecbe5..00000000 --- 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 ( char* s ) { return 0; } -int stub_PrecacheSound ( 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 dca35ee7..00000000 --- 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 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 ); -} - -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( char* s ); -int stub_PrecacheSound( 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 f9457269..00000000 --- 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 = 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 bb659360..00000000 --- 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 EXPORT 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 EXPORT 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 f538e824..00000000 --- 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 635b7124..00000000 --- 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 EXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *modelname ); - void EXPORT HUD_CreateEntities( void ); - void EXPORT HUD_StudioEvent( const struct mstudioevent_s *event, const struct cl_entity_s *entity ); - void EXPORT HUD_TxferLocalOverrides( struct entity_state_s *state, const struct clientdata_s *client ); - void EXPORT HUD_ProcessPlayerState( struct entity_state_s *dst, const struct entity_state_s *src ); - void EXPORT 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 EXPORT 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 EXPORT *HUD_GetUserEntity( int index ); -} - -/* -======================== -HUD_AddEntity - Return 0 to filter entity from visible list for rendering -======================== -*/ -int EXPORT 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 EXPORT 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 EXPORT 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 EXPORT 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 EXPORT 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 EXPORT 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 EXPORT 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 EXPORT *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 2d2e37ee..00000000 --- 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 11dbf668..00000000 --- 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 8d3aec79..00000000 --- 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 04c8f57c..00000000 --- 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 0ac3251c..00000000 --- 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 48a73f47..00000000 --- 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 7087e592..00000000 --- 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 73d8be13..00000000 --- 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 = max(m_fAttackFront, side); - } - else - { - float f = fabs(side); - if (f > 0.3) - m_fAttackRear = max(m_fAttackRear, f); - } - - if (front > 0) - { - if (front > 0.3) - m_fAttackRight = max(m_fAttackRight, front); - } - else - { - float f = fabs(front); - if (f > 0.3) - m_fAttackLeft = 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 * 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 = max( 0, m_fAttackFront - fFade ); - } else - m_fAttackFront = 0; - - if (m_fAttackRight > 0.4) - { - GetPainColor(r,g,b); - shade = a * 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 = max( 0, m_fAttackRight - fFade ); - } else - m_fAttackRight = 0; - - if (m_fAttackRear > 0.4) - { - GetPainColor(r,g,b); - shade = a * 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 = max( 0, m_fAttackRear - fFade ); - } else - m_fAttackRear = 0; - - if (m_fAttackLeft > 0.4) - { - GetPainColor(r,g,b); - shade = a * 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 = 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 = 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 dd598978..00000000 --- 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 16809e90..00000000 --- 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 0906ab3a..00000000 --- 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 204d0bcb..00000000 --- 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 59404eb1..00000000 --- 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, 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 = 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 = 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 a0e6da1f..00000000 --- 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 4d82c2bb..00000000 --- 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 d3367419..00000000 --- a/ricochet/cl_dll/hud_iface.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. -* -****/ -#if !defined( HUD_IFACEH ) -#define HUD_IFACEH -#pragma once - -#ifdef _WIN32 -#define EXPORT _declspec( dllexport ) -#else -#define EXPORT __attribute__ ((visibility("default"))) -#endif -#define DLLEXPORT EXPORT - -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 0c83bd3c..00000000 --- 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 e7a7db25..00000000 --- a/ricochet/cl_dll/hud_redraw.cpp +++ /dev/null @@ -1,262 +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 -}; - -// 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 = 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 2050d095..00000000 --- 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 577b5551..00000000 --- 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 84f1e2a2..00000000 --- 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 3a69a00d..00000000 --- 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 3df4d592..00000000 --- a/ricochet/cl_dll/in_camera.cpp +++ /dev/null @@ -1,600 +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 "Exports.h" - -#include "port.h" - -float CL_KeyState (kbutton_t *key); - -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 MAX_ANGLE_DIFF 10.0 -#define PITCH_MAX 90.0 -#define PITCH_MIN 0 -#define YAW_MAX 135.0 -#define YAW_MIN -135.0 -#define CAM_DIST_MOUSEFAC 0.05 -#define CAM_ANGLE_MOUSEFAC 1.67 - -enum ECAM_Command -{ - CAM_COMMAND_NONE = 0, - CAM_COMMAND_TOTHIRDPERSON = 1, - CAM_COMMAND_TOFIRSTPERSON = 2 -}; - -//-------------------------------------------------- Global Variables - -extern cvar_t *m_pitch; -extern cvar_t *m_yaw; -extern cvar_t *m_forward; -extern cvar_t *m_side; - -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; - -//-------------------------------------------------- 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); - -//-------------------------------------------------- - -// defined in inputw32.cpp: -void IN_GetMouseDelta( int *pOutX, int *pOuty); -void IN_ScaleMouse( float *x, float *y ); - -void CAM_GetScaledMouseDelta( float *pOutX, float *pOutY ) -{ - int x,y; - float fx, fy; - - IN_GetMouseDelta( &x, &y ); - - fx = x; - fy = y; - - IN_ScaleMouse( &fx, &fy ); - - if(pOutX) *pOutX = fx; - if(pOutY) *pOutY = fy; -} - -//-------------------------------------------------- Local Functions - -float MoveToward( float cur, float goal, float maxspeed ) -{ - if( cur != goal ) - { - if( abs( 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 CL_DLLEXPORT CAM_Think( void ) -{ - float cam_mouse_x, cam_mouse_y; - vec3_t origin; - vec3_t ext, pnt, camForward, camRight, camUp; - moveclip_t clip; - float dist; - vec3_t camAngles; -#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 mouse cursor delta - CAM_GetScaledMouseDelta (&cam_mouse_x,&cam_mouse_y); - //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>0) - { - //if ((camAngles[YAW]>=225.0)||(camAngles[YAW]<135.0)) - if (camAngles[YAW]value) - { - camAngles[ YAW ] += CAM_ANGLE_MOUSEFAC * m_yaw->value * cam_mouse_x; - } - if (camAngles[YAW]>c_maxyaw->value) - { - - camAngles[YAW]=c_maxyaw->value; - } - } - else if (cam_mouse_x<0) - { - //if ((camAngles[YAW]<=135.0)||(camAngles[YAW]>225.0)) - if (camAngles[YAW]>c_minyaw->value) - { - camAngles[ YAW ] -= CAM_ANGLE_MOUSEFAC * m_yaw->value * -cam_mouse_x; - - } - 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>0) - { - if(camAngles[PITCH]value) - { - camAngles[PITCH] += CAM_ANGLE_MOUSEFAC * m_pitch->value * cam_mouse_y; - } - if (camAngles[PITCH]>c_maxpitch->value) - { - camAngles[PITCH]=c_maxpitch->value; - } - } - else if (cam_mouse_y<0) - { - if (camAngles[PITCH]>c_minpitch->value) - { - camAngles[PITCH] -= CAM_ANGLE_MOUSEFAC * m_pitch->value * -cam_mouse_y; - } - if (camAngles[PITCH]value) - { - camAngles[PITCH]=c_minpitch->value; - } - } - } - } - - //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>0) - { - if(distvalue) - { - dist += CAM_DIST_MOUSEFAC * m_forward->value * cam_mouse_y; - } - if (dist>c_maxdistance->value) - { - dist=c_maxdistance->value; - } - } - else if (cam_mouse_y<0) - { - if (dist>c_mindistance->value) - { - dist -= CAM_DIST_MOUSEFAC * m_forward->value * -cam_mouse_y; - } - if (distvalue) - { - dist=c_mindistance->value; - } - } - } -#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( abs( 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) -{ - //only move the cam with mouse if we are in third person. - if (cam_thirdperson) - { - //set appropriate flags - if (!cam_mousemove) - { - cam_mousemove=1; - iMouseInUse=1; - } - } - //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 - if (!cam_distancemove) - { - cam_distancemove=1; - cam_mousemove=1; - iMouseInUse=1; - } - } - //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 CL_DLLEXPORT CL_IsThirdPerson( void ) -{ - return cam_thirdperson ? 1 : 0; -} - -void CL_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 18ec79ef..00000000 --- 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 f3e3de58..00000000 --- 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 EXPORT *KB_Find( const char *name ); - void EXPORT CL_CreateMove ( float frametime, struct usercmd_s *cmd, int active ); - void EXPORT HUD_Shutdown( void ); - int EXPORT HUD_Key_Event( int eventcode, int keynum, const char *pszCurrentBinding ); -} - -extern int g_weaponselect; -extern cl_enginefunc_t gEngfuncs; - -// Defined in pm_math.c -extern "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 EXPORT *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 EXPORT 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 EXPORT 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 EXPORT 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 1f9dc479..00000000 --- a/ricochet/cl_dll/inputw32.cpp +++ /dev/null @@ -1,991 +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 "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" - -#include -#include - -#define MOUSE_BUTTON_COUNT 5 - -// use IN_SetVisibleMouse to set: -int 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 = 0; -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 ]; -int 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 ); - } -} - -void IN_SetMouseMode(bool enable) -{ - static bool currentMouseMode = false; - - if(enable == currentMouseMode) - return; - - if(enable) - { -#ifdef _WIN32 - if (mouseparmsvalid) - restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); -#endif - SDL_SetRelativeMouseMode(SDL_TRUE); - - currentMouseMode = true; - } - else - { - SDL_SetRelativeMouseMode(SDL_FALSE); - -#ifdef _WIN32 - if (restore_spi) - SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); -#endif - - currentMouseMode = false; - } -} - -void IN_SetVisibleMouse(bool visible) -{ - iVisibleMouse = visible; - - IN_SetMouseMode(!visible); -} - -void IN_ResetMouse( void ); - -/* -=========== -IN_ActivateMouse -=========== -*/ -void CL_DLLEXPORT IN_ActivateMouse (void) -{ - if (mouseinitialized) - { - IN_SetMouseMode(true); - - mouseactive = 1; - - // now is a good time to reset mouse positon: - IN_ResetMouse(); - } -} - - -/* -=========== -IN_DeactivateMouse -=========== -*/ -void CL_DLLEXPORT IN_DeactivateMouse (void) -{ - if (mouseinitialized) - { - IN_SetMouseMode(false); - - 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 CL_DLLEXPORT IN_MouseEvent (int mstate) -{ - int i; - - if ( iMouseInUse || 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; - } -} - -void IN_GetMouseDelta( int *pOutX, int *pOutY) -{ - bool active = mouseactive && !iVisibleMouse; - int mx, my; - - if(active) - { - 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; - - // reset mouse position if required, so there is room to move: - IN_ResetMouse(); - } - else - { - mx = my = 0; - } - - if(pOutX) *pOutX = mx; - if(pOutY) *pOutY = my; -} - -/* -=========== -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 && !iVisibleMouse && !iSpectator ) - { - IN_GetMouseDelta( &mx, &my ); - - if (m_filter && 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; - } - } - } - - 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 CL_DLLEXPORT IN_Accumulate (void) -{ - //only accumulate mouse if we are not moving the camera with the mouse - if ( !iMouseInUse && !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 CL_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]; - - 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(abs(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/ricochet/cl_dll/kbutton.h b/ricochet/cl_dll/kbutton.h deleted file mode 100644 index f4ccf852..00000000 --- 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 222dae3a..00000000 --- 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 64dbcd96..00000000 --- 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 249205ca..00000000 --- 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 00e043c8..00000000 --- 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 = min( flScrollTime, flTime + SCROLL_SPEED ); - - // make sure the scrolltime is within reasonable bounds, to guard against the clock being reset - flScrollTime = 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], min(g_iNameLengths[i], MAX_PLAYER_NAME_LENGTH+32) ); - buf[ 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, 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 bf0b2984..00000000 --- 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 41b8de96..00000000 --- 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 = max( 0, 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 71a0cfd6..00000000 --- a/ricochet/cl_dll/studio_util.cpp +++ /dev/null @@ -1,244 +0,0 @@ -#include -#include "hud.h" -#include "cl_util.h" -#include "const.h" -#include "com_model.h" -#include "studio_util.h" - -/* -==================== -AngleMatrix - -==================== -*/ -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; -} - -/* -==================== -VectorCompare - -==================== -*/ -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; -} - -/* -==================== -CrossProduct - -==================== -*/ -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]; -} - -/* -==================== -VectorTransform - -==================== -*/ -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]; -} - -/* -================ -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]; -} - -// 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 49e506f3..00000000 --- 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 e2283d2e..00000000 --- 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 5d7c2271..00000000 --- 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 9e15e167..00000000 --- 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 5290b9e3..00000000 --- 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 EXPORT HUD_DrawNormalTriangles( void ); - void EXPORT 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 EXPORT HUD_DrawNormalTriangles( void ) -{ - -#if defined( TEST_IT ) -// Draw_Triangles(); -#endif -} - -/* -================= -HUD_DrawTransparentTriangles - -Render any triangles with transparent rendermode needs here -================= -*/ -void EXPORT 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 883d2b01..00000000 --- a/ricochet/cl_dll/util.cpp +++ /dev/null @@ -1,101 +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 "stdio.h" -#include "stdlib.h" -#include "math.h" - -#include "hud.h" -#include "cl_util.h" -#include - -vec3_t vec3_origin( 0, 0, 0 ); - -double sqrt(double x); - -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; -} - -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]; -} - - -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 1505dc1d..00000000 --- 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 172ec1fa..00000000 --- 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 7e545e76..00000000 --- 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 4c53f5c8..00000000 --- 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 1c362c4a..00000000 --- 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 9e9c7307..00000000 --- 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 ae2f026c..00000000 --- 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 c61d1f78..00000000 --- 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 b1da6398..00000000 --- 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 d061029a..00000000 --- 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 = 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 ecb6e6f8..00000000 --- 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 = 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 009b1370..00000000 --- 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 = 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 b8267705..00000000 --- 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 e1197cb2..00000000 --- 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; -void IN_SetVisibleMouse(bool visible); -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() ) - { - IN_SetVisibleMouse(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 ) - { - IN_SetVisibleMouse(true); - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_arrow) ); - return; - } - } - - App::getInstance()->setCursorOveride( App::getInstance()->getScheme()->getCursor(Scheme::scu_none) ); - IN_SetVisibleMouse(false); - IN_ResetMouse(); -} - -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 b1415cf4..00000000 --- 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 39401e8f..00000000 --- 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 0290a59e..00000000 --- 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 cb305615..00000000 --- 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 a90f80c2..00000000 --- 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 5b4db0a3..00000000 --- a/ricochet/cl_dll/view.cpp +++ /dev/null @@ -1,1061 +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 "C" -{ - float vecNewViewAngles[3]; - int iHasNewViewAngles; - float vecNewViewOrigin[3]; - int iHasNewViewOrigin; - 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 EXPORT 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 = min( bob, 4 ); - bob = 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 = 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 = 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 EXPORT 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 = 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 24d444fc..00000000 --- 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 f6cda4d3..00000000 --- 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 = 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 8edf58c7..00000000 --- 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 f2c4f127..00000000 --- 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 b16c1b53..00000000 --- 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 a496c12a..00000000 --- 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 390d634e..00000000 --- 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 fa74af41..00000000 --- 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 7fc20c22..00000000 --- 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 4a691a25..00000000 --- a/ricochet/dlls/animation.cpp +++ /dev/null @@ -1,526 +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 -#include -#include - -typedef bool BOOL; - -// 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 3da74cb6..00000000 --- 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 ab516a15..00000000 --- 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 a546c0c5..00000000 --- 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 = abs(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 = abs(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 ( abs(vecAVel.x) >= abs(pev->movedir.x * pev->speed) && - abs(vecAVel.y) >= abs(pev->movedir.y * pev->speed) && - abs(vecAVel.z) >= abs(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 eb5a3e94..00000000 --- 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 d50d4965..00000000 --- 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 ); - -extern "C" void PM_Move ( struct playermove_s *ppmove, int server ); -extern "C" void PM_Init ( struct playermove_s *ppmove ); -extern "C" 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 274efeae..00000000 --- a/ricochet/dlls/cbase.h +++ /dev/null @@ -1,803 +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 - -// C functions for external declarations that call the appropriate C++ methods - -#ifndef CBASE_DLLEXPORT -#ifdef _WIN32 -#define CBASE_DLLEXPORT _declspec( dllexport ) -#else -#define CBASE_DLLEXPORT __attribute__ ((visibility("default"))) -#endif -#endif - -#define EXPORT CBASE_DLLEXPORT - -extern "C" CBASE_DLLEXPORT int GetEntityAPI( DLL_FUNCTIONS *pFunctionTable, int interfaceVersion ); -extern "C" CBASE_DLLEXPORT int GetEntityAPI2( DLL_FUNCTIONS *pFunctionTable, int *interfaceVersion ); -extern "C" CBASE_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 ee324ad2..00000000 --- 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 453e097c..00000000 --- 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 = max( max( r, g ) , b ); - float fMin = min( 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 = max( gun->m_flTimeWeaponIdle, -0.001 ); - item->m_flNextPrimaryAttack = max( gun->m_flNextPrimaryAttack, -0.001 ); - item->m_flNextSecondaryAttack = 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 0404b6a0..00000000 --- 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 286b506b..00000000 --- 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 * 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 0cb87eef..00000000 --- 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 30919c33..00000000 --- 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 9670ef75..00000000 --- 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 067c56ef..00000000 --- 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 52e5c61a..00000000 --- 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 c9c3f3bb..00000000 --- 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 410038df..00000000 --- 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 c084dac1..00000000 --- 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 07447a05..00000000 --- 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 825dac23..00000000 --- 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 = min( startPos.x, endPos.x ); - pev->mins.y = min( startPos.y, endPos.y ); - pev->mins.z = min( startPos.z, endPos.z ); - pev->maxs.x = max( startPos.x, endPos.x ); - pev->maxs.y = max( startPos.y, endPos.y ); - pev->maxs.z = 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 = min( startPos.x, endPos.x ); - pev->absmin.y = min( startPos.y, endPos.y ); - pev->absmin.z = min( startPos.z, endPos.z ); - pev->absmax.x = max( startPos.x, endPos.x ); - pev->absmax.y = max( startPos.y, endPos.y ); - pev->absmax.z = 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 d5172681..00000000 --- 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 e960e9dd..00000000 --- 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 adce53aa..00000000 --- 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 202a581c..00000000 --- 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 75bea13f..00000000 --- a/ricochet/dlls/extdll.h +++ /dev/null @@ -1,101 +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 -// - -// Allow "DEBUG" in addition to default "_DEBUG" -#ifdef _DEBUG -#define DEBUG 1 -#endif - -// Silence certain warnings -#pragma warning(disable : 4244) // int or float down-conversion -#pragma warning(disable : 4305) // int or float data truncation -#pragma warning(disable : 4201) // nameless struct/union -#pragma warning(disable : 4514) // unreferenced inline function removed -#pragma warning(disable : 4100) // unreferenced formal parameter - -#ifdef _WIN32 -// Prevent tons of unused windows definitions -#define WIN32_LEAN_AND_MEAN -#define NOWINRES -#define NOSERVICE -#define NOMCX -#define NOIME -#include "winsani_in.h" -#include "windows.h" -#include "winsani_out.h" - -#else // _WIN32 -#define FALSE 0 -#define TRUE (!FALSE) - -typedef uint32 ULONG; -typedef unsigned char BYTE; -typedef int BOOL; - -#define MAX_PATH PATH_MAX - -#include -#include -#include - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef max -#define max(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -#define itoa(a,b,c) sprintf(b, "%d", a) -#define _snprintf snprintf -#define _vsnprintf vsnprintf -#endif //_WIN32 - -// 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 - -// 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 eb091156..00000000 --- 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) + (abs(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 3c773b13..00000000 --- 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 20b24f91..00000000 --- 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 c70b8c0b..00000000 --- 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 9597833c..00000000 --- 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 eb103322..00000000 --- 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 1ebdd413..00000000 --- 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 faa72042..00000000 --- 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 9f6125cc..00000000 --- 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 d526bcfb..00000000 --- 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 7a029ce5..00000000 --- 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 6822c852..00000000 --- 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 480bccdd..00000000 --- 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 68ec4ef3..00000000 --- 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 0429a75a..00000000 --- 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 = 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 3fbb370a..00000000 --- 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 d49e1815..00000000 --- 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 2e922759..00000000 --- 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] = 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 9c50dcc3..00000000 --- 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 27bcb05d..00000000 --- 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 f46ae525..00000000 --- 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 22f48b5d..00000000 --- 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 2a12a7c4..00000000 --- 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 7cfcc194..00000000 --- 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 41631f03..00000000 --- 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 440aea4c..00000000 --- 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 = max( item->minplayers, 0 ); - item->minplayers = min( item->minplayers, gpGlobals->maxClients ); - } - s = g_engfuncs.pfnInfoKeyValue( szBuffer, "maxplayers" ); - if ( s && s[0] ) - { - item->maxplayers = atoi( s ); - item->maxplayers = max( item->maxplayers, 0 ); - item->maxplayers = 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 d6dbbd89..00000000 --- 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 7ba45057..00000000 --- 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 173b9608..00000000 --- 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 77e22737..00000000 --- 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 5b64e84d..00000000 --- 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 7fcd0e48..00000000 --- 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 + (abs(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 5ee7b823..00000000 --- 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 (abs(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 = 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 = max( gun->m_flNextPrimaryAttack - gpGlobals->frametime, -1.0 ); - gun->m_flNextSecondaryAttack = max( gun->m_flNextSecondaryAttack - gpGlobals->frametime, -0.001 ); - - if ( gun->m_flTimeWeaponIdle != 1000 ) - { - gun->m_flTimeWeaponIdle = 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 = 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( max( 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 4490c8a0..00000000 --- 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 4065b04e..00000000 --- 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 f8ee15ae..00000000 --- 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 9aa7140e..00000000 --- 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 43d5df7a..00000000 --- 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 5e06914c..00000000 --- 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 30e25f8e..00000000 --- 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 ab3fb8b6..00000000 --- a/ricochet/dlls/sound.cpp +++ /dev/null @@ -1,1985 +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); - itoa(ipick, sznum, 10); - 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); - itoa(ipick, sznum, 10); - 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); - itoa(ipick, sznum, 10); - 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, "!"); - itoa(i, sznum, 10); - 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 = 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 65dac456..00000000 --- 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 1967e979..00000000 --- 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 7d7f4a8b..00000000 --- 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 cf27d0c3..00000000 --- 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 b9cc133e..00000000 --- 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 d8a92eb3..00000000 --- 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 60338e43..00000000 --- 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 86d08140..00000000 --- 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 59124411..00000000 --- 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 8f275ebc..00000000 --- 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 0db80775..00000000 --- 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( 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( min( 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 2c53ef67..00000000 --- a/ricochet/dlls/util.h +++ /dev/null @@ -1,564 +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 - -#ifndef UTIL_DLLEXPORT -#ifdef _WIN32 -#define UTIL_DLLEXPORT _declspec( dllexport ) -#else -#define UTIL_DLLEXPORT __attribute__ ((visibility("default"))) -#endif -#endif - -// Keeps clutter down a bit, when declaring external entity/global method prototypes -#define DECLARE_GLOBAL_METHOD(MethodName) \ - extern void UTIL_DLLEXPORT MethodName( void ) -#define GLOBAL_METHOD(funcname) void UTIL_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" UTIL_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); -typedef 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 adfb4368..00000000 --- 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 19871375..00000000 --- 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 = 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 = 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 = 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 533ee2d7..00000000 --- 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 5f7a1707..00000000 --- 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 ebd9b441..00000000 --- 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.c b/ricochet/pm_shared/pm_debug.c deleted file mode 100644 index 2ccb8a5b..00000000 --- a/ricochet/pm_shared/pm_debug.c +++ /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 18db48b6..00000000 --- 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 d445ad14..00000000 --- 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 bb08d4e0..00000000 --- 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 67deed62..00000000 --- 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.c b/ricochet/pm_shared/pm_math.c deleted file mode 100644 index 1deed2bc..00000000 --- a/ricochet/pm_shared/pm_math.c +++ /dev/null @@ -1,326 +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) - -#ifndef DISABLE_VEC_ORIGIN -vec3_t vec3_origin = {0,0,0}; -#endif -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 vec3_t 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 vec3_t in1, float in2[3][4], vec3_t 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 vec3_t v1, const vec3_t v2) -{ - int i; - - for (i=0 ; i<3 ; i++) - if (v1[i] != v2[i]) - return 0; - - return 1; -} - -void VectorMA (const vec3_t veca, float scale, const vec3_t vecb, vec3_t 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 vec3_t v1, const vec3_t v2, vec3_t 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]; -} - -double sqrt(double x); - -float Length(const vec3_t 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 (vec3_t 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 (vec3_t v) -{ - v[0] = -v[0]; - v[1] = -v[1]; - v[2] = -v[2]; -} - -void VectorScale (const vec3_t in, vec_t scale, vec3_t 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 vec3_t forward, vec3_t angles ) -{ - float 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; -} \ No newline at end of file diff --git a/ricochet/pm_shared/pm_movevars.h b/ricochet/pm_shared/pm_movevars.h deleted file mode 100644 index 71f21798..00000000 --- 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.c b/ricochet/pm_shared/pm_shared.c deleted file mode 100644 index d08b0ebb..00000000 --- a/ricochet/pm_shared/pm_shared.c +++ /dev/null @@ -1,3374 +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 -#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; - -#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) -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#define min(a, b) (((a) < (b)) ? (a) : (b)) -// 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 = 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 (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 (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 (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 (vec3_origin, pmove->velocity); - break; - } - } - } - - if ( allFraction == 0 ) - { - VectorCopy (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( 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( 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 (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 = 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, vec3_origin) && - VectorCompare(pmove->velocity, 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 (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 (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( 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 = 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 = 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 9da8001a..00000000 --- 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 From 314c8820f2fb0513778ea073f0f8efe222b8ceec Mon Sep 17 00:00:00 2001 From: SmileyAG Date: Sat, 10 Dec 2022 01:05:14 +0400 Subject: [PATCH 27/42] Don't lookup cvars via CVAR_GET_ macro to save performance --- cl_dll/MOTD.cpp | 6 ++++-- cl_dll/ammo.cpp | 6 +++--- cl_dll/ammohistory.cpp | 4 ++-- cl_dll/death.cpp | 5 +++-- cl_dll/hud.cpp | 10 +++++----- cl_dll/hud.h | 8 ++++++++ cl_dll/hud_oldscoreboard.cpp | 2 +- cl_dll/hud_oldscoreboard.h | 1 - cl_dll/hud_playerid.cpp | 2 +- cl_dll/hud_redraw.cpp | 4 ++-- cl_dll/statusbar.cpp | 2 +- cl_dll/vgui_CustomObjects.cpp | 4 ++-- cl_dll/vgui_TeamFortressViewport.cpp | 4 ++-- cl_dll/voice_status.cpp | 30 +++++++++++++++------------- 14 files changed, 50 insertions(+), 38 deletions(-) diff --git a/cl_dll/MOTD.cpp b/cl_dll/MOTD.cpp index e4d5208f..8809c1b5 100644 --- a/cl_dll/MOTD.cpp +++ b/cl_dll/MOTD.cpp @@ -27,6 +27,8 @@ //DECLARE_MESSAGE( m_MOTD, MOTD ); +cvar_t *motd_display_time; + int CHudMOTD::MOTD_DISPLAY_TIME; int CHudMOTD :: Init( void ) @@ -35,7 +37,7 @@ int CHudMOTD :: Init( void ) // HOOK_MESSAGE( MOTD ); - CVAR_CREATE( "motd_display_time", "15", 0 ); + motd_display_time = CVAR_CREATE( "motd_display_time", "15", 0 ); m_iFlags &= ~HUD_ACTIVE; // start out inactive m_szMOTD[0] = 0; @@ -139,7 +141,7 @@ int CHudMOTD :: MsgFunc_MOTD( const char *pszName, int iSize, void *pbuf ) { m_iFlags |= HUD_ACTIVE; - MOTD_DISPLAY_TIME = max( 10, CVAR_GET_FLOAT( "motd_display_time" ) ); + MOTD_DISPLAY_TIME = max( 10, motd_display_time->value ); m_flActiveRemaining = MOTD_DISPLAY_TIME; diff --git a/cl_dll/ammo.cpp b/cl_dll/ammo.cpp index da8f47e3..c2ea1461 100644 --- a/cl_dll/ammo.cpp +++ b/cl_dll/ammo.cpp @@ -287,8 +287,8 @@ int CHudAmmo::Init(void) Reset(); - CVAR_CREATE( "hud_drawhistory_time", HISTORY_DRAW_TIME, FCVAR_ARCHIVE ); - CVAR_CREATE( "hud_fastswitch", "0", FCVAR_ARCHIVE ); // controls whether or not weapons can be selected in one keypress + gHUD.hud_drawhistory_time = CVAR_CREATE( "hud_drawhistory_time", HISTORY_DRAW_TIME, FCVAR_ARCHIVE ); + gHUD.hud_fastswitch = CVAR_CREATE( "hud_fastswitch", "0", FCVAR_ARCHIVE ); // controls whether or not weapons can be selected in one keypress hud_weapon = CVAR_CREATE("hud_weapon", 0, FCVAR_ARCHIVE); @@ -436,7 +436,7 @@ void WeaponsResource :: SelectSlot( int iSlot, int fAdvance, int iDirection ) return; WEAPON *p = NULL; - bool fastSwitch = CVAR_GET_FLOAT( "hud_fastswitch" ) != 0; + bool fastSwitch = gHUD.hud_fastswitch->value != 0; if ( (gpActiveSel == NULL) || (gpActiveSel == (WEAPON *)1) || (iSlot != gpActiveSel->iSlot) ) { diff --git a/cl_dll/ammohistory.cpp b/cl_dll/ammohistory.cpp index c3797770..885ec995 100644 --- a/cl_dll/ammohistory.cpp +++ b/cl_dll/ammohistory.cpp @@ -55,7 +55,7 @@ void HistoryResource :: AddToHistory( int iType, int iId, int iCount ) } HIST_ITEM *freeslot = &rgAmmoHistory[iCurrentHistorySlot++]; // default to just writing to the first slot - HISTORY_DRAW_TIME = CVAR_GET_FLOAT( "hud_drawhistory_time" ); + HISTORY_DRAW_TIME = gHUD.hud_drawhistory_time->value; freeslot->type = iType; freeslot->iId = iId; @@ -86,7 +86,7 @@ void HistoryResource :: AddToHistory( int iType, const char *szName, int iCount freeslot->type = iType; freeslot->iCount = iCount; - HISTORY_DRAW_TIME = CVAR_GET_FLOAT( "hud_drawhistory_time" ); + HISTORY_DRAW_TIME = gHUD.hud_drawhistory_time->value; freeslot->DisplayTime = gHUD.m_flTime + HISTORY_DRAW_TIME; } diff --git a/cl_dll/death.cpp b/cl_dll/death.cpp index b9051f5a..3b1574eb 100644 --- a/cl_dll/death.cpp +++ b/cl_dll/death.cpp @@ -53,6 +53,7 @@ float g_ColorGrey[3] = { 0.8, 0.8, 0.8 }; cvar_t *m_pCvarKillSnd; cvar_t *m_pCvarKillSndPath; +cvar_t *hud_deathnotice_time; float *GetClientColor( int clientIndex ) { @@ -76,7 +77,7 @@ int CHudDeathNotice :: Init( void ) HOOK_MESSAGE( DeathMsg ); - CVAR_CREATE( "hud_deathnotice_time", "6", FCVAR_ARCHIVE ); + hud_deathnotice_time = CVAR_CREATE( "hud_deathnotice_time", "6", FCVAR_ARCHIVE ); m_pCvarKillSnd = CVAR_CREATE( "cl_killsound", "0", FCVAR_ARCHIVE ); m_pCvarKillSndPath = CVAR_CREATE( "cl_killsound_path", "buttons/bell1.wav", FCVAR_ARCHIVE ); @@ -265,7 +266,7 @@ int CHudDeathNotice :: MsgFunc_DeathMsg( const char *pszName, int iSize, void *p rgDeathNoticeList[i].iId = spr; - DEATHNOTICE_DISPLAY_TIME = CVAR_GET_FLOAT( "hud_deathnotice_time" ); + DEATHNOTICE_DISPLAY_TIME = hud_deathnotice_time->value; rgDeathNoticeList[i].flDisplayTime = gHUD.m_flTime + DEATHNOTICE_DISPLAY_TIME; // Play kill sound diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index d8d9486b..441d3499 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -504,8 +504,8 @@ void CHud :: Init( void ) HOOK_MESSAGE( CRC32 ); HOOK_MESSAGE( PlaySound ); - CVAR_CREATE( "hud_classautokill", "1", FCVAR_ARCHIVE | FCVAR_USERINFO ); // 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 + hud_classautokill = CVAR_CREATE( "hud_classautokill", "1", FCVAR_ARCHIVE | FCVAR_USERINFO ); // controls whether or not to suicide immediately on TF class switch + hud_takesshots = CVAR_CREATE( "hud_takesshots", "0", FCVAR_ARCHIVE ); // controls whether or not to automatically take screenshots at the end of a round // Implemented server-side, needs to be registered client-side. CVAR_CREATE( "cl_autowepswitch", "1", FCVAR_ARCHIVE | FCVAR_USERINFO | FCVAR_CLIENTDLL ); @@ -517,7 +517,7 @@ void CHud :: Init( void ) m_iLogo = 0; m_iFOV = 0; - CVAR_CREATE( "zoom_sensitivity_ratio", "1.2", 0 ); + zoom_sensitivity_ratio = CVAR_CREATE( "zoom_sensitivity_ratio", "1.2", 0 ); default_fov = CVAR_CREATE( "default_fov", "90", FCVAR_ARCHIVE ); m_pCvarStealMouse = CVAR_CREATE( "hud_capturemouse", "1", FCVAR_ARCHIVE ); m_pCvarDraw = CVAR_CREATE( "hud_draw", "1", FCVAR_ARCHIVE ); @@ -863,7 +863,7 @@ 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" ); + int def_fov = default_fov->value; //Weapon prediction already takes care of changing the fog. ( g_lastFOV ). if ( cl_lw && cl_lw->value ) @@ -891,7 +891,7 @@ int CHud::MsgFunc_SetFOV(const char *pszName, int iSize, void *pbuf) 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"); + m_flMouseSensitivity = sensitivity->value * ((float)newfov / (float)def_fov) * zoom_sensitivity_ratio->value; } return 1; diff --git a/cl_dll/hud.h b/cl_dll/hud.h index bebc755d..3aca137a 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -601,6 +601,14 @@ class CHud cvar_t *m_pCvarHideCorpses; cvar_t *m_pCvarHideOtherPlayers; cvar_t *m_pCvarPlayTeamSoundsVolume; + cvar_t *m_pCvarOldScoreboard; + + cvar_t *hud_fastswitch; + cvar_t *hud_drawhistory_time; + cvar_t *zoom_sensitivity_ratio; + cvar_t *hud_takesshots; + cvar_t *hud_classautokill; + cvar_t *hud_centerid; int m_iFontHeight; diff --git a/cl_dll/hud_oldscoreboard.cpp b/cl_dll/hud_oldscoreboard.cpp index d0ac45a7..0423dfbd 100644 --- a/cl_dll/hud_oldscoreboard.cpp +++ b/cl_dll/hud_oldscoreboard.cpp @@ -37,7 +37,7 @@ int CHudOldScoreboard::Init(void) { - m_pCvarOldScoreboard = CVAR_CREATE("cl_old_scoreboard", "0", FCVAR_ARCHIVE); + gHUD.m_pCvarOldScoreboard = CVAR_CREATE("cl_old_scoreboard", "0", FCVAR_ARCHIVE); m_pCvarOldScoreboardWidth = CVAR_CREATE("cl_old_scoreboard_width", DEFAULT_WIDTH, FCVAR_ARCHIVE); m_iFlags = 0; diff --git a/cl_dll/hud_oldscoreboard.h b/cl_dll/hud_oldscoreboard.h index cba46e65..99a77a59 100644 --- a/cl_dll/hud_oldscoreboard.h +++ b/cl_dll/hud_oldscoreboard.h @@ -24,7 +24,6 @@ class CHudOldScoreboard: public CHudBase icon_flagstatus_t m_IconFlagScore; - cvar_t *m_pCvarOldScoreboard; cvar_t *m_pCvarOldScoreboardWidth; cvar_t *m_pCvarOldScoreboardColorsTags; diff --git a/cl_dll/hud_playerid.cpp b/cl_dll/hud_playerid.cpp index 8e3be065..b4b2ba6b 100644 --- a/cl_dll/hud_playerid.cpp +++ b/cl_dll/hud_playerid.cpp @@ -51,7 +51,7 @@ int CHudPlayerId::Draw(float time) else sprintf(str, "%s", name); - if (CVAR_GET_FLOAT("hud_centerid")) + if (gHUD.hud_centerid->value) gHUD.DrawHudStringCenteredWithColorTags(ScreenWidth / 2, ScreenHeight - ScreenHeight / 4, str, diff --git a/cl_dll/hud_redraw.cpp b/cl_dll/hud_redraw.cpp index 8170f911..dc36c5f9 100644 --- a/cl_dll/hud_redraw.cpp +++ b/cl_dll/hud_redraw.cpp @@ -76,7 +76,7 @@ void CHud::Think(void) else { // set a new sensitivity that is proportional to the change from the FOV default - m_flMouseSensitivity = sensitivity->value * ((float)newfov / (float)default_fov->value) * CVAR_GET_FLOAT("zoom_sensitivity_ratio"); + m_flMouseSensitivity = sensitivity->value * ((float)newfov / (float)default_fov->value) * zoom_sensitivity_ratio->value; } // think about default fov @@ -129,7 +129,7 @@ int CHud :: Redraw( float flTime, int intermission ) gViewPort->UpdateSpectatorPanel(); // Take a screenshot if the client's got the cvar set - if ( CVAR_GET_FLOAT( "hud_takesshots" ) != 0 ) + if ( hud_takesshots->value != 0 ) m_flShotTime = flTime + 1.0; // Take a screenshot in a second if ( m_pCvarAutostop->value > 0.0f ) diff --git a/cl_dll/statusbar.cpp b/cl_dll/statusbar.cpp index 2ae41c55..e5ce3828 100644 --- a/cl_dll/statusbar.cpp +++ b/cl_dll/statusbar.cpp @@ -47,7 +47,7 @@ int CHudStatusBar :: Init( void ) Reset(); - CVAR_CREATE( "hud_centerid", "0", FCVAR_ARCHIVE ); + gHUD.hud_centerid = CVAR_CREATE( "hud_centerid", "0", FCVAR_ARCHIVE ); return 1; } diff --git a/cl_dll/vgui_CustomObjects.cpp b/cl_dll/vgui_CustomObjects.cpp index 5b49a3ec..cb97d5d5 100644 --- a/cl_dll/vgui_CustomObjects.cpp +++ b/cl_dll/vgui_CustomObjects.cpp @@ -311,7 +311,7 @@ int ClassButton::IsNotValid() #endif // Only check current class if they've got autokill on - bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0; + bool bAutoKill = gHUD.hud_classautokill->value != 0; if ( bAutoKill ) { // Is it the player's current class? @@ -546,7 +546,7 @@ void CMenuHandler_StringCommandClassSelect::actionPerformed(Panel* panel) // HAVE THE SERVER SAY "SORRY...YOU CAN'T BE THAT CLASS". #if !defined _TFC - bool bAutoKill = CVAR_GET_FLOAT( "hud_classautokill" ) != 0; + bool bAutoKill = gHUD.hud_classautokill->value != 0; if ( bAutoKill && g_iPlayerClass != 0 ) gEngfuncs.pfnClientCmd("kill"); #endif diff --git a/cl_dll/vgui_TeamFortressViewport.cpp b/cl_dll/vgui_TeamFortressViewport.cpp index ad3fdb01..8e9e7706 100644 --- a/cl_dll/vgui_TeamFortressViewport.cpp +++ b/cl_dll/vgui_TeamFortressViewport.cpp @@ -1405,7 +1405,7 @@ void TeamFortressViewport::ShowScoreBoard( void ) { // The user can change the scoreboard style while the scoreboard is being "drawn" (e.g. when togglescores is on) // Therefore make sure to close/hide the other one first - if (CVAR_GET_FLOAT("cl_old_scoreboard") != 0) + if (gHUD.m_pCvarOldScoreboard->value != 0) { m_pScoreBoard->setVisible(false); gHUD.m_OldScoreBoard.ShowScoreboard(true); @@ -1427,7 +1427,7 @@ bool TeamFortressViewport::IsScoreBoardVisible( void ) { if (m_pScoreBoard) { - if (CVAR_GET_FLOAT("cl_old_scoreboard") != 0) + if (gHUD.m_pCvarOldScoreboard->value != 0) return gHUD.m_OldScoreBoard.IsVisible(); else return m_pScoreBoard->isVisible(); diff --git a/cl_dll/voice_status.cpp b/cl_dll/voice_status.cpp index ae166e20..2b7b22ab 100644 --- a/cl_dll/voice_status.cpp +++ b/cl_dll/voice_status.cpp @@ -187,15 +187,17 @@ CVoiceStatus::~CVoiceStatus() } } +cvar_t *voice_modenable; +cvar_t *voice_clientdebug; int CVoiceStatus::Init( IVoiceStatusHelper *pHelper, Panel **pParentPanel) { // Setup the voice_modenable cvar. - gEngfuncs.pfnRegisterVariable("voice_modenable", "1", FCVAR_ARCHIVE); + voice_modenable = gEngfuncs.pfnRegisterVariable("voice_modenable", "1", FCVAR_ARCHIVE); - gEngfuncs.pfnRegisterVariable("voice_clientdebug", "0", 0); + voice_clientdebug = gEngfuncs.pfnRegisterVariable("voice_clientdebug", "0", 0); gEngfuncs.pfnAddCommand("voice_showbanned", ShowBannedCallback); @@ -405,7 +407,7 @@ void CVoiceStatus::UpdateSpeakerStatus( int entindex, qboolean bTalking ) return; } - if ( gEngfuncs.pfnGetCvarFloat( "voice_clientdebug" ) ) + if ( voice_clientdebug->value != 0.0f ) { char msg[256]; _snprintf( msg, sizeof( msg ), "CVoiceStatus::UpdateSpeakerStatus: ent %d talking = %d\n", entindex, bTalking ); @@ -510,7 +512,7 @@ void CVoiceStatus::UpdateServerState(bool bForce) char const *pLevelName = gEngfuncs.pfnGetLevelName(); if( pLevelName[0] == 0 ) { - if( gEngfuncs.pfnGetCvarFloat("voice_clientdebug") ) + if( voice_clientdebug->value != 0.0f ) { gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: pLevelName[0]==0\n" ); } @@ -518,7 +520,7 @@ void CVoiceStatus::UpdateServerState(bool bForce) return; } - int bCVarModEnable = !!gEngfuncs.pfnGetCvarFloat("voice_modenable"); + int bCVarModEnable = !!voice_modenable->value; if(bForce || m_bServerModEnable != bCVarModEnable) { m_bServerModEnable = bCVarModEnable; @@ -527,7 +529,7 @@ void CVoiceStatus::UpdateServerState(bool bForce) _snprintf(str, sizeof(str), "VModEnable %d", m_bServerModEnable); ServerCmd(str); - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) + if( voice_clientdebug->value != 0.0f ) { char msg[256]; snprintf(msg, sizeof(msg), "CVoiceStatus::UpdateServerState: Sending '%s'\n", str); @@ -567,7 +569,7 @@ void CVoiceStatus::UpdateServerState(bool bForce) if(bChange || bForce) { - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) + if( voice_clientdebug->value != 0.0f ) { char msg[256]; snprintf(msg, sizeof(msg), "CVoiceStatus::UpdateServerState: Sending '%s'\n", str); @@ -578,7 +580,7 @@ void CVoiceStatus::UpdateServerState(bool bForce) } else { - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) + if ( voice_clientdebug->value != 0.0f ) { gEngfuncs.pfnConsolePrint( "CVoiceStatus::UpdateServerState: no change\n" ); } @@ -650,7 +652,7 @@ void CVoiceStatus::HandleVoiceMaskMsg(int iSize, void *pbuf) m_AudiblePlayers.SetDWord(dw, (unsigned long)READ_LONG()); m_ServerBannedPlayers.SetDWord(dw, (unsigned long)READ_LONG()); - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) + if( voice_clientdebug->value != 0.0f ) { char str[256]; gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleVoiceMaskMsg\n"); @@ -668,7 +670,7 @@ void CVoiceStatus::HandleVoiceMaskMsg(int iSize, void *pbuf) void CVoiceStatus::HandleReqStateMsg(int iSize, void *pbuf) { - if(gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) + if( voice_clientdebug->value != 0.0f ) { gEngfuncs.pfnConsolePrint("CVoiceStatus::HandleReqStateMsg\n"); } @@ -771,7 +773,7 @@ void CVoiceStatus::RepositionLabels() m_pLocalLabel->setParent(*m_pParentPanel); m_pLocalLabel->setVisible( true ); - if( m_bServerAcked && !!gEngfuncs.pfnGetCvarFloat("voice_clientdebug") ) + if( m_bServerAcked && !!voice_clientdebug->value ) m_pLocalLabel->setImage( m_pAckBitmap ); else m_pLocalLabel->setImage( m_pLocalBitmap ); @@ -872,7 +874,7 @@ bool CVoiceStatus::IsPlayerAudible(int iPlayer) //----------------------------------------------------------------------------- void CVoiceStatus::SetPlayerBlockedState(int iPlayer, bool blocked) { - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) + if ( voice_clientdebug->value != 0.0f ) { gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 1\n" ); } @@ -881,13 +883,13 @@ void CVoiceStatus::SetPlayerBlockedState(int iPlayer, bool blocked) if (!gEngfuncs.GetPlayerUniqueID(iPlayer, playerID)) return; - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) + if ( voice_clientdebug->value != 0.0f ) { gEngfuncs.pfnConsolePrint( "CVoiceStatus::SetPlayerBlockedState part 2\n" ); } // Squelch or (try to) unsquelch this player. - if (gEngfuncs.pfnGetCvarFloat("voice_clientdebug")) + if ( voice_clientdebug->value != 0.0f ) { char str[256]; sprintf(str, "CVoiceStatus::SetPlayerBlockedState: setting player %d ban to %d\n", iPlayer, !m_BanMgr.GetPlayerBan(playerID)); From 5b0b52d3f240bddb144a87102ef8b0f1e09703f0 Mon Sep 17 00:00:00 2001 From: SmileyAG Date: Fri, 8 Dec 2023 13:43:36 +0400 Subject: [PATCH 28/42] Added hashedcdkey and m_nSteamID variables at the end of player_info_t To get directly access for SteamID of player, bypass of receiving AuthID message from the server-side --- common/com_model.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/com_model.h b/common/com_model.h index c014a399..53c2afb0 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -346,6 +346,10 @@ typedef struct player_info_s vec3_t prevgaitorigin; customization_t customdata; + + char hashedcdkey[16]; + + uint64 m_nSteamID; } player_info_t; #endif // #define COM_MODEL_H From 6c75ed8d13cbc9814d441726b247b6ae1b95b178 Mon Sep 17 00:00:00 2001 From: SmileyAG Date: Fri, 8 Dec 2023 14:13:39 +0400 Subject: [PATCH 29/42] Matched structs in com_model.h with hardware and software engine versions --- common/com_model.h | 77 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/common/com_model.h b/common/com_model.h index 53c2afb0..3f1eb278 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -94,12 +94,23 @@ typedef struct texture_s { char name[16]; unsigned width, height; + +#ifndef SOFTWARE_BUILD + int gl_texturenum; // gl texture binding + struct msurface_s *texturechain; // for sort-by-texture world drawing +#endif + 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 + +#ifdef SOFTWARE_BUILD unsigned paloffset; +#else + byte *pPal; +#endif } texture_t; typedef struct @@ -117,8 +128,12 @@ typedef struct mnode_s // common with leaf int contents; // 0, to differentiate from leafs int visframe; // node needs to be traversed if current - + +#ifdef SOFTWARE_BUILD short minmaxs[6]; // for bounding box culling +#else + float minmaxs[6]; // for bounding box culling +#endif struct mnode_s *parent; @@ -138,11 +153,20 @@ struct decal_s { decal_t *pnext; // linked list for each surface msurface_t *psurface; // Surface id for persistence / unlinking + +#ifdef SOFTWARE_BUILD 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 +#else + float dx; + float dy; + float scale; // Pixel scale + short texture; // Decal texture + short flags; // Decal flags +#endif short entityIndex; // Entity this is attached to }; @@ -153,7 +177,11 @@ typedef struct mleaf_s int contents; // wil be a negative contents number int visframe; // node needs to be traversed if current +#ifdef SOFTWARE_BUILD short minmaxs[6]; // for bounding box culling +#else + float minmaxs[6]; // for bounding box culling +#endif struct mnode_s *parent; @@ -167,6 +195,18 @@ typedef struct mleaf_s byte ambient_sound_level[NUM_AMBIENTS]; } mleaf_t; +#define VERTEXSIZE 7 + +typedef struct glpoly_s +{ + struct glpoly_s *next; + struct glpoly_s *chain; + int numverts; + int flags; + float verts[4][VERTEXSIZE]; +} glpoly_t; + +#ifdef SOFTWARE_BUILD struct msurface_s { int visframe; // should be drawn when node is crossed @@ -197,6 +237,41 @@ struct msurface_s decal_t *pdecals; }; +#else +struct msurface_s +{ + int visframe; // should be drawn when node is crossed + + 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 + + short texturemins[2]; // smallest s/t position on the surface. + short extents[2]; // ?? s/t texture size, 1..256 for all non-sky surfaces + + int light_s, light_t; // gl lightmap coordinates + + glpoly_t *polys; // multiple if warped + struct msurface_s *texturechain; + + mtexinfo_t *texinfo; + + // lighting info + 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. + + int lightmaptexturenum; + unsigned char styles[MAXLIGHTMAPS]; + int cached_light[MAXLIGHTMAPS]; // values currently used in lightmap + qboolean cached_dlight; // true if dynamic light in cache + + color24 *samples; // note: this is the actual lightmap data for this surface + decal_t *pdecals; +}; +#endif typedef struct { From 87ee37d19bef1e703f1e8a4e645e3d319ec4cf25 Mon Sep 17 00:00:00 2001 From: SmileyAG Date: Fri, 8 Dec 2023 14:17:49 +0400 Subject: [PATCH 30/42] Commented new variable at end of msurface_t struct that got added with 25th anniversary update for Half-Life --- common/com_model.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/common/com_model.h b/common/com_model.h index 3f1eb278..da5c02c9 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -206,6 +206,14 @@ typedef struct glpoly_s float verts[4][VERTEXSIZE]; } glpoly_t; +typedef struct mdisplaylist_t // Half-Life 25th Anniversary Update +{ + unsigned gl_displaylist; + int rendermode; + float scrolloffset; + int renderDetailTexture; +} mdisplaylist_t; + #ifdef SOFTWARE_BUILD struct msurface_s { @@ -270,6 +278,8 @@ struct msurface_s color24 *samples; // note: this is the actual lightmap data for this surface decal_t *pdecals; + + //mdisplaylist_t displaylist; // Half-Life 25th Anniversary Update }; #endif From ad291141fe83fbfd433da30cde64bc2a6278e99d Mon Sep 17 00:00:00 2001 From: SmileyAG Date: Sat, 9 Dec 2023 07:00:35 +0400 Subject: [PATCH 31/42] Added undocumented functions at the end of cl_enginefunc_t and enginefuncs_t interfaces (about enginefuncs_t: even that server-side not from AG mod, that still could be used as reference for pointing in github issues as one of example) --- engine/APIProxy.h | 4 ++++ engine/cdll_int.h | 1 + engine/eiface.h | 7 ++----- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/engine/APIProxy.h b/engine/APIProxy.h index f3a1ed27..18fd0924 100644 --- a/engine/APIProxy.h +++ b/engine/APIProxy.h @@ -353,6 +353,7 @@ typedef void (*pfnEngSrc_pfnFillRGBABlend_t ) ( int x, int y, int width, typedef int (*pfnEngSrc_pfnGetAppID_t) ( void ); typedef cmdalias_t* (*pfnEngSrc_pfnGetAliases_t) ( void ); typedef void (*pfnEngSrc_pfnVguiWrap2_GetMouseDelta_t) ( int *x, int *y ); +typedef int (*pfnEngSrc_pfnFilteredClientCmd_t) ( char *pszCmdString ); // Pointers to the exported engine functions themselves typedef struct cl_enginefuncs_s @@ -491,6 +492,7 @@ typedef struct cl_enginefuncs_s pfnEngSrc_pfnGetAppID_t pfnGetAppID; pfnEngSrc_pfnGetAliases_t pfnGetAliasList; pfnEngSrc_pfnVguiWrap2_GetMouseDelta_t pfnVguiWrap2_GetMouseDelta; + pfnEngSrc_pfnFilteredClientCmd_t pfnFilteredClientCmd; } cl_enginefunc_t; // Function type declarations for engine destination functions @@ -610,6 +612,7 @@ typedef void (*pfnEngDst_pfnFillRGBABlend_t ) ( int *, int *, int *, int *, i typedef void (*pfnEngDst_pfnGetAppID_t ) ( void ); typedef void (*pfnEngDst_pfnGetAliases_t ) ( void ); typedef void (*pfnEngDst_pfnVguiWrap2_GetMouseDelta_t) ( int *x, int *y ); +typedef void (*pfnEngDst_pfnFilteredClientCmd_t) ( char ** ); // Pointers to the engine destination functions @@ -737,6 +740,7 @@ typedef struct pfnEngDst_pfnGetAppID_t pfnGetAppID; pfnEngDst_pfnGetAliases_t pfnGetAliasList; pfnEngDst_pfnVguiWrap2_GetMouseDelta_t pfnVguiWrap2_GetMouseDelta; + pfnEngDst_pfnFilteredClientCmd_t pfnFilteredClientCmd; } cl_enginefunc_dst_t; diff --git a/engine/cdll_int.h b/engine/cdll_int.h index 555800fe..057c1fec 100644 --- a/engine/cdll_int.h +++ b/engine/cdll_int.h @@ -410,6 +410,7 @@ extern void NullDst(void); (pfnEngDst_pfnGetAppID_t) NullDst, \ (pfnEngDst_pfnGetAliases_t) NullDst, \ (pfnEngDst_pfnVguiWrap2_GetMouseDelta_t) NullDst, \ + (pfnEngDst_pfnFilteredClientCmd_t) NullDst, \ }; // Use this to init a cldll_func_dst structure to point to NullDst diff --git a/engine/eiface.h b/engine/eiface.h index 84c1f9bb..b2e9ad61 100644 --- a/engine/eiface.h +++ b/engine/eiface.h @@ -17,11 +17,7 @@ #include "archtypes.h" // DAL -#ifdef HLDEMO_BUILD -#define INTERFACE_VERSION 001 -#else // !HLDEMO_BUILD, i.e., regular version of HL #define INTERFACE_VERSION 140 -#endif // !HLDEMO_BUILD #include #include "custom.h" @@ -296,10 +292,11 @@ typedef struct enginefuncs_s void (*pfnQueryClientCvarValue)( const edict_t *player, const char *cvarName ); void (*pfnQueryClientCvarValue2)( const edict_t *player, const char *cvarName, int requestID ); int (*pfnCheckParm)( const char *pchCmdLineToken, char **ppnext ); + edict_t* (*pfnPEntityOfEntIndexAllEntities)( int iEntIndex ); } enginefuncs_t; -// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 138 +// ONLY ADD NEW FUNCTIONS TO THE END OF THIS STRUCT. INTERFACE VERSION IS FROZEN AT 140 // Passed to pfnKeyValue typedef struct KeyValueData_s From c20683113c5dd0e244611980e42c6acd3b68f8be Mon Sep 17 00:00:00 2001 From: SmileyAG Date: Tue, 12 Dec 2023 08:02:57 +0400 Subject: [PATCH 32/42] Added commented code for initialize the old MOTD implementation and fixed for compilation --- cl_dll/CMakeLists.txt | 1 + cl_dll/MOTD.cpp | 5 ++--- cl_dll/hud.cpp | 4 ++++ cl_dll/hud.h | 27 +++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/cl_dll/CMakeLists.txt b/cl_dll/CMakeLists.txt index a1904d93..0953a8a5 100644 --- a/cl_dll/CMakeLists.txt +++ b/cl_dll/CMakeLists.txt @@ -95,6 +95,7 @@ add_sources( kbutton.h menu.cpp message.cpp +# MOTD.cpp rainbow.cpp rainbow.h saytext.cpp diff --git a/cl_dll/MOTD.cpp b/cl_dll/MOTD.cpp index 8809c1b5..6262dff7 100644 --- a/cl_dll/MOTD.cpp +++ b/cl_dll/MOTD.cpp @@ -27,8 +27,6 @@ //DECLARE_MESSAGE( m_MOTD, MOTD ); -cvar_t *motd_display_time; - int CHudMOTD::MOTD_DISPLAY_TIME; int CHudMOTD :: Init( void ) @@ -97,7 +95,8 @@ int CHudMOTD :: Draw( float fTime ) 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++ ) + char *next_line; + for ( 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' ) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 441d3499..71f89581 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -378,6 +378,8 @@ int __MsgFunc_VGUIMenu(const char *pszName, int iSize, void *pbuf) int __MsgFunc_MOTD(const char *pszName, int iSize, void *pbuf) { + //return gHUD.m_MOTD.MsgFunc_MOTD(pszName, iSize, pbuf); + if (gViewPort) return gViewPort->MsgFunc_MOTD( pszName, iSize, pbuf ); return 0; @@ -560,6 +562,7 @@ void CHud :: Init( void ) m_Battery.Init(); m_Flash.Init(); m_Message.Init(); +// m_MOTD.Init(); m_StatusBar.Init(); m_DeathNotice.Init(); m_AmmoSecondary.Init(); @@ -726,6 +729,7 @@ void CHud :: VidInit( void ) m_Battery.VidInit(); m_Flash.VidInit(); m_Message.VidInit(); +// m_MOTD.VidInit(); m_StatusBar.VidInit(); m_DeathNotice.VidInit(); m_SayText.VidInit(); diff --git a/cl_dll/hud.h b/cl_dll/hud.h index 3aca137a..0c2f367a 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -223,7 +223,33 @@ class CHudTrain: public CHudBase 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; + + cvar_t *motd_display_time; +}; +*/ // //----------------------------------------------------- // @@ -679,6 +705,7 @@ class CHud CHudTrain m_Train; CHudFlashlight m_Flash; CHudMessage m_Message; +// CHudMOTD m_MOTD; CHudStatusBar m_StatusBar; CHudDeathNotice m_DeathNotice; CHudSayText m_SayText; From 84c813de7d3152253cd87e6dcf05c6bc2055fcdd Mon Sep 17 00:00:00 2001 From: SmileyAG Date: Thu, 14 Dec 2023 16:23:53 +0400 Subject: [PATCH 33/42] Moved some of cvar declarations to corresponding classes for them at headers for more flexibility with changing --- cl_dll/death.cpp | 4 ---- cl_dll/hud.h | 8 ++++++++ cl_dll/text_message.cpp | 2 -- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cl_dll/death.cpp b/cl_dll/death.cpp index 3b1574eb..71a609a8 100644 --- a/cl_dll/death.cpp +++ b/cl_dll/death.cpp @@ -51,10 +51,6 @@ float g_ColorGreen[3] = { 0.6, 1.0, 0.6 }; float g_ColorYellow[3] = { 1.0, 0.7, 0.0 }; float g_ColorGrey[3] = { 0.8, 0.8, 0.8 }; -cvar_t *m_pCvarKillSnd; -cvar_t *m_pCvarKillSndPath; -cvar_t *hud_deathnotice_time; - float *GetClientColor( int clientIndex ) { switch ( g_PlayerExtraInfo[clientIndex].teamnumber ) diff --git a/cl_dll/hud.h b/cl_dll/hud.h index 0c2f367a..7fe7ecb0 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -323,6 +323,11 @@ class CHudDeathNotice : public CHudBase private: int m_HUD_d_skull; // sprite index of skull icon + +protected: + cvar_t *m_pCvarKillSnd; + cvar_t *m_pCvarKillSndPath; + cvar_t *hud_deathnotice_time; }; // @@ -455,6 +460,9 @@ class CHudTextMessage: public CHudBase static char *BufferedLocaliseTextString( const char *msg ); const char *LookupString( const char *msg_name, int *msg_dest = NULL ); int MsgFunc_TextMsg(const char *pszName, int iSize, void *pbuf); + +protected: + cvar_t *m_pCvarHideCenterMessages; }; // diff --git a/cl_dll/text_message.cpp b/cl_dll/text_message.cpp index 8ecd924e..b07fcbcb 100644 --- a/cl_dll/text_message.cpp +++ b/cl_dll/text_message.cpp @@ -28,8 +28,6 @@ #include "vgui_TeamFortressViewport.h" -cvar_t *m_pCvarHideCenterMessages; - DECLARE_MESSAGE( m_TextMessage, TextMsg ); int CHudTextMessage::Init(void) From 4ad5b2fd55439b1d84b104afd9112900d85d7364 Mon Sep 17 00:00:00 2001 From: SmileyAG Date: Sat, 23 Dec 2023 13:18:18 +0400 Subject: [PATCH 34/42] Added cmd_function_t structure --- engine/cmd.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 engine/cmd.h diff --git a/engine/cmd.h b/engine/cmd.h new file mode 100644 index 00000000..06851f0b --- /dev/null +++ b/engine/cmd.h @@ -0,0 +1,36 @@ +// cmd.h -- Command buffer and command execution + +//=========================================================================== + +/* +Any number of commands can be added in a frame, from several different sources. +Most commands come from either keybindings or console line input, but remote +servers can also send across commands and entire text files can be execed. + +The + command line options are also added to the command buffer. + +The game starts with a Cbuf_AddText ("exec quake.rc\n"); Cbuf_Execute (); + +*/ + +//=========================================================================== + +/* +Command execution takes a null terminated string, breaks it into tokens, +then searches for a command or variable that matches the first token. + +Commands can come from three sources, but the handler functions may choose +to dissallow the action or forward it to a remote server if the source is +not apropriate. + +*/ + +typedef void (*xcommand_t) (void); + +typedef struct cmd_function_s +{ + struct cmd_function_s *next; + char *name; + xcommand_t function; + int flags; +} cmd_function_t; \ No newline at end of file From 0ad666a1f2bee01da47e2880877d6d3c735be06b Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Sat, 30 Dec 2023 11:22:07 +0400 Subject: [PATCH 35/42] Make a new list for hardcoded map series in Discord RPC module and fixed declaration of struct in com_model.h (#185) * Added discord_rpc_closest_map_match to pickup map from list that closest match to current * Convert the name of the current map and maps in the list to lowercase always * Revert changes from previous commit, added comment about adding maps for list only in lower case! * Removed discord_rpc_closest_map_match in favor of creating hardcoded map series list * Moved helper function for lowercase to cl_util.h * Replaced match method to eliminate wrong occurrences * Fixed quotes in comment * Separation of hldm and bhop maps into different lists for optimization For those who play only in deathmatch mode, this will be an optimization, because compared to bhop maps there are less of them in the lists * Revert empty lines that have been removed in one of previous commits * Combined both of hldm and bhop lists back to the single one, but added some comments for 'separating' them * map_series: replaced unordered_set to vector for O(n) --- cl_dll/cl_util.h | 9 +++ cl_dll/discord_integration.cpp | 109 +++++++++++++++++++-------------- common/com_model.h | 2 +- 3 files changed, 74 insertions(+), 46 deletions(-) diff --git a/cl_dll/cl_util.h b/cl_dll/cl_util.h index af195f69..f558de63 100644 --- a/cl_dll/cl_util.h +++ b/cl_dll/cl_util.h @@ -177,6 +177,15 @@ static size_t get_player_count() return player_count; } +inline void convert_to_lower_case(const char *str) +{ + unsigned char *str_lw = (unsigned char *)str; + while (*str_lw) { + *str_lw = tolower(*str_lw); + str_lw++; + } +} + 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 ) { diff --git a/cl_dll/discord_integration.cpp b/cl_dll/discord_integration.cpp index 30614821..a3fd93e9 100644 --- a/cl_dll/discord_integration.cpp +++ b/cl_dll/discord_integration.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -24,8 +25,53 @@ namespace discord_integration // This seems to be consistent across PCs. constexpr const char STEAM_APP_ID[] = "17215498729465839686"; - // Maps for which we have thumbnails. + // Maps in next lists must be lowercase! + // Discord RPC allow to upload 300 assets per app, but we also use one thumbnail as default icon, so the lists cannot contain more than 299 maps in total! + + // This list was specially created for a map series, let's say that "hl1_bhop_am" series have a several versions of maps (example: hl1_bhop_am_beta1), but in fact those maps are almost identical + // If the beginning of map name matches with what presented in the list, then we set the same name for the thumbnail as in the list (e.g. map name: hl1_bhop_uc1_beta1, thumbnail name: hl1_bhop_uc1) + const std::vector map_series { + "hl1_bhop_am"s, + "hl1_bhop_bp1"s, + "hl1_bhop_bp2"s, + "hl1_bhop_faf"s, + "hl1_bhop_lc"s, + "hl1_bhop_oar"s, + "hl1_bhop_ocwgh"s, + "hl1_bhop_pu"s, + "hl1_bhop_qe"s, + "hl1_bhop_rp"s, + "hl1_bhop_st"s, + "hl1_bhop_uc1"s, + "hl1_bhop_uc2"s, + }; + const std::unordered_set maps_with_thumbnails { + // DM maps + "boot_camp"s, + "bootbox"s, + "bounce"s, + "crossfire"s, + "datacore"s, + "dm_dust2"s, + "eden"s, + "elixir"s, + "endcamp"s, + "frenzy"s, + "gasworks"s, + "havoc"s, + "killbox"s, + "lost_village2"s, + "outcry"s, + "rapidcore"s, + "scary_1"s, + "snark_pit"s, + "stalkx"s, + "stalkyard"s, + "subtransit"s, + "urethane"s, + "vengeance"s, + // Bhop maps "2bfree"s, "8b1_hellinashop"s, "ag_bhop_dungeon"s, @@ -68,9 +114,6 @@ namespace discord_integration "bkz_aztecbhop"s, "bkz_goldbhop"s, "bkz_junglebhop"s, - "boot_camp"s, - "bootbox"s, - "bounce"s, "bunnyrace_beta2"s, "cg_cbblebhop"s, "cg_coldbhop_v2"s, @@ -80,43 +123,21 @@ namespace discord_integration "cnd_speed_bhop"s, "cobkz_construction"s, "cosy_merrychristmas4"s, - "crossfire"s, "d2_mario_bhop"s, - "datacore"s, "daza_junglebhop"s, "de_racetownz"s, "destructo_hops"s, "dev_control"s, "dg_winterclimb"s, - "dm_dust2"s, "dr0_deepbluesea"s, "dyd_axn_plant"s, "dyd_axn_sky"s, "dyd_cosy_cupbhop_ez"s, "e1m1"s, - "eden"s, - "elixir"s, - "endcamp"s, "fof_axn_scroll_killa"s, "fof_chillbhop"s, - "frenzy"s, "fu_darkhop"s, - "gasworks"s, "gayl0rd_bhop"s, - "havoc"s, - "hl1_bhop_am"s, - "hl1_bhop_bp1"s, - "hl1_bhop_bp2"s, - "hl1_bhop_faf"s, - "hl1_bhop_lc"s, - "hl1_bhop_oar"s, - "hl1_bhop_ocwgh"s, - "hl1_bhop_pu"s, - "hl1_bhop_qe"s, - "hl1_bhop_rp"s, - "hl1_bhop_st"s, - "hl1_bhop_uc1"s, - "hl1_bhop_uc2"s, "hl_trick"s, "hm_castlebhop"s, "hm_speedwinterz"s, @@ -128,7 +149,6 @@ namespace discord_integration "j2s_4floors"s, "jagkz_inferno"s, "ka_kart-race"s, - "killbox"s, "klbk_go"s, "ksz_skeleton"s, "kz-endo_bikinihop"s, @@ -168,24 +188,14 @@ namespace discord_integration "kzru_mam6ahop"s, "kzsca_snakebhop"s, "kzsca_watertemple"s, - "lost_village2"s, "mf_doom_e1m1_e"s, - "outcry"s, "pd_shafthop"s, "prochallenge2_longjump"s, - "rapidcore"s, "rnr_speedcrag"s, - "scary_1"s, "smk_floppytown"s, - "snark_pit"s, "speed_ytt_egypt"s, - "stalkx"s, - "stalkyard"s, - "subtransit"s, "uq_axn_imoor"s, "uq_skrol_bhop"s, - "urethane"s, - "vengeance"s, "xjbg_bhoptemple_hard"s, "zjumps"s, "ztricks"s @@ -343,17 +353,26 @@ namespace discord_integration get_map_name(map_name, ARRAYSIZE(map_name)); if (map_name[0]) { - // adjust to lowercase - unsigned char *tptr = (unsigned char *)map_name; - while (*tptr) { - *tptr = tolower(*tptr); - tptr++; - } + // We specifically don't want to convert the map name that will be shown when hovering over the map icon (presence.largeImageText), so that why it got moved above. + presence.largeImageText = map_name; + + convert_to_lower_case(map_name); if (maps_with_thumbnails.find(map_name) != maps_with_thumbnails.cend()) + { presence.largeImageKey = map_name; - - presence.largeImageText = map_name; + } + else + { + auto closest_match = std::find_if(map_series.begin(), map_series.end(), [&](const std::string& str) { + return static_cast(map_name).compare(0, str.length(), str) == 0; // hl1_bhop_am_beta6 -> hl1_bhop_am + }); + + if (closest_match != map_series.end()) + { + presence.largeImageKey = closest_match->c_str(); + } + } } // Get the server address. diff --git a/common/com_model.h b/common/com_model.h index da5c02c9..39e8f1da 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -206,7 +206,7 @@ typedef struct glpoly_s float verts[4][VERTEXSIZE]; } glpoly_t; -typedef struct mdisplaylist_t // Half-Life 25th Anniversary Update +typedef struct mdisplaylist_s // Half-Life 25th Anniversary Update { unsigned gl_displaylist; int rendermode; From 7c35c770553ebad521a74c6bf463b332c7bd6eca Mon Sep 17 00:00:00 2001 From: SmileyAG <58108407+SmileyAG@users.noreply.github.com> Date: Sun, 31 Dec 2023 10:37:36 +0400 Subject: [PATCH 36/42] Added cl_show_server_triggers_* cvars (related to plugin PR) (#183) * Added cl_show_server_triggers_* cvars (related to plugin PR) * Added IsTriggerForSinglePlayer function to rid from the triggers that unused in multiplayer * Added a new mode for displaying triggers via TriAPI which uses absmin/absmax * Replaced multiple vectors with vector of structs for flexibility * TriAPI triggers is only available for hardware mode * Fixed encoding issue in file * Allow to draw triggers in software engine with HUD_AddEntity if cvar value above 0 * Supported TriAPI triggers for software engine too * Loading white sprite now with each call of HUD_VidInit instead of once initialization to fix crash * SetMapName: added option to disable forcing to lowercase for RPC * Removed debug messages, map name and entities storing to std::vector as unnecessary * cl_show_server_triggers should be always 0 by default To not cost performance due of iterating through entities in cases when triggers are definitely not transmitted by plugin/server * get_map_name: removed memset as extra code * Use boolean expression to check for the valid 'white_sprite' * Use nested if statements for PR code in HUD_DrawTransparentTriangles function That done for versatility, since there is not much cases to check validity for * Replaced nested if statements with guard clauses for YaLTeR preferences * Don't need IEngineStudio for hardware check since the code is compatible with both engine versions from a while --- cl_dll/cdll_int.cpp | 2 + cl_dll/entity.cpp | 13 +++++ cl_dll/hud.cpp | 21 ++++++++ cl_dll/hud.h | 6 +++ cl_dll/hudgl.cpp | 2 + cl_dll/tri.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++ common/com_model.h | 2 +- common/const.h | 1 + 8 files changed, 159 insertions(+), 1 deletion(-) diff --git a/cl_dll/cdll_int.cpp b/cl_dll/cdll_int.cpp index 22987caf..ae8b3790 100644 --- a/cl_dll/cdll_int.cpp +++ b/cl_dll/cdll_int.cpp @@ -191,6 +191,8 @@ int CL_DLLEXPORT HUD_VidInit( void ) VGui_Startup(); + gHUD.white_sprite = gEngfuncs.pfnSPR_Load("sprites/white.spr"); + return 1; } diff --git a/cl_dll/entity.cpp b/cl_dll/entity.cpp index d6142d23..c5ceb91c 100644 --- a/cl_dll/entity.cpp +++ b/cl_dll/entity.cpp @@ -1,5 +1,6 @@ // Client side entity management functions +#include #include #include "hud.h" @@ -19,6 +20,12 @@ #include "discord_integration.h" #include "particleman.h" + +#include "r_studioint.h" + +#undef min +#undef max + extern IParticleMan *g_pParticleMan; void Game_AddObjects( void ); @@ -50,6 +57,12 @@ int CL_DLLEXPORT HUD_AddEntity( int type, struct cl_entity_s *ent, const char *m break; } + // show triggers that would be transferred from server-side with specific value in renderfx to differ it from other entities + // update: there is a new implementation of displaying triggers that allows you to display even when planes is stripped due to optimizations in updated map compiler + // so this code will only work if the value 2 is specified in the cvar, but it should not be deleted imo + if ((ent->curstate.rendermode == kRenderTransColor) && (ent->curstate.renderfx == kRenderFxTrigger) && (gHUD.m_pShowServerTriggers->value == 2.0f) && !gHUD.IsTriggerForSinglePlayer(ent->curstate.rendercolor)) + ent->curstate.renderamt = std::min(255.0f, std::max(0.0f, gHUD.m_pShowServerTriggersAlpha->value)); + // hide corpses option if (gHUD.m_pCvarHideCorpses->value > 0 && ent->curstate.renderfx == kRenderFxDeadPlayer) return 0; diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 71f89581..8d06d504 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -531,6 +531,8 @@ void CHud :: Init( void ) m_pCvarHideOtherPlayers = CVAR_CREATE("cl_hide_other_players", "0", 0); m_pCvarColor = CVAR_CREATE( "hud_color", "", FCVAR_ARCHIVE ); m_pCvarPlayTeamSoundsVolume = CVAR_CREATE("cl_team_sounds_volume", "1.0", FCVAR_ARCHIVE); + m_pShowServerTriggers = CVAR_CREATE("cl_show_server_triggers", "0", FCVAR_ARCHIVE); + m_pShowServerTriggersAlpha = CVAR_CREATE("cl_show_server_triggers_alpha", "120", FCVAR_ARCHIVE); cl_lw = gEngfuncs.pfnGetCvarPointer( "cl_lw" ); CVAR_CREATE("showtriggers", "0", 0); @@ -937,3 +939,22 @@ float CHud::GetSensitivity( void ) return m_flMouseSensitivity; } +bool CHud::IsTriggerForSinglePlayer(color24 rendercolor) +{ + auto r = rendercolor.r; + auto g = rendercolor.g; + auto b = rendercolor.b; + + if ((r == 128) && (g == 128) && (b == 128)) // trigger_autosave + return true; + else if ((r == 79) && (g == 255) && (b == 10)) // trigger_changelevel + return true; + else if ((r == 150) && (g == 75) && (b == 0)) // trigger_endsection + return true; + else if ((r == 238) && (g == 154) && (b == 77)) // trigger_monsterjump + return true; + else if ((r == 203) && (g == 103) && (b == 212)) // trigger_transition + return true; + + return false; +} diff --git a/cl_dll/hud.h b/cl_dll/hud.h index 7fe7ecb0..1964a126 100644 --- a/cl_dll/hud.h +++ b/cl_dll/hud.h @@ -644,6 +644,9 @@ class CHud cvar_t *hud_classautokill; cvar_t *hud_centerid; + cvar_t *m_pShowServerTriggers; + cvar_t *m_pShowServerTriggersAlpha; + int m_iFontHeight; cvar_t* m_pCvarColor; @@ -781,6 +784,9 @@ class CHud float GetSensitivity(); + bool IsTriggerForSinglePlayer(color24 rendercolor); + + HSPRITE white_sprite = 0; }; extern CHud gHUD; diff --git a/cl_dll/hudgl.cpp b/cl_dll/hudgl.cpp index 93dd8ff0..f9718004 100644 --- a/cl_dll/hudgl.cpp +++ b/cl_dll/hudgl.cpp @@ -6,7 +6,9 @@ #include #ifdef _WIN32 +#include #include +#include #endif #ifdef __APPLE__ diff --git a/cl_dll/tri.cpp b/cl_dll/tri.cpp index 5332eb85..1e180d10 100644 --- a/cl_dll/tri.cpp +++ b/cl_dll/tri.cpp @@ -7,6 +7,20 @@ // Triangle rendering, if any +#include + +#ifdef _WIN32 +#include +#include +#include +#endif + +#ifdef __APPLE__ +#include +#else +#include +#endif + #include "hud.h" #include "cl_util.h" @@ -22,6 +36,12 @@ #include "tri.h" extern IParticleMan *g_pParticleMan; +#include "com_model.h" +#include "r_studioint.h" + +#undef min +#undef max + /* ================= HUD_DrawNormalTriangles @@ -40,6 +60,89 @@ void CL_DLLEXPORT HUD_DrawNormalTriangles( void ) void RunEventList( void ); #endif +void DivideRGBABy255(float &r, float &g, float &b, float &a) +{ + r /= 255.0f; + g /= 255.0f; + b /= 255.0f; + a /= 255.0f; +} + +void DrawAACuboid(triangleapi_s *pTriAPI, Vector corner1, Vector corner2) +{ + pTriAPI->Begin(TRI_QUADS); + + pTriAPI->Vertex3f(corner1.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner2.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner1.z); + + pTriAPI->Vertex3f(corner1.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner1.x, corner1.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner1.z); + + pTriAPI->Vertex3f(corner1.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner1.y, corner2.z); + + pTriAPI->Vertex3f(corner2.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner1.x, corner1.y, corner2.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner2.z); + + pTriAPI->Vertex3f(corner2.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner2.z); + pTriAPI->Vertex3f(corner2.x, corner1.y, corner1.z); + pTriAPI->Vertex3f(corner2.x, corner2.y, corner1.z); + + pTriAPI->Vertex3f(corner2.x, corner2.y, corner2.z); + pTriAPI->Vertex3f(corner2.x, corner2.y, corner1.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner1.z); + pTriAPI->Vertex3f(corner1.x, corner2.y, corner2.z); + + pTriAPI->End(); +} + +void DrawServerTriggers() +{ + if ((gHUD.m_pShowServerTriggers->value > 0) && (gHUD.m_pShowServerTriggers->value != 2.0f)) + { + for (int e = 0; e < MAX_EDICTS; ++e) + { + cl_entity_t* ent = gEngfuncs.GetEntityByIndex(e); + if (ent) + { + if (ent->model) + { + if ((ent->curstate.rendermode == kRenderTransColor) && (ent->curstate.renderfx == kRenderFxTrigger)) + { + color24 colors = ent->curstate.rendercolor; + if (!gHUD.IsTriggerForSinglePlayer(colors)) + { + gEngfuncs.pTriAPI->RenderMode(kRenderTransAdd); + gEngfuncs.pTriAPI->CullFace(TRI_NONE); + + float r = colors.r, g = colors.g, b = colors.b, a = std::min(255.0f, std::max(0.0f, gHUD.m_pShowServerTriggersAlpha->value)); + DivideRGBABy255(r, g, b, a); + gEngfuncs.pTriAPI->Color4f(r, g, b, a); + + Vector mins = ent->curstate.mins; + Vector maxs = ent->curstate.maxs; + Vector origin = ent->curstate.origin; + Vector absmin = origin + mins; + Vector absmax = origin + maxs; + + DrawAACuboid(gEngfuncs.pTriAPI, absmin, absmax); + } + } + } + } + } + } +} + /* ================= HUD_DrawTransparentTriangles @@ -57,4 +160,14 @@ void CL_DLLEXPORT HUD_DrawTransparentTriangles( void ) if ( g_pParticleMan ) g_pParticleMan->Update(); + + if (!gHUD.white_sprite) + return; + + if (!gEngfuncs.pTriAPI->SpriteTexture(const_cast(gEngfuncs.GetSpritePointer(gHUD.white_sprite)), 0)) + return; + + DrawServerTriggers(); + + gEngfuncs.pTriAPI->RenderMode(kRenderNormal); } diff --git a/common/com_model.h b/common/com_model.h index 39e8f1da..94aaa7ed 100644 --- a/common/com_model.h +++ b/common/com_model.h @@ -16,7 +16,7 @@ #define STUDIO_EVENTS 2 #define MAX_CLIENTS 32 -#define MAX_EDICTS 900 +#define MAX_EDICTS 2048 #define MAX_MODEL_NAME 64 #define MAX_MAP_HULLS 4 diff --git a/common/const.h b/common/const.h index 6c5f35bd..9eee1bd5 100644 --- a/common/const.h +++ b/common/const.h @@ -713,6 +713,7 @@ enum kRenderFxGlowShell, // Glowing Shell kRenderFxClampMinScale, // Keep this sprite from getting very small (SPRITES only!) kRenderFxLightMultiplier, //CTM !!!CZERO added to tell the studiorender that the value in iuser2 is a lightmultiplier + kRenderFxTrigger = 241, }; From 1b33f0bee2cbdf53c13159697d9c8fc901a59651 Mon Sep 17 00:00:00 2001 From: Sabian Roberts <31491602+sabianroberts@users.noreply.github.com> Date: Thu, 14 Nov 2024 10:16:54 +0000 Subject: [PATCH 37/42] Add hud_watermark command (#191) hud_watermark <0|1> (1 by default) Controls whether the watermark & server-settings will display or not. The update disclaimer will display regardless, but only for 5 seconds if hud_watermark is set to 0. Co-authored-by: Ivan Molodetskikh --- cl_dll/hud.cpp | 3 +++ cl_dll/hud_settings.cpp | 47 +++++++++++++++++++++------------------- cl_dll/hud_watermark.cpp | 16 ++++++++++---- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/cl_dll/hud.cpp b/cl_dll/hud.cpp index 8d06d504..d8371919 100644 --- a/cl_dll/hud.cpp +++ b/cl_dll/hud.cpp @@ -91,6 +91,7 @@ cvar_t *cl_righthand = nullptr; cvar_t *cl_viewrollangle; cvar_t *cl_viewrollspeed; cvar_t *cl_bob_angled; +cvar_t *hud_watermark; void ShutdownInput (void); @@ -500,6 +501,8 @@ void CHud :: Init( void ) cl_viewrollspeed = CVAR_CREATE ( "cl_viewrollspeed", "300", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); cl_bob_angled = CVAR_CREATE ( "cl_bob_angled", "0", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); + hud_watermark = CVAR_CREATE ( "hud_watermark", "1", FCVAR_CLIENTDLL | FCVAR_ARCHIVE ); + HOOK_MESSAGE( CheatCheck ); HOOK_MESSAGE( WhString ); HOOK_MESSAGE( SpikeCheck ); diff --git a/cl_dll/hud_settings.cpp b/cl_dll/hud_settings.cpp index e2cac159..21d6b0ab 100644 --- a/cl_dll/hud_settings.cpp +++ b/cl_dll/hud_settings.cpp @@ -49,36 +49,39 @@ int CHudSettings::Draw(float time) char str[32]; - sprintf(str, "AG version %s", ag_version); - gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); - - gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), gamemode, r, g, b); - - sprintf(str, "Time limit: %hhd", time_limit); - gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight / 2 * 3), str, r, g, b); - - sprintf(str, "Frag limit: %hhd", frag_limit); - gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); + extern cvar_t* hud_watermark; + if (hud_watermark->value == 1) { + sprintf(str, "AG version %s", ag_version); + gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); - sprintf(str, "Friendly fire: %s", friendly_fire ? "On" : "Off"); - gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); + gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), gamemode, r, g, b); - sprintf(str, "Weaponstay: %s", weapon_stay ? "On" : "Off"); - gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); + sprintf(str, "Time limit: %hhd", time_limit); + gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight / 2 * 3), str, r, g, b); - if (wallgauss[0]) { - sprintf(str, "Wallgauss: %sx (1)", wallgauss); + sprintf(str, "Frag limit: %hhd", frag_limit); gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); - } - if (headshot[0]) { - sprintf(str, "Headshot: %sx (3)", headshot); + sprintf(str, "Friendly fire: %s", friendly_fire ? "On" : "Off"); gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); - } - if (blast_radius[0]) { - sprintf(str, "Blast radius: %sx (1)", blast_radius); + sprintf(str, "Weaponstay: %s", weapon_stay ? "On" : "Off"); gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); + + if (wallgauss[0]) { + sprintf(str, "Wallgauss: %sx (1)", wallgauss); + gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); + } + + if (headshot[0]) { + sprintf(str, "Headshot: %sx (3)", headshot); + gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); + } + + if (blast_radius[0]) { + sprintf(str, "Blast radius: %sx (1)", blast_radius); + gEngfuncs.pfnDrawString(x, (y += gHUD.m_scrinfo.iCharHeight), str, r, g, b); + } } if (match_is_on) { diff --git a/cl_dll/hud_watermark.cpp b/cl_dll/hud_watermark.cpp index 34f95d74..f255f538 100644 --- a/cl_dll/hud_watermark.cpp +++ b/cl_dll/hud_watermark.cpp @@ -3,6 +3,8 @@ #include "parsemsg.h" #include "update_checker.h" +extern cvar_t* hud_watermark; + int CHudWatermark::Init() { m_iFlags = 0; @@ -22,9 +24,13 @@ int CHudWatermark::VidInit() int CHudWatermark::Draw(float time) { - if (refresh_draw_until || (draw_until > gHUD.m_flTime + 15.0f)) { + float duration = 15.0f; + if (hud_watermark->value != 1) + duration = 5.0f; + + if (refresh_draw_until || (draw_until > gHUD.m_flTime + duration)) { refresh_draw_until = false; - draw_until = gHUD.m_flTime + 15.0f; + draw_until = gHUD.m_flTime + duration; } if (gHUD.m_flTime >= draw_until) { @@ -35,8 +41,10 @@ int CHudWatermark::Draw(float time) int r, g, b; UnpackRGB(r, g, b, gHUD.m_iDefaultHUDColor); - gEngfuncs.pfnDrawString(ScreenWidth / 20, gHUD.m_scrinfo.iCharHeight, "OpenAG client build " __DATE__, r, g, b); - gEngfuncs.pfnDrawString(ScreenWidth / 20, gHUD.m_scrinfo.iCharHeight * 2, "j.mp/OpenAG", r, g, b); + if (hud_watermark->value != 0) { + gEngfuncs.pfnDrawString(ScreenWidth / 20, gHUD.m_scrinfo.iCharHeight, "OpenAG client build " __DATE__, r, g, b); + gEngfuncs.pfnDrawString(ScreenWidth / 20, gHUD.m_scrinfo.iCharHeight * 2, "j.mp/OpenAG", r, g, b); + } if (update_is_available) gEngfuncs.pfnDrawString(ScreenWidth / 20, gHUD.m_scrinfo.iCharHeight / 2 * 7, "An update is available.", r, g, b); From ecd3d83768b3eab55df9ba74b674590dd7a21e73 Mon Sep 17 00:00:00 2001 From: larzie Date: Sun, 24 Nov 2024 22:37:24 +0300 Subject: [PATCH 38/42] update ci (#192) * Update CI * My bad :p --- .github/workflows/CI.yml | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 1dbd3bb0..96daf1bb 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -35,18 +35,23 @@ jobs: fail-fast: false matrix: config: - - {runs-on: windows-2019, toolset: v141_xp} - - {runs-on: windows-2022, toolset: v143} + - { runs-on: windows-2019, toolset: v141_xp } + - { runs-on: windows-2022, toolset: v143 } configuration: [Release, Debug] steps: - - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v4 with: submodules: recursive + - name: CMake generate run: cmake -T ${{ matrix.config.toolset }} -A Win32 -B build + - name: Build run: cmake --build build -j $env:NUMBER_OF_PROCESSORS --config ${{ matrix.configuration }} - - uses: actions/upload-artifact@v3 + + - name: Upload build artifact + uses: actions/upload-artifact@v4 if: matrix.config.toolset == 'v141_xp' with: name: openag-${{ runner.os }}-${{ matrix.configuration }} @@ -65,20 +70,26 @@ jobs: CC: gcc-${{ matrix.gcc-ver }} CXX: g++-${{ matrix.gcc-ver }} steps: - - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v4 with: submodules: recursive + - name: Setup run: | sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install -y g++-${{ matrix.gcc-ver }}-multilib libgl-dev ninja-build rapidjson-dev + - name: CMake generate run: cmake -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.configuration }} -B build + - name: Build working-directory: build run: ninja - - uses: actions/upload-artifact@v3 + + - name: Upload build artifact + uses: actions/upload-artifact@v4 if: matrix.gcc-ver == '11' with: name: openag-${{ runner.os }}-${{ matrix.configuration }} @@ -97,9 +108,11 @@ jobs: CC: clang-${{ matrix.clang-ver }} CXX: clang++-${{ matrix.clang-ver }} steps: - - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v4 with: submodules: recursive + - name: Setup run: | if [ ${{ matrix.clang-ver }} -eq 16 ]; then @@ -108,8 +121,10 @@ jobs: fi sudo apt-get update sudo apt-get install -y clang-${{ matrix.clang-ver }} g++-multilib libgl-dev ninja-build rapidjson-dev + - name: CMake generate run: cmake -G Ninja -DCMAKE_BUILD_TYPE=${{ matrix.configuration }} -B build + - name: Build working-directory: build run: ninja From d824a04e6f887d6e1a9c14985120de2ff41a53c4 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 1 Jun 2025 13:12:08 +0300 Subject: [PATCH 39/42] CI: Bump to ubuntu-22.04 --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 96daf1bb..4e9adad3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -60,7 +60,7 @@ jobs: build-linux-gcc: name: Build (Linux, gcc-${{ matrix.gcc-ver }}, ${{ matrix.configuration }}) - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: @@ -98,7 +98,7 @@ jobs: build-linux-clang: name: Build (Linux, clang-${{ matrix.clang-ver }}, ${{ matrix.configuration }}) - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false matrix: From 05b0e09753f256f878c80b20aa0eee77586a3637 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 1 Jun 2025 13:19:16 +0300 Subject: [PATCH 40/42] CI: Update compiler versions --- .github/workflows/CI.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 4e9adad3..814aacf1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -64,7 +64,7 @@ jobs: strategy: fail-fast: false matrix: - gcc-ver: [9, 11] + gcc-ver: [9, 12] configuration: [Release, Debug] env: CC: gcc-${{ matrix.gcc-ver }} @@ -102,7 +102,7 @@ jobs: strategy: fail-fast: false matrix: - clang-ver: ['6.0', 16] + clang-ver: [11, 20] configuration: [Release, Debug] env: CC: clang-${{ matrix.clang-ver }} @@ -115,9 +115,9 @@ jobs: - name: Setup run: | - if [ ${{ matrix.clang-ver }} -eq 16 ]; then + if [ ${{ matrix.clang-ver }} -eq 20 ]; then wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo add-apt-repository 'deb https://apt.llvm.org/focal/ llvm-toolchain-focal-${{ matrix.clang-ver }} main' + sudo add-apt-repository 'deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy-${{ matrix.clang-ver }} main' fi sudo apt-get update sudo apt-get install -y clang-${{ matrix.clang-ver }} g++-multilib libgl-dev ninja-build rapidjson-dev From 7e1e799a513d804eefebaf37d48b878f84d037b1 Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Sun, 1 Jun 2025 13:28:33 +0300 Subject: [PATCH 41/42] CI: Downgrade clang to 15 Newest clang errors on rapidjson (which is a rapidjson problem), but this is the rapidjson from Ubuntu repos, and they didn't fix it there. I don't want to deal with this for now. --- .github/workflows/CI.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 814aacf1..c5b18488 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -102,7 +102,7 @@ jobs: strategy: fail-fast: false matrix: - clang-ver: [11, 20] + clang-ver: [11, 15] configuration: [Release, Debug] env: CC: clang-${{ matrix.clang-ver }} @@ -115,10 +115,6 @@ jobs: - name: Setup run: | - if [ ${{ matrix.clang-ver }} -eq 20 ]; then - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo add-apt-repository 'deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy-${{ matrix.clang-ver }} main' - fi sudo apt-get update sudo apt-get install -y clang-${{ matrix.clang-ver }} g++-multilib libgl-dev ninja-build rapidjson-dev From 83e8d913c75a11155cd4de9435e1697c112e3d54 Mon Sep 17 00:00:00 2001 From: Sabian Roberts <31491602+sabianroberts@users.noreply.github.com> Date: Mon, 14 Jul 2025 04:35:27 +0100 Subject: [PATCH 42/42] Remove XP build from Continuous Integration workflow (#205) * Remove 141_xp * Update .github/workflows/CI.yml * Restore build job * Update .github/workflows/CI.yml * Update .github/workflows/CI.yml --------- Co-authored-by: Ivan Molodetskikh --- .github/workflows/CI.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index c5b18488..380487de 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -35,7 +35,6 @@ jobs: fail-fast: false matrix: config: - - { runs-on: windows-2019, toolset: v141_xp } - { runs-on: windows-2022, toolset: v143 } configuration: [Release, Debug] steps: @@ -52,7 +51,6 @@ jobs: - name: Upload build artifact uses: actions/upload-artifact@v4 - if: matrix.config.toolset == 'v141_xp' with: name: openag-${{ runner.os }}-${{ matrix.configuration }} path: build\${{ matrix.configuration }}\client.dll