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; }
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); } }
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 ) ) ); } } }
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 } }
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; }
// 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); } } }
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 ); } } } }