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);