diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/shared/tf/tf_weapon_lunchbox.cpp | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'game/shared/tf/tf_weapon_lunchbox.cpp')
| -rw-r--r-- | game/shared/tf/tf_weapon_lunchbox.cpp | 430 |
1 files changed, 430 insertions, 0 deletions
diff --git a/game/shared/tf/tf_weapon_lunchbox.cpp b/game/shared/tf/tf_weapon_lunchbox.cpp new file mode 100644 index 0000000..bfb646e --- /dev/null +++ b/game/shared/tf/tf_weapon_lunchbox.cpp @@ -0,0 +1,430 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// +//============================================================================= +#include "cbase.h" +#include "tf_weapon_lunchbox.h" +#include "tf_fx_shared.h" + +// Client specific. +#ifdef CLIENT_DLL +#include "c_tf_player.h" +// Server specific. +#else +#include "tf_player.h" +#include "entity_healthkit.h" +#include "econ_item_view.h" +#include "econ_item_system.h" +#include "tf_gamestats.h" +#endif + +//============================================================================= +// +// Weapon Lunchbox tables. +// +IMPLEMENT_NETWORKCLASS_ALIASED( TFLunchBox, DT_WeaponLunchBox ) + +BEGIN_NETWORK_TABLE( CTFLunchBox, DT_WeaponLunchBox ) +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA( CTFLunchBox ) +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS( tf_weapon_lunchbox, CTFLunchBox ); +PRECACHE_WEAPON_REGISTER( tf_weapon_lunchbox ); + +//============================================================================= + +IMPLEMENT_NETWORKCLASS_ALIASED( TFLunchBox_Drink, DT_TFLunchBox_Drink ) + +BEGIN_NETWORK_TABLE( CTFLunchBox_Drink, DT_TFLunchBox_Drink ) +END_NETWORK_TABLE() + +BEGIN_PREDICTION_DATA( CTFLunchBox_Drink ) +END_PREDICTION_DATA() + +LINK_ENTITY_TO_CLASS( tf_weapon_lunchbox_drink, CTFLunchBox_Drink ); +PRECACHE_WEAPON_REGISTER( tf_weapon_lunchbox_drink ); + +// Server specific. +#ifndef CLIENT_DLL +BEGIN_DATADESC( CTFLunchBox ) +END_DATADESC() +#endif + +#define LUNCHBOX_DROP_MODEL "models/items/plate.mdl" +#define LUNCHBOX_STEAK_DROP_MODEL "models/items/plate_steak.mdl" +#define LUNCHBOX_ROBOT_DROP_MODEL "models/items/plate_robo_sandwich.mdl" +#define LUNCHBOX_FESTIVE_DROP_MODEL "models/items/plate_sandwich_xmas.mdl" +#define LUNCHBOX_CHOCOLATE_BAR "models/props_halloween/halloween_medkit_small.mdl" + +#define LUNCHBOX_DROPPED_MINS Vector( -17, -17, -10 ) +#define LUNCHBOX_DROPPED_MAXS Vector( 17, 17, 10 ) + +static const char *s_pszLunchboxMaxHealThink = "LunchboxMaxHealThink"; + +//============================================================================= +// +// Weapon Lunchbox functions. +// + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CTFLunchBox::CTFLunchBox() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFLunchBox::UpdateOnRemove( void ) +{ +#ifndef CLIENT_DLL + // If we're removed, we remove any dropped powerups. This prevents an exploit + // where they switch classes away & back to get another lunchbox to drop with. + if ( m_hThrownPowerup ) + { + UTIL_Remove( m_hThrownPowerup ); + } +#endif + + BaseClass::UpdateOnRemove(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFLunchBox::Precache( void ) +{ + if ( DropAllowed() ) + { + PrecacheModel( "models/items/medkit_medium.mdl" ); + PrecacheModel( "models/items/medkit_medium_bday.mdl" ); + PrecacheModel( LUNCHBOX_DROP_MODEL ); + PrecacheModel( LUNCHBOX_STEAK_DROP_MODEL ); + PrecacheModel( LUNCHBOX_ROBOT_DROP_MODEL ); + PrecacheModel( LUNCHBOX_FESTIVE_DROP_MODEL ); + PrecacheModel( LUNCHBOX_CHOCOLATE_BAR ); + } + + BaseClass::Precache(); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFLunchBox::WeaponReset( void ) +{ + BaseClass::WeaponReset(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CTFLunchBox::UsesPrimaryAmmo( void ) +{ + return CBaseCombatWeapon::UsesPrimaryAmmo(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CTFLunchBox::DropAllowed( void ) +{ + CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() ); + if ( pOwner ) + { + if ( pOwner->m_Shared.InCond( TF_COND_TAUNTING ) ) + return false; + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFLunchBox::PrimaryAttack( void ) +{ + CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() ); + if ( !pOwner ) + return; + + if ( !HasAmmo() ) + return; + +#if GAME_DLL + pOwner->Taunt(); + m_flNextPrimaryAttack = pOwner->GetTauntRemoveTime() + 0.1f; +#else + m_flNextPrimaryAttack = gpGlobals->curtime + 2.0f; // this will be corrected by the game server +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFLunchBox::SecondaryAttack( void ) +{ + if ( !DropAllowed() ) + return; + + CTFPlayer *pPlayer = ToTFPlayer( GetPlayerOwner() ); + if ( !pPlayer ) + return; + + if ( !HasAmmo() ) + return; + +#ifndef CLIENT_DLL + + if ( m_hThrownPowerup ) + { + UTIL_Remove( m_hThrownPowerup ); + } + + // Throw out the medikit + Vector vecSrc = pPlayer->EyePosition() + Vector(0,0,-8); + QAngle angForward = pPlayer->EyeAngles() + QAngle(-10,0,0); + + int nLunchBoxType = GetLunchboxType(); + + const char *pszHealthKit; + switch ( nLunchBoxType ) + { + case LUNCHBOX_ADDS_MAXHEALTH: + pszHealthKit = "item_healthkit_small"; + break; + + case LUNCHBOX_ADDS_AMMO: + pszHealthKit = "item_healthammokit"; + break; + + default: + pszHealthKit = "item_healthkit_medium"; + } + + CHealthKit *pMedKit = assert_cast<CHealthKit*>( CBaseEntity::Create( pszHealthKit, vecSrc, angForward, pPlayer ) ); + + if ( pMedKit ) + { + Vector vecForward, vecRight, vecUp; + AngleVectors( angForward, &vecForward, &vecRight, &vecUp ); + Vector vecVelocity = vecForward * 500.0; + + if ( nLunchBoxType == LUNCHBOX_ADDS_MINICRITS ) + { + pMedKit->SetModel( LUNCHBOX_STEAK_DROP_MODEL ); + } + else if ( nLunchBoxType == LUNCHBOX_STANDARD_ROBO ) + { + pMedKit->SetModel( LUNCHBOX_ROBOT_DROP_MODEL ); + pMedKit->m_nSkin = ( pPlayer->GetTeamNumber() == TF_TEAM_RED ) ? 0 : 1; + } + else if ( nLunchBoxType == LUNCHBOX_STANDARD_FESTIVE ) + { + pMedKit->SetModel( LUNCHBOX_FESTIVE_DROP_MODEL ); + pMedKit->m_nSkin = ( pPlayer->GetTeamNumber() == TF_TEAM_RED ) ? 0 : 1; + } + else if ( nLunchBoxType == LUNCHBOX_ADDS_MAXHEALTH ) + { + pMedKit->SetModel( LUNCHBOX_CHOCOLATE_BAR ); + } + else + { + pMedKit->SetModel( LUNCHBOX_DROP_MODEL ); + } + + // clear out the overrides so the thrown sandvich/steak look correct in either vision mode + pMedKit->ClearModelIndexOverrides(); + + pMedKit->SetAbsAngles( vec3_angle ); + pMedKit->SetSize( LUNCHBOX_DROPPED_MINS, LUNCHBOX_DROPPED_MAXS ); + + // the thrower has to wait 0.3 to pickup the powerup (so he can throw it while running forward) + pMedKit->DropSingleInstance( vecVelocity, pPlayer, 0.3 ); + } + + m_hThrownPowerup = pMedKit; +#endif + + pPlayer->RemoveAmmo( m_pWeaponInfo->GetWeaponData( m_iWeaponMode ).m_iAmmoPerShot, m_iPrimaryAmmoType ); + g_pGameRules->SwitchToNextBestWeapon( pPlayer, this ); + + StartEffectBarRegen(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFLunchBox::DrainAmmo( bool bForceCooldown ) +{ + CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() ); + if ( !pOwner ) + return; + +#ifdef GAME_DLL + + int iLunchboxType = GetLunchboxType(); + // If we're damaged while eating/taunting, bForceCooldown will be true + if ( pOwner->IsPlayerClass( TF_CLASS_HEAVYWEAPONS ) ) + { + if ( pOwner->GetHealth() < pOwner->GetMaxHealth() || GetLunchboxType() == LUNCHBOX_ADDS_MINICRITS || iLunchboxType == LUNCHBOX_ADDS_MAXHEALTH || bForceCooldown ) + { + StartEffectBarRegen(); + } + else // Full health regular sandwhich, I can eat forever + { + return; + } + } + else if ( pOwner->IsPlayerClass( TF_CLASS_SCOUT ) ) + { + StartEffectBarRegen(); + } + + // Strange Tracking. Only go through if we have ammo at this point. + if ( !pOwner->IsBot() && pOwner->GetAmmoCount( m_iPrimaryAmmoType ) > 0 ) + { + EconEntity_OnOwnerKillEaterEventNoPartner( dynamic_cast<CEconEntity *>( this ), pOwner, kKillEaterEvent_FoodEaten ); + } + + pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType ); +#else + + pOwner->RemoveAmmo( 1, m_iPrimaryAmmoType ); + StartEffectBarRegen(); + +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFLunchBox::Detach( void ) +{ +#ifdef GAME_DLL + // Terrible - but for now, we're the only place that adds this (custom) attribute + if ( GetLunchboxType() == LUNCHBOX_ADDS_MAXHEALTH ) + { + CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() ); + if ( pOwner ) + { + // Prevents use-then-switch-class exploit (heavy->scout) + // Not a big deal in pubs, but it can mess with competitive + pOwner->RemoveCustomAttribute( "hidden maxhealth non buffed" ); + } + } +#endif + + BaseClass::Detach(); +} + +#ifdef GAME_DLL +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFLunchBox::ApplyBiteEffects( CTFPlayer *pPlayer ) +{ + int nLunchBoxType = GetLunchboxType(); + + if ( nLunchBoxType == LUNCHBOX_ADDS_MAXHEALTH ) + { + // add 50 health to player for 30 seconds + pPlayer->AddCustomAttribute( "hidden maxhealth non buffed", 50.f, 30.f ); + } + else if ( nLunchBoxType == LUNCHBOX_ADDS_MINICRITS ) + { + static const float s_fSteakSandwichDuration = 16.0f; + + // Steak sandvich. + pPlayer->m_Shared.AddCond( TF_COND_ENERGY_BUFF, s_fSteakSandwichDuration ); + pPlayer->m_Shared.AddCond( TF_COND_CANNOT_SWITCH_FROM_MELEE, s_fSteakSandwichDuration ); + pPlayer->m_Shared.SetBiteEffectWasApplied(); + + return; + } + + // Then heal the player + int iHeal = ( nLunchBoxType == LUNCHBOX_ADDS_MAXHEALTH ) ? 25 : 75; + int iHealType = DMG_GENERIC; + if ( nLunchBoxType == LUNCHBOX_ADDS_MAXHEALTH && pPlayer->GetHealth() < 400 ) + { + iHealType = DMG_IGNORE_MAXHEALTH; + iHeal = Min( 25, 400 - pPlayer->GetHealth() ); + } + + float flHealScale = 1.0f; + CALL_ATTRIB_HOOK_FLOAT( flHealScale, lunchbox_healing_scale ); + iHeal = iHeal * flHealScale; + + int iHealed = pPlayer->TakeHealth( iHeal, iHealType ); + + if ( iHealed > 0 ) + { + CTF_GameStats.Event_PlayerHealedOther( pPlayer, iHealed ); + } + + // Restore ammo if applicable + if ( nLunchBoxType == LUNCHBOX_ADDS_AMMO ) + { + int maxPrimary = pPlayer->GetMaxAmmo( TF_AMMO_PRIMARY ); + pPlayer->GiveAmmo( maxPrimary * 0.25, TF_AMMO_PRIMARY, true ); + } +} +#endif // GAME_DLL + +//----------------------------------------------------------------------------- +// Purpose: Energy Drink +//----------------------------------------------------------------------------- +CTFLunchBox_Drink::CTFLunchBox_Drink() +{ +} + +#ifdef CLIENT_DLL +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CTFLunchBox_Drink::Holster( CBaseCombatWeapon *pSwitchingTo ) +{ + CTFPlayer *pOwner = ToTFPlayer( GetPlayerOwner() ); + if ( pOwner && pOwner->IsLocalPlayer() ) + { + C_BaseEntity *pParticleEnt = pOwner->GetViewModel(0); + if ( pParticleEnt ) + { + pOwner->StopViewModelParticles( pParticleEnt ); + } + } + + return BaseClass::Holster( pSwitchingTo ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +const char* CTFLunchBox_Drink::ModifyEventParticles( const char* token ) +{ + if ( GetLunchboxType() == LUNCHBOX_ADDS_MINICRITS ) + { + if ( FStrEq( token, "energydrink_splash") ) + { + CEconItemView *pItem = m_AttributeManager.GetItem(); + int iSystems = pItem->GetStaticData()->GetNumAttachedParticles( GetTeamNumber() ); + for ( int i = 0; i < iSystems; i++ ) + { + attachedparticlesystem_t *pSystem = pItem->GetStaticData()->GetAttachedParticleData( GetTeamNumber(),i ); + if ( pSystem->iCustomType == 1 ) + { + return pSystem->pszSystemName; + } + } + } + } + + return BaseClass::ModifyEventParticles( token ); +} + +#endif // CLIENT_DLL
\ No newline at end of file |