diff options
Diffstat (limited to 'game/shared/tf/tf_item_powerup_bottle.cpp')
| -rw-r--r-- | game/shared/tf/tf_item_powerup_bottle.cpp | 786 |
1 files changed, 786 insertions, 0 deletions
diff --git a/game/shared/tf/tf_item_powerup_bottle.cpp b/game/shared/tf/tf_item_powerup_bottle.cpp new file mode 100644 index 0000000..344db35 --- /dev/null +++ b/game/shared/tf/tf_item_powerup_bottle.cpp @@ -0,0 +1,786 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "cbase.h" +#include "tf_item_powerup_bottle.h" +#include "tf_gamerules.h" + +#ifdef GAME_DLL +#include "tf_player.h" +#include "tf_obj_sentrygun.h" +#include "tf_weapon_medigun.h" +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +#ifndef GAME_DLL + extern ConVar cl_hud_minmode; +#endif + + +LINK_ENTITY_TO_CLASS( tf_powerup_bottle, CTFPowerupBottle ); +IMPLEMENT_NETWORKCLASS_ALIASED( TFPowerupBottle, DT_TFPowerupBottle ) + +// Network Table -- +BEGIN_NETWORK_TABLE( CTFPowerupBottle, DT_TFPowerupBottle ) +#if defined( GAME_DLL ) + SendPropBool( SENDINFO( m_bActive ) ), + SendPropInt( SENDINFO( m_usNumCharges ), -1, SPROP_UNSIGNED ), +#else + RecvPropBool( RECVINFO( m_bActive ) ), + RecvPropInt( RECVINFO( m_usNumCharges ) ), +#endif // GAME_DLL +END_NETWORK_TABLE() +// -- Network Table + +// Data Desc -- +BEGIN_DATADESC( CTFPowerupBottle ) +END_DATADESC() +// -- Data Desc + +PRECACHE_REGISTER( tf_powerup_bottle ); + + +//----------------------------------------------------------------------------- +// SHARED CODE +//----------------------------------------------------------------------------- + +CTFPowerupBottle::CTFPowerupBottle() : CTFWearable() +{ + m_bActive = false; + m_usNumCharges = 0; + m_flLastSpawnTime = 0.f; + +#ifdef TF_CLIENT_DLL + ListenForGameEvent( "player_spawn" ); +#endif +} + +void CTFPowerupBottle::Precache( void ) +{ + PrecacheModel( "models/player/items/mvm_loot/all_class/mvm_flask_generic.mdl" ); + PrecacheModel( "models/player/items/mvm_loot/all_class/mvm_flask_krit.mdl" ); + PrecacheModel( "models/player/items/mvm_loot/all_class/mvm_flask_uber.mdl" ); + PrecacheModel( "models/player/items/mvm_loot/all_class/mvm_flask_tele.mdl" ); + PrecacheModel( "models/player/items/mvm_loot/all_class/mvm_flask_ammo.mdl" ); + PrecacheModel( "models/player/items/mvm_loot/all_class/mvm_flask_build.mdl" ); + + BaseClass::Precache(); +} + +//----------------------------------------------------------------------------- +// Purpose: Reset the bottle to its initial state +//----------------------------------------------------------------------------- +void CTFPowerupBottle::Reset( void ) +{ + m_bActive = false; + SetNumCharges( 0 ); + +#ifdef GAME_DLL + class CAttributeIterator_ZeroRefundableCurrency : public IEconItemUntypedAttributeIterator + { + public: + CAttributeIterator_ZeroRefundableCurrency( CAttributeList *pAttrList ) + : m_pAttrList( pAttrList ) + { + Assert( m_pAttrList ); + } + + private: + virtual bool OnIterateAttributeValueUntyped( const CEconItemAttributeDefinition *pAttrDef ) + { + if ( ::FindAttribute( m_pAttrList, pAttrDef ) ) + { + m_pAttrList->SetRuntimeAttributeRefundableCurrency( pAttrDef, 0 ); + } + + return true; + } + + CAttributeList *m_pAttrList; + }; + + CAttributeIterator_ZeroRefundableCurrency it( GetAttributeList() ); + GetAttributeList()->IterateAttributes( &it ); +#endif +} + + +PowerupBottleType_t CTFPowerupBottle::GetPowerupType( void ) const +{ + int iHasCritBoost = 0; + CALL_ATTRIB_HOOK_INT( iHasCritBoost, critboost ); + if ( iHasCritBoost ) + { + return POWERUP_BOTTLE_CRITBOOST; + } + + int iHasUbercharge = 0; + CALL_ATTRIB_HOOK_INT( iHasUbercharge, ubercharge ); + if ( iHasUbercharge ) + { + return POWERUP_BOTTLE_UBERCHARGE; + } + + int iHasRecall = 0; + CALL_ATTRIB_HOOK_INT( iHasRecall, recall ); + if ( iHasRecall ) + { + return POWERUP_BOTTLE_RECALL; + } + + int iHasRefillAmmo = 0; + CALL_ATTRIB_HOOK_INT( iHasRefillAmmo, refill_ammo ); + if ( iHasRefillAmmo ) + { + return POWERUP_BOTTLE_REFILL_AMMO; + } + + int iHasInstaBuildingUpgrade = 0; + CALL_ATTRIB_HOOK_INT( iHasInstaBuildingUpgrade, building_instant_upgrade ); + if ( iHasInstaBuildingUpgrade ) + { + return POWERUP_BOTTLE_BUILDINGS_INSTANT_UPGRADE; + } + +#ifdef STAGING_ONLY + int iSeeCashThroughWall = 0; + CALL_ATTRIB_HOOK_INT( iSeeCashThroughWall, mvm_see_cash_through_wall ); + if ( iSeeCashThroughWall ) + { + return POWERUP_BOTTLE_SEE_CASH_THROUGH_WALL; + } +#endif + + return POWERUP_BOTTLE_NONE; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFPowerupBottle::ReapplyProvision( void ) +{ + // let the base class do what it needs to do in terms of adding/removing itself from old and new owners + BaseClass::ReapplyProvision(); + + CBaseEntity *pOwner = GetOwnerEntity(); + IHasAttributes *pOwnerAttribInterface = GetAttribInterface( pOwner ); + if ( pOwnerAttribInterface ) + { + if ( m_bActive ) + { + if ( !pOwnerAttribInterface->GetAttributeManager()->IsBeingProvidedToBy( this ) ) + { + GetAttributeManager()->ProvideTo( pOwner ); + } + } + else + { + GetAttributeManager()->StopProvidingTo( pOwner ); + } + +#ifdef GAME_DLL + bool bBottleShared = false; + CTFPlayer *pTFPlayer = dynamic_cast< CTFPlayer* >( pOwner ); + if ( pTFPlayer ) + { + float flDuration = 0; + CALL_ATTRIB_HOOK_FLOAT( flDuration, powerup_duration ); + + // Add extra time? + CALL_ATTRIB_HOOK_INT_ON_OTHER( pTFPlayer, flDuration, canteen_specialist ); + + // This block of code checks if a medic has the ability to + // share bottle charges with their heal target + int iShareBottle = 0; + CWeaponMedigun *pMedigun = NULL; + CTFPlayer *pHealTarget = NULL; + if ( pTFPlayer->IsPlayerClass( TF_CLASS_MEDIC ) ) + { + pMedigun = dynamic_cast<CWeaponMedigun *>( pTFPlayer->GetActiveWeapon() ); + if ( pMedigun ) + { + pHealTarget = ToTFPlayer( pMedigun->GetHealTarget() ); + if ( pHealTarget ) + { + CALL_ATTRIB_HOOK_INT_ON_OTHER( pTFPlayer, iShareBottle, canteen_specialist ); + } + } + } + + // special stuff for conditions + int iHasCritBoost = 0; + CALL_ATTRIB_HOOK_INT( iHasCritBoost, critboost ); + if ( iHasCritBoost != 0 ) + { + if ( m_bActive ) + { + pTFPlayer->m_Shared.AddCond( TF_COND_CRITBOOSTED_USER_BUFF, flDuration ); + + if ( iShareBottle && pHealTarget ) + { + pHealTarget->m_Shared.AddCond( TF_COND_CRITBOOSTED_USER_BUFF, flDuration ); + bBottleShared = true; + } + } + else + { + pTFPlayer->m_Shared.RemoveCond( TF_COND_CRITBOOSTED_USER_BUFF, true ); + } + } + + int iHasUbercharge = 0; + CALL_ATTRIB_HOOK_INT( iHasUbercharge, ubercharge ); + if ( iHasUbercharge ) + { + if ( m_bActive ) + { + pTFPlayer->m_Shared.AddCond( TF_COND_INVULNERABLE_USER_BUFF, flDuration ); + + // Shield sentries + if ( pTFPlayer->IsPlayerClass( TF_CLASS_ENGINEER ) ) + { + for ( int i = pTFPlayer->GetObjectCount()-1; i >= 0; i-- ) + { + CObjectSentrygun *pSentry = dynamic_cast<CObjectSentrygun *>( pTFPlayer->GetObject(i) ); + if ( pSentry && !pSentry->IsCarried() ) + { + pSentry->SetShieldLevel( SHIELD_MAX, flDuration ); + } + } + } + else if ( iShareBottle && pHealTarget ) + { + pHealTarget->m_Shared.AddCond( TF_COND_INVULNERABLE_USER_BUFF, flDuration, pTFPlayer ); + bBottleShared = true; + } + } + else + { + pTFPlayer->m_Shared.RemoveCond( TF_COND_INVULNERABLE_USER_BUFF, true ); + } + } + + int iHasRecall = 0; + CALL_ATTRIB_HOOK_INT( iHasRecall, recall ); + if ( iHasRecall ) + { + if ( m_bActive ) + { + pTFPlayer->ForceRespawn(); + pTFPlayer->m_Shared.AddCond( TF_COND_SPEED_BOOST, 7.f ); + } + } + + int iHasRefillAmmo = 0; + CALL_ATTRIB_HOOK_INT( iHasRefillAmmo, refill_ammo ); + if ( iHasRefillAmmo ) + { + if ( m_bActive ) + { + // Refill weapon clips + for ( int i = 0; i < MAX_WEAPONS; i++ ) + { + CBaseCombatWeapon *pWeapon = pTFPlayer->GetWeapon(i); + if ( !pWeapon ) + continue; + + // ACHIEVEMENT_TF_MVM_USE_AMMO_BOTTLE + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) + { + if ( ( pWeapon->UsesPrimaryAmmo() && !pWeapon->HasPrimaryAmmo() ) || + ( pWeapon->UsesSecondaryAmmo() && !pWeapon->HasSecondaryAmmo() ) ) + { + pTFPlayer->AwardAchievement( ACHIEVEMENT_TF_MVM_USE_AMMO_BOTTLE ); + } + } + + pWeapon->GiveDefaultAmmo(); + + if ( iShareBottle && pHealTarget ) + { + CBaseCombatWeapon *pPatientWeapon = pHealTarget->GetWeapon(i); + if ( !pPatientWeapon ) + continue; + + pPatientWeapon->GiveDefaultAmmo(); + bBottleShared = true; + } + } + + // And give the player ammo + for ( int iAmmo = 0; iAmmo < TF_AMMO_COUNT; ++iAmmo ) + { + pTFPlayer->GiveAmmo( pTFPlayer->GetMaxAmmo(iAmmo), iAmmo, true, kAmmoSource_Resupply ); + + if ( iShareBottle && pHealTarget ) + { + pHealTarget->GiveAmmo( pHealTarget->GetMaxAmmo(iAmmo), iAmmo, true, kAmmoSource_Resupply ); + bBottleShared = true; + } + } + } + } + + int iHasInstaBuildingUpgrade = 0; + CALL_ATTRIB_HOOK_INT( iHasInstaBuildingUpgrade, building_instant_upgrade ); + if ( iHasInstaBuildingUpgrade ) + { + if ( m_bActive ) + { + for ( int i = pTFPlayer->GetObjectCount()-1; i >= 0; i-- ) + { + CBaseObject *pObj = pTFPlayer->GetObject(i); + if ( pObj ) + { + int nMaxLevel = pObj->GetMaxUpgradeLevel(); + + // If object is carried, set the target max and move on + if ( pObj->IsCarried() ) + { + pObj->SetHighestUpgradeLevel( nMaxLevel ); + continue; + } + + // If we're already at max level, heal + if ( pObj->GetUpgradeLevel() == nMaxLevel ) + { + pObj->SetHealth( pObj->GetMaxHealth() ); + } + else + { + if ( TFGameRules() && TFGameRules()->IsMannVsMachineMode() ) + { + if ( pObj->GetType() == OBJ_SENTRYGUN ) + { + IGameEvent *event = gameeventmanager->CreateEvent( "mvm_quick_sentry_upgrade" ); + if ( event ) + { + event->SetInt( "player", GetOwnerEntity()->entindex() ); + gameeventmanager->FireEvent( event ); + } + } + } + + pObj->DoQuickBuild( true ); + } + } + } + } + } + + // ACHIEVEMENT_TF_MVM_MEDIC_SHARE_BOTTLES + if ( bBottleShared ) + { + IGameEvent *event = gameeventmanager->CreateEvent( "mvm_medic_powerup_shared" ); + if ( event ) + { + event->SetInt( "player", pTFPlayer->entindex() ); + gameeventmanager->FireEvent( event ); + } + } + } +#endif + } +} + + +//----------------------------------------------------------------------------- +// Purpose: Removes the item and deactivates any effect +//----------------------------------------------------------------------------- +void CTFPowerupBottle::UnEquip( CBasePlayer* pOwner ) +{ + BaseClass::UnEquip( pOwner ); + RemoveEffect(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CTFPowerupBottle::Use() +{ + if ( !m_bActive && GetNumCharges() > 0 ) + { + if ( !AllowedToUse() ) + return false; + +#ifdef GAME_DLL + // Use up one charge worth of refundable money when a charge is used + class CAttributeIterator_ConsumeOneRefundableCharge : public IEconItemUntypedAttributeIterator + { + public: + CAttributeIterator_ConsumeOneRefundableCharge( CAttributeList *pAttrList, int iNumCharges ) + : m_pAttrList( pAttrList ) + , m_iNumCharges( iNumCharges ) + { + Assert( m_pAttrList ); + Assert( m_iNumCharges > 0 ); + } + + private: + virtual bool OnIterateAttributeValueUntyped( const CEconItemAttributeDefinition *pAttrDef ) + { + if ( ::FindAttribute( m_pAttrList, pAttrDef ) ) + { + int nRefundableCurrency = m_pAttrList->GetRuntimeAttributeRefundableCurrency( pAttrDef ); + if ( nRefundableCurrency > 0 ) + { + m_pAttrList->SetRuntimeAttributeRefundableCurrency( pAttrDef, nRefundableCurrency - (nRefundableCurrency / m_iNumCharges) ); + } + } + + // Backwards compatibility -- assume any number of attributes. + return true; + } + + CAttributeList *m_pAttrList; + int m_iNumCharges; + }; + + CAttributeIterator_ConsumeOneRefundableCharge it( GetAttributeList(), GetNumCharges() ); + GetAttributeList()->IterateAttributes( &it ); +#endif + + float flDuration = 0; + CALL_ATTRIB_HOOK_FLOAT( flDuration, powerup_duration ); + + // Add extra time? + CTFPlayer *pOwner = ToTFPlayer( GetOwnerEntity() ); + if ( pOwner ) + { + CALL_ATTRIB_HOOK_INT_ON_OTHER( pOwner, flDuration, canteen_specialist ); + } + IGameEvent *event = gameeventmanager->CreateEvent( "player_used_powerup_bottle" ); + if ( event ) + { + event->SetInt( "player", GetOwnerEntity()->entindex() ); + event->SetInt( "type", GetPowerupType() ); + event->SetFloat( "time", flDuration ); + gameeventmanager->FireEvent( event ); + } + +#ifdef GAME_DLL + if ( pOwner ) + { + EconEntity_OnOwnerKillEaterEventNoPartner( dynamic_cast<CEconEntity *>( this ), pOwner, kKillEaterEvent_PowerupBottlesUsed ); + + // we consumed an upgrade - forget it + pOwner->ForgetFirstUpgradeForItem( GetAttributeContainer()->GetItem() ); + } +#endif + + SetNumCharges( GetNumCharges() - 1 ); + m_bActive = true; + ReapplyProvision(); + + SetContextThink( &CTFPowerupBottle::StatusThink, gpGlobals->curtime + flDuration, "PowerupBottleThink" ); + return true; + } + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFPowerupBottle::StatusThink() +{ + RemoveEffect(); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFPowerupBottle::RemoveEffect() +{ + m_bActive = false; + ReapplyProvision(); + SetContextThink( NULL, 0, "PowerupBottleThink" ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CTFPowerupBottle::SetNumCharges( uint8 usNumCharges ) +{ + static CSchemaAttributeDefHandle pAttrDef_PowerupCharges( "powerup charges" ); + + m_usNumCharges = usNumCharges; + + if ( !pAttrDef_PowerupCharges ) + return; + + CEconItemView *pEconItemView = GetAttributeContainer()->GetItem(); + if ( !pEconItemView ) + return; + + pEconItemView->GetAttributeList()->SetRuntimeAttributeValue( pAttrDef_PowerupCharges, float( usNumCharges ) ); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +uint8 CTFPowerupBottle::GetNumCharges() const +{ + return m_usNumCharges; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +uint8 CTFPowerupBottle::GetMaxNumCharges() const +{ + int iMaxNumCharges = 0; + CALL_ATTRIB_HOOK_INT( iMaxNumCharges, powerup_max_charges ); + + // Default canteen has 3 charges. Medic canteen specialist allows purchasing 3 more charges. + // If anything else increases max charges, we need to refactor how canteen specialist is handled. + Assert( iMaxNumCharges >= 0 && iMaxNumCharges <= 6 ); + + iMaxNumCharges = Min( iMaxNumCharges, 6 ); + + return (uint8)iMaxNumCharges; +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +bool CTFPowerupBottle::AllowedToUse() +{ + if ( TFGameRules() && !( TFGameRules()->State_Get() == GR_STATE_BETWEEN_RNDS || TFGameRules()->State_Get() == GR_STATE_RND_RUNNING ) ) + return false; + + CTFPlayer *pPlayer = ToTFPlayer( GetOwnerEntity() ); + if ( !pPlayer ) + return false; + + if ( pPlayer->IsObserver() || !pPlayer->IsAlive() ) + return false; + +#ifdef GAME_DLL + m_flLastSpawnTime = pPlayer->GetSpawnTime(); +#endif + + if ( gpGlobals->curtime < m_flLastSpawnTime + 0.7f ) + return false; + + return true; +} + +const char* CTFPowerupBottle::GetEffectLabelText( void ) +{ +#ifndef GAME_DLL + if ( cl_hud_minmode.GetBool() ) + { + return "#TF_PVE_UsePowerup_MinMode"; + } +#endif + + switch ( GetPowerupType() ) + { + case POWERUP_BOTTLE_CRITBOOST: + return "#TF_PVE_UsePowerup_CritBoost"; + + case POWERUP_BOTTLE_UBERCHARGE: + return "#TF_PVE_UsePowerup_Ubercharge"; + + case POWERUP_BOTTLE_RECALL: + return "#TF_PVE_UsePowerup_Recall"; + + case POWERUP_BOTTLE_REFILL_AMMO: + return "#TF_PVE_UsePowerup_RefillAmmo"; + + case POWERUP_BOTTLE_BUILDINGS_INSTANT_UPGRADE: + return "#TF_PVE_UsePowerup_BuildinginstaUpgrade"; + + case POWERUP_BOTTLE_RADIUS_STEALTH: + return "#TF_PVE_UsePowerup_RadiusStealth"; +#ifdef STAGING_ONLY + case POWERUP_BOTTLE_SEE_CASH_THROUGH_WALL: + return "#TF_PVE_UsePowerup_SeeCashThroughWall"; +#endif + } + + return "#TF_PVE_UsePowerup_CritBoost"; +} + +const char* CTFPowerupBottle::GetEffectIconName( void ) +{ + switch ( GetPowerupType() ) + { + case POWERUP_BOTTLE_CRITBOOST: + return "../hud/ico_powerup_critboost_red"; + + case POWERUP_BOTTLE_UBERCHARGE: + return "../hud/ico_powerup_ubercharge_red"; + + case POWERUP_BOTTLE_RECALL: + return "../hud/ico_powerup_recall_red"; + + case POWERUP_BOTTLE_REFILL_AMMO: + return "../hud/ico_powerup_refill_ammo_red"; + + case POWERUP_BOTTLE_BUILDINGS_INSTANT_UPGRADE: + return "../hud/ico_powerup_building_instant_red"; + + case POWERUP_BOTTLE_RADIUS_STEALTH: + return "../vgui/achievements/tf_soldier_kill_spy_killer"; +#ifdef STAGING_ONLY + case POWERUP_BOTTLE_SEE_CASH_THROUGH_WALL: + return "../vgui/achievements/tf_mvm_earn_money_bonus"; +#endif + } + + return "../hud/ico_powerup_critboost_red"; +} + +#ifdef TF_CLIENT_DLL +void CTFPowerupBottle::FireGameEvent( IGameEvent *event ) +{ + const char *pszEventName = event->GetName(); + + if ( FStrEq( pszEventName, "player_spawn" ) ) + { + CTFPlayer *pTFOwner = ToTFPlayer( GetOwnerEntity() ); + if ( !pTFOwner ) + return; + + const int nUserID = event->GetInt( "userid" ); + CTFPlayer *pPlayer = ToTFPlayer( UTIL_PlayerByUserId( nUserID ) ); + if ( pPlayer && pPlayer == pTFOwner ) + { + m_flLastSpawnTime = gpGlobals->curtime; + } + } +} + +int CTFPowerupBottle::GetWorldModelIndex( void ) +{ + if ( IsBasePowerUpBottle() && ( GetNumCharges() > 0 ) ) + { + switch ( GetPowerupType() ) + { + case POWERUP_BOTTLE_CRITBOOST: + return modelinfo->GetModelIndex( "models/player/items/mvm_loot/all_class/mvm_flask_krit.mdl" ); + + case POWERUP_BOTTLE_UBERCHARGE: + return modelinfo->GetModelIndex( "models/player/items/mvm_loot/all_class/mvm_flask_uber.mdl" ); + + case POWERUP_BOTTLE_RECALL: + return modelinfo->GetModelIndex( "models/player/items/mvm_loot/all_class/mvm_flask_tele.mdl" ); + + case POWERUP_BOTTLE_REFILL_AMMO: + return modelinfo->GetModelIndex( "models/player/items/mvm_loot/all_class/mvm_flask_ammo.mdl" ); + + case POWERUP_BOTTLE_BUILDINGS_INSTANT_UPGRADE: + return modelinfo->GetModelIndex( "models/player/items/mvm_loot/all_class/mvm_flask_build.mdl" ); + + case POWERUP_BOTTLE_RADIUS_STEALTH: +#ifdef STAGING_ONLY + case POWERUP_BOTTLE_SEE_CASH_THROUGH_WALL: +#endif + return modelinfo->GetModelIndex( "models/player/items/mvm_loot/all_class/mvm_flask_tele.mdl" ); + } + } + + return BaseClass::GetWorldModelIndex(); +} +#endif + +int CTFPowerupBottle::GetSkin() +{ + if ( !IsBasePowerUpBottle() ) + { + return ( ( GetNumCharges() > 0 ) ? 1 : 0 ); + } + + return BaseClass::GetSkin(); +} + + +#ifdef CLIENT_DLL +// ****************************************************************************************** +// CEquipMvMCanteenNotification - Client notification to equip a canteen +// ****************************************************************************************** +void CEquipMvMCanteenNotification::Accept() +{ + m_bHasTriggered = true; + + CPlayerInventory *pLocalInv = TFInventoryManager()->GetLocalInventory(); + if ( !pLocalInv ) + { + MarkForDeletion(); + return; + } + + C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); + if ( !pLocalPlayer ) + { + MarkForDeletion(); + return; + } + + // try to equip non-stock-spellbook first + static CSchemaItemDefHandle pItemDef_Robo( "Battery Canteens" ); + static CSchemaItemDefHandle pItemDef_KritzOrTreat( "Kritz Or Treat Canteen" ); + static CSchemaItemDefHandle pItemDef_Canteen( "Power Up Canteen (MvM)" ); + static CSchemaItemDefHandle pItemDef_DefaultCanteen( "Default Power Up Canteen (MvM)" ); + + CEconItemView *pCanteen= NULL; + + Assert( pItemDef_Robo ); + Assert( pItemDef_KritzOrTreat ); + Assert( pItemDef_Canteen ); + Assert( pItemDef_DefaultCanteen ); + + for ( int i = 0; i < pLocalInv->GetItemCount(); ++i ) + { + CEconItemView *pItem = pLocalInv->GetItem( i ); + Assert( pItem ); + + if ( pItem->GetItemDefinition() == pItemDef_Robo + || pItem->GetItemDefinition() == pItemDef_KritzOrTreat + || pItem->GetItemDefinition() == pItemDef_Canteen + || pItem->GetItemDefinition() == pItemDef_DefaultCanteen + ) { + pCanteen = pItem; + break; + } + } + + // Default item becomes a spellbook in this mode + itemid_t iItemId = INVALID_ITEM_ID; + if ( pCanteen ) + { + iItemId = pCanteen->GetItemID(); + } + + TFInventoryManager()->EquipItemInLoadout( pLocalPlayer->GetPlayerClass()->GetClassIndex(), LOADOUT_POSITION_ACTION, iItemId ); + + // Tell the GC to tell server that we should respawn if we're in a respawn room + GCSDK::CGCMsg< GCSDK::MsgGCEmpty_t > msg( k_EMsgGCRespawnPostLoadoutChange ); + GCClientSystem()->BSendMessage( msg ); + + MarkForDeletion(); +} + +//=========================================================================================== +void CEquipMvMCanteenNotification::UpdateTick() +{ + C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); + if ( pLocalPlayer ) + { + CTFPowerupBottle *pCanteen = dynamic_cast<CTFPowerupBottle*>( TFInventoryManager()->GetItemInLoadoutForClass( pLocalPlayer->GetPlayerClass()->GetClassIndex(), LOADOUT_POSITION_ACTION ) ); + if ( pCanteen ) + { + MarkForDeletion(); + } + } +} +#endif // client + |