void CASW_Weapon_Medkit::SelfHeal()
{
	CASW_Marine *pMarine = GetMarine();

	if (pMarine)		// firing from a marine
	{
		if (pMarine->GetHealth() >= pMarine->GetMaxHealth())		// already on full health
			return;

		if (pMarine->GetHealth() <= 0)		// aleady dead!
			return;

		if (pMarine->m_bSlowHeal)			// already healing
			return;

		if (pMarine->GetFlags() & FL_FROZEN)	// don't allow this if the marine is frozen
			return;

		// MUST call sound before removing a round from the clip of a CMachineGun
		WeaponSound(SINGLE);

		// sets the animation on the weapon model iteself
		SendWeaponAnim( GetPrimaryAttackActivity() );

		// sets the animation on the marine holding this weapon
		//pMarine->SetAnimation( PLAYER_ATTACK1 );
#ifndef CLIENT_DLL
		bool bMedic = (pMarine->GetMarineProfile() && pMarine->GetMarineProfile()->CanUseFirstAid());
		// put a slow heal onto the marine, play a particle effect
		if (!pMarine->m_bSlowHeal && pMarine->GetHealth() < pMarine->GetMaxHealth())
		{
			pMarine->AddSlowHeal( GetHealAmount(), 1, pMarine, this );

			// Fire event
			IGameEvent * event = gameeventmanager->CreateEvent( "player_heal" );
			if ( event )
			{
				CASW_Player *pPlayer = GetCommander();
				event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );
				event->SetInt( "entindex", pMarine->entindex() );
				gameeventmanager->FireEvent( event );
			}

			if ( ASWGameRules()->GetInfoHeal() )
			{
				ASWGameRules()->GetInfoHeal()->OnMarineHealed( pMarine, pMarine, this );

			}
			pMarine->OnWeaponFired( this, 1 );
		}
		
		if (pMarine->IsInfested() && bMedic)
		{
			float fCure = GetInfestationCureAmount();
			// cure infestation
			if (fCure < 100)
				pMarine->CureInfestation(pMarine, fCure);
		}
#endif
		// decrement ammo
		m_iClip1 -= 1;

#ifndef CLIENT_DLL
		DestroyIfEmpty( false );
#endif
	}
}
void CASW_HealGrenade_Projectile::DoAOE( CBaseEntity *pEntity )
{
	CASW_Marine *pTargetMarine = static_cast< CASW_Marine* >( pEntity );
	if ( !pTargetMarine )
		return;

	CASW_Marine *pMarine = dynamic_cast< CASW_Marine* >( GetOwnerEntity() ); // Carful! This might be null

	float flBaseHealAmount = m_flHealPerSecond * ( gpGlobals->curtime - m_flLastDoAOE );

	// At full health... multiplier is 1 + 0. At empty health multiplier is 1 + 3.0.
	float fHealthPercent = pTargetMarine->IsInfested() ? 0.0f : static_cast< float >( pTargetMarine->GetHealth() ) / pTargetMarine->GetMaxHealth();
	float flLowHealthMultiplier = ( 1.0f + 3.0f * ( 1.0f - fHealthPercent ) );
	float flHealAmount = MIN( flBaseHealAmount * flLowHealthMultiplier, pTargetMarine->GetMaxHealth() - ( pTargetMarine->GetHealth() + pTargetMarine->m_iSlowHealAmount ) );

	float flHealUsed = flHealAmount;

	if ( flHealAmount > 0.0f )
	{
		bool bHealedBefore = false;

		for ( int i = 0; i < m_hHealedEntities.Count(); ++i )
		{
			if ( m_hHealedEntities[ i ].Get() == pEntity )
			{
				bHealedBefore = true;
				break;
			}
		}

		if ( !bHealedBefore )
		{
			// Add it to the list of things we've healed at least once
			m_hHealedEntities.AddToTail( pEntity );

			// Fire event
			IGameEvent * event = gameeventmanager->CreateEvent( "player_heal" );
			if ( event )
			{
				CASW_Player *pPlayer = NULL;
				if ( pMarine )
				{
					pPlayer = pMarine->GetCommander();
				}
				event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );
				event->SetInt( "entindex", pTargetMarine->entindex() );
				gameeventmanager->FireEvent( event );
			}

			if ( pMarine )
			{
				CASW_Marine_Resource *pMR = pMarine->GetMarineResource();
				if ( pMR && !pMR->m_bAwardedHealBeaconAchievement && m_hHealedEntities.Count() >= 4 && pMarine->IsInhabited() && pMarine->GetCommander() )
				{
					pMR->m_bAwardedHealBeaconAchievement = true;
					pMarine->GetCommander()->AwardAchievement( ACHIEVEMENT_ASW_GROUP_HEAL );
				}
			}
		}

		pTargetMarine->AddSlowHeal( flHealAmount, 1, pMarine, this );

		float flHalfHealTotal = m_flHealAmountTotal / 2.0f;

		if ( m_flHealAmountLeft > flHalfHealTotal && ( m_flHealAmountLeft - flHealAmount ) <= flHalfHealTotal )
		{
			ASWFailAdvice()->OnHealGrenadeUsedWell();
		}

		m_flHealAmountLeft -= flHealUsed;

		if ( m_flHealAmountLeft <= 0.0f )
		{
			m_flTimeBurnOut = gpGlobals->curtime;
		}
	
		if ( ASWGameRules()->GetInfoHeal() && pMarine )
		{
			ASWGameRules()->GetInfoHeal()->OnMarineHealed( pMarine, pTargetMarine, NULL );
		}
	}

	if ( pTargetMarine->IsInfested() )
	{
		float fCurePercent = GetInfestationCureAmount();

		// cure infestation
		if ( fCurePercent > 0.0f )
		{
			// Cure infestation at 1/20th normal rate per second (the full 20 seconds or amount used does the full cure)
			pTargetMarine->CureInfestation( pMarine, 1.0f - ( ( 1.0f - fCurePercent ) * ( flHealUsed / m_flHealAmountTotal ) * ( gpGlobals->curtime - m_flLastDoAOE ) ) );
		}
	}
}
	void CASW_Weapon_Medical_Satchel::GiveHealthTo( CASW_Marine *pTarget )
	{
		if ( !pTarget || m_iClip1 <= 0 )
			return;

		if ( pTarget->GetHealth() >= pTarget->GetMaxHealth() )		// already on full health
			return;

		if ( pTarget->GetHealth() <= 0 )		// target is dead!
			return;

		if ( pTarget->m_bSlowHeal )			// already healing
			return;

		CASW_Marine *pMarine = GetMarine();
		if ( !pMarine )
			return;

		if ( pMarine->GetFlags() & FL_FROZEN )	// don't allow this if the marine is frozen
			return;

		// check if we're close enough
		Vector diff = pMarine->GetAbsOrigin() - pTarget->GetAbsOrigin();
		if ( diff.Length() > MAX_HEAL_DISTANCE_SERVER )	// add a bit of leeway to account for lag
			return;

		bool bMedic = pMarine && pMarine->GetMarineProfile() && pMarine->GetMarineProfile()->CanUseFirstAid();

		//pMarine->DoAnimationEvent(PLAYERANIMEVENT_HEAL);
		WeaponSound(SINGLE);

		int iHealAmount = GetHealAmount();
		pTarget->AddSlowHeal(iHealAmount, 1, pMarine, this );

		// Fire event
		IGameEvent * event = gameeventmanager->CreateEvent( "player_heal" );
		if ( event )
		{
			CASW_Player *pPlayer = GetCommander();
			event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );
			event->SetInt( "entindex", pTarget->entindex() );
			gameeventmanager->FireEvent( event );
		}

		ASWFailAdvice()->OnMarineHealed();

		if ( ASWGameRules()->GetInfoHeal() )
		{
			ASWGameRules()->GetInfoHeal()->OnMarineHealed( GetMarine(), pTarget, this );
		}

		m_iClip1 -= 1;

		if ( bMedic )
		{
			if (pTarget->IsInfested())
			{
				float fCurePercent = GetInfestationCureAmount();
				// cure infestation
				if ( fCurePercent > 0 && fCurePercent < 100 )
				{
					pTarget->CureInfestation(pMarine, fCurePercent);
				}
			}

			bool bSkipChatter = pTarget->IsInfested();
			int iTotalMeds = GetTotalMeds();
			if ( m_iClip1 <= 0 )
			{
				if ( iTotalMeds <= 0 )
				{
					ASWFailAdvice()->OnMedSatchelEmpty();

					pMarine->GetMarineSpeech()->Chatter( CHATTER_MEDS_NONE );
					bSkipChatter = true;
				}
				
				DestroyIfEmpty( false, true );	// out of medical charges, remove this item
			}
			else if ( iTotalMeds <= 1 )
			{
				if ( pMarine->GetMarineSpeech()->Chatter( CHATTER_MEDS_LOW ) )
				{
					bSkipChatter = true;
				}
			}
			if ( !bSkipChatter )
			{
				// try and do a special chatter?
				bool bSkipChatter = false;
				if (pMarine->GetMarineSpeech()->AllowCalmConversations(CONV_HEALING_CRASH))
				{
					if (!pTarget->m_bDoneWoundedRebuke && pTarget->GetMarineResource() && pTarget->GetMarineResource()->m_bTakenWoundDamage)
					{
						// marine has been wounded and this is our first heal after the fact - good chance of the medic saying something
						if (random->RandomFloat() < asw_marine_special_heal_chatter_chance.GetFloat() * 3)
						{
							if (CASW_MarineSpeech::StartConversation(CONV_SERIOUS_INJURY, pMarine, pTarget))
							{
								bSkipChatter = true;
								pTarget->m_bDoneWoundedRebuke = true;
							}
						}
					}

					// if we didn't complaint about a serious injury, check for doing a different kind of conv
					float fRand = random->RandomFloat();
					if (!bSkipChatter && fRand < asw_marine_special_heal_chatter_chance.GetFloat())
					{
						if (pTarget->GetMarineProfile() && pTarget->GetMarineProfile()->m_VoiceType == ASW_VOICE_CRASH
							&& pMarine->GetMarineProfile() && pMarine->GetMarineProfile()->m_VoiceType == ASW_VOICE_BASTILLE)	// bastille healing crash
						{
							if (random->RandomFloat() < 0.5f)
							{
								if (CASW_MarineSpeech::StartConversation(CONV_HEALING_CRASH, pMarine, pTarget))
									bSkipChatter = true;						
							}
							else
							{
								if (CASW_MarineSpeech::StartConversation(CONV_MEDIC_COMPLAIN, pMarine, pTarget))
									bSkipChatter = true;
							}
						}
						else
						{
							if (CASW_MarineSpeech::StartConversation(CONV_MEDIC_COMPLAIN, pMarine, pTarget))
								bSkipChatter = true;
						}
					}
				}
				if (!bSkipChatter)
					pMarine->GetMarineSpeech()->Chatter(CHATTER_HEALING);
			}
		}	
	}