void CASW_Rocket::SeekThink( void ) { // If we have a grace period, go solid when it ends if ( m_flGracePeriodEndsAt ) { if ( m_flGracePeriodEndsAt < gpGlobals->curtime ) { RemoveSolidFlags( FSOLID_NOT_SOLID ); m_flGracePeriodEndsAt = 0; } } Vector vNewVelocity = GetAbsVelocity(); if ( m_bFlyingWild ) { // wobble crazily. Poll for a new target every quarter second, and if none is found, go // careering off. if ( gpGlobals->curtime >= m_flNextWobbleTime ) { Assert( !m_hHomingTarget.Get() ); CBaseEntity *pHomingTarget = FindPotentialTarget(); if ( pHomingTarget ) { SetTarget( pHomingTarget ); m_bFlyingWild = false; } else { // pick a new wobble direction /* m_vWobbleAngles = GetAbsAngles(); m_vWobbleAngles.y = m_vWobbleAngles.y + RandomFloat( -asw_rocket_wobble_amp.GetFloat(), asw_rocket_wobble_amp.GetFloat() ) ; if ( m_vWobbleAngles.y < 0 ) { m_vWobbleAngles.y = 360 + m_vWobbleAngles.y; } else if ( m_vWobbleAngles.y > 360 ) { m_vWobbleAngles.y = fmod( m_vWobbleAngles.y, 360 ); } */ m_vWobbleAngles = GetAbsAngles(); m_vWobbleAngles.y = fmodf( m_vWobbleAngles.y + RandomFloat( -asw_rocket_wobble_amp.GetFloat(), asw_rocket_wobble_amp.GetFloat() ), 360 ); m_flNextWobbleTime = gpGlobals->curtime + asw_rocket_wobble_freq.GetFloat(); } } } if ( !m_bFlyingWild ) { Vector targetPos; FindHomingPosition( &targetPos ); // find target direction Vector vTargetDir; VectorSubtract( targetPos, GetAbsOrigin(), vTargetDir ); float flDist = VectorNormalize( vTargetDir ); // find current direction Vector vDir = GetAbsVelocity(); //float flSpeed = VectorNormalize( vDir ); vNewVelocity = IntegrateRocketThrust( vTargetDir, flDist ); // face direction of movement QAngle finalAngles; VectorAngles( vNewVelocity, finalAngles ); SetAbsAngles( finalAngles ); // set to the new calculated velocity SetAbsVelocity( vNewVelocity ); } else // wobble crazily { #pragma message("TODO: straighten out this math") if ( gpGlobals->curtime >= m_flNextWobbleTime ) { // pick a new wobble direction m_vWobbleAngles = GetAbsAngles(); m_vWobbleAngles.y = fmodf( m_vWobbleAngles.y + RandomFloat( -asw_rocket_wobble_amp.GetFloat(), asw_rocket_wobble_amp.GetFloat() ), 360 ); m_flNextWobbleTime = gpGlobals->curtime + asw_rocket_wobble_freq.GetFloat(); } QAngle finalAngles = GetAbsAngles(); finalAngles.y = ApproachAngle( m_vWobbleAngles.y, finalAngles.y, 360.f * (gpGlobals->curtime - GetLastThink()) ); Vector forward; AngleVectors( finalAngles, &forward ); vNewVelocity = forward * FastSqrtEst( vNewVelocity.LengthSqr() ); if ( IsWallDodging() ) { ComputeWallDodge( vNewVelocity ); finalAngles.y = ApproachAngle( m_vWobbleAngles.y, finalAngles.y, 360.f * (gpGlobals->curtime - GetLastThink()) ); } vNewVelocity = IntegrateRocketThrust( forward, 0 ); // face direction of movement SetAbsAngles( finalAngles ); // set to the new calculated velocity SetAbsVelocity( vNewVelocity ); } // blow us up after our lifetime if (GetLifeFraction() >= 1.0f) { Explode(); } else { // Think as soon as possible SetNextThink( gpGlobals->curtime ); } }
void CAPCController::TrackTarget( void ) { trace_t tr; bool updateTime = FALSE, lineOfSight; QAngle angles; Vector barrelEnd; CBaseEntity *pTarget = NULL; barrelEnd.Init(); if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 0.1f ); } else { return; } // ----------------------------------- // Get world target position // ----------------------------------- barrelEnd = WorldBarrelPosition(); Vector worldTargetPosition; CBaseEntity *pEntity = (CBaseEntity *)m_hTarget; if ( !pEntity || ( pEntity->GetFlags() & FL_NOTARGET ) ) { m_hTarget = FindTarget( m_targetEntityName, NULL ); if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 2 ); // Wait 2 sec s } return; } pTarget = pEntity; // Calculate angle needed to aim at target worldTargetPosition = pEntity->EyePosition(); float range = (worldTargetPosition - barrelEnd).Length(); if ( !InRange( range ) ) { m_bFireDelayed = false; return; } UTIL_TraceLine( barrelEnd, worldTargetPosition, MASK_BLOCKLOS, this, COLLISION_GROUP_NONE, &tr ); lineOfSight = FALSE; // No line of sight, don't track if ( tr.fraction == 1.0 || tr.m_pEnt == pTarget ) { lineOfSight = TRUE; CBaseEntity *pInstance = pTarget; if ( InRange( range ) && pInstance && pInstance->IsAlive() ) { updateTime = TRUE; // Sight position is BodyTarget with no noise (so gun doesn't bob up and down) m_sightOrigin = pInstance->BodyTarget( GetLocalOrigin(), false ); } } // Convert targetPosition to parent angles = AimBarrelAt( m_parentMatrix.WorldToLocal( m_sightOrigin ) ); // Force the angles to be relative to the center position float offsetY = UTIL_AngleDistance( angles.y, m_yawCenter ); float offsetX = UTIL_AngleDistance( angles.x, m_pitchCenter ); angles.y = m_yawCenter + offsetY; angles.x = m_pitchCenter + offsetX; // Move toward target at rate or less float distY = UTIL_AngleDistance( angles.y, GetLocalAngles().y ); QAngle vecAngVel = GetLocalAngularVelocity(); vecAngVel.y = distY * 10; vecAngVel.y = clamp( vecAngVel.y, -m_yawRate, m_yawRate ); // Move toward target at rate or less float distX = UTIL_AngleDistance( angles.x, GetLocalAngles().x ); vecAngVel.x = distX * 10; vecAngVel.x = clamp( vecAngVel.x, -m_pitchRate, m_pitchRate ); SetLocalAngularVelocity( vecAngVel ); SetMoveDoneTime( 0.1 ); Vector forward; AngleVectors( GetLocalAngles(), &forward ); forward = m_parentMatrix.ApplyRotation( forward ); AngleVectors(angles, &forward); if ( lineOfSight == TRUE ) { // FIXME: This will ultimately have to deal with NPCs being in the vehicle as well // See if the target is in a vehicle. If so, check its relationship CBasePlayer *pPlayer = ToBasePlayer( pTarget ); if ( pPlayer && pPlayer->IsInAVehicle() ) { IServerVehicle *pVehicle = pPlayer->GetVehicle(); if ( pVehicle->ClassifyPassenger( pPlayer, CLASS_PLAYER ) == CLASS_PLAYER) { if ( !m_bFireDelayed ) { m_bFireDelayed = true; m_flFiringDelay = gpGlobals->curtime + 1.5; // setup delay time before we start firing return; } if ( gpGlobals->curtime > m_flFiringDelay ) { m_OnFireAtTarget.Set(forward, this, this); // tell apc to fire rockets, and what direction } } } } else { m_bFireDelayed = false; // reset flag since we can no longer see target } }
// UNDONE: temporary scorching for PreAlpha - find a less sleazy permenant solution. void CGrenade::Explode( TraceResult *pTrace, int bitsDamageType ) { float flRndSound;// sound randomizer pev->model = iStringNull;//invisible pev->solid = SOLID_NOT;// intangible pev->takedamage = DAMAGE_NO; // Pull out of the wall a bit if ( pTrace->flFraction != 1.0 ) { pev->origin = pTrace->vecEndPos + (pTrace->vecPlaneNormal * (pev->dmg - 24) * 0.6); } int iContents = UTIL_PointContents ( pev->origin ); MESSAGE_BEGIN( MSG_PAS, gmsgTempEntity, pev->origin ); WRITE_BYTE( TE_EXPLOSION ); // This makes a dynamic light and the explosion sprites/sound WRITE_COORD( pev->origin.x ); // Send to PAS because of the sound WRITE_COORD( pev->origin.y ); WRITE_COORD( pev->origin.z ); if (iContents != CONTENTS_WATER) { WRITE_SHORT( g_sModelIndexFireball ); } else { WRITE_SHORT( g_sModelIndexWExplosion ); } WRITE_BYTE( (pev->dmg - 50) * .60 ); // scale * 10 WRITE_BYTE( 15 ); // framerate WRITE_BYTE( TE_EXPLFLAG_NONE ); MESSAGE_END(); CSoundEnt::InsertSound ( bits_SOUND_COMBAT, pev->origin, NORMAL_EXPLOSION_VOLUME, 3.0 ); entvars_t *pevOwner; if ( pev->owner ) pevOwner = VARS( pev->owner ); else pevOwner = NULL; pev->owner = NULL; // can't traceline attack owner if this is set RadiusDamage ( pev, pevOwner, pev->dmg, CLASS_NONE, bitsDamageType ); CBaseEntity *pHit = CBaseEntity::Instance( pTrace->pHit ); UTIL_DecalTrace( pTrace, DECAL_SCORCH2 ); flRndSound = RANDOM_FLOAT( 0 , 1 ); switch ( RANDOM_LONG( 0, 2 ) ) { case 0: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/debris1.wav", 0.55, ATTN_NORM); break; case 1: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/debris2.wav", 0.55, ATTN_NORM); break; case 2: EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/debris3.wav", 0.55, ATTN_NORM); break; } pev->effects |= EF_NODRAW; SetThink(&CGrenade:: Smoke ); pev->velocity = g_vecZero; SetNextThink( 0.3 ); if (iContents != CONTENTS_WATER) { int sparkCount = RANDOM_LONG(0,3); for ( int i = 0; i < sparkCount; i++ ) Create( "spark_shower", pev->origin, pTrace->vecPlaneNormal, NULL ); } }
//----------------------------------------------------------------------------- // Purpose: Creates a new NPC every so often. //----------------------------------------------------------------------------- void CBaseNPCMaker::MakerThink ( void ) { SetNextThink( gpGlobals->curtime + m_flSpawnFrequency ); MakeNPC(); }
void CHL2MP_Player::HL2MPPushawayThink(void) { // Push physics props out of our way. PerformObstaclePushaway( this ); SetNextThink( gpGlobals->curtime + PUSHAWAY_THINK_INTERVAL, HL2MP_PUSHAWAY_THINK_CONTEXT ); }
//------------------------------------------------------------------------------ // Purpose : //------------------------------------------------------------------------------ void CGameUI::InputActivate( inputdata_t &inputdata ) { CBasePlayer *pPlayer; // Determine if we're specifying this as an override parameter if ( inputdata.value.StringID() != NULL_STRING ) { CBaseEntity *pEntity = gEntList.FindEntityByName( NULL, inputdata.value.String(), this, inputdata.pActivator, inputdata.pCaller ); if ( pEntity == NULL || pEntity->IsPlayer() == false ) { Warning( "%s InputActivate: entity %s not found or is not a player!\n", STRING(GetEntityName()), inputdata.value.String() ); return; } pPlayer = ToBasePlayer( pEntity ); } else { // Otherwise try to use the activator if ( inputdata.pActivator == NULL || inputdata.pActivator->IsPlayer() == false ) { Warning( "%s InputActivate: invalid or missing !activator!\n", STRING(GetEntityName()), inputdata.value.String() ); return; } pPlayer = ToBasePlayer( inputdata.pActivator ); } // If another player is already using these controls3, ignore this activation if ( m_player.Get() != NULL && pPlayer != m_player.Get() ) { // TODO: We could allow this by calling Deactivate() at this point and continuing on -- jdw return; } // Setup our internal data m_player = pPlayer; m_playerOn.FireOutput( pPlayer, this, 0 ); // Turn the hud off SetNextThink( gpGlobals->curtime ); // Disable player's motion if ( FBitSet( m_spawnflags, SF_GAMEUI_FREEZE_PLAYER ) ) { m_player->AddFlag( FL_ATCONTROLS ); } // Store off and hide the currently held weapon if ( FBitSet( m_spawnflags, SF_GAMEUI_HIDE_WEAPON ) ) { m_player->m_Local.m_iHideHUD |= HIDEHUD_WEAPONSELECTION; if ( m_player->GetActiveWeapon() ) { m_hSaveWeapon = m_player->GetActiveWeapon(); m_player->GetActiveWeapon()->Holster(); m_player->ClearActiveWeapon(); m_player->HideViewModels(); } } // We must update our state m_bForceUpdate = true; }
//========================================================= // ActiveThink - //========================================================= void CNPC_BaseTurret::ActiveThink(void) { int fAttack = 0; SetNextThink( gpGlobals->curtime + 0.1 ); StudioFrameAdvance( ); if ( (!m_iOn) || (GetEnemy() == NULL) ) { SetEnemy( NULL ); m_flLastSight = gpGlobals->curtime + m_flMaxWait; SetThink(&CNPC_BaseTurret::SearchThink); return; } // if it's dead, look for something new if ( !GetEnemy()->IsAlive() ) { if (!m_flLastSight) { m_flLastSight = gpGlobals->curtime + 0.5; // continue-shooting timeout } else { if (gpGlobals->curtime > m_flLastSight) { SetEnemy( NULL ); m_flLastSight = gpGlobals->curtime + m_flMaxWait; SetThink(&CNPC_BaseTurret::SearchThink); return; } } } Vector vecMid = GetAbsOrigin() + GetViewOffset(); Vector vecMidEnemy = GetEnemy()->BodyTarget( vecMid, false ); // Look for our current enemy int fEnemyVisible = FBoxVisible(this, GetEnemy(), vecMidEnemy ); //We want to look at the enemy's eyes so we don't jitter Vector vecDirToEnemyEyes = vecMidEnemy - vecMid; float flDistToEnemy = vecDirToEnemyEyes.Length(); VectorNormalize( vecDirToEnemyEyes ); QAngle vecAnglesToEnemy; VectorAngles( vecDirToEnemyEyes, vecAnglesToEnemy ); // Current enmey is not visible. if (!fEnemyVisible || (flDistToEnemy > TURRET_RANGE)) { if (!m_flLastSight) m_flLastSight = gpGlobals->curtime + 0.5; else { // Should we look for a new target? if (gpGlobals->curtime > m_flLastSight) { SetEnemy( NULL ); m_flLastSight = gpGlobals->curtime + m_flMaxWait; SetThink(&CNPC_BaseTurret::SearchThink); return; } } fEnemyVisible = 0; } else { m_vecLastSight = vecMidEnemy; } //ALERT( at_console, "%.0f %.0f : %.2f %.2f %.2f\n", // m_vecCurAngles.x, m_vecCurAngles.y, // gpGlobals->v_forward.x, gpGlobals->v_forward.y, gpGlobals->v_forward.z ); Vector vecLOS = vecDirToEnemyEyes; //vecMid - m_vecLastSight; VectorNormalize( vecLOS ); Vector vecMuzzle, vecMuzzleDir; QAngle vecMuzzleAng; GetAttachment( 1, vecMuzzle, vecMuzzleAng ); AngleVectors( vecMuzzleAng, &vecMuzzleDir ); // Is the Gun looking at the target if (DotProduct(vecLOS, vecMuzzleDir) <= 0.866) // 30 degree slop fAttack = FALSE; else fAttack = TRUE; //forward // NDebugOverlay::Line(vecMuzzle, vecMid + ( vecMuzzleDir * 200 ), 255,0,0, false, 0.1); //LOS // NDebugOverlay::Line(vecMuzzle, vecMid + ( vecLOS * 200 ), 0,0,255, false, 0.1); // fire the gun if (m_iSpin && ((fAttack) || (m_fBeserk))) { Vector vecOrigin; QAngle vecAngles; GetAttachment( 1, vecOrigin, vecAngles ); Shoot(vecOrigin, vecMuzzleDir ); SetTurretAnim(TURRET_ANIM_FIRE); } else { SetTurretAnim(TURRET_ANIM_SPIN); } //move the gun if (m_fBeserk) { if (random->RandomInt(0,9) == 0) { m_vecGoalAngles.y = random->RandomFloat(0,360); m_vecGoalAngles.x = random->RandomFloat(0,90) - 90 * m_iOrientation; CTakeDamageInfo info; info.SetAttacker(this); info.SetInflictor(this); info.SetDamage( 1 ); info.SetDamageType( DMG_GENERIC ); TakeDamage( info ); // don't beserk forever return; } } else if (fEnemyVisible) { if (vecAnglesToEnemy.y > 360) vecAnglesToEnemy.y -= 360; if (vecAnglesToEnemy.y < 0) vecAnglesToEnemy.y += 360; //ALERT(at_console, "[%.2f]", vec.x); if (vecAnglesToEnemy.x < -180) vecAnglesToEnemy.x += 360; if (vecAnglesToEnemy.x > 180) vecAnglesToEnemy.x -= 360; // now all numbers should be in [1...360] // pin to turret limitations to [-90...14] if (m_iOrientation == TURRET_ORIENTATION_FLOOR) { if (vecAnglesToEnemy.x > 90) vecAnglesToEnemy.x = 90; else if (vecAnglesToEnemy.x < m_iMinPitch) vecAnglesToEnemy.x = m_iMinPitch; } else { if (vecAnglesToEnemy.x < -90) vecAnglesToEnemy.x = -90; else if (vecAnglesToEnemy.x > -m_iMinPitch) vecAnglesToEnemy.x = -m_iMinPitch; } //DevMsg( 1, "->[%.2f]\n", vec.x); m_vecGoalAngles.y = vecAnglesToEnemy.y; m_vecGoalAngles.x = vecAnglesToEnemy.x; } SpinUpCall(); MoveTurret(); }
// // ambient_generic - general-purpose user-defined static sound // void CAmbientGeneric :: Spawn( void ) { /* -1 : "Default" 0 : "Everywhere" 200 : "Small Radius" 125 : "Medium Radius" 80 : "Large Radius" */ if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_EVERYWHERE) ) { m_flAttenuation = ATTN_NONE; } else if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_SMALLRADIUS) ) { m_flAttenuation = ATTN_IDLE; } else if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_MEDIUMRADIUS) ) { m_flAttenuation = ATTN_STATIC; } else if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_LARGERADIUS) ) { m_flAttenuation = ATTN_NORM; } else {// if the designer didn't set a sound attenuation, default to one. m_flAttenuation = ATTN_STATIC; } if( !pev->health ) pev->health = 10; // just get full volume char* szSoundFile = (char*) STRING(pev->message); if ( FStringNull( pev->message ) || strlen( szSoundFile ) < 1 ) { ALERT( at_error, "ambient_generic \"%s\" at (%f, %f, %f) has no sound file\n", STRING(pev->targetname), pev->origin.x, pev->origin.y, pev->origin.z ); SetNextThink( 0.1 ); SetThink( Remove ); return; } pev->solid = SOLID_NOT; pev->movetype = MOVETYPE_NONE; // Set up think function for dynamic modification // of ambient sound's pitch or volume. Don't // start thinking yet. SetThink(RampThink); DontThink(); // allow on/off switching via 'use' function. SetUse( ToggleUse ); m_fActive = FALSE; if ( FBitSet ( pev->spawnflags, AMBIENT_SOUND_NOT_LOOPING ) ) m_fLooping = FALSE; else m_fLooping = TRUE; Precache( ); }
void CTripmineGrenade::WarningThink( void ) { // set to power up SetThink( &CTripmineGrenade::PowerupThink ); SetNextThink( gpGlobals->curtime + 1.0f ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CHarpoon::FlyThink( void ) { SetHarpoonAngles(); SetNextThink( gpGlobals->curtime + 0.1f ); }
void CNPC_ControllerHeadBall::HuntThink( void ) { SetNextThink( gpGlobals->curtime + 0.1 ); if( !m_pSprite ) { Assert(0); return; } m_pSprite->SetBrightness( m_pSprite->GetBrightness() - 5, 0.1f ); CBroadcastRecipientFilter filter; te->DynamicLight( filter, 0.0, &GetAbsOrigin(), 255, 255, 255, 0, m_pSprite->GetBrightness() / 16, 0.2, 0 ); // check world boundaries if (gpGlobals->curtime - m_flSpawnTime > 5 || m_pSprite->GetBrightness() < 64 /*|| GetEnemy() == NULL || m_hOwner == NULL*/ || !IsInWorld() ) { SetTouch( NULL ); SetThink( &CNPC_ControllerHeadBall::KillThink ); SetNextThink( gpGlobals->curtime ); return; } if( !GetEnemy() ) return; MovetoTarget( GetEnemy()->GetAbsOrigin() ); if ((GetEnemy()->WorldSpaceCenter() - GetAbsOrigin()).Length() < 64) { trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetEnemy()->WorldSpaceCenter(), MASK_ALL, this, COLLISION_GROUP_NONE, &tr ); CBaseEntity *pEntity = tr.m_pEnt; if (pEntity != NULL && pEntity->m_takedamage == DAMAGE_YES) { ClearMultiDamage( ); Vector dir = GetAbsVelocity(); VectorNormalize( dir ); CTakeDamageInfo info( this, this, sk_controller_dmgball.GetFloat(), DMG_SHOCK ); CalculateMeleeDamageForce( &info, dir, tr.endpos ); pEntity->DispatchTraceAttack( info, dir, &tr ); ApplyMultiDamage(); int haloindex = 0; int fadelength = 0; int amplitude = 0; const Vector vecEnd = tr.endpos; te->BeamEntPoint( filter, 0.0, entindex(), NULL, 0, &(tr.m_pEnt->GetAbsOrigin()), g_sModelIndexLaser, haloindex /* no halo */, 0, 10, 3, 20, 20, fadelength, amplitude, 255, 255, 255, 255, 10 ); } UTIL_EmitAmbientSound( GetSoundSourceIndex(), GetAbsOrigin(), "Controller.ElectroSound", 0.5, SNDLVL_NORM, 0, 100 ); SetNextAttack( gpGlobals->curtime + 3.0 ); SetThink( &CNPC_ControllerHeadBall::KillThink ); SetNextThink( gpGlobals->curtime + 0.3 ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CNPC_SecobModportal1::Spawn( void ) { Precache(); // This is a dummy model that is never used! UTIL_SetSize(this, Vector(-26,-26,-26), Vector(26,26,26)); SetMoveType( MOVETYPE_NONE ); SetBloodColor( BLOOD_COLOR_RED ); ClearEffects(); SetGravity( 0.0 ); //PrecacheModel( "models/obco_portal1.mdl" ); //SetModel( "models/obco_portal1.mdl" ); // set size and link into world AddSolidFlags( FSOLID_NOT_STANDABLE ); m_flFieldOfView = cos( DEG2RAD(m_flFieldOfView) / 2.0 ); //Got blood? if ( m_spawnflags & SF_SecobModportal1_BLEED ) { SetBloodColor(BLOOD_COLOR_RED); } else { SetBloodColor(DONT_BLEED); } AddFlag( FL_NPC ); AddEFlags( EFL_NO_DISSOLVE ); SetThink( &CNPC_SecobModportal1::SecobModportal1Think ); SetNextThink( gpGlobals->curtime + 0.1f ); SetSolid( SOLID_BBOX ); if( m_spawnflags & SF_SecobModportal1_NONSOLID ) { AddSolidFlags( FSOLID_NOT_SOLID ); } if ( m_spawnflags & SF_SecobModportal1_VPHYSICSSHADOW ) { VPhysicsInitShadow( false, false ); } if( m_spawnflags & SF_SecobModportal1_NODAMAGE ) { m_takedamage = DAMAGE_NO; } else { m_takedamage = DAMAGE_YES; } //AddEffects( EF_NODRAW ); //Check our water level PhysicsCheckWater(); CapabilitiesAdd( bits_CAP_SIMPLE_RADIUS_DAMAGE ); m_iMaxHealth = GetHealth(); if( m_fAutoaimRadius > 0.0f ) { // Make this an aimtarget, since it has some autoaim influence. AddFlag(FL_AIMTARGET); } }
void CControllerHeadBall :: HuntThink( void ) { SetNextThink( 0.1 ); pev->renderamt -= 5; MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); WRITE_BYTE( TE_ELIGHT ); WRITE_SHORT( entindex( ) ); // entity, attachment WRITE_COORD( pev->origin.x ); // origin WRITE_COORD( pev->origin.y ); WRITE_COORD( pev->origin.z ); WRITE_COORD( pev->renderamt / 16 ); // radius WRITE_BYTE( 255 ); // R WRITE_BYTE( 255 ); // G WRITE_BYTE( 255 ); // B WRITE_BYTE( 2 ); // life * 10 WRITE_COORD( 0 ); // decay MESSAGE_END(); // check world boundaries if (gpGlobals->time - pev->dmgtime > 5 || pev->renderamt < 64 || m_hEnemy == 0 || m_hOwner == 0 || pev->origin.x < -4096 || pev->origin.x > 4096 || pev->origin.y < -4096 || pev->origin.y > 4096 || pev->origin.z < -4096 || pev->origin.z > 4096) { SetTouch( NULL ); UTIL_Remove( this ); return; } MovetoTarget( m_hEnemy->Center( ) ); if ((m_hEnemy->Center() - pev->origin).Length() < 64) { TraceResult tr; UTIL_TraceLine( pev->origin, m_hEnemy->Center(), dont_ignore_monsters, ENT(pev), &tr ); CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit); if (pEntity != NULL && pEntity->pev->takedamage) { ClearMultiDamage( ); pEntity->TraceAttack( m_hOwner->pev, gSkillData.controllerDmgZap, pev->velocity, &tr, DMG_SHOCK ); ApplyMultiDamage( pev, m_hOwner->pev ); } MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); WRITE_BYTE( TE_BEAMENTPOINT ); WRITE_SHORT( entindex() ); WRITE_COORD( tr.vecEndPos.x ); WRITE_COORD( tr.vecEndPos.y ); WRITE_COORD( tr.vecEndPos.z ); WRITE_SHORT( g_sModelIndexLaser ); WRITE_BYTE( 0 ); // frame start WRITE_BYTE( 10 ); // framerate WRITE_BYTE( 3 ); // life WRITE_BYTE( 20 ); // width WRITE_BYTE( 0 ); // noise WRITE_BYTE( 255 ); // r, g, b WRITE_BYTE( 255 ); // r, g, b WRITE_BYTE( 255 ); // r, g, b WRITE_BYTE( 255 ); // brightness WRITE_BYTE( 10 ); // speed MESSAGE_END(); UTIL_EmitAmbientSound( ENT(pev), tr.vecEndPos, "weapons/electro4.wav", 0.5, ATTN_NORM, 0, RANDOM_LONG( 140, 160 ) ); m_flNextAttack = gpGlobals->time + 3.0; SetThink(&CControllerHeadBall :: DieThink ); SetNextThink( 0.3 ); } // Crawl( ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pOther - //----------------------------------------------------------------------------- void CGrappleHook::HookTouch( CBaseEntity *pOther ) { if ( !pOther->IsSolid() || pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS) ) return; if ( (pOther != m_hOwner) && (pOther->m_takedamage != DAMAGE_NO) ) { m_hOwner->NotifyHookDied(); SetTouch( NULL ); SetThink( NULL ); UTIL_Remove( this ); } else { trace_t tr; tr = BaseClass::GetTouchTrace(); // See if we struck the world if ( pOther->GetMoveType() == MOVETYPE_NONE && !( tr.surface.flags & SURF_SKY ) ) { EmitSound( "Weapon_AR2.Reload_Push" ); // if what we hit is static architecture, can stay around for a while. Vector vecDir = GetAbsVelocity(); //FIXME: We actually want to stick (with hierarchy) to what we've hit SetMoveType( MOVETYPE_NONE ); Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); VectorNormalize ( vForward ); CEffectData data; data.m_vOrigin = tr.endpos; data.m_vNormal = vForward; data.m_nEntIndex = 0; // DispatchEffect( "Impact", data ); // AddEffects( EF_NODRAW ); SetTouch( NULL ); VPhysicsDestroyObject(); VPhysicsInitNormal( SOLID_VPHYSICS, FSOLID_NOT_STANDABLE, false ); AddSolidFlags( FSOLID_NOT_SOLID ); // SetMoveType( MOVETYPE_NONE ); if ( !m_hPlayer ) { Assert( 0 ); return; } // Set Jay's gai flag m_hPlayer->SetPhysicsFlag( PFLAG_VPHYSICS_MOTIONCONTROLLER, true ); //IPhysicsObject *pPhysObject = m_hPlayer->VPhysicsGetObject(); IPhysicsObject *pRootPhysObject = VPhysicsGetObject(); Assert( pRootPhysObject ); Assert( pPhysObject ); pRootPhysObject->EnableMotion( false ); // Root has huge mass, tip has little pRootPhysObject->SetMass( VPHYSICS_MAX_MASS ); // pPhysObject->SetMass( 100 ); // float damping = 3; // pPhysObject->SetDamping( &damping, &damping ); Vector origin = m_hPlayer->GetAbsOrigin(); Vector rootOrigin = GetAbsOrigin(); m_fSpringLength = (origin - rootOrigin).Length(); m_bPlayerWasStanding = ( ( m_hPlayer->GetFlags() & FL_DUCKING ) == 0 ); SetThink( &CGrappleHook::HookedThink ); SetNextThink( gpGlobals->curtime + 0.1f ); } else { // Put a mark unless we've hit the sky if ( ( tr.surface.flags & SURF_SKY ) == false ) { UTIL_ImpactTrace( &tr, DMG_BULLET ); } SetTouch( NULL ); SetThink( NULL ); m_hOwner->NotifyHookDied(); UTIL_Remove( this ); } } }
//----------------------------------------------------------------------------- // Purpose: Breaks the breakable. m_hBreaker is the entity that caused us to break. //----------------------------------------------------------------------------- void CBreakable::Die( void ) { Vector vecVelocity;// shard velocity char cFlag = 0; int pitch; float fvol; pitch = 95 + random->RandomInt(0,29); if (pitch > 97 && pitch < 103) { pitch = 100; } // The more negative m_iHealth, the louder // the sound should be. fvol = random->RandomFloat(0.85, 1.0) + (abs(m_iHealth.Get()) / 100.0); if (fvol > 1.0) { fvol = 1.0; } const char *soundname = NULL; switch (m_Material) { default: break; case matGlass: soundname = "Breakable.Glass"; cFlag = BREAK_GLASS; break; case matWood: soundname = "Breakable.Crate"; cFlag = BREAK_WOOD; break; case matComputer: soundname = "Breakable.Computer"; cFlag = BREAK_METAL; break; case matMetal: soundname = "Breakable.Metal"; cFlag = BREAK_METAL; break; case matFlesh: case matWeb: soundname = "Breakable.Flesh"; cFlag = BREAK_FLESH; break; case matRocks: case matCinderBlock: soundname = "Breakable.Concrete"; cFlag = BREAK_CONCRETE; break; case matCeilingTile: soundname = "Breakable.Ceiling"; break; } if ( soundname ) { if ( m_hBreaker && m_hBreaker->IsPlayer() ) { IGameEvent * event = gameeventmanager->CreateEvent( "break_breakable" ); if ( event ) { event->SetInt( "userid", ToBasePlayer( m_hBreaker )->GetUserID() ); event->SetInt( "entindex", entindex() ); event->SetInt( "material", cFlag ); gameeventmanager->FireEvent( event ); } } CSoundParameters params; if ( GetParametersForSound( soundname, params, NULL ) ) { CPASAttenuationFilter filter( this ); EmitSound_t ep; ep.m_nChannel = params.channel; ep.m_pSoundName = params.soundname; ep.m_flVolume = fvol; ep.m_SoundLevel = params.soundlevel; ep.m_nPitch = pitch; EmitSound( filter, entindex(), ep ); } } switch( m_Explosion ) { case expDirected: vecVelocity = g_vecAttackDir * -200; break; case expUsePrecise: { AngleVectors( m_GibDir, &vecVelocity, NULL, NULL ); vecVelocity *= 200; } break; case expRandom: vecVelocity.x = 0; vecVelocity.y = 0; vecVelocity.z = 0; break; default: DevMsg("**ERROR - Unspecified gib dir method in func_breakable!\n"); break; } Vector vecSpot = WorldSpaceCenter(); CPVSFilter filter2( vecSpot ); int iModelIndex = 0; CCollisionProperty *pCollisionProp = CollisionProp(); Vector vSize = pCollisionProp->OBBSize(); int iCount = ( vSize[0] * vSize[1] + vSize[1] * vSize[2] + vSize[2] * vSize[0] ) / ( 3 * 12 * 12 ); if ( iCount > func_break_max_pieces.GetInt() ) { iCount = func_break_max_pieces.GetInt(); } if ( !breakable_disable_gib_limit.GetBool() && iCount ) { if ( m_PerformanceMode == PM_NO_GIBS ) { iCount = 0; } else if ( m_PerformanceMode == PM_REDUCED_GIBS ) { int iNewCount = iCount * func_break_reduction_factor.GetFloat(); iCount = MAX( iNewCount, 1 ); } } if ( m_iszModelName != NULL_STRING ) { for ( int i = 0; i < iCount; i++ ) { iModelIndex = modelinfo->GetModelIndex( g_PropDataSystem.GetRandomChunkModel( STRING( m_iszModelName ) ) ); // All objects except the first one in this run are marked as slaves... int slaveFlag = 0; if ( i != 0 ) { slaveFlag = BREAK_SLAVE; } te->BreakModel( filter2, 0.0, vecSpot, pCollisionProp->GetCollisionAngles(), vSize, vecVelocity, iModelIndex, 100, 1, 2.5, cFlag | slaveFlag ); } } ResetOnGroundFlags(); // Don't fire something that could fire myself SetName( NULL_STRING ); AddSolidFlags( FSOLID_NOT_SOLID ); // Fire targets on break m_OnBreak.FireOutput( m_hBreaker, this ); VPhysicsDestroyObject(); SetThink( &CBreakable::SUB_Remove ); SetNextThink( gpGlobals->curtime + 0.1f ); if ( m_iszSpawnObject != NULL_STRING ) { CBaseEntity::Create( STRING(m_iszSpawnObject), vecSpot, pCollisionProp->GetCollisionAngles(), this ); } if ( Explodable() ) { ExplosionCreate( vecSpot, pCollisionProp->GetCollisionAngles(), this, GetExplosiveDamage(), GetExplosiveRadius(), true ); } }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CBaseHelicopter::NullThink( void ) { StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.5f ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CASW_PropJeep::Think(void) { m_VehiclePhysics.Think(); // Derived classes of CPropVehicle have their own code to determine how frequently to think. // But the prop_vehicle entity native to this class will only think one time, so this flag // was added to allow prop_vehicle to always think without affecting the derived classes. if( HasSpawnFlags(SF_PROP_VEHICLE_ALWAYSTHINK) ) { SetNextThink(gpGlobals->curtime); } if ( ShouldThink() ) { SetNextThink( gpGlobals->curtime ); } // If we have an NPC Driver, tell him to drive if ( m_hNPCDriver ) { GetServerVehicle()->NPC_DriveVehicle(); } // Keep thinking while we're waiting to turn off the keep upright if ( m_flTurnOffKeepUpright ) { SetNextThink( gpGlobals->curtime ); // Time up? if ( m_hKeepUpright != NULL && m_flTurnOffKeepUpright < gpGlobals->curtime ) { variant_t emptyVariant; m_hKeepUpright->AcceptInput( "TurnOff", this, this, emptyVariant, USE_TOGGLE ); m_flTurnOffKeepUpright = 0; UTIL_Remove( m_hKeepUpright ); } } /* CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if ( m_bEngineLocked ) { m_bUnableToFire = true; if ( pPlayer != NULL ) { pPlayer->m_Local.m_iHideHUD |= HIDEHUD_VEHICLE_CROSSHAIR; } } else if ( m_bHasGun ) { // Start this as false and update it again each frame m_bUnableToFire = false; if ( pPlayer != NULL ) { pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_VEHICLE_CROSSHAIR; } }*/ // Water!? HandleWater(); SetSimulationTime( gpGlobals->curtime ); SetNextThink( gpGlobals->curtime ); SetAnimatedEveryTick( true ); if ( !m_bInitialHandbrake ) // after initial timer expires, set the handbrake { m_bInitialHandbrake = true; m_VehiclePhysics.SetHandbrake( true ); m_VehiclePhysics.Think(); } // Check overturned status. if ( !IsOverturned() ) { m_flOverturnedTime = 0.0f; } else { m_flOverturnedTime += gpGlobals->frametime; } // spin gun if charging cannon //FIXME: Don't bother for E3 if ( m_bCannonCharging ) { m_nSpinPos += JEEP_GUN_SPIN_RATE; SetPoseParameter( JEEP_GUN_SPIN, m_nSpinPos ); } // Aim gun based on the player view direction. if ( m_hPlayer && !m_bExitAnimOn && !m_bEnterAnimOn ) { Vector vecEyeDir, vecEyePos; m_hPlayer->EyePositionAndVectors( &vecEyePos, &vecEyeDir, NULL, NULL ); // Trace out from the player's eye point. Vector vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH ); trace_t trace; UTIL_TraceLine( vecEyePos, vecEndPos, MASK_SHOT, this, COLLISION_GROUP_NONE, &trace ); // See if we hit something, if so, adjust end position to hit location. if ( trace.fraction < 1.0 ) { vecEndPos = vecEyePos + ( vecEyeDir * MAX_TRACE_LENGTH * trace.fraction ); } //m_vecLookCrosshair = vecEndPos; AimGunAt( &vecEndPos, 0.1f ); } StudioFrameAdvance(); // If the enter or exit animation has finished, tell the server vehicle if ( IsSequenceFinished() && (m_bExitAnimOn || m_bEnterAnimOn) ) { if ( m_bEnterAnimOn ) { m_VehiclePhysics.ReleaseHandbrake(); StartEngine(); // HACKHACK: This forces the jeep to play a sound when it gets entered underwater if ( m_VehiclePhysics.IsEngineDisabled() ) { CBaseServerVehicle *pServerVehicle = dynamic_cast<CBaseServerVehicle *>(GetServerVehicle()); if ( pServerVehicle ) { pServerVehicle->SoundStartDisabled(); } } // The first few time we get into the jeep, print the jeep help if ( m_iNumberOfEntries < asw_hud_jeephint_numentries.GetInt() ) { UTIL_HudHintText( m_hPlayer, "#Valve_Hint_JeepKeys" ); m_iNumberOfEntries++; } } // If we're exiting and have had the tau cannon removed, we don't want to reset the animation GetServerVehicle()->HandleEntryExitFinish( m_bExitAnimOn, !(m_bExitAnimOn && TauCannonHasBeenCutOff()) ); } // See if the ammo crate needs to close if ( ( m_flAmmoCrateCloseTime < gpGlobals->curtime ) && ( GetSequence() == LookupSequence( "ammo_open" ) ) ) { m_flAnimTime = gpGlobals->curtime; m_flPlaybackRate = 0.0; SetCycle( 0 ); ResetSequence( LookupSequence( "ammo_close" ) ); } else if ( ( GetSequence() == LookupSequence( "ammo_close" ) ) && IsSequenceFinished() ) { m_flAnimTime = gpGlobals->curtime; m_flPlaybackRate = 0.0; SetCycle( 0 ); ResetSequence( LookupSequence( "idle" ) ); CPASAttenuationFilter sndFilter( this, "PropJeep.AmmoClose" ); EmitSound( sndFilter, entindex(), "PropJeep.AmmoClose" ); } }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : // Notes : Have your derived Helicopter's Spawn() function call this one FIRST //------------------------------------------------------------------------------ void CBaseHelicopter::Spawn( void ) { Precache( ); SetSolid( SOLID_BBOX ); SetMoveType( MOVETYPE_STEP ); AddFlag( FL_FLY ); SetState( NPC_STATE_IDLE ); m_lifeState = LIFE_ALIVE; // motor //****** // All of this stuff is specific to the individual type of aircraft. Handle it yourself. //****** // m_iAmmoType = g_pGameRules->GetAmmoDef()->Index("AR2"); // SetModel( "models/attack_helicopter.mdl" ); // UTIL_SetSize( this, Vector( -32, -32, -64 ), Vector( 32, 32, 0 ) ); // UTIL_SetOrigin( this, GetLocalOrigin() ); // m_iHealth = 100; // m_flFieldOfView = -0.707; // 270 degrees // InitBoneControllers(); // m_iRockets = 10; // Get the rotor sound started up. // This base class assumes the helicopter has no guns or missiles. // Set the appropriate flags in your derived class' Spawn() function. m_fHelicopterFlags &= ~BITS_HELICOPTER_MISSILE_ON; m_fHelicopterFlags &= ~BITS_HELICOPTER_GUN_ON; m_pRotorSound = NULL; m_pRotorBlast = NULL; SetCycle( 0 ); ResetSequenceInfo(); AddFlag( FL_NPC ); m_flMaxSpeed = BASECHOPPER_MAX_SPEED; m_flMaxSpeedFiring = BASECHOPPER_MAX_FIRING_SPEED; m_takedamage = DAMAGE_AIM; // Don't start up if the level designer has asked the // helicopter to start disabled. if ( !(m_spawnflags & SF_AWAITINPUT) ) { Startup(); SetNextThink( gpGlobals->curtime + 1.0f ); } else { m_flStartupTime = FLT_MAX; } InitPathingData( 0, BASECHOPPER_MIN_CHASE_DIST_DIFF, BASECHOPPER_AVOID_DIST ); // Setup collision hull ExpandBBox( m_cullBoxMins, m_cullBoxMaxs ); CollisionProp()->SetSurroundingBoundsType( USE_SPECIFIED_BOUNDS, &m_cullBoxMins, &m_cullBoxMaxs ); AddSolidFlags( FSOLID_CUSTOMRAYTEST | FSOLID_CUSTOMBOXTEST ); m_flRandomOffsetTime = -1.0f; m_vecRandomOffset.Init( 0, 0, 0 ); }
//------------------------------------------------------------------------------ // Purpose: Samples the player's inputs and fires outputs based on what buttons // are currently held down. //------------------------------------------------------------------------------ void CGameUI::Think( void ) { CBasePlayer *pPlayer = m_player; // If player is gone, stop thinking if (pPlayer == NULL) { SetNextThink( TICK_NEVER_THINK ); return; } // If we're forcing an update, state with a clean button state if ( m_bForceUpdate ) { m_nLastButtonState = pPlayer->m_nButtons; } // ------------------------------------------------ // Check that toucher is facing the UI within // the field of view tolerance. If not disconnect // ------------------------------------------------ if (m_flFieldOfView > -1) { Vector vPlayerFacing; pPlayer->EyeVectors( &vPlayerFacing ); Vector vPlayerToUI = GetAbsOrigin() - pPlayer->WorldSpaceCenter(); VectorNormalize(vPlayerToUI); float flDotPr = DotProduct(vPlayerFacing,vPlayerToUI); if (flDotPr < m_flFieldOfView) { Deactivate( pPlayer ); return; } } pPlayer->AddFlag( FL_ONTRAIN ); SetNextThink( gpGlobals->curtime ); // Deactivate if they jump or press +use. // FIXME: prevent the use from going through in player.cpp if ((( pPlayer->m_afButtonPressed & IN_USE ) && ( m_spawnflags & SF_GAMEUI_USE_DEACTIVATES )) || (( pPlayer->m_afButtonPressed & IN_JUMP ) && ( m_spawnflags & SF_GAMEUI_JUMP_DEACTIVATES ))) { Deactivate( pPlayer ); return; } // Determine what's different int nButtonsChanged = ( pPlayer->m_nButtons ^ m_nLastButtonState ); // // Handle all our possible input triggers // if ( nButtonsChanged & IN_MOVERIGHT ) { if ( m_nLastButtonState & IN_MOVERIGHT ) { m_unpressedMoveRight.FireOutput( pPlayer, this, 0 ); } else { m_pressedMoveRight.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_MOVELEFT ) { if ( m_nLastButtonState & IN_MOVELEFT ) { m_unpressedMoveLeft.FireOutput( pPlayer, this, 0 ); } else { m_pressedMoveLeft.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_FORWARD ) { if ( m_nLastButtonState & IN_FORWARD ) { m_unpressedForward.FireOutput( pPlayer, this, 0 ); } else { m_pressedForward.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_BACK ) { if ( m_nLastButtonState & IN_BACK ) { m_unpressedBack.FireOutput( pPlayer, this, 0 ); } else { m_pressedBack.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_ATTACK ) { if ( m_nLastButtonState & IN_ATTACK ) { m_unpressedAttack.FireOutput( pPlayer, this, 0 ); } else { m_pressedAttack.FireOutput( pPlayer, this, 0 ); } } if ( nButtonsChanged & IN_ATTACK2 ) { if ( m_nLastButtonState & IN_ATTACK2 ) { m_unpressedAttack2.FireOutput( pPlayer, this, 0 ); } else { m_pressedAttack2.FireOutput( pPlayer, this, 0 ); } } // Setup for the next frame m_nLastButtonState = pPlayer->m_nButtons; float x = 0, y = 0, attack = 0, attack2 = 0; if ( pPlayer->m_nButtons & IN_MOVERIGHT ) { x = 1; } else if ( pPlayer->m_nButtons & IN_MOVELEFT ) { x = -1; } if ( pPlayer->m_nButtons & IN_FORWARD ) { y = 1; } else if ( pPlayer->m_nButtons & IN_BACK ) { y = -1; } if ( pPlayer->m_nButtons & IN_ATTACK ) { attack = 1; } if ( pPlayer->m_nButtons & IN_ATTACK2 ) { attack2 = 1; } // // Fire the analog outputs if they changed. // if ( m_bForceUpdate || ( m_xaxis.Get() != x ) ) { m_xaxis.Set( x, pPlayer, this ); } if ( m_bForceUpdate || ( m_yaxis.Get() != y ) ) { m_yaxis.Set( y, pPlayer, this ); } if ( m_bForceUpdate || ( m_attackaxis.Get() != attack ) ) { m_attackaxis.Set( attack, pPlayer, this ); } if ( m_bForceUpdate || ( m_attack2axis.Get() != attack2 ) ) { m_attack2axis.Set( attack2, pPlayer, this ); } m_bForceUpdate = false; }
void CApache::NullThink( void ) { StudioFrameAdvance( ); SetNextThink( 0.5 ); }
//========================================================= // SearchThink // This search function will sit with the turret deployed and look for a new target. // After a set amount of time, the barrel will spin down. After m_flMaxWait, the turret will // retact. //========================================================= void CNPC_BaseTurret::SearchThink(void) { // ensure rethink SetTurretAnim(TURRET_ANIM_SPIN); StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1 ); if (m_flSpinUpTime == 0 && m_flMaxSpin) m_flSpinUpTime = gpGlobals->curtime + m_flMaxSpin; Ping( ); CBaseEntity *pEnemy = GetEnemy(); // If we have a target and we're still healthy if (pEnemy != NULL) { if (!pEnemy->IsAlive() ) pEnemy = NULL;// Dead enemy forces a search for new one } // Acquire Target if (pEnemy == NULL) { GetSenses()->Look(TURRET_RANGE); pEnemy = BestEnemy(); if ( pEnemy && !FVisible( pEnemy ) ) pEnemy = NULL; } // If we've found a target, spin up the barrel and start to attack if (pEnemy != NULL) { m_flLastSight = 0; m_flSpinUpTime = 0; SetThink(&CNPC_BaseTurret::ActiveThink); } else { // Are we out of time, do we need to retract? if (gpGlobals->curtime > m_flLastSight) { //Before we retrace, make sure that we are spun down. m_flLastSight = 0; m_flSpinUpTime = 0; SetThink(&CNPC_BaseTurret::Retire); } // should we stop the spin? else if ((m_flSpinUpTime) && (gpGlobals->curtime > m_flSpinUpTime)) { SpinDownCall(); } // generic hunt for new victims m_vecGoalAngles.y = (m_vecGoalAngles.y + 0.1 * m_fTurnRate); if (m_vecGoalAngles.y >= 360) m_vecGoalAngles.y -= 360; MoveTurret(); } SetEnemy( pEnemy ); }
void CApache :: DyingThink( void ) { StudioFrameAdvance( ); SetNextThink( 0.1 ); pev->avelocity = pev->avelocity * 1.02; // still falling? if (m_flNextRocket > gpGlobals->time ) { // random explosions MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin ); WRITE_BYTE( TE_EXPLOSION); // This just makes a dynamic light now WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -150, 150 )); WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -150, 150 )); WRITE_COORD( pev->origin.z + RANDOM_FLOAT( -150, -50 )); WRITE_SHORT( g_sModelIndexFireball ); WRITE_BYTE( RANDOM_LONG(0,29) + 30 ); // scale * 10 WRITE_BYTE( 12 ); // framerate WRITE_BYTE( TE_EXPLFLAG_NONE ); MESSAGE_END(); // lots of smoke MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin ); WRITE_BYTE( TE_SMOKE ); WRITE_COORD( pev->origin.x + RANDOM_FLOAT( -150, 150 )); WRITE_COORD( pev->origin.y + RANDOM_FLOAT( -150, 150 )); WRITE_COORD( pev->origin.z + RANDOM_FLOAT( -150, -50 )); WRITE_SHORT( g_sModelIndexSmoke ); WRITE_BYTE( 100 ); // scale * 10 WRITE_BYTE( 10 ); // framerate MESSAGE_END(); Vector vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot ); WRITE_BYTE( TE_BREAKMODEL); // position WRITE_COORD( vecSpot.x ); WRITE_COORD( vecSpot.y ); WRITE_COORD( vecSpot.z ); // size WRITE_COORD( 400 ); WRITE_COORD( 400 ); WRITE_COORD( 132 ); // velocity WRITE_COORD( pev->velocity.x ); WRITE_COORD( pev->velocity.y ); WRITE_COORD( pev->velocity.z ); // randomization WRITE_BYTE( 50 ); // Model WRITE_SHORT( m_iBodyGibs ); //model id# // # of shards WRITE_BYTE( 4 ); // let client decide // duration WRITE_BYTE( 30 );// 3.0 seconds // flags WRITE_BYTE( BREAK_METAL ); MESSAGE_END(); // don't stop it we touch a entity pev->flags &= ~FL_ONGROUND; SetNextThink( 0.2 ); return; } else { Vector vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; /* MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); WRITE_BYTE( TE_EXPLOSION); // This just makes a dynamic light now WRITE_COORD( vecSpot.x ); WRITE_COORD( vecSpot.y ); WRITE_COORD( vecSpot.z + 300 ); WRITE_SHORT( g_sModelIndexFireball ); WRITE_BYTE( 250 ); // scale * 10 WRITE_BYTE( 8 ); // framerate MESSAGE_END(); */ // fireball MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot ); WRITE_BYTE( TE_SPRITE ); WRITE_COORD( vecSpot.x ); WRITE_COORD( vecSpot.y ); WRITE_COORD( vecSpot.z + 256 ); WRITE_SHORT( m_iExplode ); WRITE_BYTE( 120 ); // scale * 10 WRITE_BYTE( 255 ); // brightness MESSAGE_END(); // big smoke MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot ); WRITE_BYTE( TE_SMOKE ); WRITE_COORD( vecSpot.x ); WRITE_COORD( vecSpot.y ); WRITE_COORD( vecSpot.z + 512 ); WRITE_SHORT( g_sModelIndexSmoke ); WRITE_BYTE( 250 ); // scale * 10 WRITE_BYTE( 5 ); // framerate MESSAGE_END(); // blast circle MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, pev->origin ); WRITE_BYTE( TE_BEAMCYLINDER ); WRITE_COORD( pev->origin.x); WRITE_COORD( pev->origin.y); WRITE_COORD( pev->origin.z); WRITE_COORD( pev->origin.x); WRITE_COORD( pev->origin.y); WRITE_COORD( pev->origin.z + 2000 ); // reach damage radius over .2 seconds WRITE_SHORT( m_iSpriteTexture ); WRITE_BYTE( 0 ); // startframe WRITE_BYTE( 0 ); // framerate WRITE_BYTE( 4 ); // life WRITE_BYTE( 32 ); // width WRITE_BYTE( 0 ); // noise WRITE_BYTE( 255 ); // r, g, b WRITE_BYTE( 255 ); // r, g, b WRITE_BYTE( 192 ); // r, g, b WRITE_BYTE( 128 ); // brightness WRITE_BYTE( 0 ); // speed MESSAGE_END(); EMIT_SOUND(ENT(pev), CHAN_STATIC, "weapons/mortarhit.wav", 1.0, 0.3); RadiusDamage( pev->origin, pev, pev, 300, CLASS_NONE, DMG_BLAST ); if (/*!(pev->spawnflags & SF_NOWRECKAGE) && */(pev->flags & FL_ONGROUND)) { CBaseEntity *pWreckage = Create( "cycler_wreckage", pev->origin, pev->angles ); // SET_MODEL( ENT(pWreckage->pev), STRING(pev->model) ); UTIL_SetSize( pWreckage->pev, Vector( -200, -200, -128 ), Vector( 200, 200, -32 ) ); pWreckage->pev->frame = pev->frame; pWreckage->pev->sequence = pev->sequence; pWreckage->pev->framerate = 0; pWreckage->pev->dmgtime = gpGlobals->time + 5; } // gibs vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot ); WRITE_BYTE( TE_BREAKMODEL); // position WRITE_COORD( vecSpot.x ); WRITE_COORD( vecSpot.y ); WRITE_COORD( vecSpot.z + 64); // size WRITE_COORD( 400 ); WRITE_COORD( 400 ); WRITE_COORD( 128 ); // velocity WRITE_COORD( 0 ); WRITE_COORD( 0 ); WRITE_COORD( 200 ); // randomization WRITE_BYTE( 30 ); // Model WRITE_SHORT( m_iBodyGibs ); //model id# // # of shards WRITE_BYTE( 200 ); // duration WRITE_BYTE( 200 );// 10.0 seconds // flags WRITE_BYTE( BREAK_METAL ); MESSAGE_END(); SetThink(&CApache :: SUB_Remove ); SetNextThink( 0.1 ); } }
void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { // if it's not a player, ignore if ( !pActivator->IsPlayer() ) return; // if there is no juice left, turn it off if (m_iJuice <= 0) { SetTextureFrameIndex( 1 ); Off(); } // if the player doesn't have the suit, or there is no juice left, make the deny noise if ( m_iJuice <= 0 ) { if (m_flSoundTime <= gpGlobals->curtime) { m_flSoundTime = gpGlobals->curtime + 0.62; EmitSound( "SuitRecharge.Deny" ); } return; } SetNextThink( gpGlobals->curtime + 0.25 ); SetThink(Off); // Time to recharge yet? if (m_flNextCharge >= gpGlobals->curtime) return; // Make sure that we have a caller if (!pActivator) return; m_hActivator = pActivator; //only recharge the player if (!m_hActivator->IsPlayer() ) return; // Play the on sound or the looping charging sound if (!m_iOn) { m_iOn++; EmitSound( "SuitRecharge.Start" ); m_flSoundTime = 0.56 + gpGlobals->curtime; } if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->curtime)) { m_iOn++; CPASAttenuationFilter filter( this, "SuitRecharge.ChargingLoop" ); filter.MakeReliable(); EmitSound( filter, entindex(), "SuitRecharge.ChargingLoop" ); } CBasePlayer *pl = (CBasePlayer *) m_hActivator.Get(); // charge the player if (pl->ArmorValue() < 100) { m_iJuice--; pl->IncrementArmorValue( 1, 100 ); } // Send the output. float flRemaining = m_iJuice / sk_suitcharger.GetFloat(); m_OutRemainingCharge.Set(flRemaining, pActivator, this); // govern the rate of charge m_flNextCharge = gpGlobals->curtime + 0.1; }
void CApache :: HuntThink( void ) { StudioFrameAdvance( ); SetNextThink( 0.1 ); ShowDamage( ); if ( m_pGoalEnt == NULL && !FStringNull(pev->target) )// this monster has a target { m_pGoalEnt = UTIL_FindEntityByTargetname( NULL, STRING( pev->target ) ); if (m_pGoalEnt) { m_posDesired = m_pGoalEnt->pev->origin; UTIL_MakeAimVectors( m_pGoalEnt->pev->angles ); m_vecGoal = gpGlobals->v_forward; } } // if (m_hEnemy == NULL) { Look( 4092 ); m_hEnemy = BestVisibleEnemy( ); } // generic speed up if (m_flGoalSpeed < 800) m_flGoalSpeed += 5; if (m_hEnemy != NULL) { // ALERT( at_console, "%s\n", STRING( m_hEnemy->pev->classname ) ); if (FVisible( m_hEnemy )) { if (m_flLastSeen < gpGlobals->time - 5) m_flPrevSeen = gpGlobals->time; m_flLastSeen = gpGlobals->time; m_posTarget = m_hEnemy->Center( ); } else { m_hEnemy = NULL; } } m_vecTarget = (m_posTarget - pev->origin).Normalize(); float flLength = (pev->origin - m_posDesired).Length(); if (m_pGoalEnt) { // ALERT( at_console, "%.0f\n", flLength ); if (flLength < 128) { m_pGoalEnt = UTIL_FindEntityByTargetname( NULL, STRING( m_pGoalEnt->pev->target ) ); if (m_pGoalEnt) { m_posDesired = m_pGoalEnt->pev->origin; UTIL_MakeAimVectors( m_pGoalEnt->pev->angles ); m_vecGoal = gpGlobals->v_forward; flLength = (pev->origin - m_posDesired).Length(); } } } else { m_posDesired = pev->origin; } if (flLength > 250) // 500 { // float flLength2 = (m_posTarget - pev->origin).Length() * (1.5 - DotProduct((m_posTarget - pev->origin).Normalize(), pev->velocity.Normalize() )); // if (flLength2 < flLength) if (m_flLastSeen + 90 > gpGlobals->time && DotProduct( (m_posTarget - pev->origin).Normalize(), (m_posDesired - pev->origin).Normalize( )) > 0.25) { m_vecDesired = (m_posTarget - pev->origin).Normalize( ); } else { m_vecDesired = (m_posDesired - pev->origin).Normalize( ); } } else { m_vecDesired = m_vecGoal; } Flight( ); // ALERT( at_console, "%.0f %.0f %.0f\n", gpGlobals->time, m_flLastSeen, m_flPrevSeen ); if ((m_flLastSeen + 1 > gpGlobals->time) && (m_flPrevSeen + 2 < gpGlobals->time)) { if (FireGun( )) { // slow down if we're fireing if (m_flGoalSpeed > 400) m_flGoalSpeed = 400; } // don't fire rockets and gun on easy mode if (g_iSkillLevel == SKILL_EASY) m_flNextRocket = gpGlobals->time + 10.0; } UTIL_MakeAimVectors( pev->angles ); Vector vecEst = (gpGlobals->v_forward * 800 + pev->velocity).Normalize( ); // ALERT( at_console, "%d %d %d %4.2f\n", pev->angles.x < 0, DotProduct( pev->velocity, gpGlobals->v_forward ) > -100, m_flNextRocket < gpGlobals->time, DotProduct( m_vecTarget, vecEst ) ); if ((m_iRockets % 2) == 1) { FireRocket( ); m_flNextRocket = gpGlobals->time + 0.5; if (m_iRockets <= 0) { m_flNextRocket = gpGlobals->time + 10; m_iRockets = 10; } } else if (pev->angles.x < 0 && DotProduct( pev->velocity, gpGlobals->v_forward ) > -100 && m_flNextRocket < gpGlobals->time) { if (m_flLastSeen + 60 > gpGlobals->time) { if (m_hEnemy != NULL) { // make sure it's a good shot if (DotProduct( m_vecTarget, vecEst) > .965) { TraceResult tr; UTIL_TraceLine( pev->origin, pev->origin + vecEst * 4096, ignore_monsters, edict(), &tr ); if ((tr.vecEndPos - m_posTarget).Length() < 512) FireRocket( ); } } else { TraceResult tr; UTIL_TraceLine( pev->origin, pev->origin + vecEst * 4096, dont_ignore_monsters, edict(), &tr ); // just fire when close if ((tr.vecEndPos - m_posTarget).Length() < 512) FireRocket( ); } } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CAPCController::ActivateRocketGuidance(void) { m_spawnflags |= SF_TANK_ACTIVE; SetNextThink( gpGlobals->curtime + 0.1f ); }
void CASW_Health_Regen::Spawn() { BaseClass::Spawn(); SetNextThink( gpGlobals->curtime ); // Think now }
// Timed grenade, this think is called when time runs out. void CGrenade::DetonateUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { SetThink(&CGrenade:: Detonate ); SetNextThink( 0 ); }
void CASW_Health_Regen::Think() { BaseClass::Think(); CBaseEntity* pEntity = NULL; while ((pEntity = gEntList.FindEntityByClassname( pEntity, "asw_marine" )) != NULL) { CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(pEntity); if (pMarine) { int cur_health = pMarine->GetHealth(); int max_health = pMarine->GetMaxHealth(); int regen_ammount = rm_health_regen_amount.GetInt(); if (cur_health < max_health) { //Check if this marine is dead. if (cur_health < 1) continue; int result_health = cur_health + regen_ammount; if (result_health > max_health) result_health = max_health; // if (pMarine->m_bKnockedOut) // { // result_health = cur_health - 3; // if (result_health <= 0) // { // CTakeDamageInfo info( // pMarine, // pMarine, // Vector(0,0,0), // GetAbsOrigin(), // 100, // DMG_NEVERGIB); // pMarine->TakeDamage(info); // } // else // { // pMarine->SetHealth(result_health); // } // } // else // { if (!pMarine->m_bKnockedOut && ASWGameRules()->m_iHpRegen) pMarine->SetHealth(result_health); // riflemod: incapacitated marines have decreasing hp if (pMarine->m_bKnockedOut) { int decreased_hp = pMarine->GetHealth() - rm_health_decrease_amount.GetInt(); if (decreased_hp <= 0) { pMarine->SetKnockedOut(false); pMarine->SetHealth(1); // HACK int allow_revive = ASWGameRules()->m_iAllowRevive; ASWGameRules()->m_iAllowRevive = 0; CTakeDamageInfo info(this, this, Vector(0, 0, 0), GetAbsOrigin(), 100, DMG_NEVERGIB); pMarine->TakeDamage(info); ASWGameRules()->m_iAllowRevive = allow_revive; } else pMarine->SetHealth(decreased_hp); } // } } } } SetNextThink( gpGlobals->curtime + rm_health_regen_interval.GetFloat()); }
//----------------------------------------------------------------------------- // Purpose: Intercept damage and decide whether or not we want to trigger // Input : &info - //----------------------------------------------------------------------------- int CWeaponStriderBuster::OnTakeDamage( const CTakeDamageInfo &info ) { // If we're attached, any damage from the player makes us trigger CBaseEntity *pInflictor = info.GetInflictor(); CBaseEntity *pAttacker = info.GetAttacker(); bool bInflictorIsPlayer = ( pInflictor != NULL && pInflictor->IsPlayer() ); bool bAttackerIsPlayer = ( pAttacker != NULL && pAttacker->IsPlayer() ); if ( GetParent() && GetParent()->ClassMatches( g_iszVehicle ) ) { return 0; } // Only take damage from a player, for the moment if ( striderbuster_allow_all_damage.GetBool() || ( IsAttachedToStrider() && ( bAttackerIsPlayer || bInflictorIsPlayer ) ) ) { Detonate(); return 0; } if ( pAttacker && ( pAttacker->Classify() == CLASS_COMBINE || pAttacker->Classify() == CLASS_COMBINE_HUNTER ) ) { if ( VPhysicsGetObject() && !VPhysicsGetObject()->IsMoveable() ) { return 0; } } // Hunters are able to destroy strider busters if ( hunter_hate_held_striderbusters.GetBool() || hunter_hate_thrown_striderbusters.GetBool() || hunter_hate_attached_striderbusters.GetBool() ) { if ( ( GetHealth() > 0 ) && ( pInflictor != NULL ) && FClassnameIs( pInflictor, "hunter_flechette" ) ) { // // Flechette impacts don't hurt the striderbuster unless it's attached to a strider, // but the explosions always do. This is so that held or thrown striderbusters fly // awry because of the flechette, but attached striderbusters break instantly to make // the hunters more effective at defending the strider. // if ( IsAttachedToStrider() || !( info.GetDamageType() & DMG_NEVERGIB ) ) { if( striderbuster_die_detach.GetBool() && IsAttachedToStrider() ) { // Make the buster fall off and break. m_takedamage = DAMAGE_NO; CNPC_Strider *pStrider = dynamic_cast<CNPC_Strider *>(GetOwnerEntity()); Assert( pStrider != NULL ); pStrider->StriderBusterDetached( this ); DestroyConstraint(); // Amplify some lateral force. Vector vecForce = info.GetDamageForce(); vecForce.z = 0.0f; VPhysicsGetObject()->ApplyForceCenter( vecForce * 5.0f ); SetContextThink( NULL, gpGlobals->curtime, s_pBusterPingThinkContext ); SetThink( &CWeaponStriderBuster::BusterDetachThink ); SetNextThink( gpGlobals->curtime ); m_iBusterFlags |= STRIDERBUSTER_FLAG_KNOCKED_OFF_STRIDER; return 0; } else { // Destroy the buster in place // Make sure they know it blew up prematurely. EmitSound( "Weapon_StriderBuster.Dud_Detonate" ); DispatchParticleEffect( "striderbuster_break_flechette", GetAbsOrigin(), GetAbsAngles() ); SetHealth( 0 ); Shatter( info.GetAttacker() ); return 0; } } if ( info.GetDamage() < 5 ) { bool bFirst = ( m_CarryAngles.x == 45 && m_CarryAngles.y == 0 && m_CarryAngles.z == 0); float sinTime = sin( gpGlobals->curtime ); bool bSubtractX = ( bFirst ) ? ( sinTime < 0 ) : ( m_CarryAngles.x < 45 ); m_CarryAngles.x += ( 10.0 + 10.0 * fabsf( sinTime ) + random->RandomFloat( -2.5, 2.5 ) + random->RandomFloat( -2.5, 2.5 ) ) * ( ( bSubtractX ) ? -1.0 : 1.0 ); m_CarryAngles.y = 15 * ( sin( gpGlobals->curtime ) + cos( gpGlobals->curtime * 0.5 ) ) * .5 + random->RandomFloat( -15, 15 ); m_CarryAngles.z = 7.5 * ( sin( gpGlobals->curtime ) + sin( gpGlobals->curtime * 2.0 ) ) * .5 + random->RandomFloat( -7.5, 7.5 ); } return 1; } } // Allow crushing damage if ( info.GetDamageType() & DMG_CRUSH ) return BaseClass::OnTakeDamage( info ); return 0; }
//--------------------------------------------------------- // Count of all the weapons in the world of my type and // see if we have a surplus. If there is a surplus, try // to find suitable candidates for removal. // // Right now we just remove the first weapons we find that // are behind the player, or are out of the player's PVS. // Later, we may want to score the results so that we // removed the farthest gun that's not in the player's // viewcone, etc. // // Some notes and thoughts: // // This code is designed NOT to remove weapons that are // hand-placed by level designers. It should only clean // up weapons dropped by dead NPCs, which is useful in // situations where enemies are spawned in for a sustained // period of time. // // Right now we PREFER to remove weapons that are not in the // player's PVS, but this could be opposite of what we // really want. We may only want to conduct the cleanup on // weapons that are IN the player's PVS. //--------------------------------------------------------- void CGameWeaponManager::Think() { int i; // Don't have to think all that often. SetNextThink( gpGlobals->curtime + 2.0 ); const char *pszWeaponName = STRING( m_iszWeaponName ); CUtlVector<CBaseEntity *> candidates( 0, 64 ); if ( m_bExpectingWeapon ) { CBaseCombatWeapon *pWeapon = NULL; // Firstly, count the total number of weapons of this type in the world. // Also count how many of those can potentially be removed. pWeapon = assert_cast<CBaseCombatWeapon *>(gEntList.FindEntityByClassname( pWeapon, pszWeaponName )); while( pWeapon ) { if( !pWeapon->IsEffectActive( EF_NODRAW ) && pWeapon->IsRemoveable() ) { candidates.AddToTail( pWeapon ); } pWeapon = assert_cast<CBaseCombatWeapon *>(gEntList.FindEntityByClassname( pWeapon, pszWeaponName )); } } else { for ( i = 0; i < m_ManagedNonWeapons.Count(); i++) { CBaseEntity *pEntity = m_ManagedNonWeapons[i]; if ( pEntity ) { Assert( pEntity->m_iClassname == m_iszWeaponName ); if ( !pEntity->IsEffectActive( EF_NODRAW ) ) { candidates.AddToTail( pEntity ); } } else { m_ManagedNonWeapons.FastRemove( i-- ); } } } // Calculate the surplus. int surplus = candidates.Count() - m_iMaxPieces; // Based on what the player can see, try to clean up the world by removing weapons that // the player cannot see right at the moment. CBaseEntity *pCandidate; for ( i = 0; i < candidates.Count() && surplus > 0; i++ ) { bool fRemovedOne = false; pCandidate = candidates[i]; Assert( !pCandidate->IsEffectActive( EF_NODRAW ) ); // if ( gpGlobals->maxClients == 1 ) { CBasePlayer *pPlayer = UTIL_GetNearestVisiblePlayer(pCandidate); // Nodraw serves as a flag that this weapon is already being removed since // all we're really doing inside this loop is marking them for removal by // the entity system. We don't want to count the same weapon as removed // more than once. if( !UTIL_FindClientInPVS( pCandidate->edict() ) ) { fRemovedOne = true; } else if( !pPlayer->FInViewCone( pCandidate ) ) { fRemovedOne = true; } else if ( UTIL_DistApprox( pPlayer->GetAbsOrigin(), pCandidate->GetAbsOrigin() ) > (30*12) ) { fRemovedOne = true; } } // else // { // fRemovedOne = true; // } if( fRemovedOne ) { pCandidate->AddEffects( EF_NODRAW ); UTIL_Remove( pCandidate ); DevMsg( 2, "Surplus %s removed\n", pszWeaponName); surplus--; } } }