mirror of
https://github.com/s1lentq/ReGameDLL_CS.git
synced 2025-01-27 14:08:00 +03:00
New CVars: mp_weapondrop
and mp_ammodrop
and fixes (#840)
* First implementation * Update player.cpp * Apply suggestions from code review Co-authored-by: Sergey Shorokhov <wopox1337@ya.ru> * Improve readability * Improve readability x2 Co-authored-by: Sergey Shorokhov <wopox1337@ya.ru> * Tabulation tip * Compile error resolved * Add mp_weapondrop 3: drop all weapons --------- Co-authored-by: Sergey Shorokhov <wopox1337@ya.ru>
This commit is contained in:
parent
d4deabfe59
commit
8ddda261fe
@ -45,6 +45,8 @@ This means that plugins that do binary code analysis (Orpheu for example) probab
|
||||
| mp_round_restart_delay | 5 | - | - | Number of seconds to delay before restarting a round after a win. |
|
||||
| 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 first available grenade<br/>`2` drop all grenades |
|
||||
| mp_weapondrop | 1 | 0 | 3 | Drop player weapon after death.<br/>`0` do not drop weapons after death<br/>`1` drop best/heaviest weapon after death<br/>`2` drop active weapon after death<br/>`3` drop all weapons after death (primary and secondary) |
|
||||
| mp_ammodrop | 1 | 0 | 2 | Drop ammo on weapon boxes on death or manual drop.<br/>`0` always keep ammo on player<br/>`1` drop all ammo only after death<br/>`2` drop all ammo whenever player drops a weapon |
|
||||
| mp_roundrespawn_time | 20 | 0 | - | Player cannot respawn until next round if more than N seconds has elapsed since the beginning round.<br />`-1` means no time limit<br /> |
|
||||
| mp_auto_reload_weapons | 0 | 0 | 1 | Automatically reload each weapon on player spawn.<br/>`0` disabled<br/>`1` enabled |
|
||||
| mp_refill_bpammo_weapons | 0 | 0 | 2 | Refill amount of backpack ammo up to the max.<br/>`0` disabled<br/>`1` refill backpack ammo on player spawn<br/>`2` refill backpack ammo on player spawn and on the purchase of the item |
|
||||
|
18
dist/game.cfg
vendored
18
dist/game.cfg
vendored
@ -78,6 +78,24 @@ mp_hegrenade_penetration "0"
|
||||
// Default value: "0"
|
||||
mp_nadedrops "0"
|
||||
|
||||
// Drop player weapon after death
|
||||
// 0 - do not drop weapons after death
|
||||
// 1 - drop best/heaviest weapon after death (default behaviour)
|
||||
// 2 - drop active weapon after death
|
||||
// 3 - drop all weapons after death (primary and secondary)
|
||||
// NOTE: Grenades are dropped separately depending on mp_nadedrops value
|
||||
//
|
||||
// Default value: "1"
|
||||
mp_weapondrop "1"
|
||||
|
||||
// Drop ammo on weapon boxes on death or manual drop
|
||||
// 0 - always keep ammo on player
|
||||
// 1 - drop all ammo only after death (default behaviour)
|
||||
// 2 - drop all ammo whenever player drops a weapon (NOTE: Other weapons may remain without ammo due to same ammo sharing)
|
||||
//
|
||||
// Default value: "1"
|
||||
mp_ammodrop "1"
|
||||
|
||||
// Player cannot respawn until next round
|
||||
// if more than N seconds has elapsed since the beginning round
|
||||
// -1 - means no time limit
|
||||
|
@ -109,6 +109,8 @@ cvar_t maxmoney = { "mp_maxmoney", "16000", FCVAR_SERVER, 0.0f, nul
|
||||
cvar_t round_infinite = { "mp_round_infinite", "0", FCVAR_SERVER, 0.0f, nullptr };
|
||||
cvar_t hegrenade_penetration = { "mp_hegrenade_penetration", "0", 0, 0.0f, nullptr };
|
||||
cvar_t nadedrops = { "mp_nadedrops", "0", 0, 0.0f, nullptr };
|
||||
cvar_t weapondrop = { "mp_weapondrop", "1", 0, 1.0f, nullptr };
|
||||
cvar_t ammodrop = { "mp_ammodrop", "1", 0, 1.0f, nullptr };
|
||||
cvar_t roundrespawn_time = { "mp_roundrespawn_time", "20", 0, 20.0f, nullptr };
|
||||
cvar_t auto_reload_weapons = { "mp_auto_reload_weapons", "0", 0, 0.0f, nullptr };
|
||||
cvar_t refill_bpammo_weapons = { "mp_refill_bpammo_weapons", "0", 0, 0.0f, nullptr }; // Useful for mods like DeathMatch, GunGame, ZombieMod etc
|
||||
@ -351,6 +353,8 @@ void EXT_FUNC GameDLLInit()
|
||||
CVAR_REGISTER(&round_infinite);
|
||||
CVAR_REGISTER(&hegrenade_penetration);
|
||||
CVAR_REGISTER(&nadedrops);
|
||||
CVAR_REGISTER(&weapondrop);
|
||||
CVAR_REGISTER(&ammodrop);
|
||||
CVAR_REGISTER(&roundrespawn_time);
|
||||
CVAR_REGISTER(&auto_reload_weapons);
|
||||
CVAR_REGISTER(&refill_bpammo_weapons);
|
||||
|
@ -138,6 +138,8 @@ extern cvar_t maxmoney;
|
||||
extern cvar_t round_infinite;
|
||||
extern cvar_t hegrenade_penetration;
|
||||
extern cvar_t nadedrops;
|
||||
extern cvar_t weapondrop;
|
||||
extern cvar_t ammodrop;
|
||||
extern cvar_t roundrespawn_time;
|
||||
extern cvar_t auto_reload_weapons;
|
||||
extern cvar_t refill_bpammo_weapons;
|
||||
|
@ -186,6 +186,10 @@ enum
|
||||
GR_PLR_DROP_AMMO_ALL,
|
||||
GR_PLR_DROP_AMMO_ACTIVE,
|
||||
GR_PLR_DROP_AMMO_NO,
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
GR_PLR_DROP_GUN_BEST,
|
||||
#endif
|
||||
};
|
||||
|
||||
// custom enum
|
||||
|
@ -4332,11 +4332,29 @@ LINK_HOOK_CLASS_CUSTOM_CHAIN(int, CHalfLifeMultiplay, CSGameRules, DeadPlayerWea
|
||||
|
||||
int EXT_FUNC CHalfLifeMultiplay::__API_HOOK(DeadPlayerWeapons)(CBasePlayer *pPlayer)
|
||||
{
|
||||
return GR_PLR_DROP_GUN_ACTIVE;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
switch ((int)weapondrop.value)
|
||||
{
|
||||
case 3:
|
||||
return GR_PLR_DROP_GUN_ALL;
|
||||
case 2:
|
||||
break;
|
||||
case 1:
|
||||
return GR_PLR_DROP_GUN_BEST;
|
||||
default:
|
||||
return GR_PLR_DROP_GUN_NO;
|
||||
}
|
||||
#endif
|
||||
return GR_PLR_DROP_GUN_ACTIVE; // keep original value in return
|
||||
}
|
||||
|
||||
int CHalfLifeMultiplay::DeadPlayerAmmo(CBasePlayer *pPlayer)
|
||||
{
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (ammodrop.value == 0.0f)
|
||||
return GR_PLR_DROP_AMMO_NO;
|
||||
#endif
|
||||
|
||||
return GR_PLR_DROP_AMMO_ACTIVE;
|
||||
}
|
||||
|
||||
|
@ -1297,7 +1297,14 @@ CWeaponBox *EXT_FUNC __API_HOOK(CreateWeaponBox)(CBasePlayerItem *pItem, CBasePl
|
||||
#else
|
||||
pWeaponBox->GiveAmmo(pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()], (char *)pItem->pszAmmo1(), pItem->iMaxAmmo1());
|
||||
#endif
|
||||
#ifndef REGAMEDLL_FIXES
|
||||
// by removing ammo ONLY on exhaustible weapons (slot 4 and 5)
|
||||
// you are allowing to duplicate ammo whenever:
|
||||
// (1) you have 2 weapons sharing the same ammo type (e.g. mp5navy and glock)
|
||||
// (2) you are dropping a weapon alive and pickup another (with same ammo type) without ammo
|
||||
// and, logically, you throw your ammo with your gun with packing enabled
|
||||
if (exhaustibleAmmo)
|
||||
#endif
|
||||
{
|
||||
pPlayerOwner->m_rgAmmo[pItem->PrimaryAmmoIndex()] = 0;
|
||||
}
|
||||
@ -1309,10 +1316,10 @@ CWeaponBox *EXT_FUNC __API_HOOK(CreateWeaponBox)(CBasePlayerItem *pItem, CBasePl
|
||||
return pWeaponBox;
|
||||
}
|
||||
|
||||
void PackPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
CWeaponBox *PackPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
{
|
||||
if (!pItem)
|
||||
return;
|
||||
return nullptr;
|
||||
|
||||
const char *modelName = GetCSModelName(pItem->m_iId);
|
||||
if (modelName)
|
||||
@ -1322,7 +1329,7 @@ void PackPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
Vector vecVelocity = pPlayer->pev->velocity * 0.75f;
|
||||
|
||||
// create a box to pack the stuff into
|
||||
CreateWeaponBox(pItem, pPlayer,
|
||||
return CreateWeaponBox(pItem, pPlayer,
|
||||
modelName,
|
||||
vecOrigin,
|
||||
vecAngles,
|
||||
@ -1330,6 +1337,8 @@ void PackPlayerItem(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
CGameRules::GetItemKillDelay(), packAmmo
|
||||
);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
@ -1386,78 +1395,130 @@ void PackPlayerNade(CBasePlayer *pPlayer, CBasePlayerItem *pItem, bool packAmmo)
|
||||
void CBasePlayer::PackDeadPlayerItems()
|
||||
{
|
||||
// get the game rules
|
||||
bool bPackGun = (g_pGameRules->DeadPlayerWeapons(this) != GR_PLR_DROP_GUN_NO);
|
||||
int iPackGun = g_pGameRules->DeadPlayerWeapons(this);
|
||||
bool bPackAmmo = (g_pGameRules->DeadPlayerAmmo(this) != GR_PLR_DROP_AMMO_NO);
|
||||
|
||||
if (bPackGun)
|
||||
if (iPackGun != GR_PLR_DROP_GUN_NO)
|
||||
{
|
||||
bool bShieldDropped = false;
|
||||
bool bSkipPrimSec = false;
|
||||
if (HasShield())
|
||||
{
|
||||
DropShield();
|
||||
bShieldDropped = true;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if(iPackGun != GR_PLR_DROP_GUN_ALL)
|
||||
#endif
|
||||
{
|
||||
bSkipPrimSec = true;
|
||||
}
|
||||
}
|
||||
|
||||
int nBestWeight = 0;
|
||||
CBasePlayerItem *pBestItem = nullptr;
|
||||
|
||||
for (int n = 0; n < MAX_ITEM_TYPES; n++)
|
||||
{
|
||||
// there's a weapon here. Should I pack it?
|
||||
CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[n];
|
||||
#ifdef REGAMEDLL_ADD
|
||||
int iGunsPacked = 0;
|
||||
|
||||
while (pPlayerItem)
|
||||
if (iPackGun == GR_PLR_DROP_GUN_ACTIVE)
|
||||
{
|
||||
// check if we've just already dropped our active gun
|
||||
if (!bSkipPrimSec && m_pActiveItem && m_pActiveItem->CanDrop() && m_pActiveItem->iItemSlot() < KNIFE_SLOT)
|
||||
{
|
||||
ItemInfo info;
|
||||
if (pPlayerItem->iItemSlot() < KNIFE_SLOT && !bShieldDropped)
|
||||
{
|
||||
#ifdef REGAMEDLL_API
|
||||
if (pPlayerItem->CSPlayerItem()->GetItemInfo(&info))
|
||||
#else
|
||||
if (pPlayerItem->GetItemInfo(&info))
|
||||
pBestItem = m_pActiveItem;
|
||||
|
||||
// if active item is undroppable, then nothing is dropped
|
||||
}
|
||||
|
||||
// are we allowing nade drop?
|
||||
if ((int)nadedrops.value >= 1)
|
||||
{
|
||||
// goto item loop but skip guns
|
||||
iPackGun = GR_PLR_DROP_GUN_ALL;
|
||||
bSkipPrimSec = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (iPackGun == GR_PLR_DROP_GUN_ALL || iPackGun == GR_PLR_DROP_GUN_BEST)
|
||||
#endif
|
||||
{
|
||||
for (int n = 0; n < MAX_ITEM_TYPES; n++)
|
||||
{
|
||||
// there's a weapon here. Should I pack it?
|
||||
CBasePlayerItem *pPlayerItem = m_rgpPlayerItems[n];
|
||||
|
||||
while (pPlayerItem)
|
||||
{
|
||||
ItemInfo info;
|
||||
if (pPlayerItem->iItemSlot() < KNIFE_SLOT && !bSkipPrimSec)
|
||||
{
|
||||
if (info.iWeight > nBestWeight)
|
||||
#ifdef REGAMEDLL_API
|
||||
if (pPlayerItem->CSPlayerItem()->GetItemInfo(&info)
|
||||
#else
|
||||
if (pPlayerItem->GetItemInfo(&info)
|
||||
#endif
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
&& pPlayerItem->CanDrop() // needs to be droppable
|
||||
#endif
|
||||
)
|
||||
{
|
||||
nBestWeight = info.iWeight;
|
||||
pBestItem = pPlayerItem;
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (iPackGun == GR_PLR_DROP_GUN_ALL)
|
||||
{
|
||||
CBasePlayerItem *pNext = pPlayerItem->m_pNext;
|
||||
|
||||
CWeaponBox *pWeaponBox = PackPlayerItem(this, pPlayerItem, bPackAmmo);
|
||||
if (pWeaponBox)
|
||||
{
|
||||
// just push a few units in forward to separate them
|
||||
pWeaponBox->pev->velocity = pWeaponBox->pev->velocity * (1.0 + (iGunsPacked * 0.2));
|
||||
iGunsPacked++;
|
||||
}
|
||||
|
||||
pPlayerItem = pNext;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (info.iWeight > nBestWeight)
|
||||
{
|
||||
nBestWeight = info.iWeight;
|
||||
pBestItem = pPlayerItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// drop a grenade after death
|
||||
else if (pPlayerItem->iItemSlot() == GRENADE_SLOT)
|
||||
{
|
||||
if (AreRunningCZero())
|
||||
// drop a grenade after death
|
||||
else if (pPlayerItem->iItemSlot() == GRENADE_SLOT)
|
||||
{
|
||||
if (AreRunningCZero())
|
||||
{
|
||||
|
||||
#ifdef REGAMEDLL_FIXES
|
||||
if (pPlayerItem->m_flStartThrow == 0.0f && m_rgAmmo[pPlayerItem->PrimaryAmmoIndex()] > 0)
|
||||
if (pPlayerItem->m_flStartThrow == 0.0f && m_rgAmmo[pPlayerItem->PrimaryAmmoIndex()] > 0)
|
||||
#endif
|
||||
{
|
||||
PackPlayerItem(this, pPlayerItem, true);
|
||||
{
|
||||
PackPlayerItem(this, pPlayerItem, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef REGAMEDLL_ADD
|
||||
else
|
||||
{
|
||||
switch ((int)nadedrops.value)
|
||||
else
|
||||
{
|
||||
case 1:
|
||||
PackPlayerNade(this, pPlayerItem, true);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
CBasePlayerItem *pNext = pPlayerItem->m_pNext;
|
||||
PackPlayerNade(this, pPlayerItem, true);
|
||||
pPlayerItem = pNext;
|
||||
continue;
|
||||
switch ((int)nadedrops.value)
|
||||
{
|
||||
case 1:
|
||||
PackPlayerNade(this, pPlayerItem, true);
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
CBasePlayerItem *pNext = pPlayerItem->m_pNext;
|
||||
PackPlayerNade(this, pPlayerItem, true);
|
||||
pPlayerItem = pNext;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
pPlayerItem = pPlayerItem->m_pNext;
|
||||
pPlayerItem = pPlayerItem->m_pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8033,13 +8094,21 @@ CBaseEntity *EXT_FUNC CBasePlayer::__API_HOOK(DropPlayerItem)(const char *pszIte
|
||||
Vector vecAngles = pev->angles;
|
||||
Vector vecVelocity = gpGlobals->v_forward * 300 + gpGlobals->v_forward * 100;
|
||||
|
||||
bool bPackAmmo = false;
|
||||
|
||||
#ifdef REGAMEDLL_ADD
|
||||
if (ammodrop.value >= 2.0f)
|
||||
bPackAmmo = true;
|
||||
#endif
|
||||
|
||||
CWeaponBox *pWeaponBox = CreateWeaponBox(pWeapon, this,
|
||||
modelname,
|
||||
vecOrigin,
|
||||
vecAngles,
|
||||
vecVelocity,
|
||||
CGameRules::GetItemKillDelay(),
|
||||
false);
|
||||
bPackAmmo
|
||||
);
|
||||
|
||||
if (!pWeaponBox)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user