Related #57 (Done)

Added more weapon's for armoury_entity
Added ability for mp_buytime -1, means no time limit.
This commit is contained in:
s1lentq 2016-10-07 19:19:51 +07:00
parent 42edf0ebec
commit 084512e267
18 changed files with 416 additions and 146 deletions

View File

@ -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)<br/>`0` disabled <br/>`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)<br />`-1` means no time limit<br />`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)<br/>`0` disabled<br/>`1` enabled<br/><br/>or flags<br/>`a` block round time round end check<br/>`b` block needed players round end check<br/>`c` block VIP assassination/success round end check<br/>`d` block prison escape round end check<br/>`e` block bomb round end check<br/>`f` block team extermination round end check<br/>`g` block hostage rescue round end check<br/><br/>`Example setting:` "ae" blocks round time and bomb round end checks |
| mp_hegrenade_penetration | 0 | 0 | 1 | Disable grenade damage through walls<br/>`0` disabled<br/>`1` enabled |
| mp_nadedrops | 0 | 0 | 2 | Drop a grenade after player death<br/>`0` disabled<br/>`1` drop one the grenade<br/>`2` drop a everyone grenades |

7
dist/game.cfg vendored
View File

@ -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"

View File

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

View File

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

View File

@ -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;
}
}

View File

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

View File

@ -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><TERRORIST>\" 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><TERRORIST>\" 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<CCSPlayer>((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<CCSPlayer>((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;

View File

@ -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<typename Functor>
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<typename Functor>
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 };

View File

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

View File

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

View File

@ -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
}
}

View File

@ -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

View File

@ -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

View File

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

View File

@ -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<typename Functor>
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<typename Functor>
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 };

View File

@ -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

View File

@ -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

View File

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