Difference between revisions of "Throwable weapons"

From Team Fortress Wiki
Jump to: navigation, search
m (404UNF moved page Throwable Weapons to Throwable weapons: Proper capitalization for this type of article)
m (Whoops, the bread monster throwable is the two jars from Expiration Date, not a new throwable.)
Line 211: Line 211:
 
     MODEL_SYRINGE, // Syringe Gun projectile
 
     MODEL_SYRINGE, // Syringe Gun projectile
 
     MODEL_FESTIVE_HEALING_BOLT, // Festive Crusader's Crossbow
 
     MODEL_FESTIVE_HEALING_BOLT, // Festive Crusader's Crossbow
     MODEL_BREAD_MONSTER, // Throwable Bread Monster, mentioned above
+
     MODEL_BREAD_MONSTER, // Self-Aware Beauty Mark and the other breadmonster Jar item
 
     MODEL_GRAPPLINGHOOK, // Grappling Hook
 
     MODEL_GRAPPLINGHOOK, // Grappling Hook
 
   
 
   

Revision as of 02:09, 24 April 2020

Throwable weapons were a new class of weapons that were being tested internally by Valve, but were either cut or abandoned.

Functionality

Throwable weapons were classed as either being "primable" or "chargeable";

// Primable is for timed explosions
// Charagable is for things like distance or power increases
// Can't really have both but can have neither

Slots

Throwable slots were apparently considered, with the experimental "Utility" slot making an appearance as well.

#ifdef STAGING_ONLY
CREATE_SIMPLE_WEAPON_TABLE( TFThrowablePrimary, tf_weapon_throwable_primary )
CREATE_SIMPLE_WEAPON_TABLE( TFThrowableSecondary, tf_weapon_throwable_secondary )
CREATE_SIMPLE_WEAPON_TABLE( TFThrowableMelee, tf_weapon_throwable_melee )
CREATE_SIMPLE_WEAPON_TABLE( TFThrowableUtility, tf_weapon_throwable_utility )
#endif

Throwables

Several varieties of throwable weapons have been discovered.

Repel

A throwable airblast. Throwing it would cause it to apply airblast force to any enemies within range of it, pushing them away and making their view shake;

// Apply AirBlast Force
Vector vecToTarget;
vecToTarget = pPlayer->GetAbsOrigin() - this->GetAbsOrigin();
vecToTarget.z = 0;
VectorNormalize( vecToTarget );
float flForce = 300.0f * m_flChargePercent + 350.0f;
pPlayer->ApplyAirBlastImpulse( vecToTarget * flForce + Vector( 0, 0, flForce ) );
pPlayer->ApplyPunchImpulseX( RandomInt( -50, -30 ) );

Enemies under the Quick Fix's ubercharge were programmed to be immune to this force;

// Quick Fix Uber is immune
if ( pPlayer->m_Shared.InCond( TF_COND_MEGAHEAL )) 
    return;

Enemies also take damage.

// Apply Damage to Victim
CTakeDamageInfo info;
info.SetAttacker( GetThrower() );
info.SetInflictor( this ); 
info.SetWeapon( GetLauncher() );
info.SetDamage( GetDamage() );
info.SetDamageCustom( GetCustomDamageType() );
info.SetDamagePosition( this->GetAbsOrigin() );
info.SetDamageType( DMG_CLUB | DMG_PREVENT_PHYSICS_FORCE );

pPlayer->DispatchTraceAttack( info, vecToTarget, &trace );
ApplyMultiDamage();

Brick

A brick. Highly reminiscent of Timesplitters. Hitting an enemy with it would deal some damage and shake up their view;

// Apply Damage to Victim
CTakeDamageInfo info;
info.SetAttacker( GetThrower() );
info.SetInflictor( this ); 
info.SetWeapon( GetLauncher() );
info.SetDamage( GetDamage() );
info.SetDamageCustom( GetCustomDamageType() );
info.SetDamagePosition( GetAbsOrigin() );
info.SetDamageType( DMG_CLUB );

pPlayer->DispatchTraceAttack( info, vecToTarget, &trace );
pPlayer->ApplyPunchImpulseX( RandomInt( 15, 20 ) );
ApplyMultiDamage();

Target Dummy

A portable target dummy. Throwing this would create a Target Dummy. Pretty self-explanatory.

void CTFProjectile_ThrowableTargetDummy::Explode()
{
    CTFPlayer *pPlayer = ToTFPlayer( GetThrower() );
    if ( !pPlayer )
        return;

    CTFTargetDummy::Create( GetAbsOrigin(), GetAbsAngles(), pPlayer );
    BaseClass::Explode();
}

Concussion Grenade

Return of the Concussion Grenade. It seems Valve had been playing around with trying to bring the Concussion Grenade back somehow.

Teleport Grenade

The Teleport Grenade would teleport the user to wherever the grenade was thrown.

// Try a few spots
FOR_EACH_VEC_BACK( m_vecTrailingPos, i )
{
   // Try positions starting with the current, and moving back in time a bit
   Vector vecStart = m_vecTrailingPos[i];
   UTIL_TraceHull( vecStart, vecStart, VEC_HULL_MIN, VEC_HULL_MAX, nMask, &traceFilter, &traceHull );

   if ( !traceHull.DidHit() )
   {
       // Place a teleport effect where they came from
       const Vector& vecOrigin = pThrower->GetAbsOrigin();
       CPVSFilter pvsFilter( vecOrigin );
       TE_TFParticleEffect( pvsFilter, 0.f, GetExplodeEffectParticle(), vecOrigin, vec3_angle );

       // Move 'em!
       pThrower->Teleport( &vecStart, &pThrower->GetAbsAngles(), NULL );

       // Do a zoom effect
       pThrower->SetFOV( pThrower, 0.f, 0.3f, 120.f );

       // Screen flash
       color32 fadeColor = { 255, 255, 255, 100 };
       UTIL_ScreenFade( pThrower, fadeColor, 0.25f, 0.4f, FFADE_IN );

       if ( TFGameRules() )
       {
           TFGameRules()->HaveAllPlayersSpeakConceptIfAllowed( MP_CONCEPT_PLAYER_SPELL_TELEPORT, ( pThrower->GetTeamNumber() == TF_TEAM_RED ) ? TF_TEAM_BLUE : TF_TEAM_RED );
       }
   }
}

Chain Grenade

Also referred to in code as the Gravity Grenade. A trap style grenade, it functioned similar to a black hole, dragging anyone within range closer to it.

void CTFProjectile_GravityGrenade::PulseTrap( void )
{
   const int nMaxEnts = 32;

   Vector vecPos = GetAbsOrigin();
   CBaseEntity *pObjects[ nMaxEnts ];
   int nCount = UTIL_EntitiesInSphere( pObjects, nMaxEnts, vecPos, GetDamageRadius(), FL_CLIENT );

   // Iterate through sphere's contents
   for ( int i = 0; i < nCount; i++ )
   {
       CBaseCombatCharacter *pEntity = pObjects[i]->MyCombatCharacterPointer();
       if ( !pEntity )
           continue;

       if ( InSameTeam( pEntity ) )
           continue;

       if ( !FVisible( pEntity, MASK_OPAQUE ) )
           continue;

       // Draw player toward us
       Vector vecSourcePos = pEntity->GetAbsOrigin();
       Vector vecTargetPos = GetAbsOrigin();
       Vector vecVelocity = ( vecTargetPos - vecSourcePos ) * 2.f;
       vecVelocity.z += 50.f;

       if ( pEntity->GetFlags() & FL_ONGROUND )
       {
           vecVelocity.z += 150.f;
           pEntity->SetGroundEntity( NULL );
           pEntity->SetGroundChangeTime( gpGlobals->curtime + 0.5f );
       }

       pEntity->Teleport( NULL, NULL, &vecVelocity );
   }

   // NDebugOverlay::Sphere( vecPos, GetDamageRadius(), 0, 255, 0, false, 0.35f );

   PulseEffects();
}

Smoke Grenade

Similar to the aforementioned Concussion Grenade, the Smoke Grenade would have been a second go at trying to bring back the Smoke Bomb from the early development days.

Throwing Knife

Throwing Knives were tested as well. They would do crits if they hit someone from behind and much like arrows and some other certain projectiles, throwing knives would stick out of the person you hit.

// Is from behind?
bool bIsFromBehind = DotProduct( toEnt, entForward ) > 0.7071f;

// Apply Damage to Victim
CTakeDamageInfo info;
info.SetAttacker( GetThrower() );
info.SetInflictor( this );
info.SetWeapon( GetLauncher() );
info.SetDamageCustom( GetCustomDamageType() );
info.SetDamagePosition( GetAbsOrigin() );

int iDamageType = DMG_CLUB;
if ( bIsFromBehind )
{
    iDamageType |= DMG_CRITICAL;
}

info.SetDamageType( iDamageType );
info.SetDamage( bIsFromBehind ? GetBackHitDamage() : GetDamage() );

pVictim->DispatchTraceAttack( info, toEnt, &trace );
ApplyMultiDamage();

CreateStickyAttachmentToTarget( pOwner, pVictim, &trace );

Snowball

The only evidence to the existence of the Snowball is the MODEL_SNOWBALL enum entry from the enumerator used to store model defines for arrow projectiles;

The comments in the code below were added for this article to help clarify what things are and were not written by Valve.

enum arrow_models
{
   MODEL_ARROW_REGULAR, // Regular arrow
   MODEL_ARROW_BUILDING_REPAIR, // Rescue Ranger projectile
   MODEL_SNOWBALL, // Snowball?
   MODEL_FESTIVE_ARROW_REGULAR, // Festive arrow
   MODEL_SYRINGE, // Syringe Gun projectile
   MODEL_FESTIVE_HEALING_BOLT, // Festive Crusader's Crossbow
   MODEL_BREAD_MONSTER, // Self-Aware Beauty Mark and the other breadmonster Jar item
   MODEL_GRAPPLINGHOOK, // Grappling Hook

   // Staging
   MODEL_THROWING_KNIFE, // Throwing Knife, mentioned above

   TF_ARROW_MODEL_COUNT // # of models in this enumerator which would be 9
};