Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/game/client/neo/game_controls/neo_loadoutmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ void CNeoLoadoutMenu::OnMousePressed(vgui::MouseCode code)

extern ConCommand loadoutmenu;

extern ConVar sv_neo_ignore_wep_xp_limit;
extern ConVar sv_neo_dev_loadout;

void CNeoLoadoutMenu::OnClose()
Expand Down Expand Up @@ -227,7 +226,7 @@ void CNeoLoadoutMenu::OnCommand(const char* command)
auto localPlayer = C_NEO_Player::GetLocalNEOPlayer();
if (!localPlayer) { return; }

int currentXP = localPlayer->m_iXP.Get();
int currentXP = CNEOWeaponLoadout::GetEffectiveXP(localPlayer->m_iXP.Get());
int currentClass = localPlayer->m_iNextSpawnClassChoice.Get() != NEO_CLASS_RANDOM ? localPlayer->m_iNextSpawnClassChoice.Get() : localPlayer->m_iNeoClass.Get();
int numWeapons = CNEOWeaponLoadout::GetNumberOfLoadoutWeapons(currentXP,
sv_neo_dev_loadout.GetBool() ? NEO_LOADOUT_DEV : currentClass);
Expand Down Expand Up @@ -295,7 +294,7 @@ void CNeoLoadoutMenu::ApplySchemeSettings(vgui::IScheme *pScheme)
auto localPlayer = C_NEO_Player::GetLocalNEOPlayer();
if (!localPlayer) { return; }

const int currentXP = localPlayer->m_iXP.Get();
const int currentXP = CNEOWeaponLoadout::GetEffectiveXP(localPlayer->m_iXP.Get());
const int currentClass = localPlayer->m_iNextSpawnClassChoice.Get() != NEO_CLASS_RANDOM ? localPlayer->m_iNextSpawnClassChoice.Get() : localPlayer->m_iNeoClass.Get();

int iLoadout = sv_neo_dev_loadout.GetBool() ? NEO_LOADOUT_DEV : currentClass;
Expand Down
5 changes: 3 additions & 2 deletions src/game/server/neo/bot/neo_bot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,8 @@ void CNEOBot::Spawn()

int CNEOBot::ChooseRandomWeaponIndex() const
{
const ENeoRank eRank = static_cast<ENeoRank>(GetRank(m_iXP) - 1);
const int iEffectiveXP = CNEOWeaponLoadout::GetEffectiveXP(m_iXP);
const ENeoRank eRank = static_cast<ENeoRank>(GetRank(iEffectiveXP) - 1);
if (eRank == NEO_RANK_RANKLESS_DOG || (false == IN_BETWEEN_EQ(NEO_CLASS_RECON, m_iNeoClass, NEO_CLASS_VIP)))
{
return 0;
Expand All @@ -665,7 +666,7 @@ int CNEOBot::ChooseRandomWeaponIndex() const
// Generally shouldn't happen, but if so, just pick from any under the XP limit
for (int i = 0; i < MAX_WEAPON_LOADOUTS; ++i)
{
if (CNEOWeaponLoadout::s_LoadoutWeapons[m_iNeoClass][i].m_iWeaponPrice > m_iXP)
if (CNEOWeaponLoadout::s_LoadoutWeapons[m_iNeoClass][i].m_iWeaponPrice > iEffectiveXP)
{
break;
}
Expand Down
40 changes: 18 additions & 22 deletions src/game/server/neo/neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@ CNEOGameRulesProxy* neoGameRules;
extern CBaseEntity *g_pLastSpawn;

extern ConVar sv_neo_bot_cmdr_enable;
extern ConVar sv_neo_ignore_wep_xp_limit;
extern ConVar sv_neo_clantag_allow;
extern ConVar sv_neo_detpack_xp_limit;
extern ConVar sv_neo_dev_test_clantag;
extern ConVar sv_stickysprint;
extern ConVar sv_neo_dev_loadout;
Expand Down Expand Up @@ -389,9 +389,8 @@ bool CNEO_Player::RequestSetLoadout(int loadoutNumber)
result = false;
}

if (!sv_neo_ignore_wep_xp_limit.GetBool() &&
loadoutNumber+1 > CNEOWeaponLoadout::GetNumberOfLoadoutWeapons(m_iXP,
sv_neo_dev_loadout.GetBool() ? NEO_LOADOUT_DEV : classChosen))
if (loadoutNumber+1 > CNEOWeaponLoadout::GetNumberOfLoadoutWeapons(CNEOWeaponLoadout::GetEffectiveXP(m_iXP),
sv_neo_dev_loadout.GetBool() ? NEO_LOADOUT_DEV : classChosen))
{
DevMsg("Insufficient XP for %s\n", pszWepName);
result = RequestSetLoadout(0);
Expand Down Expand Up @@ -3475,6 +3474,15 @@ CBaseEntity* CNEO_Player::GiveNamedItem(const char* szName, int iSubType)

void GiveDet(CNEO_Player* pPlayer)
{
// Cost of -1 XP means no XP cost. Checked before creating the weapon
// entity so ineligible players don't pay a create/destroy cycle.
const int detXpCost = sv_neo_detpack_xp_limit.GetInt();
const bool canHaveDet = (detXpCost < 0 || CNEOWeaponLoadout::GetEffectiveXP(pPlayer->m_iXP) >= detXpCost);
if (!canHaveDet)
{
return;
}

constexpr const char* detpackClassname = "weapon_remotedet";
if (!pPlayer->Weapon_OwnsThisType(detpackClassname))
{
Expand All @@ -3492,23 +3500,12 @@ void GiveDet(CNEO_Player* pPlayer)
auto pWeapon = assert_cast<CNEOBaseCombatWeapon*>((CBaseEntity*)pent);
if (pWeapon)
{
const int detXpCost = pWeapon->GetNeoWepXPCost(pPlayer->GetClass());
// Cost of -1 XP means no XP cost.
const bool canHaveDet = (detXpCost < 0 || pPlayer->m_iXP >= detXpCost);

pWeapon->SetSubType(0);
if (canHaveDet)
{
DispatchSpawn(pent);
DispatchSpawn(pent);

if (pent != NULL && !(pent->IsMarkedForDeletion()))
{
pent->Touch(pPlayer);
}
}
else
if (pent != NULL && !(pent->IsMarkedForDeletion()))
{
UTIL_Remove(pWeapon);
pent->Touch(pPlayer);
}
}
}
Expand All @@ -3522,7 +3519,7 @@ void CNEO_Player::GiveDefaultItems(void)
case NEO_CLASS_RECON:
GiveNamedItem("weapon_knife");
GiveNamedItem("weapon_milso");
if (this->m_iXP >= 4) { GiveDet(this); }
GiveDet(this);
Weapon_Switch(Weapon_OwnsThisType("weapon_milso"));
break;
case NEO_CLASS_ASSAULT:
Expand Down Expand Up @@ -3596,9 +3593,8 @@ void CNEO_Player::GiveLoadoutWeapon(void)
CNEOBaseCombatWeapon *pNeoWeapon = assert_cast<CNEOBaseCombatWeapon*>((CBaseEntity*)pEnt);
if (pNeoWeapon)
{
if (sv_neo_ignore_wep_xp_limit.GetBool() ||
m_iLoadoutWepChoice+1 <= CNEOWeaponLoadout::GetNumberOfLoadoutWeapons(m_iXP,
sv_neo_dev_loadout.GetBool() ? NEO_LOADOUT_DEV : m_iNeoClass.Get()))
if (m_iLoadoutWepChoice+1 <= CNEOWeaponLoadout::GetNumberOfLoadoutWeapons(CNEOWeaponLoadout::GetEffectiveXP(m_iXP),
sv_neo_dev_loadout.GetBool() ? NEO_LOADOUT_DEV : m_iNeoClass.Get()))
{
pNeoWeapon->SetSubType(wepSubType);

Expand Down
17 changes: 17 additions & 0 deletions src/game/shared/neo/neo_weapon_loadout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

#include "tier0/dbg.h"
#include "tier0/commonmacros.h"
#include "convar.h"
#include "neo_misc.h"

extern ConVar sv_neo_ignore_wep_xp_limit;

namespace CNEOWeaponLoadout {

#define WEAPON_DEF(M_BITWNAME, M_NAME, M_DISPLAY_NAME, ...) \
Expand Down Expand Up @@ -105,5 +108,19 @@ int GetNumberOfLoadoutWeapons(const int rank, const int classType)
return amount;
}

ConVar sv_neo_wep_xp_override("sv_neo_wep_xp_override", "-1", FCVAR_CHEAT | FCVAR_REPLICATED,
"Override the effective XP used for weapon eligibility checks, or -1 to disable.", true, -1.0f, false, 0.0f);

int GetEffectiveXP(const int actualXP)
{
if (sv_neo_ignore_wep_xp_limit.GetBool())
{
// Treat as max rank so every XP-gated weapon is eligible
return XP_LIEUTENANT;
}
const int iOverride = sv_neo_wep_xp_override.GetInt();
return (iOverride >= 0) ? iOverride : actualXP;
}

} // namespace CNEOWeaponLoadout

4 changes: 4 additions & 0 deletions src/game/shared/neo/neo_weapon_loadout.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,9 @@ namespace CNEOWeaponLoadout
extern const CLoadoutWeapon s_LoadoutWeapons[NEO_LOADOUT__COUNT][MAX_WEAPON_LOADOUTS];

int GetNumberOfLoadoutWeapons(const int rank, const int classType);

// The XP value to use for weapon eligibility checks. Returns actualXP unless
// sv_neo_wep_xp_override is set (>= 0), in which case the override wins.
int GetEffectiveXP(const int actualXP);
} // namespace CNEOWeaponLoadout