# Difference between revisions of "Making a weapon that heal players"

## Purpose

This tutorial will teach the programmer how to create a weapon that heals players.

## Constructor

The following block of code is a 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 is to drop one health vial per shot. Comments have been added for more clarifying.

```    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 direction forward
Vector vecSrc = vecEye + vForward * 18.0f + vRight * 8.0f; // Finding source of spawning
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
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 fun

if (!pOwner) // If owner doesn't exist
{
return false; // Terminate code and return false
}

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

CHL2MP_Player *pOwner = ToHL2MPPlayer( GetOwner() ); // Get owner of health vial

if (!pOwner) // If Owner is no longer in server
{
return false; // Terminate 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
pEntity->TakeHealth( 20, DMG_GENERIC ); // Damage 20 health under generic reason
#endif
return true;
}
}
}
return false;
}
else
{
return false;
}
}
```