Exemplo n.º 1
0
int CASW_Barrel_Explosive::OnTakeDamage( const CTakeDamageInfo &info )
{
	int saveFlags = m_takedamage;

	// don't be destroyed by buzzers
	if ( info.GetAttacker() && info.GetAttacker()->Classify() == CLASS_ASW_BUZZER )
	{
		return 0;
	}

	// prevent barrel exploding when knocked around
	if ( info.GetDamageType() & DMG_CRUSH )
		return 0;
	
	CASW_Marine* pMarine = NULL;
	if ( info.GetAttacker() && info.GetAttacker()->Classify() == CLASS_ASW_MARINE )
	{
		m_hAttacker = info.GetAttacker();

		pMarine = assert_cast< CASW_Marine* >( info.GetAttacker() );
		// prevent AI marines blowing up barrels as it makes the player ANGRY ANGRY
		if ( pMarine && !pMarine->IsInhabited() )
			return 0;
	}

	// don't burst open if melee'd
	if ( info.GetDamageType() & ( DMG_CLUB | DMG_SLASH ) )
	{
		m_takedamage = DAMAGE_EVENTS_ONLY;

		if( !m_bMeleeHit )
		{
			if ( pMarine )
			{
				IGameEvent * event = gameeventmanager->CreateEvent( "physics_melee" );
				if ( event )
				{
					CASW_Player *pCommander = pMarine->GetCommander();
					event->SetInt( "attacker", pCommander ? pCommander->GetUserID() : 0 );
					event->SetInt( "entindex", entindex() );
					gameeventmanager->FireEvent( event );
				}
			}
			m_bMeleeHit = true;
		}
	}

	if ( pMarine )
	{
		pMarine->HurtJunkItem(this, info);
	}

	// skip the breakable prop's complex damage handling and just hurt us
	int iResult = CBaseEntity::OnTakeDamage(info);
	m_takedamage = saveFlags;

	return iResult;
}
Exemplo n.º 2
0
void CASW_Button_Area::ActivateUnlockedButton(CASW_Marine* pMarine)
{
	// don't use the button if we're in the delay between using
	if ( m_fLastButtonUseTime != 0 && gpGlobals->curtime < m_fLastButtonUseTime + m_flWait )
		return;
	if ( !pMarine )
		return;

	if( !RequirementsMet( pMarine ) )
		return;

	if ( m_bIsDoorButton )
	{
		// if the door isn't sealed (or greater than a certain amount of damage?)
		//  then make it open
		CASW_Door* pDoor = GetDoor();
		if ( pDoor )
		{
			if (pDoor->GetSealAmount() > 0)
			{
				//Msg("Door mechanism not responding.  Maintenance Division has been notified of the problem.\n");
			}
			else
			{				
				//Msg("Toggling door...\n");
				variant_t emptyVariant;
				pDoor->AcceptInput("Toggle", pMarine, this, emptyVariant, 0);
			}
		}
	}

	// send our 'activated' output
	m_OnButtonActivated.FireOutput(pMarine, this);

	// Fire event
	IGameEvent * event = gameeventmanager->CreateEvent( "button_area_used" );
	if ( event )
	{
		CASW_Player *pPlayer = pMarine->GetCommander();

		event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );
		event->SetInt( "entindex", entindex() );
		gameeventmanager->FireEvent( event );
	}

	m_fLastButtonUseTime = gpGlobals->curtime;

	UpdateWaitingForInput();

	if ( m_bDisableAfterUse )
	{
		UTIL_Remove(this);
	}
}
Exemplo n.º 3
0
int ASW_GiveAmmo( CASW_Marine *pMarine, float flCount, const char *pszAmmoName, CBaseEntity *pAmmoEntity, bool bSuppressSound = false )
{
	int iAmmoType = GetAmmoDef()->Index(pszAmmoName);
	if ( iAmmoType == -1 )
	{
		Msg("ERROR: Attempting to give unknown ammo type (%s)\n",pszAmmoName);
		return 0;
	}

	int amount = pMarine->GiveAmmo( flCount, iAmmoType, bSuppressSound );
	if ( amount == 0 )
		amount = pMarine->GiveAmmoToAmmoBag( flCount, iAmmoType, bSuppressSound );

	if ( amount > 0 )
	{
		pMarine->TookAmmoPickup( pAmmoEntity );

		// Check the ammo type... for some doing a spilling bullet effect isn't fictionally appropriate
		if ( iAmmoType != GetAmmoDef()->Index( "ASW_F" ) && iAmmoType != GetAmmoDef()->Index( "ASW_ML" ) && iAmmoType != GetAmmoDef()->Index( "ASW_TG" ) && iAmmoType != GetAmmoDef()->Index( "ASW_GL" ) )
		{
			// Do effects
			int iAmmoCost = CASW_Ammo_Drop_Shared::GetAmmoUnitCost( iAmmoType );

			if ( iAmmoCost < 20 )
			{
				pAmmoEntity->EmitSound( "ASW_Ammobag.Pickup_sml" );
				DispatchParticleEffect( "ammo_satchel_take_sml", pAmmoEntity->GetAbsOrigin() + Vector( 0, 0, 4 ), vec3_angle );
			}
			else if ( iAmmoCost < 75 )
			{
				pAmmoEntity->EmitSound( "ASW_Ammobag.Pickup_med" );
				DispatchParticleEffect( "ammo_satchel_take_med", pAmmoEntity->GetAbsOrigin() + Vector( 0, 0, 4 ), vec3_angle );
			}
			else
			{
				pAmmoEntity->EmitSound( "ASW_Ammobag.Pickup_lrg" );
				DispatchParticleEffect( "ammo_satchel_take_lrg", pAmmoEntity->GetAbsOrigin() + Vector( 0, 0, 4 ), vec3_angle );
			}
		}

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

			gameeventmanager->FireEvent( event );
		}
	}

	return amount;
}
void ASW_DropTest_f()
{
	CASW_Player *pPlayer = ToASW_Player(UTIL_GetCommandClient());;
	
	if (pPlayer && pPlayer->GetMarine())
	{
		CASW_Marine *pMarine = pPlayer->GetMarine();
		if (pMarine->GetFlags() & FL_FROZEN)	// don't allow this if the marine is frozen
			return;
		if (pPlayer->GetFlags() & FL_FROZEN)
			return;
		int c = pMarine->WeaponCount();
		int current = -1;
		//int target = 0;
		for (int i=0;i<c;i++)
		{
			CBaseCombatWeapon *pWeapon = pMarine->GetWeapon(i);
			if (pWeapon == pMarine->GetActiveWeapon())
			{
				current = i;
				break;
			}
		}
		if (current == -1)
			return;
		
		pMarine->DropWeapon(current);

		IGameEvent * event = gameeventmanager->CreateEvent( "player_dropped_weapon" );
		if ( event )
		{
			event->SetInt( "userid", pPlayer->GetUserID() );

			gameeventmanager->FireEvent( event );
		}
	}
}
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 ) ) );
		}
	}
}
Exemplo n.º 6
0
void CASW_Alien::TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr )
{
#ifdef GAME_DLL
    m_fNoDamageDecal = false;
    if ( m_takedamage == DAMAGE_NO )
        return;
#endif

    CTakeDamageInfo subInfo = info;

#ifdef GAME_DLL
    SetLastHitGroup( ptr->hitgroup );
    m_nForceBone = ptr->physicsbone;		// save this bone for physics forces
#endif

    Assert( m_nForceBone > -255 && m_nForceBone < 256 );

    // mining laser does reduced damage
    if ( info.GetDamageType() & DMG_ENERGYBEAM )
    {
        subInfo.ScaleDamage( asw_alien_mining_laser_damage_scale.GetFloat() );
    }

    if ( subInfo.GetDamage() >= 1.0 && !(subInfo.GetDamageType() & DMG_SHOCK )
            && !( subInfo.GetDamageType() & DMG_BURN ) )
    {
#ifdef GAME_DLL
        Bleed( subInfo, ptr->endpos + m_LagCompensation.GetLagCompensationOffset(), vecDir, ptr );
        if ( ptr->hitgroup == HITGROUP_HEAD && m_iHealth - subInfo.GetDamage() > 0 )
        {
            m_fNoDamageDecal = true;
        }
#else
        Bleed( subInfo, ptr->endpos, vecDir, ptr );
        //OnHurt();
#endif
    }

    if( !info.GetInflictor() )
    {
        subInfo.SetInflictor( info.GetAttacker() );
    }


    AddMultiDamage( subInfo, this );
#ifdef GAME_DLL
#else
    CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>( subInfo.GetAttacker() );
    CASW_Player *pPlayerAttacker = NULL;

    if ( pMarine )
    {
        pPlayerAttacker = pMarine->GetCommander();
    }

    IGameEvent * event = gameeventmanager->CreateEvent( "alien_hurt" );
    if ( event )
    {
        event->SetInt( "attacker", ( pPlayerAttacker ? pPlayerAttacker->GetUserID() : 0 ) );
        event->SetInt( "entindex", entindex() );
        event->SetInt( "amount", subInfo.GetDamage() );
        gameeventmanager->FireEventClientSide( event );
    }

    UTIL_ASW_ClientFloatingDamageNumber( subInfo );
#endif
}
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
	}
}
Exemplo n.º 8
0
bool CASW_Weapon::ASWReload( int iClipSize1, int iClipSize2, int iActivity )
{
	if ( m_bInReload )	// we're already reloading!
	{
		Msg("ASWReload already reloading\n");
		Assert(false);
		return true;
	}

	CASW_Marine *pMarine = GetMarine();
	if ( !pMarine || !ASWGameRules() )
		return false;

	bool bReload = false;
	if ( m_bIsFiring )
	{
		OnStoppedFiring();
	}

	// If you don't have clips, then don't try to reload them.
	if ( UsesClipsForAmmo1() )
	{
		// need to reload primary clip?
		int primary	= MIN( iClipSize1 - m_iClip1, pMarine->GetAmmoCount( m_iPrimaryAmmoType ) );
		if ( primary != 0 )
		{
			bReload = true;
		}
		else
		{
			// check if we have an ammo bag we can take a clip from instead
			CASW_Weapon_Ammo_Bag* pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>( pMarine->GetASWWeapon( 0 ) );
			if ( !pAmmoBag )
			{
				pAmmoBag = dynamic_cast<CASW_Weapon_Ammo_Bag*>( pMarine->GetASWWeapon( 1 ) );
			}

			if ( pAmmoBag && pAmmoBag->CanGiveAmmoToWeapon( this ) )
			{
#ifdef CLIENT_DLL
				bReload = true;
#else
				pAmmoBag->GiveClipTo(pMarine, m_iPrimaryAmmoType, true);

				// now we've given a clip, check if we can reload
				primary	= MIN(iClipSize1 - m_iClip1, pMarine->GetAmmoCount(m_iPrimaryAmmoType));
				if ( primary != 0 )
				{
					bReload = true;
				}
#endif
			}
		}
	}

	if ( UsesClipsForAmmo2() )
	{
		// need to reload secondary clip?
		int secondary = MIN( iClipSize2 - m_iClip2, pMarine->GetAmmoCount( m_iSecondaryAmmoType ) );
		if ( secondary != 0 )
		{
			bReload = true;
		}
	}

	if ( !bReload )
		return false;

	m_bFastReloadSuccess = false;
	m_bFastReloadFailure = false;

#ifndef CLIENT_DLL
	if ( GetMaxClip1() > 1 )
	{
		// Fire event when a player reloads a weapon with more than a bullet per clip
		IGameEvent * event = gameeventmanager->CreateEvent( "weapon_reload" );
		if ( event )
		{		
			CASW_Player *pPlayer = NULL;
			pPlayer = pMarine->GetCommander();

			int nClipSize = GetMaxClip1();

			int nClips = pMarine->GetAmmoCount( m_iPrimaryAmmoType ) / nClipSize;
			CASW_Weapon_Ammo_Bag *pAmmoBag = dynamic_cast< CASW_Weapon_Ammo_Bag* >( pMarine->GetASWWeapon( 0 ) );
			if ( !pAmmoBag )
			{
				pAmmoBag = dynamic_cast< CASW_Weapon_Ammo_Bag* >( pMarine->GetASWWeapon( 1 ) );
			}
			if ( pAmmoBag && this != pAmmoBag )
			{
				nClips += pAmmoBag->NumClipsForWeapon( this );					
			}

			event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );
			event->SetInt( "marine", pMarine->entindex() );
			event->SetInt( "lost", m_iClip1 );
			event->SetInt( "clipsize", nClipSize );
			event->SetInt( "clipsremaining", nClips - 1 );
			event->SetInt( "clipsmax", GetAmmoDef()->MaxCarry( m_iPrimaryAmmoType, pMarine ) / nClipSize );

			gameeventmanager->FireEvent( event );
		}
	}
#endif

	m_fReloadClearFiringTime = gpGlobals->curtime + GetFireRate();

	float fReloadTime = GetReloadTime();
	float flSequenceEndTime = gpGlobals->curtime + fReloadTime;
	pMarine->SetNextAttack( flSequenceEndTime );
	m_flNextPrimaryAttack = m_flNextSecondaryAttack = flSequenceEndTime;
	//Msg("  Setting nextprimary attack time to %f from aswreload\n", m_flNextPrimaryAttack);

	m_bInReload = true;	

	// set fast reload timings
	//  assuming 2.8 base reload time
	//    ~0.29 
	RandomSeed( CBaseEntity::GetPredictionRandomSeed() & 255 );	

	float flStartFraction = random->RandomFloat( 0.29f, 0.35f );

	// set width by difficulty
	float flFastReloadWidth = 0.12f;
	switch( ASWGameRules()->GetSkillLevel() )
	{
		default:
		case 1: 
		case 2: flFastReloadWidth = random->RandomFloat( 0.10f, 0.1f ); break;		// easy/normal
		case 3: flFastReloadWidth = random->RandomFloat( 0.08f, 0.12f ); break;		// hard
		case 4: flFastReloadWidth = random->RandomFloat( 0.06f, 0.10f ); break;		// insane
		case 5: flFastReloadWidth = random->RandomFloat( 0.055f, 0.09f ); break;		// imba
	}
	// scale by marine skills
	flFastReloadWidth *= MarineSkills()->GetSkillBasedValueByMarine( pMarine, ASW_MARINE_SKILL_RELOADING, ASW_MARINE_SUBSKILL_RELOADING_FAST_WIDTH_SCALE );
	
	m_fReloadStart = gpGlobals->curtime;
	m_fFastReloadStart = gpGlobals->curtime + flStartFraction * fReloadTime;
	m_fFastReloadEnd = m_fFastReloadStart + flFastReloadWidth * fReloadTime;

	SendReloadEvents();

#ifdef GAME_DLL
	pMarine->RemoveWeaponPowerup( this );
#endif

	return true;
}
Exemplo n.º 9
0
// check player or marine commander's buttons for firing/reload/etc
void CASW_Weapon::ItemPostFrame( void )
{
	//CBasePlayer *pOwner = GetCommander();
	CASW_Marine* pOwner = GetMarine();
	if (!pOwner)
		return;

	bool bThisActive = ( pOwner && pOwner->GetActiveWeapon() == this );

	bool bAttack1, bAttack2, bReload, bOldReload, bOldAttack1;
	GetButtons(bAttack1, bAttack2, bReload, bOldReload, bOldAttack1 );

	if ( pOwner->IsHacking() )
	{
		bThisActive = bAttack1 = bAttack2 = bReload = false;
	}

	// check for clearing our weapon switching bool
	if (m_bSwitchingWeapons && gpGlobals->curtime > m_flNextPrimaryAttack)
	{
		m_bSwitchingWeapons = false;
	}

	// check for clearing our firing bool from reloading
	if (m_bInReload && gpGlobals->curtime > m_fReloadClearFiringTime)
	{
		ClearIsFiring();
	}

	if ( m_bShotDelayed && gpGlobals->curtime > m_flDelayedFire )
	{
		DelayedAttack();
	}

	if ( UsesClipsForAmmo1() )
	{
		CheckReload();
	}

	bool bFired = false;
	if ( bThisActive )
	{
		//Track the duration of the fire
		//FIXME: Check for IN_ATTACK2 as well?
		//FIXME: What if we're calling ItemBusyFrame?
		m_fFireDuration = bAttack1 ? ( m_fFireDuration + gpGlobals->frametime ) : 0.0f;

		if (bAttack2 && (m_flNextSecondaryAttack <= gpGlobals->curtime) && gpGlobals->curtime > pOwner->m_fFFGuardTime)
		{
			if ( SecondaryAttackUsesPrimaryAmmo() )
			{
				if ( !IsMeleeWeapon() &&  
					(( UsesClipsForAmmo1() && !(this->PrimaryAmmoLoaded())) || ( !UsesClipsForAmmo1() && pOwner->GetAmmoCount(m_iPrimaryAmmoType)<=0 )) )
				{
					HandleFireOnEmpty();
				}
				else
				{
					bFired = true;
					SecondaryAttack();

#ifndef CLIENT_DLL
					if ( pOwner->IsInhabited() )
					{
						IGameEvent * event = gameeventmanager->CreateEvent( "player_alt_fire" );
						if ( event )
						{
							CASW_Player *pPlayer = pOwner->GetCommander();
							event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );
							gameeventmanager->FireEvent( event );
						}
					}
#endif
				}
			}
			else if ( UsesSecondaryAmmo() &&  
				 ( ( UsesClipsForAmmo2() && m_iClip2 <= 0 ) ||
				   ( !UsesClipsForAmmo2() && pOwner->GetAmmoCount( m_iSecondaryAmmoType ) <= 0 ) ) )
			{
				if ( m_flNextEmptySoundTime < gpGlobals->curtime )
				{
					WeaponSound( EMPTY );
					m_flNextSecondaryAttack = m_flNextEmptySoundTime = gpGlobals->curtime + 0.5;
				}
			}		
			else
			{
				bFired = true;
				SecondaryAttack();

#ifndef CLIENT_DLL
				if ( pOwner->IsInhabited() )
				{
					IGameEvent * event = gameeventmanager->CreateEvent( "player_alt_fire" );
					if ( event )
					{
						CASW_Player *pPlayer = pOwner->GetCommander();
						event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );
						gameeventmanager->FireEvent( event );
					}
				}
#endif

				// Secondary ammo doesn't have a reload animation
				// this code makes secondary ammo come from nowhere!
				/*
				if ( UsesClipsForAmmo2() )
				{
					// reload clip2 if empty
					if (m_iClip2 < 1)
					{
						pOwner->RemoveAmmo( 1, m_iSecondaryAmmoType );
						m_iClip2 = m_iClip2 + 1;
					}
				}*/
			}
		}
		
		if ( !bFired && bAttack1 && (m_flNextPrimaryAttack <= gpGlobals->curtime) && gpGlobals->curtime > pOwner->m_fFFGuardTime)
		{
			// Clip empty? Or out of ammo on a no-clip weapon?
			if ( !IsMeleeWeapon() &&  
				(( UsesClipsForAmmo1() && !(this->PrimaryAmmoLoaded())) || ( !UsesClipsForAmmo1() && pOwner->GetAmmoCount(m_iPrimaryAmmoType)<=0 )) )
			{
				HandleFireOnEmpty();
			}
			else if (pOwner->GetWaterLevel() == 3 && m_bFiresUnderwater == false)
			{
				// This weapon doesn't fire underwater
				WeaponSound(EMPTY);
				m_flNextPrimaryAttack = gpGlobals->curtime + 0.2;
				return;
			}
			else
			{
				//NOTENOTE: There is a bug with this code with regards to the way machine guns catch the leading edge trigger
				//			on the player hitting the attack key.  It relies on the gun catching that case in the same frame.
				//			However, because the player can also be doing a secondary attack, the edge trigger may be missed.
				//			We really need to hold onto the edge trigger and only clear the condition when the gun has fired its
				//			first shot.  Right now that's too much of an architecture change -- jdw
				
				// If the firing button was just pressed, reset the firing time
				if ( pOwner && bAttack1 )
				{
	#ifdef CLIENT_DLL
					//Msg("[Client] setting nextprimaryattack to now %f\n", gpGlobals->curtime);
	#else
					//Msg("[Server] setting nextprimaryattack to now %f\n", gpGlobals->curtime);
	#endif
					 m_flNextPrimaryAttack = gpGlobals->curtime;
				}
				PrimaryAttack();
			}
		}
	}

	if (!bAttack1)	// clear our firing var if we don't have the attack button held down (not totally accurate since firing could continue for some time after pulling the trigger, but it's good enough for our purposes)
	{
		m_bIsFiring = false;		// NOTE: Only want to clear primary fire IsFiring bool here (i.e. don't call ClearIsFiring as that'll clear secondary fire too, in subclasses that have it)
		if ( bOldAttack1 )
		{
			OnStoppedFiring();
		}
	}

	// -----------------------
	//  Reload pressed / Clip Empty
	// -----------------------
	if ( bReload && UsesClipsForAmmo1())	
	{
		if ( m_bInReload ) 
		{
			// todo: check for a fast reload
			//Msg("Check for fast reload\n");
		}
		else
		{
			// reload when reload is pressed, or if no buttons are down and weapon is empty.
			Reload();
			m_fFireDuration = 0.0f;
		}
	}

	// -----------------------
	//  No buttons down
	// -----------------------
	if (!(bAttack1 || bAttack2 || bReload))
	{
		// no fire buttons down or reloading
		if ( !ReloadOrSwitchWeapons() && ( m_bInReload == false ) )
		{
			WeaponIdle();
		}
	}
}
void CASW_Weapon_Ammo_Satchel::DeployAmmoDrop()
{
	CASW_Player *pPlayer = GetCommander();
	if ( !pPlayer )
		return;

	if ( gpGlobals->curtime <= m_fLastAmmoDropTime + 1.0f )
	{
		return;
	}
	m_fLastAmmoDropTime = gpGlobals->curtime;
	if( m_iClip1 <= 0  )
	{
		//softcopy: TODO
		//temporary let it work; "asw_ent_create asw_weapon_ammo_satchel", to make ammo pack with pre-defined packs
		//Assert( false );     
		m_iClip1 = AMMO_SATCHEL_DEFAULT_DROP_COUNT; 	
		Assert( true );								

		return;
	}

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

#ifndef CLIENT_DLL
	Vector	vecAiming	= pPlayer->GetAutoaimVectorForMarine(pMarine, GetAutoAimAmount(), GetVerticalAdjustOnlyAutoAimAmount());	// 45 degrees = 0.707106781187
	Vector	vecSrc		= pMarine->Weapon_ShootPosition( ) + (vecAiming * 8);

	if ( !pMarine->IsInhabited() && vecSrc.DistTo( pMarine->m_vecOffhandItemSpot ) < 150.0f )
	{
		vecSrc.x = pMarine->m_vecOffhandItemSpot.x;
		vecSrc.y = pMarine->m_vecOffhandItemSpot.y;
	}

	Vector newVel = GetBulletSpread();
	if ( pMarine->GetWaterLevel() == 3 )
	{		
		CBaseEntity::EmitSound( "ASW_Ammobag.Fail" );
		return;
	}
	
	Vector vecSatchelMins = Vector(-20,-20,0);
	Vector vecSatchelMaxs = Vector(20,20,60);
	trace_t tr;

	UTIL_TraceHull( vecSrc + Vector( 0, 0, 50 ),
				vecSrc + Vector( 0, 0, -50 ),
				vecSatchelMins,
				vecSatchelMaxs,
				MASK_SOLID,
				pMarine,
				COLLISION_GROUP_NONE,
				&tr );

	if ( tr.startsolid || tr.allsolid || ( tr.DidHit() && tr.fraction <= 0 ) || tr.fraction >= 1.0f ) // if there's something in the way, or no floor, don't deploy
	{
		// Try right under the player
		vecSrc = pMarine->GetAbsOrigin();

		UTIL_TraceHull( vecSrc + Vector( 0, 0, 50 ),
			vecSrc + Vector( 0, 0, 50 ),
			vecSatchelMins,
			vecSatchelMaxs,
			MASK_SOLID,
			pMarine,
			COLLISION_GROUP_NONE,
			&tr );

		if ( tr.startsolid || tr.allsolid || ( tr.DidHit() && tr.fraction <= 0 ) || tr.fraction >= 1.0f )
		{
			// Ok, fail
			CBaseEntity::EmitSound( "ASW_Ammobag.Fail" );
			return;
		}
	}

	vecSrc.z = tr.endpos.z;

	CASW_Ammo_Drop *pAmmoDrop = (CASW_Ammo_Drop *)CreateEntityByName( "asw_ammo_drop" );	

	UTIL_TraceLine( vecSrc, vecSrc + Vector(0, 0, -60), 
		MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr);

	UTIL_SetOrigin( pAmmoDrop, tr.endpos );
	pAmmoDrop->SetDeployer( pMarine );
	DispatchSpawn( pAmmoDrop );
	pAmmoDrop->PlayDeploySound();

	// Rotate it in the marine's facing direction
	QAngle angMarine = pMarine->GetAbsAngles();
	angMarine.x = 0;
	angMarine.z = 0;
	pAmmoDrop->SetAbsAngles( angMarine );

	CBaseEntity *pHelpHelpImBeingSupressed = (CBaseEntity*) te->GetSuppressHost();
	te->SetSuppressHost( NULL );
	DispatchParticleEffect( "ammo_satchel_take_med", pAmmoDrop->GetAbsOrigin() + Vector( 0, 0, 4 ), vec3_angle );
	te->SetSuppressHost( pHelpHelpImBeingSupressed );
	pMarine->OnWeaponFired( this, 1 );

	IGameEvent * event = gameeventmanager->CreateEvent( "player_deploy_ammo" );
	if ( event )
	{
		CASW_Marine *pMarine = GetMarine();
		CASW_Player *pPlayer = NULL;

		if ( pMarine )
		{
			pPlayer = pMarine->GetCommander();
		}

		event->SetInt( "userid", ( pPlayer ? pPlayer->GetUserID() : 0 ) );

		gameeventmanager->FireEvent( event );
	}
#endif

	m_iClip1--;
	if ( m_iClip1 <= 0 )
	{
#ifndef CLIENT_DLL
		pMarine->Weapon_Detach(this);
		Kill();
#endif
		pMarine->SwitchToNextBestWeapon( NULL );
	}
}
	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);
			}
		}	
	}
Exemplo n.º 12
0
void CASW_Ammo_Drop::ActivateUseIcon( CASW_Marine* pMarine, int nHoldType )
{
    if ( nHoldType == ASW_USE_HOLD_START )
        return;

    CASW_Weapon *pWeapon = GetAmmoUseUnits( pMarine );

    if( pWeapon )
    {
        int iAmmoType = pWeapon->GetPrimaryAmmoType();
        int iGuns = pMarine->GetNumberOfWeaponsUsingAmmo( iAmmoType );
        int iMaxAmmoCount = GetAmmoDef()->MaxCarry( iAmmoType, pMarine ) * iGuns;
        int iBullets = pMarine->GetAmmoCount( iAmmoType );
        int iAmmoCost = GetAmmoUnitCost( iAmmoType );
        int iClipsToGive = CASW_Ammo_Drop_Shared::GetAmmoClipsToGive( iAmmoType );

        pMarine->SetAmmoCount( MIN( iBullets + pWeapon->GetMaxClip1() * iClipsToGive, iMaxAmmoCount ), iAmmoType );
        m_iAmmoUnitsRemaining -= iAmmoCost;

        pMarine->GetMarineSpeech()->Chatter(CHATTER_USE);

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

            gameeventmanager->FireEvent( event );
        }

        if ( m_iAmmoUnitsRemaining <= 0 )
        {
            CTakeDamageInfo info;

            BaseClass::Event_Killed( info );
        }

        CASW_Marine *pDeployer = m_hDeployer.Get();

        if ( pDeployer && pMarine != pDeployer && !m_bSuppliedAmmo )
        {
            m_bSuppliedAmmo = true;
            if ( pDeployer->GetCommander() )
            {
                pDeployer->GetCommander()->AwardAchievement( ACHIEVEMENT_ASW_AMMO_RESUPPLY );
            }
        }
    }
    else
    {
        if ( pMarine->IsInhabited() )
        {
            CASW_Player *pCommander = pMarine->GetCommander();
            if ( pCommander )
            {
                CSingleUserRecipientFilter filter( pCommander );
                EmitSound( filter, pMarine->entindex(), "ASW_Ammobag.Fail", NULL, 0.0f );
            }
        }
    }
}