//----------------------------------------------------------------------------- // Purpose: The turret has been tipped over and will thrash for awhile //----------------------------------------------------------------------------- void CNPC_Portal_FloorTurret::TippedThink( void ) { PreThink( TURRET_TIPPED ); SetNextThink( gpGlobals->curtime + 0.05f ); SetEnemy( NULL ); StudioFrameAdvance(); // If we're not on side anymore, stop thrashing if ( !OnSide() && VPhysicsGetObject()->GetContactPoint( NULL, NULL ) ) { ReturnToLife(); return; } LaserOn(); RopesOn(); //See if we should continue to thrash if ( gpGlobals->curtime < m_flThrashTime && !IsDissolving() ) { if ( m_flShotTime < gpGlobals->curtime ) { if( m_bOutOfAmmo ) { SetActivity( (Activity) ACT_FLOOR_TURRET_OPEN_IDLE ); DryFire(); } else { Vector vecMuzzle, vecMuzzleDir; GetAttachment( m_iMuzzleAttachment, vecMuzzle, &vecMuzzleDir ); SetActivity( (Activity) ACT_FLOOR_TURRET_OPEN_IDLE ); SetActivity( (Activity)( ( m_bShootWithBottomBarrels ) ? ( ACT_FLOOR_TURRET_FIRE2 ) : ( ACT_FLOOR_TURRET_FIRE ) ) ); #if !DISABLE_SHOT Shoot( vecMuzzle, vecMuzzleDir ); #endif } m_flShotTime = gpGlobals->curtime + 0.05f; } m_vecGoalAngles.x = GetAbsAngles().x + random->RandomFloat( -60, 60 ); m_vecGoalAngles.y = GetAbsAngles().y + random->RandomFloat( -60, 60 ); UpdateFacing(); } else { //Face forward m_vecGoalAngles = GetAbsAngles(); //Set ourselves to close if ( GetActivity() != ACT_FLOOR_TURRET_CLOSE ) { SetActivity( (Activity) ACT_FLOOR_TURRET_OPEN_IDLE ); //If we're done moving to our desired facing, close up if ( UpdateFacing() == false ) { //Make any last death noises and anims EmitSound( "NPC_FloorTurret.Die" ); EmitSound( GetTurretTalkName( PORTAL_TURRET_DISABLED ) ); SpinDown(); SetActivity( (Activity) ACT_FLOOR_TURRET_CLOSE ); EmitSound( "NPC_FloorTurret.Retract" ); CTakeDamageInfo info; info.SetDamage( 1 ); info.SetDamageType( DMG_CRUSH ); Event_Killed( info ); } } else if ( IsActivityFinished() ) { m_bActive = false; m_flLastSight = 0; SetActivity( (Activity) ACT_FLOOR_TURRET_CLOSED_IDLE ); // Don't need to store last NPC anymore, because I've been knocked over if ( m_hLastNPCToKickMe ) { m_hLastNPCToKickMe = NULL; m_flKnockOverFailedTime = 0; } //Try to look straight if ( UpdateFacing() == false ) { m_OnTipped.FireOutput( this, this ); SetEyeState( TURRET_EYE_DEAD ); //SetCollisionGroup( COLLISION_GROUP_DEBRIS_TRIGGER ); // Start thinking slowly to see if we're ever set upright somehow SetThink( &CNPC_FloorTurret::InactiveThink ); SetNextThink( gpGlobals->curtime + 1.0f ); RopesOff(); } } } }
void CBaseTurret::ActiveThink(void) { int fAttack = 0; Vector vecDirToEnemy; pev->nextthink = gpGlobals->time + 0.1; StudioFrameAdvance( ); if ((!m_iOn) || (m_hEnemy == NULL)) { m_hEnemy = NULL; m_flLastSight = gpGlobals->time + m_flMaxWait; SetThink(&CBaseTurret::SearchThink); return; } // if it's dead, look for something new if ( !m_hEnemy->IsAlive() ) { if (!m_flLastSight) { m_flLastSight = gpGlobals->time + 0.5; // continue-shooting timeout } else { if (gpGlobals->time > m_flLastSight) { m_hEnemy = NULL; m_flLastSight = gpGlobals->time + m_flMaxWait; SetThink(&CBaseTurret::SearchThink); return; } } } Vector vecMid = pev->origin + pev->view_ofs; Vector vecMidEnemy = m_hEnemy->BodyTarget( vecMid ); // Look for our current enemy int fEnemyVisible = FBoxVisible(pev, m_hEnemy->pev, vecMidEnemy ); vecDirToEnemy = vecMidEnemy - vecMid; // calculate dir and dist to enemy float flDistToEnemy = vecDirToEnemy.Length(); Vector vec = UTIL_VecToAngles(vecMidEnemy - vecMid); // Current enmey is not visible. if (!fEnemyVisible || (flDistToEnemy > TURRET_RANGE)) { if (!m_flLastSight) m_flLastSight = gpGlobals->time + 0.5; else { // Should we look for a new target? if (gpGlobals->time > m_flLastSight) { m_hEnemy = NULL; m_flLastSight = gpGlobals->time + m_flMaxWait; SetThink(&CBaseTurret::SearchThink); return; } } fEnemyVisible = 0; } else { m_vecLastSight = vecMidEnemy; } UTIL_MakeAimVectors(m_vecCurAngles); /* 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 = vecDirToEnemy; //vecMid - m_vecLastSight; vecLOS = vecLOS.Normalize(); // Is the Gun looking at the target if (DotProduct(vecLOS, gpGlobals->v_forward) <= 0.866) // 30 degree slop fAttack = FALSE; else fAttack = TRUE; // fire the gun if (m_iSpin && ((fAttack) || (m_fBeserk))) { Vector vecSrc, vecAng; GetAttachment( 0, vecSrc, vecAng ); SetTurretAnim(TURRET_ANIM_FIRE); Shoot(vecSrc, gpGlobals->v_forward ); } else { SetTurretAnim(TURRET_ANIM_SPIN); } //move the gun if (m_fBeserk) { if (RANDOM_LONG(0,9) == 0) { m_vecGoalAngles.y = RANDOM_FLOAT(0,360); m_vecGoalAngles.x = RANDOM_FLOAT(0,90) - 90 * m_iOrientation; TakeDamage(pev,pev,1, DMG_GENERIC); // don't beserk forever return; } } else if (fEnemyVisible) { if (vec.y > 360) vec.y -= 360; if (vec.y < 0) vec.y += 360; //ALERT(at_console, "[%.2f]", vec.x); if (vec.x < -180) vec.x += 360; if (vec.x > 180) vec.x -= 360; // now all numbers should be in [1...360] // pin to turret limitations to [-90...15] if (m_iOrientation == 0) { if (vec.x > 90) vec.x = 90; else if (vec.x < m_iMinPitch) vec.x = m_iMinPitch; } else { if (vec.x < -90) vec.x = -90; else if (vec.x > -m_iMinPitch) vec.x = -m_iMinPitch; } // ALERT(at_console, "->[%.2f]\n", vec.x); m_vecGoalAngles.y = vec.y; m_vecGoalAngles.x = vec.x; } SpinUpCall(); MoveTurret(); }
//------------------------------------------------------------------------------ // Purpose: //------------------------------------------------------------------------------ void CTeamControlPoint::AnimThink( void ) { StudioFrameAdvance(); DispatchAnimEvents(this); SetNextThink( gpGlobals->curtime + 0.1f ); }
void CASW_Queen_Divers::AnimThink( void ) { SetNextThink( gpGlobals->curtime + 0.1f ); StudioFrameAdvance(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPropJeep::Think(void) { BaseClass::Think(); /* CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); if ( m_bEngineLocked ) { m_bUnableToFire = true; if ( pPlayer != NULL ) { pPlayer->m_Local.m_iHideHUD |= HIDEHUD_VEHICLE_CROSSHAIR; } } else { // 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 < 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, true ); } // 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" ); } }
//========================================================= //========================================================= void CBarnacle :: BarnacleThink ( void ) { CBaseEntity *pTouchEnt; CBaseMonster *pVictim; float flLength; pev->nextthink = gpGlobals->time + 0.1; if ( m_hEnemy != NULL ) { // barnacle has prey. if ( !m_hEnemy->IsAlive() ) { // someone (maybe even the barnacle) killed the prey. Reset barnacle. m_fLiftingPrey = FALSE;// indicate that we're not lifting prey. m_hEnemy = NULL; return; } if ( m_fLiftingPrey ) { if ( m_hEnemy != NULL && m_hEnemy->pev->deadflag != DEAD_NO ) { // crap, someone killed the prey on the way up. m_hEnemy = NULL; m_fLiftingPrey = FALSE; return; } // still pulling prey. Vector vecNewEnemyOrigin = m_hEnemy->pev->origin; vecNewEnemyOrigin.x = pev->origin.x; vecNewEnemyOrigin.y = pev->origin.y; // guess as to where their neck is vecNewEnemyOrigin.x -= 6 * cos(m_hEnemy->pev->angles.y * M_PI/180.0); vecNewEnemyOrigin.y -= 6 * sin(m_hEnemy->pev->angles.y * M_PI/180.0); m_flAltitude -= BARNACLE_PULL_SPEED; vecNewEnemyOrigin.z += BARNACLE_PULL_SPEED; if ( fabs( pev->origin.z - ( vecNewEnemyOrigin.z + m_hEnemy->pev->view_ofs.z - 8 ) ) < BARNACLE_BODY_HEIGHT ) { // prey has just been lifted into position ( if the victim origin + eye height + 8 is higher than the bottom of the barnacle, it is assumed that the head is within barnacle's body ) m_fLiftingPrey = FALSE; EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_bite3.wav", 1, ATTN_NORM ); pVictim = m_hEnemy->MyMonsterPointer(); m_flKillVictimTime = gpGlobals->time + 10;// now that the victim is in place, the killing bite will be administered in 10 seconds. if ( pVictim ) { pVictim->BarnacleVictimBitten( pev ); SetActivity ( ACT_EAT ); } } UTIL_SetOrigin ( m_hEnemy->pev, vecNewEnemyOrigin ); } else { // prey is lifted fully into feeding position and is dangling there. pVictim = m_hEnemy->MyMonsterPointer(); if ( m_flKillVictimTime != -1 && gpGlobals->time > m_flKillVictimTime ) { // kill! if ( pVictim ) { pVictim->TakeDamage ( pev, pev, pVictim->pev->health, DMG_SLASH | DMG_ALWAYSGIB ); m_cGibs = 3; } return; } // bite prey every once in a while if ( pVictim && ( RANDOM_LONG(0,49) == 0 ) ) { switch ( RANDOM_LONG(0,2) ) { case 0: EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew1.wav", 1, ATTN_NORM ); break; case 1: EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew2.wav", 1, ATTN_NORM ); break; case 2: EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew3.wav", 1, ATTN_NORM ); break; } pVictim->BarnacleVictimBitten( pev ); } } } else { // barnacle has no prey right now, so just idle and check to see if anything is touching the tongue. // If idle and no nearby client, don't think so often if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) ) pev->nextthink = gpGlobals->time + RANDOM_FLOAT(1,1.5); // Stagger a bit to keep barnacles from thinking on the same frame if ( m_fSequenceFinished ) {// this is done so barnacle will fidget. SetActivity ( ACT_IDLE ); m_flTongueAdj = -100; } if ( m_cGibs && RANDOM_LONG(0,99) == 1 ) { // cough up a gib. CGib::SpawnRandomGibs( pev, 1, 1 ); m_cGibs--; switch ( RANDOM_LONG(0,2) ) { case 0: EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew1.wav", 1, ATTN_NORM ); break; case 1: EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew2.wav", 1, ATTN_NORM ); break; case 2: EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_chew3.wav", 1, ATTN_NORM ); break; } } pTouchEnt = TongueTouchEnt( &flLength ); if ( pTouchEnt != NULL && m_fTongueExtended ) { // tongue is fully extended, and is touching someone. if ( pTouchEnt->FBecomeProne() ) { EMIT_SOUND( ENT(pev), CHAN_WEAPON, "barnacle/bcl_alert2.wav", 1, ATTN_NORM ); SetSequenceByName ( "attack1" ); m_flTongueAdj = -20; m_hEnemy = pTouchEnt; pTouchEnt->pev->movetype = MOVETYPE_FLY; pTouchEnt->pev->velocity = g_vecZero; pTouchEnt->pev->basevelocity = g_vecZero; pTouchEnt->pev->origin.x = pev->origin.x; pTouchEnt->pev->origin.y = pev->origin.y; m_fLiftingPrey = TRUE;// indicate that we should be lifting prey. m_flKillVictimTime = -1;// set this to a bogus time while the victim is lifted. m_flAltitude = (pev->origin.z - pTouchEnt->EyePosition().z); } } else { // calculate a new length for the tongue to be clear of anything else that moves under it. if ( m_flAltitude < flLength ) { // if tongue is higher than is should be, lower it kind of slowly. m_flAltitude += BARNACLE_PULL_SPEED; m_fTongueExtended = FALSE; } else { m_flAltitude = flLength; m_fTongueExtended = TRUE; } } } // ALERT( at_console, "tounge %f\n", m_flAltitude + m_flTongueAdj ); SetBoneController( 0, -(m_flAltitude + m_flTongueAdj) ); StudioFrameAdvance( 0.1 ); }
void CXenPLight :: Think( void ) { StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; }
void CApache :: DyingThink( void ) { StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 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; pev->nextthink = gpGlobals->time + 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(); //modif de jULIEN pev->deadflag = DEAD_DEAD; FCheckAITrigger(); //========= SetThink( SUB_Remove ); pev->nextthink = gpGlobals->time + 0.1; } }
void CApache :: HuntThink( void ) { StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 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( ); } } } }
void CApache::NullThink( void ) { StudioFrameAdvance( ); SetNextThink( 0.5 ); }
void CApache::NullThink( void ) { StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 0.5; }
void CLeech::UpdateMotion( void ) { float flapspeed = (pev->speed - m_flAccelerate) / LEECH_ACCELERATE; m_flAccelerate = m_flAccelerate * 0.8 + pev->speed * 0.2; if (flapspeed < 0) flapspeed = -flapspeed; flapspeed += 1.0; if (flapspeed < 0.5) flapspeed = 0.5; if (flapspeed > 1.9) flapspeed = 1.9; pev->framerate = flapspeed; if ( !m_fPathBlocked ) pev->avelocity.y = pev->ideal_yaw; else pev->avelocity.y = pev->ideal_yaw * m_obstacle; if ( pev->avelocity.y > 150 ) m_IdealActivity = ACT_TURN_LEFT; else if ( pev->avelocity.y < -150 ) m_IdealActivity = ACT_TURN_RIGHT; else m_IdealActivity = ACT_SWIM; // lean float targetPitch, delta; delta = m_height - GetAbsOrigin().z; if ( delta < -10 ) targetPitch = -30; else if ( delta > 10 ) targetPitch = 30; else targetPitch = 0; pev->angles.x = UTIL_Approach( targetPitch, pev->angles.x, 60 * LEECH_FRAMETIME ); // bank pev->avelocity.z = - (pev->angles.z + (pev->avelocity.y * 0.25)); if ( m_MonsterState == MONSTERSTATE_COMBAT && HasConditions( bits_COND_CAN_MELEE_ATTACK1 ) ) m_IdealActivity = ACT_MELEE_ATTACK1; // Out of water check if ( !GetWaterLevel() ) { pev->movetype = MOVETYPE_TOSS; m_IdealActivity = ACT_TWITCH; pev->velocity = g_vecZero; // Animation will intersect the floor if either of these is non-zero pev->angles.z = 0; pev->angles.x = 0; if ( pev->framerate < 1.0 ) pev->framerate = 1.0; } else if ( pev->movetype == MOVETYPE_TOSS ) { pev->movetype = MOVETYPE_FLY; pev->flags &= ~FL_ONGROUND; RecalculateWaterlevel(); m_waterTime = gpGlobals->time + 2; // Recalc again soon, water may be rising } if ( m_Activity != m_IdealActivity ) { SetActivity ( m_IdealActivity ); } float flInterval = StudioFrameAdvance(); DispatchAnimEvents ( flInterval ); #if DEBUG_BEAMS if ( !m_pb ) m_pb = CBeam::BeamCreate( "sprites/laserbeam.spr", 5 ); if ( !m_pt ) m_pt = CBeam::BeamCreate( "sprites/laserbeam.spr", 5 ); m_pb->PointsInit( GetAbsOrigin(), GetAbsOrigin() + gpGlobals->v_forward * LEECH_CHECK_DIST ); m_pt->PointsInit( GetAbsOrigin(), GetAbsOrigin() - gpGlobals->v_right * (pev->avelocity.y*0.25) ); if ( m_fPathBlocked ) { float color = m_obstacle * 30; if ( m_obstacle == 1.0 ) color = 0; if ( color > 255 ) color = 255; m_pb->SetColor( 255, (int)color, (int)color ); } else m_pb->SetColor( 255, 255, 0 ); m_pt->SetColor( 0, 0, 255 ); #endif }
//--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::SearchThink() { if( !UTIL_FindClientInPVS(edict()) ) { // Sleep! SetNextThink( gpGlobals->curtime + 0.5 ); return; } if( (CAI_BaseNPC::m_nDebugBits & bits_debugDisableAI) ) { if( IsAwake() ) { Wake(false); } SetNextThink( gpGlobals->curtime + 0.5 ); return; } SetNextThink( gpGlobals->curtime + 0.1 ); StudioFrameAdvance(); if( m_pConstraint && gpGlobals->curtime - m_flTimeGrabbed >= 1.0f ) { m_OnPulledUp.FireOutput( this, this ); SetMineState( MINE_STATE_CAPTIVE ); return; } float flNearestNPCDist = FindNearestNPC(); if( flNearestNPCDist <= BOUNCEBOMB_WARN_RADIUS ) { if( !IsAwake() ) { Wake( true ); } } else { if( IsAwake() ) { Wake( false ); } return; } if( flNearestNPCDist <= BOUNCEBOMB_DETONATE_RADIUS && !IsFriend( m_hNearestNPC ) ) { if( m_bBounce ) { SetMineState( MINE_STATE_TRIGGERED ); } else { // Don't pop up in the air, just explode if the NPC gets closer than explode radius. SetThink( &CBounceBomb::ExplodeThink ); SetNextThink( gpGlobals->curtime + m_flExplosionDelay ); } } }
//--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::SettleThink() { SetNextThink( gpGlobals->curtime + 0.05 ); StudioFrameAdvance(); if( GetParent() ) { // A scanner or something is carrying me. Just keep checking back. return; } // Not being carried. if( !VPhysicsGetObject() ) { // Probably was just dropped. Get physics going. CreateVPhysics(); if( !VPhysicsGetObject() ) { Msg("**** Can't create vphysics for combine_mine!\n" ); UTIL_Remove( this ); return; } VPhysicsGetObject()->Wake(); return; } if( !m_bDisarmed ) { if( VPhysicsGetObject()->IsAsleep() && !(VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD) ) { // If i'm not resting on the world, jump randomly. trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector( 0, 0, 1024 ), MASK_SHOT|CONTENTS_GRATE, this, COLLISION_GROUP_NONE, &tr ); bool bHop = false; if( tr.m_pEnt ) { IPhysicsObject *pPhysics = tr.m_pEnt->VPhysicsGetObject(); if( pPhysics && pPhysics->GetMass() <= 1000 ) { // Light physics objects can be moved out from under the mine. bHop = true; } else if( tr.m_pEnt->m_takedamage != DAMAGE_NO ) { // Things that can be harmed can likely be broken. bHop = true; } if( bHop ) { Vector vecForce; vecForce.x = random->RandomFloat( -1000, 1000 ); vecForce.y = random->RandomFloat( -1000, 1000 ); vecForce.z = 2500; AngularImpulse torque( 160, 0, 160 ); Flip( vecForce, torque ); return; } // Check for upside-down Vector vecUp; GetVectors( NULL, NULL, &vecUp ); if( vecUp.z <= 0.8 ) { // Landed upside down. Right self Vector vecForce( 0, 0, 2500 ); Flip( vecForce, AngularImpulse( 60, 0, 0 ) ); return; } } // Check to make sure I'm not in a forbidden location if( !IsValidLocation() ) { return; } // Lock to what I'm resting on constraint_ballsocketparams_t ballsocket; ballsocket.Defaults(); ballsocket.constraint.Defaults(); ballsocket.constraint.forceLimit = lbs2kg(1000); ballsocket.constraint.torqueLimit = lbs2kg(1000); ballsocket.InitWithCurrentObjectState( g_PhysWorldObject, VPhysicsGetObject(), GetAbsOrigin() ); m_pConstraint = physenv->CreateBallsocketConstraint( g_PhysWorldObject, VPhysicsGetObject(), NULL, ballsocket ); CloseHooks(); SetMineState( MINE_STATE_ARMED ); } } }
void CNihilanth :: HuntThink( void ) { pev->nextthink = gpGlobals->time + 0.1; DispatchAnimEvents( ); StudioFrameAdvance( ); ShootBalls( ); // if dead, force cancelation of current animation if (pev->health <= 0) { SetThink( &CNihilanth::DyingThink ); m_fSequenceFinished = TRUE; return; } // ALERT( at_console, "health %.0f\n", pev->health ); // if damaged, try to abosorb some spheres if (pev->health < gSkillData.nihilanthHealth && AbsorbSphere( )) { pev->health += gSkillData.nihilanthHealth / N_SPHERES; } // get new sequence if (m_fSequenceFinished) { // if (!m_fSequenceLoops) pev->frame = 0; NextActivity( ); ResetSequenceInfo( ); pev->framerate = 2.0 - 1.0 * (pev->health / gSkillData.nihilanthHealth); } // look for current enemy if (m_hEnemy != NULL && m_hRecharger == NULL) { if (FVisible( m_hEnemy )) { if (m_flLastSeen < gpGlobals->time - 5) m_flPrevSeen = gpGlobals->time; m_flLastSeen = gpGlobals->time; m_posTarget = m_hEnemy->pev->origin; m_vecTarget = (m_posTarget - pev->origin).Normalize(); m_vecDesired = m_vecTarget; m_posDesired = Vector( pev->origin.x, pev->origin.y, m_posTarget.z + m_flAdj ); } else { m_flAdj = min( m_flAdj + 10, 1000 ); } } // don't go too high if (m_posDesired.z > m_flMaxZ) m_posDesired.z = m_flMaxZ; // don't go too low if (m_posDesired.z < m_flMinZ) m_posDesired.z = m_flMinZ; Flight( ); }
//========================================================= // sit, do stuff //========================================================= void CSittingScientist :: SittingThink( void ) { CBaseEntity *pent; StudioFrameAdvance( ); // try to greet player if (FIdleHello()) { pent = FindNearestFriend(TRUE); if (pent) { float yaw = VecToYaw(pent->pev->origin - pev->origin) - pev->angles.y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; if (yaw > 0) pev->sequence = m_baseSequence + SITTING_ANIM_sitlookleft; else pev->sequence = m_baseSequence + SITTING_ANIM_sitlookright; ResetSequenceInfo( ); pev->frame = 0; SetBoneController( 0, 0 ); } } else if (m_fSequenceFinished) { int i = RANDOM_LONG(0,99); m_headTurn = 0; if (m_flResponseDelay && gpGlobals->time > m_flResponseDelay) { // respond to question IdleRespond(); pev->sequence = m_baseSequence + SITTING_ANIM_sitscared; m_flResponseDelay = 0; } else if (i < 30) { pev->sequence = m_baseSequence + SITTING_ANIM_sitting3; // turn towards player or nearest friend and speak if (!FBitSet(m_bitsSaid, bit_saidHelloPlayer)) pent = FindNearestFriend(TRUE); else pent = FindNearestFriend(FALSE); if (!FIdleSpeak() || !pent) { m_headTurn = RANDOM_LONG(0,8) * 10 - 40; pev->sequence = m_baseSequence + SITTING_ANIM_sitting3; } else { // only turn head if we spoke float yaw = VecToYaw(pent->pev->origin - pev->origin) - pev->angles.y; if (yaw > 180) yaw -= 360; if (yaw < -180) yaw += 360; if (yaw > 0) pev->sequence = m_baseSequence + SITTING_ANIM_sitlookleft; else pev->sequence = m_baseSequence + SITTING_ANIM_sitlookright; //ALERT(at_console, "sitting speak\n"); } } else if (i < 60) { pev->sequence = m_baseSequence + SITTING_ANIM_sitting3; m_headTurn = RANDOM_LONG(0,8) * 10 - 40; if (RANDOM_LONG(0,99) < 5) { //ALERT(at_console, "sitting speak2\n"); FIdleSpeak(); } } else if (i < 80) { pev->sequence = m_baseSequence + SITTING_ANIM_sitting2; } else if (i < 100) { pev->sequence = m_baseSequence + SITTING_ANIM_sitscared; } ResetSequenceInfo( ); pev->frame = 0; SetBoneController( 0, m_headTurn ); } pev->nextthink = gpGlobals->time + 0.1; }
//========================================================= // MonsterThink, overridden for roaches. //========================================================= void CRoach :: MonsterThink( void ) { if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) ) SetNextThink( RANDOM_FLOAT(1,1.5) ); else SetNextThink( 0.1 );// keep monster thinking float flInterval = StudioFrameAdvance( ); // animate if ( !m_fLightHacked ) { // if light value hasn't been collection for the first time yet, // suspend the creature for a second so the world finishes spawning, then we'll collect the light level. SetNextThink( 1 ); m_fLightHacked = TRUE; return; } else if ( m_flLastLightLevel < 0 ) { // collect light level for the first time, now that all of the lightmaps in the roach's area have been calculated. m_flLastLightLevel = GETENTITYILLUM( ENT( pev ) ); } switch ( m_iMode ) { case ROACH_IDLE: case ROACH_EAT: { // if not moving, sample environment to see if anything scary is around. Do a radius search 'look' at random. if ( RANDOM_LONG(0,3) == 1 ) { Look( 150 ); if (HasConditions(bits_COND_SEE_FEAR)) { // if see something scary //ALERT ( at_aiconsole, "Scared\n" ); Eat( 30 + ( RANDOM_LONG(0,14) ) );// roach will ignore food for 30 to 45 seconds PickNewDest( ROACH_SCARED_BY_ENT ); SetActivity ( ACT_WALK ); } else if ( RANDOM_LONG(0,149) == 1 ) { // if roach doesn't see anything, there's still a chance that it will move. (boredom) //ALERT ( at_aiconsole, "Bored\n" ); PickNewDest( ROACH_BORED ); SetActivity ( ACT_WALK ); if ( m_iMode == ROACH_EAT ) { // roach will ignore food for 30 to 45 seconds if it got bored while eating. Eat( 30 + ( RANDOM_LONG(0,14) ) ); } } } // don't do this stuff if eating! if ( m_iMode == ROACH_IDLE ) { if ( FShouldEat() ) { Listen(); } if ( GETENTITYILLUM( ENT(pev) ) > m_flLastLightLevel ) { // someone turned on lights! //ALERT ( at_console, "Lights!\n" ); PickNewDest( ROACH_SCARED_BY_LIGHT ); SetActivity ( ACT_WALK ); } else if ( HasConditions(bits_COND_SMELL_FOOD) ) { CSound *pSound; pSound = CSoundEnt::SoundPointerForIndex( m_iAudibleList ); // roach smells food and is just standing around. Go to food unless food isn't on same z-plane. if ( pSound && abs( pSound->m_vecOrigin.z - pev->origin.z ) <= 3 ) { PickNewDest( ROACH_SMELL_FOOD ); SetActivity ( ACT_WALK ); } } } break; } case ROACH_SCARED_BY_LIGHT: { // if roach was scared by light, then stop if we're over a spot at least as dark as where we started! if ( GETENTITYILLUM( ENT( pev ) ) <= m_flLastLightLevel ) { SetActivity ( ACT_IDLE ); m_flLastLightLevel = GETENTITYILLUM( ENT ( pev ) );// make this our new light level. } break; } } if ( m_flGroundSpeed != 0 ) { Move( flInterval ); } }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CBaseHelicopter::NullThink( void ) { StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.5f ); }
//----------------------------------------------------------------------------- // Purpose: Advance our thinks //----------------------------------------------------------------------------- void CAntlionGrub::IdleThink( void ) { #if DEBUG_GRUB_THINK_TIMES // Test for a new frame if ( gpGlobals->framecount != nFrame ) { if ( nNumThinks > 10 ) { Msg("%d npc_antlion_grubs thinking per frame!\n", nNumThinks ); } nFrame = gpGlobals->framecount; nNumThinks = 0; } nNumThinks++; #endif // DEBUG_GRUB_THINK_TIMES // Check the PVS status if ( InPVS() == false ) { // Push out into the future until they're in our PVS SetNextThinkByDistance(); m_bOutsidePVS = true; return; } // Stagger our sounds if we've just re-entered the PVS if ( m_bOutsidePVS ) { m_flNextIdleSoundTime = gpGlobals->curtime + random->RandomFloat( 1.0f, 4.0f ); m_bOutsidePVS = false; } // See how close the player is CBasePlayer *pPlayerEnt = AI_GetSinglePlayer(); float flDistToPlayerSqr = ( GetAbsOrigin() - pPlayerEnt->GetAbsOrigin() ).LengthSqr(); bool bFlinching = ( m_flFlinchTime > gpGlobals->curtime ); // If they're far enough away, just wait to think again if ( flDistToPlayerSqr > Square( 40*12 ) && bFlinching == false ) { SetNextThinkByDistance(); return; } // At this range, the player agitates us with his presence bool bPlayerWithinAgitationRange = ( flDistToPlayerSqr <= Square( (6*12) ) ); bool bAgitated = (bPlayerWithinAgitationRange || bFlinching ); // If we're idle and the player has come close enough, get agry if ( ( m_State == GRUB_STATE_IDLE ) && bAgitated ) { SetSequence( SelectWeightedSequence( ACT_SMALL_FLINCH ) ); m_State = GRUB_STATE_AGITATED; } else if ( IsSequenceFinished() ) { // See if it's time to choose a new sequence ResetSequenceInfo(); SetCycle( 0.0f ); // If we're near enough, we want to play an "alert" animation if ( bAgitated ) { SetSequence( SelectWeightedSequence( ACT_SMALL_FLINCH ) ); m_State = GRUB_STATE_AGITATED; } else { // Just idle SetSequence( SelectWeightedSequence( ACT_IDLE ) ); m_State = GRUB_STATE_IDLE; } // Add some variation because we're often in large bunches SetPlaybackRate( random->RandomFloat( 0.8f, 1.2f ) ); } // Idle normally StudioFrameAdvance(); MakeIdleSounds(); SetNextThink( gpGlobals->curtime + 0.1f ); }
void CTank :: DriveThink ( void ) { pev->nextthink = gpGlobals->time + NEXTTHINK_TIME; StudioFrameAdvance ( ); if ( pev->sequence == 1 ) pev->sequence = 0; // ALERT ( at_console, "playerdrivetank : %s\n", m_pPlayer->m_iDrivingTank == TRUE ? "TRUE" : "FALSE" ); // apres le changement de niveau, reinitialisation de la vue if ( bSetView == 1 ) { // actualisation de la vie du bsp m_pTankBSP->pev->health = m_flTempHealth; // réglages camera & hud m_pCam->SetPlayerTankView ( TRUE ); bSetView = 0; } //quitte le tank if (m_pPlayer->pev->button & IN_USE) { pev->velocity = pev->avelocity = m_pTankBSP->pev->velocity = m_pTankBSP->pev->avelocity =Vector (0,0,0); m_pTankBSP->pev->origin = pev->origin; m_pTankBSP->pev->angles = pev->angles; m_pCam->pev->velocity = ( vecCamOrigin() - m_pCam->pev->origin ) /2; UpdateCamAngle ( m_pCam->pev->origin, 2 ); UpdateSound (); SetThink( StopThink ); pev->nextthink = gpGlobals->time + 2; return; } float flNextVAngleY = pev->v_angle.y; float flNextVAngleX = pev->v_angle.x; float flNewAVelocity; Vector vecNewVelocity; //---------------------------------------------_-_-_ _ _ //modifications de la direction de la tourelle if ( bTankOn == 0 ) { bTankOn = 1; m_PlayerAngles.x = m_pPlayer->pev->angles.x ; m_PlayerAngles.y = m_pPlayer->pev->angles.y ; } if ( m_pPlayer->pev->angles.y != m_PlayerAngles.y ) { int iSens; int iDist = ModifAngles ( m_pPlayer->pev->angles.y ) - ModifAngles ( m_PlayerAngles.y ); if ( fabs(iDist) > 180 ) { if ( iDist > 0 ) iDist = iDist - 360; else iDist = iDist + 360; } iSens = iDist == fabs(iDist) ? 1 : -1 ; iDist = fabs(iDist); if ( iDist < TANK_TOURELLE_ROT_SPEED ) flNextVAngleY += iDist * iSens; else flNextVAngleY += TANK_TOURELLE_ROT_SPEED * iSens; if ( flNextVAngleY > TOURELLE_MAX_ROT_Y ) flNextVAngleY = TOURELLE_MAX_ROT_Y; if ( flNextVAngleY < -TOURELLE_MAX_ROT_Y ) flNextVAngleY = -TOURELLE_MAX_ROT_Y; } if ( m_pPlayer->pev->angles.x != m_PlayerAngles.x ) { int iSens; int iDist = ModifAngles ( m_pPlayer->pev->angles.x ) - ModifAngles ( m_PlayerAngles.x ); if ( fabs(iDist) > 180 ) { if ( iDist > 0 ) iDist = iDist - 360; else iDist = iDist + 360; } iSens = iDist == fabs(iDist) ? 1 : -1 ; iDist = fabs(iDist); if ( iDist < TANK_TOURELLE_ROT_SPEED ) flNextVAngleX += iDist * iSens; else flNextVAngleX += TANK_TOURELLE_ROT_SPEED * iSens; if ( flNextVAngleX > TOURELLE_MAX_ROT_X ) flNextVAngleX = TOURELLE_MAX_ROT_X; if ( flNextVAngleX < TOURELLE_MAX_ROT_X2 ) flNextVAngleX = TOURELLE_MAX_ROT_X2; } m_PlayerAngles.y = m_pPlayer->pev->angles.y; m_PlayerAngles.x = m_pPlayer->pev->angles.x; //--------------------------------- // sons d'acceleration du tank float flSpeed = pev->velocity.Length(); if ( m_flNextSound < gpGlobals->time) { if ( (m_pPlayer->pev->button & IN_FORWARD) && ((flSpeed==0) || (m_iTankmove & MOVE_BACKWARD)) ) { EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, ACCELERE_SOUND1, 1 , ATTN_NONE, 0, 100 ); m_flNextSound = gpGlobals->time + 2.5; } else if ( (m_pPlayer->pev->button & IN_BACK) && (m_iTankmove & MOVE_FORWARD) ) { EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, DECCELERE_SOUND, 1 , ATTN_NONE, 0, 100 ); m_flNextSound = gpGlobals->time + 2.5; } else if ( (m_pPlayer->pev->button & IN_FORWARD) && (m_iTankmove & MOVE_FORWARD) && !(m_iTankmove & PUSH_FORWARD)) { if ( RANDOM_LONG ( 0,1 ) ) EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, ACCELERE_SOUND2, 1 , ATTN_NONE, 0, 100 ); else EMIT_SOUND_DYN(ENT(pev), CHAN_ITEM, ACCELERE_SOUND3, 1 , ATTN_NONE, 0, 100 ); m_flNextSound = gpGlobals->time + 2.5; } } //------------------------------- //modification de la vitesse du tank UTIL_MakeVectors( pev->angles ); int iSens = UTIL_AngleDiff( UTIL_VecToAngles ( pev->velocity ).y, UTIL_VecToAngles ( gpGlobals->v_forward ).y ); if ( flSpeed == 0 ) iSens = 0; else if ( iSens < -45 || iSens > 45 ) iSens = -1; else iSens = 1; if ( m_pPlayer->pev->button & IN_FORWARD) { m_iTankmove |= PUSH_FORWARD; m_iTankmove &= ~PUSH_BACKWARD; if ( iSens == -1 ) { if ( flSpeed > TANK_DECCELERATION * 2 ) vecNewVelocity = gpGlobals->v_forward * - ( flSpeed - TANK_DECCELERATION ); else vecNewVelocity = Vector ( 0,0,0 ); } else if ( flSpeed < 250 ) vecNewVelocity = gpGlobals->v_forward * ( flSpeed + TANK_ACCELERATION ); else vecNewVelocity = gpGlobals->v_forward * 250; } else if ( m_pPlayer->pev->button & IN_BACK) { m_iTankmove |= PUSH_BACKWARD; m_iTankmove &= ~PUSH_FORWARD; if ( iSens == 1 ) { if ( flSpeed > TANK_DECCELERATION * 2 ) vecNewVelocity = gpGlobals->v_forward * ( flSpeed - TANK_DECCELERATION ); else vecNewVelocity = Vector ( 0,0,0 ); } else if ( flSpeed < 150 ) vecNewVelocity = gpGlobals->v_forward * - ( flSpeed + TANK_ACCELERATION ); else vecNewVelocity = gpGlobals->v_forward * -150; } else { if ( flSpeed > 5 ) vecNewVelocity = gpGlobals->v_forward * ( flSpeed - 1 ) * iSens; else vecNewVelocity = gpGlobals->v_forward * flSpeed * iSens; m_iTankmove &= ~PUSH_BACKWARD; m_iTankmove &= ~PUSH_FORWARD; } if ( iSens == 1) { m_iTankmove |= MOVE_FORWARD; m_iTankmove &= ~MOVE_BACKWARD; } else { m_iTankmove |= MOVE_BACKWARD; m_iTankmove &= ~MOVE_FORWARD; } //modification de la direction du tank if ( m_pPlayer->pev->button & IN_MOVELEFT ) flNewAVelocity = TANK_ROT_SPEED; else if ( m_pPlayer->pev->button & IN_MOVERIGHT ) flNewAVelocity = -TANK_ROT_SPEED; else flNewAVelocity = 0; // test de la position envisagée UTIL_MakeVectors ( pev->angles + Vector ( 0, flNewAVelocity / 10 , 0) ); TraceResult tr [4]/*1,tr2,tr3,tr4*/; Vector vecFrontLeft, vecFrontRight, vecBackLeft, vecBackRight; vecFrontLeft = NEW_ORIGIN + gpGlobals->v_forward * DIST_FRONT_UP + gpGlobals->v_right * -DIST_SIDE + gpGlobals->v_up * DIST_TOP; vecFrontRight = NEW_ORIGIN + gpGlobals->v_forward * DIST_FRONT_UP + gpGlobals->v_right * DIST_SIDE + gpGlobals->v_up * DIST_TOP; vecBackLeft = NEW_ORIGIN + gpGlobals->v_forward * DIST_BACK_UP + gpGlobals->v_right * -DIST_SIDE + gpGlobals->v_up * DIST_TOP; vecBackRight = NEW_ORIGIN + gpGlobals->v_forward * DIST_BACK_UP + gpGlobals->v_right * DIST_SIDE + gpGlobals->v_up * DIST_TOP; UTIL_TraceLine (vecFrontLeft, vecFrontRight,ignore_monsters, ENT(m_pTankBSP->pev), &tr[0]); UTIL_TraceLine (vecFrontRight, vecBackRight,ignore_monsters, ENT(m_pTankBSP->pev), &tr[1]); UTIL_TraceLine (vecBackRight, vecBackLeft, ignore_monsters, ENT(m_pTankBSP->pev), &tr[2]); UTIL_TraceLine (vecBackLeft, vecFrontLeft, ignore_monsters, ENT(m_pTankBSP->pev), &tr[3]); //pas de collision - application de la nouvelle position if ( tr[0].vecEndPos == vecFrontRight && tr[1].vecEndPos == vecBackRight && tr[2].vecEndPos == vecBackLeft && tr[3].vecEndPos == vecFrontLeft ) { StudioFrameAdvance ( 0.1 ); pev->velocity = vecNewVelocity; pev->avelocity = Vector ( 0, flNewAVelocity, 0 ); m_pCam->m_vecTourelleAngle = pev->v_angle; m_pCam->m_flNextFrameTime = pev->nextthink; pev->v_angle.y = flNextVAngleY; pev->v_angle.x = flNextVAngleX; m_pTankBSP->pev->velocity = (( pev->origin + vecNewVelocity * 10 ) - m_pTankBSP->pev-> origin ) / 10 ; m_pTankBSP->pev->avelocity = (( pev->angles + Vector ( 0, flNewAVelocity * 10, 0 ) - m_pTankBSP->pev->angles )) / 10; // pour combler la différence de vitesse entre le bsp et le mdl } //collision - arret du tank else { pev->velocity = pev->avelocity = Vector (0,0,0); m_pTankBSP->pev->velocity = ( pev->origin - m_pTankBSP->pev-> origin ) / 10 ; m_pTankBSP->pev->avelocity = ( pev->angles - m_pTankBSP->pev->angles ) / 10; if ( flSpeed > 50 ) // choc violent { EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, CHOC_SOUND, 0.9, ATTN_NORM, 0, 60 ); } } // application des dommages vecFrontLeft = vecFrontLeft + Vector ( 0, 0, 10 - DIST_TOP ); vecFrontRight = vecFrontRight + Vector ( 0, 0, 10 - DIST_TOP ); vecBackRight = vecBackRight + Vector ( 0, 0, 10 - DIST_TOP ); vecBackLeft = vecBackLeft + Vector ( 0, 0, 10 - DIST_TOP ); UTIL_TraceLine (vecFrontLeft, vecFrontRight,dont_ignore_monsters, ENT(m_pTankBSP->pev), &tr[0]); UTIL_TraceLine (vecFrontRight, vecBackRight,dont_ignore_monsters, ENT(m_pTankBSP->pev), &tr[1]); UTIL_TraceLine (vecBackRight, vecBackLeft, dont_ignore_monsters, ENT(m_pTankBSP->pev), &tr[2]); UTIL_TraceLine (vecBackLeft, vecFrontLeft, dont_ignore_monsters, ENT(m_pTankBSP->pev), &tr[3]); CBaseEntity *pEntity = NULL; for ( int i = 0 ; i < 4 ; i ++ ) { if ( tr [ i ].pHit != NULL ) { pEntity = CBaseEntity :: Instance ( tr [ i ].pHit ); if ( pEntity != NULL && pEntity->pev->takedamage ) { float fDamage; if ( FClassnameIs ( tr[i].pHit, "func_breakable" ) ) { fDamage = pEntity->pev->health; } else { fDamage = pev->velocity.Length() * 1.5 + 20; } pEntity->TakeDamage ( pev, pev , fDamage , DMG_CRUSH ); } } } //rectification de la position de la camera vecCamAim = UpdateCam(); if ( m_pCam->pev->origin != vecCamAim ) m_pCam->pev->velocity = ( vecCamAim - m_pCam->pev->origin ) * 10; UpdateCamAngle ( vecCamAim, NEXTTHINK_TIME ); //tir de la tourelle if ( ( m_pPlayer->pev->button & IN_ATTACK ) && ( gpGlobals->time > m_flLastAttack1 + TANK_REFIRE_DELAY ) ) { Fire ( bCanon ); bCanon = bCanon == TRUE ? FALSE : TRUE; EMIT_SOUND(ENT(pev), CHAN_AUTO, TIR_SOUND, 1, ATTN_NORM); m_flLastAttack1 = gpGlobals->time; m_pCam->pev->avelocity.x -= 45; } //tir de la mitrailleuse if ( m_pPlayer->pev->button & IN_ATTACK2 ) { Vector posGun, dirGun; GetAttachment( 3, posGun, Vector ( 0, 0, 0 ) ); UTIL_MakeVectorsPrivate( TourelleAngle(), dirGun, NULL, NULL ); FireBullets( 1, posGun, dirGun, VECTOR_CONE_5DEGREES, 8192, BULLET_MONSTER_12MM ); EMIT_SOUND(ENT(pev), CHAN_WEAPON, MITRAILLEUSE_SOUND, 1, ATTN_NORM); if ( !FStrEq(STRING(gpGlobals->mapname), "l3m10") && !FStrEq(STRING(gpGlobals->mapname), "l3m12") && !FStrEq(STRING(gpGlobals->mapname), "l3m14") ) { CSprite *pSprite = CSprite::SpriteCreate( SPRITE_MUZ, posGun, TRUE ); pSprite->AnimateAndDie( 15 ); pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); pSprite->SetAttachment( edict(), 4 ); pSprite->SetScale( SPRITE_MUZ_SCALE ); } } //sond du tank UpdateSound (); CSoundEnt::InsertSound ( bits_SOUND_DANGER, pev->origin + pev->velocity * 2.5, 150, NEXTTHINK_TIME ); CSoundEnt::InsertSound ( bits_SOUND_PLAYER, pev->origin, 2000, 0.5 ); }
void CXenTree :: Think( void ) { float flInterval = StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; DispatchAnimEvents( flInterval ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - // *pMoveData - //----------------------------------------------------------------------------- void CPropCrane::RunCraneMovement( float flTime ) { if ( m_flExtensionRate ) { // Extend / Retract the crane m_flExtension = clamp( m_flExtension + (m_flExtensionRate * 10 * flTime), 0, 2 ); SetPoseParameter( "armextensionpose", m_flExtension ); StudioFrameAdvance(); } // Drop the magnet until it hits the ground if ( m_bDropping ) { // Drop until the magnet hits something if ( m_hCraneMagnet->HasHitSomething() ) { // We hit the ground, stop dropping m_hCraneTip->m_pSpring->SetSpringConstant( CRANE_SPRING_CONSTANT_INITIAL_RAISING ); m_bDropping = false; m_flNextDropAllowedTime = gpGlobals->curtime + 3.0; m_flSlowRaiseTime = gpGlobals->curtime; m_ServerVehicle.PlaySound( VS_MISC2 ); } } else if ( (m_flSlowRaiseTime + CRANE_SLOWRAISE_TIME) > gpGlobals->curtime ) { float flDelta = (gpGlobals->curtime - m_flSlowRaiseTime); flDelta = clamp( flDelta, 0, CRANE_SLOWRAISE_TIME ); float flCurrentSpringConstant = RemapVal( flDelta, 0, CRANE_SLOWRAISE_TIME, CRANE_SPRING_CONSTANT_INITIAL_RAISING, CRANE_SPRING_CONSTANT_HANGING ); m_hCraneTip->m_pSpring->SetSpringConstant( flCurrentSpringConstant ); } // If we've moved in any way, update the tip if ( m_bDropping || m_flExtensionRate || GetLocalAngularVelocity() != vec3_angle ) { RecalculateCraneTip(); } // Make danger sounds underneath the magnet if we have something attached to it /* if ( (m_flNextDangerSoundTime < gpGlobals->curtime) && (m_hCraneMagnet->GetTotalMassAttachedObjects() > 0) ) { // Trace down from the magnet and make a danger sound on the ground trace_t tr; Vector vecSource = m_hCraneMagnet->GetAbsOrigin(); UTIL_TraceLine( vecSource, vecSource - Vector(0,0,2048), MASK_SOLID_BRUSHONLY, m_hCraneMagnet, 0, &tr ); if ( tr.fraction < 1.0 ) { // Make the volume proportional to the amount of mass on the magnet float flVolume = clamp( (m_hCraneMagnet->GetTotalMassAttachedObjects() * 0.5), 100.f, 600.f ); CSoundEnt::InsertSound( SOUND_DANGER, tr.endpos, flVolume, 0.2, this ); //Msg("Total: %.2f Volume: %.2f\n", m_hCraneMagnet->GetTotalMassAttachedObjects(), flVolume ); //Vector vecVolume = Vector(flVolume,flVolume,flVolume) * 0.5; //NDebugOverlay::Box( tr.endpos, -vecVolume, vecVolume, 255,0,0, false, 0.3 ); //NDebugOverlay::Cross3D( tr.endpos, -Vector(10,10,10), Vector(10,10,10), 255,0,0, false, 0.3 ); } m_flNextDangerSoundTime = gpGlobals->curtime + 0.3; } */ // Play creak sounds on the magnet if there's heavy weight on it if ( (m_flNextCreakSound < gpGlobals->curtime) && (m_hCraneMagnet->GetTotalMassAttachedObjects() > 100) ) { // Randomly play creaks from the magnet, and increase the chance based on the turning speed float flSpeedPercentage = clamp( fabs(m_flTurn) / m_flMaxTurnSpeed, 0, 1 ); if ( RandomFloat(0,1) > (0.95 - (0.1 * flSpeedPercentage)) ) { if ( m_ServerVehicle.m_vehicleSounds.iszSound[VS_MISC4] != NULL_STRING ) { CPASAttenuationFilter filter( m_hCraneMagnet ); EmitSound_t ep; ep.m_nChannel = CHAN_VOICE; ep.m_pSoundName = STRING(m_ServerVehicle.m_vehicleSounds.iszSound[VS_MISC4]); ep.m_flVolume = 1.0f; ep.m_SoundLevel = SNDLVL_NORM; CBaseEntity::EmitSound( filter, m_hCraneMagnet->entindex(), ep ); } m_flNextCreakSound = gpGlobals->curtime + 5.0; } } }
void COsprey::DyingThink(void) { StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.1; pev->avelocity = pev->avelocity * 1.02; // still falling? if (m_startTime > gpGlobals->time) { UTIL_MakeAimVectors(pev->angles); ShowDamage(); Vector vecSpot = pev->origin + pev->velocity * 0.2; // random explosions MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, vecSpot); WRITE_BYTE(TE_EXPLOSION); // This just makes a dynamic light now WRITE_COORD(vecSpot.x + RANDOM_FLOAT(-150, 150)); WRITE_COORD(vecSpot.y + RANDOM_FLOAT(-150, 150)); WRITE_COORD(vecSpot.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, vecSpot); WRITE_BYTE(TE_SMOKE); WRITE_COORD(vecSpot.x + RANDOM_FLOAT(-150, 150)); WRITE_COORD(vecSpot.y + RANDOM_FLOAT(-150, 150)); WRITE_COORD(vecSpot.z + RANDOM_FLOAT(-150, -50)); WRITE_SHORT(g_sModelIndexSmoke); WRITE_BYTE(100); // scale * 10 WRITE_BYTE(10); // framerate MESSAGE_END(); 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(800); WRITE_COORD(800); 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_iTailGibs); //model id# // # of shards WRITE_BYTE(8); // let client decide // duration WRITE_BYTE(200);// 10.0 seconds // flags WRITE_BYTE(BREAK_METAL); MESSAGE_END(); // don't stop it we touch a entity pev->flags &= ~FL_ONGROUND; pev->nextthink = gpGlobals->time + 0.2; return; } else { Vector vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; // gibs MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, vecSpot); WRITE_BYTE(TE_SPRITE); WRITE_COORD(vecSpot.x); WRITE_COORD(vecSpot.y); WRITE_COORD(vecSpot.z + 512); WRITE_SHORT(m_iExplode); WRITE_BYTE(250); // scale * 10 WRITE_BYTE(255); // brightness MESSAGE_END(); // blast circle MESSAGE_BEGIN(MSG_PAS, 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); // gibs vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; MESSAGE_BEGIN(MSG_PAS, SVC_TEMPENTITY, vecSpot); WRITE_BYTE(TE_BREAKMODEL); // position WRITE_COORD(vecSpot.x); WRITE_COORD(vecSpot.y); WRITE_COORD(vecSpot.z + 64); // size WRITE_COORD(800); WRITE_COORD(800); WRITE_COORD(128); // velocity WRITE_COORD(m_velocity.x); WRITE_COORD(m_velocity.y); WRITE_COORD(fabs(m_velocity.z) * 0.25); // randomization WRITE_BYTE(40); // Model WRITE_SHORT(m_iBodyGibs); //model id# // # of shards WRITE_BYTE(128); // duration WRITE_BYTE(200);// 10.0 seconds // flags WRITE_BYTE(BREAK_METAL); MESSAGE_END(); UTIL_Remove(this); } }
void CSqueakGrenade::HuntThink( void ) { // ALERT( at_console, "think\n" ); if (!IsInWorld()) { SetTouch( nullptr ); UTIL_Remove( this ); return; } StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 0.1; // explode when ready if (gpGlobals->time >= m_flDie) { g_vecAttackDir = pev->velocity.Normalize( ); pev->health = -1; Killed( pev, 0 ); return; } // float if (pev->waterlevel != 0) { if (pev->movetype == MOVETYPE_BOUNCE) { pev->movetype = MOVETYPE_FLY; } pev->velocity = pev->velocity * 0.9; pev->velocity.z += 8.0; } else if (pev->movetype = MOVETYPE_FLY) { pev->movetype = MOVETYPE_BOUNCE; } // return if not time to hunt if (m_flNextHunt > gpGlobals->time) return; m_flNextHunt = gpGlobals->time + 2.0; CBaseEntity *pOther = nullptr; Vector vecDir; TraceResult tr; Vector vecFlat = pev->velocity; vecFlat.z = 0; vecFlat = vecFlat.Normalize( ); UTIL_MakeVectors( pev->angles ); if (m_hEnemy == nullptr || !m_hEnemy->IsAlive()) { // find target, bounce a bit towards it. Look( 512 ); m_hEnemy = BestVisibleEnemy( ); } // squeek if it's about time blow up if ((m_flDie - gpGlobals->time <= 0.5) && (m_flDie - gpGlobals->time >= 0.3)) { EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "squeek/sqk_die1.wav", 1, ATTN_NORM, 0, 100 + RANDOM_LONG(0,0x3F)); CSoundEnt::InsertSound ( bits_SOUND_COMBAT, pev->origin, 256, 0.25 ); } // higher pitch as squeeker gets closer to detonation time float flpitch = 155.0 - 60.0 * ((m_flDie - gpGlobals->time) / SQUEEK_DETONATE_DELAY); if (flpitch < 80) flpitch = 80; if (m_hEnemy != nullptr) { if (FVisible( m_hEnemy )) { vecDir = m_hEnemy->EyePosition() - pev->origin; m_vecTarget = vecDir.Normalize( ); } float flVel = pev->velocity.Length(); float flAdj = 50.0 / (flVel + 10.0); if (flAdj > 1.2) flAdj = 1.2; // ALERT( at_console, "think : enemy\n"); // ALERT( at_console, "%.0f %.2f %.2f %.2f\n", flVel, m_vecTarget.x, m_vecTarget.y, m_vecTarget.z ); pev->velocity = pev->velocity * flAdj + m_vecTarget * 300; } if (pev->flags & FL_ONGROUND) { pev->avelocity = Vector( 0, 0, 0 ); } else { if (pev->avelocity == Vector( 0, 0, 0)) { pev->avelocity.x = RANDOM_FLOAT( -100, 100 ); pev->avelocity.z = RANDOM_FLOAT( -100, 100 ); } } if ((pev->origin - m_posPrev).Length() < 1.0) { pev->velocity.x = RANDOM_FLOAT( -100, 100 ); pev->velocity.y = RANDOM_FLOAT( -100, 100 ); } m_posPrev = pev->origin; pev->angles = UTIL_VecToAngles( pev->velocity ); pev->angles.z = 0; pev->angles.x = 0; }
void CSentry :: SentryDeath( void ) { BOOL iActive = FALSE; StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 0.1; if (pev->deadflag != DEAD_DEAD) { pev->deadflag = DEAD_DEAD; float flRndSound = RANDOM_FLOAT ( 0 , 1 ); if ( flRndSound <= 0.33 ) EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die.wav", 1.0, ATTN_NORM); else if ( flRndSound <= 0.66 ) EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die2.wav", 1.0, ATTN_NORM); else EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die3.wav", 1.0, ATTN_NORM); EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "turret/tu_active2.wav", 0, 0, SND_STOP, 100); SetBoneController( 0, 0 ); SetBoneController( 1, 0 ); SetTurretAnim(TURRET_ANIM_DIE); pev->solid = SOLID_NOT; pev->angles.y = UTIL_AngleMod( pev->angles.y + RANDOM_LONG( 0, 2 ) * 120 ); EyeOn( ); } EyeOff( ); Vector vecSrc, vecAng; GetAttachment( 1, vecSrc, vecAng ); if (pev->dmgtime + RANDOM_FLOAT( 0, 2 ) > gpGlobals->time) { // lots of smoke MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); WRITE_BYTE( TE_SMOKE ); WRITE_COORD( vecSrc.x + RANDOM_FLOAT( -16, 16 ) ); WRITE_COORD( vecSrc.y + RANDOM_FLOAT( -16, 16 ) ); WRITE_COORD( vecSrc.z - 32 ); WRITE_SHORT( g_sModelIndexSmoke ); WRITE_BYTE( 15 ); // scale * 10 WRITE_BYTE( 8 ); // framerate MESSAGE_END(); } if (pev->dmgtime + RANDOM_FLOAT( 0, 8 ) > gpGlobals->time) { UTIL_Sparks( vecSrc ); } if (m_fSequenceFinished && pev->dmgtime + 5 < gpGlobals->time) { pev->framerate = 0; SetThink( NULL ); } }
void CNihilanth::NullThink( void ) { StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 0.5; }
void CBaseTurret :: TurretDeath( void ) { BOOL iActive = FALSE; StudioFrameAdvance( ); pev->nextthink = gpGlobals->time + 0.1; if (pev->deadflag != DEAD_DEAD) { pev->deadflag = DEAD_DEAD; float flRndSound = RANDOM_FLOAT ( 0 , 1 ); if ( flRndSound <= 0.33 ) EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die.wav", 1.0, ATTN_NORM); else if ( flRndSound <= 0.66 ) EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die2.wav", 1.0, ATTN_NORM); else EMIT_SOUND(ENT(pev), CHAN_BODY, "turret/tu_die3.wav", 1.0, ATTN_NORM); EMIT_SOUND_DYN(ENT(pev), CHAN_STATIC, "turret/tu_active2.wav", 0, 0, SND_STOP, 100); if (m_iOrientation == 0) m_vecGoalAngles.x = -15; else m_vecGoalAngles.x = -90; SetTurretAnim(TURRET_ANIM_DIE); EyeOn( ); } EyeOff( ); if (pev->dmgtime + RANDOM_FLOAT( 0, 2 ) > gpGlobals->time) { // lots of smoke MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); WRITE_BYTE( TE_SMOKE ); WRITE_COORD( RANDOM_FLOAT( pev->absmin.x, pev->absmax.x ) ); WRITE_COORD( RANDOM_FLOAT( pev->absmin.y, pev->absmax.y ) ); WRITE_COORD( pev->origin.z - m_iOrientation * 64 ); WRITE_SHORT( g_sModelIndexSmoke ); WRITE_BYTE( 25 ); // scale * 10 WRITE_BYTE( 10 - m_iOrientation * 5); // framerate MESSAGE_END(); } if (pev->dmgtime + RANDOM_FLOAT( 0, 5 ) > gpGlobals->time) { Vector vecSrc = Vector( RANDOM_FLOAT( pev->absmin.x, pev->absmax.x ), RANDOM_FLOAT( pev->absmin.y, pev->absmax.y ), 0 ); if (m_iOrientation == 0) vecSrc = vecSrc + Vector( 0, 0, RANDOM_FLOAT( pev->origin.z, pev->absmax.z ) ); else vecSrc = vecSrc + Vector( 0, 0, RANDOM_FLOAT( pev->absmin.z, pev->origin.z ) ); UTIL_Sparks( vecSrc ); } if (m_fSequenceFinished && !MoveTurret( ) && pev->dmgtime + 5 < gpGlobals->time) { pev->framerate = 0; SetThink( NULL ); } }
void CNihilanth :: DyingThink( void ) { pev->nextthink = gpGlobals->time + 0.1; DispatchAnimEvents( ); StudioFrameAdvance( ); if (pev->deadflag == DEAD_NO) { DeathSound( ); pev->deadflag = DEAD_DYING; m_posDesired.z = m_flMaxZ; } if (pev->deadflag == DEAD_DYING) { Flight( ); if (fabs( pev->origin.z - m_flMaxZ ) < 16) { pev->velocity = Vector( 0, 0, 0 ); FireTargets( m_szDeadUse, this, this, USE_ON, 1.0 ); pev->deadflag = DEAD_DEAD; } } if (m_fSequenceFinished) { pev->avelocity.y += RANDOM_FLOAT( -100, 100 ); if (pev->avelocity.y < -100) pev->avelocity.y = -100; if (pev->avelocity.y > 100) pev->avelocity.y = 100; pev->sequence = LookupSequence( "die1" ); } if (m_pBall) { if (m_pBall->pev->renderamt > 0) { m_pBall->pev->renderamt = max( 0, m_pBall->pev->renderamt - 2); } else { UTIL_Remove( m_pBall ); m_pBall = NULL; } } Vector vecDir, vecSrc, vecAngles; UTIL_MakeAimVectors( pev->angles ); int iAttachment = RANDOM_LONG( 1, 4 ); do { vecDir = Vector( RANDOM_FLOAT( -1, 1 ), RANDOM_FLOAT( -1, 1 ), RANDOM_FLOAT( -1, 1 )); } while (DotProduct( vecDir, vecDir) > 1.0); switch( RANDOM_LONG( 1, 4 )) { case 1: // head vecDir.z = fabs( vecDir.z ) * 0.5; vecDir = vecDir + 2 * gpGlobals->v_up; break; case 2: // eyes if (DotProduct( vecDir, gpGlobals->v_forward ) < 0) vecDir = vecDir * -1; vecDir = vecDir + 2 * gpGlobals->v_forward; break; case 3: // left hand if (DotProduct( vecDir, gpGlobals->v_right ) > 0) vecDir = vecDir * -1; vecDir = vecDir - 2 * gpGlobals->v_right; break; case 4: // right hand if (DotProduct( vecDir, gpGlobals->v_right ) < 0) vecDir = vecDir * -1; vecDir = vecDir + 2 * gpGlobals->v_right; break; } GetAttachment( iAttachment - 1, vecSrc, vecAngles ); TraceResult tr; UTIL_TraceLine( vecSrc, vecSrc + vecDir * 4096, ignore_monsters, ENT(pev), &tr ); MESSAGE_BEGIN( MSG_BROADCAST, SVC_TEMPENTITY ); WRITE_BYTE( TE_BEAMENTPOINT ); WRITE_SHORT( entindex() + 0x1000 * iAttachment ); 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( 5 ); // life WRITE_BYTE( 100 ); // width WRITE_BYTE( 120 ); // noise WRITE_BYTE( 64 ); // r, g, b WRITE_BYTE( 128 ); // r, g, b WRITE_BYTE( 255); // r, g, b WRITE_BYTE( 255 ); // brightness WRITE_BYTE( 10 ); // speed MESSAGE_END(); GetAttachment( 0, vecSrc, vecAngles ); CNihilanthHVR *pEntity = (CNihilanthHVR *)Create( "nihilanth_energy_ball", vecSrc, pev->angles, edict() ); pEntity->pev->velocity = Vector ( RANDOM_FLOAT( -0.7, 0.7 ), RANDOM_FLOAT( -0.7, 0.7 ), 1.0 ) * 600.0; pEntity->GreenBallInit( ); return; }
void CXenHair::Think( void ) { StudioFrameAdvance(); pev->nextthink = gpGlobals->time + 0.5; }
void CNPC_Tentacle::Cycle( void ) { //NDebugOverlay::Cross3D( EarPosition(), 32, 255, 0, 0, false, 0.1 ); // ALERT( at_console, "%s %.2f %d %d\n", STRING( pev->targetname ), pev->origin.z, m_MonsterState, m_IdealMonsterState ); SetNextThink( gpGlobals->curtime + 0.1 ); // ALERT( at_console, "%s %d %d %d %f %f\n", STRING( pev->targetname ), pev->sequence, m_iGoalAnim, m_iDir, pev->framerate, pev->health ); if ( m_NPCState == NPC_STATE_SCRIPT || GetIdealState() == NPC_STATE_SCRIPT) { SetAbsAngles( QAngle( GetAbsAngles().x, m_flInitialYaw, GetAbsAngles().z ) ); GetMotor()->SetIdealYaw( m_flInitialYaw ); RemoveIgnoredConditions(); NPCThink( ); m_iGoalAnim = TENTACLE_ANIM_Pit_Idle; return; } StudioFrameAdvance(); DispatchAnimEvents( this ); GetMotor()->UpdateYaw( MaxYawSpeed() ); CSound *pSound = NULL; GetSenses()->Listen(); m_BoneFollowerManager.UpdateBoneFollowers(this); // Listen will set this if there's something in my sound list if ( HeardAnything() ) pSound = GetSenses()->GetClosestSound( false, (SOUND_DANGER|SOUND_COMBAT|SOUND_WORLD|SOUND_PLAYER) ); else pSound = NULL; if ( pSound ) { //NDebugOverlay::Line( EarPosition(), pSound->GetSoundOrigin(), 0, 255, 0, false, 0.2 ); Vector vecDir; if ( gpGlobals->curtime - m_flPrevSoundTime < 0.5 ) { float dt = gpGlobals->curtime - m_flPrevSoundTime; vecDir = pSound->GetSoundOrigin() + (pSound->GetSoundOrigin() - m_vecPrevSound) / dt - GetAbsOrigin(); } else { vecDir = pSound->GetSoundOrigin() - GetAbsOrigin(); } m_flPrevSoundTime = gpGlobals->curtime; m_vecPrevSound = pSound->GetSoundOrigin(); m_flSoundYaw = VecToYaw ( vecDir ) - m_flInitialYaw; m_iSoundLevel = Level( vecDir.z ); if (m_flSoundYaw < -180) m_flSoundYaw += 360; if (m_flSoundYaw > 180) m_flSoundYaw -= 360; // ALERT( at_console, "sound %d %.0f\n", m_iSoundLevel, m_flSoundYaw ); if (m_flSoundTime < gpGlobals->curtime) { // play "I hear new something" sound UTIL_EmitAmbientSound( GetSoundSourceIndex(), GetAbsOrigin() + Vector( 0, 0, MyHeight()), "Tentacle.Alert", 1.0, SNDLVL_GUNFIRE, 0, 100); } m_flSoundTime = gpGlobals->curtime + random->RandomFloat( 5.0, 10.0 ); } // clip ideal_yaw float dy = m_flSoundYaw; switch( GetSequence() ) { case TENTACLE_ANIM_Floor_Rear: case TENTACLE_ANIM_Floor_Rear_Idle: case TENTACLE_ANIM_Lev1_Rear: case TENTACLE_ANIM_Lev1_Rear_Idle: case TENTACLE_ANIM_Lev2_Rear: case TENTACLE_ANIM_Lev2_Rear_Idle: case TENTACLE_ANIM_Lev3_Rear: case TENTACLE_ANIM_Lev3_Rear_Idle: if (dy < 0 && dy > -m_flMaxYaw) dy = -m_flMaxYaw; if (dy > 0 && dy < m_flMaxYaw) dy = m_flMaxYaw; break; default: if (dy < -m_flMaxYaw) dy = -m_flMaxYaw; if (dy > m_flMaxYaw) dy = m_flMaxYaw; } GetMotor()->SetIdealYaw( m_flInitialYaw + dy ); if ( IsSequenceFinished() ) { // ALERT( at_console, "%s done %d %d\n", STRING( pev->targetname ), pev->sequence, m_iGoalAnim ); if ( m_iHealth <= 1) { m_iGoalAnim = TENTACLE_ANIM_Pit_Idle; if ( GetSequence() == TENTACLE_ANIM_Pit_Idle) { m_iHealth = 75; } } else if ( m_flSoundTime > gpGlobals->curtime ) { if (m_flSoundYaw >= -(m_flMaxYaw + 30) && m_flSoundYaw <= (m_flMaxYaw + 30)) { // strike switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1030 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1031 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1032 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1033 ); break; } } else if (m_flSoundYaw >= -m_flMaxYaw * 2 && m_flSoundYaw <= m_flMaxYaw * 2) { // tap switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1020 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1021 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1022 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1023 ); break; } } else { // go into rear idle switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1040 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1041 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1042 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1043 ); break; case 4: m_iGoalAnim = SelectWeightedSequence ( ACT_1044 ); break; } } } else if ( GetSequence() == TENTACLE_ANIM_Pit_Idle) { // stay in pit until hear noise m_iGoalAnim = TENTACLE_ANIM_Pit_Idle; } else if ( GetSequence() == m_iGoalAnim) { if ( MyLevel() >= 0 && gpGlobals->curtime < m_flSoundTime) { if ( random->RandomInt(0,9) < m_flSoundTime - gpGlobals->curtime ) { // continue stike switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1030 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1031 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1032 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1033 ); break; } } else { // tap switch ( m_iSoundLevel ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1020 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1021 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1022 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1023 ); break; } } } else if ( MyLevel( ) < 0 ) { m_iGoalAnim = SelectWeightedSequence( ACT_1010 ); } else { if (m_flNextSong < gpGlobals->curtime) { // play "I hear new something" sound CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Tentacle.Sing" ); m_flNextSong = gpGlobals->curtime + random->RandomFloat( 10, 20 ); } if (random->RandomInt(0,15) == 0) { // idle on new level switch ( random->RandomInt( 0, 3 ) ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1010 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1011 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1012 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1013 ); break; } } else if ( random->RandomInt( 0, 3 ) == 0 ) { // tap switch ( MyLevel() ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1020 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1021 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1022 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1023 ); break; } } else { // idle switch ( MyLevel() ) { case 0: m_iGoalAnim = SelectWeightedSequence ( ACT_1010 ); break; case 1: m_iGoalAnim = SelectWeightedSequence ( ACT_1011 ); break; case 2: m_iGoalAnim = SelectWeightedSequence ( ACT_1012 ); break; case 3: m_iGoalAnim = SelectWeightedSequence ( ACT_1013 ); break; } } } if (m_flSoundYaw < 0) m_flSoundYaw += random->RandomFloat( 2, 8 ); else m_flSoundYaw -= random->RandomFloat( 2, 8 ); } SetSequence( FindTransitionSequence( GetSequence(), m_iGoalAnim, &m_iDir ) ); if (m_iDir > 0) { SetCycle( 0 ); } else { m_iDir = -1; // just to safe SetCycle( 1.0f ); } ResetSequenceInfo( ); m_flFramerateAdj = random->RandomFloat( -0.2, 0.2 ); m_flPlaybackRate = m_iDir * 1.0 + m_flFramerateAdj; switch( GetSequence() ) { case TENTACLE_ANIM_Floor_Tap: case TENTACLE_ANIM_Lev1_Tap: case TENTACLE_ANIM_Lev2_Tap: case TENTACLE_ANIM_Lev3_Tap: { Vector vecSrc, v_forward; AngleVectors( GetAbsAngles(), &v_forward ); trace_t tr1, tr2; vecSrc = GetAbsOrigin() + Vector( 0, 0, MyHeight() - 4); UTIL_TraceLine( vecSrc, vecSrc + v_forward * 512, MASK_NPCSOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr1 ); vecSrc = GetAbsOrigin() + Vector( 0, 0, MyHeight() + 8); UTIL_TraceLine( vecSrc, vecSrc + v_forward * 512, MASK_NPCSOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr2 ); // ALERT( at_console, "%f %f\n", tr1.flFraction * 512, tr2.flFraction * 512 ); m_flTapRadius = SetPoseParameter( 0, random->RandomFloat( tr1.fraction * 512, tr2.fraction * 512 ) ); } break; default: m_flTapRadius = 336; // 400 - 64 break; } SetViewOffset( Vector( 0, 0, MyHeight() ) ); // ALERT( at_console, "seq %d\n", pev->sequence ); } if (m_flPrevSoundTime + 2.0 > gpGlobals->curtime) { // 1.5 normal speed if hears sounds m_flPlaybackRate = m_iDir * 1.5 + m_flFramerateAdj; } else if (m_flPrevSoundTime + 5.0 > gpGlobals->curtime) { // slowdown to normal m_flPlaybackRate = m_iDir + m_iDir * (5 - (gpGlobals->curtime - m_flPrevSoundTime)) / 2 + m_flFramerateAdj; } }