本文整理汇总了C++中Q_irand函数的典型用法代码示例。如果您正苦于以下问题:C++ Q_irand函数的具体用法?C++ Q_irand怎么用?C++ Q_irand使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了Q_irand函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: BubbleShield_Update
void BubbleShield_Update()
{
// Shields Go When You Die
//-------------------------
if (NPC->health<=0)
{
if (BubbleShield_IsOn())
{
BubbleShield_TurnOff();
}
return;
}
// Recharge Shields
//------------------
NPC->client->ps.stats[STAT_ARMOR] += 1;
if (NPC->client->ps.stats[STAT_ARMOR]>250)
{
NPC->client->ps.stats[STAT_ARMOR] = 250;
}
// If We Have Enough Armor And Are Not Shooting Right Now, Kick The Shield On
//----------------------------------------------------------------------------
if (NPC->client->ps.stats[STAT_ARMOR]>100 && TIMER_Done(NPC, "ShieldsDown"))
{
// Check On Timers To Raise And Lower Shields
//--------------------------------------------
if ((level.time - NPCInfo->enemyLastSeenTime)<1000 && TIMER_Done(NPC, "ShieldsUp"))
{
TIMER_Set(NPC, "ShieldsDown", 2000); // Drop Shields
TIMER_Set(NPC, "ShieldsUp", Q_irand(4000, 5000)); // Then Bring Them Back Up For At Least 3 sec
}
BubbleShield_TurnOn();
if (BubbleShield_IsOn())
{
// Update Our Shader Value
//-------------------------
NPC->client->renderInfo.customRGBA[0] =
NPC->client->renderInfo.customRGBA[1] =
NPC->client->renderInfo.customRGBA[2] =
NPC->client->renderInfo.customRGBA[3] = (NPC->client->ps.stats[STAT_ARMOR] - 100);
// If Touched By An Enemy, ALWAYS Shove Them
//-------------------------------------------
if (NPC->enemy && NPCInfo->touchedByPlayer==NPC->enemy)
{
vec3_t dir;
VectorSubtract(NPC->enemy->currentOrigin, NPC->currentOrigin, dir);
VectorNormalize(dir);
BubbleShield_PushEnt(NPC->enemy, dir);
}
// Push Anybody Else Near
//------------------------
BubbleShield_PushRadiusEnts();
}
}
// Shields Gone
//--------------
else
{
BubbleShield_TurnOff();
}
}
示例2: NPC_UpdateFiringAngles
/*
qboolean NPC_UpdateFiringAngles ( qboolean doPitch, qboolean doYaw )
Includes aim when determining angles - so they don't always hit...
*/
qboolean NPC_UpdateFiringAngles ( qboolean doPitch, qboolean doYaw )
{
#if 0
float diff;
float error;
float targetPitch = 0;
float targetYaw = 0;
qboolean exact = qtrue;
if ( level.time < NPCInfo->aimTime )
{
if( doPitch )
targetPitch = NPCInfo->lockedDesiredPitch;
if( doYaw )
targetYaw = NPCInfo->lockedDesiredYaw;
}
else
{
if( doPitch )
{
targetPitch = NPCInfo->desiredPitch;
NPCInfo->lockedDesiredPitch = NPCInfo->desiredPitch;
}
if( doYaw )
{
targetYaw = NPCInfo->desiredYaw;
NPCInfo->lockedDesiredYaw = NPCInfo->desiredYaw;
}
}
if( doYaw )
{
// add yaw error based on NPCInfo->aim value
error = ((float)(6 - NPCInfo->stats.aim)) * flrand(-1, 1);
if(Q_irand(0, 1))
error *= -1;
diff = AngleDelta ( NPC->client->ps.viewangles[YAW], targetYaw );
if ( diff )
exact = qfalse;
ucmd.angles[YAW] = ANGLE2SHORT( targetYaw + diff + error ) - client->ps.delta_angles[YAW];
}
if( doPitch )
{
// add pitch error based on NPCInfo->aim value
error = ((float)(6 - NPCInfo->stats.aim)) * flrand(-1, 1);
diff = AngleDelta ( NPC->client->ps.viewangles[PITCH], targetPitch );
if ( diff )
exact = qfalse;
ucmd.angles[PITCH] = ANGLE2SHORT( targetPitch + diff + error ) - client->ps.delta_angles[PITCH];
}
ucmd.angles[ROLL] = ANGLE2SHORT ( NPC->client->ps.viewangles[ROLL] ) - client->ps.delta_angles[ROLL];
return exact;
#else
float error, diff;
float decay;
float targetPitch = 0;
float targetYaw = 0;
qboolean exact = qtrue;
// if angle changes are locked; just keep the current angles
if ( level.time < NPCInfo->aimTime )
{
if(doPitch)
targetPitch = NPCInfo->lockedDesiredPitch;
if(doYaw)
targetYaw = NPCInfo->lockedDesiredYaw;
}
else
{
if(doPitch)
targetPitch = NPCInfo->desiredPitch;
if(doYaw)
targetYaw = NPCInfo->desiredYaw;
if(doPitch)
NPCInfo->lockedDesiredPitch = NPCInfo->desiredPitch;
if(doYaw)
NPCInfo->lockedDesiredYaw = NPCInfo->desiredYaw;
}
//.........这里部分代码省略.........
示例3: NAVNEW_MoveToGoal
/*
-------------------------
NAVNEW_MoveToGoal
-------------------------
*/
int NAVNEW_MoveToGoal( gentity_t *self, navInfo_t &info )
{
int bestNode = WAYPOINT_NONE;
qboolean foundClearPath = qfalse;
vec3_t origin;
navInfo_t tempInfo;
qboolean setBlockedInfo = qtrue;
qboolean inBestWP, inGoalWP, goalWPFailed = qfalse;
int numTries = 0;
memcpy( &tempInfo, &info, sizeof( tempInfo ) );
//Must have a goal entity to move there
if( self->NPC->goalEntity == NULL )
return WAYPOINT_NONE;
if ( self->waypoint == WAYPOINT_NONE && self->noWaypointTime > level.time )
{ //didn't have a valid one in about the past second, don't look again just yet
return WAYPOINT_NONE;
}
if ( self->NPC->goalEntity->waypoint == WAYPOINT_NONE && self->NPC->goalEntity->noWaypointTime > level.time )
{ //didn't have a valid one in about the past second, don't look again just yet
return WAYPOINT_NONE;
}
if ( self->noWaypointTime > level.time &&
self->NPC->goalEntity->noWaypointTime > level.time )
{ //just use current waypoints
bestNode = navigator.GetBestNodeAltRoute( self->waypoint, self->NPC->goalEntity->waypoint, bestNode );
}
//FIXME!!!!: this is making them wiggle back and forth between waypoints
else if ( (bestNode = navigator.GetBestPathBetweenEnts( self, self->NPC->goalEntity, NF_CLEAR_PATH )) == NODE_NONE )//!NAVNEW_GetWaypoints( self, qtrue ) )
{ //one of us didn't have a valid waypoint!
if ( self->waypoint == NODE_NONE )
{ //don't even try to find one again for a bit
self->noWaypointTime = level.time + Q_irand( 500, 1500 );
}
if ( self->NPC->goalEntity->waypoint == NODE_NONE )
{ //don't even try to find one again for a bit
self->NPC->goalEntity->noWaypointTime = level.time + Q_irand( 500, 1500 );
}
return WAYPOINT_NONE;
}
else
{
if ( self->NPC->goalEntity->noWaypointTime < level.time )
{
self->NPC->goalEntity->noWaypointTime = level.time + Q_irand( 500, 1500 );
}
}
while( !foundClearPath )
{
inBestWP = inGoalWP = qfalse;
/*
bestNode = navigator.GetBestNodeAltRoute( self->waypoint, self->NPC->goalEntity->waypoint, bestNode );
*/
if ( bestNode == WAYPOINT_NONE )
{
goto failed;
}
//see if we can get directly to the next node off bestNode en route to goal's node...
//NOTE: shouldn't be necc. now
/*
int oldBestNode = bestNode;
bestNode = NAV_TestBestNode( self, self->waypoint, bestNode, qtrue );//, self->NPC->goalEntity->waypoint );//
//NOTE: Guaranteed to return something
if ( bestNode != oldBestNode )
{//we were blocked somehow
if ( setBlockedInfo )
{
self->NPC->aiFlags |= NPCAI_BLOCKED;
navigator.GetNodePosition( oldBestNode, NPCInfo->blockedDest );
}
}
*/
navigator.GetNodePosition( bestNode, origin );
/*
if ( !goalWPFailed )
{//we haven't already tried to go straight to goal or goal's wp
if ( bestNode == self->NPC->goalEntity->waypoint )
{//our bestNode is the goal's wp
if ( NAV_HitNavGoal( self->currentOrigin, self->mins, self->maxs, origin, navigator.GetNodeRadius( bestNode ), FlyingCreature( self ) ) )
{//we're in the goal's wp
inGoalWP = qtrue;
//we're in the goalEntity's waypoint already
//so head for the goalEntity since we know it's clear of architecture
//FIXME: this is pretty stupid because the NPCs try to go straight
// towards their goal before then even try macro_nav...
VectorCopy( self->NPC->goalEntity->currentOrigin, origin );
}
}
}
*/
//.........这里部分代码省略.........
示例4: Interrogator_PartsMove
/*
-------------------------
Interrogator_PartsMove
-------------------------
*/
void Interrogator_PartsMove(void)
{
// Syringe
if ( TIMER_Done(NPC,"syringeDelay") )
{
NPC->pos1[1] = AngleNormalize360( NPC->pos1[1]);
if ((NPC->pos1[1] < 60) || (NPC->pos1[1] > 300))
{
NPC->pos1[1]+=Q_irand( -20, 20 ); // Pitch
}
else if (NPC->pos1[1] > 180)
{
NPC->pos1[1]=Q_irand( 300, 360 ); // Pitch
}
else
{
NPC->pos1[1]=Q_irand( 0, 60 ); // Pitch
}
// gi.G2API_SetBoneAnglesIndex( &NPC->ghoul2[NPC->playerModel], NPC->genericBone1, NPC->pos1, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, NULL );
NPC_SetBoneAngles(NPC, "left_arm", NPC->pos1);
TIMER_Set( NPC, "syringeDelay", Q_irand( 100, 1000 ) );
}
// Scalpel
if ( TIMER_Done(NPC,"scalpelDelay") )
{
// Change pitch
if ( NPCInfo->localState == LSTATE_BLADEDOWN ) // Blade is moving down
{
NPC->pos2[0]-= 30;
if (NPC->pos2[0] < 180)
{
NPC->pos2[0] = 180;
NPCInfo->localState = LSTATE_BLADEUP; // Make it move up
}
}
else // Blade is coming back up
{
NPC->pos2[0]+= 30;
if (NPC->pos2[0] >= 360)
{
NPC->pos2[0] = 360;
NPCInfo->localState = LSTATE_BLADEDOWN; // Make it move down
TIMER_Set( NPC, "scalpelDelay", Q_irand( 100, 1000 ) );
}
}
NPC->pos2[0] = AngleNormalize360( NPC->pos2[0]);
// gi.G2API_SetBoneAnglesIndex( &NPC->ghoul2[NPC->playerModel], NPC->genericBone2, NPC->pos2, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, NULL );
NPC_SetBoneAngles(NPC, "right_arm", NPC->pos2);
}
// Claw
NPC->pos3[1] += Q_irand( 10, 30 );
NPC->pos3[1] = AngleNormalize360( NPC->pos3[1]);
//gi.G2API_SetBoneAnglesIndex( &NPC->ghoul2[NPC->playerModel], NPC->genericBone3, NPC->pos3, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, NULL );
NPC_SetBoneAngles(NPC, "claw", NPC->pos3);
}
示例5: NPC_BSGrenadier_Patrol
void NPC_BSGrenadier_Patrol( void )
{//FIXME: pick up on bodies of dead buddies?
if ( NPCInfo->confusionTime < level.time )
{
//Look for any enemies
if ( NPCInfo->scriptFlags&SCF_LOOK_FOR_ENEMIES )
{
if ( NPC_CheckPlayerTeamStealth() )
{
//NPCInfo->behaviorState = BS_HUNT_AND_KILL;//should be automatic now
//NPC_AngerSound();
NPC_UpdateAngles( qtrue, qtrue );
return;
}
}
if ( !(NPCInfo->scriptFlags&SCF_IGNORE_ALERTS) )
{
//Is there danger nearby
int alertEvent = NPC_CheckAlertEvents( qtrue, qtrue, -1, qfalse, AEL_SUSPICIOUS );
if ( NPC_CheckForDanger( alertEvent ) )
{
NPC_UpdateAngles( qtrue, qtrue );
return;
}
else
{//check for other alert events
//There is an event to look at
if ( alertEvent >= 0 )//&& level.alertEvents[alertEvent].ID != NPCInfo->lastAlertID )
{
//NPCInfo->lastAlertID = level.alertEvents[alertEvent].ID;
if ( level.alertEvents[alertEvent].level == AEL_DISCOVERED )
{
if ( level.alertEvents[alertEvent].owner &&
level.alertEvents[alertEvent].owner->client &&
level.alertEvents[alertEvent].owner->health >= 0 &&
level.alertEvents[alertEvent].owner->client->playerTeam == NPC->client->enemyTeam )
{//an enemy
G_SetEnemy( NPC, level.alertEvents[alertEvent].owner );
//NPCInfo->enemyLastSeenTime = level.time;
TIMER_Set( NPC, "attackDelay", Q_irand( 500, 2500 ) );
}
}
else
{//FIXME: get more suspicious over time?
//Save the position for movement (if necessary)
VectorCopy( level.alertEvents[alertEvent].position, NPCInfo->investigateGoal );
NPCInfo->investigateDebounceTime = level.time + Q_irand( 500, 1000 );
if ( level.alertEvents[alertEvent].level == AEL_SUSPICIOUS )
{//suspicious looks longer
NPCInfo->investigateDebounceTime += Q_irand( 500, 2500 );
}
}
}
}
if ( NPCInfo->investigateDebounceTime > level.time )
{//FIXME: walk over to it, maybe? Not if not chase enemies
//NOTE: stops walking or doing anything else below
vec3_t dir, angles;
float o_yaw, o_pitch;
VectorSubtract( NPCInfo->investigateGoal, NPC->client->renderInfo.eyePoint, dir );
vectoangles( dir, angles );
o_yaw = NPCInfo->desiredYaw;
o_pitch = NPCInfo->desiredPitch;
NPCInfo->desiredYaw = angles[YAW];
NPCInfo->desiredPitch = angles[PITCH];
NPC_UpdateAngles( qtrue, qtrue );
NPCInfo->desiredYaw = o_yaw;
NPCInfo->desiredPitch = o_pitch;
return;
}
}
}
//If we have somewhere to go, then do that
if ( UpdateGoal() )
{
ucmd.buttons |= BUTTON_WALKING;
NPC_MoveToGoal( qtrue );
}
NPC_UpdateAngles( qtrue, qtrue );
}
示例6: Mark1_AttackDecision
/*
-------------------------
Mark1_AttackDecision
-------------------------
*/
void Mark1_AttackDecision( void )
{
int blasterTest,rocketTest;
float distance;
distance_e distRate;
qboolean visible;
qboolean advance;
//randomly talk
if ( TIMER_Done(NPC,"patrolNoise") )
{
if (TIMER_Done(NPC,"angerNoise"))
{
// G_Sound( NPC, G_SoundIndex(va("sound/chars/mark1/misc/talk%d.wav", Q_irand(1, 4))));
TIMER_Set( NPC, "patrolNoise", Q_irand( 4000, 10000 ) );
}
}
// Enemy is dead or he has no enemy.
if ((NPC->enemy->health<1) || ( NPC_CheckEnemyExt(qfalse) == qfalse ))
{
NPC->enemy = NULL;
return;
}
// Rate our distance to the target and visibility
distance = (int) DistanceHorizontalSquared( NPC->r.currentOrigin, NPC->enemy->r.currentOrigin );
distRate = ( distance > MIN_MELEE_RANGE_SQR ) ? DIST_LONG : DIST_MELEE;
visible = NPC_ClearLOS4( NPC->enemy );
advance = (qboolean)(distance > MIN_DISTANCE_SQR);
// If we cannot see our target, move to see it
if ((!visible) || (!NPC_FaceEnemy(qtrue)))
{
Mark1_Hunt();
return;
}
// See if the side weapons are there
blasterTest = trap_G2API_GetSurfaceRenderStatus( NPC->ghoul2, 0, "l_arm" );
rocketTest = trap_G2API_GetSurfaceRenderStatus( NPC->ghoul2, 0, "r_arm" );
// It has both side weapons
if (!blasterTest && !rocketTest)
{
; // So do nothing.
}
else if (blasterTest!=-1
&&blasterTest)
{
distRate = DIST_LONG;
}
else if (rocketTest!=-1
&&rocketTest)
{
distRate = DIST_MELEE;
}
else // It should never get here, but just in case
{
NPC->health = 0;
NPC->client->ps.stats[STAT_HEALTH] = 0;
//GEntity_DieFunc(NPC, NPC, NPC, 100, MOD_UNKNOWN);
if (NPC->die)
{
NPC->die(NPC, NPC, NPC, 100, MOD_UNKNOWN);
}
}
// We can see enemy so shoot him if timers let you.
NPC_FaceEnemy( qtrue );
if (distRate == DIST_MELEE)
{
Mark1_BlasterAttack(advance);
}
else if (distRate == DIST_LONG)
{
Mark1_RocketAttack(advance);
}
}
示例7: NPC_BSSaberDroid_Attack
//.........这里部分代码省略.........
move = qtrue;
faceEnemy = qfalse;
shoot = qfalse;
enemyDist = DistanceSquared( NPC->enemy->r.currentOrigin, NPC->r.currentOrigin );
//can we see our target?
if ( NPC_ClearLOS4( NPC->enemy ) )
{
NPCInfo->enemyLastSeenTime = level.time;
enemyLOS = qtrue;
if ( enemyDist <= 4096 && InFOV3( NPC->enemy->r.currentOrigin, NPC->r.currentOrigin, NPC->client->ps.viewangles, 90, 45 ) )//within 64 & infront
{
VectorCopy( NPC->enemy->r.currentOrigin, NPCInfo->enemyLastSeenLocation );
enemyCS = qtrue;
}
}
/*
else if ( gi.inPVS( NPC->enemy->currentOrigin, NPC->currentOrigin ) )
{
NPCInfo->enemyLastSeenTime = level.time;
faceEnemy = qtrue;
}
*/
if ( enemyLOS )
{//FIXME: no need to face enemy if we're moving to some other goal and he's too far away to shoot?
faceEnemy = qtrue;
}
if ( !TIMER_Done( NPC, "taunting" ) )
{
move = qfalse;
}
else if ( enemyCS )
{
shoot = qtrue;
if ( enemyDist < (NPC->r.maxs[0]+NPC->enemy->r.maxs[0]+32)*(NPC->r.maxs[0]+NPC->enemy->r.maxs[0]+32) )
{//close enough
move = qfalse;
}
}//this should make him chase enemy when out of range...?
if ( NPC->client->ps.legsTimer
&& NPC->client->ps.legsAnim != BOTH_A3__L__R )//this one is a running attack
{//in the middle of a held, stationary anim, can't move
move = qfalse;
}
if ( move )
{//move toward goal
move = SaberDroid_Move();
if ( move )
{//if we had to chase him, be sure to attack as soon as possible
TIMER_Set( NPC, "attackDelay", NPC->client->ps.weaponTime );
}
}
if ( !faceEnemy )
{//we want to face in the dir we're running
if ( move )
{//don't run away and shoot
NPCInfo->desiredYaw = NPCInfo->lastPathAngles[YAW];
NPCInfo->desiredPitch = 0;
shoot = qfalse;
}
NPC_UpdateAngles( qtrue, qtrue );
}
else// if ( faceEnemy )
{//face the enemy
NPC_FaceEnemy(qtrue);
}
if ( NPCInfo->scriptFlags&SCF_DONT_FIRE )
{
shoot = qfalse;
}
//FIXME: need predicted blocking?
//FIXME: don't shoot right away!
if ( shoot )
{//try to shoot if it's time
if ( TIMER_Done( NPC, "attackDelay" ) )
{
if( !(NPCInfo->scriptFlags & SCF_FIRE_WEAPON) ) // we've already fired, no need to do it again here
{//attack!
NPC_SaberDroid_PickAttack();
//set attac delay for next attack.
if ( NPCInfo->rank > RANK_CREWMAN )
{
TIMER_Set( NPC, "attackDelay", NPC->client->ps.weaponTime+Q_irand(0, 1000) );
}
else
{
TIMER_Set( NPC, "attackDelay", NPC->client->ps.weaponTime+Q_irand( 0, 1000 )+(Q_irand( 0, (3-g_spskill.integer)*2 )*500) );
}
}
}
}
}
示例8: Remote_MaintainHeight
/*
-------------------------
Remote_MaintainHeight
-------------------------
*/
void Remote_MaintainHeight( void )
{
float dif;
// Update our angles regardless
NPC_UpdateAngles( qtrue, qtrue );
if ( NPCS.NPC->client->ps.velocity[2] )
{
NPCS.NPC->client->ps.velocity[2] *= VELOCITY_DECAY;
if ( fabs( NPCS.NPC->client->ps.velocity[2] ) < 2 )
{
NPCS.NPC->client->ps.velocity[2] = 0;
}
}
// If we have an enemy, we should try to hover at or a little below enemy eye level
if ( NPCS.NPC->enemy )
{
if (TIMER_Done( NPCS.NPC, "heightChange"))
{
TIMER_Set( NPCS.NPC,"heightChange",Q_irand( 1000, 3000 ));
// Find the height difference
dif = (NPCS.NPC->enemy->r.currentOrigin[2] + Q_irand( 0, NPCS.NPC->enemy->r.maxs[2]+8 )) - NPCS.NPC->r.currentOrigin[2];
// cap to prevent dramatic height shifts
if ( fabs( dif ) > 2 )
{
if ( fabs( dif ) > 24 )
{
dif = ( dif < 0 ? -24 : 24 );
}
dif *= 10;
NPCS.NPC->client->ps.velocity[2] = (NPCS.NPC->client->ps.velocity[2]+dif)/2;
// NPC->fx_time = level.time;
G_Sound( NPCS.NPC, CHAN_AUTO, G_SoundIndex("sound/chars/remote/misc/hiss.wav"));
}
}
}
else
{
gentity_t *goal = NULL;
if ( NPCS.NPCInfo->goalEntity ) // Is there a goal?
{
goal = NPCS.NPCInfo->goalEntity;
}
else
{
goal = NPCS.NPCInfo->lastGoalEntity;
}
if ( goal )
{
dif = goal->r.currentOrigin[2] - NPCS.NPC->r.currentOrigin[2];
if ( fabs( dif ) > 24 )
{
dif = ( dif < 0 ? -24 : 24 );
NPCS.NPC->client->ps.velocity[2] = (NPCS.NPC->client->ps.velocity[2]+dif)/2;
}
}
}
// Apply friction
if ( NPCS.NPC->client->ps.velocity[0] )
{
NPCS.NPC->client->ps.velocity[0] *= VELOCITY_DECAY;
if ( fabs( NPCS.NPC->client->ps.velocity[0] ) < 1 )
{
NPCS.NPC->client->ps.velocity[0] = 0;
}
}
if ( NPCS.NPC->client->ps.velocity[1] )
{
NPCS.NPC->client->ps.velocity[1] *= VELOCITY_DECAY;
if ( fabs( NPCS.NPC->client->ps.velocity[1] ) < 1 )
{
NPCS.NPC->client->ps.velocity[1] = 0;
}
}
}
示例9: Pick
inline void Pick(int& V)
{
V = Q_irand(mMin, mMax);
}
示例10: RT_Flying_Hunt
void RT_Flying_Hunt( qboolean visible, qboolean advance )
{
float distance, speed;
vec3_t forward;
if ( NPC->forcePushTime >= level.time )
//|| (NPC->client->ps.eFlags&EF_FORCE_GRIPPED) )
{//if being pushed, we don't have control over our movement
NPC->delay = 0;
return;
}
NPC_FaceEnemy( qtrue );
// 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 )
{
NPC->delay = 0;
RT_Flying_Strafe();
return;
}
}
// If we don't want to advance, stop here
if ( advance )
{
// Only try and navigate if the player is visible
if ( visible == qfalse )
{
// Move towards our goal
NPCInfo->goalEntity = NPC->enemy;
NPCInfo->goalRadius = 24;
NPC->delay = 0;
NPC_MoveToGoal(qtrue);
return;
}
}
//else move straight at/away from him
VectorSubtract( NPC->enemy->currentOrigin, NPC->currentOrigin, forward );
forward[2] *= 0.1f;
distance = VectorNormalize( forward );
speed = RT_FLYING_FORWARD_BASE_SPEED + RT_FLYING_FORWARD_MULTIPLIER * g_spskill->integer;
if ( advance && distance < Q_flrand( 256, 3096 ) )
{
NPC->delay = 0;
VectorMA( NPC->client->ps.velocity, speed, forward, NPC->client->ps.velocity );
}
else if ( distance < Q_flrand( 0, 128 ) )
{
if ( NPC->health <= 50 )
{//always back off
NPC->delay = 0;
}
else if ( !TIMER_Done( NPC, "backoffTime" ) )
{//still backing off from end of last delay
NPC->delay = 0;
}
else if ( !NPC->delay )
{//start a new delay
NPC->delay = Q_irand( 0, 10+(20*(2-g_spskill->integer)) );
}
else
{//continue the current delay
NPC->delay--;
}
if ( !NPC->delay )
{//delay done, now back off for a few seconds!
TIMER_Set( NPC, "backoffTime", Q_irand( 2000, 5000 ) );
VectorMA( NPC->client->ps.velocity, speed*-2, forward, NPC->client->ps.velocity );
}
}
else
{
NPC->delay = 0;
}
}
示例11: Touch_Item
void Touch_Item (gentity_t *ent, gentity_t *other, trace_t *trace) {
int respawn = 0;
if (!other->client)
return;
if (other->health < 1)
return; // dead people can't pickup
if ( other->client->ps.pm_time > 0 )
{//cant pick up when out of control
return;
}
// Only monsters can pick it up
if ((ent->spawnflags & ITMSF_MONSTER) && (other->client->playerTeam == TEAM_PLAYER))
{
return;
}
// Only starfleet can pick it up
if ((ent->spawnflags & ITMSF_TEAM) && (other->client->playerTeam != TEAM_PLAYER))
{
return;
}
if ( other->client->NPC_class == CLASS_ATST ||
other->client->NPC_class == CLASS_GONK ||
other->client->NPC_class == CLASS_MARK1 ||
other->client->NPC_class == CLASS_MARK2 ||
other->client->NPC_class == CLASS_MOUSE ||
other->client->NPC_class == CLASS_PROBE ||
other->client->NPC_class == CLASS_PROTOCOL ||
other->client->NPC_class == CLASS_R2D2 ||
other->client->NPC_class == CLASS_R5D2 ||
other->client->NPC_class == CLASS_SEEKER ||
other->client->NPC_class == CLASS_REMOTE ||
other->client->NPC_class == CLASS_SENTRY )
{//FIXME: some flag would be better
//droids can't pick up items/weapons!
return;
}
//FIXME: need to make them run toward a dropped weapon when fleeing without one?
//FIXME: need to make them come out of flee mode when pick up their old weapon?
if ( CheckItemCanBePickedUpByNPC( ent, other ) )
{
if ( other->NPC && other->NPC->goalEntity && other->NPC->goalEntity->enemy == ent )
{//they were running to pick me up, they did, so clear goal
other->NPC->goalEntity = NULL;
other->NPC->squadState = SQUAD_STAND_AND_SHOOT;
}
}
else if (!(ent->spawnflags & ITMSF_TEAM) && !(ent->spawnflags & ITMSF_MONSTER))
{// Only player can pick it up
if ( other->s.number != 0 ) // Not the player?
{
return;
}
}
// the same pickup rules are used for client side and server side
if ( !BG_CanItemBeGrabbed( &ent->s, &other->client->ps ) ) {
return;
}
if ( other->client )
{
if ( other->client->ps.eFlags&EF_FORCE_GRIPPED )
{//can't pick up anything while being gripped
return;
}
if ( PM_InKnockDown( &other->client->ps ) && !PM_InGetUp( &other->client->ps ) )
{//can't pick up while in a knockdown
return;
}
}
if (!ent->item) { //not an item!
gi.Printf( "Touch_Item: %s is not an item!\n", ent->classname);
return;
}
qboolean bHadWeapon = qfalse;
// call the item-specific pickup function
switch( ent->item->giType )
{
case IT_WEAPON:
if ( other->NPC && other->s.weapon == WP_NONE )
{//Make them duck and sit here for a few seconds
int pickUpTime = Q_irand( 1000, 3000 );
TIMER_Set( other, "duck", pickUpTime );
TIMER_Set( other, "roamTime", pickUpTime );
TIMER_Set( other, "stick", pickUpTime );
TIMER_Set( other, "verifyCP", pickUpTime );
TIMER_Set( other, "attackDelay", 600 );
respawn = 0;
}
if ( other->client->ps.stats[STAT_WEAPONS] & ( 1 << ent->item->giTag ) )
{
bHadWeapon = qtrue;
}
//.........这里部分代码省略.........
示例12: RT_Flying_Strafe
void RT_Flying_Strafe( void )
{
int side;
vec3_t end, right, dir;
trace_t tr;
if ( random() > 0.7f
|| !NPC->enemy
|| !NPC->enemy->client )
{
// Do a regular style strafe
AngleVectors( NPC->client->renderInfo.eyeAngles, NULL, right, NULL );
// Pick a random strafe direction, then check to see if doing a strafe would be
// reasonably valid
side = ( rand() & 1 ) ? -1 : 1;
VectorMA( NPC->currentOrigin, RT_FLYING_STRAFE_DIS * side, right, end );
gi.trace( &tr, NPC->currentOrigin, NULL, NULL, end, NPC->s.number, MASK_SOLID );
// Close enough
if ( tr.fraction > 0.9f )
{
float vel = RT_FLYING_STRAFE_VEL+Q_flrand(-20,20);
VectorMA( NPC->client->ps.velocity, vel*side, right, NPC->client->ps.velocity );
if ( !Q_irand( 0, 3 ) )
{
// Add a slight upward push
float upPush = RT_FLYING_UPWARD_PUSH;
if ( NPC->client->ps.velocity[2] < 300 )
{
if ( NPC->client->ps.velocity[2] < 300+upPush )
{
NPC->client->ps.velocity[2] += upPush;
}
else
{
NPC->client->ps.velocity[2] = 300;
}
}
}
// NPCInfo->standTime = level.time + 1000 + random() * 500; // Original
// NPCInfo->standTime = level.time + 2000 + random() * 500; // Revision 1
NPCInfo->standTime = level.time + 1500 + random() * 500; // Revision 2
}
}
else
{
// Do a strafe to try and keep on the side of their enemy
AngleVectors( NPC->enemy->client->renderInfo.eyeAngles, dir, right, NULL );
// Pick a random side
side = ( rand() & 1 ) ? -1 : 1;
float stDis = RT_FLYING_STRAFE_DIS*2.0f;
VectorMA( NPC->enemy->currentOrigin, stDis * side, right, end );
// then add a very small bit of random in front of/behind the player action
VectorMA( end, crandom() * 25, dir, end );
gi.trace( &tr, NPC->currentOrigin, NULL, NULL, end, NPC->s.number, MASK_SOLID );
// Close enough
if ( tr.fraction > 0.9f )
{
float vel = (RT_FLYING_STRAFE_VEL*4)+Q_flrand(-20,20);
VectorSubtract( tr.endpos, NPC->currentOrigin, dir );
dir[2] *= 0.25; // do less upward change
float dis = VectorNormalize( dir );
if ( dis > vel )
{
dis = vel;
}
// Try to move the desired enemy side
VectorMA( NPC->client->ps.velocity, dis, dir, NPC->client->ps.velocity );
if ( !Q_irand( 0, 3 ) )
{
float upPush = RT_FLYING_UPWARD_PUSH;
// Add a slight upward push
if ( NPC->client->ps.velocity[2] < 300 )
{
if ( NPC->client->ps.velocity[2] < 300+upPush )
{
NPC->client->ps.velocity[2] += upPush;
}
else
{
NPC->client->ps.velocity[2] = 300;
}
}
else if ( NPC->client->ps.velocity[2] > 300 )
{
NPC->client->ps.velocity[2] = 300;
}
}
// NPCInfo->standTime = level.time + 2500 + random() * 500; // Original
// NPCInfo->standTime = level.time + 5000 + random() * 500; // Revision 1
NPCInfo->standTime = level.time + 3500 + random() * 500; // Revision 2
//.........这里部分代码省略.........
示例13: RT_FireDecide
void RT_FireDecide( void )
{
qboolean enemyLOS = qfalse;
qboolean enemyCS = qfalse;
qboolean enemyInFOV = qfalse;
//qboolean move = qtrue;
qboolean faceEnemy = qfalse;
qboolean shoot = qfalse;
qboolean hitAlly = qfalse;
vec3_t impactPos;
float enemyDist;
if ( NPC->client->ps.groundEntityNum == ENTITYNUM_NONE
&& NPC->client->ps.forceJumpZStart
&& !PM_FlippingAnim( NPC->client->ps.legsAnim )
&& !Q_irand( 0, 10 ) )
{//take off
RT_FlyStart( NPC );
}
if ( !NPC->enemy )
{
return;
}
VectorClear( impactPos );
enemyDist = DistanceSquared( NPC->currentOrigin, NPC->enemy->currentOrigin );
vec3_t enemyDir, shootDir;
VectorSubtract( NPC->enemy->currentOrigin, NPC->currentOrigin, enemyDir );
VectorNormalize( enemyDir );
AngleVectors( NPC->client->ps.viewangles, shootDir, NULL, NULL );
float dot = DotProduct( enemyDir, shootDir );
if ( dot > 0.5f ||( enemyDist * (1.0f-dot)) < 10000 )
{//enemy is in front of me or they're very close and not behind me
enemyInFOV = qtrue;
}
if ( enemyDist < MIN_ROCKET_DIST_SQUARED )//128
{//enemy within 128
if ( (NPC->client->ps.weapon == WP_FLECHETTE || NPC->client->ps.weapon == WP_REPEATER) &&
(NPCInfo->scriptFlags & SCF_ALT_FIRE) )
{//shooting an explosive, but enemy too close, switch to primary fire
NPCInfo->scriptFlags &= ~SCF_ALT_FIRE;
//FIXME: we can never go back to alt-fire this way since, after this, we don't know if we were initially supposed to use alt-fire or not...
}
}
//can we see our target?
if ( TIMER_Done( NPC, "nextAttackDelay" ) && TIMER_Done( NPC, "flameTime" ) )
{
if ( NPC_ClearLOS( NPC->enemy ) )
{
NPCInfo->enemyLastSeenTime = level.time;
enemyLOS = qtrue;
if ( NPC->client->ps.weapon == WP_NONE )
{
enemyCS = qfalse;//not true, but should stop us from firing
}
else
{//can we shoot our target?
if ( (NPC->client->ps.weapon == WP_ROCKET_LAUNCHER
|| (NPC->client->ps.weapon == WP_CONCUSSION && !(NPCInfo->scriptFlags&SCF_ALT_FIRE))
|| (NPC->client->ps.weapon == WP_FLECHETTE && (NPCInfo->scriptFlags&SCF_ALT_FIRE))) && enemyDist < MIN_ROCKET_DIST_SQUARED )//128*128
{
enemyCS = qfalse;//not true, but should stop us from firing
hitAlly = qtrue;//us!
//FIXME: if too close, run away!
}
else if ( enemyInFOV )
{//if enemy is FOV, go ahead and check for shooting
int hit = NPC_ShotEntity( NPC->enemy, impactPos );
gentity_t *hitEnt = &g_entities[hit];
if ( hit == NPC->enemy->s.number
|| ( hitEnt && hitEnt->client && hitEnt->client->playerTeam == NPC->client->enemyTeam )
|| ( hitEnt && hitEnt->takedamage && ((hitEnt->svFlags&SVF_GLASS_BRUSH)||hitEnt->health < 40||NPC->s.weapon == WP_EMPLACED_GUN) ) )
{//can hit enemy or enemy ally or will hit glass or other minor breakable (or in emplaced gun), so shoot anyway
enemyCS = qtrue;
//NPC_AimAdjust( 2 );//adjust aim better longer we have clear shot at enemy
VectorCopy( NPC->enemy->currentOrigin, NPCInfo->enemyLastSeenLocation );
}
else
{//Hmm, have to get around this bastard
//NPC_AimAdjust( 1 );//adjust aim better longer we can see enemy
if ( hitEnt && hitEnt->client && hitEnt->client->playerTeam == NPC->client->playerTeam )
{//would hit an ally, don't fire!!!
hitAlly = qtrue;
}
else
{//Check and see where our shot *would* hit... if it's not close to the enemy (within 256?), then don't fire
}
}
}
else
{
enemyCS = qfalse;//not true, but should stop us from firing
}
}
//.........这里部分代码省略.........
示例14: RT_Flying_MaintainHeight
void RT_Flying_MaintainHeight( void )
{
float dif = 0;
// Update our angles regardless
NPC_UpdateAngles( qtrue, qtrue );
if ( NPC->forcePushTime > level.time )
{//if being pushed, we don't have control over our movement
return;
}
if ( (NPC->client->ps.pm_flags&PMF_TIME_KNOCKBACK) )
{//don't slow down for a bit
if ( NPC->client->ps.pm_time > 0 )
{
VectorScale( NPC->client->ps.velocity, 0.9f, NPC->client->ps.velocity );
return;
}
}
/*
if ( (NPC->client->ps.eFlags&EF_FORCE_GRIPPED) )
{
RT_Flying_ApplyFriction( 3.0f );
return;
}
*/
// If we have an enemy, we should try to hover at or a little below enemy eye level
if ( NPC->enemy
&& (!Q3_TaskIDPending( NPC, TID_MOVE_NAV ) || !NPCInfo->goalEntity ) )
{
if (TIMER_Done( NPC, "heightChange" ))
{
TIMER_Set( NPC,"heightChange",Q_irand( 1000, 3000 ));
float enemyZHeight = NPC->enemy->currentOrigin[2];
if ( NPC->enemy->client
&& NPC->enemy->client->ps.groundEntityNum == ENTITYNUM_NONE
&& (NPC->enemy->client->ps.forcePowersActive&(1<<FP_LEVITATION)) )
{//so we don't go up when they force jump up at us
enemyZHeight = NPC->enemy->client->ps.forceJumpZStart;
}
// Find the height difference
dif = (enemyZHeight + Q_flrand( NPC->enemy->maxs[2]/2, NPC->enemy->maxs[2]+8 )) - NPC->currentOrigin[2];
float difFactor = 10.0f;
// cap to prevent dramatic height shifts
if ( fabs( dif ) > 2*difFactor )
{
if ( fabs( dif ) > 20*difFactor )
{
dif = ( dif < 0 ? -20*difFactor : 20*difFactor );
}
NPC->client->ps.velocity[2] = (NPC->client->ps.velocity[2]+dif)/2;
}
NPC->client->ps.velocity[2] *= Q_flrand( 0.85f, 1.25f );
}
else
{//don't get too far away from height of enemy...
float enemyZHeight = NPC->enemy->currentOrigin[2];
if ( NPC->enemy->client
&& NPC->enemy->client->ps.groundEntityNum == ENTITYNUM_NONE
&& (NPC->enemy->client->ps.forcePowersActive&(1<<FP_LEVITATION)) )
{//so we don't go up when they force jump up at us
enemyZHeight = NPC->enemy->client->ps.forceJumpZStart;
}
dif = NPC->currentOrigin[2] - (enemyZHeight+64);
float maxHeight = 200;
float hDist = DistanceHorizontal( NPC->enemy->currentOrigin, NPC->currentOrigin );
if ( hDist < 512 )
{
maxHeight *= hDist/512;
}
if ( dif > maxHeight )
{
if ( NPC->client->ps.velocity[2] > 0 )//FIXME: or: we can't see him anymore
{//slow down
if ( NPC->client->ps.velocity[2] )
{
NPC->client->ps.velocity[2] *= VELOCITY_DECAY;
if ( fabs( NPC->client->ps.velocity[2] ) < 2 )
{
NPC->client->ps.velocity[2] = 0;
}
}
}
else
{//start coming back down
NPC->client->ps.velocity[2] -= 4;
}
}
else if ( dif < -200 && NPC->client->ps.velocity[2] < 0 )//we're way below him
{
if ( NPC->client->ps.velocity[2] < 0 )//FIXME: or: we can't see him anymore
{//slow down
//.........这里部分代码省略.........
示例15: Mark1_dying
/*
-------------------------
Mark1_dying
-------------------------
*/
void Mark1_dying( gentity_t *self )
{
int num,newBolt;
if (self->client->ps.torsoTimer>0)
{
if (TIMER_Done(self,"dyingExplosion"))
{
num = Q_irand( 1, 3);
// Find place to generate explosion
if (num == 1)
{
num = Q_irand( 8, 10);
newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("*flash%d",num) );
NPC_Mark1_Part_Explode(self,newBolt);
}
else
{
num = Q_irand( 1, 6);
newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("*torso_tube%d",num) );
NPC_Mark1_Part_Explode(self,newBolt);
NPC_SetSurfaceOnOff( self, va("torso_tube%d",num), TURN_OFF );
}
TIMER_Set( self, "dyingExplosion", Q_irand( 300, 1000 ) );
}
// int dir;
// vec3_t right;
// Shove to the side
// AngleVectors( self->client->renderInfo.eyeAngles, NULL, right, NULL );
// VectorMA( self->client->ps.velocity, -80, right, self->client->ps.velocity );
// See which weapons are there
// Randomly fire blaster
if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm" )) // Is the blaster still on the model?
{
if (Q_irand( 1, 5) == 1)
{
SaveNPCGlobals();
SetNPCGlobals( self );
Mark1Dead_FireBlaster();
RestoreNPCGlobals();
}
}
// Randomly fire rocket
if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm" )) // Is the rocket still on the model?
{
if (Q_irand( 1, 10) == 1)
{
SaveNPCGlobals();
SetNPCGlobals( self );
Mark1Dead_FireRocket();
RestoreNPCGlobals();
}
}
}
}