//--------------------------------------------------------- //--------------------------------------------------------- void CNPC_GroundTurret::DeathEffects() { if( !m_bHasExploded ) { //ExplosionCreate( GetAbsOrigin(), QAngle( 0, 0, 1 ), this, 150, 150, false ); CTakeDamageInfo info; DeathSound( info ); m_bHasExploded = true; SetNextThink( gpGlobals->curtime + 0.5 ); } else { // Sparks EmitSound( "DoSpark" ); m_iDeathSparks--; if( m_iDeathSparks == 0 ) { SetThink(NULL); return; } SetNextThink( gpGlobals->curtime + random->RandomFloat( 0.5, 2.5 ) ); } }
void CASW_Simple_Alien::Event_Killed( const CTakeDamageInfo &info ) { if (ASWGameRules()) { ASWGameRules()->AlienKilled(this, info); } if (m_hSpawner.Get()) m_hSpawner->AlienKilled(this); // Calculate death force Vector forceVector = CalcDeathForceVector( info ); StopLoopingSounds(); DeathSound(info); // todo: remove touch function? SetState(ASW_SIMPLE_ALIEN_DEAD); // todo: Select a death pose to extrapolate the ragdoll's velocity? //SelectDeathPose( info ); if (!ShouldGib(info)) { SetCollisionGroup(ASW_COLLISION_GROUP_PASSABLE); // don't block marines by dead bodies if ( BecomeRagdollOnClient( forceVector ) ) { } } else { Event_Gibbed( info ); } }
//========================================================= // Start task - selects the correct activity and performs // any necessary calculations to start the next task on the // schedule. //========================================================= void CBaseMonster :: StartTask ( Task_t *pTask ) { switch ( pTask->iTask ) { case TASK_TURN_RIGHT: { float flCurrentYaw; flCurrentYaw = UTIL_AngleMod( pev->angles.y ); pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw - pTask->flData ); SetTurnActivity(); break; } case TASK_TURN_LEFT: { float flCurrentYaw; flCurrentYaw = UTIL_AngleMod( pev->angles.y ); pev->ideal_yaw = UTIL_AngleMod( flCurrentYaw + pTask->flData ); SetTurnActivity(); break; } case TASK_REMEMBER: { Remember ( (int)pTask->flData ); TaskComplete(); break; } case TASK_FORGET: { Forget ( (int)pTask->flData ); TaskComplete(); break; } case TASK_FIND_HINTNODE: { m_iHintNode = FindHintNode(); if ( m_iHintNode != NO_NODE ) { TaskComplete(); } else { TaskFail(); } break; } case TASK_STORE_LASTPOSITION: { m_vecLastPosition = pev->origin; TaskComplete(); break; } case TASK_CLEAR_LASTPOSITION: { m_vecLastPosition = g_vecZero; TaskComplete(); break; } case TASK_CLEAR_HINTNODE: { m_iHintNode = NO_NODE; TaskComplete(); break; } case TASK_STOP_MOVING: { if ( m_IdealActivity == m_movementActivity ) { m_IdealActivity = GetStoppedActivity(); } RouteClear(); TaskComplete(); break; } case TASK_PLAY_SEQUENCE_FACE_ENEMY: case TASK_PLAY_SEQUENCE_FACE_TARGET: case TASK_PLAY_SEQUENCE: { m_IdealActivity = ( Activity )( int )pTask->flData; break; } case TASK_PLAY_ACTIVE_IDLE: { // monsters verify that they have a sequence for the node's activity BEFORE // moving towards the node, so it's ok to just set the activity without checking here. m_IdealActivity = ( Activity )WorldGraph.m_pNodes[ m_iHintNode ].m_sHintActivity; break; } case TASK_SET_SCHEDULE: { Schedule_t *pNewSchedule; pNewSchedule = GetScheduleOfType( (int)pTask->flData ); if ( pNewSchedule ) { ChangeSchedule( pNewSchedule ); } else { TaskFail(); } break; } case TASK_FIND_NEAR_NODE_COVER_FROM_ENEMY: { if ( m_hEnemy == NULL ) { TaskFail(); return; } if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, pTask->flData ) ) { // try for cover farther than the FLData from the schedule. TaskComplete(); } else { // no coverwhatsoever. TaskFail(); } break; } case TASK_FIND_FAR_NODE_COVER_FROM_ENEMY: { if ( m_hEnemy == NULL ) { TaskFail(); return; } if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, pTask->flData, CoverRadius() ) ) { // try for cover farther than the FLData from the schedule. TaskComplete(); } else { // no coverwhatsoever. TaskFail(); } break; } case TASK_FIND_NODE_COVER_FROM_ENEMY: { if ( m_hEnemy == NULL ) { TaskFail(); return; } if ( FindCover( m_hEnemy->pev->origin, m_hEnemy->pev->view_ofs, 0, CoverRadius() ) ) { // try for cover farther than the FLData from the schedule. TaskComplete(); } else { // no coverwhatsoever. TaskFail(); } break; } case TASK_FIND_COVER_FROM_ENEMY: { entvars_t *pevCover; if ( m_hEnemy == NULL ) { // Find cover from self if no enemy available pevCover = pev; // TaskFail(); // return; } else pevCover = m_hEnemy->pev; if ( FindLateralCover( pevCover->origin, pevCover->view_ofs ) ) { // try lateral first m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } else if ( FindCover( pevCover->origin, pevCover->view_ofs, 0, CoverRadius() ) ) { // then try for plain ole cover m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } else { // no coverwhatsoever. TaskFail(); } break; } case TASK_FIND_COVER_FROM_ORIGIN: { if ( FindCover( pev->origin, pev->view_ofs, 0, CoverRadius() ) ) { // then try for plain ole cover m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } else { // no cover! TaskFail(); } } break; case TASK_FIND_COVER_FROM_BEST_SOUND: { CSound *pBestSound; pBestSound = PBestSound(); ASSERT( pBestSound != NULL ); /* if ( pBestSound && FindLateralCover( pBestSound->m_vecOrigin, g_vecZero ) ) { // try lateral first m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } */ if ( pBestSound && FindCover( pBestSound->m_vecOrigin, g_vecZero, pBestSound->m_iVolume, CoverRadius() ) ) { // then try for plain ole cover m_flMoveWaitFinished = gpGlobals->time + pTask->flData; TaskComplete(); } else { // no coverwhatsoever. or no sound in list TaskFail(); } break; } case TASK_FACE_HINTNODE: { pev->ideal_yaw = WorldGraph.m_pNodes[ m_iHintNode ].m_flHintYaw; SetTurnActivity(); break; } case TASK_FACE_LASTPOSITION: MakeIdealYaw ( m_vecLastPosition ); SetTurnActivity(); break; case TASK_FACE_TARGET: if ( m_hTargetEnt != NULL ) { MakeIdealYaw ( m_hTargetEnt->pev->origin ); SetTurnActivity(); } else TaskFail(); break; case TASK_FACE_ENEMY: { MakeIdealYaw ( m_vecEnemyLKP ); SetTurnActivity(); break; } case TASK_FACE_IDEAL: { SetTurnActivity(); break; } case TASK_FACE_ROUTE: { if (FRouteClear()) { ALERT(at_aiconsole, "No route to face!\n"); TaskFail(); } else { MakeIdealYaw(m_Route[m_iRouteIndex].vecLocation); SetTurnActivity(); } break; } case TASK_WAIT_PVS: case TASK_WAIT_INDEFINITE: { // don't do anything. break; } case TASK_WAIT: case TASK_WAIT_FACE_ENEMY: {// set a future time that tells us when the wait is over. m_flWaitFinished = gpGlobals->time + pTask->flData; break; } case TASK_WAIT_RANDOM: {// set a future time that tells us when the wait is over. m_flWaitFinished = gpGlobals->time + RANDOM_FLOAT( 0.1, pTask->flData ); break; } case TASK_MOVE_TO_TARGET_RANGE: { if ( (m_hTargetEnt->pev->origin - pev->origin).Length() < 1 ) TaskComplete(); else { m_vecMoveGoal = m_hTargetEnt->pev->origin; if ( !MoveToTarget( ACT_WALK, 2 ) ) TaskFail(); } break; } case TASK_RUN_TO_SCRIPT: case TASK_WALK_TO_SCRIPT: { Activity newActivity; if ( !m_pGoalEnt || (m_pGoalEnt->pev->origin - pev->origin).Length() < 1 ) TaskComplete(); else { if ( pTask->iTask == TASK_WALK_TO_SCRIPT ) newActivity = ACT_WALK; else newActivity = ACT_RUN; // This monster can't do this! if ( LookupActivity( newActivity ) == ACTIVITY_NOT_AVAILABLE ) TaskComplete(); else { if ( m_pGoalEnt != NULL ) { Vector vecDest; vecDest = m_pGoalEnt->pev->origin; if ( !MoveToLocation( newActivity, 2, vecDest ) ) { TaskFail(); ALERT( at_aiconsole, "%s Failed to reach script!!!\n", STRING(pev->classname) ); RouteClear(); } } else { TaskFail(); ALERT( at_aiconsole, "%s: MoveTarget is missing!?!\n", STRING(pev->classname) ); RouteClear(); } } } TaskComplete(); break; } case TASK_CLEAR_MOVE_WAIT: { m_flMoveWaitFinished = gpGlobals->time; TaskComplete(); break; } case TASK_MELEE_ATTACK1_NOTURN: case TASK_MELEE_ATTACK1: { m_IdealActivity = ACT_MELEE_ATTACK1; break; } case TASK_MELEE_ATTACK2_NOTURN: case TASK_MELEE_ATTACK2: { m_IdealActivity = ACT_MELEE_ATTACK2; break; } case TASK_RANGE_ATTACK1_NOTURN: case TASK_RANGE_ATTACK1: { m_IdealActivity = ACT_RANGE_ATTACK1; break; } case TASK_RANGE_ATTACK2_NOTURN: case TASK_RANGE_ATTACK2: { m_IdealActivity = ACT_RANGE_ATTACK2; break; } case TASK_RELOAD_NOTURN: case TASK_RELOAD: { m_IdealActivity = ACT_RELOAD; break; } case TASK_SPECIAL_ATTACK1: { m_IdealActivity = ACT_SPECIAL_ATTACK1; break; } case TASK_SPECIAL_ATTACK2: { m_IdealActivity = ACT_SPECIAL_ATTACK2; break; } case TASK_SET_ACTIVITY: { m_IdealActivity = (Activity)(int)pTask->flData; TaskComplete(); break; } case TASK_GET_PATH_TO_ENEMY_LKP: { if ( BuildRoute ( m_vecEnemyLKP, bits_MF_TO_LOCATION, NULL ) ) { TaskComplete(); } else if (BuildNearestRoute( m_vecEnemyLKP, pev->view_ofs, 0, (m_vecEnemyLKP - pev->origin).Length() )) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToEnemyLKP failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_ENEMY: { CBaseEntity *pEnemy = m_hEnemy; if ( pEnemy == NULL ) { TaskFail(); return; } if ( BuildRoute ( pEnemy->pev->origin, bits_MF_TO_ENEMY, pEnemy ) ) { TaskComplete(); } else if (BuildNearestRoute( pEnemy->pev->origin, pEnemy->pev->view_ofs, 0, (pEnemy->pev->origin - pev->origin).Length() )) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToEnemy failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_ENEMY_CORPSE: { UTIL_MakeVectors( pev->angles ); if ( BuildRoute ( m_vecEnemyLKP - gpGlobals->v_forward * 64, bits_MF_TO_LOCATION, NULL ) ) { TaskComplete(); } else { ALERT ( at_aiconsole, "GetPathToEnemyCorpse failed!!\n" ); TaskFail(); } } break; case TASK_GET_PATH_TO_SPOT: { CBaseEntity *pPlayer = UTIL_FindEntityByClassname( NULL, "player" ); if ( BuildRoute ( m_vecMoveGoal, bits_MF_TO_LOCATION, pPlayer ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_TARGET: { RouteClear(); if ( m_hTargetEnt != NULL && MoveToTarget( m_movementActivity, 1 ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_SCRIPT: { RouteClear(); if ( m_pCine != NULL && MoveToLocation( m_movementActivity, 1, m_pCine->pev->origin ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToSpot failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_HINTNODE:// for active idles! { if ( MoveToLocation( m_movementActivity, 2, WorldGraph.m_pNodes[ m_iHintNode ].m_vecOrigin ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToHintNode failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_LASTPOSITION: { m_vecMoveGoal = m_vecLastPosition; if ( MoveToLocation( m_movementActivity, 2, m_vecMoveGoal ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToLastPosition failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_BESTSOUND: { CSound *pSound; pSound = PBestSound(); if ( pSound && MoveToLocation( m_movementActivity, 2, pSound->m_vecOrigin ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToBestSound failed!!\n" ); TaskFail(); } break; } case TASK_GET_PATH_TO_BESTSCENT: { CSound *pScent; pScent = PBestScent(); if ( pScent && MoveToLocation( m_movementActivity, 2, pScent->m_vecOrigin ) ) { TaskComplete(); } else { // no way to get there =( ALERT ( at_aiconsole, "GetPathToBestScent failed!!\n" ); TaskFail(); } break; } case TASK_RUN_PATH: { // UNDONE: This is in some default AI and some monsters can't run? -- walk instead? if ( LookupActivity( ACT_RUN ) != ACTIVITY_NOT_AVAILABLE ) { m_movementActivity = ACT_RUN; } else { m_movementActivity = ACT_WALK; } TaskComplete(); break; } case TASK_WALK_PATH: { if ( pev->movetype == MOVETYPE_FLY ) { m_movementActivity = ACT_FLY; } if ( LookupActivity( ACT_WALK ) != ACTIVITY_NOT_AVAILABLE ) { m_movementActivity = ACT_WALK; } else { m_movementActivity = ACT_RUN; } TaskComplete(); break; } case TASK_STRAFE_PATH: { Vector2D vec2DirToPoint; Vector2D vec2RightSide; // to start strafing, we have to first figure out if the target is on the left side or right side UTIL_MakeVectors ( pev->angles ); vec2DirToPoint = ( m_Route[ 0 ].vecLocation - pev->origin ).Make2D().Normalize(); vec2RightSide = gpGlobals->v_right.Make2D().Normalize(); if ( DotProduct ( vec2DirToPoint, vec2RightSide ) > 0 ) { // strafe right m_movementActivity = ACT_STRAFE_RIGHT; } else { // strafe left m_movementActivity = ACT_STRAFE_LEFT; } TaskComplete(); break; } case TASK_WAIT_FOR_MOVEMENT: { if (FRouteClear()) { TaskComplete(); } break; } case TASK_EAT: { Eat( pTask->flData ); TaskComplete(); break; } case TASK_SMALL_FLINCH: { m_IdealActivity = GetSmallFlinchActivity(); break; } case TASK_DIE: { RouteClear(); m_IdealActivity = GetDeathActivity(); pev->deadflag = DEAD_DYING; break; } case TASK_SOUND_WAKE: { AlertSound(); TaskComplete(); break; } case TASK_SOUND_DIE: { DeathSound(); TaskComplete(); break; } case TASK_SOUND_IDLE: { IdleSound(); TaskComplete(); break; } case TASK_SOUND_PAIN: { PainSound(); TaskComplete(); break; } case TASK_SOUND_DEATH: { DeathSound(); TaskComplete(); break; } case TASK_SOUND_ANGRY: { // sounds are complete as soon as we get here, cause we've already played them. ALERT ( at_aiconsole, "SOUND\n" ); TaskComplete(); break; } case TASK_WAIT_FOR_SCRIPT: { if ( m_pCine->m_iDelay <= 0 && gpGlobals->time >= m_pCine->m_startTime ) { TaskComplete(); //LRC - start playing immediately } else if (!m_pCine->IsAction() && m_pCine->m_iszIdle) { m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszIdle, FALSE ); if (FStrEq( STRING(m_pCine->m_iszIdle), STRING(m_pCine->m_iszPlay))) { pev->framerate = 0; } } else m_IdealActivity = ACT_IDLE; break; } case TASK_PLAY_SCRIPT: { if (m_pCine->IsAction()) { //ALERT(at_console,"PlayScript: setting idealactivity %d\n",m_pCine->m_fAction); switch(m_pCine->m_fAction) { case 0: m_IdealActivity = ACT_RANGE_ATTACK1; break; case 1: m_IdealActivity = ACT_RANGE_ATTACK2; break; case 2: m_IdealActivity = ACT_MELEE_ATTACK1; break; case 3: m_IdealActivity = ACT_MELEE_ATTACK2; break; case 4: m_IdealActivity = ACT_SPECIAL_ATTACK1; break; case 5: m_IdealActivity = ACT_SPECIAL_ATTACK2; break; case 6: m_IdealActivity = ACT_RELOAD; break; case 7: m_IdealActivity = ACT_HOP; break; } pev->framerate = 1.0; // shouldn't be needed, but just in case pev->movetype = MOVETYPE_FLY; ClearBits(pev->flags, FL_ONGROUND); } else { m_pCine->StartSequence( (CBaseMonster *)this, m_pCine->m_iszPlay, TRUE ); if ( m_fSequenceFinished ) ClearSchedule(); pev->framerate = 1.0; //ALERT( at_aiconsole, "Script %s has begun for %s\n", STRING( m_pCine->m_iszPlay ), STRING(pev->classname) ); } m_scriptState = SCRIPT_PLAYING; break; } case TASK_ENABLE_SCRIPT: { m_pCine->DelayStart( 0 ); TaskComplete(); break; } //LRC case TASK_END_SCRIPT: { m_pCine->SequenceDone( this ); TaskComplete(); break; } case TASK_PLANT_ON_SCRIPT: { if ( m_pCine != NULL ) { // Plant on script // LRC - if it's a teleport script, do the turn too if (m_pCine->m_fMoveTo == 4 || m_pCine->m_fMoveTo == 6) { if (m_pCine->m_fTurnType == 0) //LRC pev->angles.y = m_hTargetEnt->pev->angles.y; else if (m_pCine->m_fTurnType == 1) pev->angles.y = UTIL_VecToYaw(m_hTargetEnt->pev->origin - pev->origin); pev->ideal_yaw = pev->angles.y; pev->avelocity = Vector( 0, 0, 0 ); pev->velocity = Vector( 0, 0, 0 ); pev->effects |= EF_NOINTERP; } if (m_pCine->m_fMoveTo != 6) pev->origin = m_pGoalEnt->pev->origin; } TaskComplete(); break; } case TASK_FACE_SCRIPT: { if ( m_pCine != NULL && m_pCine->m_fMoveTo != 0) // movetype "no move" makes us ignore turntype { switch (m_pCine->m_fTurnType) { case 0: pev->ideal_yaw = UTIL_AngleMod( m_pCine->pev->angles.y ); break; case 1: // yes, this is inconsistent- turn to face uses the "target" and turn to angle uses the "cine". if (m_hTargetEnt) MakeIdealYaw ( m_hTargetEnt->pev->origin ); else MakeIdealYaw ( m_pCine->pev->origin ); break; // default: don't turn } } TaskComplete(); m_IdealActivity = ACT_IDLE; RouteClear(); break; } case TASK_SUGGEST_STATE: { m_IdealMonsterState = (MONSTERSTATE)(int)pTask->flData; TaskComplete(); break; } case TASK_SET_FAIL_SCHEDULE: m_failSchedule = (int)pTask->flData; TaskComplete(); break; case TASK_CLEAR_FAIL_SCHEDULE: m_failSchedule = SCHED_NONE; TaskComplete(); break; default: { ALERT ( at_aiconsole, "No StartTask entry for %d\n", (SHARED_TASKS)pTask->iTask ); break; } } }
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 PlayerDie() { self->ca_alive = false; DropPowerups(); if ( isCTF() ) { if ( self->hook_out ) { GrappleReset( self->hook ); self->attack_finished = g_globalvars.time + 0.75; self->hook_out = true; // FIXME: for which reason this set to true? } DropRune(); PlayerDropFlag( self, false ); } TeamplayDeathEvent (self); #ifdef BOT_SUPPORT BotPlayerDeathEvent (self); #endif self->s.v.items -= ( int ) self->s.v.items & IT_INVISIBILITY; self->invisible_finished = 0; // don't die as eyes self->invincible_finished = 0; // so we have quad few milleseconds after death // self->super_damage_finished = 0; // moved to prethink, like in ktpro self->radsuit_finished = 0; self->s.v.modelindex = modelindex_player; // don't use eyes DropBackpack(); self->weaponmodel = ""; if (vw_enabled) self->vw_index = 9; // null vwep model SetVector( self->s.v.view_ofs, 0, 0, -8 ); self->s.v.deadflag = DEAD_DYING; self->s.v.solid = SOLID_NOT; self->s.v.flags -= ( ( int ) ( self->s.v.flags ) ) & FL_ONGROUND; self->s.v.movetype = MOVETYPE_TOSS; if ( self->s.v.velocity[2] < 10 ) self->s.v.velocity[2] = self->s.v.velocity[2] + g_random() * 300; if ( self->s.v.health < -40 || dtSQUISH == self->deathtype || dtSUICIDE == self->deathtype || isRA() || isCA() ) { GibPlayer(); // Yawnmode: respawn has the same delay (900ms) regardless of deathtype gib/normal // - Molgrum // Hoonymode: Also force some time, e.g. to prevent instant respawn after /kill which // can cause bug if kill telefrags an idle player (counts as two points...) // only ever happens in testing, but oh well --phil if ( k_yawnmode || isHoonyModeDuel() ) { self->s.v.nextthink = g_globalvars.time + 0.9; self->think = ( func_t ) PlayerDead; return; } PlayerDead(); return; } if( match_in_progress == 2 ) DeathSound(); self->s.v.angles[0] = 0; self->s.v.angles[2] = 0; // function part split and called here StartDie(); }
//========================================================================= // Function handling the Spy's feign death ability void TeamFortress_SpyFeignDeath( int issilent ) { int i, j; gedict_t *at_spot; gedict_t *te; self->StatusRefreshTime = g_globalvars.time + 0.1; if ( self->is_feigning ) { // Check to make sure there isn't anyone on top of us at_spot = findradius( world, self->s.v.origin, 64 ); i = 1; j = 0; while ( at_spot ) { if ( streq( at_spot->mdl, "progs/detpack.mdl" ) ) j = 1; if ( streq( at_spot->mdl, "progs/detpack2.mdl" ) && tf_data.birthday == 1 ) j = 1; if ( streq( at_spot->mdl, "progs/turrbase.mdl" ) ) j = 1; if ( streq( at_spot->mdl, "progs/turrgun.mdl" ) ) j = 1; // if ( streq( at_spot->mdl, "progs/disp.mdl" ) ) // j = 1; if ( streq( at_spot->mdl, "progs/dispencr.mdl" ) ) j = 1; if ( streq( at_spot->s.v.classname, "player" ) && !at_spot->s.v.deadflag && self != at_spot ) j = 2; switch ( j ) { case 1: G_sprint( self, 2, "You can't get up with something\non top of you.\n" ); return; case 2: G_sprint( self, 2, "You can't get up while someone\nis standing on you.\n" ); return; } at_spot = findradius( at_spot, self->s.v.origin, 64 ); } if ( self->is_squating == TRUE ) unlay ( ); SetVector( self->s.v.velocity, 0, 0, 0 ); setsize( self, -16, -16, -24, 16, 16, 32 ); SetVector( self->s.v.view_ofs, 0, 0, 22 ); self->s.v.movetype = MOVETYPE_WALK; self->is_feigning = 0; self->current_weapon = self->s.v.weapon; W_SetCurrentAmmo( ); self->tfstate = self->tfstate - ( self->tfstate & TFSTATE_CANT_MOVE ); TeamFortress_SetSpeed( self ); // Check .weapon, because .current_weapon has been reset if ( self->s.v.weapon <= 16 ) { spy_upaxe1( ); return; } switch ( ( int ) ( g_random( ) * 4 ) ) { case 0: spy_upb1( ); break; case 1: spy_upc1( ); break; case 2: spy_upd1( ); break; default: spy_upe1( ); break; } return; } else // !self->is_feigning { if ( self->hook_out ) { G_sprint( self, 2, "You can't feign with the hook out.\n" ); return; } //REMOVE!!! /* if (self.is_unabletospy == 1) { G_sprint(self, 2, "You can't go undercover right now.\n"); return; }*/ /* if (!(self.flags & 512) && !self->s.v.waterlevel) { G_sprint(self, 2, "You can't feign in the air.\n"); return; }*/ for ( at_spot = world; ( at_spot = findradius( at_spot, self->s.v.origin, 64 ) ) ; ) { if ( streq( at_spot->s.v.classname, "player" ) && self != at_spot && at_spot->is_feigning == 1 ) { G_sprint( self, 2, "You can't feign on top of another spy!\n" ); return; } } self->tfstate = self->tfstate | TFSTATE_CANT_MOVE; TeamFortress_SetSpeed( self ); self->is_feigning = 1; Attack_Finished( 0.8 ); self->invisible_finished = 0; self->s.v.modelindex = modelindex_player; self->s.v.weapon = self->current_weapon; self->current_weapon = 0; self->s.v.weaponmodel = ""; self->s.v.weaponframe = 0; setsize( self, -16, -16, -24, 16, 16, -16 ); SetVector( self->s.v.view_ofs, 0, 0, 4 ); self->s.v.movetype = MOVETYPE_TOSS; if ( !issilent ) DeathSound( ); self->s.v.angles[0] = 0; self->s.v.angles[2] = 0; if ( self->s.v.weapon <= 16 ) { spy_die_ax1( ); return; } te = world; for( te = world; ( te = trap_find( te, FOFS( s.v.classname ), "item_tfgoal" ) ) ;) { if ( te->s.v.owner != EDICT_TO_PROG( self ) ) continue; if ( !( te->goal_activation & TFGI_KEEP ) || self->has_disconnected == 1 ) tfgoalitem_RemoveFromPlayer( te, self, 0 ); if ( CTF_Map == 1 ) { if ( te->goal_no == 1 ) G_bprint( 2, "%s лост the блуе flag!\n", self->s.v.netname ); else G_bprint( 2, "%s лост the ред flag!\n", self->s.v.netname ); } } switch ( ( int ) ( g_random( ) * 5 ) ) { case 0: spy_diea1( ); break; case 1: spy_dieb1( ); break; case 2: spy_diec1( ); break; case 3: spy_died1( ); break; default: spy_diee1( ); break; } } }