diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index ca1c0f7df..0f679f1e7 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -25,7 +25,7 @@ jobs:
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -38,7 +38,7 @@ jobs:
- run: nuget restore '${{ env.solution }}'
- name: Setup MSBuild
- uses: microsoft/setup-msbuild@v1.0.2
+ uses: microsoft/setup-msbuild@v1.1.3
with:
vs-version: '16.8'
@@ -66,86 +66,19 @@ jobs:
move msvc\${{ env.buildRelease }}\mp.pdb publish\debug\mp.pdb
- name: Deploy artifacts
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3.1.1
with:
name: win32
path: publish/*
- testdemos:
- name: 'Test demos'
- runs-on: ubuntu-latest
- container: s1lentq/testdemos:latest
- needs: [windows]
-
- env:
- WINEDEBUG: -all
- WINEDLLOVERRIDES: mshtml=
-
- defaults:
- run:
- shell: bash
- working-directory: ../../../opt/HLDS
-
- steps:
- - name: Deploying windows artifacts
- uses: actions/download-artifact@v2
- with:
- name: win32
-
- - name: Play demos
- run: |
- chown root ~
- rsync -a deps/regamedll/* .
- mv $GITHUB_WORKSPACE/tests/mp.dll cstrike/dlls/mp.dll
-
- descs=(
- "CS: Testing jumping, scenarios, shooting etc"
- )
-
- demos=(
- "cstrike-basic-1"
- )
-
- retVal=0
- for i in "${!demos[@]}"; do
- params=$(cat "testdemos/${demos[i]}.params")
-
- echo -e "\e[1m[$((i + 1))/${#demos[@]}] \e[1;36m${descs[i]} testing...\e[0m"
- echo -e " - \e[0;33mParameters $params\e[0m"
-
- wine hlds.exe --rehlds-enable-all-hooks --rehlds-test-play "testdemos/${demos[i]}.bin" $params &> result.log || retVal=$?
-
- if [ $retVal -ne 777 ] && [ $retVal -ne 9 ]; then
- # Print with catchy messages
- while read line; do
- echo -e " \e[0;33m$line"
- done <<< $(cat result.log | sed '0,/demo failed/I!d;/wine:/d;/./,$!d')
-
- echo " 🔸 🔸 🔸 🔸 🔸 🔸 🔸 🔸 🔸 🔸"
- while read line; do
- echo -e " \e[1;31m$line";
- done < rehlds_demo_error.txt
- echo -e " \e[30;41mExit code: $retVal\e[0m"
- echo -e "\e[1m[$((i + 1))/${#demos[@]}] \e[1;36m${descs[i]} testing...\e[1;31m Failed ❌"
- exit 6 # Test demo failed
- else
- # Print result HLDS console
- while read line; do
- echo -e " \e[0;33m$line"
- done <<< $(cat result.log | sed '/wine:/d;/./,$!d')
- echo -e " \e[30;43mExit code: $retVal\e[0m"
- echo -e "\e[1m[$((i + 1))/${#demos[@]}] \e[1;36m${descs[i]} testing...\e[1;32m Succeed ✔"
- fi
- done
-
linux:
name: 'Linux'
- runs-on: ubuntu-latest
+ runs-on: ubuntu-20.04
container: s1lentq/linux86buildtools:latest
steps:
- name: Checkout
- uses: actions/checkout@v2
+ uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: true
@@ -207,7 +140,7 @@ jobs:
shell: bash
- name: Deploy artifacts
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
id: upload-job
with:
name: linux32
@@ -221,17 +154,17 @@ jobs:
publish:
name: 'Publish'
- runs-on: ubuntu-latest
- needs: [windows, testdemos, linux]
+ runs-on: ubuntu-20.04
+ needs: [windows, linux]
steps:
- name: Deploying linux artifacts
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v3
with:
name: linux32
- name: Deploying windows artifacts
- uses: actions/download-artifact@v2
+ uses: actions/download-artifact@v3
with:
name: win32
diff --git a/README.md b/README.md
index 7e289f8d8..6bbb686a6 100644
--- a/README.md
+++ b/README.md
@@ -45,6 +45,8 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
| mp_round_restart_delay | 5 | - | - | Number of seconds to delay before restarting a round after a win. |
| mp_hegrenade_penetration | 0 | 0 | 1 | Disable grenade damage through walls.
`0` disabled
`1` enabled |
| mp_nadedrops | 0 | 0 | 2 | Drop a grenade after player death.
`0` disabled
`1` drop first available grenade
`2` drop all grenades |
+| mp_weapondrop | 1 | 0 | 3 | Drop player weapon after death.
`0` do not drop weapons after death
`1` drop best/heaviest weapon after death
`2` drop active weapon after death
`3` drop all weapons after death (primary and secondary) |
+| mp_ammodrop | 1 | 0 | 2 | Drop ammo on weapon boxes on death or manual drop.
`0` always keep ammo on player
`1` drop all ammo only after death
`2` drop all ammo whenever player drops a weapon |
| mp_roundrespawn_time | 20 | 0 | - | Player cannot respawn until next round if more than N seconds has elapsed since the beginning round.
`-1` means no time limit
|
| mp_auto_reload_weapons | 0 | 0 | 1 | Automatically reload each weapon on player spawn.
`0` disabled
`1` enabled |
| mp_refill_bpammo_weapons | 0 | 0 | 2 | Refill amount of backpack ammo up to the max.
`0` disabled
`1` refill backpack ammo on player spawn
`2` refill backpack ammo on player spawn and on the purchase of the item |
@@ -62,7 +64,7 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
| mp_show_scenarioicon | 0 | 0 | 1 | Show scenario icon in HUD such as count of alive hostages or ticking bomb.
`0` disabled
`1` enabled |
| mp_old_bomb_defused_sound | 1 | 0 | 1 | Play "Bomb has been defused" sound instead of "Counter-Terrorists win" when bomb was defused
`0` disabled
`1` enabled |
| showtriggers | 0 | 0 | 1 | Debug cvar shows triggers. |
-| sv_alltalk | 0 | 0 | 5 | When players can hear each other ([further explanation](../../wiki/sv_alltalk)).
`0` dead don't hear alive
`1` no restrictions
`2` teammates hear each other
`3` Same as 2, but spectators hear everybody
`4` alive hear alive, dead hear dead and alive.
`5` alive hear alive teammates, dead hear dead and alive.
+| sv_alltalk | 0 | 0 | 5 | When players can hear each other ([further explanation](../../wiki/sv_alltalk)).
`0` dead don't hear alive
`1` no restrictions
`2` teammates hear each other
`3` Same as 2, but spectators hear everybody
`4` alive hear alive, dead hear dead and alive.
`5` alive hear alive teammates, dead hear dead and alive.
`6` alive hear alive teammates, dead hear dead.
| bot_deathmatch | 0 | 0 | 1 | Sets the mode for the zBot.
`0` disabled
`1` enable mode Deathmatch and not allow to do the scenario |
| bot_quota_mode | normal | - | - | Determines the type of quota.
`normal` default behaviour
`fill` the server will adjust bots to keep `N` players in the game, where `N` is bot_quota
`match` the server will maintain a `1:N` ratio of humans to bots, where `N` is bot_quota |
| bot_join_delay | 0 | - | - | Prevents bots from joining the server for this many seconds after a map change. |
@@ -105,6 +107,9 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
| sv_enablebunnyhopping | 0 | 0 | 1 | Allow player speed to exceed maximum running speed.
`0` disabled
`1` enabled |
| mp_plant_c4_anywhere | 0 | 0 | 1 | When set, players can plant anywhere, not only in bombsites.
`0` disabled
`1` enabled |
| mp_give_c4_frags | 3 | - | - | How many bonuses (frags) will get the player who defused or exploded the bomb. |
+| mp_hostages_rescued_ratio | 1.0 | 0.0 | 1.0 | Ratio of hostages rescued to win the round. |
+| mp_legacy_vehicle_block | 1 | 0 | 1 | Legacy func_vehicle behavior when blocked by another entity.
`0` New behavior
`1` Legacy behavior |
+| 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.|
## How to install zBot for CS 1.6?
diff --git a/dist/game.cfg b/dist/game.cfg
index eb6f511ff..4443b3255 100644
--- a/dist/game.cfg
+++ b/dist/game.cfg
@@ -78,6 +78,23 @@ mp_hegrenade_penetration 0
// Default value: "0"
mp_nadedrops 0
+// Drop player weapon after death
+// 0 - do not drop weapons after death
+// 1 - drop best/heaviest weapon after death (default behaviour)
+// 2 - drop active weapon after death
+// 3 - drop all weapons after death (primary and secondary)
+// NOTE: Grenades are dropped separately depending on mp_nadedrops value
+//
+// Default value: "1"
+mp_weapondrop "1"
+// Drop ammo on weapon boxes on death or manual drop
+// 0 - always keep ammo on player
+// 1 - drop all ammo only after death (default behaviour)
+// 2 - drop all ammo whenever player drops a weapon (NOTE: Other weapons may remain without ammo due to same ammo sharing)
+//
+// Default value: "1"
+mp_ammodrop "1"
+
// Player cannot respawn until next round
// if more than N seconds has elapsed since the beginning round
// -1 - means no time limit
@@ -222,6 +239,7 @@ showtriggers 0
// 3 - same as 2, but spectators hear everybody
// 4 - alive hear alive, dead hear dead and alive.
// 5 - alive hear alive teammates, dead hear dead and alive.
+// 6 - alive hear alive teammates, dead hear dead.
//
// Default value: "0"
sv_alltalk 0
@@ -489,3 +507,25 @@ mp_plant_c4_anywhere 0
//
// Default value: "3"
mp_give_c4_frags 3
+
+// Ratio of hostages rescued to win the round.
+//
+// Default value: "1.0"
+mp_hostages_rescued_ratio "1.0"
+
+// Legacy func_vehicle behavior when blocked by another entity.
+// New one is more useful for playing multiplayer.
+//
+// 0 - New behavior
+// 1 - Legacy behavior
+//
+// Default value: "1"
+mp_legacy_vehicle_block "1"
+
+// Time for switch to free observing after death.
+// NOTE: The countdown starts when the player’s death animation is finished.
+// 0 - disable spectating around death
+// >0.00001 - time delay to start spectate
+//
+// Default value: "3.0"
+mp_dying_time "3.0"
diff --git a/regamedll/common/const.h b/regamedll/common/const.h
index 3c9873114..940cff141 100644
--- a/regamedll/common/const.h
+++ b/regamedll/common/const.h
@@ -96,6 +96,12 @@
// Goes into globalvars_t.trace_flags
#define FTRACE_SIMPLEBOX BIT(0) // Traceline with a simple box
+// Custom flags that we can retrive in pfnShouldCollide
+// Starting from BIT(16) to reserve space for more flags for Engine
+#define FTRACE_BULLET BIT(16)
+#define FTRACE_FLASH BIT(17)
+#define FTRACE_KNIFE BIT(18)
+
// walkmove modes
#define WALKMOVE_NORMAL 0 // normal walkmove
#define WALKMOVE_WORLDONLY 1 // doesn't hit ANY entities, no matter what the solid type
diff --git a/regamedll/dlls/API/CAPI_Impl.cpp b/regamedll/dlls/API/CAPI_Impl.cpp
index 0fe10a490..d0d8813cd 100644
--- a/regamedll/dlls/API/CAPI_Impl.cpp
+++ b/regamedll/dlls/API/CAPI_Impl.cpp
@@ -30,12 +30,15 @@
CReGameHookchains g_ReGameHookchains;
-int EXT_FUNC Cmd_Argc_api() {
- return CMD_ARGC_();
-}
+void Regamedll_ChangeString_api(char *&dest, const char *source)
+{
+ size_t len = Q_strlen(source);
+ if (dest == nullptr || Q_strlen(dest) != len) {
+ delete [] dest;
+ dest = new char [len + 1];
+ }
-const char *EXT_FUNC Cmd_Argv_api(int i) {
- return CMD_ARGV_(i);
+ Q_strcpy(dest, source);
}
CGrenade *PlantBomb_api(entvars_t *pevOwner, Vector &vecStart, Vector &vecVelocity) {
@@ -51,27 +54,31 @@ void SpawnRandomGibs_api(entvars_t *pevVictim, int cGibs, int human) {
}
ReGameFuncs_t g_ReGameApiFuncs = {
- &CREATE_NAMED_ENTITY,
+ CREATE_NAMED_ENTITY,
- &Regamedll_ChangeString_api,
+ Regamedll_ChangeString_api,
- &RadiusDamage_api,
- &ClearMultiDamage_api,
- &ApplyMultiDamage_api,
- &AddMultiDamage_api,
+ RadiusDamage,
+ ClearMultiDamage,
+ ApplyMultiDamage,
+ AddMultiDamage,
- &UTIL_FindEntityByString,
+ UTIL_FindEntityByString,
- &AddEntityHashValue,
- &RemoveEntityHashValue,
+ AddEntityHashValue,
+ RemoveEntityHashValue,
- Cmd_Argc_api,
- Cmd_Argv_api,
+ CMD_ARGC_,
+ CMD_ARGV_,
PlantBomb_api,
SpawnHeadGib_api,
- SpawnRandomGibs_api
+ SpawnRandomGibs_api,
+
+ UTIL_RestartOther,
+ UTIL_ResetEntities,
+ UTIL_RemoveOther,
};
GAMEHOOK_REGISTRY(CBasePlayer_Spawn);
@@ -204,6 +211,9 @@ GAMEHOOK_REGISTRY(CBasePlayer_Pain);
GAMEHOOK_REGISTRY(CBasePlayer_DeathSound);
GAMEHOOK_REGISTRY(CBasePlayer_JoiningThink);
+GAMEHOOK_REGISTRY(FreeGameRules);
+GAMEHOOK_REGISTRY(PM_LadderMove);
+
int CReGameApi::GetMajorVersion() {
return REGAMEDLL_API_VERSION_MAJOR;
}
@@ -265,35 +275,4 @@ bool CReGameApi::BGetIGameRules(const char *pchVersion) const
return false;
}
-EXT_FUNC void Regamedll_ChangeString_api(char *&dest, const char *source)
-{
- size_t len = Q_strlen(source);
- if (dest == nullptr || Q_strlen(dest) != len) {
- delete [] dest;
- dest = new char [len + 1];
- }
-
- Q_strcpy(dest, source);
-}
-
-EXT_FUNC void RadiusDamage_api(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType)
-{
- RadiusDamage(vecSrc, pevInflictor, pevAttacker, flDamage, flRadius, iClassIgnore, bitsDamageType);
-}
-
-EXT_FUNC void ClearMultiDamage_api()
-{
- ClearMultiDamage();
-}
-
-EXT_FUNC void ApplyMultiDamage_api(entvars_t *pevInflictor, entvars_t *pevAttacker)
-{
- ApplyMultiDamage(pevInflictor, pevAttacker);
-}
-
-EXT_FUNC void AddMultiDamage_api(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType)
-{
- AddMultiDamage(pevInflictor, pEntity, flDamage, bitsDamageType);
-}
-
EXPOSE_SINGLE_INTERFACE(CReGameApi, IReGameApi, VRE_GAMEDLL_API_VERSION);
diff --git a/regamedll/dlls/API/CAPI_Impl.h b/regamedll/dlls/API/CAPI_Impl.h
index 1be3dd232..80e524975 100644
--- a/regamedll/dlls/API/CAPI_Impl.h
+++ b/regamedll/dlls/API/CAPI_Impl.h
@@ -641,6 +641,14 @@ typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBase
typedef IHookChainClassImpl CReGameHook_CBasePlayer_JoiningThink;
typedef IHookChainRegistryClassImpl CReGameHookRegistry_CBasePlayer_JoiningThink;
+// FreeGameRules hook
+typedef IHookChainImpl CReGameHook_FreeGameRules;
+typedef IHookChainRegistryImpl CReGameHookRegistry_FreeGameRules;
+
+// PM_LadderMove hook
+typedef IHookChainImpl CReGameHook_PM_LadderMove;
+typedef IHookChainRegistryImpl CReGameHookRegistry_PM_LadderMove;
+
class CReGameHookchains: public IReGameHookchains {
public:
// CBasePlayer virtual
@@ -774,6 +782,9 @@ class CReGameHookchains: public IReGameHookchains {
CReGameHookRegistry_CBasePlayer_DeathSound m_CBasePlayer_DeathSound;
CReGameHookRegistry_CBasePlayer_JoiningThink m_CBasePlayer_JoiningThink;
+ CReGameHookRegistry_FreeGameRules m_FreeGameRules;
+ CReGameHookRegistry_PM_LadderMove m_PM_LadderMove;
+
public:
virtual IReGameHookRegistry_CBasePlayer_Spawn *CBasePlayer_Spawn();
virtual IReGameHookRegistry_CBasePlayer_Precache *CBasePlayer_Precache();
@@ -904,10 +915,13 @@ class CReGameHookchains: public IReGameHookchains {
virtual IReGameHookRegistry_CBasePlayer_Pain *CBasePlayer_Pain();
virtual IReGameHookRegistry_CBasePlayer_DeathSound *CBasePlayer_DeathSound();
virtual IReGameHookRegistry_CBasePlayer_JoiningThink *CBasePlayer_JoiningThink();
+
+ virtual IReGameHookRegistry_FreeGameRules *FreeGameRules();
+ virtual IReGameHookRegistry_PM_LadderMove *PM_LadderMove();
};
-extern CReGameHookchains g_ReGameHookchains;
-extern ReGameFuncs_t g_ReGameApiFuncs;
+C_DLLEXPORT CReGameHookchains g_ReGameHookchains;
+C_DLLEXPORT ReGameFuncs_t g_ReGameApiFuncs;
class CReGameApi: public IReGameApi {
public:
@@ -930,10 +944,3 @@ class CReGameApi: public IReGameApi {
EXT_FUNC virtual bool BGetICSEntity(const char *pchVersion) const;
EXT_FUNC virtual bool BGetIGameRules(const char *pchVersion) const;
};
-
-void Regamedll_ChangeString_api(char *&dest, const char *source);
-void RadiusDamage_api(Vector vecSrc, entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, float flRadius, int iClassIgnore, int bitsDamageType);
-
-void ClearMultiDamage_api();
-void ApplyMultiDamage_api(entvars_t *pevInflictor, entvars_t *pevAttacker);
-void AddMultiDamage_api(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType);
diff --git a/regamedll/dlls/API/CSPlayer.cpp b/regamedll/dlls/API/CSPlayer.cpp
index 6b11725fe..50ec3478a 100644
--- a/regamedll/dlls/API/CSPlayer.cpp
+++ b/regamedll/dlls/API/CSPlayer.cpp
@@ -43,6 +43,11 @@ EXT_FUNC bool CCSPlayer::JoinTeam(TeamName team)
pPlayer->pev->deadflag = DEAD_DEAD;
pPlayer->pev->health = 0;
+ // Drop the C4 when we move toward spectator!
+ if(pPlayer->m_bHasC4)
+ {
+ pPlayer->DropPlayerItem("weapon_c4");
+ }
pPlayer->RemoveAllItems(TRUE);
pPlayer->m_bHasC4 = false;
@@ -58,7 +63,7 @@ EXT_FUNC bool CCSPlayer::JoinTeam(TeamName team)
pPlayer->StartObserver(pentSpawnSpot->v.origin, pentSpawnSpot->v.angles);
// do we have fadetoblack on? (need to fade their screen back in)
- if (fadetoblack.value)
+ if (fadetoblack.value == FADETOBLACK_STAY)
{
UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 0.001, 0, 0, FFADE_IN);
}
@@ -112,8 +117,10 @@ EXT_FUNC bool CCSPlayer::JoinTeam(TeamName team)
if (pPlayer->pev->deadflag == DEAD_NO)
{
- ClientKill(pPlayer->edict());
- pPlayer->pev->frags++;
+ if (pPlayer->Kill())
+ {
+ pPlayer->pev->frags++;
+ }
}
MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo);
@@ -200,7 +207,6 @@ EXT_FUNC bool CCSPlayer::RemovePlayerItemEx(const char* pszItemName, bool bRemov
return true;
}
-
else if (FStrEq(pszItemName, "weapon_shield"))
{
return RemoveShield();
@@ -209,15 +215,20 @@ EXT_FUNC bool CCSPlayer::RemovePlayerItemEx(const char* pszItemName, bool bRemov
auto pItem = GetItemByName(pszItemName);
if (pItem)
{
- if (FClassnameIs(pItem->pev, "weapon_c4")) {
- pPlayer->m_bHasC4 = false;
- pPlayer->pev->body = 0;
- pPlayer->SetBombIcon(FALSE);
- pPlayer->SetProgressBarTime(0);
- }
-
if (pItem->IsWeapon())
{
+ // These weapons have a unique type of ammo that is used only by them
+ // If a weapon is removed, its ammo is also reduced, unless the ammo can be used by another weapon
+ if (!bRemoveAmmo && (IsGrenadeWeapon(pItem->m_iId) || pItem->m_iId == WEAPON_C4))
+ {
+ if (pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()] > 0)
+ pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()]--;
+
+ // Hold the weapon until it runs out of ammo
+ if (pPlayer->m_rgAmmo[pItem->PrimaryAmmoIndex()] > 0)
+ return true; // ammo was reduced, this will be considered a successful result
+ }
+
if (pItem == pPlayer->m_pActiveItem) {
((CBasePlayerWeapon *)pItem)->RetireWeapon();
}
@@ -227,7 +238,15 @@ EXT_FUNC bool CCSPlayer::RemovePlayerItemEx(const char* pszItemName, bool bRemov
}
}
- if (pPlayer->RemovePlayerItem(pItem)) {
+ if (pPlayer->RemovePlayerItem(pItem))
+ {
+ if (FClassnameIs(pItem->pev, "weapon_c4")) {
+ pPlayer->m_bHasC4 = false;
+ pPlayer->pev->body = 0;
+ pPlayer->SetBombIcon(FALSE);
+ pPlayer->SetProgressBarTime(0);
+ }
+
pPlayer->pev->weapons &= ~(1 << pItem->m_iId);
// No more weapon
if ((pPlayer->pev->weapons & ~(1 << WEAPON_SUIT)) == 0) {
@@ -303,14 +322,14 @@ EXT_FUNC void CCSPlayer::GiveShield(bool bDeploy)
BasePlayer()->GiveShield(bDeploy);
}
-EXT_FUNC void CCSPlayer::DropShield(bool bDeploy)
+EXT_FUNC CBaseEntity *CCSPlayer::DropShield(bool bDeploy)
{
- BasePlayer()->DropShield(bDeploy);
+ return BasePlayer()->DropShield(bDeploy);
}
-EXT_FUNC void CCSPlayer::DropPlayerItem(const char *pszItemName)
+EXT_FUNC CBaseEntity *CCSPlayer::DropPlayerItem(const char *pszItemName)
{
- BasePlayer()->DropPlayerItem(pszItemName);
+ return BasePlayer()->DropPlayerItem(pszItemName);
}
EXT_FUNC bool CCSPlayer::RemoveShield()
@@ -514,6 +533,21 @@ EXT_FUNC bool CCSPlayer::HintMessageEx(const char *pMessage, float duration, boo
return BasePlayer()->HintMessageEx(pMessage, duration, bDisplayIfPlayerDead, bOverride);
}
+EXT_FUNC void CCSPlayer::Reset()
+{
+ BasePlayer()->Reset();
+}
+
+EXT_FUNC void CCSPlayer::OnSpawnEquip(bool addDefault, bool equipGame)
+{
+ BasePlayer()->OnSpawnEquip(addDefault, equipGame);
+}
+
+EXT_FUNC void CCSPlayer::SetScoreboardAttributes(CBasePlayer *destination)
+{
+ BasePlayer()->SetScoreboardAttributes(destination);
+}
+
EXT_FUNC bool CCSPlayer::CheckActivityInGame()
{
const CBasePlayer* pPlayer = BasePlayer();
@@ -526,13 +560,13 @@ EXT_FUNC bool CCSPlayer::CheckActivityInGame()
return (fabs(deltaYaw) >= 0.1f && fabs(deltaPitch) >= 0.1f);
}
-void CCSPlayer::Reset()
+void CCSPlayer::ResetVars()
{
m_szModel[0] = '\0';
m_bForceShowMenu = false;
- m_flRespawnPending =
- m_flSpawnProtectionEndTime = 0.0f;
+ m_flRespawnPending = 0.0f;
+ m_flSpawnProtectionEndTime = 0.0f;
m_vecOldvAngle = g_vecZero;
m_iWeaponInfiniteAmmo = 0;
@@ -541,6 +575,8 @@ void CCSPlayer::Reset()
m_bGameForcingRespawn = false;
m_bAutoBunnyHopping = false;
m_bMegaBunnyJumping = false;
+ m_bPlantC4Anywhere = false;
+ m_bSpawnProtectionEffects = false;
}
void CCSPlayer::OnSpawn()
diff --git a/regamedll/dlls/animating.cpp b/regamedll/dlls/animating.cpp
index 8e7d84334..9e104f22e 100644
--- a/regamedll/dlls/animating.cpp
+++ b/regamedll/dlls/animating.cpp
@@ -179,6 +179,11 @@ NOXREF int CBaseAnimating::GetBodygroup(int iGroup)
return ::GetBodygroup(GET_MODEL_PTR(ENT(pev)), pev, iGroup);
}
+float CBaseAnimating::GetSequenceDuration() const
+{
+ return ::GetSequenceDuration(GET_MODEL_PTR(ENT(pev)), pev);
+}
+
int CBaseAnimating::ExtractBbox(int sequence, float *mins, float *maxs)
{
return ::ExtractBbox(GET_MODEL_PTR(ENT(pev)), sequence, mins, maxs);
diff --git a/regamedll/dlls/animation.cpp b/regamedll/dlls/animation.cpp
index 83c0bd403..7018396aa 100644
--- a/regamedll/dlls/animation.cpp
+++ b/regamedll/dlls/animation.cpp
@@ -246,6 +246,21 @@ void GetSequenceInfo(void *pmodel, entvars_t *pev, float *pflFrameRate, float *p
*pflGroundSpeed = *pflGroundSpeed * pseqdesc->fps / (pseqdesc->numframes - 1);
}
+float GetSequenceDuration(void *pmodel, entvars_t *pev)
+{
+ studiohdr_t *pstudiohdr = (studiohdr_t *)pmodel;
+ if (!pstudiohdr)
+ return 0; // model ptr is not valid
+
+ if (pev->sequence < 0 || pev->sequence >= pstudiohdr->numseq)
+ return 0; // sequence is not valid
+
+ // get current sequence time
+ mstudioseqdesc_t *pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + int(pev->sequence);
+
+ return pseqdesc->numframes / pseqdesc->fps;
+}
+
int GetSequenceFlags(void *pmodel, entvars_t *pev)
{
studiohdr_t *pstudiohdr = (studiohdr_t *)pmodel;
diff --git a/regamedll/dlls/animation.h b/regamedll/dlls/animation.h
index 54af21a8c..7889a140b 100644
--- a/regamedll/dlls/animation.h
+++ b/regamedll/dlls/animation.h
@@ -42,6 +42,7 @@ 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);
+float GetSequenceDuration(void *pmodel, entvars_t *pev);
int GetSequenceFlags(void *pmodel, entvars_t *pev);
float SetController(void *pmodel, entvars_t *pev, int iController, float flValue);
float SetBlending(void *pmodel, entvars_t *pev, int iBlender, float flValue);
diff --git a/regamedll/dlls/basemonster.h b/regamedll/dlls/basemonster.h
index dbdc22c66..63f8d8d41 100644
--- a/regamedll/dlls/basemonster.h
+++ b/regamedll/dlls/basemonster.h
@@ -34,7 +34,7 @@
enum
{
- ITBD_PARALLYZE = 0,
+ ITBD_PARALYZE = 0,
ITBD_NERVE_GAS,
ITBD_POISON,
ITBD_RADIATION,
diff --git a/regamedll/dlls/bot/cs_bot_manager.cpp b/regamedll/dlls/bot/cs_bot_manager.cpp
index 786a3f08f..4a6269ff6 100644
--- a/regamedll/dlls/bot/cs_bot_manager.cpp
+++ b/regamedll/dlls/bot/cs_bot_manager.cpp
@@ -78,7 +78,7 @@ CCSBotManager::CCSBotManager()
char *dataPointer = (char *)LOAD_FILE_FOR_ME((char *)filename, &dataLength);
if (!dataPointer)
{
- TheBotProfiles->Init("BotProfile.db");
+ TheBotProfiles->Init(cv_bot_profile_db.string);
}
else
{
@@ -410,11 +410,7 @@ void CCSBotManager::ServerCommand(const char *pcmd)
{
if (killThemAll || FStrEq(name, msg))
{
-#ifdef REGAMEDLL_FIXES
- ClientKill(pPlayer->edict());
-#else
- pPlayer->TakeDamage(pPlayer->pev, pPlayer->pev, 9999.9f, DMG_CRUSH);
-#endif
+ pPlayer->Kill();
}
}
}
diff --git a/regamedll/dlls/career_tasks.cpp b/regamedll/dlls/career_tasks.cpp
index 0b0c45a56..57d2bd707 100644
--- a/regamedll/dlls/career_tasks.cpp
+++ b/regamedll/dlls/career_tasks.cpp
@@ -136,10 +136,14 @@ void CCareerTask::OnWeaponKill(int weaponId, int weaponClassId, bool headshot, b
if (!pHostage->IsAlive())
continue;
+#ifndef REGAMEDLL_FIXES
if (!pHostage->IsFollowingSomeone())
continue;
if (pHostage->m_target == pVictim)
+#else
+ if (pHostage->IsFollowing(pVictim))
+#endif
hostagesCount++;
}
@@ -212,10 +216,14 @@ void CCareerTask::OnEvent(GameEventType event, CBasePlayer *pVictim, CBasePlayer
if (!pHostage->IsAlive())
continue;
+#ifndef REGAMEDLL_FIXES
if (!pHostage->IsFollowingSomeone())
continue;
if (pHostage->m_target == pAttacker)
+#else
+ if (pHostage->IsFollowing(pAttacker))
+#endif
hostagesCount++;
}
diff --git a/regamedll/dlls/cbase.cpp b/regamedll/dlls/cbase.cpp
index 9bf5abef0..b1cbe149e 100644
--- a/regamedll/dlls/cbase.cpp
+++ b/regamedll/dlls/cbase.cpp
@@ -1039,6 +1039,9 @@ void CBaseEntity::__API_HOOK(FireBullets)(ULONG cShots, VectorRef vecSrc, Vector
vecDir = vecDirShooting + x * vecSpread.x * vecRight + y * vecSpread.y * vecUp;
vecEnd = vecSrc + vecDir * flDistance;
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_BULLET;
+#endif
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &tr);
tracer = 0;
@@ -1182,6 +1185,9 @@ void CBaseEntity::__API_HOOK(FireBuckshots)(ULONG cShots, VectorRef vecSrc, Vect
vecDir = vecDirShooting + x * vecSpread.x * vecRight + y * vecSpread.y * vecUp;
vecEnd = vecSrc + vecDir * flDistance;
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_BULLET;
+#endif
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &tr);
tracer = 0;
@@ -1337,6 +1343,10 @@ VectorRef CBaseEntity::__API_HOOK(FireBullets3)(VectorRef vecSrc, VectorRef vecD
while (iPenetration != 0)
{
ClearMultiDamage();
+
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_BULLET;
+#endif
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, ENT(pev), &tr);
if (TheBots && tr.flFraction != 1.0f)
diff --git a/regamedll/dlls/cbase.h b/regamedll/dlls/cbase.h
index e0ae20c22..146245c76 100644
--- a/regamedll/dlls/cbase.h
+++ b/regamedll/dlls/cbase.h
@@ -369,6 +369,7 @@ class CBaseAnimating: public CBaseDelay {
float SetBoneController(int iController, float flValue = 0.0f);
void InitBoneControllers();
+ float GetSequenceDuration() const;
float SetBlending(int iBlender, float flValue);
void GetBonePosition(int iBone, Vector &origin, Vector &angles);
void GetAutomovement(Vector &origin, Vector &angles, float flInterval = 0.1f);
@@ -585,9 +586,9 @@ T *GetClassPtr(T *a)
a->pev = pev;
#ifdef REGAMEDLL_API
- a->OnCreate();
a->m_pEntity = new W();
a->m_pEntity->m_pContainingEntity = a;
+ a->OnCreate();
#endif
}
diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp
index 5ddf63adb..646270c4e 100644
--- a/regamedll/dlls/client.cpp
+++ b/regamedll/dlls/client.cpp
@@ -375,29 +375,13 @@ void EXT_FUNC ClientKill(edict_t *pEntity)
entvars_t *pev = &pEntity->v;
CBasePlayer *pPlayer = CBasePlayer::Instance(pev);
- if (pPlayer->GetObserverMode() != OBS_NONE)
- return;
-
- if (pPlayer->m_iJoiningState != JOINED)
- return;
-
// prevent suiciding too often
if (pPlayer->m_fNextSuicideTime > gpGlobals->time)
return;
- pPlayer->m_LastHitGroup = HITGROUP_GENERIC;
-
// don't let them suicide for 1 second after suiciding
pPlayer->m_fNextSuicideTime = gpGlobals->time + 1.0f;
-
- // have the player kill themself
- pEntity->v.health = 0;
- pPlayer->Killed(pev, GIB_NEVER);
-
- if (CSGameRules()->m_pVIP == pPlayer)
- {
- CSGameRules()->m_iConsecutiveVIP = 10;
- }
+ pPlayer->Kill();
}
LINK_HOOK_VOID_CHAIN(ShowMenu, (CBasePlayer *pPlayer, int bitsValidSlots, int nDisplayTime, BOOL fNeedMore, char *pszText), pPlayer, bitsValidSlots, nDisplayTime, fNeedMore, pszText)
@@ -743,7 +727,7 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
}
#ifdef REGAMEDLL_API
- pPlayer->CSPlayer()->Reset();
+ pPlayer->CSPlayer()->ResetVars();
#endif
UTIL_ClientPrintAll(HUD_PRINTNOTIFY, "#Game_connected", (sName[0] != '\0') ? sName : "");
@@ -753,7 +737,11 @@ void Host_Say(edict_t *pEntity, BOOL teamonly)
{
int j;
char *p;
+#ifdef REGAMEDLL_FIXES
+ char text[140];
+#else
char text[128];
+#endif
char szTemp[256];
const char *cpSay = "say";
const char *cpSayTeam = "say_team";
@@ -1856,10 +1844,11 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *pPlayer, int slot)
{
if (pPlayer->m_iTeam != UNASSIGNED && pPlayer->pev->deadflag == DEAD_NO)
{
- ClientKill(pPlayer->edict());
-
- // add 1 to frags to balance out the 1 subtracted for killing yourself
- pPlayer->pev->frags++;
+ if (pPlayer->Kill())
+ {
+ // add 1 to frags to balance out the 1 subtracted for killing yourself
+ pPlayer->pev->frags++;
+ }
}
pPlayer->RemoveAllItems(TRUE);
@@ -1926,7 +1915,7 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *pPlayer, int slot)
MESSAGE_END();
#endif
// do we have fadetoblack on? (need to fade their screen back in)
- if (fadetoblack.value)
+ if (fadetoblack.value == FADETOBLACK_STAY)
{
UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 0.001, 0, 0, FFADE_IN);
}
@@ -2087,10 +2076,10 @@ BOOL EXT_FUNC __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *pPlayer, int slot)
pPlayer->m_iMenu = Menu_ChooseAppearance;
// Show the appropriate Choose Appearance menu
- // This must come before ClientKill() for CheckWinConditions() to function properly
+ // This must come before pPlayer->Kill() for CheckWinConditions() to function properly
if (pPlayer->pev->deadflag == DEAD_NO)
{
- ClientKill(pPlayer->edict());
+ pPlayer->Kill();
}
}
diff --git a/regamedll/dlls/combat.cpp b/regamedll/dlls/combat.cpp
index f5ec1ce15..390c8d613 100644
--- a/regamedll/dlls/combat.cpp
+++ b/regamedll/dlls/combat.cpp
@@ -4,7 +4,7 @@ void PlayerBlind(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAt
{
UTIL_ScreenFade(pPlayer, color, fadeTime, fadeHold, alpha, 0);
- if (!fadetoblack.value)
+ if (fadetoblack.value != FADETOBLACK_STAY)
{
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
@@ -26,6 +26,9 @@ void PlayerBlind(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAt
void RadiusFlash_TraceLine_hook(CBasePlayer *pPlayer, entvars_t *pevInflictor, entvars_t *pevAttacker, Vector &vecSrc, Vector &vecSpot, TraceResult *tr)
{
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_FLASH;
+#endif
UTIL_TraceLine(vecSrc, vecSpot, dont_ignore_monsters, ENT(pevInflictor), tr);
}
diff --git a/regamedll/dlls/effects.cpp b/regamedll/dlls/effects.cpp
index 16cc2e6ab..f934edd4b 100644
--- a/regamedll/dlls/effects.cpp
+++ b/regamedll/dlls/effects.cpp
@@ -1737,10 +1737,12 @@ Vector CBlood::BloodPosition(CBaseEntity *pActivator)
void CBlood::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
{
+ const Vector direction = Direction();
+
if (pev->spawnflags & SF_BLOOD_STREAM)
- UTIL_BloodStream(BloodPosition(pActivator), Direction(), (Color() == BLOOD_COLOR_RED) ? 70 : Color(), int(BloodAmount()));
+ UTIL_BloodStream(BloodPosition(pActivator), direction, (Color() == BLOOD_COLOR_RED) ? 70 : Color(), int(BloodAmount()));
else
- UTIL_BloodDrips(BloodPosition(pActivator), Direction(), Color(), int(BloodAmount()));
+ UTIL_BloodDrips(BloodPosition(pActivator), Color(), int(BloodAmount()));
if (pev->spawnflags & SF_BLOOD_DECAL)
{
diff --git a/regamedll/dlls/func_tank.cpp b/regamedll/dlls/func_tank.cpp
index 1ca0e966e..80913ffec 100644
--- a/regamedll/dlls/func_tank.cpp
+++ b/regamedll/dlls/func_tank.cpp
@@ -208,8 +208,12 @@ BOOL CFuncTank::OnControls(entvars_t *pevTest)
if (!(pev->spawnflags & SF_TANK_CANCONTROL))
return FALSE;
+#ifdef REGAMEDLL_FIXES
+ if((pev->origin - pevTest->origin).Length() < (m_vecControllerUsePos.x + m_vecControllerUsePos.y))
+#else
Vector offset = pevTest->origin - pev->origin;
if ((m_vecControllerUsePos - pevTest->origin).Length() < 30.0f)
+#endif
{
return TRUE;
}
@@ -235,14 +239,32 @@ BOOL CFuncTank::StartControl(CBasePlayer *pController)
m_pController = pController;
- if (m_pController->m_pActiveItem)
+ CBasePlayerWeapon *pActiveWeapon = static_cast(m_pController->m_pActiveItem);
+
+ if (pActiveWeapon)
{
- m_pController->m_pActiveItem->Holster();
- m_pController->pev->weaponmodel = 0;
+#ifdef REGAMEDLL_FIXES
+ // Fix problem when we holster a granada before its "RetireWeapon" code call, to avoid having no new weapon/HUD selection when we stop controlling the tank.
+ // This happens when we throw our last granada and we quickly use the tank,
+ // the "GetNextBestWeapon" code inside "RetireWeapon" will not be called, since "m_flReleaseThrow" will be reset to -1.
+ if (IsGrenadeWeapon(pActiveWeapon->m_iId)
+ && m_pController->m_rgAmmo[pActiveWeapon->m_iPrimaryAmmoType] <= 0
+ && (m_pController->pev->weapons & ~(1 << WEAPON_SUIT | 1 << pActiveWeapon->m_iId)))
+ {
+ pActiveWeapon->RetireWeapon();
+ }
+ else
+#endif
+ {
+ pActiveWeapon->Holster();
+ }
+#ifndef REGAMEDLL_FIXES
+ m_pController->pev->weaponmodel = 0;
#ifdef BUILD_LATEST_FIXES
m_pController->pev->viewmodel = 0;
#endif
+#endif
#ifdef REGAMEDLL_FIXES
// if (m_pController->m_iFOV != DEFAULT_FOV)
@@ -254,7 +276,12 @@ BOOL CFuncTank::StartControl(CBasePlayer *pController)
}
m_pController->m_iHideHUD |= HIDEHUD_WEAPONS;
+#ifdef REGAMEDLL_FIXES
+ m_vecControllerUsePos.x = (pev->origin - m_pController->pev->origin).Length();
+ m_vecControllerUsePos.y = MAX_PLAYER_USE_TANK_RADIUS;
+#else
m_vecControllerUsePos = m_pController->pev->origin;
+#endif
pev->nextthink = pev->ltime + 0.1f;
@@ -876,6 +903,25 @@ void CFuncTankControls::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_T
if (m_pTank)
{
m_pTank->Use(pActivator, pCaller, useType, value);
+
+#ifdef REGAMEDLL_FIXES
+ m_pTank->m_vecControllerUsePos.x = (m_pTank->pev->origin - pActivator->pev->origin).Length();
+
+ // Extended distance setting, up to "MAX_PLAYER_USE_TANK_RADIUS" units or more depending on how close we were in "PlayerUse", or if we did not used it.
+ if(pActivator && pActivator->IsPlayer() && (((CBasePlayer *)pActivator)->m_afButtonPressed & IN_USE))
+ {
+ m_pTank->m_vecControllerUsePos.y = MAX_PLAYER_USE_RADIUS - (this->Center() - pActivator->pev->origin).Length();
+
+ if(m_pTank->m_vecControllerUsePos.y < 0) // Since radius function can get a higher range, so fix it to avoid "StartControl" followed by "StopControl" on a next think!
+ {
+ m_pTank->m_vecControllerUsePos.y = -m_pTank->m_vecControllerUsePos.y;
+ }
+ }
+ else
+ {
+ m_pTank->m_vecControllerUsePos.y = MAX_PLAYER_USE_TANK_RADIUS;
+ }
+#endif
}
// if this fails, most likely means save/restore hasn't worked properly
diff --git a/regamedll/dlls/func_tank.h b/regamedll/dlls/func_tank.h
index d30acdb7a..d93e6b330 100644
--- a/regamedll/dlls/func_tank.h
+++ b/regamedll/dlls/func_tank.h
@@ -105,6 +105,10 @@ class CFuncTank: public CBaseEntity
static Vector m_TankSpread[];
protected:
+#ifdef REGAMEDLL_FIXES
+ friend class CFuncTankControls;
+#endif
+
CBasePlayer *m_pController;
float m_flNextAttack;
Vector m_vecControllerUsePos;
diff --git a/regamedll/dlls/game.cpp b/regamedll/dlls/game.cpp
index 192e254e0..428d1211b 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_zmax = nullptr;
cvar_t displaysoundlist = { "displaysoundlist", "0", 0, 0.0f, nullptr };
cvar_t timelimit = { "mp_timelimit", "0", FCVAR_SERVER, 0.0f, nullptr };
@@ -109,6 +110,8 @@ cvar_t maxmoney = { "mp_maxmoney", "16000", FCVAR_SERVER, 0.0f, nul
cvar_t round_infinite = { "mp_round_infinite", "0", FCVAR_SERVER, 0.0f, nullptr };
cvar_t hegrenade_penetration = { "mp_hegrenade_penetration", "0", 0, 0.0f, nullptr };
cvar_t nadedrops = { "mp_nadedrops", "0", 0, 0.0f, nullptr };
+cvar_t weapondrop = { "mp_weapondrop", "1", 0, 1.0f, nullptr };
+cvar_t ammodrop = { "mp_ammodrop", "1", 0, 1.0f, nullptr };
cvar_t roundrespawn_time = { "mp_roundrespawn_time", "20", 0, 20.0f, nullptr };
cvar_t auto_reload_weapons = { "mp_auto_reload_weapons", "0", 0, 0.0f, nullptr };
cvar_t refill_bpammo_weapons = { "mp_refill_bpammo_weapons", "0", 0, 0.0f, nullptr }; // Useful for mods like DeathMatch, GunGame, ZombieMod etc
@@ -163,6 +166,12 @@ cvar_t sv_autobunnyhopping = { "sv_autobunnyhopping", "0", 0, 0.0f
cvar_t sv_enablebunnyhopping = { "sv_enablebunnyhopping", "0", 0, 0.0f, nullptr };
cvar_t plant_c4_anywhere = { "mp_plant_c4_anywhere", "0", 0, 0.0f, nullptr };
cvar_t give_c4_frags = { "mp_give_c4_frags", "3", 0, 3.0f, nullptr };
+cvar_t hostages_rescued_ratio = { "mp_hostages_rescued_ratio", "1.0", 0, 1.0f, nullptr };
+cvar_t legacy_vehicle_block = { "mp_legacy_vehicle_block", "1", 0, 0.0f, nullptr };
+cvar_t dying_time = { "mp_dying_time", "3.0", 0, 3.0f, nullptr };
+
+// Note: Just for my plugins & cie.
+cvar_t game_version_personnal = { "game_version_personnal", "1.3.0-public-AMXModDev", FCVAR_SERVER, 0.0f, nullptr };
void GameDLL_Version_f()
{
@@ -225,6 +234,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_zmax = CVAR_GET_POINTER("sv_zmax");
CVAR_REGISTER(&displaysoundlist);
CVAR_REGISTER(&timelimit);
@@ -347,6 +357,8 @@ void EXT_FUNC GameDLLInit()
CVAR_REGISTER(&round_infinite);
CVAR_REGISTER(&hegrenade_penetration);
CVAR_REGISTER(&nadedrops);
+ CVAR_REGISTER(&weapondrop);
+ CVAR_REGISTER(&ammodrop);
CVAR_REGISTER(&roundrespawn_time);
CVAR_REGISTER(&auto_reload_weapons);
CVAR_REGISTER(&refill_bpammo_weapons);
@@ -405,6 +417,11 @@ void EXT_FUNC GameDLLInit()
CVAR_REGISTER(&sv_enablebunnyhopping);
CVAR_REGISTER(&plant_c4_anywhere);
CVAR_REGISTER(&give_c4_frags);
+ CVAR_REGISTER(&hostages_rescued_ratio);
+ CVAR_REGISTER(&legacy_vehicle_block);
+ CVAR_REGISTER(&dying_time);
+
+ CVAR_REGISTER(&game_version_personnal);
// print version
CONSOLE_ECHO("ReGameDLL version: " APP_VERSION "\n");
diff --git a/regamedll/dlls/game.h b/regamedll/dlls/game.h
index 191211e0f..8705ad9cf 100644
--- a/regamedll/dlls/game.h
+++ b/regamedll/dlls/game.h
@@ -48,6 +48,7 @@ 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_psv_zmax;
extern cvar_t *g_footsteps;
extern cvar_t displaysoundlist;
@@ -138,6 +139,8 @@ extern cvar_t maxmoney;
extern cvar_t round_infinite;
extern cvar_t hegrenade_penetration;
extern cvar_t nadedrops;
+extern cvar_t weapondrop;
+extern cvar_t ammodrop;
extern cvar_t roundrespawn_time;
extern cvar_t auto_reload_weapons;
extern cvar_t refill_bpammo_weapons;
@@ -189,6 +192,11 @@ extern cvar_t sv_autobunnyhopping;
extern cvar_t sv_enablebunnyhopping;
extern cvar_t plant_c4_anywhere;
extern cvar_t give_c4_frags;
+extern cvar_t hostages_rescued_ratio;
+extern cvar_t legacy_vehicle_block;
+extern cvar_t dying_time;
+
+extern cvar_t game_version_personnal;
#endif
diff --git a/regamedll/dlls/gamerules.cpp b/regamedll/dlls/gamerules.cpp
index d31e6b565..5ec17fbc0 100644
--- a/regamedll/dlls/gamerules.cpp
+++ b/regamedll/dlls/gamerules.cpp
@@ -127,6 +127,10 @@ void CGameRules::RefreshSkillData()
gSkillData.batteryCapacity = 15;
gSkillData.healthchargerCapacity = 50;
gSkillData.healthkitCapacity = 15;
+
+ // Extended for own purpose.
+ gSkillData.flFlashLightDrainTime = FLASH_DRAIN_TIME;
+ gSkillData.flFlashLightChargeTime = FLASH_CHARGE_TIME;
}
LINK_HOOK_CHAIN2(CGameRules *, InstallGameRules)
@@ -141,3 +145,13 @@ CGameRules *EXT_FUNC __API_HOOK(InstallGameRules)()
return new CHalfLifeMultiplay;
}
+
+LINK_HOOK_VOID_CHAIN(FreeGameRules, (CGameRules **pGameRules), pGameRules)
+
+void EXT_FUNC __API_HOOK(FreeGameRules)(CGameRules **pGameRules)
+{
+ if (!pGameRules || !(*pGameRules))
+ return;
+
+ delete (*pGameRules);
+}
diff --git a/regamedll/dlls/gamerules.h b/regamedll/dlls/gamerules.h
index ed0111a50..aba746ed3 100644
--- a/regamedll/dlls/gamerules.h
+++ b/regamedll/dlls/gamerules.h
@@ -31,21 +31,22 @@
#include "game_shared/voice_gamemgr.h"
#include "cmdhandler.h"
-const int MAX_RULE_BUFFER = 1024;
-const int MAX_VOTE_MAPS = 100;
-const int MAX_VIP_QUEUES = 5;
-const int MAX_MONEY_THRESHOLD = 999999; // allowable money limit in the game that can be drawn on the HUD
-
-const int MAX_MOTD_CHUNK = 60;
-const int MAX_MOTD_LENGTH = 1536; // (MAX_MOTD_CHUNK * 4)
-
-const float ITEM_RESPAWN_TIME = 30.0f;
-const float WEAPON_RESPAWN_TIME = 20.0f;
-const float AMMO_RESPAWN_TIME = 20.0f;
-const float ROUND_RESPAWN_TIME = 20.0f;
-const float ROUND_BEGIN_DELAY = 5.0f; // delay before beginning new round
-const float ITEM_KILL_DELAY = 300.0f;
-const float RADIO_TIMEOUT = 1.5f;
+const int MAX_RULE_BUFFER = 1024;
+const int MAX_VOTE_MAPS = 100;
+const int MAX_VIP_QUEUES = 5;
+const int MAX_MONEY_THRESHOLD = 999999; // allowable money limit in the game that can be drawn on the HUD
+
+const int MAX_MOTD_CHUNK = 60;
+const int MAX_MOTD_LENGTH = 1536; // (MAX_MOTD_CHUNK * 4)
+
+const float ITEM_RESPAWN_TIME = 30.0f;
+const float WEAPON_RESPAWN_TIME = 20.0f;
+const float AMMO_RESPAWN_TIME = 20.0f;
+const float ROUND_RESPAWN_TIME = 20.0f;
+const float ROUND_BEGIN_DELAY = 5.0f; // delay before beginning new round
+const float ITEM_KILL_DELAY = 300.0f;
+const float RADIO_TIMEOUT = 1.5f;
+const float DEATH_ANIMATION_TIME = 3.0f;
const int MAX_INTERMISSION_TIME = 120; // longest the intermission can last, in seconds
@@ -186,6 +187,10 @@ enum
GR_PLR_DROP_AMMO_ALL,
GR_PLR_DROP_AMMO_ACTIVE,
GR_PLR_DROP_AMMO_NO,
+
+#ifdef REGAMEDLL_ADD
+ GR_PLR_DROP_GUN_BEST,
+#endif
};
// custom enum
@@ -202,7 +207,6 @@ enum
SCENARIO_BLOCK_PRISON_ESCAPE_TIME = BIT(8), // flag "i"
SCENARIO_BLOCK_BOMB_TIME = BIT(9), // flag "j"
SCENARIO_BLOCK_HOSTAGE_RESCUE_TIME = BIT(10), // flag "k"
-
};
// Player relationship return codes
@@ -332,6 +336,7 @@ class CGameRules
inline void SetGameOver() { m_bGameOver = true; }
static float GetItemKillDelay();
static float GetRadioTimeout();
+ static float GetDyingTime();
public:
BOOL m_bFreezePeriod; // TRUE at beginning of round, set to FALSE when the period expires
@@ -831,9 +836,11 @@ extern CGameRules DLLEXPORT *g_pGameRules;
#ifdef REGAMEDLL_API
CGameRules *InstallGameRules_OrigFunc();
+void FreeGameRules_OrigFunc(CGameRules **pGameRules);
#endif
CGameRules *InstallGameRules();
+void FreeGameRules(CGameRules **pGameRules);
// Gets us at the CS game rules
inline CHalfLifeMultiplay *CSGameRules()
@@ -915,6 +922,15 @@ inline float CGameRules::GetRadioTimeout()
#endif
}
+inline float CGameRules::GetDyingTime()
+{
+#ifdef REGAMEDLL_ADD
+ return dying_time.value;
+#else
+ return DEATH_ANIMATION_TIME;
+#endif
+}
+
bool IsBotSpeaking();
void SV_Continue_f();
void SV_Tutor_Toggle_f();
diff --git a/regamedll/dlls/gib.cpp b/regamedll/dlls/gib.cpp
index 5b9122d04..069b118d9 100644
--- a/regamedll/dlls/gib.cpp
+++ b/regamedll/dlls/gib.cpp
@@ -5,13 +5,14 @@ LINK_ENTITY_TO_CLASS(gib, CGib, CCSGib)
void CGib::LimitVelocity()
{
float length = pev->velocity.Length();
+ float topspeed = CVAR_GET_FLOAT("sv_maxvelocity") * 0.75f;
- // ceiling at 1500. The gib velocity equation is not bounded properly. Rather than tune it
+ // 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 > 1500.0)
+ if (length > topspeed)
{
- // This should really be sv_maxvelocity * 0.75 or something
- pev->velocity = pev->velocity.Normalize() * 1500;
+ // DONE: This should really be sv_maxvelocity * 0.75 or something
+ pev->velocity = pev->velocity.Normalize() * topspeed;
}
}
diff --git a/regamedll/dlls/h_battery.cpp b/regamedll/dlls/h_battery.cpp
index f46b86057..49a0ee391 100644
--- a/regamedll/dlls/h_battery.cpp
+++ b/regamedll/dlls/h_battery.cpp
@@ -59,6 +59,12 @@ void CRecharge::Spawn()
#ifdef REGAMEDLL_FIXES
void CRecharge::Restart()
{
+ // Stop looping sound.
+ if (m_iOn > 1)
+ STOP_SOUND(ENT(pev), CHAN_STATIC, "items/suitcharge1.wav");
+
+ m_iOn = 0;
+
pev->solid = SOLID_BSP;
pev->movetype = MOVETYPE_PUSH;
@@ -174,6 +180,11 @@ void CRecharge::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useT
void CRecharge::Recharge()
{
+ if(pev->frame == 1.0f && (!CSGameRules() || CSGameRules()->GetRoundElapsedTime() >= 0.20f))
+ {
+ EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/suitchargeok1.wav", 0.85, ATTN_NORM);
+ }
+
int armorValue = (int)gSkillData.suitchargerCapacity;
#ifdef REGAMEDLL_FIXES
if (pev->armorvalue != 0.0f) {
diff --git a/regamedll/dlls/healthkit.cpp b/regamedll/dlls/healthkit.cpp
index 5a49e4832..b87f58022 100644
--- a/regamedll/dlls/healthkit.cpp
+++ b/regamedll/dlls/healthkit.cpp
@@ -5,14 +5,16 @@ LINK_ENTITY_TO_CLASS(item_healthkit, CHealthKit, CCSHealthKit)
void CHealthKit::Spawn()
{
Precache();
- SET_MODEL(ENT(pev), "models/w_medkit.mdl");
-
CItem::Spawn();
}
void CHealthKit::Precache()
{
- PRECACHE_MODEL("models/w_medkit.mdl");
+ if(pev->model.IsNullOrEmpty())
+ {
+ pev->model = ALLOC_STRING("models/w_medkit.mdl");
+ }
+ PRECACHE_MODEL(pev->model);
PRECACHE_SOUND("items/smallmedkit1.wav");
}
@@ -106,6 +108,12 @@ void CWallHealth::Spawn()
#ifdef REGAMEDLL_FIXES
void CWallHealth::Restart()
{
+ // Stop looping sound.
+ if (m_iOn > 1)
+ STOP_SOUND(ENT(pev), CHAN_STATIC, "items/medcharge4.wav");
+
+ m_iOn = 0;
+
pev->solid = SOLID_BSP;
pev->movetype = MOVETYPE_PUSH;
@@ -196,7 +204,10 @@ void CWallHealth::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE us
void CWallHealth::Recharge()
{
- EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", VOL_NORM, ATTN_NORM);
+ if(pev->frame == 1.0f && (!CSGameRules() || CSGameRules()->GetRoundElapsedTime() >= 0.20f))
+ {
+ EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/medshot4.wav", VOL_NORM, ATTN_NORM);
+ }
int healthValue = (int)gSkillData.healthchargerCapacity;
#ifdef REGAMEDLL_FIXES
diff --git a/regamedll/dlls/items.cpp b/regamedll/dlls/items.cpp
index fc67bc57f..f934947eb 100644
--- a/regamedll/dlls/items.cpp
+++ b/regamedll/dlls/items.cpp
@@ -97,13 +97,44 @@ void CItem::Spawn()
UTIL_SetOrigin(pev, pev->origin);
UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16));
+ if(pev->model)
+ {
+ SET_MODEL(ENT(pev), pev->model);
+ }
+
SetTouch(&CItem::ItemTouch);
- if (!DROP_TO_FLOOR(ENT(pev)))
+ if (DROP_TO_FLOOR(ENT(pev)) <= 0)
{
UTIL_Remove(this);
return;
}
+
+ pev->oldorigin = pev->origin;
+}
+
+void CItem::Restart()
+{
+ pev->movetype = MOVETYPE_TOSS;
+ pev->solid = SOLID_TRIGGER;
+
+ if(pev->origin != pev->oldorigin)
+ {
+ UTIL_SetOrigin(pev, pev->oldorigin);
+ UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16));
+
+ if (DROP_TO_FLOOR(ENT(pev)) <= 0)
+ {
+ UTIL_Remove(this);
+ return;
+ }
+ }
+
+ if(pev->effects & EF_NODRAW)
+ {
+ SetThink(&CItem::Materialize);
+ pev->nextthink = gpGlobals->time;
+ }
}
void CItem::ItemTouch(CBaseEntity *pOther)
@@ -149,7 +180,10 @@ void CItem::Materialize()
if (pev->effects & EF_NODRAW)
{
// changing from invisible state to visible.
- EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "items/suitchargeok1.wav", VOL_NORM, ATTN_NORM, 0, 150);
+ if(!CSGameRules() || CSGameRules()->GetRoundElapsedTime() >= 0.10f)
+ {
+ EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "items/suitchargeok1.wav", VOL_NORM, ATTN_NORM, 0, 150);
+ }
pev->effects &= ~EF_NODRAW;
pev->effects |= EF_MUZZLEFLASH;
@@ -161,13 +195,16 @@ void CItem::Materialize()
void CItemSuit::Spawn()
{
Precache();
- SET_MODEL(ENT(pev), "models/w_kevlar.mdl");
CItem::Spawn();
}
void CItemSuit::Precache()
{
- PRECACHE_MODEL("models/w_kevlar.mdl");
+ if(pev->model.IsNullOrEmpty())
+ {
+ pev->model = ALLOC_STRING("models/w_kevlar.mdl");
+ }
+ PRECACHE_MODEL(pev->model);
PRECACHE_SOUND("items/tr_kevlar.wav");
}
@@ -189,13 +226,16 @@ LINK_ENTITY_TO_CLASS(item_suit, CItemSuit, CCSItemSuit)
void CItemBattery::Spawn()
{
Precache();
- SET_MODEL(ENT(pev), "models/w_battery.mdl");
CItem::Spawn();
}
void CItemBattery::Precache()
{
- PRECACHE_MODEL("models/w_battery.mdl");
+ if(pev->model.IsNullOrEmpty())
+ {
+ pev->model = ALLOC_STRING("models/w_battery.mdl");
+ }
+ PRECACHE_MODEL(pev->model);
PRECACHE_SOUND("items/gunpickup2.wav");
}
@@ -251,13 +291,16 @@ LINK_ENTITY_TO_CLASS(item_battery, CItemBattery, CCSItemBattery)
void CItemAntidote::Spawn()
{
Precache();
- SET_MODEL(ENT(pev), "models/w_antidote.mdl");
CItem::Spawn();
}
void CItemAntidote::Precache()
{
- PRECACHE_MODEL("models/w_antidote.mdl");
+ if(pev->model.IsNullOrEmpty())
+ {
+ pev->model = ALLOC_STRING("models/w_antidote.mdl");
+ }
+ PRECACHE_MODEL(pev->model);
}
BOOL CItemAntidote::MyTouch(CBasePlayer *pPlayer)
@@ -278,31 +321,15 @@ LINK_ENTITY_TO_CLASS(item_antidote, CItemAntidote, CCSItemAntidote)
void CItemSecurity::Spawn()
{
Precache();
-
- if (pev->model.IsNullOrEmpty())
- {
- // default model
- SET_MODEL(ENT(pev), "models/w_security.mdl");
- }
- else
- {
- // custom model
- SET_MODEL(ENT(pev), pev->model);
- }
-
CItem::Spawn();
}
void CItemSecurity::Precache()
{
- if (pev->model.IsNullOrEmpty())
+ if(pev->model.IsNullOrEmpty())
{
- // default model
- PRECACHE_MODEL("models/w_security.mdl");
- return;
+ pev->model = ALLOC_STRING("models/w_security.mdl");
}
-
- // custom model
PRECACHE_MODEL(pev->model);
}
@@ -317,13 +344,16 @@ LINK_ENTITY_TO_CLASS(item_security, CItemSecurity, CCSItemSecurity)
void CItemLongJump::Spawn()
{
Precache();
- SET_MODEL(ENT(pev), "models/w_longjump.mdl");
CItem::Spawn();
}
void CItemLongJump::Precache()
{
- PRECACHE_MODEL("models/w_longjump.mdl");
+ if(pev->model.IsNullOrEmpty())
+ {
+ pev->model = ALLOC_STRING("models/w_longjump.mdl");
+ }
+ PRECACHE_MODEL(pev->model);
}
BOOL CItemLongJump::MyTouch(CBasePlayer *pPlayer)
@@ -342,6 +372,8 @@ BOOL CItemLongJump::MyTouch(CBasePlayer *pPlayer)
pPlayer->m_fLongJump = TRUE;
SET_PHYSICS_KEY_VALUE(pPlayer->edict(), "slj", "1");
+ EMIT_SOUND(pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM);
+
MESSAGE_BEGIN(MSG_ONE, gmsgItemPickup, nullptr, pPlayer->pev);
WRITE_STRING(STRING(pev->classname));
MESSAGE_END();
@@ -359,13 +391,16 @@ LINK_ENTITY_TO_CLASS(item_longjump, CItemLongJump, CCSItemLongJump)
void CItemKevlar::Spawn()
{
Precache();
- SET_MODEL(ENT(pev), "models/w_kevlar.mdl");
CItem::Spawn();
}
void CItemKevlar::Precache()
{
- PRECACHE_MODEL("models/w_kevlar.mdl");
+ if(pev->model.IsNullOrEmpty())
+ {
+ pev->model = ALLOC_STRING("models/w_kevlar.mdl");
+ }
+ PRECACHE_MODEL(pev->model);
}
BOOL CItemKevlar::MyTouch(CBasePlayer *pPlayer)
@@ -373,8 +408,6 @@ BOOL CItemKevlar::MyTouch(CBasePlayer *pPlayer)
#ifdef REGAMEDLL_ADD
if (!g_bItemCreatedByBuying && pPlayer->HasRestrictItem(ITEM_KEVLAR, ITEM_TYPE_TOUCHED))
return FALSE;
-
- g_bItemCreatedByBuying = false;
#endif
#ifdef REGAMEDLL_FIXES
@@ -400,11 +433,13 @@ BOOL CItemKevlar::MyTouch(CBasePlayer *pPlayer)
#endif
MESSAGE_END();
- if (TheTutor)
+ if (TheTutor && g_bItemCreatedByBuying)
{
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
+ g_bItemCreatedByBuying = false;
+
return TRUE;
}
@@ -413,13 +448,16 @@ LINK_ENTITY_TO_CLASS(item_kevlar, CItemKevlar, CCSItemKevlar)
void CItemAssaultSuit::Spawn()
{
Precache();
- SET_MODEL(ENT(pev), "models/w_assault.mdl");
CItem::Spawn();
}
void CItemAssaultSuit::Precache()
{
- PRECACHE_MODEL("models/w_assault.mdl");
+ if(pev->model.IsNullOrEmpty())
+ {
+ pev->model = ALLOC_STRING("models/w_assault.mdl");
+ }
+ PRECACHE_MODEL(pev->model);
}
BOOL CItemAssaultSuit::MyTouch(CBasePlayer *pPlayer)
@@ -427,8 +465,6 @@ BOOL CItemAssaultSuit::MyTouch(CBasePlayer *pPlayer)
#ifdef REGAMEDLL_ADD
if (!g_bItemCreatedByBuying && pPlayer->HasRestrictItem(ITEM_ASSAULT, ITEM_TYPE_TOUCHED))
return FALSE;
-
- g_bItemCreatedByBuying = false;
#endif
#ifdef REGAMEDLL_FIXES
@@ -449,11 +485,13 @@ BOOL CItemAssaultSuit::MyTouch(CBasePlayer *pPlayer)
WRITE_BYTE(1); // 0 = ARMOR_KEVLAR, 1 = ARMOR_VESTHELM
MESSAGE_END();
- if (TheTutor)
+ if (TheTutor && g_bItemCreatedByBuying)
{
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
+ g_bItemCreatedByBuying = false;
+
return TRUE;
}
@@ -462,13 +500,16 @@ LINK_ENTITY_TO_CLASS(item_assaultsuit, CItemAssaultSuit, CCSItemAssaultSuit)
void CItemThighPack::Spawn()
{
Precache();
- SET_MODEL(ENT(pev), "models/w_thighpack.mdl");
CItem::Spawn();
}
void CItemThighPack::Precache()
{
- PRECACHE_MODEL("models/w_thighpack.mdl");
+ if(pev->model.IsNullOrEmpty())
+ {
+ pev->model = ALLOC_STRING("models/w_thighpack.mdl");
+ }
+ PRECACHE_MODEL(pev->model);
}
BOOL CItemThighPack::MyTouch(CBasePlayer *pPlayer)
@@ -499,7 +540,7 @@ BOOL CItemThighPack::MyTouch(CBasePlayer *pPlayer)
EMIT_SOUND(pPlayer->edict(), CHAN_VOICE, "items/kevlar.wav", VOL_NORM, ATTN_NORM);
- if (TheTutor)
+ if (TheTutor && g_bItemCreatedByBuying)
{
TheTutor->OnEvent(EVENT_PLAYER_BOUGHT_SOMETHING, pPlayer);
}
diff --git a/regamedll/dlls/items.h b/regamedll/dlls/items.h
index fd8f3e717..8afa27b17 100644
--- a/regamedll/dlls/items.h
+++ b/regamedll/dlls/items.h
@@ -91,6 +91,8 @@ class CItem: public CBaseEntity
{
public:
virtual void Spawn();
+ virtual void Restart();
+ virtual int ObjectCaps() { return (CBaseEntity::ObjectCaps() | FCAP_MUST_RESET); }
virtual CBaseEntity *Respawn();
virtual BOOL MyTouch(CBasePlayer *pPlayer) { return FALSE; }
diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp
index 7824ef516..5f6216f1b 100644
--- a/regamedll/dlls/multiplay_gamerules.cpp
+++ b/regamedll/dlls/multiplay_gamerules.cpp
@@ -109,6 +109,8 @@ bool CCStrikeGameMgrHelper::__API_HOOK(CanPlayerHearPlayer)(CBasePlayer *pListen
return (pListener->IsAlive() == pSender->IsAlive() || pSender->IsAlive());
case 5:
return ((pListener->IsAlive() == pSender->IsAlive() && pListener->m_iTeam == pSender->m_iTeam) || !pListener->IsAlive());
+ case 6:
+ return ((pListener->IsAlive() == pSender->IsAlive() && pListener->m_iTeam == pSender->m_iTeam) || (!pListener->IsAlive() && !pSender->IsAlive()));
#endif
default:
{
@@ -1486,6 +1488,12 @@ bool CHalfLifeMultiplay::HostageRescueRoundEndCheck()
}
}
+#ifdef REGAMEDLL_ADD
+ if (hostagesCount > 0 && m_iHostagesRescued >= (hostagesCount * Q_min(hostages_rescued_ratio.value, 1.0f)))
+ {
+ return OnRoundEnd_Intercept(WINSTATUS_CTS, ROUND_ALL_HOSTAGES_RESCUED, GetRoundRestartDelay());
+ }
+#else
// There are no hostages alive.. check to see if the CTs have rescued atleast 50% of them.
if (!bHostageAlive && hostagesCount > 0)
{
@@ -1494,6 +1502,7 @@ bool CHalfLifeMultiplay::HostageRescueRoundEndCheck()
return OnRoundEnd_Intercept(WINSTATUS_CTS, ROUND_ALL_HOSTAGES_RESCUED, GetRoundRestartDelay());
}
}
+#endif
return false;
}
@@ -2028,6 +2037,10 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(RestartRound)()
#endif
pPlayer->RoundRespawn();
+
+#ifdef REGAMEDLL_ADD
+ FireTargets("game_entity_restart", pPlayer, nullptr, USE_TOGGLE, 0.0);
+#endif
}
// Gooseman : The following code fixes the HUD icon bug
@@ -2066,6 +2079,10 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(RestartRound)()
m_bTargetBombed = m_bBombDefused = false;
m_bLevelInitialized = false;
m_bCompleteReset = false;
+
+#ifdef REGAMEDLL_ADD
+ FireTargets("game_round_start", nullptr, nullptr, USE_TOGGLE, 0.0);
+#endif
}
BOOL CHalfLifeMultiplay::IsThereABomber()
@@ -2378,7 +2395,7 @@ void CHalfLifeMultiplay::Think()
MESSAGE_BEGIN(MSG_ALL, gmsgForceCam);
WRITE_BYTE(forcecamera.value != 0);
WRITE_BYTE(forcechasecam.value != 0);
- WRITE_BYTE(fadetoblack.value != 0);
+ WRITE_BYTE(fadetoblack.value == FADETOBLACK_STAY);
MESSAGE_END();
m_flForceCameraValue = forcecamera.value;
@@ -3441,7 +3458,7 @@ void CHalfLifeMultiplay::InitHUD(CBasePlayer *pl)
MESSAGE_BEGIN(MSG_ONE, gmsgForceCam, nullptr, pl->edict());
WRITE_BYTE(forcecamera.value != 0);
WRITE_BYTE(forcechasecam.value != 0);
- WRITE_BYTE(fadetoblack.value != 0);
+ WRITE_BYTE(fadetoblack.value == FADETOBLACK_STAY);
MESSAGE_END();
if (m_bGameOver)
@@ -3859,7 +3876,7 @@ BOOL EXT_FUNC CHalfLifeMultiplay::__API_HOOK(FPlayerCanRespawn)(CBasePlayer *pPl
{
// If this player just connected and fadetoblack is on, then maybe
// the server admin doesn't want him peeking around.
- if (fadetoblack.value != 0.0f)
+ if (fadetoblack.value == FADETOBLACK_STAY)
{
UTIL_ScreenFade(pPlayer, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT));
}
@@ -3919,7 +3936,11 @@ void EXT_FUNC CHalfLifeMultiplay::__API_HOOK(PlayerKilled)(CBasePlayer *pVictim,
else if (ktmp && ktmp->Classify() == CLASS_VEHICLE)
{
CBasePlayer *pDriver = static_cast(((CFuncVehicle *)ktmp)->m_pDriver);
+#ifdef REGAMEDLL_FIXES
+ if (pDriver && !pDriver->has_disconnected)
+#else
if (pDriver)
+#endif
{
pKiller = pDriver->pev;
peKiller = static_cast(pDriver);
@@ -4312,11 +4333,29 @@ LINK_HOOK_CLASS_CUSTOM_CHAIN(int, CHalfLifeMultiplay, CSGameRules, DeadPlayerWea
int EXT_FUNC CHalfLifeMultiplay::__API_HOOK(DeadPlayerWeapons)(CBasePlayer *pPlayer)
{
- return GR_PLR_DROP_GUN_ACTIVE;
+#ifdef REGAMEDLL_ADD
+ switch ((int)weapondrop.value)
+ {
+ case 3:
+ return GR_PLR_DROP_GUN_ALL;
+ case 2:
+ break;
+ case 1:
+ return GR_PLR_DROP_GUN_BEST;
+ default:
+ return GR_PLR_DROP_GUN_NO;
+ }
+#endif
+ return GR_PLR_DROP_GUN_ACTIVE; // keep original value in return
}
int CHalfLifeMultiplay::DeadPlayerAmmo(CBasePlayer *pPlayer)
{
+#ifdef REGAMEDLL_ADD
+ if (ammodrop.value == 0.0f)
+ return GR_PLR_DROP_AMMO_NO;
+#endif
+
return GR_PLR_DROP_AMMO_ACTIVE;
}
diff --git a/regamedll/dlls/observer.cpp b/regamedll/dlls/observer.cpp
index 336b7b3cc..c35b17f9a 100644
--- a/regamedll/dlls/observer.cpp
+++ b/regamedll/dlls/observer.cpp
@@ -6,7 +6,7 @@ int __API_HOOK(GetForceCamera)(CBasePlayer *pObserver)
{
int retVal;
- if (!fadetoblack.value)
+ if (fadetoblack.value != FADETOBLACK_STAY)
{
retVal = int(CVAR_GET_FLOAT("mp_forcechasecam"));
@@ -51,7 +51,7 @@ void UpdateClientEffects(CBasePlayer *pObserver, int oldMode)
{
bool clearProgress = false;
bool clearBlindness = false;
- bool blindnessOk = (fadetoblack.value == 0);
+ bool blindnessOk = (fadetoblack.value != FADETOBLACK_STAY);
bool clearNightvision = false;
if (pObserver->GetObserverMode() == OBS_IN_EYE)
diff --git a/regamedll/dlls/observer.h b/regamedll/dlls/observer.h
index 722c977a4..743936ff9 100644
--- a/regamedll/dlls/observer.h
+++ b/regamedll/dlls/observer.h
@@ -32,6 +32,12 @@
#define CAMERA_MODE_SPEC_ONLY_TEAM 1
#define CAMERA_MODE_SPEC_ONLY_FIRST_PERSON 2
+enum FadeToBlack {
+ FADETOBLACK_OFF,
+ FADETOBLACK_STAY,
+ FADETOBLACK_AT_DYING,
+};
+
int GetForceCamera(CBasePlayer *pObserver);
void UpdateClientEffects(CBasePlayer *pObserver, int oldMode);
diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp
index 3b51675bc..801b8918a 100644
--- a/regamedll/dlls/player.cpp
+++ b/regamedll/dlls/player.cpp
@@ -569,7 +569,13 @@ Vector CBasePlayer::GetGunPosition()
bool CBasePlayer::IsHittingShield(Vector &vecDirection, TraceResult *ptr)
{
+#ifdef REGAMEDLL_FIXES
+ if (!HasShield()
+ || pev->gamestate == HITGROUP_SHIELD_DISABLED
+ || (m_pActiveItem && m_pActiveItem->m_iId == WEAPON_C4))
+#else
if ((m_pActiveItem && m_pActiveItem->m_iId == WEAPON_C4) || !HasShield())
+#endif
return false;
if (ptr->iHitgroup == HITGROUP_SHIELD)
@@ -1292,9 +1298,19 @@ CWeaponBox *EXT_FUNC __API_HOOK(CreateWeaponBox)(CBasePlayerItem *pItem, CBasePl
bool exhaustibleAmmo = (pItem->iFlags() & ITEM_FLAG_EXHAUSTIBLE) == ITEM_FLAG_EXHAUSTIBLE;
if (exhaustibleAmmo || packAmmo)
{
+#ifndef REGAMEDLL_ADD
pWeaponBox->PackAmmo(MAKE_STRING(pItem->pszAmmo1()), pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()]);
-
+#else
+ pWeaponBox->GiveAmmo(pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()], (char *)pItem->pszAmmo1(), pItem->iMaxAmmo1());
+#endif
+#ifndef REGAMEDLL_FIXES
+ // by removing ammo ONLY on exhaustible weapons (slot 4 and 5)
+ // you are allowing to duplicate ammo whenever:
+ // (1) you have 2 weapons sharing the same ammo type (e.g. mp5navy and glock)
+ // (2) you are dropping a weapon alive and pickup another (with same ammo type) without ammo
+ // and, logically, you throw your ammo with your gun with packing enabled
if (exhaustibleAmmo)
+#endif
{
pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()] = 0;
}
@@ -1306,10 +1322,10 @@ CWeaponBox *EXT_FUNC __API_HOOK(CreateWeaponBox)(CBasePlayerItem *pItem, CBasePl
return pWeaponBox;
}
-void PackPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
+CWeaponBox *PackPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
{
if (!pItem)
- return;
+ return nullptr;
const char *modelName = GetCSModelName(pItem->m_iId);
if (modelName)
@@ -1319,7 +1335,7 @@ void PackPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
Vector vecVelocity = pPlayer->pev->velocity * 0.75f;
// create a box to pack the stuff into
- CreateWeaponBox(pItem, pPlayer,
+ return CreateWeaponBox(pItem, pPlayer,
modelName,
vecOrigin,
vecAngles,
@@ -1327,6 +1343,8 @@ void PackPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
CGameRules::GetItemKillDelay(), packAmmo
);
}
+
+ return nullptr;
}
#ifdef REGAMEDLL_ADD
@@ -1383,78 +1401,132 @@ void PackPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
void CBasePlayer::PackDeadPlayerItems()
{
// get the game rules
- bool bPackGun = (g_pGameRules->DeadPlayerWeapons(this) != GR_PLR_DROP_GUN_NO);
+ int iPackGun = g_pGameRules->DeadPlayerWeapons(this);
bool bPackAmmo = (g_pGameRules->DeadPlayerAmmo(this) != GR_PLR_DROP_AMMO_NO);
- if (bPackGun)
+ if (iPackGun != GR_PLR_DROP_GUN_NO)
{
- bool bShieldDropped = false;
+ bool bSkipPrimSec = false;
if (HasShield())
{
DropShield();
- bShieldDropped = true;
+#ifdef REGAMEDLL_ADD
+ if(iPackGun != GR_PLR_DROP_GUN_ALL)
+#endif
+ {
+ bSkipPrimSec = true;
+ }
}
int nBestWeight = 0;
CBasePlayerItem *pBestItem = nullptr;
- for (int n = 0; n < MAX_ITEM_TYPES; n++)
+#ifdef REGAMEDLL_ADD
+ int iGunsPacked = 0;
+
+ if (iPackGun == GR_PLR_DROP_GUN_ACTIVE)
{
- // there's a weapon here. Should I pack it?
- CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[n];
+ // check if we've just already dropped our active gun
+ if (!bSkipPrimSec && m_pActiveItem && m_pActiveItem->CanDrop() && m_pActiveItem->iItemSlot() < KNIFE_SLOT)
+ {
+ pBestItem = m_pActiveItem;
- while (pPlayerItem)
+ // if active item is undroppable, then nothing is dropped
+ }
+
+ // are we allowing nade drop?
+ if ((int)nadedrops.value >= 1)
+ {
+ // goto item loop but skip guns
+ iPackGun = GR_PLR_DROP_GUN_ALL;
+ bSkipPrimSec = true;
+ }
+ }
+
+ if (iPackGun == GR_PLR_DROP_GUN_ALL || iPackGun == GR_PLR_DROP_GUN_BEST)
+#endif
+ {
+ for (int n = 0; n < MAX_ITEM_TYPES; n++)
{
- ItemInfo info;
- if (pPlayerItem->iItemSlot() < KNIFE_SLOT && !bShieldDropped)
+ // there's a weapon here. Should I pack it?
+ CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[n];
+
+ while (pPlayerItem)
{
+ ItemInfo info;
+ if (pPlayerItem->iItemSlot() < KNIFE_SLOT && !bSkipPrimSec)
+ {
#ifdef REGAMEDLL_API
- if (pPlayerItem->CSPlayerItem()->GetItemInfo(&info))
+ if (pPlayerItem->CSPlayerItem()->GetItemInfo(&info)
#else
- if (pPlayerItem->GetItemInfo(&info))
+ if (pPlayerItem->GetItemInfo(&info)
#endif
- {
- if (info.iWeight > nBestWeight)
+#ifdef REGAMEDLL_FIXES
+ && pPlayerItem->CanDrop() // needs to be droppable
+#endif
+ )
{
- nBestWeight = info.iWeight;
- pBestItem = pPlayerItem;
+#ifdef REGAMEDLL_ADD
+ if (iPackGun == GR_PLR_DROP_GUN_ALL)
+ {
+ CBasePlayerItem *pNext = pPlayerItem->m_pNext;
+
+ CWeaponBox *pWeaponBox = PackPlayerItem(this, pPlayerItem, bPackAmmo);
+ if (pWeaponBox)
+ {
+ // just push a few units in forward to separate them
+ pWeaponBox->pev->velocity = pWeaponBox->pev->velocity * (1.0 + (iGunsPacked * 0.2));
+ iGunsPacked++;
+ }
+
+ pPlayerItem = pNext;
+ continue;
+ }
+#endif
+ if (info.iWeight > nBestWeight)
+ {
+ nBestWeight = info.iWeight;
+ pBestItem = pPlayerItem;
+ }
}
}
- }
- // drop a grenade after death
- else if (pPlayerItem->iItemSlot() == GRENADE_SLOT)
- {
- if (AreRunningCZero())
+ // drop a grenade after death
+ else if (pPlayerItem->iItemSlot() == GRENADE_SLOT)
{
+ if (AreRunningCZero())
+ {
#ifdef REGAMEDLL_FIXES
- if (pPlayerItem->m_flStartThrow == 0.0f && m_rgAmmo[pPlayerItem->PrimaryAmmoIndex()] > 0)
+ if (pPlayerItem->m_flStartThrow == 0.0f && m_rgAmmo[pPlayerItem->PrimaryAmmoIndex()] > 0)
#endif
- {
- PackPlayerItem(this, pPlayerItem, true);
+ {
+ PackPlayerItem(this, pPlayerItem, true);
+ }
}
- }
#ifdef REGAMEDLL_ADD
- else
- {
- switch ((int)nadedrops.value)
- {
- case 1:
- PackPlayerNade(this, pPlayerItem, true);
- break;
- case 2:
+ else
{
- CBasePlayerItem *pNext = pPlayerItem->m_pNext;
- PackPlayerNade(this, pPlayerItem, true);
- pPlayerItem = pNext;
- continue;
- }
+ switch ((int)nadedrops.value)
+ {
+ case 1:
+ {
+ PackPlayerNade(this, pPlayerItem, true);
+ break;
+ }
+ case 2:
+ {
+ CBasePlayerItem *pNext = pPlayerItem->m_pNext;
+ PackPlayerNade(this, pPlayerItem, true);
+ pPlayerItem = pNext;
+ continue;
+ }
+ }
}
- }
#endif
- }
+ }
- pPlayerItem = pPlayerItem->m_pNext;
+ pPlayerItem = pPlayerItem->m_pNext;
+ }
}
}
@@ -2043,8 +2115,27 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
}
TheCareerTasks->HandleDeath(m_iTeam, this);
+
+#ifdef REGAMEDLL_FIXES
+ if (!m_bKilledByBomb)
+ {
+ CBasePlayer *pAttacker = CBasePlayer::Instance(pevAttacker);
+
+ if(pAttacker /*safety*/ && !pAttacker->IsBot() && pAttacker->m_iTeam != m_iTeam)
+ {
+ if (pAttacker->HasShield())
+ killerHasShield = true;
+
+ if (IsBot() && IsBlind()) // dystopm: shouldn't be !IsBot() ?
+ wasBlind = true;
+
+ TheCareerTasks->HandleEnemyKill(wasBlind, GetWeaponName(g_pevLastInflictor, pevAttacker), m_bHeadshotKilled, killerHasShield, pAttacker, this); // last 2 param swapped to match function definition
+ }
+ }
+#endif
}
+#ifndef REGAMEDLL_FIXES
if (!m_bKilledByBomb)
{
CBasePlayer *pAttacker = CBasePlayer::Instance(pevAttacker);
@@ -2074,6 +2165,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
}
}
}
+#endif
}
if (!m_bKilledByBomb)
@@ -2184,8 +2276,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
pev->gamestate = HITGROUP_SHIELD_DISABLED;
m_bShieldDrawn = false;
+#ifdef REGAMEDLL_FIXES
+ pev->flags &= ~(FL_ONGROUND | FL_FROZEN);
+#else
pev->flags &= ~FL_ONGROUND;
-
+#endif
#ifdef REGAMEDLL_FIXES
// FlashlightTurnOff()
pev->effects &= ~EF_DIMLIGHT;
@@ -2208,6 +2303,8 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
UTIL_ScreenFade(this, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT));
}
#else
+ float flDyingDuration = GetSequenceDuration() + CGameRules::GetDyingTime();
+
switch ((int)fadetoblack.value)
{
default:
@@ -2223,12 +2320,12 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
break;
}
- case 1:
+ case FADETOBLACK_STAY:
{
- UTIL_ScreenFade(this, Vector(0, 0, 0), 3, 3, 255, (FFADE_OUT | FFADE_STAYOUT));
+ UTIL_ScreenFade(this, Vector(0, 0, 0), 0.8f, flDyingDuration, 255, (FFADE_OUT | FFADE_STAYOUT));
break;
}
- case 2:
+ case FADETOBLACK_AT_DYING:
{
pev->iuser1 = OBS_CHASE_FREE;
pev->iuser2 = ENTINDEX(edict());
@@ -2239,16 +2336,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(Killed)(entvars_t *pevAttacker, int iGib)
MESSAGE_BEGIN(MSG_ONE, gmsgADStop, nullptr, pev);
MESSAGE_END();
- for (int i = 1; i <= gpGlobals->maxClients; i++)
- {
- CBasePlayer* pObserver = UTIL_PlayerByIndex(i);
-
- if (pObserver == this || (pObserver && pObserver->IsObservingPlayer(this)))
- {
- UTIL_ScreenFade(pObserver, Vector(0, 0, 0), 1, 4, 255, (FFADE_OUT));
- }
- }
-
+ UTIL_ScreenFade(this, Vector(0, 0, 0), 0.8f, flDyingDuration, 255, (FFADE_OUT));
break;
}
}
@@ -2436,7 +2524,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetAnimation)(PLAYER_ANIM playerAnim)
if (!pev->modelindex)
return;
+#ifdef REGAMEDLL_FIXES
+ if ((playerAnim == PLAYER_FLINCH || playerAnim == PLAYER_LARGE_FLINCH) && HasShield() && pev->gamestate == HITGROUP_SHIELD_ENABLED)
+#else
if ((playerAnim == PLAYER_FLINCH || playerAnim == PLAYER_LARGE_FLINCH) && HasShield())
+#endif
return;
if (playerAnim != PLAYER_FLINCH && playerAnim != PLAYER_LARGE_FLINCH && m_flFlinchTime > gpGlobals->time && pev->health > 0.0f)
@@ -3773,7 +3865,7 @@ void CBasePlayer::PlayerDeathThink()
{
// 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() && HasTimePassedSinceDeath(3.0f) && !(m_afPhysicsFlags & PFLAG_OBSERVER))
+ if (g_pGameRules->IsMultiplayer() && HasTimePassedSinceDeath(CGameRules::GetDyingTime()) && !(m_afPhysicsFlags & PFLAG_OBSERVER))
{
// Send message to everybody to spawn a corpse.
SpawnClientSideCorpse();
@@ -3863,7 +3955,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(RoundRespawn)()
#ifdef REGAMEDLL_FIXES
if (m_bPunishedForTK && pev->health > 0)
{
- ClientKill(ENT(pev));
+ Kill();
}
#endif
@@ -4010,6 +4102,11 @@ void CBasePlayer::PlayerUse()
if (!((pev->button | m_afButtonPressed | m_afButtonReleased) & IN_USE))
return;
+#ifdef REGAMEDLL_FIXES
+ if (IsReloading())
+ return;
+#endif
+
// Hit Use on a train?
if (m_afButtonPressed & IN_USE)
{
@@ -4030,7 +4127,12 @@ void CBasePlayer::PlayerUse()
CBaseEntity *pTrain = Instance(pev->groundentity);
if (pTrain && pTrain->Classify() == CLASS_VEHICLE)
{
+#ifdef REGAMEDLL_ADD
+ if (legacy_vehicle_block.value)
+ ((CFuncVehicle *)pTrain)->m_pDriver = nullptr;
+#else
((CFuncVehicle *)pTrain)->m_pDriver = nullptr;
+#endif
}
return;
}
@@ -4581,7 +4683,12 @@ void EXT_FUNC CBasePlayer::__API_HOOK(PreThink)()
// Turn off the train if you jump, strafe, or the train controls go dead
m_afPhysicsFlags &= ~PFLAG_ONTRAIN;
m_iTrain = (TRAIN_NEW | TRAIN_OFF);
+#ifdef REGAMEDLL_ADD
+ if (legacy_vehicle_block.value)
+ ((CFuncVehicle *)pTrain)->m_pDriver = nullptr;
+#else
((CFuncVehicle *)pTrain)->m_pDriver = nullptr;
+#endif
return;
}
@@ -4720,7 +4827,7 @@ void CBasePlayer::CheckTimeBasedDamage()
{
switch (i)
{
- case ITBD_PARALLYZE:
+ case ITBD_PARALYZE:
// UNDONE - flag movement as half-speed
bDuration = PARALYZE_DURATION;
break;
@@ -5045,6 +5152,11 @@ void EXT_FUNC CBasePlayer::__API_HOOK(PostThink)()
}
}
+#ifdef REGAMEDLL_FIXES
+ // Handle use events
+ PlayerUse();
+ ImpulseCommands();
+#endif
// do weapon stuff
ItemPostFrame();
@@ -6257,7 +6369,7 @@ void CBasePlayer::FlashlightTurnOn()
WRITE_BYTE(m_iFlashBattery);
MESSAGE_END();
- m_flFlashLightTime = gpGlobals->time + FLASH_DRAIN_TIME;
+ m_flFlashLightTime = gpGlobals->time + gSkillData.flFlashLightDrainTime;
}
}
@@ -6271,7 +6383,7 @@ void CBasePlayer::FlashlightTurnOff()
WRITE_BYTE(m_iFlashBattery);
MESSAGE_END();
- m_flFlashLightTime = gpGlobals->time + FLASH_CHARGE_TIME;
+ m_flFlashLightTime = gpGlobals->time + gSkillData.flFlashLightChargeTime;
}
// 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.
@@ -6301,8 +6413,10 @@ void EXT_FUNC CBasePlayer::__API_HOOK(ImpulseCommands)()
{
TraceResult tr;
+#ifndef REGAMEDLL_FIXES
// Handle use events
PlayerUse();
+#endif
int iImpulse = pev->impulse;
@@ -6499,7 +6613,7 @@ void CBasePlayer::CheatImpulseCommands(int iImpulse)
TraceResult tr;
Vector dir(0, 0, 1);
- UTIL_BloodDrips(pev->origin, dir, BLOOD_COLOR_RED, 2000);
+ UTIL_BloodDrips(pev->origin, BLOOD_COLOR_RED, 2000);
for (int r = 1; r < 4; r++)
{
@@ -6920,7 +7034,9 @@ void CBasePlayer::ItemPostFrame()
#endif
return;
+#ifndef REGAMEDLL_FIXES
ImpulseCommands();
+#endif
if (m_pActiveItem)
m_pActiveItem->ItemPostFrame();
@@ -6928,7 +7044,7 @@ void CBasePlayer::ItemPostFrame()
int CBasePlayer::AmmoInventory(int iAmmoIndex)
{
- if (iAmmoIndex == -1)
+ if (iAmmoIndex <= -1)
return -1;
return m_rgAmmo[iAmmoIndex];
@@ -7297,7 +7413,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(UpdateClientData)()
{
if (m_iFlashBattery)
{
- m_flFlashLightTime = gpGlobals->time + FLASH_DRAIN_TIME;
+ m_flFlashLightTime = gpGlobals->time + gSkillData.flFlashLightDrainTime;
if (--m_iFlashBattery <= 0)
{
@@ -7309,7 +7425,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(UpdateClientData)()
{
if (m_iFlashBattery < 100)
{
- m_flFlashLightTime = gpGlobals->time + FLASH_CHARGE_TIME;
+ m_flFlashLightTime = gpGlobals->time + gSkillData.flFlashLightChargeTime;
m_iFlashBattery++;
}
else
@@ -7756,9 +7872,12 @@ void CBasePlayer::UpdateStatusBar()
UTIL_MakeVectors(pev->v_angle + pev->punchangle);
Vector vecSrc = EyePosition();
- Vector vecEnd = vecSrc + (gpGlobals->v_forward * ((pev->flags & FL_SPECTATOR) != 0 ? MAX_SPEC_ID_RANGE : MAX_ID_RANGE));
+ Vector vecEnd = vecSrc + (gpGlobals->v_forward * (g_psv_zmax ? g_psv_zmax->value : ((pev->flags & FL_SPECTATOR) != 0 ? MAX_SPEC_ID_RANGE : MAX_ID_RANGE)));
+ int iSolidityTypeArray[MAX_CLIENTS + 1];
+ UTIL_ManageClientsSolidity(true, 1, SOLID_SLIDEBOX, iSolidityTypeArray); // Store in array & set solidity from variable.
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, edict(), &tr);
+ UTIL_ManageClientsSolidity(false, 2, 0, iSolidityTypeArray); // Restore solidity from array.
if (tr.flFraction != 1.0f)
{
@@ -7997,13 +8116,21 @@ CBaseEntity *EXT_FUNC CBasePlayer::__API_HOOK(DropPlayerItem)(const char *pszIte
Vector vecAngles = pev->angles;
Vector vecVelocity = gpGlobals->v_forward * 300 + gpGlobals->v_forward * 100;
+ bool bPackAmmo = false;
+
+#ifdef REGAMEDLL_ADD
+ if (ammodrop.value >= 2.0f)
+ bPackAmmo = true;
+#endif
+
CWeaponBox *pWeaponBox = CreateWeaponBox(pWeapon, this,
modelname,
vecOrigin,
vecAngles,
vecVelocity,
CGameRules::GetItemKillDelay(),
- false);
+ bPackAmmo
+ );
if (!pWeaponBox)
{
@@ -8401,13 +8528,7 @@ void CStripWeapons::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
{
if (m_iszSpecialItem)
{
- const char *weaponName = STRING(m_iszSpecialItem);
- WeaponSlotInfo *slotInfo = GetWeaponSlot(weaponName);
-
- if (slotInfo != nullptr && slotInfo->slot == GRENADE_SLOT)
- pPlayer->CSPlayer()->RemovePlayerItemEx(weaponName, true);
- else
- pPlayer->CSPlayer()->RemovePlayerItem(weaponName);
+ pPlayer->CSPlayer()->RemovePlayerItem(STRING(m_iszSpecialItem));
}
for (int slot = PRIMARY_WEAPON_SLOT; slot <= ALL_OTHER_ITEMS; slot++)
@@ -8417,22 +8538,17 @@ void CStripWeapons::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE
if (slot == ALL_OTHER_ITEMS)
{
- pPlayer->CSPlayer()->RemovePlayerItem("item_thighpack");
- pPlayer->CSPlayer()->RemovePlayerItem("item_longjump");
- pPlayer->CSPlayer()->RemovePlayerItem("item_assaultsuit");
pPlayer->CSPlayer()->RemovePlayerItem("item_kevlar");
+ pPlayer->CSPlayer()->RemovePlayerItem("item_assaultsuit");
pPlayer->CSPlayer()->RemovePlayerItem("item_thighpack");
+ pPlayer->CSPlayer()->RemovePlayerItem("item_longjump");
pPlayer->CSPlayer()->RemovePlayerItem("weapon_shield");
}
else
{
pPlayer->ForEachItem(slot, [pPlayer](CBasePlayerItem *pItem)
{
- if (pItem->iItemSlot() == GRENADE_SLOT)
- pPlayer->CSPlayer()->RemovePlayerItemEx(STRING(pItem->pev->classname), true);
- else
- pPlayer->CSPlayer()->RemovePlayerItem(STRING(pItem->pev->classname));
-
+ pPlayer->CSPlayer()->RemovePlayerItem(STRING(pItem->pev->classname));
return false;
});
}
@@ -8706,6 +8822,23 @@ int GetPlayerGaitsequence(const edict_t *pEdict)
return pPlayer->m_iGaitsequence;
}
+float CBasePlayer::GetDyingAnimationDuration() const
+{
+ float animDuration = -1.0f;
+
+ if (CGameRules::GetDyingTime() < DEATH_ANIMATION_TIME) // a short time, timeDiff estimates to be small
+ {
+ float flSequenceDuration = GetSequenceDuration();
+ if (flSequenceDuration > 0)
+ animDuration = flSequenceDuration;
+ }
+
+ if (animDuration <= 0)
+ animDuration = CGameRules::GetDyingTime(); // in case of failure
+
+ return animDuration;
+}
+
void CBasePlayer::SpawnClientSideCorpse()
{
#ifdef REGAMEDLL_FIXES
@@ -8713,9 +8846,7 @@ void CBasePlayer::SpawnClientSideCorpse()
if (pev->effects & EF_NODRAW)
return;
- // do not make a corpse if the player goes to respawn.
- if (pev->deadflag == DEAD_RESPAWNABLE)
- return;
+ // deadflag == DEAD_RESPAWNABLE already checked before
#endif
#ifdef REGAMEDLL_ADD
@@ -8725,6 +8856,27 @@ void CBasePlayer::SpawnClientSideCorpse()
char *infobuffer = GET_INFO_BUFFER(edict());
char *pModel = GET_KEY_VALUE(infobuffer, "model");
+ float timeDiff = pev->animtime - gpGlobals->time;
+
+#ifdef REGAMEDLL_ADD
+ if (CGameRules::GetDyingTime() < DEATH_ANIMATION_TIME) // a short time, timeDiff estimates to be small
+ {
+ float animDuration = GetDyingAnimationDuration();
+
+ // client receives a negative value
+ animDuration *= -1.0;
+
+ if (animDuration < timeDiff) // reasonable way to fix client side unfinished sequence bug
+ {
+ // by some reason, if client receives a value less
+ // than "(negative current sequence time) * 100"
+ // animation will play visually awkward
+ // at this function call time, player death animation
+ // has already finished so we can safely fake it
+ timeDiff = animDuration;
+ }
+ }
+#endif
MESSAGE_BEGIN(MSG_ALL, gmsgSendCorpse);
WRITE_STRING(pModel);
@@ -8734,14 +8886,17 @@ void CBasePlayer::SpawnClientSideCorpse()
WRITE_COORD(pev->angles.x);
WRITE_COORD(pev->angles.y);
WRITE_COORD(pev->angles.z);
- WRITE_LONG((pev->animtime - gpGlobals->time) * 100);
+ WRITE_LONG(timeDiff * 100);
WRITE_BYTE(pev->sequence);
WRITE_BYTE(pev->body);
WRITE_BYTE(m_iTeam);
WRITE_BYTE(entindex());
MESSAGE_END();
+#ifndef REGAMEDLL_FIXES
+ // already defined in StartDeathCam
m_canSwitchObserverModes = true;
+#endif
if (TheTutor)
{
@@ -9790,7 +9945,7 @@ void CBasePlayer::UpdateLocation(bool forceUpdate)
const char *placeName = "";
- if (pev->deadflag == DEAD_NO && AreRunningCZero())
+ if (pev->deadflag == DEAD_NO && AreBotsAllowed())
{
// search the place name where is located the player
Place playerPlace = TheNavAreaGrid.GetPlace(&pev->origin);
@@ -10232,6 +10387,7 @@ void EXT_FUNC CBasePlayer::__API_HOOK(SetSpawnProtection)(float flProtectionTime
#ifdef REGAMEDLL_ADD
if (respawn_immunity_effects.value > 0)
{
+ CSPlayer()->m_bSpawnProtectionEffects = true;
pev->rendermode = kRenderTransAdd;
pev->renderamt = 100.0f;
@@ -10253,12 +10409,11 @@ LINK_HOOK_CLASS_VOID_CHAIN2(CBasePlayer, RemoveSpawnProtection)
void CBasePlayer::__API_HOOK(RemoveSpawnProtection)()
{
#ifdef REGAMEDLL_ADD
- if (respawn_immunity_effects.value > 0)
+ if (CSPlayer()->m_bSpawnProtectionEffects)
{
- if (pev->rendermode == kRenderTransAdd &&
- pev->renderamt == 100.0f)
+ if (pev->rendermode == kRenderTransAdd && pev->renderamt == 100.0f)
{
- pev->renderamt = 255.0f;
+ pev->renderamt = 255.0f;
pev->rendermode = kRenderNormal;
}
@@ -10266,6 +10421,8 @@ void CBasePlayer::__API_HOOK(RemoveSpawnProtection)()
WRITE_BYTE(STATUSICON_HIDE);
WRITE_STRING("suithelmet_full");
MESSAGE_END();
+
+ CSPlayer()->m_bSpawnProtectionEffects = false;
}
CSPlayer()->m_flSpawnProtectionEndTime = 0.0f;
@@ -10296,3 +10453,23 @@ void EXT_FUNC CBasePlayer::__API_HOOK(DropIdlePlayer)(const char *reason)
SERVER_COMMAND(UTIL_VarArgs("kick \"%s\"\n", STRING(pev->netname)));
#endif // #ifdef REGAMEDLL_FIXES
}
+
+bool CBasePlayer::Kill()
+{
+ if (GetObserverMode() != OBS_NONE)
+ return false;
+
+ if (m_iJoiningState != JOINED)
+ return false;
+
+ m_LastHitGroup = HITGROUP_GENERIC;
+
+ // have the player kill himself
+ pev->health = 0.0f;
+ Killed(pev, GIB_NEVER);
+
+ if (CSGameRules()->m_pVIP == this)
+ CSGameRules()->m_iConsecutiveVIP = 10;
+
+ return true;
+}
diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h
index e62c1b730..7efead2f2 100644
--- a/regamedll/dlls/player.h
+++ b/regamedll/dlls/player.h
@@ -61,6 +61,7 @@ const float SUIT_FIRST_UPDATE_TIME = 0.1f;
const float MAX_PLAYER_FATAL_FALL_SPEED = 1100.0f;
const float MAX_PLAYER_SAFE_FALL_SPEED = 500.0f;
const float MAX_PLAYER_USE_RADIUS = 64.0f;
+const float MAX_PLAYER_USE_TANK_RADIUS = 30.0f;
const float ARMOR_RATIO = 0.5f; // Armor Takes 50% of the damage
const float ARMOR_BONUS = 0.5f; // Each Point of Armor is work 1/x points of health
@@ -453,6 +454,7 @@ class CBasePlayer: public CBaseMonster {
static CBasePlayer *Instance(entvars_t *pev) { return Instance(ENT(pev)); }
static CBasePlayer *Instance(int offset) { return Instance(ENT(offset)); }
+ float GetDyingAnimationDuration() const;
void SpawnClientSideCorpse();
void Observer_FindNextPlayer(bool bReverse, const char *name = nullptr);
CBasePlayer *Observer_IsValidTarget(int iPlayerIndex, bool bSameTeam);
@@ -642,6 +644,7 @@ class CBasePlayer: public CBaseMonster {
void RemoveSpawnProtection();
void UseEmpty();
void DropIdlePlayer(const char *reason);
+ bool Kill();
// templates
template
diff --git a/regamedll/dlls/skill.h b/regamedll/dlls/skill.h
index 23fda28c9..a2f19dc1c 100644
--- a/regamedll/dlls/skill.h
+++ b/regamedll/dlls/skill.h
@@ -49,6 +49,10 @@ struct skilldata_t
float batteryCapacity;
float healthchargerCapacity;
float healthkitCapacity;
+
+ // Extended for own purpose.
+ float flFlashLightDrainTime;
+ float flFlashLightChargeTime;
};
extern skilldata_t gSkillData;
diff --git a/regamedll/dlls/training_gamerules.h b/regamedll/dlls/training_gamerules.h
index 04ba82f33..3bd75b0d4 100644
--- a/regamedll/dlls/training_gamerules.h
+++ b/regamedll/dlls/training_gamerules.h
@@ -34,6 +34,7 @@ class CHalfLifeTraining: public CHalfLifeMultiplay
CHalfLifeTraining();
virtual ~CHalfLifeTraining() {};
+ virtual void Think() {}
virtual BOOL IsMultiplayer() { return FALSE; }
virtual BOOL IsDeathmatch();
virtual void InitHUD(CBasePlayer *pl);
diff --git a/regamedll/dlls/tutor_base_tutor.cpp b/regamedll/dlls/tutor_base_tutor.cpp
index 8723ca2c8..2268d18b7 100644
--- a/regamedll/dlls/tutor_base_tutor.cpp
+++ b/regamedll/dlls/tutor_base_tutor.cpp
@@ -104,7 +104,7 @@ char *TutorMessageEvent::GetNextParameter(char *buf, int buflen)
Q_strncpy(buf, param->m_data, buflen);
#ifdef REGAMEDLL_FIXES
- buf[buflen] = '\0';
+ buf[buflen - 1] = '\0';
#endif
delete param;
diff --git a/regamedll/dlls/util.cpp b/regamedll/dlls/util.cpp
index 6c10ca406..42250319f 100644
--- a/regamedll/dlls/util.cpp
+++ b/regamedll/dlls/util.cpp
@@ -1056,7 +1056,7 @@ void UTIL_BloodStream(const Vector &origin, const Vector &direction, int color,
MESSAGE_END();
}
-void UTIL_BloodDrips(const Vector &origin, const Vector &direction, int color, int amount)
+void UTIL_BloodDrips(const Vector &origin, int color, int amount)
{
if (!UTIL_ShouldShowBlood(color))
return;
@@ -1497,6 +1497,10 @@ void UTIL_RestartOther(const char *szClassname)
while ((pEntity = UTIL_FindEntityByClassname(pEntity, szClassname)))
{
pEntity->Restart();
+
+#ifdef REGAMEDLL_ADD
+ FireTargets("game_entity_restart", pEntity, nullptr, USE_TOGGLE, 0.0);
+#endif
}
}
@@ -1853,3 +1857,43 @@ int UTIL_CountPlayersInBrushVolume(bool bOnlyAlive, CBaseEntity *pBrushEntity, i
return playersInCount + playersOutCount;
}
+
+// Set modes (iSetMode):
+// 0 - Do not set solidity.
+// 1 - Set solidity from the value of the variable "iSolidityType".
+// 2 - Set solidity from the value of the array "iSolidityTypeArray".
+int UTIL_ManageClientsSolidity(bool bStore, int iSetMode, int iSolidityType, int iSolidityTypeArray[MAX_CLIENTS + 1]) {
+ iSetMode = clamp(iSetMode, 0, 2);
+
+ // Note: Can not store to array & set from it at the same time! Not made for such goal!
+ if(bStore && iSetMode == 2) {
+ iSetMode = 0;
+ }
+ else if(iSetMode == 0)
+ return 0;
+
+ if(bStore) {
+ Q_memset(iSolidityTypeArray, SOLID_NOT, sizeof(iSolidityTypeArray));
+ }
+
+ int iClientsBitsFound = 0;
+ for(int iClientID = 1; iClientID <= gpGlobals->maxClients; iClientID++)
+ {
+ CBasePlayer *pPlayer = UTIL_PlayerByIndex(iClientID);
+
+ if (!pPlayer || pPlayer->has_disconnected || !pPlayer->IsAlive())
+ continue;
+
+ if(bStore) {
+ iSolidityTypeArray[iClientID] = pPlayer->pev->solid;
+ }
+
+ if(iSetMode) {
+ pPlayer->pev->solid = (iSetMode == 1) ? iSolidityType : iSolidityTypeArray[iClientID];
+ }
+
+ iClientsBitsFound |= (1<<(iClientID - 1));
+ }
+
+ return iClientsBitsFound;
+}
diff --git a/regamedll/dlls/util.h b/regamedll/dlls/util.h
index baeea3634..edcf393cc 100644
--- a/regamedll/dlls/util.h
+++ b/regamedll/dlls/util.h
@@ -262,7 +262,7 @@ bool UTIL_IsMasterTriggered(string_t sMaster, CBaseEntity *pActivator);
BOOL UTIL_ShouldShowBlood(int color);
int UTIL_PointContents(const Vector &vec);
void UTIL_BloodStream(const Vector &origin, const Vector &direction, int color, int amount);
-void UTIL_BloodDrips(const Vector &origin, const Vector &direction, int color, int amount);
+void UTIL_BloodDrips(const Vector &origin, int color, int amount);
Vector UTIL_RandomBloodVector();
void UTIL_BloodDecalTrace(TraceResult *pTrace, int bloodColor);
void UTIL_DecalTrace(TraceResult *pTrace, int decalNumber);
@@ -354,6 +354,7 @@ class CPlayerInVolumeAdapter
};
int UTIL_CountPlayersInBrushVolume(bool bOnlyAlive, CBaseEntity *pBrushEntity, int &playersInCount, int &playersOutCount, CPlayerInVolumeAdapter *pAdapter = nullptr);
+int UTIL_ManageClientsSolidity(bool bStore, int iSetMode, int iSolidityType, int iSolidityTypeArray[MAX_CLIENTS + 1] = nullptr);
inline real_t UTIL_FixupAngle(real_t v)
{
diff --git a/regamedll/dlls/vehicle.cpp b/regamedll/dlls/vehicle.cpp
index 55b453ed7..a621cf3f4 100644
--- a/regamedll/dlls/vehicle.cpp
+++ b/regamedll/dlls/vehicle.cpp
@@ -109,8 +109,7 @@ void CFuncVehicle::Blocked(CBaseEntity *pOther)
pevOther->velocity.z += 300;
pev->velocity = pev->velocity * 0.85;
- ALERT(at_aiconsole, "TRAIN(%s): Blocked by %s (dmg:%.2f)\n", STRING(pev->targetname), STRING(pOther->pev->classname), pev->dmg);
- UTIL_MakeVectors(pev->angles);
+ ALERT(at_aiconsole, "TRAIN(%s): Blocked by %s (dmg:%.2f)\n", STRING(pev->targetname), STRING(pevOther->classname), pev->dmg);
Vector forward, right, vOrigin;
Vector vFrontLeft = (gpGlobals->v_forward * -1) * (m_length * 0.5);
@@ -131,13 +130,42 @@ void CFuncVehicle::Blocked(CBaseEntity *pOther)
float maxz = pev->origin.z + (2 * Q_abs(int(pev->mins.z - pev->maxs.z)));
#endif
- if (pOther->pev->origin.x < minx
- || pOther->pev->origin.x > maxx
- || pOther->pev->origin.y < miny
- || pOther->pev->origin.y > maxy
- || pOther->pev->origin.z < minz
- || pOther->pev->origin.z > maxz)
+ if (pevOther->origin.x < minx
+ || pevOther->origin.x > maxx
+ || pevOther->origin.y < miny
+ || pevOther->origin.y > maxy
+ || pevOther->origin.z < minz
+ || pevOther->origin.z > maxz)
{
+#ifdef REGAMEDLL_ADD
+ if (legacy_vehicle_block.value)
+ {
+ pOther->TakeDamage(pev, pev, 150, DMG_CRUSH);
+ return;
+ }
+
+ CBasePlayer* playerDriver = static_cast(m_pDriver);
+
+ if (pOther->Classify() == CLASS_PLAYER)
+ {
+ CBasePlayer* playerOther = static_cast(pOther);
+ if (!playerDriver || !g_pGameRules->FPlayerCanTakeDamage(playerOther, playerDriver))
+ {
+ // Just kick player
+ return;
+ }
+ else
+ {
+ playerOther->TakeDamage(pev, playerDriver->pev, 150, DMG_CRUSH);
+ return;
+ }
+ }
+ else if (playerDriver && FClassnameIs(pevOther, "hostage_entity"))
+ {
+ pOther->TakeDamage(playerDriver->pev, playerDriver->pev, 150, DMG_CRUSH);
+ return;
+ }
+#endif
pOther->TakeDamage(pev, pev, 150, DMG_CRUSH);
}
}
diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp
index 22d61fc9f..479d4da59 100644
--- a/regamedll/dlls/weapons.cpp
+++ b/regamedll/dlls/weapons.cpp
@@ -70,6 +70,8 @@ float GetBaseAccuracy(WeaponIdType id)
case WEAPON_MP5N:
return 0.0f;
}
+
+ return 0.0f;
}
// Resets the global multi damage accumulator
@@ -110,7 +112,7 @@ void AddMultiDamage(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamag
void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage)
{
- UTIL_BloodDrips(vecSpot, g_vecAttackDir, bloodColor, int(flDamage));
+ UTIL_BloodDrips(vecSpot, bloodColor, int(flDamage));
}
NOXREF int DamageDecal(CBaseEntity *pEntity, int bitsDamageType)
@@ -587,11 +589,12 @@ void CBasePlayerItem::DefaultTouch(CBaseEntity *pOther)
CBasePlayer *pPlayer = static_cast(pOther);
if (pPlayer->m_bIsVIP
- && m_iId != WEAPON_USP
- && m_iId != WEAPON_GLOCK18
- && m_iId != WEAPON_P228
- && m_iId != WEAPON_DEAGLE
- && m_iId != WEAPON_KNIFE)
+ && m_iId != WEAPON_USP
+ && m_iId != WEAPON_GLOCK18
+ && m_iId != WEAPON_P228
+ && m_iId != WEAPON_FIVESEVEN
+ && m_iId != WEAPON_DEAGLE
+ && m_iId != WEAPON_KNIFE)
{
return;
}
@@ -759,7 +762,9 @@ void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL bI
if (bIsGlock)
{
vecDir = m_pPlayer->FireBullets3(vecSrc, gpGlobals->v_forward, 0.05, 8192, 1, BULLET_PLAYER_9MM, 18, 0.9, m_pPlayer->pev, true, m_pPlayer->random_seed);
+#ifndef REGAMEDLL_FIXES
--m_pPlayer->ammo_9mm;
+#endif
PLAYBACK_EVENT_FULL(flag, m_pPlayer->edict(), m_usFireGlock18, 0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y,
int(m_pPlayer->pev->punchangle.x * 10000), int(m_pPlayer->pev->punchangle.y * 10000), m_iClip == 0, FALSE);
@@ -768,7 +773,9 @@ void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL bI
{
vecDir = m_pPlayer->FireBullets3(vecSrc, gpGlobals->v_forward, m_fBurstSpread, 8192, 2, BULLET_PLAYER_556MM, 30, 0.96, m_pPlayer->pev, false, m_pPlayer->random_seed);
+#ifndef REGAMEDLL_FIXES
--m_pPlayer->ammo_556nato;
+#endif
#ifdef REGAMEDLL_ADD
// HACKHACK: client-side weapon prediction fix
@@ -1111,7 +1118,6 @@ void CBasePlayerItem::DestroyItem()
// if attached to a player, remove.
if (m_pPlayer->RemovePlayerItem(this))
{
-
#ifdef REGAMEDLL_FIXES
m_pPlayer->pev->weapons &= ~(1 << m_iId);
@@ -1120,8 +1126,11 @@ void CBasePlayerItem::DestroyItem()
m_pPlayer->m_iHideHUD |= HIDEHUD_WEAPONS;
}
#endif
-
}
+#ifdef REGAMEDLL_FIXES
+ else if(!(pev->flags & FL_KILLME)) // Do not kill the item when unable to unhook from player's inventory (as if we manually refused this).
+ return;
+#endif
}
Kill();
@@ -1154,8 +1163,19 @@ void CBasePlayerItem::Kill()
void CBasePlayerItem::Holster(int skiplocal)
{
- m_pPlayer->pev->viewmodel = 0;
- m_pPlayer->pev->weaponmodel = 0;
+ if(m_pPlayer)
+ {
+ m_pPlayer->pev->viewmodel = 0;
+ m_pPlayer->pev->weaponmodel = 0;
+
+#ifdef REGAMEDLL_FIXES
+ if(m_pPlayer->HasShield())
+ {
+ m_pPlayer->m_bShieldDrawn = false;
+ m_pPlayer->pev->gamestate = HITGROUP_SHIELD_DISABLED;
+ }
+#endif
+ }
}
void CBasePlayerItem::AttachToPlayer(CBasePlayer *pPlayer)
@@ -1371,7 +1391,7 @@ BOOL EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultDeploy)(char *szViewModel, ch
return FALSE;
m_pPlayer->TabulateAmmo();
-#ifdef REGAMEDLL_API
+#ifdef REGAMEDLL_FIXES
m_pPlayer->pev->viewmodel = ALLOC_STRING(szViewModel);
m_pPlayer->pev->weaponmodel = ALLOC_STRING(szWeaponModel);
#else
@@ -1392,6 +1412,13 @@ BOOL EXT_FUNC CBasePlayerWeapon::__API_HOOK(DefaultDeploy)(char *szViewModel, ch
m_pPlayer->m_iLastZoom = DEFAULT_FOV;
m_pPlayer->m_bResumeZoom = false;
+#ifdef REGAMEDLL_FIXES
+ if(m_pPlayer->HasShield() && m_iId != WEAPON_C4 && m_pPlayer->pev->weaponmodel)
+ {
+ m_pPlayer->pev->gamestate = HITGROUP_SHIELD_ENABLED;
+ }
+#endif
+
return TRUE;
}
@@ -1550,8 +1577,21 @@ void CBasePlayerWeapon::Holster(int skiplocal)
{
// cancel any reload in progress.
m_fInReload = FALSE;
- m_pPlayer->pev->viewmodel = 0;
- m_pPlayer->pev->weaponmodel = 0;
+
+ if(m_pPlayer)
+ {
+ m_pPlayer->pev->viewmodel = 0;
+ m_pPlayer->pev->weaponmodel = 0;
+
+#ifdef REGAMEDLL_FIXES
+ if(m_pPlayer->HasShield())
+ {
+ m_iWeaponState &= ~WPNSTATE_SHIELD_DRAWN;
+ m_pPlayer->m_bShieldDrawn = false;
+ m_pPlayer->pev->gamestate = HITGROUP_SHIELD_DISABLED;
+ }
+#endif
+ }
}
// called by the new item with the existing item as parameter
@@ -1593,7 +1633,17 @@ int CBasePlayerWeapon::ExtractClipAmmo(CBasePlayerWeapon *pWeapon)
iAmmo = m_iClip;
}
- return pWeapon->m_pPlayer->GiveAmmo(iAmmo, pszAmmo1(), iMaxAmmo1());
+ int iIdAmmo = pWeapon->m_pPlayer->GiveAmmo(iAmmo, pszAmmo1(), iMaxAmmo1());
+
+#ifdef REGAMEDLL_FIXES
+ if (iIdAmmo > 0 && IsGrenadeWeapon(m_iId))
+ {
+ // grenades have WEAPON_NOCLIP force play the "got ammo" sound.
+ EMIT_SOUND(pWeapon->m_pPlayer->edict(), CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM);
+ }
+#endif
+
+ return iIdAmmo;
}
// RetireWeapon - no more ammo for this gun, put it away.
@@ -1835,7 +1885,7 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
if (FClassnameIs(pItem->pev, "weapon_c4"))
{
#ifdef REGAMEDLL_FIXES
- if (pPlayer->m_iTeam != TERRORIST)
+ if (pPlayer->m_iTeam != TERRORIST || pPlayer->m_bHasC4)
return;
#else
if (pPlayer->m_iTeam != TERRORIST || pPlayer->pev->deadflag != DEAD_NO)
@@ -1918,19 +1968,35 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
int playerGrenades = pPlayer->m_rgAmmo[pGrenade->m_iPrimaryAmmoType];
#ifdef REGAMEDLL_FIXES
- auto info = GetWeaponInfo(pGrenade->m_iId);
- if (info && playerGrenades < info->maxRounds)
+ // sorry for hardcode :(
+ const int boxAmmoSlot = 1;
+
+ if (playerGrenades < pGrenade->iMaxAmmo1())
{
- auto pNext = m_rgpPlayerItems[i]->m_pNext;
- if (pPlayer->AddPlayerItem(pItem))
+ if (m_rgAmmo[boxAmmoSlot] > 1 && playerGrenades > 0)
{
- pItem->AttachToPlayer(pPlayer);
- bEmitSound = true;
+ if (!FStringNull(m_rgiszAmmo[boxAmmoSlot])
+ && pPlayer->GiveAmmo(1, STRING(m_rgiszAmmo[boxAmmoSlot]), pGrenade->iMaxAmmo1()) != -1)
+ {
+ m_rgAmmo[boxAmmoSlot]--;
+
+ EMIT_SOUND(pPlayer->edict(), CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM);
+ }
}
+ else
+ {
+ auto pNext = m_rgpPlayerItems[i]->m_pNext;
- // unlink this weapon from the box
- m_rgpPlayerItems[i] = pItem = pNext;
- continue;
+ if (pPlayer->AddPlayerItem(pItem))
+ {
+ pItem->AttachToPlayer(pPlayer);
+ bEmitSound = true;
+ }
+
+ // unlink this weapon from the box
+ m_rgpPlayerItems[i] = pItem = pNext;
+ continue;
+ }
}
#else
@@ -2004,8 +2070,11 @@ void CWeaponBox::Touch(CBaseEntity *pOther)
if (!FStringNull(m_rgiszAmmo[n]))
{
// there's some ammo of this type.
+#ifndef REGAMEDLL_ADD
pPlayer->GiveAmmo(m_rgAmmo[n], (char *)STRING(m_rgiszAmmo[n]), MaxAmmoCarry(m_rgiszAmmo[n]));
-
+#else
+ pPlayer->GiveAmmo(m_rgAmmo[n], STRING(m_rgiszAmmo[n]), m_rgAmmo[n]);
+#endif
// now empty the ammo from the weaponbox since we just gave it to the player
m_rgiszAmmo[n] = iStringNull;
m_rgAmmo[n] = 0;
diff --git a/regamedll/dlls/weapons.h b/regamedll/dlls/weapons.h
index bd22989e3..cbcf231c0 100644
--- a/regamedll/dlls/weapons.h
+++ b/regamedll/dlls/weapons.h
@@ -534,7 +534,7 @@ enum usp_shield_e
USP_SHIELD_SHOOT_EMPTY,
USP_SHIELD_RELOAD,
USP_SHIELD_DRAW,
- USP_SHIELD_UP_IDLE,
+ USP_SHIELD_IDLE_UP,
USP_SHIELD_UP,
USP_SHIELD_DOWN,
};
@@ -861,7 +861,7 @@ class CC4: public CBasePlayerWeapon
virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
virtual int GetItemInfo(ItemInfo *p);
virtual BOOL Deploy();
- virtual void Holster(int skiplocal);
+ virtual void Holster(int skiplocal = 0);
virtual float GetMaxSpeed();
virtual int iItemSlot() { return C4_SLOT; }
virtual void PrimaryAttack();
@@ -900,6 +900,19 @@ enum deagle_e
DEAGLE_DRAW,
};
+enum deagle_shield_e
+{
+ DEAGLE_SHIELD_IDLE1,
+ DEAGLE_SHIELD_SHOOT,
+ DEAGLE_SHIELD_SHOOT2,
+ DEAGLE_SHIELD_SHOOT_EMPTY,
+ DEAGLE_SHIELD_RELOAD,
+ DEAGLE_SHIELD_DRAW,
+ DEAGLE_SHIELD_IDLE_UP,
+ DEAGLE_SHIELD_UP,
+ DEAGLE_SHIELD_DOWN,
+};
+
class CDEAGLE: public CBasePlayerWeapon
{
public:
@@ -953,7 +966,7 @@ class CFlashbang: public CBasePlayerWeapon
virtual BOOL CanDeploy();
virtual BOOL CanDrop() { return FALSE; }
virtual BOOL Deploy();
- virtual void Holster(int skiplocal);
+ virtual void Holster(int skiplocal = 0);
virtual float GetMaxSpeed() { return m_fMaxSpeed; }
virtual int iItemSlot() { return GRENADE_SLOT; }
virtual void PrimaryAttack();
@@ -1065,7 +1078,7 @@ enum glock18_shield_e
GLOCK18_SHIELD_SHOOT_EMPTY,
GLOCK18_SHIELD_RELOAD,
GLOCK18_SHIELD_DRAW,
- GLOCK18_SHIELD_IDLE,
+ GLOCK18_SHIELD_IDLE_UP,
GLOCK18_SHIELD_UP,
GLOCK18_SHIELD_DOWN,
};
@@ -1122,7 +1135,7 @@ class CHEGrenade: public CBasePlayerWeapon
virtual BOOL CanDeploy();
virtual BOOL CanDrop() { return FALSE; }
virtual BOOL Deploy();
- virtual void Holster(int skiplocal);
+ virtual void Holster(int skiplocal = 0);
virtual float GetMaxSpeed() { return m_fMaxSpeed; }
virtual int iItemSlot() { return GRENADE_SLOT; }
virtual void PrimaryAttack();
@@ -1150,16 +1163,16 @@ class CHEGrenade: public CBasePlayerWeapon
unsigned short m_usCreateExplosion;
};
-
-const float KNIFE_BODYHIT_VOLUME = 128.0f;
-const float KNIFE_WALLHIT_VOLUME = 512.0f;
-const float KNIFE_MAX_SPEED = 250.0f;
-const float KNIFE_MAX_SPEED_SHIELD = 180.0f;
-const float KNIFE_STAB_DAMAGE = 65.0f;
-const float KNIFE_SWING_DAMAGE = 15.0f;
-const float KNIFE_SWING_DAMAGE_FAST = 20.0f;
-const float KNIFE_STAB_DISTANCE = 32.0f;
-const float KNIFE_SWING_DISTANCE = 48.0f;
+const float KNIFE_BODYHIT_VOLUME = 128.0f;
+const float KNIFE_WALLHIT_VOLUME = 512.0f;
+const float KNIFE_MAX_SPEED = 250.0f;
+const float KNIFE_MAX_SPEED_SHIELD = 180.0f;
+const float KNIFE_STAB_DAMAGE = 65.0f;
+const float KNIFE_SWING_DAMAGE = 15.0f;
+const float KNIFE_SWING_DAMAGE_FAST = 20.0f;
+const float KNIFE_STAB_DISTANCE = 32.0f;
+const float KNIFE_SWING_DISTANCE = 48.0f;
+const float KNIFE_BACKSTAB_MULTIPLIER = 3.0f;
enum knife_e
{
@@ -1179,7 +1192,7 @@ enum knife_shield_e
KNIFE_SHIELD_SLASH,
KNIFE_SHIELD_ATTACKHIT,
KNIFE_SHIELD_DRAW,
- KNIFE_SHIELD_UPIDLE,
+ KNIFE_SHIELD_IDLE_UP,
KNIFE_SHIELD_UP,
KNIFE_SHIELD_DOWN,
};
@@ -1192,7 +1205,7 @@ class CKnife: public CBasePlayerWeapon
virtual int GetItemInfo(ItemInfo *p);
virtual BOOL CanDrop() { return FALSE; }
virtual BOOL Deploy();
- virtual void Holster(int skiplocal);
+ virtual void Holster(int skiplocal = 0);
virtual float GetMaxSpeed() { return m_fMaxSpeed; }
virtual int iItemSlot() { return KNIFE_SLOT; }
virtual void PrimaryAttack();
@@ -1220,19 +1233,41 @@ class CKnife: public CBasePlayerWeapon
void SetPlayerShieldAnim();
void ResetPlayerShieldAnim();
+ float KnifeStabDamage() const;
+ float KnifeSwingDamage(bool fast) const;
+ float KnifeStabDistance() const;
+ float KnifeSwingDistance() const;
+ float KnifeBackStabMultiplier() const;
+
private:
TraceResult m_trHit;
unsigned short m_usKnife;
- // Extra RegameDLL features
+#ifdef REGAMEDLL_API
float m_flStabBaseDamage;
float m_flSwingBaseDamage;
float m_flSwingBaseDamage_Fast;
float m_flStabDistance;
float m_flSwingDistance;
+
+ float m_flBackStabMultiplier;
+#endif
};
+#ifdef REGAMEDLL_API
+inline float CKnife::KnifeStabDamage() const { return m_flStabBaseDamage; }
+inline float CKnife::KnifeSwingDamage(bool fast) const { return fast ? m_flSwingBaseDamage_Fast : m_flSwingBaseDamage; }
+inline float CKnife::KnifeStabDistance() const { return m_flStabDistance; }
+inline float CKnife::KnifeSwingDistance() const { return m_flSwingDistance; }
+inline float CKnife::KnifeBackStabMultiplier() const { return m_flBackStabMultiplier; }
+#else
+inline float CKnife::KnifeStabDamage() const { return KNIFE_STAB_DAMAGE; }
+inline float CKnife::KnifeSwingDamage(bool fast) const { return fast ? KNIFE_SWING_DAMAGE_FAST : KNIFE_SWING_DAMAGE; }
+inline float CKnife::KnifeStabDistance() const { return KNIFE_STAB_DISTANCE; }
+inline float CKnife::KnifeSwingDistance() const { return KNIFE_SWING_DISTANCE; }
+inline float CKnife::KnifeBackStabMultiplier() const { return KNIFE_BACKSTAB_MULTIPLIER; }
+#endif // REGAMEDLL_API
const float M249_MAX_SPEED = 220.0f;
const float M249_DAMAGE = 32.0f;
@@ -1634,7 +1669,7 @@ class CSmokeGrenade: public CBasePlayerWeapon
virtual BOOL CanDeploy();
virtual BOOL CanDrop() { return FALSE; }
virtual BOOL Deploy();
- virtual void Holster(int skiplocal);
+ virtual void Holster(int skiplocal = 0);
virtual float GetMaxSpeed() { return m_fMaxSpeed; }
virtual int iItemSlot() { return GRENADE_SLOT; }
virtual void PrimaryAttack();
@@ -1835,6 +1870,19 @@ enum fiveseven_e
FIVESEVEN_DRAW,
};
+enum fiveseven_shield_e
+{
+ FIVESEVEN_SHIELD_IDLE1,
+ FIVESEVEN_SHIELD_SHOOT,
+ FIVESEVEN_SHIELD_SHOOT2,
+ FIVESEVEN_SHIELD_SHOOT_EMPTY,
+ FIVESEVEN_SHIELD_RELOAD,
+ FIVESEVEN_SHIELD_DRAW,
+ FIVESEVEN_SHIELD_IDLE_UP,
+ FIVESEVEN_SHIELD_UP,
+ FIVESEVEN_SHIELD_DOWN,
+};
+
class CFiveSeven: public CBasePlayerWeapon
{
public:
diff --git a/regamedll/dlls/weapontype.h b/regamedll/dlls/weapontype.h
index e3527e5fa..97752ec8f 100644
--- a/regamedll/dlls/weapontype.h
+++ b/regamedll/dlls/weapontype.h
@@ -318,25 +318,12 @@ enum AmmoBuyAmount
AMMO_SMOKEGRENADE_BUY = 1,
};
-enum shieldgun_e
-{
- SHIELDGUN_IDLE,
- SHIELDGUN_SHOOT1,
- SHIELDGUN_SHOOT2,
- SHIELDGUN_SHOOT_EMPTY,
- SHIELDGUN_RELOAD,
- SHIELDGUN_DRAW,
- SHIELDGUN_DRAWN_IDLE,
- SHIELDGUN_UP,
- SHIELDGUN_DOWN,
-};
-
// custom
enum shieldgren_e
{
- SHIELDREN_IDLE = 4,
- SHIELDREN_UP,
- SHIELDREN_DOWN
+ SHIELDGREN_IDLE = 4, // 3 is last grenade viewmodel sequence
+ SHIELDGREN_UP,
+ SHIELDGREN_DOWN
};
enum InventorySlotType
diff --git a/regamedll/dlls/world.cpp b/regamedll/dlls/world.cpp
index efbb4dcf1..e4a385450 100644
--- a/regamedll/dlls/world.cpp
+++ b/regamedll/dlls/world.cpp
@@ -288,10 +288,7 @@ void CWorld::Precache()
CVAR_SET_STRING("room_type", "0");
// Set up game rules
- if (g_pGameRules)
- {
- delete g_pGameRules;
- }
+ FreeGameRules(&g_pGameRules);
g_pGameRules = InstallGameRules();
diff --git a/regamedll/dlls/wpn_shared/wpn_aug.cpp b/regamedll/dlls/wpn_shared/wpn_aug.cpp
index c54780f3a..b5a0aeb18 100644
--- a/regamedll/dlls/wpn_shared/wpn_aug.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_aug.cpp
@@ -78,13 +78,15 @@ void CAUG::SecondaryAttack()
void CAUG::PrimaryAttack()
{
+ const float flCycleTime = (m_pPlayer->pev->fov == DEFAULT_FOV) ? 0.0825f : 0.135f;
+
if (!(m_pPlayer->pev->flags & FL_ONGROUND))
{
- AUGFire(0.035 + (0.4 * m_flAccuracy), 0.0825, FALSE);
+ AUGFire(0.035 + (0.4 * m_flAccuracy), flCycleTime, FALSE);
}
else if (m_pPlayer->pev->velocity.Length2D() > 140)
{
- AUGFire(0.035 + (0.07 * m_flAccuracy), 0.0825, FALSE);
+ AUGFire(0.035 + (0.07 * m_flAccuracy), flCycleTime, FALSE);
}
else if (m_pPlayer->pev->fov == DEFAULT_FOV)
{
@@ -92,7 +94,7 @@ void CAUG::PrimaryAttack()
}
else
{
- AUGFire(0.02 * m_flAccuracy, 0.135, FALSE);
+ AUGFire(0.02 * m_flAccuracy, flCycleTime, FALSE);
}
}
diff --git a/regamedll/dlls/wpn_shared/wpn_c4.cpp b/regamedll/dlls/wpn_shared/wpn_c4.cpp
index 63736adef..278847a7d 100644
--- a/regamedll/dlls/wpn_shared/wpn_c4.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_c4.cpp
@@ -101,6 +101,10 @@ void CC4::Holster(int skiplocal)
m_pPlayer->pev->gamestate = HITGROUP_SHIELD_ENABLED;
m_bHasShield = false;
}
+
+#ifdef REGAMEDLL_FIXES
+ CBasePlayerWeapon::Holster();
+#endif
}
void CC4::PrimaryAttack()
@@ -168,8 +172,9 @@ void CC4::PrimaryAttack()
m_fArmedTime = 0;
Broadcast("BOMBPL");
+#ifndef REGAMEDLL_FIXES
m_pPlayer->m_bHasC4 = false;
-
+#endif
if (pev->speed != 0 && CSGameRules())
{
CSGameRules()->m_iC4Timer = int(pev->speed);
@@ -217,19 +222,34 @@ void CC4::PrimaryAttack()
// Play the plant sound.
EMIT_SOUND(edict(), CHAN_WEAPON, "weapons/c4_plant.wav", VOL_NORM, ATTN_NORM);
-
+#ifndef REGAMEDLL_FIXES
// hide the backpack in Terrorist's models.
m_pPlayer->pev->body = 0;
-
+#endif
// release the player from being frozen
m_pPlayer->ResetMaxSpeed();
-
+#ifndef REGAMEDLL_FIXES
// No more c4!
m_pPlayer->SetBombIcon(FALSE);
-
+#endif
if (--m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
{
- RetireWeapon();
+#ifdef REGAMEDLL_FIXES
+ m_pPlayer->m_bHasC4 = false;
+ // hide the backpack in Terrorist's models.
+ m_pPlayer->pev->body = 0;
+ // No more c4!
+ m_pPlayer->SetBombIcon(FALSE);
+
+ if ((m_pPlayer->pev->weapons & ~(1 << WEAPON_SUIT | 1 << m_iId )) == 0)
+ {
+ Holster();
+ }
+ else
+#endif
+ {
+ RetireWeapon();
+ }
return;
}
}
@@ -299,7 +319,16 @@ void CC4::WeaponIdle()
{
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
{
- RetireWeapon();
+#ifdef REGAMEDLL_FIXES
+ if ((m_pPlayer->pev->weapons & ~(1 << WEAPON_SUIT | 1 << m_iId )) == 0)
+ {
+ Holster();
+ }
+ else
+#endif
+ {
+ RetireWeapon();
+ }
return;
}
diff --git a/regamedll/dlls/wpn_shared/wpn_deagle.cpp b/regamedll/dlls/wpn_shared/wpn_deagle.cpp
index f7a97d5d0..7dbed0c6b 100644
--- a/regamedll/dlls/wpn_shared/wpn_deagle.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_deagle.cpp
@@ -93,7 +93,7 @@ void CDEAGLE::PrimaryAttack()
void CDEAGLE::SecondaryAttack()
{
- ShieldSecondaryFire(SHIELDGUN_UP, SHIELDGUN_DOWN);
+ ShieldSecondaryFire(DEAGLE_SHIELD_UP, DEAGLE_SHIELD_DOWN);
}
void CDEAGLE::DEAGLEFire(float flSpread, float flCycleTime, BOOL fUseSemi)
@@ -204,7 +204,7 @@ void CDEAGLE::WeaponIdle()
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
{
- SendWeaponAnim(SHIELDGUN_DRAWN_IDLE, UseDecrement() != FALSE);
+ SendWeaponAnim(DEAGLE_SHIELD_IDLE_UP, UseDecrement() != FALSE);
}
}
}
diff --git a/regamedll/dlls/wpn_shared/wpn_fiveseven.cpp b/regamedll/dlls/wpn_shared/wpn_fiveseven.cpp
index 67f2f3d57..31f211f08 100644
--- a/regamedll/dlls/wpn_shared/wpn_fiveseven.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_fiveseven.cpp
@@ -92,7 +92,7 @@ void CFiveSeven::PrimaryAttack()
void CFiveSeven::SecondaryAttack()
{
- ShieldSecondaryFire(SHIELDGUN_UP, SHIELDGUN_DOWN);
+ ShieldSecondaryFire(FIVESEVEN_SHIELD_UP, FIVESEVEN_SHIELD_DOWN);
}
void CFiveSeven::FiveSevenFire(float flSpread, float flCycleTime, BOOL fUseSemi)
@@ -208,7 +208,7 @@ void CFiveSeven::WeaponIdle()
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
{
- SendWeaponAnim(SHIELDGUN_DRAWN_IDLE, UseDecrement() != FALSE);
+ SendWeaponAnim(FIVESEVEN_SHIELD_IDLE_UP, UseDecrement() != FALSE);
}
}
else if (m_iClip)
diff --git a/regamedll/dlls/wpn_shared/wpn_flashbang.cpp b/regamedll/dlls/wpn_shared/wpn_flashbang.cpp
index c5462e49b..409a0c466 100644
--- a/regamedll/dlls/wpn_shared/wpn_flashbang.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_flashbang.cpp
@@ -83,6 +83,10 @@ void CFlashbang::Holster(int skiplocal)
m_flStartThrow = 0;
m_flReleaseThrow = -1.0f;
+
+#ifdef REGAMEDLL_FIXES
+ CBasePlayerWeapon::Holster();
+#endif
}
void CFlashbang::PrimaryAttack()
@@ -142,7 +146,7 @@ bool CFlashbang::ShieldSecondaryFire(int iUpAnim, int iDownAnim)
void CFlashbang::SecondaryAttack()
{
- ShieldSecondaryFire(SHIELDGUN_DRAW, SHIELDGUN_DRAWN_IDLE);
+ ShieldSecondaryFire(SHIELDGREN_UP, SHIELDGREN_DOWN);
}
void CFlashbang::SetPlayerShieldAnim()
@@ -223,7 +227,24 @@ void CFlashbang::WeaponIdle()
{
// we've finished the throw, restart.
m_flStartThrow = 0;
- RetireWeapon();
+
+#ifdef REGAMEDLL_FIXES
+ if ((m_pPlayer->pev->weapons & ~(1 << WEAPON_SUIT | 1 << m_iId )) == 0)
+ {
+ if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0)
+ {
+ Holster();
+ }
+ else
+ {
+ SendWeaponAnim(FLASHBANG_DRAW, UseDecrement() != FALSE);
+ }
+ }
+ else
+#endif
+ {
+ RetireWeapon();
+ }
}
else if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
{
@@ -236,7 +257,7 @@ void CFlashbang::WeaponIdle()
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
{
- SendWeaponAnim(SHIELDREN_IDLE, UseDecrement() != FALSE);
+ SendWeaponAnim(SHIELDGREN_IDLE, UseDecrement() != FALSE);
}
}
else
diff --git a/regamedll/dlls/wpn_shared/wpn_glock18.cpp b/regamedll/dlls/wpn_shared/wpn_glock18.cpp
index b82d5148f..c2f5399d5 100644
--- a/regamedll/dlls/wpn_shared/wpn_glock18.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_glock18.cpp
@@ -295,7 +295,7 @@ void CGLOCK18::WeaponIdle()
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
{
- SendWeaponAnim(GLOCK18_SHIELD_IDLE, UseDecrement() != FALSE);
+ SendWeaponAnim(GLOCK18_SHIELD_IDLE_UP, UseDecrement() != FALSE);
}
}
// only idle if the slid isn't back
diff --git a/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp b/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp
index 3f17e7254..031cb2451 100644
--- a/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_hegrenade.cpp
@@ -87,6 +87,10 @@ void CHEGrenade::Holster(int skiplocal)
m_flStartThrow = 0;
m_flReleaseThrow = -1.0f;
+
+#ifdef REGAMEDLL_FIXES
+ CBasePlayerWeapon::Holster();
+#endif
}
void CHEGrenade::PrimaryAttack()
@@ -144,7 +148,7 @@ bool CHEGrenade::ShieldSecondaryFire(int iUpAnim, int iDownAnim)
void CHEGrenade::SecondaryAttack()
{
- ShieldSecondaryFire(SHIELDGUN_DRAW, SHIELDGUN_DRAWN_IDLE);
+ ShieldSecondaryFire(SHIELDGREN_UP, SHIELDGREN_DOWN);
}
void CHEGrenade::SetPlayerShieldAnim()
@@ -226,13 +230,22 @@ void CHEGrenade::WeaponIdle()
// we've finished the throw, restart.
m_flStartThrow = 0;
- if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
+ if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0)
{
SendWeaponAnim(HEGRENADE_DRAW, UseDecrement() != FALSE);
}
else
{
- RetireWeapon();
+#ifdef REGAMEDLL_FIXES
+ if ((m_pPlayer->pev->weapons & ~(1 << WEAPON_SUIT | 1 << m_iId )) == 0)
+ {
+ Holster();
+ }
+ else
+#endif
+ {
+ RetireWeapon();
+ }
return;
}
@@ -247,7 +260,7 @@ void CHEGrenade::WeaponIdle()
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
{
- SendWeaponAnim(SHIELDREN_IDLE, UseDecrement() != FALSE);
+ SendWeaponAnim(SHIELDGREN_IDLE, UseDecrement() != FALSE);
}
}
else
diff --git a/regamedll/dlls/wpn_shared/wpn_knife.cpp b/regamedll/dlls/wpn_shared/wpn_knife.cpp
index 18275c047..bff4cfce1 100644
--- a/regamedll/dlls/wpn_shared/wpn_knife.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_knife.cpp
@@ -12,6 +12,7 @@ void CKnife::Spawn()
m_iWeaponState &= ~WPNSTATE_SHIELD_DRAWN;
m_iClip = WEAPON_NOCLIP;
+#ifdef REGAMEDLL_API
m_flStabBaseDamage = KNIFE_STAB_DAMAGE;
m_flSwingBaseDamage = KNIFE_SWING_DAMAGE;
m_flSwingBaseDamage_Fast = KNIFE_SWING_DAMAGE_FAST;
@@ -19,6 +20,9 @@ void CKnife::Spawn()
m_flStabDistance = KNIFE_STAB_DISTANCE;
m_flSwingDistance = KNIFE_SWING_DISTANCE;
+ m_flBackStabMultiplier = KNIFE_BACKSTAB_MULTIPLIER;
+#endif
+
// Get ready to fall down
FallInit();
@@ -44,12 +48,16 @@ void CKnife::Precache()
m_usKnife = PRECACHE_EVENT(1, "events/knife.sc");
+#ifdef REGAMEDLL_API
m_flStabBaseDamage = KNIFE_STAB_DAMAGE;
m_flSwingBaseDamage = KNIFE_SWING_DAMAGE;
m_flSwingBaseDamage_Fast = KNIFE_SWING_DAMAGE_FAST;
m_flStabDistance = KNIFE_STAB_DISTANCE;
m_flSwingDistance = KNIFE_SWING_DISTANCE;
+
+ m_flBackStabMultiplier = KNIFE_BACKSTAB_MULTIPLIER;
+#endif
}
int CKnife::GetItemInfo(ItemInfo *p)
@@ -80,9 +88,7 @@ BOOL CKnife::Deploy()
m_pPlayer->m_bShieldDrawn = false;
if (m_pPlayer->HasShield())
- {
return DefaultDeploy("models/shield/v_shield_knife.mdl", "models/shield/p_shield_knife.mdl", KNIFE_SHIELD_DRAW, "shieldknife", UseDecrement() != FALSE);
- }
else
return DefaultDeploy("models/v_knife.mdl", "models/p_knife.mdl", KNIFE_DRAW, "knife", UseDecrement() != FALSE);
}
@@ -90,6 +96,10 @@ BOOL CKnife::Deploy()
void CKnife::Holster(int skiplocal)
{
m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.5f;
+
+#ifdef REGAMEDLL_FIXES
+ CBasePlayerWeapon::Holster();
+#endif
}
NOXREF void CKnife::WeaponAnimation(int iAnimation)
@@ -121,6 +131,9 @@ void FindHullIntersection(const Vector &vecSrc, TraceResult &tr, float *mins, fl
distance = 1e6f;
vecHullEnd = vecSrc + ((vecHullEnd - vecSrc) * 2);
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_KNIFE;
+#endif
UTIL_TraceLine(vecSrc, vecHullEnd, dont_ignore_monsters, pEntity, &tmpTrace);
if (tmpTrace.flFraction < 1.0f)
@@ -138,7 +151,9 @@ void FindHullIntersection(const Vector &vecSrc, TraceResult &tr, float *mins, fl
vecEnd.x = vecHullEnd.x + minmaxs[i][0];
vecEnd.y = vecHullEnd.y + minmaxs[j][1];
vecEnd.z = vecHullEnd.z + minmaxs[k][2];
-
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_KNIFE;
+#endif
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, pEntity, &tmpTrace);
if (tmpTrace.flFraction < 1.0f)
@@ -166,14 +181,7 @@ void CKnife::SetPlayerShieldAnim()
if (!m_pPlayer->HasShield())
return;
- if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
- {
- Q_strcpy(m_pPlayer->m_szAnimExtention, "shield");
- }
- else
- {
- Q_strcpy(m_pPlayer->m_szAnimExtention, "shieldknife");
- }
+ Q_strcpy(m_pPlayer->m_szAnimExtention, (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) != 0 ? "shield" : "shieldknife");
}
void CKnife::ResetPlayerShieldAnim()
@@ -271,14 +279,23 @@ BOOL CKnife::Swing(BOOL fFirst)
UTIL_MakeVectors(m_pPlayer->pev->v_angle);
vecSrc = m_pPlayer->GetGunPosition();
- vecEnd = vecSrc + gpGlobals->v_forward * m_flSwingDistance;
+ vecEnd = vecSrc + gpGlobals->v_forward * KnifeSwingDistance();
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_KNIFE;
+#endif
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, m_pPlayer->edict(), &tr);
if (tr.flFraction >= 1.0f)
{
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_KNIFE;
+#endif
UTIL_TraceHull(vecSrc, vecEnd, dont_ignore_monsters, head_hull, m_pPlayer->edict(), &tr);
-
+#ifdef REGAMEDLL_ADD
+ // We manually reset it because Engine doesn't unlike TraceLine
+ gpGlobals->trace_flags = 0;
+#endif
if (tr.flFraction < 1.0f)
{
// Calculate the point of intersection of the line (or hull) and the object we hit
@@ -303,8 +320,8 @@ BOOL CKnife::Swing(BOOL fFirst)
{
switch ((m_iSwing++) % 2)
{
- case 0: SendWeaponAnim(KNIFE_MIDATTACK1HIT, UseDecrement() != FALSE); break;
- case 1: SendWeaponAnim(KNIFE_MIDATTACK2HIT, UseDecrement() != FALSE); break;
+ case 0: SendWeaponAnim(KNIFE_MIDATTACK1HIT, UseDecrement() != FALSE); break;
+ case 1: SendWeaponAnim(KNIFE_MIDATTACK2HIT, UseDecrement() != FALSE); break;
}
// miss
@@ -322,10 +339,15 @@ BOOL CKnife::Swing(BOOL fFirst)
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f;
// play wiff or swish sound
- if (RANDOM_LONG(0, 1))
- EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_slash1.wav", VOL_NORM, ATTN_NORM, 0, 94);
- else
- EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_slash2.wav", VOL_NORM, ATTN_NORM, 0, 94);
+ EMIT_SOUND_DYN(m_pPlayer->edict(),
+ CHAN_WEAPON,
+ RANDOM_LONG(0, 1) ?
+ "weapons/knife_slash1.wav" :
+ "weapons/knife_slash2.wav",
+ VOL_NORM,
+ ATTN_NORM,
+ 0,
+ 94);
// player "shoot" animation
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
@@ -340,8 +362,8 @@ BOOL CKnife::Swing(BOOL fFirst)
{
switch ((m_iSwing++) % 2)
{
- case 0: SendWeaponAnim(KNIFE_MIDATTACK1HIT, UseDecrement() != FALSE); break;
- case 1: SendWeaponAnim(KNIFE_MIDATTACK2HIT, UseDecrement() != FALSE); break;
+ case 0: SendWeaponAnim(KNIFE_MIDATTACK1HIT, UseDecrement() != FALSE); break;
+ case 1: SendWeaponAnim(KNIFE_MIDATTACK2HIT, UseDecrement() != FALSE); break;
}
m_flNextPrimaryAttack = GetNextAttackDelay(0.4);
@@ -368,10 +390,11 @@ BOOL CKnife::Swing(BOOL fFirst)
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
ClearMultiDamage();
- if (m_flNextPrimaryAttack + 0.4f < UTIL_WeaponTimeBase())
- pEntity->TraceAttack(m_pPlayer->pev, m_flSwingBaseDamage_Fast, gpGlobals->v_forward, &tr, (DMG_NEVERGIB | DMG_BULLET));
- else
- pEntity->TraceAttack(m_pPlayer->pev, m_flSwingBaseDamage, gpGlobals->v_forward, &tr, (DMG_NEVERGIB | DMG_BULLET));
+ pEntity->TraceAttack(m_pPlayer->pev,
+ KnifeSwingDamage(m_flNextPrimaryAttack + 0.4f < UTIL_WeaponTimeBase()),
+ gpGlobals->v_forward,
+ &tr,
+ (DMG_NEVERGIB | DMG_BULLET));
ApplyMultiDamage(m_pPlayer->pev, m_pPlayer->pev);
@@ -379,28 +402,27 @@ BOOL CKnife::Swing(BOOL fFirst)
if (pEntity) // -V595
#endif
{
+ if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE
#ifdef REGAMEDLL_FIXES
- if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE && pEntity->Classify() != CLASS_VEHICLE)
-#else
- if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE)
+ && pEntity->Classify() != CLASS_VEHICLE
#endif
+ )
{
// play thwack or smack sound
switch (RANDOM_LONG(0, 3))
{
- case 0: EMIT_SOUND(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_hit1.wav", VOL_NORM, ATTN_NORM); break;
- case 1: EMIT_SOUND(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_hit2.wav", VOL_NORM, ATTN_NORM); break;
- case 2: EMIT_SOUND(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_hit3.wav", VOL_NORM, ATTN_NORM); break;
- case 3: EMIT_SOUND(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_hit4.wav", VOL_NORM, ATTN_NORM); break;
+ case 0: EMIT_SOUND(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_hit1.wav", VOL_NORM, ATTN_NORM); break;
+ case 1: EMIT_SOUND(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_hit2.wav", VOL_NORM, ATTN_NORM); break;
+ case 2: EMIT_SOUND(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_hit3.wav", VOL_NORM, ATTN_NORM); break;
+ case 3: EMIT_SOUND(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_hit4.wav", VOL_NORM, ATTN_NORM); break;
}
m_pPlayer->m_iWeaponVolume = KNIFE_BODYHIT_VOLUME;
if (!pEntity->IsAlive())
return TRUE;
- else
- flVol = 0.1f;
+ flVol = 0.1f;
fHitWorld = FALSE;
}
}
@@ -449,14 +471,22 @@ BOOL CKnife::Stab(BOOL fFirst)
UTIL_MakeVectors(m_pPlayer->pev->v_angle);
vecSrc = m_pPlayer->GetGunPosition();
- vecEnd = vecSrc + gpGlobals->v_forward * m_flStabDistance;
-
+ vecEnd = vecSrc + gpGlobals->v_forward * KnifeStabDistance();
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_KNIFE;
+#endif
UTIL_TraceLine(vecSrc, vecEnd, dont_ignore_monsters, m_pPlayer->edict(), &tr);
if (tr.flFraction >= 1.0f)
{
+#ifdef REGAMEDLL_ADD
+ gpGlobals->trace_flags = FTRACE_KNIFE;
+#endif
UTIL_TraceHull(vecSrc, vecEnd, dont_ignore_monsters, head_hull, m_pPlayer->edict(), &tr);
-
+#ifdef REGAMEDLL_ADD
+ // We manually reset it because Engine doesn't unlike TraceLine
+ gpGlobals->trace_flags = 0;
+#endif
if (tr.flFraction < 1.0f)
{
// Calculate the point of intersection of the line (or hull) and the object we hit
@@ -486,10 +516,15 @@ BOOL CKnife::Stab(BOOL fFirst)
m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 1.0f;
// play wiff or swish sound
- if (RANDOM_LONG(0, 1))
- EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_slash1.wav", VOL_NORM, ATTN_NORM, 0, 94);
- else
- EMIT_SOUND_DYN(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_slash2.wav", VOL_NORM, ATTN_NORM, 0, 94);
+ EMIT_SOUND_DYN(m_pPlayer->edict(),
+ CHAN_WEAPON,
+ RANDOM_LONG(0, 1) ?
+ "weapons/knife_slash1.wav" :
+ "weapons/knife_slash2.wav",
+ VOL_NORM,
+ ATTN_NORM,
+ 0,
+ 94);
// player "shoot" animation
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
@@ -517,7 +552,7 @@ BOOL CKnife::Stab(BOOL fFirst)
// player "shoot" animation
m_pPlayer->SetAnimation(PLAYER_ATTACK1);
- float flDamage = m_flStabBaseDamage;
+ float flDamage = KnifeStabDamage();
if (pEntity && pEntity->IsPlayer())
{
@@ -532,10 +567,10 @@ BOOL CKnife::Stab(BOOL fFirst)
flDot = DotProduct(vec2LOS, gpGlobals->v_forward.Make2D());
- //Triple the damage if we are stabbing them in the back.
+ // Multiply the damage if we are stabbing them in the back.
if (flDot > 0.80f)
{
- flDamage *= 3.0f;
+ flDamage *= KnifeBackStabMultiplier();
}
}
@@ -549,11 +584,11 @@ BOOL CKnife::Stab(BOOL fFirst)
if (pEntity) // -V595
#endif
{
+ if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE
#ifdef REGAMEDLL_FIXES
- if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE && pEntity->Classify() != CLASS_VEHICLE)
-#else
- if (pEntity->Classify() != CLASS_NONE && pEntity->Classify() != CLASS_MACHINE)
+ && pEntity->Classify() != CLASS_VEHICLE
#endif
+ )
{
EMIT_SOUND(m_pPlayer->edict(), CHAN_WEAPON, "weapons/knife_stab.wav", VOL_NORM, ATTN_NORM);
m_pPlayer->m_iWeaponVolume = KNIFE_BODYHIT_VOLUME;
diff --git a/regamedll/dlls/wpn_shared/wpn_p228.cpp b/regamedll/dlls/wpn_shared/wpn_p228.cpp
index 6e2c8d05b..b64f5fcf3 100644
--- a/regamedll/dlls/wpn_shared/wpn_p228.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_p228.cpp
@@ -92,7 +92,7 @@ void CP228::PrimaryAttack()
void CP228::SecondaryAttack()
{
- ShieldSecondaryFire(SHIELDGUN_UP, SHIELDGUN_DOWN);
+ ShieldSecondaryFire(P228_SHIELD_UP, P228_SHIELD_DOWN);
}
void CP228::P228Fire(float flSpread, float flCycleTime, BOOL fUseSemi)
diff --git a/regamedll/dlls/wpn_shared/wpn_sg552.cpp b/regamedll/dlls/wpn_shared/wpn_sg552.cpp
index c95a66878..7f77ccb88 100644
--- a/regamedll/dlls/wpn_shared/wpn_sg552.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_sg552.cpp
@@ -77,13 +77,15 @@ void CSG552::SecondaryAttack()
void CSG552::PrimaryAttack()
{
+ const float flCycleTime = (m_pPlayer->pev->fov == DEFAULT_FOV) ? 0.0825f : 0.135f;
+
if (!(m_pPlayer->pev->flags & FL_ONGROUND))
{
- SG552Fire(0.035 + (0.45 * m_flAccuracy), 0.0825, FALSE);
+ SG552Fire(0.035 + (0.45 * m_flAccuracy), flCycleTime, FALSE);
}
else if (m_pPlayer->pev->velocity.Length2D() > 140)
{
- SG552Fire(0.035 + (0.075 * m_flAccuracy), 0.0825, FALSE);
+ SG552Fire(0.035 + (0.075 * m_flAccuracy), flCycleTime, FALSE);
}
else if (m_pPlayer->pev->fov == DEFAULT_FOV)
{
@@ -91,7 +93,7 @@ void CSG552::PrimaryAttack()
}
else
{
- SG552Fire(0.02 * m_flAccuracy, 0.135, FALSE);
+ SG552Fire(0.02 * m_flAccuracy, flCycleTime, FALSE);
}
}
diff --git a/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp b/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp
index d63fe3a69..e0d51f951 100644
--- a/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_smokegrenade.cpp
@@ -88,6 +88,10 @@ void CSmokeGrenade::Holster(int skiplocal)
m_flStartThrow = 0;
m_flReleaseThrow = -1;
+
+#ifdef REGAMEDLL_FIXES
+ CBasePlayerWeapon::Holster();
+#endif
}
void CSmokeGrenade::PrimaryAttack()
@@ -145,7 +149,7 @@ bool CSmokeGrenade::ShieldSecondaryFire(int iUpAnim, int iDownAnim)
void CSmokeGrenade::SecondaryAttack()
{
- ShieldSecondaryFire(SHIELDGUN_DRAW, SHIELDGUN_DRAWN_IDLE);
+ ShieldSecondaryFire(SHIELDGREN_UP, SHIELDGREN_DOWN);
}
void CSmokeGrenade::SetPlayerShieldAnim()
@@ -227,13 +231,22 @@ void CSmokeGrenade::WeaponIdle()
// we've finished the throw, restart.
m_flStartThrow = 0;
- if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType])
+ if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] > 0)
{
SendWeaponAnim(SMOKEGRENADE_DRAW, UseDecrement() != FALSE);
}
else
{
- RetireWeapon();
+#ifdef REGAMEDLL_FIXES
+ if ((m_pPlayer->pev->weapons & ~(1 << WEAPON_SUIT | 1 << m_iId )) == 0)
+ {
+ Holster();
+ }
+ else
+#endif
+ {
+ RetireWeapon();
+ }
return;
}
@@ -251,7 +264,7 @@ void CSmokeGrenade::WeaponIdle()
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
{
- SendWeaponAnim(SHIELDREN_IDLE, UseDecrement() != FALSE);
+ SendWeaponAnim(SHIELDGREN_IDLE, UseDecrement() != FALSE);
}
}
else
diff --git a/regamedll/dlls/wpn_shared/wpn_usp.cpp b/regamedll/dlls/wpn_shared/wpn_usp.cpp
index 6141baebe..0d830d690 100644
--- a/regamedll/dlls/wpn_shared/wpn_usp.cpp
+++ b/regamedll/dlls/wpn_shared/wpn_usp.cpp
@@ -279,7 +279,7 @@ void CUSP::WeaponIdle()
if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN)
{
- SendWeaponAnim(USP_DRAW, UseDecrement());
+ SendWeaponAnim(USP_SHIELD_IDLE_UP, UseDecrement());
}
}
else if (m_iClip)
diff --git a/regamedll/game_shared/bot/bot_util.cpp b/regamedll/game_shared/bot/bot_util.cpp
index d14aaaeba..06b5b526f 100644
--- a/regamedll/game_shared/bot/bot_util.cpp
+++ b/regamedll/game_shared/bot/bot_util.cpp
@@ -613,6 +613,12 @@ void CONSOLE_ECHO_LOGGED(const char *pszMsg, ...)
void BotPrecache()
{
+#ifdef REGAMEDLL_FIXES
+ // all resources above are used between navarea, improved bots and tutor
+ // you can run cs1.6 with bots so it's not only limited to czero
+ if (!AreRunningCZero() && !AreBotsAllowed())
+ return;
+#endif
s_iBeamSprite = PRECACHE_MODEL("sprites/smoke.spr");
PRECACHE_SOUND("buttons/bell1.wav");
@@ -622,7 +628,11 @@ void BotPrecache()
PRECACHE_SOUND("buttons/latchunlocked2.wav");
PRECACHE_SOUND("buttons/lightswitch2.wav");
PRECACHE_SOUND("ambience/quail1.wav");
-
+#ifdef REGAMEDLL_FIXES
+ PRECACHE_GENERIC("sound/ambience/quail1.wav");
+#else
+ PRECACHE_SOUND("ambience/quail1.wav"); // not used internally
+#endif
PRECACHE_SOUND("events/tutor_msg.wav");
PRECACHE_SOUND("events/enemy_died.wav");
PRECACHE_SOUND("events/friend_died.wav");
diff --git a/regamedll/pm_shared/pm_shared.cpp b/regamedll/pm_shared/pm_shared.cpp
index 75d4a4909..b3b57fa5d 100644
--- a/regamedll/pm_shared/pm_shared.cpp
+++ b/regamedll/pm_shared/pm_shared.cpp
@@ -1967,7 +1967,9 @@ void PM_Duck()
}
}
-void PM_LadderMove(physent_t *pLadder)
+LINK_HOOK_VOID_CHAIN(PM_LadderMove, (physent_t *pLadder), pLadder);
+
+void EXT_FUNC __API_HOOK(PM_LadderMove)(physent_t *pLadder)
{
vec3_t ladderCenter;
trace_t trace;
diff --git a/regamedll/pm_shared/pm_shared.h b/regamedll/pm_shared/pm_shared.h
index 94113ae0a..da15fb5b0 100644
--- a/regamedll/pm_shared/pm_shared.h
+++ b/regamedll/pm_shared/pm_shared.h
@@ -77,12 +77,14 @@ void PM_Init(struct playermove_s *ppmove);
void PM_Move(struct playermove_s *ppmove, int server);
char PM_FindTextureType(char *name);
void PM_AirMove_internal();
+void PM_LadderMove(physent_t *pLadder);
#ifdef REGAMEDLL_API
void PM_Init_OrigFunc(struct playermove_s *ppmove);
void PM_Move_OrigFunc(struct playermove_s *ppmove, int server);
void PM_AirMove_OrigFunc(int playerIndex = 0);
void PM_UpdateStepSound_OrigFunc();
+void PM_LadderMove_OrigFunc(physent_t *pLadder);
#else
void PM_AirMove(int playerIndex = 0);
#endif
diff --git a/regamedll/public/regamedll/API/CSPlayer.h b/regamedll/public/regamedll/API/CSPlayer.h
index 8410d95f7..8648a0816 100644
--- a/regamedll/public/regamedll/API/CSPlayer.h
+++ b/regamedll/public/regamedll/API/CSPlayer.h
@@ -49,7 +49,8 @@ class CCSPlayer: public CCSMonster {
m_bGameForcingRespawn(false),
m_bAutoBunnyHopping(false),
m_bMegaBunnyJumping(false),
- m_bPlantC4Anywhere(false)
+ m_bPlantC4Anywhere(false),
+ m_bSpawnProtectionEffects(false)
{
m_szModel[0] = '\0';
}
@@ -61,8 +62,8 @@ class CCSPlayer: public CCSMonster {
virtual CBaseEntity *GiveNamedItemEx(const char *pszName);
virtual void GiveDefaultItems();
virtual void GiveShield(bool bDeploy = true);
- virtual void DropShield(bool bDeploy = true);
- virtual void DropPlayerItem(const char *pszItemName);
+ virtual CBaseEntity *DropShield(bool bDeploy = true);
+ virtual CBaseEntity *DropPlayerItem(const char *pszItemName);
virtual bool RemoveShield();
virtual void RemoveAllItems(bool bRemoveSuit);
virtual bool RemovePlayerItem(const char* pszItemName);
@@ -99,8 +100,11 @@ class CCSPlayer: public CCSMonster {
virtual void SetSpawnProtection(float flProtectionTime);
virtual void RemoveSpawnProtection();
virtual bool HintMessageEx(const char *pMessage, float duration = 6.0f, bool bDisplayIfPlayerDead = false, bool bOverride = false);
+ virtual void Reset();
+ virtual void OnSpawnEquip(bool addDefault = true, bool equipGame = true);
+ virtual void SetScoreboardAttributes(CBasePlayer *destination = nullptr);
- void Reset();
+ void ResetVars();
void OnSpawn();
void OnKilled();
@@ -131,6 +135,7 @@ class CCSPlayer: public CCSMonster {
bool m_bAutoBunnyHopping;
bool m_bMegaBunnyJumping;
bool m_bPlantC4Anywhere;
+ bool m_bSpawnProtectionEffects;
};
// Inlines
diff --git a/regamedll/public/regamedll/regamedll_api.h b/regamedll/public/regamedll/regamedll_api.h
index ba7a8517c..bfd6caf25 100644
--- a/regamedll/public/regamedll/regamedll_api.h
+++ b/regamedll/public/regamedll/regamedll_api.h
@@ -38,7 +38,7 @@
#include
#define REGAMEDLL_API_VERSION_MAJOR 5
-#define REGAMEDLL_API_VERSION_MINOR 21
+#define REGAMEDLL_API_VERSION_MINOR 22
// CBasePlayer::Spawn hook
typedef IHookChainClass IReGameHook_CBasePlayer_Spawn;
@@ -520,6 +520,14 @@ typedef IHookChainRegistryClass IReGameHookRegistry_CBa
typedef IHookChainClass IReGameHook_CBasePlayer_JoiningThink;
typedef IHookChainRegistryClass IReGameHookRegistry_CBasePlayer_JoiningThink;
+// FreeGameRules hook
+typedef IHookChain IReGameHook_FreeGameRules;
+typedef IHookChainRegistry IReGameHookRegistry_FreeGameRules;
+
+// PM_LadderMove hook
+typedef IHookChain IReGameHook_PM_LadderMove;
+typedef IHookChainRegistry IReGameHookRegistry_PM_LadderMove;
+
class IReGameHookchains {
public:
virtual ~IReGameHookchains() {}
@@ -653,6 +661,9 @@ class IReGameHookchains {
virtual IReGameHookRegistry_CBasePlayer_Pain *CBasePlayer_Pain() = 0;
virtual IReGameHookRegistry_CBasePlayer_DeathSound *CBasePlayer_DeathSound() = 0;
virtual IReGameHookRegistry_CBasePlayer_JoiningThink *CBasePlayer_JoiningThink() = 0;
+
+ virtual IReGameHookRegistry_FreeGameRules *FreeGameRules() = 0;
+ virtual IReGameHookRegistry_PM_LadderMove *PM_LadderMove() = 0;
};
struct ReGameFuncs_t {
@@ -670,6 +681,9 @@ struct ReGameFuncs_t {
class CGrenade *(*PlantBomb)(entvars_t *pevOwner, Vector &vecStart, Vector &vecVelocity);
class CGib *(*SpawnHeadGib)(entvars_t* pevVictim);
void (*SpawnRandomGibs)(entvars_t* pevVictim, int cGibs, int human);
+ void (*UTIL_RestartOther)(const char *szClassname);
+ void (*UTIL_ResetEntities)();
+ void (*UTIL_RemoveOther)(const char *szClassname, int nCount);
};
class IReGameApi {
diff --git a/regamedll/version/version.h b/regamedll/version/version.h
index ba22bb751..b65ba1ab2 100644
--- a/regamedll/version/version.h
+++ b/regamedll/version/version.h
@@ -6,5 +6,5 @@
#pragma once
#define VERSION_MAJOR 5
-#define VERSION_MINOR 21
+#define VERSION_MINOR 22
#define VERSION_MAINTENANCE 0