diff --git a/README.md b/README.md
index 2785c08e..ee928a92 100644
--- a/README.md
+++ b/README.md
@@ -113,6 +113,8 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
| mp_dying_time | 3.0 | 0.0 | - | Time for switch to free observing after death.
`0` - disable spectating around death.
`>0.00001` - time delay to start spectate.
`NOTE`: The countdown starts when the player’s death animation is finished. |
| mp_deathmsg_flags | abc | 0 | - | Sets a flags for extra information in the player's death message.
`0` disabled
`a` position where the victim died
`b` index of the assistant who helped the attacker kill the victim
`c` rarity classification bits, e.g., `blinkill`, `noscope`, `penetrated`, etc. |
| mp_assist_damage_threshold | 40 | 0 | 100 | Sets the percentage of damage needed to score an assist. |
+| mp_freezetime_duck | 1 | 0 | 1 | Allow players to duck during freezetime.
`0` disabled
`1` enabled |
+| mp_freezetime_jump | 1 | 0 | 1 | Allow players to jump during freezetime.
`0` disabled
`1` enabled |
## How to install zBot for CS 1.6?
diff --git a/dist/game.cfg b/dist/game.cfg
index 8f0b9d47..a1d77c20 100644
--- a/dist/game.cfg
+++ b/dist/game.cfg
@@ -553,3 +553,17 @@ mp_deathmsg_flags "abc"
//
// Default value: "40"
mp_assist_damage_threshold "40"
+
+// Allow players to duck during freezetime
+// 0 - disabled
+// 1 - enabled (default behaviour)
+//
+// Default value: "1"
+mp_freezetime_duck "1"
+
+// Allow players to jump during freezetime
+// 0 - disabled
+// 1 - enabled (default behaviour)
+//
+// Default value: "1"
+mp_freezetime_jump "1"
\ No newline at end of file
diff --git a/regamedll/dlls/API/CAPI_Impl.cpp b/regamedll/dlls/API/CAPI_Impl.cpp
index 55a56e31..5bb6b394 100644
--- a/regamedll/dlls/API/CAPI_Impl.cpp
+++ b/regamedll/dlls/API/CAPI_Impl.cpp
@@ -334,6 +334,7 @@ GAMEHOOK_REGISTRY(CBasePlayerWeapon_SendWeaponAnim);
GAMEHOOK_REGISTRY(CSGameRules_SendDeathMessage);
GAMEHOOK_REGISTRY(CBasePlayer_PlayerDeathThink);
+GAMEHOOK_REGISTRY(CBasePlayer_Observer_Think);
int CReGameApi::GetMajorVersion() {
return REGAMEDLL_API_VERSION_MAJOR;
diff --git a/regamedll/dlls/API/CAPI_Impl.h b/regamedll/dlls/API/CAPI_Impl.h
index b64f6d81..0548a841 100644
--- a/regamedll/dlls/API/CAPI_Impl.h
+++ b/regamedll/dlls/API/CAPI_Impl.h
@@ -741,6 +741,10 @@ typedef IHookChainRegistryClassImpl CReGameHo
typedef IHookChainClassImpl CReGameHook_CBasePlayer_PlayerDeathThink;
typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_PlayerDeathThink;
+// CBasePlayer::Observer_Think hook
+typedef IHookChainClassImpl CReGameHook_CBasePlayer_Observer_Think;
+typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_Observer_Think;
+
class CReGameHookchains: public IReGameHookchains {
public:
// CBasePlayer virtual
@@ -900,6 +904,7 @@ public:
CReGameHookRegistry_CSGameRules_SendDeathMessage m_CSGameRules_SendDeathMessage;
CReGameHookRegistry_CBasePlayer_PlayerDeathThink m_CBasePlayer_PlayerDeathThink;
+ CReGameHookRegistry_CBasePlayer_Observer_Think m_CBasePlayer_Observer_Think;
public:
virtual IReGameHookRegistry_CBasePlayer_Spawn *CBasePlayer_Spawn();
@@ -1058,6 +1063,7 @@ public:
virtual IReGameHookRegistry_CSGameRules_SendDeathMessage *CSGameRules_SendDeathMessage();
virtual IReGameHookRegistry_CBasePlayer_PlayerDeathThink *CBasePlayer_PlayerDeathThink();
+ virtual IReGameHookRegistry_CBasePlayer_Observer_Think *CBasePlayer_Observer_Think();
};
extern CReGameHookchains g_ReGameHookchains;
diff --git a/regamedll/dlls/API/CSEntity.cpp b/regamedll/dlls/API/CSEntity.cpp
index 0e037d29..00f7badc 100644
--- a/regamedll/dlls/API/CSEntity.cpp
+++ b/regamedll/dlls/API/CSEntity.cpp
@@ -30,15 +30,15 @@
void CCSEntity::FireBullets(int iShots, Vector &vecSrc, Vector &vecDirShooting, Vector &vecSpread, float flDistance, int iBulletType, int iTracerFreq, int iDamage, entvars_t *pevAttacker)
{
- m_pContainingEntity->FireBullets(iShots, vecSrc, vecDirShooting, vecSpread, flDistance, iBulletType, iTracerFreq, iDamage, pevAttacker);
+ BaseEntity()->FireBullets(iShots, vecSrc, vecDirShooting, vecSpread, flDistance, iBulletType, iTracerFreq, iDamage, pevAttacker);
}
void CCSEntity::FireBuckshots(ULONG cShots, Vector &vecSrc, Vector &vecDirShooting, Vector &vecSpread, float flDistance, int iTracerFreq, int iDamage, entvars_t *pevAttacker)
{
- m_pContainingEntity->FireBuckshots(cShots, vecSrc, vecDirShooting, vecSpread, flDistance, iTracerFreq, iDamage, pevAttacker);
+ BaseEntity()->FireBuckshots(cShots, vecSrc, vecDirShooting, vecSpread, flDistance, iTracerFreq, iDamage, pevAttacker);
}
Vector CCSEntity::FireBullets3(Vector &vecSrc, Vector &vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand)
{
- return m_pContainingEntity->FireBullets3(vecSrc, vecDirShooting, vecSpread, flDistance, iPenetration, iBulletType, iDamage, flRangeModifier, pevAttacker, bPistol, shared_rand);
+ return BaseEntity()->FireBullets3(vecSrc, vecDirShooting, vecSpread, flDistance, iPenetration, iBulletType, iDamage, flRangeModifier, pevAttacker, bPistol, shared_rand);
}
diff --git a/regamedll/dlls/API/CSPlayer.cpp b/regamedll/dlls/API/CSPlayer.cpp
index e55afd08..09941134 100644
--- a/regamedll/dlls/API/CSPlayer.cpp
+++ b/regamedll/dlls/API/CSPlayer.cpp
@@ -249,11 +249,13 @@ EXT_FUNC CBaseEntity *CCSPlayer::GiveNamedItemEx(const char *pszName)
if (FStrEq(pszName, "weapon_c4")) {
pPlayer->m_bHasC4 = true;
- pPlayer->SetBombIcon();
if (pPlayer->m_iTeam == TERRORIST) {
pPlayer->pev->body = 1;
}
+
+ pPlayer->SetBombIcon();
+
} else if (FStrEq(pszName, "weapon_shield")) {
pPlayer->DropPrimary();
pPlayer->DropPlayerItem("weapon_elite");
@@ -266,7 +268,7 @@ EXT_FUNC CBaseEntity *CCSPlayer::GiveNamedItemEx(const char *pszName)
EXT_FUNC bool CCSPlayer::IsConnected() const
{
- return m_pContainingEntity->has_disconnected == false;
+ return BaseEntity()->has_disconnected == false;
}
EXT_FUNC void CCSPlayer::SetAnimation(PLAYER_ANIM playerAnim)
diff --git a/regamedll/dlls/basemonster.cpp b/regamedll/dlls/basemonster.cpp
index a134d99c..bfa9a1e1 100644
--- a/regamedll/dlls/basemonster.cpp
+++ b/regamedll/dlls/basemonster.cpp
@@ -451,17 +451,13 @@ BOOL CBaseMonster::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, f
if (pev->health <= 0.0f)
{
- g_pevLastInflictor = pevInflictor;
-
if (bitsDamageType & DMG_ALWAYSGIB)
- Killed(pevAttacker, GIB_ALWAYS);
-
+ KilledInflicted(pevInflictor, pevAttacker, GIB_ALWAYS);
else if (bitsDamageType & DMG_NEVERGIB)
- Killed(pevAttacker, GIB_NEVER);
+ KilledInflicted(pevInflictor, pevAttacker, GIB_NEVER);
else
- Killed(pevAttacker, GIB_NORMAL);
+ KilledInflicted(pevInflictor, pevAttacker, GIB_NORMAL);
- g_pevLastInflictor = nullptr;
return FALSE;
}
if ((pev->flags & FL_MONSTER) && !FNullEnt(pevAttacker))
diff --git a/regamedll/dlls/cbase.cpp b/regamedll/dlls/cbase.cpp
index 9e14bf43..77a49944 100644
--- a/regamedll/dlls/cbase.cpp
+++ b/regamedll/dlls/cbase.cpp
@@ -697,7 +697,11 @@ BOOL CBaseEntity::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, fl
pev->health -= flDamage;
if (pev->health <= 0)
{
+#ifdef REGAMEDLL_FIXES
+ KilledInflicted(pevInflictor, pevAttacker, GIB_NORMAL);
+#else
Killed(pevAttacker, GIB_NORMAL);
+#endif
return FALSE;
}
@@ -866,6 +870,17 @@ BOOL CBaseEntity::IsInWorld()
}
// speed
+#ifdef REGAMEDLL_FIXES
+ float maxvel = g_psv_maxvelocity->value;
+ if (pev->velocity.x > maxvel || pev->velocity.y > maxvel || pev->velocity.z > maxvel)
+ {
+ return FALSE;
+ }
+ if (pev->velocity.x < -maxvel || pev->velocity.y < -maxvel || pev->velocity.z < -maxvel)
+ {
+ return FALSE;
+ }
+#else
if (pev->velocity.x >= 2000.0 || pev->velocity.y >= 2000.0 || pev->velocity.z >= 2000.0)
{
return FALSE;
@@ -874,6 +889,7 @@ BOOL CBaseEntity::IsInWorld()
{
return FALSE;
}
+#endif
return TRUE;
}
diff --git a/regamedll/dlls/cbase.h b/regamedll/dlls/cbase.h
index 986933f5..e6830142 100644
--- a/regamedll/dlls/cbase.h
+++ b/regamedll/dlls/cbase.h
@@ -246,6 +246,9 @@ public:
void ResetDmgPenetrationLevel();
int GetDmgPenetrationLevel() const;
+ void KilledInflicted(entvars_t *pevInflictor, entvars_t *pevAttacker, int iGib);
+ entvars_t *GetLastInflictor();
+
#ifdef REGAMEDLL_API
CCSEntity *m_pEntity;
CCSEntity *CSEntity() const;
diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp
index 56297b35..825125cf 100644
--- a/regamedll/dlls/client.cpp
+++ b/regamedll/dlls/client.cpp
@@ -673,10 +673,12 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
CBaseEntity *pTarget = nullptr;
pPlayer->m_pIntroCamera = UTIL_FindEntityByClassname(nullptr, "trigger_camera");
+#ifndef REGAMEDLL_FIXES
if (g_pGameRules && g_pGameRules->IsMultiplayer())
{
CSGameRules()->m_bMapHasCameras = (pPlayer->m_pIntroCamera != nullptr);
}
+#endif
if (pPlayer->m_pIntroCamera)
{
@@ -694,7 +696,12 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
pPlayer->pev->angles = CamAngles;
pPlayer->pev->v_angle = pPlayer->pev->angles;
- pPlayer->m_fIntroCamTime = gpGlobals->time + 6;
+ pPlayer->m_fIntroCamTime =
+#ifdef REGAMEDLL_FIXES
+ (CSGameRules()->m_bMapHasCameras <= 1) ? 0.0 : // no need to refresh cameras if map has only one
+#endif
+ gpGlobals->time + 6;
+
pPlayer->pev->view_ofs = g_vecZero;
}
#ifndef REGAMEDLL_FIXES
diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp
index 5ea4138d..0ca187d4 100644
--- a/regamedll/dlls/game.cpp
+++ b/regamedll/dlls/game.cpp
@@ -9,6 +9,7 @@ cvar_t *g_psv_friction = nullptr;
cvar_t *g_psv_stopspeed = nullptr;
cvar_t *g_psv_stepsize = nullptr;
cvar_t *g_psv_clienttrace = nullptr;
+cvar_t *g_psv_maxvelocity = nullptr;
cvar_t displaysoundlist = { "displaysoundlist", "0", 0, 0.0f, nullptr };
cvar_t timelimit = { "mp_timelimit", "0", FCVAR_SERVER, 0.0f, nullptr };
@@ -168,6 +169,8 @@ cvar_t plant_c4_anywhere = { "mp_plant_c4_anywhere", "0", 0, 0.0
cvar_t give_c4_frags = { "mp_give_c4_frags", "3", 0, 3.0f, nullptr };
cvar_t deathmsg_flags = { "mp_deathmsg_flags", "abc", 0, 0.0f, nullptr };
cvar_t assist_damage_threshold = { "mp_assist_damage_threshold", "40", 0, 40.0f, nullptr };
+cvar_t freezetime_duck = { "mp_freezetime_duck", "1", 0, 1.0f, nullptr };
+cvar_t freezetime_jump = { "mp_freezetime_jump", "1", 0, 1.0f, nullptr };
cvar_t hostages_rescued_ratio = { "mp_hostages_rescued_ratio", "1.0", 0, 1.0f, nullptr };
@@ -238,6 +241,7 @@ void EXT_FUNC GameDLLInit()
g_psv_stopspeed = CVAR_GET_POINTER("sv_stopspeed");
g_psv_stepsize = CVAR_GET_POINTER("sv_stepsize");
g_psv_clienttrace = CVAR_GET_POINTER("sv_clienttrace");
+ g_psv_maxvelocity = CVAR_GET_POINTER("sv_maxvelocity");
CVAR_REGISTER(&displaysoundlist);
CVAR_REGISTER(&timelimit);
@@ -432,6 +436,9 @@ void EXT_FUNC GameDLLInit()
CVAR_REGISTER(&deathmsg_flags);
CVAR_REGISTER(&assist_damage_threshold);
+ CVAR_REGISTER(&freezetime_duck);
+ CVAR_REGISTER(&freezetime_jump);
+
// print version
CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n");
diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h
index 7a11628a..9a1a5d9d 100644
--- a/regamedll/dlls/game.h
+++ b/regamedll/dlls/game.h
@@ -43,12 +43,13 @@
extern cvar_t *g_pskill;
extern cvar_t *g_psv_gravity;
extern cvar_t *g_psv_aim;
+extern cvar_t *g_footsteps;
extern cvar_t *g_psv_accelerate;
extern cvar_t *g_psv_friction;
extern cvar_t *g_psv_stopspeed;
extern cvar_t *g_psv_stepsize;
extern cvar_t *g_psv_clienttrace;
-extern cvar_t *g_footsteps;
+extern cvar_t *g_psv_maxvelocity;
extern cvar_t displaysoundlist;
extern cvar_t timelimit;
@@ -199,6 +200,8 @@ extern cvar_t player_movement_legacy;
extern cvar_t player_movement_penalty_jump;
extern cvar_t deathmsg_flags;
extern cvar_t assist_damage_threshold;
+extern cvar_t freezetime_duck;
+extern cvar_t freezetime_jump;
#endif
diff --git a/regamedll/dlls/gamerules.h b/regamedll/dlls/gamerules.h
index 1346de2f..e29aaba8 100644
--- a/regamedll/dlls/gamerules.h
+++ b/regamedll/dlls/gamerules.h
@@ -779,7 +779,7 @@ public:
bool m_bMapHasEscapeZone;
BOOL m_bMapHasVIPSafetyZone; // TRUE = has VIP safety zone, FALSE = does not have VIP safetyzone
- BOOL m_bMapHasCameras;
+ int m_bMapHasCameras;
int m_iC4Timer;
int m_iC4Guy; // The current Terrorist who has the C4.
int m_iLoserBonus; // the amount of money the losing team gets. This scales up as they lose more rounds in a row
diff --git a/regamedll/dlls/ggrenade.cpp b/regamedll/dlls/ggrenade.cpp
index 678a78d5..41e92f27 100644
--- a/regamedll/dlls/ggrenade.cpp
+++ b/regamedll/dlls/ggrenade.cpp
@@ -772,6 +772,13 @@ void CGrenade::BounceSound()
void CGrenade::TumbleThink()
{
+#ifdef REGAMEDLL_FIXES
+ if (pev->velocity.IsLengthGreaterThan(g_psv_maxvelocity->value))
+ {
+ pev->velocity = pev->velocity.Normalize() * g_psv_maxvelocity->value;
+ }
+#endif
+
if (!IsInWorld())
{
UTIL_Remove(this);
@@ -809,6 +816,13 @@ void CGrenade::TumbleThink()
void CGrenade::SG_TumbleThink()
{
+#ifdef REGAMEDLL_FIXES
+ if (pev->velocity.IsLengthGreaterThan(g_psv_maxvelocity->value))
+ {
+ pev->velocity = pev->velocity.Normalize() * g_psv_maxvelocity->value;
+ }
+#endif
+
if (!IsInWorld())
{
UTIL_Remove(this);
@@ -1322,6 +1336,13 @@ void AnnounceFlashInterval(float interval, float offset)
void CGrenade::C4Think()
{
+#ifdef REGAMEDLL_FIXES
+ if (pev->velocity.IsLengthGreaterThan(g_psv_maxvelocity->value))
+ {
+ pev->velocity = pev->velocity.Normalize() * g_psv_maxvelocity->value;
+ }
+#endif
+
if (!IsInWorld())
{
#ifdef REGAMEDLL_FIXES
diff --git a/regamedll/dlls/gib.cpp b/regamedll/dlls/gib.cpp
index 069b118d..9301e283 100644
--- a/regamedll/dlls/gib.cpp
+++ b/regamedll/dlls/gib.cpp
@@ -4,12 +4,11 @@ LINK_ENTITY_TO_CLASS(gib, CGib, CCSGib)
void CGib::LimitVelocity()
{
- float length = pev->velocity.Length();
- float topspeed = CVAR_GET_FLOAT("sv_maxvelocity") * 0.75f;
+ float topspeed = g_psv_maxvelocity->value * 0.75f;
// ceiling at topspeed. 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 > topspeed)
+ if (pev->velocity.IsLengthGreaterThan(topspeed))
{
// DONE: This should really be sv_maxvelocity * 0.75 or something
pev->velocity = pev->velocity.Normalize() * topspeed;
diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp
index 58116bd9..4f489971 100644
--- a/regamedll/dlls/multiplay_gamerules.cpp
+++ b/regamedll/dlls/multiplay_gamerules.cpp
@@ -382,7 +382,7 @@ CHalfLifeMultiplay::CHalfLifeMultiplay()
m_iNumTerrorist = 0;
m_iNumSpawnableCT = 0;
m_iNumSpawnableTerrorist = 0;
- m_bMapHasCameras = FALSE;
+ m_bMapHasCameras = -1;
m_iLoserBonus = m_rgRewardAccountRules[RR_LOSER_BONUS_DEFAULT];
m_iNumConsecutiveCTLoses = 0;
@@ -3086,17 +3086,11 @@ void CHalfLifeMultiplay::CheckLevelInitialized()
{
// Count the number of spawn points for each team
// This determines the maximum number of players allowed on each
- CBaseEntity *pEnt = nullptr;
-
- m_iSpawnPointCount_Terrorist = 0;
- m_iSpawnPointCount_CT = 0;
-
- while ((pEnt = UTIL_FindEntityByClassname(pEnt, "info_player_deathmatch")))
- m_iSpawnPointCount_Terrorist++;
-
- while ((pEnt = UTIL_FindEntityByClassname(pEnt, "info_player_start")))
- m_iSpawnPointCount_CT++;
-
+ m_iSpawnPointCount_Terrorist = UTIL_CountEntities("info_player_deathmatch");
+ m_iSpawnPointCount_CT = UTIL_CountEntities("info_player_start");
+#ifdef REGAMEDLL_FIXES
+ m_bMapHasCameras = UTIL_CountEntities("trigger_camera");
+#endif
m_bLevelInitialized = true;
}
}
diff --git a/regamedll/dlls/observer.cpp b/regamedll/dlls/observer.cpp
index e0bdc644..4b3521a6 100644
--- a/regamedll/dlls/observer.cpp
+++ b/regamedll/dlls/observer.cpp
@@ -541,9 +541,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Observer_SetMode)(int iMode)
m_bWasFollowing = false;
}
-void CBasePlayer::Observer_Think()
+LINK_HOOK_CLASS_VOID_CHAIN2(CBasePlayer, Observer_Think)
+
+void EXT_FUNC CBasePlayer::__API_HOOK(Observer_Think)()
{
Observer_HandleButtons();
Observer_CheckTarget();
Observer_CheckProperties();
-}
+}
\ No newline at end of file
diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp
index 5e7eed2f..8b71d844 100644
--- a/regamedll/dlls/player.cpp
+++ b/regamedll/dlls/player.cpp
@@ -82,7 +82,9 @@ const char *CDeadHEV::m_szPoses[] =
"deadtable"
};
+#ifndef REGAMEDLL_API
entvars_t *g_pevLastInflictor;
+#endif
LINK_ENTITY_TO_CLASS(player, CBasePlayer, CCSPlayer)
@@ -1693,7 +1695,6 @@ void EXT_FUNC CBasePlayer::__API_HOOK(GiveDefaultItems)()
void CBasePlayer::RemoveAllItems(BOOL removeSuit)
{
- bool bKillProgBar = false;
int i;
#ifdef REGAMEDLL_FIXES
@@ -1713,20 +1714,12 @@ void CBasePlayer::RemoveAllItems(BOOL removeSuit)
{
m_bHasC4 = false;
pev->body = 0;
-
- MESSAGE_BEGIN(MSG_ONE, gmsgStatusIcon, nullptr, pev);
- WRITE_BYTE(STATUSICON_HIDE);
- WRITE_STRING("c4");
- MESSAGE_END();
-
- bKillProgBar = true;
+ SetBombIcon(FALSE);
+ SetProgressBarTime(0);
}
RemoveShield();
- if (bKillProgBar)
- SetProgressBarTime(0);
-
if (m_pActiveItem)
{
ResetAutoaim();
@@ -2130,7 +2123,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
if (IsBot() && IsBlind()) // dystopm: shouldn't be !IsBot() ?
wasBlind = true;
- TheCareerTasks->HandleEnemyKill(wasBlind, GetKillerWeaponName(g_pevLastInflictor, pevAttacker), m_bHeadshotKilled, killerHasShield, pAttacker, this); // last 2 param swapped to match function definition
+ TheCareerTasks->HandleEnemyKill(wasBlind, GetKillerWeaponName(GetLastInflictor(), pevAttacker), m_bHeadshotKilled, killerHasShield, pAttacker, this); // last 2 param swapped to match function definition
}
}
#endif
@@ -2161,7 +2154,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
{
if (TheCareerTasks)
{
- TheCareerTasks->HandleEnemyKill(wasBlind, GetKillerWeaponName(g_pevLastInflictor, pevAttacker), m_bHeadshotKilled, killerHasShield, this, pPlayer);
+ TheCareerTasks->HandleEnemyKill(wasBlind, GetKillerWeaponName(GetLastInflictor(), pevAttacker), m_bHeadshotKilled, killerHasShield, this, pPlayer);
}
}
}
@@ -2171,7 +2164,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
if (!m_bKilledByBomb)
{
- g_pGameRules->PlayerKilled(this, pevAttacker, g_pevLastInflictor);
+ g_pGameRules->PlayerKilled(this, pevAttacker, GetLastInflictor());
}
MESSAGE_BEGIN(MSG_ONE, gmsgNVGToggle, nullptr, pev);
@@ -3673,7 +3666,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(JoiningThink)()
}
}
- if (m_pIntroCamera && gpGlobals->time >= m_fIntroCamTime)
+ if (m_pIntroCamera && gpGlobals->time >= m_fIntroCamTime
+#ifdef REGAMEDLL_FIXES
+ && m_fIntroCamTime > 0.0 // update only if cameras are available
+#endif
+ )
{
// find the next another camera
m_pIntroCamera = UTIL_FindEntityByClassname(m_pIntroCamera, "trigger_camera");
@@ -10359,8 +10356,8 @@ bool EXT_FUNC CBasePlayer::__API_HOOK(MakeBomber)()
}
m_bHasC4 = true;
- SetBombIcon();
pev->body = 1;
+ SetBombIcon();
m_flDisplayHistory |= DHF_BOMB_RETRIEVED;
HintMessage("#Hint_you_have_the_bomb", FALSE, TRUE);
diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h
index d3b8e623..bd3bf33e 100644
--- a/regamedll/dlls/player.h
+++ b/regamedll/dlls/player.h
@@ -447,7 +447,8 @@ public:
void CheckTimeBasedDamage_OrigFunc();
edict_t *EntSelectSpawnPoint_OrigFunc();
void PlayerDeathThink_OrigFunc();
-
+ void Observer_Think_OrigFunc();
+
CCSPlayer *CSPlayer() const;
#endif // REGAMEDLL_API
@@ -975,7 +976,9 @@ inline CBasePlayer *UTIL_PlayerByIndexSafe(int playerIndex)
return pPlayer;
}
+#ifndef REGAMEDLL_API
extern entvars_t *g_pevLastInflictor;
+#endif
extern CBaseEntity *g_pLastSpawn;
extern CBaseEntity *g_pLastCTSpawn;
extern CBaseEntity *g_pLastTerroristSpawn;
diff --git a/regamedll/dlls/util.cpp b/regamedll/dlls/util.cpp
index 6b2fda0c..714fe79d 100644
--- a/regamedll/dlls/util.cpp
+++ b/regamedll/dlls/util.cpp
@@ -1758,6 +1758,17 @@ int UTIL_GetNumPlayers()
return nNumPlayers;
}
+int UTIL_CountEntities(const char *szName)
+{
+ int count = 0;
+ CBaseEntity *pEnt = nullptr;
+
+ while ((pEnt = UTIL_FindEntityByClassname(pEnt, szName)))
+ count++;
+
+ return count;
+}
+
bool UTIL_IsSpawnPointOccupied(CBaseEntity *pSpot)
{
if (!pSpot)
diff --git a/regamedll/dlls/util.h b/regamedll/dlls/util.h
index 9ed3f40e..f96be669 100644
--- a/regamedll/dlls/util.h
+++ b/regamedll/dlls/util.h
@@ -297,6 +297,7 @@ bool UTIL_AreBotsAllowed();
bool UTIL_IsBeta();
bool UTIL_AreHostagesImprov();
int UTIL_GetNumPlayers();
+int UTIL_CountEntities(const char *szName);
bool UTIL_IsSpawnPointOccupied(CBaseEntity *pSpot);
void MAKE_STRING_CLASS(const char *str, entvars_t *pev);
void NORETURN Sys_Error(const char *error, ...);
diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp
index 2d5b5ed5..3baa8a44 100644
--- a/regamedll/dlls/weapons.cpp
+++ b/regamedll/dlls/weapons.cpp
@@ -1920,8 +1920,8 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
MESSAGE_END();
pPlayer->m_bHasC4 = true;
- pPlayer->SetBombIcon(FALSE);
pPlayer->pev->body = 1;
+ pPlayer->SetBombIcon(FALSE);
CBaseEntity *pEntity = nullptr;
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")))
diff --git a/regamedll/pm_shared/pm_shared.cpp b/regamedll/pm_shared/pm_shared.cpp
index 0f813c38..032a42f4 100644
--- a/regamedll/pm_shared/pm_shared.cpp
+++ b/regamedll/pm_shared/pm_shared.cpp
@@ -1917,8 +1917,8 @@ void EXT_FUNC __API_HOOK(PM_Duck)()
}
#ifdef REGAMEDLL_ADD
- // Prevent ducking if the iuser3 variable is contain PLAYER_PREVENT_DUCK
- if ((pmove->iuser3 & PLAYER_PREVENT_DUCK) == PLAYER_PREVENT_DUCK)
+ if ((pmove->iuser3 & PLAYER_PREVENT_DUCK) == PLAYER_PREVENT_DUCK // Prevent ducking if the iuser3 variable is contain PLAYER_PREVENT_DUCK
+ || freezetime_duck.value == 0.0f && CSGameRules()->IsFreezePeriod()) // Prevent ducking during freezetime if the freezetime_duck cvar is 0
{
// Try to unduck
if (pmove->flags & FL_DUCKING)
@@ -2473,8 +2473,8 @@ void EXT_FUNC __API_HOOK(PM_Jump)()
}
#ifdef REGAMEDLL_ADD
- // Prevent jumping if the iuser3 variable is contain PLAYER_PREVENT_JUMP
- if ((pmove->iuser3 & PLAYER_PREVENT_JUMP) == PLAYER_PREVENT_JUMP)
+ if ((pmove->iuser3 & PLAYER_PREVENT_JUMP) == PLAYER_PREVENT_JUMP // Prevent jumping if the iuser3 variable is contain PLAYER_PREVENT_JUMP
+ || freezetime_jump.value == 0.0f && CSGameRules()->IsFreezePeriod()) // Prevent jumping during freezetime if the freezetime_jump cvar is 0
{
return;
}
diff --git a/regamedll/public/regamedll/API/CSEntity.h b/regamedll/public/regamedll/API/CSEntity.h
index e2c1922c..edfb660a 100644
--- a/regamedll/public/regamedll/API/CSEntity.h
+++ b/regamedll/public/regamedll/API/CSEntity.h
@@ -43,15 +43,18 @@ public:
virtual void FireBuckshots(ULONG cShots, Vector &vecSrc, Vector &vecDirShooting, Vector &vecSpread, float flDistance, int iTracerFreq, int iDamage, entvars_t *pevAttacker);
virtual Vector FireBullets3(Vector &vecSrc, Vector &vecDirShooting, float vecSpread, float flDistance, int iPenetration, int iBulletType, int iDamage, float flRangeModifier, entvars_t *pevAttacker, bool bPistol, int shared_rand);
+ CBaseEntity *BaseEntity() const;
+
public:
CBaseEntity *m_pContainingEntity;
unsigned char m_ucDmgPenetrationLevel; // penetration level of the damage caused by the inflictor
+ entvars_t *m_pevLastInflictor;
private:
#if defined(_MSC_VER)
#pragma region reserve_data_Region
#endif
- char CCSEntity_Reserve[0x3FFF];
+ char CCSEntity_Reserve[0x3FF7];
virtual void func_reserve1() {};
virtual void func_reserve2() {};
@@ -88,29 +91,61 @@ private:
#endif
};
+// Inlines
+inline CBaseEntity *CCSEntity::BaseEntity() const
+{
+ return this->m_pContainingEntity;
+}
+
inline void CBaseEntity::SetDmgPenetrationLevel(int iPenetrationLevel)
{
#ifdef REGAMEDLL_API
- m_pEntity->m_ucDmgPenetrationLevel = iPenetrationLevel;
+ CSEntity()->m_ucDmgPenetrationLevel = iPenetrationLevel;
#endif
}
inline void CBaseEntity::ResetDmgPenetrationLevel()
{
#ifdef REGAMEDLL_API
- m_pEntity->m_ucDmgPenetrationLevel = 0;
+ CSEntity()->m_ucDmgPenetrationLevel = 0;
#endif
}
inline int CBaseEntity::GetDmgPenetrationLevel() const
{
#ifdef REGAMEDLL_API
- return m_pEntity->m_ucDmgPenetrationLevel;
+ return CSEntity()->m_ucDmgPenetrationLevel;
#else
return 0;
#endif
}
+inline void CBaseEntity::KilledInflicted(entvars_t* pevInflictor, entvars_t *pevAttacker, int iGib)
+{
+#ifdef REGAMEDLL_API
+ CSEntity()->m_pevLastInflictor = pevInflictor;
+#else
+ g_pevLastInflictor = pevInflictor;
+#endif
+
+ Killed(pevAttacker, iGib);
+
+#ifdef REGAMEDLL_API
+ CSEntity()->m_pevLastInflictor = nullptr;
+#else
+ g_pevLastInflictor = nullptr;
+#endif
+}
+
+inline entvars_t* CBaseEntity::GetLastInflictor()
+{
+#ifdef REGAMEDLL_API
+ return CSEntity()->m_pevLastInflictor;
+#else
+ return g_pevLastInflictor;
+#endif
+}
+
class CCSDelay: public CCSEntity
{
public:
diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h
index e1191494..4aeb1254 100644
--- a/regamedll/public/regamedll/regamedll_api.h
+++ b/regamedll/public/regamedll/regamedll_api.h
@@ -588,10 +588,6 @@ typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_TeamS
typedef IHookChain IReGameHook_CSGameRules_PlayerGotWeapon;
typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_PlayerGotWeapon;
-// CHalfLifeMultiplay::SendDeathMessage hook
-typedef IHookChain IReGameHook_CSGameRules_SendDeathMessage;
-typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_SendDeathMessage;
-
// CBotManager::OnEvent hook
typedef IHookChain IReGameHook_CBotManager_OnEvent;
typedef IHookChainRegistry IReGameHookRegistry_CBotManager_OnEvent;
@@ -616,10 +612,18 @@ typedef IHookChainRegistryClass IReGameHook_CBasePlayerWeapon_SendWeaponAnim;
typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayerWeapon_SendWeaponAnim;
+// CHalfLifeMultiplay::SendDeathMessage hook
+typedef IHookChain IReGameHook_CSGameRules_SendDeathMessage;
+typedef IHookChainRegistry IReGameHookRegistry_CSGameRules_SendDeathMessage;
+
// CBasePlayer::PlayerDeathThink hook
typedef IHookChainClass IReGameHook_CBasePlayer_PlayerDeathThink;
typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_PlayerDeathThink;
+// CBasePlayer::Observer_Think hook
+typedef IHookChainClass IReGameHook_CBasePlayer_Observer_Think;
+typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_Observer_Think;
+
class IReGameHookchains {
public:
virtual ~IReGameHookchains() {}
@@ -780,6 +784,7 @@ public:
virtual IReGameHookRegistry_CSGameRules_SendDeathMessage *CSGameRules_SendDeathMessage() = 0;
virtual IReGameHookRegistry_CBasePlayer_PlayerDeathThink *CBasePlayer_PlayerDeathThink() = 0;
+ virtual IReGameHookRegistry_CBasePlayer_Observer_Think *CBasePlayer_Observer_Think() = 0;
};
struct ReGameFuncs_t {