diff --git a/README.md b/README.md
index 1d959aac..3c3108b9 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,8 @@ Archive's bin directory contains 2 subdirectories, 'bugfixed' and 'pure'
| CVar | Default | Min | Max | Description |
| :---------------------------- | :-----: | :-: | :----------: | :--------------------------------------------- |
| mp_freeforall | 0 | 0 | 1 | The style of gameplay where there aren't any teams (FFA mode)
`0` disabled
`1` enabled |
-| mp_maxmoney | 16000 | 0 | `0x7FFFFFFF` | The maximum allowable amount of money in the game
+| mp_buytime | 1.5 | 0.0 | - | Designate the desired amount of buy time for each round. (in minutes)
`-1` means no time limit
`0` disable buy |
+| mp_maxmoney | 16000 | 0 | `0x7FFFFFFF` | The maximum allowable amount of money in the game |
| mp_round_infinite | 0 | 0 | 1 | Flags for fine grained control (choose as many as needed)
`0` disabled
`1` enabled
or flags
`a` block round time round end check
`b` block needed players round end check
`c` block VIP assassination/success round end check
`d` block prison escape round end check
`e` block bomb round end check
`f` block team extermination round end check
`g` block hostage rescue round end check
`Example setting:` "ae" blocks round time and bomb round end checks |
| 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 one the grenade
`2` drop a everyone grenades |
diff --git a/dist/game.cfg b/dist/game.cfg
index ef446f91..0331fda4 100644
--- a/dist/game.cfg
+++ b/dist/game.cfg
@@ -8,6 +8,13 @@ echo Executing ReGameDLL Configuration File
// Default value: "0"
mp_freeforall 0
+// Designate the desired amount of buy time for each round. (in minutes)
+// -1 - means no time limit
+// 0 - disable buy
+//
+// Default value: "1.5"
+mp_buytime 0.25
+
// The maximum allowable amount of money in the game
//
// Default value: "16000"
diff --git a/regamedll/dlls/cbase.h b/regamedll/dlls/cbase.h
index 7160bc9e..9f678661 100644
--- a/regamedll/dlls/cbase.h
+++ b/regamedll/dlls/cbase.h
@@ -49,6 +49,8 @@
#define FCAP_ONOFF_USE 0x00000020 // can be used by the player
#define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains)
#define FCAP_MASTER 0x00000080 // Can be used to "master" other entities (like multisource)
+#define FCAP_MUST_RESET 0x00000100 // should reset on the new round
+#define FCAP_MUST_RELEASE 0x00000200 // should release on the new round
// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!!
#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions
@@ -257,7 +259,13 @@ public:
virtual int DamageDecal(int bitsDamageType);
virtual void SetToggleState(int state) {}
virtual void StartSneaking() {}
+
+#ifndef REGAMEDLL_FIXES
virtual void StopSneaking() {}
+#else
+ virtual void UpdateOnRemove();
+#endif
+
virtual BOOL OnControls(entvars_t *onpev) { return FALSE; }
virtual BOOL IsSneaking() { return FALSE; }
virtual BOOL IsAlive() { return (pev->deadflag == DEAD_NO && pev->health > 0.0f); }
@@ -314,7 +322,10 @@ public:
void operator delete(void *pMem, entvars_t *pevnew) { pevnew->flags |= FL_KILLME; }
#endif
+#ifndef REGAMEDLL_FIXES
void UpdateOnRemove();
+#endif
+
void EXPORT SUB_Remove();
void EXPORT SUB_DoNothing();
void EXPORT SUB_StartFadeOut();
diff --git a/regamedll/dlls/client.cpp b/regamedll/dlls/client.cpp
index b3b93343..4525039b 100644
--- a/regamedll/dlls/client.cpp
+++ b/regamedll/dlls/client.cpp
@@ -429,7 +429,12 @@ void EXT_FUNC ClientPutInServer(edict_t *pEntity)
CheckStartMoney();
+#ifdef REGAMEDLL_ADD
+ pPlayer->AddAccount(startmoney.value, RT_PLAYER_JOIN);
+#else
pPlayer->m_iAccount = int(startmoney.value);
+#endif
+
pPlayer->m_fGameHUDInitialized = FALSE;
pPlayer->m_flDisplayHistory &= ~DHF_ROUND_STARTED;
pPlayer->pev->flags |= FL_SPECTATOR;
@@ -1606,12 +1611,16 @@ BOOL __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *player, int slot)
player->m_iJoiningState = JOINED;
// Reset money
+#ifdef REGAMEDLL_ADD
+ player->AddAccount(0, RT_PLAYER_SPEC_JOIN, false);
+#else
player->m_iAccount = 0;
MESSAGE_BEGIN(MSG_ONE, gmsgMoney, NULL, player->pev);
WRITE_LONG(player->m_iAccount);
WRITE_BYTE(0);
MESSAGE_END();
+#endif
#ifndef REGAMEDLL_FIXES
MESSAGE_BEGIN(MSG_BROADCAST, gmsgScoreInfo);
@@ -1745,7 +1754,11 @@ BOOL __API_HOOK(HandleMenu_ChooseTeam)(CBasePlayer *player, int slot)
CheckStartMoney();
// all players start with "mp_startmoney" bucks
+#ifdef REGAMEDLL_ADD
+ player->AddAccount(startmoney.value, RT_PLAYER_SPEC_JOIN, false);
+#else
player->m_iAccount = int(startmoney.value);
+#endif
player->pev->solid = SOLID_NOT;
player->pev->movetype = MOVETYPE_NOCLIP;
diff --git a/regamedll/dlls/items.cpp b/regamedll/dlls/items.cpp
index 8f908b2b..efed8ea9 100644
--- a/regamedll/dlls/items.cpp
+++ b/regamedll/dlls/items.cpp
@@ -502,6 +502,17 @@ ItemID GetItemIdByArmoury(ArmouryItemPack armoury)
case ARMOURY_KEVLAR: return ITEM_KEVLAR;
case ARMOURY_ASSAULT: return ITEM_ASSAULT;
case ARMOURY_SMOKEGRENADE: return ITEM_SMOKEGRENADE;
+ case ARMOURY_SHIELD: return ITEM_SHIELDGUN;
+ case ARMOURY_GLOCK18: return ITEM_GLOCK18;
+ case ARMOURY_USP: return ITEM_USP;
+ case ARMOURY_ELITE: return ITEM_ELITE;
+ case ARMOURY_FIVESEVEN: return ITEM_FIVESEVEN;
+ case ARMOURY_P228: return ITEM_P228;
+ case ARMOURY_DEAGLE: return ITEM_DEAGLE;
+ case ARMOURY_FAMAS: return ITEM_FAMAS;
+ case ARMOURY_SG550: return ITEM_SG550;
+ case ARMOURY_GALIL: return ITEM_GALIL;
+ case ARMOURY_UMP45: return ITEM_UMP45;
default: return ITEM_NONE;
}
}
diff --git a/regamedll/dlls/multiplay_gamerules.cpp b/regamedll/dlls/multiplay_gamerules.cpp
index 9d336100..0e19de56 100644
--- a/regamedll/dlls/multiplay_gamerules.cpp
+++ b/regamedll/dlls/multiplay_gamerules.cpp
@@ -665,6 +665,12 @@ LINK_HOOK_CLASS_VOID_CUSTOM_CHAIN2(CHalfLifeMultiplay, CSGameRules, CleanUpMap);
void CHalfLifeMultiplay::__API_VHOOK(CleanUpMap)()
{
+#ifdef REGAMEDLL_FIXES
+ // Release or reset everything entities in depending of flags ObjectCaps
+ // (FCAP_MUST_RESET / FCAP_MUST_RELEASE)
+ UTIL_ResetEntities();
+#endif
+
// Recreate all the map entities from the map data (preserving their indices),
// then remove everything else except the players.
UTIL_RestartOther("cycler_sprite");
diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp
index bb220b1e..89132360 100644
--- a/regamedll/dlls/player.cpp
+++ b/regamedll/dlls/player.cpp
@@ -3192,18 +3192,46 @@ NOXREF void CBasePlayer::ThrowPrimary()
LINK_HOOK_CLASS_VOID_CHAIN(CBasePlayer, AddAccount, (int amount, RewardType type, bool bTrackChange), amount, type, bTrackChange);
+#ifdef REGAMEDLL_ADD
+void CBasePlayer::__API_HOOK(AddAccount)(int amount, RewardType type, bool bTrackChange)
+{
+ bool bSendMoney = true;
+ switch (type)
+ {
+ case RT_INTO_GAME:
+ case RT_PLAYER_JOIN:
+ bSendMoney = false;
+ case RT_PLAYER_RESET:
+ case RT_PLAYER_SPEC_JOIN:
+ m_iAccount = 0;
+ break;
+ }
+
+ m_iAccount += amount;
+
+ if (bSendMoney)
+ {
+ auto nMax = int(maxmoney.value);
+ if (m_iAccount > nMax)
+ m_iAccount = nMax;
+
+ else if (m_iAccount < 0)
+ m_iAccount = 0;
+
+ // Send money update to HUD
+ MESSAGE_BEGIN(MSG_ONE, gmsgMoney, NULL, pev);
+ WRITE_LONG(m_iAccount);
+ WRITE_BYTE(bTrackChange);
+ MESSAGE_END();
+ }
+}
+#else
void CBasePlayer::__API_HOOK(AddAccount)(int amount, RewardType type, bool bTrackChange)
{
m_iAccount += amount;
-#ifndef REGAMEDLL_ADD
if (m_iAccount > 16000)
m_iAccount = 16000;
-#else
- auto nMax = int(maxmoney.value);
- if (m_iAccount > nMax)
- m_iAccount = nMax;
-#endif
else if (m_iAccount < 0)
m_iAccount = 0;
@@ -3214,6 +3242,7 @@ void CBasePlayer::__API_HOOK(AddAccount)(int amount, RewardType type, bool bTrac
WRITE_BYTE(bTrackChange);
MESSAGE_END();
}
+#endif
void CBasePlayer::ResetMenu()
{
@@ -3412,7 +3441,9 @@ void CBasePlayer::JoiningThink()
if (CSGameRules()->m_bMapHasEscapeZone && m_iTeam == CT)
{
+#ifndef REGAMEDLL_ADD
m_iAccount = 0;
+#endif
CheckStartMoney();
AddAccount(startmoney.value, RT_INTO_GAME);
}
@@ -4128,7 +4159,11 @@ void CBasePlayer::__API_VHOOK(AddPoints)(int score, BOOL bAllowNegativeScore)
pev->frags += score;
+#ifdef REGAMEDLL_FIXES
+ MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo);
+#else
MESSAGE_BEGIN(MSG_BROADCAST, gmsgScoreInfo);
+#endif
WRITE_BYTE(ENTINDEX(edict()));
WRITE_SHORT(int(pev->frags));
WRITE_SHORT(m_iDeaths);
@@ -4183,7 +4218,11 @@ bool CBasePlayer::CanPlayerBuy(bool display)
CVAR_SET_FLOAT("mp_buytime", (MIN_BUY_TIME / 60.0f));
}
- if (gpGlobals->time - CSGameRules()->m_fRoundStartTime > buyTime)
+ if (gpGlobals->time - CSGameRules()->m_fRoundStartTime > buyTime
+#ifdef REGAMEDLL_ADD
+ && buytime.value != -1.0f
+#endif
+)
{
if (display)
{
@@ -5622,7 +5661,10 @@ void CBasePlayer::Reset()
{
pev->frags = 0;
m_iDeaths = 0;
+
+#ifndef REGAMEDLL_ADD
m_iAccount = 0;
+#endif
#ifndef REGAMEDLL_FIXES
MESSAGE_BEGIN(MSG_ONE, gmsgMoney, NULL, pev);
@@ -5709,33 +5751,12 @@ void CBasePlayer::SelectItem(const char *pstr)
return;
}
- CBasePlayerItem *pItem = NULL;
-
- for (int i = 0; i < MAX_ITEM_TYPES; ++i)
- {
- pItem = m_rgpPlayerItems[ i ];
-
- if (pItem != NULL)
- {
- while (pItem != NULL)
- {
- if (FClassnameIs(pItem->pev, pstr))
- break;
-
- pItem = pItem->m_pNext;
- }
-
- if (pItem != NULL)
- {
- break;
- }
- }
- }
+ auto pItem = ForEachItem([this, pstr](CBasePlayerItem *item) {
+ return FClassnameIs(item->pev, pstr);
+ });
if (!pItem || pItem == m_pActiveItem)
- {
return;
- }
ResetAutoaim();
@@ -7397,14 +7418,16 @@ void CBasePlayer::__API_HOOK(DropPlayerItem)(const char *pszItemName)
return;
}
+#ifndef REGAMEDLL_FIXES
+ CBasePlayerItem *pWeapon = NULL;
for (int i = 0; i < MAX_ITEM_TYPES; ++i)
{
- CBasePlayerItem *pWeapon = m_rgpPlayerItems[i];
+ pWeapon = m_rgpPlayerItems[i];
while (pWeapon)
{
if (pszItemName)
{
- if (!Q_strcmp(pszItemName, STRING(pWeapon->pev->classname)))
+ if (FClassnameIs(pWeapon->pev, pszItemName))
break;
}
else
@@ -7417,106 +7440,109 @@ void CBasePlayer::__API_HOOK(DropPlayerItem)(const char *pszItemName)
}
if (pWeapon)
+ break;
+ }
+#else
+ auto pWeapon = pszItemName ? GetItemByName(pszItemName) : m_pActiveItem;
+#endif
+ if (pWeapon)
+ {
+ if (!pWeapon->CanDrop())
{
- if (!pWeapon->CanDrop())
+ ClientPrint(pev, HUD_PRINTCENTER, "#Weapon_Cannot_Be_Dropped");
+ return;
+ }
+
+ // take item off hud
+ pev->weapons &= ~(1 << pWeapon->m_iId);
+ g_pGameRules->GetNextBestWeapon(this, pWeapon);
+ UTIL_MakeVectors(pev->angles);
+
+ if (pWeapon->iItemSlot() == PRIMARY_WEAPON_SLOT)
+ m_bHasPrimary = false;
+
+ if (FClassnameIs(pWeapon->pev, "weapon_c4"))
+ {
+ m_bHasC4 = false;
+ pev->body = 0;
+ SetBombIcon(FALSE);
+ pWeapon->m_pPlayer->SetProgressBarTime(0);
+
+ if (!CSGameRules()->m_flRestartRoundTime)
{
- ClientPrint(pev, HUD_PRINTCENTER, "#Weapon_Cannot_Be_Dropped");
- continue;
- }
+ UTIL_LogPrintf("\"%s<%i><%s>\" triggered \"Dropped_The_Bomb\"\n", STRING(pev->netname), GETPLAYERUSERID(edict()), GETPLAYERAUTHID(edict()));
+ g_pGameRules->m_bBombDropped = TRUE;
- // take item off hud
- pev->weapons &= ~(1 << pWeapon->m_iId);
- g_pGameRules->GetNextBestWeapon(this, pWeapon);
- UTIL_MakeVectors(pev->angles);
-
- if (pWeapon->iItemSlot() == PRIMARY_WEAPON_SLOT)
- m_bHasPrimary = false;
-
- if (FClassnameIs(pWeapon->pev, "weapon_c4"))
- {
- m_bHasC4 = false;
- pev->body = 0;
- SetBombIcon(FALSE);
- pWeapon->m_pPlayer->SetProgressBarTime(0);
-
- if (!CSGameRules()->m_flRestartRoundTime)
+ CBaseEntity *pEntity = NULL;
+ while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")) != NULL)
{
- UTIL_LogPrintf("\"%s<%i><%s>\" triggered \"Dropped_The_Bomb\"\n", STRING(pev->netname), GETPLAYERUSERID(edict()), GETPLAYERAUTHID(edict()));
- g_pGameRules->m_bBombDropped = TRUE;
+ if (FNullEnt(pEntity->edict()))
+ break;
- CBaseEntity *pEntity = NULL;
- while ((pEntity = UTIL_FindEntityByClassname(pEntity, "player")) != NULL)
+ if (!pEntity->IsPlayer())
+ continue;
+
+ if (pEntity->pev->flags != FL_DORMANT)
{
- if (FNullEnt(pEntity->edict()))
- break;
+ CBasePlayer *pOther = GetClassPtr((CBasePlayer *)pEntity->pev);
- if (!pEntity->IsPlayer())
- continue;
-
- if (pEntity->pev->flags != FL_DORMANT)
+ if (pOther->pev->deadflag == DEAD_NO && pOther->m_iTeam == TERRORIST)
{
- CBasePlayer *pOther = GetClassPtr((CBasePlayer *)pEntity->pev);
+ ClientPrint(pOther->pev, HUD_PRINTCENTER, "#Game_bomb_drop", STRING(pev->netname));
- if (pOther->pev->deadflag == DEAD_NO && pOther->m_iTeam == TERRORIST)
- {
- ClientPrint(pOther->pev, HUD_PRINTCENTER, "#Game_bomb_drop", STRING(pev->netname));
-
- MESSAGE_BEGIN(MSG_ONE, gmsgBombDrop, NULL, pOther->pev);
- WRITE_COORD(pev->origin.x);
- WRITE_COORD(pev->origin.y);
- WRITE_COORD(pev->origin.z);
- WRITE_BYTE(0);
- MESSAGE_END();
- }
+ MESSAGE_BEGIN(MSG_ONE, gmsgBombDrop, NULL, pOther->pev);
+ WRITE_COORD(pev->origin.x);
+ WRITE_COORD(pev->origin.y);
+ WRITE_COORD(pev->origin.z);
+ WRITE_BYTE(0);
+ MESSAGE_END();
}
}
}
}
+ }
- CWeaponBox *pWeaponBox = (CWeaponBox *)Create("weaponbox", pev->origin + gpGlobals->v_forward * 10, pev->angles, edict());
- pWeaponBox->pev->angles.x = 0;
- pWeaponBox->pev->angles.z = 0;
- pWeaponBox->SetThink(&CWeaponBox::Kill);
- pWeaponBox->pev->nextthink = gpGlobals->time + 300;
- pWeaponBox->PackWeapon(pWeapon);
- pWeaponBox->pev->velocity = gpGlobals->v_forward * 300 + gpGlobals->v_forward * 100;
+ CWeaponBox *pWeaponBox = (CWeaponBox *)Create("weaponbox", pev->origin + gpGlobals->v_forward * 10, pev->angles, edict());
+ pWeaponBox->pev->angles.x = 0;
+ pWeaponBox->pev->angles.z = 0;
+ pWeaponBox->SetThink(&CWeaponBox::Kill);
+ pWeaponBox->pev->nextthink = gpGlobals->time + 300;
+ pWeaponBox->PackWeapon(pWeapon);
+ pWeaponBox->pev->velocity = gpGlobals->v_forward * 300 + gpGlobals->v_forward * 100;
- if (FClassnameIs(pWeapon->pev, "weapon_c4"))
+ if (FClassnameIs(pWeapon->pev, "weapon_c4"))
+ {
+ pWeaponBox->m_bIsBomb = true;
+ pWeaponBox->SetThink(&CWeaponBox::BombThink);
+ pWeaponBox->pev->nextthink = gpGlobals->time + 1.0f;
+
+ if (TheCSBots() != NULL)
{
- pWeaponBox->m_bIsBomb = true;
- pWeaponBox->SetThink(&CWeaponBox::BombThink);
- pWeaponBox->pev->nextthink = gpGlobals->time + 1.0f;
-
- if (TheCSBots() != NULL)
- {
- // tell the bots about the dropped bomb
- TheCSBots()->SetLooseBomb(pWeaponBox);
- TheCSBots()->OnEvent(EVENT_BOMB_DROPPED);
- }
+ // tell the bots about the dropped bomb
+ TheCSBots()->SetLooseBomb(pWeaponBox);
+ TheCSBots()->OnEvent(EVENT_BOMB_DROPPED);
}
+ }
- if (pWeapon->iFlags() & ITEM_FLAG_EXHAUSTIBLE)
+ if (pWeapon->iFlags() & ITEM_FLAG_EXHAUSTIBLE)
+ {
+ int iAmmoIndex = GetAmmoIndex(pWeapon->pszAmmo1());
+ if (iAmmoIndex != -1)
{
- int iAmmoIndex = GetAmmoIndex(pWeapon->pszAmmo1());
- if (iAmmoIndex != -1)
- {
#ifdef REGAMEDLL_FIXES
- // why not pack the ammo more than one?
- pWeaponBox->PackAmmo(MAKE_STRING(pWeapon->pszAmmo1()), m_rgAmmo[iAmmoIndex]);
+ // why not pack the ammo more than one?
+ pWeaponBox->PackAmmo(MAKE_STRING(pWeapon->pszAmmo1()), m_rgAmmo[iAmmoIndex]);
#else
- pWeaponBox->PackAmmo(MAKE_STRING(pWeapon->pszAmmo1()), m_rgAmmo[iAmmoIndex] > 0);
+ pWeaponBox->PackAmmo(MAKE_STRING(pWeapon->pszAmmo1()), m_rgAmmo[iAmmoIndex] > 0);
#endif
- m_rgAmmo[iAmmoIndex] = 0;
- }
+ m_rgAmmo[iAmmoIndex] = 0;
}
+ }
- const char *modelname = GetCSModelName(pWeapon->m_iId);
- if (modelname != NULL)
- {
- SET_MODEL(ENT(pWeaponBox->pev), modelname);
- }
-
- return;
+ const char *modelname = GetCSModelName(pWeapon->m_iId);
+ if (modelname != NULL)
+ {
+ SET_MODEL(ENT(pWeaponBox->pev), modelname);
}
}
}
@@ -9401,15 +9427,13 @@ void CBasePlayer::DropSecondary()
m_bShieldDrawn = false;
}
- auto item = m_rgpPlayerItems[ PISTOL_SLOT ];
-
#ifdef REGAMEDLL_ADD
- while (item)
- {
+ ForEachItem(PISTOL_SLOT, [this](CBasePlayerItem *item) {
DropPlayerItem(STRING(item->pev->classname));
- item = item->m_pNext;
- }
+ return false;
+ });
#else
+ auto item = m_rgpPlayerItems[ PISTOL_SLOT ];
if (item)
{
DropPlayerItem(STRING(item->pev->classname));
@@ -9425,15 +9449,13 @@ void CBasePlayer::DropPrimary()
return;
}
- auto item = m_rgpPlayerItems[ PRIMARY_WEAPON_SLOT ];
-
#ifdef REGAMEDLL_ADD
- while (item)
- {
+ ForEachItem(PRIMARY_WEAPON_SLOT, [this](CBasePlayerItem *item) {
DropPlayerItem(STRING(item->pev->classname));
- item = item->m_pNext;
- }
+ return false;
+ });
#else
+ auto item = m_rgpPlayerItems[ PRIMARY_WEAPON_SLOT ];
if (item)
{
DropPlayerItem(STRING(item->pev->classname));
@@ -9442,23 +9464,21 @@ void CBasePlayer::DropPrimary()
}
-CBasePlayerItem *CBasePlayer::GetItemOfNamed(const char *pszItemName)
-{
- for (auto pItem : m_rgpPlayerItems) {
- while (pItem) {
- if (FClassnameIs(pItem->pev, pszItemName))
- return pItem;
+CBasePlayerItem *CBasePlayer::GetItemByName(const char *itemName) {
+ return ForEachItem([this, itemName](CBasePlayerItem *item) {
+ return FClassnameIs(item->pev, itemName);
+ });
+}
- pItem = pItem->m_pNext;
- }
- }
-
- return nullptr;
+CBasePlayerItem *CBasePlayer::GetItemById(WeaponIdType weaponID) {
+ return ForEachItem([this, weaponID](CBasePlayerItem *item) {
+ return item->m_iId == weaponID;
+ });
}
void CBasePlayer::RemoveBomb()
{
- auto pBomb = GetItemOfNamed("weapon_c4");
+ auto pBomb = GetItemByName("weapon_c4");
if (!pBomb)
return;
diff --git a/regamedll/dlls/player.h b/regamedll/dlls/player.h
index 60d3f1a1..4689cee4 100644
--- a/regamedll/dlls/player.h
+++ b/regamedll/dlls/player.h
@@ -148,6 +148,8 @@ enum RewardType
RT_NONE,
RT_ROUND_BONUS,
RT_PLAYER_RESET,
+ RT_PLAYER_JOIN,
+ RT_PLAYER_SPEC_JOIN,
RT_PLAYER_BOUGHT_SOMETHING,
RT_HOSTAGE_TOOK,
RT_HOSTAGE_RESCUED,
@@ -365,7 +367,11 @@ public:
virtual BOOL RemovePlayerItem(CBasePlayerItem *pItem);
virtual int GiveAmmo(int iAmount, char *szName, int iMax);
virtual void StartSneaking() { m_tSneaking = gpGlobals->time - 1; }
+
+#ifndef REGAMEDLL_FIXES
virtual void StopSneaking() { m_tSneaking = gpGlobals->time + 30; }
+#endif
+
virtual BOOL IsSneaking() { return m_tSneaking <= gpGlobals->time; }
virtual BOOL IsAlive() { return (pev->deadflag == DEAD_NO && pev->health > 0.0f); }
virtual BOOL IsPlayer() { return (pev->flags & FL_SPECTATOR) != FL_SPECTATOR; }
@@ -604,12 +610,42 @@ public:
void DropPrimary();
void RemoveBomb();
- CBasePlayerItem *GetItemOfNamed(const char *pszItemName);
+ CBasePlayerItem *GetItemByName(const char *itemName);
+ CBasePlayerItem *GetItemById(WeaponIdType weaponID);
#ifdef REGAMEDLL_API
CCSPlayer *CSPlayer() const;
#endif
+ // templates
+ template
+ CBasePlayerItem *ForEachItem(int slot, const Functor &func)
+ {
+ auto item = m_rgpPlayerItems[ slot ];
+ while (item)
+ {
+ if (func(item))
+ return item;
+
+ item = item->m_pNext;
+ }
+ return nullptr;
+ }
+ template
+ CBasePlayerItem *ForEachItem(const Functor &func)
+ {
+ for (auto item : m_rgpPlayerItems)
+ {
+ while (item)
+ {
+ if (func(item))
+ return item;
+
+ item = item->m_pNext;
+ }
+ }
+ return nullptr;
+ }
public:
enum { MaxLocationLen = 32 };
diff --git a/regamedll/dlls/util.cpp b/regamedll/dlls/util.cpp
index d7395dab..d3b09d89 100644
--- a/regamedll/dlls/util.cpp
+++ b/regamedll/dlls/util.cpp
@@ -1471,6 +1471,31 @@ void UTIL_RestartOther(const char *szClassname)
}
}
+void UTIL_ResetEntities()
+{
+ edict_t *pEdict = INDEXENT(1);
+ for (int i = 1; i < gpGlobals->maxEntities; ++i, ++pEdict)
+ {
+ if (pEdict->free)
+ continue;
+
+ CBaseEntity *pEntity = CBaseEntity::Instance(pEdict);
+ if (!pEntity)
+ continue;
+
+ // only non-player entities
+ if (pEntity->IsPlayer())
+ continue;
+
+ int caps = pEntity->ObjectCaps();
+ if ((caps & FCAP_MUST_RELEASE) == FCAP_MUST_RELEASE)
+ UTIL_Remove(pEntity);
+
+ else if ((caps & FCAP_MUST_RESET) == FCAP_MUST_RESET)
+ pEntity->Restart();
+ }
+}
+
void UTIL_RemoveOther(const char *szClassname)
{
CBaseEntity *pEntity = nullptr;
diff --git a/regamedll/dlls/util.h b/regamedll/dlls/util.h
index 9123fb13..fca3a565 100644
--- a/regamedll/dlls/util.h
+++ b/regamedll/dlls/util.h
@@ -310,6 +310,7 @@ void UTIL_Remove(CBaseEntity *pEntity);
BOOL UTIL_IsValidEntity(edict_t *pent);
void UTIL_PrecacheOther(const char *szClassname);
void UTIL_RestartOther(const char *szClassname);
+void UTIL_ResetEntities();
void UTIL_RemoveOther(const char *szClassname);
void UTIL_LogPrintf(const char *fmt, ...);
float UTIL_DotPoints(const Vector &vecSrc, const Vector &vecCheck, const Vector &vecDir);
diff --git a/regamedll/dlls/weapons.cpp b/regamedll/dlls/weapons.cpp
index a0ead723..c8ff5e09 100644
--- a/regamedll/dlls/weapons.cpp
+++ b/regamedll/dlls/weapons.cpp
@@ -2102,7 +2102,21 @@ char *armouryItemModels[] = {
"models/w_kevlar.mdl",
"models/w_assault.mdl",
"models/w_smokegrenade.mdl",
- "models/w_kevlar.mdl",
+
+#ifdef REGAMEDLL_ADD
+ "models/w_shield.mdl",
+ "models/w_famas.mdl",
+ "models/w_sg550.mdl",
+ "models/w_galil.mdl",
+ "models/w_ump45.mdl",
+ "models/w_glock18.mdl",
+ "models/w_usp.mdl",
+ "models/w_elite.mdl",
+ "models/w_fiveseven.mdl",
+ "models/w_p228.mdl",
+ "models/w_deagle.mdl"
+#endif
+
};
void CArmoury::__MAKE_VHOOK(Spawn)()
@@ -2116,7 +2130,11 @@ void CArmoury::__MAKE_VHOOK(Spawn)()
UTIL_SetOrigin(pev, pev->origin);
SetTouch(&CArmoury::ArmouryTouch);
- SET_MODEL(ENT(pev), armouryItemModels[m_iItem]);
+
+ if (m_iItem < ARRAYSIZE(armouryItemModels))
+ {
+ SET_MODEL(ENT(pev), armouryItemModels[m_iItem]);
+ }
if (m_iCount <= 0)
{
@@ -2204,7 +2222,10 @@ void CArmoury::__MAKE_VHOOK(Restart)()
void CArmoury::__MAKE_VHOOK(Precache)()
{
- PRECACHE_MODEL(armouryItemModels[m_iItem]);
+ if (m_iItem < ARRAYSIZE(armouryItemModels))
+ {
+ PRECACHE_MODEL(armouryItemModels[m_iItem]);
+ }
}
void CArmoury::Draw()
@@ -2231,7 +2252,7 @@ struct ArmouryItemStruct
const char *entityName;
char *ammoName;
int giveAmount;
- MaxAmmoType maxRounds;
+ int maxRounds;
} armouryItemInfo[] = {
{ "weapon_mp5navy", "9mm", 60, MAX_AMMO_9MM }, // ARMOURY_MP5NAVY
{ "weapon_tmp", "9mm", 60, MAX_AMMO_9MM }, // ARMOURY_TMP
@@ -2247,6 +2268,24 @@ struct ArmouryItemStruct
{ "weapon_m3", "buckshot", 24, MAX_AMMO_BUCKSHOT }, // ARMOURY_M3
{ "weapon_xm1014", "buckshot", 24, MAX_AMMO_BUCKSHOT }, // ARMOURY_XM1014
{ "weapon_m249", "556NatoBox", 60, MAX_AMMO_556NATOBOX }, // ARMOURY_M249
+
+ { NULL, NULL, 0, 0 }, // ARMOURY_FLASHBANG
+ { NULL, NULL, 0, 0 }, // ARMOURY_HEGRENADE
+ { NULL, NULL, 0, 0 }, // ARMOURY_KEVLAR
+ { NULL, NULL, 0, 0 }, // ARMOURY_ASSAULT
+ { NULL, NULL, 0, 0 }, // ARMOURY_SMOKEGRENADE
+ { NULL, NULL, 0, 0 }, // ARMOURY_SHIELD
+
+ { "weapon_famas", "556Nato", 90, MAX_AMMO_556NATO }, // ARMOURY_FAMAS
+ { "weapon_sg550", "556Nato", 90, MAX_AMMO_556NATO }, // ARMOURY_SG550
+ { "weapon_galil", "556Nato", 90, MAX_AMMO_556NATO }, // ARMOURY_GALIL
+ { "weapon_ump45", "45acp", 100, MAX_AMMO_45ACP }, // ARMOURY_UMP45
+ { "weapon_glock18", "9mm", 120, MAX_AMMO_9MM }, // ARMOURY_GLOCK18
+ { "weapon_usp", "45acp", 100, MAX_AMMO_45ACP }, // ARMOURY_USP
+ { "weapon_elite", "9mm", 120, MAX_AMMO_9MM }, // ARMOURY_ELITE
+ { "weapon_fiveseven", "57mm", 100, MAX_AMMO_57MM }, // ARMOURY_FIVESEVEN
+ { "weapon_p228", "357SIG", 52, MAX_AMMO_357SIG }, // ARMOURY_P228
+ { "weapon_deagle", "50AE", 35, MAX_AMMO_50AE }, // ARMOURY_DEAGLE
};
void CArmoury::ArmouryTouch(CBaseEntity *pOther)
@@ -2264,8 +2303,12 @@ void CArmoury::ArmouryTouch(CBaseEntity *pOther)
return;
#endif
- // weapons
- if (m_iCount > 0 && m_iItem <= ARMOURY_M249)
+ // primary weapons
+ if (m_iCount > 0 && (m_iItem <= ARMOURY_M249
+#ifdef REGAMEDLL_ADD
+ || (m_iItem >= ARMOURY_FAMAS && m_iItem <= ARMOURY_UMP45)
+#endif
+))
{
if (p->m_bHasPrimary)
return;
@@ -2273,9 +2316,28 @@ void CArmoury::ArmouryTouch(CBaseEntity *pOther)
m_iCount--;
auto item = &armouryItemInfo[m_iItem];
+#ifdef REGAMEDLL_FIXES
+ p->GiveNamedItemEx(item->entityName);
+#else
p->GiveNamedItem(item->entityName);
+#endif
+
p->GiveAmmo(item->giveAmount, item->ammoName, item->maxRounds);
}
+#ifdef REGAMEDLL_ADD
+ // secondary weapons (pistols)
+ else if (m_iCount > 0 && m_iItem >= ARMOURY_GLOCK18)
+ {
+ if (p->m_rgpPlayerItems[ PISTOL_SLOT ])
+ return;
+
+ m_iCount--;
+ auto item = &armouryItemInfo[m_iItem];
+
+ p->GiveNamedItemEx(item->entityName);
+ p->GiveAmmo(item->giveAmount, item->ammoName, item->maxRounds);
+ }
+#endif
// items & grenades
else if (m_iCount > 0 && m_iItem >= ARMOURY_FLASHBANG)
{
@@ -2326,6 +2388,17 @@ void CArmoury::ArmouryTouch(CBaseEntity *pOther)
m_iCount--;
break;
}
+#ifdef REGAMEDLL_ADD
+ case ARMOURY_SHIELD:
+ {
+ if (p->m_bHasPrimary || (p->m_rgpPlayerItems[ PISTOL_SLOT ] && p->GetItemById(WEAPON_ELITE)))
+ return;
+
+ p->GiveNamedItemEx("weapon_shield");
+ m_iCount--;
+ break;
+ }
+#endif
}
}
diff --git a/regamedll/dlls/weapons.h b/regamedll/dlls/weapons.h
index 37fdcd51..da5c9b11 100644
--- a/regamedll/dlls/weapons.h
+++ b/regamedll/dlls/weapons.h
@@ -97,7 +97,18 @@ enum ArmouryItemPack
ARMOURY_HEGRENADE,
ARMOURY_KEVLAR,
ARMOURY_ASSAULT,
- ARMOURY_SMOKEGRENADE
+ ARMOURY_SMOKEGRENADE,
+ ARMOURY_SHIELD,
+ ARMOURY_FAMAS,
+ ARMOURY_SG550,
+ ARMOURY_GALIL,
+ ARMOURY_UMP45,
+ ARMOURY_GLOCK18,
+ ARMOURY_USP,
+ ARMOURY_ELITE,
+ ARMOURY_FIVESEVEN,
+ ARMOURY_P228,
+ ARMOURY_DEAGLE
};
struct ItemInfo
diff --git a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd
index cc26f276..0f0a843e 100644
--- a/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd
+++ b/regamedll/extra/Toolkit/GameDefinitionFile/regamedll-cs.fgd
@@ -994,6 +994,17 @@
16: "item_kevlar"
17: "item_assaultsuit"
18: "weapon_smokegrenade"
+ 19: "weapon_shield"
+ 20: "weapon_famas"
+ 21: "weapon_sg550"
+ 22: "weapon_galil"
+ 23: "weapon_ump45"
+ 24: "weapon_glock18"
+ 25: "weapon_usp"
+ 26: "weapon_elite"
+ 27: "weapon_fiveseven"
+ 28: "weapon_p228"
+ 29: "weapon_deagle"
]
// note: count always resets to only one item after first round
count(integer) : "Count" : 1
diff --git a/regamedll/extra/cssdk/dlls/cbase.h b/regamedll/extra/cssdk/dlls/cbase.h
index 5118f509..b187a08b 100644
--- a/regamedll/extra/cssdk/dlls/cbase.h
+++ b/regamedll/extra/cssdk/dlls/cbase.h
@@ -90,7 +90,7 @@ public:
// This is ONLY used by the node graph to test movement through a door
virtual void SetToggleState(int state) = 0;
virtual void StartSneaking() = 0;
- virtual void StopSneaking() = 0;
+ virtual void UpdateOnRemove() = 0;
virtual BOOL OnControls(entvars_t *onpev) = 0;
virtual BOOL IsSneaking() = 0;
virtual BOOL IsAlive() = 0;
diff --git a/regamedll/extra/cssdk/dlls/player.h b/regamedll/extra/cssdk/dlls/player.h
index 690cd93c..e3fc59cb 100644
--- a/regamedll/extra/cssdk/dlls/player.h
+++ b/regamedll/extra/cssdk/dlls/player.h
@@ -138,6 +138,8 @@ enum RewardType
RT_NONE,
RT_ROUND_BONUS,
RT_PLAYER_RESET,
+ RT_PLAYER_JOIN,
+ RT_PLAYER_SPEC_JOIN,
RT_PLAYER_BOUGHT_SOMETHING,
RT_HOSTAGE_TOOK,
RT_HOSTAGE_RESCUED,
@@ -320,7 +322,6 @@ public:
virtual BOOL RemovePlayerItem(CBasePlayerItem *pItem) = 0;
virtual int GiveAmmo(int iAmount, char *szName, int iMax) = 0;
virtual void StartSneaking() = 0;
- virtual void StopSneaking() = 0;
virtual BOOL IsSneaking() = 0;
virtual BOOL IsAlive() = 0;
virtual BOOL IsPlayer() = 0;
@@ -359,6 +360,36 @@ public:
void SetObserverAutoDirector(bool val) { m_bObserverAutoDirector = val; }
bool CanSwitchObserverModes() const { return m_canSwitchObserverModes; }
CCSPlayer *CSPlayer() const;
+
+ // templates
+ template
+ CBasePlayerItem *ForEachItem(int slot, const Functor &func)
+ {
+ auto item = m_rgpPlayerItems[ slot ];
+ while (item)
+ {
+ if (func(item))
+ return item;
+
+ item = item->m_pNext;
+ }
+ return nullptr;
+ }
+ template
+ CBasePlayerItem *ForEachItem(const Functor &func)
+ {
+ for (auto item : m_rgpPlayerItems)
+ {
+ while (item)
+ {
+ if (func(item))
+ return item;
+
+ item = item->m_pNext;
+ }
+ }
+ return nullptr;
+ }
public:
enum { MaxLocationLen = 32 };
diff --git a/regamedll/extra/cssdk/dlls/regamedll_const.h b/regamedll/extra/cssdk/dlls/regamedll_const.h
index 36d038b9..87945b05 100644
--- a/regamedll/extra/cssdk/dlls/regamedll_const.h
+++ b/regamedll/extra/cssdk/dlls/regamedll_const.h
@@ -37,6 +37,8 @@
#define FCAP_ONOFF_USE 0x00000020 // can be used by the player
#define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains)
#define FCAP_MASTER 0x00000080 // Can be used to "master" other entities (like multisource)
+#define FCAP_MUST_RESET 0x00000100 // should reset on the new round
+#define FCAP_MUST_RELEASE 0x00000200 // should release on the new round
// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!!
#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions
diff --git a/regamedll/extra/cssdk/dlls/weapons.h b/regamedll/extra/cssdk/dlls/weapons.h
index e17cc27a..e3eddd81 100644
--- a/regamedll/extra/cssdk/dlls/weapons.h
+++ b/regamedll/extra/cssdk/dlls/weapons.h
@@ -92,7 +92,18 @@ enum ArmouryItemPack
ARMOURY_HEGRENADE,
ARMOURY_KEVLAR,
ARMOURY_ASSAULT,
- ARMOURY_SMOKEGRENADE
+ ARMOURY_SMOKEGRENADE,
+ ARMOURY_GLOCK18,
+ ARMOURY_USP,
+ ARMOURY_ELITE,
+ ARMOURY_FIVESEVEN,
+ ARMOURY_P228,
+ ARMOURY_DEAGLE,
+ ARMOURY_FAMAS,
+ ARMOURY_SG550,
+ ARMOURY_GALIL,
+ ARMOURY_UMP45,
+ ARMOURY_SHIELD
};
struct ItemInfo
diff --git a/regamedll/regamedll/regamedll_interfaces_impl.cpp b/regamedll/regamedll/regamedll_interfaces_impl.cpp
index 102ecea9..f0d92455 100644
--- a/regamedll/regamedll/regamedll_interfaces_impl.cpp
+++ b/regamedll/regamedll/regamedll_interfaces_impl.cpp
@@ -114,7 +114,7 @@ bool EXT_FUNC CCSPlayer::JoinTeam(TeamName team)
pPlayer->pev->frags++;
}
- MESSAGE_BEGIN(MSG_BROADCAST, gmsgScoreInfo);
+ MESSAGE_BEGIN(MSG_ALL, gmsgScoreInfo);
WRITE_BYTE(ENTINDEX(pPlayer->edict()));
WRITE_SHORT(int(pPlayer->pev->frags));
WRITE_SHORT(pPlayer->m_iDeaths);