/* ------------------------- MineMonster_Patrol ------------------------- */ void MineMonster_Patrol( void ) { NPCInfo->localState = LSTATE_CLEAR; //If we have somewhere to go, then do that if ( UpdateGoal() ) { ucmd.buttons &= ~BUTTON_WALKING; NPC_MoveToGoal( qtrue ); } vec3_t dif; VectorSubtract( g_entities[0].currentOrigin, NPC->currentOrigin, dif ); if ( VectorLengthSquared( dif ) < 256 * 256 ) { G_SetEnemy( NPC, &g_entities[0] ); } if ( NPC_CheckEnemyExt( qtrue ) == qfalse ) { MineMonster_Idle(); return; } }
/* ------------------------- Mark2_Patrol ------------------------- */ void Mark2_Patrol( void ) { if ( NPC_CheckPlayerTeamStealth() ) { NPC_UpdateAngles( qtrue, qtrue ); return; } //If we have somewhere to go, then do that if (!NPC->enemy) { if ( UpdateGoal() ) { ucmd.buttons |= BUTTON_WALKING; NPC_MoveToGoal( qtrue ); NPC_UpdateAngles( qtrue, qtrue ); } //randomly talk if (TIMER_Done(NPC,"patrolNoise")) { TIMER_Set( NPC, "patrolNoise", Q_irand( 2000, 4000 ) ); } } }
/* ------------------------- GM_Move ------------------------- */ static qboolean GM_Move( void ) { NPCInfo->combatMove = qtrue;//always bMove straight toward our goal qboolean moved = NPC_MoveToGoal( qtrue ); navInfo_t info; //Get the bMove info NAV_GetLastMove( info ); //FIXME: if we bump into another one of our guys and can't get around him, just stop! //If we hit our target, then stop and fire! if ( info.flags & NIF_COLLISION ) { if ( info.blocker == NPC->enemy ) { GM_HoldPosition(); } } //If our bMove failed, then reset if ( moved == qfalse ) {//FIXME: if we're going to a combat point, need to pick a different one if ( !Q3_TaskIDPending( NPC, TID_MOVE_NAV ) ) {//can't transfer movegoal or stop when a script we're running is waiting to complete GM_HoldPosition(); } } return moved; }
/* ------------------------- Mark2_Patrol ------------------------- */ void Mark2_Patrol( void ) { if ( NPC_CheckPlayerTeamStealth() ) { // G_Sound( NPC, G_SoundIndex("sound/chars/mark1/misc/anger.wav")); NPC_UpdateAngles( qtrue, qtrue ); return; } //If we have somewhere to go, then do that if (!NPC->enemy) { if ( UpdateGoal() ) { ucmd.buttons |= BUTTON_WALKING; NPC_MoveToGoal( qtrue ); NPC_UpdateAngles( qtrue, qtrue ); } //randomly talk if (TIMER_Done(NPC,"patrolNoise")) { // G_Sound( NPC, G_SoundIndex(va("sound/chars/mark1/misc/talk%d.wav", Q_irand(1, 4)))); TIMER_Set( NPC, "patrolNoise", Q_irand( 2000, 4000 ) ); } } }
/* ------------------------- Howler_Patrol ------------------------- */ void Howler_Patrol( void ) { vector3 dif; NPCInfo->localState = LSTATE_CLEAR; //If we have somewhere to go, then do that if ( UpdateGoal() ) { ucmd.buttons &= ~BUTTON_WALKING; NPC_MoveToGoal( qtrue ); } else { if ( TIMER_Done( NPC, "patrolTime" )) { TIMER_Set( NPC, "patrolTime", crandom() * 5000 + 5000 ); } } //rwwFIXMEFIXME: Care about all clients, not just client 0 VectorSubtract( &g_entities[0].r.currentOrigin, &NPC->r.currentOrigin, &dif ); if ( VectorLengthSquared( &dif ) < 256 * 256 ) { G_SetEnemy( NPC, &g_entities[0] ); } if ( NPC_CheckEnemyExt( qtrue ) == qfalse ) { Howler_Idle(); return; } }
void NPC_BSCinematic( void ) { if( NPCInfo->scriptFlags & SCF_FIRE_WEAPON ) { WeaponThink( qtrue ); } if ( UpdateGoal() ) {//have a goalEntity //move toward goal, should also face that goal NPC_MoveToGoal( qtrue ); } if ( NPCInfo->watchTarget ) {//have an entity which we want to keep facing //NOTE: this will override any angles set by NPC_MoveToGoal vec3_t eyes, viewSpot, viewvec, viewangles; CalcEntitySpot( NPC, SPOT_HEAD_LEAN, eyes ); CalcEntitySpot( NPCInfo->watchTarget, SPOT_HEAD_LEAN, viewSpot ); VectorSubtract( viewSpot, eyes, viewvec ); vectoangles( viewvec, viewangles ); NPCInfo->lockedDesiredYaw = NPCInfo->desiredYaw = viewangles[YAW]; NPCInfo->lockedDesiredPitch = NPCInfo->desiredPitch = viewangles[PITCH]; } NPC_UpdateAngles( qtrue, qtrue ); }
/* ------------------------- Rancor_Patrol ------------------------- */ void Rancor_Patrol( void ) { NPCS.NPCInfo->localState = LSTATE_CLEAR; //If we have somewhere to go, then do that if ( UpdateGoal() ) { NPCS.ucmd.buttons &= ~BUTTON_WALKING; NPC_MoveToGoal( qtrue ); } else { if ( TIMER_Done( NPCS.NPC, "patrolTime" )) { TIMER_Set( NPCS.NPC, "patrolTime", crandom() * 5000 + 5000 ); } } if ( NPC_CheckEnemyExt( qtrue ) == qfalse ) { Rancor_Idle(); return; } Rancor_CheckRoar( NPCS.NPC ); TIMER_Set( NPCS.NPC, "lookForNewEnemy", Q_irand( 5000, 15000 ) ); }
void ImperialProbe_Patrol( void ) { ImperialProbe_MaintainHeight(); if ( NPC_CheckPlayerTeamStealth() ) { NPC_UpdateAngles( qtrue, qtrue ); return; } //If we have somewhere to go, then do that if ( !NPC->enemy ) { NPC_SetAnim( NPC, SETANIM_BOTH, BOTH_RUN1, SETANIM_FLAG_NORMAL ); if ( UpdateGoal() ) { //start loop sound once we move NPC->s.loopSound = G_SoundIndex( "sound/chars/probe/misc/probedroidloop" ); ucmd.buttons |= BUTTON_WALKING; NPC_MoveToGoal( qtrue ); } //randomly talk if ( TIMER_Done( NPC, "patrolNoise" ) ) { G_SoundOnEnt( NPC, CHAN_AUTO, va( "sound/chars/probe/misc/probetalk%d", Q_irand( 1, 3 ) ) ); TIMER_Set( NPC, "patrolNoise", Q_irand( 2000, 4000 ) ); } } else // He's got an enemy. Make him angry. { G_SoundOnEnt( NPC, CHAN_AUTO, "sound/chars/probe/misc/anger1" ); TIMER_Set( NPC, "angerNoise", Q_irand( 2000, 4000 ) ); //NPCInfo->behaviorState = BS_HUNT_AND_KILL; } NPC_UpdateAngles( qtrue, qtrue ); }
/* ------------------------- NPC_Sentry_Patrol ------------------------- */ void NPC_Sentry_Patrol( void ) { Sentry_MaintainHeight(); //If we have somewhere to go, then do that if ( !NPC->enemy ) { if ( NPC_CheckPlayerTeamStealth() ) { //NPC_AngerSound(); NPC_UpdateAngles( qtrue, qtrue ); return; } if ( UpdateGoal() ) { //start loop sound once we move ucmd.buttons |= BUTTON_WALKING; NPC_MoveToGoal( qtrue ); } //randomly talk if ( TIMER_Done( NPC, "patrolNoise" ) ) { G_SoundOnEnt( NPC, CHAN_AUTO, va( "sound/chars/sentry/misc/talk%d", Q_irand( 1, 3 ) ) ); TIMER_Set( NPC, "patrolNoise", Q_irand( 2000, 4000 ) ); } } NPC_UpdateAngles( qtrue, qtrue ); }
/* ------------------------- Howler_Patrol ------------------------- */ void Howler_Patrol( void ) { NPCInfo->localState = LSTATE_CLEAR; //If we have somewhere to go, then do that if ( UpdateGoal() ) { ucmd.buttons &= ~BUTTON_WALKING; NPC_MoveToGoal( qtrue ); } else { if ( TIMER_Done( NPC, "patrolTime" )) { TIMER_Set( NPC, "patrolTime", crandom() * 5000 + 5000 ); } } vec3_t dif; VectorSubtract( g_entities[0].currentOrigin, NPC->currentOrigin, dif ); if ( VectorLengthSquared( dif ) < 256 * 256 ) { G_SetEnemy( NPC, &g_entities[0] ); } if ( NPC_CheckEnemyExt( qtrue ) == qfalse ) { Howler_Idle(); return; } }
/* ------------------------- MineMonster_Patrol ------------------------- */ void MineMonster_Patrol( void ) { vec3_t dif; NPCS.NPCInfo->localState = LSTATE_CLEAR; //If we have somewhere to go, then do that if ( UpdateGoal() ) { NPCS.ucmd.buttons &= ~BUTTON_WALKING; NPC_MoveToGoal( qtrue ); } else { if ( TIMER_Done( NPCS.NPC, "patrolTime" )) { TIMER_Set( NPCS.NPC, "patrolTime", Q_flrand(-1.0f, 1.0f) * 5000 + 5000 ); } } //rwwFIXMEFIXME: Care about all clients, not just client 0 //OJKFIXME: clietnum 0 VectorSubtract( g_entities[0].r.currentOrigin, NPCS.NPC->r.currentOrigin, dif ); if ( VectorLengthSquared( dif ) < 256 * 256 ) { G_SetEnemy( NPCS.NPC, &g_entities[0] ); } if ( NPC_CheckEnemyExt( qtrue ) == qfalse ) { MineMonster_Idle(); return; } }
/* ------------------------- Droid_Run ------------------------- */ void Droid_Run( void ) { R2D2_PartsMove(); if ( NPCInfo->localState == LSTATE_BACKINGUP ) { ucmd.forwardmove = -127; NPCInfo->desiredYaw += 5; NPCInfo->localState = LSTATE_NONE; // So he doesn't constantly backup. } else { ucmd.forwardmove = 64; //If we have somewhere to go, then do that if ( UpdateGoal() ) { if (NPC_MoveToGoal( qfalse )) { NPCInfo->desiredYaw += sin(level.time*.5) * 5; // Weaves side to side a little } } } NPC_UpdateAngles( qtrue, qtrue ); }
/* ------------------------- MineMonster_Idle ------------------------- */ void MineMonster_Idle( void ) { if ( UpdateGoal() ) { ucmd.buttons &= ~BUTTON_WALKING; NPC_MoveToGoal( qtrue ); } }
void Rancor_Idle( void ) { NPCInfo->localState = LSTATE_CLEAR; //If we have somewhere to go, then do that if ( UpdateGoal() ) { ucmd.buttons &= ~BUTTON_WALKING; NPC_MoveToGoal( qtrue ); } }
/* ------------------------- MineMonster_Move ------------------------- */ void MineMonster_Move( qboolean visible ) { if ( NPCInfo->localState != LSTATE_WAITING ) { NPCInfo->goalEntity = NPC->enemy; NPC_MoveToGoal( qtrue ); NPCInfo->goalRadius = MAX_DISTANCE; // just get us within combat range } }
void NPC_BSReaver_Idle( void ) { //See if we have a goal to run to if ( UpdateGoal() ) { NPC_MoveToGoal(); } NPC_UpdateAngles( qfalse, qtrue ); }
qboolean SandCreature_Move( void ) { qboolean moved = qfalse; //FIXME should ignore doors..? vec3_t dest; VectorCopy( NPCInfo->goalEntity->currentOrigin, dest ); //Sand Creatures look silly using waypoints when they can go straight to the goal if ( SandCreature_CheckAhead( dest ) ) {//use our temp move straight to goal check VectorSubtract( dest, NPC->currentOrigin, NPC->client->ps.moveDir ); NPC->client->ps.speed = VectorNormalize( NPC->client->ps.moveDir ); if ( (ucmd.buttons&BUTTON_WALKING) && NPC->client->ps.speed > NPCInfo->stats.walkSpeed ) { NPC->client->ps.speed = NPCInfo->stats.walkSpeed; } else { if ( NPC->client->ps.speed < NPCInfo->stats.walkSpeed ) { NPC->client->ps.speed = NPCInfo->stats.walkSpeed; } if ( !(ucmd.buttons&BUTTON_WALKING) && NPC->client->ps.speed < NPCInfo->stats.runSpeed ) { NPC->client->ps.speed = NPCInfo->stats.runSpeed; } else if ( NPC->client->ps.speed > NPCInfo->stats.runSpeed ) { NPC->client->ps.speed = NPCInfo->stats.runSpeed; } } moved = qtrue; } else { moved = NPC_MoveToGoal( qtrue ); } if ( moved && NPC->radius ) { vec3_t newPos; float curTurfRange, newTurfRange; curTurfRange = DistanceHorizontal( NPC->currentOrigin, NPC->s.origin ); VectorMA( NPC->currentOrigin, NPC->client->ps.speed/100.0f, NPC->client->ps.moveDir, newPos ); newTurfRange = DistanceHorizontal( newPos, NPC->s.origin ); if ( newTurfRange > NPC->radius && newTurfRange > curTurfRange ) {//would leave our range //stop NPC->client->ps.speed = 0.0f; VectorClear( NPC->client->ps.moveDir ); ucmd.forwardmove = ucmd.rightmove = 0; moved = qfalse; } } return (moved); //often erroneously returns false ??? something wrong with NAV...? }
void Droid_Patrol( void ) { NPC->pos1.yaw = AngleNormalize360( NPC->pos1.yaw ); if ( NPC->client && NPC->client->NPC_class != CLASS_GONK ) { if ( NPC->client->NPC_class != CLASS_R5D2 ) { //he doesn't have an eye. R2D2_PartsMove(); // Get his eye moving. } R2D2_TurnAnims(); } //If we have somewhere to go, then do that if ( UpdateGoal() ) { ucmd.buttons |= BUTTON_WALKING; NPC_MoveToGoal( qtrue ); if ( NPC->client && NPC->client->NPC_class == CLASS_MOUSE ) { NPCInfo->desiredYaw += sinf( level.time*.5f ) * 25; // Weaves side to side a little if ( TIMER_Done( NPC, "patrolNoise" ) ) { G_SoundOnEnt( NPC, CHAN_AUTO, va( "sound/chars/mouse/misc/mousego%d.wav", Q_irand( 1, 3 ) ) ); TIMER_Set( NPC, "patrolNoise", Q_irand( 2000, 4000 ) ); } } else if ( NPC->client && NPC->client->NPC_class == CLASS_R2D2 ) { if ( TIMER_Done( NPC, "patrolNoise" ) ) { G_SoundOnEnt( NPC, CHAN_AUTO, va( "sound/chars/r2d2/misc/r2d2talk0%d.wav", Q_irand( 1, 3 ) ) ); TIMER_Set( NPC, "patrolNoise", Q_irand( 2000, 4000 ) ); } } else if ( NPC->client && NPC->client->NPC_class == CLASS_R5D2 ) { if ( TIMER_Done( NPC, "patrolNoise" ) ) { G_SoundOnEnt( NPC, CHAN_AUTO, va( "sound/chars/r5d2/misc/r5talk%d.wav", Q_irand( 1, 4 ) ) ); TIMER_Set( NPC, "patrolNoise", Q_irand( 2000, 4000 ) ); } } if ( NPC->client && NPC->client->NPC_class == CLASS_GONK ) { if ( TIMER_Done( NPC, "patrolNoise" ) ) { G_SoundOnEnt( NPC, CHAN_AUTO, va( "sound/chars/gonk/misc/gonktalk%d.wav", Q_irand( 1, 2 ) ) ); TIMER_Set( NPC, "patrolNoise", Q_irand( 2000, 4000 ) ); } } // else // { // R5D2_LookAround(); // } } NPC_UpdateAngles( qtrue, qtrue ); }
static qboolean Sniper_Move( void ) { qboolean moved; navInfo_t info; NPCInfo->combatMove = qtrue;//always move straight toward our goal moved = NPC_MoveToGoal( qtrue ); //Get the move info NAV_GetLastMove( &info ); //FIXME: if we bump into another one of our guys and can't get around him, just stop! //If we hit our target, then stop and fire! if ( info.flags & NIF_COLLISION ) { if ( info.blocker == NPC->enemy ) { Sniper_HoldPosition(); } } //If our move failed, then reset if ( moved == qfalse ) {//couldn't get to enemy if ( (NPCInfo->scriptFlags&SCF_CHASE_ENEMIES) && NPCInfo->goalEntity && NPCInfo->goalEntity == NPC->enemy ) {//we were running after enemy //Try to find a combat point that can hit the enemy int cpFlags = (CP_CLEAR|CP_HAS_ROUTE); int cp; if ( NPCInfo->scriptFlags&SCF_USE_CP_NEAREST ) { cpFlags &= ~(CP_FLANK|CP_APPROACH_ENEMY|CP_CLOSEST); cpFlags |= CP_NEAREST; } cp = NPC_FindCombatPoint( NPC->r.currentOrigin, NPC->r.currentOrigin, NPC->r.currentOrigin, cpFlags, 32, -1 ); if ( cp == -1 && !(NPCInfo->scriptFlags&SCF_USE_CP_NEAREST) ) {//okay, try one by the enemy cp = NPC_FindCombatPoint( NPC->r.currentOrigin, NPC->r.currentOrigin, NPC->enemy->r.currentOrigin, CP_CLEAR|CP_HAS_ROUTE|CP_HORZ_DIST_COLL, 32, -1 ); } //NOTE: there may be a perfectly valid one, just not one within CP_COLLECT_RADIUS of either me or him... if ( cp != -1 ) {//found a combat point that has a clear shot to enemy NPC_SetCombatPoint( cp ); NPC_SetMoveGoal( NPC, level.combatPoints[cp].origin, 8, qtrue, cp, NULL ); return moved; } } //just hang here Sniper_HoldPosition(); } return moved; }
void Mark2_Hunt( void ) { if ( NPCInfo->goalEntity == NULL ) { NPCInfo->goalEntity = NPC->enemy; } // Turn toward him before moving towards him. NPC_FaceEnemy( qtrue ); NPCInfo->combatMove = qtrue; NPC_MoveToGoal( qtrue ); }
void NPC_BSRun (void) { //FIXME if there is no nav data, we need to do something else // if we're stuck, try to move around it if ( UpdateGoal() ) { NPC_MoveToGoal( qtrue ); } NPC_UpdateAngles( qtrue, qtrue ); }
void ATST_Hunt( qboolean visible, qboolean advance ) { if ( NPCInfo->goalEntity == NULL ) {//hunt NPCInfo->goalEntity = NPC->enemy; } NPCInfo->combatMove = qtrue; NPC_MoveToGoal( qtrue ); }
void Rancor_Move( qboolean visible ) { if ( NPCInfo->localState != LSTATE_WAITING ) { NPCInfo->goalEntity = NPC->enemy; if ( !NPC_MoveToGoal( qtrue ) ) { NPCInfo->consecutiveBlockedMoves++; } else { NPCInfo->consecutiveBlockedMoves = 0; } NPCInfo->goalRadius = MAX_DISTANCE; // just get us within combat range } }
/* ------------------------- void NPC_SlideMoveToGoal( void ) Now assumes goal is goalEntity, if want to use tempGoal, you set that before calling the func ------------------------- */ qboolean NPC_SlideMoveToGoal( void ) { float saveYaw = NPC->client->ps.viewangles.yaw; qboolean ret; NPCInfo->combatMove = qtrue; ret = NPC_MoveToGoal( qtrue ); NPCInfo->desiredYaw = saveYaw; return ret; }
void Hirogen_Hunt( void ) { if ( NPCInfo->combatPoint == -1 ) { NPCInfo->combatPoint = NPC_FindCombatPoint( CP_CLEAR ); if ( NPCInfo->combatPoint == -1 ) { assert(0); return; } //Move there NPC_SetMoveGoal( NPC, level.combatPoints[NPCInfo->combatPoint].origin, 4, qtrue ); NPCInfo->combatMove = qtrue; NPC_MoveToGoal(); NPC_UpdateAngles( qtrue, qtrue ); return; } //See if we made it if ( NAV_HitNavGoal( NPC->currentOrigin, NPC->mins, NPC->maxs, level.combatPoints[NPCInfo->combatPoint].origin, 2 ) ) { NPCInfo->combatPoint = -1; //Hirogen_Hunt(); //NOTENOTE: Remove the 10Hz latency that would be introduced otherwise, but be careful with this one! return; } //Move there NPC_SetMoveGoal( NPC, level.combatPoints[NPCInfo->combatPoint].origin, 2, qtrue ); NPCInfo->combatMove = qtrue; NPC_MoveToGoal(); NPC_UpdateAngles( qtrue, qtrue ); }
/* ------------------------- Mark1_Hunt - look for enemy. -------------------------` */ void Mark1_Hunt(void) { if ( NPCInfo->goalEntity == NULL ) { NPCInfo->goalEntity = NPC->enemy; } NPC_FaceEnemy( qtrue ); NPCInfo->combatMove = qtrue; NPC_MoveToGoal( qtrue ); }
/* ------------------------- Remote_Hunt ------------------------- */ void Remote_Hunt( qboolean visible, qboolean advance, qboolean retreat ) { float distance, speed; vec3_t forward; //If we're not supposed to stand still, pursue the player if ( NPCInfo->standTime < level.time ) { // Only strafe when we can see the player if ( visible ) { Remote_Strafe(); return; } } //If we don't want to advance, stop here if ( advance == qfalse && visible == qtrue ) return; //Only try and navigate if the player is visible if ( visible == qfalse ) { // Move towards our goal NPCInfo->goalEntity = NPC->enemy; NPCInfo->goalRadius = 12; //[CoOp] NPC_MoveToGoal(qtrue); return; /* //Get our direction from the navigator if we can't see our target if ( NPC_GetMoveDirection( forward, &distance ) == qfalse ) return; */ //[/CoOp] } else { VectorSubtract( NPC->enemy->r.currentOrigin, NPC->r.currentOrigin, forward ); distance = VectorNormalize( forward ); } speed = REMOTE_FORWARD_BASE_SPEED + REMOTE_FORWARD_MULTIPLIER * g_spskill.integer; if ( retreat == qtrue ) { speed *= -1; } VectorMA( NPC->client->ps.velocity, speed, forward, NPC->client->ps.velocity ); }
void ATST_Patrol( void ) { if ( NPC_CheckPlayerTeamStealth() ) { NPC_UpdateAngles( qtrue, qtrue ); return; } //If we have somewhere to go, then do that if ( !NPC->enemy ) { if ( UpdateGoal() ) { ucmd.buttons |= BUTTON_WALKING; NPC_MoveToGoal( qtrue ); NPC_UpdateAngles( qtrue, qtrue ); } } }
void Reaver_Hunt( void ) { NPCInfo->combatMove = qtrue; //If we're not supposed to stand still, pursue the player if ( NPCInfo->standTime < level.time ) { //Move towards our goal NPCInfo->goalEntity = NPC->enemy; NPCInfo->goalRadius = 12; NPC_MoveToGoal(); } //Update our angles regardless NPC_UpdateAngles( qtrue, qtrue ); }
void Interrogator_Hunt( qboolean visible, qboolean advance ) { float distance, speed; vec3_t forward; Interrogator_PartsMove(); NPC_FaceEnemy(qfalse); //If we're not supposed to stand still, pursue the player if ( NPCInfo->standTime < level.time ) { // Only strafe when we can see the player if ( visible ) { Interrogator_Strafe(); if ( NPCInfo->standTime > level.time ) {//successfully strafed return; } } } //If we don't want to advance, stop here if ( advance == qfalse ) return; //Only try and navigate if the player is visible if ( visible == qfalse ) { // Move towards our goal NPCInfo->goalEntity = NPC->enemy; NPCInfo->goalRadius = 12; NPC_MoveToGoal(qtrue); return; } else { VectorSubtract( NPC->enemy->currentOrigin, NPC->currentOrigin, forward ); distance = VectorNormalize( forward ); } speed = HUNTER_FORWARD_BASE_SPEED + HUNTER_FORWARD_MULTIPLIER * g_spskill->integer; VectorMA( NPC->client->ps.velocity, speed, forward, NPC->client->ps.velocity ); }