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.

Status effects in TF2 — burning, crit boosts, Ubercharge, invisibility, stun, and dozens more — are all represented as conditions. Each condition is a value from the ETFCond enum. Active conditions are managed by CTFConditionList, which is embedded in CTFPlayerShared and networked to the client automatically.

The ETFCond enum

ETFCond is declared in game/shared/tf/tf_shareddefs.h. A selection of key values:
ConditionValueEffect
TF_COND_AIMING0Sniper scoped / Heavy spun-up; caps move speed
TF_COND_DISGUISED3Spy has an active disguise
TF_COND_STEALTHED4Spy is cloaked
TF_COND_INVULNERABLE5ÜberCharge active; blocks all damage
TF_COND_CRITBOOSTED11Guaranteed crits (Kritzkrieg / revenge)
TF_COND_STUNNED16Any stun; check iStunFlags for type
TF_COND_BURNING22On fire from Pyro or similar source
TF_COND_HEALTH_OVERHEALED23Medic overheal above base HP
TF_COND_SPEED_BOOST32Temporary speed increase
TF_COND_BLASTJUMPING80In the air from a blast jump; skips landing speed clamp
TF_COND_MEDIGUN_UBER_BULLET_RESIST57Vaccinator bullet-resist Über
TF_COND_MEDIGUN_UBER_BLAST_RESIST58Vaccinator blast-resist Über
TF_COND_MEDIGUN_UBER_FIRE_RESIST59Vaccinator fire-resist Über
The comment on TF_COND_CRITBOOSTED in the source reads “DO NOT RE-USE THIS — THIS IS FOR KRITZKRIEG AND REVENGE CRITS ONLY”. Weapon-specific crit boosts use dedicated values such as TF_COND_CRITBOOSTED_ON_KILL (40) or TF_COND_CRITBOOSTED_DEMO_CHARGE (35).

CTFPlayerShared API

Conditions are added, removed, and queried through three methods on CTFPlayerShared (game/shared/tf/tf_player_shared.h):
// game/shared/tf/tf_player_shared.h:279
void AddCond  ( ETFCond eCond, float flDuration = PERMANENT_CONDITION,
                CBaseEntity *pProvider = NULL );
void RemoveCond( ETFCond eCond, bool ignore_duration = false );
bool InCond   ( ETFCond eCond ) const;
PERMANENT_CONDITION is defined as -1. Passing it (the default) means the condition lasts until explicitly removed. Any positive value is a duration in seconds. pProvider is the entity that applied the condition. It is stored on the underlying CTFCondition object and used to credit kills, calculate crit multipliers, and handle edge cases like Medic disconnects.

How conditions are stored and checked

Conditions are managed by CTFConditionList, embedded in CTFPlayerShared:
// game/shared/tf/tf_condition.h:27
class CTFConditionList
{
    bool Add   ( ETFCond type, float duration, CTFPlayer* outer,
                 CBaseEntity* provider = NULL );
    bool Remove( ETFCond type, bool ignore_duration = false );
    bool InCond( ETFCond type ) const;

private:
    CUtlVector< CTFCondition* > _conditions;   // active condition objects
    CNetworkVar( int, _condition_bits );        // bitmask for fast InCond() checks
};
InCond() checks the _condition_bits bitmask rather than walking _conditions, so condition tests are O(1). The bitmask is a CNetworkVar, meaning it is sent to the client in every delta-compressed network update.

Duration-based vs permanent conditions

Each CTFCondition tracks _max_duration and _min_duration. OnThink() is called every tick to count down the remaining duration and call Remove() when it expires. Some conditions override UsesMinDuration() to enforce a floor — for example CTFCondition_CritBoost prevents the crit boost from being healed or removed before the minimum duration has elapsed:
// game/shared/tf/tf_condition.h:107
class CTFCondition_CritBoost : public CTFCondition
{
    virtual bool IsHealable()      { return false; }
    virtual bool UsesMinDuration() { return true;  }
};
When a condition is added while it is already active, CTFCondition::Add() refreshes the duration to the new value if it is longer than the remaining time. It does not stack duplicate condition objects.

Network replication

_condition_bits is a CNetworkVar(int, ...) inside CTFConditionList, which is itself declared with DECLARE_EMBEDDED_NETWORKVAR(). The Source DataTable system propagates the bitmask inside DT_TFPlayerShared every time it changes. The client-side OnDataChanged() callback on CTFConditionList diffs the old and new bitmasks to drive visual and audio effects (flame particles, Über glow, cloak shimmer, etc.) without the server needing to send explicit event messages.

Build docs developers (and LLMs) love