Making a weapon that heal players

== Constructor ==
The following block of code is an integer variable.
m_bDropped = 0; // This is to make sure the Medic drops it one at a time
== Primary Fire ==
The primary fire of the weapon drops one health vial per shot. Comments have been added for clarity.
 if (!m_bDropped) { // If the health vial hasn't been dropped, continue
#ifndef CLIENT_DLL
 CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); // Grab the wielder
 Vector vecEye = pPlayer->EyePosition(); // Get the eye vector of the wielder
 Vector vForward, vRight; // Create 2 new vectors
 pPlayer->EyeVectors( &vForward, &vRight, NULL ); // Getting forward direction
 Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f; // Find source of spawn
 trace_t tr; // Gets the trace
 UTIL_TraceHull( vecEye, vecSrc, -Vector(6,6,6), Vector(6,6,6),
 pPlayer->PhysicsSolidMaskForEntity(), pPlayer, pPlayer->GetCollisionGroup(), &tr ); // Checks if anything in front of it
 
 if ( tr.DidHit() ) // If hit
 {
 vecSrc = tr.endpos; // Drop at location
 }
 // CheckThrowPosition( pPlayer, vecEye, vecSrc );
 // vForward[0] += 0.1f;
 vForward[2] += 0.1f; // Something else
 Vector vecThrow;
 AngleVectors( pPlayer->EyeAngles() + pPlayer->GetPunchAngle(), &vecThrow ); // Get Vector for Impulse on Health Vial
 // pPlayer->GetVelocity( &vecThrow, NULL );
 VectorScale( vecThrow, 1000.0f, vecThrow ); // Scale vial down
 // vecThrow += vForward * 1200;
 CBaseEntity *pVial = NULL; // Null
 pVial = CBaseEntity::Create( "item_healthvial", pPlayer->Weapon_ShootPosition(), QAngle(80,60,0), pPlayer ); // Creates
 pVial->AddSpawnFlags(SF_NORESPAWN); // Doesn't allow respawning
 if (!pVial) // Has to have to be created to throw it
 {
 DevMsg("Unable to create item!\n");
 }else // Works
 {
 DevMsg(2, "Starting item throw (Server)\n");
 IPhysicsObject *pPhysicsObject = pVial->VPhysicsGetObject(); // Get the physic object
 if ( pPhysicsObject )
 {
 DevMsg(2, "Throwing item (Server)\n");
 pPhysicsObject->SetVelocity( &vecThrow, NULL );// Throw vial
 
 }
 }
 m_bDropped = 1; // Change flag
#endif
 } else {
 DevMsg(2, "Already dropped one. Release the button. (Server)\n"); // Let go of button
 }
== Item Post Frame ==
This block of code will add to the ItemPostFrame in the weapon.
if (!((pOwner->m_nButtons & IN_ATTACK) || (pOwner->m_nButtons & IN_ATTACK2) || (pOwner->m_nButtons & IN_RELOAD)))
 {
 m_bDropped = 0;
 }
== Secondary Fire ==
If player(s) are too close from the medic or the gun, it will heal the player(s).
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CWeaponHealer::SecondaryAttack( void ) 
{
 if (CanHealPlayer()) // Checks if it can heal
 HealPlayer(); // Run method
}
bool CWeaponHealer::CanHealPlayer( void ) // Checks boolean
{
 if (!m_bFired){ // If it hasn't been fired,
 CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() ); // Get owner of this weapon
 if (!pOwner) // If owner doesn't exist
 {
 return false; // Terminate code
 }
 Vector vecSrc, vecAiming; // Create vectors used for secondary fire
 // Take the eye position and direction
 vecSrc = pOwner->EyePosition();
 
 QAngle angles = pOwner->GetLocalAngles(); // Get local angles
 AngleVectors( angles, &vecAiming );
 trace_t tr; // Create a new trace to use
 Vector vecEnd = vecSrc + (vecAiming * 42);
 UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr );
 
 if (tr.fraction < 1.0)
 {
 // Don't attach to a living creature
 if (tr.m_pEnt)
 {
 CBaseEntity *pEntity = tr.m_pEnt;
 CBaseCombatCharacter *pBCC = ToBaseCombatCharacter( pEntity );
 if (pBCC)
 {
 if (pBCC->GetHealth()<100) // If player does not have 100 health
 return true; // Return true to 
 }
 }
 return false; // Else return false
 }
 else
 {
 return false;
 }
 }else {return false;}
}
bool CWeaponHealer::HealPlayer( void ) // Heal player declaration
{
 m_bFired = 1; // Sets it to fired "shoot"
 CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() ); // Get owner of health vial
 if (!pOwner) // If Owner is no longer in server
 {
 return false; // close code
 }
 Vector vecSrc, vecAiming;
 // Take the eye position and direction
 vecSrc = pOwner->EyePosition();
 
 QAngle angles = pOwner->GetLocalAngles();
 AngleVectors( angles, &vecAiming );
 trace_t tr;
 Vector vecEnd = vecSrc + (vecAiming * 42);
 UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr );
 
 if (tr.fraction < 1.0)
 {
 // Don't attach to a living creature
 if (tr.m_pEnt)
 {
 CBaseEntity *pEntity = tr.m_pEnt;
 if (pEntity->IsPlayer())
 {
 if (pEntity->GetHealth()<pEntity->GetMaxHealth())
 {
#ifndef CLIENT_DLL
 CBasePlayer *pPlayer = ToBasePlayer(pEntity);
 CPASAttenuationFilter filter( pPlayer, "HealthVial.Touch" ); // Filters
 EmitSound( filter, pPlayer->entindex(), "HealthVial.Touch" ); // Play HealthVial.Touch sound
 pEntity->TakeHealth( 20, DMG_GENERIC ); // Damage 20 health under generic reason
#endif
 return true;
 }
 }
 }
 return false;
 }
 else
 {
 return false;
 }
}
Category:tutorials