void CHudRoundTimer::Paint() { // Update the time. C_CSGameRules *pRules = CSGameRules(); if ( pRules ) { SetDisplayValue( (int)ceil( CSGameRules()->TimeRemaining() ) ); SetShouldDisplayValue( true ); BaseClass::Paint(); } }
void CC4::Drop( const Vector &vecVelocity ) { #if !defined( CLIENT_DLL ) m_bStartedArming = false; // stop arming sequence if ( !CSGameRules()->m_bBombPlanted ) // its not dropped if its planted { // tell the bots about the dropped bomb TheCSBots()->SetLooseBomb( this ); CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(GetOwnerEntity()); Assert( pPlayer ); if ( pPlayer ) { IGameEvent * event = gameeventmanager->CreateEvent("bomb_dropped" ); if ( event ) { event->SetInt( "userid", pPlayer->GetUserID() ); event->SetInt( "priority", 6 ); gameeventmanager->FireEvent( event ); } } } #endif BaseClass::Drop( vecVelocity ); }
void CWeaponHL2MPBase::Materialize( void ) { if ( IsEffectActive( EF_NODRAW ) ) { // changing from invisible state to visible. EmitSound( "AlyxEmp.Charge" ); RemoveEffects( EF_NODRAW ); DoMuzzleFlash(); } if ( HasSpawnFlags( SF_NORESPAWN ) == false ) { VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false ); SetMoveType( MOVETYPE_VPHYSICS ); #ifndef CSTRIKE_DLL CSGameRules()->AddLevelDesignerPlacedObject( this ); #endif } if ( HasSpawnFlags( SF_NORESPAWN ) == false ) { if ( GetOriginalSpawnOrigin() == vec3_origin ) { m_vOriginalSpawnOrigin = GetAbsOrigin(); m_vOriginalSpawnAngles = GetAbsAngles(); } } SetPickupTouch(); SetThink (NULL); }
void CMapInfo::CheckMapInfo() { bool bCTCantBuy, bTCantBuy; switch (m_iBuyingStatus) { case BUYING_EVERYONE: bCTCantBuy = false; bTCantBuy = false; ALERT(at_console, "EVERYONE CAN BUY!\n"); break; case BUYING_ONLY_CTS: bCTCantBuy = false; bTCantBuy = true; ALERT(at_console, "Only CT's can buy!!\n"); break; case BUYING_ONLY_TERRORISTS: bCTCantBuy = true; bTCantBuy = false; ALERT(at_console, "Only T's can buy!!\n"); break; case BUYING_NO_ONE: bCTCantBuy = true; bTCantBuy = true; ALERT(at_console, "No one can buy!!\n"); break; default: bCTCantBuy = false; bTCantBuy = false; break; } CSGameRules()->m_flBombRadius = m_flBombRadius; CSGameRules()->m_bCTCantBuy = bCTCantBuy; CSGameRules()->m_bTCantBuy = bTCantBuy; }
void CC4::__MAKE_VHOOK(Use)(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) { if (m_pPlayer != NULL) { return; } CBasePlayer *pPlayer = UTIL_PlayerByIndex(1); if (pPlayer != NULL) { edict_t *m_pentOldCurBombTarget = pPlayer->m_pentCurBombTarget; pPlayer->m_pentCurBombTarget = NULL; if (pev->speed != 0 && CSGameRules() != NULL) { CSGameRules()->m_iC4Timer = int(pev->speed); } EMIT_SOUND(edict(), CHAN_WEAPON, "weapons/c4_plant.wav", VOL_NORM, ATTN_NORM); CGrenade::ShootSatchelCharge(m_pPlayer->pev, m_pPlayer->pev->origin, Vector(0, 0, 0)); CGrenade *pC4 = NULL; while ((pC4 = (CGrenade *)UTIL_FindEntityByClassname(pC4, "grenade")) != NULL) { if (pC4->m_bIsC4 && pC4->m_flNextFreq == gpGlobals->time) { pC4->pev->target = pev->target; pC4->pev->noise1 = pev->noise1; break; } } pPlayer->m_pentCurBombTarget = m_pentOldCurBombTarget; SUB_Remove(); } }
void CC4::PrimaryAttack() { bool PlaceBomb = false; CCSPlayer *pPlayer = GetPlayerOwner(); int onGround = FBitSet( pPlayer->GetFlags(), FL_ONGROUND ); if( m_bStartedArming == false ) { if( pPlayer->m_bInBombZone && onGround ) { m_bStartedArming = true; m_fArmedTime = gpGlobals->curtime + WEAPON_C4_ARM_TIME; m_bBombPlacedAnimation = false; //SendWeaponAnim( C4_ARM, UseDecrement() ? 1: 0 ); #if !defined( CLIENT_DLL ) // freeze the player in place while planting pPlayer->SetMaxSpeed( 1 ); // player "arming bomb" animation pPlayer->SetAnimation( PLAYER_ATTACK1 ); pPlayer->SetProgressBarTime( 3 ); #endif } else { if ( !pPlayer->m_bInBombZone ) { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_At_Bomb_Spot"); } else { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground"); } m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; return; } } else { if ( !onGround || !pPlayer->m_bInBombZone ) { if( !pPlayer->m_bInBombZone ) { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Arming_Cancelled" ); } else { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground" ); } m_flNextPrimaryAttack = gpGlobals->curtime + 1.5; m_bStartedArming = false; #if !defined( CLIENT_DLL ) // release the player from being frozen, we've somehow left the bomb zone pPlayer->ResetMaxSpeed(); pPlayer->SetProgressBarTime( 0 ); //pPlayer->SetAnimation( PLAYER_HOLDBOMB ); #endif /* if(m_bBombPlacedAnimation == true) //this means the placement animation is canceled { SendWeaponAnim( C4_DRAW, UseDecrement() ? 1: 0 ); } else { SendWeaponAnim( C4_IDLE1, UseDecrement() ? 1: 0 ); } */ return; } else { if( gpGlobals->curtime >= m_fArmedTime ) //the c4 is ready to be armed { //check to make sure the player is still in the bomb target area PlaceBomb = true; } else if( ( gpGlobals->curtime >= (m_fArmedTime - 0.75) ) && ( !m_bBombPlacedAnimation ) ) { //call the c4 Placement animation m_bBombPlacedAnimation = true; //SendWeaponAnim( C4_DROP, UseDecrement() ? 1: 0 ); #if !defined( CLIENT_DLL ) // player "place" animation //pPlayer->SetAnimation( PLAYER_HOLDBOMB ); #endif } } } if ( PlaceBomb && m_bStartedArming ) { m_bStartedArming = false; m_fArmedTime = 0; if( pPlayer->m_bInBombZone ) { #if !defined( CLIENT_DLL ) //Broadcast("BOMBPL"); CPlantedC4::ShootSatchelCharge( pPlayer, pPlayer->GetAbsOrigin(), QAngle(0,0,0) ); // send director message, that something important happened here /* MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR ); WRITE_BYTE ( 9 ); // command length in bytes WRITE_BYTE ( DRC_CMD_EVENT ); // bomb placed WRITE_SHORT( ENTINDEX(pPlayer->edict()) ); WRITE_SHORT( 0 ); WRITE_LONG( 11 | DRC_FLAG_FACEPLAYER ); // eventflags (priority and flags) MESSAGE_END(); */ // tell the Ts the bomb has been planted (on radar) CTeam *pTeam = GetGlobalTeam( TEAM_TERRORIST ); for ( int iPlayer=0; iPlayer < pTeam->GetNumPlayers(); iPlayer++ ) { CBasePlayer *pTempPlayer = pTeam->GetPlayer( iPlayer ); if ( pTempPlayer->m_lifeState != LIFE_DEAD ) { /* MESSAGE_BEGIN( MSG_ONE, gmsgBombDrop, NULL, pTempPlayer->pev ); WRITE_COORD( pBomb->pev->origin.x ); WRITE_COORD( pBomb->pev->origin.y ); WRITE_COORD( pBomb->pev->origin.z ); WRITE_BYTE( 1 ); // bomb was planted MESSAGE_END(); */ } } UTIL_ClientPrintAll( HUD_PRINTCENTER,"#Bomb_Planted" ); pPlayer->SetProgressBarTime( 0 ); // tell bots the bomb has been planted //g_pBotControl->OnEvent( EVENT_BOMB_PLANTED, pPlayer ); CSGameRules()->m_bBombDropped = false; // Play the plant sound. CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "c4.plant" ); // release the player from being frozen pPlayer->ResetMaxSpeed(); // Remove the C4 icon from the HUD //pPlayer->SetBombIcon(); // No more c4! pPlayer->Weapon_Drop( this, NULL, NULL ); UTIL_Remove( this ); #endif return; } else { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Activated_At_Bomb_Spot" ); #if !defined( CLIENT_DLL ) //pPlayer->SetAnimation( PLAYER_HOLDBOMB ); // release the player from being frozen pPlayer->ResetMaxSpeed(); #endif m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; return; } } m_flNextPrimaryAttack = gpGlobals->curtime + 0.3; m_flTimeWeaponIdle = gpGlobals->curtime + random->RandomFloat ( 10, 15 ); }
// Regular explosions void CPlantedC4::Explode2( trace_t *pTrace, int bitsDamageType ) { float flRndSound;// sound randomizer CCSGameRules *mp = CSGameRules(); SetSolidFlags( FSOLID_NOT_SOLID ); m_takedamage = DAMAGE_NO; // Shake the ground!! //UTIL_ScreenShake( pTrace->endpos, 25.0, 150.0, 1.0, 3000 ); mp->m_bTargetBombed = true; // This variable is checked by the function CheckWinConditions() to see if the bomb has just detonated. m_bJustBlew = true; // Check to see if the round is over after the bomb went off... mp->CheckWinConditions(); // Pull out of the wall a bit if ( pTrace->fraction != 1.0 ) { SetAbsOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) ); } // Fireball sprite and sound!! { Vector fireballPos = GetAbsOrigin(); CPVSFilter filter( fireballPos ); te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 ); } { Vector fireballPos = GetAbsOrigin() + Vector( random->RandomFloat( -512, 512 ), random->RandomFloat( -512, 512 ), random->RandomFloat( -10, 10 ) ); CPVSFilter filter( fireballPos ); te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 ); } { Vector fireballPos = GetAbsOrigin() + Vector( random->RandomFloat( -512, 512 ), random->RandomFloat( -512, 512 ), random->RandomFloat( -10, 10 ) ); CPVSFilter filter( fireballPos ); te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 ); } // Emit a sound effect of the explosion that travels across the entire level! CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "c4.explode" ); //EMIT_SOUND(ENT(pev), CHAN_WEAPON, "weapons/c4_explode1.wav", 1.0, 0.25); SetOwnerEntity( NULL ); // can't traceline attack owner if this is set float flBombRadius = 100; if ( g_pMapInfo ) flBombRadius = g_pMapInfo->m_flBombRadius; CSGameRules()->RadiusDamage( CTakeDamageInfo( this, GetOwnerEntity(), 1000, bitsDamageType ), GetAbsOrigin(), flBombRadius, CLASS_NONE ); // send director message, that something important happed here /* MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR ); WRITE_BYTE ( 9 ); // command length in bytes WRITE_BYTE ( DRC_CMD_EVENT ); // bomb explode WRITE_SHORT( ENTINDEX(this->edict()) ); // index number of primary entity WRITE_SHORT( 0 ); // index number of secondary entity WRITE_LONG( 15 | DRC_FLAG_FINAL ); // eventflags (priority and flags) MESSAGE_END(); */ UTIL_DecalTrace( pTrace, "Scorch" ); flRndSound = random->RandomFloat( 0 , 1 ); CPASAttenuationFilter debrisFilter( this ); EmitSound( debrisFilter, entindex(), "c4.debris" ); m_fEffects |= EF_NODRAW; //SetThink( &CPlantedC4::Smoke2 ); //SetNextThink( gpGlobals->curtime + 0.85 ); }
void CPlantedC4::C4Think() { if (!IsInWorld()) { UTIL_Remove( this ); return; } SetNextThink( gpGlobals->curtime + 0.12 ); if ( gpGlobals->curtime >= m_flNextFreq ) { m_flNextFreq = gpGlobals->curtime + m_flNextFreqInterval; m_flNextFreqInterval *= 0.9; m_iCurWave = clamp( m_iCurWave+1, 0, 5 ); } if ( gpGlobals->curtime >= m_flNextBeep ) { m_flNextBeep = gpGlobals->curtime + 1.4; // Play a beep sound. char soundName[64]; Q_snprintf( soundName, sizeof( soundName ), "c4.beep%d", m_iCurWave ); CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), soundName ); // let the bots hear the bomb beeping //g_pBotControl->OnEvent( EVENT_BOMB_BEEP, this ); } if(gpGlobals->curtime >= m_flNextBlink)//added by SupraFiend to improve Bomb visibility { m_flNextBlink = gpGlobals->curtime + BLINK_INTERVAL; Vector vPos = GetAbsOrigin(); vPos.z += 5; CPVSFilter filter( GetAbsOrigin() ); te->GlowSprite( filter, 0, &vPos, g_sModelIndexC4Glow, 1, 0.5, 255 ); } // IF the timer has expired ! blow this bomb up! if (m_flC4Blow <= gpGlobals->curtime) { // let the bots hear the bomb exploding //g_pBotControl->OnEvent( EVENT_BOMB_EXPLODED ); // Tell the bomb target brush to trigger its targets //MIKETODO: use entity IO? /* if ( m_pentCurBombTarget ) { CBaseEntity* pBombTarget = CBaseEntity::Instance( m_pentCurBombTarget ); if ( pBombTarget ) pBombTarget->Use( CBaseEntity::Instance( pev->owner ), this, USE_TOGGLE, 0 ); } */ // give the defuser credit for defusing the bomb CBasePlayer *pBombOwner = dynamic_cast< CBasePlayer* >( GetOwnerEntity() ); if ( pBombOwner ) { pBombOwner->IncrementFragCount( 3 ); } CSGameRules()->m_bBombDropped = false; if (GetWaterLevel() == 0) SetThink ( &CPlantedC4::Detonate2 ); else UTIL_Remove (this); // Get rid of this thing if it's underwater.. } //if the defusing process has started if ((m_bStartDefuse == true) && (m_pBombDefuser != NULL)) { //if the defusing process has not ended yet if ( m_flDefuseCountDown > gpGlobals->curtime) { int iOnGround = FBitSet( m_pBombDefuser->GetFlags(), FL_ONGROUND ); //if the bomb defuser has stopped defusing the bomb if( m_fNextDefuse < gpGlobals->curtime || !iOnGround ) { if ( !iOnGround ) ClientPrint( m_pBombDefuser, HUD_PRINTCENTER, "#C4_Defuse_Must_Be_On_Ground"); // release the player from being frozen m_pBombDefuser->ResetMaxSpeed(); m_pBombDefuser->m_bIsDefusing = false; //cancel the progress bar m_pBombDefuser->SetProgressBarTime( 0 ); m_pBombDefuser = NULL; m_bStartDefuse = false; m_flDefuseCountDown = 0; // tell the bots someone has aborted defusing //g_pBotControl->OnEvent( EVENT_BOMB_DEFUSE_ABORTED ); } return; } //if the defuse process has ended, kill the c4 else if ( !m_pBombDefuser->IsDead() ) { // tell the bots the bomb is defused //g_pBotControl->OnEvent( EVENT_BOMB_DEFUSED ); //MIKETODO: spectator /* // Broadcast to the entire server Broadcast( "BOMBDEF" ); // send director message, that something important happened here MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR ); WRITE_BYTE ( 9 ); WRITE_BYTE ( DRC_CMD_EVENT ); // bomb defuse WRITE_SHORT( ENTINDEX( m_pBombDefuser->edict() )); // index number of secondary entity WRITE_SHORT( 0 ); // index number of secondary entity WRITE_LONG( 15 | DRC_FLAG_DRAMATIC | DRC_FLAG_FINAL | DRC_FLAG_FACEPLAYER ); // eventflags (priority and flags) MESSAGE_END(); */ CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "c4.disarmed" ); UTIL_Remove(this); // The bomb has just been disarmed.. Check to see if the round should end now m_bJustBlew = true; // release the player from being frozen m_pBombDefuser->ResetMaxSpeed(); m_pBombDefuser->m_bIsDefusing = false; CSGameRules()->m_bBombDefused = true; CSGameRules()->CheckWinConditions(); // give the defuser credit for defusing the bomb m_pBombDefuser->IncrementFragCount( 3 ); CSGameRules()->m_bBombDropped = false; // Clear their progress bar. m_pBombDefuser->SetProgressBarTime( 0 ); m_pBombDefuser = NULL; m_bStartDefuse = false; return; } //if it gets here then the previouse defuser has taken off or been killed // release the player from being frozen m_pBombDefuser->ResetMaxSpeed(); m_pBombDefuser->m_bIsDefusing = false; m_bStartDefuse = false; m_pBombDefuser = NULL; // tell the bots someone has aborted defusing //g_pBotControl->OnEvent( EVENT_BOMB_DEFUSE_ABORTED ); } }
void CC4::PrimaryAttack() { bool PlaceBomb = false; CCSPlayer *pPlayer = GetPlayerOwner(); if ( !pPlayer ) return; int onGround = FBitSet( pPlayer->GetFlags(), FL_ONGROUND ); CBaseEntity *groundEntity = (onGround) ? pPlayer->GetGroundEntity() : NULL; if ( groundEntity ) { // Don't let us stand on players, breakables, or pushaway physics objects to plant if ( groundEntity->IsPlayer() || IsPushableEntity( groundEntity ) || #ifndef CLIENT_DLL IsBreakableEntity( groundEntity ) || #endif // !CLIENT_DLL IsPushAwayEntity( groundEntity ) ) { onGround = false; } } if( m_bStartedArming == false && m_bBombPlanted == false ) { if( pPlayer->m_bInBombZone && onGround ) { m_bStartedArming = true; m_fArmedTime = gpGlobals->curtime + WEAPON_C4_ARM_TIME; m_bBombPlacedAnimation = false; #if !defined( CLIENT_DLL ) // init the beep flags int i; for( i=0;i<NUM_BEEPS;i++ ) m_bPlayedArmingBeeps[i] = false; // freeze the player in place while planting pPlayer->SetMaxSpeed( 1 ); // player "arming bomb" animation pPlayer->SetAnimation( PLAYER_ATTACK1 ); pPlayer->SetNextAttack( gpGlobals->curtime ); IGameEvent * event = gameeventmanager->CreateEvent( "bomb_beginplant" ); if( event ) { event->SetInt("userid", pPlayer->GetUserID() ); event->SetInt("site", pPlayer->m_iBombSiteIndex ); event->SetInt( "priority", 8 ); gameeventmanager->FireEvent( event ); } #endif SendWeaponAnim( ACT_VM_PRIMARYATTACK ); FX_PlantBomb( pPlayer->entindex(), pPlayer->Weapon_ShootPosition() ); } else { if ( !pPlayer->m_bInBombZone ) { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_At_Bomb_Spot"); } else { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground"); } m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; return; } } else { if ( !onGround || !pPlayer->m_bInBombZone ) { if( !pPlayer->m_bInBombZone ) { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Arming_Cancelled" ); } else { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground" ); } m_flNextPrimaryAttack = gpGlobals->curtime + 1.5; m_bStartedArming = false; #if !defined( CLIENT_DLL ) // release the player from being frozen, we've somehow left the bomb zone pPlayer->ResetMaxSpeed(); pPlayer->SetProgressBarTime( 0 ); //pPlayer->SetAnimation( PLAYER_HOLDBOMB ); IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortplant" ); if( event ) { event->SetInt("userid", pPlayer->GetUserID() ); event->SetInt("site", pPlayer->m_iBombSiteIndex ); event->SetInt( "priority", 8 ); gameeventmanager->FireEvent( event ); } #endif if(m_bBombPlacedAnimation == true) //this means the placement animation is canceled { SendWeaponAnim( ACT_VM_DRAW ); } else { SendWeaponAnim( ACT_VM_IDLE ); } return; } else { #ifndef CLIENT_DLL PlayArmingBeeps(); #endif if( gpGlobals->curtime >= m_fArmedTime ) //the c4 is ready to be armed { //check to make sure the player is still in the bomb target area PlaceBomb = true; } else if( ( gpGlobals->curtime >= (m_fArmedTime - 0.75) ) && ( !m_bBombPlacedAnimation ) ) { //call the c4 Placement animation m_bBombPlacedAnimation = true; SendWeaponAnim( ACT_VM_SECONDARYATTACK ); #if !defined( CLIENT_DLL ) // player "place" animation //pPlayer->SetAnimation( PLAYER_HOLDBOMB ); #endif } } } if ( PlaceBomb && m_bStartedArming ) { m_bStartedArming = false; m_fArmedTime = 0; if( pPlayer->m_bInBombZone ) { #if !defined( CLIENT_DLL ) CPlantedC4 *pC4 = CPlantedC4::ShootSatchelCharge( pPlayer, pPlayer->GetAbsOrigin(), pPlayer->GetAbsAngles() ); if ( pC4 ) { pC4->SetBombSiteIndex( pPlayer->m_iBombSiteIndex ); trace_t tr; UTIL_TraceEntity( pC4, GetAbsOrigin(), GetAbsOrigin() + Vector(0,0,-200), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); pC4->SetAbsOrigin( tr.endpos ); CBombTarget *pBombTarget = (CBombTarget*)UTIL_EntityByIndex( pPlayer->m_iBombSiteIndex ); if ( pBombTarget ) { CBaseEntity *pAttachPoint = gEntList.FindEntityByName( NULL, pBombTarget->GetBombMountTarget() ); if ( pAttachPoint ) { pC4->SetAbsOrigin( pAttachPoint->GetAbsOrigin() ); pC4->SetAbsAngles( pAttachPoint->GetAbsAngles() ); pC4->SetParent( pAttachPoint ); } variant_t emptyVariant; pBombTarget->AcceptInput( "BombPlanted", pC4, pC4, emptyVariant, 0 ); } } IGameEvent * event = gameeventmanager->CreateEvent( "bomb_planted" ); if( event ) { event->SetInt("userid", pPlayer->GetUserID() ); event->SetInt("site", pPlayer->m_iBombSiteIndex ); event->SetInt("posx", pPlayer->GetAbsOrigin().x ); event->SetInt("posy", pPlayer->GetAbsOrigin().y ); event->SetInt( "priority", 8 ); gameeventmanager->FireEvent( event ); } // Fire a beep event also so the bots have a chance to hear the bomb event = gameeventmanager->CreateEvent( "bomb_beep" ); if ( event ) { event->SetInt( "entindex", entindex() ); gameeventmanager->FireEvent( event ); } pPlayer->SetProgressBarTime( 0 ); CSGameRules()->m_bBombDropped = false; CSGameRules()->m_bBombPlanted = true; // Play the plant sound. Vector plantPosition = pPlayer->GetAbsOrigin() + Vector( 0, 0, 5 ); CPASAttenuationFilter filter( plantPosition ); EmitSound( filter, entindex(), "c4.plant" ); // release the player from being frozen pPlayer->ResetMaxSpeed(); // No more c4! pPlayer->Weapon_Drop( this, NULL, NULL ); UTIL_Remove( this ); #endif //don't allow the planting to start over again next frame. m_bBombPlanted = true; return; } else { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Activated_At_Bomb_Spot" ); #if !defined( CLIENT_DLL ) //pPlayer->SetAnimation( PLAYER_HOLDBOMB ); // release the player from being frozen pPlayer->ResetMaxSpeed(); IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortplant" ); if( event ) { event->SetInt("userid", pPlayer->GetUserID() ); event->SetInt("site", pPlayer->m_iBombSiteIndex ); event->SetInt( "priority", 8 ); gameeventmanager->FireEvent( event ); } #endif m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; return; } } m_flNextPrimaryAttack = gpGlobals->curtime + 0.3; SetWeaponIdleTime( gpGlobals->curtime + SharedRandomFloat("C4IdleTime", 10, 15 ) ); }
void CC4::__MAKE_VHOOK(PrimaryAttack)() { if (m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) return; int inBombZone = (m_pPlayer->m_signals.GetState() & SIGNAL_BOMB) == SIGNAL_BOMB; int onGround = (m_pPlayer->pev->flags & FL_ONGROUND) == FL_ONGROUND; bool bPlaceBomb = (onGround && inBombZone); if (!m_bStartedArming) { if (!inBombZone) { ClientPrint(m_pPlayer->pev, HUD_PRINTCENTER, "#C4_Plant_At_Bomb_Spot"); m_flNextPrimaryAttack = GetNextAttackDelay(1.0); return; } if (!onGround) { ClientPrint(m_pPlayer->pev, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground"); m_flNextPrimaryAttack = GetNextAttackDelay(1.0); return; } m_bStartedArming = true; m_bBombPlacedAnimation = false; m_fArmedTime = gpGlobals->time + C4_ARMING_ON_TIME; // player "arming bomb" animation SendWeaponAnim(C4_ARM, UseDecrement() != FALSE); // freeze the player in place while planting SET_CLIENT_MAXSPEED(m_pPlayer->edict(), 1.0); m_pPlayer->SetAnimation(PLAYER_ATTACK1); m_pPlayer->SetProgressBarTime(C4_ARMING_ON_TIME); } else { if (bPlaceBomb) { CBaseEntity *pEntity = NULL; CBasePlayer *pTempPlayer = NULL; if (m_fArmedTime <= gpGlobals->time) { if (m_bStartedArming) { m_bStartedArming = false; m_fArmedTime = 0; Broadcast("BOMBPL"); m_pPlayer->m_bHasC4 = false; if (pev->speed != 0 && CSGameRules() != NULL) { CSGameRules()->m_iC4Timer = int(pev->speed); } CGrenade *pBomb = CGrenade::ShootSatchelCharge(m_pPlayer->pev, m_pPlayer->pev->origin, Vector(0, 0, 0)); MESSAGE_BEGIN(MSG_SPEC, SVC_DIRECTOR); WRITE_BYTE(9); WRITE_BYTE(DRC_CMD_EVENT); WRITE_SHORT(m_pPlayer->entindex()); WRITE_SHORT(0); WRITE_LONG(DRC_FLAG_FACEPLAYER | 11); MESSAGE_END(); MESSAGE_BEGIN(MSG_ALL, gmsgBombDrop); WRITE_COORD(pBomb->pev->origin.x); WRITE_COORD(pBomb->pev->origin.y); WRITE_COORD(pBomb->pev->origin.z); WRITE_BYTE(1); MESSAGE_END(); UTIL_ClientPrintAll(HUD_PRINTCENTER, "#Bomb_Planted"); if (TheBots != NULL) { TheBots->OnEvent(EVENT_BOMB_PLANTED, m_pPlayer, pBomb); } if (TheCareerTasks != NULL && CSGameRules()->IsCareer() && !m_pPlayer->IsBot()) { TheCareerTasks->HandleEvent(EVENT_BOMB_PLANTED, m_pPlayer); } UTIL_LogPrintf("\"%s<%i><%s><TERRORIST>\" triggered \"Planted_The_Bomb\"\n", STRING(m_pPlayer->pev->netname), GETPLAYERUSERID(m_pPlayer->edict()), GETPLAYERAUTHID(m_pPlayer->edict())); g_pGameRules->m_bBombDropped = FALSE; // Play the plant sound. EMIT_SOUND(edict(), CHAN_WEAPON, "weapons/c4_plant.wav", VOL_NORM, ATTN_NORM); // hide the backpack in Terrorist's models. m_pPlayer->pev->body = 0; // release the player from being frozen m_pPlayer->ResetMaxSpeed(); // No more c4! m_pPlayer->SetBombIcon(FALSE); if (--m_pPlayer->m_rgAmmo[m_iPrimaryAmmoType] <= 0) { RetireWeapon(); return; } } } else { if (m_fArmedTime - 0.75f <= gpGlobals->time && !m_bBombPlacedAnimation) { // call the c4 Placement animation m_bBombPlacedAnimation = true; SendWeaponAnim(C4_DROP, UseDecrement() != FALSE); // player "place" animation m_pPlayer->SetAnimation(PLAYER_HOLDBOMB); } } } else { if (inBombZone) ClientPrint(m_pPlayer->pev, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground"); else ClientPrint(m_pPlayer->pev, HUD_PRINTCENTER, "#C4_Arming_Cancelled"); m_bStartedArming = false; m_flNextPrimaryAttack = GetNextAttackDelay(1.5); // release the player from being frozen, we've somehow left the bomb zone m_pPlayer->ResetMaxSpeed(); m_pPlayer->SetProgressBarTime(0); m_pPlayer->SetAnimation(PLAYER_HOLDBOMB); // this means the placement animation is canceled if (m_bBombPlacedAnimation) SendWeaponAnim(C4_DRAW, UseDecrement() != FALSE); else SendWeaponAnim(C4_IDLE1, UseDecrement() != FALSE); return; } } m_flNextPrimaryAttack = GetNextAttackDelay(0.3); m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + RANDOM_FLOAT(10, 15); }
/** * Buy weapons, armor, etc. */ void BuyState::OnEnter( CCSBot *me ) { m_retries = 0; m_prefRetries = 0; m_prefIndex = 0; const char *cheatWeaponString = bot_loadout.GetString(); if ( cheatWeaponString && *cheatWeaponString ) { m_doneBuying = false; // we're going to be given weapons - ignore the eco limit } else { // check if we are saving money for the next round if (me->m_iAccount < cv_bot_eco_limit.GetFloat()) { me->PrintIfWatched( "Saving money for next round.\n" ); m_doneBuying = true; } else { m_doneBuying = false; } } m_isInitialDelay = true; // this will force us to stop holding live grenade me->EquipBestWeapon( MUST_EQUIP ); m_buyDefuseKit = false; m_buyShield = false; if (me->GetTeamNumber() == TEAM_CT) { if (TheCSBots()->GetScenario() == CCSBotManager::SCENARIO_DEFUSE_BOMB) { // CT's sometimes buy defuse kits in the bomb scenario (except in career mode, where the player should defuse) if (CSGameRules()->IsCareer() == false) { const float buyDefuseKitChance = 100.0f * (me->GetProfile()->GetSkill() + 0.2f); if (RandomFloat( 0.0f, 100.0f ) < buyDefuseKitChance) { m_buyDefuseKit = true; } } } // determine if we want a tactical shield if (!me->HasPrimaryWeapon() && TheCSBots()->AllowTacticalShield()) { if (me->m_iAccount > 2500) { if (me->m_iAccount < 4000) m_buyShield = (RandomFloat( 0, 100.0f ) < 33.3f) ? true : false; else m_buyShield = (RandomFloat( 0, 100.0f ) < 10.0f) ? true : false; } } } if (TheCSBots()->AllowGrenades()) { m_buyGrenade = (RandomFloat( 0.0f, 100.0f ) < 33.3f) ? true : false; } else { m_buyGrenade = false; } m_buyPistol = false; if (TheCSBots()->AllowPistols()) { // check if we have a pistol if (me->Weapon_GetSlot( WEAPON_SLOT_PISTOL )) { // if we have our default pistol, think about buying a different one if (HasDefaultPistol( me )) { // if everything other than pistols is disallowed, buy a pistol if (TheCSBots()->AllowShotguns() == false && TheCSBots()->AllowSubMachineGuns() == false && TheCSBots()->AllowRifles() == false && TheCSBots()->AllowMachineGuns() == false && TheCSBots()->AllowTacticalShield() == false && TheCSBots()->AllowSnipers() == false) { m_buyPistol = (RandomFloat( 0, 100 ) < 75.0f); } else if (me->m_iAccount < 1000) { // if we're low on cash, buy a pistol m_buyPistol = (RandomFloat( 0, 100 ) < 75.0f); } else { m_buyPistol = (RandomFloat( 0, 100 ) < 33.3f); } } } else { // we dont have a pistol - buy one m_buyPistol = true; } } }
void BuyState::__MAKE_VHOOK(OnUpdate)(CCSBot *me) { // wait for a Navigation Mesh if (!TheNavAreaList.size()) return; // apparently we cant buy things in the first few seconds, so wait a bit if (m_isInitialDelay) { const float waitToBuyTime = 2.0f; // 0.25f; if (gpGlobals->time - me->GetStateTimestamp() < waitToBuyTime) return; m_isInitialDelay = false; } // if we're done buying and still in the freeze period, wait if (m_doneBuying) { if (CSGameRules()->IsMultiplayer() && CSGameRules()->IsFreezePeriod()) { #ifdef REGAMEDLL_FIXES // make sure we're locked and loaded me->EquipBestWeapon(MUST_EQUIP); me->Reload(); me->ResetStuckMonitor(); #endif return; } me->Idle(); #ifdef REGAMEDLL_FIXES return; #endif } // is the bot spawned outside of a buy zone? if (!(me->m_signals.GetState() & SIGNAL_BUY)) { m_doneBuying = true; UTIL_DPrintf("%s bot spawned outside of a buy zone (%d, %d, %d)\n", (me->m_iTeam == CT) ? "CT" : "Terrorist", int(me->pev->origin.x), int(me->pev->origin.y), int(me->pev->origin.z)); return; } // try to buy some weapons const float buyInterval = 0.2f; // 0.02f if (gpGlobals->time - me->GetStateTimestamp() > buyInterval) { me->m_stateTimestamp = gpGlobals->time; bool isPreferredAllDisallowed = true; // try to buy our preferred weapons first if (m_prefIndex < me->GetProfile()->GetWeaponPreferenceCount()) { // need to retry because sometimes first buy fails?? const int maxPrefRetries = 2; if (m_prefRetries >= maxPrefRetries) { // try to buy next preferred weapon ++m_prefIndex; m_prefRetries = 0; return; } int weaponPreference = me->GetProfile()->GetWeaponPreference(m_prefIndex); // don't buy it again if we still have one from last round CBasePlayerWeapon *weapon = me->GetActiveWeapon(); if (weapon != NULL && weapon->m_iId == weaponPreference) { // done with buying preferred weapon m_prefIndex = 9999; return; } if (me->HasShield() && weaponPreference == WEAPON_SHIELDGUN) { // done with buying preferred weapon m_prefIndex = 9999; return; } const char *buyAlias = NULL; if (weaponPreference == WEAPON_SHIELDGUN) { if (TheCSBots()->AllowTacticalShield()) buyAlias = "shield"; } else { buyAlias = WeaponIDToAlias(weaponPreference); WeaponType type = GetWeaponType(buyAlias); switch (type) { case PISTOL: if (!TheCSBots()->AllowPistols()) buyAlias = NULL; break; case SHOTGUN: if (!TheCSBots()->AllowShotguns()) buyAlias = NULL; break; case SUB_MACHINE_GUN: if (!TheCSBots()->AllowSubMachineGuns()) buyAlias = NULL; break; case RIFLE: if (!TheCSBots()->AllowRifles()) buyAlias = NULL; break; case MACHINE_GUN: if (!TheCSBots()->AllowMachineGuns()) buyAlias = NULL; break; case SNIPER_RIFLE: if (!TheCSBots()->AllowSnipers()) buyAlias = NULL; break; } } if (buyAlias) { me->ClientCommand(buyAlias); me->PrintIfWatched("Tried to buy preferred weapon %s.\n", buyAlias); isPreferredAllDisallowed = false; } ++m_prefRetries; // bail out so we dont waste money on other equipment // unless everything we prefer has been disallowed, then buy at random if (isPreferredAllDisallowed == false) return; } // if we have no preferred primary weapon (or everything we want is disallowed), buy at random if (!me->m_bHasPrimary && (isPreferredAllDisallowed || !me->GetProfile()->HasPrimaryPreference())) { if (m_buyShield) { // buy a shield me->ClientCommand("shield"); me->PrintIfWatched("Tried to buy a shield.\n"); } else { // build list of allowable weapons to buy BuyInfo *masterPrimary = (me->m_iTeam == TERRORIST) ? primaryWeaponBuyInfoT : primaryWeaponBuyInfoCT; BuyInfo *stockPrimary[ PRIMARY_WEAPON_BUY_COUNT ]; int stockPrimaryCount = 0; // dont choose sniper rifles as often const float sniperRifleChance = 50.0f; bool wantSniper = (RANDOM_FLOAT(0, 100) < sniperRifleChance) ? true : false; for (int i = 0; i < PRIMARY_WEAPON_BUY_COUNT; ++i) { if ((masterPrimary[i].type == SHOTGUN && TheCSBots()->AllowShotguns()) || (masterPrimary[i].type == SUB_MACHINE_GUN && TheCSBots()->AllowSubMachineGuns()) || (masterPrimary[i].type == RIFLE && TheCSBots()->AllowRifles()) || (masterPrimary[i].type == SNIPER_RIFLE && TheCSBots()->AllowSnipers() && wantSniper) || (masterPrimary[i].type == MACHINE_GUN && TheCSBots()->AllowMachineGuns())) { stockPrimary[ stockPrimaryCount++ ] = &masterPrimary[i]; } } if (stockPrimaryCount) { // buy primary weapon if we don't have one int which; // on hard difficulty levels, bots try to buy preferred weapons on the first pass if (m_retries == 0 && TheCSBots()->GetDifficultyLevel() >= BOT_HARD) { // count up available preferred weapons int prefCount = 0; for (which = 0; which < stockPrimaryCount; ++which) { if (stockPrimary[which]->preferred) ++prefCount; } if (prefCount) { int whichPref = RANDOM_LONG(0, prefCount - 1); for (which = 0; which < stockPrimaryCount; ++which) { if (stockPrimary[which]->preferred && whichPref-- == 0) break; } } else { // no preferred weapons available, just pick randomly which = RANDOM_LONG(0, stockPrimaryCount - 1); } } else { which = RANDOM_LONG(0, stockPrimaryCount - 1); } me->ClientCommand(stockPrimary[ which ]->buyAlias); me->PrintIfWatched("Tried to buy %s.\n", stockPrimary[ which ]->buyAlias); } } } // If we now have a weapon, or have tried for too long, we're done if (me->m_bHasPrimary || m_retries++ > 5) { // primary ammo if (me->m_bHasPrimary) { me->ClientCommand("primammo"); } // buy armor last, to make sure we bought a weapon first me->ClientCommand("vesthelm"); me->ClientCommand("vest"); // pistols - if we have no preferred pistol, buy at random if (TheCSBots()->AllowPistols() && !me->GetProfile()->HasPistolPreference()) { if (m_buyPistol) { int which = RANDOM_LONG(0, SECONDARY_WEAPON_BUY_COUNT - 1); if (me->m_iTeam == TERRORIST) me->ClientCommand(secondaryWeaponBuyInfoT[ which ].buyAlias); else me->ClientCommand(secondaryWeaponBuyInfoCT[ which ].buyAlias); // only buy one pistol m_buyPistol = false; } me->ClientCommand("secammo"); } // buy a grenade if we wish, and we don't already have one if (m_buyGrenade && !me->HasGrenade()) { if (UTIL_IsTeamAllBots(me->m_iTeam)) { // only allow Flashbangs if everyone on the team is a bot (dont want to blind our friendly humans) float rnd = RANDOM_FLOAT(0, 100); if (rnd < 10.0f) { // smoke grenade me->ClientCommand("sgren"); } else if (rnd < 35.0f) { // flashbang me->ClientCommand("flash"); } else { // he grenade me->ClientCommand("hegren"); } } else { if (RANDOM_FLOAT(0, 100) < 10.0f) { // smoke grenade me->ClientCommand("sgren"); } else { // he grenade me->ClientCommand("hegren"); } } } if (m_buyDefuseKit) { me->ClientCommand("defuser"); } m_doneBuying = true; } } }
// Buy weapons, armor, etc. void BuyState::__MAKE_VHOOK(OnEnter)(CCSBot *me) { m_retries = 0; m_prefRetries = 0; m_prefIndex = 0; m_doneBuying = false; m_isInitialDelay = true; // this will force us to stop holding live grenade me->EquipBestWeapon(); m_buyDefuseKit = false; m_buyShield = false; if (me->m_iTeam == CT) { if (TheCSBots()->GetScenario() == CCSBotManager::SCENARIO_DEFUSE_BOMB) { // CT's sometimes buy defuse kits in the bomb scenario (except in career mode, where the player should defuse) if (!CSGameRules()->IsCareer()) { const float buyDefuseKitChance = 50.0f; // 100.0f * (me->GetProfile()->GetSkill() + 0.2f); if (RANDOM_FLOAT(0.0f, 100.0f) < buyDefuseKitChance) { m_buyDefuseKit = true; } } } // determine if we want a tactical shield if (!me->m_bHasPrimary && TheCSBots()->AllowTacticalShield()) { if (me->m_iAccount > 2500) { if (me->m_iAccount < 4000) m_buyShield = (RANDOM_FLOAT(0, 100.0f) < 33.3f) ? true : false; else m_buyShield = (RANDOM_FLOAT(0, 100.0f) < 10.0f) ? true : false; } } } if (TheCSBots()->AllowGrenades()) { m_buyGrenade = (RANDOM_FLOAT(0.0f, 100.0f) < 33.3f) ? true : false; } else { m_buyGrenade = false; } m_buyPistol = false; if (TheCSBots()->AllowPistols()) { CBasePlayerWeapon *pistol = static_cast<CBasePlayerWeapon *>(me->m_rgpPlayerItems[ PISTOL_SLOT ]); // check if we have a pistol if (pistol != NULL) { // if we have our default pistol, think about buying a different one if (HasDefaultPistol(me)) { // if everything other than pistols is disallowed, buy a pistol if (TheCSBots()->AllowShotguns() == false && TheCSBots()->AllowSubMachineGuns() == false && TheCSBots()->AllowRifles() == false && TheCSBots()->AllowMachineGuns() == false && TheCSBots()->AllowTacticalShield() == false && TheCSBots()->AllowSnipers() == false) { m_buyPistol = (RANDOM_FLOAT(0, 100) < 75.0f); } else if (me->m_iAccount < 1000) { // if we're low on cash, buy a pistol m_buyPistol = (RANDOM_FLOAT(0, 100) < 75.0f); } else { m_buyPistol = (RANDOM_FLOAT(0, 100) < 33.3f); } } } else { // we dont have a pistol - buy one m_buyPistol = true; } } }
void CWeaponCSBase::ItemPostFrame() { CCSPlayer *pPlayer = GetPlayerOwner(); //GOOSEMAN : Return zoom level back to previous zoom level before we fired a shot. This is used only for the AWP. if ( (m_flNextPrimaryAttack <= gpGlobals->curtime) && (pPlayer->m_bResumeZoom == TRUE) ) { #ifndef CLIENT_DLL pPlayer->SetFOV( pPlayer->m_iLastZoom ); if ( pPlayer->GetFOV() == pPlayer->m_iLastZoom ) { // return the fade level in zoom. pPlayer->m_bResumeZoom = false; } #endif } //GOOSEMAN : Delayed shell ejection code.. if ( (pPlayer->m_flEjectBrass != 0.0) && (pPlayer->m_flEjectBrass <= gpGlobals->curtime ) ) { pPlayer->m_flEjectBrass = 0.0; EjectBrassLate(); } if ((m_bInReload) && (pPlayer->m_flNextAttack <= gpGlobals->curtime)) { // complete the reload. int j = min( GetMaxClip1() - m_iClip1, pPlayer->GetAmmoCount( m_iPrimaryAmmoType ) ); // Add them to the clip m_iClip1 += j; pPlayer->RemoveAmmo( j, m_iPrimaryAmmoType ); m_bInReload = false; } if ((pPlayer->m_nButtons & IN_ATTACK2) && (m_flNextSecondaryAttack <= gpGlobals->curtime)) { if ( m_iClip2 != -1 && !pPlayer->GetAmmoCount( GetSecondaryAmmoType() ) ) { m_bFireOnEmpty = TRUE; } SecondaryAttack(); pPlayer->m_nButtons &= ~IN_ATTACK2; } else if ((pPlayer->m_nButtons & IN_ATTACK) && (m_flNextPrimaryAttack <= gpGlobals->curtime )) { if ( (m_iClip1 == 0/* && pszAmmo1()*/) || (GetMaxClip1() == -1 && !pPlayer->GetAmmoCount( GetPrimaryAmmoType() ) ) ) { m_bFireOnEmpty = TRUE; } // Can't shoot during the freeze period // Ken: Always allow firing in single player //--- if ( !CSGameRules()->IsFreezePeriod() && !pPlayer->m_bIsDefusing && pPlayer->State_Get() == STATE_JOINED ) { PrimaryAttack(); } //--- } else if ( pPlayer->m_nButtons & IN_RELOAD && GetMaxClip1() != WEAPON_NOCLIP && !m_bInReload && m_flNextPrimaryAttack < gpGlobals->curtime) { // reload when reload is pressed, or if no buttons are down and weapon is empty. //MIKETODO: add code for shields... //if ( !FBitSet( m_iWeaponState, WPNSTATE_SHIELD_DRAWN ) ) Reload(); } else if ( !(pPlayer->m_nButtons & (IN_ATTACK|IN_ATTACK2) ) ) { // no fire buttons down // The following code prevents the player from tapping the firebutton repeatedly // to simulate full auto and retaining the single shot accuracy of single fire if (m_bDelayFire == TRUE) { m_bDelayFire = FALSE; if (m_iShotsFired > 15) m_iShotsFired = 15; m_flDecreaseShotsFired = gpGlobals->curtime + 0.4; } m_bFireOnEmpty = FALSE; // if it's a pistol then set the shots fired to 0 after the player releases a button if ( IsPistol() ) { m_iShotsFired = 0; } else { if ( (m_iShotsFired > 0) && (m_flDecreaseShotsFired < gpGlobals->curtime) ) { m_flDecreaseShotsFired = gpGlobals->curtime + 0.0225; m_iShotsFired--; } } #ifndef CLIENT_DLL if ( !IsUseable() && m_flNextPrimaryAttack < gpGlobals->curtime ) { // Intentionally blank -- used to switch weapons here } else #endif { // weapon is useable. Reload if empty and weapon has waited as long as it has to after firing if ( m_iClip1 == 0 && !(GetFlags() & ITEM_FLAG_NOAUTORELOAD) && m_flNextPrimaryAttack < gpGlobals->curtime ) { Reload(); return; } } WeaponIdle( ); return; } }
void GameDLL_EndRound_f() { CSGameRules()->EndRoundMessage("#Round_Draw", ROUND_END_DRAW); Broadcast("rounddraw"); CSGameRules()->TerminateRound(5, WINSTATUS_DRAW); }
//-------------------------------------------------------------------------------------------------------------- void BuyState::OnUpdate( CCSBot *me ) { char cmdBuffer[256]; // wait for a Navigation Mesh if (!TheNavMesh->IsLoaded()) return; // apparently we cant buy things in the first few seconds, so wait a bit if (m_isInitialDelay) { const float waitToBuyTime = 0.25f; if (gpGlobals->curtime - me->GetStateTimestamp() < waitToBuyTime) return; m_isInitialDelay = false; } // if we're done buying and still in the freeze period, wait if (m_doneBuying) { if (CSGameRules()->IsMultiplayer() && CSGameRules()->IsFreezePeriod()) { // make sure we're locked and loaded me->EquipBestWeapon( MUST_EQUIP ); me->Reload(); me->ResetStuckMonitor(); return; } me->Idle(); return; } // If we're supposed to buy a specific weapon for debugging, do so and then bail const char *cheatWeaponString = bot_loadout.GetString(); if ( cheatWeaponString && *cheatWeaponString ) { CUtlVector<char*, CUtlMemory<char*> > loadout; Q_SplitString( cheatWeaponString, " ", loadout ); for ( int i=0; i<loadout.Count(); ++i ) { const char *item = loadout[i]; if ( FStrEq( item, "vest" ) ) { me->GiveNamedItem( "item_kevlar" ); } else if ( FStrEq( item, "vesthelm" ) ) { me->GiveNamedItem( "item_assaultsuit" ); } else if ( FStrEq( item, "defuser" ) ) { if ( me->GetTeamNumber() == TEAM_CT ) { me->GiveDefuser(); } } else if ( FStrEq( item, "nvgs" ) ) { me->m_bHasNightVision = true; } else if ( FStrEq( item, "primammo" ) ) { me->AttemptToBuyAmmo( 0 ); } else if ( FStrEq( item, "secammo" ) ) { me->AttemptToBuyAmmo( 1 ); } else { me->GiveWeapon( item ); } } m_doneBuying = true; return; } if (!me->IsInBuyZone()) { m_doneBuying = true; CONSOLE_ECHO( "%s bot spawned outside of a buy zone (%d, %d, %d)\n", (me->GetTeamNumber() == TEAM_CT) ? "CT" : "Terrorist", (int)me->GetAbsOrigin().x, (int)me->GetAbsOrigin().y, (int)me->GetAbsOrigin().z ); return; } // try to buy some weapons const float buyInterval = 0.02f; if (gpGlobals->curtime - me->GetStateTimestamp() > buyInterval) { me->m_stateTimestamp = gpGlobals->curtime; bool isPreferredAllDisallowed = true; // try to buy our preferred weapons first if (m_prefIndex < me->GetProfile()->GetWeaponPreferenceCount() && bot_randombuy.GetBool() == false ) { // need to retry because sometimes first buy fails?? const int maxPrefRetries = 2; if (m_prefRetries >= maxPrefRetries) { // try to buy next preferred weapon ++m_prefIndex; m_prefRetries = 0; return; } int weaponPreference = me->GetProfile()->GetWeaponPreference( m_prefIndex ); // don't buy it again if we still have one from last round char weaponPreferenceName[32]; Q_snprintf( weaponPreferenceName, sizeof(weaponPreferenceName), "weapon_%s", me->GetProfile()->GetWeaponPreferenceAsString( m_prefIndex ) ); if( me->Weapon_OwnsThisType(weaponPreferenceName) )//Prefs and buyalias use the short version, this uses the long { // done with buying preferred weapon m_prefIndex = 9999; return; } if (me->HasShield() && weaponPreference == WEAPON_SHIELDGUN) { // done with buying preferred weapon m_prefIndex = 9999; return; } const char *buyAlias = NULL; if (weaponPreference == WEAPON_SHIELDGUN) { if (TheCSBots()->AllowTacticalShield()) buyAlias = "shield"; } else { buyAlias = WeaponIDToAlias( weaponPreference ); WeaponType type = GetWeaponType( buyAlias ); switch( type ) { case PISTOL: if (!TheCSBots()->AllowPistols()) buyAlias = NULL; break; case SHOTGUN: if (!TheCSBots()->AllowShotguns()) buyAlias = NULL; break; case SUB_MACHINE_GUN: if (!TheCSBots()->AllowSubMachineGuns()) buyAlias = NULL; break; case RIFLE: if (!TheCSBots()->AllowRifles()) buyAlias = NULL; break; case MACHINE_GUN: if (!TheCSBots()->AllowMachineGuns()) buyAlias = NULL; break; case SNIPER_RIFLE: if (!TheCSBots()->AllowSnipers()) buyAlias = NULL; break; } } if (buyAlias) { Q_snprintf( cmdBuffer, 256, "buy %s\n", buyAlias ); CCommand args; args.Tokenize( cmdBuffer ); me->ClientCommand( args ); me->PrintIfWatched( "Tried to buy preferred weapon %s.\n", buyAlias ); isPreferredAllDisallowed = false; } ++m_prefRetries; // bail out so we dont waste money on other equipment // unless everything we prefer has been disallowed, then buy at random if (isPreferredAllDisallowed == false) return; } // if we have no preferred primary weapon (or everything we want is disallowed), buy at random if (!me->HasPrimaryWeapon() && (isPreferredAllDisallowed || !me->GetProfile()->HasPrimaryPreference())) { if (m_buyShield) { // buy a shield CCommand args; args.Tokenize( "buy shield" ); me->ClientCommand( args ); me->PrintIfWatched( "Tried to buy a shield.\n" ); } else { // build list of allowable weapons to buy BuyInfo *masterPrimary = (me->GetTeamNumber() == TEAM_TERRORIST) ? primaryWeaponBuyInfoT : primaryWeaponBuyInfoCT; BuyInfo *stockPrimary[ PRIMARY_WEAPON_BUY_COUNT ]; int stockPrimaryCount = 0; // dont choose sniper rifles as often const float sniperRifleChance = 50.0f; bool wantSniper = (RandomFloat( 0, 100 ) < sniperRifleChance) ? true : false; if ( bot_randombuy.GetBool() ) { wantSniper = true; } for( int i=0; i<PRIMARY_WEAPON_BUY_COUNT; ++i ) { if ((masterPrimary[i].type == SHOTGUN && TheCSBots()->AllowShotguns()) || (masterPrimary[i].type == SUB_MACHINE_GUN && TheCSBots()->AllowSubMachineGuns()) || (masterPrimary[i].type == RIFLE && TheCSBots()->AllowRifles()) || (masterPrimary[i].type == SNIPER_RIFLE && TheCSBots()->AllowSnipers() && wantSniper) || (masterPrimary[i].type == MACHINE_GUN && TheCSBots()->AllowMachineGuns())) { stockPrimary[ stockPrimaryCount++ ] = &masterPrimary[i]; } } if (stockPrimaryCount) { // buy primary weapon if we don't have one int which; // on hard difficulty levels, bots try to buy preferred weapons on the first pass if (m_retries == 0 && TheCSBots()->GetDifficultyLevel() >= BOT_HARD && bot_randombuy.GetBool() == false ) { // count up available preferred weapons int prefCount = 0; for( which=0; which<stockPrimaryCount; ++which ) if (stockPrimary[which]->preferred) ++prefCount; if (prefCount) { int whichPref = RandomInt( 0, prefCount-1 ); for( which=0; which<stockPrimaryCount; ++which ) if (stockPrimary[which]->preferred && whichPref-- == 0) break; } else { // no preferred weapons available, just pick randomly which = RandomInt( 0, stockPrimaryCount-1 ); } } else { which = RandomInt( 0, stockPrimaryCount-1 ); } Q_snprintf( cmdBuffer, 256, "buy %s\n", stockPrimary[ which ]->buyAlias ); CCommand args; args.Tokenize( cmdBuffer ); me->ClientCommand( args ); me->PrintIfWatched( "Tried to buy %s.\n", stockPrimary[ which ]->buyAlias ); } } } // // If we now have a weapon, or have tried for too long, we're done // if (me->HasPrimaryWeapon() || m_retries++ > 5) { // primary ammo CCommand args; if (me->HasPrimaryWeapon()) { args.Tokenize( "buy primammo" ); me->ClientCommand( args ); } // buy armor last, to make sure we bought a weapon first args.Tokenize( "buy vesthelm" ); me->ClientCommand( args ); args.Tokenize( "buy vest" ); me->ClientCommand( args ); // pistols - if we have no preferred pistol, buy at random if (TheCSBots()->AllowPistols() && !me->GetProfile()->HasPistolPreference()) { if (m_buyPistol) { int which = RandomInt( 0, SECONDARY_WEAPON_BUY_COUNT-1 ); const char *what = NULL; if (me->GetTeamNumber() == TEAM_TERRORIST) what = secondaryWeaponBuyInfoT[ which ].buyAlias; else what = secondaryWeaponBuyInfoCT[ which ].buyAlias; Q_snprintf( cmdBuffer, 256, "buy %s\n", what ); args.Tokenize( cmdBuffer ); me->ClientCommand( args ); // only buy one pistol m_buyPistol = false; } // make sure we have enough pistol ammo args.Tokenize( "buy secammo" ); me->ClientCommand( args ); } // buy a grenade if we wish, and we don't already have one if (m_buyGrenade && !me->HasGrenade()) { if (UTIL_IsTeamAllBots( me->GetTeamNumber() )) { // only allow Flashbangs if everyone on the team is a bot (dont want to blind our friendly humans) float rnd = RandomFloat( 0, 100 ); if (rnd < 10) { args.Tokenize( "buy smokegrenade" ); me->ClientCommand( args ); // smoke grenade } else if (rnd < 35) { args.Tokenize( "buy flashbang" ); me->ClientCommand( args ); // flashbang } else { args.Tokenize( "buy hegrenade" ); me->ClientCommand( args ); // he grenade } } else { if (RandomFloat( 0, 100 ) < 10) { args.Tokenize( "buy smokegrenade" ); // smoke grenade me->ClientCommand( args ); } else { args.Tokenize( "buy hegrenade" ); // he grenade me->ClientCommand( args ); } } } if (m_buyDefuseKit) { args.Tokenize( "buy defuser" ); me->ClientCommand( args ); } m_doneBuying = true; } } }
void CPlantedC4::C4Think() { if (!IsInWorld()) { UTIL_Remove( this ); return; } //Bomb is dead, don't think anymore if( !m_bBombTicking ) { SetThink( NULL ); return; } SetNextThink( gpGlobals->curtime + 0.12 ); #ifndef CLIENT_DLL // let the bots hear the bomb beeping // BOTPORT: Emit beep events at same time as client effects IGameEvent * event = gameeventmanager->CreateEvent( "bomb_beep" ); if( event ) { event->SetInt( "entindex", entindex() ); gameeventmanager->FireEvent( event ); } #endif // IF the timer has expired ! blow this bomb up! if (m_flC4Blow <= gpGlobals->curtime) { // give the defuser credit for defusing the bomb CBasePlayer *pBombOwner = dynamic_cast< CBasePlayer* >( GetOwnerEntity() ); if ( pBombOwner ) { pBombOwner->IncrementFragCount( 3 ); } CSGameRules()->m_bBombDropped = false; trace_t tr; Vector vecSpot = GetAbsOrigin(); vecSpot[2] += 8; UTIL_TraceLine( vecSpot, vecSpot + Vector ( 0, 0, -40 ), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); Explode( &tr, DMG_BLAST ); CSGameRules()->m_bBombPlanted = false; IGameEvent * event = gameeventmanager->CreateEvent( "bomb_exploded" ); if( event ) { event->SetInt( "userid", pBombOwner?pBombOwner->GetUserID():-1 ); event->SetInt( "site", m_iBombSiteIndex ); event->SetInt( "priority", 9 ); gameeventmanager->FireEvent( event ); } } //if the defusing process has started if ((m_bStartDefuse == true) && (m_pBombDefuser != NULL)) { //if the defusing process has not ended yet if ( m_flDefuseCountDown > gpGlobals->curtime) { int iOnGround = FBitSet( m_pBombDefuser->GetFlags(), FL_ONGROUND ); //if the bomb defuser has stopped defusing the bomb if( m_flNextDefuse < gpGlobals->curtime || !iOnGround ) { if ( !iOnGround && m_pBombDefuser->IsAlive() ) ClientPrint( m_pBombDefuser, HUD_PRINTCENTER, "#C4_Defuse_Must_Be_On_Ground"); // release the player from being frozen m_pBombDefuser->ResetMaxSpeed(); m_pBombDefuser->m_bIsDefusing = false; #ifndef CLIENT_DLL // tell the bots someone has aborted defusing IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortdefuse" ); if( event ) { event->SetInt("userid", m_pBombDefuser->GetUserID() ); event->SetInt( "priority", 6 ); gameeventmanager->FireEvent( event ); } #endif //cancel the progress bar m_pBombDefuser->SetProgressBarTime( 0 ); m_pBombDefuser = NULL; m_bStartDefuse = false; m_flDefuseCountDown = 0; m_flDefuseLength = 0; //force it to show completely defused } return; } //if the defuse process has ended, kill the c4 else if ( !m_pBombDefuser->IsDead() ) { IGameEvent * event = gameeventmanager->CreateEvent( "bomb_defused" ); if( event ) { event->SetInt("userid", m_pBombDefuser->GetUserID() ); event->SetInt("site", m_iBombSiteIndex ); event->SetInt( "priority", 9 ); gameeventmanager->FireEvent( event ); } Vector soundPosition = m_pBombDefuser->GetAbsOrigin() + Vector( 0, 0, 5 ); CPASAttenuationFilter filter( soundPosition ); EmitSound( filter, entindex(), "c4.disarmfinish" ); // The bomb has just been disarmed.. Check to see if the round should end now m_bBombTicking = false; // release the player from being frozen m_pBombDefuser->ResetMaxSpeed(); m_pBombDefuser->m_bIsDefusing = false; CSGameRules()->m_bBombDefused = true; CSGameRules()->CheckWinConditions(); // give the defuser credit for defusing the bomb m_pBombDefuser->IncrementFragCount( 3 ); CSGameRules()->m_bBombDropped = false; CSGameRules()->m_bBombPlanted = false; // Clear their progress bar. m_pBombDefuser->SetProgressBarTime( 0 ); m_pBombDefuser = NULL; m_bStartDefuse = false; m_flDefuseLength = 10; return; } #ifndef CLIENT_DLL // tell the bots someone has aborted defusing IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortdefuse" ); if( event ) { event->SetInt("userid", m_pBombDefuser->GetUserID() ); event->SetInt( "priority", 6 ); gameeventmanager->FireEvent( event ); } #endif //if it gets here then the previouse defuser has taken off or been killed // release the player from being frozen m_pBombDefuser->ResetMaxSpeed(); m_pBombDefuser->m_bIsDefusing = false; m_bStartDefuse = false; m_pBombDefuser = NULL; } }
void CCSBot::__MAKE_VHOOK(OnEvent)(GameEventType event, CBaseEntity *entity, CBaseEntity *other) { GetGameState()->OnEvent(event, entity, other); GetChatter()->OnEvent(event, entity, other); // Morale adjustments happen even for dead players switch (event) { case EVENT_TERRORISTS_WIN: if (m_iTeam == CT) { DecreaseMorale(); } else { IncreaseMorale(); } break; case EVENT_CTS_WIN: if (m_iTeam == CT) { IncreaseMorale(); } else { DecreaseMorale(); } break; } if (!IsAlive()) return; CBasePlayer *player = static_cast<CBasePlayer *>(entity); // If we just saw a nearby friend die, and we haven't yet acquired an enemy // automatically acquire our dead friend's killer if (!IsAttacking() && (GetDisposition() == ENGAGE_AND_INVESTIGATE || GetDisposition() == OPPORTUNITY_FIRE)) { if (event == EVENT_PLAYER_DIED) { if (BotRelationship(player) == BOT_TEAMMATE) { CBasePlayer *killer = static_cast<CBasePlayer *>(other); // check that attacker is an enemy (for friendly fire, etc) if (killer != NULL && killer->IsPlayer()) { // check if we saw our friend die - dont check FOV - assume we're aware of our surroundings in combat // snipers stay put if (!IsSniper() && IsVisible(&player->pev->origin)) { // people are dying - we should hurry Hurry(RANDOM_FLOAT(10.0f, 15.0f)); // if we're hiding with only our knife, be a little more cautious const float knifeAmbushChance = 50.0f; if (!IsHiding() || !IsUsingKnife() || RANDOM_FLOAT(0, 100) < knifeAmbushChance) { PrintIfWatched("Attacking our friend's killer!\n"); Attack(killer); return; } } } } } } switch (event) { case EVENT_PLAYER_DIED: { CBasePlayer *victim = player; CBasePlayer *killer = (other != NULL && other->IsPlayer()) ? static_cast<CBasePlayer *>(other) : NULL; // if the human player died in the single player game, tell the team if (CSGameRules()->IsCareer() && !victim->IsBot() && BotRelationship(victim) == BOT_TEAMMATE) { GetChatter()->Say("CommanderDown", 20.0f); } // keep track of the last player we killed if (killer == this) { m_lastVictimID = victim->entindex(); } // react to teammate death if (BotRelationship(victim) == BOT_TEAMMATE) { // chastise friendly fire from humans if (killer != NULL && !killer->IsBot() && BotRelationship(killer) == BOT_TEAMMATE && killer != this) { GetChatter()->KilledFriend(); } if (IsHunting()) { PrintIfWatched("Rethinking hunt due to teammate death\n"); Idle(); return; } if (IsAttacking()) { if (GetTimeSinceLastSawEnemy() > 0.4f) { PrintIfWatched("Rethinking my attack due to teammate death\n"); // allow us to sneak past windows, doors, etc IgnoreEnemies(1.0f); // move to last known position of enemy - this could cause us to flank if // the danger has changed due to our teammate's recent death SetTask(MOVE_TO_LAST_KNOWN_ENEMY_POSITION, GetEnemy()); MoveTo(&GetLastKnownEnemyPosition()); return; } } } // an enemy was killed else { if (killer != NULL && BotRelationship(killer) == BOT_TEAMMATE) { // only chatter about enemy kills if we see them occur, and they were the last one we see if (GetNearbyEnemyCount() <= 1) { // report if number of enemies left is few and we killed the last one we saw locally GetChatter()->EnemiesRemaining(); if (IsVisible(&victim->pev->origin, CHECK_FOV)) { // congratulate teammates on their kills if (killer != this) { float delay = RANDOM_FLOAT(2.0f, 3.0f); if (killer->IsBot()) { if (RANDOM_FLOAT(0.0f, 100.0f) < 40.0f) GetChatter()->Say("NiceShot", 3.0f, delay); } else { // humans get the honorific if (CSGameRules()->IsCareer()) GetChatter()->Say("NiceShotCommander", 3.0f, delay); else GetChatter()->Say("NiceShotSir", 3.0f, delay); } } } } } } return; } case EVENT_TERRORISTS_WIN: if (m_iTeam == TERRORIST) GetChatter()->CelebrateWin(); return; case EVENT_CTS_WIN: if (m_iTeam == CT) GetChatter()->CelebrateWin(); return; case EVENT_BOMB_DEFUSED: if (m_iTeam == CT && TheCSBots()->GetBombTimeLeft() < 2.0) GetChatter()->Say("BarelyDefused"); return; case EVENT_BOMB_PICKED_UP: { if (m_iTeam == CT && player != NULL) { // check if we're close enough to hear it const float bombPickupHearRangeSq = 1000.0f * 1000.0f; if ((pev->origin - player->pev->origin).LengthSquared() < bombPickupHearRangeSq) { GetChatter()->TheyPickedUpTheBomb(); } } return; } case EVENT_BOMB_BEEP: { // if we don't know where the bomb is, but heard it beep, we've discovered it if (GetGameState()->IsPlantedBombLocationKnown() == false) { // check if we're close enough to hear it const float bombBeepHearRangeSq = 1000.0f * 1000.0f; if ((pev->origin - entity->pev->origin).LengthSquared() < bombBeepHearRangeSq) { // radio the news to our team if (m_iTeam == CT && GetGameState()->GetPlantedBombsite() == CSGameState::UNKNOWN) { const CCSBotManager::Zone *zone = TheCSBots()->GetZone(&entity->pev->origin); if (zone != NULL) GetChatter()->FoundPlantedBomb(zone->m_index); } // remember where the bomb is GetGameState()->UpdatePlantedBomb(&entity->pev->origin); } } return; } case EVENT_BOMB_PLANTED: { // if we're a CT, forget what we're doing and go after the bomb if (m_iTeam == CT) { Idle(); } // if we are following someone, stop following if (IsFollowing()) { StopFollowing(); Idle(); } OnEvent(EVENT_BOMB_BEEP, other); return; } case EVENT_BOMB_DEFUSE_ABORTED: PrintIfWatched("BOMB DEFUSE ABORTED\n"); return; case EVENT_WEAPON_FIRED: case EVENT_WEAPON_FIRED_ON_EMPTY: case EVENT_WEAPON_RELOADED: { if (m_enemy == entity && IsUsingKnife()) ForceRun(5.0f); break; } default: break; } // Process radio events from our team if (player != NULL && BotRelationship(player) == BOT_TEAMMATE && event > EVENT_START_RADIO_1 && event < EVENT_END_RADIO) { // TODO: Distinguish between radio commands and responses if (event != EVENT_RADIO_AFFIRMATIVE && event != EVENT_RADIO_NEGATIVE && event != EVENT_RADIO_REPORTING_IN) { m_lastRadioCommand = event; m_lastRadioRecievedTimestamp = gpGlobals->time; m_radioSubject = player; m_radioPosition = player->pev->origin; } } // player_follows needs a player if (player == NULL) return; if (!IsRogue() && event == EVENT_HOSTAGE_CALLED_FOR_HELP && m_iTeam == CT && IsHunting()) { if ((entity->pev->origin - pev->origin).IsLengthGreaterThan(1000.0f)) return; if (IsVisible(&entity->Center())) { m_task = COLLECT_HOSTAGES; m_taskEntity = NULL; Run(); m_goalEntity = entity; MoveTo(&entity->pev->origin, m_hostageEscortCount == 0 ? SAFEST_ROUTE : FASTEST_ROUTE); PrintIfWatched("I'm fetching a hostage that called out to me\n"); return; } } // don't pay attention to noise that friends make if (!IsEnemy(player)) return; float range; PriorityType priority; bool isHostile; if (IsGameEventAudible(event, entity, other, &range, &priority, &isHostile) == false) return; if (event == EVENT_HOSTAGE_USED) { if (m_iTeam == CT) return; if ((entity->pev->origin - pev->origin).IsLengthGreaterThan(range)) return; GetChatter()->HostagesBeingTaken(); if (!GetGameState()->GetNearestVisibleFreeHostage() && m_task != GUARD_HOSTAGE_RESCUE_ZONE && GuardRandomZone()) { m_task = GUARD_HOSTAGE_RESCUE_ZONE; m_taskEntity = NULL; SetDisposition(OPPORTUNITY_FIRE); PrintIfWatched("Trying to beat them to an escape zone!\n"); } } // check if noise is close enough for us to hear const Vector *newNoisePosition = &player->pev->origin; float newNoiseDist = (pev->origin - *newNoisePosition).Length(); if (newNoiseDist < range) { // we heard the sound if ((IsLocalPlayerWatchingMe() && cv_bot_debug.value == 3.0f) || cv_bot_debug.value == 4.0f) { PrintIfWatched("Heard noise (%s from %s, pri %s, time %3.1f)\n", (event == EVENT_WEAPON_FIRED) ? "Weapon fire " : "", STRING(player->pev->netname), (priority == PRIORITY_HIGH) ? "HIGH" : ((priority == PRIORITY_MEDIUM) ? "MEDIUM" : "LOW"), gpGlobals->time); } if (event == EVENT_PLAYER_FOOTSTEP && IsUsingSniperRifle() && newNoiseDist < 300.0) EquipPistol(); // should we pay attention to it // if noise timestamp is zero, there is no prior noise if (m_noiseTimestamp > 0.0f) { // only overwrite recent sound if we are louder (closer), or more important - if old noise was long ago, its faded const float shortTermMemoryTime = 3.0f; if (gpGlobals->time - m_noiseTimestamp < shortTermMemoryTime) { // prior noise is more important - ignore new one if (priority < m_noisePriority) return; float oldNoiseDist = (pev->origin - m_noisePosition).Length(); if (newNoiseDist >= oldNoiseDist) return; } } // find the area in which the noise occured // TODO: Better handle when noise occurs off the nav mesh // TODO: Make sure noise area is not through a wall or ceiling from source of noise // TODO: Change GetNavTravelTime to better deal with NULL destination areas CNavArea *noiseArea = TheNavAreaGrid.GetNavArea(newNoisePosition); if (noiseArea == NULL) noiseArea = TheNavAreaGrid.GetNearestNavArea(newNoisePosition); if (noiseArea == NULL) { PrintIfWatched(" *** Noise occurred off the nav mesh - ignoring!\n"); return; } m_noiseArea = noiseArea; // remember noise priority m_noisePriority = priority; // randomize noise position in the area a bit - hearing isn't very accurate // the closer the noise is, the more accurate our placement // TODO: Make sure not to pick a position on the opposite side of ourselves. const float maxErrorRadius = 400.0f; const float maxHearingRange = 2000.0f; float errorRadius = maxErrorRadius * newNoiseDist / maxHearingRange; m_noisePosition.x = newNoisePosition->x + RANDOM_FLOAT(-errorRadius, errorRadius); m_noisePosition.y = newNoisePosition->y + RANDOM_FLOAT(-errorRadius, errorRadius); // make sure noise position remains in the same area m_noiseArea->GetClosestPointOnArea(&m_noisePosition, &m_noisePosition); m_isNoiseTravelRangeChecked = false; // note when we heard the noise m_noiseTimestamp = gpGlobals->time; } }
// Regular explosions void CPlantedC4::Explode( trace_t *pTrace, int bitsDamageType ) { // Check to see if the round is over after the bomb went off... CSGameRules()->m_bTargetBombed = true; m_bBombTicking = false; CSGameRules()->CheckWinConditions(); // Do the Damage float flBombRadius = 500; if ( g_pMapInfo ) flBombRadius = g_pMapInfo->m_flBombRadius; // Output to the bomb target ent CBaseEntity *pTarget = NULL; variant_t emptyVariant; while ((pTarget = gEntList.FindEntityByClassname( pTarget, "func_bomb_target" )) != NULL) { //Adrian - But only to the one we want! if ( pTarget->entindex() != m_iBombSiteIndex ) continue; pTarget->AcceptInput( "BombExplode", this, this, emptyVariant, 0 ); break; } // Pull out of the wall a bit if ( pTrace->fraction != 1.0 ) { SetAbsOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) ); } { Vector pos = GetAbsOrigin() + Vector( 0,0,8 ); // add an explosion TE so it affects clientside physics CPASFilter filter( pos ); te->Explosion( filter, 0.0, &pos, g_sModelIndexFireball, 50.0, 25, TE_EXPLFLAG_NONE, flBombRadius * 3.5, 200 ); } // Fireball sprite and sound!! { Vector fireballPos = GetAbsOrigin(); CPVSFilter filter( fireballPos ); te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 ); } { Vector fireballPos = GetAbsOrigin() + Vector( random->RandomFloat( -512, 512 ), random->RandomFloat( -512, 512 ), random->RandomFloat( -10, 10 ) ); CPVSFilter filter( fireballPos ); te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 ); } { Vector fireballPos = GetAbsOrigin() + Vector( random->RandomFloat( -512, 512 ), random->RandomFloat( -512, 512 ), random->RandomFloat( -10, 10 ) ); CPVSFilter filter( fireballPos ); te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 ); } // Sound! for everyone CBroadcastRecipientFilter filter; EmitSound( filter, entindex(), "c4.explode" ); // Decal! UTIL_DecalTrace( pTrace, "Scorch" ); // Shake! UTIL_ScreenShake( pTrace->endpos, 25.0, 150.0, 1.0, 3000, SHAKE_START ); SetOwnerEntity( NULL ); // can't traceline attack owner if this is set CSGameRules()->RadiusDamage( CTakeDamageInfo( this, GetOwnerEntity(), flBombRadius, bitsDamageType ), GetAbsOrigin(), flBombRadius * 3.5, //Matt - don't ask me, this is how CS does it. CLASS_NONE, true ); // IGNORE THE WORLD!! // send director message, that something important happed here /* MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR ); WRITE_BYTE ( 9 ); // command length in bytes WRITE_BYTE ( DRC_CMD_EVENT ); // bomb explode WRITE_SHORT( ENTINDEX(this->edict()) ); // index number of primary entity WRITE_SHORT( 0 ); // index number of secondary entity WRITE_LONG( 15 | DRC_FLAG_FINAL ); // eventflags (priority and flags) MESSAGE_END(); */ UTIL_Remove( this ); }