Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/sr2echa/TF2-Source-Code/llms.txt

Use this file to discover all available pages before exploring further.

All world pickups in TF2 share a common base hierarchy: CItemCTFPowerup → specific pack class. CTFPowerup (defined in game/server/tf/tf_powerup.h) handles the respawn cycle, ValidTouch gating, and the DropSingleInstance path used when packs are thrown into the world (e.g. from a dead player).

Pack types and sizes

The powerupsize_t enum has three values that each subclass returns from GetPowerupSize():
Size constantHealth kitsAmmo packsHeal %Ammo %
POWERUP_SMALLCHealthKitSmallCAmmoPackSmall20.5%20%
POWERUP_MEDIUMCHealthKitMediumCAmmoPackMedium50%50%
POWERUP_FULLCHealthKit (large)CAmmoPack (large)100%100%
Actual heal and ammo amounts are calculated at pickup time using the PackRatios[POWERUP_SIZES] array against the player’s max health or max ammo. CHealthAmmoKit is a hybrid that restores both health and ammo; it derives from CHealthKit and overrides MyTouch to additionally top up ammo.

Health kit class hierarchy

// entity_healthkit.h
class CHealthKit : public CTFPowerup { ... };          // large — POWERUP_FULL
class CHealthKitSmall  : public CHealthKit { ... };    // POWERUP_SMALL
class CHealthKitMedium : public CHealthKit { ... };    // POWERUP_MEDIUM
class CHealthAmmoKit   : public CHealthKit { ... };    // POWERUP_SMALL, heals + reloads
All three sizes override GetDefaultPowerupModel() to swap in birthday and Halloween model variants when the corresponding holiday is active via TFGameRules()->IsHolidayActive(kHoliday_TFBirthday).

Ammo pack class hierarchy

// entity_ammopack.h
class CAmmoPack       : public CTFPowerup { ... };   // large — POWERUP_FULL
class CAmmoPackSmall  : public CAmmoPack  { ... };   // POWERUP_SMALL
class CAmmoPackMedium : public CAmmoPack  { ... };   // POWERUP_MEDIUM
CAmmoPack::MyTouch calls TFGameRules()->DistributeAmmo() to fill the touching player’s ammo pools. The dropped-weapon variant (CTFAmmoPack, a separate class) uses physics simulation — it’s thrown with velocity when a player dies and disappears after TF_POWERUP_LIFETIME (30 seconds).

Touch detection

CTFPowerup uses the engine’s CItem::ItemTouch touch callback, gated by ValidTouch:
// tf_powerup.h:46
virtual bool ValidTouch( CBasePlayer *pPlayer );
virtual bool MyTouch( CBasePlayer *pPlayer );  // subclass override for actual effect
ValidTouch checks that the touching entity is a live player on the correct team. MyTouch is called only if ValidTouch passes — returning true removes the pickup and starts the respawn timer.

Respawn timer

// tf_powerup.h:54
virtual float GetRespawnDelay( void ) { return g_pGameRules->FlItemRespawnTime( this ); }
CTFPowerup::Respawn() hides the model and schedules Materialize() after GetRespawnDelay() seconds. CHealthKit overrides GetRespawnDelay() to return a custom value. During the respawn window, m_bRespawning is true and ValidTouch rejects all touches.

MvM currency packs

CCurrencyPack (in entity_currencypack.h) is the MvM money drop. It extends CTFPowerup with a radius collection system: nearby players “claim” a pack (SetClaimed()) and the pack steers toward them via physics. m_bDistributed is a CNetworkVar<bool> used to sync the claimed state to clients.
// entity_currencypack.h
class CCurrencyPack       : public CTFPowerup { ... };  // TF_CURRENCY_PACK_LARGE
class CCurrencyPackMedium : public CCurrencyPack { ... };
class CCurrencyPackSmall  : public CCurrencyPack { ... };
class CCurrencyPackCustom : public CCurrencyPack { ... };  // TF_CURRENCY_PACK_CUSTOM
SetAmount(float) sets the credit value independently of pack size, used by CCurrencyPackCustom for wave-specific reward scaling. BlinkThink() drives the visual blink effect before the pack expires.
Currency packs override AffectedByRadiusCollection() returning true, which opts them into the MvM magnet mechanic. Standard health and ammo packs do not implement this method.

Build docs developers (and LLMs) love