diff --git a/README.md b/README.md index 0ca8b1536..c1e38b634 100644 --- a/README.md +++ b/README.md @@ -128,11 +128,11 @@ This means that plugins that do binary code analysis (Orpheu for example) probab ## How to install zBot for CS 1.6? * Extract all the files from an [archive](regamedll/extra/zBot/bot_profiles.zip?raw=true) -* Enter `-bots` option at the command line HLDS +* Enable CVar `bot_enable 1` in `cstrike/game_init.cfg` (if this config file does not exist, create it) -## How to install CSCZ hostage AI for CS 1.6? +## How to install CS:CZ hostage AI for CS 1.6? * Extract all the files from an [archive](regamedll/extra/HostageImprov/host_improv.zip?raw=true) -* Enter `-host-improv` option at the command line HLDS +* Enable CVar `hostage_ai_enable 1` in `cstrike/game_init.cfg` (if this config file does not exist, create it) ## Build instructions ### Checking requirements diff --git a/dist/game_init.cfg b/dist/game_init.cfg index 90e31b2d5..de6cb5326 100644 --- a/dist/game_init.cfg +++ b/dist/game_init.cfg @@ -1,3 +1,18 @@ +// Enables ZBots for the server +// NOTE: ZBots are always enabled on a listen server, regardless of this cvar +// 0 - disabled +// 1 - enabled +// +// Default value: "0" +bot_enable "0" + +// Enables the improve AI for hostages from CS:CZ +// 0 - disabled (classic hostage) +// 1 - enabled (improved hostage) +// +// Default value: "0" +hostage_ai_enable "0" + // Sets mins/maxs hull bounds for the player. // 0 - disabled (default behaviour, sets engine) // 1 - enabled (sets gamedll) diff --git a/regamedll/dlls/ammo.cpp b/regamedll/dlls/ammo.cpp index 1df3622cc..8c264ac78 100644 --- a/regamedll/dlls/ammo.cpp +++ b/regamedll/dlls/ammo.cpp @@ -24,7 +24,7 @@ void CBasePlayerAmmo::Spawn() BOOL CBasePlayerAmmo::AddAmmo(CBaseEntity *pOther) { auto ammoInfo = GetAmmoInfo(pev->classname); - if (pOther->GiveAmmo(ammoInfo->buyClipSize, ammoInfo->ammoName2) == -1) + if (!ammoInfo || pOther->GiveAmmo(ammoInfo->buyClipSize, ammoInfo->ammoName2) == -1) { return FALSE; } diff --git a/regamedll/dlls/bot/cs_bot_chatter.cpp b/regamedll/dlls/bot/cs_bot_chatter.cpp index 1476d8d58..f58759fe5 100644 --- a/regamedll/dlls/bot/cs_bot_chatter.cpp +++ b/regamedll/dlls/bot/cs_bot_chatter.cpp @@ -464,6 +464,7 @@ bool BotPhraseManager::Initialize(const char *filename, int bankIndex) phraseData = SharedParse(phraseData); if (!phraseData) { + if (phrase) delete phrase; CONSOLE_ECHO("Error parsing '%s' - expected identifier\n", filename); FREE_FILE(phraseDataFile); return false; diff --git a/regamedll/dlls/bot/cs_bot_event.cpp b/regamedll/dlls/bot/cs_bot_event.cpp index 199616659..70411c8e5 100644 --- a/regamedll/dlls/bot/cs_bot_event.cpp +++ b/regamedll/dlls/bot/cs_bot_event.cpp @@ -56,6 +56,11 @@ void CCSBot::OnEvent(GameEventType event, CBaseEntity *pEntity, CBaseEntity *pOt DecreaseMorale(); } break; +#ifdef REGAMEDLL_FIXES + case EVENT_NEW_MATCH: + m_morale = POSITIVE; // starting a new round makes everyone a little happy + break; +#endif } if (!IsAlive()) diff --git a/regamedll/dlls/bot/cs_bot_init.cpp b/regamedll/dlls/bot/cs_bot_init.cpp index 1bf7aec00..665b3c337 100644 --- a/regamedll/dlls/bot/cs_bot_init.cpp +++ b/regamedll/dlls/bot/cs_bot_init.cpp @@ -28,6 +28,7 @@ #include "precompiled.h" +cvar_t cv_bot_enable = { "bot_enable", "0", 0, 0.0f, nullptr }; cvar_t cv_bot_traceview = { "bot_traceview", "0", FCVAR_SERVER, 0.0f, nullptr }; cvar_t cv_bot_stop = { "bot_stop", "0", FCVAR_SERVER, 0.0f, nullptr }; cvar_t cv_bot_show_nav = { "bot_show_nav", "0", FCVAR_SERVER, 0.0f, nullptr }; diff --git a/regamedll/dlls/bot/cs_bot_init.h b/regamedll/dlls/bot/cs_bot_init.h index 8687e3f7f..b50e020c3 100644 --- a/regamedll/dlls/bot/cs_bot_init.h +++ b/regamedll/dlls/bot/cs_bot_init.h @@ -28,6 +28,7 @@ #pragma once +extern cvar_t cv_bot_enable; extern cvar_t cv_bot_traceview; extern cvar_t cv_bot_stop; extern cvar_t cv_bot_show_nav; diff --git a/regamedll/dlls/bot/cs_bot_manager.cpp b/regamedll/dlls/bot/cs_bot_manager.cpp index 730805bbf..a5be7342e 100644 --- a/regamedll/dlls/bot/cs_bot_manager.cpp +++ b/regamedll/dlls/bot/cs_bot_manager.cpp @@ -889,12 +889,10 @@ void CCSBotManager::MaintainBotQuota() if (m_isLearningMap) return; - int totalHumansInGame = UTIL_HumansInGame(); - int humanPlayersInGame = UTIL_HumansInGame(IGNORE_SPECTATORS); - int spectatorPlayersInGame = UTIL_SpectatorsInGame(); + int humanPlayersInGame = UTIL_HumansInGame(); // don't add bots until local player has been registered, to make sure he's player ID #1 - if (!IS_DEDICATED_SERVER() && totalHumansInGame == 0) + if (!IS_DEDICATED_SERVER() && humanPlayersInGame == 0) return; int desiredBotCount = int(cv_bot_quota.value); @@ -949,7 +947,7 @@ void CCSBotManager::MaintainBotQuota() // wait for a player to join, if necessary if (cv_bot_join_after_player.value > 0.0) { - if (humanPlayersInGame == 0 && spectatorPlayersInGame == 0) + if (humanPlayersInGame == 0) desiredBotCount = 0; } diff --git a/regamedll/dlls/career_tasks.cpp b/regamedll/dlls/career_tasks.cpp index 972ccca9b..050a9aab0 100644 --- a/regamedll/dlls/career_tasks.cpp +++ b/regamedll/dlls/career_tasks.cpp @@ -260,7 +260,7 @@ void CCareerTask::OnEvent(GameEventType event, CBasePlayer *pVictim, CBasePlayer while ((pHostage = UTIL_FindEntityByClassname(pHostage, "hostage_entity"))) { - if (pHostage && pHostage->IsDead()) + if (pHostage->IsDead()) hostagesCount++; } @@ -389,7 +389,6 @@ void CCareerTaskManager::Reset(bool deleteTasks) delete task; m_tasks.clear(); - m_nextId = 0; } else { @@ -397,6 +396,7 @@ void CCareerTaskManager::Reset(bool deleteTasks) task->Reset(); } + m_nextId = 0; m_finishedTaskTime = 0; m_finishedTaskRound = 0; m_shouldLatchRoundEndMessage = false; diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp index e116e1e92..1ee4f3e95 100644 --- a/regamedll/dlls/client.cpp +++ b/regamedll/dlls/client.cpp @@ -811,7 +811,9 @@ void Host_Say(edict_t *pEntity, BOOL teamonly) if (*p == '"') { p++; - p[Q_strlen(p) - 1] = '\0'; + size_t len = Q_strlen(p); + if (len > 0) + p[len - 1] = '\0'; } // Check if buffer contains an invalid unicode sequence diff --git a/regamedll/dlls/combat.cpp b/regamedll/dlls/combat.cpp index 17fe84e27..8c66a4754 100644 --- a/regamedll/dlls/combat.cpp +++ b/regamedll/dlls/combat.cpp @@ -285,8 +285,6 @@ void RadiusDamage(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker damageRatio = GetAmountOfPlayerVisible(vecSrc, pEntity); } - damageRatio = GetAmountOfPlayerVisible(vecSrc, pEntity); - float length; #ifdef REGAMEDLL_ADD // allow to damage breakable objects diff --git a/regamedll/dlls/ehandle.h b/regamedll/dlls/ehandle.h index 9a8717826..61d22a5cc 100644 --- a/regamedll/dlls/ehandle.h +++ b/regamedll/dlls/ehandle.h @@ -130,6 +130,10 @@ inline edict_t *EntityHandle::Set(edict_t *pEdict) { m_serialnumber = pEdict->serialnumber; } + else + { + m_serialnumber = 0; + } return pEdict; } diff --git a/regamedll/dlls/func_tank.cpp b/regamedll/dlls/func_tank.cpp index e12c90768..14c2ef6fc 100644 --- a/regamedll/dlls/func_tank.cpp +++ b/regamedll/dlls/func_tank.cpp @@ -302,7 +302,7 @@ void CFuncTank::ControllerPostFrame() Assert(m_pController != nullptr); - if (m_pController->pev->button & IN_ATTACK) + if (m_pController && m_pController->pev->button & IN_ATTACK) { Vector vecForward; UTIL_MakeVectorsPrivate(pev->angles, vecForward, nullptr, nullptr); diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp index d3947fb76..659cd79f2 100644 --- a/regamedll/dlls/game.cpp +++ b/regamedll/dlls/game.cpp @@ -179,7 +179,7 @@ cvar_t legacy_vehicle_block = { "mp_legacy_vehicle_block", "1", 0, cvar_t dying_time = { "mp_dying_time", "3.0", 0, 3.0f, nullptr }; cvar_t defuser_allocation = { "mp_defuser_allocation", "0", 0, 0.0f, nullptr }; cvar_t location_area_info = { "mp_location_area_info", "0", 0, 0.0f, nullptr }; -cvar_t chat_loc_fallback = { "mp_chat_loc_fallback", "1", 1, 0.0f, nullptr }; +cvar_t chat_loc_fallback = { "mp_chat_loc_fallback", "1", 0, 1.0f, nullptr }; cvar_t item_respawn_time = { "mp_item_respawn_time", "30", FCVAR_SERVER, 30.0f, nullptr }; cvar_t weapon_respawn_time = { "mp_weapon_respawn_time", "20", FCVAR_SERVER, 20.0f, nullptr }; @@ -462,13 +462,22 @@ void EXT_FUNC GameDLLInit() CVAR_REGISTER(&vote_flags); CVAR_REGISTER(&votemap_min_time); + CVAR_REGISTER(&cv_bot_enable); + CVAR_REGISTER(&cv_hostage_ai_enable); + CVAR_REGISTER(&scoreboard_fix); // print version CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n"); + // execute initial pre-configurations + SERVER_COMMAND("exec game_init.cfg\n"); + SERVER_EXECUTE(); + #endif // REGAMEDLL_ADD + Regamedll_Game_Init(); + Bot_RegisterCVars(); Tutor_RegisterCVars(); Hostage_RegisterCVars(); @@ -477,12 +486,6 @@ void EXT_FUNC GameDLLInit() VoiceGameMgr_RegisterCVars(); #endif -#ifdef REGAMEDLL_ADD - // execute initial pre-configurations - SERVER_COMMAND("exec game_init.cfg\n"); - SERVER_EXECUTE(); -#endif - } SpewRetval_t GameDLL_SpewHandler(SpewType_t spewType, int level, const char *pMsg) diff --git a/regamedll/dlls/globals.cpp b/regamedll/dlls/globals.cpp index 3f698d59f..d02c8fee9 100644 --- a/regamedll/dlls/globals.cpp +++ b/regamedll/dlls/globals.cpp @@ -11,4 +11,3 @@ BOOL gDisplayTitle; bool g_bIsBeta = false; bool g_bIsCzeroGame = false; bool g_bAllowedCSBot = false; -bool g_bHostageImprov = false; diff --git a/regamedll/dlls/globals.h b/regamedll/dlls/globals.h index 020242918..805fd12ad 100644 --- a/regamedll/dlls/globals.h +++ b/regamedll/dlls/globals.h @@ -38,4 +38,3 @@ extern BOOL gDisplayTitle; extern bool g_bIsBeta; extern bool g_bIsCzeroGame; extern bool g_bAllowedCSBot; -extern bool g_bHostageImprov; diff --git a/regamedll/dlls/h_export.cpp b/regamedll/dlls/h_export.cpp index 486a3eedf..544a92ffb 100644 --- a/regamedll/dlls/h_export.cpp +++ b/regamedll/dlls/h_export.cpp @@ -13,7 +13,6 @@ C_DLLEXPORT void WINAPI GiveFnptrsToDll(enginefuncs_t *pEnginefuncsTable, global gpGlobals = pGlobals; FileSystem_Init(); - Regamedll_Game_Init(); } #if defined(_LINUX) diff --git a/regamedll/dlls/hostage/hostage.cpp b/regamedll/dlls/hostage/hostage.cpp index 7ef34b222..c6f57091c 100644 --- a/regamedll/dlls/hostage/hostage.cpp +++ b/regamedll/dlls/hostage/hostage.cpp @@ -28,6 +28,7 @@ #include "precompiled.h" +cvar_t cv_hostage_ai_enable = { "hostage_ai_enable", "0", 0, 0.0f, nullptr }; cvar_t cv_hostage_debug = { "hostage_debug", "0", FCVAR_SERVER, 0.0f, nullptr }; cvar_t cv_hostage_stop = { "hostage_stop", "0", FCVAR_SERVER, 0.0f, nullptr }; @@ -268,39 +269,48 @@ void CHostage::Spawn() void CHostage::Precache() { - if (AreImprovAllowed()) + if (cv_hostage_ai_enable.value) { + string_t model = iStringNull; + static int which = 0; switch (which) { + default: case REGULAR_GUY: - pev->model = MAKE_STRING("models/hostageA.mdl"); + model = MAKE_STRING("models/hostageA.mdl"); break; case OLD_GUY: - pev->model = MAKE_STRING("models/hostageB.mdl"); + model = MAKE_STRING("models/hostageB.mdl"); break; case BLACK_GUY: - pev->model = MAKE_STRING("models/hostageC.mdl"); + model = MAKE_STRING("models/hostageC.mdl"); break; case GOOFY_GUY: - pev->model = MAKE_STRING("models/hostageD.mdl"); - break; - default: + model = MAKE_STRING("models/hostageD.mdl"); break; } m_whichModel = static_cast(which); - if (++which > 3) - which = 0; + if (++which > GOOFY_GUY) + which = REGULAR_GUY; + + if (g_pFileSystem->FileExists(model)) + { + pev->model = model; + } + else + { + // It seems that the model is missing, so use classic hostages + CVAR_SET_FLOAT("hostage_ai_enable", 0); + } } - else + + if (pev->model.IsNull()) { m_whichModel = REGULAR_GUY; - if (pev->model.IsNull()) - { - pev->model = MAKE_STRING("models/scientist.mdl"); - } + pev->model = MAKE_STRING("models/scientist.mdl"); } PRECACHE_MODEL(pev->model); @@ -342,7 +352,7 @@ void CHostage::IdleThink() const float giveUpTime = (1 / 30.0f); float const updateRate = 0.1f; - if (AreImprovAllowed() && !TheNavAreaList.empty()) + if (cv_hostage_ai_enable.value && !TheNavAreaList.empty()) { if (!m_improv) { @@ -619,7 +629,7 @@ void CHostage::TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir BOOL CHostage::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) { #ifdef REGAMEDLL_ADD - if (!CanTakeDamage(pevAttacker)) + if (pevAttacker && !CanTakeDamage(pevAttacker)) return FALSE; #endif @@ -771,7 +781,7 @@ void CHostage::SetDeathActivity() return; } - if (AreImprovAllowed()) + if (cv_hostage_ai_enable.value) { switch (m_LastHitGroup) { @@ -1397,7 +1407,7 @@ void Hostage_RegisterCVars() { // These cvars are only used in czero #ifdef REGAMEDLL_FIXES - if (!AreImprovAllowed()) + if (!cv_hostage_ai_enable.value) return; #endif @@ -1432,7 +1442,7 @@ void CHostageManager::ServerActivate() AddHostage(pHostage); } - if (AreImprovAllowed()) + if (cv_hostage_ai_enable.value) { for (auto& snd : hostageSoundStruct) { m_chatter.AddSound(snd.type, snd.fileName); @@ -1568,6 +1578,9 @@ void SimpleChatter::AddSound(HostageChatterType type, char *filename) Q_snprintf(actualFilename, sizeof(actualFilename), "sound\\%s", filename); + if (!g_pFileSystem->FileExists(actualFilename)) + return; + chatter->file[chatter->count].filename = CloneString(filename); chatter->file[chatter->count].duration = (double)GET_APPROX_WAVE_PLAY_LEN(actualFilename) / 1000.0; @@ -1605,6 +1618,9 @@ void SimpleChatter::Shuffle(ChatterSet *chatter) char *SimpleChatter::GetSound(HostageChatterType type, float *duration) { ChatterSet *chatter = &m_chatter[type]; + if (chatter->count == 0) + return nullptr; + char *sound; Shuffle(chatter); diff --git a/regamedll/dlls/hostage/hostage.h b/regamedll/dlls/hostage/hostage.h index 44a501235..f869cacfb 100644 --- a/regamedll/dlls/hostage/hostage.h +++ b/regamedll/dlls/hostage/hostage.h @@ -77,6 +77,7 @@ enum HostageChatterType extern CHostageManager *g_pHostages; extern int g_iHostageNumber; +extern cvar_t cv_hostage_ai_enable; extern cvar_t cv_hostage_debug; extern cvar_t cv_hostage_stop; @@ -284,11 +285,5 @@ class CHostageManager SimpleChatter m_chatter; }; -// Determine whether hostage improv can be used or not -inline bool AreImprovAllowed() -{ - return g_bHostageImprov; -} - void Hostage_RegisterCVars(); void InstallHostageManager(); diff --git a/regamedll/dlls/hostage/states/hostage_idle.cpp b/regamedll/dlls/hostage/states/hostage_idle.cpp index c2c311a15..618848fc8 100644 --- a/regamedll/dlls/hostage/states/hostage_idle.cpp +++ b/regamedll/dlls/hostage/states/hostage_idle.cpp @@ -78,7 +78,7 @@ void HostageIdleState::OnUpdate(CHostageImprov *improv) } } - if (m_moveState && improv->IsAtMoveGoal()) + if (m_moveState != NotMoving && improv->IsAtMoveGoal()) { m_moveState = NotMoving; diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index d1783dfb3..111d61aa0 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -2462,8 +2462,16 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib) break; } + // UNDO: This code was intended to set the victim's angle with the throw direction + // For bots, it works correctly because they do not send angle updates to the server, + // However, for players, the client overrides the angle with its own view direction in the next frame, + // causing a visual glitch where the model rotates excessively + // The issue is more noticeable with high cmdrate values (e.g., cl_cmdrate >100) + // Disabled to avoid this artifact +#ifndef REGAMEDLL_FIXES pev->angles.y = UTIL_VecToAngles(-pev->velocity).y; pev->v_angle.y = pev->angles.y; +#endif m_iThrowDirection = THROW_NONE; } @@ -2952,10 +2960,8 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim) break; case 3: case 4: -#ifndef REGAMEDLL_FIXES m_iThrowDirection = THROW_FORWARD; break; -#endif case 5: case 6: m_iThrowDirection = THROW_HITVEL; @@ -4167,7 +4173,7 @@ void CBasePlayer::PlayerUse() } } - bool useNewHostages = !TheNavAreaList.empty() && AreImprovAllowed(); + bool useNewHostages = !TheNavAreaList.empty() && cv_hostage_ai_enable.value; CBaseEntity *pObject = nullptr; CBaseEntity *pClosest = nullptr; Vector vecLOS; @@ -5152,12 +5158,9 @@ void CBasePlayer::UpdatePlayerSound() m_iExtraSoundTypes = 0; } - if (pSound) - { - pSound->m_vecOrigin = pev->origin; - pSound->m_iVolume = iVolume; - pSound->m_iType |= (bits_SOUND_PLAYER | m_iExtraSoundTypes); - } + pSound->m_vecOrigin = pev->origin; + pSound->m_iVolume = iVolume; + pSound->m_iType |= (bits_SOUND_PLAYER | m_iExtraSoundTypes); // keep track of virtual muzzle flash m_iWeaponFlash -= 256 * gpGlobals->frametime; @@ -5917,7 +5920,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Spawn)() TheBots->OnEvent(EVENT_PLAYER_SPAWNED, this); } - m_allowAutoFollowTime = false; + m_allowAutoFollowTime = 0.0f; for (i = 0; i < COMMANDS_TO_TRACK; i++) m_flLastCommandTime[i] = -1; @@ -8474,7 +8477,7 @@ void CBasePlayer::__API_HOOK(SwitchTeam)() UpdateLocation(true); - if (m_iTeam) + if (m_iTeam != UNASSIGNED) { SetScoreboardAttributes(); } @@ -9686,7 +9689,7 @@ void CBasePlayer::PrioritizeAutoBuyString(char (&autobuyString)[MAX_AUTOBUY_LENG int newStringPos = 0; char priorityToken[32]; - if (!priorityString || !autobuyString) + if (!priorityString) return; const char *priorityChar = priorityString; diff --git a/regamedll/dlls/saverestore.cpp b/regamedll/dlls/saverestore.cpp index 897452c4f..514ca64b8 100644 --- a/regamedll/dlls/saverestore.cpp +++ b/regamedll/dlls/saverestore.cpp @@ -250,10 +250,10 @@ edict_t *CSaveRestoreBuffer::EntityFromIndex(int entityIndex) int CSaveRestoreBuffer::EntityFlagsSet(int entityIndex, int flags) { - if (!m_pData || entityIndex < 0) + if (!m_pData) return 0; - if (!m_pData || entityIndex < 0 || entityIndex > m_pData->tableCount) + if (entityIndex < 0 || entityIndex > m_pData->tableCount) return 0; m_pData->pTable[entityIndex].flags |= flags; diff --git a/regamedll/dlls/sound.cpp b/regamedll/dlls/sound.cpp index a4dc0a7d6..25e930e3d 100644 --- a/regamedll/dlls/sound.cpp +++ b/regamedll/dlls/sound.cpp @@ -1362,7 +1362,7 @@ void SENTENCEG_Init() i = 0; - while (rgsentenceg[i].count && i < MAX_SENTENCE_GROUPS) + while (i < MAX_SENTENCE_GROUPS && rgsentenceg[i].count) { USENTENCEG_InitLRU(&(rgsentenceg[i].rgblru[0]), rgsentenceg[i].count); i++; @@ -1380,11 +1380,7 @@ int SENTENCEG_Lookup(const char *sample, char (&sentencenum)[32]) { if (!Q_stricmp(gszallsentencenames[i], sample + 1)) { - if (sentencenum) - { - Q_snprintf(sentencenum, sizeof(sentencenum), "!%d", i); - } - + Q_snprintf(sentencenum, sizeof(sentencenum), "!%d", i); return i; } } diff --git a/regamedll/dlls/triggers.cpp b/regamedll/dlls/triggers.cpp index 1bfd85b94..63282c06e 100644 --- a/regamedll/dlls/triggers.cpp +++ b/regamedll/dlls/triggers.cpp @@ -585,7 +585,6 @@ void CTriggerCDAudio::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYP PlayTrack(pCaller->edict()); } -#ifdef REGAMEDLL_FIXES const char *g_szMP3trackFileMap[] = { "", "", @@ -617,7 +616,6 @@ const char *g_szMP3trackFileMap[] = "media/Suspense05.mp3", "media/Suspense07.mp3" }; -#endif void PlayCDTrack(edict_t *pClient, int iTrack) { @@ -625,7 +623,7 @@ void PlayCDTrack(edict_t *pClient, int iTrack) if (!pClient) return; - if (iTrack < -1 || iTrack > 30) + if (iTrack < -1 || iTrack >= (int)ARRAYSIZE(g_szMP3trackFileMap)) { ALERT(at_console, "TriggerCDAudio - Track %d out of range\n", iTrack); return; diff --git a/regamedll/dlls/util.cpp b/regamedll/dlls/util.cpp index de6159469..b1102c470 100644 --- a/regamedll/dlls/util.cpp +++ b/regamedll/dlls/util.cpp @@ -1660,14 +1660,12 @@ int UTIL_ReadFlags(const char *c) // Determine whether bots can be used or not bool UTIL_AreBotsAllowed() { -#ifdef REGAMEDLL_ADD - if (g_engfuncs.pfnEngCheckParm == nullptr) - return false; -#endif - if (AreRunningCZero()) { #ifdef REGAMEDLL_ADD + if (g_engfuncs.pfnEngCheckParm == nullptr) + return false; + // If they pass in -nobots, don't allow bots. This is for people who host servers, to // allow them to disallow bots to enforce CPU limits. int nobots = ENG_CHECK_PARM("-nobots", nullptr); @@ -1687,15 +1685,10 @@ bool UTIL_AreBotsAllowed() return true; } - // allow the using of bots for CS 1.6 - int bots = ENG_CHECK_PARM("-bots", nullptr); - if (bots) - { - return true; - } -#endif - + return cv_bot_enable.value > 0; +#else return false; +#endif } bool UTIL_IsBeta() @@ -1728,18 +1721,10 @@ bool UTIL_AreHostagesImprov() } #ifdef REGAMEDLL_ADD - if (g_engfuncs.pfnEngCheckParm == nullptr) - return false; - - // someday in CS 1.6 - int improv = ENG_CHECK_PARM("-host-improv", nullptr); - if (improv) - { - return true; - } -#endif - + return cv_hostage_ai_enable.value > 0; +#else return false; +#endif } int UTIL_GetNumPlayers() diff --git a/regamedll/dlls/vehicle.cpp b/regamedll/dlls/vehicle.cpp index 3ff84b941..7bf2d4184 100644 --- a/regamedll/dlls/vehicle.cpp +++ b/regamedll/dlls/vehicle.cpp @@ -126,7 +126,7 @@ void CFuncVehicle::Blocked(CBaseEntity *pOther) float minz = pev->origin.z; #ifdef REGAMEDLL_FIXES - float maxz = pev->origin.z + (2 * Q_abs(pev->mins.z - pev->maxs.z)); + float maxz = pev->origin.z + (2 * Q_abs(pev->mins.z - pev->maxs.z)); #else float maxz = pev->origin.z + (2 * Q_abs(int(pev->mins.z - pev->maxs.z))); #endif @@ -343,15 +343,20 @@ void CFuncVehicle::CheckTurning() if (pev->speed > 0) { UTIL_TraceLine(m_vFrontRight, m_vFrontRight - (gpGlobals->v_right * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr); + + if (tr.flFraction != 1.0f) + { + m_iTurnAngle = 1; + } } else if (pev->speed < 0) { UTIL_TraceLine(m_vBackLeft, m_vBackLeft + (gpGlobals->v_right * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr); - } - if (tr.flFraction != 1.0f) - { - m_iTurnAngle = 1; + if (tr.flFraction != 1.0f) + { + m_iTurnAngle = 1; + } } } else if (m_iTurnAngle > 0) @@ -359,15 +364,20 @@ void CFuncVehicle::CheckTurning() if (pev->speed > 0) { UTIL_TraceLine(m_vFrontLeft, m_vFrontLeft + (gpGlobals->v_right * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr); + + if (tr.flFraction != 1.0f) + { + m_iTurnAngle = -1; + } } else if (pev->speed < 0) { UTIL_TraceLine(m_vBackRight, m_vBackRight - (gpGlobals->v_right * 16.0), ignore_monsters, dont_ignore_glass, ENT(pev), &tr); - } - if (tr.flFraction != 1.0f) - { - m_iTurnAngle = -1; + if (tr.flFraction != 1.0f) + { + m_iTurnAngle = -1; + } } } diff --git a/regamedll/dlls/weapons.h b/regamedll/dlls/weapons.h index 9266d8434..252c4c5f1 100644 --- a/regamedll/dlls/weapons.h +++ b/regamedll/dlls/weapons.h @@ -1333,7 +1333,6 @@ class CM249: public CBasePlayerWeapon const float M3_MAX_SPEED = 230.0f; const float M3_DAMAGE = 20.0f; -const Vector M3_CONE_VECTOR = Vector(0.0675, 0.0675, 0.0); // special shotgun spreads enum m3_e { @@ -1764,7 +1763,6 @@ class CTMP: public CBasePlayerWeapon const float XM1014_MAX_SPEED = 240.0f; const float XM1014_DAMAGE = 20.0f; -const Vector XM1014_CONE_VECTOR = Vector(0.0725, 0.0725, 0.0); // special shotgun spreads enum xm1014_e { diff --git a/regamedll/dlls/weapontype.cpp b/regamedll/dlls/weapontype.cpp index dd7dc0f82..cc341d7c9 100644 --- a/regamedll/dlls/weapontype.cpp +++ b/regamedll/dlls/weapontype.cpp @@ -545,7 +545,7 @@ WeaponInfoStruct *GetDefaultWeaponInfo(int weaponID) AmmoInfoStruct *GetAmmoInfo(const char *ammoName) { for (auto& info : g_ammoInfo) { - if (!Q_stricmp(info.ammoName1, ammoName)) { + if (info.ammoName1 && !Q_stricmp(info.ammoName1, ammoName)) { return &info; } } diff --git a/regamedll/dlls/wpn_shared/wpn_aug.cpp b/regamedll/dlls/wpn_shared/wpn_aug.cpp index 988c74808..dfba3fdf9 100644 --- a/regamedll/dlls/wpn_shared/wpn_aug.cpp +++ b/regamedll/dlls/wpn_shared/wpn_aug.cpp @@ -73,6 +73,15 @@ void CAUG::SecondaryAttack() else m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 90; +#ifdef REGAMEDLL_FIXES + if (TheBots) + { + TheBots->OnEvent(EVENT_WEAPON_ZOOMED, m_pPlayer); + } + + m_pPlayer->ResetMaxSpeed(); +#endif + m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.3f; } diff --git a/regamedll/dlls/wpn_shared/wpn_m3.cpp b/regamedll/dlls/wpn_shared/wpn_m3.cpp index 64ad7c5f0..2f341c951 100644 --- a/regamedll/dlls/wpn_shared/wpn_m3.cpp +++ b/regamedll/dlls/wpn_shared/wpn_m3.cpp @@ -1,5 +1,7 @@ #include "precompiled.h" +const Vector M3_CONE_VECTOR = Vector(0.0675, 0.0675, 0.0); // special shotgun spreads + LINK_ENTITY_TO_CLASS(weapon_m3, CM3, CCSM3) void CM3::Spawn() diff --git a/regamedll/dlls/wpn_shared/wpn_sg552.cpp b/regamedll/dlls/wpn_shared/wpn_sg552.cpp index e86eec412..f9eb61f5f 100644 --- a/regamedll/dlls/wpn_shared/wpn_sg552.cpp +++ b/regamedll/dlls/wpn_shared/wpn_sg552.cpp @@ -72,6 +72,15 @@ void CSG552::SecondaryAttack() else m_pPlayer->pev->fov = m_pPlayer->m_iFOV = 90; +#ifdef REGAMEDLL_FIXES + if (TheBots) + { + TheBots->OnEvent(EVENT_WEAPON_ZOOMED, m_pPlayer); + } + + m_pPlayer->ResetMaxSpeed(); +#endif + m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.3f; } diff --git a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp index a4e4304eb..c664fe597 100644 --- a/regamedll/dlls/wpn_shared/wpn_xm1014.cpp +++ b/regamedll/dlls/wpn_shared/wpn_xm1014.cpp @@ -1,5 +1,7 @@ #include "precompiled.h" +const Vector XM1014_CONE_VECTOR = Vector(0.0725, 0.0725, 0.0); // special shotgun spreads + LINK_ENTITY_TO_CLASS(weapon_xm1014, CXM1014, CCSXM1014) void CXM1014::Spawn() diff --git a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd index 79fe8333a..3d56907ea 100644 --- a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd +++ b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd @@ -1,12 +1,17 @@ // ----------------------------------------------------------------------- // Counter-Strike game definition file (.fgd) -// Version 0.9.0.0 +// Version 0.9.5.0 // Valve Hammer Editor >= 3.5 // Last update: September 25th, 2016 // ----------------------------------------------------------------------- // Based on FGD 0.8.0.0 by Dmitrich! // -// Full compatibility with https://github.com/s1lentq/ReGameDLL_CS +// Full compatibility with https://github.com/rehlds/ReGameDLL_CS +// ----------------------------------------------------------------------- +// December 12th, 2024 (0.9.5.0) +// - Added target_cdaudio +// ----------------------------------------------------------------------- +// // ----------------------------------------------------------------------- // September 25th, 2016 - s1lent (0.9.0.0) // - Removed xen entities. @@ -2323,6 +2328,46 @@ ] ] +// This entity allows to play a specific CD track when the player is within the specified radius around the entity or when triggered +// A brush entity equivalent is available as trigger_cdaudio +@PointClass base(Targetname) color(255 240 128) = target_cdaudio : "CD Audio Target" +[ + health(choices) : "Track #" : -1 = + [ + -1 : "Stop" +// 1 : "None" + 2 : "Track 1" + 3 : "Track 2" + 4 : "Track 3" + 5 : "Track 4" + 6 : "Track 5" + 7 : "Track 6" + 8 : "Track 7" + 9 : "Track 8" + 10 : "Track 9" + 11 : "Track 10" + 12 : "Track 11" + 13 : "Track 12" + 14 : "Track 13" + 15 : "Track 14" + 16 : "Track 15" + 17 : "Track 16" + 18 : "Track 17" + 19 : "Track 18" + 20 : "Track 19" + 21 : "Track 20" + 22 : "Track 21" + 23 : "Track 22" + 24 : "Track 23" + 25 : "Track 24" + 26 : "Track 25" + 27 : "Track 26" + 28 : "Track 27" + 29 : "Track 28" + ] + scale(string) : "Player Radius" : "128.0" // The player must come within this radius for the track to start playing +] + @SolidClass base(Targetname) = trigger_changelevel : "Trigger Change level" [ map(string) : "New map name" diff --git a/regamedll/game_shared/bot/nav_file.cpp b/regamedll/game_shared/bot/nav_file.cpp index 5c6d65c38..cf97f6f6a 100644 --- a/regamedll/game_shared/bot/nav_file.cpp +++ b/regamedll/game_shared/bot/nav_file.cpp @@ -67,7 +67,7 @@ Place PlaceDirectory::EntryToPlace(EntryType entry) const return UNDEFINED_PLACE; unsigned int i = entry - 1; - if (i > m_directory.size()) + if (i >= m_directory.size()) { DbgAssert(false && "PlaceDirectory::EntryToPlace: Invalid entry"); return UNDEFINED_PLACE; diff --git a/regamedll/regamedll/regamedll.cpp b/regamedll/regamedll/regamedll.cpp index 5e6190d15..9602faa17 100644 --- a/regamedll/regamedll/regamedll.cpp +++ b/regamedll/regamedll/regamedll.cpp @@ -33,7 +33,6 @@ void Regamedll_Game_Init() g_bIsBeta = UTIL_IsBeta(); g_bIsCzeroGame = UTIL_IsGame("czero"); g_bAllowedCSBot = UTIL_AreBotsAllowed(); // determine whether bots can be used or not - g_bHostageImprov = UTIL_AreHostagesImprov(); // determine whether hostage improv can be used or not WeaponInfoReset(); }