[HL25] Backport busters game mode
Also backport a define being moved at the top in "multiplay_gamerules.cpp". And two changes related to weapons in general in "weapons.cpp".
This commit is contained in:
parent
33b2b3acd4
commit
e0ba8cebc7
10 changed files with 447 additions and 17 deletions
|
@ -27,6 +27,8 @@
|
||||||
#ifdef CLIENT_DLL
|
#ifdef CLIENT_DLL
|
||||||
#include "hud.h"
|
#include "hud.h"
|
||||||
#include "com_weapons.h"
|
#include "com_weapons.h"
|
||||||
|
#else
|
||||||
|
extern bool IsBustingGame();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define EGON_SWITCH_NARROW_TIME 0.75 // Time it takes to switch fire modes
|
#define EGON_SWITCH_NARROW_TIME 0.75 // Time it takes to switch fire modes
|
||||||
|
@ -124,6 +126,11 @@ bool CEgon::HasAmmo()
|
||||||
|
|
||||||
void CEgon::UseAmmo(int count)
|
void CEgon::UseAmmo(int count)
|
||||||
{
|
{
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
if (IsBustingGame())
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] >= count)
|
if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] >= count)
|
||||||
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= count;
|
m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= count;
|
||||||
else
|
else
|
||||||
|
@ -491,7 +498,17 @@ void CEgon::WeaponIdle()
|
||||||
m_deployed = true;
|
m_deployed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CEgon::CanHolster()
|
||||||
|
{
|
||||||
|
#ifndef CLIENT_DLL
|
||||||
|
if (IsBustingGame())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void CEgon::EndAttack()
|
void CEgon::EndAttack()
|
||||||
{
|
{
|
||||||
|
|
|
@ -454,6 +454,8 @@ cvar_t sk_player_leg3 = {"sk_player_leg3", "1"};
|
||||||
|
|
||||||
// END Cvars for Skill Level settings
|
// END Cvars for Skill Level settings
|
||||||
|
|
||||||
|
cvar_t sv_busters = {"sv_busters", "0", FCVAR_SERVER};
|
||||||
|
|
||||||
static bool SV_InitServer()
|
static bool SV_InitServer()
|
||||||
{
|
{
|
||||||
if (!FileSystem_LoadFileSystem())
|
if (!FileSystem_LoadFileSystem())
|
||||||
|
@ -515,6 +517,8 @@ void GameDLLInit()
|
||||||
|
|
||||||
CVAR_REGISTER(&mp_chattime);
|
CVAR_REGISTER(&mp_chattime);
|
||||||
|
|
||||||
|
CVAR_REGISTER(&sv_busters);
|
||||||
|
|
||||||
CVAR_REGISTER(&sv_allowbunnyhopping);
|
CVAR_REGISTER(&sv_allowbunnyhopping);
|
||||||
|
|
||||||
// REGISTER CVARS FOR SKILL LEVEL STUFF
|
// REGISTER CVARS FOR SKILL LEVEL STUFF
|
||||||
|
|
|
@ -43,6 +43,8 @@ extern cvar_t mp_chattime;
|
||||||
|
|
||||||
extern cvar_t sv_allowbunnyhopping;
|
extern cvar_t sv_allowbunnyhopping;
|
||||||
|
|
||||||
|
extern cvar_t sv_busters;
|
||||||
|
|
||||||
// Engine Cvars
|
// Engine Cvars
|
||||||
inline cvar_t* g_psv_gravity;
|
inline cvar_t* g_psv_gravity;
|
||||||
inline cvar_t* g_psv_aim;
|
inline cvar_t* g_psv_aim;
|
||||||
|
|
|
@ -373,7 +373,12 @@ CGameRules* InstallGameRules()
|
||||||
SERVER_COMMAND("exec game.cfg\n");
|
SERVER_COMMAND("exec game.cfg\n");
|
||||||
SERVER_EXECUTE();
|
SERVER_EXECUTE();
|
||||||
|
|
||||||
if (0 == gpGlobals->deathmatch)
|
if (1 == sv_busters.value)
|
||||||
|
{
|
||||||
|
g_teamplay = false;
|
||||||
|
return new CMultiplayBusters;
|
||||||
|
}
|
||||||
|
else if (0 == gpGlobals->deathmatch)
|
||||||
{
|
{
|
||||||
// generic half-life
|
// generic half-life
|
||||||
g_teamplay = false;
|
g_teamplay = false;
|
||||||
|
|
|
@ -363,6 +363,33 @@ protected:
|
||||||
void SendMOTDToClient(edict_t* client);
|
void SendMOTDToClient(edict_t* client);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// CMultiplayBusters
|
||||||
|
// Rules for a multiplayer mode that makes you feel good
|
||||||
|
//=========================================================
|
||||||
|
class CMultiplayBusters : public CHalfLifeMultiplay
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMultiplayBusters();
|
||||||
|
|
||||||
|
void Think();
|
||||||
|
int IPointsForKill(CBasePlayer* pAttacker, CBasePlayer* pKilled);
|
||||||
|
void PlayerKilled(CBasePlayer* pVictim, entvars_t* pKiller, entvars_t* pInflictor);
|
||||||
|
void DeathNotice(CBasePlayer* pVictim, entvars_t* pKiller, entvars_t* pInflictor);
|
||||||
|
int WeaponShouldRespawn(CBasePlayerItem* pWeapon);
|
||||||
|
bool CanHavePlayerItem(CBasePlayer* pPlayer, CBasePlayerItem* pWeapon);
|
||||||
|
bool CanHaveItem(CBasePlayer* pPlayer, CItem* pItem);
|
||||||
|
void PlayerGotWeapon(CBasePlayer* pPlayer, CBasePlayerItem* pWeapon);
|
||||||
|
void ClientUserInfoChanged(CBasePlayer* pPlayer, char* infobuffer);
|
||||||
|
void PlayerSpawn(CBasePlayer* pPlayer);
|
||||||
|
|
||||||
|
void SetPlayerModel(CBasePlayer* pPlayer);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
float m_flEgonBustingCheckTime = -1.0f;
|
||||||
|
void CheckForEgons();
|
||||||
|
};
|
||||||
|
|
||||||
inline DLL_GLOBAL CGameRules* g_pGameRules = nullptr;
|
inline DLL_GLOBAL CGameRules* g_pGameRules = nullptr;
|
||||||
inline DLL_GLOBAL bool g_fGameOver;
|
inline DLL_GLOBAL bool g_fGameOver;
|
||||||
inline bool g_teamplay = false;
|
inline bool g_teamplay = false;
|
||||||
|
|
|
@ -34,6 +34,9 @@
|
||||||
#define WEAPON_RESPAWN_TIME 20
|
#define WEAPON_RESPAWN_TIME 20
|
||||||
#define AMMO_RESPAWN_TIME 20
|
#define AMMO_RESPAWN_TIME 20
|
||||||
|
|
||||||
|
// longest the intermission can last, in seconds
|
||||||
|
#define MAX_INTERMISSION_TIME 120
|
||||||
|
|
||||||
CVoiceGameMgr g_VoiceGameMgr;
|
CVoiceGameMgr g_VoiceGameMgr;
|
||||||
|
|
||||||
class CMultiplayGameMgrHelper : public IVoiceGameMgrHelper
|
class CMultiplayGameMgrHelper : public IVoiceGameMgrHelper
|
||||||
|
@ -159,9 +162,6 @@ void CHalfLifeMultiplay::RefreshSkillData()
|
||||||
gSkillData.plrDmgHornet = 10;
|
gSkillData.plrDmgHornet = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// longest the intermission can last, in seconds
|
|
||||||
#define MAX_INTERMISSION_TIME 120
|
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
//=========================================================
|
//=========================================================
|
||||||
void CHalfLifeMultiplay::Think()
|
void CHalfLifeMultiplay::Think()
|
||||||
|
@ -1631,3 +1631,286 @@ void CHalfLifeMultiplay::SendMOTDToClient(edict_t* client)
|
||||||
|
|
||||||
FREE_FILE(aFileList);
|
FREE_FILE(aFileList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
//=========================================================
|
||||||
|
// Busters Gamerules
|
||||||
|
//=========================================================
|
||||||
|
//=========================================================
|
||||||
|
|
||||||
|
#define EGON_BUSTING_TIME 10
|
||||||
|
|
||||||
|
bool IsBustingGame()
|
||||||
|
{
|
||||||
|
return sv_busters.value == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsPlayerBusting(CBaseEntity* pPlayer)
|
||||||
|
{
|
||||||
|
if (!pPlayer || !pPlayer->IsPlayer() || !IsBustingGame())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ((CBasePlayer*)pPlayer)->HasPlayerItemFromID(WEAPON_EGON);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BustingCanHaveItem(CBasePlayer* pPlayer, CBaseEntity* pItem)
|
||||||
|
{
|
||||||
|
bool bIsWeaponOrAmmo = false;
|
||||||
|
|
||||||
|
if (strstr(STRING(pItem->pev->classname), "weapon_") || strstr(STRING(pItem->pev->classname), "ammo_"))
|
||||||
|
{
|
||||||
|
bIsWeaponOrAmmo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Busting players can't have ammo nor weapons
|
||||||
|
if (IsPlayerBusting(pPlayer) && bIsWeaponOrAmmo)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
CMultiplayBusters::CMultiplayBusters()
|
||||||
|
{
|
||||||
|
m_flEgonBustingCheckTime = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
void CMultiplayBusters::Think()
|
||||||
|
{
|
||||||
|
CheckForEgons();
|
||||||
|
|
||||||
|
CHalfLifeMultiplay::Think();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
int CMultiplayBusters::IPointsForKill(CBasePlayer* pAttacker, CBasePlayer* pKilled)
|
||||||
|
{
|
||||||
|
// If the attacker is busting, they get a point per kill
|
||||||
|
if (IsPlayerBusting(pAttacker))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// If the victim is busting, then the attacker gets a point
|
||||||
|
if (IsPlayerBusting(pKilled))
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
void CMultiplayBusters::PlayerKilled(CBasePlayer* pVictim, entvars_t* pKiller, entvars_t* pInflictor)
|
||||||
|
{
|
||||||
|
if (IsPlayerBusting(pVictim))
|
||||||
|
{
|
||||||
|
UTIL_ClientPrintAll(HUD_PRINTCENTER, "The Buster is dead!!");
|
||||||
|
|
||||||
|
// Reset egon check time
|
||||||
|
m_flEgonBustingCheckTime = -1;
|
||||||
|
|
||||||
|
CBasePlayer* peKiller = NULL;
|
||||||
|
CBaseEntity* ktmp = CBaseEntity::Instance(pKiller);
|
||||||
|
|
||||||
|
if (ktmp && (ktmp->Classify() == CLASS_PLAYER))
|
||||||
|
{
|
||||||
|
peKiller = (CBasePlayer*)ktmp;
|
||||||
|
}
|
||||||
|
else if (ktmp && (ktmp->Classify() == CLASS_VEHICLE))
|
||||||
|
{
|
||||||
|
CBasePlayer* pDriver = ((CFuncVehicle*)ktmp)->m_pDriver;
|
||||||
|
|
||||||
|
if (pDriver != NULL)
|
||||||
|
{
|
||||||
|
peKiller = pDriver;
|
||||||
|
ktmp = pDriver;
|
||||||
|
pKiller = pDriver->pev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (peKiller)
|
||||||
|
{
|
||||||
|
UTIL_ClientPrintAll(HUD_PRINTTALK, UTIL_VarArgs("%s has has killed the Buster!\n", STRING((CBasePlayer*)peKiller->pev->netname)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pVictim->pev->renderfx = kRenderFxNone;
|
||||||
|
pVictim->pev->rendercolor = g_vecZero;
|
||||||
|
// pVictim->pev->effects &= ~EF_BRIGHTFIELD;
|
||||||
|
}
|
||||||
|
|
||||||
|
CHalfLifeMultiplay::PlayerKilled(pVictim, pKiller, pInflictor);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
void CMultiplayBusters::DeathNotice(CBasePlayer* pVictim, entvars_t* pKiller, entvars_t* pevInflictor)
|
||||||
|
{
|
||||||
|
// Only death notices that the Buster was involved in in Busting game mode
|
||||||
|
if (!IsPlayerBusting(pVictim) && !IsPlayerBusting(CBaseEntity::Instance(pKiller)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
CHalfLifeMultiplay::DeathNotice(pVictim, pKiller, pevInflictor);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
int CMultiplayBusters::WeaponShouldRespawn(CBasePlayerItem* pWeapon)
|
||||||
|
{
|
||||||
|
if (pWeapon->m_iId == WEAPON_EGON)
|
||||||
|
return GR_WEAPON_RESPAWN_NO;
|
||||||
|
|
||||||
|
return CHalfLifeMultiplay::WeaponShouldRespawn(pWeapon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// CheckForEgons:
|
||||||
|
// Check to see if any player has an egon
|
||||||
|
// If they don't then get the lowest player on the scoreboard and give them one
|
||||||
|
// Then check to see if any weapon boxes out there has an egon, and delete it
|
||||||
|
//=========================================================
|
||||||
|
void CMultiplayBusters::CheckForEgons()
|
||||||
|
{
|
||||||
|
if (m_flEgonBustingCheckTime <= 0.0f)
|
||||||
|
{
|
||||||
|
m_flEgonBustingCheckTime = gpGlobals->time + EGON_BUSTING_TIME;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_flEgonBustingCheckTime <= gpGlobals->time)
|
||||||
|
{
|
||||||
|
m_flEgonBustingCheckTime = -1.0f;
|
||||||
|
|
||||||
|
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||||
|
{
|
||||||
|
CBasePlayer* pPlayer = (CBasePlayer*)UTIL_PlayerByIndex(i);
|
||||||
|
|
||||||
|
// Someone is busting, no need to continue
|
||||||
|
if (IsPlayerBusting(pPlayer))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bBestFrags = 9999;
|
||||||
|
CBasePlayer* pBestPlayer = NULL;
|
||||||
|
|
||||||
|
for (int i = 1; i <= gpGlobals->maxClients; i++)
|
||||||
|
{
|
||||||
|
CBasePlayer* pPlayer = (CBasePlayer*)UTIL_PlayerByIndex(i);
|
||||||
|
|
||||||
|
if (pPlayer && pPlayer->pev->frags <= bBestFrags)
|
||||||
|
{
|
||||||
|
bBestFrags = pPlayer->pev->frags;
|
||||||
|
pBestPlayer = pPlayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pBestPlayer)
|
||||||
|
{
|
||||||
|
pBestPlayer->GiveNamedItem("weapon_egon");
|
||||||
|
|
||||||
|
CBaseEntity* pEntity = NULL;
|
||||||
|
|
||||||
|
// Find a weaponbox that includes an Egon, then destroy it
|
||||||
|
while ((pEntity = UTIL_FindEntityByClassname(pEntity, "weaponbox")) != NULL)
|
||||||
|
{
|
||||||
|
CWeaponBox* pWeaponBox = (CWeaponBox*)pEntity;
|
||||||
|
|
||||||
|
if (pWeaponBox)
|
||||||
|
{
|
||||||
|
CBasePlayerItem* pWeapon;
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_ITEM_TYPES; i++)
|
||||||
|
{
|
||||||
|
pWeapon = pWeaponBox->m_rgpPlayerItems[i];
|
||||||
|
|
||||||
|
while (pWeapon)
|
||||||
|
{
|
||||||
|
// There you are, bye box
|
||||||
|
if (pWeapon->m_iId == WEAPON_EGON)
|
||||||
|
{
|
||||||
|
pWeaponBox->Kill();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pWeapon = pWeapon->m_pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
bool CMultiplayBusters::CanHavePlayerItem(CBasePlayer* pPlayer, CBasePlayerItem* pItem)
|
||||||
|
{
|
||||||
|
// Buster cannot have more weapons nor ammo
|
||||||
|
if (BustingCanHaveItem(pPlayer, pItem) == false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHalfLifeMultiplay::CanHavePlayerItem(pPlayer, pItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
bool CMultiplayBusters::CanHaveItem(CBasePlayer* pPlayer, CItem* pItem)
|
||||||
|
{
|
||||||
|
// Buster cannot have more weapons nor ammo
|
||||||
|
if (BustingCanHaveItem(pPlayer, pItem) == false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CHalfLifeMultiplay::CanHaveItem(pPlayer, pItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
void CMultiplayBusters::PlayerGotWeapon(CBasePlayer* pPlayer, CBasePlayerItem* pWeapon)
|
||||||
|
{
|
||||||
|
if (pWeapon->m_iId == WEAPON_EGON)
|
||||||
|
{
|
||||||
|
pPlayer->RemoveAllItems(false);
|
||||||
|
|
||||||
|
UTIL_ClientPrintAll(HUD_PRINTCENTER, "Long live the new Buster!");
|
||||||
|
UTIL_ClientPrintAll(HUD_PRINTTALK, UTIL_VarArgs("%s is busting!\n", STRING((CBasePlayer*)pPlayer->pev->netname)));
|
||||||
|
|
||||||
|
SetPlayerModel(pPlayer);
|
||||||
|
|
||||||
|
pPlayer->pev->health = pPlayer->pev->max_health;
|
||||||
|
pPlayer->pev->armorvalue = 100;
|
||||||
|
|
||||||
|
pPlayer->pev->renderfx = kRenderFxGlowShell;
|
||||||
|
pPlayer->pev->renderamt = 25;
|
||||||
|
pPlayer->pev->rendercolor = Vector(0, 75, 250);
|
||||||
|
|
||||||
|
CBasePlayerWeapon* pEgon = (CBasePlayerWeapon*)pWeapon;
|
||||||
|
|
||||||
|
pEgon->m_iDefaultAmmo = 100;
|
||||||
|
pPlayer->m_rgAmmo[pEgon->m_iPrimaryAmmoType] = pEgon->m_iDefaultAmmo;
|
||||||
|
|
||||||
|
g_engfuncs.pfnSetClientKeyValue(pPlayer->entindex(), g_engfuncs.pfnGetInfoKeyBuffer(pPlayer->edict()), "model", "ivan");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMultiplayBusters::ClientUserInfoChanged(CBasePlayer* pPlayer, char* infobuffer)
|
||||||
|
{
|
||||||
|
SetPlayerModel(pPlayer);
|
||||||
|
|
||||||
|
// Set preferences
|
||||||
|
pPlayer->SetPrefsFromUserinfo(infobuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMultiplayBusters::PlayerSpawn(CBasePlayer* pPlayer)
|
||||||
|
{
|
||||||
|
CHalfLifeMultiplay::PlayerSpawn(pPlayer);
|
||||||
|
SetPlayerModel(pPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMultiplayBusters::SetPlayerModel(CBasePlayer* pPlayer)
|
||||||
|
{
|
||||||
|
if (IsPlayerBusting(pPlayer))
|
||||||
|
{
|
||||||
|
g_engfuncs.pfnSetClientKeyValue(pPlayer->entindex(), g_engfuncs.pfnGetInfoKeyBuffer(pPlayer->edict()), "model", "ivan");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_engfuncs.pfnSetClientKeyValue(pPlayer->entindex(), g_engfuncs.pfnGetInfoKeyBuffer(pPlayer->edict()), "model", "skeleton");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -47,6 +47,8 @@
|
||||||
extern void CopyToBodyQue(entvars_t* pev);
|
extern void CopyToBodyQue(entvars_t* pev);
|
||||||
extern edict_t* EntSelectSpawnPoint(CBaseEntity* pPlayer);
|
extern edict_t* EntSelectSpawnPoint(CBaseEntity* pPlayer);
|
||||||
|
|
||||||
|
extern bool IsBustingGame();
|
||||||
|
|
||||||
#define TRAIN_ACTIVE 0x80
|
#define TRAIN_ACTIVE 0x80
|
||||||
#define TRAIN_NEW 0xc0
|
#define TRAIN_NEW 0xc0
|
||||||
#define TRAIN_OFF 0x00
|
#define TRAIN_OFF 0x00
|
||||||
|
@ -688,24 +690,67 @@ void CBasePlayer::PackDeadPlayerItems()
|
||||||
iPA = 0;
|
iPA = 0;
|
||||||
iPW = 0;
|
iPW = 0;
|
||||||
|
|
||||||
// pack the ammo
|
if (IsBustingGame())
|
||||||
while (iPackAmmo[iPA] != -1)
|
|
||||||
{
|
{
|
||||||
pWeaponBox->PackAmmo(MAKE_STRING(CBasePlayerItem::AmmoInfoArray[iPackAmmo[iPA]].pszName), m_rgAmmo[iPackAmmo[iPA]]);
|
if (HasNamedPlayerItem("weapon_egon"))
|
||||||
iPA++;
|
{
|
||||||
}
|
for (i = 0; i < MAX_ITEM_TYPES; i++)
|
||||||
|
{
|
||||||
|
CBasePlayerItem* pItem = m_rgpPlayerItems[i];
|
||||||
|
|
||||||
// now pack all of the items in the lists
|
if (pItem)
|
||||||
while (rgpPackWeapons[iPW])
|
{
|
||||||
|
if (!strcmp("weapon_egon", STRING(pItem->pev->classname)))
|
||||||
|
{
|
||||||
|
pWeaponBox->PackWeapon(pItem);
|
||||||
|
|
||||||
|
SET_MODEL(ENT(pWeaponBox->pev), "models/w_egon.mdl");
|
||||||
|
|
||||||
|
pWeaponBox->pev->velocity = Vector(0, 0, 0);
|
||||||
|
pWeaponBox->pev->renderfx = kRenderFxGlowShell;
|
||||||
|
pWeaponBox->pev->renderamt = 25;
|
||||||
|
pWeaponBox->pev->rendercolor = Vector(0, 75, 250);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// weapon unhooked from the player. Pack it into der box.
|
bool bPackItems = true;
|
||||||
pWeaponBox->PackWeapon(rgpPackWeapons[iPW]);
|
|
||||||
|
|
||||||
iPW++;
|
if (iAmmoRules == GR_PLR_DROP_AMMO_ACTIVE && iWeaponRules == GR_PLR_DROP_GUN_ACTIVE)
|
||||||
|
{
|
||||||
|
if (FClassnameIs(rgpPackWeapons[0]->pev, "weapon_satchel") && (iPackAmmo[0] == -1 || (m_rgAmmo[iPackAmmo[0]] == 0)))
|
||||||
|
{
|
||||||
|
bPackItems = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bPackItems)
|
||||||
|
{
|
||||||
|
// pack the ammo
|
||||||
|
while (iPackAmmo[iPA] != -1)
|
||||||
|
{
|
||||||
|
pWeaponBox->PackAmmo(MAKE_STRING(CBasePlayerItem::AmmoInfoArray[iPackAmmo[iPA]].pszName), m_rgAmmo[iPackAmmo[iPA]]);
|
||||||
|
iPA++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// now pack all of the items in the lists
|
||||||
|
while (rgpPackWeapons[iPW])
|
||||||
|
{
|
||||||
|
// weapon unhooked from the player. Pack it into der box.
|
||||||
|
pWeaponBox->PackWeapon(rgpPackWeapons[iPW]);
|
||||||
|
|
||||||
|
iPW++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pWeaponBox->pev->velocity = pev->velocity * 1.2; // weaponbox has player's velocity, then some.
|
||||||
}
|
}
|
||||||
|
|
||||||
pWeaponBox->pev->velocity = pev->velocity * 1.2; // weaponbox has player's velocity, then some.
|
|
||||||
|
|
||||||
RemoveAllItems(true); // now strip off everything that wasn't handled by the code above.
|
RemoveAllItems(true); // now strip off everything that wasn't handled by the code above.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4746,6 +4791,33 @@ bool CBasePlayer::HasNamedPlayerItem(const char* pszItemName)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=========================================================
|
||||||
|
// HasPlayerItemFromID
|
||||||
|
// Just compare IDs, rather than classnames
|
||||||
|
//=========================================================
|
||||||
|
bool CBasePlayer::HasPlayerItemFromID(int nID)
|
||||||
|
{
|
||||||
|
CBasePlayerItem* pItem;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_ITEM_TYPES; i++)
|
||||||
|
{
|
||||||
|
pItem = m_rgpPlayerItems[i];
|
||||||
|
|
||||||
|
while (pItem)
|
||||||
|
{
|
||||||
|
if (pItem->m_iId == nID)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pItem = pItem->m_pNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
//
|
//
|
||||||
//=========================================================
|
//=========================================================
|
||||||
|
|
|
@ -283,6 +283,7 @@ public:
|
||||||
void DropPlayerItem(char* pszItemName);
|
void DropPlayerItem(char* pszItemName);
|
||||||
bool HasPlayerItem(CBasePlayerItem* pCheckItem);
|
bool HasPlayerItem(CBasePlayerItem* pCheckItem);
|
||||||
bool HasNamedPlayerItem(const char* pszItemName);
|
bool HasNamedPlayerItem(const char* pszItemName);
|
||||||
|
bool HasPlayerItemFromID(int nID);
|
||||||
bool HasWeapons(); // do I have ANY weapons?
|
bool HasWeapons(); // do I have ANY weapons?
|
||||||
void SelectPrevItem(int iItem);
|
void SelectPrevItem(int iItem);
|
||||||
void SelectNextItem(int iItem);
|
void SelectNextItem(int iItem);
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
#define TRACER_FREQ 4 // Tracers fire every fourth bullet
|
#define TRACER_FREQ 4 // Tracers fire every fourth bullet
|
||||||
|
|
||||||
|
extern bool IsBustingGame();
|
||||||
|
extern bool IsPlayerBusting(CBaseEntity* pPlayer);
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
// MaxAmmoCarry - pass in a name and this function will tell
|
// MaxAmmoCarry - pass in a name and this function will tell
|
||||||
|
@ -444,6 +446,19 @@ void CBasePlayerItem::FallThink()
|
||||||
|
|
||||||
Materialize();
|
Materialize();
|
||||||
}
|
}
|
||||||
|
else if (m_pPlayer != NULL)
|
||||||
|
{
|
||||||
|
SetThink(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This weapon is an egon, it has no owner and we're in busting mode, so just remove it when it hits the ground
|
||||||
|
if (IsBustingGame() && FNullEnt(pev->owner))
|
||||||
|
{
|
||||||
|
if (!strcmp("weapon_egon", STRING(pev->classname)))
|
||||||
|
{
|
||||||
|
UTIL_Remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=========================================================
|
//=========================================================
|
||||||
|
@ -536,6 +551,9 @@ void CBasePlayerItem::DefaultTouch(CBaseEntity* pOther)
|
||||||
if (!pOther->IsPlayer())
|
if (!pOther->IsPlayer())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (IsPlayerBusting(pOther))
|
||||||
|
return;
|
||||||
|
|
||||||
CBasePlayer* pPlayer = (CBasePlayer*)pOther;
|
CBasePlayer* pPlayer = (CBasePlayer*)pOther;
|
||||||
|
|
||||||
// can I have this?
|
// can I have this?
|
||||||
|
@ -811,7 +829,7 @@ bool CBasePlayerWeapon::IsUseable()
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip is empty (or nonexistant) and the player has no more ammo of this type.
|
// clip is empty (or nonexistant) and the player has no more ammo of this type.
|
||||||
return false;
|
return CanDeploy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBasePlayerWeapon::DefaultDeploy(const char* szViewModel, const char* szWeaponModel, int iAnim, const char* szAnimExt, int body)
|
bool CBasePlayerWeapon::DefaultDeploy(const char* szViewModel, const char* szWeaponModel, int iAnim, const char* szAnimExt, int body)
|
||||||
|
|
|
@ -974,6 +974,7 @@ public:
|
||||||
void Fire(const Vector& vecOrigSrc, const Vector& vecDir);
|
void Fire(const Vector& vecOrigSrc, const Vector& vecDir);
|
||||||
|
|
||||||
bool HasAmmo();
|
bool HasAmmo();
|
||||||
|
bool CanHolster();
|
||||||
|
|
||||||
void UseAmmo(int count);
|
void UseAmmo(int count);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue