/*** * * Copyright (c) 1996-2002, Valve LLC. All rights reserved. * * This product contains software technology licensed from Id * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * All Rights Reserved. * * Use, distribution, and modification of this source code and/or resulting * object code is restricted to non-commercial enhancements to products from * Valve LLC. All other use, distribution, or modification is prohibited * without written permission from Valve LLC. * ****/ #include "stdafx.h" #include "cbase.h" #include "player.h" #include "monsters.h" #include "weapons.h" #include "nodes.h" #include "soundent.h" #include "decals.h" #include "gamerules.h" #include "hltv.h" #ifdef LINUX #include #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif bool g_bGlockBurstMode; DLL_GLOBAL short g_sModelIndexLaser; DLL_GLOBAL const char *g_pModelNameLaser = "sprites/laserbeam.spr"; DLL_GLOBAL short g_sModelIndexLaserDot; DLL_GLOBAL short g_sModelIndexFireball; DLL_GLOBAL short g_sModelIndexFireball2; DLL_GLOBAL short g_sModelIndexFireball3; DLL_GLOBAL short g_sModelIndexFireball4; DLL_GLOBAL short g_sModelIndexSmoke; DLL_GLOBAL short g_sModelIndexSmokePuff; DLL_GLOBAL short g_sModelIndexWExplosion; DLL_GLOBAL short g_sModelIndexBubbles; DLL_GLOBAL short g_sModelIndexBloodDrop; DLL_GLOBAL short g_sModelIndexBloodSpray; DLL_GLOBAL short g_sModelIndexRadio; DLL_GLOBAL short g_sModelIndexCTGhost; DLL_GLOBAL short g_sModelIndexTGhost; DLL_GLOBAL short g_sModelIndexC4Glow; ItemInfo CBasePlayerItem::ItemInfoArray[MAX_WEAPONS]; AmmoInfo CBasePlayerItem::AmmoInfoArray[MAX_AMMO_SLOTS]; extern int gEvilImpulse101; extern int gmsgCurWeapon; MULTIDAMAGE gMultiDamage; int MaxAmmoCarry(int iszName) { for (int i = 0; i < MAX_WEAPONS; i++) { if (CBasePlayerItem::ItemInfoArray[i].pszAmmo1 && !strcmp(STRING(iszName), CBasePlayerItem::ItemInfoArray[i].pszAmmo1)) return CBasePlayerItem::ItemInfoArray[i].iMaxAmmo1; if (CBasePlayerItem::ItemInfoArray[i].pszAmmo2 && !strcmp(STRING(iszName), CBasePlayerItem::ItemInfoArray[i].pszAmmo2)) return CBasePlayerItem::ItemInfoArray[i].iMaxAmmo2; } ALERT(at_console, "MaxAmmoCarry() doesn't recognize '%s'!\n", STRING(iszName)); return -1; } void ClearMultiDamage(void) { gMultiDamage.pEntity = NULL; gMultiDamage.amount = 0; gMultiDamage.type = 0; } void ApplyMultiDamage(entvars_t *pevInflictor, entvars_t *pevAttacker) { if (!gMultiDamage.pEntity) return; gMultiDamage.pEntity->TakeDamage(pevInflictor, pevAttacker, gMultiDamage.amount, gMultiDamage.type); } void AddMultiDamage(entvars_t *pevInflictor, CBaseEntity *pEntity, float flDamage, int bitsDamageType) { if (!pEntity) return; gMultiDamage.type |= bitsDamageType; if (pEntity != gMultiDamage.pEntity) { ApplyMultiDamage(pevInflictor,pevInflictor); gMultiDamage.pEntity = pEntity; gMultiDamage.amount = 0; } gMultiDamage.amount += flDamage; } void SpawnBlood(Vector vecSpot, int bloodColor, float flDamage) { UTIL_BloodDrips(vecSpot, g_vecAttackDir, bloodColor, flDamage); } void DecalGunshot(TraceResult *pTrace, int iBulletType, bool ClientOnly, entvars_t *pShooter, bool bHitMetal) { } extern int gmsgBrass; void EjectBrass(const Vector &vecOrigin, const Vector &vecLeft, const Vector &vecVelocity, float rotation, int model, int soundtype, int entityIndex) { MESSAGE_BEGIN(MSG_PVS, gmsgBrass, vecOrigin); WRITE_BYTE(TE_MODEL); WRITE_COORD(vecOrigin.x); WRITE_COORD(vecOrigin.y); WRITE_COORD(vecOrigin.z); WRITE_COORD(vecLeft.x); WRITE_COORD(vecLeft.y); WRITE_COORD(vecLeft.z); WRITE_COORD(vecVelocity.x); WRITE_COORD(vecVelocity.y); WRITE_COORD(vecVelocity.z); WRITE_ANGLE(rotation); WRITE_SHORT(model); WRITE_BYTE(soundtype); WRITE_BYTE(entityIndex); MESSAGE_END(); } void EjectBrass2(const Vector &vecOrigin, const Vector &vecVelocity, float rotation, int model, int soundtype, entvars_t *pev) { MESSAGE_BEGIN(MSG_ONE, SVC_TEMPENTITY, NULL, pev); WRITE_BYTE(TE_MODEL); WRITE_COORD(vecOrigin.x); WRITE_COORD(vecOrigin.y); WRITE_COORD(vecOrigin.z); WRITE_COORD(vecVelocity.x); WRITE_COORD(vecVelocity.y); WRITE_COORD(vecVelocity.z); WRITE_ANGLE(rotation); WRITE_SHORT(model); WRITE_BYTE(0); WRITE_BYTE(5); MESSAGE_END(); } int giAmmoIndex = 0; void AddAmmoNameToAmmoRegistry(const char *szAmmoName) { for (int i = 0; i < MAX_AMMO_SLOTS; i++) { if (!CBasePlayerItem::AmmoInfoArray[i].pszName) continue; if (!stricmp(CBasePlayerItem::AmmoInfoArray[i].pszName, szAmmoName)) return; } giAmmoIndex++; ASSERT(giAmmoIndex < MAX_AMMO_SLOTS); if (giAmmoIndex >= MAX_AMMO_SLOTS) giAmmoIndex = 0; CBasePlayerItem::AmmoInfoArray[giAmmoIndex].pszName = szAmmoName; CBasePlayerItem::AmmoInfoArray[giAmmoIndex].iId = giAmmoIndex; } void UTIL_PrecacheOtherWeapon(const char *szClassname) { edict_t *pent = CREATE_NAMED_ENTITY(MAKE_STRING(szClassname)); if (FNullEnt(pent)) { ALERT(at_console, "NULL Ent in UTIL_PrecacheOtherWeapon\n"); return; } CBaseEntity *pEntity = CBaseEntity::Instance(VARS(pent)); if (pEntity) { ItemInfo II; pEntity->Precache(); memset(&II, 0, sizeof II); if (((CBasePlayerItem *)pEntity)->GetItemInfo(&II)) { CBasePlayerItem::ItemInfoArray[II.iId] = II; if (II.pszAmmo1 && *II.pszAmmo1) AddAmmoNameToAmmoRegistry(II.pszAmmo1); if (II.pszAmmo2 && *II.pszAmmo2) AddAmmoNameToAmmoRegistry(II.pszAmmo2); memset(&II, 0, sizeof II); } } REMOVE_ENTITY(pent); } void W_Precache(void) { memset(CBasePlayerItem::ItemInfoArray, 0, sizeof(CBasePlayerItem::ItemInfoArray)); memset(CBasePlayerItem::AmmoInfoArray, 0, sizeof(CBasePlayerItem::AmmoInfoArray)); giAmmoIndex = 0; UTIL_PrecacheOther("item_suit"); UTIL_PrecacheOther("item_battery"); UTIL_PrecacheOther("item_antidote"); UTIL_PrecacheOther("item_security"); UTIL_PrecacheOther("item_longjump"); UTIL_PrecacheOther("item_kevlar"); UTIL_PrecacheOther("item_assaultsuit"); UTIL_PrecacheOther("item_thighpack"); UTIL_PrecacheOtherWeapon("weapon_awp"); UTIL_PrecacheOther("ammo_338magnum"); UTIL_PrecacheOtherWeapon("weapon_g3sg1"); UTIL_PrecacheOtherWeapon("weapon_ak47"); UTIL_PrecacheOtherWeapon("weapon_scout"); UTIL_PrecacheOther("ammo_762nato"); UTIL_PrecacheOtherWeapon("weapon_m249"); UTIL_PrecacheOther("ammo_556natobox"); UTIL_PrecacheOtherWeapon("weapon_m4a1"); UTIL_PrecacheOtherWeapon("weapon_sg552"); UTIL_PrecacheOtherWeapon("weapon_aug"); UTIL_PrecacheOtherWeapon("weapon_sg550"); UTIL_PrecacheOther("ammo_556nato"); UTIL_PrecacheOtherWeapon("weapon_m3"); UTIL_PrecacheOtherWeapon("weapon_xm1014"); UTIL_PrecacheOther("ammo_buckshot"); UTIL_PrecacheOtherWeapon("weapon_usp"); UTIL_PrecacheOtherWeapon("weapon_mac10"); UTIL_PrecacheOtherWeapon("weapon_ump45"); UTIL_PrecacheOther("ammo_45acp"); UTIL_PrecacheOtherWeapon("weapon_fiveseven"); UTIL_PrecacheOtherWeapon("weapon_p90"); UTIL_PrecacheOther("ammo_57mm"); UTIL_PrecacheOtherWeapon("weapon_deagle"); UTIL_PrecacheOther("ammo_50ae"); UTIL_PrecacheOtherWeapon("weapon_p228"); UTIL_PrecacheOther("ammo_357sig"); UTIL_PrecacheOtherWeapon("weapon_knife"); UTIL_PrecacheOtherWeapon("weapon_glock18"); UTIL_PrecacheOtherWeapon("weapon_mp5navy"); UTIL_PrecacheOtherWeapon("weapon_tmp"); UTIL_PrecacheOtherWeapon("weapon_elite"); UTIL_PrecacheOther("ammo_9mm"); UTIL_PrecacheOtherWeapon("weapon_flashbang"); UTIL_PrecacheOtherWeapon("weapon_hegrenade"); UTIL_PrecacheOtherWeapon("weapon_smokegrenade"); UTIL_PrecacheOtherWeapon("weapon_c4"); UTIL_PrecacheOtherWeapon("weapon_galil"); UTIL_PrecacheOtherWeapon("weapon_famas"); if (g_pGameRules->IsDeathmatch()) UTIL_PrecacheOther("weaponbox"); g_sModelIndexFireball = PRECACHE_MODEL("sprites/zerogxplode.spr"); g_sModelIndexWExplosion = PRECACHE_MODEL("sprites/WXplo1.spr"); g_sModelIndexSmoke = PRECACHE_MODEL("sprites/steam1.spr"); g_sModelIndexBubbles = PRECACHE_MODEL("sprites/bubble.spr"); g_sModelIndexBloodSpray = PRECACHE_MODEL("sprites/bloodspray.spr"); g_sModelIndexBloodDrop = PRECACHE_MODEL("sprites/blood.spr"); g_sModelIndexSmokePuff = PRECACHE_MODEL("sprites/smokepuff.spr"); g_sModelIndexFireball2 = PRECACHE_MODEL("sprites/eexplo.spr"); g_sModelIndexFireball3 = PRECACHE_MODEL("sprites/fexplo.spr"); g_sModelIndexFireball4 = PRECACHE_MODEL("sprites/fexplo1.spr"); g_sModelIndexRadio = PRECACHE_MODEL("sprites/radio.spr"); g_sModelIndexCTGhost = PRECACHE_MODEL("sprites/b-tele1.spr"); g_sModelIndexTGhost = PRECACHE_MODEL("sprites/c-tele1.spr"); g_sModelIndexC4Glow = PRECACHE_MODEL("sprites/ledglow.spr"); g_sModelIndexLaser = PRECACHE_MODEL((char *)g_pModelNameLaser); g_sModelIndexLaserDot = PRECACHE_MODEL("sprites/laserdot.spr"); PRECACHE_MODEL("models/grenade.mdl"); PRECACHE_MODEL("sprites/explode1.spr"); PRECACHE_SOUND("weapons/debris1.wav"); PRECACHE_SOUND("weapons/debris2.wav"); PRECACHE_SOUND("weapons/debris3.wav"); PRECACHE_SOUND("weapons/grenade_hit1.wav"); PRECACHE_SOUND("weapons/grenade_hit2.wav"); PRECACHE_SOUND("weapons/grenade_hit3.wav"); PRECACHE_SOUND("weapons/bullet_hit1.wav"); PRECACHE_SOUND("weapons/bullet_hit2.wav"); PRECACHE_SOUND("items/weapondrop1.wav"); PRECACHE_SOUND("weapons/generic_reload.wav"); } TYPEDESCRIPTION CBasePlayerItem::m_SaveData[] = { DEFINE_FIELD(CBasePlayerItem, m_pPlayer, FIELD_CLASSPTR), DEFINE_FIELD(CBasePlayerItem, m_pNext, FIELD_CLASSPTR), DEFINE_FIELD(CBasePlayerItem, m_iId, FIELD_INTEGER), }; IMPLEMENT_SAVERESTORE(CBasePlayerItem, CBaseAnimating); TYPEDESCRIPTION CBasePlayerWeapon::m_SaveData[] = { #ifdef CLIENT_WEAPONS DEFINE_FIELD(CBasePlayerWeapon, m_flNextPrimaryAttack, FIELD_FLOAT), DEFINE_FIELD(CBasePlayerWeapon, m_flNextSecondaryAttack, FIELD_FLOAT), DEFINE_FIELD(CBasePlayerWeapon, m_flTimeWeaponIdle, FIELD_FLOAT), #else DEFINE_FIELD(CBasePlayerWeapon, m_flNextPrimaryAttack, FIELD_TIME), DEFINE_FIELD(CBasePlayerWeapon, m_flNextSecondaryAttack, FIELD_TIME), DEFINE_FIELD(CBasePlayerWeapon, m_flTimeWeaponIdle, FIELD_TIME), #endif DEFINE_FIELD(CBasePlayerWeapon, m_iPrimaryAmmoType, FIELD_INTEGER), DEFINE_FIELD(CBasePlayerWeapon, m_iSecondaryAmmoType, FIELD_INTEGER), DEFINE_FIELD(CBasePlayerWeapon, m_iClip, FIELD_INTEGER), DEFINE_FIELD(CBasePlayerWeapon, m_iDefaultAmmo, FIELD_INTEGER), }; IMPLEMENT_SAVERESTORE(CBasePlayerWeapon, CBasePlayerItem); void CBasePlayerItem::SetObjectCollisionBox(void) { pev->absmin = pev->origin + Vector(-24, -24, 0); pev->absmax = pev->origin + Vector(24, 24, 16); } void CBasePlayerItem::FallInit(void) { pev->movetype = MOVETYPE_TOSS; pev->solid = SOLID_BBOX; UTIL_SetOrigin(pev, pev->origin); UTIL_SetSize(pev, Vector(0, 0, 0), Vector(0, 0, 0)); SetTouch(&CBasePlayerItem::DefaultTouch); SetThink(&CBasePlayerItem::FallThink); pev->nextthink = gpGlobals->time + 0.1; } void CBasePlayerItem::FallThink(void) { pev->nextthink = gpGlobals->time + 0.1; if (FBitSet(pev->flags, FL_ONGROUND)) { if (!FNullEnt(pev->owner)) { int pitch = 95 + RANDOM_LONG(0, 29); EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "items/weapondrop1.wav", VOL_NORM, ATTN_NORM, 0, pitch); } pev->angles.x = 0; pev->angles.z = 0; Materialize(); } } void CBasePlayerItem::Materialize(void) { if (pev->effects & EF_NODRAW) { if (g_pGameRules->IsMultiplayer()) EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "items/suitchargeok1.wav", VOL_NORM, ATTN_NORM, 0, 150); pev->effects &= ~EF_NODRAW; pev->effects |= EF_MUZZLEFLASH; } pev->solid = SOLID_TRIGGER; UTIL_SetOrigin(pev, pev->origin); SetTouch(&CBasePlayerItem::DefaultTouch); if (g_pGameRules->IsMultiplayer()) { SetThink(&CBaseEntity::SUB_Remove); pev->nextthink = gpGlobals->time + 1; } else SetThink(NULL); } void CBasePlayerItem::AttemptToMaterialize(void) { float time = g_pGameRules->FlWeaponTryRespawn(this); if (!time) { Materialize(); return; } pev->nextthink = gpGlobals->time + time; } void CBasePlayerItem::CheckRespawn(void) { switch (g_pGameRules->WeaponShouldRespawn(this)) { case GR_WEAPON_RESPAWN_YES: return; case GR_WEAPON_RESPAWN_NO: return; } } CBaseEntity *CBasePlayerItem::Respawn(void) { CBaseEntity *pNewWeapon = CBaseEntity::Create((char *)STRING(pev->classname), g_pGameRules->VecWeaponRespawnSpot(this), pev->angles, pev->owner); if (pNewWeapon) { pNewWeapon->pev->effects |= EF_NODRAW; pNewWeapon->SetTouch(NULL); pNewWeapon->SetThink(&CBasePlayerItem::AttemptToMaterialize); DROP_TO_FLOOR(ENT(pev)); pNewWeapon->pev->nextthink = g_pGameRules->FlWeaponRespawnTime(this); } else ALERT(at_console, "Respawn failed to create %s!\n", STRING(pev->classname)); return pNewWeapon; } void CBasePlayerItem::DefaultTouch(CBaseEntity *pOther) { if (!pOther->IsPlayer()) return; CBasePlayer *pPlayer = (CBasePlayer *)pOther; if (pPlayer->m_bIsVIP == true && m_iId != WEAPON_USP && m_iId != WEAPON_GLOCK18 && m_iId != WEAPON_P228 && m_iId != WEAPON_DEAGLE && m_iId != WEAPON_KNIFE) return; if (!g_pGameRules->CanHavePlayerItem(pPlayer, this)) { if (gEvilImpulse101) UTIL_Remove(this); return; } if (pOther->AddPlayerItem(this)) { AttachToPlayer(pPlayer); EMIT_SOUND(ENT(pPlayer->pev), CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM); } SUB_UseTargets(pOther, USE_TOGGLE, 0); } BOOL CanAttack(float attack_time, float curtime, BOOL isPredicted) { #ifdef CLIENT_WEAPONS if (!isPredicted) #else if (1) #endif return (attack_time <= curtime) ? TRUE : FALSE; else return (attack_time <= 0) ? TRUE : FALSE; } void CBasePlayerWeapon::SetPlayerShieldAnim(void) { if (m_pPlayer->HasShield() == true) { if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) strcpy(m_pPlayer->m_szAnimExtention, "shield"); else strcpy(m_pPlayer->m_szAnimExtention, "shieldgun"); } } void CBasePlayerWeapon::ResetPlayerShieldAnim(void) { if (m_pPlayer->HasShield() == true) { if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) strcpy(m_pPlayer->m_szAnimExtention, "shieldgun"); } } void CBasePlayerWeapon::EjectBrassLate(void) { UTIL_MakeVectors(m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle); Vector vecShellVelocity = m_pPlayer->pev->velocity + gpGlobals->v_right * RANDOM_FLOAT(50, 70) + gpGlobals->v_up * RANDOM_FLOAT(100, 150) + gpGlobals->v_forward * 25; //EjectBrass(pev->origin + m_pPlayer->pev->view_ofs + gpGlobals->v_up * -9 + gpGlobals->v_forward * 16 - gpGlobals->v_right * 9, vecShellVelocity, pev->angles.y, m_iShellId, TE_BOUNCE_SHELL); } bool CBasePlayerWeapon::ShieldSecondaryFire(int up_anim, int down_anim) { if (m_pPlayer->HasShield() == false) return false; if (m_iWeaponState & WPNSTATE_SHIELD_DRAWN) { m_iWeaponState &= ~WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(down_anim, UseDecrement() != FALSE); strcpy(m_pPlayer->m_szAnimExtention, "shieldgun"); m_fMaxSpeed = 250; m_pPlayer->m_bShieldDrawn = false; } else { m_iWeaponState |= WPNSTATE_SHIELD_DRAWN; SendWeaponAnim(up_anim, UseDecrement() != FALSE); strcpy(m_pPlayer->m_szAnimExtention, "shielded"); m_fMaxSpeed = 180; m_pPlayer->m_bShieldDrawn = true; } m_pPlayer->UpdateShieldCrosshair((m_iWeaponState & WPNSTATE_SHIELD_DRAWN) == 0 ); m_pPlayer->ResetMaxSpeed(); m_flNextSecondaryAttack = UTIL_WeaponTimeBase() + 0.4; m_flNextPrimaryAttack = UTIL_WeaponTimeBase() + 0.4; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 0.6; return true; } void CBasePlayerWeapon::KickBack(float up_base, float lateral_base, float up_modifier, float lateral_modifier, float up_max, float lateral_max, int direction_change) { float flFront, flSide; if (m_iShotsFired == 1) { flFront = up_base; flSide = lateral_base; } else { flFront = m_iShotsFired * up_modifier + up_base; flSide = m_iShotsFired * lateral_modifier + lateral_base; } m_pPlayer->pev->punchangle.x -= flFront; if (m_pPlayer->pev->punchangle.x < -up_max) m_pPlayer->pev->punchangle.x = -up_max; if (m_iDirection == 1) { m_pPlayer->pev->punchangle.y += flSide; if (m_pPlayer->pev->punchangle.y > lateral_max) m_pPlayer->pev->punchangle.y = lateral_max; } else { m_pPlayer->pev->punchangle.y -= flSide; if (m_pPlayer->pev->punchangle.y < -lateral_max) m_pPlayer->pev->punchangle.y = -lateral_max; } if (!RANDOM_LONG(0, direction_change)) m_iDirection = !m_iDirection; } void CBasePlayerWeapon::FireRemaining(int &shotsFired, float &shootTime, BOOL isGlock18) { m_iClip--; if (m_iClip < 0) { m_iClip = 0; shotsFired = 3; shootTime = 0; return; } UTIL_MakeVectors(m_pPlayer->pev->v_angle + m_pPlayer->pev->punchangle); Vector vecSrc = m_pPlayer->GetGunPosition(); Vector vecDir; int flags; #ifdef CLIENT_WEAPONS flags = FEV_NOTHOST; #else flags = 0; #endif if (isGlock18) { vecDir = m_pPlayer->FireBullets3(m_pPlayer->GetGunPosition(), gpGlobals->v_forward, 0.05, 8192, 1, BULLET_PLAYER_9MM, 18, 0.9, m_pPlayer->pev, TRUE, m_pPlayer->random_seed); PLAYBACK_EVENT_FULL(flags, ENT(m_pPlayer->pev), m_usFireGlock18, 0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, (int)(m_pPlayer->pev->punchangle.x * 10000), (int)(m_pPlayer->pev->punchangle.y * 10000), m_iClip != 0, FALSE); m_pPlayer->ammo_9mm--; } else { vecDir = m_pPlayer->FireBullets3(m_pPlayer->GetGunPosition(), gpGlobals->v_forward, m_fBurstSpread, 8192, 2, BULLET_PLAYER_556MM, 30, 0.96, m_pPlayer->pev, TRUE, m_pPlayer->random_seed); PLAYBACK_EVENT_FULL(flags, ENT(m_pPlayer->pev), m_usFireFamas, 0, (float *)&g_vecZero, (float *)&g_vecZero, vecDir.x, vecDir.y, (int)(m_pPlayer->pev->punchangle.x * 10000000), (int)(m_pPlayer->pev->punchangle.y * 10000000), m_iClip != 0, FALSE); m_pPlayer->ammo_556nato--; } m_pPlayer->pev->effects |= EF_MUZZLEFLASH; m_pPlayer->SetAnimation(PLAYER_ATTACK1); shotsFired++; if (shotsFired == 3) shootTime = 0; else shootTime = gpGlobals->time + 0.1; } bool CBasePlayerWeapon::HasSecondaryAttack(void) { if (m_pPlayer->HasShield() == false) { if (m_iId == WEAPON_AK47 || m_iId == WEAPON_XM1014 || m_iId == WEAPON_MAC10 || m_iId == WEAPON_ELITE || m_iId == WEAPON_FIVESEVEN || m_iId == WEAPON_MP5N || m_iId == WEAPON_M249 || m_iId == WEAPON_M3 || m_iId == WEAPON_TMP || m_iId == WEAPON_DEAGLE || m_iId == WEAPON_P228 || m_iId == WEAPON_P90 || m_iId == WEAPON_C4 || m_iId == WEAPON_GALIL) return false; } return true; } void CBasePlayerWeapon::ItemPostFrame(void) { int button = m_pPlayer->pev->button; if (!HasSecondaryAttack()) button &= ~IN_ATTACK2; if (m_flGlock18Shoot != 0) FireRemaining(m_iGlock18ShotsFired, m_flGlock18Shoot, TRUE); else if (gpGlobals->time > m_flFamasShoot && m_flFamasShoot != 0) FireRemaining(m_iFamasShotsFired, m_flFamasShoot, FALSE); if (m_flNextPrimaryAttack <= UTIL_WeaponTimeBase()) { if (m_pPlayer->m_bResumeZoom == true) { m_pPlayer->pev->fov = m_pPlayer->m_iFOV = m_pPlayer->m_iLastZoom; if (m_pPlayer->m_iFOV == m_pPlayer->m_iLastZoom) m_pPlayer->m_bResumeZoom = false; } } if (m_pPlayer->m_flEjectBrass != 0) { if (gpGlobals->time >= m_pPlayer->m_flEjectBrass) { m_pPlayer->m_flEjectBrass = 0; EjectBrassLate(); } } if (m_pPlayer->HasShield() != false) { if (m_fInReload && m_pPlayer->pev->button & IN_ATTACK2) { SecondaryAttack(); m_pPlayer->pev->button &= ~IN_ATTACK2; m_fInReload = FALSE; m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase(); } } if ((m_fInReload) && m_pPlayer->m_flNextAttack <= UTIL_WeaponTimeBase()) { int j = min(iMaxClip() - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); m_iClip += j; m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] -= j; m_pPlayer->TabulateAmmo(); m_fInReload = FALSE; } if ((button & IN_ATTACK2) && m_flNextSecondaryAttack <= UTIL_WeaponTimeBase()) { if (pszAmmo2() && !m_pPlayer->m_rgAmmo[SecondaryAmmoIndex()]) m_fFireOnEmpty = TRUE; SecondaryAttack(); m_pPlayer->pev->button &= ~IN_ATTACK2; } else if ((m_pPlayer->pev->button & IN_ATTACK) && m_flNextPrimaryAttack <= UTIL_WeaponTimeBase()) { if ((!m_iClip && pszAmmo1()) || (iMaxClip() == WEAPON_NOCLIP && !m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()])) m_fFireOnEmpty = TRUE; m_pPlayer->TabulateAmmo(); if ((m_pPlayer->m_bCanShoot == true && g_pGameRules->IsMultiplayer() && !g_pGameRules->IsFreezePeriod() && !m_pPlayer->m_bIsDefusing) || !g_pGameRules->IsMultiplayer()) PrimaryAttack(); } else if (m_pPlayer->pev->button & IN_RELOAD && iMaxClip() != WEAPON_NOCLIP && !m_fInReload) { if (m_flNextPrimaryAttack < UTIL_WeaponTimeBase()) { if (m_flFamasShoot == 0 && m_flGlock18Shoot == 0) { if (!(m_iWeaponState & WPNSTATE_SHIELD_DRAWN)) Reload(); } } } else if (!(button & (IN_ATTACK | IN_ATTACK2))) { if (m_bDelayFire == true) { m_bDelayFire = false; if (m_iShotsFired > 15) m_iShotsFired = 15; m_flDecreaseShotsFired = gpGlobals->time + 0.4; } m_fFireOnEmpty = FALSE; if (m_iId != WEAPON_USP && m_iId != WEAPON_GLOCK18 && m_iId != WEAPON_P228 && m_iId != WEAPON_DEAGLE && m_iId != WEAPON_ELITE && m_iId != WEAPON_FIVESEVEN) { if (m_iShotsFired > 0) { if (gpGlobals->time > m_flDecreaseShotsFired) { m_iShotsFired--; m_flDecreaseShotsFired = gpGlobals->time + 0.0225; } } } else m_iShotsFired = 0; if (!IsUseable() && m_flNextPrimaryAttack < UTIL_WeaponTimeBase()) { } else { if (!m_iClip && !(iFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < UTIL_WeaponTimeBase()) { if (m_flFamasShoot == 0 && m_flGlock18Shoot == 0) { Reload(); return; } } } WeaponIdle(); return; } if (ShouldWeaponIdle()) WeaponIdle(); } void CBasePlayerItem::DestroyItem(void) { if (m_pPlayer) m_pPlayer->RemovePlayerItem(this); Kill(); } int CBasePlayerItem::AddToPlayer(CBasePlayer *pPlayer) { m_pPlayer = pPlayer; return TRUE; } void CBasePlayerItem::Drop(void) { SetTouch(NULL); SetThink(&CBaseEntity::SUB_Remove); pev->nextthink = gpGlobals->time + 0.1; } void CBasePlayerItem::Kill(void) { SetTouch(NULL); SetThink(&CBaseEntity::SUB_Remove); pev->nextthink = gpGlobals->time + 0.1; } void CBasePlayerItem::Holster(int skiplocal) { m_pPlayer->pev->viewmodel = 0; m_pPlayer->pev->weaponmodel = 0; } void CBasePlayerItem::AttachToPlayer(CBasePlayer *pPlayer) { pev->movetype = MOVETYPE_FOLLOW; pev->solid = SOLID_NOT; pev->aiment = pPlayer->edict(); pev->effects = EF_NODRAW; pev->modelindex = 0; pev->model = iStringNull; pev->owner = pPlayer->edict(); pev->nextthink = gpGlobals->time + 0.1; SetTouch(NULL); } int CBasePlayerWeapon::AddDuplicate(CBasePlayerItem *pOriginal) { if (m_iDefaultAmmo) return ExtractAmmo((CBasePlayerWeapon *)pOriginal); else return ExtractClipAmmo((CBasePlayerWeapon *)pOriginal); } int CBasePlayerWeapon::AddToPlayer(CBasePlayer *pPlayer) { int bResult = CBasePlayerItem::AddToPlayer(pPlayer); pPlayer->pev->weapons |= (1 << m_iId); if (!m_iPrimaryAmmoType) { m_iPrimaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo1()); m_iSecondaryAmmoType = pPlayer->GetAmmoIndex(pszAmmo2()); } if (bResult) bResult = AddWeapon(); if (bResult) { MESSAGE_BEGIN(MSG_ONE, gmsgWeapPickup, NULL, pPlayer->pev); WRITE_BYTE(m_iId); MESSAGE_END(); } return bResult; } int CBasePlayerWeapon::UpdateClientData(CBasePlayer *pPlayer) { BOOL bSend = FALSE; int state = 0; if (pPlayer->m_pActiveItem == this) { if (pPlayer->m_fOnTarget) state = WEAPON_IS_ONTARGET; else state = 1; } if (!pPlayer->m_fWeapon) bSend = TRUE; if (this == pPlayer->m_pActiveItem || this == pPlayer->m_pClientActiveItem) { if (pPlayer->m_pActiveItem != pPlayer->m_pClientActiveItem) bSend = TRUE; } if (m_iClip != m_iClientClip || state != m_iClientWeaponState || pPlayer->m_iFOV != pPlayer->m_iClientFOV) bSend = TRUE; if (bSend) { MESSAGE_BEGIN(MSG_ONE, gmsgCurWeapon, NULL, pPlayer->pev); WRITE_BYTE(state); WRITE_BYTE(m_iId); WRITE_BYTE(m_iClip); MESSAGE_END(); m_iClientClip = m_iClip; m_iClientWeaponState = state; pPlayer->m_fWeapon = TRUE; } if (m_pNext) m_pNext->UpdateClientData(pPlayer); return 1; } void CBasePlayerWeapon::SendWeaponAnim(int iAnim, int skiplocal) { m_pPlayer->pev->weaponanim = iAnim; #ifdef CLIENT_WEAPONS if (skiplocal && ENGINE_CANSKIP(ENT(m_pPlayer->pev))) return; #endif MESSAGE_BEGIN(MSG_ONE, SVC_WEAPONANIM, NULL, m_pPlayer->pev); WRITE_BYTE(iAnim); WRITE_BYTE(pev->body); MESSAGE_END(); } BOOL CBasePlayerWeapon::AddPrimaryAmmo(int iCount, char *szName, int iMaxClip, int iMaxCarry) { int iIdAmmo; if (iMaxClip < 1) { m_iClip = -1; iIdAmmo = m_pPlayer->GiveAmmo(iCount, szName, iMaxCarry); } else if (!m_iClip) { int i = min(m_iClip + iCount, iMaxClip) - m_iClip; m_iClip += i; iIdAmmo = m_pPlayer->GiveAmmo(iCount - i, szName, iMaxCarry); } else iIdAmmo = m_pPlayer->GiveAmmo(iCount, szName, iMaxCarry); if (iIdAmmo > 0) { m_iPrimaryAmmoType = iIdAmmo; if (m_pPlayer->HasPlayerItem(this)) EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM); } return iIdAmmo > 0 ? TRUE : FALSE; } BOOL CBasePlayerWeapon::AddSecondaryAmmo(int iCount, char *szName, int iMax) { int iIdAmmo = m_pPlayer->GiveAmmo(iCount, szName, iMax); if (iIdAmmo > 0) { m_iSecondaryAmmoType = iIdAmmo; EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", VOL_NORM, ATTN_NORM); } return iIdAmmo > 0 ? TRUE : FALSE; } BOOL CBasePlayerWeapon::IsUseable(void) { if (m_iClip <= 0) { if (m_pPlayer->m_rgAmmo[PrimaryAmmoIndex()] <= 0 && iMaxAmmo1() != -1) return FALSE; } return TRUE; } BOOL CBasePlayerWeapon::CanDeploy(void) { return TRUE; } BOOL CBasePlayerWeapon::DefaultDeploy(char *szViewModel, char *szWeaponModel, int iAnim, char *szAnimExt, int skiplocal) { if (!CanDeploy()) return FALSE; m_pPlayer->TabulateAmmo(); m_pPlayer->pev->viewmodel = MAKE_STRING(szViewModel); m_pPlayer->pev->weaponmodel = MAKE_STRING(szWeaponModel); model_name = m_pPlayer->pev->weaponmodel; strcpy(m_pPlayer->m_szAnimExtention, szAnimExt); SendWeaponAnim(iAnim, skiplocal); m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + 0.75; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 1.5; m_flDecreaseShotsFired = gpGlobals->time; m_pPlayer->m_iFOV = m_pPlayer->pev->fov = 90; m_pPlayer->m_bResumeZoom = false; m_pPlayer->m_iLastZoom = 90; return TRUE; } void CBasePlayerWeapon::ReloadSound(void) { CBasePlayer *pPlayer = NULL; while ((pPlayer = (CBasePlayer *)UTIL_FindEntityByClassname(pPlayer, "player")) != NULL) { if (pPlayer->pev->flags == FL_DORMANT) break; if (pPlayer == m_pPlayer) continue; float flDistance = m_pPlayer->pev->origin.Length() - pPlayer->pev->origin.Length(); if (flDistance <= 512) { MESSAGE_BEGIN(MSG_ONE, gmsgReloadSound, NULL, ENT(m_pPlayer->pev)); WRITE_BYTE((1.0 - (flDistance / 512.0)) * 255.0); const char *classname = STRING(pev->classname); if (!strcmp(classname, "weapon_m3") || !strcmp(classname, "weapon_xm1014")) WRITE_BYTE(0); else WRITE_BYTE(1); MESSAGE_END(); } } } BOOL CBasePlayerWeapon::DefaultReload(int iClipSize, int iAnim, float fDelay, int body) { if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) return FALSE; int j = min(iClipSize - m_iClip, m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType]); if (!j) return FALSE; m_pPlayer->m_flNextAttack = UTIL_WeaponTimeBase() + fDelay; ReloadSound(); SendWeaponAnim(iAnim, UseDecrement() ? 1 : 0); m_fInReload = TRUE; m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + fDelay + 0.5; return TRUE; } BOOL CBasePlayerWeapon::PlayEmptySound(void) { if (m_iId == WEAPON_USP || m_iId == WEAPON_GLOCK18 || m_iId == WEAPON_P228 || m_iId == WEAPON_DEAGLE || m_iId == WEAPON_ELITE || m_iId == WEAPON_FIVESEVEN) { if (m_iPlayEmptySound) { EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/dryfire_pistol.wav", 0.8, ATTN_NORM); return FALSE; } } else { if (m_iPlayEmptySound) { EMIT_SOUND(ENT(m_pPlayer->pev), CHAN_WEAPON, "weapons/dryfire_rifle.wav", 0.8, ATTN_NORM); return FALSE; } } return FALSE; } void CBasePlayerWeapon::ResetEmptySound(void) { m_iPlayEmptySound = 1; } int CBasePlayerWeapon::PrimaryAmmoIndex(void) { return m_iPrimaryAmmoType; } int CBasePlayerWeapon::SecondaryAmmoIndex(void) { return -1; } void CBasePlayerWeapon::Holster(int skiplocal) { m_fInReload = FALSE; m_pPlayer->pev->viewmodel = 0; m_pPlayer->pev->weaponmodel = 0; } void CBasePlayerAmmo::Spawn(void) { pev->movetype = MOVETYPE_TOSS; pev->solid = SOLID_TRIGGER; UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16)); UTIL_SetOrigin(pev, pev->origin); SetTouch(&CBasePlayerAmmo::DefaultTouch); if (g_pGameRules->IsMultiplayer()) { SetThink(&CBaseEntity::SUB_Remove); pev->nextthink = gpGlobals->time + 2; } } CBaseEntity *CBasePlayerAmmo::Respawn(void) { pev->effects |= EF_NODRAW; SetTouch(NULL); UTIL_SetOrigin(pev, g_pGameRules->VecAmmoRespawnSpot(this)); SetThink(&CBasePlayerAmmo::Materialize); pev->nextthink = g_pGameRules->FlAmmoRespawnTime(this); return this; } void CBasePlayerAmmo::Materialize(void) { if (pev->effects & EF_NODRAW) { EMIT_SOUND_DYN(ENT(pev), CHAN_WEAPON, "items/suitchargeok1.wav", VOL_NORM, ATTN_NORM, 0, 150); pev->effects &= ~EF_NODRAW; pev->effects |= EF_MUZZLEFLASH; } SetTouch(&CBasePlayerAmmo::DefaultTouch); } void CBasePlayerAmmo::DefaultTouch(CBaseEntity *pOther) { if (!pOther->IsPlayer()) return; if (AddAmmo(pOther)) { if (g_pGameRules->AmmoShouldRespawn(this) != GR_AMMO_RESPAWN_YES) { SetTouch(NULL); SetThink(&CBaseEntity::SUB_Remove); pev->nextthink = gpGlobals->time + 0.1; } else Respawn(); } else if (gEvilImpulse101) { SetTouch(NULL); SetThink(&CBaseEntity::SUB_Remove); pev->nextthink = gpGlobals->time + 0.1; } } int CBasePlayerWeapon::ExtractAmmo(CBasePlayerWeapon *pWeapon) { int iReturn = 0; if (pszAmmo1()) { iReturn = pWeapon->AddPrimaryAmmo(m_iDefaultAmmo, (char *)pszAmmo1(), iMaxClip(), iMaxAmmo1()); m_iDefaultAmmo = 0; } if (pszAmmo2()) iReturn = AddSecondaryAmmo(0, (char *)pszAmmo2(), iMaxAmmo2()); return iReturn; } BOOL CBasePlayerWeapon::ExtractClipAmmo(CBasePlayerWeapon *pWeapon) { int iAmmo; if (m_iClip == WEAPON_NOCLIP) iAmmo = 0; else iAmmo = m_iClip; return pWeapon->m_pPlayer->GiveAmmo(iAmmo, (char *)pszAmmo1(), iMaxAmmo1()); } void CBasePlayerWeapon::RetireWeapon(void) { m_pPlayer->pev->viewmodel = NULL; m_pPlayer->pev->weaponmodel = NULL; g_pGameRules->GetNextBestWeapon(m_pPlayer, this); } LINK_ENTITY_TO_CLASS(weaponbox, CWeaponBox); TYPEDESCRIPTION CWeaponBox::m_SaveData[] = { DEFINE_ARRAY(CWeaponBox, m_rgAmmo, FIELD_INTEGER, MAX_AMMO_SLOTS), DEFINE_ARRAY(CWeaponBox, m_rgiszAmmo, FIELD_STRING, MAX_AMMO_SLOTS), DEFINE_ARRAY(CWeaponBox, m_rgpPlayerItems, FIELD_CLASSPTR, MAX_ITEM_TYPES), DEFINE_FIELD(CWeaponBox, m_cAmmoTypes, FIELD_INTEGER), }; IMPLEMENT_SAVERESTORE(CWeaponBox, CBaseEntity); void CWeaponBox::Precache(void) { PRECACHE_MODEL("models/w_weaponbox.mdl"); } void CWeaponBox::KeyValue(KeyValueData *pkvd) { if (m_cAmmoTypes < MAX_AMMO_SLOTS) { PackAmmo(ALLOC_STRING(pkvd->szKeyName), atoi(pkvd->szValue)); m_cAmmoTypes++; pkvd->fHandled = TRUE; } else ALERT(at_console, "WeaponBox too full! only %d ammotypes allowed\n", MAX_AMMO_SLOTS); } void CWeaponBox::Spawn(void) { Precache(); pev->movetype = MOVETYPE_TOSS; pev->solid = SOLID_TRIGGER; UTIL_SetSize(pev, g_vecZero, g_vecZero); SET_MODEL(ENT(pev), "models/w_weaponbox.mdl"); } void CWeaponBox::Kill(void) { for (int i = 0; i < MAX_ITEM_TYPES; i++) { CBasePlayerItem *pWeapon = m_rgpPlayerItems[i]; while (pWeapon) { pWeapon->SetThink(&CBaseEntity::SUB_Remove); pWeapon->pev->nextthink = gpGlobals->time + 0.1; pWeapon = pWeapon->m_pNext; } } UTIL_Remove(this); } extern int gmsgBombPickup; void CWeaponBox::Touch(CBaseEntity *pOther) { if (!(pev->flags & FL_ONGROUND)) return; if (!pOther->IsPlayer()) return; if (!pOther->IsAlive()) return; CBasePlayer *pPlayer = (CBasePlayer *)pOther; if (pPlayer->m_bIsVIP == true || pPlayer->m_bShieldDrawn == true) return; bool bCanAmmo = true; bool bAddItem = false; for (int i = 0; i < MAX_ITEM_TYPES; i++) { if (m_rgpPlayerItems[i]) { CBasePlayerItem *pItem = m_rgpPlayerItems[i]; while (pItem) { if (FClassnameIs(pItem->pev, "weapon_c4")) { if (pPlayer->m_iTeam != TEAM_TERRORIST || pPlayer->pev->deadflag != DEAD_NO) return; if (pPlayer->m_bShowHints && !(pPlayer->m_flDisplayHistory & DHF_BOMB_RETRIEVED)) { pPlayer->m_flDisplayHistory |= DHF_BOMB_RETRIEVED; pPlayer->HintMessage("#Hint_you_have_the_bomb"); } else ClientPrint(pPlayer->pev, HUD_PRINTCENTER, "#Got_bomb"); UTIL_LogPrintf("\"%s<%i><%s>\" triggered \"Got_The_Bomb\"\n", STRING(pPlayer->pev->netname), GETPLAYERUSERID(pPlayer->edict()), GETPLAYERAUTHID(pPlayer->edict())); MESSAGE_BEGIN(MSG_SPEC, SVC_DIRECTOR); WRITE_BYTE(9); WRITE_BYTE(DRC_CMD_EVENT); WRITE_SHORT(ENTINDEX(pPlayer->edict())); WRITE_SHORT(ENTINDEX(edict())); WRITE_LONG(5); MESSAGE_END(); pPlayer->m_bHasC4 = true; pPlayer->SetBombIcon(FALSE); pPlayer->pev->body = 1; CBaseEntity *pEntity = NULL; while (pEntity = UTIL_FindEntityByClassname(pEntity, "player")) { if (FNullEnt(pEntity->edict())) break; if (!pEntity->IsPlayer()) continue; if (pEntity->pev->flags == FL_DORMANT) continue; CBasePlayer *pOther = GetClassPtr((CBasePlayer *)pEntity->pev); if (pOther->pev->deadflag == DEAD_NO && pOther->m_iTeam == TEAM_TERRORIST) { if (pOther != pPlayer) ClientPrint(pOther->pev, HUD_PRINTCENTER, "#Game_bomb_pickup", &gpGlobals->pStringBase[pPlayer->pev->netname]); MESSAGE_BEGIN(MSG_ONE, gmsgBombPickup, NULL, pOther->pev); MESSAGE_END(); } } } if (i >= WPNSLOT_PRIMARY && i <= WPNSLOT_SECONDARY && pPlayer->m_rgpPlayerItems[i] != NULL) { } else if (i == WPNSLOT_GRENADE) { if (m_rgpPlayerItems[i]&&m_rgpPlayerItems[i]->IsWeapon()) { CBasePlayerWeapon *pWeapon = (CBasePlayerWeapon *)m_rgpPlayerItems[i]; const char *pszGrenadeName = NULL; int iMaxGrenades = 1; switch (pWeapon->m_iId) { case WEAPON_HEGRENADE: pszGrenadeName = "weapon_hegrenade"; break; case WEAPON_SMOKEGRENADE: pszGrenadeName = "weapon_smokegrenade"; break; case WEAPON_FLASHBANG: pszGrenadeName = "weapon_flashbang"; iMaxGrenades = 2; break; } if (m_rgAmmo[pWeapon->m_iPrimaryAmmoType] < iMaxGrenades && pszGrenadeName) { pPlayer->GiveNamedItem(pszGrenadeName); pItem = m_rgpPlayerItems[i] = m_rgpPlayerItems[i]->m_pNext; continue; } } } else if (pPlayer->HasShield() != false && i == WPNSLOT_PRIMARY) { } else { bAddItem = true; if (pPlayer->AddPlayerItem(pItem)) pItem->AttachToPlayer(pPlayer); pItem = m_rgpPlayerItems[i] = m_rgpPlayerItems[i]->m_pNext; continue; } bCanAmmo = false; pItem = m_rgpPlayerItems[i]->m_pNext; } } } if (bCanAmmo) { for (int i = 0; i < MAX_AMMO_SLOTS; i++) { if (!FStringNull(m_rgiszAmmo[i])) { pPlayer->GiveAmmo(m_rgAmmo[i], (char *)STRING(m_rgiszAmmo[i]), MaxAmmoCarry(m_rgiszAmmo[i])); m_rgiszAmmo[i] = NULL; m_rgAmmo[i] = 0; } } } if (bAddItem) EMIT_SOUND(ENT(pOther->pev), CHAN_ITEM, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM); if (bCanAmmo) { SetTouch(NULL); UTIL_Remove(this); } } BOOL CWeaponBox::PackWeapon(CBasePlayerItem *pWeapon) { if (HasWeapon(pWeapon)) return FALSE; if (pWeapon->m_pPlayer) { if (pWeapon->m_pPlayer->m_pActiveItem == pWeapon) pWeapon->Holster(); if (!pWeapon->m_pPlayer->RemovePlayerItem(pWeapon)) return FALSE; } int iWeaponSlot = pWeapon->iItemSlot(); if (m_rgpPlayerItems[iWeaponSlot]) { pWeapon->m_pNext = m_rgpPlayerItems[iWeaponSlot]; m_rgpPlayerItems[iWeaponSlot] = pWeapon; } else { m_rgpPlayerItems[iWeaponSlot] = pWeapon; pWeapon->m_pNext = NULL; } pWeapon->pev->spawnflags |= SF_NORESPAWN; pWeapon->pev->movetype = MOVETYPE_NONE; pWeapon->pev->solid = SOLID_NOT; pWeapon->pev->effects = EF_NODRAW; pWeapon->pev->modelindex = 0; pWeapon->pev->model = NULL; pWeapon->pev->owner = ENT(pev); pWeapon->SetThink(NULL); pWeapon->SetTouch(NULL); pWeapon->m_pPlayer = NULL; return TRUE; } BOOL CWeaponBox::PackAmmo(int iszName, int iCount) { if (FStringNull(iszName)) { ALERT(at_console, "NULL String in PackAmmo!\n"); return FALSE; } int iMaxCarry = MaxAmmoCarry(iszName); if (iMaxCarry != -1 && iCount > 0) { GiveAmmo(iCount, (char *)STRING(iszName), iMaxCarry); return TRUE; } return FALSE; } int CWeaponBox::GiveAmmo(int iCount, char *szName, int iMax, int *pIndex) { int i = 1; for (; i < MAX_AMMO_SLOTS && !FStringNull(m_rgiszAmmo[i]); i++) { if (!stricmp(szName, STRING(m_rgiszAmmo[i]))) { if (pIndex) *pIndex = i; int iAdd = min(iCount, iMax - m_rgAmmo[i]); if (iCount == 0 || iAdd > 0) { m_rgAmmo[i] += iAdd; return i; } return -1; } } if (i < MAX_AMMO_SLOTS) { if (pIndex) *pIndex = i; m_rgiszAmmo[i] = MAKE_STRING(szName); m_rgAmmo[i] = iCount; return i; } ALERT(at_console, "out of named ammo slots\n"); return i; } BOOL CWeaponBox::HasWeapon(CBasePlayerItem *pCheckItem) { CBasePlayerItem *pItem = m_rgpPlayerItems[pCheckItem->iItemSlot()]; while (pItem) { if (FClassnameIs(pItem->pev, STRING(pCheckItem->pev->classname))) return TRUE; pItem = pItem->m_pNext; } return FALSE; } BOOL CWeaponBox::IsEmpty(void) { int i; for (i = 0; i < MAX_ITEM_TYPES; i++) { if (m_rgpPlayerItems[i]) return FALSE; } for (i = 0; i < MAX_AMMO_SLOTS; i++) { if (m_rgiszAmmo[i]) return FALSE; } return TRUE; } void CWeaponBox::SetObjectCollisionBox(void) { pev->absmin = pev->origin + Vector(-16, -16, 0); pev->absmax = pev->origin + Vector(16, 16, 16); } void CArmoury::ArmouryTouch(CBaseEntity *pOther) { if (!pOther->IsPlayer()) return; CBasePlayer *pPlayer = (CBasePlayer *)pOther; if (pPlayer->m_bIsVIP == true) return; if (m_iCount > 0 && m_iItem <= ARMOURY_M249) { if (pPlayer->m_bHasPrimary == true) return; m_iCount--; switch (m_iItem) { case ARMOURY_MP5NAVY: { pPlayer->GiveNamedItem("weapon_mp5navy"); pPlayer->GiveAmmo(60, "9mm", _9MM_MAX_CARRY); break; } case ARMOURY_TMP: { pPlayer->GiveNamedItem("weapon_tmp"); pPlayer->GiveAmmo(60, "9mm", _9MM_MAX_CARRY); break; } case ARMOURY_P90: { pPlayer->GiveNamedItem("weapon_p90"); pPlayer->GiveAmmo(50, "57mm", _57MM_MAX_CARRY); break; } case ARMOURY_MAC10: { pPlayer->GiveNamedItem("weapon_mac10"); pPlayer->GiveAmmo(60, "45acp", _45ACP_MAX_CARRY); break; } case ARMOURY_AK47: { pPlayer->GiveNamedItem("weapon_ak47"); pPlayer->GiveAmmo(60, "762Nato", _762NATO_MAX_CARRY); break; } case ARMOURY_SG552: { pPlayer->GiveNamedItem("weapon_sg552"); pPlayer->GiveAmmo(60, "556Nato", _556NATO_MAX_CARRY); break; } case ARMOURY_M4A1: { pPlayer->GiveNamedItem("weapon_m4a1"); pPlayer->GiveAmmo(60, "556Nato", _556NATO_MAX_CARRY); break; } case ARMOURY_AUG: { pPlayer->GiveNamedItem("weapon_aug"); pPlayer->GiveAmmo(60, "556Nato", _556NATO_MAX_CARRY); break; } case ARMOURY_SCOUT: { pPlayer->GiveNamedItem("weapon_scout"); pPlayer->GiveAmmo(30, "762Nato", _762NATO_MAX_CARRY); break; } case ARMOURY_G3SG1: { pPlayer->GiveNamedItem("weapon_g3sg1"); pPlayer->GiveAmmo(30, "762Nato", _762NATO_MAX_CARRY); break; } case ARMOURY_AWP: { pPlayer->GiveNamedItem("weapon_awp"); pPlayer->GiveAmmo(20, "338Magnum", _338MAGNUM_MAX_CARRY); break; } case ARMOURY_M3: { pPlayer->GiveNamedItem("weapon_m3"); pPlayer->GiveAmmo(24, "buckshot", BUCKSHOT_MAX_CARRY); break; } case ARMOURY_XM1014: { pPlayer->GiveNamedItem("weapon_xm1014"); pPlayer->GiveAmmo(24, "buckshot", BUCKSHOT_MAX_CARRY); break; } case ARMOURY_M249: { pPlayer->GiveNamedItem("weapon_m249"); pPlayer->GiveAmmo(60, "556NatoBox", _556NATOBOX_MAX_CARRY); break; } } } else if (m_iCount > 0 && m_iItem >= ARMOURY_FLASHBANG) { switch (m_iItem) { case ARMOURY_FLASHBANG: { if (pPlayer->AmmoInventory(pPlayer->GetAmmoIndex("Flashbang")) >= 2) return; pPlayer->GiveNamedItem("weapon_flashbang"); m_iCount--; break; } case ARMOURY_HEGRENADE: { if (pPlayer->AmmoInventory(pPlayer->GetAmmoIndex("HEGrenade")) >= 1) return; pPlayer->GiveNamedItem("weapon_hegrenade"); m_iCount--; break; } case ARMOURY_KEVLAR: { if (pPlayer->m_iKevlar == 1) return; pPlayer->GiveNamedItem("item_kevlar"); m_iCount--; } case ARMOURY_ASSAULT: { if (pPlayer->m_iKevlar == 2) return; pPlayer->GiveNamedItem("item_assaultsuit"); m_iCount--; } case ARMOURY_SMOKEGRENADE: { if (pPlayer->AmmoInventory(pPlayer->GetAmmoIndex("SmokeGrenade")) >= 1) return; pPlayer->GiveNamedItem("weapon_smokegrenade"); m_iCount--; break; } } } if (!m_iCount) pev->effects |= EF_NODRAW; } void CArmoury::KeyValue(KeyValueData *pkvd) { if (!strcmp(pkvd->szKeyName, "item")) { m_iItem = atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else if (!strcmp(pkvd->szKeyName, "count")) { m_iCount = atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue(pkvd); } LINK_ENTITY_TO_CLASS(armoury_entity, CArmoury); void CArmoury::Spawn(void) { Precache(); pev->movetype = MOVETYPE_TOSS; pev->solid = SOLID_TRIGGER; UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16)); UTIL_SetOrigin(pev, pev->origin); SetTouch(&CArmoury::ArmouryTouch); switch (m_iItem) { case ARMOURY_MP5NAVY: SET_MODEL(ENT(pev), "models/w_mp5.mdl"); break; case ARMOURY_TMP: SET_MODEL(ENT(pev), "models/w_tmp.mdl"); break; case ARMOURY_P90: SET_MODEL(ENT(pev), "models/w_p90.mdl"); break; case ARMOURY_MAC10: SET_MODEL(ENT(pev), "models/w_mac10.mdl"); break; case ARMOURY_AK47: SET_MODEL(ENT(pev), "models/w_ak47.mdl"); break; case ARMOURY_SG552: SET_MODEL(ENT(pev), "models/w_sg552.mdl"); break; case ARMOURY_M4A1: SET_MODEL(ENT(pev), "models/w_m4a1.mdl"); break; case ARMOURY_AUG: SET_MODEL(ENT(pev), "models/w_aug.mdl"); break; case ARMOURY_SCOUT: SET_MODEL(ENT(pev), "models/w_scout.mdl"); break; case ARMOURY_G3SG1: SET_MODEL(ENT(pev), "models/w_g3sg1.mdl"); break; case ARMOURY_AWP: SET_MODEL(ENT(pev), "models/w_awp.mdl"); break; case ARMOURY_M3: SET_MODEL(ENT(pev), "models/w_m3.mdl"); break; case ARMOURY_XM1014: SET_MODEL(ENT(pev), "models/w_xm1014.mdl"); break; case ARMOURY_M249: SET_MODEL(ENT(pev), "models/w_m249.mdl"); break; case ARMOURY_FLASHBANG: SET_MODEL(ENT(pev), "models/w_flashbang.mdl"); break; case ARMOURY_HEGRENADE: SET_MODEL(ENT(pev), "models/w_hegrenade.mdl"); break; case ARMOURY_KEVLAR: SET_MODEL(ENT(pev), "models/w_kevlar.mdl"); break; case ARMOURY_ASSAULT: SET_MODEL(ENT(pev), "models/w_assault.mdl"); break; case ARMOURY_SMOKEGRENADE: SET_MODEL(ENT(pev), "models/w_smokegrenade.mdl"); break; default: PRECACHE_MODEL("models/w_kevlar.mdl"); break; } if (m_iCount <= 0) m_iCount = 1; m_bAlreadyCounted = false; m_iInitialCount = m_iCount; } void CArmoury::Restart(void) { if (m_iItem == ARMOURY_FLASHBANG || m_iItem == ARMOURY_HEGRENADE) { if (!m_bAlreadyCounted) { m_bAlreadyCounted = true; g_pGameRules->m_iTotalGrenadeCount += m_iInitialCount; m_iCount = m_iInitialCount; pev->effects &= ~EF_NODRAW; return; } m_iCount = (float)(m_iInitialCount / g_pGameRules->m_iTotalGrenadeCount) * g_pGameRules->m_iNumTerrorist * 1.75; } else if (m_iItem == ARMOURY_KEVLAR || m_iItem == ARMOURY_ASSAULT) { if (!m_bAlreadyCounted) { m_bAlreadyCounted = true; g_pGameRules->m_iTotalArmourCount += m_iInitialCount; m_iCount = m_iInitialCount; pev->effects &= ~EF_NODRAW; return; } m_iCount = (float)(m_iInitialCount / g_pGameRules->m_iTotalArmourCount) * g_pGameRules->m_iNumTerrorist; } else { if (!m_bAlreadyCounted) { m_bAlreadyCounted = true; g_pGameRules->m_iTotalGunCount += m_iInitialCount; m_iCount = m_iInitialCount; pev->effects &= ~EF_NODRAW; return; } m_iCount = (float)(m_iInitialCount / g_pGameRules->m_iTotalGunCount) * g_pGameRules->m_iNumTerrorist * 0.85; } if (m_iCount < 1) m_iCount = 1; pev->effects &= ~EF_NODRAW; } void CArmoury::Precache(void) { switch (m_iItem) { case ARMOURY_MP5NAVY: PRECACHE_MODEL("models/w_mp5.mdl"); break; case ARMOURY_TMP: PRECACHE_MODEL("models/w_tmp.mdl"); break; case ARMOURY_P90: PRECACHE_MODEL("models/w_p90.mdl"); break; case ARMOURY_MAC10: PRECACHE_MODEL("models/w_mac10.mdl"); break; case ARMOURY_AK47: PRECACHE_MODEL("models/w_ak47.mdl"); break; case ARMOURY_SG552: PRECACHE_MODEL("models/w_sg552.mdl"); break; case ARMOURY_M4A1: PRECACHE_MODEL("models/w_m4a1.mdl"); break; case ARMOURY_AUG: PRECACHE_MODEL("models/w_aug.mdl"); break; case ARMOURY_SCOUT: PRECACHE_MODEL("models/w_scout.mdl"); break; case ARMOURY_G3SG1: PRECACHE_MODEL("models/w_g3sg1.mdl"); break; case ARMOURY_AWP: PRECACHE_MODEL("models/w_awp.mdl"); break; case ARMOURY_M3: PRECACHE_MODEL("models/w_m3.mdl"); break; case ARMOURY_XM1014: PRECACHE_MODEL("models/w_xm1014.mdl"); break; case ARMOURY_M249: PRECACHE_MODEL("models/w_m249.mdl"); break; case ARMOURY_FLASHBANG: PRECACHE_MODEL("models/w_flashbang.mdl"); break; case ARMOURY_HEGRENADE: PRECACHE_MODEL("models/w_hegrenade.mdl"); break; case ARMOURY_KEVLAR: PRECACHE_MODEL("models/w_kevlar.mdl"); break; case ARMOURY_ASSAULT: PRECACHE_MODEL("models/w_assault.mdl"); break; case ARMOURY_SMOKEGRENADE: PRECACHE_MODEL("models/w_smokegrenade.mdl"); break; default: PRECACHE_MODEL("models/w_kevlar.mdl"); break; } }