Skip to content

Commit

Permalink
Add ability to remove ammo and weapons via game_player_settings. Depr…
Browse files Browse the repository at this point in the history
…ecate spawnflags of game_player_settings
  • Loading branch information
FreeSlave committed Jun 28, 2024
1 parent 755ae43 commit 037d828
Show file tree
Hide file tree
Showing 11 changed files with 348 additions and 85 deletions.
4 changes: 1 addition & 3 deletions dlls/ammoregistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ bool AmmoType::IsValid() const
{
if (!name || *name == '\0')
return false;
if (id <= 0)
return false;
return true;
return id > 0;
}

int AmmoRegistry::Register(const char *name, int maxAmmo, bool exhaustible)
Expand Down
1 change: 0 additions & 1 deletion dlls/handgrenade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ void CHandGrenade::Holster()
else
{
// no more grenades!
m_pPlayer->pev->weapons &= ~( 1 << WEAPON_HANDGRENADE );
DestroyItem();
}

Expand Down
115 changes: 109 additions & 6 deletions dlls/maprules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,14 @@ class CGamePlayerSettings : public CRulePointEntity
SUIT_LIGHT_NVG = 2,
};

enum
{
WEAPON_SETTING_REMOVE = -1,
WEAPON_SETTING_NOCHANGE = 0,
WEAPON_SETTING_GIVE = 1,
WEAPON_SETTING_GIVE_ALLOW_DUP = 2,
};

void PreEntvarsKeyvalue( KeyValueData* pkvd );
void KeyValue( KeyValueData *pkvd );
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
Expand All @@ -974,8 +982,13 @@ class CGamePlayerSettings : public CRulePointEntity
SuitNoLogon
};
int m_ammoCounts[MAX_AMMO_TYPES];
string_t m_weapons[MAX_WEAPONS];
short m_weaponSettings[MAX_WEAPONS];
short m_suit;
short m_suitLogon;
short m_suitLight;
short m_longjump;

BOOL m_allowOverheal;
BOOL m_allowOvercharge;
float m_armorStrength;
Expand All @@ -989,8 +1002,12 @@ LINK_ENTITY_TO_CLASS( game_player_settings, CGamePlayerSettings )
TYPEDESCRIPTION CGamePlayerSettings::m_SaveData[] =
{
DEFINE_ARRAY( CGamePlayerSettings, m_ammoCounts, FIELD_INTEGER, MAX_AMMO_TYPES ),
DEFINE_ARRAY( CGamePlayerSettings, m_weapons, FIELD_STRING, MAX_WEAPONS ),
DEFINE_ARRAY( CGamePlayerSettings, m_weaponSettings, FIELD_SHORT, MAX_WEAPONS ),
DEFINE_FIELD( CGamePlayerSettings, m_suit, FIELD_SHORT ),
DEFINE_FIELD( CGamePlayerSettings, m_suitLogon, FIELD_SHORT ),
DEFINE_FIELD( CGamePlayerSettings, m_suitLight, FIELD_SHORT ),
DEFINE_FIELD( CGamePlayerSettings, m_longjump, FIELD_SHORT ),
DEFINE_FIELD( CGamePlayerSettings, m_allowOverheal, FIELD_BOOLEAN ),
DEFINE_FIELD( CGamePlayerSettings, m_allowOvercharge, FIELD_BOOLEAN ),
DEFINE_FIELD( CGamePlayerSettings, m_armorStrength, FIELD_FLOAT ),
Expand Down Expand Up @@ -1064,6 +1081,11 @@ void CGamePlayerSettings::KeyValue(KeyValueData *pkvd)
m_ammoCounts[ammoType->id] = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "suit"))
{
m_suit = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "suitlogon"))
{
m_suitLogon = atoi(pkvd->szValue);
Expand All @@ -1074,6 +1096,11 @@ void CGamePlayerSettings::KeyValue(KeyValueData *pkvd)
m_suitLight = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "longjump"))
{
m_longjump = atoi(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (FStrEq(pkvd->szKeyName, "max_armor"))
{
pev->armortype = atoi(pkvd->szValue);
Expand All @@ -1094,6 +1121,25 @@ void CGamePlayerSettings::KeyValue(KeyValueData *pkvd)
m_armorStrength = atof(pkvd->szValue);
pkvd->fHandled = TRUE;
}
else if (strncmp(pkvd->szKeyName, "weapon_", 7) == 0)
{
int i;
for (i=0; i<ARRAYSIZE(m_weapons); ++i)
{
if (FStringNull(m_weapons[i]))
{
m_weapons[i] = ALLOC_STRING(pkvd->szKeyName);
m_weaponSettings[i] = atoi(pkvd->szValue);
break;
}
if (FStrEq(pkvd->szKeyName, STRING(m_weapons[i])))
{
m_weaponSettings[i] = atoi(pkvd->szValue);
break;
}
}
pkvd->fHandled = TRUE;
}
else
CRulePointEntity::KeyValue(pkvd);
}
Expand Down Expand Up @@ -1179,7 +1225,12 @@ void CGamePlayerSettings::EquipPlayer(CBaseEntity *pPlayer)
player->m_armorStrength = m_armorStrength;
}

if (pev->spawnflags & SF_PLAYER_SETTINGS_SUIT)
short giveSuit = m_suit;
if (!giveSuit && FBitSet(pev->spawnflags, SF_PLAYER_SETTINGS_SUIT))
{
giveSuit = 1;
}
if (giveSuit > 0)
{
if (!player->HasSuit())
{
Expand All @@ -1197,10 +1248,26 @@ void CGamePlayerSettings::EquipPlayer(CBaseEntity *pPlayer)
player->GiveNamedItem("item_suit", suitSpawnFlags);
}
}
else if (giveSuit < 0)
{
player->m_iItemsBits &= ~(PLAYER_ITEM_SUIT);
}

if ((pev->spawnflags & SF_PLAYER_SETTINGS_LONGJUMP) && player->HasSuit() && !player->m_fLongJump)
short giveLongjump = m_longjump;
if (!giveLongjump && FBitSet(pev->spawnflags, SF_PLAYER_SETTINGS_LONGJUMP))
{
giveLongjump = 1;
}
if (giveLongjump > 0)
{
if (player->HasSuit() && !player->m_fLongJump)
{
player->GiveNamedItem("item_longjump", SF_ITEM_NOFALL);
}
}
else if (giveLongjump < 0)
{
player->GiveNamedItem("item_longjump", SF_ITEM_NOFALL);
player->SetLongjump(false);
}

switch (m_suitLight) {
Expand Down Expand Up @@ -1307,12 +1374,16 @@ void CGamePlayerSettings::EquipPlayer(CBaseEntity *pPlayer)
for (i=1; i<MAX_AMMO_TYPES; ++i)
{
const AmmoType* ammoInfo = g_AmmoRegistry.GetByIndex(i);
if (ammoInfo && m_ammoCounts[i])
if (ammoInfo)
{
player->GiveAmmo(m_ammoCounts[i], ammoInfo->name);
if (m_ammoCounts[i] > 0)
player->GiveAmmo(m_ammoCounts[i], ammoInfo->name);
else if (m_ammoCounts[i] < 0)
player->RemoveAmmo(-m_ammoCounts[i], ammoInfo->name);
}
}

// This way of setting weapons is deprecated
for (i=0; i<ARRAYSIZE(weaponFlags); ++i)
{
if (pev->spawnflags & weaponFlags[i])
Expand All @@ -1325,9 +1396,41 @@ void CGamePlayerSettings::EquipPlayer(CBaseEntity *pPlayer)
}
}

if (!hadWeapons)
for (i=0; i<ARRAYSIZE(m_weapons); ++i)
{
if (FStringNull(m_weapons[i]))
break;
string_t weaponName = m_weapons[i];
const int weaponSetting = m_weaponSettings[i];
if (weaponSetting == WEAPON_SETTING_REMOVE)
{
CBasePlayerWeapon* pWeapon = player->GetWeaponByName(STRING(weaponName));
if (pWeapon)
{
pWeapon->DestroyItem();
}
}
else if (weaponSetting == WEAPON_SETTING_GIVE)
{
if (!player->HasNamedPlayerItem(STRING(weaponName)))
{
player->GiveNamedItem(STRING(weaponName));
}
}
else if (weaponSetting == WEAPON_SETTING_GIVE_ALLOW_DUP)
{
player->GiveNamedItem(STRING(weaponName));
}
}

if (!hadWeapons || player->m_pActiveItem == NULL)
player->SwitchToBestWeapon();

if (player->m_pActiveItem == NULL)
{
player->SendCurWeaponClear();
}

SUB_UseTargets(pPlayer);
}

Expand Down
97 changes: 60 additions & 37 deletions dlls/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1107,12 +1107,7 @@ void CBasePlayer::RemoveAllItems( int stripFlags )

UpdateClientData();

// send Selected Weapon Message to our client
MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev );
WRITE_BYTE( 0 );
WRITE_BYTE( 0 );
WRITE_SHORT( 0 );
MESSAGE_END();
SendCurWeaponClear();
}

/*
Expand Down Expand Up @@ -1172,11 +1167,7 @@ void CBasePlayer::Killed( entvars_t *pevInflictor, entvars_t *pevAttacker, int i
MESSAGE_END();

// Tell Ammo Hud that the player is dead
MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev );
WRITE_BYTE( 0 );
WRITE_BYTE( 0XFF );
WRITE_SHORT( -1 );
MESSAGE_END();
SendCurWeaponDead();

// reset FOV
pev->fov = m_iFOV = m_iClientFOV = 0;
Expand Down Expand Up @@ -1734,11 +1725,7 @@ void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle )
SetSuitUpdate( NULL, FALSE, 0 );

// Tell Ammo Hud that the player is dead
MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev );
WRITE_BYTE( 0 );
WRITE_BYTE( 0XFF );
WRITE_SHORT( -1 );
MESSAGE_END();
SendCurWeaponDead();

// reset FOV
m_iFOV = m_iClientFOV = 0;
Expand Down Expand Up @@ -3948,6 +3935,24 @@ BOOL CBasePlayer::HasWeapons( void )
return FALSE;
}

void CBasePlayer::SendCurWeaponClear()
{
MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev );
WRITE_BYTE( 0 );
WRITE_BYTE( 0 );
WRITE_SHORT( 0 );
MESSAGE_END();
}

void CBasePlayer::SendCurWeaponDead()
{
MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev );
WRITE_BYTE( 0 );
WRITE_BYTE( 0XFF );
WRITE_SHORT( -1 );
MESSAGE_END();
}

void CBasePlayer::SelectPrevItem( int iItem )
{
}
Expand Down Expand Up @@ -4658,12 +4663,6 @@ BOOL CBasePlayer::RemovePlayerItem( CBasePlayerWeapon *pItem, bool bCallHolster
//
int CBasePlayer::GiveAmmo(int iCount, const char *szName)
{
if( !szName )
{
// no ammo.
return -1;
}

const AmmoType* ammoType = CBasePlayerWeapon::GetAmmoType(szName);
if (!ammoType)
return -1;
Expand Down Expand Up @@ -4736,6 +4735,32 @@ int CBasePlayer::GiveAmmo(int iCount, const char *szName)
return i;
}

void CBasePlayer::RemoveAmmo(int iAmount, const char *szName)
{
const AmmoType* ammoType = CBasePlayerWeapon::GetAmmoType(szName);
if (!ammoType)
return;

int i = ammoType->id;
m_rgAmmo[i] -= iAmount;
if (m_rgAmmo[i] < 0)
m_rgAmmo[i] = 0;

if (m_rgAmmo[i] <= 0 && ammoType->exhaustible)
{
for (int j=0; j<MAX_WEAPONS; ++j)
{
const ItemInfo& II = CBasePlayerWeapon::ItemInfoArray[j];
if ((II.iFlags & ITEM_FLAG_EXHAUSTIBLE) && II.pszAmmo1 && FStrEq(szName, II.pszAmmo1)) {
// we found a weapon that uses this ammo type
CBasePlayerWeapon* pWeapon = WeaponById(j);
if (pWeapon)
pWeapon->RetireWeapon();
}
}
}
}

/*
============
ItemPreFrame
Expand Down Expand Up @@ -5721,23 +5746,24 @@ BOOL CBasePlayer::HasPlayerItem( CBasePlayerWeapon *pCheckItem )
//=========================================================
BOOL CBasePlayer::HasNamedPlayerItem( const char *pszItemName )
{
CBasePlayerWeapon *pItem;
int i;
return GetWeaponByName(pszItemName) != NULL;
}

for( i = 0; i < MAX_WEAPONS; i++ )
CBasePlayerWeapon* CBasePlayer::GetWeaponByName(const char *pszItemName)
{
for( int i = 0; i < MAX_WEAPONS; i++ )
{
pItem = m_rgpPlayerWeapons[i];
CBasePlayerWeapon* pWeapon = m_rgpPlayerWeapons[i];

if( pItem )
if( pWeapon )
{
if( !strcmp( pszItemName, STRING( pItem->pev->classname ) ) )
if( strcmp( pszItemName, STRING( pWeapon->pev->classname ) ) == 0 )
{
return TRUE;
return pWeapon;
}
}
}

return FALSE;
return NULL;
}

//=========================================================
Expand Down Expand Up @@ -5769,18 +5795,15 @@ BOOL CBasePlayer::SwitchWeapon(CBasePlayerWeapon *pWeapon )
BOOL CBasePlayer::SwitchToBestWeapon()
{
CBasePlayerWeapon *pBest = m_pActiveItem;
int i;

if (!pBest)
return FALSE;

for( i = 0; i < MAX_WEAPONS; i++ )
for( int i = 0; i < MAX_WEAPONS; i++ )
{
CBasePlayerWeapon *pCheck = m_rgpPlayerWeapons[i];

if ( pCheck )
{
if( pCheck->iWeight() > pBest->iWeight() && pCheck != pBest )
const int bestWeight = pBest ? pBest->iWeight() : -1;
if( pCheck->iWeight() > bestWeight && pCheck != pBest )
{
if( pCheck->CanDeploy() )
{
Expand Down
Loading

0 comments on commit 037d828

Please sign in to comment.